Merge pull request #630 from FreeRDP/winpr

WinPR Registry, SAM, SSPI NTLM
This commit is contained in:
Marc-André Moreau 2012-06-15 08:10:13 -07:00
commit c27d7954f6
64 changed files with 2752 additions and 709 deletions

View File

@ -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})

View File

@ -25,6 +25,7 @@
#cmakedefine WITH_PROFILER
#cmakedefine WITH_SSE2
#cmakedefine WITH_NEON
#cmakedefine WITH_NATIVE_SSPI
/* Debug */
#cmakedefine WITH_DEBUG_CERTIFICATE

View File

@ -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;

View File

@ -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
View 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
View 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 */

View File

@ -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
View 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 */

View File

@ -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
View 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 */

View File

@ -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>

View File

@ -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
View 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 */

View File

@ -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 */

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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)

View File

@ -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;
}

View File

@ -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:

View File

@ -32,4 +32,6 @@ if(NOT WIN32)
# Build Server Channels library
add_subdirectory(channels)
else()
add_subdirectory(Windows)
endif()

View 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
View 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
View 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
View 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
View File

@ -0,0 +1,3 @@
tools/hash/winpr-hash
tools/reg/winpr-reg

View File

@ -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)

View File

@ -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

View File

@ -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

View 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
View 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
View 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
View 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

View File

@ -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})

View File

@ -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;

View 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;
}
}

View 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);

View File

@ -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);
}

View File

@ -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})

View File

@ -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 */
};

View File

@ -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 */
};

View File

@ -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;

View File

@ -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)

View File

@ -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);

View File

@ -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 */
};

View File

@ -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 */
};

View File

@ -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);

View 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
View 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
View 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
View 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
View 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
View 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>

View 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)

View 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
View 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;
}

View 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
View 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;
}

View File

@ -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
View 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
View 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);
}
}