Mercurial > dropbear
comparison cli-auth.c @ 1318:10e2a7727253 coverity
merge coverity
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Fri, 22 Jul 2016 00:08:02 +0800 |
parents | 6959c88c8f13 |
children | 06d52bcb8094 |
comparison
equal
deleted
inserted
replaced
1286:7d02b83c61fd | 1318:10e2a7727253 |
---|---|
49 SSH_SERVICE_CONNECTION_LEN); | 49 SSH_SERVICE_CONNECTION_LEN); |
50 buf_putstring(ses.writepayload, "none", 4); /* 'none' method */ | 50 buf_putstring(ses.writepayload, "none", 4); /* 'none' method */ |
51 | 51 |
52 encrypt_packet(); | 52 encrypt_packet(); |
53 | 53 |
54 #ifdef DROPBEAR_CLI_IMMEDIATE_AUTH | 54 #if DROPBEAR_CLI_IMMEDIATE_AUTH |
55 /* We can't haven't two auth requests in-flight with delayed zlib mode | 55 /* We can't haven't two auth requests in-flight with delayed zlib mode |
56 since if the first one succeeds then the remote side will | 56 since if the first one succeeds then the remote side will |
57 expect the second one to be compressed. | 57 expect the second one to be compressed. |
58 Race described at | 58 Race described at |
59 http://www.chiark.greenend.org.uk/~sgtatham/putty/wishlist/zlib-openssh.html | 59 http://www.chiark.greenend.org.uk/~sgtatham/putty/wishlist/zlib-openssh.html |
76 void recv_msg_userauth_banner() { | 76 void recv_msg_userauth_banner() { |
77 | 77 |
78 char* banner = NULL; | 78 char* banner = NULL; |
79 unsigned int bannerlen; | 79 unsigned int bannerlen; |
80 unsigned int i, linecount; | 80 unsigned int i, linecount; |
81 int truncated = 0; | |
81 | 82 |
82 TRACE(("enter recv_msg_userauth_banner")) | 83 TRACE(("enter recv_msg_userauth_banner")) |
83 if (ses.authstate.authdone) { | 84 if (ses.authstate.authdone) { |
84 TRACE(("leave recv_msg_userauth_banner: banner after auth done")) | 85 TRACE(("leave recv_msg_userauth_banner: banner after auth done")) |
85 return; | 86 return; |
88 banner = buf_getstring(ses.payload, &bannerlen); | 89 banner = buf_getstring(ses.payload, &bannerlen); |
89 buf_eatstring(ses.payload); /* The language string */ | 90 buf_eatstring(ses.payload); /* The language string */ |
90 | 91 |
91 if (bannerlen > MAX_BANNER_SIZE) { | 92 if (bannerlen > MAX_BANNER_SIZE) { |
92 TRACE(("recv_msg_userauth_banner: bannerlen too long: %d", bannerlen)) | 93 TRACE(("recv_msg_userauth_banner: bannerlen too long: %d", bannerlen)) |
93 goto out; | 94 truncated = 1; |
94 } | 95 } else { |
95 | 96 cleantext(banner); |
96 cleantext(banner); | 97 |
97 | 98 /* Limit to 24 lines */ |
98 /* Limit to 25 lines */ | 99 linecount = 1; |
99 linecount = 1; | 100 for (i = 0; i < bannerlen; i++) { |
100 for (i = 0; i < bannerlen; i++) { | 101 if (banner[i] == '\n') { |
101 if (banner[i] == '\n') { | 102 if (linecount >= MAX_BANNER_LINES) { |
102 if (linecount >= MAX_BANNER_LINES) { | 103 banner[i] = '\0'; |
103 banner[i] = '\0'; | 104 truncated = 1; |
104 break; | 105 break; |
105 } | 106 } |
106 linecount++; | 107 linecount++; |
107 } | 108 } |
108 } | 109 } |
109 | 110 fprintf(stderr, "%s\n", banner); |
110 fprintf(stderr, "%s\n", banner); | 111 } |
111 | 112 |
112 out: | 113 if (truncated) { |
114 fprintf(stderr, "[Banner from the server is too long]\n"); | |
115 } | |
116 | |
113 m_free(banner); | 117 m_free(banner); |
114 TRACE(("leave recv_msg_userauth_banner")) | 118 TRACE(("leave recv_msg_userauth_banner")) |
115 } | 119 } |
116 | 120 |
117 /* This handles the message-specific types which | 121 /* This handles the message-specific types which |
119 * SSH_MSG_USERAUTH_PASSWD_CHANGEREQ, | 123 * SSH_MSG_USERAUTH_PASSWD_CHANGEREQ, |
120 * SSH_MSG_USERAUTH_PK_OK, & | 124 * SSH_MSG_USERAUTH_PK_OK, & |
121 * SSH_MSG_USERAUTH_INFO_REQUEST. */ | 125 * SSH_MSG_USERAUTH_INFO_REQUEST. */ |
122 void recv_msg_userauth_specific_60() { | 126 void recv_msg_userauth_specific_60() { |
123 | 127 |
124 #ifdef ENABLE_CLI_PUBKEY_AUTH | 128 #if DROPBEAR_CLI_PUBKEY_AUTH |
125 if (cli_ses.lastauthtype == AUTH_TYPE_PUBKEY) { | 129 if (cli_ses.lastauthtype == AUTH_TYPE_PUBKEY) { |
126 recv_msg_userauth_pk_ok(); | 130 recv_msg_userauth_pk_ok(); |
127 return; | 131 return; |
128 } | 132 } |
129 #endif | 133 #endif |
130 | 134 |
131 #ifdef ENABLE_CLI_INTERACT_AUTH | 135 #if DROPBEAR_CLI_INTERACT_AUTH |
132 if (cli_ses.lastauthtype == AUTH_TYPE_INTERACT) { | 136 if (cli_ses.lastauthtype == AUTH_TYPE_INTERACT) { |
133 recv_msg_userauth_info_request(); | 137 recv_msg_userauth_info_request(); |
134 return; | 138 return; |
135 } | 139 } |
136 #endif | 140 #endif |
137 | 141 |
138 #ifdef ENABLE_CLI_PASSWORD_AUTH | 142 #if DROPBEAR_CLI_PASSWORD_AUTH |
139 if (cli_ses.lastauthtype == AUTH_TYPE_PASSWORD) { | 143 if (cli_ses.lastauthtype == AUTH_TYPE_PASSWORD) { |
140 /* Eventually there could be proper password-changing | 144 /* Eventually there could be proper password-changing |
141 * support. However currently few servers seem to | 145 * support. However currently few servers seem to |
142 * implement it, and password auth is last-resort | 146 * implement it, and password auth is last-resort |
143 * regardless - keyboard-interactive is more likely | 147 * regardless - keyboard-interactive is more likely |
177 cli_ses.state = USERAUTH_REQ_SENT; | 181 cli_ses.state = USERAUTH_REQ_SENT; |
178 cli_ses.ignore_next_auth_response = 0; | 182 cli_ses.ignore_next_auth_response = 0; |
179 TRACE(("leave recv_msg_userauth_failure, ignored response, state set to USERAUTH_REQ_SENT")); | 183 TRACE(("leave recv_msg_userauth_failure, ignored response, state set to USERAUTH_REQ_SENT")); |
180 return; | 184 return; |
181 } else { | 185 } else { |
182 #ifdef ENABLE_CLI_PUBKEY_AUTH | 186 #if DROPBEAR_CLI_PUBKEY_AUTH |
183 /* If it was a pubkey auth request, we should cross that key | 187 /* If it was a pubkey auth request, we should cross that key |
184 * off the list. */ | 188 * off the list. */ |
185 if (cli_ses.lastauthtype == AUTH_TYPE_PUBKEY) { | 189 if (cli_ses.lastauthtype == AUTH_TYPE_PUBKEY) { |
186 cli_pubkeyfail(); | 190 cli_pubkeyfail(); |
187 } | 191 } |
188 #endif | 192 #endif |
189 | 193 |
190 #ifdef ENABLE_CLI_INTERACT_AUTH | 194 #if DROPBEAR_CLI_INTERACT_AUTH |
191 /* If we get a failure message for keyboard interactive without | 195 /* If we get a failure message for keyboard interactive without |
192 * receiving any request info packet, then we don't bother trying | 196 * receiving any request info packet, then we don't bother trying |
193 * keyboard interactive again */ | 197 * keyboard interactive again */ |
194 if (cli_ses.lastauthtype == AUTH_TYPE_INTERACT | 198 if (cli_ses.lastauthtype == AUTH_TYPE_INTERACT |
195 && !cli_ses.interact_request_received) { | 199 && !cli_ses.interact_request_received) { |
225 | 229 |
226 tok = methods; /* tok stores the next method we'll compare */ | 230 tok = methods; /* tok stores the next method we'll compare */ |
227 for (i = 0; i <= methlen; i++) { | 231 for (i = 0; i <= methlen; i++) { |
228 if (methods[i] == '\0') { | 232 if (methods[i] == '\0') { |
229 TRACE(("auth method '%s'", tok)) | 233 TRACE(("auth method '%s'", tok)) |
230 #ifdef ENABLE_CLI_PUBKEY_AUTH | 234 #if DROPBEAR_CLI_PUBKEY_AUTH |
231 if (strncmp(AUTH_METHOD_PUBKEY, tok, | 235 if (strncmp(AUTH_METHOD_PUBKEY, tok, |
232 AUTH_METHOD_PUBKEY_LEN) == 0) { | 236 AUTH_METHOD_PUBKEY_LEN) == 0) { |
233 ses.authstate.authtypes |= AUTH_TYPE_PUBKEY; | 237 ses.authstate.authtypes |= AUTH_TYPE_PUBKEY; |
234 } | 238 } |
235 #endif | 239 #endif |
236 #ifdef ENABLE_CLI_INTERACT_AUTH | 240 #if DROPBEAR_CLI_INTERACT_AUTH |
237 if (strncmp(AUTH_METHOD_INTERACT, tok, | 241 if (strncmp(AUTH_METHOD_INTERACT, tok, |
238 AUTH_METHOD_INTERACT_LEN) == 0) { | 242 AUTH_METHOD_INTERACT_LEN) == 0) { |
239 ses.authstate.authtypes |= AUTH_TYPE_INTERACT; | 243 ses.authstate.authtypes |= AUTH_TYPE_INTERACT; |
240 } | 244 } |
241 #endif | 245 #endif |
242 #ifdef ENABLE_CLI_PASSWORD_AUTH | 246 #if DROPBEAR_CLI_PASSWORD_AUTH |
243 if (strncmp(AUTH_METHOD_PASSWORD, tok, | 247 if (strncmp(AUTH_METHOD_PASSWORD, tok, |
244 AUTH_METHOD_PASSWORD_LEN) == 0) { | 248 AUTH_METHOD_PASSWORD_LEN) == 0) { |
245 ses.authstate.authtypes |= AUTH_TYPE_PASSWORD; | 249 ses.authstate.authtypes |= AUTH_TYPE_PASSWORD; |
246 } | 250 } |
247 #endif | 251 #endif |
265 * will enable compression in the transport layer */ | 269 * will enable compression in the transport layer */ |
266 ses.authstate.authdone = 1; | 270 ses.authstate.authdone = 1; |
267 cli_ses.state = USERAUTH_SUCCESS_RCVD; | 271 cli_ses.state = USERAUTH_SUCCESS_RCVD; |
268 cli_ses.lastauthtype = AUTH_TYPE_NONE; | 272 cli_ses.lastauthtype = AUTH_TYPE_NONE; |
269 | 273 |
270 #ifdef ENABLE_CLI_PUBKEY_AUTH | 274 #if DROPBEAR_CLI_PUBKEY_AUTH |
271 cli_auth_pubkey_cleanup(); | 275 cli_auth_pubkey_cleanup(); |
272 #endif | 276 #endif |
273 } | 277 } |
274 | 278 |
275 int cli_auth_try() { | 279 int cli_auth_try() { |
279 | 283 |
280 CHECKCLEARTOWRITE(); | 284 CHECKCLEARTOWRITE(); |
281 | 285 |
282 /* Order to try is pubkey, interactive, password. | 286 /* Order to try is pubkey, interactive, password. |
283 * As soon as "finished" is set for one, we don't do any more. */ | 287 * As soon as "finished" is set for one, we don't do any more. */ |
284 #ifdef ENABLE_CLI_PUBKEY_AUTH | 288 #if DROPBEAR_CLI_PUBKEY_AUTH |
285 if (ses.authstate.authtypes & AUTH_TYPE_PUBKEY) { | 289 if (ses.authstate.authtypes & AUTH_TYPE_PUBKEY) { |
286 finished = cli_auth_pubkey(); | 290 finished = cli_auth_pubkey(); |
287 cli_ses.lastauthtype = AUTH_TYPE_PUBKEY; | 291 cli_ses.lastauthtype = AUTH_TYPE_PUBKEY; |
288 } | 292 } |
289 #endif | 293 #endif |
290 | 294 |
291 #ifdef ENABLE_CLI_PASSWORD_AUTH | 295 #if DROPBEAR_CLI_PASSWORD_AUTH |
292 if (!finished && (ses.authstate.authtypes & AUTH_TYPE_PASSWORD)) { | 296 if (!finished && (ses.authstate.authtypes & AUTH_TYPE_PASSWORD)) { |
293 if (ses.keys->trans.algo_crypt->cipherdesc == NULL) { | 297 if (ses.keys->trans.algo_crypt->cipherdesc == NULL) { |
294 fprintf(stderr, "Sorry, I won't let you use password auth unencrypted.\n"); | 298 fprintf(stderr, "Sorry, I won't let you use password auth unencrypted.\n"); |
295 } else { | 299 } else { |
296 cli_auth_password(); | 300 cli_auth_password(); |
298 cli_ses.lastauthtype = AUTH_TYPE_PASSWORD; | 302 cli_ses.lastauthtype = AUTH_TYPE_PASSWORD; |
299 } | 303 } |
300 } | 304 } |
301 #endif | 305 #endif |
302 | 306 |
303 #ifdef ENABLE_CLI_INTERACT_AUTH | 307 #if DROPBEAR_CLI_INTERACT_AUTH |
304 if (!finished && (ses.authstate.authtypes & AUTH_TYPE_INTERACT)) { | 308 if (!finished && (ses.authstate.authtypes & AUTH_TYPE_INTERACT)) { |
305 if (ses.keys->trans.algo_crypt->cipherdesc == NULL) { | 309 if (ses.keys->trans.algo_crypt->cipherdesc == NULL) { |
306 fprintf(stderr, "Sorry, I won't let you use interactive auth unencrypted.\n"); | 310 fprintf(stderr, "Sorry, I won't let you use interactive auth unencrypted.\n"); |
307 } else { | 311 } else { |
308 if (!cli_ses.auth_interact_failed) { | 312 if (!cli_ses.auth_interact_failed) { |
322 } | 326 } |
323 TRACE(("leave cli_auth_try failure")) | 327 TRACE(("leave cli_auth_try failure")) |
324 return DROPBEAR_FAILURE; | 328 return DROPBEAR_FAILURE; |
325 } | 329 } |
326 | 330 |
327 #if defined(ENABLE_CLI_PASSWORD_AUTH) || defined(ENABLE_CLI_INTERACT_AUTH) | 331 #if DROPBEAR_CLI_PASSWORD_AUTH || DROPBEAR_CLI_INTERACT_AUTH |
328 /* A helper for getpass() that exits if the user cancels. The returned | 332 /* A helper for getpass() that exits if the user cancels. The returned |
329 * password is statically allocated by getpass() */ | 333 * password is statically allocated by getpass() */ |
330 char* getpass_or_cancel(char* prompt) | 334 char* getpass_or_cancel(char* prompt) |
331 { | 335 { |
332 char* password = NULL; | 336 char* password = NULL; |