/* authclient.c --
 *
 * Receive and verify the kerberos authentication from the client.
 * Return the client authorization struction, so we can verify the
 * name.
 *
 * Changed in this file should mirror changes in serverconn.c
 *
 * Created by:	Derek Atkins <warlord@MIT.EDU>
 *
 * Copyright 1994 Derek A. Atkins and the Massachusetts Institute of
 * Technology
 *
 * For copying and distribution information, please see the file
 * <warlord-copyright.h>.
 *
 * $Source: /mit/warlord/C/pgpsign/src/RCS/authclient.c,v $
 * $Author: warlord $
 *
 */

#include "warlord-copyright.h"
#include "pgpsign.h"

int
authclient(int sock, AUTH_DAT *auth_dat)
{
  int retval;
  struct sockaddr_in laddr, faddr;
  KTEXT_ST ktext;
  char inst[INST_SZ+1];
  Key_schedule schedule;
  char version[KRB_SENDAUTH_VLEN+1];
  char authtype[AUTHTYPELEN];

  /* Check Args */
  assert (sock >= 0);
  assert (auth_dat != NULL);

  retval = sizeof(struct sockaddr_in);
  if (getsockname(sock, (struct sockaddr *)&laddr, &retval) != 0) {
    return -1;
  }

  retval = sizeof(struct sockaddr_in);
  if (getpeername(sock, (struct sockaddr *)&faddr, &retval) != 0) {
    return -1;
  }

  if (krb_net_read(sock, authtype, AUTHTYPELEN) != AUTHTYPELEN) {
    return -1;
  }

  /* Check the authtype..  Only Krb4 is currently allowed.  Otherwise
   * we could jump to other tables.
   */
  if (strcmp(authtype, AUTHTYPEKRB4)) {
    syslog(LOG_ERR, "Unknown Auth Type: %s", authtype);
    return -1;
  }

  strcpy(inst, "*");

  retval = krb_recvauth(0, sock, &ktext, PGPSERVICE, inst,
			&faddr, &laddr, auth_dat, PGPSRVTAB, schedule, 
			version);

  bzero(&schedule, sizeof(Key_schedule));
  bzero(&ktext, sizeof(KTEXT_ST));

  if (retval != KSUCCESS) {
    syslog(LOG_ERR, "Kerberos error while authenticating: %d", retval);
    return(retval);
  }

  if (strcmp(version, "PSN0.0")) {
    syslog(LOG_ERR, "Version error, received version %s, want %s",
	   version, "PSN0.0");
    return(-1);
  }

  syslog(LOG_INFO, "Authorization is good: %s.%s@%s", auth_dat->pname,
	 auth_dat->pinst, auth_dat->prealm);

  return 0;
}
