*/
static int
_sasl_client_order_mechs(const sasl_utils_t *utils,
- const char *mechs,
- int has_cb_data,
- char **ordered_mechs,
- size_t *count,
- int *server_can_cb)
+ const char *mechs,
+ int has_cb_data,
+ char **ordered_mechs,
+ size_t *count,
+ int *server_can_cb)
{
char *list, *listp;
size_t i;
listp = list = utils->malloc(strlen(mechs) + 1);
if (list == NULL)
- return SASL_NOMEM;
+ return SASL_NOMEM;
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);
- listp[len] = '\0';
- listp += len + 1;
- (*count)++;
- if (*server_can_cb == 0 && has_cb_data)
- *server_can_cb = 1;
- }
- start = p + 1;
- }
- }
- if (has_cb_data)
- has_cb_data = 0;
- else
- break;
+ 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);
+ listp[len] = '\0';
+ listp += len + 1;
+ (*count)++;
+ if (*server_can_cb == 0 && has_cb_data)
+ *server_can_cb = 1;
+ }
+ start = p + 1;
+ }
+ }
+ if (has_cb_data)
+ has_cb_data = 0;
+ else
+ break;
} while (1);
*listp = '\0';
size_t i, list_len;
sasl_ssf_t bestssf = 0, minssf = 0;
int result, server_can_cb = 0;
+ unsigned int cbindingdisp = 0;
if(_sasl_client_active==0) return SASL_NOTINIT;
}
result = _sasl_client_order_mechs(c_conn->cparams->utils,
- mechlist,
- SASL_CB_PRESENT(c_conn->cparams),
- &ordered_mechs,
- &list_len,
- &server_can_cb);
+ mechlist,
+ SASL_CB_PRESENT(c_conn->cparams),
+ &ordered_mechs,
+ &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_NOMECH;
+ 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 */
for (m = cmechlist->mech_list; m != NULL; m = m->next) {
int myflags, plus;
- if (!_sasl_is_equal_mech(name, m->m.plug->mech_name, &plus))
- continue;
+ if (!_sasl_is_equal_mech(name, m->m.plug->mech_name, &plus))
+ continue;
/* Do we have the prompts for it? */
if (!have_prompts(conn, m->m.plug))
}
/* Can we meet it's features? */
+ if (SASL_CB_PRESENT(c_conn->cparams) &&
+ !(m->m.plug->features & SASL_FEAT_CHANNEL_BINDING)) {
+ break;
+ }
+
if ((m->m.plug->features & SASL_FEAT_NEEDSERVERFQDN)
&& !conn->serverFQDN) {
break;
break;
}
- /* Prefer server advertised CB mechanisms */
- if (SASL_CB_PRESENT(c_conn->cparams) && plus)
- c_conn->cparams->chanbindingflag = SASL_CB_FLAG_USED;
+ /* Prefer server advertised CB mechanisms */
+ if (SASL_CB_PRESENT(c_conn->cparams) && plus) {
+ cbindingdisp = SASL_CB_DISP_USED;
+ }
if (mech) {
*mech = m->m.plug->mech_name;
bestm = m;
break;
}
- name += strlen(name) + 1;
+ name += strlen(name) + 1;
}
if (bestm == NULL) {
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 */
done:
if (ordered_mechs != NULL)
- c_conn->cparams->utils->free(ordered_mechs);
+ c_conn->cparams->utils->free(ordered_mechs);
RETURN(conn, result);
}