
#ifdef KERBEROS
#include <krb.h>
#endif

#include <syslog.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "server.h"
#include "config.h"

int check_authentication(fd, p, i, r)	/* Reads a kerberos ticket from the given fd */
     int fd;				/* Returns 0 for ok, -1 to reject */
     char *p;				/*   Return: kerberos principle: at least ANAME_SZ */
     char *i;				/*   Return: kerberos instance: at least INST_SZ */
     char *r;				/*   Return: kerberos realm: at least REALM_SZ */
{
  struct sockaddr_in saddr;
  int slen = sizeof(saddr);
  
  if (getpeername (fd, &saddr, &slen) < 0) {
    syslog (LOG_ERR, "check_authentication: can't get peer name: %m");
    return -1;
  }
#ifdef KERBEROS
  {
    KTEXT_ST ticket;
    AUTH_DAT ad;
    u_short ticket_size;
    int krb_err;
    char my_hostname[64];		  

    gethostname (my_hostname, 64);
    if (read (fd, &ticket_size, 2) != 2) {
    readerr:
      syslog (LOG_ERR, "can't read kerberos ticket: %m");
      return -1;
    }
    ticket.length = ntohs(ticket_size);
    if (read (fd, ticket.dat, ticket.length) != ticket.length)
      goto readerr;
    if (krb_err = krb_rd_req (&ticket, KRB_SERVICE, my_hostname, saddr.sin_addr.s_addr, &ad, srvtab)) {
      syslog (LOG_ERR, "check_authentication: authentication failed: %s", krb_err_txt[krb_err]);
      return -1;
    }
    strcpy (p, ad.pname);
    strcpy (i, ad.pinst);
    strcpy (r, ad.prealm);
  }
#else
  {
    unsigned short uname_size;
    if (read (fd, &uname_size, 2) != 2) {
    readerr:
      syslog (LOG_ERR, "can't read username: %m");
      return -1;
    }
    uname_size = ntohs(uname_size);
    if (read (fd, p, uname_size) != uname_size)
      goto readerr;
    strcpy (i, "");
    strcpy (r, "NO-REALM");
  }
#endif
  syslog (LOG_INFO, "connection by %s.%s@%s from %s", p, i, r, inet_ntoa(saddr.sin_addr));
  return 0;
}

