diff options
Diffstat (limited to 'source4/libcli')
-rw-r--r-- | source4/libcli/auth/credentials.c | 50 | ||||
-rw-r--r-- | source4/libcli/auth/credentials.h | 29 | ||||
-rw-r--r-- | source4/libcli/auth/ntlm_check.c | 4 | ||||
-rw-r--r-- | source4/libcli/auth/ntlmssp.c | 4 | ||||
-rw-r--r-- | source4/libcli/raw/clisession.c | 29 | ||||
-rw-r--r-- | source4/libcli/raw/clitransport.c | 8 | ||||
-rw-r--r-- | source4/libcli/raw/smb_signing.c | 12 | ||||
-rw-r--r-- | source4/libcli/util/smbdes.c | 13 | ||||
-rw-r--r-- | source4/libcli/util/smbencrypt.c | 3 |
9 files changed, 101 insertions, 51 deletions
diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index acc083d57f7..638bff7e8ba 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 00000000000..7a7a34ced2c --- /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 a7764f9e986..32a7507c1fb 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 161a15023a1..9513d5a138a 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 1c0af77d11d..fe64565597a 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 b8eef65c7f2..72cad2e9251 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 2ab61aa001e..5f47a5e42a7 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 80b938b4601..22bafcb449d 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 cefd01bf1c9..5468bdbebec 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 */ |