1 /*
2  * Packet protocol layer for the client side of the SSH-2 userauth
3  * protocol (RFC 4252).
4  */
5 
6 #include <assert.h>
7 
8 #include "putty.h"
9 #include "ssh.h"
10 #include "sshbpp.h"
11 #include "sshppl.h"
12 #include "sshcr.h"
13 
14 #ifndef NO_GSSAPI
15 #include "sshgssc.h"
16 #include "sshgss.h"
17 #endif
18 
19 #define BANNER_LIMIT 131072
20 
21 typedef struct agent_key {
22     strbuf *blob, *comment;
23     ptrlen algorithm;
24 } agent_key;
25 
26 typedef struct Loaded_keyfile_list Loaded_keyfile_list;
27 struct Loaded_keyfile_list
28 {
29     struct ssh2_userkey *ssh2key;
30     strbuf* publickey_blob;
31     Filename* file;
32     char* publickey_comment;
33     char* publickey_algorithm;
34 
35     Loaded_keyfile_list* next;
36 };
37 
38 struct ssh2_userauth_state {
39     int crState;
40 
41     PacketProtocolLayer *transport_layer, *successor_layer;
42     Filename *keyfile;
43     Loaded_keyfile_list* loaded_keyfile_list;
44     bool show_banner, tryagent, notrivialauth, change_username;
45     char *hostname, *fullhostname;
46     char *default_username;
47     bool try_ki_auth, try_gssapi_auth, try_gssapi_kex_auth, gssapi_fwd;
48 
49     ptrlen session_id;
50     enum {
51         AUTH_TYPE_NONE,
52         AUTH_TYPE_PUBLICKEY,
53         AUTH_TYPE_PUBLICKEY_OFFER_LOUD,
54         AUTH_TYPE_PUBLICKEY_OFFER_QUIET,
55         AUTH_TYPE_PASSWORD,
56         AUTH_TYPE_GSSAPI,      /* always QUIET */
57         AUTH_TYPE_KEYBOARD_INTERACTIVE,
58         AUTH_TYPE_KEYBOARD_INTERACTIVE_QUIET
59     } type;
60     bool need_pw, can_pubkey, can_passwd, can_keyb_inter;
61     int userpass_ret;
62     bool tried_pubkey_config, done_agent;
63     struct ssh_connection_shared_gss_state *shgss;
64 #ifndef NO_GSSAPI
65     bool can_gssapi;
66     bool can_gssapi_keyex_auth;
67     bool tried_gssapi;
68     bool tried_gssapi_keyex_auth;
69     time_t gss_cred_expiry;
70     Ssh_gss_buf gss_buf;
71     Ssh_gss_buf gss_rcvtok, gss_sndtok;
72     Ssh_gss_stat gss_stat;
73 #endif
74     bool suppress_wait_for_response_packet;
75     strbuf *last_methods_string;
76     bool kbd_inter_refused;
77     prompts_t *cur_prompt;
78     uint32_t num_prompts;
79     /*fz const*/ char *username;
80     char *locally_allocated_username;
81     char *password;
82     bool got_username;
83     strbuf *publickey_blob;
84     bool privatekey_available, privatekey_encrypted;
85     char *publickey_algorithm;
86     char *publickey_comment;
87     void *agent_response_to_free;
88     ptrlen agent_response;
89     BinarySource asrc[1];          /* for reading SSH agent response */
90     size_t agent_keys_len;
91     agent_key *agent_keys;
92     size_t agent_key_index, agent_key_limit;
93     ptrlen agent_keyalg;
94     unsigned signflags;
95     int len;
96     PktOut *pktout;
97     bool want_user_input;
98     bool is_trivial_auth;
99 
100     agent_pending_query *auth_agent_query;
101     bufchain banner;
102     bufchain_sink banner_bs;
103     StripCtrlChars *banner_scc;
104     bool banner_scc_initialised;
105 
106     StripCtrlChars *ki_scc;
107     bool ki_scc_initialised;
108     bool ki_printed_header;
109 
110     PacketProtocolLayer ppl;
111 
112     Conf* conf;
113 };
114 
115 
new_loaded_keyfile(char * file)116 static Loaded_keyfile_list* new_loaded_keyfile(char* file)
117 {
118     Loaded_keyfile_list* item = snew(Loaded_keyfile_list);
119     item->file = filename_from_str(file);
120     item->next = 0;
121     item->ssh2key = NULL;
122     item->publickey_blob = NULL;
123     item->publickey_comment = NULL;
124     item->publickey_algorithm = NULL;
125 
126     return item;
127 }
128 
free_loaded_keyfile(Loaded_keyfile_list * item)129 static void free_loaded_keyfile(Loaded_keyfile_list* item)
130 {
131     if (!item) {
132         return;
133     }
134     if (item->publickey_blob) {
135         strbuf_free(item->publickey_blob);
136     }
137 
138     if (item->ssh2key) {
139         ssh_key_free(item->ssh2key->key);
140         sfree(item->ssh2key->comment);
141         sfree(item->ssh2key);
142     }
143     filename_free(item->file);
144     sfree(item->publickey_comment);
145     sfree(item->publickey_algorithm);
146 
147     sfree(item);
148 }
149 
150 /* Purge duplicate keys from loaded_keyfile_list */
remove_duplicate_keys(PacketProtocolLayer * ppl,Loaded_keyfile_list ** list,ptrlen blob)151 static void remove_duplicate_keys(PacketProtocolLayer* ppl, Loaded_keyfile_list** list, ptrlen blob)
152 {
153     Loaded_keyfile_list* cur, * prev = NULL;
154     if (!list)
155         return;
156 
157     cur = *list;
158     while (cur) {
159         if (blob.len == cur->publickey_blob->len && !memcmp(blob.ptr, cur->publickey_blob->u, blob.len)) {
160             Loaded_keyfile_list* next;
161             ppl_logevent("Key matched loaded keyfile, remove duplicate");
162             next = cur->next;
163             if (!prev)
164                 *list = next;
165             else
166                 prev->next = next;
167             free_loaded_keyfile(cur);
168             break;
169         }
170         else {
171             prev = cur;
172             cur = cur->next;
173         }
174     }
175 }
176 
load_keyfiles(PacketProtocolLayer * ppl,struct ssh2_userauth_state * s)177 static Loaded_keyfile_list* load_keyfiles(PacketProtocolLayer* ppl, struct ssh2_userauth_state* s)
178 {
179     Loaded_keyfile_list* loaded_list = NULL;
180     int num_loaded = 0;
181     int num_tried = 0;
182     int type;
183 
184     char* val, * file;
185     for (val = conf_get_str_strs(s->conf, CONF_fz_keyfiles, NULL, &file);
186         val != NULL;
187         val = conf_get_str_strs(s->conf, CONF_fz_keyfiles, file, &file))
188     {
189         const char* error = NULL;
190         ++num_tried;
191 
192         Loaded_keyfile_list* loaded = new_loaded_keyfile(file);
193 
194         type = key_type(loaded->file);
195 
196         if (type == SSH_KEYTYPE_SSH2) {
197             loaded->publickey_blob = strbuf_new();
198             if (!ppk_loadpub_f(loaded->file, &loaded->publickey_algorithm,
199                 BinarySink_UPCAST(loaded->publickey_blob),
200                 &loaded->publickey_comment, &error))
201             {
202                 if (!error) {
203                     error = "unknown";
204                 }
205                 ppl_logevent("Failed to load private key '%s': %s", filename_to_str(loaded->file), error);
206                 free_loaded_keyfile(loaded);
207                 continue;
208             }
209 
210             if (ppk_encrypted_f(loaded->file, NULL)) {
211                 loaded->ssh2key = NULL;
212                 ppl_logevent("Private key in '%s' is encrypted, defer loading until use.", filename_to_str(loaded->file));
213             }
214             else {
215                 loaded->ssh2key = ppk_load_f(loaded->file, 0, &error);
216                 if (!loaded->ssh2key) {
217                     if (!error) {
218                         error = "unknown";
219                     }
220                     ppl_logevent("Failed to load private key '%s': %s", filename_to_str(loaded->file), error);
221                     free_loaded_keyfile(loaded);
222                     continue;
223                 }
224             }
225         }
226         else if (type == SSH_KEYTYPE_OPENSSH_PEM || type == SSH_KEYTYPE_OPENSSH_NEW || type == SSH_KEYTYPE_SSHCOM) {
227             loaded->ssh2key = import_ssh2(loaded->file, type, "", &error);
228             if (loaded->ssh2key == SSH2_WRONG_PASSPHRASE) {
229                 loaded->ssh2key = NULL;
230                 ppl_logevent("Failed to load private key '%s': Key is encrypted and not in PuTTY format.", filename_to_str(loaded->file));
231                 free_loaded_keyfile(loaded);
232                 continue;
233             }
234             else if (!loaded->ssh2key) {
235                 if (!error) {
236                     error = "unknown";
237                 }
238                 ppl_logevent("Failed to load private key '%s': %s", filename_to_str(loaded->file), error);
239                 free_loaded_keyfile(loaded);
240                 continue;
241             }
242             else {
243                 loaded->publickey_blob = strbuf_new();
244                 ssh_key_public_blob(loaded->ssh2key->key, BinarySink_UPCAST(loaded->publickey_blob));
245 
246                 if (!loaded->publickey_blob->len) {
247                     ppl_logevent("Failed to load private key '%s': %s", filename_to_str(loaded->file), error);
248                     free_loaded_keyfile(loaded);
249                     continue;
250                 }
251 
252                 loaded->publickey_comment = dupstr(loaded->ssh2key->comment);
253                 loaded->publickey_algorithm = dupstr(ssh_key_ssh_id(loaded->ssh2key->key));
254             }
255         }
256         else {
257             free_loaded_keyfile(loaded);
258             continue;
259         }
260 
261         loaded->next = loaded_list;
262         loaded_list = loaded;
263 
264         num_loaded++;
265     }
266 
267     if (num_tried) {
268         if (num_loaded == 1)
269             ppl_logevent("Successfully loaded %d key pair from file", num_loaded);
270         else
271             ppl_logevent("Successfully loaded %d key pairs from file", num_loaded);
272     }
273 
274     return loaded_list;
275 }
276 
free_loaded_keyfiles(Loaded_keyfile_list * list)277 static void free_loaded_keyfiles(Loaded_keyfile_list* list)
278 {
279     while (list) {
280         Loaded_keyfile_list* next = list->next;
281 
282         free_loaded_keyfile(list);
283 
284         list = next;
285     }
286 }
287 
288 static void ssh2_userauth_free(PacketProtocolLayer *);
289 static void ssh2_userauth_process_queue(PacketProtocolLayer *);
290 static bool ssh2_userauth_get_specials(
291     PacketProtocolLayer *ppl, add_special_fn_t add_special, void *ctx);
292 static void ssh2_userauth_special_cmd(PacketProtocolLayer *ppl,
293                                       SessionSpecialCode code, int arg);
294 static bool ssh2_userauth_want_user_input(PacketProtocolLayer *ppl);
295 static void ssh2_userauth_got_user_input(PacketProtocolLayer *ppl);
296 static void ssh2_userauth_reconfigure(PacketProtocolLayer *ppl, Conf *conf);
297 
298 static void ssh2_userauth_agent_query(struct ssh2_userauth_state *, strbuf *);
299 static void ssh2_userauth_agent_callback(void *, void *, int);
300 static void ssh2_userauth_add_sigblob(
301     struct ssh2_userauth_state *s, PktOut *pkt, ptrlen pkblob, ptrlen sigblob);
302 static void ssh2_userauth_add_session_id(
303     struct ssh2_userauth_state *s, strbuf *sigdata);
304 #ifndef NO_GSSAPI
305 static PktOut *ssh2_userauth_gss_packet(
306     struct ssh2_userauth_state *s, const char *authtype);
307 #endif
308 static void ssh2_userauth_antispoof_msg(
309     struct ssh2_userauth_state *s, const char *msg);
310 
311 static const PacketProtocolLayerVtable ssh2_userauth_vtable = {
312     .free = ssh2_userauth_free,
313     .process_queue = ssh2_userauth_process_queue,
314     .get_specials = ssh2_userauth_get_specials,
315     .special_cmd = ssh2_userauth_special_cmd,
316     .want_user_input = ssh2_userauth_want_user_input,
317     .got_user_input = ssh2_userauth_got_user_input,
318     .reconfigure = ssh2_userauth_reconfigure,
319     .queued_data_size = ssh_ppl_default_queued_data_size,
320     .name = "ssh-userauth",
321 };
322 
ssh2_userauth_new(PacketProtocolLayer * successor_layer,const char * hostname,const char * fullhostname,Filename * keyfile,bool show_banner,bool tryagent,bool notrivialauth,const char * default_username,bool change_username,bool try_ki_auth,bool try_gssapi_auth,bool try_gssapi_kex_auth,bool gssapi_fwd,struct ssh_connection_shared_gss_state * shgss,Conf * conf)323 PacketProtocolLayer *ssh2_userauth_new(
324     PacketProtocolLayer *successor_layer,
325     const char *hostname, const char *fullhostname,
326     Filename *keyfile, bool show_banner, bool tryagent, bool notrivialauth,
327     const char *default_username, bool change_username,
328     bool try_ki_auth, bool try_gssapi_auth, bool try_gssapi_kex_auth,
329     bool gssapi_fwd, struct ssh_connection_shared_gss_state *shgss,
330     Conf* conf)
331 {
332     struct ssh2_userauth_state *s = snew(struct ssh2_userauth_state);
333     memset(s, 0, sizeof(*s));
334     s->ppl.vt = &ssh2_userauth_vtable;
335 
336     s->successor_layer = successor_layer;
337     s->hostname = dupstr(hostname);
338     s->fullhostname = dupstr(fullhostname);
339     s->keyfile = filename_copy(keyfile);
340     s->show_banner = show_banner;
341     s->tryagent = tryagent;
342     s->notrivialauth = notrivialauth;
343     s->default_username = dupstr(default_username);
344     s->change_username = change_username;
345     s->try_ki_auth = try_ki_auth;
346     s->try_gssapi_auth = try_gssapi_auth;
347     s->try_gssapi_kex_auth = try_gssapi_kex_auth;
348     s->gssapi_fwd = gssapi_fwd;
349     s->shgss = shgss;
350     s->last_methods_string = strbuf_new();
351     s->is_trivial_auth = true;
352     bufchain_init(&s->banner);
353     bufchain_sink_init(&s->banner_bs, &s->banner);
354 
355     s->conf = conf_copy(conf);
356 
357     return &s->ppl;
358 }
359 
ssh2_userauth_set_transport_layer(PacketProtocolLayer * userauth,PacketProtocolLayer * transport)360 void ssh2_userauth_set_transport_layer(PacketProtocolLayer *userauth,
361                                        PacketProtocolLayer *transport)
362 {
363     struct ssh2_userauth_state *s =
364         container_of(userauth, struct ssh2_userauth_state, ppl);
365     s->transport_layer = transport;
366 }
367 
ssh2_userauth_free(PacketProtocolLayer * ppl)368 static void ssh2_userauth_free(PacketProtocolLayer *ppl)
369 {
370     struct ssh2_userauth_state *s =
371         container_of(ppl, struct ssh2_userauth_state, ppl);
372     bufchain_clear(&s->banner);
373 
374     if (s->successor_layer)
375         ssh_ppl_free(s->successor_layer);
376 
377     if (s->agent_keys) {
378         for (size_t i = 0; i < s->agent_keys_len; i++) {
379             strbuf_free(s->agent_keys[i].blob);
380             strbuf_free(s->agent_keys[i].comment);
381         }
382         sfree(s->agent_keys);
383     }
384     sfree(s->agent_response_to_free);
385     if (s->auth_agent_query)
386         agent_cancel_query(s->auth_agent_query);
387     filename_free(s->keyfile);
388     free_loaded_keyfiles(s->loaded_keyfile_list);
389     s->loaded_keyfile_list = NULL;
390     sfree(s->default_username);
391     sfree(s->locally_allocated_username);
392     sfree(s->hostname);
393     sfree(s->fullhostname);
394     sfree(s->publickey_comment);
395     sfree(s->publickey_algorithm);
396     if (s->publickey_blob)
397         strbuf_free(s->publickey_blob);
398     strbuf_free(s->last_methods_string);
399     if (s->banner_scc)
400         stripctrl_free(s->banner_scc);
401     if (s->ki_scc)
402         stripctrl_free(s->ki_scc);
403 
404     conf_free(s->conf);
405 
406     sfree(s);
407 }
408 
ssh2_userauth_filter_queue(struct ssh2_userauth_state * s)409 static void ssh2_userauth_filter_queue(struct ssh2_userauth_state *s)
410 {
411     PktIn *pktin;
412     ptrlen string;
413 
414     while ((pktin = pq_peek(s->ppl.in_pq)) != NULL) {
415         switch (pktin->type) {
416           case SSH2_MSG_USERAUTH_BANNER:
417             if (!s->show_banner) {
418                 pq_pop(s->ppl.in_pq);
419                 break;
420             }
421 
422             string = get_string(pktin);
423             if (string.len > BANNER_LIMIT - bufchain_size(&s->banner))
424                 string.len = BANNER_LIMIT - bufchain_size(&s->banner);
425             if (!s->banner_scc_initialised) {
426                 s->banner_scc = seat_stripctrl_new(
427                     s->ppl.seat, BinarySink_UPCAST(&s->banner_bs), SIC_BANNER);
428                 /* FZ GUI does it
429                 if (s->banner_scc)
430                     stripctrl_enable_line_limiting(s->banner_scc);
431                 */
432                 s->banner_scc_initialised = true;
433             }
434             if (s->banner_scc)
435                 put_datapl(s->banner_scc, string);
436             else
437                 put_datapl(&s->banner_bs, string);
438             pq_pop(s->ppl.in_pq);
439             break;
440 
441           default:
442             return;
443         }
444     }
445 }
446 
ssh2_userauth_pop(struct ssh2_userauth_state * s)447 static PktIn *ssh2_userauth_pop(struct ssh2_userauth_state *s)
448 {
449     ssh2_userauth_filter_queue(s);
450     return pq_pop(s->ppl.in_pq);
451 }
452 
ssh2_userauth_process_queue(PacketProtocolLayer * ppl)453 static void ssh2_userauth_process_queue(PacketProtocolLayer *ppl)
454 {
455     struct ssh2_userauth_state *s =
456         container_of(ppl, struct ssh2_userauth_state, ppl);
457     PktIn *pktin;
458 
459     ssh2_userauth_filter_queue(s);     /* no matter why we were called */
460 
461     crBegin(s->crState);
462 
463 #ifndef NO_GSSAPI
464     s->tried_gssapi = false;
465     s->tried_gssapi_keyex_auth = false;
466 #endif
467 
468     /*
469      * Misc one-time setup for authentication.
470      */
471     s->publickey_blob = NULL;
472     s->session_id = ssh2_transport_get_session_id(s->transport_layer);
473 
474     /*
475      * Load the public half of any configured public key file for
476      * later use.
477      */
478     if (!filename_is_null(s->keyfile)) {
479         int keytype;
480         ppl_logevent("Reading key file \"%s\"",
481                      filename_to_str(s->keyfile));
482         keytype = key_type(s->keyfile);
483         if (keytype == SSH_KEYTYPE_SSH2 ||
484             keytype == SSH_KEYTYPE_SSH2_PUBLIC_RFC4716 ||
485             keytype == SSH_KEYTYPE_SSH2_PUBLIC_OPENSSH) {
486             const char *error;
487             s->publickey_blob = strbuf_new();
488             if (ppk_loadpub_f(s->keyfile, &s->publickey_algorithm,
489                               BinarySink_UPCAST(s->publickey_blob),
490                               &s->publickey_comment, &error)) {
491                 s->privatekey_available = (keytype == SSH_KEYTYPE_SSH2);
492                 if (!s->privatekey_available)
493                     ppl_logevent("Key file contains public key only");
494                 s->privatekey_encrypted = ppk_encrypted_f(s->keyfile, NULL);
495             } else {
496                 ppl_logevent("Unable to load key (%s)", error);
497                 ppl_printf("Unable to load key file \"%s\" (%s)\r\n",
498                            filename_to_str(s->keyfile), error);
499                 strbuf_free(s->publickey_blob);
500                 s->publickey_blob = NULL;
501             }
502         } else {
503             ppl_logevent("Unable to use this key file (%s)",
504                          key_type_to_str(keytype));
505             ppl_printf("Unable to use key file \"%s\" (%s)\r\n",
506                        filename_to_str(s->keyfile),
507                        key_type_to_str(keytype));
508             s->publickey_blob = NULL;
509         }
510     }
511 
512     /*
513      * Find out about any keys Pageant has (but if there's a public
514      * key configured, filter out all others).
515      */
516     if (s->tryagent && agent_exists()) {
517         ppl_logevent("Pageant is running. Requesting keys.");
518 
519         /* Request the keys held by the agent. */
520         {
521             strbuf *request = strbuf_new_for_agent_query();
522             put_byte(request, SSH2_AGENTC_REQUEST_IDENTITIES);
523             ssh2_userauth_agent_query(s, request);
524             strbuf_free(request);
525             crWaitUntilV(!s->auth_agent_query);
526         }
527         BinarySource_BARE_INIT_PL(s->asrc, s->agent_response);
528 
529         get_uint32(s->asrc); /* skip length field */
530         if (get_byte(s->asrc) == SSH2_AGENT_IDENTITIES_ANSWER) {
531             size_t nkeys = get_uint32(s->asrc);
532             size_t origpos = s->asrc->pos;
533 
534             /*
535              * Check that the agent response is well formed.
536              */
537             for (size_t i = 0; i < nkeys; i++) {
538                 get_string(s->asrc);   /* blob */
539                 get_string(s->asrc);   /* comment */
540                 if (get_err(s->asrc)) {
541                     ppl_logevent("Pageant's response was truncated");
542                     goto done_agent_query;
543                 }
544             }
545 
546             /*
547              * Copy the list of public-key blobs out of the Pageant
548              * response.
549              */
550             BinarySource_REWIND_TO(s->asrc, origpos);
551             s->agent_keys_len = nkeys;
552             s->agent_keys = snewn(s->agent_keys_len, agent_key);
553             for (size_t i = 0; i < nkeys; i++) {
554                 s->agent_keys[i].blob = strbuf_new();
555                 put_datapl(s->agent_keys[i].blob, get_string(s->asrc));
556                 s->agent_keys[i].comment = strbuf_new();
557                 put_datapl(s->agent_keys[i].comment, get_string(s->asrc));
558 
559                 /* Also, extract the algorithm string from the start
560                  * of the public-key blob. */
561                 BinarySource src[1];
562                 BinarySource_BARE_INIT_PL(src, ptrlen_from_strbuf(
563                     s->agent_keys[i].blob));
564                 s->agent_keys[i].algorithm = get_string(src);
565             }
566 
567             ppl_logevent("Pageant has %"SIZEu" SSH-2 keys", nkeys);
568 
569             if (s->publickey_blob) {
570                 /*
571                  * If we've been given a specific public key blob,
572                  * filter the list of keys to try from the agent down
573                  * to only that one, or none if it's not there.
574                  */
575                 ptrlen our_blob = ptrlen_from_strbuf(s->publickey_blob);
576                 size_t i;
577 
578                 for (i = 0; i < nkeys; i++) {
579                     if (ptrlen_eq_ptrlen(our_blob, ptrlen_from_strbuf(
580                                              s->agent_keys[i].blob)))
581                         break;
582                 }
583 
584                 if (i < nkeys) {
585                     ppl_logevent("Pageant key #%"SIZEu" matches "
586                                  "configured key file", i);
587                     s->agent_key_index = i;
588                     s->agent_key_limit = i+1;
589                 } else {
590                     ppl_logevent("Configured key file not in Pageant");
591                     s->agent_key_index = 0;
592                     s->agent_key_limit = 0;
593                 }
594             } else {
595                 /*
596                  * Otherwise, try them all.
597                  */
598                 s->agent_key_index = 0;
599                 s->agent_key_limit = nkeys;
600             }
601         } else {
602             ppl_logevent("Failed to get reply from Pageant");
603         }
604       done_agent_query:;
605     }
606 
607     /* FZ: Load the keyfiles */
608     s->loaded_keyfile_list = load_keyfiles(ppl, s);
609 
610     /*
611      * We repeat this whole loop, including the username prompt,
612      * until we manage a successful authentication. If the user
613      * types the wrong _password_, they can be sent back to the
614      * beginning to try another username, if this is configured on.
615      * (If they specify a username in the config, they are never
616      * asked, even if they do give a wrong password.)
617      *
618      * I think this best serves the needs of
619      *
620      *  - the people who have no configuration, no keys, and just
621      *    want to try repeated (username,password) pairs until they
622      *    type both correctly
623      *
624      *  - people who have keys and configuration but occasionally
625      *    need to fall back to passwords
626      *
627      *  - people with a key held in Pageant, who might not have
628      *    logged in to a particular machine before; so they want to
629      *    type a username, and then _either_ their key will be
630      *    accepted, _or_ they will type a password. If they mistype
631      *    the username they will want to be able to get back and
632      *    retype it!
633      */
634     s->got_username = false;
635     while (1) {
636         /*
637          * Get a username.
638          */
639         if (s->got_username && !s->change_username) {
640             /*
641              * We got a username last time round this loop, and
642              * with change_username turned off we don't try to get
643              * it again.
644              */
645         } else if ((s->username = s->default_username) == NULL) {
646             s->cur_prompt = new_prompts();
647             s->cur_prompt->to_server = true;
648             s->cur_prompt->from_server = false;
649             s->cur_prompt->name = dupstr("SSH login name");
650             add_prompt(s->cur_prompt, dupstr("login as: "), true);
651             s->userpass_ret = seat_get_userpass_input(
652                 s->ppl.seat, s->cur_prompt, NULL);
653             while (1) {
654                 while (s->userpass_ret < 0 &&
655                        bufchain_size(s->ppl.user_input) > 0)
656                     s->userpass_ret = seat_get_userpass_input(
657                         s->ppl.seat, s->cur_prompt, s->ppl.user_input);
658 
659                 if (s->userpass_ret >= 0)
660                     break;
661 
662                 s->want_user_input = true;
663                 crReturnV;
664                 s->want_user_input = false;
665             }
666             if (!s->userpass_ret) {
667                 /*
668                  * seat_get_userpass_input() failed to get a username.
669                  * Terminate.
670                  */
671                 free_prompts(s->cur_prompt);
672                 ssh_user_close(s->ppl.ssh, "No username provided");
673                 return;
674             }
675             sfree(s->locally_allocated_username); /* for change_username */
676             s->username = s->locally_allocated_username =
677                 prompt_get_result(s->cur_prompt->prompts[0]);
678             free_prompts(s->cur_prompt);
679         } else {
680             if (seat_verbose(s->ppl.seat) || seat_interactive(s->ppl.seat))
681                 ppl_printf("Using username \"%s\".\r\n", s->username);
682         }
683         s->got_username = true;
684 
685         /*
686          * Send an authentication request using method "none": (a)
687          * just in case it succeeds, and (b) so that we know what
688          * authentication methods we can usefully try next.
689          */
690         s->ppl.bpp->pls->actx = SSH2_PKTCTX_NOAUTH;
691 
692         s->pktout = ssh_bpp_new_pktout(s->ppl.bpp, SSH2_MSG_USERAUTH_REQUEST);
693         put_stringz(s->pktout, s->username);
694         put_stringz(s->pktout, s->successor_layer->vt->name);
695         put_stringz(s->pktout, "none");    /* method */
696         pq_push(s->ppl.out_pq, s->pktout);
697         s->type = AUTH_TYPE_NONE;
698 
699         s->tried_pubkey_config = false;
700         s->kbd_inter_refused = false;
701         s->done_agent = false;
702 
703         while (1) {
704             /*
705              * Wait for the result of the last authentication request,
706              * unless the request terminated for some reason on our
707              * own side.
708              */
709             if (s->suppress_wait_for_response_packet) {
710                 pktin = NULL;
711                 s->suppress_wait_for_response_packet = false;
712             } else {
713                 crMaybeWaitUntilV((pktin = ssh2_userauth_pop(s)) != NULL);
714             }
715 
716             /*
717              * Now is a convenient point to spew any banner material
718              * that we've accumulated. (This should ensure that when
719              * we exit the auth loop, we haven't any left to deal
720              * with.)
721              *
722              * Don't show the banner if we're operating in non-verbose
723              * non-interactive mode. (It's probably a script, which
724              * means nobody will read the banner _anyway_, and
725              * moreover the printing of the banner will screw up
726              * processing on the output of (say) plink.)
727              *
728              * The banner data has been sanitised already by this
729              * point, but we still need to precede and follow it with
730              * anti-spoofing header lines.
731              */
732             if (bufchain_size(&s->banner) &&
733                 (seat_verbose(s->ppl.seat) || seat_interactive(s->ppl.seat))) {
734                 if (s->banner_scc) {
735                     ssh2_userauth_antispoof_msg(
736                         s, "Pre-authentication banner message from server:");
737                     seat_set_trust_status(s->ppl.seat, false);
738                 }
739 
740                 bool mid_line = false;
741                 while (bufchain_size(&s->banner) > 0) {
742                     ptrlen data = bufchain_prefix(&s->banner);
743                     seat_stderr_pl(s->ppl.seat, data);
744                     mid_line =
745                         (((const char *)data.ptr)[data.len-1] != '\n');
746                     bufchain_consume(&s->banner, data.len);
747                 }
748                 bufchain_clear(&s->banner);
749 
750                 if (mid_line)
751                     seat_stderr_pl(s->ppl.seat, PTRLEN_LITERAL("\r\n"));
752 
753                 if (s->banner_scc) {
754                     seat_set_trust_status(s->ppl.seat, true);
755                     ssh2_userauth_antispoof_msg(
756                         s, "End of banner message from server");
757                 }
758             }
759 
760             if (pktin && pktin->type == SSH2_MSG_USERAUTH_SUCCESS) {
761                 ppl_logevent("Access granted");
762                 goto userauth_success;
763             }
764 
765             if (pktin && pktin->type != SSH2_MSG_USERAUTH_FAILURE &&
766                 s->type != AUTH_TYPE_GSSAPI) {
767                 ssh_proto_error(s->ppl.ssh, "Received unexpected packet "
768                                 "in response to authentication request, "
769                                 "type %d (%s)", pktin->type,
770                                 ssh2_pkt_type(s->ppl.bpp->pls->kctx,
771                                               s->ppl.bpp->pls->actx,
772                                               pktin->type));
773                 return;
774             }
775 
776             /*
777              * OK, we're now sitting on a USERAUTH_FAILURE message, so
778              * we can look at the string in it and know what we can
779              * helpfully try next.
780              */
781             if (pktin && pktin->type == SSH2_MSG_USERAUTH_FAILURE) {
782                 ptrlen methods = get_string(pktin);
783                 bool partial_success = get_bool(pktin);
784 
785                 if (!partial_success) {
786                     /*
787                      * We have received an unequivocal Access
788                      * Denied. This can translate to a variety of
789                      * messages, or no message at all.
790                      *
791                      * For forms of authentication which are attempted
792                      * implicitly, by which I mean without printing
793                      * anything in the window indicating that we're
794                      * trying them, we should never print 'Access
795                      * denied'.
796                      *
797                      * If we do print a message saying that we're
798                      * attempting some kind of authentication, it's OK
799                      * to print a followup message saying it failed -
800                      * but the message may sometimes be more specific
801                      * than simply 'Access denied'.
802                      *
803                      * Additionally, if we'd just tried password
804                      * authentication, we should break out of this
805                      * whole loop so as to go back to the username
806                      * prompt (iff we're configured to allow
807                      * username change attempts).
808                      */
809                     if (s->type == AUTH_TYPE_NONE) {
810                         /* do nothing */
811                     } else if (s->type == AUTH_TYPE_PUBLICKEY_OFFER_LOUD ||
812                                s->type == AUTH_TYPE_PUBLICKEY_OFFER_QUIET) {
813                         if (s->type == AUTH_TYPE_PUBLICKEY_OFFER_LOUD)
814                             ppl_printf("Server refused our key\r\n");
815                         ppl_logevent("Server refused our key");
816                     } else if (s->type == AUTH_TYPE_PUBLICKEY) {
817                         /* This _shouldn't_ happen except by a
818                          * protocol bug causing client and server to
819                          * disagree on what is a correct signature. */
820                         ppl_printf("Server refused public-key signature"
821                                    " despite accepting key!\r\n");
822                         ppl_logevent("Server refused public-key signature"
823                                      " despite accepting key!");
824                     } else if (s->type==AUTH_TYPE_KEYBOARD_INTERACTIVE_QUIET) {
825                         /* quiet, so no ppl_printf */
826                         ppl_logevent("Server refused keyboard-interactive "
827                                      "authentication");
828                     } else if (s->type==AUTH_TYPE_GSSAPI) {
829                         /* always quiet, so no ppl_printf */
830                         /* also, the code down in the GSSAPI block has
831                          * already logged this in the Event Log */
832                     } else if (s->type == AUTH_TYPE_KEYBOARD_INTERACTIVE) {
833                         ppl_logevent("Keyboard-interactive authentication "
834                                      "failed");
835                         ppl_printf("Access denied\r\n");
836                     } else {
837                         assert(s->type == AUTH_TYPE_PASSWORD);
838                         ppl_logevent("Password authentication failed");
839                         ppl_printf("Access denied\r\n");
840 
841                         if (s->change_username) {
842                             /* XXX perhaps we should allow
843                              * keyboard-interactive to do this too? */
844                             goto try_new_username;
845                         }
846                     }
847                 } else {
848                     ppl_printf("Further authentication required\r\n");
849                     ppl_logevent("Further authentication required");
850                 }
851 
852                 /*
853                  * Save the methods string for use in error messages.
854                  */
855                 strbuf_clear(s->last_methods_string);
856                 put_datapl(s->last_methods_string, methods);
857 
858                 /*
859                  * Scan it for method identifiers we know about.
860                  */
861                 bool srv_pubkey = false, srv_passwd = false;
862                 bool srv_keyb_inter = false;
863 #ifndef NO_GSSAPI
864                 bool srv_gssapi = false, srv_gssapi_keyex_auth = false;
865 #endif
866 
867                 for (ptrlen method; get_commasep_word(&methods, &method) ;) {
868                     if (ptrlen_eq_string(method, "publickey"))
869                         srv_pubkey = true;
870                     else if (ptrlen_eq_string(method, "password"))
871                         srv_passwd = true;
872                     else if (ptrlen_eq_string(method, "keyboard-interactive"))
873                         srv_keyb_inter = true;
874 #ifndef NO_GSSAPI
875                     else if (ptrlen_eq_string(method, "gssapi-with-mic"))
876                         srv_gssapi = true;
877                     else if (ptrlen_eq_string(method, "gssapi-keyex"))
878                         srv_gssapi_keyex_auth = true;
879 #endif
880                 }
881 
882                 /*
883                  * And combine those flags with our own configuration
884                  * and context to set the main can_foo variables.
885                  */
886                 s->can_pubkey = srv_pubkey;
887                 s->can_passwd = srv_passwd;
888                 s->can_keyb_inter = s->try_ki_auth && srv_keyb_inter;
889 #ifndef NO_GSSAPI
890                 s->can_gssapi = s->try_gssapi_auth && srv_gssapi &&
891                     s->shgss->libs->nlibraries > 0;
892                 s->can_gssapi_keyex_auth = s->try_gssapi_kex_auth &&
893                     srv_gssapi_keyex_auth &&
894                     s->shgss->libs->nlibraries > 0 && s->shgss->ctx;
895 #endif
896             }
897 
898             s->ppl.bpp->pls->actx = SSH2_PKTCTX_NOAUTH;
899 
900 #ifndef NO_GSSAPI
901             if (s->can_gssapi_keyex_auth && !s->tried_gssapi_keyex_auth) {
902 
903                 /* gssapi-keyex authentication */
904 
905                 s->type = AUTH_TYPE_GSSAPI;
906                 s->tried_gssapi_keyex_auth = true;
907                 s->ppl.bpp->pls->actx = SSH2_PKTCTX_GSSAPI;
908 
909                 if (s->shgss->lib->gsslogmsg)
910                     ppl_logevent("%s", s->shgss->lib->gsslogmsg);
911 
912                 ppl_logevent("Trying gssapi-keyex...");
913                 s->pktout = ssh2_userauth_gss_packet(s, "gssapi-keyex");
914                 pq_push(s->ppl.out_pq, s->pktout);
915                 s->shgss->lib->release_cred(s->shgss->lib, &s->shgss->ctx);
916                 s->shgss->ctx = NULL;
917 
918                 continue;
919             } else
920 #endif /* NO_GSSAPI */
921 
922             if (s->can_pubkey && !s->done_agent &&
923                 s->agent_key_index < s->agent_key_limit) {
924 
925                 /*
926                  * Attempt public-key authentication using a key from Pageant.
927                  */
928                 s->agent_keyalg = s->agent_keys[s->agent_key_index].algorithm;
929                 s->signflags = 0;
930                 if (ptrlen_eq_string(s->agent_keyalg, "ssh-rsa")) {
931                     /* Try to upgrade ssh-rsa to one of the rsa-sha2-* family,
932                      * if the server has announced support for them. */
933                     if (s->ppl.bpp->ext_info_rsa_sha512_ok) {
934                         s->agent_keyalg = PTRLEN_LITERAL("rsa-sha2-512");
935                         s->signflags = SSH_AGENT_RSA_SHA2_512;
936                     } else if (s->ppl.bpp->ext_info_rsa_sha256_ok) {
937                         s->agent_keyalg = PTRLEN_LITERAL("rsa-sha2-256");
938                         s->signflags = SSH_AGENT_RSA_SHA2_256;
939                     }
940                 }
941 
942                 s->ppl.bpp->pls->actx = SSH2_PKTCTX_PUBLICKEY;
943 
944                 ppl_logevent("Trying Pageant key #%"SIZEu, s->agent_key_index);
945 
946                 remove_duplicate_keys(ppl, &s->loaded_keyfile_list, ptrlen_from_strbuf(
947                           s->agent_keys[s->agent_key_index].blob));
948 
949                 /* See if server will accept it */
950                 s->pktout = ssh_bpp_new_pktout(
951                     s->ppl.bpp, SSH2_MSG_USERAUTH_REQUEST);
952                 put_stringz(s->pktout, s->username);
953                 put_stringz(s->pktout, s->successor_layer->vt->name);
954                 put_stringz(s->pktout, "publickey");
955                                                     /* method */
956                 put_bool(s->pktout, false); /* no signature included */
957                 put_stringpl(s->pktout, s->agent_keyalg);
958                 put_stringpl(s->pktout, ptrlen_from_strbuf(
959                             s->agent_keys[s->agent_key_index].blob));
960                 pq_push(s->ppl.out_pq, s->pktout);
961                 s->type = AUTH_TYPE_PUBLICKEY_OFFER_QUIET;
962 
963                 crMaybeWaitUntilV((pktin = ssh2_userauth_pop(s)) != NULL);
964                 if (pktin->type != SSH2_MSG_USERAUTH_PK_OK) {
965 
966                     /* Offer of key refused, presumably via
967                      * USERAUTH_FAILURE. Requeue for the next iteration. */
968                     pq_push_front(s->ppl.in_pq, pktin);
969 
970                 } else {
971                     strbuf *agentreq, *sigdata;
972                     ptrlen comment = ptrlen_from_strbuf(
973                         s->agent_keys[s->agent_key_index].comment);
974 
975                     if (seat_verbose(s->ppl.seat))
976                         ppl_printf("Authenticating with public key "
977                                    "\"%.*s\" from agent\r\n",
978                                    PTRLEN_PRINTF(comment));
979 
980                     /*
981                      * Server is willing to accept the key.
982                      * Construct a SIGN_REQUEST.
983                      */
984                     s->pktout = ssh_bpp_new_pktout(
985                         s->ppl.bpp, SSH2_MSG_USERAUTH_REQUEST);
986                     put_stringz(s->pktout, s->username);
987                     put_stringz(s->pktout, s->successor_layer->vt->name);
988                     put_stringz(s->pktout, "publickey");
989                                                         /* method */
990                     put_bool(s->pktout, true);  /* signature included */
991                     put_stringpl(s->pktout, s->agent_keyalg);
992                     put_stringpl(s->pktout, ptrlen_from_strbuf(
993                             s->agent_keys[s->agent_key_index].blob));
994 
995                     /* Ask agent for signature. */
996                     agentreq = strbuf_new_for_agent_query();
997                     put_byte(agentreq, SSH2_AGENTC_SIGN_REQUEST);
998                     put_stringpl(agentreq, ptrlen_from_strbuf(
999                             s->agent_keys[s->agent_key_index].blob));
1000                     /* Now the data to be signed... */
1001                     sigdata = strbuf_new();
1002                     ssh2_userauth_add_session_id(s, sigdata);
1003                     put_data(sigdata, s->pktout->data + 5,
1004                              s->pktout->length - 5);
1005                     put_stringsb(agentreq, sigdata);
1006                     /* And finally the flags word. */
1007                     put_uint32(agentreq, s->signflags);
1008                     ssh2_userauth_agent_query(s, agentreq);
1009                     strbuf_free(agentreq);
1010                     crWaitUntilV(!s->auth_agent_query);
1011 
1012                     if (s->agent_response.ptr) {
1013                         ptrlen sigblob;
1014                         BinarySource src[1];
1015                         BinarySource_BARE_INIT(src, s->agent_response.ptr,
1016                                                s->agent_response.len);
1017                         get_uint32(src); /* skip length field */
1018                         if (get_byte(src) == SSH2_AGENT_SIGN_RESPONSE &&
1019                             (sigblob = get_string(src), !get_err(src))) {
1020                             ppl_logevent("Sending Pageant's response");
1021                             ssh2_userauth_add_sigblob(
1022                                 s, s->pktout,
1023                                 ptrlen_from_strbuf(
1024                                     s->agent_keys[s->agent_key_index].blob),
1025                                 sigblob);
1026                             pq_push(s->ppl.out_pq, s->pktout);
1027                             s->type = AUTH_TYPE_PUBLICKEY;
1028                             s->is_trivial_auth = false;
1029                         } else {
1030                             ppl_logevent("Pageant refused signing request");
1031                             ppl_printf("Pageant failed to "
1032                                        "provide a signature\r\n");
1033                             s->suppress_wait_for_response_packet = true;
1034                             ssh_free_pktout(s->pktout);
1035                         }
1036                     } else {
1037                         ppl_logevent("Pageant failed to respond to "
1038                                      "signing request");
1039                         ppl_printf("Pageant failed to "
1040                                    "respond to signing request\r\n");
1041                         s->suppress_wait_for_response_packet = true;
1042                         ssh_free_pktout(s->pktout);
1043                     }
1044                 }
1045 
1046                 /* Do we have any keys left to try? */
1047                 if (++s->agent_key_index >= s->agent_key_limit)
1048                     s->done_agent = true;
1049 
1050             } else if (s->can_pubkey && s->publickey_blob &&
1051                        s->privatekey_available && !s->tried_pubkey_config) {
1052 
1053                 ssh2_userkey *key;   /* not live over crReturn */
1054                 char *passphrase;           /* not live over crReturn */
1055 
1056                 s->ppl.bpp->pls->actx = SSH2_PKTCTX_PUBLICKEY;
1057 
1058                 s->tried_pubkey_config = true;
1059 
1060                 /*
1061                  * Try the public key supplied in the configuration.
1062                  *
1063                  * First, try to upgrade its algorithm.
1064                  */
1065                 if (!strcmp(s->publickey_algorithm, "ssh-rsa")) {
1066                     /* Try to upgrade ssh-rsa to one of the rsa-sha2-* family,
1067                      * if the server has announced support for them. */
1068                     if (s->ppl.bpp->ext_info_rsa_sha512_ok) {
1069                         sfree(s->publickey_algorithm);
1070                         s->publickey_algorithm = dupstr("rsa-sha2-512");
1071                         s->signflags = SSH_AGENT_RSA_SHA2_512;
1072                     } else if (s->ppl.bpp->ext_info_rsa_sha256_ok) {
1073                         sfree(s->publickey_algorithm);
1074                         s->publickey_algorithm = dupstr("rsa-sha2-256");
1075                         s->signflags = SSH_AGENT_RSA_SHA2_256;
1076                     }
1077                 }
1078 
1079                 /*
1080                  * Offer the public blob to see if the server is willing to
1081                  * accept it.
1082                  */
1083                 s->pktout = ssh_bpp_new_pktout(
1084                     s->ppl.bpp, SSH2_MSG_USERAUTH_REQUEST);
1085                 put_stringz(s->pktout, s->username);
1086                 put_stringz(s->pktout, s->successor_layer->vt->name);
1087                 put_stringz(s->pktout, "publickey");    /* method */
1088                 put_bool(s->pktout, false);
1089                                                 /* no signature included */
1090                 put_stringz(s->pktout, s->publickey_algorithm);
1091                 put_string(s->pktout, s->publickey_blob->s,
1092                            s->publickey_blob->len);
1093                 pq_push(s->ppl.out_pq, s->pktout);
1094                 ppl_logevent("Offered public key");
1095 
1096                 crMaybeWaitUntilV((pktin = ssh2_userauth_pop(s)) != NULL);
1097                 if (pktin->type != SSH2_MSG_USERAUTH_PK_OK) {
1098                     /* Key refused. Give up. */
1099                     pq_push_front(s->ppl.in_pq, pktin);
1100                     s->type = AUTH_TYPE_PUBLICKEY_OFFER_LOUD;
1101                     continue; /* process this new message */
1102                 }
1103                 ppl_logevent("Offer of public key accepted");
1104 
1105                 /*
1106                  * Actually attempt a serious authentication using
1107                  * the key.
1108                  */
1109                 if (seat_verbose(s->ppl.seat))
1110                     ppl_printf("Authenticating with public key \"%s\"\r\n",
1111                                s->publickey_comment);
1112 
1113                 key = NULL;
1114                 while (!key) {
1115                     const char *error;  /* not live over crReturn */
1116                     if (s->privatekey_encrypted) {
1117                         /*
1118                          * Get a passphrase from the user.
1119                          */
1120                         s->cur_prompt = new_prompts();
1121                         s->cur_prompt->to_server = false;
1122                         s->cur_prompt->from_server = false;
1123                         s->cur_prompt->name = dupstr("SSH key passphrase");
1124                         add_prompt(s->cur_prompt,
1125                                    dupprintf("Passphrase for key \"%s\" in key file \"%s\"",
1126                                              s->publickey_comment, filename_to_str(s->keyfile)),
1127                                    false);
1128                         s->userpass_ret = seat_get_userpass_input(
1129                             s->ppl.seat, s->cur_prompt, NULL);
1130                         while (1) {
1131                             while (s->userpass_ret < 0 &&
1132                                    bufchain_size(s->ppl.user_input) > 0)
1133                                 s->userpass_ret = seat_get_userpass_input(
1134                                     s->ppl.seat, s->cur_prompt,
1135                                     s->ppl.user_input);
1136 
1137                             if (s->userpass_ret >= 0)
1138                                 break;
1139 
1140                             s->want_user_input = true;
1141                             crReturnV;
1142                             s->want_user_input = false;
1143                         }
1144                         if (!s->userpass_ret) {
1145                             /* Failed to get a passphrase. Terminate. */
1146                             free_prompts(s->cur_prompt);
1147                             ssh_bpp_queue_disconnect(
1148                                 s->ppl.bpp, "Unable to authenticate",
1149                                 SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER);
1150                             ssh_user_close(s->ppl.ssh, "User aborted at "
1151                                            "passphrase prompt");
1152                             return;
1153                         }
1154                         passphrase =
1155                             prompt_get_result(s->cur_prompt->prompts[0]);
1156                         free_prompts(s->cur_prompt);
1157                     } else {
1158                         passphrase = NULL; /* no passphrase needed */
1159                     }
1160 
1161                     /*
1162                      * Try decrypting the key.
1163                      */
1164                     key = ppk_load_f(s->keyfile, passphrase, &error);
1165                     if (passphrase) {
1166                         /* burn the evidence */
1167                         smemclr(passphrase, strlen(passphrase));
1168                         sfree(passphrase);
1169                     }
1170                     if (key == SSH2_WRONG_PASSPHRASE || key == NULL) {
1171                         if (passphrase &&
1172                             (key == SSH2_WRONG_PASSPHRASE)) {
1173                             ppl_printf("Wrong passphrase\r\n");
1174                             key = NULL;
1175                             /* and loop again */
1176                         } else {
1177                             ppl_printf("Unable to load private key (%s)\r\n",
1178                                        error);
1179                             key = NULL;
1180                             s->suppress_wait_for_response_packet = true;
1181                             break; /* try something else */
1182                         }
1183                     } else {
1184                         /* FIXME: if we ever support variable signature
1185                          * flags, this is somewhere they'll need to be
1186                          * put */
1187                         char *invalid = ssh_key_invalid(key->key, 0);
1188                         if (invalid) {
1189                             ppl_printf("Cannot use this private key (%s)\r\n",
1190                                        invalid);
1191                             ssh_key_free(key->key);
1192                             sfree(key->comment);
1193                             sfree(key);
1194                             sfree(invalid);
1195                             key = NULL;
1196                             s->suppress_wait_for_response_packet = true;
1197                             break; /* try something else */
1198                         }
1199                     }
1200                 }
1201 
1202                 if (key) {
1203                     strbuf *pkblob, *sigdata, *sigblob;
1204 
1205                     /*
1206                      * We have loaded the private key and the server
1207                      * has announced that it's willing to accept it.
1208                      * Hallelujah. Generate a signature and send it.
1209                      */
1210                     s->pktout = ssh_bpp_new_pktout(
1211                         s->ppl.bpp, SSH2_MSG_USERAUTH_REQUEST);
1212                     put_stringz(s->pktout, s->username);
1213                     put_stringz(s->pktout, s->successor_layer->vt->name);
1214                     put_stringz(s->pktout, "publickey"); /* method */
1215                     put_bool(s->pktout, true); /* signature follows */
1216                     put_stringz(s->pktout, s->publickey_algorithm);
1217                     pkblob = strbuf_new();
1218                     ssh_key_public_blob(key->key, BinarySink_UPCAST(pkblob));
1219                     put_string(s->pktout, pkblob->s, pkblob->len);
1220 
1221                     /*
1222                      * The data to be signed is:
1223                      *
1224                      *   string  session-id
1225                      *
1226                      * followed by everything so far placed in the
1227                      * outgoing packet.
1228                      */
1229                     sigdata = strbuf_new();
1230                     ssh2_userauth_add_session_id(s, sigdata);
1231                     put_data(sigdata, s->pktout->data + 5,
1232                              s->pktout->length - 5);
1233                     sigblob = strbuf_new();
1234                     ssh_key_sign(key->key, ptrlen_from_strbuf(sigdata),
1235                                  s->signflags, BinarySink_UPCAST(sigblob));
1236                     strbuf_free(sigdata);
1237                     ssh2_userauth_add_sigblob(
1238                         s, s->pktout, ptrlen_from_strbuf(pkblob),
1239                         ptrlen_from_strbuf(sigblob));
1240                     strbuf_free(pkblob);
1241                     strbuf_free(sigblob);
1242 
1243                     pq_push(s->ppl.out_pq, s->pktout);
1244                     ppl_logevent("Sent public key signature");
1245                     s->type = AUTH_TYPE_PUBLICKEY;
1246                     ssh_key_free(key->key);
1247                     sfree(key->comment);
1248                     sfree(key);
1249                     s->is_trivial_auth = false;
1250                 }
1251 
1252             } else if (s->can_pubkey && s->loaded_keyfile_list) {
1253 
1254                 Loaded_keyfile_list *next_keyfile;
1255                 ssh2_userkey *key;   /* not live over crReturn */
1256                 char *passphrase;
1257 
1258                 s->ppl.bpp->pls->actx = SSH2_PKTCTX_PUBLICKEY;
1259 
1260                 /*
1261                  * Try the public key supplied in the configuration.
1262                  *
1263                  * First, try to upgrade its algorithm.
1264                  */
1265                 if (!strcmp(s->loaded_keyfile_list->publickey_algorithm, "ssh-rsa")) {
1266                     /* Try to upgrade ssh-rsa to one of the rsa-sha2-* family,
1267                      * if the server has announced support for them. */
1268                     if (s->ppl.bpp->ext_info_rsa_sha512_ok) {
1269                         sfree(s->loaded_keyfile_list->publickey_algorithm);
1270                         s->loaded_keyfile_list->publickey_algorithm = dupstr("rsa-sha2-512");
1271                         s->signflags = SSH_AGENT_RSA_SHA2_512;
1272                     } else if (s->ppl.bpp->ext_info_rsa_sha256_ok) {
1273                         sfree(s->loaded_keyfile_list->publickey_algorithm);
1274                         s->loaded_keyfile_list->publickey_algorithm = dupstr("rsa-sha2-256");
1275                         s->signflags = SSH_AGENT_RSA_SHA2_256;
1276                     }
1277                 }
1278 
1279                 /*
1280                  * Offer the public blob to see if the server is willing to
1281                  * accept it.
1282                  */
1283                 s->pktout = ssh_bpp_new_pktout(s->ppl.bpp, SSH2_MSG_USERAUTH_REQUEST);
1284                 put_stringz(s->pktout, s->username);
1285                 put_stringz(s->pktout, s->successor_layer->vt->name);
1286                 put_stringz(s->pktout, "publickey");    /* method */
1287                 put_bool(s->pktout, false);
1288                                                 /* no signature included */
1289                 put_stringz(s->pktout, s->loaded_keyfile_list->publickey_algorithm);
1290                 put_string(s->pktout, s->loaded_keyfile_list->publickey_blob->s,
1291                            s->loaded_keyfile_list->publickey_blob->len);
1292                 pq_push(s->ppl.out_pq, s->pktout);
1293                 ppl_logevent("Offered public key from \"%s\"", filename_to_str(s->loaded_keyfile_list->file));
1294 
1295                 crMaybeWaitUntilV((pktin = ssh2_userauth_pop(s)) != NULL);
1296                 if (pktin->type != SSH2_MSG_USERAUTH_PK_OK) {
1297                     /* Key refused. Give up. */
1298                     next_keyfile = s->loaded_keyfile_list->next;
1299                     free_loaded_keyfile(s->loaded_keyfile_list);
1300                     s->loaded_keyfile_list = next_keyfile;
1301                     pq_push_front(s->ppl.in_pq, pktin);
1302                     s->type = AUTH_TYPE_PUBLICKEY_OFFER_LOUD;
1303                     continue; /* process this new message */
1304                 }
1305                 ppl_logevent("Offer of public key accepted, trying to authenticate using it.");
1306 
1307                 /*
1308                  * Actually attempt a serious authentication using
1309                  * the key.
1310                  */
1311                 /*if (flags & FLAG_VERBOSE)
1312                     ppl_printf("Authenticating with public key \"%s\"\r\n",
1313                                s->publickey_comment);
1314                 */
1315 
1316                 key = s->loaded_keyfile_list->ssh2key;
1317                 while (!key) {
1318                     const char *error;  /* not live over crReturn */
1319                     if (!key) {
1320                         /*
1321                          * Get a passphrase from the user.
1322                          */
1323                         s->cur_prompt = new_prompts();
1324                         s->cur_prompt->to_server = false;
1325                         s->cur_prompt->from_server = false;
1326                         s->cur_prompt->name = dupstr("SSH key passphrase");
1327                         add_prompt(s->cur_prompt,
1328                                    dupprintf("Passphrase for key \"%s\" in key file \"%s\"",
1329                                              s->loaded_keyfile_list->publickey_comment, filename_to_str(s->loaded_keyfile_list->file)),
1330                                    false);
1331                         s->userpass_ret = seat_get_userpass_input(
1332                             s->ppl.seat, s->cur_prompt, NULL);
1333                         while (1) {
1334                            while (s->userpass_ret < 0 &&
1335                                    bufchain_size(s->ppl.user_input) > 0)
1336                                 s->userpass_ret = seat_get_userpass_input(
1337                                     s->ppl.seat, s->cur_prompt,
1338                                     s->ppl.user_input);
1339 
1340                             if (s->userpass_ret >= 0)
1341                                 break;
1342 
1343                             s->want_user_input = true;
1344                             crReturnV;
1345                             s->want_user_input = false;
1346                         }
1347                         if (!s->userpass_ret) {
1348                             /* Failed to get a passphrase. Terminate. */
1349                             free_prompts(s->cur_prompt);
1350                             ssh_bpp_queue_disconnect(
1351                                 s->ppl.bpp, "Unable to authenticate",
1352                                 SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER);
1353                             ssh_user_close(s->ppl.ssh, "User aborted at "
1354                                            "passphrase prompt");
1355                             return;
1356                         }
1357                         passphrase =
1358                             prompt_get_result(s->cur_prompt->prompts[0]);
1359                         free_prompts(s->cur_prompt);
1360                     } else {
1361                         passphrase = NULL; /* no passphrase needed */
1362                     }
1363 
1364                     /*
1365                      * Try decrypting the key.
1366                      */
1367                     key = ppk_load_f(s->loaded_keyfile_list->file, passphrase, &error);
1368                     if (passphrase) {
1369                         /* burn the evidence */
1370                         smemclr(passphrase, strlen(passphrase));
1371                         sfree(passphrase);
1372                     }
1373                     if (key == SSH2_WRONG_PASSPHRASE || key == NULL) {
1374                         if (passphrase &&
1375                             (key == SSH2_WRONG_PASSPHRASE)) {
1376                             ppl_printf("Wrong passphrase\r\n");
1377                             key = NULL;
1378                             /* and loop again */
1379                         } else {
1380                             ppl_printf("Unable to load private key (%s)\r\n", error);
1381                             key = NULL;
1382                             break; /* try something else */
1383                         }
1384                     } else {
1385                         /* FIXME: if we ever support variable signature
1386                          * flags, this is somewhere they'll need to be
1387                          * put */
1388                         char *invalid = ssh_key_invalid(key->key, 0);
1389                         if (invalid) {
1390                             ppl_printf("Cannot use this private key (%s)\r\n",
1391                                        invalid);
1392                             ssh_key_free(key->key);
1393                             sfree(key->comment);
1394                             sfree(key);
1395                             sfree(invalid);
1396                             key = NULL;
1397                             s->suppress_wait_for_response_packet = true;
1398                             break; /* try something else */
1399                         }
1400                     }
1401                 }
1402 
1403                 if (key) {
1404                     strbuf *sigdata, *sigblob;
1405 
1406                     /*
1407                      * We have loaded the private key and the server
1408                      * has announced that it's willing to accept it.
1409                      * Hallelujah. Generate a signature and send it.
1410                      */
1411                     s->pktout = ssh_bpp_new_pktout(
1412                         s->ppl.bpp, SSH2_MSG_USERAUTH_REQUEST);
1413                     put_stringz(s->pktout, s->username);
1414                     put_stringz(s->pktout, s->successor_layer->vt->name);
1415                     put_stringz(s->pktout, "publickey"); /* method */
1416                     put_bool(s->pktout, true); /* signature follows */
1417                     put_stringz(s->pktout, s->loaded_keyfile_list->publickey_algorithm);
1418                     put_string(s->pktout, s->loaded_keyfile_list->publickey_blob->s, s->loaded_keyfile_list->publickey_blob->len);
1419 
1420                     /*
1421                      * The data to be signed is:
1422                      *
1423                      *   string  session-id
1424                      *
1425                      * followed by everything so far placed in the
1426                      * outgoing packet.
1427                      */
1428                     sigdata = strbuf_new();
1429                     ssh2_userauth_add_session_id(s, sigdata);
1430                     put_data(sigdata, s->pktout->data + 5,
1431                              s->pktout->length - 5);
1432                     sigblob = strbuf_new();
1433                     ssh_key_sign(key->key, ptrlen_from_strbuf(sigdata),
1434                                  s->signflags, BinarySink_UPCAST(sigblob));
1435                     strbuf_free(sigdata);
1436                     ssh2_userauth_add_sigblob(
1437                         s, s->pktout, ptrlen_from_strbuf(s->loaded_keyfile_list->publickey_blob),
1438                         ptrlen_from_strbuf(sigblob));
1439                     strbuf_free(sigblob);
1440 
1441                     pq_push(s->ppl.out_pq, s->pktout);
1442                     ppl_logevent("Sent public key signature");
1443                     s->type = AUTH_TYPE_PUBLICKEY;
1444                     s->loaded_keyfile_list->ssh2key = key;
1445                     s->is_trivial_auth = false;
1446                 }
1447                 next_keyfile = s->loaded_keyfile_list->next;
1448                 free_loaded_keyfile(s->loaded_keyfile_list);
1449                 s->loaded_keyfile_list = next_keyfile;
1450 #ifndef NO_GSSAPI
1451             } else if (s->can_gssapi && !s->tried_gssapi) {
1452 
1453                 /* gssapi-with-mic authentication */
1454 
1455                 ptrlen data;
1456 
1457                 s->type = AUTH_TYPE_GSSAPI;
1458                 s->tried_gssapi = true;
1459                 s->ppl.bpp->pls->actx = SSH2_PKTCTX_GSSAPI;
1460 
1461                 if (s->shgss->lib->gsslogmsg)
1462                     ppl_logevent("%s", s->shgss->lib->gsslogmsg);
1463 
1464                 /* Sending USERAUTH_REQUEST with "gssapi-with-mic" method */
1465                 ppl_logevent("Trying gssapi-with-mic...");
1466                 s->pktout = ssh_bpp_new_pktout(
1467                     s->ppl.bpp, SSH2_MSG_USERAUTH_REQUEST);
1468                 put_stringz(s->pktout, s->username);
1469                 put_stringz(s->pktout, s->successor_layer->vt->name);
1470                 put_stringz(s->pktout, "gssapi-with-mic");
1471                 ppl_logevent("Attempting GSSAPI authentication");
1472 
1473                 /* add mechanism info */
1474                 s->shgss->lib->indicate_mech(s->shgss->lib, &s->gss_buf);
1475 
1476                 /* number of GSSAPI mechanisms */
1477                 put_uint32(s->pktout, 1);
1478 
1479                 /* length of OID + 2 */
1480                 put_uint32(s->pktout, s->gss_buf.length + 2);
1481                 put_byte(s->pktout, SSH2_GSS_OIDTYPE);
1482 
1483                 /* length of OID */
1484                 put_byte(s->pktout, s->gss_buf.length);
1485 
1486                 put_data(s->pktout, s->gss_buf.value, s->gss_buf.length);
1487                 pq_push(s->ppl.out_pq, s->pktout);
1488                 crMaybeWaitUntilV((pktin = ssh2_userauth_pop(s)) != NULL);
1489                 if (pktin->type != SSH2_MSG_USERAUTH_GSSAPI_RESPONSE) {
1490                     ppl_logevent("GSSAPI authentication request refused");
1491                     pq_push_front(s->ppl.in_pq, pktin);
1492                     continue;
1493                 }
1494 
1495                 /* check returned packet ... */
1496 
1497                 data = get_string(pktin);
1498                 s->gss_rcvtok.value = (char *)data.ptr;
1499                 s->gss_rcvtok.length = data.len;
1500                 if (s->gss_rcvtok.length != s->gss_buf.length + 2 ||
1501                     ((char *)s->gss_rcvtok.value)[0] != SSH2_GSS_OIDTYPE ||
1502                     ((char *)s->gss_rcvtok.value)[1] != s->gss_buf.length ||
1503                     memcmp((char *)s->gss_rcvtok.value + 2,
1504                            s->gss_buf.value,s->gss_buf.length) ) {
1505                     ppl_logevent("GSSAPI authentication - wrong response "
1506                                  "from server");
1507                     continue;
1508                 }
1509 
1510                 /* Import server name if not cached from KEX */
1511                 if (s->shgss->srv_name == GSS_C_NO_NAME) {
1512                     s->gss_stat = s->shgss->lib->import_name(
1513                         s->shgss->lib, s->fullhostname, &s->shgss->srv_name);
1514                     if (s->gss_stat != SSH_GSS_OK) {
1515                         if (s->gss_stat == SSH_GSS_BAD_HOST_NAME)
1516                             ppl_logevent("GSSAPI import name failed -"
1517                                          " Bad service name");
1518                         else
1519                             ppl_logevent("GSSAPI import name failed");
1520                         continue;
1521                     }
1522                 }
1523 
1524                 /* Allocate our gss_ctx */
1525                 s->gss_stat = s->shgss->lib->acquire_cred(
1526                     s->shgss->lib, &s->shgss->ctx, NULL);
1527                 if (s->gss_stat != SSH_GSS_OK) {
1528                     ppl_logevent("GSSAPI authentication failed to get "
1529                                  "credentials");
1530                     /* The failure was on our side, so the server
1531                      * won't be sending a response packet indicating
1532                      * failure. Avoid waiting for it next time round
1533                      * the loop. */
1534                     s->suppress_wait_for_response_packet = true;
1535                     continue;
1536                 }
1537 
1538                 /* initial tokens are empty */
1539                 SSH_GSS_CLEAR_BUF(&s->gss_rcvtok);
1540                 SSH_GSS_CLEAR_BUF(&s->gss_sndtok);
1541 
1542                 /* now enter the loop */
1543                 do {
1544                     /*
1545                      * When acquire_cred yields no useful expiration, go with
1546                      * the service ticket expiration.
1547                      */
1548                     s->gss_stat = s->shgss->lib->init_sec_context
1549                         (s->shgss->lib,
1550                          &s->shgss->ctx,
1551                          s->shgss->srv_name,
1552                          s->gssapi_fwd,
1553                          &s->gss_rcvtok,
1554                          &s->gss_sndtok,
1555                          NULL,
1556                          NULL);
1557 
1558                     if (s->gss_stat!=SSH_GSS_S_COMPLETE &&
1559                         s->gss_stat!=SSH_GSS_S_CONTINUE_NEEDED) {
1560                         ppl_logevent("GSSAPI authentication initialisation "
1561                                      "failed");
1562 
1563                         if (s->shgss->lib->display_status(s->shgss->lib,
1564                                 s->shgss->ctx, &s->gss_buf) == SSH_GSS_OK) {
1565                             ppl_logevent("%s", (char *)s->gss_buf.value);
1566                             sfree(s->gss_buf.value);
1567                         }
1568 
1569                         pq_push_front(s->ppl.in_pq, pktin);
1570                         break;
1571                     }
1572                     ppl_logevent("GSSAPI authentication initialised");
1573 
1574                     /*
1575                      * Client and server now exchange tokens until GSSAPI
1576                      * no longer says CONTINUE_NEEDED
1577                      */
1578                     if (s->gss_sndtok.length != 0) {
1579                         s->is_trivial_auth = false;
1580                         s->pktout =
1581                             ssh_bpp_new_pktout(
1582                                 s->ppl.bpp, SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
1583                         put_string(s->pktout,
1584                                    s->gss_sndtok.value, s->gss_sndtok.length);
1585                         pq_push(s->ppl.out_pq, s->pktout);
1586                         s->shgss->lib->free_tok(s->shgss->lib, &s->gss_sndtok);
1587                     }
1588 
1589                     if (s->gss_stat == SSH_GSS_S_CONTINUE_NEEDED) {
1590                         crMaybeWaitUntilV((pktin = ssh2_userauth_pop(s)) != NULL);
1591 
1592                         if (pktin->type == SSH2_MSG_USERAUTH_GSSAPI_ERRTOK) {
1593                             /*
1594                              * Per RFC 4462 section 3.9, this packet
1595                              * type MUST immediately precede an
1596                              * ordinary USERAUTH_FAILURE.
1597                              *
1598                              * We currently don't know how to do
1599                              * anything with the GSSAPI error token
1600                              * contained in this packet, so we ignore
1601                              * it and just wait for the following
1602                              * FAILURE.
1603                              */
1604                             crMaybeWaitUntilV(
1605                                 (pktin = ssh2_userauth_pop(s)) != NULL);
1606                             if (pktin->type != SSH2_MSG_USERAUTH_FAILURE) {
1607                                 ssh_proto_error(
1608                                     s->ppl.ssh, "Received unexpected packet "
1609                                     "after SSH_MSG_USERAUTH_GSSAPI_ERRTOK "
1610                                     "(expected SSH_MSG_USERAUTH_FAILURE): "
1611                                     "type %d (%s)", pktin->type,
1612                                     ssh2_pkt_type(s->ppl.bpp->pls->kctx,
1613                                                   s->ppl.bpp->pls->actx,
1614                                                   pktin->type));
1615                                 return;
1616                             }
1617                         }
1618 
1619                         if (pktin->type == SSH2_MSG_USERAUTH_FAILURE) {
1620                             ppl_logevent("GSSAPI authentication failed");
1621                             s->gss_stat = SSH_GSS_FAILURE;
1622                             pq_push_front(s->ppl.in_pq, pktin);
1623                             break;
1624                         } else if (pktin->type !=
1625                                    SSH2_MSG_USERAUTH_GSSAPI_TOKEN) {
1626                             ppl_logevent("GSSAPI authentication -"
1627                                          " bad server response");
1628                             s->gss_stat = SSH_GSS_FAILURE;
1629                             break;
1630                         }
1631                         data = get_string(pktin);
1632                         s->gss_rcvtok.value = (char *)data.ptr;
1633                         s->gss_rcvtok.length = data.len;
1634                     }
1635                 } while (s-> gss_stat == SSH_GSS_S_CONTINUE_NEEDED);
1636 
1637                 if (s->gss_stat != SSH_GSS_OK) {
1638                     s->shgss->lib->release_cred(s->shgss->lib, &s->shgss->ctx);
1639                     continue;
1640                 }
1641                 ppl_logevent("GSSAPI authentication loop finished OK");
1642 
1643                 /* Now send the MIC */
1644 
1645                 s->pktout = ssh2_userauth_gss_packet(s, "gssapi-with-mic");
1646                 pq_push(s->ppl.out_pq, s->pktout);
1647 
1648                 s->shgss->lib->release_cred(s->shgss->lib, &s->shgss->ctx);
1649                 continue;
1650 #endif
1651             } else if (s->can_keyb_inter && !s->kbd_inter_refused) {
1652 
1653                 /*
1654                  * Keyboard-interactive authentication.
1655                  */
1656 
1657                 s->type = AUTH_TYPE_KEYBOARD_INTERACTIVE;
1658 
1659                 s->ppl.bpp->pls->actx = SSH2_PKTCTX_KBDINTER;
1660 
1661                 s->pktout = ssh_bpp_new_pktout(
1662                     s->ppl.bpp, SSH2_MSG_USERAUTH_REQUEST);
1663                 put_stringz(s->pktout, s->username);
1664                 put_stringz(s->pktout, s->successor_layer->vt->name);
1665                 put_stringz(s->pktout, "keyboard-interactive");
1666                                                         /* method */
1667                 put_stringz(s->pktout, "");     /* lang */
1668                 put_stringz(s->pktout, "");     /* submethods */
1669                 pq_push(s->ppl.out_pq, s->pktout);
1670 
1671                 ppl_logevent("Attempting keyboard-interactive authentication");
1672 
1673                 if (!s->ki_scc_initialised) {
1674                     s->ki_scc = seat_stripctrl_new(
1675                         s->ppl.seat, NULL, SIC_KI_PROMPTS);
1676                     /* FZ GUI does it
1677                     if (s->ki_scc)
1678                         stripctrl_enable_line_limiting(s->ki_scc);
1679                     */
1680                     s->ki_scc_initialised = true;
1681                 }
1682 
1683                 crMaybeWaitUntilV((pktin = ssh2_userauth_pop(s)) != NULL);
1684                 if (pktin->type != SSH2_MSG_USERAUTH_INFO_REQUEST) {
1685                     /* Server is not willing to do keyboard-interactive
1686                      * at all (or, bizarrely but legally, accepts the
1687                      * user without actually issuing any prompts).
1688                      * Give up on it entirely. */
1689                     pq_push_front(s->ppl.in_pq, pktin);
1690                     s->type = AUTH_TYPE_KEYBOARD_INTERACTIVE_QUIET;
1691                     s->kbd_inter_refused = true; /* don't try it again */
1692                     continue;
1693                 }
1694 
1695                 s->ki_printed_header = false;
1696 
1697                 /*
1698                  * Loop while the server continues to send INFO_REQUESTs.
1699                  */
1700                 while (pktin->type == SSH2_MSG_USERAUTH_INFO_REQUEST) {
1701                     ptrlen name, inst;
1702                     strbuf *sb;
1703 
1704                     /*
1705                      * We've got a fresh USERAUTH_INFO_REQUEST.
1706                      * Get the preamble and start building a prompt.
1707                      */
1708                     name = get_string(pktin);
1709                     inst = get_string(pktin);
1710                     get_string(pktin); /* skip language tag */
1711                     s->cur_prompt = new_prompts();
1712                     s->cur_prompt->to_server = true;
1713                     s->cur_prompt->from_server = true;
1714 
1715                     /*
1716                      * Get any prompt(s) from the packet.
1717                      */
1718                     s->num_prompts = get_uint32(pktin);
1719                     for (uint32_t i = 0; i < s->num_prompts; i++) {
1720                         s->is_trivial_auth = false;
1721                         ptrlen prompt = get_string(pktin);
1722                         bool echo = get_bool(pktin);
1723 
1724                         if (get_err(pktin)) {
1725                             ssh_proto_error(
1726                                 s->ppl.ssh, "Server sent truncated "
1727                                 "SSH_MSG_USERAUTH_INFO_REQUEST packet");
1728                             return;
1729                         }
1730 
1731                         sb = strbuf_new();
1732                         if (!prompt.len) {
1733                             put_datapl(sb, PTRLEN_LITERAL(
1734                                 "<server failed to send prompt>: "));
1735                         } else if (s->ki_scc) {
1736                             stripctrl_retarget(
1737                                 s->ki_scc, BinarySink_UPCAST(sb));
1738                             put_datapl(s->ki_scc, prompt);
1739                             stripctrl_retarget(s->ki_scc, NULL);
1740                         } else {
1741                             put_datapl(sb, prompt);
1742                         }
1743                         add_prompt(s->cur_prompt, strbuf_to_str(sb), echo);
1744                     }
1745 
1746                     /*
1747                      * Make the header strings. This includes the
1748                      * 'name' (optional dialog-box title) and
1749                      * 'instruction' from the server.
1750                      *
1751                      * First, display our disambiguating header line
1752                      * if this is the first time round the loop -
1753                      * _unless_ the server has sent a completely empty
1754                      * k-i packet with no prompts _or_ text, which
1755                      * apparently some do. In that situation there's
1756                      * no need to alert the user that the following
1757                      * text is server- supplied, because, well, _what_
1758                      * text?
1759                      *
1760                      * We also only do this if we got a stripctrl,
1761                      * because if we didn't, that suggests this is all
1762                      * being done via dialog boxes anyway.
1763                      */
1764                     if (!s->ki_printed_header && s->ki_scc &&
1765                         (s->num_prompts || name.len || inst.len)) {
1766                         ssh2_userauth_antispoof_msg(
1767                             s, "Keyboard-interactive authentication "
1768                             "prompts from server:");
1769                         s->ki_printed_header = true;
1770                         seat_set_trust_status(s->ppl.seat, false);
1771                     }
1772 
1773                     sb = strbuf_new();
1774                     if (name.len) {
1775                         if (s->ki_scc) {
1776                             stripctrl_retarget(s->ki_scc,
1777                                                BinarySink_UPCAST(sb));
1778                             put_datapl(s->ki_scc, name);
1779                             stripctrl_retarget(s->ki_scc, NULL);
1780                         } else {
1781                             put_datapl(sb, name);
1782                         }
1783                         s->cur_prompt->name_reqd = true;
1784                     } else {
1785                         put_datapl(sb, PTRLEN_LITERAL(
1786                             "SSH server authentication"));
1787                         s->cur_prompt->name_reqd = false;
1788                     }
1789                     s->cur_prompt->name = strbuf_to_str(sb);
1790 
1791                     sb = strbuf_new();
1792                     if (inst.len) {
1793                         if (s->ki_scc) {
1794                             stripctrl_retarget(s->ki_scc,
1795                                                BinarySink_UPCAST(sb));
1796                             put_datapl(s->ki_scc, inst);
1797                             stripctrl_retarget(s->ki_scc, NULL);
1798                         } else {
1799                             put_datapl(sb, inst);
1800                         }
1801                         s->cur_prompt->instr_reqd = true;
1802                     } else {
1803                         s->cur_prompt->instr_reqd = false;
1804                     }
1805                     if (sb->len)
1806                         s->cur_prompt->instruction = strbuf_to_str(sb);
1807                     else
1808                         strbuf_free(sb);
1809 
1810                     /*
1811                      * Our prompts_t is fully constructed now. Get the
1812                      * user's response(s).
1813                      */
1814                     s->userpass_ret = seat_get_userpass_input(
1815                         s->ppl.seat, s->cur_prompt, NULL);
1816                     while (1) {
1817                         while (s->userpass_ret < 0 &&
1818                                bufchain_size(s->ppl.user_input) > 0)
1819                             s->userpass_ret = seat_get_userpass_input(
1820                                 s->ppl.seat, s->cur_prompt, s->ppl.user_input);
1821 
1822                         if (s->userpass_ret >= 0)
1823                             break;
1824 
1825                         s->want_user_input = true;
1826                         crReturnV;
1827                         s->want_user_input = false;
1828                     }
1829                     if (!s->userpass_ret) {
1830                         /*
1831                          * Failed to get responses. Terminate.
1832                          */
1833                         free_prompts(s->cur_prompt);
1834                         ssh_bpp_queue_disconnect(
1835                             s->ppl.bpp, "Unable to authenticate",
1836                             SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER);
1837                         ssh_user_close(s->ppl.ssh, "User aborted during "
1838                                        "keyboard-interactive authentication");
1839                         return;
1840                     }
1841 
1842                     /*
1843                      * Send the response(s) to the server.
1844                      */
1845                     s->pktout = ssh_bpp_new_pktout(
1846                         s->ppl.bpp, SSH2_MSG_USERAUTH_INFO_RESPONSE);
1847                     put_uint32(s->pktout, s->num_prompts);
1848                     for (uint32_t i = 0; i < s->num_prompts; i++) {
1849                         put_stringz(s->pktout, prompt_get_result_ref(
1850                                         s->cur_prompt->prompts[i]));
1851                     }
1852                     s->pktout->minlen = 256;
1853                     pq_push(s->ppl.out_pq, s->pktout);
1854 
1855                     /*
1856                      * Free the prompts structure from this iteration.
1857                      * If there's another, a new one will be allocated
1858                      * when we return to the top of this while loop.
1859                      */
1860                     free_prompts(s->cur_prompt);
1861 
1862                     /*
1863                      * Get the next packet in case it's another
1864                      * INFO_REQUEST.
1865                      */
1866                     crMaybeWaitUntilV((pktin = ssh2_userauth_pop(s)) != NULL);
1867 
1868                 }
1869 
1870                 /*
1871                  * Print our trailer line, if we printed a header.
1872                  */
1873                 if (s->ki_printed_header) {
1874                     seat_set_trust_status(s->ppl.seat, true);
1875                     ssh2_userauth_antispoof_msg(
1876                         s, "End of keyboard-interactive prompts from server");
1877                 }
1878 
1879                 /*
1880                  * We should have SUCCESS or FAILURE now.
1881                  */
1882                 pq_push_front(s->ppl.in_pq, pktin);
1883 
1884             } else if (s->can_passwd) {
1885                 s->is_trivial_auth = false;
1886                 /*
1887                  * Plain old password authentication.
1888                  */
1889                 bool changereq_first_time; /* not live over crReturn */
1890 
1891                 s->ppl.bpp->pls->actx = SSH2_PKTCTX_PASSWORD;
1892 
1893                 s->cur_prompt = new_prompts();
1894                 s->cur_prompt->to_server = true;
1895                 s->cur_prompt->from_server = false;
1896                 s->cur_prompt->name = dupstr("SSH password");
1897                 /* FZ: We construct our own prompt in the GUI */
1898                 add_prompt(s->cur_prompt, dupprintf("Password: "),
1899                            false);
1900 
1901                 s->userpass_ret = seat_get_userpass_input(
1902                     s->ppl.seat, s->cur_prompt, NULL);
1903                 while (1) {
1904                     while (s->userpass_ret < 0 &&
1905                            bufchain_size(s->ppl.user_input) > 0)
1906                         s->userpass_ret = seat_get_userpass_input(
1907                             s->ppl.seat, s->cur_prompt, s->ppl.user_input);
1908 
1909                     if (s->userpass_ret >= 0)
1910                         break;
1911 
1912                     s->want_user_input = true;
1913                     crReturnV;
1914                     s->want_user_input = false;
1915                 }
1916                 if (!s->userpass_ret) {
1917                     /*
1918                      * Failed to get responses. Terminate.
1919                      */
1920                     free_prompts(s->cur_prompt);
1921                     ssh_bpp_queue_disconnect(
1922                         s->ppl.bpp, "Unable to authenticate",
1923                         SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER);
1924                     ssh_user_close(s->ppl.ssh, "User aborted during password "
1925                                    "authentication");
1926                     return;
1927                 }
1928                 /*
1929                  * Squirrel away the password. (We may need it later if
1930                  * asked to change it.)
1931                  */
1932                 s->password = prompt_get_result(s->cur_prompt->prompts[0]);
1933                 free_prompts(s->cur_prompt);
1934 
1935                 /*
1936                  * Send the password packet.
1937                  *
1938                  * We pad out the password packet to 256 bytes to make
1939                  * it harder for an attacker to find the length of the
1940                  * user's password.
1941                  *
1942                  * Anyone using a password longer than 256 bytes
1943                  * probably doesn't have much to worry about from
1944                  * people who find out how long their password is!
1945                  */
1946                 s->pktout = ssh_bpp_new_pktout(
1947                     s->ppl.bpp, SSH2_MSG_USERAUTH_REQUEST);
1948                 put_stringz(s->pktout, s->username);
1949                 put_stringz(s->pktout, s->successor_layer->vt->name);
1950                 put_stringz(s->pktout, "password");
1951                 put_bool(s->pktout, false);
1952                 put_stringz(s->pktout, s->password);
1953                 s->pktout->minlen = 256;
1954                 pq_push(s->ppl.out_pq, s->pktout);
1955                 ppl_logevent("Sent password");
1956                 s->type = AUTH_TYPE_PASSWORD;
1957 
1958                 /*
1959                  * Wait for next packet, in case it's a password change
1960                  * request.
1961                  */
1962                 crMaybeWaitUntilV((pktin = ssh2_userauth_pop(s)) != NULL);
1963                 changereq_first_time = true;
1964 
1965                 while (pktin->type == SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ) {
1966 
1967                     /*
1968                      * We're being asked for a new password
1969                      * (perhaps not for the first time).
1970                      * Loop until the server accepts it.
1971                      */
1972 
1973                     bool got_new = false; /* not live over crReturn */
1974                     ptrlen prompt;  /* not live over crReturn */
1975 
1976                     {
1977                         const char *msg;
1978                         if (changereq_first_time)
1979                             msg = "Server requested password change";
1980                         else
1981                             msg = "Server rejected new password";
1982                         ppl_logevent("%s", msg);
1983                         ppl_printf("%s\r\n", msg);
1984                     }
1985 
1986                     prompt = get_string(pktin);
1987 
1988                     s->cur_prompt = new_prompts();
1989                     s->cur_prompt->to_server = true;
1990                     s->cur_prompt->from_server = false;
1991                     s->cur_prompt->name = dupstr("New SSH password");
1992                     s->cur_prompt->instruction = mkstr(prompt);
1993                     s->cur_prompt->instr_reqd = true;
1994                     /*
1995                      * There's no explicit requirement in the protocol
1996                      * for the "old" passwords in the original and
1997                      * password-change messages to be the same, and
1998                      * apparently some Cisco kit supports password change
1999                      * by the user entering a blank password originally
2000                      * and the real password subsequently, so,
2001                      * reluctantly, we prompt for the old password again.
2002                      *
2003                      * (On the other hand, some servers don't even bother
2004                      * to check this field.)
2005                      */
2006                     add_prompt(s->cur_prompt,
2007                                dupstr("Current password (blank for previously entered password): "),
2008                                false);
2009                     add_prompt(s->cur_prompt, dupstr("Enter new password: "),
2010                                false);
2011                     add_prompt(s->cur_prompt, dupstr("Confirm new password: "),
2012                                false);
2013 
2014                     /*
2015                      * Loop until the user manages to enter the same
2016                      * password twice.
2017                      */
2018                     while (!got_new) {
2019                         s->userpass_ret = seat_get_userpass_input(
2020                             s->ppl.seat, s->cur_prompt, NULL);
2021                         while (1) {
2022                             while (s->userpass_ret < 0 &&
2023                                    bufchain_size(s->ppl.user_input) > 0)
2024                                 s->userpass_ret = seat_get_userpass_input(
2025                                     s->ppl.seat, s->cur_prompt,
2026                                     s->ppl.user_input);
2027 
2028                             if (s->userpass_ret >= 0)
2029                                 break;
2030 
2031                             s->want_user_input = true;
2032                             crReturnV;
2033                             s->want_user_input = false;
2034                         }
2035                         if (!s->userpass_ret) {
2036                             /*
2037                              * Failed to get responses. Terminate.
2038                              */
2039                             /* burn the evidence */
2040                             free_prompts(s->cur_prompt);
2041                             smemclr(s->password, strlen(s->password));
2042                             sfree(s->password);
2043                             ssh_bpp_queue_disconnect(
2044                                 s->ppl.bpp, "Unable to authenticate",
2045                                 SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER);
2046                             ssh_user_close(s->ppl.ssh, "User aborted during "
2047                                            "password changing");
2048                             return;
2049                         }
2050 
2051                         /*
2052                          * If the user specified a new original password
2053                          * (IYSWIM), overwrite any previously specified
2054                          * one.
2055                          * (A side effect is that the user doesn't have to
2056                          * re-enter it if they louse up the new password.)
2057                          */
2058                         if (s->cur_prompt->prompts[0]->result->s[0]) {
2059                             smemclr(s->password, strlen(s->password));
2060                                 /* burn the evidence */
2061                             sfree(s->password);
2062                             s->password = prompt_get_result(
2063                                 s->cur_prompt->prompts[0]);
2064                         }
2065 
2066                         /*
2067                          * Check the two new passwords match.
2068                          */
2069                         got_new = !strcmp(
2070                             prompt_get_result_ref(s->cur_prompt->prompts[1]),
2071                             prompt_get_result_ref(s->cur_prompt->prompts[2]));
2072                         if (!got_new)
2073                             /* They don't. Silly user. */
2074                             ppl_printf("Passwords do not match\r\n");
2075 
2076                     }
2077 
2078                     /*
2079                      * Send the new password (along with the old one).
2080                      * (see above for padding rationale)
2081                      */
2082                     s->pktout = ssh_bpp_new_pktout(
2083                         s->ppl.bpp, SSH2_MSG_USERAUTH_REQUEST);
2084                     put_stringz(s->pktout, s->username);
2085                     put_stringz(s->pktout, s->successor_layer->vt->name);
2086                     put_stringz(s->pktout, "password");
2087                     put_bool(s->pktout, true);
2088                     put_stringz(s->pktout, s->password);
2089                     put_stringz(s->pktout, prompt_get_result_ref(
2090                                     s->cur_prompt->prompts[1]));
2091                     free_prompts(s->cur_prompt);
2092                     s->pktout->minlen = 256;
2093                     pq_push(s->ppl.out_pq, s->pktout);
2094                     ppl_logevent("Sent new password");
2095 
2096                     /*
2097                      * Now see what the server has to say about it.
2098                      * (If it's CHANGEREQ again, it's not happy with the
2099                      * new password.)
2100                      */
2101                     crMaybeWaitUntilV((pktin = ssh2_userauth_pop(s)) != NULL);
2102                     changereq_first_time = false;
2103 
2104                 }
2105 
2106                 /*
2107                  * We need to reexamine the current pktin at the top
2108                  * of the loop. Either:
2109                  *  - we weren't asked to change password at all, in
2110                  *    which case it's a SUCCESS or FAILURE with the
2111                  *    usual meaning
2112                  *  - we sent a new password, and the server was
2113                  *    either OK with it (SUCCESS or FAILURE w/partial
2114                  *    success) or unhappy with the _old_ password
2115                  *    (FAILURE w/o partial success)
2116                  * In any of these cases, we go back to the top of
2117                  * the loop and start again.
2118                  */
2119                 pq_push_front(s->ppl.in_pq, pktin);
2120 
2121                 /*
2122                  * We don't need the old password any more, in any
2123                  * case. Burn the evidence.
2124                  */
2125                 smemclr(s->password, strlen(s->password));
2126                 sfree(s->password);
2127 
2128             } else {
2129                 ssh_bpp_queue_disconnect(
2130                     s->ppl.bpp,
2131                     "No supported authentication methods available",
2132                     SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE);
2133                 ssh_sw_abort(s->ppl.ssh, "No supported authentication methods "
2134                              "available (server sent: %s)",
2135                              s->last_methods_string->s);
2136                 return;
2137             }
2138 
2139         }
2140       try_new_username:;
2141     }
2142 
2143   userauth_success:
2144     if (s->notrivialauth && s->is_trivial_auth) {
2145         ssh_proto_error(s->ppl.ssh, "Authentication was trivial! "
2146                         "Abandoning session as specified in configuration.");
2147         return;
2148     }
2149 
2150     /*
2151      * We've just received USERAUTH_SUCCESS, and we haven't sent
2152      * any packets since. Signal the transport layer to consider
2153      * doing an immediate rekey, if it has any reason to want to.
2154      */
2155     ssh2_transport_notify_auth_done(s->transport_layer);
2156 
2157     /*
2158      * Finally, hand over to our successor layer, and return
2159      * immediately without reaching the crFinishV: ssh_ppl_replace
2160      * will have freed us, so crFinishV's zeroing-out of crState would
2161      * be a use-after-free bug.
2162      */
2163     {
2164         PacketProtocolLayer *successor = s->successor_layer;
2165         s->successor_layer = NULL;     /* avoid freeing it ourself */
2166         ssh_ppl_replace(&s->ppl, successor);
2167         return;   /* we've just freed s, so avoid even touching s->crState */
2168     }
2169 
2170     crFinishV;
2171 }
2172 
ssh2_userauth_add_session_id(struct ssh2_userauth_state * s,strbuf * sigdata)2173 static void ssh2_userauth_add_session_id(
2174     struct ssh2_userauth_state *s, strbuf *sigdata)
2175 {
2176     if (s->ppl.remote_bugs & BUG_SSH2_PK_SESSIONID) {
2177         put_datapl(sigdata, s->session_id);
2178     } else {
2179         put_stringpl(sigdata, s->session_id);
2180     }
2181 }
2182 
ssh2_userauth_agent_query(struct ssh2_userauth_state * s,strbuf * req)2183 static void ssh2_userauth_agent_query(
2184     struct ssh2_userauth_state *s, strbuf *req)
2185 {
2186     void *response;
2187     int response_len;
2188 
2189     sfree(s->agent_response_to_free);
2190     s->agent_response_to_free = NULL;
2191 
2192     s->auth_agent_query = agent_query(req, &response, &response_len,
2193                                       ssh2_userauth_agent_callback, s);
2194     if (!s->auth_agent_query)
2195         ssh2_userauth_agent_callback(s, response, response_len);
2196 }
2197 
ssh2_userauth_agent_callback(void * uav,void * reply,int replylen)2198 static void ssh2_userauth_agent_callback(void *uav, void *reply, int replylen)
2199 {
2200     struct ssh2_userauth_state *s = (struct ssh2_userauth_state *)uav;
2201 
2202     s->auth_agent_query = NULL;
2203     s->agent_response_to_free = reply;
2204     s->agent_response = make_ptrlen(reply, replylen);
2205 
2206     queue_idempotent_callback(&s->ppl.ic_process_queue);
2207 }
2208 
2209 /*
2210  * Helper function to add an SSH-2 signature blob to a packet. Expects
2211  * to be shown the public key blob as well as the signature blob.
2212  * Normally just appends the sig blob unmodified as a string, except
2213  * that it optionally breaks it open and fiddle with it to work around
2214  * BUG_SSH2_RSA_PADDING.
2215  */
ssh2_userauth_add_sigblob(struct ssh2_userauth_state * s,PktOut * pkt,ptrlen pkblob,ptrlen sigblob)2216 static void ssh2_userauth_add_sigblob(
2217     struct ssh2_userauth_state *s, PktOut *pkt, ptrlen pkblob, ptrlen sigblob)
2218 {
2219     BinarySource pk[1], sig[1];
2220     BinarySource_BARE_INIT_PL(pk, pkblob);
2221     BinarySource_BARE_INIT_PL(sig, sigblob);
2222 
2223     /* dmemdump(pkblob, pkblob_len); */
2224     /* dmemdump(sigblob, sigblob_len); */
2225 
2226     /*
2227      * See if this is in fact an ssh-rsa signature and a buggy
2228      * server; otherwise we can just do this the easy way.
2229      */
2230     if ((s->ppl.remote_bugs & BUG_SSH2_RSA_PADDING) &&
2231         ptrlen_eq_string(get_string(pk), "ssh-rsa") &&
2232         ptrlen_eq_string(get_string(sig), "ssh-rsa")) {
2233         ptrlen mod_mp, sig_mp;
2234         size_t sig_prefix_len;
2235 
2236         /*
2237          * Find the modulus and signature integers.
2238          */
2239         get_string(pk);                /* skip over exponent */
2240         mod_mp = get_string(pk);       /* remember modulus */
2241         sig_prefix_len = sig->pos;
2242         sig_mp = get_string(sig);
2243         if (get_err(pk) || get_err(sig))
2244             goto give_up;
2245 
2246         /*
2247          * Find the byte length of the modulus, not counting leading
2248          * zeroes.
2249          */
2250         while (mod_mp.len > 0 && *(const char *)mod_mp.ptr == 0) {
2251             mod_mp.len--;
2252             mod_mp.ptr = (const char *)mod_mp.ptr + 1;
2253         }
2254 
2255         /* debug("modulus length is %d\n", len); */
2256         /* debug("signature length is %d\n", siglen); */
2257 
2258         if (mod_mp.len > sig_mp.len) {
2259             strbuf *substr = strbuf_new();
2260             put_data(substr, sigblob.ptr, sig_prefix_len);
2261             put_uint32(substr, mod_mp.len);
2262             put_padding(substr, mod_mp.len - sig_mp.len, 0);
2263             put_datapl(substr, sig_mp);
2264             put_stringsb(pkt, substr);
2265             return;
2266         }
2267 
2268         /* Otherwise fall through and do it the easy way. We also come
2269          * here as a fallback if we discover above that the key blob
2270          * is misformatted in some way. */
2271       give_up:;
2272     }
2273 
2274     put_stringpl(pkt, sigblob);
2275 }
2276 
2277 #ifndef NO_GSSAPI
ssh2_userauth_gss_packet(struct ssh2_userauth_state * s,const char * authtype)2278 static PktOut *ssh2_userauth_gss_packet(
2279     struct ssh2_userauth_state *s, const char *authtype)
2280 {
2281     strbuf *sb;
2282     PktOut *p;
2283     Ssh_gss_buf buf;
2284     Ssh_gss_buf mic;
2285 
2286     /*
2287      * The mic is computed over the session id + intended
2288      * USERAUTH_REQUEST packet.
2289      */
2290     sb = strbuf_new();
2291     put_stringpl(sb, s->session_id);
2292     put_byte(sb, SSH2_MSG_USERAUTH_REQUEST);
2293     put_stringz(sb, s->username);
2294     put_stringz(sb, s->successor_layer->vt->name);
2295     put_stringz(sb, authtype);
2296 
2297     /* Compute the mic */
2298     buf.value = sb->s;
2299     buf.length = sb->len;
2300     s->shgss->lib->get_mic(s->shgss->lib, s->shgss->ctx, &buf, &mic);
2301     strbuf_free(sb);
2302 
2303     /* Now we can build the real packet */
2304     if (strcmp(authtype, "gssapi-with-mic") == 0) {
2305         p = ssh_bpp_new_pktout(s->ppl.bpp, SSH2_MSG_USERAUTH_GSSAPI_MIC);
2306     } else {
2307         p = ssh_bpp_new_pktout(s->ppl.bpp, SSH2_MSG_USERAUTH_REQUEST);
2308         put_stringz(p, s->username);
2309         put_stringz(p, s->successor_layer->vt->name);
2310         put_stringz(p, authtype);
2311     }
2312     put_string(p, mic.value, mic.length);
2313 
2314     return p;
2315 }
2316 #endif
2317 
ssh2_userauth_get_specials(PacketProtocolLayer * ppl,add_special_fn_t add_special,void * ctx)2318 static bool ssh2_userauth_get_specials(
2319     PacketProtocolLayer *ppl, add_special_fn_t add_special, void *ctx)
2320 {
2321     /* No specials provided by this layer. */
2322     return false;
2323 }
2324 
ssh2_userauth_special_cmd(PacketProtocolLayer * ppl,SessionSpecialCode code,int arg)2325 static void ssh2_userauth_special_cmd(PacketProtocolLayer *ppl,
2326                                       SessionSpecialCode code, int arg)
2327 {
2328     /* No specials provided by this layer. */
2329 }
2330 
ssh2_userauth_want_user_input(PacketProtocolLayer * ppl)2331 static bool ssh2_userauth_want_user_input(PacketProtocolLayer *ppl)
2332 {
2333     struct ssh2_userauth_state *s =
2334         container_of(ppl, struct ssh2_userauth_state, ppl);
2335     return s->want_user_input;
2336 }
2337 
ssh2_userauth_got_user_input(PacketProtocolLayer * ppl)2338 static void ssh2_userauth_got_user_input(PacketProtocolLayer *ppl)
2339 {
2340     struct ssh2_userauth_state *s =
2341         container_of(ppl, struct ssh2_userauth_state, ppl);
2342     if (s->want_user_input)
2343         queue_idempotent_callback(&s->ppl.ic_process_queue);
2344 }
2345 
ssh2_userauth_reconfigure(PacketProtocolLayer * ppl,Conf * conf)2346 static void ssh2_userauth_reconfigure(PacketProtocolLayer *ppl, Conf *conf)
2347 {
2348     struct ssh2_userauth_state *s =
2349         container_of(ppl, struct ssh2_userauth_state, ppl);
2350     ssh_ppl_reconfigure(s->successor_layer, conf);
2351 }
2352 
ssh2_userauth_antispoof_msg(struct ssh2_userauth_state * s,const char * msg)2353 static void ssh2_userauth_antispoof_msg(
2354     struct ssh2_userauth_state *s, const char *msg)
2355 {
2356     strbuf *sb = strbuf_new();
2357     if (seat_set_trust_status(s->ppl.seat, true)) {
2358         /*
2359          * If the seat can directly indicate that this message is
2360          * generated by the client, then we can just use the message
2361          * unmodified as an unspoofable header.
2362          */
2363         put_datapl(sb, ptrlen_from_asciz(msg));
2364     } else {
2365         /*
2366          * Otherwise, add enough padding around it that the server
2367          * wouldn't be able to mimic it within our line-length
2368          * constraint.
2369          */
2370         strbuf_catf(sb, "-- %s ", msg);
2371         while (sb->len < 78)
2372             put_byte(sb, '-');
2373     }
2374     put_datapl(sb, PTRLEN_LITERAL("\r\n"));
2375     seat_stderr_pl(s->ppl.seat, ptrlen_from_strbuf(sb));
2376     strbuf_free(sb);
2377 }
2378