📄 ipop3d.c
字号:
} state = LOGOUT; stream = NIL; _exit (1); /* die die die */ }}/* Kiss Of Death interrupt */void kodint (){ /* only if idle */ if (idletime && ((time (0) - idletime) > KODTIMEOUT)) { alarm (0); /* disable all interrupts */ server_init (NIL,NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); PSOUT ("-ERR Received Kiss of Death\015\012"); syslog (LOG_INFO,"Killed (lost mailbox lock) user=%.80s host=%.80s", user ? user : "???",tcp_clienthost ()); if (critical) state =LOGOUT;/* must defer if in critical code */ else { /* try to gracefully close the stream */ if ((state == TRANSACTION) && !stream->lock) { rset (); mail_close (stream); } state = LOGOUT; stream = NIL; _exit (1); /* die die die */ } }}/* Hangup interrupt */void hupint (){ alarm (0); /* disable all interrupts */ server_init (NIL,NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); syslog (LOG_INFO,"Hangup user=%.80s host=%.80s",user ? user : "???", tcp_clienthost ()); if (critical) state = LOGOUT; /* must defer if in critical code */ else { /* try to gracefully close the stream */ if ((state == TRANSACTION) && !stream->lock) { rset (); mail_close (stream); } state = LOGOUT; stream = NIL; _exit (1); /* die die die */ }}/* Termination interrupt */void trmint (){ alarm (0); /* disable all interrupts */ server_init (NIL,NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); PSOUT ("-ERR Killed\015\012"); syslog (LOG_INFO,"Killed user=%.80s host=%.80s",user ? user : "???", tcp_clienthost ()); if (critical) state = LOGOUT; /* must defer if in critical code */ else { /* try to gracefully close the stream */ if ((state == TRANSACTION) && !stream->lock) { rset (); mail_close (stream); } state = LOGOUT; stream = NIL; _exit (1); /* die die die */ }}/* Parse PASS command * Accepts: pointer to command argument * Returns: new state */int login (char *t,int argc,char *argv[]){ char tmp[TMPLEN]; /* flush old passowrd */ if (pass) fs_give ((void **) &pass); if (!(t && *t)) { /* if no password given */ PSOUT ("-ERR Missing password argument\015\012"); return AUTHORIZATION; } pass = cpystr (t); /* copy password argument */ if (!host) { /* want remote mailbox? */ /* no, delimit user from possible admin */ if (t = strchr (user,'*')) *t++ ='\0'; /* attempt the login */ if (server_login (user,pass,t,argc,argv)) { int ret = mbxopen ("INBOX"); if (ret == TRANSACTION) /* mailbox opened OK? */ syslog (LOG_INFO,"%sLogin user=%.80s host=%.80s nmsgs=%ld/%ld", t ? "Admin " : "",user,tcp_clienthost (),nmsgs,stream->nmsgs); else syslog (LOG_INFO,"%sLogin user=%.80s host=%.80s no mailbox", t ? "Admin " : "",user,tcp_clienthost ()); return ret; } }#ifndef DISABLE_POP_PROXY /* remote; build remote INBOX */ else if (anonymous_login (argc,argv)) { syslog (LOG_INFO,"IMAP login to host=%.80s user=%.80s host=%.80s",host, user,tcp_clienthost ()); sprintf (tmp,"{%.128s/user=%.128s}INBOX",host,user); /* disable rimap just in case */ mail_parameters (NIL,SET_RSHTIMEOUT,0); return mbxopen (tmp); }#endif /* vague error message to confuse crackers */ PSOUT ("-ERR Bad login\015\012"); return AUTHORIZATION;}/* Authentication responder * Accepts: challenge * length of challenge * pointer to response length return location if non-NIL * Returns: response */#define RESPBUFLEN 8*MAILTMPLENchar *responder (void *challenge,unsigned long clen,unsigned long *rlen){ unsigned long i,j; unsigned char *t,resp[RESPBUFLEN]; if (initial) { /* initial response given? */ if (clen) return NIL; /* not permitted */ /* set up response */ t = (unsigned char *) initial; initial = NIL; /* no more initial response */ return (char *) rfc822_base64 (t,strlen ((char *) t),rlen ? rlen : &i); } PSOUT ("+ "); for (t = rfc822_binary (challenge,clen,&i),j = 0; j < i; j++) if (t[j] > ' ') PBOUT (t[j]); fs_give ((void **) &t); CRLF; PFLUSH; /* dump output buffer */ resp[RESPBUFLEN-1] = '\0'; /* last buffer character is guaranteed NUL */ alarm (LOGINTIMEOUT); /* get a response under timeout */ clearerr (stdin); /* clear stdin errors */ /* read buffer */ while (!PSIN ((char *) resp,RESPBUFLEN)) { /* ignore if some interrupt */ if (ferror (stdin) && (errno == EINTR)) clearerr (stdin); else { char *e = ferror (stdin) ? strerror (errno) : "Command stream end of file"; alarm (0); /* disable all interrupts */ server_init (NIL,NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); syslog (LOG_INFO,"%s, while reading authentication host=%.80s", e,tcp_clienthost ()); state = UPDATE; _exit (1); } } if (!(t = (unsigned char *) strchr ((char *) resp,'\012'))) { int c; while ((c = PBIN ()) != '\012') if (c == EOF) { /* ignore if some interrupt */ if (ferror (stdin) && (errno == EINTR)) clearerr (stdin); else { char *e = ferror (stdin) ? strerror (errno) : "Command stream end of file"; alarm (0); /* disable all interrupts */ server_init (NIL,NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); syslog (LOG_INFO,"%s, while reading auth char user=%.80s host=%.80s", e,user ? user : "???",tcp_clienthost ()); state = UPDATE; _exit (1); } } return NIL; } alarm (0); /* make sure timeout disabled */ if (t[-1] == '\015') --t; /* remove CR */ *t = '\0'; /* tie off buffer */ return (resp[0] != '*') ? (char *) rfc822_base64 (resp,t-resp,rlen ? rlen : &i) : NIL;}/* Select mailbox * Accepts: mailbox name * Returns: new state */int mbxopen (char *mailbox){ unsigned long i,j; char tmp[TMPLEN]; MESSAGECACHE *elt; nmsgs = 0; /* no messages yet */ if (msg) fs_give ((void **) &msg); /* open mailbox */ if (stream = mail_open (stream,mailbox,NIL)) { if (!stream->rdonly) { /* make sure not readonly */ if (j = stream->nmsgs) { /* if mailbox non-empty */ sprintf (tmp,"1:%lu",j);/* fetch fast information for all messages */ mail_fetch_fast (stream,tmp,NIL); msg = (long *) fs_get ((stream->nmsgs + 1) * sizeof (long)); for (i = 1; i <= j; i++) if (!(elt = mail_elt (stream,i))->deleted) { msg[++nmsgs] = i; /* note the presence of this message */ if (elt->seen) il = last = nmsgs; } } sprintf (tmp,"+OK Mailbox open, %lu messages\015\012",nmsgs); PSOUT (tmp); return TRANSACTION; } else sayonara = "-ERR Can't get lock. Mailbox in use\015\012"; } else sayonara = "-ERR Unable to open user's INBOX\015\012"; syslog (LOG_INFO,"Error opening or locking INBOX user=%.80s host=%.80s", user,tcp_clienthost ()); return UPDATE;}/* Blat a string with dot checking * Accepts: string * maximum number of lines if greater than zero * maximum number of bytes to output * Returns: number of lines output * * This routine is uglier and kludgier than it should be, just to be robust * in the case of a message which doesn't end in a newline. Yes, this routine * does truncate the last two bytes from the text. Since it is normally a * newline and the main routine adds it back, it usually does not make a * difference. But if it isn't, since the newline is required and the octet * counts have to match, there's no choice but to truncate. */long blat (char *text,long lines,unsigned long size){ char c,d,e; long ret = 0; /* no-op if zero lines or empty string */ if (!(lines && (size-- > 2))) return 0; c = *text++; d = *text++; /* collect first two bytes */ if (c == '.') PBOUT ('.'); /* double string-leading dot if necessary */ while (lines && --size) { /* copy loop */ e = *text++; /* get next byte */ PBOUT (c); /* output character */ if (c == '\012') { /* end of line? */ ret++; --lines; /* count another line */ /* double leading dot as necessary */ if (lines && size && (d == '.')) PBOUT ('.'); } c = d; d = e; /* move to next character */ } return ret;}/* Reset mailbox */void rset (){ unsigned long i; char tmp[20]; if (nmsgs) { /* undelete and unmark all of our messages */ for (i = 1; i <= nmsgs; i++) { /* */ if (msg[i] < 0) { /* ugly and inefficient, but trustworthy */ sprintf (tmp,"%ld",msg[i] = -msg[i]); mail_clearflag (stream,tmp,i <= il ? "\\Deleted" : "\\Deleted \\Seen"); } else if (i > il) { sprintf (tmp,"%ld",msg[i]); mail_clearflag (stream,tmp,"\\Seen"); } } last = il; } ndele = 0; /* no more deleted messages */}/* Co-routines from MAIL library *//* Message matches a search * Accepts: MAIL stream * message number */void mm_searched (MAILSTREAM *stream,unsigned long msgno){ /* Never called */}/* Message exists (i.e. there are that many messages in the mailbox) * Accepts: MAIL stream * message number */void mm_exists (MAILSTREAM *stream,unsigned long number){ /* Can't use this mechanism. POP has no means of notifying the client of new mail during the session. */}/* Message expunged * Accepts: MAIL stream * message number */void mm_expunged (MAILSTREAM *stream,unsigned long number){ unsigned long i = number + 1; msg[number] = 0; /* I bet that this will annoy someone */ while (i <= nmsgs) --msg[i++];}/* Message flag status change * Accepts: MAIL stream * message number */void mm_flags (MAILSTREAM *stream,unsigned long number){ /* This isn't used */}/* Mailbox found * Accepts: MAIL stream * hierarchy delimiter * mailbox name * mailbox attributes */void mm_list (MAILSTREAM *stream,int delimiter,char *name,long attributes){ /* This isn't used */}/* Subscribe mailbox found * Accepts: MAIL stream * hierarchy delimiter * mailbox name * mailbox attributes */void mm_lsub (MAILSTREAM *stream,int delimiter,char *name,long attributes){ /* This isn't used */}/* Mailbox status * Accepts: MAIL stream * mailbox name * mailbox status */void mm_status (MAILSTREAM *stream,char *mailbox,MAILSTATUS *status){ /* This isn't used */}/* Notification event * Accepts: MAIL stream * string to log * error flag */void mm_notify (MAILSTREAM *stream,char *string,long errflg){ mm_log (string,errflg); /* just do mm_log action */}/* Log an event for the user to see * Accepts: string to log * error flag */void mm_log (char *string,long errflg){ switch (errflg) { case NIL: /* information message */ case PARSE: /* parse glitch */ break; /* too many of these to log */ case WARN: /* warning */ syslog (LOG_DEBUG,"%s",string); break; case ERROR: /* error that broke command */ default: /* default should never happen */ syslog (LOG_NOTICE,"%s",string); break; }}/* Log an event to debugging telemetry * Accepts: string to log */void mm_dlog (char *string){ /* Not doing anything here for now */}/* Get user name and password for this host * Accepts: parse of network mailbox name * where to return user name * where to return password * trial count */void mm_login (NETMBX *mb,char *username,char *password,long trial){ /* set user name */ strncpy (username,*mb->user ? mb->user : user,NETMAXUSER-1); strncpy (password,pass,255); /* and password */ username[NETMAXUSER] = password[255] = '\0';}/* About to enter critical code * Accepts: stream */void mm_critical (MAILSTREAM *stream){ critical = T;}/* About to exit critical code * Accepts: stream */void mm_nocritical (MAILSTREAM *stream){ critical = NIL;}/* Disk error found * Accepts: stream * system error code * flag indicating that mailbox may be clobbered * Returns: abort flag */long mm_diskerror (MAILSTREAM *stream,long errcode,long serious){ if (serious) { /* try your damnest if clobberage likely */ syslog (LOG_ALERT, "Retrying after disk error user=%.80s host=%.80s mbx=%.80s: %.80s", user,tcp_clienthost (), (stream && stream->mailbox) ? stream->mailbox : "???", strerror (errcode)); alarm (0); /* make damn sure timeout disabled */ sleep (60); /* give it some time to clear up */ return NIL; } syslog (LOG_ALERT,"Fatal disk error user=%.80s host=%.80s mbx=%.80s: %.80s", user,tcp_clienthost (), (stream && stream->mailbox) ? stream->mailbox : "???", strerror (errcode)); return T;}/* Log a fatal error event * Accepts: string to log */void mm_fatal (char *string){ mm_log (string,ERROR); /* shouldn't happen normally */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -