/*

authfd.c

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

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

Created: Wed Mar 29 01:30:28 1995 ylo

Functions for connecting the local authentication agent.

*/

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

#include "ssh.h"
#include "rsa.h"
#include "authfd.h"
#include "buffer.h"
#include "bufaux.h"
#include "xmalloc.h"
#include "getput.h"

#include <openssl/rsa.h>

/* Returns the number of the authentication fd, or -1 if there is none. */

int
ssh_get_authentication_socket()
{
  const char *authsocket;
  int sock;
  struct sockaddr_un sunaddr;

  authsocket = getenv(SSH_AUTHSOCKET_ENV_NAME);
  if (!authsocket)
    return -1;

  sunaddr.sun_family = AF_UNIX;
  strlcpy(sunaddr.sun_path, authsocket, sizeof(sunaddr.sun_path));
  
  sock = socket(AF_UNIX, SOCK_STREAM, 0);
  if (sock < 0)
    return -1;
  
  if (connect(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0)
    {
      close(sock);
      return -1;
    }

  return sock;
}

/* Closes the agent socket if it should be closed (depends on how it was
   obtained).  The argument must have been returned by 
   ssh_get_authentication_socket(). */

void ssh_close_authentication_socket(int sock)
{
  if (getenv(SSH_AUTHSOCKET_ENV_NAME))
    close(sock);
}

/* Opens and connects a private socket for communication with the
   authentication agent.  Returns the file descriptor (which must be
   shut down and closed by the caller when no longer needed).
   Returns NULL if an error occurred and the connection could not be
   opened. */

AuthenticationConnection *ssh_get_authentication_connection()
{
  AuthenticationConnection *auth;
  int sock;
  
  sock = ssh_get_authentication_socket();

  /* Fail if we couldn't obtain a connection.  This happens if we exited
     due to a timeout. */
  if (sock < 0)
    return NULL;

  /* Applocate the connection structure and initialize it. */
  auth = xmalloc(sizeof(*auth));
  auth->fd = sock;
  buffer_init(&auth->packet);
  buffer_init(&auth->identities);
  auth->howmany = 0;

  return auth;
}

/* Closes the connection to the authentication agent and frees any associated
   memory. */

void ssh_close_authentication_connection(AuthenticationConnection *ac)
{
  buffer_free(&ac->packet);
  buffer_free(&ac->identities);
  close(ac->fd);
  /* Free the connection data structure. */
  xfree(ac);
}

/* Returns the first authentication identity held by the agent.
   Returns true if an identity is available, 0 otherwise.
   The caller must initialize the integers before the call, and free the
   comment after a successful call (before calling ssh_get_next_identity). */

int
ssh_get_first_identity(AuthenticationConnection *auth,
		       int *bitsp, BIGNUM *e, BIGNUM *n, char **comment)
{
  unsigned char msg[8192];
  int len, l;

  /* Send a message to the agent requesting for a list of the identities
     it can represent. */
  msg[0] = 0;
  msg[1] = 0;
  msg[2] = 0;
  msg[3] = 1;
  msg[4] = SSH_AGENTC_REQUEST_RSA_IDENTITIES;
  if (write(auth->fd, msg, 5) != 5)
    {
      error("write auth->fd: %.100s", strerror(errno));
      return 0;
    }

  /* Read the length of the response.  XXX implement timeouts here. */
  len = 4;
  while (len > 0)
    {
      l = read(auth->fd, msg + 4 - len, len);
      if (l <= 0)
	{
	  error("read auth->fd: %.100s", strerror(errno));
	  return 0;
	}
      len -= l;
    }

  /* Extract the length, and check it for sanity.  (We cannot trust
     authentication agents). */
  len = GET_32BIT(msg);
  if (len < 1 || len > 256*1024)
    fatal("Authentication reply message too long: %d\n", len);

  /* Read the packet itself. */
  buffer_clear(&auth->identities);
  while (len > 0)
    {
      l = len;
      if (l > sizeof(msg))
	l = sizeof(msg);
      l = read(auth->fd, msg, l);
      if (l <= 0)
	fatal("Incomplete authentication reply.");
      buffer_append(&auth->identities, (char *)msg, l);
      len -= l;
    }
  
  /* Get message type, and verify that we got a proper answer. */
  buffer_get(&auth->identities, (char *)msg, 1);
  if (msg[0] != SSH_AGENT_RSA_IDENTITIES_ANSWER)
    fatal("Bad authentication reply message type: %d", msg[0]);
  
  /* Get the number of entries in the response and check it for sanity. */
  auth->howmany = buffer_get_int(&auth->identities);
  if (auth->howmany > 1024)
    fatal("Too many identities in authentication reply: %d\n", auth->howmany);

  /* Return the first entry (if any). */
  return ssh_get_next_identity(auth, bitsp, e, n, comment);
}

/* Returns the next authentication identity for the agent.  Other functions
   can be called between this and ssh_get_first_identity or two calls of this
   function.  This returns 0 if there are no more identities.  The caller
   must free comment after a successful return. */

int
ssh_get_next_identity(AuthenticationConnection *auth,
		      int *bitsp, BIGNUM *e, BIGNUM *n, char **comment)
{
  /* Return failure if no more entries. */
  if (auth->howmany <= 0)
    return 0;

  /* Get the next entry from the packet.  These will abort with a fatal
     error if the packet is too short or contains corrupt data. */
  *bitsp = buffer_get_int(&auth->identities);
  buffer_get_bignum(&auth->identities, e);
  buffer_get_bignum(&auth->identities, n);
  *comment = buffer_get_string(&auth->identities, NULL);

  /* Decrement the number of remaining entries. */
  auth->howmany--;

  return 1;
}

/* Generates a random challenge, sends it to the agent, and waits for response
   from the agent.  Returns true (non-zero) if the agent gave the correct
   answer, zero otherwise.  Response type selects the style of response
   desired, with 0 corresponding to protocol version 1.0 (no longer supported)
   and 1 corresponding to protocol version 1.1. */

int
ssh_decrypt_challenge(AuthenticationConnection *auth,
		      int bits, BIGNUM *e, BIGNUM *n, BIGNUM *challenge,
		      unsigned char session_id[16],
		      unsigned int response_type,
		      unsigned char response[16])
{
  Buffer buffer;
  unsigned char buf[8192];
  int len, l, i;

  /* Response type 0 is no longer supported. */
  if (response_type == 0)
    fatal("Compatibility with ssh protocol version 1.0 no longer supported.");

  /* Format a message to the agent. */
  buf[0] = SSH_AGENTC_RSA_CHALLENGE;
  buffer_init(&buffer);
  buffer_append(&buffer, (char *)buf, 1);
  buffer_put_int(&buffer, bits);
  buffer_put_bignum(&buffer, e);
  buffer_put_bignum(&buffer, n);
  buffer_put_bignum(&buffer, challenge);
  buffer_append(&buffer, (char *)session_id, 16);
  buffer_put_int(&buffer, response_type);

  /* Get the length of the message, and format it in the buffer. */
  len = buffer_len(&buffer);
  PUT_32BIT(buf, len);

  /* Send the length and then the packet to the agent. */
  if (write(auth->fd, buf, 4) != 4 ||
      write(auth->fd, buffer_ptr(&buffer), buffer_len(&buffer)) !=
        buffer_len(&buffer))
    {
      error("Error writing to authentication socket.");
    error_cleanup:
      buffer_free(&buffer);
      return 0;
    }

  /* Wait for response from the agent.  First read the length of the
     response packet. */
  len = 4;
  while (len > 0)
    {
      l = read(auth->fd, buf + 4 - len, len);
      if (l <= 0)
	{
	  error("Error reading response length from authentication socket.");
	  goto error_cleanup;
	}
      len -= l;
    }

  /* Extract the length, and check it for sanity. */
  len = GET_32BIT(buf);
  if (len > 256*1024)
    fatal("Authentication response too long: %d", len);

  /* Read the rest of the response in tothe buffer. */
  buffer_clear(&buffer);
  while (len > 0)
    {
      l = len;
      if (l > sizeof(buf))
	l = sizeof(buf);
      l = read(auth->fd, buf, l);
      if (l <= 0)
	{
	  error("Error reading response from authentication socket.");
	  goto error_cleanup;
	}
      buffer_append(&buffer, (char *)buf, l);
      len -= l;
    }

  /* Get the type of the packet. */
  buffer_get(&buffer, (char *)buf, 1);

  /* Check for agent failure message. */
  if (buf[0] == SSH_AGENT_FAILURE)
    {
      log("Agent admitted failure to authenticate using the key.");
      goto error_cleanup;
    }
      
  /* Now it must be an authentication response packet. */
  if (buf[0] != SSH_AGENT_RSA_RESPONSE)
    fatal("Bad authentication response: %d", buf[0]);

  /* Get the response from the packet.  This will abort with a fatal error
     if the packet is corrupt. */
  for (i = 0; i < 16; i++)
    response[i] = buffer_get_char(&buffer);

  /* The buffer containing the packet is no longer needed. */
  buffer_free(&buffer);

  /* Correct answer. */
  return 1;
}  

/* Adds an identity to the authentication server.  This call is not meant to
   be used by normal applications. */

int ssh_add_identity(AuthenticationConnection *auth,
		     RSA *key, const char *comment)
{
  Buffer buffer;
  unsigned char buf[8192];
  int len, l, type;

  /* Format a message to the agent. */
  buffer_init(&buffer);
  buffer_put_char(&buffer, SSH_AGENTC_ADD_RSA_IDENTITY);
  buffer_put_int(&buffer, BN_num_bits(key->n));
  buffer_put_bignum(&buffer, key->n);
  buffer_put_bignum(&buffer, key->e);
  buffer_put_bignum(&buffer, key->d);
  /* To keep within the protocol: p < q for ssh. in SSL p > q */
  buffer_put_bignum(&buffer, key->iqmp); /* ssh key->u */
  buffer_put_bignum(&buffer, key->q); /* ssh key->p, SSL key->q */
  buffer_put_bignum(&buffer, key->p); /* ssh key->q, SSL key->p */
  buffer_put_string(&buffer, comment, strlen(comment));

  /* Get the length of the message, and format it in the buffer. */
  len = buffer_len(&buffer);
  PUT_32BIT(buf, len);

  /* Send the length and then the packet to the agent. */
  if (write(auth->fd, buf, 4) != 4 ||
      write(auth->fd, buffer_ptr(&buffer), buffer_len(&buffer)) !=
        buffer_len(&buffer))
    {
      error("Error writing to authentication socket.");
    error_cleanup:
      buffer_free(&buffer);
      return 0;
    }

  /* Wait for response from the agent.  First read the length of the
     response packet. */
  len = 4;
  while (len > 0)
    {
      l = read(auth->fd, buf + 4 - len, len);
      if (l <= 0)
	{
	  error("Error reading response length from authentication socket.");
	  goto error_cleanup;
	}
      len -= l;
    }

  /* Extract the length, and check it for sanity. */
  len = GET_32BIT(buf);
  if (len > 256*1024)
    fatal("Add identity response too long: %d", len);

  /* Read the rest of the response in tothe buffer. */
  buffer_clear(&buffer);
  while (len > 0)
    {
      l = len;
      if (l > sizeof(buf))
	l = sizeof(buf);
      l = read(auth->fd, buf, l);
      if (l <= 0)
	{
	  error("Error reading response from authentication socket.");
	  goto error_cleanup;
	}
      buffer_append(&buffer, (char *)buf, l);
      len -= l;
    }

  /* Get the type of the packet. */
  type = buffer_get_char(&buffer);
  switch (type)
    {
    case SSH_AGENT_FAILURE:
      buffer_free(&buffer);
      return 0;
    case SSH_AGENT_SUCCESS:
      buffer_free(&buffer);
      return 1;
    default:
      fatal("Bad response to add identity from authentication agent: %d", 
	    type);
    }
  /*NOTREACHED*/
  return 0;
}  

/* Removes an identity from the authentication server.  This call is not meant 
   to be used by normal applications. */

int ssh_remove_identity(AuthenticationConnection *auth, RSA *key)
{
  Buffer buffer;
  unsigned char buf[8192];
  int len, l, type;

  /* Format a message to the agent. */
  buffer_init(&buffer);
  buffer_put_char(&buffer, SSH_AGENTC_REMOVE_RSA_IDENTITY);
  buffer_put_int(&buffer, BN_num_bits(key->n));
  buffer_put_bignum(&buffer, key->e);
  buffer_put_bignum(&buffer, key->n);

  /* Get the length of the message, and format it in the buffer. */
  len = buffer_len(&buffer);
  PUT_32BIT(buf, len);

  /* Send the length and then the packet to the agent. */
  if (write(auth->fd, buf, 4) != 4 ||
      write(auth->fd, buffer_ptr(&buffer), buffer_len(&buffer)) !=
        buffer_len(&buffer))
    {
      error("Error writing to authentication socket.");
    error_cleanup:
      buffer_free(&buffer);
      return 0;
    }

  /* Wait for response from the agent.  First read the length of the
     response packet. */
  len = 4;
  while (len > 0)
    {
      l = read(auth->fd, buf + 4 - len, len);
      if (l <= 0)
	{
	  error("Error reading response length from authentication socket.");
	  goto error_cleanup;
	}
      len -= l;
    }

  /* Extract the length, and check it for sanity. */
  len = GET_32BIT(buf);
  if (len > 256*1024)
    fatal("Remove identity response too long: %d", len);

  /* Read the rest of the response in tothe buffer. */
  buffer_clear(&buffer);
  while (len > 0)
    {
      l = len;
      if (l > sizeof(buf))
	l = sizeof(buf);
      l = read(auth->fd, buf, l);
      if (l <= 0)
	{
	  error("Error reading response from authentication socket.");
	  goto error_cleanup;
	}
      buffer_append(&buffer, (char *)buf, l);
      len -= l;
    }

  /* Get the type of the packet. */
  type = buffer_get_char(&buffer);
  switch (type)
    {
    case SSH_AGENT_FAILURE:
      buffer_free(&buffer);
      return 0;
    case SSH_AGENT_SUCCESS:
      buffer_free(&buffer);
      return 1;
    default:
      fatal("Bad response to remove identity from authentication agent: %d", 
	    type);
    }
  /*NOTREACHED*/
  return 0;
}  

/* Removes all identities from the agent.  This call is not meant 
   to be used by normal applications. */

int ssh_remove_all_identities(AuthenticationConnection *auth)
{
  Buffer buffer;
  unsigned char buf[8192];
  int len, l, type;

  /* Get the length of the message, and format it in the buffer. */
  PUT_32BIT(buf, 1);
  buf[4] = SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES;

  /* Send the length and then the packet to the agent. */
  if (write(auth->fd, buf, 5) != 5)
    {
      error("Error writing to authentication socket.");
      return 0;
    }

  /* Wait for response from the agent.  First read the length of the
     response packet. */
  len = 4;
  while (len > 0)
    {
      l = read(auth->fd, buf + 4 - len, len);
      if (l <= 0)
	{
	  error("Error reading response length from authentication socket.");
	  return 0;
	}
      len -= l;
    }

  /* Extract the length, and check it for sanity. */
  len = GET_32BIT(buf);
  if (len > 256*1024)
    fatal("Remove identity response too long: %d", len);

  /* Read the rest of the response into the buffer. */
  buffer_init(&buffer);
  while (len > 0)
    {
      l = len;
      if (l > sizeof(buf))
	l = sizeof(buf);
      l = read(auth->fd, buf, l);
      if (l <= 0)
	{
	  error("Error reading response from authentication socket.");
	  buffer_free(&buffer);
	  return 0;
	}
      buffer_append(&buffer, (char *)buf, l);
      len -= l;
    }

  /* Get the type of the packet. */
  type = buffer_get_char(&buffer);
  switch (type)
    {
    case SSH_AGENT_FAILURE:
      buffer_free(&buffer);
      return 0;
    case SSH_AGENT_SUCCESS:
      buffer_free(&buffer);
      return 1;
    default:
      fatal("Bad response to remove identity from authentication agent: %d", 
	    type);
    }
  /*NOTREACHED*/
  return 0;
}  
