Commit Graph

504 Commits

Author SHA1 Message Date
Luke Howard
5b7cf5d56f kdc: centralize include PAC logic
Add a helper function that returns TRUE if a PAC should be included in ticket
authorization data, that can be called from both AS and TGS paths.

Per [MS-KILE] 3.3.5.3, PACs are always included for TGTs; for service
tickets, policy is governed by whether the client explicitly requested
a PAC be omitted when requesting a TGT, or if the no-auth-data-reqd
flag is set on the service principal entry.
2021-12-23 13:52:15 +11:00
Luke Howard
ebd7092dff kdc: distinguish long-term key from replacing reply key
Distinguish pre-authentication mechanisms that replace the reply key from those
that use the client's long-term key. In the general case, one is the inverse of
the other, however KRB5_PADATA_ENCRYPTED_CHALLENGE replaces the reply-key with
one derived from the long-term key.

PA_REPLACE_REPLY_KEY indicates that the kvno should be set to zero in the
reply; the absence of PA_USES_LONG_TERM_KEY indicates that the client's
long-term key may be included in the PAC (PAC_CREDENTIAL_INFO with Samba only).

Corrects e8984871.
2021-12-23 11:24:35 +11:00
Luke Howard
bdb3e1020c Revert "kdc: distinguish long-term key from replacing reply key"
This reverts commit e89848719a.

(Reverting: typo.)
2021-12-23 11:24:00 +11:00
Luke Howard
e89848719a kdc: distinguish long-term key from replacing reply key
Distinguish pre-authentication mechanisms that replace the reply key from those
that use the client's long-term key. In the general case, one is the inverse of
the other, however KRB5_PADATA_ENCRYPTED_CHALLENGE replaces the reply-key with
one derived from the long-term key.

PA_REPLACE_REPLY_KEY indicates that the kvno should be set to zero in the
reply; the absence of PA_USES_LONG_TERM_KEY indicates that the client's
long-term key may be included in the PAC (PAC_CREDENTIAL_INFO with Samba only).
2021-12-23 11:21:30 +11:00
Luke Howard
357c73e013 kdc: avoid linear search of PA types
Store a dispatch table pointer for the used pre-authentication type to avoid
needing to traverse the table.
2021-12-23 11:04:38 +11:00
Luke Howard
f18c9e06a8 kdc: honor PAC_ATTRIBUTES in presented TGT
PACs are included when issuing TGTs, if there is no PAC_ATTRIBUTES buffer
(legacy behavior) or if the attributes buffer indicates the AS client requested
one.
2021-12-22 17:13:13 +11:00
Luke Howard
b4f3617964 kdc: don't add PAC_ATTRIBUTES PAC buffer for service tickets
Only include the PAC_ATTRIBUTES PAC info buffer if we are issuing a TGT, as its
contents are not relevant to application services. (The buffer contains a bit
indicating whether the client explicitly or implicitly requested a PAC.)
2021-12-22 16:38:52 +11:00
Luke Howard
8590499b53 kdc: include SID in PAC with GSS authorizer
Update the sample GSS pre-authentication authorizer plugin to allow the PAC to
be pinned to the authenticating user's SID.

There is still a race condition between the time the user authenticates and the
time the SID is looked up via LDAP, but it should be sufficient as an example;
if more security is required, then users should be enrolled with their SIDs.
2021-12-22 10:36:26 +11:00
Luke Howard
a2c225fe0a kdc: add PA PAC finalize callback
Note the selected pre-authentication mechanism, and add a callback to allow the
pre-authentication mechanism to update the PAC immediately prior to signing.
2021-12-22 10:36:26 +11:00
Luke Howard
f7964251ff kdc: support for PAC_ATTRIBUTES_INFO
Add PAC_ATTRIBUTES_INFO to the PAC. This info buffer indicates whether the user
explicitly requested a PAC be present or absent.

Note: this changes the windc plugin ABI.
2021-12-22 10:36:26 +11:00
Luke Howard
e50033aec2 kdc: add canonical principal name to authz data
Use the UPN_DNS_INFO buffer of the PAC to include the canonical principal name.

Arguably we should use AD-LOGIN-ALIAS as defined in RFC6806, but we may not
always know all the principal's aliases, and this approach allows us to share
application service logic with Windows.
2021-12-22 10:36:26 +11:00
Luke Howard
a3392b099e kdc: allow cross-realm FAST armor TGT
08e0305b introduced a patch to validate armor ticket PACs, but required that
the armor client principal was in the local realm (as it did not allow
_kdc_db_fetch() to fail).

Allow cross-realm FAST armor clients by using the same logic to look up the
client principal as the TGS itself does, i.e. use db_fetch_client() which
handles the case where the client is not local to the KDC.

Note: the armor PAC is only required to be validated when issuing a final,
non-referral service ticket, as this is the only point upon which device claims
should be inserted (according to my understanding).

Closes: #901
2021-12-18 15:09:38 +11:00
Luke Howard
e7588952ce kdc: add auth data type for synthetic principals
Add a new authorization data type to indicate a synthetic principal was used,
to allow synthetic clients acquired outside of PKINIT (e.g. with GSS-API
pre-authentication) to use the TGS.

Note: we continue to honor KRB5_AUTHDATA_INITIAL_VERIFIED_CAS to indicate that
it is OK for the client to be synthetic, even though it is only an indication
that the client *may* have been synthetic.
2021-12-18 15:09:38 +11:00
Nicolas Williams
27d6526e3a kdc: Check unparse_flags() result differently 2021-12-18 11:34:12 +11:00
Luke Howard
e0929d16b7 kdc: don't leak msg in pa_enc_chal_validate()
Move initialization of msg in pa_enc_chal_validate() to avoid leak on invalid
password.
2021-12-17 13:41:55 +11:00
Luke Howard
5d92219788 kdc: set kvno to zero if reply key replaced
If the pre-authentication mechanism replaced the reply key, then the kvno in
the KDC-REP should be zero, as the reply is not encrypted in the client's
(versioned) long-term key.

Closes: #899
2021-12-17 13:27:31 +11:00
Andrew Bartlett
4a2e40a5b6 kdc: Use HDB_AUTHSTATUS_INVALID to mark that the status has not be set yet
-1 is unclear, so use a named constant.

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
2021-12-17 13:19:52 +11:00
Andrew Bartlett
93deac696f hdb: Improve naming of constants for hdb_auth_status()
We drop the unused HDB_AUTH_INVALID_SIGNATURE and
rebase the set to start at an invalid 0.

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
2021-12-17 13:19:52 +11:00
Joseph Sutton
49420aa3a1 kdc: Don't return PREAUTH_FAILED if encrypted challenge did not fail to decrypt
Instead we return ETYPE_NOSUPP.

Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
2021-12-17 13:19:52 +11:00
Andrew Bartlett
842b856e4c kdc: Pass extra information to hdb_auth_status() to log success and failures
We now pass on the original client name and the client address to allow
consistent audit logging in Samba across multiple protocols.

We also log the authentication duration.

This is not a general purpose profiling solution, but in Smaba
these JSON logs are already being generated and stored, so this
is worth adding.

Some administrators are very keen to know how long authentication
takes, particularly due to long replication transactions in other
Samba processes.

We use config->db[0] to find the first database to record incorrect
users.

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
(Similar to Samba commit f498ba77df2313e78863e5f2706840c43e232a96 and
 bb2a1c6b3eaccf114ac3f3b5b51f57828a04996)
[metze@samba.org: improved for heimdal upstream]
Signed-off-by: Stefan Metzmacher <metze@samba.org>
[abartlet@samba.org: improved again for Heimdal based on feedback]
2021-12-17 13:19:52 +11:00
Joseph Sutton
91e86460cd kdc: Add krb5_is_enctype_old() to determine whether an enctype is older
AES256 and AES128 are newer enctypes because they are officially
specified in RFC4120 and RFC8009, while enctypes not officially
specified since RFC4120 are considered older. This function differs from
older_enctype() in that it does not report unknown or non-existent
enctypes as being 'newer'.

Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
2021-12-16 16:11:29 +11:00
Joseph Sutton
c0fa930590 kdc: Don't advertise padata types that will not be accepted
Instead of always advertising PADATA-ENCRYPTED-CHALLENGE, we only
advertise it if FAST is in use.

We also check configuration options to only advertise
PADATA-ENC-TIMESTAMP if it will be accepted based on whether FAST is
currently in use. This permits the non-RFC behaviour required to avoid
breaking earlier Heimdal clients.

This incorporates changes from Apple Heimdal-597.140.2.

Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
2021-12-16 10:49:15 +11:00
Joseph Sutton
54129c319c kdc: Don't keep trying keys for encrypted-challenge if one decrypts but fails to verify
This also enables a KRB5KRB_AP_ERR_SKEW error to be returned to the
client.

Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
2021-12-14 17:55:54 +11:00
Nicolas Williams
660f875a34 kdc: Add [kdc] params to control PA-ENC-TIMESTAMP 2021-12-14 17:32:20 +11:00
Luke Howard
2087e07c1e kdc: update PAC hooks for Samba
Samba includes the user's long-term credentials (encrypted in the AS reply key)
to allow legacy authentication protocols such as NTLM to work even if the
pre-authentication mechanism replaced the reply key (as PKINIT does).

Samba also needs to know whether the client explicitly requested a PAC be
included (or excluded), in order to defer PAC exclusion until a service ticket
is issued (thereby avoiding a name binding attack if the user is renamed
between TGT and service ticket issuance).

References:

https://bugzilla.samba.org/show_bug.cgi?id=11441
https://bugzilla.samba.org/show_bug.cgi?id=14561

Closes: #864

Original authors:
 - Joseph Sutton <josephsutton@catalyst.net.nz>
 - Andrew Bartlett <abartlet@samba.org>
 - Stefan Metzmacher <metze@samba.org>
2021-12-14 13:51:53 +11:00
Luke Howard
007cc9fdc3 kdc: remove temporary krb5_context variable
Use r->context (from request) instead of a temporary context variable, where
available.
2021-12-14 09:03:42 +11:00
Luke Howard
9b55215a2a kdc: sync KDC FAST with Heimdal-597.121.1
Import KDC FAST from Apple's Heimdal-597.121.1, adding support for:

  - PA-ENC-CHALLENGE
  - reply key strengthening
  - FAST authentication in TGS

kuser: Apple sync (squash)

krb5_init_creds_store_config/krb5_init_creds_warn_user in kinit
2021-12-14 09:03:42 +11:00
Nicolas Williams
7672ad31db kdc: Fix leak and loss of kdc_check_flags() reason
We were losing and leaking the reason for which kdc_check_flags() was
rejecting any S4U requests, yielding incomplete error messages.

The issue is that kdc_check_flags() wants to check the client and server
principals in the input state structure, but doesn't know about
impersonated principal name, and so we want to pass it a state structure
that has the impersonated instead of the impersonator client name.  This
is a bad design, but I'm ignoring that for now and just fixing this one
leak.
2021-10-11 13:58:15 -05:00
Luke Howard
e7863e2af9 kdc: correctly generate PAC TGS signature
When generating an AS-REQ, the TGS signature was incorrectly generated using
the server key, which would fail to validate if the server was not also the
TGS. Fix this.

Patch from Isaac Bourkis <iboukris@gmail.com>.
2021-09-23 17:51:51 +10:00
Luke Howard
3b0856cab2 kdc: use ticket client name when signing PAC
The principal in the PAC_LOGON_NAME buffer is expected to match the client name
in the ticket. Previously we were setting this to the canonical client name,
which would have broken PAC validation if the client did not request name
canonicalization
2021-09-23 14:39:35 +10:00
Isaac Boukris
2ffaba9401 kdc: sign ticket using Windows PAC
Split Windows PAC signing and verification logic, as the signing has to be when
the ticket is ready.

Create sign and verify the PAC KDC signature if the plugin did not, allowing
for S4U2Proxy to work, instead of KRB5SignedPath.

Use the header key to verify PAC server signature, as the same key used to
encrypt/decrypt the ticket should be used for PAC server signature, like U2U
tickets are signed witht the tgt session-key and not with the longterm key,
and so krbtgt should be no different and the header key should be used.

Lookup the delegated client in DB instead of passing the delegator DB entry.

Add PAC ticket-signatures and related functions.

Note: due to the change from KRB5SignedPath to PAC, S4U2Proxy requests
against new KDC will not work if the evidence ticket was acquired from
an old KDC, and vide versa.

Closes: #767
2021-09-19 13:25:27 +10:00
Isaac Boukris
bb1d8f2a8c kdc: remove KRB5SignedPath, to be replaced with PAC
KRB5SignedPath was a Heimdal-specific authorization data element used to
protect the authenticity of evidence tickets when used in constrained
delegation (without a Windows PAC).

Remove this, to be replaced with the Windows PAC which itself now supports
signing the entire ticket in the TGS key.
2021-09-19 13:02:12 +10:00
Luke Howard
892a1ffcaa kdc: KRB5KDC_ERR_{C,S}_PRINCIPAL_UNKNOWN if missing field
If missing cname or sname in AS-REQ, return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN and
KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN. This matches MIT behaviour.
2021-08-27 11:45:41 +10:00
Luke Howard
df9e74b292 kdc: allow GSS error tokens in PA reply
If GSS_Accept_sec_context() returns an error status and error token, ensure we
include the error token in the PA-GSS padata in the KRB-ERROR reply, rather
than bailing out early.
2021-08-15 15:40:59 +10:00
Luke Howard
49f3f5bd99 kdc: support for GSS-API pre-authentication
Add support for GSS-API pre-authentication to the KDC, using a simplified
variation of draft-perez-krb-wg-gss-preauth-02 that encodes GSS-API context
tokens directly in PADATA, and uses FX-COOKIE for state management.

More information on the protocol and implementation may be found in
lib/gssapi/preauth/README.md.
2021-08-12 17:37:01 +10:00
Luke Howard
b216697924 kdc: use anonymous, not empty, cname when hiding
RFC 6113 5.4.2 says that when hiding client names in the outer reply of a FAST
response, the wellknown anonymous principal MUST be used.

The previous implementation returned an empty client name and realm, which may
not be expected by some clients.
2021-08-11 12:23:25 +10:00
Andrew Bartlett
d5b6869dc7 Allow KDC to always return the salt in the PA-ETYPE-INFO[2]
This is to match the Windows KDC behaviour, optionally.

Samba will use this mode, as Samba has tests that show
the difference and is keen for bug-for-bug/byte-for-byte
rather than strict RFC compliance where there is a
reasonable choice.

The Samba test (for reference) is
samba.tests.krb5.as_canonicalization_tests

The behaviour was changed in:

commit de1f37a6aa
Author: Luke Howard <lukeh@padl.com>
Date:   Mon Jan 7 15:45:36 2019 +1100

    kdc: omit default salt from PA-ETYPE-INFO[2]

    If the salt for the AS-REP client key matches the default password salt for the
    client principal in the AS-REQ, then it can be omitted from the PA-ETYPE-INFO,
    PA-ETYPE-INFO2 (RFC4120) as the client will assume the default salt in its
    absence.

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
2021-08-09 23:20:08 +10:00
Andrew Bartlett
33fccb8bbe heimdal: Match windows and return KRB5KDC_ERR_CLIENT_REVOKED when the account is locked out
Windows does not check the password on an account that has been locked.

Heimdal does not implement locked_out, however the Samba hdb
backend does, and needs this checked before passwords (for bad
password lockout), not after in kdc_check_access().

Based on work to update Samba to current Heimdal by
Gary Lockyer <gary@catalyst.net.nz> and including cherry-pick of
Samba commit 580a705b83014e94556b9d5a8877406816e02190 which noted
that we need to return KRB5KDC_ERR_CLIENT_REVOKED to match Windows.

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
2021-08-06 12:48:12 +10:00
Luke Howard
5ba7f270eb kdc: return revoked error if principal locked out
According to #788, Windows clients expect a revoked error to be returned if the
client or service is locked out, rather than a generic policy error. This
should not affect non-Windows paths as the locked_out HDB entry flag is
otherwise not used by Heimdal.
2021-08-06 12:34:52 +10:00
Luke Howard
3604497fda kdc: zero KDCFastState padata before free 2021-08-04 18:01:48 +10:00
Andrew Bartlett
2ee8834696 Add const to _kdc_set_e_text()
On Ubuntu 20.04 with gcc version 9.3.0 in a Samba compile
using -Wdiscarded-qualifiers and -Werror we get:

../../source4/heimdal/kdc/kerberos5.c:2516:21: warning: passing argument 2 of ‘_kdc_set_e_text’ discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
 2516 |  _kdc_set_e_text(r, "Client have no reply key");
      |                     ^~~~~~~~~~~~~~~~~~~~~~~~~~
../../source4/heimdal/kdc/kerberos5.c:428:42: note: expected ‘char *’ but argument is of type ‘const char *’
  428 | _kdc_set_e_text(astgs_request_t r, char *fmt, ...)
      |                                    ~~~~~~^~~

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
2021-06-30 12:47:41 +10:00
Nicolas Williams
00358252d3 kdc: Add synthetic PKINIT principals option 2021-06-29 14:52:07 -05:00
Nicolas Williams
9ce3cbbf2a kdc: Improve warn_ticket_addresses feature
- Don't log "Request from wrong address (ignoring)".
 - Add "wrongaddr=yes" kv to final log message.
 - Add request and ticket addresses (up to 3) to final log message.
2021-05-12 17:56:26 -05:00
Nicolas Williams
966f18f57e kdc: Add warn_ticket_addresses config option (fix missing) 2021-04-14 19:27:21 -05:00
Nicolas Williams
a5e289f4f7 kdc: Add warn_ticket_addresses config option 2021-04-13 23:22:45 -05:00
Nicolas Williams
28cdea6de4 kdc: Reduce log level of some messages 2021-03-26 16:40:52 -05:00
Nicolas Williams
dc74e9d00c kdc: Add Heimdal cert ext for ticket max_life
This adds support for using a Heimdal-specific PKIX extension to derive
a maximum Kerberos ticket lifetime from a client's PKINIT certificate.

KDC configuration parameters:

 - pkinit_max_life_from_cert_extension
 - pkinit_max_life_bound

If `pkinit_max_life_from_cert_extension` is set to true then the
certificate extension or EKU will be checked.

If `pkinit_max_life_bound` is set to a positive relative time, then that
will be the upper bound of maximum Kerberos ticket lifetime derived from
these extensions.

The KDC config `pkinit_ticket_max_life_from_cert` that was added earlier
has been renamed to `pkinit_max_life_from_cert`.

See lib/hx509 and lib/krb5/krb5.conf.5.
2021-03-24 19:12:00 -05:00
Nicolas Williams
8e7c7209e8 kdc: Add param to derive max_life from client cert
This adds a KDC configuration parameter that can be used to indicate
that a PKINIT client's certificate's notAfter overrides the client
principal's HDB entry's max_life.  This parameter is a relative time
parameter, and it enables this only if set to a non-zero value (defaults
to zero).  The value of this parameter caps the max_life inferred from
the certificate.
2021-03-23 16:44:50 -05:00
Nicolas Williams
db7763ca7b asn1: X.681/682/683 magic handling of open types
Status:

 - And it works!

 - We have an extensive test based on decoding a rich EK certficate.

   This test exercises all of:

    - decoding
    - encoding with and without decoded open types
    - copying of decoded values with decoded open types
    - freeing of decoded values with decoded open types

   Valgrind finds no memory errors.

 - Added a manual page for the compiler.

 - rfc2459.asn1 now has all three primary PKIX types that we care about
   defined as in RFC5912, with IOS constraints and parameterization:

    - `Extension`       (embeds open type in an `OCTET STRING`)
    - `OtherName`       (embeds open type in an        `ANY`-like type)
    - `SingleAttribute` (embeds open type in an        `ANY`-like type)
    - `AttributeSet`    (embeds open type in a  `SET OF ANY`-like type)

   All of these use OIDs as the open type type ID field, but integer
   open type type ID fields are also supported (and needed, for
   Kerberos).

   That will cover every typed hole pattern in all our ASN.1 modules.

   With this we'll be able to automatically and recursively decode
   through all subject DN attributes even when the subject DN is a
   directoryName SAN, and subjectDirectoryAttributes, and all
   extensions, and all SANs, and all authorization-data elements, and
   PA-data, and...

   We're not really using `SingleAttribute` and `AttributeSet` yet
   because various changes are needed in `lib/hx509` for that.

 - `asn1_compile` builds and recognizes the subset of X.681/682/683 that
   we need for, and now use in, rfc2459.asn1.  It builds the necessary
   AST, generates the correct C types, and generates templating for
   object sets and open types!

 - See READMEs for details.

 - Codegen backend not tested; I won't make it implement automatic open
   type handling, but it should at least not crash by substituting
   `heim_any` for open types not embedded in `OCTET STRING`.

 - We're _really_ starting to have problems with the ITU-T ASN.1
   grammar and our version of it...

   Type names have to start with upper-case, value names with
   lower-case, but it's not enough to disambiguate.

   The fact the we've allowed value and type names to violate their
   respective start-with case rules is causing us trouble now that we're
   adding grammar from X.681/682/683, and we're going to have to undo
   that.

   In preparation for that I'm capitalizing the `heim_any` and
   `heim_any_set` types, and doing some additional cleanup, which
   requires changes to other parts of Heimdal (all in this same commit
   for now).

   Problems we have because of this:

    - We cannot IMPORT values into modules because we have no idea if a
      symbol being imported refers to a value or a type because the only
      clue we would have is the symbol's name, so we assume IMPORTed
      symbols are for types.

      This means we can't import OIDs, for example, which is super
      annoying.

      One thing we might be able to do here is mark imported symbols as
      being of an undetermined-but-not-undefined type, then coerce the
      symbol's type the first time it's used in a context where its type
      is inferred as type, value, object, object set, or class.  (Though
      since we don't generate C symbols for objects or classes, we won't
      be able to import them, especially since we need to know them at
      compile time and cannot defer their handling to link- or
      run-time.)

    - The `NULL` type name, and the `NULL` value name now cause two
      reduce/reduce conflicts via the `FieldSetting` production.

    - Various shift/reduce conflicts involving `NULL` values in
      non-top-level contexts (in constraints, for example).

 - Currently I have a bug where to disambiguate the grammar I have a
   CLASS_IDENTIFIER token that is all caps, while TYPE_IDENTIFIER must
   start with a capital but not be all caps, but this breaks Kerberos
   since all its types are all capitalized -- oof!

   To fix this I made it so class names have to be all caps and
   start with an underscore (ick).

TBD:

 - Check all the XXX comments and address them
 - Apply this treatment to Kerberos!  Automatic handling of authz-data
   sounds useful :)
 - Apply this treatment to PKCS#10 (CSRs) and other ASN.1 modules too.
 - Replace various bits of code in `lib/hx509/` with uses of this
   feature.
 - Add JER.
 - Enhance `hxtool` and `asn1_print`.

Getting there!
2021-02-28 18:13:08 -06:00
Nicolas Williams
ff13573ce5 hdb: Do not apply new service key delay to clients
The new [hdb] new_service_key_delay parameter should not apply to
principal entries when used as clients.  Otherwise new passwords would
not take effect immediately, and that would be very confusing.
2020-09-09 21:48:29 -05:00