diff options
author | Jeremy Harris <jgh146exb@wizmail.org> | 2019-01-05 20:40:08 +0000 |
---|---|---|
committer | Jeremy Harris <jgh146exb@wizmail.org> | 2019-02-11 00:15:24 +0000 |
commit | b53c265b5c7825d7fb6bb672547c44d080459d71 (patch) | |
tree | 41f6e133c24de5e551590239f2898dba9d6b06bd /src | |
parent | 37942ad83fcb6b788cceb4abe2891c92651811a7 (diff) |
EXTERNAL authenticator
(cherry picked from commit c4a8c663b74a35b547d8320547079ca56b3b772e)
Diffstat (limited to 'src')
-rw-r--r-- | src/OS/Makefile-Base | 5 | ||||
-rwxr-xr-x | src/scripts/MakeLinks | 2 | ||||
-rw-r--r-- | src/src/EDITME | 1 | ||||
-rw-r--r-- | src/src/auths/Makefile | 3 | ||||
-rw-r--r-- | src/src/auths/external.c | 158 | ||||
-rw-r--r-- | src/src/auths/external.h | 32 | ||||
-rw-r--r-- | src/src/config.h.defaults | 1 | ||||
-rw-r--r-- | src/src/drtables.c | 18 |
8 files changed, 217 insertions, 3 deletions
diff --git a/src/OS/Makefile-Base b/src/OS/Makefile-Base index fed3134cf..79bec063b 100644 --- a/src/OS/Makefile-Base +++ b/src/OS/Makefile-Base @@ -135,7 +135,7 @@ OBJ_MACRO = macro_predef.o \ macro-smtp.o macro-accept.o macro-dnslookup.o macro-ipliteral.o macro-iplookup.o \ macro-manualroute.o macro-queryprogram.o macro-redirect.o \ macro-auth-spa.o macro-cram_md5.o macro-cyrus_sasl.o macro-dovecot.o macro-gsasl_exim.o \ - macro-heimdal_gssapi.o macro-plaintext.o macro-spa.o macro-authtls.o \ + macro-heimdal_gssapi.o macro-plaintext.o macro-spa.o macro-authtls.o macro-external.o \ macro-dkim.o macro-malware.o macro-signing.o $(OBJ_MACRO): $(MACRO_HSRC) @@ -212,6 +212,9 @@ macro-cyrus_sasl.o : auths/cyrus_sasl.c macro-dovecot.o: auths/dovecot.c @echo "$(CC) -DMACRO_PREDEF auths/dovecot.c" $(FE)$(CC) -c $(CFLAGS) -DMACRO_PREDEF $(INCLUDE) -o $@ auths/dovecot.c +macro-external.o: auths/external.c + @echo "$(CC) -DMACRO_PREDEF auths/external.c" + $(FE)$(CC) -c $(CFLAGS) -DMACRO_PREDEF $(INCLUDE) -o $@ auths/external.c macro-gsasl_exim.o : auths/gsasl_exim.c @echo "$(CC) -DMACRO_PREDEF auths/gsasl_exim.c" $(FE)$(CC) -c $(CFLAGS) -DMACRO_PREDEF $(INCLUDE) -o $@ auths/gsasl_exim.c diff --git a/src/scripts/MakeLinks b/src/scripts/MakeLinks index 08f4ff1f8..f69bde437 100755 --- a/src/scripts/MakeLinks +++ b/src/scripts/MakeLinks @@ -75,7 +75,7 @@ for f in README Makefile call_pam.c call_pwcheck.c \ gsasl_exim.h get_data.c get_no64_data.c heimdal_gssapi.c heimdal_gssapi.h \ md5.c xtextencode.c xtextdecode.c cram_md5.c cram_md5.h plaintext.c plaintext.h \ pwcheck.c pwcheck.h auth-spa.c auth-spa.h dovecot.c dovecot.h sha1.c spa.c \ - spa.h tls.c tls.h + spa.h tls.c tls.h external.c external.h do ln -s ../../src/auths/$f $f done diff --git a/src/src/EDITME b/src/src/EDITME index cbb080545..15360db9a 100644 --- a/src/src/EDITME +++ b/src/src/EDITME @@ -643,6 +643,7 @@ FIXED_NEVER_USERS=root # AUTH_CRAM_MD5=yes # AUTH_CYRUS_SASL=yes # AUTH_DOVECOT=yes +# AUTH_EXTERNAL=yes # AUTH_GSASL=yes # AUTH_GSASL_PC=libgsasl # AUTH_HEIMDAL_GSSAPI=yes diff --git a/src/src/auths/Makefile b/src/src/auths/Makefile index 62ce9d0a9..402f1417a 100644 --- a/src/src/auths/Makefile +++ b/src/src/auths/Makefile @@ -7,7 +7,7 @@ OBJ = auth-spa.o call_pam.o call_pwcheck.o \ call_radius.o check_serv_cond.o cram_md5.o cyrus_sasl.o dovecot.o \ - get_data.o get_no64_data.o gsasl_exim.o heimdal_gssapi.o \ + external.o get_data.o get_no64_data.o gsasl_exim.o heimdal_gssapi.o \ md5.o plaintext.o pwcheck.o \ spa.o tls.o xtextdecode.o xtextencode.o @@ -36,6 +36,7 @@ xtextencode.o: $(HDRS) xtextencode.c cram_md5.o: $(HDRS) cram_md5.c cram_md5.h cyrus_sasl.o: $(HDRS) cyrus_sasl.c cyrus_sasl.h dovecot.o: $(HDRS) dovecot.c dovecot.h +external.o: $(HDRS) external.c external.h gsasl_exim.o: $(HDRS) gsasl_exim.c gsasl_exim.h heimdal_gssapi.o: $(HDRS) heimdal_gssapi.c heimdal_gssapi.h plaintext.o: $(HDRS) plaintext.c plaintext.h diff --git a/src/src/auths/external.c b/src/src/auths/external.c new file mode 100644 index 000000000..10e1366a8 --- /dev/null +++ b/src/src/auths/external.c @@ -0,0 +1,158 @@ +/************************************************* +* Exim - an Internet mail transport agent * +*************************************************/ + +/* Copyright (c) Jeremy Harris 2019 */ +/* See the file NOTICE for conditions of use and distribution. */ + +/* This file provides an Exim authenticator driver for +a server to verify a client SSL certificate, using the EXTERNAL +method defined in RFC 4422 Appendix A. +*/ + + +#include "../exim.h" +#include "external.h" + +/* Options specific to the external authentication mechanism. */ + +optionlist auth_external_options[] = { + { "client_send", opt_stringptr, + (void *)(offsetof(auth_external_options_block, client_send)) }, + { "server_param2", opt_stringptr, + (void *)(offsetof(auth_external_options_block, server_param2)) }, + { "server_param3", opt_stringptr, + (void *)(offsetof(auth_external_options_block, server_param3)) }, +}; + +/* Size of the options list. An extern variable has to be used so that its +address can appear in the tables drtables.c. */ + +int auth_external_options_count = nelem(auth_external_options); + +/* Default private options block for the authentication method. */ + +auth_external_options_block auth_external_option_defaults = { + .server_param2 = NULL, + .server_param3 = NULL, + + .client_send = NULL, +}; + + +#ifdef MACRO_PREDEF + +/* Dummy values */ +void auth_external_init(auth_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;} + +#else /*!MACRO_PREDEF*/ + + + + +/************************************************* +* Initialization entry point * +*************************************************/ + +/* Called for each instance, after its options have been read, to +enable consistency checks to be done, or anything else that needs +to be set up. */ + +void +auth_external_init(auth_instance *ablock) +{ +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; +} + + + +/************************************************* +* Server entry point * +*************************************************/ + +/* For interface, see auths/README */ + +int +auth_external_server(auth_instance * ablock, uschar * data) +{ +auth_external_options_block * ob = (auth_external_options_block *)ablock->options_block; +int rc; + +/* If data was supplied on the AUTH command, decode it, and split it up into +multiple items at binary zeros. The strings are put into $auth1, $auth2, etc, +up to a maximum. To retain backwards compatibility, they are also put int $1, +$2, etc. If the data consists of the string "=" it indicates a single, empty +string. */ + +if (*data) + if ((rc = auth_read_input(data)) != OK) + return rc; + +/* Now go through the list of prompt strings. Skip over any whose data has +already been provided as part of the AUTH command. For the rest, send them +out as prompts, and get a data item back. If the data item is "*", abandon the +authentication attempt. Otherwise, split it into items as above. */ + +if (expand_nmax == 0) /* skip if rxd data */ + if ((rc = auth_prompt(CUS"")) != OK) + return rc; + +if (ob->server_param2) + { + uschar * s = expand_string(ob->server_param2); + auth_vars[expand_nmax] = s; + expand_nstring[++expand_nmax] = s; + expand_nlength[expand_nmax] = Ustrlen(s); + if (ob->server_param3) + { + s = expand_string(ob->server_param3); + auth_vars[expand_nmax] = s; + expand_nstring[++expand_nmax] = s; + expand_nlength[expand_nmax] = Ustrlen(s); + } + } + +return auth_check_serv_cond(ablock); +} + + + +/************************************************* +* Client entry point * +*************************************************/ + +/* For interface, see auths/README */ + +int +auth_external_client( + auth_instance *ablock, /* authenticator block */ + void * sx, /* smtp connextion */ + int timeout, /* command timeout */ + uschar *buffer, /* buffer for reading response */ + int buffsize) /* size of buffer */ +{ +auth_external_options_block *ob = + (auth_external_options_block *)(ablock->options_block); +const uschar * text = ob->client_send; +int rc; + +/* We output an AUTH command with one expanded argument, the client_send option */ + +if ((rc = auth_client_item(sx, ablock, &text, AUTH_ITEM_FIRST | AUTH_ITEM_LAST, + timeout, buffer, buffsize)) != OK) + return rc == DEFER ? FAIL : rc; + +if (text) auth_vars[0] = string_copy(text); +return OK; +} + + + +#endif /*!MACRO_PREDEF*/ +/* End of external.c */ diff --git a/src/src/auths/external.h b/src/src/auths/external.h new file mode 100644 index 000000000..7d43650bb --- /dev/null +++ b/src/src/auths/external.h @@ -0,0 +1,32 @@ +/************************************************* +* Exim - an Internet mail transport agent * +*************************************************/ + +/* Copyright (c) Jeremy Harris 2019 */ +/* See the file NOTICE for conditions of use and distribution. */ + +/* Private structure for the private options. */ + +typedef struct { + uschar * server_param2; + uschar * server_param3; + + uschar * client_send; +} auth_external_options_block; + +/* Data for reading the private options. */ + +extern optionlist auth_external_options[]; +extern int auth_external_options_count; + +/* Block containing default values. */ + +extern auth_external_options_block auth_external_option_defaults; + +/* The entry points for the mechanism */ + +extern void auth_external_init(auth_instance *); +extern int auth_external_server(auth_instance *, uschar *); +extern int auth_external_client(auth_instance *, void *, int, uschar *, int); + +/* End of external.h */ diff --git a/src/src/config.h.defaults b/src/src/config.h.defaults index 7c2e534f3..74ec3f4df 100644 --- a/src/src/config.h.defaults +++ b/src/src/config.h.defaults @@ -24,6 +24,7 @@ Do not put spaces between # and the 'define'. #define AUTH_CRAM_MD5 #define AUTH_CYRUS_SASL #define AUTH_DOVECOT +#define AUTH_EXTERNAL #define AUTH_GSASL #define AUTH_HEIMDAL_GSSAPI #define AUTH_PLAINTEXT diff --git a/src/src/drtables.c b/src/src/drtables.c index cd12dd1da..54d03edab 100644 --- a/src/src/drtables.c +++ b/src/src/drtables.c @@ -35,6 +35,10 @@ set to NULL for those that are not compiled into the binary. */ #include "auths/dovecot.h" #endif +#ifdef AUTH_EXTERNAL +#include "auths/external.h" +#endif + #ifdef AUTH_GSASL #include "auths/gsasl_exim.h" #endif @@ -101,6 +105,20 @@ auth_info auths_available[] = { }, #endif +#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, + .servercode = auth_external_server, + .clientcode = auth_external_client, + .version_report = NULL + }, +#endif + #ifdef AUTH_GSASL { .driver_name = US"gsasl", |