summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/src/deliver.c47
-rw-r--r--src/src/expand.c2
-rw-r--r--src/src/globals.c4
-rw-r--r--src/src/globals.h2
-rw-r--r--src/src/structs.h3
-rw-r--r--src/src/transports/smtp.c3
6 files changed, 54 insertions, 7 deletions
diff --git a/src/src/deliver.c b/src/src/deliver.c
index 02329d272..c01e4e61b 100644
--- a/src/src/deliver.c
+++ b/src/src/deliver.c
@@ -774,6 +774,13 @@ else
string_printing(addr->peerdn), US"\"");
#endif
+ if (smtp_authenticated)
+ {
+ s = string_append(s, &size, &ptr, 2, US" A=", client_authenticator);
+ if (client_authenticated_id)
+ s = string_append(s, &size, &ptr, 2, US":", client_authenticated_id);
+ }
+
if ((log_extra_selector & LX_smtp_confirmation) != 0 &&
addr->message != NULL)
{
@@ -2913,6 +2920,20 @@ while (!done)
break;
#endif
+ case 'C': /* client authenticator information */
+ switch (*ptr++)
+ {
+ case '1':
+ smtp_authenticated = TRUE;
+ client_authenticator = (*ptr)? string_copy(ptr) : NULL;
+ break;
+ case '2':
+ client_authenticated_id = (*ptr)? string_copy(ptr) : NULL;
+ break;
+ }
+ while (*ptr++);
+ break;
+
case 'A':
if (addr == NULL)
{
@@ -3950,10 +3971,10 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++)
memcpy(big_buffer+1, &transport_count, sizeof(transport_count));
(void)write(fd, big_buffer, sizeof(transport_count) + 1);
- /* Information about what happened to each address. Three item types are
- used: an optional 'X' item first, for TLS information, followed by 'R'
- items for any retry settings, and finally an 'A' item for the remaining
- data. */
+ /* Information about what happened to each address. Four item types are
+ used: an optional 'X' item first, for TLS information, then an optional "C"
+ item for any client-auth info followed by 'R' items for any retry settings,
+ and finally an 'A' item for the remaining data. */
for(; addr != NULL; addr = addr->next)
{
@@ -3970,8 +3991,7 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++)
if (addr->cipher != NULL)
{
ptr = big_buffer;
- *ptr++ = 'X';
- sprintf(CS ptr, "%.128s", addr->cipher);
+ sprintf(CS ptr, "X%.128s", addr->cipher);
while(*ptr++);
if (addr->peerdn == NULL) *ptr++ = 0; else
{
@@ -3982,6 +4002,21 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++)
}
#endif
+ if (client_authenticator)
+ {
+ ptr = big_buffer;
+ sprintf(CS big_buffer, "C1%.64s", client_authenticator);
+ while(*ptr++);
+ (void)write(fd, big_buffer, ptr - big_buffer);
+ }
+ if (client_authenticated_id)
+ {
+ ptr = big_buffer;
+ sprintf(CS big_buffer, "C2%.64s", client_authenticated_id);
+ while(*ptr++);
+ (void)write(fd, big_buffer, ptr - big_buffer);
+ }
+
/* Retry information: for most success cases this will be null. */
for (r = addr->retries; r != NULL; r = r->next)
diff --git a/src/src/expand.c b/src/src/expand.c
index 786d4279c..a3d56eae6 100644
--- a/src/src/expand.c
+++ b/src/src/expand.c
@@ -426,6 +426,8 @@ static var_entry var_table[] = {
{ "bounce_return_size_limit", vtype_int, &bounce_return_size_limit },
{ "caller_gid", vtype_gid, &real_gid },
{ "caller_uid", vtype_uid, &real_uid },
+ { "client_authenticator", vtype_stringptr, &client_authenticator },
+ { "client_authenticated_id", vtype_stringptr, &client_authenticated_id },
{ "compile_date", vtype_stringptr, &version_date },
{ "compile_number", vtype_stringptr, &version_cnumber },
{ "csa_status", vtype_stringptr, &csa_status },
diff --git a/src/src/globals.c b/src/src/globals.c
index 5dff0ee4b..8df1119fb 100644
--- a/src/src/globals.c
+++ b/src/src/globals.c
@@ -17,6 +17,8 @@ data blocks and hence have the opt_public flag set. */
optionlist optionlist_auths[] = {
{ "client_condition", opt_stringptr | opt_public,
(void *)(offsetof(auth_instance, client_condition)) },
+ { "client_set_id", opt_stringptr | opt_public,
+ (void *)(offsetof(auth_instance, set_client_id)) },
{ "driver", opt_stringptr | opt_public,
(void *)(offsetof(auth_instance, driver_name)) },
{ "public_name", opt_stringptr | opt_public,
@@ -426,6 +428,8 @@ int check_log_space = 0;
BOOL check_rfc2047_length = TRUE;
int check_spool_inodes = 0;
int check_spool_space = 0;
+uschar *client_authenticator = NULL;
+uschar *client_authenticated_id = NULL;
int clmacro_count = 0;
uschar *clmacros[MAX_CLMACROS];
BOOL config_changed = FALSE;
diff --git a/src/src/globals.h b/src/src/globals.h
index a27f62cfe..b3025db5a 100644
--- a/src/src/globals.h
+++ b/src/src/globals.h
@@ -238,6 +238,8 @@ extern int check_log_space; /* Minimum for message acceptance */
extern BOOL check_rfc2047_length; /* Check RFC 2047 encoded string length */
extern int check_spool_inodes; /* Minimum for message acceptance */
extern int check_spool_space; /* Minimum for message acceptance */
+extern uschar *client_authenticator; /* Authenticator name used for smtp delivery */
+extern uschar *client_authenticated_id; /* (not yet used) */
extern int clmacro_count; /* Number of command line macros */
extern uschar *clmacros[]; /* Copy of them, for re-exec */
extern int connection_max_messages;/* Max down one SMTP connection */
diff --git a/src/src/structs.h b/src/src/structs.h
index c319611df..1ad5d9b7e 100644
--- a/src/src/structs.h
+++ b/src/src/structs.h
@@ -335,7 +335,8 @@ typedef struct auth_instance {
uschar *advertise_condition; /* Are we going to advertise this?*/
uschar *client_condition; /* Should the client try this? */
uschar *public_name; /* Advertised name */
- uschar *set_id; /* String to set as authenticated id */
+ uschar *set_id; /* String to set when server as authenticated id */
+ uschar *set_client_id; /* String to set when client as client_authenticated id */
uschar *mail_auth_condition; /* Condition for AUTH on MAIL command */
uschar *server_debug_string; /* Debugging output */
uschar *server_condition; /* Authorization condition */
diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c
index dc24e6938..0ab173232 100644
--- a/src/src/transports/smtp.c
+++ b/src/src/transports/smtp.c
@@ -1349,6 +1349,9 @@ if (continue_hostname == NULL
{
case OK:
smtp_authenticated = TRUE; /* stops the outer loop */
+ client_authenticator = au->name;
+ if (au->set_client_id != NULL)
+ client_authenticated_id = expand_string(au->set_client_id);
break;
/* Failure after writing a command */