cleanup channel bindings logic
[cyrus-sasl.git] / lib / client.c
index 9fdcf46..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) {