From 5c5cb66c05ca197975c7546c05bb9e6739f1a9cf Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Tue, 2 Jan 2024 13:46:27 +0000 Subject: [PATCH] krb5: Set principal as proxy userid when getting creds. This enables Tor stream isolation. --- lib/krb5/get_cred.c | 5 +++++ lib/krb5/init_creds_pw.c | 3 +++ lib/krb5/krb5.conf.5 | 3 +++ lib/krb5/send_to_kdc.c | 19 +++++++++++++++++-- 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/lib/krb5/get_cred.c b/lib/krb5/get_cred.c index 334eaaae7..f603e54b6 100644 --- a/lib/krb5/get_cred.c +++ b/lib/krb5/get_cred.c @@ -652,6 +652,11 @@ get_cred_kdc(krb5_context context, krb5_sendto_set_hostname(context, stctx, kdc_hostname); if (sitename) krb5_sendto_set_sitename(context, stctx, sitename); + ret = _krb5_sendto_set_principal(context, stctx, in_creds->client); + if (ret) { + krb5_sendto_ctx_free(context, stctx); + goto out; + } ret = krb5_sendto_context (context, stctx, &enc, krbtgt->server->name.name_string.val[1], diff --git a/lib/krb5/init_creds_pw.c b/lib/krb5/init_creds_pw.c index 701b5f92e..34206c80d 100644 --- a/lib/krb5/init_creds_pw.c +++ b/lib/krb5/init_creds_pw.c @@ -3930,6 +3930,9 @@ krb5_init_creds_get(krb5_context context, krb5_init_creds_context ctx) krb5_sendto_set_hostname(context, stctx, ctx->kdc_hostname); if (ctx->sitename) krb5_sendto_set_sitename(context, stctx, ctx->sitename); + ret = _krb5_sendto_set_principal(context, stctx, ctx->cred.client); + if (ret) + goto out; while (1) { struct timeval nstart, nend; diff --git a/lib/krb5/krb5.conf.5 b/lib/krb5/krb5.conf.5 index d58cdeb8b..4d9d935ad 100644 --- a/lib/krb5/krb5.conf.5 +++ b/lib/krb5/krb5.conf.5 @@ -326,6 +326,9 @@ The KDC hostname is passed to the SOCKS4a proxy verbatim without any DNS resolution first. Other DNS resolution, of the proxy address and for any realm mapping or KDC discovery, may still be done outside the SOCKS4a proxy. +.Pp +The caller's principal is passed as the SOCKS user id in order to +enable stream isolation with Tor. .It Li http_proxy = Va proxy-spec A HTTP-proxy to use when talking to the KDC via HTTP. .It Li dns_proxy = Va proxy-spec diff --git a/lib/krb5/send_to_kdc.c b/lib/krb5/send_to_kdc.c index 0705b92b2..8a9f03e69 100644 --- a/lib/krb5/send_to_kdc.c +++ b/lib/krb5/send_to_kdc.c @@ -153,6 +153,7 @@ struct krb5_sendto_ctx_data { void *data; char *hostname; char *sitename; + char *proxy_userid; krb5_krbhst_handle krbhst; /* context2 */ @@ -185,6 +186,8 @@ dealloc_sendto_ctx(void *ptr) free(ctx->hostname); if (ctx->sitename) free(ctx->sitename); + if (ctx->proxy_userid) + free(ctx->proxy_userid); heim_release(ctx->hosts); heim_release(ctx->krbhst); } @@ -270,6 +273,18 @@ krb5_sendto_set_sitename(krb5_context context, return 0; } +krb5_error_code +_krb5_sendto_set_principal(krb5_context context, + krb5_sendto_ctx ctx, + krb5_const_principal principal) +{ + + if (context->socks4a_proxy == NULL) + return 0; + + return krb5_unparse_name(context, principal, &ctx->proxy_userid); +} + KRB5_LIB_FUNCTION void KRB5_LIB_CALL _krb5_sendto_ctx_set_krb5hst(krb5_context context, krb5_sendto_ctx ctx, @@ -544,7 +559,7 @@ host_connected(krb5_context context, krb5_sendto_ctx ctx, struct host *host) debug_host(context, 5, host, "socks4a proxying"); host->socks4a = NULL; ret = _krb5_socks4a_connect(host_socks4a_io(context, host), - host->hi->hostname, host->hi->port, /*userid*/NULL, + host->hi->hostname, host->hi->port, ctx->proxy_userid, &host->socks4a); if (ret) { host_dead(context, host, "socks4a proxy failed"); @@ -1120,7 +1135,7 @@ submit_request(krb5_context context, krb5_sendto_ctx ctx, krb5_krbhst_info *hi) } if (freeai) - freeai = NULL; + freeaddrinfo(freeai); if (submitted_host == 0) return KRB5_KDC_UNREACH;