bx509: Complete /get-tgt?cname= support

This commit is contained in:
Nicolas Williams
2021-04-22 17:01:49 -05:00
parent 76d6ee4abc
commit a4adb8354f
2 changed files with 54 additions and 13 deletions

View File

@@ -119,6 +119,7 @@ typedef struct bx509_request_desc {
krb5_times token_times;
time_t req_life;
hx509_request req;
const char *for_cname;
const char *target;
const char *redir;
char *pkix_store;
@@ -863,6 +864,7 @@ set_req_desc(struct MHD_Connection *connection,
r->reqtype = url;
r->target = r->redir = NULL;
r->pkix_store = NULL;
r->for_cname = NULL;
r->freeme1 = NULL;
r->reason = NULL;
r->ccname = NULL;
@@ -1157,6 +1159,7 @@ do_pkinit(struct bx509_request_desc *r, enum k5_creds_kind kind)
krb5_ccache cc = NULL;
krb5_principal p = NULL;
const char *crealm;
const char *cname = r->for_cname ? r->for_cname : r->cname;
if (kind == K5_CREDS_CACHED) {
int won = -1;
@@ -1177,7 +1180,7 @@ do_pkinit(struct bx509_request_desc *r, enum k5_creds_kind kind)
ret = krb5_cc_new_unique(r->context, "FILE", NULL, &temp_cc);
}
ret = krb5_parse_name(r->context, r->cname, &p);
ret = krb5_parse_name(r->context, cname, &p);
if (ret == 0)
crealm = krb5_principal_get_realm(r->context, p);
if (ret == 0)
@@ -1282,6 +1285,7 @@ k5_do_CA(struct bx509_request_desc *r)
hx509_request req = NULL;
hx509_certs certs = NULL;
KeyUsage ku = int2KeyUsage(0);
const char *cname = r->for_cname ? r->for_cname : r->cname;
memset(&spki, 0, sizeof(spki));
ku.digitalSignature = 1;
@@ -1292,7 +1296,7 @@ k5_do_CA(struct bx509_request_desc *r)
if (ret == 0)
ret = hx509_request_init(r->context->hx509ctx, &req);
if (ret == 0)
ret = krb5_parse_name(r->context, r->cname, &p);
ret = krb5_parse_name(r->context, cname, &p);
if (ret == 0)
hx509_private_key2SPKI(r->context->hx509ctx, key, &spki);
if (ret == 0)
@@ -1300,7 +1304,7 @@ k5_do_CA(struct bx509_request_desc *r)
&spki);
free_SubjectPublicKeyInfo(&spki);
if (ret == 0)
ret = hx509_request_add_pkinit(r->context->hx509ctx, req, r->cname);
ret = hx509_request_add_pkinit(r->context->hx509ctx, req, cname);
if (ret == 0)
ret = hx509_request_add_eku(r->context->hx509ctx, req,
&asn1_oid_id_pkekuoid);
@@ -1353,10 +1357,11 @@ static krb5_error_code
k5_get_creds(struct bx509_request_desc *r, enum k5_creds_kind kind)
{
krb5_error_code ret;
const char *cname = r->for_cname ? r->for_cname : r->cname;
/* If we have a live ccache for `cprinc', we're done */
if (kind == K5_CREDS_CACHED &&
(ret = find_ccache(r->context, r->cname, &r->ccname)) == 0)
(ret = find_ccache(r->context, cname, &r->ccname)) == 0)
return ret; /* Success */
/*
@@ -1460,14 +1465,15 @@ mk_nego_tok(struct bx509_request_desc *r,
gss_name_t aname = GSS_C_NO_NAME;
OM_uint32 major, minor, junk;
krb5_error_code ret; /* More like a system error code here */
const char *cname = r->for_cname ? r->for_cname : r->cname;
char *token_b64 = NULL;
*nego_tok = NULL;
*nego_toksz = 0;
/* Import initiator name */
name.length = strlen(r->cname);
name.value = r->cname;
name.length = strlen(cname);
name.value = rk_UNCONST(cname);
major = gss_import_name(&minor, &name, GSS_KRB5_NT_PRINCIPAL_NAME, &iname);
if (major != GSS_S_COMPLETE)
return bad_req_gss(r, major, minor, GSS_C_NO_OID,
@@ -1665,21 +1671,26 @@ bnegotiate(struct bx509_request_desc *r)
}
static krb5_error_code
authorize_TGT_REQ(struct bx509_request_desc *r, const char *cname)
authorize_TGT_REQ(struct bx509_request_desc *r)
{
krb5_principal p = NULL;
krb5_error_code ret;
const char *for_cname = r->for_cname ? r->for_cname : r->cname;
if (for_cname == r->cname || strcmp(r->cname, r->for_cname) == 0)
return 0;
ret = krb5_parse_name(r->context, r->cname, &p);
ret = hx509_request_init(r->context->hx509ctx, &r->req);
if (ret)
return bad_500(r, ret, "Out of resources");
heim_audit_addkv((heim_svc_req_desc)r, KDC_AUDIT_VIS,
"requested_krb5PrincipalName", "%s", cname);
"requested_krb5PrincipalName", "%s", for_cname);
ret = hx509_request_add_eku(r->context->hx509ctx, r->req,
ASN1_OID_ID_PKEKUOID);
if (ret == 0)
ret = hx509_request_add_pkinit(r->context->hx509ctx, r->req, cname);
ret = hx509_request_add_pkinit(r->context->hx509ctx, r->req,
for_cname);
if (ret == 0)
ret = kdc_authorize_csr(r->context, "get-tgt", r->req, p);
krb5_free_principal(r->context, p);
@@ -1740,15 +1751,16 @@ get_tgt(struct bx509_request_desc *r)
{
krb5_error_code ret;
size_t bodylen;
const char *cname = NULL;
const char *fn;
void *body;
cname = MHD_lookup_connection_value(r->connection, MHD_GET_ARGUMENT_KIND,
"cname");
r->for_cname = MHD_lookup_connection_value(r->connection,
MHD_GET_ARGUMENT_KIND, "cname");
if (r->for_cname && r->for_cname[0] == '\0')
r->for_cname = NULL;
ret = validate_token(r);
if (ret == 0)
ret = authorize_TGT_REQ(r, cname ? cname : r->cname);
ret = authorize_TGT_REQ(r);
/* validate_token() and authorize_TGT_REQ() call bad_req() */
if (ret)
return ret;

View File

@@ -290,6 +290,7 @@ ${kadmin} init \
--realm-max-renewable-life=1month \
${R} || exit 1
${kadmin} add -r --use-defaults foo@${R} || exit 1
${kadmin} add -r --use-defaults bar@${R} || exit 1
${kadmin} modify --pkinit-acl="CN=foo,DC=test,DC=h5l,DC=se" foo@${R} || exit 1
@@ -433,6 +434,17 @@ trap "kill -9 ${kdcpid} ${bx509pid}; echo signal killing kdc and bx509d; exit 1;
${kinit} -kt $ukeytab foo@${R} || exit 1
$klist || { echo "failed to setup kimpersonate credentials"; exit 2; }
echo "Fetch TGT (not granted for other)"
token=$(KRB5CCNAME=$cache $gsstoken HTTP@$server)
if (set -vx;
curl -o "${cachefile2}" -Lgsf \
--resolve ${server}:${bx509port}:127.0.0.1 \
-H "Authorization: Negotiate $token" \
"http://${server}:${bx509port}/get-tgt?cname=bar@${R}&address=8.8.8.8"); then
echo "Got a TGT with /get-tgt end-point when not granted!"
exit 2
fi
echo "Fetch TGT"
(set -vx; csr_grant pkinit foo@${R} foo@${R})
(set -vx; csr_grant eku 1.3.6.1.5.2.3.4 foo@${R})
@@ -465,6 +477,23 @@ ${kgetcred} -H HTTP/${server}@${R} ||
${klist} | grep Addresses:.IPv4:8.8.8.8 ||
{ echo "Failed to get a TGT with /get-tgt end-point with addresses"; exit 2; }
echo "Fetch TGT (for other)"
(set -vx; csr_grant pkinit bar@${R} foo@${R})
${kdestroy}
token=$(KRB5CCNAME=$cache2 $gsstoken HTTP@$server)
if ! (set -vx;
curl -o "${cachefile}" -Lgsf \
--resolve ${server}:${bx509port}:127.0.0.1 \
-H "Authorization: Negotiate $token" \
"http://${server}:${bx509port}/get-tgt?cname=bar@${R}&address=8.8.8.8"); then
echo "Failed to get a TGT with /get-tgt end-point"
exit 2
fi
${kgetcred} -H HTTP/${server}@${R} ||
{ echo "Trivial offline CA test failed (TGS)"; exit 2; }
${klist} | grep Addresses:.IPv4:8.8.8.8 ||
{ echo "Failed to get a TGT with /get-tgt end-point with addresses"; exit 2; }
echo "Fetch negotiate token (pre-test)"
# Do what /bnegotiate does, roughly, prior to testing /bnegotiate
$hxtool request-create --subject='' --generate-key=rsa --key-bits=1024 \