📄 popser.c
字号:
char buffer[BUFSIZ]; register struct bboard *pw;#endif /* DPOP */#ifndef DPOP if (!rproto || (pw = getpwnam (username)) == NULL) {#ifdef TRUSTED trusted (0, hostname, vec[1], 0, username, 0, "rpop", "tcp", NULL);#endif /* TRUSTED */ return respond (NOTOK, "login incorrect"); } if (chdir (pw -> pw_dir) == NOTOK && chdir ("/") == NOTOK) return respond (NOTOK, "no remote directory"); if (ruserok (hostname, pw -> pw_uid == 0, vec[1], username) == NOTOK) {#ifdef TRUSTED trusted (0, hostname, vec[1], 0, pw -> pw_name, pw -> pw_uid == 0, "rpop", "tcp", NULL);#endif /* TRUSTED */ return respond (NOTOK, "permission denied"); }#else /* DPOP */ if (!rproto || ((pw = getbbnam (username)) == NULL && (pw = getbbaka (username)) == NULL)) {#ifdef TRUSTED trusted (0, hostname, vec[1], 0, username, 0, "rpop", "tcp", NULL);#endif /* TRUSTED */ return respond (NOTOK, "login incorrect"); }/* * hacked by Dave Cohrs Tue Feb 4 14:12:15 CST 1986 * to allow the hostname to be a list: user@host1,user@host2 * NOTE: the separator must be a comma -- no spaces are allowed */ (void) sprintf (buffer, "%s@%s", vec[1], hostname); for (bp = pw -> bb_addr; bp; bp = cp) { if ((cp = index (bp, ','))) *cp = 0; hostok = uleq (bp, buffer); if (cp) *cp++ = ','; if (hostok) break; } if (!hostok) {#ifdef TRUSTED trusted (0, hostname, vec[1], 0, pw -> bb_name, 0, "rpop", "tcp", NULL);#endif /* TRUSTED */ return respond (NOTOK, "permission denied"); }#endif /* DPOP */#ifdef TRUSTED if (trusted (1, hostname, vec[1], 0, username,#ifndef DPOP pw -> pw_uid == 0,#else /* DPOP */ 0,#endif /* DPOP */ "rpop", "tcp", NULL) == 0) return respond (NOTOK, "permission denied");#endif /* TRUSTED */ return setup (pw, FALSE);}#endif /* RPOP *//* */#ifdef APOP#include "popauth.h"#include "../../uip/md5.c"#include <ndbm.h>#include <sys/file.h>#ifdef SYS5#include <fcntl.h>#endifstatic int apop (vec)register char **vec;{ register char *cp; char buffer[BUFSIZ]; register unsigned char *dp; unsigned char *ep, digest[16];#ifndef DPOP register struct passwd *pw;#else register struct bboard *pw;#endif struct stat st; datum key, value; DBM *db; MD5_CTX mdContext; struct authinfo auth; (void) strcpy (username, vec[1]);#ifndef DPOP if ((pw = getpwnam (username)) == NULL || *pw -> pw_passwd == NULL) { return respond (NOTOK, "user invalid"); }#else if (((pw = getbbnam (username)) == NULL && (pw = getbbaka (username)) == NULL) || *pw -> bb_passwd == NULL) { return respond (NOTOK, "subscriber invalid"); }#endif if ((db = dbm_open (APOP, O_RDONLY, 0)) == NULL) return respond (NOTOK, "POP authorization DB not available (%d)", errno); if (fstat (dbm_pagfno (db), &st) != NOTOK && (st.st_mode & 0777) != 0600) { dbm_close (db); return respond (NOTOK, "POP authorization DB has wrong mode (0%o)", st.st_mode & 0777); } if (flock (dbm_pagfno (db), LOCK_SH) == NOTOK) { dbm_close (db); return respond (NOTOK, "unable to lock POP authorization DB (%d)", errno); } key.dsize = strlen (key.dptr = vec[1]) + 1; value = dbm_fetch (db, key); if (value.dptr == NULL) { dbm_close (db); return respond (NOTOK, "not authorized"); } bcopy (value.dptr, (char *) &auth, sizeof auth); (void) sprintf (cp = buffer, "%s%*.*s", timestamp, auth.auth_secretlen, auth.auth_secretlen, auth.auth_secret); dbm_close (db); MD5Init (&mdContext); MD5Update (&mdContext, (unsigned char *) buffer, (unsigned int) (strlen (timestamp) + auth.auth_secretlen)); MD5Final (digest, &mdContext); cp = buffer; for (ep = (dp = digest) + sizeof digest / sizeof digest[0]; dp < ep; cp += 2) (void) sprintf (cp, "%02x", *dp++ & 0xff); *cp = NULL; if (strcmp (vec[2], buffer)) return respond (NOTOK, "authentication failure"); return setup (pw, 0);}#endif/* */static int setup (pw, guest)#ifndef DPOPregister struct passwd *pw;#else /* DPOP */register struct bboard *pw;#endif /* DPOP */int guest;{#ifdef BPOP if (guest) { (void) setgid (guest_gid);#ifndef SYS5 (void) initgroups (popbbuser, guest_gid);#endif /* SYS5 */ (void) setuid (guest_uid); } else {#endif /* BPOP */#ifndef DPOP (void) setgid (pw -> pw_gid);#ifndef SYS5 (void) initgroups (pw -> pw_name, pw -> pw_gid);#endif /* SYS5 */ (void) setuid (pw -> pw_uid);#else /* DPOP */ (void) setgid (pop_gid);#ifndef SYS5 (void) initgroups (POPUID, pop_gid);#endif /* SYS5 */ (void) setuid (pop_uid);#endif /* DPOP */#ifdef BPOP }#endif /* BPOP */#ifndef DPOP (void) sprintf (maildrop, "%s/%s", mmdfldir && *mmdfldir ? mmdfldir : pw -> pw_dir, mmdflfil && *mmdflfil ? mmdflfil : pw -> pw_name);#else /* DPOP */ (void) strcpy (maildrop, pw -> bb_file);#endif /* DPOP */ if (setupaux (guest) == NOTOK) return NOTOK;#ifdef POP2 if (pop2 != NOTOK) { /* in response to pop2 "helo" */ pop2 = nmsgs > 0 ? 1 : 0; return respond ('#', "%d message%s (%d octets)", nmsgs, nmsgs != 1 ? "s" : "", Msgs[0].m_size); } else#endif /* POP2 */ return respond (OK, nmsgs ? "maildrop has %d message%s (%d octets)" : "maildrop empty", nmsgs, nmsgs != 1 ? "s" : "", Msgs[0].m_size);}/* */static int setupaux (readonly)int readonly;{ register int i, msgp; struct stat st;#ifdef BPOP xtnded = 0;#endif /* BPOP */ if ((dp = readonly ? fopen (maildrop, "r") : lkfopen (maildrop, "r")) == NULL) switch (errno) { case ENOENT: m_gMsgs (msgp = 0); goto no_mail; default: nmsgs = dmsgs = 0; return respond (NOTOK, "unable to %s maildrop: \"%s\"", readonly ? "read" : "lock", maildrop); } if (fstat (fileno (dp), &st) != NOTOK) { mode = (int) (st.st_mode & 0777), mtime = st.st_mtime; msgp = read_map (maildrop, (long) st.st_size); } else { mode = 0600, mtime = 0; msgp = 0; } if ((msgp = read_file (msgp ? Msgs[msgp].m_stop : 0L, msgp + 1)) < 1) m_gMsgs (0);no_mail: ; lastseen = Msgs[0].m_last;if(debug)padvise(NULLCP,LOG_DEBUG,"XXX: lastseen=%d",lastseen); dmsgs = rmsgs = 0; nmsgs = msgp; Msgs[0].m_flags = readonly ? MREAD : MNULL; Msgs[0].m_size = 0; for (i = 1; i <= nmsgs; i++) { if (Msgs[i].m_size == 0) Msgs[i].m_size = pmbx_size (i); Msgs[0].m_size += Msgs[i].m_size; Msgs[i].m_flags = MNULL; } return OK;}/* */static int read_map (file, pos)char *file;long pos;{ register int i, msgp; register struct drop *pp, *mp; struct drop *rp; if (debug) padvise (NULLCP, LOG_DEBUG, "read_map (%s, %ld)", file, pos); if ((i = map_read (file, pos, &rp, debug)) == 0) return 0; m_gMsgs (i); Msgs[0].m_last = rp -> d_start; msgp = 1; for (pp = rp + 1; i-- > 0; msgp++, pp++) { mp = &Msgs[msgp].m_drop; mp -> d_id = pp -> d_id; mp -> d_size = pp -> d_size; mp -> d_start = pp -> d_start; mp -> d_stop = pp -> d_stop; } free ((char *) rp); if (Msgs[0].m_last > msgp) { if (debug) padvise (NULLCP, LOG_DEBUG, "lastseen adjusted from %d to %d", Msgs[0].m_last, msgp); Msgs[0].m_last = msgp; } return (msgp - 1);}/* */static int read_file (pos, msgp)register long pos;register int msgp;{ register int i; register struct drop *pp, *mp; struct drop *rp; if (debug) padvise (NULLCP, LOG_DEBUG, "read_file (%ld, %d)", pos, msgp); if ((i = MBX_READ (dp, pos, &rp, debug)) <= 0) return (msgp - 1); m_gMsgs ((msgp - 1) + i); for (pp = rp; i-- > 0; msgp++, pp++) { mp = &Msgs[msgp].m_drop; mp -> d_id = 0; mp -> d_size = pp -> d_size; mp -> d_start = pp -> d_start; mp -> d_stop = pp -> d_stop; } free ((char *) rp); return (msgp - 1);}/* */static m_gMsgs (n)int n;{ if (debug) padvise (NULLCP, LOG_DEBUG, "m_gMsgs (%d) 0x%x %d", n, Msgs, nMsgs); if (Msgs == NULL) { nMsgs = n + MAXFOLDER / 2; Msgs = (struct Msg *) calloc ((unsigned) (nMsgs + 2), sizeof *Msgs); if (Msgs == NULL) padios (NULLCP, "unable to allocate Msgs structure"); return; } if (nMsgs >= n) return; nMsgs = n + MAXFOLDER / 2; Msgs = (struct Msg *) realloc ((char *) Msgs, (unsigned) (nMsgs + 2) * sizeof *Msgs); if (Msgs == NULL) padios (NULLCP, "unable to reallocate Msgs structure");}/* */static int pmbx_size (m)register int m;{ register int i; register long pos; (void) fseek (dp, Msgs[m].m_start, 0); for (i = 0, pos = Msgs[m].m_stop - Msgs[m].m_start; pos > 0; i++, pos--) if (fgetc (dp) == '\n') i++; return i;}/* *//* ARGSUSED */static int status (vec)char **vec;{ return respond (OK, "%d %d", nmsgs - dmsgs, Msgs[0].m_size);}#ifdef POP2static int rdp2 (vec) /* always returns OK */char **vec;{ if (vec[1]) { if ((pop2 = atoi (vec[1])) <= 0) pop2 = 0; } else if (pop2 == 0) return NOTOK; /* close 'em down */ if (pop2 <= 0 || pop2 > nmsgs) { pop2 = 0; return respond ('=', "0 no message"); } if (Msgs[pop2].m_flags & MDELE) { pop2 = 0; return respond ('=', "0 message %d is deleted", pop2); } return respond ('=', "%d (message %d)", Msgs[pop2].m_size, pop2);}static int ack2 (vec)char **vec;{ if (strcmp (vec[0], "ackd") == 0) { Msgs[pop2].m_flags |= MDELE; /* ignored later if MREAD */ Msgs[0].m_size -= Msgs[pop2].m_size; dmsgs++; } if (pop2) { /* a current msg */ rmsgs++; /* mark this one as read */ if (++pop2 > nmsgs) pop2 = -1; /* let rdp2 reset */ else if (Msgs[pop2].m_flags & MDELE) pop2 = -1; /* let rdp2 reset */ if (pop2 > Msgs[0].m_last) Msgs[0].m_last = pop2; } return rdp2 (vec); /* vec = { "acks", 0 } */}static int fold (vec)register char **vec;{ pop2 = 0;#ifdef notdef /* This might work, or it might be a huge security hole. For my purpose, * it doesn't need to work, so I'm not going to make sure it's OK. * 16Nov90/JLR */ if (quitaux (NULLVP) == NOTOK) return respond ('#', "0 unable to close folder"); (void) sprintf (maildrop, vec[1]); if (setupaux (access (maildrop, 2) ? 1 : 0) == NOTOK) return respond ('#', "0 unable to read %s", maildrop); pop2 = nmsgs > 0 ? 1 : 0; return respond ('#', "%d message%s in %s (%d octets)", nmsgs, nmsgs != 1 ? "s" : "", maildrop, Msgs[0].m_size); #endif respond ('#', "0 unable to change folders"); return NOTOK;}#endif /* POP2 */static int list (vec)register char **vec;{ register int i; if (vec[1]) { if ((i = atoi (vec[1])) <= 0 || i > nmsgs) return respond (NOTOK, "no such message: \"%s\"", vec[1]); if (Msgs[i].m_flags & MDELE) return respond (NOTOK, "message %d is deleted", i);#ifndef BPOP return respond (OK, "%d %d", i, Msgs[i].m_size);#else /* BPOP */#ifdef MPOP if (nfs && !xtnded) { char *cp; (void) fseek (dp, Msgs[i].m_start, 0); switch (scan (dp, i, 0, nfs, 0, 0, NULLCP, (long) Msgs[i].m_size, 0)) { case SCNMSG: case SCNENC: case SCNERR: if (cp = index (scanl, '\n')) *cp = NULL; return respond (OK, "%d %d #%s", i, Msgs[i].m_size, scanl); case SCNEOF: return respond (OK, "%d %d #%*d empty", i, Msgs[i].m_size, DMAXFOLDER, i); default: break; } }#endif /* MPOP */ return respond (OK, xtnded ? "%d %d %d" : "%d %d", i, Msgs[i].m_size, Msgs[i].m_id);#endif /* BPOP */ } (void) respond (OK, "%d message%s (%d octets)", nmsgs - dmsgs, nmsgs - dmsgs != 1 ? "s" : "", Msgs[0].m_size); for (i = 1; i <= nmsgs; i++) if (!(Msgs[i].m_flags & MDELE)) {#ifndef BPOP multiline ("%d %d", i, Msgs[i].m_size);#else /* BPOP */#ifdef MPOP if (nfs && !xtnded) { char *cp; (void) fseek (dp, Msgs[i].m_start, 0); switch (scan (dp, i, 0, nfs, 0, 0, NULLCP, (long) Msgs[i].m_size, 0)) { case SCNMSG: case SCNENC: case SCNERR: if (cp = index (scanl, '\n')) *cp = NULL; multiline ("%d %d #%s", i, Msgs[i].m_size, scanl); continue; case SCNEOF: multiline ("%d %d #%*d empty", i, Msgs[i].m_size, DMAXFOLDER, i); continue; default: break; } }#endif /* MPOP */ multiline (xtnded ? "%d %d %d" : "%d %d", i, Msgs[i].m_size, Msgs[i].m_id);#endif /* BPOP */ } multiend (); return OK;}/* */static int retrieve (vec)register char **vec;{ register int i; register long pos; register char *cp; char buffer[BUFSIZ];#ifdef POP2 if (pop2 == 0) return NOTOK; else if (pop2 == NOTOK) {#endif if ((i = atoi (vec[1])) <= 0 || i > nmsgs) return respond (NOTOK, "no such message: \"%s\"", vec[1]); if (Msgs[i].m_flags & MDELE) return respond (NOTOK, "message %d is deleted", i);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -