From: Jeremy Harris Date: Tue, 19 Jul 2022 22:37:27 +0000 (+0100) Subject: Event for auth fail X-Git-Tag: exim-4.97-RC0~268 X-Git-Url: https://git.exim.org/exim.git/commitdiff_plain/7a97480c2bb86d9385597680ec2d4461e1656193 Event for auth fail --- diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index c76aceb69..935a78a39 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -27647,7 +27647,16 @@ no successful authentication. Successful authentication sets up information used by the &%authresults%& expansion item. - +.new +.cindex authentication "failure event" +If an authenticator is run and does not succeed, +an event (see &<>&) of type "auth:fail" is raised. +While the event is being processed the variables +&$sender_host_authenticated$& (with the authenticator name) +and &$authenticated_fail_id$& (as set by the suthenticator &%server_set_id%& option) +will be valid. +See <> for details on events. +.wen .section "Testing server authentication" "SECID169" @@ -42701,6 +42710,7 @@ expansion must check this, as it will be called for every possible event type. The current list of events is: .itable all 0 0 4 25* left 10* center 15* center 50* left +.row auth:fail after main "per driver per authentication attempt" .row dane:fail after transport "per connection" .row msg:complete after main "per message" .row msg:defer after transport "per message per delivery try" @@ -42733,6 +42743,7 @@ should define the event action. An additional variable, &$event_data$&, is filled with information varying with the event type: .itable all 0 0 2 20* left 80* left +.row auth:fail "smtp response" .row dane:fail "failure reason" .row msg:defer "error string" .row msg:delivery "smtp confirmation message" diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff index 807d9e434..bd7f02cfa 100644 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@ -11,6 +11,8 @@ Version 4.97 1. The expansion-test faciility (exim -be) can set variables. + 2. An event on a failing SMTP AUTH, server side. + Version 4.96 ------------ diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index edb0adfaf..4a5c44714 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -3765,7 +3765,7 @@ smtp_respond(code, len, TRUE, user_msg); static int -smtp_in_auth(auth_instance *au, uschar ** s, uschar ** ss) +smtp_in_auth(auth_instance *au, uschar ** smtp_resp, uschar ** errmsg) { const uschar *set_id = NULL; int rc; @@ -3829,7 +3829,7 @@ switch(rc) received_protocol = (sender_host_address ? protocols : protocols_local) [pextend + pauthed + (tls_in.active.sock >= 0 ? pcrpted:0)]; - *s = *ss = US"235 Authentication succeeded"; + *smtp_resp = *errmsg = US"235 Authentication succeeded"; authenticated_by = au; break; } @@ -3842,34 +3842,34 @@ switch(rc) case DEFER: if (set_id) authenticated_fail_id = string_copy_perm(set_id, TRUE); - *s = string_sprintf("435 Unable to authenticate at present%s", + *smtp_resp = string_sprintf("435 Unable to authenticate at present%s", auth_defer_user_msg); - *ss = string_sprintf("435 Unable to authenticate at present%s: %s", + *errmsg = string_sprintf("435 Unable to authenticate at present%s: %s", set_id, auth_defer_msg); break; case BAD64: - *s = *ss = US"501 Invalid base64 data"; + *smtp_resp = *errmsg = US"501 Invalid base64 data"; break; case CANCELLED: - *s = *ss = US"501 Authentication cancelled"; + *smtp_resp = *errmsg = US"501 Authentication cancelled"; break; case UNEXPECTED: - *s = *ss = US"553 Initial data not expected"; + *smtp_resp = *errmsg = US"553 Initial data not expected"; break; case FAIL: if (set_id) authenticated_fail_id = string_copy_perm(set_id, TRUE); - *s = US"535 Incorrect authentication data"; - *ss = string_sprintf("535 Incorrect authentication data%s", set_id); + *smtp_resp = US"535 Incorrect authentication data"; + *errmsg = string_sprintf("535 Incorrect authentication data%s", set_id); break; default: if (set_id) authenticated_fail_id = string_copy_perm(set_id, TRUE); - *s = US"435 Internal error"; - *ss = string_sprintf("435 Internal error%s: return %d from authentication " + *smtp_resp = US"435 Internal error"; + *errmsg = string_sprintf("435 Internal error%s: return %d from authentication " "check", set_id, rc); break; } @@ -4098,7 +4098,13 @@ while (done <= 0) if (smtp_in_auth(au, &s, &ss) == OK) { DEBUG(D_auth) debug_printf("tls auth succeeded\n"); } else - { DEBUG(D_auth) debug_printf("tls auth not succeeded\n"); } + { + uschar * save_name = sender_host_authenticated; + DEBUG(D_auth) debug_printf("tls auth not succeeded\n"); + sender_host_authenticated = au->name; + (void) event_raise(event_action, US"auth:fail", s, NULL); + sender_host_authenticated = save_name; + } } break; } @@ -4188,6 +4194,8 @@ while (done <= 0) { auth_instance * au; + uschar * smtp_resp, * errmsg; + for (au = auths; au; au = au->next) if (strcmpic(s, au->public_name) == 0 && au->server && (au->advertised || f.allow_auth_unadvertised)) @@ -4195,12 +4203,19 @@ while (done <= 0) if (au) { - c = smtp_in_auth(au, &s, &ss); + int rc = smtp_in_auth(au, &smtp_resp, &errmsg); + + smtp_printf("%s\r\n", FALSE, smtp_resp); + if (rc != OK) + { + uschar * save_name = sender_host_authenticated; - smtp_printf("%s\r\n", FALSE, s); - if (c != OK) log_write(0, LOG_MAIN|LOG_REJECT, "%s authenticator failed for %s: %s", - au->name, host_and_ident(FALSE), ss); + au->name, host_and_ident(FALSE), errmsg); + sender_host_authenticated = au->name; + (void) event_raise(event_action, US"auth:fail", smtp_resp, NULL); + sender_host_authenticated = save_name; + } } else done = synprot_error(L_smtp_protocol_error, 504, NULL, @@ -4389,7 +4404,7 @@ while (done <= 0) else { - char *ss; + char * ss; int codelen = 4; smtp_message_code(&smtp_code, &codelen, &user_msg, NULL, TRUE); s = string_sprintf("%.*s%s", codelen, smtp_code, user_msg); diff --git a/test/aux-fixed/event-logger-acl b/test/aux-fixed/event-logger-acl index 15321724e..cc18c0692 100644 --- a/test/aux-fixed/event-logger-acl +++ b/test/aux-fixed/event-logger-acl @@ -75,12 +75,19 @@ ev_msg: accept condition = ${if eq {$event_name}{msg:rcpt:host:defer}} accept logwrite = UNEXPECTED $event_name +ev_auth: + accept condition = ${if eq {$event_name}{auth:fail}} + logwrite = . \ + "auth fail" \ + event_data <$event_data> \ + sender_host_authenticated <$sender_host_authenticated> \ + authenticated_fail_id <$authenticated_fail_id> + + accept logwrite = UNEXPECTED $event_name + logger: warn logwrite = event $event_name - accept condition = ${if eq {tcp} {${listextract{1}{$event_name}}}} - acl = ev_tcp - accept condition = ${if eq {smtp} {${listextract{1}{$event_name}}}} - acl = ev_smtp - accept condition = ${if eq {msg} {${listextract{1}{$event_name}}}} - acl = ev_msg - accept logwrite = UNEXPECTED $event_name + set acl_m1 = ${listextract{1}{$event_name}} + accept condition = ${if !inlist{$acl_m1}{tcp:smtp:msg:auth}} + logwrite = UNEXPECTED $event_name + accept acl = ev_$acl_m1 diff --git a/test/confs/3418 b/test/confs/3418 new file mode 100644 index 000000000..42413b4e4 --- /dev/null +++ b/test/confs/3418 @@ -0,0 +1,38 @@ +# Exim test configuration 3418 + +.include DIR/aux-var/std_conf_prefix + +primary_hostname = myhost.test.ex + +# ----- Main settings ----- + +domainlist local_domains = test.ex : *.test.ex + +auth_advertise_hosts = 10.0.0.5 +trusted_users = CALLER + +event_action = ${acl {logger}} + +# ----- ACL ----- + +begin acl + +.include DIR/aux-fixed/event-logger-acl + + + +# ----- Authentication ----- + +begin authenticators + +testname: + driver = plaintext + public_name = mylogin + server_debug_print = +++MYLOGIN \$1="$1" \$2=\"$2" \$3="$3" + server_condition = "\ + ${if match{$1}{^(\\\\S+)\\\\s+(\\\\S+)\\$}\ + {${if and {{eq{$1}{userx}}{eq{$2}{secret}}}{yes}{no}}}{no}}" + server_set_id = $auth1 + + +# End diff --git a/test/log/3418 b/test/log/3418 new file mode 100644 index 000000000..2de0ec655 --- /dev/null +++ b/test/log/3418 @@ -0,0 +1,6 @@ +1999-03-02 09:44:33 testname authenticator failed for (testing.testing) [10.0.0.5] U=CALLER: 535 Incorrect authentication data (set_id=rx secret) +1999-03-02 09:44:33 event auth:fail +1999-03-02 09:44:33 . "auth fail" event_data <535 Incorrect authentication data> sender_host_authenticated authenticated_fail_id < (set_id=rx secret)> +1999-03-02 09:44:33 testname authenticator failed for (testing.testing) [10.0.0.5] U=CALLER: 501 Invalid base64 data +1999-03-02 09:44:33 event auth:fail +1999-03-02 09:44:33 . "auth fail" event_data <501 Invalid base64 data> sender_host_authenticated authenticated_fail_id <> diff --git a/test/rejectlog/3418 b/test/rejectlog/3418 new file mode 100644 index 000000000..dca36042e --- /dev/null +++ b/test/rejectlog/3418 @@ -0,0 +1,2 @@ +1999-03-02 09:44:33 testname authenticator failed for (testing.testing) [10.0.0.5] U=CALLER: 535 Incorrect authentication data (set_id=rx secret) +1999-03-02 09:44:33 testname authenticator failed for (testing.testing) [10.0.0.5] U=CALLER: 501 Invalid base64 data diff --git a/test/scripts/3418-plaintext-event/3418 b/test/scripts/3418-plaintext-event/3418 new file mode 100644 index 000000000..2df7dd3ce --- /dev/null +++ b/test/scripts/3418-plaintext-event/3418 @@ -0,0 +1,17 @@ +# plaintext server fail event +# +# Incorrect auth +exim -odi -bs -oMa 10.0.0.5 +ehlo testing.testing +auth mylogin cnggc2VjcmV0 +quit +**** +# +# Bad base64 +exim -odi -bs -oMa 10.0.0.5 +ehlo testing.testing +auth mylogin XNlcnggc2VjcmV0 +quit +**** +# +no_msglog_check diff --git a/test/scripts/3418-plaintext-event/REQUIRES b/test/scripts/3418-plaintext-event/REQUIRES new file mode 100644 index 000000000..2c5eb3f1c --- /dev/null +++ b/test/scripts/3418-plaintext-event/REQUIRES @@ -0,0 +1,2 @@ +authenticator plaintext +support Event diff --git a/test/stdout/3418 b/test/stdout/3418 new file mode 100644 index 000000000..0ed179c33 --- /dev/null +++ b/test/stdout/3418 @@ -0,0 +1,18 @@ +220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +250-myhost.test.ex Hello CALLER at testing.testing [10.0.0.5] +250-SIZE 52428800 +250-8BITMIME +250-PIPELINING +250-AUTH MYLOGIN +250 HELP +535 Incorrect authentication data +221 myhost.test.ex closing connection +220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +250-myhost.test.ex Hello CALLER at testing.testing [10.0.0.5] +250-SIZE 52428800 +250-8BITMIME +250-PIPELINING +250-AUTH MYLOGIN +250 HELP +501 Invalid base64 data +221 myhost.test.ex closing connection