Merge pull request #630 from FreeRDP/winpr
WinPR Registry, SAM, SSPI NTLM
This commit is contained in:
commit
c27d7954f6
@ -24,3 +24,4 @@ target_link_libraries(freerdp-test freerdp-core)
|
||||
target_link_libraries(freerdp-test freerdp-gdi)
|
||||
target_link_libraries(freerdp-test freerdp-utils)
|
||||
target_link_libraries(freerdp-test freerdp-channels ${CMAKE_DL_LIBS})
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#cmakedefine WITH_PROFILER
|
||||
#cmakedefine WITH_SSE2
|
||||
#cmakedefine WITH_NEON
|
||||
#cmakedefine WITH_NATIVE_SSPI
|
||||
|
||||
/* Debug */
|
||||
#cmakedefine WITH_DEBUG_CERTIFICATE
|
||||
|
@ -47,6 +47,7 @@ struct rdp_credssp
|
||||
SecBuffer PublicKey;
|
||||
SecBuffer ts_credentials;
|
||||
CryptoRc4 rc4_seal_state;
|
||||
LPTSTR ServicePrincipalName;
|
||||
SEC_WINNT_AUTH_IDENTITY identity;
|
||||
PSecurityFunctionTable table;
|
||||
SecPkgContext_Sizes ContextSizes;
|
||||
|
@ -49,6 +49,7 @@ FREERDP_API boolean tls_disconnect(rdpTls* tls);
|
||||
FREERDP_API int tls_read(rdpTls* tls, uint8* data, int length);
|
||||
FREERDP_API int tls_write(rdpTls* tls, uint8* data, int length);
|
||||
|
||||
FREERDP_API int tls_read_all(rdpTls* tls, uint8* data, int length);
|
||||
FREERDP_API int tls_write_all(rdpTls* tls, uint8* data, int length);
|
||||
|
||||
FREERDP_API boolean tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname);
|
||||
|
45
include/winpr/handle.h
Normal file
45
include/winpr/handle.h
Normal file
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Handle Management
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef WINPR_HANDLE_H
|
||||
#define WINPR_HANDLE_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <winpr/winpr.h>
|
||||
#include <winpr/wtypes.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
#define HANDLE_FLAG_INHERIT 0x00000001
|
||||
#define HANDLE_FLAG_PROTECT_FROM_CLOSE 0x00000002
|
||||
|
||||
WINPR_API BOOL CloseHandle(HANDLE hObject);
|
||||
|
||||
WINPR_API BOOL DuplicateHandle(HANDLE hSourceProcessHandle, HANDLE hSourceHandle, HANDLE hTargetProcessHandle,
|
||||
LPHANDLE lpTargetHandle, DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwOptions);
|
||||
|
||||
WINPR_API BOOL GetHandleInformation(HANDLE hObject, LPDWORD lpdwFlags);
|
||||
WINPR_API BOOL SetHandleInformation(HANDLE hObject, DWORD dwMask, DWORD dwFlags);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* WINPR_HANDLE_H */
|
||||
|
44
include/winpr/heap.h
Normal file
44
include/winpr/heap.h
Normal file
@ -0,0 +1,44 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Heap Memory Allocation
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef WINPR_HEAP_H
|
||||
#define WINPR_HEAP_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <winpr/winpr.h>
|
||||
#include <winpr/wtypes.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
#define HEAP_GENERATE_EXCEPTIONS 0x00000004
|
||||
#define HEAP_NO_SERIALIZE 0x00000001
|
||||
#define HEAP_ZERO_MEMORY 0x00000008
|
||||
#define HEAP_REALLOC_IN_PLACE_ONLY 0x00000010
|
||||
|
||||
WINPR_API HANDLE GetProcessHeap(void);
|
||||
WINPR_API LPVOID HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
|
||||
WINPR_API LPVOID HeapReAlloc(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, SIZE_T dwBytes);
|
||||
WINPR_API BOOL HeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* WINPR_HEAP_H */
|
||||
|
@ -38,16 +38,9 @@
|
||||
#define RtlFillMemory(Destination, Length, Fill) memset((Destination), (Fill), (Length))
|
||||
#define RtlZeroMemory(Destination, Length) memset((Destination), 0, (Length))
|
||||
|
||||
#define HEAP_GENERATE_EXCEPTIONS 0x00000004
|
||||
#define HEAP_NO_SERIALIZE 0x00000001
|
||||
#define HEAP_ZERO_MEMORY 0x00000008
|
||||
#define HEAP_REALLOC_IN_PLACE_ONLY 0x00000010
|
||||
|
||||
WINPR_API HANDLE GetProcessHeap(void);
|
||||
WINPR_API LPVOID HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
|
||||
WINPR_API LPVOID HeapReAlloc(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, SIZE_T dwBytes);
|
||||
WINPR_API BOOL HeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem);
|
||||
|
||||
#endif
|
||||
|
||||
#include <winpr/heap.h>
|
||||
|
||||
#endif /* WINPR_CRT_MEMORY_H */
|
||||
|
||||
|
46
include/winpr/ntlm.h
Normal file
46
include/winpr/ntlm.h
Normal file
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* NTLM Utils
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef WINPR_UTILS_NTLM_H
|
||||
#define WINPR_UTILS_NTLM_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <winpr/winpr.h>
|
||||
#include <winpr/wtypes.h>
|
||||
|
||||
WINPR_API BYTE* NTOWFv1W(LPWSTR Password, UINT32 PasswordLength, BYTE* NtHash);
|
||||
WINPR_API BYTE* NTOWFv1A(LPSTR Password, UINT32 PasswordLength, BYTE* NtHash);
|
||||
|
||||
WINPR_API BYTE* NTOWFv2W(LPWSTR Password, UINT32 PasswordLength, LPWSTR User,
|
||||
UINT32 UserLength, LPWSTR Domain, UINT32 DomainLength, BYTE* NtHash);
|
||||
WINPR_API BYTE* NTOWFv2A(LPSTR Password, UINT32 PasswordLength, LPSTR User,
|
||||
UINT32 UserLength, LPSTR Domain, UINT32 DomainLength, BYTE* NtHash);
|
||||
|
||||
#ifdef UNICODE
|
||||
#define NTOWFv1 NTOWFv1W
|
||||
#define NTOWFv2 NTOWFv2W
|
||||
#else
|
||||
#define NTOWFv1 NTOWFv1A
|
||||
#define NTOWFv2 NTOWFv2W
|
||||
#endif
|
||||
|
||||
#endif /* WINPR_UTILS_NTLM_H */
|
||||
|
@ -148,13 +148,6 @@ typedef ACCESS_MASK REGSAM;
|
||||
#define RRF_NOEXPAND 0x10000000
|
||||
#define RRF_ZEROONFAILURE 0x20000000
|
||||
|
||||
typedef struct _SECURITY_ATTRIBUTES
|
||||
{
|
||||
DWORD nLength;
|
||||
LPVOID lpSecurityDescriptor;
|
||||
BOOL bInheritHandle;
|
||||
} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;
|
||||
|
||||
struct val_context
|
||||
{
|
||||
int valuelen;
|
||||
@ -214,15 +207,6 @@ typedef PVALENTA PVALENT;
|
||||
|
||||
WINPR_API LONG RegCloseKey(HKEY hKey);
|
||||
|
||||
WINPR_API LONG RegConnectRegistryW(LPCWSTR lpMachineName, HKEY hKey, PHKEY phkResult);
|
||||
WINPR_API LONG RegConnectRegistryA(LPCSTR lpMachineName, HKEY hKey, PHKEY phkResult);
|
||||
|
||||
#ifdef UNICODE
|
||||
#define RegConnectRegistry RegConnectRegistryW
|
||||
#else
|
||||
#define RegConnectRegistry RegConnectRegistryA
|
||||
#endif
|
||||
|
||||
WINPR_API LONG RegCopyTreeW(HKEY hKeySrc, LPCWSTR lpSubKey, HKEY hKeyDest);
|
||||
WINPR_API LONG RegCopyTreeA(HKEY hKeySrc, LPCSTR lpSubKey, HKEY hKeyDest);
|
||||
|
||||
@ -243,28 +227,6 @@ WINPR_API LONG RegCreateKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD Reserved, LPSTR
|
||||
#define RegCreateKeyEx RegCreateKeyExA
|
||||
#endif
|
||||
|
||||
WINPR_API LONG RegCreateKeyTransactedW(HKEY hKey, LPCWSTR lpSubKey, DWORD Reserved, LPWSTR lpClass,
|
||||
DWORD dwOptions, REGSAM samDesired, const LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
||||
PHKEY phkResult, LPDWORD lpdwDisposition, HANDLE hTransaction, PVOID pExtendedParemeter);
|
||||
WINPR_API LONG RegCreateKeyTransactedA(HKEY hKey, LPCSTR lpSubKey, DWORD Reserved, LPSTR lpClass,
|
||||
DWORD dwOptions, REGSAM samDesired, const LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
||||
PHKEY phkResult, LPDWORD lpdwDisposition, HANDLE hTransaction, PVOID pExtendedParemeter);
|
||||
|
||||
#ifdef UNICODE
|
||||
#define RegCreateKeyTransacted RegCreateKeyTransactedW
|
||||
#else
|
||||
#define RegCreateKeyTransacted RegCreateKeyTransactedA
|
||||
#endif
|
||||
|
||||
WINPR_API LONG RegDeleteKeyW(HKEY hKey, LPCWSTR lpSubKey);
|
||||
WINPR_API LONG RegDeleteKeyA(HKEY hKey, LPCSTR lpSubKey);
|
||||
|
||||
#ifdef UNICODE
|
||||
#define RegDeleteKey RegDeleteKeyW
|
||||
#else
|
||||
#define RegDeleteKey RegDeleteKeyA
|
||||
#endif
|
||||
|
||||
WINPR_API LONG RegDeleteKeyExW(HKEY hKey, LPCWSTR lpSubKey, REGSAM samDesired, DWORD Reserved);
|
||||
WINPR_API LONG RegDeleteKeyExA(HKEY hKey, LPCSTR lpSubKey, REGSAM samDesired, DWORD Reserved);
|
||||
|
||||
@ -274,26 +236,6 @@ WINPR_API LONG RegDeleteKeyExA(HKEY hKey, LPCSTR lpSubKey, REGSAM samDesired, DW
|
||||
#define RegDeleteKeyEx RegDeleteKeyExA
|
||||
#endif
|
||||
|
||||
WINPR_API LONG RegDeleteKeyTransactedW(HKEY hKey, LPCWSTR lpSubKey, REGSAM samDesired,
|
||||
DWORD Reserved, HANDLE hTransaction, PVOID pExtendedParameter);
|
||||
WINPR_API LONG RegDeleteKeyTransactedA(HKEY hKey, LPCSTR lpSubKey, REGSAM samDesired,
|
||||
DWORD Reserved, HANDLE hTransaction, PVOID pExtendedParameter);
|
||||
|
||||
#ifdef UNICODE
|
||||
#define RegDeleteKeyTransacted RegDeleteKeyTransactedW
|
||||
#else
|
||||
#define RegDeleteKeyTransacted RegDeleteKeyTransactedA
|
||||
#endif
|
||||
|
||||
WINPR_API LONG RegDeleteKeyValueW(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpValueName);
|
||||
WINPR_API LONG RegDeleteKeyValueA(HKEY hKey, LPCSTR lpSubKey, LPCSTR lpValueName);
|
||||
|
||||
#ifdef UNICODE
|
||||
#define RegDeleteKeyValue RegDeleteKeyValueW
|
||||
#else
|
||||
#define RegDeleteKeyValue RegDeleteKeyValueA
|
||||
#endif
|
||||
|
||||
WINPR_API LONG RegDeleteTreeW(HKEY hKey, LPCWSTR lpSubKey);
|
||||
WINPR_API LONG RegDeleteTreeA(HKEY hKey, LPCSTR lpSubKey);
|
||||
|
||||
@ -312,14 +254,8 @@ WINPR_API LONG RegDeleteValueA(HKEY hKey, LPCSTR lpValueName);
|
||||
#define RegDeleteValue RegDeleteValueA
|
||||
#endif
|
||||
|
||||
WINPR_API LONG RegDisablePredefinedCache(void);
|
||||
|
||||
WINPR_API LONG RegDisablePredefinedCacheEx(void);
|
||||
|
||||
WINPR_API LONG RegDisableReflectionKey(HKEY hBase);
|
||||
|
||||
WINPR_API LONG RegEnableReflectionKey(HKEY hBase);
|
||||
|
||||
WINPR_API LONG RegEnumKeyExW(HKEY hKey, DWORD dwIndex, LPWSTR lpName, LPDWORD lpcName,
|
||||
LPDWORD lpReserved, LPWSTR lpClass, LPDWORD lpcClass, PFILETIME lpftLastWriteTime);
|
||||
WINPR_API LONG RegEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpName, LPDWORD lpcName,
|
||||
@ -358,6 +294,17 @@ WINPR_API LONG RegGetValueA(HKEY hkey, LPCSTR lpSubKey, LPCSTR lpValue,
|
||||
#define RegGetValue RegGetValueA
|
||||
#endif
|
||||
|
||||
WINPR_API LONG RegLoadAppKeyW(LPCWSTR lpFile, PHKEY phkResult,
|
||||
REGSAM samDesired, DWORD dwOptions, DWORD Reserved);
|
||||
WINPR_API LONG RegLoadAppKeyA(LPCSTR lpFile, PHKEY phkResult,
|
||||
REGSAM samDesired, DWORD dwOptions, DWORD Reserved);
|
||||
|
||||
#ifdef UNICODE
|
||||
#define RegLoadAppKey RegLoadAppKeyW
|
||||
#else
|
||||
#define RegLoadAppKey RegLoadAppKeyA
|
||||
#endif
|
||||
|
||||
WINPR_API LONG RegLoadKeyW(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpFile);
|
||||
WINPR_API LONG RegLoadKeyA(HKEY hKey, LPCSTR lpSubKey, LPCSTR lpFile);
|
||||
|
||||
@ -391,21 +338,8 @@ WINPR_API LONG RegOpenKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM
|
||||
#define RegOpenKeyEx RegOpenKeyExA
|
||||
#endif
|
||||
|
||||
WINPR_API LONG RegOpenKeyTransactedW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions,
|
||||
REGSAM samDesired, PHKEY phkResult, HANDLE hTransaction, PVOID pExtendedParameter);
|
||||
WINPR_API LONG RegOpenKeyTransactedA(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions,
|
||||
REGSAM samDesired, PHKEY phkResult, HANDLE hTransaction, PVOID pExtendedParameter);
|
||||
|
||||
#ifdef UNICODE
|
||||
#define RegOpenKeyTransacted RegOpenKeyTransactedW
|
||||
#else
|
||||
#define RegOpenKeyTransacted RegOpenKeyTransactedA
|
||||
#endif
|
||||
|
||||
WINPR_API LONG RegOpenUserClassesRoot(HANDLE hToken, DWORD dwOptions, REGSAM samDesired, PHKEY phkResult);
|
||||
|
||||
WINPR_API LONG RegOverridePredefKey(HKEY hKey, HKEY hNewHKey);
|
||||
|
||||
WINPR_API LONG RegQueryInfoKeyW(HKEY hKey, LPWSTR lpClass, LPDWORD lpcClass, LPDWORD lpReserved,
|
||||
LPDWORD lpcSubKeys, LPDWORD lpcMaxSubKeyLen, LPDWORD lpcMaxClassLen,
|
||||
LPDWORD lpcValues, LPDWORD lpcMaxValueNameLen, LPDWORD lpcMaxValueLen,
|
||||
@ -421,10 +355,6 @@ WINPR_API LONG RegQueryInfoKeyA(HKEY hKey, LPSTR lpClass, LPDWORD lpcClass, LPDW
|
||||
#define RegQueryInfoKey RegQueryInfoKeyA
|
||||
#endif
|
||||
|
||||
WINPR_API LONG RegQueryMultipleValues(HKEY hKey, PVALENT val_list, DWORD num_vals, LPTSTR lpValueBuf, LPDWORD ldwTotsize);
|
||||
|
||||
WINPR_API LONG RegQueryReflectionKey(HKEY hBase, BOOL* bIsReflectionDisabled);
|
||||
|
||||
WINPR_API LONG RegQueryValueExW(HKEY hKey, LPCWSTR lpValueName,
|
||||
LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData);
|
||||
WINPR_API LONG RegQueryValueExA(HKEY hKey, LPCSTR lpValueName,
|
||||
@ -436,15 +366,6 @@ WINPR_API LONG RegQueryValueExA(HKEY hKey, LPCSTR lpValueName,
|
||||
#define RegQueryValueEx RegQueryValueExA
|
||||
#endif
|
||||
|
||||
WINPR_API LONG RegReplaceKeyW(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpNewFile, LPCWSTR lpOldFile);
|
||||
WINPR_API LONG RegReplaceKeyA(HKEY hKey, LPCSTR lpSubKey, LPCSTR lpNewFile, LPCSTR lpOldFile);
|
||||
|
||||
#ifdef UNICODE
|
||||
#define RegReplaceKey RegReplaceKeyW
|
||||
#else
|
||||
#define RegReplaceKey RegReplaceKeyA
|
||||
#endif
|
||||
|
||||
WINPR_API LONG RegRestoreKeyW(HKEY hKey, LPCWSTR lpFile, DWORD dwFlags);
|
||||
WINPR_API LONG RegRestoreKeyA(HKEY hKey, LPCSTR lpFile, DWORD dwFlags);
|
||||
|
||||
@ -454,15 +375,6 @@ WINPR_API LONG RegRestoreKeyA(HKEY hKey, LPCSTR lpFile, DWORD dwFlags);
|
||||
#define RegRestoreKey RegRestoreKeyA
|
||||
#endif
|
||||
|
||||
WINPR_API LONG RegSaveKeyW(HKEY hKey, LPCWSTR lpFile, LPSECURITY_ATTRIBUTES lpSecurityAttributes);
|
||||
WINPR_API LONG RegSaveKeyA(HKEY hKey, LPCSTR lpFile, LPSECURITY_ATTRIBUTES lpSecurityAttributes);
|
||||
|
||||
#ifdef UNICODE
|
||||
#define RegSaveKey RegSaveKeyW
|
||||
#else
|
||||
#define RegSaveKey RegSaveKeyA
|
||||
#endif
|
||||
|
||||
WINPR_API LONG RegSaveKeyExW(HKEY hKey, LPCWSTR lpFile, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD Flags);
|
||||
WINPR_API LONG RegSaveKeyExA(HKEY hKey, LPCSTR lpFile, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD Flags);
|
||||
|
||||
@ -472,15 +384,6 @@ WINPR_API LONG RegSaveKeyExA(HKEY hKey, LPCSTR lpFile, LPSECURITY_ATTRIBUTES lpS
|
||||
#define RegSaveKeyEx RegSaveKeyExA
|
||||
#endif
|
||||
|
||||
WINPR_API LONG RegSetKeyValueW(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpValueName, DWORD dwType, LPCVOID lpData, DWORD cbData);
|
||||
WINPR_API LONG RegSetKeyValueA(HKEY hKey, LPCSTR lpSubKey, LPCSTR lpValueName, DWORD dwType, LPCVOID lpData, DWORD cbData);
|
||||
|
||||
#ifdef UNICODE
|
||||
#define RegSetKeyValue RegSetKeyValueW
|
||||
#else
|
||||
#define RegSetKeyValue RegSetKeyValueA
|
||||
#endif
|
||||
|
||||
WINPR_API LONG RegSetKeySecurity(HKEY hKey, SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR pSecurityDescriptor);
|
||||
|
||||
WINPR_API LONG RegSetValueExW(HKEY hKey, LPCWSTR lpValueName, DWORD Reserved, DWORD dwType, const BYTE* lpData, DWORD cbData);
|
||||
|
55
include/winpr/sam.h
Normal file
55
include/winpr/sam.h
Normal file
@ -0,0 +1,55 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Security Accounts Manager (SAM)
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef WINPR_UTILS_SAM_H
|
||||
#define WINPR_UTILS_SAM_H
|
||||
|
||||
#include <winpr/winpr.h>
|
||||
#include <winpr/wtypes.h>
|
||||
|
||||
struct winpr_sam
|
||||
{
|
||||
FILE* fp;
|
||||
char* line;
|
||||
char* buffer;
|
||||
BOOL read_only;
|
||||
};
|
||||
typedef struct winpr_sam WINPR_SAM;
|
||||
|
||||
struct winpr_sam_entry
|
||||
{
|
||||
LPSTR User;
|
||||
UINT32 UserLength;
|
||||
LPSTR Domain;
|
||||
UINT32 DomainLength;
|
||||
BYTE LmHash[16];
|
||||
BYTE NtHash[16];
|
||||
};
|
||||
typedef struct winpr_sam_entry WINPR_SAM_ENTRY;
|
||||
|
||||
WINPR_API WINPR_SAM_ENTRY* SamLookupUserA(WINPR_SAM* sam, LPSTR User, UINT32 UserLength, LPSTR Domain, UINT32 DomainLength);
|
||||
WINPR_API WINPR_SAM_ENTRY* SamLookupUserW(WINPR_SAM* sam, LPWSTR User, UINT32 UserLength, LPWSTR Domain, UINT32 DomainLength);
|
||||
|
||||
WINPR_API void SamFreeEntry(WINPR_SAM* sam, WINPR_SAM_ENTRY* entry);
|
||||
|
||||
WINPR_API WINPR_SAM* SamOpen(BOOL read_only);
|
||||
WINPR_API void SamClose(WINPR_SAM* sam);
|
||||
|
||||
#endif /* WINPR_UTILS_SAM_H */
|
||||
|
@ -22,8 +22,6 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
//#define NATIVE_SSPI
|
||||
|
||||
#include <wchar.h>
|
||||
#include <winpr/winpr.h>
|
||||
#include <winpr/wtypes.h>
|
||||
@ -34,7 +32,7 @@
|
||||
#include <tchar.h>
|
||||
#include <winerror.h>
|
||||
|
||||
#ifdef NATIVE_SSPI
|
||||
#ifdef WITH_NATIVE_SSPI
|
||||
#define SECURITY_WIN32
|
||||
#include <sspi.h>
|
||||
#include <security.h>
|
||||
|
@ -45,7 +45,7 @@
|
||||
#define MB_ERR_INVALID_CHARS 0x00000008
|
||||
|
||||
WINPR_API char* _strdup(const char* strSource);
|
||||
WINPR_API wchar_t* _wcsdup(const wchar_t* strSource);
|
||||
WINPR_API WCHAR* _wcsdup(const WCHAR* strSource);
|
||||
|
||||
WINPR_API LPSTR CharUpperA(LPSTR lpsz);
|
||||
WINPR_API LPWSTR CharUpperW(LPWSTR lpsz);
|
||||
@ -125,6 +125,24 @@ WINPR_API int MultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiBy
|
||||
WINPR_API int WideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int cchWideChar,
|
||||
LPSTR lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar);
|
||||
|
||||
WINPR_API int lstrlenA(LPCSTR lpString);
|
||||
WINPR_API int lstrlenW(LPCWSTR lpString);
|
||||
|
||||
#ifdef UNICODE
|
||||
#define lstrlen lstrlenW
|
||||
#else
|
||||
#define lstrlen lstrlenA
|
||||
#endif
|
||||
|
||||
WINPR_API int lstrcmpA(LPCSTR lpString1, LPCSTR lpString2);
|
||||
WINPR_API int lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2);
|
||||
|
||||
#ifdef UNICODE
|
||||
#define lstrcmp lstrcmpW
|
||||
#else
|
||||
#define lstrcmp lstrcmpA
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* WINPR_CRT_STRING_H */
|
||||
|
64
include/winpr/synch.h
Normal file
64
include/winpr/synch.h
Normal file
@ -0,0 +1,64 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Synchronization Functions
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef WINPR_SYNCH_H
|
||||
#define WINPR_SYNCH_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <winpr/winpr.h>
|
||||
#include <winpr/wtypes.h>
|
||||
|
||||
#include <winpr/handle.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
WINPR_API HANDLE CreateSemaphoreA(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, LPCSTR lpName);
|
||||
WINPR_API HANDLE CreateSemaphoreW(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, LPCWSTR lpName);
|
||||
|
||||
#ifdef UNICODE
|
||||
#define CreateSemaphore CreateSemaphoreW
|
||||
#else
|
||||
#define CreateSemaphore CreateSemaphoreA
|
||||
#endif
|
||||
|
||||
WINPR_API HANDLE OpenSemaphoreA(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName);
|
||||
WINPR_API HANDLE OpenSemaphoreW(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpName);
|
||||
|
||||
#ifdef UNICODE
|
||||
#define OpenSemaphore OpenSemaphoreW
|
||||
#else
|
||||
#define OpenSemaphore OpenSemaphoreA
|
||||
#endif
|
||||
|
||||
WINPR_API BOOL ReleaseSemaphore(HANDLE hSemaphore, LONG lReleaseCount, LPLONG lpPreviousCount);
|
||||
|
||||
#define WAIT_OBJECT_0 0x00000000L
|
||||
#define WAIT_ABANDONED 0x00000080L
|
||||
#define WAIT_TIMEOUT 0x00000102L
|
||||
#define WAIT_FAILED ((DWORD) 0xFFFFFFFF)
|
||||
|
||||
WINPR_API DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds);
|
||||
WINPR_API DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAll, DWORD dwMilliseconds);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* WINPR_SYNCH_H */
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Windows Registry
|
||||
* TCHAR
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
@ -17,16 +17,25 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <libxml/parser.h>
|
||||
#include <libxml/xmlmemory.h>
|
||||
#ifndef WINPR_TCHAR_H
|
||||
#define WINPR_TCHAR_H
|
||||
|
||||
struct _registry_xml
|
||||
{
|
||||
xmlDocPtr doc;
|
||||
xmlNodePtr node;
|
||||
};
|
||||
typedef struct _registry_xml RegistryXml;
|
||||
#include <winpr/wtypes.h>
|
||||
|
||||
RegistryXml* registry_xml_new();
|
||||
RegistryXml* registry_xml_open();
|
||||
void registry_xml_close(RegistryXml* registry);
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <tchar.h>
|
||||
|
||||
#else
|
||||
|
||||
#ifdef UNICODE
|
||||
typedef WCHAR TCHAR;
|
||||
#define _tprintf wprintf
|
||||
#else
|
||||
typedef CHAR TCHAR;
|
||||
#define _tprintf printf
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* WINPR_TCHAR_H */
|
@ -42,7 +42,7 @@
|
||||
typedef int BOOL, *PBOOL, *LPBOOL;
|
||||
typedef unsigned char BYTE, *PBYTE, *LPBYTE;
|
||||
typedef BYTE BOOLEAN, *PBOOLEAN;
|
||||
typedef wchar_t WCHAR, *PWCHAR;
|
||||
typedef unsigned short WCHAR, *PWCHAR;
|
||||
typedef WCHAR* BSTR;
|
||||
typedef char CHAR, *PCHAR;
|
||||
typedef unsigned long DWORD, *PDWORD, *LPDWORD;
|
||||
@ -54,14 +54,14 @@ typedef float FLOAT;
|
||||
typedef unsigned char UCHAR, *PUCHAR;
|
||||
typedef short SHORT;
|
||||
|
||||
typedef void* HANDLE;
|
||||
typedef void* HANDLE, *LPHANDLE;
|
||||
typedef DWORD HCALL;
|
||||
typedef int INT, *LPINT;
|
||||
typedef signed char INT8;
|
||||
typedef signed short INT16;
|
||||
typedef signed int INT32;
|
||||
typedef signed __int64 INT64;
|
||||
typedef const wchar_t* LMCSTR;
|
||||
typedef const WCHAR* LMCSTR;
|
||||
typedef WCHAR* LMSTR;
|
||||
typedef long LONG, *PLONG, *LPLONG;
|
||||
typedef signed __int64 LONGLONG;
|
||||
@ -74,10 +74,10 @@ typedef signed int LONG32;
|
||||
typedef signed __int64 LONG64;
|
||||
typedef const char* LPCSTR;
|
||||
|
||||
typedef const wchar_t* LPCWSTR;
|
||||
typedef const WCHAR* LPCWSTR;
|
||||
typedef char* PSTR, *LPSTR;
|
||||
|
||||
typedef wchar_t* LPWSTR, *PWSTR;
|
||||
typedef WCHAR* LPWSTR, *PWSTR;
|
||||
|
||||
typedef unsigned __int64 QWORD;
|
||||
typedef UCHAR* STRING;
|
||||
@ -176,6 +176,13 @@ typedef struct _SECURITY_DESCRIPTOR
|
||||
PACL Dacl;
|
||||
} SECURITY_DESCRIPTOR, *PSECURITY_DESCRIPTOR;
|
||||
|
||||
typedef struct _SECURITY_ATTRIBUTES
|
||||
{
|
||||
DWORD nLength;
|
||||
LPVOID lpSecurityDescriptor;
|
||||
BOOL bInheritHandle;
|
||||
} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;
|
||||
|
||||
#endif
|
||||
|
||||
typedef BYTE byte;
|
||||
|
@ -543,7 +543,7 @@ boolean gcc_read_client_core_data(STREAM* s, rdpSettings* settings, uint16 block
|
||||
break;
|
||||
str = freerdp_uniconv_in(settings->uniconv, stream_get_tail(s), 64);
|
||||
stream_seek(s, 64);
|
||||
snprintf(settings->client_product_id, sizeof(settings->client_product_id), "%s", str);
|
||||
snprintf(settings->client_product_id, 32, "%s", str);
|
||||
xfree(str);
|
||||
blockLength -= 64;
|
||||
|
||||
|
@ -40,7 +40,7 @@
|
||||
|
||||
static boolean freerdp_listener_open(freerdp_listener* instance, const char* bind_address, uint16 port)
|
||||
{
|
||||
rdpListener* listener = (rdpListener*)instance->listener;
|
||||
rdpListener* listener = (rdpListener*) instance->listener;
|
||||
int status;
|
||||
int sockfd;
|
||||
char servname[10];
|
||||
@ -56,14 +56,20 @@ static boolean freerdp_listener_open(freerdp_listener* instance, const char* bin
|
||||
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
if (bind_address == NULL)
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
|
||||
snprintf(servname, sizeof(servname), "%d", port);
|
||||
status = getaddrinfo(bind_address, servname, &hints, &res);
|
||||
|
||||
if (status != 0)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
_tprintf(_T("getaddrinfo error: %s\n"), gai_strerror(status));
|
||||
#else
|
||||
perror("getaddrinfo");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -73,6 +79,7 @@ static boolean freerdp_listener_open(freerdp_listener* instance, const char* bin
|
||||
continue;
|
||||
|
||||
sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
||||
|
||||
if (sockfd == -1)
|
||||
{
|
||||
perror("socket");
|
||||
@ -92,14 +99,21 @@ static boolean freerdp_listener_open(freerdp_listener* instance, const char* bin
|
||||
#endif
|
||||
|
||||
status = bind(sockfd, ai->ai_addr, ai->ai_addrlen);
|
||||
|
||||
if (status != 0)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
_tprintf(L"bind() failed with error: %u\n", WSAGetLastError());
|
||||
WSACleanup();
|
||||
#else
|
||||
perror("bind");
|
||||
close(sockfd);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
status = listen(sockfd, 10);
|
||||
|
||||
if (status != 0)
|
||||
{
|
||||
perror("listen");
|
||||
@ -110,9 +124,9 @@ static boolean freerdp_listener_open(freerdp_listener* instance, const char* bin
|
||||
listener->sockfds[listener->num_sockfds++] = sockfd;
|
||||
|
||||
if (ai->ai_family == AF_INET)
|
||||
sin_addr = &(((struct sockaddr_in*)ai->ai_addr)->sin_addr);
|
||||
sin_addr = &(((struct sockaddr_in*) ai->ai_addr)->sin_addr);
|
||||
else
|
||||
sin_addr = &(((struct sockaddr_in6*)ai->ai_addr)->sin6_addr);
|
||||
sin_addr = &(((struct sockaddr_in6*) ai->ai_addr)->sin6_addr);
|
||||
|
||||
printf("Listening on %s port %s.\n", inet_ntop(ai->ai_family, sin_addr, buf, sizeof(buf)), servname);
|
||||
}
|
||||
@ -125,12 +139,13 @@ static boolean freerdp_listener_open(freerdp_listener* instance, const char* bin
|
||||
static boolean freerdp_listener_open_local(freerdp_listener* instance, const char* path)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
rdpListener* listener = (rdpListener*)instance->listener;
|
||||
int status;
|
||||
int sockfd;
|
||||
struct sockaddr_un addr;
|
||||
rdpListener* listener = (rdpListener*) instance->listener;
|
||||
|
||||
sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
|
||||
if (sockfd == -1)
|
||||
{
|
||||
perror("socket");
|
||||
@ -142,7 +157,9 @@ static boolean freerdp_listener_open_local(freerdp_listener* instance, const cha
|
||||
addr.sun_family = AF_UNIX;
|
||||
strncpy(addr.sun_path, path, sizeof(addr.sun_path));
|
||||
unlink(path);
|
||||
status = bind(sockfd, (struct sockaddr *) &addr, sizeof(addr));
|
||||
|
||||
status = bind(sockfd, (struct sockaddr*) &addr, sizeof(addr));
|
||||
|
||||
if (status != 0)
|
||||
{
|
||||
perror("bind");
|
||||
@ -151,6 +168,7 @@ static boolean freerdp_listener_open_local(freerdp_listener* instance, const cha
|
||||
}
|
||||
|
||||
status = listen(sockfd, 10);
|
||||
|
||||
if (status != 0)
|
||||
{
|
||||
perror("listen");
|
||||
@ -164,7 +182,7 @@ static boolean freerdp_listener_open_local(freerdp_listener* instance, const cha
|
||||
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -172,19 +190,20 @@ static void freerdp_listener_close(freerdp_listener* instance)
|
||||
{
|
||||
int i;
|
||||
|
||||
rdpListener* listener = (rdpListener*)instance->listener;
|
||||
rdpListener* listener = (rdpListener*) instance->listener;
|
||||
|
||||
for (i = 0; i < listener->num_sockfds; i++)
|
||||
{
|
||||
close(listener->sockfds[i]);
|
||||
}
|
||||
|
||||
listener->num_sockfds = 0;
|
||||
}
|
||||
|
||||
static boolean freerdp_listener_get_fds(freerdp_listener* instance, void** rfds, int* rcount)
|
||||
{
|
||||
rdpListener* listener = (rdpListener*)instance->listener;
|
||||
int i;
|
||||
rdpListener* listener = (rdpListener*) instance->listener;
|
||||
|
||||
if (listener->num_sockfds < 1)
|
||||
return false;
|
||||
|
@ -912,8 +912,10 @@ rdpRdp* rdp_new(freerdp* instance)
|
||||
{
|
||||
rdp->instance = instance;
|
||||
rdp->settings = settings_new((void*) instance);
|
||||
|
||||
if (instance != NULL)
|
||||
instance->settings = rdp->settings;
|
||||
|
||||
rdp->extension = extension_new(instance);
|
||||
rdp->transport = transport_new(rdp->settings);
|
||||
rdp->license = license_new(rdp);
|
||||
@ -937,6 +939,8 @@ rdpRdp* rdp_new(freerdp* instance)
|
||||
|
||||
void rdp_free(rdpRdp* rdp)
|
||||
{
|
||||
return;
|
||||
|
||||
if (rdp != NULL)
|
||||
{
|
||||
crypto_rc4_free(rdp->rc4_decrypt_key);
|
||||
|
@ -38,7 +38,7 @@ boolean ntlm_client_init(rdpNtlm* ntlm, boolean confidentiality, char* user, cha
|
||||
|
||||
ntlm->confidentiality = confidentiality;
|
||||
|
||||
#ifdef NATIVE_SSPI
|
||||
#ifdef WITH_NATIVE_SSPI
|
||||
{
|
||||
HMODULE hSSPI;
|
||||
INIT_SECURITY_INTERFACE InitSecurityInterface;
|
||||
|
@ -189,8 +189,14 @@ boolean tcp_set_blocking_mode(rdpTcp* tcp, boolean blocking)
|
||||
else
|
||||
fcntl(tcp->sockfd, F_SETFL, flags | O_NONBLOCK);
|
||||
#else
|
||||
int status;
|
||||
u_long arg = blocking;
|
||||
ioctlsocket(tcp->sockfd, FIONBIO, &arg);
|
||||
|
||||
status = ioctlsocket(tcp->sockfd, FIONBIO, &arg);
|
||||
|
||||
if (status != NO_ERROR)
|
||||
printf("ioctlsocket() failed with error: %ld\n", status);
|
||||
|
||||
tcp->wsa_event = WSACreateEvent();
|
||||
WSAEventSelect(tcp->sockfd, tcp->wsa_event, FD_READ);
|
||||
#endif
|
||||
|
@ -69,7 +69,8 @@ void crypto_rc4(CryptoRc4 rc4, uint32 length, const uint8* in_data, uint8* out_d
|
||||
|
||||
void crypto_rc4_free(CryptoRc4 rc4)
|
||||
{
|
||||
xfree(rc4);
|
||||
if (rc4)
|
||||
xfree(rc4);
|
||||
}
|
||||
|
||||
CryptoDes3 crypto_des3_encrypt_init(const uint8* key, const uint8* ivec)
|
||||
|
@ -76,6 +76,8 @@
|
||||
#define WITH_DEBUG_CREDSSP
|
||||
#endif
|
||||
|
||||
#define TERMSRV_SPN_PREFIX "TERMSRV/"
|
||||
|
||||
void credssp_send(rdpCredssp* credssp);
|
||||
int credssp_recv(rdpCredssp* credssp);
|
||||
void credssp_buffer_print(rdpCredssp* credssp);
|
||||
@ -92,8 +94,12 @@ SECURITY_STATUS credssp_decrypt_ts_credentials(rdpCredssp* credssp);
|
||||
|
||||
int credssp_ntlm_client_init(rdpCredssp* credssp)
|
||||
{
|
||||
char* spn;
|
||||
int length;
|
||||
freerdp* instance;
|
||||
rdpSettings* settings = credssp->settings;
|
||||
rdpSettings* settings;
|
||||
|
||||
settings = credssp->settings;
|
||||
instance = (freerdp*) settings->instance;
|
||||
|
||||
if ((settings->password == NULL) || (settings->username == NULL))
|
||||
@ -112,6 +118,20 @@ int credssp_ntlm_client_init(rdpCredssp* credssp)
|
||||
sspi_SecBufferAlloc(&credssp->PublicKey, credssp->tls->public_key.length);
|
||||
CopyMemory(credssp->PublicKey.pvBuffer, credssp->tls->public_key.data, credssp->tls->public_key.length);
|
||||
|
||||
length = sizeof(TERMSRV_SPN_PREFIX) + strlen(settings->hostname);
|
||||
|
||||
spn = (SEC_CHAR*) malloc(length + 1);
|
||||
sprintf(spn, "%s%s", TERMSRV_SPN_PREFIX, settings->hostname);
|
||||
|
||||
#ifdef UNICODE
|
||||
credssp->ServicePrincipalName = (LPTSTR) malloc(length * 2 + 2);
|
||||
MultiByteToWideChar(CP_ACP, 0, spn, length,
|
||||
(LPWSTR) credssp->ServicePrincipalName, length);
|
||||
free(spn);
|
||||
#else
|
||||
credssp->ServicePrincipalName = spn;
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -126,8 +146,6 @@ int credssp_ntlm_server_init(rdpCredssp* credssp)
|
||||
rdpSettings* settings = credssp->settings;
|
||||
instance = (freerdp*) settings->instance;
|
||||
|
||||
sspi_SetAuthIdentity(&(credssp->identity), "username", NULL, NULL);
|
||||
|
||||
sspi_SecBufferAlloc(&credssp->PublicKey, credssp->tls->public_key.length);
|
||||
CopyMemory(credssp->PublicKey.pvBuffer, credssp->tls->public_key.data, credssp->tls->public_key.length);
|
||||
|
||||
@ -157,13 +175,13 @@ int credssp_client_authenticate(rdpCredssp* credssp)
|
||||
if (credssp_ntlm_client_init(credssp) == 0)
|
||||
return 0;
|
||||
|
||||
#ifdef NATIVE_SSPI
|
||||
#ifdef WITH_NATIVE_SSPI
|
||||
{
|
||||
HMODULE hSSPI;
|
||||
INIT_SECURITY_INTERFACE InitSecurityInterface;
|
||||
PSecurityFunctionTable pSecurityInterface = NULL;
|
||||
|
||||
hSSPI = LoadLibrary(_T("secur32.dll"));
|
||||
hSSPI = LoadLibrary(_T("security.dll"));
|
||||
|
||||
#ifdef UNICODE
|
||||
InitSecurityInterface = (INIT_SECURITY_INTERFACE) GetProcAddress(hSSPI, "InitSecurityInterfaceW");
|
||||
@ -202,8 +220,8 @@ int credssp_client_authenticate(rdpCredssp* credssp)
|
||||
memset(&output_buffer, 0, sizeof(SecBuffer));
|
||||
memset(&credssp->ContextSizes, 0, sizeof(SecPkgContext_Sizes));
|
||||
|
||||
fContextReq = ISC_REQ_REPLAY_DETECT | ISC_REQ_SEQUENCE_DETECT |
|
||||
ISC_REQ_CONFIDENTIALITY | ISC_REQ_DELEGATE;
|
||||
fContextReq = ISC_REQ_CONFIDENTIALITY | ISC_REQ_INTEGRITY | ISC_REQ_IDENTIFY |
|
||||
ISC_REQ_EXTENDED_ERROR | ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT;
|
||||
|
||||
while (true)
|
||||
{
|
||||
@ -216,8 +234,8 @@ int credssp_client_authenticate(rdpCredssp* credssp)
|
||||
|
||||
status = credssp->table->InitializeSecurityContext(&credentials,
|
||||
(have_context) ? &credssp->context : NULL,
|
||||
NULL, fContextReq, 0, SECURITY_NETWORK_DREP,
|
||||
(have_input_buffer) ? &input_buffer_desc : NULL,
|
||||
credssp->ServicePrincipalName, fContextReq, 0,
|
||||
SECURITY_NATIVE_DREP, (have_input_buffer) ? &input_buffer_desc : NULL,
|
||||
0, &credssp->context, &output_buffer_desc, &pfContextAttr, &expiration);
|
||||
|
||||
if (input_buffer.pvBuffer != NULL)
|
||||
@ -324,7 +342,7 @@ int credssp_client_authenticate(rdpCredssp* credssp)
|
||||
return -1;
|
||||
|
||||
#ifdef WITH_DEBUG_CREDSSP
|
||||
printf("Receiving Authentication Token\n");
|
||||
printf("Receiving Authentication Token (%d)\n", credssp->negoToken.cbBuffer);
|
||||
winpr_HexDump(credssp->negoToken.pvBuffer, credssp->negoToken.cbBuffer);
|
||||
#endif
|
||||
|
||||
@ -398,7 +416,7 @@ int credssp_server_authenticate(rdpCredssp* credssp)
|
||||
if (credssp_ntlm_server_init(credssp) == 0)
|
||||
return 0;
|
||||
|
||||
#ifdef NATIVE_SSPI
|
||||
#ifdef WITH_NATIVE_SSPI
|
||||
{
|
||||
HMODULE hSSPI;
|
||||
INIT_SECURITY_INTERFACE InitSecurityInterface;
|
||||
@ -439,9 +457,9 @@ int credssp_server_authenticate(rdpCredssp* credssp)
|
||||
have_context = false;
|
||||
have_input_buffer = false;
|
||||
have_pub_key_auth = false;
|
||||
memset(&input_buffer, 0, sizeof(SecBuffer));
|
||||
memset(&output_buffer, 0, sizeof(SecBuffer));
|
||||
memset(&credssp->ContextSizes, 0, sizeof(SecPkgContext_Sizes));
|
||||
ZeroMemory(&input_buffer, sizeof(SecBuffer));
|
||||
ZeroMemory(&output_buffer, sizeof(SecBuffer));
|
||||
ZeroMemory(&credssp->ContextSizes, sizeof(SecPkgContext_Sizes));
|
||||
|
||||
fContextReq = ASC_REQ_REPLAY_DETECT | ASC_REQ_SEQUENCE_DETECT |
|
||||
ASC_REQ_CONFIDENTIALITY | ASC_REQ_DELEGATE;
|
||||
@ -472,6 +490,12 @@ int credssp_server_authenticate(rdpCredssp* credssp)
|
||||
p_buffer->pvBuffer = credssp->negoToken.pvBuffer;
|
||||
p_buffer->cbBuffer = credssp->negoToken.cbBuffer;
|
||||
|
||||
if (credssp->negoToken.cbBuffer < 1)
|
||||
{
|
||||
printf("CredSSP: invalid negoToken!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
output_buffer_desc.ulVersion = SECBUFFER_VERSION;
|
||||
output_buffer_desc.cBuffers = 1;
|
||||
output_buffer_desc.pBuffers = &output_buffer;
|
||||
@ -688,15 +712,15 @@ int credssp_skip_ts_password_creds(rdpCredssp* credssp)
|
||||
int length;
|
||||
int ts_password_creds_length = 0;
|
||||
|
||||
length = ber_skip_octet_string(credssp->identity.DomainLength);
|
||||
length = ber_skip_octet_string(credssp->identity.DomainLength * 2);
|
||||
length += ber_skip_contextual_tag(length);
|
||||
ts_password_creds_length += length;
|
||||
|
||||
length = ber_skip_octet_string(credssp->identity.UserLength);
|
||||
length = ber_skip_octet_string(credssp->identity.UserLength * 2);
|
||||
length += ber_skip_contextual_tag(length);
|
||||
ts_password_creds_length += length;
|
||||
|
||||
length = ber_skip_octet_string(credssp->identity.PasswordLength);
|
||||
length = ber_skip_octet_string(credssp->identity.PasswordLength * 2);
|
||||
length += ber_skip_contextual_tag(length);
|
||||
ts_password_creds_length += length;
|
||||
|
||||
@ -719,6 +743,7 @@ void credssp_read_ts_password_creds(rdpCredssp* credssp, STREAM* s)
|
||||
credssp->identity.Domain = (UINT16*) malloc(length);
|
||||
CopyMemory(credssp->identity.Domain, s->p, credssp->identity.DomainLength);
|
||||
stream_seek(s, credssp->identity.DomainLength);
|
||||
credssp->identity.DomainLength /= 2;
|
||||
|
||||
/* [1] userName (OCTET STRING) */
|
||||
ber_read_contextual_tag(s, 1, &length, true);
|
||||
@ -727,6 +752,7 @@ void credssp_read_ts_password_creds(rdpCredssp* credssp, STREAM* s)
|
||||
credssp->identity.User = (UINT16*) malloc(length);
|
||||
CopyMemory(credssp->identity.User, s->p, credssp->identity.UserLength);
|
||||
stream_seek(s, credssp->identity.UserLength);
|
||||
credssp->identity.UserLength /= 2;
|
||||
|
||||
/* [2] password (OCTET STRING) */
|
||||
ber_read_contextual_tag(s, 2, &length, true);
|
||||
@ -735,6 +761,7 @@ void credssp_read_ts_password_creds(rdpCredssp* credssp, STREAM* s)
|
||||
credssp->identity.Password = (UINT16*) malloc(length);
|
||||
CopyMemory(credssp->identity.Password, s->p, credssp->identity.PasswordLength);
|
||||
stream_seek(s, credssp->identity.PasswordLength);
|
||||
credssp->identity.PasswordLength /= 2;
|
||||
}
|
||||
|
||||
void credssp_write_ts_password_creds(rdpCredssp* credssp, STREAM* s)
|
||||
@ -748,16 +775,16 @@ void credssp_write_ts_password_creds(rdpCredssp* credssp, STREAM* s)
|
||||
ber_write_sequence_tag(s, length);
|
||||
|
||||
/* [0] domainName (OCTET STRING) */
|
||||
ber_write_contextual_tag(s, 0, credssp->identity.DomainLength + 2, true);
|
||||
ber_write_octet_string(s, (BYTE*) credssp->identity.Domain, credssp->identity.DomainLength);
|
||||
ber_write_contextual_tag(s, 0, credssp->identity.DomainLength * 2 + 2, true);
|
||||
ber_write_octet_string(s, (BYTE*) credssp->identity.Domain, credssp->identity.DomainLength * 2);
|
||||
|
||||
/* [1] userName (OCTET STRING) */
|
||||
ber_write_contextual_tag(s, 1, credssp->identity.UserLength + 2, true);
|
||||
ber_write_octet_string(s, (BYTE*) credssp->identity.User, credssp->identity.UserLength);
|
||||
ber_write_contextual_tag(s, 1, credssp->identity.UserLength * 2 + 2, true);
|
||||
ber_write_octet_string(s, (BYTE*) credssp->identity.User, credssp->identity.UserLength * 2);
|
||||
|
||||
/* [2] password (OCTET STRING) */
|
||||
ber_write_contextual_tag(s, 2, credssp->identity.PasswordLength + 2, true);
|
||||
ber_write_octet_string(s, (BYTE*) credssp->identity.Password, credssp->identity.PasswordLength);
|
||||
ber_write_contextual_tag(s, 2, credssp->identity.PasswordLength * 2 + 2, true);
|
||||
ber_write_octet_string(s, (BYTE*) credssp->identity.Password, credssp->identity.PasswordLength * 2);
|
||||
}
|
||||
|
||||
int credssp_skip_ts_credentials(rdpCredssp* credssp)
|
||||
@ -1039,12 +1066,14 @@ int credssp_recv(rdpCredssp* credssp)
|
||||
int status;
|
||||
UINT32 version;
|
||||
|
||||
s = stream_new(2048);
|
||||
status = tls_read(credssp->tls, s->data, stream_get_left(s));
|
||||
s = stream_new(4096);
|
||||
|
||||
status = tls_read_all(credssp->tls, s->p, stream_get_left(s));
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
stream_free(s) ;
|
||||
printf("credssp_recv() error: %d\n", status);
|
||||
stream_free(s);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,6 @@ static void tls_free_certificate(CryptoCert cert)
|
||||
xfree(cert);
|
||||
}
|
||||
|
||||
|
||||
boolean tls_connect(rdpTls* tls)
|
||||
{
|
||||
CryptoCert cert;
|
||||
@ -116,7 +115,8 @@ boolean tls_connect(rdpTls* tls)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!tls_verify_certificate(tls, cert, tls->settings->hostname)) {
|
||||
if (!tls_verify_certificate(tls, cert, tls->settings->hostname))
|
||||
{
|
||||
printf("tls_connect: certificate not trusted, aborting.\n");
|
||||
tls_disconnect(tls);
|
||||
tls_free_certificate(cert);
|
||||
@ -188,12 +188,29 @@ boolean tls_accept(rdpTls* tls, const char* cert_file, const char* privatekey_fi
|
||||
return false;
|
||||
}
|
||||
|
||||
connection_status = SSL_accept(tls->ssl);
|
||||
|
||||
if (connection_status <= 0)
|
||||
while (1)
|
||||
{
|
||||
if (tls_print_error("SSL_accept", tls->ssl, connection_status))
|
||||
return false;
|
||||
connection_status = SSL_accept(tls->ssl);
|
||||
|
||||
if (connection_status <= 0)
|
||||
{
|
||||
switch (SSL_get_error(tls->ssl, connection_status))
|
||||
{
|
||||
case SSL_ERROR_WANT_READ:
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
break;
|
||||
|
||||
default:
|
||||
if (tls_print_error("SSL_accept", tls->ssl, connection_status))
|
||||
return false;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf("TLS connection accepted\n");
|
||||
@ -232,6 +249,19 @@ int tls_read(rdpTls* tls, uint8* data, int length)
|
||||
return status;
|
||||
}
|
||||
|
||||
int tls_read_all(rdpTls* tls, uint8* data, int length)
|
||||
{
|
||||
int status;
|
||||
|
||||
do
|
||||
{
|
||||
status = tls_read(tls, data, length);
|
||||
}
|
||||
while (status == 0);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int tls_write(rdpTls* tls, uint8* data, int length)
|
||||
{
|
||||
int status;
|
||||
@ -298,11 +328,11 @@ boolean tls_print_error(char* func, SSL* connection, int value)
|
||||
return true;
|
||||
|
||||
case SSL_ERROR_WANT_READ:
|
||||
printf("SSL_ERROR_WANT_READ\n");
|
||||
printf("%s: SSL_ERROR_WANT_READ\n", func);
|
||||
return false;
|
||||
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
printf("SSL_ERROR_WANT_WRITE\n");
|
||||
printf("%s: SSL_ERROR_WANT_WRITE\n", func);
|
||||
return false;
|
||||
|
||||
case SSL_ERROR_SYSCALL:
|
||||
|
@ -32,4 +32,6 @@ if(NOT WIN32)
|
||||
|
||||
# Build Server Channels library
|
||||
add_subdirectory(channels)
|
||||
else()
|
||||
add_subdirectory(Windows)
|
||||
endif()
|
||||
|
26
server/Windows/CMakeLists.txt
Normal file
26
server/Windows/CMakeLists.txt
Normal file
@ -0,0 +1,26 @@
|
||||
# FreeRDP: A Remote Desktop Protocol Client
|
||||
# FreeRDP Windows Server cmake build script
|
||||
#
|
||||
# Copyright 2011 O.S. Systems Software Ltda.
|
||||
# Copyright 2011 Otavio Salvador <otavio@ossystems.com.br>
|
||||
# Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
add_executable(wfreerdp-server
|
||||
wfreerdp.c)
|
||||
|
||||
target_link_libraries(wfreerdp-server freerdp-core)
|
||||
target_link_libraries(wfreerdp-server freerdp-utils)
|
||||
target_link_libraries(wfreerdp-server freerdp-codec)
|
||||
target_link_libraries(wfreerdp-server freerdp-channels)
|
17
server/Windows/server.crt
Normal file
17
server/Windows/server.crt
Normal file
@ -0,0 +1,17 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICyzCCAbOgAwIBAgIJANbqtAWwlQZuMA0GCSqGSIb3DQEBBQUAMBIxEDAOBgNV
|
||||
BAMTB0ZyZWVSRFAwHhcNMDkxMDI5MDA0MTQ5WhcNMDkxMTI4MDA0MTQ5WjASMRAw
|
||||
DgYDVQQDEwdGcmVlUkRQMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
|
||||
q7mxFgRbS2FYJZX7BzpNd4T/n4nEVDBY6YaObLjGpaB1TptzXTcmfDrDslTGwcEY
|
||||
hTFAC4ZvY6yOURExqbph4LSgvkoa6J722RjVPfshGa4mlh2SXvTiaV26VPPxddGb
|
||||
o6fbs2u029lbtBlpIVbhx5RN9vstNkll26oSZ6wfEdBNHQJLd2SU4ItWHj8zjz1f
|
||||
eGxjgChHihUlwcBYKDJsKFkzHZmLrMgB37KsGlXi/WV+eEsjgvz4yP7I3TL8+GsN
|
||||
MjV8fRGVEKTbKSmgunO67d5u+IaqUQb0Ad1ha1jzDQ+a6hdymrulJSIhoOVfKkwi
|
||||
ptTe43FgwxVRIygJP9HjHQIDAQABoyQwIjATBgNVHSUEDDAKBggrBgEFBQcDATAL
|
||||
BgNVHQ8EBAMCBDAwDQYJKoZIhvcNAQEFBQADggEBAIOdEDhOX2kbl02znltd9hCr
|
||||
nV4kRPKm979RKwBNkrEuwYSlcsjAHg5MZ5itH3wFOUo2s5pjt7/vMOAg+6rOBbIa
|
||||
nqr22/gKBtOmuaJLG1yjxDC2vfez7f3B26pKgxa/krM8oxiFdT9n8QbdxdkN7/D9
|
||||
3RLU/aCfgrMzXxRus7eq3kR00jnSs6ggnAfE1E9gric3vFgr1wCzdcriRXmXDfUb
|
||||
hRq+4VG+ZWk16TwCofV5GVU39XWCv5HNO2swAdjkNXgI5e3tQbV3wWLZLqqYzBco
|
||||
iWulAXtoCGmE81+u1Ms7hLLzpXitLZSGPu1r+sDdkKPLCmOvkAaljDQ4nBz7fIA=
|
||||
-----END CERTIFICATE-----
|
27
server/Windows/server.key
Normal file
27
server/Windows/server.key
Normal file
@ -0,0 +1,27 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEogIBAAKCAQEAq7mxFgRbS2FYJZX7BzpNd4T/n4nEVDBY6YaObLjGpaB1Tptz
|
||||
XTcmfDrDslTGwcEYhTFAC4ZvY6yOURExqbph4LSgvkoa6J722RjVPfshGa4mlh2S
|
||||
XvTiaV26VPPxddGbo6fbs2u029lbtBlpIVbhx5RN9vstNkll26oSZ6wfEdBNHQJL
|
||||
d2SU4ItWHj8zjz1feGxjgChHihUlwcBYKDJsKFkzHZmLrMgB37KsGlXi/WV+eEsj
|
||||
gvz4yP7I3TL8+GsNMjV8fRGVEKTbKSmgunO67d5u+IaqUQb0Ad1ha1jzDQ+a6hdy
|
||||
mrulJSIhoOVfKkwiptTe43FgwxVRIygJP9HjHQIDAQABAoIBAAVv5K54xtc1JtBR
|
||||
1lfdPbSqDlnjx8aOnVIPg5TnqMp3sR8jBt0NsPc/+RA9ZOmfjoIxFAEJaZ9zSDJC
|
||||
5BqmnxC5R1mfCQkSd2haQ+4pdFvWyrv4Bblh8YU6hXrJGn0LfO0KlIcywtAvKpsi
|
||||
LtTyZkWmaW2HeF/+pO32jYygw38R1wd8Tl6GwjOXwTF6lFACJXOT4YAzcfp3FKSB
|
||||
AiKBIGuMzozoSND7KPFNRrhGhNumJpdS5A8Fb8D2c/ZMv6Cq5IbwOgTfKun+Bz+s
|
||||
mFbnzeb1uWRqQbsVXOBBW/zHfuG3SU5qeZsaAyuu4DTy+LE1oAHF9uhBSHuT5C6i
|
||||
vCJ8A8ECgYEA1iaOmiEJYBrs25iAc4SjCKqhY0mwR3wtu3I06vmgUoML5fhPMv36
|
||||
SvYQIqDyNw3p7TE6mZtw9+G+kK3PqhuJhogwSwg0a6o51RdKnhXH3/68oNWtKCLC
|
||||
1AmR8q/Gd3FwAR3b49CuOIZ9uOiJrc/ejzKdFEJTDR1/TX1frWfZznECgYEAzUiz
|
||||
XxFf7YrGel7JgmfRD2eZRYngOoteFlg5Tee42UjeAY2Pt2aiDLk+2TqQEdI9+Xg7
|
||||
LcFdBqcSNd8bh33xSzgNthIkX+lTDzx0SmKGfyxfFBJcY8nzsLvvnNt3YeuMeaJQ
|
||||
CPszwoZ0jcD46jTCjbrKhaLyEWmUkDp1O71NTW0CgYAXKF49Xpsz8FVyvcAOPeaf
|
||||
dkwzf3F3mX8ciRId4taqdY9g1AREgGCDoK5IAF2RBIkqZCtxFvUVaS0BWjpdq9Ko
|
||||
YKvQQVfh2KueVoF0LOjLWTGutsydzXyCD3Lf6pAstHCnPkJcFWHxrOGFkGfrCtKH
|
||||
a7K+0RlIDsuIZqllCBjukQKBgA31+MTpYJW+D1t5IMkumEgs6n6RLt+sZLyuSU9k
|
||||
B+03CGogn3qAj1rAKmcJlYywuKhDpfqpoNL3/8QMJUokpYlRCZWtTC39pzltCheY
|
||||
9b6mXNz3lrLupBUL4vLO9iKBq28GO90wgEelbz3ItuTuq6CJ6IYIG+BVRtY8M4bZ
|
||||
i+1NAoGANXZjYnJYDnh8Je9SDxDSc5byzK7ddkQoId64RCIfNHqNKH63P81vjgnH
|
||||
YBIPtagY75ZVVNxujCF7m8Rety+d8tEFwfQKDin2EVI7PD2rOJra385/izp7HuBR
|
||||
vqxvLzG9Xv3cNOU2l7PttVw4Pa2i5E37atKi3V3Zp2kMW+KaKPQ=
|
||||
-----END RSA PRIVATE KEY-----
|
289
server/Windows/wfreerdp.c
Normal file
289
server/Windows/wfreerdp.c
Normal file
@ -0,0 +1,289 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Client
|
||||
* FreeRDP Windows Server
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <winpr/windows.h>
|
||||
#include <freerdp/constants.h>
|
||||
#include <freerdp/utils/sleep.h>
|
||||
#include <freerdp/utils/memory.h>
|
||||
#include <freerdp/utils/thread.h>
|
||||
#include <freerdp/codec/rfx.h>
|
||||
#include <freerdp/codec/nsc.h>
|
||||
#include <freerdp/listener.h>
|
||||
|
||||
HANDLE g_done_event;
|
||||
int g_thread_count = 0;
|
||||
|
||||
struct wf_peer_context
|
||||
{
|
||||
rdpContext _p;
|
||||
boolean activated;
|
||||
};
|
||||
typedef struct wf_peer_context wfPeerContext;
|
||||
|
||||
void wf_peer_context_new(freerdp_peer* client, wfPeerContext* context)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void wf_peer_context_free(freerdp_peer* client, wfPeerContext* context)
|
||||
{
|
||||
if (context)
|
||||
{
|
||||
xfree(context);
|
||||
}
|
||||
}
|
||||
|
||||
static void wf_peer_init(freerdp_peer* client)
|
||||
{
|
||||
client->context_size = sizeof(wfPeerContext);
|
||||
client->ContextNew = (psPeerContextNew) wf_peer_context_new;
|
||||
client->ContextFree = (psPeerContextFree) wf_peer_context_free;
|
||||
freerdp_peer_context_new(client);
|
||||
}
|
||||
|
||||
boolean wf_peer_post_connect(freerdp_peer* client)
|
||||
{
|
||||
wfPeerContext* context = (wfPeerContext*) client->context;
|
||||
|
||||
/**
|
||||
* This callback is called when the entire connection sequence is done, i.e. we've received the
|
||||
* Font List PDU from the client and sent out the Font Map PDU.
|
||||
* The server may start sending graphics output and receiving keyboard/mouse input after this
|
||||
* callback returns.
|
||||
*/
|
||||
|
||||
printf("Client %s is activated (osMajorType %d osMinorType %d)", client->local ? "(local)" : client->hostname,
|
||||
client->settings->os_major_type, client->settings->os_minor_type);
|
||||
|
||||
if (client->settings->autologon)
|
||||
{
|
||||
printf(" and wants to login automatically as %s\\%s",
|
||||
client->settings->domain ? client->settings->domain : "",
|
||||
client->settings->username);
|
||||
|
||||
/* A real server may perform OS login here if NLA is not executed previously. */
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf("Client requested desktop: %dx%dx%d\n",
|
||||
client->settings->width, client->settings->height, client->settings->color_depth);
|
||||
|
||||
/* A real server should tag the peer as activated here and start sending updates in main loop. */
|
||||
|
||||
/* Return false here would stop the execution of the peer mainloop. */
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean wf_peer_activate(freerdp_peer* client)
|
||||
{
|
||||
wfPeerContext* context = (wfPeerContext*) client->context;
|
||||
|
||||
context->activated = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void wf_peer_synchronize_event(rdpInput* input, uint32 flags)
|
||||
{
|
||||
printf("Client sent a synchronize event (flags:0x%X)\n", flags);
|
||||
}
|
||||
|
||||
void wf_peer_keyboard_event(rdpInput* input, uint16 flags, uint16 code)
|
||||
{
|
||||
freerdp_peer* client = input->context->peer;
|
||||
rdpUpdate* update = client->update;
|
||||
wfPeerContext* context = (wfPeerContext*) input->context;
|
||||
|
||||
printf("Client sent a keyboard event (flags:0x%X code:0x%X)\n", flags, code);
|
||||
|
||||
if ((flags & 0x4000) && code == 0x1F) /* 's' key */
|
||||
{
|
||||
if (client->settings->width != 800)
|
||||
{
|
||||
client->settings->width = 800;
|
||||
client->settings->height = 600;
|
||||
}
|
||||
else
|
||||
{
|
||||
client->settings->width = 640;
|
||||
client->settings->height = 480;
|
||||
}
|
||||
update->DesktopResize(update->context);
|
||||
context->activated = false;
|
||||
}
|
||||
else if ((flags & 0x4000) && code == 0x2D) /* 'x' key */
|
||||
{
|
||||
client->Close(client);
|
||||
}
|
||||
}
|
||||
|
||||
void wf_peer_unicode_keyboard_event(rdpInput* input, uint16 flags, uint16 code)
|
||||
{
|
||||
printf("Client sent a unicode keyboard event (flags:0x%X code:0x%X)\n", flags, code);
|
||||
}
|
||||
|
||||
void wf_peer_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y)
|
||||
{
|
||||
printf("Client sent a mouse event (flags:0x%X pos:%d,%d)\n", flags, x, y);
|
||||
}
|
||||
|
||||
void wf_peer_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y)
|
||||
{
|
||||
printf("Client sent an extended mouse event (flags:0x%X pos:%d,%d)\n", flags, x, y);
|
||||
}
|
||||
|
||||
static DWORD WINAPI wf_peer_main_loop(LPVOID lpParam)
|
||||
{
|
||||
int rcount;
|
||||
void* rfds[32];
|
||||
wfPeerContext* context;
|
||||
freerdp_peer* client = (freerdp_peer*) lpParam;
|
||||
|
||||
memset(rfds, 0, sizeof(rfds));
|
||||
|
||||
wf_peer_init(client);
|
||||
|
||||
/* Initialize the real server settings here */
|
||||
client->settings->cert_file = xstrdup("server.crt");
|
||||
client->settings->privatekey_file = xstrdup("server.key");
|
||||
|
||||
client->settings->nla_security = true;
|
||||
client->settings->tls_security = false;
|
||||
client->settings->rdp_security = false;
|
||||
|
||||
client->PostConnect = wf_peer_post_connect;
|
||||
client->Activate = wf_peer_activate;
|
||||
|
||||
client->input->SynchronizeEvent = wf_peer_synchronize_event;
|
||||
client->input->KeyboardEvent = wf_peer_keyboard_event;
|
||||
client->input->UnicodeKeyboardEvent = wf_peer_unicode_keyboard_event;
|
||||
client->input->MouseEvent = wf_peer_mouse_event;
|
||||
client->input->ExtendedMouseEvent = wf_peer_extended_mouse_event;
|
||||
|
||||
client->Initialize(client);
|
||||
context = (wfPeerContext*) client->context;
|
||||
|
||||
printf("We've got a client %s\n", client->local ? "(local)" : client->hostname);
|
||||
|
||||
while (1)
|
||||
{
|
||||
rcount = 0;
|
||||
|
||||
if (client->GetFileDescriptor(client, rfds, &rcount) != true)
|
||||
{
|
||||
printf("Failed to get FreeRDP file descriptor\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (client->CheckFileDescriptor(client) != true)
|
||||
{
|
||||
printf("Failed to check FreeRDP file descriptor\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf("Client %s disconnected.\n", client->local ? "(local)" : client->hostname);
|
||||
|
||||
client->Disconnect(client);
|
||||
freerdp_peer_context_free(client);
|
||||
freerdp_peer_free(client);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void wf_peer_accepted(freerdp_listener* instance, freerdp_peer* client)
|
||||
{
|
||||
/* start peer main loop thread */
|
||||
|
||||
if (CreateThread(NULL, 0, wf_peer_main_loop, client, 0, NULL) != 0)
|
||||
g_thread_count++;
|
||||
}
|
||||
|
||||
static void wf_server_main_loop(freerdp_listener* instance)
|
||||
{
|
||||
int rcount;
|
||||
void* rfds[32];
|
||||
|
||||
memset(rfds, 0, sizeof(rfds));
|
||||
|
||||
while (1)
|
||||
{
|
||||
rcount = 0;
|
||||
|
||||
if (instance->GetFileDescriptor(instance, rfds, &rcount) != true)
|
||||
{
|
||||
printf("Failed to get FreeRDP file descriptor\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (instance->CheckFileDescriptor(instance) != true)
|
||||
{
|
||||
printf("Failed to check FreeRDP file descriptor\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
instance->Close(instance);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int port = 3389;
|
||||
WSADATA wsa_data;
|
||||
freerdp_listener* instance;
|
||||
|
||||
instance = freerdp_listener_new();
|
||||
|
||||
instance->PeerAccepted = wf_peer_accepted;
|
||||
|
||||
if (WSAStartup(0x101, &wsa_data) != 0)
|
||||
return 1;
|
||||
|
||||
g_done_event = CreateEvent(0, 1, 0, 0);
|
||||
|
||||
if (argc == 2)
|
||||
port = atoi(argv[1]);
|
||||
|
||||
/* Open the server socket and start listening. */
|
||||
|
||||
if (instance->Open(instance, NULL, port))
|
||||
{
|
||||
/* Entering the server main loop. In a real server the listener can be run in its own thread. */
|
||||
wf_server_main_loop(instance);
|
||||
}
|
||||
|
||||
if (g_thread_count > 0)
|
||||
WaitForSingleObject(g_done_event, INFINITE);
|
||||
else
|
||||
MessageBox(GetConsoleWindow(),
|
||||
L"Failed to start wfreerdp-server.\n\nPlease check the debug output.",
|
||||
L"FreeRDP Error", MB_ICONSTOP);
|
||||
|
||||
WSACleanup();
|
||||
|
||||
freerdp_listener_free(instance);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
3
winpr/.gitignore
vendored
Normal file
3
winpr/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
tools/hash/winpr-hash
|
||||
tools/reg/winpr-reg
|
||||
|
@ -19,8 +19,13 @@
|
||||
|
||||
add_subdirectory(crt)
|
||||
add_subdirectory(utils)
|
||||
add_subdirectory(heap)
|
||||
add_subdirectory(handle)
|
||||
add_subdirectory(synch)
|
||||
add_subdirectory(bcrypt)
|
||||
add_subdirectory(rpc)
|
||||
add_subdirectory(sspi)
|
||||
add_subdirectory(registry)
|
||||
|
||||
add_subdirectory(tools)
|
||||
|
||||
|
@ -24,36 +24,6 @@
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
HANDLE GetProcessHeap(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LPVOID HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes)
|
||||
{
|
||||
LPVOID lpMem = NULL;
|
||||
|
||||
if (dwFlags & HEAP_ZERO_MEMORY)
|
||||
lpMem = calloc(1, dwBytes);
|
||||
else
|
||||
lpMem = malloc(dwBytes);
|
||||
|
||||
return lpMem;
|
||||
}
|
||||
|
||||
LPVOID HeapReAlloc(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, SIZE_T dwBytes)
|
||||
{
|
||||
LPVOID lpNewMem;
|
||||
|
||||
lpNewMem = realloc(lpMem, dwBytes);
|
||||
|
||||
return lpNewMem;
|
||||
}
|
||||
|
||||
BOOL HeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem)
|
||||
{
|
||||
free(lpMem);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -41,9 +41,9 @@ char* _strdup(const char* strSource)
|
||||
return strDestination;
|
||||
}
|
||||
|
||||
wchar_t* _wcsdup(const wchar_t* strSource)
|
||||
WCHAR* _wcsdup(const WCHAR* strSource)
|
||||
{
|
||||
wchar_t* strDestination;
|
||||
WCHAR* strDestination;
|
||||
|
||||
if (strSource == NULL)
|
||||
return NULL;
|
||||
@ -56,7 +56,7 @@ wchar_t* _wcsdup(const wchar_t* strSource)
|
||||
if (strDestination != NULL)
|
||||
wcscpy(strDestination, strSource);
|
||||
#else
|
||||
strDestination = wcsdup(strSource);
|
||||
strDestination = (WCHAR*) wcsdup((wchar_t*) strSource);
|
||||
#endif
|
||||
|
||||
if (strDestination == NULL)
|
||||
@ -505,4 +505,40 @@ int WideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int
|
||||
return conv_out_len;
|
||||
}
|
||||
|
||||
int lstrlenA(LPCSTR lpString)
|
||||
{
|
||||
return strlen(lpString);
|
||||
}
|
||||
|
||||
int lstrlenW(LPCWSTR lpString)
|
||||
{
|
||||
LPWSTR p;
|
||||
|
||||
if (!lpString)
|
||||
return 0;
|
||||
|
||||
p = (LPWSTR) lpString;
|
||||
|
||||
while (*p)
|
||||
p++;
|
||||
|
||||
return p - lpString;
|
||||
}
|
||||
|
||||
int lstrcmpA(LPCSTR lpString1, LPCSTR lpString2)
|
||||
{
|
||||
return strcmp(lpString1, lpString2);
|
||||
}
|
||||
|
||||
int lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
|
||||
{
|
||||
while (*lpString1 && (*lpString1 == *lpString2))
|
||||
{
|
||||
lpString1++;
|
||||
lpString2++;
|
||||
}
|
||||
|
||||
return *lpString1 - *lpString2;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
28
winpr/handle/CMakeLists.txt
Normal file
28
winpr/handle/CMakeLists.txt
Normal file
@ -0,0 +1,28 @@
|
||||
# WinPR: Windows Portable Runtime
|
||||
# libwinpr-handle cmake build script
|
||||
#
|
||||
# Copyright 2011 O.S. Systems Software Ltda.
|
||||
# Copyright 2011 Otavio Salvador <otavio@ossystems.com.br>
|
||||
# Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
set(WINPR_HANDLE_SRCS
|
||||
handle.c)
|
||||
|
||||
add_library(winpr-handle ${WINPR_HANDLE_SRCS})
|
||||
|
||||
set_target_properties(winpr-handle PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib")
|
||||
|
||||
install(TARGETS winpr-handle DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
|
66
winpr/handle/handle.c
Normal file
66
winpr/handle/handle.c
Normal file
@ -0,0 +1,66 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Handle Management
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <winpr/handle.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
#if defined __APPLE__
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <mach/mach.h>
|
||||
#include <mach/semaphore.h>
|
||||
#include <mach/task.h>
|
||||
#define winpr_sem_t semaphore_td
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#define winpr_sem_t sem_t
|
||||
#endif
|
||||
|
||||
BOOL CloseHandle(HANDLE hObject)
|
||||
{
|
||||
#if defined __APPLE__
|
||||
semaphore_destroy(mach_task_self(), *((winpr_sem_t*) hObject));
|
||||
#else
|
||||
sem_destroy((winpr_sem_t*) hObject);
|
||||
#endif
|
||||
|
||||
free(hObject);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
BOOL DuplicateHandle(HANDLE hSourceProcessHandle, HANDLE hSourceHandle, HANDLE hTargetProcessHandle,
|
||||
LPHANDLE lpTargetHandle, DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwOptions)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
BOOL GetHandleInformation(HANDLE hObject, LPDWORD lpdwFlags)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
BOOL SetHandleInformation(HANDLE hObject, DWORD dwMask, DWORD dwFlags)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
28
winpr/heap/CMakeLists.txt
Normal file
28
winpr/heap/CMakeLists.txt
Normal file
@ -0,0 +1,28 @@
|
||||
# WinPR: Windows Portable Runtime
|
||||
# libwinpr-heap cmake build script
|
||||
#
|
||||
# Copyright 2011 O.S. Systems Software Ltda.
|
||||
# Copyright 2011 Otavio Salvador <otavio@ossystems.com.br>
|
||||
# Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
set(WINPR_HEAP_SRCS
|
||||
heap.c)
|
||||
|
||||
add_library(winpr-heap ${WINPR_HEAP_SRCS})
|
||||
|
||||
set_target_properties(winpr-heap PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib")
|
||||
|
||||
install(TARGETS winpr-heap DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
|
59
winpr/heap/heap.c
Normal file
59
winpr/heap/heap.c
Normal file
@ -0,0 +1,59 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Memory Allocation
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <winpr/crt.h>
|
||||
|
||||
/* Memory Allocation: http://msdn.microsoft.com/en-us/library/hk1k7x6x.aspx */
|
||||
/* Memory Management Functions: http://msdn.microsoft.com/en-us/library/windows/desktop/aa366781/ */
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
HANDLE GetProcessHeap(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LPVOID HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes)
|
||||
{
|
||||
LPVOID lpMem = NULL;
|
||||
|
||||
if (dwFlags & HEAP_ZERO_MEMORY)
|
||||
lpMem = calloc(1, dwBytes);
|
||||
else
|
||||
lpMem = malloc(dwBytes);
|
||||
|
||||
return lpMem;
|
||||
}
|
||||
|
||||
LPVOID HeapReAlloc(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, SIZE_T dwBytes)
|
||||
{
|
||||
LPVOID lpNewMem;
|
||||
|
||||
lpNewMem = realloc(lpMem, dwBytes);
|
||||
|
||||
return lpNewMem;
|
||||
}
|
||||
|
||||
BOOL HeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem)
|
||||
{
|
||||
free(lpMem);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
@ -17,32 +17,15 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
if(NOT WIN32)
|
||||
set(WITH_REGISTRY_XML true)
|
||||
endif()
|
||||
|
||||
set(WINPR_REGISTRY_SRCS
|
||||
registry_reg.c
|
||||
registry_reg.h
|
||||
registry.c)
|
||||
|
||||
set(WINPR_REGISTRY_XML_SRCS
|
||||
registry_xml.c
|
||||
registry_xml.h)
|
||||
|
||||
if(WITH_REGISTRY_XML)
|
||||
set(WINPR_REGISTRY_SRCS ${WINPR_REGISTRY_SRCS} ${WINPR_REGISTRY_XML_SRCS})
|
||||
endif()
|
||||
|
||||
add_library(winpr-registry ${WINPR_REGISTRY_SRCS})
|
||||
|
||||
set_target_properties(winpr-registry PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib")
|
||||
|
||||
if(WITH_REGISTRY_XML)
|
||||
find_required_package(LibXml2)
|
||||
add_definitions("${LIBXML2_DEFINITIONS}")
|
||||
include_directories(SYSTEM ${LIBXML2_INCLUDE_DIR})
|
||||
target_link_libraries(winpr-registry ${LIBXML2_LIBRARIES})
|
||||
endif()
|
||||
|
||||
target_link_libraries(winpr-registry winpr-utils)
|
||||
|
||||
install(TARGETS winpr-registry DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
|
@ -27,23 +27,29 @@
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
#include "registry_xml.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "registry_reg.h"
|
||||
|
||||
static Reg* instance = NULL;
|
||||
|
||||
static Reg* RegGetInstance()
|
||||
{
|
||||
if (!instance)
|
||||
{
|
||||
instance = reg_open(1);
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
LONG RegCloseKey(HKEY hKey)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
LONG RegConnectRegistryW(LPCWSTR lpMachineName, HKEY hKey, PHKEY phkResult)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
LONG RegConnectRegistryA(LPCSTR lpMachineName, HKEY hKey, PHKEY phkResult)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
LONG RegCopyTreeW(HKEY hKeySrc, LPCWSTR lpSubKey, HKEY hKeyDest)
|
||||
{
|
||||
return 0;
|
||||
@ -66,30 +72,6 @@ LONG RegCreateKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD Reserved, LPSTR lpClass,
|
||||
return 0;
|
||||
}
|
||||
|
||||
LONG RegCreateKeyTransactedW(HKEY hKey, LPCWSTR lpSubKey, DWORD Reserved, LPWSTR lpClass,
|
||||
DWORD dwOptions, REGSAM samDesired, const LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
||||
PHKEY phkResult, LPDWORD lpdwDisposition, HANDLE hTransaction, PVOID pExtendedParemeter)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
LONG RegCreateKeyTransactedA(HKEY hKey, LPCSTR lpSubKey, DWORD Reserved, LPSTR lpClass,
|
||||
DWORD dwOptions, REGSAM samDesired, const LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
||||
PHKEY phkResult, LPDWORD lpdwDisposition, HANDLE hTransaction, PVOID pExtendedParemeter)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
LONG RegDeleteKeyW(HKEY hKey, LPCWSTR lpSubKey)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
LONG RegDeleteKeyA(HKEY hKey, LPCSTR lpSubKey)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
LONG RegDeleteKeyExW(HKEY hKey, LPCWSTR lpSubKey, REGSAM samDesired, DWORD Reserved)
|
||||
{
|
||||
return 0;
|
||||
@ -100,28 +82,6 @@ LONG RegDeleteKeyExA(HKEY hKey, LPCSTR lpSubKey, REGSAM samDesired, DWORD Reserv
|
||||
return 0;
|
||||
}
|
||||
|
||||
LONG RegDeleteKeyTransactedW(HKEY hKey, LPCWSTR lpSubKey, REGSAM samDesired,
|
||||
DWORD Reserved, HANDLE hTransaction, PVOID pExtendedParameter)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
LONG RegDeleteKeyTransactedA(HKEY hKey, LPCSTR lpSubKey, REGSAM samDesired,
|
||||
DWORD Reserved, HANDLE hTransaction, PVOID pExtendedParameter)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
LONG RegDeleteKeyValueW(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpValueName)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
LONG RegDeleteKeyValueA(HKEY hKey, LPCSTR lpSubKey, LPCSTR lpValueName)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
LONG RegDeleteTreeW(HKEY hKey, LPCWSTR lpSubKey)
|
||||
{
|
||||
return 0;
|
||||
@ -142,26 +102,11 @@ LONG RegDeleteValueA(HKEY hKey, LPCSTR lpValueName)
|
||||
return 0;
|
||||
}
|
||||
|
||||
LONG RegDisablePredefinedCache(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
LONG RegDisablePredefinedCacheEx(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
LONG RegDisableReflectionKey(HKEY hBase)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
LONG RegEnableReflectionKey(HKEY hBase)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
LONG RegEnumKeyExW(HKEY hKey, DWORD dwIndex, LPWSTR lpName, LPDWORD lpcName,
|
||||
LPDWORD lpReserved, LPWSTR lpClass, LPDWORD lpcClass, PFILETIME lpftLastWriteTime)
|
||||
{
|
||||
@ -209,6 +154,18 @@ LONG RegGetValueA(HKEY hkey, LPCSTR lpSubKey, LPCSTR lpValue,
|
||||
return 0;
|
||||
}
|
||||
|
||||
LONG RegLoadAppKeyW(LPCWSTR lpFile, PHKEY phkResult,
|
||||
REGSAM samDesired, DWORD dwOptions, DWORD Reserved)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
LONG RegLoadAppKeyA(LPCSTR lpFile, PHKEY phkResult,
|
||||
REGSAM samDesired, DWORD dwOptions, DWORD Reserved)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
LONG RegLoadKeyW(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpFile)
|
||||
{
|
||||
return 0;
|
||||
@ -248,18 +205,25 @@ LONG RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesir
|
||||
|
||||
LONG RegOpenKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
Reg* reg;
|
||||
RegKey* pKey;
|
||||
|
||||
LONG RegOpenKeyTransactedW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions,
|
||||
REGSAM samDesired, PHKEY phkResult, HANDLE hTransaction, PVOID pExtendedParameter)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
reg = RegGetInstance();
|
||||
pKey = reg->root_key->subkeys;
|
||||
|
||||
while (pKey != NULL)
|
||||
{
|
||||
if (strcmp(pKey->subname, lpSubKey) == 0)
|
||||
{
|
||||
*phkResult = pKey;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
pKey = pKey->next;
|
||||
}
|
||||
|
||||
*phkResult = NULL;
|
||||
|
||||
LONG RegOpenKeyTransactedA(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions,
|
||||
REGSAM samDesired, PHKEY phkResult, HANDLE hTransaction, PVOID pExtendedParameter)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -268,11 +232,6 @@ LONG RegOpenUserClassesRoot(HANDLE hToken, DWORD dwOptions, REGSAM samDesired, P
|
||||
return 0;
|
||||
}
|
||||
|
||||
LONG RegOverridePredefKey(HKEY hKey, HKEY hNewHKey)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
LONG RegQueryInfoKeyW(HKEY hKey, LPWSTR lpClass, LPDWORD lpcClass, LPDWORD lpReserved,
|
||||
LPDWORD lpcSubKeys, LPDWORD lpcMaxSubKeyLen, LPDWORD lpcMaxClassLen,
|
||||
LPDWORD lpcValues, LPDWORD lpcMaxValueNameLen, LPDWORD lpcMaxValueLen,
|
||||
@ -289,16 +248,6 @@ LONG RegQueryInfoKeyA(HKEY hKey, LPSTR lpClass, LPDWORD lpcClass, LPDWORD lpRese
|
||||
return 0;
|
||||
}
|
||||
|
||||
LONG RegQueryMultipleValues(HKEY hKey, PVALENT val_list, DWORD num_vals, LPTSTR lpValueBuf, LPDWORD ldwTotsize)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
LONG RegQueryReflectionKey(HKEY hBase, BOOL* bIsReflectionDisabled)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
LONG RegQueryValueExW(HKEY hKey, LPCWSTR lpValueName,
|
||||
LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData)
|
||||
{
|
||||
@ -308,16 +257,52 @@ LONG RegQueryValueExW(HKEY hKey, LPCWSTR lpValueName,
|
||||
LONG RegQueryValueExA(HKEY hKey, LPCSTR lpValueName,
|
||||
LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
Reg* reg;
|
||||
RegKey* key;
|
||||
RegVal* pValue;
|
||||
|
||||
LONG RegReplaceKeyW(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpNewFile, LPCWSTR lpOldFile)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
key = (RegKey*) hKey;
|
||||
reg = RegGetInstance();
|
||||
|
||||
pValue = key->values;
|
||||
|
||||
while (pValue != NULL)
|
||||
{
|
||||
if (strcmp(pValue->name, lpValueName) == 0)
|
||||
{
|
||||
if (pValue->type == REG_DWORD)
|
||||
{
|
||||
DWORD* pData = (DWORD*) lpData;
|
||||
|
||||
if (pData != NULL)
|
||||
{
|
||||
*pData = pValue->data.dword;
|
||||
}
|
||||
|
||||
*lpcbData = sizeof(DWORD);
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
else if (pValue->type == REG_SZ)
|
||||
{
|
||||
int length;
|
||||
char* pData = (char*) lpData;
|
||||
|
||||
length = strlen(pValue->data.string);
|
||||
|
||||
if (pData != NULL)
|
||||
{
|
||||
memcpy(pData, pValue->data.string, length);
|
||||
pData[length] = '\0';
|
||||
}
|
||||
|
||||
*lpcbData = length;
|
||||
}
|
||||
}
|
||||
|
||||
pValue = pValue->next;
|
||||
}
|
||||
|
||||
LONG RegReplaceKeyA(HKEY hKey, LPCSTR lpSubKey, LPCSTR lpNewFile, LPCSTR lpOldFile)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -331,16 +316,6 @@ LONG RegRestoreKeyA(HKEY hKey, LPCSTR lpFile, DWORD dwFlags)
|
||||
return 0;
|
||||
}
|
||||
|
||||
LONG RegSaveKeyW(HKEY hKey, LPCWSTR lpFile, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
LONG RegSaveKeyA(HKEY hKey, LPCSTR lpFile, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
LONG RegSaveKeyExW(HKEY hKey, LPCWSTR lpFile, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD Flags)
|
||||
{
|
||||
return 0;
|
||||
@ -351,16 +326,6 @@ LONG RegSaveKeyExA(HKEY hKey, LPCSTR lpFile, LPSECURITY_ATTRIBUTES lpSecurityAtt
|
||||
return 0;
|
||||
}
|
||||
|
||||
LONG RegSetKeyValueW(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpValueName, DWORD dwType, LPCVOID lpData, DWORD cbData)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
LONG RegSetKeyValueA(HKEY hKey, LPCSTR lpSubKey, LPCSTR lpValueName, DWORD dwType, LPCVOID lpData, DWORD cbData)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
LONG RegSetKeySecurity(HKEY hKey, SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR pSecurityDescriptor)
|
||||
{
|
||||
return 0;
|
||||
|
437
winpr/registry/registry_reg.c
Normal file
437
winpr/registry/registry_reg.c
Normal file
@ -0,0 +1,437 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Windows Registry (.reg file format)
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
|
||||
#include "registry_reg.h"
|
||||
|
||||
#define WINPR_HKLM_HIVE "/etc/winpr/HKLM.reg"
|
||||
|
||||
struct reg_data_type
|
||||
{
|
||||
char* tag;
|
||||
int length;
|
||||
DWORD type;
|
||||
};
|
||||
|
||||
struct reg_data_type REG_DATA_TYPE_TABLE[] =
|
||||
{
|
||||
{ "\"", 1, REG_SZ },
|
||||
{ "dword:", 6, REG_DWORD },
|
||||
{ "str:\"", 5, REG_SZ },
|
||||
{ "str(2):\"", 8, REG_EXPAND_SZ },
|
||||
{ "str(7):\"", 8, REG_MULTI_SZ },
|
||||
{ "hex:", 4, REG_BINARY },
|
||||
{ "hex(2):\"", 8, REG_EXPAND_SZ },
|
||||
{ "hex(7):\"", 8, REG_MULTI_SZ },
|
||||
{ "hex(b):\"", 8, REG_QWORD },
|
||||
{ NULL, 0, 0 }
|
||||
};
|
||||
|
||||
char* REG_DATA_TYPE_STRINGS[] =
|
||||
{
|
||||
"REG_NONE",
|
||||
"REG_SZ",
|
||||
"REG_EXPAND_SZ",
|
||||
"REG_BINARY",
|
||||
"REG_DWORD",
|
||||
"REG_DWORD_BIG_ENDIAN",
|
||||
"REG_LINK",
|
||||
"REG_MULTI_SZ",
|
||||
"REG_RESOURCE_LIST",
|
||||
"REG_FULL_RESOURCE_DESCRIPTOR",
|
||||
"REG_RESOURCE_REQUIREMENTS_LIST",
|
||||
"REG_QWORD"
|
||||
};
|
||||
|
||||
void reg_load_start(Reg* reg)
|
||||
{
|
||||
long int file_size;
|
||||
|
||||
fseek(reg->fp, 0, SEEK_END);
|
||||
file_size = ftell(reg->fp);
|
||||
fseek(reg->fp, 0, SEEK_SET);
|
||||
|
||||
if (file_size < 1)
|
||||
return;
|
||||
|
||||
reg->buffer = (char*) malloc(file_size + 2);
|
||||
|
||||
if (fread(reg->buffer, file_size, 1, reg->fp) != 1)
|
||||
{
|
||||
free(reg->buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
reg->buffer[file_size] = '\n';
|
||||
reg->buffer[file_size + 1] = '\0';
|
||||
|
||||
reg->line = NULL;
|
||||
reg->next_line = strtok(reg->buffer, "\n");
|
||||
}
|
||||
|
||||
void reg_load_finish(Reg* reg)
|
||||
{
|
||||
free(reg->buffer);
|
||||
reg->buffer = NULL;
|
||||
reg->line = NULL;
|
||||
}
|
||||
|
||||
RegVal* reg_load_value(Reg* reg, RegKey* key)
|
||||
{
|
||||
int index;
|
||||
char* p[5];
|
||||
int length;
|
||||
char* name;
|
||||
char* type;
|
||||
char* data;
|
||||
RegVal* value;
|
||||
|
||||
p[0] = reg->line + 1;
|
||||
p[1] = strstr(p[0], "\"=");
|
||||
p[2] = p[1] + 2;
|
||||
type = p[2];
|
||||
|
||||
if (p[2][0] == '"')
|
||||
p[3] = p[2];
|
||||
else
|
||||
p[3] = strchr(p[2], ':');
|
||||
|
||||
data = p[3] + 1;
|
||||
|
||||
length = p[1] - p[0];
|
||||
name = (char*) malloc(length + 1);
|
||||
memcpy(name, p[0], length);
|
||||
name[length] = '\0';
|
||||
|
||||
value = (RegVal*) malloc(sizeof(RegVal));
|
||||
|
||||
value->name = name;
|
||||
value->type = REG_NONE;
|
||||
value->next = value->prev = NULL;
|
||||
|
||||
for (index = 0; REG_DATA_TYPE_TABLE[index].length > 0; index++)
|
||||
{
|
||||
if (strncmp(type, REG_DATA_TYPE_TABLE[index].tag, REG_DATA_TYPE_TABLE[index].length) == 0)
|
||||
{
|
||||
value->type = REG_DATA_TYPE_TABLE[index].type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (value->type == REG_DWORD)
|
||||
{
|
||||
value->data.dword = strtoul(data, NULL, 0);
|
||||
}
|
||||
else if (value->type == REG_SZ)
|
||||
{
|
||||
p[4] = strchr(data, '"');
|
||||
p[4][0] = '\0';
|
||||
value->data.string = _strdup(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("unimplemented format: %s\n", REG_DATA_TYPE_STRINGS[value->type]);
|
||||
}
|
||||
|
||||
if (!key->values)
|
||||
{
|
||||
key->values = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
RegVal* pValue = key->values;
|
||||
|
||||
while (pValue->next != NULL)
|
||||
{
|
||||
pValue = pValue->next;
|
||||
}
|
||||
|
||||
pValue->next = value;
|
||||
value->prev = pValue;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
BOOL reg_load_has_next_line(Reg* reg)
|
||||
{
|
||||
return (reg->next_line != NULL) ? 1 : 0;
|
||||
}
|
||||
|
||||
char* reg_load_get_next_line(Reg* reg)
|
||||
{
|
||||
reg->line = reg->next_line;
|
||||
reg->next_line = strtok(NULL, "\n");
|
||||
reg->line_length = strlen(reg->line);
|
||||
|
||||
return reg->line;
|
||||
}
|
||||
|
||||
char* reg_load_peek_next_line(Reg* reg)
|
||||
{
|
||||
return reg->next_line;
|
||||
}
|
||||
|
||||
void reg_insert_key(Reg* reg, RegKey* key, RegKey* subkey)
|
||||
{
|
||||
char* name;
|
||||
char* path;
|
||||
int length;
|
||||
|
||||
path = _strdup(subkey->name);
|
||||
|
||||
name = strtok(path, "\\");
|
||||
|
||||
while (name != NULL)
|
||||
{
|
||||
if (strcmp(key->name, name) == 0)
|
||||
{
|
||||
length = strlen(name);
|
||||
name += length + 1;
|
||||
subkey->subname = _strdup(name);
|
||||
}
|
||||
|
||||
name = strtok(NULL, "\\");
|
||||
}
|
||||
|
||||
free(path);
|
||||
}
|
||||
|
||||
RegKey* reg_load_key(Reg* reg, RegKey* key)
|
||||
{
|
||||
char* p[2];
|
||||
int length;
|
||||
char* line;
|
||||
RegKey* subkey;
|
||||
|
||||
p[0] = reg->line + 1;
|
||||
p[1] = strrchr(p[0], ']');
|
||||
|
||||
subkey = (RegKey*) malloc(sizeof(RegKey));
|
||||
|
||||
subkey->values = NULL;
|
||||
subkey->prev = subkey->next = NULL;
|
||||
|
||||
length = p[1] - p[0];
|
||||
subkey->name = (char*) malloc(length + 1);
|
||||
memcpy(subkey->name, p[0], length);
|
||||
subkey->name[length] = '\0';
|
||||
|
||||
while (reg_load_has_next_line(reg))
|
||||
{
|
||||
line = reg_load_peek_next_line(reg);
|
||||
|
||||
if (line[0] == '[')
|
||||
break;
|
||||
|
||||
reg_load_get_next_line(reg);
|
||||
|
||||
if (reg->line[0] == '"')
|
||||
{
|
||||
reg_load_value(reg, subkey);
|
||||
}
|
||||
}
|
||||
|
||||
reg_insert_key(reg, key, subkey);
|
||||
|
||||
if (!key->subkeys)
|
||||
{
|
||||
key->subkeys = subkey;
|
||||
}
|
||||
else
|
||||
{
|
||||
RegKey* pKey = key->subkeys;
|
||||
|
||||
while (pKey->next != NULL)
|
||||
{
|
||||
pKey = pKey->next;
|
||||
}
|
||||
|
||||
pKey->next = subkey;
|
||||
subkey->prev = pKey;
|
||||
}
|
||||
|
||||
return subkey;
|
||||
}
|
||||
|
||||
void reg_load(Reg* reg)
|
||||
{
|
||||
reg_load_start(reg);
|
||||
|
||||
while (reg_load_has_next_line(reg))
|
||||
{
|
||||
reg_load_get_next_line(reg);
|
||||
|
||||
if (reg->line[0] == '[')
|
||||
{
|
||||
reg_load_key(reg, reg->root_key);
|
||||
}
|
||||
}
|
||||
|
||||
reg_load_finish(reg);
|
||||
}
|
||||
|
||||
void reg_unload_value(Reg* reg, RegVal* value)
|
||||
{
|
||||
if (value->type == REG_DWORD)
|
||||
{
|
||||
|
||||
}
|
||||
else if (value->type == REG_SZ)
|
||||
{
|
||||
free(value->data.string);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("unimplemented format: %s\n", REG_DATA_TYPE_STRINGS[value->type]);
|
||||
}
|
||||
|
||||
free(value);
|
||||
}
|
||||
|
||||
void reg_unload_key(Reg* reg, RegKey* key)
|
||||
{
|
||||
RegVal* pValue;
|
||||
RegVal* pValueNext;
|
||||
|
||||
pValue = key->values;
|
||||
|
||||
while (pValue != NULL)
|
||||
{
|
||||
pValueNext = pValue->next;
|
||||
reg_unload_value(reg, pValue);
|
||||
pValue = pValueNext;
|
||||
}
|
||||
|
||||
free(key->name);
|
||||
free(key);
|
||||
}
|
||||
|
||||
void reg_unload(Reg* reg)
|
||||
{
|
||||
RegKey* pKey;
|
||||
RegKey* pKeyNext;
|
||||
|
||||
pKey = reg->root_key->subkeys;
|
||||
|
||||
while (pKey != NULL)
|
||||
{
|
||||
pKeyNext = pKey->next;
|
||||
reg_unload_key(reg, pKey);
|
||||
pKey = pKeyNext;
|
||||
}
|
||||
|
||||
free(reg->root_key);
|
||||
}
|
||||
|
||||
Reg* reg_open(BOOL read_only)
|
||||
{
|
||||
Reg* reg;
|
||||
|
||||
reg = (Reg*) malloc(sizeof(Reg));
|
||||
|
||||
if (reg)
|
||||
{
|
||||
reg->read_only = read_only;
|
||||
reg->filename = WINPR_HKLM_HIVE;
|
||||
|
||||
if (reg->read_only)
|
||||
{
|
||||
reg->fp = fopen(reg->filename, "r");
|
||||
}
|
||||
else
|
||||
{
|
||||
reg->fp = fopen(reg->filename, "r+");
|
||||
|
||||
if (!reg->fp)
|
||||
reg->fp = fopen(reg->filename, "w+");
|
||||
}
|
||||
|
||||
reg->root_key = (RegKey*) malloc(sizeof(RegKey));
|
||||
|
||||
reg->root_key->values = NULL;
|
||||
reg->root_key->subkeys = NULL;
|
||||
reg->root_key->name = "HKEY_LOCAL_MACHINE";
|
||||
|
||||
reg_load(reg);
|
||||
}
|
||||
|
||||
return reg;
|
||||
}
|
||||
|
||||
void reg_close(Reg* reg)
|
||||
{
|
||||
if (reg)
|
||||
{
|
||||
reg_unload(reg);
|
||||
fclose(reg->fp);
|
||||
free(reg);
|
||||
}
|
||||
}
|
||||
|
||||
void reg_print_value(Reg* reg, RegVal* value)
|
||||
{
|
||||
printf("\"%s\"=", value->name);
|
||||
|
||||
if (value->type == REG_DWORD)
|
||||
{
|
||||
printf("dword:%08lX\n", value->data.dword);
|
||||
}
|
||||
else if (value->type == REG_SZ)
|
||||
{
|
||||
printf("%s\"\n", value->data.string);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("unimplemented format: %s\n", REG_DATA_TYPE_STRINGS[value->type]);
|
||||
}
|
||||
}
|
||||
|
||||
void reg_print_key(Reg* reg, RegKey* key)
|
||||
{
|
||||
RegVal* pValue;
|
||||
|
||||
pValue = key->values;
|
||||
|
||||
printf("[%s]\n", key->name);
|
||||
|
||||
while (pValue != NULL)
|
||||
{
|
||||
reg_print_value(reg, pValue);
|
||||
pValue = pValue->next;
|
||||
}
|
||||
}
|
||||
|
||||
void reg_print(Reg* reg)
|
||||
{
|
||||
RegKey* pKey;
|
||||
|
||||
pKey = reg->root_key->subkeys;
|
||||
|
||||
while (pKey != NULL)
|
||||
{
|
||||
reg_print_key(reg, pKey);
|
||||
pKey = pKey->next;
|
||||
}
|
||||
}
|
64
winpr/registry/registry_reg.h
Normal file
64
winpr/registry/registry_reg.h
Normal file
@ -0,0 +1,64 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Windows Registry (.reg file format)
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <winpr/registry.h>
|
||||
|
||||
typedef struct _reg Reg;
|
||||
typedef struct _reg_key RegKey;
|
||||
typedef struct _reg_val RegVal;
|
||||
|
||||
struct _reg
|
||||
{
|
||||
FILE* fp;
|
||||
char* line;
|
||||
char* next_line;
|
||||
int line_length;
|
||||
char* buffer;
|
||||
char* filename;
|
||||
BOOL read_only;
|
||||
RegKey* root_key;
|
||||
};
|
||||
|
||||
struct _reg_val
|
||||
{
|
||||
char* name;
|
||||
DWORD type;
|
||||
RegVal* prev;
|
||||
RegVal* next;
|
||||
|
||||
union reg_data
|
||||
{
|
||||
DWORD dword;
|
||||
char* string;
|
||||
} data;
|
||||
};
|
||||
|
||||
struct _reg_key
|
||||
{
|
||||
char* name;
|
||||
DWORD type;
|
||||
RegKey* prev;
|
||||
RegKey* next;
|
||||
|
||||
char* subname;
|
||||
RegVal* values;
|
||||
RegKey* subkeys;
|
||||
};
|
||||
|
||||
Reg* reg_open(BOOL read_only);
|
@ -1,127 +0,0 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Windows Registry
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "registry_xml.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#define PATH_SEPARATOR_STR "/"
|
||||
#define PATH_SEPARATOR_CHR '/'
|
||||
#define HOME_ENV_VARIABLE "HOME"
|
||||
#else
|
||||
#define PATH_SEPARATOR_STR "\\"
|
||||
#define PATH_SEPARATOR_CHR '\\'
|
||||
#define HOME_ENV_VARIABLE "HOME"
|
||||
#endif
|
||||
|
||||
char* construct_path(char* base_path, char* relative_path)
|
||||
{
|
||||
char* path;
|
||||
int length;
|
||||
int base_path_length;
|
||||
int relative_path_length;
|
||||
|
||||
base_path_length = strlen(base_path);
|
||||
relative_path_length = strlen(relative_path);
|
||||
length = base_path_length + relative_path_length + 1;
|
||||
|
||||
path = malloc(length + 1);
|
||||
sprintf(path, "%s" PATH_SEPARATOR_STR "%s", base_path, relative_path);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
char* find_registry_path()
|
||||
{
|
||||
char* path;
|
||||
char* home_path;
|
||||
|
||||
home_path = getenv("HOME");
|
||||
path = construct_path(home_path, "registry.xml");
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
RegistryXml* registry_xml_new()
|
||||
{
|
||||
char* filename;
|
||||
RegistryXml* registry;
|
||||
|
||||
registry = (RegistryXml*) malloc(sizeof(RegistryXml));
|
||||
ZeroMemory(registry, sizeof(RegistryXml));
|
||||
|
||||
filename = find_registry_path();
|
||||
registry->doc = xmlParseFile(filename);
|
||||
|
||||
if (registry->doc == NULL)
|
||||
{
|
||||
fprintf(stderr, "xmlParseFile error\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
registry->node = xmlDocGetRootElement(registry->doc);
|
||||
|
||||
if (registry->node == NULL)
|
||||
{
|
||||
fprintf(stderr, "empty document\n");
|
||||
xmlFreeDoc(registry->doc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (xmlStrcmp(registry->node->name, (const xmlChar*) "registry"))
|
||||
{
|
||||
fprintf(stderr, "document of the wrong type, root node != registry");
|
||||
xmlFreeDoc(registry->doc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
registry->node = registry->node->xmlChildrenNode;
|
||||
|
||||
while (registry->node != NULL)
|
||||
{
|
||||
if ((!xmlStrcmp(registry->node->name, (const xmlChar*) "key")))
|
||||
{
|
||||
//read_registry_key(doc, node, 0);
|
||||
}
|
||||
|
||||
registry->node = registry->node->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static RegistryXml* instance = NULL;
|
||||
|
||||
RegistryXml* registry_xml_open()
|
||||
{
|
||||
if (instance == NULL)
|
||||
instance = registry_xml_new();
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
void registry_xml_close(RegistryXml* registry)
|
||||
{
|
||||
xmlFreeDoc(registry->doc);
|
||||
}
|
@ -50,8 +50,6 @@ if(NOT WITH_NATIVE_SSPI)
|
||||
${WINPR_SSPI_NEGOTIATE_SRCS}
|
||||
${WINPR_SSPI_SCHANNEL_SRCS}
|
||||
${WINPR_SSPI_SRCS})
|
||||
else()
|
||||
add_definitions(-DNATIVE_SSPI)
|
||||
endif()
|
||||
|
||||
add_library(winpr-sspi ${WINPR_SSPI_SRCS})
|
||||
|
@ -251,12 +251,22 @@ const SecPkgInfoA CREDSSP_SecPkgInfoA =
|
||||
"Microsoft CredSSP Security Provider" /* Comment */
|
||||
};
|
||||
|
||||
WCHAR CREDSSP_SecPkgInfoW_Name[] = { 'C','R','E','D','S','S','P','\0' };
|
||||
|
||||
WCHAR CREDSSP_SecPkgInfoW_Comment[] =
|
||||
{
|
||||
'M','i','c','r','o','s','o','f','t',' ',
|
||||
'C','r','e','d','S','S','P',' ',
|
||||
'S','e','c','u','r','i','t','y',' ',
|
||||
'P','r','o','v','i','d','e','r','\0'
|
||||
};
|
||||
|
||||
const SecPkgInfoW CREDSSP_SecPkgInfoW =
|
||||
{
|
||||
0x000110733, /* fCapabilities */
|
||||
1, /* wVersion */
|
||||
0xFFFF, /* wRPCID */
|
||||
0x000090A8, /* cbMaxToken */
|
||||
L"CREDSSP", /* Name */
|
||||
L"Microsoft CredSSP Security Provider" /* Comment */
|
||||
CREDSSP_SecPkgInfoW_Name, /* Name */
|
||||
CREDSSP_SecPkgInfoW_Comment /* Comment */
|
||||
};
|
||||
|
@ -62,7 +62,10 @@ NTLM_CONTEXT* ntlm_ContextNew()
|
||||
{
|
||||
context->ntlm_v2 = 0;
|
||||
context->NegotiateFlags = 0;
|
||||
context->SendVersionInfo = 0;
|
||||
context->LmCompatibilityLevel = 3;
|
||||
context->state = NTLM_STATE_INITIAL;
|
||||
context->SuppressExtendedProtection = 1;
|
||||
context->av_pairs = (AV_PAIRS*) malloc(sizeof(AV_PAIRS));
|
||||
ZeroMemory(context->av_pairs, sizeof(AV_PAIRS));
|
||||
}
|
||||
@ -183,14 +186,6 @@ SECURITY_STATUS SEC_ENTRY ntlm_QueryCredentialsAttributesW(PCredHandle phCredent
|
||||
{
|
||||
if (ulAttribute == SECPKG_CRED_ATTR_NAMES)
|
||||
{
|
||||
CREDENTIALS* credentials;
|
||||
//SecPkgCredentials_Names* credential_names = (SecPkgCredentials_Names*) pBuffer;
|
||||
|
||||
credentials = (CREDENTIALS*) sspi_SecureHandleGetLowerPointer(phCredential);
|
||||
|
||||
//if (credentials->identity.Flags == SEC_WINNT_AUTH_IDENTITY_ANSI)
|
||||
// credential_names->sUserName = xstrdup((char*) credentials->identity.User);
|
||||
|
||||
return SEC_E_OK;
|
||||
}
|
||||
|
||||
@ -201,14 +196,6 @@ SECURITY_STATUS SEC_ENTRY ntlm_QueryCredentialsAttributesA(PCredHandle phCredent
|
||||
{
|
||||
if (ulAttribute == SECPKG_CRED_ATTR_NAMES)
|
||||
{
|
||||
CREDENTIALS* credentials;
|
||||
//SecPkgCredentials_Names* credential_names = (SecPkgCredentials_Names*) pBuffer;
|
||||
|
||||
credentials = (CREDENTIALS*) sspi_SecureHandleGetLowerPointer(phCredential);
|
||||
|
||||
//if (credentials->identity.Flags == SEC_WINNT_AUTH_IDENTITY_ANSI)
|
||||
// credential_names->sUserName = xstrdup((char*) credentials->identity.User);
|
||||
|
||||
return SEC_E_OK;
|
||||
}
|
||||
|
||||
@ -228,7 +215,7 @@ SECURITY_STATUS SEC_ENTRY ntlm_AcceptSecurityContext(PCredHandle phCredential, P
|
||||
PSecBuffer input_buffer;
|
||||
PSecBuffer output_buffer;
|
||||
|
||||
context = sspi_SecureHandleGetLowerPointer(phContext);
|
||||
context = (NTLM_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
|
||||
|
||||
if (!context)
|
||||
{
|
||||
@ -343,7 +330,7 @@ SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextA(PCredHandle phCredenti
|
||||
PSecBuffer input_buffer;
|
||||
PSecBuffer output_buffer;
|
||||
|
||||
context = sspi_SecureHandleGetLowerPointer(phContext);
|
||||
context = (NTLM_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
|
||||
|
||||
if (!context)
|
||||
{
|
||||
@ -434,7 +421,7 @@ SECURITY_STATUS SEC_ENTRY ntlm_DeleteSecurityContext(PCtxtHandle phContext)
|
||||
{
|
||||
NTLM_CONTEXT* context;
|
||||
|
||||
context = sspi_SecureHandleGetLowerPointer(phContext);
|
||||
context = (NTLM_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
|
||||
|
||||
if (!context)
|
||||
return SEC_E_INVALID_HANDLE;
|
||||
@ -493,7 +480,7 @@ SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext, ULONG fQOP,
|
||||
PSecBuffer data_buffer = NULL;
|
||||
PSecBuffer signature_buffer = NULL;
|
||||
|
||||
context = sspi_SecureHandleGetLowerPointer(phContext);
|
||||
context = (NTLM_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
|
||||
|
||||
for (index = 0; index < (int) pMessage->cBuffers; index++)
|
||||
{
|
||||
@ -732,12 +719,21 @@ const SecPkgInfoA NTLM_SecPkgInfoA =
|
||||
"NTLM Security Package" /* Comment */
|
||||
};
|
||||
|
||||
WCHAR NTLM_SecPkgInfoW_Name[] = { 'N','T','L','M','\0' };
|
||||
|
||||
WCHAR NTLM_SecPkgInfoW_Comment[] =
|
||||
{
|
||||
'N','T','L','M',' ',
|
||||
'S','e','c','u','r','i','t','y',' ',
|
||||
'P','a','c','k','a','g','e','\0'
|
||||
};
|
||||
|
||||
const SecPkgInfoW NTLM_SecPkgInfoW =
|
||||
{
|
||||
0x00082B37, /* fCapabilities */
|
||||
1, /* wVersion */
|
||||
0x000A, /* wRPCID */
|
||||
0x00000B48, /* cbMaxToken */
|
||||
L"NTLM", /* Name */
|
||||
L"NTLM Security Package" /* Comment */
|
||||
NTLM_SecPkgInfoW_Name, /* Name */
|
||||
NTLM_SecPkgInfoW_Comment /* Comment */
|
||||
};
|
||||
|
@ -89,6 +89,7 @@ struct _NTLM_CONTEXT
|
||||
NTLM_STATE state;
|
||||
int SendSeqNum;
|
||||
int RecvSeqNum;
|
||||
int SendVersionInfo;
|
||||
BOOL confidentiality;
|
||||
RC4_KEY SendRc4Seal;
|
||||
RC4_KEY RecvRc4Seal;
|
||||
@ -100,6 +101,8 @@ struct _NTLM_CONTEXT
|
||||
UINT32 NegotiateFlags;
|
||||
UINT16* Workstation;
|
||||
UINT32 WorkstationLength;
|
||||
int LmCompatibilityLevel;
|
||||
int SuppressExtendedProtection;
|
||||
SEC_WINNT_AUTH_IDENTITY identity;
|
||||
SecBuffer NegotiateMessage;
|
||||
SecBuffer ChallengeMessage;
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include "../sspi.h"
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/sam.h>
|
||||
#include <winpr/ntlm.h>
|
||||
#include <winpr/print.h>
|
||||
|
||||
#include "ntlm_compute.h"
|
||||
@ -159,155 +161,39 @@ void ntlm_generate_timestamp(NTLM_CONTEXT* context)
|
||||
}
|
||||
}
|
||||
|
||||
void ntlm_compute_ntlm_hash(UINT16* password, UINT32 length, char* hash)
|
||||
{
|
||||
/* NTLMv1("password") = 8846F7EAEE8FB117AD06BDD830B7586C */
|
||||
|
||||
MD4_CTX md4_ctx;
|
||||
|
||||
/* Password needs to be in unicode */
|
||||
|
||||
/* Apply the MD4 digest algorithm on the password in unicode, the result is the NTLM hash */
|
||||
|
||||
MD4_Init(&md4_ctx);
|
||||
MD4_Update(&md4_ctx, password, length);
|
||||
MD4_Final((void*) hash, &md4_ctx);
|
||||
}
|
||||
|
||||
static void ascii_hex_string_to_binary(char* str, unsigned char* hex)
|
||||
{
|
||||
int i;
|
||||
int length;
|
||||
|
||||
CharUpperA(str);
|
||||
|
||||
length = strlen(str);
|
||||
|
||||
for (i = 0; i < length / 2; i++)
|
||||
{
|
||||
hex[i] = 0;
|
||||
|
||||
if ((str[i * 2] >= '0') && (str[i * 2] <= '9'))
|
||||
hex[i] |= (str[i * 2] - '0') << 4;
|
||||
|
||||
if ((str[i * 2] >= 'A') && (str[i * 2] <= 'F'))
|
||||
hex[i] |= (str[i * 2] - 'A' + 10) << 4;
|
||||
|
||||
if ((str[i * 2 + 1] >= '0') && (str[i * 2 + 1] <= '9'))
|
||||
hex[i] |= (str[i * 2 + 1] - '0');
|
||||
|
||||
if ((str[i * 2 + 1] >= 'A') && (str[i * 2 + 1] <= 'F'))
|
||||
hex[i] |= (str[i * 2 + 1] - 'A' + 10);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* username // password
|
||||
* username:661e58eb6743798326f388fc5edb0b3a
|
||||
*/
|
||||
|
||||
void ntlm_fetch_ntlm_v2_hash(NTLM_CONTEXT* context, char* hash)
|
||||
{
|
||||
FILE* fp;
|
||||
char* data;
|
||||
char* line;
|
||||
int length;
|
||||
char* db_user;
|
||||
char* db_hash;
|
||||
UINT16* User;
|
||||
UINT32 UserLength;
|
||||
long int file_size;
|
||||
BYTE db_hash_bin[16];
|
||||
WINPR_SAM* sam;
|
||||
WINPR_SAM_ENTRY* entry;
|
||||
|
||||
/* Fetch NTLMv2 hash from database */
|
||||
sam = SamOpen(1);
|
||||
|
||||
fp = fopen("/etc/winpr/SAM.txt", "r");
|
||||
entry = SamLookupUserW(sam,
|
||||
(LPWSTR) context->identity.User, context->identity.UserLength * 2,
|
||||
(LPWSTR) context->identity.Domain, context->identity.DomainLength * 2);
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
file_size = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
|
||||
if (file_size < 1)
|
||||
return;
|
||||
|
||||
data = (char*) malloc(file_size + 2);
|
||||
|
||||
if (fread(data, file_size, 1, fp) != 1)
|
||||
if (entry != NULL)
|
||||
{
|
||||
free(data);
|
||||
return;
|
||||
CopyMemory(hash, entry->NtHash, 16);
|
||||
}
|
||||
|
||||
data[file_size] = '\n';
|
||||
data[file_size + 1] = '\0';
|
||||
line = strtok(data, "\n");
|
||||
SamFreeEntry(sam, entry);
|
||||
|
||||
while (line != NULL)
|
||||
{
|
||||
length = strlen(line);
|
||||
|
||||
if (length > 0)
|
||||
{
|
||||
length = strcspn(line, ":");
|
||||
line[length] = '\0';
|
||||
|
||||
db_user = line;
|
||||
db_hash = &line[length + 1];
|
||||
|
||||
UserLength = strlen(db_user) * 2;
|
||||
User = (UINT16*) malloc(UserLength);
|
||||
MultiByteToWideChar(CP_ACP, 0, db_user, strlen(db_user),
|
||||
(LPWSTR) User, UserLength / 2);
|
||||
|
||||
if (UserLength == context->identity.UserLength)
|
||||
{
|
||||
if (memcmp(User, context->identity.User, UserLength) == 0)
|
||||
{
|
||||
ascii_hex_string_to_binary(db_hash, db_hash_bin);
|
||||
CopyMemory(hash, db_hash_bin, 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
line = strtok(NULL, "\n");
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
free(data);
|
||||
SamClose(sam);
|
||||
}
|
||||
|
||||
void ntlm_compute_ntlm_v2_hash(NTLM_CONTEXT* context, char* hash)
|
||||
{
|
||||
char* p;
|
||||
SecBuffer buffer;
|
||||
char ntlm_hash[16];
|
||||
|
||||
if (context->identity.PasswordLength > 0)
|
||||
{
|
||||
/* First, compute the NTLMv1 hash of the password */
|
||||
ntlm_compute_ntlm_hash(context->identity.Password, context->identity.PasswordLength, ntlm_hash);
|
||||
}
|
||||
|
||||
sspi_SecBufferAlloc(&buffer, context->identity.UserLength + context->identity.DomainLength);
|
||||
p = (char*) buffer.pvBuffer;
|
||||
|
||||
/* Concatenate(Uppercase(username),domain)*/
|
||||
CopyMemory(p, context->identity.User, context->identity.UserLength);
|
||||
CharUpperBuffW((LPWSTR) p, context->identity.UserLength / 2);
|
||||
|
||||
CopyMemory(&p[context->identity.UserLength], context->identity.Domain, context->identity.DomainLength);
|
||||
|
||||
if (context->identity.PasswordLength > 0)
|
||||
{
|
||||
/* Compute the HMAC-MD5 hash of the above value using the NTLMv1 hash as the key, the result is the NTLMv2 hash */
|
||||
HMAC(EVP_md5(), (void*) ntlm_hash, 16, buffer.pvBuffer, buffer.cbBuffer, (void*) hash, NULL);
|
||||
NTOWFv2W((LPWSTR) context->identity.Password, context->identity.PasswordLength * 2,
|
||||
(LPWSTR) context->identity.User, context->identity.UserLength * 2,
|
||||
(LPWSTR) context->identity.Domain, context->identity.DomainLength * 2, (BYTE*) hash);
|
||||
}
|
||||
else
|
||||
{
|
||||
ntlm_fetch_ntlm_v2_hash(context, hash);
|
||||
}
|
||||
|
||||
sspi_SecBufferFree(&buffer);
|
||||
}
|
||||
|
||||
void ntlm_compute_lm_v2_response(NTLM_CONTEXT* context)
|
||||
|
@ -118,11 +118,11 @@ static const char* const NTLM_NEGOTIATE_STRINGS[] =
|
||||
|
||||
void ntlm_output_version(PStream s)
|
||||
{
|
||||
/* The following version information was observed with Windows 7 */
|
||||
/* Version Info for Windows 7 SP1 */
|
||||
|
||||
StreamWrite_UINT8(s, WINDOWS_MAJOR_VERSION_6); /* ProductMajorVersion (1 byte) */
|
||||
StreamWrite_UINT8(s, WINDOWS_MINOR_VERSION_1); /* ProductMinorVersion (1 byte) */
|
||||
StreamWrite_UINT16(s, 7600); /* ProductBuild (2 bytes) */
|
||||
StreamWrite_UINT16(s, 7601); /* ProductBuild (2 bytes) */
|
||||
StreamZero(s, 3); /* Reserved (3 bytes) */
|
||||
StreamWrite_UINT8(s, NTLMSSP_REVISION_W2K3); /* NTLMRevisionCurrent (1 byte) */
|
||||
}
|
||||
@ -263,6 +263,9 @@ SECURITY_STATUS ntlm_write_NegotiateMessage(NTLM_CONTEXT* context, PSecBuffer bu
|
||||
if (context->confidentiality)
|
||||
NegotiateFlags |= NTLMSSP_NEGOTIATE_SEAL;
|
||||
|
||||
if (context->SendVersionInfo)
|
||||
NegotiateFlags |= NTLMSSP_NEGOTIATE_VERSION;
|
||||
|
||||
context->NegotiateFlags = NegotiateFlags;
|
||||
|
||||
StreamWrite_UINT32(s, NegotiateFlags); /* NegotiateFlags (4 bytes) */
|
||||
@ -431,10 +434,9 @@ SECURITY_STATUS ntlm_read_ChallengeMessage(NTLM_CONTEXT* context, PSecBuffer buf
|
||||
ntlm_generate_timestamp(context);
|
||||
|
||||
/* LmChallengeResponse */
|
||||
ntlm_compute_lm_v2_response(context);
|
||||
|
||||
if (context->ntlm_v2)
|
||||
memset(context->LmChallengeResponse.pvBuffer, 0, context->LmChallengeResponse.cbBuffer);
|
||||
if (context->LmCompatibilityLevel < 2)
|
||||
ntlm_compute_lm_v2_response(context);
|
||||
|
||||
/* NtChallengeResponse */
|
||||
ntlm_compute_ntlm_v2_response(context);
|
||||
@ -820,11 +822,24 @@ SECURITY_STATUS ntlm_read_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
||||
#endif
|
||||
}
|
||||
|
||||
/* LmChallengeResponse */
|
||||
ntlm_compute_lm_v2_response(context);
|
||||
if (UserNameLen > 0)
|
||||
{
|
||||
context->identity.User = (UINT16*) malloc(UserNameLen);
|
||||
CopyMemory(context->identity.User, UserNameBuffer, UserNameLen);
|
||||
context->identity.UserLength = UserNameLen;
|
||||
}
|
||||
|
||||
if (context->ntlm_v2)
|
||||
memset(context->LmChallengeResponse.pvBuffer, 0, context->LmChallengeResponse.cbBuffer);
|
||||
if (DomainNameLen > 0)
|
||||
{
|
||||
context->identity.Domain = (UINT16*) malloc(DomainNameLen);
|
||||
CopyMemory(context->identity.Domain, DomainNameBuffer, DomainNameLen);
|
||||
context->identity.DomainLength = DomainNameLen;
|
||||
}
|
||||
|
||||
/* LmChallengeResponse */
|
||||
|
||||
if (context->LmCompatibilityLevel < 2)
|
||||
ntlm_compute_lm_v2_response(context);
|
||||
|
||||
/* NtChallengeResponse */
|
||||
ntlm_compute_ntlm_v2_response(context);
|
||||
@ -944,13 +959,13 @@ SECURITY_STATUS ntlm_write_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
||||
if (context->ntlm_v2 < 1)
|
||||
WorkstationLen = 0;
|
||||
|
||||
DomainNameLen = (UINT16) context->identity.DomainLength;
|
||||
DomainNameLen = (UINT16) context->identity.DomainLength * 2;
|
||||
DomainNameBuffer = (BYTE*) context->identity.Domain;
|
||||
|
||||
UserNameLen = (UINT16) context->identity.UserLength;
|
||||
UserNameLen = (UINT16) context->identity.UserLength * 2;
|
||||
UserNameBuffer = (BYTE*) context->identity.User;
|
||||
|
||||
LmChallengeResponseLen = (UINT16) context->LmChallengeResponse.cbBuffer;
|
||||
LmChallengeResponseLen = (UINT16) 24;
|
||||
NtChallengeResponseLen = (UINT16) context->NtChallengeResponse.cbBuffer;
|
||||
|
||||
EncryptedRandomSessionKeyLen = 16;
|
||||
@ -1095,13 +1110,21 @@ SECURITY_STATUS ntlm_write_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
||||
}
|
||||
|
||||
/* LmChallengeResponse */
|
||||
StreamWrite(s, context->LmChallengeResponse.pvBuffer, LmChallengeResponseLen);
|
||||
|
||||
if (context->LmCompatibilityLevel < 2)
|
||||
{
|
||||
StreamWrite(s, context->LmChallengeResponse.pvBuffer, LmChallengeResponseLen);
|
||||
|
||||
#ifdef WITH_DEBUG_NTLM
|
||||
printf("LmChallengeResponse (length = %d, offset = %d)\n", LmChallengeResponseLen, LmChallengeResponseBufferOffset);
|
||||
winpr_HexDump(context->LmChallengeResponse.pvBuffer, LmChallengeResponseLen);
|
||||
printf("\n");
|
||||
printf("LmChallengeResponse (length = %d, offset = %d)\n", LmChallengeResponseLen, LmChallengeResponseBufferOffset);
|
||||
winpr_HexDump(context->LmChallengeResponse.pvBuffer, LmChallengeResponseLen);
|
||||
printf("\n");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
StreamZero(s, LmChallengeResponseLen);
|
||||
}
|
||||
|
||||
/* NtChallengeResponse */
|
||||
StreamWrite(s, context->NtChallengeResponse.pvBuffer, NtChallengeResponseLen);
|
||||
|
@ -26,26 +26,6 @@
|
||||
|
||||
char* NEGOTIATE_PACKAGE_NAME = "Negotiate";
|
||||
|
||||
const SecPkgInfoA NEGOTIATE_SecPkgInfoA =
|
||||
{
|
||||
0x00083BB3, /* fCapabilities */
|
||||
1, /* wVersion */
|
||||
0x0009, /* wRPCID */
|
||||
0x00002FE0, /* cbMaxToken */
|
||||
"Negotiate", /* Name */
|
||||
"Microsoft Package Negotiator" /* Comment */
|
||||
};
|
||||
|
||||
const SecPkgInfoW NEGOTIATE_SecPkgInfoW =
|
||||
{
|
||||
0x00083BB3, /* fCapabilities */
|
||||
1, /* wVersion */
|
||||
0x0009, /* wRPCID */
|
||||
0x00002FE0, /* cbMaxToken */
|
||||
L"Negotiate", /* Name */
|
||||
L"Microsoft Package Negotiator" /* Comment */
|
||||
};
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY negotiate_InitializeSecurityContextW(PCredHandle phCredential, PCtxtHandle phContext,
|
||||
SEC_WCHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
|
||||
PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
|
||||
@ -277,3 +257,32 @@ const SecurityFunctionTableW NEGOTIATE_SecurityFunctionTableW =
|
||||
negotiate_DecryptMessage, /* DecryptMessage */
|
||||
NULL, /* SetContextAttributes */
|
||||
};
|
||||
|
||||
const SecPkgInfoA NEGOTIATE_SecPkgInfoA =
|
||||
{
|
||||
0x00083BB3, /* fCapabilities */
|
||||
1, /* wVersion */
|
||||
0x0009, /* wRPCID */
|
||||
0x00002FE0, /* cbMaxToken */
|
||||
"Negotiate", /* Name */
|
||||
"Microsoft Package Negotiator" /* Comment */
|
||||
};
|
||||
|
||||
WCHAR NEGOTIATE_SecPkgInfoW_Name[] = { 'N','e','g','o','t','i','a','t','e','\0' };
|
||||
|
||||
WCHAR NEGOTIATE_SecPkgInfoW_Comment[] =
|
||||
{
|
||||
'M','i','c','r','o','s','o','f','t',' ',
|
||||
'P','a','c','k','a','g','e',' ',
|
||||
'N','e','g','o','t','i','a','t','o','r','\0'
|
||||
};
|
||||
|
||||
const SecPkgInfoW NEGOTIATE_SecPkgInfoW =
|
||||
{
|
||||
0x00083BB3, /* fCapabilities */
|
||||
1, /* wVersion */
|
||||
0x0009, /* wRPCID */
|
||||
0x00002FE0, /* cbMaxToken */
|
||||
NEGOTIATE_SecPkgInfoW_Name, /* Name */
|
||||
NEGOTIATE_SecPkgInfoW_Comment /* Comment */
|
||||
};
|
||||
|
@ -251,13 +251,21 @@ const SecPkgInfoA SCHANNEL_SecPkgInfoA =
|
||||
"Schannel Security Package" /* Comment */
|
||||
};
|
||||
|
||||
WCHAR SCHANNEL_SecPkgInfoW_Name[] = { 'S','c','h','a','n','n','e','l','\0' };
|
||||
|
||||
WCHAR SCHANNEL_SecPkgInfoW_Comment[] =
|
||||
{
|
||||
'S','c','h','a','n','n','e','l',' ',
|
||||
'S','e','c','u','r','i','t','y',' ',
|
||||
'P','a','c','k','a','g','e','\0'
|
||||
};
|
||||
|
||||
const SecPkgInfoW SCHANNEL_SecPkgInfoW =
|
||||
{
|
||||
0x000107B3, /* fCapabilities */
|
||||
1, /* wVersion */
|
||||
0x000E, /* wRPCID */
|
||||
0x00006000, /* cbMaxToken */
|
||||
L"Schannel", /* Name */
|
||||
L"Schannel Security Package" /* Comment */
|
||||
SCHANNEL_SecPkgInfoW_Name, /* Name */
|
||||
SCHANNEL_SecPkgInfoW_Comment /* Comment */
|
||||
};
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/sspi.h>
|
||||
#include <winpr/print.h>
|
||||
|
||||
#include "sspi.h"
|
||||
|
||||
@ -73,10 +74,13 @@ const SecurityFunctionTableA_NAME SecurityFunctionTableA_NAME_LIST[] =
|
||||
{ "CREDSSP", &CREDSSP_SecurityFunctionTableA }
|
||||
};
|
||||
|
||||
WCHAR NTLM_NAME_W[] = { 'N','T','L','M','\0' };
|
||||
WCHAR CREDSSP_NAME_W[] = { 'C','r','e','d','S','S','P','\0' };
|
||||
|
||||
const SecurityFunctionTableW_NAME SecurityFunctionTableW_NAME_LIST[] =
|
||||
{
|
||||
{ L"NTLM", &NTLM_SecurityFunctionTableW },
|
||||
{ L"CREDSSP", &CREDSSP_SecurityFunctionTableW }
|
||||
{ NTLM_NAME_W, &NTLM_SecurityFunctionTableW },
|
||||
{ CREDSSP_NAME_W, &CREDSSP_SecurityFunctionTableW }
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -122,8 +126,8 @@ void sspi_ContextBufferAllocTableGrow()
|
||||
|
||||
size = sizeof(CONTEXT_BUFFER_ALLOC_ENTRY) * ContextBufferAllocTable.cMaxEntries;
|
||||
|
||||
ContextBufferAllocTable.entries = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ContextBufferAllocTable.entries, size);
|
||||
memset((void*) &ContextBufferAllocTable.entries[ContextBufferAllocTable.cMaxEntries / 2], 0, size / 2);
|
||||
ContextBufferAllocTable.entries = realloc(ContextBufferAllocTable.entries, size);
|
||||
ZeroMemory((void*) &ContextBufferAllocTable.entries[ContextBufferAllocTable.cMaxEntries / 2], size / 2);
|
||||
}
|
||||
|
||||
void sspi_ContextBufferAllocTableFree()
|
||||
@ -273,17 +277,23 @@ void sspi_SetAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity, char* user, char* d
|
||||
{
|
||||
identity->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
|
||||
|
||||
identity->UserLength = strlen(user) * 2;
|
||||
identity->User = (UINT16*) malloc(identity->UserLength);
|
||||
MultiByteToWideChar(CP_ACP, 0, user, strlen(user),
|
||||
(LPWSTR) identity->User, identity->UserLength / 2);
|
||||
if (user)
|
||||
{
|
||||
identity->UserLength = MultiByteToWideChar(CP_UTF8, 0, user, strlen(user), NULL, 0);
|
||||
identity->User = (UINT16*) malloc(identity->UserLength * sizeof(WCHAR));
|
||||
MultiByteToWideChar(CP_UTF8, 0, user, identity->UserLength, (LPWSTR) identity->User, identity->UserLength * sizeof(WCHAR));
|
||||
}
|
||||
else
|
||||
{
|
||||
identity->User = (UINT16*) NULL;
|
||||
identity->UserLength = 0;
|
||||
}
|
||||
|
||||
if (domain)
|
||||
{
|
||||
identity->DomainLength = strlen(domain) * 2;
|
||||
identity->Domain = (UINT16*) malloc(identity->DomainLength);
|
||||
MultiByteToWideChar(CP_ACP, 0, domain, strlen(domain),
|
||||
(LPWSTR) identity->Domain, identity->DomainLength / 2);
|
||||
identity->DomainLength = MultiByteToWideChar(CP_UTF8, 0, domain, strlen(domain), NULL, 0);
|
||||
identity->Domain = (UINT16*) malloc(identity->DomainLength * sizeof(WCHAR));
|
||||
MultiByteToWideChar(CP_UTF8, 0, domain, identity->DomainLength, (LPWSTR) identity->Domain, identity->DomainLength * sizeof(WCHAR));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -293,10 +303,9 @@ void sspi_SetAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity, char* user, char* d
|
||||
|
||||
if (password != NULL)
|
||||
{
|
||||
identity->PasswordLength = strlen(password) * 2;
|
||||
identity->Password = (UINT16*) malloc(identity->PasswordLength);
|
||||
MultiByteToWideChar(CP_ACP, 0, password, strlen(password),
|
||||
(LPWSTR) identity->Password, identity->PasswordLength / 2);
|
||||
identity->PasswordLength = MultiByteToWideChar(CP_UTF8, 0, password, strlen(password), NULL, 0);
|
||||
identity->Password = (UINT16*) malloc(identity->PasswordLength * sizeof(WCHAR));
|
||||
MultiByteToWideChar(CP_UTF8, 0, password, identity->PasswordLength, (LPWSTR) identity->Password, identity->PasswordLength * sizeof(WCHAR));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -320,16 +329,16 @@ void sspi_CopyAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity, SEC_WINNT_AUTH_IDE
|
||||
identity->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
|
||||
|
||||
identity->UserLength = srcIdentity->UserLength;
|
||||
identity->User = malloc(identity->UserLength);
|
||||
CopyMemory(identity->User, srcIdentity->User, identity->UserLength);
|
||||
identity->User = (UINT16*) malloc(identity->UserLength * sizeof(WCHAR));
|
||||
CopyMemory(identity->User, srcIdentity->User, identity->UserLength * sizeof(WCHAR));
|
||||
|
||||
identity->DomainLength = srcIdentity->DomainLength;
|
||||
identity->Domain = malloc(identity->DomainLength);
|
||||
CopyMemory(identity->Domain, srcIdentity->Domain, identity->DomainLength);
|
||||
identity->Domain = (UINT16*) malloc(identity->DomainLength * sizeof(WCHAR));
|
||||
CopyMemory(identity->Domain, srcIdentity->Domain, identity->DomainLength * sizeof(WCHAR));
|
||||
|
||||
identity->PasswordLength = srcIdentity->PasswordLength;
|
||||
identity->Password = malloc(identity->PasswordLength);
|
||||
CopyMemory(identity->Password, srcIdentity->Password, identity->PasswordLength);
|
||||
identity->Password = (UINT16*) malloc(identity->PasswordLength * sizeof(WCHAR));
|
||||
CopyMemory(identity->Password, srcIdentity->Password, identity->PasswordLength * sizeof(WCHAR));
|
||||
}
|
||||
|
||||
void sspi_GlobalInit()
|
||||
@ -342,7 +351,7 @@ void sspi_GlobalFinish()
|
||||
sspi_ContextBufferAllocTableFree();
|
||||
}
|
||||
|
||||
#ifndef NATIVE_SSPI
|
||||
#ifndef WITH_NATIVE_SSPI
|
||||
|
||||
SecurityFunctionTableA* sspi_GetSecurityFunctionTableByNameA(const SEC_CHAR* Name)
|
||||
{
|
||||
@ -371,7 +380,7 @@ SecurityFunctionTableW* sspi_GetSecurityFunctionTableByNameW(const SEC_WCHAR* Na
|
||||
|
||||
for (index = 0; index < (int) cPackages; index++)
|
||||
{
|
||||
if (wcscmp(Name, SecurityFunctionTableW_NAME_LIST[index].Name) == 0)
|
||||
if (lstrcmpW(Name, SecurityFunctionTableW_NAME_LIST[index].Name) == 0)
|
||||
{
|
||||
return (SecurityFunctionTableW*) SecurityFunctionTableW_NAME_LIST[index].SecurityFunctionTable;
|
||||
}
|
||||
@ -513,7 +522,7 @@ SECURITY_STATUS SEC_ENTRY QuerySecurityPackageInfoW(SEC_WCHAR* pszPackageName, P
|
||||
|
||||
for (index = 0; index < (int) cPackages; index++)
|
||||
{
|
||||
if (wcscmp(pszPackageName, SecPkgInfoW_LIST[index]->Name) == 0)
|
||||
if (lstrcmpW(pszPackageName, SecPkgInfoW_LIST[index]->Name) == 0)
|
||||
{
|
||||
size = sizeof(SecPkgInfoW);
|
||||
pPackageInfo = (SecPkgInfoW*) sspi_ContextBufferAlloc(QuerySecurityPackageInfoIndex, size);
|
||||
|
36
winpr/synch/CMakeLists.txt
Normal file
36
winpr/synch/CMakeLists.txt
Normal file
@ -0,0 +1,36 @@
|
||||
# WinPR: Windows Portable Runtime
|
||||
# libwinpr-synch cmake build script
|
||||
#
|
||||
# Copyright 2011 O.S. Systems Software Ltda.
|
||||
# Copyright 2011 Otavio Salvador <otavio@ossystems.com.br>
|
||||
# Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
set(WINPR_SYNCH_SRCS
|
||||
critical.c
|
||||
event.c
|
||||
mutex.c
|
||||
semaphore.c
|
||||
sleep.c)
|
||||
|
||||
add_library(winpr-synch ${WINPR_SYNCH_SRCS})
|
||||
|
||||
set_target_properties(winpr-synch PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib")
|
||||
|
||||
if(NOT WIN32)
|
||||
target_link_libraries(winpr-synch winpr-handle)
|
||||
endif()
|
||||
|
||||
install(TARGETS winpr-synch DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
|
23
winpr/synch/critical.c
Normal file
23
winpr/synch/critical.c
Normal file
@ -0,0 +1,23 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Synchronization Functions
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <winpr/synch.h>
|
||||
|
||||
|
||||
|
23
winpr/synch/event.c
Normal file
23
winpr/synch/event.c
Normal file
@ -0,0 +1,23 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Synchronization Functions
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <winpr/synch.h>
|
||||
|
||||
|
||||
|
23
winpr/synch/mutex.c
Normal file
23
winpr/synch/mutex.c
Normal file
@ -0,0 +1,23 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Synchronization Functions
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <winpr/synch.h>
|
||||
|
||||
|
||||
|
104
winpr/synch/semaphore.c
Normal file
104
winpr/synch/semaphore.c
Normal file
@ -0,0 +1,104 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Synchronization Functions
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <winpr/synch.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
#if defined __APPLE__
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <mach/mach.h>
|
||||
#include <mach/semaphore.h>
|
||||
#include <mach/task.h>
|
||||
#define winpr_sem_t semaphore_td
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#define winpr_sem_t sem_t
|
||||
#endif
|
||||
|
||||
HANDLE CreateSemaphoreA(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, LPCSTR lpName)
|
||||
{
|
||||
winpr_sem_t* hSemaphore;
|
||||
|
||||
hSemaphore = malloc(sizeof(winpr_sem_t));
|
||||
|
||||
#if defined __APPLE__
|
||||
semaphore_create(mach_task_self(), hSemaphore, SYNC_POLICY_FIFO, lMaximumCount);
|
||||
#else
|
||||
sem_init(hSemaphore, 0, lMaximumCount);
|
||||
#endif
|
||||
|
||||
return (HANDLE) hSemaphore;
|
||||
}
|
||||
|
||||
HANDLE CreateSemaphoreW(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, LPCWSTR lpName)
|
||||
{
|
||||
winpr_sem_t* hSemaphore;
|
||||
|
||||
hSemaphore = malloc(sizeof(winpr_sem_t));
|
||||
|
||||
#if defined __APPLE__
|
||||
semaphore_create(mach_task_self(), hSemaphore, SYNC_POLICY_FIFO, lMaximumCount);
|
||||
#else
|
||||
sem_init(hSemaphore, 0, lMaximumCount);
|
||||
#endif
|
||||
|
||||
return (HANDLE) hSemaphore;
|
||||
}
|
||||
|
||||
HANDLE OpenSemaphoreA(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HANDLE OpenSemaphoreW(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpName)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL ReleaseSemaphore(HANDLE hSemaphore, LONG lReleaseCount, LPLONG lpPreviousCount)
|
||||
{
|
||||
#if defined __APPLE__
|
||||
semaphore_signal(*((winpr_sem_t*) hSemaphore));
|
||||
#else
|
||||
sem_post((winpr_sem_t*) hSemaphore);
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
|
||||
{
|
||||
#if defined __APPLE__
|
||||
semaphore_wait(*((winpr_sem_t*) hHandle));
|
||||
#else
|
||||
sem_wait((winpr_sem_t*) hHandle);
|
||||
#endif
|
||||
|
||||
return WAIT_OBJECT_0;
|
||||
}
|
||||
|
||||
DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAll, DWORD dwMilliseconds)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
23
winpr/synch/sleep.c
Normal file
23
winpr/synch/sleep.c
Normal file
@ -0,0 +1,23 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Synchronization Functions
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <winpr/synch.h>
|
||||
|
||||
|
||||
|
22
winpr/tools/CMakeLists.txt
Normal file
22
winpr/tools/CMakeLists.txt
Normal file
@ -0,0 +1,22 @@
|
||||
# WinPR: Windows Portable Runtime
|
||||
# winpr cmake build script
|
||||
#
|
||||
# Copyright 2011 O.S. Systems Software Ltda.
|
||||
# Copyright 2011 Otavio Salvador <otavio@ossystems.com.br>
|
||||
# Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
add_subdirectory(reg)
|
||||
add_subdirectory(hash)
|
||||
|
24
winpr/tools/hash/CMakeLists.txt
Normal file
24
winpr/tools/hash/CMakeLists.txt
Normal file
@ -0,0 +1,24 @@
|
||||
# WinPR: Windows Portable Runtime
|
||||
# winpr-hash cmake build script
|
||||
#
|
||||
# Copyright 2011 O.S. Systems Software Ltda.
|
||||
# Copyright 2011 Otavio Salvador <otavio@ossystems.com.br>
|
||||
# Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
add_executable(winpr-hash
|
||||
hash.c)
|
||||
|
||||
target_link_libraries(winpr-hash winpr-utils)
|
||||
|
146
winpr/tools/hash/hash.c
Normal file
146
winpr/tools/hash/hash.c
Normal file
@ -0,0 +1,146 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* NTLM Hashing Tool
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <winpr/ntlm.h>
|
||||
|
||||
/**
|
||||
* Define NTOWFv1(Password, User, Domain) as
|
||||
* MD4(UNICODE(Password))
|
||||
* EndDefine
|
||||
*
|
||||
* Define LMOWFv1(Password, User, Domain) as
|
||||
* ConcatenationOf(DES(UpperCase(Password)[0..6], "KGS!@#$%"),
|
||||
* DES(UpperCase(Password)[7..13], "KGS!@#$%"))
|
||||
* EndDefine
|
||||
*
|
||||
* Define NTOWFv2(Password, User, Domain) as
|
||||
* HMAC_MD5(MD4(UNICODE(Password)),
|
||||
* UNICODE(ConcatenationOf(UpperCase(User), Domain)))
|
||||
* EndDefine
|
||||
*
|
||||
* Define LMOWFv2(Password, User, Domain) as
|
||||
* NTOWFv2(Password, User, Domain)
|
||||
* EndDefine
|
||||
*
|
||||
*/
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int index = 1;
|
||||
BYTE NtHash[16];
|
||||
BOOL sam_entry = 0;
|
||||
char* User = NULL;
|
||||
UINT32 UserLength;
|
||||
char* Domain = NULL;
|
||||
UINT32 DomainLength;
|
||||
char* Password = NULL;
|
||||
UINT32 PasswordLength;
|
||||
|
||||
while (index < argc)
|
||||
{
|
||||
if (strcmp("-d", argv[index]) == 0)
|
||||
{
|
||||
index++;
|
||||
|
||||
if (index == argc)
|
||||
{
|
||||
printf("missing domain\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
Domain = argv[index];
|
||||
}
|
||||
else if (strcmp("-u", argv[index]) == 0)
|
||||
{
|
||||
index++;
|
||||
|
||||
if (index == argc)
|
||||
{
|
||||
printf("missing username\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
User = argv[index];
|
||||
}
|
||||
else if (strcmp("-p", argv[index]) == 0)
|
||||
{
|
||||
index++;
|
||||
|
||||
if (index == argc)
|
||||
{
|
||||
printf("missing password\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
Password = argv[index];
|
||||
}
|
||||
else if (strcmp("-h", argv[index]) == 0)
|
||||
{
|
||||
printf("winpr-hash: NTLM hashing tool\n");
|
||||
printf("Usage: winpr-hash -u <username> -p <password> [-d <domain>]\n");
|
||||
exit(1);
|
||||
}
|
||||
else if (strcmp("-s", argv[index]) == 0)
|
||||
{
|
||||
sam_entry = 1;
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
if ((!User) || (!Password))
|
||||
{
|
||||
printf("missing username or password\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
UserLength = strlen(User);
|
||||
PasswordLength = strlen(Password);
|
||||
DomainLength = (Domain) ? strlen(Domain) : 0;
|
||||
|
||||
NTOWFv2A(Password, PasswordLength, User, UserLength, Domain, DomainLength, NtHash);
|
||||
|
||||
if (sam_entry)
|
||||
{
|
||||
printf("%s:", User);
|
||||
|
||||
if (DomainLength > 0)
|
||||
printf("%s:", Domain);
|
||||
else
|
||||
printf(":");
|
||||
|
||||
printf(":");
|
||||
|
||||
for (index = 0; index < 16; index++)
|
||||
printf("%02x", NtHash[index]);
|
||||
printf("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (index = 0; index < 16; index++)
|
||||
printf("%02x", NtHash[index]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
27
winpr/tools/reg/CMakeLists.txt
Normal file
27
winpr/tools/reg/CMakeLists.txt
Normal file
@ -0,0 +1,27 @@
|
||||
# WinPR: Windows Portable Runtime
|
||||
# winpr-reg cmake build script
|
||||
#
|
||||
# Copyright 2011 O.S. Systems Software Ltda.
|
||||
# Copyright 2011 Otavio Salvador <otavio@ossystems.com.br>
|
||||
# Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
add_executable(winpr-reg
|
||||
reg.c)
|
||||
|
||||
target_link_libraries(winpr-reg winpr-utils)
|
||||
|
||||
if(NOT WIN32)
|
||||
target_link_libraries(winpr-reg winpr-registry)
|
||||
endif()
|
86
winpr/tools/reg/reg.c
Normal file
86
winpr/tools/reg/reg.c
Normal file
@ -0,0 +1,86 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Client
|
||||
* Registry API Tool
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/wtypes.h>
|
||||
|
||||
#include <winpr/print.h>
|
||||
#include <winpr/registry.h>
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
HKEY hKey;
|
||||
LONG status;
|
||||
DWORD dwType;
|
||||
DWORD dwSize;
|
||||
DWORD dwValue;
|
||||
DWORD RemoteFX;
|
||||
char* ComputerName;
|
||||
|
||||
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\FreeRDP"), 0, KEY_READ, &hKey);
|
||||
|
||||
if (status != ERROR_SUCCESS)
|
||||
{
|
||||
_tprintf(_T("RegOpenKeyEx error: 0x%08lX\n"), status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dwValue = 0;
|
||||
status = RegQueryValueEx(hKey, _T("RemoteFX"), NULL, &dwType, (BYTE*) &dwValue, &dwSize);
|
||||
|
||||
if (status != ERROR_SUCCESS)
|
||||
{
|
||||
_tprintf(_T("RegQueryValueEx error: 0x%08lX\n"), status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
RemoteFX = dwValue;
|
||||
|
||||
status = RegQueryValueEx(hKey, _T("ComputerName"), NULL, &dwType, NULL, &dwSize);
|
||||
|
||||
if (status != ERROR_SUCCESS)
|
||||
{
|
||||
_tprintf(_T("RegQueryValueEx error: 0x%08lX\n"), status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ComputerName = (char*) malloc(dwSize + 1);
|
||||
|
||||
status = RegQueryValueEx(hKey, _T("ComputerName"), NULL, &dwType, (BYTE*) ComputerName, &dwSize);
|
||||
|
||||
if (status != ERROR_SUCCESS)
|
||||
{
|
||||
_tprintf(_T("RegQueryValueEx error: 0x%08lX\n"), status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("RemoteFX: %08lX\n", RemoteFX);
|
||||
printf("ComputerName: %s\n", ComputerName);
|
||||
|
||||
RegCloseKey(hKey);
|
||||
|
||||
free(ComputerName);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -18,16 +18,24 @@
|
||||
# limitations under the License.
|
||||
|
||||
set(WINPR_UTILS_SRCS
|
||||
ntlm.c
|
||||
print.c
|
||||
sam.c
|
||||
stream.c)
|
||||
|
||||
add_library(winpr-utils ${WINPR_UTILS_SRCS})
|
||||
|
||||
include_directories(${ZLIB_INCLUDE_DIRS})
|
||||
include_directories(${OPENSSL_INCLUDE_DIR})
|
||||
|
||||
set_target_properties(winpr-utils PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib")
|
||||
|
||||
if (NOT WIN32)
|
||||
target_link_libraries(winpr-utils winpr-crt)
|
||||
endif()
|
||||
|
||||
target_link_libraries(winpr-utils ${ZLIB_LIBRARIES})
|
||||
target_link_libraries(winpr-utils ${OPENSSL_LIBRARIES})
|
||||
|
||||
install(TARGETS winpr-utils DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
|
||||
|
131
winpr/utils/ntlm.c
Normal file
131
winpr/utils/ntlm.c
Normal file
@ -0,0 +1,131 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* NTLM Utils
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <winpr/ntlm.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/windows.h>
|
||||
|
||||
#include <time.h>
|
||||
#include <openssl/des.h>
|
||||
#include <openssl/md4.h>
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/rc4.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/engine.h>
|
||||
|
||||
/**
|
||||
* Define NTOWFv1(Password, User, Domain) as
|
||||
* MD4(UNICODE(Password))
|
||||
* EndDefine
|
||||
*/
|
||||
|
||||
BYTE* NTOWFv1W(LPWSTR Password, UINT32 PasswordLength, BYTE* NtHash)
|
||||
{
|
||||
MD4_CTX md4_ctx;
|
||||
|
||||
if (!Password)
|
||||
return NULL;
|
||||
|
||||
if (!NtHash)
|
||||
NtHash = malloc(16);
|
||||
|
||||
MD4_Init(&md4_ctx);
|
||||
MD4_Update(&md4_ctx, Password, PasswordLength);
|
||||
MD4_Final((void*) NtHash, &md4_ctx);
|
||||
|
||||
return NtHash;
|
||||
}
|
||||
|
||||
BYTE* NTOWFv1A(LPSTR Password, UINT32 PasswordLength, BYTE* NtHash)
|
||||
{
|
||||
LPWSTR PasswordW = NULL;
|
||||
|
||||
PasswordW = (LPWSTR) malloc(PasswordLength * 2);
|
||||
MultiByteToWideChar(CP_ACP, 0, Password, PasswordLength, PasswordW, PasswordLength);
|
||||
|
||||
NtHash = NTOWFv1W(PasswordW, PasswordLength, NtHash);
|
||||
|
||||
free(PasswordW);
|
||||
|
||||
return NtHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define NTOWFv2(Password, User, Domain) as
|
||||
* HMAC_MD5(MD4(UNICODE(Password)),
|
||||
* UNICODE(ConcatenationOf(UpperCase(User), Domain)))
|
||||
* EndDefine
|
||||
*/
|
||||
|
||||
BYTE* NTOWFv2W(LPWSTR Password, UINT32 PasswordLength, LPWSTR User,
|
||||
UINT32 UserLength, LPWSTR Domain, UINT32 DomainLength, BYTE* NtHash)
|
||||
{
|
||||
BYTE* buffer;
|
||||
BYTE NtHashV1[16];
|
||||
|
||||
if ((!User) || (!Password))
|
||||
return NULL;
|
||||
|
||||
if (!NtHash)
|
||||
NtHash = (BYTE*) malloc(16);
|
||||
|
||||
NTOWFv1W(Password, PasswordLength, NtHashV1);
|
||||
|
||||
buffer = (BYTE*) malloc(UserLength + DomainLength);
|
||||
|
||||
/* Concatenate(UpperCase(User), Domain) */
|
||||
|
||||
CopyMemory(buffer, User, UserLength);
|
||||
CharUpperBuffW((LPWSTR) buffer, UserLength / 2);
|
||||
CopyMemory(&buffer[UserLength], Domain, DomainLength);
|
||||
|
||||
/* Compute the HMAC-MD5 hash of the above value using the NTLMv1 hash as the key, the result is the NTLMv2 hash */
|
||||
HMAC(EVP_md5(), (void*) NtHashV1, 16, buffer, UserLength + DomainLength, (void*) NtHash, NULL);
|
||||
|
||||
free(buffer);
|
||||
|
||||
return NtHash;
|
||||
}
|
||||
|
||||
BYTE* NTOWFv2A(LPSTR Password, UINT32 PasswordLength, LPSTR User,
|
||||
UINT32 UserLength, LPSTR Domain, UINT32 DomainLength, BYTE* NtHash)
|
||||
{
|
||||
LPWSTR UserW = NULL;
|
||||
LPWSTR DomainW = NULL;
|
||||
LPWSTR PasswordW = NULL;
|
||||
|
||||
UserW = (LPWSTR) malloc(UserLength * 2);
|
||||
DomainW = (LPWSTR) malloc(DomainLength * 2);
|
||||
PasswordW = (LPWSTR) malloc(PasswordLength * 2);
|
||||
|
||||
MultiByteToWideChar(CP_ACP, 0, User, UserLength, UserW, UserLength);
|
||||
MultiByteToWideChar(CP_ACP, 0, Domain, DomainLength, DomainW, DomainLength);
|
||||
MultiByteToWideChar(CP_ACP, 0, Password, PasswordLength, PasswordW, PasswordLength);
|
||||
|
||||
NtHash = NTOWFv2W(PasswordW, PasswordLength * 2, UserW, UserLength * 2, DomainW, DomainLength * 2, NtHash);
|
||||
|
||||
free(UserW);
|
||||
free(DomainW);
|
||||
free(PasswordW);
|
||||
|
||||
return NtHash;
|
||||
}
|
||||
|
272
winpr/utils/sam.c
Normal file
272
winpr/utils/sam.c
Normal file
@ -0,0 +1,272 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Security Accounts Manager (SAM)
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/sam.h>
|
||||
#include <winpr/print.h>
|
||||
|
||||
#define WINPR_SAM_FILE "/etc/winpr/SAM"
|
||||
|
||||
WINPR_SAM* SamOpen(BOOL read_only)
|
||||
{
|
||||
WINPR_SAM* sam;
|
||||
|
||||
sam = (WINPR_SAM*) malloc(sizeof(WINPR_SAM));
|
||||
|
||||
if (sam != NULL)
|
||||
{
|
||||
sam->read_only = read_only;
|
||||
|
||||
if (sam->read_only)
|
||||
{
|
||||
sam->fp = fopen(WINPR_SAM_FILE, "r");
|
||||
}
|
||||
else
|
||||
{
|
||||
sam->fp = fopen(WINPR_SAM_FILE, "r+");
|
||||
|
||||
if (!sam->fp)
|
||||
sam->fp = fopen(WINPR_SAM_FILE, "w+");
|
||||
}
|
||||
}
|
||||
|
||||
return sam;
|
||||
}
|
||||
|
||||
void SamLookupStart(WINPR_SAM* sam)
|
||||
{
|
||||
long int file_size;
|
||||
|
||||
fseek(sam->fp, 0, SEEK_END);
|
||||
file_size = ftell(sam->fp);
|
||||
fseek(sam->fp, 0, SEEK_SET);
|
||||
|
||||
if (file_size < 1)
|
||||
return;
|
||||
|
||||
sam->buffer = (char*) malloc(file_size + 2);
|
||||
|
||||
if (fread(sam->buffer, file_size, 1, sam->fp) != 1)
|
||||
{
|
||||
free(sam->buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
sam->buffer[file_size] = '\n';
|
||||
sam->buffer[file_size + 1] = '\0';
|
||||
|
||||
sam->line = strtok(sam->buffer, "\n");
|
||||
}
|
||||
|
||||
void SamLookupFinish(WINPR_SAM* sam)
|
||||
{
|
||||
free(sam->buffer);
|
||||
|
||||
sam->buffer = NULL;
|
||||
sam->line = NULL;
|
||||
}
|
||||
|
||||
void HexStrToBin(char* str, BYTE* bin, int length)
|
||||
{
|
||||
int i;
|
||||
|
||||
CharUpperBuffA(str, length * 2);
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
bin[i] = 0;
|
||||
|
||||
if ((str[i * 2] >= '0') && (str[i * 2] <= '9'))
|
||||
bin[i] |= (str[i * 2] - '0') << 4;
|
||||
|
||||
if ((str[i * 2] >= 'A') && (str[i * 2] <= 'F'))
|
||||
bin[i] |= (str[i * 2] - 'A' + 10) << 4;
|
||||
|
||||
if ((str[i * 2 + 1] >= '0') && (str[i * 2 + 1] <= '9'))
|
||||
bin[i] |= (str[i * 2 + 1] - '0');
|
||||
|
||||
if ((str[i * 2 + 1] >= 'A') && (str[i * 2 + 1] <= 'F'))
|
||||
bin[i] |= (str[i * 2 + 1] - 'A' + 10);
|
||||
}
|
||||
}
|
||||
|
||||
WINPR_SAM_ENTRY* SamReadEntry(WINPR_SAM* sam, WINPR_SAM_ENTRY* entry)
|
||||
{
|
||||
char* p[5];
|
||||
int LmHashLength;
|
||||
int NtHashLength;
|
||||
|
||||
p[0] = sam->line;
|
||||
p[1] = strchr(p[0], ':') + 1;
|
||||
p[2] = strchr(p[1], ':') + 1;
|
||||
p[3] = strchr(p[2], ':') + 1;
|
||||
p[4] = p[0] + strlen(p[0]);
|
||||
|
||||
entry->UserLength = p[1] - p[0] - 1;
|
||||
entry->DomainLength = p[2] - p[1] - 1;
|
||||
|
||||
LmHashLength = p[3] - p[2] - 1;
|
||||
NtHashLength = p[4] - p[3];
|
||||
|
||||
entry->User = (LPSTR) malloc(entry->UserLength + 1);
|
||||
memcpy(entry->User, p[0], entry->UserLength);
|
||||
entry->User[entry->UserLength] = '\0';
|
||||
|
||||
if (entry->DomainLength > 0)
|
||||
{
|
||||
entry->Domain = (LPSTR) malloc(entry->DomainLength + 1);
|
||||
memcpy(entry->Domain, p[1], entry->DomainLength);
|
||||
entry->Domain[entry->DomainLength] = '\0';
|
||||
}
|
||||
|
||||
if (LmHashLength == 32)
|
||||
{
|
||||
HexStrToBin(p[2], (BYTE*) entry->LmHash, 16);
|
||||
}
|
||||
|
||||
if (NtHashLength == 32)
|
||||
{
|
||||
HexStrToBin(p[3], (BYTE*) entry->NtHash, 16);
|
||||
}
|
||||
|
||||
printf("SamReadEntry: %s\n", entry->User);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
void SamFreeEntry(WINPR_SAM* sam, WINPR_SAM_ENTRY* entry)
|
||||
{
|
||||
if (entry)
|
||||
{
|
||||
if (entry->UserLength > 0)
|
||||
free(entry->User);
|
||||
|
||||
if (entry->DomainLength > 0)
|
||||
free(entry->Domain);
|
||||
|
||||
free(entry);
|
||||
}
|
||||
}
|
||||
|
||||
WINPR_SAM_ENTRY* SamLookupUserA(WINPR_SAM* sam, LPSTR User, UINT32 UserLength, LPSTR Domain, UINT32 DomainLength)
|
||||
{
|
||||
int length;
|
||||
BOOL found = 0;
|
||||
WINPR_SAM_ENTRY* entry;
|
||||
|
||||
entry = (WINPR_SAM_ENTRY*) malloc(sizeof(WINPR_SAM_ENTRY));
|
||||
|
||||
SamLookupStart(sam);
|
||||
|
||||
while (sam->line != NULL)
|
||||
{
|
||||
length = strlen(sam->line);
|
||||
|
||||
if (length > 1)
|
||||
{
|
||||
if (sam->line[0] != '#')
|
||||
{
|
||||
SamReadEntry(sam, entry);
|
||||
|
||||
if (strcmp(User, entry->User) == 0)
|
||||
{
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sam->line = strtok(NULL, "\n");
|
||||
}
|
||||
|
||||
SamLookupFinish(sam);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
free(entry);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
WINPR_SAM_ENTRY* SamLookupUserW(WINPR_SAM* sam, LPWSTR User, UINT32 UserLength, LPWSTR Domain, UINT32 DomainLength)
|
||||
{
|
||||
int length;
|
||||
BOOL found = 0;
|
||||
LPWSTR EntryUser;
|
||||
UINT32 EntryUserLength;
|
||||
WINPR_SAM_ENTRY* entry;
|
||||
|
||||
entry = (WINPR_SAM_ENTRY*) malloc(sizeof(WINPR_SAM_ENTRY));
|
||||
|
||||
SamLookupStart(sam);
|
||||
|
||||
while (sam->line != NULL)
|
||||
{
|
||||
length = strlen(sam->line);
|
||||
|
||||
if (length > 1)
|
||||
{
|
||||
if (sam->line[0] != '#')
|
||||
{
|
||||
entry = SamReadEntry(sam, entry);
|
||||
|
||||
EntryUserLength = strlen(entry->User) * 2;
|
||||
EntryUser = (LPWSTR) malloc(EntryUserLength + 2);
|
||||
MultiByteToWideChar(CP_ACP, 0, entry->User, EntryUserLength / 2,
|
||||
(LPWSTR) EntryUser, EntryUserLength / 2);
|
||||
|
||||
if (UserLength == EntryUserLength)
|
||||
{
|
||||
if (memcmp(User, EntryUser, UserLength) == 0)
|
||||
{
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sam->line = strtok(NULL, "\n");
|
||||
}
|
||||
|
||||
SamLookupFinish(sam);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
free(entry);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
void SamClose(WINPR_SAM* sam)
|
||||
{
|
||||
if (sam != NULL)
|
||||
{
|
||||
fclose(sam->fp);
|
||||
free(sam);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user