From: Ken Hornstein Date: Tue, 24 Oct 2017 18:47:19 +0000 (-0400) Subject: Add context information to SASL callback. X-Git-Url: https://diplodocus.org/git/nmh/commitdiff_plain/c2655c2b98253e03c42eeeee1e5c60fe7107c5a4?ds=sidebyside Add context information to SASL callback. Provide an extra context argument for the SASL negotiation callback that application code can use to pass down information that the callback might need. --- diff --git a/h/netsec.h b/h/netsec.h index 0a14a1d0..b115ed7c 100644 --- a/h/netsec.h +++ b/h/netsec.h @@ -258,6 +258,7 @@ enum sasl_message_type { * indatasize - The size of the input data in bytes * outdata - Output data (freed by caller) * outdatasize - Size of output data + * context - Extra context information potentially required by callback * errstr - An error string to be returned (freed by caller). * * As a general note, plugins should perform their own I/O. Buffers returned @@ -298,7 +299,8 @@ typedef int (*netsec_sasl_callback)(enum sasl_message_type mtype, unsigned const char *indata, unsigned int indatasize, unsigned char **outdata, - unsigned int *outdatasize, char **errstr); + unsigned int *outdatasize, + void *context, char **errstr); /* * Sets the SASL parameters for this connection. If this function is @@ -315,6 +317,7 @@ typedef int (*netsec_sasl_callback)(enum sasl_message_type mtype, * mechanism - The mechanism desired by the user. If NULL, the SASL * library will attempt to negotiate the best mechanism. * callback - SASL protocol callbacks + * context - Extra context information passed to the protocol callback * errstr - Error string. * * Returns NOTOK if SASL is not supported. @@ -322,7 +325,8 @@ typedef int (*netsec_sasl_callback)(enum sasl_message_type mtype, int netsec_set_sasl_params(netsec_context *ns_context, const char *service, const char *mechanism, - netsec_sasl_callback callback, char **errstr); + netsec_sasl_callback callback, + void *context, char **errstr); /* * Start SASL negotiation. The Netsec library will use the callbacks diff --git a/mts/smtp/smtp.c b/mts/smtp/smtp.c index c7d95073..cc4a27cb 100644 --- a/mts/smtp/smtp.c +++ b/mts/smtp/smtp.c @@ -68,7 +68,7 @@ static int smhear (void); static char *EHLOset (char *) PURE; static int sm_sasl_callback(enum sasl_message_type, unsigned const char *, unsigned int, unsigned char **, unsigned int *, - char **); + void *, char **); int sm_init (char *client, char *server, char *port, int watch, int verbose, @@ -133,7 +133,7 @@ smtp_init (char *client, char *server, char *port, int watch, int verbose, if (sasl) { if (netsec_set_sasl_params(nsc, "smtp", saslmech, sm_sasl_callback, - &errstr) != OK) + NULL, &errstr) != OK) return sm_nerror(errstr); } @@ -295,7 +295,7 @@ sendmail_init (char *client, int watch, int verbose, int debug, int sasl, if (sasl) { if (netsec_set_sasl_params(nsc, "smtp", saslmech, sm_sasl_callback, - &errstr) != OK) + NULL, &errstr) != OK) return sm_nerror(errstr); } @@ -947,11 +947,12 @@ EHLOset (char *s) static int sm_sasl_callback(enum sasl_message_type mtype, unsigned const char *indata, unsigned int indatalen, unsigned char **outdata, - unsigned int *outdatalen, char **errstr) + unsigned int *outdatalen, void *context, char **errstr) { int rc, snoopoffset; char *mech, *line; size_t len; + NMH_UNUSED(context); switch (mtype) { case NETSEC_SASL_START: diff --git a/sbr/netsec.c b/sbr/netsec.c index a0b11d37..537df825 100644 --- a/sbr/netsec.c +++ b/sbr/netsec.c @@ -74,6 +74,7 @@ struct _netsec_context { char *sasl_mech; /* User-requested mechanism */ char *sasl_chosen_mech; /* Mechanism chosen by SASL */ netsec_sasl_callback sasl_proto_cb; /* SASL callback we use */ + void *sasl_proto_context; /* Context to be used by SASL callback */ #ifdef OAUTH_SUPPORT char *oauth_service; /* OAuth2 service name */ #endif /* OAUTH_SUPPORT */ @@ -161,6 +162,7 @@ netsec_init(void) nsc->sasl_mech = NULL; nsc->sasl_chosen_mech = NULL; nsc->sasl_proto_cb = NULL; + nsc->sasl_proto_context = NULL; #ifdef OAUTH_SUPPORT nsc->oauth_service = NULL; #endif /* OAUTH_SUPPORT */ @@ -951,7 +953,7 @@ netsec_flush(netsec_context *nsc, char **errstr) int netsec_set_sasl_params(netsec_context *nsc, const char *service, const char *mechanism, netsec_sasl_callback callback, - char **errstr) + void *context, char **errstr) { #ifdef CYRUS_SASL sasl_callback_t *sasl_cbs; @@ -1029,6 +1031,7 @@ netsec_set_sasl_params(netsec_context *nsc, const char *service, } nsc->sasl_proto_cb = callback; + nsc->sasl_proto_context = context; return OK; } @@ -1173,7 +1176,8 @@ netsec_negotiate_sasl(netsec_context *nsc, const char *mechlist, char **errstr) } rc = nsc->sasl_proto_cb(NETSEC_SASL_START, xoauth_client_res, - xoauth_client_res_len, NULL, 0, errstr); + xoauth_client_res_len, NULL, 0, + nsc->sasl_proto_context, errstr); free(xoauth_client_res); if (rc != OK) @@ -1186,7 +1190,8 @@ netsec_negotiate_sasl(netsec_context *nsc, const char *mechlist, char **errstr) * error. */ - rc = nsc->sasl_proto_cb(NETSEC_SASL_FINISH, NULL, 0, NULL, 0, errstr); + rc = nsc->sasl_proto_cb(NETSEC_SASL_FINISH, NULL, 0, NULL, 0, + nsc->sasl_proto_context, errstr); if (rc != OK) { /* @@ -1196,9 +1201,10 @@ netsec_negotiate_sasl(netsec_context *nsc, const char *mechlist, char **errstr) * NOT get a success message at this point. */ free(*errstr); - nsc->sasl_proto_cb(NETSEC_SASL_WRITE, NULL, 0, NULL, 0, NULL); + nsc->sasl_proto_cb(NETSEC_SASL_WRITE, NULL, 0, NULL, 0, + nsc->sasl_proto_context, NULL); rc = nsc->sasl_proto_cb(NETSEC_SASL_FINISH, NULL, 0, NULL, 0, - errstr); + nsc->sasl_proto_context, errstr); if (rc == 0) { netsec_err(errstr, "Unexpected success after OAuth failure!"); } @@ -1256,7 +1262,7 @@ netsec_negotiate_sasl(netsec_context *nsc, const char *mechlist, char **errstr) nsc->sasl_chosen_mech = getcpy(chosen_mech); if (nsc->sasl_proto_cb(NETSEC_SASL_START, saslbuf, saslbuflen, NULL, 0, - errstr) != OK) + nsc->sasl_proto_context, errstr) != OK) return NOTOK; /* @@ -1270,8 +1276,9 @@ netsec_negotiate_sasl(netsec_context *nsc, const char *mechlist, char **errstr) */ if (nsc->sasl_proto_cb(NETSEC_SASL_READ, NULL, 0, &outbuf, &outbuflen, - errstr) != OK) { - nsc->sasl_proto_cb(NETSEC_SASL_CANCEL, NULL, 0, NULL, 0, NULL); + nsc->sasl_proto_context, errstr) != OK) { + nsc->sasl_proto_cb(NETSEC_SASL_CANCEL, NULL, 0, NULL, 0, + nsc->sasl_proto_context, NULL); return NOTOK; } @@ -1283,13 +1290,16 @@ netsec_negotiate_sasl(netsec_context *nsc, const char *mechlist, char **errstr) if (rc != SASL_OK && rc != SASL_CONTINUE) { netsec_err(errstr, "SASL client negotiation failed: %s", sasl_errdetail(nsc->sasl_conn)); - nsc->sasl_proto_cb(NETSEC_SASL_CANCEL, NULL, 0, NULL, 0, NULL); + nsc->sasl_proto_cb(NETSEC_SASL_CANCEL, NULL, 0, NULL, 0, + nsc->sasl_proto_context, NULL); return NOTOK; } if (nsc->sasl_proto_cb(NETSEC_SASL_WRITE, saslbuf, saslbuflen, - NULL, 0, errstr) != OK) { - nsc->sasl_proto_cb(NETSEC_SASL_CANCEL, NULL, 0, NULL, 0, NULL); + NULL, 0, nsc->sasl_proto_context, + errstr) != OK) { + nsc->sasl_proto_cb(NETSEC_SASL_CANCEL, NULL, 0, NULL, 0, + nsc->sasl_proto_context, NULL); return NOTOK; } } @@ -1300,7 +1310,7 @@ netsec_negotiate_sasl(netsec_context *nsc, const char *mechlist, char **errstr) */ if (nsc->sasl_proto_cb(NETSEC_SASL_FINISH, NULL, 0, NULL, 0, - errstr) != OK) { + nsc->sasl_proto_context, errstr) != OK) { /* * At this point we can't really send an abort since the SASL dialog * has completed, so just bubble back up the error message. diff --git a/uip/popsbr.c b/uip/popsbr.c index d79c8b3d..a9e442ba 100644 --- a/uip/popsbr.c +++ b/uip/popsbr.c @@ -34,7 +34,7 @@ static int vcommand(const char *, va_list) CHECK_PRINTF(1, 0); static int pop_getline (char *, int, netsec_context *); static int pop_sasl_callback(enum sasl_message_type, unsigned const char *, unsigned int, unsigned char **, unsigned int *, - char **); + void *, char **); static int check_mech(char *server_mechs, size_t server_mechs_size) @@ -223,7 +223,7 @@ pop_init (char *host, char *port, char *user, char *proxy, int snoop, if (sasl) { if (netsec_set_sasl_params(nsc, "pop", mech, pop_sasl_callback, - &errstr) != OK) { + NULL, &errstr) != OK) { snprintf(response, sizeof(response), "%s", errstr); free(errstr); return NOTOK; @@ -292,11 +292,12 @@ pop_init (char *host, char *port, char *user, char *proxy, int snoop, static int pop_sasl_callback(enum sasl_message_type mtype, unsigned const char *indata, unsigned int indatalen, unsigned char **outdata, - unsigned int *outdatalen, char **errstr) + unsigned int *outdatalen, void *context, char **errstr) { int rc, snoopoffset; char *mech, *line; size_t len, b64len; + NMH_UNUSED(context); switch (mtype) { case NETSEC_SASL_START: