#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
typedef struct sasl_channel_bindings {
char *type;
+ int critical;
unsigned long len;
unsigned char *data;
} sasl_channel_bindings;
int (*spare_fptr1)();
+ int chanbindingscrit;
int chanbindingslen;
- int spare_int2;
int spare_int3;
/* flags field as passed to sasl_client_new */
/* 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
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 */
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
!(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) &&
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;
}
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);
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);