Use correct method for string comparison
[TortoiseGit.git] / src / TortoisePlink / ssh2userauth.c
blob26dc30d1ccdb1648ae91cf1b07c206d7aaf4d173
1 /*
2 * Packet protocol layer for the client side of the SSH-2 userauth
3 * protocol (RFC 4252).
4 */
6 #include <assert.h>
8 #include "putty.h"
9 #include "ssh.h"
10 #include "sshbpp.h"
11 #include "sshppl.h"
12 #include "sshcr.h"
14 #ifndef NO_GSSAPI
15 #include "sshgssc.h"
16 #include "sshgss.h"
17 #endif
19 #define BANNER_LIMIT 131072
21 typedef struct agent_key {
22 strbuf *blob, *comment;
23 ptrlen algorithm;
24 } agent_key;
26 struct ssh2_userauth_state {
27 int crState;
29 PacketProtocolLayer *transport_layer, *successor_layer;
30 Filename *keyfile;
31 bool show_banner, tryagent, notrivialauth, change_username;
32 char *hostname, *fullhostname;
33 char *default_username;
34 bool try_ki_auth, try_gssapi_auth, try_gssapi_kex_auth, gssapi_fwd;
36 ptrlen session_id;
37 enum {
38 AUTH_TYPE_NONE,
39 AUTH_TYPE_PUBLICKEY,
40 AUTH_TYPE_PUBLICKEY_OFFER_LOUD,
41 AUTH_TYPE_PUBLICKEY_OFFER_QUIET,
42 AUTH_TYPE_PASSWORD,
43 AUTH_TYPE_GSSAPI, /* always QUIET */
44 AUTH_TYPE_KEYBOARD_INTERACTIVE,
45 AUTH_TYPE_KEYBOARD_INTERACTIVE_QUIET
46 } type;
47 bool need_pw, can_pubkey, can_passwd, can_keyb_inter;
48 int userpass_ret;
49 bool tried_pubkey_config, done_agent;
50 struct ssh_connection_shared_gss_state *shgss;
51 #ifndef NO_GSSAPI
52 bool can_gssapi;
53 bool can_gssapi_keyex_auth;
54 bool tried_gssapi;
55 bool tried_gssapi_keyex_auth;
56 time_t gss_cred_expiry;
57 Ssh_gss_buf gss_buf;
58 Ssh_gss_buf gss_rcvtok, gss_sndtok;
59 Ssh_gss_stat gss_stat;
60 #endif
61 bool suppress_wait_for_response_packet;
62 strbuf *last_methods_string;
63 bool kbd_inter_refused;
64 prompts_t *cur_prompt;
65 uint32_t num_prompts;
66 const char *username;
67 char *locally_allocated_username;
68 char *password;
69 bool got_username;
70 strbuf *publickey_blob;
71 bool privatekey_available, privatekey_encrypted;
72 char *publickey_algorithm;
73 char *publickey_comment;
74 void *agent_response_to_free;
75 ptrlen agent_response;
76 BinarySource asrc[1]; /* for reading SSH agent response */
77 size_t agent_keys_len;
78 agent_key *agent_keys;
79 size_t agent_key_index, agent_key_limit;
80 ptrlen agent_keyalg;
81 unsigned signflags;
82 int len;
83 PktOut *pktout;
84 bool want_user_input;
85 bool is_trivial_auth;
87 agent_pending_query *auth_agent_query;
88 bufchain banner;
89 bufchain_sink banner_bs;
90 StripCtrlChars *banner_scc;
91 bool banner_scc_initialised;
93 StripCtrlChars *ki_scc;
94 bool ki_scc_initialised;
95 bool ki_printed_header;
97 PacketProtocolLayer ppl;
100 static void ssh2_userauth_free(PacketProtocolLayer *);
101 static void ssh2_userauth_process_queue(PacketProtocolLayer *);
102 static bool ssh2_userauth_get_specials(
103 PacketProtocolLayer *ppl, add_special_fn_t add_special, void *ctx);
104 static void ssh2_userauth_special_cmd(PacketProtocolLayer *ppl,
105 SessionSpecialCode code, int arg);
106 static bool ssh2_userauth_want_user_input(PacketProtocolLayer *ppl);
107 static void ssh2_userauth_got_user_input(PacketProtocolLayer *ppl);
108 static void ssh2_userauth_reconfigure(PacketProtocolLayer *ppl, Conf *conf);
110 static void ssh2_userauth_agent_query(struct ssh2_userauth_state *, strbuf *);
111 static void ssh2_userauth_agent_callback(void *, void *, int);
112 static void ssh2_userauth_add_sigblob(
113 struct ssh2_userauth_state *s, PktOut *pkt, ptrlen pkblob, ptrlen sigblob);
114 static void ssh2_userauth_add_session_id(
115 struct ssh2_userauth_state *s, strbuf *sigdata);
116 #ifndef NO_GSSAPI
117 static PktOut *ssh2_userauth_gss_packet(
118 struct ssh2_userauth_state *s, const char *authtype);
119 #endif
120 static void ssh2_userauth_antispoof_msg(
121 struct ssh2_userauth_state *s, const char *msg);
123 static const PacketProtocolLayerVtable ssh2_userauth_vtable = {
124 .free = ssh2_userauth_free,
125 .process_queue = ssh2_userauth_process_queue,
126 .get_specials = ssh2_userauth_get_specials,
127 .special_cmd = ssh2_userauth_special_cmd,
128 .want_user_input = ssh2_userauth_want_user_input,
129 .got_user_input = ssh2_userauth_got_user_input,
130 .reconfigure = ssh2_userauth_reconfigure,
131 .queued_data_size = ssh_ppl_default_queued_data_size,
132 .name = "ssh-userauth",
135 PacketProtocolLayer *ssh2_userauth_new(
136 PacketProtocolLayer *successor_layer,
137 const char *hostname, const char *fullhostname,
138 Filename *keyfile, bool show_banner, bool tryagent, bool notrivialauth,
139 const char *default_username, bool change_username,
140 bool try_ki_auth, bool try_gssapi_auth, bool try_gssapi_kex_auth,
141 bool gssapi_fwd, struct ssh_connection_shared_gss_state *shgss)
143 struct ssh2_userauth_state *s = snew(struct ssh2_userauth_state);
144 memset(s, 0, sizeof(*s));
145 s->ppl.vt = &ssh2_userauth_vtable;
147 s->successor_layer = successor_layer;
148 s->hostname = dupstr(hostname);
149 s->fullhostname = dupstr(fullhostname);
150 s->keyfile = filename_copy(keyfile);
151 s->show_banner = show_banner;
152 s->tryagent = tryagent;
153 s->notrivialauth = notrivialauth;
154 s->default_username = dupstr(default_username);
155 s->change_username = change_username;
156 s->try_ki_auth = try_ki_auth;
157 s->try_gssapi_auth = try_gssapi_auth;
158 s->try_gssapi_kex_auth = try_gssapi_kex_auth;
159 s->gssapi_fwd = gssapi_fwd;
160 s->shgss = shgss;
161 s->last_methods_string = strbuf_new();
162 s->is_trivial_auth = true;
163 bufchain_init(&s->banner);
164 bufchain_sink_init(&s->banner_bs, &s->banner);
166 return &s->ppl;
169 void ssh2_userauth_set_transport_layer(PacketProtocolLayer *userauth,
170 PacketProtocolLayer *transport)
172 struct ssh2_userauth_state *s =
173 container_of(userauth, struct ssh2_userauth_state, ppl);
174 s->transport_layer = transport;
177 static void ssh2_userauth_free(PacketProtocolLayer *ppl)
179 struct ssh2_userauth_state *s =
180 container_of(ppl, struct ssh2_userauth_state, ppl);
181 bufchain_clear(&s->banner);
183 if (s->successor_layer)
184 ssh_ppl_free(s->successor_layer);
186 if (s->agent_keys) {
187 for (size_t i = 0; i < s->agent_keys_len; i++) {
188 strbuf_free(s->agent_keys[i].blob);
189 strbuf_free(s->agent_keys[i].comment);
191 sfree(s->agent_keys);
193 sfree(s->agent_response_to_free);
194 if (s->auth_agent_query)
195 agent_cancel_query(s->auth_agent_query);
196 filename_free(s->keyfile);
197 sfree(s->default_username);
198 sfree(s->locally_allocated_username);
199 sfree(s->hostname);
200 sfree(s->fullhostname);
201 sfree(s->publickey_comment);
202 sfree(s->publickey_algorithm);
203 if (s->publickey_blob)
204 strbuf_free(s->publickey_blob);
205 strbuf_free(s->last_methods_string);
206 if (s->banner_scc)
207 stripctrl_free(s->banner_scc);
208 if (s->ki_scc)
209 stripctrl_free(s->ki_scc);
210 sfree(s);
213 static void ssh2_userauth_filter_queue(struct ssh2_userauth_state *s)
215 PktIn *pktin;
216 ptrlen string;
218 while ((pktin = pq_peek(s->ppl.in_pq)) != NULL) {
219 switch (pktin->type) {
220 case SSH2_MSG_USERAUTH_BANNER:
221 if (!s->show_banner) {
222 pq_pop(s->ppl.in_pq);
223 break;
226 string = get_string(pktin);
227 if (string.len > BANNER_LIMIT - bufchain_size(&s->banner))
228 string.len = BANNER_LIMIT - bufchain_size(&s->banner);
229 if (!s->banner_scc_initialised) {
230 s->banner_scc = seat_stripctrl_new(
231 s->ppl.seat, BinarySink_UPCAST(&s->banner_bs), SIC_BANNER);
232 if (s->banner_scc)
233 stripctrl_enable_line_limiting(s->banner_scc);
234 s->banner_scc_initialised = true;
236 if (s->banner_scc)
237 put_datapl(s->banner_scc, string);
238 else
239 put_datapl(&s->banner_bs, string);
240 pq_pop(s->ppl.in_pq);
241 break;
243 default:
244 return;
249 static PktIn *ssh2_userauth_pop(struct ssh2_userauth_state *s)
251 ssh2_userauth_filter_queue(s);
252 return pq_pop(s->ppl.in_pq);
255 static void ssh2_userauth_process_queue(PacketProtocolLayer *ppl)
257 struct ssh2_userauth_state *s =
258 container_of(ppl, struct ssh2_userauth_state, ppl);
259 PktIn *pktin;
261 ssh2_userauth_filter_queue(s); /* no matter why we were called */
263 crBegin(s->crState);
265 #ifndef NO_GSSAPI
266 s->tried_gssapi = false;
267 s->tried_gssapi_keyex_auth = false;
268 #endif
271 * Misc one-time setup for authentication.
273 s->publickey_blob = NULL;
274 s->session_id = ssh2_transport_get_session_id(s->transport_layer);
277 * Load the public half of any configured public key file for
278 * later use.
280 if (!filename_is_null(s->keyfile)) {
281 int keytype;
282 ppl_logevent("Reading key file \"%s\"",
283 filename_to_str(s->keyfile));
284 keytype = key_type(s->keyfile);
285 if (keytype == SSH_KEYTYPE_SSH2 ||
286 keytype == SSH_KEYTYPE_SSH2_PUBLIC_RFC4716 ||
287 keytype == SSH_KEYTYPE_SSH2_PUBLIC_OPENSSH) {
288 const char *error;
289 s->publickey_blob = strbuf_new();
290 if (ppk_loadpub_f(s->keyfile, &s->publickey_algorithm,
291 BinarySink_UPCAST(s->publickey_blob),
292 &s->publickey_comment, &error)) {
293 s->privatekey_available = (keytype == SSH_KEYTYPE_SSH2);
294 if (!s->privatekey_available)
295 ppl_logevent("Key file contains public key only");
296 s->privatekey_encrypted = ppk_encrypted_f(s->keyfile, NULL);
297 } else {
298 ppl_logevent("Unable to load key (%s)", error);
299 ppl_printf("Unable to load key file \"%s\" (%s)\r\n",
300 filename_to_str(s->keyfile), error);
301 strbuf_free(s->publickey_blob);
302 s->publickey_blob = NULL;
304 } else {
305 ppl_logevent("Unable to use this key file (%s)",
306 key_type_to_str(keytype));
307 ppl_printf("Unable to use key file \"%s\" (%s)\r\n",
308 filename_to_str(s->keyfile),
309 key_type_to_str(keytype));
310 s->publickey_blob = NULL;
315 * Find out about any keys Pageant has (but if there's a public
316 * key configured, filter out all others).
318 if (s->tryagent && agent_exists()) {
319 ppl_logevent("Pageant is running. Requesting keys.");
321 /* Request the keys held by the agent. */
323 strbuf *request = strbuf_new_for_agent_query();
324 put_byte(request, SSH2_AGENTC_REQUEST_IDENTITIES);
325 ssh2_userauth_agent_query(s, request);
326 strbuf_free(request);
327 crWaitUntilV(!s->auth_agent_query);
329 BinarySource_BARE_INIT_PL(s->asrc, s->agent_response);
331 get_uint32(s->asrc); /* skip length field */
332 if (get_byte(s->asrc) == SSH2_AGENT_IDENTITIES_ANSWER) {
333 size_t nkeys = get_uint32(s->asrc);
334 size_t origpos = s->asrc->pos;
337 * Check that the agent response is well formed.
339 for (size_t i = 0; i < nkeys; i++) {
340 get_string(s->asrc); /* blob */
341 get_string(s->asrc); /* comment */
342 if (get_err(s->asrc)) {
343 ppl_logevent("Pageant's response was truncated");
344 goto done_agent_query;
349 * Copy the list of public-key blobs out of the Pageant
350 * response.
352 BinarySource_REWIND_TO(s->asrc, origpos);
353 s->agent_keys_len = nkeys;
354 s->agent_keys = snewn(s->agent_keys_len, agent_key);
355 for (size_t i = 0; i < nkeys; i++) {
356 s->agent_keys[i].blob = strbuf_new();
357 put_datapl(s->agent_keys[i].blob, get_string(s->asrc));
358 s->agent_keys[i].comment = strbuf_new();
359 put_datapl(s->agent_keys[i].comment, get_string(s->asrc));
361 /* Also, extract the algorithm string from the start
362 * of the public-key blob. */
363 BinarySource src[1];
364 BinarySource_BARE_INIT_PL(src, ptrlen_from_strbuf(
365 s->agent_keys[i].blob));
366 s->agent_keys[i].algorithm = get_string(src);
369 ppl_logevent("Pageant has %"SIZEu" SSH-2 keys", nkeys);
371 if (s->publickey_blob) {
373 * If we've been given a specific public key blob,
374 * filter the list of keys to try from the agent down
375 * to only that one, or none if it's not there.
377 ptrlen our_blob = ptrlen_from_strbuf(s->publickey_blob);
378 size_t i;
380 for (i = 0; i < nkeys; i++) {
381 if (ptrlen_eq_ptrlen(our_blob, ptrlen_from_strbuf(
382 s->agent_keys[i].blob)))
383 break;
386 if (i < nkeys) {
387 ppl_logevent("Pageant key #%"SIZEu" matches "
388 "configured key file", i);
389 s->agent_key_index = i;
390 s->agent_key_limit = i+1;
391 } else {
392 ppl_logevent("Configured key file not in Pageant");
393 s->agent_key_index = 0;
394 s->agent_key_limit = 0;
396 } else {
398 * Otherwise, try them all.
400 s->agent_key_index = 0;
401 s->agent_key_limit = nkeys;
403 } else {
404 ppl_logevent("Failed to get reply from Pageant");
406 done_agent_query:;
410 * We repeat this whole loop, including the username prompt,
411 * until we manage a successful authentication. If the user
412 * types the wrong _password_, they can be sent back to the
413 * beginning to try another username, if this is configured on.
414 * (If they specify a username in the config, they are never
415 * asked, even if they do give a wrong password.)
417 * I think this best serves the needs of
419 * - the people who have no configuration, no keys, and just
420 * want to try repeated (username,password) pairs until they
421 * type both correctly
423 * - people who have keys and configuration but occasionally
424 * need to fall back to passwords
426 * - people with a key held in Pageant, who might not have
427 * logged in to a particular machine before; so they want to
428 * type a username, and then _either_ their key will be
429 * accepted, _or_ they will type a password. If they mistype
430 * the username they will want to be able to get back and
431 * retype it!
433 s->got_username = false;
434 while (1) {
436 * Get a username.
438 if (s->got_username && !s->change_username) {
440 * We got a username last time round this loop, and
441 * with change_username turned off we don't try to get
442 * it again.
444 } else if ((s->username = s->default_username) == NULL) {
445 s->cur_prompt = new_prompts();
446 s->cur_prompt->to_server = true;
447 s->cur_prompt->from_server = false;
448 s->cur_prompt->name = dupstr("SSH login name");
449 add_prompt(s->cur_prompt, dupstr("login as: "), true);
450 s->userpass_ret = seat_get_userpass_input(
451 s->ppl.seat, s->cur_prompt, NULL);
452 while (1) {
453 while (s->userpass_ret < 0 &&
454 bufchain_size(s->ppl.user_input) > 0)
455 s->userpass_ret = seat_get_userpass_input(
456 s->ppl.seat, s->cur_prompt, s->ppl.user_input);
458 if (s->userpass_ret >= 0)
459 break;
461 s->want_user_input = true;
462 crReturnV;
463 s->want_user_input = false;
465 if (!s->userpass_ret) {
467 * seat_get_userpass_input() failed to get a username.
468 * Terminate.
470 free_prompts(s->cur_prompt);
471 ssh_user_close(s->ppl.ssh, "No username provided");
472 return;
474 sfree(s->locally_allocated_username); /* for change_username */
475 s->username = s->locally_allocated_username =
476 prompt_get_result(s->cur_prompt->prompts[0]);
477 free_prompts(s->cur_prompt);
478 } else {
479 if (seat_verbose(s->ppl.seat) || seat_interactive(s->ppl.seat))
480 ppl_printf("Using username \"%s\".\r\n", s->username);
482 s->got_username = true;
485 * Send an authentication request using method "none": (a)
486 * just in case it succeeds, and (b) so that we know what
487 * authentication methods we can usefully try next.
489 s->ppl.bpp->pls->actx = SSH2_PKTCTX_NOAUTH;
491 s->pktout = ssh_bpp_new_pktout(s->ppl.bpp, SSH2_MSG_USERAUTH_REQUEST);
492 put_stringz(s->pktout, s->username);
493 put_stringz(s->pktout, s->successor_layer->vt->name);
494 put_stringz(s->pktout, "none"); /* method */
495 pq_push(s->ppl.out_pq, s->pktout);
496 s->type = AUTH_TYPE_NONE;
498 s->tried_pubkey_config = false;
499 s->kbd_inter_refused = false;
500 s->done_agent = false;
502 while (1) {
504 * Wait for the result of the last authentication request,
505 * unless the request terminated for some reason on our
506 * own side.
508 if (s->suppress_wait_for_response_packet) {
509 pktin = NULL;
510 s->suppress_wait_for_response_packet = false;
511 } else {
512 crMaybeWaitUntilV((pktin = ssh2_userauth_pop(s)) != NULL);
516 * Now is a convenient point to spew any banner material
517 * that we've accumulated. (This should ensure that when
518 * we exit the auth loop, we haven't any left to deal
519 * with.)
521 * Don't show the banner if we're operating in non-verbose
522 * non-interactive mode. (It's probably a script, which
523 * means nobody will read the banner _anyway_, and
524 * moreover the printing of the banner will screw up
525 * processing on the output of (say) plink.)
527 * The banner data has been sanitised already by this
528 * point, but we still need to precede and follow it with
529 * anti-spoofing header lines.
531 if (bufchain_size(&s->banner) &&
532 (seat_verbose(s->ppl.seat) || seat_interactive(s->ppl.seat))) {
533 if (s->banner_scc) {
534 ssh2_userauth_antispoof_msg(
535 s, "Pre-authentication banner message from server:");
536 seat_set_trust_status(s->ppl.seat, false);
539 bool mid_line = false;
540 while (bufchain_size(&s->banner) > 0) {
541 ptrlen data = bufchain_prefix(&s->banner);
542 seat_stderr_pl(s->ppl.seat, data);
543 mid_line =
544 (((const char *)data.ptr)[data.len-1] != '\n');
545 bufchain_consume(&s->banner, data.len);
547 bufchain_clear(&s->banner);
549 if (mid_line)
550 seat_stderr_pl(s->ppl.seat, PTRLEN_LITERAL("\r\n"));
552 if (s->banner_scc) {
553 seat_set_trust_status(s->ppl.seat, true);
554 ssh2_userauth_antispoof_msg(
555 s, "End of banner message from server");
559 if (pktin && pktin->type == SSH2_MSG_USERAUTH_SUCCESS) {
560 ppl_logevent("Access granted");
561 goto userauth_success;
564 if (pktin && pktin->type != SSH2_MSG_USERAUTH_FAILURE &&
565 s->type != AUTH_TYPE_GSSAPI) {
566 ssh_proto_error(s->ppl.ssh, "Received unexpected packet "
567 "in response to authentication request, "
568 "type %d (%s)", pktin->type,
569 ssh2_pkt_type(s->ppl.bpp->pls->kctx,
570 s->ppl.bpp->pls->actx,
571 pktin->type));
572 return;
576 * OK, we're now sitting on a USERAUTH_FAILURE message, so
577 * we can look at the string in it and know what we can
578 * helpfully try next.
580 if (pktin && pktin->type == SSH2_MSG_USERAUTH_FAILURE) {
581 ptrlen methods = get_string(pktin);
582 bool partial_success = get_bool(pktin);
584 if (!partial_success) {
586 * We have received an unequivocal Access
587 * Denied. This can translate to a variety of
588 * messages, or no message at all.
590 * For forms of authentication which are attempted
591 * implicitly, by which I mean without printing
592 * anything in the window indicating that we're
593 * trying them, we should never print 'Access
594 * denied'.
596 * If we do print a message saying that we're
597 * attempting some kind of authentication, it's OK
598 * to print a followup message saying it failed -
599 * but the message may sometimes be more specific
600 * than simply 'Access denied'.
602 * Additionally, if we'd just tried password
603 * authentication, we should break out of this
604 * whole loop so as to go back to the username
605 * prompt (iff we're configured to allow
606 * username change attempts).
608 if (s->type == AUTH_TYPE_NONE) {
609 /* do nothing */
610 } else if (s->type == AUTH_TYPE_PUBLICKEY_OFFER_LOUD ||
611 s->type == AUTH_TYPE_PUBLICKEY_OFFER_QUIET) {
612 if (s->type == AUTH_TYPE_PUBLICKEY_OFFER_LOUD)
613 ppl_printf("Server refused our key\r\n");
614 ppl_logevent("Server refused our key");
615 } else if (s->type == AUTH_TYPE_PUBLICKEY) {
616 /* This _shouldn't_ happen except by a
617 * protocol bug causing client and server to
618 * disagree on what is a correct signature. */
619 ppl_printf("Server refused public-key signature"
620 " despite accepting key!\r\n");
621 ppl_logevent("Server refused public-key signature"
622 " despite accepting key!");
623 } else if (s->type==AUTH_TYPE_KEYBOARD_INTERACTIVE_QUIET) {
624 /* quiet, so no ppl_printf */
625 ppl_logevent("Server refused keyboard-interactive "
626 "authentication");
627 } else if (s->type==AUTH_TYPE_GSSAPI) {
628 /* always quiet, so no ppl_printf */
629 /* also, the code down in the GSSAPI block has
630 * already logged this in the Event Log */
631 } else if (s->type == AUTH_TYPE_KEYBOARD_INTERACTIVE) {
632 ppl_logevent("Keyboard-interactive authentication "
633 "failed");
634 ppl_printf("Access denied\r\n");
635 } else {
636 assert(s->type == AUTH_TYPE_PASSWORD);
637 ppl_logevent("Password authentication failed");
638 ppl_printf("Access denied\r\n");
640 if (s->change_username) {
641 /* XXX perhaps we should allow
642 * keyboard-interactive to do this too? */
643 goto try_new_username;
646 } else {
647 ppl_printf("Further authentication required\r\n");
648 ppl_logevent("Further authentication required");
652 * Save the methods string for use in error messages.
654 strbuf_clear(s->last_methods_string);
655 put_datapl(s->last_methods_string, methods);
658 * Scan it for method identifiers we know about.
660 bool srv_pubkey = false, srv_passwd = false;
661 bool srv_keyb_inter = false;
662 #ifndef NO_GSSAPI
663 bool srv_gssapi = false, srv_gssapi_keyex_auth = false;
664 #endif
666 for (ptrlen method; get_commasep_word(&methods, &method) ;) {
667 if (ptrlen_eq_string(method, "publickey"))
668 srv_pubkey = true;
669 else if (ptrlen_eq_string(method, "password"))
670 srv_passwd = true;
671 else if (ptrlen_eq_string(method, "keyboard-interactive"))
672 srv_keyb_inter = true;
673 #ifndef NO_GSSAPI
674 else if (ptrlen_eq_string(method, "gssapi-with-mic"))
675 srv_gssapi = true;
676 else if (ptrlen_eq_string(method, "gssapi-keyex"))
677 srv_gssapi_keyex_auth = true;
678 #endif
682 * And combine those flags with our own configuration
683 * and context to set the main can_foo variables.
685 s->can_pubkey = srv_pubkey;
686 s->can_passwd = srv_passwd;
687 s->can_keyb_inter = s->try_ki_auth && srv_keyb_inter;
688 #ifndef NO_GSSAPI
689 s->can_gssapi = s->try_gssapi_auth && srv_gssapi &&
690 s->shgss->libs->nlibraries > 0;
691 s->can_gssapi_keyex_auth = s->try_gssapi_kex_auth &&
692 srv_gssapi_keyex_auth &&
693 s->shgss->libs->nlibraries > 0 && s->shgss->ctx;
694 #endif
697 s->ppl.bpp->pls->actx = SSH2_PKTCTX_NOAUTH;
699 #ifndef NO_GSSAPI
700 if (s->can_gssapi_keyex_auth && !s->tried_gssapi_keyex_auth) {
702 /* gssapi-keyex authentication */
704 s->type = AUTH_TYPE_GSSAPI;
705 s->tried_gssapi_keyex_auth = true;
706 s->ppl.bpp->pls->actx = SSH2_PKTCTX_GSSAPI;
708 if (s->shgss->lib->gsslogmsg)
709 ppl_logevent("%s", s->shgss->lib->gsslogmsg);
711 ppl_logevent("Trying gssapi-keyex...");
712 s->pktout = ssh2_userauth_gss_packet(s, "gssapi-keyex");
713 pq_push(s->ppl.out_pq, s->pktout);
714 s->shgss->lib->release_cred(s->shgss->lib, &s->shgss->ctx);
715 s->shgss->ctx = NULL;
717 continue;
718 } else
719 #endif /* NO_GSSAPI */
721 if (s->can_pubkey && !s->done_agent &&
722 s->agent_key_index < s->agent_key_limit) {
725 * Attempt public-key authentication using a key from Pageant.
727 s->agent_keyalg = s->agent_keys[s->agent_key_index].algorithm;
728 s->signflags = 0;
729 if (ptrlen_eq_string(s->agent_keyalg, "ssh-rsa")) {
730 /* Try to upgrade ssh-rsa to one of the rsa-sha2-* family,
731 * if the server has announced support for them. */
732 if (s->ppl.bpp->ext_info_rsa_sha512_ok) {
733 s->agent_keyalg = PTRLEN_LITERAL("rsa-sha2-512");
734 s->signflags = SSH_AGENT_RSA_SHA2_512;
735 } else if (s->ppl.bpp->ext_info_rsa_sha256_ok) {
736 s->agent_keyalg = PTRLEN_LITERAL("rsa-sha2-256");
737 s->signflags = SSH_AGENT_RSA_SHA2_256;
741 s->ppl.bpp->pls->actx = SSH2_PKTCTX_PUBLICKEY;
743 ppl_logevent("Trying Pageant key #%"SIZEu, s->agent_key_index);
745 /* See if server will accept it */
746 s->pktout = ssh_bpp_new_pktout(
747 s->ppl.bpp, SSH2_MSG_USERAUTH_REQUEST);
748 put_stringz(s->pktout, s->username);
749 put_stringz(s->pktout, s->successor_layer->vt->name);
750 put_stringz(s->pktout, "publickey");
751 /* method */
752 put_bool(s->pktout, false); /* no signature included */
753 put_stringpl(s->pktout, s->agent_keyalg);
754 put_stringpl(s->pktout, ptrlen_from_strbuf(
755 s->agent_keys[s->agent_key_index].blob));
756 pq_push(s->ppl.out_pq, s->pktout);
757 s->type = AUTH_TYPE_PUBLICKEY_OFFER_QUIET;
759 crMaybeWaitUntilV((pktin = ssh2_userauth_pop(s)) != NULL);
760 if (pktin->type != SSH2_MSG_USERAUTH_PK_OK) {
762 /* Offer of key refused, presumably via
763 * USERAUTH_FAILURE. Requeue for the next iteration. */
764 pq_push_front(s->ppl.in_pq, pktin);
766 } else {
767 strbuf *agentreq, *sigdata;
768 ptrlen comment = ptrlen_from_strbuf(
769 s->agent_keys[s->agent_key_index].comment);
771 if (seat_verbose(s->ppl.seat))
772 ppl_printf("Authenticating with public key "
773 "\"%.*s\" from agent\r\n",
774 PTRLEN_PRINTF(comment));
777 * Server is willing to accept the key.
778 * Construct a SIGN_REQUEST.
780 s->pktout = ssh_bpp_new_pktout(
781 s->ppl.bpp, SSH2_MSG_USERAUTH_REQUEST);
782 put_stringz(s->pktout, s->username);
783 put_stringz(s->pktout, s->successor_layer->vt->name);
784 put_stringz(s->pktout, "publickey");
785 /* method */
786 put_bool(s->pktout, true); /* signature included */
787 put_stringpl(s->pktout, s->agent_keyalg);
788 put_stringpl(s->pktout, ptrlen_from_strbuf(
789 s->agent_keys[s->agent_key_index].blob));
791 /* Ask agent for signature. */
792 agentreq = strbuf_new_for_agent_query();
793 put_byte(agentreq, SSH2_AGENTC_SIGN_REQUEST);
794 put_stringpl(agentreq, ptrlen_from_strbuf(
795 s->agent_keys[s->agent_key_index].blob));
796 /* Now the data to be signed... */
797 sigdata = strbuf_new();
798 ssh2_userauth_add_session_id(s, sigdata);
799 put_data(sigdata, s->pktout->data + 5,
800 s->pktout->length - 5);
801 put_stringsb(agentreq, sigdata);
802 /* And finally the flags word. */
803 put_uint32(agentreq, s->signflags);
804 ssh2_userauth_agent_query(s, agentreq);
805 strbuf_free(agentreq);
806 crWaitUntilV(!s->auth_agent_query);
808 if (s->agent_response.ptr) {
809 ptrlen sigblob;
810 BinarySource src[1];
811 BinarySource_BARE_INIT(src, s->agent_response.ptr,
812 s->agent_response.len);
813 get_uint32(src); /* skip length field */
814 if (get_byte(src) == SSH2_AGENT_SIGN_RESPONSE &&
815 (sigblob = get_string(src), !get_err(src))) {
816 ppl_logevent("Sending Pageant's response");
817 ssh2_userauth_add_sigblob(
818 s, s->pktout,
819 ptrlen_from_strbuf(
820 s->agent_keys[s->agent_key_index].blob),
821 sigblob);
822 pq_push(s->ppl.out_pq, s->pktout);
823 s->type = AUTH_TYPE_PUBLICKEY;
824 s->is_trivial_auth = false;
825 } else {
826 ppl_logevent("Pageant refused signing request");
827 ppl_printf("Pageant failed to "
828 "provide a signature\r\n");
829 s->suppress_wait_for_response_packet = true;
830 ssh_free_pktout(s->pktout);
832 } else {
833 ppl_logevent("Pageant failed to respond to "
834 "signing request");
835 ppl_printf("Pageant failed to "
836 "respond to signing request\r\n");
837 s->suppress_wait_for_response_packet = true;
838 ssh_free_pktout(s->pktout);
842 /* Do we have any keys left to try? */
843 if (++s->agent_key_index >= s->agent_key_limit)
844 s->done_agent = true;
846 } else if (s->can_pubkey && s->publickey_blob &&
847 s->privatekey_available && !s->tried_pubkey_config) {
849 ssh2_userkey *key; /* not live over crReturn */
850 char *passphrase; /* not live over crReturn */
852 s->ppl.bpp->pls->actx = SSH2_PKTCTX_PUBLICKEY;
854 s->tried_pubkey_config = true;
857 * Try the public key supplied in the configuration.
859 * First, try to upgrade its algorithm.
861 if (!strcmp(s->publickey_algorithm, "ssh-rsa")) {
862 /* Try to upgrade ssh-rsa to one of the rsa-sha2-* family,
863 * if the server has announced support for them. */
864 if (s->ppl.bpp->ext_info_rsa_sha512_ok) {
865 sfree(s->publickey_algorithm);
866 s->publickey_algorithm = dupstr("rsa-sha2-512");
867 s->signflags = SSH_AGENT_RSA_SHA2_512;
868 } else if (s->ppl.bpp->ext_info_rsa_sha256_ok) {
869 sfree(s->publickey_algorithm);
870 s->publickey_algorithm = dupstr("rsa-sha2-256");
871 s->signflags = SSH_AGENT_RSA_SHA2_256;
876 * Offer the public blob to see if the server is willing to
877 * accept it.
879 s->pktout = ssh_bpp_new_pktout(
880 s->ppl.bpp, SSH2_MSG_USERAUTH_REQUEST);
881 put_stringz(s->pktout, s->username);
882 put_stringz(s->pktout, s->successor_layer->vt->name);
883 put_stringz(s->pktout, "publickey"); /* method */
884 put_bool(s->pktout, false);
885 /* no signature included */
886 put_stringz(s->pktout, s->publickey_algorithm);
887 put_string(s->pktout, s->publickey_blob->s,
888 s->publickey_blob->len);
889 pq_push(s->ppl.out_pq, s->pktout);
890 ppl_logevent("Offered public key");
892 crMaybeWaitUntilV((pktin = ssh2_userauth_pop(s)) != NULL);
893 if (pktin->type != SSH2_MSG_USERAUTH_PK_OK) {
894 /* Key refused. Give up. */
895 pq_push_front(s->ppl.in_pq, pktin);
896 s->type = AUTH_TYPE_PUBLICKEY_OFFER_LOUD;
897 continue; /* process this new message */
899 ppl_logevent("Offer of public key accepted");
902 * Actually attempt a serious authentication using
903 * the key.
905 if (seat_verbose(s->ppl.seat))
906 ppl_printf("Authenticating with public key \"%s\"\r\n",
907 s->publickey_comment);
909 key = NULL;
910 while (!key) {
911 const char *error; /* not live over crReturn */
912 if (s->privatekey_encrypted) {
914 * Get a passphrase from the user.
916 s->cur_prompt = new_prompts();
917 s->cur_prompt->to_server = false;
918 s->cur_prompt->from_server = false;
919 s->cur_prompt->name = dupstr("SSH key passphrase");
920 add_prompt(s->cur_prompt,
921 dupprintf("Passphrase for key \"%s\": ",
922 s->publickey_comment),
923 false);
924 s->userpass_ret = seat_get_userpass_input(
925 s->ppl.seat, s->cur_prompt, NULL);
926 while (1) {
927 while (s->userpass_ret < 0 &&
928 bufchain_size(s->ppl.user_input) > 0)
929 s->userpass_ret = seat_get_userpass_input(
930 s->ppl.seat, s->cur_prompt,
931 s->ppl.user_input);
933 if (s->userpass_ret >= 0)
934 break;
936 s->want_user_input = true;
937 crReturnV;
938 s->want_user_input = false;
940 if (!s->userpass_ret) {
941 /* Failed to get a passphrase. Terminate. */
942 free_prompts(s->cur_prompt);
943 ssh_bpp_queue_disconnect(
944 s->ppl.bpp, "Unable to authenticate",
945 SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER);
946 ssh_user_close(s->ppl.ssh, "User aborted at "
947 "passphrase prompt");
948 return;
950 passphrase =
951 prompt_get_result(s->cur_prompt->prompts[0]);
952 free_prompts(s->cur_prompt);
953 } else {
954 passphrase = NULL; /* no passphrase needed */
958 * Try decrypting the key.
960 key = ppk_load_f(s->keyfile, passphrase, &error);
961 if (passphrase) {
962 /* burn the evidence */
963 smemclr(passphrase, strlen(passphrase));
964 sfree(passphrase);
966 if (key == SSH2_WRONG_PASSPHRASE || key == NULL) {
967 if (passphrase &&
968 (key == SSH2_WRONG_PASSPHRASE)) {
969 ppl_printf("Wrong passphrase\r\n");
970 key = NULL;
971 /* and loop again */
972 } else {
973 ppl_printf("Unable to load private key (%s)\r\n",
974 error);
975 key = NULL;
976 s->suppress_wait_for_response_packet = true;
977 break; /* try something else */
979 } else {
980 /* FIXME: if we ever support variable signature
981 * flags, this is somewhere they'll need to be
982 * put */
983 char *invalid = ssh_key_invalid(key->key, 0);
984 if (invalid) {
985 ppl_printf("Cannot use this private key (%s)\r\n",
986 invalid);
987 ssh_key_free(key->key);
988 sfree(key->comment);
989 sfree(key);
990 sfree(invalid);
991 key = NULL;
992 s->suppress_wait_for_response_packet = true;
993 break; /* try something else */
998 if (key) {
999 strbuf *pkblob, *sigdata, *sigblob;
1002 * We have loaded the private key and the server
1003 * has announced that it's willing to accept it.
1004 * Hallelujah. Generate a signature and send it.
1006 s->pktout = ssh_bpp_new_pktout(
1007 s->ppl.bpp, SSH2_MSG_USERAUTH_REQUEST);
1008 put_stringz(s->pktout, s->username);
1009 put_stringz(s->pktout, s->successor_layer->vt->name);
1010 put_stringz(s->pktout, "publickey"); /* method */
1011 put_bool(s->pktout, true); /* signature follows */
1012 put_stringz(s->pktout, s->publickey_algorithm);
1013 pkblob = strbuf_new();
1014 ssh_key_public_blob(key->key, BinarySink_UPCAST(pkblob));
1015 put_string(s->pktout, pkblob->s, pkblob->len);
1018 * The data to be signed is:
1020 * string session-id
1022 * followed by everything so far placed in the
1023 * outgoing packet.
1025 sigdata = strbuf_new();
1026 ssh2_userauth_add_session_id(s, sigdata);
1027 put_data(sigdata, s->pktout->data + 5,
1028 s->pktout->length - 5);
1029 sigblob = strbuf_new();
1030 ssh_key_sign(key->key, ptrlen_from_strbuf(sigdata),
1031 s->signflags, BinarySink_UPCAST(sigblob));
1032 strbuf_free(sigdata);
1033 ssh2_userauth_add_sigblob(
1034 s, s->pktout, ptrlen_from_strbuf(pkblob),
1035 ptrlen_from_strbuf(sigblob));
1036 strbuf_free(pkblob);
1037 strbuf_free(sigblob);
1039 pq_push(s->ppl.out_pq, s->pktout);
1040 ppl_logevent("Sent public key signature");
1041 s->type = AUTH_TYPE_PUBLICKEY;
1042 ssh_key_free(key->key);
1043 sfree(key->comment);
1044 sfree(key);
1045 s->is_trivial_auth = false;
1048 #ifndef NO_GSSAPI
1049 } else if (s->can_gssapi && !s->tried_gssapi) {
1051 /* gssapi-with-mic authentication */
1053 ptrlen data;
1055 s->type = AUTH_TYPE_GSSAPI;
1056 s->tried_gssapi = true;
1057 s->ppl.bpp->pls->actx = SSH2_PKTCTX_GSSAPI;
1059 if (s->shgss->lib->gsslogmsg)
1060 ppl_logevent("%s", s->shgss->lib->gsslogmsg);
1062 /* Sending USERAUTH_REQUEST with "gssapi-with-mic" method */
1063 ppl_logevent("Trying gssapi-with-mic...");
1064 s->pktout = ssh_bpp_new_pktout(
1065 s->ppl.bpp, SSH2_MSG_USERAUTH_REQUEST);
1066 put_stringz(s->pktout, s->username);
1067 put_stringz(s->pktout, s->successor_layer->vt->name);
1068 put_stringz(s->pktout, "gssapi-with-mic");
1069 ppl_logevent("Attempting GSSAPI authentication");
1071 /* add mechanism info */
1072 s->shgss->lib->indicate_mech(s->shgss->lib, &s->gss_buf);
1074 /* number of GSSAPI mechanisms */
1075 put_uint32(s->pktout, 1);
1077 /* length of OID + 2 */
1078 put_uint32(s->pktout, s->gss_buf.length + 2);
1079 put_byte(s->pktout, SSH2_GSS_OIDTYPE);
1081 /* length of OID */
1082 put_byte(s->pktout, s->gss_buf.length);
1084 put_data(s->pktout, s->gss_buf.value, s->gss_buf.length);
1085 pq_push(s->ppl.out_pq, s->pktout);
1086 crMaybeWaitUntilV((pktin = ssh2_userauth_pop(s)) != NULL);
1087 if (pktin->type != SSH2_MSG_USERAUTH_GSSAPI_RESPONSE) {
1088 ppl_logevent("GSSAPI authentication request refused");
1089 pq_push_front(s->ppl.in_pq, pktin);
1090 continue;
1093 /* check returned packet ... */
1095 data = get_string(pktin);
1096 s->gss_rcvtok.value = (char *)data.ptr;
1097 s->gss_rcvtok.length = data.len;
1098 if (s->gss_rcvtok.length != s->gss_buf.length + 2 ||
1099 ((char *)s->gss_rcvtok.value)[0] != SSH2_GSS_OIDTYPE ||
1100 ((char *)s->gss_rcvtok.value)[1] != s->gss_buf.length ||
1101 memcmp((char *)s->gss_rcvtok.value + 2,
1102 s->gss_buf.value,s->gss_buf.length) ) {
1103 ppl_logevent("GSSAPI authentication - wrong response "
1104 "from server");
1105 continue;
1108 /* Import server name if not cached from KEX */
1109 if (s->shgss->srv_name == GSS_C_NO_NAME) {
1110 s->gss_stat = s->shgss->lib->import_name(
1111 s->shgss->lib, s->fullhostname, &s->shgss->srv_name);
1112 if (s->gss_stat != SSH_GSS_OK) {
1113 if (s->gss_stat == SSH_GSS_BAD_HOST_NAME)
1114 ppl_logevent("GSSAPI import name failed -"
1115 " Bad service name");
1116 else
1117 ppl_logevent("GSSAPI import name failed");
1118 continue;
1122 /* Allocate our gss_ctx */
1123 s->gss_stat = s->shgss->lib->acquire_cred(
1124 s->shgss->lib, &s->shgss->ctx, NULL);
1125 if (s->gss_stat != SSH_GSS_OK) {
1126 ppl_logevent("GSSAPI authentication failed to get "
1127 "credentials");
1128 /* The failure was on our side, so the server
1129 * won't be sending a response packet indicating
1130 * failure. Avoid waiting for it next time round
1131 * the loop. */
1132 s->suppress_wait_for_response_packet = true;
1133 continue;
1136 /* initial tokens are empty */
1137 SSH_GSS_CLEAR_BUF(&s->gss_rcvtok);
1138 SSH_GSS_CLEAR_BUF(&s->gss_sndtok);
1140 /* now enter the loop */
1141 do {
1143 * When acquire_cred yields no useful expiration, go with
1144 * the service ticket expiration.
1146 s->gss_stat = s->shgss->lib->init_sec_context
1147 (s->shgss->lib,
1148 &s->shgss->ctx,
1149 s->shgss->srv_name,
1150 s->gssapi_fwd,
1151 &s->gss_rcvtok,
1152 &s->gss_sndtok,
1153 NULL,
1154 NULL);
1156 if (s->gss_stat!=SSH_GSS_S_COMPLETE &&
1157 s->gss_stat!=SSH_GSS_S_CONTINUE_NEEDED) {
1158 ppl_logevent("GSSAPI authentication initialisation "
1159 "failed");
1161 if (s->shgss->lib->display_status(s->shgss->lib,
1162 s->shgss->ctx, &s->gss_buf) == SSH_GSS_OK) {
1163 ppl_logevent("%s", (char *)s->gss_buf.value);
1164 sfree(s->gss_buf.value);
1167 pq_push_front(s->ppl.in_pq, pktin);
1168 break;
1170 ppl_logevent("GSSAPI authentication initialised");
1173 * Client and server now exchange tokens until GSSAPI
1174 * no longer says CONTINUE_NEEDED
1176 if (s->gss_sndtok.length != 0) {
1177 s->is_trivial_auth = false;
1178 s->pktout =
1179 ssh_bpp_new_pktout(
1180 s->ppl.bpp, SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
1181 put_string(s->pktout,
1182 s->gss_sndtok.value, s->gss_sndtok.length);
1183 pq_push(s->ppl.out_pq, s->pktout);
1184 s->shgss->lib->free_tok(s->shgss->lib, &s->gss_sndtok);
1187 if (s->gss_stat == SSH_GSS_S_CONTINUE_NEEDED) {
1188 crMaybeWaitUntilV((pktin = ssh2_userauth_pop(s)) != NULL);
1190 if (pktin->type == SSH2_MSG_USERAUTH_GSSAPI_ERRTOK) {
1192 * Per RFC 4462 section 3.9, this packet
1193 * type MUST immediately precede an
1194 * ordinary USERAUTH_FAILURE.
1196 * We currently don't know how to do
1197 * anything with the GSSAPI error token
1198 * contained in this packet, so we ignore
1199 * it and just wait for the following
1200 * FAILURE.
1202 crMaybeWaitUntilV(
1203 (pktin = ssh2_userauth_pop(s)) != NULL);
1204 if (pktin->type != SSH2_MSG_USERAUTH_FAILURE) {
1205 ssh_proto_error(
1206 s->ppl.ssh, "Received unexpected packet "
1207 "after SSH_MSG_USERAUTH_GSSAPI_ERRTOK "
1208 "(expected SSH_MSG_USERAUTH_FAILURE): "
1209 "type %d (%s)", pktin->type,
1210 ssh2_pkt_type(s->ppl.bpp->pls->kctx,
1211 s->ppl.bpp->pls->actx,
1212 pktin->type));
1213 return;
1217 if (pktin->type == SSH2_MSG_USERAUTH_FAILURE) {
1218 ppl_logevent("GSSAPI authentication failed");
1219 s->gss_stat = SSH_GSS_FAILURE;
1220 pq_push_front(s->ppl.in_pq, pktin);
1221 break;
1222 } else if (pktin->type !=
1223 SSH2_MSG_USERAUTH_GSSAPI_TOKEN) {
1224 ppl_logevent("GSSAPI authentication -"
1225 " bad server response");
1226 s->gss_stat = SSH_GSS_FAILURE;
1227 break;
1229 data = get_string(pktin);
1230 s->gss_rcvtok.value = (char *)data.ptr;
1231 s->gss_rcvtok.length = data.len;
1233 } while (s-> gss_stat == SSH_GSS_S_CONTINUE_NEEDED);
1235 if (s->gss_stat != SSH_GSS_OK) {
1236 s->shgss->lib->release_cred(s->shgss->lib, &s->shgss->ctx);
1237 continue;
1239 ppl_logevent("GSSAPI authentication loop finished OK");
1241 /* Now send the MIC */
1243 s->pktout = ssh2_userauth_gss_packet(s, "gssapi-with-mic");
1244 pq_push(s->ppl.out_pq, s->pktout);
1246 s->shgss->lib->release_cred(s->shgss->lib, &s->shgss->ctx);
1247 continue;
1248 #endif
1249 } else if (s->can_keyb_inter && !s->kbd_inter_refused) {
1252 * Keyboard-interactive authentication.
1255 s->type = AUTH_TYPE_KEYBOARD_INTERACTIVE;
1257 s->ppl.bpp->pls->actx = SSH2_PKTCTX_KBDINTER;
1259 s->pktout = ssh_bpp_new_pktout(
1260 s->ppl.bpp, SSH2_MSG_USERAUTH_REQUEST);
1261 put_stringz(s->pktout, s->username);
1262 put_stringz(s->pktout, s->successor_layer->vt->name);
1263 put_stringz(s->pktout, "keyboard-interactive");
1264 /* method */
1265 put_stringz(s->pktout, ""); /* lang */
1266 put_stringz(s->pktout, ""); /* submethods */
1267 pq_push(s->ppl.out_pq, s->pktout);
1269 ppl_logevent("Attempting keyboard-interactive authentication");
1271 if (!s->ki_scc_initialised) {
1272 s->ki_scc = seat_stripctrl_new(
1273 s->ppl.seat, NULL, SIC_KI_PROMPTS);
1274 if (s->ki_scc)
1275 stripctrl_enable_line_limiting(s->ki_scc);
1276 s->ki_scc_initialised = true;
1279 crMaybeWaitUntilV((pktin = ssh2_userauth_pop(s)) != NULL);
1280 if (pktin->type != SSH2_MSG_USERAUTH_INFO_REQUEST) {
1281 /* Server is not willing to do keyboard-interactive
1282 * at all (or, bizarrely but legally, accepts the
1283 * user without actually issuing any prompts).
1284 * Give up on it entirely. */
1285 pq_push_front(s->ppl.in_pq, pktin);
1286 s->type = AUTH_TYPE_KEYBOARD_INTERACTIVE_QUIET;
1287 s->kbd_inter_refused = true; /* don't try it again */
1288 continue;
1291 s->ki_printed_header = false;
1294 * Loop while the server continues to send INFO_REQUESTs.
1296 while (pktin->type == SSH2_MSG_USERAUTH_INFO_REQUEST) {
1297 ptrlen name, inst;
1298 strbuf *sb;
1301 * We've got a fresh USERAUTH_INFO_REQUEST.
1302 * Get the preamble and start building a prompt.
1304 name = get_string(pktin);
1305 inst = get_string(pktin);
1306 get_string(pktin); /* skip language tag */
1307 s->cur_prompt = new_prompts();
1308 s->cur_prompt->to_server = true;
1309 s->cur_prompt->from_server = true;
1312 * Get any prompt(s) from the packet.
1314 s->num_prompts = get_uint32(pktin);
1315 for (uint32_t i = 0; i < s->num_prompts; i++) {
1316 s->is_trivial_auth = false;
1317 ptrlen prompt = get_string(pktin);
1318 bool echo = get_bool(pktin);
1320 if (get_err(pktin)) {
1321 ssh_proto_error(
1322 s->ppl.ssh, "Server sent truncated "
1323 "SSH_MSG_USERAUTH_INFO_REQUEST packet");
1324 return;
1327 sb = strbuf_new();
1328 if (!prompt.len) {
1329 put_datapl(sb, PTRLEN_LITERAL(
1330 "<server failed to send prompt>: "));
1331 } else if (s->ki_scc) {
1332 stripctrl_retarget(
1333 s->ki_scc, BinarySink_UPCAST(sb));
1334 put_datapl(s->ki_scc, prompt);
1335 stripctrl_retarget(s->ki_scc, NULL);
1336 } else {
1337 put_datapl(sb, prompt);
1339 add_prompt(s->cur_prompt, strbuf_to_str(sb), echo);
1343 * Make the header strings. This includes the
1344 * 'name' (optional dialog-box title) and
1345 * 'instruction' from the server.
1347 * First, display our disambiguating header line
1348 * if this is the first time round the loop -
1349 * _unless_ the server has sent a completely empty
1350 * k-i packet with no prompts _or_ text, which
1351 * apparently some do. In that situation there's
1352 * no need to alert the user that the following
1353 * text is server- supplied, because, well, _what_
1354 * text?
1356 * We also only do this if we got a stripctrl,
1357 * because if we didn't, that suggests this is all
1358 * being done via dialog boxes anyway.
1360 if (!s->ki_printed_header && s->ki_scc &&
1361 (s->num_prompts || name.len || inst.len)) {
1362 ssh2_userauth_antispoof_msg(
1363 s, "Keyboard-interactive authentication "
1364 "prompts from server:");
1365 s->ki_printed_header = true;
1366 seat_set_trust_status(s->ppl.seat, false);
1369 sb = strbuf_new();
1370 if (name.len) {
1371 if (s->ki_scc) {
1372 stripctrl_retarget(s->ki_scc,
1373 BinarySink_UPCAST(sb));
1374 put_datapl(s->ki_scc, name);
1375 stripctrl_retarget(s->ki_scc, NULL);
1376 } else {
1377 put_datapl(sb, name);
1379 s->cur_prompt->name_reqd = true;
1380 } else {
1381 put_datapl(sb, PTRLEN_LITERAL(
1382 "SSH server authentication"));
1383 s->cur_prompt->name_reqd = false;
1385 s->cur_prompt->name = strbuf_to_str(sb);
1387 sb = strbuf_new();
1388 if (inst.len) {
1389 if (s->ki_scc) {
1390 stripctrl_retarget(s->ki_scc,
1391 BinarySink_UPCAST(sb));
1392 put_datapl(s->ki_scc, inst);
1393 stripctrl_retarget(s->ki_scc, NULL);
1394 } else {
1395 put_datapl(sb, inst);
1397 s->cur_prompt->instr_reqd = true;
1398 } else {
1399 s->cur_prompt->instr_reqd = false;
1401 if (sb->len)
1402 s->cur_prompt->instruction = strbuf_to_str(sb);
1403 else
1404 strbuf_free(sb);
1407 * Our prompts_t is fully constructed now. Get the
1408 * user's response(s).
1410 s->userpass_ret = seat_get_userpass_input(
1411 s->ppl.seat, s->cur_prompt, NULL);
1412 while (1) {
1413 while (s->userpass_ret < 0 &&
1414 bufchain_size(s->ppl.user_input) > 0)
1415 s->userpass_ret = seat_get_userpass_input(
1416 s->ppl.seat, s->cur_prompt, s->ppl.user_input);
1418 if (s->userpass_ret >= 0)
1419 break;
1421 s->want_user_input = true;
1422 crReturnV;
1423 s->want_user_input = false;
1425 if (!s->userpass_ret) {
1427 * Failed to get responses. Terminate.
1429 free_prompts(s->cur_prompt);
1430 ssh_bpp_queue_disconnect(
1431 s->ppl.bpp, "Unable to authenticate",
1432 SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER);
1433 ssh_user_close(s->ppl.ssh, "User aborted during "
1434 "keyboard-interactive authentication");
1435 return;
1439 * Send the response(s) to the server.
1441 s->pktout = ssh_bpp_new_pktout(
1442 s->ppl.bpp, SSH2_MSG_USERAUTH_INFO_RESPONSE);
1443 put_uint32(s->pktout, s->num_prompts);
1444 for (uint32_t i = 0; i < s->num_prompts; i++) {
1445 put_stringz(s->pktout, prompt_get_result_ref(
1446 s->cur_prompt->prompts[i]));
1448 s->pktout->minlen = 256;
1449 pq_push(s->ppl.out_pq, s->pktout);
1452 * Free the prompts structure from this iteration.
1453 * If there's another, a new one will be allocated
1454 * when we return to the top of this while loop.
1456 free_prompts(s->cur_prompt);
1459 * Get the next packet in case it's another
1460 * INFO_REQUEST.
1462 crMaybeWaitUntilV((pktin = ssh2_userauth_pop(s)) != NULL);
1467 * Print our trailer line, if we printed a header.
1469 if (s->ki_printed_header) {
1470 seat_set_trust_status(s->ppl.seat, true);
1471 ssh2_userauth_antispoof_msg(
1472 s, "End of keyboard-interactive prompts from server");
1476 * We should have SUCCESS or FAILURE now.
1478 pq_push_front(s->ppl.in_pq, pktin);
1480 } else if (s->can_passwd) {
1481 s->is_trivial_auth = false;
1483 * Plain old password authentication.
1485 bool changereq_first_time; /* not live over crReturn */
1487 s->ppl.bpp->pls->actx = SSH2_PKTCTX_PASSWORD;
1489 s->cur_prompt = new_prompts();
1490 s->cur_prompt->to_server = true;
1491 s->cur_prompt->from_server = false;
1492 s->cur_prompt->name = dupstr("SSH password");
1493 add_prompt(s->cur_prompt, dupprintf("%s@%s's password: ",
1494 s->username, s->hostname),
1495 false);
1497 s->userpass_ret = seat_get_userpass_input(
1498 s->ppl.seat, s->cur_prompt, NULL);
1499 while (1) {
1500 while (s->userpass_ret < 0 &&
1501 bufchain_size(s->ppl.user_input) > 0)
1502 s->userpass_ret = seat_get_userpass_input(
1503 s->ppl.seat, s->cur_prompt, s->ppl.user_input);
1505 if (s->userpass_ret >= 0)
1506 break;
1508 s->want_user_input = true;
1509 crReturnV;
1510 s->want_user_input = false;
1512 if (!s->userpass_ret) {
1514 * Failed to get responses. Terminate.
1516 free_prompts(s->cur_prompt);
1517 ssh_bpp_queue_disconnect(
1518 s->ppl.bpp, "Unable to authenticate",
1519 SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER);
1520 ssh_user_close(s->ppl.ssh, "User aborted during password "
1521 "authentication");
1522 return;
1525 * Squirrel away the password. (We may need it later if
1526 * asked to change it.)
1528 s->password = prompt_get_result(s->cur_prompt->prompts[0]);
1529 free_prompts(s->cur_prompt);
1532 * Send the password packet.
1534 * We pad out the password packet to 256 bytes to make
1535 * it harder for an attacker to find the length of the
1536 * user's password.
1538 * Anyone using a password longer than 256 bytes
1539 * probably doesn't have much to worry about from
1540 * people who find out how long their password is!
1542 s->pktout = ssh_bpp_new_pktout(
1543 s->ppl.bpp, SSH2_MSG_USERAUTH_REQUEST);
1544 put_stringz(s->pktout, s->username);
1545 put_stringz(s->pktout, s->successor_layer->vt->name);
1546 put_stringz(s->pktout, "password");
1547 put_bool(s->pktout, false);
1548 put_stringz(s->pktout, s->password);
1549 s->pktout->minlen = 256;
1550 pq_push(s->ppl.out_pq, s->pktout);
1551 ppl_logevent("Sent password");
1552 s->type = AUTH_TYPE_PASSWORD;
1555 * Wait for next packet, in case it's a password change
1556 * request.
1558 crMaybeWaitUntilV((pktin = ssh2_userauth_pop(s)) != NULL);
1559 changereq_first_time = true;
1561 while (pktin->type == SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ) {
1564 * We're being asked for a new password
1565 * (perhaps not for the first time).
1566 * Loop until the server accepts it.
1569 bool got_new = false; /* not live over crReturn */
1570 ptrlen prompt; /* not live over crReturn */
1573 const char *msg;
1574 if (changereq_first_time)
1575 msg = "Server requested password change";
1576 else
1577 msg = "Server rejected new password";
1578 ppl_logevent("%s", msg);
1579 ppl_printf("%s\r\n", msg);
1582 prompt = get_string(pktin);
1584 s->cur_prompt = new_prompts();
1585 s->cur_prompt->to_server = true;
1586 s->cur_prompt->from_server = false;
1587 s->cur_prompt->name = dupstr("New SSH password");
1588 s->cur_prompt->instruction = mkstr(prompt);
1589 s->cur_prompt->instr_reqd = true;
1591 * There's no explicit requirement in the protocol
1592 * for the "old" passwords in the original and
1593 * password-change messages to be the same, and
1594 * apparently some Cisco kit supports password change
1595 * by the user entering a blank password originally
1596 * and the real password subsequently, so,
1597 * reluctantly, we prompt for the old password again.
1599 * (On the other hand, some servers don't even bother
1600 * to check this field.)
1602 add_prompt(s->cur_prompt,
1603 dupstr("Current password (blank for previously entered password): "),
1604 false);
1605 add_prompt(s->cur_prompt, dupstr("Enter new password: "),
1606 false);
1607 add_prompt(s->cur_prompt, dupstr("Confirm new password: "),
1608 false);
1611 * Loop until the user manages to enter the same
1612 * password twice.
1614 while (!got_new) {
1615 s->userpass_ret = seat_get_userpass_input(
1616 s->ppl.seat, s->cur_prompt, NULL);
1617 while (1) {
1618 while (s->userpass_ret < 0 &&
1619 bufchain_size(s->ppl.user_input) > 0)
1620 s->userpass_ret = seat_get_userpass_input(
1621 s->ppl.seat, s->cur_prompt,
1622 s->ppl.user_input);
1624 if (s->userpass_ret >= 0)
1625 break;
1627 s->want_user_input = true;
1628 crReturnV;
1629 s->want_user_input = false;
1631 if (!s->userpass_ret) {
1633 * Failed to get responses. Terminate.
1635 /* burn the evidence */
1636 free_prompts(s->cur_prompt);
1637 smemclr(s->password, strlen(s->password));
1638 sfree(s->password);
1639 ssh_bpp_queue_disconnect(
1640 s->ppl.bpp, "Unable to authenticate",
1641 SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER);
1642 ssh_user_close(s->ppl.ssh, "User aborted during "
1643 "password changing");
1644 return;
1648 * If the user specified a new original password
1649 * (IYSWIM), overwrite any previously specified
1650 * one.
1651 * (A side effect is that the user doesn't have to
1652 * re-enter it if they louse up the new password.)
1654 if (s->cur_prompt->prompts[0]->result->s[0]) {
1655 smemclr(s->password, strlen(s->password));
1656 /* burn the evidence */
1657 sfree(s->password);
1658 s->password = prompt_get_result(
1659 s->cur_prompt->prompts[0]);
1663 * Check the two new passwords match.
1665 got_new = !strcmp(
1666 prompt_get_result_ref(s->cur_prompt->prompts[1]),
1667 prompt_get_result_ref(s->cur_prompt->prompts[2]));
1668 if (!got_new)
1669 /* They don't. Silly user. */
1670 ppl_printf("Passwords do not match\r\n");
1675 * Send the new password (along with the old one).
1676 * (see above for padding rationale)
1678 s->pktout = ssh_bpp_new_pktout(
1679 s->ppl.bpp, SSH2_MSG_USERAUTH_REQUEST);
1680 put_stringz(s->pktout, s->username);
1681 put_stringz(s->pktout, s->successor_layer->vt->name);
1682 put_stringz(s->pktout, "password");
1683 put_bool(s->pktout, true);
1684 put_stringz(s->pktout, s->password);
1685 put_stringz(s->pktout, prompt_get_result_ref(
1686 s->cur_prompt->prompts[1]));
1687 free_prompts(s->cur_prompt);
1688 s->pktout->minlen = 256;
1689 pq_push(s->ppl.out_pq, s->pktout);
1690 ppl_logevent("Sent new password");
1693 * Now see what the server has to say about it.
1694 * (If it's CHANGEREQ again, it's not happy with the
1695 * new password.)
1697 crMaybeWaitUntilV((pktin = ssh2_userauth_pop(s)) != NULL);
1698 changereq_first_time = false;
1703 * We need to reexamine the current pktin at the top
1704 * of the loop. Either:
1705 * - we weren't asked to change password at all, in
1706 * which case it's a SUCCESS or FAILURE with the
1707 * usual meaning
1708 * - we sent a new password, and the server was
1709 * either OK with it (SUCCESS or FAILURE w/partial
1710 * success) or unhappy with the _old_ password
1711 * (FAILURE w/o partial success)
1712 * In any of these cases, we go back to the top of
1713 * the loop and start again.
1715 pq_push_front(s->ppl.in_pq, pktin);
1718 * We don't need the old password any more, in any
1719 * case. Burn the evidence.
1721 smemclr(s->password, strlen(s->password));
1722 sfree(s->password);
1724 } else {
1725 ssh_bpp_queue_disconnect(
1726 s->ppl.bpp,
1727 "No supported authentication methods available",
1728 SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE);
1729 ssh_sw_abort(s->ppl.ssh, "No supported authentication methods "
1730 "available (server sent: %s)",
1731 s->last_methods_string->s);
1732 return;
1736 try_new_username:;
1739 userauth_success:
1740 if (s->notrivialauth && s->is_trivial_auth) {
1741 ssh_proto_error(s->ppl.ssh, "Authentication was trivial! "
1742 "Abandoning session as specified in configuration.");
1743 return;
1747 * We've just received USERAUTH_SUCCESS, and we haven't sent
1748 * any packets since. Signal the transport layer to consider
1749 * doing an immediate rekey, if it has any reason to want to.
1751 ssh2_transport_notify_auth_done(s->transport_layer);
1754 * Finally, hand over to our successor layer, and return
1755 * immediately without reaching the crFinishV: ssh_ppl_replace
1756 * will have freed us, so crFinishV's zeroing-out of crState would
1757 * be a use-after-free bug.
1760 PacketProtocolLayer *successor = s->successor_layer;
1761 s->successor_layer = NULL; /* avoid freeing it ourself */
1762 ssh_ppl_replace(&s->ppl, successor);
1763 return; /* we've just freed s, so avoid even touching s->crState */
1766 crFinishV;
1769 static void ssh2_userauth_add_session_id(
1770 struct ssh2_userauth_state *s, strbuf *sigdata)
1772 if (s->ppl.remote_bugs & BUG_SSH2_PK_SESSIONID) {
1773 put_datapl(sigdata, s->session_id);
1774 } else {
1775 put_stringpl(sigdata, s->session_id);
1779 static void ssh2_userauth_agent_query(
1780 struct ssh2_userauth_state *s, strbuf *req)
1782 void *response;
1783 int response_len;
1785 sfree(s->agent_response_to_free);
1786 s->agent_response_to_free = NULL;
1788 s->auth_agent_query = agent_query(req, &response, &response_len,
1789 ssh2_userauth_agent_callback, s);
1790 if (!s->auth_agent_query)
1791 ssh2_userauth_agent_callback(s, response, response_len);
1794 static void ssh2_userauth_agent_callback(void *uav, void *reply, int replylen)
1796 struct ssh2_userauth_state *s = (struct ssh2_userauth_state *)uav;
1798 s->auth_agent_query = NULL;
1799 s->agent_response_to_free = reply;
1800 s->agent_response = make_ptrlen(reply, replylen);
1802 queue_idempotent_callback(&s->ppl.ic_process_queue);
1806 * Helper function to add an SSH-2 signature blob to a packet. Expects
1807 * to be shown the public key blob as well as the signature blob.
1808 * Normally just appends the sig blob unmodified as a string, except
1809 * that it optionally breaks it open and fiddle with it to work around
1810 * BUG_SSH2_RSA_PADDING.
1812 static void ssh2_userauth_add_sigblob(
1813 struct ssh2_userauth_state *s, PktOut *pkt, ptrlen pkblob, ptrlen sigblob)
1815 BinarySource pk[1], sig[1];
1816 BinarySource_BARE_INIT_PL(pk, pkblob);
1817 BinarySource_BARE_INIT_PL(sig, sigblob);
1819 /* dmemdump(pkblob, pkblob_len); */
1820 /* dmemdump(sigblob, sigblob_len); */
1823 * See if this is in fact an ssh-rsa signature and a buggy
1824 * server; otherwise we can just do this the easy way.
1826 if ((s->ppl.remote_bugs & BUG_SSH2_RSA_PADDING) &&
1827 ptrlen_eq_string(get_string(pk), "ssh-rsa") &&
1828 ptrlen_eq_string(get_string(sig), "ssh-rsa")) {
1829 ptrlen mod_mp, sig_mp;
1830 size_t sig_prefix_len;
1833 * Find the modulus and signature integers.
1835 get_string(pk); /* skip over exponent */
1836 mod_mp = get_string(pk); /* remember modulus */
1837 sig_prefix_len = sig->pos;
1838 sig_mp = get_string(sig);
1839 if (get_err(pk) || get_err(sig))
1840 goto give_up;
1843 * Find the byte length of the modulus, not counting leading
1844 * zeroes.
1846 while (mod_mp.len > 0 && *(const char *)mod_mp.ptr == 0) {
1847 mod_mp.len--;
1848 mod_mp.ptr = (const char *)mod_mp.ptr + 1;
1851 /* debug("modulus length is %d\n", len); */
1852 /* debug("signature length is %d\n", siglen); */
1854 if (mod_mp.len > sig_mp.len) {
1855 strbuf *substr = strbuf_new();
1856 put_data(substr, sigblob.ptr, sig_prefix_len);
1857 put_uint32(substr, mod_mp.len);
1858 put_padding(substr, mod_mp.len - sig_mp.len, 0);
1859 put_datapl(substr, sig_mp);
1860 put_stringsb(pkt, substr);
1861 return;
1864 /* Otherwise fall through and do it the easy way. We also come
1865 * here as a fallback if we discover above that the key blob
1866 * is misformatted in some way. */
1867 give_up:;
1870 put_stringpl(pkt, sigblob);
1873 #ifndef NO_GSSAPI
1874 static PktOut *ssh2_userauth_gss_packet(
1875 struct ssh2_userauth_state *s, const char *authtype)
1877 strbuf *sb;
1878 PktOut *p;
1879 Ssh_gss_buf buf;
1880 Ssh_gss_buf mic;
1883 * The mic is computed over the session id + intended
1884 * USERAUTH_REQUEST packet.
1886 sb = strbuf_new();
1887 put_stringpl(sb, s->session_id);
1888 put_byte(sb, SSH2_MSG_USERAUTH_REQUEST);
1889 put_stringz(sb, s->username);
1890 put_stringz(sb, s->successor_layer->vt->name);
1891 put_stringz(sb, authtype);
1893 /* Compute the mic */
1894 buf.value = sb->s;
1895 buf.length = sb->len;
1896 s->shgss->lib->get_mic(s->shgss->lib, s->shgss->ctx, &buf, &mic);
1897 strbuf_free(sb);
1899 /* Now we can build the real packet */
1900 if (strcmp(authtype, "gssapi-with-mic") == 0) {
1901 p = ssh_bpp_new_pktout(s->ppl.bpp, SSH2_MSG_USERAUTH_GSSAPI_MIC);
1902 } else {
1903 p = ssh_bpp_new_pktout(s->ppl.bpp, SSH2_MSG_USERAUTH_REQUEST);
1904 put_stringz(p, s->username);
1905 put_stringz(p, s->successor_layer->vt->name);
1906 put_stringz(p, authtype);
1908 put_string(p, mic.value, mic.length);
1910 return p;
1912 #endif
1914 static bool ssh2_userauth_get_specials(
1915 PacketProtocolLayer *ppl, add_special_fn_t add_special, void *ctx)
1917 /* No specials provided by this layer. */
1918 return false;
1921 static void ssh2_userauth_special_cmd(PacketProtocolLayer *ppl,
1922 SessionSpecialCode code, int arg)
1924 /* No specials provided by this layer. */
1927 static bool ssh2_userauth_want_user_input(PacketProtocolLayer *ppl)
1929 struct ssh2_userauth_state *s =
1930 container_of(ppl, struct ssh2_userauth_state, ppl);
1931 return s->want_user_input;
1934 static void ssh2_userauth_got_user_input(PacketProtocolLayer *ppl)
1936 struct ssh2_userauth_state *s =
1937 container_of(ppl, struct ssh2_userauth_state, ppl);
1938 if (s->want_user_input)
1939 queue_idempotent_callback(&s->ppl.ic_process_queue);
1942 static void ssh2_userauth_reconfigure(PacketProtocolLayer *ppl, Conf *conf)
1944 struct ssh2_userauth_state *s =
1945 container_of(ppl, struct ssh2_userauth_state, ppl);
1946 ssh_ppl_reconfigure(s->successor_layer, conf);
1949 static void ssh2_userauth_antispoof_msg(
1950 struct ssh2_userauth_state *s, const char *msg)
1952 strbuf *sb = strbuf_new();
1953 if (seat_set_trust_status(s->ppl.seat, true)) {
1955 * If the seat can directly indicate that this message is
1956 * generated by the client, then we can just use the message
1957 * unmodified as an unspoofable header.
1959 put_datapl(sb, ptrlen_from_asciz(msg));
1960 } else {
1962 * Otherwise, add enough padding around it that the server
1963 * wouldn't be able to mimic it within our line-length
1964 * constraint.
1966 strbuf_catf(sb, "-- %s ", msg);
1967 while (sb->len < 78)
1968 put_byte(sb, '-');
1970 put_datapl(sb, PTRLEN_LITERAL("\r\n"));
1971 seat_stderr_pl(s->ppl.seat, ptrlen_from_strbuf(sb));
1972 strbuf_free(sb);