Upgrade libgit2
[TortoiseGit.git] / src / TortoisePlink / ssh / login1.c
blobbd58d006afdea1c0e05ba35a818d02f45c9f9144
1 /*
2 * Packet protocol layer for the SSH-1 login phase (combining what
3 * SSH-2 would think of as key exchange and user authentication).
4 */
6 #include <assert.h>
8 #include "putty.h"
9 #include "ssh.h"
10 #include "mpint.h"
11 #include "bpp.h"
12 #include "ppl.h"
13 #include "sshcr.h"
15 typedef struct agent_key {
16 RSAKey key;
17 strbuf *comment;
18 ptrlen blob; /* only used during initial parsing of agent response */
19 } agent_key;
21 struct ssh1_login_state {
22 int crState;
24 PacketProtocolLayer *successor_layer;
26 Conf *conf;
28 char *savedhost;
29 int savedport;
30 bool try_agent_auth, is_trivial_auth;
32 int remote_protoflags;
33 int local_protoflags;
34 unsigned char session_key[32];
35 char *username;
36 agent_pending_query *auth_agent_query;
38 int len;
39 unsigned char *rsabuf;
40 unsigned long supported_ciphers_mask, supported_auths_mask;
41 bool tried_publickey, tried_agent;
42 bool tis_auth_refused, ccard_auth_refused;
43 unsigned char cookie[8];
44 unsigned char session_id[16];
45 int cipher_type;
46 strbuf *publickey_blob;
47 char *publickey_comment;
48 bool privatekey_available, privatekey_encrypted;
49 prompts_t *cur_prompt;
50 SeatPromptResult spr;
51 char c;
52 int pwpkt_type;
53 void *agent_response_to_free;
54 ptrlen agent_response;
55 BinarySource asrc[1]; /* response from SSH agent */
56 size_t agent_keys_len;
57 agent_key *agent_keys;
58 size_t agent_key_index, agent_key_limit;
59 bool authed;
60 RSAKey key;
61 Filename *keyfile;
62 RSAKey servkey, hostkey;
64 StripCtrlChars *tis_scc;
65 bool tis_scc_initialised;
67 PacketProtocolLayer ppl;
70 static void ssh1_login_free(PacketProtocolLayer *);
71 static void ssh1_login_process_queue(PacketProtocolLayer *);
72 static void ssh1_login_dialog_callback(void *, SeatPromptResult);
73 static void ssh1_login_special_cmd(PacketProtocolLayer *ppl,
74 SessionSpecialCode code, int arg);
75 static void ssh1_login_reconfigure(PacketProtocolLayer *ppl, Conf *conf);
77 static const PacketProtocolLayerVtable ssh1_login_vtable = {
78 .free = ssh1_login_free,
79 .process_queue = ssh1_login_process_queue,
80 .get_specials = ssh1_common_get_specials,
81 .special_cmd = ssh1_login_special_cmd,
82 .reconfigure = ssh1_login_reconfigure,
83 .queued_data_size = ssh_ppl_default_queued_data_size,
84 .final_output = ssh_ppl_default_final_output,
85 .name = NULL, /* no layer names in SSH-1 */
88 static void ssh1_login_agent_query(struct ssh1_login_state *s, strbuf *req);
89 static void ssh1_login_agent_callback(void *loginv, void *reply, int replylen);
91 PacketProtocolLayer *ssh1_login_new(
92 Conf *conf, const char *host, int port,
93 PacketProtocolLayer *successor_layer)
95 struct ssh1_login_state *s = snew(struct ssh1_login_state);
96 memset(s, 0, sizeof(*s));
97 s->ppl.vt = &ssh1_login_vtable;
99 s->conf = conf_copy(conf);
100 s->savedhost = dupstr(host);
101 s->savedport = port;
102 s->successor_layer = successor_layer;
103 s->is_trivial_auth = true;
105 return &s->ppl;
108 static void ssh1_login_free(PacketProtocolLayer *ppl)
110 struct ssh1_login_state *s =
111 container_of(ppl, struct ssh1_login_state, ppl);
113 if (s->successor_layer)
114 ssh_ppl_free(s->successor_layer);
116 conf_free(s->conf);
117 sfree(s->savedhost);
118 sfree(s->rsabuf);
119 sfree(s->username);
120 if (s->publickey_blob)
121 strbuf_free(s->publickey_blob);
122 sfree(s->publickey_comment);
123 if (s->cur_prompt)
124 free_prompts(s->cur_prompt);
125 if (s->agent_keys) {
126 for (size_t i = 0; i < s->agent_keys_len; i++) {
127 freersakey(&s->agent_keys[i].key);
128 strbuf_free(s->agent_keys[i].comment);
130 sfree(s->agent_keys);
132 sfree(s->agent_response_to_free);
133 if (s->auth_agent_query)
134 agent_cancel_query(s->auth_agent_query);
135 sfree(s);
138 static bool ssh1_login_filter_queue(struct ssh1_login_state *s)
140 return ssh1_common_filter_queue(&s->ppl);
143 static PktIn *ssh1_login_pop(struct ssh1_login_state *s)
145 if (ssh1_login_filter_queue(s))
146 return NULL;
147 return pq_pop(s->ppl.in_pq);
150 static void ssh1_login_setup_tis_scc(struct ssh1_login_state *s);
152 static void ssh1_login_process_queue(PacketProtocolLayer *ppl)
154 struct ssh1_login_state *s =
155 container_of(ppl, struct ssh1_login_state, ppl);
156 PktIn *pktin;
157 PktOut *pkt;
158 int i;
160 /* Filter centrally handled messages off the front of the queue on
161 * every entry to this coroutine, no matter where we're resuming
162 * from, even if we're _not_ looping on pq_pop. That way we can
163 * still proactively handle those messages even if we're waiting
164 * for a user response. */
165 if (ssh1_login_filter_queue(s))
166 return;
168 crBegin(s->crState);
170 crMaybeWaitUntilV((pktin = ssh1_login_pop(s)) != NULL);
172 if (pktin->type != SSH1_SMSG_PUBLIC_KEY) {
173 ssh_proto_error(s->ppl.ssh, "Public key packet not received");
174 return;
177 ppl_logevent("Received public keys");
180 ptrlen pl = get_data(pktin, 8);
181 memcpy(s->cookie, pl.ptr, pl.len);
184 get_rsa_ssh1_pub(pktin, &s->servkey, RSA_SSH1_EXPONENT_FIRST);
185 get_rsa_ssh1_pub(pktin, &s->hostkey, RSA_SSH1_EXPONENT_FIRST);
187 s->hostkey.comment = NULL; /* avoid confusing rsa_ssh1_fingerprint */
190 * Log the host key fingerprint.
192 if (!get_err(pktin)) {
193 char *fingerprint = rsa_ssh1_fingerprint(&s->hostkey);
194 ppl_logevent("Host key fingerprint is:");
195 ppl_logevent(" %s", fingerprint);
196 sfree(fingerprint);
199 s->remote_protoflags = get_uint32(pktin);
200 s->supported_ciphers_mask = get_uint32(pktin);
201 s->supported_auths_mask = get_uint32(pktin);
203 if (get_err(pktin)) {
204 ssh_proto_error(s->ppl.ssh, "Bad SSH-1 public key packet");
205 return;
208 if ((s->ppl.remote_bugs & BUG_CHOKES_ON_RSA))
209 s->supported_auths_mask &= ~(1 << SSH1_AUTH_RSA);
211 s->local_protoflags =
212 s->remote_protoflags & SSH1_PROTOFLAGS_SUPPORTED;
213 s->local_protoflags |= SSH1_PROTOFLAG_SCREEN_NUMBER;
215 ssh1_compute_session_id(s->session_id, s->cookie,
216 &s->hostkey, &s->servkey);
218 random_read(s->session_key, 32);
221 * Verify that the `bits' and `bytes' parameters match.
223 if (s->hostkey.bits > s->hostkey.bytes * 8 ||
224 s->servkey.bits > s->servkey.bytes * 8) {
225 ssh_proto_error(s->ppl.ssh, "SSH-1 public keys were badly formatted");
226 return;
229 s->len = 32;
230 if (s->len < s->hostkey.bytes)
231 s->len = s->hostkey.bytes;
232 if (s->len < s->servkey.bytes)
233 s->len = s->servkey.bytes;
235 s->rsabuf = snewn(s->len, unsigned char);
238 * Verify the host key.
241 char *keystr = rsastr_fmt(&s->hostkey);
242 char *keydisp = ssh1_pubkey_str(&s->hostkey);
243 char **fingerprints = rsa_ssh1_fake_all_fingerprints(&s->hostkey);
245 s->spr = verify_ssh_host_key(
246 ppl_get_iseat(&s->ppl), s->conf, s->savedhost, s->savedport, NULL,
247 "rsa", keystr, keydisp, fingerprints, 0,
248 ssh1_login_dialog_callback, s);
250 ssh2_free_all_fingerprints(fingerprints);
251 sfree(keydisp);
252 sfree(keystr);
255 #ifdef FUZZING
256 s->spr = SPR_OK;
257 #endif
258 crMaybeWaitUntilV(s->spr.kind != SPRK_INCOMPLETE);
260 if (spr_is_abort(s->spr)) {
261 ssh_spr_close(s->ppl.ssh, s->spr, "host key verification");
262 return;
265 for (i = 0; i < 32; i++) {
266 s->rsabuf[i] = s->session_key[i];
267 if (i < 16)
268 s->rsabuf[i] ^= s->session_id[i];
272 RSAKey *smaller = (s->hostkey.bytes > s->servkey.bytes ?
273 &s->servkey : &s->hostkey);
274 RSAKey *larger = (s->hostkey.bytes > s->servkey.bytes ?
275 &s->hostkey : &s->servkey);
277 if (!rsa_ssh1_encrypt(s->rsabuf, 32, smaller) ||
278 !rsa_ssh1_encrypt(s->rsabuf, smaller->bytes, larger)) {
279 ssh_proto_error(s->ppl.ssh, "SSH-1 public key encryptions failed "
280 "due to bad formatting");
281 return;
285 ppl_logevent("Encrypted session key");
288 bool cipher_chosen = false, warn = false;
289 const char *cipher_string = NULL;
290 int i;
291 for (i = 0; !cipher_chosen && i < CIPHER_MAX; i++) {
292 int next_cipher = conf_get_int_int(
293 s->conf, CONF_ssh_cipherlist, i);
294 if (next_cipher == CIPHER_WARN) {
295 /* If/when we choose a cipher, warn about it */
296 warn = true;
297 } else if (next_cipher == CIPHER_AES) {
298 /* XXX Probably don't need to mention this. */
299 ppl_logevent("AES not supported in SSH-1, skipping");
300 } else {
301 switch (next_cipher) {
302 case CIPHER_3DES: s->cipher_type = SSH1_CIPHER_3DES;
303 cipher_string = "3DES"; break;
304 case CIPHER_BLOWFISH: s->cipher_type = SSH1_CIPHER_BLOWFISH;
305 cipher_string = "Blowfish"; break;
306 case CIPHER_DES: s->cipher_type = SSH1_CIPHER_DES;
307 cipher_string = "single-DES"; break;
309 if (s->supported_ciphers_mask & (1 << s->cipher_type))
310 cipher_chosen = true;
313 if (!cipher_chosen) {
314 if ((s->supported_ciphers_mask & (1 << SSH1_CIPHER_3DES)) == 0) {
315 ssh_proto_error(s->ppl.ssh, "Server violates SSH-1 protocol "
316 "by not supporting 3DES encryption");
317 } else {
318 /* shouldn't happen */
319 ssh_sw_abort(s->ppl.ssh, "No supported ciphers found");
321 return;
324 /* Warn about chosen cipher if necessary. */
325 if (warn) {
326 s->spr = confirm_weak_crypto_primitive(
327 ppl_get_iseat(&s->ppl), "cipher", cipher_string,
328 ssh1_login_dialog_callback, s, WCR_BELOW_THRESHOLD);
329 crMaybeWaitUntilV(s->spr.kind != SPRK_INCOMPLETE);
330 if (spr_is_abort(s->spr)) {
331 ssh_spr_close(s->ppl.ssh, s->spr, "cipher warning");
332 return;
337 switch (s->cipher_type) {
338 case SSH1_CIPHER_3DES:
339 ppl_logevent("Using 3DES encryption");
340 break;
341 case SSH1_CIPHER_DES:
342 ppl_logevent("Using single-DES encryption");
343 break;
344 case SSH1_CIPHER_BLOWFISH:
345 ppl_logevent("Using Blowfish encryption");
346 break;
349 pkt = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_CMSG_SESSION_KEY);
350 put_byte(pkt, s->cipher_type);
351 put_data(pkt, s->cookie, 8);
352 put_uint16(pkt, s->len * 8);
353 put_data(pkt, s->rsabuf, s->len);
354 put_uint32(pkt, s->local_protoflags);
355 pq_push(s->ppl.out_pq, pkt);
357 ppl_logevent("Trying to enable encryption...");
359 sfree(s->rsabuf);
360 s->rsabuf = NULL;
363 * Force the BPP to synchronously marshal all packets up to and
364 * including the SESSION_KEY into wire format, before we turn on
365 * crypto.
367 ssh_bpp_handle_output(s->ppl.bpp);
370 const ssh_cipheralg *cipher =
371 (s->cipher_type == SSH1_CIPHER_BLOWFISH ? &ssh_blowfish_ssh1 :
372 s->cipher_type == SSH1_CIPHER_DES ? &ssh_des : &ssh_3des_ssh1);
373 ssh1_bpp_new_cipher(s->ppl.bpp, cipher, s->session_key);
376 freersakey(&s->servkey);
377 freersakey(&s->hostkey);
378 crMaybeWaitUntilV((pktin = ssh1_login_pop(s)) != NULL);
380 if (pktin->type != SSH1_SMSG_SUCCESS) {
381 ssh_proto_error(s->ppl.ssh, "Encryption not successfully enabled");
382 return;
385 ppl_logevent("Successfully started encryption");
387 if ((s->username = get_remote_username(s->conf)) == NULL) {
388 s->cur_prompt = ssh_ppl_new_prompts(&s->ppl);
389 s->cur_prompt->to_server = true;
390 s->cur_prompt->from_server = false;
391 s->cur_prompt->name = dupstr("SSH login name");
392 add_prompt(s->cur_prompt, dupstr("login as: "), true);
393 s->spr = seat_get_userpass_input(
394 ppl_get_iseat(&s->ppl), s->cur_prompt);
395 while (s->spr.kind == SPRK_INCOMPLETE) {
396 crReturnV;
397 s->spr = seat_get_userpass_input(
398 ppl_get_iseat(&s->ppl), s->cur_prompt);
400 if (spr_is_abort(s->spr)) {
402 * Failed to get a username. Terminate.
404 ssh_spr_close(s->ppl.ssh, s->spr, "username prompt");
405 return;
407 s->username = prompt_get_result(s->cur_prompt->prompts[0]);
408 free_prompts(s->cur_prompt);
409 s->cur_prompt = NULL;
412 pkt = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_CMSG_USER);
413 put_stringz(pkt, s->username);
414 pq_push(s->ppl.out_pq, pkt);
416 ppl_logevent("Sent username \"%s\"", s->username);
417 if (seat_verbose(s->ppl.seat) || seat_interactive(s->ppl.seat))
418 ppl_printf("Sent username \"%s\"\r\n", s->username);
420 crMaybeWaitUntilV((pktin = ssh1_login_pop(s)) != NULL);
422 if (!(s->supported_auths_mask & (1 << SSH1_AUTH_RSA))) {
423 /* We must not attempt PK auth. Pretend we've already tried it. */
424 s->tried_publickey = s->tried_agent = true;
425 } else {
426 s->tried_publickey = s->tried_agent = false;
428 s->tis_auth_refused = s->ccard_auth_refused = false;
431 * Load the public half of any configured keyfile for later use.
433 s->keyfile = conf_get_filename(s->conf, CONF_keyfile);
434 if (!filename_is_null(s->keyfile)) {
435 int keytype;
436 ppl_logevent("Reading key file \"%s\"", filename_to_str(s->keyfile));
437 keytype = key_type(s->keyfile);
438 if (keytype == SSH_KEYTYPE_SSH1 ||
439 keytype == SSH_KEYTYPE_SSH1_PUBLIC) {
440 const char *error;
441 s->publickey_blob = strbuf_new();
442 if (rsa1_loadpub_f(s->keyfile,
443 BinarySink_UPCAST(s->publickey_blob),
444 &s->publickey_comment, &error)) {
445 s->privatekey_available = (keytype == SSH_KEYTYPE_SSH1);
446 if (!s->privatekey_available)
447 ppl_logevent("Key file contains public key only");
448 s->privatekey_encrypted = rsa1_encrypted_f(s->keyfile, NULL);
449 } else {
450 ppl_logevent("Unable to load key (%s)", error);
451 ppl_printf("Unable to load key file \"%s\" (%s)\r\n",
452 filename_to_str(s->keyfile), error);
454 strbuf_free(s->publickey_blob);
455 s->publickey_blob = NULL;
457 } else {
458 ppl_logevent("Unable to use this key file (%s)",
459 key_type_to_str(keytype));
460 ppl_printf("Unable to use key file \"%s\" (%s)\r\n",
461 filename_to_str(s->keyfile),
462 key_type_to_str(keytype));
466 /* Check whether we're configured to try Pageant, and also whether
467 * it's available. */
468 s->try_agent_auth = (conf_get_bool(s->conf, CONF_tryagent) &&
469 agent_exists());
471 while (pktin->type == SSH1_SMSG_FAILURE) {
472 s->pwpkt_type = SSH1_CMSG_AUTH_PASSWORD;
474 if (s->try_agent_auth && !s->tried_agent) {
476 * Attempt RSA authentication using Pageant.
478 s->authed = false;
479 s->tried_agent = true;
480 ppl_logevent("Pageant is running. Requesting keys.");
482 /* Request the keys held by the agent. */
484 strbuf *request = strbuf_new_for_agent_query();
485 put_byte(request, SSH1_AGENTC_REQUEST_RSA_IDENTITIES);
486 ssh1_login_agent_query(s, request);
487 strbuf_free(request);
488 crMaybeWaitUntilV(!s->auth_agent_query);
490 BinarySource_BARE_INIT_PL(s->asrc, s->agent_response);
492 get_uint32(s->asrc); /* skip length field */
493 if (get_byte(s->asrc) == SSH1_AGENT_RSA_IDENTITIES_ANSWER) {
494 size_t nkeys = get_uint32(s->asrc);
495 size_t origpos = s->asrc->pos;
498 * Check that the agent response is well formed.
500 for (size_t i = 0; i < nkeys; i++) {
501 get_rsa_ssh1_pub(s->asrc, NULL, RSA_SSH1_EXPONENT_FIRST);
502 get_string(s->asrc); /* comment */
503 if (get_err(s->asrc)) {
504 ppl_logevent("Pageant's response was truncated");
505 goto parsed_agent_query;
510 * Copy the list of public-key blobs out of the Pageant
511 * response.
513 BinarySource_REWIND_TO(s->asrc, origpos);
514 s->agent_keys_len = nkeys;
515 s->agent_keys = snewn(s->agent_keys_len, agent_key);
516 for (size_t i = 0; i < nkeys; i++) {
517 memset(&s->agent_keys[i].key, 0,
518 sizeof(s->agent_keys[i].key));
520 const char *blobstart = get_ptr(s->asrc);
521 get_rsa_ssh1_pub(s->asrc, &s->agent_keys[i].key,
522 RSA_SSH1_EXPONENT_FIRST);
523 const char *blobend = get_ptr(s->asrc);
525 s->agent_keys[i].comment = strbuf_dup(get_string(s->asrc));
527 s->agent_keys[i].blob = make_ptrlen(
528 blobstart, blobend - blobstart);
531 ppl_logevent("Pageant has %"SIZEu" SSH-1 keys", nkeys);
533 if (s->publickey_blob) {
535 * If we've been given a specific public key blob,
536 * filter the list of keys to try from the agent
537 * down to only that one, or none if it's not
538 * there.
540 ptrlen our_blob = ptrlen_from_strbuf(s->publickey_blob);
541 size_t i;
543 for (i = 0; i < nkeys; i++) {
544 if (ptrlen_eq_ptrlen(our_blob, s->agent_keys[i].blob))
545 break;
548 if (i < nkeys) {
549 ppl_logevent("Pageant key #%"SIZEu" matches "
550 "configured key file", i);
551 s->agent_key_index = i;
552 s->agent_key_limit = i+1;
553 } else {
554 ppl_logevent("Configured key file not in Pageant");
555 s->agent_key_index = 0;
556 s->agent_key_limit = 0;
558 } else {
560 * Otherwise, try them all.
562 s->agent_key_index = 0;
563 s->agent_key_limit = nkeys;
565 } else {
566 ppl_logevent("Failed to get reply from Pageant");
568 parsed_agent_query:;
570 for (; s->agent_key_index < s->agent_key_limit;
571 s->agent_key_index++) {
572 ppl_logevent("Trying Pageant key #%"SIZEu, s->agent_key_index);
573 pkt = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_CMSG_AUTH_RSA);
574 put_mp_ssh1(pkt,
575 s->agent_keys[s->agent_key_index].key.modulus);
576 pq_push(s->ppl.out_pq, pkt);
577 crMaybeWaitUntilV((pktin = ssh1_login_pop(s))
578 != NULL);
579 if (pktin->type != SSH1_SMSG_AUTH_RSA_CHALLENGE) {
580 ppl_logevent("Key refused");
581 continue;
583 ppl_logevent("Received RSA challenge");
586 mp_int *challenge = get_mp_ssh1(pktin);
587 if (get_err(pktin)) {
588 mp_free(challenge);
589 ssh_proto_error(s->ppl.ssh, "Server's RSA challenge "
590 "was badly formatted");
591 return;
594 strbuf *agentreq = strbuf_new_for_agent_query();
595 put_byte(agentreq, SSH1_AGENTC_RSA_CHALLENGE);
597 rsa_ssh1_public_blob(
598 BinarySink_UPCAST(agentreq),
599 &s->agent_keys[s->agent_key_index].key,
600 RSA_SSH1_EXPONENT_FIRST);
602 put_mp_ssh1(agentreq, challenge);
603 mp_free(challenge);
605 put_data(agentreq, s->session_id, 16);
606 put_uint32(agentreq, 1); /* response format */
607 ssh1_login_agent_query(s, agentreq);
608 strbuf_free(agentreq);
609 crMaybeWaitUntilV(!s->auth_agent_query);
613 const unsigned char *ret = s->agent_response.ptr;
614 if (ret) {
615 if (s->agent_response.len >= 5+16 &&
616 ret[4] == SSH1_AGENT_RSA_RESPONSE) {
617 ppl_logevent("Sending Pageant's response");
618 pkt = ssh_bpp_new_pktout(
619 s->ppl.bpp, SSH1_CMSG_AUTH_RSA_RESPONSE);
620 put_data(pkt, ret + 5, 16);
621 pq_push(s->ppl.out_pq, pkt);
622 s->is_trivial_auth = false;
623 crMaybeWaitUntilV(
624 (pktin = ssh1_login_pop(s))
625 != NULL);
626 if (pktin->type == SSH1_SMSG_SUCCESS) {
627 ppl_logevent("Pageant's response "
628 "accepted");
629 if (seat_verbose(s->ppl.seat)) {
630 ptrlen comment = ptrlen_from_strbuf(
631 s->agent_keys[s->agent_key_index].
632 comment);
633 ppl_printf("Authenticated using RSA "
634 "key \"%.*s\" from "
635 "agent\r\n",
636 PTRLEN_PRINTF(comment));
638 s->authed = true;
639 } else
640 ppl_logevent("Pageant's response not "
641 "accepted");
642 } else {
643 ppl_logevent("Pageant failed to answer "
644 "challenge");
645 sfree((char *)ret);
647 } else {
648 ppl_logevent("No reply received from Pageant");
651 if (s->authed)
652 break;
654 if (s->authed)
655 break;
657 if (s->publickey_blob && s->privatekey_available &&
658 !s->tried_publickey) {
660 * Try public key authentication with the specified
661 * key file.
663 bool got_passphrase; /* need not be kept over crReturn */
664 if (seat_verbose(s->ppl.seat))
665 ppl_printf("Trying public key authentication.\r\n");
666 ppl_logevent("Trying public key \"%s\"",
667 filename_to_str(s->keyfile));
668 s->tried_publickey = true;
669 got_passphrase = false;
670 while (!got_passphrase) {
672 * Get a passphrase, if necessary.
674 int retd;
675 char *passphrase = NULL; /* only written after crReturn */
676 const char *error;
677 if (!s->privatekey_encrypted) {
678 if (seat_verbose(s->ppl.seat))
679 ppl_printf("No passphrase required.\r\n");
680 passphrase = NULL;
681 } else {
682 s->cur_prompt = ssh_ppl_new_prompts(&s->ppl);
683 s->cur_prompt->to_server = false;
684 s->cur_prompt->from_server = false;
685 s->cur_prompt->name = dupstr("SSH key passphrase");
686 add_prompt(s->cur_prompt,
687 dupprintf("Passphrase for key \"%s\": ",
688 s->publickey_comment), false);
689 s->spr = seat_get_userpass_input(
690 ppl_get_iseat(&s->ppl), s->cur_prompt);
691 while (s->spr.kind == SPRK_INCOMPLETE) {
692 crReturnV;
693 s->spr = seat_get_userpass_input(
694 ppl_get_iseat(&s->ppl), s->cur_prompt);
696 if (spr_is_abort(s->spr)) {
697 /* Failed to get a passphrase. Terminate. */
698 ssh_spr_close(s->ppl.ssh, s->spr, "passphrase prompt");
699 return;
701 passphrase = prompt_get_result(s->cur_prompt->prompts[0]);
702 free_prompts(s->cur_prompt);
703 s->cur_prompt = NULL;
706 * Try decrypting key with passphrase.
708 retd = rsa1_load_f(s->keyfile, &s->key, passphrase, &error);
709 if (passphrase) {
710 smemclr(passphrase, strlen(passphrase));
711 sfree(passphrase);
713 if (retd == 1) {
714 /* Correct passphrase. */
715 got_passphrase = true;
716 } else if (retd == 0) {
717 ppl_printf("Couldn't load private key from %s (%s).\r\n",
718 filename_to_str(s->keyfile), error);
719 got_passphrase = false;
720 break; /* go and try something else */
721 } else if (retd == -1) {
722 ppl_printf("Wrong passphrase.\r\n");
723 got_passphrase = false;
724 /* and try again */
725 } else {
726 unreachable("unexpected return from rsa1_load_f()");
730 if (got_passphrase) {
733 * Send a public key attempt.
735 pkt = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_CMSG_AUTH_RSA);
736 put_mp_ssh1(pkt, s->key.modulus);
737 pq_push(s->ppl.out_pq, pkt);
739 crMaybeWaitUntilV((pktin = ssh1_login_pop(s))
740 != NULL);
741 if (pktin->type == SSH1_SMSG_FAILURE) {
742 ppl_printf("Server refused our public key.\r\n");
743 continue; /* go and try something else */
745 if (pktin->type != SSH1_SMSG_AUTH_RSA_CHALLENGE) {
746 ssh_proto_error(s->ppl.ssh, "Received unexpected packet"
747 " in response to offer of public key, "
748 "type %d (%s)", pktin->type,
749 ssh1_pkt_type(pktin->type));
750 return;
754 int i;
755 unsigned char buffer[32];
756 mp_int *challenge, *response;
758 challenge = get_mp_ssh1(pktin);
759 if (get_err(pktin)) {
760 mp_free(challenge);
761 ssh_proto_error(s->ppl.ssh, "Server's RSA challenge "
762 "was badly formatted");
763 return;
765 response = rsa_ssh1_decrypt(challenge, &s->key);
766 freersapriv(&s->key); /* burn the evidence */
768 for (i = 0; i < 32; i++) {
769 buffer[i] = mp_get_byte(response, 31 - i);
773 ssh_hash *h = ssh_hash_new(&ssh_md5);
774 put_data(h, buffer, 32);
775 put_data(h, s->session_id, 16);
776 ssh_hash_final(h, buffer);
779 pkt = ssh_bpp_new_pktout(
780 s->ppl.bpp, SSH1_CMSG_AUTH_RSA_RESPONSE);
781 put_data(pkt, buffer, 16);
782 pq_push(s->ppl.out_pq, pkt);
783 s->is_trivial_auth = false;
785 mp_free(challenge);
786 mp_free(response);
789 crMaybeWaitUntilV((pktin = ssh1_login_pop(s))
790 != NULL);
791 if (pktin->type == SSH1_SMSG_FAILURE) {
792 if (seat_verbose(s->ppl.seat))
793 ppl_printf("Failed to authenticate with"
794 " our public key.\r\n");
795 continue; /* go and try something else */
796 } else if (pktin->type != SSH1_SMSG_SUCCESS) {
797 ssh_proto_error(s->ppl.ssh, "Received unexpected packet"
798 " in response to RSA authentication, "
799 "type %d (%s)", pktin->type,
800 ssh1_pkt_type(pktin->type));
801 return;
804 break; /* we're through! */
810 * Otherwise, try various forms of password-like authentication.
812 s->cur_prompt = ssh_ppl_new_prompts(&s->ppl);
814 if (conf_get_bool(s->conf, CONF_try_tis_auth) &&
815 (s->supported_auths_mask & (1 << SSH1_AUTH_TIS)) &&
816 !s->tis_auth_refused) {
817 ssh1_login_setup_tis_scc(s);
818 s->pwpkt_type = SSH1_CMSG_AUTH_TIS_RESPONSE;
819 ppl_logevent("Requested TIS authentication");
820 pkt = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_CMSG_AUTH_TIS);
821 pq_push(s->ppl.out_pq, pkt);
822 crMaybeWaitUntilV((pktin = ssh1_login_pop(s)) != NULL);
823 if (pktin->type == SSH1_SMSG_FAILURE) {
824 ppl_logevent("TIS authentication declined");
825 if (seat_interactive(s->ppl.seat))
826 ppl_printf("TIS authentication refused.\r\n");
827 s->tis_auth_refused = true;
828 continue;
829 } else if (pktin->type == SSH1_SMSG_AUTH_TIS_CHALLENGE) {
830 ptrlen challenge = get_string(pktin);
831 if (get_err(pktin)) {
832 ssh_proto_error(s->ppl.ssh, "TIS challenge packet was "
833 "badly formed");
834 return;
836 ppl_logevent("Received TIS challenge");
837 s->cur_prompt->to_server = true;
838 s->cur_prompt->from_server = true;
839 s->cur_prompt->name = dupstr("SSH TIS authentication");
841 strbuf *sb = strbuf_new();
842 put_datapl(sb, PTRLEN_LITERAL("\
843 -- TIS authentication challenge from server: ---------------------------------\
844 \r\n"));
845 if (s->tis_scc) {
846 stripctrl_retarget(s->tis_scc, BinarySink_UPCAST(sb));
847 put_datapl(s->tis_scc, challenge);
848 stripctrl_retarget(s->tis_scc, NULL);
849 } else {
850 put_datapl(sb, challenge);
852 if (!ptrlen_endswith(challenge, PTRLEN_LITERAL("\n"), NULL))
853 put_datapl(sb, PTRLEN_LITERAL("\r\n"));
854 put_datapl(sb, PTRLEN_LITERAL("\
855 -- End of TIS authentication challenge from server: --------------------------\
856 \r\n"));
858 s->cur_prompt->instruction = strbuf_to_str(sb);
859 s->cur_prompt->instr_reqd = true;
860 add_prompt(s->cur_prompt, dupstr(
861 "TIS authentication response: "), false);
862 } else {
863 ssh_proto_error(s->ppl.ssh, "Received unexpected packet"
864 " in response to TIS authentication, "
865 "type %d (%s)", pktin->type,
866 ssh1_pkt_type(pktin->type));
867 return;
869 } else if (conf_get_bool(s->conf, CONF_try_tis_auth) &&
870 (s->supported_auths_mask & (1 << SSH1_AUTH_CCARD)) &&
871 !s->ccard_auth_refused) {
872 ssh1_login_setup_tis_scc(s);
873 s->pwpkt_type = SSH1_CMSG_AUTH_CCARD_RESPONSE;
874 ppl_logevent("Requested CryptoCard authentication");
875 pkt = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_CMSG_AUTH_CCARD);
876 pq_push(s->ppl.out_pq, pkt);
877 crMaybeWaitUntilV((pktin = ssh1_login_pop(s)) != NULL);
878 if (pktin->type == SSH1_SMSG_FAILURE) {
879 ppl_logevent("CryptoCard authentication declined");
880 ppl_printf("CryptoCard authentication refused.\r\n");
881 s->ccard_auth_refused = true;
882 continue;
883 } else if (pktin->type == SSH1_SMSG_AUTH_CCARD_CHALLENGE) {
884 ptrlen challenge = get_string(pktin);
885 if (get_err(pktin)) {
886 ssh_proto_error(s->ppl.ssh, "CryptoCard challenge packet "
887 "was badly formed");
888 return;
890 ppl_logevent("Received CryptoCard challenge");
891 s->cur_prompt->to_server = true;
892 s->cur_prompt->from_server = true;
893 s->cur_prompt->name = dupstr("SSH CryptoCard authentication");
895 strbuf *sb = strbuf_new();
896 put_datapl(sb, PTRLEN_LITERAL("\
897 -- CryptoCard authentication challenge from server: --------------------------\
898 \r\n"));
899 if (s->tis_scc) {
900 stripctrl_retarget(s->tis_scc, BinarySink_UPCAST(sb));
901 put_datapl(s->tis_scc, challenge);
902 stripctrl_retarget(s->tis_scc, NULL);
903 } else {
904 put_datapl(sb, challenge);
906 if (!ptrlen_endswith(challenge, PTRLEN_LITERAL("\n"), NULL))
907 put_datapl(sb, PTRLEN_LITERAL("\r\n"));
908 put_datapl(sb, PTRLEN_LITERAL("\
909 -- End of CryptoCard authentication challenge from server: -------------------\
910 \r\n"));
912 s->cur_prompt->instruction = strbuf_to_str(sb);
913 s->cur_prompt->instr_reqd = true;
914 add_prompt(s->cur_prompt, dupstr(
915 "CryptoCard authentication response: "), false);
916 } else {
917 ssh_proto_error(s->ppl.ssh, "Received unexpected packet"
918 " in response to TIS authentication, "
919 "type %d (%s)", pktin->type,
920 ssh1_pkt_type(pktin->type));
921 return;
924 if (s->pwpkt_type == SSH1_CMSG_AUTH_PASSWORD) {
925 if ((s->supported_auths_mask & (1 << SSH1_AUTH_PASSWORD)) == 0) {
926 ssh_sw_abort(s->ppl.ssh, "No supported authentication methods "
927 "available");
928 return;
930 s->cur_prompt->to_server = true;
931 s->cur_prompt->from_server = false;
932 s->cur_prompt->name = dupstr("SSH password");
933 add_prompt(s->cur_prompt, dupprintf("%s@%s's password: ",
934 s->username, s->savedhost),
935 false);
939 * Show password prompt, having first obtained it via a TIS
940 * or CryptoCard exchange if we're doing TIS or CryptoCard
941 * authentication.
943 s->spr = seat_get_userpass_input(
944 ppl_get_iseat(&s->ppl), s->cur_prompt);
945 while (s->spr.kind == SPRK_INCOMPLETE) {
946 crReturnV;
947 s->spr = seat_get_userpass_input(
948 ppl_get_iseat(&s->ppl), s->cur_prompt);
950 if (spr_is_abort(s->spr)) {
952 * Failed to get a password (for example
953 * because one was supplied on the command line
954 * which has already failed to work). Terminate.
956 ssh_spr_close(s->ppl.ssh, s->spr, "password prompt");
957 return;
960 if (s->pwpkt_type == SSH1_CMSG_AUTH_PASSWORD) {
962 * Defence against traffic analysis: we send a
963 * whole bunch of packets containing strings of
964 * different lengths. One of these strings is the
965 * password, in a SSH1_CMSG_AUTH_PASSWORD packet.
966 * The others are all random data in
967 * SSH1_MSG_IGNORE packets. This way a passive
968 * listener can't tell which is the password, and
969 * hence can't deduce the password length.
971 * Anybody with a password length greater than 16
972 * bytes is going to have enough entropy in their
973 * password that a listener won't find it _that_
974 * much help to know how long it is. So what we'll
975 * do is:
977 * - if password length < 16, we send 15 packets
978 * containing string lengths 1 through 15
980 * - otherwise, we let N be the nearest multiple
981 * of 8 below the password length, and send 8
982 * packets containing string lengths N through
983 * N+7. This won't obscure the order of
984 * magnitude of the password length, but it will
985 * introduce a bit of extra uncertainty.
987 * A few servers can't deal with SSH1_MSG_IGNORE, at
988 * least in this context. For these servers, we need
989 * an alternative defence. We make use of the fact
990 * that the password is interpreted as a C string:
991 * so we can append a NUL, then some random data.
993 * A few servers can deal with neither SSH1_MSG_IGNORE
994 * here _nor_ a padded password string.
995 * For these servers we are left with no defences
996 * against password length sniffing.
998 if (!(s->ppl.remote_bugs & BUG_CHOKES_ON_SSH1_IGNORE) &&
999 !(s->ppl.remote_bugs & BUG_NEEDS_SSH1_PLAIN_PASSWORD)) {
1001 * The server can deal with SSH1_MSG_IGNORE, so
1002 * we can use the primary defence.
1004 int bottom, top, pwlen, i;
1005 const char *pw = prompt_get_result_ref(
1006 s->cur_prompt->prompts[0]);
1008 pwlen = strlen(pw);
1009 if (pwlen < 16) {
1010 bottom = 0; /* zero length passwords are OK! :-) */
1011 top = 15;
1012 } else {
1013 bottom = pwlen & ~7;
1014 top = bottom + 7;
1017 assert(pwlen >= bottom && pwlen <= top);
1019 for (i = bottom; i <= top; i++) {
1020 if (i == pwlen) {
1021 pkt = ssh_bpp_new_pktout(s->ppl.bpp, s->pwpkt_type);
1022 put_stringz(pkt, pw);
1023 pq_push(s->ppl.out_pq, pkt);
1024 } else {
1025 strbuf *random_data = strbuf_new_nm();
1026 random_read(strbuf_append(random_data, i), i);
1028 pkt = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_MSG_IGNORE);
1029 put_stringsb(pkt, random_data);
1030 pq_push(s->ppl.out_pq, pkt);
1033 ppl_logevent("Sending password with camouflage packets");
1035 else if (!(s->ppl.remote_bugs & BUG_NEEDS_SSH1_PLAIN_PASSWORD)) {
1037 * The server can't deal with SSH1_MSG_IGNORE
1038 * but can deal with padded passwords, so we
1039 * can use the secondary defence.
1041 strbuf *padded_pw = strbuf_new_nm();
1043 ppl_logevent("Sending length-padded password");
1044 pkt = ssh_bpp_new_pktout(s->ppl.bpp, s->pwpkt_type);
1045 put_asciz(padded_pw, prompt_get_result_ref(
1046 s->cur_prompt->prompts[0]));
1047 size_t pad = 63 & -padded_pw->len;
1048 random_read(strbuf_append(padded_pw, pad), pad);
1049 put_stringsb(pkt, padded_pw);
1050 pq_push(s->ppl.out_pq, pkt);
1051 } else {
1053 * The server is believed unable to cope with
1054 * any of our password camouflage methods.
1056 ppl_logevent("Sending unpadded password");
1057 pkt = ssh_bpp_new_pktout(s->ppl.bpp, s->pwpkt_type);
1058 put_stringz(pkt, prompt_get_result_ref(
1059 s->cur_prompt->prompts[0]));
1060 pq_push(s->ppl.out_pq, pkt);
1062 } else {
1063 pkt = ssh_bpp_new_pktout(s->ppl.bpp, s->pwpkt_type);
1064 put_stringz(pkt, prompt_get_result_ref(s->cur_prompt->prompts[0]));
1065 pq_push(s->ppl.out_pq, pkt);
1067 s->is_trivial_auth = false;
1068 ppl_logevent("Sent password");
1069 free_prompts(s->cur_prompt);
1070 s->cur_prompt = NULL;
1071 crMaybeWaitUntilV((pktin = ssh1_login_pop(s)) != NULL);
1072 if (pktin->type == SSH1_SMSG_FAILURE) {
1073 if (seat_verbose(s->ppl.seat))
1074 ppl_printf("Access denied\r\n");
1075 ppl_logevent("Authentication refused");
1076 } else if (pktin->type != SSH1_SMSG_SUCCESS) {
1077 ssh_proto_error(s->ppl.ssh, "Received unexpected packet"
1078 " in response to password authentication, type %d "
1079 "(%s)", pktin->type, ssh1_pkt_type(pktin->type));
1080 return;
1084 if (conf_get_bool(s->conf, CONF_ssh_no_trivial_userauth) &&
1085 s->is_trivial_auth) {
1086 ssh_proto_error(s->ppl.ssh, "Authentication was trivial! "
1087 "Abandoning session as specified in configuration.");
1088 return;
1091 ppl_logevent("Authentication successful");
1093 if (conf_get_bool(s->conf, CONF_compression)) {
1094 ppl_logevent("Requesting compression");
1095 pkt = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_CMSG_REQUEST_COMPRESSION);
1096 put_uint32(pkt, 6); /* gzip compression level */
1097 pq_push(s->ppl.out_pq, pkt);
1098 crMaybeWaitUntilV((pktin = ssh1_login_pop(s)) != NULL);
1099 if (pktin->type == SSH1_SMSG_SUCCESS) {
1101 * We don't have to actually do anything here: the SSH-1
1102 * BPP will take care of automatically starting the
1103 * compression, by recognising our outgoing request packet
1104 * and the success response. (Horrible, but it's the
1105 * easiest way to avoid race conditions if other packets
1106 * cross in transit.)
1108 } else if (pktin->type == SSH1_SMSG_FAILURE) {
1109 ppl_logevent("Server refused to enable compression");
1110 ppl_printf("Server refused to compress\r\n");
1111 } else {
1112 ssh_proto_error(s->ppl.ssh, "Received unexpected packet"
1113 " in response to compression request, type %d "
1114 "(%s)", pktin->type, ssh1_pkt_type(pktin->type));
1115 return;
1119 ssh1_connection_set_protoflags(
1120 s->successor_layer, s->local_protoflags, s->remote_protoflags);
1122 PacketProtocolLayer *successor = s->successor_layer;
1123 s->successor_layer = NULL; /* avoid freeing it ourself */
1124 ssh_ppl_replace(&s->ppl, successor);
1125 return; /* we've just freed s, so avoid even touching s->crState */
1128 crFinishV;
1131 static void ssh1_login_setup_tis_scc(struct ssh1_login_state *s)
1133 if (s->tis_scc_initialised)
1134 return;
1135 s->tis_scc = seat_stripctrl_new(s->ppl.seat, NULL, SIC_KI_PROMPTS);
1136 if (s->tis_scc)
1137 stripctrl_enable_line_limiting(s->tis_scc);
1138 s->tis_scc_initialised = true;
1141 static void ssh1_login_dialog_callback(void *loginv, SeatPromptResult spr)
1143 struct ssh1_login_state *s = (struct ssh1_login_state *)loginv;
1144 s->spr = spr;
1145 ssh_ppl_process_queue(&s->ppl);
1148 static void ssh1_login_agent_query(struct ssh1_login_state *s, strbuf *req)
1150 void *response;
1151 int response_len;
1153 sfree(s->agent_response_to_free);
1154 s->agent_response_to_free = NULL;
1156 s->auth_agent_query = agent_query(req, &response, &response_len,
1157 ssh1_login_agent_callback, s);
1158 if (!s->auth_agent_query)
1159 ssh1_login_agent_callback(s, response, response_len);
1162 static void ssh1_login_agent_callback(void *loginv, void *reply, int replylen)
1164 struct ssh1_login_state *s = (struct ssh1_login_state *)loginv;
1166 s->auth_agent_query = NULL;
1167 s->agent_response_to_free = reply;
1168 s->agent_response = make_ptrlen(reply, replylen);
1170 queue_idempotent_callback(&s->ppl.ic_process_queue);
1173 static void ssh1_login_special_cmd(PacketProtocolLayer *ppl,
1174 SessionSpecialCode code, int arg)
1176 struct ssh1_login_state *s =
1177 container_of(ppl, struct ssh1_login_state, ppl);
1178 PktOut *pktout;
1180 if (code == SS_PING || code == SS_NOP) {
1181 if (!(s->ppl.remote_bugs & BUG_CHOKES_ON_SSH1_IGNORE)) {
1182 pktout = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_MSG_IGNORE);
1183 put_stringz(pktout, "");
1184 pq_push(s->ppl.out_pq, pktout);
1189 static void ssh1_login_reconfigure(PacketProtocolLayer *ppl, Conf *conf)
1191 struct ssh1_login_state *s =
1192 container_of(ppl, struct ssh1_login_state, ppl);
1193 ssh_ppl_reconfigure(s->successor_layer, conf);