/* This file is part of the Project Athena Zephyr Notification System.
 * It contains code for the "zpopnotify" command.
 *
 *	Created by:	Robert French
 *
 *	$Source: /afs/stacken.kth.se/src/SourceRepository/stacken-zephyr/clients/zcomsat/zcomsat.c,v $
 *	$Author: lha $
 *
 *	Copyright (c) 1987,1988 by the Massachusetts Institute of Technology.
 *	For copying and distribution information, see the file
 *	"mit-copyright.h". 
 */


#include <sysdep.h>
#include <zephyr/mit-copyright.h>
#include <zephyr/zephyr.h>
#include <stdio.h>
#include <netdb.h>
#include <string.h>
#include <sys/param.h>			/* for MAXHOSTNAMELEN */
#include <com_err.h>
#include <errno.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <unistd.h>
#include <ctype.h>


#ifndef lint
static char rcsid_zcomsat_c[] = "$Header: /afs/stacken.kth.se/src/SourceRepository/stacken-zephyr/clients/zcomsat/zcomsat.c,v 1.2 1999/02/26 07:12:07 lha Exp $";
#endif /* lint */

#define MAIL_CLASS "MAIL"
#define MAIL_INSTANCE "POP"

/* #ifdef KERBEROS */
#define ZC_NAME "zcomsat"
#define SRVTAB "/etc/srvtab"

char realm[REALM_SZ] ;
krb_principal princ;
des_cblock key;

key_to_key(char *user, char *instance, char *realm, void *arg,
           des_cblock *key)
{
    memcpy(key, arg, sizeof(des_cblock));
    return 0;
}


int get_kerb_ticket(char *hostname) 
{
    char *tmp ;
    char tf[MAXPATHLEN];
    int f ;
    int code ;

    strcpy(princ.name, ZC_NAME) ;
    strncpy(princ.instance, hostname, sizeof(princ.instance)) ;

    if (krb_get_lrealm(princ.realm, 1) != KSUCCESS)
        strcpy(princ.realm, KRB_REALM) ;

    do{
        snprintf(tf, sizeof(tf),
		 TKT_ROOT "%u_%u",
		 (unsigned)getuid(),
		 (unsigned)(getpid()*time(0)));
	f = open(tf, O_CREAT|O_EXCL|O_RDWR);
    }while(f < 0);
    close(f);
    unlink(tf);

    krb_set_tkt_string (tf);

    code = read_service_key (princ.name, princ.instance, princ.realm, 0, 
                                     SRVTAB, (char *)&key);
        if (code == KSUCCESS)
            code = krb_get_in_tkt(princ.name, princ.instance, princ.realm,
				  KRB_TICKET_GRANTING_TICKET,
				  princ.realm, 1,
				  key_to_key, NULL, key);

    if (code != KSUCCESS) {
      memset (key, 0, sizeof(key));
      return 1 ;
    }

    return 0 ;
}

/* #endif KERBEROS */


main(argc,argv)
	int argc;
	char *argv[];
{
	ZNotice_t notice;
	struct hostent *hent;
	int retval;
	register int i;
	char *whoami,myhost[MAXHOSTNAMELEN],mysender[BUFSIZ];
	char shortmyhost[MAXHOSTNAMELEN] ;
	char *lines[2];
	char from[BUFSIZ] ;
	char *tmp ;
	struct sockaddr_in peer ;
	int peersize = sizeof(peer) ;
	int safe ;
	Z_AuthProc auth ;
	
	openlog("zcomsat", LOG_PID, LOG_DAEMON);

	whoami = argv[0];

	if (gethostname(myhost,MAXHOSTNAMELEN) == -1) {
		syslog(LOG_INFO,"Can't get hostname");
		exit(1);
	}
	myhost[MAXHOSTNAMELEN-1] = '\0';

	if (!(hent = gethostbyname(myhost))) {
		syslog(LOG_INFO, "Can't get canonical hostname");
		closelog() ;
		exit(1);
	}

	(void) strncpy(myhost,hent->h_name,MAXHOSTNAMELEN);
	myhost[MAXHOSTNAMELEN-1] = '\0';

	(void) strncpy(shortmyhost, myhost, MAXHOSTNAMELEN) ;
	shortmyhost[MAXHOSTNAMELEN-1] = '\0';
	
	/* Find the frist . and punch a hole there */
	if ((tmp = strchr(shortmyhost, '.')) != NULL)
	    *tmp = '\0' ;

	/* Get the kerberos ticket and set auth accodingly */
	if (get_kerb_ticket(shortmyhost)) {
	    auth = ZNOAUTH ; safe = 0 ;
	} else {
	    auth = ZAUTH ; safe = 1 ;
	}

	if ((retval = ZInitialize()) != ZERR_NONE) {
		syslog(LOG_INFO, "failed while initializing");
		closelog() ;
		exit(1);
	} 

	/* get the message, its on format user@offset */
	i = recvfrom(0, from, BUFSIZ, 0, (struct sockaddr*) &peer, &peersize) ;
	if (i <= 0) {
	  syslog(LOG_INFO, "error reading comsat msg") ;
	  closelog() ;
	  dest_tkt() ;
	  exit (0) ;
	}

	/* procmail contacts via localhost */
	if (peer.sin_addr.s_addr != inet_addr("127.0.0.1")) {
	  syslog(LOG_AUTH, "Someone tries to fake a comsat msg from %s", inet_ntoa(peer.sin_addr.s_addr)) ;
	  closelog() ;
	  dest_tkt() ;
	  exit(0) ;
	}
	
	from[BUFSIZ-1] = '\0' ;

	tmp = strchr(from, '@') ;
	/* Punch a hole in @ */
	if (tmp != NULL)
	    *tmp = '\0' ;

	lines[0] = myhost;
	lines[1] = "You have new mail.";
	
	(void) strcpy(mysender,ZC_NAME);
	(void) strcat(mysender,".");
	(void) strcat(mysender,shortmyhost);
	(void) strcat(mysender,"@");
	(void) strcat(mysender,ZGetRealm());

	(void) memset((char *)&notice, 0, sizeof(notice));
	notice.z_kind = (safe?UNACKED:UNSAFE) ;
	notice.z_class = MAIL_CLASS;
	notice.z_class_inst = MAIL_INSTANCE;
	notice.z_opcode = "";
	notice.z_sender = mysender;
	notice.z_default_format = "From Post Office $1:\n$2";
	
	notice.z_recipient = from ;
	
	if ((retval = ZSendList(&notice,lines,2,auth)) != ZERR_NONE) {
	  com_err(whoami,retval,"while sending notice");
	  closelog() ;
	  dest_tkt() ;
	  exit(1);
	} 

	dest_tkt() ;
	closelog() ;
	return 0 ;
}
