- Merge big update to OpenSSH-2.0 from OpenBSD CVS
   [README.openssh2]
   - interop w/ F-secure windows client
   - sync documentation
   - ssh_host_dsa_key not ssh_dsa_key
   [auth-rsa.c]
   - missing fclose
   [auth.c authfile.c compat.c dsa.c dsa.h hostfile.c key.c key.h radix.c]
   [readconf.c readconf.h ssh-add.c ssh-keygen.c ssh.c ssh.h sshconnect.c]
   [sshd.c uuencode.c uuencode.h authfile.h]
   - add DSA pubkey auth and other SSH2 fixes.  use ssh-keygen -[xX]
     for trading keys with the real and the original SSH, directly from the
     people who invented the SSH protocol.
   [auth.c auth.h authfile.c sshconnect.c auth1.c auth2.c sshconnect.h]
   [sshconnect1.c sshconnect2.c]
   - split auth/sshconnect in one file per protocol version
   [sshconnect2.c]
   - remove debug
   [uuencode.c]
   - add trailing =
   [version.h]
   - OpenSSH-2.0
   [ssh-keygen.1 ssh-keygen.c]
   - add -R flag: exit code indicates if RSA is alive
   [sshd.c]
   - remove unused
     silent if -Q is specified
   [ssh.h]
   - host key becomes /etc/ssh_host_dsa_key
   [readconf.c servconf.c ]
   - ssh/sshd default to proto 1 and 2
   [uuencode.c]
   - remove debug
   [auth2.c ssh-keygen.c sshconnect2.c sshd.c]
   - xfree DSA blobs
   [auth2.c serverloop.c session.c]
   - cleanup logging for sshd/2, respect PasswordAuth no
   [sshconnect2.c]
   - less debug, respect .ssh/config
   [README.openssh2 channels.c channels.h]
   - clientloop.c session.c ssh.c
   - support for x11-fwding, client+server
diff --git a/sshconnect.c b/sshconnect.c
index f58289e..5554c06 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -5,48 +5,29 @@
  * Created: Sat Mar 18 22:15:47 1995 ylo
  * Code to connect to a remote host, and to perform the client side of the
  * login (authentication) dialog.
- *
- * SSH2 support added by Markus Friedl.
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshconnect.c,v 1.69 2000/04/19 07:05:50 deraadt Exp $");
+RCSID("$OpenBSD: sshconnect.c,v 1.71 2000/04/26 21:28:33 markus Exp $");
 
 #include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/rsa.h>
+
 #include "xmalloc.h"
 #include "rsa.h"
 #include "ssh.h"
 #include "buffer.h"
 #include "packet.h"
-#include "authfd.h"
-#include "cipher.h"
-#include "mpaux.h"
 #include "uidswap.h"
 #include "compat.h"
 #include "readconf.h"
-
-#include "bufaux.h"
-#include <openssl/rsa.h>
-#include <openssl/dsa.h>
-
-#include "ssh2.h"
-#include <openssl/md5.h>
-#include <openssl/dh.h>
-#include <openssl/hmac.h>
-#include "kex.h"
-#include "myproposal.h"
 #include "key.h"
-#include "dsa.h"
+#include "sshconnect.h"
 #include "hostfile.h"
 
-/* Session id for the current session. */
-unsigned char session_id[16];
-
-/* authentications supported by server */
-unsigned int supported_authentications;
-
-static char *client_version_string = NULL;
-static char *server_version_string = NULL;
+char *client_version_string = NULL;
+char *server_version_string = NULL;
 
 extern Options options;
 extern char *__progname;
@@ -316,653 +297,6 @@
 	return 1;
 }
 
-/*
- * Checks if the user has an authentication agent, and if so, tries to
- * authenticate using the agent.
- */
-int
-try_agent_authentication()
-{
-	int status, type;
-	char *comment;
-	AuthenticationConnection *auth;
-	unsigned char response[16];
-	unsigned int i;
-	BIGNUM *e, *n, *challenge;
-
-	/* Get connection to the agent. */
-	auth = ssh_get_authentication_connection();
-	if (!auth)
-		return 0;
-
-	e = BN_new();
-	n = BN_new();
-	challenge = BN_new();
-
-	/* Loop through identities served by the agent. */
-	for (status = ssh_get_first_identity(auth, e, n, &comment);
-	     status;
-	     status = ssh_get_next_identity(auth, e, n, &comment)) {
-		int plen, clen;
-
-		/* Try this identity. */
-		debug("Trying RSA authentication via agent with '%.100s'", comment);
-		xfree(comment);
-
-		/* Tell the server that we are willing to authenticate using this key. */
-		packet_start(SSH_CMSG_AUTH_RSA);
-		packet_put_bignum(n);
-		packet_send();
-		packet_write_wait();
-
-		/* Wait for server's response. */
-		type = packet_read(&plen);
-
-		/* The server sends failure if it doesn\'t like our key or
-		   does not support RSA authentication. */
-		if (type == SSH_SMSG_FAILURE) {
-			debug("Server refused our key.");
-			continue;
-		}
-		/* Otherwise it should have sent a challenge. */
-		if (type != SSH_SMSG_AUTH_RSA_CHALLENGE)
-			packet_disconnect("Protocol error during RSA authentication: %d",
-					  type);
-
-		packet_get_bignum(challenge, &clen);
-
-		packet_integrity_check(plen, clen, type);
-
-		debug("Received RSA challenge from server.");
-
-		/* Ask the agent to decrypt the challenge. */
-		if (!ssh_decrypt_challenge(auth, e, n, challenge,
-					   session_id, 1, response)) {
-			/* The agent failed to authenticate this identifier although it
-			   advertised it supports this.  Just return a wrong value. */
-			log("Authentication agent failed to decrypt challenge.");
-			memset(response, 0, sizeof(response));
-		}
-		debug("Sending response to RSA challenge.");
-
-		/* Send the decrypted challenge back to the server. */
-		packet_start(SSH_CMSG_AUTH_RSA_RESPONSE);
-		for (i = 0; i < 16; i++)
-			packet_put_char(response[i]);
-		packet_send();
-		packet_write_wait();
-
-		/* Wait for response from the server. */
-		type = packet_read(&plen);
-
-		/* The server returns success if it accepted the authentication. */
-		if (type == SSH_SMSG_SUCCESS) {
-			debug("RSA authentication accepted by server.");
-			BN_clear_free(e);
-			BN_clear_free(n);
-			BN_clear_free(challenge);
-			return 1;
-		}
-		/* Otherwise it should return failure. */
-		if (type != SSH_SMSG_FAILURE)
-			packet_disconnect("Protocol error waiting RSA auth response: %d",
-					  type);
-	}
-
-	BN_clear_free(e);
-	BN_clear_free(n);
-	BN_clear_free(challenge);
-
-	debug("RSA authentication using agent refused.");
-	return 0;
-}
-
-/*
- * Computes the proper response to a RSA challenge, and sends the response to
- * the server.
- */
-void
-respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv)
-{
-	unsigned char buf[32], response[16];
-	MD5_CTX md;
-	int i, len;
-
-	/* Decrypt the challenge using the private key. */
-	rsa_private_decrypt(challenge, challenge, prv);
-
-	/* Compute the response. */
-	/* The response is MD5 of decrypted challenge plus session id. */
-	len = BN_num_bytes(challenge);
-	if (len <= 0 || len > sizeof(buf))
-		packet_disconnect("respond_to_rsa_challenge: bad challenge length %d",
-				  len);
-
-	memset(buf, 0, sizeof(buf));
-	BN_bn2bin(challenge, buf + sizeof(buf) - len);
-	MD5_Init(&md);
-	MD5_Update(&md, buf, 32);
-	MD5_Update(&md, session_id, 16);
-	MD5_Final(response, &md);
-
-	debug("Sending response to host key RSA challenge.");
-
-	/* Send the response back to the server. */
-	packet_start(SSH_CMSG_AUTH_RSA_RESPONSE);
-	for (i = 0; i < 16; i++)
-		packet_put_char(response[i]);
-	packet_send();
-	packet_write_wait();
-
-	memset(buf, 0, sizeof(buf));
-	memset(response, 0, sizeof(response));
-	memset(&md, 0, sizeof(md));
-}
-
-/*
- * Checks if the user has authentication file, and if so, tries to authenticate
- * the user using it.
- */
-int
-try_rsa_authentication(const char *authfile)
-{
-	BIGNUM *challenge;
-	RSA *private_key;
-	RSA *public_key;
-	char *passphrase, *comment;
-	int type, i;
-	int plen, clen;
-
-	/* Try to load identification for the authentication key. */
-	public_key = RSA_new();
-	if (!load_public_key(authfile, public_key, &comment)) {
-		RSA_free(public_key);
-		/* Could not load it.  Fail. */
-		return 0;
-	}
-	debug("Trying RSA authentication with key '%.100s'", comment);
-
-	/* Tell the server that we are willing to authenticate using this key. */
-	packet_start(SSH_CMSG_AUTH_RSA);
-	packet_put_bignum(public_key->n);
-	packet_send();
-	packet_write_wait();
-
-	/* We no longer need the public key. */
-	RSA_free(public_key);
-
-	/* Wait for server's response. */
-	type = packet_read(&plen);
-
-	/*
-	 * The server responds with failure if it doesn\'t like our key or
-	 * doesn\'t support RSA authentication.
-	 */
-	if (type == SSH_SMSG_FAILURE) {
-		debug("Server refused our key.");
-		xfree(comment);
-		return 0;
-	}
-	/* Otherwise, the server should respond with a challenge. */
-	if (type != SSH_SMSG_AUTH_RSA_CHALLENGE)
-		packet_disconnect("Protocol error during RSA authentication: %d", type);
-
-	/* Get the challenge from the packet. */
-	challenge = BN_new();
-	packet_get_bignum(challenge, &clen);
-
-	packet_integrity_check(plen, clen, type);
-
-	debug("Received RSA challenge from server.");
-
-	private_key = RSA_new();
-	/*
-	 * Load the private key.  Try first with empty passphrase; if it
-	 * fails, ask for a passphrase.
-	 */
-	if (!load_private_key(authfile, "", private_key, NULL)) {
-		char buf[300];
-		snprintf(buf, sizeof buf, "Enter passphrase for RSA key '%.100s': ",
-		    comment);
-		if (!options.batch_mode)
-			passphrase = read_passphrase(buf, 0);
-		else {
-			debug("Will not query passphrase for %.100s in batch mode.",
-			      comment);
-			passphrase = xstrdup("");
-		}
-
-		/* Load the authentication file using the pasphrase. */
-		if (!load_private_key(authfile, passphrase, private_key, NULL)) {
-			memset(passphrase, 0, strlen(passphrase));
-			xfree(passphrase);
-			error("Bad passphrase.");
-
-			/* Send a dummy response packet to avoid protocol error. */
-			packet_start(SSH_CMSG_AUTH_RSA_RESPONSE);
-			for (i = 0; i < 16; i++)
-				packet_put_char(0);
-			packet_send();
-			packet_write_wait();
-
-			/* Expect the server to reject it... */
-			packet_read_expect(&plen, SSH_SMSG_FAILURE);
-			xfree(comment);
-			return 0;
-		}
-		/* Destroy the passphrase. */
-		memset(passphrase, 0, strlen(passphrase));
-		xfree(passphrase);
-	}
-	/* We no longer need the comment. */
-	xfree(comment);
-
-	/* Compute and send a response to the challenge. */
-	respond_to_rsa_challenge(challenge, private_key);
-
-	/* Destroy the private key. */
-	RSA_free(private_key);
-
-	/* We no longer need the challenge. */
-	BN_clear_free(challenge);
-
-	/* Wait for response from the server. */
-	type = packet_read(&plen);
-	if (type == SSH_SMSG_SUCCESS) {
-		debug("RSA authentication accepted by server.");
-		return 1;
-	}
-	if (type != SSH_SMSG_FAILURE)
-		packet_disconnect("Protocol error waiting RSA auth response: %d", type);
-	debug("RSA authentication refused.");
-	return 0;
-}
-
-/*
- * Tries to authenticate the user using combined rhosts or /etc/hosts.equiv
- * authentication and RSA host authentication.
- */
-int
-try_rhosts_rsa_authentication(const char *local_user, RSA * host_key)
-{
-	int type;
-	BIGNUM *challenge;
-	int plen, clen;
-
-	debug("Trying rhosts or /etc/hosts.equiv with RSA host authentication.");
-
-	/* Tell the server that we are willing to authenticate using this key. */
-	packet_start(SSH_CMSG_AUTH_RHOSTS_RSA);
-	packet_put_string(local_user, strlen(local_user));
-	packet_put_int(BN_num_bits(host_key->n));
-	packet_put_bignum(host_key->e);
-	packet_put_bignum(host_key->n);
-	packet_send();
-	packet_write_wait();
-
-	/* Wait for server's response. */
-	type = packet_read(&plen);
-
-	/* The server responds with failure if it doesn't admit our
-	   .rhosts authentication or doesn't know our host key. */
-	if (type == SSH_SMSG_FAILURE) {
-		debug("Server refused our rhosts authentication or host key.");
-		return 0;
-	}
-	/* Otherwise, the server should respond with a challenge. */
-	if (type != SSH_SMSG_AUTH_RSA_CHALLENGE)
-		packet_disconnect("Protocol error during RSA authentication: %d", type);
-
-	/* Get the challenge from the packet. */
-	challenge = BN_new();
-	packet_get_bignum(challenge, &clen);
-
-	packet_integrity_check(plen, clen, type);
-
-	debug("Received RSA challenge for host key from server.");
-
-	/* Compute a response to the challenge. */
-	respond_to_rsa_challenge(challenge, host_key);
-
-	/* We no longer need the challenge. */
-	BN_clear_free(challenge);
-
-	/* Wait for response from the server. */
-	type = packet_read(&plen);
-	if (type == SSH_SMSG_SUCCESS) {
-		debug("Rhosts or /etc/hosts.equiv with RSA host authentication accepted by server.");
-		return 1;
-	}
-	if (type != SSH_SMSG_FAILURE)
-		packet_disconnect("Protocol error waiting RSA auth response: %d", type);
-	debug("Rhosts or /etc/hosts.equiv with RSA host authentication refused.");
-	return 0;
-}
-
-#ifdef KRB4
-int
-try_kerberos_authentication()
-{
-	KTEXT_ST auth;		/* Kerberos data */
-	char *reply;
-	char inst[INST_SZ];
-	char *realm;
-	CREDENTIALS cred;
-	int r, type, plen;
-	socklen_t slen;
-	Key_schedule schedule;
-	u_long checksum, cksum;
-	MSG_DAT msg_data;
-	struct sockaddr_in local, foreign;
-	struct stat st;
-
-	/* Don't do anything if we don't have any tickets. */
-	if (stat(tkt_string(), &st) < 0)
-		return 0;
-
-	strncpy(inst, (char *) krb_get_phost(get_canonical_hostname()), INST_SZ);
-
-	realm = (char *) krb_realmofhost(get_canonical_hostname());
-	if (!realm) {
-		debug("Kerberos V4: no realm for %s", get_canonical_hostname());
-		return 0;
-	}
-	/* This can really be anything. */
-	checksum = (u_long) getpid();
-
-	r = krb_mk_req(&auth, KRB4_SERVICE_NAME, inst, realm, checksum);
-	if (r != KSUCCESS) {
-		debug("Kerberos V4 krb_mk_req failed: %s", krb_err_txt[r]);
-		return 0;
-	}
-	/* Get session key to decrypt the server's reply with. */
-	r = krb_get_cred(KRB4_SERVICE_NAME, inst, realm, &cred);
-	if (r != KSUCCESS) {
-		debug("get_cred failed: %s", krb_err_txt[r]);
-		return 0;
-	}
-	des_key_sched((des_cblock *) cred.session, schedule);
-
-	/* Send authentication info to server. */
-	packet_start(SSH_CMSG_AUTH_KERBEROS);
-	packet_put_string((char *) auth.dat, auth.length);
-	packet_send();
-	packet_write_wait();
-
-	/* Zero the buffer. */
-	(void) memset(auth.dat, 0, MAX_KTXT_LEN);
-
-	slen = sizeof(local);
-	memset(&local, 0, sizeof(local));
-	if (getsockname(packet_get_connection_in(),
-			(struct sockaddr *) & local, &slen) < 0)
-		debug("getsockname failed: %s", strerror(errno));
-
-	slen = sizeof(foreign);
-	memset(&foreign, 0, sizeof(foreign));
-	if (getpeername(packet_get_connection_in(),
-			(struct sockaddr *) & foreign, &slen) < 0) {
-		debug("getpeername failed: %s", strerror(errno));
-		fatal_cleanup();
-	}
-	/* Get server reply. */
-	type = packet_read(&plen);
-	switch (type) {
-	case SSH_SMSG_FAILURE:
-		/* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */
-		debug("Kerberos V4 authentication failed.");
-		return 0;
-		break;
-
-	case SSH_SMSG_AUTH_KERBEROS_RESPONSE:
-		/* SSH_SMSG_AUTH_KERBEROS_SUCCESS */
-		debug("Kerberos V4 authentication accepted.");
-
-		/* Get server's response. */
-		reply = packet_get_string((unsigned int *) &auth.length);
-		memcpy(auth.dat, reply, auth.length);
-		xfree(reply);
-
-		packet_integrity_check(plen, 4 + auth.length, type);
-
-		/*
-		 * If his response isn't properly encrypted with the session
-		 * key, and the decrypted checksum fails to match, he's
-		 * bogus. Bail out.
-		 */
-		r = krb_rd_priv(auth.dat, auth.length, schedule, &cred.session,
-				&foreign, &local, &msg_data);
-		if (r != KSUCCESS) {
-			debug("Kerberos V4 krb_rd_priv failed: %s", krb_err_txt[r]);
-			packet_disconnect("Kerberos V4 challenge failed!");
-		}
-		/* Fetch the (incremented) checksum that we supplied in the request. */
-		(void) memcpy((char *) &cksum, (char *) msg_data.app_data, sizeof(cksum));
-		cksum = ntohl(cksum);
-
-		/* If it matches, we're golden. */
-		if (cksum == checksum + 1) {
-			debug("Kerberos V4 challenge successful.");
-			return 1;
-		} else
-			packet_disconnect("Kerberos V4 challenge failed!");
-		break;
-
-	default:
-		packet_disconnect("Protocol error on Kerberos V4 response: %d", type);
-	}
-	return 0;
-}
-
-#endif /* KRB4 */
-
-#ifdef AFS
-int
-send_kerberos_tgt()
-{
-	CREDENTIALS *creds;
-	char pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ];
-	int r, type, plen;
-	char buffer[8192];
-	struct stat st;
-
-	/* Don't do anything if we don't have any tickets. */
-	if (stat(tkt_string(), &st) < 0)
-		return 0;
-
-	creds = xmalloc(sizeof(*creds));
-
-	if ((r = krb_get_tf_fullname(TKT_FILE, pname, pinst, prealm)) != KSUCCESS) {
-		debug("Kerberos V4 tf_fullname failed: %s", krb_err_txt[r]);
-		return 0;
-	}
-	if ((r = krb_get_cred("krbtgt", prealm, prealm, creds)) != GC_OK) {
-		debug("Kerberos V4 get_cred failed: %s", krb_err_txt[r]);
-		return 0;
-	}
-	if (time(0) > krb_life_to_time(creds->issue_date, creds->lifetime)) {
-		debug("Kerberos V4 ticket expired: %s", TKT_FILE);
-		return 0;
-	}
-	creds_to_radix(creds, (unsigned char *)buffer);
-	xfree(creds);
-
-	packet_start(SSH_CMSG_HAVE_KERBEROS_TGT);
-	packet_put_string(buffer, strlen(buffer));
-	packet_send();
-	packet_write_wait();
-
-	type = packet_read(&plen);
-
-	if (type == SSH_SMSG_FAILURE)
-		debug("Kerberos TGT for realm %s rejected.", prealm);
-	else if (type != SSH_SMSG_SUCCESS)
-		packet_disconnect("Protocol error on Kerberos TGT response: %d", type);
-
-	return 1;
-}
-
-void
-send_afs_tokens(void)
-{
-	CREDENTIALS creds;
-	struct ViceIoctl parms;
-	struct ClearToken ct;
-	int i, type, len, plen;
-	char buf[2048], *p, *server_cell;
-	char buffer[8192];
-
-	/* Move over ktc_GetToken, here's something leaner. */
-	for (i = 0; i < 100; i++) {	/* just in case */
-		parms.in = (char *) &i;
-		parms.in_size = sizeof(i);
-		parms.out = buf;
-		parms.out_size = sizeof(buf);
-		if (k_pioctl(0, VIOCGETTOK, &parms, 0) != 0)
-			break;
-		p = buf;
-
-		/* Get secret token. */
-		memcpy(&creds.ticket_st.length, p, sizeof(unsigned int));
-		if (creds.ticket_st.length > MAX_KTXT_LEN)
-			break;
-		p += sizeof(unsigned int);
-		memcpy(creds.ticket_st.dat, p, creds.ticket_st.length);
-		p += creds.ticket_st.length;
-
-		/* Get clear token. */
-		memcpy(&len, p, sizeof(len));
-		if (len != sizeof(struct ClearToken))
-			break;
-		p += sizeof(len);
-		memcpy(&ct, p, len);
-		p += len;
-		p += sizeof(len);	/* primary flag */
-		server_cell = p;
-
-		/* Flesh out our credentials. */
-		strlcpy(creds.service, "afs", sizeof creds.service);
-		creds.instance[0] = '\0';
-		strlcpy(creds.realm, server_cell, REALM_SZ);
-		memcpy(creds.session, ct.HandShakeKey, DES_KEY_SZ);
-		creds.issue_date = ct.BeginTimestamp;
-		creds.lifetime = krb_time_to_life(creds.issue_date, ct.EndTimestamp);
-		creds.kvno = ct.AuthHandle;
-		snprintf(creds.pname, sizeof(creds.pname), "AFS ID %d", ct.ViceId);
-		creds.pinst[0] = '\0';
-
-		/* Encode token, ship it off. */
-		if (!creds_to_radix(&creds, (unsigned char*) buffer))
-			break;
-		packet_start(SSH_CMSG_HAVE_AFS_TOKEN);
-		packet_put_string(buffer, strlen(buffer));
-		packet_send();
-		packet_write_wait();
-
-		/* Roger, Roger. Clearance, Clarence. What's your vector,
-		   Victor? */
-		type = packet_read(&plen);
-
-		if (type == SSH_SMSG_FAILURE)
-			debug("AFS token for cell %s rejected.", server_cell);
-		else if (type != SSH_SMSG_SUCCESS)
-			packet_disconnect("Protocol error on AFS token response: %d", type);
-	}
-}
-
-#endif /* AFS */
-
-/*
- * Tries to authenticate with any string-based challenge/response system.
- * Note that the client code is not tied to s/key or TIS.
- */
-int
-try_skey_authentication()
-{
-	int type, i;
-	int payload_len;
-	unsigned int clen;
-	char *challenge, *response;
-
-	debug("Doing skey authentication.");
-
-	/* request a challenge */
-	packet_start(SSH_CMSG_AUTH_TIS);
-	packet_send();
-	packet_write_wait();
-
-	type = packet_read(&payload_len);
-	if (type != SSH_SMSG_FAILURE &&
-	    type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
-		packet_disconnect("Protocol error: got %d in response "
-				  "to skey-auth", type);
-	}
-	if (type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
-		debug("No challenge for skey authentication.");
-		return 0;
-	}
-	challenge = packet_get_string(&clen);
-	packet_integrity_check(payload_len, (4 + clen), type);
-	if (options.cipher == SSH_CIPHER_NONE)
-		log("WARNING: Encryption is disabled! "
-		    "Reponse will be transmitted in clear text.");
-	fprintf(stderr, "%s\n", challenge);
-	xfree(challenge);
-	fflush(stderr);
-	for (i = 0; i < options.number_of_password_prompts; i++) {
-		if (i != 0)
-			error("Permission denied, please try again.");
-		response = read_passphrase("Response: ", 0);
-		packet_start(SSH_CMSG_AUTH_TIS_RESPONSE);
-		packet_put_string(response, strlen(response));
-		memset(response, 0, strlen(response));
-		xfree(response);
-		packet_send();
-		packet_write_wait();
-		type = packet_read(&payload_len);
-		if (type == SSH_SMSG_SUCCESS)
-			return 1;
-		if (type != SSH_SMSG_FAILURE)
-			packet_disconnect("Protocol error: got %d in response "
-					  "to skey-auth-reponse", type);
-	}
-	/* failure */
-	return 0;
-}
-
-/*
- * Tries to authenticate with plain passwd authentication.
- */
-int
-try_password_authentication(char *prompt)
-{
-	int type, i, payload_len;
-	char *password;
-
-	debug("Doing password authentication.");
-	if (options.cipher == SSH_CIPHER_NONE)
-		log("WARNING: Encryption is disabled! Password will be transmitted in clear text.");
-	for (i = 0; i < options.number_of_password_prompts; i++) {
-		if (i != 0)
-			error("Permission denied, please try again.");
-		password = read_passphrase(prompt, 0);
-		packet_start(SSH_CMSG_AUTH_PASSWORD);
-		packet_put_string(password, strlen(password));
-		memset(password, 0, strlen(password));
-		xfree(password);
-		packet_send();
-		packet_write_wait();
-
-		type = packet_read(&payload_len);
-		if (type == SSH_SMSG_SUCCESS)
-			return 1;
-		if (type != SSH_SMSG_FAILURE)
-			packet_disconnect("Protocol error: got %d in response to passwd auth", type);
-	}
-	/* failure */
-	return 0;
-}
-
 char *
 chop(char *s)
 {
@@ -1060,7 +394,8 @@
 		fatal("Protocol major versions differ: %d vs. %d",
 		    (options.protocol & SSH_PROTO_2) ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
 		    remote_major);
-
+	if (compat20)
+		packet_set_ssh2_format();
 	/* Send our own protocol version identification. */
 	snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n",
 	    compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
@@ -1122,7 +457,8 @@
  */
 
 void
-check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
+check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
+	const char *user_hostfile, const char *system_hostfile)
 {
 	Key *file_key;
 	char *ip = NULL;
@@ -1141,6 +477,7 @@
 	 * essentially disables host authentication for localhost; however,
 	 * this is probably not a real problem.
 	 */
+	/**  hostaddr == 0! */
 	switch (hostaddr->sa_family) {
 	case AF_INET:
 		local = (ntohl(((struct sockaddr_in *)hostaddr)->sin_addr.s_addr) >> 24) == IN_LOOPBACKNET;
@@ -1184,19 +521,19 @@
 	 * Check if the host key is present in the user\'s list of known
 	 * hosts or in the systemwide list.
 	 */
-	host_status = check_host_in_hostfile(options.user_hostfile, host, host_key, file_key);
+	host_status = check_host_in_hostfile(user_hostfile, host, host_key, file_key);
 	if (host_status == HOST_NEW)
-		host_status = check_host_in_hostfile(options.system_hostfile, host, host_key, file_key);
+		host_status = check_host_in_hostfile(system_hostfile, host, host_key, file_key);
 	/*
 	 * Also perform check for the ip address, skip the check if we are
 	 * localhost or the hostname was an ip address to begin with
 	 */
 	if (options.check_host_ip && !local && strcmp(host, ip)) {
 		Key *ip_key = key_new(host_key->type);
-		ip_status = check_host_in_hostfile(options.user_hostfile, ip, host_key, ip_key);
+		ip_status = check_host_in_hostfile(user_hostfile, ip, host_key, ip_key);
 
 		if (ip_status == HOST_NEW)
-			ip_status = check_host_in_hostfile(options.system_hostfile, ip, host_key, ip_key);
+			ip_status = check_host_in_hostfile(system_hostfile, ip, host_key, ip_key);
 		if (host_status == HOST_CHANGED &&
 		    (ip_status != HOST_CHANGED || !key_equal(ip_key, file_key)))
 			host_ip_differ = 1;
@@ -1213,9 +550,9 @@
 		debug("Host '%.200s' is known and matches the host key.", host);
 		if (options.check_host_ip) {
 			if (ip_status == HOST_NEW) {
-				if (!add_host_to_hostfile(options.user_hostfile, ip, host_key))
+				if (!add_host_to_hostfile(user_hostfile, ip, host_key))
 					log("Failed to add the host key for IP address '%.30s' to the list of known hosts (%.30s).",
-					    ip, options.user_hostfile);
+					    ip, user_hostfile);
 				else
 					log("Warning: Permanently added host key for IP address '%.30s' to the list of known hosts.",
 					    ip);
@@ -1249,9 +586,9 @@
 			hostp = host;
 
 		/* If not in strict mode, add the key automatically to the local known_hosts file. */
-		if (!add_host_to_hostfile(options.user_hostfile, hostp, host_key))
+		if (!add_host_to_hostfile(user_hostfile, hostp, host_key))
 			log("Failed to add the host to the list of known hosts (%.500s).",
-			    options.user_hostfile);
+			    user_hostfile);
 		else
 			log("Warning: Permanently added '%.200s' to the list of known hosts.",
 			    hostp);
@@ -1283,7 +620,7 @@
 		error("It is also possible that the host key has just been changed.");
 		error("Please contact your system administrator.");
 		error("Add correct host key in %.100s to get rid of this message.",
-		      options.user_hostfile);
+		      user_hostfile);
 
 		/*
 		 * If strict host key checking is in use, the user will have
@@ -1317,644 +654,7 @@
 	if (options.check_host_ip)
 		xfree(ip);
 }
-void
-check_rsa_host_key(char *host, struct sockaddr *hostaddr, RSA *host_key)
-{
-	Key k;
-	k.type = KEY_RSA;
-	k.rsa = host_key;
-	check_host_key(host, hostaddr, &k);
-}
-
-/*
- * SSH2 key exchange
- */
-void
-ssh_kex2(char *host, struct sockaddr *hostaddr)
-{
-	Kex *kex;
-	char *cprop[PROPOSAL_MAX];
-	char *sprop[PROPOSAL_MAX];
-	Buffer *client_kexinit;
-	Buffer *server_kexinit;
-	int payload_len, dlen;
-	unsigned int klen, kout;
-	char *ptr;
-	char *signature = NULL;
-	unsigned int slen;
-	char *server_host_key_blob = NULL;
-	Key *server_host_key;
-	unsigned int sbloblen;
-	DH *dh;
-	BIGNUM *dh_server_pub = 0;
-	BIGNUM *shared_secret = 0;
-	int i;
-	unsigned char *kbuf;
-	unsigned char *hash;
-
-/* KEXINIT */
-
-	debug("Sending KEX init.");
-	if (options.ciphers != NULL) {
-		myproposal[PROPOSAL_ENC_ALGS_CTOS] =
-		myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
-	} else if (
-	    options.cipher == SSH_CIPHER_ARCFOUR ||
-	    options.cipher == SSH_CIPHER_3DES_CBC ||
-	    options.cipher == SSH_CIPHER_CAST128_CBC ||
-	    options.cipher == SSH_CIPHER_BLOWFISH_CBC) {
-		myproposal[PROPOSAL_ENC_ALGS_CTOS] =
-		myproposal[PROPOSAL_ENC_ALGS_STOC] = cipher_name(options.cipher);
-	}
-	if (options.compression) {
-		myproposal[PROPOSAL_COMP_ALGS_CTOS] = "zlib";
-		myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib";
-	} else {
-		myproposal[PROPOSAL_COMP_ALGS_CTOS] = "none";
-		myproposal[PROPOSAL_COMP_ALGS_STOC] = "none";
-	}
-	for (i = 0; i < PROPOSAL_MAX; i++)
-		cprop[i] = xstrdup(myproposal[i]);
-
-	client_kexinit = kex_init(cprop);
-	packet_start(SSH2_MSG_KEXINIT);
-	packet_put_raw(buffer_ptr(client_kexinit), buffer_len(client_kexinit));	
-	packet_send();
-	packet_write_wait();
-
-	debug("done");
-
-	packet_read_expect(&payload_len, SSH2_MSG_KEXINIT);
-
-	/* save payload for session_id */
-	server_kexinit = xmalloc(sizeof(*server_kexinit));
-	buffer_init(server_kexinit);
-	ptr = packet_get_raw(&payload_len);
-	buffer_append(server_kexinit, ptr, payload_len);
-
-	/* skip cookie */
-	for (i = 0; i < 16; i++)
-		(void) packet_get_char();
-	/* kex init proposal strings */
-	for (i = 0; i < PROPOSAL_MAX; i++) {
-		sprop[i] = packet_get_string(NULL);
-		debug("got kexinit string: %s", sprop[i]);
-	}
-	i = (int) packet_get_char();
-	debug("first kex follow == %d", i);
-	i = packet_get_int();
-	debug("reserved == %d", i);
-	packet_done();
-
-	debug("done read kexinit");
-	kex = kex_choose_conf(cprop, sprop, 0);
-
-/* KEXDH */
-
-	debug("Sending SSH2_MSG_KEXDH_INIT.");
-
-	/* generate and send 'e', client DH public key */
-	dh = dh_new_group1();
-	packet_start(SSH2_MSG_KEXDH_INIT);
-	packet_put_bignum2(dh->pub_key);
-	packet_send();
-	packet_write_wait();
-
-#ifdef DEBUG_KEXDH
-	fprintf(stderr, "\np= ");
-	bignum_print(dh->p);
-	fprintf(stderr, "\ng= ");
-	bignum_print(dh->g);
-	fprintf(stderr, "\npub= ");
-	bignum_print(dh->pub_key);
-	fprintf(stderr, "\n");
-	DHparams_print_fp(stderr, dh);
-#endif
-
-	debug("Wait SSH2_MSG_KEXDH_REPLY.");
-
-	packet_read_expect(&payload_len, SSH2_MSG_KEXDH_REPLY);
-
-	debug("Got SSH2_MSG_KEXDH_REPLY.");
-
-	/* key, cert */
-	server_host_key_blob = packet_get_string(&sbloblen);
-	server_host_key = dsa_serverkey_from_blob(server_host_key_blob, sbloblen);
-	if (server_host_key == NULL)
-		fatal("cannot decode server_host_key_blob");
-
-	check_host_key(host, hostaddr, server_host_key);
-
-	/* DH paramter f, server public DH key */
-	dh_server_pub = BN_new();
-	if (dh_server_pub == NULL)
-		fatal("dh_server_pub == NULL");
-	packet_get_bignum2(dh_server_pub, &dlen);
-
-#ifdef DEBUG_KEXDH
-	fprintf(stderr, "\ndh_server_pub= ");
-	bignum_print(dh_server_pub);
-	fprintf(stderr, "\n");
-	debug("bits %d", BN_num_bits(dh_server_pub));
-#endif
-
-	/* signed H */
-	signature = packet_get_string(&slen);
-	packet_done();
-
-	if (!dh_pub_is_valid(dh, dh_server_pub))
-		packet_disconnect("bad server public DH value");
-
-	klen = DH_size(dh);
-	kbuf = xmalloc(klen);
-	kout = DH_compute_key(kbuf, dh_server_pub, dh);
-#ifdef DEBUG_KEXDH
-	debug("shared secret: len %d/%d", klen, kout);
-	fprintf(stderr, "shared secret == ");
-	for (i = 0; i< kout; i++)
-		fprintf(stderr, "%02x", (kbuf[i])&0xff);
-	fprintf(stderr, "\n");
-#endif
-	shared_secret = BN_new();
-
-	BN_bin2bn(kbuf, kout, shared_secret);
-	memset(kbuf, 0, klen);
-	xfree(kbuf);
-
-	/* calc and verify H */
-	hash = kex_hash(
-	    client_version_string,
-	    server_version_string,
-	    buffer_ptr(client_kexinit), buffer_len(client_kexinit),
-	    buffer_ptr(server_kexinit), buffer_len(server_kexinit),
-	    server_host_key_blob, sbloblen,
-	    dh->pub_key,
-	    dh_server_pub,
-	    shared_secret
-	);
-	buffer_free(client_kexinit);
-	buffer_free(server_kexinit);
-	xfree(client_kexinit);
-	xfree(server_kexinit);
-#ifdef DEBUG_KEXDH
-	fprintf(stderr, "hash == ");
-	for (i = 0; i< 20; i++)
-		fprintf(stderr, "%02x", (hash[i])&0xff);
-	fprintf(stderr, "\n");
-#endif
-	dsa_verify(server_host_key, (unsigned char *)signature, slen, hash, 20);
-	key_free(server_host_key);
-
-	kex_derive_keys(kex, hash, shared_secret);
-	packet_set_kex(kex);
-
-	/* have keys, free DH */
-	DH_free(dh);
-
-	debug("Wait SSH2_MSG_NEWKEYS.");
-	packet_read_expect(&payload_len, SSH2_MSG_NEWKEYS);
-	packet_done();
-	debug("GOT SSH2_MSG_NEWKEYS.");
-
-	debug("send SSH2_MSG_NEWKEYS.");
-	packet_start(SSH2_MSG_NEWKEYS);
-	packet_send();
-	packet_write_wait();
-	debug("done: send SSH2_MSG_NEWKEYS.");
-
-#ifdef DEBUG_KEXDH
-	/* send 1st encrypted/maced/compressed message */
-	packet_start(SSH2_MSG_IGNORE);
-	packet_put_cstring("markus");
-	packet_send();
-	packet_write_wait();
-#endif
-	debug("done: KEX2.");
-}
-/*
- * Authenticate user
- */
-void
-ssh_userauth2(int host_key_valid, RSA *own_host_key,
-    uid_t original_real_uid, char *host)
-{
-	int type;
-	int plen;
-	unsigned int dlen;
-	int partial;
-	struct passwd *pw;
-	char prompt[80];
-	char *server_user, *local_user;
-	char *auths;
-	char *password;
-	char *service = "ssh-connection";		/* service name */
-
-	debug("send SSH2_MSG_SERVICE_REQUEST");
-	packet_start(SSH2_MSG_SERVICE_REQUEST);
-	packet_put_cstring("ssh-userauth");
-	packet_send();
-	packet_write_wait();
-
-	type = packet_read(&plen);
-	if (type != SSH2_MSG_SERVICE_ACCEPT) {
-		fatal("denied SSH2_MSG_SERVICE_ACCEPT: %d", type);
-	}
-	if (packet_remaining() > 0) {
-		char *reply = packet_get_string(&plen);
-		debug("service_accept: %s", reply);
-		xfree(reply);
-	} else {
-		/* payload empty for ssh-2.0.13 ?? */
-		log("buggy server: service_accept w/o service");
-	}
-	packet_done();
-	debug("got SSH2_MSG_SERVICE_ACCEPT");
-
-	/*XX COMMONCODE: */
-	/* Get local user name.  Use it as server user if no user name was given. */
-	pw = getpwuid(original_real_uid);
-	if (!pw)
-		fatal("User id %d not found from user database.", original_real_uid);
-	local_user = xstrdup(pw->pw_name);
-	server_user = options.user ? options.user : local_user;
-
-	/* INITIAL request for auth */
-	packet_start(SSH2_MSG_USERAUTH_REQUEST);
-	packet_put_cstring(server_user);
-	packet_put_cstring(service);
-	packet_put_cstring("none");
-	packet_send();
-	packet_write_wait();
-
-	for (;;) {
-		type = packet_read(&plen);
-		if (type == SSH2_MSG_USERAUTH_SUCCESS)
-			break;
-		if (type != SSH2_MSG_USERAUTH_FAILURE)
-			fatal("access denied: %d", type);
-		/* SSH2_MSG_USERAUTH_FAILURE means: try again */
-		auths = packet_get_string(&dlen);
-		debug("authentications that can continue: %s", auths);
-		partial = packet_get_char();
-		packet_done();
-		if (partial)
-			debug("partial success");
-		if (strstr(auths, "password") == NULL)
-			fatal("passwd auth not supported: %s", auths);
-		xfree(auths);
-		/* try passwd */
-		snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ",
-		    server_user, host);
-		password = read_passphrase(prompt, 0);
-		packet_start(SSH2_MSG_USERAUTH_REQUEST);
-		packet_put_cstring(server_user);
-		packet_put_cstring(service);
-		packet_put_cstring("password");
-		packet_put_char(0);
-		packet_put_cstring(password);
-		memset(password, 0, strlen(password));
-		xfree(password);
-		packet_send();
-		packet_write_wait();
-	}
-	packet_done();
-	debug("ssh-userauth2 successfull");
-}
-
-/*
- * SSH1 key exchange
- */
-void
-ssh_kex(char *host, struct sockaddr *hostaddr)
-{
-	int i;
-	BIGNUM *key;
-	RSA *host_key;
-	RSA *public_key;
-	int bits, rbits;
-	int ssh_cipher_default = SSH_CIPHER_3DES;
-	unsigned char session_key[SSH_SESSION_KEY_LENGTH];
-	unsigned char cookie[8];
-	unsigned int supported_ciphers;
-	unsigned int server_flags, client_flags;
-	int payload_len, clen, sum_len = 0;
-	u_int32_t rand = 0;
-
-	debug("Waiting for server public key.");
-
-	/* Wait for a public key packet from the server. */
-	packet_read_expect(&payload_len, SSH_SMSG_PUBLIC_KEY);
-
-	/* Get cookie from the packet. */
-	for (i = 0; i < 8; i++)
-		cookie[i] = packet_get_char();
-
-	/* Get the public key. */
-	public_key = RSA_new();
-	bits = packet_get_int();/* bits */
-	public_key->e = BN_new();
-	packet_get_bignum(public_key->e, &clen);
-	sum_len += clen;
-	public_key->n = BN_new();
-	packet_get_bignum(public_key->n, &clen);
-	sum_len += clen;
-
-	rbits = BN_num_bits(public_key->n);
-	if (bits != rbits) {
-		log("Warning: Server lies about size of server public key: "
-		    "actual size is %d bits vs. announced %d.", rbits, bits);
-		log("Warning: This may be due to an old implementation of ssh.");
-	}
-	/* Get the host key. */
-	host_key = RSA_new();
-	bits = packet_get_int();/* bits */
-	host_key->e = BN_new();
-	packet_get_bignum(host_key->e, &clen);
-	sum_len += clen;
-	host_key->n = BN_new();
-	packet_get_bignum(host_key->n, &clen);
-	sum_len += clen;
-
-	rbits = BN_num_bits(host_key->n);
-	if (bits != rbits) {
-		log("Warning: Server lies about size of server host key: "
-		    "actual size is %d bits vs. announced %d.", rbits, bits);
-		log("Warning: This may be due to an old implementation of ssh.");
-	}
-
-	/* Get protocol flags. */
-	server_flags = packet_get_int();
-	packet_set_protocol_flags(server_flags);
-
-	supported_ciphers = packet_get_int();
-	supported_authentications = packet_get_int();
-
-	debug("Received server public key (%d bits) and host key (%d bits).",
-	      BN_num_bits(public_key->n), BN_num_bits(host_key->n));
-
-	packet_integrity_check(payload_len,
-			       8 + 4 + sum_len + 0 + 4 + 0 + 0 + 4 + 4 + 4,
-			       SSH_SMSG_PUBLIC_KEY);
-
-	check_rsa_host_key(host, hostaddr, host_key);
-
-	client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN;
-
-	compute_session_id(session_id, cookie, host_key->n, public_key->n);
-
-	/* Generate a session key. */
-	arc4random_stir();
-
-	/*
-	 * Generate an encryption key for the session.   The key is a 256 bit
-	 * random number, interpreted as a 32-byte key, with the least
-	 * significant 8 bits being the first byte of the key.
-	 */
-	for (i = 0; i < 32; i++) {
-		if (i % 4 == 0)
-			rand = arc4random();
-		session_key[i] = rand & 0xff;
-		rand >>= 8;
-	}
-
-	/*
-	 * According to the protocol spec, the first byte of the session key
-	 * is the highest byte of the integer.  The session key is xored with
-	 * the first 16 bytes of the session id.
-	 */
-	key = BN_new();
-	BN_set_word(key, 0);
-	for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) {
-		BN_lshift(key, key, 8);
-		if (i < 16)
-			BN_add_word(key, session_key[i] ^ session_id[i]);
-		else
-			BN_add_word(key, session_key[i]);
-	}
-
-	/*
-	 * Encrypt the integer using the public key and host key of the
-	 * server (key with smaller modulus first).
-	 */
-	if (BN_cmp(public_key->n, host_key->n) < 0) {
-		/* Public key has smaller modulus. */
-		if (BN_num_bits(host_key->n) <
-		    BN_num_bits(public_key->n) + SSH_KEY_BITS_RESERVED) {
-			fatal("respond_to_rsa_challenge: host_key %d < public_key %d + "
-			      "SSH_KEY_BITS_RESERVED %d",
-			      BN_num_bits(host_key->n),
-			      BN_num_bits(public_key->n),
-			      SSH_KEY_BITS_RESERVED);
-		}
-		rsa_public_encrypt(key, key, public_key);
-		rsa_public_encrypt(key, key, host_key);
-	} else {
-		/* Host key has smaller modulus (or they are equal). */
-		if (BN_num_bits(public_key->n) <
-		    BN_num_bits(host_key->n) + SSH_KEY_BITS_RESERVED) {
-			fatal("respond_to_rsa_challenge: public_key %d < host_key %d + "
-			      "SSH_KEY_BITS_RESERVED %d",
-			      BN_num_bits(public_key->n),
-			      BN_num_bits(host_key->n),
-			      SSH_KEY_BITS_RESERVED);
-		}
-		rsa_public_encrypt(key, key, host_key);
-		rsa_public_encrypt(key, key, public_key);
-	}
-
-	/* Destroy the public keys since we no longer need them. */
-	RSA_free(public_key);
-	RSA_free(host_key);
-
-	if (options.cipher == SSH_CIPHER_NOT_SET) {
-		if (cipher_mask1() & supported_ciphers & (1 << ssh_cipher_default))
-			options.cipher = ssh_cipher_default;
-		else {
-			debug("Cipher %s not supported, using %.100s instead.",
-			      cipher_name(ssh_cipher_default),
-			      cipher_name(SSH_FALLBACK_CIPHER));
-			options.cipher = SSH_FALLBACK_CIPHER;
-		}
-	}
-	/* Check that the selected cipher is supported. */
-	if (!(supported_ciphers & (1 << options.cipher)))
-		fatal("Selected cipher type %.100s not supported by server.",
-		      cipher_name(options.cipher));
-
-	debug("Encryption type: %.100s", cipher_name(options.cipher));
-
-	/* Send the encrypted session key to the server. */
-	packet_start(SSH_CMSG_SESSION_KEY);
-	packet_put_char(options.cipher);
-
-	/* Send the cookie back to the server. */
-	for (i = 0; i < 8; i++)
-		packet_put_char(cookie[i]);
-
-	/* Send and destroy the encrypted encryption key integer. */
-	packet_put_bignum(key);
-	BN_clear_free(key);
-
-	/* Send protocol flags. */
-	packet_put_int(client_flags);
-
-	/* Send the packet now. */
-	packet_send();
-	packet_write_wait();
-
-	debug("Sent encrypted session key.");
-
-	/* Set the encryption key. */
-	packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, options.cipher);
-
-	/* We will no longer need the session key here.  Destroy any extra copies. */
-	memset(session_key, 0, sizeof(session_key));
-
-	/*
-	 * Expect a success message from the server.  Note that this message
-	 * will be received in encrypted form.
-	 */
-	packet_read_expect(&payload_len, SSH_SMSG_SUCCESS);
-
-	debug("Received encrypted confirmation.");
-}
-
-/*
- * Authenticate user
- */
-void
-ssh_userauth(int host_key_valid, RSA *own_host_key,
-    uid_t original_real_uid, char *host)
-{
-	int i, type;
-	int payload_len;
-	struct passwd *pw;
-	const char *server_user, *local_user;
-
-	/* Get local user name.  Use it as server user if no user name was given. */
-	pw = getpwuid(original_real_uid);
-	if (!pw)
-		fatal("User id %d not found from user database.", original_real_uid);
-	local_user = xstrdup(pw->pw_name);
-	server_user = options.user ? options.user : local_user;
-
-	/* Send the name of the user to log in as on the server. */
-	packet_start(SSH_CMSG_USER);
-	packet_put_string(server_user, strlen(server_user));
-	packet_send();
-	packet_write_wait();
-
-	/*
-	 * The server should respond with success if no authentication is
-	 * needed (the user has no password).  Otherwise the server responds
-	 * with failure.
-	 */
-	type = packet_read(&payload_len);
-
-	/* check whether the connection was accepted without authentication. */
-	if (type == SSH_SMSG_SUCCESS)
-		return;
-	if (type != SSH_SMSG_FAILURE)
-		packet_disconnect("Protocol error: got %d in response to SSH_CMSG_USER",
-				  type);
-
-#ifdef AFS
-	/* Try Kerberos tgt passing if the server supports it. */
-	if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) &&
-	    options.kerberos_tgt_passing) {
-		if (options.cipher == SSH_CIPHER_NONE)
-			log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!");
-		(void) send_kerberos_tgt();
-	}
-	/* Try AFS token passing if the server supports it. */
-	if ((supported_authentications & (1 << SSH_PASS_AFS_TOKEN)) &&
-	    options.afs_token_passing && k_hasafs()) {
-		if (options.cipher == SSH_CIPHER_NONE)
-			log("WARNING: Encryption is disabled! Token will be transmitted in the clear!");
-		send_afs_tokens();
-	}
-#endif /* AFS */
-
-#ifdef KRB4
-	if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) &&
-	    options.kerberos_authentication) {
-		debug("Trying Kerberos authentication.");
-		if (try_kerberos_authentication()) {
-			/* The server should respond with success or failure. */
-			type = packet_read(&payload_len);
-			if (type == SSH_SMSG_SUCCESS)
-				return;
-			if (type != SSH_SMSG_FAILURE)
-				packet_disconnect("Protocol error: got %d in response to Kerberos auth", type);
-		}
-	}
-#endif /* KRB4 */
-
-	/*
-	 * Use rhosts authentication if running in privileged socket and we
-	 * do not wish to remain anonymous.
-	 */
-	if ((supported_authentications & (1 << SSH_AUTH_RHOSTS)) &&
-	    options.rhosts_authentication) {
-		debug("Trying rhosts authentication.");
-		packet_start(SSH_CMSG_AUTH_RHOSTS);
-		packet_put_string(local_user, strlen(local_user));
-		packet_send();
-		packet_write_wait();
-
-		/* The server should respond with success or failure. */
-		type = packet_read(&payload_len);
-		if (type == SSH_SMSG_SUCCESS)
-			return;
-		if (type != SSH_SMSG_FAILURE)
-			packet_disconnect("Protocol error: got %d in response to rhosts auth",
-					  type);
-	}
-	/*
-	 * Try .rhosts or /etc/hosts.equiv authentication with RSA host
-	 * authentication.
-	 */
-	if ((supported_authentications & (1 << SSH_AUTH_RHOSTS_RSA)) &&
-	    options.rhosts_rsa_authentication && host_key_valid) {
-		if (try_rhosts_rsa_authentication(local_user, own_host_key))
-			return;
-	}
-	/* Try RSA authentication if the server supports it. */
-	if ((supported_authentications & (1 << SSH_AUTH_RSA)) &&
-	    options.rsa_authentication) {
-		/*
-		 * Try RSA authentication using the authentication agent. The
-		 * agent is tried first because no passphrase is needed for
-		 * it, whereas identity files may require passphrases.
-		 */
-		if (try_agent_authentication())
-			return;
-
-		/* Try RSA authentication for each identity. */
-		for (i = 0; i < options.num_identity_files; i++)
-			if (try_rsa_authentication(options.identity_files[i]))
-				return;
-	}
-	/* Try skey authentication if the server supports it. */
-	if ((supported_authentications & (1 << SSH_AUTH_TIS)) &&
-	    options.skey_authentication && !options.batch_mode) {
-		if (try_skey_authentication())
-			return;
-	}
-	/* Try password authentication if the server supports it. */
-	if ((supported_authentications & (1 << SSH_AUTH_PASSWORD)) &&
-	    options.password_authentication && !options.batch_mode) {
-		char prompt[80];
 
-		snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ",
-		    server_user, host);
-		if (try_password_authentication(prompt))
-			return;
-	}
-	/* All authentication methods have failed.  Exit with an error message. */
-	fatal("Permission denied.");
-	/* NOTREACHED */
-}
 /*
  * Starts a dialog with the server, and authenticates the current user on the
  * server.  This does not need any extra privileges.  The basic connection
@@ -1966,7 +666,16 @@
 ssh_login(int host_key_valid, RSA *own_host_key, const char *orighost,
     struct sockaddr *hostaddr, uid_t original_real_uid)
 {
+	struct passwd *pw;
 	char *host, *cp;
+	char *server_user, *local_user;
+
+	/* Get local user name.  Use it as server user if no user name was given. */
+	pw = getpwuid(original_real_uid);
+	if (!pw)
+		fatal("User id %d not found from user database.", original_real_uid);
+	local_user = xstrdup(pw->pw_name);
+	server_user = options.user ? options.user : local_user;
 
 	/* Convert the user-supplied hostname into all lowercase. */
 	host = xstrdup(orighost);
@@ -1984,12 +693,9 @@
 	/* authenticate user */
 	if (compat20) {
 		ssh_kex2(host, hostaddr);
-		ssh_userauth2(host_key_valid, own_host_key, original_real_uid, host);
+		ssh_userauth2(server_user, host);
 	} else {
-		supported_authentications = 0;
 		ssh_kex(host, hostaddr);
-		if (supported_authentications == 0)
-			fatal("supported_authentications == 0.");
-		ssh_userauth(host_key_valid, own_host_key, original_real_uid, host);
+		ssh_userauth(local_user, server_user, host, host_key_valid, own_host_key);
 	}
 }