Mercurial > dropbear
comparison cli-auth.c @ 293:9d110777f345 contrib-blacklist
propagate from branch 'au.asn.ucc.matt.dropbear' (head 7ad1775ed65e75dbece27fe6b65bf1a234db386a)
to branch 'au.asn.ucc.matt.dropbear.contrib.blacklist' (head 1d86a4f0a401cc68c2670d821a2f6366c37af143)
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Fri, 10 Mar 2006 06:31:29 +0000 |
parents | 475a818dd6e7 |
children | 64abb124763d baea1d43e7eb |
comparison
equal
deleted
inserted
replaced
247:c07de41b53d7 | 293:9d110777f345 |
---|---|
30 #include "buffer.h" | 30 #include "buffer.h" |
31 #include "ssh.h" | 31 #include "ssh.h" |
32 #include "packet.h" | 32 #include "packet.h" |
33 #include "runopts.h" | 33 #include "runopts.h" |
34 | 34 |
35 | |
36 void cli_authinitialise() { | 35 void cli_authinitialise() { |
37 | 36 |
38 memset(&ses.authstate, 0, sizeof(ses.authstate)); | 37 memset(&ses.authstate, 0, sizeof(ses.authstate)); |
39 } | 38 } |
40 | 39 |
97 out: | 96 out: |
98 m_free(banner); | 97 m_free(banner); |
99 TRACE(("leave recv_msg_userauth_banner")) | 98 TRACE(("leave recv_msg_userauth_banner")) |
100 } | 99 } |
101 | 100 |
101 /* This handles the message-specific types which | |
102 * all have a value of 60. These are | |
103 * SSH_MSG_USERAUTH_PASSWD_CHANGEREQ, | |
104 * SSH_MSG_USERAUTH_PK_OK, & | |
105 * SSH_MSG_USERAUTH_INFO_REQUEST. */ | |
106 void recv_msg_userauth_specific_60() { | |
107 | |
108 #ifdef ENABLE_CLI_PUBKEY_AUTH | |
109 if (cli_ses.lastauthtype == AUTH_TYPE_PUBKEY) { | |
110 recv_msg_userauth_pk_ok(); | |
111 return; | |
112 } | |
113 #endif | |
114 | |
115 #ifdef ENABLE_CLI_INTERACT_AUTH | |
116 if (cli_ses.lastauthtype == AUTH_TYPE_INTERACT) { | |
117 recv_msg_userauth_info_request(); | |
118 return; | |
119 } | |
120 #endif | |
121 | |
122 #ifdef ENABLE_CLI_PASSWORD_AUTH | |
123 if (cli_ses.lastauthtype == AUTH_TYPE_PASSWORD) { | |
124 /* Eventually there could be proper password-changing | |
125 * support. However currently few servers seem to | |
126 * implement it, and password auth is last-resort | |
127 * regardless - keyboard-interactive is more likely | |
128 * to be used anyway. */ | |
129 dropbear_close("Your password has expired."); | |
130 } | |
131 #endif | |
132 | |
133 dropbear_exit("Unexpected userauth packet"); | |
134 } | |
102 | 135 |
103 void recv_msg_userauth_failure() { | 136 void recv_msg_userauth_failure() { |
104 | 137 |
105 unsigned char * methods = NULL; | 138 unsigned char * methods = NULL; |
106 unsigned char * tok = NULL; | 139 unsigned char * tok = NULL; |
111 TRACE(("<- MSG_USERAUTH_FAILURE")) | 144 TRACE(("<- MSG_USERAUTH_FAILURE")) |
112 TRACE(("enter recv_msg_userauth_failure")) | 145 TRACE(("enter recv_msg_userauth_failure")) |
113 | 146 |
114 if (cli_ses.state != USERAUTH_REQ_SENT) { | 147 if (cli_ses.state != USERAUTH_REQ_SENT) { |
115 /* Perhaps we should be more fatal? */ | 148 /* Perhaps we should be more fatal? */ |
116 TRACE(("But we didn't send a userauth request!!!!!!")) | 149 dropbear_exit("Unexpected userauth failure"); |
117 return; | |
118 } | 150 } |
119 | 151 |
120 #ifdef ENABLE_CLI_PUBKEY_AUTH | 152 #ifdef ENABLE_CLI_PUBKEY_AUTH |
121 /* If it was a pubkey auth request, we should cross that key | 153 /* If it was a pubkey auth request, we should cross that key |
122 * off the list. */ | 154 * off the list. */ |
123 if (cli_ses.lastauthtype == AUTH_TYPE_PUBKEY) { | 155 if (cli_ses.lastauthtype == AUTH_TYPE_PUBKEY) { |
124 cli_pubkeyfail(); | 156 cli_pubkeyfail(); |
125 } | 157 } |
126 #endif | 158 #endif |
127 | 159 |
160 #ifdef ENABLE_CLI_INTERACT_AUTH | |
161 /* If we get a failure message for keyboard interactive without | |
162 * receiving any request info packet, then we don't bother trying | |
163 * keyboard interactive again */ | |
164 if (cli_ses.lastauthtype == AUTH_TYPE_INTERACT | |
165 && !cli_ses.interact_request_received) { | |
166 TRACE(("setting auth_interact_failed = 1")) | |
167 cli_ses.auth_interact_failed = 1; | |
168 } | |
169 #endif | |
170 | |
171 cli_ses.lastauthtype = AUTH_TYPE_NONE; | |
172 | |
128 methods = buf_getstring(ses.payload, &methlen); | 173 methods = buf_getstring(ses.payload, &methlen); |
129 | 174 |
130 partial = buf_getbool(ses.payload); | 175 partial = buf_getbool(ses.payload); |
131 | 176 |
132 if (partial) { | 177 if (partial) { |
155 if (strncmp(AUTH_METHOD_PUBKEY, tok, | 200 if (strncmp(AUTH_METHOD_PUBKEY, tok, |
156 AUTH_METHOD_PUBKEY_LEN) == 0) { | 201 AUTH_METHOD_PUBKEY_LEN) == 0) { |
157 ses.authstate.authtypes |= AUTH_TYPE_PUBKEY; | 202 ses.authstate.authtypes |= AUTH_TYPE_PUBKEY; |
158 } | 203 } |
159 #endif | 204 #endif |
205 #ifdef ENABLE_CLI_INTERACT_AUTH | |
206 if (strncmp(AUTH_METHOD_INTERACT, tok, | |
207 AUTH_METHOD_INTERACT_LEN) == 0) { | |
208 ses.authstate.authtypes |= AUTH_TYPE_INTERACT; | |
209 } | |
210 #endif | |
160 #ifdef ENABLE_CLI_PASSWORD_AUTH | 211 #ifdef ENABLE_CLI_PASSWORD_AUTH |
161 if (strncmp(AUTH_METHOD_PASSWORD, tok, | 212 if (strncmp(AUTH_METHOD_PASSWORD, tok, |
162 AUTH_METHOD_PASSWORD_LEN) == 0) { | 213 AUTH_METHOD_PASSWORD_LEN) == 0) { |
163 ses.authstate.authtypes |= AUTH_TYPE_PASSWORD; | 214 ses.authstate.authtypes |= AUTH_TYPE_PASSWORD; |
164 } | 215 } |
178 | 229 |
179 void recv_msg_userauth_success() { | 230 void recv_msg_userauth_success() { |
180 TRACE(("received msg_userauth_success")) | 231 TRACE(("received msg_userauth_success")) |
181 ses.authstate.authdone = 1; | 232 ses.authstate.authdone = 1; |
182 cli_ses.state = USERAUTH_SUCCESS_RCVD; | 233 cli_ses.state = USERAUTH_SUCCESS_RCVD; |
234 cli_ses.lastauthtype = AUTH_TYPE_NONE; | |
183 } | 235 } |
184 | 236 |
185 void cli_auth_try() { | 237 void cli_auth_try() { |
186 | 238 |
187 TRACE(("enter cli_auth_try")) | 239 TRACE(("enter cli_auth_try")) |
188 int finished = 0; | 240 int finished = 0; |
189 | 241 |
190 CHECKCLEARTOWRITE(); | 242 CHECKCLEARTOWRITE(); |
191 | 243 |
192 /* XXX We hardcode that we try a pubkey first */ | 244 /* Order to try is pubkey, interactive, password. |
245 * As soon as "finished" is set for one, we don't do any more. */ | |
193 #ifdef ENABLE_CLI_PUBKEY_AUTH | 246 #ifdef ENABLE_CLI_PUBKEY_AUTH |
194 if (ses.authstate.authtypes & AUTH_TYPE_PUBKEY) { | 247 if (ses.authstate.authtypes & AUTH_TYPE_PUBKEY) { |
195 finished = cli_auth_pubkey(); | 248 finished = cli_auth_pubkey(); |
196 cli_ses.lastauthtype = AUTH_TYPE_PUBKEY; | 249 cli_ses.lastauthtype = AUTH_TYPE_PUBKEY; |
197 } | 250 } |
198 #endif | 251 #endif |
199 | 252 |
253 #ifdef ENABLE_CLI_INTERACT_AUTH | |
254 if (!finished && ses.authstate.authtypes & AUTH_TYPE_INTERACT) { | |
255 if (cli_ses.auth_interact_failed) { | |
256 finished = 0; | |
257 } else { | |
258 cli_auth_interactive(); | |
259 cli_ses.lastauthtype = AUTH_TYPE_INTERACT; | |
260 finished = 1; | |
261 } | |
262 } | |
263 #endif | |
264 | |
200 #ifdef ENABLE_CLI_PASSWORD_AUTH | 265 #ifdef ENABLE_CLI_PASSWORD_AUTH |
201 if (!finished && ses.authstate.authtypes & AUTH_TYPE_PASSWORD) { | 266 if (!finished && ses.authstate.authtypes & AUTH_TYPE_PASSWORD) { |
202 finished = cli_auth_password(); | 267 cli_auth_password(); |
268 finished = 1; | |
203 cli_ses.lastauthtype = AUTH_TYPE_PASSWORD; | 269 cli_ses.lastauthtype = AUTH_TYPE_PASSWORD; |
204 } | 270 } |
205 #endif | 271 #endif |
272 | |
273 TRACE(("cli_auth_try lastauthtype %d", cli_ses.lastauthtype)) | |
206 | 274 |
207 if (!finished) { | 275 if (!finished) { |
208 dropbear_exit("No auth methods could be used."); | 276 dropbear_exit("No auth methods could be used."); |
209 } | 277 } |
210 | 278 |
211 TRACE(("leave cli_auth_try")) | 279 TRACE(("leave cli_auth_try")) |
212 } | 280 } |
281 | |
282 /* A helper for getpass() that exits if the user cancels. The returned | |
283 * password is statically allocated by getpass() */ | |
284 char* getpass_or_cancel() | |
285 { | |
286 char* password = NULL; | |
287 | |
288 password = getpass("Password: "); | |
289 | |
290 /* 0x03 is a ctrl-c character in the buffer. */ | |
291 if (password == NULL || strchr(password, '\3') != NULL) { | |
292 dropbear_close("Interrupted."); | |
293 } | |
294 return password; | |
295 } |