summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/doc-txt/ChangeLog2
-rw-r--r--src/src/auths/cyrus_sasl.c60
2 files changed, 61 insertions, 1 deletions
diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index 3739345af..2db67c045 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -18,6 +18,8 @@ PP/04 First step towards DNSSEC, provide $sender_host_dnssec for
PP/05 DSCP support for outbound connections and control modifier for inbound.
+PP/06 Cyrus SASL: set local and remote IP;port properties for driver.
+
Exim version 4.80
-----------------
diff --git a/src/src/auths/cyrus_sasl.c b/src/src/auths/cyrus_sasl.c
index 9b80f8d83..7922363ec 100644
--- a/src/src/auths/cyrus_sasl.c
+++ b/src/src/auths/cyrus_sasl.c
@@ -205,7 +205,7 @@ uschar *debug = NULL; /* Stops compiler complaining */
sasl_callback_t cbs[]={{SASL_CB_LIST_END, NULL, NULL}};
sasl_conn_t *conn;
char *realm_expanded;
-int rc, firsttime=1, clen, *negotiated_ssf_ptr=NULL, negotiated_ssf;
+int rc, i, firsttime=1, clen, *negotiated_ssf_ptr=NULL, negotiated_ssf;
unsigned int inlen, outlen;
input=data;
@@ -273,6 +273,64 @@ if (tls_cipher)
else
HDEBUG(D_auth) debug_printf("Cyrus SASL: no TLS, no EXTERNAL SSF set\n");
+/* So sasl_setprop() documents non-shorted IPv6 addresses which is incredibly
+annoying; looking at cyrus-imapd-2.3.x source, the IP address is constructed
+with their iptostring() function, which just wraps
+getnameinfo(..., NI_NUMERICHOST|NI_NUMERICSERV), which is equivalent to the
+inet_ntop which we wrap in our host_ntoa() function.
+
+So the docs are too strict and we shouldn't worry about :: contractions. */
+
+/* Set properties for remote and local host-ip;port */
+for (i=0; i < 2; ++i)
+ {
+ struct sockaddr_storage ss;
+ int (*query)(int, struct sockaddr *, socklen_t *);
+ int propnum, port;
+ const uschar *label;
+ uschar *address, *address_port;
+ const char *s_err;
+ socklen_t sslen;
+
+ if (i)
+ {
+ query = &getpeername;
+ propnum = SASL_IPREMOTEPORT;
+ label = CUS"peer";
+ }
+ else
+ {
+ query = &getsockname;
+ propnum = SASL_IPLOCALPORT;
+ label = CUS"local";
+ }
+
+ sslen = sizeof(ss);
+ rc = query(fileno(smtp_in), (struct sockaddr *) &ss, &sslen);
+ if (rc < 0)
+ {
+ HDEBUG(D_auth)
+ debug_printf("Failed to get %s address information: %s\n",
+ label, strerror(errno));
+ break;
+ }
+
+ address = host_ntoa(-1, &ss, NULL, &port);
+ address_port = string_sprintf("%s;%d", address, port);
+
+ rc = sasl_setprop(conn, propnum, address_port);
+ if (rc != SASL_OK)
+ {
+ s_err = sasl_errdetail(conn);
+ HDEBUG(D_auth)
+ debug_printf("Failed to set %s SASL property: [%d] %s\n",
+ label, rc, s_err ? s_err : "<unknown reason>");
+ break;
+ }
+ HDEBUG(D_auth) debug_printf("Cyrus SASL set %s hostport to: %s\n",
+ label, address_port);
+ }
+
rc=SASL_CONTINUE;
while(rc==SASL_CONTINUE)