159 lines
5.2 KiB
Diff
159 lines
5.2 KiB
Diff
From c58836f29dbff9bda9ecb307329fc11942b9d0e0 Mon Sep 17 00:00:00 2001
|
|
From: Simo Sorce <ssorce@redhat.com>
|
|
Date: Fri, 13 Jul 2012 12:19:03 -0400
|
|
Subject: [PATCH 74/79] Add PAC filtering
|
|
|
|
This check the PAC we receive is consistent.
|
|
realm, flat name and domain sid must much our understanding or the trustd
|
|
realm and no additional sids beyond the own realm ones must be present.
|
|
|
|
Ticket #2849
|
|
---
|
|
daemons/ipa-kdb/ipa_kdb_mspac.c | 108 +++++++++++++++++++++++++++++++++++++---
|
|
1 file changed, 100 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c
|
|
index 2a48c4f8ca7cee30d01380fbc12dddb928472963..b5346fed1230d02a88c94ab913507112990a1651 100644
|
|
--- a/daemons/ipa-kdb/ipa_kdb_mspac.c
|
|
+++ b/daemons/ipa-kdb/ipa_kdb_mspac.c
|
|
@@ -977,7 +977,101 @@ static krb5_error_code save_logon_info(krb5_context context,
|
|
return 0;
|
|
}
|
|
|
|
+static struct ipadb_adtrusts *get_domain_from_realm(krb5_context context,
|
|
+ krb5_data realm)
|
|
+{
|
|
+ struct ipadb_context *ipactx;
|
|
+ struct ipadb_adtrusts *domain;
|
|
+ int i;
|
|
+
|
|
+ ipactx = ipadb_get_context(context);
|
|
+ if (!ipactx) {
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ if (ipactx->mspac == NULL) {
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ for (i = 0; i < ipactx->mspac->num_trusts; i++) {
|
|
+ domain = &ipactx->mspac->trusts[i];
|
|
+ if (strlen(domain->domain_name) != realm.length) {
|
|
+ continue;
|
|
+ }
|
|
+ if (strncasecmp(domain->domain_name, realm.data, realm.length) == 0) {
|
|
+ return domain;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
+static krb5_error_code filter_logon_info(krb5_context context,
|
|
+ TALLOC_CTX *memctx,
|
|
+ krb5_data realm,
|
|
+ struct PAC_LOGON_INFO_CTR *info)
|
|
+{
|
|
+
|
|
+ /* We must refuse a PAC that comes signed with a cross realm TGT
|
|
+ * where the client pretends to be from a different realm. It is an
|
|
+ * attempt at getting us to sign fake credentials with the help of a
|
|
+ * compromised trusted realm */
|
|
+
|
|
+ struct ipadb_adtrusts *domain;
|
|
+ char *domsid;
|
|
+
|
|
+ domain = get_domain_from_realm(context, realm);
|
|
+ if (!domain) {
|
|
+ return EINVAL;
|
|
+ }
|
|
+
|
|
+ /* check netbios/flat name */
|
|
+ if (strcasecmp(info->info->info3.base.logon_domain.string,
|
|
+ domain->flat_name) != 0) {
|
|
+ krb5_klog_syslog(LOG_ERR, "PAC Info mismatch: domain = %s, "
|
|
+ "expected flat name = %s, "
|
|
+ "found logon name = %s",
|
|
+ domain->domain_name, domain->flat_name,
|
|
+ info->info->info3.base.logon_domain.string);
|
|
+ return EINVAL;
|
|
+ }
|
|
+
|
|
+ /* check sid */
|
|
+ domsid = dom_sid_string(NULL, info->info->info3.base.domain_sid);
|
|
+ if (!domsid) {
|
|
+ return EINVAL;
|
|
+ }
|
|
+
|
|
+ if (strcmp(domsid, domain->domain_sid) != 0) {
|
|
+ krb5_klog_syslog(LOG_ERR, "PAC Info mismatch: domain = %s, "
|
|
+ "expected domain SID = %s, "
|
|
+ "found domain SID = %s",
|
|
+ domain->domain_name, domain->domain_sid,
|
|
+ domsid);
|
|
+ talloc_free(domsid);
|
|
+ return EINVAL;
|
|
+ }
|
|
+ talloc_free(domsid);
|
|
+
|
|
+ /* According to MS-KILE, info->info->info3.sids must be zero, so check
|
|
+ * that it is the case here */
|
|
+ if (info->info->info3.sidcount != 0) {
|
|
+ return EINVAL;
|
|
+ }
|
|
+
|
|
+ /* According to MS-KILE, ResourceGroups must be zero, so check
|
|
+ * that it is the case here */
|
|
+ if (info->info->res_group_dom_sid != NULL &&
|
|
+ info->info->res_groups.count != 0) {
|
|
+ return EINVAL;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
static krb5_error_code ipadb_check_logon_info(krb5_context context,
|
|
+ krb5_data origin_realm,
|
|
krb5_data *pac_blob)
|
|
{
|
|
struct PAC_LOGON_INFO_CTR info;
|
|
@@ -994,6 +1088,11 @@ static krb5_error_code ipadb_check_logon_info(krb5_context context,
|
|
goto done;
|
|
}
|
|
|
|
+ kerr = filter_logon_info(context, tmpctx, origin_realm, &info);
|
|
+ if (kerr) {
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
kerr = add_local_groups(context, tmpctx, &info);
|
|
if (kerr) {
|
|
goto done;
|
|
@@ -1050,13 +1149,6 @@ static krb5_error_code ipadb_verify_pac(krb5_context context,
|
|
/* krbtgt from a trusted realm */
|
|
is_cross_realm = true;
|
|
|
|
- /* FIXME:
|
|
- * We must refuse a PAC that comes signed with a cross realm TGT
|
|
- * where the client pretends to be from our realm. It is an attempt
|
|
- * at getting us to sign fake credentials with the help of a
|
|
- * compromised trusted realm */
|
|
-
|
|
- /* TODO: Here is where we need to plug our PAC Filtering, later on */
|
|
srv_key = krbtgt_key;
|
|
|
|
} else {
|
|
@@ -1079,7 +1171,7 @@ static krb5_error_code ipadb_verify_pac(krb5_context context,
|
|
goto done;
|
|
}
|
|
|
|
- kerr = ipadb_check_logon_info(context, &pac_blob);
|
|
+ kerr = ipadb_check_logon_info(context, client_princ->realm, &pac_blob);
|
|
if (kerr != 0) {
|
|
goto done;
|
|
}
|
|
--
|
|
1.7.11.2
|
|
|