Commit 74cd6eaf authored by Sam Varshavchik's avatar Sam Varshavchik

checkpoint

parent 231c4ae6
......@@ -77,6 +77,11 @@ AX_COURIER_UNICODE_VERSION
dnl Checks for libraries.
PKG_CHECK_MODULES(LIBIDN, libidn >= 0.0.0, [libidn=yes], [libidn=no])
if test "$libidn" != "yes"
then
AC_MSG_ERROR([libidn not found])
fi
dnl Replace `main' with a function in -lefence:
......
......@@ -84,6 +84,12 @@ then
fi
fi
PKG_CHECK_MODULES(LIBIDN, libidn >= 0.0.0, [libidn=yes], [libidn=no])
if test "$libidn" != "yes"
then
AC_MSG_ERROR([libidn not found])
fi
AC_ARG_WITH(redhat, [], [ redhat=$withval ], [redhat=no])
if test "$srcdir" = "."
......
2018-07-28 Sam Varshavchik <mrsam@courier-mta.com>
* courier: implement the SMTPUTF8 extension.
* dotforward: parse for Delivered-To: only in the header portion
of the message.
2018-07-21 Sam Varshavchik <mrsam@courier-mta.com>
* courier-imap: update Courier-IMAP to support UTF8 POP3. Update
......
......@@ -153,6 +153,12 @@ then
AC_MSG_ERROR(Courier authentication library version 0.66 is required.)
fi
PKG_CHECK_MODULES(LIBIDN, libidn >= 0.0.0, [libidn=yes], [libidn=no])
if test "$libidn" != "yes"
then
AC_MSG_ERROR([libidn not found])
fi
dnl Check whether we should use gdbm, or db.
needs_withdb=0
......
......@@ -79,6 +79,7 @@
/submitmkdir
/sysconfdir.h
/testmxlookup
/testtrack
/uidgid
/uidgid.h
/webmail
......
......@@ -194,7 +194,7 @@ showmodules_LDFLAGS=`@COURIERAUTHCONFIG@ --ldflags`
showconfig_SOURCES=cppmain.C showconfig.C
showconfig_DEPENDENCIES=$(COURIERDEPENDENCIES) module.esmtp/esmtpconfig.o
showconfig_LDADD=$(COURIERLDADD) module.esmtp/esmtpconfig.o
showconfig_LDFLAGS=$(COURIERLDFLAGS)
showconfig_LDFLAGS=$(COURIERLDFLAGS) @LIBIDN_LIBS@
# submit - message submission
......@@ -217,7 +217,7 @@ submit_LDADD=../libs/rfc1035/librfc1035.a \
../libs/md5/libmd5.la ../libs/random128/librandom128.la \
../libs/soxwrap/libsoxwrap.a \
`cat ../libs/soxwrap/soxlibs.dep` \
../afx/libafx.a @NETLIBS@ -lcourierauth
../afx/libafx.a @NETLIBS@ @LIBIDN_LIBS@ -lcourierauth
submit_LDFLAGS=`@COURIERAUTHCONFIG@ --ldflags`
......@@ -226,7 +226,7 @@ submit_LDFLAGS=`@COURIERAUTHCONFIG@ --ldflags`
aliaslookup_SOURCES=aliaslookup.C ldapaliasdrc.c
aliaslookup_DEPENDENCIES=libs/libcommon.la libs/libcourier.la ../afx/libafx.a
aliaslookup_LDADD=libs/libcommon.la libs/libcourier.la ../afx/libafx.a\
@dblibrary@ @NETLIBS@
@dblibrary@ @NETLIBS@ @LIBIDN_LIBS@ -lcourier-unicode
# ldapaliasd - resolve aliases via LDAP
......@@ -265,7 +265,7 @@ testmxlookup_DEPENDENCIES=../libs/rfc1035/librfc1035.a ../libs/soxwrap/libsoxwra
testmxlookup_LDADD=../libs/rfc1035/librfc1035.a ../libs/soxwrap/libsoxwrap.a `cat ../libs/soxwrap/soxlibs.dep` libs/libcourier.la \
../libs/md5/libmd5.la ../libs/random128/librandom128.la \
@dblibrary@ @NETLIBS@
@dblibrary@ @NETLIBS@ -lcourier-unicode @LIBIDN_LIBS@
# maildirmake - create a maildir
......@@ -285,7 +285,7 @@ maildirkw$(EXEEXT): ../libs/maildir/maildirkw$(EXEEXT)
aliasexp_SOURCES=cppmain.C aliasexp.C
aliasexp_DEPENDENCIES=$(COURIERDEPENDENCIES) ../libs/tcpd/libspipe.la ../libs/soxwrap/libsoxwrap.a ../libs/soxwrap/soxlibs.dep ../afx/libafx.a
aliasexp_LDADD=$(COURIERLDADD) ../libs/tcpd/libspipe.la ../libs/soxwrap/libsoxwrap.a `cat ../libs/soxwrap/soxlibs.dep` ../afx/libafx.a -lcourierauth
aliasexp_LDADD=$(COURIERLDADD) ../libs/tcpd/libspipe.la ../libs/soxwrap/libsoxwrap.a `cat ../libs/soxwrap/soxlibs.dep` ../afx/libafx.a -lcourierauth -lcourier-unicode @LIBIDN_LIBS@
aliasexp_LDFLAGS=`@COURIERAUTHCONFIG@ --ldflags`
# aliascombine - Merge alias specifications
......@@ -309,7 +309,8 @@ courierpop3d$(EXEEXT): ../libs/imap/pop3d$(EXEEXT)
mailq_SOURCES=mailq.c
mailq_DEPENDENCIES=libs/libcommon.la libs/libcourier.la ../libs/numlib/libnumlib.la
mailq_LDADD=libs/libcommon.la libs/libcourier.la ../libs/numlib/libnumlib.la
mailq_LDADD=libs/libcommon.la libs/libcourier.la ../libs/numlib/libnumlib.la \
-lcourier-unicode @LIBIDN_LIBS@
# courierd
......@@ -403,11 +404,11 @@ dotforward_LDADD=$(dotforward_DEPENDENCIES) -lcourier-unicode
courier_SOURCES=courier.c courier2.C
courier_DEPENDENCIES=libs/libcommon.la libs/libcourier.la ../libs/liblock/liblock.la \
../libs/numlib/libnumlib.la
courier_LDADD=$(courier_DEPENDENCIES)
courier_LDADD=$(courier_DEPENDENCIES) -lcourier-unicode @LIBIDN_LIBS@
cancelmsg_SOURCES=cancelmsg.c
cancelmsg_DEPENDENCIES=libs/libcommon.la libs/libcourier.la ../libs/numlib/libnumlib.la
cancelmsg_LDADD=$(cancelmsg_DEPENDENCIES)
cancelmsg_LDADD=$(cancelmsg_DEPENDENCIES) -lcourier-unicode @LIBIDN_LIBS@
# courier-config
......@@ -661,7 +662,18 @@ install-perms-local:
#
# Lame regression test.
#
noinst_PROGRAMS=testtrack
testtrack_SOURCES=testtrack.c
testtrack_DEPENDENCIES=../libs/numlib/libnumlib.la
testtrack_LDADD=../libs/numlib/libnumlib.la \
@LIBIDN_LIBS@ -lcourier-unicode
check-am: aliascreate
./aliascreate -tmp=./testsuite.tmp -dump=1 <$(srcdir)/testsuite.alias1.in | sed '/^$$/d' | sort | cmp -s $(srcdir)/testsuite.alias -
./aliascreate -tmp=./testsuite.tmp -dump=1 <$(srcdir)/testsuite.alias2.in | sed '/^$$/d' | sort | cmp -s $(srcdir)/testsuite.alias -
$(srcdir)/dotforward.tst | cmp -s $(srcdir)/dotforward.tst.chk -
rm -rf testtrack.tmp
mkdir testtrack.tmp
./testtrack
rm -rf testtrack.tmp
......@@ -86,16 +86,26 @@ char *hostdomain;
if ((p=strrchr(address, '@')) == 0
|| (config_islocal(p+1, &hostdomain) && hostdomain == 0))
{
locallower(address);
/*
** Local address, convert the userid to lowercase.
*/
char *ua=ulocallower(address);
free(address);
address=ua;
islocal=1;
}
if (hostdomain) free(hostdomain);
domainlower(address);
/*
** Make sure the domain is in UTF8, and is in lowercase.
*/
char *addressu=udomainutf8(address);
std::string s=address;
free(address);
std::string s=addressu;
free(addressu);
return (s);
}
......
/*
** Copyright 2001-2002 Double Precision, Inc.
** Copyright 2001-2018 Double Precision, Inc.
** See COPYING for distribution information.
*/
......@@ -10,6 +10,7 @@
#include <unistd.h>
#include <stdlib.h>
#include <ctype.h>
#include <idna.h>
unsigned max_bofh=100;
int max_bofh_ishard=0;
......@@ -19,21 +20,14 @@ static struct bofh_list *bofh_freemail, *bofh_spamtrap, *bofh_badmx,
*bofh_badfrom;
static struct bofh_list **freemailp, **spamtrapp, **badmxp, **badfromp;
static void addbofh(struct bofh_list ***, void (*)(char *), int);
static void addbofh(struct bofh_list ***, char *(*)(const char *), int);
static void strlower(char *p)
static char *uaddress_lower(const char *p)
{
while (*p)
{
*p=tolower( (int)(unsigned char)*p );
++p;
}
}
static void address_lower(char *p)
{
domainlower(p);
locallower(p);
char *s=ulocallower(p);
char *r=udomainutf8(s);
free(s);
return r;
}
static void bofh_free(struct bofh_list *p)
......@@ -75,7 +69,7 @@ void bofh_init()
bofh_free(p);
}
spamtrapp= &bofh_spamtrap;
while ((p=bofh_badmx) != 0)
{
bofh_badmx=p->next;
......@@ -109,11 +103,11 @@ void bofh_init()
if (strcasecmp(p, "freemail") == 0)
{
addbofh(&freemailp, &strlower, 1);
addbofh(&freemailp, &ualllower, 1);
}
else if (strcasecmp(p, "spamtrap") == 0)
{
addbofh(&spamtrapp, &address_lower, 0);
addbofh(&spamtrapp, &uaddress_lower, 0);
}
else if (strcasecmp(p, "badmx") == 0)
{
......@@ -121,12 +115,12 @@ void bofh_init()
}
else if (strcasecmp(p, "badfrom") == 0)
{
addbofh(&badfromp, &address_lower, 0);
addbofh(&badfromp, &uaddress_lower, 0);
}
else if (strcasecmp(p, "maxrcpts") == 0)
{
char *q=strtok(NULL, " \t\r");
if (q)
{
unsigned n=atoi(q);
......@@ -173,7 +167,8 @@ void bofh_init()
fclose(fp);
}
static void addbofh(struct bofh_list ***p, void (*func)(char *), int moreflag)
static void addbofh(struct bofh_list ***p, char *(*func)(const char *),
int moreflag)
{
char *q=strtok(NULL, " \t\r");
struct bofh_list *b;
......@@ -182,10 +177,13 @@ static void addbofh(struct bofh_list ***p, void (*func)(char *), int moreflag)
return;
b=(struct bofh_list *)courier_malloc(sizeof(struct bofh_list));
b->name=courier_malloc(strlen(q)+1);
strcpy(b->name, q);
b->name=courier_strdup(q);
if (func)
(*func)(b->name);
{
char *p=(*func)(b->name);
free(b->name);
b->name=p;
}
b->next=NULL;
b->aliases=NULL;
**p=b;
......@@ -197,10 +195,14 @@ static void addbofh(struct bofh_list ***p, void (*func)(char *), int moreflag)
struct bofh_list *bb=(struct bofh_list *)
courier_malloc(sizeof(struct bofh_list));
bb->name=courier_malloc(strlen(q)+1);
strcpy(bb->name, q);
bb->name=courier_strdup(q);
if (func)
(*func)(bb->name);
{
char *p=(*func)(bb->name);
free(bb->name);
bb->name=p;
}
bb->next=b->aliases;
b->aliases=bb;
......@@ -228,7 +230,7 @@ static int chkusersubdom(const char *p, const char *d, const char *name)
{
return (0);
}
lp = d - p;
ln = dn - name;
if (lp != ln || strncmp(p, name, ln) != 0)
......@@ -243,13 +245,10 @@ static int chkusersubdom(const char *p, const char *d, const char *name)
static int chkbadlist(const char *pp, struct bofh_list *b)
{
char *p=courier_malloc(strlen(pp)+1);
char *p=uaddress_lower(pp);
const char *d;
int l, ll;
strcpy(p, pp);
address_lower(p);
d=strrchr(p, '@');
l=d ? strlen(d):0;
......@@ -272,28 +271,29 @@ static int chkbadlist(const char *pp, struct bofh_list *b)
return (0);
}
struct bofh_list *bofh_chkfreemail(const char *pp)
struct bofh_list *bofh_chkfreemail(const char *email)
{
char *p;
char *s=uaddress_lower(email);
char *pp;
struct bofh_list *b;
pp=strrchr(pp, '@');
pp=strrchr(s, '@');
if (!pp)
{
free(s);
return (NULL);
p=courier_malloc(strlen(pp));
}
++pp;
strcpy(p, pp);
address_lower(p);
for (b=bofh_freemail; b; b=b->next)
{
if (strcmp(b->name, p) == 0)
if (strcmp(b->name, pp) == 0)
{
free(p);
free(s);
return (b);
}
}
free(p);
free(s);
return (NULL);
}
......
......@@ -1047,7 +1047,7 @@ static int help()
time(&curtime);
addrlower(addr);
uaddrlower(addr);
std::string vaddr= TMP "/help." + toverp(addr);
......
......@@ -164,8 +164,7 @@ int is_subscriber(std::string);
int getinfo(std::string, int (*)(std::string));
std::string myname();
void addrlower(char *);
void addrlower(std::string &); // TODO
void uaddrlower(std::string &);
int isfound(std::string);
int sendmail(const char **, pid_t &);
......
......@@ -71,7 +71,7 @@ std::string fromverp(std::string buf)
while (b != e)
{
if (*b != '+' || e-b < 3)
if (*b != '+' || e-b < 3)
{
obuf.push_back(*b++);
continue;
......@@ -217,7 +217,7 @@ int rc;
key="1";
key += from;
addrlower(key);
uaddrlower(key);
if (alias.Fetch(key, "").size() != 0)
{
......@@ -247,7 +247,7 @@ int getinfodir(std::string dir, std::string address, int (*func)(std::string))
return (1);
}
addrlower(address);
uaddrlower(address);
std::string shared_lock_name=dir;
......
......@@ -216,8 +216,8 @@ struct stat stat_buf;
char bufn[NUMBUFSIZE];
libmail_str_size_t(n, bufn);
addrlower(addr);
uaddrlower(addr);
if (addr.find('@') == addr.npos)
{
std::cerr << "Invalid address." << std::endl;
......
/*
** Copyright 2000-2008 Double Precision, Inc.
** Copyright 2000-2018 Double Precision, Inc.
** See COPYING for distribution information.
*/
......@@ -18,33 +18,39 @@
#include <iostream>
#include <fstream>
#include <list>
#include <courier-unicode.h>
#include <ctype.h>
#include <sysexits.h>
#include <idna.h>
// subscribe an address
void addrlower(char *p)
void uaddrlower(std::string &s)
{
if (cmdget_s("CASESENSITIVE") == "1")
p=strchr(p, '@');
std::string::iterator b=s.begin(), e=s.end();
while (p && *p)
{
*p=tolower((int)(unsigned char)*p);
std::string::iterator p=std::find(b, e, '@');
if (p != e)
++p;
}
}
void addrlower(std::string &s)
{
std::string::iterator b=s.begin(), e=s.end();
std::string username(b, p);
if (cmdget_s("CASESENSITIVE") != "1")
username=unicode::iconvert::convert_tocase(username,
unicode::utf_8,
unicode_lc);
std::string domain(p, e);
if (cmdget_s("CASESENSITIVE") == "1")
b=std::find(b, e, '@');
char *ptr;
if (idna_to_ascii_8z(domain.c_str(), &ptr, 0) == IDNA_SUCCESS)
{
domain=ptr;
free(ptr);
}
std::transform(b, e, b, std::ptr_fun(::tolower));
s=username+unicode::iconvert::convert_tocase(domain,
unicode::utf_8,
unicode_lc);
}
static int cmdsubunsub(const std::vector<std::string> &args,
......@@ -119,7 +125,7 @@ int docmdsub(const char *aptr, std::string subbuf, bool addflag)
std::string buf;
time_t timestamp;
addrlower(addr);
uaddrlower(addr);
std::string::iterator b=addr.begin(), e=addr.end(),
p=std::find(b, e, '@');
......@@ -289,7 +295,7 @@ static int unsub_common(std::string addr, std::string reason, const char *log)
{
struct stat stat_buf;
addrlower(addr);
uaddrlower(addr);
std::string::iterator b=addr.begin(), e=addr.end(),
p=std::find(b, e, '@');
......
......@@ -112,7 +112,7 @@ DbObj dat;
std::string key="sub." + addr;
std::string subfilename;
addrlower(key);
uaddrlower(key);
filename=dat.Fetch(key, "");
......@@ -205,7 +205,7 @@ DbObj dat;
key += ".";
key += addr;
addrlower(key);
uaddrlower(key);
std::string subfilename;
......@@ -404,7 +404,7 @@ int dosubunsubconfirm(const char *address, const char *pfix,
std::string subfilename;
addrlower(key);
uaddrlower(key);
filename=dat.Fetch(key, "");
......@@ -453,7 +453,7 @@ int dosubunsubconfirm(const char *address, const char *pfix,
get_verp_return("owner");
afxopipestream ack(sendmail_bcc(p, owner));
owner= myname() + (" <" + owner + ">");
ack << "Bcc: " << addr << std::endl
......
......@@ -77,6 +77,7 @@ dnl Check whether we should use gdbm, or db.
saveLIBS="$LIBS"
AC_CHECK_LIB(dl, dlopen, [ LIBDL="-ldl" ])
LIBS="$saveLIBS"
PKG_CHECK_MODULES(LIBIDN, libidn >= 0.0.0, [libidn=yes], [libidn=no])
dnl Checks for transport libraries.
......
......@@ -100,6 +100,7 @@ struct rw_list {
void set_courierdir(const char *);
const char *courierdir();
void *courier_malloc(unsigned);
char *courier_strdup(const char *);
struct ctlfile;
struct rfc822token;
......@@ -114,8 +115,11 @@ struct stat;
char *readfile(const char *, struct stat *);
void removecomments(char *);
char *makeerrmsgtext(int, const char *);
void domainlower(char *);
void locallower(char *);
char *udomainlower(const char *);
char *udomainutf8(const char *);
char *udomainace(const char *);
char *ulocallower(const char *);
char *ualllower(const char *);
void gettmpfilenameargs(const char **, const char **, const char **);
void getnewtmpfilenameargs(const char **, const char **, const char **);
char *mktmpfilename();
......@@ -151,9 +155,11 @@ void clog_msg_errno();
void clog_msg_prerrno();
const char *config_me(); /* me config file */
const char *config_me_ace(); /* me config file */
const char *config_esmtphelo(); /* helohost config file */
const char *config_msgidhost(); /* msgidhost config file */
const char *config_defaultdomain(); /* defaultdomain config file */
const char *config_defaultdomain_ace(); /* defaultdomain config file */
const char *config_gethostname(); /* gethostname() call */
const char *config_batchsize(); /* Max addresses per message */
const char *config_defaultdelivery(); /* default delivery instructions */
......
......@@ -11,8 +11,8 @@
</refmeta>
<refnamediv>
<refname>dotforward</refname>
<refname>dot-forward</refname>
<refname>dotforward</refname>
<refpurpose>Read <filename moreinfo="none">$HOME/.forward</filename></refpurpose>
</refnamediv>
......
......@@ -30,21 +30,19 @@ static int exit_code;
static void initdelivto()
{
char buf[BUFSIZ];
char *p, *r;
char *p, *r, *s;
struct delivered_to *q;
int inheader=1;
p=getenv("DTLINE");
if (!p || !(p=strchr(p, ':'))) exit(0);
++p;
while (*p && isspace((int)(unsigned char)*p)) ++p;
myaddr=strdup(p);
if (!myaddr)
{
perror("malloc");
exit(EX_TEMPFAIL);
}
domainlower(myaddr);
locallower(myaddr);
r=udomainutf8(p);
myaddr=ulocallower(r);
free(r);
if (strchr(myaddr, '@') == 0)
{
fprintf(stderr, "Invalid DTLINE environment variable.\n");
......@@ -55,22 +53,34 @@ struct delivered_to *q;
{
p=strchr(buf, '\n');
if (p) *p=0;
if (buf[0] == 0)
inheader=0;
if (!inheader)
continue;
if (strncasecmp(buf, "Delivered-To:", 13)) continue;
p=buf+13;
while (*p && isspace((int)(unsigned char)*p)) ++p;
q=malloc(sizeof(*q)+1+strlen(p));
s=udomainutf8(p);
r=strchr(s, '@');
if (!r || config_islocal(r+1, 0))
{
char *ss=ulocallower(s);
free(s);
s=ss;
}
q=malloc(sizeof(*q)+1+strlen(s));
if (!q)
{
perror("malloc");
exit(EX_TEMPFAIL);
}
strcpy(q->addr=(char *)(q+1), p);
strcpy(q->addr=(char *)(q+1), s);
q->next=delivtolist;
delivtolist=q;
domainlower(q->addr);
r=strchr(q->addr, '@');
if (!r || config_islocal(r+1, 0))
locallower(q->addr);
free(s);
}
}
......@@ -166,10 +176,18 @@ char *sep;
if (*q == '\\')
++q;
q=udomainutf8(q);
free(p);
p=q;
r=strchr(q, '@');
if (!r || config_islocal(r+1, 0))
locallower(q);
domainlower(q);
{
q=ulocallower(q);
free(p);
p=q;
}
t=0;
orig=q;
......
......@@ -40,7 +40,8 @@ dupfilter_LDADD=libfilter/libfilter.la ../../libs/md5/libmd5.la \
../libs/libcommon.la ../libs/libcourier.la \
../../libs/liblock/liblock.la \
../../libs/threadlib/libthreadlib.a ../../libs/numlib/libnumlib.la \
`cat ../../libs/threadlib/libthread.dep` @NETLIBS@
`cat ../../libs/threadlib/libthread.dep` @NETLIBS@ -lcourier-unicode \
@LIBIDN_LIBS@
ratefilter_SOURCES=ratefilter.C
ratefilter_DEPENDENCIES=libfilter/libfilter.la ../../afx/libafx.a \
......@@ -83,6 +84,7 @@ verifyfilter_LDADD=libfilter/libfilter.la \
../../libs/soxwrap/libsoxwrap.a \
`cat ../../libs/soxwrap/soxlibs.dep` \
-lcourierauthsaslclient -lcourierauth -lcourier-unicode \
@LIBIDN_LIBS@
@NETLIBS@
verifyfilter_LDFLAGS=`@COURIERAUTHCONFIG@ --ldflags`
......
......@@ -22,6 +22,11 @@ AM_PROG_LIBTOOL
AC_PATH_PROGS(PERL, perl5 perl, perl, $LPATH)
dnl Checks for libraries.
PKG_CHECK_MODULES(LIBIDN, libidn >= 0.0.0, [libidn=yes], [libidn=no])
if test "$libidn" != "yes"
then
AC_MSG_ERROR([libidn not found])
fi
dnl Checks for header files.
......
......@@ -76,6 +76,7 @@ PerlInterpreter *my_perl;
ENTER ;
SAVETMPS ;
(void)sp;
perl_call_argv("Embed::Persistent::eval_file",
G_VOID | G_DISCARD | G_EVAL, args);
......
......@@ -166,6 +166,10 @@ static void do_verify(struct verify_info *my_info,
struct esmtp_info *info;
int smtproutes_flags=0;
char *smtproute=0;
struct esmtp_mailfrom_info mfi;
char *mail_from_cmd;
const char *errmsg;
char *s;
if (!domain)