diff --git a/channels/rail/rail_orders.c b/channels/rail/rail_orders.c index 65c96c6d8..a5a641678 100644 --- a/channels/rail/rail_orders.c +++ b/channels/rail/rail_orders.c @@ -60,7 +60,7 @@ static const char* const RAIL_ORDER_TYPE_STRINGS[] = "Execute Result" }; -void rail_string_to_unicode_string(rdpRailOrder* rail_order, char* string, UNICODE_STRING* unicode_string) +void rail_string_to_unicode_string(rdpRailOrder* rail_order, char* string, RAIL_UNICODE_STRING* unicode_string) { char* buffer; size_t length = 0; diff --git a/channels/rail/rail_orders.h b/channels/rail/rail_orders.h index fbbe20f66..cd4e07bb5 100644 --- a/channels/rail/rail_orders.h +++ b/channels/rail/rail_orders.h @@ -54,7 +54,7 @@ #define RAIL_GET_APPID_REQ_ORDER_LENGTH 4 /* fixed */ #define RAIL_LANGBAR_INFO_ORDER_LENGTH 4 /* fixed */ -void rail_string_to_unicode_string(rdpRailOrder* rail_order, char* string, UNICODE_STRING* unicode_string); +void rail_string_to_unicode_string(rdpRailOrder* rail_order, char* string, RAIL_UNICODE_STRING* unicode_string); void rail_read_handshake_order(STREAM* s, RAIL_HANDSHAKE_ORDER* handshake); void rail_read_server_exec_result_order(STREAM* s, RAIL_EXEC_RESULT_ORDER* exec_result); diff --git a/include/freerdp/crypto/der.h b/include/freerdp/crypto/der.h index e692823b9..1902f93cb 100644 --- a/include/freerdp/crypto/der.h +++ b/include/freerdp/crypto/der.h @@ -30,6 +30,7 @@ FREERDP_API int der_skip_octet_string(int length); FREERDP_API int der_skip_sequence_tag(int length); FREERDP_API int der_write_sequence_tag(STREAM* s, int length); FREERDP_API int der_skip_contextual_tag(int length); +FREERDP_API int der_write_contextual_tag(STREAM* s, uint8 tag, int length, boolean pc); FREERDP_API void der_write_octet_string(STREAM* s, uint8* oct_str, int length); #endif /* FREERDP_CRYPTO_DER_H */ diff --git a/include/freerdp/rail.h b/include/freerdp/rail.h index 840e7f0c6..6ac2b4c2b 100644 --- a/include/freerdp/rail.h +++ b/include/freerdp/rail.h @@ -150,18 +150,18 @@ enum SPI_MASK #define TF_SFT_NOEXTRAICONSONMINIMIZED 0x00000400 #define TF_SFT_DESKBAND 0x00000800 -struct _UNICODE_STRING +struct _RAIL_UNICODE_STRING { uint16 length; uint8* string; }; -typedef struct _UNICODE_STRING UNICODE_STRING; +typedef struct _RAIL_UNICODE_STRING RAIL_UNICODE_STRING; struct _HIGH_CONTRAST { uint32 flags; uint32 colorSchemeLength; - UNICODE_STRING colorScheme; + RAIL_UNICODE_STRING colorScheme; }; typedef struct _HIGH_CONTRAST HIGH_CONTRAST; @@ -182,9 +182,9 @@ typedef struct _RAIL_CLIENT_STATUS_ORDER RAIL_CLIENT_STATUS_ORDER; struct _RAIL_EXEC_ORDER { uint16 flags; - UNICODE_STRING exeOrFile; - UNICODE_STRING workingDir; - UNICODE_STRING arguments; + RAIL_UNICODE_STRING exeOrFile; + RAIL_UNICODE_STRING workingDir; + RAIL_UNICODE_STRING arguments; }; typedef struct _RAIL_EXEC_ORDER RAIL_EXEC_ORDER; @@ -193,7 +193,7 @@ struct _RAIL_EXEC_RESULT_ORDER uint16 flags; uint16 execResult; uint32 rawResult; - UNICODE_STRING exeOrFile; + RAIL_UNICODE_STRING exeOrFile; }; typedef struct _RAIL_EXEC_RESULT_ORDER RAIL_EXEC_RESULT_ORDER; @@ -287,7 +287,7 @@ typedef struct _RAIL_GET_APPID_REQ_ORDER RAIL_GET_APPID_REQ_ORDER; struct _RAIL_GET_APPID_RESP_ORDER { uint32 windowId; - UNICODE_STRING applicationId; + RAIL_UNICODE_STRING applicationId; uint8 applicationIdBuffer[512]; }; typedef struct _RAIL_GET_APPID_RESP_ORDER RAIL_GET_APPID_RESP_ORDER; diff --git a/include/freerdp/rail/window.h b/include/freerdp/rail/window.h index 87eeb2318..7f32615b4 100644 --- a/include/freerdp/rail/window.h +++ b/include/freerdp/rail/window.h @@ -46,7 +46,7 @@ struct rdp_window uint32 style; uint32 extendedStyle; uint8 showState; - UNICODE_STRING titleInfo; + RAIL_UNICODE_STRING titleInfo; uint32 clientOffsetX; uint32 clientOffsetY; uint32 clientAreaWidth; diff --git a/include/freerdp/utils/rail.h b/include/freerdp/utils/rail.h index c47a16917..8ad2129fc 100644 --- a/include/freerdp/utils/rail.h +++ b/include/freerdp/utils/rail.h @@ -25,11 +25,11 @@ #include #include -FREERDP_API void rail_unicode_string_alloc(UNICODE_STRING* unicode_string, uint16 cbString); -FREERDP_API void rail_unicode_string_free(UNICODE_STRING* unicode_string); -FREERDP_API void rail_read_unicode_string(STREAM* s, UNICODE_STRING* unicode_string); -FREERDP_API void rail_write_unicode_string(STREAM* s, UNICODE_STRING* unicode_string); -FREERDP_API void rail_write_unicode_string_value(STREAM* s, UNICODE_STRING* unicode_string); +FREERDP_API void rail_unicode_string_alloc(RAIL_UNICODE_STRING* unicode_string, uint16 cbString); +FREERDP_API void rail_unicode_string_free(RAIL_UNICODE_STRING* unicode_string); +FREERDP_API void rail_read_unicode_string(STREAM* s, RAIL_UNICODE_STRING* unicode_string); +FREERDP_API void rail_write_unicode_string(STREAM* s, RAIL_UNICODE_STRING* unicode_string); +FREERDP_API void rail_write_unicode_string_value(STREAM* s, RAIL_UNICODE_STRING* unicode_string); FREERDP_API void* rail_clone_order(uint32 event_type, void* order); FREERDP_API void rail_free_cloned_order(uint32 event_type, void* order); diff --git a/include/freerdp/window.h b/include/freerdp/window.h index 3a4fcf098..3338e1757 100644 --- a/include/freerdp/window.h +++ b/include/freerdp/window.h @@ -155,8 +155,8 @@ struct _NOTIFY_ICON_INFOTIP { uint32 timeout; uint32 flags; - UNICODE_STRING text; - UNICODE_STRING title; + RAIL_UNICODE_STRING text; + RAIL_UNICODE_STRING title; }; typedef struct _NOTIFY_ICON_INFOTIP NOTIFY_ICON_INFOTIP; @@ -166,7 +166,7 @@ struct _WINDOW_STATE_ORDER uint32 style; uint32 extendedStyle; uint32 showState; - UNICODE_STRING titleInfo; + RAIL_UNICODE_STRING titleInfo; uint32 clientOffsetX; uint32 clientOffsetY; uint32 clientAreaWidth; @@ -203,7 +203,7 @@ typedef struct _WINDOW_CACHED_ICON_ORDER WINDOW_CACHED_ICON_ORDER; struct _NOTIFY_ICON_STATE_ORDER { uint32 version; - UNICODE_STRING toolTip; + RAIL_UNICODE_STRING toolTip; NOTIFY_ICON_INFOTIP infoTip; uint32 state; ICON_INFO icon; diff --git a/include/winpr/dsparse.h b/include/winpr/dsparse.h new file mode 100644 index 000000000..b180c8076 --- /dev/null +++ b/include/winpr/dsparse.h @@ -0,0 +1,60 @@ +/** + * WinPR: Windows Portable Runtime + * Active Directory Domain Services Parsing Functions + * + * Copyright 2012 Marc-Andre Moreau + * + * 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_DSPARSE_H +#define WINPR_DSPARSE_H + +#ifdef _WIN32 + +#include +#include + +#else + +#include +#include +#include + +WINPR_API DWORD DsCrackSpnW(LPCWSTR pszSpn, DWORD* pcServiceClass, LPWSTR ServiceClass, DWORD* pcServiceName, + LPWSTR ServiceName, DWORD* pcInstanceName, LPWSTR InstanceName, USHORT* pInstancePort); + +WINPR_API DWORD DsCrackSpnA(LPCSTR pszSpn, LPDWORD pcServiceClass, LPSTR ServiceClass, LPDWORD pcServiceName, + LPSTR ServiceName, LPDWORD pcInstanceName, LPSTR InstanceName, USHORT* pInstancePort); + +#ifdef UNICODE +#define DsCrackSpn DsCrackSpnW +#else +#define DsCrackSpn DsCrackSpnA +#endif + +WINPR_API DWORD DsMakeSpnW(LPCWSTR ServiceClass, LPCWSTR ServiceName, LPCWSTR InstanceName, + USHORT InstancePort, LPCWSTR Referrer, DWORD* pcSpnLength, LPWSTR pszSpn); + +WINPR_API DWORD DsMakeSpnA(LPCSTR ServiceClass, LPCSTR ServiceName, LPCSTR InstanceName, + USHORT InstancePort, LPCSTR Referrer, DWORD* pcSpnLength, LPSTR pszSpn); + +#ifdef UNICODE +#define DsMakeSpn DsMakeSpnW +#else +#define DsMakeSpn DsMakeSpnA +#endif + +#endif + +#endif /* WINPR_DSPARSE_H */ diff --git a/include/winpr/security.h b/include/winpr/security.h new file mode 100644 index 000000000..f4b97d8e7 --- /dev/null +++ b/include/winpr/security.h @@ -0,0 +1,34 @@ +/** + * WinPR: Windows Portable Runtime + * Security Definitions + * + * Copyright 2012 Marc-Andre Moreau + * + * 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_SECURITY_H +#define WINPR_SECURITY_H + +#include +#include + +typedef struct _LSA_UNICODE_STRING +{ + USHORT Length; + USHORT MaximumLength; + PWSTR Buffer; +} LSA_UNICODE_STRING, *PLSA_UNICODE_STRING, UNICODE_STRING, *PUNICODE_STRING; + +#endif /* WINPR_SECURITY_H */ + diff --git a/include/winpr/sspi.h b/include/winpr/sspi.h index bc375d692..e0881e566 100644 --- a/include/winpr/sspi.h +++ b/include/winpr/sspi.h @@ -26,6 +26,7 @@ #include #include #include +#include #ifdef _WIN32 diff --git a/include/winpr/sspicli.h b/include/winpr/sspicli.h new file mode 100644 index 000000000..602da2931 --- /dev/null +++ b/include/winpr/sspicli.h @@ -0,0 +1,90 @@ +/** + * WinPR: Windows Portable Runtime + * Security Support Provider Interface + * + * Copyright 2012 Marc-Andre Moreau + * + * 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_SSPICLI_H +#define WINPR_SSPICLI_H + +#include +#include +#include +#include +#include + +#ifndef _WIN32 + +typedef enum +{ + /* An unknown name type */ + NameUnknown = 0, + + /* The fully qualified distinguished name (for example, CN=Jeff Smith,OU=Users,DC=Engineering,DC=Microsoft,DC=Com) */ + NameFullyQualifiedDN = 1, + + /* + * A legacy account name (for example, Engineering\JSmith). + * The domain-only version includes trailing backslashes (\\) + */ + NameSamCompatible = 2, + + /* + * A "friendly" display name (for example, Jeff Smith). + * The display name is not necessarily the defining relative distinguished name (RDN) + */ + NameDisplay = 3, + + /* A GUID string that the IIDFromString function returns (for example, {4fa050f0-f561-11cf-bdd9-00aa003a77b6}) */ + NameUniqueId = 6, + + /* + * The complete canonical name (for example, engineering.microsoft.com/software/someone). + * The domain-only version includes a trailing forward slash (/) + */ + NameCanonical = 7, + + /* The user principal name (for example, someone@example.com) */ + NameUserPrincipal = 8, + + /* + * The same as NameCanonical except that the rightmost forward slash (/) + * is replaced with a new line character (\n), even in a domain-only case + * (for example, engineering.microsoft.com/software\nJSmith) + */ + NameCanonicalEx = 9, + + /* The generalized service principal name (for example, www/www.microsoft.com@microsoft.com) */ + NameServicePrincipal = 10, + + /* The DNS domain name followed by a backward-slash and the SAM user name */ + NameDnsDomain = 12 + +} EXTENDED_NAME_FORMAT, *PEXTENDED_NAME_FORMAT; + +WINPR_API BOOL GetUserNameExA(EXTENDED_NAME_FORMAT NameFormat, LPSTR lpNameBuffer, PULONG nSize); +WINPR_API BOOL GetUserNameExW(EXTENDED_NAME_FORMAT NameFormat, LPWSTR lpNameBuffer, PULONG nSize); + +#ifdef UNICODE +#define GetUserNameEx GetUserNameExW +#else +#define GetUserNameEx GetUserNameExA +#endif + +#endif + +#endif /* WINPR_SSPICLI_H */ + diff --git a/include/winpr/sysinfo.h b/include/winpr/sysinfo.h new file mode 100644 index 000000000..85ba5bdc4 --- /dev/null +++ b/include/winpr/sysinfo.h @@ -0,0 +1,151 @@ +/** + * WinPR: Windows Portable Runtime + * System Information + * + * Copyright 2012 Marc-Andre Moreau + * + * 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_SYSINFO_H +#define WINPR_SYSINFO_H + +#include +#include +#include +#include +#include + +#ifndef _WIN32 + +typedef enum _COMPUTER_NAME_FORMAT +{ + ComputerNameNetBIOS, + ComputerNameDnsHostname, + ComputerNameDnsDomain, + ComputerNameDnsFullyQualified, + ComputerNamePhysicalNetBIOS, + ComputerNamePhysicalDnsHostname, + ComputerNamePhysicalDnsDomain, + ComputerNamePhysicalDnsFullyQualified, + ComputerNameMax +} COMPUTER_NAME_FORMAT; + +WINPR_API BOOL GetComputerNameExA(COMPUTER_NAME_FORMAT NameType, LPSTR lpBuffer, LPDWORD nSize); +WINPR_API BOOL GetComputerNameExW(COMPUTER_NAME_FORMAT NameType, LPWSTR lpBuffer, LPDWORD nSize); + +#ifdef UNICODE +#define GetComputerNameEx GetComputerNameExW +#else +#define GetComputerNameEx GetComputerNameExA +#endif + +typedef struct _OSVERSIONINFOA +{ + DWORD dwOSVersionInfoSize; + DWORD dwMajorVersion; + DWORD dwMinorVersion; + DWORD dwBuildNumber; + DWORD dwPlatformId; + CHAR szCSDVersion[128]; +} OSVERSIONINFOA, *POSVERSIONINFOA, *LPOSVERSIONINFOA; + +typedef struct _OSVERSIONINFOW +{ + DWORD dwOSVersionInfoSize; + DWORD dwMajorVersion; + DWORD dwMinorVersion; + DWORD dwBuildNumber; + DWORD dwPlatformId; + WCHAR szCSDVersion[128]; +} OSVERSIONINFOW, *POSVERSIONINFOW, *LPOSVERSIONINFOW; + +typedef struct _OSVERSIONINFOEXA +{ + DWORD dwOSVersionInfoSize; + DWORD dwMajorVersion; + DWORD dwMinorVersion; + DWORD dwBuildNumber; + DWORD dwPlatformId; + CHAR szCSDVersion[128]; + WORD wServicePackMajor; + WORD wServicePackMinor; + WORD wSuiteMask; + BYTE wProductType; + BYTE wReserved; +} OSVERSIONINFOEXA, *POSVERSIONINFOEXA, *LPOSVERSIONINFOEXA; + +typedef struct _OSVERSIONINFOEXW +{ + DWORD dwOSVersionInfoSize; + DWORD dwMajorVersion; + DWORD dwMinorVersion; + DWORD dwBuildNumber; + DWORD dwPlatformId; + WCHAR szCSDVersion[128]; + WORD wServicePackMajor; + WORD wServicePackMinor; + WORD wSuiteMask; + BYTE wProductType; + BYTE wReserved; +} OSVERSIONINFOEXW, *POSVERSIONINFOEXW, *LPOSVERSIONINFOEXW; + +#ifdef UNICODE +#define OSVERSIONINFO OSVERSIONINFOW +#define OSVERSIONINFOEX OSVERSIONINFOEXW +#define POSVERSIONINFO POSVERSIONINFOW +#define POSVERSIONINFOEX POSVERSIONINFOEXW +#define LPOSVERSIONINFO LPOSVERSIONINFOW +#define LPOSVERSIONINFOEX LPOSVERSIONINFOEXW +#else +#define OSVERSIONINFO OSVERSIONINFOA +#define OSVERSIONINFOEX OSVERSIONINFOEXA +#define POSVERSIONINFO POSVERSIONINFOA +#define POSVERSIONINFOEX POSVERSIONINFOEXA +#define LPOSVERSIONINFO LPOSVERSIONINFOA +#define LPOSVERSIONINFOEX LPOSVERSIONINFOEXA +#endif + +#define VER_PLATFORM_WIN32_NT 0x00000002 + +#define VER_SUITE_BACKOFFICE 0x00000004 +#define VER_SUITE_BLADE 0x00000400 +#define VER_SUITE_COMPUTE_SERVER 0x00004000 +#define VER_SUITE_DATACENTER 0x00000080 +#define VER_SUITE_ENTERPRISE 0x00000002 +#define VER_SUITE_EMBEDDEDNT 0x00000040 +#define VER_SUITE_PERSONAL 0x00000200 +#define VER_SUITE_SINGLEUSERTS 0x00000100 +#define VER_SUITE_SMALLBUSINESS 0x00000001 +#define VER_SUITE_SMALLBUSINESS_RESTRICTED 0x00000020 +#define VER_SUITE_STORAGE_SERVER 0x00002000 +#define VER_SUITE_TERMINAL 0x00000010 +#define VER_SUITE_WH_SERVER 0x00008000 + +#define VER_NT_DOMAIN_CONTROLLER 0x0000002 +#define VER_NT_SERVER 0x0000003 +#define VER_NT_WORKSTATION 0x0000001 + +WINPR_API BOOL GetVersionExA(LPOSVERSIONINFOA lpVersionInformation); +WINPR_API BOOL GetVersionExW(LPOSVERSIONINFOW lpVersionInformation); + +#ifdef UNICODE +#define GetVersionEx GetVersionExW +#else +#define GetVersionEx GetVersionExA +#endif + +#endif + +#endif /* WINPR_SYSINFO_H */ + diff --git a/libfreerdp-core/connection.c b/libfreerdp-core/connection.c index a59a478e3..f82bb878e 100644 --- a/libfreerdp-core/connection.c +++ b/libfreerdp-core/connection.c @@ -524,6 +524,7 @@ boolean rdp_client_connect_finalize(rdpRdp* rdp) boolean rdp_server_accept_nego(rdpRdp* rdp, STREAM* s) { boolean status; + rdpSettings* settings = rdp->settings; transport_set_blocking_mode(rdp->transport, true); @@ -532,41 +533,35 @@ boolean rdp_server_accept_nego(rdpRdp* rdp, STREAM* s) rdp->nego->selected_protocol = 0; - printf("Requested protocols:"); + printf("Client Security: NLA:%d TLS:%d RDP:%d\n", + (rdp->nego->requested_protocols & PROTOCOL_NLA) ? 1 : 0, + (rdp->nego->requested_protocols & PROTOCOL_TLS) ? 1 : 0, + (rdp->nego->requested_protocols == PROTOCOL_RDP) ? 1: 0); - if ((rdp->nego->requested_protocols & PROTOCOL_TLS)) + printf("Server Security: NLA:%d TLS:%d RDP:%d\n", + settings->nla_security, settings->tls_security, settings->rdp_security); + + if ((settings->nla_security) && (rdp->nego->requested_protocols & PROTOCOL_NLA)) { - printf(" TLS"); - if (rdp->settings->tls_security) - { - printf("(Y)"); - rdp->nego->selected_protocol |= PROTOCOL_TLS; - } - else - printf("(n)"); + rdp->nego->selected_protocol = PROTOCOL_NLA; } - - if ((rdp->nego->requested_protocols & PROTOCOL_NLA)) + else if ((settings->tls_security) && (rdp->nego->requested_protocols & PROTOCOL_TLS)) { - printf(" NLA"); - if (rdp->settings->nla_security) - { - printf("(Y)"); - rdp->nego->selected_protocol |= PROTOCOL_NLA; - } - else - printf("(n)"); + rdp->nego->selected_protocol = PROTOCOL_TLS; } - - printf(" RDP"); - if (rdp->settings->rdp_security && rdp->nego->selected_protocol == 0) + else if ((settings->rdp_security) && (rdp->nego->selected_protocol == PROTOCOL_RDP)) { - printf("(Y)"); rdp->nego->selected_protocol = PROTOCOL_RDP; } else - printf("(n)"); - printf("\n"); + { + printf("Protocol security negotiation failure\n"); + } + + printf("Negotiated Security: NLA:%d TLS:%d RDP:%d\n", + (rdp->nego->selected_protocol & PROTOCOL_NLA) ? 1 : 0, + (rdp->nego->selected_protocol & PROTOCOL_TLS) ? 1 : 0, + (rdp->nego->selected_protocol == PROTOCOL_RDP) ? 1: 0); if (!nego_send_negotiation_response(rdp->nego)) return false; diff --git a/libfreerdp-core/nego.c b/libfreerdp-core/nego.c index b7ddbf0c3..f92d2edfc 100644 --- a/libfreerdp-core/nego.c +++ b/libfreerdp-core/nego.c @@ -297,15 +297,24 @@ boolean nego_recv(rdpTransport* transport, STREAM* s, void* extra) DEBUG_NEGO("selected_protocol: %d", nego->selected_protocol); /* enhanced security selected ? */ - if (nego->selected_protocol) { - if (nego->selected_protocol == PROTOCOL_NLA && - !nego->enabled_protocols[PROTOCOL_NLA]) + + if (nego->selected_protocol) + { + if ((nego->selected_protocol == PROTOCOL_NLA) && + (!nego->enabled_protocols[PROTOCOL_NLA])) + { nego->state = NEGO_STATE_FAIL; - if (nego->selected_protocol == PROTOCOL_TLS && - !nego->enabled_protocols[PROTOCOL_TLS]) + } + if ((nego->selected_protocol == PROTOCOL_TLS) && + (!nego->enabled_protocols[PROTOCOL_TLS])) + { nego->state = NEGO_STATE_FAIL; - } else if (!nego->enabled_protocols[PROTOCOL_RDP]) + } + } + else if (!nego->enabled_protocols[PROTOCOL_RDP]) + { nego->state = NEGO_STATE_FAIL; + } break; case TYPE_RDP_NEG_FAILURE: @@ -316,6 +325,7 @@ boolean nego_recv(rdpTransport* transport, STREAM* s, void* extra) else { DEBUG_NEGO("no rdpNegData"); + if (!nego->enabled_protocols[PROTOCOL_RDP]) nego->state = NEGO_STATE_FAIL; else @@ -368,6 +378,7 @@ boolean nego_read_request(rdpNego* nego, STREAM* s) /* rdpNegData (optional) */ stream_read_uint8(s, type); /* Type */ + if (type != TYPE_RDP_NEG_REQ) { printf("Incorrect negotiation request type %d\n", type); @@ -470,6 +481,8 @@ void nego_process_negotiation_request(rdpNego* nego, STREAM* s) stream_read_uint16(s, length); stream_read_uint32(s, nego->requested_protocols); + DEBUG_NEGO("requested_protocols: %d", nego->requested_protocols); + nego->state = NEGO_STATE_FINAL; } @@ -543,12 +556,13 @@ void nego_process_negotiation_failure(rdpNego* nego, STREAM* s) boolean nego_send_negotiation_response(rdpNego* nego) { STREAM* s; - rdpSettings* settings; + uint8* bm; + uint8* em; int length; - uint8 *bm, *em; - boolean ret; + boolean status; + rdpSettings* settings; - ret = true; + status = true; settings = nego->transport->settings; s = transport_send_stream_init(nego->transport, 256); @@ -577,7 +591,7 @@ boolean nego_send_negotiation_response(rdpNego* nego) printf("nego_send_negotiation_response: client supports only Standard RDP Security\n"); stream_write_uint32(s, SSL_REQUIRED_BY_SERVER); length += 8; - ret = false; + status = false; } stream_get_mark(s, em); @@ -589,7 +603,7 @@ boolean nego_send_negotiation_response(rdpNego* nego) if (transport_write(nego->transport, s) < 0) return false; - if (ret) + if (status) { /* update settings with negotiated protocol security */ settings->requested_protocols = nego->requested_protocols; @@ -600,12 +614,14 @@ boolean nego_send_negotiation_response(rdpNego* nego) settings->tls_security = false; settings->nla_security = false; settings->rdp_security = true; + if (!settings->local) { settings->encryption = true; settings->encryption_method = ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS; settings->encryption_level = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE; } + if (settings->encryption && settings->server_key == NULL && settings->rdp_key_file == NULL) return false; } @@ -629,7 +645,7 @@ boolean nego_send_negotiation_response(rdpNego* nego) } } - return ret; + return status; } /** diff --git a/libfreerdp-crypto/der.c b/libfreerdp-crypto/der.c index 8c127136f..395b94ec3 100644 --- a/libfreerdp-crypto/der.c +++ b/libfreerdp-crypto/der.c @@ -60,6 +60,11 @@ int der_get_content_length(int length) return length - 2; } +int der_skip_contextual_tag(int length) +{ + return _der_skip_length(length) + 1; +} + int der_write_contextual_tag(STREAM* s, uint8 tag, int length, boolean pc) { stream_write_uint8(s, (ER_CLASS_CTXT | ER_PC(pc)) | (ER_TAG_MASK & tag)); @@ -94,7 +99,3 @@ int der_write_sequence_tag(STREAM* s, int length) return der_write_length(s, length) + 1; } -int der_skip_contextual_tag(int length) -{ - return _der_skip_length(length) + 1; -} diff --git a/libfreerdp-crypto/nla.c b/libfreerdp-crypto/nla.c index fe882d9b4..df87c2232 100644 --- a/libfreerdp-crypto/nla.c +++ b/libfreerdp-crypto/nla.c @@ -90,7 +90,6 @@ void credssp_buffer_print(rdpCredssp* credssp); void credssp_buffer_free(rdpCredssp* credssp); SECURITY_STATUS credssp_encrypt_public_key_echo(rdpCredssp* credssp); SECURITY_STATUS credssp_decrypt_public_key_echo(rdpCredssp* credssp); -void credssp_encode_ts_credentials(rdpCredssp* credssp); SECURITY_STATUS credssp_encrypt_ts_credentials(rdpCredssp* credssp); SECURITY_STATUS credssp_decrypt_ts_credentials(rdpCredssp* credssp); @@ -311,7 +310,7 @@ int credssp_client_authenticate(rdpCredssp* credssp) return -1; #ifdef WITH_DEBUG_CREDSSP - printf("Receiving Authentication Token (%d)\n", credssp->negoToken.cbBuffer); + printf("Receiving Authentication Token (%d)\n", (int) credssp->negoToken.cbBuffer); winpr_HexDump(credssp->negoToken.pvBuffer, credssp->negoToken.cbBuffer); #endif @@ -520,8 +519,6 @@ int credssp_server_authenticate(rdpCredssp* credssp) return 0; } - printf("verifying public key echo\n"); - credssp_decrypt_public_key_echo(credssp); sspi_SecBufferFree(&credssp->negoToken); @@ -655,7 +652,7 @@ SECURITY_STATUS credssp_decrypt_public_key_echo(rdpCredssp* credssp) if (credssp->PublicKey.cbBuffer + credssp->ContextSizes.cbMaxSignature != credssp->pubKeyAuth.cbBuffer) { - printf("credssp_decrypt_public_key_echo: unexpected pubKeyAuth buffer size:%d\n", credssp->pubKeyAuth.cbBuffer); + printf("unexpected pubKeyAuth buffer size:%d\n", (int) credssp->pubKeyAuth.cbBuffer); return SEC_E_INVALID_TOKEN; } @@ -678,7 +675,7 @@ SECURITY_STATUS credssp_decrypt_public_key_echo(rdpCredssp* credssp) Message.ulVersion = SECBUFFER_VERSION; Message.pBuffers = (PSecBuffer) &Buffers; - status = credssp->table->DecryptMessage(&credssp->context, &Message, 0, &pfQOP); + status = credssp->table->DecryptMessage(&credssp->context, &Message, credssp->recv_seq_num++, &pfQOP); if (status != SEC_E_OK) { @@ -887,7 +884,6 @@ void credssp_encode_ts_credentials(rdpCredssp* credssp) SECURITY_STATUS credssp_encrypt_ts_credentials(rdpCredssp* credssp) { - BYTE* p; SecBuffer Buffers[2]; SecBufferDesc Message; SECURITY_STATUS status; @@ -897,37 +893,32 @@ SECURITY_STATUS credssp_encrypt_ts_credentials(rdpCredssp* credssp) Buffers[0].BufferType = SECBUFFER_TOKEN; /* Signature */ Buffers[1].BufferType = SECBUFFER_DATA; /* TSCredentials */ - Buffers[0].cbBuffer = 16; - Buffers[0].pvBuffer = xzalloc(Buffers[0].cbBuffer); + sspi_SecBufferAlloc(&credssp->authInfo, credssp->ContextSizes.cbMaxSignature + credssp->ts_credentials.cbBuffer); + + Buffers[0].cbBuffer = credssp->ContextSizes.cbMaxSignature; + Buffers[0].pvBuffer = credssp->authInfo.pvBuffer; + ZeroMemory(Buffers[0].pvBuffer, Buffers[0].cbBuffer); Buffers[1].cbBuffer = credssp->ts_credentials.cbBuffer; - Buffers[1].pvBuffer = malloc(Buffers[1].cbBuffer); + Buffers[1].pvBuffer = &((BYTE*) credssp->authInfo.pvBuffer)[Buffers[0].cbBuffer]; CopyMemory(Buffers[1].pvBuffer, credssp->ts_credentials.pvBuffer, Buffers[1].cbBuffer); Message.cBuffers = 2; Message.ulVersion = SECBUFFER_VERSION; Message.pBuffers = (PSecBuffer) &Buffers; - sspi_SecBufferAlloc(&credssp->authInfo, Buffers[0].cbBuffer + Buffers[1].cbBuffer); - status = credssp->table->EncryptMessage(&credssp->context, 0, &Message, credssp->send_seq_num++); if (status != SEC_E_OK) return status; - p = (BYTE*) credssp->authInfo.pvBuffer; - CopyMemory(p, Buffers[0].pvBuffer, Buffers[0].cbBuffer); /* Message Signature */ - CopyMemory(&p[Buffers[0].cbBuffer], Buffers[1].pvBuffer, Buffers[1].cbBuffer); /* Encrypted TSCredentials */ - - free(Buffers[0].pvBuffer); - free(Buffers[1].pvBuffer); - return SEC_E_OK; } SECURITY_STATUS credssp_decrypt_ts_credentials(rdpCredssp* credssp) { - BYTE* p; + int length; + BYTE* buffer; ULONG pfQOP; SecBuffer Buffers[2]; SecBufferDesc Message; @@ -942,21 +933,20 @@ SECURITY_STATUS credssp_decrypt_ts_credentials(rdpCredssp* credssp) return SEC_E_INVALID_TOKEN; } - Buffers[0].cbBuffer = 16; - Buffers[0].pvBuffer = malloc(Buffers[0].cbBuffer); - CopyMemory(Buffers[0].pvBuffer, credssp->authInfo.pvBuffer, Buffers[0].cbBuffer); + length = credssp->authInfo.cbBuffer; + buffer = (BYTE*) malloc(length); + CopyMemory(buffer, credssp->authInfo.pvBuffer, length); - Buffers[1].cbBuffer = credssp->authInfo.cbBuffer - Buffers[0].cbBuffer; - Buffers[1].pvBuffer = malloc(Buffers[1].cbBuffer); - p = (BYTE*) credssp->authInfo.pvBuffer; - CopyMemory(Buffers[1].pvBuffer, &p[Buffers[0].cbBuffer], Buffers[1].cbBuffer); + Buffers[0].cbBuffer = credssp->ContextSizes.cbMaxSignature; + Buffers[0].pvBuffer = buffer; + + Buffers[1].cbBuffer = length - credssp->ContextSizes.cbMaxSignature; + Buffers[1].pvBuffer = &buffer[credssp->ContextSizes.cbMaxSignature]; Message.cBuffers = 2; Message.ulVersion = SECBUFFER_VERSION; Message.pBuffers = (PSecBuffer) &Buffers; - sspi_SecBufferAlloc(&credssp->authInfo, Buffers[0].cbBuffer + Buffers[1].cbBuffer); - status = credssp->table->DecryptMessage(&credssp->context, &Message, credssp->recv_seq_num++, &pfQOP); if (status != SEC_E_OK) @@ -964,8 +954,7 @@ SECURITY_STATUS credssp_decrypt_ts_credentials(rdpCredssp* credssp) credssp_read_ts_credentials(credssp, &Buffers[1]); - free(Buffers[0].pvBuffer); - free(Buffers[1].pvBuffer); + free(buffer); return SEC_E_OK; } diff --git a/libfreerdp-crypto/tls.c b/libfreerdp-crypto/tls.c index beba56bc8..1bd2f9acb 100644 --- a/libfreerdp-crypto/tls.c +++ b/libfreerdp-crypto/tls.c @@ -56,6 +56,7 @@ static void tls_free_certificate(CryptoCert cert) boolean tls_connect(rdpTls* tls) { CryptoCert cert; + long options = 0; int connection_status; tls->ctx = SSL_CTX_new(TLSv1_client_method()); @@ -66,15 +67,34 @@ boolean tls_connect(rdpTls* tls) return false; } - /* - * This is necessary, because the Microsoft TLS implementation is not perfect. - * SSL_OP_ALL enables a couple of workarounds for buggy TLS implementations, - * but the most important workaround being SSL_OP_TLS_BLOCK_PADDING_BUG. - * As the size of the encrypted payload may give hints about its contents, - * block padding is normally used, but the Microsoft TLS implementation - * won't recognize it and will disconnect you after sending a TLS alert. + /** + * SSL_OP_NO_COMPRESSION: + * + * The Microsoft RDP server does not advertise support + * for TLS compression, but alternative servers may support it. + * This was observed between early versions of the FreeRDP server + * and the FreeRDP client, and caused major performance issues, + * which is why we're disabling it. */ - SSL_CTX_set_options(tls->ctx, SSL_OP_ALL); + options |= SSL_OP_NO_COMPRESSION; + + /** + * SSL_OP_TLS_BLOCK_PADDING_BUG: + * + * The Microsoft RDP server does *not* support TLS padding. + * It absolutely needs to be disabled otherwise it won't work. + */ + options |= SSL_OP_TLS_BLOCK_PADDING_BUG; + + /** + * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: + * + * Just like TLS padding, the Microsoft RDP server does not + * support empty fragments. This needs to be disabled. + */ + options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; + + SSL_CTX_set_options(tls->ctx, options); tls->ssl = SSL_new(tls->ctx); @@ -131,6 +151,7 @@ boolean tls_connect(rdpTls* tls) boolean tls_accept(rdpTls* tls, const char* cert_file, const char* privatekey_file) { CryptoCert cert; + long options = 0; int connection_status; tls->ctx = SSL_CTX_new(SSLv23_server_method()); @@ -142,10 +163,41 @@ boolean tls_accept(rdpTls* tls, const char* cert_file, const char* privatekey_fi } /* + * SSL_OP_NO_SSLv2: + * * We only want SSLv3 and TLSv1, so disable SSLv2. * SSLv3 is used by, eg. Microsoft RDC for Mac OS X. */ - SSL_CTX_set_options(tls->ctx, SSL_OP_NO_SSLv2); + options |= SSL_OP_NO_SSLv2; + + /** + * SSL_OP_NO_COMPRESSION: + * + * The Microsoft RDP server does not advertise support + * for TLS compression, but alternative servers may support it. + * This was observed between early versions of the FreeRDP server + * and the FreeRDP client, and caused major performance issues, + * which is why we're disabling it. + */ + options |= SSL_OP_NO_COMPRESSION; + + /** + * SSL_OP_TLS_BLOCK_PADDING_BUG: + * + * The Microsoft RDP server does *not* support TLS padding. + * It absolutely needs to be disabled otherwise it won't work. + */ + options |= SSL_OP_TLS_BLOCK_PADDING_BUG; + + /** + * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: + * + * Just like TLS padding, the Microsoft RDP server does not + * support empty fragments. This needs to be disabled. + */ + options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; + + SSL_CTX_set_options(tls->ctx, options); if (SSL_CTX_use_RSAPrivateKey_file(tls->ctx, privatekey_file, SSL_FILETYPE_PEM) <= 0) { diff --git a/libfreerdp-utils/rail.c b/libfreerdp-utils/rail.c index 4cf5906d5..dbd7d3f54 100644 --- a/libfreerdp-utils/rail.c +++ b/libfreerdp-utils/rail.c @@ -23,13 +23,13 @@ #include #include -void rail_unicode_string_alloc(UNICODE_STRING* unicode_string, uint16 cbString) +void rail_unicode_string_alloc(RAIL_UNICODE_STRING* unicode_string, uint16 cbString) { unicode_string->length = cbString; unicode_string->string = xzalloc(cbString); } -void rail_unicode_string_free(UNICODE_STRING* unicode_string) +void rail_unicode_string_free(RAIL_UNICODE_STRING* unicode_string) { unicode_string->length = 0; @@ -37,7 +37,7 @@ void rail_unicode_string_free(UNICODE_STRING* unicode_string) xfree(unicode_string->string); } -void rail_read_unicode_string(STREAM* s, UNICODE_STRING* unicode_string) +void rail_read_unicode_string(STREAM* s, RAIL_UNICODE_STRING* unicode_string) { stream_read_uint16(s, unicode_string->length); /* cbString (2 bytes) */ @@ -49,14 +49,14 @@ void rail_read_unicode_string(STREAM* s, UNICODE_STRING* unicode_string) stream_read(s, unicode_string->string, unicode_string->length); } -void rail_write_unicode_string(STREAM* s, UNICODE_STRING* unicode_string) +void rail_write_unicode_string(STREAM* s, RAIL_UNICODE_STRING* unicode_string) { stream_check_size(s, 2 + unicode_string->length); stream_write_uint16(s, unicode_string->length); /* cbString (2 bytes) */ stream_write(s, unicode_string->string, unicode_string->length); /* string */ } -void rail_write_unicode_string_value(STREAM* s, UNICODE_STRING* unicode_string) +void rail_write_unicode_string_value(STREAM* s, RAIL_UNICODE_STRING* unicode_string) { if (unicode_string->length > 0) { diff --git a/server/X11/xf_peer.c b/server/X11/xf_peer.c index 1689ac8e2..0fdb71730 100644 --- a/server/X11/xf_peer.c +++ b/server/X11/xf_peer.c @@ -634,6 +634,8 @@ void* xf_peer_main_loop(void* arg) settings->privatekey_file = freerdp_construct_path(server_file_path, "server.key"); settings->nla_security = true; + settings->tls_security = false; + settings->rdp_security = false; settings->rfx_codec = true; diff --git a/winpr/CMakeLists.txt b/winpr/CMakeLists.txt index 1b4e1b5f9..177734588 100644 --- a/winpr/CMakeLists.txt +++ b/winpr/CMakeLists.txt @@ -22,8 +22,11 @@ add_subdirectory(utils) add_subdirectory(heap) add_subdirectory(handle) add_subdirectory(synch) +add_subdirectory(sysinfo) add_subdirectory(bcrypt) +add_subdirectory(dsparse) add_subdirectory(rpc) +add_subdirectory(sspicli) add_subdirectory(sspi) add_subdirectory(registry) diff --git a/winpr/dsparse/CMakeLists.txt b/winpr/dsparse/CMakeLists.txt new file mode 100644 index 000000000..9d4e188d1 --- /dev/null +++ b/winpr/dsparse/CMakeLists.txt @@ -0,0 +1,28 @@ +# WinPR: Windows Portable Runtime +# libwinpr-dsparse cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# 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_DSPARSE_SRCS + dsparse.c) + +add_library(winpr-dsparse ${WINPR_DSPARSE_SRCS}) + +set_target_properties(winpr-dsparse PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") + +install(TARGETS winpr-dsparse DESTINATION ${CMAKE_INSTALL_LIBDIR}) + diff --git a/winpr/dsparse/dsparse.c b/winpr/dsparse/dsparse.c new file mode 100644 index 000000000..cf4e04926 --- /dev/null +++ b/winpr/dsparse/dsparse.c @@ -0,0 +1,68 @@ +/** + * WinPR: Windows Portable Runtime + * Active Directory Domain Services Parsing Functions + * + * Copyright 2012 Marc-Andre Moreau + * + * 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 + +/** + * dsparse.dll: + * + * DsCrackSpnA + * DsCrackSpnW + * DsCrackUnquotedMangledRdnA + * DsCrackUnquotedMangledRdnW + * DsGetRdnW + * DsIsMangledDnA + * DsIsMangledDnW + * DsIsMangledRdnValueA + * DsIsMangledRdnValueW + * DsMakeSpnA + * DsMakeSpnW + * DsQuoteRdnValueA + * DsQuoteRdnValueW + * DsUnquoteRdnValueA + * DsUnquoteRdnValueW + */ + +#ifndef _WIN32 + +DWORD DsCrackSpnW(LPCWSTR pszSpn, DWORD* pcServiceClass, LPWSTR ServiceClass, DWORD* pcServiceName, + LPWSTR ServiceName, DWORD* pcInstanceName, LPWSTR InstanceName, USHORT* pInstancePort) +{ + return 0; +} + +DWORD DsCrackSpnA(LPCSTR pszSpn, LPDWORD pcServiceClass, LPSTR ServiceClass, LPDWORD pcServiceName, + LPSTR ServiceName, LPDWORD pcInstanceName, LPSTR InstanceName, USHORT* pInstancePort) +{ + return 0; +} + +DWORD DsMakeSpnW(LPCWSTR ServiceClass, LPCWSTR ServiceName, LPCWSTR InstanceName, + USHORT InstancePort, LPCWSTR Referrer, DWORD* pcSpnLength, LPWSTR pszSpn) +{ + return 0; +} + +DWORD DsMakeSpnA(LPCSTR ServiceClass, LPCSTR ServiceName, LPCSTR InstanceName, + USHORT InstancePort, LPCSTR Referrer, DWORD* pcSpnLength, LPSTR pszSpn) +{ + return 0; +} + +#endif diff --git a/winpr/sspi/CMakeLists.txt b/winpr/sspi/CMakeLists.txt index 283822edc..6ec31db3a 100644 --- a/winpr/sspi/CMakeLists.txt +++ b/winpr/sspi/CMakeLists.txt @@ -61,6 +61,7 @@ set_target_properties(winpr-sspi PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVE if (NOT WIN32) target_link_libraries(winpr-sspi winpr-crt) + target_link_libraries(winpr-sspi winpr-sysinfo) endif() target_link_libraries(winpr-sspi winpr-utils) diff --git a/winpr/sspi/NTLM/ntlm.c b/winpr/sspi/NTLM/ntlm.c index ba3480d31..93e9c73bd 100644 --- a/winpr/sspi/NTLM/ntlm.c +++ b/winpr/sspi/NTLM/ntlm.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "ntlm.h" #include "../sspi.h" @@ -37,18 +38,42 @@ char* NTLM_PACKAGE_NAME = "NTLM"; void ntlm_SetContextWorkstation(NTLM_CONTEXT* context, char* Workstation) { + DWORD nSize = 0; + + if (!Workstation) + { + GetComputerNameExA(ComputerNameNetBIOS, NULL, &nSize); + Workstation = malloc(nSize); + GetComputerNameExA(ComputerNameNetBIOS, Workstation, &nSize); + } + context->WorkstationLength = strlen(Workstation) * 2; context->Workstation = (UINT16*) malloc(context->WorkstationLength); MultiByteToWideChar(CP_ACP, 0, Workstation, strlen(Workstation), (LPWSTR) context->Workstation, context->WorkstationLength / 2); + + if (nSize > 0) + free(Workstation); } void ntlm_SetContextTargetName(NTLM_CONTEXT* context, char* TargetName) { + DWORD nSize = 0; + + if (!TargetName) + { + GetComputerNameExA(ComputerNameDnsHostname, NULL, &nSize); + TargetName = malloc(nSize); + GetComputerNameExA(ComputerNameDnsHostname, TargetName, &nSize); + } + context->TargetName.cbBuffer = strlen(TargetName) * 2; context->TargetName.pvBuffer = (void*) malloc(context->TargetName.cbBuffer); MultiByteToWideChar(CP_ACP, 0, TargetName, strlen(TargetName), (LPWSTR) context->TargetName.pvBuffer, context->TargetName.cbBuffer / 2); + + if (nSize > 0) + free(TargetName); } NTLM_CONTEXT* ntlm_ContextNew() @@ -142,7 +167,9 @@ SECURITY_STATUS SEC_ENTRY ntlm_AcquireCredentialsHandleA(SEC_CHAR* pszPrincipal, credentials = sspi_CredentialsNew(); identity = (SEC_WINNT_AUTH_IDENTITY*) pAuthData; - CopyMemory(&(credentials->identity), identity, sizeof(SEC_WINNT_AUTH_IDENTITY)); + + if (identity != NULL) + CopyMemory(&(credentials->identity), identity, sizeof(SEC_WINNT_AUTH_IDENTITY)); sspi_SecureHandleSetLowerPointer(phCredential, (void*) credentials); sspi_SecureHandleSetUpperPointer(phCredential, (void*) NTLM_PACKAGE_NAME); @@ -154,7 +181,9 @@ SECURITY_STATUS SEC_ENTRY ntlm_AcquireCredentialsHandleA(SEC_CHAR* pszPrincipal, credentials = sspi_CredentialsNew(); identity = (SEC_WINNT_AUTH_IDENTITY*) pAuthData; - CopyMemory(&(credentials->identity), identity, sizeof(SEC_WINNT_AUTH_IDENTITY)); + + if (identity != NULL) + CopyMemory(&(credentials->identity), identity, sizeof(SEC_WINNT_AUTH_IDENTITY)); sspi_SecureHandleSetLowerPointer(phCredential, (void*) credentials); sspi_SecureHandleSetUpperPointer(phCredential, (void*) NTLM_PACKAGE_NAME); @@ -232,7 +261,7 @@ SECURITY_STATUS SEC_ENTRY ntlm_AcceptSecurityContext(PCredHandle phCredential, P credentials = (CREDENTIALS*) sspi_SecureHandleGetLowerPointer(phCredential); sspi_CopyAuthIdentity(&context->identity, &credentials->identity); - ntlm_SetContextTargetName(context, "FreeRDP"); + ntlm_SetContextTargetName(context, NULL); sspi_SecureHandleSetLowerPointer(phNewContext, context); sspi_SecureHandleSetUpperPointer(phNewContext, (void*) NTLM_PACKAGE_NAME); @@ -344,7 +373,7 @@ SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextA(PCredHandle phCredenti credentials = (CREDENTIALS*) sspi_SecureHandleGetLowerPointer(phCredential); sspi_CopyAuthIdentity(&context->identity, &credentials->identity); - ntlm_SetContextWorkstation(context, "WORKSTATION"); + ntlm_SetContextWorkstation(context, NULL); sspi_SecureHandleSetLowerPointer(phNewContext, context); sspi_SecureHandleSetUpperPointer(phNewContext, (void*) NTLM_PACKAGE_NAME); diff --git a/winpr/sspi/NTLM/ntlm_av_pairs.c b/winpr/sspi/NTLM/ntlm_av_pairs.c index 86c4575bd..29167fca6 100644 --- a/winpr/sspi/NTLM/ntlm_av_pairs.c +++ b/winpr/sspi/NTLM/ntlm_av_pairs.c @@ -22,6 +22,7 @@ #include #include +#include #include "ntlm_compute.h" @@ -327,39 +328,68 @@ void ntlm_populate_av_pairs(NTLM_CONTEXT* context) * @param NTLM context */ -char* test_NbDomainName = "FREERDP"; -char* test_NbComputerName = "FREERDP"; -char* test_DnsDomainName = "FreeRDP"; -char* test_DnsComputerName = "FreeRDP"; - void ntlm_populate_server_av_pairs(NTLM_CONTEXT* context) { int length; - AV_PAIRS* av_pairs = context->av_pairs; + DWORD nSize; + AV_PAIRS* av_pairs; + char* NbDomainName; + char* NbComputerName; + char* DnsDomainName; + char* DnsComputerName; - av_pairs->NbDomainName.length = strlen(test_NbDomainName) * 2; + av_pairs = context->av_pairs; + + nSize = 0; + GetComputerNameExA(ComputerNameNetBIOS, NULL, &nSize); + NbDomainName = malloc(nSize); + GetComputerNameExA(ComputerNameNetBIOS, NbDomainName, &nSize); + CharUpperA(NbDomainName); + + nSize = 0; + GetComputerNameExA(ComputerNameNetBIOS, NULL, &nSize); + NbComputerName = malloc(nSize); + GetComputerNameExA(ComputerNameNetBIOS, NbComputerName, &nSize); + CharUpperA(NbComputerName); + + nSize = 0; + GetComputerNameExA(ComputerNameDnsDomain, NULL, &nSize); + DnsDomainName = malloc(nSize); + GetComputerNameExA(ComputerNameDnsDomain, DnsDomainName, &nSize); + + nSize = 0; + GetComputerNameExA(ComputerNameDnsHostname, NULL, &nSize); + DnsComputerName = malloc(nSize); + GetComputerNameExA(ComputerNameDnsHostname, DnsComputerName, &nSize); + + av_pairs->NbDomainName.length = strlen(NbDomainName) * 2; av_pairs->NbDomainName.value = (BYTE*) malloc(av_pairs->NbDomainName.length); - MultiByteToWideChar(CP_ACP, 0, test_NbDomainName, strlen(test_NbDomainName), + MultiByteToWideChar(CP_ACP, 0, NbDomainName, strlen(NbDomainName), (LPWSTR) av_pairs->NbDomainName.value, av_pairs->NbDomainName.length / 2); - av_pairs->NbComputerName.length = strlen(test_NbDomainName) * 2; + av_pairs->NbComputerName.length = strlen(NbDomainName) * 2; av_pairs->NbComputerName.value = (BYTE*) malloc(av_pairs->NbComputerName.length); - MultiByteToWideChar(CP_ACP, 0, test_NbComputerName, strlen(test_NbComputerName), + MultiByteToWideChar(CP_ACP, 0, NbComputerName, strlen(NbComputerName), (LPWSTR) av_pairs->NbComputerName.value, av_pairs->NbComputerName.length / 2); - av_pairs->DnsDomainName.length = strlen(test_DnsDomainName) * 2; + av_pairs->DnsDomainName.length = strlen(DnsDomainName) * 2; av_pairs->DnsDomainName.value = (BYTE*) malloc(av_pairs->DnsDomainName.length); - MultiByteToWideChar(CP_ACP, 0, test_DnsDomainName, strlen(test_DnsDomainName), + MultiByteToWideChar(CP_ACP, 0, DnsDomainName, strlen(DnsDomainName), (LPWSTR) av_pairs->DnsDomainName.value, av_pairs->DnsDomainName.length / 2); - av_pairs->DnsComputerName.length = strlen(test_DnsComputerName) * 2; + av_pairs->DnsComputerName.length = strlen(DnsComputerName) * 2; av_pairs->DnsComputerName.value = (BYTE*) malloc(av_pairs->DnsComputerName.length); - MultiByteToWideChar(CP_ACP, 0, test_DnsComputerName, strlen(test_DnsComputerName), + MultiByteToWideChar(CP_ACP, 0, DnsComputerName, strlen(DnsComputerName), (LPWSTR) av_pairs->DnsComputerName.value, av_pairs->DnsComputerName.length / 2); length = ntlm_compute_av_pairs_length(context) + 4; sspi_SecBufferAlloc(&context->TargetInfo, length); ntlm_output_av_pairs(context, &context->TargetInfo); + + free(NbDomainName); + free(NbComputerName); + free(DnsDomainName); + free(DnsComputerName); } /** diff --git a/winpr/sspi/NTLM/ntlm_compute.c b/winpr/sspi/NTLM/ntlm_compute.c index ae17013a9..998eb8e94 100644 --- a/winpr/sspi/NTLM/ntlm_compute.c +++ b/winpr/sspi/NTLM/ntlm_compute.c @@ -169,8 +169,8 @@ void ntlm_fetch_ntlm_v2_hash(NTLM_CONTEXT* context, char* hash) sam = SamOpen(1); entry = SamLookupUserW(sam, - (LPWSTR) context->identity.User, context->identity.UserLength * 2, - (LPWSTR) context->identity.Domain, context->identity.DomainLength * 2); + (LPWSTR) context->identity.User, context->identity.UserLength, + (LPWSTR) context->identity.Domain, context->identity.DomainLength); if (entry != NULL) { diff --git a/winpr/sspi/NTLM/ntlm_message.c b/winpr/sspi/NTLM/ntlm_message.c index 8a7451ee2..ebf9b8a1d 100644 --- a/winpr/sspi/NTLM/ntlm_message.c +++ b/winpr/sspi/NTLM/ntlm_message.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "ntlm_compute.h" @@ -118,11 +119,15 @@ static const char* const NTLM_NEGOTIATE_STRINGS[] = void ntlm_output_version(PStream s) { - /* Version Info for Windows 7 SP1 */ + OSVERSIONINFOA osVersionInfo; - StreamWrite_UINT8(s, WINDOWS_MAJOR_VERSION_6); /* ProductMajorVersion (1 byte) */ - StreamWrite_UINT8(s, WINDOWS_MINOR_VERSION_1); /* ProductMinorVersion (1 byte) */ - StreamWrite_UINT16(s, 7601); /* ProductBuild (2 bytes) */ + osVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); + + GetVersionExA(&osVersionInfo); + + StreamWrite_UINT8(s, osVersionInfo.dwMajorVersion); /* ProductMajorVersion (1 byte) */ + StreamWrite_UINT8(s, osVersionInfo.dwMinorVersion); /* ProductMinorVersion (1 byte) */ + StreamWrite_UINT16(s, osVersionInfo.dwBuildNumber); /* ProductBuild (2 bytes) */ StreamZero(s, 3); /* Reserved (3 bytes) */ StreamWrite_UINT8(s, NTLMSSP_REVISION_W2K3); /* NTLMRevisionCurrent (1 byte) */ } diff --git a/winpr/sspicli/CMakeLists.txt b/winpr/sspicli/CMakeLists.txt new file mode 100644 index 000000000..b747a9d2f --- /dev/null +++ b/winpr/sspicli/CMakeLists.txt @@ -0,0 +1,28 @@ +# WinPR: Windows Portable Runtime +# libwinpr-sspicli cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# 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_SSPICLI_SRCS + sspicli.c) + +add_library(winpr-sspicli ${WINPR_SSPICLI_SRCS}) + +set_target_properties(winpr-sspicli PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") + +install(TARGETS winpr-sspicli DESTINATION ${CMAKE_INSTALL_LIBDIR}) + diff --git a/winpr/sspicli/sspicli.c b/winpr/sspicli/sspicli.c new file mode 100644 index 000000000..ef18f7e0c --- /dev/null +++ b/winpr/sspicli/sspicli.c @@ -0,0 +1,101 @@ +/** + * WinPR: Windows Portable Runtime + * Security Support Provider Interface + * + * Copyright 2012 Marc-Andre Moreau + * + * 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 + +/** + * sspicli.dll: + * + * EnumerateSecurityPackagesA + * EnumerateSecurityPackagesW + * GetUserNameExW + * ImportSecurityContextA + * LogonUserExExW + * SspiCompareAuthIdentities + * SspiCopyAuthIdentity + * SspiDecryptAuthIdentity + * SspiEncodeAuthIdentityAsStrings + * SspiEncodeStringsAsAuthIdentity + * SspiEncryptAuthIdentity + * SspiExcludePackage + * SspiFreeAuthIdentity + * SspiGetTargetHostName + * SspiIsAuthIdentityEncrypted + * SspiLocalFree + * SspiMarshalAuthIdentity + * SspiPrepareForCredRead + * SspiPrepareForCredWrite + * SspiUnmarshalAuthIdentity + * SspiValidateAuthIdentity + * SspiZeroAuthIdentity + */ + +#ifndef _WIN32 + +#include +#include + +BOOL GetUserNameExA(EXTENDED_NAME_FORMAT NameFormat, LPSTR lpNameBuffer, PULONG nSize) +{ + int length; + char* login; + + switch (NameFormat) + { + case NameSamCompatible: + + login = getlogin(); + length = strlen(login); + + if (*nSize >= length) + { + CopyMemory(lpNameBuffer, login, length + 1); + return 1; + } + else + { + *nSize = length + 1; + } + + break; + + case NameFullyQualifiedDN: + case NameDisplay: + case NameUniqueId: + case NameCanonical: + case NameUserPrincipal: + case NameCanonicalEx: + case NameServicePrincipal: + case NameDnsDomain: + break; + + default: + break; + } + + return 0; +} + +BOOL GetUserNameExW(EXTENDED_NAME_FORMAT NameFormat, LPWSTR lpNameBuffer, PULONG nSize) +{ + return 0; +} + +#endif + diff --git a/winpr/sysinfo/CMakeLists.txt b/winpr/sysinfo/CMakeLists.txt new file mode 100644 index 000000000..cf82e0be7 --- /dev/null +++ b/winpr/sysinfo/CMakeLists.txt @@ -0,0 +1,28 @@ +# WinPR: Windows Portable Runtime +# libwinpr-sysinfo cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# 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_SYSINFO_SRCS + sysinfo.c) + +add_library(winpr-sysinfo ${WINPR_SYSINFO_SRCS}) + +set_target_properties(winpr-sysinfo PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") + +install(TARGETS winpr-sysinfo DESTINATION ${CMAKE_INSTALL_LIBDIR}) + diff --git a/winpr/sysinfo/sysinfo.c b/winpr/sysinfo/sysinfo.c new file mode 100644 index 000000000..fb1e5d02a --- /dev/null +++ b/winpr/sysinfo/sysinfo.c @@ -0,0 +1,155 @@ +/** + * WinPR: Windows Portable Runtime + * System Information + * + * Copyright 2012 Marc-Andre Moreau + * + * 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 + +/** + * api-ms-win-core-sysinfo-l1-1-1.dll: + * + * EnumSystemFirmwareTables + * GetComputerNameExA + * GetComputerNameExW + * GetDynamicTimeZoneInformation + * GetLocalTime + * GetLogicalProcessorInformation + * GetLogicalProcessorInformationEx + * GetNativeSystemInfo + * GetProductInfo + * GetSystemDirectoryA + * GetSystemDirectoryW + * GetSystemFirmwareTable + * GetSystemInfo + * GetSystemTime + * GetSystemTimeAdjustment + * GetSystemTimeAsFileTime + * GetSystemWindowsDirectoryA + * GetSystemWindowsDirectoryW + * GetTickCount + * GetTickCount64 + * GetTimeZoneInformation + * GetTimeZoneInformationForYear + * GetVersion + * GetVersionExA + * GetVersionExW + * GetWindowsDirectoryA + * GetWindowsDirectoryW + * GlobalMemoryStatusEx + * SetComputerNameExW + * SetDynamicTimeZoneInformation + * SetLocalTime + * SetSystemTime + * SetTimeZoneInformation + * SystemTimeToFileTime + * SystemTimeToTzSpecificLocalTime + * TzSpecificLocalTimeToSystemTime + * VerSetConditionMask + */ + +#ifndef _WIN32 + +#include +#include + +BOOL GetComputerNameExA(COMPUTER_NAME_FORMAT NameType, LPSTR lpBuffer, LPDWORD nSize) +{ + char hostname[256]; + int hostname_length; + + gethostname(hostname, sizeof(hostname)); + hostname_length = strlen(hostname); + + switch (NameType) + { + case ComputerNameNetBIOS: + case ComputerNameDnsHostname: + case ComputerNameDnsDomain: + case ComputerNameDnsFullyQualified: + case ComputerNamePhysicalNetBIOS: + case ComputerNamePhysicalDnsHostname: + case ComputerNamePhysicalDnsDomain: + case ComputerNamePhysicalDnsFullyQualified: + + if (*nSize <= hostname_length) + { + *nSize = hostname_length + 1; + return 0; + } + + if (!lpBuffer) + return 0; + + CopyMemory(lpBuffer, hostname, hostname_length + 1); + + break; + + default: + return 0; + break; + } + + return 1; +} + +BOOL GetComputerNameExW(COMPUTER_NAME_FORMAT NameType, LPWSTR lpBuffer, LPDWORD nSize) +{ + printf("GetComputerNameExW unimplemented\n"); + return 0; +} + +/* OSVERSIONINFOEX Structure: + * http://msdn.microsoft.com/en-us/library/windows/desktop/ms724833 + */ + +BOOL GetVersionExA(LPOSVERSIONINFOA lpVersionInformation) +{ + /* Windows 7 SP1 Version Info */ + + if ((lpVersionInformation->dwOSVersionInfoSize == sizeof(OSVERSIONINFOA)) || + (lpVersionInformation->dwOSVersionInfoSize == sizeof(OSVERSIONINFOEXA))) + { + lpVersionInformation->dwMajorVersion = 6; + lpVersionInformation->dwMinorVersion = 1; + lpVersionInformation->dwBuildNumber = 7601; + lpVersionInformation->dwPlatformId = VER_PLATFORM_WIN32_NT; + ZeroMemory(lpVersionInformation->szCSDVersion, sizeof(lpVersionInformation->szCSDVersion)); + + if (lpVersionInformation->dwOSVersionInfoSize == sizeof(OSVERSIONINFOEXA)) + { + LPOSVERSIONINFOEXA lpVersionInformationEx = (LPOSVERSIONINFOEXA) lpVersionInformation; + + lpVersionInformationEx->wServicePackMajor = 1; + lpVersionInformationEx->wServicePackMinor = 0; + lpVersionInformationEx->wSuiteMask = 0; + lpVersionInformationEx->wProductType = VER_NT_WORKSTATION; + lpVersionInformationEx->wReserved = 0; + } + + return 1; + } + + return 0; +} + +BOOL GetVersionExW(LPOSVERSIONINFOW lpVersionInformation) +{ + printf("GetVersionExW unimplemented\n"); + return 1; +} + +#endif diff --git a/winpr/utils/sam.c b/winpr/utils/sam.c index 684d38283..58bb3d4bb 100644 --- a/winpr/utils/sam.c +++ b/winpr/utils/sam.c @@ -149,8 +149,6 @@ WINPR_SAM_ENTRY* SamReadEntry(WINPR_SAM* sam, WINPR_SAM_ENTRY* entry) HexStrToBin(p[3], (BYTE*) entry->NtHash, 16); } - printf("SamReadEntry: %s\n", entry->User); - return entry; }