From fbba33d46e846cd66952bfd575b6691812430ead Mon Sep 17 00:00:00 2001 From: John Kohl Date: Wed, 20 Mar 1991 15:25:30 +0000 Subject: [PATCH] Initial revision git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@1923 dc483132-0cff-0310-8789-dd5450dbe970 --- src/appl/popper/orig-makefiles/Makefile | 108 +++++++++ src/appl/popper/pop_init.c | 235 ++++++++++++++++++ src/appl/popper/pop_pass.c | 305 ++++++++++++++++++++++++ 3 files changed, 648 insertions(+) create mode 100644 src/appl/popper/orig-makefiles/Makefile create mode 100644 src/appl/popper/pop_init.c create mode 100644 src/appl/popper/pop_pass.c diff --git a/src/appl/popper/orig-makefiles/Makefile b/src/appl/popper/orig-makefiles/Makefile new file mode 100644 index 000000000..346e4aa85 --- /dev/null +++ b/src/appl/popper/orig-makefiles/Makefile @@ -0,0 +1,108 @@ +CSRCS = pop_dele.c pop_dropcopy.c pop_dropinfo.c \ + pop_get_command.c pop_get_subcommand.c pop_init.c \ + pop_last.c pop_list.c pop_log.c pop_lower.c \ + pop_msg.c pop_parse.c pop_pass.c pop_quit.c \ + pop_rset.c pop_send.c pop_stat.c pop_updt.c \ + pop_user.c pop_xtnd.c pop_xmit.c popper.c + +OBJS = pop_dele.o pop_dropcopy.o pop_dropinfo.o \ + pop_get_command.o pop_get_subcommand.o pop_init.o \ + pop_last.o pop_list.o pop_log.o pop_lower.o \ + pop_msg.o pop_parse.o pop_pass.o pop_quit.o \ + pop_rset.o pop_send.o pop_stat.o pop_updt.o \ + pop_user.o pop_xtnd.o pop_xmit.o popper.o + +SP_SRCS = pop_enter.c +SP_OBJS = pop_enter.o + +DOCS = README pop3.rfc1081 pop3e.rfc1082 popper.8 + +INCLUDES = popper.h version.h + +SRCS = ${CSRCS} ${INCLUDES} + +SCCS = /usr/ucb/sccs + +REL = + +MAKEFILE = Makefile + +# Options are: +# BIND43 - If you are using BSD 4.3 domain +# name service. +# DEBUG - Include the debugging code. Note: You +# still have to use the -d or -t flag to +# enable debugging. +# HAVE_VSPRINTF - If the vsprintf functions are available +# on your system. +# SYSLOG42 - For BSD 4.2 syslog (default is BSD 4.3 +# syslog). +# STRNCASECMP - If you do not have strncasecmp() +# KERBEROS - If you want authentication vis Kerberos +# (tom) +# KERBEROS_PASSWD_HSCK - Use popper as passwd server + +CFLAGS = -O -DBIND43 -DKERBEROS -DNOSTATUS + +TARGET = popper + +TAR = ${TARGET}.tar + +INSTALLDIR = /usr/etc + +MANPAGE = popper.8 + +CATPAGE = popper.0 + +MANDIR = /usr/local/man/cat8 + +LIBS = -lkrb -ldes + +all: ${TARGET} + +spop: ${SP_OBJS} + cc ${SP_OBJS} -o spop ${LIBS} + +${TARGET}: ${OBJS} + cc ${OBJS} -o ${TARGET} ${LIBS} + +tar: ${SRCS} ${DOCS} ${MAKEFILE} + rm -f ${TAR} *.Z* + tar -cvf ${TAR} ${SRCS} ${DOCS} ${MAKEFILE} + compress ${TAR} + uuencode ${TAR}.Z ${TAR}.Z > ${TAR}.Z.uuencoded + split -300 ${TAR}.Z.uuencoded + mv xaa ${TAR}.Z.uuencoded.xaa + mv xab ${TAR}.Z.uuencoded.xab + mv xac ${TAR}.Z.uuencoded.xac + mv xad ${TAR}.Z.uuencoded.xad + mv xae ${TAR}.Z.uuencoded.xae + +clean: + rm -f core *~ *.o *.Z* +# ${SCCS} clean + +install: ${TARGET} + install -c -m 700 -o root -g staff ${TARGET} ${INSTALLDIR} + +installman: + rm -f ${CATPAGE} + nroff -man ${MANPAGE} > ${CATPAGE} + install -c -m 644 -o root -g staff ${CATPAGE} ${MANDIR} + +edit: + ${SCCS} edit ${REL} ${SRCS} + +admin: + ${SCCS} admin -ft"Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n" ${SRCS} + +sources: ${SRCS} + +${SRCS}: + ${SCCS} get ${REL} $@ -p | expand -4 > $@ + +${DOCS}: + ${SCCS} get README -p | expand -4 > README + ${SCCS} get popper.8 -p | expand -4 > popper.8 + +${OBJS}: popper.h version.h diff --git a/src/appl/popper/pop_init.c b/src/appl/popper/pop_init.c new file mode 100644 index 000000000..8b91109a2 --- /dev/null +++ b/src/appl/popper/pop_init.c @@ -0,0 +1,235 @@ +/* + * Copyright (c) 1989 Regents of the University of California. + * All rights reserved. The Berkeley software License Agreement + * specifies the terms and conditions for redistribution. + */ + +/* + * added kerberos authentication (tom coppeto, 1/15/91) + */ + +#ifndef lint +static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n"; +static char SccsId[] = "@(#)pop_init.c 1.12 8/16/90"; +#endif not lint + +#include +#include +#include +#include +#include +#include +#include +#include "popper.h" + +#ifdef KERBEROS +#include + +AUTH_DAT kdata; +#endif /* KERBEROS */ + +extern int errno; + +/* + * init: Start a Post Office Protocol session + */ + +pop_init(p,argcount,argmessage) +POP * p; +int argcount; +char ** argmessage; +{ + + struct sockaddr_in cs; /* Communication parameters */ + struct hostent * ch; /* Client host information */ + int errflag = 0; + int c; + int len; + extern char * optarg; + int options = 0; + int sp = 0; /* Socket pointer */ + char * trace_file_name; + + /* Initialize the POP parameter block */ + bzero ((char *)p,(int)sizeof(POP)); + + /* Save my name in a global variable */ + p->myname = argmessage[0]; + + /* Get the name of our host */ + (void)gethostname(p->myhost,MAXHOSTNAMELEN); + + /* Open the log file */ +#ifdef SYSLOG42 + (void)openlog(p->myname,0); +#else + (void)openlog(p->myname,POP_LOGOPTS,POP_FACILITY); +#endif + + /* Process command line arguments */ + while ((c = getopt(argcount,argmessage,"dt:")) != EOF) + switch (c) { + + /* Debugging requested */ + case 'd': + p->debug++; + options |= SO_DEBUG; + break; + + /* Debugging trace file specified */ + case 't': + p->debug++; + if ((p->trace = fopen(optarg,"a+")) == NULL) { + pop_log(p,POP_ERROR, + "Unable to open trace file \"%s\", err = %d", + optarg,errno); + exit(-1); + } + trace_file_name = optarg; + break; + + /* Unknown option received */ + default: + errflag++; + } + + /* Exit if bad options specified */ + if (errflag) { + (void)fprintf(stderr,"Usage: %s [-d]\n",argmessage[0]); + exit(-1); + } + + /* Get the address and socket of the client to whom I am speaking */ + len = sizeof(cs); + if (getpeername(sp,(struct sockaddr *)&cs,&len) < 0){ + pop_log(p,POP_ERROR, + "Unable to obtain socket and address of client, err = %d",errno); + exit(-1); + } + + /* Save the dotted decimal form of the client's IP address + in the POP parameter block */ + p->ipaddr = inet_ntoa(cs.sin_addr); + + /* Save the client's port */ + p->ipport = ntohs(cs.sin_port); + + /* Get the canonical name of the host to whom I am speaking */ + ch = gethostbyaddr((char *) &cs.sin_addr, sizeof(cs.sin_addr), AF_INET); + if (ch == NULL){ + pop_log(p,POP_PRIORITY, + "%s: unable to get canonical name of client, err = %d", + p->ipaddr, errno); + p->client = p->ipaddr; + } + /* Save the cannonical name of the client host in + the POP parameter block */ + else { + +#ifndef BIND43 + p->client = ch->h_name; +#else +# include +# include + + /* Distrust distant nameservers */ + extern struct state _res; + struct hostent * ch_again; + char * * addrp; + + /* We already have a fully-qualified name */ + _res.options &= ~RES_DEFNAMES; + + /* See if the name obtained for the client's IP + address returns an address */ + if ((ch_again = gethostbyname(ch->h_name)) == NULL) { + pop_log(p,POP_PRIORITY, + "%s: resolves to an unknown host name \"%s\".", + p->ipaddr,ch->h_name); + p->client = p->ipaddr; + } + else { + /* Save the host name (the previous value was + destroyed by gethostbyname) */ + p->client = ch_again->h_name; + + /* Look for the client's IP address in the list returned + for its name */ + for (addrp=ch_again->h_addr_list; *addrp; ++addrp) + if (bcmp(*addrp,&(cs.sin_addr),sizeof(cs.sin_addr)) == 0) break; + + if (!*addrp) { + pop_log (p,POP_PRIORITY, + "%s: not listed for its host name \"%s\".", + p->ipaddr,ch->h_name); + p->client = p->ipaddr; + } + } +#endif BIND43 + } + + /* Create input file stream for TCP/IP communication */ + if ((p->input = fdopen(sp,"r")) == NULL){ + pop_log(p,POP_ERROR, + "%s: unable to open communication stream for input, err = %d", + p->client, errno); + exit (-1); + } + + /* Create output file stream for TCP/IP communication */ + if ((p->output = fdopen(sp,"w")) == NULL){ + pop_log(p,POP_ERROR, + "%s: unable to open communication stream for output, err = %d", + p->client, errno); + exit (-1); + } + + pop_log(p,POP_INFO, + "%s: (v%s) Servicing request at %s\n", p->client, VERSION, p->ipaddr); + +#ifdef DEBUG + if (p->trace) + pop_log(p,POP_PRIORITY, + "Tracing session and debugging information in file \"%s\"", + trace_file_name); + else if (p->debug) + pop_log(p,POP_PRIORITY,"Debugging turned on"); +#endif DEBUG + + return(authenticate(p, &cs)); +} + + +authenticate(p, addr) + POP *p; + struct sockaddr_in *addr; +{ +#ifdef KERBEROS + Key_schedule schedule; + KTEXT_ST ticket; + char instance[INST_SZ]; + char version[9]; + int auth; + + strcpy(instance, "*"); + auth = krb_recvauth(0L, 0, &ticket, "pop", instance, + addr, (struct sockaddr_in *) NULL, + &kdata, "", schedule, version); + + if (auth != KSUCCESS) { + pop_msg(p, POP_FAILURE, "Kerberos authentication failure: %s", + krb_err_txt[auth]); + pop_log(p, POP_WARNING, "%s: (%s.%s@%s) %s", p->client, + kdata.pname, kdata.pinst, kdata.prealm, krb_err_txt[auth]); + exit(-1); + } + +#ifdef DEBUG + pop_log(p, POP_DEBUG, "%s.%s@%s (%s): ok", kdata.pname, + kdata.pinst, kdata.prealm, inet_ntoa(addr->sin_addr)); +#endif /* DEBUG */ + +#endif /* KERBEROS */ + + return(POP_SUCCESS); +} diff --git a/src/appl/popper/pop_pass.c b/src/appl/popper/pop_pass.c new file mode 100644 index 000000000..127dfb65b --- /dev/null +++ b/src/appl/popper/pop_pass.c @@ -0,0 +1,305 @@ +/* + * Copyright (c) 1989 Regents of the University of California. + * All rights reserved. The Berkeley software License Agreement + * specifies the terms and conditions for redistribution. + */ + +/* + * authorization rules for use with kerberos (tom) + * password server using kerberos (jon) + */ + +#ifndef lint +static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n"; +static char SccsId[] = "@(#)pop_pass.c 1.7 7/13/90"; +#endif not lint + +#include +#include +#include +#include +#include "popper.h" + +#ifdef KERBEROS +#include +extern AUTH_DAT kdata; +#endif /* KERBEROS */ + +#ifndef KERBEROS_PASSWD_HACK + +/* + * pass: Obtain the user password from a POP client + */ + +int pop_pass (p) +POP * p; +{ +#ifdef KERBEROS + char lrealm[REALM_SZ]; + int status; +#else + register struct passwd * pw; + char *crypt(); +#endif /* KERBEROS */ + + +#ifdef KERBEROS + if ((status = krb_get_lrealm(lrealm,1)) == KFAILURE) { + pop_log(p, POP_WARNING, "%s: (%s.%s@%s) %s", p->client, kdata.pname, + kdata.pinst, kdata.prealm, krb_err_txt[status]); + return(pop_msg(p,POP_FAILURE, + "Kerberos error: \"%s\".", krb_err_txt[status])); + } + + if (strcmp(kdata.prealm,lrealm)) { + pop_log(p, POP_WARNING, "%s: (%s.%s@%s) realm not accepted.", + p->client, kdata.pname, kdata.pinst, kdata.prealm); + return(pop_msg(p,POP_FAILURE, + "Kerberos realm \"%s\" not accepted.", kdata.prealm)); + } + + if (strcmp(kdata.pinst,"")) { + pop_log(p, POP_WARNING, "%s: (%s.%s@%s) instance not accepted.", + p->client, kdata.pname, kdata.pinst, kdata.prealm); + return(pop_msg(p,POP_FAILURE, + "Must use null Kerberos(tm) instance - \"%s.%s\" not accepted.", + kdata.pname, kdata.pinst)); + } + + /* + * be careful! we are assuming that the instance and realm have been + * checked already! I used to simply copy the pname into p->user + * but this causes too much confusion and assumes p->user will never + * change. This makes me feel more comfortable. + */ + if(strcmp(p->user, kdata.pname)) + { + pop_log(p, POP_WARNING, "%s: auth failed: %s.%s@%s vs %s", + p->client, kdata.pname, kdata.pinst, kdata.prealm, p->user); + return(pop_msg(p,POP_FAILURE, + "Wrong username supplied (%s vs. %s).\n", kdata.pname, + p->user)); + } + + /* Build the name of the user's maildrop */ + (void)sprintf(p->drop_name,"%s/%s",POP_MAILDIR,p->user); + + /* Make a temporary copy of the user's maildrop */ + if (pop_dropcopy(p) != POP_SUCCESS) return (POP_FAILURE); + +#else /* KERBEROS */ + + /* Look for the user in the password file */ + if ((pw = getpwnam(p->user)) == NULL) + return (pop_msg(p,POP_FAILURE, + "Password supplied for \"%s\" is incorrect.",p->user)); + + /* We don't accept connections from users with null passwords */ + if (pw->pw_passwd == NULL) + return (pop_msg(p,POP_FAILURE, + "Password supplied for \"%s\" is incorrect.",p->user)); + + /* Compare the supplied password with the password file entry */ + if (strcmp (crypt (p->pop_parm[1], pw->pw_passwd), pw->pw_passwd) != 0) + return (pop_msg(p,POP_FAILURE, + "Password supplied for \"%s\" is incorrect.",p->user)); + + /* Build the name of the user's maildrop */ + (void)sprintf(p->drop_name,"%s/%s",POP_MAILDIR,p->user); + + /* Make a temporary copy of the user's maildrop */ + if (pop_dropcopy(p) != POP_SUCCESS) return (POP_FAILURE); + + /* Set the group and user id */ + (void)setgid(pw->pw_gid); + (void)setuid(pw->pw_uid); + +#ifdef DEBUG + if(p->debug)pop_log(p,POP_DEBUG,"uid = %d, gid = %d",getuid(),getgid()); +#endif DEBUG + +#endif /* KERBEROS */ + + /* Get information about the maildrop */ + if (pop_dropinfo(p) != POP_SUCCESS) { + pop_log(p, POP_PRIORITY, "dropinfo failure"); + return(POP_FAILURE); + } + + /* Initialize the last-message-accessed number */ + p->last_msg = 0; + + /* Authorization completed successfully */ + return (pop_msg (p,POP_SUCCESS, + "%s has %d message(s) (%d octets).", + p->user,p->msg_count,p->drop_size)); +} + + + + + +#else /* KERBEROS_PASSWD_HACK */ + + + + +/* + * Check to see if the user is in the passwd file, if not get a kerberos + * ticket with the password + */ + + + +#include +#include +#include + +int pop_pass (p) +POP * p; +{ + register struct passwd * pw; + char *crypt(); + + setpwfile(POP_PASSFILE); + + /* Look for the user in the password file */ + pw = getpwnam(p->user); + + /* Compare the supplied password with the password file entry */ + if (pw && pw->pw_passwd) { + if (strcmp (crypt (p->pop_parm[1], pw->pw_passwd), pw->pw_passwd) != 0) + return (pop_msg(p,POP_FAILURE, + "Password supplied for \"%s\" is incorrect.",p->user)); + } + else { + if(verify_passwd_hack_hack_hack(p) != POP_SUCCESS) + return(POP_FAILURE); + + pop_log(p, POP_WARNING, "hack successful"); + } + + /* Build the name of the user's maildrop */ + (void)sprintf(p->drop_name,"%s/%s",POP_MAILDIR,p->user); + + /* Make a temporary copy of the user's maildrop */ + if (pop_dropcopy(p) != POP_SUCCESS) return (POP_FAILURE); + + /* Set the group and user id */ + (void)setgid(pw->pw_gid); + (void)setuid(pw->pw_uid); + +#ifdef DEBUG + if(p->debug)pop_log(p,POP_DEBUG,"uid = %d, gid = %d",getuid(),getgid()); +#endif DEBUG + + /* Get information about the maildrop */ + if (pop_dropinfo(p) != POP_SUCCESS) { + pop_log(p, POP_PRIORITY, "dropinfo failure"); + return(POP_FAILURE); + } + pop_log(p, POP_WARNING, "DRP successful"); + /* Initialize the last-message-accessed number */ + p->last_msg = 0; + + /* Authorization completed successfully */ + return (pop_msg (p,POP_SUCCESS, + "%s has %d message(s) (%d octets).", + p->user,p->msg_count,p->drop_size)); +} + + +/* for Ultrix and friends ... */ +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 64 +#endif + +#ifndef MAXPATHLEN +#define MAXPATHLEN 1024 +#endif + + +int verify_passwd_hack_hack_hack(p) + POP *p; +{ + char lrealm[REALM_SZ]; + int status, fd; + KTEXT_ST ticket; + AUTH_DAT kdata; + char savehost[MAXHOSTNAMELEN]; + char tkt_file_name[MAXPATHLEN]; + unsigned long faddr; + struct hostent *hp; + extern int errno; + + /* Be sure ticket file is correct and exists */ + + sprintf(tkt_file_name, "/tmp/tkt_pop.%s.%d", p->user, getpid()); + if (setenv("KRBTKFILE", tkt_file_name, 1 /* overwrite = yes */)) + return(pop_msg(p,POP_FAILURE, "Could not set ticket file name.")); + + if ((fd = open(tkt_file_name, O_RDWR|O_CREAT, 0600)) == -1) { + close(fd); + return(pop_msg(p,POP_FAILURE, "Could not create ticket file, \"%s\": %s", + tkt_file_name, sys_errlist[errno])); + } + close(fd); + + /* + * Get an initial ticket using the given name/password and then use it. + * This hack will allow us to stop maintaining a separate pop passwd + * on eagle. We can cut over to real Kerberos POP clients at any point. + */ + + if ((status = krb_get_lrealm(lrealm,1)) == KFAILURE) + return(pop_msg(p,POP_FAILURE, "Kerberos error: \"%s\".", + krb_err_txt[status])); + status = krb_get_pw_in_tkt(p->user, "", lrealm, "krbtgt", lrealm, + 2 /* 10 minute lifetime */, p->pop_parm[1]); + + if (status != KSUCCESS) + return(pop_msg(p,POP_FAILURE, + "Kerberos error: \"%s\".", krb_err_txt[status])); + + /* + * Now use the ticket for something useful, to make sure + * it is valid. + */ + + if ((hp = gethostbyname(p->myhost)) == (struct hostent *) NULL) { + dest_tkt(); + return(pop_msg(p, POP_FAILURE, + "Unable to get address of \"%s\": %s", + p->myhost, sys_errlist[errno])); + } + bcopy((char *)hp->h_addr, (char *) &faddr, sizeof(faddr)); + + (void) strncpy(savehost, krb_get_phost(p->myhost), sizeof(savehost)); + savehost[sizeof(savehost)-1] = 0; + + status = krb_mk_req(&ticket, "pop", savehost, lrealm, 0); + if (status == KDC_PR_UNKNOWN) { + return(pop_msg(p,POP_FAILURE, + "POP Server configuration error: \"%s\".", + krb_err_txt[status])); + } + + if (status != KSUCCESS) { + dest_tkt(); + return(pop_msg(p,POP_FAILURE, + "Kerberos error (getting mk_req): \"%s\".", + krb_err_txt[status])); + } + + if ((status = krb_rd_req(&ticket, "pop", savehost, faddr, &kdata, "")) + != KSUCCESS) { + dest_tkt(); + return(pop_msg(p,POP_FAILURE, + "Could not use ticket. Bad password? \"%s\".", + krb_err_txt[status])); + } + dest_tkt(); + return(POP_SUCCESS); +} + +#endif /* KERBEROS_PASSWD_HACK */ -- 2.26.2