|
|
b6b438 |
From 8d840662df55c11616338af5c3b4b062485b19a4 Mon Sep 17 00:00:00 2001
|
|
|
b6b438 |
From: Isaac Boukris <iboukris@gmail.com>
|
|
|
b6b438 |
Date: Wed, 20 Nov 2019 16:02:16 +0100
|
|
|
b6b438 |
Subject: [PATCH 184/187] smbdes: convert des_crypt112_16 to use gnutls
|
|
|
b6b438 |
|
|
|
b6b438 |
Signed-off-by: Isaac Boukris <iboukris@samba.org>
|
|
|
b6b438 |
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
|
|
b6b438 |
(cherry picked from commit dcc33103d5c0927bb3757974d4663df888dce95e)
|
|
|
b6b438 |
---
|
|
|
b6b438 |
libcli/auth/credentials.c | 38 +++++++++++++++----
|
|
|
b6b438 |
libcli/auth/netlogon_creds_cli.c | 24 +++++++++---
|
|
|
b6b438 |
libcli/auth/proto.h | 9 +++--
|
|
|
b6b438 |
libcli/auth/smbdes.c | 13 +++++--
|
|
|
b6b438 |
libcli/auth/tests/test_gnutls.c | 7 +++-
|
|
|
b6b438 |
source3/rpc_server/netlogon/srv_netlog_nt.c | 16 ++++++--
|
|
|
b6b438 |
source4/rpc_server/netlogon/dcerpc_netlogon.c | 13 +++++--
|
|
|
b6b438 |
7 files changed, 92 insertions(+), 28 deletions(-)
|
|
|
b6b438 |
|
|
|
b6b438 |
diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c
|
|
|
b6b438 |
index 5f65428a1d7..c541eeff470 100644
|
|
|
b6b438 |
--- a/libcli/auth/credentials.c
|
|
|
b6b438 |
+++ b/libcli/auth/credentials.c
|
|
|
b6b438 |
@@ -302,21 +302,37 @@ NTSTATUS netlogon_creds_des_decrypt_LMKey(struct netlogon_creds_CredentialState
|
|
|
b6b438 |
/*
|
|
|
b6b438 |
DES encrypt a 16 byte password buffer using the session key
|
|
|
b6b438 |
*/
|
|
|
b6b438 |
-void netlogon_creds_des_encrypt(struct netlogon_creds_CredentialState *creds, struct samr_Password *pass)
|
|
|
b6b438 |
+NTSTATUS netlogon_creds_des_encrypt(struct netlogon_creds_CredentialState *creds,
|
|
|
b6b438 |
+ struct samr_Password *pass)
|
|
|
b6b438 |
{
|
|
|
b6b438 |
struct samr_Password tmp;
|
|
|
b6b438 |
- des_crypt112_16(tmp.hash, pass->hash, creds->session_key, 1);
|
|
|
b6b438 |
+ int rc;
|
|
|
b6b438 |
+
|
|
|
b6b438 |
+ rc = des_crypt112_16(tmp.hash, pass->hash, creds->session_key, SAMBA_GNUTLS_ENCRYPT);
|
|
|
b6b438 |
+ if (rc < 0) {
|
|
|
b6b438 |
+ return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
|
|
|
b6b438 |
+ }
|
|
|
b6b438 |
*pass = tmp;
|
|
|
b6b438 |
+
|
|
|
b6b438 |
+ return NT_STATUS_OK;
|
|
|
b6b438 |
}
|
|
|
b6b438 |
|
|
|
b6b438 |
/*
|
|
|
b6b438 |
DES decrypt a 16 byte password buffer using the session key
|
|
|
b6b438 |
*/
|
|
|
b6b438 |
-void netlogon_creds_des_decrypt(struct netlogon_creds_CredentialState *creds, struct samr_Password *pass)
|
|
|
b6b438 |
+NTSTATUS netlogon_creds_des_decrypt(struct netlogon_creds_CredentialState *creds,
|
|
|
b6b438 |
+ struct samr_Password *pass)
|
|
|
b6b438 |
{
|
|
|
b6b438 |
struct samr_Password tmp;
|
|
|
b6b438 |
- des_crypt112_16(tmp.hash, pass->hash, creds->session_key, 0);
|
|
|
b6b438 |
+ int rc;
|
|
|
b6b438 |
+
|
|
|
b6b438 |
+ rc = des_crypt112_16(tmp.hash, pass->hash, creds->session_key, SAMBA_GNUTLS_DECRYPT);
|
|
|
b6b438 |
+ if (rc < 0) {
|
|
|
b6b438 |
+ return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
|
|
|
b6b438 |
+ }
|
|
|
b6b438 |
*pass = tmp;
|
|
|
b6b438 |
+
|
|
|
b6b438 |
+ return NT_STATUS_OK;
|
|
|
b6b438 |
}
|
|
|
b6b438 |
|
|
|
b6b438 |
/*
|
|
|
b6b438 |
@@ -993,17 +1009,23 @@ static NTSTATUS netlogon_creds_crypt_samlogon_logon(struct netlogon_creds_Creden
|
|
|
b6b438 |
p = &logon->password->lmpassword;
|
|
|
b6b438 |
if (!all_zero(p->hash, 16)) {
|
|
|
b6b438 |
if (do_encrypt) {
|
|
|
b6b438 |
- netlogon_creds_des_encrypt(creds, p);
|
|
|
b6b438 |
+ status = netlogon_creds_des_encrypt(creds, p);
|
|
|
b6b438 |
} else {
|
|
|
b6b438 |
- netlogon_creds_des_decrypt(creds, p);
|
|
|
b6b438 |
+ status = netlogon_creds_des_decrypt(creds, p);
|
|
|
b6b438 |
+ }
|
|
|
b6b438 |
+ if (!NT_STATUS_IS_OK(status)) {
|
|
|
b6b438 |
+ return status;
|
|
|
b6b438 |
}
|
|
|
b6b438 |
}
|
|
|
b6b438 |
p = &logon->password->ntpassword;
|
|
|
b6b438 |
if (!all_zero(p->hash, 16)) {
|
|
|
b6b438 |
if (do_encrypt) {
|
|
|
b6b438 |
- netlogon_creds_des_encrypt(creds, p);
|
|
|
b6b438 |
+ status = netlogon_creds_des_encrypt(creds, p);
|
|
|
b6b438 |
} else {
|
|
|
b6b438 |
- netlogon_creds_des_decrypt(creds, p);
|
|
|
b6b438 |
+ status = netlogon_creds_des_decrypt(creds, p);
|
|
|
b6b438 |
+ }
|
|
|
b6b438 |
+ if (!NT_STATUS_IS_OK(status)) {
|
|
|
b6b438 |
+ return status;
|
|
|
b6b438 |
}
|
|
|
b6b438 |
}
|
|
|
b6b438 |
}
|
|
|
b6b438 |
diff --git a/libcli/auth/netlogon_creds_cli.c b/libcli/auth/netlogon_creds_cli.c
|
|
|
b6b438 |
index 0378f302ffa..c8f4227a924 100644
|
|
|
b6b438 |
--- a/libcli/auth/netlogon_creds_cli.c
|
|
|
b6b438 |
+++ b/libcli/auth/netlogon_creds_cli.c
|
|
|
b6b438 |
@@ -2032,8 +2032,12 @@ static void netlogon_creds_cli_ServerPasswordSet_locked(struct tevent_req *subre
|
|
|
b6b438 |
return;
|
|
|
b6b438 |
}
|
|
|
b6b438 |
} else {
|
|
|
b6b438 |
- netlogon_creds_des_encrypt(&state->tmp_creds,
|
|
|
b6b438 |
- &state->samr_password);
|
|
|
b6b438 |
+ status = netlogon_creds_des_encrypt(&state->tmp_creds,
|
|
|
b6b438 |
+ &state->samr_password);
|
|
|
b6b438 |
+ if (tevent_req_nterror(req, status)) {
|
|
|
b6b438 |
+ netlogon_creds_cli_ServerPasswordSet_cleanup(req, status);
|
|
|
b6b438 |
+ return;
|
|
|
b6b438 |
+ }
|
|
|
b6b438 |
|
|
|
b6b438 |
subreq = dcerpc_netr_ServerPasswordSet_send(state, state->ev,
|
|
|
b6b438 |
state->binding_handle,
|
|
|
b6b438 |
@@ -3187,14 +3191,22 @@ static void netlogon_creds_cli_ServerGetTrustInfo_done(struct tevent_req *subreq
|
|
|
b6b438 |
cmp = memcmp(state->new_owf_password.hash,
|
|
|
b6b438 |
zero.hash, sizeof(zero.hash));
|
|
|
b6b438 |
if (cmp != 0) {
|
|
|
b6b438 |
- netlogon_creds_des_decrypt(&state->tmp_creds,
|
|
|
b6b438 |
- &state->new_owf_password);
|
|
|
b6b438 |
+ status = netlogon_creds_des_decrypt(&state->tmp_creds,
|
|
|
b6b438 |
+ &state->new_owf_password);
|
|
|
b6b438 |
+ if (tevent_req_nterror(req, status)) {
|
|
|
b6b438 |
+ netlogon_creds_cli_ServerGetTrustInfo_cleanup(req, status);
|
|
|
b6b438 |
+ return;
|
|
|
b6b438 |
+ }
|
|
|
b6b438 |
}
|
|
|
b6b438 |
cmp = memcmp(state->old_owf_password.hash,
|
|
|
b6b438 |
zero.hash, sizeof(zero.hash));
|
|
|
b6b438 |
if (cmp != 0) {
|
|
|
b6b438 |
- netlogon_creds_des_decrypt(&state->tmp_creds,
|
|
|
b6b438 |
- &state->old_owf_password);
|
|
|
b6b438 |
+ status = netlogon_creds_des_decrypt(&state->tmp_creds,
|
|
|
b6b438 |
+ &state->old_owf_password);
|
|
|
b6b438 |
+ if (tevent_req_nterror(req, status)) {
|
|
|
b6b438 |
+ netlogon_creds_cli_ServerGetTrustInfo_cleanup(req, status);
|
|
|
b6b438 |
+ return;
|
|
|
b6b438 |
+ }
|
|
|
b6b438 |
}
|
|
|
b6b438 |
|
|
|
b6b438 |
*state->creds = state->tmp_creds;
|
|
|
b6b438 |
diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h
|
|
|
b6b438 |
index 3994db20a36..4c6d7af6763 100644
|
|
|
b6b438 |
--- a/libcli/auth/proto.h
|
|
|
b6b438 |
+++ b/libcli/auth/proto.h
|
|
|
b6b438 |
@@ -17,8 +17,10 @@ NTSTATUS netlogon_creds_des_encrypt_LMKey(struct netlogon_creds_CredentialState
|
|
|
b6b438 |
struct netr_LMSessionKey *key);
|
|
|
b6b438 |
NTSTATUS netlogon_creds_des_decrypt_LMKey(struct netlogon_creds_CredentialState *creds,
|
|
|
b6b438 |
struct netr_LMSessionKey *key);
|
|
|
b6b438 |
-void netlogon_creds_des_encrypt(struct netlogon_creds_CredentialState *creds, struct samr_Password *pass);
|
|
|
b6b438 |
-void netlogon_creds_des_decrypt(struct netlogon_creds_CredentialState *creds, struct samr_Password *pass);
|
|
|
b6b438 |
+NTSTATUS netlogon_creds_des_encrypt(struct netlogon_creds_CredentialState *creds,
|
|
|
b6b438 |
+ struct samr_Password *pass);
|
|
|
b6b438 |
+NTSTATUS netlogon_creds_des_decrypt(struct netlogon_creds_CredentialState *creds,
|
|
|
b6b438 |
+ struct samr_Password *pass);
|
|
|
b6b438 |
NTSTATUS netlogon_creds_arcfour_crypt(struct netlogon_creds_CredentialState *creds,
|
|
|
b6b438 |
uint8_t *data,
|
|
|
b6b438 |
size_t len);
|
|
|
b6b438 |
@@ -229,7 +231,8 @@ int E_old_pw_hash( uint8_t *p14, const uint8_t *in, uint8_t *out);
|
|
|
b6b438 |
int des_crypt128(uint8_t out[8], const uint8_t in[8], const uint8_t key[16]);
|
|
|
b6b438 |
int des_crypt112(uint8_t out[8], const uint8_t in[8], const uint8_t key[14],
|
|
|
b6b438 |
enum samba_gnutls_direction encrypt);
|
|
|
b6b438 |
-void des_crypt112_16(uint8_t out[16], const uint8_t in[16], const uint8_t key[14], int forw);
|
|
|
b6b438 |
+int des_crypt112_16(uint8_t out[16], const uint8_t in[16], const uint8_t key[14],
|
|
|
b6b438 |
+ enum samba_gnutls_direction encrypt);
|
|
|
b6b438 |
int sam_rid_crypt(unsigned int rid, const uint8_t *in, uint8_t *out,
|
|
|
b6b438 |
enum samba_gnutls_direction encrypt);
|
|
|
b6b438 |
#undef _PRINTF_ATTRIBUTE
|
|
|
b6b438 |
diff --git a/libcli/auth/smbdes.c b/libcli/auth/smbdes.c
|
|
|
b6b438 |
index 8dc4fc4097c..8fc79dc5c71 100644
|
|
|
b6b438 |
--- a/libcli/auth/smbdes.c
|
|
|
b6b438 |
+++ b/libcli/auth/smbdes.c
|
|
|
b6b438 |
@@ -442,10 +442,17 @@ int des_crypt112(uint8_t out[8], const uint8_t in[8], const uint8_t key[14],
|
|
|
b6b438 |
}
|
|
|
b6b438 |
|
|
|
b6b438 |
/* des encryption of a 16 byte lump of data with a 112 bit key */
|
|
|
b6b438 |
-void des_crypt112_16(uint8_t out[16], const uint8_t in[16], const uint8_t key[14], int forw)
|
|
|
b6b438 |
+int des_crypt112_16(uint8_t out[16], const uint8_t in[16], const uint8_t key[14],
|
|
|
b6b438 |
+ enum samba_gnutls_direction encrypt)
|
|
|
b6b438 |
{
|
|
|
b6b438 |
- des_crypt56(out, in, key, forw);
|
|
|
b6b438 |
- des_crypt56(out + 8, in + 8, key+7, forw);
|
|
|
b6b438 |
+ int ret;
|
|
|
b6b438 |
+
|
|
|
b6b438 |
+ ret = des_crypt56_gnutls(out, in, key, encrypt);
|
|
|
b6b438 |
+ if (ret != 0) {
|
|
|
b6b438 |
+ return ret;
|
|
|
b6b438 |
+ }
|
|
|
b6b438 |
+
|
|
|
b6b438 |
+ return des_crypt56_gnutls(out + 8, in + 8, key+7, encrypt);
|
|
|
b6b438 |
}
|
|
|
b6b438 |
|
|
|
b6b438 |
/* Decode a sam password hash into a password. The password hash is the
|
|
|
b6b438 |
diff --git a/libcli/auth/tests/test_gnutls.c b/libcli/auth/tests/test_gnutls.c
|
|
|
b6b438 |
index 68a27adc894..a6692b9a913 100644
|
|
|
b6b438 |
--- a/libcli/auth/tests/test_gnutls.c
|
|
|
b6b438 |
+++ b/libcli/auth/tests/test_gnutls.c
|
|
|
b6b438 |
@@ -414,11 +414,14 @@ static void torture_gnutls_des_crypt112_16(void **state)
|
|
|
b6b438 |
|
|
|
b6b438 |
uint8_t crypt[16];
|
|
|
b6b438 |
uint8_t decrypt[16];
|
|
|
b6b438 |
+ int rc;
|
|
|
b6b438 |
|
|
|
b6b438 |
- des_crypt112_16(crypt, clear, key, 1);
|
|
|
b6b438 |
+ rc = des_crypt112_16(crypt, clear, key, SAMBA_GNUTLS_ENCRYPT);
|
|
|
b6b438 |
+ assert_int_equal(rc, 0);
|
|
|
b6b438 |
assert_memory_equal(crypt, crypt_expected, 16);
|
|
|
b6b438 |
|
|
|
b6b438 |
- des_crypt112_16(decrypt, crypt, key, 0);
|
|
|
b6b438 |
+ rc = des_crypt112_16(decrypt, crypt, key, SAMBA_GNUTLS_DECRYPT);
|
|
|
b6b438 |
+ assert_int_equal(rc, 0);
|
|
|
b6b438 |
assert_memory_equal(decrypt, clear, 16);
|
|
|
b6b438 |
}
|
|
|
b6b438 |
|
|
|
b6b438 |
diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
|
|
|
b6b438 |
index 671300676ff..124bae95064 100644
|
|
|
b6b438 |
--- a/source3/rpc_server/netlogon/srv_netlog_nt.c
|
|
|
b6b438 |
+++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
|
|
|
b6b438 |
@@ -1311,7 +1311,10 @@ NTSTATUS _netr_ServerPasswordSet(struct pipes_struct *p,
|
|
|
b6b438 |
DEBUG(3,("_netr_ServerPasswordSet: Server Password Set by remote machine:[%s] on account [%s]\n",
|
|
|
b6b438 |
r->in.computer_name, creds->computer_name));
|
|
|
b6b438 |
|
|
|
b6b438 |
- netlogon_creds_des_decrypt(creds, r->in.new_password);
|
|
|
b6b438 |
+ status = netlogon_creds_des_decrypt(creds, r->in.new_password);
|
|
|
b6b438 |
+ if (!NT_STATUS_IS_OK(status)) {
|
|
|
b6b438 |
+ return status;
|
|
|
b6b438 |
+ }
|
|
|
b6b438 |
|
|
|
b6b438 |
DEBUG(100,("_netr_ServerPasswordSet: new given value was :\n"));
|
|
|
b6b438 |
for(i = 0; i < sizeof(r->in.new_password->hash); i++)
|
|
|
b6b438 |
@@ -2560,6 +2563,7 @@ static NTSTATUS get_password_from_trustAuth(TALLOC_CTX *mem_ctx,
|
|
|
b6b438 |
{
|
|
|
b6b438 |
enum ndr_err_code ndr_err;
|
|
|
b6b438 |
struct trustAuthInOutBlob trustAuth;
|
|
|
b6b438 |
+ NTSTATUS status;
|
|
|
b6b438 |
|
|
|
b6b438 |
ndr_err = ndr_pull_struct_blob_all(trustAuth_blob, mem_ctx, &trustAuth,
|
|
|
b6b438 |
(ndr_pull_flags_fn_t)ndr_pull_trustAuthInOutBlob);
|
|
|
b6b438 |
@@ -2572,7 +2576,10 @@ static NTSTATUS get_password_from_trustAuth(TALLOC_CTX *mem_ctx,
|
|
|
b6b438 |
mdfour(current_pw_enc->hash,
|
|
|
b6b438 |
trustAuth.current.array[0].AuthInfo.clear.password,
|
|
|
b6b438 |
trustAuth.current.array[0].AuthInfo.clear.size);
|
|
|
b6b438 |
- netlogon_creds_des_encrypt(creds, current_pw_enc);
|
|
|
b6b438 |
+ status = netlogon_creds_des_encrypt(creds, current_pw_enc);
|
|
|
b6b438 |
+ if (!NT_STATUS_IS_OK(status)) {
|
|
|
b6b438 |
+ return status;
|
|
|
b6b438 |
+ }
|
|
|
b6b438 |
} else {
|
|
|
b6b438 |
return NT_STATUS_UNSUCCESSFUL;
|
|
|
b6b438 |
}
|
|
|
b6b438 |
@@ -2583,7 +2590,10 @@ static NTSTATUS get_password_from_trustAuth(TALLOC_CTX *mem_ctx,
|
|
|
b6b438 |
mdfour(previous_pw_enc->hash,
|
|
|
b6b438 |
trustAuth.previous.array[0].AuthInfo.clear.password,
|
|
|
b6b438 |
trustAuth.previous.array[0].AuthInfo.clear.size);
|
|
|
b6b438 |
- netlogon_creds_des_encrypt(creds, previous_pw_enc);
|
|
|
b6b438 |
+ status = netlogon_creds_des_encrypt(creds, previous_pw_enc);
|
|
|
b6b438 |
+ if (!NT_STATUS_IS_OK(status)) {
|
|
|
b6b438 |
+ return status;
|
|
|
b6b438 |
+ }
|
|
|
b6b438 |
} else {
|
|
|
b6b438 |
ZERO_STRUCTP(previous_pw_enc);
|
|
|
b6b438 |
}
|
|
|
b6b438 |
diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
|
|
|
b6b438 |
index 49a075137ff..6c92db7b53a 100644
|
|
|
b6b438 |
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
|
|
|
b6b438 |
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
|
|
|
b6b438 |
@@ -678,7 +678,8 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet(struct dcesrv_call_state *dce_call
|
|
|
b6b438 |
return NT_STATUS_INVALID_SYSTEM_SERVICE;
|
|
|
b6b438 |
}
|
|
|
b6b438 |
|
|
|
b6b438 |
- netlogon_creds_des_decrypt(creds, r->in.new_password);
|
|
|
b6b438 |
+ nt_status = netlogon_creds_des_decrypt(creds, r->in.new_password);
|
|
|
b6b438 |
+ NT_STATUS_NOT_OK_RETURN(nt_status);
|
|
|
b6b438 |
|
|
|
b6b438 |
/* fetch the old password hashes (the NT hash has to exist) */
|
|
|
b6b438 |
|
|
|
b6b438 |
@@ -4193,11 +4194,17 @@ static NTSTATUS dcesrv_netr_ServerGetTrustInfo(struct dcesrv_call_state *dce_cal
|
|
|
b6b438 |
|
|
|
b6b438 |
if (curNtHash != NULL) {
|
|
|
b6b438 |
*r->out.new_owf_password = *curNtHash;
|
|
|
b6b438 |
- netlogon_creds_des_encrypt(creds, r->out.new_owf_password);
|
|
|
b6b438 |
+ nt_status = netlogon_creds_des_encrypt(creds, r->out.new_owf_password);
|
|
|
b6b438 |
+ if (!NT_STATUS_IS_OK(nt_status)) {
|
|
|
b6b438 |
+ return nt_status;
|
|
|
b6b438 |
+ }
|
|
|
b6b438 |
}
|
|
|
b6b438 |
if (prevNtHash != NULL) {
|
|
|
b6b438 |
*r->out.old_owf_password = *prevNtHash;
|
|
|
b6b438 |
- netlogon_creds_des_encrypt(creds, r->out.old_owf_password);
|
|
|
b6b438 |
+ nt_status = netlogon_creds_des_encrypt(creds, r->out.old_owf_password);
|
|
|
b6b438 |
+ if (!NT_STATUS_IS_OK(nt_status)) {
|
|
|
b6b438 |
+ return nt_status;
|
|
|
b6b438 |
+ }
|
|
|
b6b438 |
}
|
|
|
b6b438 |
|
|
|
b6b438 |
if (trust_info != NULL) {
|
|
|
b6b438 |
--
|
|
|
b6b438 |
2.23.0
|
|
|
b6b438 |
|