X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=src%2Fsrc%2Fauths%2Fcyrus_sasl.c;h=bab2be36c4780bea78d921ef5deeace8982bf1ad;hb=4d3d955f2791199b35704c3e9784dc99fd229696;hp=9b80f8d83938c1d85e5acb7dfe223b50c1f497d7;hpb=16880d1a95a51a8b57692b216512e8cbb7cc917d;p=exim.git diff --git a/src/src/auths/cyrus_sasl.c b/src/src/auths/cyrus_sasl.c index 9b80f8d83..bab2be36c 100644 --- a/src/src/auths/cyrus_sasl.c +++ b/src/src/auths/cyrus_sasl.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2012 */ +/* Copyright (c) University of Cambridge 1995 - 2015 */ /* See the file NOTICE for conditions of use and distribution. */ /* This code was originally contributed by Matthew Byng-Maddick */ @@ -25,7 +25,9 @@ in a dummy argument to stop even pickier compilers complaining about infinite loops. */ #ifndef AUTH_CYRUS_SASL -static void dummy(int x) { dummy(x-1); } +static void dummy(int x); +static void dummy2(int x) { dummy(x-1); } +static void dummy(int x) { dummy2(x-1); } #else @@ -95,7 +97,7 @@ auth_cyrus_sasl_init(auth_instance *ablock) { auth_cyrus_sasl_options_block *ob = (auth_cyrus_sasl_options_block *)(ablock->options_block); -uschar *list, *listptr, *buffer; +const uschar *list, *listptr, *buffer; int rc, i; unsigned int len; uschar *rs_point, *expanded_hostname; @@ -144,7 +146,7 @@ if( rc != SASL_OK ) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s authenticator: " "couldn't initialise Cyrus SASL server connection.", ablock->name); -rc=sasl_listmech(conn, NULL, "", ":", "", (const char **)(&list), &len, &i); +rc=sasl_listmech(conn, NULL, "", ":", "", (const char **)&list, &len, &i); if( rc != SASL_OK ) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s authenticator: " "couldn't get Cyrus SASL mechanism list.", ablock->name); @@ -205,7 +207,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; @@ -226,7 +228,7 @@ if((hname == NULL) || if(inlen) { - clen=auth_b64decode(input, &clear); + clen = b64decode(input, &clear); if(clen < 0) { return BAD64; @@ -256,23 +258,81 @@ if( rc != SASL_OK ) return DEFER; } -if (tls_cipher) +if (tls_in.cipher) { - rc = sasl_setprop(conn, SASL_SSF_EXTERNAL, (sasl_ssf_t *) &tls_bits); + rc = sasl_setprop(conn, SASL_SSF_EXTERNAL, (sasl_ssf_t *) &tls_in.bits); if (rc != SASL_OK) { HDEBUG(D_auth) debug_printf("Cyrus SASL EXTERNAL SSF set %d failed: %s\n", - tls_bits, sasl_errstring(rc, NULL, NULL)); + tls_in.bits, sasl_errstring(rc, NULL, NULL)); auth_defer_msg = US"couldn't set Cyrus SASL EXTERNAL SSF"; sasl_done(); return DEFER; } else - HDEBUG(D_auth) debug_printf("Cyrus SASL set EXTERNAL SSF to %d\n", tls_bits); + HDEBUG(D_auth) debug_printf("Cyrus SASL set EXTERNAL SSF to %d\n", tls_in.bits); } 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 : ""); + break; + } + HDEBUG(D_auth) debug_printf("Cyrus SASL set %s hostport to: %s\n", + label, address_port); + } + rc=SASL_CONTINUE; while(rc==SASL_CONTINUE) @@ -303,7 +363,7 @@ while(rc==SASL_CONTINUE) HDEBUG(D_auth) debug=string_copy(input); if(inlen) { - clen=auth_b64decode(input, &clear); + clen = b64decode(input, &clear); if(clen < 0) { sasl_dispose(&conn);