1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-11 05:18:09 +03:00

r13407: Change the credentials code to be more like the Samba4 structure,

makes fixes much easier to port. Fix the size of dc->sess_key to
be 16 bytes, not 8 bytes - only store 8 bytes in the inter-smbd
store in secrets.tdb though. Should fix some uses of the dc->sess_key
where we where assuming we could read 16 bytes.
Jeremy.
This commit is contained in:
Jeremy Allison 2006-02-09 07:03:23 +00:00 committed by Gerald (Jerry) Carter
parent 8ae70122b7
commit 5b3c2e63c7
7 changed files with 84 additions and 72 deletions

View File

@ -140,7 +140,7 @@ struct dcinfo {
DOM_CHAL clnt_chal; /* Client credential */ DOM_CHAL clnt_chal; /* Client credential */
DOM_CHAL srv_chal; /* Server credential */ DOM_CHAL srv_chal; /* Server credential */
uchar sess_key[8]; /* Session key */ uchar sess_key[16]; /* Session key - 8 bytes followed by 8 zero bytes */
uchar mach_pw[16]; /* md4(machine password) */ uchar mach_pw[16]; /* md4(machine password) */
fstring mach_acct; /* Machine name we've authenticated. */ fstring mach_acct; /* Machine name we've authenticated. */

View File

@ -90,12 +90,19 @@ enum RPC_PKT_TYPE {
#define RPC_AUTH_SCHANNEL_SIGN_ONLY_CHK_LEN 0x18 #define RPC_AUTH_SCHANNEL_SIGN_ONLY_CHK_LEN 0x18
#define NETLOGON_EXTRA_SIDS 0x0020
#define NETLOGON_RESOURCE_GROUPS 0x0200
#define NETLOGON_NEG_ARCFOUR 0x00000004
#define NETLOGON_NEG_128BIT 0x00004000
#define NETLOGON_NEG_SCHANNEL 0x40000000
/* The 7 here seems to be required to get Win2k not to downgrade us /* The 7 here seems to be required to get Win2k not to downgrade us
to NT4. Actually, anything other than 1ff would seem to do... */ to NT4. Actually, anything other than 1ff would seem to do... */
#define NETLOGON_NEG_AUTH2_FLAGS 0x000701ff #define NETLOGON_NEG_AUTH2_FLAGS 0x000701ff
#define NETLOGON_NEG_SCHANNEL 0x40000000
#define NETLOGON_NEG_DOMAIN_TRUST_ACCOUNT 0x2010b000 #define NETLOGON_NEG_DOMAIN_TRUST_ACCOUNT 0x2010b000
/* these are the flags that ADS clients use */
#define NETLOGON_NEG_AUTH2_ADS_FLAGS (0x200fbffb | NETLOGON_NEG_ARCFOUR | NETLOGON_NEG_128BIT | NETLOGON_NEG_SCHANNEL)
enum schannel_direction { enum schannel_direction {
SENDER_IS_INITIATOR, SENDER_IS_INITIATOR,

View File

@ -36,38 +36,52 @@ char *credstr(const uchar *cred)
/**************************************************************************** /****************************************************************************
Setup the session key. Setup the session key and the client and server creds in dc.
Input: 8 byte challenge block Used by both client and server creds setup.
8 byte server challenge block
16 byte md4 encrypted password
Output:
16 byte session key (last 8 bytes zero).
****************************************************************************/ ****************************************************************************/
static void cred_create_session_key(const DOM_CHAL *clnt_chal_in, static void creds_init_64(struct dcinfo *dc,
const DOM_CHAL *clnt_chal_in,
const DOM_CHAL *srv_chal_in, const DOM_CHAL *srv_chal_in,
const uchar *pass_in, const char mach_pw[16])
uchar session_key_out[16])
{ {
uint32 sum[2]; uint32 sum[2];
unsigned char sum2[8]; unsigned char sum2[8];
/* Just in case this isn't already there */
memcpy(dc->mach_pw, mach_pw, 16);
sum[0] = IVAL(clnt_chal_in->data, 0) + IVAL(srv_chal_in->data, 0); sum[0] = IVAL(clnt_chal_in->data, 0) + IVAL(srv_chal_in->data, 0);
sum[1] = IVAL(clnt_chal_in->data, 4) + IVAL(srv_chal_in->data, 4); sum[1] = IVAL(clnt_chal_in->data, 4) + IVAL(srv_chal_in->data, 4);
SIVAL(sum2,0,sum[0]); SIVAL(sum2,0,sum[0]);
SIVAL(sum2,4,sum[1]); SIVAL(sum2,4,sum[1]);
cred_hash1(session_key_out, sum2, pass_in); ZERO_STRUCT(dc->sess_key);
memset(&session_key_out[8], '\0', 8);
des_crypt128(dc->sess_key, sum2, dc->mach_pw);
/* debug output */ /* debug output */
DEBUG(4,("cred_create_session_key\n")); DEBUG(5,("creds_init_64\n"));
DEBUG(5,(" clnt_chal_in: %s\n", credstr(clnt_chal_in->data))); DEBUG(5,(" clnt_chal_in: %s\n", credstr(clnt_chal_in->data)));
DEBUG(5,(" srv_chal_in : %s\n", credstr(srv_chal_in->data))); DEBUG(5,(" srv_chal_in : %s\n", credstr(srv_chal_in->data)));
DEBUG(5,(" clnt+srv : %s\n", credstr(sum2))); DEBUG(5,(" clnt+srv : %s\n", credstr(sum2)));
DEBUG(5,(" sess_key_out : %s\n", credstr(session_key_out))); DEBUG(5,(" sess_key_out : %s\n", credstr(dc->sess_key)));
/* Generate the next client and server creds. */
des_crypt112(dc->clnt_chal.data, /* output */
clnt_chal_in->data, /* input */
dc->sess_key, /* input */
1);
des_crypt112(dc->srv_chal.data, /* output */
srv_chal_in->data, /* input */
dc->sess_key, /* input */
1);
/* Seed is the client chal. */
memcpy(dc->seed_chal.data, dc->clnt_chal.data, 8);
} }
/**************************************************************************** /****************************************************************************
@ -88,7 +102,7 @@ static void creds_step(struct dcinfo *dc)
DEBUG(5,("\tseed+seq %s\n", credstr(time_chal.data) )); DEBUG(5,("\tseed+seq %s\n", credstr(time_chal.data) ));
cred_hash2(dc->clnt_chal.data, time_chal.data, dc->sess_key); des_crypt112(dc->clnt_chal.data, time_chal.data, dc->sess_key, 1);
DEBUG(5,("\tCLIENT %s\n", credstr(dc->clnt_chal.data) )); DEBUG(5,("\tCLIENT %s\n", credstr(dc->clnt_chal.data) ));
@ -97,12 +111,11 @@ static void creds_step(struct dcinfo *dc)
DEBUG(5,("\tseed+seq+1 %s\n", credstr(time_chal.data) )); DEBUG(5,("\tseed+seq+1 %s\n", credstr(time_chal.data) ));
cred_hash2(dc->srv_chal.data, time_chal.data, dc->sess_key); des_crypt112(dc->srv_chal.data, time_chal.data, dc->sess_key, 1);
DEBUG(5,("\tSERVER %s\n", credstr(dc->srv_chal.data) )); DEBUG(5,("\tSERVER %s\n", credstr(dc->srv_chal.data) ));
} }
/**************************************************************************** /****************************************************************************
Create a server credential struct. Create a server credential struct.
****************************************************************************/ ****************************************************************************/
@ -117,29 +130,14 @@ void creds_server_init(struct dcinfo *dc,
DEBUG(10,("creds_server_init: server chal : %s\n", credstr(srv_chal->data) )); DEBUG(10,("creds_server_init: server chal : %s\n", credstr(srv_chal->data) ));
dump_data_pw("creds_server_init: machine pass", (const unsigned char *)mach_pw, 16); dump_data_pw("creds_server_init: machine pass", (const unsigned char *)mach_pw, 16);
/* Just in case this isn't already there */ /* Generate the session key and the next client and server creds. */
memcpy(dc->mach_pw, mach_pw, 16); creds_init_64(dc,
clnt_chal,
/* Generate the session key. */ srv_chal,
cred_create_session_key(clnt_chal, /* Stored client challenge. */ mach_pw);
srv_chal, /* Stored server challenge. */
dc->mach_pw, /* input machine password. */
dc->sess_key); /* output session key. */
dump_data_pw("creds_server_init: session key", dc->sess_key, 16); dump_data_pw("creds_server_init: session key", dc->sess_key, 16);
/* Generate the next client and server creds. */
cred_hash2(dc->clnt_chal.data, /* output */
clnt_chal->data, /* input */
dc->sess_key); /* input */
cred_hash2(dc->srv_chal.data, /* output */
srv_chal->data, /* input */
dc->sess_key); /* input */
/* Seed is the client chal. */
memcpy(dc->seed_chal.data, dc->clnt_chal.data, 8);
DEBUG(10,("creds_server_init: clnt : %s\n", credstr(dc->clnt_chal.data) )); DEBUG(10,("creds_server_init: clnt : %s\n", credstr(dc->clnt_chal.data) ));
DEBUG(10,("creds_server_init: server : %s\n", credstr(dc->srv_chal.data) )); DEBUG(10,("creds_server_init: server : %s\n", credstr(dc->srv_chal.data) ));
DEBUG(10,("creds_server_init: seed : %s\n", credstr(dc->seed_chal.data) )); DEBUG(10,("creds_server_init: seed : %s\n", credstr(dc->seed_chal.data) ));
@ -214,29 +212,14 @@ void creds_client_init(struct dcinfo *dc,
DEBUG(10,("creds_client_init: server chal : %s\n", credstr(srv_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); dump_data_pw("creds_client_init: machine pass", (const unsigned char *)mach_pw, 16);
/* Just in case this isn't already there */ /* Generate the session key and the next client and server creds. */
memcpy(dc->mach_pw, mach_pw, 16); creds_init_64(dc,
clnt_chal,
/* Generate the session key. */ srv_chal,
cred_create_session_key(clnt_chal, /* Stored client challenge. */ mach_pw);
srv_chal, /* Stored server challenge. */
dc->mach_pw, /* input machine password. */
dc->sess_key); /* output session key. */
dump_data_pw("creds_client_init: session key", dc->sess_key, 16); dump_data_pw("creds_client_init: session key", dc->sess_key, 16);
/* Generate the next client and server creds. */
cred_hash2(dc->clnt_chal.data, /* output */
clnt_chal->data, /* input */
dc->sess_key); /* input */
cred_hash2(dc->srv_chal.data, /* output */
srv_chal->data, /* input */
dc->sess_key); /* input */
/* Seed is the client cred. */
memcpy(dc->seed_chal.data, dc->clnt_chal.data, 8);
DEBUG(10,("creds_client_init: clnt : %s\n", credstr(dc->clnt_chal.data) )); 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: server : %s\n", credstr(dc->srv_chal.data) ));
DEBUG(10,("creds_client_init: seed : %s\n", credstr(dc->seed_chal.data) )); DEBUG(10,("creds_client_init: seed : %s\n", credstr(dc->seed_chal.data) ));

View File

@ -258,7 +258,8 @@ static void dohash(char *out, char *in, char *key, int forw)
permute(out, rl, perm6, 64); permute(out, rl, perm6, 64);
} }
static void str_to_key(const unsigned char *str,unsigned char *key) /* Convert a 7 byte string to an 8 byte key. */
static void str_to_key(const unsigned char str[7], unsigned char key[8])
{ {
int i; int i;
@ -330,7 +331,8 @@ void E_old_pw_hash( unsigned char *p14, const unsigned char *in, unsigned char *
des_crypt56(out+8, in+8, p14+7, 1); des_crypt56(out+8, in+8, p14+7, 1);
} }
void cred_hash1(unsigned char *out, const unsigned char *in, const unsigned char *key) /* forward des encryption with a 128 bit key */
void des_crypt128(unsigned char out[8], const unsigned char in[8], const unsigned char key[16])
{ {
unsigned char buf[8]; unsigned char buf[8];
@ -338,25 +340,49 @@ void cred_hash1(unsigned char *out, const unsigned char *in, const unsigned char
des_crypt56(out, buf, key+9, 1); des_crypt56(out, buf, key+9, 1);
} }
void cred_hash2(unsigned char *out, const unsigned char *in, const unsigned char *key) /* forward des encryption with a 64 bit key */
void des_crypt64(unsigned char out[8], const unsigned char in[8], const unsigned char key[8])
{ {
unsigned char buf[8]; unsigned char buf[8];
static unsigned char key2[8]; unsigned char key2[8];
memset(key2,'\0',8);
des_crypt56(buf, in, key, 1); des_crypt56(buf, in, key, 1);
key2[0] = key[7]; key2[0] = key[7];
des_crypt56(out, buf, key2, 1); des_crypt56(out, buf, key2, 1);
} }
/* des encryption with a 112 bit (14 byte) key */
/* Note that if the forw is 1, and key is actually 8 bytes of key, followed by 6 bytes of zeros,
this is identical to des_crypt64(). JRA. */
void des_crypt112(unsigned char out[8], const unsigned char in[8], const unsigned char key[14], int forw)
{
unsigned char buf[8];
des_crypt56(buf, in, key, forw);
des_crypt56(out, buf, key+7, forw);
}
void cred_hash3(unsigned char *out, const unsigned char *in, const unsigned char *key, int forw) void cred_hash3(unsigned char *out, const unsigned char *in, const unsigned char *key, int forw)
{ {
static unsigned char key2[8]; unsigned char key2[8];
memset(key2,'\0',8);
des_crypt56(out, in, key, forw); des_crypt56(out, in, key, forw);
key2[0] = key[7]; key2[0] = key[7];
des_crypt56(out + 8, in + 8, key2, forw); des_crypt56(out + 8, in + 8, key2, forw);
} }
/* des encryption of a 16 byte lump of data with a 112 bit key */
/* Note that if the key is actually 8 bytes of key, followed by 6 bytes of zeros,
this is identical to cred_hash3(). JRA. */
void des_crypt112_16(unsigned char out[16], unsigned char in[16], const unsigned char key[14], int forw)
{
des_crypt56(out, in, key, forw);
des_crypt56(out + 8, in + 8, key+7, forw);
}
/***************************************************************** /*****************************************************************
arc4 crypt/decrypt with a 16 byte key. arc4 crypt/decrypt with a 16 byte key.
*****************************************************************/ *****************************************************************/

View File

@ -1063,6 +1063,7 @@ BOOL secrets_restore_schannel_session_info(TALLOC_CTX *mem_ctx,
memcpy(pdc->clnt_chal.data, pclnt_chal, 8); memcpy(pdc->clnt_chal.data, pclnt_chal, 8);
memcpy(pdc->srv_chal.data, psrv_chal, 8); memcpy(pdc->srv_chal.data, psrv_chal, 8);
memcpy(pdc->sess_key, psess_key, 8); memcpy(pdc->sess_key, psess_key, 8);
memset(&pdc->sess_key[8], '\0', 8); /* key followed by 8 bytes of zero. */
memcpy(pdc->mach_pw, pmach_pw, 16); memcpy(pdc->mach_pw, pmach_pw, 16);
/* We know these are true so didn't bother to store them. */ /* We know these are true so didn't bother to store them. */

View File

@ -848,4 +848,3 @@ BOOL smb_io_rpc_auth_schannel_chk(const char *desc, int auth_len,
return True; return True;
} }

View File

@ -817,7 +817,6 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
fstring group_sid_string; fstring group_sid_string;
uchar user_session_key[16]; uchar user_session_key[16];
uchar lm_session_key[16]; uchar lm_session_key[16];
uchar netlogon_sess_key[16];
sampw = server_info->sam_account; sampw = server_info->sam_account;
@ -859,23 +858,20 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
return status; return status;
} }
ZERO_STRUCT(netlogon_sess_key);
memcpy(netlogon_sess_key, p->dc->sess_key, 8);
if (server_info->user_session_key.length) { if (server_info->user_session_key.length) {
memcpy(user_session_key, memcpy(user_session_key,
server_info->user_session_key.data, server_info->user_session_key.data,
MIN(sizeof(user_session_key), MIN(sizeof(user_session_key),
server_info->user_session_key.length)); server_info->user_session_key.length));
SamOEMhash(user_session_key, netlogon_sess_key, 16); SamOEMhash(user_session_key, p->dc->sess_key, 16);
} }
if (server_info->lm_session_key.length) { if (server_info->lm_session_key.length) {
memcpy(lm_session_key, memcpy(lm_session_key,
server_info->lm_session_key.data, server_info->lm_session_key.data,
MIN(sizeof(lm_session_key), MIN(sizeof(lm_session_key),
server_info->lm_session_key.length)); server_info->lm_session_key.length));
SamOEMhash(lm_session_key, netlogon_sess_key, 16); SamOEMhash(lm_session_key, p->dc->sess_key, 16);
} }
ZERO_STRUCT(netlogon_sess_key);
init_net_user_info3(p->mem_ctx, usr_info, init_net_user_info3(p->mem_ctx, usr_info,
user_rid, user_rid,