{
u_char *p;
+#define _GSS_C_NON_8003_WIRE_FLAGS \
+ GSS_C_CHANNEL_BOUND_FLAG
+
+ flags &= ~_GSS_C_NON_8003_WIRE_FLAGS;
+
/*
* see rfc1964 (section 1.1.1 (Initial Token), and the checksum value
* field's format) */
krb5_data fwd_data, timedata;
int32_t offset = 0, oldoffset = 0;
uint32_t flagmask;
+ krb5_boolean channel_bound = FALSE;
krb5_data_zero(&outbuf);
krb5_data_zero(&fwd_data);
}
flags |= GSS_C_TRANS_FLAG;
+ if (req_flags & GSS_C_CHANNEL_BOUND_FLAG) {
+ flags |= GSS_C_CHANNEL_BOUND_FLAG;
+ channel_bound = TRUE;
+ }
+
if (ret_flags)
*ret_flags = flags;
ctx->flags = flags;
enctype,
ctx->kcred,
&cksum,
+ channel_bound,
&authenticator,
KRB5_KU_AP_REQ_AUTH);
return GSS_S_FAILURE;
}
}
+ if (ret != GSS_S_COMPLETE) {
+ return ret;
+ }
kret = krb5_rd_rep (context,
ctx->auth_context,
&indata,
static int version_flag = 0;
static int verbose_flag = 0;
static int help_flag = 0;
+static int i_channel_bound = 0;
static char *i_channel_bindings = NULL;
static char *a_channel_bindings = NULL;
flags |= GSS_C_DELEG_FLAG;
if (policy_deleg_flag)
flags |= GSS_C_DELEG_POLICY_FLAG;
+ if (i_channel_bound)
+ flags |= GSS_C_CHANNEL_BOUND_FLAG;
input_token.value = rk_UNCONST(target);
input_token.length = strlen(target);
{"client-name", 0, arg_string, &client_name, "client name", NULL },
{"client-password", 0, arg_string, &client_password, "client password", NULL },
{"anonymous", 0, arg_flag, &anon_flag, "anonymous auth", NULL },
+ {"i-channel-bound",0, arg_flag, &i_channel_bound, "initiator channel bound", NULL },
{"i-channel-bindings", 0, arg_string, &i_channel_bindings, "initiator channel binding data", NULL },
{"a-channel-bindings", 0, arg_string, &a_channel_bindings, "acceptor channel binding data", NULL },
{"limit-enctype",0, arg_string, &limit_enctype_string, "enctype", NULL },
static krb5_error_code
add_ap_options(krb5_context context,
+ krb5_boolean channel_bound,
krb5_authdata *auth_data)
{
krb5_error_code ret;
"client_aware_channel_bindings",
NULL);
+ if (channel_bound)
+ require_cb = TRUE;
+
if (!require_cb)
return 0;
return ret;
}
+static krb5_error_code
+add_target_principal(krb5_context context,
+ krb5_const_principal server,
+ krb5_authdata *auth_data)
+{
+ krb5_error_code ret;
+ AuthorizationDataElement ade;
+ char *s, *s2 = NULL;
+ size_t s2_len;
+
+ if (server == NULL) {
+ return 0;
+ }
+
+ ret = krb5_unparse_name_flags(context, server,
+ KRB5_PRINCIPAL_UNPARSE_DISPLAY,
+ &s);
+ if (ret)
+ return ret;
+
+ {
+ size_t ucs2_len;
+ uint16_t *ucs2;
+ unsigned int flags;
+
+ ret = wind_utf8ucs2_length(s, &ucs2_len);
+ if (ret) {
+ krb5_set_error_message(context, ret, "Principal %s is not valid UTF-8", s);
+ free(s);
+ return ret;
+ }
+
+ ucs2 = malloc(sizeof(ucs2[0]) * ucs2_len);
+ if (ucs2 == NULL) {
+ free(s);
+ return krb5_enomem(context);
+ }
+
+ ret = wind_utf8ucs2(s, ucs2, &ucs2_len);
+ if (ret) {
+ free(ucs2);
+ krb5_set_error_message(context, ret, "Principal %s is not valid UTF-8", s);
+ free(s);
+ return ret;
+ } else
+ free(s);
+
+ s2_len = (ucs2_len + 1) * 2;
+ s2 = malloc(s2_len);
+ if (s2 == NULL) {
+ free(ucs2);
+ return krb5_enomem(context);
+ }
+
+ flags = WIND_RW_LE;
+ ret = wind_ucs2write(ucs2, ucs2_len,
+ &flags, s2, &s2_len);
+ free(ucs2);
+ if (ret) {
+ free(s2);
+ krb5_set_error_message(context, ret, "Failed to write to UCS-2 buffer");
+ return ret;
+ }
+
+ /*
+ * we do not want zero termination
+ */
+ s2_len = ucs2_len * 2;
+ }
+
+ ade.ad_type = KRB5_AUTHDATA_TARGET_PRINCIPAL;
+ ade.ad_data.length = s2_len;
+ ade.ad_data.data = s2;
+
+ ret = add_AuthorizationData(auth_data, &ade);
+ free(s2);
+
+ return ret;
+}
+
static krb5_error_code
make_ap_authdata(krb5_context context,
+ krb5_boolean channel_bound,
+ krb5_const_principal server,
krb5_authdata **auth_data)
{
krb5_error_code ret;
* in the AP authenticator when looking for AD-AP-OPTIONS. Make sure to
* bundle it together with etypes.
*/
- ret = add_ap_options(context, &ad);
+ ret = add_ap_options(context, channel_bound, &ad);
+ if (ret) {
+ free_AuthorizationData(&ad);
+ return ret;
+ }
+
+ ret = add_target_principal(context, server, &ad);
if (ret) {
free_AuthorizationData(&ad);
return ret;
krb5_enctype enctype,
krb5_creds *cred,
Checksum *cksum,
+ krb5_boolean channel_bound,
krb5_data *result,
krb5_key_usage usage)
{
* This is not GSS-API specific, we only enable it for
* GSS for now
*/
- ret = make_ap_authdata(context, &auth.authorization_data);
+ ret = make_ap_authdata(context,
+ channel_bound,
+ cred->server,
+ &auth.authorization_data);
if (ret)
goto fail;
}
ac->keyblock->keytype,
in_creds,
c_opt,
+ FALSE, /* channel_bound */
&authenticator,
encrypt_usage);
if (c_opt)
--mech-type=$mech host@lucid.test.h5l.se 2>/dev/null && \
{ eval "$testfailed"; }
+ echo "${mech}: initiator null bindings bound (client-aware-flag)" ; > messages.log
+ ${context} -v --i-channel-bound \
+ --mech-type=$mech host@lucid.test.h5l.se > cbinding.log || \
+ { eval "$testfailed"; }
+ grep "sflags:" cbinding.log | grep "channel-bound" > /dev/null && \
+ { echo "channel-bound flag unexpected"; eval "$testfailed"; }
+
+ echo "${mech}: initiator only bindings (client-aware-flag)" ; > messages.log
+ ${context} -v --i-channel-bound \
+ --i-channel-bindings=abc \
+ --mech-type=$mech host@lucid.test.h5l.se > cbinding.log || \
+ { eval "$testfailed"; }
+ grep "sflags:" cbinding.log | grep "channel-bound" > /dev/null && \
+ { echo "channel-bound flag unexpected"; eval "$testfailed"; }
+
+ echo "${mech}: acceptor only bindings (client-aware-flag)" ; > messages.log
+ ${context} -v --i-channel-bound \
+ --a-channel-bindings=abc \
+ --mech-type=$mech host@lucid.test.h5l.se 2>/dev/null && \
+ { eval "$testfailed"; }
+
+ echo "${mech}: matching bindings (client-aware-flag)" ; > messages.log
+ ${context} -v --i-channel-bound \
+ --i-channel-bindings=abc --a-channel-bindings=abc \
+ --mech-type=$mech host@lucid.test.h5l.se > cbinding.log || \
+ { eval "$testfailed"; }
+ grep "sflags:" cbinding.log | grep "channel-bound" > /dev/null || \
+ { echo "no channel-bound flag"; eval "$testfailed"; }
+
+ echo "${mech}: non matching bindings (client-aware-flag)" ; > messages.log
+ ${context} -v --i-channel-bound \
+ --i-channel-bindings=abc --a-channel-bindings=xyz \
+ --mech-type=$mech host@lucid.test.h5l.se 2>/dev/null && \
+ { eval "$testfailed"; }
+
done
#echo "sasl-digest-md5"