From 64b305b3b24d73ddcc324e81529cf229a7c41889 Mon Sep 17 00:00:00 2001 From: manojampalam Date: Sat, 14 May 2016 14:27:26 -0700 Subject: [PATCH] 5-14 C1 --- contrib/win32/win32compat/lsa/LsaString.cpp | 140 +- contrib/win32/win32compat/lsa/Ssh-lsa.cpp | 1222 ++++++++--------- .../win32compat/ssh-agent/authagent-request.c | 66 +- 3 files changed, 713 insertions(+), 715 deletions(-) diff --git a/contrib/win32/win32compat/lsa/LsaString.cpp b/contrib/win32/win32compat/lsa/LsaString.cpp index 0f88f41..76187c1 100644 --- a/contrib/win32/win32compat/lsa/LsaString.cpp +++ b/contrib/win32/win32compat/lsa/LsaString.cpp @@ -54,36 +54,36 @@ extern "C" { NTSTATUS LsaAllocUnicodeString(PUNICODE_STRING *lsaStr, DWORD maxLen) { - NTSTATUS ntStat = STATUS_NO_MEMORY; - - FAIL(lsaStr == NULL); + NTSTATUS ntStat = STATUS_NO_MEMORY; + + FAIL(lsaStr == NULL); + + *lsaStr = (PUNICODE_STRING)LsaApi.AllocateLsaHeap(sizeof(UNICODE_STRING)); + + FAIL((*lsaStr) == NULL); + + (*lsaStr)->Buffer = (WCHAR *)LsaApi.AllocateLsaHeap(sizeof(maxLen)); + (*lsaStr)->Length = 0; + (*lsaStr)->MaximumLength = maxLen; + + FAIL((*lsaStr)->Buffer == NULL); + + ntStat = 0; - *lsaStr = (PUNICODE_STRING) LsaApi.AllocateLsaHeap(sizeof(UNICODE_STRING)); - - FAIL((*lsaStr) == NULL); - - (*lsaStr) -> Buffer = (WCHAR *) LsaApi.AllocateLsaHeap(sizeof(maxLen)); - (*lsaStr) -> Length = 0; - (*lsaStr) -> MaximumLength = maxLen; - - FAIL((*lsaStr) -> Buffer == NULL); - - ntStat = 0; - fail: - if (ntStat) - { - if (lsaStr && (*lsaStr)) - { - LsaApi.FreeLsaHeap((*lsaStr) -> Buffer); - - LsaApi.FreeLsaHeap((*lsaStr)); - } + if (ntStat) + { + if (lsaStr && (*lsaStr)) + { + LsaApi.FreeLsaHeap((*lsaStr)->Buffer); - } - - return ntStat; + LsaApi.FreeLsaHeap((*lsaStr)); + } + + } + + return ntStat; } // @@ -94,15 +94,15 @@ fail: void LsaFreeUnicodeString(PUNICODE_STRING lsaStr) { - if (lsaStr) - { - if (lsaStr -> Buffer) - { - LsaApi.FreeLsaHeap(lsaStr -> Buffer); - } + if (lsaStr) + { + if (lsaStr->Buffer) + { + LsaApi.FreeLsaHeap(lsaStr->Buffer); + } - LsaApi.FreeLsaHeap(lsaStr); - } + LsaApi.FreeLsaHeap(lsaStr); + } } // @@ -116,46 +116,46 @@ void LsaFreeUnicodeString(PUNICODE_STRING lsaStr) NTSTATUS FillUnicodeString(UNICODE_STRING *lsaStr, const Char *str) { - NTSTATUS ntStat = STATUS_NO_MEMORY; - - DWORD cbSize = 0; - - // - // Is arguments ok? - // - - FAIL(lsaStr == NULL); - - FAIL(lsaStr -> Buffer == NULL); + NTSTATUS ntStat = STATUS_NO_MEMORY; + + DWORD cbSize = 0; + + // + // Is arguments ok? + // + + FAIL(lsaStr == NULL); + + FAIL(lsaStr->Buffer == NULL); + + FAIL(str == NULL); + + // + // Is string buffer too small? + // + + cbSize = strlen(str); + + FAIL(cbSize >= lsaStr->MaximumLength); + + // + // Fill string buffer. + // - FAIL(str == NULL); - - // - // Is string buffer too small? - // - - cbSize = strlen(str); - - FAIL(cbSize >= lsaStr -> MaximumLength); - - // - // Fill string buffer. - // - #ifdef __VS_BUILD__ - _swprintf(lsaStr -> Buffer, L"%hs", str); + _swprintf(lsaStr->Buffer, L"%hs", str); #else - swprintf(lsaStr->Buffer, L"%hs", str); + swprintf(lsaStr->Buffer, L"%hs", str); #endif - - lsaStr -> Length = cbSize * 2; - - lsaStr -> Buffer[cbSize * 2] = 0x0000; - - ntStat = STATUS_SUCCESS; - + + lsaStr->Length = cbSize * 2; + + lsaStr->Buffer[cbSize * 2] = 0x0000; + + ntStat = STATUS_SUCCESS; + fail: - - return ntStat; + + return ntStat; } diff --git a/contrib/win32/win32compat/lsa/Ssh-lsa.cpp b/contrib/win32/win32compat/lsa/Ssh-lsa.cpp index cb2987a..0290a0b 100644 --- a/contrib/win32/win32compat/lsa/Ssh-lsa.cpp +++ b/contrib/win32/win32compat/lsa/Ssh-lsa.cpp @@ -37,625 +37,609 @@ extern "C" { #endif -// -// Handle to 'ntdll.dll' module and address of 'RtlInitUnicodeString()' -// function. -// - -RtlInitUnicodeStringPtr RtlInitUnicodeString = NULL; - -HMODULE NtDll = NULL; - -#ifdef DYNAMIC_OPENSSL - // - // Handle to 'libcrypto.dll' and 'libssl.dll' modules. - // - - HMODULE LibCrypto = NULL; - HMODULE LibSSL = NULL; - - // - // This is global struct with dynamic loaded libssl and libcrypto - // functions. - // - - SSLFuncList DynSSL; -#endif - -// -// This is table with addresses of LSA API functions. -// We retrieve this table from system at package initialization -// moment. -// - -LSA_SECPKG_FUNCTION_TABLE LsaApi; - -// -// Called once to initialize package at system startup. -// -// pkgId - our package's ID given by LSA (IN) -// func - table with adresses of LSA functions (IN) -// database - uunsed / reserved (IN) -// confident - unused / reserved (IN) -// pkgName - name of our package (OUT) -// -// RETURNS: STATUSS_SUCCESS if OK. -// - -NTSTATUS NTAPI LsaApInitializePackage(ULONG pkgId, - PLSA_SECPKG_FUNCTION_TABLE func, - PLSA_STRING database, - PLSA_STRING confident, - PLSA_STRING *pkgName) -{ - - // - // Save table with adresses of LSA API functions. - // - - memcpy(&LsaApi, func, sizeof(LsaApi)); - - // - // Allocate buffer for package name. - // - - - *pkgName = (PLSA_STRING) LsaApi.AllocateLsaHeap(sizeof(LSA_STRING)); - - (*pkgName) -> Buffer = (PCHAR) LsaApi.AllocateLsaHeap(PKG_NAME_SIZE); - - // - // Fill buffer with our name. - // - - - memcpy((*pkgName) -> Buffer, PKG_NAME, PKG_NAME_SIZE); - - (*pkgName) -> Length = PKG_NAME_SIZE - 1; - - (*pkgName) -> MaximumLength = PKG_NAME_SIZE; - - - return STATUS_SUCCESS; -} - -// -// Allocate new buffer in LSA address space and copy input SID to it. -// -// dst - pointer that retrieves new allocated copy of input SID (OUT) -// src - input SID to copy (IN) -// -// RETURNS: 0 if OK. -// - -Int LsaCopySid(PSID &dst, PSID src) -{ - Int exitCode = 1; - - DWORD size = 0; - - FAIL(IsValidSid(src) == FALSE); - - size = GetLengthSid(src); - - dst = LsaApi.AllocateLsaHeap(size); - - memcpy(dst, src, size); - - exitCode = 0; - -fail: - - if (exitCode) - { - } - - return exitCode; -} - -// -// Allocate LSA_TOKEN_INFORMATION_V1 structure in LSA address space -// and fill it with data from given token. -// -// tokenInfo - new allocated struct with info from given token (OUT) -// token - handle to token (IN) -// -// RETURNS: 0 if OK. -// - -Int LsaAllocTokenInfo(PLSA_TOKEN_INFORMATION_V1 &tokenInfo, HANDLE token) -{ - - Int exitCode = 1; - - DWORD cbSize = 0; - - DWORD i = 0; - - // - // Temporary buffers for infos retrieved from input token. - // - - PTOKEN_USER pUserToken = NULL; - PTOKEN_GROUPS pGroupsToken = NULL; - PTOKEN_OWNER pOwnerToken = NULL; - - PTOKEN_PRIMARY_GROUP pPrimaryGroupToken = NULL; - - // - // Allocate LSA_TOKEN_INFORMATION_V1 struct for output, - // - - - tokenInfo = (PLSA_TOKEN_INFORMATION_V1) - LsaApi.AllocateLsaHeap(sizeof(LSA_TOKEN_INFORMATION_V1)); - - FAIL(tokenInfo == NULL); - - // - // Copy TOKEN_USER part from input token. - // We can't retrieve all token infos directly to output buffer, - // becouse SIDs must be allocated as separately memory blocks. - // - - - GetTokenInformation(token, TokenUser, NULL, 0, &cbSize); - - pUserToken = (PTOKEN_USER) LocalAlloc(LPTR, cbSize); - - FAIL(GetTokenInformation(token, TokenUser, - pUserToken, cbSize, &cbSize) == FALSE); - - tokenInfo -> User.User.Attributes = pUserToken -> User.Attributes; - - FAIL(LsaCopySid(tokenInfo -> User.User.Sid, pUserToken -> User.Sid)); - - // - // Copy TOKEN_GROUPS part from input token. - // - - - GetTokenInformation(token, TokenGroups, NULL, 0, &cbSize); - - pGroupsToken = (PTOKEN_GROUPS) LocalAlloc(LPTR, cbSize); - - FAIL(GetTokenInformation(token, TokenGroups, - pGroupsToken, cbSize, &cbSize) == FALSE); - - - cbSize = pGroupsToken -> GroupCount * sizeof(SID_AND_ATTRIBUTES) + sizeof(DWORD); - - tokenInfo -> Groups = (PTOKEN_GROUPS) LsaApi.AllocateLsaHeap(cbSize); - - tokenInfo -> Groups -> GroupCount = pGroupsToken -> GroupCount; - - - for (i = 0; i < pGroupsToken -> GroupCount; i++) - { - FAIL(LsaCopySid(tokenInfo -> Groups -> Groups[i].Sid, - pGroupsToken -> Groups[i].Sid)); - - tokenInfo -> Groups -> Groups[i].Attributes = pGroupsToken -> Groups[i].Attributes; - } - - // - // Retrieve TOKEN_PRIVILEGES part from input token. There are no SID's - // in this struct, so we can retrieve it directly to output buffer. - // - - - GetTokenInformation(token, TokenPrivileges, NULL, 0, &cbSize); - - tokenInfo -> Privileges = (PTOKEN_PRIVILEGES) LsaApi.AllocateLsaHeap(cbSize); - - FAIL(GetTokenInformation(token, TokenPrivileges, - tokenInfo -> Privileges, cbSize, &cbSize) == FALSE); - - // - // Copy TOKEN_OWNER part from input token. - // - - - GetTokenInformation(token, TokenOwner, NULL, 0, &cbSize); - - pOwnerToken = (PTOKEN_OWNER) LocalAlloc(LPTR, cbSize); - - FAIL(GetTokenInformation(token, TokenOwner, - pOwnerToken, cbSize, &cbSize) == FALSE); - - FAIL(LsaCopySid(tokenInfo -> Owner.Owner, pOwnerToken -> Owner)); - - // - // Copy TOKEN_PRIMARY_GROUP part from input token. - // - - - GetTokenInformation(token, TokenPrimaryGroup, NULL, 0, &cbSize); - - pPrimaryGroupToken = (PTOKEN_PRIMARY_GROUP) LocalAlloc(LPTR, cbSize); - - FAIL(GetTokenInformation(token, TokenPrimaryGroup, - pPrimaryGroupToken, cbSize, &cbSize) == FALSE); - - FAIL(LsaCopySid(tokenInfo -> PrimaryGroup.PrimaryGroup, - pPrimaryGroupToken -> PrimaryGroup)); - - // - // Copy TOKEN_DEFAULT_DACL part from input token. - // - - - //GetTokenInformation(token, TokenDefaultDacl, NULL, 0, &cbSize); - - //pDaclToken = (PTOKEN_DEFAULT_DACL) LocalAlloc(LPTR, cbSize); - - //FAIL(GetTokenInformation(token, TokenDefaultDacl, - // pDaclToken, cbSize, &cbSize) == FALSE); - - tokenInfo -> DefaultDacl.DefaultDacl = NULL; - - // - // Fill expiration time. Our token never expires. - // - - tokenInfo -> ExpirationTime.HighPart = 0x7fffffff; - tokenInfo -> ExpirationTime.LowPart = 0xffffffff; - - exitCode = 0; - -fail: - - // - // Clean up. - // - - LsaApi.FreeLsaHeap(pUserToken); - LsaApi.FreeLsaHeap(pGroupsToken); - LsaApi.FreeLsaHeap(pOwnerToken); - LsaApi.FreeLsaHeap(pPrimaryGroupToken); - - if (exitCode) - { - } - - - return exitCode; -} - - -// -// Called, when client logon process want logon user. -// -// request - internal LSA struct for allocating client buffer (IN) -// logonType - what type of logon client need (e.g. Interactive) (IN) -// authData - buffer with authorization data (we use SshLsaAuth) (IN) -// authDataClient - adress of original authData in client address space (IN) -// authDataSize - size of authData buffer in bytes (IN) -// profile - profile data (we decide what to return) (OUT) -// profileSize - number of bytes returnet in profile (OUT) -// subStat - additional NTSTATUS code used when logon failure (OUT) -// tokenInfoType - what structure we returned to LSA in tokenInfo (OUT) -// tokenInfo - structure with token's parts for LSA (OUT) -// accountName - on which account we try to logon (OUT) -// authority - ?? We use it as domain name and fill with NULL (OUT) -// - -NTSTATUS NTAPI - LsaApLogonUser(PLSA_CLIENT_REQUEST request, SECURITY_LOGON_TYPE logonType, - PVOID authData, PVOID clientAuthData, ULONG authDataSize, - PVOID *profile, PULONG profileSize, PLUID logonId, - PNTSTATUS subStat, - PLSA_TOKEN_INFORMATION_TYPE tokenInfoType, - PVOID *tokenInfo, - PLSA_UNICODE_STRING *accountName, - PLSA_UNICODE_STRING *authority) -{ - - NTSTATUS ntStat = STATUS_LOGON_FAILURE; - - Int exitCode = 1; - - // - // Function should retrieve authorization data as SshLsaAuth struct. - // - - wchar_t *inUserName = NULL; - - // - // Buffers used for retrieving user auth data from SAM database. - // - - WCHAR samUserBuf[MAX_ACCOUNT_NAME_SIZE + 1]; - - SECURITY_STRING samUser; - - UNICODE_STRING *flatName = NULL; - - UCHAR *userAuth = NULL; - - ULONG userAuthSize; - - wchar_t homeDir[MAX_PATH]; - - // - // Buffers used for creating new token from SAM data. - // We use this token as pattern for token info, which we send to LSA - // on output args. - // - - TOKEN_SOURCE tokenSource; - - HANDLE token = NULL; - HANDLE clientToken = NULL; - - // - // Info about client process. We use it to detect has client got - // SeTcbPrivilege. - // - - SECPKG_CLIENT_INFO clientInfo; - - // - // Check are input args ok? - // - - - inUserName = (wchar_t *) (((char*)authData)+4); - - - - - // - // Get info about client process. - // - - - NTFAIL(LsaApi.GetClientInfo(&clientInfo)); - - - // - // Fail if client has not got SeTcbPrivilege. - // - - FAIL(Not(clientInfo.HasTcbPrivilege)); - - // - // Allocate buffers. - // - - - NTFAIL(LsaAllocUnicodeString(authority, MAX_ACCOUNT_NAME_SIZE)); - NTFAIL(LsaAllocUnicodeString(accountName, MAX_ACCOUNT_NAME_SIZE)); - NTFAIL(LsaAllocUnicodeString(&flatName, MAX_ACCOUNT_NAME_SIZE)); - - // - // Retrieve user data from SAM base. - // - - - lstrcpyW(samUserBuf, inUserName); - - samUserBuf[MAX_ACCOUNT_NAME_SIZE] = 0x00; - - RtlInitUnicodeString((PUNICODE_STRING) &samUser, samUserBuf); - - NTFAIL(LsaApi.GetAuthDataForUser(&samUser, SecNameFlat, NULL, - &userAuth, &userAuthSize, flatName)); - - - // - // Create token basing on SAM data. - // - - - memcpy (tokenSource.SourceName, "_sshlsa_", 8); - - AllocateLocallyUniqueId(&tokenSource.SourceIdentifier); - - NTFAIL(LsaApi.ConvertAuthDataToToken(userAuth, userAuthSize, - SecurityDelegation, - &tokenSource, Network, - *authority, &token, logonId, - *accountName, subStat)); - - // - // Print token info. - // - - - // - // Allocate client buffer and copy home dir to it. - // - - - NTFAIL(LsaApi.AllocateClientBuffer(request, MAX_PATH * sizeof(wchar_t), profile)); - - *profileSize = MAX_PATH; - - - NTFAIL(LsaApi.CopyToClientBuffer(request, MAX_PATH * sizeof(wchar_t), - *profile, homeDir)); - - // - // Fill token info for LSA, using token created from SAM database - // as input pattern. We create LSA_TOKEN_INFORMATION_V1 struct - // here. - // - - - PLSA_TOKEN_INFORMATION_V1 outTokenInfo; - - FAIL(LsaAllocTokenInfo(outTokenInfo, token)); - - *tokenInfoType = LsaTokenInformationV1; - - *tokenInfo = outTokenInfo; - - // - // Duplicate token from lsa space to client space. - // - - - NTFAIL(LsaApi.DuplicateHandle(token, &clientToken)); - - ntStat = STATUS_SUCCESS; - - exitCode = 0; - -fail: - - if (exitCode) - { - - ntStat = STATUS_LOGON_FAILURE; - - CloseHandle(clientToken); - - LsaApi.DeleteLogonSession(logonId); - - *profileSize = 0; - } - else - { - } - - // - // Cleanup temporary buffers. - // - - CloseHandle(token); - - - LsaFreeUnicodeString(flatName); - - - return ntStat; -} - - -// -// This functions is called, after session closed. This is only -// information for package and we don't need to do anything here. -// - -VOID NTAPI LsaApLogonTerminated(PLUID logonId) -{ - } - - -// -// DllMain function (called when DLL is loaded or unloaded) -// - -BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpRes) -{ - BOOL exitCode = FALSE; - - switch (dwReason) - { - - // - // init package dll. - // - - case DLL_PROCESS_ATTACH: - { - // - // Initialize log. - // - - - - // - // Load 'ntdll.dll' module. - // - - - NtDll = GetModuleHandle("ntdll.dll"); - - FAIL(NtDll == NULL); - - // - // Load RtlInitUnicodeString() function from 'ntdll.dll'. - // - - - RtlInitUnicodeString = (RtlInitUnicodeStringPtr) - GetProcAddress(NtDll, "RtlInitUnicodeString"); - - FAIL(RtlInitUnicodeString == NULL); - - break; - } - - // - // uninit package dll. - // - - case DLL_PROCESS_DETACH: - { - - FreeModule(NtDll); - } - } - - exitCode = TRUE; - -fail: - - if (exitCode == FALSE) - { - - FreeModule(NtDll); - } - - return exitCode; -} - -// -// For compatibility only. -// - -NTSTATUS NTAPI LsaApCallPackagePassthrough(PLSA_CLIENT_REQUEST request, - PVOID submitBuf, - PVOID clientBufBase, - ULONG submitBufSize, - PVOID *outBuf, - PULONG outBufSize, - PNTSTATUS status) -{ - - return STATUS_NOT_IMPLEMENTED; -} - -// -// For compatibility only. -// - -NTSTATUS NTAPI LsaApCallPackageUntrusted(PLSA_CLIENT_REQUEST request, - PVOID submitBuf, - PVOID clientBufBase, - ULONG submitBufSize, - PVOID *outBuf, - PULONG outBufSize, - PNTSTATUS status) -{ - - return STATUS_NOT_IMPLEMENTED; -} - -// -// For compatibility only. -// - -NTSTATUS NTAPI LsaApCallPackage(PLSA_CLIENT_REQUEST request, PVOID submitBuf, - PVOID clientBufBase, ULONG submitBufSize, - PVOID *outBuf, PULONG outBufSize, - PNTSTATUS status) -{ - - return STATUS_NOT_IMPLEMENTED; -} + // + // Handle to 'ntdll.dll' module and address of 'RtlInitUnicodeString()' + // function. + // + + RtlInitUnicodeStringPtr RtlInitUnicodeString = NULL; + + HMODULE NtDll = NULL; + + // + // This is table with addresses of LSA API functions. + // We retrieve this table from system at package initialization + // moment. + // + + LSA_SECPKG_FUNCTION_TABLE LsaApi; + + // + // Called once to initialize package at system startup. + // + // pkgId - our package's ID given by LSA (IN) + // func - table with adresses of LSA functions (IN) + // database - uunsed / reserved (IN) + // confident - unused / reserved (IN) + // pkgName - name of our package (OUT) + // + // RETURNS: STATUSS_SUCCESS if OK. + // + + NTSTATUS NTAPI LsaApInitializePackage(ULONG pkgId, + PLSA_SECPKG_FUNCTION_TABLE func, + PLSA_STRING database, + PLSA_STRING confident, + PLSA_STRING *pkgName) + { + + // + // Save table with adresses of LSA API functions. + // + + memcpy(&LsaApi, func, sizeof(LsaApi)); + + // + // Allocate buffer for package name. + // + + + *pkgName = (PLSA_STRING)LsaApi.AllocateLsaHeap(sizeof(LSA_STRING)); + + (*pkgName)->Buffer = (PCHAR)LsaApi.AllocateLsaHeap(PKG_NAME_SIZE); + + // + // Fill buffer with our name. + // + + + memcpy((*pkgName)->Buffer, PKG_NAME, PKG_NAME_SIZE); + + (*pkgName)->Length = PKG_NAME_SIZE - 1; + + (*pkgName)->MaximumLength = PKG_NAME_SIZE; + + + return STATUS_SUCCESS; + } + + // + // Allocate new buffer in LSA address space and copy input SID to it. + // + // dst - pointer that retrieves new allocated copy of input SID (OUT) + // src - input SID to copy (IN) + // + // RETURNS: 0 if OK. + // + + Int LsaCopySid(PSID &dst, PSID src) + { + Int exitCode = 1; + + DWORD size = 0; + + FAIL(IsValidSid(src) == FALSE); + + size = GetLengthSid(src); + + dst = LsaApi.AllocateLsaHeap(size); + + memcpy(dst, src, size); + + exitCode = 0; + + fail: + + if (exitCode) + { + } + + return exitCode; + } + + // + // Allocate LSA_TOKEN_INFORMATION_V1 structure in LSA address space + // and fill it with data from given token. + // + // tokenInfo - new allocated struct with info from given token (OUT) + // token - handle to token (IN) + // + // RETURNS: 0 if OK. + // + + Int LsaAllocTokenInfo(PLSA_TOKEN_INFORMATION_V1 &tokenInfo, HANDLE token) + { + + Int exitCode = 1; + + DWORD cbSize = 0; + + DWORD i = 0; + + // + // Temporary buffers for infos retrieved from input token. + // + + PTOKEN_USER pUserToken = NULL; + PTOKEN_GROUPS pGroupsToken = NULL; + PTOKEN_OWNER pOwnerToken = NULL; + + PTOKEN_PRIMARY_GROUP pPrimaryGroupToken = NULL; + + // + // Allocate LSA_TOKEN_INFORMATION_V1 struct for output, + // + + + tokenInfo = (PLSA_TOKEN_INFORMATION_V1) + LsaApi.AllocateLsaHeap(sizeof(LSA_TOKEN_INFORMATION_V1)); + + FAIL(tokenInfo == NULL); + + // + // Copy TOKEN_USER part from input token. + // We can't retrieve all token infos directly to output buffer, + // becouse SIDs must be allocated as separately memory blocks. + // + + + GetTokenInformation(token, TokenUser, NULL, 0, &cbSize); + + pUserToken = (PTOKEN_USER)LocalAlloc(LPTR, cbSize); + + FAIL(GetTokenInformation(token, TokenUser, + pUserToken, cbSize, &cbSize) == FALSE); + + tokenInfo->User.User.Attributes = pUserToken->User.Attributes; + + FAIL(LsaCopySid(tokenInfo->User.User.Sid, pUserToken->User.Sid)); + + // + // Copy TOKEN_GROUPS part from input token. + // + + + GetTokenInformation(token, TokenGroups, NULL, 0, &cbSize); + + pGroupsToken = (PTOKEN_GROUPS)LocalAlloc(LPTR, cbSize); + + FAIL(GetTokenInformation(token, TokenGroups, + pGroupsToken, cbSize, &cbSize) == FALSE); + + + cbSize = pGroupsToken->GroupCount * sizeof(SID_AND_ATTRIBUTES) + sizeof(DWORD); + + tokenInfo->Groups = (PTOKEN_GROUPS)LsaApi.AllocateLsaHeap(cbSize); + + tokenInfo->Groups->GroupCount = pGroupsToken->GroupCount; + + + for (i = 0; i < pGroupsToken->GroupCount; i++) + { + FAIL(LsaCopySid(tokenInfo->Groups->Groups[i].Sid, + pGroupsToken->Groups[i].Sid)); + + tokenInfo->Groups->Groups[i].Attributes = pGroupsToken->Groups[i].Attributes; + } + + // + // Retrieve TOKEN_PRIVILEGES part from input token. There are no SID's + // in this struct, so we can retrieve it directly to output buffer. + // + + + GetTokenInformation(token, TokenPrivileges, NULL, 0, &cbSize); + + tokenInfo->Privileges = (PTOKEN_PRIVILEGES)LsaApi.AllocateLsaHeap(cbSize); + + FAIL(GetTokenInformation(token, TokenPrivileges, + tokenInfo->Privileges, cbSize, &cbSize) == FALSE); + + // + // Copy TOKEN_OWNER part from input token. + // + + + GetTokenInformation(token, TokenOwner, NULL, 0, &cbSize); + + pOwnerToken = (PTOKEN_OWNER)LocalAlloc(LPTR, cbSize); + + FAIL(GetTokenInformation(token, TokenOwner, + pOwnerToken, cbSize, &cbSize) == FALSE); + + FAIL(LsaCopySid(tokenInfo->Owner.Owner, pOwnerToken->Owner)); + + // + // Copy TOKEN_PRIMARY_GROUP part from input token. + // + + + GetTokenInformation(token, TokenPrimaryGroup, NULL, 0, &cbSize); + + pPrimaryGroupToken = (PTOKEN_PRIMARY_GROUP)LocalAlloc(LPTR, cbSize); + + FAIL(GetTokenInformation(token, TokenPrimaryGroup, + pPrimaryGroupToken, cbSize, &cbSize) == FALSE); + + FAIL(LsaCopySid(tokenInfo->PrimaryGroup.PrimaryGroup, + pPrimaryGroupToken->PrimaryGroup)); + + // + // Copy TOKEN_DEFAULT_DACL part from input token. + // + + + //GetTokenInformation(token, TokenDefaultDacl, NULL, 0, &cbSize); + + //pDaclToken = (PTOKEN_DEFAULT_DACL) LocalAlloc(LPTR, cbSize); + + //FAIL(GetTokenInformation(token, TokenDefaultDacl, + // pDaclToken, cbSize, &cbSize) == FALSE); + + tokenInfo->DefaultDacl.DefaultDacl = NULL; + + // + // Fill expiration time. Our token never expires. + // + + tokenInfo->ExpirationTime.HighPart = 0x7fffffff; + tokenInfo->ExpirationTime.LowPart = 0xffffffff; + + exitCode = 0; + + fail: + + // + // Clean up. + // + + LsaApi.FreeLsaHeap(pUserToken); + LsaApi.FreeLsaHeap(pGroupsToken); + LsaApi.FreeLsaHeap(pOwnerToken); + LsaApi.FreeLsaHeap(pPrimaryGroupToken); + + if (exitCode) + { + } + + + return exitCode; + } + + + // + // Called, when client logon process want logon user. + // + // request - internal LSA struct for allocating client buffer (IN) + // logonType - what type of logon client need (e.g. Interactive) (IN) + // authData - buffer with authorization data (we use SshLsaAuth) (IN) + // authDataClient - adress of original authData in client address space (IN) + // authDataSize - size of authData buffer in bytes (IN) + // profile - profile data (we decide what to return) (OUT) + // profileSize - number of bytes returnet in profile (OUT) + // subStat - additional NTSTATUS code used when logon failure (OUT) + // tokenInfoType - what structure we returned to LSA in tokenInfo (OUT) + // tokenInfo - structure with token's parts for LSA (OUT) + // accountName - on which account we try to logon (OUT) + // authority - ?? We use it as domain name and fill with NULL (OUT) + // + + NTSTATUS NTAPI + LsaApLogonUser(PLSA_CLIENT_REQUEST request, SECURITY_LOGON_TYPE logonType, + PVOID authData, PVOID clientAuthData, ULONG authDataSize, + PVOID *profile, PULONG profileSize, PLUID logonId, + PNTSTATUS subStat, + PLSA_TOKEN_INFORMATION_TYPE tokenInfoType, + PVOID *tokenInfo, + PLSA_UNICODE_STRING *accountName, + PLSA_UNICODE_STRING *authority) + { + + NTSTATUS ntStat = STATUS_LOGON_FAILURE; + + Int exitCode = 1; + + // + // Function should retrieve authorization data as SshLsaAuth struct. + // + + wchar_t *inUserName = NULL; + + // + // Buffers used for retrieving user auth data from SAM database. + // + + WCHAR samUserBuf[MAX_ACCOUNT_NAME_SIZE + 1]; + + SECURITY_STRING samUser; + + UNICODE_STRING *flatName = NULL; + + UCHAR *userAuth = NULL; + + ULONG userAuthSize; + + wchar_t homeDir[MAX_PATH]; + + // + // Buffers used for creating new token from SAM data. + // We use this token as pattern for token info, which we send to LSA + // on output args. + // + + TOKEN_SOURCE tokenSource; + + HANDLE token = NULL; + HANDLE clientToken = NULL; + + // + // Info about client process. We use it to detect has client got + // SeTcbPrivilege. + // + + SECPKG_CLIENT_INFO clientInfo; + + // + // Check are input args ok? + // + + + inUserName = (wchar_t *)authData; + + + + + // + // Get info about client process. + // + + + NTFAIL(LsaApi.GetClientInfo(&clientInfo)); + + + // + // Fail if client has not got SeTcbPrivilege. + // + + FAIL(Not(clientInfo.HasTcbPrivilege)); + + // + // Allocate buffers. + // + + + NTFAIL(LsaAllocUnicodeString(authority, MAX_ACCOUNT_NAME_SIZE)); + NTFAIL(LsaAllocUnicodeString(accountName, MAX_ACCOUNT_NAME_SIZE)); + NTFAIL(LsaAllocUnicodeString(&flatName, MAX_ACCOUNT_NAME_SIZE)); + + // + // Retrieve user data from SAM base. + // + + + lstrcpyW(samUserBuf, inUserName); + + samUserBuf[MAX_ACCOUNT_NAME_SIZE] = 0x00; + + RtlInitUnicodeString((PUNICODE_STRING)&samUser, samUserBuf); + + NTFAIL(LsaApi.GetAuthDataForUser(&samUser, SecNameFlat, NULL, + &userAuth, &userAuthSize, flatName)); + + + // + // Create token basing on SAM data. + // + + + memcpy(tokenSource.SourceName, "_sshlsa_", 8); + + AllocateLocallyUniqueId(&tokenSource.SourceIdentifier); + + NTFAIL(LsaApi.ConvertAuthDataToToken(userAuth, userAuthSize, + SecurityDelegation, + &tokenSource, Network, + *authority, &token, logonId, + *accountName, subStat)); + + // + // Print token info. + // + + + // + // Allocate client buffer and copy home dir to it. + // + + + NTFAIL(LsaApi.AllocateClientBuffer(request, MAX_PATH * sizeof(wchar_t), profile)); + + *profileSize = MAX_PATH; + + + NTFAIL(LsaApi.CopyToClientBuffer(request, MAX_PATH * sizeof(wchar_t), + *profile, homeDir)); + + // + // Fill token info for LSA, using token created from SAM database + // as input pattern. We create LSA_TOKEN_INFORMATION_V1 struct + // here. + // + + + PLSA_TOKEN_INFORMATION_V1 outTokenInfo; + + FAIL(LsaAllocTokenInfo(outTokenInfo, token)); + + *tokenInfoType = LsaTokenInformationV1; + + *tokenInfo = outTokenInfo; + + // + // Duplicate token from lsa space to client space. + // + + + NTFAIL(LsaApi.DuplicateHandle(token, &clientToken)); + + ntStat = STATUS_SUCCESS; + + exitCode = 0; + + fail: + + if (exitCode) + { + + ntStat = STATUS_LOGON_FAILURE; + + CloseHandle(clientToken); + + LsaApi.DeleteLogonSession(logonId); + + *profileSize = 0; + } + else + { + } + + // + // Cleanup temporary buffers. + // + + CloseHandle(token); + + + LsaFreeUnicodeString(flatName); + + + return ntStat; + } + + + // + // This functions is called, after session closed. This is only + // information for package and we don't need to do anything here. + // + + VOID NTAPI LsaApLogonTerminated(PLUID logonId) + { + } + + + // + // DllMain function (called when DLL is loaded or unloaded) + // + + BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpRes) + { + BOOL exitCode = FALSE; + + switch (dwReason) + { + + // + // init package dll. + // + + case DLL_PROCESS_ATTACH: + { + // + // Initialize log. + // + + + + // + // Load 'ntdll.dll' module. + // + + + NtDll = GetModuleHandle("ntdll.dll"); + + FAIL(NtDll == NULL); + + // + // Load RtlInitUnicodeString() function from 'ntdll.dll'. + // + + + RtlInitUnicodeString = (RtlInitUnicodeStringPtr) + GetProcAddress(NtDll, "RtlInitUnicodeString"); + + FAIL(RtlInitUnicodeString == NULL); + + break; + } + + // + // uninit package dll. + // + + case DLL_PROCESS_DETACH: + { + + FreeModule(NtDll); + } + } + + exitCode = TRUE; + + fail: + + if (exitCode == FALSE) + { + + FreeModule(NtDll); + } + + return exitCode; + } + + // + // For compatibility only. + // + + NTSTATUS NTAPI LsaApCallPackagePassthrough(PLSA_CLIENT_REQUEST request, + PVOID submitBuf, + PVOID clientBufBase, + ULONG submitBufSize, + PVOID *outBuf, + PULONG outBufSize, + PNTSTATUS status) + { + + return STATUS_NOT_IMPLEMENTED; + } + + // + // For compatibility only. + // + + NTSTATUS NTAPI LsaApCallPackageUntrusted(PLSA_CLIENT_REQUEST request, + PVOID submitBuf, + PVOID clientBufBase, + ULONG submitBufSize, + PVOID *outBuf, + PULONG outBufSize, + PNTSTATUS status) + { + + return STATUS_NOT_IMPLEMENTED; + } + + // + // For compatibility only. + // + + NTSTATUS NTAPI LsaApCallPackage(PLSA_CLIENT_REQUEST request, PVOID submitBuf, + PVOID clientBufBase, ULONG submitBufSize, + PVOID *outBuf, PULONG outBufSize, + PNTSTATUS status) + { + + return STATUS_NOT_IMPLEMENTED; + } #ifdef __cplusplus } diff --git a/contrib/win32/win32compat/ssh-agent/authagent-request.c b/contrib/win32/win32compat/ssh-agent/authagent-request.c index 4056438..c2ed041 100644 --- a/contrib/win32/win32compat/ssh-agent/authagent-request.c +++ b/contrib/win32/win32compat/ssh-agent/authagent-request.c @@ -56,18 +56,22 @@ generate_user_token(wchar_t* user) { LSA_OPERATIONAL_MODE mode; ULONG auth_package_id; NTSTATUS ret, subStatus; - KERB_S4U_LOGON *s4u_logon = NULL; + void * logon_info = NULL; size_t logon_info_size; LSA_STRING logon_process_name, auth_package_name, originName; TOKEN_SOURCE sourceContext; PKERB_INTERACTIVE_PROFILE pProfile = NULL; - LUID logonId; - QUOTA_LIMITS quotas; - DWORD cbProfile; - + LUID logonId; + QUOTA_LIMITS quotas; + DWORD cbProfile; + BOOL domain_user = (wcschr(user, L'@') != NULL)? TRUE : FALSE; + InitLsaString(&logon_process_name, "ssh-agent"); - //InitLsaString(&auth_package_name, MICROSOFT_KERBEROS_NAME_A); - InitLsaString(&auth_package_name, "Negotiate"); + if (domain_user) + InitLsaString(&auth_package_name, MICROSOFT_KERBEROS_NAME_A); + else + InitLsaString(&auth_package_name, "SSH-LSA"); + InitLsaString(&originName, "sshd"); if (ret = LsaRegisterLogonProcess(&logon_process_name, &lsa_handle, &mode) != STATUS_SUCCESS) goto done; @@ -75,23 +79,33 @@ generate_user_token(wchar_t* user) { if (ret = LsaLookupAuthenticationPackage(lsa_handle, &auth_package_name, &auth_package_id) != STATUS_SUCCESS) goto done; - logon_info_size = sizeof(KERB_S4U_LOGON); - logon_info_size += (wcslen(user) * 2 + 2); - s4u_logon = malloc(logon_info_size); - if (s4u_logon == NULL) - goto done; + if (domain_user) { + KERB_S4U_LOGON *s4u_logon; + logon_info_size = sizeof(KERB_S4U_LOGON); + logon_info_size += (wcslen(user) * 2 + 2); + logon_info = malloc(logon_info_size); + if (logon_info == NULL) + goto done; + s4u_logon = (KERB_S4U_LOGON*)logon_info; + s4u_logon->MessageType = KerbS4ULogon; + s4u_logon->Flags = 0; + s4u_logon->ClientUpn.Length = wcslen(user) * 2; + s4u_logon->ClientUpn.MaximumLength = s4u_logon->ClientUpn.Length; + s4u_logon->ClientUpn.Buffer = (WCHAR*)(s4u_logon + 1); + memcpy(s4u_logon->ClientUpn.Buffer, user, s4u_logon->ClientUpn.Length + 2); + s4u_logon->ClientRealm.Length = 0; + s4u_logon->ClientRealm.MaximumLength = 0; + s4u_logon->ClientRealm.Buffer = 0; + } + else { + logon_info_size = (wcslen(user) + 1)*sizeof(wchar_t); + logon_info = malloc(logon_info_size); + if (logon_info == NULL) + goto done; + memcpy(logon_info, user, logon_info_size); + } - s4u_logon->MessageType = KerbS4ULogon; - s4u_logon->Flags = 0; - s4u_logon->ClientUpn.Length = wcslen(user) * 2; - s4u_logon->ClientUpn.MaximumLength = s4u_logon->ClientUpn.Length; - s4u_logon->ClientUpn.Buffer = (WCHAR*)(s4u_logon + 1); - memcpy(s4u_logon->ClientUpn.Buffer, user, s4u_logon->ClientUpn.Length + 2); - s4u_logon->ClientRealm.Length = 0; - s4u_logon->ClientRealm.MaximumLength = 0; - s4u_logon->ClientRealm.Buffer = 0; - - memcpy(sourceContext.SourceName,".Jobs ", sizeof(sourceContext.SourceName)); + memcpy(sourceContext.SourceName,"sshagent", sizeof(sourceContext.SourceName)); if (AllocateLocallyUniqueId(&sourceContext.SourceIdentifier) != TRUE) goto done; @@ -100,7 +114,7 @@ generate_user_token(wchar_t* user) { &originName, Network, auth_package_id, - s4u_logon, + logon_info, logon_info_size, NULL, &sourceContext, @@ -115,8 +129,8 @@ generate_user_token(wchar_t* user) { done: if (lsa_handle) LsaDeregisterLogonProcess(lsa_handle); - if (s4u_logon) - free(s4u_logon); + if (logon_info) + free(logon_info); if (pProfile) LsaFreeReturnBuffer(pProfile);