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') 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