Mercurial > dropbear
comparison svr-authpubkeyoptions.c @ 476:df7f7da7f6e4 pubkey-options
- Rework pubkey options to be more careful about buffer lengths. Needs review.
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Fri, 12 Sep 2008 17:23:56 +0000 |
parents | 52a644e7b8e1 |
children | 43bbe17d6ba0 |
comparison
equal
deleted
inserted
replaced
475:52a644e7b8e1 | 476:df7f7da7f6e4 |
---|---|
100 m_free(ses.authstate.pubkey_options); | 100 m_free(ses.authstate.pubkey_options); |
101 ses.authstate.pubkey_options = NULL; | 101 ses.authstate.pubkey_options = NULL; |
102 } | 102 } |
103 } | 103 } |
104 | 104 |
105 /* helper for svr_add_pubkey_options. returns DROPBEAR_SUCCESS if the option is matched, | |
106 and increments the options_buf */ | |
107 static int match_option(buffer *options_buf, const char *opt_name) { | |
108 const int len = strlen(opt_name); | |
109 if (options_buf->len - options_buf->pos < len) { | |
110 return DROPBEAR_FAILURE; | |
111 } | |
112 if (strncasecmp(buf_getptr(options_buf, len), opt_name, len) == 0) { | |
113 buf_incrpos(options_buf, len); | |
114 return DROPBEAR_SUCCESS; | |
115 } | |
116 return DROPBEAR_FAILURE; | |
117 } | |
118 | |
105 /* Parse pubkey options and set ses.authstate.pubkey_options accordingly. | 119 /* Parse pubkey options and set ses.authstate.pubkey_options accordingly. |
106 * Returns DROPBEAR_SUCCESS if key is ok for auth, DROPBEAR_FAILURE otherwise */ | 120 * Returns DROPBEAR_SUCCESS if key is ok for auth, DROPBEAR_FAILURE otherwise */ |
107 int svr_add_pubkey_options(const char* opts) { | 121 int svr_add_pubkey_options(buffer *options_buf, int line_num, const char* filename) { |
108 const char *cp; | |
109 int i; | |
110 int ret = DROPBEAR_FAILURE; | 122 int ret = DROPBEAR_FAILURE; |
111 | 123 |
112 TRACE(("enter addpubkeyoptions")) | 124 TRACE(("enter addpubkeyoptions")) |
113 | 125 |
114 if (!opts || *opts == ' ') { | |
115 /* no option, success */ | |
116 ret = DROPBEAR_SUCCESS; | |
117 goto end; | |
118 } | |
119 | |
120 ses.authstate.pubkey_options = (struct PubKeyOptions*)m_malloc(sizeof( struct PubKeyOptions )); | 126 ses.authstate.pubkey_options = (struct PubKeyOptions*)m_malloc(sizeof( struct PubKeyOptions )); |
121 | 127 memset(ses.authstate.pubkey_options, '\0', sizeof(*ses.authstate.pubkey_options)); |
122 while (*opts && *opts != ' ' && *opts != '\t') { | 128 |
123 cp = "no-port-forwarding"; | 129 buf_setpos(options_buf, 0); |
124 if (strncasecmp(opts, cp, strlen(cp)) == 0) { | 130 while (options_buf->pos < options_buf->len) { |
131 if (match_option(options_buf, "no-port-forwarding") == DROPBEAR_SUCCESS) { | |
125 dropbear_log(LOG_WARNING, "Port forwarding disabled."); | 132 dropbear_log(LOG_WARNING, "Port forwarding disabled."); |
126 ses.authstate.pubkey_options->no_port_forwarding_flag = 1; | 133 ses.authstate.pubkey_options->no_port_forwarding_flag = 1; |
127 opts += strlen(cp); | |
128 goto next_option; | 134 goto next_option; |
129 } | 135 } |
130 #ifdef ENABLE_AGENTFWD | 136 #ifdef ENABLE_AGENTFWD |
131 cp = "no-agent-forwarding"; | 137 if (match_option(options_buf, "no-agent-forwarding") == DROPBEAR_SUCCESS) { |
132 if (strncasecmp(opts, cp, strlen(cp)) == 0) { | |
133 dropbear_log(LOG_WARNING, "Agent forwarding disabled."); | 138 dropbear_log(LOG_WARNING, "Agent forwarding disabled."); |
134 ses.authstate.pubkey_options->no_agent_forwarding_flag = 1; | 139 ses.authstate.pubkey_options->no_agent_forwarding_flag = 1; |
135 opts += strlen(cp); | |
136 goto next_option; | 140 goto next_option; |
137 } | 141 } |
138 #endif | 142 #endif |
139 #ifdef ENABLE_X11FWD | 143 #ifdef ENABLE_X11FWD |
140 cp = "no-X11-forwarding"; | 144 if (match_option(options_buf, "no-X11-forwarding") == DROPBEAR_SUCCESS) { |
141 if (strncasecmp(opts, cp, strlen(cp)) == 0) { | |
142 dropbear_log(LOG_WARNING, "X11 forwarding disabled."); | 145 dropbear_log(LOG_WARNING, "X11 forwarding disabled."); |
143 ses.authstate.pubkey_options->no_x11_forwarding_flag = 1; | 146 ses.authstate.pubkey_options->no_x11_forwarding_flag = 1; |
144 opts += strlen(cp); | |
145 goto next_option; | 147 goto next_option; |
146 } | 148 } |
147 #endif | 149 #endif |
148 cp = "no-pty"; | 150 if (match_option(options_buf, "no-pty") == DROPBEAR_SUCCESS) { |
149 if (strncasecmp(opts, cp, strlen(cp)) == 0) { | |
150 dropbear_log(LOG_WARNING, "Pty allocation disabled."); | 151 dropbear_log(LOG_WARNING, "Pty allocation disabled."); |
151 ses.authstate.pubkey_options->no_pty_flag = 1; | 152 ses.authstate.pubkey_options->no_pty_flag = 1; |
152 opts += strlen(cp); | 153 goto next_option; |
153 goto next_option; | 154 } |
154 } | 155 if (match_option(options_buf, "command=\"") == DROPBEAR_SUCCESS) { |
155 cp = "command=\""; | 156 int escaped = 0; |
156 if (strncasecmp(opts, cp, strlen(cp)) == 0) { | 157 const unsigned char* command_start = buf_getptr(options_buf, 0); |
157 opts += strlen(cp); | 158 while (options_buf->pos < options_buf->len) { |
158 ses.authstate.pubkey_options->forced_command = (char*)m_malloc(strlen(opts) + 1); | 159 const char c = buf_getbyte(options_buf); |
159 i = 0; | 160 if (!escaped && c == '"') { |
160 while (*opts) { | 161 const int command_len = buf_getptr(options_buf, 0) - command_start; |
161 if (*opts == '"') | 162 ses.authstate.pubkey_options->forced_command = m_malloc(command_len); |
162 break; | 163 memcpy(ses.authstate.pubkey_options->forced_command, |
163 if (*opts == '\\' && opts[1] == '"') { | 164 command_start, command_len-1); |
164 opts += 2; | 165 ses.authstate.pubkey_options->forced_command[command_len-1] = '\0'; |
165 ses.authstate.pubkey_options->forced_command[i++] = '"'; | 166 dropbear_log(LOG_WARNING, "Forced command '%s'", |
166 continue; | 167 ses.authstate.pubkey_options->forced_command); |
168 goto next_option; | |
167 } | 169 } |
168 ses.authstate.pubkey_options->forced_command[i++] = *opts++; | 170 escaped = (!escaped && c == '\\'); |
169 } | 171 } |
170 if (!*opts) { | 172 dropbear_log(LOG_WARNING, "Badly formatted command= authorized_keys option"); |
171 dropbear_log(LOG_WARNING, | 173 goto bad_option; |
172 "Missing end quote in public key command option"); | 174 } |
173 m_free(ses.authstate.pubkey_options->forced_command); | 175 |
174 ses.authstate.pubkey_options->forced_command = NULL; | 176 next_option: |
175 goto bad_option; | |
176 } | |
177 ses.authstate.pubkey_options->forced_command[i] = '\0'; | |
178 if (strlen(ses.authstate.pubkey_options->forced_command) > MAX_CMD_LEN) { | |
179 dropbear_log(LOG_WARNING, | |
180 "Public key option command too long (>MAX_CMD_LEN)."); | |
181 m_free(ses.authstate.pubkey_options->forced_command); | |
182 ses.authstate.pubkey_options->forced_command = NULL; | |
183 goto bad_option; | |
184 } | |
185 dropbear_log(LOG_WARNING, "Forced command '%s'", | |
186 ses.authstate.pubkey_options->forced_command); | |
187 opts++; | |
188 goto next_option; | |
189 } | |
190 next_option: | |
191 /* | 177 /* |
192 * Skip the comma, and move to the next option | 178 * Skip the comma, and move to the next option |
193 * (or break out if there are no more). | 179 * (or break out if there are no more). |
194 */ | 180 */ |
195 if (!*opts) { | 181 if (options_buf->pos < options_buf->len |
196 TRACE(("Bugs in svr-chansession.c pubkey option processing.")) | 182 && buf_getbyte(options_buf) != ',') { |
197 } | |
198 if (*opts == ' ' || *opts == '\t') { | |
199 break; /* End of options. */ | |
200 } | |
201 if (*opts != ',') { | |
202 goto bad_option; | 183 goto bad_option; |
203 } | 184 } |
204 opts++; | |
205 /* Process the next option. */ | 185 /* Process the next option. */ |
206 } | 186 } |
207 /* parsed all options with no problem */ | 187 /* parsed all options with no problem */ |
208 ret = DROPBEAR_SUCCESS; | 188 ret = DROPBEAR_SUCCESS; |
209 goto end; | 189 goto end; |
210 | 190 |
211 bad_option: | 191 bad_option: |
212 ret = DROPBEAR_FAILURE; | 192 ret = DROPBEAR_FAILURE; |
213 m_free(ses.authstate.pubkey_options); | 193 m_free(ses.authstate.pubkey_options); |
214 ses.authstate.pubkey_options = NULL; | 194 ses.authstate.pubkey_options = NULL; |
215 dropbear_log(LOG_WARNING, "Bad public key options : '%.50s'", opts); | 195 dropbear_log(LOG_WARNING, "Bad public key options at %s:%d", filename, line_num); |
216 | 196 |
217 end: | 197 end: |
218 TRACE(("leave addpubkeyoptions")) | 198 TRACE(("leave addpubkeyoptions")) |
219 return ret; | 199 return ret; |
220 | |
221 } | 200 } |
222 | 201 |
223 #endif | 202 #endif |