summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--qmail-smtpd.c31
2 files changed, 31 insertions, 2 deletions
diff --git a/Makefile b/Makefile
index a13882b..9ffde73 100644
--- a/Makefile
+++ b/Makefile
@@ -1626,7 +1626,7 @@ socket.lib dns.lib
1626 tls.o ssl_timeoutio.o ndelay.a -L/usr/local/ssl/lib -lssl -lcrypto \ 1626 tls.o ssl_timeoutio.o ndelay.a -L/usr/local/ssl/lib -lssl -lcrypto \
1627 cdb.a fd.a wait.a datetime.a getln.a open.a sig.a case.a env.a \ 1627 cdb.a fd.a wait.a datetime.a getln.a open.a sig.a case.a env.a \
1628 stralloc.a alloc.a strerr.a substdio.a error.a str.a fs.a \ 1628 stralloc.a alloc.a strerr.a substdio.a error.a str.a fs.a \
1629 `cat socket.lib` `cat dns.lib` 1629 `cat socket.lib` `cat dns.lib` -lidn2
1630 1630
1631qmail-smtpd.0: \ 1631qmail-smtpd.0: \
1632qmail-smtpd.8 1632qmail-smtpd.8
diff --git a/qmail-smtpd.c b/qmail-smtpd.c
index db0e16b..95993eb 100644
--- a/qmail-smtpd.c
+++ b/qmail-smtpd.c
@@ -77,6 +77,11 @@ stralloc proto = {0};
77int tls_before_auth = 0; 77int tls_before_auth = 0;
78#endif 78#endif
79 79
80#ifdef SMTPUTF8
81# include <idn2.h>
82int smtputf8 = 0;
83#endif
84
80int safewrite(fd,buf,len) int fd; char *buf; int len; 85int safewrite(fd,buf,len) int fd; char *buf; int len;
81{ 86{
82 int r; 87 int r;
@@ -385,6 +390,25 @@ char *arg;
385 return 1; 390 return 1;
386} 391}
387 392
393#ifdef SMTPUTF8
394static int idn_addr_convert(stralloc *addr)
395{
396 int i = byte_rchr(addr->s, addr->len, '@') + 1;
397 if (i < addr->len) {
398 char *asciihost = NULL;
399 switch (idn2_lookup_u8(addr->s + i, (uint8_t **)&asciihost, IDN2_NFC_INPUT)) {
400 case IDN2_OK: break;
401 case IDN2_MALLOC: die_nomem();
402 default: err_smf(); return 0;
403 }
404 addr->len = i;
405 if (!stralloc_cats(addr, asciihost)) die_nomem();
406 if (!stralloc_0(addr)) die_nomem();
407 }
408 return 1;
409}
410#endif
411
388static void log_deny(m,f,t) char *m,*f,*t; 412static void log_deny(m,f,t) char *m,*f,*t;
389{ 413{
390 enew(); eout(m); eout(" check failed ("); eout(f); eout(") -> ("); 414 enew(); eout(m); eout(" check failed ("); eout(f); eout(") -> (");
@@ -515,7 +539,6 @@ stralloc mailfrom = {0};
515stralloc rcptto = {0}; 539stralloc rcptto = {0};
516stralloc fuser = {0}; 540stralloc fuser = {0};
517stralloc mfparms = {0}; 541stralloc mfparms = {0};
518int smtputf8 = 0;
519int recipcount; 542int recipcount;
520 543
521int mailfrom_size(arg) char *arg; 544int mailfrom_size(arg) char *arg;
@@ -630,6 +653,9 @@ void smtp_mail(arg) char *arg;
630 flagsize = 0; 653 flagsize = 0;
631 mailfrom_parms(arg); 654 mailfrom_parms(arg);
632 if (flagsize) { err_size(); return; } 655 if (flagsize) { err_size(); return; }
656#ifdef SMTPUTF8
657 if (smtputf8) { if (!idn_addr_convert(&addr)) return; }
658#endif
633 flagbarfbmf = 0; /* bmcheck is skipped for empty envelope senders */ 659 flagbarfbmf = 0; /* bmcheck is skipped for empty envelope senders */
634 if ((bmfok) && (addr.len != 1)) flagbarfbmf = bmcheck(BMCHECK_BMF); 660 if ((bmfok) && (addr.len != 1)) flagbarfbmf = bmcheck(BMCHECK_BMF);
635 if ((!flagbarfbmf) && (bmfnrok) && (addr.len != 1) && (!relayclient)) { 661 if ((!flagbarfbmf) && (bmfnrok) && (addr.len != 1) && (!relayclient)) {
@@ -673,6 +699,9 @@ void smtp_rcpt(arg) char *arg; {
673 err_bmf(); 699 err_bmf();
674 return; 700 return;
675 } 701 }
702#ifdef SMTPUTF8
703 if (smtputf8) { if (!idn_addr_convert(&addr)) return; }
704#endif
676 if (bmtok) flagbarfbmt = bmcheck(BMCHECK_BMT); 705 if (bmtok) flagbarfbmt = bmcheck(BMCHECK_BMT);
677 if ((!flagbarfbmt) && (bmtnrok) && (!relayclient)) { 706 if ((!flagbarfbmt) && (bmtnrok) && (!relayclient)) {
678 flagbarfbmt = bmcheck(BMCHECK_BMTNR); 707 flagbarfbmt = bmcheck(BMCHECK_BMTNR);