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 &<<CHAPevents>>&) 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 <<CHAPevents>> for details on events.
+.wen
.section "Testing server authentication" "SECID169"
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"
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"
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;
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;
}
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;
}
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;
}
{
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))
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,
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);
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