/*

sshconnect.c

Author: Tatu Ylonen <ylo@cs.hut.fi>

Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
                   All rights reserved

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.

*/

#include "includes.h"
RCSID("$Id: sshconnect.c,v 1.1 1999/10/27 03:42:45 damien Exp $");

#include <openssl/bn.h>
#include "xmalloc.h"
#include "rsa.h"
#include "ssh.h"
#include "packet.h"
#include "authfd.h"
#include "cipher.h"
#include "mpaux.h"
#include "uidswap.h"
#include "compat.h"

#include <openssl/md5.h>

/* Session id for the current session. */
unsigned char session_id[16];

/* Connect to the given ssh server using a proxy command. */

int
ssh_proxy_connect(const char *host, int port, uid_t original_real_uid,
		  const char *proxy_command)
{
  Buffer command;
  const char *cp;
  char *command_string;
  int pin[2], pout[2];
  int pid;
  char portstring[100];

  /* Convert the port number into a string. */
  snprintf(portstring, sizeof portstring, "%d", port);

  /* Build the final command string in the buffer by making the appropriate
     substitutions to the given proxy command. */
  buffer_init(&command);
  for (cp = proxy_command; *cp; cp++)
    {
      if (cp[0] == '%' && cp[1] == '%')
	{
	  buffer_append(&command, "%", 1);
	  cp++;
	  continue;
	}
      if (cp[0] == '%' && cp[1] == 'h')
	{
	  buffer_append(&command, host, strlen(host));
	  cp++;
	  continue;
	}
      if (cp[0] == '%' && cp[1] == 'p')
	{
	  buffer_append(&command, portstring, strlen(portstring));
	  cp++;
	  continue;
	}
      buffer_append(&command, cp, 1);
    }
  buffer_append(&command, "\0", 1);

  /* Get the final command string. */
  command_string = buffer_ptr(&command);

  /* Create pipes for communicating with the proxy. */
  if (pipe(pin) < 0 || pipe(pout) < 0)
    fatal("Could not create pipes to communicate with the proxy: %.100s",
	  strerror(errno));

  debug("Executing proxy command: %.500s", command_string);

  /* Fork and execute the proxy command. */
  if ((pid = fork()) == 0)
    {
      char *argv[10];

      /* Child.  Permanently give up superuser privileges. */
      permanently_set_uid(original_real_uid);

      /* Redirect stdin and stdout. */
      close(pin[1]);
      if (pin[0] != 0)
	{
	  if (dup2(pin[0], 0) < 0)
	    perror("dup2 stdin");
	  close(pin[0]);
	}
      close(pout[0]);
      if (dup2(pout[1], 1) < 0)
	perror("dup2 stdout");
      close(pout[1]); /* Cannot be 1 because pin allocated two descriptors. */

      /* Stderr is left as it is so that error messages get printed on
	 the user's terminal. */
      argv[0] = "/bin/sh";
      argv[1] = "-c";
      argv[2] = command_string;
      argv[3] = NULL;
      
      /* Execute the proxy command.  Note that we gave up any extra 
	 privileges above. */
      execv("/bin/sh", argv);
      perror("/bin/sh");
      exit(1);
    }
  /* Parent. */
  if (pid < 0)
    fatal("fork failed: %.100s", strerror(errno));
  
  /* Close child side of the descriptors. */
  close(pin[0]);
  close(pout[1]);

  /* Free the command name. */
  buffer_free(&command);
  
  /* Set the connection file descriptors. */
  packet_set_connection(pout[0], pin[1]);

  return 1;
}

/* Creates a (possibly privileged) socket for use as the ssh connection. */

int ssh_create_socket(uid_t original_real_uid, int privileged)
{
  int sock;

  /* If we are running as root and want to connect to a privileged port,
     bind our own socket to a privileged port. */
  if (privileged)
    {
      int p = IPPORT_RESERVED - 1;

      sock = rresvport(&p);
      if (sock < 0)
        fatal("rresvport: %.100s", strerror(errno));
      debug("Allocated local port %d.", p);
    }
  else
    { 
      /* Just create an ordinary socket on arbitrary port.  We use the
	 user's uid to create the socket. */
      temporarily_use_uid(original_real_uid);
      sock = socket(AF_INET, SOCK_STREAM, 0);
      if (sock < 0)
	fatal("socket: %.100s", strerror(errno));
      restore_uid();
    }
  return sock;
}

/* Opens a TCP/IP connection to the remote server on the given host.  If
   port is 0, the default port will be used.  If anonymous is zero,
   a privileged port will be allocated to make the connection. 
   This requires super-user privileges if anonymous is false. 
   Connection_attempts specifies the maximum number of tries (one per
   second).  If proxy_command is non-NULL, it specifies the command (with %h 
   and %p substituted for host and port, respectively) to use to contact
   the daemon. */

int ssh_connect(const char *host, struct sockaddr_in *hostaddr,
		int port, int connection_attempts,
		int anonymous, uid_t original_real_uid, 
		const char *proxy_command)
{
  int sock = -1, attempt, i;
  int on = 1;
  struct servent *sp;
  struct hostent *hp;
  struct linger linger;

  debug("ssh_connect: getuid %d geteuid %d anon %d", 
	(int)getuid(), (int)geteuid(), anonymous);

  /* Get default port if port has not been set. */
  if (port == 0)
    {
      sp = getservbyname(SSH_SERVICE_NAME, "tcp");
      if (sp)
	port = ntohs(sp->s_port);
      else
	port = SSH_DEFAULT_PORT;
    }

  /* If a proxy command is given, connect using it. */
  if (proxy_command != NULL)
    return ssh_proxy_connect(host, port, original_real_uid, proxy_command);

  /* No proxy command. */

  /* No host lookup made yet. */
  hp = NULL;
  
  /* Try to connect several times.  On some machines, the first time will
     sometimes fail.  In general socket code appears to behave quite
     magically on many machines. */
  for (attempt = 0; attempt < connection_attempts; attempt++)
    {
      if (attempt > 0)
	debug("Trying again...");

      /* Try to parse the host name as a numeric inet address. */
      memset(hostaddr, 0, sizeof(hostaddr));
      hostaddr->sin_family = AF_INET;
      hostaddr->sin_port = htons(port);
      hostaddr->sin_addr.s_addr = inet_addr(host);
      if ((hostaddr->sin_addr.s_addr & 0xffffffff) != 0xffffffff)
	{ 
	  /* Valid numeric IP address */
	  debug("Connecting to %.100s port %d.", 
		inet_ntoa(hostaddr->sin_addr), port);
      
	  /* Create a socket. */
	  sock = ssh_create_socket(original_real_uid, 
				   !anonymous && geteuid() == 0 && 
				     port < IPPORT_RESERVED);
      
	  /* Connect to the host.  We use the user's uid in the hope that
	     it will help with the problems of tcp_wrappers showing the
	     remote uid as root. */
	  temporarily_use_uid(original_real_uid);
	  if (connect(sock, (struct sockaddr *)hostaddr, sizeof(*hostaddr))
	      >= 0)
	    {
	      /* Successful connect. */
	      restore_uid();
	      break;
	    }
	  debug("connect: %.100s", strerror(errno));
	  restore_uid();

	  /* Destroy the failed socket. */
	  shutdown(sock, SHUT_RDWR);
	  close(sock);
	}
      else
	{ 
	  /* Not a valid numeric inet address. */
	  /* Map host name to an address. */
	  if (!hp)
	    hp = gethostbyname(host);
	  if (!hp)
	    fatal("Bad host name: %.100s", host);
	  if (!hp->h_addr_list[0])
	    fatal("Host does not have an IP address: %.100s", host);

	  /* Loop through addresses for this host, and try each one in
	     sequence until the connection succeeds. */
	  for (i = 0; hp->h_addr_list[i]; i++)
	    {
	      /* Set the address to connect to. */
	      hostaddr->sin_family = hp->h_addrtype;
	      memcpy(&hostaddr->sin_addr, hp->h_addr_list[i],
		     sizeof(hostaddr->sin_addr));

	      debug("Connecting to %.200s [%.100s] port %d.",
		    host, inet_ntoa(hostaddr->sin_addr), port);

	      /* Create a socket for connecting. */
	      sock = ssh_create_socket(original_real_uid, 
				       !anonymous && geteuid() == 0 && 
				         port < IPPORT_RESERVED);

	      /* Connect to the host.  We use the user's uid in the hope that
	         it will help with tcp_wrappers showing the remote uid as
		 root. */
	      temporarily_use_uid(original_real_uid);
	      if (connect(sock, (struct sockaddr *)hostaddr, 
			  sizeof(*hostaddr)) >= 0)
		{
		  /* Successful connection. */
		  restore_uid();
		  break;
		}
	      debug("connect: %.100s", strerror(errno));
	      restore_uid();

	      /* Close the failed socket; there appear to be some problems 
		 when reusing a socket for which connect() has already 
		 returned an error. */
	      shutdown(sock, SHUT_RDWR);
	      close(sock);
	    }
	  if (hp->h_addr_list[i])
	    break; /* Successful connection. */
	}

      /* Sleep a moment before retrying. */
      sleep(1);
    }
  /* Return failure if we didn't get a successful connection. */
  if (attempt >= connection_attempts)
    return 0;

  debug("Connection established.");

  /* Set socket options.  We would like the socket to disappear as soon as
     it has been closed for whatever reason. */
  /* setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); */
  setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *)&on, sizeof(on));
  linger.l_onoff = 1;
  linger.l_linger = 5;
  setsockopt(sock, SOL_SOCKET, SO_LINGER, (void *)&linger, sizeof(linger));

  /* Set the connection. */
  packet_set_connection(sock, sock);

  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, bits;
  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, &bits, e, n, &comment);
       status;
       status = ssh_get_next_identity(auth, &bits, 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, bits, 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);
  assert(len <= sizeof(buf) && 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(struct passwd *pw, const char *authfile,
		       int may_ask_passphrase)
{
  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);
    return 0; /* Could not load it.  Fail. */
  }

  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; /* Server refuses to authenticate with this key. */
    }

  /* 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];
      /* Request passphrase from the user.  We read from /dev/tty to make
         this work even if stdin has been redirected.  If running in
	 batch mode, we just use the empty passphrase, which will fail and
	 return. */
      snprintf(buf, sizeof buf,
	"Enter passphrase for RSA key '%.100s': ", comment);
      if (may_ask_passphrase)
	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; /* Server refuses to authenticate us with this method. */
    }

  /* 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;
  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);
  
  r = sizeof(local);
  memset(&local, 0, sizeof(local));
  if (getsockname(packet_get_connection_in(),
 		  (struct sockaddr *) &local, &r) < 0)
    debug("getsockname failed: %s", strerror(errno));
  
  r = sizeof(foreign);
  memset(&foreign, 0, sizeof(foreign));
   if (getpeername(packet_get_connection_in(),
		   (struct sockaddr *)&foreign, &r) < 0)
     debug("getpeername failed: %s", strerror(errno));
   
   /* 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;
  unsigned 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, buffer);
  xfree(creds);
    
  packet_start(SSH_CMSG_HAVE_KERBEROS_TGT);
  packet_put_string((char *)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;
  unsigned 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, buffer)) break;
    packet_start(SSH_CMSG_HAVE_AFS_TOKEN);
    packet_put_string((char *)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 */

/* Waits for the server identification string, and sends our own identification
   string. */

void ssh_exchange_identification()
{
  char buf[256], remote_version[256]; /* must be same size! */
  int remote_major, remote_minor, i;
  int connection_in = packet_get_connection_in();
  int connection_out = packet_get_connection_out();
  extern Options options;

  /* Read other side\'s version identification. */
  for (i = 0; i < sizeof(buf) - 1; i++)
    {
      if (read(connection_in, &buf[i], 1) != 1)
	fatal("read: %.100s", strerror(errno));
      if (buf[i] == '\r')
	{
	  buf[i] = '\n';
	  buf[i + 1] = 0;
	  break;
	}
      if (buf[i] == '\n')
	{
	  buf[i + 1] = 0;
	  break;
	}
    }
  buf[sizeof(buf) - 1] = 0;
  
  /* Check that the versions match.  In future this might accept several
     versions and set appropriate flags to handle them. */
  if (sscanf(buf, "SSH-%d.%d-%[^\n]\n", &remote_major, &remote_minor, 
	     remote_version) != 3)
    fatal("Bad remote protocol version identification: '%.100s'", buf);
  debug("Remote protocol version %d.%d, remote software version %.100s",
	remote_major, remote_minor, remote_version);

  /* Check if the remote protocol version is too old. */
  if (remote_major == 1 && remote_minor < 3)
    fatal("Remote machine has too old SSH software version.");

  /* We speak 1.3, too. */
  if (remote_major == 1 && remote_minor == 3) {
    enable_compat13();
    if (options.forward_agent && strcmp(remote_version, SSH_VERSION) != 0) {
      log("Agent forwarding disabled, remote version '%s' is not compatible.",
	    remote_version);
      options.forward_agent = 0;
    }
  }
#if 0
  /* Removed for now, to permit compatibility with latter versions.  The server
     will reject our version and disconnect if it doesn't support it. */
  if (remote_major != PROTOCOL_MAJOR)
    fatal("Protocol major versions differ: %d vs. %d",
	  PROTOCOL_MAJOR, remote_major);
#endif

  /* Send our own protocol version identification. */
  snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", 
	  PROTOCOL_MAJOR, PROTOCOL_MINOR, SSH_VERSION);
  if (write(connection_out, buf, strlen(buf)) != strlen(buf))
    fatal("write: %.100s", strerror(errno));
}

int ssh_cipher_default = SSH_CIPHER_3DES;

int read_yes_or_no(const char *prompt, int defval)
{
  char buf[1024];
  FILE *f;
  int retval = -1;
      
  if (isatty(0))
    f = stdin;
  else
    f = fopen("/dev/tty", "rw");

  if (f == NULL)
    return 0;

  fflush(stdout);

  while (1)
    {
      fprintf(stderr, "%s", prompt);
      if (fgets(buf, sizeof(buf), f) == NULL)
	{
	  /* Print a newline (the prompt probably didn\'t have one). */
	  fprintf(stderr, "\n");
	  strlcpy(buf, "no", sizeof buf);
	}
      /* Remove newline from response. */
      if (strchr(buf, '\n'))
	*strchr(buf, '\n') = 0;

      if (buf[0] == 0)
	retval = defval;
      if (strcmp(buf, "yes") == 0)
	retval = 1;
      if (strcmp(buf, "no") == 0)
	retval = 0;

      if (retval != -1)
	{
	  if (f != stdin)
	    fclose(f);
	  return retval;
	}
    }
}

/* Starts a dialog with the server, and authenticates the current user on the
   server.  This does not need any extra privileges.  The basic connection
   to the server must already have been established before this is called. 
   User is the remote user; if it is NULL, the current local user name will
   be used.  Anonymous indicates that no rhosts authentication will be used.
   If login fails, this function prints an error and never returns. 
   This function does not require super-user privileges. */

void ssh_login(int host_key_valid, 
	       RSA *own_host_key,
	       const char *orighost, 
	       struct sockaddr_in *hostaddr,
	       Options *options, uid_t original_real_uid)
{
  int i, type;
  char *password;
  struct passwd *pw;
  BIGNUM *key;
  RSA *host_key, *file_key;
  RSA *public_key;
  unsigned char session_key[SSH_SESSION_KEY_LENGTH];
  const char *server_user, *local_user;
  char *cp, *host, *ip = NULL;
  unsigned char check_bytes[8];
  unsigned int supported_ciphers, supported_authentications, protocol_flags;
  HostStatus host_status;
  HostStatus ip_status;
  int host_ip_differ = 0;
  int local = (ntohl(hostaddr->sin_addr.s_addr) >> 24) == IN_LOOPBACKNET;
  int payload_len, clen, sum_len = 0;
  u_int32_t rand = 0;

  if (options->check_host_ip)
    ip = xstrdup(inet_ntoa(hostaddr->sin_addr));

  /* Convert the user-supplied hostname into all lowercase. */
  host = xstrdup(orighost);
  for (cp = host; *cp; cp++)
    if (isupper(*cp))
      *cp = tolower(*cp);

  /* Exchange protocol version identification strings with the server. */
  ssh_exchange_identification();

  /* Put the connection into non-blocking mode. */
  packet_set_nonblocking();

  /* 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;

  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 check bytes from the packet. */
  for (i = 0; i < 8; i++)
    check_bytes[i] = packet_get_char();

  /* Get the public key. */
  public_key = RSA_new();
  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;

  /* Get the host key. */
  host_key = RSA_new();
  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;

  /* Store the host key from the known host file in here
   * so that we can compare it with the key for the IP
   * address. */
  file_key = RSA_new();
  file_key->n = BN_new();
  file_key->e = BN_new();

  /* Get protocol flags. */
  protocol_flags = packet_get_int();
  packet_set_protocol_flags(protocol_flags);

  /* Get supported cipher types. */
  supported_ciphers = packet_get_int();

  /* Get supported authentication types. */
  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);

  /* Compute the session id. */
  compute_session_id(session_id, check_bytes, 
		     BN_num_bits(host_key->n), host_key->n, 
		     BN_num_bits(public_key->n), public_key->n);

  /* 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, BN_num_bits(host_key->n), 
				       host_key->e, host_key->n,
				       file_key->e, file_key->n);
  if (host_status == HOST_NEW)
    host_status = check_host_in_hostfile(options->system_hostfile, host, 
					 BN_num_bits(host_key->n),
					 host_key->e, host_key->n,
					 file_key->e, file_key->n);
  /* Force accepting of the host key for localhost and 127.0.0.1.
     The problem is that if the home directory is NFS-mounted to multiple
     machines, localhost will refer to a different machine in each of them,
     and the user will get bogus HOST_CHANGED warnings.  This essentially
     disables host authentication for localhost; however, this is probably
     not a real problem. */
  if (local) {
    debug("Forcing accepting of host key for localhost.");
    host_status = HOST_OK;
  }

  /* 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)) {
    RSA *ip_key = RSA_new();
    ip_key->n = BN_new();
    ip_key->e = BN_new();
    ip_status = check_host_in_hostfile(options->user_hostfile, ip,
				       BN_num_bits(host_key->n),
				       host_key->e, host_key->n,
				       ip_key->e, ip_key->n);

    if (ip_status == HOST_NEW)
      ip_status = check_host_in_hostfile(options->system_hostfile, ip,
					 BN_num_bits(host_key->n),
					 host_key->e, host_key->n,
					 ip_key->e, ip_key->n);
    if (host_status == HOST_CHANGED &&
	(ip_status != HOST_CHANGED || 
	 (BN_cmp(ip_key->e, file_key->e) || BN_cmp(ip_key->n, file_key->n))))
      host_ip_differ = 1;

    RSA_free(ip_key);
  } else
    ip_status = host_status;

  RSA_free(file_key);

  switch (host_status) {
  case HOST_OK:
    /* The host is known and the key matches. */
    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,
				  BN_num_bits(host_key->n), 
				  host_key->e, host_key->n))
	  log("Failed to add the host ip to the list of known hosts (%.30s).", 
	      options->user_hostfile);
	else
	  log("Warning: Permanently added host ip '%.30s' to the list of known hosts.", ip);
      } else if (ip_status != HOST_OK)
	log("Warning: the host key differ from the key of the ip address '%.30s' differs", ip);
    }
    
    break;
  case HOST_NEW:
    {
      char hostline[1000], *hostp = hostline;
      /* The host is new. */
      if (options->strict_host_key_checking == 1) {
	/* User has requested strict host key checking.  We will not
	   add the host key automatically.  The only alternative left
	   is to abort. */
	fatal("No host key is known for %.200s and you have requested strict checking.", host);
      } else if (options->strict_host_key_checking == 2) { /* The default */
	char prompt[1024];
	snprintf(prompt, sizeof(prompt),
		 "The authenticity of host '%.200s' can't be established.\n"
		 "Are you sure you want to continue connecting (yes/no)? ",
		 host);
	if (!read_yes_or_no(prompt, -1))
	  fatal("Aborted by user!\n");
      }
      
      if (options->check_host_ip && ip_status == HOST_NEW && strcmp(host, ip))
	snprintf(hostline, sizeof(hostline), "%s,%s", host, ip);
      else
	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,
				BN_num_bits(host_key->n), 
				host_key->e, host_key->n))
	log("Failed to add the host to the list of known hosts (%.500s).", 
	    options->user_hostfile);
      else
	log("Warning: Permanently added '%.200s' to the list of known hosts.",
	    hostp);
      break;
    }
  case HOST_CHANGED:
    if (options->check_host_ip) {
      if (host_ip_differ) {
	error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
	error("@       WARNING: POSSIBLE DNS SPOOFING DETECTED!          @");
	error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
	error("The host key for %s has changed,", host);
	error("but the key for the according IP address %s has", ip);
	error("a different status.  This could either mean that DNS");
	error("SPOOFING is happening or the IP address for the host");
	error("and its host key have changed at the same time");
      }
    }
    
    /* The host key has changed. */
    error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
    error("@       WARNING: HOST IDENTIFICATION HAS CHANGED!         @");
    error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
    error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!");
    error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!");
    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);
    
    /* If strict host key checking is in use, the user will have to edit
       the key manually and we can only abort. */
    if (options->strict_host_key_checking)
      fatal("Host key for %.200s has changed and you have requested strict checking.", host);
    
    /* If strict host key checking has not been requested, allow the
       connection but without password authentication or
       agent forwarding. */
    if (options->password_authentication) {
      error("Password authentication is disabled to avoid trojan horses.");
      options->password_authentication = 0;
    }
    if (options->forward_agent) {
      error("Agent forwarding is disabled to avoid trojan horses.");
      options->forward_agent = 0;
    }
    /* XXX Should permit the user to change to use the new id.  This could
       be done by converting the host key to an identifying sentence, tell
       that the host identifies itself by that sentence, and ask the user
       if he/she whishes to accept the authentication. */
    break;
  }

  if (options->check_host_ip)
    xfree(ip);
  
  /* 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. */
      assert(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). */
      assert(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);
    }

  if (options->cipher == SSH_CIPHER_NOT_SET) {
    if (cipher_mask() & supported_ciphers & (1 << ssh_cipher_default))
      options->cipher = ssh_cipher_default;
    else {
      debug("Cipher %d 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 check bytes back to the server. */
  for (i = 0; i < 8; i++)
    packet_put_char(check_bytes[i]);

  /* Send the encrypted encryption key. */
  packet_put_bignum(key);

  /* Send protocol flags. */
  packet_put_int(SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN);

  /* Send the packet now. */
  packet_send();
  packet_write_wait();

  /* Destroy the session key integer and the public keys since we no longer
     need them. */
  BN_clear_free(key);
  RSA_free(public_key);
  RSA_free(host_key);

  debug("Sent encrypted session key.");
  
  /* Set the encryption key. */
  packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, 
			    options->cipher, 1);

  /* 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.");

  /* 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);
  if (type == SSH_SMSG_SUCCESS)
    return;  /* Connection was accepted without authentication. */
  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; /* Successful connection. */
        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; /* Successful connection. */
      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; /* Successful authentication. */
    }

  /* 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; /* Successful connection. */

      /* Try RSA authentication for each identity. */
      for (i = 0; i < options->num_identity_files; i++)
	if (try_rsa_authentication(pw, options->identity_files[i],
				   !options->batch_mode))
	  return; /* Successful connection. */
    }
  
  /* 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@%.30s's password: ",
	server_user, host);
      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; /* Successful connection. */
	if (type != SSH_SMSG_FAILURE)
	  packet_disconnect("Protocol error: got %d in response to passwd auth", type);
      }
    }

  /* All authentication methods have failed.  Exit with an error message. */
  fatal("Permission denied.");
  /*NOTREACHED*/
}
