1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-08 21:18:16 +03:00

libcli:auth: Return NTSTATUS for netlogon_creds_arcfour_crypt()

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
This commit is contained in:
Andreas Schneider 2019-05-29 14:46:17 +02:00 committed by Andreas Schneider
parent 99d250a3ab
commit 67e6a9af2c
8 changed files with 121 additions and 35 deletions

View File

@ -1317,6 +1317,8 @@ _PUBLIC_ NTSTATUS netlogon_creds_session_encrypt(
struct netlogon_creds_CredentialState *state,
DATA_BLOB data)
{
NTSTATUS status;
if (data.data == NULL || data.length == 0) {
DBG_ERR("Nothing to encrypt "
"data.data == NULL or data.length == 0");
@ -1335,9 +1337,12 @@ _PUBLIC_ NTSTATUS netlogon_creds_session_encrypt(
data.data,
data.length);
} else if (state->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
netlogon_creds_arcfour_crypt(state,
data.data,
data.length);
status = netlogon_creds_arcfour_crypt(state,
data.data,
data.length);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
} else {
DBG_ERR("Unsupported encryption option negotiated");
return NT_STATUS_NOT_SUPPORTED;

View File

@ -262,7 +262,9 @@ void netlogon_creds_des_decrypt(struct netlogon_creds_CredentialState *creds, st
/*
ARCFOUR encrypt/decrypt a password buffer using the session key
*/
void netlogon_creds_arcfour_crypt(struct netlogon_creds_CredentialState *creds, uint8_t *data, size_t len)
NTSTATUS netlogon_creds_arcfour_crypt(struct netlogon_creds_CredentialState *creds,
uint8_t *data,
size_t len)
{
gnutls_cipher_hd_t cipher_hnd = NULL;
gnutls_datum_t session_key = {
@ -276,12 +278,19 @@ void netlogon_creds_arcfour_crypt(struct netlogon_creds_CredentialState *creds,
&session_key,
NULL);
if (rc < 0) {
return;
return gnutls_error_to_ntstatus(rc,
NT_STATUS_CRYPTO_SYSTEM_INVALID);
}
gnutls_cipher_encrypt(cipher_hnd,
data,
len);
rc = gnutls_cipher_encrypt(cipher_hnd,
data,
len);
gnutls_cipher_deinit(cipher_hnd);
if (rc < 0) {
return gnutls_error_to_ntstatus(rc,
NT_STATUS_CRYPTO_SYSTEM_INVALID);
}
return NT_STATUS_OK;
}
/*
@ -591,6 +600,7 @@ static NTSTATUS netlogon_creds_crypt_samlogon_validation(struct netlogon_creds_C
bool do_encrypt)
{
struct netr_SamBaseInfo *base = NULL;
NTSTATUS status;
if (validation == NULL) {
return NT_STATUS_INVALID_PARAMETER;
@ -654,16 +664,22 @@ static NTSTATUS netlogon_creds_crypt_samlogon_validation(struct netlogon_creds_C
} else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
/* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
if (!all_zero(base->key.key, sizeof(base->key.key))) {
netlogon_creds_arcfour_crypt(creds,
base->key.key,
sizeof(base->key.key));
status = netlogon_creds_arcfour_crypt(creds,
base->key.key,
sizeof(base->key.key));
if (!NT_STATUS_IS_OK(status)) {
return status;
}
}
if (!all_zero(base->LMSessKey.key,
sizeof(base->LMSessKey.key))) {
netlogon_creds_arcfour_crypt(creds,
base->LMSessKey.key,
sizeof(base->LMSessKey.key));
status = netlogon_creds_arcfour_crypt(creds,
base->LMSessKey.key,
sizeof(base->LMSessKey.key));
if (!NT_STATUS_IS_OK(status)) {
return status;
}
}
} else {
/* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
@ -707,6 +723,8 @@ static NTSTATUS netlogon_creds_crypt_samlogon_logon(struct netlogon_creds_Creden
union netr_LogonLevel *logon,
bool do_encrypt)
{
NTSTATUS status;
if (logon == NULL) {
return NT_STATUS_INVALID_PARAMETER;
}
@ -745,12 +763,22 @@ static NTSTATUS netlogon_creds_crypt_samlogon_logon(struct netlogon_creds_Creden
h = logon->password->lmpassword.hash;
if (!all_zero(h, 16)) {
netlogon_creds_arcfour_crypt(creds, h, 16);
status = netlogon_creds_arcfour_crypt(creds,
h,
16);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
}
h = logon->password->ntpassword.hash;
if (!all_zero(h, 16)) {
netlogon_creds_arcfour_crypt(creds, h, 16);
status = netlogon_creds_arcfour_crypt(creds,
h,
16);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
}
} else {
struct samr_Password *p;
@ -794,9 +822,12 @@ static NTSTATUS netlogon_creds_crypt_samlogon_logon(struct netlogon_creds_Creden
logon->generic->length);
}
} else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
netlogon_creds_arcfour_crypt(creds,
logon->generic->data,
logon->generic->length);
status = netlogon_creds_arcfour_crypt(creds,
logon->generic->data,
logon->generic->length);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
} else {
/* Using DES to verify kerberos tickets makes no sense */
}

View File

@ -1992,9 +1992,13 @@ static void netlogon_creds_cli_ServerPasswordSet_locked(struct tevent_req *subre
state->samr_crypt_password.data,
516);
} else {
netlogon_creds_arcfour_crypt(&state->tmp_creds,
state->samr_crypt_password.data,
516);
status = netlogon_creds_arcfour_crypt(&state->tmp_creds,
state->samr_crypt_password.data,
516);
if (tevent_req_nterror(req, status)) {
netlogon_creds_cli_ServerPasswordSet_cleanup(req, status);
return;
}
}
memcpy(state->netr_crypt_password.data,
@ -3685,9 +3689,13 @@ static void netlogon_creds_cli_SendToSam_locked(struct tevent_req *subreq)
state->opaque.data,
state->opaque.length);
} else {
netlogon_creds_arcfour_crypt(&state->tmp_creds,
state->opaque.data,
state->opaque.length);
status = netlogon_creds_arcfour_crypt(&state->tmp_creds,
state->opaque.data,
state->opaque.length);
if (tevent_req_nterror(req, status)) {
netlogon_creds_cli_SendToSam_cleanup(req, status);
return;
}
}
subreq = dcerpc_netr_NetrLogonSendToSam_send(state, state->ev,

View File

@ -15,7 +15,9 @@ void netlogon_creds_des_encrypt_LMKey(struct netlogon_creds_CredentialState *cre
void netlogon_creds_des_decrypt_LMKey(struct netlogon_creds_CredentialState *creds, struct netr_LMSessionKey *key);
void netlogon_creds_des_encrypt(struct netlogon_creds_CredentialState *creds, struct samr_Password *pass);
void netlogon_creds_des_decrypt(struct netlogon_creds_CredentialState *creds, struct samr_Password *pass);
void netlogon_creds_arcfour_crypt(struct netlogon_creds_CredentialState *creds, uint8_t *data, size_t len);
NTSTATUS netlogon_creds_arcfour_crypt(struct netlogon_creds_CredentialState *creds,
uint8_t *data,
size_t len);
void netlogon_creds_aes_encrypt(struct netlogon_creds_CredentialState *creds, uint8_t *data, size_t len);
void netlogon_creds_aes_decrypt(struct netlogon_creds_CredentialState *creds, uint8_t *data, size_t len);

View File

@ -69,9 +69,18 @@ static NTSTATUS fix_user(TALLOC_CTX *mem_ctx,
DATA_BLOB data;
struct netr_USER_KEYS keys;
enum ndr_err_code ndr_err;
NTSTATUS status;
data.data = user->user_private_info.SensitiveData;
data.length = user->user_private_info.DataLength;
netlogon_creds_arcfour_crypt(creds, data.data, data.length);
status = netlogon_creds_arcfour_crypt(creds,
data.data,
data.length);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
user->user_private_info.SensitiveData = data.data;
user->user_private_info.DataLength = data.length;
@ -125,11 +134,21 @@ static NTSTATUS fix_secret(TALLOC_CTX *mem_ctx,
struct netr_DELTA_ENUM *delta)
{
struct netr_DELTA_SECRET *secret = delta->delta_union.secret;
netlogon_creds_arcfour_crypt(creds, secret->current_cipher.cipher_data,
secret->current_cipher.maxlen);
NTSTATUS status;
netlogon_creds_arcfour_crypt(creds, secret->old_cipher.cipher_data,
secret->old_cipher.maxlen);
status = netlogon_creds_arcfour_crypt(creds,
secret->current_cipher.cipher_data,
secret->current_cipher.maxlen);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
status = netlogon_creds_arcfour_crypt(creds,
secret->old_cipher.cipher_data,
secret->old_cipher.maxlen);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
return NT_STATUS_OK;
}

View File

@ -31,13 +31,19 @@ void init_netr_CryptPassword(const char *pwd,
struct netr_CryptPassword *pwd_buf)
{
struct samr_CryptPassword password_buf;
NTSTATUS status;
encode_pw_buffer(password_buf.data, pwd, STR_UNICODE);
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
} else {
netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
status = netlogon_creds_arcfour_crypt(creds,
password_buf.data,
516);
if (!NT_STATUS_IS_OK(status)) {
return;
}
}
memcpy(pwd_buf->data, password_buf.data, 512);
pwd_buf->length = IVAL(password_buf.data, 512);

View File

@ -1361,7 +1361,12 @@ NTSTATUS _netr_ServerPasswordSet2(struct pipes_struct *p,
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
netlogon_creds_aes_decrypt(creds, password_buf.data, 516);
} else {
netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
status = netlogon_creds_arcfour_crypt(creds,
password_buf.data,
516);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
}
if (!decode_pw_buffer(p->mem_ctx,

View File

@ -749,7 +749,12 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_cal
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
netlogon_creds_aes_decrypt(creds, password_buf.data, 516);
} else {
netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
nt_status = netlogon_creds_arcfour_crypt(creds,
password_buf.data,
516);
if (!NT_STATUS_IS_OK(nt_status)) {
return nt_status;
}
}
switch (creds->secure_channel_type) {
@ -2800,7 +2805,12 @@ static NTSTATUS dcesrv_netr_NetrLogonSendToSam(struct dcesrv_call_state *dce_cal
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
netlogon_creds_aes_decrypt(creds, r->in.opaque_buffer, r->in.buffer_len);
} else {
netlogon_creds_arcfour_crypt(creds, r->in.opaque_buffer, r->in.buffer_len);
nt_status = netlogon_creds_arcfour_crypt(creds,
r->in.opaque_buffer,
r->in.buffer_len);
if (!NT_STATUS_IS_OK(nt_status)) {
return nt_status;
}
}
decrypted_blob.data = r->in.opaque_buffer;