summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2003-07-25 23:15:30 +0000
committerJeremy Allison <jra@samba.org>2003-07-25 23:15:30 +0000
commit4632786cfb193dd80ce04206912297186e871814 (patch)
treeb38cc3953923988443fd2ea76664677c24033366 /source3
parent37d77e3d6cf85eae9f45d18b756101fc1f50460b (diff)
downloadsamba-4632786cfb193dd80ce04206912297186e871814.tar.gz
samba-4632786cfb193dd80ce04206912297186e871814.tar.bz2
samba-4632786cfb193dd80ce04206912297186e871814.zip
W00t! Client smb signing is now working correctly with krb5 and w2k server.
Server code *should* also work (I'll check shortly). May be the odd memory leak. Problem was we (a) weren't setting signing on in the client krb5 sessionsetup code (b) we need to ask for a subkey... (c). The client and server need to ask for local and remote subkeys respectively. Thanks to Paul Nelson @ Thursby for some sage advice on this :-). Jeremy. (This used to be commit 3f9e3b60709df5ab755045a093e642510d4cde00)
Diffstat (limited to 'source3')
-rw-r--r--source3/include/includes.h2
-rw-r--r--source3/libads/kerberos_verify.c2
-rw-r--r--source3/libads/sasl.c3
-rw-r--r--source3/libsmb/cliconnect.c16
-rw-r--r--source3/libsmb/clikrb5.c23
-rw-r--r--source3/libsmb/clispnego.c6
-rw-r--r--source3/libsmb/smb_signing.c15
7 files changed, 48 insertions, 19 deletions
diff --git a/source3/include/includes.h b/source3/include/includes.h
index 77c2b437bd..d900d7feb9 100644
--- a/source3/include/includes.h
+++ b/source3/include/includes.h
@@ -1296,7 +1296,7 @@ krb5_const_principal get_principal_from_tkt(krb5_ticket *tkt);
krb5_error_code krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, struct sockaddr **addr_pp, int *naddrs, int get_masters);
krb5_error_code get_kerberos_allowed_etypes(krb5_context context, krb5_enctype **enctypes);
void free_kerberos_etypes(krb5_context context, krb5_enctype *enctypes);
-BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16]);
+BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16], BOOL remote);
#endif /* HAVE_KRB5 */
/* TRUE and FALSE are part of the C99 standard and gcc, but
diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c
index 25b7f9d948..4098b44c39 100644
--- a/source3/libads/kerberos_verify.c
+++ b/source3/libads/kerberos_verify.c
@@ -178,7 +178,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket,
*ap_rep = data_blob(packet.data, packet.length);
free(packet.data);
- get_krb5_smb_session_key(context, auth_context, session_key);
+ get_krb5_smb_session_key(context, auth_context, session_key, True);
#ifdef DEBUG_PASSWORD
DEBUG(10,("SMB session key (from ticket) follows:\n"));
dump_data(10, session_key, 16);
diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c
index 598208b17f..910ff3f4dc 100644
--- a/source3/libads/sasl.c
+++ b/source3/libads/sasl.c
@@ -124,9 +124,10 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *princip
{
DATA_BLOB blob;
struct berval cred, *scred;
+ unsigned char sk[16];
int rc;
- blob = spnego_gen_negTokenTarg(principal, ads->auth.time_offset);
+ blob = spnego_gen_negTokenTarg(principal, ads->auth.time_offset, sk);
if (!blob.data) {
return ADS_ERROR(LDAP_OPERATIONS_ERROR);
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index eceeb96309..8873c1fdc8 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -472,6 +472,7 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob)
/****************************************************************************
Use in-memory credentials cache
****************************************************************************/
+
static void use_in_memory_ccache(void) {
setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1);
}
@@ -483,18 +484,23 @@ static void use_in_memory_ccache(void) {
static BOOL cli_session_setup_kerberos(struct cli_state *cli, const char *principal, const char *workgroup)
{
DATA_BLOB blob2, negTokenTarg;
-
+ unsigned char session_key_krb5[16];
+ DATA_BLOB null_blob = data_blob(NULL, 0);
+
DEBUG(2,("Doing kerberos session setup\n"));
/* generate the encapsulated kerberos5 ticket */
- negTokenTarg = spnego_gen_negTokenTarg(principal, 0);
+ negTokenTarg = spnego_gen_negTokenTarg(principal, 0, session_key_krb5);
- if (!negTokenTarg.data) return False;
+ if (!negTokenTarg.data)
+ return False;
#if 0
file_save("negTokenTarg.dat", negTokenTarg.data, negTokenTarg.length);
#endif
+ cli_simple_set_signing(cli, session_key_krb5, null_blob);
+
blob2 = cli_session_setup_blob(cli, negTokenTarg);
/* we don't need this blob for kerberos */
@@ -551,7 +557,7 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user,
blob_in, &blob_out);
data_blob_free(&blob_in);
if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- DATA_BLOB null = data_blob(NULL, 0);
+ DATA_BLOB null_blob = data_blob(NULL, 0);
if (turn == 1) {
/* and wrap it in a SPNEGO wrapper */
msg1 = gen_negTokenInit(OID_NTLMSSP, blob_out);
@@ -562,7 +568,7 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user,
cli_simple_set_signing(cli,
ntlmssp_state->session_key.data,
- null);
+ null_blob);
/* now send that blob on its way */
if (!cli_session_setup_blob_send(cli, msg1)) {
diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c
index ba8ba11368..beac8cb2c1 100644
--- a/source3/libsmb/clikrb5.c
+++ b/source3/libsmb/clikrb5.c
@@ -305,7 +305,7 @@ cleanup_princ:
/*
get a kerberos5 ticket for the given service
*/
-DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset)
+DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset, unsigned char session_key_krb5[16])
{
krb5_error_code retval;
krb5_data packet;
@@ -345,13 +345,15 @@ DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset)
}
if ((retval = ads_krb5_mk_req(context,
- &auth_context,
- 0,
- principal,
- ccdef, &packet))) {
+ &auth_context,
+ AP_OPTS_USE_SUBKEY,
+ principal,
+ ccdef, &packet))) {
goto failed;
}
+ get_krb5_smb_session_key(context, auth_context, session_key_krb5, False);
+
ret = data_blob(packet.data, packet.length);
/* Hmm, heimdal dooesn't have this - what's the correct call? */
/* krb5_free_data_contents(context, &packet); */
@@ -365,17 +367,22 @@ failed:
return data_blob(NULL, 0);
}
- BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16])
+ BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16], BOOL remote)
{
#ifdef ENCTYPE_ARCFOUR_HMAC
krb5_keyblock *skey;
#endif
BOOL ret = False;
+ krb5_error_code err;
memset(session_key, 0, 16);
#ifdef ENCTYPE_ARCFOUR_HMAC
- if (krb5_auth_con_getremotesubkey(context, auth_context, &skey) == 0 && skey != NULL) {
+ if (remote)
+ err = krb5_auth_con_getremotesubkey(context, auth_context, &skey);
+ else
+ err = krb5_auth_con_getlocalsubkey(context, auth_context, &skey);
+ if (err == 0 && skey != NULL) {
if (KRB5_KEY_TYPE(skey) ==
ENCTYPE_ARCFOUR_HMAC
&& KRB5_KEY_LENGTH(skey) == 16) {
@@ -403,7 +410,7 @@ failed:
#else /* HAVE_KRB5 */
/* this saves a few linking headaches */
-DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset)
+DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset, unsigned char session_key_krb5[16])
{
DEBUG(0,("NO KERBEROS SUPPORT\n"));
return data_blob(NULL, 0);
diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c
index bb48f57915..fbf8323679 100644
--- a/source3/libsmb/clispnego.c
+++ b/source3/libsmb/clispnego.c
@@ -323,13 +323,13 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2])
generate a SPNEGO negTokenTarg packet, ready for a EXTENDED_SECURITY
kerberos session setup
*/
-DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset)
+DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset, unsigned char session_key_krb5[16])
{
DATA_BLOB tkt, tkt_wrapped, targ;
const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL};
- /* get a kerberos ticket for the service */
- tkt = cli_krb5_get_ticket(principal, time_offset);
+ /* get a kerberos ticket for the service and extract the session key */
+ tkt = cli_krb5_get_ticket(principal, time_offset, session_key_krb5);
/* wrap that up in a nice GSS-API wrapping */
tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c
index 4a98b84826..977d5e3905 100644
--- a/source3/libsmb/smb_signing.c
+++ b/source3/libsmb/smb_signing.c
@@ -330,6 +330,21 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si)
DEBUG(5, ("client_check_incoming_message: BAD SIG: got SMB signature of\n"));
dump_data(5, server_sent_mac, 8);
+#if 0 /* JRATEST */
+ {
+ int i;
+ reply_seq_number -= 5;
+ for (i = 0; i < 10; i++, reply_seq_number++) {
+ simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac);
+ if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) {
+ DEBUG(0,("client_check_incoming_message: out of seq. seq num %u matches.\n",
+ reply_seq_number ));
+ break;
+ }
+ }
+ }
+#endif /* JRATEST */
+
}
return signing_good(inbuf, si, good);
}