move CB validation into libsasl
authorLuke Howard <lukeh@padl.com>
Sun, 26 Sep 2010 23:54:20 +0000 (01:54 +0200)
committerLuke Howard <lukeh@padl.com>
Sun, 26 Sep 2010 23:54:20 +0000 (01:54 +0200)
include/saslplug.h
lib/server.c
plugins/gs2.c

index ea5368e..1024fab 100755 (executable)
@@ -198,7 +198,7 @@ typedef struct sasl_out_params {
     void *spare_ptr4;
     int (*spare_fptr1)();
     int (*spare_fptr2)();
-    int spare_int1;
+    int chanbindingflag;
     int spare_int2;
     int spare_int3;
     int spare_int4;
@@ -566,8 +566,8 @@ typedef struct sasl_server_params {
     void *spare_ptr4;
     int (*spare_fptr1)();
     int (*spare_fptr2)();
-    int chanbindingcrit;
     int chanbindinglen;
+    int chanbindingcrit;
     int spare_int3;
 
     /* flags field as passed to sasl_server_new */
index 3013019..4cdf456 100644 (file)
@@ -1453,7 +1453,18 @@ int sasl_server_step(sasl_conn_t *conn,
            conn->oparams.maxoutbuf = conn->props.maxbufsize;
        }
 
-       if(conn->oparams.user == NULL || conn->oparams.authid == NULL) {
+        /* Validate channel bindings */
+        if (conn->oparams.chanbindingflag == SASL_CB_FLAG_NONE &&
+            s_conn->sparams->chanbindingcrit) {
+           sasl_seterror(conn, 0,
+                         "server requires channel binding but client provided none");
+            ret = SASL_BADAUTH;
+        } else if (conn->oparams.chanbindingflag == SASL_CB_FLAG_WANT &&
+            SASL_CB_PRESENT(s_conn->sparams)) {
+            sasl_seterror(conn, 0,
+                          "client incorrectly determined server had no channel binding");
+            ret = SASL_BADAUTH;
+        } else if (conn->oparams.user == NULL || conn->oparams.authid == NULL) {
            sasl_seterror(conn, 0,
                          "mech did not call canon_user for both authzid " \
                          "and authid");
index cee634f..fefa9af 100644 (file)
@@ -369,16 +369,6 @@ gs2_server_mech_step(void *conn_context,
                                          &input_token);
         if (ret != SASL_OK)
             goto cleanup;
-
-        if ((text->gs2_flags & GS2_CB_FLAG_MASK) == GS2_CB_FLAG_N) {
-            if (params->chanbindingcrit != 0)
-                ret = SASL_BADAUTH;
-        } else if ((text->gs2_flags & GS2_CB_FLAG_MASK) == GS2_CB_FLAG_Y) {
-            if (SASL_CB_PRESENT(params))
-                ret = SASL_BADAUTH;
-        }
-        if (ret != SASL_OK)
-            goto cleanup;
     } else {
         input_token.value = (void *)clientin;
         input_token.length = clientinlen;
@@ -489,6 +479,18 @@ gs2_server_mech_step(void *conn_context,
     if (ret != SASL_OK)
         goto cleanup;
 
+    switch (text->gs2_flags & GS2_CB_FLAG_MASK) {
+    case GS2_CB_FLAG_N:
+        oparams->chanbindingflag = SASL_CB_FLAG_NONE;
+        break;
+    case GS2_CB_FLAG_P:
+        oparams->chanbindingflag = SASL_CB_FLAG_USED;
+        break;
+    case GS2_CB_FLAG_Y:
+        oparams->chanbindingflag == SASL_CB_FLAG_WANT;
+        break;
+    }
+
     if (text->client_creds != GSS_C_NO_CREDENTIAL)
         oparams->client_creds = &text->client_creds;
     else