mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +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:
parent
8ae70122b7
commit
5b3c2e63c7
@ -140,7 +140,7 @@ struct dcinfo {
|
||||
DOM_CHAL clnt_chal; /* Client 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) */
|
||||
|
||||
fstring mach_acct; /* Machine name we've authenticated. */
|
||||
|
@ -90,12 +90,19 @@ enum RPC_PKT_TYPE {
|
||||
#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
|
||||
to NT4. Actually, anything other than 1ff would seem to do... */
|
||||
#define NETLOGON_NEG_AUTH2_FLAGS 0x000701ff
|
||||
|
||||
#define NETLOGON_NEG_SCHANNEL 0x40000000
|
||||
#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 {
|
||||
SENDER_IS_INITIATOR,
|
||||
|
@ -36,38 +36,52 @@ char *credstr(const uchar *cred)
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
Setup the session key.
|
||||
Input: 8 byte challenge block
|
||||
8 byte server challenge block
|
||||
16 byte md4 encrypted password
|
||||
Output:
|
||||
16 byte session key (last 8 bytes zero).
|
||||
Setup the session key and the client and server creds in dc.
|
||||
Used by both client and server creds setup.
|
||||
****************************************************************************/
|
||||
|
||||
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 uchar *pass_in,
|
||||
uchar session_key_out[16])
|
||||
const char mach_pw[16])
|
||||
{
|
||||
uint32 sum[2];
|
||||
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[1] = IVAL(clnt_chal_in->data, 4) + IVAL(srv_chal_in->data, 4);
|
||||
|
||||
SIVAL(sum2,0,sum[0]);
|
||||
SIVAL(sum2,4,sum[1]);
|
||||
|
||||
cred_hash1(session_key_out, sum2, pass_in);
|
||||
memset(&session_key_out[8], '\0', 8);
|
||||
ZERO_STRUCT(dc->sess_key);
|
||||
|
||||
des_crypt128(dc->sess_key, sum2, dc->mach_pw);
|
||||
|
||||
/* 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,(" srv_chal_in : %s\n", credstr(srv_chal_in->data)));
|
||||
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) ));
|
||||
|
||||
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) ));
|
||||
|
||||
@ -97,12 +111,11 @@ static void creds_step(struct dcinfo *dc)
|
||||
|
||||
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) ));
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
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) ));
|
||||
dump_data_pw("creds_server_init: machine pass", (const unsigned char *)mach_pw, 16);
|
||||
|
||||
/* Just in case this isn't already there */
|
||||
memcpy(dc->mach_pw, mach_pw, 16);
|
||||
|
||||
/* Generate the session key. */
|
||||
cred_create_session_key(clnt_chal, /* Stored client challenge. */
|
||||
srv_chal, /* Stored server challenge. */
|
||||
dc->mach_pw, /* input machine password. */
|
||||
dc->sess_key); /* output session key. */
|
||||
/* Generate the session key and the next client and server creds. */
|
||||
creds_init_64(dc,
|
||||
clnt_chal,
|
||||
srv_chal,
|
||||
mach_pw);
|
||||
|
||||
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: server : %s\n", credstr(dc->srv_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) ));
|
||||
dump_data_pw("creds_client_init: machine pass", (const unsigned char *)mach_pw, 16);
|
||||
|
||||
/* Just in case this isn't already there */
|
||||
memcpy(dc->mach_pw, mach_pw, 16);
|
||||
|
||||
/* Generate the session key. */
|
||||
cred_create_session_key(clnt_chal, /* Stored client challenge. */
|
||||
srv_chal, /* Stored server challenge. */
|
||||
dc->mach_pw, /* input machine password. */
|
||||
dc->sess_key); /* output session key. */
|
||||
/* Generate the session key and the next client and server creds. */
|
||||
creds_init_64(dc,
|
||||
clnt_chal,
|
||||
srv_chal,
|
||||
mach_pw);
|
||||
|
||||
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: server : %s\n", credstr(dc->srv_chal.data) ));
|
||||
DEBUG(10,("creds_client_init: seed : %s\n", credstr(dc->seed_chal.data) ));
|
||||
|
@ -258,7 +258,8 @@ static void dohash(char *out, char *in, char *key, int forw)
|
||||
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;
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
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];
|
||||
|
||||
@ -338,25 +340,49 @@ void cred_hash1(unsigned char *out, const unsigned char *in, const unsigned char
|
||||
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];
|
||||
static unsigned char key2[8];
|
||||
unsigned char key2[8];
|
||||
|
||||
memset(key2,'\0',8);
|
||||
des_crypt56(buf, in, key, 1);
|
||||
key2[0] = key[7];
|
||||
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)
|
||||
{
|
||||
static unsigned char key2[8];
|
||||
unsigned char key2[8];
|
||||
|
||||
memset(key2,'\0',8);
|
||||
des_crypt56(out, in, key, forw);
|
||||
key2[0] = key[7];
|
||||
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.
|
||||
*****************************************************************/
|
||||
|
@ -1063,6 +1063,7 @@ BOOL secrets_restore_schannel_session_info(TALLOC_CTX *mem_ctx,
|
||||
memcpy(pdc->clnt_chal.data, pclnt_chal, 8);
|
||||
memcpy(pdc->srv_chal.data, psrv_chal, 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);
|
||||
|
||||
/* We know these are true so didn't bother to store them. */
|
||||
|
@ -848,4 +848,3 @@ BOOL smb_io_rpc_auth_schannel_chk(const char *desc, int auth_len,
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
uchar user_session_key[16];
|
||||
uchar lm_session_key[16];
|
||||
uchar netlogon_sess_key[16];
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
ZERO_STRUCT(netlogon_sess_key);
|
||||
memcpy(netlogon_sess_key, p->dc->sess_key, 8);
|
||||
if (server_info->user_session_key.length) {
|
||||
memcpy(user_session_key,
|
||||
server_info->user_session_key.data,
|
||||
MIN(sizeof(user_session_key),
|
||||
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) {
|
||||
memcpy(lm_session_key,
|
||||
server_info->lm_session_key.data,
|
||||
MIN(sizeof(lm_session_key),
|
||||
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,
|
||||
user_rid,
|
||||
|
Loading…
Reference in New Issue
Block a user