diff --git a/.gitignore b/.gitignore index 99161ff..a0f2568 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ SOURCES/gpgkey-52FBC0B86D954B0843324CDC6F33915B6568B7EA.gpg -SOURCES/samba-4.10.4.tar.xz +SOURCES/samba-4.11.2.tar.xz diff --git a/.samba.metadata b/.samba.metadata index 1e4e8c9..791c4ac 100644 --- a/.samba.metadata +++ b/.samba.metadata @@ -1,2 +1,2 @@ 6bf33724c18b74427453f0e3fc0180f84ff60818 SOURCES/gpgkey-52FBC0B86D954B0843324CDC6F33915B6568B7EA.gpg -c24e15add96d79950552f0ffbb44234e4142342c SOURCES/samba-4.10.4.tar.xz +e920c3d96119b51c1d12a2428e8830000b331fe5 SOURCES/samba-4.11.2.tar.xz diff --git a/SOURCES/0001-s3-profile-Use-SHA1-for-hashing-in-profiling-functio.patch b/SOURCES/0001-s3-profile-Use-SHA1-for-hashing-in-profiling-functio.patch new file mode 100644 index 0000000..c0139ce --- /dev/null +++ b/SOURCES/0001-s3-profile-Use-SHA1-for-hashing-in-profiling-functio.patch @@ -0,0 +1,61 @@ +From 826e500242004b269219ad3deeacf0e01d136933 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Mon, 1 Jul 2019 16:54:15 +0200 +Subject: [PATCH 001/187] s3:profile: Use SHA1 for hashing in profiling + functions. + +This can use SHA NI instructions if the CPU supports it. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Ralph Boehme +(cherry picked from commit 6fe2193b17ac2d57c559d3b936b37238d06d6be8) +--- + source3/profile/profile.c | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +diff --git a/source3/profile/profile.c b/source3/profile/profile.c +index df0ba5b0af3..90a30f01f58 100644 +--- a/source3/profile/profile.c ++++ b/source3/profile/profile.c +@@ -124,7 +124,7 @@ static void reqprofile_message(struct messaging_context *msg_ctx, + ******************************************************************/ + bool profile_setup(struct messaging_context *msg_ctx, bool rdonly) + { +- unsigned char tmp[16] = {}; ++ uint8_t digest[gnutls_hash_get_len(GNUTLS_DIG_SHA1)]; + gnutls_hash_hd_t hash_hnd = NULL; + char *db_name; + bool ok = false; +@@ -154,7 +154,7 @@ bool profile_setup(struct messaging_context *msg_ctx, bool rdonly) + reqprofile_message); + } + +- rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5); ++ rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_SHA1); + if (rc < 0) { + goto out; + } +@@ -210,15 +210,14 @@ bool profile_setup(struct messaging_context *msg_ctx, bool rdonly) + goto out; + } + +- gnutls_hash_deinit(hash_hnd, tmp); ++ gnutls_hash_deinit(hash_hnd, digest); + + profile_p = &smbprofile_state.stats.global; + +- profile_p->magic = BVAL(tmp, 0); ++ profile_p->magic = BVAL(digest, 0); + if (profile_p->magic == 0) { +- profile_p->magic = BVAL(tmp, 8); ++ profile_p->magic = BVAL(digest, 8); + } +- ZERO_ARRAY(tmp); + + ok = true; + out: +-- +2.23.0 + diff --git a/SOURCES/0002-lib-crypto-Fix-path-to-header-file-in-gnutls_helpers.patch b/SOURCES/0002-lib-crypto-Fix-path-to-header-file-in-gnutls_helpers.patch new file mode 100644 index 0000000..7c82b01 --- /dev/null +++ b/SOURCES/0002-lib-crypto-Fix-path-to-header-file-in-gnutls_helpers.patch @@ -0,0 +1,33 @@ +From bb29683ddc7cdacfe9129074652d97a11a9084af Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Fri, 5 Jul 2019 16:28:27 +0200 +Subject: [PATCH 002/187] lib:crypto: Fix path to header file in + gnutls_helpers.h + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Ralph Boehme +(cherry picked from commit a31a40b41a18ae09a4e2e76f41c95b011ed30bea) +--- + lib/crypto/gnutls_helpers.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/lib/crypto/gnutls_helpers.h b/lib/crypto/gnutls_helpers.h +index b8288c25649..7c950c79525 100644 +--- a/lib/crypto/gnutls_helpers.h ++++ b/lib/crypto/gnutls_helpers.h +@@ -18,8 +18,8 @@ + #ifndef _GNUTLS_HELPERS_H + #define _GNUTLS_HELPERS_H + +-#include "ntstatus.h" +-#include "werror.h" ++#include "libcli/util/ntstatus.h" ++#include "libcli/util/werror.h" + + NTSTATUS _gnutls_error_to_ntstatus(int gnutls_rc, + NTSTATUS blocked_status, +-- +2.23.0 + diff --git a/SOURCES/0003-lib-crypto-Add-GNUTLS_FIPS140_SET_-LAX-STRICT-_MODE-.patch b/SOURCES/0003-lib-crypto-Add-GNUTLS_FIPS140_SET_-LAX-STRICT-_MODE-.patch new file mode 100644 index 0000000..9e58569 --- /dev/null +++ b/SOURCES/0003-lib-crypto-Add-GNUTLS_FIPS140_SET_-LAX-STRICT-_MODE-.patch @@ -0,0 +1,65 @@ +From bd6da0ff651385f14f8414ecb440e228d5a8a7d1 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Fri, 5 Jul 2019 10:38:44 +0200 +Subject: [PATCH 003/187] lib:crypto: Add GNUTLS_FIPS140_SET_(LAX|STRICT)_MODE + to helpers + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Ralph Boehme +(cherry picked from commit 31a943fa0890438cffc67a566373f36c94c0a5a8) +--- + lib/crypto/gnutls_helpers.h | 11 +++++++++++ + source3/modules/hash_inode.c | 10 +--------- + 2 files changed, 12 insertions(+), 9 deletions(-) + +diff --git a/lib/crypto/gnutls_helpers.h b/lib/crypto/gnutls_helpers.h +index 7c950c79525..8a2a49baf73 100644 +--- a/lib/crypto/gnutls_helpers.h ++++ b/lib/crypto/gnutls_helpers.h +@@ -18,9 +18,20 @@ + #ifndef _GNUTLS_HELPERS_H + #define _GNUTLS_HELPERS_H + ++#include ++ + #include "libcli/util/ntstatus.h" + #include "libcli/util/werror.h" + ++/* Those macros are only available in GnuTLS >= 3.6.4 */ ++#ifndef GNUTLS_FIPS140_SET_LAX_MODE ++#define GNUTLS_FIPS140_SET_LAX_MODE() ++#endif ++ ++#ifndef GNUTLS_FIPS140_SET_STRICT_MODE ++#define GNUTLS_FIPS140_SET_STRICT_MODE() ++#endif ++ + NTSTATUS _gnutls_error_to_ntstatus(int gnutls_rc, + NTSTATUS blocked_status, + const char *function, +diff --git a/source3/modules/hash_inode.c b/source3/modules/hash_inode.c +index 231538c72cb..a9144621901 100644 +--- a/source3/modules/hash_inode.c ++++ b/source3/modules/hash_inode.c +@@ -22,15 +22,7 @@ + + #include + #include +- +-/* Those macros are only available in GnuTLS >= 3.6.4 */ +-#ifndef GNUTLS_FIPS140_SET_LAX_MODE +-#define GNUTLS_FIPS140_SET_LAX_MODE() +-#endif +- +-#ifndef GNUTLS_FIPS140_SET_STRICT_MODE +-#define GNUTLS_FIPS140_SET_STRICT_MODE() +-#endif ++#include "lib/crypto/gnutls_helpers.h" + + SMB_INO_T hash_inode(const SMB_STRUCT_STAT *sbuf, const char *sname) + { +-- +2.23.0 + diff --git a/SOURCES/0004-s3-profile-Allow-profile-subsystem-to-use-SHA1-in-FI.patch b/SOURCES/0004-s3-profile-Allow-profile-subsystem-to-use-SHA1-in-FI.patch new file mode 100644 index 0000000..853541d --- /dev/null +++ b/SOURCES/0004-s3-profile-Allow-profile-subsystem-to-use-SHA1-in-FI.patch @@ -0,0 +1,63 @@ +From 4728c82b9a9d857bac4cf04434856daa8d739995 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 15 May 2019 08:41:12 +0200 +Subject: [PATCH 004/187] s3:profile: Allow profile subsystem to use SHA1 in + FIPS mode + +This is non-cryptographic use. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Ralph Boehme + +Autobuild-User(master): Andreas Schneider +Autobuild-Date(master): Tue Jul 9 13:31:46 UTC 2019 on sn-devel-184 + +(cherry picked from commit ccf3e76625c42f5aceea0882971a232a9f56a971) +--- + source3/profile/profile.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/source3/profile/profile.c b/source3/profile/profile.c +index 90a30f01f58..7e17d065d75 100644 +--- a/source3/profile/profile.c ++++ b/source3/profile/profile.c +@@ -35,6 +35,7 @@ + + #include + #include ++#include "lib/crypto/gnutls_helpers.h" + + struct profile_stats *profile_p; + struct smbprofile_global_state smbprofile_state; +@@ -154,6 +155,8 @@ bool profile_setup(struct messaging_context *msg_ctx, bool rdonly) + reqprofile_message); + } + ++ GNUTLS_FIPS140_SET_LAX_MODE(); ++ + rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_SHA1); + if (rc < 0) { + goto out; +@@ -212,6 +215,8 @@ bool profile_setup(struct messaging_context *msg_ctx, bool rdonly) + + gnutls_hash_deinit(hash_hnd, digest); + ++ GNUTLS_FIPS140_SET_STRICT_MODE(); ++ + profile_p = &smbprofile_state.stats.global; + + profile_p->magic = BVAL(digest, 0); +@@ -221,6 +226,8 @@ bool profile_setup(struct messaging_context *msg_ctx, bool rdonly) + + ok = true; + out: ++ GNUTLS_FIPS140_SET_STRICT_MODE(); ++ + return ok; + } + +-- +2.23.0 + diff --git a/SOURCES/0005-lib-util-Use-GnuTLS-random-number-generator-in-genra.patch b/SOURCES/0005-lib-util-Use-GnuTLS-random-number-generator-in-genra.patch new file mode 100644 index 0000000..b939f95 --- /dev/null +++ b/SOURCES/0005-lib-util-Use-GnuTLS-random-number-generator-in-genra.patch @@ -0,0 +1,114 @@ +From 290c078652ffcacd69b0b00ea5e5413515c5de22 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Mon, 18 Mar 2019 17:03:30 +0100 +Subject: [PATCH 005/187] lib:util: Use GnuTLS random number generator in + genrand.c + +FIPS requires that a random number generator from a certified crypto +library is used. + +Signed-off-by: Andreas Schneider +Reviewed-by: Jeremy Allison + +Autobuild-User(master): Jeremy Allison +Autobuild-Date(master): Thu Jul 18 01:30:20 UTC 2019 on sn-devel-184 + +(cherry picked from commit 664eed2e926f8f572b81e6d7c8e09b7ccbafb908) +--- + lib/util/genrand.c | 31 +++++++------------------------ + lib/util/genrand.h | 11 ++++------- + lib/util/wscript_build | 2 +- + 3 files changed, 12 insertions(+), 32 deletions(-) + +diff --git a/lib/util/genrand.c b/lib/util/genrand.c +index a775535c49e..55997c3dd55 100644 +--- a/lib/util/genrand.c ++++ b/lib/util/genrand.c +@@ -20,35 +20,17 @@ + */ + + #include "replace.h" +-#include "system/filesys.h" + #include "lib/util/genrand.h" +-#include "sys_rw_data.h" +-#include "lib/util/blocking.h" + +-static int urand_fd = -1; ++#include ++#include + +-static void open_urandom(void) +-{ +- if (urand_fd != -1) { +- return; +- } +- urand_fd = open( "/dev/urandom", O_RDONLY,0); +- if (urand_fd == -1) { +- abort(); +- } +- smb_set_close_on_exec(urand_fd); +-} ++/* TODO: Add API for generating nonce or use gnutls_rnd directly everywhere. */ + + _PUBLIC_ void generate_random_buffer(uint8_t *out, int len) + { +- ssize_t rw_ret; +- +- open_urandom(); +- +- rw_ret = read_data(urand_fd, out, len); +- if (rw_ret != len) { +- abort(); +- } ++ /* Thread and fork safe random number generator for temporary keys. */ ++ gnutls_rnd(GNUTLS_RND_RANDOM, out, len); + } + + /* +@@ -57,5 +39,6 @@ _PUBLIC_ void generate_random_buffer(uint8_t *out, int len) + */ + _PUBLIC_ void generate_secret_buffer(uint8_t *out, int len) + { +- generate_random_buffer(out, len); ++ /* Thread and fork safe random number generator for long term keys. */ ++ gnutls_rnd(GNUTLS_RND_KEY, out, len); + } +diff --git a/lib/util/genrand.h b/lib/util/genrand.h +index ef6bbc64157..899ce8badc0 100644 +--- a/lib/util/genrand.h ++++ b/lib/util/genrand.h +@@ -20,14 +20,11 @@ + */ + + /** +- Interface to the (hopefully) good crypto random number generator. +- Will use our internal PRNG if more than 40 bytes of random generation +- has been requested, otherwise tries to read from /dev/random +-**/ ++ * Thread and fork safe random number generator for temporary keys. ++ */ + void generate_random_buffer(uint8_t *out, int len); + + /** +- Interface to the (hopefully) good crypto random number generator. +- Will always use /dev/urandom if available. +-**/ ++ * Thread and fork safe random number generator for long term keys. ++ */ + void generate_secret_buffer(uint8_t *out, int len); +diff --git a/lib/util/wscript_build b/lib/util/wscript_build +index ff1c76e3686..5f005c41e49 100644 +--- a/lib/util/wscript_build ++++ b/lib/util/wscript_build +@@ -104,7 +104,7 @@ else: + + bld.SAMBA_LIBRARY('genrand', + source='genrand.c', +- deps='replace socket-blocking sys_rw', ++ deps='replace gnutls', + local_include=False, + private_library=True) + +-- +2.23.0 + diff --git a/SOURCES/0006-lib-crypto-Document-gnutls_error_to_werror.patch b/SOURCES/0006-lib-crypto-Document-gnutls_error_to_werror.patch new file mode 100644 index 0000000..c26f699 --- /dev/null +++ b/SOURCES/0006-lib-crypto-Document-gnutls_error_to_werror.patch @@ -0,0 +1,49 @@ +From 8391caf4f4aa8fed5167b5e5cf04197a29ba40e8 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Thu, 18 Jul 2019 13:27:57 +0200 +Subject: [PATCH 006/187] lib:crypto: Document gnutls_error_to_werror() + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit e43678b84a3434b977f44b265599f1d9207d3b78) +--- + lib/crypto/gnutls_helpers.h | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/lib/crypto/gnutls_helpers.h b/lib/crypto/gnutls_helpers.h +index 8a2a49baf73..debaa701554 100644 +--- a/lib/crypto/gnutls_helpers.h ++++ b/lib/crypto/gnutls_helpers.h +@@ -40,6 +40,21 @@ NTSTATUS _gnutls_error_to_ntstatus(int gnutls_rc, + _gnutls_error_to_ntstatus(gnutls_rc, blocked_status, \ + __FUNCTION__, __location__) + ++#ifdef DOXYGEN ++/** ++ * @brief Convert a gnutls error code to a corresponding WERROR. ++ * ++ * @param[in] gnutls_rc The GnuTLS return code. ++ * ++ * @param[in] blocked_werr The WERROR code which should be returned if e.g ++ * the cipher we want to used it not allowed to be ++ * used because of FIPS mode. ++ * ++ * @return A corresponding WERROR code. ++ */ ++WERROR gnutls_error_to_werror(int gnutls_rc, ++ WERROR blocked_werr); ++#else + WERROR _gnutls_error_to_werror(int gnutls_rc, + WERROR blocked_werr, + const char *function, +@@ -47,6 +62,7 @@ WERROR _gnutls_error_to_werror(int gnutls_rc, + #define gnutls_error_to_werror(gnutls_rc, blocked_werr) \ + _gnutls_error_to_werror(gnutls_rc, blocked_werr, \ + __FUNCTION__, __location__) ++#endif + + enum samba_gnutls_direction { + SAMBA_GNUTLS_ENCRYPT, +-- +2.23.0 + diff --git a/SOURCES/0007-lib-crypto-Document-samba_gnutls_arcfour_confounded_.patch b/SOURCES/0007-lib-crypto-Document-samba_gnutls_arcfour_confounded_.patch new file mode 100644 index 0000000..297b242 --- /dev/null +++ b/SOURCES/0007-lib-crypto-Document-samba_gnutls_arcfour_confounded_.patch @@ -0,0 +1,45 @@ +From 47f922c797006a3158fa3e077a7086086917b5e4 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Thu, 18 Jul 2019 13:33:54 +0200 +Subject: [PATCH 007/187] lib:crypto: Document + samba_gnutls_arcfour_confounded_md5() + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit baa96ef20945638fb5ee76b03543c7b611e9c7d7) +--- + lib/crypto/gnutls_helpers.h | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/lib/crypto/gnutls_helpers.h b/lib/crypto/gnutls_helpers.h +index debaa701554..d6000c7b316 100644 +--- a/lib/crypto/gnutls_helpers.h ++++ b/lib/crypto/gnutls_helpers.h +@@ -69,6 +69,24 @@ enum samba_gnutls_direction { + SAMBA_GNUTLS_DECRYPT + }; + ++/** ++ * @brief Encrypt or decrypt a data blob using RC4 with a key and salt. ++ * ++ * One of the key input should be a session key and the other a confounder ++ * (aka salt). Which one depends on the implementation details of the ++ * protocol. ++ * ++ * @param[in] key_input1 Either a session_key or a confounder. ++ * ++ * @param[in] key_input2 Either a session_key or a confounder. ++ * ++ * @param[in] data The data blob ot either encrypt or decrypt. The data ++ * will be encrypted or decrypted in place. ++ * ++ * @param[in] encrypt The encryption direction. ++ * ++ * @return A gnutls error code. ++ */ + int samba_gnutls_arcfour_confounded_md5(const DATA_BLOB *key_input1, + const DATA_BLOB *key_input2, + DATA_BLOB *data, +-- +2.23.0 + diff --git a/SOURCES/0008-s3-rpc_client-Return-NTSTATUS-for-init_samr_CryptPas.patch b/SOURCES/0008-s3-rpc_client-Return-NTSTATUS-for-init_samr_CryptPas.patch new file mode 100644 index 0000000..d3f8436 --- /dev/null +++ b/SOURCES/0008-s3-rpc_client-Return-NTSTATUS-for-init_samr_CryptPas.patch @@ -0,0 +1,150 @@ +From bcbc9eca11583426d9b0e7ce4d4e51b16bda32f0 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 29 May 2019 16:22:11 +0200 +Subject: [PATCH 008/187] s3:rpc_client: Return NTSTATUS for + init_samr_CryptPassword() + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 4b9b1dbe9c8c988a39b1318a4f7aac031bc1ea8b) +--- + source3/lib/netapi/user.c | 9 ++++++--- + source3/libnet/libnet_join.c | 10 +++++++--- + source3/rpc_client/init_samr.c | 14 ++++++++++---- + source3/rpc_client/init_samr.h | 6 +++--- + source3/rpcclient/cmd_samr.c | 5 ++++- + source3/utils/net_rpc.c | 9 ++++++--- + 6 files changed, 36 insertions(+), 17 deletions(-) + +diff --git a/source3/lib/netapi/user.c b/source3/lib/netapi/user.c +index 4b66dab2f99..2136ef47ee6 100644 +--- a/source3/lib/netapi/user.c ++++ b/source3/lib/netapi/user.c +@@ -326,9 +326,12 @@ static NTSTATUS set_user_info_USER_INFO_X(TALLOC_CTX *ctx, + + user_info.info23.info = info21; + +- init_samr_CryptPassword(uX->usriX_password, +- session_key, +- &user_info.info23.password); ++ status = init_samr_CryptPassword(uX->usriX_password, ++ session_key, ++ &user_info.info23.password); ++ if (!NT_STATUS_IS_OK(status)) { ++ return status; ++ } + + status = dcerpc_samr_SetUserInfo2(b, talloc_tos(), + user_handle, +diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c +index 9d4f656ffec..abf8672d050 100644 +--- a/source3/libnet/libnet_join.c ++++ b/source3/libnet/libnet_join.c +@@ -1570,9 +1570,12 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx, + + /* retry with level 24 */ + +- init_samr_CryptPassword(r->in.machine_password, +- &session_key, +- &crypt_pwd); ++ status = init_samr_CryptPassword(r->in.machine_password, ++ &session_key, ++ &crypt_pwd); ++ if (!NT_STATUS_IS_OK(status)) { ++ goto error; ++ } + + user_info.info24.password = crypt_pwd; + user_info.info24.password_expired = PASS_DONT_CHANGE_AT_NEXT_LOGON; +@@ -1584,6 +1587,7 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx, + &result); + } + ++error: + old_timeout = rpccli_set_timeout(pipe_hnd, old_timeout); + + if (!NT_STATUS_IS_OK(status)) { +diff --git a/source3/rpc_client/init_samr.c b/source3/rpc_client/init_samr.c +index d116ece576f..8b41ec2f10f 100644 +--- a/source3/rpc_client/init_samr.c ++++ b/source3/rpc_client/init_samr.c +@@ -81,12 +81,18 @@ out: + inits a samr_CryptPassword structure + *************************************************************************/ + +-void init_samr_CryptPassword(const char *pwd, +- DATA_BLOB *session_key, +- struct samr_CryptPassword *pwd_buf) ++NTSTATUS init_samr_CryptPassword(const char *pwd, ++ DATA_BLOB *session_key, ++ struct samr_CryptPassword *pwd_buf) + { + /* samr_CryptPassword */ ++ bool ok; + +- encode_pw_buffer(pwd_buf->data, pwd, STR_UNICODE); ++ ok = encode_pw_buffer(pwd_buf->data, pwd, STR_UNICODE); ++ if (!ok) { ++ return NT_STATUS_INTERNAL_ERROR; ++ } + arcfour_crypt_blob(pwd_buf->data, 516, session_key); ++ ++ return NT_STATUS_OK; + } +diff --git a/source3/rpc_client/init_samr.h b/source3/rpc_client/init_samr.h +index 223fa91e3d9..4214ab55a04 100644 +--- a/source3/rpc_client/init_samr.h ++++ b/source3/rpc_client/init_samr.h +@@ -25,8 +25,8 @@ + void init_samr_CryptPasswordEx(const char *pwd, + DATA_BLOB *session_key, + struct samr_CryptPasswordEx *pwd_buf); +-void init_samr_CryptPassword(const char *pwd, +- DATA_BLOB *session_key, +- struct samr_CryptPassword *pwd_buf); ++NTSTATUS init_samr_CryptPassword(const char *pwd, ++ DATA_BLOB *session_key, ++ struct samr_CryptPassword *pwd_buf); + + #endif /* _RPC_CLIENT_INIT_SAMR_H_ */ +diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c +index 8cbf8ab24bd..ccaec1ada40 100644 +--- a/source3/rpcclient/cmd_samr.c ++++ b/source3/rpcclient/cmd_samr.c +@@ -3063,7 +3063,10 @@ static NTSTATUS cmd_samr_setuserinfo_int(struct rpc_pipe_client *cli, + return status; + } + +- init_samr_CryptPassword(param, &session_key, &pwd_buf); ++ status = init_samr_CryptPassword(param, &session_key, &pwd_buf); ++ if (!NT_STATUS_IS_OK(status)) { ++ return status; ++ } + init_samr_CryptPasswordEx(param, &session_key, &pwd_buf_ex); + nt_lm_owf_gen(param, nt_hash, lm_hash); + +diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c +index a56190f7be5..f6fb892a2d9 100644 +--- a/source3/utils/net_rpc.c ++++ b/source3/utils/net_rpc.c +@@ -6195,9 +6195,12 @@ static NTSTATUS rpc_trustdom_add_internals(struct net_context *c, + + ZERO_STRUCT(info.info23); + +- init_samr_CryptPassword(argv[1], +- &session_key, +- &crypt_pwd); ++ status = init_samr_CryptPassword(argv[1], ++ &session_key, ++ &crypt_pwd); ++ if (!NT_STATUS_IS_OK(status)) { ++ goto done; ++ } + + info.info23.info.fields_present = SAMR_FIELD_ACCT_FLAGS | + SAMR_FIELD_NT_PASSWORD_PRESENT; +-- +2.23.0 + diff --git a/SOURCES/0009-s3-rpc_client-Return-NTSTATUS-for-init_samr_CryptPas.patch b/SOURCES/0009-s3-rpc_client-Return-NTSTATUS-for-init_samr_CryptPas.patch new file mode 100644 index 0000000..81ce920 --- /dev/null +++ b/SOURCES/0009-s3-rpc_client-Return-NTSTATUS-for-init_samr_CryptPas.patch @@ -0,0 +1,199 @@ +From 97f9ec9431ebf22ae06f61c97c183e04b59d6e7f Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 29 May 2019 17:16:26 +0200 +Subject: [PATCH 009/187] s3:rpc_client: Return NTSTATUS for + init_samr_CryptPasswordEx() + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 7915a48e53c8f72ba56da2f433427b961feeb16f) +--- + source3/lib/netapi/user.c | 9 ++++--- + source3/libnet/libnet_join.c | 9 ++++--- + source3/rpc_client/init_samr.c | 27 +++++++++++++++------ + source3/rpc_client/init_samr.h | 6 ++--- + source3/rpc_server/netlogon/srv_netlog_nt.c | 9 ++++--- + source3/rpcclient/cmd_samr.c | 5 +++- + 6 files changed, 44 insertions(+), 21 deletions(-) + +diff --git a/source3/lib/netapi/user.c b/source3/lib/netapi/user.c +index 2136ef47ee6..827b7902040 100644 +--- a/source3/lib/netapi/user.c ++++ b/source3/lib/netapi/user.c +@@ -313,9 +313,12 @@ static NTSTATUS set_user_info_USER_INFO_X(TALLOC_CTX *ctx, + + user_info.info25.info = info21; + +- init_samr_CryptPasswordEx(uX->usriX_password, +- session_key, +- &user_info.info25.password); ++ status = init_samr_CryptPasswordEx(uX->usriX_password, ++ session_key, ++ &user_info.info25.password); ++ if (!NT_STATUS_IS_OK(status)) { ++ return status; ++ } + + status = dcerpc_samr_SetUserInfo2(b, talloc_tos(), + user_handle, +diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c +index abf8672d050..eb8e0ea17f7 100644 +--- a/source3/libnet/libnet_join.c ++++ b/source3/libnet/libnet_join.c +@@ -1553,9 +1553,12 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx, + */ + old_timeout = rpccli_set_timeout(pipe_hnd, 600000); + +- init_samr_CryptPasswordEx(r->in.machine_password, +- &session_key, +- &crypt_pwd_ex); ++ status = init_samr_CryptPasswordEx(r->in.machine_password, ++ &session_key, ++ &crypt_pwd_ex); ++ if (!NT_STATUS_IS_OK(status)) { ++ goto error; ++ } + + user_info.info26.password = crypt_pwd_ex; + user_info.info26.password_expired = PASS_DONT_CHANGE_AT_NEXT_LOGON; +diff --git a/source3/rpc_client/init_samr.c b/source3/rpc_client/init_samr.c +index 8b41ec2f10f..5f6cbc5d3c7 100644 +--- a/source3/rpc_client/init_samr.c ++++ b/source3/rpc_client/init_samr.c +@@ -22,6 +22,7 @@ + #include "../lib/crypto/arcfour.h" + #include "rpc_client/init_samr.h" + ++#include "lib/crypto/gnutls_helpers.h" + #include + #include + +@@ -29,9 +30,9 @@ + inits a samr_CryptPasswordEx structure + *************************************************************************/ + +-void init_samr_CryptPasswordEx(const char *pwd, +- DATA_BLOB *session_key, +- struct samr_CryptPasswordEx *pwd_buf) ++NTSTATUS init_samr_CryptPasswordEx(const char *pwd, ++ DATA_BLOB *session_key, ++ struct samr_CryptPasswordEx *pwd_buf) + { + /* samr_CryptPasswordEx */ + +@@ -39,42 +40,52 @@ void init_samr_CryptPasswordEx(const char *pwd, + gnutls_hash_hd_t hash_hnd = NULL; + uint8_t confounder[16]; + DATA_BLOB confounded_session_key = data_blob(NULL, 16); ++ NTSTATUS status; ++ bool ok; + int rc; + +- encode_pw_buffer(pwbuf, pwd, STR_UNICODE); ++ ok = encode_pw_buffer(pwbuf, pwd, STR_UNICODE); ++ if (!ok) { ++ status = NT_STATUS_INTERNAL_ERROR; ++ goto out; ++ } + + generate_random_buffer((uint8_t *)confounder, 16); + + rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5); + if (rc < 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED); + goto out; + } + + rc = gnutls_hash(hash_hnd, confounder, 16); + if (rc < 0) { + gnutls_hash_deinit(hash_hnd, NULL); ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED); + goto out; + } + rc = gnutls_hash(hash_hnd, session_key->data, session_key->length); + if (rc < 0) { + gnutls_hash_deinit(hash_hnd, NULL); ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED); + goto out; + } + + gnutls_hash_deinit(hash_hnd, confounded_session_key.data); + + arcfour_crypt_blob(pwbuf, 516, &confounded_session_key); +- ZERO_ARRAY_LEN(confounded_session_key.data, +- confounded_session_key.length); +- data_blob_free(&confounded_session_key); ++ data_blob_clear_free(&confounded_session_key); + + memcpy(&pwbuf[516], confounder, 16); + ZERO_ARRAY(confounder); + + memcpy(pwd_buf->data, pwbuf, sizeof(pwbuf)); + ZERO_ARRAY(pwbuf); ++ ++ status = NT_STATUS_OK; + out: +- return; ++ data_blob_clear_free(&confounded_session_key); ++ return status; + } + + /************************************************************************* +diff --git a/source3/rpc_client/init_samr.h b/source3/rpc_client/init_samr.h +index 4214ab55a04..3f0dc847dd2 100644 +--- a/source3/rpc_client/init_samr.h ++++ b/source3/rpc_client/init_samr.h +@@ -22,9 +22,9 @@ + + /* The following definitions come from rpc_client/init_samr.c */ + +-void init_samr_CryptPasswordEx(const char *pwd, +- DATA_BLOB *session_key, +- struct samr_CryptPasswordEx *pwd_buf); ++NTSTATUS init_samr_CryptPasswordEx(const char *pwd, ++ DATA_BLOB *session_key, ++ struct samr_CryptPasswordEx *pwd_buf); + NTSTATUS init_samr_CryptPassword(const char *pwd, + DATA_BLOB *session_key, + struct samr_CryptPassword *pwd_buf); +diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c +index c9aaa90cbb9..d5267bf7062 100644 +--- a/source3/rpc_server/netlogon/srv_netlog_nt.c ++++ b/source3/rpc_server/netlogon/srv_netlog_nt.c +@@ -1226,9 +1226,12 @@ static NTSTATUS netr_set_machine_account_password(TALLOC_CTX *mem_ctx, + + infolevel = UserInternal5InformationNew; + +- init_samr_CryptPasswordEx(cr->creds.password, +- &session_key, +- &info26.password); ++ status = init_samr_CryptPasswordEx(cr->creds.password, ++ &session_key, ++ &info26.password); ++ if (!NT_STATUS_IS_OK(status)) { ++ goto out; ++ } + + info26.password_expired = PASS_DONT_CHANGE_AT_NEXT_LOGON; + info->info26 = info26; +diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c +index ccaec1ada40..b1b7c06515c 100644 +--- a/source3/rpcclient/cmd_samr.c ++++ b/source3/rpcclient/cmd_samr.c +@@ -3067,7 +3067,10 @@ static NTSTATUS cmd_samr_setuserinfo_int(struct rpc_pipe_client *cli, + if (!NT_STATUS_IS_OK(status)) { + return status; + } +- init_samr_CryptPasswordEx(param, &session_key, &pwd_buf_ex); ++ status = init_samr_CryptPasswordEx(param, &session_key, &pwd_buf_ex); ++ if (!NT_STATUS_IS_OK(status)) { ++ return status; ++ } + nt_lm_owf_gen(param, nt_hash, lm_hash); + + switch (level) { +-- +2.23.0 + diff --git a/SOURCES/0010-libcli-auth-Return-NTSTATUS-for-encode_or_decode_arc.patch b/SOURCES/0010-libcli-auth-Return-NTSTATUS-for-encode_or_decode_arc.patch new file mode 100644 index 0000000..8f97449 --- /dev/null +++ b/SOURCES/0010-libcli-auth-Return-NTSTATUS-for-encode_or_decode_arc.patch @@ -0,0 +1,115 @@ +From 6125794925d054da191cf6c21a76ceb904848710 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 29 May 2019 14:57:52 +0200 +Subject: [PATCH 010/187] libcli:auth: Return NTSTATUS for + encode_or_decode_arc4_passwd_buffer() + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 57dd415ba49b9621deddf604a5bf148c10ebc37e) +--- + libcli/auth/proto.h | 3 ++- + libcli/auth/smbencrypt.c | 10 ++++++++-- + source3/rpc_server/samr/srv_samr_nt.c | 10 ++++++++-- + 3 files changed, 18 insertions(+), 5 deletions(-) + +diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h +index afd7f0d148d..651f1139cf5 100644 +--- a/libcli/auth/proto.h ++++ b/libcli/auth/proto.h +@@ -184,7 +184,8 @@ bool decode_pw_buffer(TALLOC_CTX *ctx, + /*********************************************************** + Decode an arc4 encrypted password change buffer. + ************************************************************/ +-void encode_or_decode_arc4_passwd_buffer(unsigned char pw_buf[532], const DATA_BLOB *psession_key); ++NTSTATUS encode_or_decode_arc4_passwd_buffer(unsigned char pw_buf[532], ++ const DATA_BLOB *psession_key); + + /*********************************************************** + encode a password buffer with an already unicode password. The +diff --git a/libcli/auth/smbencrypt.c b/libcli/auth/smbencrypt.c +index a74ccf09b02..ae97f3cc93e 100644 +--- a/libcli/auth/smbencrypt.c ++++ b/libcli/auth/smbencrypt.c +@@ -843,27 +843,32 @@ bool decode_pw_buffer(TALLOC_CTX *ctx, + Decode an arc4 encrypted password change buffer. + ************************************************************/ + +-void encode_or_decode_arc4_passwd_buffer(unsigned char pw_buf[532], const DATA_BLOB *psession_key) ++NTSTATUS encode_or_decode_arc4_passwd_buffer(unsigned char pw_buf[532], ++ const DATA_BLOB *psession_key) + { + gnutls_hash_hd_t hash_hnd = NULL; + unsigned char key_out[16]; ++ NTSTATUS status; + int rc; + + /* Confounder is last 16 bytes. */ + + rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5); + if (rc < 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED); + goto out; + } + + rc = gnutls_hash(hash_hnd, &pw_buf[516], 16); + if (rc < 0) { + gnutls_hash_deinit(hash_hnd, NULL); ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED); + goto out; + } + rc = gnutls_hash(hash_hnd, psession_key->data, psession_key->length); + if (rc < 0) { + gnutls_hash_deinit(hash_hnd, NULL); ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED); + goto out; + } + gnutls_hash_deinit(hash_hnd, key_out); +@@ -873,8 +878,9 @@ void encode_or_decode_arc4_passwd_buffer(unsigned char pw_buf[532], const DATA_B + + ZERO_ARRAY(key_out); + ++ status = NT_STATUS_OK; + out: +- return; ++ return status; + } + + /*********************************************************** +diff --git a/source3/rpc_server/samr/srv_samr_nt.c b/source3/rpc_server/samr/srv_samr_nt.c +index 124d6d38cd7..c2be8bfc19a 100644 +--- a/source3/rpc_server/samr/srv_samr_nt.c ++++ b/source3/rpc_server/samr/srv_samr_nt.c +@@ -5185,9 +5185,12 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p, + if(!NT_STATUS_IS_OK(status)) { + break; + } +- encode_or_decode_arc4_passwd_buffer( ++ status = encode_or_decode_arc4_passwd_buffer( + info->info25.password.data, + &session_key); ++ if (!NT_STATUS_IS_OK(status)) { ++ break; ++ } + + dump_data(100, info->info25.password.data, 532); + +@@ -5201,9 +5204,12 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p, + if(!NT_STATUS_IS_OK(status)) { + break; + } +- encode_or_decode_arc4_passwd_buffer( ++ status = encode_or_decode_arc4_passwd_buffer( + info->info26.password.data, + &session_key); ++ if (!NT_STATUS_IS_OK(status)) { ++ break; ++ } + + dump_data(100, info->info26.password.data, 516); + +-- +2.23.0 + diff --git a/SOURCES/0011-libcli-auth-Add-test-for-decoding-an-RC4-password-bu.patch b/SOURCES/0011-libcli-auth-Add-test-for-decoding-an-RC4-password-bu.patch new file mode 100644 index 0000000..6213705 --- /dev/null +++ b/SOURCES/0011-libcli-auth-Add-test-for-decoding-an-RC4-password-bu.patch @@ -0,0 +1,234 @@ +From f0d4f6ec31079506b01502f7b515245ace03227d Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Fri, 5 Jul 2019 09:39:02 +0200 +Subject: [PATCH 011/187] libcli:auth: Add test for decoding an RC4 password + buffer + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 7ccc76f951a626a25d553ac85c5bf30eb29ffa2b) +--- + libcli/auth/tests/test_rc4_passwd_buffer.c | 177 +++++++++++++++++++++ + libcli/auth/wscript_build | 9 ++ + selftest/tests.py | 2 + + 3 files changed, 188 insertions(+) + create mode 100644 libcli/auth/tests/test_rc4_passwd_buffer.c + +diff --git a/libcli/auth/tests/test_rc4_passwd_buffer.c b/libcli/auth/tests/test_rc4_passwd_buffer.c +new file mode 100644 +index 00000000000..f40ac3a5655 +--- /dev/null ++++ b/libcli/auth/tests/test_rc4_passwd_buffer.c +@@ -0,0 +1,177 @@ ++/* ++ * Unix SMB/CIFS implementation. ++ * ++ * Copyright (C) 2018-2019 Andreas Schneider ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "includes.h" ++#include "libcli/auth/libcli_auth.h" ++#include "rpc_client/init_samr.h" ++ ++#define PASSWORD "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" ++ ++static const uint8_t encrypted_test_blob[] = { ++ 0x37, 0x8e, 0x1d, 0xd5, 0xd3, 0x9f, 0xca, 0x8e, ++ 0x2f, 0x2d, 0xee, 0xc3, 0xb5, 0x50, 0xcd, 0x4e, ++ 0xc9, 0x08, 0x04, 0x68, 0x32, 0xc3, 0xac, 0x8e, ++ 0x53, 0x69, 0xd6, 0xb7, 0x56, 0xcc, 0xc0, 0xbe, ++ 0x4e, 0x96, 0xa7, 0x74, 0xe9, 0xaa, 0x10, 0x3d, ++ 0xd5, 0x8c, 0xaa, 0x12, 0x56, 0xb6, 0xf1, 0x85, ++ 0x21, 0xfa, 0xe9, 0xa1, 0x76, 0xe6, 0xa5, 0x33, ++ 0x33, 0x2f, 0x47, 0x29, 0xd6, 0xbd, 0xde, 0x64, ++ 0x4d, 0x15, 0x3e, 0x6a, 0x11, 0x9b, 0x52, 0xbf, ++ 0x7e, 0x3a, 0xeb, 0x1c, 0x55, 0xd1, 0xb2, 0xa4, ++ 0x35, 0x03, 0x6c, 0x39, 0x61, 0x28, 0x98, 0xc3, ++ 0x2d, 0xd4, 0x70, 0x69, 0x8b, 0x83, 0xe9, 0x62, ++ 0xbe, 0xd8, 0x72, 0x4e, 0xdf, 0xd4, 0xe9, 0xe3, ++ 0x46, 0x2a, 0xf9, 0x3c, 0x0f, 0x41, 0x62, 0xe1, ++ 0x43, 0xf0, 0x91, 0xbe, 0x72, 0xa0, 0xc9, 0x08, ++ 0x73, 0x20, 0x1f, 0x0d, 0x68, 0x2e, 0x32, 0xa1, ++ 0xb8, 0x9b, 0x08, 0xa1, 0xb4, 0x81, 0x6b, 0xf1, ++ 0xde, 0x0c, 0x28, 0x34, 0xe2, 0x65, 0x62, 0x54, ++ 0xeb, 0xc0, 0x71, 0x14, 0xad, 0x36, 0x43, 0x0e, ++ 0x92, 0x4d, 0x11, 0xe8, 0xdd, 0x2d, 0x5f, 0x05, ++ 0xff, 0x07, 0xda, 0x81, 0x4e, 0x27, 0x42, 0xa8, ++ 0xa9, 0x64, 0x4c, 0x74, 0xc8, 0x05, 0xbb, 0x83, ++ 0x5a, 0xd9, 0x90, 0x3e, 0x0d, 0x9d, 0xe5, 0x2f, ++ 0x08, 0xf9, 0x1b, 0xbd, 0x26, 0xc3, 0x0d, 0xac, ++ 0x43, 0xd5, 0x17, 0xf2, 0x61, 0xf5, 0x74, 0x9b, ++ 0xf3, 0x5b, 0x5f, 0xe1, 0x8a, 0xa6, 0xfd, 0xdf, ++ 0xff, 0xb5, 0x8b, 0xf1, 0x26, 0xf7, 0xe0, 0xa7, ++ 0x4f, 0x5b, 0xb8, 0x6d, 0xeb, 0xf6, 0x52, 0x68, ++ 0x8d, 0xa3, 0xd4, 0x7f, 0x56, 0x43, 0xaa, 0xec, ++ 0x58, 0x47, 0x03, 0xee, 0x9b, 0x59, 0xd9, 0x78, ++ 0x9a, 0xfb, 0x9e, 0xe9, 0xa6, 0x61, 0x4e, 0x6d, ++ 0x92, 0x35, 0xd3, 0x37, 0x6e, 0xf2, 0x34, 0x39, ++ 0xd4, 0xd2, 0xeb, 0xcf, 0x1c, 0x10, 0xb3, 0x2b, ++ 0x3e, 0x07, 0x42, 0x3e, 0x20, 0x90, 0x07, 0x3e, ++ 0xc7, 0xed, 0xd4, 0xdf, 0x50, 0xe5, 0xff, 0xaf, ++ 0x05, 0xce, 0x29, 0xbe, 0x01, 0xf8, 0xb0, 0x30, ++ 0x96, 0xae, 0x1b, 0x62, 0x23, 0x93, 0x91, 0x1a, ++ 0x52, 0x98, 0xd9, 0x59, 0xb8, 0x11, 0xec, 0xb8, ++ 0xcf, 0x20, 0x32, 0x90, 0x9e, 0xf2, 0x06, 0x43, ++ 0xb8, 0x36, 0xe3, 0x33, 0x4e, 0x6f, 0x75, 0xeb, ++ 0xf7, 0x6c, 0xac, 0x06, 0x5f, 0x24, 0x8e, 0x4a, ++ 0x03, 0xdf, 0x50, 0x31, 0xaa, 0x91, 0xd5, 0x85, ++ 0x95, 0x78, 0x5b, 0xf4, 0x7f, 0x3e, 0xbc, 0x41, ++ 0xfa, 0x10, 0xd3, 0x0f, 0x86, 0x8b, 0x23, 0xed, ++ 0xfc, 0xcc, 0x3e, 0x7d, 0x8c, 0xb4, 0x7c, 0xec, ++ 0x04, 0x7d, 0x12, 0x53, 0xa1, 0x30, 0xc5, 0xac, ++ 0xf3, 0x1e, 0x54, 0x1f, 0x97, 0x05, 0x86, 0x74, ++ 0x51, 0x13, 0x45, 0x98, 0xb8, 0x50, 0x62, 0x18, ++ 0x0f, 0x6d, 0x66, 0xa4, 0x88, 0x31, 0x76, 0xa3, ++ 0xb0, 0x75, 0x55, 0x44, 0x18, 0x7c, 0x67, 0xc7, ++ 0x09, 0x9c, 0xab, 0x53, 0x49, 0xc0, 0xc9, 0x27, ++ 0x53, 0xa6, 0x99, 0x01, 0x10, 0x49, 0x67, 0x8e, ++ 0x5b, 0x12, 0x96, 0x40, 0x16, 0x39, 0x11, 0x53, ++ 0x44, 0x8f, 0xa9, 0xbe, 0x84, 0xbe, 0xe0, 0x45, ++ 0xe3, 0xfd, 0x48, 0x46, 0x43, 0x53, 0x13, 0x5f, ++ 0xfa, 0xcf, 0x09, 0x67, 0x90, 0xa3, 0x94, 0xaa, ++ 0x0d, 0x1f, 0xc2, 0xc3, 0xd4, 0x7e, 0xc8, 0x14, ++ 0xbe, 0x84, 0xa5, 0x55, 0xee, 0x49, 0x8e, 0x03, ++ 0x1d, 0xaf, 0xad, 0x65, 0x2f, 0xf0, 0xd5, 0x90, ++ 0x5e, 0x8d, 0x29, 0x40, 0xba, 0x57, 0x26, 0xa8, ++ 0x6c, 0x4b, 0x59, 0x40, 0x4e, 0xc2, 0xc4, 0x88, ++ 0x0a, 0x06, 0x2b, 0x6c, 0x2a, 0xc7, 0x3f, 0xfe, ++ 0x37, 0x2c, 0x41, 0x58, 0xfe, 0x7e, 0xaf, 0xd1, ++ 0xd9, 0xd2, 0x9c, 0xd7, 0x8a, 0x01, 0x0e, 0x8c, ++ 0x9e, 0x8b, 0x5d, 0x72, 0x54, 0x00, 0xbe, 0xb2, ++ 0x9a, 0xc7, 0xfd, 0x83, 0x1e, 0x9c, 0x79, 0xdd, ++ 0x15, 0x13, 0xdc, 0x15, ++}; ++ ++static void torture_decode_rc4_passwd_buffer(void **state) ++{ ++ char *password_decoded = NULL; ++ size_t password_decoded_len = 0; ++ DATA_BLOB session_key = data_blob_const("SystemLibraryDTC", 16); ++ struct samr_CryptPasswordEx out_pwd_buf = { ++ .data = {0}, ++ }; ++ NTSTATUS status; ++ bool ok; ++ ++ memcpy(out_pwd_buf.data, ++ encrypted_test_blob, ++ sizeof(out_pwd_buf.data)); ++ ++ status = encode_or_decode_arc4_passwd_buffer(out_pwd_buf.data, ++ &session_key); ++ assert_true(NT_STATUS_IS_OK(status)); ++ ++ ok = decode_pw_buffer(NULL, ++ out_pwd_buf.data, ++ &password_decoded, ++ &password_decoded_len, ++ CH_UTF16); ++ assert_true(ok); ++ assert_int_equal(password_decoded_len, strlen(PASSWORD)); ++ assert_string_equal(password_decoded, PASSWORD); ++} ++ ++static void torture_rc4_passwd_buffer(void **state) ++{ ++ char *password_decoded = NULL; ++ size_t password_decoded_len = 0; ++ DATA_BLOB session_key = data_blob_const("SystemLibraryDTC", 16); ++ struct samr_CryptPasswordEx out_pwd_buf = { ++ .data = {0}, ++ }; ++ NTSTATUS status; ++ bool ok; ++ ++ status = init_samr_CryptPasswordEx(PASSWORD, ++ &session_key, ++ &out_pwd_buf); ++ assert_true(NT_STATUS_IS_OK(status)); ++ ++ status = encode_or_decode_arc4_passwd_buffer(out_pwd_buf.data, ++ &session_key); ++ assert_true(NT_STATUS_IS_OK(status)); ++ ++ ok = decode_pw_buffer(NULL, ++ out_pwd_buf.data, ++ &password_decoded, ++ &password_decoded_len, ++ CH_UTF16); ++ assert_true(ok); ++ assert_int_equal(password_decoded_len, strlen(PASSWORD)); ++ assert_string_equal(password_decoded, PASSWORD); ++} ++ ++int main(int argc, char *argv[]) ++{ ++ int rc; ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test(torture_decode_rc4_passwd_buffer), ++ cmocka_unit_test(torture_rc4_passwd_buffer), ++ }; ++ ++ if (argc == 2) { ++ cmocka_set_test_filter(argv[1]); ++ } ++ cmocka_set_message_output(CM_OUTPUT_SUBUNIT); ++ ++ rc = cmocka_run_group_tests(tests, NULL, NULL); ++ ++ return rc; ++} +diff --git a/libcli/auth/wscript_build b/libcli/auth/wscript_build +index 04e2b09eadf..eabf3814ba1 100644 +--- a/libcli/auth/wscript_build ++++ b/libcli/auth/wscript_build +@@ -62,3 +62,12 @@ bld.SAMBA_BINARY('test_schannel', + cmocka + ''', + install=False) ++ ++bld.SAMBA_BINARY('test_rc4_passwd_buffer', ++ source='tests/test_rc4_passwd_buffer.c', ++ deps=''' ++ INIT_SAMR ++ LIBCLI_AUTH ++ cmocka ++ ''', ++ install=False) +diff --git a/selftest/tests.py b/selftest/tests.py +index bbb5709ee47..c91d9b445fe 100644 +--- a/selftest/tests.py ++++ b/selftest/tests.py +@@ -392,6 +392,8 @@ plantestsuite("samba.unittests.ntlm_check", "none", + [os.path.join(bindir(), "default/libcli/auth/test_ntlm_check")]) + plantestsuite("samba.unittests.schannel", "none", + [os.path.join(bindir(), "default/libcli/auth/test_schannel")]) ++plantestsuite("samba.unittests.rc4_passwd_buffer", "none", ++ [os.path.join(bindir(), "default/libcli/auth/test_rc4_passwd_buffer")]) + plantestsuite("samba.unittests.test_registry_regfio", "none", + [os.path.join(bindir(), "default/source3/test_registry_regfio")]) + plantestsuite("samba.unittests.test_oLschema2ldif", "none", +-- +2.23.0 + diff --git a/SOURCES/0012-s3-rpc_client-Use-samba_gnutls_arcfour_confounded_md.patch b/SOURCES/0012-s3-rpc_client-Use-samba_gnutls_arcfour_confounded_md.patch new file mode 100644 index 0000000..c83542b --- /dev/null +++ b/SOURCES/0012-s3-rpc_client-Use-samba_gnutls_arcfour_confounded_md.patch @@ -0,0 +1,94 @@ +From 6546e97d27e45db9cbfd2f7d8c4838b2fd8d6a6a Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Thu, 4 Jul 2019 16:22:48 +0200 +Subject: [PATCH 012/187] s3:rpc_client: Use + samba_gnutls_arcfour_confounded_md5 in init_samr_CryptPasswordEx + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 2075019ca90d7d474003c87b2f0202239891eba5) +--- + source3/rpc_client/init_samr.c | 50 ++++++++++------------------------ + 1 file changed, 15 insertions(+), 35 deletions(-) + +diff --git a/source3/rpc_client/init_samr.c b/source3/rpc_client/init_samr.c +index 5f6cbc5d3c7..3968dfea99f 100644 +--- a/source3/rpc_client/init_samr.c ++++ b/source3/rpc_client/init_samr.c +@@ -36,56 +36,36 @@ NTSTATUS init_samr_CryptPasswordEx(const char *pwd, + { + /* samr_CryptPasswordEx */ + +- uint8_t pwbuf[532]; +- gnutls_hash_hd_t hash_hnd = NULL; +- uint8_t confounder[16]; +- DATA_BLOB confounded_session_key = data_blob(NULL, 16); +- NTSTATUS status; ++ uint8_t _confounder[16] = {0}; ++ DATA_BLOB confounder = data_blob_const(_confounder, 16); ++ uint8_t pwbuf[532] = {0}; ++ DATA_BLOB encrypt_pwbuf = data_blob_const(pwbuf, 516); + bool ok; + int rc; + + ok = encode_pw_buffer(pwbuf, pwd, STR_UNICODE); + if (!ok) { +- status = NT_STATUS_INTERNAL_ERROR; +- goto out; ++ return NT_STATUS_INTERNAL_ERROR; + } + +- generate_random_buffer((uint8_t *)confounder, 16); ++ generate_random_buffer(_confounder, sizeof(_confounder)); + +- rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5); ++ rc = samba_gnutls_arcfour_confounded_md5(&confounder, ++ session_key, ++ &encrypt_pwbuf, ++ SAMBA_GNUTLS_ENCRYPT); + if (rc < 0) { +- status = gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED); +- goto out; ++ ZERO_ARRAY(_confounder); ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); + } + +- rc = gnutls_hash(hash_hnd, confounder, 16); +- if (rc < 0) { +- gnutls_hash_deinit(hash_hnd, NULL); +- status = gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED); +- goto out; +- } +- rc = gnutls_hash(hash_hnd, session_key->data, session_key->length); +- if (rc < 0) { +- gnutls_hash_deinit(hash_hnd, NULL); +- status = gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED); +- goto out; +- } +- +- gnutls_hash_deinit(hash_hnd, confounded_session_key.data); +- +- arcfour_crypt_blob(pwbuf, 516, &confounded_session_key); +- data_blob_clear_free(&confounded_session_key); +- +- memcpy(&pwbuf[516], confounder, 16); +- ZERO_ARRAY(confounder); ++ memcpy(&pwbuf[516], confounder.data, confounder.length); ++ ZERO_ARRAY(_confounder); + + memcpy(pwd_buf->data, pwbuf, sizeof(pwbuf)); + ZERO_ARRAY(pwbuf); + +- status = NT_STATUS_OK; +-out: +- data_blob_clear_free(&confounded_session_key); +- return status; ++ return NT_STATUS_OK; + } + + /************************************************************************* +-- +2.23.0 + diff --git a/SOURCES/0013-s3-rpc_client-Use-GnuTLS-RC4-in-init_samr_CryptPassw.patch b/SOURCES/0013-s3-rpc_client-Use-GnuTLS-RC4-in-init_samr_CryptPassw.patch new file mode 100644 index 0000000..7eac25c --- /dev/null +++ b/SOURCES/0013-s3-rpc_client-Use-GnuTLS-RC4-in-init_samr_CryptPassw.patch @@ -0,0 +1,65 @@ +From 9913d8e981dd39fd1f7e260644f35aa6718c9bd2 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 16 Jan 2019 13:15:08 +0100 +Subject: [PATCH 013/187] s3:rpc_client: Use GnuTLS RC4 in + init_samr_CryptPassword() + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 95db9a81db093488e625b4ef385a184a5e517ede) +--- + source3/rpc_client/init_samr.c | 23 +++++++++++++++++++++-- + 1 file changed, 21 insertions(+), 2 deletions(-) + +diff --git a/source3/rpc_client/init_samr.c b/source3/rpc_client/init_samr.c +index 3968dfea99f..0eb50c54525 100644 +--- a/source3/rpc_client/init_samr.c ++++ b/source3/rpc_client/init_samr.c +@@ -19,7 +19,6 @@ + + #include "includes.h" + #include "../libcli/auth/libcli_auth.h" +-#include "../lib/crypto/arcfour.h" + #include "rpc_client/init_samr.h" + + #include "lib/crypto/gnutls_helpers.h" +@@ -77,13 +76,33 @@ NTSTATUS init_samr_CryptPassword(const char *pwd, + struct samr_CryptPassword *pwd_buf) + { + /* samr_CryptPassword */ ++ gnutls_cipher_hd_t cipher_hnd = NULL; ++ gnutls_datum_t sess_key = { ++ .data = session_key->data, ++ .size = session_key->length, ++ }; + bool ok; ++ int rc; + + ok = encode_pw_buffer(pwd_buf->data, pwd, STR_UNICODE); + if (!ok) { + return NT_STATUS_INTERNAL_ERROR; + } +- arcfour_crypt_blob(pwd_buf->data, 516, session_key); ++ ++ rc = gnutls_cipher_init(&cipher_hnd, ++ GNUTLS_CIPHER_ARCFOUR_128, ++ &sess_key, ++ NULL); ++ if (rc != 0) { ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ } ++ rc = gnutls_cipher_encrypt(cipher_hnd, ++ pwd_buf->data, ++ 516); ++ gnutls_cipher_deinit(cipher_hnd); ++ if (rc != 0) { ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ } + + return NT_STATUS_OK; + } +-- +2.23.0 + diff --git a/SOURCES/0014-libcli-auth-Use-samba_gnutls_arcfour_confounded_md5-.patch b/SOURCES/0014-libcli-auth-Use-samba_gnutls_arcfour_confounded_md5-.patch new file mode 100644 index 0000000..f5580d9 --- /dev/null +++ b/SOURCES/0014-libcli-auth-Use-samba_gnutls_arcfour_confounded_md5-.patch @@ -0,0 +1,73 @@ +From 15ca4ae322f88f797c571ad7801a9e44a6262d73 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Fri, 5 Jul 2019 10:09:32 +0200 +Subject: [PATCH 014/187] libcli:auth: Use + samba_gnutls_arcfour_confounded_md5() for rc4 passwd buffer + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit dea160820a393be51985a4e761a3f73da83972e7) +--- + libcli/auth/smbencrypt.c | 39 +++++++++------------------------------ + 1 file changed, 9 insertions(+), 30 deletions(-) + +diff --git a/libcli/auth/smbencrypt.c b/libcli/auth/smbencrypt.c +index ae97f3cc93e..17c1e1f69ff 100644 +--- a/libcli/auth/smbencrypt.c ++++ b/libcli/auth/smbencrypt.c +@@ -846,41 +846,20 @@ bool decode_pw_buffer(TALLOC_CTX *ctx, + NTSTATUS encode_or_decode_arc4_passwd_buffer(unsigned char pw_buf[532], + const DATA_BLOB *psession_key) + { +- gnutls_hash_hd_t hash_hnd = NULL; +- unsigned char key_out[16]; +- NTSTATUS status; +- int rc; +- + /* Confounder is last 16 bytes. */ ++ DATA_BLOB confounder = data_blob_const(&pw_buf[516], 16); ++ DATA_BLOB pw_data = data_blob_const(pw_buf, 516); ++ int rc; + +- rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5); ++ rc = samba_gnutls_arcfour_confounded_md5(&confounder, ++ psession_key, ++ &pw_data, ++ SAMBA_GNUTLS_DECRYPT); + if (rc < 0) { +- status = gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED); +- goto out; ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); + } + +- rc = gnutls_hash(hash_hnd, &pw_buf[516], 16); +- if (rc < 0) { +- gnutls_hash_deinit(hash_hnd, NULL); +- status = gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED); +- goto out; +- } +- rc = gnutls_hash(hash_hnd, psession_key->data, psession_key->length); +- if (rc < 0) { +- gnutls_hash_deinit(hash_hnd, NULL); +- status = gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED); +- goto out; +- } +- gnutls_hash_deinit(hash_hnd, key_out); +- +- /* arc4 with key_out. */ +- arcfour_crypt(pw_buf, key_out, 516); +- +- ZERO_ARRAY(key_out); +- +- status = NT_STATUS_OK; +-out: +- return status; ++ return NT_STATUS_OK; + } + + /*********************************************************** +-- +2.23.0 + diff --git a/SOURCES/0015-libcli-auth-Rename-encode_or_decode_arc4_passwd_buff.patch b/SOURCES/0015-libcli-auth-Rename-encode_or_decode_arc4_passwd_buff.patch new file mode 100644 index 0000000..5da71fc --- /dev/null +++ b/SOURCES/0015-libcli-auth-Rename-encode_or_decode_arc4_passwd_buff.patch @@ -0,0 +1,97 @@ +From 228c16e06b82a3d7a33c2d4440aa258518c8c29f Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Fri, 5 Jul 2019 10:12:43 +0200 +Subject: [PATCH 015/187] libcli:auth: Rename + encode_or_decode_arc4_passwd_buffer() + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 89f8b028e2d595348f9996854488d7aa552ae905) +--- + libcli/auth/proto.h | 4 ++-- + libcli/auth/smbencrypt.c | 4 ++-- + libcli/auth/tests/test_rc4_passwd_buffer.c | 6 ++---- + source3/rpc_server/samr/srv_samr_nt.c | 4 ++-- + 4 files changed, 8 insertions(+), 10 deletions(-) + +diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h +index 651f1139cf5..1bcbeddb228 100644 +--- a/libcli/auth/proto.h ++++ b/libcli/auth/proto.h +@@ -184,8 +184,8 @@ bool decode_pw_buffer(TALLOC_CTX *ctx, + /*********************************************************** + Decode an arc4 encrypted password change buffer. + ************************************************************/ +-NTSTATUS encode_or_decode_arc4_passwd_buffer(unsigned char pw_buf[532], +- const DATA_BLOB *psession_key); ++NTSTATUS decode_rc4_passwd_buffer(unsigned char pw_buf[532], ++ const DATA_BLOB *psession_key); + + /*********************************************************** + encode a password buffer with an already unicode password. The +diff --git a/libcli/auth/smbencrypt.c b/libcli/auth/smbencrypt.c +index 17c1e1f69ff..7e343f71577 100644 +--- a/libcli/auth/smbencrypt.c ++++ b/libcli/auth/smbencrypt.c +@@ -843,8 +843,8 @@ bool decode_pw_buffer(TALLOC_CTX *ctx, + Decode an arc4 encrypted password change buffer. + ************************************************************/ + +-NTSTATUS encode_or_decode_arc4_passwd_buffer(unsigned char pw_buf[532], +- const DATA_BLOB *psession_key) ++NTSTATUS decode_rc4_passwd_buffer(unsigned char pw_buf[532], ++ const DATA_BLOB *psession_key) + { + /* Confounder is last 16 bytes. */ + DATA_BLOB confounder = data_blob_const(&pw_buf[516], 16); +diff --git a/libcli/auth/tests/test_rc4_passwd_buffer.c b/libcli/auth/tests/test_rc4_passwd_buffer.c +index f40ac3a5655..eb737703230 100644 +--- a/libcli/auth/tests/test_rc4_passwd_buffer.c ++++ b/libcli/auth/tests/test_rc4_passwd_buffer.c +@@ -114,8 +114,7 @@ static void torture_decode_rc4_passwd_buffer(void **state) + encrypted_test_blob, + sizeof(out_pwd_buf.data)); + +- status = encode_or_decode_arc4_passwd_buffer(out_pwd_buf.data, +- &session_key); ++ status = decode_rc4_passwd_buffer(out_pwd_buf.data, &session_key); + assert_true(NT_STATUS_IS_OK(status)); + + ok = decode_pw_buffer(NULL, +@@ -144,8 +143,7 @@ static void torture_rc4_passwd_buffer(void **state) + &out_pwd_buf); + assert_true(NT_STATUS_IS_OK(status)); + +- status = encode_or_decode_arc4_passwd_buffer(out_pwd_buf.data, +- &session_key); ++ status = decode_rc4_passwd_buffer(out_pwd_buf.data, &session_key); + assert_true(NT_STATUS_IS_OK(status)); + + ok = decode_pw_buffer(NULL, +diff --git a/source3/rpc_server/samr/srv_samr_nt.c b/source3/rpc_server/samr/srv_samr_nt.c +index c2be8bfc19a..4dc9132511f 100644 +--- a/source3/rpc_server/samr/srv_samr_nt.c ++++ b/source3/rpc_server/samr/srv_samr_nt.c +@@ -5185,7 +5185,7 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p, + if(!NT_STATUS_IS_OK(status)) { + break; + } +- status = encode_or_decode_arc4_passwd_buffer( ++ status = decode_rc4_passwd_buffer( + info->info25.password.data, + &session_key); + if (!NT_STATUS_IS_OK(status)) { +@@ -5204,7 +5204,7 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p, + if(!NT_STATUS_IS_OK(status)) { + break; + } +- status = encode_or_decode_arc4_passwd_buffer( ++ status = decode_rc4_passwd_buffer( + info->info26.password.data, + &session_key); + if (!NT_STATUS_IS_OK(status)) { +-- +2.23.0 + diff --git a/SOURCES/0016-libcli-auth-Pass-samr_CryptPasswordEx-to-decode_rc4_.patch b/SOURCES/0016-libcli-auth-Pass-samr_CryptPasswordEx-to-decode_rc4_.patch new file mode 100644 index 0000000..a2adbc3 --- /dev/null +++ b/SOURCES/0016-libcli-auth-Pass-samr_CryptPasswordEx-to-decode_rc4_.patch @@ -0,0 +1,115 @@ +From 3eb3f3bdabd103c3858323e08a9180913c223e16 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Tue, 9 Jul 2019 12:53:31 +0200 +Subject: [PATCH 016/187] libcli:auth: Pass samr_CryptPasswordEx to + decode_rc4_passwd_buffer() + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 79ca72ec3d13fea5d2ad608415757ca9870035a3) +--- + libcli/auth/proto.h | 4 ++-- + libcli/auth/smbencrypt.c | 8 ++++---- + libcli/auth/tests/test_rc4_passwd_buffer.c | 5 +++-- + source3/rpc_server/samr/srv_samr_nt.c | 10 ++++------ + 4 files changed, 13 insertions(+), 14 deletions(-) + +diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h +index 1bcbeddb228..a67c89d8552 100644 +--- a/libcli/auth/proto.h ++++ b/libcli/auth/proto.h +@@ -184,8 +184,8 @@ bool decode_pw_buffer(TALLOC_CTX *ctx, + /*********************************************************** + Decode an arc4 encrypted password change buffer. + ************************************************************/ +-NTSTATUS decode_rc4_passwd_buffer(unsigned char pw_buf[532], +- const DATA_BLOB *psession_key); ++NTSTATUS decode_rc4_passwd_buffer(const DATA_BLOB *psession_key, ++ struct samr_CryptPasswordEx *inout_crypt_pwd); + + /*********************************************************** + encode a password buffer with an already unicode password. The +diff --git a/libcli/auth/smbencrypt.c b/libcli/auth/smbencrypt.c +index 7e343f71577..b7b17130f07 100644 +--- a/libcli/auth/smbencrypt.c ++++ b/libcli/auth/smbencrypt.c +@@ -843,12 +843,12 @@ bool decode_pw_buffer(TALLOC_CTX *ctx, + Decode an arc4 encrypted password change buffer. + ************************************************************/ + +-NTSTATUS decode_rc4_passwd_buffer(unsigned char pw_buf[532], +- const DATA_BLOB *psession_key) ++NTSTATUS decode_rc4_passwd_buffer(const DATA_BLOB *psession_key, ++ struct samr_CryptPasswordEx *inout_crypt_pwd) + { + /* Confounder is last 16 bytes. */ +- DATA_BLOB confounder = data_blob_const(&pw_buf[516], 16); +- DATA_BLOB pw_data = data_blob_const(pw_buf, 516); ++ DATA_BLOB confounder = data_blob_const(&inout_crypt_pwd->data[516], 16); ++ DATA_BLOB pw_data = data_blob_const(&inout_crypt_pwd->data, 516); + int rc; + + rc = samba_gnutls_arcfour_confounded_md5(&confounder, +diff --git a/libcli/auth/tests/test_rc4_passwd_buffer.c b/libcli/auth/tests/test_rc4_passwd_buffer.c +index eb737703230..3bf371c5dd5 100644 +--- a/libcli/auth/tests/test_rc4_passwd_buffer.c ++++ b/libcli/auth/tests/test_rc4_passwd_buffer.c +@@ -114,7 +114,7 @@ static void torture_decode_rc4_passwd_buffer(void **state) + encrypted_test_blob, + sizeof(out_pwd_buf.data)); + +- status = decode_rc4_passwd_buffer(out_pwd_buf.data, &session_key); ++ status = decode_rc4_passwd_buffer(&session_key, &out_pwd_buf); + assert_true(NT_STATUS_IS_OK(status)); + + ok = decode_pw_buffer(NULL, +@@ -143,7 +143,7 @@ static void torture_rc4_passwd_buffer(void **state) + &out_pwd_buf); + assert_true(NT_STATUS_IS_OK(status)); + +- status = decode_rc4_passwd_buffer(out_pwd_buf.data, &session_key); ++ status = decode_rc4_passwd_buffer(&session_key, &out_pwd_buf); + assert_true(NT_STATUS_IS_OK(status)); + + ok = decode_pw_buffer(NULL, +@@ -154,6 +154,7 @@ static void torture_rc4_passwd_buffer(void **state) + assert_true(ok); + assert_int_equal(password_decoded_len, strlen(PASSWORD)); + assert_string_equal(password_decoded, PASSWORD); ++ talloc_free(password_decoded); + } + + int main(int argc, char *argv[]) +diff --git a/source3/rpc_server/samr/srv_samr_nt.c b/source3/rpc_server/samr/srv_samr_nt.c +index 4dc9132511f..fd5c453e0eb 100644 +--- a/source3/rpc_server/samr/srv_samr_nt.c ++++ b/source3/rpc_server/samr/srv_samr_nt.c +@@ -5185,9 +5185,8 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p, + if(!NT_STATUS_IS_OK(status)) { + break; + } +- status = decode_rc4_passwd_buffer( +- info->info25.password.data, +- &session_key); ++ status = decode_rc4_passwd_buffer(&session_key, ++ &info->info25.password); + if (!NT_STATUS_IS_OK(status)) { + break; + } +@@ -5204,9 +5203,8 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p, + if(!NT_STATUS_IS_OK(status)) { + break; + } +- status = decode_rc4_passwd_buffer( +- info->info26.password.data, +- &session_key); ++ status = decode_rc4_passwd_buffer(&session_key, ++ &info->info26.password); + if (!NT_STATUS_IS_OK(status)) { + break; + } +-- +2.23.0 + diff --git a/SOURCES/0017-libcli-auth-Add-encode_rc4_passwd_buffer.patch b/SOURCES/0017-libcli-auth-Add-encode_rc4_passwd_buffer.patch new file mode 100644 index 0000000..61eb21d --- /dev/null +++ b/SOURCES/0017-libcli-auth-Add-encode_rc4_passwd_buffer.patch @@ -0,0 +1,89 @@ +From 13dfa7d5a1c96d78eca81eb0eb97bc0668561738 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Tue, 9 Jul 2019 13:01:10 +0200 +Subject: [PATCH 017/187] libcli:auth: Add encode_rc4_passwd_buffer() + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 06d46c447e69a6b384c0089863c343b4924c7caf) +--- + libcli/auth/proto.h | 7 +++++++ + libcli/auth/smbencrypt.c | 42 ++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 49 insertions(+) + +diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h +index a67c89d8552..67caaca8c41 100644 +--- a/libcli/auth/proto.h ++++ b/libcli/auth/proto.h +@@ -181,6 +181,13 @@ bool decode_pw_buffer(TALLOC_CTX *ctx, + size_t *new_pw_len, + charset_t string_charset); + ++/*********************************************************** ++ Encode an arc4 password change buffer. ++************************************************************/ ++NTSTATUS encode_rc4_passwd_buffer(const char *passwd, ++ const DATA_BLOB *session_key, ++ struct samr_CryptPasswordEx *out_crypt_pwd); ++ + /*********************************************************** + Decode an arc4 encrypted password change buffer. + ************************************************************/ +diff --git a/libcli/auth/smbencrypt.c b/libcli/auth/smbencrypt.c +index b7b17130f07..793012553b2 100644 +--- a/libcli/auth/smbencrypt.c ++++ b/libcli/auth/smbencrypt.c +@@ -839,6 +839,48 @@ bool decode_pw_buffer(TALLOC_CTX *ctx, + return true; + } + ++/*********************************************************** ++ Encode an arc4 password change buffer. ++************************************************************/ ++NTSTATUS encode_rc4_passwd_buffer(const char *passwd, ++ const DATA_BLOB *session_key, ++ struct samr_CryptPasswordEx *out_crypt_pwd) ++{ ++ uint8_t _confounder[16] = {0}; ++ DATA_BLOB confounder = data_blob_const(_confounder, 16); ++ DATA_BLOB pw_data = data_blob_const(out_crypt_pwd->data, 516); ++ bool ok; ++ int rc; ++ ++ ok = encode_pw_buffer(pw_data.data, passwd, STR_UNICODE); ++ if (!ok) { ++ return NT_STATUS_INVALID_PARAMETER; ++ } ++ ++ generate_random_buffer(confounder.data, confounder.length); ++ ++ rc = samba_gnutls_arcfour_confounded_md5(&confounder, ++ session_key, ++ &pw_data, ++ SAMBA_GNUTLS_ENCRYPT); ++ if (rc < 0) { ++ ZERO_ARRAY(_confounder); ++ data_blob_clear(&pw_data); ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ } ++ ++ /* ++ * The packet format is the 516 byte RC4 encrypted ++ * pasword followed by the 16 byte counfounder ++ * The confounder is a salt to prevent pre-computed hash attacks on the ++ * database. ++ */ ++ memcpy(&out_crypt_pwd->data[516], confounder.data, confounder.length); ++ ZERO_ARRAY(_confounder); ++ ++ return NT_STATUS_OK; ++} ++ + /*********************************************************** + Decode an arc4 encrypted password change buffer. + ************************************************************/ +-- +2.23.0 + diff --git a/SOURCES/0018-libcli-auth-Add-test-for-encode_rc4_passwd_buffer.patch b/SOURCES/0018-libcli-auth-Add-test-for-encode_rc4_passwd_buffer.patch new file mode 100644 index 0000000..7ed5a49 --- /dev/null +++ b/SOURCES/0018-libcli-auth-Add-test-for-encode_rc4_passwd_buffer.patch @@ -0,0 +1,65 @@ +From fe1f6278c7a5c54d948f6ca031686745ad653a94 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Tue, 9 Jul 2019 13:06:49 +0200 +Subject: [PATCH 018/187] libcli:auth: Add test for encode_rc4_passwd_buffer() + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit fe00b3735a7e8ae16fb6443965769f1e947a6aa6) +--- + libcli/auth/tests/test_rc4_passwd_buffer.c | 31 ++++++++++++++++++++++ + 1 file changed, 31 insertions(+) + +diff --git a/libcli/auth/tests/test_rc4_passwd_buffer.c b/libcli/auth/tests/test_rc4_passwd_buffer.c +index 3bf371c5dd5..db6ca3f3f4c 100644 +--- a/libcli/auth/tests/test_rc4_passwd_buffer.c ++++ b/libcli/auth/tests/test_rc4_passwd_buffer.c +@@ -157,12 +157,43 @@ static void torture_rc4_passwd_buffer(void **state) + talloc_free(password_decoded); + } + ++static void torture_endode_decode_rc4_passwd_buffer(void **state) ++{ ++ char *password_decoded = NULL; ++ size_t password_decoded_len = 0; ++ DATA_BLOB session_key = data_blob_const("SystemLibraryDTC", 16); ++ struct samr_CryptPasswordEx out_pwd_buf = { ++ .data = {0}, ++ }; ++ NTSTATUS status; ++ bool ok; ++ ++ status = encode_rc4_passwd_buffer(PASSWORD, ++ &session_key, ++ &out_pwd_buf); ++ assert_true(NT_STATUS_IS_OK(status)); ++ ++ status = decode_rc4_passwd_buffer(&session_key, &out_pwd_buf); ++ assert_true(NT_STATUS_IS_OK(status)); ++ ++ ok = decode_pw_buffer(NULL, ++ out_pwd_buf.data, ++ &password_decoded, ++ &password_decoded_len, ++ CH_UTF16); ++ assert_true(ok); ++ assert_int_equal(password_decoded_len, strlen(PASSWORD)); ++ assert_string_equal(password_decoded, PASSWORD); ++ talloc_free(password_decoded); ++} ++ + int main(int argc, char *argv[]) + { + int rc; + const struct CMUnitTest tests[] = { + cmocka_unit_test(torture_decode_rc4_passwd_buffer), + cmocka_unit_test(torture_rc4_passwd_buffer), ++ cmocka_unit_test(torture_endode_decode_rc4_passwd_buffer), + }; + + if (argc == 2) { +-- +2.23.0 + diff --git a/SOURCES/0019-s3-rpc_client-Use-encode_rc4_passwd_buffer-in-init_s.patch b/SOURCES/0019-s3-rpc_client-Use-encode_rc4_passwd_buffer-in-init_s.patch new file mode 100644 index 0000000..53605d5 --- /dev/null +++ b/SOURCES/0019-s3-rpc_client-Use-encode_rc4_passwd_buffer-in-init_s.patch @@ -0,0 +1,60 @@ +From 26b7ab9339d9e6530244bf35e38a3658d7fc8aa9 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 24 Jul 2019 11:44:51 +0200 +Subject: [PATCH 019/187] s3:rpc_client: Use encode_rc4_passwd_buffer() in + init_samr_CryptPasswordEx() + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit f0c0cf299eb99e7b78be2f04141b6d415bf525e2) +--- + source3/rpc_client/init_samr.c | 33 +-------------------------------- + 1 file changed, 1 insertion(+), 32 deletions(-) + +diff --git a/source3/rpc_client/init_samr.c b/source3/rpc_client/init_samr.c +index 0eb50c54525..a98d50e3f6a 100644 +--- a/source3/rpc_client/init_samr.c ++++ b/source3/rpc_client/init_samr.c +@@ -33,38 +33,7 @@ NTSTATUS init_samr_CryptPasswordEx(const char *pwd, + DATA_BLOB *session_key, + struct samr_CryptPasswordEx *pwd_buf) + { +- /* samr_CryptPasswordEx */ +- +- uint8_t _confounder[16] = {0}; +- DATA_BLOB confounder = data_blob_const(_confounder, 16); +- uint8_t pwbuf[532] = {0}; +- DATA_BLOB encrypt_pwbuf = data_blob_const(pwbuf, 516); +- bool ok; +- int rc; +- +- ok = encode_pw_buffer(pwbuf, pwd, STR_UNICODE); +- if (!ok) { +- return NT_STATUS_INTERNAL_ERROR; +- } +- +- generate_random_buffer(_confounder, sizeof(_confounder)); +- +- rc = samba_gnutls_arcfour_confounded_md5(&confounder, +- session_key, +- &encrypt_pwbuf, +- SAMBA_GNUTLS_ENCRYPT); +- if (rc < 0) { +- ZERO_ARRAY(_confounder); +- return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); +- } +- +- memcpy(&pwbuf[516], confounder.data, confounder.length); +- ZERO_ARRAY(_confounder); +- +- memcpy(pwd_buf->data, pwbuf, sizeof(pwbuf)); +- ZERO_ARRAY(pwbuf); +- +- return NT_STATUS_OK; ++ return encode_rc4_passwd_buffer(pwd, session_key, pwd_buf); + } + + /************************************************************************* +-- +2.23.0 + diff --git a/SOURCES/0020-s4-libnet-Use-encode_rc4_passwd_buffer-in-libnet_Set.patch b/SOURCES/0020-s4-libnet-Use-encode_rc4_passwd_buffer-in-libnet_Set.patch new file mode 100644 index 0000000..151c7c8 --- /dev/null +++ b/SOURCES/0020-s4-libnet-Use-encode_rc4_passwd_buffer-in-libnet_Set.patch @@ -0,0 +1,108 @@ +From c82322be0012f8bf467d75681bd82322eba11145 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Tue, 9 Jul 2019 13:01:49 +0200 +Subject: [PATCH 020/187] s4:libnet: Use encode_rc4_passwd_buffer() in + libnet_SetPassword_samr_handle_26() + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 5afa402bb7ba11a8eefc6e14047eeec1f3327681) +--- + source4/libnet/libnet_passwd.c | 47 ++++++++-------------------------- + 1 file changed, 11 insertions(+), 36 deletions(-) + +diff --git a/source4/libnet/libnet_passwd.c b/source4/libnet/libnet_passwd.c +index 97ce7f58ddf..0beea077bd0 100644 +--- a/source4/libnet/libnet_passwd.c ++++ b/source4/libnet/libnet_passwd.c +@@ -23,6 +23,7 @@ + #include "../lib/crypto/crypto.h" + #include "libcli/auth/libcli_auth.h" + #include "librpc/gen_ndr/ndr_samr_c.h" ++#include "source4/librpc/rpc/dcerpc.h" + + #include "lib/crypto/gnutls_helpers.h" + #include +@@ -276,10 +277,6 @@ static NTSTATUS libnet_SetPassword_samr_handle_26(struct libnet_context *ctx, TA + struct samr_SetUserInfo2 sui; + union samr_UserInfo u_info; + DATA_BLOB session_key; +- DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16); +- uint8_t confounder[16]; +- gnutls_hash_hd_t hash_hnd = NULL; +- int rc; + + if (r->samr_handle.in.info21) { + return NT_STATUS_INVALID_PARAMETER_MIX; +@@ -287,9 +284,8 @@ static NTSTATUS libnet_SetPassword_samr_handle_26(struct libnet_context *ctx, TA + + /* prepare samr_SetUserInfo2 level 26 */ + ZERO_STRUCT(u_info); +- encode_pw_buffer(u_info.info26.password.data, r->samr_handle.in.newpassword, STR_UNICODE); + u_info.info26.password_expired = 0; +- ++ + status = dcerpc_fetch_session_key(r->samr_handle.in.dcerpc_pipe, &session_key); + if (!NT_STATUS_IS_OK(status)) { + r->samr_handle.out.error_string = talloc_asprintf(mem_ctx, +@@ -297,38 +293,18 @@ static NTSTATUS libnet_SetPassword_samr_handle_26(struct libnet_context *ctx, TA + nt_errstr(status)); + return status; + } +- +- generate_random_buffer((uint8_t *)confounder, 16); +- +- rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5); +- if (rc < 0) { +- status = gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED); +- goto out; +- } + +- rc = gnutls_hash(hash_hnd, confounder, 16); +- if (rc < 0) { +- gnutls_hash_deinit(hash_hnd, NULL); +- status = gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED); +- goto out; +- } +- rc = gnutls_hash(hash_hnd, session_key.data, session_key.length); +- if (rc < 0) { +- gnutls_hash_deinit(hash_hnd, NULL); +- status = gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED); +- goto out; ++ status = encode_rc4_passwd_buffer(r->samr_handle.in.newpassword, ++ &session_key, ++ &u_info.info26.password); ++ if (!NT_STATUS_IS_OK(status)) { ++ r->samr_handle.out.error_string = ++ talloc_asprintf(mem_ctx, ++ "encode_rc4_passwd_buffer failed: %s", ++ nt_errstr(status)); ++ return status; + } + +- gnutls_hash_deinit(hash_hnd, confounded_session_key.data); +- +- arcfour_crypt_blob(u_info.info26.password.data, 516, &confounded_session_key); +- ZERO_ARRAY_LEN(confounded_session_key.data, +- confounded_session_key.length); +- data_blob_free(&confounded_session_key); +- +- memcpy(&u_info.info26.password.data[516], confounder, 16); +- ZERO_ARRAY(confounder); +- + sui.in.user_handle = r->samr_handle.in.user_handle; + sui.in.info = &u_info; + sui.in.level = 26; +@@ -346,7 +322,6 @@ static NTSTATUS libnet_SetPassword_samr_handle_26(struct libnet_context *ctx, TA + r->samr_handle.in.account_name, nt_errstr(status)); + } + +-out: + return status; + } + +-- +2.23.0 + diff --git a/SOURCES/0021-s4-libnet-Use-encode_rc4_passwd_buffer-in-libnet_Set.patch b/SOURCES/0021-s4-libnet-Use-encode_rc4_passwd_buffer-in-libnet_Set.patch new file mode 100644 index 0000000..eeac450 --- /dev/null +++ b/SOURCES/0021-s4-libnet-Use-encode_rc4_passwd_buffer-in-libnet_Set.patch @@ -0,0 +1,95 @@ +From c162d52b14947990fb6102180a7e2fd6a7d8d1d5 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Tue, 9 Jul 2019 13:11:54 +0200 +Subject: [PATCH 021/187] s4:libnet: Use encode_rc4_passwd_buffer() in + libnet_SetPassword_samr_handle_25() + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit e44ba0397c7558e1da6a46cc38237a3b0e5cef49) +--- + source4/libnet/libnet_passwd.c | 43 +++++++--------------------------- + 1 file changed, 9 insertions(+), 34 deletions(-) + +diff --git a/source4/libnet/libnet_passwd.c b/source4/libnet/libnet_passwd.c +index 0beea077bd0..b2105121523 100644 +--- a/source4/libnet/libnet_passwd.c ++++ b/source4/libnet/libnet_passwd.c +@@ -331,10 +331,6 @@ static NTSTATUS libnet_SetPassword_samr_handle_25(struct libnet_context *ctx, TA + struct samr_SetUserInfo2 sui; + union samr_UserInfo u_info; + DATA_BLOB session_key; +- DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16); +- uint8_t confounder[16]; +- gnutls_hash_hd_t hash_hnd = NULL; +- int rc; + + if (!r->samr_handle.in.info21) { + return NT_STATUS_INVALID_PARAMETER_MIX; +@@ -344,7 +340,6 @@ static NTSTATUS libnet_SetPassword_samr_handle_25(struct libnet_context *ctx, TA + ZERO_STRUCT(u_info); + u_info.info25.info = *r->samr_handle.in.info21; + u_info.info25.info.fields_present |= SAMR_FIELD_NT_PASSWORD_PRESENT; +- encode_pw_buffer(u_info.info25.password.data, r->samr_handle.in.newpassword, STR_UNICODE); + + status = dcerpc_fetch_session_key(r->samr_handle.in.dcerpc_pipe, &session_key); + if (!NT_STATUS_IS_OK(status)) { +@@ -354,36 +349,17 @@ static NTSTATUS libnet_SetPassword_samr_handle_25(struct libnet_context *ctx, TA + return status; + } + +- generate_random_buffer((uint8_t *)confounder, 16); +- +- rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5); +- if (rc < 0) { +- status = gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED); +- goto out; +- } +- +- rc = gnutls_hash(hash_hnd, confounder, 16); +- if (rc < 0) { +- gnutls_hash_deinit(hash_hnd, NULL); +- status = gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED); +- goto out; +- } +- rc = gnutls_hash(hash_hnd, session_key.data, session_key.length); +- if (rc < 0) { +- gnutls_hash_deinit(hash_hnd, NULL); +- status = gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED); +- goto out; ++ status = encode_rc4_passwd_buffer(r->samr_handle.in.newpassword, ++ &session_key, ++ &u_info.info25.password); ++ if (!NT_STATUS_IS_OK(status)) { ++ r->samr_handle.out.error_string = ++ talloc_asprintf(mem_ctx, ++ "encode_rc4_passwd_buffer failed: %s", ++ nt_errstr(status)); ++ return status; + } + +- gnutls_hash_deinit(hash_hnd, confounded_session_key.data); +- +- arcfour_crypt_blob(u_info.info25.password.data, 516, &confounded_session_key); +- ZERO_ARRAY_LEN(confounded_session_key.data, +- confounded_session_key.length); +- data_blob_free(&confounded_session_key); +- +- memcpy(&u_info.info25.password.data[516], confounder, 16); +- ZERO_ARRAY(confounder); + + sui.in.user_handle = r->samr_handle.in.user_handle; + sui.in.info = &u_info; +@@ -401,7 +377,6 @@ static NTSTATUS libnet_SetPassword_samr_handle_25(struct libnet_context *ctx, TA + r->samr_handle.in.account_name, nt_errstr(status)); + } + +-out: + return status; + } + +-- +2.23.0 + diff --git a/SOURCES/0022-s4-libnet-Use-GnuTLS-RC4-in-libnet_SetPassword_samr_.patch b/SOURCES/0022-s4-libnet-Use-GnuTLS-RC4-in-libnet_SetPassword_samr_.patch new file mode 100644 index 0000000..a771e6e --- /dev/null +++ b/SOURCES/0022-s4-libnet-Use-GnuTLS-RC4-in-libnet_SetPassword_samr_.patch @@ -0,0 +1,72 @@ +From 5b0f5925814742ca8b7e772f1a7f4558b770c45b Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Fri, 1 Feb 2019 13:38:21 +0100 +Subject: [PATCH 022/187] s4:libnet: Use GnuTLS RC4 in + libnet_SetPassword_samr_handle_24() + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 18937f9ceb5aca23899555c5a34fe359f6fcb126) +--- + source4/libnet/libnet_passwd.c | 29 ++++++++++++++++++++++++++++- + 1 file changed, 28 insertions(+), 1 deletion(-) + +diff --git a/source4/libnet/libnet_passwd.c b/source4/libnet/libnet_passwd.c +index b2105121523..064ef98879a 100644 +--- a/source4/libnet/libnet_passwd.c ++++ b/source4/libnet/libnet_passwd.c +@@ -386,6 +386,9 @@ static NTSTATUS libnet_SetPassword_samr_handle_24(struct libnet_context *ctx, TA + struct samr_SetUserInfo2 sui; + union samr_UserInfo u_info; + DATA_BLOB session_key; ++ gnutls_cipher_hd_t cipher_hnd = NULL; ++ gnutls_datum_t enc_session_key; ++ int rc; + + if (r->samr_handle.in.info21) { + return NT_STATUS_INVALID_PARAMETER_MIX; +@@ -404,7 +407,28 @@ static NTSTATUS libnet_SetPassword_samr_handle_24(struct libnet_context *ctx, TA + return status; + } + +- arcfour_crypt_blob(u_info.info24.password.data, 516, &session_key); ++ enc_session_key = (gnutls_datum_t) { ++ .data = session_key.data, ++ .size = session_key.length, ++ }; ++ ++ rc = gnutls_cipher_init(&cipher_hnd, ++ GNUTLS_CIPHER_ARCFOUR_128, ++ &enc_session_key, ++ NULL); ++ if (rc < 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); ++ goto out; ++ } ++ ++ rc = gnutls_cipher_encrypt(cipher_hnd, ++ u_info.info24.password.data, ++ 516); ++ gnutls_cipher_deinit(cipher_hnd); ++ if (rc < 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); ++ goto out; ++ } + + sui.in.user_handle = r->samr_handle.in.user_handle; + sui.in.info = &u_info; +@@ -421,6 +445,9 @@ static NTSTATUS libnet_SetPassword_samr_handle_24(struct libnet_context *ctx, TA + "SetUserInfo2 level 24 for [%s] failed: %s", + r->samr_handle.in.account_name, nt_errstr(status)); + } ++ ++out: ++ data_blob_clear(&session_key); + return status; + } + +-- +2.23.0 + diff --git a/SOURCES/0023-s4-libnet-Use-GnuTLS-RC4-in-libnet_SetPassword_samr_.patch b/SOURCES/0023-s4-libnet-Use-GnuTLS-RC4-in-libnet_SetPassword_samr_.patch new file mode 100644 index 0000000..07b7252 --- /dev/null +++ b/SOURCES/0023-s4-libnet-Use-GnuTLS-RC4-in-libnet_SetPassword_samr_.patch @@ -0,0 +1,72 @@ +From e5e6605b40f80eee699f3fde275a620022979f05 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Fri, 1 Feb 2019 13:38:21 +0100 +Subject: [PATCH 023/187] s4:libnet: Use GnuTLS RC4 in + libnet_SetPassword_samr_handle_23() + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit cdb4e12765266ae767021d932870fbfcd55ccbf6) +--- + source4/libnet/libnet_passwd.c | 29 ++++++++++++++++++++++++++++- + 1 file changed, 28 insertions(+), 1 deletion(-) + +diff --git a/source4/libnet/libnet_passwd.c b/source4/libnet/libnet_passwd.c +index 064ef98879a..dce3813de38 100644 +--- a/source4/libnet/libnet_passwd.c ++++ b/source4/libnet/libnet_passwd.c +@@ -457,6 +457,9 @@ static NTSTATUS libnet_SetPassword_samr_handle_23(struct libnet_context *ctx, TA + struct samr_SetUserInfo2 sui; + union samr_UserInfo u_info; + DATA_BLOB session_key; ++ gnutls_cipher_hd_t cipher_hnd = NULL; ++ gnutls_datum_t _session_key; ++ int rc; + + if (!r->samr_handle.in.info21) { + return NT_STATUS_INVALID_PARAMETER_MIX; +@@ -477,7 +480,29 @@ static NTSTATUS libnet_SetPassword_samr_handle_23(struct libnet_context *ctx, TA + return status; + } + +- arcfour_crypt_blob(u_info.info23.password.data, 516, &session_key); ++ _session_key = (gnutls_datum_t) { ++ .data = session_key.data, ++ .size = session_key.length, ++ }; ++ ++ rc = gnutls_cipher_init(&cipher_hnd, ++ GNUTLS_CIPHER_ARCFOUR_128, ++ &_session_key, ++ NULL); ++ if (rc < 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); ++ goto out; ++ } ++ ++ rc = gnutls_cipher_encrypt(cipher_hnd, ++ u_info.info23.password.data, ++ 516); ++ data_blob_clear_free(&session_key); ++ gnutls_cipher_deinit(cipher_hnd); ++ if (rc < 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); ++ goto out; ++ } + + sui.in.user_handle = r->samr_handle.in.user_handle; + sui.in.info = &u_info; +@@ -494,6 +519,8 @@ static NTSTATUS libnet_SetPassword_samr_handle_23(struct libnet_context *ctx, TA + "SetUserInfo2 level 23 for [%s] failed: %s", + r->samr_handle.in.account_name, nt_errstr(status)); + } ++ ++out: + return status; + } + +-- +2.23.0 + diff --git a/SOURCES/0024-s4-libnet-Use-GnuTLS-RC4-in-libnet_ChangePassword_sa.patch b/SOURCES/0024-s4-libnet-Use-GnuTLS-RC4-in-libnet_ChangePassword_sa.patch new file mode 100644 index 0000000..772ffa7 --- /dev/null +++ b/SOURCES/0024-s4-libnet-Use-GnuTLS-RC4-in-libnet_ChangePassword_sa.patch @@ -0,0 +1,174 @@ +From 01c0b0ac77baae946d270d44d1c40dbdf17a8ee3 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Thu, 25 Jul 2019 15:15:46 +1200 +Subject: [PATCH 024/187] s4:libnet: Use GnuTLS RC4 in + libnet_ChangePassword_samr() + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Signed-off-by: Andrew Bartlett +Reviewed-by: Andrew Bartlett +(cherry picked from commit 9ea736590d9b22a7518f86b18e8c55b0d0e213d5) +--- + source4/libnet/libnet_passwd.c | 110 +++++++++++++++++++++++++++++++-- + 1 file changed, 104 insertions(+), 6 deletions(-) + +diff --git a/source4/libnet/libnet_passwd.c b/source4/libnet/libnet_passwd.c +index dce3813de38..704a94a5864 100644 +--- a/source4/libnet/libnet_passwd.c ++++ b/source4/libnet/libnet_passwd.c +@@ -20,7 +20,6 @@ + + #include "includes.h" + #include "libnet/libnet.h" +-#include "../lib/crypto/crypto.h" + #include "libcli/auth/libcli_auth.h" + #include "librpc/gen_ndr/ndr_samr_c.h" + #include "source4/librpc/rpc/dcerpc.h" +@@ -57,6 +56,16 @@ static NTSTATUS libnet_ChangePassword_samr(struct libnet_context *ctx, TALLOC_CT + uint8_t old_lm_hash[16], new_lm_hash[16]; + struct samr_DomInfo1 *dominfo = NULL; + struct userPwdChangeFailureInformation *reject = NULL; ++ gnutls_cipher_hd_t cipher_hnd = NULL; ++ gnutls_datum_t nt_session_key = { ++ .data = old_nt_hash, ++ .size = sizeof(old_nt_hash), ++ }; ++ gnutls_datum_t lm_session_key = { ++ .data = old_lm_hash, ++ .size = sizeof(old_lm_hash), ++ }; ++ int rc; + + ZERO_STRUCT(c); + +@@ -87,11 +96,47 @@ static NTSTATUS libnet_ChangePassword_samr(struct libnet_context *ctx, TALLOC_CT + + /* prepare samr_ChangePasswordUser3 */ + encode_pw_buffer(lm_pass.data, r->samr.in.newpassword, STR_UNICODE); +- arcfour_crypt(lm_pass.data, old_nt_hash, 516); ++ ++ rc = gnutls_cipher_init(&cipher_hnd, ++ GNUTLS_CIPHER_ARCFOUR_128, ++ &nt_session_key, ++ NULL); ++ if (rc < 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); ++ goto disconnect; ++ } ++ ++ rc = gnutls_cipher_encrypt(cipher_hnd, ++ lm_pass.data, ++ 516); ++ gnutls_cipher_deinit(cipher_hnd); ++ if (rc < 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); ++ goto disconnect; ++ } ++ + E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash); + + encode_pw_buffer(nt_pass.data, r->samr.in.newpassword, STR_UNICODE); +- arcfour_crypt(nt_pass.data, old_nt_hash, 516); ++ ++ rc = gnutls_cipher_init(&cipher_hnd, ++ GNUTLS_CIPHER_ARCFOUR_128, ++ &nt_session_key, ++ NULL); ++ if (rc < 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); ++ goto disconnect; ++ } ++ ++ rc = gnutls_cipher_encrypt(cipher_hnd, ++ nt_pass.data, ++ 516); ++ gnutls_cipher_deinit(cipher_hnd); ++ if (rc < 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); ++ goto disconnect; ++ } ++ + E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash); + + pw3.in.server = &server; +@@ -125,11 +170,46 @@ static NTSTATUS libnet_ChangePassword_samr(struct libnet_context *ctx, TALLOC_CT + + /* prepare samr_ChangePasswordUser2 */ + encode_pw_buffer(lm_pass.data, r->samr.in.newpassword, STR_ASCII|STR_TERMINATE); +- arcfour_crypt(lm_pass.data, old_lm_hash, 516); ++ ++ rc = gnutls_cipher_init(&cipher_hnd, ++ GNUTLS_CIPHER_ARCFOUR_128, ++ &lm_session_key, ++ NULL); ++ if (rc < 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); ++ goto disconnect; ++ } ++ ++ rc = gnutls_cipher_encrypt(cipher_hnd, ++ lm_pass.data, ++ 516); ++ gnutls_cipher_deinit(cipher_hnd); ++ if (rc < 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); ++ goto disconnect; ++ } ++ + E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash); + + encode_pw_buffer(nt_pass.data, r->samr.in.newpassword, STR_UNICODE); +- arcfour_crypt(nt_pass.data, old_nt_hash, 516); ++ ++ rc = gnutls_cipher_init(&cipher_hnd, ++ GNUTLS_CIPHER_ARCFOUR_128, ++ &nt_session_key, ++ NULL); ++ if (rc < 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); ++ goto disconnect; ++ } ++ rc = gnutls_cipher_encrypt(cipher_hnd, ++ nt_pass.data, ++ 516); ++ gnutls_cipher_deinit(cipher_hnd); ++ if (rc < 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); ++ goto disconnect; ++ } ++ + E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash); + + pw2.in.server = &server; +@@ -161,7 +241,25 @@ static NTSTATUS libnet_ChangePassword_samr(struct libnet_context *ctx, TALLOC_CT + a_account.string = r->samr.in.account_name; + + encode_pw_buffer(lm_pass.data, r->samr.in.newpassword, STR_ASCII); +- arcfour_crypt(lm_pass.data, old_lm_hash, 516); ++ ++ rc = gnutls_cipher_init(&cipher_hnd, ++ GNUTLS_CIPHER_ARCFOUR_128, ++ &lm_session_key, ++ NULL); ++ if (rc < 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); ++ goto disconnect; ++ } ++ ++ rc = gnutls_cipher_encrypt(cipher_hnd, ++ lm_pass.data, ++ 516); ++ gnutls_cipher_deinit(cipher_hnd); ++ if (rc < 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); ++ goto disconnect; ++ } ++ + E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash); + + oe2.in.server = &a_server; +-- +2.23.0 + diff --git a/SOURCES/0025-libcli-auth-Return-WERROR-for-encode_wkssvc_join_pas.patch b/SOURCES/0025-libcli-auth-Return-WERROR-for-encode_wkssvc_join_pas.patch new file mode 100644 index 0000000..0500388 --- /dev/null +++ b/SOURCES/0025-libcli-auth-Return-WERROR-for-encode_wkssvc_join_pas.patch @@ -0,0 +1,236 @@ +From 2d6f95107af7357d1084a4ba272f865c8249510a Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 29 May 2019 15:50:45 +0200 +Subject: [PATCH 025/187] libcli:auth: Return WERROR for + encode_wkssvc_join_password_buffer() + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 576bcf61555fb641b2919ad84a6b26b242b57061) +--- + libcli/auth/proto.h | 8 +++--- + libcli/auth/smbencrypt.c | 20 ++++++++++----- + source3/lib/netapi/joindomain.c | 44 +++++++++++++++++++++------------ + source4/torture/rpc/wkssvc.c | 20 ++++++++++++--- + 4 files changed, 62 insertions(+), 30 deletions(-) + +diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h +index 67caaca8c41..65ee06215dc 100644 +--- a/libcli/auth/proto.h ++++ b/libcli/auth/proto.h +@@ -207,10 +207,10 @@ bool set_pw_in_buffer(uint8_t buffer[516], const DATA_BLOB *password); + bool extract_pw_from_buffer(TALLOC_CTX *mem_ctx, + uint8_t in_buffer[516], DATA_BLOB *new_pass); + struct wkssvc_PasswordBuffer; +-void encode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, +- const char *pwd, +- DATA_BLOB *session_key, +- struct wkssvc_PasswordBuffer **pwd_buf); ++WERROR encode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, ++ const char *pwd, ++ DATA_BLOB *session_key, ++ struct wkssvc_PasswordBuffer **pwd_buf); + WERROR decode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, + struct wkssvc_PasswordBuffer *pwd_buf, + DATA_BLOB *session_key, +diff --git a/libcli/auth/smbencrypt.c b/libcli/auth/smbencrypt.c +index 793012553b2..745f47999cd 100644 +--- a/libcli/auth/smbencrypt.c ++++ b/libcli/auth/smbencrypt.c +@@ -965,10 +965,10 @@ bool extract_pw_from_buffer(TALLOC_CTX *mem_ctx, + * buffer), calling MD5Update() first with session_key and then with confounder + * (vice versa in samr) - Guenther */ + +-void encode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, +- const char *pwd, +- DATA_BLOB *session_key, +- struct wkssvc_PasswordBuffer **pwd_buf) ++WERROR encode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, ++ const char *pwd, ++ DATA_BLOB *session_key, ++ struct wkssvc_PasswordBuffer **pwd_buf) + { + uint8_t buffer[516]; + gnutls_hash_hd_t hash_hnd = NULL; +@@ -976,11 +976,12 @@ void encode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, + DATA_BLOB confounded_session_key; + int confounder_len = 8; + uint8_t confounder[8]; ++ WERROR werr; + int rc; + + my_pwd_buf = talloc_zero(mem_ctx, struct wkssvc_PasswordBuffer); + if (!my_pwd_buf) { +- return; ++ return WERR_NOT_ENOUGH_MEMORY; + } + + confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16); +@@ -991,17 +992,23 @@ void encode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, + + rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5); + if (rc < 0) { ++ werr = gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR); ++ + goto out; + } + + rc = gnutls_hash(hash_hnd, session_key->data, session_key->length); + if (rc < 0) { + gnutls_hash_deinit(hash_hnd, NULL); ++ werr = gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR); ++ + goto out; + } + rc = gnutls_hash(hash_hnd, confounder, confounder_len); + if (rc < 0) { + gnutls_hash_deinit(hash_hnd, NULL); ++ werr = gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR); ++ + goto out; + } + gnutls_hash_deinit(hash_hnd, confounded_session_key.data); +@@ -1017,8 +1024,9 @@ void encode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, + + *pwd_buf = my_pwd_buf; + ++ werr = WERR_OK; + out: +- return; ++ return werr; + } + + WERROR decode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, +diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c +index 8d0752f4531..f2d36fc00db 100644 +--- a/source3/lib/netapi/joindomain.c ++++ b/source3/lib/netapi/joindomain.c +@@ -137,10 +137,13 @@ WERROR NetJoinDomain_r(struct libnetapi_ctx *ctx, + goto done; + } + +- encode_wkssvc_join_password_buffer(ctx, +- r->in.password, +- &session_key, +- &encrypted_password); ++ werr = encode_wkssvc_join_password_buffer(ctx, ++ r->in.password, ++ &session_key, ++ &encrypted_password); ++ if (!W_ERROR_IS_OK(werr)) { ++ goto done; ++ } + } + + old_timeout = rpccli_set_timeout(pipe_cli, 600000); +@@ -279,10 +282,13 @@ WERROR NetUnjoinDomain_r(struct libnetapi_ctx *ctx, + goto done; + } + +- encode_wkssvc_join_password_buffer(ctx, +- r->in.password, +- &session_key, +- &encrypted_password); ++ werr = encode_wkssvc_join_password_buffer(ctx, ++ r->in.password, ++ &session_key, ++ &encrypted_password); ++ if (!W_ERROR_IS_OK(werr)) { ++ goto done; ++ } + } + + old_timeout = rpccli_set_timeout(pipe_cli, 60000); +@@ -484,10 +490,13 @@ WERROR NetGetJoinableOUs_r(struct libnetapi_ctx *ctx, + goto done; + } + +- encode_wkssvc_join_password_buffer(ctx, +- r->in.password, +- &session_key, +- &encrypted_password); ++ werr = encode_wkssvc_join_password_buffer(ctx, ++ r->in.password, ++ &session_key, ++ &encrypted_password); ++ if (!W_ERROR_IS_OK(werr)) { ++ goto done; ++ } + } + + status = dcerpc_wkssvc_NetrGetJoinableOus2(b, talloc_tos(), +@@ -537,10 +546,13 @@ WERROR NetRenameMachineInDomain_r(struct libnetapi_ctx *ctx, + goto done; + } + +- encode_wkssvc_join_password_buffer(ctx, +- r->in.password, +- &session_key, +- &encrypted_password); ++ werr = encode_wkssvc_join_password_buffer(ctx, ++ r->in.password, ++ &session_key, ++ &encrypted_password); ++ if (!W_ERROR_IS_OK(werr)) { ++ goto done; ++ } + } + + status = dcerpc_wkssvc_NetrRenameMachineInDomain2(b, talloc_tos(), +diff --git a/source4/torture/rpc/wkssvc.c b/source4/torture/rpc/wkssvc.c +index c98ac92b39b..4bc1f9cd0c7 100644 +--- a/source4/torture/rpc/wkssvc.c ++++ b/source4/torture/rpc/wkssvc.c +@@ -1199,6 +1199,7 @@ static bool test_NetrJoinDomain2(struct torture_context *tctx, + enum wkssvc_NetJoinStatus join_status; + const char *join_name = NULL; + WERROR expected_err; ++ WERROR werr; + DATA_BLOB session_key; + struct dcerpc_binding_handle *b = p->binding_handle; + +@@ -1240,8 +1241,13 @@ static bool test_NetrJoinDomain2(struct torture_context *tctx, + return false; + } + +- encode_wkssvc_join_password_buffer(tctx, domain_admin_password, +- &session_key, &pwd_buf); ++ werr = encode_wkssvc_join_password_buffer(tctx, ++ domain_admin_password, ++ &session_key, ++ &pwd_buf); ++ if (!W_ERROR_IS_OK(werr)) { ++ return false; ++ } + + r.in.server_name = dcerpc_server_name(p); + r.in.domain_name = domain_name; +@@ -1284,6 +1290,7 @@ static bool test_NetrUnjoinDomain2(struct torture_context *tctx, + enum wkssvc_NetJoinStatus join_status; + const char *join_name = NULL; + WERROR expected_err; ++ WERROR werr; + DATA_BLOB session_key; + struct dcerpc_binding_handle *b = p->binding_handle; + +@@ -1322,8 +1329,13 @@ static bool test_NetrUnjoinDomain2(struct torture_context *tctx, + return false; + } + +- encode_wkssvc_join_password_buffer(tctx, domain_admin_password, +- &session_key, &pwd_buf); ++ werr = encode_wkssvc_join_password_buffer(tctx, ++ domain_admin_password, ++ &session_key, ++ &pwd_buf); ++ if (!W_ERROR_IS_OK(werr)) { ++ return false; ++ } + + r.in.server_name = dcerpc_server_name(p); + r.in.account = domain_admin_account; +-- +2.23.0 + diff --git a/SOURCES/0026-libcli-auth-Add-test-for-encode-decode-_wkssvc_join_.patch b/SOURCES/0026-libcli-auth-Add-test-for-encode-decode-_wkssvc_join_.patch new file mode 100644 index 0000000..77ecc50 --- /dev/null +++ b/SOURCES/0026-libcli-auth-Add-test-for-encode-decode-_wkssvc_join_.patch @@ -0,0 +1,172 @@ +From 32004f3011bb6bb45f21d39c6e2830a47ec43f3e Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Mon, 8 Jul 2019 17:36:58 +0200 +Subject: [PATCH 026/187] libcli:auth: Add test for + (encode|decode)_wkssvc_join_password_buffer + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit f4a16bfba8d87de883d3d2e54cdc825fc5e01c2b) +--- + libcli/auth/tests/test_rc4_passwd_buffer.c | 129 +++++++++++++++++++++ + 1 file changed, 129 insertions(+) + +diff --git a/libcli/auth/tests/test_rc4_passwd_buffer.c b/libcli/auth/tests/test_rc4_passwd_buffer.c +index db6ca3f3f4c..6d97ac6e2f7 100644 +--- a/libcli/auth/tests/test_rc4_passwd_buffer.c ++++ b/libcli/auth/tests/test_rc4_passwd_buffer.c +@@ -99,6 +99,76 @@ static const uint8_t encrypted_test_blob[] = { + 0x15, 0x13, 0xdc, 0x15, + }; + ++ ++static const uint8_t encrypted_wkssvc_test_blob[] = { ++ 0x13, 0x79, 0x1f, 0x1a, 0x02, 0x15, 0x72, 0x1c, ++ 0xa6, 0x26, 0x37, 0xeb, 0x1d, 0x41, 0x7f, 0x76, ++ 0x11, 0x3f, 0x49, 0x4c, 0xf9, 0x69, 0x17, 0xc8, ++ 0x90, 0x92, 0x53, 0xb9, 0x3f, 0xcd, 0x06, 0xfe, ++ 0x5c, 0x17, 0x82, 0xbd, 0x86, 0xab, 0x49, 0xee, ++ 0x61, 0x76, 0x55, 0xc0, 0x10, 0x51, 0xcd, 0xd9, ++ 0x6f, 0x12, 0x86, 0xc6, 0x19, 0x59, 0x9a, 0x2f, ++ 0x27, 0x1d, 0x99, 0x30, 0x60, 0x0d, 0x65, 0xc6, ++ 0x43, 0xd6, 0xda, 0x6b, 0x66, 0x95, 0xd4, 0xca, ++ 0xf5, 0x04, 0xf7, 0x01, 0x5a, 0x55, 0xb0, 0x5e, ++ 0x72, 0x8a, 0x75, 0xe5, 0x33, 0x4c, 0xd8, 0xc4, ++ 0x0e, 0xf4, 0x6d, 0x23, 0xdd, 0x05, 0x90, 0xff, ++ 0xe0, 0x91, 0x7b, 0x62, 0x86, 0xee, 0x78, 0x31, ++ 0x07, 0xad, 0x8b, 0xf9, 0xdf, 0x6f, 0x8b, 0xbd, ++ 0x15, 0xde, 0x1b, 0xae, 0x84, 0x68, 0xe5, 0x41, ++ 0x7a, 0xe3, 0x47, 0x99, 0xba, 0x61, 0xe5, 0x51, ++ 0x64, 0x9a, 0xa0, 0x41, 0x44, 0xa1, 0x3a, 0x52, ++ 0x59, 0x7d, 0x6c, 0xcf, 0xcc, 0xf0, 0x11, 0xbc, ++ 0xb7, 0x51, 0xa9, 0xd8, 0xfd, 0xbf, 0x58, 0x77, ++ 0x28, 0x86, 0xa1, 0x27, 0x94, 0xe5, 0xf6, 0x1a, ++ 0x6b, 0x76, 0xf7, 0x72, 0x6e, 0x17, 0x09, 0xd8, ++ 0x3c, 0x6f, 0x39, 0x91, 0xea, 0x48, 0x98, 0xdc, ++ 0x1d, 0x50, 0x2e, 0x02, 0x6e, 0x7f, 0x80, 0x5d, ++ 0x6e, 0x96, 0xe1, 0xcf, 0x8b, 0x6b, 0xb6, 0xed, ++ 0xb4, 0x6a, 0x08, 0xd2, 0x45, 0x09, 0x88, 0x86, ++ 0x32, 0x58, 0xd8, 0x5e, 0x33, 0x8c, 0x29, 0x1a, ++ 0x8f, 0xc5, 0x54, 0x9b, 0xa8, 0x32, 0xb2, 0xc1, ++ 0x72, 0x14, 0x6c, 0x5d, 0x9d, 0xd3, 0xf2, 0x6c, ++ 0x6e, 0xa4, 0x84, 0x52, 0x26, 0x73, 0x7a, 0x30, ++ 0x56, 0x75, 0xef, 0xd1, 0x9d, 0xcd, 0xb7, 0x87, ++ 0xa9, 0x5c, 0xaf, 0xe6, 0xda, 0x1d, 0x3c, 0x9c, ++ 0xa3, 0xb1, 0x03, 0xb0, 0x8e, 0xf6, 0xc8, 0x8f, ++ 0x57, 0x1c, 0xce, 0x05, 0x54, 0x99, 0xf1, 0xf9, ++ 0x35, 0xe6, 0xf7, 0x67, 0x94, 0xb2, 0x67, 0x5b, ++ 0xe7, 0xa0, 0xa2, 0x1e, 0xa2, 0x74, 0xd3, 0x99, ++ 0x9c, 0xd5, 0xd9, 0x90, 0x86, 0x24, 0x0e, 0x1a, ++ 0x0d, 0xc8, 0x9e, 0x68, 0x4c, 0x43, 0x2f, 0x42, ++ 0xb1, 0x7c, 0xce, 0x1e, 0xb6, 0xac, 0x56, 0xb0, ++ 0x8d, 0x93, 0xf1, 0x53, 0x7d, 0x0e, 0x00, 0x46, ++ 0xba, 0x2e, 0x14, 0x7a, 0x0b, 0xaa, 0xcb, 0x07, ++ 0x9b, 0x09, 0x05, 0xa0, 0xd3, 0xa1, 0x80, 0xc2, ++ 0xd3, 0x59, 0x92, 0x27, 0x66, 0x1f, 0xdd, 0x76, ++ 0x36, 0xb3, 0x3c, 0xeb, 0xd7, 0x61, 0x94, 0xb1, ++ 0xf8, 0x3a, 0xe0, 0xba, 0x91, 0x0f, 0xef, 0x72, ++ 0x2b, 0x26, 0xc6, 0xb8, 0x6d, 0x0b, 0xdb, 0x60, ++ 0xf8, 0xb4, 0x98, 0xd7, 0x8b, 0x8d, 0xfb, 0xa7, ++ 0x4e, 0x27, 0xeb, 0x00, 0xe8, 0xf7, 0x5a, 0xec, ++ 0xf5, 0x60, 0x28, 0x37, 0xb2, 0xc4, 0x13, 0x48, ++ 0x2a, 0xe1, 0x34, 0xb2, 0x53, 0xcb, 0x44, 0x34, ++ 0x08, 0x7e, 0x56, 0x5c, 0x2b, 0x9b, 0xe2, 0xca, ++ 0x90, 0xb0, 0x57, 0xee, 0x10, 0x88, 0x39, 0x84, ++ 0xc6, 0x66, 0x07, 0x50, 0x63, 0xcc, 0x2a, 0x7c, ++ 0x99, 0x8c, 0x05, 0xf9, 0xf0, 0xb8, 0x62, 0xf0, ++ 0x92, 0xf7, 0x2a, 0x4a, 0x17, 0x14, 0x78, 0xa1, ++ 0x71, 0xb6, 0x42, 0xf0, 0x87, 0xa8, 0xa4, 0x48, ++ 0xeb, 0xdb, 0xed, 0x8a, 0x15, 0x19, 0x1a, 0xd9, ++ 0xfe, 0x6f, 0x07, 0x93, 0x5d, 0x39, 0xe8, 0x0e, ++ 0x47, 0xe6, 0x7a, 0x7d, 0x52, 0x2e, 0x40, 0x6f, ++ 0x31, 0x1b, 0xf6, 0x0c, 0xc2, 0x83, 0xae, 0xc1, ++ 0xf0, 0xf5, 0x71, 0xcd, 0xe2, 0xf5, 0x19, 0xb6, ++ 0xd8, 0xb0, 0x4d, 0xa9, 0x51, 0x1c, 0xb4, 0xaf, ++ 0x69, 0x9a, 0x89, 0xb6, 0x5b, 0x4d, 0xfa, 0x1b, ++ 0xca, 0xc8, 0x61, 0x92, 0x3a, 0xd6, 0x76, 0xad, ++ 0x5d, 0xa6, 0x17, 0x60, 0x3e, 0xea, 0x94, 0xcf, ++ 0x6d, 0x1b, 0x98, 0x5c, 0x19, 0x9e, 0x4e, 0xd3, ++ 0x21, 0x55, 0xda, 0xe3, ++}; ++ + static void torture_decode_rc4_passwd_buffer(void **state) + { + char *password_decoded = NULL; +@@ -187,6 +257,63 @@ static void torture_endode_decode_rc4_passwd_buffer(void **state) + talloc_free(password_decoded); + } + ++static void torture_decode_wkssvc_join_password_buffer(void **state) ++{ ++ DATA_BLOB session_key = data_blob_const("SystemLibraryDTC", 16); ++ struct wkssvc_PasswordBuffer pwd_buf = { ++ .data = {0}, ++ }; ++ char *password_decoded = NULL; ++ TALLOC_CTX *mem_ctx = NULL; ++ WERROR werr; ++ ++ mem_ctx = talloc_new(NULL); ++ assert_non_null(mem_ctx); ++ ++ memcpy(pwd_buf.data, ++ encrypted_wkssvc_test_blob, ++ sizeof(pwd_buf.data)); ++ ++ werr = decode_wkssvc_join_password_buffer(mem_ctx, ++ &pwd_buf, ++ &session_key, ++ &password_decoded); ++ assert_true(W_ERROR_IS_OK(werr)); ++ assert_non_null(password_decoded); ++ assert_string_equal(password_decoded, PASSWORD); ++ ++ TALLOC_FREE(mem_ctx); ++} ++ ++static void torture_wkssvc_join_password_buffer(void **state) ++{ ++ DATA_BLOB session_key = data_blob_const("SystemLibraryDTC", 16); ++ struct wkssvc_PasswordBuffer *pwd_buf = NULL; ++ char *password_decoded = NULL; ++ TALLOC_CTX *mem_ctx = NULL; ++ WERROR werr; ++ ++ mem_ctx = talloc_new(NULL); ++ assert_non_null(mem_ctx); ++ ++ werr = encode_wkssvc_join_password_buffer(mem_ctx, ++ PASSWORD, ++ &session_key, ++ &pwd_buf); ++ assert_true(W_ERROR_IS_OK(werr)); ++ assert_non_null(pwd_buf); ++ ++ werr = decode_wkssvc_join_password_buffer(mem_ctx, ++ pwd_buf, ++ &session_key, ++ &password_decoded); ++ assert_true(W_ERROR_IS_OK(werr)); ++ assert_non_null(password_decoded); ++ assert_string_equal(password_decoded, PASSWORD); ++ ++ TALLOC_FREE(mem_ctx); ++} ++ + int main(int argc, char *argv[]) + { + int rc; +@@ -194,6 +321,8 @@ int main(int argc, char *argv[]) + cmocka_unit_test(torture_decode_rc4_passwd_buffer), + cmocka_unit_test(torture_rc4_passwd_buffer), + cmocka_unit_test(torture_endode_decode_rc4_passwd_buffer), ++ cmocka_unit_test(torture_decode_wkssvc_join_password_buffer), ++ cmocka_unit_test(torture_wkssvc_join_password_buffer), + }; + + if (argc == 2) { +-- +2.23.0 + diff --git a/SOURCES/0027-libcli-auth-Use-samba_gnutls_arcfour_confounded_md5-.patch b/SOURCES/0027-libcli-auth-Use-samba_gnutls_arcfour_confounded_md5-.patch new file mode 100644 index 0000000..c9baa44 --- /dev/null +++ b/SOURCES/0027-libcli-auth-Use-samba_gnutls_arcfour_confounded_md5-.patch @@ -0,0 +1,111 @@ +From cbabf1224f61900eb96ea15841950c26b8b88cb5 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Mon, 8 Jul 2019 18:03:00 +0200 +Subject: [PATCH 027/187] libcli:auth: Use + samba_gnutls_arcfour_confounded_md5() in encode_wkssvc_join_password_buffer() + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 85e2a3c96ad9acc1a85db189f6418c9d880b4718) +--- + libcli/auth/smbencrypt.c | 69 ++++++++++++++-------------------------- + 1 file changed, 23 insertions(+), 46 deletions(-) + +diff --git a/libcli/auth/smbencrypt.c b/libcli/auth/smbencrypt.c +index 745f47999cd..823e16a3387 100644 +--- a/libcli/auth/smbencrypt.c ++++ b/libcli/auth/smbencrypt.c +@@ -968,65 +968,42 @@ bool extract_pw_from_buffer(TALLOC_CTX *mem_ctx, + WERROR encode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, + const char *pwd, + DATA_BLOB *session_key, +- struct wkssvc_PasswordBuffer **pwd_buf) ++ struct wkssvc_PasswordBuffer **out_pwd_buf) + { +- uint8_t buffer[516]; +- gnutls_hash_hd_t hash_hnd = NULL; +- struct wkssvc_PasswordBuffer *my_pwd_buf = NULL; +- DATA_BLOB confounded_session_key; +- int confounder_len = 8; +- uint8_t confounder[8]; +- WERROR werr; ++ struct wkssvc_PasswordBuffer *pwd_buf = NULL; ++ uint8_t _confounder[8] = {0}; ++ DATA_BLOB confounder = data_blob_const(_confounder, 8); ++ uint8_t pwbuf[516] = {0}; ++ DATA_BLOB encrypt_pwbuf = data_blob_const(pwbuf, 516); + int rc; + +- my_pwd_buf = talloc_zero(mem_ctx, struct wkssvc_PasswordBuffer); +- if (!my_pwd_buf) { ++ pwd_buf = talloc_zero(mem_ctx, struct wkssvc_PasswordBuffer); ++ if (pwd_buf == NULL) { + return WERR_NOT_ENOUGH_MEMORY; + } + +- confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16); +- +- encode_pw_buffer(buffer, pwd, STR_UNICODE); ++ encode_pw_buffer(pwbuf, pwd, STR_UNICODE); + +- generate_random_buffer((uint8_t *)confounder, confounder_len); +- +- rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5); +- if (rc < 0) { +- werr = gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR); +- +- goto out; +- } +- +- rc = gnutls_hash(hash_hnd, session_key->data, session_key->length); +- if (rc < 0) { +- gnutls_hash_deinit(hash_hnd, NULL); +- werr = gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR); ++ generate_random_buffer(_confounder, sizeof(_confounder)); + +- goto out; +- } +- rc = gnutls_hash(hash_hnd, confounder, confounder_len); ++ rc = samba_gnutls_arcfour_confounded_md5(session_key, ++ &confounder, ++ &encrypt_pwbuf, ++ SAMBA_GNUTLS_ENCRYPT); + if (rc < 0) { +- gnutls_hash_deinit(hash_hnd, NULL); +- werr = gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR); +- +- goto out; ++ ZERO_ARRAY(_confounder); ++ TALLOC_FREE(pwd_buf); ++ return gnutls_error_to_werror(rc, WERR_CONTENT_BLOCKED); + } +- gnutls_hash_deinit(hash_hnd, confounded_session_key.data); + +- arcfour_crypt_blob(buffer, 516, &confounded_session_key); +- +- memcpy(&my_pwd_buf->data[0], confounder, confounder_len); +- ZERO_ARRAY(confounder); +- memcpy(&my_pwd_buf->data[8], buffer, 516); +- ZERO_ARRAY(buffer); +- +- data_blob_clear_free(&confounded_session_key); ++ memcpy(&pwd_buf->data[0], confounder.data, confounder.length); ++ ZERO_ARRAY(_confounder); ++ memcpy(&pwd_buf->data[8], encrypt_pwbuf.data, encrypt_pwbuf.length); ++ ZERO_ARRAY(pwbuf); + +- *pwd_buf = my_pwd_buf; ++ *out_pwd_buf = pwd_buf; + +- werr = WERR_OK; +-out: +- return werr; ++ return WERR_OK; + } + + WERROR decode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, +-- +2.23.0 + diff --git a/SOURCES/0028-libcli-auth-Use-samba_gnutls_arcfour_confounded_md5-.patch b/SOURCES/0028-libcli-auth-Use-samba_gnutls_arcfour_confounded_md5-.patch new file mode 100644 index 0000000..1fdb6bd --- /dev/null +++ b/SOURCES/0028-libcli-auth-Use-samba_gnutls_arcfour_confounded_md5-.patch @@ -0,0 +1,117 @@ +From 0d2898429e7eb2ca144885d5a1f9485cca620464 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Mon, 8 Jul 2019 18:21:18 +0200 +Subject: [PATCH 028/187] libcli:auth: Use + samba_gnutls_arcfour_confounded_md5() in decode_wkssvc_join_password_buffer() + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit bcf7808d3aa8a5932a40955e4b764f55061e07d7) +--- + libcli/auth/smbencrypt.c | 71 ++++++++++++++-------------------------- + 1 file changed, 24 insertions(+), 47 deletions(-) + +diff --git a/libcli/auth/smbencrypt.c b/libcli/auth/smbencrypt.c +index 823e16a3387..cc5e1fbb899 100644 +--- a/libcli/auth/smbencrypt.c ++++ b/libcli/auth/smbencrypt.c +@@ -1011,70 +1011,47 @@ WERROR decode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, + DATA_BLOB *session_key, + char **pwd) + { +- gnutls_hash_hd_t hash_hnd = NULL; +- uint8_t buffer[516]; +- size_t pwd_len; +- WERROR result; ++ uint8_t _confounder[8]; ++ DATA_BLOB confounder = data_blob_const(_confounder, 8); ++ uint8_t pwbuf[516] = {0}; ++ DATA_BLOB decrypt_pwbuf = data_blob_const(pwbuf, 516); + bool ok; + int rc; + +- DATA_BLOB confounded_session_key; +- +- int confounder_len = 8; +- uint8_t confounder[8]; +- +- *pwd = NULL; +- +- if (!pwd_buf) { ++ if (pwd_buf == NULL) { + return WERR_INVALID_PASSWORD; + } + ++ *pwd = NULL; ++ + if (session_key->length != 16) { + DEBUG(10,("invalid session key\n")); + return WERR_INVALID_PASSWORD; + } + +- confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16); ++ confounder = data_blob_const(&pwd_buf->data[0], 8); ++ memcpy(&pwbuf, &pwd_buf->data[8], 516); + +- memcpy(&confounder, &pwd_buf->data[0], confounder_len); +- memcpy(&buffer, &pwd_buf->data[8], 516); +- +- rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5); +- if (rc < 0) { +- result = gnutls_error_to_werror(rc, WERR_CONTENT_BLOCKED); +- goto out; +- } +- +- rc = gnutls_hash(hash_hnd, session_key->data, session_key->length); +- if (rc < 0) { +- gnutls_hash_deinit(hash_hnd, NULL); +- result = gnutls_error_to_werror(rc, WERR_CONTENT_BLOCKED); +- goto out; +- } +- rc = gnutls_hash(hash_hnd, confounder, confounder_len); ++ rc = samba_gnutls_arcfour_confounded_md5(session_key, ++ &confounder, ++ &decrypt_pwbuf, ++ SAMBA_GNUTLS_ENCRYPT); + if (rc < 0) { +- gnutls_hash_deinit(hash_hnd, NULL); +- result = gnutls_error_to_werror(rc, WERR_CONTENT_BLOCKED); +- goto out; ++ ZERO_ARRAY(_confounder); ++ TALLOC_FREE(pwd_buf); ++ return gnutls_error_to_werror(rc, WERR_CONTENT_BLOCKED); + } +- gnutls_hash_deinit(hash_hnd, confounded_session_key.data); + +- arcfour_crypt_blob(buffer, 516, &confounded_session_key); +- +- ok = decode_pw_buffer(mem_ctx, buffer, pwd, &pwd_len, CH_UTF16); +- +- ZERO_ARRAY(confounder); +- ZERO_ARRAY(buffer); +- +- data_blob_clear_free(&confounded_session_key); ++ ok = decode_pw_buffer(mem_ctx, ++ decrypt_pwbuf.data, ++ pwd, ++ &decrypt_pwbuf.length, ++ CH_UTF16); ++ ZERO_ARRAY(pwbuf); + + if (!ok) { +- result = WERR_INVALID_PASSWORD; +- goto out; ++ return WERR_INVALID_PASSWORD; + } + +- result = WERR_OK; +-out: +- return result; ++ return WERR_OK; + } +- +-- +2.23.0 + diff --git a/SOURCES/0029-auth-ntlmssp-Use-GnuTLS-RC4-in-ntlmssp-client.patch b/SOURCES/0029-auth-ntlmssp-Use-GnuTLS-RC4-in-ntlmssp-client.patch new file mode 100644 index 0000000..3eb4f73 --- /dev/null +++ b/SOURCES/0029-auth-ntlmssp-Use-GnuTLS-RC4-in-ntlmssp-client.patch @@ -0,0 +1,66 @@ +From ba125c495c950570017d84b1cb2a223679250961 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Fri, 9 Nov 2018 12:29:55 +0100 +Subject: [PATCH 029/187] auth:ntlmssp: Use GnuTLS RC4 in ntlmssp client + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit cb4025a50232f24139f21d87e50b6e6ea69238ba) +--- + auth/ntlmssp/ntlmssp_client.c | 28 +++++++++++++++++++++++++++- + 1 file changed, 27 insertions(+), 1 deletion(-) + +diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c +index df891f8d933..b8d1190466b 100644 +--- a/auth/ntlmssp/ntlmssp_client.c ++++ b/auth/ntlmssp/ntlmssp_client.c +@@ -690,17 +690,43 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { + /* Make up a new session key */ + uint8_t client_session_key[16]; ++ gnutls_cipher_hd_t cipher_hnd; ++ gnutls_datum_t enc_session_key = { ++ .data = session_key.data, ++ .size = session_key.length, ++ }; ++ + generate_secret_buffer(client_session_key, sizeof(client_session_key)); + + /* Encrypt the new session key with the old one */ + encrypted_session_key = data_blob_talloc(ntlmssp_state, + client_session_key, sizeof(client_session_key)); + dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length); +- arcfour_crypt(encrypted_session_key.data, session_key.data, encrypted_session_key.length); ++ ++ rc = gnutls_cipher_init(&cipher_hnd, ++ GNUTLS_CIPHER_ARCFOUR_128, ++ &enc_session_key, ++ NULL); ++ if (rc < 0) { ++ nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED); ++ ZERO_ARRAY(client_session_key); ++ goto done; ++ } ++ rc = gnutls_cipher_encrypt(cipher_hnd, ++ encrypted_session_key.data, ++ encrypted_session_key.length); ++ gnutls_cipher_deinit(cipher_hnd); ++ if (rc < 0) { ++ nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED); ++ ZERO_ARRAY(client_session_key); ++ goto done; ++ } ++ + dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length); + + /* Mark the new session key as the 'real' session key */ + session_key = data_blob_talloc(mem_ctx, client_session_key, sizeof(client_session_key)); ++ ZERO_ARRAY(client_session_key); + } + + /* this generates the actual auth packet */ +-- +2.23.0 + diff --git a/SOURCES/0030-auth-ntlmssp-Use-GnuTLS-RC4-for-ntlmssp-signing.patch b/SOURCES/0030-auth-ntlmssp-Use-GnuTLS-RC4-for-ntlmssp-signing.patch new file mode 100644 index 0000000..34d448c --- /dev/null +++ b/SOURCES/0030-auth-ntlmssp-Use-GnuTLS-RC4-for-ntlmssp-signing.patch @@ -0,0 +1,411 @@ +From 73f0d5f5a62edbcfeb8f79fffa422416b83edf3e Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Thu, 6 Dec 2018 18:11:14 +0100 +Subject: [PATCH 030/187] auth:ntlmssp: Use GnuTLS RC4 for ntlmssp signing + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 7bd502dcdb44c7d0f8a56b2ba489ae8cf2b886bd) +--- + auth/ntlmssp/ntlmssp_private.h | 5 +- + auth/ntlmssp/ntlmssp_sign.c | 212 ++++++++++++++++++++++++++------- + 2 files changed, 174 insertions(+), 43 deletions(-) + +diff --git a/auth/ntlmssp/ntlmssp_private.h b/auth/ntlmssp/ntlmssp_private.h +index 95ec6374f51..4d84e3347b6 100644 +--- a/auth/ntlmssp/ntlmssp_private.h ++++ b/auth/ntlmssp/ntlmssp_private.h +@@ -20,14 +20,15 @@ + + /* For structures internal to the NTLMSSP implementation that should not be exposed */ + +-#include "../lib/crypto/arcfour.h" ++#include ++#include + + struct auth_session_info; + + struct ntlmssp_crypt_direction { + uint32_t seq_num; + uint8_t sign_key[16]; +- struct arcfour_state seal_state; ++ gnutls_cipher_hd_t seal_state; + }; + + union ntlmssp_crypt_state { +diff --git a/auth/ntlmssp/ntlmssp_sign.c b/auth/ntlmssp/ntlmssp_sign.c +index 8ba2e246b34..89f1aa04f7a 100644 +--- a/auth/ntlmssp/ntlmssp_sign.c ++++ b/auth/ntlmssp/ntlmssp_sign.c +@@ -47,9 +47,9 @@ + */ + + static void dump_arc4_state(const char *description, +- struct arcfour_state *state) ++ gnutls_cipher_hd_t *state) + { +- dump_data_pw(description, state->sbox, sizeof(state->sbox)); ++ DBG_DEBUG("%s\n", description); + } + + static NTSTATUS calc_ntlmv2_key(uint8_t subkey[16], +@@ -90,13 +90,13 @@ static NTSTATUS ntlmssp_make_packet_signature(struct ntlmssp_state *ntlmssp_stat + enum ntlmssp_direction direction, + DATA_BLOB *sig, bool encrypt_sig) + { +- NTSTATUS status; ++ NTSTATUS status = NT_STATUS_UNSUCCESSFUL; ++ int rc; + + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { + gnutls_hmac_hd_t hmac_hnd = NULL; + uint8_t digest[16]; + uint8_t seq_num[4]; +- int rc; + + *sig = data_blob_talloc(sig_mem_ctx, NULL, NTLMSSP_SIG_SIZE); + if (!sig->data) { +@@ -158,14 +158,24 @@ static NTSTATUS ntlmssp_make_packet_signature(struct ntlmssp_state *ntlmssp_stat + if (encrypt_sig && (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) { + switch (direction) { + case NTLMSSP_SEND: +- arcfour_crypt_sbox(&ntlmssp_state->crypt->ntlm2.sending.seal_state, +- digest, 8); ++ rc = gnutls_cipher_encrypt(ntlmssp_state->crypt->ntlm2.sending.seal_state, ++ digest, ++ 8); + break; + case NTLMSSP_RECEIVE: +- arcfour_crypt_sbox(&ntlmssp_state->crypt->ntlm2.receiving.seal_state, +- digest, 8); ++ rc = gnutls_cipher_encrypt(ntlmssp_state->crypt->ntlm2.receiving.seal_state, ++ digest, ++ 8); + break; + } ++ if (rc < 0) { ++ DBG_ERR("gnutls_cipher_encrypt for NTLMv2 EXCH " ++ "%s packet signature failed: %s\n", ++ direction == NTLMSSP_SEND ? ++ "send" : "receive", ++ gnutls_strerror(rc)); ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED); ++ } + } + + SIVAL(sig->data, 0, NTLMSSP_SIGN_VERSION); +@@ -194,8 +204,15 @@ static NTSTATUS ntlmssp_make_packet_signature(struct ntlmssp_state *ntlmssp_stat + + dump_arc4_state("ntlmssp hash: \n", + &ntlmssp_state->crypt->ntlm.seal_state); +- arcfour_crypt_sbox(&ntlmssp_state->crypt->ntlm.seal_state, +- sig->data+4, sig->length-4); ++ rc = gnutls_cipher_encrypt(ntlmssp_state->crypt->ntlm.seal_state, ++ sig->data + 4, ++ sig->length - 4); ++ if (rc < 0) { ++ DBG_ERR("gnutls_cipher_encrypt for NTLM packet " ++ "signature failed: %s\n", ++ gnutls_strerror(rc)); ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED); ++ } + } + + return NT_STATUS_OK; +@@ -317,6 +334,8 @@ NTSTATUS ntlmssp_seal_packet(struct ntlmssp_state *ntlmssp_state, + const uint8_t *whole_pdu, size_t pdu_length, + DATA_BLOB *sig) + { ++ int rc; ++ + if (!(ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) { + DEBUG(3, ("NTLMSSP Sealing not negotiated - cannot seal packet!\n")); + return NT_STATUS_INVALID_PARAMETER; +@@ -353,11 +372,25 @@ NTSTATUS ntlmssp_seal_packet(struct ntlmssp_state *ntlmssp_state, + return nt_status; + } + +- arcfour_crypt_sbox(&ntlmssp_state->crypt->ntlm2.sending.seal_state, +- data, length); ++ rc = gnutls_cipher_encrypt(ntlmssp_state->crypt->ntlm2.sending.seal_state, ++ data, ++ length); ++ if (rc < 0) { ++ DBG_ERR("gnutls_cipher_encrypt ntlmv2 sealing the data " ++ "failed: %s\n", ++ gnutls_strerror(rc)); ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED); ++ } + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { +- arcfour_crypt_sbox(&ntlmssp_state->crypt->ntlm2.sending.seal_state, +- sig->data+4, 8); ++ rc = gnutls_cipher_encrypt(ntlmssp_state->crypt->ntlm2.sending.seal_state, ++ sig->data + 4, ++ 8); ++ if (rc < 0) { ++ DBG_ERR("gnutls_cipher_encrypt ntlmv2 sealing " ++ "the EXCH signature data failed: %s\n", ++ gnutls_strerror(rc)); ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED); ++ } + } + } else { + NTSTATUS status; +@@ -381,17 +414,30 @@ NTSTATUS ntlmssp_seal_packet(struct ntlmssp_state *ntlmssp_state, + * is not constant, but is is rather updated with + * each iteration + */ +- + dump_arc4_state("ntlmv1 arc4 state:\n", + &ntlmssp_state->crypt->ntlm.seal_state); +- arcfour_crypt_sbox(&ntlmssp_state->crypt->ntlm.seal_state, +- data, length); ++ rc = gnutls_cipher_encrypt(ntlmssp_state->crypt->ntlm.seal_state, ++ data, ++ length); ++ if (rc < 0) { ++ DBG_ERR("gnutls_cipher_encrypt ntlmv1 sealing data" ++ "failed: %s\n", ++ gnutls_strerror(rc)); ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED); ++ } + + dump_arc4_state("ntlmv1 arc4 state:\n", + &ntlmssp_state->crypt->ntlm.seal_state); + +- arcfour_crypt_sbox(&ntlmssp_state->crypt->ntlm.seal_state, +- sig->data+4, sig->length-4); ++ rc = gnutls_cipher_encrypt(ntlmssp_state->crypt->ntlm.seal_state, ++ sig->data + 4, ++ sig->length - 4); ++ if (rc < 0) { ++ DBG_ERR("gnutls_cipher_encrypt ntlmv1 sealing signing " ++ "data failed: %s\n", ++ gnutls_strerror(rc)); ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED); ++ } + + ntlmssp_state->crypt->ntlm.seq_num++; + } +@@ -412,6 +458,8 @@ NTSTATUS ntlmssp_unseal_packet(struct ntlmssp_state *ntlmssp_state, + const DATA_BLOB *sig) + { + NTSTATUS status; ++ int rc; ++ + if (!ntlmssp_state->session_key.length) { + DEBUG(3, ("NO session key, cannot unseal packet\n")); + return NT_STATUS_NO_USER_SESSION_KEY; +@@ -422,14 +470,29 @@ NTSTATUS ntlmssp_unseal_packet(struct ntlmssp_state *ntlmssp_state, + + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { + /* First unseal the data. */ +- arcfour_crypt_sbox(&ntlmssp_state->crypt->ntlm2.receiving.seal_state, +- data, length); ++ rc = gnutls_cipher_decrypt(ntlmssp_state->crypt->ntlm2.receiving.seal_state, ++ data, ++ length); ++ if (rc < 0) { ++ DBG_ERR("gnutls_cipher_decrypt ntlmv2 unsealing the " ++ "data failed: %s\n", ++ gnutls_strerror(rc)); ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED); ++ } + dump_data_pw("ntlmv2 clear data\n", data, length); + } else { +- arcfour_crypt_sbox(&ntlmssp_state->crypt->ntlm.seal_state, +- data, length); ++ rc = gnutls_cipher_decrypt(ntlmssp_state->crypt->ntlm.seal_state, ++ data, ++ length); ++ if (rc < 0) { ++ DBG_ERR("gnutls_cipher_decrypt ntlmv1 unsealing the " ++ "data failed: %s\n", ++ gnutls_strerror(rc)); ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED); ++ } + dump_data_pw("ntlmv1 clear data\n", data, length); + } ++ + status = ntlmssp_check_packet(ntlmssp_state, + data, length, + whole_pdu, pdu_length, +@@ -555,6 +618,8 @@ NTSTATUS ntlmssp_unwrap(struct ntlmssp_state *ntlmssp_state, + NTSTATUS ntlmssp_sign_reset(struct ntlmssp_state *ntlmssp_state, + bool reset_seqnums) + { ++ int rc; ++ + DEBUG(3, ("NTLMSSP Sign/Seal - Initialising with flags:\n")); + debug_ntlmssp_flags(ntlmssp_state->neg_flags); + +@@ -584,12 +649,16 @@ NTSTATUS ntlmssp_sign_reset(struct ntlmssp_state *ntlmssp_state, + const char *send_seal_const; + const char *recv_sign_const; + const char *recv_seal_const; +- uint8_t send_seal_key[16]; +- DATA_BLOB send_seal_blob = data_blob_const(send_seal_key, +- sizeof(send_seal_key)); +- uint8_t recv_seal_key[16]; +- DATA_BLOB recv_seal_blob = data_blob_const(recv_seal_key, +- sizeof(recv_seal_key)); ++ uint8_t send_seal_key[16] = {0}; ++ gnutls_datum_t send_seal_blob = { ++ .data = send_seal_key, ++ .size = sizeof(send_seal_key), ++ }; ++ uint8_t recv_seal_key[16] = {0}; ++ gnutls_datum_t recv_seal_blob = { ++ .data = recv_seal_key, ++ .size = sizeof(recv_seal_key), ++ }; + NTSTATUS status; + + switch (ntlmssp_state->role) { +@@ -648,10 +717,22 @@ NTSTATUS ntlmssp_sign_reset(struct ntlmssp_state *ntlmssp_state, + if (!NT_STATUS_IS_OK(status)) { + return status; + } +- dump_data_pw("NTLMSSP send seal key:\n", send_seal_key, 16); ++ dump_data_pw("NTLMSSP send seal key:\n", ++ send_seal_key, ++ sizeof(send_seal_key)); + +- arcfour_init(&ntlmssp_state->crypt->ntlm2.sending.seal_state, +- &send_seal_blob); ++ if (ntlmssp_state->crypt->ntlm2.sending.seal_state != NULL) { ++ gnutls_cipher_deinit(ntlmssp_state->crypt->ntlm2.sending.seal_state); ++ } ++ rc = gnutls_cipher_init(&ntlmssp_state->crypt->ntlm2.sending.seal_state, ++ GNUTLS_CIPHER_ARCFOUR_128, ++ &send_seal_blob, ++ NULL); ++ if (rc < 0) { ++ DBG_ERR("gnutls_cipher_init failed: %s\n", ++ gnutls_strerror(rc)); ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED); ++ } + + dump_arc4_state("NTLMSSP send seal arc4 state:\n", + &ntlmssp_state->crypt->ntlm2.sending.seal_state); +@@ -677,10 +758,22 @@ NTSTATUS ntlmssp_sign_reset(struct ntlmssp_state *ntlmssp_state, + if (!NT_STATUS_IS_OK(status)) { + return status; + } +- dump_data_pw("NTLMSSP recv seal key:\n", recv_seal_key, 16); ++ dump_data_pw("NTLMSSP recv seal key:\n", ++ recv_seal_key, ++ sizeof(recv_seal_key)); + +- arcfour_init(&ntlmssp_state->crypt->ntlm2.receiving.seal_state, +- &recv_seal_blob); ++ if (ntlmssp_state->crypt->ntlm2.receiving.seal_state != NULL) { ++ gnutls_cipher_deinit(ntlmssp_state->crypt->ntlm2.receiving.seal_state); ++ } ++ rc = gnutls_cipher_init(&ntlmssp_state->crypt->ntlm2.receiving.seal_state, ++ GNUTLS_CIPHER_ARCFOUR_128, ++ &recv_seal_blob, ++ NULL); ++ if (rc < 0) { ++ DBG_ERR("gnutls_cipher_init failed: %s\n", ++ gnutls_strerror(rc)); ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED); ++ } + + dump_arc4_state("NTLMSSP recv seal arc4 state:\n", + &ntlmssp_state->crypt->ntlm2.receiving.seal_state); +@@ -690,8 +783,10 @@ NTSTATUS ntlmssp_sign_reset(struct ntlmssp_state *ntlmssp_state, + ntlmssp_state->crypt->ntlm2.receiving.seq_num = 0; + } + } else { +- uint8_t weak_session_key[8]; +- DATA_BLOB seal_session_key = ntlmssp_state->session_key; ++ gnutls_datum_t seal_session_key = { ++ .data = ntlmssp_state->session_key.data, ++ .size = ntlmssp_state->session_key.length, ++ }; + bool do_weak = false; + + DEBUG(5, ("NTLMSSP Sign/Seal - using NTLM1\n")); +@@ -709,14 +804,19 @@ NTSTATUS ntlmssp_sign_reset(struct ntlmssp_state *ntlmssp_state, + * Nothing to weaken. + * We certainly don't want to 'extend' the length... + */ +- if (seal_session_key.length < 16) { ++ if (ntlmssp_state->session_key.length < 16) { + /* TODO: is this really correct? */ + do_weak = false; + } + + if (do_weak) { ++ uint8_t weak_session_key[8]; ++ + memcpy(weak_session_key, seal_session_key.data, 8); +- seal_session_key = data_blob_const(weak_session_key, 8); ++ seal_session_key = (gnutls_datum_t) { ++ .data = weak_session_key, ++ .size = sizeof(weak_session_key), ++ }; + + /* + * LM key doesn't support 128 bit crypto, so this is +@@ -732,8 +832,18 @@ NTSTATUS ntlmssp_sign_reset(struct ntlmssp_state *ntlmssp_state, + } + } + +- arcfour_init(&ntlmssp_state->crypt->ntlm.seal_state, +- &seal_session_key); ++ if (ntlmssp_state->crypt->ntlm.seal_state != NULL) { ++ gnutls_cipher_deinit(ntlmssp_state->crypt->ntlm.seal_state); ++ } ++ rc = gnutls_cipher_init(&ntlmssp_state->crypt->ntlm.seal_state, ++ GNUTLS_CIPHER_ARCFOUR_128, ++ &seal_session_key, ++ NULL); ++ if (rc < 0) { ++ DBG_ERR("gnutls_cipher_init failed: %s\n", ++ gnutls_strerror(rc)); ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED); ++ } + + dump_arc4_state("NTLMv1 arc4 state:\n", + &ntlmssp_state->crypt->ntlm.seal_state); +@@ -746,6 +856,24 @@ NTSTATUS ntlmssp_sign_reset(struct ntlmssp_state *ntlmssp_state, + return NT_STATUS_OK; + } + ++static int ntlmssp_crypt_free_gnutls_cipher_state(union ntlmssp_crypt_state *c) ++{ ++ if (c->ntlm2.sending.seal_state != NULL) { ++ gnutls_cipher_deinit(c->ntlm2.sending.seal_state); ++ c->ntlm2.sending.seal_state = NULL; ++ } ++ if (c->ntlm2.receiving.seal_state != NULL) { ++ gnutls_cipher_deinit(c->ntlm2.receiving.seal_state); ++ c->ntlm2.receiving.seal_state = NULL; ++ } ++ if (c->ntlm.seal_state != NULL) { ++ gnutls_cipher_deinit(c->ntlm.seal_state); ++ c->ntlm.seal_state = NULL; ++ } ++ ++ return 0; ++} ++ + NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) + { + if (ntlmssp_state->session_key.length < 8) { +@@ -758,6 +886,8 @@ NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) + if (ntlmssp_state->crypt == NULL) { + return NT_STATUS_NO_MEMORY; + } ++ talloc_set_destructor(ntlmssp_state->crypt, ++ ntlmssp_crypt_free_gnutls_cipher_state); + + return ntlmssp_sign_reset(ntlmssp_state, true); + } +-- +2.23.0 + diff --git a/SOURCES/0031-s3-libsmb-Use-GnuTLS-RC4-in-clirap.patch b/SOURCES/0031-s3-libsmb-Use-GnuTLS-RC4-in-clirap.patch new file mode 100644 index 0000000..44e1ed0 --- /dev/null +++ b/SOURCES/0031-s3-libsmb-Use-GnuTLS-RC4-in-clirap.patch @@ -0,0 +1,76 @@ +From c7e79b33a10a8e393df78fd7adf60a5a3dbebcc6 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Tue, 15 Jan 2019 18:14:17 +0100 +Subject: [PATCH 031/187] s3:libsmb: Use GnuTLS RC4 in clirap + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 0947d8388def40b01b322d0deee4dba386983410) +--- + source3/libsmb/clirap.c | 27 +++++++++++++++++++++++++-- + 1 file changed, 25 insertions(+), 2 deletions(-) + +diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c +index b4b40ebdab4..c0b9dcdff39 100644 +--- a/source3/libsmb/clirap.c ++++ b/source3/libsmb/clirap.c +@@ -22,7 +22,6 @@ + #include "includes.h" + #include "../libcli/auth/libcli_auth.h" + #include "../librpc/gen_ndr/rap.h" +-#include "../lib/crypto/arcfour.h" + #include "../lib/util/tevent_ntstatus.h" + #include "async_smb.h" + #include "libsmb/libsmb.h" +@@ -31,6 +30,9 @@ + #include "../libcli/smb/smbXcli_base.h" + #include "cli_smb2_fnum.h" + ++#include ++#include ++ + #define PIPE_LANMAN "\\PIPE\\LANMAN" + + /**************************************************************************** +@@ -508,6 +510,12 @@ bool cli_oem_change_password(struct cli_state *cli, const char *user, const char + char *rparam = NULL; + char *rdata = NULL; + unsigned int rprcnt, rdrcnt; ++ gnutls_cipher_hd_t cipher_hnd = NULL; ++ gnutls_datum_t old_pw_key = { ++ .data = old_pw_hash, ++ .size = sizeof(old_pw_hash), ++ }; ++ int rc; + + if (strlen(user) >= sizeof(fstring)-1) { + DEBUG(0,("cli_oem_change_password: user name %s is too long.\n", user)); +@@ -539,7 +547,22 @@ bool cli_oem_change_password(struct cli_state *cli, const char *user, const char + DEBUG(100,("make_oem_passwd_hash\n")); + dump_data(100, data, 516); + #endif +- arcfour_crypt( (unsigned char *)data, (unsigned char *)old_pw_hash, 516); ++ rc = gnutls_cipher_init(&cipher_hnd, ++ GNUTLS_CIPHER_ARCFOUR_128, ++ &old_pw_key, ++ NULL); ++ if (rc < 0) { ++ DBG_ERR("gnutls_cipher_init failed: %s\n", ++ gnutls_strerror(rc)); ++ return false; ++ } ++ rc = gnutls_cipher_encrypt(cipher_hnd, ++ data, ++ 516); ++ gnutls_cipher_deinit(cipher_hnd); ++ if (rc < 0) { ++ return false; ++ } + + /* + * Now place the old password hash in the data. +-- +2.23.0 + diff --git a/SOURCES/0032-s3-rpc_client-Use-init_samr_CryptPassword-in-cli_sam.patch b/SOURCES/0032-s3-rpc_client-Use-init_samr_CryptPassword-in-cli_sam.patch new file mode 100644 index 0000000..cfd6340 --- /dev/null +++ b/SOURCES/0032-s3-rpc_client-Use-init_samr_CryptPassword-in-cli_sam.patch @@ -0,0 +1,160 @@ +From 36dfd6496dc9b954b2243bbb5293af8ce332cf4f Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 16 Jan 2019 12:41:32 +0100 +Subject: [PATCH 032/187] s3:rpc_client: Use init_samr_CryptPassword in + cli_samr rpc_client + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit a95647e12ac75ffda42d95b41144596a078aebd6) +--- + source3/rpc_client/cli_samr.c | 59 ++++++++++++++++++++++++++++------- + source3/wscript_build | 2 +- + 2 files changed, 48 insertions(+), 13 deletions(-) + +diff --git a/source3/rpc_client/cli_samr.c b/source3/rpc_client/cli_samr.c +index 7764e1a8540..452e9593f6a 100644 +--- a/source3/rpc_client/cli_samr.c ++++ b/source3/rpc_client/cli_samr.c +@@ -26,8 +26,8 @@ + #include "../libcli/auth/libcli_auth.h" + #include "../librpc/gen_ndr/ndr_samr_c.h" + #include "rpc_client/cli_samr.h" +-#include "../lib/crypto/arcfour.h" + #include "rpc_client/init_lsa.h" ++#include "rpc_client/init_samr.h" + + /* User change password */ + +@@ -128,6 +128,8 @@ NTSTATUS dcerpc_samr_chgpasswd_user2(struct dcerpc_binding_handle *h, + uint8_t new_lanman_hash[16]; + struct lsa_String server, account; + ++ DATA_BLOB session_key = data_blob_const(old_nt_hash, 16); ++ + DEBUG(10,("rpccli_samr_chgpasswd_user2\n")); + + init_lsa_String(&server, srv_name_slash); +@@ -144,19 +146,25 @@ NTSTATUS dcerpc_samr_chgpasswd_user2(struct dcerpc_binding_handle *h, + DOS chars). This allows us to match Win2k, which + does not store a LM hash for these passwords (which + would reduce the effective password length to 14) */ ++ status = init_samr_CryptPassword(newpassword, ++ &session_key, ++ &new_lm_password); ++ if (!NT_STATUS_IS_OK(status)) { ++ return status; ++ } + +- encode_pw_buffer(new_lm_password.data, newpassword, STR_UNICODE); +- +- arcfour_crypt(new_lm_password.data, old_nt_hash, 516); + E_old_pw_hash(new_nt_hash, old_lanman_hash, old_lanman_hash_enc.hash); + } else { + ZERO_STRUCT(new_lm_password); + ZERO_STRUCT(old_lanman_hash_enc); + } + +- encode_pw_buffer(new_nt_password.data, newpassword, STR_UNICODE); +- +- arcfour_crypt(new_nt_password.data, old_nt_hash, 516); ++ status = init_samr_CryptPassword(newpassword, ++ &session_key, ++ &new_nt_password); ++ if (!NT_STATUS_IS_OK(status)) { ++ return status; ++ } + E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash); + + status = dcerpc_samr_ChangePasswordUser2(h, +@@ -170,6 +178,15 @@ NTSTATUS dcerpc_samr_chgpasswd_user2(struct dcerpc_binding_handle *h, + &old_lanman_hash_enc, + presult); + ++ ZERO_STRUCT(new_nt_password); ++ ZERO_STRUCT(new_lm_password); ++ ZERO_STRUCT(old_nt_hash_enc); ++ ZERO_STRUCT(old_lanman_hash_enc); ++ ZERO_ARRAY(new_nt_hash); ++ ZERO_ARRAY(new_lanman_hash); ++ ZERO_ARRAY(old_nt_hash); ++ ZERO_ARRAY(old_lanman_hash); ++ + return status; + } + +@@ -308,6 +325,8 @@ NTSTATUS dcerpc_samr_chgpasswd_user3(struct dcerpc_binding_handle *h, + + struct lsa_String server, account; + ++ DATA_BLOB session_key = data_blob_const(old_nt_hash, 16); ++ + DEBUG(10,("rpccli_samr_chgpasswd_user3\n")); + + init_lsa_String(&server, srv_name_slash); +@@ -324,19 +343,26 @@ NTSTATUS dcerpc_samr_chgpasswd_user3(struct dcerpc_binding_handle *h, + DOS chars). This allows us to match Win2k, which + does not store a LM hash for these passwords (which + would reduce the effective password length to 14) */ ++ status = init_samr_CryptPassword(newpassword, ++ &session_key, ++ &new_lm_password); ++ if (!NT_STATUS_IS_OK(status)) { ++ return status; ++ } + +- encode_pw_buffer(new_lm_password.data, newpassword, STR_UNICODE); +- +- arcfour_crypt(new_lm_password.data, old_nt_hash, 516); + E_old_pw_hash(new_nt_hash, old_lanman_hash, old_lanman_hash_enc.hash); + } else { + ZERO_STRUCT(new_lm_password); + ZERO_STRUCT(old_lanman_hash_enc); + } + +- encode_pw_buffer(new_nt_password.data, newpassword, STR_UNICODE); ++ status = init_samr_CryptPassword(newpassword, ++ &session_key, ++ &new_nt_password); ++ if (!NT_STATUS_IS_OK(status)) { ++ return status; ++ } + +- arcfour_crypt(new_nt_password.data, old_nt_hash, 516); + E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash); + + status = dcerpc_samr_ChangePasswordUser3(h, +@@ -353,6 +379,15 @@ NTSTATUS dcerpc_samr_chgpasswd_user3(struct dcerpc_binding_handle *h, + reject, + presult); + ++ ZERO_STRUCT(new_nt_password); ++ ZERO_STRUCT(new_lm_password); ++ ZERO_STRUCT(old_nt_hash_enc); ++ ZERO_STRUCT(old_lanman_hash_enc); ++ ZERO_ARRAY(new_nt_hash); ++ ZERO_ARRAY(new_lanman_hash); ++ ZERO_ARRAY(old_nt_hash); ++ ZERO_ARRAY(old_lanman_hash); ++ + return status; + } + +diff --git a/source3/wscript_build b/source3/wscript_build +index aa3c7175202..b73f6dc0664 100644 +--- a/source3/wscript_build ++++ b/source3/wscript_build +@@ -1009,7 +1009,7 @@ bld.SAMBA3_SUBSYSTEM('errors3', + + bld.SAMBA3_SUBSYSTEM('LIBCLI_SAMR', + source='rpc_client/cli_samr.c', +- deps='RPC_NDR_SAMR') ++ deps='RPC_NDR_SAMR INIT_SAMR') + + bld.SAMBA3_LIBRARY('libcli_lsa3', + source='rpc_client/cli_lsarpc.c', +-- +2.23.0 + diff --git a/SOURCES/0033-s3-rpc_server-Use-GnuTLS-RC4-in-samr-password-check.patch b/SOURCES/0033-s3-rpc_server-Use-GnuTLS-RC4-in-samr-password-check.patch new file mode 100644 index 0000000..143e695 --- /dev/null +++ b/SOURCES/0033-s3-rpc_server-Use-GnuTLS-RC4-in-samr-password-check.patch @@ -0,0 +1,77 @@ +From 07925f22341c508792b3ce8feeae2abc939a61f2 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 16 Jan 2019 17:40:13 +0100 +Subject: [PATCH 033/187] s3:rpc_server: Use GnuTLS RC4 in samr password check + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit d31f6a6803c86b8de0a97927731091f5a7bee4f1) +--- + source3/rpc_server/samr/srv_samr_chgpasswd.c | 30 ++++++++++++++++++-- + 1 file changed, 28 insertions(+), 2 deletions(-) + +diff --git a/source3/rpc_server/samr/srv_samr_chgpasswd.c b/source3/rpc_server/samr/srv_samr_chgpasswd.c +index 3749edbb044..fc509494ebc 100644 +--- a/source3/rpc_server/samr/srv_samr_chgpasswd.c ++++ b/source3/rpc_server/samr/srv_samr_chgpasswd.c +@@ -50,12 +50,15 @@ + #include "system/passwd.h" + #include "system/filesys.h" + #include "../libcli/auth/libcli_auth.h" +-#include "../lib/crypto/arcfour.h" + #include "rpc_server/samr/srv_samr_util.h" + #include "passdb.h" + #include "auth.h" + #include "lib/util/sys_rw.h" + ++#include "lib/crypto/gnutls_helpers.h" ++#include ++#include ++ + #ifndef ALLOW_CHANGE_PASSWORD + #if (defined(HAVE_TERMIOS_H) && defined(HAVE_DUP2) && defined(HAVE_SETSID)) + #define ALLOW_CHANGE_PASSWORD 1 +@@ -685,6 +688,10 @@ static NTSTATUS check_oem_password(const char *user, + bool lm_pass_set = (password_encrypted_with_lm_hash && old_lm_hash_encrypted); + enum ntlm_auth_level ntlm_auth_level = lp_ntlm_auth(); + ++ gnutls_cipher_hd_t cipher_hnd = NULL; ++ gnutls_datum_t enc_key; ++ int rc; ++ + /* this call should be disabled without NTLM auth */ + if (ntlm_auth_level == NTLM_AUTH_DISABLED) { + DBG_WARNING("NTLM password changes not" +@@ -752,7 +759,26 @@ static NTSTATUS check_oem_password(const char *user, + /* + * Decrypt the password with the key + */ +- arcfour_crypt( password_encrypted, encryption_key, 516); ++ enc_key = (gnutls_datum_t) { ++ .data = discard_const_p(unsigned char, encryption_key), ++ .size = 16, ++ }; ++ ++ rc = gnutls_cipher_init(&cipher_hnd, ++ GNUTLS_CIPHER_ARCFOUR_128, ++ &enc_key, ++ NULL); ++ if (rc < 0) { ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); ++ } ++ ++ rc = gnutls_cipher_decrypt(cipher_hnd, ++ password_encrypted, ++ 516); ++ gnutls_cipher_deinit(cipher_hnd); ++ if (rc < 0) { ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); ++ } + + if (!decode_pw_buffer(talloc_tos(), + password_encrypted, +-- +2.23.0 + diff --git a/SOURCES/0034-s3-rpc_server-Use-GnuTLS-RC4-to-decrypt-samr-passwor.patch b/SOURCES/0034-s3-rpc_server-Use-GnuTLS-RC4-to-decrypt-samr-passwor.patch new file mode 100644 index 0000000..99c6513 --- /dev/null +++ b/SOURCES/0034-s3-rpc_server-Use-GnuTLS-RC4-to-decrypt-samr-passwor.patch @@ -0,0 +1,119 @@ +From 6eb8a45387ae6400d4b48d838ec89510afe2b37a Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 15 May 2019 14:04:31 +0200 +Subject: [PATCH 034/187] s3:rpc_server: Use GnuTLS RC4 to decrypt samr + password buffers + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit cd0b5e5d9377bc79b4468081f3999ad39be3cb8f) +--- + source3/rpc_server/samr/srv_samr_nt.c | 58 ++++++++++++++++++++++++--- + 1 file changed, 52 insertions(+), 6 deletions(-) + +diff --git a/source3/rpc_server/samr/srv_samr_nt.c b/source3/rpc_server/samr/srv_samr_nt.c +index fd5c453e0eb..ad1d1853bda 100644 +--- a/source3/rpc_server/samr/srv_samr_nt.c ++++ b/source3/rpc_server/samr/srv_samr_nt.c +@@ -37,7 +37,6 @@ + #include "ntdomain.h" + #include "../librpc/gen_ndr/srv_samr.h" + #include "rpc_server/samr/srv_samr_util.h" +-#include "../lib/crypto/arcfour.h" + #include "secrets.h" + #include "rpc_client/init_lsa.h" + #include "../libcli/security/security.h" +@@ -47,6 +46,10 @@ + #include "../lib/tsocket/tsocket.h" + #include "lib/util/base64.h" + ++#include "lib/crypto/gnutls_helpers.h" ++#include ++#include ++ + #undef DBGC_CLASS + #define DBGC_CLASS DBGC_RPC_SRV + +@@ -4946,6 +4949,41 @@ static uint32_t samr_set_user_info_map_fields_to_access_mask(uint32_t fields) + return acc_required; + } + ++static NTSTATUS arc4_decrypt_data(DATA_BLOB session_key, ++ uint8_t *data, ++ size_t data_size) ++{ ++ gnutls_cipher_hd_t cipher_hnd = NULL; ++ gnutls_datum_t my_session_key = { ++ .data = session_key.data, ++ .size = session_key.length, ++ }; ++ NTSTATUS status = NT_STATUS_INTERNAL_ERROR; ++ int rc; ++ ++ rc = gnutls_cipher_init(&cipher_hnd, ++ GNUTLS_CIPHER_ARCFOUR_128, ++ &my_session_key, ++ NULL); ++ if (rc < 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); ++ goto out; ++ } ++ ++ rc = gnutls_cipher_decrypt(cipher_hnd, ++ data, ++ data_size); ++ gnutls_cipher_deinit(cipher_hnd); ++ if (rc < 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); ++ goto out; ++ } ++ ++ status = NT_STATUS_OK; ++out: ++ return status; ++} ++ + /******************************************************************* + samr_SetUserInfo + ********************************************************************/ +@@ -5153,8 +5191,12 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p, + if(!NT_STATUS_IS_OK(status)) { + break; + } +- arcfour_crypt_blob(info->info23.password.data, 516, +- &session_key); ++ status = arc4_decrypt_data(session_key, ++ info->info23.password.data, ++ 516); ++ if(!NT_STATUS_IS_OK(status)) { ++ break; ++ } + + dump_data(100, info->info23.password.data, 516); + +@@ -5165,13 +5207,17 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p, + break; + + case 24: ++ + status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES); + if(!NT_STATUS_IS_OK(status)) { + break; + } +- arcfour_crypt_blob(info->info24.password.data, +- 516, +- &session_key); ++ status = arc4_decrypt_data(session_key, ++ info->info24.password.data, ++ 516); ++ if(!NT_STATUS_IS_OK(status)) { ++ break; ++ } + + dump_data(100, info->info24.password.data, 516); + +-- +2.23.0 + diff --git a/SOURCES/0035-s3-utils-Use-GnuTLS-RC4-in-ntlm_auth.patch b/SOURCES/0035-s3-utils-Use-GnuTLS-RC4-in-ntlm_auth.patch new file mode 100644 index 0000000..33cd2ba --- /dev/null +++ b/SOURCES/0035-s3-utils-Use-GnuTLS-RC4-in-ntlm_auth.patch @@ -0,0 +1,110 @@ +From ef374b9b3b98b498545d40f0aa2e537bdf81ae59 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Thu, 17 Jan 2019 12:40:21 +0100 +Subject: [PATCH 035/187] s3:utils: Use GnuTLS RC4 in ntlm_auth + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 359ae5be0d21e7ab235035aab65710c9459e9593) +--- + source3/utils/ntlm_auth.c | 45 ++++++++++++++++++++++++++++++++++++--- + 1 file changed, 42 insertions(+), 3 deletions(-) + +diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c +index 87f6554ae4f..8a6218ac9ec 100644 +--- a/source3/utils/ntlm_auth.c ++++ b/source3/utils/ntlm_auth.c +@@ -37,7 +37,6 @@ + #include "librpc/crypto/gse.h" + #include "smb_krb5.h" + #include "lib/util/tiniparser.h" +-#include "../lib/crypto/arcfour.h" + #include "nsswitch/winbind_client.h" + #include "librpc/gen_ndr/krb5pac.h" + #include "../lib/util/asn1.h" +@@ -49,6 +48,9 @@ + #include "lib/util/base64.h" + #include "cmdline_contexts.h" + ++#include ++#include ++ + #ifdef HAVE_KRB5 + #include "auth/kerberos/pac_utils.h" + #endif +@@ -1937,6 +1939,13 @@ static void manage_ntlm_change_password_1_request(enum stdio_helper_mode stdio_h + uchar new_nt_hash[16]; + uchar new_lm_hash[16]; + ++ gnutls_cipher_hd_t cipher_hnd = NULL; ++ gnutls_datum_t old_nt_key = { ++ .data = old_nt_hash, ++ .size = sizeof(old_nt_hash), ++ }; ++ int rc; ++ + new_nt_pswd = data_blob(NULL, 516); + old_nt_hash_enc = data_blob(NULL, 16); + +@@ -1956,6 +1965,19 @@ static void manage_ntlm_change_password_1_request(enum stdio_helper_mode stdio_h + Likewise, obey the admin's restriction + */ + ++ rc = gnutls_cipher_init(&cipher_hnd, ++ GNUTLS_CIPHER_ARCFOUR_128, ++ &old_nt_key, ++ NULL); ++ if (rc < 0) { ++ DBG_ERR("gnutls_cipher_init failed: %s\n", ++ gnutls_strerror(rc)); ++ if (rc == GNUTLS_E_UNWANTED_ALGORITHM) { ++ DBG_ERR("Running in FIPS mode, NTLM blocked\n"); ++ } ++ return; ++ } ++ + if (lp_client_lanman_auth() && + E_deshash(newpswd, new_lm_hash) && + E_deshash(oldpswd, old_lm_hash)) { +@@ -1964,7 +1986,13 @@ static void manage_ntlm_change_password_1_request(enum stdio_helper_mode stdio_h + encode_pw_buffer(new_lm_pswd.data, newpswd, + STR_UNICODE); + +- arcfour_crypt(new_lm_pswd.data, old_nt_hash, 516); ++ rc = gnutls_cipher_encrypt(cipher_hnd, ++ new_lm_pswd.data, ++ 516); ++ if (rc < 0) { ++ gnutls_cipher_deinit(cipher_hnd); ++ return; ++ } + E_old_pw_hash(new_nt_hash, old_lm_hash, + old_lm_hash_enc.data); + } else { +@@ -1977,9 +2005,20 @@ static void manage_ntlm_change_password_1_request(enum stdio_helper_mode stdio_h + encode_pw_buffer(new_nt_pswd.data, newpswd, + STR_UNICODE); + +- arcfour_crypt(new_nt_pswd.data, old_nt_hash, 516); ++ rc = gnutls_cipher_encrypt(cipher_hnd, ++ new_nt_pswd.data, ++ 516); ++ gnutls_cipher_deinit(cipher_hnd); ++ if (rc < 0) { ++ return; ++ } + E_old_pw_hash(new_nt_hash, old_nt_hash, + old_nt_hash_enc.data); ++ ++ ZERO_ARRAY(old_nt_hash); ++ ZERO_ARRAY(old_lm_hash); ++ ZERO_ARRAY(new_nt_hash); ++ ZERO_ARRAY(new_lm_hash); + } + + if (!full_username && !username) { +-- +2.23.0 + diff --git a/SOURCES/0036-s4-rpc_server-Use-samba_gnutls_arcfour_confounded_md.patch b/SOURCES/0036-s4-rpc_server-Use-samba_gnutls_arcfour_confounded_md.patch new file mode 100644 index 0000000..85da370 --- /dev/null +++ b/SOURCES/0036-s4-rpc_server-Use-samba_gnutls_arcfour_confounded_md.patch @@ -0,0 +1,76 @@ +From e81c7a540896c9a3fed8d6a8b080f76c83d70369 Mon Sep 17 00:00:00 2001 +From: Andrew Bartlett +Date: Thu, 25 Jul 2019 12:50:57 +1200 +Subject: [PATCH 036/187] s4:rpc_server: Use + samba_gnutls_arcfour_confounded_md5() in samr_set_password_ex() + +This allows the use of GnuTLS for the underlying RC4 crypto operations. + +Signed-off-by: Andrew Bartlett +Reviewed-by: Andreas Schneider +(cherry picked from commit 9363abfb5fcfeff30295ce0cf94c18941a6c4e9f) +--- + source4/rpc_server/samr/samr_password.c | 34 ++++++------------------- + 1 file changed, 8 insertions(+), 26 deletions(-) + +diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c +index 7c441f38ce2..fde0de2c3cc 100644 +--- a/source4/rpc_server/samr/samr_password.c ++++ b/source4/rpc_server/samr/samr_password.c +@@ -586,9 +586,11 @@ NTSTATUS samr_set_password_ex(struct dcesrv_call_state *dce_call, + { + NTSTATUS nt_status; + DATA_BLOB new_password; +- DATA_BLOB co_session_key; ++ ++ /* The confounder is in the last 16 bytes of the buffer */ ++ DATA_BLOB confounder = data_blob_const(&pwbuf->data[516], 16); ++ DATA_BLOB pw_data = data_blob_const(pwbuf->data, 516); + DATA_BLOB session_key = data_blob(NULL, 0); +- gnutls_hash_hd_t hash_hnd = NULL; + int rc; + + nt_status = dcesrv_transport_session_key(dce_call, &session_key); +@@ -599,35 +601,15 @@ NTSTATUS samr_set_password_ex(struct dcesrv_call_state *dce_call, + return NT_STATUS_WRONG_PASSWORD; + } + +- co_session_key = data_blob_talloc(mem_ctx, NULL, 16); +- if (!co_session_key.data) { +- return NT_STATUS_NO_MEMORY; +- } +- +- rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5); ++ rc = samba_gnutls_arcfour_confounded_md5(&confounder, ++ &session_key, ++ &pw_data, ++ SAMBA_GNUTLS_DECRYPT); + if (rc < 0) { + nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED); + goto out; + } + +- rc = gnutls_hash(hash_hnd, &pwbuf->data[516], 16); +- if (rc < 0) { +- gnutls_hash_deinit(hash_hnd, NULL); +- nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED); +- goto out; +- } +- rc = gnutls_hash(hash_hnd, session_key.data, session_key.length); +- if (rc < 0) { +- gnutls_hash_deinit(hash_hnd, NULL); +- nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED); +- goto out; +- } +- gnutls_hash_deinit(hash_hnd, co_session_key.data); +- +- arcfour_crypt_blob(pwbuf->data, 516, &co_session_key); +- ZERO_ARRAY_LEN(co_session_key.data, +- co_session_key.length); +- + if (!extract_pw_from_buffer(mem_ctx, pwbuf->data, &new_password)) { + DEBUG(3,("samr: failed to decode password buffer\n")); + nt_status = NT_STATUS_WRONG_PASSWORD; +-- +2.23.0 + diff --git a/SOURCES/0037-s4-rpc_server-Use-GnuTLS-RC4-for-samr-password.patch b/SOURCES/0037-s4-rpc_server-Use-GnuTLS-RC4-for-samr-password.patch new file mode 100644 index 0000000..a9c5115 --- /dev/null +++ b/SOURCES/0037-s4-rpc_server-Use-GnuTLS-RC4-for-samr-password.patch @@ -0,0 +1,195 @@ +From 23f422c0df67c0f9e701e0deb5f1708a930a98bd Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Tue, 19 Feb 2019 17:40:29 +0100 +Subject: [PATCH 037/187] s4:rpc_server: Use GnuTLS RC4 for samr password + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 4326e7de6ba0ce02ab23af7297d2f7242988daa4) +--- + source4/rpc_server/samr/samr_password.c | 105 ++++++++++++++++++++---- + 1 file changed, 89 insertions(+), 16 deletions(-) + +diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c +index fde0de2c3cc..b04e37f06f3 100644 +--- a/source4/rpc_server/samr/samr_password.c ++++ b/source4/rpc_server/samr/samr_password.c +@@ -24,7 +24,7 @@ + #include "rpc_server/dcerpc_server.h" + #include "rpc_server/samr/dcesrv_samr.h" + #include "system/time.h" +-#include "../lib/crypto/crypto.h" ++#include "lib/crypto/md4.h" + #include "dsdb/samdb/samdb.h" + #include "auth/auth.h" + #include "libcli/auth/libcli_auth.h" +@@ -119,13 +119,15 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call, + "samAccountName", + NULL }; + struct samr_Password *lm_pwd; +- DATA_BLOB lm_pwd_blob; + uint8_t new_lm_hash[16]; + struct samr_Password lm_verifier; + size_t unicode_pw_len; + size_t converted_size = 0; + const char *user_samAccountName = NULL; + struct dom_sid *user_objectSid = NULL; ++ gnutls_cipher_hd_t cipher_hnd = NULL; ++ gnutls_datum_t lm_session_key; ++ int rc; + + if (pwbuf == NULL) { + return NT_STATUS_INVALID_PARAMETER; +@@ -179,9 +181,28 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call, + } + + /* decrypt the password we have been given */ +- lm_pwd_blob = data_blob(lm_pwd->hash, sizeof(lm_pwd->hash)); +- arcfour_crypt_blob(pwbuf->data, 516, &lm_pwd_blob); +- data_blob_free(&lm_pwd_blob); ++ lm_session_key = (gnutls_datum_t) { ++ .data = lm_pwd->hash, ++ .size = sizeof(lm_pwd->hash), ++ }; ++ ++ rc = gnutls_cipher_init(&cipher_hnd, ++ GNUTLS_CIPHER_ARCFOUR_128, ++ &lm_session_key, ++ NULL); ++ if (rc < 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); ++ goto failed; ++ } ++ ++ rc = gnutls_cipher_decrypt(cipher_hnd, ++ pwbuf->data, ++ 516); ++ gnutls_cipher_deinit(cipher_hnd); ++ if (rc < 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); ++ goto failed; ++ } + + if (!extract_pw_from_buffer(mem_ctx, pwbuf->data, &new_password)) { + DEBUG(3,("samr: failed to decode password buffer\n")); +@@ -315,7 +336,6 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call, + "badPwdCount", "badPasswordTime", + "objectSid", NULL }; + struct samr_Password *nt_pwd, *lm_pwd; +- DATA_BLOB nt_pwd_blob; + struct samr_DomInfo1 *dominfo = NULL; + struct userPwdChangeFailureInformation *reject = NULL; + enum samPwdChangeReason reason = SAM_PWD_CHANGE_NO_ERROR; +@@ -325,6 +345,9 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call, + struct dom_sid *user_objectSid = NULL; + enum ntlm_auth_level ntlm_auth_level + = lpcfg_ntlm_auth(dce_call->conn->dce_ctx->lp_ctx); ++ gnutls_cipher_hd_t cipher_hnd = NULL; ++ gnutls_datum_t nt_session_key; ++ int rc; + + *r->out.dominfo = NULL; + *r->out.reject = NULL; +@@ -381,9 +404,28 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call, + } + + /* decrypt the password we have been given */ +- nt_pwd_blob = data_blob(nt_pwd->hash, sizeof(nt_pwd->hash)); +- arcfour_crypt_blob(r->in.nt_password->data, 516, &nt_pwd_blob); +- data_blob_free(&nt_pwd_blob); ++ nt_session_key = (gnutls_datum_t) { ++ .data = nt_pwd->hash, ++ .size = sizeof(nt_pwd->hash), ++ }; ++ ++ rc = gnutls_cipher_init(&cipher_hnd, ++ GNUTLS_CIPHER_ARCFOUR_128, ++ &nt_session_key, ++ NULL); ++ if (rc < 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); ++ goto failed; ++ } ++ ++ rc = gnutls_cipher_decrypt(cipher_hnd, ++ r->in.nt_password->data, ++ 516); ++ gnutls_cipher_deinit(cipher_hnd); ++ if (rc < 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); ++ goto failed; ++ } + + if (!extract_pw_from_buffer(mem_ctx, r->in.nt_password->data, &new_password)) { + DEBUG(3,("samr: failed to decode password buffer\n")); +@@ -547,6 +589,9 @@ NTSTATUS samr_set_password(struct dcesrv_call_state *dce_call, + NTSTATUS nt_status; + DATA_BLOB new_password; + DATA_BLOB session_key = data_blob(NULL, 0); ++ gnutls_cipher_hd_t cipher_hnd = NULL; ++ gnutls_datum_t _session_key; ++ int rc; + + nt_status = dcesrv_transport_session_key(dce_call, &session_key); + if (!NT_STATUS_IS_OK(nt_status)) { +@@ -556,7 +601,28 @@ NTSTATUS samr_set_password(struct dcesrv_call_state *dce_call, + return NT_STATUS_WRONG_PASSWORD; + } + +- arcfour_crypt_blob(pwbuf->data, 516, &session_key); ++ _session_key = (gnutls_datum_t) { ++ .data = session_key.data, ++ .size = session_key.length, ++ }; ++ ++ rc = gnutls_cipher_init(&cipher_hnd, ++ GNUTLS_CIPHER_ARCFOUR_128, ++ &_session_key, ++ NULL); ++ if (rc < 0) { ++ nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); ++ goto out; ++ } ++ ++ rc = gnutls_cipher_decrypt(cipher_hnd, ++ pwbuf->data, ++ 516); ++ gnutls_cipher_deinit(cipher_hnd); ++ if (rc < 0) { ++ nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); ++ goto out; ++ } + + if (!extract_pw_from_buffer(mem_ctx, pwbuf->data, &new_password)) { + DEBUG(3,("samr: failed to decode password buffer\n")); +@@ -565,12 +631,19 @@ NTSTATUS samr_set_password(struct dcesrv_call_state *dce_call, + + /* set the password - samdb needs to know both the domain and user DNs, + so the domain password policy can be used */ +- return samdb_set_password(sam_ctx, mem_ctx, +- account_dn, domain_dn, +- &new_password, +- NULL, NULL, +- NULL, NULL, /* This is a password set, not change */ +- NULL, NULL); ++ nt_status = samdb_set_password(sam_ctx, ++ mem_ctx, ++ account_dn, ++ domain_dn, ++ &new_password, ++ NULL, ++ NULL, ++ NULL, ++ NULL, /* This is a password set, not change */ ++ NULL, ++ NULL); ++out: ++ return nt_status; + } + + +-- +2.23.0 + diff --git a/SOURCES/0038-s4-torture-Use-GnuTLS-RC4-for-RAP-SAM-test.patch b/SOURCES/0038-s4-torture-Use-GnuTLS-RC4-for-RAP-SAM-test.patch new file mode 100644 index 0000000..36d396c --- /dev/null +++ b/SOURCES/0038-s4-torture-Use-GnuTLS-RC4-for-RAP-SAM-test.patch @@ -0,0 +1,64 @@ +From 7839408010ba413f766e950192dd5a0632234ce7 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 20 Feb 2019 15:52:49 +0100 +Subject: [PATCH 038/187] s4:torture: Use GnuTLS RC4 for RAP SAM test + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 811c412da5c24d7274f9aa4c7d653bbb1191e6a6) +--- + source4/torture/rap/sam.c | 19 +++++++++++++++++-- + 1 file changed, 17 insertions(+), 2 deletions(-) + +diff --git a/source4/torture/rap/sam.c b/source4/torture/rap/sam.c +index 4ca7b793dec..3c13849b398 100644 +--- a/source4/torture/rap/sam.c ++++ b/source4/torture/rap/sam.c +@@ -26,10 +26,12 @@ + #include "torture/util.h" + #include "libcli/rap/rap.h" + #include "torture/rap/proto.h" +-#include "../lib/crypto/crypto.h" + #include "../libcli/auth/libcli_auth.h" + #include "torture/rpc/torture_rpc.h" + ++#include ++#include ++ + #define TEST_RAP_USER "torture_rap_user" + + static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len) +@@ -137,6 +139,11 @@ static bool test_oemchangepassword_args(struct torture_context *tctx, + char *newpass = samr_rand_pass(tctx, 9); + uint8_t old_pw_hash[16]; + uint8_t new_pw_hash[16]; ++ gnutls_cipher_hd_t cipher_hnd = NULL; ++ gnutls_datum_t pw_key = { ++ .data = old_pw_hash, ++ .size = sizeof(old_pw_hash), ++ }; + + r.in.UserName = username; + +@@ -144,7 +151,15 @@ static bool test_oemchangepassword_args(struct torture_context *tctx, + E_deshash(newpass, new_pw_hash); + + encode_pw_buffer(r.in.crypt_password, newpass, STR_ASCII); +- arcfour_crypt(r.in.crypt_password, old_pw_hash, 516); ++ ++ gnutls_cipher_init(&cipher_hnd, ++ GNUTLS_CIPHER_ARCFOUR_128, ++ &pw_key, ++ NULL); ++ gnutls_cipher_encrypt(cipher_hnd, ++ r.in.crypt_password, ++ 516); ++ gnutls_cipher_deinit(cipher_hnd); + E_old_pw_hash(new_pw_hash, old_pw_hash, r.in.password_hash); + + torture_comment(tctx, "Testing rap_NetOEMChangePassword(%s)\n", r.in.UserName); +-- +2.23.0 + diff --git a/SOURCES/0039-s4-torture-Use-init_samr_CryptPassword-Ex-in-samba3r.patch b/SOURCES/0039-s4-torture-Use-init_samr_CryptPassword-Ex-in-samba3r.patch new file mode 100644 index 0000000..868677f --- /dev/null +++ b/SOURCES/0039-s4-torture-Use-init_samr_CryptPassword-Ex-in-samba3r.patch @@ -0,0 +1,121 @@ +From d68771ee1f47bc238a2967ac43ccded3717d4bb5 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Thu, 21 Feb 2019 10:21:39 +0100 +Subject: [PATCH 039/187] s4:torture: Use init_samr_CryptPassword(Ex) in + samba3rpc test + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 80f5beb4804c694ee6e5f5b450e751f538677593) +--- + source4/torture/rpc/samba3rpc.c | 43 ++++++++++++++------------------- + 1 file changed, 18 insertions(+), 25 deletions(-) + +diff --git a/source4/torture/rpc/samba3rpc.c b/source4/torture/rpc/samba3rpc.c +index bf1de04a5b5..d55d6c47b57 100644 +--- a/source4/torture/rpc/samba3rpc.c ++++ b/source4/torture/rpc/samba3rpc.c +@@ -36,7 +36,6 @@ + #include "libcli/libcli.h" + #include "libcli/smb_composite/smb_composite.h" + #include "libcli/auth/libcli_auth.h" +-#include "../lib/crypto/crypto.h" + #include "libcli/security/security.h" + #include "param/param.h" + #include "lib/registry/registry.h" +@@ -47,9 +46,7 @@ + #include "librpc/rpc/dcerpc.h" + #include "librpc/rpc/dcerpc_proto.h" + #include "libcli/smb/smbXcli_base.h" +- +-#include +-#include ++#include "source3/rpc_client/init_samr.h" + + /* + * open pipe and bind, given an IPC$ context +@@ -666,7 +663,6 @@ static bool create_user(struct torture_context *tctx, + union samr_UserInfo *info; + DATA_BLOB session_key; + +- + ZERO_STRUCT(u_info); + encode_pw_buffer(u_info.info23.password.data, password, + STR_UNICODE); +@@ -676,8 +672,15 @@ static bool create_user(struct torture_context *tctx, + torture_comment(tctx, "dcerpc_fetch_session_key failed\n"); + goto done; + } +- arcfour_crypt_blob(u_info.info23.password.data, 516, +- &session_key); ++ ++ status = init_samr_CryptPassword(password, ++ &session_key, ++ &u_info.info23.password); ++ if (!NT_STATUS_IS_OK(status)) { ++ torture_comment(tctx, "init_samr_CryptPassword failed\n"); ++ goto done; ++ } ++ + u_info.info23.info.password_expired = 0; + u_info.info23.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT | + SAMR_FIELD_LM_PASSWORD_PRESENT | +@@ -872,10 +875,6 @@ static bool join3(struct torture_context *tctx, + union samr_UserInfo u_info; + struct samr_UserInfo21 *i21 = &u_info.info25.info; + DATA_BLOB session_key; +- DATA_BLOB confounded_session_key = data_blob_talloc( +- mem_ctx, NULL, 16); +- gnutls_hash_hd_t hash_hnd; +- uint8_t confounder[16]; + + ZERO_STRUCT(u_info); + +@@ -890,25 +889,16 @@ static bool join3(struct torture_context *tctx, + i21->password_expired = 1; + */ + +- encode_pw_buffer(u_info.info25.password.data, +- cli_credentials_get_password(wks_creds), +- STR_UNICODE); + status = dcerpc_fetch_session_key(samr_pipe, &session_key); + if (!NT_STATUS_IS_OK(status)) { + torture_comment(tctx, "dcerpc_fetch_session_key failed: %s\n", + nt_errstr(status)); + goto done; + } +- generate_random_buffer((uint8_t *)confounder, 16); + +- gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5); +- gnutls_hash(hash_hnd, confounder, 16); +- gnutls_hash(hash_hnd, session_key.data, session_key.length); +- gnutls_hash_deinit(hash_hnd, confounded_session_key.data); +- +- arcfour_crypt_blob(u_info.info25.password.data, 516, +- &confounded_session_key); +- memcpy(&u_info.info25.password.data[516], confounder, 16); ++ status = init_samr_CryptPasswordEx(cli_credentials_get_password(wks_creds), ++ &session_key, ++ &u_info.info25.password); + + sui2.in.user_handle = wks_handle; + sui2.in.level = 25; +@@ -942,8 +932,11 @@ static bool join3(struct torture_context *tctx, + torture_comment(tctx, "dcerpc_fetch_session_key failed\n"); + goto done; + } +- arcfour_crypt_blob(u_info.info24.password.data, 516, +- &session_key); ++ ++ status = init_samr_CryptPassword(cli_credentials_get_password(wks_creds), ++ &session_key, ++ &u_info.info24.password); ++ + sui2.in.user_handle = wks_handle; + sui2.in.info = &u_info; + sui2.in.level = 24; +-- +2.23.0 + diff --git a/SOURCES/0040-s4-torture-Use-init_samr_CryptPassword-in-test_SetUs.patch b/SOURCES/0040-s4-torture-Use-init_samr_CryptPassword-in-test_SetUs.patch new file mode 100644 index 0000000..a77f5d5 --- /dev/null +++ b/SOURCES/0040-s4-torture-Use-init_samr_CryptPassword-in-test_SetUs.patch @@ -0,0 +1,60 @@ +From 92a1bd505e5bb9c793f05b386d4e9ee2b2b74027 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 24 Jul 2019 15:56:08 +0200 +Subject: [PATCH 040/187] s4:torture: Use init_samr_CryptPassword in + test_SetUserPass + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 70e05d7eb78a0c363dbd72cbbf4f3a264636c840) +--- + source4/torture/rpc/samr.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c +index eb1bb14a555..f281be654cc 100644 +--- a/source4/torture/rpc/samr.c ++++ b/source4/torture/rpc/samr.c +@@ -31,7 +31,7 @@ + #include "librpc/gen_ndr/ndr_netlogon_c.h" + #include "librpc/gen_ndr/ndr_samr_c.h" + #include "librpc/gen_ndr/ndr_lsa_c.h" +-#include "../lib/crypto/crypto.h" ++#include "lib/crypto/crypto.h" + #include "libcli/auth/libcli_auth.h" + #include "libcli/security/security.h" + #include "torture/rpc/torture_rpc.h" +@@ -40,6 +40,8 @@ + #include "auth/gensec/gensec_proto.h" + #include "../libcli/auth/schannel.h" + #include "torture/util.h" ++#include "source4/librpc/rpc/dcerpc.h" ++#include "source3/rpc_client/init_samr.h" + + #define TEST_ACCOUNT_NAME "samrtorturetest" + #define TEST_ACCOUNT_NAME_PWD "samrpwdlastset" +@@ -637,7 +639,6 @@ static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx + s.in.info = &u; + s.in.level = 24; + +- encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE); + u.info24.password_expired = 0; + + status = dcerpc_fetch_session_key(p, &session_key); +@@ -647,7 +648,12 @@ static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx + return false; + } + +- arcfour_crypt_blob(u.info24.password.data, 516, &session_key); ++ status = init_samr_CryptPassword(newpass, ++ &session_key, ++ &u.info24.password); ++ torture_assert_ntstatus_ok(tctx, ++ status, ++ "init_samr_CryptPassword failed"); + + torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n"); + +-- +2.23.0 + diff --git a/SOURCES/0041-s4-torture-Use-init_samr_CryptPassword-in-test_SetUs.patch b/SOURCES/0041-s4-torture-Use-init_samr_CryptPassword-in-test_SetUs.patch new file mode 100644 index 0000000..f1c1ae2 --- /dev/null +++ b/SOURCES/0041-s4-torture-Use-init_samr_CryptPassword-in-test_SetUs.patch @@ -0,0 +1,72 @@ +From 2f7cd9ededefa6499f4fad15758fec27a15a5de3 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 24 Jul 2019 15:57:25 +0200 +Subject: [PATCH 041/187] s4:torture: Use init_samr_CryptPassword in + test_SetUserPass_23 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit b0b9cabc4de64497140d33d0fdaf2927f2915987) +--- + source4/torture/rpc/samr.c | 24 +++++++++++++++++------- + 1 file changed, 17 insertions(+), 7 deletions(-) + +diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c +index f281be654cc..543ef64e9ac 100644 +--- a/source4/torture/rpc/samr.c ++++ b/source4/torture/rpc/samr.c +@@ -706,8 +706,6 @@ static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *t + + u.info23.info.fields_present = fields_present; + +- encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE); +- + status = dcerpc_fetch_session_key(p, &session_key); + if (!NT_STATUS_IS_OK(status)) { + torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n", +@@ -715,7 +713,12 @@ static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *t + return false; + } + +- arcfour_crypt_blob(u.info23.password.data, 516, &session_key); ++ status = init_samr_CryptPassword(newpass, ++ &session_key, ++ &u.info23.password); ++ torture_assert_ntstatus_ok(tctx, ++ status, ++ "init_samr_CryptPassword failed"); + + torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n"); + +@@ -732,8 +735,6 @@ static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *t + *password = newpass; + } + +- encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE); +- + status = dcerpc_fetch_session_key(p, &session_key); + if (!NT_STATUS_IS_OK(status)) { + torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n", +@@ -742,8 +743,17 @@ static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *t + } + + /* This should break the key nicely */ +- session_key.length--; +- arcfour_crypt_blob(u.info23.password.data, 516, &session_key); ++ session_key.data[0]++; ++ ++ status = init_samr_CryptPassword(newpass, ++ &session_key, ++ &u.info23.password); ++ torture_assert_ntstatus_ok(tctx, ++ status, ++ "init_samr_CryptPassword failed"); ++ ++ /* Reset the session key */ ++ session_key.data[0]--; + + torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n"); + +-- +2.23.0 + diff --git a/SOURCES/0042-s4-torture-Use-init_samr_CryptPassword-in-test_SetUs.patch b/SOURCES/0042-s4-torture-Use-init_samr_CryptPassword-in-test_SetUs.patch new file mode 100644 index 0000000..3ab9eb6 --- /dev/null +++ b/SOURCES/0042-s4-torture-Use-init_samr_CryptPassword-in-test_SetUs.patch @@ -0,0 +1,87 @@ +From d56d8f629ea89a9a3cc7aecc17331ac5c57a61fa Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 24 Jul 2019 15:58:06 +0200 +Subject: [PATCH 042/187] s4:torture: Use init_samr_CryptPassword in + test_SetUserPassEx + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit e398ecbd8e32bb428073f3635d9178abfae28255) +--- + source4/torture/rpc/samr.c | 33 +++++++++++++++++---------------- + 1 file changed, 17 insertions(+), 16 deletions(-) + +diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c +index 543ef64e9ac..0e9989449be 100644 +--- a/source4/torture/rpc/samr.c ++++ b/source4/torture/rpc/samr.c +@@ -781,14 +781,12 @@ static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tc + union samr_UserInfo u; + bool ret = true; + DATA_BLOB session_key; +- DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16); +- uint8_t confounder[16]; + char *newpass; + struct dcerpc_binding_handle *b = p->binding_handle; +- gnutls_hash_hd_t hash_hnd; + struct samr_GetUserPwInfo pwp; + struct samr_PwInfo info; + int policy_min_pw_len = 0; ++ + pwp.in.user_handle = handle; + pwp.out.info = &info; + +@@ -807,7 +805,6 @@ static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tc + s.in.info = &u; + s.in.level = 26; + +- encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE); + u.info26.password_expired = 0; + + status = dcerpc_fetch_session_key(p, &session_key); +@@ -817,15 +814,12 @@ static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tc + return false; + } + +- generate_random_buffer((uint8_t *)confounder, 16); +- +- gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5); +- gnutls_hash(hash_hnd, confounder, 16); +- gnutls_hash(hash_hnd, session_key.data, session_key.length); +- gnutls_hash_deinit(hash_hnd, confounded_session_key.data); +- +- arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key); +- memcpy(&u.info26.password.data[516], confounder, 16); ++ status = init_samr_CryptPasswordEx(newpass, ++ &session_key, ++ &u.info26.password); ++ torture_assert_ntstatus_ok(tctx, ++ status, ++ "init_samr_CryptPasswordEx failed"); + + torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n"); + +@@ -843,10 +837,17 @@ static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tc + } + + /* This should break the key nicely */ +- confounded_session_key.data[0]++; ++ session_key.data[0]++; + +- arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key); +- memcpy(&u.info26.password.data[516], confounder, 16); ++ status = init_samr_CryptPasswordEx(newpass, ++ &session_key, ++ &u.info26.password); ++ torture_assert_ntstatus_ok(tctx, ++ status, ++ "init_samr_CryptPasswordEx failed"); ++ ++ /* Reset the key */ ++ session_key.data[0]--; + + torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n"); + +-- +2.23.0 + diff --git a/SOURCES/0043-s4-torture-Use-init_samr_CryptPassword-in-test_SetUs.patch b/SOURCES/0043-s4-torture-Use-init_samr_CryptPassword-in-test_SetUs.patch new file mode 100644 index 0000000..7a51b7f --- /dev/null +++ b/SOURCES/0043-s4-torture-Use-init_samr_CryptPassword-in-test_SetUs.patch @@ -0,0 +1,88 @@ +From 9f2f94aff0be089658eabd0c62896775332e1acb Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 24 Jul 2019 15:58:38 +0200 +Subject: [PATCH 043/187] s4:torture: Use init_samr_CryptPassword in + test_SetUserPass_25 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 3b9496d905408b75c21919b35b2105e2b0b0325f) +--- + source4/torture/rpc/samr.c | 34 +++++++++++++++++----------------- + 1 file changed, 17 insertions(+), 17 deletions(-) + +diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c +index 0e9989449be..2f67bcf6be7 100644 +--- a/source4/torture/rpc/samr.c ++++ b/source4/torture/rpc/samr.c +@@ -876,14 +876,12 @@ static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *t + union samr_UserInfo u; + bool ret = true; + DATA_BLOB session_key; +- DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16); +- gnutls_hash_hd_t hash_hnd; +- uint8_t confounder[16]; + char *newpass; + struct dcerpc_binding_handle *b = p->binding_handle; + struct samr_GetUserPwInfo pwp; + struct samr_PwInfo info; + int policy_min_pw_len = 0; ++ + pwp.in.user_handle = handle; + pwp.out.info = &info; + +@@ -902,8 +900,6 @@ static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *t + + u.info25.info.fields_present = fields_present; + +- encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE); +- + status = dcerpc_fetch_session_key(p, &session_key); + if (!NT_STATUS_IS_OK(status)) { + torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n", +@@ -911,15 +907,12 @@ static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *t + return false; + } + +- generate_random_buffer((uint8_t *)confounder, 16); +- +- gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5); +- gnutls_hash(hash_hnd, confounder, 16); +- gnutls_hash(hash_hnd, session_key.data, session_key.length); +- gnutls_hash_deinit(hash_hnd, confounded_session_key.data); +- +- arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key); +- memcpy(&u.info25.password.data[516], confounder, 16); ++ status = init_samr_CryptPasswordEx(newpass, ++ &session_key, ++ &u.info25.password); ++ torture_assert_ntstatus_ok(tctx, ++ status, ++ "init_samr_CryptPasswordEx failed"); + + torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n"); + +@@ -937,10 +930,17 @@ static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *t + } + + /* This should break the key nicely */ +- confounded_session_key.data[0]++; ++ session_key.data[0]++; + +- arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key); +- memcpy(&u.info25.password.data[516], confounder, 16); ++ status = init_samr_CryptPasswordEx(newpass, ++ &session_key, ++ &u.info25.password); ++ torture_assert_ntstatus_ok(tctx, ++ status, ++ "init_samr_CryptPasswordEx failed"); ++ ++ /* Reset the key */ ++ session_key.data[0]--; + + torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n"); + +-- +2.23.0 + diff --git a/SOURCES/0044-s4-torture-Use-init_samr_CryptPassword-in-test_SetUs.patch b/SOURCES/0044-s4-torture-Use-init_samr_CryptPassword-in-test_SetUs.patch new file mode 100644 index 0000000..05ba0aa --- /dev/null +++ b/SOURCES/0044-s4-torture-Use-init_samr_CryptPassword-in-test_SetUs.patch @@ -0,0 +1,116 @@ +From 905ffa85002a4100172835c550547bab024ef30f Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 24 Jul 2019 15:59:19 +0200 +Subject: [PATCH 044/187] s4:torture: Use init_samr_CryptPassword in + test_SetUserPass_level_ex + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit f45ba47afb11c1f7bbb8c5c84670395500e1afc1) +--- + source4/torture/rpc/samr.c | 48 +++++++++++++++++++------------------- + 1 file changed, 24 insertions(+), 24 deletions(-) + +diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c +index 2f67bcf6be7..530c457bbd9 100644 +--- a/source4/torture/rpc/samr.c ++++ b/source4/torture/rpc/samr.c +@@ -1166,9 +1166,6 @@ static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p, + union samr_UserInfo u; + bool ret = true; + DATA_BLOB session_key; +- DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16); +- gnutls_hash_hd_t hash_hnd; +- uint8_t confounder[16]; + char *newpass; + struct dcerpc_binding_handle *b = p->binding_handle; + struct samr_GetUserPwInfo pwp; +@@ -1244,28 +1241,20 @@ static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p, + u.info23.info.password_expired = password_expired; + u.info23.info.comment.string = comment; + +- encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE); +- + break; + case 24: + u.info24.password_expired = password_expired; + +- encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE); +- + break; + case 25: + u.info25.info.fields_present = fields_present; + u.info25.info.password_expired = password_expired; + u.info25.info.comment.string = comment; + +- encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE); +- + break; + case 26: + u.info26.password_expired = password_expired; + +- encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE); +- + break; + } + +@@ -1276,13 +1265,6 @@ static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p, + return false; + } + +- generate_random_buffer((uint8_t *)confounder, 16); +- +- gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5); +- gnutls_hash(hash_hnd, confounder, 16); +- gnutls_hash(hash_hnd, session_key.data, session_key.length); +- gnutls_hash_deinit(hash_hnd, confounded_session_key.data); +- + switch (level) { + case 18: + { +@@ -1320,18 +1302,36 @@ static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p, + } + break; + case 23: +- arcfour_crypt_blob(u.info23.password.data, 516, &session_key); ++ status = init_samr_CryptPassword(newpass, ++ &session_key, ++ &u.info23.password); ++ torture_assert_ntstatus_ok(tctx, ++ status, ++ "init_samr_CryptPassword failed"); + break; + case 24: +- arcfour_crypt_blob(u.info24.password.data, 516, &session_key); ++ status = init_samr_CryptPassword(newpass, ++ &session_key, ++ &u.info24.password); ++ torture_assert_ntstatus_ok(tctx, ++ status, ++ "init_samr_CryptPassword failed"); + break; + case 25: +- arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key); +- memcpy(&u.info25.password.data[516], confounder, 16); ++ status = init_samr_CryptPasswordEx(newpass, ++ &session_key, ++ &u.info25.password); ++ torture_assert_ntstatus_ok(tctx, ++ status, ++ "init_samr_CryptPasswordEx failed"); + break; + case 26: +- arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key); +- memcpy(&u.info26.password.data[516], confounder, 16); ++ status = init_samr_CryptPasswordEx(newpass, ++ &session_key, ++ &u.info26.password); ++ torture_assert_ntstatus_ok(tctx, ++ status, ++ "init_samr_CryptPasswordEx failed"); + break; + } + +-- +2.23.0 + diff --git a/SOURCES/0045-s4-torture-Use-GnuTLS-RC4-in-test_OemChangePasswordU.patch b/SOURCES/0045-s4-torture-Use-GnuTLS-RC4-in-test_OemChangePasswordU.patch new file mode 100644 index 0000000..140daba --- /dev/null +++ b/SOURCES/0045-s4-torture-Use-GnuTLS-RC4-in-test_OemChangePasswordU.patch @@ -0,0 +1,91 @@ +From 752f6efc6ac65cba6b8ebf125b19a6685a0d40c2 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 24 Jul 2019 16:49:53 +0200 +Subject: [PATCH 045/187] s4:torture: Use GnuTLS RC4 in + test_OemChangePasswordUser2 + +This uses STR_ASCII for password encoding! + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit b512b5974494fe41010800f60df0f248b8ea850e) +--- + source4/torture/rpc/samr.c | 34 ++++++++++++++++++++++++++++++---- + 1 file changed, 30 insertions(+), 4 deletions(-) + +diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c +index 530c457bbd9..eb032905dc8 100644 +--- a/source4/torture/rpc/samr.c ++++ b/source4/torture/rpc/samr.c +@@ -2032,6 +2032,11 @@ static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, + char *newpass; + struct dcerpc_binding_handle *b = p->binding_handle; + uint8_t old_lm_hash[16], new_lm_hash[16]; ++ gnutls_cipher_hd_t cipher_hnd = NULL; ++ gnutls_datum_t session_key = { ++ .data = old_lm_hash, ++ .size = 16 ++ }; + + struct samr_GetDomPwInfo dom_pw_info; + struct samr_PwInfo info; +@@ -2065,7 +2070,13 @@ static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, + E_deshash(newpass, new_lm_hash); + + encode_pw_buffer(lm_pass.data, newpass, STR_ASCII); +- arcfour_crypt(lm_pass.data, old_lm_hash, 516); ++ ++ gnutls_cipher_init(&cipher_hnd, ++ GNUTLS_CIPHER_ARCFOUR_128, ++ &session_key, ++ NULL); ++ gnutls_cipher_encrypt(cipher_hnd, lm_pass.data, 516); ++ gnutls_cipher_deinit(cipher_hnd); + E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash); + + r.in.server = &server; +@@ -2092,7 +2103,12 @@ static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, + encode_pw_buffer(lm_pass.data, newpass, STR_ASCII); + /* Break the old password */ + old_lm_hash[0]++; +- arcfour_crypt(lm_pass.data, old_lm_hash, 516); ++ gnutls_cipher_init(&cipher_hnd, ++ GNUTLS_CIPHER_ARCFOUR_128, ++ &session_key, ++ NULL); ++ gnutls_cipher_encrypt(cipher_hnd, lm_pass.data, 516); ++ gnutls_cipher_deinit(cipher_hnd); + /* unbreak it for the next operation */ + old_lm_hash[0]--; + E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash); +@@ -2116,7 +2132,12 @@ static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, + } + + encode_pw_buffer(lm_pass.data, newpass, STR_ASCII); +- arcfour_crypt(lm_pass.data, old_lm_hash, 516); ++ gnutls_cipher_init(&cipher_hnd, ++ GNUTLS_CIPHER_ARCFOUR_128, ++ &session_key, ++ NULL); ++ gnutls_cipher_encrypt(cipher_hnd, lm_pass.data, 516); ++ gnutls_cipher_deinit(cipher_hnd); + + r.in.server = &server; + r.in.account = &account; +@@ -2192,7 +2213,12 @@ static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, + E_deshash(newpass, new_lm_hash); + + encode_pw_buffer(lm_pass.data, newpass, STR_ASCII); +- arcfour_crypt(lm_pass.data, old_lm_hash, 516); ++ gnutls_cipher_init(&cipher_hnd, ++ GNUTLS_CIPHER_ARCFOUR_128, ++ &session_key, ++ NULL); ++ gnutls_cipher_encrypt(cipher_hnd, lm_pass.data, 516); ++ gnutls_cipher_deinit(cipher_hnd); + E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash); + + r.in.server = &server; +-- +2.23.0 + diff --git a/SOURCES/0046-s4-torture-Use-init_samr_CryptPassword-in-test_Chang.patch b/SOURCES/0046-s4-torture-Use-init_samr_CryptPassword-in-test_Chang.patch new file mode 100644 index 0000000..f32323c --- /dev/null +++ b/SOURCES/0046-s4-torture-Use-init_samr_CryptPassword-in-test_Chang.patch @@ -0,0 +1,53 @@ +From 88d136aae60d4aa8b6fe622e0e92a8bddbba1b1e Mon Sep 17 00:00:00 2001 +From: Andrew Bartlett +Date: Thu, 25 Jul 2019 16:46:06 +1200 +Subject: [PATCH 046/187] s4:torture: Use init_samr_CryptPassword in + test_ChangePasswordUser2 + +This allows the use of GnuTLS for the RC4 crypto operation + +Signed-off-by: Andrew Bartlett +Reviewed-by: Andreas Schneider +(cherry picked from commit dfda49472e0b4a81653963e80d8d65788f80a591) +--- + source4/torture/rpc/samr.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c +index eb032905dc8..6cc508a2d44 100644 +--- a/source4/torture/rpc/samr.c ++++ b/source4/torture/rpc/samr.c +@@ -2259,11 +2259,13 @@ static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_conte + struct dcerpc_binding_handle *b = p->binding_handle; + uint8_t old_nt_hash[16], new_nt_hash[16]; + uint8_t old_lm_hash[16], new_lm_hash[16]; +- ++ DATA_BLOB old_nt_hash_blob ++ = data_blob_const(old_nt_hash, sizeof(old_nt_hash)); + struct samr_GetDomPwInfo dom_pw_info; + struct samr_PwInfo info; + + struct lsa_String domain_name; ++ NTSTATUS status; + + domain_name.string = ""; + dom_pw_info.in.domain_name = &domain_name; +@@ -2299,8 +2301,13 @@ static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_conte + arcfour_crypt(lm_pass.data, old_lm_hash, 516); + E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash); + +- encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE); +- arcfour_crypt(nt_pass.data, old_nt_hash, 516); ++ status = init_samr_CryptPassword(newpass, ++ &old_nt_hash_blob, ++ &nt_pass); ++ torture_assert_ntstatus_ok(tctx, ++ status, ++ "init_samr_CryptPassword failed"); ++ + E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash); + + r.in.server = &server; +-- +2.23.0 + diff --git a/SOURCES/0047-s4-torture-Use-init_samr_CryptPassword-in-test_Chang.patch b/SOURCES/0047-s4-torture-Use-init_samr_CryptPassword-in-test_Chang.patch new file mode 100644 index 0000000..f4b58d8 --- /dev/null +++ b/SOURCES/0047-s4-torture-Use-init_samr_CryptPassword-in-test_Chang.patch @@ -0,0 +1,54 @@ +From 90bdf8b2063c05576450975df0983953d6febd95 Mon Sep 17 00:00:00 2001 +From: Andrew Bartlett +Date: Thu, 25 Jul 2019 16:52:41 +1200 +Subject: [PATCH 047/187] s4:torture: Use init_samr_CryptPassword in + test_ChangePasswordUser2_ntstatus + +This allows the use of GnuTLS for the RC4 crypto operation + +Signed-off-by: Andrew Bartlett +Reviewed-by: Andreas Schneider +(cherry picked from commit 1b1c302a7db23bf4377b8fa742ebf7ae913e3511) +--- + source4/torture/rpc/samr.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c +index 6cc508a2d44..5bf758e2fb2 100644 +--- a/source4/torture/rpc/samr.c ++++ b/source4/torture/rpc/samr.c +@@ -2349,11 +2349,15 @@ static bool test_ChangePasswordUser2_ntstatus(struct dcerpc_pipe *p, struct tort + struct dcerpc_binding_handle *b = p->binding_handle; + uint8_t old_nt_hash[16], new_nt_hash[16]; + uint8_t old_lm_hash[16], new_lm_hash[16]; ++ DATA_BLOB old_nt_hash_blob ++ = data_blob_const(old_nt_hash, sizeof(old_nt_hash)); + + struct samr_GetDomPwInfo dom_pw_info; + struct samr_PwInfo info; + + struct lsa_String domain_name; ++ NTSTATUS crypt_status; ++ + char *newpass; + int policy_min_pw_len = 0; + +@@ -2386,8 +2390,13 @@ static bool test_ChangePasswordUser2_ntstatus(struct dcerpc_pipe *p, struct tort + arcfour_crypt(lm_pass.data, old_lm_hash, 516); + E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash); + +- encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE); +- arcfour_crypt(nt_pass.data, old_nt_hash, 516); ++ crypt_status = init_samr_CryptPassword(newpass, ++ &old_nt_hash_blob, ++ &nt_pass); ++ torture_assert_ntstatus_ok(tctx, ++ crypt_status, ++ "init_samr_CryptPassword failed"); ++ + E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash); + + r.in.server = &server; +-- +2.23.0 + diff --git a/SOURCES/0048-s4_torture-Use-GnuTLS-RC4-in-test_ChangePasswordUser.patch b/SOURCES/0048-s4_torture-Use-GnuTLS-RC4-in-test_ChangePasswordUser.patch new file mode 100644 index 0000000..2ab75d9 --- /dev/null +++ b/SOURCES/0048-s4_torture-Use-GnuTLS-RC4-in-test_ChangePasswordUser.patch @@ -0,0 +1,57 @@ +From b21a4ac4a6d92d720e1e04b9eadf50cc59a4ebe5 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 24 Jul 2019 16:24:18 +0200 +Subject: [PATCH 048/187] s4_torture: Use GnuTLS RC4 in + test_ChangePasswordUser2 + +This uses STR_ASCII as string encodings. + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 9cbdf7b2e5f734e9b5e0e447d54d720d18977950) +--- + source4/torture/rpc/samr.c | 21 ++++++++++++++++++++- + 1 file changed, 20 insertions(+), 1 deletion(-) + +diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c +index 5bf758e2fb2..7f1da86d19a 100644 +--- a/source4/torture/rpc/samr.c ++++ b/source4/torture/rpc/samr.c +@@ -2267,6 +2267,16 @@ static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_conte + struct lsa_String domain_name; + NTSTATUS status; + ++ gnutls_cipher_hd_t cipher_hnd = NULL; ++ gnutls_datum_t old_lm_key = { ++ .data = old_lm_hash, ++ .size = sizeof(old_lm_hash), ++ }; ++ gnutls_datum_t old_nt_key = { ++ .data = old_nt_hash, ++ .size = sizeof(old_nt_hash), ++ }; ++ + domain_name.string = ""; + dom_pw_info.in.domain_name = &domain_name; + dom_pw_info.out.info = &info; +@@ -2298,7 +2308,16 @@ static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_conte + E_deshash(newpass, new_lm_hash); + + encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE); +- arcfour_crypt(lm_pass.data, old_lm_hash, 516); ++ ++ gnutls_cipher_init(&cipher_hnd, ++ GNUTLS_CIPHER_ARCFOUR_128, ++ &old_lm_key, ++ NULL); ++ gnutls_cipher_encrypt(cipher_hnd, ++ lm_pass.data, ++ 516); ++ gnutls_cipher_deinit(cipher_hnd); ++ + E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash); + + status = init_samr_CryptPassword(newpass, +-- +2.23.0 + diff --git a/SOURCES/0049-s4-torture-Use-GnuTLS-RC4-in-test_ChangePasswordUser.patch b/SOURCES/0049-s4-torture-Use-GnuTLS-RC4-in-test_ChangePasswordUser.patch new file mode 100644 index 0000000..e4f81c2 --- /dev/null +++ b/SOURCES/0049-s4-torture-Use-GnuTLS-RC4-in-test_ChangePasswordUser.patch @@ -0,0 +1,61 @@ +From b7700aa619a69f652b350b89a5a67a989658a474 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 24 Jul 2019 16:00:32 +0200 +Subject: [PATCH 049/187] s4:torture: Use GnuTLS RC4 in + test_ChangePasswordUser2_ntstatus + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit a476a2e3322a550e2857cb5a66096fa3e46416d3) +--- + source4/torture/rpc/samr.c | 20 +++++++++++++++----- + 1 file changed, 15 insertions(+), 5 deletions(-) + +diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c +index 7f1da86d19a..307b0b03594 100644 +--- a/source4/torture/rpc/samr.c ++++ b/source4/torture/rpc/samr.c +@@ -2272,10 +2272,6 @@ static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_conte + .data = old_lm_hash, + .size = sizeof(old_lm_hash), + }; +- gnutls_datum_t old_nt_key = { +- .data = old_nt_hash, +- .size = sizeof(old_nt_hash), +- }; + + domain_name.string = ""; + dom_pw_info.in.domain_name = &domain_name; +@@ -2370,6 +2366,11 @@ static bool test_ChangePasswordUser2_ntstatus(struct dcerpc_pipe *p, struct tort + uint8_t old_lm_hash[16], new_lm_hash[16]; + DATA_BLOB old_nt_hash_blob + = data_blob_const(old_nt_hash, sizeof(old_nt_hash)); ++ gnutls_cipher_hd_t cipher_hnd = NULL; ++ gnutls_datum_t old_lm_key = { ++ .data = old_lm_hash, ++ .size = sizeof(old_lm_hash), ++ }; + + struct samr_GetDomPwInfo dom_pw_info; + struct samr_PwInfo info; +@@ -2406,7 +2407,16 @@ static bool test_ChangePasswordUser2_ntstatus(struct dcerpc_pipe *p, struct tort + E_deshash(newpass, new_lm_hash); + + encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE); +- arcfour_crypt(lm_pass.data, old_lm_hash, 516); ++ ++ gnutls_cipher_init(&cipher_hnd, ++ GNUTLS_CIPHER_ARCFOUR_128, ++ &old_lm_key, ++ NULL); ++ gnutls_cipher_encrypt(cipher_hnd, ++ lm_pass.data, ++ 516); ++ gnutls_cipher_deinit(cipher_hnd); ++ + E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash); + + crypt_status = init_samr_CryptPassword(newpass, +-- +2.23.0 + diff --git a/SOURCES/0050-s4-torture-Use-init_samr_CryptPassword-in-test_Chang.patch b/SOURCES/0050-s4-torture-Use-init_samr_CryptPassword-in-test_Chang.patch new file mode 100644 index 0000000..c6cb255 --- /dev/null +++ b/SOURCES/0050-s4-torture-Use-init_samr_CryptPassword-in-test_Chang.patch @@ -0,0 +1,119 @@ +From e3c6cd617dc324d86212a50555adbeffb966555c Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 24 Jul 2019 16:01:02 +0200 +Subject: [PATCH 050/187] s4:torture: Use init_samr_CryptPassword in + test_ChangePasswordUser3 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 5b7c21fca576bf6e44233d69b47273058b9197c8) +--- + source4/torture/rpc/samr.c | 64 +++++++++++++++++++++++++++++--------- + 1 file changed, 49 insertions(+), 15 deletions(-) + +diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c +index 307b0b03594..55059a26b43 100644 +--- a/source4/torture/rpc/samr.c ++++ b/source4/torture/rpc/samr.c +@@ -2472,6 +2472,8 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct + NTTIME t; + struct samr_DomInfo1 *dominfo = NULL; + struct userPwdChangeFailureInformation *reject = NULL; ++ DATA_BLOB session_key = data_blob_const(old_nt_hash, 16); ++ NTSTATUS status; + + torture_comment(tctx, "Testing ChangePasswordUser3\n"); + +@@ -2500,12 +2502,22 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct + E_deshash(oldpass, old_lm_hash); + E_deshash(newpass, new_lm_hash); + +- encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE); +- arcfour_crypt(lm_pass.data, old_nt_hash, 516); ++ status = init_samr_CryptPassword(newpass, ++ &session_key, ++ &lm_pass); ++ torture_assert_ntstatus_ok(tctx, ++ status, ++ "init_samr_CryptPassword"); ++ + E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash); + +- encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE); +- arcfour_crypt(nt_pass.data, old_nt_hash, 516); ++ status = init_samr_CryptPassword(newpass, ++ &session_key, ++ &nt_pass); ++ torture_assert_ntstatus_ok(tctx, ++ status, ++ "init_samr_CryptPassword"); ++ + E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash); + + /* Break the verification */ +@@ -2534,16 +2546,28 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct + ret = false; + } + +- encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE); +- arcfour_crypt(lm_pass.data, old_nt_hash, 516); ++ status = init_samr_CryptPassword(newpass, ++ &session_key, ++ &lm_pass); ++ torture_assert_ntstatus_ok(tctx, ++ status, ++ "init_samr_CryptPassword"); ++ + E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash); + +- encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE); +- /* Break the NT hash */ +- old_nt_hash[0]++; +- arcfour_crypt(nt_pass.data, old_nt_hash, 516); ++ /* Break the session key */ ++ session_key.data[0]++; ++ ++ status = init_samr_CryptPassword(newpass, ++ &session_key, ++ &nt_pass); ++ torture_assert_ntstatus_ok(tctx, ++ status, ++ "init_samr_CryptPassword"); ++ + /* Unbreak it again */ +- old_nt_hash[0]--; ++ session_key.data[0]--; ++ + E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash); + + r.in.server = &server; +@@ -2590,12 +2614,22 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct + E_deshash(oldpass, old_lm_hash); + E_deshash(newpass, new_lm_hash); + +- encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE); +- arcfour_crypt(lm_pass.data, old_nt_hash, 516); ++ status = init_samr_CryptPassword(newpass, ++ &session_key, ++ &lm_pass); ++ torture_assert_ntstatus_ok(tctx, ++ status, ++ "init_samr_CryptPassword"); ++ + E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash); + +- encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE); +- arcfour_crypt(nt_pass.data, old_nt_hash, 516); ++ status = init_samr_CryptPassword(newpass, ++ &session_key, ++ &nt_pass); ++ torture_assert_ntstatus_ok(tctx, ++ status, ++ "init_samr_CryptPassword"); ++ + E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash); + + r.in.server = &server; +-- +2.23.0 + diff --git a/SOURCES/0051-s4-torture-clarify-comments-and-variable-names-in-Ch.patch b/SOURCES/0051-s4-torture-clarify-comments-and-variable-names-in-Ch.patch new file mode 100644 index 0000000..d0243ab --- /dev/null +++ b/SOURCES/0051-s4-torture-clarify-comments-and-variable-names-in-Ch.patch @@ -0,0 +1,130 @@ +From f0d05dc2dce30f851f9e1eb6a1952730dfe907f6 Mon Sep 17 00:00:00 2001 +From: Andrew Bartlett +Date: Thu, 25 Jul 2019 17:18:50 +1200 +Subject: [PATCH 051/187] s4:torture: clarify comments and variable names in + "ChangePasswordUser3 tests + +There is no session key here, the buffers are directly encrypted +with the long-term passwords. + +Signed-off-by: Andrew Bartlett +Reviewed-by: Andreas Schneider +(cherry picked from commit 8380668be7963b74cbbd31bfab3d01d1f3089034) +--- + source4/torture/rpc/samr.c | 43 +++++++++++++++++++++++++++++--------- + 1 file changed, 33 insertions(+), 10 deletions(-) + +diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c +index 55059a26b43..20afa9392e2 100644 +--- a/source4/torture/rpc/samr.c ++++ b/source4/torture/rpc/samr.c +@@ -2472,7 +2472,7 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct + NTTIME t; + struct samr_DomInfo1 *dominfo = NULL; + struct userPwdChangeFailureInformation *reject = NULL; +- DATA_BLOB session_key = data_blob_const(old_nt_hash, 16); ++ DATA_BLOB old_nt_hash_blob = data_blob_const(old_nt_hash, 16); + NTSTATUS status; + + torture_comment(tctx, "Testing ChangePasswordUser3\n"); +@@ -2502,22 +2502,45 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct + E_deshash(oldpass, old_lm_hash); + E_deshash(newpass, new_lm_hash); + ++ /* ++ * The new plaintext password is encrypted using RC4 with the ++ * old NT password hash (directly, with no confounder). The ++ * password is at the end of the random padded buffer, ++ * offering a little protection. ++ * ++ * This is almost certainly wrong, it should be the old LM ++ * hash, it was switched in an unrelated commit ++ * 579c13da43d5b40ac6d6c1436399fbc1d8dfd054 in 2004. ++ */ + status = init_samr_CryptPassword(newpass, +- &session_key, ++ &old_nt_hash_blob, + &lm_pass); + torture_assert_ntstatus_ok(tctx, + status, + "init_samr_CryptPassword"); + ++ /* ++ * Now we prepare a DES cross-hash of the old LM and new NT ++ * passwords to link the two buffers ++ */ + E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash); + ++ /* ++ * The new plaintext password is also encrypted using RC4 with ++ * the old NT password hash (directly, with no confounder). ++ * The password is at the end of the random padded buffer, ++ * offering a little protection. ++ */ + status = init_samr_CryptPassword(newpass, +- &session_key, ++ &old_nt_hash_blob, + &nt_pass); + torture_assert_ntstatus_ok(tctx, + status, + "init_samr_CryptPassword"); + ++ /* ++ * Another DES based cross-hash ++ */ + E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash); + + /* Break the verification */ +@@ -2547,7 +2570,7 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct + } + + status = init_samr_CryptPassword(newpass, +- &session_key, ++ &old_nt_hash_blob, + &lm_pass); + torture_assert_ntstatus_ok(tctx, + status, +@@ -2555,18 +2578,18 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct + + E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash); + +- /* Break the session key */ +- session_key.data[0]++; ++ /* Break the NT Hash */ ++ old_nt_hash[0]++; + + status = init_samr_CryptPassword(newpass, +- &session_key, ++ &old_nt_hash_blob, + &nt_pass); + torture_assert_ntstatus_ok(tctx, + status, + "init_samr_CryptPassword"); + + /* Unbreak it again */ +- session_key.data[0]--; ++ old_nt_hash[0]--; + + E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash); + +@@ -2615,7 +2638,7 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct + E_deshash(newpass, new_lm_hash); + + status = init_samr_CryptPassword(newpass, +- &session_key, ++ &old_nt_hash_blob, + &lm_pass); + torture_assert_ntstatus_ok(tctx, + status, +@@ -2624,7 +2647,7 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct + E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash); + + status = init_samr_CryptPassword(newpass, +- &session_key, ++ &old_nt_hash_blob, + &nt_pass); + torture_assert_ntstatus_ok(tctx, + status, +-- +2.23.0 + diff --git a/SOURCES/0052-s4-torture-Use-init_samr_CryptPassword-in-test_Chang.patch b/SOURCES/0052-s4-torture-Use-init_samr_CryptPassword-in-test_Chang.patch new file mode 100644 index 0000000..55095de --- /dev/null +++ b/SOURCES/0052-s4-torture-Use-init_samr_CryptPassword-in-test_Chang.patch @@ -0,0 +1,48 @@ +From 7ce6d4730f7ff8c5008ad91d665a172fec8e5ba8 Mon Sep 17 00:00:00 2001 +From: Andrew Bartlett +Date: Thu, 25 Jul 2019 17:43:23 +1200 +Subject: [PATCH 052/187] s4:torture: Use init_samr_CryptPassword in + test_ChangePasswordRandomBytes + +This allows the use of GnuTLS for the underlying RC4 crypto + +Signed-off-by: Andrew Bartlett +Reviewed-by: Andreas Schneider +(cherry picked from commit 19d9c2c01a54957bc3852e2565d92c1cdd89498b) +--- + source4/torture/rpc/samr.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c +index 20afa9392e2..10377850314 100644 +--- a/source4/torture/rpc/samr.c ++++ b/source4/torture/rpc/samr.c +@@ -2790,6 +2790,9 @@ bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_contex + char *oldpass; + struct dcerpc_binding_handle *b = p->binding_handle; + uint8_t old_nt_hash[16], new_nt_hash[16]; ++ DATA_BLOB old_nt_hash_blob ++ = data_blob_const(old_nt_hash, ++ sizeof(old_nt_hash)); + NTTIME t; + struct samr_DomInfo1 *dominfo = NULL; + struct userPwdChangeFailureInformation *reject = NULL; +@@ -2893,8 +2896,13 @@ bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_contex + + E_md4hash(newpass, new_nt_hash); + +- encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE); +- arcfour_crypt(nt_pass.data, old_nt_hash, 516); ++ status = init_samr_CryptPassword(newpass, ++ &old_nt_hash_blob, ++ &nt_pass); ++ torture_assert_ntstatus_ok(tctx, ++ status, ++ "init_samr_CryptPassword failed"); ++ + E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash); + + r.in.server = &server; +-- +2.23.0 + diff --git a/SOURCES/0053-s4-torture-Use-GnuTLS-RC4-in-test_ChangePasswordRand.patch b/SOURCES/0053-s4-torture-Use-GnuTLS-RC4-in-test_ChangePasswordRand.patch new file mode 100644 index 0000000..ef6822c --- /dev/null +++ b/SOURCES/0053-s4-torture-Use-GnuTLS-RC4-in-test_ChangePasswordRand.patch @@ -0,0 +1,51 @@ +From 74f61d6ecf74311a12e8454f2ce12a4b63bbfe90 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 24 Jul 2019 16:01:31 +0200 +Subject: [PATCH 053/187] s4:torture: Use GnuTLS RC4 in + test_ChangePasswordRandomBytes + +Signed-off-by: Andreas Schneider +Signed-off-by: Andrew Bartlett +Reviewed-by: Andrew Bartlett +(cherry picked from commit 82a6480611f791a3c26fcf70975e6f8b3b1757ad) +--- + source4/torture/rpc/samr.c | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + +diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c +index 10377850314..10bdd52fd47 100644 +--- a/source4/torture/rpc/samr.c ++++ b/source4/torture/rpc/samr.c +@@ -2796,6 +2796,11 @@ bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_contex + NTTIME t; + struct samr_DomInfo1 *dominfo = NULL; + struct userPwdChangeFailureInformation *reject = NULL; ++ gnutls_cipher_hd_t cipher_hnd = NULL; ++ gnutls_datum_t old_nt_key = { ++ .data = old_nt_hash, ++ .size = sizeof(old_nt_hash), ++ }; + + new_random_pass = samr_very_rand_pass(tctx, 128); + +@@ -2855,7 +2860,16 @@ bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_contex + mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length); + + set_pw_in_buffer(nt_pass.data, &new_random_pass); +- arcfour_crypt(nt_pass.data, old_nt_hash, 516); ++ ++ gnutls_cipher_init(&cipher_hnd, ++ GNUTLS_CIPHER_ARCFOUR_128, ++ &old_nt_key, ++ NULL); ++ gnutls_cipher_encrypt(cipher_hnd, ++ nt_pass.data, ++ 516); ++ gnutls_cipher_deinit(cipher_hnd); ++ + E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash); + + r.in.server = &server; +-- +2.23.0 + diff --git a/SOURCES/0054-s4-torture-Use-samba_gnutls_arcfour_confounded_md5-i.patch b/SOURCES/0054-s4-torture-Use-samba_gnutls_arcfour_confounded_md5-i.patch new file mode 100644 index 0000000..659209c --- /dev/null +++ b/SOURCES/0054-s4-torture-Use-samba_gnutls_arcfour_confounded_md5-i.patch @@ -0,0 +1,84 @@ +From 0f56ee5720764eec28ce23bc82a01c16411df5fb Mon Sep 17 00:00:00 2001 +From: Andrew Bartlett +Date: Thu, 25 Jul 2019 13:07:48 +1200 +Subject: [PATCH 054/187] s4:torture: Use samba_gnutls_arcfour_confounded_md5() + in test_ChangePasswordRandomBytes + +This ensures GnuTLS is used as the underlying RC4 crypto engine + +Signed-off-by: Andrew Bartlett +Reviewed-by: Andreas Schneider +(cherry picked from commit 5740e9516f3587e3a9f72cf52cfe1eedd940b2a9) +--- + source4/torture/rpc/samr.c | 25 +++++++++++++++---------- + 1 file changed, 15 insertions(+), 10 deletions(-) + +diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c +index 10bdd52fd47..4b3ad093bf6 100644 +--- a/source4/torture/rpc/samr.c ++++ b/source4/torture/rpc/samr.c +@@ -42,6 +42,7 @@ + #include "torture/util.h" + #include "source4/librpc/rpc/dcerpc.h" + #include "source3/rpc_client/init_samr.h" ++#include "lib/crypto/gnutls_helpers.h" + + #define TEST_ACCOUNT_NAME "samrtorturetest" + #define TEST_ACCOUNT_NAME_PWD "samrpwdlastset" +@@ -2777,9 +2778,6 @@ bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_contex + struct samr_SetUserInfo s; + union samr_UserInfo u; + DATA_BLOB session_key; +- DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16); +- uint8_t confounder[16]; +- gnutls_hash_hd_t hash_hnd; + + bool ret = true; + struct lsa_String server, account; +@@ -2797,6 +2795,11 @@ bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_contex + struct samr_DomInfo1 *dominfo = NULL; + struct userPwdChangeFailureInformation *reject = NULL; + gnutls_cipher_hd_t cipher_hnd = NULL; ++ uint8_t _confounder[16] = {0}; ++ DATA_BLOB confounder ++ = data_blob_const(_confounder, ++ sizeof(_confounder)); ++ DATA_BLOB pw_data; + gnutls_datum_t old_nt_key = { + .data = old_nt_hash, + .size = sizeof(old_nt_hash), +@@ -2821,6 +2824,8 @@ bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_contex + + set_pw_in_buffer(u.info25.password.data, &new_random_pass); + ++ pw_data = data_blob_const(u.info25.password.data, 516); ++ + status = dcerpc_fetch_session_key(p, &session_key); + if (!NT_STATUS_IS_OK(status)) { + torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n", +@@ -2828,15 +2833,15 @@ bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_contex + return false; + } + +- generate_random_buffer((uint8_t *)confounder, 16); ++ generate_random_buffer(_confounder, ++ sizeof(_confounder)); + +- gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5); +- gnutls_hash(hash_hnd, confounder, 16); +- gnutls_hash(hash_hnd, session_key.data, session_key.length); +- gnutls_hash_deinit(hash_hnd, confounded_session_key.data); ++ samba_gnutls_arcfour_confounded_md5(&confounder, ++ &session_key, ++ &pw_data, ++ SAMBA_GNUTLS_ENCRYPT); + +- arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key); +- memcpy(&u.info25.password.data[516], confounder, 16); ++ memcpy(&u.info25.password.data[516], _confounder, sizeof(_confounder)); + + torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n"); + +-- +2.23.0 + diff --git a/SOURCES/0055-s4-torture-Use-init_samr_CryptPassword-in-testjoin-R.patch b/SOURCES/0055-s4-torture-Use-init_samr_CryptPassword-in-testjoin-R.patch new file mode 100644 index 0000000..f06f4f9 --- /dev/null +++ b/SOURCES/0055-s4-torture-Use-init_samr_CryptPassword-in-testjoin-R.patch @@ -0,0 +1,68 @@ +From e1fd1c24002f30d31367d1caa59ccb057e8c9794 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Fri, 22 Feb 2019 13:06:34 +0100 +Subject: [PATCH 055/187] s4:torture: Use init_samr_CryptPassword in testjoin + RPC test + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 301544ab2b0c85752d5307f2daab59652c08e1e0) +--- + source4/torture/rpc/testjoin.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/source4/torture/rpc/testjoin.c b/source4/torture/rpc/testjoin.c +index c4e287d579b..11394b1c277 100644 +--- a/source4/torture/rpc/testjoin.c ++++ b/source4/torture/rpc/testjoin.c +@@ -26,7 +26,6 @@ + + #include "includes.h" + #include "system/time.h" +-#include "../lib/crypto/crypto.h" + #include "libnet/libnet.h" + #include "lib/cmdline/popt_common.h" + #include "librpc/gen_ndr/ndr_lsa_c.h" +@@ -36,6 +35,7 @@ + #include "torture/rpc/torture_rpc.h" + #include "libcli/security/security.h" + #include "param/param.h" ++#include "source3/rpc_client/init_samr.h" + + struct test_join { + struct dcerpc_pipe *p; +@@ -145,7 +145,6 @@ struct test_join *torture_create_testuser_max_pwlen(struct torture_context *tctx + char *random_pw; + const char *dc_binding = torture_setting_string(tctx, "dc_binding", NULL); + struct dcerpc_binding_handle *b = NULL; +- + join = talloc(NULL, struct test_join); + if (join == NULL) { + return NULL; +@@ -330,7 +329,6 @@ again: + s.in.info = &u; + s.in.level = 24; + +- encode_pw_buffer(u.info24.password.data, random_pw, STR_UNICODE); + u.info24.password_expired = 0; + + status = dcerpc_fetch_session_key(join->p, &session_key); +@@ -341,7 +339,12 @@ again: + goto failed; + } + +- arcfour_crypt_blob(u.info24.password.data, 516, &session_key); ++ status = init_samr_CryptPassword(random_pw, ++ &session_key, ++ &u.info24.password); ++ torture_assert_ntstatus_ok(tctx, ++ status, ++ "init_samr_CryptPassword failed"); + + status = dcerpc_samr_SetUserInfo_r(b, join, &s); + if (!NT_STATUS_IS_OK(status)) { +-- +2.23.0 + diff --git a/SOURCES/0056-lib-crypto-Use-GnuTLS-RC4-in-py_crypto.patch b/SOURCES/0056-lib-crypto-Use-GnuTLS-RC4-in-py_crypto.patch new file mode 100644 index 0000000..41c94b4 --- /dev/null +++ b/SOURCES/0056-lib-crypto-Use-GnuTLS-RC4-in-py_crypto.patch @@ -0,0 +1,91 @@ +From f20d681243aed9c4e2c1a669cb04964b380413f3 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Fri, 22 Feb 2019 12:59:13 +0100 +Subject: [PATCH 056/187] lib:crypto: Use GnuTLS RC4 in py_crypto + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit fc4ae06001fbb0045318a8cec7af6af81241c60e) +--- + lib/crypto/py_crypto.c | 34 +++++++++++++++++++++++++++++----- + lib/crypto/wscript_build | 7 +++---- + 2 files changed, 32 insertions(+), 9 deletions(-) + +diff --git a/lib/crypto/py_crypto.c b/lib/crypto/py_crypto.c +index 13e2569945d..c85cd2c13d2 100644 +--- a/lib/crypto/py_crypto.c ++++ b/lib/crypto/py_crypto.c +@@ -21,13 +21,18 @@ + #include + #include "includes.h" + #include "python/py3compat.h" +-#include "lib/crypto/arcfour.h" ++ ++#include ++#include + + static PyObject *py_crypto_arcfour_crypt_blob(PyObject *module, PyObject *args) + { +- DATA_BLOB data, key; ++ DATA_BLOB data; + PyObject *py_data, *py_key, *result; + TALLOC_CTX *ctx; ++ gnutls_cipher_hd_t cipher_hnd = NULL; ++ gnutls_datum_t key; ++ int rc; + + if (!PyArg_ParseTuple(args, "OO", &py_data, &py_key)) + return NULL; +@@ -51,10 +56,29 @@ static PyObject *py_crypto_arcfour_crypt_blob(PyObject *module, PyObject *args) + return PyErr_NoMemory(); + } + +- key.data = (uint8_t *)PyBytes_AsString(py_key); +- key.length = PyBytes_Size(py_key); ++ key = (gnutls_datum_t) { ++ .data = (uint8_t *)PyBytes_AsString(py_key), ++ .size = PyBytes_Size(py_key), ++ }; + +- arcfour_crypt_blob(data.data, data.length, &key); ++ rc = gnutls_cipher_init(&cipher_hnd, ++ GNUTLS_CIPHER_ARCFOUR_128, ++ &key, ++ NULL); ++ if (rc < 0) { ++ talloc_free(ctx); ++ PyErr_Format(PyExc_OSError, "encryption failed"); ++ return NULL; ++ } ++ rc = gnutls_cipher_encrypt(cipher_hnd, ++ data.data, ++ data.length); ++ gnutls_cipher_deinit(cipher_hnd); ++ if (rc < 0) { ++ talloc_free(ctx); ++ PyErr_Format(PyExc_OSError, "encryption failed"); ++ return NULL; ++ } + + result = PyBytes_FromStringAndSize((const char*) data.data, data.length); + talloc_free(ctx); +diff --git a/lib/crypto/wscript_build b/lib/crypto/wscript_build +index 2ad8dfe2cd0..46b0e084328 100644 +--- a/lib/crypto/wscript_build ++++ b/lib/crypto/wscript_build +@@ -28,7 +28,6 @@ bld.SAMBA_SUBSYSTEM('TORTURE_LIBCRYPTO', + ) + + bld.SAMBA_PYTHON('python_crypto', +- source='py_crypto.c', +- deps='LIBCRYPTO', +- realname='samba/crypto.so' +- ) ++ source='py_crypto.c', ++ deps='gnutls talloc', ++ realname='samba/crypto.so') +-- +2.23.0 + diff --git a/SOURCES/0057-lib-crypto-Remove-arcfour.h-from-crypto.h.patch b/SOURCES/0057-lib-crypto-Remove-arcfour.h-from-crypto.h.patch new file mode 100644 index 0000000..fe1f7f8 --- /dev/null +++ b/SOURCES/0057-lib-crypto-Remove-arcfour.h-from-crypto.h.patch @@ -0,0 +1,29 @@ +From d40afca3d8b1881ecebc171fede2aa36aa0240d0 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Tue, 26 Feb 2019 18:18:36 +0100 +Subject: [PATCH 057/187] lib:crypto: Remove arcfour.h from crypto.h + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 14c4a075875860e709a9e2e52aad83aa4c58a5ad) +--- + lib/crypto/crypto.h | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/lib/crypto/crypto.h b/lib/crypto/crypto.h +index 12aebaecefd..d7409f9a46d 100644 +--- a/lib/crypto/crypto.h ++++ b/lib/crypto/crypto.h +@@ -21,7 +21,6 @@ + #define _SAMBA_CRYPTO_H_ + + #include "../lib/crypto/md4.h" +-#include "../lib/crypto/arcfour.h" + #include "../lib/crypto/aes.h" + #include "../lib/crypto/aes_cmac_128.h" + #include "../lib/crypto/aes_ccm_128.h" +-- +2.23.0 + diff --git a/SOURCES/0058-lib-crypto-Don-t-build-RC4-if-we-have-GnuTLS-3.4.7.patch b/SOURCES/0058-lib-crypto-Don-t-build-RC4-if-we-have-GnuTLS-3.4.7.patch new file mode 100644 index 0000000..63bbfc8 --- /dev/null +++ b/SOURCES/0058-lib-crypto-Don-t-build-RC4-if-we-have-GnuTLS-3.4.7.patch @@ -0,0 +1,59 @@ +From 32aea65d8f1c896a78f93d1183fb9bdf88eee7df Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Fri, 22 Feb 2019 13:28:01 +0100 +Subject: [PATCH 058/187] lib:crypto: Don't build RC4 if we have GnuTLS >= + 3.4.7 + +We have a GnuTLS DCEPRC backupkey implementation for the server and the +test. However this is only working with GnuTLS >= 3.4.7. So we need to +keep this around till we can require at least GnuTLS in a newer version. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14031 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 9ede63fbada7842cd9ae120936bc6bd4b6ad16ac) +--- + lib/crypto/wscript_build | 25 ++++++++++++++++++++----- + 1 file changed, 20 insertions(+), 5 deletions(-) + +diff --git a/lib/crypto/wscript_build b/lib/crypto/wscript_build +index 46b0e084328..a26c10b627b 100644 +--- a/lib/crypto/wscript_build ++++ b/lib/crypto/wscript_build +@@ -12,12 +12,27 @@ bld.SAMBA_SUBSYSTEM('GNUTLS_HELPERS', + ''', + deps='gnutls samba-errors'); + ++# We have a GnuTLS DCEPRC backupkey implementation for the server and the test. ++# However this is only working with GnuTLS >= 3.4.7. So we need to keep this ++# around till we can require at least GnuTLS in a newer version. ++bld.SAMBA_SUBSYSTEM('LIBCRYPTO_RC4', ++ source='arcfour.c', ++ deps='talloc', ++ enabled=not bld.CONFIG_SET('HAVE_GNUTLS_3_4_7')) ++ + bld.SAMBA_SUBSYSTEM('LIBCRYPTO', +- source='''md4.c arcfour.c +- aes.c rijndael-alg-fst.c aes_cmac_128.c aes_ccm_128.c aes_gcm_128.c +- ''', +- deps='talloc' + extra_deps +- ) ++ source=''' ++ md4.c ++ aes.c ++ rijndael-alg-fst.c ++ aes_cmac_128.c ++ aes_ccm_128.c ++ aes_gcm_128.c ++ ''', ++ deps=''' ++ talloc ++ LIBCRYPTO_RC4 ++ ''' + extra_deps) + + bld.SAMBA_SUBSYSTEM('TORTURE_LIBCRYPTO', + source='''md4test.c +-- +2.23.0 + diff --git a/SOURCES/0059-s3-lib-Use-the-passed-mem_ctx-instead-of-talloc_tos.patch b/SOURCES/0059-s3-lib-Use-the-passed-mem_ctx-instead-of-talloc_tos.patch new file mode 100644 index 0000000..d6c0e1a --- /dev/null +++ b/SOURCES/0059-s3-lib-Use-the-passed-mem_ctx-instead-of-talloc_tos.patch @@ -0,0 +1,56 @@ +From 0fb7a341e75794027de988894da7547a5258d705 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Tue, 16 Jul 2019 15:20:23 +0200 +Subject: [PATCH 059/187] s3:lib: Use the passed mem_ctx instead of + talloc_tos() + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit fa09e811ca6fb08a66940380b310ce9794397071) +--- + source3/lib/netapi/user.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/source3/lib/netapi/user.c b/source3/lib/netapi/user.c +index 827b7902040..fc236e55d1f 100644 +--- a/source3/lib/netapi/user.c ++++ b/source3/lib/netapi/user.c +@@ -290,7 +290,7 @@ static NTSTATUS construct_USER_INFO_X(uint32_t level, + /**************************************************************** + ****************************************************************/ + +-static NTSTATUS set_user_info_USER_INFO_X(TALLOC_CTX *ctx, ++static NTSTATUS set_user_info_USER_INFO_X(TALLOC_CTX *mem_ctx, + struct rpc_pipe_client *pipe_cli, + DATA_BLOB *session_key, + struct policy_handle *user_handle, +@@ -320,7 +320,7 @@ static NTSTATUS set_user_info_USER_INFO_X(TALLOC_CTX *ctx, + return status; + } + +- status = dcerpc_samr_SetUserInfo2(b, talloc_tos(), ++ status = dcerpc_samr_SetUserInfo2(b, mem_ctx, + user_handle, + 25, + &user_info, +@@ -336,7 +336,7 @@ static NTSTATUS set_user_info_USER_INFO_X(TALLOC_CTX *ctx, + return status; + } + +- status = dcerpc_samr_SetUserInfo2(b, talloc_tos(), ++ status = dcerpc_samr_SetUserInfo2(b, mem_ctx, + user_handle, + 23, + &user_info, +@@ -353,7 +353,7 @@ static NTSTATUS set_user_info_USER_INFO_X(TALLOC_CTX *ctx, + + user_info.info21 = info21; + +- status = dcerpc_samr_SetUserInfo(b, talloc_tos(), ++ status = dcerpc_samr_SetUserInfo(b, mem_ctx, + user_handle, + 21, + &user_info, +-- +2.23.0 + diff --git a/SOURCES/0060-s3-rpcclient-Use-a-stackframe-for-temporary-memory.patch b/SOURCES/0060-s3-rpcclient-Use-a-stackframe-for-temporary-memory.patch new file mode 100644 index 0000000..2139a62 --- /dev/null +++ b/SOURCES/0060-s3-rpcclient-Use-a-stackframe-for-temporary-memory.patch @@ -0,0 +1,188 @@ +From a2b0dcbb525b7aa3a6f79ca8f8cca4ef7fc2f8f7 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Tue, 16 Jul 2019 15:45:51 +0200 +Subject: [PATCH 060/187] s3:rpcclient: Use a stackframe for temporary memory + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 9158a6ba8693070f3b2b71dd15089488869ab6cd) +--- + source3/rpcclient/cmd_samr.c | 56 +++++++++++++++++++++++++----------- + 1 file changed, 39 insertions(+), 17 deletions(-) + +diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c +index b1b7c06515c..0cd8b50058e 100644 +--- a/source3/rpcclient/cmd_samr.c ++++ b/source3/rpcclient/cmd_samr.c +@@ -3043,6 +3043,7 @@ static NTSTATUS cmd_samr_setuserinfo_int(struct rpc_pipe_client *cli, + DATA_BLOB session_key; + uint8_t password_expired = 0; + struct dcerpc_binding_handle *b = cli->binding_handle; ++ TALLOC_CTX *frame = NULL; + + if (argc < 4) { + printf("Usage: %s username level password [password_expired]\n", +@@ -3050,6 +3051,8 @@ static NTSTATUS cmd_samr_setuserinfo_int(struct rpc_pipe_client *cli, + return NT_STATUS_INVALID_PARAMETER; + } + ++ frame = talloc_stackframe(); ++ + user = argv[1]; + level = atoi(argv[2]); + param = argv[3]; +@@ -3058,18 +3061,18 @@ static NTSTATUS cmd_samr_setuserinfo_int(struct rpc_pipe_client *cli, + password_expired = atoi(argv[4]); + } + +- status = cli_get_session_key(mem_ctx, cli, &session_key); ++ status = cli_get_session_key(frame, cli, &session_key); + if (!NT_STATUS_IS_OK(status)) { +- return status; ++ goto done; + } + + status = init_samr_CryptPassword(param, &session_key, &pwd_buf); + if (!NT_STATUS_IS_OK(status)) { +- return status; ++ goto done; + } + status = init_samr_CryptPasswordEx(param, &session_key, &pwd_buf_ex); + if (!NT_STATUS_IS_OK(status)) { +- return status; ++ goto done; + } + nt_lm_owf_gen(param, nt_hash, lm_hash); + +@@ -3078,14 +3081,22 @@ static NTSTATUS cmd_samr_setuserinfo_int(struct rpc_pipe_client *cli, + { + DATA_BLOB in,out; + in = data_blob_const(nt_hash, 16); +- out = data_blob_talloc_zero(mem_ctx, 16); ++ out = data_blob_talloc_zero(frame, 16); ++ if (out.data == NULL) { ++ status = NT_STATUS_NO_MEMORY; ++ goto done; ++ } + sess_crypt_blob(&out, &in, &session_key, true); + memcpy(nt_hash, out.data, out.length); + } + { + DATA_BLOB in,out; + in = data_blob_const(lm_hash, 16); +- out = data_blob_talloc_zero(mem_ctx, 16); ++ out = data_blob_talloc_zero(frame, 15); ++ if (out.data == NULL) { ++ status = NT_STATUS_NO_MEMORY; ++ goto done; ++ } + sess_crypt_blob(&out, &in, &session_key, true); + memcpy(lm_hash, out.data, out.length); + } +@@ -3118,18 +3129,26 @@ static NTSTATUS cmd_samr_setuserinfo_int(struct rpc_pipe_client *cli, + { + DATA_BLOB in,out; + in = data_blob_const(nt_hash, 16); +- out = data_blob_talloc_zero(mem_ctx, 16); ++ out = data_blob_talloc_zero(frame, 16); ++ if (out.data == NULL) { ++ status = NT_STATUS_NO_MEMORY; ++ goto done; ++ } + sess_crypt_blob(&out, &in, &session_key, true); + info.info21.nt_owf_password.array = +- (uint16_t *)talloc_memdup(mem_ctx, out.data, 16); ++ (uint16_t *)talloc_memdup(frame, out.data, 16); + } + { + DATA_BLOB in,out; + in = data_blob_const(lm_hash, 16); +- out = data_blob_talloc_zero(mem_ctx, 16); ++ out = data_blob_talloc_zero(frame, 16); + sess_crypt_blob(&out, &in, &session_key, true); + info.info21.lm_owf_password.array = +- (uint16_t *)talloc_memdup(mem_ctx, out.data, 16); ++ (uint16_t *)talloc_memdup(frame, out.data, 16); ++ if (out.data == NULL) { ++ status = NT_STATUS_NO_MEMORY; ++ goto done; ++ } + } + + break; +@@ -3175,7 +3194,7 @@ static NTSTATUS cmd_samr_setuserinfo_int(struct rpc_pipe_client *cli, + + /* Get sam policy handle */ + +- status = rpccli_try_samr_connects(cli, mem_ctx, ++ status = rpccli_try_samr_connects(cli, frame, + MAXIMUM_ALLOWED_ACCESS, + &connect_pol); + if (!NT_STATUS_IS_OK(status)) { +@@ -3184,7 +3203,7 @@ static NTSTATUS cmd_samr_setuserinfo_int(struct rpc_pipe_client *cli, + + /* Get domain policy handle */ + +- status = dcerpc_samr_OpenDomain(b, mem_ctx, ++ status = dcerpc_samr_OpenDomain(b, frame, + &connect_pol, + access_mask, + &domain_sid, +@@ -3200,7 +3219,7 @@ static NTSTATUS cmd_samr_setuserinfo_int(struct rpc_pipe_client *cli, + + user_rid = strtol(user, NULL, 0); + if (user_rid) { +- status = dcerpc_samr_OpenUser(b, mem_ctx, ++ status = dcerpc_samr_OpenUser(b, frame, + &domain_pol, + access_mask, + user_rid, +@@ -3222,7 +3241,7 @@ static NTSTATUS cmd_samr_setuserinfo_int(struct rpc_pipe_client *cli, + + init_lsa_String(&lsa_acct_name, user); + +- status = dcerpc_samr_LookupNames(b, mem_ctx, ++ status = dcerpc_samr_LookupNames(b, frame, + &domain_pol, + 1, + &lsa_acct_name, +@@ -3242,7 +3261,7 @@ static NTSTATUS cmd_samr_setuserinfo_int(struct rpc_pipe_client *cli, + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + +- status = dcerpc_samr_OpenUser(b, mem_ctx, ++ status = dcerpc_samr_OpenUser(b, frame, + &domain_pol, + access_mask, + rids.ids[0], +@@ -3258,14 +3277,14 @@ static NTSTATUS cmd_samr_setuserinfo_int(struct rpc_pipe_client *cli, + + switch (opcode) { + case NDR_SAMR_SETUSERINFO: +- status = dcerpc_samr_SetUserInfo(b, mem_ctx, ++ status = dcerpc_samr_SetUserInfo(b, frame, + &user_pol, + level, + &info, + &result); + break; + case NDR_SAMR_SETUSERINFO2: +- status = dcerpc_samr_SetUserInfo2(b, mem_ctx, ++ status = dcerpc_samr_SetUserInfo2(b, frame, + &user_pol, + level, + &info, +@@ -3283,7 +3302,10 @@ static NTSTATUS cmd_samr_setuserinfo_int(struct rpc_pipe_client *cli, + DEBUG(0,("result: %s\n", nt_errstr(status))); + goto done; + } ++ ++ status = NT_STATUS_OK; + done: ++ TALLOC_FREE(frame); + return status; + } + +-- +2.23.0 + diff --git a/SOURCES/0061-s3-utils-Use-a-stackframe-for-temporary-memory.patch b/SOURCES/0061-s3-utils-Use-a-stackframe-for-temporary-memory.patch new file mode 100644 index 0000000..896dca3 --- /dev/null +++ b/SOURCES/0061-s3-utils-Use-a-stackframe-for-temporary-memory.patch @@ -0,0 +1,104 @@ +From 5a4fb7d50cfa71a57ce62fdd0e090b70da56b33c Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Tue, 16 Jul 2019 15:49:43 +0200 +Subject: [PATCH 061/187] s3:utils: Use a stackframe for temporary memory + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 52b3f921ad2d04cb30232a6aadf261c9fc9aafb2) +--- + source3/utils/net_rpc.c | 21 +++++++++++++-------- + 1 file changed, 13 insertions(+), 8 deletions(-) + +diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c +index f6fb892a2d9..03462d89e1b 100644 +--- a/source3/utils/net_rpc.c ++++ b/source3/utils/net_rpc.c +@@ -6095,6 +6095,7 @@ static NTSTATUS rpc_trustdom_add_internals(struct net_context *c, + unsigned int orig_timeout; + struct dcerpc_binding_handle *b = pipe_hnd->binding_handle; + DATA_BLOB session_key = data_blob_null; ++ TALLOC_CTX *frame = NULL; + + if (argc != 2) { + d_printf("%s\n%s", +@@ -6104,22 +6105,24 @@ static NTSTATUS rpc_trustdom_add_internals(struct net_context *c, + return NT_STATUS_INVALID_PARAMETER; + } + ++ frame = talloc_stackframe(); ++ + /* + * Make valid trusting domain account (ie. uppercased and with '$' appended) + */ + + if (asprintf(&acct_name, "%s$", argv[0]) < 0) { +- return NT_STATUS_NO_MEMORY; ++ status = NT_STATUS_NO_MEMORY; + } + + if (!strupper_m(acct_name)) { +- SAFE_FREE(acct_name); +- return NT_STATUS_INVALID_PARAMETER; ++ status = NT_STATUS_INVALID_PARAMETER; ++ goto done; + } + + init_lsa_String(&lsa_acct_name, acct_name); + +- status = cli_get_session_key(mem_ctx, pipe_hnd, &session_key); ++ status = cli_get_session_key(frame, pipe_hnd, &session_key); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Error getting session_key of SAM pipe. Error was %s\n", + nt_errstr(status))); +@@ -6127,7 +6130,7 @@ static NTSTATUS rpc_trustdom_add_internals(struct net_context *c, + } + + /* Get samr policy handle */ +- status = dcerpc_samr_Connect2(b, mem_ctx, ++ status = dcerpc_samr_Connect2(b, frame, + pipe_hnd->desthost, + MAXIMUM_ALLOWED_ACCESS, + &connect_pol, +@@ -6141,7 +6144,7 @@ static NTSTATUS rpc_trustdom_add_internals(struct net_context *c, + } + + /* Get domain policy handle */ +- status = dcerpc_samr_OpenDomain(b, mem_ctx, ++ status = dcerpc_samr_OpenDomain(b, frame, + &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + discard_const_p(struct dom_sid2, domain_sid), +@@ -6168,7 +6171,7 @@ static NTSTATUS rpc_trustdom_add_internals(struct net_context *c, + SAMR_USER_ACCESS_GET_ATTRIBUTES | + SAMR_USER_ACCESS_SET_ATTRIBUTES; + +- status = dcerpc_samr_CreateUser2(b, mem_ctx, ++ status = dcerpc_samr_CreateUser2(b, frame, + &domain_pol, + &lsa_acct_name, + acb_info, +@@ -6207,7 +6210,7 @@ static NTSTATUS rpc_trustdom_add_internals(struct net_context *c, + info.info23.info.acct_flags = ACB_DOMTRUST; + info.info23.password = crypt_pwd; + +- status = dcerpc_samr_SetUserInfo2(b, mem_ctx, ++ status = dcerpc_samr_SetUserInfo2(b, frame, + &user_pol, + 23, + &info, +@@ -6224,9 +6227,11 @@ static NTSTATUS rpc_trustdom_add_internals(struct net_context *c, + } + } + ++ status = NT_STATUS_OK; + done: + SAFE_FREE(acct_name); + data_blob_clear_free(&session_key); ++ TALLOC_FREE(frame); + return status; + } + +-- +2.23.0 + diff --git a/SOURCES/0062-s3-rpc_server-Use-a-stackframe-for-temporary-memory.patch b/SOURCES/0062-s3-rpc_server-Use-a-stackframe-for-temporary-memory.patch new file mode 100644 index 0000000..5f9d636 --- /dev/null +++ b/SOURCES/0062-s3-rpc_server-Use-a-stackframe-for-temporary-memory.patch @@ -0,0 +1,96 @@ +From cb51fd8abb0f0d3fa672452cd15d49af193de6ee Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Tue, 16 Jul 2019 16:02:12 +0200 +Subject: [PATCH 062/187] s3:rpc_server: Use a stackframe for temporary memory + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 1c84bda361678cb6c4685cff17a2d5a5026f2bce) +--- + source3/rpc_server/netlogon/srv_netlog_nt.c | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c +index d5267bf7062..791aa7acaff 100644 +--- a/source3/rpc_server/netlogon/srv_netlog_nt.c ++++ b/source3/rpc_server/netlogon/srv_netlog_nt.c +@@ -1134,6 +1134,7 @@ static NTSTATUS netr_set_machine_account_password(TALLOC_CTX *mem_ctx, + int rc; + DATA_BLOB session_key; + enum samr_UserInfoLevel infolevel; ++ TALLOC_CTX *frame = talloc_stackframe(); + + ZERO_STRUCT(user_handle); + +@@ -1144,7 +1145,7 @@ static NTSTATUS netr_set_machine_account_password(TALLOC_CTX *mem_ctx, + goto out; + } + +- rc = tsocket_address_inet_from_strings(mem_ctx, ++ rc = tsocket_address_inet_from_strings(frame, + "ip", + "127.0.0.1", + 0, +@@ -1154,7 +1155,7 @@ static NTSTATUS netr_set_machine_account_password(TALLOC_CTX *mem_ctx, + goto out; + } + +- status = rpcint_binding_handle(mem_ctx, ++ status = rpcint_binding_handle(frame, + &ndr_table_samr, + local, + NULL, +@@ -1166,7 +1167,7 @@ static NTSTATUS netr_set_machine_account_password(TALLOC_CTX *mem_ctx, + } + + become_root(); +- status = samr_find_machine_account(mem_ctx, ++ status = samr_find_machine_account(frame, + h, + account_name, + SEC_FLAG_MAXIMUM_ALLOWED, +@@ -1179,7 +1180,7 @@ static NTSTATUS netr_set_machine_account_password(TALLOC_CTX *mem_ctx, + } + + status = dcerpc_samr_QueryUserInfo2(h, +- mem_ctx, ++ frame, + &user_handle, + UserControlInformation, + &info, +@@ -1213,7 +1214,11 @@ static NTSTATUS netr_set_machine_account_password(TALLOC_CTX *mem_ctx, + infolevel = UserInternal1Information; + + in = data_blob_const(cr->creds.nt_hash, 16); +- out = data_blob_talloc_zero(mem_ctx, 16); ++ out = data_blob_talloc_zero(frame, 16); ++ if (out.data == NULL) { ++ status = NT_STATUS_NO_MEMORY; ++ goto out; ++ } + sess_crypt_blob(&out, &in, &session_key, true); + memcpy(info18.nt_pwd.hash, out.data, out.length); + +@@ -1244,7 +1249,7 @@ static NTSTATUS netr_set_machine_account_password(TALLOC_CTX *mem_ctx, + + become_root(); + status = dcerpc_samr_SetUserInfo2(h, +- mem_ctx, ++ frame, + &user_handle, + infolevel, + info, +@@ -1260,8 +1265,9 @@ static NTSTATUS netr_set_machine_account_password(TALLOC_CTX *mem_ctx, + + out: + if (h && is_valid_policy_hnd(&user_handle)) { +- dcerpc_samr_Close(h, mem_ctx, &user_handle, &result); ++ dcerpc_samr_Close(h, frame, &user_handle, &result); + } ++ TALLOC_FREE(frame); + + return status; + } +-- +2.23.0 + diff --git a/SOURCES/0063-netlogon-Fix-potential-use-of-uninitialized-variable.patch b/SOURCES/0063-netlogon-Fix-potential-use-of-uninitialized-variable.patch new file mode 100644 index 0000000..b2a7151 --- /dev/null +++ b/SOURCES/0063-netlogon-Fix-potential-use-of-uninitialized-variable.patch @@ -0,0 +1,32 @@ +From b26c0a881c5a71ee310a942ffd65960974eabea8 Mon Sep 17 00:00:00 2001 +From: David Disseldorp +Date: Fri, 12 Jul 2019 17:29:23 +0200 +Subject: [PATCH 063/187] netlogon: Fix potential use of uninitialized variable + +The _netr_NetrEnumerateTrustedDomains()->dcerpc_lsa_open_policy2() error +path checks the policy handle and closes it if non-empty. The policy +handle may be uninitialized in this code-path - fix this. + +Signed-off-by: David Disseldorp +Reviewed-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 93d424528f1c3d0d50ebd8a784f4624b2721d416) +--- + source3/rpc_server/netlogon/srv_netlog_nt.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c +index 791aa7acaff..08bce367bf0 100644 +--- a/source3/rpc_server/netlogon/srv_netlog_nt.c ++++ b/source3/rpc_server/netlogon/srv_netlog_nt.c +@@ -419,6 +419,7 @@ NTSTATUS _netr_NetrEnumerateTrustedDomains(struct pipes_struct *p, + int i; + uint32_t max_size = (uint32_t)-1; + ++ ZERO_STRUCT(pol); + DEBUG(6,("_netr_NetrEnumerateTrustedDomains: %d\n", __LINE__)); + + status = rpcint_binding_handle(p->mem_ctx, +-- +2.23.0 + diff --git a/SOURCES/0064-s3-rpc_server-Only-dump-passwords-in-developer-build.patch b/SOURCES/0064-s3-rpc_server-Only-dump-passwords-in-developer-build.patch new file mode 100644 index 0000000..34e2ab3 --- /dev/null +++ b/SOURCES/0064-s3-rpc_server-Only-dump-passwords-in-developer-build.patch @@ -0,0 +1,64 @@ +From 8746734f6874d62825209a49b29b06f28183559d Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Tue, 16 Jul 2019 16:13:17 +0200 +Subject: [PATCH 064/187] s3:rpc_server: Only dump passwords in developer + builds + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett + +Autobuild-User(master): Andrew Bartlett +Autobuild-Date(master): Fri Jul 26 03:05:01 UTC 2019 on sn-devel-184 + +(cherry picked from commit 1f923e067dbe358c17cbccfe179baa811aa3b8b3) +--- + source3/rpc_server/samr/srv_samr_nt.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/source3/rpc_server/samr/srv_samr_nt.c b/source3/rpc_server/samr/srv_samr_nt.c +index ad1d1853bda..87214b2899e 100644 +--- a/source3/rpc_server/samr/srv_samr_nt.c ++++ b/source3/rpc_server/samr/srv_samr_nt.c +@@ -5198,7 +5198,9 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p, + break; + } + ++#ifdef DEBUG_PASSWORD + dump_data(100, info->info23.password.data, 516); ++#endif + + status = set_user_info_23(p->mem_ctx, + &info->info23, +@@ -5219,7 +5221,9 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p, + break; + } + ++#ifdef DEBUG_PASSWORD + dump_data(100, info->info24.password.data, 516); ++#endif + + status = set_user_info_24(p->mem_ctx, + rhost, +@@ -5237,7 +5241,9 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p, + break; + } + ++#ifdef DEBUG_PASSWORD + dump_data(100, info->info25.password.data, 532); ++#endif + + status = set_user_info_25(p->mem_ctx, + rhost, +@@ -5255,7 +5261,9 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p, + break; + } + ++#ifdef DEBUG_PASSWORD + dump_data(100, info->info26.password.data, 516); ++#endif + + status = set_user_info_26(p->mem_ctx, + rhost, +-- +2.23.0 + diff --git a/SOURCES/0065-libcli-smb-Add-forward-declaration-for-gnutls_hmac_h.patch b/SOURCES/0065-libcli-smb-Add-forward-declaration-for-gnutls_hmac_h.patch new file mode 100644 index 0000000..be2ef40 --- /dev/null +++ b/SOURCES/0065-libcli-smb-Add-forward-declaration-for-gnutls_hmac_h.patch @@ -0,0 +1,38 @@ +From 595df06b59c80cbb7a484a893e1ebaf917ddddb6 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Thu, 8 Aug 2019 11:57:02 +0200 +Subject: [PATCH 065/187] libcli:smb: Add forward declaration for + gnutls_hmac_hd_t + +This file is basically included everywhere. So use a forward declaration +for gnutls_hmac_hd_t. This way we don't have to link everthing against +gnutls to get access to the header path. + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 6bf6cb1643ae5e8fff66a7cbec50f58ede632666) +--- + libcli/smb/smb2_signing.h | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/libcli/smb/smb2_signing.h b/libcli/smb/smb2_signing.h +index 6e1682955c9..96a002f4a0c 100644 +--- a/libcli/smb/smb2_signing.h ++++ b/libcli/smb/smb2_signing.h +@@ -21,10 +21,10 @@ + #ifndef _LIBCLI_SMB_SMB2_SIGNING_H_ + #define _LIBCLI_SMB_SMB2_SIGNING_H_ + +-#include +-#include +- + struct iovec; ++ /* Forward declaration of GnuTLS typedefs */ ++struct hmac_hd_st; ++typedef struct hmac_hd_st* gnutls_hmac_hd_t; + + struct smb2_signing_key { + gnutls_hmac_hd_t hmac_hnd; +-- +2.23.0 + diff --git a/SOURCES/0066-s3-modules-Link-vfs_acl_common-against-gnutls.patch b/SOURCES/0066-s3-modules-Link-vfs_acl_common-against-gnutls.patch new file mode 100644 index 0000000..d4c3e79 --- /dev/null +++ b/SOURCES/0066-s3-modules-Link-vfs_acl_common-against-gnutls.patch @@ -0,0 +1,29 @@ +From 5132a12a30ccc008644be11fa6af4a3d253a8a27 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Thu, 8 Aug 2019 13:14:45 +0200 +Subject: [PATCH 066/187] s3:modules: Link vfs_acl_common against gnutls + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit b81cb04d03d57b8175d862ba48ac476fedf23636) +--- + source3/modules/wscript_build | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/source3/modules/wscript_build b/source3/modules/wscript_build +index 80b0ce9ff90..b8b965c8edd 100644 +--- a/source3/modules/wscript_build ++++ b/source3/modules/wscript_build +@@ -10,7 +10,8 @@ bld.SAMBA3_BINARY('test_nfs4_acls', + install=False) + + bld.SAMBA3_SUBSYSTEM('vfs_acl_common', +- source='vfs_acl_common.c') ++ source='vfs_acl_common.c', ++ deps='gnutls') + + bld.SAMBA3_SUBSYSTEM('POSIXACL_XATTR', + source='posixacl_xattr.c', +-- +2.23.0 + diff --git a/SOURCES/0067-lib-util-Add-generate_nonce_buffer.patch b/SOURCES/0067-lib-util-Add-generate_nonce_buffer.patch new file mode 100644 index 0000000..fe1730b --- /dev/null +++ b/SOURCES/0067-lib-util-Add-generate_nonce_buffer.patch @@ -0,0 +1,62 @@ +From 45c34e04c2018d839be71371bee594bc4794de2d Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 31 Jul 2019 15:16:37 +0200 +Subject: [PATCH 067/187] lib:util: Add generate_nonce_buffer() + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 70ff216935acc099b762b527033b6191ba3307d0) +--- + lib/util/genrand.c | 12 ++++++++++-- + lib/util/genrand.h | 11 +++++++++++ + 2 files changed, 21 insertions(+), 2 deletions(-) + +diff --git a/lib/util/genrand.c b/lib/util/genrand.c +index 55997c3dd55..76c2cb81962 100644 +--- a/lib/util/genrand.c ++++ b/lib/util/genrand.c +@@ -25,8 +25,6 @@ + #include + #include + +-/* TODO: Add API for generating nonce or use gnutls_rnd directly everywhere. */ +- + _PUBLIC_ void generate_random_buffer(uint8_t *out, int len) + { + /* Thread and fork safe random number generator for temporary keys. */ +@@ -42,3 +40,13 @@ _PUBLIC_ void generate_secret_buffer(uint8_t *out, int len) + /* Thread and fork safe random number generator for long term keys. */ + gnutls_rnd(GNUTLS_RND_KEY, out, len); + } ++ ++_PUBLIC_ void generate_nonce_buffer(uint8_t *out, int len) ++{ ++ /* ++ * The nonce generator will reseed after outputting a fixed amount of ++ * bytes (typically few megabytes), or after few hours of operation ++ * without reaching the limit has passed. ++ */ ++ gnutls_rnd(GNUTLS_RND_NONCE, out, len); ++} +diff --git a/lib/util/genrand.h b/lib/util/genrand.h +index 899ce8badc0..5af23100596 100644 +--- a/lib/util/genrand.h ++++ b/lib/util/genrand.h +@@ -28,3 +28,14 @@ void generate_random_buffer(uint8_t *out, int len); + * Thread and fork safe random number generator for long term keys. + */ + void generate_secret_buffer(uint8_t *out, int len); ++ ++/** ++ * @brief Generate random values for a nonce buffer. ++ * ++ * This is also known as initialization vector. ++ * ++ * @param[in] out A pointer to the buffer to fill with random data. ++ * ++ * @param[in] len The size of the buffer to fill. ++ */ ++void generate_nonce_buffer(uint8_t *out, int len); +-- +2.23.0 + diff --git a/SOURCES/0068-libcli-smb-Use-generate_nonce_buffer-for-AES-CCM-and.patch b/SOURCES/0068-libcli-smb-Use-generate_nonce_buffer-for-AES-CCM-and.patch new file mode 100644 index 0000000..783a98f --- /dev/null +++ b/SOURCES/0068-libcli-smb-Use-generate_nonce_buffer-for-AES-CCM-and.patch @@ -0,0 +1,31 @@ +From 85272ea8c52056f559b7bfde79805ce2b7ab4f72 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 31 Jul 2019 15:25:35 +0200 +Subject: [PATCH 068/187] libcli:smb: Use generate_nonce_buffer() for AES-CCM + and AES-GCM nonce + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit b2506f2407429efb40c3e4e4c360f5817ac13d27) +--- + libcli/smb/smbXcli_base.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c +index c9b396106ae..5db86720c9c 100644 +--- a/libcli/smb/smbXcli_base.c ++++ b/libcli/smb/smbXcli_base.c +@@ -6253,8 +6253,8 @@ NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session, + * + * NOTE: We assume nonces greater than 8 bytes. + */ +- generate_random_buffer((uint8_t *)&session->smb2->nonce_high_random, +- sizeof(session->smb2->nonce_high_random)); ++ generate_nonce_buffer((uint8_t *)&session->smb2->nonce_high_random, ++ sizeof(session->smb2->nonce_high_random)); + switch (conn->smb2.server.cipher) { + case SMB2_ENCRYPTION_AES128_CCM: + nonce_size = AES_CCM_128_NONCE_SIZE; +-- +2.23.0 + diff --git a/SOURCES/0069-s3-smbd-Use-generate_nonce_buffer-for-AES-CCM-and-AE.patch b/SOURCES/0069-s3-smbd-Use-generate_nonce_buffer-for-AES-CCM-and-AE.patch new file mode 100644 index 0000000..bda42f9 --- /dev/null +++ b/SOURCES/0069-s3-smbd-Use-generate_nonce_buffer-for-AES-CCM-and-AE.patch @@ -0,0 +1,31 @@ +From 230457a6c024e236815b6f9f0351b236044ad515 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 31 Jul 2019 15:28:34 +0200 +Subject: [PATCH 069/187] s3:smbd: Use generate_nonce_buffer() for AES-CCM and + AES-GCM nonce + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 2b2df6cd398c9cb62989710f9b1642665ec89406) +--- + source3/smbd/smb2_sesssetup.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c +index 770c22b00f1..591d5c37160 100644 +--- a/source3/smbd/smb2_sesssetup.c ++++ b/source3/smbd/smb2_sesssetup.c +@@ -419,8 +419,8 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session, + * + * NOTE: We assume nonces greater than 8 bytes. + */ +- generate_random_buffer((uint8_t *)&x->nonce_high_random, +- sizeof(x->nonce_high_random)); ++ generate_nonce_buffer((uint8_t *)&x->nonce_high_random, ++ sizeof(x->nonce_high_random)); + switch (xconn->smb2.server.cipher) { + case SMB2_ENCRYPTION_AES128_CCM: + nonce_size = AES_CCM_128_NONCE_SIZE; +-- +2.23.0 + diff --git a/SOURCES/0070-lib-util-Add-better-documentation-for-generate_secre.patch b/SOURCES/0070-lib-util-Add-better-documentation-for-generate_secre.patch new file mode 100644 index 0000000..60978d4 --- /dev/null +++ b/SOURCES/0070-lib-util-Add-better-documentation-for-generate_secre.patch @@ -0,0 +1,70 @@ +From deeb93c2fb7cc131741ced4877b75bcd3a64cef4 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 31 Jul 2019 15:38:50 +0200 +Subject: [PATCH 070/187] lib:util: Add better documentation for + generate_secret_buffer() + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit bf52ab7d2982de84a68a1b9c6d2f68250b7e7cca) +--- + lib/util/genrand.c | 17 ++++++++++++----- + lib/util/genrand.h | 6 +++++- + 2 files changed, 17 insertions(+), 6 deletions(-) + +diff --git a/lib/util/genrand.c b/lib/util/genrand.c +index 76c2cb81962..a5809aa2bc9 100644 +--- a/lib/util/genrand.c ++++ b/lib/util/genrand.c +@@ -25,19 +25,26 @@ + #include + #include + ++/* ++ * Details about the GnuTLS CSPRNG: ++ * ++ * https://nikmav.blogspot.com/2017/03/improving-by-simplifying-gnutls-prng.html ++ */ ++ + _PUBLIC_ void generate_random_buffer(uint8_t *out, int len) + { + /* Thread and fork safe random number generator for temporary keys. */ + gnutls_rnd(GNUTLS_RND_RANDOM, out, len); + } + +-/* +- * Keep generate_secret_buffer in case we ever want to do something +- * different +- */ + _PUBLIC_ void generate_secret_buffer(uint8_t *out, int len) + { +- /* Thread and fork safe random number generator for long term keys. */ ++ /* The key generator, will re-seed after a fixed amount of bytes is ++ * generated (typically less than the nonce), and will also re-seed ++ * based on time, i.e., after few hours of operation without reaching ++ * the limit for a re-seed. For its re-seed it mixes mixes data obtained ++ * from the OS random device with the previous key. ++ */ + gnutls_rnd(GNUTLS_RND_KEY, out, len); + } + +diff --git a/lib/util/genrand.h b/lib/util/genrand.h +index 5af23100596..abb8ce2c10a 100644 +--- a/lib/util/genrand.h ++++ b/lib/util/genrand.h +@@ -25,7 +25,11 @@ + void generate_random_buffer(uint8_t *out, int len); + + /** +- * Thread and fork safe random number generator for long term keys. ++ * @brief Generate random values for key buffers (e.g. session keys) ++ * ++ * @param[in] out A pointer to the buffer to fill with random data. ++ * ++ * @param[in] len The size of the buffer to fill. + */ + void generate_secret_buffer(uint8_t *out, int len); + +-- +2.23.0 + diff --git a/SOURCES/0071-s4-rpc_server-Use-generate_secret_buffer-to-create-a.patch b/SOURCES/0071-s4-rpc_server-Use-generate_secret_buffer-to-create-a.patch new file mode 100644 index 0000000..d9c53b1 --- /dev/null +++ b/SOURCES/0071-s4-rpc_server-Use-generate_secret_buffer-to-create-a.patch @@ -0,0 +1,33 @@ +From 299dd35d7816770560a17a0e30886c08d9687589 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 31 Jul 2019 15:40:12 +0200 +Subject: [PATCH 071/187] s4:rpc_server: Use generate_secret_buffer() to create + a session key + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 4b2480518bd3887be3a6cfb713523ac084e09fd5) +--- + source4/rpc_server/samr/samr_password.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c +index b04e37f06f3..6bf907181c8 100644 +--- a/source4/rpc_server/samr/samr_password.c ++++ b/source4/rpc_server/samr/samr_password.c +@@ -733,9 +733,10 @@ NTSTATUS samr_set_password_buffers(struct dcesrv_call_state *dce_call, + nt_errstr(nt_status))); + + /* +- * Windows just uses a random key ++ * Windows just uses a random key. We need to use a CSPRNG ++ * which reseeds for generating session keys. + */ +- generate_random_buffer(random_session_key, ++ generate_secret_buffer(random_session_key, + sizeof(random_session_key)); + session_key = data_blob_const(random_session_key, + sizeof(random_session_key)); +-- +2.23.0 + diff --git a/SOURCES/0072-s4-rpc_server-Use-generate_secret_buffer-for-backupk.patch b/SOURCES/0072-s4-rpc_server-Use-generate_secret_buffer-for-backupk.patch new file mode 100644 index 0000000..0813c0f --- /dev/null +++ b/SOURCES/0072-s4-rpc_server-Use-generate_secret_buffer-for-backupk.patch @@ -0,0 +1,30 @@ +From 5cd54770ca2055eee9ae651510b0ff5d1c914f6c Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 31 Jul 2019 15:41:29 +0200 +Subject: [PATCH 072/187] s4:rpc_server: Use generate_secret_buffer() for + backupkey wap_key + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 5a62056b4530e4c509444be9164a1fca1dce193f) +--- + source4/rpc_server/backupkey/dcesrv_backupkey.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/source4/rpc_server/backupkey/dcesrv_backupkey.c b/source4/rpc_server/backupkey/dcesrv_backupkey.c +index a826ae083f4..d192858e468 100644 +--- a/source4/rpc_server/backupkey/dcesrv_backupkey.c ++++ b/source4/rpc_server/backupkey/dcesrv_backupkey.c +@@ -1263,7 +1263,8 @@ static WERROR generate_bkrp_server_wrap_key(TALLOC_CTX *ctx, struct ldb_context + char *secret_name; + TALLOC_CTX *frame = talloc_stackframe(); + +- generate_random_buffer(wrap_key.key, sizeof(wrap_key.key)); ++ /* We need to use a CSPRNG which reseeds for generating session keys. */ ++ generate_secret_buffer(wrap_key.key, sizeof(wrap_key.key)); + + ndr_err = ndr_push_struct_blob(&blob_wrap_key, ctx, &wrap_key, (ndr_push_flags_fn_t)ndr_push_bkrp_dc_serverwrap_key); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { +-- +2.23.0 + diff --git a/SOURCES/0073-s4-rpc_server-Use-generate_secret_buffer-for-netlogo.patch b/SOURCES/0073-s4-rpc_server-Use-generate_secret_buffer-for-netlogo.patch new file mode 100644 index 0000000..466851b --- /dev/null +++ b/SOURCES/0073-s4-rpc_server-Use-generate_secret_buffer-for-netlogo.patch @@ -0,0 +1,30 @@ +From a9efbcf21a5dc8b8b8195916b8a5eaa03ccbf5a5 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 31 Jul 2019 15:42:26 +0200 +Subject: [PATCH 073/187] s4:rpc_server: Use generate_secret_buffer() for + netlogon challange + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit a21770cfdffd2a21045a1bc87e489af0f4c6f130) +--- + source4/rpc_server/netlogon/dcerpc_netlogon.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c +index ac745e32b02..f4e24b7fd7f 100644 +--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c ++++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c +@@ -90,7 +90,8 @@ static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_cal + + pipe_state->client_challenge = *r->in.credentials; + +- generate_random_buffer(pipe_state->server_challenge.data, ++ /* We need to use a CSPRNG which reseeds for generating session keys. */ ++ generate_secret_buffer(pipe_state->server_challenge.data, + sizeof(pipe_state->server_challenge.data)); + + *r->out.return_credentials = pipe_state->server_challenge; +-- +2.23.0 + diff --git a/SOURCES/0074-libcli-auth-Use-generate_secret_buffer-for-netlogon-.patch b/SOURCES/0074-libcli-auth-Use-generate_secret_buffer-for-netlogon-.patch new file mode 100644 index 0000000..31f8907 --- /dev/null +++ b/SOURCES/0074-libcli-auth-Use-generate_secret_buffer-for-netlogon-.patch @@ -0,0 +1,34 @@ +From 34c4199f21f5d2dfbf3d732fd4da7be390ce095b Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 31 Jul 2019 15:44:24 +0200 +Subject: [PATCH 074/187] libcli:auth: Use generate_secret_buffer() for + netlogon challenge + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett + +Autobuild-User(master): Andreas Schneider +Autobuild-Date(master): Mon Aug 12 10:42:35 UTC 2019 on sn-devel-184 + +(cherry picked from commit c3ba556f52b15dd80efc26e4fb8f43ce2ee3a7f0) +--- + libcli/auth/netlogon_creds_cli.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/libcli/auth/netlogon_creds_cli.c b/libcli/auth/netlogon_creds_cli.c +index 50a5f50a57d..18143ca36d0 100644 +--- a/libcli/auth/netlogon_creds_cli.c ++++ b/libcli/auth/netlogon_creds_cli.c +@@ -1177,7 +1177,8 @@ static void netlogon_creds_cli_auth_challenge_start(struct tevent_req *req) + + TALLOC_FREE(state->creds); + +- generate_random_buffer(state->client_challenge.data, ++ /* We need to use a CSPRNG which reseeds for generating session keys. */ ++ generate_secret_buffer(state->client_challenge.data, + sizeof(state->client_challenge.data)); + + subreq = dcerpc_netr_ServerReqChallenge_send(state, state->ev, +-- +2.23.0 + diff --git a/SOURCES/0075-lib-util-Fix-documentation-for-random-number-functio.patch b/SOURCES/0075-lib-util-Fix-documentation-for-random-number-functio.patch new file mode 100644 index 0000000..4266de9 --- /dev/null +++ b/SOURCES/0075-lib-util-Fix-documentation-for-random-number-functio.patch @@ -0,0 +1,72 @@ +From 5d53f417762503b9c73edcdb1364834f3b665e74 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Mon, 12 Aug 2019 16:10:20 +0200 +Subject: [PATCH 075/187] lib:util: Fix documentation for random number + functions + +Signed-off-by: Andreas Schneider +Reviewed-by: Alexander Bokovoy +(cherry picked from commit 97c441d7c28feb29168e81ebbc5c55b09a845087) +--- + lib/util/genrand.c | 9 +++++++-- + lib/util/genrand.h | 8 ++++++-- + 2 files changed, 13 insertions(+), 4 deletions(-) + +diff --git a/lib/util/genrand.c b/lib/util/genrand.c +index a5809aa2bc9..18ffa0d95e6 100644 +--- a/lib/util/genrand.c ++++ b/lib/util/genrand.c +@@ -33,13 +33,16 @@ + + _PUBLIC_ void generate_random_buffer(uint8_t *out, int len) + { +- /* Thread and fork safe random number generator for temporary keys. */ ++ /* Random number generator for temporary keys. */ + gnutls_rnd(GNUTLS_RND_RANDOM, out, len); + } + + _PUBLIC_ void generate_secret_buffer(uint8_t *out, int len) + { +- /* The key generator, will re-seed after a fixed amount of bytes is ++ /* ++ * Random number generator for long term keys. ++ * ++ * The key generator, will re-seed after a fixed amount of bytes is + * generated (typically less than the nonce), and will also re-seed + * based on time, i.e., after few hours of operation without reaching + * the limit for a re-seed. For its re-seed it mixes mixes data obtained +@@ -51,6 +54,8 @@ _PUBLIC_ void generate_secret_buffer(uint8_t *out, int len) + _PUBLIC_ void generate_nonce_buffer(uint8_t *out, int len) + { + /* ++ * Random number generator for nonce and initialization vectors. ++ * + * The nonce generator will reseed after outputting a fixed amount of + * bytes (typically few megabytes), or after few hours of operation + * without reaching the limit has passed. +diff --git a/lib/util/genrand.h b/lib/util/genrand.h +index abb8ce2c10a..70f36312e58 100644 +--- a/lib/util/genrand.h ++++ b/lib/util/genrand.h +@@ -20,12 +20,16 @@ + */ + + /** +- * Thread and fork safe random number generator for temporary keys. ++ * @brief Generate random values for session and temporary keys. ++ * ++ * @param[in] out A pointer to the buffer to fill with random data. ++ * ++ * @param[in] len The size of the buffer to fill. + */ + void generate_random_buffer(uint8_t *out, int len); + + /** +- * @brief Generate random values for key buffers (e.g. session keys) ++ * @brief Generate random values for long term keys and passwords. + * + * @param[in] out A pointer to the buffer to fill with random data. + * +-- +2.23.0 + diff --git a/SOURCES/0076-Revert-libcli-auth-Use-generate_secret_buffer-for-ne.patch b/SOURCES/0076-Revert-libcli-auth-Use-generate_secret_buffer-for-ne.patch new file mode 100644 index 0000000..bc01509 --- /dev/null +++ b/SOURCES/0076-Revert-libcli-auth-Use-generate_secret_buffer-for-ne.patch @@ -0,0 +1,31 @@ +From 5b8d3df9856f081cbca601926ca909085cc73f05 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Mon, 12 Aug 2019 18:49:31 +0200 +Subject: [PATCH 076/187] Revert "libcli:auth: Use generate_secret_buffer() for + netlogon challenge" + +This reverts commit c3ba556f52b15dd80efc26e4fb8f43ce2ee3a7f0. + +Reviewed-by: Alexander Bokovoy +(cherry picked from commit 689760f26521fe5b4c8964a25ddd3ab1c9e9977c) +--- + libcli/auth/netlogon_creds_cli.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/libcli/auth/netlogon_creds_cli.c b/libcli/auth/netlogon_creds_cli.c +index 18143ca36d0..50a5f50a57d 100644 +--- a/libcli/auth/netlogon_creds_cli.c ++++ b/libcli/auth/netlogon_creds_cli.c +@@ -1177,8 +1177,7 @@ static void netlogon_creds_cli_auth_challenge_start(struct tevent_req *req) + + TALLOC_FREE(state->creds); + +- /* We need to use a CSPRNG which reseeds for generating session keys. */ +- generate_secret_buffer(state->client_challenge.data, ++ generate_random_buffer(state->client_challenge.data, + sizeof(state->client_challenge.data)); + + subreq = dcerpc_netr_ServerReqChallenge_send(state, state->ev, +-- +2.23.0 + diff --git a/SOURCES/0077-Revert-s4-rpc_server-Use-generate_secret_buffer-for-.patch b/SOURCES/0077-Revert-s4-rpc_server-Use-generate_secret_buffer-for-.patch new file mode 100644 index 0000000..fea4ddc --- /dev/null +++ b/SOURCES/0077-Revert-s4-rpc_server-Use-generate_secret_buffer-for-.patch @@ -0,0 +1,31 @@ +From c08b8c1b2ccbd3c180c730940d7efce8fcef8b5b Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Mon, 12 Aug 2019 18:49:37 +0200 +Subject: [PATCH 077/187] Revert "s4:rpc_server: Use generate_secret_buffer() + for netlogon challange" + +This reverts commit a21770cfdffd2a21045a1bc87e489af0f4c6f130. + +Reviewed-by: Alexander Bokovoy +(cherry picked from commit 1c68085404cd467c217640e3eabfc4b7f8b1ce9f) +--- + source4/rpc_server/netlogon/dcerpc_netlogon.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c +index f4e24b7fd7f..ac745e32b02 100644 +--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c ++++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c +@@ -90,8 +90,7 @@ static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_cal + + pipe_state->client_challenge = *r->in.credentials; + +- /* We need to use a CSPRNG which reseeds for generating session keys. */ +- generate_secret_buffer(pipe_state->server_challenge.data, ++ generate_random_buffer(pipe_state->server_challenge.data, + sizeof(pipe_state->server_challenge.data)); + + *r->out.return_credentials = pipe_state->server_challenge; +-- +2.23.0 + diff --git a/SOURCES/0078-Revert-s4-rpc_server-Use-generate_secret_buffer-for-.patch b/SOURCES/0078-Revert-s4-rpc_server-Use-generate_secret_buffer-for-.patch new file mode 100644 index 0000000..30c7e4e --- /dev/null +++ b/SOURCES/0078-Revert-s4-rpc_server-Use-generate_secret_buffer-for-.patch @@ -0,0 +1,31 @@ +From 5576562cc327cfa6cc77d5962ee8ec85d9ca0ad6 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Mon, 12 Aug 2019 18:49:52 +0200 +Subject: [PATCH 078/187] Revert "s4:rpc_server: Use generate_secret_buffer() + for backupkey wap_key" + +This reverts commit 5a62056b4530e4c509444be9164a1fca1dce193f. + +Reviewed-by: Alexander Bokovoy +(cherry picked from commit 38b0695ddac244c67b2a33eb927ad3e95d2e8bd6) +--- + source4/rpc_server/backupkey/dcesrv_backupkey.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/source4/rpc_server/backupkey/dcesrv_backupkey.c b/source4/rpc_server/backupkey/dcesrv_backupkey.c +index d192858e468..a826ae083f4 100644 +--- a/source4/rpc_server/backupkey/dcesrv_backupkey.c ++++ b/source4/rpc_server/backupkey/dcesrv_backupkey.c +@@ -1263,8 +1263,7 @@ static WERROR generate_bkrp_server_wrap_key(TALLOC_CTX *ctx, struct ldb_context + char *secret_name; + TALLOC_CTX *frame = talloc_stackframe(); + +- /* We need to use a CSPRNG which reseeds for generating session keys. */ +- generate_secret_buffer(wrap_key.key, sizeof(wrap_key.key)); ++ generate_random_buffer(wrap_key.key, sizeof(wrap_key.key)); + + ndr_err = ndr_push_struct_blob(&blob_wrap_key, ctx, &wrap_key, (ndr_push_flags_fn_t)ndr_push_bkrp_dc_serverwrap_key); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { +-- +2.23.0 + diff --git a/SOURCES/0079-Revert-s4-rpc_server-Use-generate_secret_buffer-to-c.patch b/SOURCES/0079-Revert-s4-rpc_server-Use-generate_secret_buffer-to-c.patch new file mode 100644 index 0000000..e38e467 --- /dev/null +++ b/SOURCES/0079-Revert-s4-rpc_server-Use-generate_secret_buffer-to-c.patch @@ -0,0 +1,34 @@ +From ea69efd5e269e3ec0c93121d0448a1f6fb4275ac Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Mon, 12 Aug 2019 18:50:02 +0200 +Subject: [PATCH 079/187] Revert "s4:rpc_server: Use generate_secret_buffer() + to create a session key" + +This reverts commit 4b2480518bd3887be3a6cfb713523ac084e09fd5. + +Reviewed-by: Alexander Bokovoy +(cherry picked from commit d73be972ea58d564c770698bf6374a6074f111fe) +--- + source4/rpc_server/samr/samr_password.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c +index 6bf907181c8..b04e37f06f3 100644 +--- a/source4/rpc_server/samr/samr_password.c ++++ b/source4/rpc_server/samr/samr_password.c +@@ -733,10 +733,9 @@ NTSTATUS samr_set_password_buffers(struct dcesrv_call_state *dce_call, + nt_errstr(nt_status))); + + /* +- * Windows just uses a random key. We need to use a CSPRNG +- * which reseeds for generating session keys. ++ * Windows just uses a random key + */ +- generate_secret_buffer(random_session_key, ++ generate_random_buffer(random_session_key, + sizeof(random_session_key)); + session_key = data_blob_const(random_session_key, + sizeof(random_session_key)); +-- +2.23.0 + diff --git a/SOURCES/0080-lib-util-Use-generate_secret_buffer-for-long-term-pa.patch b/SOURCES/0080-lib-util-Use-generate_secret_buffer-for-long-term-pa.patch new file mode 100644 index 0000000..dd413c1 --- /dev/null +++ b/SOURCES/0080-lib-util-Use-generate_secret_buffer-for-long-term-pa.patch @@ -0,0 +1,47 @@ +From d2cc9f2ef31092c1ce5e5ad967a6be4f3bc84c06 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Mon, 12 Aug 2019 18:55:56 +0200 +Subject: [PATCH 080/187] lib:util: Use generate_secret_buffer() for long term + passwords + +Signed-off-by: Andreas Schneider +Reviewed-by: Alexander Bokovoy +(cherry picked from commit 93196dd823e114f260a68d28bb59eac3909c30d8) +--- + lib/util/genrand_util.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/lib/util/genrand_util.c b/lib/util/genrand_util.c +index d7b74c6cf1a..05d1f3ef6e5 100644 +--- a/lib/util/genrand_util.c ++++ b/lib/util/genrand_util.c +@@ -185,7 +185,7 @@ _PUBLIC_ char *generate_random_str_list(TALLOC_CTX *mem_ctx, size_t len, const c + char *retstr = talloc_array(mem_ctx, char, len + 1); + if (!retstr) return NULL; + +- generate_random_buffer((uint8_t *)retstr, len); ++ generate_secret_buffer((uint8_t *)retstr, len); + for (i = 0; i < len; i++) { + retstr[i] = list[retstr[i] % list_len]; + } +@@ -247,7 +247,7 @@ _PUBLIC_ char *generate_random_password(TALLOC_CTX *mem_ctx, size_t min, size_t + if (diff > 0 ) { + size_t tmp; + +- generate_random_buffer((uint8_t *)&tmp, sizeof(tmp)); ++ generate_secret_buffer((uint8_t *)&tmp, sizeof(tmp)); + + tmp %= diff; + +@@ -317,7 +317,7 @@ _PUBLIC_ char *generate_random_machine_password(TALLOC_CTX *mem_ctx, size_t min, + if (diff > 0) { + size_t tmp; + +- generate_random_buffer((uint8_t *)&tmp, sizeof(tmp)); ++ generate_secret_buffer((uint8_t *)&tmp, sizeof(tmp)); + + tmp %= diff; + +-- +2.23.0 + diff --git a/SOURCES/0081-s4-samdb-Use-generate_nonce_buffer-for-AEC-GCM-nonce.patch b/SOURCES/0081-s4-samdb-Use-generate_nonce_buffer-for-AEC-GCM-nonce.patch new file mode 100644 index 0000000..1abba96 --- /dev/null +++ b/SOURCES/0081-s4-samdb-Use-generate_nonce_buffer-for-AEC-GCM-nonce.patch @@ -0,0 +1,29 @@ +From 3a22faf5aa81b8a2e918e250cb201440094f9757 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Mon, 12 Aug 2019 18:56:35 +0200 +Subject: [PATCH 081/187] s4:samdb: Use generate_nonce_buffer() for AEC GCM + nonce + +Signed-off-by: Andreas Schneider +Reviewed-by: Alexander Bokovoy +(cherry picked from commit a3e36dd8f43a5c06969ae158fa54fbc649f44d03) +--- + source4/dsdb/samdb/ldb_modules/encrypted_secrets.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/source4/dsdb/samdb/ldb_modules/encrypted_secrets.c b/source4/dsdb/samdb/ldb_modules/encrypted_secrets.c +index b2df15c08f4..deaa03cbb35 100644 +--- a/source4/dsdb/samdb/ldb_modules/encrypted_secrets.c ++++ b/source4/dsdb/samdb/ldb_modules/encrypted_secrets.c +@@ -447,7 +447,7 @@ static struct ldb_val samba_encrypt_aead(int *err, + goto error_exit; + } + +- generate_random_buffer(iv, AES_GCM_128_IV_SIZE); ++ generate_nonce_buffer(iv, AES_GCM_128_IV_SIZE); + + es->iv.length = AES_GCM_128_IV_SIZE; + es->iv.data = iv; +-- +2.23.0 + diff --git a/SOURCES/0082-s3-passdb-Use-generate_secret_buffer-for-generating-.patch b/SOURCES/0082-s3-passdb-Use-generate_secret_buffer-for-generating-.patch new file mode 100644 index 0000000..39ed0eb --- /dev/null +++ b/SOURCES/0082-s3-passdb-Use-generate_secret_buffer-for-generating-.patch @@ -0,0 +1,30 @@ +From 8057d84f33d96a3143b1908b47e65e6a89d4f861 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Mon, 12 Aug 2019 18:57:06 +0200 +Subject: [PATCH 082/187] s3:passdb: Use generate_secret_buffer() for + generating passwords + +Signed-off-by: Andreas Schneider +Reviewed-by: Alexander Bokovoy +(cherry picked from commit 6fa3e4de7c168dc7c869ec9966729a36bda27f57) +--- + source3/passdb/pdb_nds.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/source3/passdb/pdb_nds.c b/source3/passdb/pdb_nds.c +index 349ea0b6c38..216c9e6b50b 100644 +--- a/source3/passdb/pdb_nds.c ++++ b/source3/passdb/pdb_nds.c +@@ -814,7 +814,8 @@ static NTSTATUS pdb_nds_update_login_attempts(struct pdb_methods *methods, + got_clear_text_pw = True; + } + } else { +- generate_random_buffer((unsigned char *)clear_text_pw, 24); ++ /* This is a long term key */ ++ generate_secret_buffer((unsigned char *)clear_text_pw, 24); + clear_text_pw[24] = '\0'; + DEBUG(5,("pdb_nds_update_login_attempts: using random password %s\n", clear_text_pw)); + } +-- +2.23.0 + diff --git a/SOURCES/0083-auth-ntlmssp-Use-generate_random_buffer-for-session-.patch b/SOURCES/0083-auth-ntlmssp-Use-generate_random_buffer-for-session-.patch new file mode 100644 index 0000000..1d4f07e --- /dev/null +++ b/SOURCES/0083-auth-ntlmssp-Use-generate_random_buffer-for-session-.patch @@ -0,0 +1,33 @@ +From 9a257522e3c811853b2b9f0b93992b07ecdad5d9 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Mon, 12 Aug 2019 19:07:15 +0200 +Subject: [PATCH 083/187] auth:ntlmssp: Use generate_random_buffer() for + session keys + +Signed-off-by: Andreas Schneider +Reviewed-by: Alexander Bokovoy + +Autobuild-User(master): Alexander Bokovoy +Autobuild-Date(master): Wed Aug 14 16:26:47 UTC 2019 on sn-devel-184 + +(cherry picked from commit 9b7825d2d387bcb2515154418a990669ab96358d) +--- + auth/ntlmssp/ntlmssp_client.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c +index b8d1190466b..2a80feb4fed 100644 +--- a/auth/ntlmssp/ntlmssp_client.c ++++ b/auth/ntlmssp/ntlmssp_client.c +@@ -696,7 +696,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, + .size = session_key.length, + }; + +- generate_secret_buffer(client_session_key, sizeof(client_session_key)); ++ generate_random_buffer(client_session_key, sizeof(client_session_key)); + + /* Encrypt the new session key with the old one */ + encrypted_session_key = data_blob_talloc(ntlmssp_state, +-- +2.23.0 + diff --git a/SOURCES/0084-encrypted_secrets-Add-known-and-expected-value-test.patch b/SOURCES/0084-encrypted_secrets-Add-known-and-expected-value-test.patch new file mode 100644 index 0000000..28df652 --- /dev/null +++ b/SOURCES/0084-encrypted_secrets-Add-known-and-expected-value-test.patch @@ -0,0 +1,84 @@ +From 40a13974c5279d43fa2e13b8a274ba41ec051533 Mon Sep 17 00:00:00 2001 +From: Andrew Bartlett +Date: Thu, 15 Aug 2019 15:27:30 +1200 +Subject: [PATCH 084/187] encrypted_secrets: Add known and expected value test + +Signed-off-by: Andrew Bartlett +Reviewed-by: Andreas Schneider +(cherry picked from commit 92b9cdf99da1f8657c166d413c5136c8db938a9e) +--- + .../tests/test_encrypted_secrets.c | 51 +++++++++++++++++++ + 1 file changed, 51 insertions(+) + +diff --git a/source4/dsdb/samdb/ldb_modules/tests/test_encrypted_secrets.c b/source4/dsdb/samdb/ldb_modules/tests/test_encrypted_secrets.c +index 258e1ba829f..cfea95ae544 100644 +--- a/source4/dsdb/samdb/ldb_modules/tests/test_encrypted_secrets.c ++++ b/source4/dsdb/samdb/ldb_modules/tests/test_encrypted_secrets.c +@@ -1101,6 +1101,53 @@ static void test_unencrypted_secret(void **state) + assert_int_equal(LDB_ERR_OPERATIONS_ERROR, ret); + } + ++/* ++ * Test full decryption of a static value with static key ++ */ ++static void test_record_decryption(void **state) ++{ ++ struct ldbtest_ctx *test_ctx = ++ talloc_get_type_abort(*state, struct ldbtest_ctx); ++ unsigned char plain_data[] = { ++ 0xe6, 0xa6, 0xb8, 0xff, 0xdf, 0x06, 0x6c, 0xe3, ++ 0xea, 0xd0, 0x94, 0xbb, 0x79, 0xbd, 0x0a, 0x24 ++ }; ++ unsigned char encrypted_data[] = { ++ 0x0c, 0x00, 0x00, 0x00, 0x33, 0x91, 0x74, 0x25, ++ 0x26, 0xcc, 0x0b, 0x8c, 0x21, 0xc1, 0x13, 0xe2, ++ 0xed, 0xad, 0x5c, 0xca, 0x01, 0x00, 0x00, 0x00, ++ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x1a, 0xdc, 0xc9, 0x11, 0x08, 0xca, 0x2c, 0xfb, ++ 0xc8, 0x32, 0x6b, 0x1b, 0x25, 0x7f, 0x52, 0xbb, ++ 0xae, 0x9b, 0x88, 0x52, 0xb0, 0x18, 0x6d, 0x9d, ++ 0x9b, 0xdd, 0xcd, 0x1b, 0x5f, 0x4a, 0x5c, 0x29, ++ 0xca, 0x0b, 0x36, 0xaa ++ }; ++ struct ldb_val cipher_text ++ = data_blob_const(encrypted_data, ++ sizeof(encrypted_data)); ++ unsigned char es_keys_blob[] = { ++ 0x1d, 0xae, 0xf5, 0xaa, 0xa3, 0x85, 0x0d, 0x0a, ++ 0x8c, 0x24, 0x5c, 0x4c, 0xa7, 0x0f, 0x81, 0x79 ++ }; ++ struct es_data data = { ++ .encrypt_secrets = true, ++ .keys[0] = { ++ .data = es_keys_blob, ++ .length = sizeof(es_keys_blob), ++ }, ++#ifdef HAVE_GNUTLS_AEAD ++ .encryption_algorithm = GNUTLS_CIPHER_AES_128_GCM, ++#endif ++ }; ++ int err = LDB_SUCCESS; ++ struct ldb_val dec = decrypt_value(&err, test_ctx, test_ctx->ldb, cipher_text, ++ &data); ++ assert_int_equal(LDB_SUCCESS, err); ++ assert_int_equal(sizeof(plain_data), dec.length); ++ assert_memory_equal(dec.data, plain_data, sizeof(plain_data)); ++} ++ + + int main(void) { + const struct CMUnitTest tests[] = { +@@ -1166,6 +1213,10 @@ int main(void) { + test_unencrypted_secret, + setup_with_key, + teardown), ++ cmocka_unit_test_setup_teardown( ++ test_record_decryption, ++ setup_with_key, ++ teardown), + }; + + cmocka_set_message_output(CM_OUTPUT_SUBUNIT); +-- +2.23.0 + diff --git a/SOURCES/0085-s4-samdb-Remove-dual-stack-mode-from-test_-encrypted.patch b/SOURCES/0085-s4-samdb-Remove-dual-stack-mode-from-test_-encrypted.patch new file mode 100644 index 0000000..a2fa5bb --- /dev/null +++ b/SOURCES/0085-s4-samdb-Remove-dual-stack-mode-from-test_-encrypted.patch @@ -0,0 +1,154 @@ +From ce7a5f793d0d5983504be61189ec7c57cfbf07d0 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Tue, 26 Feb 2019 18:32:34 +0100 +Subject: [PATCH 085/187] s4:samdb: Remove dual-stack mode from + (test_)encrypted_secrets + +Now we either build with GnuTLS or Samba crypto. If a modern GnuTLS +version is detected that will be used and Samba crypto wont be +available. + +This removes the dual-stack mode that encrypted with one and decrypted +with the other in the testsuite. + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett + +Commit message clarified by Andrew Bartlett + +Signed-off-by: Andrew Bartlett +(cherry picked from commit 7bf3c5d7640daaf5dc799eaf698618903ec09127) +--- + .../samdb/ldb_modules/encrypted_secrets.c | 16 ++---- + .../tests/test_encrypted_secrets.c | 49 ++----------------- + 2 files changed, 10 insertions(+), 55 deletions(-) + +diff --git a/source4/dsdb/samdb/ldb_modules/encrypted_secrets.c b/source4/dsdb/samdb/ldb_modules/encrypted_secrets.c +index deaa03cbb35..5f8cd8747ea 100644 +--- a/source4/dsdb/samdb/ldb_modules/encrypted_secrets.c ++++ b/source4/dsdb/samdb/ldb_modules/encrypted_secrets.c +@@ -39,18 +39,12 @@ + #include "dsdb/samdb/samdb.h" + #include "dsdb/samdb/ldb_modules/util.h" + +-#ifdef TEST_ENCRYPTED_SECRETS ++/* Build either with GnuTLS crypto or Samba crypto. */ ++#ifdef HAVE_GNUTLS_AEAD ++ #define BUILD_WITH_GNUTLS_AEAD ++#else /* !HAVE_GNUTLS_AEAD */ + #define BUILD_WITH_SAMBA_AES_GCM +- #ifdef HAVE_GNUTLS_AEAD +- #define BUILD_WITH_GNUTLS_AEAD +- #endif +-#else +- #ifdef HAVE_GNUTLS_AEAD +- #define BUILD_WITH_GNUTLS_AEAD +- #else +- #define BUILD_WITH_SAMBA_AES_GCM +- #endif +-#endif ++#endif /* HAVE_GNUTLS_AEAD */ + + #ifdef BUILD_WITH_GNUTLS_AEAD + #include +diff --git a/source4/dsdb/samdb/ldb_modules/tests/test_encrypted_secrets.c b/source4/dsdb/samdb/ldb_modules/tests/test_encrypted_secrets.c +index cfea95ae544..a33781d703d 100644 +--- a/source4/dsdb/samdb/ldb_modules/tests/test_encrypted_secrets.c ++++ b/source4/dsdb/samdb/ldb_modules/tests/test_encrypted_secrets.c +@@ -390,26 +390,6 @@ static void test_gnutls_value_encryption(void **state) + &decrypted->cleartext, + &plain_text)); + } +- +- { +- struct PlaintextSecret *decrypted = +- talloc_zero(test_ctx, struct PlaintextSecret); +- samba_decrypt_aead( +- &err, +- test_ctx, +- test_ctx->ldb, +- &es, +- decrypted, +- data); +- assert_int_equal(LDB_SUCCESS, err); +- assert_int_equal( +- plain_text.length, +- decrypted->cleartext.length); +- assert_int_equal(0, +- data_blob_cmp( +- &decrypted->cleartext, +- &plain_text)); +- } + } + #endif /* HAVE_GNUTLS_AEAD */ + +@@ -613,9 +593,11 @@ static void test_gnutls_altered_iv(void **state) + } + } + #endif /* HAVE_GNUTLS_AEAD */ ++ + /* + * Test samba encryption and decryption and decryption. + */ ++#ifndef HAVE_GNUTLS_AEAD + static void test_samba_value_encryption(void **state) + { + struct ldbtest_ctx *test_ctx = +@@ -647,29 +629,6 @@ static void test_samba_value_encryption(void **state) + assert_true(NDR_ERR_CODE_IS_SUCCESS(rc)); + assert_true(check_header(&es)); + +-#ifdef HAVE_GNUTLS_AEAD +- { +- struct PlaintextSecret *decrypted = +- talloc_zero(test_ctx, struct PlaintextSecret); +- gnutls_decrypt_aead( +- &err, +- test_ctx, +- test_ctx->ldb, +- &es, +- decrypted, +- data); +- assert_int_equal(LDB_SUCCESS, err); +- assert_int_equal( +- plain_text.length, +- decrypted->cleartext.length); +- assert_int_equal(0, +- data_blob_cmp( +- &decrypted->cleartext, +- &plain_text)); +- } +-#endif /* HAVE_GNUTLS_AEAD */ +- +- + { + struct PlaintextSecret *decrypted = + talloc_zero(test_ctx, struct PlaintextSecret); +@@ -886,6 +845,7 @@ static void test_samba_altered_iv(void **state) + assert_int_equal(LDB_ERR_OPERATIONS_ERROR, err); + } + } ++#endif + + /* + * Test message encryption. +@@ -1188,7 +1148,7 @@ int main(void) { + test_gnutls_altered_iv, + setup_with_key, + teardown), +-#endif /* HAVE_GNUTLS_AEAD */ ++#else + cmocka_unit_test_setup_teardown( + test_samba_value_encryption, + setup_with_key, +@@ -1205,6 +1165,7 @@ int main(void) { + test_samba_altered_iv, + setup_with_key, + teardown), ++#endif /* HAVE_GNUTLS_AEAD */ + cmocka_unit_test_setup_teardown( + test_message_encryption_decryption, + setup_with_key, +-- +2.23.0 + diff --git a/SOURCES/0086-s4-samdb-Only-include-necessary-header-files-in-encr.patch b/SOURCES/0086-s4-samdb-Only-include-necessary-header-files-in-encr.patch new file mode 100644 index 0000000..36a587e --- /dev/null +++ b/SOURCES/0086-s4-samdb-Only-include-necessary-header-files-in-encr.patch @@ -0,0 +1,30 @@ +From 23e2849f8f5b119ebce9cb0aeee098a8c1a388e0 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Tue, 26 Feb 2019 18:33:09 +0100 +Subject: [PATCH 086/187] s4:samdb: Only include necessary header files in + encrypted_secrets + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit d46e538d52433f5f30a5696e5b18bc4b82101951) +--- + source4/dsdb/samdb/ldb_modules/encrypted_secrets.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/source4/dsdb/samdb/ldb_modules/encrypted_secrets.c b/source4/dsdb/samdb/ldb_modules/encrypted_secrets.c +index 5f8cd8747ea..e0932858588 100644 +--- a/source4/dsdb/samdb/ldb_modules/encrypted_secrets.c ++++ b/source4/dsdb/samdb/ldb_modules/encrypted_secrets.c +@@ -52,7 +52,8 @@ + #endif /* BUILD_WITH_GNUTLS_AEAD */ + + #ifdef BUILD_WITH_SAMBA_AES_GCM +- #include "lib/crypto/crypto.h" ++ #include "lib/crypto/aes.h" ++ #include "lib/crypto/aes_gcm_128.h" + #endif /* BUILD_WITH_SAMBA_AES_GCM */ + + static const char * const secret_attributes[] = {DSDB_SECRET_ATTRIBUTES}; +-- +2.23.0 + diff --git a/SOURCES/0087-waf-Check-for-GNUTLS-AES-CFB-support.patch b/SOURCES/0087-waf-Check-for-GNUTLS-AES-CFB-support.patch new file mode 100644 index 0000000..4ad05c2 --- /dev/null +++ b/SOURCES/0087-waf-Check-for-GNUTLS-AES-CFB-support.patch @@ -0,0 +1,29 @@ +From ea3711fc1f4459a9654dd237ffbc71a42375629c Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Fri, 1 Mar 2019 17:35:02 +0100 +Subject: [PATCH 087/187] waf: Check for GNUTLS AES CFB support + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 20a42459df4fdd57cdf1807a3d97dc5b1c553476) +--- + wscript_configure_system_gnutls | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/wscript_configure_system_gnutls b/wscript_configure_system_gnutls +index cc9a2b035a2..85824aad4ed 100644 +--- a/wscript_configure_system_gnutls ++++ b/wscript_configure_system_gnutls +@@ -36,3 +36,9 @@ if conf.CHECK_FUNCS_IN('gnutls_aead_cipher_init', + conf.DEFINE('HAVE_GNUTLS_AEAD', '1') + else: + Logs.warn('No gnutls support for AEAD encryption') ++ ++if conf.CHECK_VALUEOF('GNUTLS_CIPHER_AES_128_CFB8', headers='gnutls/gnutls.h'): ++ conf.DEFINE('HAVE_GNUTLS_AES_CFB8', 1) ++ conf.DEFINE('HAVE_GNUTLS_3_4_7', 1) ++else: ++ Logs.warn('No gnutls support for AES CFB8') +-- +2.23.0 + diff --git a/SOURCES/0088-libcli-auth-Use-netlogon_creds_aes_encrypt-in-netlog.patch b/SOURCES/0088-libcli-auth-Use-netlogon_creds_aes_encrypt-in-netlog.patch new file mode 100644 index 0000000..6d50e27 --- /dev/null +++ b/SOURCES/0088-libcli-auth-Use-netlogon_creds_aes_encrypt-in-netlog.patch @@ -0,0 +1,35 @@ +From 563e6a454706f29171b4bf06473cc40c557b0eed Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Fri, 1 Mar 2019 17:33:01 +0100 +Subject: [PATCH 088/187] libcli:auth: Use netlogon_creds_aes_encrypt() in + netlogon_creds_step_crypt() + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit cd97c47873007bfc502926070a758b520d95abf1) +--- + libcli/auth/credentials.c | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) + +diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c +index 319dacdac0b..3b31d1e0300 100644 +--- a/libcli/auth/credentials.c ++++ b/libcli/auth/credentials.c +@@ -35,12 +35,9 @@ static void netlogon_creds_step_crypt(struct netlogon_creds_CredentialState *cre + struct netr_Credential *out) + { + if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { +- AES_KEY key; +- uint8_t iv[AES_BLOCK_SIZE] = {0}; ++ memcpy(out->data, in->data, sizeof(out->data)); + +- AES_set_encrypt_key(creds->session_key, 128, &key); +- +- aes_cfb8_encrypt(in->data, out->data, 8, &key, iv, AES_ENCRYPT); ++ netlogon_creds_aes_encrypt(creds, out->data, sizeof(out->data)); + } else { + des_crypt112(out->data, in->data, creds->session_key, 1); + } +-- +2.23.0 + diff --git a/SOURCES/0089-libcli-auth-Use-GnuTLS-AES128-CFB-for-netlogon_creds.patch b/SOURCES/0089-libcli-auth-Use-GnuTLS-AES128-CFB-for-netlogon_creds.patch new file mode 100644 index 0000000..232ab2f --- /dev/null +++ b/SOURCES/0089-libcli-auth-Use-GnuTLS-AES128-CFB-for-netlogon_creds.patch @@ -0,0 +1,69 @@ +From efe2ed9aa8d1a1be574149f591015cc063c24fb7 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Fri, 1 Mar 2019 17:41:11 +0100 +Subject: [PATCH 089/187] libcli:auth: Use GnuTLS AES128 CFB for + netlogon_creds_aes_encrypt() + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 054efd118d7500e28f118722312aaae0df2749b0) +--- + libcli/auth/credentials.c | 36 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 36 insertions(+) + +diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c +index 3b31d1e0300..5a1692ef436 100644 +--- a/libcli/auth/credentials.c ++++ b/libcli/auth/credentials.c +@@ -295,12 +295,48 @@ NTSTATUS netlogon_creds_arcfour_crypt(struct netlogon_creds_CredentialState *cre + */ + void netlogon_creds_aes_encrypt(struct netlogon_creds_CredentialState *creds, uint8_t *data, size_t len) + { ++#ifdef HAVE_GNUTLS_AES_CFB8 ++ gnutls_cipher_hd_t cipher_hnd = NULL; ++ gnutls_datum_t key = { ++ .data = creds->session_key, ++ .size = sizeof(creds->session_key), ++ }; ++ uint32_t iv_size = ++ gnutls_cipher_get_iv_size(GNUTLS_CIPHER_AES_128_CFB8); ++ uint8_t _iv[iv_size]; ++ gnutls_datum_t iv = { ++ .data = _iv, ++ .size = iv_size, ++ }; ++ int rc; ++ ++ ZERO_ARRAY(_iv); ++ ++ rc = gnutls_cipher_init(&cipher_hnd, ++ GNUTLS_CIPHER_AES_128_CFB8, ++ &key, ++ &iv); ++ if (rc < 0) { ++ DBG_ERR("ERROR: gnutls_cipher_init: %s\n", ++ gnutls_strerror(rc)); ++ return; ++ } ++ ++ rc = gnutls_cipher_encrypt(cipher_hnd, data, len); ++ gnutls_cipher_deinit(cipher_hnd); ++ if (rc < 0) { ++ DBG_ERR("ERROR: gnutls_cipher_encrypt: %s\n", ++ gnutls_strerror(rc)); ++ return; ++ } ++#else /* NOT HAVE_GNUTLS_AES_CFB8 */ + AES_KEY key; + uint8_t iv[AES_BLOCK_SIZE] = {0}; + + AES_set_encrypt_key(creds->session_key, 128, &key); + + aes_cfb8_encrypt(data, data, len, &key, iv, AES_ENCRYPT); ++#endif /* HAVE_GNUTLS_AES_CFB8 */ + } + + /* +-- +2.23.0 + diff --git a/SOURCES/0090-libcli-auth-Return-NTSTATUS-for-netlogon_creds_aes_e.patch b/SOURCES/0090-libcli-auth-Return-NTSTATUS-for-netlogon_creds_aes_e.patch new file mode 100644 index 0000000..e09d0d6 --- /dev/null +++ b/SOURCES/0090-libcli-auth-Return-NTSTATUS-for-netlogon_creds_aes_e.patch @@ -0,0 +1,82 @@ +From cd45ceb7c38ef77ad9d6cc42ad8184ebc6829cf7 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 29 May 2019 16:38:09 +0200 +Subject: [PATCH 090/187] libcli:auth: Return NTSTATUS for + netlogon_creds_aes_encrypt() + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett + +Adapted by Andrew Bartlett to use gnutls_error_to_ntstatus() + +Signed-off-by: Andrew Bartlett +(cherry picked from commit ded5aad21b54b8783f7390fb2eca483d3861eeff) +--- + libcli/auth/credentials.c | 15 ++++++++------- + libcli/auth/proto.h | 4 +++- + 2 files changed, 11 insertions(+), 8 deletions(-) + +diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c +index 5a1692ef436..87f8820238e 100644 +--- a/libcli/auth/credentials.c ++++ b/libcli/auth/credentials.c +@@ -293,7 +293,9 @@ NTSTATUS netlogon_creds_arcfour_crypt(struct netlogon_creds_CredentialState *cre + /* + AES encrypt a password buffer using the session key + */ +-void netlogon_creds_aes_encrypt(struct netlogon_creds_CredentialState *creds, uint8_t *data, size_t len) ++NTSTATUS netlogon_creds_aes_encrypt(struct netlogon_creds_CredentialState *creds, ++ uint8_t *data, ++ size_t len) + { + #ifdef HAVE_GNUTLS_AES_CFB8 + gnutls_cipher_hd_t cipher_hnd = NULL; +@@ -317,18 +319,15 @@ void netlogon_creds_aes_encrypt(struct netlogon_creds_CredentialState *creds, ui + &key, + &iv); + if (rc < 0) { +- DBG_ERR("ERROR: gnutls_cipher_init: %s\n", +- gnutls_strerror(rc)); +- return; ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); + } + + rc = gnutls_cipher_encrypt(cipher_hnd, data, len); + gnutls_cipher_deinit(cipher_hnd); + if (rc < 0) { +- DBG_ERR("ERROR: gnutls_cipher_encrypt: %s\n", +- gnutls_strerror(rc)); +- return; ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); + } ++ + #else /* NOT HAVE_GNUTLS_AES_CFB8 */ + AES_KEY key; + uint8_t iv[AES_BLOCK_SIZE] = {0}; +@@ -337,6 +336,8 @@ void netlogon_creds_aes_encrypt(struct netlogon_creds_CredentialState *creds, ui + + aes_cfb8_encrypt(data, data, len, &key, iv, AES_ENCRYPT); + #endif /* HAVE_GNUTLS_AES_CFB8 */ ++ ++ return NT_STATUS_OK; + } + + /* +diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h +index 65ee06215dc..639a50425e5 100644 +--- a/libcli/auth/proto.h ++++ b/libcli/auth/proto.h +@@ -18,7 +18,9 @@ void netlogon_creds_des_decrypt(struct netlogon_creds_CredentialState *creds, st + 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); ++NTSTATUS 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); + + /***************************************************************** +-- +2.23.0 + diff --git a/SOURCES/0091-libcli-auth-Use-GnuTLS-AES128-CFB-for-netlogon_creds.patch b/SOURCES/0091-libcli-auth-Use-GnuTLS-AES128-CFB-for-netlogon_creds.patch new file mode 100644 index 0000000..db39b96 --- /dev/null +++ b/SOURCES/0091-libcli-auth-Use-GnuTLS-AES128-CFB-for-netlogon_creds.patch @@ -0,0 +1,84 @@ +From 9b5fa6c165e98ddec38bc976bac0cfee62fd0d72 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Mon, 18 Mar 2019 15:13:08 +0100 +Subject: [PATCH 091/187] libcli:auth: Use GnuTLS AES128 CFB for + netlogon_creds_aes_decrypt() + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit a96728586150768957b88a0714b15f13ee9f81af) +--- + libcli/auth/credentials.c | 41 ++++++++++++++++++++++++++++++++++++++- + 1 file changed, 40 insertions(+), 1 deletion(-) + +diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c +index 87f8820238e..cfeab6efdcd 100644 +--- a/libcli/auth/credentials.c ++++ b/libcli/auth/credentials.c +@@ -22,10 +22,13 @@ + + #include "includes.h" + #include "system/time.h" +-#include "../lib/crypto/crypto.h" + #include "libcli/auth/libcli_auth.h" + #include "../libcli/security/dom_sid.h" + ++#ifndef HAVE_GNUTLS_AES_CFB8 ++#include "lib/crypto/aes.h" ++#endif ++ + #include "lib/crypto/gnutls_helpers.h" + #include + #include +@@ -345,12 +348,48 @@ NTSTATUS netlogon_creds_aes_encrypt(struct netlogon_creds_CredentialState *creds + */ + void netlogon_creds_aes_decrypt(struct netlogon_creds_CredentialState *creds, uint8_t *data, size_t len) + { ++#ifdef HAVE_GNUTLS_AES_CFB8 ++ gnutls_cipher_hd_t cipher_hnd = NULL; ++ gnutls_datum_t key = { ++ .data = creds->session_key, ++ .size = sizeof(creds->session_key), ++ }; ++ uint32_t iv_size = ++ gnutls_cipher_get_iv_size(GNUTLS_CIPHER_AES_128_CFB8); ++ uint8_t _iv[iv_size]; ++ gnutls_datum_t iv = { ++ .data = _iv, ++ .size = iv_size, ++ }; ++ int rc; ++ ++ ZERO_ARRAY(_iv); ++ ++ rc = gnutls_cipher_init(&cipher_hnd, ++ GNUTLS_CIPHER_AES_128_CFB8, ++ &key, ++ &iv); ++ if (rc < 0) { ++ DBG_ERR("ERROR: gnutls_cipher_init: %s\n", ++ gnutls_strerror(rc)); ++ return; ++ } ++ ++ rc = gnutls_cipher_decrypt(cipher_hnd, data, len); ++ gnutls_cipher_deinit(cipher_hnd); ++ if (rc < 0) { ++ DBG_ERR("ERROR: gnutls_cipher_decrypt: %s\n", ++ gnutls_strerror(rc)); ++ return; ++ } ++#else /* NOT HAVE_GNUTLS_AES_CFB8 */ + AES_KEY key; + uint8_t iv[AES_BLOCK_SIZE] = {0}; + + AES_set_encrypt_key(creds->session_key, 128, &key); + + aes_cfb8_encrypt(data, data, len, &key, iv, AES_DECRYPT); ++#endif /* HAVE_GNUTLS_AES_CFB8 */ + } + + /***************************************************************** +-- +2.23.0 + diff --git a/SOURCES/0092-libcli-auth-Return-NTSTATUS-from-netlogon_creds_aes_.patch b/SOURCES/0092-libcli-auth-Return-NTSTATUS-from-netlogon_creds_aes_.patch new file mode 100644 index 0000000..bdeeaca --- /dev/null +++ b/SOURCES/0092-libcli-auth-Return-NTSTATUS-from-netlogon_creds_aes_.patch @@ -0,0 +1,78 @@ +From a5149014cc8a0da7b8c664a465f6108c390d127d Mon Sep 17 00:00:00 2001 +From: Andrew Bartlett +Date: Fri, 16 Aug 2019 12:34:28 +1200 +Subject: [PATCH 092/187] libcli:auth Return NTSTATUS from + netlogon_creds_aes_decrypt() + +Signed-off-by: Andrew Bartlett +Reviewed-by: Andreas Schneider +(cherry picked from commit 8ec796f1a1daa444bba06f34a50d2b62ee4a2ef9) +--- + libcli/auth/credentials.c | 15 ++++++++------- + libcli/auth/proto.h | 4 +++- + 2 files changed, 11 insertions(+), 8 deletions(-) + +diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c +index cfeab6efdcd..955e08b7385 100644 +--- a/libcli/auth/credentials.c ++++ b/libcli/auth/credentials.c +@@ -346,7 +346,7 @@ NTSTATUS netlogon_creds_aes_encrypt(struct netlogon_creds_CredentialState *creds + /* + AES decrypt a password buffer using the session key + */ +-void netlogon_creds_aes_decrypt(struct netlogon_creds_CredentialState *creds, uint8_t *data, size_t len) ++NTSTATUS netlogon_creds_aes_decrypt(struct netlogon_creds_CredentialState *creds, uint8_t *data, size_t len) + { + #ifdef HAVE_GNUTLS_AES_CFB8 + gnutls_cipher_hd_t cipher_hnd = NULL; +@@ -370,18 +370,17 @@ void netlogon_creds_aes_decrypt(struct netlogon_creds_CredentialState *creds, ui + &key, + &iv); + if (rc < 0) { +- DBG_ERR("ERROR: gnutls_cipher_init: %s\n", +- gnutls_strerror(rc)); +- return; ++ return gnutls_error_to_ntstatus(rc, ++ NT_STATUS_CRYPTO_SYSTEM_INVALID); + } + + rc = gnutls_cipher_decrypt(cipher_hnd, data, len); + gnutls_cipher_deinit(cipher_hnd); + if (rc < 0) { +- DBG_ERR("ERROR: gnutls_cipher_decrypt: %s\n", +- gnutls_strerror(rc)); +- return; ++ return gnutls_error_to_ntstatus(rc, ++ NT_STATUS_CRYPTO_SYSTEM_INVALID); + } ++ + #else /* NOT HAVE_GNUTLS_AES_CFB8 */ + AES_KEY key; + uint8_t iv[AES_BLOCK_SIZE] = {0}; +@@ -390,6 +389,8 @@ void netlogon_creds_aes_decrypt(struct netlogon_creds_CredentialState *creds, ui + + aes_cfb8_encrypt(data, data, len, &key, iv, AES_DECRYPT); + #endif /* HAVE_GNUTLS_AES_CFB8 */ ++ ++ return NT_STATUS_OK; + } + + /***************************************************************** +diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h +index 639a50425e5..714652bdb76 100644 +--- a/libcli/auth/proto.h ++++ b/libcli/auth/proto.h +@@ -21,7 +21,9 @@ NTSTATUS netlogon_creds_arcfour_crypt(struct netlogon_creds_CredentialState *cre + NTSTATUS 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); ++NTSTATUS netlogon_creds_aes_decrypt(struct netlogon_creds_CredentialState *creds, ++ uint8_t *data, ++ size_t len); + + /***************************************************************** + The above functions are common to the client and server interface +-- +2.23.0 + diff --git a/SOURCES/0093-crypto-Update-REQUIREMENTS-file-with-new-minimum-ver.patch b/SOURCES/0093-crypto-Update-REQUIREMENTS-file-with-new-minimum-ver.patch new file mode 100644 index 0000000..d002f49 --- /dev/null +++ b/SOURCES/0093-crypto-Update-REQUIREMENTS-file-with-new-minimum-ver.patch @@ -0,0 +1,30 @@ +From fb7713126043eaa2bffcf4b73d63fe371781cc1c Mon Sep 17 00:00:00 2001 +From: Andrew Bartlett +Date: Fri, 16 Aug 2019 13:52:36 +1200 +Subject: [PATCH 093/187] crypto: Update REQUIREMENTS file with new minimum + version + +Signed-off-by: Andrew Bartlett +Reviewed-by: Andreas Schneider +(cherry picked from commit 5ae119e7e9ddcfb3473e14585ba6079147a307bd) +--- + lib/crypto/REQUIREMENTS | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/lib/crypto/REQUIREMENTS b/lib/crypto/REQUIREMENTS +index ff91a2f9174..5ebf3ba0e05 100644 +--- a/lib/crypto/REQUIREMENTS ++++ b/lib/crypto/REQUIREMENTS +@@ -4,8 +4,7 @@ This list is to allow research into using external crypto libraries. + Those possibly supported in the git version of GnuTLS are indicated as '# GNUTLS' + Those possibly supported in the git version of nettle are indicated as '# NETTLE' + +-For Samba AD with Heimdal gnutls >= 3.0.0 is required +-For Samba AD with MIT kerberos gnutls >= 3.4.7 is required ++Samba in general gnutls >= 3.4.7 is required + Samba FS with MS Catalog support will require gnutls >= 3.5.6 + + GnuTLS Milestone for Samba support: +-- +2.23.0 + diff --git a/SOURCES/0094-libcli-auth-Check-NTSTATUS-from-netlogon_creds_aes_-.patch b/SOURCES/0094-libcli-auth-Check-NTSTATUS-from-netlogon_creds_aes_-.patch new file mode 100644 index 0000000..dc1b31d --- /dev/null +++ b/SOURCES/0094-libcli-auth-Check-NTSTATUS-from-netlogon_creds_aes_-.patch @@ -0,0 +1,134 @@ +From d054df5519b1a25d031f95e098c1f40d59083c3d Mon Sep 17 00:00:00 2001 +From: Andrew Bartlett +Date: Fri, 16 Aug 2019 13:55:49 +1200 +Subject: [PATCH 094/187] libcli:auth Check NTSTATUS from + netlogon_creds_aes_{en,de}crypt() + +Signed-off-by: Andrew Bartlett +Reviewed-by: Andreas Schneider +(cherry picked from commit d515b255aa67186ff375af0b465c49722eb56427) +--- + libcli/auth/credentials.c | 76 +++++++++++++++++++++++++++------------ + 1 file changed, 53 insertions(+), 23 deletions(-) + +diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c +index 955e08b7385..baa436df71b 100644 +--- a/libcli/auth/credentials.c ++++ b/libcli/auth/credentials.c +@@ -712,27 +712,36 @@ static NTSTATUS netlogon_creds_crypt_samlogon_validation(struct netlogon_creds_C + /* 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))) { + if (do_encrypt) { +- netlogon_creds_aes_encrypt(creds, +- base->key.key, +- sizeof(base->key.key)); ++ status = netlogon_creds_aes_encrypt( ++ creds, ++ base->key.key, ++ sizeof(base->key.key)); + } else { +- netlogon_creds_aes_decrypt(creds, +- base->key.key, +- sizeof(base->key.key)); ++ status = netlogon_creds_aes_decrypt( ++ 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))) { + if (do_encrypt) { +- netlogon_creds_aes_encrypt(creds, +- base->LMSessKey.key, +- sizeof(base->LMSessKey.key)); +- ++ status = netlogon_creds_aes_encrypt( ++ creds, ++ base->LMSessKey.key, ++ sizeof(base->LMSessKey.key)); + } else { +- netlogon_creds_aes_decrypt(creds, +- base->LMSessKey.key, +- sizeof(base->LMSessKey.key)); ++ status = netlogon_creds_aes_decrypt( ++ creds, ++ base->LMSessKey.key, ++ sizeof(base->LMSessKey.key)); ++ } ++ if (!NT_STATUS_IS_OK(status)) { ++ return status; + } + } + } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { +@@ -818,18 +827,34 @@ static NTSTATUS netlogon_creds_crypt_samlogon_logon(struct netlogon_creds_Creden + h = logon->password->lmpassword.hash; + if (!all_zero(h, 16)) { + if (do_encrypt) { +- netlogon_creds_aes_encrypt(creds, h, 16); ++ status = netlogon_creds_aes_encrypt( ++ creds, ++ h, ++ 16); + } else { +- netlogon_creds_aes_decrypt(creds, h, 16); ++ status = netlogon_creds_aes_decrypt( ++ creds, ++ h, ++ 16); ++ } ++ if (!NT_STATUS_IS_OK(status)) { ++ return status; + } + } + + h = logon->password->ntpassword.hash; + if (!all_zero(h, 16)) { + if (do_encrypt) { +- netlogon_creds_aes_encrypt(creds, h, 16); ++ status = netlogon_creds_aes_encrypt(creds, ++ h, ++ 16); + } else { +- netlogon_creds_aes_decrypt(creds, h, 16); ++ status = netlogon_creds_aes_decrypt(creds, ++ h, ++ 16); ++ } ++ if (!NT_STATUS_IS_OK(status)) { ++ return status; + } + } + } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { +@@ -887,13 +912,18 @@ static NTSTATUS netlogon_creds_crypt_samlogon_logon(struct netlogon_creds_Creden + + if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { + if (do_encrypt) { +- netlogon_creds_aes_encrypt(creds, +- logon->generic->data, +- logon->generic->length); ++ status = netlogon_creds_aes_encrypt( ++ creds, ++ logon->generic->data, ++ logon->generic->length); + } else { +- netlogon_creds_aes_decrypt(creds, +- logon->generic->data, +- logon->generic->length); ++ status = netlogon_creds_aes_decrypt( ++ creds, ++ logon->generic->data, ++ logon->generic->length); ++ } ++ if (!NT_STATUS_IS_OK(status)) { ++ return status; + } + } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { + status = netlogon_creds_arcfour_crypt(creds, +-- +2.23.0 + diff --git a/SOURCES/0095-s3-rpc_server-Check-NTSTATUS-return-value-from-netlo.patch b/SOURCES/0095-s3-rpc_server-Check-NTSTATUS-return-value-from-netlo.patch new file mode 100644 index 0000000..8b22567 --- /dev/null +++ b/SOURCES/0095-s3-rpc_server-Check-NTSTATUS-return-value-from-netlo.patch @@ -0,0 +1,41 @@ +From ca38586a27089b6bf8769b3701e8fc7ccd5f9215 Mon Sep 17 00:00:00 2001 +From: Andrew Bartlett +Date: Fri, 16 Aug 2019 14:05:38 +1200 +Subject: [PATCH 095/187] s3-rpc_server: Check NTSTATUS return value from + netlogon_creds_aes_decrypt() + +Signed-off-by: Andrew Bartlett +Reviewed-by: Andreas Schneider +(cherry picked from commit 2f827bec8ca831fb486c8ebedc6b89b7f1cb99e2) +--- + source3/rpc_server/netlogon/srv_netlog_nt.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c +index 08bce367bf0..671300676ff 100644 +--- a/source3/rpc_server/netlogon/srv_netlog_nt.c ++++ b/source3/rpc_server/netlogon/srv_netlog_nt.c +@@ -1369,14 +1369,16 @@ NTSTATUS _netr_ServerPasswordSet2(struct pipes_struct *p, + SIVAL(password_buf.data, 512, r->in.new_password->length); + + if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { +- netlogon_creds_aes_decrypt(creds, password_buf.data, 516); ++ status = netlogon_creds_aes_decrypt(creds, ++ password_buf.data, ++ 516); + } else { + status = netlogon_creds_arcfour_crypt(creds, + password_buf.data, + 516); +- if (!NT_STATUS_IS_OK(status)) { +- return status; +- } ++ } ++ if (!NT_STATUS_IS_OK(status)) { ++ return status; + } + + if (!decode_pw_buffer(p->mem_ctx, +-- +2.23.0 + diff --git a/SOURCES/0096-s4-rpc_server-Check-NTSTATUS-return-value-from-netlo.patch b/SOURCES/0096-s4-rpc_server-Check-NTSTATUS-return-value-from-netlo.patch new file mode 100644 index 0000000..a2dfae5 --- /dev/null +++ b/SOURCES/0096-s4-rpc_server-Check-NTSTATUS-return-value-from-netlo.patch @@ -0,0 +1,63 @@ +From 2558252a6fc918cfe5e9bdfc0d7b98a1324ab61b Mon Sep 17 00:00:00 2001 +From: Andrew Bartlett +Date: Fri, 16 Aug 2019 14:15:45 +1200 +Subject: [PATCH 096/187] s4-rpc_server: Check NTSTATUS return value from + netlogon_creds_aes_decrypt() + +Signed-off-by: Andrew Bartlett +Reviewed-by: Andreas Schneider +(cherry picked from commit 1e427f55d71350b25a8a26e94a5cb7895d8efdf6) +--- + source4/rpc_server/netlogon/dcerpc_netlogon.c | 21 ++++++++++++------- + 1 file changed, 13 insertions(+), 8 deletions(-) + +diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c +index ac745e32b02..49a075137ff 100644 +--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c ++++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c +@@ -747,14 +747,17 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_cal + SIVAL(password_buf.data, 512, r->in.new_password->length); + + if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { +- netlogon_creds_aes_decrypt(creds, password_buf.data, 516); ++ nt_status = netlogon_creds_aes_decrypt(creds, ++ password_buf.data, ++ 516); + } else { + nt_status = netlogon_creds_arcfour_crypt(creds, + password_buf.data, + 516); +- if (!NT_STATUS_IS_OK(nt_status)) { +- return nt_status; +- } ++ } ++ ++ if (!NT_STATUS_IS_OK(nt_status)) { ++ return nt_status; + } + + switch (creds->secure_channel_type) { +@@ -2803,14 +2806,16 @@ static NTSTATUS dcesrv_netr_NetrLogonSendToSam(struct dcesrv_call_state *dce_cal + + /* Buffer is meant to be 16-bit aligned */ + if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { +- netlogon_creds_aes_decrypt(creds, r->in.opaque_buffer, r->in.buffer_len); ++ nt_status = netlogon_creds_aes_decrypt(creds, ++ r->in.opaque_buffer, ++ r->in.buffer_len); + } else { + 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; +- } ++ } ++ if (!NT_STATUS_IS_OK(nt_status)) { ++ return nt_status; + } + + decrypted_blob.data = r->in.opaque_buffer; +-- +2.23.0 + diff --git a/SOURCES/0097-s3-librpc-Remove-unused-init_netr_CryptPassword.patch b/SOURCES/0097-s3-librpc-Remove-unused-init_netr_CryptPassword.patch new file mode 100644 index 0000000..f7fb55a --- /dev/null +++ b/SOURCES/0097-s3-librpc-Remove-unused-init_netr_CryptPassword.patch @@ -0,0 +1,148 @@ +From 5913cd056fae4d3a147326a30182a2d30bfe7857 Mon Sep 17 00:00:00 2001 +From: Andrew Bartlett +Date: Fri, 16 Aug 2019 14:22:42 +1200 +Subject: [PATCH 097/187] s3-librpc: Remove unused init_netr_CryptPassword() + +Unused since 38d4dba37406515181e4d6f1a1faffc18e652e27 in 2013 + +Signed-off-by: Andrew Bartlett +Reviewed-by: Andreas Schneider +(cherry picked from commit 1aa249e7f4a1c4222b4cc79bac64c8b95c89d868) +--- + source3/rpc_client/cli_netlogon.c | 1 - + source3/rpc_client/init_netlogon.c | 50 ------------------------------ + source3/rpc_client/init_netlogon.h | 29 ----------------- + source3/wscript_build | 5 --- + 4 files changed, 85 deletions(-) + delete mode 100644 source3/rpc_client/init_netlogon.c + delete mode 100644 source3/rpc_client/init_netlogon.h + +diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c +index 505a1d015bc..ea9cb757048 100644 +--- a/source3/rpc_client/cli_netlogon.c ++++ b/source3/rpc_client/cli_netlogon.c +@@ -30,7 +30,6 @@ + #include "../librpc/gen_ndr/ndr_netlogon_c.h" + #include "../librpc/gen_ndr/schannel.h" + #include "rpc_client/cli_netlogon.h" +-#include "rpc_client/init_netlogon.h" + #include "rpc_client/util_netlogon.h" + #include "../libcli/security/security.h" + #include "lib/param/param.h" +diff --git a/source3/rpc_client/init_netlogon.c b/source3/rpc_client/init_netlogon.c +deleted file mode 100644 +index 26deaba8065..00000000000 +--- a/source3/rpc_client/init_netlogon.c ++++ /dev/null +@@ -1,50 +0,0 @@ +-/* +- * Unix SMB/CIFS implementation. +- * RPC Pipe client / server routines +- * Copyright (C) Guenther Deschner 2008,2012 +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation; either version 3 of the License, or +- * (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, see . +- */ +- +-#include "includes.h" +-#include "../libcli/auth/libcli_auth.h" +-#include "../lib/crypto/crypto.h" +-#include "rpc_client/init_netlogon.h" +- +-/************************************************************************* +- inits a netr_CryptPassword structure +- *************************************************************************/ +- +-void init_netr_CryptPassword(const char *pwd, +- struct netlogon_creds_CredentialState *creds, +- 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 { +- 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); +-} +diff --git a/source3/rpc_client/init_netlogon.h b/source3/rpc_client/init_netlogon.h +deleted file mode 100644 +index bb4496b4cd9..00000000000 +--- a/source3/rpc_client/init_netlogon.h ++++ /dev/null +@@ -1,29 +0,0 @@ +-/* +- * Unix SMB/CIFS implementation. +- * RPC Pipe client / server routines +- * Copyright (C) Guenther Deschner 2008. +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation; either version 3 of the License, or +- * (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, see . +- */ +- +-#ifndef _RPC_CLIENT_INIT_NETLOGON_H_ +-#define _RPC_CLIENT_INIT_NETLOGON_H_ +- +-/* The following definitions come from rpc_client/init_netlogon.c */ +- +-void init_netr_CryptPassword(const char *pwd, +- struct netlogon_creds_CredentialState *creds, +- struct netr_CryptPassword *pwd_buf); +- +-#endif /* _RPC_CLIENT_INIT_NETLOGON_H_ */ +diff --git a/source3/wscript_build b/source3/wscript_build +index b73f6dc0664..ce3fa362bc2 100644 +--- a/source3/wscript_build ++++ b/source3/wscript_build +@@ -1024,7 +1024,6 @@ bld.SAMBA3_LIBRARY('libcli_netlogon3', + deps=''' + msrpc3 + RPC_NDR_NETLOGON +- INIT_NETLOGON + cliauth + smbconf + NETLOGON_CREDS_CLI''', +@@ -1057,10 +1056,6 @@ bld.SAMBA3_SUBSYSTEM('INIT_LSA', + source='rpc_client/init_lsa.c', + deps='samba-util') + +-bld.SAMBA3_SUBSYSTEM('INIT_NETLOGON', +- source='rpc_client/init_netlogon.c', +- deps='samba-util') +- + bld.SAMBA3_SUBSYSTEM('INIT_SAMR', + source='rpc_client/init_samr.c', + deps='samba-util GNUTLS_HELPERS') +-- +2.23.0 + diff --git a/SOURCES/0098-auth-credentials-Check-NTSTATUS-return-from-netlogon.patch b/SOURCES/0098-auth-credentials-Check-NTSTATUS-return-from-netlogon.patch new file mode 100644 index 0000000..fdd9693 --- /dev/null +++ b/SOURCES/0098-auth-credentials-Check-NTSTATUS-return-from-netlogon.patch @@ -0,0 +1,47 @@ +From cef95d8835a04065b9c7422a637f60efdb9a93fe Mon Sep 17 00:00:00 2001 +From: Andrew Bartlett +Date: Fri, 16 Aug 2019 14:29:45 +1200 +Subject: [PATCH 098/187] auth/credentials: Check NTSTATUS return from + netlogon_creds_aes_encrypt() + +Signed-off-by: Andrew Bartlett +Reviewed-by: Andreas Schneider +(cherry picked from commit fefd95091cc52f5e2655fa392312a8b1fa1d35fd) +--- + auth/credentials/credentials.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/auth/credentials/credentials.c b/auth/credentials/credentials.c +index 5ebec483705..81f9dbb9eb3 100644 +--- a/auth/credentials/credentials.c ++++ b/auth/credentials/credentials.c +@@ -1333,19 +1333,19 @@ _PUBLIC_ NTSTATUS netlogon_creds_session_encrypt( + return NT_STATUS_INVALID_PARAMETER; + } + if (state->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { +- netlogon_creds_aes_encrypt(state, +- data.data, +- data.length); ++ status = netlogon_creds_aes_encrypt(state, ++ data.data, ++ data.length); + } else if (state->negotiate_flags & NETLOGON_NEG_ARCFOUR) { + 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; ++ status = NT_STATUS_NOT_SUPPORTED; ++ } ++ if (!NT_STATUS_IS_OK(status)) { ++ return status; + } + return NT_STATUS_OK; + } +-- +2.23.0 + diff --git a/SOURCES/0099-auth-gensec-Use-GnuTLS-AES128-CFB8-in-netsec_do_seq_.patch b/SOURCES/0099-auth-gensec-Use-GnuTLS-AES128-CFB8-in-netsec_do_seq_.patch new file mode 100644 index 0000000..da56ce3 --- /dev/null +++ b/SOURCES/0099-auth-gensec-Use-GnuTLS-AES128-CFB8-in-netsec_do_seq_.patch @@ -0,0 +1,74 @@ +From 9be58c7b284bad6a721363354603a25a9aa4b29b Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Fri, 1 Mar 2019 17:55:02 +0100 +Subject: [PATCH 099/187] auth:gensec: Use GnuTLS AES128 CFB8 in + netsec_do_seq_num() + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 58c781dc93e24895b2c4b97fa311c66af30e278e) +--- + auth/gensec/schannel.c | 40 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 40 insertions(+) + +diff --git a/auth/gensec/schannel.c b/auth/gensec/schannel.c +index 74a3eb5c690..719849fa0cc 100644 +--- a/auth/gensec/schannel.c ++++ b/auth/gensec/schannel.c +@@ -147,6 +147,45 @@ static NTSTATUS netsec_do_seq_num(struct schannel_state *state, + uint8_t seq_num[8]) + { + if (state->creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { ++#ifdef HAVE_GNUTLS_AES_CFB8 ++ gnutls_cipher_hd_t cipher_hnd = NULL; ++ gnutls_datum_t key = { ++ .data = state->creds->session_key, ++ .size = sizeof(state->creds->session_key), ++ }; ++ uint32_t iv_size = ++ gnutls_cipher_get_iv_size(GNUTLS_CIPHER_AES_128_CFB8); ++ uint8_t _iv[iv_size]; ++ gnutls_datum_t iv = { ++ .data = _iv, ++ .size = iv_size, ++ }; ++ int rc; ++ ++ ZERO_ARRAY(_iv); ++ ++ memcpy(iv.data + 0, checksum, 8); ++ memcpy(iv.data + 8, checksum, 8); ++ ++ rc = gnutls_cipher_init(&cipher_hnd, ++ GNUTLS_CIPHER_AES_128_CFB8, ++ &key, ++ &iv); ++ if (rc < 0) { ++ DBG_ERR("ERROR: gnutls_cipher_init: %s\n", ++ gnutls_strerror(rc)); ++ return NT_STATUS_INTERNAL_ERROR; ++ } ++ ++ rc = gnutls_cipher_encrypt(cipher_hnd, seq_num, 8); ++ gnutls_cipher_deinit(cipher_hnd); ++ if (rc < 0) { ++ DBG_ERR("ERROR: gnutls_cipher_encrypt: %s\n", ++ gnutls_strerror(rc)); ++ return NT_STATUS_INTERNAL_ERROR; ++ } ++ ++#else /* NOT HAVE_GNUTLS_AES_CFB8 */ + AES_KEY key; + uint8_t iv[AES_BLOCK_SIZE]; + +@@ -156,6 +195,7 @@ static NTSTATUS netsec_do_seq_num(struct schannel_state *state, + memcpy(iv+8, checksum, 8); + + aes_cfb8_encrypt(seq_num, seq_num, 8, &key, iv, AES_ENCRYPT); ++#endif /* HAVE_GNUTLS_AES_CFB8 */ + } else { + static const uint8_t zeros[4]; + uint8_t _sequence_key[16]; +-- +2.23.0 + diff --git a/SOURCES/0100-auth-gensec-Use-gnutls_error_to_ntstatus-consistentl.patch b/SOURCES/0100-auth-gensec-Use-gnutls_error_to_ntstatus-consistentl.patch new file mode 100644 index 0000000..de1f97f --- /dev/null +++ b/SOURCES/0100-auth-gensec-Use-gnutls_error_to_ntstatus-consistentl.patch @@ -0,0 +1,69 @@ +From 1a04e7bc20749e262a61ce52c8173245af8fb69d Mon Sep 17 00:00:00 2001 +From: Andrew Bartlett +Date: Fri, 16 Aug 2019 15:43:01 +1200 +Subject: [PATCH 100/187] auth/gensec: Use gnutls_error_to_ntstatus() + consistently in schannel + +Signed-off-by: Andrew Bartlett +Reviewed-by: Andreas Schneider +(cherry picked from commit 3b27fd8a490f29cbc94b8ac377b3a2cb6db7598c) +--- + auth/gensec/schannel.c | 16 +++++++--------- + 1 file changed, 7 insertions(+), 9 deletions(-) + +diff --git a/auth/gensec/schannel.c b/auth/gensec/schannel.c +index 719849fa0cc..2a36d0cfa7d 100644 +--- a/auth/gensec/schannel.c ++++ b/auth/gensec/schannel.c +@@ -172,17 +172,15 @@ static NTSTATUS netsec_do_seq_num(struct schannel_state *state, + &key, + &iv); + if (rc < 0) { +- DBG_ERR("ERROR: gnutls_cipher_init: %s\n", +- gnutls_strerror(rc)); +- return NT_STATUS_INTERNAL_ERROR; ++ return gnutls_error_to_ntstatus(rc, ++ NT_STATUS_CRYPTO_SYSTEM_INVALID); + } + + rc = gnutls_cipher_encrypt(cipher_hnd, seq_num, 8); + gnutls_cipher_deinit(cipher_hnd); + if (rc < 0) { +- DBG_ERR("ERROR: gnutls_cipher_encrypt: %s\n", +- gnutls_strerror(rc)); +- return NT_STATUS_INTERNAL_ERROR; ++ return gnutls_error_to_ntstatus(rc, ++ NT_STATUS_CRYPTO_SYSTEM_INVALID); + } + + #else /* NOT HAVE_GNUTLS_AES_CFB8 */ +@@ -306,7 +304,7 @@ static NTSTATUS netsec_do_seal(struct schannel_state *state, + digest2); + if (rc < 0) { + ZERO_ARRAY(digest2); +- return NT_STATUS_INTERNAL_ERROR; ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_HMAC_NOT_SUPPORTED); + } + + rc = gnutls_hmac_fast(GNUTLS_MAC_MD5, +@@ -318,7 +316,7 @@ static NTSTATUS netsec_do_seal(struct schannel_state *state, + + ZERO_ARRAY(digest2); + if (rc < 0) { +- return NT_STATUS_INTERNAL_ERROR; ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_HMAC_NOT_SUPPORTED); + } + + rc = gnutls_cipher_init(&cipher_hnd, +@@ -377,7 +375,7 @@ static NTSTATUS netsec_do_sign(struct schannel_state *state, + state->creds->session_key, + sizeof(state->creds->session_key)); + if (rc < 0) { +- return NT_STATUS_NO_MEMORY; ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_HMAC_NOT_SUPPORTED); + } + + if (confounder) { +-- +2.23.0 + diff --git a/SOURCES/0101-auth-gensec-Use-GnuTLS-AES-CFB8-in-netsec_do_seal.patch b/SOURCES/0101-auth-gensec-Use-GnuTLS-AES-CFB8-in-netsec_do_seal.patch new file mode 100644 index 0000000..7dd8cd0 --- /dev/null +++ b/SOURCES/0101-auth-gensec-Use-GnuTLS-AES-CFB8-in-netsec_do_seal.patch @@ -0,0 +1,137 @@ +From a156d18abb509a48c45525da2f4e4db9cfdd1f30 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Mon, 18 Mar 2019 16:24:54 +0100 +Subject: [PATCH 101/187] auth:gensec: Use GnuTLS AES CFB8 in netsec_do_seal() + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 025f6a135f930264ddcf1cd1b9e1004464618194) +--- + auth/gensec/schannel.c | 95 +++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 94 insertions(+), 1 deletion(-) + +diff --git a/auth/gensec/schannel.c b/auth/gensec/schannel.c +index 2a36d0cfa7d..20b0a74e37f 100644 +--- a/auth/gensec/schannel.c ++++ b/auth/gensec/schannel.c +@@ -33,9 +33,12 @@ + #include "librpc/gen_ndr/dcerpc.h" + #include "param/param.h" + #include "auth/gensec/gensec_toplevel_proto.h" +-#include "lib/crypto/aes.h" + #include "libds/common/roles.h" + ++#ifndef HAVE_GNUTLS_AES_CFB8 ++#include "lib/crypto/aes.h" ++#endif ++ + #include "lib/crypto/gnutls_helpers.h" + #include + #include +@@ -258,6 +261,95 @@ static NTSTATUS netsec_do_seal(struct schannel_state *state, + bool forward) + { + if (state->creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { ++#ifdef HAVE_GNUTLS_AES_CFB8 ++ gnutls_cipher_hd_t cipher_hnd = NULL; ++ uint8_t sess_kf0[16] = {0}; ++ gnutls_datum_t key = { ++ .data = sess_kf0, ++ .size = sizeof(sess_kf0), ++ }; ++ uint32_t iv_size = ++ gnutls_cipher_get_iv_size(GNUTLS_CIPHER_AES_128_CFB8); ++ uint8_t _iv[iv_size]; ++ gnutls_datum_t iv = { ++ .data = _iv, ++ .size = iv_size, ++ }; ++ uint32_t i; ++ int rc; ++ ++ for (i = 0; i < key.size; i++) { ++ key.data[i] = state->creds->session_key[i] ^ 0xf0; ++ } ++ ++ ZERO_ARRAY(_iv); ++ ++ memcpy(iv.data + 0, seq_num, 8); ++ memcpy(iv.data + 8, seq_num, 8); ++ ++ rc = gnutls_cipher_init(&cipher_hnd, ++ GNUTLS_CIPHER_AES_128_CFB8, ++ &key, ++ &iv); ++ if (rc < 0) { ++ DBG_ERR("ERROR: gnutls_cipher_init: %s\n", ++ gnutls_strerror(rc)); ++ return NT_STATUS_NO_MEMORY; ++ } ++ ++ if (forward) { ++ rc = gnutls_cipher_encrypt(cipher_hnd, ++ confounder, ++ 8); ++ if (rc < 0) { ++ DBG_ERR("ERROR: gnutls_cipher_encrypt: %s\n", ++ gnutls_strerror(errno)); ++ gnutls_cipher_deinit(cipher_hnd); ++ return NT_STATUS_INTERNAL_ERROR; ++ } ++ ++ /* ++ * Looks like we have to reuse the initial IV which is ++ * cryptographically wrong! ++ */ ++ gnutls_cipher_set_iv(cipher_hnd, iv.data, iv.size); ++ rc = gnutls_cipher_encrypt(cipher_hnd, ++ data, ++ length); ++ if (rc < 0) { ++ DBG_ERR("ERROR: gnutls_cipher_encrypt: %s\n", ++ gnutls_strerror(errno)); ++ gnutls_cipher_deinit(cipher_hnd); ++ return NT_STATUS_INTERNAL_ERROR; ++ } ++ } else { ++ rc = gnutls_cipher_decrypt(cipher_hnd, ++ confounder, ++ 8); ++ if (rc < 0) { ++ DBG_ERR("ERROR: gnutls_cipher_decrypt: %s\n", ++ gnutls_strerror(errno)); ++ gnutls_cipher_deinit(cipher_hnd); ++ return NT_STATUS_INTERNAL_ERROR; ++ } ++ ++ /* ++ * Looks like we have to reuse the initial IV which is ++ * cryptographically wrong! ++ */ ++ gnutls_cipher_set_iv(cipher_hnd, iv.data, iv.size); ++ rc = gnutls_cipher_decrypt(cipher_hnd, ++ data, ++ length); ++ if (rc < 0) { ++ DBG_ERR("ERROR: gnutls_cipher_decrypt: %s\n", ++ gnutls_strerror(errno)); ++ gnutls_cipher_deinit(cipher_hnd); ++ return NT_STATUS_INTERNAL_ERROR; ++ } ++ } ++ gnutls_cipher_deinit(cipher_hnd); ++#else /* NOT HAVE_GNUTLS_AES_CFB8 */ + AES_KEY key; + uint8_t iv[AES_BLOCK_SIZE]; + uint8_t sess_kf0[16]; +@@ -279,6 +371,7 @@ static NTSTATUS netsec_do_seal(struct schannel_state *state, + aes_cfb8_encrypt(confounder, confounder, 8, &key, iv, AES_DECRYPT); + aes_cfb8_encrypt(data, data, length, &key, iv, AES_DECRYPT); + } ++#endif /* HAVE_GNUTLS_AES_CFB8 */ + } else { + gnutls_cipher_hd_t cipher_hnd; + uint8_t _sealing_key[16]; +-- +2.23.0 + diff --git a/SOURCES/0102-auth-gensec-Use-gnutls_error_to_ntstatus-in-netsec_d.patch b/SOURCES/0102-auth-gensec-Use-gnutls_error_to_ntstatus-in-netsec_d.patch new file mode 100644 index 0000000..c3d1f4a --- /dev/null +++ b/SOURCES/0102-auth-gensec-Use-gnutls_error_to_ntstatus-in-netsec_d.patch @@ -0,0 +1,67 @@ +From 8fc821bcdc457b9f22726eb6a83f5a3a08213040 Mon Sep 17 00:00:00 2001 +From: Andrew Bartlett +Date: Fri, 16 Aug 2019 15:45:43 +1200 +Subject: [PATCH 102/187] auth/gensec: Use gnutls_error_to_ntstatus() in + netsec_do_seal() + +Signed-off-by: Andrew Bartlett +Reviewed-by: Andreas Schneider +(cherry picked from commit fa8eddc39b4ea9d316201019b603025df5c2fa5e) +--- + auth/gensec/schannel.c | 16 ++++------------ + 1 file changed, 4 insertions(+), 12 deletions(-) + +diff --git a/auth/gensec/schannel.c b/auth/gensec/schannel.c +index 20b0a74e37f..b5e6289ef3f 100644 +--- a/auth/gensec/schannel.c ++++ b/auth/gensec/schannel.c +@@ -302,10 +302,8 @@ static NTSTATUS netsec_do_seal(struct schannel_state *state, + confounder, + 8); + if (rc < 0) { +- DBG_ERR("ERROR: gnutls_cipher_encrypt: %s\n", +- gnutls_strerror(errno)); + gnutls_cipher_deinit(cipher_hnd); +- return NT_STATUS_INTERNAL_ERROR; ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); + } + + /* +@@ -317,20 +315,16 @@ static NTSTATUS netsec_do_seal(struct schannel_state *state, + data, + length); + if (rc < 0) { +- DBG_ERR("ERROR: gnutls_cipher_encrypt: %s\n", +- gnutls_strerror(errno)); + gnutls_cipher_deinit(cipher_hnd); +- return NT_STATUS_INTERNAL_ERROR; ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); + } + } else { + rc = gnutls_cipher_decrypt(cipher_hnd, + confounder, + 8); + if (rc < 0) { +- DBG_ERR("ERROR: gnutls_cipher_decrypt: %s\n", +- gnutls_strerror(errno)); + gnutls_cipher_deinit(cipher_hnd); +- return NT_STATUS_INTERNAL_ERROR; ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); + } + + /* +@@ -342,10 +336,8 @@ static NTSTATUS netsec_do_seal(struct schannel_state *state, + data, + length); + if (rc < 0) { +- DBG_ERR("ERROR: gnutls_cipher_decrypt: %s\n", +- gnutls_strerror(errno)); + gnutls_cipher_deinit(cipher_hnd); +- return NT_STATUS_INTERNAL_ERROR; ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); + } + } + gnutls_cipher_deinit(cipher_hnd); +-- +2.23.0 + diff --git a/SOURCES/0103-lib-crypto-Prepare-not-to-build-AES-or-AES-CMAC-if-w.patch b/SOURCES/0103-lib-crypto-Prepare-not-to-build-AES-or-AES-CMAC-if-w.patch new file mode 100644 index 0000000..aaaaca8 --- /dev/null +++ b/SOURCES/0103-lib-crypto-Prepare-not-to-build-AES-or-AES-CMAC-if-w.patch @@ -0,0 +1,111 @@ +From e2d47f1a730131017b7d4d71713a174da6cb270c Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Fri, 15 Mar 2019 14:54:13 +0100 +Subject: [PATCH 103/187] lib:crypto: Prepare not to build AES or AES-CMAC if + we use GnuTLS support it + +Samba will soon require GnuTLS >= 3.4.7. + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett + +Adjusted by Andrew Bartlett from an earlier more comprehensive patch by Andreas + +Signed-off-by: Andrew Bartlett +(cherry picked from commit 1f6104f09a30cf3816fd5a580ce1b4be5b94848c) +--- + lib/crypto/wscript_build | 52 ++++++++++++++++++++++++++++------- + source4/torture/local/local.c | 3 ++ + 2 files changed, 45 insertions(+), 10 deletions(-) + +diff --git a/lib/crypto/wscript_build b/lib/crypto/wscript_build +index a26c10b627b..9a7c715754d 100644 +--- a/lib/crypto/wscript_build ++++ b/lib/crypto/wscript_build +@@ -20,27 +20,59 @@ bld.SAMBA_SUBSYSTEM('LIBCRYPTO_RC4', + deps='talloc', + enabled=not bld.CONFIG_SET('HAVE_GNUTLS_3_4_7')) + ++bld.SAMBA_SUBSYSTEM('LIBCRYPTO_AES_CCM', ++ source='aes_ccm_128.c', ++ deps='talloc') ++ ++bld.SAMBA_SUBSYSTEM('LIBCRYPTO_AES_GCM', ++ source='aes_gcm_128.c', ++ deps='talloc') ++ ++bld.SAMBA_SUBSYSTEM('LIBCRYPTO_AES', ++ source='aes.c rijndael-alg-fst.c', ++ deps='talloc') ++ ++bld.SAMBA_SUBSYSTEM('LIBCRYPTO_AES_CMAC', ++ source='aes_cmac_128.c', ++ deps='talloc') ++ + bld.SAMBA_SUBSYSTEM('LIBCRYPTO', + source=''' + md4.c +- aes.c +- rijndael-alg-fst.c +- aes_cmac_128.c +- aes_ccm_128.c +- aes_gcm_128.c + ''', + deps=''' + talloc + LIBCRYPTO_RC4 ++ LIBCRYPTO_AES ++ LIBCRYPTO_AES_CCM ++ LIBCRYPTO_AES_GCM ++ LIBCRYPTO_AES_CMAC + ''' + extra_deps) + ++bld.SAMBA_SUBSYSTEM('TORTURE_LIBCRYPTO_AES_CCM', ++ source='aes_ccm_128_test.c', ++ autoproto='aes_ccm_test_proto.h', ++ deps='talloc') ++ ++bld.SAMBA_SUBSYSTEM('TORTURE_LIBCRYPTO_AES_GCM', ++ source='aes_gcm_128_test.c', ++ autoproto='aes_gcm_test_proto.h', ++ deps='talloc') ++ ++bld.SAMBA_SUBSYSTEM('TORTURE_LIBCRYPTO_AES_CMAC', ++ source='aes_cmac_128_test.c', ++ autoproto='aes_cmac_test_proto.h', ++ deps='talloc') ++ + bld.SAMBA_SUBSYSTEM('TORTURE_LIBCRYPTO', +- source='''md4test.c +- aes_cmac_128_test.c aes_ccm_128_test.c aes_gcm_128_test.c +- ''', ++ source='md4test.c', + autoproto='test_proto.h', +- deps='LIBCRYPTO' +- ) ++ deps=''' ++ LIBCRYPTO ++ TORTURE_LIBCRYPTO_AES_CCM ++ TORTURE_LIBCRYPTO_AES_GCM ++ TORTURE_LIBCRYPTO_AES_CMAC ++ ''') + + bld.SAMBA_PYTHON('python_crypto', + source='py_crypto.c', +diff --git a/source4/torture/local/local.c b/source4/torture/local/local.c +index acd88772ab7..fa4061c108b 100644 +--- a/source4/torture/local/local.c ++++ b/source4/torture/local/local.c +@@ -23,6 +23,9 @@ + #include "torture/ndr/proto.h" + #include "torture/auth/proto.h" + #include "../lib/crypto/test_proto.h" ++#include "../lib/crypto/aes_ccm_test_proto.h" ++#include "../lib/crypto/aes_gcm_test_proto.h" ++#include "../lib/crypto/aes_cmac_test_proto.h" + #include "lib/registry/tests/proto.h" + #include "lib/replace/replace-testsuite.h" + +-- +2.23.0 + diff --git a/SOURCES/0104-build-Set-minimum-GnuTLS-version-at-3.4.7.patch b/SOURCES/0104-build-Set-minimum-GnuTLS-version-at-3.4.7.patch new file mode 100644 index 0000000..acf8bab --- /dev/null +++ b/SOURCES/0104-build-Set-minimum-GnuTLS-version-at-3.4.7.patch @@ -0,0 +1,48 @@ +From 50d864024d5f165e3a649371c811cefd695fc2db Mon Sep 17 00:00:00 2001 +From: Andrew Bartlett +Date: Thu, 15 Aug 2019 14:25:41 +1200 +Subject: [PATCH 104/187] build: Set minimum GnuTLS version at 3.4.7 + +This will soon be required for encrypted_secrets in the AD DC, the BackupKey server +and SMB2 as we remove use of the internal AES code. + +Signed-off-by: Andrew Bartlett +Reviewed-by: Andreas Schneider +(cherry picked from commit 974cebdf953259f41ecfc7375bc31d72af53f51e) +--- + wscript_configure_system_gnutls | 11 +---------- + 1 file changed, 1 insertion(+), 10 deletions(-) + +diff --git a/wscript_configure_system_gnutls b/wscript_configure_system_gnutls +index 85824aad4ed..8ff0529e10c 100644 +--- a/wscript_configure_system_gnutls ++++ b/wscript_configure_system_gnutls +@@ -1,17 +1,9 @@ + from waflib import Options + +-gnutls_min_required_version = "3.2.0" ++gnutls_min_required_version = "3.4.7" + + gnutls_required_version = gnutls_min_required_version + +-# +-# If we build with MIT Kerberos we need at least GnuTLS 3.4.7 for the backupkey +-# protocol. +-# +-if Options.options.with_system_mitkrb5 and conf.env.AD_DC_BUILD_IS_ENABLED: +- gnutls_required_version = "3.4.7" +- conf.DEFINE('HAVE_GNUTLS_3_4_7', 1) +- + conf.CHECK_CFG(package='gnutls', + args=('"gnutls >= %s" --cflags --libs' % gnutls_required_version), + msg='Checking for GnuTLS >= %s' % gnutls_required_version, +@@ -39,6 +31,5 @@ else: + + if conf.CHECK_VALUEOF('GNUTLS_CIPHER_AES_128_CFB8', headers='gnutls/gnutls.h'): + conf.DEFINE('HAVE_GNUTLS_AES_CFB8', 1) +- conf.DEFINE('HAVE_GNUTLS_3_4_7', 1) + else: + Logs.warn('No gnutls support for AES CFB8') +-- +2.23.0 + diff --git a/SOURCES/0105-s4-rpc_server-Remove-Heimdal-based-BackupKey-server.patch b/SOURCES/0105-s4-rpc_server-Remove-Heimdal-based-BackupKey-server.patch new file mode 100644 index 0000000..eafa3a6 --- /dev/null +++ b/SOURCES/0105-s4-rpc_server-Remove-Heimdal-based-BackupKey-server.patch @@ -0,0 +1,4135 @@ +From dc3c16cd089f6d245afc84aa0560f76346d5e4fe Mon Sep 17 00:00:00 2001 +From: Andrew Bartlett +Date: Wed, 31 Jul 2019 16:13:38 +1200 +Subject: [PATCH 105/187] s4-rpc_server: Remove Heimdal-based BackupKey server + +We rely on a modern GnuTLS now. + +Signed-off-by: Andrew Bartlett +Reviewed-by: Andreas Schneider +(backported from commit 52b91cb33c281aeecc6270824cadac6cefbcb136) +--- + .../backupkey/dcesrv_backupkey_heimdal.c | 1861 -------------- + source4/rpc_server/wscript_build | 24 +- + source4/torture/rpc/backupkey_heimdal.c | 2160 ----------------- + source4/torture/wscript_build | 9 +- + wscript_configure_system_gnutls | 6 - + 5 files changed, 8 insertions(+), 4052 deletions(-) + delete mode 100644 source4/rpc_server/backupkey/dcesrv_backupkey_heimdal.c + delete mode 100644 source4/torture/rpc/backupkey_heimdal.c + +diff --git a/source4/rpc_server/backupkey/dcesrv_backupkey_heimdal.c b/source4/rpc_server/backupkey/dcesrv_backupkey_heimdal.c +deleted file mode 100644 +index 806f144a24b..00000000000 +--- a/source4/rpc_server/backupkey/dcesrv_backupkey_heimdal.c ++++ /dev/null +@@ -1,1861 +0,0 @@ +-/* +- Unix SMB/CIFS implementation. +- +- endpoint server for the backupkey interface +- +- Copyright (C) Matthieu Patou 2010 +- +- This program is free software; you can redistribute it and/or modify +- it under the terms of the GNU General Public License as published by +- the Free Software Foundation; either version 3 of the License, or +- (at your option) any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- GNU General Public License for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program. If not, see . +-*/ +- +-#include "includes.h" +-#include "rpc_server/dcerpc_server.h" +-#include "rpc_server/common/common.h" +-#include "librpc/gen_ndr/ndr_backupkey.h" +-#include "dsdb/common/util.h" +-#include "dsdb/samdb/samdb.h" +-#include "lib/ldb/include/ldb_errors.h" +-#include "../lib/util/util_ldb.h" +-#include "param/param.h" +-#include "auth/session.h" +-#include "system/network.h" +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include "../lib/tsocket/tsocket.h" +-#include "../libcli/security/security.h" +-#include "librpc/gen_ndr/ndr_security.h" +-#include "lib/crypto/arcfour.h" +-#include "libds/common/roles.h" +-#include +-#include +- +-#define DCESRV_INTERFACE_BACKUPKEY_BIND(context, iface) \ +- dcesrv_interface_backupkey_bind(context, iface) +-static NTSTATUS dcesrv_interface_backupkey_bind(struct dcesrv_connection_context *context, +- const struct dcesrv_interface *iface) +-{ +- return dcesrv_interface_bind_require_privacy(context, iface); +-} +- +-static const unsigned rsa_with_var_num[] = { 1, 2, 840, 113549, 1, 1, 1 }; +-/* Equivalent to asn1_oid_id_pkcs1_rsaEncryption*/ +-static const AlgorithmIdentifier _hx509_signature_rsa_with_var_num = { +- { 7, discard_const_p(unsigned, rsa_with_var_num) }, NULL +-}; +- +-static NTSTATUS set_lsa_secret(TALLOC_CTX *mem_ctx, +- struct ldb_context *ldb, +- const char *name, +- const DATA_BLOB *lsa_secret) +-{ +- struct ldb_message *msg; +- struct ldb_result *res; +- struct ldb_dn *domain_dn; +- struct ldb_dn *system_dn; +- struct ldb_val val; +- int ret; +- char *name2; +- struct timeval now = timeval_current(); +- NTTIME nt_now = timeval_to_nttime(&now); +- const char *attrs[] = { +- NULL +- }; +- +- domain_dn = ldb_get_default_basedn(ldb); +- if (!domain_dn) { +- return NT_STATUS_INTERNAL_ERROR; +- } +- +- msg = ldb_msg_new(mem_ctx); +- if (msg == NULL) { +- return NT_STATUS_NO_MEMORY; +- } +- +- /* +- * This function is a lot like dcesrv_lsa_CreateSecret +- * in the rpc_server/lsa directory +- * The reason why we duplicate the effort here is that: +- * * we want to keep the former function static +- * * we want to avoid the burden of doing LSA calls +- * when we can just manipulate the secrets directly +- * * taillor the function to the particular needs of backup protocol +- */ +- +- system_dn = samdb_search_dn(ldb, msg, domain_dn, "(&(objectClass=container)(cn=System))"); +- if (system_dn == NULL) { +- talloc_free(msg); +- return NT_STATUS_NO_MEMORY; +- } +- +- name2 = talloc_asprintf(msg, "%s Secret", name); +- if (name2 == NULL) { +- talloc_free(msg); +- return NT_STATUS_NO_MEMORY; +- } +- +- ret = ldb_search(ldb, mem_ctx, &res, system_dn, LDB_SCOPE_SUBTREE, attrs, +- "(&(cn=%s)(objectclass=secret))", +- ldb_binary_encode_string(mem_ctx, name2)); +- +- if (ret != LDB_SUCCESS || res->count != 0 ) { +- DEBUG(2, ("Secret %s already exists !\n", name2)); +- talloc_free(msg); +- return NT_STATUS_OBJECT_NAME_COLLISION; +- } +- +- /* +- * We don't care about previous value as we are +- * here only if the key didn't exists before +- */ +- +- msg->dn = ldb_dn_copy(mem_ctx, system_dn); +- if (msg->dn == NULL) { +- talloc_free(msg); +- return NT_STATUS_NO_MEMORY; +- } +- if (!ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) { +- talloc_free(msg); +- return NT_STATUS_NO_MEMORY; +- } +- +- ret = ldb_msg_add_string(msg, "cn", name2); +- if (ret != LDB_SUCCESS) { +- talloc_free(msg); +- return NT_STATUS_NO_MEMORY; +- } +- ret = ldb_msg_add_string(msg, "objectClass", "secret"); +- if (ret != LDB_SUCCESS) { +- talloc_free(msg); +- return NT_STATUS_NO_MEMORY; +- } +- ret = samdb_msg_add_uint64(ldb, mem_ctx, msg, "priorSetTime", nt_now); +- if (ret != LDB_SUCCESS) { +- talloc_free(msg); +- return NT_STATUS_NO_MEMORY; +- } +- val.data = lsa_secret->data; +- val.length = lsa_secret->length; +- ret = ldb_msg_add_value(msg, "currentValue", &val, NULL); +- if (ret != LDB_SUCCESS) { +- talloc_free(msg); +- return NT_STATUS_NO_MEMORY; +- } +- ret = samdb_msg_add_uint64(ldb, mem_ctx, msg, "lastSetTime", nt_now); +- if (ret != LDB_SUCCESS) { +- talloc_free(msg); +- return NT_STATUS_NO_MEMORY; +- } +- +- /* +- * create the secret with DSDB_MODIFY_RELAX +- * otherwise dsdb/samdb/ldb_modules/objectclass.c forbid +- * the create of LSA secret object +- */ +- ret = dsdb_add(ldb, msg, DSDB_MODIFY_RELAX); +- if (ret != LDB_SUCCESS) { +- DEBUG(2,("Failed to create secret record %s: %s\n", +- ldb_dn_get_linearized(msg->dn), +- ldb_errstring(ldb))); +- talloc_free(msg); +- return NT_STATUS_ACCESS_DENIED; +- } +- +- talloc_free(msg); +- return NT_STATUS_OK; +-} +- +-/* This function is pretty much like dcesrv_lsa_QuerySecret */ +-static NTSTATUS get_lsa_secret(TALLOC_CTX *mem_ctx, +- struct ldb_context *ldb, +- const char *name, +- DATA_BLOB *lsa_secret) +-{ +- TALLOC_CTX *tmp_mem; +- struct ldb_result *res; +- struct ldb_dn *domain_dn; +- struct ldb_dn *system_dn; +- const struct ldb_val *val; +- uint8_t *data; +- const char *attrs[] = { +- "currentValue", +- NULL +- }; +- int ret; +- +- lsa_secret->data = NULL; +- lsa_secret->length = 0; +- +- domain_dn = ldb_get_default_basedn(ldb); +- if (!domain_dn) { +- return NT_STATUS_INTERNAL_ERROR; +- } +- +- tmp_mem = talloc_new(mem_ctx); +- if (tmp_mem == NULL) { +- return NT_STATUS_NO_MEMORY; +- } +- +- system_dn = samdb_search_dn(ldb, tmp_mem, domain_dn, "(&(objectClass=container)(cn=System))"); +- if (system_dn == NULL) { +- talloc_free(tmp_mem); +- return NT_STATUS_NO_MEMORY; +- } +- +- ret = ldb_search(ldb, mem_ctx, &res, system_dn, LDB_SCOPE_SUBTREE, attrs, +- "(&(cn=%s Secret)(objectclass=secret))", +- ldb_binary_encode_string(tmp_mem, name)); +- +- if (ret != LDB_SUCCESS) { +- talloc_free(tmp_mem); +- return NT_STATUS_INTERNAL_DB_CORRUPTION; +- } +- if (res->count == 0) { +- talloc_free(tmp_mem); +- return NT_STATUS_RESOURCE_NAME_NOT_FOUND; +- } +- if (res->count > 1) { +- DEBUG(2, ("Secret %s collision\n", name)); +- talloc_free(tmp_mem); +- return NT_STATUS_INTERNAL_DB_CORRUPTION; +- } +- +- val = ldb_msg_find_ldb_val(res->msgs[0], "currentValue"); +- if (val == NULL) { +- /* +- * The secret object is here but we don't have the secret value +- * The most common case is a RODC +- */ +- *lsa_secret = data_blob_null; +- talloc_free(tmp_mem); +- return NT_STATUS_OK; +- } +- +- data = val->data; +- lsa_secret->data = talloc_move(mem_ctx, &data); +- lsa_secret->length = val->length; +- +- talloc_free(tmp_mem); +- return NT_STATUS_OK; +-} +- +-static DATA_BLOB *reverse_and_get_blob(TALLOC_CTX *mem_ctx, BIGNUM *bn) +-{ +- DATA_BLOB blob; +- DATA_BLOB *rev = talloc(mem_ctx, DATA_BLOB); +- uint32_t i; +- +- blob.length = BN_num_bytes(bn); +- blob.data = talloc_array(mem_ctx, uint8_t, blob.length); +- +- if (blob.data == NULL) { +- return NULL; +- } +- +- BN_bn2bin(bn, blob.data); +- +- rev->data = talloc_array(mem_ctx, uint8_t, blob.length); +- if (rev->data == NULL) { +- return NULL; +- } +- +- for(i=0; i < blob.length; i++) { +- rev->data[i] = blob.data[blob.length - i -1]; +- } +- rev->length = blob.length; +- talloc_free(blob.data); +- return rev; +-} +- +-static BIGNUM *reverse_and_get_bignum(TALLOC_CTX *mem_ctx, DATA_BLOB *blob) +-{ +- BIGNUM *ret; +- DATA_BLOB rev; +- uint32_t i; +- +- rev.data = talloc_array(mem_ctx, uint8_t, blob->length); +- if (rev.data == NULL) { +- return NULL; +- } +- +- for(i=0; i < blob->length; i++) { +- rev.data[i] = blob->data[blob->length - i -1]; +- } +- rev.length = blob->length; +- +- ret = BN_bin2bn(rev.data, rev.length, NULL); +- talloc_free(rev.data); +- +- return ret; +-} +- +-static NTSTATUS get_pk_from_raw_keypair_params(TALLOC_CTX *ctx, +- struct bkrp_exported_RSA_key_pair *keypair, +- hx509_private_key *pk) +-{ +- hx509_context hctx; +- RSA *rsa; +- struct hx509_private_key_ops *ops; +- hx509_private_key privkey = NULL; +- +- hx509_context_init(&hctx); +- ops = hx509_find_private_alg(&_hx509_signature_rsa_with_var_num.algorithm); +- if (ops == NULL) { +- DEBUG(2, ("Not supported algorithm\n")); +- hx509_context_free(&hctx); +- return NT_STATUS_INTERNAL_ERROR; +- } +- +- if (hx509_private_key_init(&privkey, ops, NULL) != 0) { +- hx509_context_free(&hctx); +- return NT_STATUS_NO_MEMORY; +- } +- +- rsa = RSA_new(); +- if (rsa ==NULL) { +- hx509_private_key_free(&privkey); +- hx509_context_free(&hctx); +- return NT_STATUS_INVALID_PARAMETER; +- } +- +- rsa->n = reverse_and_get_bignum(ctx, &(keypair->modulus)); +- if (rsa->n == NULL) { +- RSA_free(rsa); +- hx509_private_key_free(&privkey); +- hx509_context_free(&hctx); +- return NT_STATUS_INVALID_PARAMETER; +- } +- rsa->d = reverse_and_get_bignum(ctx, &(keypair->private_exponent)); +- if (rsa->d == NULL) { +- RSA_free(rsa); +- hx509_private_key_free(&privkey); +- hx509_context_free(&hctx); +- return NT_STATUS_INVALID_PARAMETER; +- } +- rsa->p = reverse_and_get_bignum(ctx, &(keypair->prime1)); +- if (rsa->p == NULL) { +- RSA_free(rsa); +- hx509_private_key_free(&privkey); +- hx509_context_free(&hctx); +- return NT_STATUS_INVALID_PARAMETER; +- } +- rsa->q = reverse_and_get_bignum(ctx, &(keypair->prime2)); +- if (rsa->q == NULL) { +- RSA_free(rsa); +- hx509_private_key_free(&privkey); +- hx509_context_free(&hctx); +- return NT_STATUS_INVALID_PARAMETER; +- } +- rsa->dmp1 = reverse_and_get_bignum(ctx, &(keypair->exponent1)); +- if (rsa->dmp1 == NULL) { +- RSA_free(rsa); +- hx509_private_key_free(&privkey); +- hx509_context_free(&hctx); +- return NT_STATUS_INVALID_PARAMETER; +- } +- rsa->dmq1 = reverse_and_get_bignum(ctx, &(keypair->exponent2)); +- if (rsa->dmq1 == NULL) { +- RSA_free(rsa); +- hx509_private_key_free(&privkey); +- hx509_context_free(&hctx); +- return NT_STATUS_INVALID_PARAMETER; +- } +- rsa->iqmp = reverse_and_get_bignum(ctx, &(keypair->coefficient)); +- if (rsa->iqmp == NULL) { +- RSA_free(rsa); +- hx509_private_key_free(&privkey); +- hx509_context_free(&hctx); +- return NT_STATUS_INVALID_PARAMETER; +- } +- rsa->e = reverse_and_get_bignum(ctx, &(keypair->public_exponent)); +- if (rsa->e == NULL) { +- RSA_free(rsa); +- hx509_private_key_free(&privkey); +- hx509_context_free(&hctx); +- return NT_STATUS_INVALID_PARAMETER; +- } +- +- *pk = privkey; +- +- hx509_private_key_assign_rsa(*pk, rsa); +- +- hx509_context_free(&hctx); +- return NT_STATUS_OK; +-} +- +-static WERROR get_and_verify_access_check(TALLOC_CTX *sub_ctx, +- uint32_t version, +- uint8_t *key_and_iv, +- uint8_t *access_check, +- uint32_t access_check_len, +- struct auth_session_info *session_info) +-{ +- heim_octet_string iv; +- heim_octet_string access_check_os; +- hx509_crypto crypto; +- +- DATA_BLOB blob_us; +- uint32_t key_len; +- uint32_t iv_len; +- int res; +- enum ndr_err_code ndr_err; +- hx509_context hctx; +- +- struct dom_sid *access_sid = NULL; +- struct dom_sid *caller_sid = NULL; +- +- /* This one should not be freed */ +- const AlgorithmIdentifier *alg; +- +- switch (version) { +- case 2: +- key_len = 24; +- iv_len = 8; +- alg = hx509_crypto_des_rsdi_ede3_cbc(); +- break; +- +- case 3: +- key_len = 32; +- iv_len = 16; +- alg =hx509_crypto_aes256_cbc(); +- break; +- +- default: +- return WERR_INVALID_DATA; +- } +- +- hx509_context_init(&hctx); +- res = hx509_crypto_init(hctx, NULL, +- &(alg->algorithm), +- &crypto); +- hx509_context_free(&hctx); +- +- if (res != 0) { +- return WERR_INVALID_DATA; +- } +- +- res = hx509_crypto_set_key_data(crypto, key_and_iv, key_len); +- +- iv.data = talloc_memdup(sub_ctx, key_len + key_and_iv, iv_len); +- iv.length = iv_len; +- +- if (res != 0) { +- hx509_crypto_destroy(crypto); +- return WERR_INVALID_DATA; +- } +- +- hx509_crypto_set_padding(crypto, HX509_CRYPTO_PADDING_NONE); +- res = hx509_crypto_decrypt(crypto, +- access_check, +- access_check_len, +- &iv, +- &access_check_os); +- +- if (res != 0) { +- hx509_crypto_destroy(crypto); +- return WERR_INVALID_DATA; +- } +- +- blob_us.data = access_check_os.data; +- blob_us.length = access_check_os.length; +- +- hx509_crypto_destroy(crypto); +- +- switch (version) { +- case 2: +- { +- uint32_t hash_size = 20; +- uint8_t hash[hash_size]; +- struct sha sctx; +- struct bkrp_access_check_v2 uncrypted_accesscheckv2; +- +- ndr_err = ndr_pull_struct_blob(&blob_us, sub_ctx, &uncrypted_accesscheckv2, +- (ndr_pull_flags_fn_t)ndr_pull_bkrp_access_check_v2); +- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { +- /* Unable to unmarshall */ +- der_free_octet_string(&access_check_os); +- return WERR_INVALID_DATA; +- } +- if (uncrypted_accesscheckv2.magic != 0x1) { +- /* wrong magic */ +- der_free_octet_string(&access_check_os); +- return WERR_INVALID_DATA; +- } +- +- SHA1_Init(&sctx); +- SHA1_Update(&sctx, blob_us.data, blob_us.length - hash_size); +- SHA1_Final(hash, &sctx); +- der_free_octet_string(&access_check_os); +- /* +- * We free it after the sha1 calculation because blob.data +- * point to the same area +- */ +- +- if (memcmp(hash, uncrypted_accesscheckv2.hash, hash_size) != 0) { +- DEBUG(2, ("Wrong hash value in the access check in backup key remote protocol\n")); +- return WERR_INVALID_DATA; +- } +- access_sid = &(uncrypted_accesscheckv2.sid); +- break; +- } +- case 3: +- { +- uint32_t hash_size = 64; +- uint8_t hash[hash_size]; +- struct hc_sha512state sctx; +- struct bkrp_access_check_v3 uncrypted_accesscheckv3; +- +- ndr_err = ndr_pull_struct_blob(&blob_us, sub_ctx, &uncrypted_accesscheckv3, +- (ndr_pull_flags_fn_t)ndr_pull_bkrp_access_check_v3); +- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { +- /* Unable to unmarshall */ +- der_free_octet_string(&access_check_os); +- return WERR_INVALID_DATA; +- } +- if (uncrypted_accesscheckv3.magic != 0x1) { +- /* wrong magic */ +- der_free_octet_string(&access_check_os); +- return WERR_INVALID_DATA; +- } +- +- SHA512_Init(&sctx); +- SHA512_Update(&sctx, blob_us.data, blob_us.length - hash_size); +- SHA512_Final(hash, &sctx); +- der_free_octet_string(&access_check_os); +- /* +- * We free it after the sha1 calculation because blob.data +- * point to the same area +- */ +- +- if (memcmp(hash, uncrypted_accesscheckv3.hash, hash_size) != 0) { +- DEBUG(2, ("Wrong hash value in the access check in backup key remote protocol\n")); +- return WERR_INVALID_DATA; +- } +- access_sid = &(uncrypted_accesscheckv3.sid); +- break; +- } +- default: +- /* Never reached normally as we filtered at the switch / case level */ +- return WERR_INVALID_DATA; +- } +- +- caller_sid = &session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; +- +- if (!dom_sid_equal(caller_sid, access_sid)) { +- return WERR_INVALID_ACCESS; +- } +- return WERR_OK; +-} +- +-/* +- * We have some data, such as saved website or IMAP passwords that the +- * client has in profile on-disk. This needs to be decrypted. This +- * version gives the server the data over the network (protected by +- * the X.509 certificate and public key encryption, and asks that it +- * be decrypted returned for short-term use, protected only by the +- * negotiated transport encryption. +- * +- * The data is NOT stored in the LSA, but a X.509 certificate, public +- * and private keys used to encrypt the data will be stored. There is +- * only one active encryption key pair and certificate per domain, it +- * is pointed at with G$BCKUPKEY_PREFERRED in the LSA secrets store. +- * +- * The potentially multiple valid decrypting key pairs are in turn +- * stored in the LSA secrets store as G$BCKUPKEY_keyGuidString. +- * +- */ +-static WERROR bkrp_client_wrap_decrypt_data(struct dcesrv_call_state *dce_call, +- TALLOC_CTX *mem_ctx, +- struct bkrp_BackupKey *r, +- struct ldb_context *ldb_ctx) +-{ +- struct auth_session_info *session_info = +- dcesrv_call_session_info(dce_call); +- struct bkrp_client_side_wrapped uncrypt_request; +- DATA_BLOB blob; +- enum ndr_err_code ndr_err; +- char *guid_string; +- char *cert_secret_name; +- DATA_BLOB lsa_secret; +- DATA_BLOB *uncrypted_data = NULL; +- NTSTATUS status; +- uint32_t requested_version; +- +- blob.data = r->in.data_in; +- blob.length = r->in.data_in_len; +- +- if (r->in.data_in_len < 4 || r->in.data_in == NULL) { +- return WERR_INVALID_PARAMETER; +- } +- +- /* +- * We check for the version here, so we can actually print the +- * message as we are unlikely to parse it with NDR. +- */ +- requested_version = IVAL(r->in.data_in, 0); +- if ((requested_version != BACKUPKEY_CLIENT_WRAP_VERSION2) +- && (requested_version != BACKUPKEY_CLIENT_WRAP_VERSION3)) { +- DEBUG(1, ("Request for unknown BackupKey sub-protocol %d\n", requested_version)); +- return WERR_INVALID_PARAMETER; +- } +- +- ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &uncrypt_request, +- (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_wrapped); +- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { +- return WERR_INVALID_PARAMETER; +- } +- +- if ((uncrypt_request.version != BACKUPKEY_CLIENT_WRAP_VERSION2) +- && (uncrypt_request.version != BACKUPKEY_CLIENT_WRAP_VERSION3)) { +- DEBUG(1, ("Request for unknown BackupKey sub-protocol %d\n", uncrypt_request.version)); +- return WERR_INVALID_PARAMETER; +- } +- +- guid_string = GUID_string(mem_ctx, &uncrypt_request.guid); +- if (guid_string == NULL) { +- return WERR_NOT_ENOUGH_MEMORY; +- } +- +- cert_secret_name = talloc_asprintf(mem_ctx, +- "BCKUPKEY_%s", +- guid_string); +- if (cert_secret_name == NULL) { +- return WERR_NOT_ENOUGH_MEMORY; +- } +- +- status = get_lsa_secret(mem_ctx, +- ldb_ctx, +- cert_secret_name, +- &lsa_secret); +- if (!NT_STATUS_IS_OK(status)) { +- DEBUG(10, ("Error while fetching secret %s\n", cert_secret_name)); +- return WERR_INVALID_DATA; +- } else if (lsa_secret.length == 0) { +- /* we do not have the real secret attribute, like if we are an RODC */ +- return WERR_INVALID_PARAMETER; +- } else { +- hx509_context hctx; +- struct bkrp_exported_RSA_key_pair keypair; +- hx509_private_key pk; +- uint32_t i, res; +- heim_octet_string reversed_secret; +- heim_octet_string uncrypted_secret; +- AlgorithmIdentifier alg; +- DATA_BLOB blob_us; +- WERROR werr; +- +- ndr_err = ndr_pull_struct_blob(&lsa_secret, mem_ctx, &keypair, (ndr_pull_flags_fn_t)ndr_pull_bkrp_exported_RSA_key_pair); +- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { +- DEBUG(2, ("Unable to parse the ndr encoded cert in key %s\n", cert_secret_name)); +- return WERR_FILE_NOT_FOUND; +- } +- +- status = get_pk_from_raw_keypair_params(mem_ctx, &keypair, &pk); +- if (!NT_STATUS_IS_OK(status)) { +- return WERR_INTERNAL_ERROR; +- } +- +- reversed_secret.data = talloc_array(mem_ctx, uint8_t, +- uncrypt_request.encrypted_secret_len); +- if (reversed_secret.data == NULL) { +- hx509_private_key_free(&pk); +- return WERR_NOT_ENOUGH_MEMORY; +- } +- +- /* The secret has to be reversed ... */ +- for(i=0; i< uncrypt_request.encrypted_secret_len; i++) { +- uint8_t *reversed = (uint8_t *)reversed_secret.data; +- uint8_t *uncrypt = uncrypt_request.encrypted_secret; +- reversed[i] = uncrypt[uncrypt_request.encrypted_secret_len - 1 - i]; +- } +- reversed_secret.length = uncrypt_request.encrypted_secret_len; +- +- /* +- * Let's try to decrypt the secret now that +- * we have the private key ... +- */ +- hx509_context_init(&hctx); +- res = hx509_private_key_private_decrypt(hctx, &reversed_secret, +- &alg.algorithm, pk, +- &uncrypted_secret); +- hx509_context_free(&hctx); +- hx509_private_key_free(&pk); +- if (res != 0) { +- /* We are not able to decrypt the secret, looks like something is wrong */ +- return WERR_INVALID_PARAMETER; +- } +- blob_us.data = uncrypted_secret.data; +- blob_us.length = uncrypted_secret.length; +- +- if (uncrypt_request.version == 2) { +- struct bkrp_encrypted_secret_v2 uncrypted_secretv2; +- +- ndr_err = ndr_pull_struct_blob(&blob_us, mem_ctx, &uncrypted_secretv2, +- (ndr_pull_flags_fn_t)ndr_pull_bkrp_encrypted_secret_v2); +- der_free_octet_string(&uncrypted_secret); +- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { +- /* Unable to unmarshall */ +- return WERR_INVALID_DATA; +- } +- if (uncrypted_secretv2.magic != 0x20) { +- /* wrong magic */ +- return WERR_INVALID_DATA; +- } +- +- werr = get_and_verify_access_check(mem_ctx, 2, +- uncrypted_secretv2.payload_key, +- uncrypt_request.access_check, +- uncrypt_request.access_check_len, +- session_info); +- if (!W_ERROR_IS_OK(werr)) { +- return werr; +- } +- uncrypted_data = talloc(mem_ctx, DATA_BLOB); +- if (uncrypted_data == NULL) { +- return WERR_INVALID_DATA; +- } +- +- uncrypted_data->data = uncrypted_secretv2.secret; +- uncrypted_data->length = uncrypted_secretv2.secret_len; +- } +- if (uncrypt_request.version == 3) { +- struct bkrp_encrypted_secret_v3 uncrypted_secretv3; +- +- ndr_err = ndr_pull_struct_blob(&blob_us, mem_ctx, &uncrypted_secretv3, +- (ndr_pull_flags_fn_t)ndr_pull_bkrp_encrypted_secret_v3); +- +- der_free_octet_string(&uncrypted_secret); +- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { +- /* Unable to unmarshall */ +- return WERR_INVALID_DATA; +- } +- +- if (uncrypted_secretv3.magic1 != 0x30 || +- uncrypted_secretv3.magic2 != 0x6610 || +- uncrypted_secretv3.magic3 != 0x800e) { +- /* wrong magic */ +- return WERR_INVALID_DATA; +- } +- +- /* +- * Confirm that the caller is permitted to +- * read this particular data. Because one key +- * pair is used per domain, the caller could +- * have stolen the profile data on-disk and +- * would otherwise be able to read the +- * passwords. +- */ +- +- werr = get_and_verify_access_check(mem_ctx, 3, +- uncrypted_secretv3.payload_key, +- uncrypt_request.access_check, +- uncrypt_request.access_check_len, +- session_info); +- if (!W_ERROR_IS_OK(werr)) { +- return werr; +- } +- +- uncrypted_data = talloc(mem_ctx, DATA_BLOB); +- if (uncrypted_data == NULL) { +- return WERR_INVALID_DATA; +- } +- +- uncrypted_data->data = uncrypted_secretv3.secret; +- uncrypted_data->length = uncrypted_secretv3.secret_len; +- } +- +- /* +- * Yeah if we are here all looks pretty good: +- * - hash is ok +- * - user sid is the same as the one in access check +- * - we were able to decrypt the whole stuff +- */ +- } +- +- if (uncrypted_data->data == NULL) { +- return WERR_INVALID_DATA; +- } +- +- /* There is a magic value a the beginning of the data +- * we can use an adhoc structure but as the +- * parent structure is just an array of bytes it a lot of work +- * work just prepending 4 bytes +- */ +- *(r->out.data_out) = talloc_zero_array(mem_ctx, uint8_t, uncrypted_data->length + 4); +- W_ERROR_HAVE_NO_MEMORY(*(r->out.data_out)); +- memcpy(4+*(r->out.data_out), uncrypted_data->data, uncrypted_data->length); +- *(r->out.data_out_len) = uncrypted_data->length + 4; +- +- return WERR_OK; +-} +- +-/* +- * Strictly, this function no longer uses Heimdal in order to generate an RSA +- * key, but GnuTLS. +- * +- * The resulting key is then imported into Heimdal's RSA structure. +- * +- * We use GnuTLS because it can reliably generate 2048 bit keys every time. +- * Windows clients strictly require 2048, no more since it won't fit and no +- * less either. Heimdal would almost always generate a smaller key. +- */ +-static WERROR create_heimdal_rsa_key(TALLOC_CTX *ctx, hx509_context *hctx, +- hx509_private_key *pk, RSA **rsa) +-{ +- int ret; +- uint8_t *p0 = NULL; +- const uint8_t *p; +- size_t len; +- int bits = 2048; +- int RSA_returned_bits; +- gnutls_x509_privkey_t gtls_key; +- WERROR werr; +- +- *rsa = NULL; +- +- ret = gnutls_global_init(); +- if (ret != GNUTLS_E_SUCCESS) { +- DBG_ERR("TLS error: %s\n", gnutls_strerror(ret)); +- return WERR_INTERNAL_ERROR; +- } +- +- ret = gnutls_x509_privkey_init(>ls_key); +- if (ret != 0) { +- gnutls_global_deinit(); +- return WERR_INTERNAL_ERROR; +- } +- +- /* +- * Unlike Heimdal's RSA_generate_key_ex(), this generates a +- * 2048 bit key 100% of the time. The heimdal code had a ~1/8 +- * chance of doing so, chewing vast quantities of computation +- * and entropy in the process. +- */ +- +- ret = gnutls_x509_privkey_generate(gtls_key, GNUTLS_PK_RSA, bits, 0); +- if (ret != 0) { +- werr = WERR_INTERNAL_ERROR; +- goto done; +- } +- +- /* No need to check error code, this SHOULD fail */ +- gnutls_x509_privkey_export(gtls_key, GNUTLS_X509_FMT_DER, NULL, &len); +- +- if (len < 1) { +- werr = WERR_INTERNAL_ERROR; +- goto done; +- } +- +- p0 = talloc_size(ctx, len); +- if (p0 == NULL) { +- werr = WERR_NOT_ENOUGH_MEMORY; +- goto done; +- } +- p = p0; +- +- /* +- * Only this GnuTLS export function correctly exports the key, +- * we can't use gnutls_rsa_params_export_raw() because while +- * it appears to be fixed in more recent versions, in the +- * Ubuntu 14.04 version 2.12.23 (at least) it incorrectly +- * exports one of the key parameters (qInv). Additionally, we +- * would have to work around subtle differences in big number +- * representations. +- * +- * We need access to the RSA parameters directly (in the +- * parameter RSA **rsa) as the caller has to manually encode +- * them in a non-standard data structure. +- */ +- ret = gnutls_x509_privkey_export(gtls_key, GNUTLS_X509_FMT_DER, p0, &len); +- +- if (ret != 0) { +- werr = WERR_INTERNAL_ERROR; +- goto done; +- } +- +- /* +- * To dump the key we can use : +- * rk_dumpdata("h5lkey", p0, len); +- */ +- ret = hx509_parse_private_key(*hctx, &_hx509_signature_rsa_with_var_num , +- p0, len, HX509_KEY_FORMAT_DER, pk); +- +- if (ret != 0) { +- werr = WERR_INTERNAL_ERROR; +- goto done; +- } +- +- *rsa = d2i_RSAPrivateKey(NULL, &p, len); +- TALLOC_FREE(p0); +- +- if (*rsa == NULL) { +- hx509_private_key_free(pk); +- werr = WERR_INTERNAL_ERROR; +- goto done; +- } +- +- RSA_returned_bits = BN_num_bits((*rsa)->n); +- DEBUG(6, ("GnuTLS returned an RSA private key with %d bits\n", RSA_returned_bits)); +- +- if (RSA_returned_bits != bits) { +- DEBUG(0, ("GnuTLS unexpectedly returned an RSA private key with %d bits, needed %d\n", RSA_returned_bits, bits)); +- hx509_private_key_free(pk); +- werr = WERR_INTERNAL_ERROR; +- goto done; +- } +- +- werr = WERR_OK; +- +-done: +- if (p0 != NULL) { +- memset(p0, 0, len); +- TALLOC_FREE(p0); +- } +- +- gnutls_x509_privkey_deinit(gtls_key); +- gnutls_global_deinit(); +- return werr; +-} +- +-static WERROR self_sign_cert(TALLOC_CTX *ctx, hx509_context *hctx, hx509_request *req, +- time_t lifetime, hx509_private_key *private_key, +- hx509_cert *cert, DATA_BLOB *guidblob) +-{ +- SubjectPublicKeyInfo spki; +- hx509_name subject = NULL; +- hx509_ca_tbs tbs; +- struct heim_bit_string uniqueid; +- struct heim_integer serialnumber; +- int ret, i; +- +- uniqueid.data = talloc_memdup(ctx, guidblob->data, guidblob->length); +- if (uniqueid.data == NULL) { +- return WERR_NOT_ENOUGH_MEMORY; +- } +- /* uniqueid is a bit string in which each byte represent 1 bit (1 or 0) +- * so as 1 byte is 8 bits we need to provision 8 times more space as in the +- * blob +- */ +- uniqueid.length = 8 * guidblob->length; +- +- serialnumber.data = talloc_array(ctx, uint8_t, +- guidblob->length); +- if (serialnumber.data == NULL) { +- talloc_free(uniqueid.data); +- return WERR_NOT_ENOUGH_MEMORY; +- } +- +- /* Native AD generates certificates with serialnumber in reversed notation */ +- for (i = 0; i < guidblob->length; i++) { +- uint8_t *reversed = (uint8_t *)serialnumber.data; +- uint8_t *uncrypt = guidblob->data; +- reversed[i] = uncrypt[guidblob->length - 1 - i]; +- } +- serialnumber.length = guidblob->length; +- serialnumber.negative = 0; +- +- memset(&spki, 0, sizeof(spki)); +- +- ret = hx509_request_get_name(*hctx, *req, &subject); +- if (ret !=0) { +- goto fail_subject; +- } +- ret = hx509_request_get_SubjectPublicKeyInfo(*hctx, *req, &spki); +- if (ret !=0) { +- goto fail_spki; +- } +- +- ret = hx509_ca_tbs_init(*hctx, &tbs); +- if (ret !=0) { +- goto fail_tbs; +- } +- +- ret = hx509_ca_tbs_set_spki(*hctx, tbs, &spki); +- if (ret !=0) { +- goto fail; +- } +- ret = hx509_ca_tbs_set_subject(*hctx, tbs, subject); +- if (ret !=0) { +- goto fail; +- } +- ret = hx509_ca_tbs_set_notAfter_lifetime(*hctx, tbs, lifetime); +- if (ret !=0) { +- goto fail; +- } +- ret = hx509_ca_tbs_set_unique(*hctx, tbs, &uniqueid, &uniqueid); +- if (ret !=0) { +- goto fail; +- } +- ret = hx509_ca_tbs_set_serialnumber(*hctx, tbs, &serialnumber); +- if (ret !=0) { +- goto fail; +- } +- ret = hx509_ca_sign_self(*hctx, tbs, *private_key, cert); +- if (ret !=0) { +- goto fail; +- } +- hx509_name_free(&subject); +- free_SubjectPublicKeyInfo(&spki); +- hx509_ca_tbs_free(&tbs); +- +- return WERR_OK; +- +-fail: +- hx509_ca_tbs_free(&tbs); +-fail_tbs: +- free_SubjectPublicKeyInfo(&spki); +-fail_spki: +- hx509_name_free(&subject); +-fail_subject: +- talloc_free(uniqueid.data); +- talloc_free(serialnumber.data); +- return WERR_INTERNAL_ERROR; +-} +- +-static WERROR create_req(TALLOC_CTX *ctx, hx509_context *hctx, hx509_request *req, +- hx509_private_key *signer,RSA **rsa, const char *dn) +-{ +- int ret; +- SubjectPublicKeyInfo key; +- +- hx509_name name; +- WERROR werr; +- +- werr = create_heimdal_rsa_key(ctx, hctx, signer, rsa); +- if (!W_ERROR_IS_OK(werr)) { +- return werr; +- } +- +- hx509_request_init(*hctx, req); +- ret = hx509_parse_name(*hctx, dn, &name); +- if (ret != 0) { +- RSA_free(*rsa); +- hx509_private_key_free(signer); +- hx509_request_free(req); +- hx509_name_free(&name); +- return WERR_INTERNAL_ERROR; +- } +- +- ret = hx509_request_set_name(*hctx, *req, name); +- if (ret != 0) { +- RSA_free(*rsa); +- hx509_private_key_free(signer); +- hx509_request_free(req); +- hx509_name_free(&name); +- return WERR_INTERNAL_ERROR; +- } +- hx509_name_free(&name); +- +- ret = hx509_private_key2SPKI(*hctx, *signer, &key); +- if (ret != 0) { +- RSA_free(*rsa); +- hx509_private_key_free(signer); +- hx509_request_free(req); +- return WERR_INTERNAL_ERROR; +- } +- ret = hx509_request_set_SubjectPublicKeyInfo(*hctx, *req, &key); +- if (ret != 0) { +- RSA_free(*rsa); +- hx509_private_key_free(signer); +- free_SubjectPublicKeyInfo(&key); +- hx509_request_free(req); +- return WERR_INTERNAL_ERROR; +- } +- +- free_SubjectPublicKeyInfo(&key); +- +- return WERR_OK; +-} +- +-/* Return an error when we fail to generate a certificate */ +-static WERROR generate_bkrp_cert(TALLOC_CTX *ctx, struct dcesrv_call_state *dce_call, struct ldb_context *ldb_ctx, const char *dn) +-{ +- heim_octet_string data; +- WERROR werr; +- RSA *rsa; +- hx509_context hctx; +- hx509_private_key pk; +- hx509_request req; +- hx509_cert cert; +- DATA_BLOB blob; +- DATA_BLOB blobkeypair; +- DATA_BLOB *tmp; +- int ret; +- bool ok = true; +- struct GUID guid = GUID_random(); +- NTSTATUS status; +- char *secret_name; +- struct bkrp_exported_RSA_key_pair keypair; +- enum ndr_err_code ndr_err; +- uint32_t nb_seconds_validity = 3600 * 24 * 365; +- +- DEBUG(6, ("Trying to generate a certificate\n")); +- hx509_context_init(&hctx); +- werr = create_req(ctx, &hctx, &req, &pk, &rsa, dn); +- if (!W_ERROR_IS_OK(werr)) { +- hx509_context_free(&hctx); +- return werr; +- } +- +- status = GUID_to_ndr_blob(&guid, ctx, &blob); +- if (!NT_STATUS_IS_OK(status)) { +- hx509_context_free(&hctx); +- hx509_private_key_free(&pk); +- RSA_free(rsa); +- return WERR_INVALID_DATA; +- } +- +- werr = self_sign_cert(ctx, &hctx, &req, nb_seconds_validity, &pk, &cert, &blob); +- if (!W_ERROR_IS_OK(werr)) { +- hx509_private_key_free(&pk); +- hx509_context_free(&hctx); +- return WERR_INVALID_DATA; +- } +- +- ret = hx509_cert_binary(hctx, cert, &data); +- if (ret !=0) { +- hx509_cert_free(cert); +- hx509_private_key_free(&pk); +- hx509_context_free(&hctx); +- return WERR_INVALID_DATA; +- } +- +- keypair.cert.data = talloc_memdup(ctx, data.data, data.length); +- keypair.cert.length = data.length; +- +- /* +- * Heimdal's bignum are big endian and the +- * structure expect it to be in little endian +- * so we reverse the buffer to make it work +- */ +- tmp = reverse_and_get_blob(ctx, rsa->e); +- if (tmp == NULL) { +- ok = false; +- } else { +- keypair.public_exponent = *tmp; +- SMB_ASSERT(tmp->length <= 4); +- /* +- * The value is now in little endian but if can happen that the length is +- * less than 4 bytes. +- * So if we have less than 4 bytes we pad with zeros so that it correctly +- * fit into the structure. +- */ +- if (tmp->length < 4) { +- /* +- * We need the expo to fit 4 bytes +- */ +- keypair.public_exponent.data = talloc_zero_array(ctx, uint8_t, 4); +- memcpy(keypair.public_exponent.data, tmp->data, tmp->length); +- keypair.public_exponent.length = 4; +- } +- } +- +- tmp = reverse_and_get_blob(ctx,rsa->d); +- if (tmp == NULL) { +- ok = false; +- } else { +- keypair.private_exponent = *tmp; +- } +- +- tmp = reverse_and_get_blob(ctx,rsa->n); +- if (tmp == NULL) { +- ok = false; +- } else { +- keypair.modulus = *tmp; +- } +- +- tmp = reverse_and_get_blob(ctx,rsa->p); +- if (tmp == NULL) { +- ok = false; +- } else { +- keypair.prime1 = *tmp; +- } +- +- tmp = reverse_and_get_blob(ctx,rsa->q); +- if (tmp == NULL) { +- ok = false; +- } else { +- keypair.prime2 = *tmp; +- } +- +- tmp = reverse_and_get_blob(ctx,rsa->dmp1); +- if (tmp == NULL) { +- ok = false; +- } else { +- keypair.exponent1 = *tmp; +- } +- +- tmp = reverse_and_get_blob(ctx,rsa->dmq1); +- if (tmp == NULL) { +- ok = false; +- } else { +- keypair.exponent2 = *tmp; +- } +- +- tmp = reverse_and_get_blob(ctx,rsa->iqmp); +- if (tmp == NULL) { +- ok = false; +- } else { +- keypair.coefficient = *tmp; +- } +- +- /* One of the keypair allocation was wrong */ +- if (ok == false) { +- der_free_octet_string(&data); +- hx509_cert_free(cert); +- hx509_private_key_free(&pk); +- hx509_context_free(&hctx); +- RSA_free(rsa); +- return WERR_INVALID_DATA; +- } +- keypair.certificate_len = keypair.cert.length; +- ndr_err = ndr_push_struct_blob(&blobkeypair, ctx, &keypair, (ndr_push_flags_fn_t)ndr_push_bkrp_exported_RSA_key_pair); +- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { +- der_free_octet_string(&data); +- hx509_cert_free(cert); +- hx509_private_key_free(&pk); +- hx509_context_free(&hctx); +- RSA_free(rsa); +- return WERR_INVALID_DATA; +- } +- +- secret_name = talloc_asprintf(ctx, "BCKUPKEY_%s", GUID_string(ctx, &guid)); +- if (secret_name == NULL) { +- der_free_octet_string(&data); +- hx509_cert_free(cert); +- hx509_private_key_free(&pk); +- hx509_context_free(&hctx); +- RSA_free(rsa); +- return WERR_OUTOFMEMORY; +- } +- +- status = set_lsa_secret(ctx, ldb_ctx, secret_name, &blobkeypair); +- if (!NT_STATUS_IS_OK(status)) { +- DEBUG(2, ("Failed to save the secret %s\n", secret_name)); +- } +- talloc_free(secret_name); +- +- GUID_to_ndr_blob(&guid, ctx, &blob); +- status = set_lsa_secret(ctx, ldb_ctx, "BCKUPKEY_PREFERRED", &blob); +- if (!NT_STATUS_IS_OK(status)) { +- DEBUG(2, ("Failed to save the secret BCKUPKEY_PREFERRED\n")); +- } +- +- der_free_octet_string(&data); +- hx509_cert_free(cert); +- hx509_private_key_free(&pk); +- hx509_context_free(&hctx); +- RSA_free(rsa); +- return WERR_OK; +-} +- +-static WERROR bkrp_retrieve_client_wrap_key(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, +- struct bkrp_BackupKey *r, struct ldb_context *ldb_ctx) +-{ +- struct GUID guid; +- char *guid_string; +- DATA_BLOB lsa_secret; +- enum ndr_err_code ndr_err; +- NTSTATUS status; +- +- /* +- * here we basicaly need to return our certificate +- * search for lsa secret BCKUPKEY_PREFERRED first +- */ +- +- status = get_lsa_secret(mem_ctx, +- ldb_ctx, +- "BCKUPKEY_PREFERRED", +- &lsa_secret); +- if (NT_STATUS_EQUAL(status, NT_STATUS_RESOURCE_NAME_NOT_FOUND)) { +- /* Ok we can be in this case if there was no certs */ +- struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; +- char *dn = talloc_asprintf(mem_ctx, "CN=%s", +- lpcfg_realm(lp_ctx)); +- +- WERROR werr = generate_bkrp_cert(mem_ctx, dce_call, ldb_ctx, dn); +- if (!W_ERROR_IS_OK(werr)) { +- return WERR_INVALID_PARAMETER; +- } +- status = get_lsa_secret(mem_ctx, +- ldb_ctx, +- "BCKUPKEY_PREFERRED", +- &lsa_secret); +- +- if (!NT_STATUS_IS_OK(status)) { +- /* Ok we really don't manage to get this certs ...*/ +- DEBUG(2, ("Unable to locate BCKUPKEY_PREFERRED after cert generation\n")); +- return WERR_FILE_NOT_FOUND; +- } +- } else if (!NT_STATUS_IS_OK(status)) { +- return WERR_INTERNAL_ERROR; +- } +- +- if (lsa_secret.length == 0) { +- DEBUG(1, ("No secret in BCKUPKEY_PREFERRED, are we an undetected RODC?\n")); +- return WERR_INTERNAL_ERROR; +- } else { +- char *cert_secret_name; +- +- status = GUID_from_ndr_blob(&lsa_secret, &guid); +- if (!NT_STATUS_IS_OK(status)) { +- return WERR_FILE_NOT_FOUND; +- } +- +- guid_string = GUID_string(mem_ctx, &guid); +- if (guid_string == NULL) { +- /* We return file not found because the client +- * expect this error +- */ +- return WERR_FILE_NOT_FOUND; +- } +- +- cert_secret_name = talloc_asprintf(mem_ctx, +- "BCKUPKEY_%s", +- guid_string); +- status = get_lsa_secret(mem_ctx, +- ldb_ctx, +- cert_secret_name, +- &lsa_secret); +- if (!NT_STATUS_IS_OK(status)) { +- return WERR_FILE_NOT_FOUND; +- } +- +- if (lsa_secret.length != 0) { +- struct bkrp_exported_RSA_key_pair keypair; +- ndr_err = ndr_pull_struct_blob(&lsa_secret, mem_ctx, &keypair, +- (ndr_pull_flags_fn_t)ndr_pull_bkrp_exported_RSA_key_pair); +- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { +- return WERR_FILE_NOT_FOUND; +- } +- *(r->out.data_out_len) = keypair.cert.length; +- *(r->out.data_out) = talloc_memdup(mem_ctx, keypair.cert.data, keypair.cert.length); +- W_ERROR_HAVE_NO_MEMORY(*(r->out.data_out)); +- return WERR_OK; +- } else { +- DEBUG(1, ("No or broken secret called %s\n", cert_secret_name)); +- return WERR_INTERNAL_ERROR; +- } +- } +- +- return WERR_NOT_SUPPORTED; +-} +- +-static WERROR generate_bkrp_server_wrap_key(TALLOC_CTX *ctx, struct ldb_context *ldb_ctx) +-{ +- struct GUID guid = GUID_random(); +- enum ndr_err_code ndr_err; +- DATA_BLOB blob_wrap_key, guid_blob; +- struct bkrp_dc_serverwrap_key wrap_key; +- NTSTATUS status; +- char *secret_name; +- TALLOC_CTX *frame = talloc_stackframe(); +- +- generate_random_buffer(wrap_key.key, sizeof(wrap_key.key)); +- +- ndr_err = ndr_push_struct_blob(&blob_wrap_key, ctx, &wrap_key, (ndr_push_flags_fn_t)ndr_push_bkrp_dc_serverwrap_key); +- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { +- TALLOC_FREE(frame); +- return WERR_INVALID_DATA; +- } +- +- secret_name = talloc_asprintf(frame, "BCKUPKEY_%s", GUID_string(ctx, &guid)); +- if (secret_name == NULL) { +- TALLOC_FREE(frame); +- return WERR_NOT_ENOUGH_MEMORY; +- } +- +- status = set_lsa_secret(frame, ldb_ctx, secret_name, &blob_wrap_key); +- if (!NT_STATUS_IS_OK(status)) { +- DEBUG(2, ("Failed to save the secret %s\n", secret_name)); +- TALLOC_FREE(frame); +- return WERR_INTERNAL_ERROR; +- } +- +- status = GUID_to_ndr_blob(&guid, frame, &guid_blob); +- if (!NT_STATUS_IS_OK(status)) { +- DEBUG(2, ("Failed to save the secret %s\n", secret_name)); +- TALLOC_FREE(frame); +- } +- +- status = set_lsa_secret(frame, ldb_ctx, "BCKUPKEY_P", &guid_blob); +- if (!NT_STATUS_IS_OK(status)) { +- DEBUG(2, ("Failed to save the secret %s\n", secret_name)); +- TALLOC_FREE(frame); +- return WERR_INTERNAL_ERROR; +- } +- +- TALLOC_FREE(frame); +- +- return WERR_OK; +-} +- +-/* +- * Find the specified decryption keys from the LSA secrets store as +- * G$BCKUPKEY_keyGuidString. +- */ +- +-static WERROR bkrp_do_retrieve_server_wrap_key(TALLOC_CTX *mem_ctx, struct ldb_context *ldb_ctx, +- struct bkrp_dc_serverwrap_key *server_key, +- struct GUID *guid) +-{ +- NTSTATUS status; +- DATA_BLOB lsa_secret; +- char *secret_name; +- char *guid_string; +- enum ndr_err_code ndr_err; +- +- guid_string = GUID_string(mem_ctx, guid); +- if (guid_string == NULL) { +- /* We return file not found because the client +- * expect this error +- */ +- return WERR_FILE_NOT_FOUND; +- } +- +- secret_name = talloc_asprintf(mem_ctx, "BCKUPKEY_%s", guid_string); +- if (secret_name == NULL) { +- return WERR_NOT_ENOUGH_MEMORY; +- } +- +- status = get_lsa_secret(mem_ctx, ldb_ctx, secret_name, &lsa_secret); +- if (!NT_STATUS_IS_OK(status)) { +- DEBUG(10, ("Error while fetching secret %s\n", secret_name)); +- return WERR_INVALID_DATA; +- } +- if (lsa_secret.length == 0) { +- /* RODC case, we do not have secrets locally */ +- DEBUG(1, ("Unable to fetch value for secret %s, are we an undetected RODC?\n", +- secret_name)); +- return WERR_INTERNAL_ERROR; +- } +- ndr_err = ndr_pull_struct_blob(&lsa_secret, mem_ctx, server_key, +- (ndr_pull_flags_fn_t)ndr_pull_bkrp_dc_serverwrap_key); +- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { +- DEBUG(2, ("Unable to parse the ndr encoded server wrap key %s\n", secret_name)); +- return WERR_INVALID_DATA; +- } +- +- return WERR_OK; +-} +- +-/* +- * Find the current, preferred ServerWrap Key by looking at +- * G$BCKUPKEY_P in the LSA secrets store. +- * +- * Then find the current decryption keys from the LSA secrets store as +- * G$BCKUPKEY_keyGuidString. +- */ +- +-static WERROR bkrp_do_retrieve_default_server_wrap_key(TALLOC_CTX *mem_ctx, +- struct ldb_context *ldb_ctx, +- struct bkrp_dc_serverwrap_key *server_key, +- struct GUID *returned_guid) +-{ +- NTSTATUS status; +- DATA_BLOB guid_binary; +- +- status = get_lsa_secret(mem_ctx, ldb_ctx, "BCKUPKEY_P", &guid_binary); +- if (!NT_STATUS_IS_OK(status)) { +- DEBUG(10, ("Error while fetching secret BCKUPKEY_P to find current GUID\n")); +- return WERR_FILE_NOT_FOUND; +- } else if (guid_binary.length == 0) { +- /* RODC case, we do not have secrets locally */ +- DEBUG(1, ("Unable to fetch value for secret BCKUPKEY_P, are we an undetected RODC?\n")); +- return WERR_INTERNAL_ERROR; +- } +- +- status = GUID_from_ndr_blob(&guid_binary, returned_guid); +- if (!NT_STATUS_IS_OK(status)) { +- return WERR_FILE_NOT_FOUND; +- } +- +- return bkrp_do_retrieve_server_wrap_key(mem_ctx, ldb_ctx, +- server_key, returned_guid); +-} +- +-static WERROR bkrp_server_wrap_decrypt_data(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, +- struct bkrp_BackupKey *r ,struct ldb_context *ldb_ctx) +-{ +- struct auth_session_info *session_info = +- dcesrv_call_session_info(dce_call); +- WERROR werr; +- struct bkrp_server_side_wrapped decrypt_request; +- DATA_BLOB sid_blob, encrypted_blob, symkey_blob; +- DATA_BLOB blob; +- enum ndr_err_code ndr_err; +- struct bkrp_dc_serverwrap_key server_key; +- struct bkrp_rc4encryptedpayload rc4payload; +- struct dom_sid *caller_sid; +- uint8_t symkey[20]; /* SHA-1 hash len */ +- uint8_t mackey[20]; /* SHA-1 hash len */ +- uint8_t mac[20]; /* SHA-1 hash len */ +- unsigned int hash_len; +- HMAC_CTX ctx; +- +- blob.data = r->in.data_in; +- blob.length = r->in.data_in_len; +- +- if (r->in.data_in_len == 0 || r->in.data_in == NULL) { +- return WERR_INVALID_PARAMETER; +- } +- +- ndr_err = ndr_pull_struct_blob_all(&blob, mem_ctx, &decrypt_request, +- (ndr_pull_flags_fn_t)ndr_pull_bkrp_server_side_wrapped); +- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { +- return WERR_INVALID_PARAMETER; +- } +- +- if (decrypt_request.magic != BACKUPKEY_SERVER_WRAP_VERSION) { +- return WERR_INVALID_PARAMETER; +- } +- +- werr = bkrp_do_retrieve_server_wrap_key(mem_ctx, ldb_ctx, &server_key, +- &decrypt_request.guid); +- if (!W_ERROR_IS_OK(werr)) { +- return werr; +- } +- +- dump_data_pw("server_key: \n", server_key.key, sizeof(server_key.key)); +- +- dump_data_pw("r2: \n", decrypt_request.r2, sizeof(decrypt_request.r2)); +- +- /* +- * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1 +- * BACKUPKEY_BACKUP_GUID, it really is the whole key +- */ +- HMAC(EVP_sha1(), server_key.key, sizeof(server_key.key), +- decrypt_request.r2, sizeof(decrypt_request.r2), +- symkey, &hash_len); +- +- dump_data_pw("symkey: \n", symkey, hash_len); +- +- /* rc4 decrypt sid and secret using sym key */ +- symkey_blob = data_blob_const(symkey, sizeof(symkey)); +- +- encrypted_blob = data_blob_const(decrypt_request.rc4encryptedpayload, +- decrypt_request.ciphertext_length); +- +- arcfour_crypt_blob(encrypted_blob.data, encrypted_blob.length, &symkey_blob); +- +- ndr_err = ndr_pull_struct_blob_all(&encrypted_blob, mem_ctx, &rc4payload, +- (ndr_pull_flags_fn_t)ndr_pull_bkrp_rc4encryptedpayload); +- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { +- return WERR_INVALID_PARAMETER; +- } +- +- if (decrypt_request.payload_length != rc4payload.secret_data.length) { +- return WERR_INVALID_PARAMETER; +- } +- +- dump_data_pw("r3: \n", rc4payload.r3, sizeof(rc4payload.r3)); +- +- /* +- * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1 +- * BACKUPKEY_BACKUP_GUID, it really is the whole key +- */ +- HMAC(EVP_sha1(), server_key.key, sizeof(server_key.key), +- rc4payload.r3, sizeof(rc4payload.r3), +- mackey, &hash_len); +- +- dump_data_pw("mackey: \n", mackey, sizeof(mackey)); +- +- ndr_err = ndr_push_struct_blob(&sid_blob, mem_ctx, &rc4payload.sid, +- (ndr_push_flags_fn_t)ndr_push_dom_sid); +- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { +- return WERR_INTERNAL_ERROR; +- } +- +- HMAC_CTX_init(&ctx); +- HMAC_Init_ex(&ctx, mackey, hash_len, EVP_sha1(), NULL); +- /* SID field */ +- HMAC_Update(&ctx, sid_blob.data, sid_blob.length); +- /* Secret field */ +- HMAC_Update(&ctx, rc4payload.secret_data.data, rc4payload.secret_data.length); +- HMAC_Final(&ctx, mac, &hash_len); +- HMAC_CTX_cleanup(&ctx); +- +- dump_data_pw("mac: \n", mac, sizeof(mac)); +- dump_data_pw("rc4payload.mac: \n", rc4payload.mac, sizeof(rc4payload.mac)); +- +- if (memcmp(mac, rc4payload.mac, sizeof(mac)) != 0) { +- return WERR_INVALID_ACCESS; +- } +- +- caller_sid = &session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; +- +- if (!dom_sid_equal(&rc4payload.sid, caller_sid)) { +- return WERR_INVALID_ACCESS; +- } +- +- *(r->out.data_out) = rc4payload.secret_data.data; +- *(r->out.data_out_len) = rc4payload.secret_data.length; +- +- return WERR_OK; +-} +- +-/* +- * For BACKUPKEY_RESTORE_GUID we need to check the first 4 bytes to +- * determine what type of restore is wanted. +- * +- * See MS-BKRP 3.1.4.1.4 BACKUPKEY_RESTORE_GUID point 1. +- */ +- +-static WERROR bkrp_generic_decrypt_data(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, +- struct bkrp_BackupKey *r, struct ldb_context *ldb_ctx) +-{ +- if (r->in.data_in_len < 4 || r->in.data_in == NULL) { +- return WERR_INVALID_PARAMETER; +- } +- +- if (IVAL(r->in.data_in, 0) == BACKUPKEY_SERVER_WRAP_VERSION) { +- return bkrp_server_wrap_decrypt_data(dce_call, mem_ctx, r, ldb_ctx); +- } +- +- return bkrp_client_wrap_decrypt_data(dce_call, mem_ctx, r, ldb_ctx); +-} +- +-/* +- * We have some data, such as saved website or IMAP passwords that the +- * client would like to put into the profile on-disk. This needs to +- * be encrypted. This version gives the server the data over the +- * network (protected only by the negotiated transport encryption), +- * and asks that it be encrypted and returned for long-term storage. +- * +- * The data is NOT stored in the LSA, but a key to encrypt the data +- * will be stored. There is only one active encryption key per domain, +- * it is pointed at with G$BCKUPKEY_P in the LSA secrets store. +- * +- * The potentially multiple valid decryptiong keys (and the encryption +- * key) are in turn stored in the LSA secrets store as +- * G$BCKUPKEY_keyGuidString. +- * +- */ +- +-static WERROR bkrp_server_wrap_encrypt_data(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, +- struct bkrp_BackupKey *r ,struct ldb_context *ldb_ctx) +-{ +- struct auth_session_info *session_info = +- dcesrv_call_session_info(dce_call); +- DATA_BLOB sid_blob, encrypted_blob, symkey_blob, server_wrapped_blob; +- WERROR werr; +- struct dom_sid *caller_sid; +- uint8_t symkey[20]; /* SHA-1 hash len */ +- uint8_t mackey[20]; /* SHA-1 hash len */ +- unsigned int hash_len; +- struct bkrp_rc4encryptedpayload rc4payload; +- HMAC_CTX ctx; +- struct bkrp_dc_serverwrap_key server_key; +- enum ndr_err_code ndr_err; +- struct bkrp_server_side_wrapped server_side_wrapped; +- struct GUID guid; +- +- if (r->in.data_in_len == 0 || r->in.data_in == NULL) { +- return WERR_INVALID_PARAMETER; +- } +- +- werr = bkrp_do_retrieve_default_server_wrap_key(mem_ctx, +- ldb_ctx, &server_key, +- &guid); +- +- if (!W_ERROR_IS_OK(werr)) { +- if (W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)) { +- /* Generate the server wrap key since one wasn't found */ +- werr = generate_bkrp_server_wrap_key(mem_ctx, +- ldb_ctx); +- if (!W_ERROR_IS_OK(werr)) { +- return WERR_INVALID_PARAMETER; +- } +- werr = bkrp_do_retrieve_default_server_wrap_key(mem_ctx, +- ldb_ctx, +- &server_key, +- &guid); +- +- if (W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)) { +- /* Ok we really don't manage to get this secret ...*/ +- return WERR_FILE_NOT_FOUND; +- } +- } else { +- /* In theory we should NEVER reach this point as it +- should only appear in a rodc server */ +- /* we do not have the real secret attribute */ +- return WERR_INVALID_PARAMETER; +- } +- } +- +- caller_sid = &session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; +- +- dump_data_pw("server_key: \n", server_key.key, sizeof(server_key.key)); +- +- /* +- * This is the key derivation step, so that the HMAC and RC4 +- * operations over the user-supplied data are not able to +- * disclose the master key. By using random data, the symkey +- * and mackey values are unique for this operation, and +- * discovering these (by reversing the RC4 over the +- * attacker-controlled data) does not return something able to +- * be used to decyrpt the encrypted data of other users +- */ +- generate_random_buffer(server_side_wrapped.r2, sizeof(server_side_wrapped.r2)); +- +- dump_data_pw("r2: \n", server_side_wrapped.r2, sizeof(server_side_wrapped.r2)); +- +- generate_random_buffer(rc4payload.r3, sizeof(rc4payload.r3)); +- +- dump_data_pw("r3: \n", rc4payload.r3, sizeof(rc4payload.r3)); +- +- +- /* +- * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1 +- * BACKUPKEY_BACKUP_GUID, it really is the whole key +- */ +- HMAC(EVP_sha1(), server_key.key, sizeof(server_key.key), +- server_side_wrapped.r2, sizeof(server_side_wrapped.r2), +- symkey, &hash_len); +- +- dump_data_pw("symkey: \n", symkey, hash_len); +- +- /* +- * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1 +- * BACKUPKEY_BACKUP_GUID, it really is the whole key +- */ +- HMAC(EVP_sha1(), server_key.key, sizeof(server_key.key), +- rc4payload.r3, sizeof(rc4payload.r3), +- mackey, &hash_len); +- +- dump_data_pw("mackey: \n", mackey, sizeof(mackey)); +- +- ndr_err = ndr_push_struct_blob(&sid_blob, mem_ctx, caller_sid, +- (ndr_push_flags_fn_t)ndr_push_dom_sid); +- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { +- return WERR_INTERNAL_ERROR; +- } +- +- rc4payload.secret_data.data = r->in.data_in; +- rc4payload.secret_data.length = r->in.data_in_len; +- +- HMAC_CTX_init(&ctx); +- HMAC_Init_ex(&ctx, mackey, 20, EVP_sha1(), NULL); +- /* SID field */ +- HMAC_Update(&ctx, sid_blob.data, sid_blob.length); +- /* Secret field */ +- HMAC_Update(&ctx, rc4payload.secret_data.data, rc4payload.secret_data.length); +- HMAC_Final(&ctx, rc4payload.mac, &hash_len); +- HMAC_CTX_cleanup(&ctx); +- +- dump_data_pw("rc4payload.mac: \n", rc4payload.mac, sizeof(rc4payload.mac)); +- +- rc4payload.sid = *caller_sid; +- +- ndr_err = ndr_push_struct_blob(&encrypted_blob, mem_ctx, &rc4payload, +- (ndr_push_flags_fn_t)ndr_push_bkrp_rc4encryptedpayload); +- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { +- return WERR_INTERNAL_ERROR; +- } +- +- /* rc4 encrypt sid and secret using sym key */ +- symkey_blob = data_blob_const(symkey, sizeof(symkey)); +- arcfour_crypt_blob(encrypted_blob.data, encrypted_blob.length, &symkey_blob); +- +- /* create server wrap structure */ +- +- server_side_wrapped.payload_length = rc4payload.secret_data.length; +- server_side_wrapped.ciphertext_length = encrypted_blob.length; +- server_side_wrapped.guid = guid; +- server_side_wrapped.rc4encryptedpayload = encrypted_blob.data; +- +- ndr_err = ndr_push_struct_blob(&server_wrapped_blob, mem_ctx, &server_side_wrapped, +- (ndr_push_flags_fn_t)ndr_push_bkrp_server_side_wrapped); +- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { +- return WERR_INTERNAL_ERROR; +- } +- +- *(r->out.data_out) = server_wrapped_blob.data; +- *(r->out.data_out_len) = server_wrapped_blob.length; +- +- return WERR_OK; +-} +- +-static WERROR dcesrv_bkrp_BackupKey(struct dcesrv_call_state *dce_call, +- TALLOC_CTX *mem_ctx, struct bkrp_BackupKey *r) +-{ +- WERROR error = WERR_INVALID_PARAMETER; +- struct ldb_context *ldb_ctx; +- bool is_rodc; +- const char *addr = "unknown"; +- /* At which level we start to add more debug of what is done in the protocol */ +- const int debuglevel = 4; +- +- if (DEBUGLVL(debuglevel)) { +- const struct tsocket_address *remote_address; +- remote_address = dcesrv_connection_get_remote_address(dce_call->conn); +- if (tsocket_address_is_inet(remote_address, "ip")) { +- addr = tsocket_address_inet_addr_string(remote_address, mem_ctx); +- W_ERROR_HAVE_NO_MEMORY(addr); +- } +- } +- +- if (lpcfg_server_role(dce_call->conn->dce_ctx->lp_ctx) != ROLE_ACTIVE_DIRECTORY_DC) { +- return WERR_NOT_SUPPORTED; +- } +- +- /* +- * Save the current remote session details so they can used by the +- * audit logging module. This allows the audit logging to report the +- * remote users details, rather than the system users details. +- */ +- ldb_ctx = dcesrv_samdb_connect_as_system(mem_ctx, dce_call); +- if (samdb_rodc(ldb_ctx, &is_rodc) != LDB_SUCCESS) { +- talloc_unlink(mem_ctx, ldb_ctx); +- return WERR_INVALID_PARAMETER; +- } +- +- if (!is_rodc) { +- if(strncasecmp(GUID_string(mem_ctx, r->in.guidActionAgent), +- BACKUPKEY_RESTORE_GUID, strlen(BACKUPKEY_RESTORE_GUID)) == 0) { +- DEBUG(debuglevel, ("Client %s requested to decrypt a wrapped secret\n", addr)); +- error = bkrp_generic_decrypt_data(dce_call, mem_ctx, r, ldb_ctx); +- } +- +- if (strncasecmp(GUID_string(mem_ctx, r->in.guidActionAgent), +- BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID, strlen(BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID)) == 0) { +- DEBUG(debuglevel, ("Client %s requested certificate for client wrapped secret\n", addr)); +- error = bkrp_retrieve_client_wrap_key(dce_call, mem_ctx, r, ldb_ctx); +- } +- +- if (strncasecmp(GUID_string(mem_ctx, r->in.guidActionAgent), +- BACKUPKEY_RESTORE_GUID_WIN2K, strlen(BACKUPKEY_RESTORE_GUID_WIN2K)) == 0) { +- DEBUG(debuglevel, ("Client %s requested to decrypt a server side wrapped secret\n", addr)); +- error = bkrp_server_wrap_decrypt_data(dce_call, mem_ctx, r, ldb_ctx); +- } +- +- if (strncasecmp(GUID_string(mem_ctx, r->in.guidActionAgent), +- BACKUPKEY_BACKUP_GUID, strlen(BACKUPKEY_BACKUP_GUID)) == 0) { +- DEBUG(debuglevel, ("Client %s requested a server wrapped secret\n", addr)); +- error = bkrp_server_wrap_encrypt_data(dce_call, mem_ctx, r, ldb_ctx); +- } +- } +- /*else: I am a RODC so I don't handle backup key protocol */ +- +- talloc_unlink(mem_ctx, ldb_ctx); +- return error; +-} +- +-/* include the generated boilerplate */ +-#include "librpc/gen_ndr/ndr_backupkey_s.c" +diff --git a/source4/rpc_server/wscript_build b/source4/rpc_server/wscript_build +index a7459d6b851..a5c1c1d9a2c 100644 +--- a/source4/rpc_server/wscript_build ++++ b/source4/rpc_server/wscript_build +@@ -119,23 +119,13 @@ bld.SAMBA_MODULE('dcerpc_lsarpc', + ) + + +-if (bld.CONFIG_SET('HAVE_GNUTLS_PRIVKEY_EXPORT_X509') and +- bld.CONFIG_SET('HAVE_GNUTLS_X509_CRT_SET_SUBJECT_UNIQUE_ID')): +- bld.SAMBA_MODULE('dcerpc_backupkey', +- source='backupkey/dcesrv_backupkey.c ', +- autoproto='backupkey/proto.h', +- subsystem='dcerpc_server', +- init_function='dcerpc_server_backupkey_init', +- deps='samdb DCERPC_COMMON NDR_BACKUPKEY RPC_NDR_BACKUPKEY gnutls', +- ) +-else: +- bld.SAMBA_MODULE('dcerpc_backupkey', +- source='backupkey/dcesrv_backupkey_heimdal.c ', +- autoproto='backupkey/proto.h', +- subsystem='dcerpc_server', +- init_function='dcerpc_server_backupkey_init', +- deps='samdb DCERPC_COMMON NDR_BACKUPKEY RPC_NDR_BACKUPKEY krb5 hx509 hcrypto gnutls DCERPC_COMMON', +- ) ++bld.SAMBA_MODULE('dcerpc_backupkey', ++ source='backupkey/dcesrv_backupkey.c ', ++ autoproto='backupkey/proto.h', ++ subsystem='dcerpc_server', ++ init_function='dcerpc_server_backupkey_init', ++ deps='samdb DCERPC_COMMON NDR_BACKUPKEY RPC_NDR_BACKUPKEY gnutls', ++ ) + + + bld.SAMBA_MODULE('dcerpc_drsuapi', +diff --git a/source4/torture/rpc/backupkey_heimdal.c b/source4/torture/rpc/backupkey_heimdal.c +deleted file mode 100644 +index 79b45e7aab8..00000000000 +--- a/source4/torture/rpc/backupkey_heimdal.c ++++ /dev/null +@@ -1,2160 +0,0 @@ +-/* +- Unix SMB/CIFS implementation. +- test suite for backupkey remote protocol rpc operations +- +- Copyright (C) Matthieu Patou 2010-2011 +- +- This program is free software; you can redistribute it and/or modify +- it under the terms of the GNU General Public License as published by +- the Free Software Foundation; either version 3 of the License, or +- (at your option) any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- GNU General Public License for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program. If not, see . +-*/ +- +-#include "includes.h" +-#include "../libcli/security/security.h" +- +-#include "torture/rpc/torture_rpc.h" +-#include "torture/ndr/ndr.h" +- +-#include "librpc/gen_ndr/ndr_backupkey_c.h" +-#include "librpc/gen_ndr/ndr_backupkey.h" +-#include "librpc/gen_ndr/ndr_lsa_c.h" +-#include "librpc/gen_ndr/ndr_security.h" +-#include "lib/cmdline/popt_common.h" +-#include "libcli/auth/proto.h" +-#include "lib/crypto/arcfour.h" +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-enum test_wrong { +- WRONG_MAGIC, +- WRONG_R2, +- WRONG_PAYLOAD_LENGTH, +- WRONG_CIPHERTEXT_LENGTH, +- SHORT_PAYLOAD_LENGTH, +- SHORT_CIPHERTEXT_LENGTH, +- ZERO_PAYLOAD_LENGTH, +- ZERO_CIPHERTEXT_LENGTH, +- RIGHT_KEY, +- WRONG_KEY, +- WRONG_SID, +-}; +- +-/* Our very special and valued secret */ +-/* No need to put const as we cast the array in uint8_t +- * we will get a warning about the discared const +- */ +-static const char secret[] = "tata yoyo mais qu'est ce qu'il y a sous ton grand chapeau ?"; +- +-/* Get the SID from a user */ +-static struct dom_sid *get_user_sid(struct torture_context *tctx, +- TALLOC_CTX *mem_ctx, +- const char *user) +-{ +- struct lsa_ObjectAttribute attr; +- struct lsa_QosInfo qos; +- struct lsa_OpenPolicy2 r; +- struct lsa_Close c; +- NTSTATUS status; +- struct policy_handle handle; +- struct lsa_LookupNames l; +- struct lsa_TransSidArray sids; +- struct lsa_RefDomainList *domains = NULL; +- struct lsa_String lsa_name; +- uint32_t count = 0; +- struct dom_sid *result; +- TALLOC_CTX *tmp_ctx; +- struct dcerpc_pipe *p2; +- struct dcerpc_binding_handle *b; +- +- const char *domain = cli_credentials_get_domain( +- popt_get_cmdline_credentials()); +- +- torture_assert_ntstatus_ok(tctx, +- torture_rpc_connection(tctx, &p2, &ndr_table_lsarpc), +- "could not open lsarpc pipe"); +- b = p2->binding_handle; +- +- if (!(tmp_ctx = talloc_new(mem_ctx))) { +- return NULL; +- } +- qos.len = 0; +- qos.impersonation_level = 2; +- qos.context_mode = 1; +- qos.effective_only = 0; +- +- attr.len = 0; +- attr.root_dir = NULL; +- attr.object_name = NULL; +- attr.attributes = 0; +- attr.sec_desc = NULL; +- attr.sec_qos = &qos; +- +- r.in.system_name = "\\"; +- r.in.attr = &attr; +- r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; +- r.out.handle = &handle; +- +- status = dcerpc_lsa_OpenPolicy2_r(b, tmp_ctx, &r); +- if (!NT_STATUS_IS_OK(status)) { +- torture_comment(tctx, +- "OpenPolicy2 failed - %s\n", +- nt_errstr(status)); +- talloc_free(tmp_ctx); +- return NULL; +- } +- if (!NT_STATUS_IS_OK(r.out.result)) { +- torture_comment(tctx, +- "OpenPolicy2_ failed - %s\n", +- nt_errstr(r.out.result)); +- talloc_free(tmp_ctx); +- return NULL; +- } +- +- sids.count = 0; +- sids.sids = NULL; +- +- lsa_name.string = talloc_asprintf(tmp_ctx, "%s\\%s", domain, user); +- +- l.in.handle = &handle; +- l.in.num_names = 1; +- l.in.names = &lsa_name; +- l.in.sids = &sids; +- l.in.level = 1; +- l.in.count = &count; +- l.out.count = &count; +- l.out.sids = &sids; +- l.out.domains = &domains; +- +- status = dcerpc_lsa_LookupNames_r(b, tmp_ctx, &l); +- if (!NT_STATUS_IS_OK(status)) { +- torture_comment(tctx, +- "LookupNames of %s failed - %s\n", +- lsa_name.string, +- nt_errstr(status)); +- talloc_free(tmp_ctx); +- return NULL; +- } +- +- if (domains->count == 0) { +- return NULL; +- } +- +- result = dom_sid_add_rid(mem_ctx, +- domains->domains[0].sid, +- l.out.sids->sids[0].rid); +- c.in.handle = &handle; +- c.out.handle = &handle; +- +- status = dcerpc_lsa_Close_r(b, tmp_ctx, &c); +- +- if (!NT_STATUS_IS_OK(status)) { +- torture_comment(tctx, +- "dcerpc_lsa_Close failed - %s\n", +- nt_errstr(status)); +- talloc_free(tmp_ctx); +- return NULL; +- } +- +- if (!NT_STATUS_IS_OK(c.out.result)) { +- torture_comment(tctx, +- "dcerpc_lsa_Close failed - %s\n", +- nt_errstr(c.out.result)); +- talloc_free(tmp_ctx); +- return NULL; +- } +- +- talloc_free(tmp_ctx); +- talloc_free(p2); +- +- torture_comment(tctx, "Get_user_sid finished\n"); +- return result; +-} +- +-/* +- * Create a bkrp_encrypted_secret_vX structure +- * the version depends on the version parameter +- * the structure is returned as a blob. +- * The broken flag is to indicate if we want +- * to create a non conform to specification structre +- */ +-static DATA_BLOB *create_unencryptedsecret(TALLOC_CTX *mem_ctx, +- bool broken, +- int version) +-{ +- TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); +- DATA_BLOB *blob = talloc_zero(mem_ctx, DATA_BLOB); +- enum ndr_err_code ndr_err; +- +- if (version == 2) { +- struct bkrp_encrypted_secret_v2 unenc_sec; +- +- ZERO_STRUCT(unenc_sec); +- unenc_sec.secret_len = sizeof(secret); +- unenc_sec.secret = discard_const_p(uint8_t, secret); +- generate_random_buffer(unenc_sec.payload_key, +- sizeof(unenc_sec.payload_key)); +- +- ndr_err = ndr_push_struct_blob(blob, blob, &unenc_sec, +- (ndr_push_flags_fn_t)ndr_push_bkrp_encrypted_secret_v2); +- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { +- return NULL; +- } +- +- if (broken) { +- /* The magic value is correctly set by the NDR push +- * but we want to test the behavior of the server +- * if a differrent value is provided +- */ +- ((uint8_t*)blob->data)[4] = 79; /* A great year !!! */ +- } +- } +- +- if (version == 3) { +- struct bkrp_encrypted_secret_v3 unenc_sec; +- +- ZERO_STRUCT(unenc_sec); +- unenc_sec.secret_len = sizeof(secret); +- unenc_sec.secret = discard_const_p(uint8_t, secret); +- generate_random_buffer(unenc_sec.payload_key, +- sizeof(unenc_sec.payload_key)); +- +- ndr_err = ndr_push_struct_blob(blob, blob, &unenc_sec, +- (ndr_push_flags_fn_t)ndr_push_bkrp_encrypted_secret_v3); +- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { +- return NULL; +- } +- +- if (broken) { +- /* +- * The magic value is correctly set by the NDR push +- * but we want to test the behavior of the server +- * if a differrent value is provided +- */ +- ((uint8_t*)blob->data)[4] = 79; /* A great year !!! */ +- } +- } +- talloc_free(tmp_ctx); +- return blob; +-} +- +-/* +- * Create an access check structure, the format depends on the version parameter. +- * If broken is specified then we create a stucture that isn't conform to the +- * specification. +- * +- * If the structure can't be created then NULL is returned. +- */ +-static DATA_BLOB *create_access_check(struct torture_context *tctx, +- struct dcerpc_pipe *p, +- TALLOC_CTX *mem_ctx, +- const char *user, +- bool broken, +- uint32_t version) +-{ +- TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); +- DATA_BLOB *blob = talloc_zero(mem_ctx, DATA_BLOB); +- enum ndr_err_code ndr_err; +- const struct dom_sid *sid = get_user_sid(tctx, tmp_ctx, user); +- +- if (sid == NULL) { +- return NULL; +- } +- +- if (version == 2) { +- struct bkrp_access_check_v2 access_struct; +- struct sha sctx; +- uint8_t nonce[32]; +- +- ZERO_STRUCT(access_struct); +- generate_random_buffer(nonce, sizeof(nonce)); +- access_struct.nonce_len = sizeof(nonce); +- access_struct.nonce = nonce; +- access_struct.sid = *sid; +- +- ndr_err = ndr_push_struct_blob(blob, blob, &access_struct, +- (ndr_push_flags_fn_t)ndr_push_bkrp_access_check_v2); +- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { +- return NULL; +- } +- +- /* +- * We pushed the whole structure including a null hash +- * but the hash need to be calculated only up to the hash field +- * so we reduce the size of what has to be calculated +- */ +- +- SHA1_Init(&sctx); +- SHA1_Update(&sctx, blob->data, +- blob->length - sizeof(access_struct.hash)); +- SHA1_Final(blob->data + blob->length - sizeof(access_struct.hash), +- &sctx); +- +- /* Altering the SHA */ +- if (broken) { +- blob->data[blob->length - 1]++; +- } +- } +- +- if (version == 3) { +- struct bkrp_access_check_v3 access_struct; +- struct hc_sha512state sctx; +- uint8_t nonce[32]; +- +- ZERO_STRUCT(access_struct); +- generate_random_buffer(nonce, sizeof(nonce)); +- access_struct.nonce_len = sizeof(nonce); +- access_struct.nonce = nonce; +- access_struct.sid = *sid; +- +- ndr_err = ndr_push_struct_blob(blob, blob, &access_struct, +- (ndr_push_flags_fn_t)ndr_push_bkrp_access_check_v3); +- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { +- return NULL; +- } +- +- /*We pushed the whole structure including a null hash +- * but the hash need to be calculated only up to the hash field +- * so we reduce the size of what has to be calculated +- */ +- +- SHA512_Init(&sctx); +- SHA512_Update(&sctx, blob->data, +- blob->length - sizeof(access_struct.hash)); +- SHA512_Final(blob->data + blob->length - sizeof(access_struct.hash), +- &sctx); +- +- /* Altering the SHA */ +- if (broken) { +- blob->data[blob->length -1]++; +- } +- } +- talloc_free(tmp_ctx); +- return blob; +-} +- +- +-static DATA_BLOB *encrypt_blob(struct torture_context *tctx, +- TALLOC_CTX *mem_ctx, +- DATA_BLOB *key, +- DATA_BLOB *iv, +- DATA_BLOB *to_encrypt, +- const AlgorithmIdentifier *alg) +-{ +- hx509_crypto crypto; +- hx509_context hctx; +- heim_octet_string ivos; +- heim_octet_string *encrypted; +- DATA_BLOB *blob = talloc_zero(mem_ctx, DATA_BLOB); +- int res; +- +- ivos.data = talloc_array(mem_ctx, uint8_t, iv->length); +- ivos.length = iv->length; +- memcpy(ivos.data, iv->data, iv->length); +- +- hx509_context_init(&hctx); +- res = hx509_crypto_init(hctx, NULL, &alg->algorithm, &crypto); +- if (res) { +- torture_comment(tctx, +- "error while doing the init of the crypto object\n"); +- hx509_context_free(&hctx); +- return NULL; +- } +- res = hx509_crypto_set_key_data(crypto, key->data, key->length); +- if (res) { +- torture_comment(tctx, +- "error while setting the key of the crypto object\n"); +- hx509_context_free(&hctx); +- return NULL; +- } +- +- hx509_crypto_set_padding(crypto, HX509_CRYPTO_PADDING_NONE); +- res = hx509_crypto_encrypt(crypto, +- to_encrypt->data, +- to_encrypt->length, +- &ivos, +- &encrypted); +- if (res) { +- torture_comment(tctx, "error while encrypting\n"); +- hx509_crypto_destroy(crypto); +- hx509_context_free(&hctx); +- return NULL; +- } +- +- *blob = data_blob_talloc(blob, encrypted->data, encrypted->length); +- der_free_octet_string(encrypted); +- free(encrypted); +- hx509_crypto_destroy(crypto); +- hx509_context_free(&hctx); +- return blob; +-} +- +-/* +- * Certs used for this protocol have a GUID in the issuer_uniq_id field. +- * This function fetch it. +- */ +-static struct GUID *get_cert_guid(struct torture_context *tctx, +- TALLOC_CTX *mem_ctx, +- uint8_t *cert_data, +- uint32_t cert_len) +-{ +- hx509_context hctx; +- hx509_cert cert; +- heim_bit_string issuer_unique_id; +- DATA_BLOB data; +- int hret; +- uint32_t size; +- struct GUID *guid = talloc_zero(mem_ctx, struct GUID); +- NTSTATUS status; +- +- hx509_context_init(&hctx); +- +- hret = hx509_cert_init_data(hctx, cert_data, cert_len, &cert); +- if (hret) { +- torture_comment(tctx, "error while loading the cert\n"); +- hx509_context_free(&hctx); +- return NULL; +- } +- hret = hx509_cert_get_issuer_unique_id(hctx, cert, &issuer_unique_id); +- if (hret) { +- torture_comment(tctx, "error while getting the issuer_uniq_id\n"); +- hx509_cert_free(cert); +- hx509_context_free(&hctx); +- return NULL; +- } +- +- /* The issuer_unique_id is a bit string, +- * which means that the real size has to be divided by 8 +- * to have the number of bytes +- */ +- hx509_cert_free(cert); +- hx509_context_free(&hctx); +- size = issuer_unique_id.length / 8; +- data = data_blob_const(issuer_unique_id.data, size); +- +- status = GUID_from_data_blob(&data, guid); +- der_free_bit_string(&issuer_unique_id); +- if (!NT_STATUS_IS_OK(status)) { +- return NULL; +- } +- +- return guid; +-} +- +-/* +- * Encrypt a blob with the private key of the certificate +- * passed as a parameter. +- */ +-static DATA_BLOB *encrypt_blob_pk(struct torture_context *tctx, +- TALLOC_CTX *mem_ctx, +- uint8_t *cert_data, +- uint32_t cert_len, +- DATA_BLOB *to_encrypt) +-{ +- hx509_context hctx; +- hx509_cert cert; +- heim_octet_string secretdata; +- heim_octet_string encrypted; +- heim_oid encryption_oid; +- DATA_BLOB *blob; +- int hret; +- +- hx509_context_init(&hctx); +- +- hret = hx509_cert_init_data(hctx, cert_data, cert_len, &cert); +- if (hret) { +- torture_comment(tctx, "error while loading the cert\n"); +- hx509_context_free(&hctx); +- return NULL; +- } +- +- secretdata.data = to_encrypt->data; +- secretdata.length = to_encrypt->length; +- hret = hx509_cert_public_encrypt(hctx, &secretdata, +- cert, &encryption_oid, +- &encrypted); +- hx509_cert_free(cert); +- hx509_context_free(&hctx); +- if (hret) { +- torture_comment(tctx, "error while encrypting\n"); +- return NULL; +- } +- +- blob = talloc_zero(mem_ctx, DATA_BLOB); +- if (blob == NULL) { +- der_free_oid(&encryption_oid); +- der_free_octet_string(&encrypted); +- return NULL; +- } +- +- *blob = data_blob_talloc(blob, encrypted.data, encrypted.length); +- der_free_octet_string(&encrypted); +- der_free_oid(&encryption_oid); +- if (blob->data == NULL) { +- return NULL; +- } +- +- return blob; +-} +- +- +-static struct bkrp_BackupKey *createRetrieveBackupKeyGUIDStruct(struct torture_context *tctx, +- struct dcerpc_pipe *p, int version, DATA_BLOB *out) +-{ +- struct dcerpc_binding *binding; +- struct bkrp_client_side_wrapped data; +- struct GUID *g = talloc(tctx, struct GUID); +- struct bkrp_BackupKey *r = talloc_zero(tctx, struct bkrp_BackupKey); +- enum ndr_err_code ndr_err; +- DATA_BLOB blob; +- NTSTATUS status; +- +- if (r == NULL) { +- return NULL; +- } +- +- binding = dcerpc_binding_dup(tctx, p->binding); +- if (binding == NULL) { +- return NULL; +- } +- +- status = dcerpc_binding_set_flags(binding, DCERPC_SEAL|DCERPC_AUTH_SPNEGO, 0); +- if (!NT_STATUS_IS_OK(status)) { +- return NULL; +- } +- +- ZERO_STRUCT(data); +- status = GUID_from_string(BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID, g); +- if (!NT_STATUS_IS_OK(status)) { +- return NULL; +- } +- +- r->in.guidActionAgent = g; +- data.version = version; +- ndr_err = ndr_push_struct_blob(&blob, tctx, &data, +- (ndr_push_flags_fn_t)ndr_push_bkrp_client_side_wrapped); +- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { +- return NULL; +- } +- r->in.data_in = blob.data; +- r->in.data_in_len = blob.length; +- r->out.data_out = &out->data; +- r->out.data_out_len = talloc(r, uint32_t); +- return r; +-} +- +-static struct bkrp_BackupKey *createRestoreGUIDStruct(struct torture_context *tctx, +- struct dcerpc_pipe *p, int version, DATA_BLOB *out, +- bool norevert, +- bool broken_version, +- bool broken_user, +- bool broken_magic_secret, +- bool broken_magic_access, +- bool broken_hash_access, +- bool broken_cert_guid) +-{ +- struct dcerpc_binding_handle *b = p->binding_handle; +- struct bkrp_client_side_wrapped data; +- DATA_BLOB *xs; +- DATA_BLOB *sec; +- DATA_BLOB *enc_sec = NULL; +- DATA_BLOB *enc_xs = NULL; +- DATA_BLOB *blob2; +- DATA_BLOB enc_sec_reverted; +- DATA_BLOB des3_key; +- DATA_BLOB aes_key; +- DATA_BLOB iv; +- DATA_BLOB out_blob; +- struct GUID *guid, *g; +- int t; +- uint32_t size; +- enum ndr_err_code ndr_err; +- NTSTATUS status; +- const char *user; +- struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, version, &out_blob); +- if (r == NULL) { +- return NULL; +- } +- +- if (broken_user) { +- /* we take a fake user*/ +- user = "guest"; +- } else { +- user = cli_credentials_get_username( +- popt_get_cmdline_credentials()); +- } +- +- +- torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), +- "Get GUID"); +- torture_assert_werr_ok(tctx, r->out.result, +- "Get GUID"); +- +- /* +- * We have to set it outside of the function createRetrieveBackupKeyGUIDStruct +- * the len of the blob, this is due to the fact that they don't have the +- * same size (one is 32bits the other 64bits) +- */ +- out_blob.length = *r->out.data_out_len; +- +- sec = create_unencryptedsecret(tctx, broken_magic_secret, version); +- if (sec == NULL) { +- return NULL; +- } +- +- xs = create_access_check(tctx, p, tctx, user, broken_hash_access, version); +- if (xs == NULL) { +- return NULL; +- } +- +- if (broken_magic_access){ +- /* The start of the access_check structure contains the +- * GUID of the certificate +- */ +- xs->data[0]++; +- } +- +- enc_sec = encrypt_blob_pk(tctx, tctx, out_blob.data, out_blob.length, sec); +- if (!enc_sec) { +- return NULL; +- } +- enc_sec_reverted.data = talloc_array(tctx, uint8_t, enc_sec->length); +- if (enc_sec_reverted.data == NULL) { +- return NULL; +- } +- enc_sec_reverted.length = enc_sec->length; +- +- /* +- * We DO NOT revert the array on purpose it's in order to check that +- * when the server is not able to decrypt then it answer the correct error +- */ +- if (norevert) { +- for(t=0; t< enc_sec->length; t++) { +- enc_sec_reverted.data[t] = ((uint8_t*)enc_sec->data)[t]; +- } +- } else { +- for(t=0; t< enc_sec->length; t++) { +- enc_sec_reverted.data[t] = ((uint8_t*)enc_sec->data)[enc_sec->length - t -1]; +- } +- } +- +- size = sec->length; +- if (version ==2) { +- const AlgorithmIdentifier *alg = hx509_crypto_des_rsdi_ede3_cbc(); +- iv.data = sec->data+(size - 8); +- iv.length = 8; +- +- des3_key.data = sec->data+(size - 32); +- des3_key.length = 24; +- +- enc_xs = encrypt_blob(tctx, tctx, &des3_key, &iv, xs, alg); +- } +- if (version == 3) { +- const AlgorithmIdentifier *alg = hx509_crypto_aes256_cbc(); +- iv.data = sec->data+(size-16); +- iv.length = 16; +- +- aes_key.data = sec->data+(size-48); +- aes_key.length = 32; +- +- enc_xs = encrypt_blob(tctx, tctx, &aes_key, &iv, xs, alg); +- } +- +- if (!enc_xs) { +- return NULL; +- } +- +- /* To cope with the fact that heimdal do padding at the end for the moment */ +- enc_xs->length = xs->length; +- +- guid = get_cert_guid(tctx, tctx, out_blob.data, out_blob.length); +- if (guid == NULL) { +- return NULL; +- } +- +- if (broken_version) { +- data.version = 1; +- } else { +- data.version = version; +- } +- +- data.guid = *guid; +- data.encrypted_secret = enc_sec_reverted.data; +- data.access_check = enc_xs->data; +- data.encrypted_secret_len = enc_sec->length; +- data.access_check_len = enc_xs->length; +- +- /* We want the blob to persist after this function so we don't +- * allocate it in the stack +- */ +- blob2 = talloc(tctx, DATA_BLOB); +- if (blob2 == NULL) { +- return NULL; +- } +- +- ndr_err = ndr_push_struct_blob(blob2, tctx, &data, +- (ndr_push_flags_fn_t)ndr_push_bkrp_client_side_wrapped); +- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { +- return NULL; +- } +- +- if (broken_cert_guid) { +- blob2->data[12]++; +- } +- +- ZERO_STRUCT(*r); +- +- g = talloc(tctx, struct GUID); +- if (g == NULL) { +- return NULL; +- } +- +- status = GUID_from_string(BACKUPKEY_RESTORE_GUID, g); +- if (!NT_STATUS_IS_OK(status)) { +- return NULL; +- } +- +- r->in.guidActionAgent = g; +- r->in.data_in = blob2->data; +- r->in.data_in_len = blob2->length; +- r->in.param = 0; +- r->out.data_out = &(out->data); +- r->out.data_out_len = talloc(r, uint32_t); +- return r; +-} +- +-/* Check that we are able to receive the certificate of the DCs +- * used for client wrap version of the backup key protocol +- */ +-static bool test_RetrieveBackupKeyGUID(struct torture_context *tctx, +- struct dcerpc_pipe *p) +-{ +- struct dcerpc_binding_handle *b = p->binding_handle; +- DATA_BLOB out_blob; +- struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob); +- enum dcerpc_AuthType auth_type; +- enum dcerpc_AuthLevel auth_level; +- +- if (r == NULL) { +- return false; +- } +- +- dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level); +- +- if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { +- torture_assert_ntstatus_ok(tctx, +- dcerpc_bkrp_BackupKey_r(b, tctx, r), +- "Get GUID"); +- +- out_blob.length = *r->out.data_out_len; +- torture_assert_werr_equal(tctx, +- r->out.result, +- WERR_OK, +- "Wrong dce/rpc error code"); +- } else { +- torture_assert_ntstatus_equal(tctx, +- dcerpc_bkrp_BackupKey_r(b, tctx, r), +- NT_STATUS_ACCESS_DENIED, +- "Get GUID"); +- } +- return true; +-} +- +-/* Test to check the failure to recover a secret because the +- * secret blob is not reversed +- */ +-static bool test_RestoreGUID_ko(struct torture_context *tctx, +- struct dcerpc_pipe *p) +-{ +- enum ndr_err_code ndr_err; +- struct dcerpc_binding_handle *b = p->binding_handle; +- DATA_BLOB out_blob; +- struct bkrp_client_side_unwrapped resp; +- enum dcerpc_AuthType auth_type; +- enum dcerpc_AuthLevel auth_level; +- +- dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level); +- +- if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { +- struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 2, &out_blob, +- true, false, false, false, false, false, false); +- torture_assert(tctx, r != NULL, "createRestoreGUIDStruct failed"); +- torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID"); +- out_blob.length = *r->out.data_out_len; +- ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped); +- torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 0, "Unable to unmarshall bkrp_client_side_unwrapped"); +- if (!W_ERROR_EQUAL(r->out.result, WERR_INVALID_PARAMETER)) { +- torture_assert_werr_equal(tctx, r->out.result, +- WERR_INVALID_DATA, +- "Wrong error code"); +- } +- } else { +- struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob); +- torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), +- NT_STATUS_ACCESS_DENIED, "Get GUID"); +- } +- return true; +-} +- +-static bool test_RestoreGUID_wrongversion(struct torture_context *tctx, +- struct dcerpc_pipe *p) +-{ +- enum ndr_err_code ndr_err; +- struct dcerpc_binding_handle *b = p->binding_handle; +- DATA_BLOB out_blob; +- struct bkrp_client_side_unwrapped resp; +- enum dcerpc_AuthType auth_type; +- enum dcerpc_AuthLevel auth_level; +- +- dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level); +- +- if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { +- struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 2, &out_blob, +- false, true, false, false, false, false, false); +- torture_assert(tctx, r != NULL, "createRestoreGUIDStruct failed"); +- torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID"); +- out_blob.length = *r->out.data_out_len; +- ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped); +- torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 0, "Unable to unmarshall bkrp_client_side_unwrapped"); +- torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_PARAMETER, "Wrong error code on wrong version"); +- } else { +- struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob); +- torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), +- NT_STATUS_ACCESS_DENIED, "Get GUID"); +- } +- return true; +-} +- +-static bool test_RestoreGUID_wronguser(struct torture_context *tctx, +- struct dcerpc_pipe *p) +-{ +- enum ndr_err_code ndr_err; +- struct dcerpc_binding_handle *b = p->binding_handle; +- DATA_BLOB out_blob; +- struct bkrp_client_side_unwrapped resp; +- enum dcerpc_AuthType auth_type; +- enum dcerpc_AuthLevel auth_level; +- +- dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level); +- +- if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { +- struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 2, &out_blob, +- false, false, true, false, false, false, false); +- torture_assert(tctx, r != NULL, "createRestoreGUIDStruct failed"); +- torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID"); +- out_blob.length = *r->out.data_out_len; +- ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped); +- torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 0, "Unable to unmarshall bkrp_client_side_unwrapped"); +- torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_ACCESS, "Restore GUID"); +- } else { +- struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob); +- torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), +- NT_STATUS_ACCESS_DENIED, "Get GUID"); +- } +- return true; +-} +- +-static bool test_RestoreGUID_v3(struct torture_context *tctx, +- struct dcerpc_pipe *p) +-{ +- enum ndr_err_code ndr_err; +- struct dcerpc_binding_handle *b = p->binding_handle; +- DATA_BLOB out_blob; +- struct bkrp_client_side_unwrapped resp; +- enum dcerpc_AuthType auth_type; +- enum dcerpc_AuthLevel auth_level; +- +- dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level); +- +- if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { +- struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 3, &out_blob, +- false, false, false, false, false, false, false); +- torture_assert(tctx, r != NULL, "createRestoreGUIDStruct failed"); +- torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID"); +- out_blob.length = *r->out.data_out_len; +- ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped); +- torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 1, "Unable to unmarshall bkrp_client_side_unwrapped"); +- torture_assert_werr_equal(tctx, r->out.result, WERR_OK, "Restore GUID"); +- torture_assert_str_equal(tctx, (char*)resp.secret.data, secret, "Wrong secret"); +- } else { +- struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob); +- torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), +- NT_STATUS_ACCESS_DENIED, "Get GUID"); +- } +- return true; +-} +- +-static bool test_RestoreGUID(struct torture_context *tctx, +- struct dcerpc_pipe *p) +-{ +- struct dcerpc_binding_handle *b = p->binding_handle; +- DATA_BLOB out_blob; +- struct bkrp_client_side_unwrapped resp; +- enum dcerpc_AuthType auth_type; +- enum dcerpc_AuthLevel auth_level; +- +- dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level); +- +- if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { +- struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 2, &out_blob, +- false, false, false, false, false, false, false); +- torture_assert(tctx, r != NULL, "createRestoreGUIDStruct failed"); +- torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID"); +- out_blob.length = *r->out.data_out_len; +- torture_assert_werr_equal(tctx, r->out.result, WERR_OK, "Restore GUID"); +- torture_assert_ndr_err_equal(tctx, +- ndr_pull_struct_blob(&out_blob, tctx, &resp, +- (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped), +- NDR_ERR_SUCCESS, +- "Unable to unmarshall bkrp_client_side_unwrapped"); +- torture_assert_str_equal(tctx, (char*)resp.secret.data, secret, "Wrong secret"); +- } else { +- struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob); +- torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), +- NT_STATUS_ACCESS_DENIED, "Get GUID"); +- } +- return true; +-} +- +-static bool test_RestoreGUID_badmagiconsecret(struct torture_context *tctx, +- struct dcerpc_pipe *p) +-{ +- enum ndr_err_code ndr_err; +- struct dcerpc_binding_handle *b = p->binding_handle; +- DATA_BLOB out_blob; +- struct bkrp_client_side_unwrapped resp; +- enum dcerpc_AuthType auth_type; +- enum dcerpc_AuthLevel auth_level; +- +- dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level); +- +- if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { +- struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 3, &out_blob, +- false, false, false, true, false, false, false); +- torture_assert(tctx, r != NULL, "createRestoreGUIDStruct failed"); +- torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID"); +- out_blob.length = *r->out.data_out_len; +- ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped); +- torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 0, "Unable to unmarshall bkrp_client_side_unwrapped"); +- torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_DATA, "Wrong error code while providing bad magic in secret"); +- } else { +- struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob); +- torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), +- NT_STATUS_ACCESS_DENIED, "Get GUID"); +- } +- return true; +-} +- +-static bool test_RestoreGUID_emptyrequest(struct torture_context *tctx, +- struct dcerpc_pipe *p) +-{ +- struct dcerpc_binding_handle *b = p->binding_handle; +- DATA_BLOB out_blob; +- enum dcerpc_AuthType auth_type; +- enum dcerpc_AuthLevel auth_level; +- +- dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level); +- +- if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { +- struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 3, &out_blob, +- false, false, false, true, false, false, true); +- +- torture_assert(tctx, r != NULL, "createRestoreGUIDStruct failed"); +- r->in.data_in = talloc(tctx, uint8_t); +- r->in.data_in_len = 0; +- r->in.param = 0; +- torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID"); +- out_blob.length = *r->out.data_out_len; +- torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_PARAMETER, "Bad error code on wrong has in access check"); +- } else { +- struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob); +- torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), +- NT_STATUS_ACCESS_DENIED, "Get GUID"); +- } +- return true; +-} +- +-static bool test_RestoreGUID_badcertguid(struct torture_context *tctx, +- struct dcerpc_pipe *p) +-{ +- enum ndr_err_code ndr_err; +- struct dcerpc_binding_handle *b = p->binding_handle; +- DATA_BLOB out_blob; +- struct bkrp_client_side_unwrapped resp; +- enum dcerpc_AuthType auth_type; +- enum dcerpc_AuthLevel auth_level; +- +- dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level); +- +- if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { +- struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 3, &out_blob, +- false, false, false, false, false, false, true); +- torture_assert(tctx, r != NULL, "createRestoreGUIDStruct() failed"); +- torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID"); +- out_blob.length = *r->out.data_out_len; +- ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped); +- torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 0, "Unable to unmarshall bkrp_client_side_unwrapped"); +- +- /* +- * Windows 2012R2 has, presumably, a programming error +- * returning an NTSTATUS code on this interface +- */ +- if (W_ERROR_V(r->out.result) != NT_STATUS_V(NT_STATUS_OBJECT_NAME_NOT_FOUND)) { +- torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_DATA, "Bad error code on wrong has in access check"); +- } +- } else { +- struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob); +- torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), +- NT_STATUS_ACCESS_DENIED, "Get GUID"); +- } +- return true; +-} +- +-static bool test_RestoreGUID_badmagicaccesscheck(struct torture_context *tctx, +- struct dcerpc_pipe *p) +-{ +- enum ndr_err_code ndr_err; +- struct dcerpc_binding_handle *b = p->binding_handle; +- DATA_BLOB out_blob; +- struct bkrp_client_side_unwrapped resp; +- enum dcerpc_AuthType auth_type; +- enum dcerpc_AuthLevel auth_level; +- +- dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level); +- +- if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { +- struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 2, &out_blob, +- false, false, false, false, true, false, false); +- torture_assert(tctx, r != NULL, "createRestoreGUIDStruct failed"); +- torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID"); +- out_blob.length = *r->out.data_out_len; +- ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped); +- torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 0, "Unable to unmarshall bkrp_client_side_unwrapped"); +- torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_DATA, "Bad error code on wrong has in access check"); +- } else { +- struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob); +- torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), +- NT_STATUS_ACCESS_DENIED, "Get GUID"); +- } +- return true; +-} +- +-static bool test_RestoreGUID_badhashaccesscheck(struct torture_context *tctx, +- struct dcerpc_pipe *p) +-{ +- enum ndr_err_code ndr_err; +- struct dcerpc_binding_handle *b = p->binding_handle; +- DATA_BLOB out_blob; +- struct bkrp_client_side_unwrapped resp; +- enum dcerpc_AuthType auth_type; +- enum dcerpc_AuthLevel auth_level; +- +- dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level); +- +- if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { +- struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 2, &out_blob, +- false, false, false, false, false, true, false); +- torture_assert(tctx, r != NULL, "createRestoreGUIDStruct failed"); +- torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID"); +- out_blob.length = *r->out.data_out_len; +- ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped); +- torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 0, "Unable to unmarshall bkrp_client_side_unwrapped"); +- torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_DATA, "Bad error code on wrong has in access check"); +- } else { +- struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob); +- torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), +- NT_STATUS_ACCESS_DENIED, "Get GUID"); +- } +- return true; +-} +- +-/* +- * Check that the RSA modulus in the certificate of the DCs has 2048 bits. +- */ +-static bool test_RetrieveBackupKeyGUID_2048bits(struct torture_context *tctx, +- struct dcerpc_pipe *p) +-{ +- struct dcerpc_binding_handle *b = p->binding_handle; +- DATA_BLOB out_blob; +- struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob); +- enum dcerpc_AuthType auth_type; +- enum dcerpc_AuthLevel auth_level; +- +- hx509_context hctx; +- int hret; +- hx509_cert cert; +- SubjectPublicKeyInfo spki; +- RSA *rsa; +- int RSA_returned_bits; +- +- torture_assert(tctx, r != NULL, "createRetrieveBackupKeyGUIDStruct failed"); +- +- hx509_context_init(&hctx); +- +- if (r == NULL) { +- return false; +- } +- +- dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level); +- +- if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { +- const unsigned char *spki_spk_data; +- torture_assert_ntstatus_ok(tctx, +- dcerpc_bkrp_BackupKey_r(b, tctx, r), +- "Get GUID"); +- +- torture_assert_werr_ok(tctx, r->out.result, +- "Get GUID"); +- +- out_blob.length = *r->out.data_out_len; +- +- hret = hx509_cert_init_data(hctx, out_blob.data, out_blob.length, &cert); +- torture_assert_int_equal(tctx, hret, 0, "hx509_cert_init_data failed"); +- +- hret = hx509_cert_get_SPKI(hctx, cert , &spki); +- torture_assert_int_equal(tctx, hret, 0, "hx509_cert_get_SPKI failed"); +- +- /* We must take a copy, as d2i_RSAPublicKey *changes* the input parameter */ +- spki_spk_data = spki.subjectPublicKey.data; +- rsa = d2i_RSAPublicKey(NULL, &spki_spk_data, spki.subjectPublicKey.length / 8); +- torture_assert_int_equal(tctx, rsa != NULL, 1, "d2i_RSAPublicKey failed"); +- +- RSA_returned_bits = BN_num_bits(rsa->n); +- torture_assert_int_equal(tctx, +- RSA_returned_bits, +- 2048, +- "RSA Key doesn't have 2048 bits"); +- +- RSA_free(rsa); +- +- /* +- * Because we prevented spki from being changed above, +- * we can now safely call this to free it +- */ +- free_SubjectPublicKeyInfo(&spki); +- hx509_cert_free(cert); +- hx509_context_free(&hctx); +- +- } else { +- torture_assert_ntstatus_equal(tctx, +- dcerpc_bkrp_BackupKey_r(b, tctx, r), +- NT_STATUS_ACCESS_DENIED, +- "Get GUID"); +- } +- return true; +-} +- +-static bool test_ServerWrap_encrypt_decrypt(struct torture_context *tctx, +- struct dcerpc_pipe *p) +-{ +- struct bkrp_BackupKey r; +- struct GUID guid; +- DATA_BLOB plaintext = data_blob_const(secret, sizeof(secret)); +- DATA_BLOB encrypted; +- uint32_t enclen; +- DATA_BLOB decrypted; +- uint32_t declen; +- struct dcerpc_binding_handle *b = p->binding_handle; +- enum dcerpc_AuthType auth_type; +- enum dcerpc_AuthLevel auth_level; +- ZERO_STRUCT(r); +- +- dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level); +- +- /* Encrypt */ +- torture_assert_ntstatus_ok(tctx, +- GUID_from_string(BACKUPKEY_BACKUP_GUID, &guid), +- "obtain GUID"); +- +- r.in.guidActionAgent = &guid; +- r.in.data_in = plaintext.data; +- r.in.data_in_len = plaintext.length; +- r.in.param = 0; +- r.out.data_out = &encrypted.data; +- r.out.data_out_len = &enclen; +- if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { +- torture_assert_ntstatus_ok(tctx, +- dcerpc_bkrp_BackupKey_r(b, tctx, &r), +- "encrypt"); +- } else { +- torture_assert_ntstatus_equal(tctx, +- dcerpc_bkrp_BackupKey_r(b, tctx, &r), +- NT_STATUS_ACCESS_DENIED, +- "encrypt"); +- return true; +- } +- torture_assert_werr_ok(tctx, +- r.out.result, +- "encrypt"); +- encrypted.length = *r.out.data_out_len; +- +- /* Decrypt */ +- torture_assert_ntstatus_ok(tctx, +- GUID_from_string(BACKUPKEY_RESTORE_GUID, &guid), +- "obtain GUID"); +- +- r.in.guidActionAgent = &guid; +- r.in.data_in = encrypted.data; +- r.in.data_in_len = encrypted.length; +- r.in.param = 0; +- r.out.data_out = &(decrypted.data); +- r.out.data_out_len = &declen; +- torture_assert_ntstatus_ok(tctx, +- dcerpc_bkrp_BackupKey_r(b, tctx, &r), +- "decrypt"); +- torture_assert_werr_ok(tctx, +- r.out.result, +- "decrypt"); +- decrypted.length = *r.out.data_out_len; +- +- /* Compare */ +- torture_assert_data_blob_equal(tctx, plaintext, decrypted, "Decrypt failed"); +- +- /* Decrypt */ +- torture_assert_ntstatus_ok(tctx, +- GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K, &guid), +- "obtain GUID"); +- +- r.in.guidActionAgent = &guid; +- r.in.data_in = encrypted.data; +- r.in.data_in_len = encrypted.length; +- r.in.param = 0; +- r.out.data_out = &(decrypted.data); +- r.out.data_out_len = &declen; +- torture_assert_ntstatus_ok(tctx, +- dcerpc_bkrp_BackupKey_r(b, tctx, &r), +- "decrypt"); +- torture_assert_werr_ok(tctx, +- r.out.result, +- "decrypt"); +- decrypted.length = *r.out.data_out_len; +- +- /* Compare */ +- torture_assert_data_blob_equal(tctx, plaintext, decrypted, "Decrypt failed"); +- return true; +-} +- +-static bool test_ServerWrap_decrypt_wrong_keyGUID(struct torture_context *tctx, +- struct dcerpc_pipe *p) +-{ +- struct bkrp_BackupKey r; +- struct GUID guid; +- DATA_BLOB plaintext = data_blob_const(secret, sizeof(secret)); +- DATA_BLOB encrypted; +- uint32_t enclen; +- DATA_BLOB decrypted; +- uint32_t declen; +- struct dcerpc_binding_handle *b = p->binding_handle; +- enum ndr_err_code ndr_err; +- struct bkrp_server_side_wrapped server_side_wrapped; +- enum dcerpc_AuthType auth_type; +- enum dcerpc_AuthLevel auth_level; +- ZERO_STRUCT(r); +- +- dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level); +- +- /* Encrypt */ +- torture_assert_ntstatus_ok(tctx, +- GUID_from_string(BACKUPKEY_BACKUP_GUID, &guid), +- "obtain GUID"); +- +- r.in.guidActionAgent = &guid; +- r.in.data_in = plaintext.data; +- r.in.data_in_len = plaintext.length; +- r.in.param = 0; +- r.out.data_out = &encrypted.data; +- r.out.data_out_len = &enclen; +- if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { +- torture_assert_ntstatus_ok(tctx, +- dcerpc_bkrp_BackupKey_r(b, tctx, &r), +- "encrypt"); +- } else { +- torture_assert_ntstatus_equal(tctx, +- dcerpc_bkrp_BackupKey_r(b, tctx, &r), +- NT_STATUS_ACCESS_DENIED, +- "encrypt"); +- return true; +- } +- torture_assert_werr_ok(tctx, +- r.out.result, +- "encrypt"); +- encrypted.length = *r.out.data_out_len; +- +- ndr_err = ndr_pull_struct_blob(&encrypted, tctx, &server_side_wrapped, +- (ndr_pull_flags_fn_t)ndr_pull_bkrp_server_side_wrapped); +- torture_assert_ndr_err_equal(tctx, ndr_err, NDR_ERR_SUCCESS, "pull of server_side_wrapped"); +- +- /* Change the GUID */ +- server_side_wrapped.guid = GUID_random(); +- +- ndr_err = ndr_push_struct_blob(&encrypted, tctx, &server_side_wrapped, +- (ndr_push_flags_fn_t)ndr_push_bkrp_server_side_wrapped); +- torture_assert_ndr_err_equal(tctx, ndr_err, NDR_ERR_SUCCESS, "push of server_side_wrapped"); +- +- /* Decrypt */ +- torture_assert_ntstatus_ok(tctx, +- GUID_from_string(BACKUPKEY_RESTORE_GUID, &guid), +- "obtain GUID"); +- +- r.in.guidActionAgent = &guid; +- r.in.data_in = encrypted.data; +- r.in.data_in_len = encrypted.length; +- r.in.param = 0; +- r.out.data_out = &(decrypted.data); +- r.out.data_out_len = &declen; +- torture_assert_ntstatus_ok(tctx, +- dcerpc_bkrp_BackupKey_r(b, tctx, &r), +- "decrypt"); +- torture_assert_werr_equal(tctx, +- r.out.result, +- WERR_INVALID_DATA, +- "decrypt should fail with WERR_INVALID_DATA"); +- +- /* Decrypt */ +- torture_assert_ntstatus_ok(tctx, +- GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K, &guid), +- "obtain GUID"); +- +- r.in.guidActionAgent = &guid; +- r.in.data_in = encrypted.data; +- r.in.data_in_len = encrypted.length; +- r.in.param = 0; +- r.out.data_out = &(decrypted.data); +- r.out.data_out_len = &declen; +- torture_assert_ntstatus_ok(tctx, +- dcerpc_bkrp_BackupKey_r(b, tctx, &r), +- "decrypt"); +- torture_assert_werr_equal(tctx, +- r.out.result, +- WERR_INVALID_DATA, +- "decrypt should fail with WERR_INVALID_DATA"); +- +- return true; +-} +- +-static bool test_ServerWrap_decrypt_empty_request(struct torture_context *tctx, +- struct dcerpc_pipe *p) +-{ +- struct bkrp_BackupKey r; +- struct GUID guid; +- DATA_BLOB decrypted; +- uint32_t declen; +- struct dcerpc_binding_handle *b = p->binding_handle; +- uint8_t short_request[4] = { 1, 0, 0, 0 }; +- enum dcerpc_AuthType auth_type; +- enum dcerpc_AuthLevel auth_level; +- ZERO_STRUCT(r); +- +- dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level); +- +- /* Decrypt */ +- torture_assert_ntstatus_ok(tctx, +- GUID_from_string(BACKUPKEY_RESTORE_GUID, &guid), +- "obtain GUID"); +- +- r.in.guidActionAgent = &guid; +- r.in.data_in = short_request; +- r.in.data_in_len = 0; +- r.in.param = 0; +- r.out.data_out = &(decrypted.data); +- r.out.data_out_len = &declen; +- if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { +- torture_assert_ntstatus_ok(tctx, +- dcerpc_bkrp_BackupKey_r(b, tctx, &r), +- "encrypt"); +- } else { +- torture_assert_ntstatus_equal(tctx, +- dcerpc_bkrp_BackupKey_r(b, tctx, &r), +- NT_STATUS_ACCESS_DENIED, +- "encrypt"); +- return true; +- } +- torture_assert_werr_equal(tctx, +- r.out.result, +- WERR_INVALID_PARAMETER, +- "decrypt should fail with WERR_INVALID_PARAMETER"); +- +- /* Decrypt */ +- torture_assert_ntstatus_ok(tctx, +- GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K, &guid), +- "obtain GUID"); +- +- r.in.guidActionAgent = &guid; +- r.in.data_in = short_request; +- r.in.data_in_len = 0; +- r.in.param = 0; +- r.out.data_out = &(decrypted.data); +- r.out.data_out_len = &declen; +- torture_assert_ntstatus_ok(tctx, +- dcerpc_bkrp_BackupKey_r(b, tctx, &r), +- "decrypt"); +- torture_assert_werr_equal(tctx, +- r.out.result, +- WERR_INVALID_PARAMETER, +- "decrypt should fail with WERR_INVALID_PARAMETER"); +- +- /* Decrypt */ +- torture_assert_ntstatus_ok(tctx, +- GUID_from_string(BACKUPKEY_RESTORE_GUID, &guid), +- "obtain GUID"); +- +- r.in.guidActionAgent = &guid; +- r.in.data_in = NULL; +- r.in.data_in_len = 0; +- r.in.param = 0; +- r.out.data_out = &(decrypted.data); +- r.out.data_out_len = &declen; +- torture_assert_ntstatus_equal(tctx, +- dcerpc_bkrp_BackupKey_r(b, tctx, &r), +- NT_STATUS_INVALID_PARAMETER_MIX, +- "decrypt"); +- +- /* Decrypt */ +- torture_assert_ntstatus_ok(tctx, +- GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K, &guid), +- "obtain GUID"); +- +- r.in.guidActionAgent = &guid; +- r.in.data_in = NULL; +- r.in.data_in_len = 0; +- r.in.param = 0; +- r.out.data_out = &(decrypted.data); +- r.out.data_out_len = &declen; +- torture_assert_ntstatus_equal(tctx, +- dcerpc_bkrp_BackupKey_r(b, tctx, &r), +- NT_STATUS_INVALID_PARAMETER_MIX, +- "decrypt"); +- +- return true; +-} +- +- +-static bool test_ServerWrap_decrypt_short_request(struct torture_context *tctx, +- struct dcerpc_pipe *p) +-{ +- struct bkrp_BackupKey r; +- struct GUID guid; +- DATA_BLOB decrypted; +- uint32_t declen; +- struct dcerpc_binding_handle *b = p->binding_handle; +- uint8_t short_request[4] = { 1, 0, 0, 0 }; +- enum dcerpc_AuthType auth_type; +- enum dcerpc_AuthLevel auth_level; +- ZERO_STRUCT(r); +- +- dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level); +- +- /* Decrypt */ +- torture_assert_ntstatus_ok(tctx, +- GUID_from_string(BACKUPKEY_RESTORE_GUID, &guid), +- "obtain GUID"); +- +- r.in.guidActionAgent = &guid; +- r.in.data_in = short_request; +- r.in.data_in_len = 4; +- r.in.param = 0; +- r.out.data_out = &(decrypted.data); +- r.out.data_out_len = &declen; +- if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { +- torture_assert_ntstatus_ok(tctx, +- dcerpc_bkrp_BackupKey_r(b, tctx, &r), +- "encrypt"); +- } else { +- torture_assert_ntstatus_equal(tctx, +- dcerpc_bkrp_BackupKey_r(b, tctx, &r), +- NT_STATUS_ACCESS_DENIED, +- "encrypt"); +- return true; +- } +- torture_assert_werr_equal(tctx, +- r.out.result, +- WERR_INVALID_PARAMETER, +- "decrypt should fail with WERR_INVALID_PARAMETER"); +- +- /* Decrypt */ +- torture_assert_ntstatus_ok(tctx, +- GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K, &guid), +- "obtain GUID"); +- +- r.in.guidActionAgent = &guid; +- r.in.data_in = short_request; +- r.in.data_in_len = 4; +- r.in.param = 0; +- r.out.data_out = &(decrypted.data); +- r.out.data_out_len = &declen; +- torture_assert_ntstatus_ok(tctx, +- dcerpc_bkrp_BackupKey_r(b, tctx, &r), +- "decrypt"); +- torture_assert_werr_equal(tctx, +- r.out.result, +- WERR_INVALID_PARAMETER, +- "decrypt should fail with WERR_INVALID_PARAMETER"); +- +- /* Decrypt */ +- torture_assert_ntstatus_ok(tctx, +- GUID_from_string(BACKUPKEY_RESTORE_GUID, &guid), +- "obtain GUID"); +- +- r.in.guidActionAgent = &guid; +- r.in.data_in = short_request; +- r.in.data_in_len = 1; +- r.in.param = 0; +- r.out.data_out = &(decrypted.data); +- r.out.data_out_len = &declen; +- torture_assert_ntstatus_ok(tctx, +- dcerpc_bkrp_BackupKey_r(b, tctx, &r), +- "decrypt"); +- torture_assert_werr_equal(tctx, +- r.out.result, +- WERR_INVALID_PARAMETER, +- "decrypt should fail with WERR_INVALID_PARAMETER"); +- +- /* Decrypt */ +- torture_assert_ntstatus_ok(tctx, +- GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K, &guid), +- "obtain GUID"); +- +- r.in.guidActionAgent = &guid; +- r.in.data_in = short_request; +- r.in.data_in_len = 1; +- r.in.param = 0; +- r.out.data_out = &(decrypted.data); +- r.out.data_out_len = &declen; +- torture_assert_ntstatus_ok(tctx, +- dcerpc_bkrp_BackupKey_r(b, tctx, &r), +- "decrypt"); +- torture_assert_werr_equal(tctx, +- r.out.result, +- WERR_INVALID_PARAMETER, +- "decrypt should fail with WERR_INVALID_PARAMETER"); +- +- return true; +-} +- +-static bool test_ServerWrap_encrypt_decrypt_manual(struct torture_context *tctx, +- struct bkrp_server_side_wrapped *server_side_wrapped, +- enum test_wrong wrong) +-{ +- char *lsa_binding_string = NULL; +- struct dcerpc_binding *lsa_binding = NULL; +- struct dcerpc_pipe *lsa_p = NULL; +- struct dcerpc_binding_handle *lsa_b = NULL; +- struct lsa_OpenSecret r_secret; +- struct lsa_QuerySecret r_query_secret; +- struct policy_handle *handle, sec_handle; +- struct bkrp_BackupKey r; +- struct GUID preferred_key_guid; +- DATA_BLOB plaintext = data_blob_const(secret, sizeof(secret)); +- DATA_BLOB preferred_key, preferred_key_clear, session_key, +- decrypt_key, decrypt_key_clear, encrypted_blob, symkey_blob, +- sid_blob; +- struct bkrp_dc_serverwrap_key server_key; +- struct lsa_DATA_BUF_PTR bufp1; +- char *key_guid_string; +- struct bkrp_rc4encryptedpayload rc4payload; +- struct dom_sid *caller_sid; +- uint8_t symkey[20]; /* SHA-1 hash len */ +- uint8_t mackey[20]; /* SHA-1 hash len */ +- uint8_t mac[20]; /* SHA-1 hash len */ +- unsigned int hash_len; +- HMAC_CTX ctx; +- ZERO_STRUCT(r); +- ZERO_STRUCT(r_secret); +- ZERO_STRUCT(r_query_secret); +- +- /* Now read BCKUPKEY_P and prove we can do a matching decrypt and encrypt */ +- +- /* lsa_OpenSecret only works with ncacn_np and AUTH_LEVEL_NONE */ +- lsa_binding_string = talloc_asprintf(tctx, "ncacn_np:%s", +- torture_setting_string(tctx, "host", NULL)); +- torture_assert(tctx, lsa_binding_string != NULL, "lsa_binding_string"); +- +- torture_assert_ntstatus_ok(tctx, +- dcerpc_parse_binding(tctx, lsa_binding_string, &lsa_binding), +- "Failed to parse dcerpc binding"); +- +- torture_assert_ntstatus_ok(tctx, +- dcerpc_pipe_connect_b(tctx, &lsa_p, +- lsa_binding, &ndr_table_lsarpc, +- popt_get_cmdline_credentials(), +- tctx->ev, tctx->lp_ctx), +- "Opening LSA pipe"); +- lsa_b = lsa_p->binding_handle; +- +- torture_assert(tctx, test_lsa_OpenPolicy2(lsa_b, tctx, &handle), "OpenPolicy failed"); +- r_secret.in.name.string = "G$BCKUPKEY_P"; +- +- r_secret.in.handle = handle; +- r_secret.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; +- r_secret.out.sec_handle = &sec_handle; +- +- torture_comment(tctx, "Testing OpenSecret\n"); +- +- torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenSecret_r(lsa_b, tctx, &r_secret), +- "OpenSecret failed"); +- torture_assert_ntstatus_ok(tctx, r_secret.out.result, +- "OpenSecret failed"); +- +- r_query_secret.in.sec_handle = &sec_handle; +- r_query_secret.in.new_val = &bufp1; +- bufp1.buf = NULL; +- +- torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecret_r(lsa_b, tctx, &r_query_secret), +- "QuerySecret failed"); +- torture_assert_ntstatus_ok(tctx, r_query_secret.out.result, +- "QuerySecret failed"); +- +- +- preferred_key.data = r_query_secret.out.new_val->buf->data; +- preferred_key.length = r_query_secret.out.new_val->buf->size; +- torture_assert_ntstatus_ok(tctx, dcerpc_fetch_session_key(lsa_p, &session_key), +- "dcerpc_fetch_session_key failed"); +- +- torture_assert_ntstatus_ok(tctx, +- sess_decrypt_blob(tctx, +- &preferred_key, &session_key, &preferred_key_clear), +- "sess_decrypt_blob failed"); +- +- torture_assert_ntstatus_ok(tctx, GUID_from_ndr_blob(&preferred_key_clear, &preferred_key_guid), +- "GUID parse failed"); +- +- torture_assert_guid_equal(tctx, server_side_wrapped->guid, +- preferred_key_guid, +- "GUID didn't match value pointed at by G$BCKUPKEY_P"); +- +- /* And read BCKUPKEY_ and get the actual key */ +- +- key_guid_string = GUID_string(tctx, &server_side_wrapped->guid); +- r_secret.in.name.string = talloc_asprintf(tctx, "G$BCKUPKEY_%s", key_guid_string); +- +- r_secret.in.handle = handle; +- r_secret.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; +- r_secret.out.sec_handle = &sec_handle; +- +- torture_comment(tctx, "Testing OpenSecret\n"); +- +- torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenSecret_r(lsa_b, tctx, &r_secret), +- "OpenSecret failed"); +- torture_assert_ntstatus_ok(tctx, r_secret.out.result, +- "OpenSecret failed"); +- +- r_query_secret.in.sec_handle = &sec_handle; +- r_query_secret.in.new_val = &bufp1; +- +- torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecret_r(lsa_b, tctx, &r_query_secret), +- "QuerySecret failed"); +- torture_assert_ntstatus_ok(tctx, r_query_secret.out.result, +- "QuerySecret failed"); +- +- +- decrypt_key.data = r_query_secret.out.new_val->buf->data; +- decrypt_key.length = r_query_secret.out.new_val->buf->size; +- +- torture_assert_ntstatus_ok(tctx, +- sess_decrypt_blob(tctx, +- &decrypt_key, &session_key, &decrypt_key_clear), +- "sess_decrypt_blob failed"); +- +- torture_assert_ndr_err_equal(tctx, ndr_pull_struct_blob(&decrypt_key_clear, tctx, &server_key, +- (ndr_pull_flags_fn_t)ndr_pull_bkrp_dc_serverwrap_key), +- NDR_ERR_SUCCESS, "Failed to parse server_key"); +- +- torture_assert_int_equal(tctx, server_key.magic, 1, "Failed to correctly decrypt server key"); +- +- /* +- * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1 +- * BACKUPKEY_BACKUP_GUID, it really is the whole key +- */ +- HMAC(EVP_sha1(), server_key.key, sizeof(server_key.key), +- server_side_wrapped->r2, sizeof(server_side_wrapped->r2), +- symkey, &hash_len); +- +- /* rc4 decrypt sid and secret using sym key */ +- symkey_blob = data_blob_const(symkey, sizeof(symkey)); +- +- encrypted_blob = data_blob_talloc(tctx, server_side_wrapped->rc4encryptedpayload, +- server_side_wrapped->ciphertext_length); +- +- arcfour_crypt_blob(encrypted_blob.data, encrypted_blob.length, &symkey_blob); +- +- torture_assert_ndr_err_equal(tctx, ndr_pull_struct_blob(&encrypted_blob, tctx, &rc4payload, +- (ndr_pull_flags_fn_t)ndr_pull_bkrp_rc4encryptedpayload), +- NDR_ERR_SUCCESS, "Failed to parse rc4encryptedpayload"); +- +- torture_assert_int_equal(tctx, rc4payload.secret_data.length, +- server_side_wrapped->payload_length, +- "length of decrypted payload not the length declared in surrounding structure"); +- +- /* +- * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1 +- * BACKUPKEY_BACKUP_GUID, it really is the whole key +- */ +- HMAC(EVP_sha1(), server_key.key, sizeof(server_key.key), +- rc4payload.r3, sizeof(rc4payload.r3), +- mackey, &hash_len); +- +- torture_assert_ndr_err_equal(tctx, ndr_push_struct_blob(&sid_blob, tctx, &rc4payload.sid, +- (ndr_push_flags_fn_t)ndr_push_dom_sid), +- NDR_ERR_SUCCESS, "unable to push SID"); +- +- HMAC_CTX_init(&ctx); +- HMAC_Init_ex(&ctx, mackey, hash_len, EVP_sha1(), NULL); +- /* SID field */ +- HMAC_Update(&ctx, sid_blob.data, sid_blob.length); +- /* Secret field */ +- HMAC_Update(&ctx, rc4payload.secret_data.data, rc4payload.secret_data.length); +- HMAC_Final(&ctx, mac, &hash_len); +- HMAC_CTX_cleanup(&ctx); +- +- torture_assert_mem_equal(tctx, mac, rc4payload.mac, sizeof(mac), "mac not correct"); +- torture_assert_int_equal(tctx, rc4payload.secret_data.length, +- plaintext.length, "decrypted data is not correct length"); +- torture_assert_mem_equal(tctx, rc4payload.secret_data.data, +- plaintext.data, plaintext.length, +- "decrypted data is not correct"); +- +- /* Not strictly correct all the time, but good enough for this test */ +- caller_sid = get_user_sid(tctx, tctx, +- cli_credentials_get_username( +- popt_get_cmdline_credentials())); +- +- torture_assert_sid_equal(tctx, &rc4payload.sid, caller_sid, "Secret saved with wrong SID"); +- +- +- /* RE-encrypt */ +- +- if (wrong == WRONG_SID) { +- rc4payload.sid.sub_auths[rc4payload.sid.num_auths - 1] = DOMAIN_RID_KRBTGT; +- } +- +- dump_data_pw("mackey: \n", mackey, sizeof(mackey)); +- +- torture_assert_ndr_err_equal(tctx, +- ndr_push_struct_blob(&sid_blob, tctx, &rc4payload.sid, +- (ndr_push_flags_fn_t)ndr_push_dom_sid), +- NDR_ERR_SUCCESS, +- "push of sid failed"); +- +- HMAC_CTX_init(&ctx); +- HMAC_Init_ex(&ctx, mackey, 20, EVP_sha1(), NULL); +- /* SID field */ +- HMAC_Update(&ctx, sid_blob.data, sid_blob.length); +- /* Secret field */ +- HMAC_Update(&ctx, rc4payload.secret_data.data, rc4payload.secret_data.length); +- HMAC_Final(&ctx, rc4payload.mac, &hash_len); +- HMAC_CTX_cleanup(&ctx); +- +- dump_data_pw("rc4payload.mac: \n", rc4payload.mac, sizeof(rc4payload.mac)); +- +- torture_assert_ndr_err_equal(tctx, +- ndr_push_struct_blob(&encrypted_blob, tctx, &rc4payload, +- (ndr_push_flags_fn_t)ndr_push_bkrp_rc4encryptedpayload), +- NDR_ERR_SUCCESS, +- "push of rc4payload failed"); +- +- if (wrong == WRONG_KEY) { +- symkey_blob.data[0] = 78; +- symkey_blob.data[1] = 78; +- symkey_blob.data[2] = 78; +- } +- +- /* rc4 encrypt sid and secret using sym key */ +- arcfour_crypt_blob(encrypted_blob.data, encrypted_blob.length, &symkey_blob); +- +- /* re-create server wrap structure */ +- +- torture_assert_int_equal(tctx, encrypted_blob.length, +- server_side_wrapped->ciphertext_length, +- "expected encrypted length not to change"); +- if (wrong == RIGHT_KEY) { +- torture_assert_mem_equal(tctx, server_side_wrapped->rc4encryptedpayload, +- encrypted_blob.data, +- encrypted_blob.length, +- "expected encrypted data not to change"); +- } +- +- server_side_wrapped->payload_length = rc4payload.secret_data.length; +- server_side_wrapped->ciphertext_length = encrypted_blob.length; +- server_side_wrapped->rc4encryptedpayload = encrypted_blob.data; +- +- return true; +-} +- +- +-static bool test_ServerWrap_decrypt_wrong_stuff(struct torture_context *tctx, +- struct dcerpc_pipe *p, +- enum test_wrong wrong) +-{ +- struct bkrp_BackupKey r; +- struct GUID guid; +- DATA_BLOB plaintext = data_blob_const(secret, sizeof(secret)); +- DATA_BLOB encrypted; +- uint32_t enclen; +- DATA_BLOB decrypted; +- uint32_t declen; +- struct dcerpc_binding_handle *b = p->binding_handle; +- enum ndr_err_code ndr_err; +- struct bkrp_server_side_wrapped server_side_wrapped; +- bool repush = false; +- enum dcerpc_AuthType auth_type; +- enum dcerpc_AuthLevel auth_level; +- ZERO_STRUCT(r); +- +- dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level); +- +- /* Encrypt */ +- torture_assert_ntstatus_ok(tctx, +- GUID_from_string(BACKUPKEY_BACKUP_GUID, &guid), +- "obtain GUID"); +- +- r.in.guidActionAgent = &guid; +- r.in.data_in = plaintext.data; +- r.in.data_in_len = plaintext.length; +- r.in.param = 0; +- r.out.data_out = &encrypted.data; +- r.out.data_out_len = &enclen; +- if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { +- torture_assert_ntstatus_ok(tctx, +- dcerpc_bkrp_BackupKey_r(b, tctx, &r), +- "encrypt"); +- } else { +- torture_assert_ntstatus_equal(tctx, +- dcerpc_bkrp_BackupKey_r(b, tctx, &r), +- NT_STATUS_ACCESS_DENIED, +- "encrypt"); +- return true; +- } +- torture_assert_werr_ok(tctx, +- r.out.result, +- "encrypt"); +- encrypted.length = *r.out.data_out_len; +- +- ndr_err = ndr_pull_struct_blob(&encrypted, tctx, &server_side_wrapped, +- (ndr_pull_flags_fn_t)ndr_pull_bkrp_server_side_wrapped); +- torture_assert_ndr_err_equal(tctx, ndr_err, NDR_ERR_SUCCESS, "pull of server_side_wrapped"); +- +- torture_assert_int_equal(tctx, server_side_wrapped.payload_length, plaintext.length, +- "wrong payload length"); +- +- switch (wrong) { +- case WRONG_MAGIC: +- /* Change the magic. Forced by our NDR layer, so do it raw */ +- SIVAL(encrypted.data, 0, 78); /* valid values are 1-3 */ +- break; +- case WRONG_R2: +- server_side_wrapped.r2[0] = 78; +- server_side_wrapped.r2[1] = 78; +- server_side_wrapped.r2[3] = 78; +- repush = true; +- break; +- case WRONG_PAYLOAD_LENGTH: +- server_side_wrapped.payload_length = UINT32_MAX - 8; +- repush = true; +- break; +- case WRONG_CIPHERTEXT_LENGTH: +- /* +- * Change the ciphertext len. We can't push this if +- * we have it wrong, so do it raw +- */ +- SIVAL(encrypted.data, 8, UINT32_MAX - 8); /* valid values are 1-3 */ +- break; +- case SHORT_PAYLOAD_LENGTH: +- server_side_wrapped.payload_length = server_side_wrapped.payload_length - 8; +- repush = true; +- break; +- case SHORT_CIPHERTEXT_LENGTH: +- /* +- * Change the ciphertext len. We can't push this if +- * we have it wrong, so do it raw +- */ +- SIVAL(encrypted.data, 8, server_side_wrapped.ciphertext_length - 8); /* valid values are 1-3 */ +- break; +- case ZERO_PAYLOAD_LENGTH: +- server_side_wrapped.payload_length = 0; +- repush = true; +- break; +- case ZERO_CIPHERTEXT_LENGTH: +- /* +- * Change the ciphertext len. We can't push this if +- * we have it wrong, so do it raw +- */ +- SIVAL(encrypted.data, 8, 0); /* valid values are 1-3 */ +- break; +- +- case RIGHT_KEY: +- case WRONG_KEY: +- case WRONG_SID: +- torture_assert(tctx, +- test_ServerWrap_encrypt_decrypt_manual(tctx, &server_side_wrapped, wrong), +- "test_ServerWrap_encrypt_decrypt_manual failed"); +- repush = true; +- break; +- } +- +- if (repush) { +- ndr_err = ndr_push_struct_blob(&encrypted, tctx, &server_side_wrapped, +- (ndr_push_flags_fn_t)ndr_push_bkrp_server_side_wrapped); +- torture_assert_ndr_err_equal(tctx, ndr_err, NDR_ERR_SUCCESS, "push of server_side_wrapped"); +- } +- +- /* Decrypt */ +- torture_assert_ntstatus_ok(tctx, +- GUID_from_string(BACKUPKEY_RESTORE_GUID, &guid), +- "obtain GUID"); +- +- r.in.guidActionAgent = &guid; +- r.in.data_in = encrypted.data; +- r.in.data_in_len = encrypted.length; +- r.in.param = 0; +- r.out.data_out = &(decrypted.data); +- r.out.data_out_len = &declen; +- torture_assert_ntstatus_ok(tctx, +- dcerpc_bkrp_BackupKey_r(b, tctx, &r), +- "decrypt"); +- +- if ((wrong == WRONG_R2 || wrong == WRONG_KEY) +- && W_ERROR_EQUAL(r.out.result, WERR_INVALID_SID)) { +- torture_assert_werr_equal(tctx, +- r.out.result, +- WERR_INVALID_SID, +- "decrypt should fail with WERR_INVALID_SID or WERR_INVALID_PARAMETER"); +- } else if (wrong == RIGHT_KEY) { +- torture_assert_werr_equal(tctx, +- r.out.result, +- WERR_OK, +- "decrypt should succeed!"); +- } else if (wrong == WRONG_SID) { +- torture_assert_werr_equal(tctx, +- r.out.result, +- WERR_INVALID_ACCESS, +- "decrypt should fail with WERR_INVALID_ACCESS"); +- } else { +- if (!W_ERROR_EQUAL(r.out.result, WERR_INVALID_PARAMETER)) { +- torture_assert_werr_equal(tctx, +- r.out.result, +- WERR_INVALID_ACCESS, +- "decrypt should fail with WERR_INVALID_ACCESS or WERR_INVALID_PARAMETER"); +- } +- } +- +- /* Decrypt */ +- torture_assert_ntstatus_ok(tctx, +- GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K, &guid), +- "obtain GUID"); +- +- r.in.guidActionAgent = &guid; +- r.in.data_in = encrypted.data; +- r.in.data_in_len = encrypted.length; +- r.in.param = 0; +- r.out.data_out = &(decrypted.data); +- r.out.data_out_len = &declen; +- torture_assert_ntstatus_ok(tctx, +- dcerpc_bkrp_BackupKey_r(b, tctx, &r), +- "decrypt"); +- +- if ((wrong == WRONG_R2 || wrong == WRONG_KEY) +- && W_ERROR_EQUAL(r.out.result, WERR_INVALID_SID)) { +- torture_assert_werr_equal(tctx, +- r.out.result, +- WERR_INVALID_SID, +- "decrypt should fail with WERR_INVALID_SID or WERR_INVALID_PARAMETER"); +- } else if (wrong == RIGHT_KEY) { +- torture_assert_werr_equal(tctx, +- r.out.result, +- WERR_OK, +- "decrypt should succeed!"); +- } else if (wrong == WRONG_SID) { +- torture_assert_werr_equal(tctx, +- r.out.result, +- WERR_INVALID_ACCESS, +- "decrypt should fail with WERR_INVALID_ACCESS"); +- } else { +- if (!W_ERROR_EQUAL(r.out.result, WERR_INVALID_ACCESS) +- && !W_ERROR_EQUAL(r.out.result, WERR_INVALID_PARAMETER)) { +- torture_assert_werr_equal(tctx, r.out.result, +- WERR_INVALID_DATA, +- "decrypt should fail with WERR_INVALID_ACCESS, WERR_INVALID_PARAMETER or WERR_INVALID_DATA"); +- } +- } +- +- return true; +-} +- +-static bool test_ServerWrap_decrypt_wrong_magic(struct torture_context *tctx, +- struct dcerpc_pipe *p) +-{ +- return test_ServerWrap_decrypt_wrong_stuff(tctx, p, WRONG_MAGIC); +-} +- +-static bool test_ServerWrap_decrypt_wrong_r2(struct torture_context *tctx, +- struct dcerpc_pipe *p) +-{ +- return test_ServerWrap_decrypt_wrong_stuff(tctx, p, WRONG_R2); +-} +- +-static bool test_ServerWrap_decrypt_wrong_payload_length(struct torture_context *tctx, +- struct dcerpc_pipe *p) +-{ +- return test_ServerWrap_decrypt_wrong_stuff(tctx, p, WRONG_PAYLOAD_LENGTH); +-} +- +-static bool test_ServerWrap_decrypt_short_payload_length(struct torture_context *tctx, +- struct dcerpc_pipe *p) +-{ +- return test_ServerWrap_decrypt_wrong_stuff(tctx, p, SHORT_PAYLOAD_LENGTH); +-} +- +-static bool test_ServerWrap_decrypt_zero_payload_length(struct torture_context *tctx, +- struct dcerpc_pipe *p) +-{ +- return test_ServerWrap_decrypt_wrong_stuff(tctx, p, ZERO_PAYLOAD_LENGTH); +-} +- +-static bool test_ServerWrap_decrypt_wrong_ciphertext_length(struct torture_context *tctx, +- struct dcerpc_pipe *p) +-{ +- return test_ServerWrap_decrypt_wrong_stuff(tctx, p, WRONG_CIPHERTEXT_LENGTH); +-} +- +-static bool test_ServerWrap_decrypt_short_ciphertext_length(struct torture_context *tctx, +- struct dcerpc_pipe *p) +-{ +- return test_ServerWrap_decrypt_wrong_stuff(tctx, p, SHORT_CIPHERTEXT_LENGTH); +-} +- +-static bool test_ServerWrap_decrypt_zero_ciphertext_length(struct torture_context *tctx, +- struct dcerpc_pipe *p) +-{ +- return test_ServerWrap_decrypt_wrong_stuff(tctx, p, ZERO_CIPHERTEXT_LENGTH); +-} +- +-static bool test_ServerWrap_encrypt_decrypt_remote_key(struct torture_context *tctx, +- struct dcerpc_pipe *p) +-{ +- return test_ServerWrap_decrypt_wrong_stuff(tctx, p, RIGHT_KEY); +-} +- +-static bool test_ServerWrap_encrypt_decrypt_wrong_key(struct torture_context *tctx, +- struct dcerpc_pipe *p) +-{ +- return test_ServerWrap_decrypt_wrong_stuff(tctx, p, WRONG_KEY); +-} +- +-static bool test_ServerWrap_encrypt_decrypt_wrong_sid(struct torture_context *tctx, +- struct dcerpc_pipe *p) +-{ +- return test_ServerWrap_decrypt_wrong_stuff(tctx, p, WRONG_SID); +-} +- +-struct torture_suite *torture_rpc_backupkey(TALLOC_CTX *mem_ctx) +-{ +- struct torture_suite *suite = torture_suite_create(mem_ctx, "backupkey"); +- +- struct torture_rpc_tcase *tcase; +- +- tcase = torture_suite_add_rpc_iface_tcase(suite, "backupkey", +- &ndr_table_backupkey); +- +- torture_rpc_tcase_add_test(tcase, "retreive_backup_key_guid", +- test_RetrieveBackupKeyGUID); +- +- torture_rpc_tcase_add_test(tcase, "restore_guid", +- test_RestoreGUID); +- +- torture_rpc_tcase_add_test(tcase, "restore_guid version 3", +- test_RestoreGUID_v3); +- +-/* We double the test in order to be sure that we don't mess stuff (ie. freeing static stuff) */ +- +- torture_rpc_tcase_add_test(tcase, "restore_guid_2nd", +- test_RestoreGUID); +- +- torture_rpc_tcase_add_test(tcase, "unable_to_decrypt_secret", +- test_RestoreGUID_ko); +- +- torture_rpc_tcase_add_test(tcase, "wrong_user_restore_guid", +- test_RestoreGUID_wronguser); +- +- torture_rpc_tcase_add_test(tcase, "wrong_version_restore_guid", +- test_RestoreGUID_wrongversion); +- +- torture_rpc_tcase_add_test(tcase, "bad_magic_on_secret_restore_guid", +- test_RestoreGUID_badmagiconsecret); +- +- torture_rpc_tcase_add_test(tcase, "bad_hash_on_secret_restore_guid", +- test_RestoreGUID_badhashaccesscheck); +- +- torture_rpc_tcase_add_test(tcase, "bad_magic_on_accesscheck_restore_guid", +- test_RestoreGUID_badmagicaccesscheck); +- +- torture_rpc_tcase_add_test(tcase, "bad_cert_guid_restore_guid", +- test_RestoreGUID_badcertguid); +- +- torture_rpc_tcase_add_test(tcase, "empty_request_restore_guid", +- test_RestoreGUID_emptyrequest); +- +- torture_rpc_tcase_add_test(tcase, "retreive_backup_key_guid_2048_bits", +- test_RetrieveBackupKeyGUID_2048bits); +- +- torture_rpc_tcase_add_test(tcase, "server_wrap_encrypt_decrypt", +- test_ServerWrap_encrypt_decrypt); +- +- torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_wrong_keyGUID", +- test_ServerWrap_decrypt_wrong_keyGUID); +- +- torture_rpc_tcase_add_test(tcase, "server_wrap_empty_request", +- test_ServerWrap_decrypt_empty_request); +- +- torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_short_request", +- test_ServerWrap_decrypt_short_request); +- +- torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_wrong_magic", +- test_ServerWrap_decrypt_wrong_magic); +- +- torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_wrong_r2", +- test_ServerWrap_decrypt_wrong_r2); +- +- torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_wrong_payload_length", +- test_ServerWrap_decrypt_wrong_payload_length); +- +- torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_short_payload_length", +- test_ServerWrap_decrypt_short_payload_length); +- +- torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_zero_payload_length", +- test_ServerWrap_decrypt_zero_payload_length); +- +- torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_wrong_ciphertext_length", +- test_ServerWrap_decrypt_wrong_ciphertext_length); +- +- torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_short_ciphertext_length", +- test_ServerWrap_decrypt_short_ciphertext_length); +- +- torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_zero_ciphertext_length", +- test_ServerWrap_decrypt_zero_ciphertext_length); +- +- torture_rpc_tcase_add_test(tcase, "server_wrap_encrypt_decrypt_remote_key", +- test_ServerWrap_encrypt_decrypt_remote_key); +- +- torture_rpc_tcase_add_test(tcase, "server_wrap_encrypt_decrypt_wrong_key", +- test_ServerWrap_encrypt_decrypt_wrong_key); +- +- torture_rpc_tcase_add_test(tcase, "server_wrap_encrypt_decrypt_wrong_sid", +- test_ServerWrap_encrypt_decrypt_wrong_sid); +- +- return suite; +-} +diff --git a/source4/torture/wscript_build b/source4/torture/wscript_build +index 7dde54fefba..d9fbcbb6ebe 100644 +--- a/source4/torture/wscript_build ++++ b/source4/torture/wscript_build +@@ -82,13 +82,6 @@ bld.SAMBA_SUBSYSTEM('IREMOTEWINSPOOL_COMMON', + deps='talloc', + enabled=bld.PYTHON_BUILD_IS_ENABLED()) + +-torture_rpc_backupkey = '' +-if bld.AD_DC_BUILD_IS_ENABLED(): +- if (bld.CONFIG_SET('HAVE_GNUTLS_PRIVKEY_EXPORT_X509') and +- bld.CONFIG_SET('HAVE_GNUTLS_X509_CRT_SET_SUBJECT_UNIQUE_ID')): +- torture_rpc_backupkey = 'rpc/backupkey.c' +- else: +- torture_rpc_backupkey = 'rpc/backupkey_heimdal.c' + bld.SAMBA_MODULE('torture_rpc', + source=''' + rpc/join.c +@@ -145,7 +138,7 @@ bld.SAMBA_MODULE('torture_rpc', + rpc/witness.c + rpc/iremotewinspool.c + rpc/iremotewinspool_driver.c +- ''' + torture_rpc_backupkey + ntvfs_specific['source'], ++ rpc/backupkey.c''' + ntvfs_specific['source'], + autoproto='rpc/proto.h', + subsystem='smbtorture', + init_function='torture_rpc_init', +diff --git a/wscript_configure_system_gnutls b/wscript_configure_system_gnutls +index 8ff0529e10c..02e6567ba2f 100644 +--- a/wscript_configure_system_gnutls ++++ b/wscript_configure_system_gnutls +@@ -12,12 +12,6 @@ conf.CHECK_CFG(package='gnutls', + # Define gnutls as a system library + conf.SET_TARGET_TYPE('gnutls', 'SYSLIB') + +-# Check for gnutls_privkey_export_x509 (>= 3.4.0) required by backupkey +-conf.CHECK_FUNCS_IN('gnutls_privkey_export_x509', 'gnutls') +- +-# Check for gnutls_x509_crt_set_subject_unique_id (>= 3.4.7) required by backupkey +-conf.CHECK_FUNCS_IN('gnutls_x509_crt_set_subject_unique_id', 'gnutls') +- + # Check for gnutls_pkcs7_get_embedded_data_oid (>= 3.5.5) required by libmscat + conf.CHECK_FUNCS_IN('gnutls_pkcs7_get_embedded_data_oid', 'gnutls') + +-- +2.23.0 + diff --git a/SOURCES/0106-s4-rpc_server-backupkey-consistently-check-error-cod.patch b/SOURCES/0106-s4-rpc_server-backupkey-consistently-check-error-cod.patch new file mode 100644 index 0000000..bd4031b --- /dev/null +++ b/SOURCES/0106-s4-rpc_server-backupkey-consistently-check-error-cod.patch @@ -0,0 +1,271 @@ +From ac505bb247d1f63d6c22d380e4db5a5f84cd2ff1 Mon Sep 17 00:00:00 2001 +From: Andrew Bartlett +Date: Fri, 16 Aug 2019 16:08:57 +1200 +Subject: [PATCH 106/187] s4-rpc_server/backupkey: consistently check error + codes from GnuTLS + +This uses the new gnutls_error_to_werror() + +This should resolve Coverity 1452111 as forwarded by Volker. + +Signed-off-by: Andrew Bartlett +Reviewed-by: Andreas Schneider +(cherry picked from commit 2d54559aad9af81cf21d223dad28b48184c59f44) +--- + .../rpc_server/backupkey/dcesrv_backupkey.c | 146 +++++++++++------- + source4/rpc_server/wscript_build | 2 +- + 2 files changed, 92 insertions(+), 56 deletions(-) + +diff --git a/source4/rpc_server/backupkey/dcesrv_backupkey.c b/source4/rpc_server/backupkey/dcesrv_backupkey.c +index a826ae083f4..cea6a28e4e2 100644 +--- a/source4/rpc_server/backupkey/dcesrv_backupkey.c ++++ b/source4/rpc_server/backupkey/dcesrv_backupkey.c +@@ -42,6 +42,8 @@ + #include + #include + ++#include "lib/crypto/gnutls_helpers.h" ++ + #define DCESRV_INTERFACE_BACKUPKEY_BIND(context, iface) \ + dcesrv_interface_backupkey_bind(context, iface) + static NTSTATUS dcesrv_interface_backupkey_bind(struct dcesrv_connection_context *context, +@@ -1439,15 +1441,23 @@ static WERROR bkrp_server_wrap_decrypt_data(struct dcesrv_call_state *dce_call, + * BACKUPKEY_BACKUP_GUID, it really is the whole key + */ + +- gnutls_hmac_init(&hmac_hnd, +- GNUTLS_MAC_SHA1, +- server_key.key, +- sizeof(server_key.key)); +- gnutls_hmac(hmac_hnd, ++ rc = gnutls_hmac_init(&hmac_hnd, ++ GNUTLS_MAC_SHA1, ++ server_key.key, ++ sizeof(server_key.key)); ++ if (rc != GNUTLS_E_SUCCESS) { ++ return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR); ++ } ++ ++ rc = gnutls_hmac(hmac_hnd, + decrypt_request.r2, + sizeof(decrypt_request.r2)); +- gnutls_hmac_output(hmac_hnd, symkey); + ++ if (rc != GNUTLS_E_SUCCESS) { ++ return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR); ++ } ++ ++ gnutls_hmac_output(hmac_hnd, symkey); + dump_data_pw("symkey: \n", symkey, sizeof(symkey)); + + /* rc4 decrypt sid and secret using sym key */ +@@ -1462,9 +1472,7 @@ static WERROR bkrp_server_wrap_decrypt_data(struct dcesrv_call_state *dce_call, + &cipher_key, + NULL); + if (rc != GNUTLS_E_SUCCESS) { +- DBG_ERR("gnutls_cipher_init failed - %s\n", +- gnutls_strerror(rc)); +- return WERR_INVALID_PARAMETER; ++ return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR); + } + rc = gnutls_cipher_encrypt2(cipher_hnd, + encrypted_blob.data, +@@ -1473,9 +1481,7 @@ static WERROR bkrp_server_wrap_decrypt_data(struct dcesrv_call_state *dce_call, + encrypted_blob.length); + gnutls_cipher_deinit(cipher_hnd); + if (rc != GNUTLS_E_SUCCESS) { +- DBG_ERR("gnutls_cipher_encrypt2 failed - %s\n", +- gnutls_strerror(rc)); +- return WERR_INVALID_PARAMETER; ++ return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR); + } + + ndr_err = ndr_pull_struct_blob_all(&encrypted_blob, mem_ctx, &rc4payload, +@@ -1494,9 +1500,13 @@ static WERROR bkrp_server_wrap_decrypt_data(struct dcesrv_call_state *dce_call, + * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1 + * BACKUPKEY_BACKUP_GUID, it really is the whole key + */ +- gnutls_hmac(hmac_hnd, +- rc4payload.r3, +- sizeof(rc4payload.r3)); ++ rc = gnutls_hmac(hmac_hnd, ++ rc4payload.r3, ++ sizeof(rc4payload.r3)); ++ if (rc != GNUTLS_E_SUCCESS) { ++ return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR); ++ } ++ + gnutls_hmac_deinit(hmac_hnd, mackey); + + dump_data_pw("mackey: \n", mackey, sizeof(mackey)); +@@ -1507,20 +1517,31 @@ static WERROR bkrp_server_wrap_decrypt_data(struct dcesrv_call_state *dce_call, + return WERR_INTERNAL_ERROR; + } + +- gnutls_hmac_init(&hmac_hnd, +- GNUTLS_MAC_SHA1, +- mackey, +- sizeof(mackey)); ++ rc = gnutls_hmac_init(&hmac_hnd, ++ GNUTLS_MAC_SHA1, ++ mackey, ++ sizeof(mackey)); ++ if (rc != GNUTLS_E_SUCCESS) { ++ return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR); ++ } ++ + /* SID field */ +- gnutls_hmac(hmac_hnd, +- sid_blob.data, +- sid_blob.length); ++ rc = gnutls_hmac(hmac_hnd, ++ sid_blob.data, ++ sid_blob.length); ++ if (rc != GNUTLS_E_SUCCESS) { ++ return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR); ++ } ++ + /* Secret field */ +- gnutls_hmac(hmac_hnd, +- rc4payload.secret_data.data, +- rc4payload.secret_data.length); +- gnutls_hmac_deinit(hmac_hnd, mac); ++ rc = gnutls_hmac(hmac_hnd, ++ rc4payload.secret_data.data, ++ rc4payload.secret_data.length); ++ if (rc != GNUTLS_E_SUCCESS) { ++ return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR); ++ } + ++ gnutls_hmac_deinit(hmac_hnd, mac); + dump_data_pw("mac: \n", mac, sizeof(mac)); + dump_data_pw("rc4payload.mac: \n", rc4payload.mac, sizeof(rc4payload.mac)); + +@@ -1657,26 +1678,34 @@ static WERROR bkrp_server_wrap_encrypt_data(struct dcesrv_call_state *dce_call, + * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1 + * BACKUPKEY_BACKUP_GUID, it really is the whole key + */ +- gnutls_hmac_init(&hmac_hnd, +- GNUTLS_MAC_SHA1, +- server_key.key, +- sizeof(server_key.key)); +- gnutls_hmac(hmac_hnd, +- server_side_wrapped.r2, +- sizeof(server_side_wrapped.r2)); +- gnutls_hmac_output(hmac_hnd, symkey); ++ rc = gnutls_hmac_init(&hmac_hnd, ++ GNUTLS_MAC_SHA1, ++ server_key.key, ++ sizeof(server_key.key)); ++ if (rc != GNUTLS_E_SUCCESS) { ++ return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR); ++ } + ++ rc = gnutls_hmac(hmac_hnd, ++ server_side_wrapped.r2, ++ sizeof(server_side_wrapped.r2)); ++ if (rc != GNUTLS_E_SUCCESS) { ++ return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR); ++ } ++ gnutls_hmac_output(hmac_hnd, symkey); + dump_data_pw("symkey: \n", symkey, sizeof(symkey)); + + /* + * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1 + * BACKUPKEY_BACKUP_GUID, it really is the whole key + */ +- gnutls_hmac(hmac_hnd, +- rc4payload.r3, +- sizeof(rc4payload.r3)); ++ rc = gnutls_hmac(hmac_hnd, ++ rc4payload.r3, ++ sizeof(rc4payload.r3)); ++ if (rc != GNUTLS_E_SUCCESS) { ++ return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR); ++ } + gnutls_hmac_deinit(hmac_hnd, mackey); +- + dump_data_pw("mackey: \n", mackey, sizeof(mackey)); + + ndr_err = ndr_push_struct_blob(&sid_blob, mem_ctx, caller_sid, +@@ -1688,20 +1717,31 @@ static WERROR bkrp_server_wrap_encrypt_data(struct dcesrv_call_state *dce_call, + rc4payload.secret_data.data = r->in.data_in; + rc4payload.secret_data.length = r->in.data_in_len; + +- gnutls_hmac_init(&hmac_hnd, +- GNUTLS_MAC_SHA1, +- mackey, +- sizeof(mackey)); ++ rc = gnutls_hmac_init(&hmac_hnd, ++ GNUTLS_MAC_SHA1, ++ mackey, ++ sizeof(mackey)); ++ if (rc != GNUTLS_E_SUCCESS) { ++ return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR); ++ } ++ + /* SID field */ +- gnutls_hmac(hmac_hnd, +- sid_blob.data, +- sid_blob.length); ++ rc = gnutls_hmac(hmac_hnd, ++ sid_blob.data, ++ sid_blob.length); ++ if (rc != GNUTLS_E_SUCCESS) { ++ return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR); ++ } ++ + /* Secret field */ +- gnutls_hmac(hmac_hnd, +- rc4payload.secret_data.data, +- rc4payload.secret_data.length); +- gnutls_hmac_deinit(hmac_hnd, rc4payload.mac); ++ rc = gnutls_hmac(hmac_hnd, ++ rc4payload.secret_data.data, ++ rc4payload.secret_data.length); ++ if (rc != GNUTLS_E_SUCCESS) { ++ return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR); ++ } + ++ gnutls_hmac_deinit(hmac_hnd, rc4payload.mac); + dump_data_pw("rc4payload.mac: \n", rc4payload.mac, sizeof(rc4payload.mac)); + + rc4payload.sid = *caller_sid; +@@ -1721,9 +1761,7 @@ static WERROR bkrp_server_wrap_encrypt_data(struct dcesrv_call_state *dce_call, + &cipher_key, + NULL); + if (rc != GNUTLS_E_SUCCESS) { +- DBG_ERR("gnutls_cipher_init failed - %s\n", +- gnutls_strerror(rc)); +- return WERR_INVALID_PARAMETER; ++ return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR); + } + rc = gnutls_cipher_encrypt2(cipher_hnd, + encrypted_blob.data, +@@ -1732,9 +1770,7 @@ static WERROR bkrp_server_wrap_encrypt_data(struct dcesrv_call_state *dce_call, + encrypted_blob.length); + gnutls_cipher_deinit(cipher_hnd); + if (rc != GNUTLS_E_SUCCESS) { +- DBG_ERR("gnutls_cipher_encrypt2 failed - %s\n", +- gnutls_strerror(rc)); +- return WERR_INVALID_PARAMETER; ++ return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR); + } + + /* create server wrap structure */ +diff --git a/source4/rpc_server/wscript_build b/source4/rpc_server/wscript_build +index a5c1c1d9a2c..18ec5aef894 100644 +--- a/source4/rpc_server/wscript_build ++++ b/source4/rpc_server/wscript_build +@@ -124,7 +124,7 @@ bld.SAMBA_MODULE('dcerpc_backupkey', + autoproto='backupkey/proto.h', + subsystem='dcerpc_server', + init_function='dcerpc_server_backupkey_init', +- deps='samdb DCERPC_COMMON NDR_BACKUPKEY RPC_NDR_BACKUPKEY gnutls', ++ deps='samdb DCERPC_COMMON NDR_BACKUPKEY RPC_NDR_BACKUPKEY gnutls GNUTLS_HELPERS', + ) + + +-- +2.23.0 + diff --git a/SOURCES/0107-lib-crypto-Remove-unused-RC4-code-from-Samba.patch b/SOURCES/0107-lib-crypto-Remove-unused-RC4-code-from-Samba.patch new file mode 100644 index 0000000..5987744 --- /dev/null +++ b/SOURCES/0107-lib-crypto-Remove-unused-RC4-code-from-Samba.patch @@ -0,0 +1,168 @@ +From 2bdfe3735e50438213359e3c7a070ea873cf30be Mon Sep 17 00:00:00 2001 +From: Andrew Bartlett +Date: Thu, 15 Aug 2019 14:23:35 +1200 +Subject: [PATCH 107/187] lib/crypto: Remove unused RC4 code from Samba + +Signed-off-by: Andrew Bartlett +Reviewed-by: Andreas Schneider +(cherry picked from commit e9859ad356b42f39585dcef1a38def97a50a3744) +--- + lib/crypto/arcfour.c | 93 ---------------------------------------- + lib/crypto/arcfour.h | 17 -------- + lib/crypto/wscript_build | 9 ---- + 3 files changed, 119 deletions(-) + delete mode 100644 lib/crypto/arcfour.c + delete mode 100644 lib/crypto/arcfour.h + +diff --git a/lib/crypto/arcfour.c b/lib/crypto/arcfour.c +deleted file mode 100644 +index af9b20cc01e..00000000000 +--- a/lib/crypto/arcfour.c ++++ /dev/null +@@ -1,93 +0,0 @@ +-/* +- Unix SMB/CIFS implementation. +- +- An implementation of the arcfour algorithm +- +- Copyright (C) Andrew Tridgell 1998 +- +- This program is free software; you can redistribute it and/or modify +- it under the terms of the GNU General Public License as published by +- the Free Software Foundation; either version 3 of the License, or +- (at your option) any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- GNU General Public License for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program. If not, see . +-*/ +- +-#include "replace.h" +-#include "../lib/crypto/arcfour.h" +- +-/* initialise the arcfour sbox with key */ +-_PUBLIC_ void arcfour_init(struct arcfour_state *state, const DATA_BLOB *key) +-{ +- size_t ind; +- uint8_t j = 0; +- for (ind = 0; ind < sizeof(state->sbox); ind++) { +- state->sbox[ind] = (uint8_t)ind; +- } +- +- for (ind = 0; ind < sizeof(state->sbox); ind++) { +- uint8_t tc; +- +- j += (state->sbox[ind] + key->data[ind%key->length]); +- +- tc = state->sbox[ind]; +- state->sbox[ind] = state->sbox[j]; +- state->sbox[j] = tc; +- } +- state->index_i = 0; +- state->index_j = 0; +-} +- +-/* crypt the data with arcfour */ +-_PUBLIC_ void arcfour_crypt_sbox(struct arcfour_state *state, uint8_t *data, +- int len) +-{ +- int ind; +- +- for (ind = 0; ind < len; ind++) { +- uint8_t tc; +- uint8_t t; +- +- state->index_i++; +- state->index_j += state->sbox[state->index_i]; +- +- tc = state->sbox[state->index_i]; +- state->sbox[state->index_i] = state->sbox[state->index_j]; +- state->sbox[state->index_j] = tc; +- +- t = state->sbox[state->index_i] + state->sbox[state->index_j]; +- data[ind] = data[ind] ^ state->sbox[t]; +- } +-} +- +-/* +- arcfour encryption with a blob key +-*/ +-_PUBLIC_ void arcfour_crypt_blob(uint8_t *data, int len, const DATA_BLOB *key) +-{ +- struct arcfour_state state; +- arcfour_init(&state, key); +- arcfour_crypt_sbox(&state, data, len); +-} +- +-/* +- a variant that assumes a 16 byte key. This should be removed +- when the last user is gone +-*/ +-_PUBLIC_ void arcfour_crypt(uint8_t *data, const uint8_t keystr[16], int len) +-{ +- uint8_t keycopy[16]; +- DATA_BLOB key = { .data = keycopy, .length = sizeof(keycopy) }; +- +- memcpy(keycopy, keystr, sizeof(keycopy)); +- +- arcfour_crypt_blob(data, len, &key); +-} +- +- +diff --git a/lib/crypto/arcfour.h b/lib/crypto/arcfour.h +deleted file mode 100644 +index a9f80c474d5..00000000000 +--- a/lib/crypto/arcfour.h ++++ /dev/null +@@ -1,17 +0,0 @@ +-#ifndef ARCFOUR_HEADER_H +-#define ARCFOUR_HEADER_H +- +-#include "../lib/util/data_blob.h" +- +-struct arcfour_state { +- uint8_t sbox[256]; +- uint8_t index_i; +- uint8_t index_j; +-}; +- +-void arcfour_init(struct arcfour_state *state, const DATA_BLOB *key); +-void arcfour_crypt_sbox(struct arcfour_state *state, uint8_t *data, int len); +-void arcfour_crypt_blob(uint8_t *data, int len, const DATA_BLOB *key); +-void arcfour_crypt(uint8_t *data, const uint8_t keystr[16], int len); +- +-#endif /* ARCFOUR_HEADER_H */ +diff --git a/lib/crypto/wscript_build b/lib/crypto/wscript_build +index 9a7c715754d..dcac8fcd30c 100644 +--- a/lib/crypto/wscript_build ++++ b/lib/crypto/wscript_build +@@ -12,14 +12,6 @@ bld.SAMBA_SUBSYSTEM('GNUTLS_HELPERS', + ''', + deps='gnutls samba-errors'); + +-# We have a GnuTLS DCEPRC backupkey implementation for the server and the test. +-# However this is only working with GnuTLS >= 3.4.7. So we need to keep this +-# around till we can require at least GnuTLS in a newer version. +-bld.SAMBA_SUBSYSTEM('LIBCRYPTO_RC4', +- source='arcfour.c', +- deps='talloc', +- enabled=not bld.CONFIG_SET('HAVE_GNUTLS_3_4_7')) +- + bld.SAMBA_SUBSYSTEM('LIBCRYPTO_AES_CCM', + source='aes_ccm_128.c', + deps='talloc') +@@ -42,7 +34,6 @@ bld.SAMBA_SUBSYSTEM('LIBCRYPTO', + ''', + deps=''' + talloc +- LIBCRYPTO_RC4 + LIBCRYPTO_AES + LIBCRYPTO_AES_CCM + LIBCRYPTO_AES_GCM +-- +2.23.0 + diff --git a/SOURCES/0108-s4-samdb-Remove-duplicate-encrypted_secrets-code-usi.patch b/SOURCES/0108-s4-samdb-Remove-duplicate-encrypted_secrets-code-usi.patch new file mode 100644 index 0000000..e3019fb --- /dev/null +++ b/SOURCES/0108-s4-samdb-Remove-duplicate-encrypted_secrets-code-usi.patch @@ -0,0 +1,705 @@ +From d2a0904b915c4f9ffe8ca7f8015ef201dd8b827d Mon Sep 17 00:00:00 2001 +From: Andrew Bartlett +Date: Wed, 31 Jul 2019 16:37:00 +1200 +Subject: [PATCH 108/187] s4-samdb: Remove duplicate encrypted_secrets code + using internal Samba AES + +We now rely on GnuTLS 3.4.7 or later. + +Signed-off-by: Andrew Bartlett +Reviewed-by: Andreas Schneider +(cherry picked from commit 85a1c4973921fdf9412ec56a3ed6a77f3ab84116) +--- + .../samdb/ldb_modules/encrypted_secrets.c | 266 +---------------- + .../tests/test_encrypted_secrets.c | 278 ------------------ + 2 files changed, 2 insertions(+), 542 deletions(-) + +diff --git a/source4/dsdb/samdb/ldb_modules/encrypted_secrets.c b/source4/dsdb/samdb/ldb_modules/encrypted_secrets.c +index e0932858588..0d46031ec64 100644 +--- a/source4/dsdb/samdb/ldb_modules/encrypted_secrets.c ++++ b/source4/dsdb/samdb/ldb_modules/encrypted_secrets.c +@@ -39,22 +39,8 @@ + #include "dsdb/samdb/samdb.h" + #include "dsdb/samdb/ldb_modules/util.h" + +-/* Build either with GnuTLS crypto or Samba crypto. */ +-#ifdef HAVE_GNUTLS_AEAD +- #define BUILD_WITH_GNUTLS_AEAD +-#else /* !HAVE_GNUTLS_AEAD */ +- #define BUILD_WITH_SAMBA_AES_GCM +-#endif /* HAVE_GNUTLS_AEAD */ +- +-#ifdef BUILD_WITH_GNUTLS_AEAD +- #include +- #include +-#endif /* BUILD_WITH_GNUTLS_AEAD */ +- +-#ifdef BUILD_WITH_SAMBA_AES_GCM +- #include "lib/crypto/aes.h" +- #include "lib/crypto/aes_gcm_128.h" +-#endif /* BUILD_WITH_SAMBA_AES_GCM */ ++#include ++#include + + static const char * const secret_attributes[] = {DSDB_SECRET_ATTRIBUTES}; + static const size_t num_secret_attributes = ARRAY_SIZE(secret_attributes); +@@ -74,12 +60,10 @@ struct es_data { + * Encryption keys for secret attributes + */ + DATA_BLOB keys[NUMBER_OF_KEYS]; +-#ifdef BUILD_WITH_GNUTLS_AEAD + /* + * The gnutls algorithm used to encrypt attributes + */ + int encryption_algorithm; +-#endif /* BUILD_WITH_GNUTLS_AEAD */ + }; + + /* +@@ -262,9 +246,7 @@ static int load_keys(struct ldb_module *module, struct es_data *data) + + data->keys[0] = key; + data->encrypt_secrets = true; +-#ifdef BUILD_WITH_GNUTLS_AEAD + data->encryption_algorithm = GNUTLS_CIPHER_AES_128_GCM; +-#endif + TALLOC_FREE(frame); + + return LDB_SUCCESS; +@@ -299,7 +281,6 @@ static bool should_encrypt(const struct ldb_message_element *el) + * + * @return Size rounded up to the nearest multiple of block_size + */ +-#ifdef BUILD_WITH_GNUTLS_AEAD + static size_t round_to_block_size(size_t block_size, size_t size) + { + if ((size % block_size) == 0) { +@@ -308,7 +289,6 @@ static size_t round_to_block_size(size_t block_size, size_t size) + return ((int)(size/block_size) + 1) * block_size; + } + } +-#endif /* BUILD_WITH_GNUTLS_AEAD */ + + /* + * @brief Create an new EncryptedSecret owned by the supplied talloc context. +@@ -375,239 +355,6 @@ static DATA_BLOB makePlainText(TALLOC_CTX *ctx, + return pt; + } + +-#ifdef BUILD_WITH_SAMBA_AES_GCM +-/* +- * @brief Encrypt an ldb value using an aead algorithm. +- * +- * This function uses the samba internal implementation to perform the encryption. However +- * the encrypted data and tag are stored in a manner compatible with gnutls, +- * so the gnutls aead functions can be used to decrypt and verify the data. +- * +- * @param err Pointer to an error code, set to: +- * LDB_SUCESS If the value was successfully encrypted +- * LDB_ERR_OPERATIONS_ERROR If there was an error. +- * +- * @param ctx Talloc memory context the will own the memory allocated +- * @param ldb ldb context, to allow logging. +- * @param val The ldb value to encrypt, not altered or freed +- * @param data The context data for this module. +- * +- * @return The encrypted ldb_val, or data_blob_null if there was an error. +- */ +-static struct ldb_val samba_encrypt_aead(int *err, +- TALLOC_CTX *ctx, +- struct ldb_context *ldb, +- const struct ldb_val val, +- const struct es_data *data) +-{ +- struct aes_gcm_128_context cctx; +- struct EncryptedSecret *es = NULL; +- DATA_BLOB pt = data_blob_null; +- struct ldb_val enc = data_blob_null; +- DATA_BLOB key_blob = data_blob_null; +- int rc; +- TALLOC_CTX *frame = talloc_stackframe(); +- +- es = makeEncryptedSecret(ldb, frame); +- if (es == NULL) { +- goto error_exit; +- } +- +- pt = makePlainText(frame, ldb, val); +- if (pt.length == 0) { +- goto error_exit; +- } +- +- /* +- * Set the encryption key +- */ +- key_blob = get_key(data); +- if (key_blob.length != AES_BLOCK_SIZE) { +- ldb_asprintf_errstring(ldb, +- "Invalid EncryptedSecrets key size, " +- "expected %u bytes and is %zu bytes\n", +- AES_BLOCK_SIZE, +- key_blob.length); +- goto error_exit; +- } +- +- /* +- * Set the initialisation vector +- */ +- { +- uint8_t *iv = talloc_zero_size(frame, AES_GCM_128_IV_SIZE); +- if (iv == NULL) { +- ldb_set_errstring(ldb, +- "Out of memory allocating iv\n"); +- goto error_exit; +- } +- +- generate_nonce_buffer(iv, AES_GCM_128_IV_SIZE); +- +- es->iv.length = AES_GCM_128_IV_SIZE; +- es->iv.data = iv; +- } +- +- /* +- * Encrypt the value, and append the GCM digest to the encrypted +- * data so that it can be decrypted and validated by the +- * gnutls aead decryption routines. +- */ +- { +- uint8_t *ct = talloc_zero_size(frame, pt.length + AES_BLOCK_SIZE); +- if (ct == NULL) { +- ldb_oom(ldb); +- goto error_exit; +- } +- +- memcpy(ct, pt.data, pt.length); +- es->encrypted.length = pt.length + AES_BLOCK_SIZE; +- es->encrypted.data = ct; +- } +- +- aes_gcm_128_init(&cctx, key_blob.data, es->iv.data); +- aes_gcm_128_updateA(&cctx, +- (uint8_t *)&es->header, +- sizeof(struct EncryptedSecretHeader)); +- aes_gcm_128_crypt(&cctx, es->encrypted.data, pt.length); +- aes_gcm_128_updateC(&cctx, es->encrypted.data, pt.length); +- aes_gcm_128_digest(&cctx, &es->encrypted.data[pt.length]); +- +- rc = ndr_push_struct_blob(&enc, +- ctx, +- es, +- (ndr_push_flags_fn_t) +- ndr_push_EncryptedSecret); +- if (!NDR_ERR_CODE_IS_SUCCESS(rc)) { +- ldb_set_errstring(ldb, +- "Unable to ndr push EncryptedSecret\n"); +- goto error_exit; +- } +- TALLOC_FREE(frame); +- return enc; +- +-error_exit: +- *err = LDB_ERR_OPERATIONS_ERROR; +- TALLOC_FREE(frame); +- return data_blob_null; +-} +- +-/* +- * @brief Decrypt data encrypted using an aead algorithm. +- * +- * Decrypt the data in ed and insert it into ev. The data was encrypted +- * with the samba aes gcm implementation. +- * +- * @param err Pointer to an error code, set to: +- * LDB_SUCESS If the value was successfully decrypted +- * LDB_ERR_OPERATIONS_ERROR If there was an error. +- * +- * @param ctx Talloc memory context that will own the memory allocated +- * @param ldb ldb context, to allow logging. +- * @param ev The value to be updated with the decrypted data. +- * @param ed The data to decrypt. +- * @param data The context data for this module. +- * +- * @return ev is updated with the unencrypted data. +- */ +-static void samba_decrypt_aead(int *err, +- TALLOC_CTX *ctx, +- struct ldb_context *ldb, +- struct EncryptedSecret *es, +- struct PlaintextSecret *ps, +- const struct es_data *data) +-{ +- struct aes_gcm_128_context cctx; +- DATA_BLOB pt = data_blob_null; +- DATA_BLOB key_blob = data_blob_null; +- uint8_t sig[AES_BLOCK_SIZE] = {0, }; +- int rc; +- int cmp; +- TALLOC_CTX *frame = talloc_stackframe(); +- +- /* +- * Set the encryption key +- */ +- key_blob = get_key(data); +- if (key_blob.length != AES_BLOCK_SIZE) { +- ldb_asprintf_errstring(ldb, +- "Invalid EncryptedSecrets key size, " +- "expected %u bytes and is %zu bytes\n", +- AES_BLOCK_SIZE, +- key_blob.length); +- goto error_exit; +- } +- +- if (es->iv.length < AES_GCM_128_IV_SIZE) { +- ldb_asprintf_errstring(ldb, +- "Invalid EncryptedSecrets iv size, " +- "expected %u bytes and is %zu bytes\n", +- AES_GCM_128_IV_SIZE, +- es->iv.length); +- goto error_exit; +- } +- +- if (es->encrypted.length < AES_BLOCK_SIZE) { +- ldb_asprintf_errstring(ldb, +- "Invalid EncryptedData size, " +- "expected %u bytes and is %zu bytes\n", +- AES_BLOCK_SIZE, +- es->encrypted.length); +- goto error_exit; +- } +- +- pt.length = es->encrypted.length - AES_BLOCK_SIZE; +- pt.data = talloc_zero_size(ctx, pt.length); +- if (pt.data == NULL) { +- ldb_set_errstring(ldb, +- "Out of memory allocating space for " +- "plain text\n"); +- goto error_exit; +- } +- memcpy(pt.data, es->encrypted.data, pt.length); +- +- aes_gcm_128_init(&cctx, key_blob.data, es->iv.data); +- aes_gcm_128_updateA(&cctx, +- (uint8_t *)&es->header, +- sizeof(struct EncryptedSecretHeader)); +- aes_gcm_128_updateC(&cctx, pt.data, pt.length); +- aes_gcm_128_crypt(&cctx, pt.data, pt.length); +- aes_gcm_128_digest(&cctx, sig); +- +- /* +- * Check the authentication tag +- */ +- cmp = memcmp(&es->encrypted.data[pt.length], sig, AES_BLOCK_SIZE); +- if (cmp != 0) { +- ldb_set_errstring(ldb, +- "Tag does not match, " +- "data corrupted or altered\n"); +- goto error_exit; +- } +- +- rc = ndr_pull_struct_blob(&pt, +- ctx, +- ps, +- (ndr_pull_flags_fn_t) +- ndr_pull_PlaintextSecret); +- if(!NDR_ERR_CODE_IS_SUCCESS(rc)) { +- ldb_asprintf_errstring(ldb, +- "Error(%d) unpacking decrypted data, " +- "data possibly corrupted or altered\n", +- rc); +- goto error_exit; +- } +- TALLOC_FREE(frame); +- return; +- +-error_exit: +- *err = LDB_ERR_OPERATIONS_ERROR; +- TALLOC_FREE(frame); +- return; +-} +-#endif /* BUILD_WITH_SAMBA_AES_GCM */ +- +-#ifdef BUILD_WITH_GNUTLS_AEAD + + /* + * Helper function converts a data blob to a gnutls_datum_t. +@@ -946,7 +693,6 @@ error_exit: + *err = LDB_ERR_OPERATIONS_ERROR; + return; + } +-#endif /* BUILD_WITH_GNUTLS_AEAD */ + + /* + * @brief Encrypt an attribute value using the default encryption algorithm. +@@ -972,11 +718,7 @@ static struct ldb_val encrypt_value(int *err, + const struct ldb_val val, + const struct es_data *data) + { +-#ifdef BUILD_WITH_GNUTLS_AEAD + return gnutls_encrypt_aead(err, ctx, ldb, val, data); +-#elif defined BUILD_WITH_SAMBA_AES_GCM +- return samba_encrypt_aead(err, ctx, ldb, val, data); +-#endif + } + + /* +@@ -1206,11 +948,7 @@ static struct ldb_val decrypt_value(int *err, + *err = LDB_ERR_OPERATIONS_ERROR; + return data_blob_null; + } +-#ifdef BUILD_WITH_GNUTLS_AEAD + gnutls_decrypt_aead(err, frame, ldb, &es, &ps, data); +-#elif defined BUILD_WITH_SAMBA_AES_GCM +- samba_decrypt_aead(err, frame, ldb, &es, &ps, data); +-#endif + + if (*err != LDB_SUCCESS) { + TALLOC_FREE(frame); +diff --git a/source4/dsdb/samdb/ldb_modules/tests/test_encrypted_secrets.c b/source4/dsdb/samdb/ldb_modules/tests/test_encrypted_secrets.c +index a33781d703d..b9516815f75 100644 +--- a/source4/dsdb/samdb/ldb_modules/tests/test_encrypted_secrets.c ++++ b/source4/dsdb/samdb/ldb_modules/tests/test_encrypted_secrets.c +@@ -336,7 +336,6 @@ static void test_key_file_long_key(void **state) + assert_int_equal(0, data_blob_cmp(&key, &data->keys[0])); + } + +-#ifdef HAVE_GNUTLS_AEAD + /* + * Test gnutls_encryption and decryption. + */ +@@ -391,9 +390,7 @@ static void test_gnutls_value_encryption(void **state) + &plain_text)); + } + } +-#endif /* HAVE_GNUTLS_AEAD */ + +-#ifdef HAVE_GNUTLS_AEAD + static void test_gnutls_altered_header(void **state) + { + struct ldbtest_ctx *test_ctx = +@@ -458,9 +455,7 @@ static void test_gnutls_altered_header(void **state) + assert_int_equal(LDB_ERR_OPERATIONS_ERROR, err); + } + } +-#endif /* HAVE_GNUTLS_AEAD */ + +-#ifdef HAVE_GNUTLS_AEAD + static void test_gnutls_altered_data(void **state) + { + struct ldbtest_ctx *test_ctx = +@@ -525,9 +520,7 @@ static void test_gnutls_altered_data(void **state) + assert_int_equal(LDB_ERR_OPERATIONS_ERROR, err); + } + } +-#endif /* HAVE_GNUTLS_AEAD */ + +-#ifdef HAVE_GNUTLS_AEAD + static void test_gnutls_altered_iv(void **state) + { + struct ldbtest_ctx *test_ctx = +@@ -592,260 +585,10 @@ static void test_gnutls_altered_iv(void **state) + assert_int_equal(LDB_ERR_OPERATIONS_ERROR, err); + } + } +-#endif /* HAVE_GNUTLS_AEAD */ + + /* + * Test samba encryption and decryption and decryption. + */ +-#ifndef HAVE_GNUTLS_AEAD +-static void test_samba_value_encryption(void **state) +-{ +- struct ldbtest_ctx *test_ctx = +- talloc_get_type_abort(*state, struct ldbtest_ctx); +- struct ldb_val plain_text = data_blob_null; +- struct ldb_val cipher_text = data_blob_null; +- struct EncryptedSecret es; +- +- struct es_data *data = talloc_get_type( +- ldb_module_get_private(test_ctx->module), +- struct es_data); +- int err = LDB_SUCCESS; +- int rc; +- +- plain_text = data_blob_string_const("A text value"); +- cipher_text = samba_encrypt_aead( +- &err, +- test_ctx, +- test_ctx->ldb, +- plain_text, +- data); +- assert_int_equal(LDB_SUCCESS, err); +- +- rc = ndr_pull_struct_blob( +- &cipher_text, +- test_ctx, +- &es, +- (ndr_pull_flags_fn_t) ndr_pull_EncryptedSecret); +- assert_true(NDR_ERR_CODE_IS_SUCCESS(rc)); +- assert_true(check_header(&es)); +- +- { +- struct PlaintextSecret *decrypted = +- talloc_zero(test_ctx, struct PlaintextSecret); +- samba_decrypt_aead( +- &err, +- test_ctx, +- test_ctx->ldb, +- &es, +- decrypted, +- data); +- assert_int_equal(LDB_SUCCESS, err); +- assert_int_equal( +- plain_text.length, +- decrypted->cleartext.length); +- assert_int_equal(0, +- data_blob_cmp( +- &decrypted->cleartext, +- &plain_text)); +- } +- +-} +- +-static void test_samba_altered_header(void **state) +-{ +- struct ldbtest_ctx *test_ctx = +- talloc_get_type_abort(*state, struct ldbtest_ctx); +- struct ldb_val plain_text = data_blob_null; +- struct ldb_val cipher_text = data_blob_null; +- struct EncryptedSecret es; +- +- struct es_data *data = talloc_get_type( +- ldb_module_get_private(test_ctx->module), +- struct es_data); +- int err = LDB_SUCCESS; +- int rc; +- +- plain_text = data_blob_string_const("A text value"); +- cipher_text = samba_encrypt_aead( +- &err, +- test_ctx, +- test_ctx->ldb, +- plain_text, +- data); +- assert_int_equal(LDB_SUCCESS, err); +- +- rc = ndr_pull_struct_blob( +- &cipher_text, +- test_ctx, +- &es, +- (ndr_pull_flags_fn_t) ndr_pull_EncryptedSecret); +- assert_true(NDR_ERR_CODE_IS_SUCCESS(rc)); +- assert_true(check_header(&es)); +- +- { +- struct PlaintextSecret *decrypted = +- talloc_zero(test_ctx, struct PlaintextSecret); +- samba_decrypt_aead( +- &err, +- test_ctx, +- test_ctx->ldb, +- &es, +- decrypted, +- data); +- assert_int_equal(LDB_SUCCESS, err); +- assert_int_equal( +- plain_text.length, +- decrypted->cleartext.length); +- assert_int_equal(0, +- data_blob_cmp( +- &decrypted->cleartext, +- &plain_text)); +- } +- es.header.flags = es.header.flags ^ 0xffffffff; +- { +- struct PlaintextSecret *decrypted = +- talloc_zero(test_ctx, struct PlaintextSecret); +- samba_decrypt_aead( +- &err, +- test_ctx, +- test_ctx->ldb, +- &es, +- decrypted, +- data); +- assert_int_equal(LDB_ERR_OPERATIONS_ERROR, err); +- } +-} +- +-static void test_samba_altered_data(void **state) +-{ +- struct ldbtest_ctx *test_ctx = +- talloc_get_type_abort(*state, struct ldbtest_ctx); +- struct ldb_val plain_text = data_blob_null; +- struct ldb_val cipher_text = data_blob_null; +- struct EncryptedSecret es; +- +- struct es_data *data = talloc_get_type( +- ldb_module_get_private(test_ctx->module), +- struct es_data); +- int err = LDB_SUCCESS; +- int rc; +- +- plain_text = data_blob_string_const("A text value"); +- cipher_text = samba_encrypt_aead( +- &err, +- test_ctx, +- test_ctx->ldb, +- plain_text, +- data); +- assert_int_equal(LDB_SUCCESS, err); +- +- rc = ndr_pull_struct_blob( +- &cipher_text, +- test_ctx, +- &es, +- (ndr_pull_flags_fn_t) ndr_pull_EncryptedSecret); +- assert_true(NDR_ERR_CODE_IS_SUCCESS(rc)); +- assert_true(check_header(&es)); +- +- { +- struct PlaintextSecret *decrypted = +- talloc_zero(test_ctx, struct PlaintextSecret); +- samba_decrypt_aead( +- &err, +- test_ctx, +- test_ctx->ldb, +- &es, +- decrypted, +- data); +- assert_int_equal(LDB_SUCCESS, err); +- assert_int_equal( +- plain_text.length, +- decrypted->cleartext.length); +- assert_int_equal(0, +- data_blob_cmp( +- &decrypted->cleartext, +- &plain_text)); +- } +- es.encrypted.data[0] = es.encrypted.data[0] ^ 0xff; +- { +- struct PlaintextSecret *decrypted = +- talloc_zero(test_ctx, struct PlaintextSecret); +- samba_decrypt_aead( +- &err, +- test_ctx, +- test_ctx->ldb, +- &es, +- decrypted, +- data); +- assert_int_equal(LDB_ERR_OPERATIONS_ERROR, err); +- } +-} +- +-static void test_samba_altered_iv(void **state) +-{ +- struct ldbtest_ctx *test_ctx = +- talloc_get_type_abort(*state, struct ldbtest_ctx); +- struct ldb_val plain_text = data_blob_null; +- struct ldb_val cipher_text = data_blob_null; +- struct EncryptedSecret es; +- +- struct es_data *data = talloc_get_type( +- ldb_module_get_private(test_ctx->module), +- struct es_data); +- int err = LDB_SUCCESS; +- int rc; +- +- plain_text = data_blob_string_const("A text value"); +- cipher_text = samba_encrypt_aead( +- &err, +- test_ctx, +- test_ctx->ldb, +- plain_text, +- data); +- assert_int_equal(LDB_SUCCESS, err); +- +- rc = ndr_pull_struct_blob( +- &cipher_text, +- test_ctx, +- &es, +- (ndr_pull_flags_fn_t) ndr_pull_EncryptedSecret); +- assert_true(NDR_ERR_CODE_IS_SUCCESS(rc)); +- assert_true(check_header(&es)); +- +- { +- struct PlaintextSecret *decrypted = +- talloc_zero(test_ctx, struct PlaintextSecret); +- samba_decrypt_aead( +- &err, +- test_ctx, +- test_ctx->ldb, +- &es, +- decrypted, +- data); +- assert_int_equal(LDB_SUCCESS, err); +- assert_int_equal( +- plain_text.length, +- decrypted->cleartext.length); +- assert_int_equal(0, +- data_blob_cmp( +- &decrypted->cleartext, +- &plain_text)); +- } +- es.iv.data[0] = es.iv.data[0] ^ 0xff; +- { +- struct PlaintextSecret *decrypted = +- talloc_zero(test_ctx, struct PlaintextSecret); +- samba_decrypt_aead( +- &err, +- test_ctx, +- test_ctx->ldb, +- &es, +- decrypted, +- data); +- assert_int_equal(LDB_ERR_OPERATIONS_ERROR, err); +- } +-} +-#endif + + /* + * Test message encryption. +@@ -1096,9 +839,7 @@ static void test_record_decryption(void **state) + .data = es_keys_blob, + .length = sizeof(es_keys_blob), + }, +-#ifdef HAVE_GNUTLS_AEAD + .encryption_algorithm = GNUTLS_CIPHER_AES_128_GCM, +-#endif + }; + int err = LDB_SUCCESS; + struct ldb_val dec = decrypt_value(&err, test_ctx, test_ctx->ldb, cipher_text, +@@ -1131,7 +872,6 @@ int main(void) { + test_check_header, + setup, + teardown), +-#ifdef HAVE_GNUTLS_AEAD + cmocka_unit_test_setup_teardown( + test_gnutls_value_encryption, + setup_with_key, +@@ -1148,24 +888,6 @@ int main(void) { + test_gnutls_altered_iv, + setup_with_key, + teardown), +-#else +- cmocka_unit_test_setup_teardown( +- test_samba_value_encryption, +- setup_with_key, +- teardown), +- cmocka_unit_test_setup_teardown( +- test_samba_altered_header, +- setup_with_key, +- teardown), +- cmocka_unit_test_setup_teardown( +- test_samba_altered_data, +- setup_with_key, +- teardown), +- cmocka_unit_test_setup_teardown( +- test_samba_altered_iv, +- setup_with_key, +- teardown), +-#endif /* HAVE_GNUTLS_AEAD */ + cmocka_unit_test_setup_teardown( + test_message_encryption_decryption, + setup_with_key, +-- +2.23.0 + diff --git a/SOURCES/0109-build-Remove-explicit-check-for-HAVE_GNUTLS_AEAD-as-.patch b/SOURCES/0109-build-Remove-explicit-check-for-HAVE_GNUTLS_AEAD-as-.patch new file mode 100644 index 0000000..a608ec4 --- /dev/null +++ b/SOURCES/0109-build-Remove-explicit-check-for-HAVE_GNUTLS_AEAD-as-.patch @@ -0,0 +1,37 @@ +From 858d3355e4f7de925ce653a7cb3604d58f54a8a0 Mon Sep 17 00:00:00 2001 +From: Andrew Bartlett +Date: Thu, 15 Aug 2019 17:28:30 +1200 +Subject: [PATCH 109/187] build: Remove explicit check for HAVE_GNUTLS_AEAD as + we require GnuTLS 3.4.7 + +We strictly require it and if this were to fail we would want the compile to fail. + +Signed-off-by: Andrew Bartlett +Reviewed-by: Andreas Schneider +(cherry picked from commit 068da56a20a2712e498fb3724407836bda2f977b) +--- + wscript_configure_system_gnutls | 8 -------- + 1 file changed, 8 deletions(-) + +diff --git a/wscript_configure_system_gnutls b/wscript_configure_system_gnutls +index 02e6567ba2f..68cc306e3dc 100644 +--- a/wscript_configure_system_gnutls ++++ b/wscript_configure_system_gnutls +@@ -15,14 +15,6 @@ conf.SET_TARGET_TYPE('gnutls', 'SYSLIB') + # Check for gnutls_pkcs7_get_embedded_data_oid (>= 3.5.5) required by libmscat + conf.CHECK_FUNCS_IN('gnutls_pkcs7_get_embedded_data_oid', 'gnutls') + +-# Check for gnutls_aead_cipher_init (>= 3.4.0) used by encrypted_secrets +-if conf.CHECK_FUNCS_IN('gnutls_aead_cipher_init', +- 'gnutls', +- headers='gnutls/gnutls.h'): +- conf.DEFINE('HAVE_GNUTLS_AEAD', '1') +-else: +- Logs.warn('No gnutls support for AEAD encryption') +- + if conf.CHECK_VALUEOF('GNUTLS_CIPHER_AES_128_CFB8', headers='gnutls/gnutls.h'): + conf.DEFINE('HAVE_GNUTLS_AES_CFB8', 1) + else: +-- +2.23.0 + diff --git a/SOURCES/0110-libcli-smb-Define-SMB2_AES_128_CCM_NONCE_SIZE.patch b/SOURCES/0110-libcli-smb-Define-SMB2_AES_128_CCM_NONCE_SIZE.patch new file mode 100644 index 0000000..37a2c38 --- /dev/null +++ b/SOURCES/0110-libcli-smb-Define-SMB2_AES_128_CCM_NONCE_SIZE.patch @@ -0,0 +1,27 @@ +From b31a1e4fd75654c5995d631ac1961ee56fe3e937 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Tue, 26 Feb 2019 18:06:46 +0100 +Subject: [PATCH 110/187] libcli:smb: Define SMB2_AES_128_CCM_NONCE_SIZE + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 43a941f51b2954ffa1a7ab8a9d5c4a18e654b9f6) +--- + libcli/smb/smb2_constants.h | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/libcli/smb/smb2_constants.h b/libcli/smb/smb2_constants.h +index 1430f02689c..5832c0e7f83 100644 +--- a/libcli/smb/smb2_constants.h ++++ b/libcli/smb/smb2_constants.h +@@ -282,4 +282,7 @@ + */ + #define SMB2_DHANDLE_FLAG_PERSISTENT 0x00000002 + ++/* The AES CCM nonce N of 15 - L octets. Where L=4 */ ++#define SMB2_AES_128_CCM_NONCE_SIZE 11 ++ + #endif +-- +2.23.0 + diff --git a/SOURCES/0111-libcli-smb-Use-GnuTLS-for-AES-constants.patch b/SOURCES/0111-libcli-smb-Use-GnuTLS-for-AES-constants.patch new file mode 100644 index 0000000..6dc9072 --- /dev/null +++ b/SOURCES/0111-libcli-smb-Use-GnuTLS-for-AES-constants.patch @@ -0,0 +1,46 @@ +From 198ddcb18122e922f148c1380d08aec832701c7d Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Tue, 26 Feb 2019 18:12:57 +0100 +Subject: [PATCH 111/187] libcli:smb: Use GnuTLS for AES constants + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett + +Adapted to remove Samba AES support + +Signed-off-by: Andrew Bartlett +(cherry picked from commit 1b384f378c95f550718ac697271327442e3d09dd) +--- + libcli/smb/smbXcli_base.c | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) + +diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c +index 5db86720c9c..bfc85ecc225 100644 +--- a/libcli/smb/smbXcli_base.c ++++ b/libcli/smb/smbXcli_base.c +@@ -34,9 +34,6 @@ + #include "librpc/ndr/libndr.h" + #include "libcli/smb/smb2_negotiate_context.h" + #include "libcli/smb/smb2_signing.h" +-#include "lib/crypto/aes.h" +-#include "lib/crypto/aes_ccm_128.h" +-#include "lib/crypto/aes_gcm_128.h" + + #include "lib/crypto/gnutls_helpers.h" + #include +@@ -6257,10 +6254,10 @@ NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session, + sizeof(session->smb2->nonce_high_random)); + switch (conn->smb2.server.cipher) { + case SMB2_ENCRYPTION_AES128_CCM: +- nonce_size = AES_CCM_128_NONCE_SIZE; ++ nonce_size = SMB2_AES_128_CCM_NONCE_SIZE; + break; + case SMB2_ENCRYPTION_AES128_GCM: +- nonce_size = AES_GCM_128_IV_SIZE; ++ nonce_size = gnutls_cipher_get_iv_size(GNUTLS_CIPHER_AES_128_GCM); + break; + default: + nonce_size = 0; +-- +2.23.0 + diff --git a/SOURCES/0112-libcli-smb-Add-gnutls_aead_cipher_hd_t-to-smb2_signi.patch b/SOURCES/0112-libcli-smb-Add-gnutls_aead_cipher_hd_t-to-smb2_signi.patch new file mode 100644 index 0000000..182803d --- /dev/null +++ b/SOURCES/0112-libcli-smb-Add-gnutls_aead_cipher_hd_t-to-smb2_signi.patch @@ -0,0 +1,54 @@ +From de4a182c0fab70125cd7e572a8f913c2f686f827 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Thu, 14 Mar 2019 09:26:04 +0100 +Subject: [PATCH 112/187] libcli:smb: Add gnutls_aead_cipher_hd_t to + smb2_signing_key structure + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett + +Adapted to remove Samba AES support + +Signed-off-by: Andrew Bartlett +(cherry picked from commit 37dc63e8afab8e1f88dc8a4b77c6ef3337933eb1) +--- + libcli/smb/smb2_signing.c | 5 +++++ + libcli/smb/smb2_signing.h | 3 +++ + 2 files changed, 8 insertions(+) + +diff --git a/libcli/smb/smb2_signing.c b/libcli/smb/smb2_signing.c +index 2f9bae4ba8e..01027d55fbe 100644 +--- a/libcli/smb/smb2_signing.c ++++ b/libcli/smb/smb2_signing.c +@@ -35,6 +35,11 @@ int smb2_signing_key_destructor(struct smb2_signing_key *key) + key->hmac_hnd = NULL; + } + ++ if (key->cipher_hnd != NULL) { ++ gnutls_aead_cipher_deinit(key->cipher_hnd); ++ key->cipher_hnd = NULL; ++ } ++ + return 0; + } + +diff --git a/libcli/smb/smb2_signing.h b/libcli/smb/smb2_signing.h +index 96a002f4a0c..13fb54e4e4e 100644 +--- a/libcli/smb/smb2_signing.h ++++ b/libcli/smb/smb2_signing.h +@@ -25,9 +25,12 @@ struct iovec; + /* Forward declaration of GnuTLS typedefs */ + struct hmac_hd_st; + typedef struct hmac_hd_st* gnutls_hmac_hd_t; ++struct api_aead_cipher_hd_st; ++typedef struct api_aead_cipher_hd_st *gnutls_aead_cipher_hd_t; + + struct smb2_signing_key { + gnutls_hmac_hd_t hmac_hnd; ++ gnutls_aead_cipher_hd_t cipher_hnd; + DATA_BLOB blob; + }; + +-- +2.23.0 + diff --git a/SOURCES/0113-libcli-smb-Use-a-smb2_signing_key-for-storing-the-en.patch b/SOURCES/0113-libcli-smb-Use-a-smb2_signing_key-for-storing-the-en.patch new file mode 100644 index 0000000..b155d73 --- /dev/null +++ b/SOURCES/0113-libcli-smb-Use-a-smb2_signing_key-for-storing-the-en.patch @@ -0,0 +1,102 @@ +From 5076ca90caf92b56a5708cf185835e74ddfe3cfb Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Thu, 14 Mar 2019 09:34:23 +0100 +Subject: [PATCH 113/187] libcli:smb: Use a smb2_signing_key for storing the + encryption key + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 48116a30d51d9bac6201a8b94262aa78b451ad63) +--- + libcli/smb/smbXcli_base.c | 29 +++++++++++++++++++---------- + 1 file changed, 19 insertions(+), 10 deletions(-) + +diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c +index bfc85ecc225..52bc438c389 100644 +--- a/libcli/smb/smbXcli_base.c ++++ b/libcli/smb/smbXcli_base.c +@@ -154,7 +154,7 @@ struct smb2cli_session { + struct smb2_signing_key *signing_key; + bool should_sign; + bool should_encrypt; +- DATA_BLOB encryption_key; ++ struct smb2_signing_key *encryption_key; + DATA_BLOB decryption_key; + uint64_t nonce_high_random; + uint64_t nonce_high_max; +@@ -3090,7 +3090,7 @@ NTSTATUS smb2cli_req_compound_submit(struct tevent_req **reqs, + struct iovec *iov; + int i, num_iov, nbt_len; + int tf_iov = -1; +- const DATA_BLOB *encryption_key = NULL; ++ const struct smb2_signing_key *encryption_key = NULL; + uint64_t encryption_session_id = 0; + uint64_t nonce_high = UINT64_MAX; + uint64_t nonce_low = UINT64_MAX; +@@ -3137,8 +3137,8 @@ NTSTATUS smb2cli_req_compound_submit(struct tevent_req **reqs, + continue; + } + +- encryption_key = &state->session->smb2->encryption_key; +- if (encryption_key->length == 0) { ++ encryption_key = state->session->smb2->encryption_key; ++ if (!smb2_signing_key_valid(encryption_key)) { + return NT_STATUS_INVALID_PARAMETER_MIX; + } + +@@ -3379,7 +3379,7 @@ skip_credits: + buf += v->iov_len; + } + +- status = smb2_signing_encrypt_pdu(*encryption_key, ++ status = smb2_signing_encrypt_pdu(encryption_key->blob, + state->conn->smb2.server.cipher, + &iov[tf_iov], num_iov - tf_iov); + if (!NT_STATUS_IS_OK(status)) { +@@ -5723,11 +5723,11 @@ NTSTATUS smb2cli_session_encryption_key(struct smbXcli_session *session, + return NT_STATUS_NO_USER_SESSION_KEY; + } + +- if (session->smb2->encryption_key.length == 0) { ++ if (!smb2_signing_key_valid(session->smb2->encryption_key)) { + return NT_STATUS_NO_USER_SESSION_KEY; + } + +- *key = data_blob_dup_talloc(mem_ctx, session->smb2->encryption_key); ++ *key = data_blob_dup_talloc(mem_ctx, session->smb2->encryption_key->blob); + if (key->data == NULL) { + return NT_STATUS_NO_MEMORY; + } +@@ -6121,9 +6121,18 @@ NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session, + } + + session->smb2->encryption_key = +- data_blob_dup_talloc(session, ++ talloc_zero(session, struct smb2_signing_key); ++ if (session->smb2->encryption_key == NULL) { ++ ZERO_STRUCT(session_key); ++ return NT_STATUS_NO_MEMORY; ++ } ++ talloc_set_destructor(session->smb2->encryption_key, ++ smb2_signing_key_destructor); ++ ++ session->smb2->encryption_key->blob = ++ data_blob_dup_talloc(session->smb2->encryption_key, + session->smb2->signing_key->blob); +- if (session->smb2->encryption_key.data == NULL) { ++ if (!smb2_signing_key_valid(session->smb2->encryption_key)) { + ZERO_STRUCT(session_key); + return NT_STATUS_NO_MEMORY; + } +@@ -6134,7 +6143,7 @@ NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session, + status = smb2_key_derivation(session_key, sizeof(session_key), + d->label.data, d->label.length, + d->context.data, d->context.length, +- session->smb2->encryption_key.data); ++ session->smb2->encryption_key->blob.data); + if (!NT_STATUS_IS_OK(status)) { + return status; + } +-- +2.23.0 + diff --git a/SOURCES/0114-libcli-smb-Use-a-smb2_signing_key-for-storing-the-de.patch b/SOURCES/0114-libcli-smb-Use-a-smb2_signing_key-for-storing-the-de.patch new file mode 100644 index 0000000..03234bf --- /dev/null +++ b/SOURCES/0114-libcli-smb-Use-a-smb2_signing_key-for-storing-the-de.patch @@ -0,0 +1,82 @@ +From 225ae1ca2ea83fe0cb212b6675770d8053ff07ce Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Thu, 14 Mar 2019 09:48:54 +0100 +Subject: [PATCH 114/187] libcli:smb: Use a smb2_signing_key for storing the + decryption key + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 87832f6140aa5afb42983a1291ba6faa250c7ea3) +--- + libcli/smb/smbXcli_base.c | 23 ++++++++++++++++------- + 1 file changed, 16 insertions(+), 7 deletions(-) + +diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c +index 52bc438c389..aa69c374d49 100644 +--- a/libcli/smb/smbXcli_base.c ++++ b/libcli/smb/smbXcli_base.c +@@ -155,7 +155,7 @@ struct smb2cli_session { + bool should_sign; + bool should_encrypt; + struct smb2_signing_key *encryption_key; +- DATA_BLOB decryption_key; ++ struct smb2_signing_key *decryption_key; + uint64_t nonce_high_random; + uint64_t nonce_high_max; + uint64_t nonce_high; +@@ -3567,7 +3567,7 @@ static NTSTATUS smb2cli_inbuf_parse_compound(struct smbXcli_conn *conn, + tf_iov[1].iov_base = (void *)hdr; + tf_iov[1].iov_len = enc_len; + +- status = smb2_signing_decrypt_pdu(s->smb2->decryption_key, ++ status = smb2_signing_decrypt_pdu(s->smb2->decryption_key->blob, + conn->smb2.server.cipher, + tf_iov, 2); + if (!NT_STATUS_IS_OK(status)) { +@@ -5747,11 +5747,11 @@ NTSTATUS smb2cli_session_decryption_key(struct smbXcli_session *session, + return NT_STATUS_NO_USER_SESSION_KEY; + } + +- if (session->smb2->decryption_key.length == 0) { ++ if (!smb2_signing_key_valid(session->smb2->decryption_key)) { + return NT_STATUS_NO_USER_SESSION_KEY; + } + +- *key = data_blob_dup_talloc(mem_ctx, session->smb2->decryption_key); ++ *key = data_blob_dup_talloc(mem_ctx, session->smb2->decryption_key->blob); + if (key->data == NULL) { + return NT_STATUS_NO_MEMORY; + } +@@ -6150,9 +6150,18 @@ NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session, + } + + session->smb2->decryption_key = +- data_blob_dup_talloc(session, ++ talloc_zero(session, struct smb2_signing_key); ++ if (session->smb2->decryption_key == NULL) { ++ ZERO_STRUCT(session_key); ++ return NT_STATUS_NO_MEMORY; ++ } ++ talloc_set_destructor(session->smb2->decryption_key, ++ smb2_signing_key_destructor); ++ ++ session->smb2->decryption_key->blob = ++ data_blob_dup_talloc(session->smb2->decryption_key, + session->smb2->signing_key->blob); +- if (session->smb2->decryption_key.data == NULL) { ++ if (!smb2_signing_key_valid(session->smb2->decryption_key)) { + ZERO_STRUCT(session_key); + return NT_STATUS_NO_MEMORY; + } +@@ -6163,7 +6172,7 @@ NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session, + status = smb2_key_derivation(session_key, sizeof(session_key), + d->label.data, d->label.length, + d->context.data, d->context.length, +- session->smb2->decryption_key.data); ++ session->smb2->decryption_key->blob.data); + if (!NT_STATUS_IS_OK(status)) { + return status; + } +-- +2.23.0 + diff --git a/SOURCES/0115-s3-smbd-Use-smb2_signing_key-structure-for-the-encry.patch b/SOURCES/0115-s3-smbd-Use-smb2_signing_key-structure-for-the-encry.patch new file mode 100644 index 0000000..dec2b57 --- /dev/null +++ b/SOURCES/0115-s3-smbd-Use-smb2_signing_key-structure-for-the-encry.patch @@ -0,0 +1,131 @@ +From e644d8953c09ec4c73f1cc623f5b70fcdd65ccc1 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Thu, 14 Mar 2019 10:02:27 +0100 +Subject: [PATCH 115/187] s3:smbd: Use smb2_signing_key structure for the + encryption key + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 95e1c85a47e925fdb9105b85f0e1dbea1ff09950) +--- + source3/librpc/idl/smbXsrv.idl | 1 + + source3/smbd/smb2_server.c | 17 ++++++++++------- + source3/smbd/smb2_sesssetup.c | 24 +++++++++++++++++------- + 3 files changed, 28 insertions(+), 14 deletions(-) + +diff --git a/source3/librpc/idl/smbXsrv.idl b/source3/librpc/idl/smbXsrv.idl +index 72017bc3e15..f7acb2198fb 100644 +--- a/source3/librpc/idl/smbXsrv.idl ++++ b/source3/librpc/idl/smbXsrv.idl +@@ -229,6 +229,7 @@ interface smbXsrv + [noprint] DATA_BLOB signing_key_blob; + [ignore] smb2_signing_key *signing_key; + [noprint] DATA_BLOB encryption_key_blob; ++ [ignore] smb2_signing_key *encryption_key; + [noprint] DATA_BLOB decryption_key_blob; + [noprint] DATA_BLOB application_key; + [range(1, 1024)] uint32 num_channels; +diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c +index c0c4a0272d1..b708fdb90b9 100644 +--- a/source3/smbd/smb2_server.c ++++ b/source3/smbd/smb2_server.c +@@ -1737,9 +1737,9 @@ static void smbd_smb2_request_pending_timer(struct tevent_context *ev, + + if (req->do_encryption) { + struct smbXsrv_session *x = req->session; +- DATA_BLOB encryption_key = x->global->encryption_key_blob; ++ struct smb2_signing_key *encryption_key = x->global->encryption_key; + +- status = smb2_signing_encrypt_pdu(encryption_key, ++ status = smb2_signing_encrypt_pdu(encryption_key->blob, + xconn->smb2.server.cipher, + &state->vector[1+SMBD_SMB2_TF_IOV_OFS], + SMBD_SMB2_NUM_IOV_PER_REQ); +@@ -2852,9 +2852,10 @@ static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req) + (firsttf->iov_len == 0) && + (req->first_key.length == 0) && + (req->session != NULL) && +- (req->session->global->encryption_key_blob.length != 0)) ++ smb2_signing_key_valid(req->session->global->encryption_key)) + { +- DATA_BLOB encryption_key = req->session->global->encryption_key_blob; ++ struct smb2_signing_key *encryption_key = ++ req->session->global->encryption_key; + uint8_t *tf; + uint64_t session_id = req->session->global->session_wire_id; + uint64_t nonce_high; +@@ -2878,7 +2879,8 @@ static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req) + * we are sure that we do not change + * the header again. + */ +- req->first_key = data_blob_dup_talloc(req, encryption_key); ++ req->first_key = data_blob_dup_talloc(req, ++ encryption_key->blob); + if (req->first_key.data == NULL) { + return NT_STATUS_NO_MEMORY; + } +@@ -3414,9 +3416,10 @@ static NTSTATUS smbd_smb2_send_break(struct smbXsrv_connection *xconn, + } + + if (do_encryption) { +- DATA_BLOB encryption_key = session->global->encryption_key_blob; ++ struct smb2_signing_key *encryption_key = ++ session->global->encryption_key; + +- status = smb2_signing_encrypt_pdu(encryption_key, ++ status = smb2_signing_encrypt_pdu(encryption_key->blob, + xconn->smb2.server.cipher, + &state->vector[1+SMBD_SMB2_TF_IOV_OFS], + SMBD_SMB2_NUM_IOV_PER_REQ); +diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c +index 591d5c37160..c2725825d7a 100644 +--- a/source3/smbd/smb2_sesssetup.c ++++ b/source3/smbd/smb2_sesssetup.c +@@ -394,18 +394,28 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session, + struct _derivation *d = &derivation.encryption; + size_t nonce_size; + +- x->global->encryption_key_blob = data_blob_talloc(x->global, +- session_key, +- sizeof(session_key)); +- if (x->global->encryption_key_blob.data == NULL) { ++ x->global->encryption_key = ++ talloc_zero(x->global, struct smb2_signing_key); ++ if (x->global->encryption_key == NULL) { ++ ZERO_STRUCT(session_key); ++ return NT_STATUS_NO_MEMORY; ++ } ++ ++ x->global->encryption_key->blob = ++ x->global->encryption_key_blob = ++ data_blob_talloc(x->global->encryption_key, ++ session_key, ++ sizeof(session_key)); ++ if (!smb2_signing_key_valid(x->global->encryption_key)) { + ZERO_STRUCT(session_key); + return NT_STATUS_NO_MEMORY; + } ++ talloc_keep_secret(x->global->encryption_key->blob.data); + + status = smb2_key_derivation(session_key, sizeof(session_key), + d->label.data, d->label.length, + d->context.data, d->context.length, +- x->global->encryption_key_blob.data); ++ x->global->encryption_key->blob.data); + if (!NT_STATUS_IS_OK(status)) { + return status; + } +@@ -477,8 +487,8 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session, + dump_data(0, x->global->decryption_key_blob.data, + x->global->decryption_key_blob.length); + DEBUGADD(0, ("ServerOut Key ")); +- dump_data(0, x->global->encryption_key_blob.data, +- x->global->encryption_key_blob.length); ++ dump_data(0, x->global->encryption_key->blob.data, ++ x->global->encryption_key->blob.length); + } + + ZERO_STRUCT(session_key); +-- +2.23.0 + diff --git a/SOURCES/0116-s3-smbd-Use-smb2_signing_key-structure-for-the-decry.patch b/SOURCES/0116-s3-smbd-Use-smb2_signing_key-structure-for-the-decry.patch new file mode 100644 index 0000000..a93dd46 --- /dev/null +++ b/SOURCES/0116-s3-smbd-Use-smb2_signing_key-structure-for-the-decry.patch @@ -0,0 +1,92 @@ +From 4dc911798e6e5a534c194cb2519c955a0589bf66 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Thu, 14 Mar 2019 10:10:34 +0100 +Subject: [PATCH 116/187] s3:smbd: Use smb2_signing_key structure for the + decryption key + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit b51c4293f7430b5ce6a81599fb0c7be5dc444c46) +--- + source3/librpc/idl/smbXsrv.idl | 1 + + source3/smbd/smb2_server.c | 2 +- + source3/smbd/smb2_sesssetup.c | 24 +++++++++++++++++------- + 3 files changed, 19 insertions(+), 8 deletions(-) + +diff --git a/source3/librpc/idl/smbXsrv.idl b/source3/librpc/idl/smbXsrv.idl +index f7acb2198fb..330c6896114 100644 +--- a/source3/librpc/idl/smbXsrv.idl ++++ b/source3/librpc/idl/smbXsrv.idl +@@ -231,6 +231,7 @@ interface smbXsrv + [noprint] DATA_BLOB encryption_key_blob; + [ignore] smb2_signing_key *encryption_key; + [noprint] DATA_BLOB decryption_key_blob; ++ [ignore] smb2_signing_key *decryption_key; + [noprint] DATA_BLOB application_key; + [range(1, 1024)] uint32 num_channels; + smbXsrv_channel_global0 channels[num_channels]; +diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c +index b708fdb90b9..56e7b70696b 100644 +--- a/source3/smbd/smb2_server.c ++++ b/source3/smbd/smb2_server.c +@@ -432,7 +432,7 @@ static NTSTATUS smbd_smb2_inbuf_parse_compound(struct smbXsrv_connection *xconn, + tf_iov[1].iov_base = (void *)hdr; + tf_iov[1].iov_len = enc_len; + +- status = smb2_signing_decrypt_pdu(s->global->decryption_key_blob, ++ status = smb2_signing_decrypt_pdu(s->global->decryption_key->blob, + xconn->smb2.server.cipher, + tf_iov, 2); + if (!NT_STATUS_IS_OK(status)) { +diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c +index c2725825d7a..d6900665a95 100644 +--- a/source3/smbd/smb2_sesssetup.c ++++ b/source3/smbd/smb2_sesssetup.c +@@ -373,18 +373,28 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session, + if (xconn->protocol >= PROTOCOL_SMB2_24) { + struct _derivation *d = &derivation.decryption; + +- x->global->decryption_key_blob = data_blob_talloc(x->global, +- session_key, +- sizeof(session_key)); +- if (x->global->decryption_key_blob.data == NULL) { ++ x->global->decryption_key = ++ talloc_zero(x->global, struct smb2_signing_key); ++ if (x->global->decryption_key == NULL) { ++ ZERO_STRUCT(session_key); ++ return NT_STATUS_NO_MEMORY; ++ } ++ ++ x->global->decryption_key->blob = ++ x->global->decryption_key_blob = ++ data_blob_talloc(x->global->decryption_key, ++ session_key, ++ sizeof(session_key)); ++ if (!smb2_signing_key_valid(x->global->decryption_key)) { + ZERO_STRUCT(session_key); + return NT_STATUS_NO_MEMORY; + } ++ talloc_keep_secret(x->global->decryption_key->blob.data); + + status = smb2_key_derivation(session_key, sizeof(session_key), + d->label.data, d->label.length, + d->context.data, d->context.length, +- x->global->decryption_key_blob.data); ++ x->global->decryption_key->blob.data); + if (!NT_STATUS_IS_OK(status)) { + return status; + } +@@ -484,8 +494,8 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session, + /* In server code, ServerIn is the decryption key */ + + DEBUGADD(0, ("ServerIn Key ")); +- dump_data(0, x->global->decryption_key_blob.data, +- x->global->decryption_key_blob.length); ++ dump_data(0, x->global->decryption_key->blob.data, ++ x->global->decryption_key->blob.length); + DEBUGADD(0, ("ServerOut Key ")); + dump_data(0, x->global->encryption_key->blob.data, + x->global->encryption_key->blob.length); +-- +2.23.0 + diff --git a/SOURCES/0117-s3-smbd-Use-GnuTLS-for-AES-constants.patch b/SOURCES/0117-s3-smbd-Use-GnuTLS-for-AES-constants.patch new file mode 100644 index 0000000..589327a --- /dev/null +++ b/SOURCES/0117-s3-smbd-Use-GnuTLS-for-AES-constants.patch @@ -0,0 +1,46 @@ +From ad4ee458c404dda36480a9c501e1ffb221b35b61 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Tue, 26 Feb 2019 18:11:27 +0100 +Subject: [PATCH 117/187] s3:smbd: Use GnuTLS for AES constants + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett + +Adapted to remove Samba AES + +Signed-off-by: Andrew Bartlett +(cherry picked from commit 33bca1fb8087f7392a8ff0d295a5bdc01f1012e7) +--- + source3/smbd/smb2_sesssetup.c | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) + +diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c +index d6900665a95..82ac1182ecc 100644 +--- a/source3/smbd/smb2_sesssetup.c ++++ b/source3/smbd/smb2_sesssetup.c +@@ -28,9 +28,6 @@ + #include "../lib/tsocket/tsocket.h" + #include "../libcli/security/security.h" + #include "../lib/util/tevent_ntstatus.h" +-#include "lib/crypto/aes.h" +-#include "lib/crypto/aes_ccm_128.h" +-#include "lib/crypto/aes_gcm_128.h" + + #include "lib/crypto/gnutls_helpers.h" + #include +@@ -443,10 +440,10 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session, + sizeof(x->nonce_high_random)); + switch (xconn->smb2.server.cipher) { + case SMB2_ENCRYPTION_AES128_CCM: +- nonce_size = AES_CCM_128_NONCE_SIZE; ++ nonce_size = SMB2_AES_128_CCM_NONCE_SIZE; + break; + case SMB2_ENCRYPTION_AES128_GCM: +- nonce_size = AES_GCM_128_IV_SIZE; ++ nonce_size = gnutls_cipher_get_iv_size(GNUTLS_CIPHER_AES_128_GCM); + break; + default: + nonce_size = 0; +-- +2.23.0 + diff --git a/SOURCES/0118-waf-Check-for-AES128-CMAC-support-in-GnuTLS.patch b/SOURCES/0118-waf-Check-for-AES128-CMAC-support-in-GnuTLS.patch new file mode 100644 index 0000000..919bf3b --- /dev/null +++ b/SOURCES/0118-waf-Check-for-AES128-CMAC-support-in-GnuTLS.patch @@ -0,0 +1,28 @@ +From 9dbaac0a6d4bc0a5dfd3b08ceeab5e0e0245e090 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 27 Feb 2019 14:40:07 +0100 +Subject: [PATCH 118/187] waf: Check for AES128 CMAC support in GnuTLS + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 69be6b8416198cfa8e2404a0a62ce6432425adef) +--- + wscript_configure_system_gnutls | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/wscript_configure_system_gnutls b/wscript_configure_system_gnutls +index 68cc306e3dc..f71fd4fb97f 100644 +--- a/wscript_configure_system_gnutls ++++ b/wscript_configure_system_gnutls +@@ -19,3 +19,8 @@ if conf.CHECK_VALUEOF('GNUTLS_CIPHER_AES_128_CFB8', headers='gnutls/gnutls.h'): + conf.DEFINE('HAVE_GNUTLS_AES_CFB8', 1) + else: + Logs.warn('No gnutls support for AES CFB8') ++ ++if conf.CHECK_VALUEOF('GNUTLS_MAC_AES_CMAC_128', headers='gnutls/gnutls.h'): ++ conf.DEFINE('HAVE_GNUTLS_AES_CMAC', 1) ++else: ++ Logs.warn('No gnutls support for AES CMAC') +-- +2.23.0 + diff --git a/SOURCES/0119-libcli-smb-Use-GnuTLS-AES128-CMAC-in-smb2_signing_si.patch b/SOURCES/0119-libcli-smb-Use-GnuTLS-AES128-CMAC-in-smb2_signing_si.patch new file mode 100644 index 0000000..ad98e9e --- /dev/null +++ b/SOURCES/0119-libcli-smb-Use-GnuTLS-AES128-CMAC-in-smb2_signing_si.patch @@ -0,0 +1,79 @@ +From d693c836b1d5f37d9dae8a6dbefc7b731863eacb Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 27 Feb 2019 14:40:30 +0100 +Subject: [PATCH 119/187] libcli:smb: Use GnuTLS AES128 CMAC in + smb2_signing_sign_pdu() + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett + +Adapted by Andrew Bartlett to followup from earlier patch to +allow compile without GnuTLS over the whole series. + +Signed-off-by: Andrew Bartlett +(cherry picked from commit ee11e3ffd8d801cb5988bb73dbccd1e2f0cbe7b0) +--- + libcli/smb/smb2_signing.c | 33 +++++++++++++++++++++++++++++++++ + 1 file changed, 33 insertions(+) + +diff --git a/libcli/smb/smb2_signing.c b/libcli/smb/smb2_signing.c +index 01027d55fbe..b7c0be528b7 100644 +--- a/libcli/smb/smb2_signing.c ++++ b/libcli/smb/smb2_signing.c +@@ -24,6 +24,11 @@ + #include "../lib/crypto/crypto.h" + #include "lib/util/iov_buf.h" + ++#ifndef HAVE_GNUTLS_AES_CMAC ++#include "lib/crypto/aes.h" ++#include "lib/crypto/aes_cmac_128.h" ++#endif ++ + #include "lib/crypto/gnutls_helpers.h" + #include + #include +@@ -96,6 +101,33 @@ NTSTATUS smb2_signing_sign_pdu(struct smb2_signing_key *signing_key, + SIVAL(hdr, SMB2_HDR_FLAGS, IVAL(hdr, SMB2_HDR_FLAGS) | SMB2_HDR_FLAG_SIGNED); + + if (protocol >= PROTOCOL_SMB2_24) { ++#ifdef HAVE_GNUTLS_AES_CMAC ++ gnutls_datum_t key = { ++ .data = signing_key->blob.data, ++ .size = MIN(signing_key->blob.length, 16), ++ }; ++ int rc; ++ ++ if (signing_key->hmac_hnd == NULL) { ++ rc = gnutls_hmac_init(&signing_key->hmac_hnd, ++ GNUTLS_MAC_AES_CMAC_128, ++ key.data, ++ key.size); ++ if (rc < 0) { ++ return NT_STATUS_NO_MEMORY; ++ } ++ } ++ ++ for (i = 0; i < count; i++) { ++ rc = gnutls_hmac(signing_key->hmac_hnd, ++ vector[i].iov_base, ++ vector[i].iov_len); ++ if (rc < 0) { ++ return NT_STATUS_INTERNAL_ERROR; ++ } ++ } ++ gnutls_hmac_output(signing_key->hmac_hnd, res); ++#else /* NOT HAVE_GNUTLS_AES_CMAC */ + struct aes_cmac_128_context ctx; + uint8_t key[AES_BLOCK_SIZE] = {0}; + +@@ -112,6 +144,7 @@ NTSTATUS smb2_signing_sign_pdu(struct smb2_signing_key *signing_key, + aes_cmac_128_final(&ctx, res); + + ZERO_ARRAY(key); ++#endif /* HAVE_GNUTLS_AES_CMAC */ + } else { + uint8_t digest[gnutls_hmac_get_len(GNUTLS_MAC_SHA256)]; + int rc; +-- +2.23.0 + diff --git a/SOURCES/0120-libcli-smb-Use-gnutls_error_to_ntstatus-in-smb2_sign.patch b/SOURCES/0120-libcli-smb-Use-gnutls_error_to_ntstatus-in-smb2_sign.patch new file mode 100644 index 0000000..cc4684b --- /dev/null +++ b/SOURCES/0120-libcli-smb-Use-gnutls_error_to_ntstatus-in-smb2_sign.patch @@ -0,0 +1,38 @@ +From a7169122940d8eb3e37320dc1dca4c99e0c6f37a Mon Sep 17 00:00:00 2001 +From: Andrew Bartlett +Date: Fri, 16 Aug 2019 15:47:49 +1200 +Subject: [PATCH 120/187] libcli/smb: Use gnutls_error_to_ntstatus() in + smb2_signing_sign_pdu() + +Signed-off-by: Andrew Bartlett +Reviewed-by: Andreas Schneider +(cherry picked from commit 9d8ffc81a53b6b3d7c29f0da8fd71e696ca7e9d8) +--- + libcli/smb/smb2_signing.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libcli/smb/smb2_signing.c b/libcli/smb/smb2_signing.c +index b7c0be528b7..466fe9a49e3 100644 +--- a/libcli/smb/smb2_signing.c ++++ b/libcli/smb/smb2_signing.c +@@ -114,7 +114,7 @@ NTSTATUS smb2_signing_sign_pdu(struct smb2_signing_key *signing_key, + key.data, + key.size); + if (rc < 0) { +- return NT_STATUS_NO_MEMORY; ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_HMAC_NOT_SUPPORTED); + } + } + +@@ -123,7 +123,7 @@ NTSTATUS smb2_signing_sign_pdu(struct smb2_signing_key *signing_key, + vector[i].iov_base, + vector[i].iov_len); + if (rc < 0) { +- return NT_STATUS_INTERNAL_ERROR; ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_HMAC_NOT_SUPPORTED); + } + } + gnutls_hmac_output(signing_key->hmac_hnd, res); +-- +2.23.0 + diff --git a/SOURCES/0121-libcli-smb-Use-GnuTLS-AES128-CMAC-in-smb2_signing_ch.patch b/SOURCES/0121-libcli-smb-Use-GnuTLS-AES128-CMAC-in-smb2_signing_ch.patch new file mode 100644 index 0000000..2638564 --- /dev/null +++ b/SOURCES/0121-libcli-smb-Use-GnuTLS-AES128-CMAC-in-smb2_signing_ch.patch @@ -0,0 +1,72 @@ +From 7f4ab026bdb4b276a76c8359481124ff77597a42 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Fri, 15 Mar 2019 16:58:21 +0100 +Subject: [PATCH 121/187] libcli:smb: Use GnuTLS AES128 CMAC in + smb2_signing_check_pdu() + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 1490f9260060104b31beefac9e61addd36b1919a) +--- + libcli/smb/smb2_signing.c | 38 ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 38 insertions(+) + +diff --git a/libcli/smb/smb2_signing.c b/libcli/smb/smb2_signing.c +index 466fe9a49e3..5bf61bd477b 100644 +--- a/libcli/smb/smb2_signing.c ++++ b/libcli/smb/smb2_signing.c +@@ -216,6 +216,43 @@ NTSTATUS smb2_signing_check_pdu(struct smb2_signing_key *signing_key, + sig = hdr+SMB2_HDR_SIGNATURE; + + if (protocol >= PROTOCOL_SMB2_24) { ++#ifdef HAVE_GNUTLS_AES_CMAC ++ gnutls_datum_t key = { ++ .data = signing_key->blob.data, ++ .size = MIN(signing_key->blob.length, 16), ++ }; ++ int rc; ++ ++ if (signing_key->hmac_hnd == NULL) { ++ rc = gnutls_hmac_init(&signing_key->hmac_hnd, ++ GNUTLS_MAC_AES_CMAC_128, ++ key.data, ++ key.size); ++ if (rc < 0) { ++ return NT_STATUS_NO_MEMORY; ++ } ++ } ++ ++ rc = gnutls_hmac(signing_key->hmac_hnd, hdr, SMB2_HDR_SIGNATURE); ++ if (rc < 0) { ++ return NT_STATUS_INTERNAL_ERROR; ++ } ++ ++ rc = gnutls_hmac(signing_key->hmac_hnd, zero_sig, 16); ++ if (rc < 0) { ++ return NT_STATUS_INTERNAL_ERROR; ++ } ++ ++ for (i = 1; i < count; i++) { ++ rc = gnutls_hmac(signing_key->hmac_hnd, ++ vector[i].iov_base, ++ vector[i].iov_len); ++ if (rc < 0) { ++ return NT_STATUS_INTERNAL_ERROR; ++ } ++ } ++ gnutls_hmac_output(signing_key->hmac_hnd, res); ++#else /* NOT HAVE_GNUTLS_AES_CMAC */ + struct aes_cmac_128_context ctx; + uint8_t key[AES_BLOCK_SIZE] = {0}; + +@@ -234,6 +271,7 @@ NTSTATUS smb2_signing_check_pdu(struct smb2_signing_key *signing_key, + aes_cmac_128_final(&ctx, res); + + ZERO_ARRAY(key); ++#endif + } else { + uint8_t digest[gnutls_hash_get_len(GNUTLS_MAC_SHA256)]; + int rc; +-- +2.23.0 + diff --git a/SOURCES/0122-libcli-smb-Use-gnutls_error_to_ntstatus-in-smb2_sign.patch b/SOURCES/0122-libcli-smb-Use-gnutls_error_to_ntstatus-in-smb2_sign.patch new file mode 100644 index 0000000..2018bb7 --- /dev/null +++ b/SOURCES/0122-libcli-smb-Use-gnutls_error_to_ntstatus-in-smb2_sign.patch @@ -0,0 +1,51 @@ +From 1aa93773ac48915c8eaabc959ae2bf65037a368c Mon Sep 17 00:00:00 2001 +From: Andrew Bartlett +Date: Fri, 16 Aug 2019 15:50:03 +1200 +Subject: [PATCH 122/187] libcli/smb: Use gnutls_error_to_ntstatus() in + smb2_signing_check_pdu() + +Signed-off-by: Andrew Bartlett +Reviewed-by: Andreas Schneider +(cherry picked from commit 70ff03ecb6826525727d87ef8807428f91f4e506) +--- + libcli/smb/smb2_signing.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/libcli/smb/smb2_signing.c b/libcli/smb/smb2_signing.c +index 5bf61bd477b..1ec60a4f9a5 100644 +--- a/libcli/smb/smb2_signing.c ++++ b/libcli/smb/smb2_signing.c +@@ -229,18 +229,18 @@ NTSTATUS smb2_signing_check_pdu(struct smb2_signing_key *signing_key, + key.data, + key.size); + if (rc < 0) { +- return NT_STATUS_NO_MEMORY; ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_HMAC_NOT_SUPPORTED); + } + } + + rc = gnutls_hmac(signing_key->hmac_hnd, hdr, SMB2_HDR_SIGNATURE); + if (rc < 0) { +- return NT_STATUS_INTERNAL_ERROR; ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_HMAC_NOT_SUPPORTED); + } + + rc = gnutls_hmac(signing_key->hmac_hnd, zero_sig, 16); + if (rc < 0) { +- return NT_STATUS_INTERNAL_ERROR; ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_HMAC_NOT_SUPPORTED); + } + + for (i = 1; i < count; i++) { +@@ -248,7 +248,7 @@ NTSTATUS smb2_signing_check_pdu(struct smb2_signing_key *signing_key, + vector[i].iov_base, + vector[i].iov_len); + if (rc < 0) { +- return NT_STATUS_INTERNAL_ERROR; ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_HMAC_NOT_SUPPORTED); + } + } + gnutls_hmac_output(signing_key->hmac_hnd, res); +-- +2.23.0 + diff --git a/SOURCES/0123-lib-crypto-Do-not-build-AES-CMAC-if-we-use-GnuTLS-th.patch b/SOURCES/0123-lib-crypto-Do-not-build-AES-CMAC-if-we-use-GnuTLS-th.patch new file mode 100644 index 0000000..ce22e15 --- /dev/null +++ b/SOURCES/0123-lib-crypto-Do-not-build-AES-CMAC-if-we-use-GnuTLS-th.patch @@ -0,0 +1,72 @@ +From 5c7eee2facbfc51078ecbdfcfe895a1215e56029 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Fri, 15 Mar 2019 14:54:13 +0100 +Subject: [PATCH 123/187] lib:crypto: Do not build AES-CMAC if we use GnuTLS + that supports it + +This requires GnuTLS >= 3.6.5. + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett + +Autobuild-User(master): Andreas Schneider +Autobuild-Date(master): Wed Aug 21 11:14:11 UTC 2019 on sn-devel-184 + +(cherry picked from commit c3f969817553dc9c9db88741bad51100b4d24604) +--- + lib/crypto/wscript_build | 6 ++++-- + source4/torture/local/local.c | 4 ++++ + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/lib/crypto/wscript_build b/lib/crypto/wscript_build +index dcac8fcd30c..4f1665a7fd9 100644 +--- a/lib/crypto/wscript_build ++++ b/lib/crypto/wscript_build +@@ -26,7 +26,8 @@ bld.SAMBA_SUBSYSTEM('LIBCRYPTO_AES', + + bld.SAMBA_SUBSYSTEM('LIBCRYPTO_AES_CMAC', + source='aes_cmac_128.c', +- deps='talloc') ++ deps='talloc', ++ enabled=not bld.CONFIG_SET('HAVE_GNUTLS_AES_CMAC')) + + bld.SAMBA_SUBSYSTEM('LIBCRYPTO', + source=''' +@@ -53,7 +54,8 @@ bld.SAMBA_SUBSYSTEM('TORTURE_LIBCRYPTO_AES_GCM', + bld.SAMBA_SUBSYSTEM('TORTURE_LIBCRYPTO_AES_CMAC', + source='aes_cmac_128_test.c', + autoproto='aes_cmac_test_proto.h', +- deps='talloc') ++ deps='talloc', ++ enabled=not bld.CONFIG_SET('HAVE_GNUTLS_AES_CMAC')) + + bld.SAMBA_SUBSYSTEM('TORTURE_LIBCRYPTO', + source='md4test.c', +diff --git a/source4/torture/local/local.c b/source4/torture/local/local.c +index fa4061c108b..5812f4dd20c 100644 +--- a/source4/torture/local/local.c ++++ b/source4/torture/local/local.c +@@ -25,7 +25,9 @@ + #include "../lib/crypto/test_proto.h" + #include "../lib/crypto/aes_ccm_test_proto.h" + #include "../lib/crypto/aes_gcm_test_proto.h" ++#ifndef HAVE_GNUTLS_AES_CMAC + #include "../lib/crypto/aes_cmac_test_proto.h" ++#endif + #include "lib/registry/tests/proto.h" + #include "lib/replace/replace-testsuite.h" + +@@ -94,8 +96,10 @@ NTSTATUS torture_local_init(TALLOC_CTX *ctx) + + torture_suite_add_simple_test(suite, + "crypto.md4", torture_local_crypto_md4); ++#ifndef HAVE_GNUTLS_AES_CMAC + torture_suite_add_simple_test(suite, "crypto.aes_cmac_128", + torture_local_crypto_aes_cmac_128); ++#endif + torture_suite_add_simple_test(suite, "crypto.aes_ccm_128", + torture_local_crypto_aes_ccm_128); + torture_suite_add_simple_test(suite, "crypto.aes_gcm_128", +-- +2.23.0 + diff --git a/SOURCES/0124-libcli-smb-Support-GnuTLS-AES-CCM-and-GCM-in-smb2_si.patch b/SOURCES/0124-libcli-smb-Support-GnuTLS-AES-CCM-and-GCM-in-smb2_si.patch new file mode 100644 index 0000000..aa3f7c0 --- /dev/null +++ b/SOURCES/0124-libcli-smb-Support-GnuTLS-AES-CCM-and-GCM-in-smb2_si.patch @@ -0,0 +1,225 @@ +From c69a481c6777b156165fe1226b3af7c4be365be4 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Mon, 25 Feb 2019 18:05:16 +0100 +Subject: [PATCH 124/187] libcli:smb: Support GnuTLS AES CCM and GCM in + smb2_signing_encrypt_pdu() + +This requires GnuTLS >= 3.4.0. + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett + +Adapted to remove Samba AES support + +Signed-off-by: Andrew Bartlett +(cherry picked from commit f43da2adf64a8ff20ce6478f656927e531bc42af) +--- + libcli/smb/smb2_signing.c | 169 ++++++++++++++++++++++++++++---------- + 1 file changed, 124 insertions(+), 45 deletions(-) + +diff --git a/libcli/smb/smb2_signing.c b/libcli/smb/smb2_signing.c +index 1ec60a4f9a5..52209d9553b 100644 +--- a/libcli/smb/smb2_signing.c ++++ b/libcli/smb/smb2_signing.c +@@ -392,15 +392,19 @@ NTSTATUS smb2_signing_encrypt_pdu(DATA_BLOB encryption_key, + int count) + { + uint8_t *tf; +- uint8_t sig[16]; + int i; + size_t a_total; + ssize_t m_total; +- union { +- struct aes_ccm_128_context ccm; +- struct aes_gcm_128_context gcm; +- } c; +- uint8_t key[AES_BLOCK_SIZE]; ++ uint32_t iv_size = 0; ++ uint32_t key_size = 0; ++ uint32_t tag_size = 0; ++ uint8_t _key[16] = {0}; ++ gnutls_cipher_algorithm_t algo = 0; ++ gnutls_aead_cipher_hd_t cipher_hnd = NULL; ++ gnutls_datum_t key; ++ gnutls_datum_t iv; ++ NTSTATUS status; ++ int rc; + + if (count < 1) { + return NT_STATUS_INVALID_PARAMETER; +@@ -428,58 +432,133 @@ NTSTATUS smb2_signing_encrypt_pdu(DATA_BLOB encryption_key, + SSVAL(tf, SMB2_TF_FLAGS, SMB2_TF_FLAGS_ENCRYPTED); + SIVAL(tf, SMB2_TF_MSG_SIZE, m_total); + +- ZERO_STRUCT(key); +- memcpy(key, encryption_key.data, +- MIN(encryption_key.length, AES_BLOCK_SIZE)); +- + switch (cipher_id) { + case SMB2_ENCRYPTION_AES128_CCM: +- aes_ccm_128_init(&c.ccm, key, +- tf + SMB2_TF_NONCE, +- a_total, m_total); +- memset(tf + SMB2_TF_NONCE + AES_CCM_128_NONCE_SIZE, 0, +- 16 - AES_CCM_128_NONCE_SIZE); +- aes_ccm_128_update(&c.ccm, tf + SMB2_TF_NONCE, a_total); +- for (i=1; i < count; i++) { +- aes_ccm_128_update(&c.ccm, +- (const uint8_t *)vector[i].iov_base, +- vector[i].iov_len); +- aes_ccm_128_crypt(&c.ccm, +- (uint8_t *)vector[i].iov_base, +- vector[i].iov_len); +- } +- aes_ccm_128_digest(&c.ccm, sig); ++ algo = GNUTLS_CIPHER_AES_128_CCM; ++ iv_size = SMB2_AES_128_CCM_NONCE_SIZE; + break; +- + case SMB2_ENCRYPTION_AES128_GCM: +- aes_gcm_128_init(&c.gcm, key, tf + SMB2_TF_NONCE); +- memset(tf + SMB2_TF_NONCE + AES_GCM_128_IV_SIZE, 0, +- 16 - AES_GCM_128_IV_SIZE); +- aes_gcm_128_updateA(&c.gcm, tf + SMB2_TF_NONCE, a_total); +- for (i=1; i < count; i++) { +- aes_gcm_128_crypt(&c.gcm, +- (uint8_t *)vector[i].iov_base, +- vector[i].iov_len); +- aes_gcm_128_updateC(&c.gcm, +- (const uint8_t *)vector[i].iov_base, +- vector[i].iov_len); +- } +- aes_gcm_128_digest(&c.gcm, sig); ++ algo = GNUTLS_CIPHER_AES_128_GCM; ++ iv_size = gnutls_cipher_get_iv_size(algo); + break; +- + default: +- ZERO_STRUCT(key); + return NT_STATUS_INVALID_PARAMETER; + } +- ZERO_STRUCT(key); + +- memcpy(tf + SMB2_TF_SIGNATURE, sig, 16); ++ key_size = gnutls_cipher_get_key_size(algo); ++ tag_size = gnutls_cipher_get_tag_size(algo); + +- DEBUG(5,("encrypt SMB2 message\n")); ++ if (key_size > sizeof(_key)) { ++ return NT_STATUS_BUFFER_TOO_SMALL; ++ } + +- return NT_STATUS_OK; ++ key = (gnutls_datum_t) { ++ .data = _key, ++ .size = key_size, ++ }; ++ ++ memcpy(key.data, ++ encryption_key.data, ++ MIN(encryption_key.length, key.size)); ++ ++ iv = (gnutls_datum_t) { ++ .data = tf + SMB2_TF_NONCE, ++ .size = iv_size, ++ }; ++ ++ rc = gnutls_aead_cipher_init(&cipher_hnd, ++ algo, ++ &key); ++ if (rc < 0) { ++ status = NT_STATUS_NO_MEMORY; ++ goto out; ++ } ++ ++ memset(tf + SMB2_TF_NONCE + iv_size, ++ 0, ++ 16 - iv_size); ++ ++ { ++ size_t ptext_size = m_total; ++ uint8_t *ptext = NULL; ++ size_t ctext_size = m_total + tag_size; ++ uint8_t *ctext = NULL; ++ size_t len = 0; ++ ++ ptext = talloc_size(talloc_tos(), ptext_size); ++ if (ptext == NULL) { ++ gnutls_aead_cipher_deinit(cipher_hnd); ++ status = NT_STATUS_NO_MEMORY; ++ goto out; ++ } ++ ++ ctext = talloc_size(talloc_tos(), ctext_size); ++ if (ctext == NULL) { ++ gnutls_aead_cipher_deinit(cipher_hnd); ++ status = NT_STATUS_NO_MEMORY; ++ goto out; ++ } ++ ++ for (i = 1; i < count; i++) { ++ memcpy(ptext + len, ++ vector[i].iov_base, ++ vector[i].iov_len); ++ ++ len += vector[i].iov_len; ++ if (len > ptext_size) { ++ TALLOC_FREE(ptext); ++ TALLOC_FREE(ctext); ++ gnutls_aead_cipher_deinit(cipher_hnd); ++ status = NT_STATUS_INTERNAL_ERROR; ++ goto out; ++ } ++ } ++ ++ rc = gnutls_aead_cipher_encrypt(cipher_hnd, ++ iv.data, ++ iv.size, ++ tf + SMB2_TF_NONCE, ++ a_total, ++ tag_size, ++ ptext, ++ ptext_size, ++ ctext, ++ &ctext_size); ++ if (rc < 0 || ctext_size != m_total + tag_size) { ++ DBG_ERR("ERROR: %s\n", gnutls_strerror(rc)); ++ TALLOC_FREE(ptext); ++ TALLOC_FREE(ctext); ++ gnutls_aead_cipher_deinit(cipher_hnd); ++ status = NT_STATUS_INTERNAL_ERROR; ++ goto out; ++ } ++ ++ len = 0; ++ for (i = 1; i < count; i++) { ++ memcpy(vector[i].iov_base, ++ ctext + len, ++ vector[i].iov_len); ++ ++ len += vector[i].iov_len; ++ } ++ ++ memcpy(tf + SMB2_TF_SIGNATURE, ctext + m_total, tag_size); ++ ++ TALLOC_FREE(ptext); ++ TALLOC_FREE(ctext); ++ } ++ gnutls_aead_cipher_deinit(cipher_hnd); ++ ++ DBG_INFO("Enencrypted SMB2 message\n"); ++ ++ status = NT_STATUS_OK; ++out: ++ ZERO_ARRAY(_key); ++ ++ return status; + } + ++ + NTSTATUS smb2_signing_decrypt_pdu(DATA_BLOB decryption_key, + uint16_t cipher_id, + struct iovec *vector, +-- +2.23.0 + diff --git a/SOURCES/0125-libcli-smb-Support-GnuTLS-AES-CCM-and-GCM-in-smb2_si.patch b/SOURCES/0125-libcli-smb-Support-GnuTLS-AES-CCM-and-GCM-in-smb2_si.patch new file mode 100644 index 0000000..0b77f9f --- /dev/null +++ b/SOURCES/0125-libcli-smb-Support-GnuTLS-AES-CCM-and-GCM-in-smb2_si.patch @@ -0,0 +1,231 @@ +From 94b8f3071fafea18ceb59098f8611a0f2cb5a655 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Tue, 26 Feb 2019 16:43:36 +0100 +Subject: [PATCH 125/187] libcli:smb: Support GnuTLS AES CCM and GCM in + smb2_signing_decrypt_pdu() + +This requires GnuTLS >= 3.4.0. + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett + +Adapted to remove Samba AES support + +Signed-off-by: Andrew Bartlett +(cherry picked from commit 3d2de36d9a08354fb775a5d93a9b40012bf6966f) +--- + libcli/smb/smb2_signing.c | 170 ++++++++++++++++++++++++++++---------- + 1 file changed, 125 insertions(+), 45 deletions(-) + +diff --git a/libcli/smb/smb2_signing.c b/libcli/smb/smb2_signing.c +index 52209d9553b..1d9c99337d8 100644 +--- a/libcli/smb/smb2_signing.c ++++ b/libcli/smb/smb2_signing.c +@@ -558,7 +558,6 @@ out: + return status; + } + +- + NTSTATUS smb2_signing_decrypt_pdu(DATA_BLOB decryption_key, + uint16_t cipher_id, + struct iovec *vector, +@@ -566,17 +565,20 @@ NTSTATUS smb2_signing_decrypt_pdu(DATA_BLOB decryption_key, + { + uint8_t *tf; + uint16_t flags; +- uint8_t *sig_ptr = NULL; +- uint8_t sig[16]; + int i; + size_t a_total; + ssize_t m_total; + uint32_t msg_size = 0; +- union { +- struct aes_ccm_128_context ccm; +- struct aes_gcm_128_context gcm; +- } c; +- uint8_t key[AES_BLOCK_SIZE]; ++ uint32_t iv_size = 0; ++ uint32_t key_size = 0; ++ uint32_t tag_size = 0; ++ uint8_t _key[16] = {0}; ++ gnutls_cipher_algorithm_t algo = 0; ++ gnutls_aead_cipher_hd_t cipher_hnd = NULL; ++ gnutls_datum_t key; ++ gnutls_datum_t iv; ++ NTSTATUS status; ++ int rc; + + if (count < 1) { + return NT_STATUS_INVALID_PARAMETER; +@@ -612,53 +614,131 @@ NTSTATUS smb2_signing_decrypt_pdu(DATA_BLOB decryption_key, + return NT_STATUS_INTERNAL_ERROR; + } + +- ZERO_STRUCT(key); +- memcpy(key, decryption_key.data, +- MIN(decryption_key.length, AES_BLOCK_SIZE)); +- + switch (cipher_id) { + case SMB2_ENCRYPTION_AES128_CCM: +- aes_ccm_128_init(&c.ccm, key, +- tf + SMB2_TF_NONCE, +- a_total, m_total); +- aes_ccm_128_update(&c.ccm, tf + SMB2_TF_NONCE, a_total); +- for (i=1; i < count; i++) { +- aes_ccm_128_crypt(&c.ccm, +- (uint8_t *)vector[i].iov_base, +- vector[i].iov_len); +- aes_ccm_128_update(&c.ccm, +- ( uint8_t *)vector[i].iov_base, +- vector[i].iov_len); +- } +- aes_ccm_128_digest(&c.ccm, sig); ++ algo = GNUTLS_CIPHER_AES_128_CCM; ++ iv_size = SMB2_AES_128_CCM_NONCE_SIZE; + break; +- + case SMB2_ENCRYPTION_AES128_GCM: +- aes_gcm_128_init(&c.gcm, key, tf + SMB2_TF_NONCE); +- aes_gcm_128_updateA(&c.gcm, tf + SMB2_TF_NONCE, a_total); +- for (i=1; i < count; i++) { +- aes_gcm_128_updateC(&c.gcm, +- (const uint8_t *)vector[i].iov_base, +- vector[i].iov_len); +- aes_gcm_128_crypt(&c.gcm, +- (uint8_t *)vector[i].iov_base, +- vector[i].iov_len); +- } +- aes_gcm_128_digest(&c.gcm, sig); ++ algo = GNUTLS_CIPHER_AES_128_GCM; ++ iv_size = gnutls_cipher_get_iv_size(algo); + break; +- + default: +- ZERO_STRUCT(key); + return NT_STATUS_INVALID_PARAMETER; + } +- ZERO_STRUCT(key); + +- sig_ptr = tf + SMB2_TF_SIGNATURE; +- if (memcmp(sig_ptr, sig, 16) != 0) { +- return NT_STATUS_ACCESS_DENIED; ++ key_size = gnutls_cipher_get_key_size(algo); ++ tag_size = gnutls_cipher_get_tag_size(algo); ++ ++ if (key_size > sizeof(_key)) { ++ return NT_STATUS_BUFFER_TOO_SMALL; + } + +- DEBUG(5,("decrypt SMB2 message\n")); ++ key = (gnutls_datum_t) { ++ .data = _key, ++ .size = key_size, ++ }; + +- return NT_STATUS_OK; ++ memcpy(key.data, ++ decryption_key.data, ++ MIN(decryption_key.length, key.size)); ++ ++ iv = (gnutls_datum_t) { ++ .data = tf + SMB2_TF_NONCE, ++ .size = iv_size, ++ }; ++ ++ rc = gnutls_aead_cipher_init(&cipher_hnd, ++ algo, ++ &key); ++ if (rc < 0) { ++ status = NT_STATUS_NO_MEMORY; ++ goto out; ++ } ++ ++ { ++ size_t ctext_size = m_total + tag_size; ++ uint8_t *ctext = NULL; ++ size_t ptext_size = m_total; ++ uint8_t *ptext = NULL; ++ size_t len = 0; ++ ++ /* GnuTLS doesn't have a iovec API for decryption yet */ ++ ++ ptext = talloc_size(talloc_tos(), ptext_size); ++ if (ptext == NULL) { ++ gnutls_aead_cipher_deinit(cipher_hnd); ++ status = NT_STATUS_NO_MEMORY; ++ goto out; ++ } ++ ++ ctext = talloc_size(talloc_tos(), ctext_size); ++ if (ctext == NULL) { ++ TALLOC_FREE(ptext); ++ gnutls_aead_cipher_deinit(cipher_hnd); ++ status = NT_STATUS_NO_MEMORY; ++ goto out; ++ } ++ ++ ++ for (i = 1; i < count; i++) { ++ memcpy(ctext + len, ++ vector[i].iov_base, ++ vector[i].iov_len); ++ ++ len += vector[i].iov_len; ++ } ++ if (len != m_total) { ++ TALLOC_FREE(ptext); ++ TALLOC_FREE(ctext); ++ gnutls_aead_cipher_deinit(cipher_hnd); ++ status = NT_STATUS_INTERNAL_ERROR; ++ goto out; ++ } ++ ++ memcpy(ctext + len, ++ tf + SMB2_TF_SIGNATURE, ++ tag_size); ++ ++ /* This function will verify the tag */ ++ rc = gnutls_aead_cipher_decrypt(cipher_hnd, ++ iv.data, ++ iv.size, ++ tf + SMB2_TF_NONCE, ++ a_total, ++ tag_size, ++ ctext, ++ ctext_size, ++ ptext, ++ &ptext_size); ++ if (rc < 0 || ptext_size != m_total) { ++ DBG_ERR("ERROR: %s\n", gnutls_strerror(rc)); ++ TALLOC_FREE(ptext); ++ TALLOC_FREE(ctext); ++ gnutls_aead_cipher_deinit(cipher_hnd); ++ status = NT_STATUS_INTERNAL_ERROR; ++ goto out; ++ } ++ ++ len = 0; ++ for (i = 1; i < count; i++) { ++ memcpy(vector[i].iov_base, ++ ptext + len, ++ vector[i].iov_len); ++ ++ len += vector[i].iov_len; ++ } ++ ++ TALLOC_FREE(ptext); ++ TALLOC_FREE(ctext); ++ } ++ gnutls_aead_cipher_deinit(cipher_hnd); ++ ++ DBG_INFO("Decrypted SMB2 message\n"); ++ ++ status = NT_STATUS_OK; ++out: ++ ZERO_ARRAY(_key); ++ ++ return status; + } +-- +2.23.0 + diff --git a/SOURCES/0126-libcli-smb-Use-smb2_signing_key-in-smb2_signing_decr.patch b/SOURCES/0126-libcli-smb-Use-smb2_signing_key-in-smb2_signing_decr.patch new file mode 100644 index 0000000..9ab31ce --- /dev/null +++ b/SOURCES/0126-libcli-smb-Use-smb2_signing_key-in-smb2_signing_decr.patch @@ -0,0 +1,176 @@ +From fcbef176770dc8531ab9eb8bb091b44b3923f405 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Thu, 14 Mar 2019 10:53:23 +0100 +Subject: [PATCH 126/187] libcli:smb: Use smb2_signing_key in + smb2_signing_decrypt_pdu() + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett + +Adaped to remove Samba AES support + +Signed-off-by: Andrew Bartlett +(cherry picked from commit 7f56e91dbe404bc1ee40e4843c4046336945b057) +--- + libcli/smb/smb2_signing.c | 34 +++++++++++++++------------------- + libcli/smb/smb2_signing.h | 2 +- + libcli/smb/smbXcli_base.c | 2 +- + source3/smbd/smb2_server.c | 2 +- + 4 files changed, 18 insertions(+), 22 deletions(-) + +diff --git a/libcli/smb/smb2_signing.c b/libcli/smb/smb2_signing.c +index 1d9c99337d8..9f40e8bbea5 100644 +--- a/libcli/smb/smb2_signing.c ++++ b/libcli/smb/smb2_signing.c +@@ -558,7 +558,7 @@ out: + return status; + } + +-NTSTATUS smb2_signing_decrypt_pdu(DATA_BLOB decryption_key, ++NTSTATUS smb2_signing_decrypt_pdu(struct smb2_signing_key *decryption_key, + uint16_t cipher_id, + struct iovec *vector, + int count) +@@ -574,7 +574,6 @@ NTSTATUS smb2_signing_decrypt_pdu(DATA_BLOB decryption_key, + uint32_t tag_size = 0; + uint8_t _key[16] = {0}; + gnutls_cipher_algorithm_t algo = 0; +- gnutls_aead_cipher_hd_t cipher_hnd = NULL; + gnutls_datum_t key; + gnutls_datum_t iv; + NTSTATUS status; +@@ -590,9 +589,9 @@ NTSTATUS smb2_signing_decrypt_pdu(DATA_BLOB decryption_key, + + tf = (uint8_t *)vector[0].iov_base; + +- if (decryption_key.length == 0) { +- DEBUG(2,("Wrong decryption key length %u for SMB2 signing\n", +- (unsigned)decryption_key.length)); ++ if (!smb2_signing_key_valid(decryption_key)) { ++ DBG_WARNING("Wrong decryption key length %zu for SMB2 signing\n", ++ decryption_key->blob.length); + return NT_STATUS_ACCESS_DENIED; + } + +@@ -640,20 +639,22 @@ NTSTATUS smb2_signing_decrypt_pdu(DATA_BLOB decryption_key, + }; + + memcpy(key.data, +- decryption_key.data, +- MIN(decryption_key.length, key.size)); ++ decryption_key->blob.data, ++ MIN(decryption_key->blob.length, key.size)); + + iv = (gnutls_datum_t) { + .data = tf + SMB2_TF_NONCE, + .size = iv_size, + }; + +- rc = gnutls_aead_cipher_init(&cipher_hnd, +- algo, +- &key); +- if (rc < 0) { +- status = NT_STATUS_NO_MEMORY; +- goto out; ++ if (decryption_key->cipher_hnd == NULL) { ++ rc = gnutls_aead_cipher_init(&decryption_key->cipher_hnd, ++ algo, ++ &key); ++ if (rc < 0) { ++ status = NT_STATUS_NO_MEMORY; ++ goto out; ++ } + } + + { +@@ -667,7 +668,6 @@ NTSTATUS smb2_signing_decrypt_pdu(DATA_BLOB decryption_key, + + ptext = talloc_size(talloc_tos(), ptext_size); + if (ptext == NULL) { +- gnutls_aead_cipher_deinit(cipher_hnd); + status = NT_STATUS_NO_MEMORY; + goto out; + } +@@ -675,7 +675,6 @@ NTSTATUS smb2_signing_decrypt_pdu(DATA_BLOB decryption_key, + ctext = talloc_size(talloc_tos(), ctext_size); + if (ctext == NULL) { + TALLOC_FREE(ptext); +- gnutls_aead_cipher_deinit(cipher_hnd); + status = NT_STATUS_NO_MEMORY; + goto out; + } +@@ -691,7 +690,6 @@ NTSTATUS smb2_signing_decrypt_pdu(DATA_BLOB decryption_key, + if (len != m_total) { + TALLOC_FREE(ptext); + TALLOC_FREE(ctext); +- gnutls_aead_cipher_deinit(cipher_hnd); + status = NT_STATUS_INTERNAL_ERROR; + goto out; + } +@@ -701,7 +699,7 @@ NTSTATUS smb2_signing_decrypt_pdu(DATA_BLOB decryption_key, + tag_size); + + /* This function will verify the tag */ +- rc = gnutls_aead_cipher_decrypt(cipher_hnd, ++ rc = gnutls_aead_cipher_decrypt(decryption_key->cipher_hnd, + iv.data, + iv.size, + tf + SMB2_TF_NONCE, +@@ -715,7 +713,6 @@ NTSTATUS smb2_signing_decrypt_pdu(DATA_BLOB decryption_key, + DBG_ERR("ERROR: %s\n", gnutls_strerror(rc)); + TALLOC_FREE(ptext); + TALLOC_FREE(ctext); +- gnutls_aead_cipher_deinit(cipher_hnd); + status = NT_STATUS_INTERNAL_ERROR; + goto out; + } +@@ -732,7 +729,6 @@ NTSTATUS smb2_signing_decrypt_pdu(DATA_BLOB decryption_key, + TALLOC_FREE(ptext); + TALLOC_FREE(ctext); + } +- gnutls_aead_cipher_deinit(cipher_hnd); + + DBG_INFO("Decrypted SMB2 message\n"); + +diff --git a/libcli/smb/smb2_signing.h b/libcli/smb/smb2_signing.h +index 13fb54e4e4e..7eefad93b3e 100644 +--- a/libcli/smb/smb2_signing.h ++++ b/libcli/smb/smb2_signing.h +@@ -57,7 +57,7 @@ NTSTATUS smb2_signing_encrypt_pdu(DATA_BLOB encryption_key, + uint16_t cipher_id, + struct iovec *vector, + int count); +-NTSTATUS smb2_signing_decrypt_pdu(DATA_BLOB decryption_key, ++NTSTATUS smb2_signing_decrypt_pdu(struct smb2_signing_key *decryption_key, + uint16_t cipher_id, + struct iovec *vector, + int count); +diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c +index aa69c374d49..421fc434305 100644 +--- a/libcli/smb/smbXcli_base.c ++++ b/libcli/smb/smbXcli_base.c +@@ -3567,7 +3567,7 @@ static NTSTATUS smb2cli_inbuf_parse_compound(struct smbXcli_conn *conn, + tf_iov[1].iov_base = (void *)hdr; + tf_iov[1].iov_len = enc_len; + +- status = smb2_signing_decrypt_pdu(s->smb2->decryption_key->blob, ++ status = smb2_signing_decrypt_pdu(s->smb2->decryption_key, + conn->smb2.server.cipher, + tf_iov, 2); + if (!NT_STATUS_IS_OK(status)) { +diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c +index 56e7b70696b..9df22b5a6ac 100644 +--- a/source3/smbd/smb2_server.c ++++ b/source3/smbd/smb2_server.c +@@ -432,7 +432,7 @@ static NTSTATUS smbd_smb2_inbuf_parse_compound(struct smbXsrv_connection *xconn, + tf_iov[1].iov_base = (void *)hdr; + tf_iov[1].iov_len = enc_len; + +- status = smb2_signing_decrypt_pdu(s->global->decryption_key->blob, ++ status = smb2_signing_decrypt_pdu(s->global->decryption_key, + xconn->smb2.server.cipher, + tf_iov, 2); + if (!NT_STATUS_IS_OK(status)) { +-- +2.23.0 + diff --git a/SOURCES/0127-libcli-smb-Use-gnutls_error_to_ntstatus-in-smb2_sign.patch b/SOURCES/0127-libcli-smb-Use-gnutls_error_to_ntstatus-in-smb2_sign.patch new file mode 100644 index 0000000..659d4a2 --- /dev/null +++ b/SOURCES/0127-libcli-smb-Use-gnutls_error_to_ntstatus-in-smb2_sign.patch @@ -0,0 +1,41 @@ +From c75283e42d0758247fca67b6f59ac5a76ace2dd7 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Fri, 23 Aug 2019 09:27:35 +0200 +Subject: [PATCH 127/187] libcli:smb: Use gnutls_error_to_ntstatus() in + smb2_signing_decrypt_pdu() + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit b9c4990f57aa778942c310b802437e6df1d17e04) +--- + libcli/smb/smb2_signing.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/libcli/smb/smb2_signing.c b/libcli/smb/smb2_signing.c +index 9f40e8bbea5..15dbf3d8b2a 100644 +--- a/libcli/smb/smb2_signing.c ++++ b/libcli/smb/smb2_signing.c +@@ -652,7 +652,7 @@ NTSTATUS smb2_signing_decrypt_pdu(struct smb2_signing_key *decryption_key, + algo, + &key); + if (rc < 0) { +- status = NT_STATUS_NO_MEMORY; ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_INTERNAL_ERROR); + goto out; + } + } +@@ -710,10 +710,9 @@ NTSTATUS smb2_signing_decrypt_pdu(struct smb2_signing_key *decryption_key, + ptext, + &ptext_size); + if (rc < 0 || ptext_size != m_total) { +- DBG_ERR("ERROR: %s\n", gnutls_strerror(rc)); + TALLOC_FREE(ptext); + TALLOC_FREE(ctext); +- status = NT_STATUS_INTERNAL_ERROR; ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_INTERNAL_ERROR); + goto out; + } + +-- +2.23.0 + diff --git a/SOURCES/0128-libcli-smb-Use-smb2_signing_key-in-smb2_signing_encr.patch b/SOURCES/0128-libcli-smb-Use-smb2_signing_key-in-smb2_signing_encr.patch new file mode 100644 index 0000000..2958ffa --- /dev/null +++ b/SOURCES/0128-libcli-smb-Use-smb2_signing_key-in-smb2_signing_encr.patch @@ -0,0 +1,223 @@ +From 89fa1828d7b01416da929c234ec8612f113d6d60 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Thu, 14 Mar 2019 10:27:06 +0100 +Subject: [PATCH 128/187] libcli:smb: Use smb2_signing_key in + smb2_signing_encrypt_pdu() + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett + +Adaped to remove Samba AES support + +Signed-off-by: Andrew Bartlett +(cherry picked from commit eb65fe5505e32f451d4cf5d0203abce77c05dae4) +--- + libcli/smb/smb2_signing.c | 34 +++++++++++++++------------------- + libcli/smb/smb2_signing.h | 2 +- + libcli/smb/smbXcli_base.c | 4 ++-- + source3/smbd/smb2_server.c | 16 ++++++++++++---- + 4 files changed, 30 insertions(+), 26 deletions(-) + +diff --git a/libcli/smb/smb2_signing.c b/libcli/smb/smb2_signing.c +index 15dbf3d8b2a..682327bb21b 100644 +--- a/libcli/smb/smb2_signing.c ++++ b/libcli/smb/smb2_signing.c +@@ -386,7 +386,7 @@ NTSTATUS smb2_key_derivation(const uint8_t *KI, size_t KI_len, + return NT_STATUS_OK; + } + +-NTSTATUS smb2_signing_encrypt_pdu(DATA_BLOB encryption_key, ++NTSTATUS smb2_signing_encrypt_pdu(struct smb2_signing_key *encryption_key, + uint16_t cipher_id, + struct iovec *vector, + int count) +@@ -400,7 +400,6 @@ NTSTATUS smb2_signing_encrypt_pdu(DATA_BLOB encryption_key, + uint32_t tag_size = 0; + uint8_t _key[16] = {0}; + gnutls_cipher_algorithm_t algo = 0; +- gnutls_aead_cipher_hd_t cipher_hnd = NULL; + gnutls_datum_t key; + gnutls_datum_t iv; + NTSTATUS status; +@@ -416,9 +415,9 @@ NTSTATUS smb2_signing_encrypt_pdu(DATA_BLOB encryption_key, + + tf = (uint8_t *)vector[0].iov_base; + +- if (encryption_key.length == 0) { +- DEBUG(2,("Wrong encryption key length %u for SMB2 signing\n", +- (unsigned)encryption_key.length)); ++ if (!smb2_signing_key_valid(encryption_key)) { ++ DBG_WARNING("Wrong encryption key length %zu for SMB2 signing\n", ++ encryption_key->blob.length); + return NT_STATUS_ACCESS_DENIED; + } + +@@ -458,20 +457,22 @@ NTSTATUS smb2_signing_encrypt_pdu(DATA_BLOB encryption_key, + }; + + memcpy(key.data, +- encryption_key.data, +- MIN(encryption_key.length, key.size)); ++ encryption_key->blob.data, ++ MIN(encryption_key->blob.length, key.size)); + + iv = (gnutls_datum_t) { + .data = tf + SMB2_TF_NONCE, + .size = iv_size, + }; + +- rc = gnutls_aead_cipher_init(&cipher_hnd, +- algo, +- &key); +- if (rc < 0) { +- status = NT_STATUS_NO_MEMORY; +- goto out; ++ if (encryption_key->cipher_hnd == NULL) { ++ rc = gnutls_aead_cipher_init(&encryption_key->cipher_hnd, ++ algo, ++ &key); ++ if (rc < 0) { ++ status = NT_STATUS_NO_MEMORY; ++ goto out; ++ } + } + + memset(tf + SMB2_TF_NONCE + iv_size, +@@ -487,14 +488,12 @@ NTSTATUS smb2_signing_encrypt_pdu(DATA_BLOB encryption_key, + + ptext = talloc_size(talloc_tos(), ptext_size); + if (ptext == NULL) { +- gnutls_aead_cipher_deinit(cipher_hnd); + status = NT_STATUS_NO_MEMORY; + goto out; + } + + ctext = talloc_size(talloc_tos(), ctext_size); + if (ctext == NULL) { +- gnutls_aead_cipher_deinit(cipher_hnd); + status = NT_STATUS_NO_MEMORY; + goto out; + } +@@ -508,13 +507,12 @@ NTSTATUS smb2_signing_encrypt_pdu(DATA_BLOB encryption_key, + if (len > ptext_size) { + TALLOC_FREE(ptext); + TALLOC_FREE(ctext); +- gnutls_aead_cipher_deinit(cipher_hnd); + status = NT_STATUS_INTERNAL_ERROR; + goto out; + } + } + +- rc = gnutls_aead_cipher_encrypt(cipher_hnd, ++ rc = gnutls_aead_cipher_encrypt(encryption_key->cipher_hnd, + iv.data, + iv.size, + tf + SMB2_TF_NONCE, +@@ -528,7 +526,6 @@ NTSTATUS smb2_signing_encrypt_pdu(DATA_BLOB encryption_key, + DBG_ERR("ERROR: %s\n", gnutls_strerror(rc)); + TALLOC_FREE(ptext); + TALLOC_FREE(ctext); +- gnutls_aead_cipher_deinit(cipher_hnd); + status = NT_STATUS_INTERNAL_ERROR; + goto out; + } +@@ -547,7 +544,6 @@ NTSTATUS smb2_signing_encrypt_pdu(DATA_BLOB encryption_key, + TALLOC_FREE(ptext); + TALLOC_FREE(ctext); + } +- gnutls_aead_cipher_deinit(cipher_hnd); + + DBG_INFO("Enencrypted SMB2 message\n"); + +diff --git a/libcli/smb/smb2_signing.h b/libcli/smb/smb2_signing.h +index 7eefad93b3e..e28b5c8de9a 100644 +--- a/libcli/smb/smb2_signing.h ++++ b/libcli/smb/smb2_signing.h +@@ -53,7 +53,7 @@ NTSTATUS smb2_key_derivation(const uint8_t *KI, size_t KI_len, + const uint8_t *Context, size_t Context_len, + uint8_t KO[16]); + +-NTSTATUS smb2_signing_encrypt_pdu(DATA_BLOB encryption_key, ++NTSTATUS smb2_signing_encrypt_pdu(struct smb2_signing_key *encryption_key, + uint16_t cipher_id, + struct iovec *vector, + int count); +diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c +index 421fc434305..d9837d48083 100644 +--- a/libcli/smb/smbXcli_base.c ++++ b/libcli/smb/smbXcli_base.c +@@ -3090,7 +3090,7 @@ NTSTATUS smb2cli_req_compound_submit(struct tevent_req **reqs, + struct iovec *iov; + int i, num_iov, nbt_len; + int tf_iov = -1; +- const struct smb2_signing_key *encryption_key = NULL; ++ struct smb2_signing_key *encryption_key = NULL; + uint64_t encryption_session_id = 0; + uint64_t nonce_high = UINT64_MAX; + uint64_t nonce_low = UINT64_MAX; +@@ -3379,7 +3379,7 @@ skip_credits: + buf += v->iov_len; + } + +- status = smb2_signing_encrypt_pdu(encryption_key->blob, ++ status = smb2_signing_encrypt_pdu(encryption_key, + state->conn->smb2.server.cipher, + &iov[tf_iov], num_iov - tf_iov); + if (!NT_STATUS_IS_OK(status)) { +diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c +index 9df22b5a6ac..0776fa2bdd2 100644 +--- a/source3/smbd/smb2_server.c ++++ b/source3/smbd/smb2_server.c +@@ -1336,10 +1336,14 @@ static NTSTATUS smb2_send_async_interim_response(const struct smbd_smb2_request + * we need to sign/encrypt here with the last/first key we remembered + */ + if (firsttf->iov_len == SMB2_TF_HDR_SIZE) { +- status = smb2_signing_encrypt_pdu(req->first_key, ++ struct smb2_signing_key key = { ++ .blob = req->first_key, ++ }; ++ status = smb2_signing_encrypt_pdu(&key, + xconn->smb2.server.cipher, + firsttf, + nreq->out.vector_count - first_idx); ++ smb2_signing_key_destructor(&key); + if (!NT_STATUS_IS_OK(status)) { + return status; + } +@@ -1739,7 +1743,7 @@ static void smbd_smb2_request_pending_timer(struct tevent_context *ev, + struct smbXsrv_session *x = req->session; + struct smb2_signing_key *encryption_key = x->global->encryption_key; + +- status = smb2_signing_encrypt_pdu(encryption_key->blob, ++ status = smb2_signing_encrypt_pdu(encryption_key, + xconn->smb2.server.cipher, + &state->vector[1+SMBD_SMB2_TF_IOV_OFS], + SMBD_SMB2_NUM_IOV_PER_REQ); +@@ -2994,10 +2998,14 @@ static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req) + * now check if we need to sign the current response + */ + if (firsttf->iov_len == SMB2_TF_HDR_SIZE) { +- status = smb2_signing_encrypt_pdu(req->first_key, ++ struct smb2_signing_key key = { ++ .blob = req->first_key, ++ }; ++ status = smb2_signing_encrypt_pdu(&key, + xconn->smb2.server.cipher, + firsttf, + req->out.vector_count - first_idx); ++ smb2_signing_key_destructor(&key); + if (!NT_STATUS_IS_OK(status)) { + return status; + } +@@ -3419,7 +3427,7 @@ static NTSTATUS smbd_smb2_send_break(struct smbXsrv_connection *xconn, + struct smb2_signing_key *encryption_key = + session->global->encryption_key; + +- status = smb2_signing_encrypt_pdu(encryption_key->blob, ++ status = smb2_signing_encrypt_pdu(encryption_key, + xconn->smb2.server.cipher, + &state->vector[1+SMBD_SMB2_TF_IOV_OFS], + SMBD_SMB2_NUM_IOV_PER_REQ); +-- +2.23.0 + diff --git a/SOURCES/0129-libcli-smb-Use-gnutls_error_to_ntstatus-in-smb2_sign.patch b/SOURCES/0129-libcli-smb-Use-gnutls_error_to_ntstatus-in-smb2_sign.patch new file mode 100644 index 0000000..4866084 --- /dev/null +++ b/SOURCES/0129-libcli-smb-Use-gnutls_error_to_ntstatus-in-smb2_sign.patch @@ -0,0 +1,42 @@ +From b72fbb819de245fe77b4d5bdb2465fc65488cc62 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Fri, 23 Aug 2019 09:28:28 +0200 +Subject: [PATCH 129/187] libcli:smb: Use gnutls_error_to_ntstatus() in + smb2_signing_encrypt_pdu() + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +Signed-off-by: Andrew Bartlett +(cherry picked from commit f24f26aaa58b9223e2c0cfd3e5086278b27903f1) +--- + libcli/smb/smb2_signing.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/libcli/smb/smb2_signing.c b/libcli/smb/smb2_signing.c +index 682327bb21b..c39f8e4780a 100644 +--- a/libcli/smb/smb2_signing.c ++++ b/libcli/smb/smb2_signing.c +@@ -470,7 +470,7 @@ NTSTATUS smb2_signing_encrypt_pdu(struct smb2_signing_key *encryption_key, + algo, + &key); + if (rc < 0) { +- status = NT_STATUS_NO_MEMORY; ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_INTERNAL_ERROR); + goto out; + } + } +@@ -523,10 +523,9 @@ NTSTATUS smb2_signing_encrypt_pdu(struct smb2_signing_key *encryption_key, + ctext, + &ctext_size); + if (rc < 0 || ctext_size != m_total + tag_size) { +- DBG_ERR("ERROR: %s\n", gnutls_strerror(rc)); + TALLOC_FREE(ptext); + TALLOC_FREE(ctext); +- status = NT_STATUS_INTERNAL_ERROR; ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_INTERNAL_ERROR); + goto out; + } + +-- +2.23.0 + diff --git a/SOURCES/0130-libcli-smb-Prefer-AES-GCM-over-AES-CCM-with-GnuTLS.patch b/SOURCES/0130-libcli-smb-Prefer-AES-GCM-over-AES-CCM-with-GnuTLS.patch new file mode 100644 index 0000000..8c70c02 --- /dev/null +++ b/SOURCES/0130-libcli-smb-Prefer-AES-GCM-over-AES-CCM-with-GnuTLS.patch @@ -0,0 +1,41 @@ +From 146a33a845cd38089f0aed6953387123f59bc652 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Fri, 15 Mar 2019 16:25:28 +0100 +Subject: [PATCH 130/187] libcli:smb: Prefer AES-GCM over AES-CCM with GnuTLS + +The AES-GCM implementation in GnuTLS is faster. + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett + +Adapted to remove Samba AES support + +Signed-off-by: Andrew Bartlett +(cherry picked from commit 454ed53221b1374ad8148e922b64c3788ad4998e) +--- + libcli/smb/smbXcli_base.c | 9 +++------ + 1 file changed, 3 insertions(+), 6 deletions(-) + +diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c +index d9837d48083..f0ba7803a53 100644 +--- a/libcli/smb/smbXcli_base.c ++++ b/libcli/smb/smbXcli_base.c +@@ -4788,12 +4788,9 @@ static struct tevent_req *smbXcli_negprot_smb2_subreq(struct smbXcli_negprot_sta + } + + SSVAL(p, 0, 2); /* ChiperCount */ +- /* +- * For now we preferr CCM because our implementation +- * is faster than GCM, see bug #11451. +- */ +- SSVAL(p, 2, SMB2_ENCRYPTION_AES128_CCM); +- SSVAL(p, 4, SMB2_ENCRYPTION_AES128_GCM); ++ ++ SSVAL(p, 2, SMB2_ENCRYPTION_AES128_GCM); ++ SSVAL(p, 4, SMB2_ENCRYPTION_AES128_CCM); + + status = smb2_negotiate_context_add( + state, &c, SMB2_ENCRYPTION_CAPABILITIES, p, 6); +-- +2.23.0 + diff --git a/SOURCES/0131-s3-smbd-Prefer-AES-GCM-over-AES-CCM-with-GnuTLS.patch b/SOURCES/0131-s3-smbd-Prefer-AES-GCM-over-AES-CCM-with-GnuTLS.patch new file mode 100644 index 0000000..1c46101 --- /dev/null +++ b/SOURCES/0131-s3-smbd-Prefer-AES-GCM-over-AES-CCM-with-GnuTLS.patch @@ -0,0 +1,41 @@ +From 728fe099d044b2890eb98a84c0deb9702bdd9971 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Fri, 15 Mar 2019 16:28:12 +0100 +Subject: [PATCH 131/187] s3:smbd: Prefer AES-GCM over AES-CCM with GnuTLS + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett + +Adapted to remove Samba AES support + +Signed-off-by: Andrew Bartlett +(cherry picked from commit 2ee1764ca88c882cddcc0a17f7d83950ec709b5d) +--- + source3/smbd/smb2_negprot.c | 10 +++------- + 1 file changed, 3 insertions(+), 7 deletions(-) + +diff --git a/source3/smbd/smb2_negprot.c b/source3/smbd/smb2_negprot.c +index 528d3f8cc74..6e7201b1cd8 100644 +--- a/source3/smbd/smb2_negprot.c ++++ b/source3/smbd/smb2_negprot.c +@@ -492,14 +492,10 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req) + } + } + +- /* +- * For now we preferr CCM because our implementation +- * is faster than GCM, see bug #11451. +- */ +- if (aes_128_ccm_supported) { +- xconn->smb2.server.cipher = SMB2_ENCRYPTION_AES128_CCM; +- } else if (aes_128_gcm_supported) { ++ if (aes_128_gcm_supported) { + xconn->smb2.server.cipher = SMB2_ENCRYPTION_AES128_GCM; ++ } else if (aes_128_ccm_supported) { ++ xconn->smb2.server.cipher = SMB2_ENCRYPTION_AES128_CCM; + } + + SSVAL(buf, 0, 1); /* ChiperCount */ +-- +2.23.0 + diff --git a/SOURCES/0132-auth-gensec-fix-non-AES-schannel-seal.patch b/SOURCES/0132-auth-gensec-fix-non-AES-schannel-seal.patch new file mode 100644 index 0000000..4e6d6e9 --- /dev/null +++ b/SOURCES/0132-auth-gensec-fix-non-AES-schannel-seal.patch @@ -0,0 +1,49 @@ +From 7d0f882b196ce9045488dee68ec979b4fb96d6d5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?G=C3=BCnther=20Deschner?= +Date: Fri, 20 Sep 2019 18:32:43 +0200 +Subject: [PATCH 132/187] auth/gensec: fix non-AES schannel seal + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14134 + +Guenther + +Signed-off-by: Guenther Deschner +Reviewed-by: Andreas Schneider +(cherry picked from commit 709d54d68a9c2cb3cda91d9ab63228a7adbaceb4) +--- + auth/gensec/schannel.c | 9 +++++++++ + selftest/knownfail | 1 + + 2 files changed, 10 insertions(+) + +diff --git a/auth/gensec/schannel.c b/auth/gensec/schannel.c +index b5e6289ef3f..9f2611e5f04 100644 +--- a/auth/gensec/schannel.c ++++ b/auth/gensec/schannel.c +@@ -428,6 +428,15 @@ static NTSTATUS netsec_do_seal(struct schannel_state *state, + ZERO_ARRAY(_sealing_key); + return gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); + } ++ gnutls_cipher_deinit(cipher_hnd); ++ rc = gnutls_cipher_init(&cipher_hnd, ++ GNUTLS_CIPHER_ARCFOUR_128, ++ &sealing_key, ++ NULL); ++ if (rc < 0) { ++ ZERO_ARRAY(_sealing_key); ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); ++ } + rc = gnutls_cipher_encrypt(cipher_hnd, + data, + length); +diff --git a/selftest/knownfail b/selftest/knownfail +index 7b54b77a708..95db97a44e0 100644 +--- a/selftest/knownfail ++++ b/selftest/knownfail +@@ -374,3 +374,4 @@ + ^samba.tests.ntlmdisabled.python\(ktest\).python2.ntlmdisabled.NtlmDisabledTests.test_samr_change_password\(ktest\) + ^samba.tests.ntlmdisabled.python\(ad_dc_no_ntlm\).python3.ntlmdisabled.NtlmDisabledTests.test_ntlm_connection\(ad_dc_no_ntlm\) + ^samba.tests.ntlmdisabled.python\(ad_dc_no_ntlm\).python2.ntlmdisabled.NtlmDisabledTests.test_ntlm_connection\(ad_dc_no_ntlm\) ++^samba.unittests.schannel.torture_schannel_seal_aes +-- +2.23.0 + diff --git a/SOURCES/0133-auth-gensec-fix-AES-schannel-seal-and-unseal.patch b/SOURCES/0133-auth-gensec-fix-AES-schannel-seal-and-unseal.patch new file mode 100644 index 0000000..b09c9d8 --- /dev/null +++ b/SOURCES/0133-auth-gensec-fix-AES-schannel-seal-and-unseal.patch @@ -0,0 +1,106 @@ +From 279d31dfa642126ce7670292390e02b2e33ea36e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?G=C3=BCnther=20Deschner?= +Date: Tue, 17 Sep 2019 22:37:06 +0200 +Subject: [PATCH 133/187] auth/gensec: fix AES schannel seal and unseal + +Workaround bug present in gnutls 3.6.8: + +gnutls_cipher_decrypt() uses an optimization +internally that breaks decryption when processing +buffers with their length not being a multiple +of the blocksize. + +Signed-off-by: Stefan Metzmacher +Pair-Programmed-With: Guenther Deschner +Reviewed-by: Andreas Schneider +(cherry picked from commit f988756599c2f7253989f2ca1dea2975dd89e6ea) +--- + auth/gensec/schannel.c | 47 +++++++++++++++++++++++++++--------------- + selftest/knownfail | 1 - + 2 files changed, 30 insertions(+), 18 deletions(-) + +diff --git a/auth/gensec/schannel.c b/auth/gensec/schannel.c +index 9f2611e5f04..ea2a8b201ce 100644 +--- a/auth/gensec/schannel.c ++++ b/auth/gensec/schannel.c +@@ -306,11 +306,6 @@ static NTSTATUS netsec_do_seal(struct schannel_state *state, + return gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); + } + +- /* +- * Looks like we have to reuse the initial IV which is +- * cryptographically wrong! +- */ +- gnutls_cipher_set_iv(cipher_hnd, iv.data, iv.size); + rc = gnutls_cipher_encrypt(cipher_hnd, + data, + length); +@@ -319,26 +314,44 @@ static NTSTATUS netsec_do_seal(struct schannel_state *state, + return gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); + } + } else { +- rc = gnutls_cipher_decrypt(cipher_hnd, +- confounder, +- 8); +- if (rc < 0) { +- gnutls_cipher_deinit(cipher_hnd); +- return gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); +- } + + /* +- * Looks like we have to reuse the initial IV which is +- * cryptographically wrong! ++ * Workaround bug present in gnutls 3.6.8: ++ * ++ * gnutls_cipher_decrypt() uses an optimization ++ * internally that breaks decryption when processing ++ * buffers with their length not being a multiple ++ * of the blocksize. + */ +- gnutls_cipher_set_iv(cipher_hnd, iv.data, iv.size); ++ ++ uint8_t tmp[16] = { 0, }; ++ uint32_t tmp_dlength = MIN(length, sizeof(tmp) - 8); ++ ++ memcpy(tmp, confounder, 8); ++ memcpy(tmp + 8, data, tmp_dlength); ++ + rc = gnutls_cipher_decrypt(cipher_hnd, +- data, +- length); ++ tmp, ++ 8 + tmp_dlength); + if (rc < 0) { ++ ZERO_STRUCT(tmp); + gnutls_cipher_deinit(cipher_hnd); + return gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); + } ++ ++ memcpy(confounder, tmp, 8); ++ memcpy(data, tmp + 8, tmp_dlength); ++ ZERO_STRUCT(tmp); ++ ++ if (length > tmp_dlength) { ++ rc = gnutls_cipher_decrypt(cipher_hnd, ++ data + tmp_dlength, ++ length - tmp_dlength); ++ if (rc < 0) { ++ gnutls_cipher_deinit(cipher_hnd); ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); ++ } ++ } + } + gnutls_cipher_deinit(cipher_hnd); + #else /* NOT HAVE_GNUTLS_AES_CFB8 */ +diff --git a/selftest/knownfail b/selftest/knownfail +index 95db97a44e0..7b54b77a708 100644 +--- a/selftest/knownfail ++++ b/selftest/knownfail +@@ -374,4 +374,3 @@ + ^samba.tests.ntlmdisabled.python\(ktest\).python2.ntlmdisabled.NtlmDisabledTests.test_samr_change_password\(ktest\) + ^samba.tests.ntlmdisabled.python\(ad_dc_no_ntlm\).python3.ntlmdisabled.NtlmDisabledTests.test_ntlm_connection\(ad_dc_no_ntlm\) + ^samba.tests.ntlmdisabled.python\(ad_dc_no_ntlm\).python2.ntlmdisabled.NtlmDisabledTests.test_ntlm_connection\(ad_dc_no_ntlm\) +-^samba.unittests.schannel.torture_schannel_seal_aes +-- +2.23.0 + diff --git a/SOURCES/0134-libcli-auth-add-gnutls-test-for-aes-128-cfb8-cipher-.patch b/SOURCES/0134-libcli-auth-add-gnutls-test-for-aes-128-cfb8-cipher-.patch new file mode 100644 index 0000000..5d4c5e2 --- /dev/null +++ b/SOURCES/0134-libcli-auth-add-gnutls-test-for-aes-128-cfb8-cipher-.patch @@ -0,0 +1,286 @@ +From 3160995484a1e56bb878a28d3f3b0fb4e1eb2869 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?G=C3=BCnther=20Deschner?= +Date: Sat, 28 Sep 2019 13:10:32 +0200 +Subject: [PATCH 134/187] libcli/auth: add gnutls test for aes-128-cfb8 cipher + bug + +Guenther + +Signed-off-by: Guenther Deschner +Reviewed-by: Andreas Schneider + +Autobuild-User(master): Andreas Schneider +Autobuild-Date(master): Mon Oct 7 09:31:35 UTC 2019 on sn-devel-184 + +(cherry picked from commit 7c2745d41e808b7240358f5d0702dfe7abdc93a1) +--- + libcli/auth/tests/test_gnutls.c | 239 ++++++++++++++++++++++++++++++++ + libcli/auth/wscript_build | 9 ++ + 2 files changed, 248 insertions(+) + create mode 100644 libcli/auth/tests/test_gnutls.c + +diff --git a/libcli/auth/tests/test_gnutls.c b/libcli/auth/tests/test_gnutls.c +new file mode 100644 +index 00000000000..f4ef4ec19c8 +--- /dev/null ++++ b/libcli/auth/tests/test_gnutls.c +@@ -0,0 +1,239 @@ ++/* ++ * Unix SMB/CIFS implementation. ++ * ++ * Copyright (C) 2019 Guenther Deschner ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "includes.h" ++ ++#include "lib/crypto/gnutls_helpers.h" ++#include ++#include ++ ++#ifdef HAVE_GNUTLS_AES_CFB8 ++static void torture_gnutls_aes_128_cfb_flags(void **state, ++ const DATA_BLOB session_key, ++ const DATA_BLOB seq_num_initial, ++ const DATA_BLOB confounder_initial, ++ const DATA_BLOB confounder_expected, ++ const DATA_BLOB clear_initial, ++ const DATA_BLOB crypt_expected) ++{ ++ uint8_t confounder[8]; ++ DATA_BLOB io; ++ gnutls_cipher_hd_t cipher_hnd = NULL; ++ uint8_t sess_kf0[16] = {0}; ++ gnutls_datum_t key = { ++ .data = sess_kf0, ++ .size = sizeof(sess_kf0), ++ }; ++ uint32_t iv_size = ++ gnutls_cipher_get_iv_size(GNUTLS_CIPHER_AES_128_CFB8); ++ uint8_t _iv[iv_size]; ++ gnutls_datum_t iv = { ++ .data = _iv, ++ .size = iv_size, ++ }; ++ uint32_t i; ++ int rc; ++ ++ assert_int_equal(session_key.length, 16); ++ assert_int_equal(seq_num_initial.length, 8); ++ assert_int_equal(confounder_initial.length, 8); ++ assert_int_equal(confounder_expected.length, 8); ++ assert_int_equal(clear_initial.length, crypt_expected.length); ++ ++ DEBUG(0,("checking buffer size: %d\n", (int)clear_initial.length)); ++ ++ io = data_blob_dup_talloc(NULL, clear_initial); ++ assert_non_null(io.data); ++ assert_int_equal(io.length, clear_initial.length); ++ ++ memcpy(confounder, confounder_initial.data, 8); ++ ++ DEBUG(0,("confounder before crypt:\n")); ++ dump_data(0, confounder, 8); ++ dump_data(0, seq_num_initial.data, 8); ++ dump_data(0, io.data, io.length); ++ ++ for (i = 0; i < key.size; i++) { ++ key.data[i] = session_key.data[i] ^ 0xf0; ++ } ++ ++ ZERO_ARRAY(_iv); ++ ++ memcpy(iv.data + 0, seq_num_initial.data, 8); ++ memcpy(iv.data + 8, seq_num_initial.data, 8); ++ ++ rc = gnutls_cipher_init(&cipher_hnd, ++ GNUTLS_CIPHER_AES_128_CFB8, ++ &key, ++ &iv); ++ assert_int_equal(rc, 0); ++ ++ rc = gnutls_cipher_encrypt(cipher_hnd, ++ confounder, ++ 8); ++ assert_int_equal(rc, 0); ++ ++ rc = gnutls_cipher_encrypt(cipher_hnd, ++ io.data, ++ io.length); ++ assert_int_equal(rc, 0); ++ ++ dump_data(0, io.data, io.length); ++ DEBUG(0,("confounder after crypt:\n")); ++ dump_data(0, confounder, 8); ++ dump_data(0, seq_num_initial.data, 8); ++ assert_memory_equal(io.data, crypt_expected.data, crypt_expected.length); ++ assert_memory_equal(confounder, confounder_expected.data, confounder_expected.length); ++ ++ rc = gnutls_cipher_decrypt(cipher_hnd, ++ confounder, ++ 8); ++ assert_int_equal(rc, 0); ++ ++ rc = gnutls_cipher_decrypt(cipher_hnd, ++ io.data, ++ io.length); ++ assert_int_equal(rc, 0); ++ gnutls_cipher_deinit(cipher_hnd); ++ ++ dump_data(0, io.data, io.length); ++ DEBUG(0,("confounder after decrypt:\n")); ++ dump_data(0, confounder, 8); ++ dump_data(0, seq_num_initial.data, 8); ++ assert_memory_equal(io.data, clear_initial.data, clear_initial.length); ++ assert_memory_equal(confounder, confounder_initial.data, confounder_initial.length); ++} ++#endif ++ ++static void torture_gnutls_aes_128_cfb(void **state) ++{ ++#ifdef HAVE_GNUTLS_AES_CFB8 ++ const uint8_t _session_key[16] = { ++ 0x8E, 0xE8, 0x27, 0x85, 0x83, 0x41, 0x3C, 0x8D, ++ 0xC9, 0x54, 0x70, 0x75, 0x8E, 0xC9, 0x69, 0x91 ++ }; ++ const DATA_BLOB session_key = data_blob_const(_session_key, 16); ++ const uint8_t _seq_num_initial[8] = { ++ 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00 ++ }; ++ const DATA_BLOB seq_num_initial = ++ data_blob_const(_seq_num_initial, 8); ++ const uint8_t _confounder_initial[8] = { ++ 0x6E, 0x09, 0x25, 0x94, 0x01, 0xA0, 0x09, 0x31 ++ }; ++ const DATA_BLOB confounder_initial = ++ data_blob_const(_confounder_initial, 8); ++ const uint8_t _confounder_expected[8] = { ++ 0xCA, 0xFB, 0xAC, 0xFB, 0xA8, 0x26, 0x75, 0x2A ++ }; ++ const DATA_BLOB confounder_expected = ++ data_blob_const(_confounder_expected, 8); ++ const uint8_t _clear_initial[] = { ++ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, ++ 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, ++ 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x8A, 0xE3, 0x13, 0x71, 0x02, 0xF4, 0x36, 0x71, ++ 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, ++ 0x02, 0x40, 0x28, 0x00, 0x78, 0x57, 0x34, 0x12, ++ 0x34, 0x12, 0xCD, 0xAB, 0xEF, 0x00, 0x01, 0x23, ++ 0x45, 0x67, 0x89, 0xAB, 0x00, 0x00, 0x00, 0x00, ++ 0x04, 0x5D, 0x88, 0x8A, 0xEB, 0x1C, 0xC9, 0x11, ++ 0x9F, 0xE8, 0x08, 0x00, 0x2B, 0x10, 0x48, 0x60, ++ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ++ }; ++ const DATA_BLOB clear_initial = data_blob_const(_clear_initial, ++ sizeof(_clear_initial)); ++ const uint8_t crypt_buffer[] = { ++ 0xE2, 0xE5, 0xE3, 0x26, 0x45, 0xFB, 0xFC, 0xF3, ++ 0x9C, 0x14, 0xDD, 0xE1, 0x39, 0x23, 0xE0, 0x55, ++ 0xED, 0x8F, 0xF4, 0x92, 0xA1, 0xBD, 0xDC, 0x40, ++ 0x58, 0x6F, 0xD2, 0x5B, 0xF9, 0xC9, 0xA3, 0x87, ++ 0x46, 0x4B, 0x7F, 0xB2, 0x03, 0xD2, 0x35, 0x22, ++ 0x3E, 0x70, 0x9F, 0x1E, 0x3F, 0x1F, 0xDB, 0x7D, ++ 0x79, 0x88, 0x5A, 0x3D, 0xD3, 0x40, 0x1E, 0x69, ++ 0xD7, 0xE2, 0x1D, 0x5A, 0xE9, 0x3B, 0xE1, 0xE2, ++ 0x98, 0xFD, 0xCB, 0x3A, 0xF7, 0xB5, 0x1C, 0xF8, ++ 0xCA, 0x02, 0x00, 0x99, 0x9F, 0x0C, 0x01, 0xE6, ++ 0xD2, 0x00, 0xAF, 0xE0, 0x51, 0x88, 0x62, 0x50, ++ 0xB7, 0xE8, 0x6D, 0x63, 0x4B, 0x97, 0x05, 0xC1, ++ 0xD4, 0x83, 0x96, 0x29, 0x80, 0xAE, 0xD8, 0xA2, ++ 0xED, 0xC9, 0x5D, 0x0D, 0x29, 0xFF, 0x2C, 0x23, ++ 0x02, 0xFA, 0x3B, 0xEE, 0xE8, 0xBA, 0x06, 0x01, ++ 0x95, 0xDF, 0x80, 0x76, 0x0B, 0x17, 0x0E, 0xD8 ++ }; ++ const DATA_BLOB crypt_expected = data_blob_const(crypt_buffer, ++ sizeof(crypt_buffer)); ++ int buffer_sizes[] = { ++ 0, 1, 3, 7, 8, 9, 15, 16, 17 ++ }; ++ int i; ++ ++ torture_gnutls_aes_128_cfb_flags(state, ++ session_key, ++ seq_num_initial, ++ confounder_initial, ++ confounder_expected, ++ clear_initial, ++ crypt_expected); ++ ++ /* repeat the test for varying buffer sizes */ ++ ++ for (i = 0; i < ARRAY_SIZE(buffer_sizes); i++) { ++ DATA_BLOB clear_initial_trunc = ++ data_blob_const(clear_initial.data, buffer_sizes[i]); ++ DATA_BLOB crypt_expected_trunc = ++ data_blob_const(crypt_expected.data, buffer_sizes[i]); ++ torture_gnutls_aes_128_cfb_flags(state, ++ session_key, ++ seq_num_initial, ++ confounder_initial, ++ confounder_expected, ++ clear_initial_trunc, ++ crypt_expected_trunc); ++ } ++#endif ++} ++ ++int main(int argc, char *argv[]) ++{ ++ int rc; ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test(torture_gnutls_aes_128_cfb), ++ }; ++ ++ if (argc == 2) { ++ cmocka_set_test_filter(argv[1]); ++ } ++ cmocka_set_message_output(CM_OUTPUT_SUBUNIT); ++ ++ rc = cmocka_run_group_tests(tests, NULL, NULL); ++ ++ return rc; ++} +diff --git a/libcli/auth/wscript_build b/libcli/auth/wscript_build +index eabf3814ba1..7b765cd9e43 100644 +--- a/libcli/auth/wscript_build ++++ b/libcli/auth/wscript_build +@@ -71,3 +71,12 @@ bld.SAMBA_BINARY('test_rc4_passwd_buffer', + cmocka + ''', + install=False) ++ ++bld.SAMBA_BINARY('test_gnutls', ++ source='tests/test_gnutls.c', ++ deps=''' ++ gnutls ++ cmocka ++ samba-util ++ ''', ++ install=False) +-- +2.23.0 + diff --git a/SOURCES/0135-waf-Check-for-gnutls_aead_cipher_encryptv2.patch b/SOURCES/0135-waf-Check-for-gnutls_aead_cipher_encryptv2.patch new file mode 100644 index 0000000..b82c980 --- /dev/null +++ b/SOURCES/0135-waf-Check-for-gnutls_aead_cipher_encryptv2.patch @@ -0,0 +1,29 @@ +From e4823cc53490b21661eac22a0cf9799af6d1fd91 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Fri, 23 Aug 2019 08:40:00 +0200 +Subject: [PATCH 135/187] waf: Check for gnutls_aead_cipher_encryptv2() + +Signed-off-by: Andreas Schneider +Reviewed-by: Simo Sorce +(cherry picked from commit fa255a36df87e41717d9630ea96ac9439e186062) +--- + wscript_configure_system_gnutls | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/wscript_configure_system_gnutls b/wscript_configure_system_gnutls +index f71fd4fb97f..f6d9ac3c65e 100644 +--- a/wscript_configure_system_gnutls ++++ b/wscript_configure_system_gnutls +@@ -15,6 +15,9 @@ conf.SET_TARGET_TYPE('gnutls', 'SYSLIB') + # Check for gnutls_pkcs7_get_embedded_data_oid (>= 3.5.5) required by libmscat + conf.CHECK_FUNCS_IN('gnutls_pkcs7_get_embedded_data_oid', 'gnutls') + ++# Check for gnutls_aead_cipher_encryptv2 (>= 3.6.10) ++conf.CHECK_FUNCS_IN('gnutls_aead_cipher_encryptv2', 'gnutls') ++ + if conf.CHECK_VALUEOF('GNUTLS_CIPHER_AES_128_CFB8', headers='gnutls/gnutls.h'): + conf.DEFINE('HAVE_GNUTLS_AES_CFB8', 1) + else: +-- +2.23.0 + diff --git a/SOURCES/0136-libcli-smb-Use-gnutls_aead_cipher_encryptv2-for-AES-.patch b/SOURCES/0136-libcli-smb-Use-gnutls_aead_cipher_encryptv2-for-AES-.patch new file mode 100644 index 0000000..088e589 --- /dev/null +++ b/SOURCES/0136-libcli-smb-Use-gnutls_aead_cipher_encryptv2-for-AES-.patch @@ -0,0 +1,86 @@ +From d841537e0e835cda608d3f2b654d10d36d539bc5 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Fri, 23 Aug 2019 08:54:54 +0200 +Subject: [PATCH 136/187] libcli:smb: Use gnutls_aead_cipher_encryptv2() for + AES GCM or CCM + +This is a new call which has been added with GnuTLS 3.6.10 and will +recuduce memory allocations and copying of data. + +Signed-off-by: Andreas Schneider +Reviewed-by: Simo Sorce +(cherry picked from commit 70fdd4821aa811f90944bee17cc85e3ae9302279) +--- + libcli/smb/smb2_signing.c | 32 ++++++++++++++++++++++++++++++-- + 1 file changed, 30 insertions(+), 2 deletions(-) + +diff --git a/libcli/smb/smb2_signing.c b/libcli/smb/smb2_signing.c +index c39f8e4780a..ac0f6f4d29f 100644 +--- a/libcli/smb/smb2_signing.c ++++ b/libcli/smb/smb2_signing.c +@@ -392,12 +392,11 @@ NTSTATUS smb2_signing_encrypt_pdu(struct smb2_signing_key *encryption_key, + int count) + { + uint8_t *tf; +- int i; + size_t a_total; + ssize_t m_total; + uint32_t iv_size = 0; + uint32_t key_size = 0; +- uint32_t tag_size = 0; ++ size_t tag_size = 0; + uint8_t _key[16] = {0}; + gnutls_cipher_algorithm_t algo = 0; + gnutls_datum_t key; +@@ -479,12 +478,40 @@ NTSTATUS smb2_signing_encrypt_pdu(struct smb2_signing_key *encryption_key, + 0, + 16 - iv_size); + ++#ifdef HAVE_GNUTLS_AEAD_CIPHER_ENCRYPTV2 ++ { ++ uint8_t tag[tag_size]; ++ giovec_t auth_iov[1]; ++ ++ auth_iov[0] = (giovec_t) { ++ .iov_base = tf + SMB2_TF_NONCE, ++ .iov_len = a_total, ++ }; ++ ++ rc = gnutls_aead_cipher_encryptv2(encryption_key->cipher_hnd, ++ iv.data, ++ iv.size, ++ auth_iov, ++ 1, ++ &vector[1], ++ count - 1, ++ tag, ++ &tag_size); ++ if (rc < 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_INTERNAL_ERROR); ++ goto out; ++ } ++ ++ memcpy(tf + SMB2_TF_SIGNATURE, tag, tag_size); ++ } ++#else /* HAVE_GNUTLS_AEAD_CIPHER_ENCRYPTV2 */ + { + size_t ptext_size = m_total; + uint8_t *ptext = NULL; + size_t ctext_size = m_total + tag_size; + uint8_t *ctext = NULL; + size_t len = 0; ++ int i; + + ptext = talloc_size(talloc_tos(), ptext_size); + if (ptext == NULL) { +@@ -543,6 +570,7 @@ NTSTATUS smb2_signing_encrypt_pdu(struct smb2_signing_key *encryption_key, + TALLOC_FREE(ptext); + TALLOC_FREE(ctext); + } ++#endif /* HAVE_GNUTLS_AEAD_CIPHER_ENCRYPTV2 */ + + DBG_INFO("Enencrypted SMB2 message\n"); + +-- +2.23.0 + diff --git a/SOURCES/0137-libcli-smb-Use-gnutls_aead_cipher_decryptv2-for-AES-.patch b/SOURCES/0137-libcli-smb-Use-gnutls_aead_cipher_decryptv2-for-AES-.patch new file mode 100644 index 0000000..cac5963 --- /dev/null +++ b/SOURCES/0137-libcli-smb-Use-gnutls_aead_cipher_decryptv2-for-AES-.patch @@ -0,0 +1,88 @@ +From 8b5c3ae97f0e30e8df78e81c53b4ba02365a299d Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Fri, 23 Aug 2019 09:12:21 +0200 +Subject: [PATCH 137/187] libcli:smb: Use gnutls_aead_cipher_decryptv2() for + AES GCM or CCM + +This is a new call which has been added with GnuTLS 3.6.10 and will +recuduce memory allocations and copying of data. + +Signed-off-by: Andreas Schneider +Reviewed-by: Simo Sorce + +Autobuild-User(master): Andreas Schneider +Autobuild-Date(master): Tue Oct 8 14:12:44 UTC 2019 on sn-devel-184 + +(cherry picked from commit 4a24d9499757dea377b4e3d8beb7f2c10fd5c5d0) +--- + libcli/smb/smb2_signing.c | 29 +++++++++++++++++++++++++++-- + 1 file changed, 27 insertions(+), 2 deletions(-) + +diff --git a/libcli/smb/smb2_signing.c b/libcli/smb/smb2_signing.c +index ac0f6f4d29f..166ab9d83ff 100644 +--- a/libcli/smb/smb2_signing.c ++++ b/libcli/smb/smb2_signing.c +@@ -588,13 +588,12 @@ NTSTATUS smb2_signing_decrypt_pdu(struct smb2_signing_key *decryption_key, + { + uint8_t *tf; + uint16_t flags; +- int i; + size_t a_total; + ssize_t m_total; + uint32_t msg_size = 0; + uint32_t iv_size = 0; + uint32_t key_size = 0; +- uint32_t tag_size = 0; ++ size_t tag_size = 0; + uint8_t _key[16] = {0}; + gnutls_cipher_algorithm_t algo = 0; + gnutls_datum_t key; +@@ -680,12 +679,37 @@ NTSTATUS smb2_signing_decrypt_pdu(struct smb2_signing_key *decryption_key, + } + } + ++#ifdef HAVE_GNUTLS_AEAD_CIPHER_ENCRYPTV2 ++ { ++ giovec_t auth_iov[1]; ++ ++ auth_iov[0] = (giovec_t) { ++ .iov_base = tf + SMB2_TF_NONCE, ++ .iov_len = a_total, ++ }; ++ ++ rc = gnutls_aead_cipher_decryptv2(decryption_key->cipher_hnd, ++ iv.data, ++ iv.size, ++ auth_iov, ++ 1, ++ &vector[1], ++ count - 1, ++ tf + SMB2_TF_SIGNATURE, ++ tag_size); ++ if (rc < 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_INTERNAL_ERROR); ++ goto out; ++ } ++ } ++#else /* HAVE_GNUTLS_AEAD_CIPHER_ENCRYPTV2 */ + { + size_t ctext_size = m_total + tag_size; + uint8_t *ctext = NULL; + size_t ptext_size = m_total; + uint8_t *ptext = NULL; + size_t len = 0; ++ int i; + + /* GnuTLS doesn't have a iovec API for decryption yet */ + +@@ -751,6 +775,7 @@ NTSTATUS smb2_signing_decrypt_pdu(struct smb2_signing_key *decryption_key, + TALLOC_FREE(ptext); + TALLOC_FREE(ctext); + } ++#endif /* HAVE_GNUTLS_AEAD_CIPHER_ENCRYPTV2 */ + + DBG_INFO("Decrypted SMB2 message\n"); + +-- +2.23.0 + diff --git a/SOURCES/0138-libcli-smb-Do-not-use-gnutls_aead_cipher_encryptv2-w.patch b/SOURCES/0138-libcli-smb-Do-not-use-gnutls_aead_cipher_encryptv2-w.patch new file mode 100644 index 0000000..9b90d9b --- /dev/null +++ b/SOURCES/0138-libcli-smb-Do-not-use-gnutls_aead_cipher_encryptv2-w.patch @@ -0,0 +1,47 @@ +From d2c3c0ccc6ec7f38b995545d31431d013bd7e047 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Mon, 4 Nov 2019 08:40:34 +0100 +Subject: [PATCH 138/187] libcli:smb: Do not use gnutls_aead_cipher_encryptv2() + with GnuTLS 3.6.10 + +The gnutls_aead_cipher_encryptv2() implementation was released with a +bug. This wont be fixed before 3.6.11. + +See https://gitlab.com/gnutls/gnutls/merge_requests/1085 + +Signed-off-by: Andreas Schneider +Reviewed-by: Alexander Bokovoy +(cherry picked from commit 176d0f0364bc1deb3c8df2f3bb928e01f89f216b) +--- + libcli/smb/smb2_signing.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/libcli/smb/smb2_signing.c b/libcli/smb/smb2_signing.c +index 166ab9d83ff..7561a7a858d 100644 +--- a/libcli/smb/smb2_signing.c ++++ b/libcli/smb/smb2_signing.c +@@ -478,7 +478,9 @@ NTSTATUS smb2_signing_encrypt_pdu(struct smb2_signing_key *encryption_key, + 0, + 16 - iv_size); + +-#ifdef HAVE_GNUTLS_AEAD_CIPHER_ENCRYPTV2 ++/* gnutls_aead_cipher_encryptv2() has a bug in version 3.6.10 */ ++#if defined(HAVE_GNUTLS_AEAD_CIPHER_ENCRYPTV2) && \ ++ GNUTLS_VERSION_NUMBER > 0x03060a + { + uint8_t tag[tag_size]; + giovec_t auth_iov[1]; +@@ -679,7 +681,9 @@ NTSTATUS smb2_signing_decrypt_pdu(struct smb2_signing_key *decryption_key, + } + } + +-#ifdef HAVE_GNUTLS_AEAD_CIPHER_ENCRYPTV2 ++/* gnutls_aead_cipher_encryptv2() has a bug in version 3.6.10 */ ++#if defined(HAVE_GNUTLS_AEAD_CIPHER_ENCRYPTV2) && \ ++ GNUTLS_VERSION_NUMBER > 0x03060a + { + giovec_t auth_iov[1]; + +-- +2.23.0 + diff --git a/SOURCES/0139-libcli-auth-Return-NTSTATUS-for-SMBOWFencrypt_ntv2.patch b/SOURCES/0139-libcli-auth-Return-NTSTATUS-for-SMBOWFencrypt_ntv2.patch new file mode 100644 index 0000000..3bd6149 --- /dev/null +++ b/SOURCES/0139-libcli-auth-Return-NTSTATUS-for-SMBOWFencrypt_ntv2.patch @@ -0,0 +1,76 @@ +From 3900f0a63c3aedee8b5a53e4eda4c41a6b0f0f3e Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 13 Nov 2019 12:40:02 +0100 +Subject: [PATCH 139/187] libcli:auth: Return NTSTATUS for SMBOWFencrypt_ntv2() + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14195 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 045b9eb3f088c66e20bd19e144a2ce3597328d93) +--- + libcli/auth/proto.h | 5 +++-- + libcli/auth/smbencrypt.c | 24 ++++++++++++++++-------- + 2 files changed, 19 insertions(+), 10 deletions(-) + +diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h +index 714652bdb76..4c20783124b 100644 +--- a/libcli/auth/proto.h ++++ b/libcli/auth/proto.h +@@ -139,8 +139,9 @@ void SMBOWFencrypt_ntv2(const uint8_t kr[16], + const DATA_BLOB *srv_chal, + const DATA_BLOB *smbcli_chal, + uint8_t resp_buf[16]); +-void SMBsesskeygen_ntv2(const uint8_t kr[16], +- const uint8_t * nt_resp, uint8_t sess_key[16]); ++NTSTATUS SMBsesskeygen_ntv2(const uint8_t kr[16], ++ const uint8_t *nt_resp, ++ uint8_t sess_key[16]); + void SMBsesskeygen_ntv1(const uint8_t kr[16], uint8_t sess_key[16]); + void SMBsesskeygen_lm_sess_key(const uint8_t lm_hash[16], + const uint8_t lm_resp[24], /* only uses 8 */ +diff --git a/libcli/auth/smbencrypt.c b/libcli/auth/smbencrypt.c +index cc5e1fbb899..904d2c38219 100644 +--- a/libcli/auth/smbencrypt.c ++++ b/libcli/auth/smbencrypt.c +@@ -370,21 +370,29 @@ void SMBOWFencrypt_ntv2(const uint8_t kr[16], + #endif + } + +-void SMBsesskeygen_ntv2(const uint8_t kr[16], +- const uint8_t * nt_resp, uint8_t sess_key[16]) ++NTSTATUS SMBsesskeygen_ntv2(const uint8_t kr[16], ++ const uint8_t *nt_resp, ++ uint8_t sess_key[16]) + { ++ int rc; ++ + /* a very nice, 128 bit, variable session key */ +- gnutls_hmac_fast(GNUTLS_MAC_MD5, +- kr, +- 16, +- nt_resp, +- 16, +- sess_key); ++ rc = gnutls_hmac_fast(GNUTLS_MAC_MD5, ++ kr, ++ 16, ++ nt_resp, ++ 16, ++ sess_key); ++ if (rc != 0) { ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED); ++ } + + #ifdef DEBUG_PASSWORD + DEBUG(100, ("SMBsesskeygen_ntv2:\n")); + dump_data(100, sess_key, 16); + #endif ++ ++ return NT_STATUS_OK; + } + + void SMBsesskeygen_ntv1(const uint8_t kr[16], uint8_t sess_key[16]) +-- +2.23.0 + diff --git a/SOURCES/0140-libcli-auth-Check-return-codes-of-SMBsesskeygen_ntv2.patch b/SOURCES/0140-libcli-auth-Check-return-codes-of-SMBsesskeygen_ntv2.patch new file mode 100644 index 0000000..0727178 --- /dev/null +++ b/SOURCES/0140-libcli-auth-Check-return-codes-of-SMBsesskeygen_ntv2.patch @@ -0,0 +1,102 @@ +From 042dc64f099a2aa2dd44ba9a00c29e05eed0848b Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 13 Nov 2019 12:45:04 +0100 +Subject: [PATCH 140/187] libcli:auth: Check return codes of + SMBsesskeygen_ntv2() + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14195 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 0914824684b3a69a9926402d447e1d5781f2ec02) +--- + libcli/auth/ntlm_check.c | 17 +++++++++++++++-- + libcli/auth/smbencrypt.c | 15 +++++++++++++-- + 2 files changed, 28 insertions(+), 4 deletions(-) + +diff --git a/libcli/auth/ntlm_check.c b/libcli/auth/ntlm_check.c +index 3844abde528..ba0051d7aea 100644 +--- a/libcli/auth/ntlm_check.c ++++ b/libcli/auth/ntlm_check.c +@@ -142,8 +142,15 @@ static bool smb_pwd_check_ntlmv2(TALLOC_CTX *mem_ctx, + data_blob_clear_free(&client_key_data); + if (memcmp(value_from_encryption, ntv2_response->data, 16) == 0) { + if (user_sess_key != NULL) { ++ NTSTATUS status; + *user_sess_key = data_blob_talloc(mem_ctx, NULL, 16); +- SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key->data); ++ ++ status = SMBsesskeygen_ntv2(kr, ++ value_from_encryption, ++ user_sess_key->data); ++ if (!NT_STATUS_IS_OK(status)) { ++ return false; ++ } + } + return true; + } +@@ -166,6 +173,7 @@ static bool smb_sess_key_ntlmv2(TALLOC_CTX *mem_ctx, + uint8_t kr[16]; + uint8_t value_from_encryption[16]; + DATA_BLOB client_key_data; ++ NTSTATUS status; + + if (part_passwd == NULL) { + DEBUG(10,("No password set - DISALLOWING access\n")); +@@ -196,7 +204,12 @@ static bool smb_sess_key_ntlmv2(TALLOC_CTX *mem_ctx, + + SMBOWFencrypt_ntv2(kr, sec_blob, &client_key_data, value_from_encryption); + *user_sess_key = data_blob_talloc(mem_ctx, NULL, 16); +- SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key->data); ++ status = SMBsesskeygen_ntv2(kr, ++ value_from_encryption, ++ user_sess_key->data); ++ if (!NT_STATUS_IS_OK(status)) { ++ return false; ++ } + return true; + } + +diff --git a/libcli/auth/smbencrypt.c b/libcli/auth/smbencrypt.c +index 904d2c38219..1412274dd21 100644 +--- a/libcli/auth/smbencrypt.c ++++ b/libcli/auth/smbencrypt.c +@@ -551,6 +551,7 @@ bool SMBNTLMv2encrypt_hash(TALLOC_CTX *mem_ctx, + DATA_BLOB *lm_session_key, DATA_BLOB *user_session_key) + { + uint8_t ntlm_v2_hash[16]; ++ NTSTATUS status; + + /* We don't use the NT# directly. Instead we use it mashed up with + the username and domain. +@@ -580,7 +581,12 @@ bool SMBNTLMv2encrypt_hash(TALLOC_CTX *mem_ctx, + + /* The NTLMv2 calculations also provide a session key, for signing etc later */ + /* use only the first 16 bytes of nt_response for session key */ +- SMBsesskeygen_ntv2(ntlm_v2_hash, nt_response->data, user_session_key->data); ++ status = SMBsesskeygen_ntv2(ntlm_v2_hash, ++ nt_response->data, ++ user_session_key->data); ++ if (!NT_STATUS_IS_OK(status)) { ++ return false; ++ } + } + } + +@@ -599,7 +605,12 @@ bool SMBNTLMv2encrypt_hash(TALLOC_CTX *mem_ctx, + + /* The NTLMv2 calculations also provide a session key, for signing etc later */ + /* use only the first 16 bytes of lm_response for session key */ +- SMBsesskeygen_ntv2(ntlm_v2_hash, lm_response->data, lm_session_key->data); ++ status = SMBsesskeygen_ntv2(ntlm_v2_hash, ++ lm_response->data, ++ lm_session_key->data); ++ if (!NT_STATUS_IS_OK(status)) { ++ return false; ++ } + } + } + +-- +2.23.0 + diff --git a/SOURCES/0141-libcli-auth-Return-NTSTATUS-for-SMBOWFencrypt_ntv2.patch b/SOURCES/0141-libcli-auth-Return-NTSTATUS-for-SMBOWFencrypt_ntv2.patch new file mode 100644 index 0000000..ad7fedd --- /dev/null +++ b/SOURCES/0141-libcli-auth-Return-NTSTATUS-for-SMBOWFencrypt_ntv2.patch @@ -0,0 +1,97 @@ +From ca20c23eb8c468d96f7e302ab32362d61adb4d8f Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 13 Nov 2019 12:48:18 +0100 +Subject: [PATCH 141/187] libcli:auth: Return NTSTATUS for SMBOWFencrypt_ntv2() + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14195 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit dc75a5f27eb32caf2f2adc289bc82fb0f8042cb3) +--- + libcli/auth/proto.h | 8 ++++---- + libcli/auth/smbencrypt.c | 25 +++++++++++++++---------- + 2 files changed, 19 insertions(+), 14 deletions(-) + +diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h +index 4c20783124b..52a33d8d457 100644 +--- a/libcli/auth/proto.h ++++ b/libcli/auth/proto.h +@@ -135,10 +135,10 @@ bool ntv2_owf_gen(const uint8_t owf[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); +-void SMBOWFencrypt_ntv2(const uint8_t kr[16], +- const DATA_BLOB *srv_chal, +- const DATA_BLOB *smbcli_chal, +- uint8_t resp_buf[16]); ++NTSTATUS SMBOWFencrypt_ntv2(const uint8_t kr[16], ++ const DATA_BLOB *srv_chal, ++ const DATA_BLOB *smbcli_chal, ++ uint8_t resp_buf[16]); + NTSTATUS SMBsesskeygen_ntv2(const uint8_t kr[16], + const uint8_t *nt_resp, + uint8_t sess_key[16]); +diff --git a/libcli/auth/smbencrypt.c b/libcli/auth/smbencrypt.c +index 1412274dd21..e7ed0630cdc 100644 +--- a/libcli/auth/smbencrypt.c ++++ b/libcli/auth/smbencrypt.c +@@ -334,12 +334,13 @@ void SMBNTencrypt(const char *passwd, const uint8_t *c8, uint8_t *p24) + + + /* Does the md5 encryption from the Key Response for NTLMv2. */ +-void SMBOWFencrypt_ntv2(const uint8_t kr[16], +- const DATA_BLOB *srv_chal, +- const DATA_BLOB *smbcli_chal, +- uint8_t resp_buf[16]) ++NTSTATUS SMBOWFencrypt_ntv2(const uint8_t kr[16], ++ const DATA_BLOB *srv_chal, ++ const DATA_BLOB *smbcli_chal, ++ uint8_t resp_buf[16]) + { + gnutls_hmac_hd_t hmac_hnd = NULL; ++ NTSTATUS status; + int rc; + + rc = gnutls_hmac_init(&hmac_hnd, +@@ -347,27 +348,31 @@ void SMBOWFencrypt_ntv2(const uint8_t kr[16], + kr, + 16); + if (rc < 0) { +- return; ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_HMAC_NOT_SUPPORTED); + } + + rc = gnutls_hmac(hmac_hnd, srv_chal->data, srv_chal->length); + if (rc < 0) { +- return; ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_HMAC_NOT_SUPPORTED); ++ goto out; + } + rc = gnutls_hmac(hmac_hnd, smbcli_chal->data, smbcli_chal->length); + if (rc < 0) { +- gnutls_hmac_deinit(hmac_hnd, NULL); +- return; ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_HMAC_NOT_SUPPORTED); ++ goto out; + } + +- gnutls_hmac_deinit(hmac_hnd, resp_buf); +- + #ifdef DEBUG_PASSWORD + DEBUG(100, ("SMBOWFencrypt_ntv2: srv_chal, smbcli_chal, resp_buf\n")); + dump_data(100, srv_chal->data, srv_chal->length); + dump_data(100, smbcli_chal->data, smbcli_chal->length); + dump_data(100, resp_buf, 16); + #endif ++ ++ status = NT_STATUS_OK; ++out: ++ gnutls_hmac_deinit(hmac_hnd, resp_buf); ++ return status; + } + + NTSTATUS SMBsesskeygen_ntv2(const uint8_t kr[16], +-- +2.23.0 + diff --git a/SOURCES/0142-libcli-auth-Check-return-code-of-SMBOWFencrypt_ntv2.patch b/SOURCES/0142-libcli-auth-Check-return-code-of-SMBOWFencrypt_ntv2.patch new file mode 100644 index 0000000..f6bf2c9 --- /dev/null +++ b/SOURCES/0142-libcli-auth-Check-return-code-of-SMBOWFencrypt_ntv2.patch @@ -0,0 +1,120 @@ +From 7dbe3c67368a1b5d81564b61650f1e85beb4e1c8 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 13 Nov 2019 12:52:44 +0100 +Subject: [PATCH 142/187] libcli:auth: Check return code of + SMBOWFencrypt_ntv2() + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14195 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 3db2ca2dcf367a6c57071a76668d19f3cbf62565) +--- + libcli/auth/ntlm_check.c | 18 +++++++++++++++--- + libcli/auth/smbencrypt.c | 20 ++++++++++++++++++-- + 2 files changed, 33 insertions(+), 5 deletions(-) + +diff --git a/libcli/auth/ntlm_check.c b/libcli/auth/ntlm_check.c +index ba0051d7aea..5058add3811 100644 +--- a/libcli/auth/ntlm_check.c ++++ b/libcli/auth/ntlm_check.c +@@ -93,6 +93,7 @@ static bool smb_pwd_check_ntlmv2(TALLOC_CTX *mem_ctx, + uint8_t kr[16]; + uint8_t value_from_encryption[16]; + DATA_BLOB client_key_data; ++ NTSTATUS status; + + if (part_passwd == NULL) { + DEBUG(10,("No password set - DISALLOWING access\n")); +@@ -125,7 +126,13 @@ static bool smb_pwd_check_ntlmv2(TALLOC_CTX *mem_ctx, + return false; + } + +- SMBOWFencrypt_ntv2(kr, sec_blob, &client_key_data, value_from_encryption); ++ status = SMBOWFencrypt_ntv2(kr, ++ sec_blob, ++ &client_key_data, ++ value_from_encryption); ++ if (!NT_STATUS_IS_OK(status)) { ++ return false; ++ } + + #if DEBUG_PASSWORD + DEBUG(100,("Part password (P16) was |\n")); +@@ -142,7 +149,6 @@ static bool smb_pwd_check_ntlmv2(TALLOC_CTX *mem_ctx, + data_blob_clear_free(&client_key_data); + if (memcmp(value_from_encryption, ntv2_response->data, 16) == 0) { + if (user_sess_key != NULL) { +- NTSTATUS status; + *user_sess_key = data_blob_talloc(mem_ctx, NULL, 16); + + status = SMBsesskeygen_ntv2(kr, +@@ -202,7 +208,13 @@ static bool smb_sess_key_ntlmv2(TALLOC_CTX *mem_ctx, + return false; + } + +- SMBOWFencrypt_ntv2(kr, sec_blob, &client_key_data, value_from_encryption); ++ status = SMBOWFencrypt_ntv2(kr, ++ sec_blob, ++ &client_key_data, ++ value_from_encryption); ++ if (!NT_STATUS_IS_OK(status)) { ++ return false; ++ } + *user_sess_key = data_blob_talloc(mem_ctx, NULL, 16); + status = SMBsesskeygen_ntv2(kr, + value_from_encryption, +diff --git a/libcli/auth/smbencrypt.c b/libcli/auth/smbencrypt.c +index e7ed0630cdc..e33d29de19d 100644 +--- a/libcli/auth/smbencrypt.c ++++ b/libcli/auth/smbencrypt.c +@@ -493,6 +493,7 @@ static DATA_BLOB NTLMv2_generate_response(TALLOC_CTX *out_mem_ctx, + uint8_t ntlmv2_response[16]; + DATA_BLOB ntlmv2_client_data; + DATA_BLOB final_response; ++ NTSTATUS status; + + TALLOC_CTX *mem_ctx = talloc_named(out_mem_ctx, 0, + "NTLMv2_generate_response internal context"); +@@ -507,7 +508,14 @@ static DATA_BLOB NTLMv2_generate_response(TALLOC_CTX *out_mem_ctx, + ntlmv2_client_data = NTLMv2_generate_client_data(mem_ctx, nttime, names_blob); + + /* Given that data, and the challenge from the server, generate a response */ +- SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &ntlmv2_client_data, ntlmv2_response); ++ status = SMBOWFencrypt_ntv2(ntlm_v2_hash, ++ server_chal, ++ &ntlmv2_client_data, ++ ntlmv2_response); ++ if (!NT_STATUS_IS_OK(status)) { ++ talloc_free(mem_ctx); ++ return data_blob(NULL, 0); ++ } + + final_response = data_blob_talloc(out_mem_ctx, NULL, sizeof(ntlmv2_response) + ntlmv2_client_data.length); + +@@ -528,13 +536,21 @@ static DATA_BLOB LMv2_generate_response(TALLOC_CTX *mem_ctx, + uint8_t lmv2_response[16]; + DATA_BLOB lmv2_client_data = data_blob_talloc(mem_ctx, NULL, 8); + DATA_BLOB final_response = data_blob_talloc(mem_ctx, NULL,24); ++ NTSTATUS status; + + /* LMv2 */ + /* client-supplied random data */ + generate_random_buffer(lmv2_client_data.data, lmv2_client_data.length); + + /* Given that data, and the challenge from the server, generate a response */ +- SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &lmv2_client_data, lmv2_response); ++ status = SMBOWFencrypt_ntv2(ntlm_v2_hash, ++ server_chal, ++ &lmv2_client_data, ++ lmv2_response); ++ if (!NT_STATUS_IS_OK(status)) { ++ data_blob_free(&lmv2_client_data); ++ return data_blob(NULL, 0); ++ } + memcpy(final_response.data, lmv2_response, sizeof(lmv2_response)); + + /* after the first 16 bytes is the random data we generated above, +-- +2.23.0 + diff --git a/SOURCES/0143-s4-rpc_server-Remove-gnutls_global_-de-init.patch b/SOURCES/0143-s4-rpc_server-Remove-gnutls_global_-de-init.patch new file mode 100644 index 0000000..fedf22d --- /dev/null +++ b/SOURCES/0143-s4-rpc_server-Remove-gnutls_global_-de-init.patch @@ -0,0 +1,38 @@ +From 3c980ebcb7449db0082b68660fafcae6113d2645 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 13 Nov 2019 13:57:53 +0100 +Subject: [PATCH 143/187] s4:rpc_server: Remove gnutls_global_(de)init() + +This is done by the gnutls library constructor/destructor. + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit afb5cb669ceeb68bf93ef8db07abcc5d424580cd) +--- + source4/rpc_server/backupkey/dcesrv_backupkey.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/source4/rpc_server/backupkey/dcesrv_backupkey.c b/source4/rpc_server/backupkey/dcesrv_backupkey.c +index cea6a28e4e2..36f5e5823eb 100644 +--- a/source4/rpc_server/backupkey/dcesrv_backupkey.c ++++ b/source4/rpc_server/backupkey/dcesrv_backupkey.c +@@ -1802,8 +1802,6 @@ static WERROR dcesrv_bkrp_BackupKey(struct dcesrv_call_state *dce_call, + /* At which level we start to add more debug of what is done in the protocol */ + const int debuglevel = 4; + +- gnutls_global_init(); +- + if (DEBUGLVL(debuglevel)) { + const struct tsocket_address *remote_address; + remote_address = dcesrv_connection_get_remote_address(dce_call->conn); +@@ -1856,7 +1854,6 @@ static WERROR dcesrv_bkrp_BackupKey(struct dcesrv_call_state *dce_call, + } + /*else: I am a RODC so I don't handle backup key protocol */ + +- gnutls_global_deinit(); + talloc_unlink(mem_ctx, ldb_ctx); + return error; + } +-- +2.23.0 + diff --git a/SOURCES/0144-s4-lib-Remove-gnutls_global_-de-init-from-libtls.patch b/SOURCES/0144-s4-lib-Remove-gnutls_global_-de-init-from-libtls.patch new file mode 100644 index 0000000..df1562a --- /dev/null +++ b/SOURCES/0144-s4-lib-Remove-gnutls_global_-de-init-from-libtls.patch @@ -0,0 +1,69 @@ +From 85dab1964a66f2c520a88b368cacf655abdb89db Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 13 Nov 2019 13:59:30 +0100 +Subject: [PATCH 144/187] s4:lib: Remove gnutls_global_(de)init() from libtls + +This is handled by the gnutls library constructor/destructor. + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 0e159b725ecf2f9a6d026170253e2d1eb73ed0c2) +--- + source4/lib/tls/tls_tstream.c | 12 ------------ + source4/lib/tls/tlscert.c | 3 --- + 2 files changed, 15 deletions(-) + +diff --git a/source4/lib/tls/tls_tstream.c b/source4/lib/tls/tls_tstream.c +index b68996db894..55bca036776 100644 +--- a/source4/lib/tls/tls_tstream.c ++++ b/source4/lib/tls/tls_tstream.c +@@ -903,12 +903,6 @@ NTSTATUS tstream_tls_params_client(TALLOC_CTX *mem_ctx, + struct tstream_tls_params *tlsp; + int ret; + +- ret = gnutls_global_init(); +- if (ret != GNUTLS_E_SUCCESS) { +- DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret))); +- return NT_STATUS_NOT_SUPPORTED; +- } +- + tlsp = talloc_zero(mem_ctx, struct tstream_tls_params); + NT_STATUS_HAVE_NO_MEMORY(tlsp); + +@@ -1123,12 +1117,6 @@ NTSTATUS tstream_tls_params_server(TALLOC_CTX *mem_ctx, + return NT_STATUS_OK; + } + +- ret = gnutls_global_init(); +- if (ret != GNUTLS_E_SUCCESS) { +- DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret))); +- return NT_STATUS_NOT_SUPPORTED; +- } +- + tlsp = talloc_zero(mem_ctx, struct tstream_tls_params); + NT_STATUS_HAVE_NO_MEMORY(tlsp); + +diff --git a/source4/lib/tls/tlscert.c b/source4/lib/tls/tlscert.c +index e02ee13d7e9..f5e9a1f2d39 100644 +--- a/source4/lib/tls/tlscert.c ++++ b/source4/lib/tls/tlscert.c +@@ -62,8 +62,6 @@ void tls_cert_generate(TALLOC_CTX *mem_ctx, + } \ + } while (0) + +- TLSCHECK(gnutls_global_init()); +- + DEBUG(0,("Attempting to autogenerate TLS self-signed keys for https for hostname '%s'\n", + hostname)); + +@@ -150,7 +148,6 @@ void tls_cert_generate(TALLOC_CTX *mem_ctx, + gnutls_x509_privkey_deinit(cakey); + gnutls_x509_crt_deinit(cacrt); + gnutls_x509_crt_deinit(crt); +- gnutls_global_deinit(); + + DEBUG(0,("TLS self-signed keys generated OK\n")); + return; +-- +2.23.0 + diff --git a/SOURCES/0145-s4-torture-Remove-calls-to-gnutls_global_-de-init-in.patch b/SOURCES/0145-s4-torture-Remove-calls-to-gnutls_global_-de-init-in.patch new file mode 100644 index 0000000..0216ac8 --- /dev/null +++ b/SOURCES/0145-s4-torture-Remove-calls-to-gnutls_global_-de-init-in.patch @@ -0,0 +1,238 @@ +From 080c82dfa589f72f72f84e761adeb91e0b112072 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 13 Nov 2019 14:01:46 +0100 +Subject: [PATCH 145/187] s4:torture: Remove calls to gnutls_global_(de)init() + in backupkey test + +This is handled by the gnutls library constructor/destructor. + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit fbfb11b0f7ebd69cc4b1b545b398a367720d5473) +--- + source4/torture/rpc/backupkey.c | 48 --------------------------------- + 1 file changed, 48 deletions(-) + +diff --git a/source4/torture/rpc/backupkey.c b/source4/torture/rpc/backupkey.c +index b955f933430..284488f84ea 100644 +--- a/source4/torture/rpc/backupkey.c ++++ b/source4/torture/rpc/backupkey.c +@@ -834,8 +834,6 @@ static bool test_RestoreGUID_ko(struct torture_context *tctx, + enum dcerpc_AuthType auth_type; + enum dcerpc_AuthLevel auth_level; + +- gnutls_global_init(); +- + dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level); + + if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { +@@ -853,8 +851,6 @@ static bool test_RestoreGUID_ko(struct torture_context *tctx, + NT_STATUS_ACCESS_DENIED, "Get GUID"); + } + +- gnutls_global_deinit(); +- + return true; + } + +@@ -868,8 +864,6 @@ static bool test_RestoreGUID_wrongversion(struct torture_context *tctx, + enum dcerpc_AuthType auth_type; + enum dcerpc_AuthLevel auth_level; + +- gnutls_global_init(); +- + dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level); + + if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { +@@ -887,8 +881,6 @@ static bool test_RestoreGUID_wrongversion(struct torture_context *tctx, + NT_STATUS_ACCESS_DENIED, "Get GUID"); + } + +- gnutls_global_deinit(); +- + return true; + } + +@@ -902,8 +894,6 @@ static bool test_RestoreGUID_wronguser(struct torture_context *tctx, + enum dcerpc_AuthType auth_type; + enum dcerpc_AuthLevel auth_level; + +- gnutls_global_init(); +- + dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level); + + if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { +@@ -921,8 +911,6 @@ static bool test_RestoreGUID_wronguser(struct torture_context *tctx, + NT_STATUS_ACCESS_DENIED, "Get GUID"); + } + +- gnutls_global_deinit(); +- + return true; + } + +@@ -936,8 +924,6 @@ static bool test_RestoreGUID_v3(struct torture_context *tctx, + enum dcerpc_AuthType auth_type; + enum dcerpc_AuthLevel auth_level; + +- gnutls_global_init(); +- + dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level); + + if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { +@@ -956,8 +942,6 @@ static bool test_RestoreGUID_v3(struct torture_context *tctx, + NT_STATUS_ACCESS_DENIED, "Get GUID"); + } + +- gnutls_global_deinit(); +- + return true; + } + +@@ -970,8 +954,6 @@ static bool test_RestoreGUID(struct torture_context *tctx, + enum dcerpc_AuthType auth_type; + enum dcerpc_AuthLevel auth_level; + +- gnutls_global_init(); +- + dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level); + + if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { +@@ -993,8 +975,6 @@ static bool test_RestoreGUID(struct torture_context *tctx, + NT_STATUS_ACCESS_DENIED, "Get GUID"); + } + +- gnutls_global_deinit(); +- + return true; + } + +@@ -1008,8 +988,6 @@ static bool test_RestoreGUID_badmagiconsecret(struct torture_context *tctx, + enum dcerpc_AuthType auth_type; + enum dcerpc_AuthLevel auth_level; + +- gnutls_global_init(); +- + dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level); + + if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { +@@ -1027,8 +1005,6 @@ static bool test_RestoreGUID_badmagiconsecret(struct torture_context *tctx, + NT_STATUS_ACCESS_DENIED, "Get GUID"); + } + +- gnutls_global_deinit(); +- + return true; + } + +@@ -1040,8 +1016,6 @@ static bool test_RestoreGUID_emptyrequest(struct torture_context *tctx, + enum dcerpc_AuthType auth_type; + enum dcerpc_AuthLevel auth_level; + +- gnutls_global_init(); +- + dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level); + + if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { +@@ -1061,8 +1035,6 @@ static bool test_RestoreGUID_emptyrequest(struct torture_context *tctx, + NT_STATUS_ACCESS_DENIED, "Get GUID"); + } + +- gnutls_global_deinit(); +- + return true; + } + +@@ -1076,8 +1048,6 @@ static bool test_RestoreGUID_badcertguid(struct torture_context *tctx, + enum dcerpc_AuthType auth_type; + enum dcerpc_AuthLevel auth_level; + +- gnutls_global_init(); +- + dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level); + + if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { +@@ -1102,8 +1072,6 @@ static bool test_RestoreGUID_badcertguid(struct torture_context *tctx, + NT_STATUS_ACCESS_DENIED, "Get GUID"); + } + +- gnutls_global_deinit(); +- + return true; + } + +@@ -1117,8 +1085,6 @@ static bool test_RestoreGUID_badmagicaccesscheck(struct torture_context *tctx, + enum dcerpc_AuthType auth_type; + enum dcerpc_AuthLevel auth_level; + +- gnutls_global_init(); +- + dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level); + + if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { +@@ -1136,8 +1102,6 @@ static bool test_RestoreGUID_badmagicaccesscheck(struct torture_context *tctx, + NT_STATUS_ACCESS_DENIED, "Get GUID"); + } + +- gnutls_global_deinit(); +- + return true; + } + +@@ -1151,8 +1115,6 @@ static bool test_RestoreGUID_badhashaccesscheck(struct torture_context *tctx, + enum dcerpc_AuthType auth_type; + enum dcerpc_AuthLevel auth_level; + +- gnutls_global_init(); +- + dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level); + + if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { +@@ -1170,8 +1132,6 @@ static bool test_RestoreGUID_badhashaccesscheck(struct torture_context *tctx, + NT_STATUS_ACCESS_DENIED, "Get GUID"); + } + +- gnutls_global_init(); +- + return true; + } + +@@ -1187,8 +1147,6 @@ static bool test_RetrieveBackupKeyGUID_validate(struct torture_context *tctx, + enum dcerpc_AuthType auth_type; + enum dcerpc_AuthLevel auth_level; + +- gnutls_global_init(); +- + torture_assert(tctx, r != NULL, "test_RetrieveBackupKeyGUID_validate failed"); + + if (r == NULL) { +@@ -1376,8 +1334,6 @@ static bool test_RetrieveBackupKeyGUID_validate(struct torture_context *tctx, + "Get GUID"); + } + +- gnutls_global_deinit(); +- + return true; + } + +@@ -2091,8 +2047,6 @@ static bool test_ServerWrap_decrypt_wrong_stuff(struct torture_context *tctx, + enum dcerpc_AuthLevel auth_level; + ZERO_STRUCT(r); + +- gnutls_global_init(); +- + dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level); + + /* Encrypt */ +@@ -2268,8 +2222,6 @@ static bool test_ServerWrap_decrypt_wrong_stuff(struct torture_context *tctx, + "decrypt should fail with WERR_INVALID_PARAMETER"); + } + +- gnutls_global_deinit(); +- + return true; + } + +-- +2.23.0 + diff --git a/SOURCES/0146-libcli-auth-Check-return-value-of-netlogon_creds_ini.patch b/SOURCES/0146-libcli-auth-Check-return-value-of-netlogon_creds_ini.patch new file mode 100644 index 0000000..7f82a61 --- /dev/null +++ b/SOURCES/0146-libcli-auth-Check-return-value-of-netlogon_creds_ini.patch @@ -0,0 +1,57 @@ +From 8075ae29c9e3e0af99f035883f4ddc545d5e328b Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 13 Nov 2019 09:39:19 +0100 +Subject: [PATCH 146/187] libcli:auth: Check return value of + netlogon_creds_init_128bit() + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14195 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 2c21cd6d49d56611acb2f364473d8c2e73e74545) +--- + libcli/auth/credentials.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c +index baa436df71b..1c01930a9d9 100644 +--- a/libcli/auth/credentials.c ++++ b/libcli/auth/credentials.c +@@ -580,6 +580,8 @@ struct netlogon_creds_CredentialState *netlogon_creds_server_init(TALLOC_CTX *me + { + + struct netlogon_creds_CredentialState *creds = talloc_zero(mem_ctx, struct netlogon_creds_CredentialState); ++ NTSTATUS status; ++ + + if (!creds) { + return NULL; +@@ -604,8 +606,6 @@ struct netlogon_creds_CredentialState *netlogon_creds_server_init(TALLOC_CTX *me + } + + if (negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { +- NTSTATUS status; +- + status = netlogon_creds_init_hmac_sha256(creds, + client_challenge, + server_challenge, +@@ -615,8 +615,14 @@ struct netlogon_creds_CredentialState *netlogon_creds_server_init(TALLOC_CTX *me + return NULL; + } + } else if (negotiate_flags & NETLOGON_NEG_STRONG_KEYS) { +- netlogon_creds_init_128bit(creds, client_challenge, server_challenge, +- machine_password); ++ status = netlogon_creds_init_128bit(creds, ++ client_challenge, ++ server_challenge, ++ machine_password); ++ if (!NT_STATUS_IS_OK(status)) { ++ talloc_free(creds); ++ return NULL; ++ } + } else { + netlogon_creds_init_64bit(creds, client_challenge, server_challenge, + machine_password); +-- +2.23.0 + diff --git a/SOURCES/0147-libcli-auth-Check-return-status-of-netlogon_creds_in.patch b/SOURCES/0147-libcli-auth-Check-return-status-of-netlogon_creds_in.patch new file mode 100644 index 0000000..5f54c79 --- /dev/null +++ b/SOURCES/0147-libcli-auth-Check-return-status-of-netlogon_creds_in.patch @@ -0,0 +1,79 @@ +From 7ebffca28d3caa496e36467618f80725e8864efe Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 13 Nov 2019 09:41:18 +0100 +Subject: [PATCH 147/187] libcli:auth: Check return status of + netlogon_creds_init_64bit() + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14195 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit e4ae1ba451d408b3b5c74d303493cb7c38e6e1c8) +--- + libcli/auth/credentials.c | 29 ++++++++++++++++++++++------- + 1 file changed, 22 insertions(+), 7 deletions(-) + +diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c +index 1c01930a9d9..36d0368d198 100644 +--- a/libcli/auth/credentials.c ++++ b/libcli/auth/credentials.c +@@ -51,10 +51,10 @@ static void netlogon_creds_step_crypt(struct netlogon_creds_CredentialState *cre + + this call is made after the netr_ServerReqChallenge call + */ +-static void netlogon_creds_init_64bit(struct netlogon_creds_CredentialState *creds, +- const struct netr_Credential *client_challenge, +- const struct netr_Credential *server_challenge, +- const struct samr_Password *machine_password) ++static NTSTATUS netlogon_creds_init_64bit(struct netlogon_creds_CredentialState *creds, ++ const struct netr_Credential *client_challenge, ++ const struct netr_Credential *server_challenge, ++ const struct samr_Password *machine_password) + { + uint32_t sum[2]; + uint8_t sum2[8]; +@@ -68,6 +68,8 @@ static void netlogon_creds_init_64bit(struct netlogon_creds_CredentialState *cre + ZERO_ARRAY(creds->session_key); + + des_crypt128(creds->session_key, sum2, machine_password->hash); ++ ++ return NT_STATUS_OK; + } + + /* +@@ -458,7 +460,14 @@ struct netlogon_creds_CredentialState *netlogon_creds_client_init(TALLOC_CTX *me + return NULL; + } + } else { +- netlogon_creds_init_64bit(creds, client_challenge, server_challenge, machine_password); ++ status = netlogon_creds_init_64bit(creds, ++ client_challenge, ++ server_challenge, ++ machine_password); ++ if (!NT_STATUS_IS_OK(status)) { ++ talloc_free(creds); ++ return NULL; ++ } + } + + netlogon_creds_first_step(creds, client_challenge, server_challenge); +@@ -624,8 +633,14 @@ struct netlogon_creds_CredentialState *netlogon_creds_server_init(TALLOC_CTX *me + return NULL; + } + } else { +- netlogon_creds_init_64bit(creds, client_challenge, server_challenge, +- machine_password); ++ status = netlogon_creds_init_64bit(creds, ++ client_challenge, ++ server_challenge, ++ machine_password); ++ if (!NT_STATUS_IS_OK(status)) { ++ talloc_free(creds); ++ return NULL; ++ } + } + + netlogon_creds_first_step(creds, client_challenge, server_challenge); +-- +2.23.0 + diff --git a/SOURCES/0148-libcli-auth-Check-return-status-of-netlogon_creds_fi.patch b/SOURCES/0148-libcli-auth-Check-return-status-of-netlogon_creds_fi.patch new file mode 100644 index 0000000..b92a54d --- /dev/null +++ b/SOURCES/0148-libcli-auth-Check-return-status-of-netlogon_creds_fi.patch @@ -0,0 +1,73 @@ +From 86c2e733c461f0311eac38eb5cef1eb245aa584c Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 13 Nov 2019 09:44:32 +0100 +Subject: [PATCH 148/187] libcli:auth: Check return status of + netlogon_creds_first_step() + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14195 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 0ed92e3e60684bfb02b01479d985535d525a5be5) +--- + libcli/auth/credentials.c | 24 +++++++++++++++++++----- + 1 file changed, 19 insertions(+), 5 deletions(-) + +diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c +index 36d0368d198..359ba8c4b90 100644 +--- a/libcli/auth/credentials.c ++++ b/libcli/auth/credentials.c +@@ -174,15 +174,17 @@ static NTSTATUS netlogon_creds_init_hmac_sha256(struct netlogon_creds_Credential + return NT_STATUS_OK; + } + +-static void netlogon_creds_first_step(struct netlogon_creds_CredentialState *creds, +- const struct netr_Credential *client_challenge, +- const struct netr_Credential *server_challenge) ++static NTSTATUS netlogon_creds_first_step(struct netlogon_creds_CredentialState *creds, ++ const struct netr_Credential *client_challenge, ++ const struct netr_Credential *server_challenge) + { + netlogon_creds_step_crypt(creds, client_challenge, &creds->client); + + netlogon_creds_step_crypt(creds, server_challenge, &creds->server); + + creds->seed = creds->client; ++ ++ return NT_STATUS_OK; + } + + /* +@@ -470,7 +472,13 @@ struct netlogon_creds_CredentialState *netlogon_creds_client_init(TALLOC_CTX *me + } + } + +- netlogon_creds_first_step(creds, client_challenge, server_challenge); ++ status = netlogon_creds_first_step(creds, ++ client_challenge, ++ server_challenge); ++ if (!NT_STATUS_IS_OK(status)) { ++ talloc_free(creds); ++ return NULL; ++ } + + dump_data_pw("Session key", creds->session_key, 16); + dump_data_pw("Credential ", creds->client.data, 8); +@@ -643,7 +651,13 @@ struct netlogon_creds_CredentialState *netlogon_creds_server_init(TALLOC_CTX *me + } + } + +- netlogon_creds_first_step(creds, client_challenge, server_challenge); ++ status = netlogon_creds_first_step(creds, ++ client_challenge, ++ server_challenge); ++ if (!NT_STATUS_IS_OK(status)) { ++ talloc_free(creds); ++ return NULL; ++ } + + dump_data_pw("Session key", creds->session_key, 16); + dump_data_pw("Client Credential ", creds->client.data, 8); +-- +2.23.0 + diff --git a/SOURCES/0149-libcli-auth-Return-NTSTATUS-for-netlogon_creds_clien.patch b/SOURCES/0149-libcli-auth-Return-NTSTATUS-for-netlogon_creds_clien.patch new file mode 100644 index 0000000..0a352c6 --- /dev/null +++ b/SOURCES/0149-libcli-auth-Return-NTSTATUS-for-netlogon_creds_clien.patch @@ -0,0 +1,60 @@ +From d5b5b280fefca55a96456b9348b20b78a36fc227 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 13 Nov 2019 09:52:53 +0100 +Subject: [PATCH 149/187] libcli:auth: Return NTSTATUS for + netlogon_creds_client_authenticator() + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14195 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 7c7dc855ba982a37cb5040752ca473aab3446d6c) +--- + libcli/auth/credentials.c | 7 +++++-- + libcli/auth/proto.h | 5 +++-- + 2 files changed, 8 insertions(+), 4 deletions(-) + +diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c +index 359ba8c4b90..e5bf2c4703c 100644 +--- a/libcli/auth/credentials.c ++++ b/libcli/auth/credentials.c +@@ -513,8 +513,9 @@ struct netlogon_creds_CredentialState *netlogon_creds_client_init_session_key(TA + produce the next authenticator in the sequence ready to send to + the server + */ +-void netlogon_creds_client_authenticator(struct netlogon_creds_CredentialState *creds, +- struct netr_Authenticator *next) ++NTSTATUS ++netlogon_creds_client_authenticator(struct netlogon_creds_CredentialState *creds, ++ struct netr_Authenticator *next) + { + uint32_t t32n = (uint32_t)time(NULL); + +@@ -543,6 +544,8 @@ void netlogon_creds_client_authenticator(struct netlogon_creds_CredentialState * + + next->cred = creds->client; + next->timestamp = creds->sequence; ++ ++ return NT_STATUS_OK; + } + + /* +diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h +index 52a33d8d457..eef1c8dc095 100644 +--- a/libcli/auth/proto.h ++++ b/libcli/auth/proto.h +@@ -40,8 +40,9 @@ struct netlogon_creds_CredentialState *netlogon_creds_client_init(TALLOC_CTX *me + uint32_t negotiate_flags); + struct netlogon_creds_CredentialState *netlogon_creds_client_init_session_key(TALLOC_CTX *mem_ctx, + const uint8_t session_key[16]); +-void netlogon_creds_client_authenticator(struct netlogon_creds_CredentialState *creds, +- struct netr_Authenticator *next); ++NTSTATUS ++netlogon_creds_client_authenticator(struct netlogon_creds_CredentialState *creds, ++ struct netr_Authenticator *next); + bool netlogon_creds_client_check(struct netlogon_creds_CredentialState *creds, + const struct netr_Credential *received_credentials); + struct netlogon_creds_CredentialState *netlogon_creds_copy( +-- +2.23.0 + diff --git a/SOURCES/0150-auth-pycreds-Check-return-code-of-netlogon_creds_cli.patch b/SOURCES/0150-auth-pycreds-Check-return-code-of-netlogon_creds_cli.patch new file mode 100644 index 0000000..5e8888e --- /dev/null +++ b/SOURCES/0150-auth-pycreds-Check-return-code-of-netlogon_creds_cli.patch @@ -0,0 +1,47 @@ +From 0e97b1a6d9e46a3810d89bd6bcb863eded30399a Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 13 Nov 2019 10:06:20 +0100 +Subject: [PATCH 150/187] auth:pycreds: Check return code of + netlogon_creds_client_authenticator() + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14195 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit d3fffca5e9ab45b43fa3f460ad6051356c9a00a9) +--- + auth/credentials/pycredentials.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/auth/credentials/pycredentials.c b/auth/credentials/pycredentials.c +index 1aef16a0145..84407314d48 100644 +--- a/auth/credentials/pycredentials.c ++++ b/auth/credentials/pycredentials.c +@@ -644,6 +644,7 @@ static PyObject *py_creds_new_client_authenticator(PyObject *self, + struct cli_credentials *creds = NULL; + struct netlogon_creds_CredentialState *nc = NULL; + PyObject *ret = NULL; ++ NTSTATUS status; + + creds = PyCredentials_AsCliCredentials(self); + if (creds == NULL) { +@@ -660,9 +661,13 @@ static PyObject *py_creds_new_client_authenticator(PyObject *self, + return NULL; + } + +- netlogon_creds_client_authenticator( +- nc, +- &auth); ++ status = netlogon_creds_client_authenticator(nc, &auth); ++ if (!NT_STATUS_IS_OK(status)) { ++ PyErr_SetString(PyExc_ValueError, ++ "Failed to create client authenticator"); ++ return NULL; ++ } ++ + ret = Py_BuildValue("{s"PYARG_BYTES_LEN"si}", + "credential", + (const char *) &auth.cred, sizeof(auth.cred), +-- +2.23.0 + diff --git a/SOURCES/0151-libcli-auth-Check-return-code-of-netlogon_creds_clie.patch b/SOURCES/0151-libcli-auth-Check-return-code-of-netlogon_creds_clie.patch new file mode 100644 index 0000000..e432af1 --- /dev/null +++ b/SOURCES/0151-libcli-auth-Check-return-code-of-netlogon_creds_clie.patch @@ -0,0 +1,120 @@ +From bf554cd1d46a4e2955f5dad40f08f8e574760bde Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 13 Nov 2019 10:06:20 +0100 +Subject: [PATCH 151/187] libcli:auth: Check return code of + netlogon_creds_client_authenticator() + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14195 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 0906848936c410f49b26f7688df7ce1a0e1097f5) +--- + libcli/auth/netlogon_creds_cli.c | 49 +++++++++++++++++++++++--------- + 1 file changed, 36 insertions(+), 13 deletions(-) + +diff --git a/libcli/auth/netlogon_creds_cli.c b/libcli/auth/netlogon_creds_cli.c +index 50a5f50a57d..2123862dbd2 100644 +--- a/libcli/auth/netlogon_creds_cli.c ++++ b/libcli/auth/netlogon_creds_cli.c +@@ -1547,7 +1547,11 @@ struct tevent_req *netlogon_creds_cli_check_send(TALLOC_CTX *mem_ctx, + */ + tevent_req_defer_callback(req, state->ev); + +- netlogon_creds_client_authenticator(state->creds, &state->req_auth); ++ status = netlogon_creds_client_authenticator(state->creds, ++ &state->req_auth); ++ if (tevent_req_nterror(req, status)) { ++ return tevent_req_post(req, ev); ++ } + ZERO_STRUCT(state->rep_auth); + + subreq = dcerpc_netr_LogonGetCapabilities_send(state, state->ev, +@@ -1981,8 +1985,11 @@ static void netlogon_creds_cli_ServerPasswordSet_locked(struct tevent_req *subre + tevent_req_defer_callback(req, state->ev); + + state->tmp_creds = *state->creds; +- netlogon_creds_client_authenticator(&state->tmp_creds, +- &state->req_auth); ++ status = netlogon_creds_client_authenticator(&state->tmp_creds, ++ &state->req_auth); ++ if (tevent_req_nterror(req, status)) { ++ return; ++ } + ZERO_STRUCT(state->rep_auth); + + if (state->tmp_creds.negotiate_flags & NETLOGON_NEG_PASSWORD_SET2) { +@@ -2416,8 +2423,12 @@ static void netlogon_creds_cli_LogonSamLogon_start(struct tevent_req *req) + } + + state->tmp_creds = *state->lk_creds; +- netlogon_creds_client_authenticator(&state->tmp_creds, +- &state->req_auth); ++ status = netlogon_creds_client_authenticator(&state->tmp_creds, ++ &state->req_auth); ++ if (tevent_req_nterror(req, status)) { ++ netlogon_creds_cli_LogonSamLogon_cleanup(req, status); ++ return; ++ } + ZERO_STRUCT(state->rep_auth); + + state->logon = netlogon_creds_shallow_copy_logon(state, +@@ -2848,8 +2859,11 @@ static void netlogon_creds_cli_DsrUpdateReadOnlyServerDnsRecords_locked(struct t + tevent_req_defer_callback(req, state->ev); + + state->tmp_creds = *state->creds; +- netlogon_creds_client_authenticator(&state->tmp_creds, +- &state->req_auth); ++ status = netlogon_creds_client_authenticator(&state->tmp_creds, ++ &state->req_auth); ++ if (tevent_req_nterror(req, status)) { ++ return; ++ } + ZERO_STRUCT(state->rep_auth); + + subreq = dcerpc_netr_DsrUpdateReadOnlyServerDnsRecords_send(state, state->ev, +@@ -3100,8 +3114,11 @@ static void netlogon_creds_cli_ServerGetTrustInfo_locked(struct tevent_req *subr + tevent_req_defer_callback(req, state->ev); + + state->tmp_creds = *state->creds; +- netlogon_creds_client_authenticator(&state->tmp_creds, +- &state->req_auth); ++ status = netlogon_creds_client_authenticator(&state->tmp_creds, ++ &state->req_auth); ++ if (tevent_req_nterror(req, status)) { ++ return; ++ } + ZERO_STRUCT(state->rep_auth); + + subreq = dcerpc_netr_ServerGetTrustInfo_send(state, state->ev, +@@ -3402,8 +3419,11 @@ static void netlogon_creds_cli_GetForestTrustInformation_locked(struct tevent_re + tevent_req_defer_callback(req, state->ev); + + state->tmp_creds = *state->creds; +- netlogon_creds_client_authenticator(&state->tmp_creds, +- &state->req_auth); ++ status = netlogon_creds_client_authenticator(&state->tmp_creds, ++ &state->req_auth); ++ if (tevent_req_nterror(req, status)) { ++ return; ++ } + ZERO_STRUCT(state->rep_auth); + + subreq = dcerpc_netr_GetForestTrustInformation_send(state, state->ev, +@@ -3680,8 +3700,11 @@ static void netlogon_creds_cli_SendToSam_locked(struct tevent_req *subreq) + tevent_req_defer_callback(req, state->ev); + + state->tmp_creds = *state->creds; +- netlogon_creds_client_authenticator(&state->tmp_creds, +- &state->req_auth); ++ status = netlogon_creds_client_authenticator(&state->tmp_creds, ++ &state->req_auth); ++ if (tevent_req_nterror(req, status)) { ++ return; ++ } + ZERO_STRUCT(state->rep_auth); + + if (state->tmp_creds.negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { +-- +2.23.0 + diff --git a/SOURCES/0152-s4-librpc-Check-return-code-of-netlogon_creds_client.patch b/SOURCES/0152-s4-librpc-Check-return-code-of-netlogon_creds_client.patch new file mode 100644 index 0000000..c11b392 --- /dev/null +++ b/SOURCES/0152-s4-librpc-Check-return-code-of-netlogon_creds_client.patch @@ -0,0 +1,40 @@ +From 499521611bdba1bd17104bfc9b15bb029ad60c19 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 13 Nov 2019 10:06:20 +0100 +Subject: [PATCH 152/187] s4:librpc: Check return code of + netlogon_creds_client_authenticator() + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14195 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit a64a5b7e17d80a4363774d4e35d3ee676ecf426d) +--- + source4/librpc/rpc/dcerpc_schannel.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/source4/librpc/rpc/dcerpc_schannel.c b/source4/librpc/rpc/dcerpc_schannel.c +index 36edf4b95d7..d12647222eb 100644 +--- a/source4/librpc/rpc/dcerpc_schannel.c ++++ b/source4/librpc/rpc/dcerpc_schannel.c +@@ -456,10 +456,16 @@ static void continue_bind_auth(struct composite_context *ctx) + /* if we have a AES encrypted connection, verify the capabilities */ + if (ndr_syntax_id_equal(&s->table->syntax_id, + &ndr_table_netlogon.syntax_id)) { ++ NTSTATUS status; + ZERO_STRUCT(s->return_auth); + + s->save_creds_state = *s->creds_state; +- netlogon_creds_client_authenticator(&s->save_creds_state, &s->auth); ++ status = netlogon_creds_client_authenticator(&s->save_creds_state, ++ &s->auth); ++ if (!NT_STATUS_IS_OK(status)) { ++ composite_error(c, status); ++ return; ++ } + + s->c.in.server_name = talloc_asprintf(c, + "\\\\%s", +-- +2.23.0 + diff --git a/SOURCES/0153-libcli-auth-Check-return-code-of-netlogon_creds_step.patch b/SOURCES/0153-libcli-auth-Check-return-code-of-netlogon_creds_step.patch new file mode 100644 index 0000000..f7b6fb9 --- /dev/null +++ b/SOURCES/0153-libcli-auth-Check-return-code-of-netlogon_creds_step.patch @@ -0,0 +1,86 @@ +From 13601560c9b48466b70ad577ebab245fea1f50b5 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 13 Nov 2019 10:12:41 +0100 +Subject: [PATCH 153/187] libcli:auth: Check return code of + netlogon_creds_step() + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14195 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 05f59cbcf803d57ab41b4c7fa4f81da50cd02cd6) +--- + libcli/auth/credentials.c | 20 +++++++++++++++++--- + 1 file changed, 17 insertions(+), 3 deletions(-) + +diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c +index e5bf2c4703c..3dd50a11bce 100644 +--- a/libcli/auth/credentials.c ++++ b/libcli/auth/credentials.c +@@ -191,9 +191,10 @@ static NTSTATUS netlogon_creds_first_step(struct netlogon_creds_CredentialState + step the credentials to the next element in the chain, updating the + current client and server credentials and the seed + */ +-static void netlogon_creds_step(struct netlogon_creds_CredentialState *creds) ++static NTSTATUS netlogon_creds_step(struct netlogon_creds_CredentialState *creds) + { + struct netr_Credential time_cred; ++ NTSTATUS status; + + DEBUG(5,("\tseed %08x:%08x\n", + IVAL(creds->seed.data, 0), IVAL(creds->seed.data, 4))); +@@ -220,6 +221,8 @@ static void netlogon_creds_step(struct netlogon_creds_CredentialState *creds) + IVAL(creds->server.data, 0), IVAL(creds->server.data, 4))); + + creds->seed = time_cred; ++ ++ return NT_STATUS_OK; + } + + +@@ -518,6 +521,7 @@ netlogon_creds_client_authenticator(struct netlogon_creds_CredentialState *creds + struct netr_Authenticator *next) + { + uint32_t t32n = (uint32_t)time(NULL); ++ NTSTATUS status; + + /* + * we always increment and ignore an overflow here +@@ -540,7 +544,10 @@ netlogon_creds_client_authenticator(struct netlogon_creds_CredentialState *creds + } + } + +- netlogon_creds_step(creds); ++ status = netlogon_creds_step(creds); ++ if (!NT_STATUS_IS_OK(status)) { ++ return status; ++ } + + next->cred = creds->client; + next->timestamp = creds->sequence; +@@ -686,6 +693,8 @@ NTSTATUS netlogon_creds_server_step_check(struct netlogon_creds_CredentialState + const struct netr_Authenticator *received_authenticator, + struct netr_Authenticator *return_authenticator) + { ++ NTSTATUS status; ++ + if (!received_authenticator || !return_authenticator) { + return NT_STATUS_INVALID_PARAMETER; + } +@@ -695,7 +704,12 @@ NTSTATUS netlogon_creds_server_step_check(struct netlogon_creds_CredentialState + } + + creds->sequence = received_authenticator->timestamp; +- netlogon_creds_step(creds); ++ status = netlogon_creds_step(creds); ++ if (!NT_STATUS_IS_OK(status)) { ++ ZERO_STRUCTP(return_authenticator); ++ return status; ++ } ++ + if (netlogon_creds_server_check_internal(creds, &received_authenticator->cred)) { + return_authenticator->cred = creds->server; + return_authenticator->timestamp = 0; +-- +2.23.0 + diff --git a/SOURCES/0154-libcli-auth-Check-return-code-of-netlogon_creds_step.patch b/SOURCES/0154-libcli-auth-Check-return-code-of-netlogon_creds_step.patch new file mode 100644 index 0000000..7d9c111 --- /dev/null +++ b/SOURCES/0154-libcli-auth-Check-return-code-of-netlogon_creds_step.patch @@ -0,0 +1,94 @@ +From 760fc5d0b41a6c12c79f19ec2834925cbd651b80 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 13 Nov 2019 10:13:53 +0100 +Subject: [PATCH 154/187] libcli:auth: Check return code of + netlogon_creds_step_crypt() + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14195 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 32e75bb4cca994af80bb8440009446e4a0ff5d40) +--- + libcli/auth/credentials.c | 36 +++++++++++++++++++++++++++++------- + 1 file changed, 29 insertions(+), 7 deletions(-) + +diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c +index 3dd50a11bce..c78f2012bf2 100644 +--- a/libcli/auth/credentials.c ++++ b/libcli/auth/credentials.c +@@ -33,9 +33,9 @@ + #include + #include + +-static void netlogon_creds_step_crypt(struct netlogon_creds_CredentialState *creds, +- const struct netr_Credential *in, +- struct netr_Credential *out) ++static NTSTATUS netlogon_creds_step_crypt(struct netlogon_creds_CredentialState *creds, ++ const struct netr_Credential *in, ++ struct netr_Credential *out) + { + if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { + memcpy(out->data, in->data, sizeof(out->data)); +@@ -44,6 +44,8 @@ static void netlogon_creds_step_crypt(struct netlogon_creds_CredentialState *cre + } else { + des_crypt112(out->data, in->data, creds->session_key, 1); + } ++ ++ return NT_STATUS_OK; + } + + /* +@@ -178,9 +180,21 @@ static NTSTATUS netlogon_creds_first_step(struct netlogon_creds_CredentialState + const struct netr_Credential *client_challenge, + const struct netr_Credential *server_challenge) + { +- netlogon_creds_step_crypt(creds, client_challenge, &creds->client); ++ NTSTATUS status; + +- netlogon_creds_step_crypt(creds, server_challenge, &creds->server); ++ status = netlogon_creds_step_crypt(creds, ++ client_challenge, ++ &creds->client); ++ if (!NT_STATUS_IS_OK(status)) { ++ return status; ++ } ++ ++ status = netlogon_creds_step_crypt(creds, ++ server_challenge, ++ &creds->server); ++ if (!NT_STATUS_IS_OK(status)) { ++ return status; ++ } + + creds->seed = creds->client; + +@@ -204,7 +218,12 @@ static NTSTATUS netlogon_creds_step(struct netlogon_creds_CredentialState *creds + + DEBUG(5,("\tseed+time %08x:%08x\n", IVAL(time_cred.data, 0), IVAL(time_cred.data, 4))); + +- netlogon_creds_step_crypt(creds, &time_cred, &creds->client); ++ status = netlogon_creds_step_crypt(creds, ++ &time_cred, ++ &creds->client); ++ if (!NT_STATUS_IS_OK(status)) { ++ return status; ++ } + + DEBUG(5,("\tCLIENT %08x:%08x\n", + IVAL(creds->client.data, 0), IVAL(creds->client.data, 4))); +@@ -215,7 +234,10 @@ static NTSTATUS netlogon_creds_step(struct netlogon_creds_CredentialState *creds + DEBUG(5,("\tseed+time+1 %08x:%08x\n", + IVAL(time_cred.data, 0), IVAL(time_cred.data, 4))); + +- netlogon_creds_step_crypt(creds, &time_cred, &creds->server); ++ status = netlogon_creds_step_crypt(creds, &time_cred, &creds->server); ++ if (!NT_STATUS_IS_OK(status)) { ++ return status; ++ } + + DEBUG(5,("\tSERVER %08x:%08x\n", + IVAL(creds->server.data, 0), IVAL(creds->server.data, 4))); +-- +2.23.0 + diff --git a/SOURCES/0155-libcli-auth-Check-return-code-of-netlogon_creds_aes_.patch b/SOURCES/0155-libcli-auth-Check-return-code-of-netlogon_creds_aes_.patch new file mode 100644 index 0000000..31e9648 --- /dev/null +++ b/SOURCES/0155-libcli-auth-Check-return-code-of-netlogon_creds_aes_.patch @@ -0,0 +1,83 @@ +From 63820f4d509c10993de827bc99115f57151e8ef4 Mon Sep 17 00:00:00 2001 +From: Andrew Bartlett +Date: Thu, 14 Nov 2019 11:16:09 +1300 +Subject: [PATCH 155/187] libcli:auth Check return code of + netlogon_creds_aes_encrypt() + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14195 + +Signed-off-by: Andrew Bartlett +Reviewed-by: Andrew Bartlett + +Autobuild-User(master): Andreas Schneider +Autobuild-Date(master): Thu Nov 14 09:25:36 UTC 2019 on sn-devel-184 + +(cherry picked from commit 0361a26e395723296899c3d48cff86d532372710) +--- + libcli/auth/credentials.c | 8 +++++++- + libcli/auth/netlogon_creds_cli.c | 20 ++++++++++++++------ + 2 files changed, 21 insertions(+), 7 deletions(-) + +diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c +index c78f2012bf2..f1088a1d8e0 100644 +--- a/libcli/auth/credentials.c ++++ b/libcli/auth/credentials.c +@@ -37,10 +37,16 @@ static NTSTATUS netlogon_creds_step_crypt(struct netlogon_creds_CredentialState + const struct netr_Credential *in, + struct netr_Credential *out) + { ++ NTSTATUS status; + if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { + memcpy(out->data, in->data, sizeof(out->data)); + +- netlogon_creds_aes_encrypt(creds, out->data, sizeof(out->data)); ++ status = netlogon_creds_aes_encrypt(creds, ++ out->data, ++ sizeof(out->data)); ++ if (!NT_STATUS_IS_OK(status)) { ++ return status; ++ } + } else { + des_crypt112(out->data, in->data, creds->session_key, 1); + } +diff --git a/libcli/auth/netlogon_creds_cli.c b/libcli/auth/netlogon_creds_cli.c +index 2123862dbd2..0378f302ffa 100644 +--- a/libcli/auth/netlogon_creds_cli.c ++++ b/libcli/auth/netlogon_creds_cli.c +@@ -1995,9 +1995,13 @@ static void netlogon_creds_cli_ServerPasswordSet_locked(struct tevent_req *subre + if (state->tmp_creds.negotiate_flags & NETLOGON_NEG_PASSWORD_SET2) { + + if (state->tmp_creds.negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { +- netlogon_creds_aes_encrypt(&state->tmp_creds, +- state->samr_crypt_password.data, +- 516); ++ status = netlogon_creds_aes_encrypt(&state->tmp_creds, ++ state->samr_crypt_password.data, ++ 516); ++ if (tevent_req_nterror(req, status)) { ++ netlogon_creds_cli_ServerPasswordSet_cleanup(req, status); ++ return; ++ } + } else { + status = netlogon_creds_arcfour_crypt(&state->tmp_creds, + state->samr_crypt_password.data, +@@ -3708,9 +3712,13 @@ static void netlogon_creds_cli_SendToSam_locked(struct tevent_req *subreq) + ZERO_STRUCT(state->rep_auth); + + if (state->tmp_creds.negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { +- netlogon_creds_aes_encrypt(&state->tmp_creds, +- state->opaque.data, +- state->opaque.length); ++ status = netlogon_creds_aes_encrypt(&state->tmp_creds, ++ state->opaque.data, ++ state->opaque.length); ++ if (tevent_req_nterror(req, status)) { ++ netlogon_creds_cli_SendToSam_cleanup(req, status); ++ return; ++ } + } else { + status = netlogon_creds_arcfour_crypt(&state->tmp_creds, + state->opaque.data, +-- +2.23.0 + diff --git a/SOURCES/0156-s3-rpc_server-Replace-E_md5hash-with-GnuTLS-calls.patch b/SOURCES/0156-s3-rpc_server-Replace-E_md5hash-with-GnuTLS-calls.patch new file mode 100644 index 0000000..d8d7efb --- /dev/null +++ b/SOURCES/0156-s3-rpc_server-Replace-E_md5hash-with-GnuTLS-calls.patch @@ -0,0 +1,52 @@ +From baf13627d2bc6ade8cb6c05c6ada027fde601844 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Mon, 18 Nov 2019 10:21:06 +0100 +Subject: [PATCH 156/187] s3:rpc_server: Replace E_md5hash() with GnuTLS calls + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14195 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit a377214dce2e9d71f880949fe745d799c75f57a9) +--- + source3/rpc_server/samr/srv_samr_chgpasswd.c | 20 +++++++++++++++++++- + 1 file changed, 19 insertions(+), 1 deletion(-) + +diff --git a/source3/rpc_server/samr/srv_samr_chgpasswd.c b/source3/rpc_server/samr/srv_samr_chgpasswd.c +index fc509494ebc..8c9cf73bdd8 100644 +--- a/source3/rpc_server/samr/srv_samr_chgpasswd.c ++++ b/source3/rpc_server/samr/srv_samr_chgpasswd.c +@@ -901,11 +901,29 @@ static bool password_in_history(uint8_t nt_pw[NT_HASH_LEN], + return true; + } + } else { ++ gnutls_hash_hd_t hash_hnd = NULL; ++ int rc; ++ + /* + * Old format: md5sum of salted nt hash. + * Create salted version of new pw to compare. + */ +- E_md5hash(current_salt, nt_pw, new_nt_pw_salted_md5_hash); ++ rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5); ++ if (rc < 0) { ++ return false; ++ } ++ ++ rc = gnutls_hash(hash_hnd, current_salt, 16); ++ if (rc < 0) { ++ gnutls_hash_deinit(hash_hnd, NULL); ++ return false; ++ } ++ rc = gnutls_hash(hash_hnd, nt_pw, 16); ++ if (rc < 0) { ++ gnutls_hash_deinit(hash_hnd, NULL); ++ return false; ++ } ++ gnutls_hash_deinit(hash_hnd, new_nt_pw_salted_md5_hash); + + if (memcmp(new_nt_pw_salted_md5_hash, + old_nt_pw_salted_md5_hash, +-- +2.23.0 + diff --git a/SOURCES/0157-s3-winbindd-Replace-E_md5hash-with-GnuTLS-calls.patch b/SOURCES/0157-s3-winbindd-Replace-E_md5hash-with-GnuTLS-calls.patch new file mode 100644 index 0000000..aae1fe0 --- /dev/null +++ b/SOURCES/0157-s3-winbindd-Replace-E_md5hash-with-GnuTLS-calls.patch @@ -0,0 +1,65 @@ +From ed65e74773c0c8d3d3a9c23aa97b93baea31d9ae Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Mon, 18 Nov 2019 10:24:56 +0100 +Subject: [PATCH 157/187] s3:winbindd: Replace E_md5hash() with GnuTLS calls + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14195 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 10499507c4fd91751898696b866ce32b1e38f605) +--- + source3/winbindd/winbindd_cache.c | 23 ++++++++++++++++++++++- + 1 file changed, 22 insertions(+), 1 deletion(-) + +diff --git a/source3/winbindd/winbindd_cache.c b/source3/winbindd/winbindd_cache.c +index 394b0c774a9..3e7afdaa546 100644 +--- a/source3/winbindd/winbindd_cache.c ++++ b/source3/winbindd/winbindd_cache.c +@@ -37,6 +37,9 @@ + #include "libsmb/samlogon_cache.h" + #include "lib/namemap_cache.h" + ++#include "lib/crypto/gnutls_helpers.h" ++#include ++ + #undef DBGC_CLASS + #define DBGC_CLASS DBGC_WINBIND + +@@ -1364,6 +1367,8 @@ NTSTATUS wcache_save_creds(struct winbindd_domain *domain, + uint32_t rid; + uint8_t cred_salt[NT_HASH_LEN]; + uint8_t salted_hash[NT_HASH_LEN]; ++ gnutls_hash_hd_t hash_hnd = NULL; ++ int rc; + + if (is_null_sid(sid)) { + return NT_STATUS_INVALID_SID; +@@ -1384,7 +1389,23 @@ NTSTATUS wcache_save_creds(struct winbindd_domain *domain, + + /* Create a salt and then salt the hash. */ + generate_random_buffer(cred_salt, NT_HASH_LEN); +- E_md5hash(cred_salt, nt_pass, salted_hash); ++ ++ rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5); ++ if (rc < 0) { ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED); ++ } ++ ++ rc = gnutls_hash(hash_hnd, cred_salt, 16); ++ if (rc < 0) { ++ gnutls_hash_deinit(hash_hnd, NULL); ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED); ++ } ++ rc = gnutls_hash(hash_hnd, nt_pass, 16); ++ if (rc < 0) { ++ gnutls_hash_deinit(hash_hnd, NULL); ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED); ++ } ++ gnutls_hash_deinit(hash_hnd, salted_hash); + + centry_put_hash16(centry, salted_hash); + centry_put_hash16(centry, cred_salt); +-- +2.23.0 + diff --git a/SOURCES/0158-s3-winbind-Replace-E_md5hash-with-GnuTLS-calls.patch b/SOURCES/0158-s3-winbind-Replace-E_md5hash-with-GnuTLS-calls.patch new file mode 100644 index 0000000..438550d --- /dev/null +++ b/SOURCES/0158-s3-winbind-Replace-E_md5hash-with-GnuTLS-calls.patch @@ -0,0 +1,58 @@ +From 89693b474a37c393ceb47afd668e8a96282a98b0 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Mon, 18 Nov 2019 10:28:59 +0100 +Subject: [PATCH 158/187] s3:winbind: Replace E_md5hash() with GnuTLS calls + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14195 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 4199d1040f09b5d95522d0cbdbaeec78b7d7b9a6) +--- + source3/winbindd/winbindd_pam.c | 23 ++++++++++++++++++++++- + 1 file changed, 22 insertions(+), 1 deletion(-) + +diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c +index c5b7c09b5c1..8946dd70f99 100644 +--- a/source3/winbindd/winbindd_pam.c ++++ b/source3/winbindd/winbindd_pam.c +@@ -48,6 +48,9 @@ + #include "param/param.h" + #include "messaging/messaging.h" + ++#include "lib/crypto/gnutls_helpers.h" ++#include ++ + #undef DBGC_CLASS + #define DBGC_CLASS DBGC_WINBIND + +@@ -1086,7 +1089,25 @@ static NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain, + /* In this case we didn't store the nt_hash itself, + but the MD5 combination of salt + nt_hash. */ + uchar salted_hash[NT_HASH_LEN]; +- E_md5hash(cached_salt, new_nt_pass, salted_hash); ++ gnutls_hash_hd_t hash_hnd = NULL; ++ int rc; ++ ++ rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5); ++ if (rc < 0) { ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED); ++ } ++ ++ rc = gnutls_hash(hash_hnd, cached_salt, 16); ++ if (rc < 0) { ++ gnutls_hash_deinit(hash_hnd, NULL); ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED); ++ } ++ rc = gnutls_hash(hash_hnd, new_nt_pass, 16); ++ if (rc < 0) { ++ gnutls_hash_deinit(hash_hnd, NULL); ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED); ++ } ++ gnutls_hash_deinit(hash_hnd, salted_hash); + + password_good = (memcmp(cached_nt_pass, salted_hash, + NT_HASH_LEN) == 0); +-- +2.23.0 + diff --git a/SOURCES/0159-libcli-auth-Remove-unused-E_md5hash.patch b/SOURCES/0159-libcli-auth-Remove-unused-E_md5hash.patch new file mode 100644 index 0000000..6343a93 --- /dev/null +++ b/SOURCES/0159-libcli-auth-Remove-unused-E_md5hash.patch @@ -0,0 +1,81 @@ +From a2430d2ddcabca282d49e8dcd66cc0aaa1e85918 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Mon, 18 Nov 2019 10:29:55 +0100 +Subject: [PATCH 159/187] libcli:auth: Remove unused E_md5hash() + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14195 + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit e19b115dd27891896364f5e943b0ce7fcc89344e) +--- + libcli/auth/proto.h | 8 -------- + libcli/auth/smbencrypt.c | 33 --------------------------------- + 2 files changed, 41 deletions(-) + +diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h +index eef1c8dc095..eb725c83d15 100644 +--- a/libcli/auth/proto.h ++++ b/libcli/auth/proto.h +@@ -105,14 +105,6 @@ bool SMBencrypt(const char *passwd, const uint8_t *c8, uint8_t p24[24]); + */ + bool E_md4hash(const char *passwd, uint8_t p16[16]); + +-/** +- * Creates the MD5 Hash of a combination of 16 byte salt and 16 byte NT hash. +- * @param 16 byte salt. +- * @param 16 byte NT hash. +- * @param 16 byte return hashed with md5, caller allocated 16 byte buffer +- */ +-void E_md5hash(const uint8_t salt[16], const uint8_t nthash[16], uint8_t hash_out[16]); +- + /** + * Creates the DES forward-only Hash of the users password in DOS ASCII charset + * @param passwd password in 'unix' charset. +diff --git a/libcli/auth/smbencrypt.c b/libcli/auth/smbencrypt.c +index e33d29de19d..ab2c47ad9bb 100644 +--- a/libcli/auth/smbencrypt.c ++++ b/libcli/auth/smbencrypt.c +@@ -94,39 +94,6 @@ bool E_md4hash(const char *passwd, uint8_t p16[16]) + return true; + } + +-/** +- * Creates the MD5 Hash of a combination of 16 byte salt and 16 byte NT hash. +- * @param 16 byte salt. +- * @param 16 byte NT hash. +- * @param 16 byte return hashed with md5, caller allocated 16 byte buffer +- */ +- +-void E_md5hash(const uint8_t salt[16], const uint8_t nthash[16], uint8_t hash_out[16]) +-{ +- gnutls_hash_hd_t hash_hnd = NULL; +- int rc; +- +- rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5); +- if (rc < 0) { +- goto out; +- } +- +- rc = gnutls_hash(hash_hnd, salt, 16); +- if (rc < 0) { +- gnutls_hash_deinit(hash_hnd, NULL); +- goto out; +- } +- rc = gnutls_hash(hash_hnd, nthash, 16); +- if (rc < 0) { +- gnutls_hash_deinit(hash_hnd, NULL); +- goto out; +- } +- gnutls_hash_deinit(hash_hnd, hash_out); +- +-out: +- return; +-} +- + /** + * Creates the DES forward-only Hash of the users password in DOS ASCII charset + * @param passwd password in 'unix' charset. +-- +2.23.0 + diff --git a/SOURCES/0160-s4-lib-tls-Fix-cert-and-privkey-types.patch b/SOURCES/0160-s4-lib-tls-Fix-cert-and-privkey-types.patch new file mode 100644 index 0000000..4dacc9b --- /dev/null +++ b/SOURCES/0160-s4-lib-tls-Fix-cert-and-privkey-types.patch @@ -0,0 +1,42 @@ +From 38c91edbe9f634ba4ab90f51b5f2e69742e49f8a Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Mon, 18 Nov 2019 16:33:23 +0100 +Subject: [PATCH 160/187] s4:lib:tls: Fix cert and privkey types +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +../../source4/lib/tls/tlscert.c:42:2: warning: ‘gnutls_x509_crt’ is + deprecated [-Wdeprecated-declarations] + 42 | gnutls_x509_crt cacrt, crt; + | ^~~~~~~~~~~~~~~ +../../source4/lib/tls/tlscert.c:43:2: warning: ‘gnutls_x509_privkey’ is + deprecated [-Wdeprecated-declarations] + 43 | gnutls_x509_privkey key, cakey; + | ^~~~~~~~~~~~~~~~~~~ + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 71816984c31cd1a392355afdbfdadb0da2d05765) +--- + source4/lib/tls/tlscert.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/source4/lib/tls/tlscert.c b/source4/lib/tls/tlscert.c +index f5e9a1f2d39..9379ab094d1 100644 +--- a/source4/lib/tls/tlscert.c ++++ b/source4/lib/tls/tlscert.c +@@ -39,8 +39,8 @@ void tls_cert_generate(TALLOC_CTX *mem_ctx, + const char *keyfile, const char *certfile, + const char *cafile) + { +- gnutls_x509_crt cacrt, crt; +- gnutls_x509_privkey key, cakey; ++ gnutls_x509_crt_t cacrt, crt; ++ gnutls_x509_privkey_t key, cakey; + uint32_t serial = (uint32_t)time(NULL); + unsigned char keyid[100]; + char buf[4096]; +-- +2.23.0 + diff --git a/SOURCES/0161-winbind-Fix-CID-1455915-Resource-leak.patch b/SOURCES/0161-winbind-Fix-CID-1455915-Resource-leak.patch new file mode 100644 index 0000000..0f4c18f --- /dev/null +++ b/SOURCES/0161-winbind-Fix-CID-1455915-Resource-leak.patch @@ -0,0 +1,40 @@ +From aa688caadf30b5f212e2b5614a62268946174888 Mon Sep 17 00:00:00 2001 +From: Volker Lendecke +Date: Tue, 19 Nov 2019 14:20:14 +0100 +Subject: [PATCH 161/187] winbind: Fix CID 1455915 Resource leak + +Signed-off-by: Volker Lendecke +Reviewed-by: Andreas Schneider +(cherry picked from commit b9e74928ab99a169c76dcd3b401da70cbd1b3985) +--- + source3/winbindd/winbindd_cache.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/source3/winbindd/winbindd_cache.c b/source3/winbindd/winbindd_cache.c +index 3e7afdaa546..9122e2bc5d6 100644 +--- a/source3/winbindd/winbindd_cache.c ++++ b/source3/winbindd/winbindd_cache.c +@@ -1392,17 +1392,20 @@ NTSTATUS wcache_save_creds(struct winbindd_domain *domain, + + rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5); + if (rc < 0) { ++ centry_free(centry); + return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED); + } + + rc = gnutls_hash(hash_hnd, cred_salt, 16); + if (rc < 0) { + gnutls_hash_deinit(hash_hnd, NULL); ++ centry_free(centry); + return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED); + } + rc = gnutls_hash(hash_hnd, nt_pass, 16); + if (rc < 0) { + gnutls_hash_deinit(hash_hnd, NULL); ++ centry_free(centry); + return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED); + } + gnutls_hash_deinit(hash_hnd, salted_hash); +-- +2.23.0 + diff --git a/SOURCES/0162-auth-tests-Improve-debug-output-of-test_gnutls.patch b/SOURCES/0162-auth-tests-Improve-debug-output-of-test_gnutls.patch new file mode 100644 index 0000000..1e2a70c --- /dev/null +++ b/SOURCES/0162-auth-tests-Improve-debug-output-of-test_gnutls.patch @@ -0,0 +1,58 @@ +From 0cafa1b290e7f28f75d2796d0253d4f3a2839562 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Fri, 6 Dec 2019 08:12:34 +0100 +Subject: [PATCH 162/187] auth:tests: Improve debug output of test_gnutls + +Signed-off-by: Andreas Schneider +Reviewed-by: Isaac Boukris +Reviewed-by: Andrew Bartlett +(cherry picked from commit 1c65f1fddba77e94edc5338af81c9a25e0d4e970) +--- + libcli/auth/tests/test_gnutls.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/libcli/auth/tests/test_gnutls.c b/libcli/auth/tests/test_gnutls.c +index f4ef4ec19c8..066d5cf0a9d 100644 +--- a/libcli/auth/tests/test_gnutls.c ++++ b/libcli/auth/tests/test_gnutls.c +@@ -72,7 +72,9 @@ static void torture_gnutls_aes_128_cfb_flags(void **state, + + DEBUG(0,("confounder before crypt:\n")); + dump_data(0, confounder, 8); ++ DEBUG(0,("initial seq num:\n")); + dump_data(0, seq_num_initial.data, 8); ++ DEBUG(0,("io data before crypt:\n")); + dump_data(0, io.data, io.length); + + for (i = 0; i < key.size; i++) { +@@ -100,10 +102,12 @@ static void torture_gnutls_aes_128_cfb_flags(void **state, + io.length); + assert_int_equal(rc, 0); + +- dump_data(0, io.data, io.length); + DEBUG(0,("confounder after crypt:\n")); + dump_data(0, confounder, 8); ++ DEBUG(0,("initial seq num:\n")); + dump_data(0, seq_num_initial.data, 8); ++ DEBUG(0,("io data after crypt:\n")); ++ dump_data(0, io.data, io.length); + assert_memory_equal(io.data, crypt_expected.data, crypt_expected.length); + assert_memory_equal(confounder, confounder_expected.data, confounder_expected.length); + +@@ -118,10 +122,12 @@ static void torture_gnutls_aes_128_cfb_flags(void **state, + assert_int_equal(rc, 0); + gnutls_cipher_deinit(cipher_hnd); + +- dump_data(0, io.data, io.length); + DEBUG(0,("confounder after decrypt:\n")); + dump_data(0, confounder, 8); ++ DEBUG(0,("initial seq num:\n")); + dump_data(0, seq_num_initial.data, 8); ++ DEBUG(0,("io data after decrypt:\n")); ++ dump_data(0, io.data, io.length); + assert_memory_equal(io.data, clear_initial.data, clear_initial.length); + assert_memory_equal(confounder, confounder_initial.data, confounder_initial.length); + } +-- +2.23.0 + diff --git a/SOURCES/0163-auth-tests-Only-enable-torture_gnutls_aes_128_cfb-on.patch b/SOURCES/0163-auth-tests-Only-enable-torture_gnutls_aes_128_cfb-on.patch new file mode 100644 index 0000000..d493f43 --- /dev/null +++ b/SOURCES/0163-auth-tests-Only-enable-torture_gnutls_aes_128_cfb-on.patch @@ -0,0 +1,39 @@ +From 1e72f0d5b636d4f9a5ad39e2ac01230fcb2badd8 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Fri, 6 Dec 2019 08:49:54 +0100 +Subject: [PATCH 163/187] auth:tests: Only enable torture_gnutls_aes_128_cfb() + on GnuTLS >= 3.6.11 + +Signed-off-by: Andreas Schneider +Reviewed-by: Isaac Boukris +Reviewed-by: Andrew Bartlett +(cherry picked from commit 01f531ba6ba1306e99d2e4715dadae073eb0a8ec) +--- + libcli/auth/tests/test_gnutls.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libcli/auth/tests/test_gnutls.c b/libcli/auth/tests/test_gnutls.c +index 066d5cf0a9d..412a454b762 100644 +--- a/libcli/auth/tests/test_gnutls.c ++++ b/libcli/auth/tests/test_gnutls.c +@@ -29,7 +29,7 @@ + #include + #include + +-#ifdef HAVE_GNUTLS_AES_CFB8 ++#if defined(HAVE_GNUTLS_AES_CFB8) && GNUTLS_VERSION_NUMBER > 0x03060a + static void torture_gnutls_aes_128_cfb_flags(void **state, + const DATA_BLOB session_key, + const DATA_BLOB seq_num_initial, +@@ -135,7 +135,7 @@ static void torture_gnutls_aes_128_cfb_flags(void **state, + + static void torture_gnutls_aes_128_cfb(void **state) + { +-#ifdef HAVE_GNUTLS_AES_CFB8 ++#if defined(HAVE_GNUTLS_AES_CFB8) && GNUTLS_VERSION_NUMBER > 0x03060a + const uint8_t _session_key[16] = { + 0x8E, 0xE8, 0x27, 0x85, 0x83, 0x41, 0x3C, 0x8D, + 0xC9, 0x54, 0x70, 0x75, 0x8E, 0xC9, 0x69, 0x91 +-- +2.23.0 + diff --git a/SOURCES/0164-libcli-auth-test-des_crypt56-and-add-test_gnutls-to-.patch b/SOURCES/0164-libcli-auth-test-des_crypt56-and-add-test_gnutls-to-.patch new file mode 100644 index 0000000..707d736 --- /dev/null +++ b/SOURCES/0164-libcli-auth-test-des_crypt56-and-add-test_gnutls-to-.patch @@ -0,0 +1,90 @@ +From c1258172d502955442704264ec1c7ea926784b35 Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Sat, 9 Nov 2019 17:47:33 +0100 +Subject: [PATCH 164/187] libcli/auth: test des_crypt56() and add test_gnutls + to selftest + +Signed-off-by: Isaac Boukris +Reviewed-by: Andrew Bartlett +(cherry picked from commit 07b4606f893fabd50c2685307d58e86f55defae5) +--- + libcli/auth/tests/test_gnutls.c | 24 ++++++++++++++++++++++++ + libcli/auth/wscript_build | 1 + + selftest/tests.py | 2 ++ + 3 files changed, 27 insertions(+) + +diff --git a/libcli/auth/tests/test_gnutls.c b/libcli/auth/tests/test_gnutls.c +index 412a454b762..7847d01a4dc 100644 +--- a/libcli/auth/tests/test_gnutls.c ++++ b/libcli/auth/tests/test_gnutls.c +@@ -24,6 +24,7 @@ + #include + + #include "includes.h" ++#include "libcli/auth/libcli_auth.h" + + #include "lib/crypto/gnutls_helpers.h" + #include +@@ -227,11 +228,34 @@ static void torture_gnutls_aes_128_cfb(void **state) + #endif + } + ++static void torture_gnutls_des_crypt56(void **state) ++{ ++ static const uint8_t key[7] = { ++ 0x69, 0x88, 0x96, 0x8E, 0xB5, 0x3A, 0x24 ++ }; ++ static const uint8_t clear[8] = { ++ 0x3F, 0x49, 0x5B, 0x20, 0xA7, 0x84, 0xC2, 0x34 ++ }; ++ static const uint8_t crypt_expected[8] = { ++ 0x54, 0x86, 0xCF, 0x51, 0x49, 0x3A, 0x53, 0x5B ++ }; ++ ++ uint8_t crypt[8]; ++ uint8_t decrypt[8]; ++ ++ des_crypt56(crypt, clear, key, 1); ++ assert_memory_equal(crypt, crypt_expected, 8); ++ ++ des_crypt56(decrypt, crypt, key, 0); ++ assert_memory_equal(decrypt, clear, 8); ++} ++ + int main(int argc, char *argv[]) + { + int rc; + const struct CMUnitTest tests[] = { + cmocka_unit_test(torture_gnutls_aes_128_cfb), ++ cmocka_unit_test(torture_gnutls_des_crypt56), + }; + + if (argc == 2) { +diff --git a/libcli/auth/wscript_build b/libcli/auth/wscript_build +index 7b765cd9e43..8e856d07ddf 100644 +--- a/libcli/auth/wscript_build ++++ b/libcli/auth/wscript_build +@@ -76,6 +76,7 @@ bld.SAMBA_BINARY('test_gnutls', + source='tests/test_gnutls.c', + deps=''' + gnutls ++ LIBCLI_AUTH + cmocka + samba-util + ''', +diff --git a/selftest/tests.py b/selftest/tests.py +index c91d9b445fe..20809678104 100644 +--- a/selftest/tests.py ++++ b/selftest/tests.py +@@ -390,6 +390,8 @@ plantestsuite("samba.unittests.byteorder", "none", + [os.path.join(bindir(), "default/lib/util/test_byteorder")]) + plantestsuite("samba.unittests.ntlm_check", "none", + [os.path.join(bindir(), "default/libcli/auth/test_ntlm_check")]) ++plantestsuite("samba.unittests.gnutls", "none", ++ [os.path.join(bindir(), "default/libcli/auth/test_gnutls")]) + plantestsuite("samba.unittests.schannel", "none", + [os.path.join(bindir(), "default/libcli/auth/test_schannel")]) + plantestsuite("samba.unittests.rc4_passwd_buffer", "none", +-- +2.23.0 + diff --git a/SOURCES/0165-selftest-test-E_P16.patch b/SOURCES/0165-selftest-test-E_P16.patch new file mode 100644 index 0000000..26e83af --- /dev/null +++ b/SOURCES/0165-selftest-test-E_P16.patch @@ -0,0 +1,52 @@ +From b99a520661dbfcdd69da38be9ab35ed8a69a0b6d Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Tue, 19 Nov 2019 09:46:18 +0100 +Subject: [PATCH 165/187] selftest: test E_P16 + +Signed-off-by: Isaac Boukris +Reviewed-by: Andrew Bartlett +(cherry picked from commit 7044a41a30e43dda34eecb6df3da82ed5d568eec) +--- + libcli/auth/tests/test_gnutls.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/libcli/auth/tests/test_gnutls.c b/libcli/auth/tests/test_gnutls.c +index 7847d01a4dc..a2b7cb896d0 100644 +--- a/libcli/auth/tests/test_gnutls.c ++++ b/libcli/auth/tests/test_gnutls.c +@@ -250,12 +250,32 @@ static void torture_gnutls_des_crypt56(void **state) + assert_memory_equal(decrypt, clear, 8); + } + ++static void torture_gnutls_E_P16(void **state) ++{ ++ static const uint8_t key[14] = { ++ 0x98, 0xFD, 0xCB, 0x3A, 0xF7, 0xB5, 0x1C, 0xF8, ++ 0x69, 0x88, 0x96, 0x8E, 0xB5, 0x3A ++ }; ++ uint8_t buffer[16] = { ++ 0x9C, 0x14, 0xDD, 0xE1, 0x39, 0x23, 0xE0, 0x55, ++ 0x3F, 0x49, 0x5B, 0x20, 0xA7, 0x84, 0xC2, 0x34 ++ }; ++ static const uint8_t crypt_expected[16] = { ++ 0x41, 0x4A, 0x7B, 0xEA, 0xAB, 0xBB, 0x95, 0xCE, ++ 0x1D, 0xEA, 0xD9, 0xFF, 0xB0, 0xA9, 0xA4, 0x05 ++ }; ++ ++ E_P16(key, buffer); ++ assert_memory_equal(buffer, crypt_expected, 16); ++} ++ + int main(int argc, char *argv[]) + { + int rc; + const struct CMUnitTest tests[] = { + cmocka_unit_test(torture_gnutls_aes_128_cfb), + cmocka_unit_test(torture_gnutls_des_crypt56), ++ cmocka_unit_test(torture_gnutls_E_P16), + }; + + if (argc == 2) { +-- +2.23.0 + diff --git a/SOURCES/0166-selftest-test-sam_rid_crypt.patch b/SOURCES/0166-selftest-test-sam_rid_crypt.patch new file mode 100644 index 0000000..b6dd08a --- /dev/null +++ b/SOURCES/0166-selftest-test-sam_rid_crypt.patch @@ -0,0 +1,56 @@ +From 439a78c470c7536c4e30604e05c5c03c6a22384d Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Tue, 19 Nov 2019 16:08:49 +0100 +Subject: [PATCH 166/187] selftest: test sam_rid_crypt + +Signed-off-by: Isaac Boukris +Reviewed-by: Andrew Bartlett +(cherry picked from commit 0923f94bdc21a80cbf40aaa65c4928c13c298d82) +--- + libcli/auth/tests/test_gnutls.c | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +diff --git a/libcli/auth/tests/test_gnutls.c b/libcli/auth/tests/test_gnutls.c +index a2b7cb896d0..bef4b5d3cc2 100644 +--- a/libcli/auth/tests/test_gnutls.c ++++ b/libcli/auth/tests/test_gnutls.c +@@ -269,6 +269,28 @@ static void torture_gnutls_E_P16(void **state) + assert_memory_equal(buffer, crypt_expected, 16); + } + ++static void torture_gnutls_sam_rid_crypt(void **state) ++{ ++ static const uint8_t clear[16] = { ++ 0x02, 0xFA, 0x3B, 0xEE, 0xE8, 0xBA, 0x06, 0x01, ++ 0x3F, 0x49, 0x5B, 0x20, 0xA7, 0x84, 0xC2, 0x34 ++ }; ++ static const uint8_t crypt_expected[16] = { ++ 0x1E, 0x38, 0x27, 0x5B, 0x3B, 0xB8, 0x67, 0xEB, ++ 0xFB, 0x67, 0x99, 0xA4, 0x83, 0xF3, 0xD4, 0xED ++ }; ++ ++ uint8_t crypt[16]; ++ uint8_t decrypt[16]; ++ int rid = 500; ++ ++ sam_rid_crypt(rid, clear, crypt, 1); ++ assert_memory_equal(crypt, crypt_expected, 16); ++ ++ sam_rid_crypt(rid, crypt, decrypt, 0); ++ assert_memory_equal(decrypt, clear, 16); ++} ++ + int main(int argc, char *argv[]) + { + int rc; +@@ -276,6 +298,7 @@ int main(int argc, char *argv[]) + cmocka_unit_test(torture_gnutls_aes_128_cfb), + cmocka_unit_test(torture_gnutls_des_crypt56), + cmocka_unit_test(torture_gnutls_E_P16), ++ cmocka_unit_test(torture_gnutls_sam_rid_crypt), + }; + + if (argc == 2) { +-- +2.23.0 + diff --git a/SOURCES/0167-selftest-test-E_P24-and-SMBOWFencrypt.patch b/SOURCES/0167-selftest-test-E_P24-and-SMBOWFencrypt.patch new file mode 100644 index 0000000..f9c6d37 --- /dev/null +++ b/SOURCES/0167-selftest-test-E_P24-and-SMBOWFencrypt.patch @@ -0,0 +1,77 @@ +From 5568783eefaeae47e883f1896dbe12a1bffb374b Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Tue, 19 Nov 2019 18:26:13 +0100 +Subject: [PATCH 167/187] selftest: test E_P24 and SMBOWFencrypt + +Signed-off-by: Isaac Boukris +Reviewed-by: Andrew Bartlett +(cherry picked from commit dfad082596a53a7c6225da427447922fd4b7f0e2) +--- + libcli/auth/tests/test_gnutls.c | 44 +++++++++++++++++++++++++++++++++ + 1 file changed, 44 insertions(+) + +diff --git a/libcli/auth/tests/test_gnutls.c b/libcli/auth/tests/test_gnutls.c +index bef4b5d3cc2..3f6efa62424 100644 +--- a/libcli/auth/tests/test_gnutls.c ++++ b/libcli/auth/tests/test_gnutls.c +@@ -269,6 +269,48 @@ static void torture_gnutls_E_P16(void **state) + assert_memory_equal(buffer, crypt_expected, 16); + } + ++static void torture_gnutls_E_P24(void **state) ++{ ++ static const uint8_t key[21] = { ++ 0xFB, 0x67, 0x99, 0xA4, 0x83, 0xF3, 0xD4, 0xED, ++ 0x98, 0xFD, 0xCB, 0x3A, 0xF7, 0xB5, 0x1C, 0xF8, ++ 0x69, 0x88, 0x96, 0x8E, 0x3A ++ }; ++ const uint8_t c8[8] = { ++ 0x44, 0xFB, 0xAC, 0xFB, 0x83, 0xB6, 0x75, 0x2A ++ }; ++ static const uint8_t crypt_expected[24] = { ++ 0x1A, 0x5E, 0x11, 0xA1, 0x59, 0xA9, 0x6B, 0x4E, ++ 0x12, 0x5D, 0x81, 0x75, 0xA6, 0x62, 0x15, 0x6D, ++ 0x5D, 0x20, 0x25, 0xC1, 0xA3, 0x92, 0xB3, 0x28 ++ }; ++ ++ uint8_t crypt[24]; ++ ++ E_P24(key, c8, crypt); ++ assert_memory_equal(crypt, crypt_expected, 24); ++} ++ ++static void torture_gnutls_SMBOWFencrypt(void **state) ++{ ++ static const uint8_t password[16] = { ++ 'M', 'y', 'p', 'a', 's', 's', 'w', 'o', ++ 'r', 'd', 'i', 's', '1', '1', '1', '1' ++ }; ++ const uint8_t c8[8] = { ++ 0x79, 0x88, 0x5A, 0x3D, 0xD3, 0x40, 0x1E, 0x69 ++ }; ++ static const uint8_t crypt_expected[24] = { ++ 0x3F, 0xE3, 0x53, 0x75, 0x81, 0xB4, 0xF0, 0xE7, ++ 0x0C, 0xDE, 0xCD, 0xAE, 0x39, 0x1F, 0x14, 0xB4, ++ 0xA4, 0x2B, 0x3E, 0x39, 0x16, 0xFD, 0x1D, 0x62 ++ }; ++ ++ uint8_t crypt[24]; ++ ++ SMBOWFencrypt(password, c8, crypt); ++ assert_memory_equal(crypt, crypt_expected, 24); ++} + static void torture_gnutls_sam_rid_crypt(void **state) + { + static const uint8_t clear[16] = { +@@ -298,6 +340,8 @@ int main(int argc, char *argv[]) + cmocka_unit_test(torture_gnutls_aes_128_cfb), + cmocka_unit_test(torture_gnutls_des_crypt56), + cmocka_unit_test(torture_gnutls_E_P16), ++ cmocka_unit_test(torture_gnutls_E_P24), ++ cmocka_unit_test(torture_gnutls_SMBOWFencrypt), + cmocka_unit_test(torture_gnutls_sam_rid_crypt), + }; + +-- +2.23.0 + diff --git a/SOURCES/0168-selftest-test-E_old_pw_hash.patch b/SOURCES/0168-selftest-test-E_old_pw_hash.patch new file mode 100644 index 0000000..d7da542 --- /dev/null +++ b/SOURCES/0168-selftest-test-E_old_pw_hash.patch @@ -0,0 +1,55 @@ +From b074df7982a4783c88b23a4973662e144362eb2e Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Tue, 19 Nov 2019 18:49:58 +0100 +Subject: [PATCH 168/187] selftest: test E_old_pw_hash + +Signed-off-by: Isaac Boukris +Reviewed-by: Andrew Bartlett +(cherry picked from commit 8f042ba532fc645f2389a0a9d3e83d27c070fde4) +--- + libcli/auth/tests/test_gnutls.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/libcli/auth/tests/test_gnutls.c b/libcli/auth/tests/test_gnutls.c +index 3f6efa62424..1e6f8dd5b5b 100644 +--- a/libcli/auth/tests/test_gnutls.c ++++ b/libcli/auth/tests/test_gnutls.c +@@ -311,6 +311,27 @@ static void torture_gnutls_SMBOWFencrypt(void **state) + SMBOWFencrypt(password, c8, crypt); + assert_memory_equal(crypt, crypt_expected, 24); + } ++ ++static void torture_gnutls_E_old_pw_hash(void **state) ++{ ++ static uint8_t key[14] = { ++ 0x98, 0xFD, 0xCB, 0x3A, 0xF7, 0xB5, 0x1C, 0xF8, ++ 0x69, 0x88, 0x96, 0x8E, 0xB5, 0x3A ++ }; ++ uint8_t clear[16] = { ++ 0x9C, 0x14, 0xDD, 0xE1, 0x39, 0x23, 0xE0, 0x55, ++ 0x3F, 0x49, 0x5B, 0x20, 0xA7, 0x84, 0xC2, 0x34 ++ }; ++ static const uint8_t crypt_expected[16] = { ++ 0x6A, 0xC7, 0x08, 0xCA, 0x2A, 0xC1, 0xAA, 0x64, ++ 0x37, 0xEF, 0xBE, 0x58, 0xC2, 0x59, 0x33, 0xEC ++ }; ++ uint8_t crypt[16]; ++ ++ E_old_pw_hash(key, clear, crypt); ++ assert_memory_equal(crypt, crypt_expected, 16); ++} ++ + static void torture_gnutls_sam_rid_crypt(void **state) + { + static const uint8_t clear[16] = { +@@ -342,6 +363,7 @@ int main(int argc, char *argv[]) + cmocka_unit_test(torture_gnutls_E_P16), + cmocka_unit_test(torture_gnutls_E_P24), + cmocka_unit_test(torture_gnutls_SMBOWFencrypt), ++ cmocka_unit_test(torture_gnutls_E_old_pw_hash), + cmocka_unit_test(torture_gnutls_sam_rid_crypt), + }; + +-- +2.23.0 + diff --git a/SOURCES/0169-selftest-test-des_crypt128.patch b/SOURCES/0169-selftest-test-des_crypt128.patch new file mode 100644 index 0000000..1449361 --- /dev/null +++ b/SOURCES/0169-selftest-test-des_crypt128.patch @@ -0,0 +1,53 @@ +From 620713d0e16e07f44fb4c086290161da81d37f1f Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Tue, 19 Nov 2019 19:10:18 +0100 +Subject: [PATCH 169/187] selftest: test des_crypt128 + +Signed-off-by: Isaac Boukris +Reviewed-by: Andrew Bartlett +(cherry picked from commit e2f8f686d1e3fce91f10aadb9667854cf2a1219a) +--- + libcli/auth/tests/test_gnutls.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/libcli/auth/tests/test_gnutls.c b/libcli/auth/tests/test_gnutls.c +index 1e6f8dd5b5b..b1129db14c9 100644 +--- a/libcli/auth/tests/test_gnutls.c ++++ b/libcli/auth/tests/test_gnutls.c +@@ -332,6 +332,25 @@ static void torture_gnutls_E_old_pw_hash(void **state) + assert_memory_equal(crypt, crypt_expected, 16); + } + ++static void torture_gnutls_des_crypt128(void **state) ++{ ++ static uint8_t key[16] = { ++ 0x98, 0xFD, 0xCB, 0x3A, 0xF7, 0xB5, 0x1C, 0xF8, ++ 0xA9, 0x69, 0x88, 0x96, 0x8E, 0xB5, 0x3A, 0x24 ++ }; ++ static const uint8_t clear[8] = { ++ 0x3F, 0x49, 0x5B, 0x20, 0xA7, 0x84, 0xC2, 0x34 ++ }; ++ static const uint8_t crypt_expected[8] = { ++ 0x4C, 0xB4, 0x4B, 0xD3, 0xC8, 0xC1, 0xA5, 0x50 ++ }; ++ ++ uint8_t crypt[8]; ++ ++ des_crypt128(crypt, clear, key); ++ assert_memory_equal(crypt, crypt_expected, 8); ++} ++ + static void torture_gnutls_sam_rid_crypt(void **state) + { + static const uint8_t clear[16] = { +@@ -364,6 +383,7 @@ int main(int argc, char *argv[]) + cmocka_unit_test(torture_gnutls_E_P24), + cmocka_unit_test(torture_gnutls_SMBOWFencrypt), + cmocka_unit_test(torture_gnutls_E_old_pw_hash), ++ cmocka_unit_test(torture_gnutls_des_crypt128), + cmocka_unit_test(torture_gnutls_sam_rid_crypt), + }; + +-- +2.23.0 + diff --git a/SOURCES/0170-selftest-test-des_crypt112-and-fix-unused-decryption.patch b/SOURCES/0170-selftest-test-des_crypt112-and-fix-unused-decryption.patch new file mode 100644 index 0000000..c28a54c --- /dev/null +++ b/SOURCES/0170-selftest-test-des_crypt112-and-fix-unused-decryption.patch @@ -0,0 +1,79 @@ +From bd993cbccae8002dd3125d015c6525060fd8914e Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Tue, 19 Nov 2019 19:49:09 +0100 +Subject: [PATCH 170/187] selftest: test des_crypt112 and fix (unused) + decryption + +Signed-off-by: Isaac Boukris +Reviewed-by: Andrew Bartlett +(cherry picked from commit 394debac6b2f0838cde5d850335e0cdff14b411d) +--- + libcli/auth/smbdes.c | 9 +++++++-- + libcli/auth/tests/test_gnutls.c | 24 ++++++++++++++++++++++++ + 2 files changed, 31 insertions(+), 2 deletions(-) + +diff --git a/libcli/auth/smbdes.c b/libcli/auth/smbdes.c +index 6d9a6dc2ce8..59cb45d81f0 100644 +--- a/libcli/auth/smbdes.c ++++ b/libcli/auth/smbdes.c +@@ -342,8 +342,13 @@ 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) + { + uint8_t buf[8]; +- des_crypt56(buf, in, key, forw); +- des_crypt56(out, buf, key+7, forw); ++ if (forw) { ++ des_crypt56(buf, in, key, forw); ++ des_crypt56(out, buf, key+7, forw); ++ } else { ++ des_crypt56(buf, in, key+7, forw); ++ des_crypt56(out, buf, key, forw); ++ } + } + + /* des encryption of a 16 byte lump of data with a 112 bit key */ +diff --git a/libcli/auth/tests/test_gnutls.c b/libcli/auth/tests/test_gnutls.c +index b1129db14c9..4ae99b64c31 100644 +--- a/libcli/auth/tests/test_gnutls.c ++++ b/libcli/auth/tests/test_gnutls.c +@@ -351,6 +351,29 @@ static void torture_gnutls_des_crypt128(void **state) + assert_memory_equal(crypt, crypt_expected, 8); + } + ++static void torture_gnutls_des_crypt112(void **state) ++{ ++ static uint8_t key[14] = { ++ 0x98, 0xFD, 0xCB, 0x3A, 0xF7, 0xB5, 0x1C, 0xF8, ++ 0x88, 0x96, 0x8E, 0xB5, 0x3A, 0x24 ++ }; ++ static const uint8_t clear[8] = { ++ 0x2F, 0x49, 0x5B, 0x20, 0xD7, 0x84, 0xC2, 0x34 ++ }; ++ static const uint8_t crypt_expected[8] = { ++ 0x87, 0x35, 0xFA, 0xA4, 0x5D, 0x7A, 0xA5, 0x05 ++ }; ++ ++ uint8_t crypt[8]; ++ uint8_t decrypt[8]; ++ ++ des_crypt112(crypt, clear, key, 1); ++ assert_memory_equal(crypt, crypt_expected, 8); ++ ++ des_crypt112(decrypt, crypt, key, 0); ++ assert_memory_equal(decrypt, clear, 8); ++} ++ + static void torture_gnutls_sam_rid_crypt(void **state) + { + static const uint8_t clear[16] = { +@@ -384,6 +407,7 @@ int main(int argc, char *argv[]) + cmocka_unit_test(torture_gnutls_SMBOWFencrypt), + cmocka_unit_test(torture_gnutls_E_old_pw_hash), + cmocka_unit_test(torture_gnutls_des_crypt128), ++ cmocka_unit_test(torture_gnutls_des_crypt112), + cmocka_unit_test(torture_gnutls_sam_rid_crypt), + }; + +-- +2.23.0 + diff --git a/SOURCES/0171-selftest-test-des_crypt112_16.patch b/SOURCES/0171-selftest-test-des_crypt112_16.patch new file mode 100644 index 0000000..7f0d013 --- /dev/null +++ b/SOURCES/0171-selftest-test-des_crypt112_16.patch @@ -0,0 +1,59 @@ +From c47b882674c667bd8e0f7b059360738e72a565c9 Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Tue, 19 Nov 2019 20:02:49 +0100 +Subject: [PATCH 171/187] selftest: test des_crypt112_16 + +Signed-off-by: Isaac Boukris +Reviewed-by: Andrew Bartlett +(cherry picked from commit a4ec427e54b52307ee2e22079449ff3e59279298) +--- + libcli/auth/tests/test_gnutls.c | 26 ++++++++++++++++++++++++++ + 1 file changed, 26 insertions(+) + +diff --git a/libcli/auth/tests/test_gnutls.c b/libcli/auth/tests/test_gnutls.c +index 4ae99b64c31..2e6ed7ba98c 100644 +--- a/libcli/auth/tests/test_gnutls.c ++++ b/libcli/auth/tests/test_gnutls.c +@@ -374,6 +374,31 @@ static void torture_gnutls_des_crypt112(void **state) + assert_memory_equal(decrypt, clear, 8); + } + ++static void torture_gnutls_des_crypt112_16(void **state) ++{ ++ static uint8_t key[14] = { ++ 0x1E, 0x38, 0x27, 0x5B, 0x3B, 0xB8, 0x67, 0xEB, ++ 0x88, 0x96, 0x8E, 0xB5, 0x3A, 0x24 ++ }; ++ static const uint8_t clear[16] = { ++ 0x02, 0xFA, 0x3B, 0xEE, 0xE8, 0xBA, 0x06, 0x01, ++ 0xFB, 0x67, 0x99, 0xA4, 0x83, 0xF3, 0xD4, 0xED ++ }; ++ static const uint8_t crypt_expected[16] = { ++ 0x3C, 0x10, 0x37, 0x67, 0x96, 0x95, 0xF7, 0x96, ++ 0xAA, 0x03, 0xB9, 0xEA, 0xD6, 0xB3, 0xC3, 0x2D ++ }; ++ ++ uint8_t crypt[16]; ++ uint8_t decrypt[16]; ++ ++ des_crypt112_16(crypt, clear, key, 1); ++ assert_memory_equal(crypt, crypt_expected, 16); ++ ++ des_crypt112_16(decrypt, crypt, key, 0); ++ assert_memory_equal(decrypt, clear, 16); ++} ++ + static void torture_gnutls_sam_rid_crypt(void **state) + { + static const uint8_t clear[16] = { +@@ -408,6 +433,7 @@ int main(int argc, char *argv[]) + cmocka_unit_test(torture_gnutls_E_old_pw_hash), + cmocka_unit_test(torture_gnutls_des_crypt128), + cmocka_unit_test(torture_gnutls_des_crypt112), ++ cmocka_unit_test(torture_gnutls_des_crypt112_16), + cmocka_unit_test(torture_gnutls_sam_rid_crypt), + }; + +-- +2.23.0 + diff --git a/SOURCES/0172-selftest-test-SMBsesskeygen_lm_sess_key.patch b/SOURCES/0172-selftest-test-SMBsesskeygen_lm_sess_key.patch new file mode 100644 index 0000000..35969c1 --- /dev/null +++ b/SOURCES/0172-selftest-test-SMBsesskeygen_lm_sess_key.patch @@ -0,0 +1,56 @@ +From dd0fb9bcd71e8fdf9d609c8d5e6c5d952f6ec63f Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Wed, 20 Nov 2019 00:14:31 +0100 +Subject: [PATCH 172/187] selftest: test SMBsesskeygen_lm_sess_key + +Signed-off-by: Isaac Boukris +Reviewed-by: Andrew Bartlett +(cherry picked from commit 6c5f153e4793c0613dd843b1566bd27632912a7c) +--- + libcli/auth/tests/test_gnutls.c | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +diff --git a/libcli/auth/tests/test_gnutls.c b/libcli/auth/tests/test_gnutls.c +index 2e6ed7ba98c..368c4f74640 100644 +--- a/libcli/auth/tests/test_gnutls.c ++++ b/libcli/auth/tests/test_gnutls.c +@@ -421,6 +421,28 @@ static void torture_gnutls_sam_rid_crypt(void **state) + assert_memory_equal(decrypt, clear, 16); + } + ++static void torture_gnutls_SMBsesskeygen_lm_sess_key(void **state) ++{ ++ static const uint8_t lm_hash[16] = { ++ 0xFB, 0x67, 0x99, 0xA4, 0x83, 0xF3, 0xD4, 0xED, ++ 0x9C, 0x14, 0xDD, 0xE1, 0x39, 0x23, 0xE0, 0x55 ++ }; ++ static const uint8_t lm_resp[24] = { ++ 0x02, 0xFA, 0x3B, 0xEE, 0xE8, 0xBA, 0x06, 0x01, ++ 0x02, 0xFA, 0x3B, 0xEE, 0xE8, 0xBA, 0x06, 0x01, ++ 0x1E, 0x38, 0x27, 0x5B, 0x3B, 0xB8, 0x67, 0xEB ++ }; ++ static const uint8_t crypt_expected[16] = { ++ 0x52, 0x8D, 0xB2, 0xD3, 0x89, 0x83, 0xFB, 0x9C, ++ 0x96, 0x45, 0x15, 0x4B, 0xC3, 0xF5, 0xD5, 0x7F ++ }; ++ ++ uint8_t crypt_sess_key[16]; ++ ++ SMBsesskeygen_lm_sess_key(lm_hash, lm_resp, crypt_sess_key); ++ assert_memory_equal(crypt_sess_key, crypt_expected, 16); ++} ++ + int main(int argc, char *argv[]) + { + int rc; +@@ -435,6 +457,7 @@ int main(int argc, char *argv[]) + cmocka_unit_test(torture_gnutls_des_crypt112), + cmocka_unit_test(torture_gnutls_des_crypt112_16), + cmocka_unit_test(torture_gnutls_sam_rid_crypt), ++ cmocka_unit_test(torture_gnutls_SMBsesskeygen_lm_sess_key), + }; + + if (argc == 2) { +-- +2.23.0 + diff --git a/SOURCES/0173-selftest-test-sess_crypt_blob.patch b/SOURCES/0173-selftest-test-sess_crypt_blob.patch new file mode 100644 index 0000000..163d73e --- /dev/null +++ b/SOURCES/0173-selftest-test-sess_crypt_blob.patch @@ -0,0 +1,62 @@ +From bb2986ee6b696da256698750e4e1df1a1b1cea0b Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Wed, 20 Nov 2019 23:44:10 +0100 +Subject: [PATCH 173/187] selftest: test sess_crypt_blob + +Signed-off-by: Isaac Boukris +Reviewed-by: Andrew Bartlett +(cherry picked from commit 2c470c8035be6d70ce3fc8d1e12be284566a7037) +--- + libcli/auth/tests/test_gnutls.c | 29 +++++++++++++++++++++++++++++ + 1 file changed, 29 insertions(+) + +diff --git a/libcli/auth/tests/test_gnutls.c b/libcli/auth/tests/test_gnutls.c +index 368c4f74640..d9ce8a765cf 100644 +--- a/libcli/auth/tests/test_gnutls.c ++++ b/libcli/auth/tests/test_gnutls.c +@@ -443,6 +443,34 @@ static void torture_gnutls_SMBsesskeygen_lm_sess_key(void **state) + assert_memory_equal(crypt_sess_key, crypt_expected, 16); + } + ++static void torture_gnutls_sess_crypt_blob(void **state) ++{ ++ static uint8_t _key[16] = { ++ 0x1E, 0x38, 0x27, 0x5B, 0x3B, 0xB8, 0x67, 0xEB, ++ 0xFA, 0xEE, 0xE8, 0xBA, 0x06, 0x01, 0x2D, 0x95 ++ }; ++ DATA_BLOB key = data_blob_const(_key, 16); ++ static const uint8_t _clear[24] = { ++ 0x98, 0xFD, 0xCB, 0x3A, 0xF7, 0xB5, 0x1C, 0xF8, ++ 0x02, 0xFA, 0x3B, 0xEE, 0xE8, 0xBA, 0x06, 0x01, ++ 0x3F, 0x49, 0x5B, 0x20, 0xA7, 0x84, 0xC2, 0x34 ++ }; ++ DATA_BLOB clear = data_blob_const(_clear, 24); ++ static const uint8_t crypt_expected[24] = { ++ 0x2B, 0xDD, 0x3B, 0xFA, 0x48, 0xC9, 0x63, 0x56, ++ 0xAE, 0x8B, 0x3E, 0xCF, 0xEF, 0xDF, 0x7A, 0x42, ++ 0xB3, 0x00, 0x71, 0x7F, 0x5D, 0x1D, 0xE4, 0x70 ++ }; ++ DATA_BLOB crypt = data_blob(NULL, 24); ++ DATA_BLOB decrypt = data_blob(NULL, 24); ++ ++ sess_crypt_blob(&crypt, &clear, &key, true); ++ assert_memory_equal(crypt.data, crypt_expected, 24); ++ ++ sess_crypt_blob(&decrypt, &crypt, &key, false); ++ assert_memory_equal(decrypt.data, clear.data, 24); ++} ++ + int main(int argc, char *argv[]) + { + int rc; +@@ -458,6 +486,7 @@ int main(int argc, char *argv[]) + cmocka_unit_test(torture_gnutls_des_crypt112_16), + cmocka_unit_test(torture_gnutls_sam_rid_crypt), + cmocka_unit_test(torture_gnutls_SMBsesskeygen_lm_sess_key), ++ cmocka_unit_test(torture_gnutls_sess_crypt_blob), + }; + + if (argc == 2) { +-- +2.23.0 + diff --git a/SOURCES/0174-smbdes-add-des_crypt56_gnutls-using-DES-CBC-with-zer.patch b/SOURCES/0174-smbdes-add-des_crypt56_gnutls-using-DES-CBC-with-zer.patch new file mode 100644 index 0000000..f994535 --- /dev/null +++ b/SOURCES/0174-smbdes-add-des_crypt56_gnutls-using-DES-CBC-with-zer.patch @@ -0,0 +1,184 @@ +From 806c921c8be6d76bb8d01cf290112bceca513b42 Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Sat, 19 Oct 2019 23:48:19 +0300 +Subject: [PATCH 174/187] smbdes: add des_crypt56_gnutls() using DES-CBC with + zeroed IV + +Signed-off-by: Isaac Boukris +Reviewed-by: Andrew Bartlett +(cherry picked from commit 0f855f1ab955e3ecf47689c5e4578eb67ebe8f27) +--- + libcli/auth/proto.h | 4 +++ + libcli/auth/smbdes.c | 57 ++++++++++++++++++++++++++++++++ + libcli/auth/tests/test_gnutls.c | 9 +++++ + libcli/auth/wscript_build | 2 +- + source3/passdb/wscript_build | 2 +- + source3/rpc_server/wscript_build | 3 +- + 6 files changed, 74 insertions(+), 3 deletions(-) + +diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h +index eb725c83d15..e7c9923abf3 100644 +--- a/libcli/auth/proto.h ++++ b/libcli/auth/proto.h +@@ -4,6 +4,8 @@ + #undef _PRINTF_ATTRIBUTE + #define _PRINTF_ATTRIBUTE(a1, a2) PRINTF_ATTRIBUTE(a1, a2) + ++#include "lib/crypto/gnutls_helpers.h" ++ + /* this file contains prototypes for functions that are private + * to this subsystem or library. These functions should not be + * used outside this particular subsystem! */ +@@ -217,6 +219,8 @@ WERROR decode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, + /* The following definitions come from /home/jeremy/src/samba/git/master/source3/../source4/../libcli/auth/smbdes.c */ + + void des_crypt56(uint8_t out[8], const uint8_t in[8], const uint8_t key[7], int forw); ++int des_crypt56_gnutls(uint8_t out[8], const uint8_t in[8], const uint8_t key[7], ++ enum samba_gnutls_direction encrypt); + void E_P16(const uint8_t *p14,uint8_t *p16); + void E_P24(const uint8_t *p21, const uint8_t *c8, uint8_t *p24); + void D_P16(const uint8_t *p14, const uint8_t *in, uint8_t *out); +diff --git a/libcli/auth/smbdes.c b/libcli/auth/smbdes.c +index 59cb45d81f0..f384ef132a7 100644 +--- a/libcli/auth/smbdes.c ++++ b/libcli/auth/smbdes.c +@@ -23,6 +23,9 @@ + #include "includes.h" + #include "libcli/auth/libcli_auth.h" + ++#include ++#include ++ + /* NOTES: + + This code makes no attempt to be fast! In fact, it is a very +@@ -273,6 +276,60 @@ static void str_to_key(const uint8_t *str,uint8_t *key) + } + } + ++int des_crypt56_gnutls(uint8_t out[8], const uint8_t in[8], ++ const uint8_t key_in[7], ++ enum samba_gnutls_direction encrypt) ++{ ++ /* ++ * A single block DES-CBC op, with an all-zero IV is the same as DES ++ * because the IV is combined with the data using XOR. ++ * This allows us to use GNUTLS_CIPHER_DES_CBC from GnuTLS and not ++ * implement single-DES in Samba. ++ * ++ * In turn this is used to build DES-ECB, which is used ++ * for example in the NTLM challenge/response calculation. ++ */ ++ static const uint8_t iv8[8]; ++ gnutls_datum_t iv = { discard_const(iv8), 8 }; ++ gnutls_datum_t key; ++ gnutls_cipher_hd_t ctx; ++ uint8_t key2[8]; ++ uint8_t outb[8]; ++ int ret; ++ ++ memset(out, 0, 8); ++ ++ str_to_key(key_in, key2); ++ ++ key.data = key2; ++ key.size = 8; ++ ++ ret = gnutls_global_init(); ++ if (ret != 0) { ++ return ret; ++ } ++ ++ ret = gnutls_cipher_init(&ctx, GNUTLS_CIPHER_DES_CBC, &key, &iv); ++ if (ret != 0) { ++ return ret; ++ } ++ ++ memcpy(outb, in, 8); ++ if (encrypt == SAMBA_GNUTLS_ENCRYPT) { ++ ret = gnutls_cipher_encrypt(ctx, outb, 8); ++ } else { ++ ret = gnutls_cipher_decrypt(ctx, outb, 8); ++ } ++ ++ if (ret == 0) { ++ memcpy(out, outb, 8); ++ } ++ ++ gnutls_cipher_deinit(ctx); ++ ++ return ret; ++} ++ + /* + basic des crypt using a 56 bit (7 byte) key + */ +diff --git a/libcli/auth/tests/test_gnutls.c b/libcli/auth/tests/test_gnutls.c +index d9ce8a765cf..121848341e6 100644 +--- a/libcli/auth/tests/test_gnutls.c ++++ b/libcli/auth/tests/test_gnutls.c +@@ -242,12 +242,21 @@ static void torture_gnutls_des_crypt56(void **state) + + uint8_t crypt[8]; + uint8_t decrypt[8]; ++ int rc; + + des_crypt56(crypt, clear, key, 1); + assert_memory_equal(crypt, crypt_expected, 8); + + des_crypt56(decrypt, crypt, key, 0); + assert_memory_equal(decrypt, clear, 8); ++ ++ rc = des_crypt56_gnutls(crypt, clear, key, SAMBA_GNUTLS_ENCRYPT); ++ assert_int_equal(rc, 0); ++ assert_memory_equal(crypt, crypt_expected, 8); ++ ++ rc = des_crypt56_gnutls(decrypt, crypt, key, SAMBA_GNUTLS_DECRYPT); ++ assert_int_equal(rc, 0); ++ assert_memory_equal(decrypt, clear, 8); + } + + static void torture_gnutls_E_P16(void **state) +diff --git a/libcli/auth/wscript_build b/libcli/auth/wscript_build +index 8e856d07ddf..0a3de9a1f7b 100644 +--- a/libcli/auth/wscript_build ++++ b/libcli/auth/wscript_build +@@ -13,7 +13,7 @@ bld.SAMBA_SUBSYSTEM('MSRPC_PARSE', + + bld.SAMBA_SUBSYSTEM('NTLM_CHECK', + source='ntlm_check.c', +- deps = 'talloc' ++ deps = 'talloc LIBCLI_AUTH' + ) + + bld.SAMBA_SUBSYSTEM('LIBCLI_AUTH', +diff --git a/source3/passdb/wscript_build b/source3/passdb/wscript_build +index faa0cc4b495..7facc1fed79 100644 +--- a/source3/passdb/wscript_build ++++ b/source3/passdb/wscript_build +@@ -10,7 +10,7 @@ bld.SAMBA3_MODULE('pdb_tdbsam', + + bld.SAMBA3_MODULE('pdb_ldapsam', + subsystem='pdb', +- deps='smbldap smbldaphelper', ++ deps='smbldap smbldaphelper LIBCLI_AUTH', + source='pdb_ldap.c pdb_nds.c', + init_function='', + internal_module=bld.SAMBA3_IS_STATIC_MODULE('pdb_ldapsam'), +diff --git a/source3/rpc_server/wscript_build b/source3/rpc_server/wscript_build +index 3dec6ee3f5b..357d9c3a29f 100644 +--- a/source3/rpc_server/wscript_build ++++ b/source3/rpc_server/wscript_build +@@ -86,7 +86,8 @@ bld.SAMBA3_SUBSYSTEM('RPC_NETDFS', + + bld.SAMBA3_SUBSYSTEM('RPC_NETLOGON', + source='''netlogon/srv_netlog_nt.c +- ../../librpc/gen_ndr/srv_netlogon.c''') ++ ../../librpc/gen_ndr/srv_netlogon.c''', ++ deps='LIBCLI_AUTH') + + bld.SAMBA3_SUBSYSTEM('RPC_NTSVCS', + source='''ntsvcs/srv_ntsvcs_nt.c +-- +2.23.0 + diff --git a/SOURCES/0175-netlogon_creds_des_encrypt-decrypt_LMKey-use-gnutls-.patch b/SOURCES/0175-netlogon_creds_des_encrypt-decrypt_LMKey-use-gnutls-.patch new file mode 100644 index 0000000..946a937 --- /dev/null +++ b/SOURCES/0175-netlogon_creds_des_encrypt-decrypt_LMKey-use-gnutls-.patch @@ -0,0 +1,103 @@ +From a3d360ba0c46c077643559b4eee9df632080ef1a Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Thu, 7 Nov 2019 12:53:52 +0100 +Subject: [PATCH 175/187] netlogon_creds_des_encrypt/decrypt_LMKey: use gnutls + and return NTSTATUS + +Signed-off-by: Isaac Boukris +Reviewed-by: Andrew Bartlett +(cherry picked from commit 38189f76d8b958fff8a6351f3fb21f6ed04b76da) +--- + libcli/auth/credentials.c | 36 +++++++++++++++++++++++++++--------- + libcli/auth/proto.h | 6 ++++-- + 2 files changed, 31 insertions(+), 11 deletions(-) + +diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c +index f1088a1d8e0..d9237f3875b 100644 +--- a/libcli/auth/credentials.c ++++ b/libcli/auth/credentials.c +@@ -253,25 +253,40 @@ static NTSTATUS netlogon_creds_step(struct netlogon_creds_CredentialState *creds + return NT_STATUS_OK; + } + +- + /* + DES encrypt a 8 byte LMSessionKey buffer using the Netlogon session key + */ +-void netlogon_creds_des_encrypt_LMKey(struct netlogon_creds_CredentialState *creds, struct netr_LMSessionKey *key) ++NTSTATUS netlogon_creds_des_encrypt_LMKey(struct netlogon_creds_CredentialState *creds, ++ struct netr_LMSessionKey *key) + { ++ int rc; + struct netr_LMSessionKey tmp; +- des_crypt56(tmp.key, key->key, creds->session_key, 1); ++ ++ rc = des_crypt56_gnutls(tmp.key, key->key, creds->session_key, SAMBA_GNUTLS_ENCRYPT); ++ if (rc < 0) { ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ } + *key = tmp; ++ ++ return NT_STATUS_OK; + } + + /* + DES decrypt a 8 byte LMSessionKey buffer using the Netlogon session key + */ +-void netlogon_creds_des_decrypt_LMKey(struct netlogon_creds_CredentialState *creds, struct netr_LMSessionKey *key) ++NTSTATUS netlogon_creds_des_decrypt_LMKey(struct netlogon_creds_CredentialState *creds, ++ struct netr_LMSessionKey *key) + { ++ int rc; + struct netr_LMSessionKey tmp; +- des_crypt56(tmp.key, key->key, creds->session_key, 0); ++ ++ rc = des_crypt56_gnutls(tmp.key, key->key, creds->session_key, SAMBA_GNUTLS_DECRYPT); ++ if (rc < 0) { ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ } + *key = tmp; ++ ++ return NT_STATUS_OK; + } + + /* +@@ -849,11 +864,14 @@ static NTSTATUS netlogon_creds_crypt_samlogon_validation(struct netlogon_creds_C + if (!all_zero(base->LMSessKey.key, + sizeof(base->LMSessKey.key))) { + if (do_encrypt) { +- netlogon_creds_des_encrypt_LMKey(creds, +- &base->LMSessKey); ++ status = netlogon_creds_des_encrypt_LMKey(creds, ++ &base->LMSessKey); + } else { +- netlogon_creds_des_decrypt_LMKey(creds, +- &base->LMSessKey); ++ status = netlogon_creds_des_decrypt_LMKey(creds, ++ &base->LMSessKey); ++ } ++ if (!NT_STATUS_IS_OK(status)) { ++ return status; + } + } + } +diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h +index e7c9923abf3..4a817e210b2 100644 +--- a/libcli/auth/proto.h ++++ b/libcli/auth/proto.h +@@ -13,8 +13,10 @@ + + /* The following definitions come from /home/jeremy/src/samba/git/master/source3/../source4/../libcli/auth/credentials.c */ + +-void netlogon_creds_des_encrypt_LMKey(struct netlogon_creds_CredentialState *creds, struct netr_LMSessionKey *key); +-void netlogon_creds_des_decrypt_LMKey(struct netlogon_creds_CredentialState *creds, struct netr_LMSessionKey *key); ++NTSTATUS netlogon_creds_des_encrypt_LMKey(struct netlogon_creds_CredentialState *creds, ++ struct netr_LMSessionKey *key); ++NTSTATUS 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); + NTSTATUS netlogon_creds_arcfour_crypt(struct netlogon_creds_CredentialState *creds, +-- +2.23.0 + diff --git a/SOURCES/0176-SMBsesskeygen_lm_sess_key-use-gnutls-and-return-NTST.patch b/SOURCES/0176-SMBsesskeygen_lm_sess_key-use-gnutls-and-return-NTST.patch new file mode 100644 index 0000000..041d132 --- /dev/null +++ b/SOURCES/0176-SMBsesskeygen_lm_sess_key-use-gnutls-and-return-NTST.patch @@ -0,0 +1,159 @@ +From 404e810a0e3ea7a86c3efad7711f55abec6d2d0c Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Thu, 7 Nov 2019 13:39:20 +0100 +Subject: [PATCH 176/187] SMBsesskeygen_lm_sess_key: use gnutls and return + NTSTATUS + +Signed-off-by: Isaac Boukris +Reviewed-by: Andrew Bartlett +(cherry picked from commit bbcf568f317960229caa7486322858093f5d0d04) +--- + auth/ntlmssp/ntlmssp_client.c | 16 ++++++++++++---- + auth/ntlmssp/ntlmssp_server.c | 15 +++++++++++---- + libcli/auth/proto.h | 6 +++--- + libcli/auth/smbencrypt.c | 15 ++++++++++++--- + libcli/auth/tests/test_gnutls.c | 4 +++- + 5 files changed, 41 insertions(+), 15 deletions(-) + +diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c +index 2a80feb4fed..58e4e3d6f42 100644 +--- a/auth/ntlmssp/ntlmssp_client.c ++++ b/auth/ntlmssp/ntlmssp_client.c +@@ -673,12 +673,20 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, + && ntlmssp_state->allow_lm_key && lm_session_key.length == 16) { + DATA_BLOB new_session_key = data_blob_talloc(mem_ctx, NULL, 16); + if (lm_response.length == 24) { +- SMBsesskeygen_lm_sess_key(lm_session_key.data, lm_response.data, +- new_session_key.data); ++ nt_status = SMBsesskeygen_lm_sess_key(lm_session_key.data, ++ lm_response.data, ++ new_session_key.data); ++ if (!NT_STATUS_IS_OK(nt_status)) { ++ return nt_status; ++ } + } else { + static const uint8_t zeros[24]; +- SMBsesskeygen_lm_sess_key(lm_session_key.data, zeros, +- new_session_key.data); ++ nt_status = SMBsesskeygen_lm_sess_key(lm_session_key.data, ++ zeros, ++ new_session_key.data); ++ if (!NT_STATUS_IS_OK(nt_status)) { ++ return nt_status; ++ } + } + session_key = new_session_key; + dump_data_pw("LM session key\n", session_key.data, session_key.length); +diff --git a/auth/ntlmssp/ntlmssp_server.c b/auth/ntlmssp/ntlmssp_server.c +index 5a56a4db99f..29559b3fe02 100644 +--- a/auth/ntlmssp/ntlmssp_server.c ++++ b/auth/ntlmssp/ntlmssp_server.c +@@ -970,8 +970,12 @@ static NTSTATUS ntlmssp_server_postauth(struct gensec_security *gensec_security, + if (session_key.data == NULL) { + return NT_STATUS_NO_MEMORY; + } +- SMBsesskeygen_lm_sess_key(lm_session_key.data, ntlmssp_state->lm_resp.data, +- session_key.data); ++ nt_status = SMBsesskeygen_lm_sess_key(lm_session_key.data, ++ ntlmssp_state->lm_resp.data, ++ session_key.data); ++ if (!NT_STATUS_IS_OK(nt_status)) { ++ return nt_status; ++ } + DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n")); + } else { + static const uint8_t zeros[24] = {0, }; +@@ -980,8 +984,11 @@ static NTSTATUS ntlmssp_server_postauth(struct gensec_security *gensec_security, + if (session_key.data == NULL) { + return NT_STATUS_NO_MEMORY; + } +- SMBsesskeygen_lm_sess_key(zeros, zeros, +- session_key.data); ++ nt_status = SMBsesskeygen_lm_sess_key(zeros, zeros, ++ session_key.data); ++ if (!NT_STATUS_IS_OK(nt_status)) { ++ return nt_status; ++ } + DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n")); + } + dump_data_pw("LM session key:\n", session_key.data, +diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h +index 4a817e210b2..b7a976c048b 100644 +--- a/libcli/auth/proto.h ++++ b/libcli/auth/proto.h +@@ -140,9 +140,9 @@ NTSTATUS SMBsesskeygen_ntv2(const uint8_t kr[16], + const uint8_t *nt_resp, + uint8_t sess_key[16]); + void SMBsesskeygen_ntv1(const uint8_t kr[16], uint8_t sess_key[16]); +-void SMBsesskeygen_lm_sess_key(const uint8_t lm_hash[16], +- const uint8_t lm_resp[24], /* only uses 8 */ +- uint8_t sess_key[16]); ++NTSTATUS SMBsesskeygen_lm_sess_key(const uint8_t lm_hash[16], ++ const uint8_t lm_resp[24], /* only uses 8 */ ++ uint8_t sess_key[16]); + DATA_BLOB NTLMv2_generate_names_blob(TALLOC_CTX *mem_ctx, + const char *hostname, + const char *domain); +diff --git a/libcli/auth/smbencrypt.c b/libcli/auth/smbencrypt.c +index ab2c47ad9bb..b1d4f985ecf 100644 +--- a/libcli/auth/smbencrypt.c ++++ b/libcli/auth/smbencrypt.c +@@ -380,7 +380,7 @@ void SMBsesskeygen_ntv1(const uint8_t kr[16], uint8_t sess_key[16]) + #endif + } + +-void SMBsesskeygen_lm_sess_key(const uint8_t lm_hash[16], ++NTSTATUS SMBsesskeygen_lm_sess_key(const uint8_t lm_hash[16], + const uint8_t lm_resp[24], /* only uses 8 */ + uint8_t sess_key[16]) + { +@@ -388,12 +388,19 @@ void SMBsesskeygen_lm_sess_key(const uint8_t lm_hash[16], + but changes with each session) */ + uint8_t p24[24]; + uint8_t partial_lm_hash[14]; ++ int rc; + + memcpy(partial_lm_hash, lm_hash, 8); + memset(partial_lm_hash + 8, 0xbd, 6); + +- des_crypt56(p24, lm_resp, partial_lm_hash, 1); +- des_crypt56(p24+8, lm_resp, partial_lm_hash + 7, 1); ++ rc = des_crypt56_gnutls(p24, lm_resp, partial_lm_hash, SAMBA_GNUTLS_ENCRYPT); ++ if (rc < 0) { ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ } ++ rc = des_crypt56_gnutls(p24+8, lm_resp, partial_lm_hash + 7, SAMBA_GNUTLS_ENCRYPT); ++ if (rc < 0) { ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ } + + memcpy(sess_key, p24, 16); + +@@ -401,6 +408,8 @@ void SMBsesskeygen_lm_sess_key(const uint8_t lm_hash[16], + DEBUG(100, ("SMBsesskeygen_lm_sess_key: \n")); + dump_data(100, sess_key, 16); + #endif ++ ++ return NT_STATUS_OK; + } + + DATA_BLOB NTLMv2_generate_names_blob(TALLOC_CTX *mem_ctx, +diff --git a/libcli/auth/tests/test_gnutls.c b/libcli/auth/tests/test_gnutls.c +index 121848341e6..5bb75c2bab2 100644 +--- a/libcli/auth/tests/test_gnutls.c ++++ b/libcli/auth/tests/test_gnutls.c +@@ -447,8 +447,10 @@ static void torture_gnutls_SMBsesskeygen_lm_sess_key(void **state) + }; + + uint8_t crypt_sess_key[16]; ++ NTSTATUS status; + +- SMBsesskeygen_lm_sess_key(lm_hash, lm_resp, crypt_sess_key); ++ status = SMBsesskeygen_lm_sess_key(lm_hash, lm_resp, crypt_sess_key); ++ assert_true(NT_STATUS_IS_OK(status)); + assert_memory_equal(crypt_sess_key, crypt_expected, 16); + } + +-- +2.23.0 + diff --git a/SOURCES/0177-smbdes-convert-sam_rid_crypt-to-use-gnutls.patch b/SOURCES/0177-smbdes-convert-sam_rid_crypt-to-use-gnutls.patch new file mode 100644 index 0000000..c3c1011 --- /dev/null +++ b/SOURCES/0177-smbdes-convert-sam_rid_crypt-to-use-gnutls.patch @@ -0,0 +1,197 @@ +From 4b4197975987be299535e6c78958c81ae2c63334 Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Thu, 7 Nov 2019 18:40:03 +0100 +Subject: [PATCH 177/187] smbdes: convert sam_rid_crypt() to use gnutls + +Signed-off-by: Isaac Boukris +Reviewed-by: Andrew Bartlett +(cherry picked from commit ecee1998034b84026ab604dbe4400d9e53dcafd4) +--- + libcli/auth/proto.h | 3 ++- + libcli/auth/smbdes.c | 11 +++++++--- + libcli/auth/tests/test_gnutls.c | 7 +++++-- + libcli/drsuapi/repl_decrypt.c | 16 +++++++++++++-- + libcli/samsync/decrypt.c | 36 +++++++++++++++++++++++++-------- + 5 files changed, 57 insertions(+), 16 deletions(-) + +diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h +index b7a976c048b..7dad549fc43 100644 +--- a/libcli/auth/proto.h ++++ b/libcli/auth/proto.h +@@ -230,7 +230,8 @@ 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); + void des_crypt112_16(uint8_t out[16], const uint8_t in[16], const uint8_t key[14], int forw); +-void sam_rid_crypt(unsigned int rid, const uint8_t *in, uint8_t *out, int forw); ++int sam_rid_crypt(unsigned int rid, const uint8_t *in, uint8_t *out, ++ enum samba_gnutls_direction encrypt); + #undef _PRINTF_ATTRIBUTE + #define _PRINTF_ATTRIBUTE(a1, a2) + +diff --git a/libcli/auth/smbdes.c b/libcli/auth/smbdes.c +index f384ef132a7..fe397592fbb 100644 +--- a/libcli/auth/smbdes.c ++++ b/libcli/auth/smbdes.c +@@ -418,15 +418,20 @@ void des_crypt112_16(uint8_t out[16], const uint8_t in[16], const uint8_t key[14 + /* Decode a sam password hash into a password. The password hash is the + same method used to store passwords in the NT registry. The DES key + used is based on the RID of the user. */ +-void sam_rid_crypt(unsigned int rid, const uint8_t *in, uint8_t *out, int forw) ++int sam_rid_crypt(unsigned int rid, const uint8_t *in, uint8_t *out, ++ enum samba_gnutls_direction encrypt) + { + uint8_t s[14]; ++ int ret; + + s[0] = s[4] = s[8] = s[12] = (uint8_t)(rid & 0xFF); + s[1] = s[5] = s[9] = s[13] = (uint8_t)((rid >> 8) & 0xFF); + s[2] = s[6] = s[10] = (uint8_t)((rid >> 16) & 0xFF); + s[3] = s[7] = s[11] = (uint8_t)((rid >> 24) & 0xFF); + +- des_crypt56(out, in, s, forw); +- des_crypt56(out+8, in+8, s+7, forw); ++ ret = des_crypt56_gnutls(out, in, s, encrypt); ++ if (ret != 0) { ++ return ret; ++ } ++ return des_crypt56_gnutls(out+8, in+8, s+7, encrypt); + } +diff --git a/libcli/auth/tests/test_gnutls.c b/libcli/auth/tests/test_gnutls.c +index 5bb75c2bab2..f603fa819e8 100644 +--- a/libcli/auth/tests/test_gnutls.c ++++ b/libcli/auth/tests/test_gnutls.c +@@ -422,11 +422,14 @@ static void torture_gnutls_sam_rid_crypt(void **state) + uint8_t crypt[16]; + uint8_t decrypt[16]; + int rid = 500; ++ int rc; + +- sam_rid_crypt(rid, clear, crypt, 1); ++ rc = sam_rid_crypt(rid, clear, crypt, SAMBA_GNUTLS_ENCRYPT); ++ assert_int_equal(rc, 0); + assert_memory_equal(crypt, crypt_expected, 16); + +- sam_rid_crypt(rid, crypt, decrypt, 0); ++ rc = sam_rid_crypt(rid, crypt, decrypt, SAMBA_GNUTLS_DECRYPT); ++ assert_int_equal(rc, 0); + assert_memory_equal(decrypt, clear, 16); + } + +diff --git a/libcli/drsuapi/repl_decrypt.c b/libcli/drsuapi/repl_decrypt.c +index 83275360c7d..30b3c64379f 100644 +--- a/libcli/drsuapi/repl_decrypt.c ++++ b/libcli/drsuapi/repl_decrypt.c +@@ -135,7 +135,13 @@ static WERROR drsuapi_decrypt_attribute_value(TALLOC_CTX *mem_ctx, + num_hashes = plain_buffer.length / 16; + for (i = 0; i < num_hashes; i++) { + uint32_t offset = i * 16; +- sam_rid_crypt(rid, checked_buffer.data + offset, plain_buffer.data + offset, 0); ++ rc = sam_rid_crypt(rid, checked_buffer.data + offset, ++ plain_buffer.data + offset, ++ SAMBA_GNUTLS_DECRYPT); ++ if (rc != 0) { ++ result = gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR); ++ goto out; ++ } + } + } + +@@ -255,7 +261,13 @@ static WERROR drsuapi_encrypt_attribute_value(TALLOC_CTX *mem_ctx, + num_hashes = rid_crypt_out.length / 16; + for (i = 0; i < num_hashes; i++) { + uint32_t offset = i * 16; +- sam_rid_crypt(rid, in->data + offset, rid_crypt_out.data + offset, 1); ++ rc = sam_rid_crypt(rid, in->data + offset, ++ rid_crypt_out.data + offset, ++ SAMBA_GNUTLS_ENCRYPT); ++ if (rc != 0) { ++ result = gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR); ++ goto out; ++ } + } + in = &rid_crypt_out; + } +diff --git a/libcli/samsync/decrypt.c b/libcli/samsync/decrypt.c +index 5cda966fb42..77ef93251bc 100644 +--- a/libcli/samsync/decrypt.c ++++ b/libcli/samsync/decrypt.c +@@ -25,6 +25,7 @@ + #include "../libcli/auth/libcli_auth.h" + #include "../libcli/samsync/samsync.h" + #include "librpc/gen_ndr/ndr_netlogon.h" ++#include "lib/crypto/gnutls_helpers.h" + + /** + * Decrypt and extract the user's passwords. +@@ -43,13 +44,19 @@ static NTSTATUS fix_user(TALLOC_CTX *mem_ctx, + struct netr_DELTA_USER *user = delta->delta_union.user; + struct samr_Password lm_hash; + struct samr_Password nt_hash; ++ int rc; + + /* Note that win2000 may send us all zeros + * for the hashes if it doesn't + * think this channel is secure enough. */ + if (user->lm_password_present) { + if (!all_zero(user->lmpassword.hash, 16)) { +- sam_rid_crypt(rid, user->lmpassword.hash, lm_hash.hash, 0); ++ rc = sam_rid_crypt(rid, user->lmpassword.hash, ++ lm_hash.hash, SAMBA_GNUTLS_DECRYPT); ++ if (rc != 0) { ++ return gnutls_error_to_ntstatus(rc, ++ NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ } + } else { + memset(lm_hash.hash, '\0', sizeof(lm_hash.hash)); + } +@@ -58,7 +65,12 @@ static NTSTATUS fix_user(TALLOC_CTX *mem_ctx, + + if (user->nt_password_present) { + if (!all_zero(user->ntpassword.hash, 16)) { +- sam_rid_crypt(rid, user->ntpassword.hash, nt_hash.hash, 0); ++ rc = sam_rid_crypt(rid, user->ntpassword.hash, ++ nt_hash.hash, SAMBA_GNUTLS_DECRYPT); ++ if (rc != 0) { ++ return gnutls_error_to_ntstatus(rc, ++ NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ } + } else { + memset(nt_hash.hash, '\0', sizeof(nt_hash.hash)); + } +@@ -97,9 +109,13 @@ static NTSTATUS fix_user(TALLOC_CTX *mem_ctx, + if (keys.keys.keys2.lmpassword.length == 16) { + if (!all_zero(keys.keys.keys2.lmpassword.pwd.hash, + 16)) { +- sam_rid_crypt(rid, +- keys.keys.keys2.lmpassword.pwd.hash, +- lm_hash.hash, 0); ++ rc = sam_rid_crypt(rid, ++ keys.keys.keys2.lmpassword.pwd.hash, ++ lm_hash.hash, SAMBA_GNUTLS_DECRYPT); ++ if (rc != 0) { ++ return gnutls_error_to_ntstatus(rc, ++ NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ } + } else { + memset(lm_hash.hash, '\0', sizeof(lm_hash.hash)); + } +@@ -109,9 +125,13 @@ static NTSTATUS fix_user(TALLOC_CTX *mem_ctx, + if (keys.keys.keys2.ntpassword.length == 16) { + if (!all_zero(keys.keys.keys2.ntpassword.pwd.hash, + 16)) { +- sam_rid_crypt(rid, +- keys.keys.keys2.ntpassword.pwd.hash, +- nt_hash.hash, 0); ++ rc = sam_rid_crypt(rid, ++ keys.keys.keys2.ntpassword.pwd.hash, ++ nt_hash.hash, SAMBA_GNUTLS_DECRYPT); ++ if (rc != 0) { ++ return gnutls_error_to_ntstatus(rc, ++ NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ } + } else { + memset(nt_hash.hash, '\0', sizeof(nt_hash.hash)); + } +-- +2.23.0 + diff --git a/SOURCES/0178-smbdes-convert-E_P16-to-use-gnutls.patch b/SOURCES/0178-smbdes-convert-E_P16-to-use-gnutls.patch new file mode 100644 index 0000000..7592cb8 --- /dev/null +++ b/SOURCES/0178-smbdes-convert-E_P16-to-use-gnutls.patch @@ -0,0 +1,96 @@ +From 8fbf828c6b2e22f3ce56d7214156c75c73147e0c Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Thu, 7 Nov 2019 16:16:26 +0100 +Subject: [PATCH 178/187] smbdes: convert E_P16() to use gnutls + +Signed-off-by: Isaac Boukris +Reviewed-by: Andrew Bartlett +(cherry picked from commit 9fb6361a8b09fd575bab2f5572fa9e10bd538eed) +--- + libcli/auth/proto.h | 2 +- + libcli/auth/smbdes.c | 12 +++++++++--- + libcli/auth/smbencrypt.c | 6 +++++- + libcli/auth/tests/test_gnutls.c | 5 ++++- + 4 files changed, 19 insertions(+), 6 deletions(-) + +diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h +index 7dad549fc43..9ae62efca31 100644 +--- a/libcli/auth/proto.h ++++ b/libcli/auth/proto.h +@@ -223,7 +223,7 @@ WERROR decode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, + void des_crypt56(uint8_t out[8], const uint8_t in[8], const uint8_t key[7], int forw); + int des_crypt56_gnutls(uint8_t out[8], const uint8_t in[8], const uint8_t key[7], + enum samba_gnutls_direction encrypt); +-void E_P16(const uint8_t *p14,uint8_t *p16); ++int E_P16(const uint8_t *p14,uint8_t *p16); + void E_P24(const uint8_t *p21, const uint8_t *c8, uint8_t *p24); + void D_P16(const uint8_t *p14, const uint8_t *in, uint8_t *out); + void E_old_pw_hash( uint8_t *p14, const uint8_t *in, uint8_t *out); +diff --git a/libcli/auth/smbdes.c b/libcli/auth/smbdes.c +index fe397592fbb..c0d10278179 100644 +--- a/libcli/auth/smbdes.c ++++ b/libcli/auth/smbdes.c +@@ -361,11 +361,17 @@ void des_crypt56(uint8_t out[8], const uint8_t in[8], const uint8_t key[7], int + } + } + +-void E_P16(const uint8_t *p14,uint8_t *p16) ++int E_P16(const uint8_t *p14,uint8_t *p16) + { + const uint8_t sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25}; +- des_crypt56(p16, sp8, p14, 1); +- des_crypt56(p16+8, sp8, p14+7, 1); ++ int ret; ++ ++ ret = des_crypt56_gnutls(p16, sp8, p14, SAMBA_GNUTLS_ENCRYPT); ++ if (ret != 0) { ++ return ret; ++ } ++ ++ 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) +diff --git a/libcli/auth/smbencrypt.c b/libcli/auth/smbencrypt.c +index b1d4f985ecf..f2f446eda97 100644 +--- a/libcli/auth/smbencrypt.c ++++ b/libcli/auth/smbencrypt.c +@@ -105,6 +105,7 @@ bool E_md4hash(const char *passwd, uint8_t p16[16]) + bool E_deshash(const char *passwd, uint8_t p16[16]) + { + bool ret; ++ int rc; + uint8_t dospwd[14]; + TALLOC_CTX *frame = talloc_stackframe(); + +@@ -133,7 +134,10 @@ bool E_deshash(const char *passwd, uint8_t p16[16]) + * case to avoid returning a fixed 'password' buffer, but + * callers should not use it when E_deshash returns false */ + +- E_P16((const uint8_t *)dospwd, p16); ++ rc = E_P16((const uint8_t *)dospwd, p16); ++ if (rc != 0) { ++ ret = false; ++ } + + ZERO_STRUCT(dospwd); + +diff --git a/libcli/auth/tests/test_gnutls.c b/libcli/auth/tests/test_gnutls.c +index f603fa819e8..a6e8fd5b352 100644 +--- a/libcli/auth/tests/test_gnutls.c ++++ b/libcli/auth/tests/test_gnutls.c +@@ -274,7 +274,10 @@ static void torture_gnutls_E_P16(void **state) + 0x1D, 0xEA, 0xD9, 0xFF, 0xB0, 0xA9, 0xA4, 0x05 + }; + +- E_P16(key, buffer); ++ int rc; ++ ++ rc = E_P16(key, buffer); ++ assert_int_equal(rc, 0); + assert_memory_equal(buffer, crypt_expected, 16); + } + +-- +2.23.0 + diff --git a/SOURCES/0179-smbdes-remove-D_P16-not-used.patch b/SOURCES/0179-smbdes-remove-D_P16-not-used.patch new file mode 100644 index 0000000..06e777a --- /dev/null +++ b/SOURCES/0179-smbdes-remove-D_P16-not-used.patch @@ -0,0 +1,45 @@ +From 4f4e9952664e23b5aea4816ac2fda311415719de Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Fri, 8 Nov 2019 12:04:48 +0100 +Subject: [PATCH 179/187] smbdes: remove D_P16() (not used) + +Signed-off-by: Isaac Boukris +Reviewed-by: Andrew Bartlett +(cherry picked from commit 2eef12904f2c08257394a2ee869960f7c2e09112) +--- + libcli/auth/proto.h | 1 - + libcli/auth/smbdes.c | 6 ------ + 2 files changed, 7 deletions(-) + +diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h +index 9ae62efca31..212b46bb0e8 100644 +--- a/libcli/auth/proto.h ++++ b/libcli/auth/proto.h +@@ -225,7 +225,6 @@ 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); +-void D_P16(const uint8_t *p14, const uint8_t *in, uint8_t *out); + 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 c0d10278179..46fd5849f5b 100644 +--- a/libcli/auth/smbdes.c ++++ b/libcli/auth/smbdes.c +@@ -381,12 +381,6 @@ void E_P24(const uint8_t *p21, const uint8_t *c8, uint8_t *p24) + des_crypt56(p24+16, c8, p21+14, 1); + } + +-void D_P16(const uint8_t *p14, const uint8_t *in, uint8_t *out) +-{ +- des_crypt56(out, in, p14, 0); +- des_crypt56(out+8, in+8, p14+7, 0); +-} +- + void E_old_pw_hash( uint8_t *p14, const uint8_t *in, uint8_t *out) + { + des_crypt56(out, in, p14, 1); +-- +2.23.0 + diff --git a/SOURCES/0180-smbdes-convert-E_P24-and-SMBOWFencrypt-to-use-gnutls.patch b/SOURCES/0180-smbdes-convert-E_P24-and-SMBOWFencrypt-to-use-gnutls.patch new file mode 100644 index 0000000..0133983 --- /dev/null +++ b/SOURCES/0180-smbdes-convert-E_P24-and-SMBOWFencrypt-to-use-gnutls.patch @@ -0,0 +1,519 @@ +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 + diff --git a/SOURCES/0181-smbdes-convert-des_crypt128-to-use-gnutls.patch b/SOURCES/0181-smbdes-convert-des_crypt128-to-use-gnutls.patch new file mode 100644 index 0000000..e06089a --- /dev/null +++ b/SOURCES/0181-smbdes-convert-des_crypt128-to-use-gnutls.patch @@ -0,0 +1,96 @@ +From 20bd9ca871f318ba8360525b51f56010f8607fbb Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Fri, 8 Nov 2019 17:49:48 +0100 +Subject: [PATCH 181/187] smbdes: convert des_crypt128() to use gnutls + +Signed-off-by: Isaac Boukris +Reviewed-by: Andrew Bartlett +(cherry picked from commit c57f429574243adbcd43dca4f35d125df8d69ba0) +--- + libcli/auth/credentials.c | 6 +++++- + libcli/auth/proto.h | 2 +- + libcli/auth/smbdes.c | 12 +++++++++--- + libcli/auth/tests/test_gnutls.c | 4 +++- + 4 files changed, 18 insertions(+), 6 deletions(-) + +diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c +index d9237f3875b..1b94a06ebfb 100644 +--- a/libcli/auth/credentials.c ++++ b/libcli/auth/credentials.c +@@ -66,6 +66,7 @@ static NTSTATUS netlogon_creds_init_64bit(struct netlogon_creds_CredentialState + { + uint32_t sum[2]; + uint8_t sum2[8]; ++ int rc; + + sum[0] = IVAL(client_challenge->data, 0) + IVAL(server_challenge->data, 0); + sum[1] = IVAL(client_challenge->data, 4) + IVAL(server_challenge->data, 4); +@@ -75,7 +76,10 @@ static NTSTATUS netlogon_creds_init_64bit(struct netlogon_creds_CredentialState + + ZERO_ARRAY(creds->session_key); + +- des_crypt128(creds->session_key, sum2, machine_password->hash); ++ rc = des_crypt128(creds->session_key, sum2, machine_password->hash); ++ if (rc != 0) { ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ } + + return NT_STATUS_OK; + } +diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h +index 5209d6766e4..2ea4eca822a 100644 +--- a/libcli/auth/proto.h ++++ b/libcli/auth/proto.h +@@ -226,7 +226,7 @@ int des_crypt56_gnutls(uint8_t out[8], const uint8_t in[8], const uint8_t key[7] + int E_P16(const uint8_t *p14,uint8_t *p16); + 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]); ++int 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); + void des_crypt112_16(uint8_t out[16], const uint8_t in[16], const uint8_t key[14], int forw); + int sam_rid_crypt(unsigned int rid, const uint8_t *in, uint8_t *out, +diff --git a/libcli/auth/smbdes.c b/libcli/auth/smbdes.c +index 4e3499f9d26..6a4f4d1d42a 100644 +--- a/libcli/auth/smbdes.c ++++ b/libcli/auth/smbdes.c +@@ -398,11 +398,17 @@ void E_old_pw_hash( uint8_t *p14, const uint8_t *in, uint8_t *out) + } + + /* des encryption with a 128 bit key */ +-void des_crypt128(uint8_t out[8], const uint8_t in[8], const uint8_t key[16]) ++int des_crypt128(uint8_t out[8], const uint8_t in[8], const uint8_t key[16]) + { + uint8_t buf[8]; +- des_crypt56(buf, in, key, 1); +- des_crypt56(out, buf, key+9, 1); ++ int ret; ++ ++ ret = des_crypt56_gnutls(buf, in, key, SAMBA_GNUTLS_ENCRYPT); ++ if (ret != 0) { ++ return ret; ++ } ++ ++ return des_crypt56_gnutls(out, buf, key+9, SAMBA_GNUTLS_ENCRYPT); + } + + /* des encryption with a 112 bit (14 byte) key */ +diff --git a/libcli/auth/tests/test_gnutls.c b/libcli/auth/tests/test_gnutls.c +index 9fafe2a767b..d9acfb67075 100644 +--- a/libcli/auth/tests/test_gnutls.c ++++ b/libcli/auth/tests/test_gnutls.c +@@ -362,8 +362,10 @@ static void torture_gnutls_des_crypt128(void **state) + }; + + uint8_t crypt[8]; ++ int rc; + +- des_crypt128(crypt, clear, key); ++ rc = des_crypt128(crypt, clear, key); ++ assert_int_equal(rc, 0); + assert_memory_equal(crypt, crypt_expected, 8); + } + +-- +2.23.0 + diff --git a/SOURCES/0182-smbdes-convert-E_old_pw_hash-to-use-gnutls.patch b/SOURCES/0182-smbdes-convert-E_old_pw_hash-to-use-gnutls.patch new file mode 100644 index 0000000..eabcd8d --- /dev/null +++ b/SOURCES/0182-smbdes-convert-E_old_pw_hash-to-use-gnutls.patch @@ -0,0 +1,427 @@ +From 6e0fa4cf34ffb9a3f453269f8bd19b4aaf4be030 Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Wed, 20 Nov 2019 15:28:39 +0100 +Subject: [PATCH 182/187] smbdes: convert E_old_pw_hash to use gnutls + +Signed-off-by: Isaac Boukris +Reviewed-by: Andrew Bartlett +(cherry picked from commit dce944e8a1119034f184336f6b71a28080152a0a) +--- + libcli/auth/proto.h | 2 +- + libcli/auth/smbdes.c | 12 +++- + libcli/auth/tests/test_gnutls.c | 4 +- + source3/libsmb/clirap.c | 6 +- + source3/rpc_client/cli_samr.c | 66 +++++++++++++++++--- + source3/rpc_server/samr/srv_samr_chgpasswd.c | 18 +++++- + source3/utils/ntlm_auth.c | 14 ++++- + source4/libnet/libnet_passwd.c | 30 +++++++-- + source4/rpc_server/samr/samr_password.c | 16 ++++- + 9 files changed, 140 insertions(+), 28 deletions(-) + +diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h +index 2ea4eca822a..5e88d7527fd 100644 +--- a/libcli/auth/proto.h ++++ b/libcli/auth/proto.h +@@ -225,7 +225,7 @@ 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); + 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); ++int E_old_pw_hash( uint8_t *p14, const uint8_t *in, uint8_t *out); + int 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); + void des_crypt112_16(uint8_t out[16], const uint8_t in[16], const uint8_t key[14], int forw); +diff --git a/libcli/auth/smbdes.c b/libcli/auth/smbdes.c +index 6a4f4d1d42a..ec922da4727 100644 +--- a/libcli/auth/smbdes.c ++++ b/libcli/auth/smbdes.c +@@ -391,10 +391,16 @@ int E_P24(const uint8_t *p21, const uint8_t *c8, uint8_t *p24) + 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) ++int E_old_pw_hash( uint8_t *p14, const uint8_t *in, uint8_t *out) + { +- des_crypt56(out, in, p14, 1); +- des_crypt56(out+8, in+8, p14+7, 1); ++ int ret; ++ ++ ret = des_crypt56_gnutls(out, in, p14, SAMBA_GNUTLS_ENCRYPT); ++ if (ret != 0) { ++ return ret; ++ } ++ ++ return des_crypt56_gnutls(out+8, in+8, p14+7, SAMBA_GNUTLS_ENCRYPT); + } + + /* des encryption with a 128 bit key */ +diff --git a/libcli/auth/tests/test_gnutls.c b/libcli/auth/tests/test_gnutls.c +index d9acfb67075..087afee09db 100644 +--- a/libcli/auth/tests/test_gnutls.c ++++ b/libcli/auth/tests/test_gnutls.c +@@ -343,8 +343,10 @@ static void torture_gnutls_E_old_pw_hash(void **state) + 0x37, 0xEF, 0xBE, 0x58, 0xC2, 0x59, 0x33, 0xEC + }; + uint8_t crypt[16]; ++ int rc; + +- E_old_pw_hash(key, clear, crypt); ++ rc = E_old_pw_hash(key, clear, crypt); ++ assert_int_equal(rc, 0); + assert_memory_equal(crypt, crypt_expected, 16); + } + +diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c +index c0b9dcdff39..bf2a9ed4fdc 100644 +--- a/source3/libsmb/clirap.c ++++ b/source3/libsmb/clirap.c +@@ -569,7 +569,11 @@ bool cli_oem_change_password(struct cli_state *cli, const char *user, const char + */ + E_deshash(new_password, new_pw_hash); + +- E_old_pw_hash( new_pw_hash, old_pw_hash, (uchar *)&data[516]); ++ rc = E_old_pw_hash( new_pw_hash, old_pw_hash, (uchar *)&data[516]); ++ if (rc != 0) { ++ DBG_ERR("E_old_pw_hash failed: %s\n", gnutls_strerror(rc)); ++ return false; ++ } + + data_len = 532; + +diff --git a/source3/rpc_client/cli_samr.c b/source3/rpc_client/cli_samr.c +index 452e9593f6a..8a151c751f5 100644 +--- a/source3/rpc_client/cli_samr.c ++++ b/source3/rpc_client/cli_samr.c +@@ -39,6 +39,7 @@ NTSTATUS dcerpc_samr_chgpasswd_user(struct dcerpc_binding_handle *h, + NTSTATUS *presult) + { + NTSTATUS status; ++ int rc; + struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6; + + uint8_t old_nt_hash[16] = {0}; +@@ -54,12 +55,36 @@ NTSTATUS dcerpc_samr_chgpasswd_user(struct dcerpc_binding_handle *h, + E_deshash(oldpassword, old_lm_hash); + E_deshash(newpassword, new_lm_hash); + +- E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash); +- E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash); +- E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash); +- E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash); +- E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash); +- E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash); ++ rc = E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash); ++ if (rc != 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ goto done; ++ } ++ rc = E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash); ++ if (rc != 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ goto done; ++ } ++ rc = E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash); ++ if (rc != 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ goto done; ++ } ++ rc = E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash); ++ if (rc != 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ goto done; ++ } ++ rc = E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash); ++ if (rc != 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ goto done; ++ } ++ rc = E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash); ++ if (rc != 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ goto done; ++ } + + status = dcerpc_samr_ChangePasswordUser(h, + mem_ctx, +@@ -76,6 +101,7 @@ NTSTATUS dcerpc_samr_chgpasswd_user(struct dcerpc_binding_handle *h, + &hash6, + presult); + ++done: + ZERO_ARRAY(old_nt_hash); + ZERO_ARRAY(old_lm_hash); + ZERO_ARRAY(new_nt_hash); +@@ -117,6 +143,7 @@ NTSTATUS dcerpc_samr_chgpasswd_user2(struct dcerpc_binding_handle *h, + NTSTATUS *presult) + { + NTSTATUS status; ++ int rc; + struct samr_CryptPassword new_nt_password; + struct samr_CryptPassword new_lm_password; + struct samr_Password old_nt_hash_enc; +@@ -153,7 +180,11 @@ NTSTATUS dcerpc_samr_chgpasswd_user2(struct dcerpc_binding_handle *h, + return status; + } + +- E_old_pw_hash(new_nt_hash, old_lanman_hash, old_lanman_hash_enc.hash); ++ rc = E_old_pw_hash(new_nt_hash, old_lanman_hash, old_lanman_hash_enc.hash); ++ if (rc != 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ goto done; ++ } + } else { + ZERO_STRUCT(new_lm_password); + ZERO_STRUCT(old_lanman_hash_enc); +@@ -165,7 +196,11 @@ NTSTATUS dcerpc_samr_chgpasswd_user2(struct dcerpc_binding_handle *h, + if (!NT_STATUS_IS_OK(status)) { + return status; + } +- E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash); ++ rc = E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash); ++ if (rc != 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ goto done; ++ } + + status = dcerpc_samr_ChangePasswordUser2(h, + mem_ctx, +@@ -178,6 +213,7 @@ NTSTATUS dcerpc_samr_chgpasswd_user2(struct dcerpc_binding_handle *h, + &old_lanman_hash_enc, + presult); + ++done: + ZERO_STRUCT(new_nt_password); + ZERO_STRUCT(new_lm_password); + ZERO_STRUCT(old_nt_hash_enc); +@@ -312,6 +348,7 @@ NTSTATUS dcerpc_samr_chgpasswd_user3(struct dcerpc_binding_handle *h, + NTSTATUS *presult) + { + NTSTATUS status; ++ int rc; + + struct samr_CryptPassword new_nt_password; + struct samr_CryptPassword new_lm_password; +@@ -350,7 +387,11 @@ NTSTATUS dcerpc_samr_chgpasswd_user3(struct dcerpc_binding_handle *h, + return status; + } + +- E_old_pw_hash(new_nt_hash, old_lanman_hash, old_lanman_hash_enc.hash); ++ rc = E_old_pw_hash(new_nt_hash, old_lanman_hash, old_lanman_hash_enc.hash); ++ if (rc != 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ goto done; ++ } + } else { + ZERO_STRUCT(new_lm_password); + ZERO_STRUCT(old_lanman_hash_enc); +@@ -363,7 +404,11 @@ NTSTATUS dcerpc_samr_chgpasswd_user3(struct dcerpc_binding_handle *h, + return status; + } + +- E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash); ++ rc = E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash); ++ if (rc != 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ goto done; ++ } + + status = dcerpc_samr_ChangePasswordUser3(h, + mem_ctx, +@@ -379,6 +424,7 @@ NTSTATUS dcerpc_samr_chgpasswd_user3(struct dcerpc_binding_handle *h, + reject, + presult); + ++done: + ZERO_STRUCT(new_nt_password); + ZERO_STRUCT(new_lm_password); + ZERO_STRUCT(old_nt_hash_enc); +diff --git a/source3/rpc_server/samr/srv_samr_chgpasswd.c b/source3/rpc_server/samr/srv_samr_chgpasswd.c +index 8c9cf73bdd8..79d4b3068e5 100644 +--- a/source3/rpc_server/samr/srv_samr_chgpasswd.c ++++ b/source3/rpc_server/samr/srv_samr_chgpasswd.c +@@ -804,7 +804,11 @@ static NTSTATUS check_oem_password(const char *user, + /* + * check the NT verifier + */ +- E_old_pw_hash(new_nt_hash, nt_pw, verifier); ++ rc = E_old_pw_hash(new_nt_hash, nt_pw, verifier); ++ if (rc != 0) { ++ NTSTATUS status = NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER; ++ return gnutls_error_to_ntstatus(rc, status); ++ } + if (memcmp(verifier, old_nt_hash_encrypted, 16)) { + DEBUG(0, ("check_oem_password: old nt " + "password doesn't match.\n")); +@@ -831,7 +835,11 @@ static NTSTATUS check_oem_password(const char *user, + /* + * check the lm verifier + */ +- E_old_pw_hash(new_nt_hash, lanman_pw, verifier); ++ rc = E_old_pw_hash(new_nt_hash, lanman_pw, verifier); ++ if (rc != 0) { ++ NTSTATUS status = NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER; ++ return gnutls_error_to_ntstatus(rc, status); ++ } + if (memcmp(verifier, old_lm_hash_encrypted, 16)) { + DEBUG(0,("check_oem_password: old lm password doesn't match.\n")); + return NT_STATUS_WRONG_PASSWORD; +@@ -851,7 +859,11 @@ static NTSTATUS check_oem_password(const char *user, + /* + * check the lm verifier + */ +- E_old_pw_hash(new_lm_hash, lanman_pw, verifier); ++ rc = E_old_pw_hash(new_lm_hash, lanman_pw, verifier); ++ if (rc != 0) { ++ NTSTATUS status = NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER; ++ return gnutls_error_to_ntstatus(rc, status); ++ } + if (memcmp(verifier, old_lm_hash_encrypted, 16)) { + DEBUG(0,("check_oem_password: old lm password doesn't match.\n")); + return NT_STATUS_WRONG_PASSWORD; +diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c +index 8a6218ac9ec..22258b3b84c 100644 +--- a/source3/utils/ntlm_auth.c ++++ b/source3/utils/ntlm_auth.c +@@ -1993,8 +1993,13 @@ static void manage_ntlm_change_password_1_request(enum stdio_helper_mode stdio_h + gnutls_cipher_deinit(cipher_hnd); + return; + } +- E_old_pw_hash(new_nt_hash, old_lm_hash, ++ rc = E_old_pw_hash(new_nt_hash, old_lm_hash, + old_lm_hash_enc.data); ++ if (rc != 0) { ++ DBG_ERR("E_old_pw_hash failed: %s\n", ++ gnutls_strerror(rc)); ++ return; ++ } + } else { + new_lm_pswd.data = NULL; + new_lm_pswd.length = 0; +@@ -2012,8 +2017,13 @@ static void manage_ntlm_change_password_1_request(enum stdio_helper_mode stdio_h + if (rc < 0) { + return; + } +- E_old_pw_hash(new_nt_hash, old_nt_hash, ++ rc = E_old_pw_hash(new_nt_hash, old_nt_hash, + old_nt_hash_enc.data); ++ if (rc != 0) { ++ DBG_ERR("E_old_pw_hash failed: %s\n", ++ gnutls_strerror(rc)); ++ return; ++ } + + ZERO_ARRAY(old_nt_hash); + ZERO_ARRAY(old_lm_hash); +diff --git a/source4/libnet/libnet_passwd.c b/source4/libnet/libnet_passwd.c +index 704a94a5864..868f9442cd0 100644 +--- a/source4/libnet/libnet_passwd.c ++++ b/source4/libnet/libnet_passwd.c +@@ -115,7 +115,11 @@ static NTSTATUS libnet_ChangePassword_samr(struct libnet_context *ctx, TALLOC_CT + goto disconnect; + } + +- E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash); ++ rc = E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash); ++ if (rc != 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ goto disconnect; ++ } + + encode_pw_buffer(nt_pass.data, r->samr.in.newpassword, STR_UNICODE); + +@@ -137,7 +141,11 @@ static NTSTATUS libnet_ChangePassword_samr(struct libnet_context *ctx, TALLOC_CT + goto disconnect; + } + +- E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash); ++ rc = E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash); ++ if (rc != 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ goto disconnect; ++ } + + pw3.in.server = &server; + pw3.in.account = &account; +@@ -189,7 +197,11 @@ static NTSTATUS libnet_ChangePassword_samr(struct libnet_context *ctx, TALLOC_CT + goto disconnect; + } + +- E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash); ++ rc = E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash); ++ if (rc != 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ goto disconnect; ++ } + + encode_pw_buffer(nt_pass.data, r->samr.in.newpassword, STR_UNICODE); + +@@ -210,7 +222,11 @@ static NTSTATUS libnet_ChangePassword_samr(struct libnet_context *ctx, TALLOC_CT + goto disconnect; + } + +- E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash); ++ rc = E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash); ++ if (rc != 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ goto disconnect; ++ } + + pw2.in.server = &server; + pw2.in.account = &account; +@@ -260,7 +276,11 @@ static NTSTATUS libnet_ChangePassword_samr(struct libnet_context *ctx, TALLOC_CT + goto disconnect; + } + +- E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash); ++ rc = E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash); ++ if (rc != 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ goto disconnect; ++ } + + oe2.in.server = &a_server; + oe2.in.account = &a_account; +diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c +index b04e37f06f3..4fa00bf6360 100644 +--- a/source4/rpc_server/samr/samr_password.c ++++ b/source4/rpc_server/samr/samr_password.c +@@ -235,7 +235,11 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call, + new_unicode_password.length = unicode_pw_len; + + E_deshash(new_pass, new_lm_hash); +- E_old_pw_hash(new_lm_hash, lm_pwd->hash, lm_verifier.hash); ++ rc = E_old_pw_hash(new_lm_hash, lm_pwd->hash, lm_verifier.hash); ++ if (rc != 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ goto failed; ++ } + if (memcmp(lm_verifier.hash, r->in.hash->hash, 16) != 0) { + authsam_update_bad_pwd_count(sam_ctx, res[0], ldb_get_default_basedn(sam_ctx)); + status = NT_STATUS_WRONG_PASSWORD; +@@ -442,6 +446,10 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call, + mdfour(new_nt_hash, new_password.data, new_password.length); + + E_old_pw_hash(new_nt_hash, nt_pwd->hash, nt_verifier.hash); ++ if (rc != 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ goto failed; ++ } + if (memcmp(nt_verifier.hash, r->in.nt_verifier->hash, 16) != 0) { + status = NT_STATUS_WRONG_PASSWORD; + goto failed; +@@ -460,7 +468,11 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call, + new_password.length, + (void **)&new_pass, &converted_size)) { + E_deshash(new_pass, new_lm_hash); +- E_old_pw_hash(new_nt_hash, lm_pwd->hash, lm_verifier.hash); ++ rc = E_old_pw_hash(new_nt_hash, lm_pwd->hash, lm_verifier.hash); ++ if (rc != 0) { ++ status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ goto failed; ++ } + if (memcmp(lm_verifier.hash, r->in.lm_verifier->hash, 16) != 0) { + status = NT_STATUS_WRONG_PASSWORD; + goto failed; +-- +2.23.0 + diff --git a/SOURCES/0183-smbdes-convert-des_crypt112-to-use-gnutls.patch b/SOURCES/0183-smbdes-convert-des_crypt112-to-use-gnutls.patch new file mode 100644 index 0000000..1ad3c9b --- /dev/null +++ b/SOURCES/0183-smbdes-convert-des_crypt112-to-use-gnutls.patch @@ -0,0 +1,118 @@ +From 41f45d98f22a7bae8d29fb3828452324c6b88eef Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Wed, 20 Nov 2019 15:41:02 +0100 +Subject: [PATCH 183/187] smbdes: convert des_crypt112 to use gnutls + +Signed-off-by: Isaac Boukris +Reviewed-by: Andrew Bartlett +(cherry picked from commit 254739137bdaebca31163f1683bfd7111dfefe67) +--- + libcli/auth/credentials.c | 8 +++++++- + libcli/auth/proto.h | 3 ++- + libcli/auth/smbdes.c | 25 ++++++++++++++++++------- + libcli/auth/tests/test_gnutls.c | 7 +++++-- + 4 files changed, 32 insertions(+), 11 deletions(-) + +diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c +index 1b94a06ebfb..5f65428a1d7 100644 +--- a/libcli/auth/credentials.c ++++ b/libcli/auth/credentials.c +@@ -38,6 +38,8 @@ static NTSTATUS netlogon_creds_step_crypt(struct netlogon_creds_CredentialState + struct netr_Credential *out) + { + NTSTATUS status; ++ int rc; ++ + if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { + memcpy(out->data, in->data, sizeof(out->data)); + +@@ -48,7 +50,11 @@ static NTSTATUS netlogon_creds_step_crypt(struct netlogon_creds_CredentialState + return status; + } + } else { +- des_crypt112(out->data, in->data, creds->session_key, 1); ++ rc = des_crypt112(out->data, in->data, creds->session_key, SAMBA_GNUTLS_ENCRYPT); ++ if (rc != 0) { ++ return gnutls_error_to_ntstatus(rc, ++ NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ } + } + + return NT_STATUS_OK; +diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h +index 5e88d7527fd..3994db20a36 100644 +--- a/libcli/auth/proto.h ++++ b/libcli/auth/proto.h +@@ -227,7 +227,8 @@ int E_P16(const uint8_t *p14,uint8_t *p16); + int E_P24(const uint8_t *p21, const uint8_t *c8, uint8_t *p24); + int E_old_pw_hash( uint8_t *p14, const uint8_t *in, uint8_t *out); + int 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); ++int des_crypt112(uint8_t out[8], const uint8_t in[8], const uint8_t key[14], ++ enum samba_gnutls_direction encrypt); + void des_crypt112_16(uint8_t out[16], const uint8_t in[16], const uint8_t key[14], int forw); + int sam_rid_crypt(unsigned int rid, const uint8_t *in, uint8_t *out, + enum samba_gnutls_direction encrypt); +diff --git a/libcli/auth/smbdes.c b/libcli/auth/smbdes.c +index ec922da4727..8dc4fc4097c 100644 +--- a/libcli/auth/smbdes.c ++++ b/libcli/auth/smbdes.c +@@ -418,16 +418,27 @@ int des_crypt128(uint8_t out[8], const uint8_t in[8], const uint8_t key[16]) + } + + /* des encryption with a 112 bit (14 byte) key */ +-void des_crypt112(uint8_t out[8], const uint8_t in[8], const uint8_t key[14], int forw) ++int des_crypt112(uint8_t out[8], const uint8_t in[8], const uint8_t key[14], ++ enum samba_gnutls_direction encrypt) + { + uint8_t buf[8]; +- if (forw) { +- des_crypt56(buf, in, key, forw); +- des_crypt56(out, buf, key+7, forw); +- } else { +- des_crypt56(buf, in, key+7, forw); +- des_crypt56(out, buf, key, forw); ++ int ret; ++ ++ if (encrypt == SAMBA_GNUTLS_ENCRYPT) { ++ ret = des_crypt56_gnutls(buf, in, key, SAMBA_GNUTLS_ENCRYPT); ++ if (ret != 0) { ++ return ret; ++ } ++ ++ return des_crypt56_gnutls(out, buf, key+7, SAMBA_GNUTLS_ENCRYPT); + } ++ ++ ret = des_crypt56_gnutls(buf, in, key+7, SAMBA_GNUTLS_DECRYPT); ++ if (ret != 0) { ++ return ret; ++ } ++ ++ return des_crypt56_gnutls(out, buf, key, SAMBA_GNUTLS_DECRYPT); + } + + /* des encryption of a 16 byte lump of data with a 112 bit key */ +diff --git a/libcli/auth/tests/test_gnutls.c b/libcli/auth/tests/test_gnutls.c +index 087afee09db..68a27adc894 100644 +--- a/libcli/auth/tests/test_gnutls.c ++++ b/libcli/auth/tests/test_gnutls.c +@@ -386,11 +386,14 @@ static void torture_gnutls_des_crypt112(void **state) + + uint8_t crypt[8]; + uint8_t decrypt[8]; ++ int rc; + +- des_crypt112(crypt, clear, key, 1); ++ rc = des_crypt112(crypt, clear, key, SAMBA_GNUTLS_ENCRYPT); ++ assert_int_equal(rc, 0); + assert_memory_equal(crypt, crypt_expected, 8); + +- des_crypt112(decrypt, crypt, key, 0); ++ rc = des_crypt112(decrypt, crypt, key, SAMBA_GNUTLS_DECRYPT); ++ assert_int_equal(rc, 0); + assert_memory_equal(decrypt, clear, 8); + } + +-- +2.23.0 + diff --git a/SOURCES/0184-smbdes-convert-des_crypt112_16-to-use-gnutls.patch b/SOURCES/0184-smbdes-convert-des_crypt112_16-to-use-gnutls.patch new file mode 100644 index 0000000..31bbad8 --- /dev/null +++ b/SOURCES/0184-smbdes-convert-des_crypt112_16-to-use-gnutls.patch @@ -0,0 +1,296 @@ +From 8d840662df55c11616338af5c3b4b062485b19a4 Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Wed, 20 Nov 2019 16:02:16 +0100 +Subject: [PATCH 184/187] smbdes: convert des_crypt112_16 to use gnutls + +Signed-off-by: Isaac Boukris +Reviewed-by: Andrew Bartlett +(cherry picked from commit dcc33103d5c0927bb3757974d4663df888dce95e) +--- + libcli/auth/credentials.c | 38 +++++++++++++++---- + libcli/auth/netlogon_creds_cli.c | 24 +++++++++--- + libcli/auth/proto.h | 9 +++-- + libcli/auth/smbdes.c | 13 +++++-- + libcli/auth/tests/test_gnutls.c | 7 +++- + source3/rpc_server/netlogon/srv_netlog_nt.c | 16 ++++++-- + source4/rpc_server/netlogon/dcerpc_netlogon.c | 13 +++++-- + 7 files changed, 92 insertions(+), 28 deletions(-) + +diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c +index 5f65428a1d7..c541eeff470 100644 +--- a/libcli/auth/credentials.c ++++ b/libcli/auth/credentials.c +@@ -302,21 +302,37 @@ NTSTATUS netlogon_creds_des_decrypt_LMKey(struct netlogon_creds_CredentialState + /* + DES encrypt a 16 byte password buffer using the session key + */ +-void netlogon_creds_des_encrypt(struct netlogon_creds_CredentialState *creds, struct samr_Password *pass) ++NTSTATUS netlogon_creds_des_encrypt(struct netlogon_creds_CredentialState *creds, ++ struct samr_Password *pass) + { + struct samr_Password tmp; +- des_crypt112_16(tmp.hash, pass->hash, creds->session_key, 1); ++ int rc; ++ ++ rc = des_crypt112_16(tmp.hash, pass->hash, creds->session_key, SAMBA_GNUTLS_ENCRYPT); ++ if (rc < 0) { ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ } + *pass = tmp; ++ ++ return NT_STATUS_OK; + } + + /* + DES decrypt a 16 byte password buffer using the session key + */ +-void netlogon_creds_des_decrypt(struct netlogon_creds_CredentialState *creds, struct samr_Password *pass) ++NTSTATUS netlogon_creds_des_decrypt(struct netlogon_creds_CredentialState *creds, ++ struct samr_Password *pass) + { + struct samr_Password tmp; +- des_crypt112_16(tmp.hash, pass->hash, creds->session_key, 0); ++ int rc; ++ ++ rc = des_crypt112_16(tmp.hash, pass->hash, creds->session_key, SAMBA_GNUTLS_DECRYPT); ++ if (rc < 0) { ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ } + *pass = tmp; ++ ++ return NT_STATUS_OK; + } + + /* +@@ -993,17 +1009,23 @@ static NTSTATUS netlogon_creds_crypt_samlogon_logon(struct netlogon_creds_Creden + p = &logon->password->lmpassword; + if (!all_zero(p->hash, 16)) { + if (do_encrypt) { +- netlogon_creds_des_encrypt(creds, p); ++ status = netlogon_creds_des_encrypt(creds, p); + } else { +- netlogon_creds_des_decrypt(creds, p); ++ status = netlogon_creds_des_decrypt(creds, p); ++ } ++ if (!NT_STATUS_IS_OK(status)) { ++ return status; + } + } + p = &logon->password->ntpassword; + if (!all_zero(p->hash, 16)) { + if (do_encrypt) { +- netlogon_creds_des_encrypt(creds, p); ++ status = netlogon_creds_des_encrypt(creds, p); + } else { +- netlogon_creds_des_decrypt(creds, p); ++ status = netlogon_creds_des_decrypt(creds, p); ++ } ++ if (!NT_STATUS_IS_OK(status)) { ++ return status; + } + } + } +diff --git a/libcli/auth/netlogon_creds_cli.c b/libcli/auth/netlogon_creds_cli.c +index 0378f302ffa..c8f4227a924 100644 +--- a/libcli/auth/netlogon_creds_cli.c ++++ b/libcli/auth/netlogon_creds_cli.c +@@ -2032,8 +2032,12 @@ static void netlogon_creds_cli_ServerPasswordSet_locked(struct tevent_req *subre + return; + } + } else { +- netlogon_creds_des_encrypt(&state->tmp_creds, +- &state->samr_password); ++ status = netlogon_creds_des_encrypt(&state->tmp_creds, ++ &state->samr_password); ++ if (tevent_req_nterror(req, status)) { ++ netlogon_creds_cli_ServerPasswordSet_cleanup(req, status); ++ return; ++ } + + subreq = dcerpc_netr_ServerPasswordSet_send(state, state->ev, + state->binding_handle, +@@ -3187,14 +3191,22 @@ static void netlogon_creds_cli_ServerGetTrustInfo_done(struct tevent_req *subreq + cmp = memcmp(state->new_owf_password.hash, + zero.hash, sizeof(zero.hash)); + if (cmp != 0) { +- netlogon_creds_des_decrypt(&state->tmp_creds, +- &state->new_owf_password); ++ status = netlogon_creds_des_decrypt(&state->tmp_creds, ++ &state->new_owf_password); ++ if (tevent_req_nterror(req, status)) { ++ netlogon_creds_cli_ServerGetTrustInfo_cleanup(req, status); ++ return; ++ } + } + cmp = memcmp(state->old_owf_password.hash, + zero.hash, sizeof(zero.hash)); + if (cmp != 0) { +- netlogon_creds_des_decrypt(&state->tmp_creds, +- &state->old_owf_password); ++ status = netlogon_creds_des_decrypt(&state->tmp_creds, ++ &state->old_owf_password); ++ if (tevent_req_nterror(req, status)) { ++ netlogon_creds_cli_ServerGetTrustInfo_cleanup(req, status); ++ return; ++ } + } + + *state->creds = state->tmp_creds; +diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h +index 3994db20a36..4c6d7af6763 100644 +--- a/libcli/auth/proto.h ++++ b/libcli/auth/proto.h +@@ -17,8 +17,10 @@ NTSTATUS netlogon_creds_des_encrypt_LMKey(struct netlogon_creds_CredentialState + struct netr_LMSessionKey *key); + NTSTATUS 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); ++NTSTATUS netlogon_creds_des_encrypt(struct netlogon_creds_CredentialState *creds, ++ struct samr_Password *pass); ++NTSTATUS netlogon_creds_des_decrypt(struct netlogon_creds_CredentialState *creds, ++ struct samr_Password *pass); + NTSTATUS netlogon_creds_arcfour_crypt(struct netlogon_creds_CredentialState *creds, + uint8_t *data, + size_t len); +@@ -229,7 +231,8 @@ int E_old_pw_hash( uint8_t *p14, const uint8_t *in, uint8_t *out); + int des_crypt128(uint8_t out[8], const uint8_t in[8], const uint8_t key[16]); + int des_crypt112(uint8_t out[8], const uint8_t in[8], const uint8_t key[14], + enum samba_gnutls_direction encrypt); +-void des_crypt112_16(uint8_t out[16], const uint8_t in[16], const uint8_t key[14], int forw); ++int des_crypt112_16(uint8_t out[16], const uint8_t in[16], const uint8_t key[14], ++ enum samba_gnutls_direction encrypt); + int sam_rid_crypt(unsigned int rid, const uint8_t *in, uint8_t *out, + enum samba_gnutls_direction encrypt); + #undef _PRINTF_ATTRIBUTE +diff --git a/libcli/auth/smbdes.c b/libcli/auth/smbdes.c +index 8dc4fc4097c..8fc79dc5c71 100644 +--- a/libcli/auth/smbdes.c ++++ b/libcli/auth/smbdes.c +@@ -442,10 +442,17 @@ int des_crypt112(uint8_t out[8], const uint8_t in[8], const uint8_t key[14], + } + + /* des encryption of a 16 byte lump of data with a 112 bit key */ +-void des_crypt112_16(uint8_t out[16], const uint8_t in[16], const uint8_t key[14], int forw) ++int des_crypt112_16(uint8_t out[16], const uint8_t in[16], const uint8_t key[14], ++ enum samba_gnutls_direction encrypt) + { +- des_crypt56(out, in, key, forw); +- des_crypt56(out + 8, in + 8, key+7, forw); ++ int ret; ++ ++ ret = des_crypt56_gnutls(out, in, key, encrypt); ++ if (ret != 0) { ++ return ret; ++ } ++ ++ return des_crypt56_gnutls(out + 8, in + 8, key+7, encrypt); + } + + /* Decode a sam password hash into a password. The password hash is the +diff --git a/libcli/auth/tests/test_gnutls.c b/libcli/auth/tests/test_gnutls.c +index 68a27adc894..a6692b9a913 100644 +--- a/libcli/auth/tests/test_gnutls.c ++++ b/libcli/auth/tests/test_gnutls.c +@@ -414,11 +414,14 @@ static void torture_gnutls_des_crypt112_16(void **state) + + uint8_t crypt[16]; + uint8_t decrypt[16]; ++ int rc; + +- des_crypt112_16(crypt, clear, key, 1); ++ rc = des_crypt112_16(crypt, clear, key, SAMBA_GNUTLS_ENCRYPT); ++ assert_int_equal(rc, 0); + assert_memory_equal(crypt, crypt_expected, 16); + +- des_crypt112_16(decrypt, crypt, key, 0); ++ rc = des_crypt112_16(decrypt, crypt, key, SAMBA_GNUTLS_DECRYPT); ++ assert_int_equal(rc, 0); + assert_memory_equal(decrypt, clear, 16); + } + +diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c +index 671300676ff..124bae95064 100644 +--- a/source3/rpc_server/netlogon/srv_netlog_nt.c ++++ b/source3/rpc_server/netlogon/srv_netlog_nt.c +@@ -1311,7 +1311,10 @@ NTSTATUS _netr_ServerPasswordSet(struct pipes_struct *p, + DEBUG(3,("_netr_ServerPasswordSet: Server Password Set by remote machine:[%s] on account [%s]\n", + r->in.computer_name, creds->computer_name)); + +- netlogon_creds_des_decrypt(creds, r->in.new_password); ++ status = netlogon_creds_des_decrypt(creds, r->in.new_password); ++ if (!NT_STATUS_IS_OK(status)) { ++ return status; ++ } + + DEBUG(100,("_netr_ServerPasswordSet: new given value was :\n")); + for(i = 0; i < sizeof(r->in.new_password->hash); i++) +@@ -2560,6 +2563,7 @@ static NTSTATUS get_password_from_trustAuth(TALLOC_CTX *mem_ctx, + { + enum ndr_err_code ndr_err; + struct trustAuthInOutBlob trustAuth; ++ NTSTATUS status; + + ndr_err = ndr_pull_struct_blob_all(trustAuth_blob, mem_ctx, &trustAuth, + (ndr_pull_flags_fn_t)ndr_pull_trustAuthInOutBlob); +@@ -2572,7 +2576,10 @@ static NTSTATUS get_password_from_trustAuth(TALLOC_CTX *mem_ctx, + mdfour(current_pw_enc->hash, + trustAuth.current.array[0].AuthInfo.clear.password, + trustAuth.current.array[0].AuthInfo.clear.size); +- netlogon_creds_des_encrypt(creds, current_pw_enc); ++ status = netlogon_creds_des_encrypt(creds, current_pw_enc); ++ if (!NT_STATUS_IS_OK(status)) { ++ return status; ++ } + } else { + return NT_STATUS_UNSUCCESSFUL; + } +@@ -2583,7 +2590,10 @@ static NTSTATUS get_password_from_trustAuth(TALLOC_CTX *mem_ctx, + mdfour(previous_pw_enc->hash, + trustAuth.previous.array[0].AuthInfo.clear.password, + trustAuth.previous.array[0].AuthInfo.clear.size); +- netlogon_creds_des_encrypt(creds, previous_pw_enc); ++ status = netlogon_creds_des_encrypt(creds, previous_pw_enc); ++ if (!NT_STATUS_IS_OK(status)) { ++ return status; ++ } + } else { + ZERO_STRUCTP(previous_pw_enc); + } +diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c +index 49a075137ff..6c92db7b53a 100644 +--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c ++++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c +@@ -678,7 +678,8 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet(struct dcesrv_call_state *dce_call + return NT_STATUS_INVALID_SYSTEM_SERVICE; + } + +- netlogon_creds_des_decrypt(creds, r->in.new_password); ++ nt_status = netlogon_creds_des_decrypt(creds, r->in.new_password); ++ NT_STATUS_NOT_OK_RETURN(nt_status); + + /* fetch the old password hashes (the NT hash has to exist) */ + +@@ -4193,11 +4194,17 @@ static NTSTATUS dcesrv_netr_ServerGetTrustInfo(struct dcesrv_call_state *dce_cal + + if (curNtHash != NULL) { + *r->out.new_owf_password = *curNtHash; +- netlogon_creds_des_encrypt(creds, r->out.new_owf_password); ++ nt_status = netlogon_creds_des_encrypt(creds, r->out.new_owf_password); ++ if (!NT_STATUS_IS_OK(nt_status)) { ++ return nt_status; ++ } + } + if (prevNtHash != NULL) { + *r->out.old_owf_password = *prevNtHash; +- netlogon_creds_des_encrypt(creds, r->out.old_owf_password); ++ nt_status = netlogon_creds_des_encrypt(creds, r->out.old_owf_password); ++ if (!NT_STATUS_IS_OK(nt_status)) { ++ return nt_status; ++ } + } + + if (trust_info != NULL) { +-- +2.23.0 + diff --git a/SOURCES/0185-session-convert-sess_crypt_blob-to-use-gnutls.patch b/SOURCES/0185-session-convert-sess_crypt_blob-to-use-gnutls.patch new file mode 100644 index 0000000..8d540a8 --- /dev/null +++ b/SOURCES/0185-session-convert-sess_crypt_blob-to-use-gnutls.patch @@ -0,0 +1,449 @@ +From 3f2ab4815d9ddf6a6d4a6d8904f528f05d1802cf Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Thu, 21 Nov 2019 14:02:03 +0100 +Subject: [PATCH 185/187] session: convert sess_crypt_blob to use gnutls + +Signed-off-by: Isaac Boukris +Reviewed-by: Andrew Bartlett +(cherry picked from commit a75ca8d5d515aef1229acf5a30489ee5f5ced3e1) +--- + libcli/auth/proto.h | 4 +- + libcli/auth/session.c | 42 ++++++++++++++++----- + libcli/auth/tests/test_gnutls.c | 7 +++- + source3/rpc_server/netlogon/srv_netlog_nt.c | 7 +++- + source3/rpc_server/samr/srv_samr_nt.c | 27 +++++++++++-- + source3/rpcclient/cmd_samr.c | 25 ++++++++++-- + source4/rpc_server/samr/samr_password.c | 13 ++++++- + source4/torture/rpc/samr.c | 16 ++++---- + 8 files changed, 108 insertions(+), 33 deletions(-) + +diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h +index 4c6d7af6763..09ff3687fb7 100644 +--- a/libcli/auth/proto.h ++++ b/libcli/auth/proto.h +@@ -90,8 +90,8 @@ union netr_LogonLevel *netlogon_creds_shallow_copy_logon(TALLOC_CTX *mem_ctx, + + /* The following definitions come from /home/jeremy/src/samba/git/master/source3/../source4/../libcli/auth/session.c */ + +-void sess_crypt_blob(DATA_BLOB *out, const DATA_BLOB *in, const DATA_BLOB *session_key, +- bool forward); ++int sess_crypt_blob(DATA_BLOB *out, const DATA_BLOB *in, const DATA_BLOB *session_key, ++ enum samba_gnutls_direction encrypt); + DATA_BLOB sess_encrypt_string(const char *str, const DATA_BLOB *session_key); + char *sess_decrypt_string(TALLOC_CTX *mem_ctx, + DATA_BLOB *blob, const DATA_BLOB *session_key); +diff --git a/libcli/auth/session.c b/libcli/auth/session.c +index 10c728662db..4af70d361af 100644 +--- a/libcli/auth/session.c ++++ b/libcli/auth/session.c +@@ -29,10 +29,10 @@ + before calling, the out blob must be initialised to be the same size + as the in blob + */ +-void sess_crypt_blob(DATA_BLOB *out, const DATA_BLOB *in, const DATA_BLOB *session_key, +- bool forward) ++int sess_crypt_blob(DATA_BLOB *out, const DATA_BLOB *in, const DATA_BLOB *session_key, ++ enum samba_gnutls_direction encrypt) + { +- int i, k; ++ int i, k, rc; + + for (i=0,k=0; + ilength; +@@ -47,10 +47,14 @@ void sess_crypt_blob(DATA_BLOB *out, const DATA_BLOB *in, const DATA_BLOB *sessi + } + memcpy(key, &session_key->data[k], 7); + +- des_crypt56(bout, bin, key, forward?1:0); ++ rc = des_crypt56_gnutls(bout, bin, key, encrypt); ++ if (rc != 0) { ++ return rc; ++ } + + memcpy(&out->data[i], bout, MIN(8, in->length-i)); + } ++ return 0; + } + + +@@ -67,6 +71,7 @@ DATA_BLOB sess_encrypt_string(const char *str, const DATA_BLOB *session_key) + DATA_BLOB ret, src; + int slen = strlen(str); + int dlen = (slen+7) & ~7; ++ int rc; + + src = data_blob(NULL, 8+dlen); + if (!src.data) { +@@ -84,9 +89,13 @@ DATA_BLOB sess_encrypt_string(const char *str, const DATA_BLOB *session_key) + memset(src.data+8, 0, dlen); + memcpy(src.data+8, str, slen); + +- sess_crypt_blob(&ret, &src, session_key, true); ++ rc = sess_crypt_blob(&ret, &src, session_key, SAMBA_GNUTLS_ENCRYPT); + + data_blob_free(&src); ++ if (rc != 0) { ++ data_blob_free(&ret); ++ return data_blob(NULL, 0); ++ } + + return ret; + } +@@ -100,7 +109,7 @@ char *sess_decrypt_string(TALLOC_CTX *mem_ctx, + DATA_BLOB *blob, const DATA_BLOB *session_key) + { + DATA_BLOB out; +- int slen; ++ int rc, slen; + char *ret; + + if (blob->length < 8) { +@@ -112,7 +121,11 @@ char *sess_decrypt_string(TALLOC_CTX *mem_ctx, + return NULL; + } + +- sess_crypt_blob(&out, blob, session_key, false); ++ rc = sess_crypt_blob(&out, blob, session_key, SAMBA_GNUTLS_DECRYPT); ++ if (rc != 0) { ++ data_blob_free(&out); ++ return NULL; ++ } + + if (IVAL(out.data, 4) != 1) { + DEBUG(0,("Unexpected revision number %d in session crypted string\n", +@@ -149,6 +162,7 @@ DATA_BLOB sess_encrypt_blob(TALLOC_CTX *mem_ctx, DATA_BLOB *blob_in, const DATA_ + { + DATA_BLOB ret, src; + int dlen = (blob_in->length+7) & ~7; ++ int rc; + + src = data_blob_talloc(mem_ctx, NULL, 8+dlen); + if (!src.data) { +@@ -166,9 +180,13 @@ DATA_BLOB sess_encrypt_blob(TALLOC_CTX *mem_ctx, DATA_BLOB *blob_in, const DATA_ + memset(src.data+8, 0, dlen); + memcpy(src.data+8, blob_in->data, blob_in->length); + +- sess_crypt_blob(&ret, &src, session_key, true); ++ rc = sess_crypt_blob(&ret, &src, session_key, SAMBA_GNUTLS_ENCRYPT); + + data_blob_free(&src); ++ if (rc != 0) { ++ data_blob_free(&ret); ++ return data_blob(NULL, 0); ++ } + + return ret; + } +@@ -180,7 +198,7 @@ NTSTATUS sess_decrypt_blob(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, const DAT + DATA_BLOB *ret) + { + DATA_BLOB out; +- int slen; ++ int rc, slen; + + if (blob->length < 8) { + DEBUG(0, ("Unexpected length %d in session crypted secret (BLOB)\n", +@@ -193,7 +211,11 @@ NTSTATUS sess_decrypt_blob(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, const DAT + return NT_STATUS_NO_MEMORY; + } + +- sess_crypt_blob(&out, blob, session_key, false); ++ rc = sess_crypt_blob(&out, blob, session_key, SAMBA_GNUTLS_DECRYPT); ++ if (rc != 0) { ++ data_blob_free(&out); ++ return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ } + + if (IVAL(out.data, 4) != 1) { + DEBUG(2,("Unexpected revision number %d in session crypted secret (BLOB)\n", +diff --git a/libcli/auth/tests/test_gnutls.c b/libcli/auth/tests/test_gnutls.c +index a6692b9a913..707a1bcecc3 100644 +--- a/libcli/auth/tests/test_gnutls.c ++++ b/libcli/auth/tests/test_gnutls.c +@@ -494,11 +494,14 @@ static void torture_gnutls_sess_crypt_blob(void **state) + }; + DATA_BLOB crypt = data_blob(NULL, 24); + DATA_BLOB decrypt = data_blob(NULL, 24); ++ int rc; + +- sess_crypt_blob(&crypt, &clear, &key, true); ++ rc = sess_crypt_blob(&crypt, &clear, &key, SAMBA_GNUTLS_ENCRYPT); ++ assert_int_equal(rc, 0); + assert_memory_equal(crypt.data, crypt_expected, 24); + +- sess_crypt_blob(&decrypt, &crypt, &key, false); ++ rc = sess_crypt_blob(&decrypt, &crypt, &key, SAMBA_GNUTLS_DECRYPT); ++ assert_int_equal(rc, 0); + assert_memory_equal(decrypt.data, clear.data, 24); + } + +diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c +index 124bae95064..cbbf9feedc7 100644 +--- a/source3/rpc_server/netlogon/srv_netlog_nt.c ++++ b/source3/rpc_server/netlogon/srv_netlog_nt.c +@@ -1220,7 +1220,12 @@ static NTSTATUS netr_set_machine_account_password(TALLOC_CTX *mem_ctx, + status = NT_STATUS_NO_MEMORY; + goto out; + } +- sess_crypt_blob(&out, &in, &session_key, true); ++ rc = sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT); ++ if (rc != 0) { ++ status = gnutls_error_to_ntstatus(rc, ++ NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ goto out; ++ } + memcpy(info18.nt_pwd.hash, out.data, out.length); + + info18.nt_pwd_active = true; +diff --git a/source3/rpc_server/samr/srv_samr_nt.c b/source3/rpc_server/samr/srv_samr_nt.c +index 87214b2899e..91771e34502 100644 +--- a/source3/rpc_server/samr/srv_samr_nt.c ++++ b/source3/rpc_server/samr/srv_samr_nt.c +@@ -4411,6 +4411,8 @@ static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18, + DATA_BLOB *session_key, + struct samu *pwd) + { ++ int rc; ++ + if (id18 == NULL) { + DEBUG(2, ("set_user_info_18: id18 is NULL\n")); + return NT_STATUS_INVALID_PARAMETER; +@@ -4429,7 +4431,11 @@ static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18, + in = data_blob_const(id18->nt_pwd.hash, 16); + out = data_blob_talloc_zero(mem_ctx, 16); + +- sess_crypt_blob(&out, &in, session_key, false); ++ rc = sess_crypt_blob(&out, &in, session_key, SAMBA_GNUTLS_DECRYPT); ++ if (rc != 0) { ++ return gnutls_error_to_ntstatus(rc, ++ NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ } + + if (!pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED)) { + return NT_STATUS_ACCESS_DENIED; +@@ -4445,7 +4451,11 @@ static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18, + in = data_blob_const(id18->lm_pwd.hash, 16); + out = data_blob_talloc_zero(mem_ctx, 16); + +- sess_crypt_blob(&out, &in, session_key, false); ++ rc = sess_crypt_blob(&out, &in, session_key, SAMBA_GNUTLS_DECRYPT); ++ if (rc != 0) { ++ return gnutls_error_to_ntstatus(rc, ++ NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ } + + if (!pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED)) { + return NT_STATUS_ACCESS_DENIED; +@@ -4487,6 +4497,7 @@ static NTSTATUS set_user_info_21(struct samr_UserInfo21 *id21, + struct samu *pwd) + { + NTSTATUS status; ++ int rc; + + if (id21 == NULL) { + DEBUG(5, ("set_user_info_21: NULL id21\n")); +@@ -4517,7 +4528,11 @@ static NTSTATUS set_user_info_21(struct samr_UserInfo21 *id21, + in = data_blob_const(id21->nt_owf_password.array, 16); + out = data_blob_talloc_zero(mem_ctx, 16); + +- sess_crypt_blob(&out, &in, session_key, false); ++ rc = sess_crypt_blob(&out, &in, session_key, SAMBA_GNUTLS_DECRYPT); ++ if (rc != 0) { ++ return gnutls_error_to_ntstatus(rc, ++ NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ } + + pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED); + pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED); +@@ -4540,7 +4555,11 @@ static NTSTATUS set_user_info_21(struct samr_UserInfo21 *id21, + in = data_blob_const(id21->lm_owf_password.array, 16); + out = data_blob_talloc_zero(mem_ctx, 16); + +- sess_crypt_blob(&out, &in, session_key, false); ++ rc = sess_crypt_blob(&out, &in, session_key, SAMBA_GNUTLS_DECRYPT); ++ if (rc != 0) { ++ return gnutls_error_to_ntstatus(rc, ++ NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ } + + pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED); + pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED); +diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c +index 0cd8b50058e..de95eb2160d 100644 +--- a/source3/rpcclient/cmd_samr.c ++++ b/source3/rpcclient/cmd_samr.c +@@ -3044,6 +3044,7 @@ static NTSTATUS cmd_samr_setuserinfo_int(struct rpc_pipe_client *cli, + uint8_t password_expired = 0; + struct dcerpc_binding_handle *b = cli->binding_handle; + TALLOC_CTX *frame = NULL; ++ int rc; + + if (argc < 4) { + printf("Usage: %s username level password [password_expired]\n", +@@ -3086,7 +3087,11 @@ static NTSTATUS cmd_samr_setuserinfo_int(struct rpc_pipe_client *cli, + status = NT_STATUS_NO_MEMORY; + goto done; + } +- sess_crypt_blob(&out, &in, &session_key, true); ++ rc = sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT); ++ if (rc != 0) { ++ status = gnutls_error_to_ntstatus(rc, ++ NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ } + memcpy(nt_hash, out.data, out.length); + } + { +@@ -3097,7 +3102,11 @@ static NTSTATUS cmd_samr_setuserinfo_int(struct rpc_pipe_client *cli, + status = NT_STATUS_NO_MEMORY; + goto done; + } +- sess_crypt_blob(&out, &in, &session_key, true); ++ rc = sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT); ++ if (rc != 0) { ++ status = gnutls_error_to_ntstatus(rc, ++ NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ } + memcpy(lm_hash, out.data, out.length); + } + +@@ -3134,7 +3143,11 @@ static NTSTATUS cmd_samr_setuserinfo_int(struct rpc_pipe_client *cli, + status = NT_STATUS_NO_MEMORY; + goto done; + } +- sess_crypt_blob(&out, &in, &session_key, true); ++ rc = sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT); ++ if (rc != 0) { ++ status = gnutls_error_to_ntstatus(rc, ++ NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ } + info.info21.nt_owf_password.array = + (uint16_t *)talloc_memdup(frame, out.data, 16); + } +@@ -3142,7 +3155,11 @@ static NTSTATUS cmd_samr_setuserinfo_int(struct rpc_pipe_client *cli, + DATA_BLOB in,out; + in = data_blob_const(lm_hash, 16); + out = data_blob_talloc_zero(frame, 16); +- sess_crypt_blob(&out, &in, &session_key, true); ++ rc = sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT); ++ if (rc != 0) { ++ status = gnutls_error_to_ntstatus(rc, ++ NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ } + info.info21.lm_owf_password.array = + (uint16_t *)talloc_memdup(frame, out.data, 16); + if (out.data == NULL) { +diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c +index 4fa00bf6360..fba236ebdd7 100644 +--- a/source4/rpc_server/samr/samr_password.c ++++ b/source4/rpc_server/samr/samr_password.c +@@ -737,6 +737,7 @@ NTSTATUS samr_set_password_buffers(struct dcesrv_call_state *dce_call, + DATA_BLOB session_key = data_blob(NULL, 0); + DATA_BLOB in, out; + NTSTATUS nt_status = NT_STATUS_OK; ++ int rc; + + nt_status = dcesrv_transport_session_key(dce_call, &session_key); + if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_USER_SESSION_KEY)) { +@@ -761,7 +762,11 @@ NTSTATUS samr_set_password_buffers(struct dcesrv_call_state *dce_call, + in = data_blob_const(lm_pwd_hash, 16); + out = data_blob_talloc_zero(mem_ctx, 16); + +- sess_crypt_blob(&out, &in, &session_key, false); ++ rc = sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_DECRYPT); ++ if (rc != 0) { ++ return gnutls_error_to_ntstatus(rc, ++ NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ } + + d_lm_pwd_hash = (struct samr_Password *) out.data; + } +@@ -769,7 +774,11 @@ NTSTATUS samr_set_password_buffers(struct dcesrv_call_state *dce_call, + in = data_blob_const(nt_pwd_hash, 16); + out = data_blob_talloc_zero(mem_ctx, 16); + +- sess_crypt_blob(&out, &in, &session_key, false); ++ rc = sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_DECRYPT); ++ if (rc != 0) { ++ return gnutls_error_to_ntstatus(rc, ++ NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); ++ } + + d_nt_pwd_hash = (struct samr_Password *) out.data; + } +diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c +index 4b3ad093bf6..1961c05b5f6 100644 +--- a/source4/torture/rpc/samr.c ++++ b/source4/torture/rpc/samr.c +@@ -1007,14 +1007,14 @@ static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *t + DATA_BLOB in,out; + in = data_blob_const(nt_hash, 16); + out = data_blob_talloc_zero(tctx, 16); +- sess_crypt_blob(&out, &in, &session_key, true); ++ sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT); + memcpy(u.info18.nt_pwd.hash, out.data, out.length); + } + { + DATA_BLOB in,out; + in = data_blob_const(lm_hash, 16); + out = data_blob_talloc_zero(tctx, 16); +- sess_crypt_blob(&out, &in, &session_key, true); ++ sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT); + memcpy(u.info18.lm_pwd.hash, out.data, out.length); + } + +@@ -1096,7 +1096,7 @@ static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *t + in = data_blob_const(u.info21.lm_owf_password.array, + u.info21.lm_owf_password.length); + out = data_blob_talloc_zero(tctx, 16); +- sess_crypt_blob(&out, &in, &session_key, true); ++ sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT); + u.info21.lm_owf_password.array = (uint16_t *)out.data; + } + +@@ -1105,7 +1105,7 @@ static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *t + in = data_blob_const(u.info21.nt_owf_password.array, + u.info21.nt_owf_password.length); + out = data_blob_talloc_zero(tctx, 16); +- sess_crypt_blob(&out, &in, &session_key, true); ++ sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT); + u.info21.nt_owf_password.array = (uint16_t *)out.data; + } + +@@ -1272,14 +1272,14 @@ static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p, + DATA_BLOB in,out; + in = data_blob_const(u.info18.nt_pwd.hash, 16); + out = data_blob_talloc_zero(tctx, 16); +- sess_crypt_blob(&out, &in, &session_key, true); ++ sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT); + memcpy(u.info18.nt_pwd.hash, out.data, out.length); + } + { + DATA_BLOB in,out; + in = data_blob_const(u.info18.lm_pwd.hash, 16); + out = data_blob_talloc_zero(tctx, 16); +- sess_crypt_blob(&out, &in, &session_key, true); ++ sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT); + memcpy(u.info18.lm_pwd.hash, out.data, out.length); + } + +@@ -1290,7 +1290,7 @@ static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p, + in = data_blob_const(u.info21.lm_owf_password.array, + u.info21.lm_owf_password.length); + out = data_blob_talloc_zero(tctx, 16); +- sess_crypt_blob(&out, &in, &session_key, true); ++ sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT); + u.info21.lm_owf_password.array = (uint16_t *)out.data; + } + if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) { +@@ -1298,7 +1298,7 @@ static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p, + in = data_blob_const(u.info21.nt_owf_password.array, + u.info21.nt_owf_password.length); + out = data_blob_talloc_zero(tctx, 16); +- sess_crypt_blob(&out, &in, &session_key, true); ++ sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT); + u.info21.nt_owf_password.array = (uint16_t *)out.data; + } + break; +-- +2.23.0 + diff --git a/SOURCES/0186-sess_crypt_blob-can-only-crypt-blobs-whose-size-divi.patch b/SOURCES/0186-sess_crypt_blob-can-only-crypt-blobs-whose-size-divi.patch new file mode 100644 index 0000000..8d365a1 --- /dev/null +++ b/SOURCES/0186-sess_crypt_blob-can-only-crypt-blobs-whose-size-divi.patch @@ -0,0 +1,48 @@ +From 211f398a262298286029df78530a42fae0c7390d Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Thu, 21 Nov 2019 15:13:19 +0100 +Subject: [PATCH 186/187] sess_crypt_blob can only crypt blobs whose size + divides by 8 + +Signed-off-by: Isaac Boukris +Reviewed-by: Andrew Bartlett +(cherry picked from commit b5d8f1f78a04719c6a5d15aa92ae398be326fe56) +--- + libcli/auth/session.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/libcli/auth/session.c b/libcli/auth/session.c +index 4af70d361af..43ce9d54fdc 100644 +--- a/libcli/auth/session.c ++++ b/libcli/auth/session.c +@@ -34,13 +34,16 @@ int sess_crypt_blob(DATA_BLOB *out, const DATA_BLOB *in, const DATA_BLOB *sessio + { + int i, k, rc; + ++ if (in->length % 8 != 0) { ++ return GNUTLS_E_INVALID_REQUEST; ++ } ++ + for (i=0,k=0; + ilength; + i += 8, k += 7) { + uint8_t bin[8], bout[8], key[7]; + +- memset(bin, 0, 8); +- memcpy(bin, &in->data[i], MIN(8, in->length-i)); ++ memcpy(bin, &in->data[i], 8); + + if (k + 7 > session_key->length) { + k = (session_key->length - k); +@@ -52,7 +55,7 @@ int sess_crypt_blob(DATA_BLOB *out, const DATA_BLOB *in, const DATA_BLOB *sessio + return rc; + } + +- memcpy(&out->data[i], bout, MIN(8, in->length-i)); ++ memcpy(&out->data[i], bout, 8); + } + return 0; + } +-- +2.23.0 + diff --git a/SOURCES/0187-smbdes-remove-old-unused-DES-builtin-crypto.patch b/SOURCES/0187-smbdes-remove-old-unused-DES-builtin-crypto.patch new file mode 100644 index 0000000..7195224 --- /dev/null +++ b/SOURCES/0187-smbdes-remove-old-unused-DES-builtin-crypto.patch @@ -0,0 +1,328 @@ +From eb167a425b9a3c50d8cf1237ed1d5f726d58a3b8 Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Mon, 21 Oct 2019 20:03:04 +0300 +Subject: [PATCH 187/187] smbdes: remove old unused DES builtin-crypto + +Signed-off-by: Isaac Boukris +Reviewed-by: Andrew Bartlett +(cherry picked from commit fe2577a40c19c99c29dd54c7c43e12f3d43493be) +--- + libcli/auth/proto.h | 1 - + libcli/auth/smbdes.c | 264 -------------------------------- + libcli/auth/tests/test_gnutls.c | 6 - + 3 files changed, 271 deletions(-) + +diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h +index 09ff3687fb7..88f4a7c6c50 100644 +--- a/libcli/auth/proto.h ++++ b/libcli/auth/proto.h +@@ -222,7 +222,6 @@ WERROR decode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, + + /* The following definitions come from /home/jeremy/src/samba/git/master/source3/../source4/../libcli/auth/smbdes.c */ + +-void des_crypt56(uint8_t out[8], const uint8_t in[8], const uint8_t key[7], int forw); + 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); +diff --git a/libcli/auth/smbdes.c b/libcli/auth/smbdes.c +index 8fc79dc5c71..c6c44419306 100644 +--- a/libcli/auth/smbdes.c ++++ b/libcli/auth/smbdes.c +@@ -26,239 +26,6 @@ + #include + #include + +-/* NOTES: +- +- This code makes no attempt to be fast! In fact, it is a very +- slow implementation +- +- This code is NOT a complete DES implementation. It implements only +- the minimum necessary for SMB authentication, as used by all SMB +- products (including every copy of Microsoft Windows95 ever sold) +- +- In particular, it can only do a unchained forward DES pass. This +- means it is not possible to use this code for encryption/decryption +- of data, instead it is only useful as a "hash" algorithm. +- +- There is no entry point into this code that allows normal DES operation. +- +- I believe this means that this code does not come under ITAR +- regulations but this is NOT a legal opinion. If you are concerned +- about the applicability of ITAR regulations to this code then you +- should confirm it for yourself (and maybe let me know if you come +- up with a different answer to the one above) +-*/ +- +- +-static const uint8_t perm1[56] = {57, 49, 41, 33, 25, 17, 9, +- 1, 58, 50, 42, 34, 26, 18, +- 10, 2, 59, 51, 43, 35, 27, +- 19, 11, 3, 60, 52, 44, 36, +- 63, 55, 47, 39, 31, 23, 15, +- 7, 62, 54, 46, 38, 30, 22, +- 14, 6, 61, 53, 45, 37, 29, +- 21, 13, 5, 28, 20, 12, 4}; +- +-static const uint8_t perm2[48] = {14, 17, 11, 24, 1, 5, +- 3, 28, 15, 6, 21, 10, +- 23, 19, 12, 4, 26, 8, +- 16, 7, 27, 20, 13, 2, +- 41, 52, 31, 37, 47, 55, +- 30, 40, 51, 45, 33, 48, +- 44, 49, 39, 56, 34, 53, +- 46, 42, 50, 36, 29, 32}; +- +-static const uint8_t perm3[64] = {58, 50, 42, 34, 26, 18, 10, 2, +- 60, 52, 44, 36, 28, 20, 12, 4, +- 62, 54, 46, 38, 30, 22, 14, 6, +- 64, 56, 48, 40, 32, 24, 16, 8, +- 57, 49, 41, 33, 25, 17, 9, 1, +- 59, 51, 43, 35, 27, 19, 11, 3, +- 61, 53, 45, 37, 29, 21, 13, 5, +- 63, 55, 47, 39, 31, 23, 15, 7}; +- +-static const uint8_t perm4[48] = { 32, 1, 2, 3, 4, 5, +- 4, 5, 6, 7, 8, 9, +- 8, 9, 10, 11, 12, 13, +- 12, 13, 14, 15, 16, 17, +- 16, 17, 18, 19, 20, 21, +- 20, 21, 22, 23, 24, 25, +- 24, 25, 26, 27, 28, 29, +- 28, 29, 30, 31, 32, 1}; +- +-static const uint8_t perm5[32] = { 16, 7, 20, 21, +- 29, 12, 28, 17, +- 1, 15, 23, 26, +- 5, 18, 31, 10, +- 2, 8, 24, 14, +- 32, 27, 3, 9, +- 19, 13, 30, 6, +- 22, 11, 4, 25}; +- +- +-static const uint8_t perm6[64] ={ 40, 8, 48, 16, 56, 24, 64, 32, +- 39, 7, 47, 15, 55, 23, 63, 31, +- 38, 6, 46, 14, 54, 22, 62, 30, +- 37, 5, 45, 13, 53, 21, 61, 29, +- 36, 4, 44, 12, 52, 20, 60, 28, +- 35, 3, 43, 11, 51, 19, 59, 27, +- 34, 2, 42, 10, 50, 18, 58, 26, +- 33, 1, 41, 9, 49, 17, 57, 25}; +- +- +-static const uint8_t sc[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}; +- +-static const uint8_t sbox[8][4][16] = { +- {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}, +- {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8}, +- {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0}, +- {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}}, +- +- {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10}, +- {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5}, +- {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15}, +- {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}}, +- +- {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8}, +- {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1}, +- {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7}, +- {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}}, +- +- {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15}, +- {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9}, +- {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4}, +- {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}}, +- +- {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9}, +- {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6}, +- {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14}, +- {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}}, +- +- {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11}, +- {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8}, +- {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6}, +- {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}}, +- +- {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1}, +- {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6}, +- {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2}, +- {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}}, +- +- {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7}, +- {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2}, +- {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8}, +- {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}}; +- +-static void permute(char *out, const char *in, const uint8_t *p, int n) +-{ +- int i; +- for (i=0;i +Date: Tue, 10 Dec 2019 17:52:36 +0100 +Subject: [PATCH 188/191] lib:crypto: Remove our implementation of AES CCM + +We require GnuTLS >= 3.4.7 which provides AES CCM. + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit c3250ff7ab66fb45c9b5a66c7e3a9453fb22777b) +--- + lib/crypto/aes_ccm_128.c | 198 ------------------ + lib/crypto/aes_ccm_128.h | 58 ------ + lib/crypto/aes_ccm_128_test.c | 377 ---------------------------------- + lib/crypto/crypto.h | 1 - + lib/crypto/wscript_build | 11 - + source4/torture/local/local.c | 3 - + 6 files changed, 648 deletions(-) + delete mode 100644 lib/crypto/aes_ccm_128.c + delete mode 100644 lib/crypto/aes_ccm_128.h + delete mode 100644 lib/crypto/aes_ccm_128_test.c + +diff --git a/lib/crypto/aes_ccm_128.c b/lib/crypto/aes_ccm_128.c +deleted file mode 100644 +index 0cbc05567a8..00000000000 +--- a/lib/crypto/aes_ccm_128.c ++++ /dev/null +@@ -1,198 +0,0 @@ +-/* +- AES-CCM-128 (rfc 3610) +- +- Copyright (C) Stefan Metzmacher 2012 +- +- This program is free software; you can redistribute it and/or modify +- it under the terms of the GNU General Public License as published by +- the Free Software Foundation; either version 3 of the License, or +- (at your option) any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- GNU General Public License for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program. If not, see . +-*/ +- +-#include "replace.h" +-#include "lib/crypto/aes.h" +-#include "lib/crypto/aes_ccm_128.h" +-#include "lib/util/byteorder.h" +- +-#define M_ ((AES_CCM_128_M - 2) / 2) +-#define L_ (AES_CCM_128_L - 1) +- +-void aes_ccm_128_init(struct aes_ccm_128_context *ctx, +- const uint8_t K[AES_BLOCK_SIZE], +- const uint8_t N[AES_CCM_128_NONCE_SIZE], +- size_t a_total, size_t m_total) +-{ +- ZERO_STRUCTP(ctx); +- +- AES_set_encrypt_key(K, 128, &ctx->aes_key); +- memcpy(ctx->nonce, N, AES_CCM_128_NONCE_SIZE); +- ctx->a_remain = a_total; +- ctx->m_remain = m_total; +- +- /* +- * prepare B_0 +- */ +- ctx->B_i[0] = L_; +- ctx->B_i[0] += 8 * M_; +- if (a_total > 0) { +- ctx->B_i[0] += 64; +- } +- memcpy(&ctx->B_i[1], ctx->nonce, AES_CCM_128_NONCE_SIZE); +- RSIVAL(ctx->B_i, (AES_BLOCK_SIZE - AES_CCM_128_L), m_total); +- +- /* +- * prepare X_1 +- */ +- AES_encrypt(ctx->B_i, ctx->X_i, &ctx->aes_key); +- +- /* +- * prepare B_1 +- */ +- ZERO_STRUCT(ctx->B_i); +- if (a_total >= UINT32_MAX) { +- RSSVAL(ctx->B_i, 0, 0xFFFF); +- RSBVAL(ctx->B_i, 2, (uint64_t)a_total); +- ctx->B_i_ofs = 10; +- } else if (a_total >= 0xFF00) { +- RSSVAL(ctx->B_i, 0, 0xFFFE); +- RSIVAL(ctx->B_i, 2, a_total); +- ctx->B_i_ofs = 6; +- } else if (a_total > 0) { +- RSSVAL(ctx->B_i, 0, a_total); +- ctx->B_i_ofs = 2; +- } +- +- /* +- * prepare A_i +- */ +- ctx->A_i[0] = L_; +- memcpy(&ctx->A_i[1], ctx->nonce, AES_CCM_128_NONCE_SIZE); +- +- ctx->S_i_ofs = AES_BLOCK_SIZE; +-} +- +-void aes_ccm_128_update(struct aes_ccm_128_context *ctx, +- const uint8_t *v, size_t v_len) +-{ +- size_t *remain; +- +- if (v_len == 0) { +- return; +- } +- +- if (ctx->a_remain > 0) { +- remain = &ctx->a_remain; +- } else { +- remain = &ctx->m_remain; +- } +- +- if (unlikely(v_len > *remain)) { +- abort(); +- } +- +- if (ctx->B_i_ofs > 0) { +- size_t n = MIN(AES_BLOCK_SIZE - ctx->B_i_ofs, v_len); +- +- memcpy(&ctx->B_i[ctx->B_i_ofs], v, n); +- v += n; +- v_len -= n; +- ctx->B_i_ofs += n; +- *remain -= n; +- } +- +- if ((ctx->B_i_ofs == AES_BLOCK_SIZE) || (*remain == 0)) { +- aes_block_xor(ctx->X_i, ctx->B_i, ctx->B_i); +- AES_encrypt(ctx->B_i, ctx->X_i, &ctx->aes_key); +- ctx->B_i_ofs = 0; +- } +- +- while (v_len >= AES_BLOCK_SIZE) { +- aes_block_xor(ctx->X_i, v, ctx->B_i); +- AES_encrypt(ctx->B_i, ctx->X_i, &ctx->aes_key); +- v += AES_BLOCK_SIZE; +- v_len -= AES_BLOCK_SIZE; +- *remain -= AES_BLOCK_SIZE; +- } +- +- if (v_len > 0) { +- ZERO_STRUCT(ctx->B_i); +- memcpy(ctx->B_i, v, v_len); +- ctx->B_i_ofs += v_len; +- *remain -= v_len; +- v = NULL; +- v_len = 0; +- } +- +- if (*remain > 0) { +- return; +- } +- +- if (ctx->B_i_ofs > 0) { +- aes_block_xor(ctx->X_i, ctx->B_i, ctx->B_i); +- AES_encrypt(ctx->B_i, ctx->X_i, &ctx->aes_key); +- ctx->B_i_ofs = 0; +- } +-} +- +-static inline void aes_ccm_128_S_i(struct aes_ccm_128_context *ctx, +- uint8_t S_i[AES_BLOCK_SIZE], +- size_t i) +-{ +- RSIVAL(ctx->A_i, (AES_BLOCK_SIZE - AES_CCM_128_L), i); +- AES_encrypt(ctx->A_i, S_i, &ctx->aes_key); +-} +- +-void aes_ccm_128_crypt(struct aes_ccm_128_context *ctx, +- uint8_t *m, size_t m_len) +-{ +- while (m_len > 0) { +- if (ctx->S_i_ofs == AES_BLOCK_SIZE) { +- ctx->S_i_ctr += 1; +- aes_ccm_128_S_i(ctx, ctx->S_i, ctx->S_i_ctr); +- ctx->S_i_ofs = 0; +- } +- +- if (likely(ctx->S_i_ofs == 0 && m_len >= AES_BLOCK_SIZE)) { +- aes_block_xor(m, ctx->S_i, m); +- m += AES_BLOCK_SIZE; +- m_len -= AES_BLOCK_SIZE; +- ctx->S_i_ctr += 1; +- aes_ccm_128_S_i(ctx, ctx->S_i, ctx->S_i_ctr); +- continue; +- } +- +- m[0] ^= ctx->S_i[ctx->S_i_ofs]; +- m += 1; +- m_len -= 1; +- ctx->S_i_ofs += 1; +- } +-} +- +-void aes_ccm_128_digest(struct aes_ccm_128_context *ctx, +- uint8_t digest[AES_BLOCK_SIZE]) +-{ +- if (unlikely(ctx->a_remain != 0)) { +- abort(); +- } +- if (unlikely(ctx->m_remain != 0)) { +- abort(); +- } +- +- /* prepare S_0 */ +- aes_ccm_128_S_i(ctx, ctx->S_i, 0); +- +- /* +- * note X_i is T here +- */ +- aes_block_xor(ctx->X_i, ctx->S_i, digest); +- +- ZERO_STRUCTP(ctx); +-} +diff --git a/lib/crypto/aes_ccm_128.h b/lib/crypto/aes_ccm_128.h +deleted file mode 100644 +index 1382ee704b9..00000000000 +--- a/lib/crypto/aes_ccm_128.h ++++ /dev/null +@@ -1,58 +0,0 @@ +-/* +- AES-CCM-128 (rfc 3610) +- +- Copyright (C) Stefan Metzmacher 2012 +- +- This program is free software; you can redistribute it and/or modify +- it under the terms of the GNU General Public License as published by +- the Free Software Foundation; either version 3 of the License, or +- (at your option) any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- GNU General Public License for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program. If not, see . +-*/ +- +-#ifndef LIB_CRYPTO_AES_CCM_128_H +-#define LIB_CRYPTO_AES_CCM_128_H +- +-#define AES_CCM_128_M 16 +-#define AES_CCM_128_L 4 +-#define AES_CCM_128_NONCE_SIZE (15 - AES_CCM_128_L) +- +-struct aes_ccm_128_context { +- AES_KEY aes_key; +- +- uint8_t nonce[AES_CCM_128_NONCE_SIZE]; +- +- size_t a_remain; +- size_t m_remain; +- +- uint64_t __align; +- +- uint8_t X_i[AES_BLOCK_SIZE]; +- uint8_t B_i[AES_BLOCK_SIZE]; +- uint8_t A_i[AES_BLOCK_SIZE]; +- uint8_t S_i[AES_BLOCK_SIZE]; +- +- size_t B_i_ofs; +- size_t S_i_ofs; +- size_t S_i_ctr; +-}; +- +-void aes_ccm_128_init(struct aes_ccm_128_context *ctx, +- const uint8_t K[AES_BLOCK_SIZE], +- const uint8_t N[AES_CCM_128_NONCE_SIZE], +- size_t a_total, size_t m_total); +-void aes_ccm_128_update(struct aes_ccm_128_context *ctx, +- const uint8_t *v, size_t v_len); +-void aes_ccm_128_crypt(struct aes_ccm_128_context *ctx, +- uint8_t *m, size_t m_len); +-void aes_ccm_128_digest(struct aes_ccm_128_context *ctx, +- uint8_t digest[AES_BLOCK_SIZE]); +- +-#endif /* LIB_CRYPTO_AES_CCM_128_H */ +diff --git a/lib/crypto/aes_ccm_128_test.c b/lib/crypto/aes_ccm_128_test.c +deleted file mode 100644 +index 67745e3e1ae..00000000000 +--- a/lib/crypto/aes_ccm_128_test.c ++++ /dev/null +@@ -1,377 +0,0 @@ +-/* +- AES-CCM-128 tests +- +- Copyright (C) Stefan Metzmacher 2015 +- +- This program is free software; you can redistribute it and/or modify +- it under the terms of the GNU General Public License as published by +- the Free Software Foundation; either version 3 of the License, or +- (at your option) any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- GNU General Public License for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program. If not, see . +-*/ +-#include "replace.h" +-#include "../lib/util/samba_util.h" +-#include "lib/crypto/aes.h" +-#include "lib/crypto/aes_ccm_128.h" +-#include "lib/crypto/aes_test.h" +- +-#ifndef AES_CCM_128_ONLY_TESTVECTORS +-struct torture_context; +-bool torture_local_crypto_aes_ccm_128(struct torture_context *torture); +- +-/* +- This uses our own test values as we rely on a 11 byte nonce +- and the values from rfc rfc3610 use 13 byte nonce. +-*/ +-bool torture_local_crypto_aes_ccm_128(struct torture_context *tctx) +-{ +- bool ret = true; +- uint32_t i; +- struct aes_mode_testvector testarray[] = { +-#endif /* AES_CCM_128_ONLY_TESTVECTORS */ +-#define AES_CCM_128_TESTVECTOR(_k, _n, _a, _p, _c, _t) \ +- AES_MODE_TESTVECTOR(aes_ccm_128, _k, _n, _a, _p, _c, _t) +- +- AES_CCM_128_TESTVECTOR( +- /* K */ +- "8BF9FBC2B8149484FF11AB1F3A544FF6", +- /* N */ +- "010000000000000077F7A8", +- /* A */ +- "010000000000000077F7A80000000000" +- "A8000000000001004100002C00980000", +- /* P */ +- "FE534D4240000100000000000B00811F" +- "00000000000000000600000000000000" +- "00000000010000004100002C00980000" +- "00000000000000000000000000000000" +- "3900000094010600FFFFFFFFFFFFFFFF" +- "FFFFFFFFFFFFFFFF7800000030000000" +- "000000007800000000000000FFFF0000" +- "0100000000000000" +- "03005C003100370032002E0033003100" +- "2E0039002E003100380033005C006E00" +- "650074006C006F0067006F006E000000", +- /* C */ +- "25985364BF9AF90EB0B9C8FB55B7C446" +- "780F310F1EC4677726BFBF34E38E6408" +- "057EE228814F11CBAAB794A79F7A1F78" +- "2DE73B7477985360A02D35A7A347ABF7" +- "9F18DD8687767423BB08F18642B6EFEE" +- "8B1543D83091AF5952F58BB4BD89FF6B" +- "0206E7170481C7BC61F06653D0CF10F7" +- "C78380389382C276" +- "7B8BF34D687A5C3D4F783F926F7755C0" +- "2D44C30848C69CFDD8E54395F1881611" +- "E5502285870A7179068923105190C837", +- /* T */ +- "3C11F652F8EA5600C8607D2E0FEAFD42" +- ), +- AES_CCM_128_TESTVECTOR( +- /* K */ +- "f9fdca4ac64fe7f014de0f43039c7571", +- /* N */ +- "5a8aa485c316e947125478", +- /* A */ +- "3796cf51b8726652a4204733b8fbb047" +- "cf00fb91a9837e22ec22b1a268f88e2c", +- /* P */ +- "a265480ca88d5f536db0dc6abc40faf0" +- "d05be7a9669777682345647586786983", +- /* C */ +- "65F8D8422006FB77FB7CCEFDFFF93729" +- "B3EFCB06A0FAF3A2ABAB485723373F53", +- /* T */ +- "2C62BD82AD231887A7B326E1E045BC91" +- ), +- AES_CCM_128_TESTVECTOR( +- /* K */ +- "197afb02ffbd8f699dacae87094d5243", +- /* N */ +- "5a8aa485c316e947125478", +- /* A */ +- "", +- /* P */ +- "3796cf51b8726652a4204733b8fbb047" +- "cf00fb91a9837e22", +- /* C */ +- "CA53910394115C5DAB5D7250F04D6A27" +- "2BCFA4329528F3AC", +- /* T */ +- "38E3A318F9BA88D4DD2FAF3521820001" +- ), +- AES_CCM_128_TESTVECTOR( +- /* K */ +- "90929a4b0ac65b350ad1591611fe4829", +- /* N */ +- "5a8aa485c316e9403aff85", +- /* A */ +- "", +- /* P */ +- "a16a2e741f1cd9717285b6d882c1fc53" +- "655e9773761ad697", +- /* C */ +- "ACA5E98D2784D131AE76E3C8BF9C3988" +- "35C0206C71893F26", +- /* T */ +- "AE67C0EA38C5383BFDC7967F4E9D1678" +- ), +- AES_CCM_128_TESTVECTOR( +- /* K */ +- "f9fdca4ac64fe7f014de0f43039c7571", +- /* N */ +- "5a8aa485c316e947125478", +- /* A */ +- "3796cf51b8726652a4204733b8fbb047" +- "cf00fb91a9837e22ec22b1a268f88e2c", +- /* P */ +- "a265480ca88d5f536db0dc6abc40faf0" +- "d05be7a966977768", +- /* C */ +- "65F8D8422006FB77FB7CCEFDFFF93729" +- "B3EFCB06A0FAF3A2", +- /* T */ +- "03C6E244586AFAB9B60D9F6DBDF7EB1A" +- ), +- AES_CCM_128_TESTVECTOR( +- /* K */ +- "26511fb51fcfa75cb4b44da75a6e5a0e", +- /* N */ +- "5a8aa485c316e9403aff85", +- /* A */ +- "a16a2e741f1cd9717285b6d882c1fc53" +- "655e9773761ad697a7ee6410184c7982", +- /* P */ +- "8739b4bea1a099fe547499cbc6d1b13d" +- "849b8084c9b6acc5", +- /* C */ +- "D31F9FC23674D5272125375E0A2F5365" +- "41B1FAF1DD68C819", +- /* T */ +- "4F315233A76C4DD99972561C5158AB3B" +- ), +- AES_CCM_128_TESTVECTOR( +- /* K */ +- "f9fdca4ac64fe7f014de0f43039c7571", +- /* N */ +- "5a8aa485c316e947125478", +- /* A */ +- "3796cf51b8726652a4204733b8fbb047" +- "cf00fb91a9837e22ec22b1a268", +- /* P */ +- "a265480ca88d5f536db0dc6abc40faf0" +- "d05be7a9669777682376345745", +- /* C */ +- "65F8D8422006FB77FB7CCEFDFFF93729" +- "B3EFCB06A0FAF3A2AB981875E0", +- /* T */ +- "EA93AAEDA607226E9E79D2EE5C4B62F8" +- ), +- AES_CCM_128_TESTVECTOR( +- /* K */ +- "26511fb51fcfa75cb4b44da75a6e5a0e", +- /* N */ +- "5a8aa485c316e9403aff85", +- /* A */ +- "a16a2e741f1cd9717285b6d882c1fc53" +- "65", +- /* P */ +- "8739b4bea1a099fe547499cbc6d1b13d" +- "84", +- /* C */ +- "D31F9FC23674D5272125375E0A2F5365" +- "41", +- /* T */ +- "036F58DA2372B29BD0E01C58A0E7F9EE" +- ), +- AES_CCM_128_TESTVECTOR( +- /* K */ +- "00000000000000000000000000000000", +- /* N */ +- "0000000000000000000000", +- /* A */ +- "", +- /* P */ +- "00", +- /* C */ +- "2E", +- /* T */ +- "61787D2C432A58293B73D01154E61B6B" +- ), +- AES_CCM_128_TESTVECTOR( +- /* K */ +- "00000000000000000000000000000000", +- /* N */ +- "0000000000000000000000", +- /* A */ +- "00", +- /* P */ +- "00", +- /* C */ +- "2E", +- /* T */ +- "E4284A0E813F0FFA146CF59F9ADAFBD7" +- ), +-#ifndef AES_CCM_128_ONLY_TESTVECTORS +- }; +- +- for (i=0; i < ARRAY_SIZE(testarray); i++) { +- struct aes_ccm_128_context ctx; +- uint8_t T[AES_BLOCK_SIZE]; +- DATA_BLOB _T = data_blob_const(T, sizeof(T)); +- DATA_BLOB C; +- int e; +- +- C = data_blob_dup_talloc(tctx, testarray[i].P); +- +- aes_ccm_128_init(&ctx, testarray[i].K.data, testarray[i].N.data, +- testarray[i].A.length, testarray[i].P.length); +- aes_ccm_128_update(&ctx, +- testarray[i].A.data, +- testarray[i].A.length); +- aes_ccm_128_update(&ctx, C.data, C.length); +- aes_ccm_128_crypt(&ctx, C.data, C.length); +- aes_ccm_128_digest(&ctx, T); +- +- e = memcmp(testarray[i].T.data, T, sizeof(T)); +- if (e != 0) { +- aes_mode_testvector_debug(&testarray[i], NULL, &C, &_T); +- ret = false; +- goto fail; +- } +- +- e = memcmp(testarray[i].C.data, C.data, C.length); +- if (e != 0) { +- aes_mode_testvector_debug(&testarray[i], NULL, &C, &_T); +- ret = false; +- goto fail; +- } +- } +- +- for (i=0; i < ARRAY_SIZE(testarray); i++) { +- struct aes_ccm_128_context ctx; +- uint8_t T[AES_BLOCK_SIZE]; +- DATA_BLOB _T = data_blob_const(T, sizeof(T)); +- DATA_BLOB C; +- int e; +- size_t j; +- +- C = data_blob_dup_talloc(tctx, testarray[i].P); +- +- aes_ccm_128_init(&ctx, testarray[i].K.data, testarray[i].N.data, +- testarray[i].A.length, testarray[i].P.length); +- for (j=0; j < testarray[i].A.length; j++) { +- aes_ccm_128_update(&ctx, NULL, 0); +- aes_ccm_128_update(&ctx, &testarray[i].A.data[j], 1); +- aes_ccm_128_update(&ctx, NULL, 0); +- } +- for (j=0; j < C.length; j++) { +- aes_ccm_128_crypt(&ctx, NULL, 0); +- aes_ccm_128_update(&ctx, NULL, 0); +- aes_ccm_128_update(&ctx, &C.data[j], 1); +- aes_ccm_128_crypt(&ctx, &C.data[j], 1); +- aes_ccm_128_crypt(&ctx, NULL, 0); +- aes_ccm_128_update(&ctx, NULL, 0); +- } +- aes_ccm_128_digest(&ctx, T); +- +- e = memcmp(testarray[i].T.data, T, sizeof(T)); +- if (e != 0) { +- aes_mode_testvector_debug(&testarray[i], NULL, &C, &_T); +- ret = false; +- goto fail; +- } +- +- e = memcmp(testarray[i].C.data, C.data, C.length); +- if (e != 0) { +- aes_mode_testvector_debug(&testarray[i], NULL, &C, &_T); +- ret = false; +- goto fail; +- } +- } +- +- for (i=0; i < ARRAY_SIZE(testarray); i++) { +- struct aes_ccm_128_context ctx; +- uint8_t T[AES_BLOCK_SIZE]; +- DATA_BLOB _T = data_blob_const(T, sizeof(T)); +- DATA_BLOB P; +- int e; +- size_t j; +- +- P = data_blob_dup_talloc(tctx, testarray[i].C); +- +- aes_ccm_128_init(&ctx, testarray[i].K.data, testarray[i].N.data, +- testarray[i].A.length, testarray[i].P.length); +- for (j=0; j < testarray[i].A.length; j++) { +- aes_ccm_128_update(&ctx, NULL, 0); +- aes_ccm_128_update(&ctx, &testarray[i].A.data[j], 1); +- aes_ccm_128_update(&ctx, NULL, 0); +- } +- for (j=0; j < P.length; j++) { +- aes_ccm_128_crypt(&ctx, NULL, 0); +- aes_ccm_128_update(&ctx, NULL, 0); +- aes_ccm_128_crypt(&ctx, &P.data[j], 1); +- aes_ccm_128_update(&ctx, &P.data[j], 1); +- aes_ccm_128_crypt(&ctx, NULL, 0); +- aes_ccm_128_update(&ctx, NULL, 0); +- } +- aes_ccm_128_digest(&ctx, T); +- +- e = memcmp(testarray[i].T.data, T, sizeof(T)); +- if (e != 0) { +- aes_mode_testvector_debug(&testarray[i], &P, NULL, &_T); +- ret = false; +- goto fail; +- } +- +- e = memcmp(testarray[i].P.data, P.data, P.length); +- if (e != 0) { +- aes_mode_testvector_debug(&testarray[i], &P, NULL, &_T); +- ret = false; +- goto fail; +- } +- } +- +- for (i=0; i < ARRAY_SIZE(testarray); i++) { +- struct aes_ccm_128_context ctx; +- uint8_t T[AES_BLOCK_SIZE]; +- DATA_BLOB _T = data_blob_const(T, sizeof(T)); +- DATA_BLOB P; +- int e; +- +- P = data_blob_dup_talloc(tctx, testarray[i].C); +- +- aes_ccm_128_init(&ctx, testarray[i].K.data, testarray[i].N.data, +- testarray[i].A.length, testarray[i].P.length); +- aes_ccm_128_update(&ctx, testarray[i].A.data, testarray[i].A.length); +- aes_ccm_128_crypt(&ctx, P.data, P.length); +- aes_ccm_128_update(&ctx, P.data, P.length); +- aes_ccm_128_digest(&ctx, T); +- +- e = memcmp(testarray[i].T.data, T, sizeof(T)); +- if (e != 0) { +- aes_mode_testvector_debug(&testarray[i], &P, NULL, &_T); +- ret = false; +- goto fail; +- } +- +- e = memcmp(testarray[i].P.data, P.data, P.length); +- if (e != 0) { +- aes_mode_testvector_debug(&testarray[i], &P, NULL, &_T); +- ret = false; +- goto fail; +- } +- } +- +- fail: +- return ret; +-} +- +-#endif /* AES_CCM_128_ONLY_TESTVECTORS */ +diff --git a/lib/crypto/crypto.h b/lib/crypto/crypto.h +index d7409f9a46d..66767935925 100644 +--- a/lib/crypto/crypto.h ++++ b/lib/crypto/crypto.h +@@ -23,7 +23,6 @@ + #include "../lib/crypto/md4.h" + #include "../lib/crypto/aes.h" + #include "../lib/crypto/aes_cmac_128.h" +-#include "../lib/crypto/aes_ccm_128.h" + #include "../lib/crypto/aes_gcm_128.h" + + #endif /* _SAMBA_CRYPTO_H_ */ +diff --git a/lib/crypto/wscript_build b/lib/crypto/wscript_build +index 4f1665a7fd9..a019ebe60cf 100644 +--- a/lib/crypto/wscript_build ++++ b/lib/crypto/wscript_build +@@ -12,10 +12,6 @@ bld.SAMBA_SUBSYSTEM('GNUTLS_HELPERS', + ''', + deps='gnutls samba-errors'); + +-bld.SAMBA_SUBSYSTEM('LIBCRYPTO_AES_CCM', +- source='aes_ccm_128.c', +- deps='talloc') +- + bld.SAMBA_SUBSYSTEM('LIBCRYPTO_AES_GCM', + source='aes_gcm_128.c', + deps='talloc') +@@ -36,16 +32,10 @@ bld.SAMBA_SUBSYSTEM('LIBCRYPTO', + deps=''' + talloc + LIBCRYPTO_AES +- LIBCRYPTO_AES_CCM + LIBCRYPTO_AES_GCM + LIBCRYPTO_AES_CMAC + ''' + extra_deps) + +-bld.SAMBA_SUBSYSTEM('TORTURE_LIBCRYPTO_AES_CCM', +- source='aes_ccm_128_test.c', +- autoproto='aes_ccm_test_proto.h', +- deps='talloc') +- + bld.SAMBA_SUBSYSTEM('TORTURE_LIBCRYPTO_AES_GCM', + source='aes_gcm_128_test.c', + autoproto='aes_gcm_test_proto.h', +@@ -62,7 +52,6 @@ bld.SAMBA_SUBSYSTEM('TORTURE_LIBCRYPTO', + autoproto='test_proto.h', + deps=''' + LIBCRYPTO +- TORTURE_LIBCRYPTO_AES_CCM + TORTURE_LIBCRYPTO_AES_GCM + TORTURE_LIBCRYPTO_AES_CMAC + ''') +diff --git a/source4/torture/local/local.c b/source4/torture/local/local.c +index 5812f4dd20c..8f9148b1988 100644 +--- a/source4/torture/local/local.c ++++ b/source4/torture/local/local.c +@@ -23,7 +23,6 @@ + #include "torture/ndr/proto.h" + #include "torture/auth/proto.h" + #include "../lib/crypto/test_proto.h" +-#include "../lib/crypto/aes_ccm_test_proto.h" + #include "../lib/crypto/aes_gcm_test_proto.h" + #ifndef HAVE_GNUTLS_AES_CMAC + #include "../lib/crypto/aes_cmac_test_proto.h" +@@ -100,8 +99,6 @@ NTSTATUS torture_local_init(TALLOC_CTX *ctx) + torture_suite_add_simple_test(suite, "crypto.aes_cmac_128", + torture_local_crypto_aes_cmac_128); + #endif +- torture_suite_add_simple_test(suite, "crypto.aes_ccm_128", +- torture_local_crypto_aes_ccm_128); + torture_suite_add_simple_test(suite, "crypto.aes_gcm_128", + torture_local_crypto_aes_gcm_128); + +-- +2.23.0 + diff --git a/SOURCES/0189-lib-crypto-Remove-our-implementation-of-AES-GCM.patch b/SOURCES/0189-lib-crypto-Remove-our-implementation-of-AES-GCM.patch new file mode 100644 index 0000000..deeba45 --- /dev/null +++ b/SOURCES/0189-lib-crypto-Remove-our-implementation-of-AES-GCM.patch @@ -0,0 +1,672 @@ +From 969dbe9f0cd3386a8188f2c42177433aaa9b8ff1 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Tue, 10 Dec 2019 18:01:43 +0100 +Subject: [PATCH 189/191] lib:crypto: Remove our implementation of AES GCM + +We require GnuTLS >= 3.4.7 which provides AES GCM. + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 337c51c9f503adef58c9b875bfb4f522cfb7d9ae) +--- + lib/crypto/aes_gcm_128.c | 208 ------------------------ + lib/crypto/aes_gcm_128.h | 55 ------- + lib/crypto/aes_gcm_128_test.c | 295 ---------------------------------- + lib/crypto/crypto.h | 1 - + lib/crypto/wscript_build | 11 -- + source4/torture/local/local.c | 3 - + 6 files changed, 573 deletions(-) + delete mode 100644 lib/crypto/aes_gcm_128.c + delete mode 100644 lib/crypto/aes_gcm_128.h + delete mode 100644 lib/crypto/aes_gcm_128_test.c + +diff --git a/lib/crypto/aes_gcm_128.c b/lib/crypto/aes_gcm_128.c +deleted file mode 100644 +index 6b5a385cbd8..00000000000 +--- a/lib/crypto/aes_gcm_128.c ++++ /dev/null +@@ -1,208 +0,0 @@ +-/* +- AES-GCM-128 +- +- Copyright (C) Stefan Metzmacher 2014 +- +- This program is free software; you can redistribute it and/or modify +- it under the terms of the GNU General Public License as published by +- the Free Software Foundation; either version 3 of the License, or +- (at your option) any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- GNU General Public License for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program. If not, see . +-*/ +- +-#include "replace.h" +-#include "lib/crypto/aes.h" +-#include "lib/crypto/aes_gcm_128.h" +-#include "lib/util/byteorder.h" +- +-static inline void aes_gcm_128_inc32(uint8_t inout[AES_BLOCK_SIZE]) +-{ +- uint32_t v; +- +- v = RIVAL(inout, AES_BLOCK_SIZE - 4); +- v += 1; +- RSIVAL(inout, AES_BLOCK_SIZE - 4, v); +-} +- +-static inline void aes_gcm_128_mul(const uint8_t x[AES_BLOCK_SIZE], +- const uint8_t y[AES_BLOCK_SIZE], +- uint8_t v[AES_BLOCK_SIZE], +- uint8_t z[AES_BLOCK_SIZE]) +-{ +- uint8_t i; +- /* 11100001 || 0^120 */ +- static const uint8_t r[AES_BLOCK_SIZE] = { +- 0xE1, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, +- }; +- +- memset(z, 0, AES_BLOCK_SIZE); +- memcpy(v, y, AES_BLOCK_SIZE); +- +- for (i = 0; i < AES_BLOCK_SIZE; i++) { +- uint8_t mask; +- for (mask = 0x80; mask != 0 ; mask >>= 1) { +- uint8_t v_lsb = v[AES_BLOCK_SIZE-1] & 1; +- if (x[i] & mask) { +- aes_block_xor(z, v, z); +- } +- +- aes_block_rshift(v, v); +- if (v_lsb != 0) { +- aes_block_xor(v, r, v); +- } +- } +- } +-} +- +-static inline void aes_gcm_128_ghash_block(struct aes_gcm_128_context *ctx, +- const uint8_t in[AES_BLOCK_SIZE]) +-{ +- aes_block_xor(ctx->Y, in, ctx->y.block); +- aes_gcm_128_mul(ctx->y.block, ctx->H, ctx->v.block, ctx->Y); +-} +- +-void aes_gcm_128_init(struct aes_gcm_128_context *ctx, +- const uint8_t K[AES_BLOCK_SIZE], +- const uint8_t IV[AES_GCM_128_IV_SIZE]) +-{ +- ZERO_STRUCTP(ctx); +- +- AES_set_encrypt_key(K, 128, &ctx->aes_key); +- +- /* +- * Step 1: generate H (ctx->Y is the zero block here) +- */ +- AES_encrypt(ctx->Y, ctx->H, &ctx->aes_key); +- +- /* +- * Step 2: generate J0 +- */ +- memcpy(ctx->J0, IV, AES_GCM_128_IV_SIZE); +- aes_gcm_128_inc32(ctx->J0); +- +- /* +- * We need to prepare CB with J0. +- */ +- memcpy(ctx->CB, ctx->J0, AES_BLOCK_SIZE); +- ctx->c.ofs = AES_BLOCK_SIZE; +-} +- +-static inline void aes_gcm_128_update_tmp(struct aes_gcm_128_context *ctx, +- struct aes_gcm_128_tmp *tmp, +- const uint8_t *v, size_t v_len) +-{ +- tmp->total += v_len; +- +- if (tmp->ofs > 0) { +- size_t copy = MIN(AES_BLOCK_SIZE - tmp->ofs, v_len); +- +- memcpy(tmp->block + tmp->ofs, v, copy); +- tmp->ofs += copy; +- v += copy; +- v_len -= copy; +- } +- +- if (tmp->ofs == AES_BLOCK_SIZE) { +- aes_gcm_128_ghash_block(ctx, tmp->block); +- tmp->ofs = 0; +- } +- +- while (v_len >= AES_BLOCK_SIZE) { +- aes_gcm_128_ghash_block(ctx, v); +- v += AES_BLOCK_SIZE; +- v_len -= AES_BLOCK_SIZE; +- } +- +- if (v_len == 0) { +- return; +- } +- +- ZERO_STRUCT(tmp->block); +- memcpy(tmp->block, v, v_len); +- tmp->ofs = v_len; +-} +- +-void aes_gcm_128_updateA(struct aes_gcm_128_context *ctx, +- const uint8_t *a, size_t a_len) +-{ +- aes_gcm_128_update_tmp(ctx, &ctx->A, a, a_len); +-} +- +-void aes_gcm_128_updateC(struct aes_gcm_128_context *ctx, +- const uint8_t *c, size_t c_len) +-{ +- if (ctx->A.ofs > 0) { +- aes_gcm_128_ghash_block(ctx, ctx->A.block); +- ctx->A.ofs = 0; +- } +- +- aes_gcm_128_update_tmp(ctx, &ctx->C, c, c_len); +-} +- +-static inline void aes_gcm_128_crypt_tmp(struct aes_gcm_128_context *ctx, +- struct aes_gcm_128_tmp *tmp, +- uint8_t *m, size_t m_len) +-{ +- tmp->total += m_len; +- +- while (m_len > 0) { +- if (tmp->ofs == AES_BLOCK_SIZE) { +- aes_gcm_128_inc32(ctx->CB); +- AES_encrypt(ctx->CB, tmp->block, &ctx->aes_key); +- tmp->ofs = 0; +- } +- +- if (likely(tmp->ofs == 0 && m_len >= AES_BLOCK_SIZE)) { +- aes_block_xor(m, tmp->block, m); +- m += AES_BLOCK_SIZE; +- m_len -= AES_BLOCK_SIZE; +- aes_gcm_128_inc32(ctx->CB); +- AES_encrypt(ctx->CB, tmp->block, &ctx->aes_key); +- continue; +- } +- +- m[0] ^= tmp->block[tmp->ofs]; +- m += 1; +- m_len -= 1; +- tmp->ofs += 1; +- } +-} +- +-void aes_gcm_128_crypt(struct aes_gcm_128_context *ctx, +- uint8_t *m, size_t m_len) +-{ +- aes_gcm_128_crypt_tmp(ctx, &ctx->c, m, m_len); +-} +- +-void aes_gcm_128_digest(struct aes_gcm_128_context *ctx, +- uint8_t T[AES_BLOCK_SIZE]) +-{ +- if (ctx->A.ofs > 0) { +- aes_gcm_128_ghash_block(ctx, ctx->A.block); +- ctx->A.ofs = 0; +- } +- +- if (ctx->C.ofs > 0) { +- aes_gcm_128_ghash_block(ctx, ctx->C.block); +- ctx->C.ofs = 0; +- } +- +- RSBVAL(ctx->AC, 0, ctx->A.total * 8); +- RSBVAL(ctx->AC, 8, ctx->C.total * 8); +- aes_gcm_128_ghash_block(ctx, ctx->AC); +- +- AES_encrypt(ctx->J0, ctx->c.block, &ctx->aes_key); +- aes_block_xor(ctx->c.block, ctx->Y, T); +- +- ZERO_STRUCTP(ctx); +-} +diff --git a/lib/crypto/aes_gcm_128.h b/lib/crypto/aes_gcm_128.h +deleted file mode 100644 +index 8df11c2f6bd..00000000000 +--- a/lib/crypto/aes_gcm_128.h ++++ /dev/null +@@ -1,55 +0,0 @@ +-/* +- AES-GCM-128 +- +- Copyright (C) Stefan Metzmacher 2014 +- +- This program is free software; you can redistribute it and/or modify +- it under the terms of the GNU General Public License as published by +- the Free Software Foundation; either version 3 of the License, or +- (at your option) any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- GNU General Public License for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program. If not, see . +-*/ +- +-#ifndef LIB_CRYPTO_AES_GCM_128_H +-#define LIB_CRYPTO_AES_GCM_128_H +- +-#define AES_GCM_128_IV_SIZE (12) +- +-struct aes_gcm_128_context { +- AES_KEY aes_key; +- +- uint64_t __align; +- +- struct aes_gcm_128_tmp { +- size_t ofs; +- size_t total; +- uint8_t block[AES_BLOCK_SIZE]; +- } A, C, c, v, y; +- +- uint8_t H[AES_BLOCK_SIZE]; +- uint8_t J0[AES_BLOCK_SIZE]; +- uint8_t CB[AES_BLOCK_SIZE]; +- uint8_t Y[AES_BLOCK_SIZE]; +- uint8_t AC[AES_BLOCK_SIZE]; +-}; +- +-void aes_gcm_128_init(struct aes_gcm_128_context *ctx, +- const uint8_t K[AES_BLOCK_SIZE], +- const uint8_t IV[AES_GCM_128_IV_SIZE]); +-void aes_gcm_128_updateA(struct aes_gcm_128_context *ctx, +- const uint8_t *a, size_t a_len); +-void aes_gcm_128_updateC(struct aes_gcm_128_context *ctx, +- const uint8_t *c, size_t c_len); +-void aes_gcm_128_crypt(struct aes_gcm_128_context *ctx, +- uint8_t *m, size_t m_len); +-void aes_gcm_128_digest(struct aes_gcm_128_context *ctx, +- uint8_t T[AES_BLOCK_SIZE]); +- +-#endif /* LIB_CRYPTO_AES_GCM_128_H */ +diff --git a/lib/crypto/aes_gcm_128_test.c b/lib/crypto/aes_gcm_128_test.c +deleted file mode 100644 +index fdd87ff532d..00000000000 +--- a/lib/crypto/aes_gcm_128_test.c ++++ /dev/null +@@ -1,295 +0,0 @@ +-/* +- AES-GCM-128 tests +- +- Copyright (C) Stefan Metzmacher 2014 +- +- This program is free software; you can redistribute it and/or modify +- it under the terms of the GNU General Public License as published by +- the Free Software Foundation; either version 3 of the License, or +- (at your option) any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- GNU General Public License for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program. If not, see . +-*/ +-#include "replace.h" +-#include "../lib/util/samba_util.h" +-#include "lib/crypto/aes.h" +-#include "lib/crypto/aes_gcm_128.h" +-#include "lib/crypto/aes_test.h" +- +-#ifndef AES_GCM_128_ONLY_TESTVECTORS +-struct torture_context; +-bool torture_local_crypto_aes_gcm_128(struct torture_context *tctx); +- +-/* +- This uses the test values from ... +-*/ +-bool torture_local_crypto_aes_gcm_128(struct torture_context *tctx) +-{ +- bool ret = true; +- uint32_t i; +- struct aes_mode_testvector testarray[] = { +-#endif /* AES_GCM_128_ONLY_TESTVECTORS */ +-#define AES_GCM_128_TESTVECTOR(_k, _n, _a, _p, _c, _t) \ +- AES_MODE_TESTVECTOR(aes_gcm_128, _k, _n, _a, _p, _c, _t) +- +- AES_GCM_128_TESTVECTOR( +- /* K */ +- "8BF9FBC2B8149484FF11AB1F3A544FF6", +- /* N */ +- "010000000000000077F7A8FF", +- /* A */ +- "010000000000000077F7A80000000000" +- "A8000000000001004100002C00980000", +- /* P */ +- "FE534D4240000100000000000B00811F" +- "00000000000000000600000000000000" +- "00000000010000004100002C00980000" +- "00000000000000000000000000000000" +- "3900000094010600FFFFFFFFFFFFFFFF" +- "FFFFFFFFFFFFFFFF7800000030000000" +- "000000007800000000000000FFFF0000" +- "0100000000000000" +- "03005C003100370032002E0033003100" +- "2E0039002E003100380033005C006E00" +- "650074006C006F0067006F006E000000", +- /* C */ +- "863C07C1FBFA82D741A080C97DF52CFF" +- "432A63A37E5ACFA3865AE4E6E422D502" +- "FA7C6FBB9A7418F28C43F00A3869F687" +- "257CA665E25E62A0F458C42AA9E95DC4" +- "6CB351A0A497FABB7DCE58FEE5B20B08" +- "522E0E701B112FB93B36E7A0FB084D35" +- "62C0F3FDF0421079DD96BBCCA40949B3" +- "A7FC1AA635A72384" +- "2037DE3CA6385465D1884B29D7140790" +- "88AD3E770E2528D527B302536B7E5B1B" +- "430E048230AFE785DB89F4D87FC1F816", +- /* T */ +- "BC9B5871EBFA89ADE21439ACDCD65D22" +- ), +- AES_GCM_128_TESTVECTOR( +- /* K */ +- "00000000000000000000000000000000", +- /* N */ +- "000000000000000000000000", +- /* A */ +- "", +- /* P */ +- "", +- /* C */ +- "", +- /* T */ +- "58e2fccefa7e3061367f1d57a4e7455a" +- ), +- AES_GCM_128_TESTVECTOR( +- /* K */ +- "00000000000000000000000000000000", +- /* N */ +- "000000000000000000000000", +- /* A */ +- "", +- /* P */ +- "00000000000000000000000000000000", +- /* C */ +- "0388dace60b6a392f328c2b971b2fe78", +- /* T */ +- "ab6e47d42cec13bdf53a67b21257bddf" +- ), +- AES_GCM_128_TESTVECTOR( +- /* K */ +- "feffe9928665731c6d6a8f9467308308", +- /* N */ +- "cafebabefacedbaddecaf888", +- /* A */ +- "", +- /* P */ +- "d9313225f88406e5a55909c5aff5269a" +- "86a7a9531534f7da2e4c303d8a318a72" +- "1c3c0c95956809532fcf0e2449a6b525" +- "b16aedf5aa0de657ba637b391aafd255", +- /* C */ +- "42831ec2217774244b7221b784d0d49c" +- "e3aa212f2c02a4e035c17e2329aca12e" +- "21d514b25466931c7d8f6a5aac84aa05" +- "1ba30b396a0aac973d58e091473f5985", +- /* T */ +- "4d5c2af327cd64a62cf35abd2ba6fab4" +- ), +- AES_GCM_128_TESTVECTOR( +- /* K */ +- "feffe9928665731c6d6a8f9467308308", +- /* N */ +- "cafebabefacedbaddecaf888", +- /* A */ +- "feedfacedeadbeeffeedfacedeadbeef" +- "abaddad2", +- /* P */ +- "d9313225f88406e5a55909c5aff5269a" +- "86a7a9531534f7da2e4c303d8a318a72" +- "1c3c0c95956809532fcf0e2449a6b525" +- "b16aedf5aa0de657ba637b39", +- /* C */ +- "42831ec2217774244b7221b784d0d49c" +- "e3aa212f2c02a4e035c17e2329aca12e" +- "21d514b25466931c7d8f6a5aac84aa05" +- "1ba30b396a0aac973d58e091", +- /* T */ +- "5bc94fbc3221a5db94fae95ae7121a47" +- ), +-#ifndef AES_GCM_128_ONLY_TESTVECTORS +- }; +- +- for (i=0; i < ARRAY_SIZE(testarray); i++) { +- struct aes_gcm_128_context ctx; +- uint8_t T[AES_BLOCK_SIZE]; +- DATA_BLOB _T = data_blob_const(T, sizeof(T)); +- DATA_BLOB C; +- int e; +- +- C = data_blob_dup_talloc(tctx, testarray[i].P); +- +- aes_gcm_128_init(&ctx, testarray[i].K.data, testarray[i].N.data); +- aes_gcm_128_updateA(&ctx, +- testarray[i].A.data, +- testarray[i].A.length); +- aes_gcm_128_crypt(&ctx, C.data, C.length); +- aes_gcm_128_updateC(&ctx, C.data, C.length); +- aes_gcm_128_digest(&ctx, T); +- +- e = memcmp(testarray[i].T.data, T, sizeof(T)); +- if (e != 0) { +- aes_mode_testvector_debug(&testarray[i], NULL, &C, &_T); +- ret = false; +- goto fail; +- } +- +- e = memcmp(testarray[i].C.data, C.data, C.length); +- if (e != 0) { +- aes_mode_testvector_debug(&testarray[i], NULL, &C, &_T); +- ret = false; +- goto fail; +- } +- } +- +- for (i=0; i < ARRAY_SIZE(testarray); i++) { +- struct aes_gcm_128_context ctx; +- uint8_t T[AES_BLOCK_SIZE]; +- DATA_BLOB _T = data_blob_const(T, sizeof(T)); +- DATA_BLOB C; +- int e; +- size_t j; +- +- C = data_blob_dup_talloc(tctx, testarray[i].P); +- +- aes_gcm_128_init(&ctx, testarray[i].K.data, testarray[i].N.data); +- for (j=0; j < testarray[i].A.length; j++) { +- aes_gcm_128_updateA(&ctx, NULL, 0); +- aes_gcm_128_updateA(&ctx, &testarray[i].A.data[j], 1); +- aes_gcm_128_updateA(&ctx, NULL, 0); +- } +- for (j=0; j < C.length; j++) { +- aes_gcm_128_crypt(&ctx, NULL, 0); +- aes_gcm_128_updateC(&ctx, NULL, 0); +- aes_gcm_128_crypt(&ctx, &C.data[j], 1); +- aes_gcm_128_updateC(&ctx, &C.data[j], 1); +- aes_gcm_128_crypt(&ctx, NULL, 0); +- aes_gcm_128_updateC(&ctx, NULL, 0); +- } +- aes_gcm_128_digest(&ctx, T); +- +- e = memcmp(testarray[i].T.data, T, sizeof(T)); +- if (e != 0) { +- aes_mode_testvector_debug(&testarray[i], NULL, &C, &_T); +- ret = false; +- goto fail; +- } +- +- e = memcmp(testarray[i].C.data, C.data, C.length); +- if (e != 0) { +- aes_mode_testvector_debug(&testarray[i], NULL, &C, &_T); +- ret = false; +- goto fail; +- } +- } +- +- for (i=0; i < ARRAY_SIZE(testarray); i++) { +- struct aes_gcm_128_context ctx; +- uint8_t T[AES_BLOCK_SIZE]; +- DATA_BLOB _T = data_blob_const(T, sizeof(T)); +- DATA_BLOB P; +- int e; +- size_t j; +- +- P = data_blob_dup_talloc(tctx, testarray[i].C); +- +- aes_gcm_128_init(&ctx, testarray[i].K.data, testarray[i].N.data); +- for (j=0; j < testarray[i].A.length; j++) { +- aes_gcm_128_updateA(&ctx, NULL, 0); +- aes_gcm_128_updateA(&ctx, &testarray[i].A.data[j], 1); +- aes_gcm_128_updateA(&ctx, NULL, 0); +- } +- for (j=0; j < P.length; j++) { +- aes_gcm_128_updateC(&ctx, NULL, 0); +- aes_gcm_128_crypt(&ctx, NULL, 0); +- aes_gcm_128_updateC(&ctx, &P.data[j], 1); +- aes_gcm_128_crypt(&ctx, &P.data[j], 1); +- aes_gcm_128_updateC(&ctx, NULL, 0); +- aes_gcm_128_crypt(&ctx, NULL, 0); +- } +- aes_gcm_128_digest(&ctx, T); +- +- e = memcmp(testarray[i].T.data, T, sizeof(T)); +- if (e != 0) { +- aes_mode_testvector_debug(&testarray[i], &P, NULL, &_T); +- ret = false; +- goto fail; +- } +- +- e = memcmp(testarray[i].P.data, P.data, P.length); +- if (e != 0) { +- aes_mode_testvector_debug(&testarray[i], &P, NULL, &_T); +- ret = false; +- goto fail; +- } +- } +- +- for (i=0; i < ARRAY_SIZE(testarray); i++) { +- struct aes_gcm_128_context ctx; +- uint8_t T[AES_BLOCK_SIZE]; +- DATA_BLOB _T = data_blob_const(T, sizeof(T)); +- DATA_BLOB P; +- int e; +- +- P = data_blob_dup_talloc(tctx, testarray[i].C); +- +- aes_gcm_128_init(&ctx, testarray[i].K.data, testarray[i].N.data); +- aes_gcm_128_updateA(&ctx, testarray[i].A.data, testarray[i].A.length); +- aes_gcm_128_updateC(&ctx, P.data, P.length); +- aes_gcm_128_crypt(&ctx, P.data, P.length); +- aes_gcm_128_digest(&ctx, T); +- +- e = memcmp(testarray[i].T.data, T, sizeof(T)); +- if (e != 0) { +- aes_mode_testvector_debug(&testarray[i], &P, NULL, &_T); +- ret = false; +- goto fail; +- } +- +- e = memcmp(testarray[i].P.data, P.data, P.length); +- if (e != 0) { +- aes_mode_testvector_debug(&testarray[i], &P, NULL, &_T); +- ret = false; +- goto fail; +- } +- } +- +- fail: +- return ret; +-} +-#endif /* AES_GCM_128_ONLY_TESTVECTORS */ +diff --git a/lib/crypto/crypto.h b/lib/crypto/crypto.h +index 66767935925..d8f13f8fadd 100644 +--- a/lib/crypto/crypto.h ++++ b/lib/crypto/crypto.h +@@ -23,6 +23,5 @@ + #include "../lib/crypto/md4.h" + #include "../lib/crypto/aes.h" + #include "../lib/crypto/aes_cmac_128.h" +-#include "../lib/crypto/aes_gcm_128.h" + + #endif /* _SAMBA_CRYPTO_H_ */ +diff --git a/lib/crypto/wscript_build b/lib/crypto/wscript_build +index a019ebe60cf..cd136165a0d 100644 +--- a/lib/crypto/wscript_build ++++ b/lib/crypto/wscript_build +@@ -12,10 +12,6 @@ bld.SAMBA_SUBSYSTEM('GNUTLS_HELPERS', + ''', + deps='gnutls samba-errors'); + +-bld.SAMBA_SUBSYSTEM('LIBCRYPTO_AES_GCM', +- source='aes_gcm_128.c', +- deps='talloc') +- + bld.SAMBA_SUBSYSTEM('LIBCRYPTO_AES', + source='aes.c rijndael-alg-fst.c', + deps='talloc') +@@ -32,15 +28,9 @@ bld.SAMBA_SUBSYSTEM('LIBCRYPTO', + deps=''' + talloc + LIBCRYPTO_AES +- LIBCRYPTO_AES_GCM + LIBCRYPTO_AES_CMAC + ''' + extra_deps) + +-bld.SAMBA_SUBSYSTEM('TORTURE_LIBCRYPTO_AES_GCM', +- source='aes_gcm_128_test.c', +- autoproto='aes_gcm_test_proto.h', +- deps='talloc') +- + bld.SAMBA_SUBSYSTEM('TORTURE_LIBCRYPTO_AES_CMAC', + source='aes_cmac_128_test.c', + autoproto='aes_cmac_test_proto.h', +@@ -52,7 +42,6 @@ bld.SAMBA_SUBSYSTEM('TORTURE_LIBCRYPTO', + autoproto='test_proto.h', + deps=''' + LIBCRYPTO +- TORTURE_LIBCRYPTO_AES_GCM + TORTURE_LIBCRYPTO_AES_CMAC + ''') + +diff --git a/source4/torture/local/local.c b/source4/torture/local/local.c +index 8f9148b1988..cd20b1691f5 100644 +--- a/source4/torture/local/local.c ++++ b/source4/torture/local/local.c +@@ -23,7 +23,6 @@ + #include "torture/ndr/proto.h" + #include "torture/auth/proto.h" + #include "../lib/crypto/test_proto.h" +-#include "../lib/crypto/aes_gcm_test_proto.h" + #ifndef HAVE_GNUTLS_AES_CMAC + #include "../lib/crypto/aes_cmac_test_proto.h" + #endif +@@ -99,8 +98,6 @@ NTSTATUS torture_local_init(TALLOC_CTX *ctx) + torture_suite_add_simple_test(suite, "crypto.aes_cmac_128", + torture_local_crypto_aes_cmac_128); + #endif +- torture_suite_add_simple_test(suite, "crypto.aes_gcm_128", +- torture_local_crypto_aes_gcm_128); + + for (i = 0; suite_generators[i]; i++) + torture_suite_add_suite(suite, +-- +2.23.0 + diff --git a/SOURCES/0190-lib-crypto-Only-build-AES-code-if-we-need-AES-CMAC.patch b/SOURCES/0190-lib-crypto-Only-build-AES-code-if-we-need-AES-CMAC.patch new file mode 100644 index 0000000..0051222 --- /dev/null +++ b/SOURCES/0190-lib-crypto-Only-build-AES-code-if-we-need-AES-CMAC.patch @@ -0,0 +1,29 @@ +From bc018d1b01ae605472b83b9b6a5c0206830b49da Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Tue, 10 Dec 2019 18:03:57 +0100 +Subject: [PATCH 190/191] lib:crypto: Only build AES code if we need AES CMAC + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett +(cherry picked from commit 6713617724bfe4cba633f0e61052a703c4ca9f3e) +--- + lib/crypto/wscript_build | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/lib/crypto/wscript_build b/lib/crypto/wscript_build +index cd136165a0d..46ae5e9ba80 100644 +--- a/lib/crypto/wscript_build ++++ b/lib/crypto/wscript_build +@@ -14,7 +14,8 @@ bld.SAMBA_SUBSYSTEM('GNUTLS_HELPERS', + + bld.SAMBA_SUBSYSTEM('LIBCRYPTO_AES', + source='aes.c rijndael-alg-fst.c', +- deps='talloc') ++ deps='talloc', ++ enabled=not bld.CONFIG_SET('HAVE_GNUTLS_AES_CMAC')) + + bld.SAMBA_SUBSYSTEM('LIBCRYPTO_AES_CMAC', + source='aes_cmac_128.c', +-- +2.23.0 + diff --git a/SOURCES/0191-lib-crypto-Build-intel-aes-ni-only-if-GnuTLS-doesn-t.patch b/SOURCES/0191-lib-crypto-Build-intel-aes-ni-only-if-GnuTLS-doesn-t.patch new file mode 100644 index 0000000..7e1dd16 --- /dev/null +++ b/SOURCES/0191-lib-crypto-Build-intel-aes-ni-only-if-GnuTLS-doesn-t.patch @@ -0,0 +1,49 @@ +From 2d058fe332a9aae11607a86c349aee33fa580542 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Tue, 10 Dec 2019 18:06:29 +0100 +Subject: [PATCH 191/191] lib:crypto: Build intel aes-ni only if GnuTLS doesn't + provide AES CMAC + +Signed-off-by: Andreas Schneider +Reviewed-by: Andrew Bartlett + +Autobuild-User(master): Andreas Schneider +Autobuild-Date(master): Tue Dec 10 20:30:57 UTC 2019 on sn-devel-184 + +(cherry picked from commit 20b9cae63d5a5881cc6100a2533fab683cc307aa) +--- + lib/crypto/wscript_build | 3 ++- + third_party/aesni-intel/wscript | 3 ++- + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/lib/crypto/wscript_build b/lib/crypto/wscript_build +index 46ae5e9ba80..eb67af63f26 100644 +--- a/lib/crypto/wscript_build ++++ b/lib/crypto/wscript_build +@@ -2,7 +2,8 @@ + + extra_deps = '' + +-if bld.CONFIG_SET("HAVE_AESNI_INTEL"): ++if (bld.CONFIG_SET("HAVE_AESNI_INTEL") and ++ not bld.CONFIG_SET('HAVE_GNUTLS_AES_CMAC')): + extra_deps += ' aesni-intel' + + bld.SAMBA_SUBSYSTEM('GNUTLS_HELPERS', +diff --git a/third_party/aesni-intel/wscript b/third_party/aesni-intel/wscript +index 955b5162140..382b3c6a7ff 100644 +--- a/third_party/aesni-intel/wscript ++++ b/third_party/aesni-intel/wscript +@@ -21,7 +21,8 @@ def configure(conf): + raise Errors.WafError('--accel-aes=intelaesni selected and linker rejects -z noexecstack') + + def build(bld): +- if not bld.CONFIG_SET('HAVE_AESNI_INTEL'): ++ if (not bld.CONFIG_SET('HAVE_AESNI_INTEL') or ++ bld.CONFIG_SET('HAVE_GNUTLS_AES_CMAC')): + return + + bld.SAMBA_LIBRARY('aesni-intel', +-- +2.23.0 + diff --git a/SOURCES/0192-lib-crypto-Add-samba_gnutls_weak_crypto.patch b/SOURCES/0192-lib-crypto-Add-samba_gnutls_weak_crypto.patch new file mode 100644 index 0000000..f0aa160 --- /dev/null +++ b/SOURCES/0192-lib-crypto-Add-samba_gnutls_weak_crypto.patch @@ -0,0 +1,98 @@ +From 3c64a236dfecbe396766ec0e8d326443358d4ab3 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Mon, 4 Nov 2019 17:01:50 +0100 +Subject: [PATCH 192/208] lib:crypto: Add samba_gnutls_weak_crypto() + +Signed-off-by: Andreas Schneider +--- + lib/crypto/gnutls_helpers.h | 7 +++++ + lib/crypto/gnutls_weak_crypto.c | 48 +++++++++++++++++++++++++++++++++ + lib/crypto/wscript_build | 1 + + 3 files changed, 56 insertions(+) + create mode 100644 lib/crypto/gnutls_weak_crypto.c + +diff --git a/lib/crypto/gnutls_helpers.h b/lib/crypto/gnutls_helpers.h +index d6000c7b316..a985c028e9d 100644 +--- a/lib/crypto/gnutls_helpers.h ++++ b/lib/crypto/gnutls_helpers.h +@@ -92,4 +92,11 @@ int samba_gnutls_arcfour_confounded_md5(const DATA_BLOB *key_input1, + DATA_BLOB *data, + enum samba_gnutls_direction encrypt); + ++/** ++ * @brief Check if weak crypto is allowed. ++ * ++ * @return true if weak crypo is allowed, false otherwise. ++ */ ++bool samba_gnutls_weak_crypto_allowed(void); ++ + #endif /* _GNUTLS_HELPERS_H */ +diff --git a/lib/crypto/gnutls_weak_crypto.c b/lib/crypto/gnutls_weak_crypto.c +new file mode 100644 +index 00000000000..68ce588243f +--- /dev/null ++++ b/lib/crypto/gnutls_weak_crypto.c +@@ -0,0 +1,48 @@ ++/* ++ * Copyright (c) 2019 Andreas Schneider ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see . ++ */ ++ ++#include "includes.h" ++#include "lib/crypto/gnutls_helpers.h" ++ ++#include ++#include ++ ++bool samba_gnutls_weak_crypto_allowed(void) ++{ ++ gnutls_cipher_hd_t cipher_hnd = NULL; ++ gnutls_datum_t key = { ++ .data = discard_const_p(unsigned char, "SystemLibraryDTC"), ++ .size = 16, ++ }; ++ int rc; ++ ++ /* ++ * If RC4 is not allowed to be initialzed then weak crypto is not ++ * allowed. ++ */ ++ rc = gnutls_cipher_init(&cipher_hnd, ++ GNUTLS_CIPHER_ARCFOUR_128, ++ &key, ++ NULL); ++ if (rc == GNUTLS_E_UNWANTED_ALGORITHM) { ++ return false; ++ } ++ ++ gnutls_cipher_deinit(cipher_hnd); ++ ++ return true; ++} +diff --git a/lib/crypto/wscript_build b/lib/crypto/wscript_build +index eb67af63f26..e5766042541 100644 +--- a/lib/crypto/wscript_build ++++ b/lib/crypto/wscript_build +@@ -10,6 +10,7 @@ bld.SAMBA_SUBSYSTEM('GNUTLS_HELPERS', + source=''' + gnutls_error.c + gnutls_arcfour_confounded_md5.c ++ gnutls_weak_crypto.c + ''', + deps='gnutls samba-errors'); + +-- +2.23.0 + diff --git a/SOURCES/0193-s3-utils-Add-weak-crypto-information-to-testparm.patch b/SOURCES/0193-s3-utils-Add-weak-crypto-information-to-testparm.patch new file mode 100644 index 0000000..3057803 --- /dev/null +++ b/SOURCES/0193-s3-utils-Add-weak-crypto-information-to-testparm.patch @@ -0,0 +1,60 @@ +From 067a5405a729c6d3b91a30ab0f16c0fa10db0498 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Mon, 4 Nov 2019 17:26:48 +0100 +Subject: [PATCH 193/208] s3:utils: Add weak crypto information to testparm + +Signed-off-by: Andreas Schneider +--- + source3/utils/testparm.c | 9 +++++++++ + source3/utils/wscript_build | 1 + + 2 files changed, 10 insertions(+) + +diff --git a/source3/utils/testparm.c b/source3/utils/testparm.c +index f4e94b6ef74..c5001e01679 100644 +--- a/source3/utils/testparm.c ++++ b/source3/utils/testparm.c +@@ -35,6 +35,7 @@ + #include "system/filesys.h" + #include "popt_common.h" + #include "lib/param/loadparm.h" ++#include "lib/crypto/gnutls_helpers.h" + #include "cmdline_contexts.h" + + #include +@@ -647,6 +648,7 @@ static void do_per_share_checks(int s) + const char *caddr; + static int show_defaults; + static int skip_logic_checks = 0; ++ const char *weak_crypo_str = ""; + + struct poptOption long_options[] = { + POPT_AUTOHELP +@@ -752,6 +754,13 @@ static void do_per_share_checks(int s) + + fprintf(stderr,"Loaded services file OK.\n"); + ++ if (samba_gnutls_weak_crypto_allowed()) { ++ weak_crypo_str = "allowed"; ++ } else { ++ weak_crypo_str = "disallowed"; ++ } ++ fprintf(stderr, "Weak crypto is %s\n", weak_crypo_str); ++ + if (skip_logic_checks == 0) { + ret = do_global_checks(); + } +diff --git a/source3/utils/wscript_build b/source3/utils/wscript_build +index 9d9aa56bf37..618cc955647 100644 +--- a/source3/utils/wscript_build ++++ b/source3/utils/wscript_build +@@ -175,6 +175,7 @@ bld.SAMBA3_BINARY('testparm', + smbconf + popt_samba3 + cmdline_contexts ++ GNUTLS_HELPERS + ''') + + bld.SAMBA3_BINARY('net', +-- +2.23.0 + diff --git a/SOURCES/0194-lib-param-Add-lp-cfg-_weak_crypto.patch b/SOURCES/0194-lib-param-Add-lp-cfg-_weak_crypto.patch new file mode 100644 index 0000000..841c77e --- /dev/null +++ b/SOURCES/0194-lib-param-Add-lp-cfg-_weak_crypto.patch @@ -0,0 +1,139 @@ +From fa0c97dd4960e56864b6446ae4f5ff072763b6a2 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Mon, 4 Nov 2019 17:15:14 +0100 +Subject: [PATCH 194/208] lib:param: Add lp(cfg)_weak_crypto() + +Signed-off-by: Andreas Schneider +--- + lib/param/loadparm.c | 15 +++++++++++++++ + lib/param/loadparm.h | 10 +++++++++- + lib/param/wscript_build | 2 +- + source3/include/proto.h | 1 + + source3/param/loadparm.c | 14 ++++++++++++++ + 5 files changed, 40 insertions(+), 2 deletions(-) + +diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c +index 883d4167bf4..83dc111c05c 100644 +--- a/lib/param/loadparm.c ++++ b/lib/param/loadparm.c +@@ -71,6 +71,7 @@ + #include "libds/common/roles.h" + #include "lib/util/samba_util.h" + #include "libcli/auth/ntlm_check.h" ++#include "lib/crypto/gnutls_helpers.h" + + #ifdef HAVE_HTTPCONNECTENCRYPT + #include +@@ -95,6 +96,19 @@ int lpcfg_rpc_high_port(struct loadparm_context *lp_ctx) + return lp_ctx->globals->rpc_high_port; + } + ++enum samba_weak_crypto lpcfg_weak_crypto(struct loadparm_context *lp_ctx) ++{ ++ if (lp_ctx->globals->weak_crypto == SAMBA_WEAK_CRYPTO_UNKNOWN) { ++ lp_ctx->globals->weak_crypto = SAMBA_WEAK_CRYPTO_DISALLOWED; ++ ++ if (samba_gnutls_weak_crypto_allowed()) { ++ lp_ctx->globals->weak_crypto = SAMBA_WEAK_CRYPTO_ALLOWED; ++ } ++ } ++ ++ return lp_ctx->globals->weak_crypto; ++} ++ + /** + * Convenience routine to grab string parameters into temporary memory + * and run standard_sub_basic on them. +@@ -2592,6 +2606,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) + lp_ctx->globals->ctx = lp_ctx->globals; + lp_ctx->globals->rpc_low_port = SERVER_TCP_LOW_PORT; + lp_ctx->globals->rpc_high_port = SERVER_TCP_HIGH_PORT; ++ lp_ctx->globals->weak_crypto = SAMBA_WEAK_CRYPTO_UNKNOWN; + lp_ctx->sDefault = talloc_zero(lp_ctx, struct loadparm_service); + lp_ctx->flags = talloc_zero_array(lp_ctx, unsigned int, num_parameters()); + +diff --git a/lib/param/loadparm.h b/lib/param/loadparm.h +index 0b2e302d2a9..897031985f8 100644 +--- a/lib/param/loadparm.h ++++ b/lib/param/loadparm.h +@@ -248,6 +248,13 @@ enum inheritowner_options { + /* mangled names options */ + enum mangled_names_options {MANGLED_NAMES_NO, MANGLED_NAMES_YES, MANGLED_NAMES_ILLEGAL}; + ++/* FIPS values */ ++enum samba_weak_crypto { ++ SAMBA_WEAK_CRYPTO_UNKNOWN, ++ SAMBA_WEAK_CRYPTO_ALLOWED, ++ SAMBA_WEAK_CRYPTO_DISALLOWED, ++}; ++ + /* + * Default passwd chat script. + */ +@@ -285,7 +292,8 @@ enum mangled_names_options {MANGLED_NAMES_NO, MANGLED_NAMES_YES, MANGLED_NAMES_I + struct parmlist_entry *param_opt; \ + char *dnsdomain; \ + int rpc_low_port; \ +- int rpc_high_port; ++ int rpc_high_port; \ ++ enum samba_weak_crypto weak_crypto; + + const char* server_role_str(uint32_t role); + int lp_find_server_role(int server_role, int security, int domain_logons, int domain_master); +diff --git a/lib/param/wscript_build b/lib/param/wscript_build +index 20c8bcab22a..864975a5884 100644 +--- a/lib/param/wscript_build ++++ b/lib/param/wscript_build +@@ -40,7 +40,7 @@ bld.SAMBA_LIBRARY('samba-hostconfig', + pc_files='samba-hostconfig.pc', + vnum='0.0.1', + deps='DYNCONFIG server-role tdb', +- public_deps='samba-util param_local.h', ++ public_deps='GNUTLS_HELPERS samba-util param_local.h', + public_headers='param.h', + autoproto='param_proto.h' + ) +diff --git a/source3/include/proto.h b/source3/include/proto.h +index 43a4b8f8b4d..956a328b626 100644 +--- a/source3/include/proto.h ++++ b/source3/include/proto.h +@@ -755,6 +755,7 @@ bool lp_widelinks(int ); + int lp_rpc_low_port(void); + int lp_rpc_high_port(void); + bool lp_lanman_auth(void); ++enum samba_weak_crypto lp_weak_crypto(void); + + int lp_wi_scan_global_parametrics( + const char *regex, size_t max_matches, +diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c +index a8d5fdc5954..923c2473662 100644 +--- a/source3/param/loadparm.c ++++ b/source3/param/loadparm.c +@@ -72,6 +72,7 @@ + #include "librpc/gen_ndr/nbt.h" + #include "source4/lib/tls/tls.h" + #include "libcli/auth/ntlm_check.h" ++#include "lib/crypto/gnutls_helpers.h" + + #ifdef HAVE_SYS_SYSCTL_H + #include +@@ -4677,3 +4678,16 @@ unsigned int * get_flags(void) + + return flags_list; + } ++ ++enum samba_weak_crypto lp_weak_crypto() ++{ ++ if (Globals.weak_crypto == SAMBA_WEAK_CRYPTO_UNKNOWN) { ++ Globals.weak_crypto = SAMBA_WEAK_CRYPTO_DISALLOWED; ++ ++ if (samba_gnutls_weak_crypto_allowed()) { ++ Globals.weak_crypto = SAMBA_WEAK_CRYPTO_ALLOWED; ++ } ++ } ++ ++ return Globals.weak_crypto; ++} +-- +2.23.0 + diff --git a/SOURCES/0195-gensec-Add-a-check-if-a-gensec-module-implements-wea.patch b/SOURCES/0195-gensec-Add-a-check-if-a-gensec-module-implements-wea.patch new file mode 100644 index 0000000..e4dfc83 --- /dev/null +++ b/SOURCES/0195-gensec-Add-a-check-if-a-gensec-module-implements-wea.patch @@ -0,0 +1,50 @@ +From c8b68454839618abf0e0c467ceaa08ef88717b22 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 11 Dec 2019 17:45:39 +0100 +Subject: [PATCH 195/208] gensec: Add a check if a gensec module implements + weak crypto + +Signed-off-by: Andreas Schneider +--- + auth/gensec/gensec_internal.h | 1 + + auth/gensec/gensec_start.c | 12 +++++++++++- + 2 files changed, 12 insertions(+), 1 deletion(-) + +diff --git a/auth/gensec/gensec_internal.h b/auth/gensec/gensec_internal.h +index 911b48b52d6..8efb1bdff0f 100644 +--- a/auth/gensec/gensec_internal.h ++++ b/auth/gensec/gensec_internal.h +@@ -28,6 +28,7 @@ struct gensec_security; + struct gensec_security_ops { + const char *name; + const char *sasl_name; ++ bool weak_crypto; + uint8_t auth_type; /* 0 if not offered on DCE-RPC */ + const char **oid; /* NULL if not offered by SPNEGO */ + NTSTATUS (*client_start)(struct gensec_security *gensec_security); +diff --git a/auth/gensec/gensec_start.c b/auth/gensec/gensec_start.c +index 50f4de73110..860c974f056 100644 +--- a/auth/gensec/gensec_start.c ++++ b/auth/gensec/gensec_start.c +@@ -49,7 +49,17 @@ _PUBLIC_ const struct gensec_security_ops * const *gensec_security_all(void) + + bool gensec_security_ops_enabled(const struct gensec_security_ops *ops, struct gensec_security *security) + { +- return lpcfg_parm_bool(security->settings->lp_ctx, NULL, "gensec", ops->name, ops->enabled); ++ bool ok = lpcfg_parm_bool(security->settings->lp_ctx, ++ NULL, ++ "gensec", ++ ops->name, ++ ops->enabled); ++ ++ if (!samba_gnutls_weak_crypto_allowed() && ops->weak_crypto) { ++ ok = false; ++ } ++ ++ return ok; + } + + /* Sometimes we want to force only kerberos, sometimes we want to +-- +2.23.0 + diff --git a/SOURCES/0196-auth-ntlmssp-Mark-as-weak_crypto.patch b/SOURCES/0196-auth-ntlmssp-Mark-as-weak_crypto.patch new file mode 100644 index 0000000..2c191a0 --- /dev/null +++ b/SOURCES/0196-auth-ntlmssp-Mark-as-weak_crypto.patch @@ -0,0 +1,46 @@ +From fdbe1754e49e1820976ce24707d60e10c9745552 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Mon, 11 Nov 2019 16:39:24 +0100 +Subject: [PATCH 196/208] auth:ntlmssp: Mark as weak_crypto + +Signed-off-by: Andreas Schneider +--- + auth/gensec/gensec_start.c | 1 + + auth/ntlmssp/ntlmssp.c | 2 ++ + 2 files changed, 3 insertions(+) + +diff --git a/auth/gensec/gensec_start.c b/auth/gensec/gensec_start.c +index 860c974f056..d2d62d6652e 100644 +--- a/auth/gensec/gensec_start.c ++++ b/auth/gensec/gensec_start.c +@@ -32,6 +32,7 @@ + #include "lib/util/tsort.h" + #include "lib/util/samba_modules.h" + #include "lib/util/base64.h" ++#include "lib/crypto/gnutls_helpers.h" + + #undef DBGC_CLASS + #define DBGC_CLASS DBGC_AUTH +diff --git a/auth/ntlmssp/ntlmssp.c b/auth/ntlmssp/ntlmssp.c +index 37434fbb0c2..745f2628d21 100644 +--- a/auth/ntlmssp/ntlmssp.c ++++ b/auth/ntlmssp/ntlmssp.c +@@ -305,6 +305,7 @@ static const struct gensec_security_ops gensec_ntlmssp_security_ops = { + .name = "ntlmssp", + .sasl_name = GENSEC_SASL_NAME_NTLMSSP, /* "NTLM" */ + .auth_type = DCERPC_AUTH_TYPE_NTLMSSP, ++ .weak_crypto = true, + .oid = gensec_ntlmssp_oids, + .client_start = gensec_ntlmssp_client_start, + .server_start = gensec_ntlmssp_server_start, +@@ -329,6 +330,7 @@ static const struct gensec_security_ops gensec_ntlmssp_security_ops = { + + static const struct gensec_security_ops gensec_ntlmssp_resume_ccache_ops = { + .name = "ntlmssp_resume_ccache", ++ .weak_crypto = true, + .client_start = gensec_ntlmssp_resume_ccache_start, + .update_send = gensec_ntlmssp_update_send, + .update_recv = gensec_ntlmssp_update_recv, +-- +2.23.0 + diff --git a/SOURCES/0197-s3-param-Force-SMB-encryption-for-DECRPC-over-named-.patch b/SOURCES/0197-s3-param-Force-SMB-encryption-for-DECRPC-over-named-.patch new file mode 100644 index 0000000..d1abeab --- /dev/null +++ b/SOURCES/0197-s3-param-Force-SMB-encryption-for-DECRPC-over-named-.patch @@ -0,0 +1,33 @@ +From d88a2d900f5eaab0acda0d0715a5c8ad7e92b315 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Tue, 16 Apr 2019 11:41:46 +0200 +Subject: [PATCH 197/208] s3:param: Force SMB encryption for DECRPC over named + pipes + +If we do not allow weak crypto, we need to secure DCERPC with strong +crypto. + +Signed-off-by: Andreas Schneider +--- + source3/param/loadparm.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c +index 923c2473662..b52e2bcb036 100644 +--- a/source3/param/loadparm.c ++++ b/source3/param/loadparm.c +@@ -1616,6 +1616,11 @@ static bool lp_add_ipc(const char *ipc_name, bool guest_ok) + ServicePtrs[i]->browseable = sDefault.browseable; + ServicePtrs[i]->autoloaded = false; + ++ /* Force SMB encryption for DECRPC over named pipes. */ ++ if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED) { ++ ServicePtrs[i]->smb_encrypt = SMB_SIGNING_REQUIRED; ++ } ++ + DEBUG(3, ("adding IPC service\n")); + + TALLOC_FREE(comment); +-- +2.23.0 + diff --git a/SOURCES/0198-s3-param-Only-allow-SMB-3.0-for-DCERPC-client-connec.patch b/SOURCES/0198-s3-param-Only-allow-SMB-3.0-for-DCERPC-client-connec.patch new file mode 100644 index 0000000..fb52411 --- /dev/null +++ b/SOURCES/0198-s3-param-Only-allow-SMB-3.0-for-DCERPC-client-connec.patch @@ -0,0 +1,37 @@ +From 499fd673befa6fed6bd0e542d9bb06cb49bd150e Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Thu, 11 Apr 2019 11:40:11 +0200 +Subject: [PATCH 198/208] s3:param: Only allow SMB 3.0+ for DCERPC client + connections over named pipes + +We need an AES encrypted transport as some RPC services only encrypt +secrets using RC4, e.g. password changes over SAMR. + +Signed-off-by: Andreas Schneider +--- + source3/param/loadparm.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c +index b52e2bcb036..c1d02cf5bc6 100644 +--- a/source3/param/loadparm.c ++++ b/source3/param/loadparm.c +@@ -4614,6 +4614,15 @@ int lp_client_max_protocol(void) + int lp_client_ipc_min_protocol(void) + { + int client_ipc_min_protocol = lp__client_ipc_min_protocol(); ++ ++ /* ++ * If weak crypto is not allowed, force at least SMB3 which offers AES ++ * encrypted connections. ++ */ ++ if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED) { ++ return MAX(client_ipc_min_protocol, PROTOCOL_SMB3_00); ++ } ++ + if (client_ipc_min_protocol == PROTOCOL_DEFAULT) { + client_ipc_min_protocol = lp_client_min_protocol(); + } +-- +2.23.0 + diff --git a/SOURCES/0199-s3-rpc_server-Allow-RC4-encrypted-buffers-in-samr_Se.patch b/SOURCES/0199-s3-rpc_server-Allow-RC4-encrypted-buffers-in-samr_Se.patch new file mode 100644 index 0000000..c4c528b --- /dev/null +++ b/SOURCES/0199-s3-rpc_server-Allow-RC4-encrypted-buffers-in-samr_Se.patch @@ -0,0 +1,82 @@ +From 007b56943bbec3c3b9b28be08c3088b0d28ba2d8 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Tue, 12 Nov 2019 16:56:45 +0100 +Subject: [PATCH 199/208] s3:rpc_server: Allow RC4 encrypted buffers in + samr_SetUserInfo() + +This is only allowed if we have a sealed connections! + +Signed-off-by: Andreas Schneider +--- + source3/rpc_server/samr/srv_samr_nt.c | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +diff --git a/source3/rpc_server/samr/srv_samr_nt.c b/source3/rpc_server/samr/srv_samr_nt.c +index 91771e34502..509bce57a3b 100644 +--- a/source3/rpc_server/samr/srv_samr_nt.c ++++ b/source3/rpc_server/samr/srv_samr_nt.c +@@ -5210,9 +5210,15 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p, + if(!NT_STATUS_IS_OK(status)) { + break; + } ++ /* ++ * This can be allowed as it requires a session key ++ * which we only have if we have a SMB session. ++ */ ++ GNUTLS_FIPS140_SET_LAX_MODE(); + status = arc4_decrypt_data(session_key, + info->info23.password.data, + 516); ++ GNUTLS_FIPS140_SET_STRICT_MODE(); + if(!NT_STATUS_IS_OK(status)) { + break; + } +@@ -5233,9 +5239,15 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p, + if(!NT_STATUS_IS_OK(status)) { + break; + } ++ /* ++ * This can be allowed as it requires a session key ++ * which we only have if we have a SMB session. ++ */ ++ GNUTLS_FIPS140_SET_LAX_MODE(); + status = arc4_decrypt_data(session_key, + info->info24.password.data, + 516); ++ GNUTLS_FIPS140_SET_STRICT_MODE(); + if(!NT_STATUS_IS_OK(status)) { + break; + } +@@ -5254,8 +5266,14 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p, + if(!NT_STATUS_IS_OK(status)) { + break; + } ++ /* ++ * This can be allowed as it requires a session key ++ * which we only have if we have a SMB session. ++ */ ++ GNUTLS_FIPS140_SET_LAX_MODE(); + status = decode_rc4_passwd_buffer(&session_key, + &info->info25.password); ++ GNUTLS_FIPS140_SET_STRICT_MODE(); + if (!NT_STATUS_IS_OK(status)) { + break; + } +@@ -5274,8 +5292,14 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p, + if(!NT_STATUS_IS_OK(status)) { + break; + } ++ /* ++ * This can be allowed as it requires a session key ++ * which we only have if we have a SMB session. ++ */ ++ GNUTLS_FIPS140_SET_LAX_MODE(); + status = decode_rc4_passwd_buffer(&session_key, + &info->info26.password); ++ GNUTLS_FIPS140_SET_STRICT_MODE(); + if (!NT_STATUS_IS_OK(status)) { + break; + } +-- +2.23.0 + diff --git a/SOURCES/0200-s4-rpc_server-Allow-to-use-RC4-for-setting-passwords.patch b/SOURCES/0200-s4-rpc_server-Allow-to-use-RC4-for-setting-passwords.patch new file mode 100644 index 0000000..4314363 --- /dev/null +++ b/SOURCES/0200-s4-rpc_server-Allow-to-use-RC4-for-setting-passwords.patch @@ -0,0 +1,45 @@ +From 00351ef5dd8fb5ab1d036850a99d7dee07dadca1 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Fri, 15 Nov 2019 13:49:40 +0100 +Subject: [PATCH 200/208] s4:rpc_server: Allow to use RC4 for setting passwords + +Signed-off-by: Andreas Schneider +--- + source4/rpc_server/samr/samr_password.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c +index fba236ebdd7..e5e339842b1 100644 +--- a/source4/rpc_server/samr/samr_password.c ++++ b/source4/rpc_server/samr/samr_password.c +@@ -618,6 +618,11 @@ NTSTATUS samr_set_password(struct dcesrv_call_state *dce_call, + .size = session_key.length, + }; + ++ /* ++ * This is safe to support as we only have a session key ++ * over a SMB connection which we force to be encrypted. ++ */ ++ GNUTLS_FIPS140_SET_LAX_MODE(); + rc = gnutls_cipher_init(&cipher_hnd, + GNUTLS_CIPHER_ARCFOUR_128, + &_session_key, +@@ -635,6 +640,7 @@ NTSTATUS samr_set_password(struct dcesrv_call_state *dce_call, + nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); + goto out; + } ++ GNUTLS_FIPS140_SET_STRICT_MODE(); + + if (!extract_pw_from_buffer(mem_ctx, pwbuf->data, &new_password)) { + DEBUG(3,("samr: failed to decode password buffer\n")); +@@ -655,6 +661,7 @@ NTSTATUS samr_set_password(struct dcesrv_call_state *dce_call, + NULL, + NULL); + out: ++ GNUTLS_FIPS140_SET_STRICT_MODE(); + return nt_status; + } + +-- +2.23.0 + diff --git a/SOURCES/0201-s3-rpc_server-Only-announce-RC4-in-netlogon-server-i.patch b/SOURCES/0201-s3-rpc_server-Only-announce-RC4-in-netlogon-server-i.patch new file mode 100644 index 0000000..3bde1ce --- /dev/null +++ b/SOURCES/0201-s3-rpc_server-Only-announce-RC4-in-netlogon-server-i.patch @@ -0,0 +1,37 @@ +From f719db12774d7b22b818adb56c2abd64ab036caf Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Thu, 11 Apr 2019 16:06:14 +0200 +Subject: [PATCH 201/208] s3:rpc_server: Only announce RC4 in netlogon server + if available + +Signed-off-by: Andreas Schneider +--- + source3/rpc_server/netlogon/srv_netlog_nt.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c +index cbbf9feedc7..3dd8ecf5ca8 100644 +--- a/source3/rpc_server/netlogon/srv_netlog_nt.c ++++ b/source3/rpc_server/netlogon/srv_netlog_nt.c +@@ -909,7 +909,6 @@ NTSTATUS _netr_ServerAuthenticate3(struct pipes_struct *p, + /* 0x000001ff */ + srv_flgs = NETLOGON_NEG_ACCOUNT_LOCKOUT | + NETLOGON_NEG_PERSISTENT_SAMREPL | +- NETLOGON_NEG_ARCFOUR | + NETLOGON_NEG_PROMOTION_COUNT | + NETLOGON_NEG_CHANGELOG_BDC | + NETLOGON_NEG_FULL_SYNC_REPL | +@@ -918,6 +917,10 @@ NTSTATUS _netr_ServerAuthenticate3(struct pipes_struct *p, + NETLOGON_NEG_PASSWORD_CHANGE_REFUSAL | + NETLOGON_NEG_PASSWORD_SET2; + ++ if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_ALLOWED) { ++ srv_flgs |= NETLOGON_NEG_ARCFOUR; ++ } ++ + /* Ensure we support strong (128-bit) keys. */ + if (in_neg_flags & NETLOGON_NEG_STRONG_KEYS) { + srv_flgs |= NETLOGON_NEG_STRONG_KEYS; +-- +2.23.0 + diff --git a/SOURCES/0202-s4-rpc_server-Only-announce-RC4-in-netlogon-server-i.patch b/SOURCES/0202-s4-rpc_server-Only-announce-RC4-in-netlogon-server-i.patch new file mode 100644 index 0000000..685801d --- /dev/null +++ b/SOURCES/0202-s4-rpc_server-Only-announce-RC4-in-netlogon-server-i.patch @@ -0,0 +1,46 @@ +From e34285778e869f8cb706e4836213651b00b6e425 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Mon, 18 Nov 2019 17:10:25 +0100 +Subject: [PATCH 202/208] s4:rpc_server: Only announce RC4 in netlogon server + if available + +Signed-off-by: Andreas Schneider +--- + source4/rpc_server/netlogon/dcerpc_netlogon.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c +index 6c92db7b53a..bc3f8e6765f 100644 +--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c ++++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c +@@ -44,6 +44,7 @@ + #include "lib/socket/netif.h" + #include "rpc_server/common/sid_helper.h" + #include "lib/util/util_str_escape.h" ++#include "lib/param/loadparm.h" + + #define DCESRV_INTERFACE_NETLOGON_BIND(context, iface) \ + dcesrv_interface_netlogon_bind(context, iface) +@@ -198,7 +199,6 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper( + + server_flags = NETLOGON_NEG_ACCOUNT_LOCKOUT | + NETLOGON_NEG_PERSISTENT_SAMREPL | +- NETLOGON_NEG_ARCFOUR | + NETLOGON_NEG_PROMOTION_COUNT | + NETLOGON_NEG_CHANGELOG_BDC | + NETLOGON_NEG_FULL_SYNC_REPL | +@@ -222,6 +222,11 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper( + NETLOGON_NEG_AUTHENTICATED_RPC_LSASS | + NETLOGON_NEG_AUTHENTICATED_RPC; + ++ if (lpcfg_weak_crypto(dce_call->conn->dce_ctx->lp_ctx) == ++ SAMBA_WEAK_CRYPTO_ALLOWED) { ++ server_flags |= NETLOGON_NEG_ARCFOUR; ++ } ++ + negotiate_flags = *r->in.negotiate_flags & server_flags; + + if (negotiate_flags & NETLOGON_NEG_STRONG_KEYS) { +-- +2.23.0 + diff --git a/SOURCES/0203-s4-samdb-Allow-to-hash-password-using-MD5-in-samdb.patch b/SOURCES/0203-s4-samdb-Allow-to-hash-password-using-MD5-in-samdb.patch new file mode 100644 index 0000000..4ce8e57 --- /dev/null +++ b/SOURCES/0203-s4-samdb-Allow-to-hash-password-using-MD5-in-samdb.patch @@ -0,0 +1,51 @@ +From f1fe9abde9375d06cd4b6f0265ee1af483bbfd14 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 15 May 2019 08:46:56 +0200 +Subject: [PATCH 203/208] s4:samdb: Allow to hash password using MD5 in samdb + +Those passwords are stored in the local database. + +Signed-off-by: Andreas Schneider +--- + source4/dsdb/samdb/ldb_modules/password_hash.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c +index 006e35c46d5..1e94bb8f01c 100644 +--- a/source4/dsdb/samdb/ldb_modules/password_hash.c ++++ b/source4/dsdb/samdb/ldb_modules/password_hash.c +@@ -48,7 +48,7 @@ + #include "auth/common_auth.h" + #include "lib/messaging/messaging.h" + +-#include ++#include "lib/crypto/gnutls_helpers.h" + #include + + #ifdef ENABLE_GPGME +@@ -1372,6 +1372,8 @@ static int setup_primary_wdigest(struct setup_password_fields_io *io, + for (i=0; i < ARRAY_SIZE(wdigest); i++) { + gnutls_hash_hd_t hash_hnd = NULL; + ++ GNUTLS_FIPS140_SET_LAX_MODE(); ++ + rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5); + if (rc < 0) { + rc = ldb_oom(ldb); +@@ -1436,10 +1438,13 @@ static int setup_primary_wdigest(struct setup_password_fields_io *io, + } + + gnutls_hash_deinit(hash_hnd, pdb->hashes[i].hash); ++ ++ GNUTLS_FIPS140_SET_STRICT_MODE(); + } + + rc = LDB_SUCCESS; + out: ++ GNUTLS_FIPS140_SET_STRICT_MODE(); + return rc; + } + +-- +2.23.0 + diff --git a/SOURCES/0204-lib-crypto-Allow-py_crypto-to-use-RC4-in-FIPS-mode.patch b/SOURCES/0204-lib-crypto-Allow-py_crypto-to-use-RC4-in-FIPS-mode.patch new file mode 100644 index 0000000..7f03e3d --- /dev/null +++ b/SOURCES/0204-lib-crypto-Allow-py_crypto-to-use-RC4-in-FIPS-mode.patch @@ -0,0 +1,56 @@ +From 4e54b3526ae140a419fc50eae3a2e30e25373529 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Tue, 21 May 2019 09:31:02 +0200 +Subject: [PATCH 204/208] lib:crypto: Allow py_crypto to use RC4 in FIPS mode + +This is a public functions, so it can be consumed by others. E.g. +FreeIPA is using it to establish trusts. Not sure if this is +a problem with FIPS. + +Signed-off-by: Andreas Schneider +--- + lib/crypto/py_crypto.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/lib/crypto/py_crypto.c b/lib/crypto/py_crypto.c +index c85cd2c13d2..f4b5b745daf 100644 +--- a/lib/crypto/py_crypto.c ++++ b/lib/crypto/py_crypto.c +@@ -22,7 +22,7 @@ + #include "includes.h" + #include "python/py3compat.h" + +-#include ++#include "gnutls_helpers.h" + #include + + static PyObject *py_crypto_arcfour_crypt_blob(PyObject *module, PyObject *args) +@@ -61,11 +61,15 @@ static PyObject *py_crypto_arcfour_crypt_blob(PyObject *module, PyObject *args) + .size = PyBytes_Size(py_key), + }; + ++ GNUTLS_FIPS140_SET_LAX_MODE(); ++ + rc = gnutls_cipher_init(&cipher_hnd, + GNUTLS_CIPHER_ARCFOUR_128, + &key, + NULL); + if (rc < 0) { ++ GNUTLS_FIPS140_SET_STRICT_MODE(); ++ + talloc_free(ctx); + PyErr_Format(PyExc_OSError, "encryption failed"); + return NULL; +@@ -74,6 +78,9 @@ static PyObject *py_crypto_arcfour_crypt_blob(PyObject *module, PyObject *args) + data.data, + data.length); + gnutls_cipher_deinit(cipher_hnd); ++ ++ GNUTLS_FIPS140_SET_STRICT_MODE(); ++ + if (rc < 0) { + talloc_free(ctx); + PyErr_Format(PyExc_OSError, "encryption failed"); +-- +2.23.0 + diff --git a/SOURCES/0205-param-Do-not-use-weak-crypto-for-kerberos-if-disallo.patch b/SOURCES/0205-param-Do-not-use-weak-crypto-for-kerberos-if-disallo.patch new file mode 100644 index 0000000..c38a4c5 --- /dev/null +++ b/SOURCES/0205-param-Do-not-use-weak-crypto-for-kerberos-if-disallo.patch @@ -0,0 +1,93 @@ +From b018dd4ae5c176d61115b6ec7bf3e2bd19c559a4 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Mon, 18 Nov 2019 17:30:18 +0100 +Subject: [PATCH 205/208] param: Do not use weak crypto for kerberos if + disallowed + +Signed-off-by: Andreas Schneider +--- + .../smbdotconf/security/kerberosencryptiontypes.xml | 5 +++++ + lib/param/loadparm.c | 10 ++++++++++ + source3/include/proto.h | 1 + + source3/param/loadparm.c | 9 +++++++++ + 4 files changed, 25 insertions(+) + +diff --git a/docs-xml/smbdotconf/security/kerberosencryptiontypes.xml b/docs-xml/smbdotconf/security/kerberosencryptiontypes.xml +index 2c3c6c5d5fc..5b0c1a40fcc 100644 +--- a/docs-xml/smbdotconf/security/kerberosencryptiontypes.xml ++++ b/docs-xml/smbdotconf/security/kerberosencryptiontypes.xml +@@ -2,6 +2,7 @@ + context="G" + type="enum" + enumlist="enum_kerberos_encryption_types_vals" ++ function="_kerberos_encryption_types" + xmlns:samba="http://www.samba.org/samba/DTD/samba-doc"> + + This parameter determines the encryption types to use when operating +@@ -47,6 +48,10 @@ + encryption. It is assumed of course that the weaker legacy + encryption types are acceptable for the setup. + ++ ++ If weak cryptography is not allowed by the system, then this ++ variable will be forced to strong. In this case ++ it is not possible to override this value. + + + all +diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c +index 83dc111c05c..41a4c110195 100644 +--- a/lib/param/loadparm.c ++++ b/lib/param/loadparm.c +@@ -96,6 +96,16 @@ int lpcfg_rpc_high_port(struct loadparm_context *lp_ctx) + return lp_ctx->globals->rpc_high_port; + } + ++int lpcfg_kerberos_encryption_types(struct loadparm_context *lp_ctx) ++{ ++ if (lpcfg_weak_crypto(lp_ctx) == SAMBA_WEAK_CRYPTO_DISALLOWED) { ++ return KERBEROS_ETYPES_STRONG; ++ } ++ ++ return lpcfg__kerberos_encryption_types(lp_ctx); ++} ++ ++ + enum samba_weak_crypto lpcfg_weak_crypto(struct loadparm_context *lp_ctx) + { + if (lp_ctx->globals->weak_crypto == SAMBA_WEAK_CRYPTO_UNKNOWN) { +diff --git a/source3/include/proto.h b/source3/include/proto.h +index 956a328b626..aaa101fc63c 100644 +--- a/source3/include/proto.h ++++ b/source3/include/proto.h +@@ -755,6 +755,7 @@ bool lp_widelinks(int ); + int lp_rpc_low_port(void); + int lp_rpc_high_port(void); + bool lp_lanman_auth(void); ++int lp_kerberos_encryption_types(void); + enum samba_weak_crypto lp_weak_crypto(void); + + int lp_wi_scan_global_parametrics( +diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c +index c1d02cf5bc6..e68140ae5f0 100644 +--- a/source3/param/loadparm.c ++++ b/source3/param/loadparm.c +@@ -4679,6 +4679,15 @@ bool lp_lanman_auth(void) + } + } + ++int lp_kerberos_encryption_types(void) ++{ ++ if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED) { ++ return KERBEROS_ETYPES_STRONG; ++ } ++ ++ return lp__kerberos_encryption_types(); ++} ++ + struct loadparm_global * get_globals(void) + { + return &Globals; +-- +2.23.0 + diff --git a/SOURCES/0206-param-Do-not-use-weak-crypto-in-ldap-server-if-disal.patch b/SOURCES/0206-param-Do-not-use-weak-crypto-in-ldap-server-if-disal.patch new file mode 100644 index 0000000..a79d527 --- /dev/null +++ b/SOURCES/0206-param-Do-not-use-weak-crypto-in-ldap-server-if-disal.patch @@ -0,0 +1,103 @@ +From a1c732637f1ed984e1ff76fa8179d6fd3aa036fb Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Mon, 18 Nov 2019 17:42:11 +0100 +Subject: [PATCH 206/208] param: Do not use weak crypto in ldap server if + disallowed + +Signed-off-by: Andreas Schneider +--- + .../ldap/ldapserverrequirestrongauth.xml | 5 +++++ + lib/param/loadparm.c | 8 ++++++++ + source3/include/proto.h | 1 + + source3/param/loadparm.c | 14 +++++++++++++- + 4 files changed, 27 insertions(+), 1 deletion(-) + +diff --git a/docs-xml/smbdotconf/ldap/ldapserverrequirestrongauth.xml b/docs-xml/smbdotconf/ldap/ldapserverrequirestrongauth.xml +index 02bdd811491..e40ac06dfe6 100644 +--- a/docs-xml/smbdotconf/ldap/ldapserverrequirestrongauth.xml ++++ b/docs-xml/smbdotconf/ldap/ldapserverrequirestrongauth.xml +@@ -2,6 +2,7 @@ + context="G" + type="enum" + enumlist="enum_ldap_server_require_strong_auth_vals" ++ function="_ldap_server_require_strong_auth" + xmlns:samba="http://www.samba.org/samba/DTD/samba-doc"> + + +@@ -21,6 +22,10 @@ + A value of yes allows only simple binds + over TLS encrypted connections. Unencrypted connections only + allow sasl binds with sign or seal. ++ ++ If weak cryptography is not allowed by the system, then this ++ variable will default to allow_sasl_over_tls ++ and setting it to no will not have any effect. + + yes + +diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c +index 41a4c110195..b1497f00aaa 100644 +--- a/lib/param/loadparm.c ++++ b/lib/param/loadparm.c +@@ -105,6 +105,14 @@ int lpcfg_kerberos_encryption_types(struct loadparm_context *lp_ctx) + return lpcfg__kerberos_encryption_types(lp_ctx); + } + ++enum ldap_server_require_strong_auth lpcfg_ldap_server_require_strong_auth(struct loadparm_context *lp_ctx) ++{ ++ if (lpcfg_weak_crypto(lp_ctx) == SAMBA_WEAK_CRYPTO_DISALLOWED) { ++ return LDAP_SERVER_REQUIRE_STRONG_AUTH_YES; ++ } ++ ++ return lpcfg__ldap_server_require_strong_auth(lp_ctx); ++} + + enum samba_weak_crypto lpcfg_weak_crypto(struct loadparm_context *lp_ctx) + { +diff --git a/source3/include/proto.h b/source3/include/proto.h +index aaa101fc63c..c758c31ea67 100644 +--- a/source3/include/proto.h ++++ b/source3/include/proto.h +@@ -756,6 +756,7 @@ int lp_rpc_low_port(void); + int lp_rpc_high_port(void); + bool lp_lanman_auth(void); + int lp_kerberos_encryption_types(void); ++enum ldap_server_require_strong_auth lp_ldap_server_require_strong_auth(void); + enum samba_weak_crypto lp_weak_crypto(void); + + int lp_wi_scan_global_parametrics( +diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c +index e68140ae5f0..da2af1f9f46 100644 +--- a/source3/param/loadparm.c ++++ b/source3/param/loadparm.c +@@ -754,7 +754,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) + + Globals.client_ldap_sasl_wrapping = ADS_AUTH_SASL_SIGN; + +- Globals.ldap_server_require_strong_auth = ++ Globals._ldap_server_require_strong_auth = + LDAP_SERVER_REQUIRE_STRONG_AUTH_YES; + + /* This is what we tell the afs client. in reality we set the token +@@ -4688,6 +4688,18 @@ int lp_kerberos_encryption_types(void) + return lp__kerberos_encryption_types(); + } + ++enum ldap_server_require_strong_auth lp_ldap_server_require_strong_auth(void) ++{ ++ enum ldap_server_require_strong_auth a = ++ lp__ldap_server_require_strong_auth(); ++ ++ if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED) { ++ return MAX(a, LDAP_SERVER_REQUIRE_STRONG_AUTH_ALLOW_SASL_OVER_TLS); ++ } ++ ++ return a; ++} ++ + struct loadparm_global * get_globals(void) + { + return &Globals; +-- +2.23.0 + diff --git a/SOURCES/0207-libcli-auth-If-weak-crypto-is-disallowed-reject-md5-.patch b/SOURCES/0207-libcli-auth-If-weak-crypto-is-disallowed-reject-md5-.patch new file mode 100644 index 0000000..906db24 --- /dev/null +++ b/SOURCES/0207-libcli-auth-If-weak-crypto-is-disallowed-reject-md5-.patch @@ -0,0 +1,52 @@ +From 693540a9ac017afbaeea5800f9025b75e390f53b Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Tue, 19 Nov 2019 14:52:44 +0100 +Subject: [PATCH 207/208] libcli:auth: If weak crypto is disallowed reject md5 + servers + +Signed-off-by: Andreas Schneider +--- + docs-xml/smbdotconf/winbind/rejectmd5servers.xml | 2 ++ + libcli/auth/netlogon_creds_cli.c | 6 ++++++ + 2 files changed, 8 insertions(+) + +diff --git a/docs-xml/smbdotconf/winbind/rejectmd5servers.xml b/docs-xml/smbdotconf/winbind/rejectmd5servers.xml +index 37656293aa4..e8b06615a9c 100644 +--- a/docs-xml/smbdotconf/winbind/rejectmd5servers.xml ++++ b/docs-xml/smbdotconf/winbind/rejectmd5servers.xml +@@ -16,6 +16,8 @@ + by using 'reject md5 servers:NETBIOSDOMAIN = yes' as option. + + This option takes precedence to the option. ++ ++ If weak cryptography is not allowed by the system, md5 servers will *always* be rejected. + + + no +diff --git a/libcli/auth/netlogon_creds_cli.c b/libcli/auth/netlogon_creds_cli.c +index c8f4227a924..fe453c268cf 100644 +--- a/libcli/auth/netlogon_creds_cli.c ++++ b/libcli/auth/netlogon_creds_cli.c +@@ -39,6 +39,7 @@ + #include "libds/common/roles.h" + #include "lib/crypto/md4.h" + #include "auth/credentials/credentials.h" ++#include "loadparm.h" + + struct netlogon_creds_cli_locked_state; + +@@ -303,6 +304,11 @@ NTSTATUS netlogon_creds_cli_context_global(struct loadparm_context *lp_ctx, + server_netbios_domain, + reject_md5_servers); + ++ if (lpcfg_weak_crypto(lp_ctx) == SAMBA_WEAK_CRYPTO_DISALLOWED) { ++ reject_md5_servers = true; ++ } ++ ++ + /* + * allow overwrite per domain + * require strong key: +-- +2.23.0 + diff --git a/SOURCES/0208-s3-librpc-Only-use-RC4-if-our-systems-supports-it.patch b/SOURCES/0208-s3-librpc-Only-use-RC4-if-our-systems-supports-it.patch new file mode 100644 index 0000000..3ad0a40 --- /dev/null +++ b/SOURCES/0208-s3-librpc-Only-use-RC4-if-our-systems-supports-it.patch @@ -0,0 +1,36 @@ +From 88fed59d4c29b9ff7964db462ff56f1f92eedf3a Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 20 Nov 2019 11:18:21 +0100 +Subject: [PATCH 208/208] s3:librpc: Only use RC4 if our systems supports it + +Signed-off-by: Andreas Schneider +--- + source4/librpc/rpc/dcerpc_schannel.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/source4/librpc/rpc/dcerpc_schannel.c b/source4/librpc/rpc/dcerpc_schannel.c +index d12647222eb..8a82fdf60b5 100644 +--- a/source4/librpc/rpc/dcerpc_schannel.c ++++ b/source4/librpc/rpc/dcerpc_schannel.c +@@ -31,6 +31,7 @@ + #include "auth/credentials/credentials.h" + #include "librpc/rpc/dcerpc_proto.h" + #include "param/param.h" ++#include "lib/param/loadparm.h" + + struct schannel_key_state { + struct dcerpc_pipe *pipe; +@@ -341,6 +342,10 @@ static struct composite_context *dcerpc_schannel_key_send(TALLOC_CTX *mem_ctx, + s->dcerpc_schannel_auto = true; + } + ++ if (lpcfg_weak_crypto(lp_ctx) == SAMBA_WEAK_CRYPTO_DISALLOWED) { ++ s->local_negotiate_flags &= ~NETLOGON_NEG_ARCFOUR; ++ } ++ + /* type of authentication depends on schannel type */ + if (schannel_type == SEC_CHAN_RODC) { + s->local_negotiate_flags |= NETLOGON_NEG_RODC_PASSTHROUGH; +-- +2.23.0 + diff --git a/SOURCES/0209-s3-rpcserver-fix-security-level-check-for-DsRGetFore.patch b/SOURCES/0209-s3-rpcserver-fix-security-level-check-for-DsRGetFore.patch new file mode 100644 index 0000000..90ec59d --- /dev/null +++ b/SOURCES/0209-s3-rpcserver-fix-security-level-check-for-DsRGetFore.patch @@ -0,0 +1,84 @@ +From 2a7249a43c82d720191e29510db5633f3a92a08c Mon Sep 17 00:00:00 2001 +From: Alexander Bokovoy +Date: Tue, 7 Jan 2020 19:25:53 +0200 +Subject: [PATCH 209/209] s3-rpcserver: fix security level check for + DsRGetForestTrustInformation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Harmonize _netr_DsRGetForestTrustInformation with source4/ logic which +didn't change since DCE RPC channel refactoring. + +With the current code we return RPC faul as can be seen in the logs: + +2019/12/11 17:12:55.463081, 1, pid=20939, effective(1284200000, 1284200000), real(1284200000, 0), class=rpc_parse] ../librpc/ndr/ndr.c:471(ndr_print_function_debug) + netr_DsRGetForestTrustInformation: struct netr_DsRGetForestTrustInformation + in: struct netr_DsRGetForestTrustInformation + server_name : * + server_name : '\\some-dc.example.com' + trusted_domain_name : NULL + flags : 0x00000000 (0) +[2019/12/11 17:12:55.463122, 4, pid=20939, effective(1284200000, 1284200000), real(1284200000, 0), class=rpc_srv] ../source3/rpc_server/srv_pipe.c:1561(api_rpcTNP) + api_rpcTNP: fault(5) return. + +This is due to this check in processing a request: + if (!(p->pipe_bound && (p->auth.auth_type != DCERPC_AUTH_TYPE_NONE) + && (p->auth.auth_level != DCERPC_AUTH_LEVEL_NONE))) { + p->fault_state = DCERPC_FAULT_ACCESS_DENIED; + return WERR_ACCESS_DENIED; + } + +and since we get AuthZ response, + + Successful AuthZ: [netlogon,ncacn_np] user [EXAMPLE]\[admin] [S-1-5-21-1234567-890123456-500] at [Wed, 11 Dec 2019 17:12:55.461164 UTC] + Remote host [ipv4:Y.Y.Y.Y:59017] local host [ipv4:X.X.X.X:445] +[2019/12/11 17:12:55.461584, 4, pid=20939, effective(0, 0), real(0, 0)] ../lib/audit_logging/audit_logging.c:141(audit_log_json) + JSON Authorization: {"timestamp": "2019-12-11T17:12:55.461491+0000", + "type": "Authorization", "Authorization": {"version": {"major": 1, "minor": 1}, + "localAddress": "ipv4:X.X.X.X:445", "remoteAddress": "ipv4:Y.Y.Y.Y:59017", + "serviceDescription": "netlogon", "authType": "ncacn_np", + "domain": "EXAMPLE", "account": "admin", "sid": "S-1-5-21-1234567-890123456-500", + "sessionId": "c5a2386f-f2cc-4241-9a9e-d104cf5859d5", "logonServer": "SOME-DC", + "transportProtection": "SMB", "accountFlags": "0x00000010"}} + +this means we are actually getting anonymous DCE/RPC access to netlogon +on top of authenticated SMB connection. In such case we have exactly +auth_type set to DCERPC_AUTH_TYPE_NONE and auth_level set to +DCERPC_AUTH_LEVEL_NONE in the pipe->auth. Thus, returning an error. + +Update the code to follow the same security level check as in s4 variant +of the call. + +Signed-off-by: Alexander Bokovoy +Reviewed-by: Guenther Deschner + +Autobuild-User(master): Günther Deschner +Autobuild-Date(master): Mon Jan 13 15:05:28 UTC 2020 on sn-devel-184 + +(cherry picked from commit c6d880a115095c336b8b74f45854a99abb1bbb87) +--- + source3/rpc_server/netlogon/srv_netlog_nt.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c +index 3dd8ecf5ca8..3fb62d3f82e 100644 +--- a/source3/rpc_server/netlogon/srv_netlog_nt.c ++++ b/source3/rpc_server/netlogon/srv_netlog_nt.c +@@ -2454,10 +2454,10 @@ WERROR _netr_DsRGetForestTrustInformation(struct pipes_struct *p, + { + NTSTATUS status; + struct lsa_ForestTrustInformation *info, **info_ptr; ++ enum security_user_level security_level; + +- if (!(p->pipe_bound && (p->auth.auth_type != DCERPC_AUTH_TYPE_NONE) +- && (p->auth.auth_level != DCERPC_AUTH_LEVEL_NONE))) { +- p->fault_state = DCERPC_FAULT_ACCESS_DENIED; ++ security_level = security_session_user_level(p->session_info, NULL); ++ if (security_level < SECURITY_USER) { + return WERR_ACCESS_DENIED; + } + +-- +2.24.1 + diff --git a/SOURCES/CVE-2019-14907-4.11.patch b/SOURCES/CVE-2019-14907-4.11.patch new file mode 100644 index 0000000..1465ec8 --- /dev/null +++ b/SOURCES/CVE-2019-14907-4.11.patch @@ -0,0 +1,100 @@ +From 588b74189958630b39cb393c47495d39dead83a1 Mon Sep 17 00:00:00 2001 +From: Andrew Bartlett +Date: Fri, 29 Nov 2019 20:58:47 +1300 +Subject: [PATCH] CVE-2019-14907 lib/util: Do not print the failed to convert + string into the logs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The string may be in another charset, or may be sensitive and +certainly may not be terminated. It is not safe to just print. + +Found by Robert Święcki using a fuzzer he wrote for smbd. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14208 +Signed-off-by: Andrew Bartlett +--- + lib/util/charset/convert_string.c | 38 ++++++++++++++++--------------- + 1 file changed, 20 insertions(+), 18 deletions(-) + +diff --git a/lib/util/charset/convert_string.c b/lib/util/charset/convert_string.c +index d274e305a0c..b725b53cb5a 100644 +--- a/lib/util/charset/convert_string.c ++++ b/lib/util/charset/convert_string.c +@@ -293,31 +293,31 @@ bool convert_string_handle(struct smb_iconv_handle *ic, + switch(errno) { + case EINVAL: + reason="Incomplete multibyte sequence"; +- DEBUG(3,("convert_string_internal: Conversion error: %s(%s)\n", +- reason, (const char *)src)); ++ DBG_NOTICE("Conversion error: %s\n", ++ reason); + break; + case E2BIG: + { + reason="No more room"; + if (from == CH_UNIX) { +- DEBUG(3,("E2BIG: convert_string(%s,%s): srclen=%u destlen=%u - '%s' error: %s\n", +- charset_name(ic, from), charset_name(ic, to), +- (unsigned int)srclen, (unsigned int)destlen, (const char *)src, reason)); ++ DBG_NOTICE("E2BIG: convert_string(%s,%s): srclen=%u destlen=%u error: %s\n", ++ charset_name(ic, from), charset_name(ic, to), ++ (unsigned int)srclen, (unsigned int)destlen, reason); + } else { +- DEBUG(3,("E2BIG: convert_string(%s,%s): srclen=%u destlen=%u error: %s\n", +- charset_name(ic, from), charset_name(ic, to), +- (unsigned int)srclen, (unsigned int)destlen, reason)); ++ DBG_NOTICE("E2BIG: convert_string(%s,%s): srclen=%u destlen=%u error: %s\n", ++ charset_name(ic, from), charset_name(ic, to), ++ (unsigned int)srclen, (unsigned int)destlen, reason); + } + break; + } + case EILSEQ: + reason="Illegal multibyte sequence"; +- DEBUG(3,("convert_string_internal: Conversion error: %s(%s)\n", +- reason, (const char *)src)); ++ DBG_NOTICE("convert_string_internal: Conversion error: %s\n", ++ reason); + break; + default: +- DEBUG(0,("convert_string_internal: Conversion error: %s(%s)\n", +- reason, (const char *)src)); ++ DBG_ERR("convert_string_internal: Conversion error: %s\n", ++ reason); + break; + } + /* smb_panic(reason); */ +@@ -427,20 +427,22 @@ bool convert_string_talloc_handle(TALLOC_CTX *ctx, struct smb_iconv_handle *ic, + switch(errno) { + case EINVAL: + reason="Incomplete multibyte sequence"; +- DEBUG(3,("convert_string_talloc: Conversion error: %s(%s)\n",reason,inbuf)); ++ DBG_NOTICE("Conversion error: %s\n", ++ reason); + break; + case E2BIG: + reason = "output buffer is too small"; +- DBG_NOTICE("convert_string_talloc: " +- "Conversion error: %s(%s)\n", +- reason, inbuf); ++ DBG_NOTICE("Conversion error: %s\n", ++ reason); + break; + case EILSEQ: + reason="Illegal multibyte sequence"; +- DEBUG(3,("convert_string_talloc: Conversion error: %s(%s)\n",reason,inbuf)); ++ DBG_NOTICE("Conversion error: %s\n", ++ reason); + break; + default: +- DEBUG(0,("Conversion error: %s(%s)\n",reason,inbuf)); ++ DBG_ERR("Conversion error: %s\n", ++ reason); + break; + } + /* smb_panic(reason); */ +-- +2.17.1 + diff --git a/SOURCES/krb5_no_des_411.patch b/SOURCES/krb5_no_des_411.patch new file mode 100644 index 0000000..0fd1286 --- /dev/null +++ b/SOURCES/krb5_no_des_411.patch @@ -0,0 +1,613 @@ +From d8c48f3773d72a5e36bb46a1c09ba11fc64ae38d Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Wed, 6 Nov 2019 09:17:52 +0100 +Subject: [PATCH 01/10] selftest/remote_pac: remove + test_PACVerify_workstation_des + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14202 + +Signed-off-by: Isaac Boukris +Reviewed-by: Andrew Bartlett +--- + source4/torture/rpc/remote_pac.c | 37 -------------------------------- + 1 file changed, 37 deletions(-) + +diff --git a/source4/torture/rpc/remote_pac.c b/source4/torture/rpc/remote_pac.c +index 7a5cda74b74..f12060e3c8f 100644 +--- a/source4/torture/rpc/remote_pac.c ++++ b/source4/torture/rpc/remote_pac.c +@@ -38,7 +38,6 @@ + + #define TEST_MACHINE_NAME_BDC "torturepacbdc" + #define TEST_MACHINE_NAME_WKSTA "torturepacwksta" +-#define TEST_MACHINE_NAME_WKSTA_DES "torturepacwkdes" + #define TEST_MACHINE_NAME_S4U2SELF_BDC "tests4u2selfbdc" + #define TEST_MACHINE_NAME_S4U2SELF_WKSTA "tests4u2selfwk" + +@@ -581,39 +580,6 @@ static bool test_PACVerify_workstation_aes(struct torture_context *tctx, + NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES); + } + +-static bool test_PACVerify_workstation_des(struct torture_context *tctx, +- struct dcerpc_pipe *p, struct cli_credentials *credentials, struct test_join *join_ctx) +-{ +- struct samr_SetUserInfo r; +- union samr_UserInfo user_info; +- struct dcerpc_pipe *samr_pipe = torture_join_samr_pipe(join_ctx); +- struct smb_krb5_context *smb_krb5_context; +- krb5_error_code ret; +- +- ret = cli_credentials_get_krb5_context(popt_get_cmdline_credentials(), +- tctx->lp_ctx, &smb_krb5_context); +- torture_assert_int_equal(tctx, ret, 0, "cli_credentials_get_krb5_context() failed"); +- +- if (smb_krb5_get_allowed_weak_crypto(smb_krb5_context->krb5_context) == FALSE) { +- torture_skip(tctx, "Cannot test DES without [libdefaults] allow_weak_crypto = yes"); +- } +- +- /* Mark this workstation with DES-only */ +- user_info.info16.acct_flags = ACB_USE_DES_KEY_ONLY | ACB_WSTRUST; +- r.in.user_handle = torture_join_samr_user_policy(join_ctx); +- r.in.level = 16; +- r.in.info = &user_info; +- +- torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(samr_pipe->binding_handle, tctx, &r), +- "failed to set DES info account flags"); +- torture_assert_ntstatus_ok(tctx, r.out.result, +- "failed to set DES into account flags"); +- +- return test_PACVerify(tctx, p, credentials, SEC_CHAN_WKSTA, +- TEST_MACHINE_NAME_WKSTA_DES, +- NETLOGON_NEG_AUTH2_ADS_FLAGS); +-} +- + #ifdef SAMBA4_USES_HEIMDAL + static NTSTATUS check_primary_group_in_validation(TALLOC_CTX *mem_ctx, + uint16_t validation_level, +@@ -1000,9 +966,6 @@ struct torture_suite *torture_rpc_remote_pac(TALLOC_CTX *mem_ctx) + &ndr_table_netlogon, TEST_MACHINE_NAME_WKSTA); + torture_rpc_tcase_add_test_creds(tcase, "verify-sig-aes", test_PACVerify_workstation_aes); + +- tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "netlogon-member-des", +- &ndr_table_netlogon, TEST_MACHINE_NAME_WKSTA_DES); +- torture_rpc_tcase_add_test_join(tcase, "verify-sig", test_PACVerify_workstation_des); + #ifdef SAMBA4_USES_HEIMDAL + tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netr-bdc-arcfour", + &ndr_table_netlogon, TEST_MACHINE_NAME_S4U2SELF_BDC); +-- +2.24.1 + + +From c19bef15eba2f8436d3ffafae5e640c6581fdb81 Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Thu, 31 Oct 2019 19:41:46 +0100 +Subject: [PATCH 02/10] selftest: exclude msDS-SupportedEncryptionType in + ldapcmp + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14202 + +Pair-Programmed-With: Alexander Bokovoy + +Signed-off-by: Isaac Boukris +Reviewed-by: Andrew Bartlett +--- + testprogs/blackbox/dbcheck-oldrelease.sh | 2 +- + testprogs/blackbox/functionalprep.sh | 2 +- + testprogs/blackbox/upgradeprovision-oldrelease.sh | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/testprogs/blackbox/dbcheck-oldrelease.sh b/testprogs/blackbox/dbcheck-oldrelease.sh +index 3d0ee2c165a..41c55178d4e 100755 +--- a/testprogs/blackbox/dbcheck-oldrelease.sh ++++ b/testprogs/blackbox/dbcheck-oldrelease.sh +@@ -388,7 +388,7 @@ referenceprovision() { + + ldapcmp() { + if [ x$RELEASE = x"release-4-0-0" ]; then +- $PYTHON $BINDIR/samba-tool ldapcmp tdb://$PREFIX_ABS/${RELEASE}_reference/private/sam.ldb tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb --two --skip-missing-dn --filter=dnsRecord,displayName ++ $PYTHON $BINDIR/samba-tool ldapcmp tdb://$PREFIX_ABS/${RELEASE}_reference/private/sam.ldb tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb --two --skip-missing-dn --filter=dnsRecord,displayName,msDS-SupportedEncryptionTypes + fi + } + +diff --git a/testprogs/blackbox/functionalprep.sh b/testprogs/blackbox/functionalprep.sh +index 80e82252d45..1d37611ef7a 100755 +--- a/testprogs/blackbox/functionalprep.sh ++++ b/testprogs/blackbox/functionalprep.sh +@@ -61,7 +61,7 @@ provision_2012r2() { + ldapcmp_ignore() { + # At some point we will need to ignore, but right now, it should be perfect + IGNORE_ATTRS=$1 +- $PYTHON $BINDIR/samba-tool ldapcmp tdb://$PREFIX_ABS/$2/private/sam.ldb tdb://$PREFIX_ABS/$3/private/sam.ldb --two --skip-missing-dn ++ $PYTHON $BINDIR/samba-tool ldapcmp tdb://$PREFIX_ABS/$2/private/sam.ldb tdb://$PREFIX_ABS/$3/private/sam.ldb --two --skip-missing-dn --filter msDS-SupportedEncryptionTypes + } + + ldapcmp() { +diff --git a/testprogs/blackbox/upgradeprovision-oldrelease.sh b/testprogs/blackbox/upgradeprovision-oldrelease.sh +index 76276168011..208baa54a02 100755 +--- a/testprogs/blackbox/upgradeprovision-oldrelease.sh ++++ b/testprogs/blackbox/upgradeprovision-oldrelease.sh +@@ -106,7 +106,7 @@ referenceprovision() { + + ldapcmp() { + if [ x$RELEASE != x"alpha13" ]; then +- $PYTHON $BINDIR/samba-tool ldapcmp tdb://$PREFIX_ABS/${RELEASE}_upgrade_reference/private/sam.ldb tdb://$PREFIX_ABS/${RELEASE}_upgrade/private/sam.ldb --two --skip-missing-dn --filter=dnsRecord,displayName ++ $PYTHON $BINDIR/samba-tool ldapcmp tdb://$PREFIX_ABS/${RELEASE}_upgrade_reference/private/sam.ldb tdb://$PREFIX_ABS/${RELEASE}_upgrade/private/sam.ldb --two --skip-missing-dn --filter=dnsRecord,displayName,msDS-SupportedEncryptionTypes + fi + } + +-- +2.24.1 + + +From afb8e18c42122841111b6077bb26bd5dd95e5c55 Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Thu, 24 Oct 2019 12:20:05 +0300 +Subject: [PATCH 03/10] kerberos: remove single DES enctypes from ENC_ALL_TYPES + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14202 + +Signed-off-by: Isaac Boukris +Reviewed-by: Andrew Bartlett +--- + source4/auth/kerberos/kerberos.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/source4/auth/kerberos/kerberos.h b/source4/auth/kerberos/kerberos.h +index 2ff9e3868af..1dd63acc838 100644 +--- a/source4/auth/kerberos/kerberos.h ++++ b/source4/auth/kerberos/kerberos.h +@@ -50,7 +50,7 @@ struct keytab_container { + #define TOK_ID_GSS_GETMIC ((const uint8_t *)"\x01\x01") + #define TOK_ID_GSS_WRAP ((const uint8_t *)"\x02\x01") + +-#define ENC_ALL_TYPES (ENC_CRC32 | ENC_RSA_MD5 | ENC_RC4_HMAC_MD5 | \ ++#define ENC_ALL_TYPES (ENC_RC4_HMAC_MD5 | \ + ENC_HMAC_SHA1_96_AES128 | ENC_HMAC_SHA1_96_AES256) + + #ifndef HAVE_KRB5_SET_DEFAULT_TGS_KTYPES +-- +2.24.1 + + +From 4747d04bd8c9d694b613cdec92640312208aee9d Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Thu, 24 Oct 2019 18:53:34 +0300 +Subject: [PATCH 04/10] kdc/db-glue: do not fetch single DES keys from db + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14202 + +Signed-off-by: Isaac Boukris +Reviewed-by: Andrew Bartlett +--- + source4/kdc/db-glue.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/source4/kdc/db-glue.c b/source4/kdc/db-glue.c +index f62a633c6c7..023ae7b580d 100644 +--- a/source4/kdc/db-glue.c ++++ b/source4/kdc/db-glue.c +@@ -359,10 +359,10 @@ static krb5_error_code samba_kdc_message2entry_keys(krb5_context context, + + /* If UF_USE_DES_KEY_ONLY has been set, then don't allow use of the newer enc types */ + if (userAccountControl & UF_USE_DES_KEY_ONLY) { +- supported_enctypes = ENC_CRC32|ENC_RSA_MD5; ++ supported_enctypes = 0; + } else { + /* Otherwise, add in the default enc types */ +- supported_enctypes |= ENC_CRC32 | ENC_RSA_MD5 | ENC_RC4_HMAC_MD5; ++ supported_enctypes |= ENC_RC4_HMAC_MD5; + } + + /* Is this the krbtgt or a RODC krbtgt */ +-- +2.24.1 + + +From 5c460fe678eb5db9f0f2eed67a6be8c07ca8d53c Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Thu, 24 Oct 2019 18:32:37 +0300 +Subject: [PATCH 05/10] password_hash: do not generate single DES keys + +Per RFC-6649 single DES enctypes should not be used. + +MIT has retired single DES encryption types, see: +https://web.mit.edu/kerberos/krb5-1.12/doc/admin/advanced/retiring-des.html + +As a workaround, store random keys instead, making the usage of signle DES +encryption types virtually impossible. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14202 + +Signed-off-by: Isaac Boukris +Reviewed-by: Andrew Bartlett +--- + .../dsdb/samdb/ldb_modules/password_hash.c | 49 +++---------------- + 1 file changed, 7 insertions(+), 42 deletions(-) + +diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c +index 006e35c46d5..ffd48da616e 100644 +--- a/source4/dsdb/samdb/ldb_modules/password_hash.c ++++ b/source4/dsdb/samdb/ldb_modules/password_hash.c +@@ -783,56 +783,21 @@ static int setup_kerberos_keys(struct setup_password_fields_io *io) + } + + /* +- * create ENCTYPE_DES_CBC_MD5 key out of +- * the salt and the cleartext password ++ * As per RFC-6649 single DES encryption types are no longer considered ++ * secure to be used in Kerberos, we store random keys instead of the ++ * ENCTYPE_DES_CBC_MD5 and ENCTYPE_DES_CBC_CRC keys. + */ +- krb5_ret = smb_krb5_create_key_from_string(io->smb_krb5_context->krb5_context, +- NULL, +- &salt, +- &cleartext_data, +- ENCTYPE_DES_CBC_MD5, +- &key); +- if (krb5_ret) { +- ldb_asprintf_errstring(ldb, +- "setup_kerberos_keys: " +- "generation of a des-cbc-md5 key failed: %s", +- smb_get_krb5_error_message(io->smb_krb5_context->krb5_context, +- krb5_ret, io->ac)); +- return LDB_ERR_OPERATIONS_ERROR; +- } +- io->g.des_md5 = data_blob_talloc(io->ac, +- KRB5_KEY_DATA(&key), +- KRB5_KEY_LENGTH(&key)); +- krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key); ++ io->g.des_md5 = data_blob_talloc(io->ac, NULL, 8); + if (!io->g.des_md5.data) { + return ldb_oom(ldb); + } ++ generate_secret_buffer(io->g.des_md5.data, 8); + +- /* +- * create ENCTYPE_DES_CBC_CRC key out of +- * the salt and the cleartext password +- */ +- krb5_ret = smb_krb5_create_key_from_string(io->smb_krb5_context->krb5_context, +- NULL, +- &salt, +- &cleartext_data, +- ENCTYPE_DES_CBC_CRC, +- &key); +- if (krb5_ret) { +- ldb_asprintf_errstring(ldb, +- "setup_kerberos_keys: " +- "generation of a des-cbc-crc key failed: %s", +- smb_get_krb5_error_message(io->smb_krb5_context->krb5_context, +- krb5_ret, io->ac)); +- return LDB_ERR_OPERATIONS_ERROR; +- } +- io->g.des_crc = data_blob_talloc(io->ac, +- KRB5_KEY_DATA(&key), +- KRB5_KEY_LENGTH(&key)); +- krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key); ++ io->g.des_crc = data_blob_talloc(io->ac, NULL, 8); + if (!io->g.des_crc.data) { + return ldb_oom(ldb); + } ++ generate_secret_buffer(io->g.des_crc.data, 8); + + return LDB_SUCCESS; + } +-- +2.24.1 + + +From 000abe4e405ce5fa4eae6235335bfca2a8152e3c Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Thu, 24 Oct 2019 19:04:51 +0300 +Subject: [PATCH 06/10] kerberos_keytab: do not add single DES keys to keytab + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14202 + +Signed-off-by: Isaac Boukris +Reviewed-by: Andrew Bartlett +--- + source3/libads/kerberos_keytab.c | 2 -- + testprogs/blackbox/test_export_keytab_heimdal.sh | 16 ++++++++-------- + 2 files changed, 8 insertions(+), 10 deletions(-) + +diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c +index 97d5535041c..7d193e1a600 100644 +--- a/source3/libads/kerberos_keytab.c ++++ b/source3/libads/kerberos_keytab.c +@@ -240,8 +240,6 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc, bool update_ads) + krb5_data password; + krb5_kvno kvno; + krb5_enctype enctypes[6] = { +- ENCTYPE_DES_CBC_CRC, +- ENCTYPE_DES_CBC_MD5, + #ifdef HAVE_ENCTYPE_AES128_CTS_HMAC_SHA1_96 + ENCTYPE_AES128_CTS_HMAC_SHA1_96, + #endif +diff --git a/testprogs/blackbox/test_export_keytab_heimdal.sh b/testprogs/blackbox/test_export_keytab_heimdal.sh +index cfa245fd4de..6a2595cd684 100755 +--- a/testprogs/blackbox/test_export_keytab_heimdal.sh ++++ b/testprogs/blackbox/test_export_keytab_heimdal.sh +@@ -43,7 +43,7 @@ test_keytab() { + + echo "test: $testname" + +- NKEYS=$($VALGRIND $samba4ktutil $keytab | grep -i "$principal" | egrep -c "des|aes|arcfour") ++ NKEYS=$($VALGRIND $samba4ktutil $keytab | grep -i "$principal" | egrep -c "aes|arcfour") + status=$? + if [ x$status != x0 ]; then + echo "failure: $testname" +@@ -64,22 +64,22 @@ unc="//$SERVER/tmp" + testit "create user locally" $VALGRIND $PYTHON $newuser nettestuser $USERPASS $@ || failed=`expr $failed + 1` + + testit "dump keytab from domain" $VALGRIND $PYTHON $samba_tool domain exportkeytab $PREFIX/tmpkeytab $@ || failed=`expr $failed + 1` +-test_keytab "read keytab from domain" "$PREFIX/tmpkeytab" "$SERVER\\\$" 5 ++test_keytab "read keytab from domain" "$PREFIX/tmpkeytab" "$SERVER\\\$" 3 + testit "dump keytab from domain (2nd time)" $VALGRIND $PYTHON $samba_tool domain exportkeytab $PREFIX/tmpkeytab $@ || failed=`expr $failed + 1` +-test_keytab "read keytab from domain (2nd time)" "$PREFIX/tmpkeytab" "$SERVER\\\$" 5 ++test_keytab "read keytab from domain (2nd time)" "$PREFIX/tmpkeytab" "$SERVER\\\$" 3 + + testit "dump keytab from domain for cifs principal" $VALGRIND $PYTHON $samba_tool domain exportkeytab $PREFIX/tmpkeytab-server --principal=cifs/$SERVER_FQDN $@ || failed=`expr $failed + 1` +-test_keytab "read keytab from domain for cifs principal" "$PREFIX/tmpkeytab-server" "cifs/$SERVER_FQDN" 5 ++test_keytab "read keytab from domain for cifs principal" "$PREFIX/tmpkeytab-server" "cifs/$SERVER_FQDN" 3 + testit "dump keytab from domain for cifs principal (2nd time)" $VALGRIND $PYTHON $samba_tool domain exportkeytab $PREFIX/tmpkeytab-server --principal=cifs/$SERVER_FQDN $@ || failed=`expr $failed + 1` +-test_keytab "read keytab from domain for cifs principal (2nd time)" "$PREFIX/tmpkeytab-server" "cifs/$SERVER_FQDN" 5 ++test_keytab "read keytab from domain for cifs principal (2nd time)" "$PREFIX/tmpkeytab-server" "cifs/$SERVER_FQDN" 3 + + testit "dump keytab from domain for user principal" $VALGRIND $PYTHON $samba_tool domain exportkeytab $PREFIX/tmpkeytab-2 --principal=nettestuser $@ || failed=`expr $failed + 1` +-test_keytab "dump keytab from domain for user principal" "$PREFIX/tmpkeytab-2" "nettestuser@$REALM" 5 ++test_keytab "dump keytab from domain for user principal" "$PREFIX/tmpkeytab-2" "nettestuser@$REALM" 3 + testit "dump keytab from domain for user principal (2nd time)" $VALGRIND $PYTHON $samba_tool domain exportkeytab $PREFIX/tmpkeytab-2 --principal=nettestuser@$REALM $@ || failed=`expr $failed + 1` +-test_keytab "dump keytab from domain for user principal (2nd time)" "$PREFIX/tmpkeytab-2" "nettestuser@$REALM" 5 ++test_keytab "dump keytab from domain for user principal (2nd time)" "$PREFIX/tmpkeytab-2" "nettestuser@$REALM" 3 + + testit "dump keytab from domain for user principal with SPN as UPN" $VALGRIND $PYTHON $samba_tool domain exportkeytab $PREFIX/tmpkeytab-3 --principal=http/testupnspn.$DNSDOMAIN $@ || failed=`expr $failed + 1` +-test_keytab "dump keytab from domain for user principal" "$PREFIX/tmpkeytab-3" "http/testupnspn.$DNSDOMAIN@$REALM" 5 ++test_keytab "dump keytab from domain for user principal" "$PREFIX/tmpkeytab-3" "http/testupnspn.$DNSDOMAIN@$REALM" 3 + + KRB5CCNAME="$PREFIX/tmpuserccache" + export KRB5CCNAME +-- +2.24.1 + + +From 4e96a263c2c038bc4c835b78161623cc4d050c61 Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Mon, 16 Sep 2019 15:17:08 +0300 +Subject: [PATCH 07/10] machine_account_secrets: do not generate single DES + keys + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14202 + +Signed-off-by: Isaac Boukris +Reviewed-by: Andrew Bartlett +--- + source3/passdb/machine_account_secrets.c | 36 ------------------------ + 1 file changed, 36 deletions(-) + +diff --git a/source3/passdb/machine_account_secrets.c b/source3/passdb/machine_account_secrets.c +index dfc21f295a1..efba80f1474 100644 +--- a/source3/passdb/machine_account_secrets.c ++++ b/source3/passdb/machine_account_secrets.c +@@ -1031,7 +1031,6 @@ static int secrets_domain_info_kerberos_keys(struct secrets_domain_info1_passwor + krb5_keyblock key; + DATA_BLOB aes_256_b = data_blob_null; + DATA_BLOB aes_128_b = data_blob_null; +- DATA_BLOB des_md5_b = data_blob_null; + bool ok; + #endif /* HAVE_ADS */ + DATA_BLOB arc4_b = data_blob_null; +@@ -1177,32 +1176,6 @@ static int secrets_domain_info_kerberos_keys(struct secrets_domain_info1_passwor + return ENOMEM; + } + +- krb5_ret = smb_krb5_create_key_from_string(krb5_ctx, +- NULL, +- &salt, +- &cleartext_utf8, +- ENCTYPE_DES_CBC_MD5, +- &key); +- if (krb5_ret != 0) { +- DBG_ERR("generation of a des-cbc-md5 key failed: %s\n", +- smb_get_krb5_error_message(krb5_ctx, krb5_ret, keys)); +- krb5_free_context(krb5_ctx); +- TALLOC_FREE(keys); +- TALLOC_FREE(salt_data); +- return krb5_ret; +- } +- des_md5_b = data_blob_talloc(keys, +- KRB5_KEY_DATA(&key), +- KRB5_KEY_LENGTH(&key)); +- krb5_free_keyblock_contents(krb5_ctx, &key); +- if (des_md5_b.data == NULL) { +- DBG_ERR("data_blob_talloc failed for des-cbc-md5.\n"); +- krb5_free_context(krb5_ctx); +- TALLOC_FREE(keys); +- TALLOC_FREE(salt_data); +- return ENOMEM; +- } +- + krb5_free_context(krb5_ctx); + no_kerberos: + +@@ -1227,15 +1200,6 @@ no_kerberos: + keys[idx].value = arc4_b; + idx += 1; + +-#ifdef HAVE_ADS +- if (des_md5_b.length != 0) { +- keys[idx].keytype = ENCTYPE_DES_CBC_MD5; +- keys[idx].iteration_count = 4096; +- keys[idx].value = des_md5_b; +- idx += 1; +- } +-#endif /* HAVE_ADS */ +- + p->salt_data = salt_data; + p->default_iteration_count = 4096; + p->num_keys = idx; +-- +2.24.1 + + +From 79fce8cfb906ca8b5bfa5f1954bf81ff950c3d23 Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Tue, 12 Nov 2019 12:00:34 +0100 +Subject: [PATCH 08/10] selftest: mitm-s4u2self: use zlib for CRC32_checksum + calc + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14202 + +Signed-off-by: Isaac Boukris +Reviewed-by: Andrew Bartlett +--- + source4/torture/krb5/kdc-canon-heimdal.c | 19 +++++++++++++------ + 1 file changed, 13 insertions(+), 6 deletions(-) + +diff --git a/source4/torture/krb5/kdc-canon-heimdal.c b/source4/torture/krb5/kdc-canon-heimdal.c +index ee3045181dc..7dec67bc49b 100644 +--- a/source4/torture/krb5/kdc-canon-heimdal.c ++++ b/source4/torture/krb5/kdc-canon-heimdal.c +@@ -33,6 +33,7 @@ + #include "auth/auth_sam_reply.h" + #include "auth/gensec/gensec.h" + #include "param/param.h" ++#include "zlib.h" + + #define TEST_CANONICALIZE 0x0000001 + #define TEST_ENTERPRISE 0x0000002 +@@ -214,6 +215,17 @@ static bool test_accept_ticket(struct torture_context *tctx, + return true; + } + ++static void ++zCRC32_checksum(const void *data, ++ size_t len, ++ Checksum *C) ++{ ++ uint32_t *crc = C->checksum.data; ++ *crc = ~(crc32(0xffffffff, data, len)); ++ C->checksum.length = 4; ++ C->cksumtype = 1; ++} ++ + krb5_error_code + _krb5_s4u2self_to_checksumdata(krb5_context context, + const PA_S4U2Self *self, +@@ -252,11 +264,7 @@ static bool change_for_user_principal(struct torture_krb5_context *test_context, + torture_assert_int_equal(test_context->tctx, + _krb5_s4u2self_to_checksumdata(k5_ctx, &mod_self, &cksum_data), + 0, "_krb5_s4u2self_to_checksumdata() failed"); +- torture_assert_int_equal(test_context->tctx, +- krb5_create_checksum(k5_ctx, NULL, KRB5_KU_OTHER_CKSUM, +- CKSUMTYPE_CRC32, cksum_data.data, +- cksum_data.length, &mod_self.cksum), +- 0, "krb5_create_checksum() failed"); ++ zCRC32_checksum(cksum_data.data, cksum_data.length, &mod_self.cksum); + + ASN1_MALLOC_ENCODE(PA_S4U2Self, for_user->padata_value.data, for_user->padata_value.length, + &mod_self, &used, ret); +@@ -270,7 +278,6 @@ static bool change_for_user_principal(struct torture_krb5_context *test_context, + + free_PA_S4U2Self(&self); + krb5_data_free(&cksum_data); +- free_Checksum(&mod_self.cksum); + + return true; + } +-- +2.24.1 + + +From 1a658936884a9a18616fcb1d13b8f9b6be587322 Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Sat, 16 Nov 2019 22:46:19 +0100 +Subject: [PATCH 09/10] selftest: allow any kdc error in mitm-s4u2self test + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14202 + +Signed-off-by: Isaac Boukris +Reviewed-by: Andrew Bartlett +--- + source4/torture/krb5/kdc-canon-heimdal.c | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +diff --git a/source4/torture/krb5/kdc-canon-heimdal.c b/source4/torture/krb5/kdc-canon-heimdal.c +index 7dec67bc49b..5315afa9252 100644 +--- a/source4/torture/krb5/kdc-canon-heimdal.c ++++ b/source4/torture/krb5/kdc-canon-heimdal.c +@@ -737,13 +737,12 @@ static bool torture_krb5_post_recv_tgs_req_canon_test(struct torture_krb5_contex + error.pvno, 5, + "Got wrong error.pvno"); + expected_error = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN - KRB5KDC_ERR_NONE; +- if (error.error_code != expected_error && test_context->test_data->mitm_s4u2self) { +- expected_error = KRB5KRB_AP_ERR_INAPP_CKSUM - KRB5KDC_ERR_NONE; ++ if (!test_context->test_data->mitm_s4u2self) { ++ torture_assert_int_equal(test_context->tctx, ++ error.error_code, ++ expected_error, ++ "Got wrong error.error_code"); + } +- torture_assert_int_equal(test_context->tctx, +- error.error_code, +- expected_error, +- "Got wrong error.error_code"); + } else { + torture_assert_int_equal(test_context->tctx, + decode_TGS_REP(recv_buf->data, recv_buf->length, +@@ -2090,8 +2089,7 @@ static bool torture_krb5_as_req_canon(struct torture_context *tctx, const void * + || test_data->upn == false)) { + + if (test_data->mitm_s4u2self) { +- torture_assert_int_equal(tctx, k5ret, KRB5KRB_AP_ERR_INAPP_CKSUM, +- assertion_message); ++ torture_assert_int_not_equal(tctx, k5ret, 0, assertion_message); + /* Done testing mitm-s4u2self */ + return true; + } +-- +2.24.1 + + +From 80ebb75804312a848df4cf5ab883291eaf816130 Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Sat, 16 Nov 2019 23:03:34 +0100 +Subject: [PATCH 10/10] heimdal: do not compile weak crypto + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14202 + +Signed-off-by: Isaac Boukris +Reviewed-by: Andrew Bartlett +--- + selftest/target/Samba.pm | 1 - + source4/heimdal_build/roken.h | 3 --- + 2 files changed, 4 deletions(-) + +diff --git a/selftest/target/Samba.pm b/selftest/target/Samba.pm +index c30f6fe33ce..3f5ac64c8c2 100644 +--- a/selftest/target/Samba.pm ++++ b/selftest/target/Samba.pm +@@ -261,7 +261,6 @@ sub mk_krb5_conf($$) + dns_lookup_kdc = true + ticket_lifetime = 24h + forwardable = yes +- allow_weak_crypto = yes + + # We are running on the same machine, do not correct + # system clock differences +diff --git a/source4/heimdal_build/roken.h b/source4/heimdal_build/roken.h +index 9752c04a741..559021c0a0e 100644 +--- a/source4/heimdal_build/roken.h ++++ b/source4/heimdal_build/roken.h +@@ -6,9 +6,6 @@ + + #include "config.h" + +-/* Support 'weak' keys for now, it can't be worse than NTLM and we don't want to hard-code the behaviour at this point */ +-#define HEIM_WEAK_CRYPTO 1 +- + /* path to sysconf - should we force this to samba LIBDIR ? */ + #define SYSCONFDIR "/etc" + +-- +2.24.1 + diff --git a/SOURCES/samba-4.10-Fix_forest_trust_with_additional_attrs.patch b/SOURCES/samba-4.10-Fix_forest_trust_with_additional_attrs.patch deleted file mode 100644 index 6f7ca74..0000000 --- a/SOURCES/samba-4.10-Fix_forest_trust_with_additional_attrs.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 2d783791856be182d420555d8df5e31768b0d7d2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?G=C3=BCnther=20Deschner?= -Date: Thu, 12 Sep 2019 16:39:10 +0200 -Subject: [PATCH] s3-winbindd: fix forest trusts with additional trust - attributes. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14130 - -Guenther - -Signed-off-by: Guenther Deschner -Reviewed-by: Stefan Metzmacher -Reviewed-by: Andreas Schneider -(cherry picked from commit d78c87e665e23e6470a19a69383ede7137172c26) ---- - source3/winbindd/winbindd_ads.c | 2 +- - source3/winbindd/winbindd_util.c | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/source3/winbindd/winbindd_ads.c b/source3/winbindd/winbindd_ads.c -index 5f20cfb7f76..485ca831be9 100644 ---- a/source3/winbindd/winbindd_ads.c -+++ b/source3/winbindd/winbindd_ads.c -@@ -1457,7 +1457,7 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain, - */ - - if ((trust->trust_attributes -- == LSA_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) && -+ & LSA_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) && - !domain->primary ) - { - DEBUG(10,("trusted_domains: Skipping external trusted " -diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c -index cc4c3f7391a..ee7651c9639 100644 ---- a/source3/winbindd/winbindd_util.c -+++ b/source3/winbindd/winbindd_util.c -@@ -723,7 +723,7 @@ static void rescan_forest_trusts( void ) - - if ( (flags & NETR_TRUST_FLAG_INBOUND) && - (type == LSA_TRUST_TYPE_UPLEVEL) && -- (attribs == LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) ) -+ (attribs & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) ) - { - /* add the trusted domain if we don't know - about it */ --- -2.21.0 - diff --git a/SOURCES/samba-4.10-Remove_shm_get_configure_check.patch b/SOURCES/samba-4.10-Remove_shm_get_configure_check.patch deleted file mode 100644 index 9077d9e..0000000 --- a/SOURCES/samba-4.10-Remove_shm_get_configure_check.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 233bed607ae59f85db7592729e0e5fd3206a9ee2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Bj=C3=B6rn=20Jacke?= -Date: Mon, 11 Feb 2019 10:03:00 +0100 -Subject: [PATCH 1/2] waf: print the library name in which we search for a - function - -Signed-off-by: Bjoern Jacke -Reviewed-by: Andreas Schneider -(cherry picked from commit 7058a88cbe3c1a2ad272b6debc1c9d09a259d116) ---- - buildtools/wafsamba/samba_autoconf.py | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/buildtools/wafsamba/samba_autoconf.py b/buildtools/wafsamba/samba_autoconf.py -index 6208e3b0439..a39d6ef06d1 100644 ---- a/buildtools/wafsamba/samba_autoconf.py -+++ b/buildtools/wafsamba/samba_autoconf.py -@@ -251,7 +251,10 @@ def CHECK_FUNC(conf, f, link=True, lib=None, headers=None): - - ret = False - -- conf.COMPOUND_START('Checking for %s' % f) -+ in_lib_str = "" -+ if lib: -+ in_lib_str = " in %s" % lib -+ conf.COMPOUND_START('Checking for %s%s' % (f, in_lib_str)) - - if link is None or link: - ret = CHECK_CODE(conf, --- -2.23.0 - - -From 8ee1eed377186628675ff1590bc69175ed5def48 Mon Sep 17 00:00:00 2001 -From: Christof Schmitt -Date: Wed, 24 Apr 2019 10:16:30 -0700 -Subject: [PATCH 2/2] wscript: Remove checks for shm_open and shmget - -Commit 74a16a1094278 "s3:smbprofile: Replace sysv shmem with tdb" -removed the usage of the shared memory segment for profiling data. As -there are no other users of shared memory segments, remove the configure -check for these functions. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14140 - -Signed-off-by: Christof Schmitt -Reviewed-by: Jeremy Allison -(cherry picked from commit 94f2ed3eb35b94d5152578dbb6d5ee8f2fa2da69) ---- - source3/wscript | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/source3/wscript b/source3/wscript -index 5c2ba18f872..9d283e40a40 100644 ---- a/source3/wscript -+++ b/source3/wscript -@@ -119,8 +119,6 @@ def configure(conf): - conf.CHECK_FUNCS('lutimes futimes utimensat futimens') - conf.CHECK_FUNCS('mlock munlock mlockall munlockall') - conf.CHECK_FUNCS('memalign posix_memalign hstrerror') -- conf.CHECK_FUNCS('shmget') -- conf.CHECK_FUNCS_IN('shm_open', 'rt', checklibc=True) - conf.CHECK_FUNCS_IN('yp_get_default_domain', 'nsl') - conf.CHECK_FUNCS_IN('dn_expand _dn_expand __dn_expand', 'resolv') - conf.CHECK_FUNCS_IN('dn_expand', 'inet') -@@ -408,7 +406,6 @@ rdchk _read __read _readdir __readdir - _seekdir __seekdir - select setenv setgidx setgroups setlocale setluid - setmntent setpgid setpriv setsid setuidx --shmget shm_open - _stat __stat statvfs - strcasecmp strchr strpbrk strsignal strtol strupr sysconf sysctl sysctlbyname - __sys_llseek syslog _telldir __telldir timegm --- -2.23.0 - diff --git a/SOURCES/samba-4.10-avoid_overlinking_with_librt_and_libpthread.patch b/SOURCES/samba-4.10-avoid_overlinking_with_librt_and_libpthread.patch deleted file mode 100644 index 74df9e2..0000000 --- a/SOURCES/samba-4.10-avoid_overlinking_with_librt_and_libpthread.patch +++ /dev/null @@ -1,415 +0,0 @@ -From 5095b43b5ea079aab47963fa443a0d697f4a7af9 Mon Sep 17 00:00:00 2001 -From: Andreas Schneider -Date: Mon, 23 Sep 2019 15:18:55 +0200 -Subject: [PATCH 1/9] s3:waf: Do not check for nanosleep() as we don't use it - anywhere -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -We use usleep() in the meantime. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14140 - -Signed-off-by: Andreas Schneider -Signed-off-by: Isaac Boukris -Pair-Programmed-With: Isaac Boukris -Reviewed-by: Matthias Dieter Wallnöfer -Reviewed-by: Alexander Bokovoy -(cherry picked from commit 952e1812fa9bdc1bac2a7ae5ebb5532f1ea31447) ---- - source3/wscript | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/source3/wscript b/source3/wscript -index 84a2ad9e601..5c2ba18f872 100644 ---- a/source3/wscript -+++ b/source3/wscript -@@ -116,7 +116,6 @@ def configure(conf): - conf.CHECK_FUNCS('fstatat') - conf.CHECK_FUNCS('getpwent_r setenv clearenv strcasecmp fcvt fcvtl') - conf.CHECK_FUNCS('syslog vsyslog timegm setlocale') -- conf.CHECK_FUNCS_IN('nanosleep', 'rt') - conf.CHECK_FUNCS('lutimes futimes utimensat futimens') - conf.CHECK_FUNCS('mlock munlock mlockall munlockall') - conf.CHECK_FUNCS('memalign posix_memalign hstrerror') --- -2.23.0 - - -From 74d4e574e0f971bd7c0bf60af696d285c3a01aae Mon Sep 17 00:00:00 2001 -From: Andreas Schneider -Date: Mon, 23 Sep 2019 15:14:24 +0200 -Subject: [PATCH 2/9] replace: Only link against librt if really needed -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -fdatasync() and clock_gettime() are provided by glibc on Linux, so there -is no need to link against librt. Checks have been added so if there are -platforms which require it are still functional. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14140 - -Signed-off-by: Andreas Schneider -Signed-off-by: Isaac Boukris -Pair-Programmed-With: Isaac Boukris -Reviewed-by: Matthias Dieter Wallnöfer -Reviewed-by: Alexander Bokovoy -(cherry picked from commit 480152dd6729d4c58faca6f3e4fa91ff4614c272) ---- - lib/replace/wscript | 24 +++++++++++++++++++++--- - 1 file changed, 21 insertions(+), 3 deletions(-) - -diff --git a/lib/replace/wscript b/lib/replace/wscript -index a7fd25d15bc..d8423b1d281 100644 ---- a/lib/replace/wscript -+++ b/lib/replace/wscript -@@ -457,11 +457,28 @@ def configure(conf): - conf.CHECK_C_PROTOTYPE('dlopen', 'void *dlopen(const char* filename, unsigned int flags)', - define='DLOPEN_TAKES_UNSIGNED_FLAGS', headers='dlfcn.h dl.h') - -- if conf.CHECK_FUNCS_IN('fdatasync', 'rt', checklibc=True): -+ # -+ # Check for clock_gettime and fdatasync -+ # -+ # First check libc to avoid linking libreplace against librt. -+ # -+ if conf.CHECK_FUNCS('fdatasync'): - # some systems are missing the declaration - conf.CHECK_DECLS('fdatasync') -+ else: -+ if conf.CHECK_FUNCS_IN('fdatasync', 'rt'): -+ # some systems are missing the declaration -+ conf.CHECK_DECLS('fdatasync') -+ -+ has_clock_gettime = False -+ if conf.CHECK_FUNCS('clock_gettime'): -+ has_clock_gettime = True -+ -+ if not has_clock_gettime: -+ if conf.CHECK_FUNCS_IN('clock_gettime', 'rt', checklibc=True): -+ has_clock_gettime = True - -- if conf.CHECK_FUNCS_IN('clock_gettime', 'rt', checklibc=True): -+ if has_clock_gettime: - for c in ['CLOCK_MONOTONIC', 'CLOCK_PROCESS_CPUTIME_ID', 'CLOCK_REALTIME']: - conf.CHECK_CODE(''' - #if TIME_WITH_SYS_TIME -@@ -815,6 +832,7 @@ def build(bld): - - extra_libs = '' - if bld.CONFIG_SET('HAVE_LIBBSD'): extra_libs += ' bsd' -+ if bld.CONFIG_SET('HAVE_LIBRT'): extra_libs += ' rt' - - bld.SAMBA_SUBSYSTEM('LIBREPLACE_HOSTCC', - REPLACE_HOSTCC_SOURCE, -@@ -855,7 +873,7 @@ def build(bld): - # at the moment: - # hide_symbols=bld.BUILTIN_LIBRARY('replace'), - private_library=True, -- deps='crypt dl nsl socket rt attr' + extra_libs) -+ deps='crypt dl nsl socket attr' + extra_libs) - - replace_test_cflags = '' - if bld.CONFIG_SET('HAVE_WNO_FORMAT_TRUNCATION'): --- -2.23.0 - - -From 58859a3088a74753b301e48b964edb6d242d245a Mon Sep 17 00:00:00 2001 -From: Andreas Schneider -Date: Mon, 23 Sep 2019 16:10:35 +0200 -Subject: [PATCH 3/9] pthreadpool: Only link pthreadpool against librt if we - have to -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This calls clock_gettime() which is available in glibc on Linux. If the -wscript in libreplace detected that librt is needed for clock_gettime() -we have to link against it. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14140 - -Signed-off-by: Andreas Schneider -Signed-off-by: Isaac Boukris -Pair-Programmed-With: Isaac Boukris -Reviewed-by: Matthias Dieter Wallnöfer -Reviewed-by: Alexander Bokovoy -(cherry picked from commit 4b28239d13b17e42eb5aa4b405342f46347f3de4) ---- - lib/pthreadpool/wscript_build | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/lib/pthreadpool/wscript_build b/lib/pthreadpool/wscript_build -index 57df25548b1..70aa7cbf041 100644 ---- a/lib/pthreadpool/wscript_build -+++ b/lib/pthreadpool/wscript_build -@@ -1,12 +1,17 @@ - #!/usr/bin/env python - - if bld.env.WITH_PTHREADPOOL: -+ extra_libs='' -+ -+ # Link to librt if needed for clock_gettime() -+ if bld.CONFIG_SET('HAVE_LIBRT'): extra_libs += ' rt' -+ - bld.SAMBA_SUBSYSTEM('PTHREADPOOL', - source='''pthreadpool.c - pthreadpool_pipe.c - pthreadpool_tevent.c - ''', -- deps='pthread rt replace tevent-util') -+ deps='pthread replace tevent-util' + extra_libs) - else: - bld.SAMBA_SUBSYSTEM('PTHREADPOOL', - source='''pthreadpool_sync.c --- -2.23.0 - - -From 8a268f3af434d409dcd84db5fef10d6943266b75 Mon Sep 17 00:00:00 2001 -From: Andreas Schneider -Date: Mon, 23 Sep 2019 17:04:57 +0200 -Subject: [PATCH 4/9] third_party: Only link cmocka against librt if really - needed -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cmocka also uses clock_gettime(). - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14140 - -Signed-off-by: Andreas Schneider -Signed-off-by: Isaac Boukris -Pair-Programmed-With: Isaac Boukris -Reviewed-by: Matthias Dieter Wallnöfer -Reviewed-by: Alexander Bokovoy -(cherry picked from commit 36e8d715bc8dc1e8466f5a5c9798df76310b7572) ---- - third_party/cmocka/wscript | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/third_party/cmocka/wscript b/third_party/cmocka/wscript -index 9ebdd7cfbe9..3c2ad50801a 100644 ---- a/third_party/cmocka/wscript -+++ b/third_party/cmocka/wscript -@@ -12,8 +12,13 @@ def build(bld): - if bld.CONFIG_SET('USING_SYSTEM_CMOCKA'): - return - -+ extra_libs='' -+ -+ # Link to librt if needed for clock_gettime() -+ if bld.CONFIG_SET('HAVE_LIBRT'): extra_libs += ' rt' -+ - bld.SAMBA_LIBRARY('cmocka', - source='cmocka.c', -- deps='rt', -+ deps=extra_libs, - allow_warnings=True, - private_library=True) --- -2.23.0 - - -From 3b3d2606fefb98a9a27626f1ddfdabdf22992a9e Mon Sep 17 00:00:00 2001 -From: Andreas Schneider -Date: Mon, 23 Sep 2019 17:39:29 +0200 -Subject: [PATCH 5/9] third_party: Link nss_wrapper against pthread -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -nss_wrapper uses pthread_atfork() which is only provided by libpthread. -So we need an explicit dependency. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14140 - -Signed-off-by: Andreas Schneider -Signed-off-by: Isaac Boukris -Pair-Programmed-With: Isaac Boukris -Reviewed-by: Matthias Dieter Wallnöfer -Reviewed-by: Alexander Bokovoy -(cherry picked from commit 68d8a02ef57cce29e4ff3ef1b792adfc10d0b916) ---- - third_party/nss_wrapper/wscript | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/third_party/nss_wrapper/wscript b/third_party/nss_wrapper/wscript -index 2e9d1db13b1..40848603b36 100644 ---- a/third_party/nss_wrapper/wscript -+++ b/third_party/nss_wrapper/wscript -@@ -89,6 +89,6 @@ def build(bld): - # breaks preloading! - bld.SAMBA_LIBRARY('nss_wrapper', - source='nss_wrapper.c', -- deps='dl', -+ deps='dl pthread', - install=False, - realname='libnss-wrapper.so') --- -2.23.0 - - -From 2f27ac30a8d75b09f3ac9ac32d3a0e23d3d48581 Mon Sep 17 00:00:00 2001 -From: Andreas Schneider -Date: Mon, 23 Sep 2019 17:40:13 +0200 -Subject: [PATCH 6/9] third_party: Link uid_wrapper against pthread -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -uid_wrapper uses pthread_atfork() which is only provided by libpthread. │···················· -So we need an explicit dependency. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14140 - -Signed-off-by: Andreas Schneider -Signed-off-by: Isaac Boukris -Pair-Programmed-With: Isaac Boukris -Reviewed-by: Matthias Dieter Wallnöfer -Reviewed-by: Alexander Bokovoy -(cherry picked from commit bd0cd8e13234d684da77a65f6fdaea2572625369) ---- - third_party/uid_wrapper/wscript | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/third_party/uid_wrapper/wscript b/third_party/uid_wrapper/wscript -index 61d8a189625..738343f49e4 100644 ---- a/third_party/uid_wrapper/wscript -+++ b/third_party/uid_wrapper/wscript -@@ -119,6 +119,6 @@ def build(bld): - # breaks preloading! - bld.SAMBA_LIBRARY('uid_wrapper', - source='uid_wrapper.c', -- deps='dl', -+ deps='dl pthread', - install=False, - realname='libuid-wrapper.so') --- -2.23.0 - - -From bf1b1e4b85c516a480c5a29a98a8761870a59735 Mon Sep 17 00:00:00 2001 -From: Andreas Schneider -Date: Mon, 23 Sep 2019 16:53:12 +0200 -Subject: [PATCH 7/9] waf:replace: Do not link against libpthread if not - necessary -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -On Linux we should avoid linking everything against libpthread. Symbols -used my most application are provided by glibc and code which deals with -threads has to explicitly link against libpthread. This avoids setting -LDFLAGS=-pthread globally. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14140 - -Signed-off-by: Andreas Schneider -Signed-off-by: Isaac Boukris -Pair-Programmed-With: Isaac Boukris -Reviewed-by: Matthias Dieter Wallnöfer -Reviewed-by: Alexander Bokovoy -(cherry picked from commit 9499db075b72b147e2ff9bb78e9d5edbaac14e69) ---- - lib/replace/wscript | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - -diff --git a/lib/replace/wscript b/lib/replace/wscript -index d8423b1d281..b5919835c0b 100644 ---- a/lib/replace/wscript -+++ b/lib/replace/wscript -@@ -551,6 +551,11 @@ def configure(conf): - PTHREAD_CFLAGS='error' - PTHREAD_LDFLAGS='error' - -+ if PTHREAD_LDFLAGS == 'error': -+ # Check if pthread_attr_init() is provided by libc first! -+ if conf.CHECK_FUNCS('pthread_attr_init'): -+ PTHREAD_CFLAGS='-D_REENTRANT' -+ PTHREAD_LDFLAGS='' - if PTHREAD_LDFLAGS == 'error': - if conf.CHECK_FUNCS_IN('pthread_attr_init', 'pthread'): - PTHREAD_CFLAGS='-D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS' -@@ -563,10 +568,7 @@ def configure(conf): - if conf.CHECK_FUNCS_IN('pthread_attr_init', 'c_r'): - PTHREAD_CFLAGS='-D_THREAD_SAFE -pthread' - PTHREAD_LDFLAGS='-pthread' -- if PTHREAD_LDFLAGS == 'error': -- if conf.CHECK_FUNCS('pthread_attr_init'): -- PTHREAD_CFLAGS='-D_REENTRANT' -- PTHREAD_LDFLAGS='-lpthread' -+ - # especially for HP-UX, where the CHECK_FUNC macro fails to test for - # pthread_attr_init. On pthread_mutex_lock it works there... - if PTHREAD_LDFLAGS == 'error': --- -2.23.0 - - -From cce4834d7aacf69975bc5acf24c66e3a2913f231 Mon Sep 17 00:00:00 2001 -From: Isaac Boukris -Date: Tue, 15 Oct 2019 13:52:42 +0300 -Subject: [PATCH 8/9] nsswitch: Link stress-nss-libwbclient against pthread - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14140 - -Signed-off-by: Isaac Boukris -Reviewed-by: Andreas Schneider -Reviewed-by: Alexander Bokovoy -(cherry picked from commit d473f1e38c2822746030516269b4d70032cf9b2e) ---- - nsswitch/wscript_build | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/nsswitch/wscript_build b/nsswitch/wscript_build -index 6acc4a19b9b..861ed2f23bf 100644 ---- a/nsswitch/wscript_build -+++ b/nsswitch/wscript_build -@@ -20,7 +20,7 @@ bld.SAMBA_BINARY('nsstest', - if bld.CONFIG_SET('HAVE_PTHREAD'): - bld.SAMBA_BINARY('stress-nss-libwbclient', - source='stress-nss-libwbclient.c', -- deps='wbclient', -+ deps='wbclient pthread', - install=False - ) - --- -2.23.0 - - -From d3609fef9b4e7ac76d4dfe2f387e89e3a79749c6 Mon Sep 17 00:00:00 2001 -From: Isaac Boukris -Date: Tue, 15 Oct 2019 17:01:48 +0300 -Subject: [PATCH 9/9] s3:libsmb: Link libsmb against pthread - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14140 - -Signed-off-by: Isaac Boukris -Reviewed-by: Andreas Schneider -Reviewed-by: Alexander Bokovoy -(cherry picked from commit 7259197bf716f8b81dea74beefe6ee3b1239f172) ---- - source3/libsmb/wscript | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/source3/libsmb/wscript b/source3/libsmb/wscript -index d9e933e9e9f..febff9df7fc 100644 ---- a/source3/libsmb/wscript -+++ b/source3/libsmb/wscript -@@ -16,6 +16,7 @@ def build(bld): - libsmb_xattr.c - libsmb_setget.c''', - public_deps=''' -+ pthread - talloc - smbconf - libsmb --- -2.23.0 - diff --git a/SOURCES/samba-4.10-fix-netbios-join.patch b/SOURCES/samba-4.10-fix-netbios-join.patch new file mode 100644 index 0000000..9dd2eec --- /dev/null +++ b/SOURCES/samba-4.10-fix-netbios-join.patch @@ -0,0 +1,723 @@ +From 05f7e9a72a1769af9d41b1ca40fe6a14b3f069d1 Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Fri, 30 Aug 2019 00:22:15 +0300 +Subject: [PATCH 1/6] libnet_join: build dnsHostName from netbios name and + lp_dnsdomain() + +This make the join process much more reliable, and avoids "Constraint +violation" error when the fqdn returned from getaddrinfo has already +got assigned an SPN. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14116 + +Signed-off-by: Isaac Boukris +Reviewed-by: Ralph Boehme +Reviewed-by: Alexander Bokovoy +--- + source3/libnet/libnet_join.c | 31 +++++++++++------------------- + testprogs/blackbox/test_net_ads.sh | 7 +++++-- + 2 files changed, 16 insertions(+), 22 deletions(-) + +diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c +index 7943bef2cf6..818b3039cb9 100644 +--- a/source3/libnet/libnet_join.c ++++ b/source3/libnet/libnet_join.c +@@ -533,29 +533,23 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx, + } + } + +- if (!name_to_fqdn(my_fqdn, r->in.machine_name) +- || (strchr(my_fqdn, '.') == NULL)) { +- fstr_sprintf(my_fqdn, "%s.%s", r->in.machine_name, +- r->out.dns_domain_name); +- } ++ fstr_sprintf(my_fqdn, "%s.%s", r->in.machine_name, lp_dnsdomain()); + + if (!strlower_m(my_fqdn)) { + return ADS_ERROR_LDAP(LDAP_NO_MEMORY); + } + +- if (!strequal(my_fqdn, r->in.machine_name)) { +- spn = talloc_asprintf(mem_ctx, "HOST/%s", my_fqdn); +- if (!spn) { +- return ADS_ERROR_LDAP(LDAP_NO_MEMORY); +- } ++ spn = talloc_asprintf(mem_ctx, "HOST/%s", my_fqdn); ++ if (spn == NULL) { ++ return ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ } + +- ok = ads_element_in_array(spn_array, num_spns, spn); ++ ok = ads_element_in_array(spn_array, num_spns, spn); ++ if (!ok) { ++ ok = add_string_to_array(spn_array, spn, ++ &spn_array, &num_spns); + if (!ok) { +- ok = add_string_to_array(spn_array, spn, +- &spn_array, &num_spns); +- if (!ok) { +- return ADS_ERROR_LDAP(LDAP_NO_MEMORY); +- } ++ return ADS_ERROR_LDAP(LDAP_NO_MEMORY); + } + } + +@@ -591,12 +585,9 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx, + /* + * Add HOST/netbiosname.domainname + */ +- if (r->out.dns_domain_name == NULL) { +- continue; +- } + fstr_sprintf(my_fqdn, "%s.%s", + *netbios_aliases, +- r->out.dns_domain_name); ++ lp_dnsdomain()); + + spn = talloc_asprintf(mem_ctx, "HOST/%s", my_fqdn); + if (spn == NULL) { +diff --git a/testprogs/blackbox/test_net_ads.sh b/testprogs/blackbox/test_net_ads.sh +index cc8345c4624..ef6f99ddea4 100755 +--- a/testprogs/blackbox/test_net_ads.sh ++++ b/testprogs/blackbox/test_net_ads.sh +@@ -81,7 +81,7 @@ testit "testjoin (dedicated keytab)" $VALGRIND $net_tool ads testjoin -kP || fai + netbios=$(grep "netbios name" $BASEDIR/$WORKDIR/client.conf | cut -f2 -d= | awk '{$1=$1};1') + uc_netbios=$(echo $netbios | tr '[:lower:]' '[:upper:]') + lc_realm=$(echo $REALM | tr '[:upper:]' '[:lower:]') +-fqdns="$netbios.$lc_realm" ++fqdn="$netbios.$lc_realm" + + krb_princ="primary/instance@$REALM" + testit "test (dedicated keytab) add a fully qualified krb5 principal" $VALGRIND $net_tool ads keytab add $krb_princ -U$DC_USERNAME%$DC_PASSWORD --option="kerberosmethod=dedicatedkeytab" --option="dedicatedkeytabfile=$dedicated_keytab_file" || failed=`expr $failed + 1` +@@ -99,7 +99,7 @@ testit "test (dedicated keytab) at least one krb5 principal created from $machin + service="nfs" + testit "test (dedicated keytab) add a $service service to keytab" $VALGRIND $net_tool ads keytab add $service -U$DC_USERNAME%$DC_PASSWORD --option="kerberosmethod=dedicatedkeytab" --option="dedicatedkeytabfile=$dedicated_keytab_file" || failed=`expr $failed + 1` + +-search_str="$service/$fqdns@$REALM" ++search_str="$service/$fqdn@$REALM" + found=`$net_tool ads keytab list -U$DC_USERNAME%$DC_PASSWORD --option="kerberosmethod=dedicatedkeytab" --option="dedicatedkeytabfile=$dedicated_keytab_file" | grep $search_str | wc -l` + testit "test (dedicated keytab) at least one (long form) krb5 principal created from service added is present in keytab" test $found -gt 1 || failed=`expr $failed + 1` + +@@ -206,6 +206,9 @@ testit "join" $VALGRIND $net_tool ads join -U$DC_USERNAME%$DC_PASSWORD || failed + + testit "testjoin" $VALGRIND $net_tool ads testjoin || failed=`expr $failed + 1` + ++testit_grep "check dNSHostName" $fqdn $VALGRIND $net_tool ads search -P samaccountname=$netbios\$ dNSHostName || failed=`expr $failed + 1` ++testit_grep "check SPN" ${uc_netbios}.${lc_realm} $VALGRIND $net_tool ads search -P samaccountname=$netbios\$ servicePrincipalName || failed=`expr $failed + 1` ++ + ##Goodbye... + testit "leave" $VALGRIND $net_tool ads leave -U$DC_USERNAME%$DC_PASSWORD || failed=`expr $failed + 1` + +-- +2.21.0 + + +From 4cbad1eb46896bbd74c5b19dbb0a8937ffde90c2 Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Wed, 18 Sep 2019 20:00:34 +0300 +Subject: [PATCH 2/6] libnet_join_set_machine_spn: improve style and make a bit + room for indentation + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14116 + +Signed-off-by: Isaac Boukris +Reviewed-by: Ralph Boehme +Reviewed-by: Alexander Bokovoy +--- + source3/libnet/libnet_join.c | 95 ++++++++++++++++++------------------ + 1 file changed, 47 insertions(+), 48 deletions(-) + +diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c +index 818b3039cb9..67ab50c68a8 100644 +--- a/source3/libnet/libnet_join.c ++++ b/source3/libnet/libnet_join.c +@@ -517,7 +517,7 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx, + /* Windows only creates HOST/shortname & HOST/fqdn. */ + + spn = talloc_asprintf(mem_ctx, "HOST/%s", r->in.machine_name); +- if (!spn) { ++ if (spn == NULL) { + return ADS_ERROR_LDAP(LDAP_NO_MEMORY); + } + if (!strupper_m(spn)) { +@@ -553,60 +553,59 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx, + } + } + +- netbios_aliases = lp_netbios_aliases(); +- if (netbios_aliases != NULL) { +- for (; *netbios_aliases != NULL; netbios_aliases++) { +- /* +- * Add HOST/NETBIOSNAME +- */ +- spn = talloc_asprintf(mem_ctx, "HOST/%s", *netbios_aliases); +- if (spn == NULL) { +- TALLOC_FREE(spn); +- return ADS_ERROR_LDAP(LDAP_NO_MEMORY); +- } +- if (!strupper_m(spn)) { +- TALLOC_FREE(spn); +- return ADS_ERROR_LDAP(LDAP_NO_MEMORY); +- } ++ for (netbios_aliases = lp_netbios_aliases(); ++ netbios_aliases != NULL && *netbios_aliases != NULL; ++ netbios_aliases++) { ++ /* ++ * Add HOST/NETBIOSNAME ++ */ ++ spn = talloc_asprintf(mem_ctx, "HOST/%s", *netbios_aliases); ++ if (spn == NULL) { ++ TALLOC_FREE(spn); ++ return ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ } ++ if (!strupper_m(spn)) { ++ TALLOC_FREE(spn); ++ return ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ } + +- ok = ads_element_in_array(spn_array, num_spns, spn); +- if (ok) { +- TALLOC_FREE(spn); +- continue; +- } +- ok = add_string_to_array(spn_array, spn, +- &spn_array, &num_spns); +- if (!ok) { +- TALLOC_FREE(spn); +- return ADS_ERROR_LDAP(LDAP_NO_MEMORY); +- } ++ ok = ads_element_in_array(spn_array, num_spns, spn); ++ if (ok) { ++ TALLOC_FREE(spn); ++ continue; ++ } ++ ok = add_string_to_array(spn_array, spn, ++ &spn_array, &num_spns); ++ if (!ok) { + TALLOC_FREE(spn); ++ return ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ } ++ TALLOC_FREE(spn); + +- /* +- * Add HOST/netbiosname.domainname +- */ +- fstr_sprintf(my_fqdn, "%s.%s", +- *netbios_aliases, +- lp_dnsdomain()); ++ /* ++ * Add HOST/netbiosname.domainname ++ */ ++ fstr_sprintf(my_fqdn, "%s.%s", ++ *netbios_aliases, ++ lp_dnsdomain()); + +- spn = talloc_asprintf(mem_ctx, "HOST/%s", my_fqdn); +- if (spn == NULL) { +- return ADS_ERROR_LDAP(LDAP_NO_MEMORY); +- } ++ spn = talloc_asprintf(mem_ctx, "HOST/%s", my_fqdn); ++ if (spn == NULL) { ++ return ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ } + +- ok = ads_element_in_array(spn_array, num_spns, spn); +- if (ok) { +- TALLOC_FREE(spn); +- continue; +- } +- ok = add_string_to_array(spn_array, spn, +- &spn_array, &num_spns); +- if (!ok) { +- TALLOC_FREE(spn); +- return ADS_ERROR_LDAP(LDAP_NO_MEMORY); +- } ++ ok = ads_element_in_array(spn_array, num_spns, spn); ++ if (ok) { ++ TALLOC_FREE(spn); ++ continue; ++ } ++ ok = add_string_to_array(spn_array, spn, ++ &spn_array, &num_spns); ++ if (!ok) { + TALLOC_FREE(spn); ++ return ADS_ERROR_LDAP(LDAP_NO_MEMORY); + } ++ TALLOC_FREE(spn); + } + + /* make sure to NULL terminate the array */ +-- +2.21.0 + + +From b8e1264ececf38681ca9a519a51e8336044673f0 Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Wed, 18 Sep 2019 21:29:47 +0300 +Subject: [PATCH 3/6] libnet_join_set_machine_spn: simplify memory handling + +and avoid a possible memory leak when passing null to +add_string_to_array() as mem_ctx. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14116 + +Signed-off-by: Isaac Boukris +Reviewed-by: Ralph Boehme +Reviewed-by: Alexander Bokovoy +--- + source3/libnet/libnet_join.c | 74 ++++++++++++++++++++---------------- + 1 file changed, 42 insertions(+), 32 deletions(-) + +diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c +index 67ab50c68a8..43035370526 100644 +--- a/source3/libnet/libnet_join.c ++++ b/source3/libnet/libnet_join.c +@@ -490,6 +490,7 @@ static ADS_STATUS libnet_join_get_machine_spns(TALLOC_CTX *mem_ctx, + static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx, + struct libnet_JoinCtx *r) + { ++ TALLOC_CTX *frame = talloc_stackframe(); + ADS_STATUS status; + ADS_MODLIST mods; + fstring my_fqdn; +@@ -506,7 +507,7 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx, + return status; + } + +- status = libnet_join_get_machine_spns(mem_ctx, ++ status = libnet_join_get_machine_spns(frame, + r, + discard_const_p(char **, &spn_array), + &num_spns); +@@ -516,40 +517,46 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx, + + /* Windows only creates HOST/shortname & HOST/fqdn. */ + +- spn = talloc_asprintf(mem_ctx, "HOST/%s", r->in.machine_name); ++ spn = talloc_asprintf(frame, "HOST/%s", r->in.machine_name); + if (spn == NULL) { +- return ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ status = ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ goto done; + } + if (!strupper_m(spn)) { +- return ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ status = ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ goto done; + } + + ok = ads_element_in_array(spn_array, num_spns, spn); + if (!ok) { +- ok = add_string_to_array(spn_array, spn, ++ ok = add_string_to_array(frame, spn, + &spn_array, &num_spns); + if (!ok) { +- return ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ status = ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ goto done; + } + } + + fstr_sprintf(my_fqdn, "%s.%s", r->in.machine_name, lp_dnsdomain()); + + if (!strlower_m(my_fqdn)) { +- return ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ status = ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ goto done; + } + +- spn = talloc_asprintf(mem_ctx, "HOST/%s", my_fqdn); ++ spn = talloc_asprintf(frame, "HOST/%s", my_fqdn); + if (spn == NULL) { +- return ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ status = ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ goto done; + } + + ok = ads_element_in_array(spn_array, num_spns, spn); + if (!ok) { +- ok = add_string_to_array(spn_array, spn, ++ ok = add_string_to_array(frame, spn, + &spn_array, &num_spns); + if (!ok) { +- return ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ status = ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ goto done; + } + } + +@@ -559,28 +566,26 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx, + /* + * Add HOST/NETBIOSNAME + */ +- spn = talloc_asprintf(mem_ctx, "HOST/%s", *netbios_aliases); ++ spn = talloc_asprintf(frame, "HOST/%s", *netbios_aliases); + if (spn == NULL) { +- TALLOC_FREE(spn); +- return ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ status = ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ goto done; + } + if (!strupper_m(spn)) { +- TALLOC_FREE(spn); +- return ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ status = ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ goto done; + } + + ok = ads_element_in_array(spn_array, num_spns, spn); + if (ok) { +- TALLOC_FREE(spn); + continue; + } + ok = add_string_to_array(spn_array, spn, + &spn_array, &num_spns); + if (!ok) { +- TALLOC_FREE(spn); +- return ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ status = ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ goto done; + } +- TALLOC_FREE(spn); + + /* + * Add HOST/netbiosname.domainname +@@ -589,51 +594,56 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx, + *netbios_aliases, + lp_dnsdomain()); + +- spn = talloc_asprintf(mem_ctx, "HOST/%s", my_fqdn); ++ spn = talloc_asprintf(frame, "HOST/%s", my_fqdn); + if (spn == NULL) { +- return ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ status = ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ goto done; + } + + ok = ads_element_in_array(spn_array, num_spns, spn); + if (ok) { +- TALLOC_FREE(spn); + continue; + } + ok = add_string_to_array(spn_array, spn, + &spn_array, &num_spns); + if (!ok) { +- TALLOC_FREE(spn); +- return ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ status = ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ goto done; + } +- TALLOC_FREE(spn); + } + + /* make sure to NULL terminate the array */ +- spn_array = talloc_realloc(mem_ctx, spn_array, const char *, num_spns + 1); ++ spn_array = talloc_realloc(frame, spn_array, const char *, num_spns + 1); + if (spn_array == NULL) { +- return ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ status = ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ goto done; + } + spn_array[num_spns] = NULL; + + mods = ads_init_mods(mem_ctx); + if (!mods) { +- return ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ status = ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ goto done; + } + + /* fields of primary importance */ + + status = ads_mod_str(mem_ctx, &mods, "dNSHostName", my_fqdn); + if (!ADS_ERR_OK(status)) { +- return ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ goto done; + } + + status = ads_mod_strlist(mem_ctx, &mods, "servicePrincipalName", + spn_array); + if (!ADS_ERR_OK(status)) { +- return ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ goto done; + } + +- return ads_gen_mod(r->in.ads, r->out.dn, mods); ++ status = ads_gen_mod(r->in.ads, r->out.dn, mods); ++ ++done: ++ TALLOC_FREE(frame); ++ return status; + } + + /**************************************************************** +-- +2.21.0 + + +From 3e65f72b141a7ee256ae581e5f48f1d930aed76a Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Wed, 18 Sep 2019 23:15:57 +0300 +Subject: [PATCH 4/6] libnet_join_set_machine_spn: simplify adding uniq spn to + array + +and do not skip adding a fully qualified spn to netbios-aliases +in case a short spn already existed. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14116 + +Signed-off-by: Isaac Boukris +Reviewed-by: Ralph Boehme +Reviewed-by: Alexander Bokovoy +--- + source3/libnet/libnet_join.c | 56 +++++++++++++++--------------------- + 1 file changed, 23 insertions(+), 33 deletions(-) + +diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c +index 43035370526..a1d8a25bbc2 100644 +--- a/source3/libnet/libnet_join.c ++++ b/source3/libnet/libnet_join.c +@@ -483,6 +483,19 @@ static ADS_STATUS libnet_join_get_machine_spns(TALLOC_CTX *mem_ctx, + return status; + } + ++static ADS_STATUS add_uniq_spn(TALLOC_CTX *mem_ctx, const char *spn, ++ const char ***array, size_t *num) ++{ ++ bool ok = ads_element_in_array(*array, *num, spn); ++ if (!ok) { ++ ok = add_string_to_array(mem_ctx, spn, array, num); ++ if (!ok) { ++ return ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ } ++ } ++ return ADS_SUCCESS; ++} ++ + /**************************************************************** + Set a machines dNSHostName and servicePrincipalName attributes + ****************************************************************/ +@@ -497,7 +510,6 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx, + const char **spn_array = NULL; + size_t num_spns = 0; + char *spn = NULL; +- bool ok; + const char **netbios_aliases = NULL; + + /* Find our DN */ +@@ -527,14 +539,9 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx, + goto done; + } + +- ok = ads_element_in_array(spn_array, num_spns, spn); +- if (!ok) { +- ok = add_string_to_array(frame, spn, +- &spn_array, &num_spns); +- if (!ok) { +- status = ADS_ERROR_LDAP(LDAP_NO_MEMORY); +- goto done; +- } ++ status = add_uniq_spn(frame, spn, &spn_array, &num_spns); ++ if (!ADS_ERR_OK(status)) { ++ goto done; + } + + fstr_sprintf(my_fqdn, "%s.%s", r->in.machine_name, lp_dnsdomain()); +@@ -550,14 +557,9 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx, + goto done; + } + +- ok = ads_element_in_array(spn_array, num_spns, spn); +- if (!ok) { +- ok = add_string_to_array(frame, spn, +- &spn_array, &num_spns); +- if (!ok) { +- status = ADS_ERROR_LDAP(LDAP_NO_MEMORY); +- goto done; +- } ++ status = add_uniq_spn(frame, spn, &spn_array, &num_spns); ++ if (!ADS_ERR_OK(status)) { ++ goto done; + } + + for (netbios_aliases = lp_netbios_aliases(); +@@ -576,14 +578,8 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx, + goto done; + } + +- ok = ads_element_in_array(spn_array, num_spns, spn); +- if (ok) { +- continue; +- } +- ok = add_string_to_array(spn_array, spn, +- &spn_array, &num_spns); +- if (!ok) { +- status = ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ status = add_uniq_spn(frame, spn, &spn_array, &num_spns); ++ if (!ADS_ERR_OK(status)) { + goto done; + } + +@@ -600,14 +596,8 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx, + goto done; + } + +- ok = ads_element_in_array(spn_array, num_spns, spn); +- if (ok) { +- continue; +- } +- ok = add_string_to_array(spn_array, spn, +- &spn_array, &num_spns); +- if (!ok) { +- status = ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ status = add_uniq_spn(frame, spn, &spn_array, &num_spns); ++ if (!ADS_ERR_OK(status)) { + goto done; + } + } +-- +2.21.0 + + +From db7560ff0fb861552406bb4c422cff55c82f58bf Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Tue, 17 Sep 2019 21:38:07 +0300 +Subject: [PATCH 5/6] docs-xml: add "additional dns hostnames" smb.conf option + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14116 + +Signed-off-by: Isaac Boukris +Reviewed-by: Ralph Boehme +Reviewed-by: Alexander Bokovoy +--- + docs-xml/smbdotconf/base/additionaldnshostnames.xml | 11 +++++++++++ + 1 file changed, 11 insertions(+) + create mode 100644 docs-xml/smbdotconf/base/additionaldnshostnames.xml + +diff --git a/docs-xml/smbdotconf/base/additionaldnshostnames.xml b/docs-xml/smbdotconf/base/additionaldnshostnames.xml +new file mode 100644 +index 00000000000..ddc04ee9f81 +--- /dev/null ++++ b/docs-xml/smbdotconf/base/additionaldnshostnames.xml +@@ -0,0 +1,11 @@ ++ ++ ++ A list of additional DNS names by which this host can be identified ++ ++ ++empty string (no additional dns names) ++ host2.example.com host3.other.com ++ +-- +2.21.0 + + +From 2669cecc51f8f7d6675b4dac9b345b3c5a7fc879 Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Fri, 13 Sep 2019 10:56:10 +0300 +Subject: [PATCH 6/6] libnet_join: add SPNs for additional-dns-hostnames + entries +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +and set msDS-AdditionalDnsHostName to the specified list. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14116 + +Signed-off-by: Isaac Boukris +Reviewed-by: Ralph Boehme +Reviewed-by: Alexander Bokovoy + +Autobuild-User(master): Ralph Böhme +Autobuild-Date(master): Fri Oct 25 10:43:08 UTC 2019 on sn-devel-184 +--- + source3/libnet/libnet_join.c | 27 +++++++++++++++++++++++++++ + testprogs/blackbox/test_net_ads.sh | 10 +++++++++- + 2 files changed, 36 insertions(+), 1 deletion(-) + +diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c +index a1d8a25bbc2..eb8e0ea17f7 100644 +--- a/source3/libnet/libnet_join.c ++++ b/source3/libnet/libnet_join.c +@@ -511,6 +511,7 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx, + size_t num_spns = 0; + char *spn = NULL; + const char **netbios_aliases = NULL; ++ const char **addl_hostnames = NULL; + + /* Find our DN */ + +@@ -602,6 +603,22 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx, + } + } + ++ for (addl_hostnames = lp_additional_dns_hostnames(); ++ addl_hostnames != NULL && *addl_hostnames != NULL; ++ addl_hostnames++) { ++ ++ spn = talloc_asprintf(frame, "HOST/%s", *addl_hostnames); ++ if (spn == NULL) { ++ status = ADS_ERROR_LDAP(LDAP_NO_MEMORY); ++ goto done; ++ } ++ ++ status = add_uniq_spn(frame, spn, &spn_array, &num_spns); ++ if (!ADS_ERR_OK(status)) { ++ goto done; ++ } ++ } ++ + /* make sure to NULL terminate the array */ + spn_array = talloc_realloc(frame, spn_array, const char *, num_spns + 1); + if (spn_array == NULL) { +@@ -629,6 +646,16 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx, + goto done; + } + ++ addl_hostnames = lp_additional_dns_hostnames(); ++ if (addl_hostnames != NULL && *addl_hostnames != NULL) { ++ status = ads_mod_strlist(mem_ctx, &mods, ++ "msDS-AdditionalDnsHostName", ++ addl_hostnames); ++ if (!ADS_ERR_OK(status)) { ++ goto done; ++ } ++ } ++ + status = ads_gen_mod(r->in.ads, r->out.dn, mods); + + done: +diff --git a/testprogs/blackbox/test_net_ads.sh b/testprogs/blackbox/test_net_ads.sh +index ef6f99ddea4..8bcff006b8e 100755 +--- a/testprogs/blackbox/test_net_ads.sh ++++ b/testprogs/blackbox/test_net_ads.sh +@@ -202,13 +202,21 @@ base_dn="DC=addom,DC=samba,DC=example,DC=com" + computers_dn="CN=Computers,$base_dn" + testit "ldb check for existence of machine account" $ldbsearch -U$DC_USERNAME%$DC_PASSWORD -H ldap://$SERVER.$REALM -s base -b "cn=$HOSTNAME,$computers_dn" || failed=`expr $failed + 1` + +-testit "join" $VALGRIND $net_tool ads join -U$DC_USERNAME%$DC_PASSWORD || failed=`expr $failed + 1` ++dns_alias1="${netbios}_alias1.other.${lc_realm}" ++dns_alias2="${netbios}_alias2.other2.${lc_realm}" ++testit "join" $VALGRIND $net_tool --option=additionaldnshostnames=$dns_alias1,$dns_alias2 ads join -U$DC_USERNAME%$DC_PASSWORD || failed=`expr $failed + 1` + + testit "testjoin" $VALGRIND $net_tool ads testjoin || failed=`expr $failed + 1` + + testit_grep "check dNSHostName" $fqdn $VALGRIND $net_tool ads search -P samaccountname=$netbios\$ dNSHostName || failed=`expr $failed + 1` + testit_grep "check SPN" ${uc_netbios}.${lc_realm} $VALGRIND $net_tool ads search -P samaccountname=$netbios\$ servicePrincipalName || failed=`expr $failed + 1` + ++testit_grep "dns alias SPN" $dns_alias1 $VALGRIND $net_tool ads search -P samaccountname=$netbios\$ servicePrincipalName || failed=`expr $failed + 1` ++testit_grep "dns alias SPN" $dns_alias2 $VALGRIND $net_tool ads search -P samaccountname=$netbios\$ servicePrincipalName || failed=`expr $failed + 1` ++ ++testit_grep "dns alias addl" $dns_alias1 $VALGRIND $net_tool ads search -P samaccountname=$netbios\$ msDS-AdditionalDnsHostName || failed=`expr $failed + 1` ++testit_grep "dns alias addl" $dns_alias2 $VALGRIND $net_tool ads search -P samaccountname=$netbios\$ msDS-AdditionalDnsHostName || failed=`expr $failed + 1` ++ + ##Goodbye... + testit "leave" $VALGRIND $net_tool ads leave -U$DC_USERNAME%$DC_PASSWORD || failed=`expr $failed + 1` + +-- +2.21.0 + diff --git a/SOURCES/samba-4.10-fix_linking_nsl_socket.patch b/SOURCES/samba-4.10-fix_linking_nsl_socket.patch deleted file mode 100644 index e21e9cc..0000000 --- a/SOURCES/samba-4.10-fix_linking_nsl_socket.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 8f500a77df4a3e38f19ec5aad6f6dc62f608fffc Mon Sep 17 00:00:00 2001 -From: Andreas Schneider -Date: Mon, 21 Oct 2019 17:08:08 +0200 -Subject: [PATCH] replace: Only link libnsl and libsocket if requrired - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14168 - -Signed-off-by: Andreas Schneider -Reviewed-by: Alexander Bokovoy - -Autobuild-User(master): Andreas Schneider -Autobuild-Date(master): Wed Oct 23 08:23:13 UTC 2019 on sn-devel-184 - -(cherry picked from commit 263bec1b8d0744da73dd92e4a361fb7430289ab3) ---- - lib/replace/wscript | 36 +++++++++++++++++++++++++++++++----- - 1 file changed, 31 insertions(+), 5 deletions(-) - -diff --git a/lib/replace/wscript b/lib/replace/wscript -index b5919835c0b..0ebeb36944f 100644 ---- a/lib/replace/wscript -+++ b/lib/replace/wscript -@@ -190,10 +190,35 @@ def configure(conf): - conf.CHECK_TYPE_IN('sig_atomic_t', 'signal.h', define='HAVE_SIG_ATOMIC_T_TYPE') - conf.CHECK_FUNCS('sigsetmask siggetmask sigprocmask sigblock sigaction sigset') - -- conf.CHECK_FUNCS_IN('''inet_ntoa inet_aton inet_ntop inet_pton connect gethostbyname -- getaddrinfo getnameinfo freeaddrinfo gai_strerror socketpair''', -- 'socket nsl', checklibc=True, -- headers='sys/socket.h netinet/in.h arpa/inet.h netdb.h') -+ # Those functions are normally available in libc -+ if not conf.CHECK_FUNCS(''' -+ inet_ntoa -+ inet_aton -+ inet_ntop -+ inet_pton -+ connect -+ gethostbyname -+ getaddrinfo -+ getnameinfo -+ freeaddrinfo -+ gai_strerror -+ socketpair''', -+ headers='sys/socket.h netinet/in.h arpa/inet.h netdb.h'): -+ conf.CHECK_FUNCS_IN(''' -+ inet_ntoa -+ inet_aton -+ inet_ntop -+ inet_pton -+ connect -+ gethostbyname -+ getaddrinfo -+ getnameinfo -+ freeaddrinfo -+ gai_strerror -+ socketpair''', -+ 'socket nsl', -+ headers='sys/socket.h netinet/in.h arpa/inet.h netdb.h') -+ conf.DEFINE('REPLACE_REQUIRES_LIBSOCKET_LIBNSL', 1) - - conf.CHECK_FUNCS('memset_s memset_explicit') - -@@ -835,6 +860,7 @@ def build(bld): - extra_libs = '' - if bld.CONFIG_SET('HAVE_LIBBSD'): extra_libs += ' bsd' - if bld.CONFIG_SET('HAVE_LIBRT'): extra_libs += ' rt' -+ if bld.CONFIG_SET('REPLACE_REQUIRES_LIBSOCKET_LIBNSL'): extra_libs += ' socket nsl' - - bld.SAMBA_SUBSYSTEM('LIBREPLACE_HOSTCC', - REPLACE_HOSTCC_SOURCE, -@@ -875,7 +901,7 @@ def build(bld): - # at the moment: - # hide_symbols=bld.BUILTIN_LIBRARY('replace'), - private_library=True, -- deps='crypt dl nsl socket attr' + extra_libs) -+ deps='crypt dl attr' + extra_libs) - - replace_test_cflags = '' - if bld.CONFIG_SET('HAVE_WNO_FORMAT_TRUNCATION'): --- -2.23.0 - diff --git a/SOURCES/samba-4.10-fix_smbspool.patch b/SOURCES/samba-4.10-fix_smbspool.patch deleted file mode 100644 index fa12f06..0000000 --- a/SOURCES/samba-4.10-fix_smbspool.patch +++ /dev/null @@ -1,1127 +0,0 @@ -From 16056895403f3c673dc5adc531b7e739d46292fb Mon Sep 17 00:00:00 2001 -From: Andreas Schneider -Date: Mon, 13 May 2019 16:55:49 +0200 -Subject: [PATCH 1/9] s3:smbspool: Add the 'lp' group to the users groups - -This is required to access files in /var/spool/cups which have been -temporarily created in there by CUPS. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=13939 - -Signed-off-by: Andreas Schneider -Reviewed-by: Guenther Deschner -(cherry picked from commit 6086efb6808089c431e7307fa239924bfda1185b) ---- - source3/client/smbspool_krb5_wrapper.c | 22 ++++++++++++++++++++++ - 1 file changed, 22 insertions(+) - -diff --git a/source3/client/smbspool_krb5_wrapper.c b/source3/client/smbspool_krb5_wrapper.c -index 5c4da33238b..e6684fc0d0c 100644 ---- a/source3/client/smbspool_krb5_wrapper.c -+++ b/source3/client/smbspool_krb5_wrapper.c -@@ -82,6 +82,7 @@ int main(int argc, char *argv[]) - { - char smbspool_cmd[PATH_MAX] = {0}; - struct passwd *pwd; -+ struct group *g = NULL; - char gen_cc[PATH_MAX] = {0}; - struct stat sb; - char *env = NULL; -@@ -89,6 +90,7 @@ int main(int argc, char *argv[]) - char device_uri[4096] = {0}; - uid_t uid = (uid_t)-1; - gid_t gid = (gid_t)-1; -+ gid_t groups[1] = { (gid_t)-1 }; - unsigned long tmp; - int cmp; - int rc; -@@ -176,6 +178,26 @@ int main(int argc, char *argv[]) - return CUPS_BACKEND_FAILED; - } - -+ /* -+ * We need the primary group of the 'lp' user. This is needed to access -+ * temporary files in /var/spool/cups/. -+ */ -+ g = getgrnam("lp"); -+ if (g == NULL) { -+ CUPS_SMB_ERROR("Failed to find user 'lp' - %s", -+ strerror(errno)); -+ return CUPS_BACKEND_FAILED; -+ } -+ -+ CUPS_SMB_DEBUG("Adding group 'lp' (%u)", g->gr_gid); -+ groups[0] = g->gr_gid; -+ rc = setgroups(sizeof(groups), groups); -+ if (rc != 0) { -+ CUPS_SMB_ERROR("Failed to set groups for 'lp' - %s", -+ strerror(errno)); -+ return CUPS_BACKEND_FAILED; -+ } -+ - CUPS_SMB_DEBUG("Switching to gid=%d", gid); - rc = setgid(gid); - if (rc != 0) { --- -2.21.0 - - -From a6b29458e833db85057ef1b7c0403e90f76adfa4 Mon Sep 17 00:00:00 2001 -From: Andreas Schneider -Date: Thu, 16 May 2019 13:41:02 +0200 -Subject: [PATCH 2/9] s3:smbspool: Print the principal we use to authenticate - with - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=13939 - -Signed-off-by: Andreas Schneider -Reviewed-by: Guenther Deschner -(cherry picked from commit 42492d547661cb7a98c237b32d42ee93de35aba5) ---- - source3/client/smbspool.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/source3/client/smbspool.c b/source3/client/smbspool.c -index 22071613677..efbdd418fdb 100644 ---- a/source3/client/smbspool.c -+++ b/source3/client/smbspool.c -@@ -616,6 +616,7 @@ static bool kerberos_ccache_is_valid(void) { - return false; - } else { - krb5_principal default_princ = NULL; -+ char *princ_name = NULL; - - code = krb5_cc_get_principal(ctx, - ccache, -@@ -625,6 +626,16 @@ static bool kerberos_ccache_is_valid(void) { - krb5_free_context(ctx); - return false; - } -+ -+ code = krb5_unparse_name(ctx, -+ default_princ, -+ &princ_name); -+ if (code == 0) { -+ fprintf(stderr, -+ "DEBUG: Try to authenticate as %s\n", -+ princ_name); -+ krb5_free_unparsed_name(ctx, princ_name); -+ } - krb5_free_principal(ctx, default_princ); - } - krb5_cc_close(ctx, ccache); --- -2.21.0 - - -From b64ed8bb51c7c78d757881fc3944f7bc812f5457 Mon Sep 17 00:00:00 2001 -From: Andreas Schneider -Date: Thu, 16 May 2019 14:25:00 +0200 -Subject: [PATCH 3/9] s3:smbspool: Add debug for finding KRB5CCNAME - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=13939 - -Signed-off-by: Andreas Schneider -Reviewed-by: Guenther Deschner -(cherry picked from commit 3632bfef25e471075886eb7aecddd4cc260db8ba) ---- - source3/client/smbspool_krb5_wrapper.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/source3/client/smbspool_krb5_wrapper.c b/source3/client/smbspool_krb5_wrapper.c -index e6684fc0d0c..2cdcd372ec6 100644 ---- a/source3/client/smbspool_krb5_wrapper.c -+++ b/source3/client/smbspool_krb5_wrapper.c -@@ -219,10 +219,14 @@ int main(int argc, char *argv[]) - env = getenv("KRB5CCNAME"); - if (env != NULL && env[0] != 0) { - snprintf(gen_cc, sizeof(gen_cc), "%s", env); -+ CUPS_SMB_DEBUG("User already set KRB5CCNAME [%s] as ccache", -+ gen_cc); - - goto create_env; - } - -+ CUPS_SMB_DEBUG("Trying to guess KRB5CCNAME (FILE, DIR, KEYRING)"); -+ - snprintf(gen_cc, sizeof(gen_cc), "/tmp/krb5cc_%d", uid); - - rc = lstat(gen_cc, &sb); --- -2.21.0 - - -From 3b7be905d256955e7e8c056f14626547e08fea2d Mon Sep 17 00:00:00 2001 -From: Andreas Schneider -Date: Thu, 16 May 2019 17:10:57 +0200 -Subject: [PATCH 4/9] s3:smbspool: Use %u format specifier to print uid - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=13939 - -Signed-off-by: Andreas Schneider -Reviewed-by: Guenther Deschner -(cherry picked from commit be596ce3d2455bd49a8ebd311d8c764c37852858) ---- - source3/client/smbspool_krb5_wrapper.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/source3/client/smbspool_krb5_wrapper.c b/source3/client/smbspool_krb5_wrapper.c -index 2cdcd372ec6..3266b90ec1a 100644 ---- a/source3/client/smbspool_krb5_wrapper.c -+++ b/source3/client/smbspool_krb5_wrapper.c -@@ -227,13 +227,13 @@ int main(int argc, char *argv[]) - - CUPS_SMB_DEBUG("Trying to guess KRB5CCNAME (FILE, DIR, KEYRING)"); - -- snprintf(gen_cc, sizeof(gen_cc), "/tmp/krb5cc_%d", uid); -+ snprintf(gen_cc, sizeof(gen_cc), "/tmp/krb5cc_%u", uid); - - rc = lstat(gen_cc, &sb); - if (rc == 0) { -- snprintf(gen_cc, sizeof(gen_cc), "FILE:/tmp/krb5cc_%d", uid); -+ snprintf(gen_cc, sizeof(gen_cc), "FILE:/tmp/krb5cc_%u", uid); - } else { -- snprintf(gen_cc, sizeof(gen_cc), "/run/user/%d/krb5cc", uid); -+ snprintf(gen_cc, sizeof(gen_cc), "/run/user/%u/krb5cc", uid); - - rc = lstat(gen_cc, &sb); - if (rc == 0 && S_ISDIR(sb.st_mode)) { --- -2.21.0 - - -From 6e2069b014358b6f7e04121fa39c5f2750506d78 Mon Sep 17 00:00:00 2001 -From: Andreas Schneider -Date: Thu, 16 May 2019 17:40:43 +0200 -Subject: [PATCH 5/9] s3:smbspool: Fallback to default ccache if KRB5CCNAME is - not set - -This could also support the new KCM credential cache storage. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=13939 - -Signed-off-by: Andreas Schneider -Reviewed-by: Guenther Deschner -(cherry picked from commit 6bbdf69e406916107400e2cabdbc831e2a2bbee3) ---- - source3/client/smbspool_krb5_wrapper.c | 79 ++++++++++++++++++-------- - source3/wscript_build | 1 + - 2 files changed, 55 insertions(+), 25 deletions(-) - -diff --git a/source3/client/smbspool_krb5_wrapper.c b/source3/client/smbspool_krb5_wrapper.c -index 3266b90ec1a..bff1df417e8 100644 ---- a/source3/client/smbspool_krb5_wrapper.c -+++ b/source3/client/smbspool_krb5_wrapper.c -@@ -21,6 +21,7 @@ - - #include "includes.h" - #include "system/filesys.h" -+#include "system/kerberos.h" - #include "system/passwd.h" - - #include -@@ -68,6 +69,50 @@ static void cups_smb_debug(enum cups_smb_dbglvl_e lvl, const char *format, ...) - buffer); - } - -+static bool kerberos_get_default_ccache(char *ccache_buf, size_t len) -+{ -+ krb5_context ctx; -+ const char *ccache_name = NULL; -+ char *full_ccache_name = NULL; -+ krb5_ccache ccache = NULL; -+ krb5_error_code code; -+ -+ code = krb5_init_context(&ctx); -+ if (code != 0) { -+ return false; -+ } -+ -+ ccache_name = krb5_cc_default_name(ctx); -+ if (ccache_name == NULL) { -+ krb5_free_context(ctx); -+ return false; -+ } -+ -+ code = krb5_cc_resolve(ctx, ccache_name, &ccache); -+ if (code != 0) { -+ krb5_free_context(ctx); -+ return false; -+ } -+ -+ code = krb5_cc_get_full_name(ctx, ccache, &full_ccache_name); -+ krb5_cc_close(ctx, ccache); -+ if (code != 0) { -+ krb5_free_context(ctx); -+ return false; -+ } -+ -+ snprintf(ccache_buf, len, "%s", full_ccache_name); -+ -+#ifdef SAMBA4_USES_HEIMDAL -+ free(full_ccache_name); -+#else -+ krb5_free_string(ctx, full_ccache_name); -+#endif -+ krb5_free_context(ctx); -+ -+ return true; -+} -+ - /* - * This is a helper binary to execute smbspool. - * -@@ -84,7 +129,6 @@ int main(int argc, char *argv[]) - struct passwd *pwd; - struct group *g = NULL; - char gen_cc[PATH_MAX] = {0}; -- struct stat sb; - char *env = NULL; - char auth_info_required[256] = {0}; - char device_uri[4096] = {0}; -@@ -92,6 +136,7 @@ int main(int argc, char *argv[]) - gid_t gid = (gid_t)-1; - gid_t groups[1] = { (gid_t)-1 }; - unsigned long tmp; -+ bool ok; - int cmp; - int rc; - -@@ -225,32 +270,16 @@ int main(int argc, char *argv[]) - goto create_env; - } - -- CUPS_SMB_DEBUG("Trying to guess KRB5CCNAME (FILE, DIR, KEYRING)"); -- -- snprintf(gen_cc, sizeof(gen_cc), "/tmp/krb5cc_%u", uid); -- -- rc = lstat(gen_cc, &sb); -- if (rc == 0) { -- snprintf(gen_cc, sizeof(gen_cc), "FILE:/tmp/krb5cc_%u", uid); -- } else { -- snprintf(gen_cc, sizeof(gen_cc), "/run/user/%u/krb5cc", uid); -- -- rc = lstat(gen_cc, &sb); -- if (rc == 0 && S_ISDIR(sb.st_mode)) { -- snprintf(gen_cc, -- sizeof(gen_cc), -- "DIR:/run/user/%d/krb5cc", -- uid); -- } else { --#if defined(__linux__) -- snprintf(gen_cc, -- sizeof(gen_cc), -- "KEYRING:persistent:%d", -- uid); --#endif -- } -+ ok = kerberos_get_default_ccache(gen_cc, sizeof(gen_cc)); -+ if (ok) { -+ CUPS_SMB_DEBUG("Use default KRB5CCNAME [%s]", -+ gen_cc); -+ goto create_env; - } - -+ /* Fallback to a FILE ccache */ -+ snprintf(gen_cc, sizeof(gen_cc), "FILE:/tmp/krb5cc_%u", uid); -+ - create_env: - /* - * Make sure we do not have LD_PRELOAD or other security relevant -diff --git a/source3/wscript_build b/source3/wscript_build -index f67ce59fe52..8e34b7d0261 100644 ---- a/source3/wscript_build -+++ b/source3/wscript_build -@@ -1134,6 +1134,7 @@ bld.SAMBA3_BINARY('smbspool_krb5_wrapper', - deps=''' - DYNCONFIG - cups -+ krb5 - ''', - install_path='${LIBEXECDIR}/samba', - enabled=bld.CONFIG_SET('HAVE_CUPS')) --- -2.21.0 - - -From d6673500b639ad1402014aa35113bd395e35d4f5 Mon Sep 17 00:00:00 2001 -From: Andreas Schneider -Date: Mon, 13 May 2019 16:48:31 +0200 -Subject: [PATCH 6/9] s3:smbspool: Print the filename we failed to open - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=13939 - -Signed-off-by: Andreas Schneider -Reviewed-by: Guenther Deschner -(cherry picked from commit 281274572bcc3125fe6026a01ef7bf7ef584a0dd) ---- - source3/client/smbspool.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/source3/client/smbspool.c b/source3/client/smbspool.c -index efbdd418fdb..ef16c2bed42 100644 ---- a/source3/client/smbspool.c -+++ b/source3/client/smbspool.c -@@ -224,7 +224,9 @@ main(int argc, /* I - Number of command-line arguments */ - - fp = fopen(print_file, "rb"); - if (fp == NULL) { -- perror("ERROR: Unable to open print file"); -+ fprintf(stderr, -+ "ERROR: Unable to open print file: %s", -+ print_file); - goto done; - } - --- -2.21.0 - - -From ea931f33d92506cdab17a7b746e43831d6bf2112 Mon Sep 17 00:00:00 2001 -From: Andreas Schneider -Date: Mon, 13 May 2019 18:54:02 +0200 -Subject: [PATCH 7/9] s3:smbspool: Always try to authenticate using Kerberos - -If username and password is given, then fallback to NTLM. However try -kinit first. Also we correctly handle NULL passwords in the meantime and -this makes it easier to deal with issues. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=13939 - -Signed-off-by: Andreas Schneider -Reviewed-by: Guenther Deschner -(cherry picked from commit 3d719a1f85db8e423dc3a4116a2228961d5ac48d) ---- - source3/client/smbspool.c | 90 ++++++++++++++++++++++----------------- - 1 file changed, 51 insertions(+), 39 deletions(-) - -diff --git a/source3/client/smbspool.c b/source3/client/smbspool.c -index ef16c2bed42..f21aac2ac58 100644 ---- a/source3/client/smbspool.c -+++ b/source3/client/smbspool.c -@@ -88,8 +88,8 @@ main(int argc, /* I - Number of command-line arguments */ - int port; /* Port number */ - char uri[1024], /* URI */ - *sep, /* Pointer to separator */ -- *tmp, *tmp2, /* Temp pointers to do escaping */ -- *password; /* Password */ -+ *tmp, *tmp2; /* Temp pointers to do escaping */ -+ const char *password = NULL; /* Password */ - char *username, /* Username */ - *server, /* Server name */ - *printer;/* Printer name */ -@@ -293,8 +293,6 @@ main(int argc, /* I - Number of command-line arguments */ - if ((tmp2 = strchr_m(tmp, ':')) != NULL) { - *tmp2++ = '\0'; - password = uri_unescape_alloc(tmp2); -- } else { -- password = empty_str; - } - username = uri_unescape_alloc(tmp); - } else { -@@ -302,14 +300,15 @@ main(int argc, /* I - Number of command-line arguments */ - username = empty_str; - } - -- if ((password = getenv("AUTH_PASSWORD")) == NULL) { -- password = empty_str; -+ env = getenv("AUTH_PASSWORD"); -+ if (env != NULL && strlen(env) > 0) { -+ password = env; - } - - server = uri + 6; - } - -- if (password != empty_str) { -+ if (password != NULL) { - auth_info_required = "username,password"; - } - -@@ -514,6 +513,7 @@ smb_complete_connection(const char *myname, - NTSTATUS nt_status; - struct cli_credentials *creds = NULL; - bool use_kerberos = false; -+ bool fallback_after_kerberos = false; - - /* Start the SMB connection */ - *need_auth = false; -@@ -524,27 +524,21 @@ smb_complete_connection(const char *myname, - return NULL; - } - -- /* -- * We pretty much guarantee password must be valid or a pointer to a -- * 0 char. -- */ -- if (!password) { -- *need_auth = true; -- return NULL; -- } -- - if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) { -- auth_info_required = "negotiate"; - use_kerberos = true; - } - -+ if (flags & CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS) { -+ fallback_after_kerberos = true; -+ } -+ - creds = cli_session_creds_init(cli, - username, - workgroup, - NULL, /* realm */ - password, - use_kerberos, -- false, /* fallback_after_kerberos */ -+ fallback_after_kerberos, - false, /* use_ccache */ - false); /* password_is_nt_hash */ - if (creds == NULL) { -@@ -663,6 +657,10 @@ smb_connect(const char *workgroup, /* I - Workgroup */ - struct cli_state *cli; /* New connection */ - char *myname = NULL; /* Client name */ - struct passwd *pwd; -+ int flags = CLI_FULL_CONNECTION_USE_KERBEROS; -+ bool use_kerberos = false; -+ const char *user = username; -+ int cmp; - - /* - * Get the names and addresses of the client and server... -@@ -672,42 +670,56 @@ smb_connect(const char *workgroup, /* I - Workgroup */ - return NULL; - } - -- /* -- * See if we have a username first. This is for backwards compatible -- * behavior with 3.0.14a -- */ - -- if (username == NULL || username[0] == '\0') { -- if (kerberos_ccache_is_valid()) { -- goto kerberos_auth; -+ cmp = strcmp(auth_info_required, "negotiate"); -+ if (cmp == 0) { -+ if (!kerberos_ccache_is_valid()) { -+ return NULL; - } -+ user = jobusername; -+ -+ use_kerberos = true; -+ fprintf(stderr, -+ "DEBUG: Try to connect using Kerberos ...\n"); -+ } -+ -+ cmp = strcmp(auth_info_required, "username,password"); -+ if (cmp == 0) { -+ if (username == NULL || username[0] == '\0') { -+ return NULL; -+ } -+ -+ /* Fallback to NTLM */ -+ flags |= CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS; -+ -+ fprintf(stderr, -+ "DEBUG: Try to connect using username/password ...\n"); -+ } -+ -+ cmp = strcmp(auth_info_required, "none"); -+ if (cmp == 0) { -+ fprintf(stderr, -+ "DEBUG: This backend doesn't support none auth ...\n"); -+ return NULL; - } - - cli = smb_complete_connection(myname, - server, - port, -- username, -+ user, - password, - workgroup, - share, -- 0, -+ flags, - need_auth); - if (cli != NULL) { -- fputs("DEBUG: Connected with username/password...\n", stderr); -+ fprintf(stderr, "DEBUG: SMB connection established.\n"); - return (cli); - } - --kerberos_auth: -- /* -- * Try to use the user kerberos credentials (if any) to authenticate -- */ -- cli = smb_complete_connection(myname, server, port, jobusername, "", -- workgroup, share, -- CLI_FULL_CONNECTION_USE_KERBEROS, need_auth); -- -- if (cli) { -- fputs("DEBUG: Connected using Kerberos...\n", stderr); -- return (cli); -+ if (!use_kerberos) { -+ fprintf(stderr, "ERROR: SMB connection failed!\n"); -+ return NULL; - } - - /* give a chance for a passwordless NTLMSSP session setup */ --- -2.21.0 - - -From 8689e83030160fbdbe9b72ff0c86826b49f707a1 Mon Sep 17 00:00:00 2001 -From: Andreas Schneider -Date: Thu, 16 May 2019 18:24:32 +0200 -Subject: [PATCH 8/9] s3:smbspool: Add debug messages to - kerberos_ccache_is_valid() - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=13939 - -Signed-off-by: Andreas Schneider -Reviewed-by: Guenther Deschner -(cherry picked from commit 93acd880801524c5e621df7b5bf5ad650f93cec3) ---- - source3/client/smbspool.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/source3/client/smbspool.c b/source3/client/smbspool.c -index f21aac2ac58..79e210dd12e 100644 ---- a/source3/client/smbspool.c -+++ b/source3/client/smbspool.c -@@ -602,12 +602,15 @@ static bool kerberos_ccache_is_valid(void) { - - ccache_name = krb5_cc_default_name(ctx); - if (ccache_name == NULL) { -+ DBG_ERR("Failed to get default ccache name\n"); - krb5_free_context(ctx); - return false; - } - - code = krb5_cc_resolve(ctx, ccache_name, &ccache); - if (code != 0) { -+ DBG_ERR("Failed to resolve ccache name: %s\n", -+ ccache_name); - krb5_free_context(ctx); - return false; - } else { -@@ -618,6 +621,9 @@ static bool kerberos_ccache_is_valid(void) { - ccache, - &default_princ); - if (code != 0) { -+ DBG_ERR("Failed to get default principal from " -+ "ccache: %s\n", -+ ccache_name); - krb5_cc_close(ctx, ccache); - krb5_free_context(ctx); - return false; --- -2.21.0 - - -From d1cee66a5e66d83b2aee3a803351c51d4f5a8118 Mon Sep 17 00:00:00 2001 -From: Andreas Schneider -Date: Tue, 14 May 2019 11:35:46 +0200 -Subject: [PATCH 9/9] s3:smbspool: Use NTSTATUS return codes - -This allows us to simplify some code and return better errors. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=13939 - -Signed-off-by: Andreas Schneider -Reviewed-by: Guenther Deschner -(cherry picked from commit d9af3dc02e98a3eb22441dfbdeddbaca0af078ea) ---- - source3/client/smbspool.c | 250 ++++++++++++++++++++++---------------- - 1 file changed, 145 insertions(+), 105 deletions(-) - -diff --git a/source3/client/smbspool.c b/source3/client/smbspool.c -index 79e210dd12e..ad988eb0df9 100644 ---- a/source3/client/smbspool.c -+++ b/source3/client/smbspool.c -@@ -61,12 +61,27 @@ - * Local functions... - */ - --static int get_exit_code(struct cli_state * cli, NTSTATUS nt_status); -+static int get_exit_code(NTSTATUS nt_status); - static void list_devices(void); --static struct cli_state *smb_complete_connection(const char *, const char *, -- int, const char *, const char *, const char *, const char *, int, bool *need_auth); --static struct cli_state *smb_connect(const char *, const char *, int, const -- char *, const char *, const char *, const char *, bool *need_auth); -+static NTSTATUS -+smb_complete_connection(struct cli_state **output_cli, -+ const char *myname, -+ const char *server, -+ int port, -+ const char *username, -+ const char *password, -+ const char *workgroup, -+ const char *share, -+ int flags); -+static NTSTATUS -+smb_connect(struct cli_state **output_cli, -+ const char *workgroup, -+ const char *server, -+ const int port, -+ const char *share, -+ const char *username, -+ const char *password, -+ const char *jobusername); - static int smb_print(struct cli_state *, const char *, FILE *); - static char *uri_unescape_alloc(const char *); - #if 0 -@@ -90,16 +105,15 @@ main(int argc, /* I - Number of command-line arguments */ - *sep, /* Pointer to separator */ - *tmp, *tmp2; /* Temp pointers to do escaping */ - const char *password = NULL; /* Password */ -- char *username, /* Username */ -- *server, /* Server name */ -+ const char *username = NULL; /* Username */ -+ char *server, /* Server name */ - *printer;/* Printer name */ - const char *workgroup; /* Workgroup */ - FILE *fp; /* File to print */ - int status = 1; /* Status of LPD job */ -- struct cli_state *cli; /* SMB interface */ -- char empty_str[] = ""; -+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; -+ struct cli_state *cli = NULL; /* SMB interface */ - int tries = 0; -- bool need_auth = true; - const char *dev_uri = NULL; - const char *env = NULL; - const char *config_file = NULL; -@@ -296,8 +310,9 @@ main(int argc, /* I - Number of command-line arguments */ - } - username = uri_unescape_alloc(tmp); - } else { -- if ((username = getenv("AUTH_USERNAME")) == NULL) { -- username = empty_str; -+ env = getenv("AUTH_USERNAME"); -+ if (env != NULL && strlen(env) > 0) { -+ username = env; - } - - env = getenv("AUTH_PASSWORD"); -@@ -369,27 +384,39 @@ main(int argc, /* I - Number of command-line arguments */ - load_interfaces(); - - do { -- cli = smb_connect(workgroup, -- server, -- port, -- printer, -- username, -- password, -- print_user, -- &need_auth); -- if (cli == NULL) { -- if (need_auth) { -- exit(2); -+ nt_status = smb_connect(&cli, -+ workgroup, -+ server, -+ port, -+ printer, -+ username, -+ password, -+ print_user); -+ if (!NT_STATUS_IS_OK(nt_status)) { -+ status = get_exit_code(nt_status); -+ if (status == 2) { -+ fprintf(stderr, -+ "DEBUG: Unable to connect to CIFS " -+ "host: %s", -+ nt_errstr(nt_status)); -+ goto done; - } else if (getenv("CLASS") == NULL) { -- fprintf(stderr, "ERROR: Unable to connect to CIFS host, will retry in 60 seconds...\n"); -+ fprintf(stderr, -+ "ERROR: Unable to connect to CIFS " -+ "host: %s. Will retry in 60 " -+ "seconds...\n", -+ nt_errstr(nt_status)); - sleep(60); - tries++; - } else { -- fprintf(stderr, "ERROR: Unable to connect to CIFS host, trying next printer...\n"); -+ fprintf(stderr, -+ "ERROR: Unable to connect to CIFS " -+ "host: %s. Trying next printer...\n", -+ nt_errstr(nt_status)); - goto done; - } - } -- } while ((cli == NULL) && (tries < MAX_RETRY_CONNECT)); -+ } while (!NT_STATUS_IS_OK(nt_status) && (tries < MAX_RETRY_CONNECT)); - - if (cli == NULL) { - fprintf(stderr, "ERROR: Unable to connect to CIFS host after (tried %d times)\n", tries); -@@ -436,10 +463,9 @@ done: - */ - - static int --get_exit_code(struct cli_state * cli, -- NTSTATUS nt_status) -+get_exit_code(NTSTATUS nt_status) - { -- int i; -+ size_t i; - - /* List of NTSTATUS errors that are considered - * authentication errors -@@ -455,17 +481,16 @@ get_exit_code(struct cli_state * cli, - }; - - -- fprintf(stderr, "DEBUG: get_exit_code(cli=%p, nt_status=%s [%x])\n", -- cli, nt_errstr(nt_status), NT_STATUS_V(nt_status)); -+ fprintf(stderr, -+ "DEBUG: get_exit_code(nt_status=%s [%x])\n", -+ nt_errstr(nt_status), NT_STATUS_V(nt_status)); - - for (i = 0; i < ARRAY_SIZE(auth_errors); i++) { - if (!NT_STATUS_EQUAL(nt_status, auth_errors[i])) { - continue; - } - -- if (cli) { -- fprintf(stderr, "ATTR: auth-info-required=%s\n", auth_info_required); -- } -+ fprintf(stderr, "ATTR: auth-info-required=%s\n", auth_info_required); - - /* - * 2 = authentication required... -@@ -498,16 +523,16 @@ list_devices(void) - } - - --static struct cli_state * --smb_complete_connection(const char *myname, -+static NTSTATUS -+smb_complete_connection(struct cli_state **output_cli, -+ const char *myname, - const char *server, - int port, - const char *username, - const char *password, - const char *workgroup, - const char *share, -- int flags, -- bool *need_auth) -+ int flags) - { - struct cli_state *cli; /* New connection */ - NTSTATUS nt_status; -@@ -516,12 +541,11 @@ smb_complete_connection(const char *myname, - bool fallback_after_kerberos = false; - - /* Start the SMB connection */ -- *need_auth = false; - nt_status = cli_start_connection(&cli, myname, server, NULL, port, - SMB_SIGNING_DEFAULT, flags); - if (!NT_STATUS_IS_OK(nt_status)) { - fprintf(stderr, "ERROR: Connection failed: %s\n", nt_errstr(nt_status)); -- return NULL; -+ return nt_status; - } - - if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) { -@@ -544,20 +568,16 @@ smb_complete_connection(const char *myname, - if (creds == NULL) { - fprintf(stderr, "ERROR: cli_session_creds_init failed\n"); - cli_shutdown(cli); -- return NULL; -+ return NT_STATUS_NO_MEMORY; - } - - nt_status = cli_session_setup_creds(cli, creds); - if (!NT_STATUS_IS_OK(nt_status)) { - fprintf(stderr, "ERROR: Session setup failed: %s\n", nt_errstr(nt_status)); - -- if (get_exit_code(cli, nt_status) == 2) { -- *need_auth = true; -- } -- - cli_shutdown(cli); - -- return NULL; -+ return nt_status; - } - - nt_status = cli_tree_connect_creds(cli, share, "?????", creds); -@@ -565,13 +585,9 @@ smb_complete_connection(const char *myname, - fprintf(stderr, "ERROR: Tree connect failed (%s)\n", - nt_errstr(nt_status)); - -- if (get_exit_code(cli, nt_status) == 2) { -- *need_auth = true; -- } -- - cli_shutdown(cli); - -- return NULL; -+ return nt_status; - } - #if 0 - /* Need to work out how to specify this on the URL. */ -@@ -584,7 +600,8 @@ smb_complete_connection(const char *myname, - } - #endif - -- return cli; -+ *output_cli = cli; -+ return NT_STATUS_OK; - } - - static bool kerberos_ccache_is_valid(void) { -@@ -650,49 +667,48 @@ static bool kerberos_ccache_is_valid(void) { - * 'smb_connect()' - Return a connection to a server. - */ - --static struct cli_state * /* O - SMB connection */ --smb_connect(const char *workgroup, /* I - Workgroup */ -+static NTSTATUS -+smb_connect(struct cli_state **output_cli, -+ const char *workgroup, /* I - Workgroup */ - const char *server, /* I - Server */ - const int port, /* I - Port */ - const char *share, /* I - Printer */ - const char *username, /* I - Username */ - const char *password, /* I - Password */ -- const char *jobusername, /* I - User who issued the print job */ -- bool *need_auth) --{ /* O - Need authentication? */ -- struct cli_state *cli; /* New connection */ -+ const char *jobusername) /* I - User who issued the print job */ -+{ -+ struct cli_state *cli = NULL; /* New connection */ - char *myname = NULL; /* Client name */ - struct passwd *pwd; - int flags = CLI_FULL_CONNECTION_USE_KERBEROS; - bool use_kerberos = false; - const char *user = username; -- int cmp; -+ NTSTATUS nt_status; - - /* - * Get the names and addresses of the client and server... - */ - myname = get_myname(talloc_tos()); - if (!myname) { -- return NULL; -+ return NT_STATUS_NO_MEMORY; - } - - -- cmp = strcmp(auth_info_required, "negotiate"); -- if (cmp == 0) { -+ if (strcmp(auth_info_required, "negotiate") == 0) { - if (!kerberos_ccache_is_valid()) { -- return NULL; -+ fprintf(stderr, -+ "ERROR: No valid Kerberos credential cache " -+ "found!\n"); -+ return NT_STATUS_LOGON_FAILURE; - } - user = jobusername; - - use_kerberos = true; - fprintf(stderr, - "DEBUG: Try to connect using Kerberos ...\n"); -- } -- -- cmp = strcmp(auth_info_required, "username,password"); -- if (cmp == 0) { -- if (username == NULL || username[0] == '\0') { -- return NULL; -+ } else if (strcmp(auth_info_required, "username,password") == 0) { -+ if (username == NULL) { -+ return NT_STATUS_INVALID_ACCOUNT_NAME; - } - - /* Fallback to NTLM */ -@@ -700,59 +716,83 @@ smb_connect(const char *workgroup, /* I - Workgroup */ - - fprintf(stderr, - "DEBUG: Try to connect using username/password ...\n"); -- } -+ } else { -+ if (username != NULL) { -+ flags |= CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS; -+ } else if (kerberos_ccache_is_valid()) { -+ auth_info_required = "negotiate"; - -- cmp = strcmp(auth_info_required, "none"); -- if (cmp == 0) { -- fprintf(stderr, -- "DEBUG: This backend doesn't support none auth ...\n"); -- return NULL; -+ user = jobusername; -+ use_kerberos = true; -+ } else { -+ fprintf(stderr, -+ "DEBUG: This backend requires credentials!\n"); -+ return NT_STATUS_ACCESS_DENIED; -+ } - } - -- cli = smb_complete_connection(myname, -- server, -- port, -- user, -- password, -- workgroup, -- share, -- flags, -- need_auth); -- if (cli != NULL) { -+ nt_status = smb_complete_connection(&cli, -+ myname, -+ server, -+ port, -+ user, -+ password, -+ workgroup, -+ share, -+ flags); -+ if (NT_STATUS_IS_OK(nt_status)) { - fprintf(stderr, "DEBUG: SMB connection established.\n"); -- return (cli); -+ -+ *output_cli = cli; -+ return NT_STATUS_OK; - } - - if (!use_kerberos) { - fprintf(stderr, "ERROR: SMB connection failed!\n"); -- return NULL; -+ return nt_status; - } - - /* give a chance for a passwordless NTLMSSP session setup */ - pwd = getpwuid(geteuid()); - if (pwd == NULL) { -- return NULL; -- } -- -- cli = smb_complete_connection(myname, server, port, pwd->pw_name, "", -- workgroup, share, 0, need_auth); -- -- if (cli) { -+ return NT_STATUS_ACCESS_DENIED; -+ } -+ -+ nt_status = smb_complete_connection(&cli, -+ myname, -+ server, -+ port, -+ pwd->pw_name, -+ "", -+ workgroup, -+ share, -+ 0); -+ if (NT_STATUS_IS_OK(nt_status)) { - fputs("DEBUG: Connected with NTLMSSP...\n", stderr); -- return (cli); -+ -+ *output_cli = cli; -+ return NT_STATUS_OK; - } - - /* - * last try. Use anonymous authentication - */ - -- cli = smb_complete_connection(myname, server, port, "", "", -- workgroup, share, 0, need_auth); -- /* -- * Return the new connection... -- */ -- -- return (cli); -+ nt_status = smb_complete_connection(&cli, -+ myname, -+ server, -+ port, -+ "", -+ "", -+ workgroup, -+ share, -+ 0); -+ if (NT_STATUS_IS_OK(nt_status)) { -+ *output_cli = cli; -+ return NT_STATUS_OK; -+ } -+ -+ return nt_status; - } - - -@@ -798,7 +838,7 @@ smb_print(struct cli_state * cli, /* I - SMB connection */ - if (!NT_STATUS_IS_OK(nt_status)) { - fprintf(stderr, "ERROR: %s opening remote spool %s\n", - nt_errstr(nt_status), title); -- return get_exit_code(cli, nt_status); -+ return get_exit_code(nt_status); - } - - /* -@@ -816,7 +856,7 @@ smb_print(struct cli_state * cli, /* I - SMB connection */ - status = cli_writeall(cli, fnum, 0, (uint8_t *)buffer, - tbytes, nbytes, NULL); - if (!NT_STATUS_IS_OK(status)) { -- int ret = get_exit_code(cli, status); -+ int ret = get_exit_code(status); - fprintf(stderr, "ERROR: Error writing spool: %s\n", - nt_errstr(status)); - fprintf(stderr, "DEBUG: Returning status %d...\n", -@@ -832,7 +872,7 @@ smb_print(struct cli_state * cli, /* I - SMB connection */ - if (!NT_STATUS_IS_OK(nt_status)) { - fprintf(stderr, "ERROR: %s closing remote spool %s\n", - nt_errstr(nt_status), title); -- return get_exit_code(cli, nt_status); -+ return get_exit_code(nt_status); - } else { - return (0); - } --- -2.21.0 - -From ffa5f8b65c662130c2d23e47df6d00fef3b73cc3 Mon Sep 17 00:00:00 2001 -From: Andreas Schneider -Date: Tue, 18 Jun 2019 14:43:50 +0200 -Subject: [PATCH] s3:client: Link smbspool_krb5_wrapper against krb5samba - -Heimdal doesn't provide krb5_free_unparsed_name(), so we need to use the -function we provide in krb5samba. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=13939 - -Signed-off-by: Andreas Schneider -Reviewed-by: Ralph Boehme -(cherry picked from commit 9268919e046190c7b423133de3f9d0edada3f1b8) ---- - source3/wscript_build | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/source3/wscript_build b/source3/wscript_build -index 1ebb006781a..26e251f442a 100644 ---- a/source3/wscript_build -+++ b/source3/wscript_build -@@ -1133,7 +1133,7 @@ bld.SAMBA3_BINARY('smbspool_krb5_wrapper', - deps=''' - DYNCONFIG - cups -- krb5 -+ krb5samba - ''', - install_path='${LIBEXECDIR}/samba', - enabled=bld.CONFIG_SET('HAVE_CUPS')) --- -2.21.0 - diff --git a/SOURCES/samba-4.10-fix_smbspool_device_uri.patch b/SOURCES/samba-4.10-fix_smbspool_device_uri.patch deleted file mode 100644 index d72091e..0000000 --- a/SOURCES/samba-4.10-fix_smbspool_device_uri.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 24aa04cee5ce3cdab1fd3cf970e285dbd065305e Mon Sep 17 00:00:00 2001 -From: Bryan Mason -Date: Mon, 16 Sep 2019 12:35:06 -0700 -Subject: [PATCH] s3:client:Use DEVICE_URI, instead of argv[0],for Device URI - -CUPS sanitizes argv[0] by removing username/password, so use -DEVICE_URI environment variable first. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14128 - -Signed-off-by: Bryan Mason -Reviewed-by: Alexander Bokovoy -Reviewed-by: Andreas Schneider - -Autobuild-User(master): Andreas Schneider -Autobuild-Date(master): Wed Sep 18 12:31:11 UTC 2019 on sn-devel-184 - -(cherry picked from commit d65b17c3f7f9959ed95b03cc09e020d7387b7931) ---- - source3/client/smbspool.c | 16 +++++++++------- - 1 file changed, 9 insertions(+), 7 deletions(-) - -diff --git a/source3/client/smbspool.c b/source3/client/smbspool.c -index ad988eb0df9..36f7f67ca94 100644 ---- a/source3/client/smbspool.c -+++ b/source3/client/smbspool.c -@@ -256,13 +256,15 @@ main(int argc, /* I - Number of command-line arguments */ - - /* - * Find the URI ... -- */ -- if (dev_uri == NULL) { -- env = getenv("DEVICE_URI"); -- if (env != NULL && env[0] != '\0') { -- dev_uri = env; -- } -- } -+ * -+ * The URI in argv[0] is sanitized to remove username/password, so -+ * use DEVICE_URI if available. Otherwise keep the URI already -+ * discovered in argv. -+ */ -+ env = getenv("DEVICE_URI"); -+ if (env != NULL && env[0] != '\0') { -+ dev_uri = env; -+ } - - if (dev_uri == NULL) { - fprintf(stderr, --- -2.23.0 - diff --git a/SOURCES/samba-4.10.4.tar.asc b/SOURCES/samba-4.10.4.tar.asc deleted file mode 100644 index 29f805c..0000000 --- a/SOURCES/samba-4.10.4.tar.asc +++ /dev/null @@ -1,7 +0,0 @@ ------BEGIN PGP SIGNATURE----- - -iHMEABECADMWIQRS+8C4bZVLCEMyTNxvM5FbZWi36gUCXOUjjhUcc2FtYmEtYnVn -c0BzYW1iYS5vcmcACgkQbzORW2Vot+oeXQCgkgjBBjMDA7WRd7pl8akT65XmGaAA -n3v79/BJYEuD3vw98M5nW4GBN6C9 -=/Xfk ------END PGP SIGNATURE----- diff --git a/SOURCES/samba-4.11.2.tar.asc b/SOURCES/samba-4.11.2.tar.asc new file mode 100644 index 0000000..004f448 --- /dev/null +++ b/SOURCES/samba-4.11.2.tar.asc @@ -0,0 +1,7 @@ +-----BEGIN PGP SIGNATURE----- + +iHMEABECADMWIQRS+8C4bZVLCEMyTNxvM5FbZWi36gUCXbFv2hUcc2FtYmEtYnVn +c0BzYW1iYS5vcmcACgkQbzORW2Vot+rLpwCgkrZUeff9Ct6UDh5TH8ZBHV9tNDYA +oJ650zGhAVJEsuzoJGkEM0WeeT6N +=BZ0i +-----END PGP SIGNATURE----- diff --git a/SOURCES/samba-4.11.3-fix_smb1_cli_qpathinfo_2_3.patch b/SOURCES/samba-4.11.3-fix_smb1_cli_qpathinfo_2_3.patch new file mode 100644 index 0000000..b8afd92 --- /dev/null +++ b/SOURCES/samba-4.11.3-fix_smb1_cli_qpathinfo_2_3.patch @@ -0,0 +1,172 @@ +From f38cf794fe16e5b160db1a3f4f17d5e5c7601d5c Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Thu, 17 Oct 2019 11:39:02 -0700 +Subject: [PATCH 1/2] s3: libsmb: Ensure SMB1 cli_qpathinfo2() doesn't return + an inode number. + +The info level it uses doesn't return that, previously we +were using the field that is returned as the EA size as +the inode number (which is usually zero, so the code in +libsmbclient would then synthesize an inode number from +a hash of the pathname, which is all it can do for SMB1). + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14161 + +Signed-off-by: Jeremy Allison +Reviewed-by: Andreas Schneider +(cherry picked from commit d495074ee27a5f528d5156a69800ee58d799b1eb) +--- + source3/libsmb/clirap.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c +index e80dfc92a77..b4b40ebdab4 100644 +--- a/source3/libsmb/clirap.c ++++ b/source3/libsmb/clirap.c +@@ -855,7 +855,15 @@ NTSTATUS cli_qpathinfo2_recv(struct tevent_req *req, + *size = IVAL2_TO_SMB_BIG_UINT(state->data,48); + } + if (ino) { +- *ino = IVAL(state->data, 64); ++ /* ++ * SMB1 qpathinfo2 uses SMB_QUERY_FILE_ALL_INFO ++ * which doesn't return an inode number (fileid). ++ * We can't change this to one of the FILE_ID ++ * info levels as only Win2003 and above support ++ * these [MS-SMB: 2.2.2.3.1] and the SMB1 code ++ * needs to support older servers. ++ */ ++ *ino = 0; + } + return NT_STATUS_OK; + } +-- +2.23.0.866.gb869b98d4c-goog + + +From 9c1abe9348c83a2ecd63563f2b47ddf22fd814be Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Thu, 17 Oct 2019 12:41:08 -0700 +Subject: [PATCH 2/2] s3: torture: Ensure SMB1 cli_qpathinfo2() doesn't return + an inode number. + +Piggyback on existing tests, ensure we don't regress on: + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14161 + +Signed-off-by: Jeremy Allison +Reviewed-by: Andreas Schneider +(cherry picked from commit 8e55a8562951924e4b1aad5a6d67fc8b309590c1) +--- + source3/torture/torture.c | 49 +++++++++++++++++++++++++++++++++++++-- + 1 file changed, 47 insertions(+), 2 deletions(-) + +diff --git a/source3/torture/torture.c b/source3/torture/torture.c +index 66dc0cf4d1c..a795e61125f 100644 +--- a/source3/torture/torture.c ++++ b/source3/torture/torture.c +@@ -4211,6 +4211,7 @@ static bool run_trans2test(int dummy) + bool correct = True; + NTSTATUS status; + uint32_t fs_attr; ++ uint64_t ino; + + printf("starting trans2 test\n"); + +@@ -4218,6 +4219,14 @@ static bool run_trans2test(int dummy) + return False; + } + ++ if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) { ++ /* Ensure ino is zero, SMB2 gets a real one. */ ++ ino = 0; ++ } else { ++ /* Ensure ino is -1, SMB1 never gets a real one. */ ++ ino = (uint64_t)-1; ++ } ++ + status = cli_get_fs_attr_info(cli, &fs_attr); + if (!NT_STATUS_IS_OK(status)) { + printf("ERROR: cli_get_fs_attr_info returned %s\n", +@@ -4289,7 +4298,7 @@ static bool run_trans2test(int dummy) + O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum); + cli_close(cli, fnum); + status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts, +- &m_time_ts, &size, NULL, NULL); ++ &m_time_ts, &size, NULL, &ino); + if (!NT_STATUS_IS_OK(status)) { + printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status)); + correct = False; +@@ -4299,6 +4308,19 @@ static bool run_trans2test(int dummy) + printf("This system appears to set a initial 0 write time\n"); + correct = False; + } ++ if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) { ++ /* SMB2 should always return an inode. */ ++ if (ino == 0) { ++ printf("SMB2 bad inode (0)\n"); ++ correct = false; ++ } ++ } else { ++ /* SMB1 must always return zero here. */ ++ if (ino != 0) { ++ printf("SMB1 bad inode (!0)\n"); ++ correct = false; ++ } ++ } + } + + cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); +@@ -11593,11 +11615,20 @@ static bool run_dir_createtime(int dummy) + struct timespec create_time1; + uint16_t fnum; + bool ret = false; ++ uint64_t ino; + + if (!torture_open_connection(&cli, 0)) { + return false; + } + ++ if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) { ++ /* Ensure ino is zero, SMB2 gets a real one. */ ++ ino = 0; ++ } else { ++ /* Ensure ino is -1, SMB1 never gets a real one. */ ++ ino = (uint64_t)-1; ++ } ++ + cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); + cli_rmdir(cli, dname); + +@@ -11608,13 +11639,27 @@ static bool run_dir_createtime(int dummy) + } + + status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL, +- NULL, NULL, NULL); ++ NULL, NULL, &ino); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_qpathinfo2 returned %s\n", + nt_errstr(status)); + goto out; + } + ++ if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) { ++ /* SMB2 should always return an inode. */ ++ if (ino == 0) { ++ printf("SMB2 bad inode (0)\n"); ++ goto out; ++ } ++ } else { ++ /* SMB1 must always return zero here. */ ++ if (ino != 0) { ++ printf("SMB1 bad inode (!0)\n"); ++ goto out; ++ } ++ } ++ + /* Sleep 3 seconds, then create a file. */ + sleep(3); + +-- +2.23.0.866.gb869b98d4c-goog + diff --git a/SOURCES/samba-4.11.3-only_link_libnsl_libsocket_if_needed.patch b/SOURCES/samba-4.11.3-only_link_libnsl_libsocket_if_needed.patch new file mode 100644 index 0000000..11d8e78 --- /dev/null +++ b/SOURCES/samba-4.11.3-only_link_libnsl_libsocket_if_needed.patch @@ -0,0 +1,85 @@ +From 2958016c30a8d9f80a45b64e91a20d8ebf995d85 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Mon, 21 Oct 2019 17:08:08 +0200 +Subject: [PATCH] replace: Only link libnsl and libsocket if requrired + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14168 + +Signed-off-by: Andreas Schneider +Reviewed-by: Alexander Bokovoy + +Autobuild-User(master): Andreas Schneider +Autobuild-Date(master): Wed Oct 23 08:23:13 UTC 2019 on sn-devel-184 + +(cherry picked from commit 263bec1b8d0744da73dd92e4a361fb7430289ab3) + +Autobuild-User(v4-11-test): Karolin Seeger +Autobuild-Date(v4-11-test): Mon Nov 4 09:31:23 UTC 2019 on sn-devel-184 +--- + lib/replace/wscript | 36 +++++++++++++++++++++++++++++++----- + 1 file changed, 31 insertions(+), 5 deletions(-) + +diff --git a/lib/replace/wscript b/lib/replace/wscript +index 240d730cbee..56e2a22de49 100644 +--- a/lib/replace/wscript ++++ b/lib/replace/wscript +@@ -190,10 +190,35 @@ def configure(conf): + conf.CHECK_TYPE_IN('sig_atomic_t', 'signal.h', define='HAVE_SIG_ATOMIC_T_TYPE') + conf.CHECK_FUNCS('sigsetmask siggetmask sigprocmask sigblock sigaction sigset') + +- conf.CHECK_FUNCS_IN('''inet_ntoa inet_aton inet_ntop inet_pton connect gethostbyname +- getaddrinfo getnameinfo freeaddrinfo gai_strerror socketpair''', +- 'socket nsl', checklibc=True, +- headers='sys/socket.h netinet/in.h arpa/inet.h netdb.h') ++ # Those functions are normally available in libc ++ if not conf.CHECK_FUNCS(''' ++ inet_ntoa ++ inet_aton ++ inet_ntop ++ inet_pton ++ connect ++ gethostbyname ++ getaddrinfo ++ getnameinfo ++ freeaddrinfo ++ gai_strerror ++ socketpair''', ++ headers='sys/socket.h netinet/in.h arpa/inet.h netdb.h'): ++ conf.CHECK_FUNCS_IN(''' ++ inet_ntoa ++ inet_aton ++ inet_ntop ++ inet_pton ++ connect ++ gethostbyname ++ getaddrinfo ++ getnameinfo ++ freeaddrinfo ++ gai_strerror ++ socketpair''', ++ 'socket nsl', ++ headers='sys/socket.h netinet/in.h arpa/inet.h netdb.h') ++ conf.DEFINE('REPLACE_REQUIRES_LIBSOCKET_LIBNSL', 1) + + conf.CHECK_FUNCS('memset_s memset_explicit') + +@@ -836,6 +861,7 @@ def build(bld): + extra_libs = '' + if bld.CONFIG_SET('HAVE_LIBBSD'): extra_libs += ' bsd' + if bld.CONFIG_SET('HAVE_LIBRT'): extra_libs += ' rt' ++ if bld.CONFIG_SET('REPLACE_REQUIRES_LIBSOCKET_LIBNSL'): extra_libs += ' socket nsl' + + bld.SAMBA_SUBSYSTEM('LIBREPLACE_HOSTCC', + REPLACE_HOSTCC_SOURCE, +@@ -876,7 +902,7 @@ def build(bld): + # at the moment: + # hide_symbols=bld.BUILTIN_LIBRARY('replace'), + private_library=True, +- deps='crypt dl nsl socket attr' + extra_libs) ++ deps='crypt dl attr' + extra_libs) + + replace_test_cflags = '' + if bld.CONFIG_SET('HAVE_WNO_FORMAT_TRUNCATION'): +-- +2.23.0 + diff --git a/SOURCES/samba-4.11.7-fix_segfault_in_smbd_do_qfilepathinfo.patch b/SOURCES/samba-4.11.7-fix_segfault_in_smbd_do_qfilepathinfo.patch new file mode 100644 index 0000000..d079d31 --- /dev/null +++ b/SOURCES/samba-4.11.7-fix_segfault_in_smbd_do_qfilepathinfo.patch @@ -0,0 +1,33 @@ +From 7de67a994e84c2fadccb48c2448f2cba529a57fd Mon Sep 17 00:00:00 2001 +From: Volker Lendecke +Date: Wed, 31 Jul 2019 10:42:24 +0200 +Subject: [PATCH] smbd: Fix the build with clang + +clang correctly complains that "close_fsp" is used uninitialized if +"get_posix_fsp" fails and we end up in "goto out;". + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14251 + +Signed-off-by: Volker Lendecke +Reviewed-by: Jeremy Allison +(cherry picked from commit a8a1ca3f83dce6d725392989cbc97271cbf52f4a) +--- + source3/smbd/trans2.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c +index b0616f15ade..8164c8fd213 100644 +--- a/source3/smbd/trans2.c ++++ b/source3/smbd/trans2.c +@@ -4848,7 +4848,7 @@ static NTSTATUS smb_query_posix_acl(connection_struct *conn, + unsigned int size_needed = 0; + NTSTATUS status; + bool ok; +- bool close_fsp; ++ bool close_fsp = false; + + /* + * Ensure we always operate on a file descriptor, not just +-- +2.24.1 + diff --git a/SOURCES/samba-4.11.7-fix_smbclient_debug_spam.patch b/SOURCES/samba-4.11.7-fix_smbclient_debug_spam.patch new file mode 100644 index 0000000..ff175fe --- /dev/null +++ b/SOURCES/samba-4.11.7-fix_smbclient_debug_spam.patch @@ -0,0 +1,48 @@ +From c50d91d16292a13d29b1125c0aa85c7a7963de5f Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Mon, 27 Jan 2020 14:58:10 +0100 +Subject: [PATCH] lib:util: Log mkdir error on correct debug levels +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +For smbd we want an error and for smbclient we only want it in NOTICE +debug level. +The default log level of smbclient is log level 1 so we need notice to +not spam the user. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14253 + +Signed-off-by: Andreas Schneider +Reviewed-by: Guenther Deschner + +Autobuild-User(master): Günther Deschner +Autobuild-Date(master): Mon Jan 27 15:55:24 UTC 2020 on sn-devel-184 + +(cherry picked from commit 0ad6a243b259d284064c0c5abcc7d430d55be7e1) +--- + lib/util/util.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/lib/util/util.c b/lib/util/util.c +index 3bdeded5c1b..0d9ffe5cb7b 100644 +--- a/lib/util/util.c ++++ b/lib/util/util.c +@@ -353,9 +353,12 @@ _PUBLIC_ bool directory_create_or_exist(const char *dname, + old_umask = umask(0); + ret = mkdir(dname, dir_perms); + if (ret == -1 && errno != EEXIST) { +- DBG_WARNING("mkdir failed on directory %s: %s\n", ++ int dbg_level = geteuid() == 0 ? DBGLVL_ERR : DBGLVL_NOTICE; ++ ++ DBG_PREFIX(dbg_level, ++ ("mkdir failed on directory %s: %s\n", + dname, +- strerror(errno)); ++ strerror(errno))); + umask(old_umask); + return false; + } +-- +2.25.0 + diff --git a/SOURCES/samba.log b/SOURCES/samba.log deleted file mode 100644 index 6ccd04d..0000000 --- a/SOURCES/samba.log +++ /dev/null @@ -1,7 +0,0 @@ -/var/log/samba/* { - notifempty - olddir /var/log/samba/old - missingok - sharedscripts - copytruncate -} diff --git a/SOURCES/samba.logrotate b/SOURCES/samba.logrotate new file mode 100644 index 0000000..40f85aa --- /dev/null +++ b/SOURCES/samba.logrotate @@ -0,0 +1,10 @@ +/var/log/samba/log.* { + compress + dateext + maxage 365 + rotate 99 + notifempty + olddir /var/log/samba/old + missingok + copytruncate +} diff --git a/SPECS/samba.spec b/SPECS/samba.spec index 65b987e..51f3b9c 100644 --- a/SPECS/samba.spec +++ b/SPECS/samba.spec @@ -6,13 +6,13 @@ # ctdb is enabled by default, you can disable it with: --without clustering %bcond_without clustering -%define main_release 101 +%define main_release 13 -%define samba_version 4.10.4 -%define talloc_version 2.1.16 -%define tdb_version 1.3.18 -%define tevent_version 0.9.39 -%define ldb_version 1.5.4 +%define samba_version 4.11.2 +%define talloc_version 2.2.0 +%define tdb_version 1.4.2 +%define tevent_version 0.10.0 +%define ldb_version 2.0.7 # This should be rc1 or nil %define pre_release %nil @@ -41,7 +41,9 @@ %if 0%{?fedora} %ifarch aarch64 ppc64le s390x x86_64 %global with_vfs_cephfs 1 +#endifarch %endif +#endif fedora %endif %global with_vfs_glusterfs 1 @@ -50,12 +52,9 @@ # Only enable on x86_64 %ifarch x86_64 %global with_vfs_glusterfs 1 +#endif arch %endif -%endif - -%global with_intel_aes_accel 0 -%ifarch x86_64 -%global with_intel_aes_accel 1 +#endif rhel %endif %global libwbc_alternatives_version 0.15 @@ -102,15 +101,15 @@ Epoch: 2 Summary: Server and Client software to interoperate with Windows machines License: GPLv3+ and LGPLv3+ -URL: http://www.samba.org/ +URL: https://www.samba.org # This is a xz recompressed file of https://ftp.samba.org/pub/samba/samba-%%{version}%%{pre_release}.tar.gz -Source0: samba-%{version}%{pre_release}.tar.xz +Source0: https://ftp.samba.org/pub/samba/samba-%{version}%{pre_release}.tar.gz#/samba-%{version}%{pre_release}.tar.xz Source1: https://ftp.samba.org/pub/samba/samba-%{version}%{pre_release}.tar.asc Source2: gpgkey-52FBC0B86D954B0843324CDC6F33915B6568B7EA.gpg # Red Hat specific replacement-files -Source10: samba.log +Source10: samba.logrotate Source11: smb.conf.vendor Source12: smb.conf.example Source13: pam_winbind.conf @@ -118,12 +117,223 @@ Source14: samba.pamd Source201: README.downgrade -Patch0: samba-4.10-fix_smbspool.patch -Patch1: samba-4.10-avoid_overlinking_with_librt_and_libpthread.patch -Patch2: samba-4.10-Fix_forest_trust_with_additional_attrs.patch -Patch3: samba-4.10-fix_smbspool_device_uri.patch -Patch4: samba-4.10-Remove_shm_get_configure_check.patch -Patch5: samba-4.10-fix_linking_nsl_socket.patch +Patch0001: 0001-s3-profile-Use-SHA1-for-hashing-in-profiling-functio.patch +Patch0002: 0002-lib-crypto-Fix-path-to-header-file-in-gnutls_helpers.patch +Patch0003: 0003-lib-crypto-Add-GNUTLS_FIPS140_SET_-LAX-STRICT-_MODE-.patch +Patch0004: 0004-s3-profile-Allow-profile-subsystem-to-use-SHA1-in-FI.patch +Patch0005: 0005-lib-util-Use-GnuTLS-random-number-generator-in-genra.patch +Patch0006: 0006-lib-crypto-Document-gnutls_error_to_werror.patch +Patch0007: 0007-lib-crypto-Document-samba_gnutls_arcfour_confounded_.patch +Patch0008: 0008-s3-rpc_client-Return-NTSTATUS-for-init_samr_CryptPas.patch +Patch0009: 0009-s3-rpc_client-Return-NTSTATUS-for-init_samr_CryptPas.patch +Patch0010: 0010-libcli-auth-Return-NTSTATUS-for-encode_or_decode_arc.patch +Patch0011: 0011-libcli-auth-Add-test-for-decoding-an-RC4-password-bu.patch +Patch0012: 0012-s3-rpc_client-Use-samba_gnutls_arcfour_confounded_md.patch +Patch0013: 0013-s3-rpc_client-Use-GnuTLS-RC4-in-init_samr_CryptPassw.patch +Patch0014: 0014-libcli-auth-Use-samba_gnutls_arcfour_confounded_md5-.patch +Patch0015: 0015-libcli-auth-Rename-encode_or_decode_arc4_passwd_buff.patch +Patch0016: 0016-libcli-auth-Pass-samr_CryptPasswordEx-to-decode_rc4_.patch +Patch0017: 0017-libcli-auth-Add-encode_rc4_passwd_buffer.patch +Patch0018: 0018-libcli-auth-Add-test-for-encode_rc4_passwd_buffer.patch +Patch0019: 0019-s3-rpc_client-Use-encode_rc4_passwd_buffer-in-init_s.patch +Patch0020: 0020-s4-libnet-Use-encode_rc4_passwd_buffer-in-libnet_Set.patch +Patch0021: 0021-s4-libnet-Use-encode_rc4_passwd_buffer-in-libnet_Set.patch +Patch0022: 0022-s4-libnet-Use-GnuTLS-RC4-in-libnet_SetPassword_samr_.patch +Patch0023: 0023-s4-libnet-Use-GnuTLS-RC4-in-libnet_SetPassword_samr_.patch +Patch0024: 0024-s4-libnet-Use-GnuTLS-RC4-in-libnet_ChangePassword_sa.patch +Patch0025: 0025-libcli-auth-Return-WERROR-for-encode_wkssvc_join_pas.patch +Patch0026: 0026-libcli-auth-Add-test-for-encode-decode-_wkssvc_join_.patch +Patch0027: 0027-libcli-auth-Use-samba_gnutls_arcfour_confounded_md5-.patch +Patch0028: 0028-libcli-auth-Use-samba_gnutls_arcfour_confounded_md5-.patch +Patch0029: 0029-auth-ntlmssp-Use-GnuTLS-RC4-in-ntlmssp-client.patch +Patch0030: 0030-auth-ntlmssp-Use-GnuTLS-RC4-for-ntlmssp-signing.patch +Patch0031: 0031-s3-libsmb-Use-GnuTLS-RC4-in-clirap.patch +Patch0032: 0032-s3-rpc_client-Use-init_samr_CryptPassword-in-cli_sam.patch +Patch0033: 0033-s3-rpc_server-Use-GnuTLS-RC4-in-samr-password-check.patch +Patch0034: 0034-s3-rpc_server-Use-GnuTLS-RC4-to-decrypt-samr-passwor.patch +Patch0035: 0035-s3-utils-Use-GnuTLS-RC4-in-ntlm_auth.patch +Patch0036: 0036-s4-rpc_server-Use-samba_gnutls_arcfour_confounded_md.patch +Patch0037: 0037-s4-rpc_server-Use-GnuTLS-RC4-for-samr-password.patch +Patch0038: 0038-s4-torture-Use-GnuTLS-RC4-for-RAP-SAM-test.patch +Patch0039: 0039-s4-torture-Use-init_samr_CryptPassword-Ex-in-samba3r.patch +Patch0040: 0040-s4-torture-Use-init_samr_CryptPassword-in-test_SetUs.patch +Patch0041: 0041-s4-torture-Use-init_samr_CryptPassword-in-test_SetUs.patch +Patch0042: 0042-s4-torture-Use-init_samr_CryptPassword-in-test_SetUs.patch +Patch0043: 0043-s4-torture-Use-init_samr_CryptPassword-in-test_SetUs.patch +Patch0044: 0044-s4-torture-Use-init_samr_CryptPassword-in-test_SetUs.patch +Patch0045: 0045-s4-torture-Use-GnuTLS-RC4-in-test_OemChangePasswordU.patch +Patch0046: 0046-s4-torture-Use-init_samr_CryptPassword-in-test_Chang.patch +Patch0047: 0047-s4-torture-Use-init_samr_CryptPassword-in-test_Chang.patch +Patch0048: 0048-s4_torture-Use-GnuTLS-RC4-in-test_ChangePasswordUser.patch +Patch0049: 0049-s4-torture-Use-GnuTLS-RC4-in-test_ChangePasswordUser.patch +Patch0050: 0050-s4-torture-Use-init_samr_CryptPassword-in-test_Chang.patch +Patch0051: 0051-s4-torture-clarify-comments-and-variable-names-in-Ch.patch +Patch0052: 0052-s4-torture-Use-init_samr_CryptPassword-in-test_Chang.patch +Patch0053: 0053-s4-torture-Use-GnuTLS-RC4-in-test_ChangePasswordRand.patch +Patch0054: 0054-s4-torture-Use-samba_gnutls_arcfour_confounded_md5-i.patch +Patch0055: 0055-s4-torture-Use-init_samr_CryptPassword-in-testjoin-R.patch +Patch0056: 0056-lib-crypto-Use-GnuTLS-RC4-in-py_crypto.patch +Patch0057: 0057-lib-crypto-Remove-arcfour.h-from-crypto.h.patch +Patch0058: 0058-lib-crypto-Don-t-build-RC4-if-we-have-GnuTLS-3.4.7.patch +Patch0059: 0059-s3-lib-Use-the-passed-mem_ctx-instead-of-talloc_tos.patch +Patch0060: 0060-s3-rpcclient-Use-a-stackframe-for-temporary-memory.patch +Patch0061: 0061-s3-utils-Use-a-stackframe-for-temporary-memory.patch +Patch0062: 0062-s3-rpc_server-Use-a-stackframe-for-temporary-memory.patch +Patch0063: 0063-netlogon-Fix-potential-use-of-uninitialized-variable.patch +Patch0064: 0064-s3-rpc_server-Only-dump-passwords-in-developer-build.patch +Patch0065: 0065-libcli-smb-Add-forward-declaration-for-gnutls_hmac_h.patch +Patch0066: 0066-s3-modules-Link-vfs_acl_common-against-gnutls.patch +Patch0067: 0067-lib-util-Add-generate_nonce_buffer.patch +Patch0068: 0068-libcli-smb-Use-generate_nonce_buffer-for-AES-CCM-and.patch +Patch0069: 0069-s3-smbd-Use-generate_nonce_buffer-for-AES-CCM-and-AE.patch +Patch0070: 0070-lib-util-Add-better-documentation-for-generate_secre.patch +Patch0071: 0071-s4-rpc_server-Use-generate_secret_buffer-to-create-a.patch +Patch0072: 0072-s4-rpc_server-Use-generate_secret_buffer-for-backupk.patch +Patch0073: 0073-s4-rpc_server-Use-generate_secret_buffer-for-netlogo.patch +Patch0074: 0074-libcli-auth-Use-generate_secret_buffer-for-netlogon-.patch +Patch0075: 0075-lib-util-Fix-documentation-for-random-number-functio.patch +Patch0076: 0076-Revert-libcli-auth-Use-generate_secret_buffer-for-ne.patch +Patch0077: 0077-Revert-s4-rpc_server-Use-generate_secret_buffer-for-.patch +Patch0078: 0078-Revert-s4-rpc_server-Use-generate_secret_buffer-for-.patch +Patch0079: 0079-Revert-s4-rpc_server-Use-generate_secret_buffer-to-c.patch +Patch0080: 0080-lib-util-Use-generate_secret_buffer-for-long-term-pa.patch +Patch0081: 0081-s4-samdb-Use-generate_nonce_buffer-for-AEC-GCM-nonce.patch +Patch0082: 0082-s3-passdb-Use-generate_secret_buffer-for-generating-.patch +Patch0083: 0083-auth-ntlmssp-Use-generate_random_buffer-for-session-.patch +Patch0084: 0084-encrypted_secrets-Add-known-and-expected-value-test.patch +Patch0085: 0085-s4-samdb-Remove-dual-stack-mode-from-test_-encrypted.patch +Patch0086: 0086-s4-samdb-Only-include-necessary-header-files-in-encr.patch +Patch0087: 0087-waf-Check-for-GNUTLS-AES-CFB-support.patch +Patch0088: 0088-libcli-auth-Use-netlogon_creds_aes_encrypt-in-netlog.patch +Patch0089: 0089-libcli-auth-Use-GnuTLS-AES128-CFB-for-netlogon_creds.patch +Patch0090: 0090-libcli-auth-Return-NTSTATUS-for-netlogon_creds_aes_e.patch +Patch0091: 0091-libcli-auth-Use-GnuTLS-AES128-CFB-for-netlogon_creds.patch +Patch0092: 0092-libcli-auth-Return-NTSTATUS-from-netlogon_creds_aes_.patch +Patch0093: 0093-crypto-Update-REQUIREMENTS-file-with-new-minimum-ver.patch +Patch0094: 0094-libcli-auth-Check-NTSTATUS-from-netlogon_creds_aes_-.patch +Patch0095: 0095-s3-rpc_server-Check-NTSTATUS-return-value-from-netlo.patch +Patch0096: 0096-s4-rpc_server-Check-NTSTATUS-return-value-from-netlo.patch +Patch0097: 0097-s3-librpc-Remove-unused-init_netr_CryptPassword.patch +Patch0098: 0098-auth-credentials-Check-NTSTATUS-return-from-netlogon.patch +Patch0099: 0099-auth-gensec-Use-GnuTLS-AES128-CFB8-in-netsec_do_seq_.patch +Patch0100: 0100-auth-gensec-Use-gnutls_error_to_ntstatus-consistentl.patch +Patch0101: 0101-auth-gensec-Use-GnuTLS-AES-CFB8-in-netsec_do_seal.patch +Patch0102: 0102-auth-gensec-Use-gnutls_error_to_ntstatus-in-netsec_d.patch +Patch0103: 0103-lib-crypto-Prepare-not-to-build-AES-or-AES-CMAC-if-w.patch +Patch0104: 0104-build-Set-minimum-GnuTLS-version-at-3.4.7.patch +Patch0105: 0105-s4-rpc_server-Remove-Heimdal-based-BackupKey-server.patch +Patch0106: 0106-s4-rpc_server-backupkey-consistently-check-error-cod.patch +Patch0107: 0107-lib-crypto-Remove-unused-RC4-code-from-Samba.patch +Patch0108: 0108-s4-samdb-Remove-duplicate-encrypted_secrets-code-usi.patch +Patch0109: 0109-build-Remove-explicit-check-for-HAVE_GNUTLS_AEAD-as-.patch +Patch0110: 0110-libcli-smb-Define-SMB2_AES_128_CCM_NONCE_SIZE.patch +Patch0111: 0111-libcli-smb-Use-GnuTLS-for-AES-constants.patch +Patch0112: 0112-libcli-smb-Add-gnutls_aead_cipher_hd_t-to-smb2_signi.patch +Patch0113: 0113-libcli-smb-Use-a-smb2_signing_key-for-storing-the-en.patch +Patch0114: 0114-libcli-smb-Use-a-smb2_signing_key-for-storing-the-de.patch +Patch0115: 0115-s3-smbd-Use-smb2_signing_key-structure-for-the-encry.patch +Patch0116: 0116-s3-smbd-Use-smb2_signing_key-structure-for-the-decry.patch +Patch0117: 0117-s3-smbd-Use-GnuTLS-for-AES-constants.patch +Patch0118: 0118-waf-Check-for-AES128-CMAC-support-in-GnuTLS.patch +Patch0119: 0119-libcli-smb-Use-GnuTLS-AES128-CMAC-in-smb2_signing_si.patch +Patch0120: 0120-libcli-smb-Use-gnutls_error_to_ntstatus-in-smb2_sign.patch +Patch0121: 0121-libcli-smb-Use-GnuTLS-AES128-CMAC-in-smb2_signing_ch.patch +Patch0122: 0122-libcli-smb-Use-gnutls_error_to_ntstatus-in-smb2_sign.patch +Patch0123: 0123-lib-crypto-Do-not-build-AES-CMAC-if-we-use-GnuTLS-th.patch +Patch0124: 0124-libcli-smb-Support-GnuTLS-AES-CCM-and-GCM-in-smb2_si.patch +Patch0125: 0125-libcli-smb-Support-GnuTLS-AES-CCM-and-GCM-in-smb2_si.patch +Patch0126: 0126-libcli-smb-Use-smb2_signing_key-in-smb2_signing_decr.patch +Patch0127: 0127-libcli-smb-Use-gnutls_error_to_ntstatus-in-smb2_sign.patch +Patch0128: 0128-libcli-smb-Use-smb2_signing_key-in-smb2_signing_encr.patch +Patch0129: 0129-libcli-smb-Use-gnutls_error_to_ntstatus-in-smb2_sign.patch +Patch0130: 0130-libcli-smb-Prefer-AES-GCM-over-AES-CCM-with-GnuTLS.patch +Patch0131: 0131-s3-smbd-Prefer-AES-GCM-over-AES-CCM-with-GnuTLS.patch +Patch0132: 0132-auth-gensec-fix-non-AES-schannel-seal.patch +Patch0133: 0133-auth-gensec-fix-AES-schannel-seal-and-unseal.patch +Patch0134: 0134-libcli-auth-add-gnutls-test-for-aes-128-cfb8-cipher-.patch +Patch0135: 0135-waf-Check-for-gnutls_aead_cipher_encryptv2.patch +Patch0136: 0136-libcli-smb-Use-gnutls_aead_cipher_encryptv2-for-AES-.patch +Patch0137: 0137-libcli-smb-Use-gnutls_aead_cipher_decryptv2-for-AES-.patch +Patch0138: 0138-libcli-smb-Do-not-use-gnutls_aead_cipher_encryptv2-w.patch +Patch0139: 0139-libcli-auth-Return-NTSTATUS-for-SMBOWFencrypt_ntv2.patch +Patch0140: 0140-libcli-auth-Check-return-codes-of-SMBsesskeygen_ntv2.patch +Patch0141: 0141-libcli-auth-Return-NTSTATUS-for-SMBOWFencrypt_ntv2.patch +Patch0142: 0142-libcli-auth-Check-return-code-of-SMBOWFencrypt_ntv2.patch +Patch0143: 0143-s4-rpc_server-Remove-gnutls_global_-de-init.patch +Patch0144: 0144-s4-lib-Remove-gnutls_global_-de-init-from-libtls.patch +Patch0145: 0145-s4-torture-Remove-calls-to-gnutls_global_-de-init-in.patch +Patch0146: 0146-libcli-auth-Check-return-value-of-netlogon_creds_ini.patch +Patch0147: 0147-libcli-auth-Check-return-status-of-netlogon_creds_in.patch +Patch0148: 0148-libcli-auth-Check-return-status-of-netlogon_creds_fi.patch +Patch0149: 0149-libcli-auth-Return-NTSTATUS-for-netlogon_creds_clien.patch +Patch0150: 0150-auth-pycreds-Check-return-code-of-netlogon_creds_cli.patch +Patch0151: 0151-libcli-auth-Check-return-code-of-netlogon_creds_clie.patch +Patch0152: 0152-s4-librpc-Check-return-code-of-netlogon_creds_client.patch +Patch0153: 0153-libcli-auth-Check-return-code-of-netlogon_creds_step.patch +Patch0154: 0154-libcli-auth-Check-return-code-of-netlogon_creds_step.patch +Patch0155: 0155-libcli-auth-Check-return-code-of-netlogon_creds_aes_.patch +Patch0156: 0156-s3-rpc_server-Replace-E_md5hash-with-GnuTLS-calls.patch +Patch0157: 0157-s3-winbindd-Replace-E_md5hash-with-GnuTLS-calls.patch +Patch0158: 0158-s3-winbind-Replace-E_md5hash-with-GnuTLS-calls.patch +Patch0159: 0159-libcli-auth-Remove-unused-E_md5hash.patch +Patch0160: 0160-s4-lib-tls-Fix-cert-and-privkey-types.patch +Patch0161: 0161-winbind-Fix-CID-1455915-Resource-leak.patch +Patch0162: 0162-auth-tests-Improve-debug-output-of-test_gnutls.patch +Patch0163: 0163-auth-tests-Only-enable-torture_gnutls_aes_128_cfb-on.patch +Patch0164: 0164-libcli-auth-test-des_crypt56-and-add-test_gnutls-to-.patch +Patch0165: 0165-selftest-test-E_P16.patch +Patch0166: 0166-selftest-test-sam_rid_crypt.patch +Patch0167: 0167-selftest-test-E_P24-and-SMBOWFencrypt.patch +Patch0168: 0168-selftest-test-E_old_pw_hash.patch +Patch0169: 0169-selftest-test-des_crypt128.patch +Patch0170: 0170-selftest-test-des_crypt112-and-fix-unused-decryption.patch +Patch0171: 0171-selftest-test-des_crypt112_16.patch +Patch0172: 0172-selftest-test-SMBsesskeygen_lm_sess_key.patch +Patch0173: 0173-selftest-test-sess_crypt_blob.patch +Patch0174: 0174-smbdes-add-des_crypt56_gnutls-using-DES-CBC-with-zer.patch +Patch0175: 0175-netlogon_creds_des_encrypt-decrypt_LMKey-use-gnutls-.patch +Patch0176: 0176-SMBsesskeygen_lm_sess_key-use-gnutls-and-return-NTST.patch +Patch0177: 0177-smbdes-convert-sam_rid_crypt-to-use-gnutls.patch +Patch0178: 0178-smbdes-convert-E_P16-to-use-gnutls.patch +Patch0179: 0179-smbdes-remove-D_P16-not-used.patch +Patch0180: 0180-smbdes-convert-E_P24-and-SMBOWFencrypt-to-use-gnutls.patch +Patch0181: 0181-smbdes-convert-des_crypt128-to-use-gnutls.patch +Patch0182: 0182-smbdes-convert-E_old_pw_hash-to-use-gnutls.patch +Patch0183: 0183-smbdes-convert-des_crypt112-to-use-gnutls.patch +Patch0184: 0184-smbdes-convert-des_crypt112_16-to-use-gnutls.patch +Patch0185: 0185-session-convert-sess_crypt_blob-to-use-gnutls.patch +Patch0186: 0186-sess_crypt_blob-can-only-crypt-blobs-whose-size-divi.patch +Patch0187: 0187-smbdes-remove-old-unused-DES-builtin-crypto.patch +Patch0188: 0188-lib-crypto-Remove-our-implementation-of-AES-CCM.patch +Patch0189: 0189-lib-crypto-Remove-our-implementation-of-AES-GCM.patch +Patch0190: 0190-lib-crypto-Only-build-AES-code-if-we-need-AES-CMAC.patch +Patch0191: 0191-lib-crypto-Build-intel-aes-ni-only-if-GnuTLS-doesn-t.patch +Patch0192: 0192-lib-crypto-Add-samba_gnutls_weak_crypto.patch +Patch0193: 0193-s3-utils-Add-weak-crypto-information-to-testparm.patch +Patch0194: 0194-lib-param-Add-lp-cfg-_weak_crypto.patch +Patch0195: 0195-gensec-Add-a-check-if-a-gensec-module-implements-wea.patch +Patch0196: 0196-auth-ntlmssp-Mark-as-weak_crypto.patch +Patch0197: 0197-s3-param-Force-SMB-encryption-for-DECRPC-over-named-.patch +Patch0198: 0198-s3-param-Only-allow-SMB-3.0-for-DCERPC-client-connec.patch +Patch0199: 0199-s3-rpc_server-Allow-RC4-encrypted-buffers-in-samr_Se.patch +Patch0200: 0200-s4-rpc_server-Allow-to-use-RC4-for-setting-passwords.patch +Patch0201: 0201-s3-rpc_server-Only-announce-RC4-in-netlogon-server-i.patch +Patch0202: 0202-s4-rpc_server-Only-announce-RC4-in-netlogon-server-i.patch +Patch0203: 0203-s4-samdb-Allow-to-hash-password-using-MD5-in-samdb.patch +Patch0204: 0204-lib-crypto-Allow-py_crypto-to-use-RC4-in-FIPS-mode.patch +Patch0205: 0205-param-Do-not-use-weak-crypto-for-kerberos-if-disallo.patch +Patch0206: 0206-param-Do-not-use-weak-crypto-in-ldap-server-if-disal.patch +Patch0207: 0207-libcli-auth-If-weak-crypto-is-disallowed-reject-md5-.patch +Patch0208: 0208-s3-librpc-Only-use-RC4-if-our-systems-supports-it.patch +Patch0209: 0209-s3-rpcserver-fix-security-level-check-for-DsRGetFore.patch + +Patch1000: samba-4.11.3-only_link_libnsl_libsocket_if_needed.patch +Patch1001: CVE-2019-14907-4.11.patch +Patch1002: krb5_no_des_411.patch +Patch1003: samba-4.11.7-fix_smbclient_debug_spam.patch +Patch1004: samba-4.11.3-fix_smb1_cli_qpathinfo_2_3.patch +Patch1005: samba-4.11.7-fix_segfault_in_smbd_do_qfilepathinfo.patch +Patch1006: samba-4.10-fix-netbios-join.patch Requires(pre): /usr/sbin/groupadd Requires(post): systemd @@ -168,6 +378,7 @@ BuildRequires: docbook-style-xsl BuildRequires: e2fsprogs-devel BuildRequires: gawk BuildRequires: gnupg2 +BuildRequires: gnutls-devel >= 3.4.7 BuildRequires: gpgme-devel BuildRequires: jansson-devel BuildRequires: krb5-devel >= %{required_mit_krb5} @@ -188,17 +399,9 @@ BuildRequires: pam-devel BuildRequires: perl-interpreter BuildRequires: perl-generators BuildRequires: perl(Archive::Tar) -BuildRequires: perl(ExtUtils::MakeMaker) -BuildRequires: perl(Parse::Yapp) BuildRequires: perl(Test::More) BuildRequires: popt-devel BuildRequires: python3-devel -%if %{with_dc} -# Add python3-iso8601 to avoid that the -# version in Samba is being packaged -BuildRequires: python3-iso8601 -BuildRequires: python3-subunit-test -%endif # with_dc BuildRequires: quota-devel BuildRequires: readline-devel BuildRequires: rpcgen @@ -223,17 +426,17 @@ BuildRequires: libcephfs-devel %endif %if %{with_dc} +# Add python3-iso8601 to avoid that the +# version in Samba is being packaged +BuildRequires: python3-iso8601 + BuildRequires: bind -BuildRequires: gnutls-devel >= 3.4.7 BuildRequires: krb5-server >= %{required_mit_krb5} - -# Required by samba-tool to run tests -BuildRequires: python3-crypto -%else -BuildRequires: gnutls-devel >= 3.2.0 +#endif with_dc %endif # pidl requirements +BuildRequires: perl(ExtUtils::MakeMaker) BuildRequires: perl(Parse::Yapp) BuildRequires: libtalloc-devel >= %{talloc_version} @@ -248,7 +451,7 @@ BuildRequires: python3-tdb >= %{tdb_version} BuildRequires: libldb-devel >= %{ldb_version} BuildRequires: python3-ldb-devel >= %{ldb_version} -%if %{with testsuite} +%if %{with testsuite} || %{with_dc} BuildRequires: ldb-tools BuildRequires: tdb-tools BuildRequires: python3-gpg @@ -315,6 +518,7 @@ Summary: Files used by both Samba servers and clients BuildArch: noarch Requires(post): systemd +Recommends: logrotate Provides: samba4-common = %{samba_depver} Obsoletes: samba4-common < %{samba_depver} @@ -363,6 +567,7 @@ SMB/CIFS clients. Summary: Samba AD Domain Controller Requires: %{name} = %{samba_depver} Requires: %{name}-libs = %{samba_depver} +Requires: %{name}-dc-provision = %{samba_depver} Requires: %{name}-dc-libs = %{samba_depver} Requires: %{name}-winbind = %{samba_depver} # samba-tool needs tdbbackup @@ -386,6 +591,14 @@ Obsoletes: samba4-dc < %{samba_depver} %description dc The samba-dc package provides AD Domain Controller functionality +### DC-PROVISION +%package dc-provision +Summary: Samba AD files to provision a DC +BuildArch: noarch + +%description dc-provision +The samba-dc-provision package provides files to setup a domoin controller + ### DC-LIBS %package dc-libs Summary: Samba AD Domain Controller Libraries @@ -410,7 +623,8 @@ Requires: bind %description dc-bind-dlz The %{name}-dc-bind-dlz package contains the libraries for bind to manage all name server related details of Samba AD. -%endif # with_dc +#endif with_dc +%endif ### DEVEL %package devel @@ -435,6 +649,7 @@ Requires: %{name}-libs = %{samba_depver} %description vfs-cephfs Samba VFS module for Ceph distributed storage system integration. +#endif with_vfs_cephfs %endif ### GLUSTER @@ -512,7 +727,8 @@ Requires: libsmbclient = %{samba_depver} The libsmbclient-devel package contains the header files and libraries needed to develop programs that link against the SMB client library in the Samba suite. -%endif # with_libsmbclient +#endif with_libsmbclient +%endif ### LIBWBCLIENT %if %with_libwbclient @@ -534,7 +750,8 @@ Obsoletes: samba-winbind-devel < %{samba_depver} %description -n libwbclient-devel The libwbclient-devel package provides developer tools for the wbclient library. -%endif # with_libwbclient +#endif with_libwbclient +%endif ### PYTHON3 %package -n python3-%{name} @@ -615,7 +832,7 @@ Requires: libsmbclient = %{samba_depver} %if %with_libwbclient Requires: libwbclient = %{samba_depver} %endif -Requires: python3-%{name} = %{version}-%{release} +Requires: python3-%{name} = %{samba_depver} Requires: perl(Archive::Tar) Provides: samba4-test = %{samba_depver} @@ -656,6 +873,9 @@ Requires: libwbclient = %{samba_depver} Provides: samba4-winbind = %{samba_depver} Obsoletes: samba4-winbind < %{samba_depver} +# Old NetworkManager expects the dispatcher scripts in a different place +Conflicts: NetworkManager < 1.20 + %description winbind The samba-winbind package provides the winbind NSS library, and some client tools. Winbind enables Linux to be a full member in Windows domains and to use @@ -775,7 +995,8 @@ CTDB is a cluster implementation of the TDB database used by Samba and other projects to store temporary data. If an application is already using TDB for temporary data it is very easy to convert that application to be cluster aware and use CTDB instead. -%endif # with_clustering_support +#endif with_clustering_support +%endif @@ -842,7 +1063,7 @@ export LDFLAGS="%{__global_ldflags} -fuse-ld=gold" --private-libraries=%{_samba_private_libraries} \ %endif --with-system-mitkrb5 \ - --with-experimental-mit-ad-dc \ + --with-experimental-mit-ad-dc \ %if ! %with_dc --without-ad-dc \ %endif @@ -858,9 +1079,6 @@ export LDFLAGS="%{__global_ldflags} -fuse-ld=gold" %if %{with testsuite} --enable-selftest \ %endif -%if %with_intel_aes_accel - --accel-aes=intelaesni \ -%endif --with-systemd \ --systemd-install-services \ --with-systemddir=/usr/lib/systemd/system \ @@ -869,7 +1087,13 @@ export LDFLAGS="%{__global_ldflags} -fuse-ld=gold" --systemd-winbind-extra=%{_systemd_extra} \ --systemd-samba-extra=%{_systemd_extra} -make %{?_smp_mflags} V=1 +make %{?_smp_mflags} + +pushd pidl +%__perl Makefile.PL PREFIX=%{_prefix} + +make %{?_smp_mflags} +popd %install rm -rf %{buildroot} @@ -938,7 +1162,7 @@ install -d -m 0755 %{buildroot}%{_sysconfdir}/sysconfig install -m 0644 packaging/systemd/samba.sysconfig %{buildroot}%{_sysconfdir}/sysconfig/samba %if %with_clustering_support cat > %{buildroot}%{_sysconfdir}/sysconfig/ctdb < /dev/null -else - %{_sbindir}/update-alternatives --remove libwbclient.so%{libwbc_alternatives_suffix} %{_libdir}/samba/wbclient/libwbclient.so +if [ $1 -eq 0 ]; then + if [ "`readlink %{_libdir}/libwbclient.so`" == "libwbclient.so.%{libwbc_alternatives_version}" ]; then + /bin/rm -f /etc/alternatives/libwbclient.so%{libwbc_alternatives_suffix} \ + /var/lib/alternatives/libwbclient.so%{libwbc_alternatives_suffix} 2> /dev/null + else + %{_sbindir}/update-alternatives \ + --remove \ + libwbclient.so%{libwbc_alternatives_suffix} \ + %{_libdir}/samba/wbclient/libwbclient.so + fi fi -%endif # with_libwbclient +#endif with_libwbclient +%endif %ldconfig_scriptlets test @@ -1163,8 +1410,7 @@ fi %systemd_preun winbind.service %postun winbind -%systemd_postun_with_restart smb.service -%systemd_postun_with_restart nmb.service +%systemd_postun_with_restart winbind.service %postun winbind-krb5-locator if [ "$1" -ge "1" ]; then @@ -1237,6 +1483,7 @@ fi %{_libdir}/samba/vfs/fileid.so %{_libdir}/samba/vfs/fruit.so %{_libdir}/samba/vfs/full_audit.so +%{_libdir}/samba/vfs/gpfs.so %{_libdir}/samba/vfs/glusterfs_fuse.so %{_libdir}/samba/vfs/linux_xfs_sgid.so %{_libdir}/samba/vfs/media_harmony.so @@ -1286,6 +1533,7 @@ fi %{_mandir}/man8/vfs_fileid.8* %{_mandir}/man8/vfs_fruit.8* %{_mandir}/man8/vfs_full_audit.8* +%{_mandir}/man8/vfs_gpfs.8* %{_mandir}/man8/vfs_glusterfs_fuse.8* %{_mandir}/man8/vfs_linux_xfs_sgid.8* %{_mandir}/man8/vfs_media_harmony.8* @@ -1314,12 +1562,14 @@ fi %if ! %{with_vfs_cephfs} %exclude %{_mandir}/man8/vfs_ceph.8* +%exclude %{_mandir}/man8/vfs_ceph_snapshots.8* %endif %attr(775,root,printadmin) %dir /var/lib/samba/drivers ### CLIENT %files client +%doc source3/client/README.smbspool %{_bindir}/cifsdd %{_bindir}/dbwrap_tool %{_bindir}/dumpmscat @@ -1391,6 +1641,7 @@ fi %dir %{_libdir}/samba %{_libdir}/samba/libCHARSET3-samba4.so %{_libdir}/samba/libMESSAGING-SEND-samba4.so +%{_libdir}/samba/libMESSAGING-samba4.so %{_libdir}/samba/libaddns-samba4.so %{_libdir}/samba/libads-samba4.so %{_libdir}/samba/libasn1util-samba4.so @@ -1416,6 +1667,7 @@ fi %{_libdir}/samba/libgenrand-samba4.so %{_libdir}/samba/libgensec-samba4.so %{_libdir}/samba/libgpext-samba4.so +%{_libdir}/samba/libgpo-samba4.so %{_libdir}/samba/libgse-samba4.so %{_libdir}/samba/libhttp-samba4.so %{_libdir}/samba/libinterfaces-samba4.so @@ -1436,6 +1688,7 @@ fi %{_libdir}/samba/libnetif-samba4.so %{_libdir}/samba/libnpa-tstream-samba4.so %{_libdir}/samba/libposix-eadb-samba4.so +%{_libdir}/samba/libprinter-driver-samba4.so %{_libdir}/samba/libprinting-migrate-samba4.so %{_libdir}/samba/libreplace-samba4.so %{_libdir}/samba/libregistry-samba4.so @@ -1470,12 +1723,14 @@ fi %if ! %with_libwbclient %{_libdir}/samba/libwbclient.so.* %{_libdir}/samba/libwinbind-client-samba4.so -%endif # ! with_libwbclient +#endif ! with_libwbclient +%endif %if ! %with_libsmbclient %{_libdir}/samba/libsmbclient.so.* %{_mandir}/man7/libsmbclient.7* -%endif # ! with_libsmbclient +#endif ! with_libsmbclient +%endif ### COMMON %files common @@ -1504,9 +1759,6 @@ fi # common libraries %{_libdir}/samba/libpopt-samba3-cmdline-samba4.so %{_libdir}/samba/libpopt-samba3-samba4.so -%if %{with_intel_aes_accel} -%{_libdir}/samba/libaesni-intel-samba4.so -%endif %dir %{_libdir}/samba/ldb @@ -1535,9 +1787,10 @@ fi %{_unitdir}/samba.service %{_bindir}/samba-tool %{_sbindir}/samba -%{_sbindir}/samba_kcc %{_sbindir}/samba_dnsupdate +%{_sbindir}/samba_downgrade_db %{_sbindir}/samba-gpupdate +%{_sbindir}/samba_kcc %{_sbindir}/samba_spnupdate %{_sbindir}/samba_upgradedns @@ -1551,6 +1804,7 @@ fi %{_libdir}/samba/ldb/aclread.so %{_libdir}/samba/ldb/anr.so %{_libdir}/samba/ldb/audit_log.so +%{_libdir}/samba/ldb/count_attrs.so %{_libdir}/samba/ldb/descriptor.so %{_libdir}/samba/ldb/dirsync.so %{_libdir}/samba/ldb/dns_notify.so @@ -1598,11 +1852,14 @@ fi %{_libdir}/samba/ldb/wins_ldb.so %{_libdir}/samba/vfs/posix_eadb.so %dir /var/lib/samba/sysvol -%{_datadir}/samba/setup %{_mandir}/man8/samba.8* +%{_mandir}/man8/samba_downgrade_db.8* %{_mandir}/man8/samba-gpupdate.8* %{_mandir}/man8/samba-tool.8* +%files dc-provision +%{_datadir}/samba/setup + ### DC-LIBS %files dc-libs %{_libdir}/samba/libdb-glue-samba4.so @@ -1623,7 +1880,6 @@ fi %{_libdir}/samba/service/nbtd.so %{_libdir}/samba/service/ntp_signd.so %{_libdir}/samba/service/s3fs.so -%{_libdir}/samba/service/web.so %{_libdir}/samba/service/winbindd.so %{_libdir}/samba/service/wrepl.so %{_libdir}/libdcerpc-server.so.* @@ -1641,7 +1897,8 @@ fi %{_libdir}/samba/bind9/dlz_bind9_10.so %{_libdir}/samba/bind9/dlz_bind9_11.so %{_libdir}/samba/bind9/dlz_bind9_12.so -%endif # with_dc +#endif with_dc +%endif ### DEVEL %files devel @@ -1764,17 +2021,21 @@ fi %if ! %with_libsmbclient %{_includedir}/samba-4.0/libsmbclient.h -%endif # ! with_libsmbclient +#endif ! with_libsmbclient +%endif %if ! %with_libwbclient %{_includedir}/samba-4.0/wbclient.h -%endif # ! with_libwbclient +#endif ! with_libwbclient +%endif ### VFS-CEPHFS %if %{with_vfs_cephfs} %files vfs-cephfs %{_libdir}/samba/vfs/ceph.so +%{_libdir}/samba/vfs/ceph_snapshots.so %{_mandir}/man8/vfs_ceph.8* +%{_mandir}/man8/vfs_ceph_snapshots.8* %endif ### VFS-GLUSTERFS @@ -1793,12 +2054,10 @@ fi %files libs %{_libdir}/libdcerpc-samr.so.* -%{_libdir}/samba/libMESSAGING-samba4.so %{_libdir}/samba/libLIBWBCLIENT-OLD-samba4.so %{_libdir}/samba/libauth4-samba4.so %{_libdir}/samba/libauth-unix-token-samba4.so %{_libdir}/samba/libdcerpc-samba4.so -%{_libdir}/samba/libnon-posix-acls-samba4.so %{_libdir}/samba/libshares-samba4.so %{_libdir}/samba/libsmbpasswdparser-samba4.so %{_libdir}/samba/libxattr-tdb-samba4.so @@ -1814,7 +2073,8 @@ fi %{_libdir}/libsmbclient.so %{_libdir}/pkgconfig/smbclient.pc %{_mandir}/man7/libsmbclient.7* -%endif # with_libsmbclient +#endif with_libsmbclient +%endif ### LIBWBCLIENT %if %with_libwbclient @@ -1827,45 +2087,52 @@ fi %{_includedir}/samba-4.0/wbclient.h %{_libdir}/samba/wbclient/libwbclient.so %{_libdir}/pkgconfig/wbclient.pc -%endif # with_libwbclient +#endif with_libwbclient +%endif ### PIDL %files pidl +%doc pidl/README %attr(755,root,root) %{_bindir}/pidl %dir %{perl_vendorlib}/Parse -%{perl_vendorlib}/Parse/Pidl.pm +%attr(644,root,root) %{perl_vendorlib}/Parse/Pidl.pm %dir %{perl_vendorlib}/Parse/Pidl -%{perl_vendorlib}/Parse/Pidl/CUtil.pm -%{perl_vendorlib}/Parse/Pidl/Samba4.pm -%{perl_vendorlib}/Parse/Pidl/Expr.pm -%{perl_vendorlib}/Parse/Pidl/ODL.pm -%{perl_vendorlib}/Parse/Pidl/Typelist.pm -%{perl_vendorlib}/Parse/Pidl/IDL.pm -%{perl_vendorlib}/Parse/Pidl/Compat.pm +%attr(644,root,root) %{perl_vendorlib}/Parse/Pidl/CUtil.pm +%attr(644,root,root) %{perl_vendorlib}/Parse/Pidl/Samba4.pm +%attr(644,root,root) %{perl_vendorlib}/Parse/Pidl/Expr.pm +%attr(644,root,root) %{perl_vendorlib}/Parse/Pidl/ODL.pm +%attr(644,root,root) %{perl_vendorlib}/Parse/Pidl/Typelist.pm +%attr(644,root,root) %{perl_vendorlib}/Parse/Pidl/IDL.pm +%attr(644,root,root) %{perl_vendorlib}/Parse/Pidl/Compat.pm %dir %{perl_vendorlib}/Parse/Pidl/Wireshark -%{perl_vendorlib}/Parse/Pidl/Wireshark/Conformance.pm -%{perl_vendorlib}/Parse/Pidl/Wireshark/NDR.pm -%{perl_vendorlib}/Parse/Pidl/Dump.pm +%attr(644,root,root) %{perl_vendorlib}/Parse/Pidl/Wireshark/Conformance.pm +%attr(644,root,root) %{perl_vendorlib}/Parse/Pidl/Wireshark/NDR.pm +%attr(644,root,root) %{perl_vendorlib}/Parse/Pidl/Dump.pm %dir %{perl_vendorlib}/Parse/Pidl/Samba3 -%{perl_vendorlib}/Parse/Pidl/Samba3/ServerNDR.pm -%{perl_vendorlib}/Parse/Pidl/Samba3/ClientNDR.pm +%attr(644,root,root) %{perl_vendorlib}/Parse/Pidl/Samba3/ServerNDR.pm +%attr(644,root,root) %{perl_vendorlib}/Parse/Pidl/Samba3/ClientNDR.pm +%attr(644,root,root) %{perl_vendorlib}/Parse/Pidl/Samba3/Template.pm %dir %{perl_vendorlib}/Parse/Pidl/Samba4 -%{perl_vendorlib}/Parse/Pidl/Samba4/Header.pm +%attr(644,root,root) %{perl_vendorlib}/Parse/Pidl/Samba4/Header.pm %dir %{perl_vendorlib}/Parse/Pidl/Samba4/COM -%{perl_vendorlib}/Parse/Pidl/Samba4/COM/Header.pm -%{perl_vendorlib}/Parse/Pidl/Samba4/COM/Proxy.pm -%{perl_vendorlib}/Parse/Pidl/Samba4/COM/Stub.pm -%{perl_vendorlib}/Parse/Pidl/Samba4/Python.pm -%{perl_vendorlib}/Parse/Pidl/Samba4/Template.pm +%attr(644,root,root) %{perl_vendorlib}/Parse/Pidl/Samba4/COM/Header.pm +%attr(644,root,root) %{perl_vendorlib}/Parse/Pidl/Samba4/COM/Proxy.pm +%attr(644,root,root) %{perl_vendorlib}/Parse/Pidl/Samba4/COM/Stub.pm +%attr(644,root,root) %{perl_vendorlib}/Parse/Pidl/Samba4/Python.pm +%attr(644,root,root) %{perl_vendorlib}/Parse/Pidl/Samba4/Template.pm %dir %{perl_vendorlib}/Parse/Pidl/Samba4/NDR -%{perl_vendorlib}/Parse/Pidl/Samba4/NDR/Server.pm -%{perl_vendorlib}/Parse/Pidl/Samba4/NDR/Client.pm -%{perl_vendorlib}/Parse/Pidl/Samba4/NDR/Parser.pm -%{perl_vendorlib}/Parse/Pidl/Samba4/TDR.pm -%{perl_vendorlib}/Parse/Pidl/NDR.pm -%{perl_vendorlib}/Parse/Pidl/Util.pm -%{_mandir}/man1/pidl* -%{_mandir}/man3/Parse::Pidl* +%attr(644,root,root) %{perl_vendorlib}/Parse/Pidl/Samba4/NDR/Server.pm +%attr(644,root,root) %{perl_vendorlib}/Parse/Pidl/Samba4/NDR/Client.pm +%attr(644,root,root) %{perl_vendorlib}/Parse/Pidl/Samba4/NDR/Parser.pm +%attr(644,root,root) %{perl_vendorlib}/Parse/Pidl/Samba4/TDR.pm +%attr(644,root,root) %{perl_vendorlib}/Parse/Pidl/NDR.pm +%attr(644,root,root) %{perl_vendorlib}/Parse/Pidl/Util.pm +%attr(644,root,root) %{_mandir}/man1/pidl.1* +%attr(644,root,root) %{_mandir}/man3/Parse::Pidl::Dump.3pm* +%attr(644,root,root) %{_mandir}/man3/Parse::Pidl::NDR.3pm* +%attr(644,root,root) %{_mandir}/man3/Parse::Pidl::Util.3pm* +%attr(644,root,root) %{_mandir}/man3/Parse::Pidl::Wireshark::Conformance.3pm* +%attr(644,root,root) %{_mandir}/man3/Parse::Pidl::Wireshark::NDR.3pm* ### PYTHON3 %files -n python3-%{name} @@ -2001,6 +2268,7 @@ fi %{python3_sitearch}/samba/netcmd/__pycache__/__init__.*.pyc %{python3_sitearch}/samba/netcmd/__pycache__/common.*.pyc %{python3_sitearch}/samba/netcmd/__pycache__/computer.*.pyc +%{python3_sitearch}/samba/netcmd/__pycache__/contact.*.pyc %{python3_sitearch}/samba/netcmd/__pycache__/dbcheck.*.pyc %{python3_sitearch}/samba/netcmd/__pycache__/delegation.*.pyc %{python3_sitearch}/samba/netcmd/__pycache__/dns.*.pyc @@ -2028,6 +2296,7 @@ fi %{python3_sitearch}/samba/netcmd/__pycache__/visualize.*.pyc %{python3_sitearch}/samba/netcmd/common.py %{python3_sitearch}/samba/netcmd/computer.py +%{python3_sitearch}/samba/netcmd/contact.py %{python3_sitearch}/samba/netcmd/dbcheck.py %{python3_sitearch}/samba/netcmd/delegation.py %{python3_sitearch}/samba/netcmd/dns.py @@ -2068,7 +2337,6 @@ fi %{python3_sitearch}/samba/samba3/smbd.*.so %{python3_sitearch}/samba/sd_utils.py %{python3_sitearch}/samba/sites.py -%{python3_sitearch}/samba/smb.*.so %{python3_sitearch}/samba/subnets.py %dir %{python3_sitearch}/samba/subunit %{python3_sitearch}/samba/subunit/__init__.py @@ -2083,10 +2351,6 @@ fi %{python3_sitearch}/samba/third_party/__pycache__/__init__.*.pyc %{python3_sitearch}/samba/upgrade.py %{python3_sitearch}/samba/upgradehelpers.py -%dir %{python3_sitearch}/samba/web_server -%{python3_sitearch}/samba/web_server/__init__.py -%dir %{python3_sitearch}/samba/web_server/__pycache__ -%{python3_sitearch}/samba/web_server/__pycache__/__init__.*.pyc %{python3_sitearch}/samba/werror.*.so %{python3_sitearch}/samba/xattr.py %{python3_sitearch}/samba/xattr_native.*.so @@ -2182,6 +2446,7 @@ fi %{python3_sitearch}/samba/tests/__pycache__/auth_log_netlogon.*.pyc %{python3_sitearch}/samba/tests/__pycache__/auth_log_netlogon_bad_creds.*.pyc %{python3_sitearch}/samba/tests/__pycache__/auth_log_samlogon.*.pyc +%{python3_sitearch}/samba/tests/__pycache__/auth_log_winbind.*.pyc %{python3_sitearch}/samba/tests/__pycache__/common.*.pyc %{python3_sitearch}/samba/tests/__pycache__/complex_expressions.*.pyc %{python3_sitearch}/samba/tests/__pycache__/core.*.pyc @@ -2210,6 +2475,7 @@ fi %{python3_sitearch}/samba/tests/__pycache__/hostconfig.*.pyc %{python3_sitearch}/samba/tests/__pycache__/join.*.pyc %{python3_sitearch}/samba/tests/__pycache__/krb5_credentials.*.pyc +%{python3_sitearch}/samba/tests/__pycache__/ldap_referrals.*.pyc %{python3_sitearch}/samba/tests/__pycache__/loadparm.*.pyc %{python3_sitearch}/samba/tests/__pycache__/libsmb.*.pyc %{python3_sitearch}/samba/tests/__pycache__/lsa_string.*.pyc @@ -2253,6 +2519,7 @@ fi %{python3_sitearch}/samba/tests/__pycache__/samdb.*.pyc %{python3_sitearch}/samba/tests/__pycache__/samdb_api.*.pyc %{python3_sitearch}/samba/tests/__pycache__/security.*.pyc +%{python3_sitearch}/samba/tests/__pycache__/segfault.*.pyc %{python3_sitearch}/samba/tests/__pycache__/smb.*.pyc %{python3_sitearch}/samba/tests/__pycache__/smbd_base.*.pyc %{python3_sitearch}/samba/tests/__pycache__/source.*.pyc @@ -2262,6 +2529,7 @@ fi %{python3_sitearch}/samba/tests/__pycache__/upgrade.*.pyc %{python3_sitearch}/samba/tests/__pycache__/upgradeprovision.*.pyc %{python3_sitearch}/samba/tests/__pycache__/upgradeprovisionneeddc.*.pyc +%{python3_sitearch}/samba/tests/__pycache__/usage.*.pyc %{python3_sitearch}/samba/tests/__pycache__/xattr.*.pyc %{python3_sitearch}/samba/tests/audit_log_base.py %{python3_sitearch}/samba/tests/audit_log_dsdb.py @@ -2274,12 +2542,14 @@ fi %{python3_sitearch}/samba/tests/auth_log_netlogon.py %{python3_sitearch}/samba/tests/auth_log_pass_change.py %{python3_sitearch}/samba/tests/auth_log_samlogon.py +%{python3_sitearch}/samba/tests/auth_log_winbind.py %dir %{python3_sitearch}/samba/tests/blackbox %{python3_sitearch}/samba/tests/blackbox/__init__.py %dir %{python3_sitearch}/samba/tests/blackbox/__pycache__ %{python3_sitearch}/samba/tests/blackbox/__pycache__/__init__.*.pyc %{python3_sitearch}/samba/tests/blackbox/__pycache__/bug13653.*.pyc %{python3_sitearch}/samba/tests/blackbox/__pycache__/check_output.*.pyc +%{python3_sitearch}/samba/tests/blackbox/__pycache__/downgradedatabase.*.pyc %{python3_sitearch}/samba/tests/blackbox/__pycache__/ndrdump.*.pyc %{python3_sitearch}/samba/tests/blackbox/__pycache__/netads_json.*.pyc %{python3_sitearch}/samba/tests/blackbox/__pycache__/samba_dnsupdate.*.pyc @@ -2290,6 +2560,7 @@ fi %{python3_sitearch}/samba/tests/blackbox/__pycache__/traffic_summary.*.pyc %{python3_sitearch}/samba/tests/blackbox/bug13653.py %{python3_sitearch}/samba/tests/blackbox/check_output.py +%{python3_sitearch}/samba/tests/blackbox/downgradedatabase.py %{python3_sitearch}/samba/tests/blackbox/ndrdump.py %{python3_sitearch}/samba/tests/blackbox/netads_json.py %{python3_sitearch}/samba/tests/blackbox/samba_dnsupdate.py @@ -2341,9 +2612,7 @@ fi %{python3_sitearch}/samba/tests/dns_base.py %{python3_sitearch}/samba/tests/dns_forwarder.py %dir %{python3_sitearch}/samba/tests/dns_forwarder_helpers -%{python3_sitearch}/samba/tests/dns_forwarder_helpers/__pycache__/dns_hub.*.pyc %{python3_sitearch}/samba/tests/dns_forwarder_helpers/__pycache__/server.*.pyc -%{python3_sitearch}/samba/tests/dns_forwarder_helpers/dns_hub.py %{python3_sitearch}/samba/tests/dns_forwarder_helpers/server.py %{python3_sitearch}/samba/tests/dns_invalid.py %{python3_sitearch}/samba/tests/dns_tkey.py @@ -2385,6 +2654,7 @@ fi %{python3_sitearch}/samba/tests/kcc/kcc_utils.py %{python3_sitearch}/samba/tests/kcc/ldif_import_export.py %{python3_sitearch}/samba/tests/krb5_credentials.py +%{python3_sitearch}/samba/tests/ldap_referrals.py %{python3_sitearch}/samba/tests/libsmb.py %{python3_sitearch}/samba/tests/loadparm.py %{python3_sitearch}/samba/tests/lsa_string.py @@ -2431,18 +2701,24 @@ fi %{python3_sitearch}/samba/tests/samba_tool/__pycache__/__init__.*.pyc %{python3_sitearch}/samba/tests/samba_tool/__pycache__/base.*.pyc %{python3_sitearch}/samba/tests/samba_tool/__pycache__/computer.*.pyc +%{python3_sitearch}/samba/tests/samba_tool/__pycache__/contact.*.pyc %{python3_sitearch}/samba/tests/samba_tool/__pycache__/demote.*.pyc %{python3_sitearch}/samba/tests/samba_tool/__pycache__/dnscmd.*.pyc +%{python3_sitearch}/samba/tests/samba_tool/__pycache__/drs_clone_dc_data_lmdb_size.*.pyc +%{python3_sitearch}/samba/tests/samba_tool/__pycache__/dsacl.*.pyc %{python3_sitearch}/samba/tests/samba_tool/__pycache__/forest.*.pyc %{python3_sitearch}/samba/tests/samba_tool/__pycache__/fsmo.*.pyc %{python3_sitearch}/samba/tests/samba_tool/__pycache__/gpo.*.pyc %{python3_sitearch}/samba/tests/samba_tool/__pycache__/group.*.pyc %{python3_sitearch}/samba/tests/samba_tool/__pycache__/help.*.pyc %{python3_sitearch}/samba/tests/samba_tool/__pycache__/join.*.pyc +%{python3_sitearch}/samba/tests/samba_tool/__pycache__/join_lmdb_size.*.pyc %{python3_sitearch}/samba/tests/samba_tool/__pycache__/ntacl.*.pyc %{python3_sitearch}/samba/tests/samba_tool/__pycache__/ou.*.pyc %{python3_sitearch}/samba/tests/samba_tool/__pycache__/passwordsettings.*.pyc %{python3_sitearch}/samba/tests/samba_tool/__pycache__/processes.*.pyc +%{python3_sitearch}/samba/tests/samba_tool/__pycache__/promote_dc_lmdb_size.*.pyc +%{python3_sitearch}/samba/tests/samba_tool/__pycache__/provision_lmdb_size.*.pyc %{python3_sitearch}/samba/tests/samba_tool/__pycache__/provision_password_check.*.pyc %{python3_sitearch}/samba/tests/samba_tool/__pycache__/rodc.*.pyc %{python3_sitearch}/samba/tests/samba_tool/__pycache__/schema.*.pyc @@ -2456,18 +2732,24 @@ fi %{python3_sitearch}/samba/tests/samba_tool/__pycache__/visualize_drs.*.pyc %{python3_sitearch}/samba/tests/samba_tool/base.py %{python3_sitearch}/samba/tests/samba_tool/computer.py +%{python3_sitearch}/samba/tests/samba_tool/contact.py %{python3_sitearch}/samba/tests/samba_tool/demote.py %{python3_sitearch}/samba/tests/samba_tool/dnscmd.py +%{python3_sitearch}/samba/tests/samba_tool/drs_clone_dc_data_lmdb_size.py +%{python3_sitearch}/samba/tests/samba_tool/dsacl.py %{python3_sitearch}/samba/tests/samba_tool/forest.py %{python3_sitearch}/samba/tests/samba_tool/fsmo.py %{python3_sitearch}/samba/tests/samba_tool/gpo.py %{python3_sitearch}/samba/tests/samba_tool/group.py %{python3_sitearch}/samba/tests/samba_tool/help.py %{python3_sitearch}/samba/tests/samba_tool/join.py +%{python3_sitearch}/samba/tests/samba_tool/join_lmdb_size.py %{python3_sitearch}/samba/tests/samba_tool/ntacl.py %{python3_sitearch}/samba/tests/samba_tool/ou.py %{python3_sitearch}/samba/tests/samba_tool/passwordsettings.py %{python3_sitearch}/samba/tests/samba_tool/processes.py +%{python3_sitearch}/samba/tests/samba_tool/promote_dc_lmdb_size.py +%{python3_sitearch}/samba/tests/samba_tool/provision_lmdb_size.py %{python3_sitearch}/samba/tests/samba_tool/provision_password_check.py %{python3_sitearch}/samba/tests/samba_tool/rodc.py %{python3_sitearch}/samba/tests/samba_tool/schema.py @@ -2482,6 +2764,7 @@ fi %{python3_sitearch}/samba/tests/samdb.py %{python3_sitearch}/samba/tests/samdb_api.py %{python3_sitearch}/samba/tests/security.py +%{python3_sitearch}/samba/tests/segfault.py %{python3_sitearch}/samba/tests/smb.py %{python3_sitearch}/samba/tests/smbd_base.py %{python3_sitearch}/samba/tests/source.py @@ -2491,6 +2774,7 @@ fi %{python3_sitearch}/samba/tests/upgrade.py %{python3_sitearch}/samba/tests/upgradeprovision.py %{python3_sitearch}/samba/tests/upgradeprovisionneeddc.py +%{python3_sitearch}/samba/tests/usage.py %{python3_sitearch}/samba/tests/xattr.py ### TEST @@ -2531,7 +2815,7 @@ fi %{_sbindir}/winbindd %attr(750,root,wbpriv) %dir /var/lib/samba/winbindd_privileged %{_unitdir}/winbind.service -%{_sysconfdir}/NetworkManager/dispatcher.d/30-winbind +%{_prefix}/lib/NetworkManager %{_mandir}/man8/winbindd.8* %{_mandir}/man8/idmap_*.8* @@ -2581,6 +2865,7 @@ fi # CTDB scripts, no config files # script with executable bit means activated %dir %{_sysconfdir}/ctdb/events +%dir %{_sysconfdir}/ctdb/events/legacy %dir %{_sysconfdir}/ctdb/events/notification %{_sysconfdir}/ctdb/events/notification/README @@ -2619,6 +2904,9 @@ fi %{_libexecdir}/ctdb/smnotify %dir %{_localstatedir}/lib/ctdb/ +%dir %{_localstatedir}/lib/ctdb/persistent +%dir %{_localstatedir}/lib/ctdb/state +%dir %{_localstatedir}/lib/ctdb/volatile %{_mandir}/man1/ctdb.1.gz %{_mandir}/man1/ctdb_diagnostics.1.gz @@ -2709,7 +2997,6 @@ fi %{_libexecdir}/ctdb/tests/sock_io_test %{_libexecdir}/ctdb/tests/srvid_test %{_libexecdir}/ctdb/tests/system_socket_test -%{_libexecdir}/ctdb/tests/test_mutex_raw %{_libexecdir}/ctdb/tests/transaction_loop %{_libexecdir}/ctdb/tests/tunnel_cmd %{_libexecdir}/ctdb/tests/tunnel_test @@ -2871,10 +3158,8 @@ fi %{_datadir}/ctdb/tests/eventscripts/05.system.monitor.007.sh %{_datadir}/ctdb/tests/eventscripts/05.system.monitor.011.sh %{_datadir}/ctdb/tests/eventscripts/05.system.monitor.012.sh -%{_datadir}/ctdb/tests/eventscripts/05.system.monitor.013.sh %{_datadir}/ctdb/tests/eventscripts/05.system.monitor.014.sh %{_datadir}/ctdb/tests/eventscripts/05.system.monitor.015.sh -%{_datadir}/ctdb/tests/eventscripts/05.system.monitor.016.sh %{_datadir}/ctdb/tests/eventscripts/05.system.monitor.017.sh %{_datadir}/ctdb/tests/eventscripts/05.system.monitor.018.sh %{_datadir}/ctdb/tests/eventscripts/06.nfs.releaseip.001.sh @@ -3210,6 +3495,7 @@ fi %{_datadir}/ctdb/tests/simple/80_ctdb_traverse.sh %{_datadir}/ctdb/tests/simple/81_tunnel_ring.sh %{_datadir}/ctdb/tests/simple/90_debug_hung_script.sh +%{_datadir}/ctdb/tests/simple/91_version_check.sh %dir %{_datadir}/ctdb/tests/simple/scripts @@ -3435,16 +3721,61 @@ fi %dir %{_datadir}/ctdb/tests/tool/scripts %{_datadir}/ctdb/tests/tool/scripts/local.sh -%endif # with_clustering_support +#endif with_clustering_support +%endif %changelog +* Thu Feb 13 2020 Isaac Boukris - 4.11.2-13 +- resolves: #1802182 - Fix join using netbios name + +* Wed Jan 29 2020 Andreas Schneider - 4.11.2-12 +- related: #1781232 - Improve debug output of smbclient +- resolves: #1794461 - Do not return bogus inode numbers in + cli_qpathinfo2()/cli_qpathinfo3() for SMB1 +- resolves: #1794442 - Fix segfault in smbd_do_qfilepathinfo() + +* Thu Jan 23 2020 Isaac Boukris - 4.11.2-11 +- resolves: #1778130 - Remove usage of DES encryption types in krb5 + +* Fri Jan 17 2020 Alexander Bokovoy - 4.11.2-10 +- resolves: #1790353 - Fix access check in DsRGetForestTrustInformation +- resolves: #1791209 - Fix CVE-2019-14907 + +* Fri Jan 10 2020 Andreas Schneider - 4.11.2-9 +- resolves: #1785134 - Fix libwbclient manual alternative settings + +* Fri Jan 10 2020 Andreas Schneider - 4.11.2-8 +- resolves: #1781232 - Fix smbclient debug message + +* Thu Dec 12 2019 Andreas Schneider - 4.11.2-7 +- related: #1637861 - Fix trust creation if weak crypto is disallowed + +* Tue Dec 10 2019 Andreas Schneider - 4.11.2-6 +- resolves: #1637861 - Use GnuTLS for crypto + +* Thu Dec 05 2019 Andreas Schneider - 4.11.2-4 +- related: #1754409 - Add patch to avoid overlinking with libnsl and libsocket +- related: #1754409 - Fix permissions for pidl +- related: #1754409 - Fix logrotate script +- related: #1754409 - Add missing README files + +* Mon Dec 02 2019 Andreas Schneider - 4.11.2-3 +- related: #1754409 - Fix pidl packaging + +* Fri Nov 29 2019 Andreas Schneider - 4.11.2-1 +- resolves: #1754409 - Rebase to Samba version 4.11.2 +- resolves: #1776312 - Winbind is not restarted on upgrade +- resolves: #1764469 - Fix CVE-2019-10218 +- resolves: #1746241 - Fix CVE-2019-10197 +- resolves: #1710980 - Add support for KCM ccache in pam_winbind + * Wed Oct 23 2019 Andreas Schneider - 4.10.4-101 - related: #1760824 - Removed additional issues with overlinking * Fri Oct 11 2019 Andreas Schneider - 4.10.4-100 -- resolves: #1760824 - Avoid overlinking with librt and libpthread -- resolves: #1759236 - Fix forest trusts enumeration -- resolves: #1761719 - Fix CUPS username/password authentication with smbspool +- resolves: #1754575 - Avoid overlinking with librt and libpthread +- resolves: #1755440 - Fix forest trusts enumeration +- resolves: #1755445 - Fix CUPS username/password authentication with smbspool * Wed Jun 19 2019 Andreas Schneider - 4.10.4-1 - resolves: #1712378 - Fix smbspool CUPS backend