From 80e5911e68adc64f46a5d287c4cf793188090368 Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Sun, 26 Sep 2010 19:40:46 +0200 Subject: [PATCH] refactor gs2 plus logic a bit --- include/sasl.h | 2 +- include/saslplug.h | 8 ++++++-- lib/client.c | 19 +++++++++++++++++++ lib/common.c | 2 ++ sample/client.c | 1 + sample/server.c | 1 + 6 files changed, 30 insertions(+), 3 deletions(-) diff --git a/include/sasl.h b/include/sasl.h index 991f5d6..714f0ca 100755 --- a/include/sasl.h +++ b/include/sasl.h @@ -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; diff --git a/include/saslplug.h b/include/saslplug.h index 19eaefe..205ce4c 100755 --- a/include/saslplug.h +++ b/include/saslplug.h @@ -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 */ diff --git a/lib/client.c b/lib/client.c index 9fdcf46..5ba6116 100644 --- a/lib/client.c +++ b/lib/client.c @@ -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) && diff --git a/lib/common.c b/lib/common.c index 5ce05bd..9df3217 100644 --- a/lib/common.c +++ b/lib/common.c @@ -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; } diff --git a/sample/client.c b/sample/client.c index f7cea46..2d235e0 100644 --- a/sample/client.c +++ b/sample/client.c @@ -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); diff --git a/sample/server.c b/sample/server.c index 6eaabd8..7d680f9 100644 --- a/sample/server.c +++ b/sample/server.c @@ -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); -- 2.1.4