diff options
Diffstat (limited to 'imap')
| -rw-r--r-- | imap/.gitignore | 2 | ||||
| -rw-r--r-- | imap/ChangeLog | 123 | ||||
| -rw-r--r-- | imap/Makefile.am | 2 | ||||
| -rw-r--r-- | imap/authenticate_auth.c | 3 | ||||
| -rw-r--r-- | imap/configure.ac | 6 | ||||
| -rw-r--r-- | imap/courierpop3d.sgml | 6 | ||||
| -rw-r--r-- | imap/fetch.c | 34 | ||||
| -rw-r--r-- | imap/imapd-ssl.dist.in.git | 69 | ||||
| -rw-r--r-- | imap/imapd.c | 33 | ||||
| -rw-r--r-- | imap/imapd.cnf.gnutls.in (renamed from imap/imapd.cnf.gnutls) | 0 | ||||
| -rw-r--r-- | imap/imapd.sgml | 12 | ||||
| -rw-r--r-- | imap/imaplogin.c | 28 | ||||
| -rw-r--r-- | imap/imapscanclient.c | 2 | ||||
| -rw-r--r-- | imap/imapscanclient.h | 3 | ||||
| -rw-r--r-- | imap/imaptoken.c | 9 | ||||
| -rw-r--r-- | imap/mainloop.c | 12 | ||||
| -rw-r--r-- | imap/makeimapaccess.sgml | 8 | ||||
| -rw-r--r-- | imap/mkdhparams.sgml | 10 | ||||
| -rw-r--r-- | imap/mkimapdcert.sgml | 8 | ||||
| -rw-r--r-- | imap/mkpop3dcert.sgml | 8 | ||||
| -rw-r--r-- | imap/pop3d-ssl.dist.in.git | 67 | ||||
| -rw-r--r-- | imap/pop3d.cnf.gnutls.in (renamed from imap/pop3d.cnf.gnutls) | 0 | ||||
| -rw-r--r-- | imap/pop3d.dist.in.git | 9 | ||||
| -rw-r--r-- | imap/pop3dserver.c | 126 | ||||
| -rw-r--r-- | imap/pop3login.c | 47 | 
25 files changed, 472 insertions, 155 deletions
| diff --git a/imap/.gitignore b/imap/.gitignore index b97dbfc..0eeab13 100644 --- a/imap/.gitignore +++ b/imap/.gitignore @@ -12,6 +12,7 @@  /imapd.8  /imapd.8.in  /imapd.cnf +/imapd.cnf.gnutls  /imapd.cnf.openssl  /imapd.dist  /imapd.dist.in @@ -43,6 +44,7 @@  /pop3d-ssl.dist.in  /pop3d.cnf  /pop3d.cnf.openssl +/pop3d.cnf.gnutls  /pop3d.dist  /pop3d.dist.in  /pop3d.pam diff --git a/imap/ChangeLog b/imap/ChangeLog index 2eeece4..d011c22 100644 --- a/imap/ChangeLog +++ b/imap/ChangeLog @@ -1,3 +1,126 @@ +2020-11-04  Sam Varshavchik  <mrsam@courier-mta.com> + +	* spec file: add BuildRequires: %{__make} (will be required in F34). + +2020-10-27  Sam Varshavchik  <mrsam@courier-mta.com> + +	* waitlib: fix testwait.c failure with LTO enabled on F33. + +	* pop3login.c: fflush before STARTLS. + +5.0.11 + +2020-05-18  Sam Varshavchik  <mrsam@courier-mta.com> + +	* courier-authlib API update. + +2020-04-21  Sam Varshavchik  <mrsam@courier-mta.com> + +	* Add AC_PROG_CC_C99 to configure +5.0.10 + +2020-02-25  FlorianMickler <florian@mickler.org> + +	* tcpd/starttls.c (dossl): Start client after negotiating SSL, +	in order to allow EXTERNAL client certificate authentication. + +2019-12-05  Sam Varshavchik  <mrsam@courier-mta.com> + +	* Fix virtual IP and hostname handling when using GnuTLS for SSL. + +2019-09-05  Sam Varshavchik  <mrsam@courier-mta.com> + +	* imap, pop3: include remote port TCP port number together with the +	IP address, in log messages. + +5.0.8 + +2019-08-28  Sam Varshavchik  <mrsam@courier-mta.com> + +	* Update documentation in the imapd and pop3d ssl config flies. + +	* Fix the RPM spec file for CentOS 7 + +5.0.7 + +2019-02-24  Sam Varshavchik  <mrsam@courier-mta.com> + +	* pop3dserver.c (do_retr): Use the new MIME_UNICODE_MESSAGE_TYPE +	setting to set the type of the wrapped MIME attachment. + +5.0.6 + +2019-01-30  Sam Varshavchik  <mrsam@courier-mta.com> + +	* pop3dserver.c: Fix parsing of pop3d file cache, on some +	architectures. + +2019-01-08  Sam Varshavchik  <mrsam@courier-mta.com> + +	* tcpd/libcouriertls.c: Ignore unreadable cert files. + +5.0.5 + +2018-12-09  Sam Varshavchik  <mrsam@courier-mta.com> + +	* fetch.c: Send an alert about a Unicode messages to a non-Unicode +	client at most once per IMAP session. + +5.0.4 + +2018-11-28  Hideki SAKAMOTO <hsakamt@tsnr.com> + +	* pop3dserver.c: Deal with MS Outlook's broken implementation of +	RFC 6856. + +5.0.3 + +2018-11-17  Sam Varshavchik  <mrsam@courier-mta.com> + +	* pop3dserver.c (calcsize): Fix spurious flagging of non-UTF8 +	messages as UTF-8. + +	To fix existing mailboxes with erroneously-flagged messages. In +	each mailbox, if its existing courierpop3dsizelist file starts with + +	/3 [followed by additional data] + +	Only if the first line in courierpop3dsizelist starts with /3, then +	execute: + +	perl -p -i -e 's/:\d+$/:0/' courierpop3dsizelist + +2018-11-16  Sam Varshavchik  <mrsam@courier-mta.com> + +	* pop3dserver.c (readpop3dlist): Be able to update +	courierpop3dsizelist from version 2 to 3 in place. +	(do_retr): Instead of returning an ERR to a non-Unicode client, +	handle Unicode messages by wrapping them as an attachment. + +5.0.2 + +2018-10-27  Sam Varshavchik  <mrsam@courier-mta.com> + +	* configure.ac: Additional changes to how Unicode messages are +	handled with non-Unicode clients: disclaim all warranties, still +	report an error, but provide the raw message content, as is. + +5.0.1 + +2018-09-26  Sam Varshavchik  <mrsam@courier-mta.com> + +	* Provide an substitute message to IMAP clients that did not enable +	UTF-8. + +2018-09-24  Sam Varshavchik  <mrsam@courier-mta.com> + +	* couriertls: additional fixes. + +2018-09-24  Yoshinari Takaoka <mumumu@mumumu.org> + +	* couriertls: option to use a separate file for the SSL certificate's +	private key, as an alternative to the combined keyfile+certificate. +  5.0.0  2018-07-21  Sam Varshavchik  <mrsam@courier-mta.com> diff --git a/imap/Makefile.am b/imap/Makefile.am index 7d8f5ff..dda6235 100644 --- a/imap/Makefile.am +++ b/imap/Makefile.am @@ -196,7 +196,7 @@ courierpop3d.8.in: courierpop3d.sgml ../docbook/sgml2man  README.proxy.html: README.proxy.sgml  	rm -rf html.tmp  	xsltproc -o html.tmp/ --nonet http://docbook.sourceforge.net/release/xsl/current/xhtml/onechunk.xsl README.proxy.sgml -	xsltproc ../docbook/fixhtml.xsl html.tmp/* >README.proxy.html.tmp +	xsltproc --nonet ../docbook/fixhtml.xsl html.tmp/* >README.proxy.html.tmp  	mv -f README.proxy.html.tmp README.proxy.html  	rm -rf html.tmp diff --git a/imap/authenticate_auth.c b/imap/authenticate_auth.c index 04b03ac..60334e9 100644 --- a/imap/authenticate_auth.c +++ b/imap/authenticate_auth.c @@ -136,7 +136,8 @@ int	rc;  	if (!p || !*p)  		p="imap"; -	rc=auth_generic(p, authtype, authdata, login_callback, (void *)tag); +	rc=auth_generic_meta(NULL, p, authtype, authdata, +			     login_callback, (void *)tag);  	free(authtype);  	free(authdata);  	return (rc); diff --git a/imap/configure.ac b/imap/configure.ac index 49f909a..e538983 100644 --- a/imap/configure.ac +++ b/imap/configure.ac @@ -1,10 +1,10 @@  dnl Process this file with autoconf to produce a configure script.  dnl  dnl -dnl Copyright 1998 - 2016 Double Precision, Inc.  See COPYING for +dnl Copyright 1998 - 2019 Double Precision, Inc.  See COPYING for  dnl distribution information. -AC_INIT(courier-imap, 5.0.0, [courier-users@lists.sourceforge.net]) +AC_INIT(courier-imap, 5.0.11, [courier-users@lists.sourceforge.net])  >confdefs.h  # Kill PACKAGE_ macros @@ -18,6 +18,7 @@ AC_CONFIG_HEADERS(config.h)  dnl Checks for programs.  AC_USE_SYSTEM_EXTENSIONS  AC_PROG_CC +AC_PROG_CC_C99  AC_PROG_AWK  AC_PROG_INSTALL  AC_PROG_LN_S @@ -381,4 +382,5 @@ AC_SUBST(cacerts)  AC_OUTPUT(Makefile imapd.dist imapd-ssl.dist pop3d.dist pop3d-ssl.dist  	testsuitefix.pl mkimapdcert mkpop3dcert mkdhparams +	imapd.cnf.gnutls pop3d.cnf.gnutls  	imapd.cnf.openssl pop3d.cnf.openssl) diff --git a/imap/courierpop3d.sgml b/imap/courierpop3d.sgml index a25319c..92108e4 100644 --- a/imap/courierpop3d.sgml +++ b/imap/courierpop3d.sgml @@ -1,7 +1,7 @@  <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">  <!-- Copyright 1998 - 2009 Double Precision, Inc.  See COPYING for -->  <!-- distribution information. --> -<refentry> +<refentry id="courierpop3d">    <info><author><firstname>Sam</firstname><surname>Varshavchik</surname><contrib>Author</contrib></author><productname>Courier Mail Server</productname></info>    <refmeta> @@ -29,7 +29,7 @@      </cmdsynopsis>    </refsynopsisdiv> -  <refsect1> +  <refsect1 id="courierpop3d_description">      <title>DESCRIPTION</title>      <para> @@ -99,7 +99,7 @@ Usually, the default maildir is  "<literal moreinfo="none">./Maildir</literal>".</para>    </refsect1> -  <refsect1> +  <refsect1 id="courierpop3d_see_also">      <title>SEE ALSO</title>      <para> diff --git a/imap/fetch.c b/imap/fetch.c index fd25265..5daf150 100644 --- a/imap/fetch.c +++ b/imap/fetch.c @@ -1,5 +1,5 @@  /* -** Copyright 1998 - 2010 Double Precision, Inc. +** Copyright 1998 - 2018 Double Precision, Inc.  ** See COPYING for distribution information.  */ @@ -249,7 +249,7 @@ int do_fetch(unsigned long n, int byuid, void *p)  	struct	rfc2045 *rfc2045p;  	int	seen;  	int	open_err; -	const char *cannot_open_because=""; +	int	unicode_err=0;  	fp=NULL;  	open_err=0; @@ -284,13 +284,8 @@ int do_fetch(unsigned long n, int byuid, void *p)  			seen=1;  		if (rc < 0)  		{ -			open_err=1; -			cannot_open_because= -				" because it is a Unicode message and your" -				" 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)"; +			rc=0; +			unicode_err=1;  		}  		if ((fi=fi->next) != 0)	writes(" ");  	} @@ -300,11 +295,25 @@ int do_fetch(unsigned long n, int byuid, void *p)  	{  		writes("* NO [ALERT] Cannot open message ");  		writen(n); -		writes(cannot_open_because);  		writes("\r\n");  		return (0);  	} +	if (current_maildir_info.msgs[n-1].err8bitflag) +		unicode_err=0; + +	if (unicode_err) +	{ +		current_maildir_info.msgs[n-1].err8bitflag=1; + +		writes("* OK [ALERT] Message "); +		writen(n); +		writes(" appears to be a Unicode message and your" +		       " 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)\r\n"); +	}  #if SMAP  	if (!smapflag) @@ -450,7 +459,10 @@ static int fetchitem(FILE **fp, int *open_err, struct fetchinfo *fi,  	if (mimecorrectness && !enabled_utf8 &&  	    ((*mimep)->rfcviolation & RFC2045_ERR8BITHEADER)) -		return -1; +	{ +		/* Still return -1, in order to [ALERT] the client */ +		rc= -1; +	}  	(*fetchfunc)(*fp, fi, i, msgnum, *mimep);  	return (rc); diff --git a/imap/imapd-ssl.dist.in.git b/imap/imapd-ssl.dist.in.git index 50f1879..8ed9e36 100644 --- a/imap/imapd-ssl.dist.in.git +++ b/imap/imapd-ssl.dist.in.git @@ -5,7 +5,7 @@  # Do not alter lines that begin with ##, they are used when upgrading  # this configuration.  # -#  Copyright 2000 - 2016 Double Precision, Inc.  See COPYING for +#  Copyright 2000 - 2019 Double Precision, Inc.  See COPYING for  #  distribution information.  #  #  This configuration file sets various options for the Courier-IMAP server @@ -106,9 +106,9 @@ COURIERTLS=@bindir@/couriertls  ##NAME: TLS_PRIORITY:0  # -# GnuTLS setting only +# GnuTLS setting only (use TLS_CIPHER_LIST for OpenSSL)  # -# Set TLS protocol priority settings (GnuTLS only) +# Set TLS protocol priority settings  #  # DEFAULT: NORMAL:-CTYPE-OPENPGP  # @@ -144,33 +144,15 @@ COURIERTLS=@bindir@/couriertls  ##NAME: TLS_CIPHER_LIST:0  # +# OpenSSL only (use TLS_PRIORITY for GnuTLS): +#  # TLS_CIPHER_LIST optionally sets the list of ciphers to be used by the  # OpenSSL library.  In most situations you can leave TLS_CIPHER_LIST  # undefined  # -# OpenSSL: -#  # TLS_CIPHER_LIST="TLSv1:HIGH:!LOW:!MEDIUM:!EXP:!NULL:!aNULL@STRENGTH"  # -# GnuTLS: -# -# TLS_CIPHER_LIST="HIGH:MEDIUM" -# -# The actual list of available ciphers depend on the options GnuTLS was -# compiled against. The possible ciphers are: -# -# AES256, 3DES, AES128, ARC128, ARC40, RC2, DES, NULL -# -# Also, the following aliases: -# -# HIGH -- all ciphers that use more than a 128 bit key size -# MEDIUM -- all ciphers that use a 128 bit key size -# LOW -- all ciphers that use fewer than a 128 bit key size, the NULL cipher -#        is not included -# ALL -- all ciphers except the NULL cipher -# -# See GnuTLS documentation, gnutls_priority_init(3) for additional -# documentation. +# See the OpenSSL ciphers(1) manual page for the format of this setting.  ##NAME: TLS_STARTTLS_PROTOCOL:0  # @@ -229,6 +211,45 @@ TLS_STARTTLS_PROTOCOL="$TLS_PROTOCOL"  TLS_CERTFILE=@certsdir@/imapd.pem +##NAME: TLS_PRIVATE_KEYFILE:0 +# +# TLS_PRIVATE_KEYFILE - SSL/TLS private key for decrypting peer data. +# This file must be owned by the "@mailuser@" user, and must not be world +# readable, and must be accessible without a pass-phrase, i.e. it must not +# be encrypted. +# +# By default, courier generates SSL/TLS certifice including private key +# and install it in TLS_CERTFILE path, so TLS_PRIVATE_KEYFILE is completely +# optional. If TLS_PRIVATE_KEYFILE is not set (default), TLS_CERTFILE is +# treated as certificate including private key file. +# +# If you get SSL/TLS certificate and private key from trusted certificate +# authority(CA) and want to install them separately, TLS_PRIVATE_KEYFILE can +# be used as private key file path setting. +# +# VIRTUAL HOSTS ON THE SAME IP ADDRESS. +# +# $TLS_PRIVATE_KEYFILE.domain and $TLS_CERTFILE.domain are a pair. +# If you use VIRTUAL HOST feature on TLS_CERTFILE setting, you must set pair +# private key as $TLS_PRIVATE_KEYFILE.domain. Then, create a link from +# $TLS_PRIVATE_KEYFILE to whichever private key you consider to be the main one. +# for example: +# /etc/tls_private_keyfile.pem => /etc/tls_private_keyfile.pem.www.example.com +# +# IP-BASED VIRTUAL HOSTS: +# +# Just described on "VIRTUAL HOSTS ON THE SAME IP ADDRESS" above, +# $TLS_PRIVATE_KEYFILE.aaa.bbb.ccc.ddd and $TLS_CERTFILE.aaa.bbb.ccc.ddd are +# a pair. If TLS_PRIVATE_KEYFILE is set to /etc/tls_private_keyfile.pem, +# then you'll need to install the actual certificate files as +# /etc/tls_private_keyfile.pem.192.168.0.2, /etc/tls_private_keyfile.192.168.0.3 +# and so on, for each IP address. +# +# In all cases, $TLS_PRIVATE_KEYFILE needs to be linked to one of the existing +# certificate files. +# +#TLS_PRIVATE_KEYFILE=@certsdir@/imapd_private_key.pem +  ##NAME: TLS_DHPARAMS:0  #  # TLS_DHPARAMS - DH parameter file. diff --git a/imap/imapd.c b/imap/imapd.c index 56cdc61..095defb 100644 --- a/imap/imapd.c +++ b/imap/imapd.c @@ -714,7 +714,8 @@ static int store_mailbox(const char *tag, const char *mailbox,  			 time_t	timestamp,  			 struct imaptoken *curtoken,  			 unsigned long *new_uidv, -			 unsigned long *new_uid) +			 unsigned long *new_uid, +			 int *utf8_error)  {  	unsigned long nbytes=curtoken->tokennum;  	char	*tmpname; @@ -797,10 +798,8 @@ static int store_mailbox(const char *tag, const char *mailbox,  	if ((rfc2045_parser->rfcviolation & RFC2045_ERR8BITHEADER) &&  	    curtoken->tokentype != IT_LITERAL8_STRING_START)  	{ -		errmsg=" NO [ALERT] Your IMAP client does not appear to " -			"correctly implement Unicode messages, " -			"see https://tools.ietf.org/html/rfc6855.html\r\n"; -		errflag=1; +		/* in order to [ALERT] the client */ +		*utf8_error=1;  	}  	rfc2045_free(rfc2045_parser); @@ -1335,6 +1334,8 @@ void doNoop(int real_noop)  #endif  		new_maildir_info.msgs[j].copiedflag=  			current_maildir_info.msgs[i].copiedflag; +		new_maildir_info.msgs[j].err8bitflag= +			current_maildir_info.msgs[i].err8bitflag;  		++j;  	} @@ -1479,9 +1480,10 @@ static int doId()  		curtoken = nexttoken(); -		fprintf(stderr, "INFO: ID, user=%s, ip=[%s]", +		fprintf(stderr, "INFO: ID, user=%s, ip=[%s], port=[%s]",  			getenv("AUTHENTICATED"), -			getenv("TCPREMOTEIP")); +			getenv("TCPREMOTEIP"), +			getenv("TCPREMOTEPORT"));  		while ((k < 30) && (curtoken->tokentype != IT_RPAREN)) {  			k++; @@ -1819,9 +1821,10 @@ int log_deletions= cp && *cp != '0';  			}  			if (log_deletions) -				fprintf(stderr, "INFO: EXPUNGED, user=%s, ip=[%s], old_name=%s, new_name=%s: only new_name will be left\n", +				fprintf(stderr, "INFO: EXPUNGED, user=%s, ip=[%s], port=[%s], old_name=%s, new_name=%s: only new_name will be left\n",  					getenv("AUTHENTICATED"),  					getenv("TCPREMOTEIP"), +					getenv("TCPREMOTEPORT"),  					old_name, new_name);  			if (rename(old_name, new_name)) @@ -1857,9 +1860,10 @@ int log_deletions= cp && *cp != '0';  		}  		if (log_deletions) -			fprintf(stderr, "INFO: EXPUNGED, user=%s, ip=[%s], old_name=%s\n", +			fprintf(stderr, "INFO: EXPUNGED, user=%s, ip=[%s], port=[%s], old_name=%s\n",  				getenv("AUTHENTICATED"),  				getenv("TCPREMOTEIP"), +				getenv("TCPREMOTEPORT"),  				old_name);  		free(old_name);  	} @@ -3911,6 +3915,7 @@ static int append(const char *tag, const char *mailbox, const char *path)  	char access_rights[8];  	struct imaptoken *curtoken;  	int need_rparen; +	int utf8_error=0;  	if (access(path, 0))  	{ @@ -4030,7 +4035,7 @@ static int append(const char *tag, const char *mailbox, const char *path)  			  acl_flags_adjust(access_rights, &flags)  			  ? NULL:keywords,  			  timestamp, -			  curtoken, &new_uidv, &new_uid)) +			  curtoken, &new_uidv, &new_uid, &utf8_error))  	{  		libmail_kwmDestroy(keywords);  		unread('\n'); @@ -4052,12 +4057,18 @@ static int append(const char *tag, const char *mailbox, const char *path)  	}  	dirsync(path); +	if (utf8_error) { +		writes("* OK [ALERT] Your IMAP client does not appear to " +		       "correctly implement Unicode messages, " +		       "see https://tools.ietf.org/html/rfc6855.html\r\n"); +	}  	writes(tag);  	writes(" OK [APPENDUID ");  	writen(new_uidv);  	writes(" ");  	writen(new_uid); -	writes("] APPEND Ok.\r\n"); +	writes("] APPEND Ok."); +	writes("\r\n");  	return (0);  } diff --git a/imap/imapd.cnf.gnutls b/imap/imapd.cnf.gnutls.in index 1078baf..1078baf 100644 --- a/imap/imapd.cnf.gnutls +++ b/imap/imapd.cnf.gnutls.in diff --git a/imap/imapd.sgml b/imap/imapd.sgml index e842c20..43b8ec3 100644 --- a/imap/imapd.sgml +++ b/imap/imapd.sgml @@ -1,7 +1,7 @@  <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">  <!-- Copyright 1998 - 2007 Double Precision, Inc.  See COPYING for -->  <!-- distribution information. --> -<refentry> +<refentry id="imapd">    <info><author><firstname>Sam</firstname><surname>Varshavchik</surname><contrib>Author</contrib></author><productname>Courier Mail Server</productname></info>    <refmeta> @@ -31,7 +31,7 @@      </cmdsynopsis>    </refsynopsisdiv> -  <refsect1> +  <refsect1 id="imapd_description">      <title>DESCRIPTION</title>      <para> @@ -81,7 +81,7 @@ variable, then attempts to talk IMAP on standard input and output.</para>    </refsect1> -  <refsect1> +  <refsect1 id="imapd_files_and_environment_variables">      <title>FILES AND ENVIRONMENT VARIABLES</title>      <variablelist> @@ -136,7 +136,7 @@ Other environment variables are initialized from the  These files are loaded into the environment by the system startup script  that runs <command moreinfo="none">couriertcpd</command>.</para> -    <refsect2> +    <refsect2 id="imapd_realtime_concurrent_folder_status_updates">        <title>Realtime concurrent folder status updates</title>        <para> @@ -310,7 +310,7 @@ in IDLE mode (instead of in real time).        </variablelist>      </refsect2> -    <refsect2> +    <refsect2 id="imapd_verifying_realtime_concurrent_folder_status_updates">        <title>Verifying realtime concurrent folder status updates</title>        <para>  Use the following procedure to verify that realtime concurrent folder status @@ -482,7 +482,7 @@ all terminal windows have the same <literal moreinfo="none">EXISTS</literal> mes        </orderedlist>      </refsect2>    </refsect1> -  <refsect1> +  <refsect1 id="imapd_see_also">      <title>SEE ALSO</title>      <para> diff --git a/imap/imaplogin.c b/imap/imaplogin.c index cd223f2..8e8289e 100644 --- a/imap/imaplogin.c +++ b/imap/imaplogin.c @@ -287,8 +287,9 @@ int do_imap_command(const char *tag, int *flushflag)  		writes("* BYE Courier-IMAP server shutting down\r\n");  		cmdsuccess(tag, "LOGOUT completed\r\n");  		writeflush(); -		fprintf(stderr, "INFO: LOGOUT, ip=[%s], rcvd=%lu, sent=%lu\n", -			getenv("TCPREMOTEIP"), bytes_received_count, bytes_sent_count); +		fprintf(stderr, "INFO: LOGOUT, ip=[%s], port=[%s], rcvd=%lu, sent=%lu\n", +			getenv("TCPREMOTEIP"), getenv("TCPREMOTEPORT"), +			bytes_received_count, bytes_sent_count);  		exit(0);  	}  	if (strcmp(curtoken->tokenbuf, "NOOP") == 0) @@ -373,9 +374,11 @@ int do_imap_command(const char *tag, int *flushflag)  		if (!p || !*p)  			p="imap"; -		rc=auth_login(p, userid, passwd, login_callback, (void *)tag); -		courier_safe_printf("INFO: LOGIN FAILED, user=%s, ip=[%s]", -				  userid, getenv("TCPREMOTEIP")); +		rc=auth_login_meta(NULL, p, userid, passwd, +				   login_callback, (void *)tag); +		courier_safe_printf("INFO: LOGIN FAILED, user=%s, ip=[%s], port=[%s]", +				    userid, getenv("TCPREMOTEIP"), +				    getenv("TCPREMOTEPORT"));  		free(userid);  		free(passwd);  		if (rc > 0) @@ -401,8 +404,9 @@ int do_imap_command(const char *tag, int *flushflag)  			return (0);  		}  		rc=authenticate(tag, method, sizeof(method)); -		courier_safe_printf("INFO: LOGIN FAILED, method=%s, ip=[%s]", -				  method, getenv("TCPREMOTEIP")); +		courier_safe_printf("INFO: LOGIN FAILED, method=%s, ip=[%s], port=[%s]", +				    method, getenv("TCPREMOTEIP"), +				    getenv("TCPREMOTEPORT"));  		if (rc > 0)  		{  			perror("ERR: authentication error"); @@ -424,6 +428,7 @@ extern void ignorepunct();  int main(int argc, char **argv)  {  	const char	*ip; +	const char	*port;  #ifdef HAVE_SETVBUF_IOLBF  	setvbuf(stderr, NULL, _IOLBF, BUFSIZ); @@ -446,6 +451,11 @@ int main(int argc, char **argv)  		putenv("TCPREMOTEIP=127.0.0.1");  	ip=getenv("TCPREMOTEIP"); +	port=getenv("TCPREMOTEPORT"); +	if (!port) +		putenv("TCPREMOTEPORT=N/A"); +	port=getenv("TCPREMOTEPORT"); +  	if (!getenv("TCPLOCALPORT"))  		putenv("TCPLOCALPORT=143"); @@ -471,9 +481,9 @@ int main(int argc, char **argv)  	writes("* OK [CAPABILITY ");  	imapcapability();  	writes("] Courier-IMAP ready. " -	       "Copyright 1998-2018 Double Precision, Inc.  " +	       "Copyright 1998-2019 Double Precision, Inc.  "  	       "See COPYING for distribution information.\r\n"); -	fprintf(stderr, "DEBUG: Connection, ip=[%s]\n", ip); +	fprintf(stderr, "DEBUG: Connection, ip=[%s], port=[%s]\n", ip, port);  	writeflush();  	main_argc=argc;  	main_argv=argv; diff --git a/imap/imapscanclient.c b/imap/imapscanclient.c index da79c70..515abc2 100644 --- a/imap/imapscanclient.c +++ b/imap/imapscanclient.c @@ -868,7 +868,7 @@ int	dowritecache=0;  		scaninfo->msgs[i].filename=tempinfo_array[i]->filename;  		scaninfo->msgs[i].keywordMsg=NULL;  		scaninfo->msgs[i].copiedflag=0; - +		scaninfo->msgs[i].err8bitflag=0;  #if SMAP  		if (smapflag)  			scaninfo->msgs[i].recentflag=0; diff --git a/imap/imapscanclient.h b/imap/imapscanclient.h index 2b01180..373bc83 100644 --- a/imap/imapscanclient.h +++ b/imap/imapscanclient.h @@ -23,6 +23,7 @@ struct imapscanmessageinfo {  	char storeflag;  /* Used by imap_addRemoveKeywords() */ +	char err8bitflag;       /* Invalid 8 bit header error was reported */  	/* When reading keywords, hash messages by filename */  	struct imapscanmessageinfo *firstBucket, *nextBucket; @@ -59,7 +60,7 @@ struct uidplus_info {  	unsigned long uid; /* Initialized by imapscan_maildir2 */  	unsigned long old_uid; /* Initialized by do_copy() */ -	 +  	time_t mtime;  } ; diff --git a/imap/imaptoken.c b/imap/imaptoken.c index a11310a..153450a 100644 --- a/imap/imaptoken.c +++ b/imap/imaptoken.c @@ -60,13 +60,16 @@ void bye_msg(const char *type)  	if (a && *a)  		fprintf(stderr, "%s, user=%s, " -			"ip=[%s], headers=%lu, body=%lu, rcvd=%lu, sent=%lu, time=%s%s\n", +			"ip=[%s], port=[%s], headers=%lu, body=%lu, rcvd=%lu, sent=%lu, time=%s%s\n",  			type, -			a, getenv("TCPREMOTEIP"), header_count, body_count, bytes_received_count, bytes_sent_count, +			a, getenv("TCPREMOTEIP"), +			getenv("TCPREMOTEPORT"), +			header_count, body_count, bytes_received_count, bytes_sent_count,  			buf, tls);  	else -		fprintf(stderr, "DEBUG: Disconnected, ip=[%s], time=%s%s\n", +		fprintf(stderr, "DEBUG: Disconnected, ip=[%s], port=[%s], time=%s%s\n",  			getenv("TCPREMOTEIP"), +			getenv("TCPREMOTEPORT"),  			buf, tls);  } diff --git a/imap/mainloop.c b/imap/mainloop.c index f2224a8..dc4b06f 100644 --- a/imap/mainloop.c +++ b/imap/mainloop.c @@ -34,6 +34,7 @@ static RETSIGTYPE sigexit(int n)  	int l = 0;  	const char *tls=getenv("IMAP_TLS");  	const char *ip=getenv("TCPREMOTEIP"); +	const char *port=getenv("TCPREMOTEPORT");  	if (write(1, byemsg, sizeof(byemsg)-1) < 0)  		exit(1); @@ -49,12 +50,13 @@ static RETSIGTYPE sigexit(int n)  	if (a && *a)  		l = snprintf(msg, sizeof(msg) - 1, "NOTICE: Disconnected during shutdown by signal, user=%s, " -			"ip=[%s], headers=%lu, body=%lu, rcvd=%lu, sent=%lu, time=%s%s\n", -			a, ip, header_count, body_count, bytes_received_count, bytes_sent_count, +			     "ip=[%s], port=[%s], headers=%lu, body=%lu, rcvd=%lu, sent=%lu, time=%s%s\n", +			     a, ip, port, header_count, body_count, bytes_received_count, bytes_sent_count,  			buf, tls);  	else -		l = snprintf(msg, sizeof(msg) - 1, "NOTICE: Disconnected during shutdown by signal, ip=[%s], time=%s%s\n", -			getenv("TCPREMOTEIP"), +		l = snprintf(msg, sizeof(msg) - 1, "NOTICE: Disconnected during shutdown by signal, ip=[%s], port=[%s], time=%s%s\n", +			     getenv("TCPREMOTEIP"), +			     getenv("TCPREMOTEPORT"),  			buf, tls);  	if (l > 0 && write(2, msg, l)) @@ -123,7 +125,7 @@ void mainloop(void)  			if (strlen(tag)+strlen(curtoken->tokenbuf) > IT_MAX_ATOM_SIZE)  				write_error_exit("max atom size too small"); -		  		 +  			strncat(tag, curtoken->tokenbuf, IT_MAX_ATOM_SIZE);  			rc=do_imap_command(tag, &flushflag); diff --git a/imap/makeimapaccess.sgml b/imap/makeimapaccess.sgml index a908891..8d53284 100644 --- a/imap/makeimapaccess.sgml +++ b/imap/makeimapaccess.sgml @@ -1,7 +1,7 @@  <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">  <!-- Copyright 1998 - 2009 Double Precision, Inc.  See COPYING for -->  <!-- distribution information. --> -<refentry> +<refentry id="makeimapaccess">    <info><author><firstname>Sam</firstname><surname>Varshavchik</surname><contrib>Author</contrib></author><productname>Courier Mail Server</productname></info>    <refmeta> @@ -21,7 +21,7 @@      </cmdsynopsis>    </refsynopsisdiv> -  <refsect1> +  <refsect1 id="makeimapaccess_description">      <title>DESCRIPTION</title>      <para> @@ -46,7 +46,7 @@        describes the general format of access files.</para> -    <refsect2> +    <refsect2 id="makeimapaccess_the_imapaccess_configuration_file">        <title>The <filename>imapaccess</filename> configuration file</title>        <para> @@ -64,7 +64,7 @@      </refsect2>    </refsect1> -  <refsect1> +  <refsect1 id="makeimapaccess_see_also">      <title>SEE ALSO</title>      <para>        <ulink url="couriertcpd.html"><citerefentry><refentrytitle>couriertcpd</refentrytitle><manvolnum>8</manvolnum></citerefentry></ulink>. diff --git a/imap/mkdhparams.sgml b/imap/mkdhparams.sgml index c275829..1941278 100644 --- a/imap/mkdhparams.sgml +++ b/imap/mkdhparams.sgml @@ -1,7 +1,7 @@  <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">  <!-- Copyright 2013 Double Precision, Inc.  See COPYING for -->  <!-- distribution information. --> -<refentry> +<refentry id="mkdhparams">    <info><author><firstname>Sam</firstname><surname>Varshavchik</surname><contrib>Author</contrib></author><productname>Courier Mail Server</productname></info>    <refmeta> @@ -21,7 +21,7 @@      </cmdsynopsis>    </refsynopsisdiv> -  <refsect1> +  <refsect1 id="mkdhparams_description">      <title>DESCRIPTION</title>      <para> @@ -38,7 +38,7 @@      </para>    </refsect1> -  <refsect1> +  <refsect1 id="mkdhparams_files">      <title>FILES</title>      <variablelist> @@ -53,7 +53,7 @@      </variablelist>    </refsect1> -  <refsect1> +  <refsect1 id="mkdhparams_environment_variables">      <title>ENVIRONMENT VARIABLES</title>      <variablelist> @@ -79,7 +79,7 @@      </para>    </note> -  <refsect1> +  <refsect1 id="mkdhparams_see_also">      <title>SEE ALSO</title>      <para> diff --git a/imap/mkimapdcert.sgml b/imap/mkimapdcert.sgml index 6b1c2f8..d367e13 100644 --- a/imap/mkimapdcert.sgml +++ b/imap/mkimapdcert.sgml @@ -1,7 +1,7 @@  <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">  <!-- Copyright 2000 - 2007 Double Precision, Inc.  See COPYING for -->  <!-- distribution information. --> -<refentry> +<refentry id="mkimapdcert">    <info><author><firstname>Sam</firstname><surname>Varshavchik</surname><contrib>Author</contrib></author><productname>Courier Mail Server</productname></info>    <refmeta> @@ -21,7 +21,7 @@      </cmdsynopsis>    </refsynopsisdiv> -  <refsect1> +  <refsect1 id="mkimapdcert_description">      <title>DESCRIPTION</title>      <para> @@ -50,7 +50,7 @@ will not work if <command moreinfo="none">@certsdir@/imapd.pem</command> already    </refsect1> -  <refsect1> +  <refsect1 id="mkimapdcert_files">      <title>FILES</title>      <variablelist> @@ -74,7 +74,7 @@ create the X.509 certificate.        </varlistentry>      </variablelist>    </refsect1> -  <refsect1> +  <refsect1 id="mkimapdcert_see_also">      <title>SEE ALSO</title>      <para> diff --git a/imap/mkpop3dcert.sgml b/imap/mkpop3dcert.sgml index abd4258..137c1c4 100644 --- a/imap/mkpop3dcert.sgml +++ b/imap/mkpop3dcert.sgml @@ -1,7 +1,7 @@  <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">  <!-- Copyright 2000 - 2007 Double Precision, Inc.  See COPYING for -->  <!-- distribution information. --> -<refentry> +<refentry id="mkpop3dcert">    <info><author><firstname>Sam</firstname><surname>Varshavchik</surname><contrib>Author</contrib></author><productname>Courier Mail Server</productname></info>    <refmeta> @@ -21,7 +21,7 @@      </cmdsynopsis>    </refsynopsisdiv> -  <refsect1> +  <refsect1 id="mkpop3dcert_description">      <title>DESCRIPTION</title>      <para> @@ -50,7 +50,7 @@ will not work if <command moreinfo="none">@datadir@/pop3d.pem</command> already    </refsect1> -  <refsect1> +  <refsect1 id="mkpop3dcert_files">      <title>FILES</title>      <variablelist> @@ -74,7 +74,7 @@ create the X.509 certificate.        </varlistentry>      </variablelist>    </refsect1> -  <refsect1> +  <refsect1 id="mkpop3dcert_see_also">      <title>SEE ALSO</title>      <para> diff --git a/imap/pop3d-ssl.dist.in.git b/imap/pop3d-ssl.dist.in.git index ec16ce8..bca75e8 100644 --- a/imap/pop3d-ssl.dist.in.git +++ b/imap/pop3d-ssl.dist.in.git @@ -5,7 +5,7 @@  # Do not alter lines that begin with ##, they are used when upgrading  # this configuration.  # -#  Copyright 2000-2016 Double Precision, Inc.  See COPYING for +#  Copyright 2000-2019 Double Precision, Inc.  See COPYING for  #  distribution information.  #  #  This configuration file sets various options for the Courier-IMAP server @@ -91,7 +91,9 @@ COURIERTLS=@bindir@/couriertls  ##NAME: TLS_PRIORITY:0  # -# Set TLS protocol priority settings (GnuTLS only) +# GnuTLS setting only (use TLS_CIPHER_LIST for OpenSSL) +# +# Set TLS protocol priority settings  #  # DEFAULT: NORMAL:-CTYPE-OPENPGP  # @@ -142,29 +144,9 @@ TLS_STARTTLS_PROTOCOL="$TLS_PROTOCOL"  # OpenSSL library.  In most situations you can leave TLS_CIPHER_LIST  # undefined  # -# OpenSSL: -#  # TLS_CIPHER_LIST="TLSv1:HIGH:!LOW:!MEDIUM:!EXP:!NULL:!aNULL@STRENGTH"  # -# GnuTLS: -# -# TLS_CIPHER_LIST="HIGH:MEDIUM" -# -# The actual list of available ciphers depend on the options GnuTLS was -# compiled against. The possible ciphers are: -# -# AES256, 3DES, AES128, ARC128, ARC40, RC2, DES, NULL -# -# Also, the following aliases: -# -# HIGH -- all ciphers that use more than a 128 bit key size -# MEDIUM -- all ciphers that use a 128 bit key size -# LOW -- all ciphers that use fewer than a 128 bit key size, the NULL cipher -#        is not included -# ALL -- all ciphers except the NULL cipher -# -# See GnuTLS documentation, gnutls_priority_init(3) for additional -# documentation. +# See the OpenSSL ciphers(1) manual page for the format of this setting.  ##NAME: TLS_STARTTLS_PROTOCOL:0  # @@ -223,6 +205,45 @@ TLS_STARTTLS_PROTOCOL="$TLS_PROTOCOL"  TLS_CERTFILE=@certsdir@/pop3d.pem +##NAME: TLS_PRIVATE_KEYFILE:0 +# +# TLS_PRIVATE_KEYFILE - SSL/TLS private key for decrypting peer data. +# This file must be owned by the "@mailuser@" user, and must not be world +# readable, and must be accessible without a pass-phrase, i.e. it must not +# be encrypted. +# +# By default, courier generates SSL/TLS certifice including private key +# and install it in TLS_CERTFILE path, so TLS_PRIVATE_KEYFILE is completely +# optional. If TLS_PRIVATE_KEYFILE is not set (default), TLS_CERTFILE is +# treated as certificate including private key file. +# +# If you get SSL/TLS certificate and private key from trusted certificate +# authority(CA) and want to install them separately, TLS_PRIVATE_KEYFILE can +# be used as private key file path setting. +# +# VIRTUAL HOSTS ON THE SAME IP ADDRESS. +# +# $TLS_PRIVATE_KEYFILE.domain and $TLS_CERTFILE.domain are a pair. +# If you use VIRTUAL HOST feature on TLS_CERTFILE setting, you must set pair +# private key as $TLS_PRIVATE_KEYFILE.domain. Then, create a link from +# $TLS_PRIVATE_KEYFILE to whichever private key you consider to be the main one. +# for example: +# /etc/tls_private_keyfile.pem => /etc/tls_private_keyfile.pem.www.example.com +# +# IP-BASED VIRTUAL HOSTS: +# +# Just described on "VIRTUAL HOSTS ON THE SAME IP ADDRESS" above, +# $TLS_PRIVATE_KEYFILE.aaa.bbb.ccc.ddd and $TLS_CERTFILE.aaa.bbb.ccc.ddd are +# a pair. If TLS_PRIVATE_KEYFILE is set to /etc/tls_private_keyfile.pem, +# then you'll need to install the actual certificate files as +# /etc/tls_private_keyfile.pem.192.168.0.2, /etc/tls_private_keyfile.192.168.0.3 +# and so on, for each IP address. +# +# In all cases, $TLS_PRIVATE_KEYFILE needs to be linked to one of the existing +# certificate files. +# +#TLS_PRIVATE_KEYFILE=@certsdir@/pop3d_private_key.pem +  ##NAME: TLS_DHPARAMS:0  #  # TLS_DHPARAMS - DH parameter file. diff --git a/imap/pop3d.cnf.gnutls b/imap/pop3d.cnf.gnutls.in index a8a4466..a8a4466 100644 --- a/imap/pop3d.cnf.gnutls +++ b/imap/pop3d.cnf.gnutls.in diff --git a/imap/pop3d.dist.in.git b/imap/pop3d.dist.in.git index 17f1e38..788224f 100644 --- a/imap/pop3d.dist.in.git +++ b/imap/pop3d.dist.in.git @@ -181,3 +181,12 @@ POP3DSTART=NO  # MAILDIRPATH - directory name of the maildir directory.  #  MAILDIRPATH=Maildir + +##NAME: MIME_UNICODE_MESSAGE_TYPE:0 +# +# MIME type that wraps Unicode messages for downloading by non-Unicode +# POP3 clients. +# +# This can be changed to "message/rfc822" to accomodate older mail clients. + +MIME_UNICODE_MESSAGE_TYPE="message/global" diff --git a/imap/pop3dserver.c b/imap/pop3dserver.c index beca04a..ea5ed99 100644 --- a/imap/pop3dserver.c +++ b/imap/pop3dserver.c @@ -92,6 +92,7 @@ static unsigned msglist_cnt;  static struct stat enomem_stat;  static int enomem_1msg;  int utf8_enabled; +int savesizes=0;  /*  ** When a disk error occurs while saving an updated courierpop3dsizelist @@ -138,6 +139,7 @@ static void calcsize(struct msglist *m)  	if (m->size > 0 && fseek(f, -1, SEEK_SET) == 0 && getc(f) != '\n')  		m->size+=2; /* We'll add an extra CRLF ourselves */ +	m->isutf8=0;  	if (p->rfcviolation & RFC2045_ERR8BITHEADER)  		m->isutf8=1;  	rfc2045_free(p); @@ -178,12 +180,13 @@ static struct msglist **readpop3dlist(unsigned long *uid)  	struct msglist *list=NULL;  	size_t mcnt=0; -	char linebuf[1024]; +	char linebuf[2048];  	FILE *fp=openpop3dlist();  	size_t i;  	int vernum=0; +	unsigned long size;  	uidv=time(NULL); @@ -191,12 +194,18 @@ static struct msglist **readpop3dlist(unsigned long *uid)  	    fgets(linebuf, sizeof(linebuf)-1, fp) == NULL ||  	    linebuf[0] != '/' || sscanf(linebuf+1, "%d %lu %lu", &vernum,  					uid, &uidv) -	    < 2 || vernum != LISTVERSION) +	    < 2 || (vernum != LISTVERSION && +		    vernum != (LISTVERSION-1)))  	{  		if (fp)  			fclose(fp);  		fp=NULL;  	} +	else +	{ +		if (vernum != LISTVERSION) +			savesizes=1; +	}  	if (fp)  	{ @@ -211,7 +220,7 @@ static struct msglist **readpop3dlist(unsigned long *uid)  		{  			if (ch != '\n')  			{ -				if (n < sizeof(linebuf)-3) +				if (n < sizeof(linebuf)-20)  					linebuf[n++]=ch;  				continue;  			} @@ -243,10 +252,15 @@ static struct msglist **readpop3dlist(unsigned long *uid)  				exit(1);  			} -			if (sscanf(p, "%lu %lu:%lu:%d", &m->size, +			// Converting from LISTVERSION 2, assuming no UTF-8. +			// We have extra room at the end. +			strcat(p, ":0"); + +			if (sscanf(p, "%lu %lu:%lu:%d", &size,  				   &m->uid.n, &m->uid.uidv,  				   &m->isutf8) == 4)  			{ +				m->size=size;  				m->next=list;  				list=m;  				++mcnt; @@ -417,7 +431,6 @@ static void sortmsgs()  	size_t i, n;  	struct msglist *m;  	struct msglist **prev_list; -	int savesizes=0;  	unsigned long nextuid; @@ -545,9 +558,10 @@ static void cleanup()  			}  			if (log_deletions) -				fprintf(stderr, "INFO: DELETED, user=%s, ip=[%s], filename=%s\n", +				fprintf(stderr, "INFO: DELETED, user=%s, ip=[%s], port=[%s], filename=%s\n",  					getenv("AUTHENTICATED"), -					getenv("TCPREMOTEIP"), +					remoteip, +					remoteport,  					msglist_a[i]->filename);  			if (unlink(msglist_a[i]->filename)) @@ -637,6 +651,59 @@ char	buf[NUMBUFSIZE];  /* RETR and TOP POP3 commands */ +#define MIMEWRAPTXT							\ +	"From: Mail Delivery Subsystem <postmaster>\n"			\ +	"Subject: Cannot display Unicode content\n"			\ +	"Mime-Version: 1.0\n"						\ +	"Content-Type: multipart/mixed; boundary=\"%s\"\n"		\ +	"\n\n\n--%s\n"							\ +	"Content-Type: text/plain\n\n"					\ +	"This E-mail message was determined to be Unicode-formatted\n"	\ +	"but your E-mail reader does not support Unicode E-mail.\n\n"	\ +	"Please use an E-mail reader that supports POP3 with UTF-8\n"	\ +	"(see https://tools.ietf.org/html/rfc6856.html).\n\n"		\ +	"This can also happen when the sender's E-mail program does not\n" \ +	"correctly format the sent message.\n\n"			\ +	"The original message is included as a separate attachment\n"	\ +	"so that it can be downloaded manually.\n\n"			\ +	"--%s\n"							\ +	"Content-Type: %s\n\n" + +struct retr_source { +	char *wrapheader; +	FILE *f; +	char *wrapfooter; +}; + +static int get_retr_source(struct retr_source *s) +{ +	int c=(unsigned char)*s->wrapheader; + +	if (c) +	{ +		++s->wrapheader; +		return c; +	} + +	if (s->f) +	{ +		int c=getc(s->f); + +		if (c >= 0) +			return c; +		s->f=0; +	} + +	if (*s->wrapfooter) +	{ +		int c=(unsigned char)*s->wrapfooter; + +		++s->wrapfooter; +		return c; +	} +	return -1; +} +  static void do_retr(unsigned i, unsigned *lptr)  {  	FILE	*f; @@ -645,18 +712,25 @@ static void do_retr(unsigned i, unsigned *lptr)  	int	inheader=1;  	char	buf[NUMBUFSIZE];  	unsigned long *cntr; +	char boundary[256]; +	char wrapheader[sizeof(MIMEWRAPTXT)+1024]; +	char wrapfooter[512]; +	const char *mime_message_type=getenv("MIME_UNICODE_MESSAGE_TYPE"); +	struct retr_source rs; + +	wrapheader[0]=0; +	wrapfooter[0]=0; + +	if (!mime_message_type) +		mime_message_type="message/global";  	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; +		sprintf(boundary, "=_%d-%d", (int)getpid(), (int)time(NULL)); + +		sprintf(wrapheader, MIMEWRAPTXT, boundary, boundary, boundary, +			mime_message_type); +		sprintf(wrapfooter, "\n--%s--\n", boundary);  	}  	f=fopen(msglist_a[i]->filename, "r"); @@ -668,13 +742,20 @@ static void do_retr(unsigned i, unsigned *lptr)  		return;  	}  	printed(printf( (lptr ? "+OK headers follow.\r\n":"+OK %s octets follow.\r\n"), -			libmail_str_off_t(msglist_a[i]->size, buf))); +			libmail_str_off_t(msglist_a[i]->size + +					  strlen(wrapheader) + +					  strlen(wrapfooter), +					  buf)));  	cntr= &retr_count;  	if (lptr)  		cntr= &top_count; -	for (lastc=0; (c=getc(f)) >= 0; lastc=c) +	rs.wrapheader=wrapheader; +	rs.f=f; +	rs.wrapfooter=wrapfooter; + +	for (lastc=0; (c=get_retr_source(&rs)) >= 0; lastc=c)  	{  		if (lastc == '\n')  		{ @@ -983,6 +1064,15 @@ int	c;  			continue;  		} +              if (strcmp(p, "UTF8") == 0) +              { +                      /* XXX workaround for MS Outlook */ +                      utf8_enabled=1; +                      printed(printf("+OK UTF8 enabled\r\n")); +                      fflush(stdout); +                      continue; +              } +  error:  		printed(printf("-ERR Invalid command.\r\n"));  		fflush(stdout); diff --git a/imap/pop3login.c b/imap/pop3login.c index be96d0e..5a67fda 100644 --- a/imap/pop3login.c +++ b/imap/pop3login.c @@ -1,5 +1,5 @@  /* -** Copyright 1998 - 2014 Double Precision, Inc. +** Copyright 1998 - 2020 Double Precision, Inc.  ** See COPYING for distribution information.  */ @@ -100,7 +100,7 @@ static int	starttls()  		exit(1);  	}  	close(pipefd[0]); - +	fflush(stdin);  	putenv("POP3_STARTTLS=NO");  	putenv("POP3_TLS_REQUIRED=0");  	putenv("POP3_TLS=1"); @@ -249,7 +249,9 @@ char	*p;  char	buf[BUFSIZ];  int	c;  const	char *ip=getenv("TCPREMOTEIP"); -char authservice[40]; +const	char *port=getenv("TCPREMOTEPORT"); + + char authservice[40];  char *q ;  #ifdef HAVE_SETVBUF_IOLBF @@ -261,6 +263,9 @@ char *q ;  		ip="127.0.0.1";  	} +	if (!port || !*port) +		port="N/A"; +  	if (argc != 3)  	{  		printf("-ERR pop3login requires exactly two arguments.\r\n"); @@ -273,7 +278,7 @@ char *q ;  	courier_authdebug_login_init(); -	fprintf(stderr, "DEBUG: Connection, ip=[%s]\n", ip); +	fprintf(stderr, "DEBUG: Connection, ip=[%s], port=[%s]\n", ip, port);  	printf("+OK Hello there.\r\n");  	fflush(stdout); @@ -303,8 +308,8 @@ char *q ;  			if ( strcmp(p, "QUIT") == 0)  			{ -				fprintf(stderr, "INFO: LOGOUT, ip=[%s]\n", -					ip); +				fprintf(stderr, "INFO: LOGOUT, ip=[%s], port=[%s]\n", +					ip, port);  				fflush(stderr);  				printf("+OK Better luck next time.\r\n");  				fflush(stdout); @@ -398,18 +403,20 @@ char *q ;  						if (!q || !*q)  							q="pop3"; -						rc=auth_generic(q, -							     authtype, -							     authdata, -							     login_callback, -							     NULL); +						rc=auth_generic_meta +							(NULL, q, +							 authtype, +							 authdata, +							 login_callback, +							 NULL);  						free(authtype);  						free(authdata);  					} -					courier_safe_printf("INFO: LOGIN " -						"FAILED, method=%s, ip=[%s]", -						method, ip); +					courier_safe_printf +						("INFO: LOGIN " +						 "FAILED, method=%s, ip=[%s], port=[%s]", +						 method, ip, port);  					if (rc == AUTHSASL_ABORTED)  					    printf("-ERR Authentication aborted.\r\n");  					else if (rc > 0) @@ -446,10 +453,12 @@ char *q ;  				if (!q || !*q)  					q="pop3"; -				rc=auth_login(q, user, p, login_callback, NULL); -				courier_safe_printf("INFO: LOGIN " -					"FAILED, user=%s, ip=[%s]", -					user, ip); +				rc=auth_login_meta(NULL, q, user, p, +						   login_callback, NULL); +				courier_safe_printf +					("INFO: LOGIN " +					 "FAILED, user=%s, ip=[%s], port=[%s]", +					 user, ip, port);  				if (rc > 0)  				{  					perror("ERR: authentication error"); @@ -466,7 +475,7 @@ char *q ;  		printf("-ERR Invalid command.\r\n");  		fflush(stdout);  	} -	fprintf(stderr, "DEBUG: Disconnected, ip=[%s]\n", ip); +	fprintf(stderr, "DEBUG: Disconnected, ip=[%s], port=[%s]\n", ip, port);  	exit(0);  	return (0);  } | 
