summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/libcli/auth/credentials.c191
-rw-r--r--source4/librpc/idl/netlogon.idl35
-rw-r--r--source4/torture/rpc/netlogon.c40
3 files changed, 69 insertions, 197 deletions
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;
}
diff --git a/source4/librpc/idl/netlogon.idl b/source4/librpc/idl/netlogon.idl
index f6749b4e57..38df1c48da 100644
--- a/source4/librpc/idl/netlogon.idl
+++ b/source4/librpc/idl/netlogon.idl
@@ -64,6 +64,17 @@ interface netlogon
/*****************/
/* Function 0x02 */
+ typedef [flag(NDR_PAHEX)] struct {
+ uint8 data[8];
+ } netr_Credential;
+
+ typedef [flag(NDR_PAHEX)] struct {
+ uint8 session_key[8];
+ uint32 sequence;
+ netr_Credential client_cred;
+ netr_Credential server_cred;
+ } netr_CredentialState;
+
typedef struct {
[value(strlen_m(r->string)*2)] uint16 size;
[value(r->size)] uint16 length;
@@ -90,18 +101,14 @@ interface netlogon
} netr_PasswordInfo;
typedef [flag(NDR_PAHEX)] struct {
- uint8 data[8];
- } netr_Credential;
-
- typedef [flag(NDR_PAHEX)] struct {
uint16 length;
[value(r->length)] uint16 size;
[size_is(size),length_is(length)] uint8 *data;
} netr_ChallengeResponse;
- typedef struct {
+ typedef [flag(NDR_PAHEX)] struct {
netr_IdentityInfo logon_info;
- netr_Credential challenge;
+ uint8 challenge[8];
netr_ChallengeResponse nt;
netr_ChallengeResponse lm;
} netr_NetworkInfo;
@@ -232,17 +239,17 @@ interface netlogon
);
WERROR netr_ServerReqChallenge(
- [in] unistr *server_name,
- [in] unistr computer_name,
- [in][out][ref] netr_Credential *credential
+ [in] unistr *server_name,
+ [in] unistr computer_name,
+ [in][out] netr_Credential credentials
);
WERROR netr_ServerAuthenticate(
- [in] unistr *server_name,
- [in] unistr username,
- [in] uint16 secure_challenge_type,
- [in] unistr computer_name,
- [in,out,ref] netr_Credential *client_challenge
+ [in] unistr *server_name,
+ [in] unistr username,
+ [in] uint16 secure_challenge_type,
+ [in] unistr computer_name,
+ [in,out] netr_Credential credentials
);
#if 0
diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c
index 4ed62bc543..d0bffcc0e9 100644
--- a/source4/torture/rpc/netlogon.c
+++ b/source4/torture/rpc/netlogon.c
@@ -71,25 +71,20 @@ static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
struct netr_ServerReqChallenge r;
struct netr_ServerAuthenticate a;
struct netr_LogonSamLogon l;
- struct netr_Credential client_chal, server_chal, cred2, cred3;
- uint8 session_key[8];
const char *plain_pass;
uint8 mach_pwd[16];
struct netr_Authenticator auth, auth2;
struct netr_NetworkInfo ninfo;
const char *username = lp_parm_string(-1, "torture", "username");
const char *password = lp_parm_string(-1, "torture", "password");
+ struct netr_CredentialState creds;
printf("Testing ServerReqChallenge\n");
- ZERO_STRUCT(client_chal);
-
- generate_random_buffer(client_chal.data, sizeof(client_chal.data), False);
-
r.in.server_name = NULL;
r.in.computer_name = lp_netbios_name();
- r.in.credential = &client_chal;
- r.out.credential = &server_chal;
+ r.in.credentials.low = 1;
+ r.in.credentials.high = 2;
status = dcerpc_netr_ServerReqChallenge(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -104,16 +99,14 @@ static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
}
E_md4hash(plain_pass, mach_pwd);
- cred_session_key(&client_chal, &server_chal, mach_pwd, session_key);
- cred_create(session_key, &client_chal, 0, &cred2);
+ creds_init(&creds, &r.in.credentials, &r.out.credentials, mach_pwd);
a.in.server_name = NULL;
a.in.username = talloc_asprintf(mem_ctx, "%s$", lp_netbios_name());
a.in.secure_challenge_type = 2;
a.in.computer_name = lp_netbios_name();
- a.in.client_challenge = &cred2;
- a.out.client_challenge = &cred3;
+ a.in.credentials = creds.client_cred;
printf("Testing ServerAuthenticate\n");
@@ -123,17 +116,12 @@ static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
return False;
}
-
- if (!cred_assert(&cred3, session_key, &server_chal, 0)) {
- printf("cred_assert failed!\n");
+ if (!creds_next(&creds, &a.out.credentials)) {
+ printf("Credential chaining failed\n");
}
auth.timestamp = 0;
- auth.cred = cred3;
- auth2.timestamp = 0;
- auth2.cred = server_chal;
-
- cred_create(session_key, &cred2, 0, &auth.cred);
+ auth.cred = creds.client_cred;
ninfo.logon_info.domain_name.string = lp_workgroup();
ninfo.logon_info.parameter_control = 0;
@@ -141,14 +129,14 @@ static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
ninfo.logon_info.logon_id_high = 0;
ninfo.logon_info.username.string = username;
ninfo.logon_info.workstation.string = lp_netbios_name();
- generate_random_buffer(ninfo.challenge.data,
- sizeof(ninfo.challenge.data), False);
+ generate_random_buffer(ninfo.challenge,
+ sizeof(ninfo.challenge), False);
ninfo.nt.length = 24;
ninfo.nt.data = talloc(mem_ctx, 24);
- SMBNTencrypt(password, ninfo.challenge.data, ninfo.nt.data);
+ SMBNTencrypt(password, ninfo.challenge, ninfo.nt.data);
ninfo.lm.length = 24;
ninfo.lm.data = talloc(mem_ctx, 24);
- SMBencrypt(password, ninfo.challenge.data, ninfo.lm.data);
+ SMBencrypt(password, ninfo.challenge, ninfo.lm.data);
ZERO_STRUCT(auth2);
@@ -168,6 +156,10 @@ static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
return False;
}
+ if (!creds_next(&creds, &l.out.authenticator->cred)) {
+ printf("Credential chaining failed\n");
+ }
+
return True;
}