* 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
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
* 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.
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
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,
if (sasl) {
if (netsec_set_sasl_params(nsc, "smtp", saslmech, sm_sasl_callback,
- &errstr) != OK)
+ NULL, &errstr) != OK)
return sm_nerror(errstr);
}
if (sasl) {
if (netsec_set_sasl_params(nsc, "smtp", saslmech, sm_sasl_callback,
- &errstr) != OK)
+ NULL, &errstr) != OK)
return sm_nerror(errstr);
}
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:
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 */
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 */
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;
}
nsc->sasl_proto_cb = callback;
+ nsc->sasl_proto_context = context;
return OK;
}
}
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)
* 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) {
/*
* 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!");
}
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;
/*
*/
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;
}
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;
}
}
*/
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.
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)
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;
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: