workgrpdomnt4.cpp
来自「远程控制软件UltraVNC」· C++ 代码 · 共 886 行 · 第 1/2 页
CPP
886 行
/////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2002 Ultr@VNC Team Members. All Rights Reserved.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
//
// If the source code for the program is not available from the place from
// which you received this file, check
// http://ultravnc.sourceforge.net/
// /macine-vnc Greg Wood (wood@agressiv.com)
#include "workgrpdomnt4.h"
/////////////////////////
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
void UnloadSecurityDll(HMODULE hModule) {
if (hModule)
FreeLibrary(hModule);
_AcceptSecurityContext = NULL;
_AcquireCredentialsHandle = NULL;
_CompleteAuthToken = NULL;
_DeleteSecurityContext = NULL;
_FreeContextBuffer = NULL;
_FreeCredentialsHandle = NULL;
_InitializeSecurityContext = NULL;
_QuerySecurityPackageInfo = NULL;
}
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
HMODULE LoadSecurityDll() {
HMODULE hModule;
BOOL fAllFunctionsLoaded = FALSE;
TCHAR lpszDLL[MAX_PATH];
OSVERSIONINFO VerInfo;
_AcceptSecurityContext = NULL;
_AcquireCredentialsHandle = NULL;
_CompleteAuthToken = NULL;
_DeleteSecurityContext = NULL;
_FreeContextBuffer = NULL;
_FreeCredentialsHandle = NULL;
_InitializeSecurityContext = NULL;
_QuerySecurityPackageInfo = NULL;
//
// Find out which security DLL to use, depending on
// whether we are on NT or Win95 or 2000 or XP or .NET Server
// We have to use security.dll on Windows NT 4.0.
// All other operating systems, we have to use Secur32.dll
//
VerInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
if (!GetVersionEx (&VerInfo)) // If this fails, something has gone wrong
{
return FALSE;
}
if (VerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT &&
VerInfo.dwMajorVersion == 4 &&
VerInfo.dwMinorVersion == 0)
{
lstrcpy (lpszDLL, _T("security.dll"));
}
else
{
lstrcpy (lpszDLL, _T("secur32.dll"));
}
hModule = LoadLibrary(lpszDLL);
if (!hModule)
return NULL;
__try {
_AcceptSecurityContext = (ACCEPT_SECURITY_CONTEXT_FN)
GetProcAddress(hModule, "AcceptSecurityContext");
if (!_AcceptSecurityContext)
__leave;
#ifdef UNICODE
_AcquireCredentialsHandle = (ACQUIRE_CREDENTIALS_HANDLE_FN)
GetProcAddress(hModule, "AcquireCredentialsHandleW");
#else
_AcquireCredentialsHandle = (ACQUIRE_CREDENTIALS_HANDLE_FN)
GetProcAddress(hModule, "AcquireCredentialsHandleA");
#endif
if (!_AcquireCredentialsHandle)
__leave;
// CompleteAuthToken is not present on Windows 9x Secur32.dll
// Do not check for the availablity of the function if it is NULL;
_CompleteAuthToken = (COMPLETE_AUTH_TOKEN_FN)
GetProcAddress(hModule, "CompleteAuthToken");
_DeleteSecurityContext = (DELETE_SECURITY_CONTEXT_FN)
GetProcAddress(hModule, "DeleteSecurityContext");
if (!_DeleteSecurityContext)
__leave;
_FreeContextBuffer = (FREE_CONTEXT_BUFFER_FN)
GetProcAddress(hModule, "FreeContextBuffer");
if (!_FreeContextBuffer)
__leave;
_FreeCredentialsHandle = (FREE_CREDENTIALS_HANDLE_FN)
GetProcAddress(hModule, "FreeCredentialsHandle");
if (!_FreeCredentialsHandle)
__leave;
#ifdef UNICODE
_InitializeSecurityContext = (INITIALIZE_SECURITY_CONTEXT_FN)
GetProcAddress(hModule, "InitializeSecurityContextW");
#else
_InitializeSecurityContext = (INITIALIZE_SECURITY_CONTEXT_FN)
GetProcAddress(hModule, "InitializeSecurityContextA");
#endif
if (!_InitializeSecurityContext)
__leave;
#ifdef UNICODE
_QuerySecurityPackageInfo = (QUERY_SECURITY_PACKAGE_INFO_FN)
GetProcAddress(hModule, "QuerySecurityPackageInfoW");
#else
_QuerySecurityPackageInfo = (QUERY_SECURITY_PACKAGE_INFO_FN)
GetProcAddress(hModule, "QuerySecurityPackageInfoA");
#endif
if (!_QuerySecurityPackageInfo)
__leave;
fAllFunctionsLoaded = TRUE;
} __finally {
if (!fAllFunctionsLoaded) {
UnloadSecurityDll(hModule);
hModule = NULL;
}
}
return hModule;
}
///////////////////////////////////////////////////////////////////////////////
BOOL GenClientContext(PAUTH_SEQ pAS, PSEC_WINNT_AUTH_IDENTITY pAuthIdentity,
PVOID pIn, DWORD cbIn, PVOID pOut, PDWORD pcbOut, PBOOL pfDone) {
/*++
Routine Description:
Optionally takes an input buffer coming from the server and returns
a buffer of information to send back to the server. Also returns
an indication of whether or not the context is complete.
Return Value:
Returns TRUE if successful; otherwise FALSE.
--*/
SECURITY_STATUS ss;
TimeStamp tsExpiry;
SecBufferDesc sbdOut;
SecBuffer sbOut;
SecBufferDesc sbdIn;
SecBuffer sbIn;
ULONG fContextAttr;
if (!pAS->fInitialized) {
ss = _AcquireCredentialsHandle(NULL, _T("NTLM"),
SECPKG_CRED_OUTBOUND, NULL, pAuthIdentity, NULL, NULL,
&pAS->hcred, &tsExpiry);
if (ss < 0) {
fprintf(stderr, "AcquireCredentialsHandle failed with %08X\n", ss);
return FALSE;
}
pAS->fHaveCredHandle = TRUE;
}
// Prepare output buffer
sbdOut.ulVersion = 0;
sbdOut.cBuffers = 1;
sbdOut.pBuffers = &sbOut;
sbOut.cbBuffer = *pcbOut;
sbOut.BufferType = SECBUFFER_TOKEN;
sbOut.pvBuffer = pOut;
// Prepare input buffer
if (pAS->fInitialized) {
sbdIn.ulVersion = 0;
sbdIn.cBuffers = 1;
sbdIn.pBuffers = &sbIn;
sbIn.cbBuffer = cbIn;
sbIn.BufferType = SECBUFFER_TOKEN;
sbIn.pvBuffer = pIn;
}
ss = _InitializeSecurityContext(&pAS->hcred,
pAS->fInitialized ? &pAS->hctxt : NULL, NULL, 0, 0,
SECURITY_NATIVE_DREP, pAS->fInitialized ? &sbdIn : NULL,
0, &pAS->hctxt, &sbdOut, &fContextAttr, &tsExpiry);
if (ss < 0) {
// <winerror.h>
fprintf(stderr, "InitializeSecurityContext failed with %08X\n", ss);
return FALSE;
}
pAS->fHaveCtxtHandle = TRUE;
// If necessary, complete token
if (ss == SEC_I_COMPLETE_NEEDED || ss == SEC_I_COMPLETE_AND_CONTINUE) {
if (_CompleteAuthToken) {
ss = _CompleteAuthToken(&pAS->hctxt, &sbdOut);
if (ss < 0) {
fprintf(stderr, "CompleteAuthToken failed with %08X\n", ss);
return FALSE;
}
}
else {
fprintf (stderr, "CompleteAuthToken not supported.\n");
return FALSE;
}
}
*pcbOut = sbOut.cbBuffer;
if (!pAS->fInitialized)
pAS->fInitialized = TRUE;
*pfDone = !(ss == SEC_I_CONTINUE_NEEDED
|| ss == SEC_I_COMPLETE_AND_CONTINUE );
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
BOOL GenServerContext(PAUTH_SEQ pAS, PVOID pIn, DWORD cbIn, PVOID pOut,
PDWORD pcbOut, PBOOL pfDone) {
/*++
Routine Description:
Takes an input buffer coming from the client and returns a buffer
to be sent to the client. Also returns an indication of whether or
not the context is complete.
Return Value:
Returns TRUE if successful; otherwise FALSE.
--*/
SECURITY_STATUS ss;
TimeStamp tsExpiry;
SecBufferDesc sbdOut;
SecBuffer sbOut;
SecBufferDesc sbdIn;
SecBuffer sbIn;
ULONG fContextAttr;
if (!pAS->fInitialized) {
ss = _AcquireCredentialsHandle(NULL, _T("NTLM"),
SECPKG_CRED_INBOUND, NULL, NULL, NULL, NULL, &pAS->hcred,
&tsExpiry);
if (ss < 0) {
fprintf(stderr, "AcquireCredentialsHandle failed with %08X\n", ss);
return FALSE;
}
pAS->fHaveCredHandle = TRUE;
}
// Prepare output buffer
sbdOut.ulVersion = 0;
sbdOut.cBuffers = 1;
sbdOut.pBuffers = &sbOut;
sbOut.cbBuffer = *pcbOut;
sbOut.BufferType = SECBUFFER_TOKEN;
sbOut.pvBuffer = pOut;
// Prepare input buffer
sbdIn.ulVersion = 0;
sbdIn.cBuffers = 1;
sbdIn.pBuffers = &sbIn;
sbIn.cbBuffer = cbIn;
sbIn.BufferType = SECBUFFER_TOKEN;
sbIn.pvBuffer = pIn;
ss = _AcceptSecurityContext(&pAS->hcred,
pAS->fInitialized ? &pAS->hctxt : NULL, &sbdIn, 0,
SECURITY_NATIVE_DREP, &pAS->hctxt, &sbdOut, &fContextAttr,
&tsExpiry);
if (ss < 0) {
fprintf(stderr, "AcceptSecurityContext failed with %08X\n", ss);
return FALSE;
}
pAS->fHaveCtxtHandle = TRUE;
// If necessary, complete token
if (ss == SEC_I_COMPLETE_NEEDED || ss == SEC_I_COMPLETE_AND_CONTINUE) {
if (_CompleteAuthToken) {
ss = _CompleteAuthToken(&pAS->hctxt, &sbdOut);
if (ss < 0) {
fprintf(stderr, "CompleteAuthToken failed with %08X\n", ss);
return FALSE;
}
}
else {
fprintf (stderr, "CompleteAuthToken not supported.\n");
return FALSE;
}
}
*pcbOut = sbOut.cbBuffer;
if (!pAS->fInitialized)
pAS->fInitialized = TRUE;
*pfDone = !(ss = SEC_I_CONTINUE_NEEDED
|| ss == SEC_I_COMPLETE_AND_CONTINUE);
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
BOOL WINAPI SSPLogonUser(LPTSTR szDomain, LPTSTR szUser, LPTSTR szPassword) {
AUTH_SEQ asServer = {0};
AUTH_SEQ asClient = {0};
BOOL fDone = FALSE;
BOOL fResult = FALSE;
DWORD cbOut = 0;
DWORD cbIn = 0;
DWORD cbMaxToken = 0;
PVOID pClientBuf = NULL;
PVOID pServerBuf = NULL;
PSecPkgInfo pSPI = NULL;
HMODULE hModule = NULL;
SEC_WINNT_AUTH_IDENTITY ai;
__try {
hModule = LoadSecurityDll();
if (!hModule)
__leave;
// Get max token size
_QuerySecurityPackageInfo(_T("NTLM"), &pSPI);
cbMaxToken = pSPI->cbMaxToken;
_FreeContextBuffer(pSPI);
// Allocate buffers for client and server messages
pClientBuf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbMaxToken);
pServerBuf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbMaxToken);
// Initialize auth identity structure
ZeroMemory(&ai, sizeof(ai));
#if defined(UNICODE) || defined(_UNICODE)
ai.Domain = szDomain;
ai.DomainLength = lstrlen(szDomain);
ai.User = szUser;
ai.UserLength = lstrlen(szUser);
ai.Password = szPassword;
ai.PasswordLength = lstrlen(szPassword);
ai.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
#else
ai.Domain = (unsigned char *)szDomain;
ai.DomainLength = lstrlen(szDomain);
ai.User = (unsigned char *)szUser;
ai.UserLength = lstrlen(szUser);
ai.Password = (unsigned char *)szPassword;
ai.PasswordLength = lstrlen(szPassword);
ai.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
#endif
// Prepare client message (negotiate) .
cbOut = cbMaxToken;
if (!GenClientContext(&asClient, &ai, NULL, 0, pClientBuf, &cbOut, &fDone))
__leave;
// Prepare server message (challenge) .
cbIn = cbOut;
cbOut = cbMaxToken;
if (!GenServerContext(&asServer, pClientBuf, cbIn, pServerBuf, &cbOut,
&fDone))
__leave;
// Most likely failure: AcceptServerContext fails with SEC_E_LOGON_DENIED
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?