⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ipop3d.c

📁 Vovida 社区开源的 SIP 协议源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Program:	IPOP3D - IMAP to POP3 conversion server * * Author:	Mark Crispin *		Networks and Distributed Computing *		Computing & Communications *		University of Washington *		Administration Building, AG-44 *		Seattle, WA  98195 *		Internet: MRC@CAC.Washington.EDU * * Date:	1 November 1990 * Last Edited:	3 August 2000 * * Copyright 2000 by the University of Washington * *  Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appears in all copies and that both the * above copyright notice and this permission notice appear in supporting * documentation, and that the name of the University of Washington not be * used in advertising or publicity pertaining to distribution of the software * without specific, written prior permission.  This software is made * available "as is", and * THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, * WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN * NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL, * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT * (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */#define PBIN getchar#define PSIN(s,n) fgets (s,n,stdin)#define PBOUT(c) putchar (c)#define PSOUT(s) fputs (s,stdout)#define PFLUSH fflush (stdout)#define CRLF PSOUT ("\015\012")/* Parameter files */#include <stdio.h>#include <ctype.h>#include <errno.h>extern int errno;		/* just in case */#include <signal.h>#include <time.h>#include "c-client.h"/* Autologout timer */#define KODTIMEOUT 60*5#define LOGINTIMEOUT 60*3#define TIMEOUT 60*10/* Size of temporary buffers */#define TMPLEN 1024/* Server states */#define AUTHORIZATION 0#define TRANSACTION 1#define UPDATE 2#define LOGOUT 3/* Eudora food */#define STATUS "Status: %s%s\015\012"#define SLEN (sizeof (STATUS)-3)/* Global storage */char *version = "2000.68";	/* server version */short state = AUTHORIZATION;	/* server state */short critical = NIL;		/* non-zero if in critical code */MAILSTREAM *stream = NIL;	/* mailbox stream */long idletime = 0;		/* time we went idle */unsigned long nmsgs = 0;	/* current number of messages */unsigned long ndele = 0;	/* number of deletes */unsigned long last = 0;		/* highest message accessed */unsigned long il = 0;		/* initial last message */char challenge[128];		/* challenge */char *host = NIL;		/* remote host name */char *user = NIL;		/* user name */char *pass = NIL;		/* password */char *initial = NIL;		/* initial response */long *msg = NIL;		/* message translation vector */char *sayonara = "+OK Sayonara\015\012";/* Function prototypes */int main (int argc,char *argv[]);void clkint ();void kodint ();void hupint ();void trmint ();int login (char *t,int argc,char *argv[]);char *apop_login (char *chal,char *user,char *md5,int argc,char *argv[]);char *responder (void *challenge,unsigned long clen,unsigned long *rlen);int mbxopen (char *mailbox);long blat (char *text,long lines,unsigned long size);void rset ();/* Main program */int main (int argc,char *argv[]){  unsigned long i,j,k;  char *s,*t;  char tmp[TMPLEN];  time_t autologouttime;#include "linkage.c"				/* initialize server */  server_init (argv[0],"pop3","pop3s","pop",clkint,kodint,hupint,trmint);  challenge[0] = '\0';		/* find the CRAM-MD5 authenticator */  if (i = mail_lookup_auth_name ("CRAM-MD5",NIL)) {    AUTHENTICATOR *a = mail_lookup_auth (i);    if (a->server) {		/* have an MD5 enable file? */				/* build challenge -- less than 128 chars */      sprintf (challenge,"<%lx.%lx@%.64s>",(unsigned long) getpid (),	       (unsigned long) time (0),tcp_serverhost ());    }  }  /* There are reports of POP3 clients which get upset if anything appears   * between the "+OK" and the "POP3" in the greeting.   */  PSOUT ("+OK POP3");  if (!challenge[0]) {		/* if no MD5 enable, output host name */    PBOUT (' ');    PSOUT (tcp_serverhost ());  }  PSOUT (" v");  PSOUT (version);  PSOUT (" server ready");  if (challenge[0]) {		/* if MD5 enable, output challenge here */    PBOUT (' ');    PSOUT (challenge);  }  CRLF;  PFLUSH;			/* dump output buffer */  autologouttime = time (0) + LOGINTIMEOUT;				/* command processing loop */  while ((state != UPDATE) && (state != LOGOUT)) {    idletime = time (0);	/* get a command under timeout */    alarm ((state == TRANSACTION) ? TIMEOUT : LOGINTIMEOUT);    clearerr (stdin);		/* clear stdin errors */    while (!PSIN (tmp,TMPLEN)){	/* read command line */				/* 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 */	syslog (LOG_INFO,"%s while reading line user=%.80s host=%.80s",		e,user ? user : "???",tcp_clienthost ());	rset ();		/* try to gracefully close the stream */	if (state == TRANSACTION) mail_close (stream);	stream = NIL;	state = LOGOUT;	_exit (1);      }    }    alarm (0);			/* make sure timeout disabled */    idletime = 0;		/* no longer idle */    if (!strchr (tmp,'\012'))	/* find end of line */      PSOUT ("-ERR Command line too long\015\012");    else if (!(s = strtok (tmp," \015\012")))      PSOUT ("-ERR Null command\015\012");    else {			/* dispatch based on command */      ucase (s);		/* canonicalize case */				/* snarf argument */      t = strtok (NIL,"\015\012");				/* QUIT command always valid */      if (!strcmp (s,"QUIT")) state = UPDATE;      else if (!strcmp (s,"CAPA")) {	AUTHENTICATOR *auth = mail_lookup_auth (1);	PSOUT ("+OK Capability list follows:\015\012");	PSOUT ("TOP\015\012LOGIN-DELAY 180\015\012UIDL\015\012");#ifdef POP3SPECIALCAP	PSOUT (POP3SPECIALCAP);	CRLF;#endif#ifndef PLAINTEXT_DISABLED	PSOUT ("USER\015\012");#endif	PSOUT ("SASL");	while (auth) {#ifdef PLAINTEXT_DISABLED				/* disable insecure authenticators */	  if (!auth->secflag) auth->server = NIL;#endif	  if (auth->server) {	    PBOUT (' ');	    PSOUT (auth->name);	  }	  auth = auth->next;	}	CRLF;	PSOUT (".\015\012");      }      else switch (state) {	/* else dispatch based on state */      case AUTHORIZATION:	/* waiting to get logged in */	if (!strcmp (s,"USER")) {	  if (host) fs_give ((void **) &host);	  if (user) fs_give ((void **) &user);	  if (pass) fs_give ((void **) &pass);	  if (t && *t) {	/* if user name given */				/* skip leading whitespace (bogus clients!) */	    while (*t == ' ') ++t;				/* remote user name? */	    if (s = strchr (t,':')) {	      *s++ = '\0';	/* tie off host name */	      host = cpystr (t);/* copy host name */	      user = cpystr (s);/* copy user name */	    }				/* local user name */	    else user = cpystr (t);	    PSOUT ("+OK User name accepted, password please\015\012");	  }	  else PSOUT ("-ERR Missing username argument\015\012");	}	else if (user && *user && !strcmp (s,"PASS"))	  state = login (t,argc,argv);	else if (!strcmp (s,"AUTH")) {	  if (t && *t) {	/* mechanism given? */	    if (host) fs_give ((void **) &host);	    if (user) fs_give ((void **) &user);	    if (pass) fs_give ((void **) &pass);	    s = strtok (t," ");	/* get mechanism name */				/* get initial response */	    initial = strtok (NIL,"\015\012");	    if (!(user = cpystr (mail_auth (s,responder,argc,argv)))) {	      PSOUT ("-ERR Bad authentication\015\012");	      syslog (LOG_INFO,"AUTHENTICATE %s failure host=%.80s",s,		      tcp_clienthost ());	    }	    else if ((state = mbxopen ("INBOX")) == TRANSACTION)	      syslog (LOG_INFO,"Auth user=%.80s host=%.80s nmsgs=%ld/%ld",		      user,tcp_clienthost (),nmsgs,stream->nmsgs);	    else syslog (LOG_INFO,"Auth user=%.80s host=%.80s no mailbox",			 user,tcp_clienthost ());	  }	  else {	    AUTHENTICATOR *auth = mail_lookup_auth (1);	    PSOUT ("+OK Supported authentication mechanisms:\015\012");	    while (auth) {#ifdef PLAINTEXT_DISABLED				/* disable insecure authenticators */	      if (!auth_secflag) auth->server = NIL;#endif	      if (auth->server) {		PSOUT (auth->name);		CRLF;	      }	      auth = auth->next;	    }	    PBOUT ('.');	    CRLF;	  }	}	else if (!strcmp (s,"APOP")) {	  if (challenge[0]) {	/* can do it if have an MD5 challenge */	    if (host) fs_give ((void **) &host);	    if (user) fs_give ((void **) &user);	    if (pass) fs_give ((void **) &pass);				/* get user name */	    if (!(t && *t && (s = strtok (t," ")) && (t = strtok(NIL,"\012"))))	      PSOUT ("-ERR Missing APOP argument\015\012");	    else if (!(user = apop_login (challenge,s,t,argc,argv)))	      PSOUT ("-ERR Bad APOP\015\012");	    else if ((state = mbxopen ("INBOX")) == TRANSACTION)	      syslog (LOG_INFO,"APOP user=%.80s host=%.80s nmsgs=%ld/%ld",		      user,tcp_clienthost (),nmsgs,stream->nmsgs);	    else syslog (LOG_INFO,"APOP user=%.80s host=%.80s no mailbox",			 user,tcp_clienthost ());	  }	  else PSOUT ("-ERR Not supported\015\012");	}				/* (chuckle) */	else if (!strcmp (s,"RPOP"))	  PSOUT ("-ERR Nice try, bunkie\015\012");#ifdef IMAPSPECIALCAP	else if (!strcmp (s,POP3SPECIALCAP)) {	  char rsp[TMPLEN];	  if (t = SPECIALCAP (argv[0]))	    sprintf (rsp,"-ERR %s failed: %.100s\015\012",POP3SPECIALCAP,t);	  else sprintf (rsp,"+OK %s completed\015\012",POP3SPECIALCAP);	  PSOUT (rsp);	}#endif	else PSOUT ("-ERR Unknown AUTHORIZATION state command\015\012");	break;      case TRANSACTION:		/* logged in */	if (!strcmp (s,"STAT")) {	  for (i = 1,j = 0,k = 0; i <= nmsgs; i++)	    if (msg[i] > 0) {	/* message still exists? */	      j++;		/* count one more undeleted message */	      k += mail_elt (stream,msg[i])->rfc822_size + SLEN;	    }	  sprintf (tmp,"+OK %lu %lu\015\012",j,k);	  PSOUT (tmp);	}	else if (!strcmp (s,"LIST")) {	  if (t && *t) {	/* argument do single message */	    if ((i = strtoul (t,NIL,10)) && (i <= nmsgs) && (msg[i] > 0)) {	      sprintf (tmp,"+OK %lu %lu\015\012",i,		       mail_elt(stream,msg[i])->rfc822_size + SLEN);	      PSOUT (tmp);	    }	    else PSOUT ("-ERR No such message\015\012");	  }	  else {		/* entire mailbox */	    PSOUT ("+OK Mailbox scan listing follows\015\012");	    for (i = 1,j = 0,k = 0; i <= nmsgs; i++) if (msg[i] > 0) {	      sprintf (tmp,"%lu %lu\015\012",i,		       mail_elt (stream,msg[i])->rfc822_size + SLEN);	      PSOUT (tmp);	    }	    PBOUT ('.');	/* end of list */	    CRLF;	  }	}	else if (!strcmp (s,"UIDL")) {	  if (t && *t) {	/* argument do single message */	    if ((i = strtoul (t,NIL,10)) && (i <= nmsgs) && (msg[i] > 0)) {	      sprintf (tmp,"+OK %lu %08lx%08lx\015\012",i,stream->uid_validity,		       mail_uid (stream,msg[i]));	      PSOUT (tmp);	    }	    else PSOUT ("-ERR No such message\015\012");	  }	  else {		/* entire mailbox */	    PSOUT ("+OK Unique-ID listing follows\015\012");	    for (i = 1,j = 0,k = 0; i <= nmsgs; i++) if (msg[i] > 0) {	      sprintf (tmp,"%lu %08lx%08lx\015\012",i,stream->uid_validity,		       mail_uid (stream,msg[i]));	      PSOUT (tmp);	    }	    PBOUT ('.');	/* end of list */	    CRLF;	  }	}	else if (!strcmp (s,"RETR")) {	  if (t && *t) {	/* must have an argument */	    if ((i = strtoul (t,NIL,10)) && (i <= nmsgs) && (msg[i] > 0)) {	      MESSAGECACHE *elt;				/* update highest message accessed */	      if (i > last) last = i;	      sprintf (tmp,"+OK %lu octets\015\012",		       (elt = mail_elt (stream,msg[i]))->rfc822_size + SLEN);	      PSOUT (tmp);				/* output header */	      t = mail_fetch_header (stream,msg[i],NIL,NIL,&k,FT_PEEK);	      blat (t,-1,k);				/* output status */	      sprintf (tmp,STATUS,elt->seen ? "R" : " ",		       elt->recent ? " " : "O");	      PSOUT (tmp);	      CRLF;		/* delimit header and text */				/* output text */	      t = mail_fetch_text (stream,msg[i],NIL,&k,NIL);	      blat (t,-1,k);	      CRLF;		/* end of list */	      PBOUT ('.');	      CRLF;	    }	    else PSOUT ("-ERR No such message\015\012");	  }	  else PSOUT ("-ERR Missing message number argument\015\012");	}	else if (!strcmp (s,"DELE")) {	  if (t && *t) {	/* must have an argument */	    if ((i = strtoul (t,NIL,10)) && (i <= nmsgs) && (msg[i] > 0)) {				/* update highest message accessed */	      if (i > last) last = i;				/* delete message */	      sprintf (tmp,"%ld",msg[i]);	      mail_setflag (stream,tmp,"\\Deleted");	      msg[i] = -msg[i];	/* note that we deleted this message */	      PSOUT ("+OK Message deleted\015\012");	      ndele++;		/* one more message deleted */	    }	    else PSOUT ("-ERR No such message\015\012");	  }	  else PSOUT ("-ERR Missing message number argument\015\012");	}	else if (!strcmp (s,"NOOP"))	  PSOUT ("+OK No-op to you too!\015\012");	else if (!strcmp (s,"LAST")) {	  sprintf (tmp,"+OK %lu\015\012",last);	  PSOUT (tmp);	}	else if (!strcmp (s,"RSET")) {	  rset ();		/* reset the mailbox */	  PSOUT ("+OK Reset state\015\012");	}	else if (!strcmp (s,"TOP")) {	  if (t && *t && (i =strtoul (t,&s,10)) && (i <= nmsgs) &&	      (msg[i] > 0)) {				/* skip whitespace */	    while (isspace (*s)) s++;	    if (isdigit (*s)) {	/* make sure line count argument good */	      MESSAGECACHE *elt = mail_elt (stream,msg[i]);	      j = strtoul (s,NIL,10);				/* update highest message accessed */	      if (i > last) last = i;	      PSOUT ("+OK Top of message follows\015\012");				/* output header */	      t = mail_fetch_header (stream,msg[i],NIL,NIL,&k,FT_PEEK);	      blat (t,-1,k);				/* output status */	      sprintf (tmp,STATUS,elt->seen ? "R" : " ",		       elt->recent ? " " : "O");	      PSOUT (tmp);	      CRLF;		/* delimit header and text */	      if (j) {		/* want any text lines? */				/* output text */		t = mail_fetch_text (stream,msg[i],NIL,&k,FT_PEEK);				/* tie off final line if full text output */		if (j -= blat (t,j,k)) CRLF;	      }	      PBOUT ('.');	/* end of list */	      CRLF;	    }	    else PSOUT ("-ERR Bad line count argument\015\012");	  }	  else PSOUT ("-ERR Bad message number argument\015\012");	}	else if (!strcmp (s,"XTND"))	  PSOUT ("-ERR Sorry I can't do that\015\012");	else PSOUT ("-ERR Unknown TRANSACTION state command\015\012");	break;      default:        PSOUT ("-ERR Server in unknown state\015\012");	break;      }    }    PFLUSH;			/* make sure output finished */    if (autologouttime) {	/* have an autologout in effect? */				/* cancel if no longer waiting for login */      if (state != AUTHORIZATION) autologouttime = 0;				/* took too long to login */      else if (autologouttime < time (0)) {	PSOUT ("-ERR Autologout\015\012");	syslog (LOG_INFO,"Autologout host=%.80s",tcp_clienthost ());	PFLUSH;			/* make sure output blatted */	state = LOGOUT;		/* sayonara */      }    }  }  if (stream && (state == UPDATE)) {    mail_expunge (stream);    syslog (LOG_INFO,"Logout user=%.80s host=%.80s nmsgs=%ld ndele=%ld",	    user,tcp_clienthost (),stream->nmsgs,ndele);    mail_close (stream);  }  else syslog (LOG_INFO,"Logout user=%.80s host=%.80s",user ? user : "???",	       tcp_clienthost ());  PSOUT (sayonara);		/* "now it's time to say sayonara..." */  PFLUSH;			/* make sure output finished */  return 0;			/* all done */}/* Clock interrupt */void clkint (){  PSOUT ("-ERR Autologout; idle for too long\015\012");  syslog (LOG_INFO,"Autologout user=%.80s host=%.80s",user ? user : "???",	  tcp_clienthost ());  PFLUSH;			/* make sure output blatted */  if (critical) state = LOGOUT;	/* badly hosed if in critical code */  else {			/* try to gracefully close the stream */    if ((state == TRANSACTION) && !stream->lock) {      rset ();      mail_close (stream);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -