ctdb-daemon: Use ctdb_parse_node_address() in ctdbd
[samba4-gss.git] / third_party / waf / waflib / extras / dpapi.py
blobb94d4823581898597f71e6c86110fc7049d27643
1 #! /usr/bin/env python
2 # encoding: utf-8
3 # Matt Clarkson, 2012
5 '''
6 DPAPI access library (http://msdn.microsoft.com/en-us/library/ms995355.aspx)
7 This file uses code originally created by Crusher Joe:
8 http://article.gmane.org/gmane.comp.python.ctypes/420
9 And modified by Wayne Koorts:
10 http://stackoverflow.com/questions/463832/using-dpapi-with-python
11 '''
13 from ctypes import windll, byref, cdll, Structure, POINTER, c_char, c_buffer
14 from ctypes.wintypes import DWORD
15 from waflib.Configure import conf
17 LocalFree = windll.kernel32.LocalFree
18 memcpy = cdll.msvcrt.memcpy
19 CryptProtectData = windll.crypt32.CryptProtectData
20 CryptUnprotectData = windll.crypt32.CryptUnprotectData
21 CRYPTPROTECT_UI_FORBIDDEN = 0x01
22 try:
23 extra_entropy = 'cl;ad13 \0al;323kjd #(adl;k$#ajsd'.encode('ascii')
24 except AttributeError:
25 extra_entropy = 'cl;ad13 \0al;323kjd #(adl;k$#ajsd'
27 class DATA_BLOB(Structure):
28 _fields_ = [
29 ('cbData', DWORD),
30 ('pbData', POINTER(c_char))
33 def get_data(blob_out):
34 cbData = int(blob_out.cbData)
35 pbData = blob_out.pbData
36 buffer = c_buffer(cbData)
37 memcpy(buffer, pbData, cbData)
38 LocalFree(pbData)
39 return buffer.raw
41 @conf
42 def dpapi_encrypt_data(self, input_bytes, entropy = extra_entropy):
43 '''
44 Encrypts data and returns byte string
46 :param input_bytes: The data to be encrypted
47 :type input_bytes: String or Bytes
48 :param entropy: Extra entropy to add to the encryption process (optional)
49 :type entropy: String or Bytes
50 '''
51 if not isinstance(input_bytes, bytes) or not isinstance(entropy, bytes):
52 self.fatal('The inputs to dpapi must be bytes')
53 buffer_in = c_buffer(input_bytes, len(input_bytes))
54 buffer_entropy = c_buffer(entropy, len(entropy))
55 blob_in = DATA_BLOB(len(input_bytes), buffer_in)
56 blob_entropy = DATA_BLOB(len(entropy), buffer_entropy)
57 blob_out = DATA_BLOB()
59 if CryptProtectData(byref(blob_in), 'python_data', byref(blob_entropy),
60 None, None, CRYPTPROTECT_UI_FORBIDDEN, byref(blob_out)):
61 return get_data(blob_out)
62 else:
63 self.fatal('Failed to decrypt data')
65 @conf
66 def dpapi_decrypt_data(self, encrypted_bytes, entropy = extra_entropy):
67 '''
68 Decrypts data and returns byte string
70 :param encrypted_bytes: The encrypted data
71 :type encrypted_bytes: Bytes
72 :param entropy: Extra entropy to add to the encryption process (optional)
73 :type entropy: String or Bytes
74 '''
75 if not isinstance(encrypted_bytes, bytes) or not isinstance(entropy, bytes):
76 self.fatal('The inputs to dpapi must be bytes')
77 buffer_in = c_buffer(encrypted_bytes, len(encrypted_bytes))
78 buffer_entropy = c_buffer(entropy, len(entropy))
79 blob_in = DATA_BLOB(len(encrypted_bytes), buffer_in)
80 blob_entropy = DATA_BLOB(len(entropy), buffer_entropy)
81 blob_out = DATA_BLOB()
82 if CryptUnprotectData(byref(blob_in), None, byref(blob_entropy), None,
83 None, CRYPTPROTECT_UI_FORBIDDEN, byref(blob_out)):
84 return get_data(blob_out)
85 else:
86 self.fatal('Failed to decrypt data')