From 2ffc638cf996c213ba7c2d1b5969f1073e7d639c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 28 Jan 2016 13:44:33 +0100 Subject: [PATCH 1/6] python:samba: add a generic string_to_byte_array() helper function We should avoid implementing this again and again. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11699 Signed-off-by: Stefan Metzmacher --- python/samba/__init__.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/python/samba/__init__.py b/python/samba/__init__.py index b04e83c..59b6ebf 100644 --- a/python/samba/__init__.py +++ b/python/samba/__init__.py @@ -362,6 +362,14 @@ def dn_from_dns_name(dnsdomain): def current_unix_time(): return int(time.time()) +def string_to_byte_array(string): + blob = [0] * len(string) + + for i in range(len(string)): + blob[i] = ord(string[i]) + + return blob + import _glue version = _glue.version interface_ips = _glue.interface_ips -- 1.9.1 From db5b89853c196790a4b0590a4a6ebe3a652b2fd3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 28 Jan 2016 13:52:44 +0100 Subject: [PATCH 2/6] python:samba: add a generic arcfour_encrypt() helper function This works with Crypto.Cipher.ARC4 (from python*-crypto) and fallback to M2Crypto.RC4.RC4 (from [python*-]m2crypto). BUG: https://bugzilla.samba.org/show_bug.cgi?id=11699 Signed-off-by: Stefan Metzmacher --- python/samba/__init__.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/python/samba/__init__.py b/python/samba/__init__.py index 59b6ebf..7cfbc4c 100644 --- a/python/samba/__init__.py +++ b/python/samba/__init__.py @@ -370,6 +370,22 @@ def string_to_byte_array(string): return blob +def arcfour_encrypt(key, data): + try: + from Crypto.Cipher import ARC4 + c = ARC4.new(key) + return c.encrypt(data) + except ImportError as e: + pass + try: + from M2Crypto.RC4 import RC4 + c = RC4(key) + return c.update(data) + except ImportError as e: + pass + raise Exception("arcfour_encrypt() requires " + + "python*-crypto or python*-m2crypto or m2crypto") + import _glue version = _glue.version interface_ips = _glue.interface_ips -- 1.9.1 From 2e7d699fe23fd3a540c266c5adfecdd91387307f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 28 Jan 2016 14:00:38 +0100 Subject: [PATCH 3/6] python:samba/join.py: make use of the generic arcfour_encrypt() and string_to_byte_array() functions BUG: https://bugzilla.samba.org/show_bug.cgi?id=11699 Signed-off-by: Stefan Metzmacher --- python/samba/join.py | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/python/samba/join.py b/python/samba/join.py index cdfe452..6df337c 100644 --- a/python/samba/join.py +++ b/python/samba/join.py @@ -20,7 +20,7 @@ from samba.auth import system_session from samba.samdb import SamDB -from samba import gensec, Ldb, drs_utils +from samba import gensec, Ldb, drs_utils, arcfour_encrypt, string_to_byte_array import ldb, samba, sys, uuid from samba.ndr import ndr_pack from samba.dcerpc import security, drsuapi, misc, nbt, lsa, drsblobs @@ -963,19 +963,6 @@ class dc_join(object): def join_setup_trusts(ctx): """provision the local SAM.""" - def arcfour_encrypt(key, data): - from Crypto.Cipher import ARC4 - c = ARC4.new(key) - return c.encrypt(data) - - def string_to_array(string): - blob = [0] * len(string) - - for i in range(len(string)): - blob[i] = ord(string[i]) - - return blob - print "Setup domain trusts with server %s" % ctx.server binding_options = "" # why doesn't signing work here? w2k8r2 claims no session key lsaconn = lsa.lsarpc("ncacn_np:%s[%s]" % (ctx.server, binding_options), @@ -1005,7 +992,7 @@ class dc_join(object): except RuntimeError: pass - password_blob = string_to_array(ctx.trustdom_pass.encode('utf-16-le')) + password_blob = string_to_byte_array(ctx.trustdom_pass.encode('utf-16-le')) clear_value = drsblobs.AuthInfoClear() clear_value.size = len(password_blob) @@ -1041,7 +1028,7 @@ class dc_join(object): auth_blob = lsa.DATA_BUF2() auth_blob.size = len(encrypted_trustpass) - auth_blob.data = string_to_array(encrypted_trustpass) + auth_blob.data = string_to_byte_array(encrypted_trustpass) auth_info = lsa.TrustDomainInfoAuthInfoInternal() auth_info.auth_blob = auth_blob -- 1.9.1 From d4ced2e62ccc2f101f190b3f7a3fb60d531871f0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 28 Jan 2016 14:00:38 +0100 Subject: [PATCH 4/6] python:samba/netcmd/domain: make use of the generic arcfour_encrypt() and string_to_byte_array() functions BUG: https://bugzilla.samba.org/show_bug.cgi?id=11699 Signed-off-by: Stefan Metzmacher --- python/samba/netcmd/domain.py | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/python/samba/netcmd/domain.py b/python/samba/netcmd/domain.py index 8802803..6357144 100644 --- a/python/samba/netcmd/domain.py +++ b/python/samba/netcmd/domain.py @@ -60,7 +60,7 @@ from samba.upgrade import upgrade_from_samba3 from samba.drs_utils import ( sendDsReplicaSync, drsuapi_connect, drsException, sendRemoveDsServer) -from samba import remove_dc +from samba import remove_dc, arcfour_encrypt, string_to_byte_array from samba.dsdb import ( DS_DOMAIN_FUNCTION_2000, @@ -2230,24 +2230,16 @@ class cmd_domain_trust_create(DomainTrustCommand): password = None self.outf.write("Sorry, passwords do not match.\n") - def string_to_array(string): - blob = [0] * len(string) - - for i in range(len(string)): - blob[i] = ord(string[i]) - - return blob - incoming_secret = None outgoing_secret = None remote_policy_access = lsa.LSA_POLICY_VIEW_LOCAL_INFORMATION if create_location == "local": if local_trust_info.trust_direction & lsa.LSA_TRUST_DIRECTION_INBOUND: incoming_password = get_password("Incoming Trust") - incoming_secret = string_to_array(incoming_password.encode('utf-16-le')) + incoming_secret = string_to_byte_array(incoming_password.encode('utf-16-le')) if local_trust_info.trust_direction & lsa.LSA_TRUST_DIRECTION_OUTBOUND: outgoing_password = get_password("Outgoing Trust") - outgoing_secret = string_to_array(outgoing_password.encode('utf-16-le')) + outgoing_secret = string_to_byte_array(outgoing_password.encode('utf-16-le')) remote_trust_info = None else: @@ -2272,7 +2264,7 @@ class cmd_domain_trust_create(DomainTrustCommand): # # We can remove this once our client libraries # support using the correct NTHASH. - return string_to_array(pw1.encode('utf-16-le')) + return string_to_byte_array(pw1.encode('utf-16-le')) # We mix characters from generate_random_password # with random numbers from random.randint() @@ -2425,11 +2417,6 @@ class cmd_domain_trust_create(DomainTrustCommand): except RuntimeError as error: raise self.RemoteRuntimeError(self, error, "failed to get netlogon dc info") - def arcfour_encrypt(key, data): - from Crypto.Cipher import ARC4 - c = ARC4.new(key) - return c.encrypt(data) - def generate_AuthInOutBlob(secret, update_time): if secret is None: blob = drsblobs.trustAuthInOutBlob() @@ -2473,7 +2460,7 @@ class cmd_domain_trust_create(DomainTrustCommand): auth_blob = lsa.DATA_BUF2() auth_blob.size = len(encrypted_trustpass) - auth_blob.data = string_to_array(encrypted_trustpass) + auth_blob.data = string_to_byte_array(encrypted_trustpass) auth_info = lsa.TrustDomainInfoAuthInfoInternal() auth_info.auth_blob = auth_blob -- 1.9.1 From e04720ac49d3ae6d44f4d15550a58f239ff50a21 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 28 Jan 2016 14:00:38 +0100 Subject: [PATCH 5/6] s4:scripting/devel: make use of the generic arcfour_encrypt() and string_to_byte_array() functions BUG: https://bugzilla.samba.org/show_bug.cgi?id=11699 Signed-off-by: Stefan Metzmacher --- source4/scripting/devel/createtrust | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/source4/scripting/devel/createtrust b/source4/scripting/devel/createtrust index 7f1ba33..6c0de1c 100755 --- a/source4/scripting/devel/createtrust +++ b/source4/scripting/devel/createtrust @@ -11,21 +11,9 @@ import samba import samba.getopt as options from samba.dcerpc import lsa, security, drsblobs from samba.ndr import ndr_pack +from samba import arcfour_encrypt, string_to_byte_array import random -def arcfour_encrypt(key, data): - from Crypto.Cipher import ARC4 - c = ARC4.new(key) - return c.encrypt(data) - -def string_to_array(string): - blob = [0] * len(string) - - for i in range(len(string)): - blob[i] = ord(string[i]) - - return blob - ########### main code ########### if __name__ == "__main__": parser = OptionParser("createtrust [options] server") @@ -73,7 +61,7 @@ if __name__ == "__main__": info.trust_type = lsa.LSA_TRUST_TYPE_UPLEVEL info.trust_attributes = lsa.LSA_TRUST_ATTRIBUTE_WITHIN_FOREST - password_blob = string_to_array("password".encode('utf-16-le')) + password_blob = string_to_byte_array("password".encode('utf-16-le')) clear_value = drsblobs.AuthInfoClear() clear_value.size = len(password_blob) @@ -123,7 +111,7 @@ if __name__ == "__main__": auth_blob = lsa.DATA_BUF2() auth_blob.size = len(encrypted_trustpass) - auth_blob.data = string_to_array(encrypted_trustpass) + auth_blob.data = string_to_byte_array(encrypted_trustpass) auth_info = lsa.TrustDomainInfoAuthInfoInternal() auth_info.auth_blob = auth_blob -- 1.9.1 From f2bb68833c57ee6e51ed4718b74b3d101691cb68 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 28 Jan 2016 15:10:00 +0100 Subject: [PATCH 6/6] python:tests/core: add tests for arcfour_encrypt() and string_to_byte_array() BUG: https://bugzilla.samba.org/show_bug.cgi?id=11699 Signed-off-by: Stefan Metzmacher --- python/samba/tests/core.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/python/samba/tests/core.py b/python/samba/tests/core.py index 8206e68..9dbaff1 100644 --- a/python/samba/tests/core.py +++ b/python/samba/tests/core.py @@ -20,6 +20,7 @@ import ldb import os import samba +from samba import arcfour_encrypt, string_to_byte_array from samba.tests import TestCase, TestCaseInTempDir class SubstituteVarTestCase(TestCase): @@ -48,6 +49,21 @@ class SubstituteVarTestCase(TestCase): self.assertRaises(Exception, samba.check_all_substituted, "Not subsituted: ${FOOBAR}") +class ArcfourTestCase(TestCase): + + def test_arcfour_direct(self): + key = '12345678' + plain = 'abcdefghi' + crypt_expected = '\xda\x91Z\xb0l\xd7\xb9\xcf\x99' + crypt_calculated = arcfour_encrypt(key, plain) + self.assertEquals(crypt_expected, crypt_calculated) + +class StringToByteArrayTestCase(TestCase): + + def test_byte_array(self): + expected = [218, 145, 90, 176, 108, 215, 185, 207, 153] + calculated = string_to_byte_array('\xda\x91Z\xb0l\xd7\xb9\xcf\x99') + self.assertEquals(expected, calculated) class LdbExtensionTests(TestCaseInTempDir): -- 1.9.1