comparison cli-auth.c @ 883:ff597bf2cfb0

DROPBEAR_CLI_AUTH_IMMEDIATE fixed, now enabled by default
author Matt Johnston <matt@ucc.asn.au>
date Fri, 17 Jan 2014 21:39:27 +0800
parents 619b1ed837fd
children 7032deca6b90
comparison
equal deleted inserted replaced
882:f05107560aa9 883:ff597bf2cfb0
39 39
40 40
41 /* Send a "none" auth request to get available methods */ 41 /* Send a "none" auth request to get available methods */
42 void cli_auth_getmethods() { 42 void cli_auth_getmethods() {
43 TRACE(("enter cli_auth_getmethods")) 43 TRACE(("enter cli_auth_getmethods"))
44 #ifdef CLI_IMMEDIATE_AUTH
45 ses.authstate.authtypes = AUTH_TYPE_PUBKEY;
46 if (getenv(DROPBEAR_PASSWORD_ENV)) {
47 ses.authstate.authtypes |= AUTH_TYPE_PASSWORD | AUTH_TYPE_INTERACT;
48 }
49 if (cli_auth_try() == DROPBEAR_SUCCESS) {
50 TRACE(("skipped initial none auth query"))
51 return;
52 }
53 #endif
54 CHECKCLEARTOWRITE(); 44 CHECKCLEARTOWRITE();
55 buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST); 45 buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST);
56 buf_putstring(ses.writepayload, cli_opts.username, 46 buf_putstring(ses.writepayload, cli_opts.username,
57 strlen(cli_opts.username)); 47 strlen(cli_opts.username));
58 buf_putstring(ses.writepayload, SSH_SERVICE_CONNECTION, 48 buf_putstring(ses.writepayload, SSH_SERVICE_CONNECTION,
59 SSH_SERVICE_CONNECTION_LEN); 49 SSH_SERVICE_CONNECTION_LEN);
60 buf_putstring(ses.writepayload, "none", 4); /* 'none' method */ 50 buf_putstring(ses.writepayload, "none", 4); /* 'none' method */
61 51
62 encrypt_packet(); 52 encrypt_packet();
53
54 #ifdef DROPBEAR_CLI_IMMEDIATE_AUTH
55 ses.authstate.authtypes = AUTH_TYPE_PUBKEY;
56 if (getenv(DROPBEAR_PASSWORD_ENV)) {
57 ses.authstate.authtypes |= AUTH_TYPE_PASSWORD | AUTH_TYPE_INTERACT;
58 }
59 if (cli_auth_try() == DROPBEAR_SUCCESS) {
60 TRACE(("skipped initial none auth query"))
61 /* Note that there will be two auth responses in-flight */
62 cli_ses.ignore_next_auth_response = 1;
63 }
64 #endif
63 TRACE(("leave cli_auth_getmethods")) 65 TRACE(("leave cli_auth_getmethods"))
64 } 66 }
65 67
66 void recv_msg_userauth_banner() { 68 void recv_msg_userauth_banner() {
67 69
148 unsigned int i = 0; 150 unsigned int i = 0;
149 151
150 TRACE(("<- MSG_USERAUTH_FAILURE")) 152 TRACE(("<- MSG_USERAUTH_FAILURE"))
151 TRACE(("enter recv_msg_userauth_failure")) 153 TRACE(("enter recv_msg_userauth_failure"))
152 154
155 if (ses.authstate.authdone) {
156 TRACE(("leave recv_msg_userauth_failure, already authdone."))
157 return;
158 }
159
153 if (cli_ses.state != USERAUTH_REQ_SENT) { 160 if (cli_ses.state != USERAUTH_REQ_SENT) {
154 /* Perhaps we should be more fatal? */ 161 /* Perhaps we should be more fatal? */
155 dropbear_exit("Unexpected userauth failure"); 162 dropbear_exit("Unexpected userauth failure");
156 } 163 }
157 164
158 #ifdef ENABLE_CLI_PUBKEY_AUTH 165 /* When DROPBEAR_CLI_IMMEDIATE_AUTH is set there will be an initial response for
159 /* If it was a pubkey auth request, we should cross that key 166 the "none" auth request, and then a response to the immediate auth request.
160 * off the list. */ 167 We need to be careful handling them. */
161 if (cli_ses.lastauthtype == AUTH_TYPE_PUBKEY) { 168 if (cli_ses.ignore_next_auth_response) {
162 cli_pubkeyfail(); 169 TRACE(("ignore next response, state set to USERAUTH_REQ_SENT"))
163 } 170 cli_ses.state = USERAUTH_REQ_SENT;
171 } else {
172 cli_ses.state = USERAUTH_FAIL_RCVD;
173 cli_ses.lastauthtype = AUTH_TYPE_NONE;
174 #ifdef ENABLE_CLI_PUBKEY_AUTH
175 /* If it was a pubkey auth request, we should cross that key
176 * off the list. */
177 if (cli_ses.lastauthtype == AUTH_TYPE_PUBKEY) {
178 cli_pubkeyfail();
179 }
164 #endif 180 #endif
165 181
166 #ifdef ENABLE_CLI_INTERACT_AUTH 182 #ifdef ENABLE_CLI_INTERACT_AUTH
167 /* If we get a failure message for keyboard interactive without 183 /* If we get a failure message for keyboard interactive without
168 * receiving any request info packet, then we don't bother trying 184 * receiving any request info packet, then we don't bother trying
169 * keyboard interactive again */ 185 * keyboard interactive again */
170 if (cli_ses.lastauthtype == AUTH_TYPE_INTERACT 186 if (cli_ses.lastauthtype == AUTH_TYPE_INTERACT
171 && !cli_ses.interact_request_received) { 187 && !cli_ses.interact_request_received) {
172 TRACE(("setting auth_interact_failed = 1")) 188 TRACE(("setting auth_interact_failed = 1"))
173 cli_ses.auth_interact_failed = 1; 189 cli_ses.auth_interact_failed = 1;
174 } 190 }
175 #endif 191 #endif
176 192 }
177 cli_ses.lastauthtype = AUTH_TYPE_NONE; 193
194 cli_ses.ignore_next_auth_response = 0;
178 195
179 methods = buf_getstring(ses.payload, &methlen); 196 methods = buf_getstring(ses.payload, &methlen);
180 197
181 partial = buf_getbool(ses.payload); 198 partial = buf_getbool(ses.payload);
182 199
225 undefined */ 242 undefined */
226 } 243 }
227 } 244 }
228 245
229 m_free(methods); 246 m_free(methods);
230
231 cli_ses.state = USERAUTH_FAIL_RCVD;
232 247
233 TRACE(("leave recv_msg_userauth_failure")) 248 TRACE(("leave recv_msg_userauth_failure"))
234 } 249 }
235 250
236 void recv_msg_userauth_success() { 251 void recv_msg_userauth_success() {
252 /* This function can validly get called multiple times
253 if DROPBEAR_CLI_IMMEDIATE_AUTH is set */
254
237 TRACE(("received msg_userauth_success")) 255 TRACE(("received msg_userauth_success"))
238 /* Note: in delayed-zlib mode, setting authdone here 256 /* Note: in delayed-zlib mode, setting authdone here
239 * will enable compression in the transport layer */ 257 * will enable compression in the transport layer */
240 ses.authstate.authdone = 1; 258 ses.authstate.authdone = 1;
241 cli_ses.state = USERAUTH_SUCCESS_RCVD; 259 cli_ses.state = USERAUTH_SUCCESS_RCVD;