From 9d3ec4680cb1d460650cab011ab17f12c9cd0d69 Mon Sep 17 00:00:00 2001 From: Isaac Boukris Date: Fri, 8 Nov 2019 15:40:01 +0100 Subject: [PATCH 180/187] smbdes: convert E_P24() and SMBOWFencrypt to use gnutls Signed-off-by: Isaac Boukris Reviewed-by: Andrew Bartlett (cherry picked from commit a5548af018643f2e78c482e33ef0e6073db149e4) --- auth/credentials/credentials_ntlm.c | 31 ++++++++++++++++++++--------- libcli/auth/ntlm_check.c | 6 +++++- libcli/auth/proto.h | 10 +++++----- libcli/auth/smbdes.c | 18 +++++++++++++---- libcli/auth/smbencrypt.c | 28 +++++++++++++++++--------- libcli/auth/tests/test_gnutls.c | 8 ++++++-- source3/auth/auth_util.c | 19 +++++++++++++----- source3/rpc_client/cli_netlogon.c | 8 +++++++- source3/torture/pdbtest.c | 9 +++++++-- source3/winbindd/winbindd_pam.c | 9 ++++++++- source4/auth/ntlm/auth_util.c | 13 +++++++++--- source4/torture/rpc/samsync.c | 14 +++++++++++-- 12 files changed, 129 insertions(+), 44 deletions(-) diff --git a/auth/credentials/credentials_ntlm.c b/auth/credentials/credentials_ntlm.c index bf55ab97b04..f1b22a6c9e2 100644 --- a/auth/credentials/credentials_ntlm.c +++ b/auth/credentials/credentials_ntlm.c @@ -51,6 +51,7 @@ _PUBLIC_ NTSTATUS cli_credentials_get_ntlm_response(struct cli_credentials *cred DATA_BLOB lm_session_key = data_blob_null; DATA_BLOB session_key = data_blob_null; const struct samr_Password *nt_hash = NULL; + int rc; if (cred->use_kerberos == CRED_MUST_USE_KERBEROS) { TALLOC_FREE(frame); @@ -159,7 +160,6 @@ _PUBLIC_ NTSTATUS cli_credentials_get_ntlm_response(struct cli_credentials *cred uint8_t session_nonce[16]; uint8_t session_nonce_hash[16]; uint8_t user_session_key[16]; - int rc; lm_response = data_blob_talloc_zero(frame, 24); if (lm_response.data == NULL) { @@ -188,9 +188,13 @@ _PUBLIC_ NTSTATUS cli_credentials_get_ntlm_response(struct cli_credentials *cred TALLOC_FREE(frame); return NT_STATUS_NO_MEMORY; } - SMBOWFencrypt(nt_hash->hash, - session_nonce_hash, - nt_response.data); + rc = SMBOWFencrypt(nt_hash->hash, + session_nonce_hash, + nt_response.data); + if (rc != 0) { + TALLOC_FREE(frame); + return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); + } ZERO_ARRAY(session_nonce_hash); @@ -228,8 +232,12 @@ _PUBLIC_ NTSTATUS cli_credentials_get_ntlm_response(struct cli_credentials *cred TALLOC_FREE(frame); return NT_STATUS_NO_MEMORY; } - SMBOWFencrypt(nt_hash->hash, challenge.data, - nt_response.data); + rc = SMBOWFencrypt(nt_hash->hash, challenge.data, + nt_response.data); + if (rc != 0) { + TALLOC_FREE(frame); + return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); + } session_key = data_blob_talloc_zero(frame, 16); if (session_key.data == NULL) { @@ -254,9 +262,14 @@ _PUBLIC_ NTSTATUS cli_credentials_get_ntlm_response(struct cli_credentials *cred return NT_STATUS_NO_MEMORY; } - SMBencrypt_hash(lm_hash, - challenge.data, - lm_response.data); + rc = SMBencrypt_hash(lm_hash, + challenge.data, + lm_response.data); + if (rc != 0) { + ZERO_STRUCT(lm_hash); + TALLOC_FREE(frame); + return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); + } } else { /* just copy the nt_response */ lm_response = data_blob_dup_talloc(frame, nt_response); diff --git a/libcli/auth/ntlm_check.c b/libcli/auth/ntlm_check.c index 5058add3811..9f779f85fa1 100644 --- a/libcli/auth/ntlm_check.c +++ b/libcli/auth/ntlm_check.c @@ -36,6 +36,7 @@ static bool smb_pwd_check_ntlmv1(TALLOC_CTX *mem_ctx, { /* Finish the encryption of part_passwd. */ uint8_t p24[24]; + int rc; if (part_passwd == NULL) { DEBUG(10,("No password set - DISALLOWING access\n")); @@ -55,7 +56,10 @@ static bool smb_pwd_check_ntlmv1(TALLOC_CTX *mem_ctx, return false; } - SMBOWFencrypt(part_passwd, sec_blob->data, p24); + rc = SMBOWFencrypt(part_passwd, sec_blob->data, p24); + if (rc != 0) { + return false; + } #if DEBUG_PASSWORD DEBUG(100,("Part password (P16) was |\n")); diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h index 212b46bb0e8..5209d6766e4 100644 --- a/libcli/auth/proto.h +++ b/libcli/auth/proto.h @@ -99,7 +99,7 @@ NTSTATUS sess_decrypt_blob(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, const DAT /* The following definitions come from /home/jeremy/src/samba/git/master/source3/../source4/../libcli/auth/smbencrypt.c */ -void SMBencrypt_hash(const uint8_t lm_hash[16], const uint8_t *c8, uint8_t p24[24]); +int SMBencrypt_hash(const uint8_t lm_hash[16], const uint8_t *c8, uint8_t p24[24]); bool SMBencrypt(const char *passwd, const uint8_t *c8, uint8_t p24[24]); /** @@ -129,9 +129,9 @@ void nt_lm_owf_gen(const char *pwd, uint8_t nt_p16[16], uint8_t p16[16]); bool ntv2_owf_gen(const uint8_t owf[16], const char *user_in, const char *domain_in, uint8_t kr_buf[16]); -void SMBOWFencrypt(const uint8_t passwd[16], const uint8_t *c8, uint8_t p24[24]); -void SMBNTencrypt_hash(const uint8_t nt_hash[16], const uint8_t *c8, uint8_t *p24); -void SMBNTencrypt(const char *passwd, const uint8_t *c8, uint8_t *p24); +int SMBOWFencrypt(const uint8_t passwd[16], const uint8_t *c8, uint8_t p24[24]); +int SMBNTencrypt_hash(const uint8_t nt_hash[16], const uint8_t *c8, uint8_t *p24); +int SMBNTencrypt(const char *passwd, const uint8_t *c8, uint8_t *p24); NTSTATUS SMBOWFencrypt_ntv2(const uint8_t kr[16], const DATA_BLOB *srv_chal, const DATA_BLOB *smbcli_chal, @@ -224,7 +224,7 @@ void des_crypt56(uint8_t out[8], const uint8_t in[8], const uint8_t key[7], int int des_crypt56_gnutls(uint8_t out[8], const uint8_t in[8], const uint8_t key[7], enum samba_gnutls_direction encrypt); int E_P16(const uint8_t *p14,uint8_t *p16); -void E_P24(const uint8_t *p21, const uint8_t *c8, uint8_t *p24); +int E_P24(const uint8_t *p21, const uint8_t *c8, uint8_t *p24); void E_old_pw_hash( uint8_t *p14, const uint8_t *in, uint8_t *out); void des_crypt128(uint8_t out[8], const uint8_t in[8], const uint8_t key[16]); void des_crypt112(uint8_t out[8], const uint8_t in[8], const uint8_t key[14], int forw); diff --git a/libcli/auth/smbdes.c b/libcli/auth/smbdes.c index 46fd5849f5b..4e3499f9d26 100644 --- a/libcli/auth/smbdes.c +++ b/libcli/auth/smbdes.c @@ -374,11 +374,21 @@ int E_P16(const uint8_t *p14,uint8_t *p16) return des_crypt56_gnutls(p16+8, sp8, p14+7, SAMBA_GNUTLS_ENCRYPT); } -void E_P24(const uint8_t *p21, const uint8_t *c8, uint8_t *p24) +int E_P24(const uint8_t *p21, const uint8_t *c8, uint8_t *p24) { - des_crypt56(p24, c8, p21, 1); - des_crypt56(p24+8, c8, p21+7, 1); - des_crypt56(p24+16, c8, p21+14, 1); + int ret; + + ret = des_crypt56_gnutls(p24, c8, p21, SAMBA_GNUTLS_ENCRYPT); + if (ret != 0) { + return ret; + } + + ret = des_crypt56_gnutls(p24+8, c8, p21+7, SAMBA_GNUTLS_ENCRYPT); + if (ret != 0) { + return ret; + } + + return des_crypt56_gnutls(p24+16, c8, p21+14, SAMBA_GNUTLS_ENCRYPT); } void E_old_pw_hash( uint8_t *p14, const uint8_t *in, uint8_t *out) diff --git a/libcli/auth/smbencrypt.c b/libcli/auth/smbencrypt.c index f2f446eda97..337e89ef559 100644 --- a/libcli/auth/smbencrypt.c +++ b/libcli/auth/smbencrypt.c @@ -32,14 +32,15 @@ #include #include -void SMBencrypt_hash(const uint8_t lm_hash[16], const uint8_t *c8, uint8_t p24[24]) +int SMBencrypt_hash(const uint8_t lm_hash[16], const uint8_t *c8, uint8_t p24[24]) { uint8_t p21[21]; + int rc; memset(p21,'\0',21); memcpy(p21, lm_hash, 16); - SMBOWFencrypt(p21, c8, p24); + rc = SMBOWFencrypt(p21, c8, p24); #ifdef DEBUG_PASSWORD DEBUG(100,("SMBencrypt_hash: lm#, challenge, response\n")); @@ -47,6 +48,8 @@ void SMBencrypt_hash(const uint8_t lm_hash[16], const uint8_t *c8, uint8_t p24[2 dump_data(100, c8, 8); dump_data(100, p24, 24); #endif + + return rc; } /* @@ -61,9 +64,13 @@ bool SMBencrypt(const char *passwd, const uint8_t *c8, uint8_t p24[24]) { bool ret; uint8_t lm_hash[16]; + int rc; ret = E_deshash(passwd, lm_hash); - SMBencrypt_hash(lm_hash, c8, p24); + rc = SMBencrypt_hash(lm_hash, c8, p24); + if (rc != 0) { + ret = false; + } return ret; } @@ -266,25 +273,26 @@ out: } /* Does the des encryption from the NT or LM MD4 hash. */ -void SMBOWFencrypt(const uint8_t passwd[16], const uint8_t *c8, uint8_t p24[24]) +int SMBOWFencrypt(const uint8_t passwd[16], const uint8_t *c8, uint8_t p24[24]) { uint8_t p21[21]; ZERO_STRUCT(p21); memcpy(p21, passwd, 16); - E_P24(p21, c8, p24); + return E_P24(p21, c8, p24); } /* Does the des encryption. */ -void SMBNTencrypt_hash(const uint8_t nt_hash[16], const uint8_t *c8, uint8_t *p24) +int SMBNTencrypt_hash(const uint8_t nt_hash[16], const uint8_t *c8, uint8_t *p24) { uint8_t p21[21]; + int rc; memset(p21,'\0',21); memcpy(p21, nt_hash, 16); - SMBOWFencrypt(p21, c8, p24); + rc = SMBOWFencrypt(p21, c8, p24); #ifdef DEBUG_PASSWORD DEBUG(100,("SMBNTencrypt: nt#, challenge, response\n")); @@ -292,15 +300,17 @@ void SMBNTencrypt_hash(const uint8_t nt_hash[16], const uint8_t *c8, uint8_t *p2 dump_data(100, c8, 8); dump_data(100, p24, 24); #endif + + return rc; } /* Does the NT MD4 hash then des encryption. Plaintext version of the above. */ -void SMBNTencrypt(const char *passwd, const uint8_t *c8, uint8_t *p24) +int SMBNTencrypt(const char *passwd, const uint8_t *c8, uint8_t *p24) { uint8_t nt_hash[16]; E_md4hash(passwd, nt_hash); - SMBNTencrypt_hash(nt_hash, c8, p24); + return SMBNTencrypt_hash(nt_hash, c8, p24); } diff --git a/libcli/auth/tests/test_gnutls.c b/libcli/auth/tests/test_gnutls.c index a6e8fd5b352..9fafe2a767b 100644 --- a/libcli/auth/tests/test_gnutls.c +++ b/libcli/auth/tests/test_gnutls.c @@ -298,8 +298,10 @@ static void torture_gnutls_E_P24(void **state) }; uint8_t crypt[24]; + int rc; - E_P24(key, c8, crypt); + rc = E_P24(key, c8, crypt); + assert_int_equal(rc, 0); assert_memory_equal(crypt, crypt_expected, 24); } @@ -319,8 +321,10 @@ static void torture_gnutls_SMBOWFencrypt(void **state) }; uint8_t crypt[24]; + int rc; - SMBOWFencrypt(password, c8, crypt); + rc = SMBOWFencrypt(password, c8, crypt); + assert_int_equal(rc, 0); assert_memory_equal(crypt, crypt_expected, 24); } diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index d0be7e6c576..546a2d347e4 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -207,6 +207,7 @@ bool make_user_info_netlogon_interactive(TALLOC_CTX *mem_ctx, struct samr_Password nt_pwd; unsigned char local_lm_response[24]; unsigned char local_nt_response[24]; + int rc; if (lm_interactive_pwd) memcpy(lm_pwd.hash, lm_interactive_pwd, sizeof(lm_pwd.hash)); @@ -214,13 +215,21 @@ bool make_user_info_netlogon_interactive(TALLOC_CTX *mem_ctx, if (nt_interactive_pwd) memcpy(nt_pwd.hash, nt_interactive_pwd, sizeof(nt_pwd.hash)); - if (lm_interactive_pwd) - SMBOWFencrypt(lm_pwd.hash, chal, - local_lm_response); + if (lm_interactive_pwd) { + rc = SMBOWFencrypt(lm_pwd.hash, chal, + local_lm_response); + if (rc != 0) { + return false; + } + } - if (nt_interactive_pwd) - SMBOWFencrypt(nt_pwd.hash, chal, + if (nt_interactive_pwd) { + rc = SMBOWFencrypt(nt_pwd.hash, chal, local_nt_response); + if (rc != 0) { + return false; + } + } { bool ret; diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c index ea9cb757048..175f83d6750 100644 --- a/source3/rpc_client/cli_netlogon.c +++ b/source3/rpc_client/cli_netlogon.c @@ -37,6 +37,7 @@ #include "dbwrap/dbwrap.h" #include "dbwrap/dbwrap_open.h" #include "util_tdb.h" +#include "lib/crypto/gnutls_helpers.h" NTSTATUS rpccli_pre_open_netlogon_creds(void) @@ -528,6 +529,7 @@ NTSTATUS rpccli_netlogon_password_logon( case NetlogonNetworkTransitiveInformation: { struct netr_NetworkInfo *network_info; uint8_t chal[8]; + int rc; ZERO_STRUCT(lm); ZERO_STRUCT(nt); @@ -541,7 +543,11 @@ NTSTATUS rpccli_netlogon_password_logon( generate_random_buffer(chal, 8); SMBencrypt(password, chal, local_lm_response); - SMBNTencrypt(password, chal, local_nt_response); + rc = SMBNTencrypt(password, chal, local_nt_response); + if (rc != 0) { + TALLOC_FREE(frame); + return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); + } lm.length = 24; lm.data = local_lm_response; diff --git a/source3/torture/pdbtest.c b/source3/torture/pdbtest.c index fdf72187b6c..5d74aa9ab78 100644 --- a/source3/torture/pdbtest.c +++ b/source3/torture/pdbtest.c @@ -278,9 +278,14 @@ static bool test_auth(TALLOC_CTX *mem_ctx, struct samu *pdb_entry) NTSTATUS status; bool ok; uint8_t authoritative = 0; + int rc; + + rc = SMBOWFencrypt(pdb_get_nt_passwd(pdb_entry), challenge_8, + local_nt_response); + if (rc != 0) { + return False; + } - SMBOWFencrypt(pdb_get_nt_passwd(pdb_entry), challenge_8, - local_nt_response); SMBsesskeygen_ntv1(pdb_get_nt_passwd(pdb_entry), local_nt_session_key); if (tsocket_address_inet_from_strings(NULL, "ip", NULL, 0, &remote_address) != 0) { diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c index 8946dd70f99..b456a3994f8 100644 --- a/source3/winbindd/winbindd_pam.c +++ b/source3/winbindd/winbindd_pam.c @@ -47,6 +47,7 @@ #include "libads/krb5_errs.h" #include "param/param.h" #include "messaging/messaging.h" +#include "lib/crypto/gnutls_helpers.h" #include "lib/crypto/gnutls_helpers.h" #include @@ -1792,8 +1793,14 @@ static NTSTATUS winbindd_dual_pam_auth_samlogon( } data_blob_free(&names_blob); } else { + int rc; lm_resp = data_blob_null; - SMBNTencrypt(pass, chal, local_nt_response); + rc = SMBNTencrypt(pass, chal, local_nt_response); + if (rc != 0) { + DEBUG(0, ("winbindd_pam_auth: SMBNTencrypt() failed!\n")); + result = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); + goto done; + } nt_resp = data_blob_talloc(mem_ctx, local_nt_response, sizeof(local_nt_response)); diff --git a/source4/auth/ntlm/auth_util.c b/source4/auth/ntlm/auth_util.c index 7e72cb5123d..a0d061dca2a 100644 --- a/source4/auth/ntlm/auth_util.c +++ b/source4/auth/ntlm/auth_util.c @@ -28,6 +28,7 @@ #include "auth/ntlm/auth_proto.h" #include "librpc/gen_ndr/drsuapi.h" #include "dsdb/samdb/samdb.h" +#include "lib/crypto/gnutls_helpers.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_AUTH @@ -41,6 +42,7 @@ NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth4_context *auth_conte const struct auth_usersupplied_info *user_info_in, const struct auth_usersupplied_info **user_info_encrypted) { + int rc; NTSTATUS nt_status; struct auth_usersupplied_info *user_info_temp; switch (to_state) { @@ -103,12 +105,17 @@ NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth4_context *auth_conte data_blob_free(&ntlmv2_session_key); } else { DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, 24); - SMBOWFencrypt(user_info_in->password.hash.nt->hash, chal, blob.data); - + rc = SMBOWFencrypt(user_info_in->password.hash.nt->hash, chal, blob.data); + if (rc != 0) { + return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); + } user_info_temp->password.response.nt = blob; if (lpcfg_client_lanman_auth(auth_context->lp_ctx) && user_info_in->password.hash.lanman) { DATA_BLOB lm_blob = data_blob_talloc(mem_ctx, NULL, 24); - SMBOWFencrypt(user_info_in->password.hash.lanman->hash, chal, blob.data); + rc = SMBOWFencrypt(user_info_in->password.hash.lanman->hash, chal, blob.data); + if (rc != 0) { + return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); + } user_info_temp->password.response.lanman = lm_blob; } else { /* if not sending the LM password, send the NT password twice */ diff --git a/source4/torture/rpc/samsync.c b/source4/torture/rpc/samsync.c index 869d3ba96b6..6b9759b88fd 100644 --- a/source4/torture/rpc/samsync.c +++ b/source4/torture/rpc/samsync.c @@ -36,6 +36,7 @@ #include "librpc/gen_ndr/ndr_samr_c.h" #include "librpc/gen_ndr/ndr_security.h" #include "param/param.h" +#include "lib/crypto/gnutls_helpers.h" #define TEST_MACHINE_NAME "samsynctest" #define TEST_WKSTA_MACHINE_NAME "samsynctest2" @@ -61,6 +62,7 @@ static NTSTATUS test_SamLogon(struct torture_context *tctx, union netr_Validation validation; uint8_t authoritative; struct dcerpc_binding_handle *b = p->binding_handle; + int rc; ninfo.identity_info.domain_name.string = domain; ninfo.identity_info.parameter_control = 0; @@ -72,7 +74,11 @@ static NTSTATUS test_SamLogon(struct torture_context *tctx, if (nt_hash) { ninfo.nt.length = 24; ninfo.nt.data = talloc_array(mem_ctx, uint8_t, 24); - SMBOWFencrypt(nt_hash->hash, ninfo.challenge, ninfo.nt.data); + rc = SMBOWFencrypt(nt_hash->hash, ninfo.challenge, + ninfo.nt.data); + if (rc != 0) { + return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); + } } else { ninfo.nt.length = 0; ninfo.nt.data = NULL; @@ -81,7 +87,11 @@ static NTSTATUS test_SamLogon(struct torture_context *tctx, if (lm_hash) { ninfo.lm.length = 24; ninfo.lm.data = talloc_array(mem_ctx, uint8_t, 24); - SMBOWFencrypt(lm_hash->hash, ninfo.challenge, ninfo.lm.data); + rc = SMBOWFencrypt(lm_hash->hash, ninfo.challenge, + ninfo.lm.data); + if (rc != 0) { + return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); + } } else { ninfo.lm.length = 0; ninfo.lm.data = NULL; -- 2.23.0