more work on CB
authorLuke Howard <lukeh@padl.com>
Mon, 27 Sep 2010 01:15:52 +0000 (03:15 +0200)
committerLuke Howard <lukeh@padl.com>
Mon, 27 Sep 2010 01:15:52 +0000 (03:15 +0200)
include/saslplug.h
lib/client.c
lib/common.c

index 1024fab..c114cb6 100755 (executable)
@@ -289,10 +289,11 @@ typedef struct sasl_client_params {
 
     int (*spare_fptr1)();
 
 
     int (*spare_fptr1)();
 
-#define SASL_CB_FLAG_NONE   0       /* client did not support CB */
-#define SASL_CB_FLAG_USED   1       /* client supports and used CB */
-#define SASL_CB_FLAG_WANT   2       /* client supports CB, thinks server does not */
-    int chanbindingflag;
+#define SASL_CB_FLAG_NONE   0x00    /* client did not support CB */
+#define SASL_CB_FLAG_USED   0x01    /* client supports CB, thinks server does not */
+#define SASL_CB_FLAG_WANT   0x02    /* client supports and used CB */
+#define SASL_CB_FLAG_CRIT   0x10    /* client requires CB */
+    int chanbindingflags;
 #define SASL_CB_PRESENT(params) ((params)->chanbindingtype != NULL && (params)->chanbindinglen)
     int chanbindinglen;
     int spare_int3;
 #define SASL_CB_PRESENT(params) ((params)->chanbindingtype != NULL && (params)->chanbindinglen)
     int chanbindinglen;
     int spare_int3;
index b4ea7aa..0cff60d 100644 (file)
@@ -485,7 +485,7 @@ int sasl_client_start(sasl_conn_t *conn,
     cmechanism_t *m=NULL,*bestm=NULL;
     size_t i, list_len;
     sasl_ssf_t bestssf = 0, minssf = 0;
     cmechanism_t *m=NULL,*bestm=NULL;
     size_t i, list_len;
     sasl_ssf_t bestssf = 0, minssf = 0;
-    int result, server_can_cb = 0;
+    int result, server_can_cb = 0, cb_flag;
 
     if(_sasl_client_active==0) return SASL_NOTINIT;
 
 
     if(_sasl_client_active==0) return SASL_NOTINIT;
 
@@ -517,12 +517,19 @@ int sasl_client_start(sasl_conn_t *conn,
                                      &list_len,
                                      &server_can_cb);
     if (result != 0)
                                      &list_len,
                                      &server_can_cb);
     if (result != 0)
-       return result;
+       goto done;
 
 
-    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 &&
+           (c_conn->cparams->chanbindingflags & SASL_CB_FLAG_CRIT)) {
+           result = SASL_NOMECH;
+           goto done;
+       } else {
+           cb_flag = SASL_CB_FLAG_WANT;
+       }
+    } else {
+       cb_flag = SASL_CB_FLAG_NONE;
+    }
 
     for (i = 0, name = ordered_mechs; i < list_len; i++) {
        /* foreach in client list */
 
     for (i = 0, name = ordered_mechs; i < list_len; i++) {
        /* foreach in client list */
@@ -610,7 +617,7 @@ int sasl_client_start(sasl_conn_t *conn,
 
            /* Prefer server advertised CB mechanisms */
            if (SASL_CB_PRESENT(c_conn->cparams) && plus)
 
            /* Prefer server advertised CB mechanisms */
            if (SASL_CB_PRESENT(c_conn->cparams) && plus)
-               c_conn->cparams->chanbindingflag = SASL_CB_FLAG_USED;
+               cb_flag = SASL_CB_FLAG_USED;
 
            if (mech) {
                *mech = m->m.plug->mech_name;
 
            if (mech) {
                *mech = m->m.plug->mech_name;
@@ -642,6 +649,7 @@ int sasl_client_start(sasl_conn_t *conn,
 
     c_conn->cparams->external_ssf = conn->external.ssf;
     c_conn->cparams->props = conn->props;
 
     c_conn->cparams->external_ssf = conn->external.ssf;
     c_conn->cparams->props = conn->props;
+    c_conn->cparams->chanbindingflags |= cb_flag;
     c_conn->mech = bestm;
 
     /* init that plugin */
     c_conn->mech = bestm;
 
     /* init that plugin */
index 620395a..7827808 100644 (file)
@@ -1220,6 +1220,10 @@ int sasl_setprop(sasl_conn_t *conn, int propnum, const void *value)
         ((sasl_client_conn_t *)conn)->cparams->chanbindingtype = cb->type;
         ((sasl_client_conn_t *)conn)->cparams->chanbindingdata = cb->data;
         ((sasl_client_conn_t *)conn)->cparams->chanbindinglen = cb->len;
         ((sasl_client_conn_t *)conn)->cparams->chanbindingtype = cb->type;
         ((sasl_client_conn_t *)conn)->cparams->chanbindingdata = cb->data;
         ((sasl_client_conn_t *)conn)->cparams->chanbindinglen = cb->len;
+        if (cb->critical != 0)
+            ((sasl_client_conn_t *)conn)->cparams->chanbindingflags |= SASL_CB_FLAG_CRIT;
+        else
+            ((sasl_client_conn_t *)conn)->cparams->chanbindingflags &= ~(SASL_CB_FLAG_CRIT);
     }
     break;
   }
     }
     break;
   }