X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=lib%2Fclient.c;h=d4b37f0af9f78121611f48288633df8ca38cac12;hb=933224d8489c47068ee84469d3d997679376f8db;hp=9e1d66f613de1dc069dbe57e44d852277db94b42;hpb=f8e05292fe2f0b8691156c97c2def7280cbad662;p=cyrus-sasl.git diff --git a/lib/client.c b/lib/client.c index 9e1d66f..d4b37f0 100644 --- a/lib/client.c +++ b/lib/client.c @@ -185,7 +185,7 @@ client_idle(sasl_conn_t *conn) /* initialize the SASL client drivers * callbacks -- base callbacks for all client connections * returns: - * SASL_OK -- Success + * SASL_OK -- Success * SASL_NOMEM -- Not enough memory * SASL_BADVERS -- Mechanism version mismatch * SASL_BADPARAM -- error in config file @@ -272,18 +272,18 @@ static void client_dispose(sasl_conn_t *pconn) * service -- registered name of the service using SASL (e.g. "imap") * serverFQDN -- the fully qualified domain name of the server * iplocalport -- client IPv4/IPv6 domain literal string with port - * (if NULL, then mechanisms requiring IPaddr are disabled) + * (if NULL, then mechanisms requiring IPaddr are disabled) * ipremoteport -- server IPv4/IPv6 domain literal string with port - * (if NULL, then mechanisms requiring IPaddr are disabled) + * (if NULL, then mechanisms requiring IPaddr are disabled) * prompt_supp -- list of client interactions supported - * may also include sasl_getopt_t context & call - * NULL prompt_supp = user/pass via SASL_INTERACT only - * NULL proc = interaction supported via SASL_INTERACT + * may also include sasl_getopt_t context & call + * NULL prompt_supp = user/pass via SASL_INTERACT only + * NULL proc = interaction supported via SASL_INTERACT * secflags -- security flags (see above) * in/out: - * pconn -- connection negotiation structure - * pointer to NULL => allocate new - * non-NULL => recycle storage and go for next available mech + * pconn -- connection negotiation structure + * pointer to NULL => allocate new + * non-NULL => recycle storage and go for next available mech * * Returns: * SASL_OK -- success @@ -409,33 +409,45 @@ _sasl_client_order_mechs(const sasl_utils_t *utils, int *server_can_cb) { char *list, *listp; - size_t i; - const char *p, *start = NULL; + size_t i, mechslen, start; *count = 0; *server_can_cb = 0; - listp = list = utils->malloc(strlen(mechs) + 1); + if (mechs == NULL || mechs[0] == '\0') + return SASL_NOMECH; + + mechslen = strlen(mechs); + + listp = list = utils->malloc(mechslen + 1); if (list == NULL) return SASL_NOMEM; + /* xxx confirm this with rfc 2222 + * SASL mechanism allowable characters are "AZaz-_" + * seperators can be any other characters and of any length + * even variable lengths between + * + * Apps should be encouraged to simply use space or comma space + * though + */ +#define ismechchar(c) (isalnum((c)) || (c) == '_' || (c) == '-') do { - for (start = p = mechs, i = 0; *p != '\0'; p++) { - if (isspace(*p) || p[1] == '\0') { - size_t len = p - start; - - if (p[1] == '\0') - len++; - - if (_mech_plus_p(start, len) == has_cb_data) { - memcpy(listp, start, len); + for (i = start = 0; i <= mechslen; i++) { + if (!ismechchar(mechs[i])) { + const char *mechp = &mechs[start]; + size_t len = i - start; + + if (len != 0 && + _mech_plus_p(mechp, len) == has_cb_data) { + memcpy(listp, mechp, len); listp[len] = '\0'; listp += len + 1; (*count)++; if (*server_can_cb == 0 && has_cb_data) *server_can_cb = 1; } - start = p + 1; + start = ++i; } } if (has_cb_data) @@ -444,7 +456,6 @@ _sasl_client_order_mechs(const sasl_utils_t *utils, break; } while (1); - *listp = '\0'; *ordered_mechs = list; return SASL_OK; @@ -452,11 +463,11 @@ _sasl_client_order_mechs(const sasl_utils_t *utils, /* select a mechanism for a connection * mechlist -- mechanisms server has available (punctuation ignored) - * secret -- optional secret from previous session + * secret -- optional secret from previous session * output: * prompt_need -- on SASL_INTERACT, list of prompts needed to continue * clientout -- the initial client response to send to the server - * mech -- set to mechanism name + * mech -- set to mechanism name * * Returns: * SASL_OK -- success @@ -465,14 +476,6 @@ _sasl_client_order_mechs(const sasl_utils_t *utils, * SASL_INTERACT -- user interaction needed to fill in prompt_need list */ -/* xxx confirm this with rfc 2222 - * SASL mechanism allowable characters are "AZaz-_" - * seperators can be any other characters and of any length - * even variable lengths between - * - * Apps should be encouraged to simply use space or comma space - * though - */ int sasl_client_start(sasl_conn_t *conn, const char *mechlist, sasl_interact_t **prompt_need, @@ -486,6 +489,7 @@ int sasl_client_start(sasl_conn_t *conn, size_t i, list_len; sasl_ssf_t bestssf = 0, minssf = 0; int result, server_can_cb = 0; + unsigned int cbindingdisp; if(_sasl_client_active==0) return SASL_NOTINIT; @@ -517,13 +521,18 @@ int sasl_client_start(sasl_conn_t *conn, &list_len, &server_can_cb); if (result != 0) - return result; + goto done; - /* If we have CB and the server supports it, we should use it */ - if (SASL_CB_PRESENT(c_conn->cparams) && server_can_cb) - c_conn->cparams->chanbindingflag = SASL_CB_FLAG_WANT; - else - c_conn->cparams->chanbindingflag = SASL_CB_FLAG_NONE; + if (SASL_CB_PRESENT(c_conn->cparams)) { + if (server_can_cb == 0 && SASL_CB_CRITICAL(c_conn->cparams)) { + result = SASL_BADBINDING; + goto done; + } else { + cbindingdisp = SASL_CB_DISP_WANT; + } + } else { + cbindingdisp = SASL_CB_DISP_NONE; + } for (i = 0, name = ordered_mechs; i < list_len; i++) { /* foreach in client list */ @@ -610,8 +619,9 @@ int sasl_client_start(sasl_conn_t *conn, } /* Prefer server advertised CB mechanisms */ - if (SASL_CB_PRESENT(c_conn->cparams) && plus) - c_conn->cparams->chanbindingflag = SASL_CB_FLAG_USED; + if (SASL_CB_PRESENT(c_conn->cparams) && plus) { + cbindingdisp = SASL_CB_DISP_USED; + } if (mech) { *mech = m->m.plug->mech_name; @@ -643,6 +653,7 @@ int sasl_client_start(sasl_conn_t *conn, c_conn->cparams->external_ssf = conn->external.ssf; c_conn->cparams->props = conn->props; + c_conn->cparams->cbindingdisp = cbindingdisp; c_conn->mech = bestm; /* init that plugin */ @@ -654,14 +665,14 @@ int sasl_client_start(sasl_conn_t *conn, /* do a step -- but only if we can do a client-send-first */ dostep: if(clientout) { - if(c_conn->mech->m.plug->features & SASL_FEAT_SERVER_FIRST) { - *clientout = NULL; - *clientoutlen = 0; - result = SASL_CONTINUE; - } else { - result = sasl_client_step(conn, NULL, 0, prompt_need, - clientout, clientoutlen); - } + if(c_conn->mech->m.plug->features & SASL_FEAT_SERVER_FIRST) { + *clientout = NULL; + *clientoutlen = 0; + result = SASL_CONTINUE; + } else { + result = sasl_client_step(conn, NULL, 0, prompt_need, + clientout, clientoutlen); + } } else result = SASL_CONTINUE; @@ -674,13 +685,13 @@ int sasl_client_start(sasl_conn_t *conn, /* do a single authentication step. * serverin -- the server message received by the client, MUST have a NUL - * sentinel, not counted by serverinlen + * sentinel, not counted by serverinlen * output: * prompt_need -- on SASL_INTERACT, list of prompts needed to continue * clientout -- the client response to send to the server * * returns: - * SASL_OK -- success + * SASL_OK -- success * SASL_INTERACT -- user interaction needed to fill in prompt_need list * SASL_BADPROT -- server protocol incorrect/cancelled * SASL_BADSERV -- server failed mutual auth @@ -1058,7 +1069,7 @@ int sasl_client_plugin_info ( m = m->next; } } else { - mech_list = strdup (c_mech_list); + mech_list = strdup (c_mech_list); cur_mech = mech_list; @@ -1084,7 +1095,7 @@ int sasl_client_plugin_info ( cur_mech = p; } - free (mech_list); + free (mech_list); } info_cb (NULL, SASL_INFO_LIST_END, info_cb_rock);