]> diplodocus.org Git - nmh/commitdiff
Add context information to SASL callback.
authorKen Hornstein <kenh@pobox.com>
Tue, 24 Oct 2017 18:47:19 +0000 (14:47 -0400)
committerKen Hornstein <kenh@pobox.com>
Tue, 24 Oct 2017 18:47:19 +0000 (14:47 -0400)
Provide an extra context argument for the SASL negotiation callback
that application code can use to pass down information that the
callback might need.

h/netsec.h
mts/smtp/smtp.c
sbr/netsec.c
uip/popsbr.c

index 0a14a1d..b115ed7 100644 (file)
@@ -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
index c7d9507..cc4a27c 100644 (file)
@@ -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:
index a0b11d3..537df82 100644 (file)
@@ -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.
index d79c8b3..a9e442b 100644 (file)
@@ -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: