From ec458fa87e3ee858be39671f575e21a9350674b6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 17 Mar 2003 22:45:16 +0000 Subject: Merge from HEAD - sync up SessionSetup code to HEAD, including Luke Howard's session key and auth verifier patches. Andrew Bartlett (This used to be commit 3f9616a68a855acbae3f405c27ee2358fbe7ba2c) --- source3/libsmb/clikrb5.c | 52 ++++++++++++++++++++++++++++++++++++++-------- source3/libsmb/clispnego.c | 29 ++++++++++++++------------ 2 files changed, 59 insertions(+), 22 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index bef6998a49..5edc56daa9 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -2,7 +2,7 @@ Unix SMB/CIFS implementation. simple kerberos5 routines for active directory Copyright (C) Andrew Tridgell 2001 - Copyright (C) Luke Howard 2002 + Copyright (C) Luke Howard 2002-2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,6 +23,16 @@ #ifdef HAVE_KRB5 +#ifdef HAVE_KRB5_KEYBLOCK_KEYVALUE +#define KRB5_KEY_TYPE(k) ((k)->keytype) +#define KRB5_KEY_LENGTH(k) ((k)->keyvalue.length) +#define KRB5_KEY_DATA(k) ((k)->keyvalue.data) +#else +#define KRB5_KEY_TYPE(k) ((k)->enctype) +#define KRB5_KEY_LENGTH(k) ((k)->length) +#define KRB5_KEY_DATA(k) ((k)->contents) +#endif /* HAVE_KRB5_KEYBLOCK_KEYVALUE */ + #ifndef HAVE_KRB5_SET_REAL_TIME /* * This function is not in the Heimdal mainline. @@ -124,7 +134,7 @@ krb5_error_code get_kerberos_allowed_etypes(krb5_context context, return krb5_get_default_in_tkt_etypes(context, enctypes); } #else - __ERROR_XX_UNKNOWN_GET_ENCTYPES_FUNCTIONS +#error UNKNOWN_GET_ENCTYPES_FUNCTIONS #endif void free_kerberos_etypes(krb5_context context, @@ -305,12 +315,12 @@ DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset) DATA_BLOB ret; krb5_enctype enc_types[] = { #ifdef ENCTYPE_ARCFOUR_HMAC - ENCTYPE_ARCFOUR_HMAC, -#endif - ENCTYPE_DES_CBC_MD5, - ENCTYPE_DES_CBC_CRC, - ENCTYPE_NULL}; - + ENCTYPE_ARCFOUR_HMAC, +#endif + ENCTYPE_DES_CBC_MD5, + ENCTYPE_DES_CBC_CRC, + ENCTYPE_NULL}; + retval = krb5_init_context(&context); if (retval) { DEBUG(1,("krb5_init_context failed (%s)\n", @@ -355,11 +365,35 @@ failed: return data_blob(NULL, 0); } + BOOL krb5_get_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16]) + { +#ifdef ENCTYPE_ARCFOUR_HMAC + krb5_keyblock *skey; +#endif + BOOL ret = False; + + memset(session_key, 0, 16); + +#ifdef ENCTYPE_ARCFOUR_HMAC + if (krb5_auth_con_getremotesubkey(context, auth_context, &skey) == 0 && skey != NULL) { + if (KRB5_KEY_TYPE(skey) == + ENCTYPE_ARCFOUR_HMAC + && KRB5_KEY_LENGTH(skey) == 16) { + memcpy(session_key, KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey)); + ret = True; + } + krb5_free_keyblock(context, skey); + } +#endif /* ENCTYPE_ARCFOUR_HMAC */ + + return ret; + } #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ - DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset) +DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset) { DEBUG(0,("NO KERBEROS SUPPORT\n")); return data_blob(NULL, 0); } + #endif diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index e93f1855dd..53f7eb6e7d 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -3,6 +3,7 @@ simple kerberos5/SPNEGO routines Copyright (C) Andrew Tridgell 2001 Copyright (C) Jim McDonough 2002 + Copyright (C) Luke Howard 2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -259,7 +260,7 @@ BOOL parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *se /* generate a krb5 GSS-API wrapper packet given a ticket */ -DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket) +DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket, const uint8 tok_id[2]) { ASN1_DATA data; DATA_BLOB ret; @@ -268,7 +269,8 @@ DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket) asn1_push_tag(&data, ASN1_APPLICATION(0)); asn1_write_OID(&data, OID_KERBEROS5); - asn1_write_BOOLEAN(&data, 0); + + asn1_write(&data, tok_id, 2); asn1_write(&data, ticket.data, ticket.length); asn1_pop_tag(&data); @@ -286,7 +288,7 @@ DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket) /* parse a krb5 GSS-API wrapper packet giving a ticket */ -BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket) +BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]) { BOOL ret; ASN1_DATA data; @@ -295,15 +297,15 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket) asn1_load(&data, blob); asn1_start_tag(&data, ASN1_APPLICATION(0)); asn1_check_OID(&data, OID_KERBEROS5); - asn1_check_BOOLEAN(&data, 0); data_remaining = asn1_tag_remaining(&data); - if (data_remaining < 1) { + if (data_remaining < 3) { data.has_error = True; } else { - - *ticket = data_blob(data.data, data_remaining); + asn1_read(&data, tok_id, 2); + data_remaining -= 2; + *ticket = data_blob(NULL, data_remaining); asn1_read(&data, ticket->data, ticket->length); } @@ -330,7 +332,7 @@ DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset) tkt = krb5_get_ticket(principal, time_offset); /* wrap that up in a nice GSS-API wrapping */ - tkt_wrapped = spnego_gen_krb5_wrap(tkt); + tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ); /* and wrap that in a shiny SPNEGO wrapper */ targ = gen_negTokenTarg(krb_mechs, tkt_wrapped); @@ -438,9 +440,10 @@ BOOL spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth) } /* - generate a minimal SPNEGO NTLMSSP response packet. Doesn't contain much. + generate a minimal SPNEGO response packet. Doesn't contain much. */ -DATA_BLOB spnego_gen_auth_response(DATA_BLOB *ntlmssp_reply, NTSTATUS nt_status) +DATA_BLOB spnego_gen_auth_response(DATA_BLOB *reply, NTSTATUS nt_status, + const char *mechOID) { ASN1_DATA data; DATA_BLOB ret; @@ -462,13 +465,13 @@ DATA_BLOB spnego_gen_auth_response(DATA_BLOB *ntlmssp_reply, NTSTATUS nt_status) asn1_write_enumerated(&data, negResult); asn1_pop_tag(&data); - if (negResult == SPNEGO_NEG_RESULT_INCOMPLETE) { + if (reply->data != NULL) { asn1_push_tag(&data,ASN1_CONTEXT(1)); - asn1_write_OID(&data, OID_NTLMSSP); + asn1_write_OID(&data, mechOID); asn1_pop_tag(&data); asn1_push_tag(&data,ASN1_CONTEXT(2)); - asn1_write_OctetString(&data, ntlmssp_reply->data, ntlmssp_reply->length); + asn1_write_OctetString(&data, reply->data, reply->length); asn1_pop_tag(&data); } -- cgit