summaryrefslogtreecommitdiff
path: root/source4/libcli/auth
diff options
context:
space:
mode:
Diffstat (limited to 'source4/libcli/auth')
-rw-r--r--source4/libcli/auth/credentials.c68
1 files changed, 48 insertions, 20 deletions
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;
}