Skip to content

Commit

Permalink
Apply patches from Likewise for making smart card work, remove preaut…
Browse files Browse the repository at this point in the history
…h data for initial tgt, add debug flags

QA Notes: 
Testing Done: Tested sandbox builds with pieces from additional builds that needed to be modified as we found bugs.
Documentation Notes: 
Bug Number: 1533873
Reviewed by: erik
Approved by: 
Mailto: vmidentity-checkins
# Set "Merge to" values below to YES, SVS, NO, or MANUAL.
# If you're unsure, ask your manager or your peers, DO NOT guess.
Merge to: main: YES ## status=failed; info=Failed command [integrate];

Copied from Perforce
 Change: 73927
  • Loading branch information
ssalley authored and Jonathan Brown committed Apr 5, 2016
1 parent bf4674c commit d6511c1
Show file tree
Hide file tree
Showing 10 changed files with 169 additions and 42 deletions.
2 changes: 2 additions & 0 deletions krb5-1.13.2/MakeKitBuild
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ make()
HEADERDEPS="openssl/opensslv.h" \
LIBDEPS="ssl crypto" \
CPPFLAGS="$KRB5_CPPFLAGS" \
CFLAGS="-g" \
LDFLAGS="-g" \
HEADERS='krb5.h gssapi.h gssapi/gssapi_ext.h' \
LIBS='krb5 gssapi_krb5 k5crypto' \
--enable-shared \
Expand Down
26 changes: 25 additions & 1 deletion krb5-1.13.2/src/include/k5-int.h
Original file line number Diff line number Diff line change
Expand Up @@ -1772,14 +1772,38 @@ krb5int_random_string(krb5_context, char *string, unsigned int length);

/* To keep happy libraries which are (for now) accessing internal stuff */

/* !!!!!! DUPLICATION
The following are duplicated because I don't know how else to make them available.
*/
struct srv_dns_entry {
struct srv_dns_entry *next;
int priority;
int weight;
unsigned short port;
char *host;
};

krb5_error_code krb5int_make_srv_query_realm(const krb5_data *realm,
const char *service,
const char *protocol,
struct srv_dns_entry **answers);
void krb5int_free_srv_dns_data(struct srv_dns_entry *);
/* !!!!!! DUPLICATION */

/* Make sure to increment by one when changing the struct */
#define KRB5INT_ACCESS_STRUCT_VERSION 21
#define KRB5INT_ACCESS_STRUCT_VERSION 22

typedef struct _krb5int_access {
krb5_error_code (*auth_con_get_subkey_enctype)(krb5_context,
krb5_auth_context,
krb5_enctype *);

krb5_error_code (*make_srv_query_realm)(const krb5_data *realm,
const char *service,
const char *protocol,
struct srv_dns_entry **answers);
void (*free_srv_dns_data)(struct srv_dns_entry *);

krb5_error_code (*clean_hostname)(krb5_context, const char *, char *,
size_t);

Expand Down
9 changes: 9 additions & 0 deletions krb5-1.13.2/src/lib/krb5/os/accessor.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@ krb5int_accessor(krb5int_access *internals, krb5_int32 version)

S (clean_hostname, k5_clean_hostname),

#ifdef KRB5_DNS_LOOKUP
#define SC(FIELD, VAL) S(FIELD, VAL)
#else /* disable */
#define SC(FIELD, VAL) S(FIELD, 0)
#endif
SC (make_srv_query_realm, krb5int_make_srv_query_realm),
SC (free_srv_dns_data, krb5int_free_srv_dns_data),
#undef SC

#ifndef LEAN_CLIENT
#define SC(FIELD, VAL) S(FIELD, VAL)
#else /* disable */
Expand Down
14 changes: 0 additions & 14 deletions krb5-1.13.2/src/lib/krb5/os/dnsglue.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,19 +155,5 @@ int krb5int_dns_expand(struct krb5int_dns_state *,
const unsigned char *, char *, int);
void krb5int_dns_fini(struct krb5int_dns_state *);

struct srv_dns_entry {
struct srv_dns_entry *next;
int priority;
int weight;
unsigned short port;
char *host;
};

krb5_error_code krb5int_make_srv_query_realm(const krb5_data *realm,
const char *service,
const char *protocol,
struct srv_dns_entry **answers);
void krb5int_free_srv_dns_data(struct srv_dns_entry *);

#endif /* KRB5_DNS_LOOKUP */
#endif /* !defined(KRB5_DNSGLUE_H) */
2 changes: 2 additions & 0 deletions krb5-1.13.2/src/plugins/preauth/pkinit/pkinit.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#define DEBUG
/*
* COPYRIGHT (C) 2006,2007
* THE REGENTS OF THE UNIVERSITY OF MICHIGAN
Expand Down Expand Up @@ -31,6 +32,7 @@
#ifndef _PKINIT_H
#define _PKINIT_H

#include <autoconf.h>
#include <k5-platform.h>
#include <krb5/krb5.h>
#include <krb5/preauth_plugin.h>
Expand Down
6 changes: 6 additions & 0 deletions krb5-1.13.2/src/plugins/preauth/pkinit/pkinit_accessor.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ void KRB5_CALLCONV
void
(*k5int_set_prompt_types)(krb5_context, krb5_prompt_type *);

krb5_error_code (*k5int_make_srv_query_realm)
(const krb5_data *realm, const char *service,
const char *protocol, struct srv_dns_entry **answers);
void (*k5int_free_srv_dns_data)(struct srv_dns_entry *);

/*
* Grab internal function pointers from the krb5int_accessor
Expand Down Expand Up @@ -118,5 +122,7 @@ pkinit_accessor_init(void)
k5int.encode_krb5_pa_pk_as_rep_draft9;
k5int_krb5_free_kdc_req = k5int.free_kdc_req;
k5int_set_prompt_types = k5int.set_prompt_types;
k5int_make_srv_query_realm = k5int.make_srv_query_realm;
k5int_free_srv_dns_data = k5int.free_srv_dns_data;
return 0;
}
6 changes: 6 additions & 0 deletions krb5-1.13.2/src/plugins/preauth/pkinit/pkinit_accessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,10 @@ extern void KRB5_CALLCONV (*k5int_krb5_free_kdc_req)
extern void (*k5int_set_prompt_types)
(krb5_context, krb5_prompt_type *);

struct srv_dns_entry;
extern krb5_error_code (*k5int_make_srv_query_realm)
(const krb5_data *realm, const char *service,
const char *protocol, struct srv_dns_entry **answers);
extern void (*k5int_free_srv_dns_data)(struct srv_dns_entry *);

#endif /* _PKINIT_ACCESSOR_H */
54 changes: 51 additions & 3 deletions krb5-1.13.2/src/plugins/preauth/pkinit/pkinit_clnt.c
Original file line number Diff line number Diff line change
Expand Up @@ -466,13 +466,16 @@ verify_kdc_san(krb5_context context,
char **certhosts = NULL, **cfghosts = NULL, **hostptr;
krb5_principal *princs = NULL, *princptr;
unsigned char ***get_dns;
struct srv_dns_entry *kdc_dns_entries = NULL;
const char *kdc_realm = NULL;
int i, j;

*valid_san = 0;
*need_eku_checking = 1;

kdc_realm = krb5_princ_realm(context, kdcprinc);
retval = pkinit_libdefault_strings(context,
krb5_princ_realm(context, kdcprinc),
kdc_realm,
KRB5_CONF_PKINIT_KDC_HOSTNAME,
&cfghosts);
if (retval || cfghosts == NULL) {
Expand All @@ -496,8 +499,10 @@ verify_kdc_san(krb5_context context,
retval = KRB5KDC_ERR_KDC_NAME_MISMATCH;
goto out;
}
for (princptr = princs; *princptr != NULL; princptr++)
TRACE_PKINIT_CLIENT_SAN_KDCCERT_PRINC(context, *princptr);
if (princs != NULL) {
for (princptr = princs; *princptr != NULL; princptr++)
TRACE_PKINIT_CLIENT_SAN_KDCCERT_PRINC(context, *princptr);
}
if (certhosts != NULL) {
for (hostptr = certhosts; *hostptr != NULL; hostptr++)
TRACE_PKINIT_CLIENT_SAN_KDCCERT_DNSNAME(context, *hostptr);
Expand Down Expand Up @@ -543,6 +548,46 @@ verify_kdc_san(krb5_context context,

for (i = 0; certhosts[i] != NULL; i++) {
for (j = 0; cfghosts != NULL && cfghosts[j] != NULL; j++) {
if (!strcmp(cfghosts[j], "<DNS>")) {
#ifdef KRB5_DNS_LOOKUP
struct srv_dns_entry *entry;

if (kdc_dns_entries == NULL) {
if (k5int_make_srv_query_realm(kdc_realm,
"_kerberos", "_tcp", &kdc_dns_entries)) {
pkiDebug("%s: DNS lookup failed\n", __FUNCTION__);
continue;
}

/* Remove trailing dot from DNS names. */
for (entry = kdc_dns_entries; entry != NULL;
entry = entry->next) {
char *cp = strrchr(entry->host, '.');

if (cp != NULL && cp[1] == '\0') {
*cp = '\0';
}
}
}

for (entry = kdc_dns_entries; entry != NULL;
entry = entry->next) {
pkiDebug("%s: comparing cert name '%s' with DNS name '%s'\n",
__FUNCTION__, certhosts[i], entry->host);
if (!strcasecmp(certhosts[i], entry->host)) {
pkiDebug("%s: we have a dnsName match\n", __FUNCTION__);
*valid_san = 1;
retval = 0;
goto out;
}
}
#else /* KRB5_DNS_LOOKUP */
pkiDebug("%s: <DNS> tag used but DNS lookup not enabled in build\n",
__FUNCTION__);
#endif /* KRB5_DNS_LOOKUP */

continue;
}
pkiDebug("%s: comparing cert name '%s' with config name '%s'\n",
__FUNCTION__, certhosts[i], cfghosts[j]);
if (strcasecmp(certhosts[i], cfghosts[j]) == 0) {
Expand Down Expand Up @@ -573,6 +618,9 @@ verify_kdc_san(krb5_context context,
}
if (cfghosts != NULL)
profile_free_list(cfghosts);
if (kdc_dns_entries != NULL) {
k5int_free_srv_dns_data(kdc_dns_entries);
}

pkiDebug("%s: returning retval %d, valid_san %d, need_eku_checking %d\n",
__FUNCTION__, retval, *valid_san, *need_eku_checking);
Expand Down
90 changes: 67 additions & 23 deletions krb5-1.13.2/src/plugins/preauth/pkinit/pkinit_matching.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ relation2string(unsigned int rel)
typedef enum {
kwvaltype_undefined = 0,
kwvaltype_regexp = 1,
kwvaltype_list = 2
kwvaltype_list = 2,
kwvaltype_principal = 3,
} kw_value_type;

static char *
Expand All @@ -101,11 +102,12 @@ struct keyword_desc {
keyword_type kwtype;
kw_value_type kwvaltype;
} matching_keywords[] = {
{ "<KU>", 4, kw_ku, kwvaltype_list },
{ "<EKU>", 5, kw_eku, kwvaltype_list },
{ "<SAN>", 5, kw_san, kwvaltype_regexp },
{ "<ISSUER>", 8, kw_issuer, kwvaltype_regexp },
{ "<SUBJECT>", 9, kw_subject, kwvaltype_regexp },
{ "<KU>", 4, kw_ku, kwvaltype_list },
{ "<EKU>", 5, kw_eku, kwvaltype_list },
{ "<SAN>", 5, kw_san, kwvaltype_regexp },
{ "<ISSUER>", 8, kw_issuer, kwvaltype_regexp },
{ "<SUBJECT>", 9, kw_subject, kwvaltype_regexp },
{ "<PRINCIPAL>", 11, kw_subject, kwvaltype_principal },
{ NULL, 0, kw_undefined, kwvaltype_undefined},
};

Expand Down Expand Up @@ -322,18 +324,19 @@ parse_rule_component(krb5_context context,
else
len = (*remaining);

if (len == 0) {
if (len == 0 && kw->kwvaltype != kwvaltype_principal) {
pkiDebug("%s: Missing value for keyword '%s'\n",
__FUNCTION__, kw->value);
retval = EINVAL;
goto out;
} else {
value = calloc(1, len+1);
if (value == NULL ) {
retval = ENOMEM;
goto out;
}
}

value = calloc(1, len+1);
if (value == NULL) {
retval = ENOMEM;
goto out;
}
memcpy(value, *rule, len);
*remaining -= len;
*rule += len;
Expand Down Expand Up @@ -466,7 +469,8 @@ regexp_match(krb5_context context, rule_component *rc, char *value)
static int
component_match(krb5_context context,
rule_component *rc,
pkinit_cert_matching_data *md)
pkinit_cert_matching_data *md,
krb5_principal princ)
{
int match = 0;
int i;
Expand Down Expand Up @@ -523,6 +527,29 @@ component_match(krb5_context context,
break;
}
break;
case kwvaltype_principal:
if (md->sans == NULL)
break;
#ifdef DEBUG
krb5_unparse_name(context, princ, &princ_string);
#endif
for (i = 0, p = md->sans[i]; p != NULL; p = md->sans[++i]) {
#ifdef DEBUG
char *san_string;

krb5_unparse_name(context, p, &san_string);
pkiDebug("%s: comparing principal '%s' with cert SAN '%s'\n",
__FUNCTION__, princ_string, san_string);
#endif
if (krb5_principal_compare_flags(context, p, princ,
KRB5_PRINCIPAL_COMPARE_CASEFOLD)) {
match = 1;
break;
}
if (match)
break;
}
break;
default:
pkiDebug("%s: unknown keyword value type %d\n",
__FUNCTION__, rc->kwval_type);
Expand Down Expand Up @@ -554,6 +581,8 @@ check_all_certs(krb5_context context,
rule_component *rc;
int certs_checked = 0;
pkinit_cert_matching_data *save_match = NULL;
char *princ_string = NULL;
char *princ_realm = NULL;

if (match_found == NULL || matching_cert == NULL)
return EINVAL;
Expand All @@ -564,24 +593,34 @@ check_all_certs(krb5_context context,
pkiDebug("%s: matching rule relation is %s with %d components\n",
__FUNCTION__, relation2string(rs->relation), rs->num_crs);

if (princ)
{
retval = krb5_unparse_name(context, princ, &princ_string);
if (retval || princ_string == NULL) {
return EINVAL;
}

princ_realm = strchr(princ_string, '@');

if (princ_realm == NULL) {
krb5_free_unparsed_name(context, princ_string);
return EINVAL;
}

*princ_realm++ = '\0';
}

/*
* Loop through all the certs available and count
* how many match the rule
*/
for (i = 0, md = matchdata[i]; md != NULL; md = matchdata[++i]) {
pkiDebug("%s: subject: '%s'\n", __FUNCTION__, md->subject_dn);
#if 0
pkiDebug("%s: issuer: '%s'\n", __FUNCTION__, md->subject_dn);
for (j = 0, p = md->sans[j]; p != NULL; p = md->sans[++j]) {
char *san_string;
krb5_unparse_name(context, p, &san_string);
pkiDebug("%s: san: '%s'\n", __FUNCTION__, san_string);
krb5_free_unparsed_name(context, san_string);
}
#endif
pkiDebug("%s: issuer: '%s'\n", __FUNCTION__, md->issuer_dn);

certs_checked++;
for (rc = rs->crs; rc != NULL; rc = rc->next) {
comp_match = component_match(context, rc, md);
comp_match = component_match(context, rc, md, princ);
if (comp_match) {
pkiDebug("%s: match for keyword type %s\n",
__FUNCTION__, keyword2string(rc->kw_type));
Expand All @@ -607,6 +646,11 @@ check_all_certs(krb5_context context,
nextcert:
continue;
}

if (princ_string) {
krb5_free_unparsed_name(context, princ_string);
}

pkiDebug("%s: After checking %d certs, we found %d matches\n",
__FUNCTION__, certs_checked, total_cert_matches);
if (total_cert_matches == 1) {
Expand Down
2 changes: 1 addition & 1 deletion lwadvapi/threaded/krbtgt.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ LwKrb5GetTgtWithSmartCard(
pszCcPath,
pdwGoodUntilTime,
pPreauthTypes,
sizeof(pPreauthTypes) / sizeof(pPreauthTypes[0]),
0, //sizeof(pPreauthTypes) / sizeof(pPreauthTypes[0]),
cbKrb5Prompter,
pvPrompterData
);
Expand Down

0 comments on commit d6511c1

Please sign in to comment.