refactor gs2 plus logic a bit
authorLuke Howard <lukeh@padl.com>
Sun, 26 Sep 2010 17:40:46 +0000 (19:40 +0200)
committerLuke Howard <lukeh@padl.com>
Sun, 26 Sep 2010 17:40:46 +0000 (19:40 +0200)
include/sasl.h
include/saslplug.h
lib/client.c
lib/common.c
sample/client.c
sample/server.c

index 991f5d6..714f0ca 100755 (executable)
@@ -300,7 +300,6 @@ typedef unsigned sasl_ssf_t;
 #define SASL_SEC_NOANONYMOUS      0x0010
 #define SASL_SEC_PASS_CREDENTIALS 0x0020
 #define SASL_SEC_MUTUAL_AUTH      0x0040
-#define SASL_SEC_CHANNEL_BINDINGS 0x0080
 #define SASL_SEC_MAXIMUM          0x00FF
 
 typedef struct sasl_security_properties 
@@ -794,6 +793,7 @@ LIBSASL_API int sasl_getprop(sasl_conn_t *conn, int propnum,
 
 typedef struct sasl_channel_bindings {
     char *type;
+    int critical;
     unsigned long len;
     unsigned char *data;
 } sasl_channel_bindings;
index 19eaefe..205ce4c 100755 (executable)
@@ -289,8 +289,8 @@ typedef struct sasl_client_params {
 
     int (*spare_fptr1)();
 
+    int chanbindingscrit;
     int chanbindingslen;
-    int spare_int2;
     int spare_int3;
 
     /* flags field as passed to sasl_client_new */
@@ -331,6 +331,10 @@ typedef struct sasl_client_params {
 
 /* Underlying mechanism uses GSS framing */
 #define SASL_FEAT_GSS_FRAMING       0x0040
+
+/* Underlying mechanism supports channel binding */
+#define SASL_FEAT_CHANNEL_BINDINGS  0x0080
+
 /* client plug-in features */
 #define SASL_FEAT_NEEDSERVERFQDN 0x0001
 
@@ -558,8 +562,8 @@ typedef struct sasl_server_params {
     void *spare_ptr4;
     int (*spare_fptr1)();
     int (*spare_fptr2)();
+    int chanbindingscrit;
     int chanbindingslen;
-    int spare_int2;
     int spare_int3;
 
     /* flags field as passed to sasl_server_new */
index 9fdcf46..5ba6116 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,6 +529,12 @@ 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->chanbindingscrit &&
+               !sasl_is_plus_mech(name)) {
+               break;
+           }
            
 #ifdef PREFER_MECH
            if (strcasecmp(m->m.plug->mech_name, PREFER_MECH) &&
index 5ce05bd..9df3217 100644 (file)
@@ -1213,10 +1213,12 @@ int sasl_setprop(sasl_conn_t *conn, int propnum, const void *value)
 
     if (conn->type == SASL_CONN_SERVER) {
         ((sasl_server_conn_t *)conn)->sparams->chanbindingstype = cb->type;
+        ((sasl_server_conn_t *)conn)->sparams->chanbindingscrit = cb->critical;
         ((sasl_server_conn_t *)conn)->sparams->chanbindingsdata = cb->data;
         ((sasl_server_conn_t *)conn)->sparams->chanbindingslen = cb->len;
     } else {
         ((sasl_client_conn_t *)conn)->cparams->chanbindingstype = cb->type;
+        ((sasl_client_conn_t *)conn)->cparams->chanbindingscrit = cb->critical;
         ((sasl_client_conn_t *)conn)->cparams->chanbindingsdata = cb->data;
         ((sasl_client_conn_t *)conn)->cparams->chanbindingslen = cb->len;
     }
index f7cea46..2d235e0 100644 (file)
@@ -421,6 +421,7 @@ int main(int argc, char *argv[])
     if (r != SASL_OK) saslfail(r, "allocating connection state");
 
     cb.type = "sasl-sample";
+    cb.critical = 1;
     cb.data = "this is a test of channel bindings";
     cb.len = strlen(cb.data);
 
index 6eaabd8..7d680f9 100644 (file)
@@ -441,6 +441,7 @@ int main(int argc, char *argv[])
        if (r != SASL_OK) saslfail(r, "allocating connection state");
 
         cb.type = "sasl-sample";
+        cb.critical = 1;
         cb.data = "this is a test of channel bindings";
         cb.len = strlen(cb.data);