From b4b0177fdb5f1704a7347552e48b2ab647a03d14 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 1 Dec 2003 04:13:43 +0000 Subject: added netr_ServerAuthenticate() and test code I would like the netlogon test suite to eventually do a new domain join using a fake workstation name, then remove itself afterwards, but for now I'm assuming we are already joined to the domain when the testsuite runs. This means you need to use the Samba3 net command to do a join before running RPC-NETLOGON (This used to be commit 8c7a9446a0892a4f7722cced5019667f7a9fafdd) --- source4/libcli/auth/credentials.c | 213 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 source4/libcli/auth/credentials.c (limited to 'source4/libcli/auth/credentials.c') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c new file mode 100644 index 0000000000..6df163bdfc --- /dev/null +++ b/source4/libcli/auth/credentials.c @@ -0,0 +1,213 @@ +/* + Unix SMB/CIFS implementation. + + code to manipulate domain credentials + + Copyright (C) Andrew Tridgell 1997-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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +/**************************************************************************** +represent a credential as a string +****************************************************************************/ +char *credstr(const uchar *cred) +{ + static fstring buf; + slprintf(buf, sizeof(buf) - 1, "%02X%02X%02X%02X%02X%02X%02X%02X", + cred[0], cred[1], cred[2], cred[3], + cred[4], cred[5], cred[6], cred[7]); + return buf; +} + + +/**************************************************************************** + setup the session key. +Input: 8 byte challenge block + 8 byte server challenge block + 16 byte md4 encrypted password +Output: + 8 byte session key +****************************************************************************/ +void cred_session_key(const struct netr_Credential *client_challenge, + const struct netr_Credential *server_challenge, + const uint8 md4_pass[16], + uint8 session_key[8]) +{ + uint32 sum[2]; + uint8 sum2[8]; + + sum[0] = IVAL(client_challenge->data, 0) + IVAL(server_challenge->data, 0); + sum[1] = IVAL(client_challenge->data, 4) + IVAL(server_challenge->data, 4); + + SIVAL(sum2,0,sum[0]); + SIVAL(sum2,4,sum[1]); + + cred_hash1(session_key, sum2, md4_pass); +} + + +/**************************************************************************** +create a credential + +Input: + 8 byte sesssion key + 8 byte stored credential + 4 byte timestamp + +Output: + 8 byte credential +****************************************************************************/ +void cred_create(uchar session_key[8], struct netr_Credential *stor_cred, time_t timestamp, + struct netr_Credential *cred) +{ + struct netr_Credential time_cred; + + SIVAL(time_cred.data, 0, IVAL(stor_cred->data, 0) + timestamp); + SIVAL(time_cred.data, 4, IVAL(stor_cred->data, 4)); + + cred_hash2(cred->data, time_cred.data, session_key); + + /* debug output*/ + DEBUG(4,("cred_create\n")); + + DEBUG(5,(" sess_key : %s\n", credstr(session_key))); + DEBUG(5,(" stor_cred: %s\n", credstr(stor_cred->data))); + DEBUG(5,(" timestamp: %x\n", (unsigned)timestamp)); + DEBUG(5,(" timecred : %s\n", credstr(time_cred.data))); + DEBUG(5,(" calc_cred: %s\n", credstr(cred->data))); +} + + +/**************************************************************************** + check a supplied credential + +Input: + 8 byte received credential + 8 byte sesssion key + 8 byte stored credential + 4 byte timestamp + +Output: + returns 1 if computed credential matches received credential + returns 0 otherwise +****************************************************************************/ +int cred_assert(struct netr_Credential *cred, uchar session_key[8], + struct netr_Credential *stored_cred, + time_t timestamp) +{ + struct netr_Credential cred2; + + cred_create(session_key, stored_cred, timestamp, &cred2); + + /* debug output*/ + DEBUG(4,("cred_assert\n")); + + DEBUG(5,(" challenge : %s\n", credstr(cred->data))); + DEBUG(5,(" calculated: %s\n", credstr(cred2.data))); + + if (memcmp(cred->data, cred2.data, 8) == 0) + { + DEBUG(5, ("credentials check ok\n")); + return True; + } + else + { + DEBUG(5, ("credentials check wrong\n")); + return False; + } +} + + +/**************************************************************************** + checks credentials; generates next step in the credential chain +****************************************************************************/ +BOOL clnt_deal_with_creds(uchar sess_key[8], + struct netr_Authenticator *sto_clnt_cred, + struct netr_Authenticator *rcv_srv_cred) +{ + time_t new_clnt_time; + uint32 new_cred; + + DEBUG(5,("clnt_deal_with_creds: %d\n", __LINE__)); + + /* increment client time by one second !?! */ + new_clnt_time = sto_clnt_cred->timestamp + 1; + + /* check that the received server credentials are valid */ + if (!cred_assert(&rcv_srv_cred->cred, sess_key, + &sto_clnt_cred->cred, new_clnt_time)) { + return False; + } + + /* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */ + new_cred = IVAL(sto_clnt_cred->cred.data, 0); + new_cred += new_clnt_time; + + /* store new seed in client credentials */ + SIVAL(sto_clnt_cred->cred.data, 0, new_cred); + + DEBUG(5,(" new clnt cred: %s\n", credstr(sto_clnt_cred->cred.data))); + return True; +} + + +/**************************************************************************** + checks credentials; generates next step in the credential chain +****************************************************************************/ +BOOL deal_with_creds(uchar sess_key[8], + struct netr_Authenticator *sto_clnt_cred, + struct netr_Authenticator *rcv_clnt_cred, + struct netr_Authenticator *rtn_srv_cred) +{ + time_t new_clnt_time; + uint32 new_cred; + + DEBUG(5,("deal_with_creds: %d\n", __LINE__)); + + /* check that the received client credentials are valid */ + if (!cred_assert(&rcv_clnt_cred->cred, sess_key, + &sto_clnt_cred->cred, rcv_clnt_cred->timestamp)) + { + return False; + } + + /* increment client time by one second */ + new_clnt_time = rcv_clnt_cred->timestamp + 1; + + /* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */ + new_cred = IVAL(sto_clnt_cred->cred.data, 0); + new_cred += new_clnt_time; + + DEBUG(5,("deal_with_creds: new_cred[0]=%x\n", new_cred)); + + /* doesn't matter that server time is 0 */ + rtn_srv_cred->timestamp = 0; + + DEBUG(5,("deal_with_creds: new_clnt_time=%x\n", (unsigned)new_clnt_time)); + + /* create return credentials for inclusion in the reply */ + cred_create(sess_key, &sto_clnt_cred->cred, new_clnt_time, + &rtn_srv_cred->cred); + + DEBUG(5,("deal_with_creds: clnt_cred=%s\n", credstr(sto_clnt_cred->cred.data))); + + /* store new seed in client credentials */ + SIVAL(sto_clnt_cred->cred.data, 0, new_cred); + + return True; +} -- cgit From a6cf6cada93640fe6a24a7d3c5403079aeb7b4de Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 1 Dec 2003 09:28:10 +0000 Subject: added netr_LogonSamLogon() and test code (This used to be commit 4fa3ad3ecbfd8f8663fcdfaba9a7db481e303f2b) --- source4/libcli/auth/credentials.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source4/libcli/auth/credentials.c') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 6df163bdfc..72572d8f91 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -143,8 +143,6 @@ BOOL clnt_deal_with_creds(uchar sess_key[8], time_t new_clnt_time; uint32 new_cred; - DEBUG(5,("clnt_deal_with_creds: %d\n", __LINE__)); - /* increment client time by one second !?! */ new_clnt_time = sto_clnt_cred->timestamp + 1; @@ -161,7 +159,6 @@ BOOL clnt_deal_with_creds(uchar sess_key[8], /* store new seed in client credentials */ SIVAL(sto_clnt_cred->cred.data, 0, new_cred); - DEBUG(5,(" new clnt cred: %s\n", credstr(sto_clnt_cred->cred.data))); return True; } -- cgit From f9e2a8af391f8ecb7cf6aa2d017898503d16985f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 1 Dec 2003 12:41:54 +0000 Subject: neater credentials handling in netlogon client code (This used to be commit b7d748f499f79415b444e7cebe7d8de7186fbc94) --- source4/libcli/auth/credentials.c | 191 +++++++------------------------------- 1 file changed, 32 insertions(+), 159 deletions(-) (limited to 'source4/libcli/auth/credentials.c') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 72572d8f91..06ca416592 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -22,32 +22,15 @@ #include "includes.h" -/**************************************************************************** -represent a credential as a string -****************************************************************************/ -char *credstr(const uchar *cred) -{ - static fstring buf; - slprintf(buf, sizeof(buf) - 1, "%02X%02X%02X%02X%02X%02X%02X%02X", - cred[0], cred[1], cred[2], cred[3], - cred[4], cred[5], cred[6], cred[7]); - return buf; -} - - -/**************************************************************************** - setup the session key. -Input: 8 byte challenge block - 8 byte server challenge block - 16 byte md4 encrypted password -Output: - 8 byte session key -****************************************************************************/ -void cred_session_key(const struct netr_Credential *client_challenge, - const struct netr_Credential *server_challenge, - const uint8 md4_pass[16], - uint8 session_key[8]) +/* + initialise the credentials state +*/ +void creds_init(struct netr_CredentialState *creds, + const struct netr_Credential *client_challenge, + const struct netr_Credential *server_challenge, + const uint8 machine_password[16]) { + struct netr_Credential time_cred; uint32 sum[2]; uint8 sum2[8]; @@ -57,154 +40,44 @@ void cred_session_key(const struct netr_Credential *client_challenge, SIVAL(sum2,0,sum[0]); SIVAL(sum2,4,sum[1]); - cred_hash1(session_key, sum2, md4_pass); -} - - -/**************************************************************************** -create a credential + cred_hash1(creds->session_key, sum2, machine_password); -Input: - 8 byte sesssion key - 8 byte stored credential - 4 byte timestamp - -Output: - 8 byte credential -****************************************************************************/ -void cred_create(uchar session_key[8], struct netr_Credential *stor_cred, time_t timestamp, - struct netr_Credential *cred) -{ - struct netr_Credential time_cred; + creds->sequence = 0; - SIVAL(time_cred.data, 0, IVAL(stor_cred->data, 0) + timestamp); - SIVAL(time_cred.data, 4, IVAL(stor_cred->data, 4)); + SIVAL(time_cred.data, 0, IVAL(client_challenge->data, 0) + creds->sequence); + SIVAL(time_cred.data, 4, IVAL(client_challenge->data, 4)); - cred_hash2(cred->data, time_cred.data, session_key); + cred_hash2(creds->client_cred.data, time_cred.data, creds->session_key); - /* debug output*/ - DEBUG(4,("cred_create\n")); - - DEBUG(5,(" sess_key : %s\n", credstr(session_key))); - DEBUG(5,(" stor_cred: %s\n", credstr(stor_cred->data))); - DEBUG(5,(" timestamp: %x\n", (unsigned)timestamp)); - DEBUG(5,(" timecred : %s\n", credstr(time_cred.data))); - DEBUG(5,(" calc_cred: %s\n", credstr(cred->data))); + creds->server_cred = *server_challenge; } - -/**************************************************************************** - check a supplied credential - -Input: - 8 byte received credential - 8 byte sesssion key - 8 byte stored credential - 4 byte timestamp - -Output: - returns 1 if computed credential matches received credential - returns 0 otherwise -****************************************************************************/ -int cred_assert(struct netr_Credential *cred, uchar session_key[8], - struct netr_Credential *stored_cred, - time_t timestamp) +/* + check that the credentials reply is correct then generate the next + set of credentials +*/ +BOOL creds_next(struct netr_CredentialState *creds, + const struct netr_Credential *next) { struct netr_Credential cred2; + struct netr_Credential time_cred; - cred_create(session_key, stored_cred, timestamp, &cred2); - - /* debug output*/ - DEBUG(4,("cred_assert\n")); - - DEBUG(5,(" challenge : %s\n", credstr(cred->data))); - DEBUG(5,(" calculated: %s\n", credstr(cred2.data))); - - if (memcmp(cred->data, cred2.data, 8) == 0) - { - DEBUG(5, ("credentials check ok\n")); - return True; - } - else - { - DEBUG(5, ("credentials check wrong\n")); - return False; - } -} - - -/**************************************************************************** - checks credentials; generates next step in the credential chain -****************************************************************************/ -BOOL clnt_deal_with_creds(uchar sess_key[8], - struct netr_Authenticator *sto_clnt_cred, - struct netr_Authenticator *rcv_srv_cred) -{ - time_t new_clnt_time; - uint32 new_cred; - - /* increment client time by one second !?! */ - new_clnt_time = sto_clnt_cred->timestamp + 1; - - /* check that the received server credentials are valid */ - if (!cred_assert(&rcv_srv_cred->cred, sess_key, - &sto_clnt_cred->cred, new_clnt_time)) { - return False; - } - - /* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */ - new_cred = IVAL(sto_clnt_cred->cred.data, 0); - new_cred += new_clnt_time; - - /* store new seed in client credentials */ - SIVAL(sto_clnt_cred->cred.data, 0, new_cred); - - return True; -} - - -/**************************************************************************** - checks credentials; generates next step in the credential chain -****************************************************************************/ -BOOL deal_with_creds(uchar sess_key[8], - struct netr_Authenticator *sto_clnt_cred, - struct netr_Authenticator *rcv_clnt_cred, - struct netr_Authenticator *rtn_srv_cred) -{ - time_t new_clnt_time; - uint32 new_cred; - - DEBUG(5,("deal_with_creds: %d\n", __LINE__)); - - /* check that the received client credentials are valid */ - if (!cred_assert(&rcv_clnt_cred->cred, sess_key, - &sto_clnt_cred->cred, rcv_clnt_cred->timestamp)) - { + SIVAL(time_cred.data, 0, IVAL(creds->server_cred.data, 0) + creds->sequence); + SIVAL(time_cred.data, 4, IVAL(creds->server_cred.data, 4)); + cred_hash2(cred2.data, time_cred.data, creds->session_key); + if (memcmp(next->data, cred2.data, 8) != 0) { + DEBUG(2,("credentials check failed\n")); return False; } - /* increment client time by one second */ - new_clnt_time = rcv_clnt_cred->timestamp + 1; - - /* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */ - new_cred = IVAL(sto_clnt_cred->cred.data, 0); - new_cred += new_clnt_time; - - DEBUG(5,("deal_with_creds: new_cred[0]=%x\n", new_cred)); - - /* doesn't matter that server time is 0 */ - rtn_srv_cred->timestamp = 0; - - DEBUG(5,("deal_with_creds: new_clnt_time=%x\n", (unsigned)new_clnt_time)); + creds->server_cred = creds->client_cred; - /* create return credentials for inclusion in the reply */ - cred_create(sess_key, &sto_clnt_cred->cred, new_clnt_time, - &rtn_srv_cred->cred); - - DEBUG(5,("deal_with_creds: clnt_cred=%s\n", credstr(sto_clnt_cred->cred.data))); + SIVAL(time_cred.data, 0, IVAL(creds->client_cred.data, 0) + creds->sequence); + SIVAL(time_cred.data, 4, IVAL(creds->client_cred.data, 4)); - /* store new seed in client credentials */ - SIVAL(sto_clnt_cred->cred.data, 0, new_cred); + cred_hash2(cred2.data, time_cred.data, creds->session_key); + creds->client_cred = cred2; + creds->sequence++; return True; } -- cgit From 8b30b0071cb7668f49b2ea5951d1180bf90371e3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 1 Dec 2003 22:13:11 +0000 Subject: * another small API change in the credentials code * don't use static variables in the smbdes code (This used to be commit e6e09064646c347169852fa162c72fc0542c6d5c) --- source4/libcli/auth/credentials.c | 68 +++++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 20 deletions(-) (limited to 'source4/libcli/auth/credentials.c') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 06ca416592..80ea2e9583 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -23,12 +23,16 @@ #include "includes.h" /* - initialise the credentials state + initialise the credentials state and return the initial credentials + to be sent as part of a netr_ServerAuthenticate*() call. + + this call is made after the netr_ServerReqChallenge call */ void creds_init(struct netr_CredentialState *creds, const struct netr_Credential *client_challenge, const struct netr_Credential *server_challenge, - const uint8 machine_password[16]) + const uint8 machine_password[16], + struct netr_Credential *initial_creds) { struct netr_Credential time_cred; uint32 sum[2]; @@ -44,40 +48,64 @@ void creds_init(struct netr_CredentialState *creds, creds->sequence = 0; - SIVAL(time_cred.data, 0, IVAL(client_challenge->data, 0) + creds->sequence); + SIVAL(time_cred.data, 0, IVAL(client_challenge->data, 0)); SIVAL(time_cred.data, 4, IVAL(client_challenge->data, 4)); - cred_hash2(creds->client_cred.data, time_cred.data, creds->session_key); + cred_hash2(creds->cred2.data, time_cred.data, creds->session_key); + + creds->cred1 = *server_challenge; - creds->server_cred = *server_challenge; + *initial_creds = creds->cred2; } + /* - check that the credentials reply is correct then generate the next - set of credentials + check that a credentials reply is correct */ -BOOL creds_next(struct netr_CredentialState *creds, - const struct netr_Credential *next) +BOOL creds_check(struct netr_CredentialState *creds, + const struct netr_Credential *received_credentials) { - struct netr_Credential cred2; - struct netr_Credential time_cred; + struct netr_Credential cred2, time_cred; + uint32 sequence = creds->sequence?creds->sequence+1:0; - SIVAL(time_cred.data, 0, IVAL(creds->server_cred.data, 0) + creds->sequence); - SIVAL(time_cred.data, 4, IVAL(creds->server_cred.data, 4)); + SIVAL(time_cred.data, 0, IVAL(creds->cred1.data, 0) + sequence); + SIVAL(time_cred.data, 4, IVAL(creds->cred1.data, 4)); cred_hash2(cred2.data, time_cred.data, creds->session_key); - if (memcmp(next->data, cred2.data, 8) != 0) { + if (memcmp(received_credentials->data, cred2.data, 8) != 0) { DEBUG(2,("credentials check failed\n")); return False; } - creds->server_cred = creds->client_cred; + return True; +} - SIVAL(time_cred.data, 0, IVAL(creds->client_cred.data, 0) + creds->sequence); - SIVAL(time_cred.data, 4, IVAL(creds->client_cred.data, 4)); +/* + produce the next authenticator in the sequence ready to send to + the server +*/ +void creds_authenticator(struct netr_CredentialState *creds, + struct netr_Authenticator *next) +{ + struct netr_Credential cred2; + struct netr_Credential time_cred; + + if (creds->sequence == 0) { + creds->sequence = time(NULL); + } + + /* this step size is quite arbitrary - the client can choose + any sequence number it likes */ + creds->sequence += 2; + + creds->cred1 = creds->cred2; + + SIVAL(time_cred.data, 0, IVAL(creds->cred2.data, 0) + creds->sequence); + SIVAL(time_cred.data, 4, IVAL(creds->cred2.data, 4)); cred_hash2(cred2.data, time_cred.data, creds->session_key); - creds->client_cred = cred2; - creds->sequence++; - return True; + creds->cred2 = cred2; + + next->cred = creds->cred2; + next->timestamp = creds->sequence; } -- cgit From 06ae42483582ee76c3f6848697cf61cc142dd86a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Dec 2003 00:31:54 +0000 Subject: * netr_ServerPasswordSet() now works - the test suite changes the machine account password. * neater handling on value() options in IDL. The auto-print code will now display the right value so you don't need to initialise it in your C code (This used to be commit 3dd978b12bb5571fba4e1839c0f7ee60cf729aa2) --- source4/libcli/auth/credentials.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source4/libcli/auth/credentials.c') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 80ea2e9583..1749037e8f 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -109,3 +109,14 @@ void creds_authenticator(struct netr_CredentialState *creds, next->cred = creds->cred2; next->timestamp = creds->sequence; } + + +/* + encrypt a 16 byte password buffer using the session key +*/ +void creds_encrypt(struct netr_CredentialState *creds, struct netr_Password *pass) +{ + struct netr_Password tmp; + cred_hash3(tmp.data, pass->data, creds->session_key, 1); + *pass = tmp; +} -- cgit From 2e70035f87ebcdfbdc3cf8d05cd89d4eeeebc16c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Dec 2003 02:15:33 +0000 Subject: another big improvement in the credentials API. I think it now actually makes sense, and as a nice side effect it matches the debug output of the w2k3 netlogon.log (This used to be commit 3c7287c24e5970e5b7447ad042848505537c7d3b) --- source4/libcli/auth/credentials.c | 111 +++++++++++++++++++++++--------------- 1 file changed, 69 insertions(+), 42 deletions(-) (limited to 'source4/libcli/auth/credentials.c') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 1749037e8f..5814053d5f 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -28,11 +28,10 @@ this call is made after the netr_ServerReqChallenge call */ -void creds_init(struct netr_CredentialState *creds, - const struct netr_Credential *client_challenge, - const struct netr_Credential *server_challenge, - const uint8 machine_password[16], - struct netr_Credential *initial_creds) +static void creds_init(struct netr_CredentialState *creds, + const struct netr_Credential *client_challenge, + const struct netr_Credential *server_challenge, + const uint8 machine_password[16]) { struct netr_Credential time_cred; uint32 sum[2]; @@ -46,36 +45,82 @@ void creds_init(struct netr_CredentialState *creds, cred_hash1(creds->session_key, sum2, machine_password); - creds->sequence = 0; + creds->sequence = time(NULL); SIVAL(time_cred.data, 0, IVAL(client_challenge->data, 0)); SIVAL(time_cred.data, 4, IVAL(client_challenge->data, 4)); + cred_hash2(creds->client.data, time_cred.data, creds->session_key); - cred_hash2(creds->cred2.data, time_cred.data, creds->session_key); + SIVAL(time_cred.data, 0, IVAL(server_challenge->data, 0)); + SIVAL(time_cred.data, 4, IVAL(server_challenge->data, 4)); + cred_hash2(creds->server.data, time_cred.data, creds->session_key); - creds->cred1 = *server_challenge; + creds->seed = creds->client; +} + + +/* + step the credentials to the next element in the chain +*/ +static void creds_step(struct netr_CredentialState *creds) +{ + struct netr_Credential time_cred; + + creds->sequence += 2; + + DEBUG(5,("\tseed %08x:%08x\n", + IVAL(creds->seed.data, 0), IVAL(creds->seed.data, 4))); + + SIVAL(time_cred.data, 0, IVAL(creds->seed.data, 0) + creds->sequence); + SIVAL(time_cred.data, 4, IVAL(creds->seed.data, 4)); + + DEBUG(5,("\tseed+time %08x:%08x\n", IVAL(time_cred.data, 0), IVAL(time_cred.data, 4))); + + cred_hash2(creds->client.data, time_cred.data, creds->session_key); + + DEBUG(5,("\tCLIENT %08x:%08x\n", + IVAL(creds->client.data, 0), IVAL(creds->client.data, 4))); + + SIVAL(time_cred.data, 0, IVAL(creds->seed.data, 0) + creds->sequence + 1); + SIVAL(time_cred.data, 4, IVAL(creds->seed.data, 4)); + + DEBUG(5,("\tseed+time+1 %08x:%08x\n", + IVAL(time_cred.data, 0), IVAL(time_cred.data, 4))); + + cred_hash2(creds->server.data, time_cred.data, creds->session_key); - *initial_creds = creds->cred2; + DEBUG(5,("\tSERVER %08x:%08x\n", + IVAL(creds->server.data, 0), IVAL(creds->server.data, 4))); + + creds->seed = time_cred; } /* - check that a credentials reply is correct + initialise the credentials chain and return the first client + credentials */ -BOOL creds_check(struct netr_CredentialState *creds, - const struct netr_Credential *received_credentials) +void creds_client_init(struct netr_CredentialState *creds, + const struct netr_Credential *client_challenge, + const struct netr_Credential *server_challenge, + const uint8 machine_password[16], + struct netr_Credential *initial_credential) { - struct netr_Credential cred2, time_cred; - uint32 sequence = creds->sequence?creds->sequence+1:0; + creds_init(creds, client_challenge, server_challenge, machine_password); + + *initial_credential = creds->client; +} - SIVAL(time_cred.data, 0, IVAL(creds->cred1.data, 0) + sequence); - SIVAL(time_cred.data, 4, IVAL(creds->cred1.data, 4)); - cred_hash2(cred2.data, time_cred.data, creds->session_key); - if (memcmp(received_credentials->data, cred2.data, 8) != 0) { +/* + check that a credentials reply from a server is correct +*/ +BOOL creds_client_check(struct netr_CredentialState *creds, + const struct netr_Credential *received_credentials) +{ + if (memcmp(received_credentials->data, creds->server.data, 8) != 0) { DEBUG(2,("credentials check failed\n")); return False; } - return True; } @@ -83,30 +128,12 @@ BOOL creds_check(struct netr_CredentialState *creds, produce the next authenticator in the sequence ready to send to the server */ -void creds_authenticator(struct netr_CredentialState *creds, - struct netr_Authenticator *next) +void creds_client_authenticator(struct netr_CredentialState *creds, + struct netr_Authenticator *next) { - struct netr_Credential cred2; - struct netr_Credential time_cred; - - if (creds->sequence == 0) { - creds->sequence = time(NULL); - } - - /* this step size is quite arbitrary - the client can choose - any sequence number it likes */ - creds->sequence += 2; - - creds->cred1 = creds->cred2; - - SIVAL(time_cred.data, 0, IVAL(creds->cred2.data, 0) + creds->sequence); - SIVAL(time_cred.data, 4, IVAL(creds->cred2.data, 4)); - - cred_hash2(cred2.data, time_cred.data, creds->session_key); - - creds->cred2 = cred2; + creds_step(creds); - next->cred = creds->cred2; + next->cred = creds->client; next->timestamp = creds->sequence; } @@ -114,7 +141,7 @@ void creds_authenticator(struct netr_CredentialState *creds, /* encrypt a 16 byte password buffer using the session key */ -void creds_encrypt(struct netr_CredentialState *creds, struct netr_Password *pass) +void creds_client_encrypt(struct netr_CredentialState *creds, struct netr_Password *pass) { struct netr_Password tmp; cred_hash3(tmp.data, pass->data, creds->session_key, 1); -- cgit From d65f0095c9acc11e9512c546a99af720d7dd5036 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Dec 2003 03:06:21 +0000 Subject: added netr_DatabaseSync(). It doesn't work as I haven't done schannel yet, but at least the request is understood by w2k3 Also modified pidl to allow multiple branches in a union to have the same element. This is used in netlogon. (This used to be commit 983c0e9683fa9666a6e055d1776ebeef8cd2e700) --- source4/libcli/auth/credentials.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'source4/libcli/auth/credentials.c') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 5814053d5f..acc083d57f 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -23,8 +23,7 @@ #include "includes.h" /* - initialise the credentials state and return the initial credentials - to be sent as part of a netr_ServerAuthenticate*() call. + initialise the credentials state this call is made after the netr_ServerReqChallenge call */ @@ -60,7 +59,8 @@ static void creds_init(struct netr_CredentialState *creds, /* - step the credentials to the next element in the chain + step the credentials to the next element in the chain, updating the + current client and server credentials and the seed */ static void creds_step(struct netr_CredentialState *creds) { @@ -96,6 +96,12 @@ static void creds_step(struct netr_CredentialState *creds) } + +/***************************************************************** +The above functions are common to the client and server interface +next comes the client specific functions +******************************************************************/ + /* initialise the credentials chain and return the first client credentials -- cgit From dce84ffd379012812170f68f7de8aab73123f0b3 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 9 May 2004 12:42:18 +0000 Subject: r610: - Merge the Samba3 'ntlm_auth --diagnostics' testsuite to Samba4. - This required using NETLOGON_NEG_AUTH2_FLAGS for the SetupCredentials2 negotiation flags, which is what Samba3 does, because otherwise the server uses different crypto. - This tests the returned session keys, which we decrypt. - Update the Samba4 notion of a 'session key' to be a DATA_BLOB in most places. - Fix session key code to return NT_STATUS_NO_SESSION_KEY if none is available. - Remove a useless argument to SMBsesskeygen_ntv1 - move netr_CredentialState from the .idl to the new credentials.h Andrew Bartlett (This used to be commit 44f8b5b53e6abd4de8a676f78d729988fadff320) --- source4/libcli/auth/credentials.c | 50 +++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 18 deletions(-) (limited to 'source4/libcli/auth/credentials.c') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index acc083d57f..638bff7e8b 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -27,7 +27,7 @@ this call is made after the netr_ServerReqChallenge call */ -static void creds_init(struct netr_CredentialState *creds, +static void creds_init(struct creds_CredentialState *creds, const struct netr_Credential *client_challenge, const struct netr_Credential *server_challenge, const uint8 machine_password[16]) @@ -48,11 +48,11 @@ static void creds_init(struct netr_CredentialState *creds, SIVAL(time_cred.data, 0, IVAL(client_challenge->data, 0)); SIVAL(time_cred.data, 4, IVAL(client_challenge->data, 4)); - cred_hash2(creds->client.data, time_cred.data, creds->session_key); + cred_hash2(creds->client.data, time_cred.data, creds->session_key, 1); SIVAL(time_cred.data, 0, IVAL(server_challenge->data, 0)); SIVAL(time_cred.data, 4, IVAL(server_challenge->data, 4)); - cred_hash2(creds->server.data, time_cred.data, creds->session_key); + cred_hash2(creds->server.data, time_cred.data, creds->session_key, 1); creds->seed = creds->client; } @@ -62,7 +62,7 @@ static void creds_init(struct netr_CredentialState *creds, step the credentials to the next element in the chain, updating the current client and server credentials and the seed */ -static void creds_step(struct netr_CredentialState *creds) +static void creds_step(struct creds_CredentialState *creds) { struct netr_Credential time_cred; @@ -76,7 +76,7 @@ static void creds_step(struct netr_CredentialState *creds) DEBUG(5,("\tseed+time %08x:%08x\n", IVAL(time_cred.data, 0), IVAL(time_cred.data, 4))); - cred_hash2(creds->client.data, time_cred.data, creds->session_key); + cred_hash2(creds->client.data, time_cred.data, creds->session_key, 1); DEBUG(5,("\tCLIENT %08x:%08x\n", IVAL(creds->client.data, 0), IVAL(creds->client.data, 4))); @@ -87,7 +87,7 @@ static void creds_step(struct netr_CredentialState *creds) DEBUG(5,("\tseed+time+1 %08x:%08x\n", IVAL(time_cred.data, 0), IVAL(time_cred.data, 4))); - cred_hash2(creds->server.data, time_cred.data, creds->session_key); + cred_hash2(creds->server.data, time_cred.data, creds->session_key, 1); DEBUG(5,("\tSERVER %08x:%08x\n", IVAL(creds->server.data, 0), IVAL(creds->server.data, 4))); @@ -95,7 +95,30 @@ static void creds_step(struct netr_CredentialState *creds) creds->seed = time_cred; } +/* + DES encrypt a 16 byte password buffer using the session key +*/ +void creds_des_encrypt(struct creds_CredentialState *creds, struct netr_Password *pass) +{ + struct netr_Password tmp; + cred_hash3(tmp.data, pass->data, creds->session_key, 1); + *pass = tmp; +} + +/* + ARCFOUR encrypt/decrypt a password buffer using the session key +*/ +void creds_arcfour_crypt(struct creds_CredentialState *creds, char *data, size_t len) +{ + DATA_BLOB session_key = data_blob(NULL, 16); + + memcpy(&session_key.data[0], creds->session_key, 8); + memset(&session_key.data[8], '\0', 8); + + SamOEMhashBlob(data, len, &session_key); + data_blob_free(&session_key); +} /***************************************************************** The above functions are common to the client and server interface @@ -106,7 +129,7 @@ next comes the client specific functions initialise the credentials chain and return the first client credentials */ -void creds_client_init(struct netr_CredentialState *creds, +void creds_client_init(struct creds_CredentialState *creds, const struct netr_Credential *client_challenge, const struct netr_Credential *server_challenge, const uint8 machine_password[16], @@ -120,7 +143,7 @@ void creds_client_init(struct netr_CredentialState *creds, /* check that a credentials reply from a server is correct */ -BOOL creds_client_check(struct netr_CredentialState *creds, +BOOL creds_client_check(struct creds_CredentialState *creds, const struct netr_Credential *received_credentials) { if (memcmp(received_credentials->data, creds->server.data, 8) != 0) { @@ -134,7 +157,7 @@ BOOL creds_client_check(struct netr_CredentialState *creds, produce the next authenticator in the sequence ready to send to the server */ -void creds_client_authenticator(struct netr_CredentialState *creds, +void creds_client_authenticator(struct creds_CredentialState *creds, struct netr_Authenticator *next) { creds_step(creds); @@ -144,12 +167,3 @@ void creds_client_authenticator(struct netr_CredentialState *creds, } -/* - encrypt a 16 byte password buffer using the session key -*/ -void creds_client_encrypt(struct netr_CredentialState *creds, struct netr_Password *pass) -{ - struct netr_Password tmp; - cred_hash3(tmp.data, pass->data, creds->session_key, 1); - *pass = tmp; -} -- cgit From 064e7447bebd715c8351d9a0ee31f648990f2336 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 15 May 2004 07:51:38 +0000 Subject: r743: Start on a NETLOGON server in Samba4. Currently this only authentiates the machine, not real users. As a consequence of running the Samba4 NETLOGON test against Samba4, I found a number of issues in the SAMR server, which I have addressed. There are more templates in the provison.ldif for this reason. I also added some debug to our credentials code, and fixed some bugs in the auth_sam module. The static buffer in generate_random_string() bit me badly, so I removed it in favor of a talloc based system. Andrew Bartlett (This used to be commit 94624e519b66def97758b8a48a01ffe9029176f0) --- source4/libcli/auth/credentials.c | 46 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) (limited to 'source4/libcli/auth/credentials.c') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 638bff7e8b..7d56f26b11 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -4,6 +4,7 @@ code to manipulate domain credentials Copyright (C) Andrew Tridgell 1997-2003 + Copyright (C) Andrew Bartlett 2004 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 @@ -36,6 +37,10 @@ static void creds_init(struct creds_CredentialState *creds, uint32 sum[2]; uint8 sum2[8]; + dump_data_pw("Client chall", client_challenge->data, sizeof(client_challenge->data)); + dump_data_pw("Server chall", server_challenge->data, sizeof(server_challenge->data)); + dump_data_pw("Machine Pass", machine_password, 16); + sum[0] = IVAL(client_challenge->data, 0) + IVAL(server_challenge->data, 0); sum[1] = IVAL(client_challenge->data, 4) + IVAL(server_challenge->data, 4); @@ -44,8 +49,6 @@ static void creds_init(struct creds_CredentialState *creds, cred_hash1(creds->session_key, sum2, machine_password); - creds->sequence = time(NULL); - SIVAL(time_cred.data, 0, IVAL(client_challenge->data, 0)); SIVAL(time_cred.data, 4, IVAL(client_challenge->data, 4)); cred_hash2(creds->client.data, time_cred.data, creds->session_key, 1); @@ -136,6 +139,7 @@ void creds_client_init(struct creds_CredentialState *creds, struct netr_Credential *initial_credential) { creds_init(creds, client_challenge, server_challenge, machine_password); + creds->sequence = time(NULL); *initial_credential = creds->client; } @@ -146,7 +150,8 @@ void creds_client_init(struct creds_CredentialState *creds, BOOL creds_client_check(struct creds_CredentialState *creds, const struct netr_Credential *received_credentials) { - if (memcmp(received_credentials->data, creds->server.data, 8) != 0) { + if (!received_credentials || + memcmp(received_credentials->data, creds->server.data, 8) != 0) { DEBUG(2,("credentials check failed\n")); return False; } @@ -167,3 +172,38 @@ void creds_client_authenticator(struct creds_CredentialState *creds, } +/***************************************************************** +The above functions are common to the client and server interface +next comes the server specific functions +******************************************************************/ + +/* + initialise the credentials chain and return the first server + credentials +*/ +void creds_server_init(struct creds_CredentialState *creds, + const struct netr_Credential *client_challenge, + const struct netr_Credential *server_challenge, + const uint8 machine_password[16], + struct netr_Credential *initial_credential) +{ + creds_init(creds, client_challenge, server_challenge, machine_password); + + *initial_credential = creds->server; +} + +/* + check that a credentials reply from a server is correct +*/ +BOOL creds_server_check(const struct creds_CredentialState *creds, + const struct netr_Credential *received_credentials) +{ + if (memcmp(received_credentials->data, creds->client.data, 8) != 0) { + DEBUG(2,("credentials check failed\n")); + dump_data_pw("client creds", creds->client.data, 8); + dump_data_pw("calc creds", received_credentials->data, 8); + return False; + } + return True; +} + -- cgit From 92dd542aa01f2c3b64ca104696c731919f4d7ec7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 16 May 2004 21:30:48 +0000 Subject: r754: Implement the SetPassword operation on the netlogon pipe. This involves allowing the password set code in samdb to take an already hashed password, and some fixes to our torture code. Andrew Bartlett (This used to be commit f9f581b5804a20785df06cde157b23c952edc2ce) --- source4/libcli/auth/credentials.c | 61 +++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 16 deletions(-) (limited to 'source4/libcli/auth/credentials.c') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 7d56f26b11..5fa9d5ac4a 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -69,8 +69,6 @@ static void creds_step(struct creds_CredentialState *creds) { struct netr_Credential time_cred; - creds->sequence += 2; - DEBUG(5,("\tseed %08x:%08x\n", IVAL(creds->seed.data, 0), IVAL(creds->seed.data, 4))); @@ -98,6 +96,7 @@ static void creds_step(struct creds_CredentialState *creds) creds->seed = time_cred; } + /* DES encrypt a 16 byte password buffer using the session key */ @@ -108,6 +107,16 @@ void creds_des_encrypt(struct creds_CredentialState *creds, struct netr_Password *pass = tmp; } +/* + DES decrypt a 16 byte password buffer using the session key +*/ +void creds_des_decrypt(struct creds_CredentialState *creds, struct netr_Password *pass) +{ + struct netr_Password tmp; + cred_hash3(tmp.data, pass->data, creds->session_key, 0); + *pass = tmp; +} + /* ARCFOUR encrypt/decrypt a password buffer using the session key */ @@ -138,12 +147,29 @@ void creds_client_init(struct creds_CredentialState *creds, const uint8 machine_password[16], struct netr_Credential *initial_credential) { - creds_init(creds, client_challenge, server_challenge, machine_password); creds->sequence = time(NULL); + creds_init(creds, client_challenge, server_challenge, machine_password); *initial_credential = creds->client; } +/* + step the credentials to the next element in the chain, updating the + current client and server credentials and the seed + + produce the next authenticator in the sequence ready to send to + the server +*/ +void creds_client_authenticator(struct creds_CredentialState *creds, + struct netr_Authenticator *next) +{ + creds->sequence += 2; + creds_step(creds); + + next->cred = creds->client; + next->timestamp = creds->sequence; +} + /* check that a credentials reply from a server is correct */ @@ -158,19 +184,6 @@ BOOL creds_client_check(struct creds_CredentialState *creds, return True; } -/* - produce the next authenticator in the sequence ready to send to - the server -*/ -void creds_client_authenticator(struct creds_CredentialState *creds, - struct netr_Authenticator *next) -{ - creds_step(creds); - - next->cred = creds->client; - next->timestamp = creds->sequence; -} - /***************************************************************** The above functions are common to the client and server interface @@ -207,3 +220,19 @@ BOOL creds_server_check(const struct creds_CredentialState *creds, return True; } +BOOL creds_server_step_check(struct creds_CredentialState *creds, + struct netr_Authenticator *received_authenticator, + struct netr_Authenticator *return_authenticator) +{ + /* Should we check that this is increasing? */ + creds->sequence = received_authenticator->timestamp; + creds_step(creds); + if (creds_server_check(creds, &received_authenticator->cred)) { + return_authenticator->cred = creds->server; + return_authenticator->timestamp = creds->sequence; + return True; + } else { + ZERO_STRUCTP(return_authenticator); + return False; + } +} -- cgit From f9d8f8843dc0ab8c9d59abde7222e0f118b86b5d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 25 May 2004 16:24:13 +0000 Subject: r884: convert samba4 to use [u]int32_t instead of [u]int32 metze (This used to be commit 0e5517d937a2eb7cf707991d1c7498c1ab456095) --- source4/libcli/auth/credentials.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/auth/credentials.c') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 5fa9d5ac4a..139b17d5b3 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -34,7 +34,7 @@ static void creds_init(struct creds_CredentialState *creds, const uint8 machine_password[16]) { struct netr_Credential time_cred; - uint32 sum[2]; + uint32_t sum[2]; uint8 sum2[8]; dump_data_pw("Client chall", client_challenge->data, sizeof(client_challenge->data)); -- cgit From fcd718c7d8a6850ae8719f23ed044b06b57501cd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 25 May 2004 17:50:17 +0000 Subject: r890: convert samba4 to use [u]int8_t instead of [u]int8 metze (This used to be commit 2986c5f08c8f0c26a2ea7b6ce20aae025183109f) --- source4/libcli/auth/credentials.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/libcli/auth/credentials.c') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 139b17d5b3..cf6d0cca62 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -31,11 +31,11 @@ static void creds_init(struct creds_CredentialState *creds, const struct netr_Credential *client_challenge, const struct netr_Credential *server_challenge, - const uint8 machine_password[16]) + const uint8_t machine_password[16]) { struct netr_Credential time_cred; uint32_t sum[2]; - uint8 sum2[8]; + uint8_t sum2[8]; dump_data_pw("Client chall", client_challenge->data, sizeof(client_challenge->data)); dump_data_pw("Server chall", server_challenge->data, sizeof(server_challenge->data)); @@ -144,7 +144,7 @@ next comes the client specific functions void creds_client_init(struct creds_CredentialState *creds, const struct netr_Credential *client_challenge, const struct netr_Credential *server_challenge, - const uint8 machine_password[16], + const uint8_t machine_password[16], struct netr_Credential *initial_credential) { creds->sequence = time(NULL); @@ -197,7 +197,7 @@ next comes the server specific functions void creds_server_init(struct creds_CredentialState *creds, const struct netr_Credential *client_challenge, const struct netr_Credential *server_challenge, - const uint8 machine_password[16], + const uint8_t machine_password[16], struct netr_Credential *initial_credential) { creds_init(creds, client_challenge, server_challenge, machine_password); -- cgit From 8087d844ef59a82617be51f7c887b9bafe362f80 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 3 Jun 2004 23:15:16 +0000 Subject: r995: - renamed many of our crypto routines to use the industry standard names rather than our crazy naming scheme. So DES is now called des_crypt() rather than smbhash() - added the code from the solution of the ADS crypto challenge that allows Samba to correctly handle a 128 bit session key in all of the netr_ServerAuthenticateX() varients. A huge thanks to Luke Howard from PADL for solving this one! - restructured the server side rpc authentication to allow for other than NTLMSSP sign and seal. This commit just adds the structure, the next commit will add schannel server side support. - added 128 bit session key support to our client side code, and testing against w2k3 with smbtorture. Works well. (This used to be commit 729b2f41c924a0b435d44a14209e6dacc2304cee) --- source4/libcli/auth/credentials.c | 106 +++++++++++++++++++++++++++----------- 1 file changed, 76 insertions(+), 30 deletions(-) (limited to 'source4/libcli/auth/credentials.c') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index cf6d0cca62..27a3e32cf3 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -24,38 +24,66 @@ #include "includes.h" /* - initialise the credentials state + initialise the credentials state for old-style 64 bit session keys this call is made after the netr_ServerReqChallenge call */ -static void creds_init(struct creds_CredentialState *creds, - const struct netr_Credential *client_challenge, - const struct netr_Credential *server_challenge, - const uint8_t machine_password[16]) +static void creds_init_64bit(struct creds_CredentialState *creds, + const struct netr_Credential *client_challenge, + const struct netr_Credential *server_challenge, + const uint8_t machine_password[16]) { - struct netr_Credential time_cred; uint32_t sum[2]; uint8_t sum2[8]; - dump_data_pw("Client chall", client_challenge->data, sizeof(client_challenge->data)); - dump_data_pw("Server chall", server_challenge->data, sizeof(server_challenge->data)); - dump_data_pw("Machine Pass", machine_password, 16); - sum[0] = IVAL(client_challenge->data, 0) + IVAL(server_challenge->data, 0); sum[1] = IVAL(client_challenge->data, 4) + IVAL(server_challenge->data, 4); SIVAL(sum2,0,sum[0]); SIVAL(sum2,4,sum[1]); - cred_hash1(creds->session_key, sum2, machine_password); + ZERO_STRUCT(creds->session_key); - SIVAL(time_cred.data, 0, IVAL(client_challenge->data, 0)); - SIVAL(time_cred.data, 4, IVAL(client_challenge->data, 4)); - cred_hash2(creds->client.data, time_cred.data, creds->session_key, 1); + des_crypt128(creds->session_key, sum2, machine_password); - SIVAL(time_cred.data, 0, IVAL(server_challenge->data, 0)); - SIVAL(time_cred.data, 4, IVAL(server_challenge->data, 4)); - cred_hash2(creds->server.data, time_cred.data, creds->session_key, 1); + des_crypt112(creds->client.data, client_challenge->data, creds->session_key, 1); + des_crypt112(creds->server.data, server_challenge->data, creds->session_key, 1); + + creds->seed = creds->client; +} + +/* + initialise the credentials state for ADS-style 128 bit session keys + + this call is made after the netr_ServerReqChallenge call +*/ +static void creds_init_128bit(struct creds_CredentialState *creds, + const struct netr_Credential *client_challenge, + const struct netr_Credential *server_challenge, + const uint8_t machine_password[16]) +{ + unsigned char zero[4], tmp[16]; + HMACMD5Context ctx; + struct MD5Context md5; + + ZERO_STRUCT(creds->session_key); + + memset(zero, 0, sizeof(zero)); + + hmac_md5_init_rfc2104(machine_password, 16, &ctx); + MD5Init(&md5); + MD5Update(&md5, zero, sizeof(zero)); + MD5Update(&md5, client_challenge->data, 8); + MD5Update(&md5, server_challenge->data, 8); + MD5Final(tmp, &md5); + hmac_md5_update(tmp, 16, &ctx); + hmac_md5_final(creds->session_key, &ctx); + + creds->client = *client_challenge; + creds->server = *server_challenge; + + des_crypt112(creds->client.data, client_challenge->data, creds->session_key, 1); + des_crypt112(creds->server.data, server_challenge->data, creds->session_key, 1); creds->seed = creds->client; } @@ -77,7 +105,7 @@ static void creds_step(struct creds_CredentialState *creds) DEBUG(5,("\tseed+time %08x:%08x\n", IVAL(time_cred.data, 0), IVAL(time_cred.data, 4))); - cred_hash2(creds->client.data, time_cred.data, creds->session_key, 1); + des_crypt112(creds->client.data, time_cred.data, creds->session_key, 1); DEBUG(5,("\tCLIENT %08x:%08x\n", IVAL(creds->client.data, 0), IVAL(creds->client.data, 4))); @@ -88,7 +116,7 @@ static void creds_step(struct creds_CredentialState *creds) DEBUG(5,("\tseed+time+1 %08x:%08x\n", IVAL(time_cred.data, 0), IVAL(time_cred.data, 4))); - cred_hash2(creds->server.data, time_cred.data, creds->session_key, 1); + des_crypt112(creds->server.data, time_cred.data, creds->session_key, 1); DEBUG(5,("\tSERVER %08x:%08x\n", IVAL(creds->server.data, 0), IVAL(creds->server.data, 4))); @@ -103,7 +131,7 @@ static void creds_step(struct creds_CredentialState *creds) void creds_des_encrypt(struct creds_CredentialState *creds, struct netr_Password *pass) { struct netr_Password tmp; - cred_hash3(tmp.data, pass->data, creds->session_key, 1); + des_crypt112_16(tmp.data, pass->data, creds->session_key, 1); *pass = tmp; } @@ -113,7 +141,7 @@ void creds_des_encrypt(struct creds_CredentialState *creds, struct netr_Password void creds_des_decrypt(struct creds_CredentialState *creds, struct netr_Password *pass) { struct netr_Password tmp; - cred_hash3(tmp.data, pass->data, creds->session_key, 0); + des_crypt112_16(tmp.data, pass->data, creds->session_key, 0); *pass = tmp; } @@ -122,12 +150,9 @@ void creds_des_decrypt(struct creds_CredentialState *creds, struct netr_Password */ void creds_arcfour_crypt(struct creds_CredentialState *creds, char *data, size_t len) { - DATA_BLOB session_key = data_blob(NULL, 16); - - memcpy(&session_key.data[0], creds->session_key, 8); - memset(&session_key.data[8], '\0', 8); + DATA_BLOB session_key = data_blob(creds->session_key, 16); - SamOEMhashBlob(data, len, &session_key); + arcfour_crypt_blob(data, len, &session_key); data_blob_free(&session_key); } @@ -145,10 +170,24 @@ void creds_client_init(struct creds_CredentialState *creds, const struct netr_Credential *client_challenge, const struct netr_Credential *server_challenge, const uint8_t machine_password[16], - struct netr_Credential *initial_credential) + struct netr_Credential *initial_credential, + uint32_t negotiate_flags) { creds->sequence = time(NULL); - creds_init(creds, client_challenge, server_challenge, machine_password); + creds->negotiate_flags = negotiate_flags; + + dump_data_pw("Client chall", client_challenge->data, sizeof(client_challenge->data)); + dump_data_pw("Server chall", server_challenge->data, sizeof(server_challenge->data)); + dump_data_pw("Machine Pass", machine_password, 16); + + if (negotiate_flags & NETLOGON_NEG_128BIT) { + creds_init_128bit(creds, client_challenge, server_challenge, machine_password); + } else { + creds_init_64bit(creds, client_challenge, server_challenge, machine_password); + } + + dump_data_pw("Session key", creds->session_key, 16); + dump_data_pw("Credential ", creds->client.data, 8); *initial_credential = creds->client; } @@ -198,9 +237,16 @@ void creds_server_init(struct creds_CredentialState *creds, const struct netr_Credential *client_challenge, const struct netr_Credential *server_challenge, const uint8_t machine_password[16], - struct netr_Credential *initial_credential) + struct netr_Credential *initial_credential, + uint32_t negotiate_flags) { - creds_init(creds, client_challenge, server_challenge, machine_password); + if (negotiate_flags & NETLOGON_NEG_128BIT) { + creds_init_128bit(creds, client_challenge, server_challenge, + machine_password); + } else { + creds_init_64bit(creds, client_challenge, server_challenge, + machine_password); + } *initial_credential = creds->server; } -- cgit From 9eb6afb00d85c1a7b367d51a19eed41172f7a2e9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 4 Jun 2004 11:58:46 +0000 Subject: r1009: Make all users of NT and LM passwords use the samr_Password structure. This includes the netlogon pipe, for the machine account password change system. Andrew Bartlett (This used to be commit 49d545a82057ee8b60d50aa55e908efe59875150) --- source4/libcli/auth/credentials.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/libcli/auth/credentials.c') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 27a3e32cf3..e0989eff4b 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -128,20 +128,20 @@ static void creds_step(struct creds_CredentialState *creds) /* DES encrypt a 16 byte password buffer using the session key */ -void creds_des_encrypt(struct creds_CredentialState *creds, struct netr_Password *pass) +void creds_des_encrypt(struct creds_CredentialState *creds, struct samr_Password *pass) { - struct netr_Password tmp; - des_crypt112_16(tmp.data, pass->data, creds->session_key, 1); + struct samr_Password tmp; + des_crypt112_16(tmp.hash, pass->hash, creds->session_key, 1); *pass = tmp; } /* DES decrypt a 16 byte password buffer using the session key */ -void creds_des_decrypt(struct creds_CredentialState *creds, struct netr_Password *pass) +void creds_des_decrypt(struct creds_CredentialState *creds, struct samr_Password *pass) { - struct netr_Password tmp; - des_crypt112_16(tmp.data, pass->data, creds->session_key, 0); + struct samr_Password tmp; + des_crypt112_16(tmp.hash, pass->hash, creds->session_key, 0); *pass = tmp; } -- cgit From ae067cdaf70c7725237ec58b5e23bc6f525594c2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 5 Jun 2004 03:14:59 +0000 Subject: r1024: Use samr_Password for the machine password here - this ensures we can never pass in something of the wrong length. Andrew Bartlett (This used to be commit d6999ea9c07d8652b0d63147e7294bc35e7063fe) --- source4/libcli/auth/credentials.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source4/libcli/auth/credentials.c') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index e0989eff4b..1d4db74633 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -31,7 +31,7 @@ static void creds_init_64bit(struct creds_CredentialState *creds, const struct netr_Credential *client_challenge, const struct netr_Credential *server_challenge, - const uint8_t machine_password[16]) + const struct samr_Password *machine_password) { uint32_t sum[2]; uint8_t sum2[8]; @@ -44,7 +44,7 @@ static void creds_init_64bit(struct creds_CredentialState *creds, ZERO_STRUCT(creds->session_key); - des_crypt128(creds->session_key, sum2, machine_password); + des_crypt128(creds->session_key, sum2, machine_password->hash); des_crypt112(creds->client.data, client_challenge->data, creds->session_key, 1); des_crypt112(creds->server.data, server_challenge->data, creds->session_key, 1); @@ -60,7 +60,7 @@ static void creds_init_64bit(struct creds_CredentialState *creds, static void creds_init_128bit(struct creds_CredentialState *creds, const struct netr_Credential *client_challenge, const struct netr_Credential *server_challenge, - const uint8_t machine_password[16]) + const struct samr_Password *machine_password) { unsigned char zero[4], tmp[16]; HMACMD5Context ctx; @@ -70,13 +70,13 @@ static void creds_init_128bit(struct creds_CredentialState *creds, memset(zero, 0, sizeof(zero)); - hmac_md5_init_rfc2104(machine_password, 16, &ctx); + hmac_md5_init_rfc2104(machine_password->hash, sizeof(machine_password->hash), &ctx); MD5Init(&md5); MD5Update(&md5, zero, sizeof(zero)); MD5Update(&md5, client_challenge->data, 8); MD5Update(&md5, server_challenge->data, 8); MD5Final(tmp, &md5); - hmac_md5_update(tmp, 16, &ctx); + hmac_md5_update(tmp, sizeof(tmp), &ctx); hmac_md5_final(creds->session_key, &ctx); creds->client = *client_challenge; @@ -169,7 +169,7 @@ next comes the client specific functions void creds_client_init(struct creds_CredentialState *creds, const struct netr_Credential *client_challenge, const struct netr_Credential *server_challenge, - const uint8_t machine_password[16], + const struct samr_Password *machine_password, struct netr_Credential *initial_credential, uint32_t negotiate_flags) { @@ -178,7 +178,7 @@ void creds_client_init(struct creds_CredentialState *creds, dump_data_pw("Client chall", client_challenge->data, sizeof(client_challenge->data)); dump_data_pw("Server chall", server_challenge->data, sizeof(server_challenge->data)); - dump_data_pw("Machine Pass", machine_password, 16); + dump_data_pw("Machine Pass", machine_password->hash, sizeof(machine_password->hash)); if (negotiate_flags & NETLOGON_NEG_128BIT) { creds_init_128bit(creds, client_challenge, server_challenge, machine_password); @@ -236,7 +236,7 @@ next comes the server specific functions void creds_server_init(struct creds_CredentialState *creds, const struct netr_Credential *client_challenge, const struct netr_Credential *server_challenge, - const uint8_t machine_password[16], + const struct samr_Password *machine_password, struct netr_Credential *initial_credential, uint32_t negotiate_flags) { -- cgit From 791ee4a58110fc25d5f66e0e21372c766e400bd0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 14 Jun 2004 07:28:05 +0000 Subject: r1134: added a TODO regarding schannel credentials (This used to be commit 17dacf494ac25bb6d9f6dea8cb81968ea2b84c55) --- source4/libcli/auth/credentials.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli/auth/credentials.c') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 1d4db74633..60feee7884 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -270,7 +270,8 @@ BOOL creds_server_step_check(struct creds_CredentialState *creds, struct netr_Authenticator *received_authenticator, struct netr_Authenticator *return_authenticator) { - /* Should we check that this is increasing? */ + /* TODO: this may allow the a replay attack on a non-signed + connection. Should we check that this is increasing? */ creds->sequence = received_authenticator->timestamp; creds_step(creds); if (creds_server_check(creds, &received_authenticator->cred)) { -- cgit From ead3508ac81ff3ed2a48753f3b5e23537ba6ec73 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 00:24:21 +0000 Subject: r3447: more include/system/XXX.h include files (This used to be commit 264ce9181089922547e8f6f67116f2d7277a5105) --- source4/libcli/auth/credentials.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli/auth/credentials.c') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 60feee7884..f3f8324005 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -22,6 +22,7 @@ */ #include "includes.h" +#include "system/time.h" /* initialise the credentials state for old-style 64 bit session keys -- cgit From edbfc0f6e70150e321822365bf0eead2821551bd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 02:57:18 +0000 Subject: r3453: - split out the auth and popt includes - tidied up some of the system includes - moved a few more structures back from misc.idl to netlogon.idl and samr.idl now that pidl knows about inter-IDL dependencies (This used to be commit 7b7477ac42d96faac1b0ff361525d2c63cedfc64) --- source4/libcli/auth/credentials.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli/auth/credentials.c') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index f3f8324005..4a17b13910 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -23,6 +23,7 @@ #include "includes.h" #include "system/time.h" +#include "auth/auth.h" /* initialise the credentials state for old-style 64 bit session keys -- cgit From a1d0b97ed40fe6985bb45b1715309638e7faaffc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 06:14:15 +0000 Subject: r3462: separate out the crypto includes (This used to be commit 3f75117db921e493bb77a5dc14b8ce91a6288f30) --- source4/libcli/auth/credentials.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli/auth/credentials.c') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 4a17b13910..a09d767e89 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -24,6 +24,7 @@ #include "includes.h" #include "system/time.h" #include "auth/auth.h" +#include "lib/crypto/crypto.h" /* initialise the credentials state for old-style 64 bit session keys -- cgit From a8db4dcf03bccb2e1b954d097e758d6c7780db9e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 11 Nov 2004 04:32:01 +0000 Subject: r3677: Seperate the SamLogon tests from the main RPC-NETLOGON test into a RPC-SAMLOGON of their own. I have expanded the tests to validate the use of various flags, which change some of the crypto behaviour. Andrew Bartlett (This used to be commit 3a140a3691ce49ebf4d1efcb99cfffd26c68a28f) --- source4/libcli/auth/credentials.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'source4/libcli/auth/credentials.c') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index a09d767e89..ec41ebf4bd 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -25,6 +25,7 @@ #include "system/time.h" #include "auth/auth.h" #include "lib/crypto/crypto.h" +#include "librpc/gen_ndr/ndr_netlogon.h" /* initialise the credentials state for old-style 64 bit session keys @@ -128,6 +129,26 @@ static void creds_step(struct creds_CredentialState *creds) } +/* + DES encrypt a 8 byte LMSessionKey buffer using the Netlogon session key +*/ +void creds_des_encrypt_LMKey(struct creds_CredentialState *creds, struct netr_LMSessionKey *key) +{ + struct netr_LMSessionKey tmp; + des_crypt56(tmp.key, key->key, creds->session_key, 1); + *key = tmp; +} + +/* + DES decrypt a 8 byte LMSessionKey buffer using the Netlogon session key +*/ +void creds_des_decrypt_LMKey(struct creds_CredentialState *creds, struct netr_LMSessionKey *key) +{ + struct netr_LMSessionKey tmp; + des_crypt56(tmp.key, key->key, creds->session_key, 0); + *key = tmp; +} + /* DES encrypt a 16 byte password buffer using the session key */ -- cgit From ca751e2638ca0fbb03b54e1aaa4ed1316e903947 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 22 Nov 2004 10:59:46 +0000 Subject: r3906: fix compiler warnings metze (This used to be commit df924e18220aedbfbfae569e1fb37da652914c0b) --- source4/libcli/auth/credentials.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/auth/credentials.c') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index ec41ebf4bd..a61660d776 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -172,7 +172,7 @@ void creds_des_decrypt(struct creds_CredentialState *creds, struct samr_Password /* ARCFOUR encrypt/decrypt a password buffer using the session key */ -void creds_arcfour_crypt(struct creds_CredentialState *creds, char *data, size_t len) +void creds_arcfour_crypt(struct creds_CredentialState *creds, uint8_t *data, size_t len) { DATA_BLOB session_key = data_blob(creds->session_key, 16); -- cgit From 8eb981c90a6094b15d4b71cc14fee4f23c713cf8 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 3 Jan 2005 06:23:02 +0000 Subject: r4499: Almost make our Samba4 server pass the RPC-SAMLOGON torture test. I just need to fix a couple of NTLMv2 issues before we can fully pass, and put this in test_rpc.sh, as a 'should pass' test. Andrew Bartlett (This used to be commit 4b52409e385366d87724bb79f4fad4803e8ecfec) --- source4/libcli/auth/credentials.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'source4/libcli/auth/credentials.c') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index a61660d776..8cae71180c 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -273,6 +273,7 @@ void creds_server_init(struct creds_CredentialState *creds, } *initial_credential = creds->server; + creds->negotiate_flags = negotiate_flags; } /* @@ -290,10 +291,14 @@ BOOL creds_server_check(const struct creds_CredentialState *creds, return True; } -BOOL creds_server_step_check(struct creds_CredentialState *creds, +NTSTATUS creds_server_step_check(struct creds_CredentialState *creds, struct netr_Authenticator *received_authenticator, struct netr_Authenticator *return_authenticator) { + if (!received_authenticator || !return_authenticator) { + return NT_STATUS_INVALID_PARAMETER; + } + /* TODO: this may allow the a replay attack on a non-signed connection. Should we check that this is increasing? */ creds->sequence = received_authenticator->timestamp; @@ -301,9 +306,9 @@ BOOL creds_server_step_check(struct creds_CredentialState *creds, if (creds_server_check(creds, &received_authenticator->cred)) { return_authenticator->cred = creds->server; return_authenticator->timestamp = creds->sequence; - return True; + return NT_STATUS_OK; } else { ZERO_STRUCTP(return_authenticator); - return False; + return NT_STATUS_ACCESS_DENIED; } } -- cgit From e8c06b9221d9818042ea8a08efccfc88f17a9e3e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 10 Jan 2005 12:30:13 +0000 Subject: r4641: Push a few more details into the schannel ldb, and into the credentials struct it maintains. Clearly much of this will be replaced with some system to pass and store the session_info, as that is the 'right way' to handle this. Andrew Bartlett (This used to be commit c6fcb33a887fbf0c0b42c3bc331df942a985128c) --- source4/libcli/auth/credentials.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source4/libcli/auth/credentials.c') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 8cae71180c..18ce6fec1b 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -292,13 +292,17 @@ BOOL creds_server_check(const struct creds_CredentialState *creds, } NTSTATUS creds_server_step_check(struct creds_CredentialState *creds, - struct netr_Authenticator *received_authenticator, - struct netr_Authenticator *return_authenticator) + struct netr_Authenticator *received_authenticator, + struct netr_Authenticator *return_authenticator) { if (!received_authenticator || !return_authenticator) { return NT_STATUS_INVALID_PARAMETER; } + if (!creds) { + return NT_STATUS_ACCESS_DENIED; + } + /* TODO: this may allow the a replay attack on a non-signed connection. Should we check that this is increasing? */ creds->sequence = received_authenticator->timestamp; -- cgit From 9515fc4406464b6a015a06d89ca0370810977486 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 11 Feb 2005 02:08:39 +0000 Subject: r5322: removed a whole bunch of #include lines that minimal_includes.pl thinks are not needed. Now to see how this fares on the build farm :) (This used to be commit 80ffcc650c9c86141507edd8338b97814a85f868) --- source4/libcli/auth/credentials.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/libcli/auth/credentials.c') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 18ce6fec1b..bcb462ae9d 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -25,7 +25,6 @@ #include "system/time.h" #include "auth/auth.h" #include "lib/crypto/crypto.h" -#include "librpc/gen_ndr/ndr_netlogon.h" /* initialise the credentials state for old-style 64 bit session keys -- cgit From df643022136a4b229aca817f5b57f7302a97f852 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 19 Mar 2005 08:34:43 +0000 Subject: r5902: A rather large change... I wanted to add a simple 'workstation' argument to the DCERPC authenticated binding calls, but this patch kind of grew from there. With SCHANNEL, the 'workstation' name (the netbios name of the client) matters, as this is what ties the session between the NETLOGON ops and the SCHANNEL bind. This changes a lot of files, and these will again be changed when jelmer does the credentials work. I also correct some schannel IDL to distinguish between workstation names and account names. The distinction matters for domain trust accounts. Issues in handling this (issues with lifetime of talloc pointers) caused me to change the 'creds_CredentialsState' and 'struct dcerpc_binding' pointers to always be talloc()ed pointers. In the schannel DB, we now store both the domain and computername, and query on both. This should ensure we fault correctly when the domain is specified incorrectly in the SCHANNEL bind. In the RPC-SCHANNEL test, I finally fixed a bug that vl pointed out, where the comment claimed we re-used a connection, but in fact we made a new connection. This was achived by breaking apart some of the dcerpc_secondary_connection() logic. The addition of workstation handling was also propogated to NTLMSSP and GENSEC, for completeness. The RPC-SAMSYNC test has been cleaned up a little, using a loop over usernames/passwords rather than manually expanded tests. This will be expanded further (the code in #if 0 in this patch) to use a newly created user account for testing. In making this test pass test_rpc.sh, I found a bug in the RPC-ECHO server, caused by the removal of [ref] and the assoicated pointer from the IDL. This has been re-added, until the underlying pidl issues are solved. (This used to be commit 824289dcc20908ddec957a4a892a103eec2da9b9) --- source4/libcli/auth/credentials.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source4/libcli/auth/credentials.c') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index bcb462ae9d..90b8313c9d 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -192,12 +192,18 @@ next comes the client specific functions void creds_client_init(struct creds_CredentialState *creds, const struct netr_Credential *client_challenge, const struct netr_Credential *server_challenge, + const char *computer_name, + const char *domain, + const char *account_name, const struct samr_Password *machine_password, struct netr_Credential *initial_credential, uint32_t negotiate_flags) { creds->sequence = time(NULL); creds->negotiate_flags = negotiate_flags; + creds->computer_name = talloc_strdup(creds, computer_name); + creds->domain = talloc_strdup(creds, domain); + creds->account_name = talloc_strdup(creds, account_name); dump_data_pw("Client chall", client_challenge->data, sizeof(client_challenge->data)); dump_data_pw("Server chall", server_challenge->data, sizeof(server_challenge->data)); -- cgit From 2eb3d680625286431a3a60e37b75f47e0738f253 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 24 Mar 2005 04:14:06 +0000 Subject: r6028: A MAJOR update to intergrate the new credentails system fully with GENSEC, and to pull SCHANNEL into GENSEC, by making it less 'special'. GENSEC now no longer has it's own handling of 'set username' etc, instead it uses cli_credentials calls. In order to link the credentails code right though Samba, a lot of interfaces have changed to remove 'username, domain, password' arguments, and these have been replaced with a single 'struct cli_credentials'. In the session setup code, a new parameter 'workgroup' contains the client/server current workgroup, which seems unrelated to the authentication exchange (it was being filled in from the auth info). This allows in particular kerberos to only call back for passwords when it actually needs to perform the kinit. The kerberos code has been modified not to use the SPNEGO provided 'principal name' (in the mechListMIC), but to instead use the name the host was connected to as. This better matches Microsoft behaviour, is more secure and allows better use of standard kerberos functions. To achieve this, I made changes to our socket code so that the hostname (before name resolution) is now recorded on the socket. In schannel, most of the code from librpc/rpc/dcerpc_schannel.c is now in libcli/auth/schannel.c, and it looks much more like a standard GENSEC module. The actual sign/seal code moved to libcli/auth/schannel_sign.c in a previous commit. The schannel credentails structure is now merged with the rest of the credentails, as many of the values (username, workstation, domain) where already present there. This makes handling this in a generic manner much easier, as there is no longer a custom entry-point. The auth_domain module continues to be developed, but is now just as functional as auth_winbind. The changes here are consequential to the schannel changes. The only removed function at this point is the RPC-LOGIN test (simulating the load of a WinXP login), which needs much more work to clean it up (it contains copies of too much code from all over the torture suite, and I havn't been able to penetrate its 'structure'). Andrew Bartlett (This used to be commit 2301a4b38a21aa60917973451687063d83d18d66) --- source4/libcli/auth/credentials.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'source4/libcli/auth/credentials.c') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 90b8313c9d..bcb462ae9d 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -192,18 +192,12 @@ next comes the client specific functions void creds_client_init(struct creds_CredentialState *creds, const struct netr_Credential *client_challenge, const struct netr_Credential *server_challenge, - const char *computer_name, - const char *domain, - const char *account_name, const struct samr_Password *machine_password, struct netr_Credential *initial_credential, uint32_t negotiate_flags) { creds->sequence = time(NULL); creds->negotiate_flags = negotiate_flags; - creds->computer_name = talloc_strdup(creds, computer_name); - creds->domain = talloc_strdup(creds, domain); - creds->account_name = talloc_strdup(creds, account_name); dump_data_pw("Client chall", client_challenge->data, sizeof(client_challenge->data)); dump_data_pw("Server chall", server_challenge->data, sizeof(server_challenge->data)); -- cgit From 8aff6e005e36c21ebc9dd5a0dcd41f1c0d5c9c2f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 9 Oct 2005 12:38:23 +0000 Subject: r10845: Add new function to decrypt the session keys in samlogon responses. Andrew Bartlett (This used to be commit 6d24d8d12cdc64b180fd6277f0775e943f26e82b) --- source4/libcli/auth/credentials.c | 44 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'source4/libcli/auth/credentials.c') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index bcb462ae9d..7cfccf446c 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -315,3 +315,47 @@ NTSTATUS creds_server_step_check(struct creds_CredentialState *creds, return NT_STATUS_ACCESS_DENIED; } } + +void creds_decrypt_samlogon(struct creds_CredentialState *creds, + uint16_t validation_level, + union netr_Validation *validation) +{ + static const char zeros[16]; + + struct netr_SamBaseInfo *base; + switch (validation_level) { + case 2: + base = &validation->sam2->base; + break; + case 3: + base = &validation->sam3->base; + break; + case 6: + base = &validation->sam6->base; + break; + } + /* find and decyrpt the session keys, return in parameters above */ + if (validation_level == 6) { + /* they aren't encrypted! */ + } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { + if (memcmp(base->key.key, zeros, + sizeof(base->key.key)) != 0) { + creds_arcfour_crypt(creds, + base->key.key, + sizeof(base->key.key)); + } + + if (memcmp(base->LMSessKey.key, zeros, + sizeof(base->LMSessKey.key)) != 0) { + creds_arcfour_crypt(creds, + base->LMSessKey.key, + sizeof(base->LMSessKey.key)); + } + } else { + if (memcmp(base->LMSessKey.key, zeros, + sizeof(base->LMSessKey.key)) != 0) { + creds_des_decrypt_LMKey(creds, + &base->LMSessKey); + } + } +} -- cgit From 43adda56b6a175fa2a9e4c6f20ca921e0b1c5fab Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 9 Oct 2005 13:03:52 +0000 Subject: r10847: Fix up new 'decrypt samlogon reply' routine to be more robust, and use it in the RPC-SAMLOGON test. Andrew Bartlett (This used to be commit 675b7df2eedbcb7ea89c0411f76429d8e2357222) --- source4/libcli/auth/credentials.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'source4/libcli/auth/credentials.c') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 7cfccf446c..3f055a657d 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -322,18 +322,32 @@ void creds_decrypt_samlogon(struct creds_CredentialState *creds, { static const char zeros[16]; - struct netr_SamBaseInfo *base; + struct netr_SamBaseInfo *base = NULL; switch (validation_level) { case 2: - base = &validation->sam2->base; + if (validation->sam2) { + base = &validation->sam2->base; + } break; case 3: - base = &validation->sam3->base; + if (validation->sam3) { + base = &validation->sam3->base; + } break; case 6: - base = &validation->sam6->base; + if (validation->sam6) { + base = &validation->sam6->base; + } break; + default: + /* If we can't find it, we can't very well decrypt it */ + return; } + + if (!base) { + return; + } + /* find and decyrpt the session keys, return in parameters above */ if (validation_level == 6) { /* they aren't encrypted! */ -- cgit From 935af3eb1963761b4c8fd9e0e9902ad592f948bf Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 25 Mar 2006 18:47:47 +0000 Subject: r14724: Rearrange some source files, install more headers. (This used to be commit 7146c1600f29c349e5bb78f810e7e170b535dd37) --- source4/libcli/auth/credentials.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli/auth/credentials.c') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 3f055a657d..5bae30f580 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -25,6 +25,7 @@ #include "system/time.h" #include "auth/auth.h" #include "lib/crypto/crypto.h" +#include "libcli/auth/libcli_auth.h" /* initialise the credentials state for old-style 64 bit session keys -- cgit From 0479a2f1cbae51fcd8dbdc3c148c808421fb4d25 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 02:07:03 +0000 Subject: r23792: convert Samba4 to GPLv3 There are still a few tidyups of old FSF addresses to come (in both s3 and s4). More commits soon. (This used to be commit fcf38a38ac691abd0fa51b89dc951a08e89fdafa) --- source4/libcli/auth/credentials.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source4/libcli/auth/credentials.c') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 5bae30f580..feb8c92a0b 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -8,7 +8,7 @@ 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 - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -17,8 +17,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" -- cgit From 2151cde58014ea2e822c13d2f8a369b45dc19ca8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 6 Oct 2007 22:28:14 +0000 Subject: r25554: Convert last instances of BOOL, True and False to the standard types. (This used to be commit 566aa14139510788548a874e9213d91317f83ca9) --- source4/libcli/auth/credentials.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/libcli/auth/credentials.c') diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index feb8c92a0b..a6cb17c12e 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -235,15 +235,15 @@ void creds_client_authenticator(struct creds_CredentialState *creds, /* check that a credentials reply from a server is correct */ -BOOL creds_client_check(struct creds_CredentialState *creds, +bool creds_client_check(struct creds_CredentialState *creds, const struct netr_Credential *received_credentials) { if (!received_credentials || memcmp(received_credentials->data, creds->server.data, 8) != 0) { DEBUG(2,("credentials check failed\n")); - return False; + return false; } - return True; + return true; } @@ -278,16 +278,16 @@ void creds_server_init(struct creds_CredentialState *creds, /* check that a credentials reply from a server is correct */ -BOOL creds_server_check(const struct creds_CredentialState *creds, +bool creds_server_check(const struct creds_CredentialState *creds, const struct netr_Credential *received_credentials) { if (memcmp(received_credentials->data, creds->client.data, 8) != 0) { DEBUG(2,("credentials check failed\n")); dump_data_pw("client creds", creds->client.data, 8); dump_data_pw("calc creds", received_credentials->data, 8); - return False; + return false; } - return True; + return true; } NTSTATUS creds_server_step_check(struct creds_CredentialState *creds, -- cgit