Skip to content

Commit 12bf65d

Browse files
committed
Remove constrains to AttributeCount and Attribute
This is a cleanup commit. The code is still not fully functional.
1 parent b8f90a6 commit 12bf65d

File tree

3 files changed

+31
-45
lines changed

3 files changed

+31
-45
lines changed

win32ctypes/core/ctypes/_authentication.py

Lines changed: 27 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,8 @@
1010
from ctypes.wintypes import (
1111
BOOL, DWORD, FILETIME, LPCWSTR)
1212

13-
from win32ctypes.core.compat import is_text
1413
from ._common import LPBYTE, _PyBytes_FromStringAndSize
1514
from ._util import function_factory, check_zero_factory, dlls
16-
from ._nl_support import _GetACP
17-
18-
19-
SUPPORTED_CREDKEYS = set((
20-
u'Type', u'TargetName', u'Persist',
21-
u'UserName', u'Comment', u'CredentialBlob'))
2215

2316

2417
class CREDENTIAL(Structure):
@@ -31,68 +24,58 @@ class CREDENTIAL(Structure):
3124
("CredentialBlobSize", DWORD),
3225
("CredentialBlob", LPBYTE),
3326
("Persist", DWORD),
34-
("_DO_NOT_USE_AttributeCount", DWORD),
35-
("__DO_NOT_USE_Attribute", c_void_p),
27+
("AttributeCount", DWORD),
28+
("Attribute", c_void_p),
3629
("TargetAlias", c_wchar_p),
3730
("UserName", c_wchar_p)]
3831

3932
@classmethod
40-
def fromdict(cls, credential, flags=0):
41-
unsupported = set(credential.keys()) - SUPPORTED_CREDKEYS
42-
if len(unsupported):
43-
raise ValueError("Unsupported keys: {0}".format(unsupported))
44-
if flags != 0:
45-
raise ValueError("flag != 0 not yet supported")
46-
33+
def fromdict(cls, credential):
4734
c_creds = cls()
4835
c_pcreds = PCREDENTIAL(c_creds)
4936

5037
# zero-out memory
5138
ctypes.memset(c_pcreds, 0, ctypes.sizeof(c_creds))
5239

53-
for key in SUPPORTED_CREDKEYS:
54-
if key in credential:
55-
if key != 'CredentialBlob':
56-
setattr(c_creds, key, credential[key])
57-
else:
58-
blob = make_unicode(credential['CredentialBlob'])
59-
blob_data = ctypes.create_unicode_buffer(blob)
60-
# Create_unicode_buffer adds a NULL at the end of the
61-
# string we do not want that.
62-
c_creds.CredentialBlobSize = \
63-
ctypes.sizeof(blob_data) - \
64-
ctypes.sizeof(ctypes.c_wchar)
65-
c_creds.CredentialBlob = ctypes.cast(blob_data, LPBYTE)
40+
for key in credential:
41+
if key == 'CredentialBlob':
42+
blob_data, blob_size = _make_blob(credential['CredentialBlob'])
43+
c_creds.CredentialBlob = ctypes.cast(blob_data, LPBYTE)
44+
c_creds.CredentialBlobSize = blob_size
45+
else:
46+
setattr(c_creds, key, credential[key])
6647
return c_creds
6748

6849

6950
PCREDENTIAL = POINTER(CREDENTIAL)
7051

7152

72-
def make_unicode(password):
73-
""" Convert the input string to unicode.
74-
75-
"""
76-
if is_text(password):
77-
return password
78-
else:
79-
code_page = _GetACP()
80-
return password.decode(encoding=str(code_page), errors='strict')
81-
82-
8353
def credential2dict(creds):
8454
credential = {}
85-
for key in SUPPORTED_CREDKEYS:
86-
if key != u'CredentialBlob':
87-
credential[key] = getattr(creds, key)
88-
else:
55+
for key, type_ in CREDENTIAL._fields_:
56+
if key == u'CredentialBlob':
8957
blob = _PyBytes_FromStringAndSize(
9058
cast(creds.CredentialBlob, c_char_p),
9159
creds.CredentialBlobSize)
9260
credential[u'CredentialBlob'] = blob
61+
else:
62+
credential[key] = getattr(creds, key)
9363
return credential
9464

9565

66+
def _make_blob(data):
67+
""" Convert a string to credential compatible blob dict values
68+
69+
"""
70+
blob_data = ctypes.create_unicode_buffer(data)
71+
# Create_unicode_buffer adds a NULL at the end of the
72+
# string we do not want that.
73+
blob_size = (
74+
ctypes.sizeof(blob_data) - ctypes.sizeof(ctypes.c_wchar))
75+
blob_pointer = ctypes.cast(blob_data, LPBYTE)
76+
return blob_pointer, blob_size
77+
78+
9679
_CredWrite = function_factory(
9780
dlls.advapi32.CredWriteW,
9881
[PCREDENTIAL, DWORD],

win32ctypes/pywin32/win32cred.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def CredWrite(Credential, Flags=0):
2828
``CRED_PRESERVE_CREDENTIAL_BLOB`` or 0. Default is 0.
2929
3030
"""
31-
c_creds = _authentication.CREDENTIAL.fromdict(Credential, Flags)
31+
c_creds = _authentication.CREDENTIAL.fromdict(Credential)
3232
c_pcreds = _authentication.PCREDENTIAL(c_creds)
3333
with _pywin32error():
3434
_authentication._CredWrite(c_pcreds, 0)

win32ctypes/tests/test_win32cred.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ def test_write_to_pywin32(self):
5252
res = win32cred.CredRead(
5353
TargetName=target, Type=CRED_TYPE_GENERIC)
5454

55+
# XXX: the fact that we have to decode the password when reading, but
56+
# not encode when writing is a bit strange, but that's what pywin32
57+
# seems to do as well, and we try to be backward compatible here.
5558
self.assertEqual(res["Type"], CRED_TYPE_GENERIC)
5659
self.assertEqual(res["UserName"], username)
5760
self.assertEqual(res["TargetName"], target)

0 commit comments

Comments
 (0)