diff options
| author | Sam Varshavchik | 2018-07-21 10:43:40 -0400 | 
|---|---|---|
| committer | Sam Varshavchik | 2018-07-21 10:44:43 -0400 | 
| commit | 14179a773e02455620b8db480e5cde990301bdb1 (patch) | |
| tree | 26f00c12281c8488e37fbfe07f4324f2e641f1eb | |
| parent | f7786ceaa39b846007a38495c169fbaa23a3f7d0 (diff) | |
| download | courier-libs-14179a773e02455620b8db480e5cde990301bdb1.tar.bz2 | |
courier-imap: implement UTF8 mode in the POP3 server.
| -rw-r--r-- | imap/ChangeLog | 5 | ||||
| -rw-r--r-- | imap/Makefile.am | 6 | ||||
| -rw-r--r-- | imap/fetch.c | 4 | ||||
| -rw-r--r-- | imap/pop3dcapa.c | 9 | ||||
| -rw-r--r-- | imap/pop3dserver.c | 138 | ||||
| -rw-r--r-- | imap/pop3login.c | 13 | 
6 files changed, 99 insertions, 76 deletions
| diff --git a/imap/ChangeLog b/imap/ChangeLog index ba51db1..4c10f8e 100644 --- a/imap/ChangeLog +++ b/imap/ChangeLog @@ -1,3 +1,8 @@ +2018-07-21  Sam Varshavchik  <mrsam@courier-mta.com> + +	* pop3dserver.c: update Courier-IMAP to support UTF8 POP3. Update +	version of the courierpop3dsizelist cache file. +  2018-07-17  Sam Varshavchik  <mrsam@courier-mta.com>  	* courier-imap, sqwebmail: update Courier-IMAP to support UTF8 IMAP. diff --git a/imap/Makefile.am b/imap/Makefile.am index 7a7f4f5..7d8f5ff 100644 --- a/imap/Makefile.am +++ b/imap/Makefile.am @@ -85,14 +85,16 @@ pop3login_DEPENDENCIES=../tcpd/libspipe.la ../tcpd/libspipe.la libpop3d.la  pop3login_LDADD=../tcpd/libtlsclient.la ../tcpd/libspipe.la libpop3d.la ../tcpd/libspipe.la @LDAUTH@ -lcourierauth -lcourierauthsasl @NETLIBS@  libpop3d_la_SOURCES=externalauth.c -libpop3d_la_LIBADD=../maildir/libmaildir.la ../rfc822/librfc822.la \ +libpop3d_la_LIBADD=../maildir/libmaildir.la \ +	../rfc2045/librfc2045.la \ +	../rfc822/librfc822.la \  	../numlib/libnumlib.la  libpop3d_la_DEPENDENCIES=$(libpop3d_la_LIBADD)  libpop3d_la_LDFLAGS=-static  pop3d_SOURCES=pop3dserver.c pop3dcapa.c  pop3d_DEPENDENCIES=libpop3d.la -pop3d_LDADD=libpop3d.la @LDAUTH@ -lcourierauth +pop3d_LDADD=libpop3d.la @LDAUTH@ -lcourierauth -lcourier-unicode  HTML2TXT=links -dump -no-numbering diff --git a/imap/fetch.c b/imap/fetch.c index 1eb52dd..fd25265 100644 --- a/imap/fetch.c +++ b/imap/fetch.c @@ -287,8 +287,8 @@ int do_fetch(unsigned long n, int byuid, void *p)  			open_err=1;  			cannot_open_because=  				" because it is a Unicode message and your" -				" mail client did not enable Unicode support." -				" Please use a mail client that supports" +				" E-mail reader did not enable Unicode support." +				" Please use an E-mail reader that supports"  				" IMAP with UTF-8 (see"  				" https://tools.ietf.org/html/rfc6855.html)";  		} diff --git a/imap/pop3dcapa.c b/imap/pop3dcapa.c index 5d0eef4..ca9e12e 100644 --- a/imap/pop3dcapa.c +++ b/imap/pop3dcapa.c @@ -1,5 +1,5 @@  /* -** Copyright 1998 - 2008 Double Precision, Inc. +** Copyright 1998 - 2018 Double Precision, Inc.  ** See COPYING for distribution information.  */ @@ -78,10 +78,13 @@ void pop3dcapa()  		printf("SASL %s%s%s\r\n", p, *p && *external ? " ":"",  		       *external ? "EXTERNAL":"");  	} -		 +  	if (have_starttls())  		printf("STLS\r\n"); -	printf("TOP\r\nUSER\r\nLOGIN-DELAY 10\r\nPIPELINING\r\nUIDL\r\nIMPLEMENTATION Courier Mail Server\r\n.\r\n"); +	printf("TOP\r\nUSER\r\nLOGIN-DELAY 10\r\n" +	       "PIPELINING\r\nUIDL\r\n" +	       "UTF8 USER\r\n" +	       "IMPLEMENTATION Courier Mail Server\r\n.\r\n");  	fflush(stdout);  } diff --git a/imap/pop3dserver.c b/imap/pop3dserver.c index 13aced9..beca04a 100644 --- a/imap/pop3dserver.c +++ b/imap/pop3dserver.c @@ -1,5 +1,5 @@  /* -** Copyright 1998 - 2011 Double Precision, Inc. +** Copyright 1998 - 2018 Double Precision, Inc.  ** See COPYING for distribution information.  **  */ @@ -54,12 +54,20 @@  #include	"maildir/maildirgetquota.h"  #include	"maildir/maildircreate.h"  #include	"maildir/loginexec.h" +#include	"rfc2045/rfc2045.h"  #include	"courierauth.h"  #define POP3DLIST "courierpop3dsizelist" +#define LISTVERSION 3  extern void pop3dcapa();  static void acctout(const char *disc); +void rfc2045_error(const char *p) +{ +	if (write(2, p, strlen(p)) < 0) +		_exit(1); +	_exit(0); +}  static const char *authaddr, *remoteip, *remoteport; @@ -68,13 +76,14 @@ struct msglist {  	char *filename;  	int isdeleted;  	int isnew; +	int isutf8;  	off_t size;  	struct {  		unsigned long uidv;  		unsigned long n;  	} uid; -	} ; +} ;  static struct msglist *msglist_l;  static struct msglist **msglist_a; @@ -82,6 +91,7 @@ static unsigned msglist_cnt;  static struct stat enomem_stat;  static int enomem_1msg; +int utf8_enabled;  /*  ** When a disk error occurs while saving an updated courierpop3dsizelist @@ -109,7 +119,6 @@ static unsigned long bytes_sent_count=0;  static unsigned long bytes_received_count=0;  static unsigned long uidv=0; -static int convert_v0=0;  static time_t start_time; @@ -120,29 +129,18 @@ static time_t start_time;  static void calcsize(struct msglist *m)  { -FILE	*f=fopen(m->filename, "r"); -int	c, lastc; +	FILE	*f=fopen(m->filename, "r"); +	struct rfc2045 *p=rfc2045_fromfp(f); -	m->size=0; -	if (f == 0) -	{ -		perror("calcsize fopen"); -		return; -	} -	lastc='\n'; -	while ((c=getc(f)) >= 0) -	{ -		if (c == '\n')	++m->size; -		++m->size; -		lastc=c; -	} -	if (lastc != '\n')	m->size += 2; +	m->size=p->nlines + p->endpos; -	if (ferror(f)) -	{ -		perror("calcsize ferror"); -		return; -	} +	clearerr(f); +	if (m->size > 0 && fseek(f, -1, SEEK_SET) == 0 && getc(f) != '\n') +		m->size+=2; /* We'll add an extra CRLF ourselves */ + +	if (p->rfcviolation & RFC2045_ERR8BITHEADER) +		m->isutf8=1; +	rfc2045_free(p);  	fclose(f);  } @@ -189,27 +187,15 @@ static struct msglist **readpop3dlist(unsigned long *uid)  	uidv=time(NULL); -	convert_v0=0; -  	if (fp == NULL ||  	    fgets(linebuf, sizeof(linebuf)-1, fp) == NULL ||  	    linebuf[0] != '/' || sscanf(linebuf+1, "%d %lu %lu", &vernum,  					uid, &uidv) -	    < 2 || (vernum != 1 && vernum != 2)) +	    < 2 || vernum != LISTVERSION)  	{ -		if (fp == NULL) -			convert_v0=1; - -		if (vernum == 0 && fp && fseek(fp, 0L, SEEK_SET) >= 0) -		{ -			/* Old version 0 format courierpop3dsizelist file */ -		} -		else -		{ -			if (fp) -				fclose(fp); -			fp=NULL; -		} +		if (fp) +			fclose(fp); +		fp=NULL;  	}  	if (fp) @@ -223,8 +209,6 @@ static struct msglist **readpop3dlist(unsigned long *uid)  		while ((ch=getc(fp)) != EOF)  		{ -			unsigned long sz; -  			if (ch != '\n')  			{  				if (n < sizeof(linebuf)-3) @@ -234,10 +218,6 @@ static struct msglist **readpop3dlist(unsigned long *uid)  			linebuf[n]=0;  			n=0; -			if (vernum == 0) -				strcat(linebuf, " 0"); -			/* Convert version 0 to version 1 format - PRESTO! */ -  			if ((p=strrchr(linebuf, ' ')) == NULL)  				continue;  			*p=0; @@ -263,18 +243,16 @@ static struct msglist **readpop3dlist(unsigned long *uid)  				exit(1);  			} -			switch (sscanf(p, "%lu %lu:%lu", &sz, -				       &m->uid.n, &m->uid.uidv)) { -			case 2: -				m->uid.uidv=0; -				/* FALLTHROUGH */ -			case 3: -				m->size=sz; +			if (sscanf(p, "%lu %lu:%lu:%d", &m->size, +				   &m->uid.n, &m->uid.uidv, +				   &m->isutf8) == 4) +			{  				m->next=list;  				list=m;  				++mcnt; -				break; -			default: +			} +			else +			{  				free(m->filename);  				free(m);  			} @@ -316,7 +294,7 @@ static int savepop3dlist(struct msglist **a, size_t cnt,  		return -1;  	} -	fprintf(fp, "/2 %lu %lu\n", uid, uidv); +	fprintf(fp, "/%d %lu %lu\n", LISTVERSION, uid, uidv);  	for (i=0; i<cnt; i++)  	{ @@ -326,8 +304,8 @@ static int savepop3dlist(struct msglist **a, size_t cnt,  		if ((q=strrchr(p, '/')) != NULL)  			p=q+1; -		fprintf(fp, "%s %lu %lu:%lu\n", p, (unsigned long)a[i]->size, -			a[i]->uid.n, a[i]->uid.uidv); +		fprintf(fp, "%s %lu %lu:%lu:%d\n", p, (unsigned long)a[i]->size, +			a[i]->uid.n, a[i]->uid.uidv, a[i]->isutf8);  	}  	if (fflush(fp) || ferror(fp)) @@ -411,7 +389,7 @@ static int cmpmsgs(const void *a, const void *b)  		++bp;  	else  		bp=bname; -  +  	na=atol(ap);  	nb=atol(bp); @@ -480,6 +458,7 @@ static void sortmsgs()  		{  			msglist_a[i]->size=prev_list[n]->size;  			msglist_a[i]->uid=prev_list[n]->uid; +			msglist_a[i]->isutf8=prev_list[n]->isutf8;  			n++;  		}  		else @@ -487,12 +466,10 @@ static void sortmsgs()  			msglist_a[i]->uid.n=nextuid++;  			msglist_a[i]->uid.uidv=uidv;  			msglist_a[i]->isnew=1; -			if (convert_v0) -				msglist_a[i]->uid.n=0;  			calcsize(msglist_a[i]);  			savesizes=1; -		}       +		}  	}  	if (prev_list[n]) @@ -662,12 +639,27 @@ char	buf[NUMBUFSIZE];  static void do_retr(unsigned i, unsigned *lptr)  { -FILE	*f=fopen(msglist_a[i]->filename, "r"); -char	*p; -int	c, lastc='\n'; -int	inheader=1; -char	buf[NUMBUFSIZE]; -unsigned long *cntr; +	FILE	*f; +	char	*p; +	int	c, lastc='\n'; +	int	inheader=1; +	char	buf[NUMBUFSIZE]; +	unsigned long *cntr; + +	if (msglist_a[i]->isutf8 && !utf8_enabled) +	{ +		printed(printf("-ERR Cannot open message %u because it is" +			       " a Unicode message and your E-mail reader" +			       " did not enable Unicode support. Please" +			       " use an E-mail reader that supports POP3" +			       " with UTF-8 (see" +			       " https://tools.ietf.org/html/rfc6856.html)\r\n", +			       i+1)); +		fflush(stdout); +		return; +	} + +	f=fopen(msglist_a[i]->filename, "r");  	if (!f)  	{ @@ -1045,6 +1037,14 @@ char	*p;  			authaddr="nobody";  	} +	utf8_enabled=1; /* Until proven otherwise */ + +	{ +		const char *utf8=getenv("UTF8"); + +		if (utf8) +			utf8_enabled=atoi(utf8); +	}  	if ((remoteip=getenv("TCPREMOTEIP")) == NULL)  		remoteip="127.0.0.1"; @@ -1078,7 +1078,7 @@ char	*p;  		fflush(stdout);  		exit(1);  	} -	 +  	maildir_loginexec();  	if (auth_getoptionenvint("disablepop3")) diff --git a/imap/pop3login.c b/imap/pop3login.c index d541254..be96d0e 100644 --- a/imap/pop3login.c +++ b/imap/pop3login.c @@ -37,6 +37,7 @@ extern const char *pop3_externalauth();  static const char *pop3d;  static const char *defaultmaildir; +int utf8_enabled=0;  static const char *safe_getenv(const char *p)  { @@ -223,6 +224,10 @@ static int login_callback(struct authinfo *ainfo, void *dummy)  				       ainfo->address);  				putenv(p); +				if (utf8_enabled) +					putenv("UTF8=1"); +				else +					putenv("UTF8=0");  				alarm(0);  				execl(pop3d, pop3d,  				      ainfo->maildir ? @@ -306,6 +311,14 @@ char *q ;  				break;  			} +			if ( strcmp(p, "UTF8") == 0) +			{ +				printf("+OK UTF8 enabled\r\n"); +				fflush(stdout); +				utf8_enabled=1; +				continue; +			} +  			if ( strcmp(p, "USER") == 0)  			{  				if (tls_required()) | 
