diff --git a/NEWS b/NEWS index ab00342..ddf34a7 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,9 @@ This file lists all the major user-visible changes to nullmailer. - Fixed compile error in sendmail on GCC older than 4.9. + +- Fixed treating authentication failure as message rejection. + Thanks Fejes József ------------------------------------------------------------------------------- Changes in version 2.1 diff --git a/lib/errcodes.cc b/lib/errcodes.cc index 84b9f76..e2454e6 100644 --- a/lib/errcodes.cc +++ b/lib/errcodes.cc @@ -44,6 +44,7 @@ const char* errorstr(int code) case ERR_MSG_REFUSED: return "Server refused the message"; case ERR_MSG_PERMFAIL: return "Permanent error in sending the message"; case ERR_BIND_FAILED: return "Failed to bind source address"; + case ERR_AUTH_FAILED: return "Failed to authenticate to server"; } return (code & ERR_PERMANENT_FLAG) ? "Unspecified permanent error" diff --git a/lib/errcodes.h b/lib/errcodes.h index 94564ee..eaa1fa9 100644 --- a/lib/errcodes.h +++ b/lib/errcodes.h @@ -20,6 +20,7 @@ #define ERR_UNKNOWN 17 // Arbitrary error code #define ERR_CONFIG 18 // Error reading a config file #define ERR_BIND_FAILED 19 // Failed to bind source address +#define ERR_AUTH_FAILED 20 // Failed to authenticate to server // Permanent errors #define ERR_GHBN_FATAL 33 // gethostbyname failed with NO_RECOVERY diff --git a/protocols/smtp.cc b/protocols/smtp.cc index 706f757..02bca61 100644 --- a/protocols/smtp.cc +++ b/protocols/smtp.cc @@ -45,8 +45,8 @@ class smtp ~smtp(); int get(mystring& str); int put(mystring cmd, mystring& result); - void docmd(mystring cmd, int range, mystring& result); - void docmd(mystring cmd, int range); + void docmd(mystring cmd, int range, mystring& result, int permfail=ERR_MSG_PERMFAIL); + void docmd(mystring cmd, int range, int permfail=ERR_MSG_PERMFAIL); void dohelo(bool ehlo); bool hascap(const char* name, const char* word = NULL); void auth_login(void); @@ -91,7 +91,7 @@ int smtp::put(mystring cmd, mystring& result) return get(result); } -void smtp::docmd(mystring cmd, int range, mystring& result) +void smtp::docmd(mystring cmd, int range, mystring& result, int permfail) { int code; if(!cmd) @@ -101,7 +101,7 @@ void smtp::docmd(mystring cmd, int range, mystring& result) if(code < range || code >= (range+100)) { int e; if(code >= 500) - e = ERR_MSG_PERMFAIL; + e = permfail; else if(code >= 400) e = ERR_MSG_TEMPFAIL; else @@ -112,10 +112,10 @@ void smtp::docmd(mystring cmd, int range, mystring& result) } } -void smtp::docmd(mystring cmd, int range) +void smtp::docmd(mystring cmd, int range, int permfail) { mystring msg; - docmd(cmd, range, msg); + docmd(cmd, range, msg, permfail); } void smtp::dohelo(bool ehlo) @@ -162,7 +162,7 @@ void smtp::auth_login(void) { mystring encoded; base64_encode(user, encoded); - docmd("AUTH LOGIN " + encoded, 300); + docmd("AUTH LOGIN " + encoded, 300, ERR_AUTH_FAILED); encoded = ""; base64_encode(pass, encoded); docmd(encoded, 200); @@ -177,7 +177,7 @@ void smtp::auth_plain(void) plain += pass; mystring encoded = "AUTH PLAIN "; base64_encode(plain, encoded); - docmd(encoded, 200); + docmd(encoded, 200, ERR_AUTH_FAILED); } void smtp::send_envelope(fdibuf& msg) diff --git a/test/authtest-smtp.sh b/test/authtest-smtp.sh new file mode 100644 index 0000000..713f90e --- /dev/null +++ b/test/authtest-smtp.sh @@ -0,0 +1,11 @@ +echo 250 ME +echo 250-ME +echo 250-AUTH PLAIN +echo 250 OK +cat $1 +rm -f $1 +echo 250 OK +echo 250 OK +echo 351 OK +echo 220 OK +sleep 1 diff --git a/test/functions.in b/test/functions.in index 8df4e3d..3052ba0 100644 --- a/test/functions.in +++ b/test/functions.in @@ -48,6 +48,10 @@ stop() { wait done } +catch-port() { + local name=$1 + port=$( head -n 1 $tmpdir/service/${name}-log ) +} #not() { if "$@"; then return 1; else return 0; fi } not() { ! safe "$@"; } @@ -128,6 +132,21 @@ splitblank() { done } +make-testmail() { + testmail=$tmpdir/testmail + rm -f $testmail + cat >$testmail < +To: +Subject: Nullmailer automated test message + +Just testing, please ignore +EOF +} + export PATH=/bin:/usr/bin:/usr/local/bin rm -f $SYSCONFDIR/* echo f.q.d.n >$SYSCONFDIR/me diff --git a/test/tests/protocols b/test/tests/protocols index 8f79737..0309d12 100644 --- a/test/tests/protocols +++ b/test/tests/protocols @@ -1,69 +1,59 @@ . functions export HELOHOST=f.q.d.n -rm -f testmail -cat >testmail < -To: -Subject: Nullmailer automated test message - -Just testing, please ignore -EOF +make-testmail for p in smtp qmqp do start server "tcpserver -1 ::0 0 sh $srcdir/test/accept-$p.sh" - port=$( head -n 1 $tmpdir/service/server-log ) + catch-port server echo "Testing protocol success with $p (command-line)" - protocol $p --host=localhost --port=$port 3 $tmpdir/smtp-result +protocol smtp --host=localhost --port=$port --user=example --pass=example 3<$testmail + +echo 'Testing auth login success with smtp' +echo $'350 Go ahead\n250 AUTH' > $tmpdir/smtp-result +protocol smtp --host=localhost --port=$port --user=example --pass=example --auth-login 3<$testmail + +echo 'Testing auth temporary failure with smtp' +echo '450 No' > $tmpdir/smtp-result +error 16 protocol smtp --host=localhost --port $port --user=example --pass=example 3<$testmail + +echo 'Testing auth permanent failure with smtp' +echo '550 No' > $tmpdir/smtp-result +error 20 protocol smtp --host=localhost --port $port --user=example --pass=example 3<$testmail + +stop server