Author: spetreolle
Date: Sat Apr 27 12:37:33 2013
New Revision: 58870
URL:
http://svn.reactos.org/svn/reactos?rev=58870&view=rev
Log:
Import CredMarshalCredential and CredIsMarshaledCredential from wine.
ROSTESTS-97 #resolve
Modified:
trunk/reactos/dll/win32/advapi32/advapi32.spec
trunk/reactos/dll/win32/advapi32/sec/cred.c
Modified: trunk/reactos/dll/win32/advapi32/advapi32.spec
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/advapi32/advapi3…
==============================================================================
--- trunk/reactos/dll/win32/advapi32/advapi32.spec [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/advapi32/advapi32.spec [iso-8859-1] Sat Apr 27 12:37:33 2013
@@ -113,10 +113,10 @@
@ stdcall CredGetSessionTypes(long ptr)
@ stub CredGetTargetInfoA
@ stub CredGetTargetInfoW
-@ stub CredIsMarshaledCredentialA
-@ stub CredIsMarshaledCredentialW
-@ stub CredMarshalCredentialA
-@ stub CredMarshalCredentialW
+@ stdcall CredIsMarshaledCredentialA(str)
+@ stdcall CredIsMarshaledCredentialW(wstr)
+@ stdcall CredMarshalCredentialA(long ptr str)
+@ stdcall CredMarshalCredentialW(long ptr wstr)
@ stub CredProfileLoaded
@ stdcall CredReadA(str long long ptr)
@ stdcall CredReadDomainCredentialsA(ptr long ptr ptr)
Modified: trunk/reactos/dll/win32/advapi32/sec/cred.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/advapi32/sec/cre…
==============================================================================
--- trunk/reactos/dll/win32/advapi32/sec/cred.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/advapi32/sec/cred.c [iso-8859-1] Sat Apr 27 12:37:33 2013
@@ -1896,6 +1896,120 @@
return TRUE;
}
+/******************************************************************************
+ * CredMarshalCredentialA [ADVAPI32.@]
+ */
+BOOL WINAPI CredMarshalCredentialA( CRED_MARSHAL_TYPE type, PVOID cred, LPSTR *out )
+{
+ BOOL ret;
+ WCHAR *outW;
+
+ TRACE("%u, %p, %p\n", type, cred, out);
+
+ if ((ret = CredMarshalCredentialW( type, cred, &outW )))
+ {
+ int len = WideCharToMultiByte( CP_ACP, 0, outW, -1, NULL, 0, NULL, NULL );
+ if (!(*out = HeapAlloc( GetProcessHeap(), 0, len )))
+ {
+ HeapFree( GetProcessHeap(), 0, outW );
+ return FALSE;
+ }
+ WideCharToMultiByte( CP_ACP, 0, outW, -1, *out, len, NULL, NULL );
+ HeapFree( GetProcessHeap(), 0, outW );
+ }
+ return ret;
+}
+
+static UINT cred_encode( const char *bin, unsigned int len, WCHAR *cred )
+{
+ static char enc[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789#-";
+ UINT n = 0, x;
+
+ while (len > 0)
+ {
+ cred[n++] = enc[bin[0] & 0x3f];
+ x = (bin[0] & 0xc0) >> 6;
+ if (len == 1)
+ {
+ cred[n++] = enc[x];
+ break;
+ }
+ cred[n++] = enc[((bin[1] & 0xf) << 2) | x];
+ x = (bin[1] & 0xf0) >> 4;
+ if (len == 2)
+ {
+ cred[n++] = enc[x];
+ break;
+ }
+ cred[n++] = enc[((bin[2] & 0x3) << 4) | x];
+ cred[n++] = enc[(bin[2] & 0xfc) >> 2];
+ bin += 3;
+ len -= 3;
+ }
+ return n;
+}
+
+/******************************************************************************
+ * CredMarshalCredentialW [ADVAPI32.@]
+ */
+BOOL WINAPI CredMarshalCredentialW( CRED_MARSHAL_TYPE type, PVOID cred, LPWSTR *out )
+{
+ CERT_CREDENTIAL_INFO *cert = cred;
+ USERNAME_TARGET_CREDENTIAL_INFO *target = cred;
+ DWORD len, size;
+ WCHAR *p;
+
+ TRACE("%u, %p, %p\n", type, cred, out);
+
+ if (!cred || (type == CertCredential && cert->cbSize < sizeof(*cert))
||
+ (type != CertCredential && type != UsernameTargetCredential &&
type != BinaryBlobCredential) ||
+ (type == UsernameTargetCredential && (!target->UserName ||
!target->UserName[0])))
+ {
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return FALSE;
+ }
+ switch (type)
+ {
+ case CertCredential:
+ {
+ char hash[CERT_HASH_LENGTH + 2];
+
+ memcpy( hash, cert->rgbHashOfCert, sizeof(cert->rgbHashOfCert) );
+ memset( hash + sizeof(cert->rgbHashOfCert), 0, sizeof(hash) -
sizeof(cert->rgbHashOfCert) );
+
+ size = sizeof(hash) * 4 / 3;
+ if (!(p = HeapAlloc( GetProcessHeap(), 0, (size + 4) * sizeof(WCHAR) ))) return
FALSE;
+ p[0] = '@';
+ p[1] = '@';
+ p[2] = 'A' + type;
+ len = cred_encode( (const char *)hash, sizeof(hash), p + 3 );
+ p[len] = 0;
+ break;
+ }
+ case UsernameTargetCredential:
+ {
+ len = strlenW( target->UserName );
+ size = (sizeof(DWORD) + len * sizeof(WCHAR) + 2) * 4 / 3;
+ if (!(p = HeapAlloc( GetProcessHeap(), 0, (size + 4) * sizeof(WCHAR) ))) return
FALSE;
+ p[0] = '@';
+ p[1] = '@';
+ p[2] = 'A' + type;
+ size = len * sizeof(WCHAR);
+ len = cred_encode( (const char *)&size, sizeof(DWORD), p + 3 );
+ len += cred_encode( (const char *)target->UserName, size, p + 3 + len );
+ p[len + 3] = 0;
+ break;
+ }
+ case BinaryBlobCredential:
+ FIXME("BinaryBlobCredential not implemented\n");
+ return FALSE;
+ default:
+ return FALSE;
+ }
+ *out = p;
+ return TRUE;
+}
+
BOOL
WINAPI
CredWriteDomainCredentialsW(PCREDENTIAL_TARGET_INFORMATIONW TargetInfo,
@@ -1916,22 +2030,218 @@
return FALSE;
}
-BOOL
-WINAPI
-CredUnmarshalCredentialW(LPCWSTR MarshaledCredential,
- PCRED_MARSHAL_TYPE CredType,
- PVOID *Credential)
-{
- WARN("Not implemented\n");
+static inline char char_decode( WCHAR c )
+{
+ if (c >= 'A' && c <= 'Z') return c - 'A';
+ if (c >= 'a' && c <= 'z') return c - 'a' + 26;
+ if (c >= '0' && c <= '9') return c - '0' + 52;
+ if (c == '#') return 62;
+ if (c == '-') return 63;
+ return 64;
+}
+
+static BOOL cred_decode( const WCHAR *cred, unsigned int len, char *buf )
+{
+ unsigned int i = 0;
+ char c0, c1, c2, c3;
+ const WCHAR *p = cred;
+
+ while (len >= 4)
+ {
+ if ((c0 = char_decode( p[0] )) > 63) return FALSE;
+ if ((c1 = char_decode( p[1] )) > 63) return FALSE;
+ if ((c2 = char_decode( p[2] )) > 63) return FALSE;
+ if ((c3 = char_decode( p[3] )) > 63) return FALSE;
+
+ buf[i + 0] = (c1 << 6) | c0;
+ buf[i + 1] = (c2 << 4) | (c1 >> 2);
+ buf[i + 2] = (c3 << 2) | (c2 >> 4);
+ len -= 4;
+ i += 3;
+ p += 4;
+ }
+ if (len == 3)
+ {
+ if ((c0 = char_decode( p[0] )) > 63) return FALSE;
+ if ((c1 = char_decode( p[1] )) > 63) return FALSE;
+ if ((c2 = char_decode( p[2] )) > 63) return FALSE;
+
+ buf[i + 0] = (c1 << 6) | c0;
+ buf[i + 1] = (c2 << 4) | (c1 >> 2);
+ buf[i + 2] = c2 >> 4;
+ }
+ else if (len == 2)
+ {
+ if ((c0 = char_decode( p[0] )) > 63) return FALSE;
+ if ((c1 = char_decode( p[1] )) > 63) return FALSE;
+
+ buf[i + 0] = (c1 << 6) | c0;
+ buf[i + 1] = c1 >> 2;
+ buf[i + 2] = 0;
+ }
+ else if (len == 1)
+ {
+ if ((c0 = char_decode( p[0] )) > 63) return FALSE;
+
+ buf[i + 0] = c0;
+ buf[i + 1] = 0;
+ buf[i + 2] = 0;
+ }
+ return TRUE;
+}
+
+/******************************************************************************
+ * CredUnmarshalCredentialW [ADVAPI32.@]
+ */
+BOOL WINAPI CredUnmarshalCredentialW( LPCWSTR cred, PCRED_MARSHAL_TYPE type, PVOID *out
)
+{
+ unsigned int len, buflen;
+
+ TRACE("%s, %p, %p\n", debugstr_w(cred), type, out);
+
+ if (!cred || cred[0] != '@' || cred[1] != '@' || !cred[2] ||
!cred[3])
+ {
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return FALSE;
+ }
+ len = strlenW( cred + 3 );
+ switch (cred[2] - 'A')
+ {
+ case CertCredential:
+ {
+ char hash[CERT_HASH_LENGTH + 2];
+ CERT_CREDENTIAL_INFO *cert;
+
+ if (len != 27 || !cred_decode( cred + 3, len, hash ))
+ {
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return FALSE;
+ }
+ if (!(cert = HeapAlloc( GetProcessHeap(), 0, sizeof(*cert) ))) return FALSE;
+ memcpy( cert->rgbHashOfCert, hash, sizeof(cert->rgbHashOfCert) );
+ cert->cbSize = sizeof(*cert);
+ *type = CertCredential;
+ *out = cert;
+ break;
+ }
+ case UsernameTargetCredential:
+ {
+ USERNAME_TARGET_CREDENTIAL_INFO *target;
+ ULONGLONG size = 0;
+
+ if (len < 9 || !cred_decode( cred + 3, 6, (char *)&size ) ||
+ !size || size % sizeof(WCHAR) || size > INT_MAX)
+ {
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return FALSE;
+ }
+ buflen = sizeof(*target) + size + sizeof(WCHAR);
+ if (!(target = HeapAlloc( GetProcessHeap(), 0, buflen ))) return FALSE;
+ if (!cred_decode( cred + 9, len - 6, (char *)(target + 1) ))
+ {
+ HeapFree( GetProcessHeap(), 0, target );
+ return FALSE;
+ }
+ target->UserName = (WCHAR *)(target + 1);
+ target->UserName[size / sizeof(WCHAR)] = 0;
+ *type = UsernameTargetCredential;
+ *out = target;
+ break;
+ }
+ case BinaryBlobCredential:
+ FIXME("BinaryBlobCredential not implemented\n");
+ return FALSE;
+ default:
+ WARN("unhandled type %u\n", cred[2] - 'A');
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/******************************************************************************
+ * CredUnmarshalCredentialA [ADVAPI32.@]
+ */
+BOOL WINAPI CredUnmarshalCredentialA( LPCSTR cred, PCRED_MARSHAL_TYPE type, PVOID *out )
+{
+ BOOL ret;
+ WCHAR *credW = NULL;
+
+ TRACE("%s, %p, %p\n", debugstr_a(cred), type, out);
+
+ if (cred)
+ {
+ int len = MultiByteToWideChar( CP_ACP, 0, cred, -1, NULL, 0 );
+ if (!(credW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return
FALSE;
+ MultiByteToWideChar( CP_ACP, 0, cred, -1, credW, len );
+ }
+ ret = CredUnmarshalCredentialW( credW, type, out );
+ HeapFree( GetProcessHeap(), 0, credW );
+ return ret;
+}
+
+
+/******************************************************************************
+ * CredIsMarshaledCredentialW [ADVAPI32.@]
+ *
+ * Check, if the name parameter is a marshaled credential, hash or binary blob
+ *
+ * PARAMS
+ * name the name to check
+ *
+ * RETURNS
+ * TRUE: the name parameter is a marshaled credential, hash or binary blob
+ * FALSE: the name is a plain username
+ */
+BOOL WINAPI CredIsMarshaledCredentialW(LPCWSTR name)
+{
+ TRACE("(%s)\n", debugstr_w(name));
+
+ if (name && name[0] == '@' && name[1] == '@'
&& name[2] > 'A' && name[3])
+ {
+ char hash[CERT_HASH_LENGTH + 2];
+ int len = strlenW(name + 3 );
+ DWORD size;
+
+ if ((name[2] - 'A') == CertCredential && (len == 27) &&
cred_decode(name + 3, len, hash))
+ return TRUE;
+
+ if (((name[2] - 'A') == UsernameTargetCredential) &&
+ (len >= 9) && cred_decode(name + 3, 6, (char *)&size)
&& size)
+ return TRUE;
+
+ if ((name[2] - 'A') == BinaryBlobCredential)
+ FIXME("BinaryBlobCredential not checked\n");
+
+ if ((name[2] - 'A') > BinaryBlobCredential)
+ TRACE("unknown type: %d\n", (name[2] - 'A'));
+ }
+
+ SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
-BOOL
-WINAPI
-CredUnmarshalCredentialA(LPCSTR MarshaledCredential,
- PCRED_MARSHAL_TYPE CredType,
- PVOID *Credential)
-{
- WARN("Not implemented\n");
- return FALSE;
-}
+/******************************************************************************
+ * CredIsMarshaledCredentialA [ADVAPI32.@]
+ *
+ * See CredIsMarshaledCredentialW
+ *
+ */
+BOOL WINAPI CredIsMarshaledCredentialA(LPCSTR name)
+{
+ LPWSTR nameW = NULL;
+ BOOL res;
+ int len;
+
+ TRACE("(%s)\n", debugstr_a(name));
+
+ if (name)
+ {
+ len = MultiByteToWideChar(CP_ACP, 0, name, -1, NULL, 0);
+ nameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, name, -1, nameW, len);
+ }
+
+ res = CredIsMarshaledCredentialW(nameW);
+ HeapFree(GetProcessHeap(), 0, nameW);
+ return res;
+}