From c1a389b4d73ade7dafe1e87484b33ad87ac176a1 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Sat, 10 Aug 2024 23:47:46 +0100 Subject: [PATCH] common driver structs for auths --- src/src/auths/check_serv_cond.c | 2 +- src/src/auths/cram_md5.c | 25 +++--- src/src/auths/cram_md5.h | 2 +- src/src/auths/cyrus_sasl.c | 34 ++++---- src/src/auths/cyrus_sasl.h | 2 +- src/src/auths/dovecot.c | 28 ++++--- src/src/auths/dovecot.h | 2 +- src/src/auths/external.c | 22 +++--- src/src/auths/external.h | 2 +- src/src/auths/get_data.c | 4 +- src/src/auths/gsasl_exim.c | 55 +++++++------ src/src/auths/gsasl_exim.h | 2 +- src/src/auths/heimdal_gssapi.c | 13 +-- src/src/auths/heimdal_gssapi.h | 2 +- src/src/auths/plaintext.c | 24 +++--- src/src/auths/plaintext.h | 2 +- src/src/auths/spa.c | 33 ++++---- src/src/auths/spa.h | 2 +- src/src/auths/tls.c | 9 ++- src/src/auths/tls.h | 2 +- src/src/drtables.c | 136 ++++++++++++++++++-------------- src/src/exim.c | 6 +- src/src/globals.c | 14 ++-- src/src/readconf.c | 19 +++-- src/src/smtp_in.c | 35 ++++---- src/src/structs.h | 20 +---- src/src/transports/smtp.c | 91 +++++++++++---------- 27 files changed, 312 insertions(+), 276 deletions(-) diff --git a/src/src/auths/check_serv_cond.c b/src/src/auths/check_serv_cond.c index 16aeebdcb..e43c4c8c8 100644 --- a/src/src/auths/check_serv_cond.c +++ b/src/src/auths/check_serv_cond.c @@ -66,7 +66,7 @@ uschar * cond; HDEBUG(D_auth) { - debug_printf("%s authenticator %s:\n", ablock->name, label); + debug_printf("%s authenticator %s:\n", ablock->drinst.name, label); for (int i = 0; i < AUTH_VARS; i++) if (auth_vars[i]) debug_printf(" $auth%d = %s\n", i + 1, auth_vars[i]); for (int i = 1; i <= expand_nmax; i++) diff --git a/src/src/auths/cram_md5.c b/src/src/auths/cram_md5.c index 6d31d4b1d..a64177f2a 100644 --- a/src/src/auths/cram_md5.c +++ b/src/src/auths/cram_md5.c @@ -54,7 +54,7 @@ auth_cram_md5_options_block auth_cram_md5_option_defaults = { # ifdef MACRO_PREDEF /* Dummy values */ -void auth_cram_md5_init(auth_instance *ablock) {} +void auth_cram_md5_init(driver_instance* ablock) {} int auth_cram_md5_server(auth_instance *ablock, uschar *data) {return 0;} int auth_cram_md5_client(auth_instance *ablock, void *sx, int timeout, uschar *buffer, int buffsize) {return 0;} @@ -71,15 +71,18 @@ enable consistency checks to be done, or anything else that needs to be set up. */ void -auth_cram_md5_init(auth_instance *ablock) +auth_cram_md5_init(driver_instance * a) { -auth_cram_md5_options_block *ob = - (auth_cram_md5_options_block *)(ablock->options_block); -if (ob->server_secret != NULL) ablock->server = TRUE; -if (ob->client_secret != NULL) +auth_instance * ablock = (auth_instance *)a; +auth_cram_md5_options_block * ob = + (auth_cram_md5_options_block *)(a->options_block); + +if (ob->server_secret) + ablock->server = TRUE; +if (ob->client_secret) { ablock->client = TRUE; - if (ob->client_name == NULL) ob->client_name = primary_hostname; + if (!ob->client_name) ob->client_name = primary_hostname; } } @@ -169,8 +172,7 @@ md5_end(&base, md5secret, 16, digestptr); int auth_cram_md5_server(auth_instance * ablock, uschar * data) { -auth_cram_md5_options_block * ob = - (auth_cram_md5_options_block *)(ablock->options_block); +auth_cram_md5_options_block * ob = ablock->drinst.options_block; uschar * challenge = string_sprintf("<%d.%ld@%s>", getpid(), (long int) time(NULL), primary_hostname); uschar * clear, * secret; @@ -269,8 +271,7 @@ auth_cram_md5_client( uschar *buffer, /* for reading response */ int buffsize) /* size of buffer */ { -auth_cram_md5_options_block *ob = - (auth_cram_md5_options_block *)(ablock->options_block); +auth_cram_md5_options_block * ob = ablock->drinst.options_block; uschar *secret = expand_string(ob->client_secret); uschar *name = expand_string(ob->client_name); uschar *challenge, *p; @@ -290,7 +291,7 @@ if (!secret || !name) string_format(buffer, buffsize, "expansion of \"%s\" failed in " "%s authenticator: %s", !secret ? ob->client_secret : ob->client_name, - ablock->name, expand_string_message); + ablock->drinst.name, expand_string_message); return ERROR; } diff --git a/src/src/auths/cram_md5.h b/src/src/auths/cram_md5.h index 984bc14c7..f3a7fb944 100644 --- a/src/src/auths/cram_md5.h +++ b/src/src/auths/cram_md5.h @@ -25,7 +25,7 @@ extern auth_cram_md5_options_block auth_cram_md5_option_defaults; /* The entry points for the mechanism */ -extern void auth_cram_md5_init(auth_instance *); +extern void auth_cram_md5_init(driver_instance*); extern int auth_cram_md5_server(auth_instance *, uschar *); extern int auth_cram_md5_client(auth_instance *, void *, int, uschar *, int); diff --git a/src/src/auths/cyrus_sasl.c b/src/src/auths/cyrus_sasl.c index 8488fba19..8266e2319 100644 --- a/src/src/auths/cyrus_sasl.c +++ b/src/src/auths/cyrus_sasl.c @@ -68,7 +68,7 @@ auth_cyrus_sasl_options_block auth_cyrus_sasl_option_defaults = { #ifdef MACRO_PREDEF /* Dummy values */ -void auth_cyrus_sasl_init(auth_instance *ablock) {} +void auth_cyrus_sasl_init(driver_instance *ablock) {} int auth_cyrus_sasl_server(auth_instance *ablock, uschar *data) {return 0;} int auth_cyrus_sasl_client(auth_instance *ablock, void * sx, int timeout, uschar *buffer, int buffsize) {return 0;} @@ -106,10 +106,10 @@ return SASL_FAIL; /* Here's the real function */ void -auth_cyrus_sasl_init(auth_instance *ablock) +auth_cyrus_sasl_init(driver_instance * a) { -auth_cyrus_sasl_options_block *ob = - (auth_cyrus_sasl_options_block *)(ablock->options_block); +auth_instance * ablock = (auth_instance *)a; +auth_cyrus_sasl_options_block * ob = a->options_block; const uschar *list, *listptr, *buffer; int rc, i; unsigned int len; @@ -129,14 +129,14 @@ if (!ob->server_mech) ob->server_mech = string_copy(ablock->public_name); if (!(expanded_hostname = expand_string(ob->server_hostname))) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s authenticator: " "couldn't expand server_hostname [%s]: %s", - ablock->name, ob->server_hostname, expand_string_message); + a->name, ob->server_hostname, expand_string_message); realm_expanded = NULL; if ( ob->server_realm && !(realm_expanded = CS expand_string(ob->server_realm))) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s authenticator: " "couldn't expand server_realm [%s]: %s", - ablock->name, ob->server_realm, expand_string_message); + a->name, ob->server_realm, expand_string_message); /* we're going to initialise the library to check that there is an authenticator of type whatever mechanism we're using */ @@ -146,16 +146,16 @@ cbs[0].context = ob->server_mech; if ((rc = sasl_server_init(cbs, "exim")) != SASL_OK) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s authenticator: " - "couldn't initialise Cyrus SASL library.", ablock->name); + "couldn't initialise Cyrus SASL library.", a->name); if ((rc = sasl_server_new(CS ob->server_service, CS expanded_hostname, realm_expanded, NULL, NULL, NULL, 0, &conn)) != SASL_OK) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s authenticator: " - "couldn't initialise Cyrus SASL server connection.", ablock->name); + "couldn't initialise Cyrus SASL server connection.", a->name); if ((rc = sasl_listmech(conn, NULL, "", ":", "", CCSS &list, &len, &i)) != SASL_OK) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s authenticator: " - "couldn't get Cyrus SASL mechanism list.", ablock->name); + "couldn't get Cyrus SASL mechanism list.", a->name); i = ':'; listptr = list; @@ -181,11 +181,11 @@ while ( (buffer = string_nextinlist(&listptr, &i, NULL, 0)) if (!buffer) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s authenticator: " - "Cyrus SASL doesn't know about mechanism %s.", ablock->name, ob->server_mech); + "Cyrus SASL doesn't know about mechanism %s.", a->name, ob->server_mech); store_reset(rs_point); -HDEBUG(D_auth) debug_printf("Cyrus SASL driver %s: %s initialised\n", ablock->name, ablock->public_name); +HDEBUG(D_auth) debug_printf("Cyrus SASL driver %s: %s initialised\n", a->name, ablock->public_name); /* make sure that if we get here then we're allowed to advertise. */ ablock->server = TRUE; @@ -206,8 +206,8 @@ within a shortlived child */ int auth_cyrus_sasl_server(auth_instance * ablock, uschar * data) { -auth_cyrus_sasl_options_block * ob = - (auth_cyrus_sasl_options_block *)(ablock->options_block); +auth_cyrus_sasl_options_block * ob = ablock->drinst.options_block; +const uschar * auname = ablock->drinst.name; uschar * output, * out2, * input, * clear, * hname; uschar * debug = NULL; /* Stops compiler complaining */ sasl_callback_t cbs[] = {{SASL_CB_LIST_END, NULL, NULL}}; @@ -380,7 +380,7 @@ for (rc = SASL_CONTINUE; rc == SASL_CONTINUE; ) debug_printf("Cyrus SASL library will not tell us the username: %s\n", sasl_errstring(rc, NULL, NULL)); log_write(0, LOG_REJECT, "%s authenticator (%s): " - "Cyrus SASL username fetch problem: %s", ablock->name, ob->server_mech, + "Cyrus SASL username fetch problem: %s", auname, ob->server_mech, sasl_errstring(rc, NULL, NULL)); sasl_dispose(&conn); sasl_done(); @@ -399,7 +399,7 @@ for (rc = SASL_CONTINUE; rc == SASL_CONTINUE; ) HDEBUG(D_auth) debug_printf("Cyrus SASL permanent failure %d (%s)\n", rc, sasl_errstring(rc, NULL, NULL)); log_write(0, LOG_REJECT, "%s authenticator (%s): " - "Cyrus SASL permanent failure: %s", ablock->name, ob->server_mech, + "Cyrus SASL permanent failure: %s", auname, ob->server_mech, sasl_errstring(rc, NULL, NULL)); sasl_dispose(&conn); sasl_done(); @@ -429,7 +429,7 @@ for (rc = SASL_CONTINUE; rc == SASL_CONTINUE; ) debug_printf("Cyrus SASL library will not tell us the SSF: %s\n", sasl_errstring(rc, NULL, NULL)); log_write(0, LOG_REJECT, "%s authenticator (%s): " - "Cyrus SASL SSF value not available: %s", ablock->name, ob->server_mech, + "Cyrus SASL SSF value not available: %s", auname, ob->server_mech, sasl_errstring(rc, NULL, NULL)); sasl_dispose(&conn); sasl_done(); @@ -443,7 +443,7 @@ for (rc = SASL_CONTINUE; rc == SASL_CONTINUE; ) HDEBUG(D_auth) debug_printf("Exim does not implement SASL wrapping (needed for SSF %d).\n", negotiated_ssf); log_write(0, LOG_REJECT, "%s authenticator (%s): " - "Cyrus SASL SSF %d not supported by Exim", ablock->name, ob->server_mech, negotiated_ssf); + "Cyrus SASL SSF %d not supported by Exim", auname, ob->server_mech, negotiated_ssf); sasl_dispose(&conn); sasl_done(); return FAIL; diff --git a/src/src/auths/cyrus_sasl.h b/src/src/auths/cyrus_sasl.h index 05071b6e5..4c5bd8b25 100644 --- a/src/src/auths/cyrus_sasl.h +++ b/src/src/auths/cyrus_sasl.h @@ -29,7 +29,7 @@ extern auth_cyrus_sasl_options_block auth_cyrus_sasl_option_defaults; /* The entry points for the mechanism */ -extern void auth_cyrus_sasl_init(auth_instance *); +extern void auth_cyrus_sasl_init(driver_instance *); extern int auth_cyrus_sasl_server(auth_instance *, uschar *); extern int auth_cyrus_sasl_client(auth_instance *, void *, int, uschar *, int); extern gstring * auth_cyrus_sasl_version_report(gstring *); diff --git a/src/src/auths/dovecot.c b/src/src/auths/dovecot.c index 8b80f2c3f..fdfdbc749 100644 --- a/src/src/auths/dovecot.c +++ b/src/src/auths/dovecot.c @@ -54,8 +54,10 @@ The cost is the length of an array of pointers on the stack. /* Options specific to the authentication mechanism. */ optionlist auth_dovecot_options[] = { - { "server_socket", opt_stringptr, OPT_OFF(auth_dovecot_options_block, server_socket) }, -/*{ "server_tls", opt_bool, OPT_OFF(auth_dovecot_options_block, server_tls) },*/ + { "server_socket", opt_stringptr, + OPT_OFF(auth_dovecot_options_block, server_socket) }, +/*{ "server_tls", opt_bool, + OPT_OFF(auth_dovecot_options_block, server_tls) },*/ }; /* Size of the options list. An extern variable has to be used so that its @@ -76,7 +78,7 @@ auth_dovecot_options_block auth_dovecot_option_defaults = { #ifdef MACRO_PREDEF /* Dummy values */ -void auth_dovecot_init(auth_instance *ablock) {} +void auth_dovecot_init(driver_instance *ablock) {} int auth_dovecot_server(auth_instance *ablock, uschar *data) {return 0;} int auth_dovecot_client(auth_instance *ablock, void * sx, int timeout, uschar *buffer, int buffsize) {return 0;} @@ -100,14 +102,19 @@ enable consistency checks to be done, or anything else that needs to be set up. */ void -auth_dovecot_init(auth_instance * ablock) +auth_dovecot_init(driver_instance * a) { +auth_instance * ablock = (auth_instance *)a; auth_dovecot_options_block * ob = - (auth_dovecot_options_block *)(ablock->options_block); - -if (!ablock->public_name) ablock->public_name = ablock->name; -if (ob->server_socket) ablock->server = TRUE; -else DEBUG(D_auth) debug_printf("Dovecot auth driver: no server_socket for %s\n", ablock->public_name); + (auth_dovecot_options_block *)(a->options_block); + +if (!ablock->public_name) + ablock->public_name = a->name; +if (ob->server_socket) + ablock->server = TRUE; +else DEBUG(D_auth) + debug_printf("Dovecot auth driver: no server_socket for %s\n", + ablock->public_name); ablock->client = FALSE; } @@ -250,8 +257,7 @@ return s; int auth_dovecot_server(auth_instance * ablock, uschar * data) { -auth_dovecot_options_block *ob = - (auth_dovecot_options_block *) ablock->options_block; +auth_dovecot_options_block * ob = ablock->drinst.options_block; uschar buffer[DOVECOT_AUTH_MAXLINELEN]; uschar *args[DOVECOT_AUTH_MAXFIELDCOUNT]; uschar *auth_command; diff --git a/src/src/auths/dovecot.h b/src/src/auths/dovecot.h index 74c451930..a9cc0a2b4 100644 --- a/src/src/auths/dovecot.h +++ b/src/src/auths/dovecot.h @@ -25,7 +25,7 @@ extern auth_dovecot_options_block auth_dovecot_option_defaults; /* The entry points for the mechanism */ -extern void auth_dovecot_init(auth_instance *); +extern void auth_dovecot_init(driver_instance *); extern int auth_dovecot_server(auth_instance *, uschar *); /* End of dovecot.h */ diff --git a/src/src/auths/external.c b/src/src/auths/external.c index a8e04310f..137d1e043 100644 --- a/src/src/auths/external.c +++ b/src/src/auths/external.c @@ -44,7 +44,7 @@ auth_external_options_block auth_external_option_defaults = { #ifdef MACRO_PREDEF /* Dummy values */ -void auth_external_init(auth_instance *ablock) {} +void auth_external_init(driver_instance *ablock) {} int auth_external_server(auth_instance *ablock, uschar *data) {return 0;} int auth_external_client(auth_instance *ablock, void * sx, int timeout, uschar *buffer, int buffsize) {return 0;} @@ -63,12 +63,17 @@ enable consistency checks to be done, or anything else that needs to be set up. */ void -auth_external_init(auth_instance *ablock) +auth_external_init(driver_instance * a) { -auth_external_options_block * ob = (auth_external_options_block *)ablock->options_block; -if (!ablock->public_name) ablock->public_name = ablock->name; -if (ablock->server_condition) ablock->server = TRUE; -if (ob->client_send) ablock->client = TRUE; +auth_instance * ablock = (auth_instance *)a; +auth_external_options_block * ob = a->options_block; + +if (!ablock->public_name) + ablock->public_name = a->name; +if (ablock->server_condition) + ablock->server = TRUE; +if (ob->client_send) + ablock->client = TRUE; } @@ -82,7 +87,7 @@ if (ob->client_send) ablock->client = TRUE; int auth_external_server(auth_instance * ablock, uschar * data) { -auth_external_options_block * ob = (auth_external_options_block *)ablock->options_block; +auth_external_options_block * ob = ablock->drinst.options_block; int rc; /* If data was supplied on the AUTH command, decode it, and split it up into @@ -138,8 +143,7 @@ auth_external_client( uschar *buffer, /* buffer for reading response */ int buffsize) /* size of buffer */ { -auth_external_options_block *ob = - (auth_external_options_block *)(ablock->options_block); +auth_external_options_block * ob = ablock->drinst.options_block; const uschar * text = ob->client_send; int rc; diff --git a/src/src/auths/external.h b/src/src/auths/external.h index 0a9b0b50e..98475d670 100644 --- a/src/src/auths/external.h +++ b/src/src/auths/external.h @@ -26,7 +26,7 @@ extern auth_external_options_block auth_external_option_defaults; /* The entry points for the mechanism */ -extern void auth_external_init(auth_instance *); +extern void auth_external_init(driver_instance *); extern int auth_external_server(auth_instance *, uschar *); extern int auth_external_client(auth_instance *, void *, int, uschar *, int); diff --git a/src/src/auths/get_data.c b/src/src/auths/get_data.c index 4b79cbfa4..3a9a0a46a 100644 --- a/src/src/auths/get_data.c +++ b/src/src/auths/get_data.c @@ -166,7 +166,7 @@ if (!ss) return CANCELLED; } string_format(buffer, buffsize, "expansion of \"%s\" failed in %s " - "authenticator: %s", *inout, ablock->name, expand_string_message); + "authenticator: %s", *inout, ablock->drinst.name, expand_string_message); return ERROR; } @@ -225,7 +225,7 @@ if (flags & AUTH_ITEM_LAST) if (smtp_write_command(sx, SCMD_FLUSH, "*\r\n") >= 0) (void)smtp_read_response(sx, US buffer, buffsize, '2', timeout); string_format(buffer, buffsize, "Too few items in client_send in %s " - "authenticator", ablock->name); + "authenticator", ablock->drinst.name); return ERROR; } diff --git a/src/src/auths/gsasl_exim.c b/src/src/auths/gsasl_exim.c index 07b91e790..55ac15b4b 100644 --- a/src/src/auths/gsasl_exim.c +++ b/src/src/auths/gsasl_exim.c @@ -121,7 +121,7 @@ auth_gsasl_options_block auth_gsasl_option_defaults = { # include "../macro_predef.h" /* Dummy values */ -void auth_gsasl_init(auth_instance *ablock) {} +void auth_gsasl_init(driver_instance *ablock) {} int auth_gsasl_server(auth_instance *ablock, uschar *data) {return 0;} int auth_gsasl_client(auth_instance *ablock, void * sx, int timeout, uschar *buffer, int buffsize) {return 0;} @@ -173,12 +173,12 @@ enable consistency checks to be done, or anything else that needs to be set up. */ void -auth_gsasl_init(auth_instance *ablock) +auth_gsasl_init(driver_instance * a) { +auth_instance * ablock = (auth_instance *)a; +auth_gsasl_options_block * ob = a->options_block; static char * once = NULL; int rc; -auth_gsasl_options_block *ob = - (auth_gsasl_options_block *)(ablock->options_block); /* As per existing Cyrus glue, use the authenticator's public name as the default for the mechanism name; we don't handle multiple mechanisms @@ -195,7 +195,7 @@ if (!gsasl_ctx) if ((rc = gsasl_init(&gsasl_ctx)) != GSASL_OK) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s authenticator: " "couldn't initialise GNU SASL library: %s (%s)", - ablock->name, gsasl_strerror_name(rc), gsasl_strerror(rc)); + a->name, gsasl_strerror_name(rc), gsasl_strerror(rc)); gsasl_callback_set(gsasl_ctx, main_callback); } @@ -207,7 +207,7 @@ HDEBUG(D_auth) if (!once) if ((rc = gsasl_server_mechlist(gsasl_ctx, &once)) != GSASL_OK) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s authenticator: " "failed to retrieve list of mechanisms: %s (%s)", - ablock->name, gsasl_strerror_name(rc), gsasl_strerror(rc)); + a->name, gsasl_strerror_name(rc), gsasl_strerror(rc)); debug_printf("GNU SASL supports: %s\n", once); } @@ -215,7 +215,7 @@ HDEBUG(D_auth) if (!once) if (!gsasl_client_support_p(gsasl_ctx, CCS ob->server_mech)) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s authenticator: " "GNU SASL does not support mechanism \"%s\"", - ablock->name, ob->server_mech); + a->name, ob->server_mech); if (ablock->server_condition) ablock->server = TRUE; @@ -235,7 +235,7 @@ else if( ob->server_mech ablock->server = FALSE; HDEBUG(D_auth) debug_printf("%s authenticator: " "Need server_condition for %s mechanism\n", - ablock->name, ob->server_mech); + a->name, ob->server_mech); } /* This does *not* scale to new SASL mechanisms. Need a better way to ask @@ -247,7 +247,7 @@ if ( !ob->server_realm ablock->server = FALSE; HDEBUG(D_auth) debug_printf("%s authenticator: " "Need server_realm for %s mechanism\n", - ablock->name, ob->server_mech); + a->name, ob->server_mech); } ablock->client = ob->client_username && ob->client_password; @@ -309,7 +309,7 @@ else if (cb_state->currently == CURRENTLY_SERVER) rc = server_callback(ctx, sctx, prop, cb_state->ablock); else log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s authenticator: " - "unhandled callback state, bug in Exim", cb_state->ablock->name); + "unhandled callback state, bug in Exim", cb_state->ablock->drinst.name); /* NOTREACHED */ callback_loop = 0; @@ -384,17 +384,17 @@ gsasl_property_set(sctx, propcode, CCS val); int auth_gsasl_server(auth_instance * ablock, uschar * initial_data) { +auth_gsasl_options_block * ob = ablock->drinst.options_block; +const uschar * auname = ablock->drinst.name; uschar * tmps; char * to_send, * received; Gsasl_session * sctx = NULL; -auth_gsasl_options_block * ob = - (auth_gsasl_options_block *)(ablock->options_block); struct callback_exim_state cb_state; int rc, auth_result, exim_error, exim_error_override; HDEBUG(D_auth) debug_printf("GNU SASL: initialising session for %s, mechanism %s\n", - ablock->name, ob->server_mech); + auname, ob->server_mech); #ifndef DISABLE_TLS if (tls_in.channelbinding && ob->server_channelbinding) @@ -473,7 +473,7 @@ if (tls_in.channelbinding) if (ob->server_channelbinding) { HDEBUG(D_auth) debug_printf("Auth %s: Enabling channel-binding\n", - ablock->name); + auname); # ifndef CHANNELBIND_HACK preload_prop(sctx, # ifdef EXIM_GSASL_HAVE_EXPORTER @@ -486,12 +486,12 @@ if (tls_in.channelbinding) else HDEBUG(D_auth) debug_printf("Auth %s: Not enabling channel-binding (data available)\n", - ablock->name); + auname); } else HDEBUG(D_auth) debug_printf("Auth %s: no channel-binding data available\n", - ablock->name); + auname); #endif checked_server_condition = FALSE; @@ -524,7 +524,7 @@ do { gsasl_strerror_name(rc), gsasl_strerror(rc)); log_write(0, LOG_REJECT, "%s authenticator (%s):\n " "GNU SASL permanent failure: %s (%s)", - ablock->name, ob->server_mech, + auname, ob->server_mech, gsasl_strerror_name(rc), gsasl_strerror(rc)); if (rc == GSASL_BASE64_ERROR) exim_error_override = BAD64; @@ -607,7 +607,7 @@ switch (exim_rc) case FAIL: return GSASL_AUTHENTICATION_ERROR; default: log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s authenticator: " "Unhandled return from checking %s: %d", - ablock->name, label, exim_rc); + ablock->drinst.name, label, exim_rc); } /* NOTREACHED */ @@ -671,14 +671,13 @@ static int server_callback(Gsasl *ctx, Gsasl_session *sctx, Gsasl_property prop, auth_instance *ablock) { +auth_gsasl_options_block * ob = ablock->drinst.options_block; char * tmps; uschar * s; int cbrc = GSASL_NO_CALLBACK; -auth_gsasl_options_block * ob = - (auth_gsasl_options_block *)(ablock->options_block); HDEBUG(D_auth) debug_printf("GNU SASL callback %s for %s/%s as server\n", - gsasl_prop_code_to_name(prop), ablock->name, ablock->public_name); + gsasl_prop_code_to_name(prop), ablock->drinst.name, ablock->public_name); for (int i = 0; i < AUTH_VARS; i++) auth_vars[i] = NULL; expand_nmax = 0; @@ -846,8 +845,8 @@ auth_gsasl_client( uschar * buffer, /* buffer for reading response */ int buffsize) /* size of buffer */ { -auth_gsasl_options_block * ob = - (auth_gsasl_options_block *)(ablock->options_block); +auth_gsasl_options_block * ob = ablock->drinst.options_block; +const uschar * auname = ablock->drinst.name; Gsasl_session * sctx = NULL; struct callback_exim_state cb_state; uschar * s; @@ -856,7 +855,7 @@ int rc, yield = FAIL; HDEBUG(D_auth) debug_printf("GNU SASL: initialising session for %s, mechanism %s\n", - ablock->name, ob->server_mech); + auname, ob->server_mech); *buffer = 0; @@ -910,7 +909,7 @@ if (tls_out.channelbinding) if (ob->client_channelbinding) { HDEBUG(D_auth) debug_printf("Auth %s: Enabling channel-binding\n", - ablock->name); + auname); # ifndef CHANNELBIND_HACK preload_prop(sctx, # ifdef EXIM_GSASL_HAVE_EXPORTER @@ -923,7 +922,7 @@ if (tls_out.channelbinding) else HDEBUG(D_auth) debug_printf("Auth %s: Not enabling channel-binding (data available)\n", - ablock->name); + auname); #endif /* Run the SASL conversation with the server */ @@ -999,7 +998,7 @@ static int client_callback(Gsasl *ctx, Gsasl_session *sctx, Gsasl_property prop, auth_instance *ablock) { HDEBUG(D_auth) debug_printf("GNU SASL callback %s for %s/%s as client\n", - gsasl_prop_code_to_name(prop), ablock->name, ablock->public_name); + gsasl_prop_code_to_name(prop), ablock->drinst.name, ablock->public_name); switch (prop) { #ifdef EXIM_GSASL_HAVE_EXPORTER @@ -1019,7 +1018,7 @@ switch (prop) case GSASL_SCRAM_SALTED_PASSWORD: { uschar * client_spassword = - ((auth_gsasl_options_block *) ablock->options_block)->client_spassword; + ((auth_gsasl_options_block *) ablock->drinst.options_block)->client_spassword; uschar dummy[4]; HDEBUG(D_auth) if (!client_spassword) debug_printf(" client_spassword option unset\n"); diff --git a/src/src/auths/gsasl_exim.h b/src/src/auths/gsasl_exim.h index a56535710..180d4c848 100644 --- a/src/src/auths/gsasl_exim.h +++ b/src/src/auths/gsasl_exim.h @@ -44,7 +44,7 @@ extern auth_gsasl_options_block auth_gsasl_option_defaults; /* The entry points for the mechanism */ -extern void auth_gsasl_init(auth_instance *); +extern void auth_gsasl_init(driver_instance *); extern int auth_gsasl_server(auth_instance *, uschar *); extern int auth_gsasl_client(auth_instance *, void *, int, uschar *, int); diff --git a/src/src/auths/heimdal_gssapi.c b/src/src/auths/heimdal_gssapi.c index 686b2d98d..a5eef8d95 100644 --- a/src/src/auths/heimdal_gssapi.c +++ b/src/src/auths/heimdal_gssapi.c @@ -82,7 +82,7 @@ auth_heimdal_gssapi_options_block auth_heimdal_gssapi_option_defaults = { #ifdef MACRO_PREDEF /* Dummy values */ -void auth_heimdal_gssapi_init(auth_instance *ablock) {} +void auth_heimdal_gssapi_init(driver_instance *ablock) {} int auth_heimdal_gssapi_server(auth_instance *ablock, uschar *data) {return 0;} int auth_heimdal_gssapi_client(auth_instance *ablock, void * sx, int timeout, uschar *buffer, int buffsize) {return 0;} @@ -117,8 +117,11 @@ in the init, we mostly just use raw krb5 methods so that we can report the keytab contents, for -D+auth debugging. */ void -auth_heimdal_gssapi_init(auth_instance *ablock) +auth_heimdal_gssapi_init(driver_instance * a) { +auth_instance * ablock = (auth_instance *)a; +auth_heimdal_gssapi_options_block * ob = + (auth_heimdal_gssapi_options_block *)(a->options_block); krb5_context context; krb5_keytab keytab; krb5_kt_cursor cursor; @@ -126,8 +129,6 @@ krb5_keytab_entry entry; krb5_error_code krc; char *principal, *enctype_s; const char *k_keytab_typed_name = NULL; -auth_heimdal_gssapi_options_block *ob = - (auth_heimdal_gssapi_options_block *)(ablock->options_block); ablock->server = FALSE; ablock->client = FALSE; @@ -226,6 +227,8 @@ gss_buffer_desc / *gss_buffer_t: hold/point-to size_t .length & void *value int auth_heimdal_gssapi_server(auth_instance *ablock, uschar *initial_data) { +auth_heimdal_gssapi_options_block * ob = + (auth_heimdal_gssapi_options_block *)(ablock->drinfo.options_block); gss_name_t gclient = GSS_C_NO_NAME; gss_name_t gserver = GSS_C_NO_NAME; gss_cred_id_t gcred = GSS_C_NO_CREDENTIAL; @@ -238,8 +241,6 @@ gss_OID mech_type; OM_uint32 maj_stat, min_stat; int step, error_out; uschar *tmp1, *tmp2, *from_client; -auth_heimdal_gssapi_options_block *ob = - (auth_heimdal_gssapi_options_block *)(ablock->options_block); BOOL handled_empty_ir; rmark store_reset_point; uschar *keytab; diff --git a/src/src/auths/heimdal_gssapi.h b/src/src/auths/heimdal_gssapi.h index 6c9b24298..c438aae91 100644 --- a/src/src/auths/heimdal_gssapi.h +++ b/src/src/auths/heimdal_gssapi.h @@ -32,7 +32,7 @@ extern auth_heimdal_gssapi_options_block auth_heimdal_gssapi_option_defaults; /* The entry points for the mechanism */ -extern void auth_heimdal_gssapi_init(auth_instance *); +extern void auth_heimdal_gssapi_init(driver_instance *); extern int auth_heimdal_gssapi_server(auth_instance *, uschar *); extern int auth_heimdal_gssapi_client(auth_instance *, void *, int, uschar *, int); extern void auth_heimdal_gssapi_version_report(BOOL); diff --git a/src/src/auths/plaintext.c b/src/src/auths/plaintext.c index 7f59e4c7d..26ac4aeff 100644 --- a/src/src/auths/plaintext.c +++ b/src/src/auths/plaintext.c @@ -42,7 +42,7 @@ auth_plaintext_options_block auth_plaintext_option_defaults = { #ifdef MACRO_PREDEF /* Dummy values */ -void auth_plaintext_init(auth_instance *ablock) {} +void auth_plaintext_init(driver_instance *ablock) {} int auth_plaintext_server(auth_instance *ablock, uschar *data) {return 0;} int auth_plaintext_client(auth_instance *ablock, void * sx, int timeout, uschar *buffer, int buffsize) {return 0;} @@ -60,13 +60,17 @@ enable consistency checks to be done, or anything else that needs to be set up. */ void -auth_plaintext_init(auth_instance *ablock) +auth_plaintext_init(driver_instance * a) { -auth_plaintext_options_block *ob = - (auth_plaintext_options_block *)(ablock->options_block); -if (!ablock->public_name) ablock->public_name = ablock->name; -if (ablock->server_condition) ablock->server = TRUE; -if (ob->client_send) ablock->client = TRUE; +auth_instance * ablock = (auth_instance *)a; +auth_plaintext_options_block * ob = a->options_block; + +if (!ablock->public_name) + ablock->public_name = ablock->drinst.name; +if (ablock->server_condition) + ablock->server = TRUE; +if (ob->client_send) + ablock->client = TRUE; } @@ -80,8 +84,7 @@ if (ob->client_send) ablock->client = TRUE; int auth_plaintext_server(auth_instance * ablock, uschar * data) { -auth_plaintext_options_block * ob = - (auth_plaintext_options_block *)(ablock->options_block); +auth_plaintext_options_block * ob = ablock->drinst.options_block; const uschar * prompts = ob->server_prompts; uschar * s; int number = 1; @@ -143,8 +146,7 @@ auth_plaintext_client( uschar *buffer, /* buffer for reading response */ int buffsize) /* size of buffer */ { -auth_plaintext_options_block *ob = - (auth_plaintext_options_block *)(ablock->options_block); +auth_plaintext_options_block * ob = ablock->drinst.options_block; const uschar * text = ob->client_send; const uschar * s; int sep = 0; diff --git a/src/src/auths/plaintext.h b/src/src/auths/plaintext.h index fdf0feb93..ab820ba51 100644 --- a/src/src/auths/plaintext.h +++ b/src/src/auths/plaintext.h @@ -25,7 +25,7 @@ extern auth_plaintext_options_block auth_plaintext_option_defaults; /* The entry points for the mechanism */ -extern void auth_plaintext_init(auth_instance *); +extern void auth_plaintext_init(driver_instance *); extern int auth_plaintext_server(auth_instance *, uschar *); extern int auth_plaintext_client(auth_instance *, void *, int, uschar *, int); diff --git a/src/src/auths/spa.c b/src/src/auths/spa.c index e13798f0e..09d4e43a6 100644 --- a/src/src/auths/spa.c +++ b/src/src/auths/spa.c @@ -78,7 +78,7 @@ auth_spa_options_block auth_spa_option_defaults = { #ifdef MACRO_PREDEF /* Dummy values */ -void auth_spa_init(auth_instance *ablock) {} +void auth_spa_init(driver_instance *ablock) {} int auth_spa_server(auth_instance *ablock, uschar *data) {return 0;} int auth_spa_client(auth_instance *ablock, void * sx, int timeout, uschar *buffer, int buffsize) {return 0;} @@ -97,21 +97,22 @@ enable consistency checks to be done, or anything else that needs to be set up. */ void -auth_spa_init(auth_instance *ablock) +auth_spa_init(driver_instance * a) { -auth_spa_options_block *ob = - (auth_spa_options_block *)(ablock->options_block); +auth_instance * ablock = (auth_instance *)a; +auth_spa_options_block * ob = a->options_block; /* The public name defaults to the authenticator name */ -if (ablock->public_name == NULL) ablock->public_name = ablock->name; +if (!ablock->public_name) + ablock->public_name = ablock->drinst.name; /* Both username and password must be set for a client */ if ((ob->spa_username == NULL) != (ob->spa_password == NULL)) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s authenticator:\n " "one of client_username and client_password cannot be set without " - "the other", ablock->name); + "the other", ablock->drinst.name); ablock->client = ob->spa_username != NULL; /* For a server we have just one option */ @@ -135,7 +136,7 @@ ablock->server = ob->spa_serverpassword != NULL; int auth_spa_server(auth_instance *ablock, uschar *data) { -auth_spa_options_block *ob = (auth_spa_options_block *)(ablock->options_block); +auth_spa_options_block * ob = ablock->drinst.options_block; uint8x lmRespData[24]; uint8x ntRespData[24]; SPAAuthRequest request; @@ -281,8 +282,8 @@ auth_spa_client( uschar *buffer, /* buffer for reading response */ int buffsize) /* size of buffer */ { -auth_spa_options_block *ob = - (auth_spa_options_block *)(ablock->options_block); +auth_spa_options_block * ob = ablock->drinst.options_block; +const uschar * auname = ablock->drinst.name; SPAAuthRequest request; SPAAuthChallenge challenge; SPAAuthResponse response; @@ -297,7 +298,7 @@ if (!(username = expand_string(ob->spa_username))) { if (f.expand_string_forcedfail) return CANCELLED; string_format(buffer, buffsize, "expansion of \"%s\" failed in %s " - "authenticator: %s", ob->spa_username, ablock->name, + "authenticator: %s", ob->spa_username, auname, expand_string_message); return ERROR; } @@ -306,7 +307,7 @@ if (!(password = expand_string(ob->spa_password))) { if (f.expand_string_forcedfail) return CANCELLED; string_format(buffer, buffsize, "expansion of \"%s\" failed in %s " - "authenticator: %s", ob->spa_password, ablock->name, + "authenticator: %s", ob->spa_password, auname, expand_string_message); return ERROR; } @@ -316,7 +317,7 @@ if (ob->spa_domain) { if (f.expand_string_forcedfail) return CANCELLED; string_format(buffer, buffsize, "expansion of \"%s\" failed in %s " - "authenticator: %s", ob->spa_domain, ablock->name, + "authenticator: %s", ob->spa_domain, auname, expand_string_message); return ERROR; } @@ -330,12 +331,12 @@ if (smtp_write_command(sx, SCMD_FLUSH, "AUTH %s\r\n", ablock->public_name) < 0) if (!smtp_read_response(sx, US buffer, buffsize, '3', timeout)) return FAIL; -DSPA("\n\n%s authenticator: using domain %s\n\n", ablock->name, domain); +DSPA("\n\n%s authenticator: using domain %s\n\n", auname, domain); spa_build_auth_request(&request, username, domain); spa_bits_to_base64(US msgbuf, US &request, spa_request_length(&request)); -DSPA("\n\n%s authenticator: sending request (%s)\n\n", ablock->name, msgbuf); +DSPA("\n\n%s authenticator: sending request (%s)\n\n", auname, msgbuf); /* send the encrypted password */ if (smtp_write_command(sx, SCMD_FLUSH, "%s\r\n", msgbuf) < 0) @@ -346,12 +347,12 @@ if (!smtp_read_response(sx, US buffer, buffsize, '3', timeout)) return FAIL; /* convert the challenge into the challenge struct */ -DSPA("\n\n%s authenticator: challenge (%s)\n\n", ablock->name, buffer + 4); +DSPA("\n\n%s authenticator: challenge (%s)\n\n", auname, buffer + 4); spa_base64_to_bits(CS (&challenge), sizeof(challenge), CCS (buffer + 4)); spa_build_auth_response(&challenge, &response, username, password); spa_bits_to_base64(US msgbuf, US &response, spa_request_length(&response)); -DSPA("\n\n%s authenticator: challenge response (%s)\n\n", ablock->name, msgbuf); +DSPA("\n\n%s authenticator: challenge response (%s)\n\n", auname, msgbuf); /* send the challenge response */ if (smtp_write_command(sx, SCMD_FLUSH, "%s\r\n", msgbuf) < 0) diff --git a/src/src/auths/spa.h b/src/src/auths/spa.h index 625a252d6..916a57f81 100644 --- a/src/src/auths/spa.h +++ b/src/src/auths/spa.h @@ -32,7 +32,7 @@ extern auth_spa_options_block auth_spa_option_defaults; /* The entry points for the mechanism */ -extern void auth_spa_init(auth_instance *); +extern void auth_spa_init(driver_instance *); extern int auth_spa_server(auth_instance *, uschar *); extern int auth_spa_client(auth_instance *, void *, int, uschar *, int); diff --git a/src/src/auths/tls.c b/src/src/auths/tls.c index 85b9a6722..0bcb675f7 100644 --- a/src/src/auths/tls.c +++ b/src/src/auths/tls.c @@ -47,7 +47,7 @@ auth_tls_options_block auth_tls_option_defaults = { #ifdef MACRO_PREDEF /* Dummy values */ -void auth_tls_init(auth_instance *ablock) {} +void auth_tls_init(driver_instance *ablock) {} int auth_tls_server(auth_instance *ablock, uschar *data) {return 0;} int auth_tls_client(auth_instance *ablock, void * sx, int timeout, uschar *buffer, int buffsize) {return 0;} @@ -66,9 +66,10 @@ enable consistency checks to be done, or anything else that needs to be set up. */ void -auth_tls_init(auth_instance *ablock) +auth_tls_init(driver_instance * a) { -ablock->public_name = ablock->name; /* needed for core code */ +auth_instance * ablock = (auth_instance *)a; +ablock->public_name = a->name; /* needed for core code */ } @@ -82,7 +83,7 @@ ablock->public_name = ablock->name; /* needed for core code */ int auth_tls_server(auth_instance *ablock, uschar *data) { -auth_tls_options_block * ob = (auth_tls_options_block *)ablock->options_block; +auth_tls_options_block * ob = ablock->drinst.options_block; if (ob->server_param1) auth_vars[expand_nmax++] = expand_string(ob->server_param1); diff --git a/src/src/auths/tls.h b/src/src/auths/tls.h index 472a3e260..6b9378687 100644 --- a/src/src/auths/tls.h +++ b/src/src/auths/tls.h @@ -25,7 +25,7 @@ extern auth_tls_options_block auth_tls_option_defaults; /* The entry points for the mechanism */ -extern void auth_tls_init(auth_instance *); +extern void auth_tls_init(driver_instance *); extern int auth_tls_server(auth_instance *, uschar *); /* End of tls.h */ diff --git a/src/src/drtables.c b/src/src/drtables.c index 9872bc765..fff3af82f 100644 --- a/src/src/drtables.c +++ b/src/src/drtables.c @@ -67,12 +67,14 @@ auth_info auths_available[] = { #ifdef AUTH_CRAM_MD5 { - .driver_name = US"cram_md5", /* lookup name */ - .options = auth_cram_md5_options, - .options_count = &auth_cram_md5_options_count, - .options_block = &auth_cram_md5_option_defaults, - .options_len = sizeof(auth_cram_md5_options_block), - .init = auth_cram_md5_init, + .drinfo = { + .driver_name = US"cram_md5", /* lookup name */ + .options = auth_cram_md5_options, + .options_count = &auth_cram_md5_options_count, + .options_block = &auth_cram_md5_option_defaults, + .options_len = sizeof(auth_cram_md5_options_block), + .init = auth_cram_md5_init, + }, .servercode = auth_cram_md5_server, .clientcode = auth_cram_md5_client, .version_report = NULL, @@ -82,12 +84,14 @@ auth_info auths_available[] = { #ifdef AUTH_CYRUS_SASL { - .driver_name = US"cyrus_sasl", - .options = auth_cyrus_sasl_options, - .options_count = &auth_cyrus_sasl_options_count, - .options_block = &auth_cyrus_sasl_option_defaults, - .options_len = sizeof(auth_cyrus_sasl_options_block), - .init = auth_cyrus_sasl_init, + .drinfo = { + .driver_name = US"cyrus_sasl", + .options = auth_cyrus_sasl_options, + .options_count = &auth_cyrus_sasl_options_count, + .options_block = &auth_cyrus_sasl_option_defaults, + .options_len = sizeof(auth_cyrus_sasl_options_block), + .init = auth_cyrus_sasl_init, + }, .servercode = auth_cyrus_sasl_server, .clientcode = NULL, .version_report = auth_cyrus_sasl_version_report, @@ -97,12 +101,14 @@ auth_info auths_available[] = { #ifdef AUTH_DOVECOT { - .driver_name = US"dovecot", - .options = auth_dovecot_options, - .options_count = &auth_dovecot_options_count, - .options_block = &auth_dovecot_option_defaults, - .options_len = sizeof(auth_dovecot_options_block), - .init = auth_dovecot_init, + .drinfo = { + .driver_name = US"dovecot", + .options = auth_dovecot_options, + .options_count = &auth_dovecot_options_count, + .options_block = &auth_dovecot_option_defaults, + .options_len = sizeof(auth_dovecot_options_block), + .init = auth_dovecot_init, + }, .servercode = auth_dovecot_server, .clientcode = NULL, .version_report = NULL, @@ -112,12 +118,14 @@ auth_info auths_available[] = { #ifdef AUTH_EXTERNAL { - .driver_name = US"external", - .options = auth_external_options, - .options_count = &auth_external_options_count, - .options_block = &auth_external_option_defaults, - .options_len = sizeof(auth_external_options_block), - .init = auth_external_init, + .drinfo = { + .driver_name = US"external", + .options = auth_external_options, + .options_count = &auth_external_options_count, + .options_block = &auth_external_option_defaults, + .options_len = sizeof(auth_external_options_block), + .init = auth_external_init, + }, .servercode = auth_external_server, .clientcode = auth_external_client, .version_report = NULL, @@ -127,12 +135,14 @@ auth_info auths_available[] = { #ifdef AUTH_GSASL { - .driver_name = US"gsasl", - .options = auth_gsasl_options, - .options_count = &auth_gsasl_options_count, - .options_block = &auth_gsasl_option_defaults, - .options_len = sizeof(auth_gsasl_options_block), - .init = auth_gsasl_init, + .drinfo = { + .driver_name = US"gsasl", + .options = auth_gsasl_options, + .options_count = &auth_gsasl_options_count, + .options_block = &auth_gsasl_option_defaults, + .options_len = sizeof(auth_gsasl_options_block), + .init = auth_gsasl_init, + }, .servercode = auth_gsasl_server, .clientcode = auth_gsasl_client, .version_report = auth_gsasl_version_report, @@ -142,12 +152,14 @@ auth_info auths_available[] = { #ifdef AUTH_HEIMDAL_GSSAPI { - .driver_name = US"heimdal_gssapi", - .options = auth_heimdal_gssapi_options, - .options_count = &auth_heimdal_gssapi_options_count, - .options_block = &auth_heimdal_gssapi_option_defaults, - .options_len = sizeof(auth_heimdal_gssapi_options_block), - .init = auth_heimdal_gssapi_init, + .drinfo = { + .driver_name = US"heimdal_gssapi", + .options = auth_heimdal_gssapi_options, + .options_count = &auth_heimdal_gssapi_options_count, + .options_block = &auth_heimdal_gssapi_option_defaults, + .options_len = sizeof(auth_heimdal_gssapi_options_block), + .init = auth_heimdal_gssapi_init, + }, .servercode = auth_heimdal_gssapi_server, .clientcode = NULL, .version_report = auth_heimdal_gssapi_version_report, @@ -157,12 +169,14 @@ auth_info auths_available[] = { #ifdef AUTH_PLAINTEXT { - .driver_name = US"plaintext", - .options = auth_plaintext_options, - .options_count = &auth_plaintext_options_count, - .options_block = &auth_plaintext_option_defaults, - .options_len = sizeof(auth_plaintext_options_block), - .init = auth_plaintext_init, + .drinfo = { + .driver_name = US"plaintext", + .options = auth_plaintext_options, + .options_count = &auth_plaintext_options_count, + .options_block = &auth_plaintext_option_defaults, + .options_len = sizeof(auth_plaintext_options_block), + .init = auth_plaintext_init, + }, .servercode = auth_plaintext_server, .clientcode = auth_plaintext_client, .version_report = NULL, @@ -172,12 +186,14 @@ auth_info auths_available[] = { #ifdef AUTH_SPA { - .driver_name = US"spa", - .options = auth_spa_options, - .options_count = &auth_spa_options_count, - .options_block = &auth_spa_option_defaults, - .options_len = sizeof(auth_spa_options_block), - .init = auth_spa_init, + .drinfo = { + .driver_name = US"spa", + .options = auth_spa_options, + .options_count = &auth_spa_options_count, + .options_block = &auth_spa_option_defaults, + .options_len = sizeof(auth_spa_options_block), + .init = auth_spa_init, + }, .servercode = auth_spa_server, .clientcode = auth_spa_client, .version_report = NULL, @@ -187,12 +203,14 @@ auth_info auths_available[] = { #ifdef AUTH_TLS { - .driver_name = US"tls", - .options = auth_tls_options, - .options_count = &auth_tls_options_count, - .options_block = &auth_tls_option_defaults, - .options_len = sizeof(auth_tls_options_block), - .init = auth_tls_init, + .drinfo = { + .driver_name = US"tls", + .options = auth_tls_options, + .options_count = &auth_tls_options_count, + .options_block = &auth_tls_option_defaults, + .options_len = sizeof(auth_tls_options_block), + .init = auth_tls_init, + }, .servercode = auth_tls_server, .clientcode = NULL, .version_report = NULL, @@ -200,7 +218,7 @@ auth_info auths_available[] = { }, #endif - { .driver_name = US"" } /* end marker */ + { .drinfo = { .driver_name = US"" }} /* end marker */ }; @@ -372,7 +390,7 @@ router_info routers_available[] = { .ri_flags = ri_notransport }, #endif - { US"" } + { .drinfo = { .driver_name = US"" }} }; @@ -474,7 +492,7 @@ transport_info transports_available[] = { .local = FALSE }, #endif - { US"" } + { .drinfo = { .driver_name = US"" }} }; #ifndef MACRO_PREDEF @@ -483,8 +501,8 @@ gstring * auth_show_supported(gstring * g) { g = string_cat(g, US"Authenticators:"); -for (auth_info * ai = auths_available; ai->driver_name[0]; ai++) - g = string_fmt_append(g, " %s", ai->driver_name); +for (auth_info * ai = auths_available; ai->drinfo.driver_name[0]; ai++) + g = string_fmt_append(g, " %s", ai->drinfo.driver_name); return string_cat(g, US"\n"); } diff --git a/src/src/exim.c b/src/src/exim.c index 8a67b2aad..97a22f9d9 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -1377,9 +1377,9 @@ g = show_db_version(g); show_string(is_stdout, g); g = NULL; -for (auth_info * authi = auths_available; *authi->driver_name != '\0'; ++authi) - if (authi->version_report) - g = (*authi->version_report)(g); +for (auth_info * ai= auths_available; *ai->drinfo.driver_name != '\0'; ai++) + if (ai->version_report) + g = (*ai->version_report)(g); /* PCRE_PRERELEASE is either defined and empty or a bare sequence of characters; unless it's an ancient version of PCRE in which case it diff --git a/src/src/globals.c b/src/src/globals.c index 18ccc95a9..9efc389a6 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -22,7 +22,7 @@ optionlist optionlist_auths[] = { { "client_set_id", opt_stringptr | opt_public, OPT_OFF(auth_instance, set_client_id) }, { "driver", opt_stringptr | opt_public, - OPT_OFF(auth_instance, driver_name) }, + OPT_OFF(auth_instance, drinst.driver_name) }, { "public_name", opt_stringptr | opt_public, OPT_OFF(auth_instance, public_name) }, { "server_advertise_condition", opt_stringptr | opt_public, @@ -632,11 +632,13 @@ uschar *authenticated_sender = NULL; auth_instance *auths = NULL; uschar *auth_advertise_hosts = US"*"; auth_instance auth_defaults = { - .next = NULL, - .name = NULL, - .info = NULL, - .options_block = NULL, - .driver_name = NULL, + .drinst = { + .next = NULL, + .name = NULL, + .info = NULL, + .options_block = NULL, + .driver_name = NULL, + }, .advertise_condition = NULL, .client_condition = NULL, .public_name = NULL, diff --git a/src/src/readconf.c b/src/src/readconf.c index b79050f0c..b7df7be25 100644 --- a/src/src/readconf.c +++ b/src/src/readconf.c @@ -432,13 +432,16 @@ options_auths(void) { uschar buf[EXIM_DRIVERNAME_MAX]; -options_from_list(optionlist_auths, optionlist_auths_size, US"AUTHENTICATORS", NULL); +options_from_list(optionlist_auths, optionlist_auths_size, + US"AUTHENTICATORS", NULL); -for (struct auth_info * ai = auths_available; ai->driver_name[0]; ai++) +for (struct auth_info * ai = auths_available; ai->drinfo.driver_name[0]; ai++) { - spf(buf, sizeof(buf), US"_DRIVER_AUTHENTICATOR_%T", ai->driver_name); + driver_info * di = &ai->drinfo; + spf(buf, sizeof(buf), US"_DRIVER_AUTHENTICATOR_%T", di->driver_name); builtin_macro_create(buf); - options_from_list(ai->options, (unsigned)*ai->options_count, US"AUTHENTICATOR", ai->driver_name); + options_from_list(di->options, (unsigned)*di->options_count, + US"AUTHENTICATOR", di->driver_name); if (ai->macros_create) (ai->macros_create)(); } @@ -4249,20 +4252,20 @@ readconf_driver_init(US"authenticator", optionlist_auths, /* generic options */ optionlist_auths_size); -for (auth_instance * au = auths; au; au = au->next) +for (auth_instance * au = auths; au; au = au->drinst.next) { if (!au->public_name) log_write(0, LOG_PANIC_DIE|LOG_CONFIG, "no public name specified for " - "the %s authenticator", au->name); + "the %s authenticator", au->drinst.name); - for (auth_instance * bu = au->next; bu; bu = bu->next) + for (auth_instance * bu = au->drinst.next; bu; bu = bu->drinst.next) if (strcmpic(au->public_name, bu->public_name) == 0) if ( au->client && bu->client || au->server && bu->server) log_write(0, LOG_PANIC_DIE|LOG_CONFIG, "two %s authenticators " "(%s and %s) have the same public name (%s)", au->client && bu->client ? US"client" : US"server", - au->name, bu->name, au->public_name); + au->drinst.name, bu->drinst.name, au->public_name); #ifndef DISABLE_PIPE_CONNECT nauths++; #endif diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index 521bc05aa..7c2b4a292 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -3408,9 +3408,9 @@ int rc; /* Set up globals for error messages */ -authenticator_name = au->name; -driver_srcfile = au->srcfile; -driver_srcline = au->srcline; +authenticator_name = au->drinst.name; +driver_srcfile = au->drinst.srcfile; +driver_srcline = au->drinst.srcline; /* Run the checking code, passing the remainder of the command line as data. Initials the $auth variables as empty. Initialize $0 empty and set @@ -3428,7 +3428,10 @@ for (int i = 0; i < AUTH_VARS; i++) auth_vars[i] = NULL; expand_nmax = 0; expand_nlength[0] = 0; /* $0 contains nothing */ -rc = (au->info->servercode)(au, smtp_cmd_data); + { + auth_info * ai = au->drinst.info; + rc = (ai->servercode)(au, smtp_cmd_data); + } if (au->set_id) set_id = expand_string(au->set_id); expand_nmax = -1; /* Reset numeric variables */ for (int i = 0; i < AUTH_VARS; i++) auth_vars[i] = NULL; /* Reset $auth */ @@ -3457,7 +3460,7 @@ switch(rc) if (!au->set_id || set_id) /* Complete success */ { if (set_id) authenticated_id = string_copy_perm(set_id, TRUE); - sender_host_authenticated = au->name; + sender_host_authenticated = au->drinst.name; sender_host_auth_pubname = au->public_name; authentication_failed = FALSE; authenticated_fail_id = NULL; /* Impossible to already be set? */ @@ -3747,8 +3750,8 @@ while (done <= 0) { cmd_list[CL_TLAU].is_mail_cmd = FALSE; - for (auth_instance * au = auths; au; au = au->next) - if (strcmpic(US"tls", au->driver_name) == 0) + for (auth_instance * au = auths; au; au = au->drinst.next) + if (strcmpic(US"tls", au->drinst.driver_name) == 0) { GET_OPTION("acl_smtp_auth"); if ( acl_smtp_auth @@ -3768,7 +3771,7 @@ while (done <= 0) #ifndef DISABLE_EVENT { uschar * save_name = sender_host_authenticated, * logmsg; - sender_host_authenticated = au->name; + sender_host_authenticated = au->drinst.name; if ((logmsg = event_raise(event_action, US"auth:fail", s, NULL))) log_write(0, LOG_MAIN, "%s", logmsg); sender_host_authenticated = save_name; @@ -3867,7 +3870,7 @@ while (done <= 0) auth_instance * au; uschar * smtp_resp, * errmsg; - for (au = auths; au; au = au->next) + for (au = auths; au; au = au->drinst.next) if (strcmpic(s, au->public_name) == 0 && au->server && (au->advertised || f.allow_auth_unadvertised)) break; @@ -3882,7 +3885,7 @@ while (done <= 0) uschar * logmsg = NULL; #ifndef DISABLE_EVENT {uschar * save_name = sender_host_authenticated; - sender_host_authenticated = au->name; + sender_host_authenticated = au->drinst.name; logmsg = event_raise(event_action, US"auth:fail", smtp_resp, NULL); sender_host_authenticated = save_name; } @@ -3891,7 +3894,7 @@ while (done <= 0) log_write(0, LOG_MAIN|LOG_REJECT, "%s", logmsg); else log_write(0, LOG_MAIN|LOG_REJECT, "%s authenticator failed for %s: %s", - au->name, host_and_ident(FALSE), errmsg); + au->drinst.name, host_and_ident(FALSE), errmsg); } } else @@ -4215,17 +4218,17 @@ while (done <= 0) ) { BOOL first = TRUE; - for (auth_instance * au = auths; au; au = au->next) + for (auth_instance * au = auths; au; au = au->drinst.next) { au->advertised = FALSE; if (au->server) { DEBUG(D_auth+D_expand) debug_printf_indent( "Evaluating advertise_condition for %s %s athenticator\n", - au->name, au->public_name); + au->drinst.name, au->public_name); if ( !au->advertise_condition - || expand_check_condition(au->advertise_condition, au->name, - US"authenticator") + || expand_check_condition(au->advertise_condition, + au->drinst.name, US"authenticator") ) { int saveptr; @@ -4599,7 +4602,7 @@ while (done <= 0) if (authenticated_by == NULL || authenticated_by->mail_auth_condition == NULL || expand_check_condition(authenticated_by->mail_auth_condition, - authenticated_by->name, US"authenticator")) + authenticated_by->drinst.name, US"authenticator")) break; /* Accept the AUTH */ ignore_msg = US"server_mail_auth_condition failed"; diff --git a/src/src/structs.h b/src/src/structs.h index 73163b6c2..ee312a44e 100644 --- a/src/src/structs.h +++ b/src/src/structs.h @@ -381,13 +381,7 @@ typedef struct router_info { mechanisms */ typedef struct auth_instance { - struct auth_instance *next; - uschar *name; /* Exim instance name */ - struct auth_info *info; /* Pointer to driver info block */ - void *options_block; /* Pointer to private options */ - uschar *driver_name; /* Must be first */ - const uschar *srcfile; - int srcline; + driver_instance drinst; uschar *advertise_condition; /* Are we going to advertise this?*/ uschar *client_condition; /* Should the client try this? */ @@ -404,17 +398,11 @@ typedef struct auth_instance { /* Structure for holding information about an authentication mechanism. The -first six fields must match driver_info above. */ +first element must be a struct driver_info, to match routers and transports. */ typedef struct auth_info { - uschar *driver_name; /* e.g. "condition" */ - optionlist *options; /* Table of private options names */ - int *options_count; /* -> Number of entries in table */ - void *options_block; /* Points to default private block */ - int options_len; /* Length of same in bytes */ - void (*init)( /* initialization function */ - struct auth_instance *); -/****/ + driver_info drinfo; + int (*servercode)( /* server function */ auth_instance *, /* the instance data */ uschar *); /* rest of AUTH command */ diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index f90ac16ba..25858d982 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -1033,14 +1033,15 @@ if (!regex_match_and_setup(regex_AUTH, sx->buffer, 0, -1)) return 0; expand_nmax = -1; /* reset */ names = string_copyn(expand_nstring[1], expand_nlength[1]); -for (au = auths, authnum = 0; au; au = au->next, authnum++) if (au->client) - { - const uschar * list = names; - uschar * s; - for (int sep = ' '; s = string_nextinlist(&list, &sep, NULL, 0); ) - if (strcmpic(au->public_name, s) == 0) - { authbits |= BIT(authnum); break; } - } +for (au = auths, authnum = 0; au; au = au->drinst.next, authnum++) + if (au->client) + { + const uschar * list = names; + uschar * s; + for (int sep = ' '; s = string_nextinlist(&list, &sep, NULL, 0); ) + if (strcmpic(au->public_name, s) == 0) + { authbits |= BIT(authnum); break; } + } DEBUG(D_transport) debug_printf("server offers %s AUTH, methods '%s', usable-bitmap 0x%04x\n", @@ -1514,16 +1515,20 @@ int rc; /* Set up globals for error messages */ -authenticator_name = au->name; -driver_srcfile = au->srcfile; -driver_srcline = au->srcline; +authenticator_name = au->drinst.name; +driver_srcfile = au->drinst.srcfile; +driver_srcline = au->drinst.srcline; -sx->outblock.authenticating = TRUE; -rc = (au->info->clientcode)(au, sx, ob->command_timeout, - sx->buffer, sizeof(sx->buffer)); -sx->outblock.authenticating = FALSE; + { + auth_info * ai = au->drinst.info; + sx->outblock.authenticating = TRUE; + rc = (ai->clientcode)(au, sx, ob->command_timeout, + sx->buffer, sizeof(sx->buffer)); + sx->outblock.authenticating = FALSE; + } driver_srcfile = authenticator_name = NULL; driver_srcline = 0; -DEBUG(D_transport) debug_printf("%s authenticator yielded %s\n", au->name, rc_names[rc]); +DEBUG(D_transport) debug_printf("%s authenticator yielded %s\n", + au->drinst.name, rc_names[rc]); /* A temporary authentication failure must hold up delivery to this host. After a permanent authentication failure, we carry on @@ -1534,7 +1539,7 @@ switch(rc) { case OK: f.smtp_authenticated = TRUE; /* stops the outer loop */ - client_authenticator = au->name; + client_authenticator = au->drinst.name; if (au->set_client_id) client_authenticated_id = expand_string(au->set_client_id); break; @@ -1554,16 +1559,16 @@ switch(rc) #ifndef DISABLE_EVENT { uschar * save_name = sender_host_authenticated; - sender_host_authenticated = au->name; - if ((logmsg = event_raise(sx->conn_args.tblock->event_action, US"auth:fail", - sx->buffer, NULL))) + sender_host_authenticated = au->drinst.name; + if ((logmsg = event_raise(sx->conn_args.tblock->event_action, + US"auth:fail", sx->buffer, NULL))) log_write(0, LOG_MAIN, "%s", logmsg); sender_host_authenticated = save_name; } #endif if (!logmsg) log_write(0, LOG_MAIN, "%s authenticator failed H=%s [%s] %s", - au->name, host->name, host->address, sx->buffer); + au->drinst.name, host->name, host->address, sx->buffer); break; } @@ -1576,7 +1581,7 @@ switch(rc) case CANCELLED: if (*sx->buffer != 0) log_write(0, LOG_MAIN, "%s authenticator cancelled " - "authentication H=%s [%s] %s", au->name, host->name, + "authentication H=%s [%s] %s", au->drinst.name, host->name, host->address, sx->buffer); break; @@ -1670,26 +1675,27 @@ if ( sx->esmtp for (bitnum = 0, au = auths; !f.smtp_authenticated && au && bitnum < 16; - bitnum++, au = au->next) if (authbits & BIT(bitnum)) - { - if ( au->client_condition - && !expand_check_condition(au->client_condition, au->name, - US"client authenticator")) + bitnum++, au = au->drinst.next) + if (authbits & BIT(bitnum)) { - DEBUG(D_transport) debug_printf("skipping %s authenticator: %s\n", - au->name, "client_condition is false"); - continue; - } + if ( au->client_condition + && !expand_check_condition(au->client_condition, au->drinst.name, + US"client authenticator")) + { + DEBUG(D_transport) debug_printf("skipping %s authenticator: %s\n", + au->drinst.name, "client_condition is false"); + continue; + } - /* Found data for a listed mechanism. Call its client entry. Set - a flag in the outblock so that data is overwritten after sending so - that reflections don't show it. */ + /* Found data for a listed mechanism. Call its client entry. Set + a flag in the outblock so that data is overwritten after sending so + that reflections don't show it. */ - fail_reason = US"authentication attempt(s) failed"; + fail_reason = US"authentication attempt(s) failed"; - if ((rc = try_authenticator(sx, au)) != OK) - return rc; - } + if ((rc = try_authenticator(sx, au)) != OK) + return rc; + } } else #endif @@ -1700,17 +1706,18 @@ if ( sx->esmtp If one is found, attempt to authenticate by calling its client function. */ - for (auth_instance * au = auths; !f.smtp_authenticated && au; au = au->next) + for (auth_instance * au = auths; !f.smtp_authenticated && au; + au = au->drinst.next) { - uschar *p = names; + uschar * p = names; if ( !au->client || ( au->client_condition - && !expand_check_condition(au->client_condition, au->name, + && !expand_check_condition(au->client_condition, au->drinst.name, US"client authenticator"))) { DEBUG(D_transport) debug_printf("skipping %s authenticator: %s\n", - au->name, + au->drinst.name, au->client ? "client_condition is false" : "not configured as a client"); continue; -- 2.30.2