if (SASL_CB_PRESENT(cparams)) {
if (mech_nego) {
- if (!server_can_cb && SASL_CB_CRITICAL(cparams))
+ if (!server_can_cb && SASL_CB_CRITICAL(cparams)) {
return SASL_NOMECH;
- else
+ } else {
*cbindingdisp = SASL_CB_DISP_WANT;
+ }
} else if (SASL_CB_CRITICAL(cparams)) {
*cbindingdisp = SASL_CB_DISP_USED;
}
{
sasl_client_conn_t *c_conn= (sasl_client_conn_t *) conn;
char *ordered_mechs = NULL, *name;
- cmechanism_t *m=NULL,*bestm=NULL;
+ cmechanism_t *m = NULL, *bestm = NULL;
size_t i, list_len;
sasl_ssf_t bestssf = 0, minssf = 0;
int result, server_can_cb = 0;
sasl_cbinding_disp_t cbindingdisp;
+ sasl_cbinding_disp_t cur_cbindingdisp;
+ sasl_cbinding_disp_t best_cbindingdisp = SASL_CB_DISP_NONE;
if(_sasl_client_active==0) return SASL_NOTINIT;
* are doing mechanism negotiation and whether server supports
* channel bindings.
*/
- result = _sasl_cbinding_disp(c_conn->cparams, (list_len > 1),
- server_can_cb, &cbindingdisp);
+ result = _sasl_cbinding_disp(c_conn->cparams,
+ (list_len > 1),
+ server_can_cb,
+ &cbindingdisp);
if (result != 0)
goto done;
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))
+ if (!_sasl_is_equal_mech(name, m->m.plug->mech_name,
+ strlen(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 (cbindingdisp != SASL_CB_DISP_NONE &&
+ if (cbindingdisp == SASL_CB_DISP_USED &&
!(m->m.plug->features & SASL_FEAT_CHANNEL_BINDING)) {
break;
}
break;
}
-#ifdef PREFER_MECH
- if (strcasecmp(m->m.plug->mech_name, PREFER_MECH) &&
- bestm && m->m.plug->max_ssf <= bestssf) {
- /* this mechanism isn't our favorite, and it's no better
- than what we already have! */
- break;
- }
-#else
- if (bestm && m->m.plug->max_ssf <= bestssf) {
- /* this mechanism is no better than what we already have! */
- break;
- }
-#endif
-
/* compare security flags, only take new mechanism if it has
* all the security flags of the previous one.
*
}
if (SASL_CB_PRESENT(c_conn->cparams) && plus) {
- cbindingdisp = SASL_CB_DISP_USED;
+ cur_cbindingdisp = SASL_CB_DISP_USED;
+ } else {
+ cur_cbindingdisp = cbindingdisp;
+ }
+
+ if (bestm && (best_cbindingdisp > cur_cbindingdisp)) {
+ break;
+ }
+
+#ifdef PREFER_MECH
+ if (strcasecmp(m->m.plug->mech_name, PREFER_MECH) &&
+ bestm && m->m.plug->max_ssf <= bestssf) {
+ /* this mechanism isn't our favorite, and it's no better
+ than what we already have! */
+ break;
}
+#else
+ if (bestm && m->m.plug->max_ssf <= bestssf) {
+ /* this mechanism is no better than what we already have! */
+ break;
+ }
+#endif
if (mech) {
*mech = m->m.plug->mech_name;
}
+
+ best_cbindingdisp = cur_cbindingdisp;
bestssf = m->m.plug->max_ssf;
bestm = m;
break;
c_conn->cparams->external_ssf = conn->external.ssf;
c_conn->cparams->props = conn->props;
- c_conn->cparams->cbindingdisp = cbindingdisp;
+ c_conn->cparams->cbindingdisp = best_cbindingdisp;
c_conn->mech = bestm;
/* init that plugin */
if (_sasl_getcallback(conn, SASL_CB_GETOPT, &getopt, &context)
== SASL_OK) {
const char *mlist = NULL;
+ int plus = 0;
getopt(context, NULL, "mech_list", &mlist, NULL);
while (*mlist) {
for (cp = mlist; *cp && !isspace((int) *cp); cp++);
- if (((size_t) (cp - mlist) == strlen(plug->mech_name)) &&
- !strncasecmp(mlist, plug->mech_name,
- strlen(plug->mech_name))) {
+ if (_sasl_is_equal_mech(mlist, plug->mech_name, (size_t) (cp - mlist), &plus)) {
+ /* found a match */
break;
}
mlist = cp;
int result;
context_list_t *cur, **prev;
mechanism_t *m;
+ size_t mech_len;
int plus = 0;
if (_sasl_server_active==0) return SASL_NOTINIT;
/* make sure mech is valid mechanism
if not return appropriate error */
m=mechlist->mech_list;
+ mech_len = strlen(mech);
/* check parameters */
if(!conn) return SASL_BADPARAM;
if(serveroutlen) *serveroutlen = 0;
while (m != NULL) {
- if (_sasl_is_equal_mech(mech, m->m.plug->mech_name, &plus))
+ if (_sasl_is_equal_mech(mech, m->m.plug->mech_name, mech_len, &plus))
break;
m = m->next;