diff --git a/dlls/secur32/secur32.c b/dlls/secur32/secur32.c index 867fa2c818e..1605c7fad8a 100644 --- a/dlls/secur32/secur32.c +++ b/dlls/secur32/secur32.c @@ -36,6 +36,7 @@ #include "wine/list.h" #include "wine/debug.h" +#include "wine/unicode.h" WINE_DEFAULT_DEBUG_CHANNEL(secur32); @@ -1167,6 +1168,111 @@ BOOLEAN WINAPI TranslateNameW( return FALSE; } +/*********************************************************************** + * SspiEncodeAuthIdentityAsStrings (SECUR32.0) + */ +SECURITY_STATUS SEC_ENTRY SspiEncodeAuthIdentityAsStrings( + PSEC_WINNT_AUTH_IDENTITY_OPAQUE opaque_id, PCWSTR *username, + PCWSTR *domainname, PCWSTR *creds ) +{ + SEC_WINNT_AUTH_IDENTITY_W *id = (SEC_WINNT_AUTH_IDENTITY_W *)opaque_id; + + FIXME("%p %p %p %p\n", opaque_id, username, domainname, creds); + + *username = SECUR32_strdupW( id->User ); + *domainname = SECUR32_strdupW( id->Domain ); + *creds = SECUR32_strdupW( id->Password ); + + return SEC_E_OK; +} + +/*********************************************************************** + * SspiEncodeStringsAsAuthIdentity (SECUR32.0) + */ +SECURITY_STATUS SEC_ENTRY SspiEncodeStringsAsAuthIdentity( + PCWSTR username, PCWSTR domainname, PCWSTR creds, + PSEC_WINNT_AUTH_IDENTITY_OPAQUE *opaque_id ) +{ + SEC_WINNT_AUTH_IDENTITY_W *id; + DWORD len_username = 0, len_domainname = 0, len_password = 0, size; + WCHAR *ptr; + + FIXME( "%s %s %s %p\n", debugstr_w(username), debugstr_w(domainname), + debugstr_w(creds), opaque_id ); + + if (!username && !domainname && !creds) return SEC_E_INVALID_TOKEN; + + if (username) len_username = strlenW( username ); + if (domainname) len_domainname = strlenW( domainname ); + if (creds) len_password = strlenW( creds ); + + size = sizeof(*id); + if (username) size += (len_username + 1) * sizeof(WCHAR); + if (domainname) size += (len_domainname + 1) * sizeof(WCHAR); + if (creds) size += (len_password + 1) * sizeof(WCHAR); + if (!(id = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size ))) return ERROR_OUTOFMEMORY; + ptr = (WCHAR *)(id + 1); + + if (username) + { + memcpy( ptr, username, (len_username + 1) * sizeof(WCHAR) ); + id->User = ptr; + id->UserLength = len_username; + ptr += len_username + 1; + } + if (domainname) + { + memcpy( ptr, domainname, (len_domainname + 1) * sizeof(WCHAR) ); + id->Domain = ptr; + id->DomainLength = len_domainname; + ptr += len_domainname + 1; + } + if (creds) + { + memcpy( ptr, creds, (len_password + 1) * sizeof(WCHAR) ); + id->Password = ptr; + id->PasswordLength = len_password; + } + + *opaque_id = id; + return SEC_E_OK; +} + +/*********************************************************************** + * SspiFreeAuthIdentity (SECUR32.0) + */ +void SEC_ENTRY SspiFreeAuthIdentity( PSEC_WINNT_AUTH_IDENTITY_OPAQUE opaque_id ) +{ + + TRACE( "%p\n", opaque_id ); + HeapFree( GetProcessHeap(), 0, opaque_id ); +} + +/*********************************************************************** + * SspiLocalFree (SECUR32.0) + */ +void SEC_ENTRY SspiLocalFree( void *ptr ) +{ + TRACE( "%p\n", ptr ); + HeapFree( GetProcessHeap(), 0, ptr ); +} + +/*********************************************************************** + * SspiZeroAuthIdentity (SECUR32.0) + */ +void SEC_ENTRY SspiZeroAuthIdentity( PSEC_WINNT_AUTH_IDENTITY_OPAQUE opaque_id ) +{ + SEC_WINNT_AUTH_IDENTITY_W *id = (SEC_WINNT_AUTH_IDENTITY_W *)opaque_id; + + TRACE( "%p\n", opaque_id ); + + if (!id) return; + if (id->User) memset( id->User, 0, id->UserLength * sizeof(WCHAR) ); + if (id->Domain) memset( id->Domain, 0, id->DomainLength * sizeof(WCHAR) ); + if (id->Password) memset( id->Password, 0, id->PasswordLength * sizeof(WCHAR) ); + memset( id, 0, sizeof(*id) ); +} + /*********************************************************************** * DllMain (SECUR32.0) */ diff --git a/dlls/secur32/secur32.spec b/dlls/secur32/secur32.spec index 51182585c62..cccc0345237 100644 --- a/dlls/secur32/secur32.spec +++ b/dlls/secur32/secur32.spec @@ -69,6 +69,11 @@ @ stub SecpTranslateNameEx @ stdcall SetContextAttributesA(ptr long ptr long) @ stdcall SetContextAttributesW(ptr long ptr long) +@ stdcall SspiEncodeAuthIdentityAsStrings(ptr ptr ptr ptr) +@ stdcall SspiEncodeStringsAsAuthIdentity(wstr wstr wstr ptr) +@ stdcall SspiFreeAuthIdentity(ptr) +@ stdcall SspiLocalFree(ptr) +@ stdcall SspiZeroAuthIdentity(ptr) @ stdcall TranslateNameA(str long long ptr ptr) @ stdcall TranslateNameW(wstr long long ptr ptr) @ stdcall UnsealMessage(ptr ptr long ptr) DecryptMessage diff --git a/dlls/secur32/tests/secur32.c b/dlls/secur32/tests/secur32.c index 6e67784ce40..97944d1089d 100644 --- a/dlls/secur32/tests/secur32.c +++ b/dlls/secur32/tests/secur32.c @@ -30,6 +30,17 @@ static HMODULE secdll; +static SECURITY_STATUS (SEC_ENTRY *pSspiEncodeAuthIdentityAsStrings) + (PSEC_WINNT_AUTH_IDENTITY_OPAQUE, PCWSTR *, PCWSTR *, PCWSTR *); +static SECURITY_STATUS (SEC_ENTRY *pSspiEncodeStringsAsAuthIdentity) + (PCWSTR, PCWSTR, PCWSTR, PSEC_WINNT_AUTH_IDENTITY_OPAQUE *); +static void (SEC_ENTRY *pSspiFreeAuthIdentity) + (PSEC_WINNT_AUTH_IDENTITY_OPAQUE); +static void (SEC_ENTRY *pSspiLocalFree) + (void *); +static void (SEC_ENTRY *pSspiZeroAuthIdentity) + (PSEC_WINNT_AUTH_IDENTITY_OPAQUE); + static BOOLEAN (WINAPI * pGetComputerObjectNameA)(EXTENDED_NAME_FORMAT NameFormat, LPSTR lpNameBuffer, PULONG lpnSize); static BOOLEAN (WINAPI * pGetComputerObjectNameW)(EXTENDED_NAME_FORMAT NameFormat, LPWSTR lpNameBuffer, PULONG lpnSize); static BOOLEAN (WINAPI * pGetUserNameExA)(EXTENDED_NAME_FORMAT NameFormat, LPSTR lpNameBuffer, PULONG lpnSize); @@ -220,6 +231,90 @@ static void test_InitSecurityInterface(void) ok(sftW->Reserved4 == sftW->DecryptMessage, "Reserved4 should be equal to DecryptMessage in the security function table\n"); } +static void test_SspiEncodeStringsAsAuthIdentity(void) +{ + static const WCHAR username[] = {'u','s','e','r','n','a','m','e',0}; + static const WCHAR domainname[] = {'d','o','m','a','i','n','n','a','m','e',0}; + static const WCHAR password[] = {'p','a','s','s','w','o','r','d',0}; + const WCHAR *username_ptr, *domainname_ptr, *password_ptr; + PSEC_WINNT_AUTH_IDENTITY_OPAQUE id; + SECURITY_STATUS status; + + if (!pSspiEncodeStringsAsAuthIdentity) + { + win_skip( "SspiEncodeAuthIdentityAsStrings not exported by secur32.dll\n" ); + return; + } + + status = pSspiEncodeStringsAsAuthIdentity( NULL, NULL, NULL, NULL ); + ok( status == SEC_E_INVALID_TOKEN, "got %08x\n", status ); + + id = (PSEC_WINNT_AUTH_IDENTITY_OPAQUE)0xdeadbeef; + status = pSspiEncodeStringsAsAuthIdentity( NULL, NULL, NULL, &id ); + ok( status == SEC_E_INVALID_TOKEN, "got %08x\n", status ); + ok( id == (PSEC_WINNT_AUTH_IDENTITY_OPAQUE)0xdeadbeef, "id set\n" ); + + id = NULL; + status = pSspiEncodeStringsAsAuthIdentity( NULL, NULL, password, &id ); + ok( status == SEC_E_OK, "got %08x\n", status ); + ok( id != NULL, "id not set\n" ); + pSspiFreeAuthIdentity( id ); + + id = NULL; + status = pSspiEncodeStringsAsAuthIdentity( NULL, domainname, password, &id ); + ok( status == SEC_E_OK, "got %08x\n", status ); + ok( id != NULL, "id not set\n" ); + pSspiFreeAuthIdentity( id ); + + id = NULL; + status = pSspiEncodeStringsAsAuthIdentity( username, NULL, password, &id ); + ok( status == SEC_E_OK, "got %08x\n", status ); + ok( id != NULL, "id not set\n" ); + pSspiFreeAuthIdentity( id ); + + id = NULL; + status = pSspiEncodeStringsAsAuthIdentity( username, NULL, NULL, &id ); + ok( status == SEC_E_OK, "got %08x\n", status ); + ok( id != NULL, "id not set\n" ); + pSspiFreeAuthIdentity( id ); + + id = NULL; + status = pSspiEncodeStringsAsAuthIdentity( username, domainname, password, &id ); + ok( status == SEC_E_OK, "got %08x\n", status ); + ok( id != NULL, "id not set\n" ); + + username_ptr = domainname_ptr = password_ptr = NULL; + status = pSspiEncodeAuthIdentityAsStrings( id, &username_ptr, &domainname_ptr, &password_ptr ); + ok( status == SEC_E_OK, "got %08x\n", status ); + ok( !lstrcmpW( username, username_ptr ), "wrong username\n" ); + ok( !lstrcmpW( domainname, domainname_ptr ), "wrong domainname\n" ); + ok( !lstrcmpW( password, password_ptr ), "wrong password\n" ); + + pSspiZeroAuthIdentity( id ); + + pSspiLocalFree( (void *)username_ptr ); + pSspiLocalFree( (void *)domainname_ptr ); + pSspiLocalFree( (void *)password_ptr ); + pSspiFreeAuthIdentity( id ); + + id = NULL; + status = pSspiEncodeStringsAsAuthIdentity( username, NULL, password, &id ); + ok( status == SEC_E_OK, "got %08x\n", status ); + ok( id != NULL, "id not set\n" ); + + username_ptr = password_ptr = NULL; + domainname_ptr = (const WCHAR *)0xdeadbeef; + status = pSspiEncodeAuthIdentityAsStrings( id, &username_ptr, &domainname_ptr, &password_ptr ); + ok( status == SEC_E_OK, "got %08x\n", status ); + ok( !lstrcmpW( username, username_ptr ), "wrong username\n" ); + ok( domainname_ptr == NULL, "domainname_ptr not cleared\n" ); + ok( !lstrcmpW( password, password_ptr ), "wrong password\n" ); + + pSspiLocalFree( (void *)username_ptr ); + pSspiLocalFree( (void *)password_ptr ); + pSspiFreeAuthIdentity( id ); +} + START_TEST(secur32) { secdll = LoadLibraryA("secur32.dll"); @@ -229,6 +324,11 @@ START_TEST(secur32) if (secdll) { + pSspiEncodeAuthIdentityAsStrings = (void *)GetProcAddress(secdll, "SspiEncodeAuthIdentityAsStrings"); + pSspiEncodeStringsAsAuthIdentity = (void *)GetProcAddress(secdll, "SspiEncodeStringsAsAuthIdentity"); + pSspiFreeAuthIdentity = (void *)GetProcAddress(secdll, "SspiFreeAuthIdentity"); + pSspiLocalFree = (void *)GetProcAddress(secdll, "SspiLocalFree"); + pSspiZeroAuthIdentity = (void *)GetProcAddress(secdll, "SspiZeroAuthIdentity"); pGetComputerObjectNameA = (PVOID)GetProcAddress(secdll, "GetComputerObjectNameA"); pGetComputerObjectNameW = (PVOID)GetProcAddress(secdll, "GetComputerObjectNameW"); pGetUserNameExA = (PVOID)GetProcAddress(secdll, "GetUserNameExA"); @@ -257,6 +357,7 @@ START_TEST(secur32) win_skip("GetUserNameExW not exported by secur32.dll\n"); test_InitSecurityInterface(); + test_SspiEncodeStringsAsAuthIdentity(); FreeLibrary(secdll); }