sshconnect1.c revision 60574
169450Smsmith/*
269450Smsmith * Author: Tatu Ylonen <ylo@cs.hut.fi>
3167802Sjkim * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
469450Smsmith *                    All rights reserved
569450Smsmith * Created: Sat Mar 18 22:15:47 1995 ylo
669450Smsmith * Code to connect to a remote host, and to perform the client side of the
769450Smsmith * login (authentication) dialog.
869450Smsmith *
969450Smsmith */
1069450Smsmith
11193267Sjkim#include "includes.h"
1270243SmsmithRCSID("$OpenBSD: sshconnect1.c,v 1.3 2000/05/08 17:12:16 markus Exp $");
1369450Smsmith
1469450Smsmith#include <openssl/bn.h>
1569450Smsmith#include <openssl/dsa.h>
1669450Smsmith#include <openssl/rsa.h>
1769450Smsmith#include <openssl/evp.h>
1869450Smsmith
1969450Smsmith#include "xmalloc.h"
2069450Smsmith#include "rsa.h"
2169450Smsmith#include "ssh.h"
2269450Smsmith#include "buffer.h"
2369450Smsmith#include "packet.h"
2469450Smsmith#include "authfd.h"
2569450Smsmith#include "cipher.h"
2669450Smsmith#include "mpaux.h"
2769450Smsmith#include "uidswap.h"
2869450Smsmith#include "readconf.h"
2969450Smsmith#include "key.h"
3069450Smsmith#include "sshconnect.h"
3169450Smsmith#include "authfile.h"
3269450Smsmith
3369450Smsmith/* Session id for the current session. */
3469450Smsmithunsigned char session_id[16];
3569450Smsmithunsigned int supported_authentications = 0;
3669450Smsmith
3769450Smsmithextern Options options;
3869450Smsmithextern char *__progname;
3969450Smsmith
4069450Smsmith/*
4169450Smsmith * Checks if the user has an authentication agent, and if so, tries to
4269450Smsmith * authenticate using the agent.
4369450Smsmith */
4469450Smsmithint
4569450Smsmithtry_agent_authentication()
4669450Smsmith{
4769450Smsmith	int status, type;
4869450Smsmith	char *comment;
4969450Smsmith	AuthenticationConnection *auth;
5069450Smsmith	unsigned char response[16];
5169450Smsmith	unsigned int i;
5269450Smsmith	BIGNUM *e, *n, *challenge;
5369450Smsmith
5469450Smsmith	/* Get connection to the agent. */
5569450Smsmith	auth = ssh_get_authentication_connection();
5669450Smsmith	if (!auth)
5769450Smsmith		return 0;
5869450Smsmith
5969450Smsmith	e = BN_new();
6069450Smsmith	n = BN_new();
6169450Smsmith	challenge = BN_new();
6269450Smsmith
6369450Smsmith	/* Loop through identities served by the agent. */
6469450Smsmith	for (status = ssh_get_first_identity(auth, e, n, &comment);
6569450Smsmith	     status;
6669450Smsmith	     status = ssh_get_next_identity(auth, e, n, &comment)) {
6769450Smsmith		int plen, clen;
6869450Smsmith
6969450Smsmith		/* Try this identity. */
7069450Smsmith		debug("Trying RSA authentication via agent with '%.100s'", comment);
7169450Smsmith		xfree(comment);
7269450Smsmith
7369450Smsmith		/* Tell the server that we are willing to authenticate using this key. */
7469450Smsmith		packet_start(SSH_CMSG_AUTH_RSA);
7569450Smsmith		packet_put_bignum(n);
7669450Smsmith		packet_send();
7769450Smsmith		packet_write_wait();
7869450Smsmith
7969450Smsmith		/* Wait for server's response. */
8069450Smsmith		type = packet_read(&plen);
8169450Smsmith
8269450Smsmith		/* The server sends failure if it doesn\'t like our key or
8369450Smsmith		   does not support RSA authentication. */
8469450Smsmith		if (type == SSH_SMSG_FAILURE) {
8569450Smsmith			debug("Server refused our key.");
8669450Smsmith			continue;
8769450Smsmith		}
8869450Smsmith		/* Otherwise it should have sent a challenge. */
8969450Smsmith		if (type != SSH_SMSG_AUTH_RSA_CHALLENGE)
9069450Smsmith			packet_disconnect("Protocol error during RSA authentication: %d",
9169450Smsmith					  type);
9269450Smsmith
9369450Smsmith		packet_get_bignum(challenge, &clen);
9469450Smsmith
9569450Smsmith		packet_integrity_check(plen, clen, type);
9669450Smsmith
9769450Smsmith		debug("Received RSA challenge from server.");
9869450Smsmith
9969450Smsmith		/* Ask the agent to decrypt the challenge. */
10069450Smsmith		if (!ssh_decrypt_challenge(auth, e, n, challenge,
10169450Smsmith					   session_id, 1, response)) {
10269450Smsmith			/* The agent failed to authenticate this identifier although it
10369450Smsmith			   advertised it supports this.  Just return a wrong value. */
10469450Smsmith			log("Authentication agent failed to decrypt challenge.");
10569450Smsmith			memset(response, 0, sizeof(response));
10669450Smsmith		}
10769450Smsmith		debug("Sending response to RSA challenge.");
10869450Smsmith
10969450Smsmith		/* Send the decrypted challenge back to the server. */
11069450Smsmith		packet_start(SSH_CMSG_AUTH_RSA_RESPONSE);
11169450Smsmith		for (i = 0; i < 16; i++)
11269450Smsmith			packet_put_char(response[i]);
11369450Smsmith		packet_send();
11469450Smsmith		packet_write_wait();
11569450Smsmith
11669450Smsmith		/* Wait for response from the server. */
11769450Smsmith		type = packet_read(&plen);
11869450Smsmith
119167802Sjkim		/* The server returns success if it accepted the authentication. */
120167802Sjkim		if (type == SSH_SMSG_SUCCESS) {
121167802Sjkim			debug("RSA authentication accepted by server.");
122167802Sjkim			BN_clear_free(e);
123167802Sjkim			BN_clear_free(n);
124167802Sjkim			BN_clear_free(challenge);
125167802Sjkim			return 1;
126167802Sjkim		}
127167802Sjkim		/* Otherwise it should return failure. */
128167802Sjkim		if (type != SSH_SMSG_FAILURE)
129167802Sjkim			packet_disconnect("Protocol error waiting RSA auth response: %d",
130167802Sjkim					  type);
131167802Sjkim	}
132167802Sjkim
133167802Sjkim	BN_clear_free(e);
134167802Sjkim	BN_clear_free(n);
135193267Sjkim	BN_clear_free(challenge);
136167802Sjkim
137167802Sjkim	debug("RSA authentication using agent refused.");
138167802Sjkim	return 0;
139167802Sjkim}
140167802Sjkim
141193267Sjkim/*
142193267Sjkim * Computes the proper response to a RSA challenge, and sends the response to
143193267Sjkim * the server.
144167802Sjkim */
145193267Sjkimvoid
146167802Sjkimrespond_to_rsa_challenge(BIGNUM * challenge, RSA * prv)
147167802Sjkim{
148167802Sjkim	unsigned char buf[32], response[16];
149193267Sjkim	MD5_CTX md;
150167802Sjkim	int i, len;
151167802Sjkim
152167802Sjkim	/* Decrypt the challenge using the private key. */
153167802Sjkim	rsa_private_decrypt(challenge, challenge, prv);
154167802Sjkim
155193267Sjkim	/* Compute the response. */
156193267Sjkim	/* The response is MD5 of decrypted challenge plus session id. */
157167802Sjkim	len = BN_num_bytes(challenge);
158167802Sjkim	if (len <= 0 || len > sizeof(buf))
159167802Sjkim		packet_disconnect("respond_to_rsa_challenge: bad challenge length %d",
160167802Sjkim				  len);
161167802Sjkim
162167802Sjkim	memset(buf, 0, sizeof(buf));
163167802Sjkim	BN_bn2bin(challenge, buf + sizeof(buf) - len);
16469450Smsmith	MD5_Init(&md);
16569450Smsmith	MD5_Update(&md, buf, 32);
16691116Smsmith	MD5_Update(&md, session_id, 16);
167167802Sjkim	MD5_Final(response, &md);
168167802Sjkim
169167802Sjkim	debug("Sending response to host key RSA challenge.");
17091116Smsmith
171167802Sjkim	/* Send the response back to the server. */
172167802Sjkim	packet_start(SSH_CMSG_AUTH_RSA_RESPONSE);
173193267Sjkim	for (i = 0; i < 16; i++)
174167802Sjkim		packet_put_char(response[i]);
175167802Sjkim	packet_send();
17669450Smsmith	packet_write_wait();
177167802Sjkim
178167802Sjkim	memset(buf, 0, sizeof(buf));
179151937Sjkim	memset(response, 0, sizeof(response));
180167802Sjkim	memset(&md, 0, sizeof(md));
18169450Smsmith}
18269450Smsmith
183193267Sjkim/*
184193267Sjkim * Checks if the user has authentication file, and if so, tries to authenticate
185193267Sjkim * the user using it.
186193267Sjkim */
187193267Sjkimint
188193267Sjkimtry_rsa_authentication(const char *authfile)
189193267Sjkim{
190193267Sjkim	BIGNUM *challenge;
191193267Sjkim	Key *public;
192193267Sjkim	Key *private;
193193267Sjkim	char *passphrase, *comment;
194193267Sjkim	int type, i;
195193267Sjkim	int plen, clen;
196193267Sjkim
197193267Sjkim	/* Try to load identification for the authentication key. */
198167802Sjkim	public = key_new(KEY_RSA);
199167802Sjkim	if (!load_public_key(authfile, public, &comment)) {
200167802Sjkim		key_free(public);
201167802Sjkim		/* Could not load it.  Fail. */
202167802Sjkim		return 0;
203167802Sjkim	}
204167802Sjkim	debug("Trying RSA authentication with key '%.100s'", comment);
205167802Sjkim
206167802Sjkim	/* Tell the server that we are willing to authenticate using this key. */
207167802Sjkim	packet_start(SSH_CMSG_AUTH_RSA);
208167802Sjkim	packet_put_bignum(public->rsa->n);
209167802Sjkim	packet_send();
210167802Sjkim	packet_write_wait();
211167802Sjkim
212167802Sjkim	/* We no longer need the public key. */
213167802Sjkim	key_free(public);
214167802Sjkim
215167802Sjkim	/* Wait for server's response. */
216167802Sjkim	type = packet_read(&plen);
217167802Sjkim
218167802Sjkim	/*
219167802Sjkim	 * The server responds with failure if it doesn\'t like our key or
220167802Sjkim	 * doesn\'t support RSA authentication.
221167802Sjkim	 */
222167802Sjkim	if (type == SSH_SMSG_FAILURE) {
223167802Sjkim		debug("Server refused our key.");
224167802Sjkim		xfree(comment);
225167802Sjkim		return 0;
226167802Sjkim	}
227167802Sjkim	/* Otherwise, the server should respond with a challenge. */
228167802Sjkim	if (type != SSH_SMSG_AUTH_RSA_CHALLENGE)
229167802Sjkim		packet_disconnect("Protocol error during RSA authentication: %d", type);
230167802Sjkim
231167802Sjkim	/* Get the challenge from the packet. */
232167802Sjkim	challenge = BN_new();
233167802Sjkim	packet_get_bignum(challenge, &clen);
234167802Sjkim
235167802Sjkim	packet_integrity_check(plen, clen, type);
23691116Smsmith
237167802Sjkim	debug("Received RSA challenge from server.");
23891116Smsmith
239167802Sjkim	private = key_new(KEY_RSA);
240167802Sjkim	/*
241167802Sjkim	 * Load the private key.  Try first with empty passphrase; if it
242167802Sjkim	 * fails, ask for a passphrase.
24369450Smsmith	 */
244167802Sjkim	if (!load_private_key(authfile, "", private, NULL)) {
245167802Sjkim		char buf[300];
246167802Sjkim		snprintf(buf, sizeof buf, "Enter passphrase for RSA key '%.100s': ",
247167802Sjkim		    comment);
248167802Sjkim		if (!options.batch_mode)
249167802Sjkim			passphrase = read_passphrase(buf, 0);
250167802Sjkim		else {
25169450Smsmith			debug("Will not query passphrase for %.100s in batch mode.",
252167802Sjkim			      comment);
253151937Sjkim			passphrase = xstrdup("");
254167802Sjkim		}
255151937Sjkim
256167802Sjkim		/* Load the authentication file using the pasphrase. */
257167802Sjkim		if (!load_private_key(authfile, passphrase, private, NULL)) {
258167802Sjkim			memset(passphrase, 0, strlen(passphrase));
259167802Sjkim			xfree(passphrase);
260167802Sjkim			error("Bad passphrase.");
261167802Sjkim
262167802Sjkim			/* Send a dummy response packet to avoid protocol error. */
263151937Sjkim			packet_start(SSH_CMSG_AUTH_RSA_RESPONSE);
264167802Sjkim			for (i = 0; i < 16; i++)
26569450Smsmith				packet_put_char(0);
266167802Sjkim			packet_send();
267167802Sjkim			packet_write_wait();
268167802Sjkim
269167802Sjkim			/* Expect the server to reject it... */
270167802Sjkim			packet_read_expect(&plen, SSH_SMSG_FAILURE);
271167802Sjkim			xfree(comment);
272167802Sjkim			return 0;
273167802Sjkim		}
274167802Sjkim		/* Destroy the passphrase. */
275167802Sjkim		memset(passphrase, 0, strlen(passphrase));
276167802Sjkim		xfree(passphrase);
277167802Sjkim	}
278167802Sjkim	/* We no longer need the comment. */
279167802Sjkim	xfree(comment);
28069450Smsmith
281167802Sjkim	/* Compute and send a response to the challenge. */
282167802Sjkim	respond_to_rsa_challenge(challenge, private->rsa);
283167802Sjkim
284167802Sjkim	/* Destroy the private key. */
285167802Sjkim	key_free(private);
286167802Sjkim
287167802Sjkim	/* We no longer need the challenge. */
288167802Sjkim	BN_clear_free(challenge);
289167802Sjkim
290167802Sjkim	/* Wait for response from the server. */
291167802Sjkim	type = packet_read(&plen);
292167802Sjkim	if (type == SSH_SMSG_SUCCESS) {
293167802Sjkim		debug("RSA authentication accepted by server.");
294167802Sjkim		return 1;
295167802Sjkim	}
296167802Sjkim	if (type != SSH_SMSG_FAILURE)
297167802Sjkim		packet_disconnect("Protocol error waiting RSA auth response: %d", type);
298167802Sjkim	debug("RSA authentication refused.");
299167802Sjkim	return 0;
300167802Sjkim}
301167802Sjkim
302167802Sjkim/*
303167802Sjkim * Tries to authenticate the user using combined rhosts or /etc/hosts.equiv
304167802Sjkim * authentication and RSA host authentication.
305167802Sjkim */
306167802Sjkimint
307167802Sjkimtry_rhosts_rsa_authentication(const char *local_user, RSA * host_key)
308167802Sjkim{
309167802Sjkim	int type;
310167802Sjkim	BIGNUM *challenge;
311167802Sjkim	int plen, clen;
312167802Sjkim
313167802Sjkim	debug("Trying rhosts or /etc/hosts.equiv with RSA host authentication.");
314167802Sjkim
315167802Sjkim	/* Tell the server that we are willing to authenticate using this key. */
316167802Sjkim	packet_start(SSH_CMSG_AUTH_RHOSTS_RSA);
317167802Sjkim	packet_put_string(local_user, strlen(local_user));
318167802Sjkim	packet_put_int(BN_num_bits(host_key->n));
319167802Sjkim	packet_put_bignum(host_key->e);
320167802Sjkim	packet_put_bignum(host_key->n);
321167802Sjkim	packet_send();
322167802Sjkim	packet_write_wait();
323167802Sjkim
324167802Sjkim	/* Wait for server's response. */
325167802Sjkim	type = packet_read(&plen);
326167802Sjkim
327167802Sjkim	/* The server responds with failure if it doesn't admit our
328167802Sjkim	   .rhosts authentication or doesn't know our host key. */
329167802Sjkim	if (type == SSH_SMSG_FAILURE) {
330167802Sjkim		debug("Server refused our rhosts authentication or host key.");
331193267Sjkim		return 0;
332193267Sjkim	}
333193267Sjkim	/* Otherwise, the server should respond with a challenge. */
334193267Sjkim	if (type != SSH_SMSG_AUTH_RSA_CHALLENGE)
335193267Sjkim		packet_disconnect("Protocol error during RSA authentication: %d", type);
336193267Sjkim
337193267Sjkim	/* Get the challenge from the packet. */
338193267Sjkim	challenge = BN_new();
339193267Sjkim	packet_get_bignum(challenge, &clen);
340193267Sjkim
341193267Sjkim	packet_integrity_check(plen, clen, type);
342193267Sjkim
343193267Sjkim	debug("Received RSA challenge for host key from server.");
344193267Sjkim
345193267Sjkim	/* Compute a response to the challenge. */
346193267Sjkim	respond_to_rsa_challenge(challenge, host_key);
347193267Sjkim
348193267Sjkim	/* We no longer need the challenge. */
349193267Sjkim	BN_clear_free(challenge);
350193267Sjkim
351193267Sjkim	/* Wait for response from the server. */
352193267Sjkim	type = packet_read(&plen);
353193267Sjkim	if (type == SSH_SMSG_SUCCESS) {
354193267Sjkim		debug("Rhosts or /etc/hosts.equiv with RSA host authentication accepted by server.");
355193267Sjkim		return 1;
356193267Sjkim	}
357193267Sjkim	if (type != SSH_SMSG_FAILURE)
358193267Sjkim		packet_disconnect("Protocol error waiting RSA auth response: %d", type);
359193267Sjkim	debug("Rhosts or /etc/hosts.equiv with RSA host authentication refused.");
360193267Sjkim	return 0;
361193267Sjkim}
362193267Sjkim
363193267Sjkim#ifdef KRB4
364193267Sjkimint
365193267Sjkimtry_kerberos_authentication()
366167802Sjkim{
367167802Sjkim	KTEXT_ST auth;		/* Kerberos data */
368167802Sjkim	char *reply;
369167802Sjkim	char inst[INST_SZ];
370167802Sjkim	char *realm;
371167802Sjkim	CREDENTIALS cred;
372167802Sjkim	int r, type, plen;
373167802Sjkim	socklen_t slen;
374167802Sjkim	Key_schedule schedule;
375167802Sjkim	u_long checksum, cksum;
376167802Sjkim	MSG_DAT msg_data;
377167802Sjkim	struct sockaddr_in local, foreign;
378167802Sjkim	struct stat st;
379167802Sjkim
380167802Sjkim	/* Don't do anything if we don't have any tickets. */
381167802Sjkim	if (stat(tkt_string(), &st) < 0)
382167802Sjkim		return 0;
383167802Sjkim
384167802Sjkim	strncpy(inst, (char *) krb_get_phost(get_canonical_hostname()), INST_SZ);
385167802Sjkim
386167802Sjkim	realm = (char *) krb_realmofhost(get_canonical_hostname());
387167802Sjkim	if (!realm) {
388167802Sjkim		debug("Kerberos V4: no realm for %s", get_canonical_hostname());
389167802Sjkim		return 0;
390167802Sjkim	}
391167802Sjkim	/* This can really be anything. */
392167802Sjkim	checksum = (u_long) getpid();
393167802Sjkim
394167802Sjkim	r = krb_mk_req(&auth, KRB4_SERVICE_NAME, inst, realm, checksum);
395167802Sjkim	if (r != KSUCCESS) {
396167802Sjkim		debug("Kerberos V4 krb_mk_req failed: %s", krb_err_txt[r]);
397167802Sjkim		return 0;
398167802Sjkim	}
399167802Sjkim	/* Get session key to decrypt the server's reply with. */
400167802Sjkim	r = krb_get_cred(KRB4_SERVICE_NAME, inst, realm, &cred);
401167802Sjkim	if (r != KSUCCESS) {
402167802Sjkim		debug("get_cred failed: %s", krb_err_txt[r]);
403167802Sjkim		return 0;
404167802Sjkim	}
405167802Sjkim	des_key_sched((des_cblock *) cred.session, schedule);
406167802Sjkim
407167802Sjkim	/* Send authentication info to server. */
408167802Sjkim	packet_start(SSH_CMSG_AUTH_KERBEROS);
409167802Sjkim	packet_put_string((char *) auth.dat, auth.length);
410167802Sjkim	packet_send();
411167802Sjkim	packet_write_wait();
412167802Sjkim
413167802Sjkim	/* Zero the buffer. */
414167802Sjkim	(void) memset(auth.dat, 0, MAX_KTXT_LEN);
415167802Sjkim
416167802Sjkim	slen = sizeof(local);
417167802Sjkim	memset(&local, 0, sizeof(local));
418167802Sjkim	if (getsockname(packet_get_connection_in(),
419167802Sjkim			(struct sockaddr *) & local, &slen) < 0)
420167802Sjkim		debug("getsockname failed: %s", strerror(errno));
421167802Sjkim
422167802Sjkim	slen = sizeof(foreign);
423167802Sjkim	memset(&foreign, 0, sizeof(foreign));
424167802Sjkim	if (getpeername(packet_get_connection_in(),
425193267Sjkim			(struct sockaddr *) & foreign, &slen) < 0) {
426167802Sjkim		debug("getpeername failed: %s", strerror(errno));
427167802Sjkim		fatal_cleanup();
428167802Sjkim	}
429167802Sjkim	/* Get server reply. */
430167802Sjkim	type = packet_read(&plen);
431167802Sjkim	switch (type) {
432167802Sjkim	case SSH_SMSG_FAILURE:
433193267Sjkim		/* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */
434193267Sjkim		debug("Kerberos V4 authentication failed.");
435167802Sjkim		return 0;
436167802Sjkim		break;
437167802Sjkim
438193267Sjkim	case SSH_SMSG_AUTH_KERBEROS_RESPONSE:
439193267Sjkim		/* SSH_SMSG_AUTH_KERBEROS_SUCCESS */
440193267Sjkim		debug("Kerberos V4 authentication accepted.");
441193267Sjkim
442167802Sjkim		/* Get server's response. */
443167802Sjkim		reply = packet_get_string((unsigned int *) &auth.length);
444167802Sjkim		memcpy(auth.dat, reply, auth.length);
445167802Sjkim		xfree(reply);
446167802Sjkim
447167802Sjkim		packet_integrity_check(plen, 4 + auth.length, type);
448167802Sjkim
449167802Sjkim		/*
450167802Sjkim		 * If his response isn't properly encrypted with the session
451167802Sjkim		 * key, and the decrypted checksum fails to match, he's
452167802Sjkim		 * bogus. Bail out.
453167802Sjkim		 */
454167802Sjkim		r = krb_rd_priv(auth.dat, auth.length, schedule, &cred.session,
455167802Sjkim				&foreign, &local, &msg_data);
456167802Sjkim		if (r != KSUCCESS) {
457193267Sjkim			debug("Kerberos V4 krb_rd_priv failed: %s", krb_err_txt[r]);
458193267Sjkim			packet_disconnect("Kerberos V4 challenge failed!");
459167802Sjkim		}
460167802Sjkim		/* Fetch the (incremented) checksum that we supplied in the request. */
461167802Sjkim		(void) memcpy((char *) &cksum, (char *) msg_data.app_data, sizeof(cksum));
462167802Sjkim		cksum = ntohl(cksum);
463167802Sjkim
464167802Sjkim		/* If it matches, we're golden. */
465193267Sjkim		if (cksum == checksum + 1) {
466193267Sjkim			debug("Kerberos V4 challenge successful.");
467167802Sjkim			return 1;
468167802Sjkim		} else
469167802Sjkim			packet_disconnect("Kerberos V4 challenge failed!");
470167802Sjkim		break;
471167802Sjkim
472167802Sjkim	default:
473167802Sjkim		packet_disconnect("Protocol error on Kerberos V4 response: %d", type);
474167802Sjkim	}
475167802Sjkim	return 0;
476167802Sjkim}
477167802Sjkim
478193267Sjkim#endif /* KRB4 */
479193267Sjkim
480193267Sjkim#ifdef AFS
481167802Sjkimint
482167802Sjkimsend_kerberos_tgt()
483193267Sjkim{
484193267Sjkim	CREDENTIALS *creds;
485193267Sjkim	char pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ];
486193267Sjkim	int r, type, plen;
487167802Sjkim	char buffer[8192];
488193267Sjkim	struct stat st;
489193267Sjkim
49091116Smsmith	/* Don't do anything if we don't have any tickets. */
491167802Sjkim	if (stat(tkt_string(), &st) < 0)
49291116Smsmith		return 0;
493167802Sjkim
494167802Sjkim	creds = xmalloc(sizeof(*creds));
495167802Sjkim
496167802Sjkim	if ((r = krb_get_tf_fullname(TKT_FILE, pname, pinst, prealm)) != KSUCCESS) {
49769450Smsmith		debug("Kerberos V4 tf_fullname failed: %s", krb_err_txt[r]);
498167802Sjkim		return 0;
499193267Sjkim	}
500193267Sjkim	if ((r = krb_get_cred("krbtgt", prealm, prealm, creds)) != GC_OK) {
501193267Sjkim		debug("Kerberos V4 get_cred failed: %s", krb_err_txt[r]);
502167802Sjkim		return 0;
50369450Smsmith	}
504167802Sjkim	if (time(0) > krb_life_to_time(creds->issue_date, creds->lifetime)) {
505151937Sjkim		debug("Kerberos V4 ticket expired: %s", TKT_FILE);
506167802Sjkim		return 0;
507151937Sjkim	}
508167802Sjkim	creds_to_radix(creds, (unsigned char *)buffer, sizeof buffer);
50969450Smsmith	xfree(creds);
510167802Sjkim
511167802Sjkim	packet_start(SSH_CMSG_HAVE_KERBEROS_TGT);
512167802Sjkim	packet_put_string(buffer, strlen(buffer));
513167802Sjkim	packet_send();
514167802Sjkim	packet_write_wait();
515193267Sjkim
516193267Sjkim	type = packet_read(&plen);
517193267Sjkim
518167802Sjkim	if (type == SSH_SMSG_FAILURE)
519167802Sjkim		debug("Kerberos TGT for realm %s rejected.", prealm);
520167802Sjkim	else if (type != SSH_SMSG_SUCCESS)
521167802Sjkim		packet_disconnect("Protocol error on Kerberos TGT response: %d", type);
522167802Sjkim
523167802Sjkim	return 1;
524167802Sjkim}
525167802Sjkim
526193267Sjkimvoid
527167802Sjkimsend_afs_tokens(void)
528193267Sjkim{
529193267Sjkim	CREDENTIALS creds;
530193267Sjkim	struct ViceIoctl parms;
531193267Sjkim	struct ClearToken ct;
532193267Sjkim	int i, type, len, plen;
533193267Sjkim	char buf[2048], *p, *server_cell;
534193267Sjkim	char buffer[8192];
535193267Sjkim
536193267Sjkim	/* Move over ktc_GetToken, here's something leaner. */
537193267Sjkim	for (i = 0; i < 100; i++) {	/* just in case */
538193267Sjkim		parms.in = (char *) &i;
539193267Sjkim		parms.in_size = sizeof(i);
540193267Sjkim		parms.out = buf;
541193267Sjkim		parms.out_size = sizeof(buf);
542167802Sjkim		if (k_pioctl(0, VIOCGETTOK, &parms, 0) != 0)
543167802Sjkim			break;
544167802Sjkim		p = buf;
545167802Sjkim
546167802Sjkim		/* Get secret token. */
547167802Sjkim		memcpy(&creds.ticket_st.length, p, sizeof(unsigned int));
548167802Sjkim		if (creds.ticket_st.length > MAX_KTXT_LEN)
549167802Sjkim			break;
550167802Sjkim		p += sizeof(unsigned int);
551167802Sjkim		memcpy(creds.ticket_st.dat, p, creds.ticket_st.length);
552167802Sjkim		p += creds.ticket_st.length;
553167802Sjkim
554167802Sjkim		/* Get clear token. */
555167802Sjkim		memcpy(&len, p, sizeof(len));
556167802Sjkim		if (len != sizeof(struct ClearToken))
557167802Sjkim			break;
558167802Sjkim		p += sizeof(len);
559167802Sjkim		memcpy(&ct, p, len);
560167802Sjkim		p += len;
561167802Sjkim		p += sizeof(len);	/* primary flag */
562193267Sjkim		server_cell = p;
563193267Sjkim
564193267Sjkim		/* Flesh out our credentials. */
565193267Sjkim		strlcpy(creds.service, "afs", sizeof creds.service);
566193267Sjkim		creds.instance[0] = '\0';
567193267Sjkim		strlcpy(creds.realm, server_cell, REALM_SZ);
568193267Sjkim		memcpy(creds.session, ct.HandShakeKey, DES_KEY_SZ);
569193267Sjkim		creds.issue_date = ct.BeginTimestamp;
570193267Sjkim		creds.lifetime = krb_time_to_life(creds.issue_date, ct.EndTimestamp);
571193267Sjkim		creds.kvno = ct.AuthHandle;
572193267Sjkim		snprintf(creds.pname, sizeof(creds.pname), "AFS ID %d", ct.ViceId);
573193267Sjkim		creds.pinst[0] = '\0';
574193267Sjkim
575193267Sjkim		/* Encode token, ship it off. */
576193267Sjkim		if (creds_to_radix(&creds, (unsigned char*) buffer, sizeof buffer) <= 0)
577193267Sjkim			break;
578193267Sjkim		packet_start(SSH_CMSG_HAVE_AFS_TOKEN);
579193267Sjkim		packet_put_string(buffer, strlen(buffer));
580193267Sjkim		packet_send();
581193267Sjkim		packet_write_wait();
582193267Sjkim
583193267Sjkim		/* Roger, Roger. Clearance, Clarence. What's your vector,
584193267Sjkim		   Victor? */
585193267Sjkim		type = packet_read(&plen);
586193267Sjkim
587193267Sjkim		if (type == SSH_SMSG_FAILURE)
588193267Sjkim			debug("AFS token for cell %s rejected.", server_cell);
589193267Sjkim		else if (type != SSH_SMSG_SUCCESS)
590193267Sjkim			packet_disconnect("Protocol error on AFS token response: %d", type);
591193267Sjkim	}
592193267Sjkim}
593193267Sjkim
594193267Sjkim#endif /* AFS */
595193267Sjkim
596193267Sjkim/*
597193267Sjkim * Tries to authenticate with any string-based challenge/response system.
598193267Sjkim * Note that the client code is not tied to s/key or TIS.
599193267Sjkim */
600193267Sjkimint
601193267Sjkimtry_skey_authentication()
602193267Sjkim{
603193267Sjkim	int type, i;
604193267Sjkim	int payload_len;
605193267Sjkim	unsigned int clen;
606193267Sjkim	char *challenge, *response;
607193267Sjkim
608193267Sjkim	debug("Doing skey authentication.");
609193267Sjkim
610193267Sjkim	/* request a challenge */
611193267Sjkim	packet_start(SSH_CMSG_AUTH_TIS);
612193267Sjkim	packet_send();
613193267Sjkim	packet_write_wait();
614193267Sjkim
615193267Sjkim	type = packet_read(&payload_len);
616193267Sjkim	if (type != SSH_SMSG_FAILURE &&
617193267Sjkim	    type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
618193267Sjkim		packet_disconnect("Protocol error: got %d in response "
619193267Sjkim				  "to skey-auth", type);
620193267Sjkim	}
621193267Sjkim	if (type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
622193267Sjkim		debug("No challenge for skey authentication.");
623193267Sjkim		return 0;
624193267Sjkim	}
625193267Sjkim	challenge = packet_get_string(&clen);
626193267Sjkim	packet_integrity_check(payload_len, (4 + clen), type);
627193267Sjkim	if (options.cipher == SSH_CIPHER_NONE)
628193267Sjkim		log("WARNING: Encryption is disabled! "
629193267Sjkim		    "Reponse will be transmitted in clear text.");
630193267Sjkim	fprintf(stderr, "%s\n", challenge);
631193267Sjkim	xfree(challenge);
632193267Sjkim	fflush(stderr);
633193267Sjkim	for (i = 0; i < options.number_of_password_prompts; i++) {
634193267Sjkim		if (i != 0)
635193267Sjkim			error("Permission denied, please try again.");
636193267Sjkim		response = read_passphrase("Response: ", 0);
637193267Sjkim		packet_start(SSH_CMSG_AUTH_TIS_RESPONSE);
638193267Sjkim		packet_put_string(response, strlen(response));
639193267Sjkim		memset(response, 0, strlen(response));
640193267Sjkim		xfree(response);
641193267Sjkim		packet_send();
642193267Sjkim		packet_write_wait();
643193267Sjkim		type = packet_read(&payload_len);
644193267Sjkim		if (type == SSH_SMSG_SUCCESS)
645193267Sjkim			return 1;
646193267Sjkim		if (type != SSH_SMSG_FAILURE)
647193267Sjkim			packet_disconnect("Protocol error: got %d in response "
648193267Sjkim					  "to skey-auth-reponse", type);
649193267Sjkim	}
650193267Sjkim	/* failure */
651193267Sjkim	return 0;
652193267Sjkim}
653193267Sjkim
654193267Sjkim/*
655193267Sjkim * Tries to authenticate with plain passwd authentication.
656193267Sjkim */
657193267Sjkimint
658193267Sjkimtry_password_authentication(char *prompt)
659193267Sjkim{
660193267Sjkim	int type, i, payload_len;
661193267Sjkim	char *password;
662193267Sjkim
663193267Sjkim	debug("Doing password authentication.");
664193267Sjkim	if (options.cipher == SSH_CIPHER_NONE)
665193267Sjkim		log("WARNING: Encryption is disabled! Password will be transmitted in clear text.");
666193267Sjkim	for (i = 0; i < options.number_of_password_prompts; i++) {
667193267Sjkim		if (i != 0)
668193267Sjkim			error("Permission denied, please try again.");
669193267Sjkim		password = read_passphrase(prompt, 0);
670193267Sjkim		packet_start(SSH_CMSG_AUTH_PASSWORD);
671193267Sjkim		packet_put_string(password, strlen(password));
672193267Sjkim		memset(password, 0, strlen(password));
673193267Sjkim		xfree(password);
674193267Sjkim		packet_send();
675193267Sjkim		packet_write_wait();
676193267Sjkim
677193267Sjkim		type = packet_read(&payload_len);
678193267Sjkim		if (type == SSH_SMSG_SUCCESS)
679193267Sjkim			return 1;
680193267Sjkim		if (type != SSH_SMSG_FAILURE)
681193267Sjkim			packet_disconnect("Protocol error: got %d in response to passwd auth", type);
682193267Sjkim	}
683193267Sjkim	/* failure */
684193267Sjkim	return 0;
685193267Sjkim}
686193267Sjkim
687193267Sjkim/*
688193267Sjkim * SSH1 key exchange
689193267Sjkim */
690193267Sjkimvoid
691193267Sjkimssh_kex(char *host, struct sockaddr *hostaddr)
692193267Sjkim{
693193267Sjkim	int i;
694193267Sjkim	BIGNUM *key;
695193267Sjkim	RSA *host_key;
696193267Sjkim	RSA *public_key;
697193267Sjkim	Key k;
698193267Sjkim	int bits, rbits;
699193267Sjkim	int ssh_cipher_default = SSH_CIPHER_3DES;
700193267Sjkim	unsigned char session_key[SSH_SESSION_KEY_LENGTH];
701193267Sjkim	unsigned char cookie[8];
702193267Sjkim	unsigned int supported_ciphers;
703193267Sjkim	unsigned int server_flags, client_flags;
704193267Sjkim	int payload_len, clen, sum_len = 0;
705193267Sjkim	u_int32_t rand = 0;
706193267Sjkim
707193267Sjkim	debug("Waiting for server public key.");
708193267Sjkim
709193267Sjkim	/* Wait for a public key packet from the server. */
710193267Sjkim	packet_read_expect(&payload_len, SSH_SMSG_PUBLIC_KEY);
711193267Sjkim
712193267Sjkim	/* Get cookie from the packet. */
713193267Sjkim	for (i = 0; i < 8; i++)
714193267Sjkim		cookie[i] = packet_get_char();
715193267Sjkim
716193267Sjkim	/* Get the public key. */
717193267Sjkim	public_key = RSA_new();
718193267Sjkim	bits = packet_get_int();/* bits */
719193267Sjkim	public_key->e = BN_new();
720193267Sjkim	packet_get_bignum(public_key->e, &clen);
721193267Sjkim	sum_len += clen;
722193267Sjkim	public_key->n = BN_new();
723193267Sjkim	packet_get_bignum(public_key->n, &clen);
724193267Sjkim	sum_len += clen;
725193267Sjkim
726193267Sjkim	rbits = BN_num_bits(public_key->n);
727193267Sjkim	if (bits != rbits) {
728193267Sjkim		log("Warning: Server lies about size of server public key: "
729193267Sjkim		    "actual size is %d bits vs. announced %d.", rbits, bits);
730193267Sjkim		log("Warning: This may be due to an old implementation of ssh.");
731193267Sjkim	}
732193267Sjkim	/* Get the host key. */
733193267Sjkim	host_key = RSA_new();
734193267Sjkim	bits = packet_get_int();/* bits */
735193267Sjkim	host_key->e = BN_new();
736193267Sjkim	packet_get_bignum(host_key->e, &clen);
737193267Sjkim	sum_len += clen;
738193267Sjkim	host_key->n = BN_new();
739193267Sjkim	packet_get_bignum(host_key->n, &clen);
740193267Sjkim	sum_len += clen;
741193267Sjkim
742193267Sjkim	rbits = BN_num_bits(host_key->n);
743193267Sjkim	if (bits != rbits) {
744193267Sjkim		log("Warning: Server lies about size of server host key: "
745193267Sjkim		    "actual size is %d bits vs. announced %d.", rbits, bits);
746193267Sjkim		log("Warning: This may be due to an old implementation of ssh.");
747193267Sjkim	}
748193267Sjkim
749193267Sjkim	/* Get protocol flags. */
750193267Sjkim	server_flags = packet_get_int();
751193267Sjkim	packet_set_protocol_flags(server_flags);
752193267Sjkim
753193267Sjkim	supported_ciphers = packet_get_int();
754193267Sjkim	supported_authentications = packet_get_int();
755193267Sjkim
756193267Sjkim	debug("Received server public key (%d bits) and host key (%d bits).",
757193267Sjkim	      BN_num_bits(public_key->n), BN_num_bits(host_key->n));
758193267Sjkim
759193267Sjkim	packet_integrity_check(payload_len,
760193267Sjkim			       8 + 4 + sum_len + 0 + 4 + 0 + 0 + 4 + 4 + 4,
761193267Sjkim			       SSH_SMSG_PUBLIC_KEY);
762193267Sjkim	k.type = KEY_RSA;
763193267Sjkim	k.rsa = host_key;
764193267Sjkim	check_host_key(host, hostaddr, &k,
765193267Sjkim	    options.user_hostfile, options.system_hostfile);
766193267Sjkim
767193267Sjkim	client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN;
768193267Sjkim
769193267Sjkim	compute_session_id(session_id, cookie, host_key->n, public_key->n);
770193267Sjkim
771193267Sjkim	/* Generate a session key. */
772193267Sjkim	arc4random_stir();
773193267Sjkim
774193267Sjkim	/*
775193267Sjkim	 * Generate an encryption key for the session.   The key is a 256 bit
776193267Sjkim	 * random number, interpreted as a 32-byte key, with the least
777193267Sjkim	 * significant 8 bits being the first byte of the key.
778193267Sjkim	 */
779193267Sjkim	for (i = 0; i < 32; i++) {
780193267Sjkim		if (i % 4 == 0)
781193267Sjkim			rand = arc4random();
782193267Sjkim		session_key[i] = rand & 0xff;
783193267Sjkim		rand >>= 8;
784193267Sjkim	}
785193267Sjkim
786193267Sjkim	/*
787193267Sjkim	 * According to the protocol spec, the first byte of the session key
788193267Sjkim	 * is the highest byte of the integer.  The session key is xored with
789193267Sjkim	 * the first 16 bytes of the session id.
790193267Sjkim	 */
791193267Sjkim	key = BN_new();
792193267Sjkim	BN_set_word(key, 0);
793193267Sjkim	for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) {
794193267Sjkim		BN_lshift(key, key, 8);
795193267Sjkim		if (i < 16)
796193267Sjkim			BN_add_word(key, session_key[i] ^ session_id[i]);
797193267Sjkim		else
798193267Sjkim			BN_add_word(key, session_key[i]);
799193267Sjkim	}
800193267Sjkim
801193267Sjkim	/*
802193267Sjkim	 * Encrypt the integer using the public key and host key of the
803193267Sjkim	 * server (key with smaller modulus first).
804193267Sjkim	 */
805193267Sjkim	if (BN_cmp(public_key->n, host_key->n) < 0) {
806193267Sjkim		/* Public key has smaller modulus. */
807193267Sjkim		if (BN_num_bits(host_key->n) <
808193267Sjkim		    BN_num_bits(public_key->n) + SSH_KEY_BITS_RESERVED) {
809193267Sjkim			fatal("respond_to_rsa_challenge: host_key %d < public_key %d + "
810193267Sjkim			      "SSH_KEY_BITS_RESERVED %d",
811193267Sjkim			      BN_num_bits(host_key->n),
812193267Sjkim			      BN_num_bits(public_key->n),
813193267Sjkim			      SSH_KEY_BITS_RESERVED);
814193267Sjkim		}
815193267Sjkim		rsa_public_encrypt(key, key, public_key);
816193267Sjkim		rsa_public_encrypt(key, key, host_key);
817193267Sjkim	} else {
818193267Sjkim		/* Host key has smaller modulus (or they are equal). */
819193267Sjkim		if (BN_num_bits(public_key->n) <
820193267Sjkim		    BN_num_bits(host_key->n) + SSH_KEY_BITS_RESERVED) {
821193267Sjkim			fatal("respond_to_rsa_challenge: public_key %d < host_key %d + "
822193267Sjkim			      "SSH_KEY_BITS_RESERVED %d",
823193267Sjkim			      BN_num_bits(public_key->n),
824193267Sjkim			      BN_num_bits(host_key->n),
825193267Sjkim			      SSH_KEY_BITS_RESERVED);
826193267Sjkim		}
827193267Sjkim		rsa_public_encrypt(key, key, host_key);
828193267Sjkim		rsa_public_encrypt(key, key, public_key);
829193267Sjkim	}
830193267Sjkim
831193267Sjkim	/* Destroy the public keys since we no longer need them. */
832193267Sjkim	RSA_free(public_key);
833193267Sjkim	RSA_free(host_key);
834193267Sjkim
835193267Sjkim	if (options.cipher == SSH_CIPHER_ILLEGAL) {
836193267Sjkim		log("No valid SSH1 cipher, using %.100s instead.",
837193267Sjkim		    cipher_name(SSH_FALLBACK_CIPHER));
838193267Sjkim		options.cipher = SSH_FALLBACK_CIPHER;
839193267Sjkim	} else if (options.cipher == SSH_CIPHER_NOT_SET) {
840193267Sjkim		if (cipher_mask1() & supported_ciphers & (1 << ssh_cipher_default))
841193267Sjkim			options.cipher = ssh_cipher_default;
842193267Sjkim		else {
843193267Sjkim			debug("Cipher %s not supported, using %.100s instead.",
844193267Sjkim			    cipher_name(ssh_cipher_default),
845193267Sjkim			    cipher_name(SSH_FALLBACK_CIPHER));
846193267Sjkim			options.cipher = SSH_FALLBACK_CIPHER;
847193267Sjkim		}
848193267Sjkim	}
849193267Sjkim	/* Check that the selected cipher is supported. */
850193267Sjkim	if (!(supported_ciphers & (1 << options.cipher)))
851193267Sjkim		fatal("Selected cipher type %.100s not supported by server.",
852193267Sjkim		      cipher_name(options.cipher));
853193267Sjkim
854193267Sjkim	debug("Encryption type: %.100s", cipher_name(options.cipher));
855193267Sjkim
856193267Sjkim	/* Send the encrypted session key to the server. */
857193267Sjkim	packet_start(SSH_CMSG_SESSION_KEY);
858193267Sjkim	packet_put_char(options.cipher);
859193267Sjkim
860193267Sjkim	/* Send the cookie back to the server. */
861193267Sjkim	for (i = 0; i < 8; i++)
862193267Sjkim		packet_put_char(cookie[i]);
863193267Sjkim
864193267Sjkim	/* Send and destroy the encrypted encryption key integer. */
865193267Sjkim	packet_put_bignum(key);
866193267Sjkim	BN_clear_free(key);
867193267Sjkim
868193267Sjkim	/* Send protocol flags. */
869193267Sjkim	packet_put_int(client_flags);
870193267Sjkim
871193267Sjkim	/* Send the packet now. */
872193267Sjkim	packet_send();
873193267Sjkim	packet_write_wait();
874193267Sjkim
875193267Sjkim	debug("Sent encrypted session key.");
876193267Sjkim
877193267Sjkim	/* Set the encryption key. */
878193267Sjkim	packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, options.cipher);
879193267Sjkim
880193267Sjkim	/* We will no longer need the session key here.  Destroy any extra copies. */
881193267Sjkim	memset(session_key, 0, sizeof(session_key));
882193267Sjkim
883193267Sjkim	/*
884193267Sjkim	 * Expect a success message from the server.  Note that this message
885193267Sjkim	 * will be received in encrypted form.
886193267Sjkim	 */
887193267Sjkim	packet_read_expect(&payload_len, SSH_SMSG_SUCCESS);
888193267Sjkim
889193267Sjkim	debug("Received encrypted confirmation.");
890193267Sjkim}
891193267Sjkim
892193267Sjkim/*
893193267Sjkim * Authenticate user
894193267Sjkim */
895193267Sjkimvoid
896193267Sjkimssh_userauth(
897193267Sjkim    const char* local_user,
898193267Sjkim    const char* server_user,
899193267Sjkim    char *host,
900193267Sjkim    int host_key_valid, RSA *own_host_key)
901193267Sjkim{
902193267Sjkim	int i, type;
903193267Sjkim	int payload_len;
904193267Sjkim
905193267Sjkim	if (supported_authentications == 0)
906193267Sjkim		fatal("ssh_userauth: server supports no auth methods");
907193267Sjkim
908193267Sjkim	/* Send the name of the user to log in as on the server. */
909193267Sjkim	packet_start(SSH_CMSG_USER);
910193267Sjkim	packet_put_string(server_user, strlen(server_user));
911193267Sjkim	packet_send();
912193267Sjkim	packet_write_wait();
913193267Sjkim
914193267Sjkim	/*
915193267Sjkim	 * The server should respond with success if no authentication is
916193267Sjkim	 * needed (the user has no password).  Otherwise the server responds
917193267Sjkim	 * with failure.
918193267Sjkim	 */
919193267Sjkim	type = packet_read(&payload_len);
920193267Sjkim
921193267Sjkim	/* check whether the connection was accepted without authentication. */
922193267Sjkim	if (type == SSH_SMSG_SUCCESS)
923193267Sjkim		return;
924193267Sjkim	if (type != SSH_SMSG_FAILURE)
925193267Sjkim		packet_disconnect("Protocol error: got %d in response to SSH_CMSG_USER",
926193267Sjkim				  type);
927193267Sjkim
928193267Sjkim#ifdef AFS
929193267Sjkim	/* Try Kerberos tgt passing if the server supports it. */
930193267Sjkim	if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) &&
931193267Sjkim	    options.kerberos_tgt_passing) {
932193267Sjkim		if (options.cipher == SSH_CIPHER_NONE)
933193267Sjkim			log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!");
934193267Sjkim		(void) send_kerberos_tgt();
935193267Sjkim	}
936193267Sjkim	/* Try AFS token passing if the server supports it. */
937193267Sjkim	if ((supported_authentications & (1 << SSH_PASS_AFS_TOKEN)) &&
938193267Sjkim	    options.afs_token_passing && k_hasafs()) {
939193267Sjkim		if (options.cipher == SSH_CIPHER_NONE)
940193267Sjkim			log("WARNING: Encryption is disabled! Token will be transmitted in the clear!");
941193267Sjkim		send_afs_tokens();
942193267Sjkim	}
943193267Sjkim#endif /* AFS */
944193267Sjkim
945193267Sjkim#ifdef KRB4
946193267Sjkim	if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) &&
947193267Sjkim	    options.kerberos_authentication) {
948193267Sjkim		debug("Trying Kerberos authentication.");
949193267Sjkim		if (try_kerberos_authentication()) {
950193267Sjkim			/* The server should respond with success or failure. */
951193267Sjkim			type = packet_read(&payload_len);
952193267Sjkim			if (type == SSH_SMSG_SUCCESS)
953193267Sjkim				return;
954193267Sjkim			if (type != SSH_SMSG_FAILURE)
955193267Sjkim				packet_disconnect("Protocol error: got %d in response to Kerberos auth", type);
956193267Sjkim		}
957193267Sjkim	}
958193267Sjkim#endif /* KRB4 */
959193267Sjkim
960193267Sjkim	/*
961193267Sjkim	 * Use rhosts authentication if running in privileged socket and we
962193267Sjkim	 * do not wish to remain anonymous.
963193267Sjkim	 */
964193267Sjkim	if ((supported_authentications & (1 << SSH_AUTH_RHOSTS)) &&
965193267Sjkim	    options.rhosts_authentication) {
966193267Sjkim		debug("Trying rhosts authentication.");
967193267Sjkim		packet_start(SSH_CMSG_AUTH_RHOSTS);
968193267Sjkim		packet_put_string(local_user, strlen(local_user));
969193267Sjkim		packet_send();
970193267Sjkim		packet_write_wait();
971193267Sjkim
972193267Sjkim		/* The server should respond with success or failure. */
973193267Sjkim		type = packet_read(&payload_len);
974193267Sjkim		if (type == SSH_SMSG_SUCCESS)
975167802Sjkim			return;
976167802Sjkim		if (type != SSH_SMSG_FAILURE)
977167802Sjkim			packet_disconnect("Protocol error: got %d in response to rhosts auth",
978167802Sjkim					  type);
979167802Sjkim	}
980167802Sjkim	/*
981167802Sjkim	 * Try .rhosts or /etc/hosts.equiv authentication with RSA host
982167802Sjkim	 * authentication.
983167802Sjkim	 */
984167802Sjkim	if ((supported_authentications & (1 << SSH_AUTH_RHOSTS_RSA)) &&
985167802Sjkim	    options.rhosts_rsa_authentication && host_key_valid) {
986167802Sjkim		if (try_rhosts_rsa_authentication(local_user, own_host_key))
987167802Sjkim			return;
988167802Sjkim	}
989167802Sjkim	/* Try RSA authentication if the server supports it. */
990167802Sjkim	if ((supported_authentications & (1 << SSH_AUTH_RSA)) &&
991167802Sjkim	    options.rsa_authentication) {
992167802Sjkim		/*
993167802Sjkim		 * Try RSA authentication using the authentication agent. The
994167802Sjkim		 * agent is tried first because no passphrase is needed for
995167802Sjkim		 * it, whereas identity files may require passphrases.
996167802Sjkim		 */
997167802Sjkim		if (try_agent_authentication())
998167802Sjkim			return;
999167802Sjkim
1000167802Sjkim		/* Try RSA authentication for each identity. */
1001193267Sjkim		for (i = 0; i < options.num_identity_files; i++)
1002193267Sjkim			if (try_rsa_authentication(options.identity_files[i]))
1003193267Sjkim				return;
1004193267Sjkim	}
1005193267Sjkim	/* Try skey authentication if the server supports it. */
1006193267Sjkim	if ((supported_authentications & (1 << SSH_AUTH_TIS)) &&
1007193267Sjkim	    options.skey_authentication && !options.batch_mode) {
1008193267Sjkim		if (try_skey_authentication())
1009193267Sjkim			return;
1010193267Sjkim	}
1011193267Sjkim	/* Try password authentication if the server supports it. */
1012193267Sjkim	if ((supported_authentications & (1 << SSH_AUTH_PASSWORD)) &&
1013193267Sjkim	    options.password_authentication && !options.batch_mode) {
1014193267Sjkim		char prompt[80];
1015193267Sjkim
1016193267Sjkim		snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ",
1017193267Sjkim		    server_user, host);
1018193267Sjkim		if (try_password_authentication(prompt))
1019193267Sjkim			return;
1020193267Sjkim	}
1021193267Sjkim	/* All authentication methods have failed.  Exit with an error message. */
1022193267Sjkim	fatal("Permission denied.");
1023193267Sjkim	/* NOTREACHED */
1024193267Sjkim}
1025193267Sjkim