cleanup channel bindings logic
[cyrus-sasl.git] / lib / client.c
index 91c2e2d..c42d6f5 100644 (file)
@@ -390,6 +390,19 @@ static int have_prompts(sasl_conn_t *conn,
   return 1; /* we have all the prompts */
 }
 
+static inline int sasl_is_plus_mech(const char *mech)
+{
+    size_t len = strlen(mech);
+    const char *p;
+
+    if (len < 5)
+        return 0;
+
+    p = &mech[len - 5];
+
+    return (strcmp(p, "-PLUS") == 0);
+}
+
 /* select a mechanism for a connection
  *  mechlist      -- mechanisms server has available (punctuation ignored)
  *  secret        -- optional secret from previous session
@@ -516,7 +529,17 @@ int sasl_client_start(sasl_conn_t *conn,
                !(m->m.plug->features & SASL_FEAT_ALLOWS_PROXY)) {
                break;
            }
-           
+
+           /* If client requires channel binding, prefer -PLUS mech */
+           if (c_conn->cparams->chanbindingslen != 0) {
+               if (sasl_is_plus_mech(name))
+                   c_conn->cparams->chanbindingsflag = SASL_CB_FLAG_USED;
+               else
+                   c_conn->cparams->chanbindingsflag = SASL_CB_FLAG_WANT;
+           } else {
+               c_conn->cparams->chanbindingsflag = SASL_CB_FLAG_NONE;
+           }
+
 #ifdef PREFER_MECH
            if (strcasecmp(m->m.plug->mech_name, PREFER_MECH) &&
                bestm && m->m.plug->max_ssf <= bestssf) {
@@ -652,7 +675,6 @@ int sasl_client_step(sasl_conn_t *conn,
   if(clientoutlen) *clientoutlen = 0;
 
   /* do a step */
-  c_conn->cparams->plug = c_conn->mech->m.plug;
   result = c_conn->mech->m.plug->mech_step(conn->context,
                                         c_conn->cparams,
                                         serverin,
@@ -661,7 +683,6 @@ int sasl_client_step(sasl_conn_t *conn,
                                         clientout, clientoutlen,
                                         &conn->oparams);
 
-  c_conn->cparams->plug = NULL;
   if (result == SASL_OK) {
       /* So we're done on this end, but if both
        * 1. the mech does server-send-last