11305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* $OpenBSD: sshconnect1.c,v 1.70 2006/11/06 21:25:28 markus Exp $ */
21305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
31305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Author: Tatu Ylonen <ylo@cs.hut.fi>
41305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
51305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *                    All rights reserved
61305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Code to connect to a remote host, and to perform the client side of the
71305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * login (authentication) dialog.
81305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *
91305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * As far as I am concerned, the code I have written for this software
101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * can be used freely for any purpose.  Any derived versions of this
111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * software must be clearly marked as such, and if the derived work is
121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * incompatible with the protocol description in the RFC file, it must be
131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * called by a name other than "ssh" or "Secure Shell".
141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "includes.h"
171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/types.h>
191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/socket.h>
201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <openssl/bn.h>
221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <openssl/md5.h>
231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdarg.h>
251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdio.h>
261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdlib.h>
271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <string.h>
281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <signal.h>
291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <pwd.h>
301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "xmalloc.h"
321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "ssh.h"
331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "ssh1.h"
341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "rsa.h"
351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "buffer.h"
361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "packet.h"
371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "key.h"
381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "cipher.h"
391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "kex.h"
401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "uidswap.h"
411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "log.h"
421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "readconf.h"
431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "authfd.h"
441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "sshconnect.h"
451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "authfile.h"
461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "misc.h"
471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "canohost.h"
481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "hostfile.h"
491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "auth.h"
501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Session id for the current session. */
521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodu_char session_id[16];
531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodu_int supported_authentications = 0;
541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodextern Options options;
561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodextern char *__progname;
571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Checks if the user has an authentication agent, and if so, tries to
601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * authenticate using the agent.
611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int
631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodtry_agent_authentication(void)
641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int type;
661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	char *comment;
671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	AuthenticationConnection *auth;
681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_char response[16];
691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_int i;
701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Key *key;
711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	BIGNUM *challenge;
721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Get connection to the agent. */
741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	auth = ssh_get_authentication_connection();
751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (!auth)
761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return 0;
771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if ((challenge = BN_new()) == NULL)
791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		fatal("try_agent_authentication: BN_new failed");
801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Loop through identities served by the agent. */
811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	for (key = ssh_get_first_identity(auth, &comment, 1);
821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    key != NULL;
831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    key = ssh_get_next_identity(auth, &comment, 1)) {
841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Try this identity. */
861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		debug("Trying RSA authentication via agent with '%.100s'", comment);
871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		xfree(comment);
881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Tell the server that we are willing to authenticate using this key. */
901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_start(SSH_CMSG_AUTH_RSA);
911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_put_bignum(key->rsa->n);
921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_send();
931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_write_wait();
941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Wait for server's response. */
961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		type = packet_read();
971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* The server sends failure if it doesn't like our key or
991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		   does not support RSA authentication. */
1001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (type == SSH_SMSG_FAILURE) {
1011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			debug("Server refused our key.");
1021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			key_free(key);
1031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			continue;
1041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
1051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Otherwise it should have sent a challenge. */
1061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (type != SSH_SMSG_AUTH_RSA_CHALLENGE)
1071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			packet_disconnect("Protocol error during RSA authentication: %d",
1081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					  type);
1091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_get_bignum(challenge);
1111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_check_eom();
1121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		debug("Received RSA challenge from server.");
1141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Ask the agent to decrypt the challenge. */
1161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (!ssh_decrypt_challenge(auth, key, challenge, session_id, 1, response)) {
1171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			/*
1181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			 * The agent failed to authenticate this identifier
1191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			 * although it advertised it supports this.  Just
1201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			 * return a wrong value.
1211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			 */
1221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			logit("Authentication agent failed to decrypt challenge.");
1231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			memset(response, 0, sizeof(response));
1241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
1251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		key_free(key);
1261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		debug("Sending response to RSA challenge.");
1271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Send the decrypted challenge back to the server. */
1291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_start(SSH_CMSG_AUTH_RSA_RESPONSE);
1301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		for (i = 0; i < 16; i++)
1311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			packet_put_char(response[i]);
1321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_send();
1331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_write_wait();
1341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Wait for response from the server. */
1361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		type = packet_read();
1371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* The server returns success if it accepted the authentication. */
1391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (type == SSH_SMSG_SUCCESS) {
1401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			ssh_close_authentication_connection(auth);
1411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			BN_clear_free(challenge);
1421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			debug("RSA authentication accepted by server.");
1431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			return 1;
1441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
1451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Otherwise it should return failure. */
1461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (type != SSH_SMSG_FAILURE)
1471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			packet_disconnect("Protocol error waiting RSA auth response: %d",
1481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					  type);
1491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
1501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	ssh_close_authentication_connection(auth);
1511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	BN_clear_free(challenge);
1521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	debug("RSA authentication using agent refused.");
1531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return 0;
1541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
1551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
1571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Computes the proper response to a RSA challenge, and sends the response to
1581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * the server.
1591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
1601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void
1611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodrespond_to_rsa_challenge(BIGNUM * challenge, RSA * prv)
1621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
1631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_char buf[32], response[16];
1641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	MD5_CTX md;
1651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int i, len;
1661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Decrypt the challenge using the private key. */
1681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* XXX think about Bleichenbacher, too */
1691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (rsa_private_decrypt(challenge, challenge, prv) <= 0)
1701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_disconnect(
1711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    "respond_to_rsa_challenge: rsa_private_decrypt failed");
1721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Compute the response. */
1741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* The response is MD5 of decrypted challenge plus session id. */
1751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	len = BN_num_bytes(challenge);
1761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (len <= 0 || (u_int)len > sizeof(buf))
1771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_disconnect(
1781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    "respond_to_rsa_challenge: bad challenge length %d", len);
1791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	memset(buf, 0, sizeof(buf));
1811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	BN_bn2bin(challenge, buf + sizeof(buf) - len);
1821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	MD5_Init(&md);
1831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	MD5_Update(&md, buf, 32);
1841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	MD5_Update(&md, session_id, 16);
1851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	MD5_Final(response, &md);
1861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	debug("Sending response to host key RSA challenge.");
1881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Send the response back to the server. */
1901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_start(SSH_CMSG_AUTH_RSA_RESPONSE);
1911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	for (i = 0; i < 16; i++)
1921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_put_char(response[i]);
1931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_send();
1941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_write_wait();
1951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	memset(buf, 0, sizeof(buf));
1971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	memset(response, 0, sizeof(response));
1981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	memset(&md, 0, sizeof(md));
1991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
2001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
2021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Checks if the user has authentication file, and if so, tries to authenticate
2031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * the user using it.
2041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
2051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int
2061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodtry_rsa_authentication(int idx)
2071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
2081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	BIGNUM *challenge;
2091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Key *public, *private;
2101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	char buf[300], *passphrase, *comment, *authfile;
2111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int i, perm_ok = 1, type, quit;
2121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	public = options.identity_keys[idx];
2141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	authfile = options.identity_files[idx];
2151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	comment = xstrdup(authfile);
2161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	debug("Trying RSA authentication with key '%.100s'", comment);
2181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Tell the server that we are willing to authenticate using this key. */
2201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_start(SSH_CMSG_AUTH_RSA);
2211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_put_bignum(public->rsa->n);
2221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_send();
2231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_write_wait();
2241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Wait for server's response. */
2261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	type = packet_read();
2271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
2291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * The server responds with failure if it doesn't like our key or
2301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * doesn't support RSA authentication.
2311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
2321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (type == SSH_SMSG_FAILURE) {
2331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		debug("Server refused our key.");
2341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		xfree(comment);
2351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return 0;
2361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
2371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Otherwise, the server should respond with a challenge. */
2381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (type != SSH_SMSG_AUTH_RSA_CHALLENGE)
2391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_disconnect("Protocol error during RSA authentication: %d", type);
2401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Get the challenge from the packet. */
2421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if ((challenge = BN_new()) == NULL)
2431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		fatal("try_rsa_authentication: BN_new failed");
2441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_get_bignum(challenge);
2451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_check_eom();
2461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	debug("Received RSA challenge from server.");
2481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
2501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * If the key is not stored in external hardware, we have to
2511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * load the private key.  Try first with empty passphrase; if it
2521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * fails, ask for a passphrase.
2531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
2541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (public->flags & KEY_FLAG_EXT)
2551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		private = public;
2561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	else
2571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		private = key_load_private_type(KEY_RSA1, authfile, "", NULL,
2581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    &perm_ok);
2591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (private == NULL && !options.batch_mode && perm_ok) {
2601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		snprintf(buf, sizeof(buf),
2611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    "Enter passphrase for RSA key '%.100s': ", comment);
2621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		for (i = 0; i < options.number_of_password_prompts; i++) {
2631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			passphrase = read_passphrase(buf, 0);
2641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (strcmp(passphrase, "") != 0) {
2651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				private = key_load_private_type(KEY_RSA1,
2661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				    authfile, passphrase, NULL, NULL);
2671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				quit = 0;
2681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			} else {
2691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				debug2("no passphrase given, try next key");
2701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				quit = 1;
2711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			}
2721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			memset(passphrase, 0, strlen(passphrase));
2731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			xfree(passphrase);
2741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (private != NULL || quit)
2751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				break;
2761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			debug2("bad passphrase given, try again...");
2771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
2781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
2791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* We no longer need the comment. */
2801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	xfree(comment);
2811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (private == NULL) {
2831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (!options.batch_mode && perm_ok)
2841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			error("Bad passphrase.");
2851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Send a dummy response packet to avoid protocol error. */
2871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_start(SSH_CMSG_AUTH_RSA_RESPONSE);
2881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		for (i = 0; i < 16; i++)
2891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			packet_put_char(0);
2901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_send();
2911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_write_wait();
2921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Expect the server to reject it... */
2941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_read_expect(SSH_SMSG_FAILURE);
2951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		BN_clear_free(challenge);
2961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return 0;
2971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
2981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Compute and send a response to the challenge. */
3001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	respond_to_rsa_challenge(challenge, private->rsa);
3011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Destroy the private key unless it in external hardware. */
3031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (!(private->flags & KEY_FLAG_EXT))
3041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		key_free(private);
3051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* We no longer need the challenge. */
3071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	BN_clear_free(challenge);
3081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Wait for response from the server. */
3101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	type = packet_read();
3111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (type == SSH_SMSG_SUCCESS) {
3121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		debug("RSA authentication accepted by server.");
3131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return 1;
3141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
3151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (type != SSH_SMSG_FAILURE)
3161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_disconnect("Protocol error waiting RSA auth response: %d", type);
3171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	debug("RSA authentication refused.");
3181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return 0;
3191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
3201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
3221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Tries to authenticate the user using combined rhosts or /etc/hosts.equiv
3231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * authentication and RSA host authentication.
3241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
3251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int
3261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodtry_rhosts_rsa_authentication(const char *local_user, Key * host_key)
3271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
3281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int type;
3291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	BIGNUM *challenge;
3301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	debug("Trying rhosts or /etc/hosts.equiv with RSA host authentication.");
3321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Tell the server that we are willing to authenticate using this key. */
3341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_start(SSH_CMSG_AUTH_RHOSTS_RSA);
3351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_put_cstring(local_user);
3361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_put_int(BN_num_bits(host_key->rsa->n));
3371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_put_bignum(host_key->rsa->e);
3381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_put_bignum(host_key->rsa->n);
3391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_send();
3401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_write_wait();
3411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Wait for server's response. */
3431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	type = packet_read();
3441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* The server responds with failure if it doesn't admit our
3461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	   .rhosts authentication or doesn't know our host key. */
3471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (type == SSH_SMSG_FAILURE) {
3481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		debug("Server refused our rhosts authentication or host key.");
3491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return 0;
3501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
3511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Otherwise, the server should respond with a challenge. */
3521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (type != SSH_SMSG_AUTH_RSA_CHALLENGE)
3531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_disconnect("Protocol error during RSA authentication: %d", type);
3541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Get the challenge from the packet. */
3561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if ((challenge = BN_new()) == NULL)
3571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		fatal("try_rhosts_rsa_authentication: BN_new failed");
3581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_get_bignum(challenge);
3591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_check_eom();
3601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	debug("Received RSA challenge for host key from server.");
3621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Compute a response to the challenge. */
3641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	respond_to_rsa_challenge(challenge, host_key->rsa);
3651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* We no longer need the challenge. */
3671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	BN_clear_free(challenge);
3681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Wait for response from the server. */
3701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	type = packet_read();
3711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (type == SSH_SMSG_SUCCESS) {
3721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		debug("Rhosts or /etc/hosts.equiv with RSA host authentication accepted by server.");
3731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return 1;
3741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
3751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (type != SSH_SMSG_FAILURE)
3761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_disconnect("Protocol error waiting RSA auth response: %d", type);
3771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	debug("Rhosts or /etc/hosts.equiv with RSA host authentication refused.");
3781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return 0;
3791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
3801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
3821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Tries to authenticate with any string-based challenge/response system.
3831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Note that the client code is not tied to s/key or TIS.
3841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
3851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int
3861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodtry_challenge_response_authentication(void)
3871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
3881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int type, i;
3891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_int clen;
3901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	char prompt[1024];
3911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	char *challenge, *response;
3921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	debug("Doing challenge response authentication.");
3941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	for (i = 0; i < options.number_of_password_prompts; i++) {
3961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* request a challenge */
3971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_start(SSH_CMSG_AUTH_TIS);
3981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_send();
3991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_write_wait();
4001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
4011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		type = packet_read();
4021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (type != SSH_SMSG_FAILURE &&
4031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
4041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			packet_disconnect("Protocol error: got %d in response "
4051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    "to SSH_CMSG_AUTH_TIS", type);
4061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
4071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
4081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			debug("No challenge.");
4091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			return 0;
4101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
4111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		challenge = packet_get_string(&clen);
4121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_check_eom();
4131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		snprintf(prompt, sizeof prompt, "%s%s", challenge,
4141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    strchr(challenge, '\n') ? "" : "\nResponse: ");
4151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		xfree(challenge);
4161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (i != 0)
4171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			error("Permission denied, please try again.");
4181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (options.cipher == SSH_CIPHER_NONE)
4191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			logit("WARNING: Encryption is disabled! "
4201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    "Response will be transmitted in clear text.");
4211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		response = read_passphrase(prompt, 0);
4221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (strcmp(response, "") == 0) {
4231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			xfree(response);
4241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
4251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
4261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_start(SSH_CMSG_AUTH_TIS_RESPONSE);
4271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		ssh_put_password(response);
4281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		memset(response, 0, strlen(response));
4291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		xfree(response);
4301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_send();
4311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_write_wait();
4321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		type = packet_read();
4331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (type == SSH_SMSG_SUCCESS)
4341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			return 1;
4351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (type != SSH_SMSG_FAILURE)
4361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			packet_disconnect("Protocol error: got %d in response "
4371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    "to SSH_CMSG_AUTH_TIS_RESPONSE", type);
4381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
4391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* failure */
4401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return 0;
4411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
4421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
4431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
4441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Tries to authenticate with plain passwd authentication.
4451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
4461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int
4471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodtry_password_authentication(char *prompt)
4481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
4491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int type, i;
4501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	char *password;
4511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
4521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	debug("Doing password authentication.");
4531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (options.cipher == SSH_CIPHER_NONE)
4541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		logit("WARNING: Encryption is disabled! Password will be transmitted in clear text.");
4551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	for (i = 0; i < options.number_of_password_prompts; i++) {
4561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (i != 0)
4571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			error("Permission denied, please try again.");
4581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		password = read_passphrase(prompt, 0);
4591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_start(SSH_CMSG_AUTH_PASSWORD);
4601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		ssh_put_password(password);
4611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		memset(password, 0, strlen(password));
4621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		xfree(password);
4631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_send();
4641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_write_wait();
4651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
4661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		type = packet_read();
4671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (type == SSH_SMSG_SUCCESS)
4681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			return 1;
4691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (type != SSH_SMSG_FAILURE)
4701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			packet_disconnect("Protocol error: got %d in response to passwd auth", type);
4711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
4721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* failure */
4731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return 0;
4741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
4751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
4761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
4771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * SSH1 key exchange
4781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
4791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
4801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodssh_kex(char *host, struct sockaddr *hostaddr)
4811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
4821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int i;
4831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	BIGNUM *key;
4841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Key *host_key, *server_key;
4851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int bits, rbits;
4861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int ssh_cipher_default = SSH_CIPHER_3DES;
4871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_char session_key[SSH_SESSION_KEY_LENGTH];
4881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_char cookie[8];
4891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_int supported_ciphers;
4901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_int server_flags, client_flags;
4911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_int32_t rnd = 0;
4921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
4931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	debug("Waiting for server public key.");
4941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
4951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Wait for a public key packet from the server. */
4961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_read_expect(SSH_SMSG_PUBLIC_KEY);
4971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
4981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Get cookie from the packet. */
4991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	for (i = 0; i < 8; i++)
5001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		cookie[i] = packet_get_char();
5011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Get the public key. */
5031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	server_key = key_new(KEY_RSA1);
5041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	bits = packet_get_int();
5051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_get_bignum(server_key->rsa->e);
5061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_get_bignum(server_key->rsa->n);
5071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	rbits = BN_num_bits(server_key->rsa->n);
5091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (bits != rbits) {
5101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		logit("Warning: Server lies about size of server public key: "
5111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    "actual size is %d bits vs. announced %d.", rbits, bits);
5121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		logit("Warning: This may be due to an old implementation of ssh.");
5131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
5141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Get the host key. */
5151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	host_key = key_new(KEY_RSA1);
5161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	bits = packet_get_int();
5171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_get_bignum(host_key->rsa->e);
5181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_get_bignum(host_key->rsa->n);
5191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	rbits = BN_num_bits(host_key->rsa->n);
5211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (bits != rbits) {
5221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		logit("Warning: Server lies about size of server host key: "
5231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    "actual size is %d bits vs. announced %d.", rbits, bits);
5241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		logit("Warning: This may be due to an old implementation of ssh.");
5251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
5261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Get protocol flags. */
5281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	server_flags = packet_get_int();
5291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_set_protocol_flags(server_flags);
5301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	supported_ciphers = packet_get_int();
5321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	supported_authentications = packet_get_int();
5331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_check_eom();
5341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	debug("Received server public key (%d bits) and host key (%d bits).",
5361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    BN_num_bits(server_key->rsa->n), BN_num_bits(host_key->rsa->n));
5371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (verify_host_key(host, hostaddr, host_key) == -1)
5391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		fatal("Host key verification failed.");
5401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN;
5421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	derive_ssh1_session_id(host_key->rsa->n, server_key->rsa->n, cookie, session_id);
5441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Generate a session key. */
5461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	arc4random_stir();
5471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
5491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * Generate an encryption key for the session.   The key is a 256 bit
5501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * random number, interpreted as a 32-byte key, with the least
5511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * significant 8 bits being the first byte of the key.
5521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
5531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	for (i = 0; i < 32; i++) {
5541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (i % 4 == 0)
5551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			rnd = arc4random();
5561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		session_key[i] = rnd & 0xff;
5571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		rnd >>= 8;
5581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
5591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
5611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * According to the protocol spec, the first byte of the session key
5621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * is the highest byte of the integer.  The session key is xored with
5631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * the first 16 bytes of the session id.
5641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
5651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if ((key = BN_new()) == NULL)
5661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		fatal("ssh_kex: BN_new failed");
5671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (BN_set_word(key, 0) == 0)
5681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		fatal("ssh_kex: BN_set_word failed");
5691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) {
5701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (BN_lshift(key, key, 8) == 0)
5711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			fatal("ssh_kex: BN_lshift failed");
5721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (i < 16) {
5731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (BN_add_word(key, session_key[i] ^ session_id[i])
5741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    == 0)
5751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				fatal("ssh_kex: BN_add_word failed");
5761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		} else {
5771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (BN_add_word(key, session_key[i]) == 0)
5781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				fatal("ssh_kex: BN_add_word failed");
5791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
5801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
5811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
5831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * Encrypt the integer using the public key and host key of the
5841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * server (key with smaller modulus first).
5851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
5861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (BN_cmp(server_key->rsa->n, host_key->rsa->n) < 0) {
5871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Public key has smaller modulus. */
5881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (BN_num_bits(host_key->rsa->n) <
5891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    BN_num_bits(server_key->rsa->n) + SSH_KEY_BITS_RESERVED) {
5901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			fatal("respond_to_rsa_challenge: host_key %d < server_key %d + "
5911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    "SSH_KEY_BITS_RESERVED %d",
5921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    BN_num_bits(host_key->rsa->n),
5931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    BN_num_bits(server_key->rsa->n),
5941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    SSH_KEY_BITS_RESERVED);
5951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
5961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		rsa_public_encrypt(key, key, server_key->rsa);
5971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		rsa_public_encrypt(key, key, host_key->rsa);
5981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	} else {
5991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Host key has smaller modulus (or they are equal). */
6001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (BN_num_bits(server_key->rsa->n) <
6011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    BN_num_bits(host_key->rsa->n) + SSH_KEY_BITS_RESERVED) {
6021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			fatal("respond_to_rsa_challenge: server_key %d < host_key %d + "
6031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    "SSH_KEY_BITS_RESERVED %d",
6041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    BN_num_bits(server_key->rsa->n),
6051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    BN_num_bits(host_key->rsa->n),
6061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    SSH_KEY_BITS_RESERVED);
6071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
6081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		rsa_public_encrypt(key, key, host_key->rsa);
6091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		rsa_public_encrypt(key, key, server_key->rsa);
6101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
6111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Destroy the public keys since we no longer need them. */
6131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	key_free(server_key);
6141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	key_free(host_key);
6151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (options.cipher == SSH_CIPHER_NOT_SET) {
6171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (cipher_mask_ssh1(1) & supported_ciphers & (1 << ssh_cipher_default))
6181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			options.cipher = ssh_cipher_default;
6191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	} else if (options.cipher == SSH_CIPHER_INVALID ||
6201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    !(cipher_mask_ssh1(1) & (1 << options.cipher))) {
6211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		logit("No valid SSH1 cipher, using %.100s instead.",
6221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    cipher_name(ssh_cipher_default));
6231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		options.cipher = ssh_cipher_default;
6241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
6251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Check that the selected cipher is supported. */
6261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (!(supported_ciphers & (1 << options.cipher)))
6271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		fatal("Selected cipher type %.100s not supported by server.",
6281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    cipher_name(options.cipher));
6291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	debug("Encryption type: %.100s", cipher_name(options.cipher));
6311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Send the encrypted session key to the server. */
6331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_start(SSH_CMSG_SESSION_KEY);
6341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_put_char(options.cipher);
6351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Send the cookie back to the server. */
6371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	for (i = 0; i < 8; i++)
6381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_put_char(cookie[i]);
6391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Send and destroy the encrypted encryption key integer. */
6411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_put_bignum(key);
6421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	BN_clear_free(key);
6431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Send protocol flags. */
6451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_put_int(client_flags);
6461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Send the packet now. */
6481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_send();
6491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_write_wait();
6501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	debug("Sent encrypted session key.");
6521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Set the encryption key. */
6541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, options.cipher);
6551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* We will no longer need the session key here.  Destroy any extra copies. */
6571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	memset(session_key, 0, sizeof(session_key));
6581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
6601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * Expect a success message from the server.  Note that this message
6611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * will be received in encrypted form.
6621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
6631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_read_expect(SSH_SMSG_SUCCESS);
6641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	debug("Received encrypted confirmation.");
6661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
6671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
6691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Authenticate user
6701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
6711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
6721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodssh_userauth1(const char *local_user, const char *server_user, char *host,
6731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood    Sensitive *sensitive)
6741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
6751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int i, type;
6761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (supported_authentications == 0)
6781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		fatal("ssh_userauth1: server supports no auth methods");
6791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Send the name of the user to log in as on the server. */
6811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_start(SSH_CMSG_USER);
6821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_put_cstring(server_user);
6831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_send();
6841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_write_wait();
6851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
6871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * The server should respond with success if no authentication is
6881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * needed (the user has no password).  Otherwise the server responds
6891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * with failure.
6901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
6911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	type = packet_read();
6921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* check whether the connection was accepted without authentication. */
6941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (type == SSH_SMSG_SUCCESS)
6951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		goto success;
6961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (type != SSH_SMSG_FAILURE)
6971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_disconnect("Protocol error: got %d in response to SSH_CMSG_USER", type);
6981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
7001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * Try .rhosts or /etc/hosts.equiv authentication with RSA host
7011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * authentication.
7021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
7031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if ((supported_authentications & (1 << SSH_AUTH_RHOSTS_RSA)) &&
7041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    options.rhosts_rsa_authentication) {
7051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		for (i = 0; i < sensitive->nkeys; i++) {
7061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (sensitive->keys[i] != NULL &&
7071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    sensitive->keys[i]->type == KEY_RSA1 &&
7081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    try_rhosts_rsa_authentication(local_user,
7091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    sensitive->keys[i]))
7101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				goto success;
7111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
7121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
7131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Try RSA authentication if the server supports it. */
7141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if ((supported_authentications & (1 << SSH_AUTH_RSA)) &&
7151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    options.rsa_authentication) {
7161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/*
7171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		 * Try RSA authentication using the authentication agent. The
7181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		 * agent is tried first because no passphrase is needed for
7191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		 * it, whereas identity files may require passphrases.
7201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		 */
7211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (try_agent_authentication())
7221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			goto success;
7231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
7241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Try RSA authentication for each identity. */
7251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		for (i = 0; i < options.num_identity_files; i++)
7261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (options.identity_keys[i] != NULL &&
7271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    options.identity_keys[i]->type == KEY_RSA1 &&
7281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    try_rsa_authentication(i))
7291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				goto success;
7301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
7311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Try challenge response authentication if the server supports it. */
7321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if ((supported_authentications & (1 << SSH_AUTH_TIS)) &&
7331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    options.challenge_response_authentication && !options.batch_mode) {
7341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (try_challenge_response_authentication())
7351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			goto success;
7361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
7371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Try password authentication if the server supports it. */
7381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if ((supported_authentications & (1 << SSH_AUTH_PASSWORD)) &&
7391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    options.password_authentication && !options.batch_mode) {
7401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		char prompt[80];
7411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
7421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
7431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    server_user, host);
7441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (try_password_authentication(prompt))
7451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			goto success;
7461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
7471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* All authentication methods have failed.  Exit with an error message. */
7481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	fatal("Permission denied.");
7491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* NOTREACHED */
7501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
7511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success:
7521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return;	/* need statement after label */
7531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
754