📄 popser.c
字号:
/* popser.c - the POP service */#ifndef lintstatic char ident[]="@(#)$Id: popser.c,v 1.31 1993/08/25 17:23:14 jromine Exp $";#endif#include "../h/mh.h"#include "../h/dropsbr.h"#ifdef MPOP#ifdef BPOP#include "../h/formatsbr.h"#include "../h/scansbr.h"#endif#endif /* MPOP */#include "../zotnet/bboards.h"#include <stdio.h>#include "../zotnet/mts.h"#include <ctype.h>#include <errno.h>#include <pwd.h>#include <signal.h>#include "syslog.h"#include <sys/types.h>#include <sys/stat.h>#ifdef KPOP#include <krb.h>#endif /* KPOP */#ifdef SYS5#include <fcntl.h>#endif /* SYS5 */#ifdef SHADOW#include <shadow.h>#endif /* SHADOW */#define TRUE 1#define FALSE 0#define NVEC 5#ifndef POPSERVICE#define POPSERVICE "pop"#endif/* */extern int errno;extern int debug;extern char myhost[];extern char *myname;#ifndef POP2static enum state { auth1, auth2, trans, update, halt, error} mystate;#elsestatic enum state { auth1, auth2, trans, mbox, item, ack, update, halt, error} mystate;#endifstatic int user (), pass ();#ifdef BPOPstatic isguest(), getbbmax();#ifndef MPOPstatic int xtnd1(), xtnd2();#elsestatic int xtnd1(), xtnd2(), xtnd3 ();#endif /* MPOP */#endif /* BPOP */#ifdef RPOPstatic int rpop ();#endif /* RPOP */#ifdef APOPstatic int apop ();#endifstatic int status (), list (), retrieve (), delete (), reset ();static int top (), last ();#ifdef BPOPstatic int xtnd ();#endif /* BPOP */static int quit ();#ifdef POP2static int helo (), rdp2 (), acks (), ack2 (), fold (), nack ();#endif /* POP2 */static struct vector { char *v_cmd; int v_min, v_max; int (*v_vec) (); enum state v_valid; enum state v_win, v_lose;} vectors[] = { "user", 1, 1, user, auth1, auth2, auth1, "pass", 1, 1, pass, auth2, trans, auth1,#ifdef RPOP "rpop", 1, 1, rpop, auth2, trans, auth1,#endif /* RPOP */#ifdef APOP "apop", 2, 2, apop, auth1, trans, auth1,#endif "quit", 0, 0, NULL, auth1, halt, halt, "quit", 0, 0, NULL, auth2, halt, halt, "stat", 0, 0, status, trans, trans, trans, "list", 0, 1, list, trans, trans, trans, "retr", 1, 1, retrieve, trans, trans, trans, "dele", 1, 1, delete, trans, trans, trans, "noop", 0, 0, NULL, trans, trans, trans, "rset", 0, 0, reset, trans, trans, trans, "top", 2, 2, top, trans, trans, trans, "last", 0, 0, last, trans, trans, trans,#ifdef BPOP#ifndef MPOP "xtnd", 1, 2, xtnd, trans, trans, trans,#else "xtnd", 1, 3, xtnd, trans, trans, trans,#endif /* MPOP */#endif /* BPOP */ "quit", 0, 0, quit, trans, halt, halt,#ifdef POP2 "helo", 2, 2, helo, auth1, mbox, auth1, "fold", 1, 1, fold, mbox, mbox, mbox, "quit", 0, 0, quit, mbox, halt, halt, "read", 0, 1, rdp2, mbox, item, error, "fold", 1, 1, fold, item, mbox, mbox, "read", 0, 1, rdp2, item, item, error, "quit", 0, 0, quit, item, halt, halt, "retr", 0, 0, retrieve, item, ack, error, "acks", 0, 0, ack2, ack, item, error, "ackd", 0, 0, ack2, ack, item, error, "nack", 0, 0, rdp2, ack, item, error, "quit", 0, 0, NULL, ack, halt, halt,#endif /* POP2 */ NULL};static struct vector *getvector ();/* */#ifdef POP2static int pop2 = NOTOK; /* current pop2 msg, or NOTOK if pop3 */#endif /* POP2 */#ifdef DPOPstatic int pop_uid;static int pop_gid;#endif /* DPOP */static int rproto;static char *hostname;static char server[BUFSIZ];static char timestamp[BUFSIZ];static char username[BUFSIZ];static char maildrop[BUFSIZ];static int mode;static time_t mtime;static FILE *dp;static long lastseen;static int rmsgs;#ifdef BPOPstatic int xtnded;static int guest_uid;static int guest_gid;static struct bboard *BBhead = NULL;static struct bboard *BBtail = NULL;static long BBtime = 0L;static struct bboard *getbbaux ();#endif /* BPOP */struct Msg { /* Msgs[0] contains info for entire maildrop */ struct drop m_drop;#define m_id m_drop.d_id#define m_size m_drop.d_size#define m_last m_drop.d_start /* Msgs[i = 0] */#define m_start m_drop.d_start /* Msgs[i > 0] */#define m_stop m_drop.d_stop unsigned m_flags;#define MNULL 0x00#define MDELE 0x01#define MREAD 0x02};static int nMsgs = 0;static struct Msg *Msgs = NULL;static int nmsgs;static int dmsgs;#ifdef MPOP#ifdef BPOPstatic int _sc_width = 0;static char *nfs = NULL;#endif#endif /* MPOP */#define TRM "."#define TRMLEN (sizeof TRM - 1)#define IAC 255static TYPESIG pipeser ();FILE *input;FILE *output;#ifndef __STDC__#ifdef SYS5struct passwd *getpwnam();#endif#endifvoid padvise (), padios ();char *crypt ();#ifdef POPUUMBOX#define MBX_READ pmbx_readstatic int pmbx_read ();static char *p_copy(), *p_copyin(), *p_nextword();static p_cmatch(), p_isdate(), p_ishead(), p_parse(), any();#else#define MBX_READ mbx_read#endifextern int mbx_read ();static int setup(), setupaux(), read_map(), read_file(), pmbx_size();static int quitaux(), quitfile(), respond(), getline();static m_gMsgs(), multiline(), multiend(), putline();/* */popinit () {#ifdef BPOP padvise (NULLCP, LOG_INFO, "initialize list of BBoards"); BBhead = BBtail = NULL; while (getbbaux (NULLCP)) continue;#endif /* BPOP */}popassert () {#ifdef BPOP register char **p; register struct bboard *bb, *bp; if (BBtime == getbbtime ()) return; padvise (NULLCP, LOG_INFO, "list of BBoards has changed"); for (bb = BBhead; bb; bb = bp) { bp = bb -> bb_next; if (bb -> bb_name) free (bb -> bb_name); if (bb -> bb_file) free (bb -> bb_file); if (bb -> bb_archive) free (bb -> bb_archive); if (bb -> bb_info) free (bb -> bb_info); if (bb -> bb_map) free (bb -> bb_map); if (bb -> bb_passwd) free (bb -> bb_passwd); if (bb -> bb_date) free (bb -> bb_date); if (bb -> bb_addr) free (bb -> bb_addr); if (bb -> bb_request) free (bb -> bb_request); if (bb -> bb_relay) free (bb -> bb_relay); for (p = bb -> bb_aka; *p; p++) free (*p); free ((char *) bb -> bb_aka); for (p = bb -> bb_leader; *p; p++) free (*p); free ((char *) bb -> bb_leader); for (p = bb -> bb_dist; *p; p++) free (*p); free ((char *) bb -> bb_dist); free ((char *) bb); } BBhead = BBtail = NULL; while (getbbaux (NULLCP)) continue;#endif /* BPOP */}/* */#ifdef KPOPstatic char *kusername;kpop (in, out, principal, rhost, auth)int in, out;char *principal, *rhost;int auth;#else /* KPOP */pop (in, out, priv, rhost)int in, out, priv;char *rhost;#endif /* KPOP */{ char buffer[BUFSIZ], *vec[NVEC + 1];#if defined (DPOP) || defined (BPOP) register struct passwd *pw;#endif /* defined (DPOP) || defined (BPOP) */ register struct vector *v; m_foil (NULLCP); mts_init (myname); hostname = rhost;#ifdef KPOP rproto = 1; (void) sprintf (server, "%s KPOP server", myhost);#else rproto = priv; (void) sprintf (server, "%s server", priv ? "RPOP" : "POP");#endif /* KPOP */ if ((input = fdopen (in, "r")) == NULL || (output = fdopen (out, "w")) == NULL) {/* you lose big */ (void) respond (NOTOK, "%s loses on initialization", server); return; } (void) signal (SIGPIPE, pipeser);#ifdef KPOP if (principal == NULLCP) { char buf[512]; strcpy(buf, "Authentication failed: "); strcat(buf, krb_err_txt[auth]); (void) respond (NOTOK, buf); return; } kusername = principal;#endif /* KPOP */#ifdef DPOP if ((pw = getpwnam (POPUID)) == NULL || !setpwinfo (pw, POPDB, 1)) { (void) respond (NOTOK, "%s loses on DB initialization -- %s", server, pw ? getbberr () : "POP user-id unknown"); return; } pop_uid = pw -> pw_uid; pop_gid = pw -> pw_gid;#endif /* DPOP */#ifdef BPOP if ((pw = getpwnam (popbbuser)) && pw -> pw_uid) { guest_uid = pw -> pw_uid; guest_gid = pw -> pw_gid; } else guest_uid = guest_gid = 0;#endif /* BPOP */ { long clock; (void) time (&clock); (void) sprintf (timestamp, "<%d.%ld@%s>", getpid (), clock, myhost); } (void) respond (OK, "%s ready %s", server, timestamp); for (mystate = auth1; mystate != halt && mystate != error;) switch (getline (buffer, sizeof buffer, input)) { case OK: if ((v = getvector (buffer, vec)) == NULL) continue; mystate = (v -> v_vec ? (v -> v_vec) (vec) : respond (OK, NULLCP)) == OK ? v -> v_win : v -> v_lose; break; case NOTOK: case DONE: mystate = error; (void) respond (NOTOK, "%s signing off", server); break; }}/* */#ifdef POP2static int helo (vec) /* sort of "user" and "pass" */register char **vec;{ pop2 = 0; /* now we're talkin' pop2! */ make_lower (username, vec[1]); /* helo user pass */ return pass (++vec); /* user pass */}#endifstatic int user (vec)register char **vec;{ make_lower (username, vec[1]);#ifdef KPOP if (!strcmp(username, kusername)) return respond (OK, "Kerberos authentication succeeded. Send username as password (%s)", username); else { respond (NOTOK, "Wrong username supplied (%s vs. %s)", kusername, username); return (NOTOK); }#else return respond (OK, "password required for %s", username);#endif}/* */static int pass (vec)register char **vec;{ int guest = 0;#ifndef DPOP register struct passwd *pw;#ifdef SHADOW register struct spwd *shpw;#endif /* SHADOW */#else /* DPOP */ register struct bboard *pw;#endif /* DPOP */#ifdef KPOP#ifndef DPOP if ((pw = getpwnam (username)) != NULL) return setup(pw, FALSE); else return respond (NOTOK, "no local password entry");#else { static struct bboard entry; static char entry_file[BUFSIZ] = "/usr/spool/pop"; pw = &entry; pw->bb_name = username; strcat(entry_file, username); pw->bb_file = entry_file; return setup(pw, FALSE); }#endif#else /* KPOP */#ifndef DPOP#ifdef BPOP if (isguest ()) {#ifdef TRUSTED static passwd gw; gw.pw_name = popbbuser; gw.pw_uid = guest_uid; pw = &gw;#endif /* TRUSTED */ guest = 1; goto anonymous; }#endif /* BPOP */ if ((pw = getpwnam (username)) == NULL#ifndef SHADOW || *pw -> pw_passwd == NULL || strcmp (crypt (vec[1], pw -> pw_passwd), pw -> pw_passwd)) {#else /* SHADOW */ || (shpw = getspnam (username)) == NULL || *shpw -> sp_pwdp == NULL || strcmp (crypt (vec[1], shpw -> sp_pwdp), shpw -> sp_pwdp)) {#endif /* SHADOW */#ifdef TRUSTED trusted (0, hostname, NULLCP, 0, pw ? pw -> pw_name : username, pw && pw -> pw_uid == 0, POPSERVICE, "tcp", NULL);#endif /* TRUSTED */ return respond (NOTOK, "login incorrect"); }#else /* DPOP */#ifdef BPOP if (isguest ()) { static struct bboard gw; gw.bb_name = popbbuser; pw = &gw; guest = 1; goto anonymous; }#endif /* BPOP */ if (((pw = getbbnam (username)) == NULL && (pw = getbbaka (username)) == NULL) || *pw -> bb_passwd == NULL || strcmp (crypt (vec[1], pw -> bb_passwd), pw -> bb_passwd)) {#ifdef TRUSTED trusted (0, hostname, NULLCP, 0, pw ? pw -> bb_name : username, 0, POPSERVICE, "tcp", NULL);#endif /* TRUSTED */ return respond (NOTOK, "login incorrect"); }#endif /* DPOP */#ifdef BPOPanonymous: ;#endif /* BPOP */#ifdef TRUSTED if (trusted (1, hostname, NULLCP, 0, myhost,#ifndef DPOP pw -> pw_name, pw -> pw_uid == 0,#else /* DPOP */ pw -> bb_name, 0,#endif /* DPOP */ POPSERVICE, "tcp", NULL) == 0) return respond (NOTOK, "permission denied");#endif /* TRUSTED */ return setup (pw, guest);#endif /* KPOP */}/* */#ifdef BPOPstatic isguest () { int i; register char *cp; char buffer[BUFSIZ]; register FILE *fp; if (strcmp (username, popbbuser) || !guest_uid) return FALSE; if (popbblist == NULL || (fp = fopen (popbblist, "r")) == NULL) return TRUE; i = FALSE; if (hostname) while (fgets (buffer, sizeof buffer, fp)) { if (cp = index (buffer, '\n')) *cp = NULL; if (strcmp (buffer, hostname) == 0) { i = TRUE; break; } } (void) fclose (fp); return i;}#endif /* BPOP *//* */#ifdef RPOPstatic int rpop (vec)register char **vec;{#ifndef DPOP register struct passwd *pw;#else /* DPOP */ register int hostok = 0; register char *bp, *cp;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -