Optional backwards-compatible anon-pkinit behaviour

* Anonymous pkinit responses from the KDC where the name
  type is not well-known (as issued by 7.5 KDCs and earlier)
  are accepted by the client.  There is no need for the client
  to strictly enforce the name type.

* With historical_anon_pkinit = true, the kinit(1) client's
  "--anonymous" option only performs anon pkinit, and does
  not require an '@' prefix for the realm argument.

* With historical_anon_realm = true, the KDC issues anon
  pkinit tickets with the legacy pre-7.0 "real" realm.
This commit is contained in:
Viktor Dukhovni
2019-07-14 23:02:57 -04:00
committed by Viktor Dukhovni
parent f40d393c83
commit fae8df3839
11 changed files with 141 additions and 27 deletions

View File

@@ -166,11 +166,21 @@ in
.It Fl A , Fl Fl no-addresses
Request a ticket with no addresses.
.It Fl n , Fl Fl anonymous
Request an anonymous ticket. If the principal is specified as @REALM, then
Request an anonymous ticket.
With the default (false) setting of the
.Ar historical_anon_pkinit
configuration parameter, if the principal is specified as @REALM, then
anonymous PKINIT will be used to acquire an unauthenticated anonymous ticket
and both the client name and realm in the returned ticket will be anonymized.
and both the client name and (with fully RFC-comformant KDCs) realm in the
returned ticket will be anonymized.
Otherwise, authentication proceeds as normal and the anonymous ticket will have
only the client name anonymized.
With
.Ar historical_anon_pkinit
set to
.Li true ,
the principal is interpreted as a realm even without an at-sign prefix, and it
is not possible to obtain authenticated anonymized tickets.
.It Fl Fl enterprise
Parse principal as a enterprise (KRB5-NT-ENTERPRISE) name. Enterprise
names are email like principals that are stored in the name part of

View File

@@ -669,7 +669,7 @@ get_new_tickets(krb5_context context,
}
} else if (pk_user_id || ent_user_id ||
krb5_principal_is_anonymous(context, principal, KRB5_ANON_MATCH_ANY)) {
/* nop */;
} else if (!interactive && passwd[0] == '\0') {
static int already_warned = 0;
@@ -1272,6 +1272,7 @@ main(int argc, char **argv)
struct sigaction sa;
#endif
krb5_boolean unique_ccache = FALSE;
krb5_boolean historical_anon_pkinit = FALSE;
int anonymous_pkinit = FALSE;
setprogname(argv[0]);
@@ -1300,6 +1301,9 @@ main(int argc, char **argv)
argc -= optidx;
argv += optidx;
krb5_appdefault_boolean(context, "kinit", NULL, "historical_anon_pkinit",
FALSE, &historical_anon_pkinit);
/*
* Open the keytab now, we use the keytab to determine the principal's
* realm when the requested principal has no realm.
@@ -1332,6 +1336,16 @@ main(int argc, char **argv)
krb5_err(context, 1, ret, "krb5_make_principal");
krb5_principal_set_type(context, principal, KRB5_NT_WELLKNOWN);
anonymous_pkinit = TRUE;
} else if (anonymous_flag && historical_anon_pkinit) {
char *realm = argc == 0 ? get_default_realm(context) :
argv[0][0] == '@' ? &argv[0][1] : argv[0];
ret = krb5_make_principal(context, &principal, realm,
KRB5_WELLKNOWN_NAME, KRB5_ANON_NAME, NULL);
if (ret)
krb5_err(context, 1, ret, "krb5_make_principal");
krb5_principal_set_type(context, principal, KRB5_NT_WELLKNOWN);
anonymous_pkinit = TRUE;
} else if (use_keytab || keytab_str) {
get_princ_kt(context, &principal, argv[0]);
} else {