This commit is contained in:
manojampalam 2016-05-14 15:46:12 -07:00
parent 64b305b3b2
commit 5ed50c217d
6 changed files with 359 additions and 902 deletions

View File

@ -20,8 +20,7 @@
</ProjectConfiguration> </ProjectConfiguration>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\lsa\LsaString.cpp" /> <ClCompile Include="..\win32compat\lsa\Ssh-lsa.c" />
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\lsa\Ssh-lsa.cpp" />
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>{02FB3D98-6516-42C6-9762-98811A99960F}</ProjectGuid> <ProjectGuid>{02FB3D98-6516-42C6-9762-98811A99960F}</ProjectGuid>

View File

@ -15,10 +15,7 @@
</Filter> </Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\lsa\LsaString.cpp"> <ClCompile Include="..\win32compat\lsa\Ssh-lsa.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\lsa\Ssh-lsa.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>

View File

@ -1,161 +0,0 @@
/*
* Author: NoMachine <developers@nomachine.com>
*
* Copyright (c) 2009, 2013 NoMachine
* All rights reserved
*
* Support functions and system calls' replacements needed to let the
* software run on Win32 based operating systems.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ssh-lsa.h"
#ifdef __VS_BUILD__
#ifdef __cplusplus
extern "C" {
#endif
#endif // __VS_BUILD__
extern LSA_SECPKG_FUNCTION_TABLE LsaApi;
#ifdef __VS_BUILD__
#ifdef __cplusplus
}
#endif
#endif
//
// Allocate empty UNICODE_STRING in LSA address space.
//
// lsaStr - pointer to new UNICODE_STRING (OUT)
// wstr - size of string buffer (IN)
//
// RETURNS: NTSTATUS code.
//
NTSTATUS LsaAllocUnicodeString(PUNICODE_STRING *lsaStr, DWORD maxLen)
{
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;
fail:
if (ntStat)
{
if (lsaStr && (*lsaStr))
{
LsaApi.FreeLsaHeap((*lsaStr)->Buffer);
LsaApi.FreeLsaHeap((*lsaStr));
}
}
return ntStat;
}
//
// Free UNICODE_STRING from LSA address space.
//
// lsaStr - pointer to UNICODE_STRING to free (IN/OUT)
//
void LsaFreeUnicodeString(PUNICODE_STRING lsaStr)
{
if (lsaStr)
{
if (lsaStr->Buffer)
{
LsaApi.FreeLsaHeap(lsaStr->Buffer);
}
LsaApi.FreeLsaHeap(lsaStr);
}
}
//
// Write ASCIIZ char table into UNICODE_STRING.
//
// lsaStr - pointer to new UNICODE_STRING (OUT)
// wstr - size of string buffer (IN)
//
// RETURNS: NTSTATUS code.
//
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);
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);
#else
swprintf(lsaStr->Buffer, L"%hs", str);
#endif
lsaStr->Length = cbSize * 2;
lsaStr->Buffer[cbSize * 2] = 0x0000;
ntStat = STATUS_SUCCESS;
fail:
return ntStat;
}

View File

@ -0,0 +1,357 @@
/*
* Author: NoMachine <developers@nomachine.com>
* Copyright (c) 2009, 2013 NoMachine
* All rights reserved
*
* Author: Manoj Ampalam <manojamp@microsoft.com>
* Simplified code to just perform local user logon
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS intERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define WINVER 0x501
#define UMDF_USING_NTSTATUS
#include <windows.h>
#define SECURITY_WIN32
#include <security.h>
#include <Ntsecapi.h>
#include <NTSecPkg.h>
#include <ntstatus.h>
#include <stdio.h>
#define Unsigned unsigned
#define Char char
#define Int int
#define Long long
#define Not(value) ((value) == 0)
#define PKG_NAME "SSH-LSA"
#define PKG_NAME_SIZE sizeof(PKG_NAME)
#define MAX_ACCOUNT_NAME_SIZE (256 * 2)
#define VERSION "4.0.346"
typedef VOID(WINAPI *RtlInitUnicodeStringPtr)
(PUNICODE_STRING, PCWSTR SourceString);
#define FAIL(CONDITION) if(CONDITION) goto fail
#define NTFAIL(NTFUNC) if((ntStat = (NTFUNC))) goto fail
RtlInitUnicodeStringPtr RtlInitUnicodeString = NULL;
HMODULE NtDll = NULL;
LSA_SECPKG_FUNCTION_TABLE LsaApi;
NTSTATUS LsaAllocUnicodeString(PUNICODE_STRING *lsaStr, USHORT maxLen)
{
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;
fail:
if (ntStat) {
if (lsaStr && (*lsaStr)) {
LsaApi.FreeLsaHeap((*lsaStr)->Buffer);
LsaApi.FreeLsaHeap((*lsaStr));
}
}
return ntStat;
}
void LsaFreeUnicodeString(PUNICODE_STRING lsaStr)
{
if (lsaStr) {
if (lsaStr->Buffer)
LsaApi.FreeLsaHeap(lsaStr->Buffer);
LsaApi.FreeLsaHeap(lsaStr);
}
}
NTSTATUS FillUnicodeString(UNICODE_STRING *lsaStr, const Char *str)
{
NTSTATUS ntStat = STATUS_NO_MEMORY;
USHORT cbSize = 0;
FAIL(lsaStr == NULL);
FAIL(lsaStr->Buffer == NULL);
FAIL(str == NULL);
cbSize = strlen(str);
FAIL(cbSize >= lsaStr->MaximumLength);
_swprintf(lsaStr->Buffer, L"%hs", str);
lsaStr->Length = cbSize * 2;
lsaStr->Buffer[cbSize * 2] = 0x0000;
ntStat = STATUS_SUCCESS;
fail:
return ntStat;
}
NTSTATUS NTAPI LsaApCallPackagePassthrough(PLSA_CLIENT_REQUEST request,
PVOID submitBuf,
PVOID clientBufBase,
ULONG submitBufSize,
PVOID *outBuf,
PULONG outBufSize,
PNTSTATUS status) {
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS NTAPI LsaApCallPackageUntrusted(PLSA_CLIENT_REQUEST request,
PVOID submitBuf,
PVOID clientBufBase,
ULONG submitBufSize,
PVOID *outBuf,
PULONG outBufSize,
PNTSTATUS status) {
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS NTAPI LsaApCallPackage(PLSA_CLIENT_REQUEST request, PVOID submitBuf,
PVOID clientBufBase, ULONG submitBufSize,
PVOID *outBuf, PULONG outBufSize,
PNTSTATUS status) {
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS NTAPI LsaApInitializePackage(ULONG pkgId,
PLSA_SECPKG_FUNCTION_TABLE func,
PLSA_STRING database,
PLSA_STRING confident,
PLSA_STRING *pkgName)
{
memcpy(&LsaApi, func, sizeof(LsaApi));
*pkgName = (PLSA_STRING)LsaApi.AllocateLsaHeap(sizeof(LSA_STRING));
(*pkgName)->Buffer = (PCHAR)LsaApi.AllocateLsaHeap(PKG_NAME_SIZE);
/* fill buffer with package name */
memcpy((*pkgName)->Buffer, PKG_NAME, PKG_NAME_SIZE);
(*pkgName)->Length = PKG_NAME_SIZE - 1;
(*pkgName)->MaximumLength = PKG_NAME_SIZE;
return STATUS_SUCCESS;
}
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:
return exitCode;
}
int LsaAllocTokenInfo(PLSA_TOKEN_INFORMATION_V1 *info, HANDLE token)
{
int exitCode = 1;
DWORD cbSize = 0;
DWORD i = 0;
PTOKEN_USER pUserToken = NULL;
PTOKEN_GROUPS pGroupsToken = NULL;
PTOKEN_OWNER pOwnerToken = NULL;
PTOKEN_PRIMARY_GROUP pPrimaryGroupToken = NULL;
PLSA_TOKEN_INFORMATION_V1 tokenInfo;
*info = (PLSA_TOKEN_INFORMATION_V1)
LsaApi.AllocateLsaHeap(sizeof(LSA_TOKEN_INFORMATION_V1));
FAIL(*info == NULL);
tokenInfo = *info;
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));
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;
}
GetTokenInformation(token, TokenPrivileges, NULL, 0, &cbSize);
tokenInfo->Privileges = (PTOKEN_PRIVILEGES)LsaApi.AllocateLsaHeap(cbSize);
FAIL(GetTokenInformation(token, TokenPrivileges,
tokenInfo->Privileges, cbSize, &cbSize) == FALSE);
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));
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));
tokenInfo->DefaultDacl.DefaultDacl = NULL;
tokenInfo->ExpirationTime.HighPart = 0x7fffffff;
tokenInfo->ExpirationTime.LowPart = 0xffffffff;
exitCode = 0;
fail:
LsaApi.FreeLsaHeap(pUserToken);
LsaApi.FreeLsaHeap(pGroupsToken);
LsaApi.FreeLsaHeap(pOwnerToken);
LsaApi.FreeLsaHeap(pPrimaryGroupToken);
return exitCode;
}
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;
wchar_t *inUserName = NULL;
WCHAR samUserBuf[MAX_ACCOUNT_NAME_SIZE + 1];
SECURITY_STRING samUser;
UNICODE_STRING *flatName = NULL;
UCHAR *userAuth = NULL;
ULONG userAuthSize;
wchar_t homeDir[MAX_PATH];
TOKEN_SOURCE tokenSource;
HANDLE token = NULL;
HANDLE clientToken = NULL;
SECPKG_CLIENT_INFO clientInfo;
inUserName = (wchar_t *)authData;
NTFAIL(LsaApi.GetClientInfo(&clientInfo));
FAIL(Not(clientInfo.HasTcbPrivilege));
NTFAIL(LsaAllocUnicodeString(authority, MAX_ACCOUNT_NAME_SIZE));
NTFAIL(LsaAllocUnicodeString(accountName, MAX_ACCOUNT_NAME_SIZE));
NTFAIL(LsaAllocUnicodeString(&flatName, MAX_ACCOUNT_NAME_SIZE));
lstrcpyW(samUserBuf, inUserName);
samUserBuf[MAX_ACCOUNT_NAME_SIZE] = 0x00;
RtlInitUnicodeString((PUNICODE_STRING)&samUser, samUserBuf);
NTFAIL(LsaApi.GetAuthDataForUser(&samUser, SecNameFlat, NULL,
&userAuth, &userAuthSize, flatName));
memcpy(tokenSource.SourceName, "_sshlsa_", 8);
AllocateLocallyUniqueId(&tokenSource.SourceIdentifier);
NTFAIL(LsaApi.ConvertAuthDataToToken(userAuth, userAuthSize,
SecurityDelegation,
&tokenSource, Network,
*authority, &token, logonId,
*accountName, subStat));
NTFAIL(LsaApi.AllocateClientBuffer(request, MAX_PATH * sizeof(wchar_t), profile));
*profileSize = MAX_PATH;
NTFAIL(LsaApi.CopyToClientBuffer(request, MAX_PATH * sizeof(wchar_t),
*profile, homeDir));
PLSA_TOKEN_INFORMATION_V1 outTokenInfo;
FAIL(LsaAllocTokenInfo(&outTokenInfo, token));
*tokenInfoType = LsaTokenInformationV1;
*tokenInfo = outTokenInfo;
NTFAIL(LsaApi.DuplicateHandle(token, &clientToken));
ntStat = STATUS_SUCCESS;
exitCode = 0;
fail:
if (exitCode)
{
ntStat = STATUS_LOGON_FAILURE;
CloseHandle(clientToken);
LsaApi.DeleteLogonSession(logonId);
*profileSize = 0;
}
CloseHandle(token);
LsaFreeUnicodeString(flatName);
return ntStat;
}
VOID NTAPI LsaApLogonTerminated(PLUID logonId)
{
}
BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpRes)
{
BOOL exitCode = FALSE;
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
{
NtDll = GetModuleHandle("ntdll.dll");
FAIL(NtDll == NULL);
RtlInitUnicodeString = (RtlInitUnicodeStringPtr)
GetProcAddress(NtDll, "RtlInitUnicodeString");
FAIL(RtlInitUnicodeString == NULL);
break;
}
case DLL_PROCESS_DETACH:
FreeModule(NtDll);
}
exitCode = TRUE;
fail:
if (exitCode == FALSE)
FreeModule(NtDll);
return exitCode;
}

View File

@ -1,646 +0,0 @@
/*
* Author: NoMachine <developers@nomachine.com>
*
* Copyright (c) 2009, 2013 NoMachine
* All rights reserved
*
* Support functions and system calls' replacements needed to let the
* software run on Win32 based operating systems.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define WINVER 0x501
#include "Ssh-lsa.h"
#ifdef __cplusplus
extern "C" {
#endif
//
// 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
}
#endif

View File

@ -1,89 +0,0 @@
/*
* Author: NoMachine <developers@nomachine.com>
*
* Copyright (c) 2009, 2013 NoMachine
* All rights reserved
*
* Support functions and system calls' replacements needed to let the
* software run on Win32 based operating systems.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SSH_Lsa_H
#define SSH_Lsa_H
#undef STRING
#undef TEST_APP
#define UMDF_USING_NTSTATUS
#include <windows.h>
#define SECURITY_WIN32
#include <security.h>
#include <Ntsecapi.h>
#include <NTSecPkg.h>
#include <ntstatus.h>
#include <stdio.h>
#define Unsigned unsigned
#define Char char
#define Int int
#define Long long
#define Not(value) ((value) == 0)
#define PKG_NAME "SSH-LSA"
#define PKG_NAME_SIZE sizeof(PKG_NAME)
#define MAX_ACCOUNT_NAME_SIZE (256 * 2)
#define VERSION "4.0.346"
typedef struct _SshLsaAuth
{
DWORD totalSize_;
DWORD dataFellow_;
DWORD userSize_;
DWORD signSize_;
DWORD dataSize_;
DWORD pkBlobSize_;
DWORD authFilesCount_;
BYTE buf_[1];
}
SshLsaAuth;
#ifndef __VS_BUILD__
typedef VOID WINAPI (*RtlInitUnicodeStringPtr)
(PUNICODE_STRING, PCWSTR SourceString);
#else
typedef VOID (WINAPI *RtlInitUnicodeStringPtr)
(PUNICODE_STRING, PCWSTR SourceString);
#endif
#define FAIL(CONDITION) if(CONDITION) goto fail
#define NTFAIL(NTFUNC) if((ntStat = (NTFUNC))) goto fail
NTSTATUS LsaAllocUnicodeString(UNICODE_STRING **lsaStr, DWORD maxLen);
NTSTATUS FillUnicodeString(UNICODE_STRING *lsaStr, const Char *str);
void LsaFreeUnicodeString(UNICODE_STRING *lsaStr);
#endif