Home | History | Annotate | Download | only in ssh
      1 /*
      2  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
      3  * Use is subject to license terms.
      4  */
      5 /*
      6  * Author: Tatu Ylonen <ylo (at) cs.hut.fi>
      7  * Copyright (c) 1995 Tatu Ylonen <ylo (at) cs.hut.fi>, Espoo, Finland
      8  *                    All rights reserved
      9  * Code to connect to a remote host, and to perform the client side of the
     10  * login (authentication) dialog.
     11  *
     12  * As far as I am concerned, the code I have written for this software
     13  * can be used freely for any purpose.  Any derived versions of this
     14  * software must be clearly marked as such, and if the derived work is
     15  * incompatible with the protocol description in the RFC file, it must be
     16  * called by a name other than "ssh" or "Secure Shell".
     17  */
     18 
     19 #include "includes.h"
     20 RCSID("$OpenBSD: sshconnect1.c,v 1.52 2002/08/08 13:50:23 aaron Exp $");
     21 
     22 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     23 
     24 #include <openssl/bn.h>
     25 #include <openssl/md5.h>
     26 
     27 #ifdef KRB4
     28 #include <krb.h>
     29 #endif
     30 #ifdef KRB5
     31 #include <krb5.h>
     32 #ifndef HEIMDAL
     33 #define krb5_get_err_text(context,code) error_message(code)
     34 #endif /* !HEIMDAL */
     35 #endif
     36 #ifdef AFS
     37 #include <kafs.h>
     38 #include "radix.h"
     39 #endif
     40 
     41 #include "ssh.h"
     42 #include "ssh1.h"
     43 #include "xmalloc.h"
     44 #include "rsa.h"
     45 #include "buffer.h"
     46 #include "packet.h"
     47 #include "mpaux.h"
     48 #include "uidswap.h"
     49 #include "log.h"
     50 #include "readconf.h"
     51 #include "key.h"
     52 #include "authfd.h"
     53 #include "sshconnect.h"
     54 #include "authfile.h"
     55 #include "readpass.h"
     56 #include "cipher.h"
     57 #include "canohost.h"
     58 #include "auth.h"
     59 
     60 /* Session id for the current session. */
     61 u_char session_id[16];
     62 u_int supported_authentications = 0;
     63 
     64 extern Options options;
     65 extern char *__progname;
     66 
     67 /*
     68  * Checks if the user has an authentication agent, and if so, tries to
     69  * authenticate using the agent.
     70  */
     71 static int
     72 try_agent_authentication(void)
     73 {
     74 	int type;
     75 	char *comment;
     76 	AuthenticationConnection *auth;
     77 	u_char response[16];
     78 	u_int i;
     79 	Key *key;
     80 	BIGNUM *challenge;
     81 
     82 	/* Get connection to the agent. */
     83 	auth = ssh_get_authentication_connection();
     84 	if (!auth)
     85 		return 0;
     86 
     87 	if ((challenge = BN_new()) == NULL)
     88 		fatal("try_agent_authentication: BN_new failed");
     89 	/* Loop through identities served by the agent. */
     90 	for (key = ssh_get_first_identity(auth, &comment, 1);
     91 	    key != NULL;
     92 	    key = ssh_get_next_identity(auth, &comment, 1)) {
     93 
     94 		/* Try this identity. */
     95 		debug("Trying RSA authentication via agent with '%.100s'", comment);
     96 		xfree(comment);
     97 
     98 		/* Tell the server that we are willing to authenticate using this key. */
     99 		packet_start(SSH_CMSG_AUTH_RSA);
    100 		packet_put_bignum(key->rsa->n);
    101 		packet_send();
    102 		packet_write_wait();
    103 
    104 		/* Wait for server's response. */
    105 		type = packet_read();
    106 
    107 		/* The server sends failure if it doesn\'t like our key or
    108 		   does not support RSA authentication. */
    109 		if (type == SSH_SMSG_FAILURE) {
    110 			debug("Server refused our key.");
    111 			key_free(key);
    112 			continue;
    113 		}
    114 		/* Otherwise it should have sent a challenge. */
    115 		if (type != SSH_SMSG_AUTH_RSA_CHALLENGE)
    116 			packet_disconnect("Protocol error during RSA authentication: %d",
    117 					  type);
    118 
    119 		packet_get_bignum(challenge);
    120 		packet_check_eom();
    121 
    122 		debug("Received RSA challenge from server.");
    123 
    124 		/* Ask the agent to decrypt the challenge. */
    125 		if (!ssh_decrypt_challenge(auth, key, challenge, session_id, 1, response)) {
    126 			/*
    127 			 * The agent failed to authenticate this identifier
    128 			 * although it advertised it supports this.  Just
    129 			 * return a wrong value.
    130 			 */
    131 			log("Authentication agent failed to decrypt challenge.");
    132 			memset(response, 0, sizeof(response));
    133 		}
    134 		key_free(key);
    135 		debug("Sending response to RSA challenge.");
    136 
    137 		/* Send the decrypted challenge back to the server. */
    138 		packet_start(SSH_CMSG_AUTH_RSA_RESPONSE);
    139 		for (i = 0; i < 16; i++)
    140 			packet_put_char(response[i]);
    141 		packet_send();
    142 		packet_write_wait();
    143 
    144 		/* Wait for response from the server. */
    145 		type = packet_read();
    146 
    147 		/* The server returns success if it accepted the authentication. */
    148 		if (type == SSH_SMSG_SUCCESS) {
    149 			ssh_close_authentication_connection(auth);
    150 			BN_clear_free(challenge);
    151 			debug("RSA authentication accepted by server.");
    152 			return 1;
    153 		}
    154 		/* Otherwise it should return failure. */
    155 		if (type != SSH_SMSG_FAILURE)
    156 			packet_disconnect("Protocol error waiting RSA auth response: %d",
    157 					  type);
    158 	}
    159 	ssh_close_authentication_connection(auth);
    160 	BN_clear_free(challenge);
    161 	debug("RSA authentication using agent refused.");
    162 	return 0;
    163 }
    164 
    165 /*
    166  * Computes the proper response to a RSA challenge, and sends the response to
    167  * the server.
    168  */
    169 static void
    170 respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv)
    171 {
    172 	u_char buf[32], response[16];
    173 	MD5_CTX md;
    174 	int i, len;
    175 
    176 	/* Decrypt the challenge using the private key. */
    177 	/* XXX think about Bleichenbacher, too */
    178 	if (rsa_private_decrypt(challenge, challenge, prv) <= 0)
    179 		packet_disconnect(
    180 		    "respond_to_rsa_challenge: rsa_private_decrypt failed");
    181 
    182 	/* Compute the response. */
    183 	/* The response is MD5 of decrypted challenge plus session id. */
    184 	len = BN_num_bytes(challenge);
    185 	if (len <= 0 || len > sizeof(buf))
    186 		packet_disconnect(
    187 		    "respond_to_rsa_challenge: bad challenge length %d", len);
    188 
    189 	memset(buf, 0, sizeof(buf));
    190 	BN_bn2bin(challenge, buf + sizeof(buf) - len);
    191 	MD5_Init(&md);
    192 	MD5_Update(&md, buf, 32);
    193 	MD5_Update(&md, session_id, 16);
    194 	MD5_Final(response, &md);
    195 
    196 	debug("Sending response to host key RSA challenge.");
    197 
    198 	/* Send the response back to the server. */
    199 	packet_start(SSH_CMSG_AUTH_RSA_RESPONSE);
    200 	for (i = 0; i < 16; i++)
    201 		packet_put_char(response[i]);
    202 	packet_send();
    203 	packet_write_wait();
    204 
    205 	memset(buf, 0, sizeof(buf));
    206 	memset(response, 0, sizeof(response));
    207 	memset(&md, 0, sizeof(md));
    208 }
    209 
    210 /*
    211  * Checks if the user has authentication file, and if so, tries to authenticate
    212  * the user using it.
    213  */
    214 static int
    215 try_rsa_authentication(int idx)
    216 {
    217 	BIGNUM *challenge;
    218 	Key *public, *private;
    219 	char buf[300], *passphrase, *comment, *authfile;
    220 	int i, type, quit;
    221 
    222 	public = options.identity_keys[idx];
    223 	authfile = options.identity_files[idx];
    224 	comment = xstrdup(authfile);
    225 
    226 	debug("Trying RSA authentication with key '%.100s'", comment);
    227 
    228 	/* Tell the server that we are willing to authenticate using this key. */
    229 	packet_start(SSH_CMSG_AUTH_RSA);
    230 	packet_put_bignum(public->rsa->n);
    231 	packet_send();
    232 	packet_write_wait();
    233 
    234 	/* Wait for server's response. */
    235 	type = packet_read();
    236 
    237 	/*
    238 	 * The server responds with failure if it doesn\'t like our key or
    239 	 * doesn\'t support RSA authentication.
    240 	 */
    241 	if (type == SSH_SMSG_FAILURE) {
    242 		debug("Server refused our key.");
    243 		xfree(comment);
    244 		return 0;
    245 	}
    246 	/* Otherwise, the server should respond with a challenge. */
    247 	if (type != SSH_SMSG_AUTH_RSA_CHALLENGE)
    248 		packet_disconnect("Protocol error during RSA authentication: %d", type);
    249 
    250 	/* Get the challenge from the packet. */
    251 	if ((challenge = BN_new()) == NULL)
    252 		fatal("try_rsa_authentication: BN_new failed");
    253 	packet_get_bignum(challenge);
    254 	packet_check_eom();
    255 
    256 	debug("Received RSA challenge from server.");
    257 
    258 	/*
    259 	 * If the key is not stored in external hardware, we have to
    260 	 * load the private key.  Try first with empty passphrase; if it
    261 	 * fails, ask for a passphrase.
    262 	 */
    263 	if (public->flags & KEY_FLAG_EXT)
    264 		private = public;
    265 	else
    266 		private = key_load_private_type(KEY_RSA1, authfile, "", NULL);
    267 	if (private == NULL && !options.batch_mode) {
    268 		snprintf(buf, sizeof(buf),
    269 		    gettext("Enter passphrase for RSA key '%.100s': "),
    270 		    comment);
    271 		for (i = 0; i < options.number_of_password_prompts; i++) {
    272 			passphrase = read_passphrase(buf, 0);
    273 			if (strcmp(passphrase, "") != 0) {
    274 				private = key_load_private_type(KEY_RSA1,
    275 				    authfile, passphrase, NULL);
    276 				quit = 0;
    277 			} else {
    278 				debug2("no passphrase given, try next key");
    279 				quit = 1;
    280 			}
    281 			memset(passphrase, 0, strlen(passphrase));
    282 			xfree(passphrase);
    283 			if (private != NULL || quit)
    284 				break;
    285 			debug2("bad passphrase given, try again...");
    286 		}
    287 	}
    288 	/* We no longer need the comment. */
    289 	xfree(comment);
    290 
    291 	if (private == NULL) {
    292 		if (!options.batch_mode)
    293 			error("Bad passphrase.");
    294 
    295 		/* Send a dummy response packet to avoid protocol error. */
    296 		packet_start(SSH_CMSG_AUTH_RSA_RESPONSE);
    297 		for (i = 0; i < 16; i++)
    298 			packet_put_char(0);
    299 		packet_send();
    300 		packet_write_wait();
    301 
    302 		/* Expect the server to reject it... */
    303 		packet_read_expect(SSH_SMSG_FAILURE);
    304 		BN_clear_free(challenge);
    305 		return 0;
    306 	}
    307 
    308 	/* Compute and send a response to the challenge. */
    309 	respond_to_rsa_challenge(challenge, private->rsa);
    310 
    311 	/* Destroy the private key unless it in external hardware. */
    312 	if (!(private->flags & KEY_FLAG_EXT))
    313 		key_free(private);
    314 
    315 	/* We no longer need the challenge. */
    316 	BN_clear_free(challenge);
    317 
    318 	/* Wait for response from the server. */
    319 	type = packet_read();
    320 	if (type == SSH_SMSG_SUCCESS) {
    321 		debug("RSA authentication accepted by server.");
    322 		return 1;
    323 	}
    324 	if (type != SSH_SMSG_FAILURE)
    325 		packet_disconnect("Protocol error waiting RSA auth response: %d", type);
    326 	debug("RSA authentication refused.");
    327 	return 0;
    328 }
    329 
    330 /*
    331  * Tries to authenticate the user using combined rhosts or /etc/hosts.equiv
    332  * authentication and RSA host authentication.
    333  */
    334 static int
    335 try_rhosts_rsa_authentication(const char *local_user, Key * host_key)
    336 {
    337 	int type;
    338 	BIGNUM *challenge;
    339 
    340 	debug("Trying rhosts or /etc/hosts.equiv with RSA host authentication.");
    341 
    342 	/* Tell the server that we are willing to authenticate using this key. */
    343 	packet_start(SSH_CMSG_AUTH_RHOSTS_RSA);
    344 	packet_put_cstring(local_user);
    345 	packet_put_int(BN_num_bits(host_key->rsa->n));
    346 	packet_put_bignum(host_key->rsa->e);
    347 	packet_put_bignum(host_key->rsa->n);
    348 	packet_send();
    349 	packet_write_wait();
    350 
    351 	/* Wait for server's response. */
    352 	type = packet_read();
    353 
    354 	/* The server responds with failure if it doesn't admit our
    355 	   .rhosts authentication or doesn't know our host key. */
    356 	if (type == SSH_SMSG_FAILURE) {
    357 		debug("Server refused our rhosts authentication or host key.");
    358 		return 0;
    359 	}
    360 	/* Otherwise, the server should respond with a challenge. */
    361 	if (type != SSH_SMSG_AUTH_RSA_CHALLENGE)
    362 		packet_disconnect("Protocol error during RSA authentication: %d", type);
    363 
    364 	/* Get the challenge from the packet. */
    365 	if ((challenge = BN_new()) == NULL)
    366 		fatal("try_rhosts_rsa_authentication: BN_new failed");
    367 	packet_get_bignum(challenge);
    368 	packet_check_eom();
    369 
    370 	debug("Received RSA challenge for host key from server.");
    371 
    372 	/* Compute a response to the challenge. */
    373 	respond_to_rsa_challenge(challenge, host_key->rsa);
    374 
    375 	/* We no longer need the challenge. */
    376 	BN_clear_free(challenge);
    377 
    378 	/* Wait for response from the server. */
    379 	type = packet_read();
    380 	if (type == SSH_SMSG_SUCCESS) {
    381 		debug("Rhosts or /etc/hosts.equiv with RSA host authentication accepted by server.");
    382 		return 1;
    383 	}
    384 	if (type != SSH_SMSG_FAILURE)
    385 		packet_disconnect("Protocol error waiting RSA auth response: %d", type);
    386 	debug("Rhosts or /etc/hosts.equiv with RSA host authentication refused.");
    387 	return 0;
    388 }
    389 
    390 #ifdef KRB4
    391 static int
    392 try_krb4_authentication(void)
    393 {
    394 	KTEXT_ST auth;		/* Kerberos data */
    395 	char *reply;
    396 	char inst[INST_SZ];
    397 	char *realm;
    398 	CREDENTIALS cred;
    399 	int r, type;
    400 	socklen_t slen;
    401 	Key_schedule schedule;
    402 	u_long checksum, cksum;
    403 	MSG_DAT msg_data;
    404 	struct sockaddr_in local, foreign;
    405 	struct stat st;
    406 
    407 	/* Don't do anything if we don't have any tickets. */
    408 	if (stat(tkt_string(), &st) < 0)
    409 		return 0;
    410 
    411 	strlcpy(inst, (char *)krb_get_phost(get_canonical_hostname(1)),
    412 	    INST_SZ);
    413 
    414 	realm = (char *)krb_realmofhost(get_canonical_hostname(1));
    415 	if (!realm) {
    416 		debug("Kerberos v4: no realm for %s", get_canonical_hostname(1));
    417 		return 0;
    418 	}
    419 	/* This can really be anything. */
    420 	checksum = (u_long)getpid();
    421 
    422 	r = krb_mk_req(&auth, KRB4_SERVICE_NAME, inst, realm, checksum);
    423 	if (r != KSUCCESS) {
    424 		debug("Kerberos v4 krb_mk_req failed: %s", krb_err_txt[r]);
    425 		return 0;
    426 	}
    427 	/* Get session key to decrypt the server's reply with. */
    428 	r = krb_get_cred(KRB4_SERVICE_NAME, inst, realm, &cred);
    429 	if (r != KSUCCESS) {
    430 		debug("get_cred failed: %s", krb_err_txt[r]);
    431 		return 0;
    432 	}
    433 	des_key_sched((des_cblock *) cred.session, schedule);
    434 
    435 	/* Send authentication info to server. */
    436 	packet_start(SSH_CMSG_AUTH_KERBEROS);
    437 	packet_put_string((char *) auth.dat, auth.length);
    438 	packet_send();
    439 	packet_write_wait();
    440 
    441 	/* Zero the buffer. */
    442 	(void) memset(auth.dat, 0, MAX_KTXT_LEN);
    443 
    444 	slen = sizeof(local);
    445 	memset(&local, 0, sizeof(local));
    446 	if (getsockname(packet_get_connection_in(),
    447 	    (struct sockaddr *)&local, &slen) < 0)
    448 		debug("getsockname failed: %s", strerror(errno));
    449 
    450 	slen = sizeof(foreign);
    451 	memset(&foreign, 0, sizeof(foreign));
    452 	if (getpeername(packet_get_connection_in(),
    453 	    (struct sockaddr *)&foreign, &slen) < 0) {
    454 		debug("getpeername failed: %s", strerror(errno));
    455 		fatal_cleanup();
    456 	}
    457 	/* Get server reply. */
    458 	type = packet_read();
    459 	switch (type) {
    460 	case SSH_SMSG_FAILURE:
    461 		/* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */
    462 		debug("Kerberos v4 authentication failed.");
    463 		return 0;
    464 		break;
    465 
    466 	case SSH_SMSG_AUTH_KERBEROS_RESPONSE:
    467 		/* SSH_SMSG_AUTH_KERBEROS_SUCCESS */
    468 		debug("Kerberos v4 authentication accepted.");
    469 
    470 		/* Get server's response. */
    471 		reply = packet_get_string((u_int *) &auth.length);
    472 		if (auth.length >= MAX_KTXT_LEN)
    473 			fatal("Kerberos v4: Malformed response from server");
    474 		memcpy(auth.dat, reply, auth.length);
    475 		xfree(reply);
    476 
    477 		packet_check_eom();
    478 
    479 		/*
    480 		 * If his response isn't properly encrypted with the session
    481 		 * key, and the decrypted checksum fails to match, he's
    482 		 * bogus. Bail out.
    483 		 */
    484 		r = krb_rd_priv(auth.dat, auth.length, schedule, &cred.session,
    485 		    &foreign, &local, &msg_data);
    486 		if (r != KSUCCESS) {
    487 			debug("Kerberos v4 krb_rd_priv failed: %s",
    488 			    krb_err_txt[r]);
    489 			packet_disconnect("Kerberos v4 challenge failed!");
    490 		}
    491 		/* Fetch the (incremented) checksum that we supplied in the request. */
    492 		memcpy((char *)&cksum, (char *)msg_data.app_data,
    493 		    sizeof(cksum));
    494 		cksum = ntohl(cksum);
    495 
    496 		/* If it matches, we're golden. */
    497 		if (cksum == checksum + 1) {
    498 			debug("Kerberos v4 challenge successful.");
    499 			return 1;
    500 		} else
    501 			packet_disconnect("Kerberos v4 challenge failed!");
    502 		break;
    503 
    504 	default:
    505 		packet_disconnect("Protocol error on Kerberos v4 response: %d", type);
    506 	}
    507 	return 0;
    508 }
    509 
    510 #endif /* KRB4 */
    511 
    512 #ifdef KRB5
    513 static int
    514 try_krb5_authentication(krb5_context *context, krb5_auth_context *auth_context)
    515 {
    516 	krb5_error_code problem;
    517 	const char *tkfile;
    518 	struct stat buf;
    519 	krb5_ccache ccache = NULL;
    520 	const char *remotehost;
    521 	krb5_data ap;
    522 	int type;
    523 	krb5_ap_rep_enc_part *reply = NULL;
    524 	int ret;
    525 
    526 	memset(&ap, 0, sizeof(ap));
    527 
    528 	problem = krb5_init_context(context);
    529 	if (problem) {
    530 		debug("Kerberos v5: krb5_init_context failed");
    531 		ret = 0;
    532 		goto out;
    533 	}
    534 
    535 	problem = krb5_auth_con_init(*context, auth_context);
    536 	if (problem) {
    537 		debug("Kerberos v5: krb5_auth_con_init failed");
    538 		ret = 0;
    539 		goto out;
    540 	}
    541 
    542 #ifndef HEIMDAL
    543 	problem = krb5_auth_con_setflags(*context, *auth_context,
    544 					 KRB5_AUTH_CONTEXT_RET_TIME);
    545 	if (problem) {
    546 		debug("Keberos v5: krb5_auth_con_setflags failed");
    547 		ret = 0;
    548 		goto out;
    549 	}
    550 #endif
    551 
    552 	tkfile = krb5_cc_default_name(*context);
    553 	if (strncmp(tkfile, "FILE:", 5) == 0)
    554 		tkfile += 5;
    555 
    556 	if (stat(tkfile, &buf) == 0 && getuid() != buf.st_uid) {
    557 		debug("Kerberos v5: could not get default ccache (permission denied).");
    558 		ret = 0;
    559 		goto out;
    560 	}
    561 
    562 	problem = krb5_cc_default(*context, &ccache);
    563 	if (problem) {
    564 		debug("Kerberos v5: krb5_cc_default failed: %s",
    565 		    krb5_get_err_text(*context, problem));
    566 		ret = 0;
    567 		goto out;
    568 	}
    569 
    570 	remotehost = get_canonical_hostname(1);
    571 
    572 	problem = krb5_mk_req(*context, auth_context, AP_OPTS_MUTUAL_REQUIRED,
    573 	    "host", remotehost, NULL, ccache, &ap);
    574 	if (problem) {
    575 		debug("Kerberos v5: krb5_mk_req failed: %s",
    576 		    krb5_get_err_text(*context, problem));
    577 		ret = 0;
    578 		goto out;
    579 	}
    580 
    581 	packet_start(SSH_CMSG_AUTH_KERBEROS);
    582 	packet_put_string((char *) ap.data, ap.length);
    583 	packet_send();
    584 	packet_write_wait();
    585 
    586 	xfree(ap.data);
    587 	ap.length = 0;
    588 
    589 	type = packet_read();
    590 	switch (type) {
    591 	case SSH_SMSG_FAILURE:
    592 		/* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */
    593 		debug("Kerberos v5 authentication failed.");
    594 		ret = 0;
    595 		break;
    596 
    597 	case SSH_SMSG_AUTH_KERBEROS_RESPONSE:
    598 		/* SSH_SMSG_AUTH_KERBEROS_SUCCESS */
    599 		debug("Kerberos v5 authentication accepted.");
    600 
    601 		/* Get server's response. */
    602 		ap.data = packet_get_string((unsigned int *) &ap.length);
    603 		packet_check_eom();
    604 		/* XXX je to dobre? */
    605 
    606 		problem = krb5_rd_rep(*context, *auth_context, &ap, &reply);
    607 		if (problem) {
    608 			ret = 0;
    609 		}
    610 		ret = 1;
    611 		break;
    612 
    613 	default:
    614 		packet_disconnect("Protocol error on Kerberos v5 response: %d",
    615 		    type);
    616 		ret = 0;
    617 		break;
    618 
    619 	}
    620 
    621  out:
    622 	if (ccache != NULL)
    623 		krb5_cc_close(*context, ccache);
    624 	if (reply != NULL)
    625 		krb5_free_ap_rep_enc_part(*context, reply);
    626 	if (ap.length > 0)
    627 #ifdef HEIMDAL
    628 		krb5_data_free(&ap);
    629 #else
    630 		krb5_free_data_contents(*context, &ap);
    631 #endif
    632 
    633 	return (ret);
    634 }
    635 
    636 static void
    637 send_krb5_tgt(krb5_context context, krb5_auth_context auth_context)
    638 {
    639 	int fd, type;
    640 	krb5_error_code problem;
    641 	krb5_data outbuf;
    642 	krb5_ccache ccache = NULL;
    643 	krb5_creds creds;
    644 #ifdef HEIMDAL
    645 	krb5_kdc_flags flags;
    646 #else
    647 	int forwardable;
    648 #endif
    649 	const char *remotehost;
    650 
    651 	memset(&creds, 0, sizeof(creds));
    652 	memset(&outbuf, 0, sizeof(outbuf));
    653 
    654 	fd = packet_get_connection_in();
    655 
    656 #ifdef HEIMDAL
    657 	problem = krb5_auth_con_setaddrs_from_fd(context, auth_context, &fd);
    658 #else
    659 	problem = krb5_auth_con_genaddrs(context, auth_context, fd,
    660 			KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR |
    661 			KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR);
    662 #endif
    663 	if (problem)
    664 		goto out;
    665 
    666 	problem = krb5_cc_default(context, &ccache);
    667 	if (problem)
    668 		goto out;
    669 
    670 	problem = krb5_cc_get_principal(context, ccache, &creds.client);
    671 	if (problem)
    672 		goto out;
    673 
    674 	remotehost = get_canonical_hostname(1);
    675 
    676 #ifdef HEIMDAL
    677 	problem = krb5_build_principal(context, &creds.server,
    678 	    strlen(creds.client->realm), creds.client->realm,
    679 	    "krbtgt", creds.client->realm, NULL);
    680 #else
    681 	problem = krb5_build_principal(context, &creds.server,
    682 	    creds.client->realm.length, creds.client->realm.data,
    683 	    "host", remotehost, NULL);
    684 #endif
    685 	if (problem)
    686 		goto out;
    687 
    688 	creds.times.endtime = 0;
    689 
    690 #ifdef HEIMDAL
    691 	flags.i = 0;
    692 	flags.b.forwarded = 1;
    693 	flags.b.forwardable = krb5_config_get_bool(context,  NULL,
    694 	    "libdefaults", "forwardable", NULL);
    695 	problem = krb5_get_forwarded_creds(context, auth_context,
    696 	    ccache, flags.i, remotehost, &creds, &outbuf);
    697 #else
    698 	forwardable = 1;
    699 	problem = krb5_fwd_tgt_creds(context, auth_context, remotehost,
    700 	    creds.client, creds.server, ccache, forwardable, &outbuf);
    701 #endif
    702 
    703 	if (problem)
    704 		goto out;
    705 
    706 	packet_start(SSH_CMSG_HAVE_KERBEROS_TGT);
    707 	packet_put_string((char *)outbuf.data, outbuf.length);
    708 	packet_send();
    709 	packet_write_wait();
    710 
    711 	type = packet_read();
    712 
    713 	if (type == SSH_SMSG_SUCCESS) {
    714 		char *pname;
    715 
    716 		krb5_unparse_name(context, creds.client, &pname);
    717 		debug("Kerberos v5 TGT forwarded (%s).", pname);
    718 		xfree(pname);
    719 	} else
    720 		debug("Kerberos v5 TGT forwarding failed.");
    721 
    722 	return;
    723 
    724  out:
    725 	if (problem)
    726 		debug("Kerberos v5 TGT forwarding failed: %s",
    727 		    krb5_get_err_text(context, problem));
    728 	if (creds.client)
    729 		krb5_free_principal(context, creds.client);
    730 	if (creds.server)
    731 		krb5_free_principal(context, creds.server);
    732 	if (ccache)
    733 		krb5_cc_close(context, ccache);
    734 	if (outbuf.data)
    735 		xfree(outbuf.data);
    736 }
    737 #endif /* KRB5 */
    738 
    739 #ifdef AFS
    740 static void
    741 send_krb4_tgt(void)
    742 {
    743 	CREDENTIALS *creds;
    744 	struct stat st;
    745 	char buffer[4096], pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ];
    746 	int problem, type;
    747 
    748 	/* Don't do anything if we don't have any tickets. */
    749 	if (stat(tkt_string(), &st) < 0)
    750 		return;
    751 
    752 	creds = xmalloc(sizeof(*creds));
    753 
    754 	problem = krb_get_tf_fullname(TKT_FILE, pname, pinst, prealm);
    755 	if (problem)
    756 		goto out;
    757 
    758 	problem = krb_get_cred("krbtgt", prealm, prealm, creds);
    759 	if (problem)
    760 		goto out;
    761 
    762 	if (time(0) > krb_life_to_time(creds->issue_date, creds->lifetime)) {
    763 		problem = RD_AP_EXP;
    764 		goto out;
    765 	}
    766 	creds_to_radix(creds, (u_char *)buffer, sizeof(buffer));
    767 
    768 	packet_start(SSH_CMSG_HAVE_KERBEROS_TGT);
    769 	packet_put_cstring(buffer);
    770 	packet_send();
    771 	packet_write_wait();
    772 
    773 	type = packet_read();
    774 
    775 	if (type == SSH_SMSG_SUCCESS)
    776 		debug("Kerberos v4 TGT forwarded (%s%s%s@%s).",
    777 		    creds->pname, creds->pinst[0] ? "." : "",
    778 		    creds->pinst, creds->realm);
    779 	else
    780 		debug("Kerberos v4 TGT rejected.");
    781 
    782 	xfree(creds);
    783 	return;
    784 
    785  out:
    786 	debug("Kerberos v4 TGT passing failed: %s", krb_err_txt[problem]);
    787 	xfree(creds);
    788 }
    789 
    790 static void
    791 send_afs_tokens(void)
    792 {
    793 	CREDENTIALS creds;
    794 	struct ViceIoctl parms;
    795 	struct ClearToken ct;
    796 	int i, type, len;
    797 	char buf[2048], *p, *server_cell;
    798 	char buffer[8192];
    799 
    800 	/* Move over ktc_GetToken, here's something leaner. */
    801 	for (i = 0; i < 100; i++) {	/* just in case */
    802 		parms.in = (char *) &i;
    803 		parms.in_size = sizeof(i);
    804 		parms.out = buf;
    805 		parms.out_size = sizeof(buf);
    806 		if (k_pioctl(0, VIOCGETTOK, &parms, 0) != 0)
    807 			break;
    808 		p = buf;
    809 
    810 		/* Get secret token. */
    811 		memcpy(&creds.ticket_st.length, p, sizeof(u_int));
    812 		if (creds.ticket_st.length > MAX_KTXT_LEN)
    813 			break;
    814 		p += sizeof(u_int);
    815 		memcpy(creds.ticket_st.dat, p, creds.ticket_st.length);
    816 		p += creds.ticket_st.length;
    817 
    818 		/* Get clear token. */
    819 		memcpy(&len, p, sizeof(len));
    820 		if (len != sizeof(struct ClearToken))
    821 			break;
    822 		p += sizeof(len);
    823 		memcpy(&ct, p, len);
    824 		p += len;
    825 		p += sizeof(len);	/* primary flag */
    826 		server_cell = p;
    827 
    828 		/* Flesh out our credentials. */
    829 		strlcpy(creds.service, "afs", sizeof(creds.service));
    830 		creds.instance[0] = '\0';
    831 		strlcpy(creds.realm, server_cell, REALM_SZ);
    832 		memcpy(creds.session, ct.HandShakeKey, DES_KEY_SZ);
    833 		creds.issue_date = ct.BeginTimestamp;
    834 		creds.lifetime = krb_time_to_life(creds.issue_date,
    835 		    ct.EndTimestamp);
    836 		creds.kvno = ct.AuthHandle;
    837 		snprintf(creds.pname, sizeof(creds.pname), "AFS ID %d", ct.ViceId);
    838 		creds.pinst[0] = '\0';
    839 
    840 		/* Encode token, ship it off. */
    841 		if (creds_to_radix(&creds, (u_char *)buffer,
    842 		    sizeof(buffer)) <= 0)
    843 			break;
    844 		packet_start(SSH_CMSG_HAVE_AFS_TOKEN);
    845 		packet_put_cstring(buffer);
    846 		packet_send();
    847 		packet_write_wait();
    848 
    849 		/* Roger, Roger. Clearance, Clarence. What's your vector,
    850 		   Victor? */
    851 		type = packet_read();
    852 
    853 		if (type == SSH_SMSG_FAILURE)
    854 			debug("AFS token for cell %s rejected.", server_cell);
    855 		else if (type != SSH_SMSG_SUCCESS)
    856 			packet_disconnect("Protocol error on AFS token response: %d", type);
    857 	}
    858 }
    859 
    860 #endif /* AFS */
    861 
    862 /*
    863  * Tries to authenticate with any string-based challenge/response system.
    864  * Note that the client code is not tied to s/key or TIS.
    865  */
    866 static int
    867 try_challenge_response_authentication(void)
    868 {
    869 	int type, i;
    870 	u_int clen;
    871 	char prompt[1024];
    872 	char *challenge, *response;
    873 
    874 	debug("Doing challenge response authentication.");
    875 
    876 	for (i = 0; i < options.number_of_password_prompts; i++) {
    877 		/* request a challenge */
    878 		packet_start(SSH_CMSG_AUTH_TIS);
    879 		packet_send();
    880 		packet_write_wait();
    881 
    882 		type = packet_read();
    883 		if (type != SSH_SMSG_FAILURE &&
    884 		    type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
    885 			packet_disconnect("Protocol error: got %d in response "
    886 			    "to SSH_CMSG_AUTH_TIS", type);
    887 		}
    888 		if (type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
    889 			debug("No challenge.");
    890 			return 0;
    891 		}
    892 		challenge = packet_get_string(&clen);
    893 		packet_check_eom();
    894 		snprintf(prompt, sizeof prompt, "%s%s", challenge,
    895 		    strchr(challenge, '\n') ? "" : gettext("\nResponse: "));
    896 		xfree(challenge);
    897 		if (i != 0)
    898 			error("Permission denied, please try again.");
    899 		if (options.cipher == SSH_CIPHER_NONE)
    900 			log("WARNING: Encryption is disabled! "
    901 			    "Response will be transmitted in clear text.");
    902 		response = read_passphrase(prompt, 0);
    903 		if (strcmp(response, "") == 0) {
    904 			xfree(response);
    905 			break;
    906 		}
    907 		packet_start(SSH_CMSG_AUTH_TIS_RESPONSE);
    908 		ssh_put_password(response);
    909 		memset(response, 0, strlen(response));
    910 		xfree(response);
    911 		packet_send();
    912 		packet_write_wait();
    913 		type = packet_read();
    914 		if (type == SSH_SMSG_SUCCESS)
    915 			return 1;
    916 		if (type != SSH_SMSG_FAILURE)
    917 			packet_disconnect("Protocol error: got %d in response "
    918 			    "to SSH_CMSG_AUTH_TIS_RESPONSE", type);
    919 	}
    920 	/* failure */
    921 	return 0;
    922 }
    923 
    924 /*
    925  * Tries to authenticate with plain passwd authentication.
    926  */
    927 static int
    928 try_password_authentication(char *prompt)
    929 {
    930 	int type, i;
    931 	char *password;
    932 
    933 	debug("Doing password authentication.");
    934 	if (options.cipher == SSH_CIPHER_NONE)
    935 		log("WARNING: Encryption is disabled! Password will be transmitted in clear text.");
    936 	for (i = 0; i < options.number_of_password_prompts; i++) {
    937 		if (i != 0)
    938 			error("Permission denied, please try again.");
    939 		password = read_passphrase(prompt, 0);
    940 		packet_start(SSH_CMSG_AUTH_PASSWORD);
    941 		ssh_put_password(password);
    942 		memset(password, 0, strlen(password));
    943 		xfree(password);
    944 		packet_send();
    945 		packet_write_wait();
    946 
    947 		type = packet_read();
    948 		if (type == SSH_SMSG_SUCCESS)
    949 			return 1;
    950 		if (type != SSH_SMSG_FAILURE)
    951 			packet_disconnect("Protocol error: got %d in response to passwd auth", type);
    952 	}
    953 	/* failure */
    954 	return 0;
    955 }
    956 
    957 /*
    958  * SSH1 key exchange
    959  */
    960 void
    961 ssh_kex(char *host, struct sockaddr *hostaddr)
    962 {
    963 	int i;
    964 	BIGNUM *key;
    965 	Key *host_key, *server_key;
    966 	int bits, rbits;
    967 	int ssh_cipher_default = SSH_CIPHER_3DES;
    968 	u_char session_key[SSH_SESSION_KEY_LENGTH];
    969 	u_char cookie[8];
    970 	u_int supported_ciphers;
    971 	u_int server_flags, client_flags;
    972 	u_int32_t rand = 0;
    973 
    974 	debug("Waiting for server public key.");
    975 
    976 	/* Wait for a public key packet from the server. */
    977 	packet_read_expect(SSH_SMSG_PUBLIC_KEY);
    978 
    979 	/* Get cookie from the packet. */
    980 	for (i = 0; i < 8; i++)
    981 		cookie[i] = packet_get_char();
    982 
    983 	/* Get the public key. */
    984 	server_key = key_new(KEY_RSA1);
    985 	bits = packet_get_int();
    986 	packet_get_bignum(server_key->rsa->e);
    987 	packet_get_bignum(server_key->rsa->n);
    988 
    989 	rbits = BN_num_bits(server_key->rsa->n);
    990 	if (bits != rbits) {
    991 		log("Warning: Server lies about size of server public key: "
    992 		    "actual size is %d bits vs. announced %d.", rbits, bits);
    993 		log("Warning: This may be due to an old implementation of ssh.");
    994 	}
    995 	/* Get the host key. */
    996 	host_key = key_new(KEY_RSA1);
    997 	bits = packet_get_int();
    998 	packet_get_bignum(host_key->rsa->e);
    999 	packet_get_bignum(host_key->rsa->n);
   1000 
   1001 	rbits = BN_num_bits(host_key->rsa->n);
   1002 	if (bits != rbits) {
   1003 		log("Warning: Server lies about size of server host key: "
   1004 		    "actual size is %d bits vs. announced %d.", rbits, bits);
   1005 		log("Warning: This may be due to an old implementation of ssh.");
   1006 	}
   1007 
   1008 	/* Get protocol flags. */
   1009 	server_flags = packet_get_int();
   1010 	packet_set_protocol_flags(server_flags);
   1011 
   1012 	supported_ciphers = packet_get_int();
   1013 	supported_authentications = packet_get_int();
   1014 	packet_check_eom();
   1015 
   1016 	debug("Received server public key (%d bits) and host key (%d bits).",
   1017 	    BN_num_bits(server_key->rsa->n), BN_num_bits(host_key->rsa->n));
   1018 
   1019 	if (verify_host_key(host, hostaddr, host_key) == -1)
   1020 		fatal("Host key verification failed.");
   1021 
   1022 	client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN;
   1023 
   1024 	compute_session_id(session_id, cookie, host_key->rsa->n, server_key->rsa->n);
   1025 
   1026 	/* Generate a session key. */
   1027 	arc4random_stir();
   1028 
   1029 	/*
   1030 	 * Generate an encryption key for the session.   The key is a 256 bit
   1031 	 * random number, interpreted as a 32-byte key, with the least
   1032 	 * significant 8 bits being the first byte of the key.
   1033 	 */
   1034 	for (i = 0; i < 32; i++) {
   1035 		if (i % 4 == 0)
   1036 			rand = arc4random();
   1037 		session_key[i] = rand & 0xff;
   1038 		rand >>= 8;
   1039 	}
   1040 
   1041 	/*
   1042 	 * According to the protocol spec, the first byte of the session key
   1043 	 * is the highest byte of the integer.  The session key is xored with
   1044 	 * the first 16 bytes of the session id.
   1045 	 */
   1046 	if ((key = BN_new()) == NULL)
   1047 		fatal("respond_to_rsa_challenge: BN_new failed");
   1048 	BN_set_word(key, 0);
   1049 	for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) {
   1050 		BN_lshift(key, key, 8);
   1051 		if (i < 16)
   1052 			BN_add_word(key, session_key[i] ^ session_id[i]);
   1053 		else
   1054 			BN_add_word(key, session_key[i]);
   1055 	}
   1056 
   1057 	/*
   1058 	 * Encrypt the integer using the public key and host key of the
   1059 	 * server (key with smaller modulus first).
   1060 	 */
   1061 	if (BN_cmp(