summaryrefslogtreecommitdiff
path: root/source4/libcli
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2004-05-09 12:42:18 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:51:51 -0500
commitdce84ffd379012812170f68f7de8aab73123f0b3 (patch)
treec5f6973838572fd06c07d6771f5286bc2073b569 /source4/libcli
parent55fa62be31c9027d84be0e4caad3ee59d78ca1b0 (diff)
downloadsamba-dce84ffd379012812170f68f7de8aab73123f0b3.tar.gz
samba-dce84ffd379012812170f68f7de8aab73123f0b3.tar.bz2
samba-dce84ffd379012812170f68f7de8aab73123f0b3.zip
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)
Diffstat (limited to 'source4/libcli')
-rw-r--r--source4/libcli/auth/credentials.c50
-rw-r--r--source4/libcli/auth/credentials.h29
-rw-r--r--source4/libcli/auth/ntlm_check.c4
-rw-r--r--source4/libcli/auth/ntlmssp.c4
-rw-r--r--source4/libcli/raw/clisession.c29
-rw-r--r--source4/libcli/raw/clitransport.c8
-rw-r--r--source4/libcli/raw/smb_signing.c12
-rw-r--r--source4/libcli/util/smbdes.c13
-rw-r--r--source4/libcli/util/smbencrypt.c3
9 files changed, 101 insertions, 51 deletions
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;
-}
diff --git a/source4/libcli/auth/credentials.h b/source4/libcli/auth/credentials.h
new file mode 100644
index 0000000000..7a7a34ced2
--- /dev/null
+++ b/source4/libcli/auth/credentials.h
@@ -0,0 +1,29 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ code to manipulate domain credentials
+
+ Copyright (C) Andrew Tridgell 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
+ 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.
+*/
+
+struct creds_CredentialState {
+ uint8 session_key[8];
+ uint32 sequence;
+ struct netr_Credential seed;
+ struct netr_Credential client;
+ struct netr_Credential server;
+};
diff --git a/source4/libcli/auth/ntlm_check.c b/source4/libcli/auth/ntlm_check.c
index a7764f9e98..32a7507c1f 100644
--- a/source4/libcli/auth/ntlm_check.c
+++ b/source4/libcli/auth/ntlm_check.c
@@ -59,7 +59,7 @@ static BOOL smb_pwd_check_ntlmv1(const DATA_BLOB *nt_response,
SMBOWFencrypt(part_passwd, sec_blob->data, p24);
if (user_sess_key != NULL) {
*user_sess_key = data_blob(NULL, 16);
- SMBsesskeygen_ntv1(part_passwd, NULL, user_sess_key->data);
+ SMBsesskeygen_ntv1(part_passwd, user_sess_key->data);
}
@@ -195,7 +195,7 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
if (memcmp(nt_interactive_pwd->data, nt_pw, 16) == 0) {
if (user_sess_key) {
*user_sess_key = data_blob(NULL, 16);
- SMBsesskeygen_ntv1(nt_pw, NULL, user_sess_key->data);
+ SMBsesskeygen_ntv1(nt_pw, user_sess_key->data);
}
return NT_STATUS_OK;
} else {
diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c
index 161a15023a..9513d5a138 100644
--- a/source4/libcli/auth/ntlmssp.c
+++ b/source4/libcli/auth/ntlmssp.c
@@ -1093,7 +1093,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
- SMBsesskeygen_ntv1(nt_hash, NULL, user_session_key);
+ SMBsesskeygen_ntv1(nt_hash, user_session_key);
hmac_md5(user_session_key, session_nonce, sizeof(session_nonce), session_key.data);
dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
@@ -1108,7 +1108,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
nt_response.data);
E_md4hash(ntlmssp_state->password, nt_hash);
session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
- SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data);
+ SMBsesskeygen_ntv1(nt_hash, session_key.data);
dump_data_pw("NT session key:\n", session_key.data, session_key.length);
}
diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c
index 1c0af77d11..fe64565597 100644
--- a/source4/libcli/raw/clisession.c
+++ b/source4/libcli/raw/clisession.c
@@ -235,21 +235,33 @@ static DATA_BLOB nt_blob(const char *pass, DATA_BLOB challenge)
}
/*
+ store the user session key for a transport
+*/
+void cli_session_set_user_session_key(struct cli_session *session,
+ const DATA_BLOB *session_key)
+{
+ session->user_session_key = data_blob_talloc(session->mem_ctx,
+ session_key->data,
+ session_key->length);
+}
+
+/*
setup signing for a NT1 style session setup
*/
-static void setup_nt1_signing(struct cli_transport *transport, const char *password)
+static void use_nt1_session_keys(struct cli_session *session,
+ const char *password, const DATA_BLOB *nt_response)
{
+ struct cli_transport *transport = session->transport;
uchar nt_hash[16];
- uchar session_key[16];
- DATA_BLOB nt_response;
+ DATA_BLOB session_key = data_blob(NULL, 16);
E_md4hash(password, nt_hash);
- SMBsesskeygen_ntv1(nt_hash, NULL, session_key);
- nt_response = nt_blob(password, transport->negotiate.secblob);
+ SMBsesskeygen_ntv1(nt_hash, session_key.data);
- cli_transport_set_session_key(transport, session_key);
+ cli_transport_simple_set_signing(transport, session_key, *nt_response);
- cli_transport_simple_set_signing(transport, session_key, nt_response);
+ cli_session_set_user_session_key(session, &session_key);
+ data_blob_free(&session_key);
}
/****************************************************************************
@@ -332,7 +344,8 @@ static NTSTATUS smb_raw_session_setup_generic_nt1(struct cli_session *session,
session->transport->negotiate.secblob);
s2.nt1.in.password2 = nt_blob(parms->generic.in.password,
session->transport->negotiate.secblob);
- setup_nt1_signing(session->transport, parms->generic.in.password);
+ use_nt1_session_keys(session, parms->generic.in.password, &s2.nt1.in.password2);
+
} else {
s2.nt1.in.password1 = data_blob(parms->generic.in.password,
strlen(parms->generic.in.password));
diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c
index b8eef65c7f..72cad2e925 100644
--- a/source4/libcli/raw/clitransport.c
+++ b/source4/libcli/raw/clitransport.c
@@ -231,11 +231,3 @@ BOOL cli_transport_select(struct cli_transport *transport)
return True;
}
-/*
- store the user session key for a transport
-*/
-void cli_transport_set_session_key(struct cli_transport *transport,
- const uint8 session_key[16])
-{
- memcpy(transport->negotiate.user_session_key, session_key, 16);
-}
diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c
index 2ab61aa001..5f47a5e42a 100644
--- a/source4/libcli/raw/smb_signing.c
+++ b/source4/libcli/raw/smb_signing.c
@@ -220,7 +220,8 @@ static void cli_transport_simple_free_signing_context(struct cli_transport *tran
SMB signing - Simple implementation - setup the MAC key.
************************************************************/
BOOL cli_transport_simple_set_signing(struct cli_transport *transport,
- const uchar user_transport_key[16], const DATA_BLOB response)
+ const DATA_BLOB user_session_key,
+ const DATA_BLOB response)
{
struct smb_basic_signing_context *data;
@@ -235,10 +236,13 @@ BOOL cli_transport_simple_set_signing(struct cli_transport *transport,
data = smb_xmalloc(sizeof(*data));
transport->negotiate.sign_info.signing_context = data;
- data->mac_key = data_blob(NULL, MIN(response.length + 16, 40));
+ data->mac_key = data_blob(NULL, response.length + user_session_key.length);
- memcpy(&data->mac_key.data[0], user_transport_key, 16);
- memcpy(&data->mac_key.data[16],response.data, MIN(response.length, 40 - 16));
+ memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length);
+
+ if (response.length) {
+ memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length);
+ }
/* Initialise the sequence number */
data->next_seq_num = 0;
diff --git a/source4/libcli/util/smbdes.c b/source4/libcli/util/smbdes.c
index 80b938b460..22bafcb449 100644
--- a/source4/libcli/util/smbdes.c
+++ b/source4/libcli/util/smbdes.c
@@ -338,14 +338,14 @@ void cred_hash1(unsigned char *out, const unsigned char *in, const unsigned char
smbhash(out, buf, key+9, 1);
}
-void cred_hash2(unsigned char *out, const unsigned char *in, const unsigned char *key)
+void cred_hash2(unsigned char *out, const unsigned char *in, const unsigned char *key, int forw)
{
unsigned char buf[8];
unsigned char key2[8];
ZERO_STRUCT(key2);
- smbhash(buf, in, key, 1);
+ smbhash(buf, in, key, forw);
key2[0] = key[7];
- smbhash(out, buf, key2, 1);
+ smbhash(out, buf, key2, forw);
}
void cred_hash3(unsigned char *out, unsigned char *in, const unsigned char *key, int forw)
@@ -401,12 +401,11 @@ void SamOEMhashBlob(unsigned char *data, int len, const DATA_BLOB *key)
*/
void SamOEMhash(unsigned char *data, const unsigned char keystr[16], int len)
{
- DATA_BLOB key;
-
- key.length = 16;
- key.data = keystr;
+ DATA_BLOB key = data_blob(keystr, 16);
SamOEMhashBlob(data, len, &key);
+
+ data_blob_free(&key);
}
diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c
index cefd01bf1c..5468bdbebe 100644
--- a/source4/libcli/util/smbencrypt.c
+++ b/source4/libcli/util/smbencrypt.c
@@ -255,8 +255,7 @@ void SMBsesskeygen_ntv2(const uchar kr[16],
#endif
}
-void SMBsesskeygen_ntv1(const uchar kr[16],
- const uchar * nt_resp, uint8 sess_key[16])
+void SMBsesskeygen_ntv1(const uchar kr[16], uint8 sess_key[16])
{
/* yes, this session key does not change - yes, this
is a problem - but it is 128 bits */