*/
#include "includes.h"
+#include "../lib/crypto/crypto.h"
+#include "libcli/auth/libcli_auth.h"
/****************************************************************************
Represent a credential as a string.
char *credstr(const unsigned char *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;
+ char *result;
+ result = talloc_asprintf(talloc_tos(),
+ "%02X%02X%02X%02X%02X%02X%02X%02X",
+ cred[0], cred[1], cred[2], cred[3],
+ cred[4], cred[5], cred[6], cred[7]);
+ SMB_ASSERT(result != NULL);
+ return result;
}
/****************************************************************************
****************************************************************************/
static void creds_init_128(struct dcinfo *dc,
- const DOM_CHAL *clnt_chal_in,
- const DOM_CHAL *srv_chal_in,
- const unsigned char mach_pw[16])
+ const struct netr_Credential *clnt_chal_in,
+ const struct netr_Credential *srv_chal_in,
+ const unsigned char mach_pw[16])
{
unsigned char zero[4], tmp[16];
HMACMD5Context ctx;
****************************************************************************/
static void creds_init_64(struct dcinfo *dc,
- const DOM_CHAL *clnt_chal_in,
- const DOM_CHAL *srv_chal_in,
- const unsigned char mach_pw[16])
+ const struct netr_Credential *clnt_chal_in,
+ const struct netr_Credential *srv_chal_in,
+ const unsigned char mach_pw[16])
{
uint32 sum[2];
unsigned char sum2[8];
static void creds_step(struct dcinfo *dc)
{
- DOM_CHAL time_chal;
+ struct netr_Credential time_chal;
DEBUG(5,("\tsequence = 0x%x\n", (unsigned int)dc->sequence ));
void creds_server_init(uint32 neg_flags,
struct dcinfo *dc,
- DOM_CHAL *clnt_chal,
- DOM_CHAL *srv_chal,
+ struct netr_Credential *clnt_chal,
+ struct netr_Credential *srv_chal,
const unsigned char mach_pw[16],
- DOM_CHAL *init_chal_out)
+ struct netr_Credential *init_chal_out)
{
DEBUG(10,("creds_server_init: neg_flags : %x\n", (unsigned int)neg_flags));
DEBUG(10,("creds_server_init: client chal : %s\n", credstr(clnt_chal->data) ));
Check a credential sent by the client.
****************************************************************************/
-bool creds_server_check(const struct dcinfo *dc, const DOM_CHAL *rcv_cli_chal_in)
+bool netlogon_creds_server_check(const struct dcinfo *dc,
+ const struct netr_Credential *rcv_cli_chal_in)
{
if (memcmp(dc->clnt_chal.data, rcv_cli_chal_in->data, 8)) {
- DEBUG(5,("creds_server_check: challenge : %s\n", credstr(rcv_cli_chal_in->data)));
+ DEBUG(5,("netlogon_creds_server_check: challenge : %s\n",
+ credstr(rcv_cli_chal_in->data)));
DEBUG(5,("calculated: %s\n", credstr(dc->clnt_chal.data)));
- DEBUG(2,("creds_server_check: credentials check failed.\n"));
- return False;
+ DEBUG(2,("netlogon_creds_server_check: credentials check failed.\n"));
+ return false;
}
- DEBUG(10,("creds_server_check: credentials check OK.\n"));
- return True;
-}
+ DEBUG(10,("netlogon_creds_server_check: credentials check OK.\n"));
+
+ return true;
+}
/****************************************************************************
Replace current seed chal. Internal function - due to split server step below.
****************************************************************************/
static void creds_reseed(struct dcinfo *dc)
{
- DOM_CHAL time_chal;
+ struct netr_Credential time_chal;
SIVAL(time_chal.data, 0, IVAL(dc->seed_chal.data, 0) + dc->sequence + 1);
SIVAL(time_chal.data, 4, IVAL(dc->seed_chal.data, 4));
Step the server credential chain one forward.
****************************************************************************/
-bool creds_server_step(struct dcinfo *dc, const DOM_CRED *received_cred, DOM_CRED *cred_out)
+bool netlogon_creds_server_step(struct dcinfo *dc,
+ const struct netr_Authenticator *received_cred,
+ struct netr_Authenticator *cred_out)
{
bool ret;
struct dcinfo tmp_dc = *dc;
+ if (!received_cred || !cred_out) {
+ return false;
+ }
+
/* Do all operations on a temporary copy of the dc,
which we throw away if the checks fail. */
- tmp_dc.sequence = received_cred->timestamp.time;
+ tmp_dc.sequence = received_cred->timestamp;
creds_step(&tmp_dc);
/* Create the outgoing credentials */
- cred_out->timestamp.time = tmp_dc.sequence + 1;
- cred_out->challenge = tmp_dc.srv_chal;
+ cred_out->timestamp = tmp_dc.sequence + 1;
+ memcpy(&cred_out->cred, &tmp_dc.srv_chal, sizeof(cred_out->cred));
creds_reseed(&tmp_dc);
- ret = creds_server_check(&tmp_dc, &received_cred->challenge);
+ ret = netlogon_creds_server_check(&tmp_dc, &received_cred->cred);
if (!ret) {
- return False;
+ return false;
}
/* creds step succeeded - replace the current creds. */
*dc = tmp_dc;
- return True;
+ return true;
}
-/****************************************************************************
- Create a client credential struct.
-****************************************************************************/
-
-void creds_client_init(uint32 neg_flags,
- struct dcinfo *dc,
- DOM_CHAL *clnt_chal,
- DOM_CHAL *srv_chal,
- const unsigned char mach_pw[16],
- DOM_CHAL *init_chal_out)
-{
- dc->sequence = time(NULL);
-
- DEBUG(10,("creds_client_init: neg_flags : %x\n", (unsigned int)neg_flags));
- DEBUG(10,("creds_client_init: client chal : %s\n", credstr(clnt_chal->data) ));
- DEBUG(10,("creds_client_init: server chal : %s\n", credstr(srv_chal->data) ));
- dump_data_pw("creds_client_init: machine pass", (const unsigned char *)mach_pw, 16);
-
- /* Generate the session key and the next client and server creds. */
- if (neg_flags & NETLOGON_NEG_128BIT) {
- creds_init_128(dc,
- clnt_chal,
- srv_chal,
- mach_pw);
- } else {
- creds_init_64(dc,
- clnt_chal,
- srv_chal,
- mach_pw);
- }
-
- dump_data_pw("creds_client_init: session key", dc->sess_key, 16);
-
- DEBUG(10,("creds_client_init: clnt : %s\n", credstr(dc->clnt_chal.data) ));
- DEBUG(10,("creds_client_init: server : %s\n", credstr(dc->srv_chal.data) ));
- DEBUG(10,("creds_client_init: seed : %s\n", credstr(dc->seed_chal.data) ));
-
- memcpy(init_chal_out->data, dc->clnt_chal.data, 8);
-}
-
-/****************************************************************************
- Check a credential returned by the server.
-****************************************************************************/
-
-bool creds_client_check(const struct dcinfo *dc, const DOM_CHAL *rcv_srv_chal_in)
-{
- if (memcmp(dc->srv_chal.data, rcv_srv_chal_in->data, 8)) {
- DEBUG(5,("creds_client_check: challenge : %s\n", credstr(rcv_srv_chal_in->data)));
- DEBUG(5,("calculated: %s\n", credstr(dc->srv_chal.data)));
- DEBUG(0,("creds_client_check: credentials check failed.\n"));
- return False;
- }
- DEBUG(10,("creds_client_check: credentials check OK.\n"));
- return True;
-}
-
-/****************************************************************************
- Step the client credentials to the next element in the chain, updating the
- current client and server credentials and the seed
- produce the next authenticator in the sequence ready to send to
- the server
-****************************************************************************/
-
-void creds_client_step(struct dcinfo *dc, DOM_CRED *next_cred_out)
+void cred_hash3(unsigned char *out, const unsigned char *in, const unsigned char *key, int forw)
{
- dc->sequence += 2;
- creds_step(dc);
- creds_reseed(dc);
+ unsigned char key2[8];
- next_cred_out->challenge = dc->clnt_chal;
- next_cred_out->timestamp.time = dc->sequence;
+ memset(key2,'\0',8);
+ des_crypt56(out, in, key, forw);
+ key2[0] = key[7];
+ des_crypt56(out + 8, in + 8, key2, forw);
}