Merge pull request #579 from FreeRDP/tsg

Terminal Server Gateway (Round 1)
This commit is contained in:
Marc-André Moreau
2012-05-05 17:32:20 -07:00
90 changed files with 8959 additions and 88 deletions

View File

@@ -79,6 +79,7 @@ if(MSVC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /O2 /Ob2")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_X86_")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_UNICODE")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWINPR_EXPORTS")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFREERDP_EXPORTS")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_CRT_SECURE_NO_WARNINGS")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWIN32_LEAN_AND_MEAN")
@@ -155,11 +156,13 @@ add_subdirectory(libfreerdp-rail)
add_subdirectory(libfreerdp-cache)
add_subdirectory(libfreerdp-codec)
add_subdirectory(libfreerdp-crypto)
add_subdirectory(libfreerdp-sspi)
add_subdirectory(libfreerdp-channels)
add_subdirectory(libfreerdp-locale)
add_subdirectory(libfreerdp-core)
add_subdirectory(libwinpr-rpc)
add_subdirectory(libwinpr-sspi)
if(NOT WIN32)
add_subdirectory(channels)
endif()

View File

@@ -19,7 +19,7 @@
* limitations under the License.
*/
#include <freerdp/utils/windows.h>
#include <winpr/windows.h>
#include <errno.h>
#include <stdio.h>

View File

@@ -22,7 +22,7 @@
#ifndef __WFREERDP_H
#define __WFREERDP_H
#include <freerdp/utils/windows.h>
#include <winpr/windows.h>
#include <freerdp/freerdp.h>
#include <freerdp/gdi/gdi.h>

View File

@@ -14,6 +14,7 @@ option(WITH_DEBUG_LICENSE "Print license debug messages." OFF)
option(WITH_DEBUG_NEGO "Print negotiation related debug messages." OFF)
option(WITH_DEBUG_NLA "Print authentication related debug messages." OFF)
option(WITH_DEBUG_NTLM "Print NTLM debug messages" OFF)
option(WITH_DEBUG_TSG "Print Terminal Server Gateway debug messages" OFF)
option(WITH_DEBUG_ORDERS "Print drawing orders debug messages" OFF)
option(WITH_DEBUG_RAIL "Print RemoteApp debug messages" OFF)
option(WITH_DEBUG_RDP "Print RDP debug messages" OFF)

View File

@@ -37,6 +37,7 @@
#cmakedefine WITH_DEBUG_NEGO
#cmakedefine WITH_DEBUG_NLA
#cmakedefine WITH_DEBUG_NTLM
#cmakedefine WITH_DEBUG_TSG
#cmakedefine WITH_DEBUG_ORDERS
#cmakedefine WITH_DEBUG_RAIL
#cmakedefine WITH_DEBUG_RDP

View File

@@ -21,7 +21,7 @@
#define FREERDP_CRYPTO_H
/* OpenSSL includes windows.h */
#include <freerdp/utils/windows.h>
#include <winpr/windows.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
@@ -142,4 +142,7 @@ FREERDP_API void crypto_rsa_private_decrypt(const uint8* input, int length, uint
FREERDP_API void crypto_reverse(uint8* data, int length);
FREERDP_API void crypto_nonce(uint8* nonce, int size);
FREERDP_API char* crypto_base64_encode(uint8* data, int length);
FREERDP_API void crypto_base64_decode(uint8* enc_data, int length, uint8** dec_data, int* res_length);
#endif /* FREERDP_CRYPTO_H */

View File

@@ -49,6 +49,8 @@ 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_write_all(rdpTls* tls, uint8* data, int length);
FREERDP_API boolean tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname);
FREERDP_API void tls_print_certificate_error(char* hostname, char* fingerprint);
FREERDP_API void tls_print_certificate_name_mismatch_error(char* hostname, char* common_name, char** alt_names, int alt_names_count);

View File

@@ -288,7 +288,11 @@ struct rdp_settings
ALIGN64 rdpBlob* password_cookie; /* 61 */
ALIGN64 char* kerberos_kdc; /* 62 */
ALIGN64 char* kerberos_realm; /* 63 */
ALIGN64 uint64 paddingC[80 - 64]; /* 64 */
ALIGN64 boolean ts_gateway; /* 64 */
ALIGN64 char* tsg_hostname; /* 65 */
ALIGN64 char* tsg_username; /* 66 */
ALIGN64 char* tsg_password; /* 67 */
ALIGN64 uint64 paddingC[80 - 68]; /* 68 */
/* User Interface Parameters */
ALIGN64 boolean sw_gdi; /* 80 */

View File

@@ -119,6 +119,16 @@ typedef int boolean;
#include <freerdp/settings.h>
typedef struct
{
uint32 time_low;
uint16 time_mid;
uint16 time_hi_and_version;
uint8 clock_seq_hi_and_reserved;
uint8 clock_seq_low;
uint8 node[6];
} uuid;
struct _RDP_PLUGIN_DATA
{
uint16 size;

View File

@@ -48,7 +48,7 @@ typedef struct _UNICONV UNICONV;
FREERDP_API UNICONV* freerdp_uniconv_new();
FREERDP_API void freerdp_uniconv_free(UNICONV *uniconv);
FREERDP_API char* freerdp_uniconv_in(UNICONV *uniconv, unsigned char* pin, size_t in_len);
FREERDP_API char* freerdp_uniconv_out(UNICONV *uniconv, char *str, size_t *pout_len);
FREERDP_API char* freerdp_uniconv_out(UNICONV *uniconv, const char *str, size_t *pout_len);
FREERDP_API void freerdp_uniconv_uppercase(UNICONV *uniconv, char *wstr, int length);
#endif /* __UNICODE_UTILS_H */

View File

@@ -28,7 +28,7 @@ typedef struct rdp_credssp rdpCredssp;
#include <freerdp/utils/stream.h>
#include <freerdp/utils/hexdump.h>
#include <freerdp/sspi/sspi.h>
#include <winpr/sspi.h>
#include <freerdp/crypto/tls.h>
#include <freerdp/crypto/ber.h>

28
include/winpr/midl.h Normal file
View File

@@ -0,0 +1,28 @@
/**
* WinPR: Windows Portable Runtime
* Microsoft Remote Procedure Call (MSRPC)
*
* 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_RPC_MIDL_H
#define WINPR_RPC_MIDL_H
#include <winpr/rpc.h>
WINPR_API void* MIDL_user_allocate(size_t cBytes);
WINPR_API void MIDL_user_free(void* p);
#endif /* WINPR_RPC_MIDL_H */

530
include/winpr/ndr.h Normal file
View File

@@ -0,0 +1,530 @@
/**
* WinPR: Windows Portable Runtime
* Network Data Representation (NDR)
*
* 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_RPC_NDR_H
#define WINPR_RPC_NDR_H
#include <winpr/rpc.h>
#include <winpr/wtypes.h>
#define __RPC_WIN32__ 1
#define TARGET_IS_NT50_OR_LATER 1
typedef union _CLIENT_CALL_RETURN
{
void* Pointer;
LONG_PTR Simple;
} CLIENT_CALL_RETURN;
typedef void* RPC_IF_HANDLE;
typedef struct _RPC_VERSION
{
unsigned short MajorVersion;
unsigned short MinorVersion;
} RPC_VERSION;
typedef struct _RPC_SYNTAX_IDENTIFIER
{
GUID SyntaxGUID;
RPC_VERSION SyntaxVersion;
} RPC_SYNTAX_IDENTIFIER, PRPC_SYNTAX_IDENTIFIER;
#define RPC_MGR_EPV void
typedef struct _RPC_MESSAGE
{
RPC_BINDING_HANDLE Handle;
unsigned long DataRepresentation;
void* Buffer;
unsigned int BufferLength;
unsigned int ProcNum;
PRPC_SYNTAX_IDENTIFIER TransferSyntax;
void* RpcInterfaceInformation;
void* ReservedForRuntime;
RPC_MGR_EPV* ManagerEpv;
void* ImportContext;
unsigned long RpcFlags;
} RPC_MESSAGE, *PRPC_MESSAGE;
typedef void (*RPC_DISPATCH_FUNCTION)(PRPC_MESSAGE Message);
typedef struct
{
unsigned int DispatchTableCount;
RPC_DISPATCH_FUNCTION* DispatchTable;
LONG_PTR Reserved;
} RPC_DISPATCH_TABLE, *PRPC_DISPATCH_TABLE;
typedef struct _RPC_PROTSEQ_ENDPOINT
{
unsigned char* RpcProtocolSequence;
unsigned char* Endpoint;
} RPC_PROTSEQ_ENDPOINT, * PRPC_PROTSEQ_ENDPOINT;
typedef struct _RPC_SERVER_INTERFACE
{
unsigned int Length;
RPC_SYNTAX_IDENTIFIER InterfaceId;
RPC_SYNTAX_IDENTIFIER TransferSyntax;
PRPC_DISPATCH_TABLE DispatchTable;
unsigned int RpcProtseqEndpointCount;
PRPC_PROTSEQ_ENDPOINT RpcProtseqEndpoint;
RPC_MGR_EPV* DefaultManagerEpv;
void const* InterpreterInfo;
unsigned int Flags;
} RPC_SERVER_INTERFACE, *PRPC_SERVER_INTERFACE;
typedef struct _RPC_CLIENT_INTERFACE
{
unsigned int Length;
RPC_SYNTAX_IDENTIFIER InterfaceId;
RPC_SYNTAX_IDENTIFIER TransferSyntax;
PRPC_DISPATCH_TABLE DispatchTable;
unsigned int RpcProtseqEndpointCount;
PRPC_PROTSEQ_ENDPOINT RpcProtseqEndpoint;
ULONG_PTR Reserved;
void const* InterpreterInfo;
unsigned int Flags;
} RPC_CLIENT_INTERFACE, *PRPC_CLIENT_INTERFACE;
typedef void* (*GENERIC_BINDING_ROUTINE)(void*);
typedef void (*GENERIC_UNBIND_ROUTINE)(void*, unsigned char*);
typedef struct _GENERIC_BINDING_ROUTINE_PAIR
{
GENERIC_BINDING_ROUTINE pfnBind;
GENERIC_UNBIND_ROUTINE pfnUnbind;
} GENERIC_BINDING_ROUTINE_PAIR, *PGENERIC_BINDING_ROUTINE_PAIR;
typedef struct __GENERIC_BINDING_INFO
{
void* pObj;
unsigned int Size;
GENERIC_BINDING_ROUTINE pfnBind;
GENERIC_UNBIND_ROUTINE pfnUnbind;
} GENERIC_BINDING_INFO, *PGENERIC_BINDING_INFO;
typedef void (*NDR_RUNDOWN)(void* context);
typedef void (*NDR_NOTIFY_ROUTINE)(void);
typedef const unsigned char* PFORMAT_STRING;
typedef struct _MIDL_STUB_DESC MIDL_STUB_DESC;
typedef MIDL_STUB_DESC* PMIDL_STUB_DESC;
typedef struct _MIDL_STUB_MESSAGE
{
PRPC_MESSAGE RpcMsg;
unsigned char* Buffer;
unsigned char* BufferStart;
unsigned char* BufferEnd;
unsigned char* BufferMark;
unsigned long BufferLength;
unsigned long MemorySize;
unsigned char* Memory;
int IsClient;
int ReuseBuffer;
struct NDR_ALLOC_ALL_NODES_CONTEXT* pAllocAllNodesContext;
struct NDR_POINTER_QUEUE_STATE* pPointerQueueState;
int IgnoreEmbeddedPointers;
unsigned char* PointerBufferMark;
unsigned char fBufferValid;
unsigned char uFlags;
unsigned short Unused2;
ULONG_PTR MaxCount;
unsigned long Offset;
unsigned long ActualCount;
void *(*pfnAllocate)(size_t);
void (*pfnFree)(void*);
unsigned char* StackTop;
unsigned char* pPresentedType;
unsigned char* pTransmitType;
handle_t SavedHandle;
const struct _MIDL_STUB_DESC* StubDesc;
struct _FULL_PTR_XLAT_TABLES* FullPtrXlatTables;
unsigned long FullPtrRefId;
unsigned long PointerLength;
int fInDontFree : 1;
int fDontCallFreeInst : 1;
int fInOnlyParam : 1;
int fHasReturn : 1;
int fHasExtensions : 1;
int fHasNewCorrDesc : 1;
int fUnused : 10;
int fUnused2 : 16;
unsigned long dwDestContext;
void* pvDestContext;
//NDR_SCONTEXT* SavedContextHandles;
long ParamNumber;
struct IRpcChannelBuffer* pRpcChannelBuffer;
//PARRAY_INFO pArrayInfo;
unsigned long* SizePtrCountArray;
unsigned long* SizePtrOffsetArray;
unsigned long* SizePtrLengthArray;
void* pArgQueue;
unsigned long dwStubPhase;
void* LowStackMark;
//PNDR_ASYNC_MESSAGE pAsyncMsg;
//PNDR_CORRELATION_INFO pCorrInfo;
unsigned char* pCorrMemory;
void* pMemoryList;
//CS_STUB_INFO* pCSInfo;
unsigned char* ConformanceMark;
unsigned char* VarianceMark;
void* BackingStoreLowMark;
INT_PTR Unused;
struct _NDR_PROC_CONTEXT* pContext;
INT_PTR Reserved51_1;
INT_PTR Reserved51_2;
INT_PTR Reserved51_3;
INT_PTR Reserved51_4;
INT_PTR Reserved51_5;
} MIDL_STUB_MESSAGE, *PMIDL_STUB_MESSAGE;
typedef struct _MIDL_STUB_MESSAGE MIDL_STUB_MESSAGE, *PMIDL_STUB_MESSAGE;
typedef void (*EXPR_EVAL)(struct _MIDL_STUB_MESSAGE*);
typedef void (*XMIT_HELPER_ROUTINE)(PMIDL_STUB_MESSAGE);
typedef struct _XMIT_ROUTINE_QUINTUPLE
{
XMIT_HELPER_ROUTINE pfnTranslateToXmit;
XMIT_HELPER_ROUTINE pfnTranslateFromXmit;
XMIT_HELPER_ROUTINE pfnFreeXmit;
XMIT_HELPER_ROUTINE pfnFreeInst;
} XMIT_ROUTINE_QUINTUPLE, *PXMIT_ROUTINE_QUINTUPLE;
typedef unsigned long (*USER_MARSHAL_SIZING_ROUTINE)(unsigned long*, unsigned long, void*);
typedef unsigned char* (*USER_MARSHAL_MARSHALLING_ROUTINE)(unsigned long*, unsigned char*, void*);
typedef unsigned char* (*USER_MARSHAL_UNMARSHALLING_ROUTINE)(unsigned long*, unsigned char*, void*);
typedef void (*USER_MARSHAL_FREEING_ROUTINE)(unsigned long*, void*);
typedef struct _USER_MARSHAL_ROUTINE_QUADRUPLE
{
USER_MARSHAL_SIZING_ROUTINE pfnBufferSize;
USER_MARSHAL_MARSHALLING_ROUTINE pfnMarshall;
USER_MARSHAL_UNMARSHALLING_ROUTINE pfnUnmarshall;
USER_MARSHAL_FREEING_ROUTINE pfnFree;
} USER_MARSHAL_ROUTINE_QUADRUPLE;
typedef struct _MALLOC_FREE_STRUCT
{
void* (*pfnAllocate)(size_t);
void (*pfnFree)(void*);
} MALLOC_FREE_STRUCT;
typedef struct _COMM_FAULT_OFFSETS
{
short CommOffset;
short FaultOffset;
} COMM_FAULT_OFFSETS;
typedef void* NDR_CS_ROUTINES;
typedef void* NDR_EXPR_DESC;
struct _MIDL_STUB_DESC
{
void* RpcInterfaceInformation;
void* (*pfnAllocate)(size_t);
void (*pfnFree)(void*);
union
{
handle_t* pAutoHandle;
handle_t* pPrimitiveHandle;
PGENERIC_BINDING_INFO pGenericBindingInfo;
} IMPLICIT_HANDLE_INFO;
const NDR_RUNDOWN* apfnNdrRundownRoutines;
const GENERIC_BINDING_ROUTINE_PAIR* aGenericBindingRoutinePairs;
const EXPR_EVAL* apfnExprEval;
const XMIT_ROUTINE_QUINTUPLE* aXmitQuintuple;
const unsigned char* pFormatTypes;
int fCheckBounds;
unsigned long Version;
MALLOC_FREE_STRUCT* pMallocFreeStruct;
long MIDLVersion;
const COMM_FAULT_OFFSETS* CommFaultOffsets;
const USER_MARSHAL_ROUTINE_QUADRUPLE* aUserMarshalQuadruple;
const NDR_NOTIFY_ROUTINE* NotifyRoutineTable;
ULONG_PTR mFlags;
const NDR_CS_ROUTINES* CsRoutineTables;
void* ProxyServerInfo;
const NDR_EXPR_DESC* pExprInfo;
};
typedef struct
{
unsigned char FullPtrUsed : 1;
unsigned char RpcSsAllocUsed : 1;
unsigned char ObjectProc : 1;
unsigned char HasRpcFlags : 1;
unsigned char IgnoreObjectException : 1;
unsigned char HasCommOrFault : 1;
unsigned char UseNewInitRoutines : 1;
unsigned char Unused : 1;
} INTERPRETER_FLAGS, *PINTERPRETER_FLAGS;
typedef struct
{
unsigned short MustSize : 1;
unsigned short MustFree : 1;
unsigned short IsPipe : 1;
unsigned short IsIn : 1;
unsigned short IsOut : 1;
unsigned short IsReturn : 1;
unsigned short IsBasetype : 1;
unsigned short IsByValue : 1;
unsigned short IsSimpleRef : 1;
unsigned short IsDontCallFreeInst : 1;
unsigned short SaveForAsyncFinish : 1;
unsigned short Unused : 2;
unsigned short ServerAllocSize : 3;
} PARAM_ATTRIBUTES, *PPARAM_ATTRIBUTES;
typedef struct
{
unsigned char ServerMustSize : 1;
unsigned char ClientMustSize : 1;
unsigned char HasReturn : 1;
unsigned char HasPipes : 1;
unsigned char Unused : 1;
unsigned char HasAsyncUuid : 1;
unsigned char HasExtensions : 1;
unsigned char HasAsyncHandle : 1;
} INTERPRETER_OPT_FLAGS, *PINTERPRETER_OPT_FLAGS;
typedef struct
{
unsigned char HasNewCorrDesc : 1;
unsigned char ClientCorrCheck : 1;
unsigned char ServerCorrCheck : 1;
unsigned char HasNotify : 1;
unsigned char HasNotify2 : 1;
unsigned char Unused : 3;
} INTERPRETER_OPT_FLAGS2, *PINTERPRETER_OPT_FLAGS2;
typedef struct _NDR_CORRELATION_FLAGS
{
unsigned char Early : 1;
unsigned char Split : 1;
unsigned char IsIidIs : 1;
unsigned char DontCheck : 1;
unsigned char Unused : 4;
} NDR_CORRELATION_FLAGS;
#define FC_ALLOCATE_ALL_NODES 0x01
#define FC_DONT_FREE 0x02
#define FC_ALLOCED_ON_STACK 0x03
#define FC_SIMPLE_POINTER 0x04
#define FC_POINTER_DEREF 0x05
#define HANDLE_PARAM_IS_VIA_PTR 0x80
#define HANDLE_PARAM_IS_IN 0x40
#define HANDLE_PARAM_IS_OUT 0x20
#define HANDLE_PARAM_IS_RETURN 0x21
#define NDR_STRICT_CONTEXT_HANDLE 0x08
#define NDR_CONTEXT_HANDLE_NO_SERIALIZE 0x04
#define NDR_CONTEXT_HANDLE_SERIALIZE 0x02
#define NDR_CONTEXT_HANDLE_CANNOT_BE_NULL 0x01
typedef struct
{
PARAM_ATTRIBUTES Attributes;
unsigned short StackOffset;
union
{
unsigned char FormatChar;
unsigned short Offset;
} Type;
} NDR_PARAM;
typedef struct
{
unsigned char Size;
INTERPRETER_OPT_FLAGS2 Flags2;
unsigned short ClientCorrHint;
unsigned short ServerCorrHint;
unsigned short NotifyIndex;
} NDR_PROC_HEADER_EXTS;
typedef struct _NDR_PROC_HEADER
{
unsigned char HandleType;
INTERPRETER_FLAGS OldOiFlags;
unsigned short RpcFlagsLow;
unsigned short RpcFlagsHi;
unsigned short ProcNum;
unsigned short StackSize;
} NDR_PROC_HEADER, *PNDR_PROC_HEADER;
typedef struct _NDR_OI2_PROC_HEADER
{
unsigned short ClientBufferSize;
unsigned short ServerBufferSize;
INTERPRETER_OPT_FLAGS Oi2Flags;
unsigned char NumberParams;
} NDR_OI2_PROC_HEADER, *PNDR_OI2_PROC_HEADER;
typedef enum _NDR_PHASE
{
NDR_PHASE_SIZE,
NDR_PHASE_MARSHALL,
NDR_PHASE_UNMARSHALL,
NDR_PHASE_FREE
} NDR_PHASE;
#define FC_NORMAL_CONFORMANCE 0x00
#define FC_POINTER_CONFORMANCE 0x10
#define FC_TOP_LEVEL_CONFORMANCE 0x20
#define FC_CONSTANT_CONFORMANCE 0x40
#define FC_TOP_LEVEL_MULTID_CONFORMANCE 0x80
/* Type Format Strings: http://msdn.microsoft.com/en-us/library/windows/desktop/aa379093/ */
#define FC_ZERO 0x00
#define FC_BYTE 0x01
#define FC_CHAR 0x02
#define FC_SMALL 0x03
#define FC_USMALL 0x04
#define FC_WCHAR 0x05
#define FC_SHORT 0x06
#define FC_USHORT 0x07
#define FC_LONG 0x08
#define FC_ULONG 0x09
#define FC_FLOAT 0x0A
#define FC_HYPER 0x0B
#define FC_DOUBLE 0x0C
#define FC_ENUM16 0x0D
#define FC_ENUM32 0x0E
#define FC_IGNORE 0x0F
#define FC_ERROR_STATUS_T 0x10
#define FC_RP 0x11
#define FC_UP 0x12
#define FC_OP 0x13
#define FC_FP 0x14
#define FC_STRUCT 0x15
#define FC_PSTRUCT 0x16
#define FC_CSTRUCT 0x17
#define FC_CPSTRUCT 0x18
#define FC_CVSTRUCT 0x19
#define FC_BOGUS_STRUCT 0x1A
#define FC_CARRAY 0x1B
#define FC_CVARRAY 0x1C
#define FC_SMFARRAY 0x1D
#define FC_LGFARRAY 0x1E
#define FC_SMVARRAY 0x1F
#define FC_LGVARRAY 0x20
#define FC_BOGUS_ARRAY 0x21
#define FC_C_CSTRING 0x22
#define FC_C_BSTRING 0x23
#define FC_C_SSTRING 0x24
#define FC_C_WSTRING 0x25
#define FC_CSTRING 0x26
#define FC_BSTRING 0x27
#define FC_SSTRING 0x28
#define FC_WSTRING 0x29
#define FC_ENCAPSULATED_UNION 0x2A
#define FC_NON_ENCAPSULATED_UNION 0x2B
#define FC_BYTE_COUNT_POINTER 0x2C
#define FC_TRANSMIT_AS 0x2D
#define FC_REPRESENT_AS 0x2E
#define FC_IP 0x2F
#define FC_BIND_CONTEXT 0x30
#define FC_BIND_GENERIC 0x31
#define FC_BIND_PRIMITIVE 0x32
#define FC_AUTO_HANDLE 0x33
#define FC_CALLBACK_HANDLE 0x34
#define FC_UNUSED1 0x35
#define FC_POINTER 0x36
#define FC_ALIGNM2 0x37
#define FC_ALIGNM4 0x38
#define FC_ALIGNM8 0x39
#define FC_UNUSED2 0x3A
#define FC_UNUSED3 0x3B
#define FC_UNUSED4 0x3C
#define FC_STRUCTPAD1 0x3D
#define FC_STRUCTPAD2 0x3E
#define FC_STRUCTPAD3 0x3F
#define FC_STRUCTPAD4 0x40
#define FC_STRUCTPAD5 0x41
#define FC_STRUCTPAD6 0x42
#define FC_STRUCTPAD7 0x43
#define FC_STRING_SIZED 0x44
#define FC_UNUSED5 0x45
#define FC_NO_REPEAT 0x46
#define FC_FIXED_REPEAT 0x47
#define FC_VARIABLE_REPEAT 0x48
#define FC_FIXED_OFFSET 0x49
#define FC_VARIABLE_OFFSET 0x4A
#define FC_PP 0x4B
#define FC_EMBEDDED_COMPLEX 0x4C
#define FC_IN_PARAM 0x4D
#define FC_IN_PARAM_BASETYPE 0x4E
#define FC_IN_PARAM_NO_FREE_INST 0x4F
#define FC_IN_OUT_PARAM 0x50
#define FC_OUT_PARAM 0x51
#define FC_RETURN_PARAM 0x52
#define FC_RETURN_PARAM_BASETYPE 0x53
#define FC_DEREFERENCE 0x54
#define FC_DIV_2 0x55
#define FC_MULT_2 0x56
#define FC_ADD_1 0x57
#define FC_SUB_1 0x58
#define FC_CALLBACK 0x59
#define FC_CONSTANT_IID 0x5A
#define FC_END 0x5B
#define FC_PAD 0x5C
#define FC_SPLIT_DEREFERENCE 0x74
#define FC_SPLIT_DIV_2 0x75
#define FC_SPLIT_MULT_2 0x76
#define FC_SPLIT_ADD_1 0x77
#define FC_SPLIT_SUB_1 0x78
#define FC_SPLIT_CALLBACK 0x79
#define FC_HARD_STRUCT 0xB1
#define FC_TRANSMIT_AS_PTR 0xB2
#define FC_REPRESENT_AS_PTR 0xB3
#define FC_USER_MARSHAL 0xB4
#define FC_PIPE 0xB5
#define FC_BLKHOLE 0xB6
#define FC_RANGE 0xB7
#define FC_INT3264 0xB8
#define FC_UINT3264 0xB9
#define FC_END_OF_UNIVERSE 0xBA
#define NdrFcShort(s) (byte)(s & 0xFF), (byte)(s >> 8)
#define NdrFcLong(s) (byte)(s & 0xFF), (byte)((s & 0x0000FF00) >> 8), \
(byte)((s & 0x00FF0000) >> 16), (byte)(s >> 24)
typedef void (*NDR_TYPE_SIZE_ROUTINE)(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat);
typedef void (*NDR_TYPE_MARSHALL_ROUTINE)(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, unsigned char FormatChar);
typedef void (*NDR_TYPE_UNMARSHALL_ROUTINE)(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, unsigned char FormatChar);
typedef void (*NDR_TYPE_FREE_ROUTINE)(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat);
WINPR_API CLIENT_CALL_RETURN NdrClientCall2(PMIDL_STUB_DESC pStubDescriptor, PFORMAT_STRING pFormat, ...);
#endif /* WINPR_RPC_NDR_H */

45
include/winpr/rpc.h Normal file
View File

@@ -0,0 +1,45 @@
/**
* WinPR: Windows Portable Runtime
* Microsoft Remote Procedure Call (MSRPC)
*
* 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_RPC_H
#define WINPR_RPC_H
#include <winpr/winpr.h>
#include <winpr/wtypes.h>
#define RPC_VAR_ENTRY __cdecl
typedef long RPC_STATUS;
typedef void* I_RPC_HANDLE;
typedef I_RPC_HANDLE RPC_BINDING_HANDLE;
typedef RPC_BINDING_HANDLE handle_t;
typedef PCONTEXT_HANDLE PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE;
typedef PCONTEXT_HANDLE PTUNNEL_CONTEXT_HANDLE_SERIALIZE;
typedef PCONTEXT_HANDLE PCHANNEL_CONTEXT_HANDLE_NOSERIALIZE;
typedef PCONTEXT_HANDLE PCHANNEL_CONTEXT_HANDLE_SERIALIZE;
#include <winpr/ndr.h>
#include <winpr/midl.h>
void RpcRaiseException(RPC_STATUS exception);
#endif /* WINPR_RPC_H */

View File

@@ -21,10 +21,10 @@
#define FREERDP_SSPI_H
#include <wchar.h>
#include <winpr/windows.h>
#include <freerdp/api.h>
#include <freerdp/types.h>
#include <freerdp/utils/windows.h>
#ifdef _WIN32
@@ -43,7 +43,7 @@
#else
#define FREERDP_SSPI
#include <freerdp/wtypes.h>
#include <winpr/wtypes.h>
#endif
@@ -953,7 +953,10 @@ FREERDP_API SECURITY_STATUS SEC_ENTRY VerifySignature(PCtxtHandle phContext, PSe
/* Custom API */
void sspi_GlobalInit();
void sspi_GlobalFinish();
FREERDP_API void sspi_GlobalInit();
FREERDP_API void sspi_GlobalFinish();
FREERDP_API void sspi_SecBufferAlloc(PSecBuffer SecBuffer, size_t size);
FREERDP_API void sspi_SecBufferFree(PSecBuffer SecBuffer);
#endif /* FREERDP_SSPI_H */

View File

@@ -1,6 +1,6 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* Windows Header Utils
* WinPR: Windows Portable Runtime
* Windows Header Include Wrapper
*
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
@@ -17,8 +17,8 @@
* limitations under the License.
*/
#ifndef FREERDP_WINDOWS_UTILS_H
#define FREERDP_WINDOWS_UTILS_H
#ifndef WINPR_WINDOWS_H
#define WINPR_WINDOWS_H
/* Windows header include order is important, use this instead of including windows.h directly */
@@ -34,4 +34,4 @@
#endif
#endif /* FREERDP_WINDOWS_UTILS_H */
#endif /* WINPR_WINDOWS_H */

52
include/winpr/winpr.h Normal file
View File

@@ -0,0 +1,52 @@
/**
* WinPR: Windows Portable Runtime
*
* 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_H
#define WINPR_H
#include "config.h"
#if defined _WIN32 || defined __CYGWIN__
#ifdef WINPR_EXPORTS
#ifdef __GNUC__
#define WINPR_API __attribute__((dllexport))
#else
#define WINPR_API __declspec(dllexport)
#endif
#else
#ifdef __GNUC__
#define WINPR_API __attribute__((dllimport))
#else
#define WINPR_API __declspec(dllimport)
#endif
#endif
#else
#if __GNUC__ >= 4
#define WINPR_API __attribute__ ((visibility("default")))
#else
#define WINPR_API
#endif
#endif
#ifdef _WIN32
#define INLINE __inline
#else
#define INLINE inline
#endif
#endif /* WINPR_H */

View File

@@ -1,5 +1,5 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* WinPR: Windows Portable Runtime
* Windows Data Types
*
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
@@ -17,15 +17,14 @@
* limitations under the License.
*/
#ifndef FREERDP_WINDOWS_TYPES_H
#define FREERDP_WINDOWS_TYPES_H
#ifndef WINPR_WTYPES_H
#define WINPR_WTYPES_H
/* MSDN: Windows Data Types - http://msdn.microsoft.com/en-us/library/aa383751/ */
/* [MS-DTYP]: Windows Data Types - http://msdn.microsoft.com/en-us/library/cc230273/ */
#include <wchar.h>
#include <freerdp/types.h>
#include <freerdp/utils/windows.h>
#include <winpr/windows.h>
#ifndef _WIN32
@@ -42,12 +41,10 @@
typedef int BOOL, *PBOOL, *LPBOOL;
typedef unsigned char BYTE, *PBYTE, *LPBYTE;
typedef BYTE byte;
typedef BYTE BOOLEAN, *PBOOLEAN;
typedef wchar_t WCHAR, *PWCHAR;
typedef WCHAR* BSTR;
typedef char CHAR, *PCHAR;
typedef double DOUBLE;
typedef unsigned long DWORD, *PDWORD, *LPDWORD;
typedef unsigned int DWORD32;
typedef unsigned __int64 DWORD64;
@@ -103,15 +100,20 @@ typedef void VOID, *PVOID, *LPVOID;
typedef const void *LPCVOID;
typedef unsigned short WORD, *PWORD, *LPWORD;
typedef void* PCONTEXT_HANDLE;
typedef PCONTEXT_HANDLE* PPCONTEXT_HANDLE;
#if __x86_64__
typedef __int64 INT_PTR;
typedef unsigned __int64 UINT_PTR;
#else
typedef int INT_PTR;
typedef unsigned int UINT_PTR;
#endif
typedef struct _GUID
{
unsigned long Data1;
unsigned short Data2;
unsigned short Data3;
byte Data4[8];
BYTE Data4[8];
} GUID, UUID, *PGUID;
#ifdef UNICODE
@@ -171,4 +173,12 @@ typedef struct _SECURITY_DESCRIPTOR
#endif
#endif /* FREERDP_WINDOWS_TYPES_H */
typedef BYTE byte;
typedef double DOUBLE;
typedef void* PCONTEXT_HANDLE;
typedef PCONTEXT_HANDLE* PPCONTEXT_HANDLE;
typedef unsigned long error_status_t;
#endif /* WINPR_WTYPES_H */

View File

@@ -35,6 +35,12 @@ set(LIBFREERDP_CORE_SRCS
nego.h
info.c
info.h
http.c
http.h
rpc.c
rpc.h
rts.c
rts.h
input.c
input.h
license.c
@@ -62,6 +68,8 @@ set(LIBFREERDP_CORE_SRCS
rdp.h
tcp.c
tcp.h
tsg.c
tsg.h
tpdu.c
tpdu.h
tpkt.c
@@ -97,9 +105,11 @@ endif()
target_link_libraries(freerdp-core freerdp-utils)
target_link_libraries(freerdp-core freerdp-codec)
target_link_libraries(freerdp-core freerdp-crypto)
target_link_libraries(freerdp-core freerdp-sspi)
target_link_libraries(freerdp-core freerdp-locale)
target_link_libraries(freerdp-core ${OPENSSL_LIBRARIES})
target_link_libraries(freerdp-core winpr-rpc)
target_link_libraries(freerdp-core winpr-sspi)
install(TARGETS freerdp-core DESTINATION ${CMAKE_INSTALL_LIBDIR})

View File

@@ -69,8 +69,12 @@ boolean rdp_client_connect(rdpRdp* rdp)
nego_set_target(rdp->nego, settings->hostname, settings->port);
nego_set_cookie(rdp->nego, settings->username);
nego_enable_rdp(rdp->nego, settings->rdp_security);
nego_enable_nla(rdp->nego, settings->nla_security);
nego_enable_tls(rdp->nego, settings->tls_security);
if (!settings->ts_gateway)
{
nego_enable_nla(rdp->nego, settings->nla_security);
nego_enable_tls(rdp->nego, settings->tls_security);
}
if (nego_connect(rdp->nego) != true)
{

View File

@@ -21,10 +21,11 @@
#ifndef __EXTENSION_H
#define __EXTENSION_H
#include <winpr/windows.h>
#include <freerdp/api.h>
#include <freerdp/freerdp.h>
#include <freerdp/extension.h>
#include <freerdp/utils/windows.h>
#define FREERDP_EXT_MAX_COUNT 16

432
libfreerdp-core/http.c Normal file
View File

@@ -0,0 +1,432 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* Hypertext Transfer Protocol (HTTP)
*
* 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 <freerdp/utils/memory.h>
#include "http.h"
HttpContext* http_context_new()
{
HttpContext* http_context = xnew(HttpContext);
if (http_context != NULL)
{
}
return http_context;
}
void http_context_set_method(HttpContext* http_context, char* method)
{
http_context->Method = xstrdup(method);
}
void http_context_set_uri(HttpContext* http_context, char* uri)
{
http_context->URI = xstrdup(uri);
}
void http_context_set_user_agent(HttpContext* http_context, char* user_agent)
{
http_context->UserAgent = xstrdup(user_agent);
}
void http_context_set_host(HttpContext* http_context, char* host)
{
http_context->Host = xstrdup(host);
}
void http_context_set_accept(HttpContext* http_context, char* accept)
{
http_context->Accept = xstrdup(accept);
}
void http_context_set_cache_control(HttpContext* http_context, char* cache_control)
{
http_context->CacheControl = xstrdup(cache_control);
}
void http_context_set_connection(HttpContext* http_context, char* connection)
{
http_context->Connection = xstrdup(connection);
}
void http_context_set_pragma(HttpContext* http_context, char* pragma)
{
http_context->Pragma = xstrdup(pragma);
}
void http_context_free(HttpContext* http_context)
{
if (http_context != NULL)
{
xfree(http_context->UserAgent);
xfree(http_context->Host);
xfree(http_context->Accept);
xfree(http_context->CacheControl);
xfree(http_context->Connection);
xfree(http_context->Pragma);
xfree(http_context);
}
}
void http_request_set_method(HttpRequest* http_request, char* method)
{
http_request->Method = xstrdup(method);
}
void http_request_set_uri(HttpRequest* http_request, char* uri)
{
http_request->URI = xstrdup(uri);
}
void http_request_set_auth_scheme(HttpRequest* http_request, char* auth_scheme)
{
http_request->AuthScheme = xstrdup(auth_scheme);
}
void http_request_set_auth_param(HttpRequest* http_request, char* auth_param)
{
http_request->AuthParam = xstrdup(auth_param);
}
#ifdef _WIN32
#define http_encode_line(_str, _fmt, ...) \
_str = xmalloc(sprintf_s(NULL, 0, _fmt, ## __VA_ARGS__) + 1); \
sprintf_s(_str, sprintf_s(NULL, 0, _fmt, ## __VA_ARGS__) + 1, _fmt, ## __VA_ARGS__);
#else
#define http_encode_line(_str, _fmt, ...) \
_str = xmalloc(snprintf(NULL, 0, _fmt, ## __VA_ARGS__) + 1); \
snprintf(_str, snprintf(NULL, 0, _fmt, ## __VA_ARGS__) + 1, _fmt, ## __VA_ARGS__);
#endif
STREAM* http_request_write(HttpContext* http_context, HttpRequest* http_request)
{
int i;
STREAM* s;
int length = 0;
http_request->count = 9;
http_request->lines = (char**) xmalloc(sizeof(char*) * http_request->count);
http_encode_line(http_request->lines[0], "%s %s HTTP/1.1", http_request->Method, http_request->URI);
http_encode_line(http_request->lines[1], "Cache-Control: %s", http_context->CacheControl);
http_encode_line(http_request->lines[2], "Connection: %s", http_context->Connection);
http_encode_line(http_request->lines[3], "Pragma: %s", http_context->Pragma);
http_encode_line(http_request->lines[4], "Accept: %s", http_context->Accept);
http_encode_line(http_request->lines[5], "User-Agent: %s", http_context->UserAgent);
http_encode_line(http_request->lines[6], "Content-Length: %d", http_request->ContentLength);
http_encode_line(http_request->lines[7], "Host: %s", http_context->Host);
if (http_request->Authorization != NULL)
{
http_encode_line(http_request->lines[8], "Authorization: %s", http_request->Authorization);
}
else if ((http_request->AuthScheme != NULL) && (http_request->AuthParam != NULL))
{
http_encode_line(http_request->lines[8], "Authorization: %s %s",
http_request->AuthScheme, http_request->AuthParam);
}
for (i = 0; i < http_request->count; i++)
{
length += (strlen(http_request->lines[i]) + 1); /* add +1 for each '\n' character */
}
length += 1; /* empty line "\n" at end of header */
length += 1; /* null terminator */
s = stream_new(length);
for (i = 0; i < http_request->count; i++)
{
stream_write(s, http_request->lines[i], strlen(http_request->lines[i]));
stream_write(s, "\n", 1);
xfree(http_request->lines[i]);
}
stream_write(s, "\n", 1);
xfree(http_request->lines);
stream_write(s, "\0", 1); /* append null terminator */
stream_rewind(s, 1); /* don't include null terminator in length */
stream_seal(s);
return s;
}
HttpRequest* http_request_new()
{
HttpRequest* http_request = xnew(HttpRequest);
if (http_request != NULL)
{
}
return http_request;
}
void http_request_free(HttpRequest* http_request)
{
if (http_request != NULL)
{
xfree(http_request->Method);
xfree(http_request->URI);
xfree(http_request);
}
}
void http_response_parse_header_status_line(HttpResponse* http_response, char* status_line)
{
char* separator;
char* status_code;
char* reason_phrase;
separator = strchr(status_line, ' ');
status_code = separator + 1;
separator = strchr(status_code, ' ');
reason_phrase = separator + 1;
*separator = '\0';
http_response->StatusCode = atoi(status_code);
http_response->ReasonPhrase = xstrdup(reason_phrase);
*separator = ' ';
}
void http_response_parse_header_field(HttpResponse* http_response, char* name, char* value)
{
if (strcmp(name, "Content-Length") == 0)
{
http_response->ContentLength = atoi(value);
}
else if (strcmp(name, "Authorization") == 0)
{
char* separator;
http_response->Authorization = xstrdup(value);
separator = strchr(value, ' ');
if (separator != NULL)
{
*separator = '\0';
http_response->AuthScheme = xstrdup(value);
http_response->AuthParam = xstrdup(separator + 1);
*separator = ' ';
}
}
else if (strcmp(name, "WWW-Authenticate") == 0)
{
char* separator;
separator = strstr(value, "=\"");
if (separator != NULL)
{
/* WWW-Authenticate: parameter with spaces="value" */
return;
}
separator = strchr(value, ' ');
if (separator != NULL)
{
/* WWW-Authenticate: NTLM base64token */
*separator = '\0';
http_response->AuthScheme = xstrdup(value);
http_response->AuthParam = xstrdup(separator + 1);
*separator = ' ';
return;
}
}
}
void http_response_parse_header(HttpResponse* http_response)
{
int count;
char* line;
char* name;
char* value;
char* separator;
http_response_parse_header_status_line(http_response, http_response->lines[0]);
for (count = 1; count < http_response->count; count++)
{
line = http_response->lines[count];
separator = strstr(line, ": ");
if (separator == NULL)
continue;
separator[0] = '\0';
separator[1] = '\0';
name = line;
value = separator + 2;
http_response_parse_header_field(http_response, name, value);
separator[0] = ':';
separator[1] = ' ';
}
}
void http_response_print(HttpResponse* http_response)
{
int i;
for (i = 0; i < http_response->count; i++)
{
printf("%s\n", http_response->lines[i]);
}
printf("\n");
}
HttpResponse* http_response_recv(rdpTls* tls)
{
uint8* p;
int nbytes;
int length;
int status;
uint8* buffer;
char* content;
char* header_end;
HttpResponse* http_response;
nbytes = 0;
length = 0xFFFF;
buffer = xmalloc(length);
http_response = http_response_new();
p = buffer;
while (true)
{
status = tls_read(tls, p, length - nbytes);
if (status > 0)
{
nbytes += status;
p = (uint8*) &buffer[nbytes];
}
else if (status == 0)
{
continue;
}
else
{
return NULL;
break;
}
header_end = strstr((char*) buffer, "\r\n\r\n") + 2;
if (header_end != NULL)
{
int count;
char* line;
header_end[0] = '\0';
header_end[1] = '\0';
content = &header_end[2];
count = 0;
line = (char*) buffer;
while ((line = strstr(line, "\r\n")) != NULL)
{
line++;
count++;
}
http_response->count = count;
http_response->lines = (char**) xmalloc(sizeof(char*) * http_response->count);
count = 0;
line = strtok((char*) buffer, "\r\n");
while (line != NULL)
{
http_response->lines[count] = xstrdup(line);
line = strtok(NULL, "\r\n");
count++;
}
http_response_parse_header(http_response);
if (http_response->ContentLength > 0)
{
http_response->Content = xstrdup(content);
}
break;
}
if ((length - nbytes) <= 0)
{
length *= 2;
buffer = xrealloc(buffer, length);
p = (uint8*) &buffer[nbytes];
}
}
return http_response;
}
HttpResponse* http_response_new()
{
HttpResponse* http_response = xnew(HttpResponse);
if (http_response != NULL)
{
}
return http_response;
}
void http_response_free(HttpResponse* http_response)
{
int i;
if (http_response != NULL)
{
for (i = 0; i < http_response->count; i++)
xfree(http_response->lines[i]);
xfree(http_response->lines);
xfree(http_response->ReasonPhrase);
xfree(http_response->AuthParam);
xfree(http_response->AuthScheme);
xfree(http_response->Authorization);
if (http_response->ContentLength > 0)
xfree(http_response->Content);
xfree(http_response);
}
}

101
libfreerdp-core/http.h Normal file
View File

@@ -0,0 +1,101 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* Hypertext Transfer Protocol (HTTP)
*
* 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 FREERDP_CORE_HTTP_H
#define FREERDP_CORE_HTTP_H
typedef struct _http_context HttpContext;
typedef struct _http_request HttpRequest;
typedef struct _http_response HttpResponse;
#include <freerdp/types.h>
#include <freerdp/crypto/tls.h>
#include <freerdp/utils/stream.h>
struct _http_context
{
char* Method;
char* URI;
char* UserAgent;
char* Host;
char* Accept;
char* CacheControl;
char* Connection;
char* Pragma;
};
void http_context_set_method(HttpContext* http_context, char* method);
void http_context_set_uri(HttpContext* http_context, char* uri);
void http_context_set_user_agent(HttpContext* http_context, char* user_agent);
void http_context_set_host(HttpContext* http_context, char* host);
void http_context_set_accept(HttpContext* http_context, char* accept);
void http_context_set_cache_control(HttpContext* http_context, char* cache_control);
void http_context_set_connection(HttpContext* http_context, char* connection);
void http_context_set_pragma(HttpContext* http_context, char* pragma);
HttpContext* http_context_new();
void http_context_free(HttpContext* http_context);
struct _http_request
{
int count;
char** lines;
char* Method;
char* URI;
char* AuthScheme;
char* AuthParam;
char* Authorization;
int ContentLength;
char* Content;
};
void http_request_set_method(HttpRequest* http_request, char* method);
void http_request_set_uri(HttpRequest* http_request, char* uri);
void http_request_set_auth_scheme(HttpRequest* http_request, char* auth_scheme);
void http_request_set_auth_param(HttpRequest* http_request, char* auth_param);
STREAM* http_request_write(HttpContext* http_context, HttpRequest* http_request);
HttpRequest* http_request_new();
void http_request_free(HttpRequest* http_request);
struct _http_response
{
int count;
char** lines;
int StatusCode;
char* ReasonPhrase;
char* AuthScheme;
char* AuthParam;
char* Authorization;
int ContentLength;
char* Content;
};
void http_response_print(HttpResponse* http_response);
HttpResponse* http_response_recv(rdpTls* tls);
HttpResponse* http_response_new();
void http_response_free(HttpResponse* http_response);
#endif /* FREERDP_CORE_HTTP_H */

990
libfreerdp-core/rpc.c Normal file
View File

@@ -0,0 +1,990 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* RPC over HTTP
*
* Copyright 2012 Fujitsu Technology Solutions GmbH
* Copyright 2012 Dmitrij Jasnov <dmitrij.jasnov@ts.fujitsu.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 "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/rand.h>
#include "http.h"
#include "rpc.h"
#define NTLM_PACKAGE_NAME _T("NTLM")
boolean ntlm_client_init(rdpNtlm* ntlm, boolean confidentiality, char* user, char* domain, char* password)
{
size_t size;
SECURITY_STATUS status;
sspi_GlobalInit();
ntlm->confidentiality = confidentiality;
ntlm->table = InitSecurityInterface();
ntlm->identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
ntlm->identity.User = (uint16*) freerdp_uniconv_out(ntlm->uniconv, user, &size);
ntlm->identity.UserLength = (uint32) size;
if (domain)
{
ntlm->identity.Domain = (uint16*) freerdp_uniconv_out(ntlm->uniconv, domain, &size);
ntlm->identity.DomainLength = (uint32) size;
}
else
{
ntlm->identity.Domain = (uint16*) NULL;
ntlm->identity.DomainLength = 0;
}
ntlm->identity.Password = (uint16*) freerdp_uniconv_out(ntlm->uniconv, (char*) password, &size);
ntlm->identity.PasswordLength = (uint32) size;
status = QuerySecurityPackageInfo(NTLM_PACKAGE_NAME, &ntlm->pPackageInfo);
if (status != SEC_E_OK)
{
printf("QuerySecurityPackageInfo status: 0x%08X\n", status);
return false;
}
ntlm->cbMaxToken = ntlm->pPackageInfo->cbMaxToken;
status = ntlm->table->AcquireCredentialsHandle(NULL, NTLM_PACKAGE_NAME,
SECPKG_CRED_OUTBOUND, NULL, &ntlm->identity, NULL, NULL, &ntlm->credentials, &ntlm->expiration);
if (status != SEC_E_OK)
{
printf("AcquireCredentialsHandle status: 0x%08X\n", status);
return false;
}
ntlm->haveContext = false;
ntlm->haveInputBuffer = false;
memset(&ntlm->inputBuffer, 0, sizeof(SecBuffer));
memset(&ntlm->outputBuffer, 0, sizeof(SecBuffer));
memset(&ntlm->ContextSizes, 0, sizeof(SecPkgContext_Sizes));
ntlm->fContextReq = ISC_REQ_REPLAY_DETECT | ISC_REQ_SEQUENCE_DETECT | ISC_REQ_DELEGATE;
if (ntlm->confidentiality)
ntlm->fContextReq |= ISC_REQ_CONFIDENTIALITY;
return true;
}
boolean ntlm_authenticate(rdpNtlm* ntlm)
{
SECURITY_STATUS status;
ntlm->outputBufferDesc.ulVersion = SECBUFFER_VERSION;
ntlm->outputBufferDesc.cBuffers = 1;
ntlm->outputBufferDesc.pBuffers = &ntlm->outputBuffer;
ntlm->outputBuffer.BufferType = SECBUFFER_TOKEN;
ntlm->outputBuffer.cbBuffer = ntlm->cbMaxToken;
ntlm->outputBuffer.pvBuffer = xmalloc(ntlm->outputBuffer.cbBuffer);
if (ntlm->haveInputBuffer)
{
ntlm->inputBufferDesc.ulVersion = SECBUFFER_VERSION;
ntlm->inputBufferDesc.cBuffers = 1;
ntlm->inputBufferDesc.pBuffers = &ntlm->inputBuffer;
ntlm->inputBuffer.BufferType = SECBUFFER_TOKEN;
}
status = ntlm->table->InitializeSecurityContext(&ntlm->credentials,
(ntlm->haveContext) ? &ntlm->context : NULL,
NULL, ntlm->fContextReq, 0, SECURITY_NATIVE_DREP,
(ntlm->haveInputBuffer) ? &ntlm->inputBufferDesc : NULL,
0, &ntlm->context, &ntlm->outputBufferDesc,
&ntlm->pfContextAttr, &ntlm->expiration);
if ((status == SEC_I_COMPLETE_AND_CONTINUE) || (status == SEC_I_COMPLETE_NEEDED) || (status == SEC_E_OK))
{
if (ntlm->table->CompleteAuthToken != NULL)
ntlm->table->CompleteAuthToken(&ntlm->context, &ntlm->outputBufferDesc);
if (ntlm->table->QueryContextAttributes(&ntlm->context, SECPKG_ATTR_SIZES, &ntlm->ContextSizes) != SEC_E_OK)
{
printf("QueryContextAttributes SECPKG_ATTR_SIZES failure\n");
return 0;
}
if (status == SEC_I_COMPLETE_NEEDED)
status = SEC_E_OK;
else if (status == SEC_I_COMPLETE_AND_CONTINUE)
status = SEC_I_CONTINUE_NEEDED;
}
ntlm->haveInputBuffer = true;
ntlm->haveContext = true;
return true;
}
void ntlm_client_uninit(rdpNtlm* ntlm)
{
FreeCredentialsHandle(&ntlm->credentials);
FreeContextBuffer(ntlm->pPackageInfo);
}
rdpNtlm* ntlm_new()
{
rdpNtlm* ntlm = xnew(rdpNtlm);
if (ntlm != NULL)
{
ntlm->uniconv = freerdp_uniconv_new();
}
return ntlm;
}
void ntlm_free(rdpNtlm* ntlm)
{
if (ntlm != NULL)
{
freerdp_uniconv_free(ntlm->uniconv);
}
}
STREAM* rpc_ntlm_http_request(rdpRpc* rpc, SecBuffer* ntlm_token, int content_length, TSG_CHANNEL channel)
{
STREAM* s;
char* base64_ntlm_token;
HttpContext* http_context;
HttpRequest* http_request;
http_request = http_request_new();
base64_ntlm_token = crypto_base64_encode(ntlm_token->pvBuffer, ntlm_token->cbBuffer);
if (channel == TSG_CHANNEL_IN)
{
http_context = rpc->ntlm_http_in->context;
http_request_set_method(http_request, "RPC_IN_DATA");
}
else if (channel == TSG_CHANNEL_OUT)
{
http_context = rpc->ntlm_http_out->context;
http_request_set_method(http_request, "RPC_OUT_DATA");
}
else
{
return NULL;
}
http_request->ContentLength = content_length;
http_request_set_uri(http_request, http_context->URI);
http_request_set_auth_scheme(http_request, "NTLM");
http_request_set_auth_param(http_request, base64_ntlm_token);
s = http_request_write(http_context, http_request);
http_request_free(http_request);
return s;
}
boolean rpc_ntlm_http_out_connect(rdpRpc* rpc)
{
STREAM* s;
int ntlm_token_length;
uint8* ntlm_token_data;
HttpResponse* http_response;
rdpNtlm* ntlm = rpc->ntlm_http_out->ntlm;
ntlm_client_init(ntlm, true, rpc->settings->username,
rpc->settings->domain, rpc->settings->password);
ntlm_authenticate(ntlm);
s = rpc_ntlm_http_request(rpc, &ntlm->outputBuffer, 0, TSG_CHANNEL_OUT);
/* Send OUT Channel Request */
DEBUG_RPC("\n%s", s->data);
tls_write_all(rpc->tls_out, s->data, s->size);
stream_free(s);
/* Receive OUT Channel Response */
http_response = http_response_recv(rpc->tls_out);
ntlm_token_data = NULL;
crypto_base64_decode((uint8*) http_response->AuthParam, strlen(http_response->AuthParam),
&ntlm_token_data, &ntlm_token_length);
ntlm->inputBuffer.pvBuffer = ntlm_token_data;
ntlm->inputBuffer.cbBuffer = ntlm_token_length;
ntlm_authenticate(ntlm);
http_response_free(http_response);
s = rpc_ntlm_http_request(rpc, &ntlm->outputBuffer, 76, TSG_CHANNEL_OUT);
/* Send OUT Channel Request */
DEBUG_RPC("\n%s", s->data);
tls_write_all(rpc->tls_out, s->data, s->size);
stream_free(s);
ntlm_client_uninit(ntlm);
ntlm_free(ntlm);
return true;
}
boolean rpc_ntlm_http_in_connect(rdpRpc* rpc)
{
STREAM* s;
int ntlm_token_length;
uint8* ntlm_token_data;
HttpResponse* http_response;
rdpNtlm* ntlm = rpc->ntlm_http_in->ntlm;
ntlm_client_init(ntlm, true, rpc->settings->username,
rpc->settings->domain, rpc->settings->password);
ntlm_authenticate(ntlm);
s = rpc_ntlm_http_request(rpc, &ntlm->outputBuffer, 0, TSG_CHANNEL_IN);
/* Send IN Channel Request */
DEBUG_RPC("\n%s", s->data);
tls_write_all(rpc->tls_in, s->data, s->size);
stream_free(s);
/* Receive IN Channel Response */
http_response = http_response_recv(rpc->tls_in);
ntlm_token_data = NULL;
crypto_base64_decode((uint8*) http_response->AuthParam, strlen(http_response->AuthParam),
&ntlm_token_data, &ntlm_token_length);
ntlm->inputBuffer.pvBuffer = ntlm_token_data;
ntlm->inputBuffer.cbBuffer = ntlm_token_length;
ntlm_authenticate(ntlm);
http_response_free(http_response);
s = rpc_ntlm_http_request(rpc, &ntlm->outputBuffer, 0x40000000, TSG_CHANNEL_IN);
/* Send IN Channel Request */
DEBUG_RPC("\n%s", s->data);
tls_write_all(rpc->tls_in, s->data, s->size);
stream_free(s);
ntlm_client_uninit(ntlm);
ntlm_free(ntlm);
return true;
}
void rpc_pdu_header_read(STREAM* s, RPC_PDU_HEADER* header)
{
stream_read_uint8(s, header->rpc_vers); /* rpc_vers (1 byte) */
stream_read_uint8(s, header->rpc_vers_minor); /* rpc_vers_minor (1 byte) */
stream_read_uint8(s, header->ptype); /* PTYPE (1 byte) */
stream_read_uint8(s, header->pfc_flags); /* pfc_flags (1 byte) */
stream_read_uint8(s, header->packed_drep[0]); /* packet_drep[0] (1 byte) */
stream_read_uint8(s, header->packed_drep[1]); /* packet_drep[1] (1 byte) */
stream_read_uint8(s, header->packed_drep[2]); /* packet_drep[2] (1 byte) */
stream_read_uint8(s, header->packed_drep[3]); /* packet_drep[3] (1 byte) */
stream_read_uint16(s, header->frag_length); /* frag_length (2 bytes) */
stream_read_uint16(s, header->auth_length); /* auth_length (2 bytes) */
stream_read_uint32(s, header->call_id); /* call_id (4 bytes) */
}
int rpc_out_write(rdpRpc* rpc, uint8* data, int length)
{
int status;
#ifdef WITH_DEBUG_RPC
printf("rpc_out_write(): length: %d\n", length);
freerdp_hexdump(data, length);
printf("\n");
#endif
status = tls_write_all(rpc->tls_out, data, length);
return status;
}
int rpc_in_write(rdpRpc* rpc, uint8* data, int length)
{
int status;
#ifdef WITH_DEBUG_RPC
printf("rpc_in_write() length: %d\n", length);
freerdp_hexdump(data, length);
printf("\n");
#endif
status = tls_write_all(rpc->tls_in, data, length);
if (status > 0)
rpc->VirtualConnection->DefaultInChannel->BytesSent += status;
return status;
}
boolean rpc_send_bind_pdu(rdpRpc* rpc)
{
STREAM* pdu;
rpcconn_bind_hdr_t* bind_pdu;
rdpSettings* settings = rpc->settings;
STREAM* ntlm_stream = stream_new(0xFFFF);
rpc->ntlm = ntlm_new();
DEBUG_RPC("Sending bind PDU");
ntlm_client_init(rpc->ntlm, false, settings->username, settings->domain, settings->password);
ntlm_authenticate(rpc->ntlm);
ntlm_stream->size = rpc->ntlm->outputBuffer.cbBuffer;
ntlm_stream->p = ntlm_stream->data = rpc->ntlm->outputBuffer.pvBuffer;
bind_pdu = xnew(rpcconn_bind_hdr_t);
bind_pdu->rpc_vers = 5;
bind_pdu->rpc_vers_minor = 0;
bind_pdu->PTYPE = PTYPE_BIND;
bind_pdu->pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG | PFC_PENDING_CANCEL | PFC_CONC_MPX;
bind_pdu->packed_drep[0] = 0x10;
bind_pdu->packed_drep[1] = 0x00;
bind_pdu->packed_drep[2] = 0x00;
bind_pdu->packed_drep[3] = 0x00;
bind_pdu->frag_length = 124 + ntlm_stream->size;
bind_pdu->auth_length = ntlm_stream->size;
bind_pdu->call_id = 2;
bind_pdu->max_xmit_frag = 0x0FF8;
bind_pdu->max_recv_frag = 0x0FF8;
bind_pdu->assoc_group_id = 0;
bind_pdu->p_context_elem.n_context_elem = 2;
bind_pdu->p_context_elem.reserved = 0;
bind_pdu->p_context_elem.reserved2 = 0;
bind_pdu->p_context_elem.p_cont_elem = xmalloc(sizeof(p_cont_elem_t) * bind_pdu->p_context_elem.n_context_elem);
bind_pdu->p_context_elem.p_cont_elem[0].p_cont_id = 0;
bind_pdu->p_context_elem.p_cont_elem[0].n_transfer_syn = 1;
bind_pdu->p_context_elem.p_cont_elem[0].reserved = 0;
bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.time_low = 0x44e265dd;
bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.time_mid = 0x7daf;
bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.time_hi_and_version = 0x42cd;
bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.clock_seq_hi_and_reserved = 0x85;
bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.clock_seq_low = 0x60;
bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.node[0] = 0x3c;
bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.node[1] = 0xdb;
bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.node[2] = 0x6e;
bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.node[3] = 0x7a;
bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.node[4] = 0x27;
bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.node[5] = 0x29;
bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_version = 0x00030001;
bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes = xmalloc(sizeof(p_syntax_id_t));
bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.time_low = 0x8a885d04;
bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.time_mid = 0x1ceb;
bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.time_hi_and_version = 0x11c9;
bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.clock_seq_hi_and_reserved = 0x9f;
bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.clock_seq_low = 0xe8;
bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.node[0] = 0x08;
bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.node[1] = 0x00;
bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.node[2] = 0x2b;
bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.node[3] = 0x10;
bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.node[4] = 0x48;
bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.node[5] = 0x60;
bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_version = 0x00000002;
bind_pdu->p_context_elem.p_cont_elem[1].p_cont_id = 1;
bind_pdu->p_context_elem.p_cont_elem[1].n_transfer_syn = 1;
bind_pdu->p_context_elem.p_cont_elem[1].reserved = 0;
bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.time_low = 0x44e265dd;
bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.time_mid = 0x7daf;
bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.time_hi_and_version = 0x42cd;
bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.clock_seq_hi_and_reserved = 0x85;
bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.clock_seq_low = 0x60;
bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.node[0] = 0x3c;
bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.node[1] = 0xdb;
bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.node[2] = 0x6e;
bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.node[3] = 0x7a;
bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.node[4] = 0x27;
bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.node[5] = 0x29;
bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_version = 0x00030001;
bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes = xmalloc(sizeof(p_syntax_id_t));
bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_uuid.time_low = 0x6cb71c2c;
bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_uuid.time_mid = 0x9812;
bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_uuid.time_hi_and_version = 0x4540;
bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_uuid.clock_seq_hi_and_reserved = 0x03;
bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_uuid.clock_seq_low = 0x00;
bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_uuid.node[0] = 0x00;
bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_uuid.node[1] = 0x00;
bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_uuid.node[2] = 0x00;
bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_uuid.node[3] = 0x00;
bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_uuid.node[4] = 0x00;
bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_uuid.node[5] = 0x00;
bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_version = 0x00000001;
bind_pdu->auth_verifier.auth_pad = NULL; /* align(4); size_is(auth_pad_length) p*/
bind_pdu->auth_verifier.auth_type = 0x0a; /* :01 which authent service */
bind_pdu->auth_verifier.auth_level = 0x05; /* :01 which level within service */
bind_pdu->auth_verifier.auth_pad_length = 0x00; /* :01 */
bind_pdu->auth_verifier.auth_reserved = 0x00; /* :01 reserved, m.b.z. */
bind_pdu->auth_verifier.auth_context_id = 0x00000000; /* :04 */
bind_pdu->auth_verifier.auth_value = xmalloc(bind_pdu->auth_length); /* credentials; size_is(auth_length) p*/;
memcpy(bind_pdu->auth_verifier.auth_value, ntlm_stream->data, bind_pdu->auth_length);
stream_free(ntlm_stream);
pdu = stream_new(bind_pdu->frag_length);
stream_write(pdu, bind_pdu, 24);
stream_write(pdu, &bind_pdu->p_context_elem, 4);
stream_write(pdu, bind_pdu->p_context_elem.p_cont_elem, 24);
stream_write(pdu, bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes, 20);
stream_write(pdu, bind_pdu->p_context_elem.p_cont_elem + 1, 24);
stream_write(pdu, bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes, 20);
if (bind_pdu->auth_verifier.auth_pad_length > 0)
stream_write(pdu, bind_pdu->auth_verifier.auth_pad, bind_pdu->auth_verifier.auth_pad_length);
stream_write(pdu, &bind_pdu->auth_verifier.auth_type, 8); /* assumed that uint8 pointer is 32bit long (4 bytes) */
stream_write(pdu, bind_pdu->auth_verifier.auth_value, bind_pdu->auth_length);
stream_seal(pdu);
rpc_in_write(rpc, pdu->data, pdu->size);
xfree(bind_pdu);
return true;
}
int rpc_recv_bind_ack_pdu(rdpRpc* rpc)
{
uint8* p;
STREAM* s;
int status;
uint8* pdu;
uint8* auth_data;
RPC_PDU_HEADER header;
int pdu_length = 0x8FFF;
pdu = xmalloc(pdu_length);
status = rpc_out_read(rpc, pdu, pdu_length);
if (status > 0)
{
s = stream_new(0);
stream_attach(s, pdu, pdu_length);
rpc_pdu_header_read(s, &header);
stream_detach(s);
stream_free(s);
auth_data = xmalloc(header.auth_length);
p = (pdu + (header.frag_length - header.auth_length));
memcpy(auth_data, p, header.auth_length);
rpc->ntlm->inputBuffer.pvBuffer = auth_data;
rpc->ntlm->inputBuffer.cbBuffer = header.auth_length;
ntlm_authenticate(rpc->ntlm);
}
xfree(pdu);
return status;
}
boolean rpc_send_rpc_auth_3_pdu(rdpRpc* rpc)
{
STREAM* pdu;
STREAM* s = stream_new(0);
rpcconn_rpc_auth_3_hdr_t* rpc_auth_3_pdu;
DEBUG_RPC("Sending auth_3 PDU");
s->size = rpc->ntlm->outputBuffer.cbBuffer;
s->p = s->data = rpc->ntlm->outputBuffer.pvBuffer;
rpc_auth_3_pdu = xnew(rpcconn_rpc_auth_3_hdr_t);
rpc_auth_3_pdu->rpc_vers = 5;
rpc_auth_3_pdu->rpc_vers_minor = 0;
rpc_auth_3_pdu->PTYPE = PTYPE_RPC_AUTH_3;
rpc_auth_3_pdu->pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG | PFC_CONC_MPX;
rpc_auth_3_pdu->packed_drep[0] = 0x10;
rpc_auth_3_pdu->packed_drep[1] = 0x00;
rpc_auth_3_pdu->packed_drep[2] = 0x00;
rpc_auth_3_pdu->packed_drep[3] = 0x00;
rpc_auth_3_pdu->frag_length = 28 + s->size;
rpc_auth_3_pdu->auth_length = s->size;
rpc_auth_3_pdu->call_id = 2;
rpc_auth_3_pdu->max_xmit_frag = 0x0FF8;
rpc_auth_3_pdu->max_recv_frag = 0x0FF8;
rpc_auth_3_pdu->auth_verifier.auth_pad = NULL; /* align(4); size_is(auth_pad_length) p */
rpc_auth_3_pdu->auth_verifier.auth_type = 0x0a; /* :01 which authent service */
rpc_auth_3_pdu->auth_verifier.auth_level = 0x05; /* :01 which level within service */
rpc_auth_3_pdu->auth_verifier.auth_pad_length = 0x00; /* :01 */
rpc_auth_3_pdu->auth_verifier.auth_reserved = 0x00; /* :01 reserved, m.b.z. */
rpc_auth_3_pdu->auth_verifier.auth_context_id = 0x00000000; /* :04 */
rpc_auth_3_pdu->auth_verifier.auth_value = xmalloc(rpc_auth_3_pdu->auth_length); /* credentials; size_is(auth_length) p */
memcpy(rpc_auth_3_pdu->auth_verifier.auth_value, s->data, rpc_auth_3_pdu->auth_length);
stream_free(s);
pdu = stream_new(rpc_auth_3_pdu->frag_length);
stream_write(pdu, rpc_auth_3_pdu, 20);
if (rpc_auth_3_pdu->auth_verifier.auth_pad_length > 0)
stream_write(pdu, rpc_auth_3_pdu->auth_verifier.auth_pad, rpc_auth_3_pdu->auth_verifier.auth_pad_length);
stream_write(pdu, &rpc_auth_3_pdu->auth_verifier.auth_type, 8);
stream_write(pdu, rpc_auth_3_pdu->auth_verifier.auth_value, rpc_auth_3_pdu->auth_length);
rpc_in_write(rpc, pdu->data, stream_get_length(pdu));
xfree(rpc_auth_3_pdu);
return true;
}
int rpc_out_read(rdpRpc* rpc, uint8* data, int length)
{
STREAM* s;
int status;
uint8* pdu;
int content_length;
RPC_PDU_HEADER header;
if (rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow < 0x00008FFF) /* Just a simple workaround */
rts_send_flow_control_ack_pdu(rpc); /* Send FlowControlAck every time AvailableWindow reaches the half */
pdu = xmalloc(0xFFFF);
status = tls_read(rpc->tls_out, pdu, 16); /* read first 16 bytes to get RPC PDU Header */
if (status <= 0)
{
xfree(pdu);
return status;
}
s = stream_new(0);
stream_attach(s, pdu, 16);
rpc_pdu_header_read(s, &header);
stream_detach(s);
stream_free(s);
content_length = header.frag_length - 16;
status = tls_read(rpc->tls_out, pdu + 16, content_length);
if (status < 0)
{
xfree(pdu);
return status;
}
if (header.ptype == PTYPE_RTS) /* RTS PDU */
{
printf("rpc_out_read error: Unexpected RTS PDU\n");
return -1;
}
else
{
/* RTS PDUs are not subject to flow control */
rpc->VirtualConnection->DefaultOutChannel->BytesReceived += header.frag_length;
rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow -= header.frag_length;
}
if (length < header.frag_length)
{
printf("rpc_out_read error! receive buffer is not large enough\n");
return -1;
}
memcpy(data, pdu, header.frag_length);
#ifdef WITH_DEBUG_RPC
printf("rpc_out_read(): length: %d\n", header.frag_length);
freerdp_hexdump(data, header.frag_length);
printf("\n");
#endif
xfree(pdu);
return header.frag_length;
}
int rpc_tsg_write(rdpRpc* rpc, uint8* data, int length, uint16 opnum)
{
int i;
int status;
STREAM* pdu;
rdpNtlm* ntlm;
SecBuffer Buffers[2];
SecBufferDesc Message;
SECURITY_STATUS encrypt_status;
rpcconn_request_hdr_t* request_pdu;
uint8 auth_pad_length = 16 - ((24 + length + 8 + 16) % 16);
ntlm = rpc->ntlm;
if (auth_pad_length == 16)
auth_pad_length = 0;
request_pdu = xnew(rpcconn_request_hdr_t);
request_pdu->rpc_vers = 5;
request_pdu->rpc_vers_minor = 0;
request_pdu->PTYPE = PTYPE_REQUEST;
request_pdu->pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG;
request_pdu->packed_drep[0] = 0x10;
request_pdu->packed_drep[1] = 0x00;
request_pdu->packed_drep[2] = 0x00;
request_pdu->packed_drep[3] = 0x00;
request_pdu->frag_length = 24 + length + auth_pad_length + 8 + 16;
request_pdu->auth_length = 16;
request_pdu->call_id = ++rpc->call_id;
/* opnum=8 means [MS-TSGU] TsProxySetupReceivePipe, save call_id for checking pipe responses */
if (opnum == 8)
rpc->pipe_call_id = rpc->call_id;
request_pdu->alloc_hint = length;
request_pdu->p_cont_id = 0x0000;
request_pdu->opnum = opnum;
request_pdu->stub_data = data;
request_pdu->auth_verifier.auth_type = 0x0A; /* :01 which authentication service */
request_pdu->auth_verifier.auth_level = 0x05; /* :01 which level within service */
request_pdu->auth_verifier.auth_pad_length = auth_pad_length; /* :01 */
request_pdu->auth_verifier.auth_pad = xmalloc(auth_pad_length); /* align(4); size_is(auth_pad_length) p */
for (i = 0; i < auth_pad_length; i++)
{
request_pdu->auth_verifier.auth_pad[i] = 0x00;
}
request_pdu->auth_verifier.auth_reserved = 0x00; /* :01 reserved, m.b.z. */
request_pdu->auth_verifier.auth_context_id = 0x00000000; /* :04 */
request_pdu->auth_verifier.auth_value = xmalloc(request_pdu->auth_length); /* credentials; size_is(auth_length) p */
pdu = stream_new(request_pdu->frag_length);
stream_write(pdu, request_pdu, 24);
stream_write(pdu, request_pdu->stub_data, request_pdu->alloc_hint);
if (request_pdu->auth_verifier.auth_pad_length > 0)
stream_write(pdu, request_pdu->auth_verifier.auth_pad, request_pdu->auth_verifier.auth_pad_length);
stream_write(pdu, &request_pdu->auth_verifier.auth_type, 8);
if (ntlm->table->QueryContextAttributes(&ntlm->context, SECPKG_ATTR_SIZES, &ntlm->ContextSizes) != SEC_E_OK)
{
printf("QueryContextAttributes SECPKG_ATTR_SIZES failure\n");
return 0;
}
Buffers[0].BufferType = SECBUFFER_DATA; /* auth_data */
Buffers[1].BufferType = SECBUFFER_TOKEN; /* signature */
Buffers[0].pvBuffer = pdu->data;
Buffers[0].cbBuffer = stream_get_length(pdu);
Buffers[1].cbBuffer = ntlm->ContextSizes.cbMaxSignature;
Buffers[1].pvBuffer = xzalloc(Buffers[1].cbBuffer);
Message.cBuffers = 2;
Message.ulVersion = SECBUFFER_VERSION;
Message.pBuffers = (PSecBuffer) &Buffers;
encrypt_status = ntlm->table->EncryptMessage(&ntlm->context, 0, &Message, rpc->send_seq_num++);
if (encrypt_status != SEC_E_OK)
{
printf("EncryptMessage status: 0x%08X\n", encrypt_status);
return 0;
}
stream_write(pdu, Buffers[1].pvBuffer, Buffers[1].cbBuffer);
status = rpc_in_write(rpc, pdu->data, pdu->p - pdu->data);
xfree(request_pdu->auth_verifier.auth_value);
xfree(request_pdu->auth_verifier.auth_pad);
xfree(request_pdu);
if (status < 0)
{
printf("rpc_write(): Error! rpc_tsg_write returned negative value.\n");
return -1;
}
return length;
}
int rpc_read(rdpRpc* rpc, uint8* data, int length)
{
int status;
int read = 0;
int data_length;
uint16 frag_length;
uint16 auth_length;
uint8 auth_pad_length;
uint32 call_id = -1;
int rpc_length = length + 0xFF;
uint8* rpc_data = xmalloc(rpc_length);
if (rpc->read_buffer_len > 0)
{
if (rpc->read_buffer_len > (uint32) length)
{
printf("rpc_read error: receiving buffer is not large enough\n");
return -1;
}
memcpy(data, rpc->read_buffer, rpc->read_buffer_len);
read += rpc->read_buffer_len;
xfree(rpc->read_buffer);
rpc->read_buffer_len = 0;
}
while (true)
{
status = rpc_out_read(rpc, rpc_data, rpc_length);
if (status == 0)
{
xfree(rpc_data);
return read;
}
else if (status < 0)
{
printf("Error! rpc_out_read() returned negative value. BytesSent: %d, BytesReceived: %d\n",
rpc->VirtualConnection->DefaultInChannel->BytesSent,
rpc->VirtualConnection->DefaultOutChannel->BytesReceived);
xfree(rpc_data);
return status;
}
frag_length = *(uint16*)(rpc_data + 8);
auth_length = *(uint16*)(rpc_data + 10);
call_id = *(uint32*)(rpc_data + 12);
status = *(uint32*)(rpc_data + 16); /* alloc_hint */
auth_pad_length = *(rpc_data + frag_length - auth_length - 6); /* -6 = -8 + 2 (sec_trailer + 2) */
/* data_length must be calculated because alloc_hint carries size of more than one pdu */
data_length = frag_length - auth_length - 24 - 8 - auth_pad_length; /* 24 is header; 8 is sec_trailer */
if (status == 4)
continue;
if (read + data_length > length) /* if read data is greater then given buffer */
{
rpc->read_buffer_len = read + data_length - length;
rpc->read_buffer = xmalloc(rpc->read_buffer_len);
data_length -= rpc->read_buffer_len;
memcpy(rpc->read_buffer, rpc_data + 24 + data_length, rpc->read_buffer_len);
}
memcpy(data + read, rpc_data + 24, data_length);
read += data_length;
if (status > data_length && read < length)
continue;
break;
}
xfree(rpc_data);
return read;
}
boolean rpc_connect(rdpRpc* rpc)
{
rpc->tls_in = rpc->transport->tls_in;
rpc->tls_out = rpc->transport->tls_out;
if (!rts_connect(rpc))
{
printf("rts_connect error!\n");
return false;
}
if (!rpc_send_bind_pdu(rpc))
{
printf("rpc_send_bind_pdu error!\n");
return false;
}
if (!rpc_recv_bind_ack_pdu(rpc))
{
printf("rpc_recv_bind_ack_pdu error!\n");
return false;
}
if (!rpc_send_rpc_auth_3_pdu(rpc))
{
printf("rpc_send_rpc_auth_3 error!\n");
return false;
}
return true;
}
void rpc_client_virtual_connection_init(rdpRpc* rpc, RpcVirtualConnection* virtual_connection)
{
virtual_connection->DefaultInChannel->BytesSent = 0;
virtual_connection->DefaultOutChannel->BytesReceived = 0;
virtual_connection->DefaultOutChannel->ReceiverAvailableWindow = rpc->ReceiveWindow;
virtual_connection->DefaultOutChannel->ReceiveWindow = rpc->ReceiveWindow;
virtual_connection->DefaultOutChannel->ReceiveWindowSize = rpc->ReceiveWindow;
virtual_connection->DefaultInChannel->SenderAvailableWindow = rpc->ReceiveWindow;
virtual_connection->DefaultInChannel->PingOriginator.ConnectionTimeout = 30;
virtual_connection->DefaultInChannel->PingOriginator.KeepAliveInterval = 0;
}
RpcVirtualConnection* rpc_client_virtual_connection_new(rdpRpc* rpc)
{
RpcVirtualConnection* virtual_connection = xnew(RpcVirtualConnection);
if (virtual_connection != NULL)
{
virtual_connection->State = VIRTUAL_CONNECTION_STATE_INITIAL;
virtual_connection->DefaultInChannel = xnew(RpcInChannel);
virtual_connection->DefaultOutChannel = xnew(RpcOutChannel);
rpc_client_virtual_connection_init(rpc, virtual_connection);
}
return virtual_connection;
}
void rpc_client_virtual_connection_free(RpcVirtualConnection* virtual_connection)
{
if (virtual_connection != NULL)
{
xfree(virtual_connection);
}
}
rdpNtlmHttp* ntlm_http_new()
{
rdpNtlmHttp* ntlm_http;
ntlm_http = xnew(rdpNtlmHttp);
if (ntlm_http != NULL)
{
ntlm_http->ntlm = ntlm_new();
ntlm_http->context = http_context_new();
}
return ntlm_http;
}
void rpc_ntlm_http_init_channel(rdpRpc* rpc, rdpNtlmHttp* ntlm_http, TSG_CHANNEL channel)
{
if (channel == TSG_CHANNEL_IN)
http_context_set_method(ntlm_http->context, "RPC_IN_DATA");
else if (channel == TSG_CHANNEL_OUT)
http_context_set_method(ntlm_http->context, "RPC_OUT_DATA");
http_context_set_uri(ntlm_http->context, "/rpc/rpcproxy.dll?localhost:3388");
http_context_set_accept(ntlm_http->context, "application/rpc");
http_context_set_cache_control(ntlm_http->context, "no-cache");
http_context_set_connection(ntlm_http->context, "Keep-Alive");
http_context_set_user_agent(ntlm_http->context, "MSRPC");
http_context_set_host(ntlm_http->context, rpc->settings->tsg_hostname);
if (channel == TSG_CHANNEL_IN)
{
http_context_set_pragma(ntlm_http->context,
"ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729");
}
else if (channel == TSG_CHANNEL_OUT)
{
http_context_set_pragma(ntlm_http->context,
"ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729" ", "
"SessionId=fbd9c34f-397d-471d-a109-1b08cc554624");
}
}
void ntlm_http_free(rdpNtlmHttp* ntlm_http)
{
if (ntlm_http != NULL)
{
ntlm_free(ntlm_http->ntlm);
http_context_free(ntlm_http->context);
}
}
rdpRpc* rpc_new(rdpTransport* transport)
{
rdpRpc* rpc = (rdpRpc*) xnew(rdpRpc);
if (rpc != NULL)
{
rpc->transport = transport;
rpc->settings = transport->settings;
rpc->send_seq_num = 0;
rpc->ntlm = ntlm_new();
rpc->ntlm_http_in = ntlm_http_new();
rpc->ntlm_http_out = ntlm_http_new();
rpc_ntlm_http_init_channel(rpc, rpc->ntlm_http_in, TSG_CHANNEL_IN);
rpc_ntlm_http_init_channel(rpc, rpc->ntlm_http_out, TSG_CHANNEL_OUT);
rpc->read_buffer = NULL;
rpc->write_buffer = NULL;
rpc->read_buffer_len = 0;
rpc->write_buffer_len = 0;
rpc->ReceiveWindow = 0x00010000;
rpc->VirtualConnection = rpc_client_virtual_connection_new(rpc);
rpc->call_id = 0;
}
return rpc;
}
void rpc_free(rdpRpc* rpc)
{
if (rpc != NULL)
{
ntlm_http_free(rpc->ntlm_http_in);
ntlm_http_free(rpc->ntlm_http_out);
rpc_client_virtual_connection_free(rpc->VirtualConnection);
xfree(rpc);
}
}

703
libfreerdp-core/rpc.h Normal file
View File

@@ -0,0 +1,703 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* RPC over HTTP
*
* Copyright 2012 Fujitsu Technology Solutions GmbH
* Copyright 2012 Dmitrij Jasnov <dmitrij.jasnov@ts.fujitsu.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 FREERDP_CORE_RPC_H
#define FREERDP_CORE_RPC_H
typedef struct rdp_rpc rdpRpc;
typedef struct rdp_ntlm_http rdpNtlmHttp;
#include "tcp.h"
#include "rts.h"
#include "http.h"
#include "transport.h"
#include <time.h>
#include <winpr/sspi.h>
#include <freerdp/types.h>
#include <freerdp/settings.h>
#include <freerdp/crypto/tls.h>
#include <freerdp/crypto/crypto.h>
#include <freerdp/utils/wait_obj.h>
#include <freerdp/utils/sleep.h>
#include <freerdp/utils/debug.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/hexdump.h>
struct _rpc_pdu_header
{
uint8 rpc_vers;
uint8 rpc_vers_minor;
uint8 ptype;
uint8 pfc_flags;
uint8 packed_drep[4];
uint16 frag_length;
uint16 auth_length;
uint32 call_id;
};
typedef struct _rpc_pdu_header RPC_PDU_HEADER;
typedef uint16 p_context_id_t;
typedef struct {
uuid if_uuid;
uint32 if_version;
} p_syntax_id_t;
typedef struct {
p_context_id_t p_cont_id;
uint8 n_transfer_syn; /* number of items */
uint8 reserved; /* alignment pad, m.b.z. */
p_syntax_id_t abstract_syntax; /* transfer syntax list */
p_syntax_id_t* transfer_syntaxes; /*size_is(n_transfer_syn)*/
} p_cont_elem_t;
typedef struct {
uint8 n_context_elem; /* number of items */
uint8 reserved; /* alignment pad, m.b.z. */
uint16 reserved2; /* alignment pad, m.b.z. */
p_cont_elem_t* p_cont_elem; /*size_is(n_cont_elem)*/
} p_cont_list_t;
typedef enum {
acceptance, user_rejection, provider_rejection
} p_cont_def_result_t;
typedef enum {
reason_not_specified,
abstract_syntax_not_supported,
proposed_transfer_syntaxes_not_supported,
local_limit_exceeded
} p_provider_reason_t;
typedef struct {
p_cont_def_result_t result;
p_provider_reason_t reason; /* only relevant if result !=
* acceptance */
p_syntax_id_t transfer_syntax;/* tr syntax selected
* 0 if result not
* accepted */
} p_result_t;
/* Same order and number of elements as in bind request */
typedef struct {
uint8 n_results; /* count */
uint8 reserved; /* alignment pad, m.b.z. */
uint16 reserved2; /* alignment pad, m.b.z. */
p_result_t* p_results; /*size_is(n_results)*/
} p_result_list_t;
typedef struct {
uint8 major;
uint8 minor;
} version_t;
typedef version_t p_rt_version_t;
typedef struct {
uint8 n_protocols; /* count */
p_rt_version_t* p_protocols; /* size_is(n_protocols) */
} p_rt_versions_supported_t;
typedef struct {
uint16 length;
char* port_spec; /* port string spec; size_is(length) */
} port_any_t;
#define REASON_NOT_SPECIFIED 0
#define TEMPORARY_CONGESTION 1
#define LOCAL_LIMIT_EXCEEDED 2
#define CALLED_PADDR_UNKNOWN 3 /* not used */
#define PROTOCOL_VERSION_NOT_SUPPORTED 4
#define DEFAULT_CONTEXT_NOT_SUPPORTED 5 /* not used */
#define USER_DATA_NOT_READABLE 6 /* not used */
#define NO_PSAP_AVAILABLE 7 /* not used */
typedef uint16 rpcrt_reason_code_t;/* 0..65535 */
typedef struct {
uint8 rpc_vers;
uint8 rpc_vers_minor;
uint8 reserved[2];/* must be zero */
uint8 packed_drep[4];
uint32 reject_status;
uint8 reserved2[4];
} rpcrt_optional_data_t;
typedef struct {
rpcrt_reason_code_t reason_code; /* 0..65535 */
rpcrt_optional_data_t rpc_info; /* may be RPC specific */
} rpcconn_reject_optional_data_t;
typedef struct {
rpcrt_reason_code_t reason_code; /* 0..65535 */
rpcrt_optional_data_t rpc_info; /* may be RPC-specific */
} rpcconn_disc_optional_data_t;
typedef struct{
/* restore 4 byte alignment */
uint8* auth_pad; /* align(4); size_is(auth_pad_length) */
uint8 auth_type; /* :01 which authent service */
uint8 auth_level; /* :01 which level within service */
uint8 auth_pad_length; /* :01 */
uint8 auth_reserved; /* :01 reserved, m.b.z. */
uint32 auth_context_id; /* :04 */
uint8* auth_value; /* credentials; size_is(auth_length) */
} auth_verifier_co_t;
/* Connection-oriented PDU Definitions */
typedef struct {
/* start 8-octet aligned */
/* common fields */
uint8 rpc_vers; /* 00:01 RPC version */
uint8 rpc_vers_minor ; /* 01:01 minor version */
uint8 PTYPE; /* 02:01 alter context PDU */
uint8 pfc_flags; /* 03:01 flags */
uint8 packed_drep[4]; /* 04:04 NDR data rep format label*/
uint16 frag_length; /* 08:02 total length of fragment */
uint16 auth_length; /* 10:02 length of auth_value */
uint32 call_id; /* 12:04 call identifier */
/* end common fields */
uint16 max_xmit_frag; /* ignored */
uint16 max_recv_frag; /* ignored */
uint32 assoc_group_id; /* ignored */
/* presentation context list */
p_cont_list_t p_context_elem; /* variable size */
/* optional authentication verifier */
/* following fields present iff auth_length != 0 */
auth_verifier_co_t auth_verifier;
} rpcconn_alter_context_hdr_t;
typedef struct {
/* start 8-octet aligned */
/* common fields */
uint8 rpc_vers; /* 00:01 RPC version */
uint8 rpc_vers_minor; /* 01:01 minor version */
uint8 PTYPE; /* 02:01 alter
context response PDU */
uint8 pfc_flags; /* 03:01 flags */
uint8 packed_drep[4]; /* 04:04 NDR data rep format label*/
uint16 frag_length; /* 08:02 total length of fragment */
uint16 auth_length; /* 10:02 length of auth_value */
uint32 call_id; /* 12:04 call identifier */
/* end common fields */
uint16 max_xmit_frag; /* ignored */
uint16 max_recv_frag; /* ignored */
uint32 assoc_group_id; /* ignored */
port_any_t sec_addr; /* ignored */
/* restore 4-octet alignment */
uint8* pad2; /* size_is(align(4)) */
/* presentation context result list, including hints */
p_result_list_t p_result_list; /* variable size */
/* optional authentication verifier */
/* following fields present iff auth_length != 0 */
auth_verifier_co_t auth_verifier; /* xx:yy */
} rpcconn_alter_context_response_hdr_t;
/* bind header */
typedef struct {
/* start 8-octet aligned */
/* common fields */
uint8 rpc_vers; /* 00:01 RPC version */
uint8 rpc_vers_minor; /* 01:01 minor version */
uint8 PTYPE; /* 02:01 bind PDU */
uint8 pfc_flags; /* 03:01 flags */
uint8 packed_drep[4]; /* 04:04 NDR data rep format label*/
uint16 frag_length; /* 08:02 total length of fragment */
uint16 auth_length; /* 10:02 length of auth_value */
uint32 call_id; /* 12:04 call identifier */
/* end common fields */
uint16 max_xmit_frag; /* 16:02 max transmit frag size, bytes */
uint16 max_recv_frag; /* 18:02 max receive frag size, bytes */
uint32 assoc_group_id; /* 20:04 incarnation of client-server
* assoc group */
/* presentation context list */
p_cont_list_t p_context_elem; /* variable size */
/* optional authentication verifier */
/* following fields present iff auth_length != 0 */
auth_verifier_co_t auth_verifier;
} rpcconn_bind_hdr_t;
typedef struct {
/* start 8-octet aligned */
/* common fields */
uint8 rpc_vers; /* 00:01 RPC version */
uint8 rpc_vers_minor ; /* 01:01 minor version */
uint8 PTYPE; /* 02:01 bind ack PDU */
uint8 pfc_flags; /* 03:01 flags */
uint8 packed_drep[4]; /* 04:04 NDR data rep format label*/
uint16 frag_length; /* 08:02 total length of fragment */
uint16 auth_length; /* 10:02 length of auth_value */
uint32 call_id; /* 12:04 call identifier */
/* end common fields */
uint16 max_xmit_frag; /* 16:02 max transmit frag size */
uint16 max_recv_frag; /* 18:02 max receive frag size */
uint32 assoc_group_id; /* 20:04 returned assoc_group_id */
port_any_t sec_addr; /* 24:yy optional secondary address
* for process incarnation; local port
* part of address only */
/* restore 4-octet alignment */
uint8* pad2; /* size_is(align(4)) */
/* presentation context result list, including hints */
p_result_list_t p_result_list; /* variable size */
/* optional authentication verifier */
/* following fields present iff auth_length != 0 */
auth_verifier_co_t auth_verifier; /* xx:yy */
} rpcconn_bind_ack_hdr_t;
typedef struct {
/* start 8-octet aligned */
/* common fields */
uint8 rpc_vers; /* 00:01 RPC version */
uint8 rpc_vers_minor ; /* 01:01 minor version */
uint8 PTYPE; /* 02:01 bind ack PDU */
uint8 pfc_flags; /* 03:01 flags */
uint8 packed_drep[4]; /* 04:04 NDR data rep format label*/
uint16 frag_length; /* 08:02 total length of fragment */
uint16 auth_length; /* 10:02 length of auth_value */
uint32 call_id; /* 12:04 call identifier */
/* end common fields */
uint16 max_xmit_frag; /* 16:02 max transmit frag size */
uint16 max_recv_frag; /* 18:02 max receive frag size */
/* optional authentication verifier */
/* following fields present iff auth_length != 0 */
auth_verifier_co_t auth_verifier; /* xx:yy */
} rpcconn_rpc_auth_3_hdr_t;
typedef struct {
/* start 8-octet aligned */
/* common fields */
uint8 rpc_vers; /* 00:01 RPC version */
uint8 rpc_vers_minor ; /* 01:01 minor version */
uint8 PTYPE; /* 02:01 bind nak PDU */
uint8 pfc_flags; /* 03:01 flags */
uint8 packed_drep[4]; /* 04:04 NDR data rep format label*/
uint16 frag_length; /* 08:02 total length of fragment */
uint16 auth_length; /* 10:02 length of auth_value */
uint32 call_id; /* 12:04 call identifier */
/* end common fields */
/*p_reject_reason_t*/uint16 provider_reject_reason; /* 16:02 presentation (TODO search definition of p_reject_reason_t)
context reject */
p_rt_versions_supported_t versions; /* 18:yy array of protocol
* versions supported */
} rpcconn_bind_nak_hdr_t;
typedef struct {
/* start 8-octet aligned */
/* common fields */
uint8 rpc_vers; /* 00:01 RPC version */
uint8 rpc_vers_minor; /* 01:01 minor version */
uint8 PTYPE; /* 02:01 CO cancel PDU */
uint8 pfc_flags; /* 03:01 flags */
uint8 packed_drep[4]; /* 04:04 NDR data rep format label*/
uint16 frag_length; /* 08:02 total length of fragment */
uint16 auth_length; /* 10:02 length of auth_value */
uint32 call_id; /* 12:04 call identifier */
/* end common fields */
/* optional authentication verifier
* following fields present iff auth_length != 0 */
auth_verifier_co_t auth_verifier; /* xx:yy */
} rpcconn_cancel_hdr_t;
typedef struct {
/* start 8-octet aligned */
/* common fields */
uint8 rpc_vers; /* 00:01 RPC version */
uint8 rpc_vers_minor; /* 01:01 minor version */
uint8 PTYPE; /* 02:01 fault PDU */
uint8 pfc_flags; /* 03:01 flags */
uint8 packed_drep[4]; /* 04:04 NDR data rep format label*/
uint16 frag_length; /* 08:02 total length of fragment */
uint16 auth_length; /* 10:02 length of auth_value */
uint32 call_id; /* 12:04 call identifier */
/* end common fields */
/* needed for request, response, fault */
uint32 alloc_hint; /* 16:04 allocation hint */
p_context_id_t p_cont_id; /* 20:02 pres context, i.e. data rep */
/* needed for response or fault */
uint8 cancel_count; /* 22:01 received cancel count */
uint8 reserved; /* 23:01 reserved, m.b.z. */
/* fault code */
uint32 status; /* 24:04 run-time fault code or zero */
/* always pad to next 8-octet boundary */
uint8 reserved2[4]; /* 28:04 reserved padding, m.b.z. */
/* stub data here, 8-octet aligned
.
.
. */
uint8* stub_data;
/* optional authentication verifier */
/* following fields present iff auth_length != 0 */
auth_verifier_co_t auth_verifier; /* xx:yy */
} rpcconn_fault_hdr_t;
typedef struct {
/* start 8-octet aligned */
/* common fields */
uint8 rpc_vers; /* 00:01 RPC version */
uint8 rpc_vers_minor; /* 01:01 minor version */
uint8 PTYPE; /* 02:01 orphaned PDU */
uint8 pfc_flags; /* 03:01 flags */
uint8 packed_drep[4]; /* 04:04 NDR data rep format label*/
uint16 frag_length; /* 08:02 total length of fragment */
uint16 auth_length; /* 10:02 length of auth_value */
uint32 call_id; /* 12:04 call identifier */
/* end common fields */
/* optional authentication verifier
* following fields present iff auth_length != 0 */
auth_verifier_co_t auth_verifier; /* xx:yy */
} rpcconn_orphaned_hdr_t;
typedef struct {
/* start 8-octet aligned */
/* common fields */
uint8 rpc_vers; /* 00:01 RPC version */
uint8 rpc_vers_minor; /* 01:01 minor version */
uint8 PTYPE; /* 02:01 request PDU */
uint8 pfc_flags; /* 03:01 flags */
uint8 packed_drep[4]; /* 04:04 NDR data rep format label*/
uint16 frag_length; /* 08:02 total length of fragment */
uint16 auth_length; /* 10:02 length of auth_value */
uint32 call_id; /* 12:04 call identifier */
/* end common fields */
/* needed on request, response, fault */
uint32 alloc_hint; /* 16:04 allocation hint */
p_context_id_t p_cont_id; /* 20:02 pres context, i.e. data rep */
uint16 opnum; /* 22:02 operation #
* within the interface */
/* optional field for request, only present if the PFC_OBJECT_UUID
* field is non-zero */
uuid object; /* 24:16 object UID */
/* stub data, 8-octet aligned
.
.
. */
uint8* stub_data;
/* optional authentication verifier */
/* following fields present iff auth_length != 0 */
auth_verifier_co_t auth_verifier; /* xx:yy */
} rpcconn_request_hdr_t;
typedef struct {
/* start 8-octet aligned */
/* common fields */
uint8 rpc_vers; /* 00:01 RPC version */
uint8 rpc_vers_minor; /* 01:01 minor version */
uint8 PTYPE; /* 02:01 response PDU */
uint8 pfc_flags; /* 03:01 flags */
uint8 packed_drep[4]; /* 04:04 NDR data rep format label*/
uint16 frag_length; /* 08:02 total length of fragment */
uint16 auth_length; /* 10:02 length of auth_value */
uint32 call_id; /* 12:04 call identifier */
/* end common fields */
/* needed for request, response, fault */
uint32 alloc_hint; /* 16:04 allocation hint */
p_context_id_t p_cont_id; /* 20:02 pres context, i.e.
* data rep */
/* needed for response or fault */
uint8 cancel_count; /* 22:01 cancel count */
uint8 reserved; /* 23:01 reserved, m.b.z. */
/* stub data here, 8-octet aligned
.
.
. */
uint8* stub_data;
/* optional authentication verifier */
/* following fields present iff auth_length != 0 */
auth_verifier_co_t auth_verifier; /* xx:yy */
} rpcconn_response_hdr_t;
typedef struct {
/* start 8-octet aligned */
/* common fields */
uint8 rpc_vers; /* 00:01 RPC version */
uint8 rpc_vers_minor; /* 01:01 minor version */
uint8 PTYPE; /* 02:01 shutdown PDU */
uint8 pfc_flags; /* 03:01 flags */
uint8 packed_drep[4]; /* 04:04 NDR data rep format label*/
uint16 frag_length; /* 08:02 total length of fragment */
uint16 auth_length; /* 10:02 */
uint32 call_id; /* 12:04 call identifier */
/* end common fields */
} rpcconn_shutdown_hdr_t;
struct rdp_ntlm
{
UNICONV* uniconv;
CtxtHandle context;
uint32 cbMaxToken;
uint32 fContextReq;
uint32 pfContextAttr;
TimeStamp expiration;
PSecBuffer pBuffer;
SecBuffer inputBuffer;
SecBuffer outputBuffer;
boolean haveContext;
boolean haveInputBuffer;
SecBufferDesc inputBufferDesc;
SecBufferDesc outputBufferDesc;
CredHandle credentials;
boolean confidentiality;
SecPkgInfo* pPackageInfo;
SecurityFunctionTable* table;
SEC_WINNT_AUTH_IDENTITY identity;
SecPkgContext_Sizes ContextSizes;
};
typedef struct rdp_ntlm rdpNtlm;
enum _TSG_CHANNEL
{
TSG_CHANNEL_IN,
TSG_CHANNEL_OUT
};
typedef enum _TSG_CHANNEL TSG_CHANNEL;
struct rdp_ntlm_http
{
rdpNtlm* ntlm;
HttpContext* context;
};
/* Ping Originator */
struct rpc_ping_originator
{
uint32 ConnectionTimeout;
uint32 LastPacketSentTimestamp;
uint32 KeepAliveInterval;
};
typedef struct rpc_ping_originator RpcPingOriginator;
/* Client In Channel */
struct rpc_in_channel
{
/* Sending Channel */
uint32 PlugState;
void* SendQueue;
uint32 BytesSent;
uint32 SenderAvailableWindow;
uint32 PeerReceiveWindow;
/* Ping Originator */
RpcPingOriginator PingOriginator;
};
typedef struct rpc_in_channel RpcInChannel;
/* Client Out Channel */
struct rpc_out_channel
{
/* Receiving Channel */
uint32 ReceiveWindow;
uint32 ReceiveWindowSize;
uint32 ReceiverAvailableWindow;
uint32 BytesReceived;
uint32 AvailableWindowAdvertised;
};
typedef struct rpc_out_channel RpcOutChannel;
/* Client Virtual Connection */
enum _VIRTUAL_CONNECTION_STATE
{
VIRTUAL_CONNECTION_STATE_INITIAL,
VIRTUAL_CONNECTION_STATE_OUT_CHANNEL_WAIT,
VIRTUAL_CONNECTION_STATE_WAIT_A3W,
VIRTUAL_CONNECTION_STATE_WAIT_C2,
VIRTUAL_CONNECTION_STATE_OPENED,
VIRTUAL_CONNECTION_STATE_FINAL
};
typedef enum _VIRTUAL_CONNECTION_STATE VIRTUAL_CONNECTION_STATE;
struct rpc_virtual_connection
{
uint8 Cookie[16]; /* Virtual Connection Cookie */
VIRTUAL_CONNECTION_STATE State; /* Virtual Connection State */
RpcInChannel* DefaultInChannel; /* Default IN Channel */
RpcInChannel* NonDefaultInChannel; /* Non-Default IN Channel */
uint8 DefaultInChannelCookie[16]; /* Default IN Channel Cookie */
uint8 NonDefaultInChannelCookie[16]; /* Non-Default Default IN Channel Cookie */
RpcOutChannel* DefaultOutChannel; /* Default OUT Channel */
RpcOutChannel* NonDefaultOutChannel; /* Non-Default OUT Channel */
uint8 DefaultOutChannelCookie[16]; /* Default OUT Channel Cookie */
uint8 NonDefaultOutChannelCookie[16]; /* Non-Default Default OUT Channel Cookie */
uint8 AssociationGroupId[16]; /* AssociationGroupId */
};
typedef struct rpc_virtual_connection RpcVirtualConnection;
struct rdp_rpc
{
rdpTls* tls_in;
rdpTls* tls_out;
rdpNtlm* ntlm;
int send_seq_num;
rdpNtlmHttp* ntlm_http_in;
rdpNtlmHttp* ntlm_http_out;
UNICONV* uniconv;
rdpSettings* settings;
rdpTransport* transport;
uint8* write_buffer;
uint32 write_buffer_len;
uint8* read_buffer;
uint32 read_buffer_len;
uint32 call_id;
uint32 pipe_call_id;
uint32 ReceiveWindow;
RpcVirtualConnection* VirtualConnection;
};
boolean ntlm_authenticate(rdpNtlm* ntlm);
boolean ntlm_client_init(rdpNtlm* ntlm, boolean confidentiality, char* user, char* domain, char* password);
void ntlm_client_uninit(rdpNtlm* ntlm);
rdpNtlm* ntlm_new();
void ntlm_free(rdpNtlm* ntlm);
boolean rpc_connect(rdpRpc* rpc);
boolean rpc_ntlm_http_out_connect(rdpRpc* rpc);
boolean rpc_ntlm_http_in_connect(rdpRpc* rpc);
void rpc_pdu_header_read(STREAM* s, RPC_PDU_HEADER* header);
int rpc_out_write(rdpRpc* rpc, uint8* data, int length);
int rpc_in_write(rdpRpc* rpc, uint8* data, int length);
int rpc_out_read(rdpRpc* rpc, uint8* data, int length);
int rpc_tsg_write(rdpRpc* rpc, uint8* data, int length, uint16 opnum);
int rpc_read(rdpRpc* rpc, uint8* data, int length);
rdpRpc* rpc_new(rdpTransport* transport);
void rpc_free(rdpRpc* rpc);
#ifdef WITH_DEBUG_TSG
#define WITH_DEBUG_RPC
#endif
#ifdef WITH_DEBUG_RPC
#define DEBUG_RPC(fmt, ...) DEBUG_CLASS(RPC, fmt, ## __VA_ARGS__)
#else
#define DEBUG_RPC(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
#endif
#endif /* FREERDP_CORE_RPC_H */

709
libfreerdp-core/rts.c Normal file
View File

@@ -0,0 +1,709 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Request To Send (RTS) PDUs
*
* 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 "rts.h"
/**
* Connection Establishment\n
*
* Client Outbound Proxy Inbound Proxy Server\n
* | | | |\n
* |-----------------IN Channel Request--------------->| |\n
* |---OUT Channel Request-->| |<-Legacy Server Response-|\n
* | |<--------------Legacy Server Response--------------|\n
* | | | |\n
* |---------CONN_A1-------->| | |\n
* |----------------------CONN_B1--------------------->| |\n
* | |----------------------CONN_A2--------------------->|\n
* | | | |\n
* |<--OUT Channel Response--| |---------CONN_B2-------->|\n
* |<--------CONN_A3---------| | |\n
* | |<---------------------CONN_C1----------------------|\n
* | | |<--------CONN_B3---------|\n
* |<--------CONN_C2---------| | |\n
* | | | |\n
*
*/
boolean rts_connect(rdpRpc* rpc)
{
int status;
RTS_PDU rts_pdu;
HttpResponse* http_response;
if (!rpc_ntlm_http_out_connect(rpc))
{
printf("rpc_out_connect_http error!\n");
return false;
}
if (!rts_send_CONN_A1_pdu(rpc))
{
printf("rpc_send_CONN_A1_pdu error!\n");
return false;
}
if (!rpc_ntlm_http_in_connect(rpc))
{
printf("rpc_in_connect_http error!\n");
return false;
}
if (!rts_send_CONN_B1_pdu(rpc))
{
printf("rpc_send_CONN_B1_pdu error!\n");
return false;
}
/* Receive OUT Channel Response */
http_response = http_response_recv(rpc->tls_out);
if (http_response->StatusCode != 200)
{
printf("rts_connect error!\n");
http_response_print(http_response);
return false;
}
http_response_print(http_response);
http_response_free(http_response);
/* Receive CONN_A3 RTS PDU */
status = rts_recv_pdu(rpc, &rts_pdu);
/* Receive CONN_C2 RTS PDU */
status = rts_recv_pdu(rpc, &rts_pdu);
return true;
}
#ifdef WITH_DEBUG_RTS
static const char* const RTS_CMD_STRINGS[] =
{
"ReceiveWindowSize",
"FlowControlAck",
"ConnectionTimeout",
"Cookie",
"ChannelLifetime",
"ClientKeepalive",
"Version",
"Empty",
"Padding",
"NegativeANCE",
"ANCE",
"ClientAddress",
"AssociationGroupId",
"Destination",
"PingTrafficSentNotify"
};
#endif
void rts_pdu_header_read(STREAM* s, RTS_PDU_HEADER* header)
{
stream_read_uint8(s, header->rpc_vers); /* rpc_vers (1 byte) */
stream_read_uint8(s, header->rpc_vers_minor); /* rpc_vers_minor (1 byte) */
stream_read_uint8(s, header->ptype); /* PTYPE (1 byte) */
stream_read_uint8(s, header->pfc_flags); /* pfc_flags (1 byte) */
stream_read_uint8(s, header->packed_drep[0]); /* packet_drep[0] (1 byte) */
stream_read_uint8(s, header->packed_drep[1]); /* packet_drep[1] (1 byte) */
stream_read_uint8(s, header->packed_drep[2]); /* packet_drep[2] (1 byte) */
stream_read_uint8(s, header->packed_drep[3]); /* packet_drep[3] (1 byte) */
stream_read_uint16(s, header->frag_length); /* frag_length (2 bytes) */
stream_read_uint16(s, header->auth_length); /* auth_length (2 bytes) */
stream_read_uint32(s, header->call_id); /* call_id (4 bytes) */
stream_read_uint16(s, header->flags); /* flags (2 bytes) */
stream_read_uint16(s, header->numberOfCommands); /* numberOfCommands (2 bytes) */
}
void rts_pdu_header_write(STREAM* s, RTS_PDU_HEADER* header)
{
stream_write_uint8(s, header->rpc_vers); /* rpc_vers (1 byte) */
stream_write_uint8(s, header->rpc_vers_minor); /* rpc_vers_minor (1 byte) */
stream_write_uint8(s, header->ptype); /* PTYPE (1 byte) */
stream_write_uint8(s, header->pfc_flags); /* pfc_flags (1 byte) */
stream_write_uint8(s, header->packed_drep[0]); /* packet_drep[0] (1 byte) */
stream_write_uint8(s, header->packed_drep[1]); /* packet_drep[1] (1 byte) */
stream_write_uint8(s, header->packed_drep[2]); /* packet_drep[2] (1 byte) */
stream_write_uint8(s, header->packed_drep[3]); /* packet_drep[3] (1 byte) */
stream_write_uint16(s, header->frag_length); /* frag_length (2 bytes) */
stream_write_uint16(s, header->auth_length); /* auth_length (2 bytes) */
stream_write_uint32(s, header->call_id); /* call_id (4 bytes) */
stream_write_uint16(s, header->flags); /* flags (2 bytes) */
stream_write_uint16(s, header->numberOfCommands); /* numberOfCommands (2 bytes) */
}
void rts_receive_window_size_command_read(rdpRpc* rpc, STREAM* s)
{
stream_seek_uint32(s); /* ReceiveWindowSize (4 bytes) */
}
void rts_receive_window_size_command_write(STREAM* s, uint32 ReceiveWindowSize)
{
stream_write_uint32(s, RTS_CMD_RECEIVE_WINDOW_SIZE); /* CommandType (4 bytes) */
stream_write_uint32(s, ReceiveWindowSize); /* ReceiveWindowSize (4 bytes) */
}
void rts_flow_control_ack_command_read(rdpRpc* rpc, STREAM* s)
{
/* Ack (24 bytes) */
stream_seek_uint32(s); /* BytesReceived (4 bytes) */
stream_seek_uint32(s); /* AvailableWindow (4 bytes) */
stream_seek(s, 16); /* ChannelCookie (16 bytes) */
}
void rts_flow_control_ack_command_write(STREAM* s, uint32 BytesReceived, uint32 AvailableWindow, uint8* ChannelCookie)
{
stream_write_uint32(s, RTS_CMD_FLOW_CONTROL_ACK); /* CommandType (4 bytes) */
/* Ack (24 bytes) */
stream_write_uint32(s, BytesReceived); /* BytesReceived (4 bytes) */
stream_write_uint32(s, AvailableWindow); /* AvailableWindow (4 bytes) */
stream_write(s, ChannelCookie, 16); /* ChannelCookie (16 bytes) */
}
void rts_connection_timeout_command_read(rdpRpc* rpc, STREAM* s)
{
stream_seek_uint32(s); /* ConnectionTimeout (4 bytes) */
}
void rts_connection_timeout_command_write(STREAM* s, uint32 ConnectionTimeout)
{
stream_write_uint32(s, RTS_CMD_CONNECTION_TIMEOUT); /* CommandType (4 bytes) */
stream_write_uint32(s, ConnectionTimeout); /* ConnectionTimeout (4 bytes) */
}
void rts_cookie_command_read(rdpRpc* rpc, STREAM* s)
{
stream_seek(s, 16); /* Cookie (16 bytes) */
}
void rts_cookie_command_write(STREAM* s, uint8* Cookie)
{
stream_write_uint32(s, RTS_CMD_COOKIE); /* CommandType (4 bytes) */
stream_write(s, Cookie, 16); /* Cookie (16 bytes) */
}
void rts_channel_lifetime_command_read(rdpRpc* rpc, STREAM* s)
{
stream_seek_uint32(s); /* ChannelLifetime (4 bytes) */
}
void rts_channel_lifetime_command_write(STREAM* s, uint32 ChannelLifetime)
{
stream_write_uint32(s, RTS_CMD_CHANNEL_LIFETIME); /* CommandType (4 bytes) */
stream_write_uint32(s, ChannelLifetime); /* ChannelLifetime (4 bytes) */
}
void rts_client_keepalive_command_read(rdpRpc* rpc, STREAM* s)
{
stream_seek_uint32(s); /* ClientKeepalive (4 bytes) */
}
void rts_client_keepalive_command_write(STREAM* s, uint32 ClientKeepalive)
{
stream_write_uint32(s, RTS_CMD_CLIENT_KEEPALIVE); /* CommandType (4 bytes) */
stream_write_uint32(s, ClientKeepalive); /* ClientKeepalive (4 bytes) */
}
void rts_version_command_read(rdpRpc* rpc, STREAM* s)
{
stream_seek_uint32(s); /* Version (4 bytes) */
}
void rts_version_command_write(STREAM* s)
{
stream_write_uint32(s, RTS_CMD_VERSION); /* CommandType (4 bytes) */
stream_write_uint32(s, 1); /* Version (4 bytes) */
}
void rts_empty_command_read(rdpRpc* rpc, STREAM* s)
{
}
void rts_empty_command_write(STREAM* s)
{
stream_write_uint32(s, RTS_CMD_EMPTY); /* CommandType (4 bytes) */
}
void rts_padding_command_read(rdpRpc* rpc, STREAM* s)
{
uint32 ConformanceCount;
stream_read_uint32(s, ConformanceCount); /* ConformanceCount (4 bytes) */
stream_seek(s, ConformanceCount); /* Padding (variable) */
}
void rts_padding_command_write(STREAM* s, uint32 ConformanceCount)
{
stream_write_uint32(s, ConformanceCount); /* ConformanceCount (4 bytes) */
stream_write_zero(s, ConformanceCount); /* Padding (variable) */
}
void rts_negative_ance_command_read(rdpRpc* rpc, STREAM* s)
{
}
void rts_negative_ance_command_write(STREAM* s)
{
stream_write_uint32(s, RTS_CMD_NEGATIVE_ANCE); /* CommandType (4 bytes) */
}
void rts_ance_command_read(rdpRpc* rpc, STREAM* s)
{
}
void rts_ance_command_write(STREAM* s)
{
stream_write_uint32(s, RTS_CMD_ANCE); /* CommandType (4 bytes) */
}
void rts_client_address_command_read(rdpRpc* rpc, STREAM* s)
{
uint32 AddressType;
stream_read_uint32(s, AddressType); /* AddressType (4 bytes) */
if (AddressType == 0)
{
stream_seek(s, 4); /* ClientAddress (4 bytes) */
}
else
{
stream_seek(s, 16); /* ClientAddress (16 bytes) */
}
stream_seek(s, 12); /* padding (12 bytes) */
}
void rts_client_address_command_write(STREAM* s, uint32 AddressType, uint8* ClientAddress)
{
stream_write_uint32(s, RTS_CMD_CLIENT_ADDRESS); /* CommandType (4 bytes) */
stream_write_uint32(s, AddressType); /* AddressType (4 bytes) */
if (AddressType == 0)
{
stream_write(s, ClientAddress, 4); /* ClientAddress (4 bytes) */
}
else
{
stream_write(s, ClientAddress, 16); /* ClientAddress (16 bytes) */
}
stream_write_zero(s, 12); /* padding (12 bytes) */
}
void rts_association_group_id_command_read(rdpRpc* rpc, STREAM* s)
{
stream_seek(s, 16); /* AssociationGroupId (16 bytes) */
}
void rts_association_group_id_command_write(STREAM* s, uint8* associationGroupId)
{
stream_write_uint32(s, RTS_CMD_ASSOCIATION_GROUP_ID); /* CommandType (4 bytes) */
stream_write(s, associationGroupId, 16); /* AssociationGroupId (16 bytes) */
}
void rts_destination_command_read(rdpRpc* rpc, STREAM* s)
{
stream_seek_uint32(s); /* Destination (4 bytes) */
}
void rts_destination_command_write(STREAM* s, uint32 Destination)
{
stream_write_uint32(s, RTS_CMD_DESTINATION); /* CommandType (4 bytes) */
stream_write_uint32(s, Destination); /* Destination (4 bytes) */
}
void rts_ping_traffic_sent_notify_command_read(rdpRpc* rpc, STREAM* s)
{
stream_seek_uint32(s); /* PingTrafficSent (4 bytes) */
}
void rts_ping_traffic_sent_notify_command_write(STREAM* s, uint32 PingTrafficSent)
{
stream_write_uint32(s, RTS_CMD_PING_TRAFFIC_SENT_NOTIFY); /* CommandType (4 bytes) */
stream_write_uint32(s, PingTrafficSent); /* PingTrafficSent (4 bytes) */
}
void rpc_generate_cookie(uint8* cookie)
{
RAND_pseudo_bytes(cookie, 16);
}
boolean rts_send_CONN_A1_pdu(rdpRpc* rpc)
{
STREAM* s;
RTS_PDU_HEADER header;
uint32 ReceiveWindowSize;
uint8* OUTChannelCookie;
uint8* VirtualConnectionCookie;
header.rpc_vers = 5;
header.rpc_vers_minor = 0;
header.ptype = PTYPE_RTS;
header.pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG;
header.packed_drep[0] = 0x10;
header.packed_drep[1] = 0x00;
header.packed_drep[2] = 0x00;
header.packed_drep[3] = 0x00;
header.frag_length = 76;
header.auth_length = 0;
header.call_id = 0;
header.flags = 0;
header.numberOfCommands = 4;
DEBUG_RPC("Sending CONN_A1 RTS PDU");
s = stream_new(header.frag_length);
rpc_generate_cookie((uint8*) &(rpc->VirtualConnection->Cookie));
rpc_generate_cookie((uint8*) &(rpc->VirtualConnection->DefaultOutChannelCookie));
VirtualConnectionCookie = (uint8*) &(rpc->VirtualConnection->Cookie);
OUTChannelCookie = (uint8*) &(rpc->VirtualConnection->DefaultOutChannelCookie);
ReceiveWindowSize = rpc->VirtualConnection->DefaultOutChannel->ReceiveWindow;
rts_pdu_header_write(s, &header); /* RTS Header (20 bytes) */
rts_version_command_write(s); /* Version (8 bytes) */
rts_cookie_command_write(s, VirtualConnectionCookie); /* VirtualConnectionCookie (20 bytes) */
rts_cookie_command_write(s, OUTChannelCookie); /* OUTChannelCookie (20 bytes) */
rts_receive_window_size_command_write(s, ReceiveWindowSize); /* ReceiveWindowSize (8 bytes) */
stream_seal(s);
rpc_out_write(rpc, s->data, s->size);
stream_free(s);
return true;
}
boolean rts_send_CONN_B1_pdu(rdpRpc* rpc)
{
STREAM* s;
RTS_PDU_HEADER header;
uint8* INChannelCookie;
uint8* AssociationGroupId;
uint8* VirtualConnectionCookie;
header.rpc_vers = 5;
header.rpc_vers_minor = 0;
header.ptype = PTYPE_RTS;
header.pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG;
header.packed_drep[0] = 0x10;
header.packed_drep[1] = 0x00;
header.packed_drep[2] = 0x00;
header.packed_drep[3] = 0x00;
header.frag_length = 104;
header.auth_length = 0;
header.call_id = 0;
header.flags = 0;
header.numberOfCommands = 6;
DEBUG_RPC("Sending CONN_B1 RTS PDU");
s = stream_new(header.frag_length);
rpc_generate_cookie((uint8*) &(rpc->VirtualConnection->DefaultInChannelCookie));
rpc_generate_cookie((uint8*) &(rpc->VirtualConnection->AssociationGroupId));
VirtualConnectionCookie = (uint8*) &(rpc->VirtualConnection->Cookie);
INChannelCookie = (uint8*) &(rpc->VirtualConnection->DefaultInChannelCookie);
AssociationGroupId = (uint8*) &(rpc->VirtualConnection->AssociationGroupId);
rts_pdu_header_write(s, &header); /* RTS Header (20 bytes) */
rts_version_command_write(s); /* Version (8 bytes) */
rts_cookie_command_write(s, VirtualConnectionCookie); /* VirtualConnectionCookie (20 bytes) */
rts_cookie_command_write(s, INChannelCookie); /* INChannelCookie (20 bytes) */
rts_channel_lifetime_command_write(s, 0x40000000); /* ChannelLifetime (8 bytes) */
rts_client_keepalive_command_write(s, 0x000493E0); /* ClientKeepalive (8 bytes) */
rts_association_group_id_command_write(s, AssociationGroupId); /* AssociationGroupId (20 bytes) */
stream_seal(s);
rpc_in_write(rpc, s->data, s->size);
stream_free(s);
return true;
}
boolean rts_send_keep_alive_pdu(rdpRpc* rpc)
{
STREAM* s;
RTS_PDU_HEADER header;
header.rpc_vers = 5;
header.rpc_vers_minor = 0;
header.ptype = PTYPE_RTS;
header.pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG;
header.packed_drep[0] = 0x10;
header.packed_drep[1] = 0x00;
header.packed_drep[2] = 0x00;
header.packed_drep[3] = 0x00;
header.frag_length = 28;
header.auth_length = 0;
header.call_id = 0;
header.flags = 2;
header.numberOfCommands = 1;
DEBUG_RPC("Sending Keep-Alive RTS PDU");
s = stream_new(header.frag_length);
rts_pdu_header_write(s, &header); /* RTS Header (20 bytes) */
rts_client_keepalive_command_write(s, 0x00007530); /* ClientKeepalive (8 bytes) */
stream_seal(s);
rpc_in_write(rpc, s->data, s->size);
stream_free(s);
return true;
}
boolean rts_send_flow_control_ack_pdu(rdpRpc* rpc)
{
STREAM* s;
RTS_PDU_HEADER header;
uint32 BytesReceived;
uint32 AvailableWindow;
uint8* ChannelCookie;
header.rpc_vers = 5;
header.rpc_vers_minor = 0;
header.ptype = PTYPE_RTS;
header.pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG;
header.packed_drep[0] = 0x10;
header.packed_drep[1] = 0x00;
header.packed_drep[2] = 0x00;
header.packed_drep[3] = 0x00;
header.frag_length = 56;
header.auth_length = 0;
header.call_id = 0;
header.flags = 2;
header.numberOfCommands = 2;
DEBUG_RPC("Sending FlowControlAck RTS PDU");
BytesReceived = rpc->VirtualConnection->DefaultOutChannel->BytesReceived;
AvailableWindow = rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow;
ChannelCookie = (uint8*) &(rpc->VirtualConnection->DefaultOutChannelCookie);
s = stream_new(header.frag_length);
rts_pdu_header_write(s, &header); /* RTS Header (20 bytes) */
rts_destination_command_write(s, FDOutProxy); /* Destination Command (8 bytes) */
/* FlowControlAck Command (28 bytes) */
rts_flow_control_ack_command_write(s, BytesReceived, AvailableWindow, ChannelCookie);
stream_seal(s);
rpc_in_write(rpc, s->data, s->size);
stream_free(s);
return true;
}
boolean rts_send_ping_pdu(rdpRpc* rpc)
{
STREAM* s;
RTS_PDU_HEADER header;
header.rpc_vers = 5;
header.rpc_vers_minor = 0;
header.ptype = PTYPE_RTS;
header.pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG;
header.packed_drep[0] = 0x10;
header.packed_drep[1] = 0x00;
header.packed_drep[2] = 0x00;
header.packed_drep[3] = 0x00;
header.frag_length = 20;
header.auth_length = 0;
header.call_id = 0;
header.flags = 1;
header.numberOfCommands = 0;
DEBUG_RPC("Sending Ping RTS PDU");
s = stream_new(header.frag_length);
rts_pdu_header_write(s, &header); /* RTS Header (20 bytes) */
stream_seal(s);
rpc_in_write(rpc, s->data, s->size);
stream_free(s);
return true;
}
int rts_recv_pdu_commands(rdpRpc* rpc, RTS_PDU* rts_pdu)
{
int i;
STREAM* s;
uint32 CommandType;
s = stream_new(0);
stream_attach(s, rts_pdu->content, rts_pdu->header.frag_length);
DEBUG_RTS("numberOfCommands:%d", rts_pdu->header.numberOfCommands);
if (rts_pdu->header.flags & RTS_FLAG_PING)
{
rts_send_keep_alive_pdu(rpc);
return 0;
}
for (i = 0; i < rts_pdu->header.numberOfCommands; i++)
{
stream_read_uint32(s, CommandType); /* CommandType (4 bytes) */
DEBUG_RTS("CommandType: %s (0x%08X)", RTS_CMD_STRINGS[CommandType % 14], CommandType);
switch (CommandType)
{
case RTS_CMD_RECEIVE_WINDOW_SIZE:
rts_receive_window_size_command_read(rpc, s);
break;
case RTS_CMD_FLOW_CONTROL_ACK:
rts_flow_control_ack_command_read(rpc, s);
break;
case RTS_CMD_CONNECTION_TIMEOUT:
rts_connection_timeout_command_read(rpc, s);
break;
case RTS_CMD_COOKIE:
rts_cookie_command_read(rpc, s);
break;
case RTS_CMD_CHANNEL_LIFETIME:
rts_channel_lifetime_command_read(rpc, s);
break;
case RTS_CMD_CLIENT_KEEPALIVE:
rts_client_keepalive_command_read(rpc, s);
break;
case RTS_CMD_VERSION:
rts_version_command_read(rpc, s);
break;
case RTS_CMD_EMPTY:
rts_empty_command_read(rpc, s);
break;
case RTS_CMD_PADDING:
rts_padding_command_read(rpc, s);
break;
case RTS_CMD_NEGATIVE_ANCE:
rts_negative_ance_command_read(rpc, s);
break;
case RTS_CMD_ANCE:
rts_ance_command_read(rpc, s);
break;
case RTS_CMD_CLIENT_ADDRESS:
rts_client_address_command_read(rpc, s);
break;
case RTS_CMD_ASSOCIATION_GROUP_ID:
rts_association_group_id_command_read(rpc, s);
break;
case RTS_CMD_DESTINATION:
rts_destination_command_read(rpc, s);
break;
case RTS_CMD_PING_TRAFFIC_SENT_NOTIFY:
rts_ping_traffic_sent_notify_command_read(rpc, s);
break;
default:
printf("Error: Unknown RTS Command Type: 0x%x\n", CommandType);
return -1;
break;
}
}
stream_detach(s);
stream_free(s);
return 0;
}
int rts_recv_pdu(rdpRpc* rpc, RTS_PDU* rts_pdu)
{
STREAM* s;
int status;
int length;
uint8 header_buffer[20];
rdpTls* tls_out = rpc->tls_out;
/* read first 20 bytes to get RTS PDU Header */
status = tls_read(tls_out, (uint8*) &header_buffer, 20);
if (status <= 0)
{
printf("rts_recv error\n");
return status;
}
s = stream_new(0);
stream_attach(s, header_buffer, 20);
rts_pdu_header_read(s, &(rts_pdu->header));
stream_detach(s);
stream_free(s);
length = rts_pdu->header.frag_length - 20;
rts_pdu->content = (uint8*) xmalloc(length);
status = tls_read(tls_out, rts_pdu->content, length);
if (status < 0)
{
printf("rts_recv error\n");
return status;
}
if (rts_pdu->header.ptype != PTYPE_RTS)
{
printf("rts_recv error: unexpected ptype:%d\n", rts_pdu->header.ptype);
return -1;
}
#ifdef WITH_DEBUG_RTS
printf("rts_recv(): length: %d\n", length);
freerdp_hexdump(rts_pdu->content, length);
printf("\n");
#endif
rts_recv_pdu_commands(rpc, rts_pdu);
return rts_pdu->header.frag_length;
}

168
libfreerdp-core/rts.h Normal file
View File

@@ -0,0 +1,168 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Request To Send (RTS) PDUs
*
* 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 FREERDP_CORE_RTS_H
#define FREERDP_CORE_RTS_H
#include "rpc.h"
#include "config.h"
#include <freerdp/types.h>
#include <freerdp/utils/debug.h>
#include <freerdp/utils/stream.h>
#define PTYPE_REQUEST 0x00
#define PTYPE_PING 0x01
#define PTYPE_RESPONSE 0x02
#define PTYPE_FAULT 0x03
#define PTYPE_WORKING 0x04
#define PTYPE_NOCALL 0x05
#define PTYPE_REJECT 0x06
#define PTYPE_ACK 0x07
#define PTYPE_CL_CANCEL 0x08
#define PTYPE_FACK 0x09
#define PTYPE_CANCEL_ACK 0x0A
#define PTYPE_BIND 0x0B
#define PTYPE_BIND_ACK 0x0C
#define PTYPE_BIND_NAK 0x0D
#define PTYPE_ALTER_CONTEXT 0x0E
#define PTYPE_ALTER_CONTEXT_RESP 0x0F
#define PTYPE_RPC_AUTH_3 0x10
#define PTYPE_SHUTDOWN 0x11
#define PTYPE_CO_CANCEL 0x12
#define PTYPE_ORPHANED 0x13
#define PTYPE_RTS 0x14
#define PFC_FIRST_FRAG 0x01
#define PFC_LAST_FRAG 0x02
#define PFC_PENDING_CANCEL 0x04
#define PFC_RESERVED_1 0x08
#define PFC_CONC_MPX 0x10
#define PFC_DID_NOT_EXECUTE 0x20
#define PFC_MAYBE 0x40
#define PFC_OBJECT_UUID 0x80
#define RTS_FLAG_NONE 0x0000
#define RTS_FLAG_PING 0x0001
#define RTS_FLAG_OTHER_CMD 0x0002
#define RTS_FLAG_RECYCLE_CHANNEL 0x0004
#define RTS_FLAG_IN_CHANNEL 0x0008
#define RTS_FLAG_OUT_CHANNEL 0x0010
#define RTS_FLAG_EOF 0x0020
#define RTS_FLAG_ECHO 0x0040
#define RTS_CMD_RECEIVE_WINDOW_SIZE 0x00000000
#define RTS_CMD_FLOW_CONTROL_ACK 0x00000001
#define RTS_CMD_CONNECTION_TIMEOUT 0x00000002
#define RTS_CMD_COOKIE 0x00000003
#define RTS_CMD_CHANNEL_LIFETIME 0x00000004
#define RTS_CMD_CLIENT_KEEPALIVE 0x00000005
#define RTS_CMD_VERSION 0x00000006
#define RTS_CMD_EMPTY 0x00000007
#define RTS_CMD_PADDING 0x00000008
#define RTS_CMD_NEGATIVE_ANCE 0x00000009
#define RTS_CMD_ANCE 0x0000000A
#define RTS_CMD_CLIENT_ADDRESS 0x0000000B
#define RTS_CMD_ASSOCIATION_GROUP_ID 0x0000000C
#define RTS_CMD_DESTINATION 0x0000000D
#define RTS_CMD_PING_TRAFFIC_SENT_NOTIFY 0x0000000E
#define FDClient 0x00000000
#define FDInProxy 0x00000001
#define FDServer 0x00000002
#define FDOutProxy 0x00000003
struct _rts_pdu_header
{
uint8 rpc_vers;
uint8 rpc_vers_minor;
uint8 ptype;
uint8 pfc_flags;
uint8 packed_drep[4];
uint16 frag_length;
uint16 auth_length;
uint32 call_id;
uint16 flags;
uint16 numberOfCommands;
};
typedef struct _rts_pdu_header RTS_PDU_HEADER;
struct _rts_pdu
{
RTS_PDU_HEADER header;
uint8* content;
};
typedef struct _rts_pdu RTS_PDU;
boolean rts_connect(rdpRpc* rpc);
void rts_pdu_header_read(STREAM* s, RTS_PDU_HEADER* header);
void rts_pdu_header_write(STREAM* s, RTS_PDU_HEADER* header);
void rts_receive_window_size_command_read(rdpRpc* rpc, STREAM* s);
void rts_receive_window_size_command_write(STREAM* s, uint32 ReceiveWindowSize);
void rts_flow_control_ack_command_read(rdpRpc* rpc, STREAM* s);
void rts_flow_control_ack_command_write(STREAM* s, uint32 BytesReceived, uint32 AvailableWindow, uint8* ChannelCookie);
void rts_connection_timeout_command_read(rdpRpc* rpc, STREAM* s);
void rts_connection_timeout_command_write(STREAM* s, uint32 ConnectionTimeout);
void rts_cookie_command_read(rdpRpc* rpc, STREAM* s);
void rts_cookie_command_write(STREAM* s, uint8* Cookie);
void rts_channel_lifetime_command_read(rdpRpc* rpc, STREAM* s);
void rts_channel_lifetime_command_write(STREAM* s, uint32 ChannelLifetime);
void rts_client_keepalive_command_read(rdpRpc* rpc, STREAM* s);
void rts_client_keepalive_command_write(STREAM* s, uint32 ClientKeepalive);
void rts_version_command_read(rdpRpc* rpc, STREAM* s);
void rts_version_command_write(STREAM* s);
void rts_empty_command_read(rdpRpc* rpc, STREAM* s);
void rts_empty_command_write(STREAM* s);
void rts_padding_command_read(rdpRpc* rpc, STREAM* s);
void rts_padding_command_write(STREAM* s, uint32 ConformanceCount);
void rts_negative_ance_command_read(rdpRpc* rpc, STREAM* s);
void rts_negative_ance_command_write(STREAM* s);
void rts_ance_command_read(rdpRpc* rpc, STREAM* s);
void rts_ance_command_write(STREAM* s);
void rts_client_address_command_read(rdpRpc* rpc, STREAM* s);
void rts_client_address_command_write(STREAM* s, uint32 AddressType, uint8* ClientAddress);
void rts_association_group_id_command_read(rdpRpc* rpc, STREAM* s);
void rts_association_group_id_command_write(STREAM* s, uint8* AssociationGroupId);
void rts_destination_command_read(rdpRpc* rpc, STREAM* s);
void rts_destination_command_write(STREAM* s, uint32 Destination);
void rts_ping_traffic_sent_notify_command_read(rdpRpc* rpc, STREAM* s);
void rts_ping_traffic_sent_notify_command_write(STREAM* s, uint32 PingTrafficSent);
boolean rts_send_CONN_A1_pdu(rdpRpc* rpc);
boolean rts_send_CONN_B1_pdu(rdpRpc* rpc);
boolean rts_send_keep_alive_pdu(rdpRpc* rpc);
boolean rts_send_flow_control_ack_pdu(rdpRpc* rpc);
boolean rts_send_ping_pdu(rdpRpc* rpc);
int rts_recv_pdu(rdpRpc* rpc, RTS_PDU* rts_pdu);
#ifdef WITH_DEBUG_TSG
#define WITH_DEBUG_RTS
#endif
#ifdef WITH_DEBUG_RTS
#define DEBUG_RTS(fmt, ...) DEBUG_CLASS(RTS, fmt, ## __VA_ARGS__)
#else
#define DEBUG_RTS(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
#endif
#endif /* FREERDP_CORE_RTS_H */

View File

@@ -21,7 +21,7 @@
#ifndef __TCP_H
#define __TCP_H
#include <freerdp/utils/windows.h>
#include <winpr/windows.h>
#include <freerdp/types.h>
#include <freerdp/settings.h>

View File

@@ -39,7 +39,7 @@
#include "fastpath.h"
#include "transport.h"
#include <freerdp/sspi/credssp.h>
#include <winpr/credssp.h>
#define BUFFER_SIZE 16384
@@ -59,11 +59,6 @@ STREAM* transport_send_stream_init(rdpTransport* transport, int size)
return s;
}
boolean transport_connect(rdpTransport* transport, const char* hostname, uint16 port)
{
return tcp_connect(transport->tcp, hostname, port);
}
void transport_attach(rdpTransport* transport, int sockfd)
{
transport->tcp->sockfd = sockfd;
@@ -143,6 +138,61 @@ boolean transport_connect_nla(rdpTransport* transport)
return true;
}
boolean transport_tsg_connect(rdpTransport* transport, const char* hostname, uint16 port)
{
rdpTsg* tsg = tsg_new(transport);
tsg->transport = transport;
transport->tsg = tsg;
if (transport->tls_in == NULL)
transport->tls_in = tls_new(transport->settings);
transport->tls_in->sockfd = transport->tcp_in->sockfd;
if (transport->tls_out == NULL)
transport->tls_out = tls_new(transport->settings);
transport->tls_out->sockfd = transport->tcp_out->sockfd;
if (tls_connect(transport->tls_in) != true)
return false;
if (tls_connect(transport->tls_out) != true)
return false;
if (!tsg_connect(tsg, hostname, port))
return false;
return true;
}
boolean transport_connect(rdpTransport* transport, const char* hostname, uint16 port)
{
boolean status = false;
rdpSettings* settings = transport->settings;
if (transport->settings->ts_gateway)
{
transport->layer = TRANSPORT_LAYER_TSG;
transport->tcp_out = tcp_new(settings);
status = tcp_connect(transport->tcp_in, settings->tsg_hostname, 443);
if (status)
status = tcp_connect(transport->tcp_out, settings->tsg_hostname, 443);
if (status)
status = transport_tsg_connect(transport, hostname, port);
}
else
{
status = tcp_connect(transport->tcp, hostname, port);
}
return status;
}
boolean transport_accept_rdp(rdpTransport* transport)
{
/* RDP encryption */
@@ -211,6 +261,8 @@ int transport_read(rdpTransport* transport, STREAM* s)
status = tls_read(transport->tls, stream_get_tail(s), stream_get_left(s));
else if (transport->layer == TRANSPORT_LAYER_TCP)
status = tcp_read(transport->tcp, stream_get_tail(s), stream_get_left(s));
else if (transport->layer == TRANSPORT_LAYER_TSG)
status = tsg_read(transport->tsg, stream_get_tail(s), stream_get_left(s));
if (status == 0 && transport->blocking)
{
@@ -269,6 +321,8 @@ int transport_write(rdpTransport* transport, STREAM* s)
status = tls_write(transport->tls, stream_get_tail(s), length);
else if (transport->layer == TRANSPORT_LAYER_TCP)
status = tcp_write(transport->tcp, stream_get_tail(s), length);
else if (transport->layer == TRANSPORT_LAYER_TSG)
status = tsg_write(transport->tsg, stream_get_tail(s), length);
if (status < 0)
break; /* error occurred */
@@ -424,6 +478,8 @@ rdpTransport* transport_new(rdpSettings* settings)
if (transport != NULL)
{
transport->tcp = tcp_new(settings);
transport->tcp_in = tcp_new(settings);
transport->settings = settings;
/* a small 0.1ms delay when transport is blocking. */
@@ -453,9 +509,13 @@ void transport_free(rdpTransport* transport)
stream_free(transport->recv_stream);
stream_free(transport->send_stream);
wait_obj_free(transport->recv_event);
if (transport->tls)
tls_free(transport->tls);
tcp_free(transport->tcp);
tsg_free(transport->tsg);
xfree(transport);
}
}

View File

@@ -24,14 +24,17 @@ typedef enum
{
TRANSPORT_LAYER_TCP,
TRANSPORT_LAYER_TLS,
TRANSPORT_LAYER_TSG,
TRANSPORT_LAYER_CLOSED
} TRANSPORT_LAYER;
typedef struct rdp_transport rdpTransport;
#include "tcp.h"
#include "tsg.h"
#include <winpr/sspi.h>
#include <freerdp/crypto/tls.h>
#include <freerdp/sspi/credssp.h>
#include <time.h>
#include <freerdp/types.h>
@@ -48,8 +51,13 @@ struct rdp_transport
TRANSPORT_LAYER layer;
struct rdp_tcp* tcp;
struct rdp_tls* tls;
struct rdp_settings* settings;
struct rdp_tsg* tsg;
struct rdp_tcp* tcp_in;
struct rdp_tcp* tcp_out;
struct rdp_tls* tls_in;
struct rdp_tls* tls_out;
struct rdp_credssp* credssp;
struct rdp_settings* settings;
uint32 usleep_interval;
void* recv_extra;
STREAM* recv_buffer;
@@ -67,6 +75,7 @@ boolean transport_disconnect(rdpTransport* transport);
boolean transport_connect_rdp(rdpTransport* transport);
boolean transport_connect_tls(rdpTransport* transport);
boolean transport_connect_nla(rdpTransport* transport);
boolean transport_connect_tsg(rdpTransport* transport);
boolean transport_accept_rdp(rdpTransport* transport);
boolean transport_accept_tls(rdpTransport* transport);
boolean transport_accept_nla(rdpTransport* transport);

2032
libfreerdp-core/tsg.c Normal file

File diff suppressed because it is too large Load Diff

279
libfreerdp-core/tsg.h Normal file
View File

@@ -0,0 +1,279 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* Terminal Server Gateway (TSG)
*
* Copyright 2012 Fujitsu Technology Solutions GmbH
* Copyright 2012 Dmitrij Jasnov <dmitrij.jasnov@ts.fujitsu.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 FREERDP_CORE_TSG_H
#define FREERDP_CORE_TSG_H
typedef struct rdp_tsg rdpTsg;
#include "rpc.h"
#include "transport.h"
#include <winpr/rpc.h>
#include <winpr/winpr.h>
#include <time.h>
#include <freerdp/types.h>
#include <freerdp/settings.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/wait_obj.h>
#include <freerdp/utils/debug.h>
struct rdp_tsg
{
rdpRpc* rpc;
rdpSettings* settings;
rdpTransport* transport;
uint8 TunnelContext[16];
uint8 ChannelContext[16];
};
typedef wchar_t* RESOURCENAME;
#define MAX_RESOURCE_NAMES 50
typedef struct _tsendpointinfo
{
RESOURCENAME* resourceName;
unsigned long numResourceNames;
RESOURCENAME* alternateResourceNames;
unsigned short numAlternateResourceNames;
unsigned long Port;
} TSENDPOINTINFO, *PTSENDPOINTINFO;
#define TSG_PACKET_TYPE_HEADER 0x00004844
#define TSG_PACKET_TYPE_VERSIONCAPS 0x00005643
#define TSG_PACKET_TYPE_QUARCONFIGREQUEST 0x00005143
#define TSG_PACKET_TYPE_QUARREQUEST 0x00005152
#define TSG_PACKET_TYPE_RESPONSE 0x00005052
#define TSG_PACKET_TYPE_QUARENC_RESPONSE 0x00004552
#define TSG_CAPABILITY_TYPE_NAP 0x00000001
#define TSG_PACKET_TYPE_CAPS_RESPONSE 0x00004350
#define TSG_PACKET_TYPE_MSGREQUEST_PACKET 0x00004752
#define TSG_PACKET_TYPE_MESSAGE_PACKET 0x00004750
#define TSG_PACKET_TYPE_AUTH 0x00004054
#define TSG_PACKET_TYPE_REAUTH 0x00005250
#define TSG_ASYNC_MESSAGE_CONSENT_MESSAGE 0x00000001
#define TSG_ASYNC_MESSAGE_SERVICE_MESSAGE 0x00000002
#define TSG_ASYNC_MESSAGE_REAUTH 0x00000003
#define TSG_TUNNEL_CALL_ASYNC_MSG_REQUEST 0x00000001
#define TSG_TUNNEL_CANCEL_ASYNC_MSG_REQUEST 0x00000002
#define TSG_NAP_CAPABILITY_QUAR_SOH 0x00000001
#define TSG_NAP_CAPABILITY_IDLE_TIMEOUT 0x00000002
#define TSG_MESSAGING_CAP_CONSENT_SIGN 0x00000004
#define TSG_MESSAGING_CAP_SERVICE_MSG 0x00000008
#define TSG_MESSAGING_CAP_REAUTH 0x00000010
typedef struct _TSG_PACKET_HEADER
{
unsigned short ComponentId;
unsigned short PacketId;
} TSG_PACKET_HEADER, *PTSG_PACKET_HEADER;
typedef struct _TSG_CAPABILITY_NAP
{
unsigned long capabilities;
} TSG_CAPABILITY_NAP, *PTSG_CAPABILITY_NAP;
typedef union
{
TSG_CAPABILITY_NAP tsgCapNap;
} TSG_CAPABILITIES_UNION, *PTSG_CAPABILITIES_UNION;
typedef struct _TSG_PACKET_CAPABILITIES
{
unsigned long capabilityType;
TSG_CAPABILITIES_UNION tsgPacket;
} TSG_PACKET_CAPABILITIES, *PTSG_PACKET_CAPABILITIES;
typedef struct _TSG_PACKET_VERSIONCAPS
{
TSG_PACKET_HEADER tsgHeader;
PTSG_PACKET_CAPABILITIES tsgCaps;
unsigned long numCapabilities;
unsigned short majorVersion;
unsigned short minorVersion;
unsigned short quarantineCapabilities;
} TSG_PACKET_VERSIONCAPS, *PTSG_PACKET_VERSIONCAPS;
typedef struct _TSG_PACKET_QUARCONFIGREQUEST
{
unsigned long flags;
} TSG_PACKET_QUARCONFIGREQUEST, *PTSG_PACKET_QUARCONFIGREQUEST;
typedef struct _TSG_PACKET_QUARREQUEST
{
unsigned long flags;
wchar_t* machineName;
unsigned long nameLength;
byte* data;
unsigned long dataLen;
} TSG_PACKET_QUARREQUEST, *PTSG_PACKET_QUARREQUEST;
typedef struct _TSG_REDIRECTION_FLAGS
{
BOOL enableAllRedirections;
BOOL disableAllRedirections;
BOOL driveRedirectionDisabled;
BOOL printerRedirectionDisabled;
BOOL portRedirectionDisabled;
BOOL reserved;
BOOL clipboardRedirectionDisabled;
BOOL pnpRedirectionDisabled;
} TSG_REDIRECTION_FLAGS, *PTSG_REDIRECTION_FLAGS;
typedef struct _TSG_PACKET_RESPONSE
{
unsigned long flags;
unsigned long reserved;
byte* responseData;
unsigned long responseDataLen;
TSG_REDIRECTION_FLAGS redirectionFlags;
} TSG_PACKET_RESPONSE, *PTSG_PACKET_RESPONSE;
typedef struct _TSG_PACKET_QUARENC_RESPONSE
{
unsigned long flags;
unsigned long certChainLen;
wchar_t* certChainData;
GUID nonce;
PTSG_PACKET_VERSIONCAPS versionCaps;
} TSG_PACKET_QUARENC_RESPONSE, *PTSG_PACKET_QUARENC_RESPONSE;
typedef struct TSG_PACKET_STRING_MESSAGE
{
long isDisplayMandatory;
long isConsentMandatory;
unsigned long msgBytes;
wchar_t* msgBuffer;
} TSG_PACKET_STRING_MESSAGE, *PTSG_PACKET_STRING_MESSAGE;
typedef struct TSG_PACKET_REAUTH_MESSAGE
{
unsigned __int64 tunnelContext;
} TSG_PACKET_REAUTH_MESSAGE, *PTSG_PACKET_REAUTH_MESSAGE;
typedef union
{
PTSG_PACKET_STRING_MESSAGE consentMessage;
PTSG_PACKET_STRING_MESSAGE serviceMessage;
PTSG_PACKET_REAUTH_MESSAGE reauthMessage;
} TSG_PACKET_TYPE_MESSAGE_UNION, *PTSG_PACKET_TYPE_MESSAGE_UNION;
typedef struct _TSG_PACKET_MSG_RESPONSE
{
unsigned long msgID;
unsigned long msgType;
long isMsgPresent;
TSG_PACKET_TYPE_MESSAGE_UNION messagePacket;
} TSG_PACKET_MSG_RESPONSE, *PTSG_PACKET_MSG_RESPONSE;
typedef struct TSG_PACKET_CAPS_RESPONSE
{
TSG_PACKET_QUARENC_RESPONSE pktQuarEncResponse;
TSG_PACKET_MSG_RESPONSE pktConsentMessage;
} TSG_PACKET_CAPS_RESPONSE, *PTSG_PACKET_CAPS_RESPONSE;
typedef struct TSG_PACKET_MSG_REQUEST
{
unsigned long maxMessagesPerBatch;
} TSG_PACKET_MSG_REQUEST, *PTSG_PACKET_MSG_REQUEST;
typedef struct _TSG_PACKET_AUTH
{
TSG_PACKET_VERSIONCAPS tsgVersionCaps;
unsigned long cookieLen;
byte* cookie;
} TSG_PACKET_AUTH, *PTSG_PACKET_AUTH;
typedef union
{
PTSG_PACKET_VERSIONCAPS packetVersionCaps;
PTSG_PACKET_AUTH packetAuth;
} TSG_INITIAL_PACKET_TYPE_UNION, *PTSG_INITIAL_PACKET_TYPE_UNION;
typedef struct TSG_PACKET_REAUTH
{
unsigned __int64 tunnelContext;
unsigned long packetId;
TSG_INITIAL_PACKET_TYPE_UNION tsgInitialPacket;
} TSG_PACKET_REAUTH, *PTSG_PACKET_REAUTH;
typedef union
{
PTSG_PACKET_HEADER packetHeader;
PTSG_PACKET_VERSIONCAPS packetVersionCaps;
PTSG_PACKET_QUARCONFIGREQUEST packetQuarConfigRequest;
PTSG_PACKET_QUARREQUEST packetQuarRequest;
PTSG_PACKET_RESPONSE packetResponse;
PTSG_PACKET_QUARENC_RESPONSE packetQuarEncResponse;
PTSG_PACKET_CAPS_RESPONSE packetCapsResponse;
PTSG_PACKET_MSG_REQUEST packetMsgRequest;
PTSG_PACKET_MSG_RESPONSE packetMsgResponse;
PTSG_PACKET_AUTH packetAuth;
PTSG_PACKET_REAUTH packetReauth;
} TSG_PACKET_TYPE_UNION;
typedef struct _TSG_PACKET
{
unsigned long packetId;
TSG_PACKET_TYPE_UNION tsgPacket;
} TSG_PACKET, *PTSG_PACKET;
void Opnum0NotUsedOnWire(handle_t IDL_handle);
HRESULT TsProxyCreateTunnel(PTSG_PACKET tsgPacket, PTSG_PACKET* tsgPacketResponse,
PTUNNEL_CONTEXT_HANDLE_SERIALIZE* tunnelContext, unsigned long* tunnelId);
HRESULT TsProxyAuthorizeTunnel(PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext,
PTSG_PACKET tsgPacket, PTSG_PACKET* tsgPacketResponse);
HRESULT TsProxyMakeTunnelCall(PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext,
unsigned long procId, PTSG_PACKET tsgPacket, PTSG_PACKET* tsgPacketResponse);
HRESULT TsProxyCreateChannel(PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext,
PTSENDPOINTINFO tsEndPointInfo, PCHANNEL_CONTEXT_HANDLE_SERIALIZE* channelContext, unsigned long* channelId);
void Opnum5NotUsedOnWire(handle_t IDL_handle);
HRESULT TsProxyCloseChannel(PCHANNEL_CONTEXT_HANDLE_NOSERIALIZE* context);
HRESULT TsProxyCloseTunnel(PTUNNEL_CONTEXT_HANDLE_SERIALIZE* context);
DWORD TsProxySetupReceivePipe(handle_t IDL_handle, byte pRpcMessage[]);
DWORD TsProxySendToServer(handle_t IDL_handle, byte pRpcMessage[], uint32 count, uint32* lengths);
boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port);
int tsg_write(rdpTsg* tsg, uint8* data, uint32 length);
int tsg_read(rdpTsg* tsg, uint8* data, uint32 length);
rdpTsg* tsg_new(rdpTransport* transport);
void tsg_free(rdpTsg* tsg);
#ifdef WITH_DEBUG_TSG
#define DEBUG_TSG(fmt, ...) DEBUG_CLASS(TSG, fmt, ## __VA_ARGS__)
#else
#define DEBUG_TSG(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
#endif
#endif /* FREERDP_CORE_TSG_H */

View File

@@ -511,3 +511,46 @@ void crypto_cert_print_info(X509* xcert)
xfree(fp);
}
char* crypto_base64_encode(uint8* data, int length)
{
BIO* bmem;
BIO* b64;
BUF_MEM *bptr;
char* base64_string;
b64 = BIO_new(BIO_f_base64());
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
bmem = BIO_new(BIO_s_mem());
b64 = BIO_push(b64, bmem);
BIO_write(b64, data, length);
if (BIO_flush(b64) < 1)
return NULL;
BIO_get_mem_ptr(b64, &bptr);
base64_string = xmalloc(bptr->length);
memcpy(base64_string, bptr->data, bptr->length - 1);
base64_string[bptr->length - 1] = '\0';
BIO_free_all(b64);
return base64_string;
}
void crypto_base64_decode(uint8* enc_data, int length, uint8** dec_data, int* res_length)
{
BIO *b64, *bmem;
*dec_data = xmalloc(length);
memset(*dec_data, 0, length);
b64 = BIO_new(BIO_f_base64());
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
bmem = BIO_new_mem_buf(enc_data, length);
bmem = BIO_push(b64, bmem);
*res_length = BIO_read(bmem, *dec_data, length);
BIO_free_all(bmem);
}

View File

@@ -255,6 +255,30 @@ int tls_write(rdpTls* tls, uint8* data, int length)
return status;
}
int tls_write_all(rdpTls* tls, uint8* data, int length)
{
int status;
int sent = 0;
do
{
status = tls_write(tls, &data[sent], length - sent);
if (status > 0)
sent += status;
if (sent >= length)
break;
}
while (status >= 0);
if (status > 0)
return length;
else
return status;
}
static void tls_errors(const char *prefix)
{
unsigned long error;

View File

@@ -17,11 +17,11 @@
* limitations under the License.
*/
#include <winpr/windows.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/hexdump.h>
#include <freerdp/utils/unicode.h>
#include <freerdp/utils/windows.h>
#include "librail.h"

View File

@@ -102,11 +102,12 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv,
" --ignore-certificate: ignore verification of logon certificate\n"
" --certificate-name: use this name for the logon certificate, instead of the server name\n"
" --sec: force protocol security (rdp, tls or nla)\n"
" --tsg: Terminal Server Gateway (<username> <password> <hostname>)\n"
" --kbd-list: list all keyboard layout ids used by -k\n"
" --no-salted-checksum: disable salted checksums with Standard RDP encryption\n"
" --version: print version information\n"
"\n", argv[0]);
return FREERDP_ARGS_PARSE_HELP; //TODO: What is the correct return
return FREERDP_ARGS_PARSE_HELP; /* TODO: What is the correct return? */
}
else if (strcmp("-a", argv[index]) == 0)
{
@@ -534,6 +535,31 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv,
return FREERDP_ARGS_PARSE_FAILURE;
}
}
else if (strcmp("--tsg", argv[index]) == 0)
{
settings->ts_gateway = true;
index++;
if (index == argc)
{
printf("missing TSG username\n");
return -1;
}
settings->tsg_username = xstrdup(argv[index]);
index++;
if (index == argc)
{
printf("missing TSG password\n");
return -1;
}
settings->tsg_password = xstrdup(argv[index]);
index++;
if (index == argc)
{
printf("missing TSG server\n");
return -1;
}
settings->tsg_hostname = xstrdup(argv[index]);
}
else if (strcmp("--plugin", argv[index]) == 0)
{
index++;

View File

@@ -34,8 +34,8 @@
#define getcwd _getcwd
#endif
#include <winpr/windows.h>
#include <freerdp/utils/file.h>
#include <freerdp/utils/windows.h>
#ifndef _WIN32
#define PATH_SEPARATOR_STR "/"

View File

@@ -22,11 +22,11 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winpr/windows.h>
#include <freerdp/utils/file.h>
#include <freerdp/utils/print.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/load_plugin.h>
#include <freerdp/utils/windows.h>
#ifdef _WIN32

View File

@@ -17,9 +17,9 @@
* limitations under the License.
*/
#include <winpr/windows.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/mutex.h>
#include <freerdp/utils/windows.h>
#ifdef _WIN32
#define freerdp_mutex_t HANDLE

View File

@@ -17,9 +17,9 @@
* limitations under the License.
*/
#include <winpr/windows.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/semaphore.h>
#include <freerdp/utils/windows.h>
#if defined __APPLE__

View File

@@ -17,8 +17,8 @@
* limitations under the License.
*/
#include <winpr/windows.h>
#include <freerdp/utils/sleep.h>
#include <freerdp/utils/windows.h>
#include <time.h>

View File

@@ -45,7 +45,7 @@
#else /* ifdef _WIN32 */
#include <freerdp/utils/windows.h>
#include <winpr/windows.h>
#define SHUT_RDWR SD_BOTH
#define close(_fd) closesocket(_fd)
#endif

View File

@@ -22,7 +22,7 @@
#include <string.h>
#include <time.h>
#include <freerdp/utils/windows.h>
#include <winpr/windows.h>
#ifdef _WIN32
#ifdef _MSC_VER

View File

@@ -17,8 +17,8 @@
* limitations under the License.
*/
#include <winpr/windows.h>
#include <freerdp/utils/time.h>
#include <freerdp/utils/windows.h>
uint64 freerdp_windows_gmtime()
{

View File

@@ -98,7 +98,7 @@ char* freerdp_uniconv_in(UNICONV* uniconv, unsigned char* pin, size_t in_len)
/* Convert str from DEFAULT_CODEPAGE to WINDOWS_CODEPAGE and return buffer like xstrdup.
* Buffer is 0-terminated but that is not included in the returned length. */
char* freerdp_uniconv_out(UNICONV *uniconv, char *str, size_t *pout_len)
char* freerdp_uniconv_out(UNICONV* uniconv, const char *str, size_t* pout_len)
{
size_t ibl;
size_t obl;
@@ -114,7 +114,7 @@ char* freerdp_uniconv_out(UNICONV *uniconv, char *str, size_t *pout_len)
ibl = strlen(str);
obl = 2 * ibl;
pin = str;
pin = (char*) str;
pout0 = xmalloc(obl + 2);
pout = pout0;

View File

@@ -18,12 +18,13 @@
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winpr/windows.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/wait_obj.h>
#include <freerdp/utils/windows.h>
#ifndef _WIN32
#include <sys/time.h>

View File

@@ -0,0 +1,49 @@
# WinPR: Windows Portable Runtime
# libwinpr-rpc 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_RPC_SRCS
rpc.c
ndr.c
ndr_array.c ndr_array.h
ndr_context.c ndr_context.h
ndr_correlation.c ndr_correlation.h
ndr_pointer.c ndr_pointer.h
ndr_private.c ndr_private.h
ndr_simple.c ndr_simple.h
ndr_string.c ndr_string.h
ndr_structure.c ndr_structure.h
ndr_union.c ndr_union.h
midl.c)
add_library(winpr-rpc ${WINPR_RPC_SRCS})
include_directories(${OPENSSL_INCLUDE_DIR})
include_directories(${ZLIB_INCLUDE_DIRS})
set_target_properties(winpr-rpc PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib")
if(WIN32)
target_link_libraries(winpr-rpc ws2_32)
else()
target_link_libraries(winpr-rpc ${ZLIB_LIBRARIES})
endif()
target_link_libraries(winpr-rpc ${OPENSSL_LIBRARIES})
install(TARGETS winpr-rpc DESTINATION ${CMAKE_INSTALL_LIBDIR})

33
libwinpr-rpc/midl.c Normal file
View File

@@ -0,0 +1,33 @@
/**
* WinPR: Windows Portable Runtime
* Microsoft Remote Procedure Call (MSRPC)
*
* 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 <winpr/midl.h>
void* MIDL_user_allocate(size_t cBytes)
{
return (malloc(cBytes));
}
void MIDL_user_free(void* p)
{
free(p);
}

342
libwinpr-rpc/ndr.c Normal file
View File

@@ -0,0 +1,342 @@
/**
* WinPR: Windows Portable Runtime
* Network Data Representation (NDR)
*
* 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 <stdarg.h>
#include <winpr/ndr.h>
#include "ndr_array.h"
#include "ndr_context.h"
#include "ndr_pointer.h"
#include "ndr_simple.h"
#include "ndr_string.h"
#include "ndr_structure.h"
#include "ndr_union.h"
#include "ndr_private.h"
/**
* MSRPC NDR Types Technical Overview:
* http://dvlabs.tippingpoint.com/blog/2007/11/24/msrpc-ndr-types/
*/
void NdrPrintParamAttributes(PARAM_ATTRIBUTES attributes)
{
if (attributes.ServerAllocSize)
printf("ServerAllocSize, ");
if (attributes.SaveForAsyncFinish)
printf("SaveForAsyncFinish, ");
if (attributes.IsDontCallFreeInst)
printf("IsDontCallFreeInst, ");
if (attributes.IsSimpleRef)
printf("IsSimpleRef, ");
if (attributes.IsByValue)
printf("IsByValue, ");
if (attributes.IsBasetype)
printf("IsBaseType, ");
if (attributes.IsReturn)
printf("IsReturn, ");
if (attributes.IsOut)
printf("IsOut, ");
if (attributes.IsIn)
printf("IsIn, ");
if (attributes.IsPipe)
printf("IsPipe, ");
if (attributes.MustFree)
printf("MustFree, ");
if (attributes.MustSize)
printf("MustSize, ");
}
void NdrProcessParam(PMIDL_STUB_MESSAGE pStubMsg, NDR_PHASE phase, unsigned char* pMemory, NDR_PARAM* param)
{
unsigned char type;
PFORMAT_STRING pFormat;
/* Parameter Descriptors: http://msdn.microsoft.com/en-us/library/windows/desktop/aa374362/ */
if (param->Attributes.IsBasetype)
{
pFormat = &param->Type.FormatChar;
if (param->Attributes.IsSimpleRef)
pMemory = *(unsigned char**) pMemory;
}
else
{
pFormat = &pStubMsg->StubDesc->pFormatTypes[param->Type.Offset];
if (!(param->Attributes.IsByValue))
pMemory = *(unsigned char**) pMemory;
}
type = (pFormat[0] & 0x7F);
if (type > FC_PAD)
return;
if (phase == NDR_PHASE_SIZE)
{
NDR_TYPE_SIZE_ROUTINE pfnSizeRoutine = pfnSizeRoutines[type];
if (pfnSizeRoutine)
pfnSizeRoutine(pStubMsg, pMemory, pFormat);
}
else if (phase == NDR_PHASE_MARSHALL)
{
NDR_TYPE_MARSHALL_ROUTINE pfnMarshallRoutine = pfnMarshallRoutines[type];
if (pfnMarshallRoutine)
pfnMarshallRoutine(pStubMsg, pMemory, *pFormat);
}
else if (phase == NDR_PHASE_UNMARSHALL)
{
NDR_TYPE_UNMARSHALL_ROUTINE pfnUnmarshallRoutine = pfnUnmarshallRoutines[type];
if (pfnUnmarshallRoutine)
pfnUnmarshallRoutine(pStubMsg, pMemory, *pFormat);
}
else if (phase == NDR_PHASE_FREE)
{
NDR_TYPE_FREE_ROUTINE pfnFreeRoutine = pfnFreeRoutines[type];
if (pfnFreeRoutine)
pfnFreeRoutine(pStubMsg, pMemory, pFormat);
}
}
void NdrProcessParams(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, NDR_PHASE phase, void** fpuArgs, unsigned short numberParams)
{
unsigned int i;
NDR_PARAM* params;
PFORMAT_STRING fmt;
unsigned char* arg;
unsigned char type;
params = (NDR_PARAM*) pFormat;
printf("Params = \n{\n");
for (i = 0; i < numberParams; i++)
{
arg = pStubMsg->StackTop + params[i].StackOffset;
fmt = (PFORMAT_STRING) &pStubMsg->StubDesc->pFormatTypes[params[i].Type.Offset];
#ifdef __x86_64__
if ((params[i].Attributes.IsBasetype) &&
!(params[i].Attributes.IsSimpleRef) &&
((params[i].Type.FormatChar) == FC_FLOAT) && !fpuArgs)
{
float tmp = *(double*) arg;
arg = (unsigned char*) &tmp;
}
#endif
printf("\t#%d\t", i);
type = (params[i].Attributes.IsBasetype) ? params[i].Type.FormatChar : *fmt;
printf(" type %s (0x%02X) ", FC_TYPE_STRINGS[type], type);
NdrPrintParamAttributes(params[i].Attributes);
if (params[i].Attributes.IsIn)
{
NdrProcessParam(pStubMsg, phase, arg, &params[i]);
}
printf("\n");
}
printf("}\n");
}
void NdrClientInitializeNew(PRPC_MESSAGE pRpcMessage, PMIDL_STUB_MESSAGE pStubMsg,
PMIDL_STUB_DESC pStubDesc, unsigned int ProcNum)
{
pRpcMessage->Handle = NULL;
pRpcMessage->RpcFlags = 0;
pRpcMessage->ProcNum = ProcNum;
pRpcMessage->DataRepresentation = 0;
pRpcMessage->ReservedForRuntime = NULL;
pRpcMessage->RpcInterfaceInformation = pStubDesc->RpcInterfaceInformation;
pStubMsg->RpcMsg = pRpcMessage;
pStubMsg->BufferStart = NULL;
pStubMsg->BufferEnd = NULL;
pStubMsg->BufferLength = 0;
pStubMsg->StackTop = NULL;
pStubMsg->StubDesc = pStubDesc;
pStubMsg->IgnoreEmbeddedPointers = 0;
pStubMsg->PointerLength = 0;
}
void NdrPrintOptFlags(INTERPRETER_OPT_FLAGS optFlags)
{
if (optFlags.ClientMustSize)
printf("ClientMustSize, ");
if (optFlags.ServerMustSize)
printf("ServerMustSize, ");
if (optFlags.HasAsyncUuid)
printf("HasAsyncUiid, ");
if (optFlags.HasAsyncHandle)
printf("HasAsyncHandle, ");
if (optFlags.HasReturn)
printf("HasReturn, ");
if (optFlags.HasPipes)
printf("HasPipes, ");
if (optFlags.HasExtensions)
printf("HasExtensions, ");
}
void NdrPrintExtFlags(INTERPRETER_OPT_FLAGS2 extFlags)
{
if (extFlags.HasNewCorrDesc)
printf("HasNewCorrDesc, ");
if (extFlags.ClientCorrCheck)
printf("ClientCorrCheck, ");
if (extFlags.ServerCorrCheck)
printf("ServerCorrCheck, ");
if (extFlags.HasNotify)
printf("HasNotify, ");
if (extFlags.HasNotify2)
printf("HasNotify2, ");
}
CLIENT_CALL_RETURN NdrClientCall(PMIDL_STUB_DESC pStubDescriptor, PFORMAT_STRING pFormat, void** stackTop, void** fpuStack)
{
RPC_MESSAGE rpcMsg;
unsigned short procNum;
unsigned short stackSize;
unsigned char numberParams;
unsigned char handleType;
MIDL_STUB_MESSAGE stubMsg;
INTERPRETER_FLAGS flags;
INTERPRETER_OPT_FLAGS optFlags;
INTERPRETER_OPT_FLAGS2 extFlags;
NDR_PROC_HEADER* procHeader;
NDR_OI2_PROC_HEADER* oi2ProcHeader;
CLIENT_CALL_RETURN client_call_return;
procNum = stackSize = numberParams = 0;
procHeader = (NDR_PROC_HEADER*) &pFormat[0];
client_call_return.Pointer = NULL;
handleType = procHeader->HandleType;
flags = procHeader->OldOiFlags;
procNum = procHeader->ProcNum;
stackSize = procHeader->StackSize;
pFormat += sizeof(NDR_PROC_HEADER);
/* The Header: http://msdn.microsoft.com/en-us/library/windows/desktop/aa378707/ */
/* Procedure Header Descriptor: http://msdn.microsoft.com/en-us/library/windows/desktop/aa374387/ */
/* Handles: http://msdn.microsoft.com/en-us/library/windows/desktop/aa373932/ */
printf("Oi Header: HandleType: 0x%02X OiFlags: 0x%02X ProcNum: %d StackSize: 0x%04X\n",
handleType, *((unsigned char*) &flags),
(unsigned short) procNum, (unsigned short) stackSize);
if (handleType > 0)
{
/* implicit handle */
printf("Implicit Handle\n");
oi2ProcHeader = (NDR_OI2_PROC_HEADER*) &pFormat[0];
pFormat += sizeof(NDR_OI2_PROC_HEADER);
}
else
{
/* explicit handle */
printf("Explicit Handle\n");
oi2ProcHeader = (NDR_OI2_PROC_HEADER*) &pFormat[6];
pFormat += sizeof(NDR_OI2_PROC_HEADER) + 6;
}
optFlags = oi2ProcHeader->Oi2Flags;
numberParams = oi2ProcHeader->NumberParams;
printf("Oi2 Header: Oi2Flags: 0x%02X, NumberParams: %d ClientBufferSize: %d ServerBufferSize: %d\n",
*((unsigned char*) &optFlags),
(unsigned char) numberParams,
oi2ProcHeader->ClientBufferSize,
oi2ProcHeader->ServerBufferSize);
printf("Oi2Flags: ");
NdrPrintOptFlags(optFlags);
printf("\n");
NdrClientInitializeNew(&rpcMsg, &stubMsg, pStubDescriptor, procNum);
if (optFlags.HasExtensions)
{
NDR_PROC_HEADER_EXTS* extensions = (NDR_PROC_HEADER_EXTS*) pFormat;
pFormat += extensions->Size;
extFlags = extensions->Flags2;
printf("Extensions: Size: %d, flags2: 0x%02X\n",
extensions->Size, *((unsigned char*) &extensions->Flags2));
#ifdef __x86_64__
if (extensions->Size > sizeof(*extensions) && fpuStack)
{
int i;
unsigned short fpuMask = *(unsigned short*) (extensions + 1);
for (i = 0; i < 4; i++, fpuMask >>= 2)
{
switch (fpuMask & 3)
{
case 1: *(float*) &stackTop[i] = *(float*) &fpuStack[i];
break;
case 2: *(double*) &stackTop[i] = *(double*) &fpuStack[i];
break;
}
}
}
#endif
}
stubMsg.StackTop = (unsigned char*) stackTop;
printf("ExtFlags: ");
NdrPrintExtFlags(extFlags);
printf("\n");
NdrProcessParams(&stubMsg, pFormat, NDR_PHASE_SIZE, fpuStack, numberParams);
printf("stubMsg BufferLength: %d\n", (int) stubMsg.BufferLength);
return client_call_return;
}
CLIENT_CALL_RETURN NdrClientCall2(PMIDL_STUB_DESC pStubDescriptor, PFORMAT_STRING pFormat, ...)
{
va_list args;
CLIENT_CALL_RETURN client_call_return;
va_start(args, pFormat);
client_call_return = NdrClientCall(pStubDescriptor, pFormat, va_arg(args, void**), NULL);
va_end(args);
return client_call_return;
}

137
libwinpr-rpc/ndr_array.c Normal file
View File

@@ -0,0 +1,137 @@
/**
* WinPR: Windows Portable Runtime
* Microsoft Remote Procedure Call (MSRPC)
*
* 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 <winpr/rpc.h>
#include "ndr_array.h"
void NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
{
/**
* FC_CARRAY
* alignment<1>
* element_size<2>
* conformance_description<>
* [pointer_layout<>]
* element_description<>
* FC_END
*/
unsigned char type;
unsigned char alignment;
unsigned short element_size;
type = pFormat[0];
alignment = pFormat[1] + 1;
element_size = *(unsigned short*) &pFormat[2];
if (type != FC_CARRAY)
{
printf("error: expected FC_CARRAY, got 0x%02X\n", type);
return;
}
printf("warning: NdrConformantArrayBufferSize unimplemented\n");
}
void NdrConformantVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
{
/**
* FC_CVARRAY
* alignment<1>
* element_size<2>
* conformance_description<>
* variance_description<>
* [pointer_layout<>]
* element_description<>
* FC_END
*/
printf("warning: NdrConformantVaryingArrayBufferSize unimplemented\n");
}
void NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
{
/**
* FC_SMFARRAY
* alignment<1>
* total_size<2>
* [pointer_layout<>]
* element_description<>
* FC_END
*/
/**
* FC_LGFARRAY
* alignment<1>
* total_size<4>
* [pointer_layout<>]
* element_description<>
* FC_END
*/
printf("warning: NdrFixedArrayBufferSize unimplemented\n");
}
void NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
{
/**
* FC_SMVARRAY
* alignment<1>
* total_size<2>
* number_elements<2>
* element_size<2>
* variance_description<>
* [pointer_layout<>]
* element_description<>
* FC_END
*/
/**
* FC_LGVARRAY
* alignment<1>
* total_size<4>
* number_elements<4>
* element_size<2>
* variance_description<4>
* [pointer_layout<>]
* element_description<>
* FC_END
*/
printf("warning: NdrVaryingArrayBufferSize unimplemented\n");
}
void NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
{
/**
* FC_BOGUS_ARRAY
* alignment<1>
* number_of_elements<2>
* conformance_description<>
* variance_description<>
* element_description<>
* FC_END
*/
printf("warning: NdrComplexArrayBufferSize unimplemented\n");
}

31
libwinpr-rpc/ndr_array.h Normal file
View File

@@ -0,0 +1,31 @@
/**
* WinPR: Windows Portable Runtime
* Microsoft Remote Procedure Call (MSRPC)
*
* 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_RPC_NDR_ARRAY_H
#define WINPR_RPC_NDR_ARRAY_H
#include <winpr/rpc.h>
void NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat);
void NdrConformantVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat);
void NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat);
void NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat);
void NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat);
#endif /* WINPR_RPC_NDR_ARRAY_H */

View File

@@ -0,0 +1,66 @@
/**
* WinPR: Windows Portable Runtime
* Microsoft Remote Procedure Call (MSRPC)
*
* 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 <winpr/rpc.h>
#include "ndr_context.h"
#include "ndr_private.h"
void NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
{
unsigned char type = *pFormat;
if (type == FC_BIND_PRIMITIVE)
{
/**
* FC_BIND_PRIMITIVE
* flag<1>
* offset<2>
*/
printf("warning: NdrContextHandleBufferSize FC_BIND_PRIMITIVE unimplemented\n");
}
else if (type == FC_BIND_GENERIC)
{
/**
* FC_BIND_GENERIC
* flag_and_size<1>
* offset<2>
* binding_routine_pair_index<1>
* FC_PAD
*/
printf("warning: NdrContextHandleBufferSize FC_BIND_GENERIC unimplemented\n");
}
else if (type == FC_BIND_CONTEXT)
{
/**
* FC_BIND_CONTEXT
* flags<1>
* offset<2>
* context_rundown_routine_index<1>
* param_num<1>
*/
NdrpAlignLength(&(pStubMsg->BufferLength), 4);
NdrpIncrementLength(&(pStubMsg->BufferLength), 20);
}
}

View File

@@ -0,0 +1,27 @@
/**
* WinPR: Windows Portable Runtime
* Microsoft Remote Procedure Call (MSRPC)
*
* 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_RPC_NDR_CONTEXT_H
#define WINPR_RPC_NDR_CONTEXT_H
#include <winpr/rpc.h>
void NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat);
#endif /* WINPR_RPC_NDR_CONTEXT_H */

View File

@@ -0,0 +1,187 @@
/**
* WinPR: Windows Portable Runtime
* Microsoft Remote Procedure Call (MSRPC)
*
* 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 <winpr/rpc.h>
#include "ndr_correlation.h"
#include "ndr_private.h"
/*
* Correlation Descriptors: http://msdn.microsoft.com/en-us/library/windows/desktop/aa373607/
*
* correlation_type<1>
* correlation_operator<1>
* offset<2>
* [robust_flags<2>]
*
*/
PFORMAT_STRING NdrpComputeCount(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat, ULONG_PTR* pCount)
{
LPVOID ptr = NULL;
ULONG_PTR data = 0;
unsigned char type;
unsigned short offset;
unsigned char conformance;
unsigned char correlation_type;
unsigned char correlation_operator;
correlation_type = pFormat[0];
type = correlation_type & 0x0F;
conformance = correlation_type & 0xF0;
correlation_operator = pFormat[1];
offset = *(unsigned short*) & pFormat[2];
if (conformance == FC_NORMAL_CONFORMANCE)
{
ptr = pMemory;
}
else if (conformance == FC_POINTER_CONFORMANCE)
{
ptr = pStubMsg->Memory;
}
else if (conformance == FC_TOP_LEVEL_CONFORMANCE)
{
ptr = pStubMsg->StackTop;
}
else if (conformance == FC_CONSTANT_CONFORMANCE )
{
data = offset | ((DWORD) pFormat[1] << 16);
*pCount = data;
}
else if (conformance == FC_TOP_LEVEL_MULTID_CONFORMANCE)
{
if (pStubMsg->StackTop)
ptr = pStubMsg->StackTop;
}
switch (correlation_operator)
{
case FC_DEREFERENCE:
ptr = *(LPVOID*)((char*) ptr + offset);
break;
case FC_DIV_2:
ptr = (char*) ptr + offset;
break;
case FC_MULT_2:
ptr = (char*) ptr + offset;
break;
case FC_SUB_1:
ptr = (char*) ptr + offset;
break;
case FC_ADD_1:
ptr = (char*) ptr + offset;
break;
case FC_CALLBACK:
{
printf("warning: NdrpComputeConformance FC_CALLBACK unimplemented\n");
}
break;
}
switch (type)
{
case FC_LONG:
data = *(LONG*) ptr;
break;
case FC_ULONG:
data = *(ULONG*) ptr;
break;
case FC_SHORT:
data = *(SHORT*) ptr;
break;
case FC_USHORT:
data = *(USHORT*) ptr;
break;
case FC_CHAR:
case FC_SMALL:
data = *(CHAR*) ptr;
break;
case FC_BYTE:
case FC_USMALL:
data = *(BYTE*) ptr;
break;
case FC_HYPER:
data = (ULONG_PTR) *(ULONGLONG*) ptr;
break;
}
switch (correlation_operator)
{
case FC_ZERO:
case FC_DEREFERENCE:
*pCount = data;
break;
case FC_DIV_2:
*pCount = data / 1;
break;
case FC_MULT_2:
*pCount = data * 1;
break;
case FC_SUB_1:
*pCount = data - 1;
break;
case FC_ADD_1:
*pCount = data + 1;
break;
case FC_CALLBACK:
break;
}
if (pStubMsg->fHasNewCorrDesc)
pFormat += 6;
else
pFormat += 4;
return pFormat;
}
PFORMAT_STRING NdrpComputeConformance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
{
return NdrpComputeCount(pStubMsg, pMemory, pFormat, &pStubMsg->MaxCount);
}
PFORMAT_STRING NdrpComputeVariance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
{
ULONG_PTR ActualCount = pStubMsg->ActualCount;
pFormat = NdrpComputeCount(pStubMsg, pMemory, pFormat, &ActualCount);
pStubMsg->ActualCount = (ULONG) ActualCount;
return pFormat;
}

View File

@@ -0,0 +1,29 @@
/**
* WinPR: Windows Portable Runtime
* Microsoft Remote Procedure Call (MSRPC)
*
* 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_RPC_NDR_CORRELATION_H
#define WINPR_RPC_NDR_CORRELATION_H
#include <winpr/rpc.h>
PFORMAT_STRING NdrpComputeCount(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat, ULONG_PTR* pCount);
PFORMAT_STRING NdrpComputeConformance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat);
PFORMAT_STRING NdrpComputeVariance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat);
#endif /* WINPR_RPC_NDR_CORRELATION_H */

322
libwinpr-rpc/ndr_pointer.c Normal file
View File

@@ -0,0 +1,322 @@
/**
* WinPR: Windows Portable Runtime
* Microsoft Remote Procedure Call (MSRPC)
*
* 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 <winpr/rpc.h>
#include "ndr_pointer.h"
#include "ndr_private.h"
/**
* Pointer Layout: http://msdn.microsoft.com/en-us/library/windows/desktop/aa374376/
*
* pointer_layout<>:
*
* FC_PP
* FC_PAD
* { pointer_instance_layout<> }*
* FC_END
*
* pointer_instance<8>:
*
* offset_to_pointer_in_memory<2>
* offset_to_pointer_in_buffer<2>
* pointer_description<4>
*
*/
PFORMAT_STRING NdrpSkipPointerLayout(PFORMAT_STRING pFormat)
{
pFormat += 2;
while (*pFormat != FC_END)
{
if (*pFormat == FC_NO_REPEAT)
{
/**
* FC_NO_REPEAT
* FC_PAD
* pointer_instance<8>
*/
pFormat += 10;
}
else if (*pFormat == FC_FIXED_REPEAT)
{
unsigned short number_of_pointers;
/**
* FC_FIXED_REPEAT
* FC_PAD
* iterations<2>
* increment<2>
* offset_to_array<2>
* number_of_pointers<2>
* { pointer_instance<8> }*
*/
pFormat += 8;
number_of_pointers = *(unsigned short*) pFormat;
pFormat += 2 + (number_of_pointers * 8);
}
else if (*pFormat == FC_VARIABLE_REPEAT)
{
unsigned short number_of_pointers;
/**
* FC_VARIABLE_REPEAT (FC_FIXED_OFFSET | FC_VARIABLE_OFFSET)
* FC_PAD ?!
* increment<2>
* offset_to_array<2>
* number_of_pointers<2>
* { pointer_instance<8> }*
*/
pFormat += 6;
number_of_pointers = *(unsigned short*) pFormat;
pFormat += 2 + (number_of_pointers * 8);
}
else
{
printf("error: NdrpSkipPointerLayout unexpected 0x%02X\n", *pFormat);
break;
}
}
return pFormat + 1;
}
/* Pointers: http://msdn.microsoft.com/en-us/library/windows/desktop/hh802750/ */
/**
* pointer_type<1>
* pointer_attributes<1>
* simple_type<1>
* FC_PAD
*/
/**
* pointer_type<1>
* pointer_attributes<1>
* offset_to_complex_description<2>
*/
void NdrpPointerBufferSize(unsigned char* pMemory, PFORMAT_STRING pFormat, PMIDL_STUB_MESSAGE pStubMsg)
{
unsigned char type;
unsigned char attributes;
PFORMAT_STRING pNextFormat;
NDR_TYPE_SIZE_ROUTINE pfnSizeRoutine;
type = pFormat[0];
attributes = pFormat[1];
pFormat += 2;
if (attributes & FC_SIMPLE_POINTER)
pNextFormat = pFormat;
else
pNextFormat = pFormat + *(SHORT*) pFormat;
switch (type)
{
case FC_RP: /* Reference Pointer */
break;
case FC_UP: /* Unique Pointer */
case FC_OP: /* Unique Pointer in an object interface */
if (!pMemory)
return;
break;
case FC_FP: /* Full Pointer */
printf("warning: FC_FP unimplemented\n");
break;
}
if (attributes & FC_POINTER_DEREF)
pMemory = *(unsigned char**) pMemory;
pfnSizeRoutine = pfnSizeRoutines[*pNextFormat];
if (pfnSizeRoutine)
pfnSizeRoutine(pStubMsg, pMemory, pNextFormat);
}
PFORMAT_STRING NdrpEmbeddedRepeatPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat, unsigned char** ppMemory)
{
ULONG_PTR MaxCount;
unsigned char* Memory;
unsigned char* MemoryCopy;
unsigned char* MemoryPointer;
PFORMAT_STRING pFormatNext;
PFORMAT_STRING pFormatPointers;
unsigned short increment;
unsigned short pointer_count;
unsigned short offset_to_array;
unsigned short number_of_pointers;
Memory = pStubMsg->Memory;
MemoryCopy = pStubMsg->Memory;
if (*pFormat == FC_FIXED_REPEAT)
{
pFormat += 2;
MaxCount = *(unsigned short*) pFormat;
}
else
{
if (*pFormat != FC_VARIABLE_REPEAT)
{
RpcRaiseException(1766);
return pFormat;
}
MaxCount = pStubMsg->MaxCount;
if (pFormat[1] == FC_VARIABLE_OFFSET)
{
pMemory += pStubMsg->Offset * *((unsigned short*) &pFormat[1]);
}
}
pFormat += 2;
increment = *(unsigned short*) pFormat;
pFormat += 2;
offset_to_array = *(unsigned short*) pFormat;
pStubMsg->Memory = Memory + offset_to_array;
pFormat += 2;
number_of_pointers = *(unsigned short*) pFormat;
pFormat += 2;
pFormatPointers = pFormat;
if (MaxCount)
{
do
{
MaxCount--;
pFormatNext = pFormatPointers;
pointer_count = number_of_pointers;
if (number_of_pointers)
{
do
{
pointer_count--;
MemoryPointer = &pMemory[*(unsigned short*) pFormatNext];
NdrpPointerBufferSize(MemoryPointer, pFormatNext + 4, pStubMsg);
pFormatNext += 8;
}
while (pointer_count);
}
pMemory += increment;
pStubMsg->Memory += increment;
}
while (MaxCount);
Memory = MemoryCopy;
}
pFormat = pFormatPointers + (number_of_pointers * 8);
pStubMsg->Memory = Memory;
return pFormat;
}
PFORMAT_STRING NdrpEmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
{
ULONG_PTR MaxCount;
unsigned long Offset;
unsigned char* Memory;
char PointerLengthSet;
PFORMAT_STRING pFormatCopy;
unsigned long BufferLength;
unsigned long BufferLengthCopy;
unsigned long PointerLength;
unsigned char* pMemoryPtr = NULL;
pFormatCopy = pFormat;
if (!pStubMsg->IgnoreEmbeddedPointers)
{
PointerLength = pStubMsg->PointerLength;
PointerLengthSet = (PointerLength != 0);
if (PointerLengthSet)
{
BufferLength = pStubMsg->BufferLength;
pStubMsg->PointerLength = 0;
BufferLengthCopy = BufferLength;
pStubMsg->BufferLength = PointerLength;
}
MaxCount = pStubMsg->MaxCount;
Offset = pStubMsg->Offset;
Memory = pStubMsg->Memory;
pStubMsg->Memory = pMemory;
pFormat = pFormatCopy + 2;
while (*pFormat != FC_END)
{
if (*pFormat == FC_NO_REPEAT)
{
NdrpPointerBufferSize(&pMemory[pFormat[2]], &pFormat[6], pStubMsg);
pFormat += 10;
}
pStubMsg->Offset = Offset;
pStubMsg->MaxCount = MaxCount;
NdrpEmbeddedRepeatPointerBufferSize(pStubMsg, pMemory, pFormat, &pMemoryPtr);
}
pStubMsg->Memory = Memory;
if (PointerLengthSet)
{
pStubMsg->PointerLength = pStubMsg->BufferLength;
pStubMsg->BufferLength = BufferLengthCopy;
}
}
return pFormat;
}
void NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
{
if (*pFormat != FC_RP)
{
NdrpAlignLength((&pStubMsg->BufferLength), 4);
NdrpIncrementLength((&pStubMsg->BufferLength), 4);
}
NdrpPointerBufferSize(pMemory, pFormat, pStubMsg);
}
void NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
{
printf("warning: NdrByteCountPointerBufferSize unimplemented\n");
}

View File

@@ -0,0 +1,37 @@
/**
* WinPR: Windows Portable Runtime
* Microsoft Remote Procedure Call (MSRPC)
*
* 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_RPC_NDR_POINTER_H
#define WINPR_RPC_NDR_POINTER_H
#include <winpr/rpc.h>
PFORMAT_STRING NdrpSkipPointerLayout(PFORMAT_STRING pFormat);
void NdrpPointerBufferSize(unsigned char* pMemory, PFORMAT_STRING pFormat, PMIDL_STUB_MESSAGE pStubMsg);
PFORMAT_STRING NdrpEmbeddedRepeatPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
unsigned char* pMemory, PFORMAT_STRING pFormat, unsigned char** ppMemory);
PFORMAT_STRING NdrpEmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat);
void NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat);
void NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat);
#endif /* WINPR_RPC_NDR_POINTER_H */

552
libwinpr-rpc/ndr_private.c Normal file
View File

@@ -0,0 +1,552 @@
/**
* WinPR: Windows Portable Runtime
* Microsoft Remote Procedure Call (MSRPC)
*
* 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 <winpr/rpc.h>
#include "ndr_array.h"
#include "ndr_context.h"
#include "ndr_pointer.h"
#include "ndr_simple.h"
#include "ndr_string.h"
#include "ndr_structure.h"
#include "ndr_union.h"
#include "ndr_private.h"
void NdrpAlignLength(unsigned long* length, unsigned int alignment)
{
*length = (*length + alignment - 1) & ~(alignment - 1);
}
void NdrpIncrementLength(unsigned long* length, unsigned int size)
{
*length += size;
}
const char* FC_TYPE_STRINGS[] =
{
"FC_ZERO",
"FC_BYTE",
"FC_CHAR",
"FC_SMALL",
"FC_USMALL",
"FC_WCHAR",
"FC_SHORT",
"FC_USHORT",
"FC_LONG",
"FC_ULONG",
"FC_FLOAT",
"FC_HYPER",
"FC_DOUBLE",
"FC_ENUM16",
"FC_ENUM32",
"FC_IGNORE",
"FC_ERROR_STATUS_T",
"FC_RP",
"FC_UP",
"FC_OP",
"FC_FP",
"FC_STRUCT",
"FC_PSTRUCT",
"FC_CSTRUCT",
"FC_CPSTRUCT",
"FC_CVSTRUCT",
"FC_BOGUS_STRUCT",
"FC_CARRAY",
"FC_CVARRAY",
"FC_SMFARRAY",
"FC_LGFARRAY",
"FC_SMVARRAY",
"FC_LGVARRAY",
"FC_BOGUS_ARRAY",
"FC_C_CSTRING",
"FC_C_BSTRING",
"FC_C_SSTRING",
"FC_C_WSTRING",
"FC_CSTRING",
"FC_BSTRING",
"FC_SSTRING",
"FC_WSTRING",
"FC_ENCAPSULATED_UNION",
"FC_NON_ENCAPSULATED_UNION",
"FC_BYTE_COUNT_POINTER",
"FC_TRANSMIT_AS",
"FC_REPRESENT_AS",
"FC_IP",
"FC_BIND_CONTEXT",
"FC_BIND_GENERIC",
"FC_BIND_PRIMITIVE",
"FC_AUTO_HANDLE",
"FC_CALLBACK_HANDLE",
"FC_UNUSED1",
"FC_POINTER",
"FC_ALIGNM2",
"FC_ALIGNM4",
"FC_ALIGNM8",
"FC_UNUSED2",
"FC_UNUSED3",
"FC_UNUSED4",
"FC_STRUCTPAD1",
"FC_STRUCTPAD2",
"FC_STRUCTPAD3",
"FC_STRUCTPAD4",
"FC_STRUCTPAD5",
"FC_STRUCTPAD6",
"FC_STRUCTPAD7",
"FC_STRING_SIZED",
"FC_UNUSED5",
"FC_NO_REPEAT",
"FC_FIXED_REPEAT",
"FC_VARIABLE_REPEAT",
"FC_FIXED_OFFSET",
"FC_VARIABLE_OFFSET",
"FC_PP",
"FC_EMBEDDED_COMPLEX",
"FC_IN_PARAM",
"FC_IN_PARAM_BASETYPE",
"FC_IN_PARAM_NO_FREE_INST",
"FC_IN_OUT_PARAM",
"FC_OUT_PARAM",
"FC_RETURN_PARAM",
"FC_RETURN_PARAM_BASETYPE",
"FC_DEREFERENCE",
"FC_DIV_2",
"FC_MULT_2",
"FC_ADD_1",
"FC_SUB_1",
"FC_CALLBACK",
"FC_CONSTANT_IID",
"FC_END",
"FC_PAD",
"", "", "", "", "", "",
"", "", "", "", "", "",
"", "", "", "", "", "",
"", "", "", "", "", "",
"FC_SPLIT_DEREFERENCE",
"FC_SPLIT_DIV_2",
"FC_SPLIT_MULT_2",
"FC_SPLIT_ADD_1",
"FC_SPLIT_SUB_1",
"FC_SPLIT_CALLBACK",
"", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "",
"FC_HARD_STRUCT",
"FC_TRANSMIT_AS_PTR",
"FC_REPRESENT_AS_PTR",
"FC_USER_MARSHAL",
"FC_PIPE",
"FC_BLKHOLE",
"FC_RANGE",
"FC_INT3264",
"FC_UINT3264",
"FC_END_OF_UNIVERSE",
};
const NDR_TYPE_SIZE_ROUTINE pfnSizeRoutines[] =
{
NULL, /* FC_ZERO */
NdrSimpleTypeBufferSize, /* FC_BYTE */
NdrSimpleTypeBufferSize, /* FC_CHAR */
NdrSimpleTypeBufferSize, /* FC_SMALL */
NdrSimpleTypeBufferSize, /* FC_USMALL */
NdrSimpleTypeBufferSize, /* FC_WCHAR */
NdrSimpleTypeBufferSize, /* FC_SHORT */
NdrSimpleTypeBufferSize, /* FC_USHORT */
NdrSimpleTypeBufferSize, /* FC_LONG */
NdrSimpleTypeBufferSize, /* FC_ULONG */
NdrSimpleTypeBufferSize, /* FC_FLOAT */
NdrSimpleTypeBufferSize, /* FC_HYPER */
NdrSimpleTypeBufferSize, /* FC_DOUBLE */
NdrSimpleTypeBufferSize, /* FC_ENUM16 */
NdrSimpleTypeBufferSize, /* FC_ENUM32 */
NdrSimpleTypeBufferSize, /* FC_IGNORE */
NdrSimpleTypeBufferSize, /* FC_ERROR_STATUS_T */
NdrPointerBufferSize, /* FC_RP */
NdrPointerBufferSize, /* FC_UP */
NdrPointerBufferSize, /* FC_OP */
NdrPointerBufferSize, /* FC_FP */
NdrSimpleStructBufferSize, /* FC_STRUCT */
NdrSimpleStructBufferSize, /* FC_PSTRUCT */
NdrConformantStructBufferSize, /* FC_CSTRUCT */
NdrConformantStructBufferSize, /* FC_CPSTRUCT */
NdrConformantVaryingStructBufferSize, /* FC_CVSTRUCT */
NdrComplexStructBufferSize, /* FC_BOGUS_STRUCT */
NdrConformantArrayBufferSize, /* FC_CARRAY */
NdrConformantVaryingArrayBufferSize, /* FC_CVARRAY */
NdrFixedArrayBufferSize, /* FC_SMFARRAY */
NdrFixedArrayBufferSize, /* FC_LGFARRAY */
NdrVaryingArrayBufferSize, /* FC_SMVARRAY */
NdrVaryingArrayBufferSize, /* FC_LGVARRAY */
NdrComplexArrayBufferSize, /* FC_BOGUS_ARRAY */
NdrConformantStringBufferSize, /* FC_C_CSTRING */
NULL, /* FC_C_BSTRING */
NULL, /* FC_C_SSTRING */
NdrConformantStringBufferSize, /* FC_C_WSTRING */
NdrNonConformantStringBufferSize, /* FC_CSTRING */
NULL, /* FC_BSTRING */
NULL, /* FC_SSTRING */
NULL, /* FC_WSTRING */
NdrEncapsulatedUnionBufferSize, /* FC_ENCAPSULATED_UNION */
NdrNonEncapsulatedUnionBufferSize, /* FC_NON_ENCAPSULATED_UNION */
NdrByteCountPointerBufferSize, /* FC_BYTE_COUNT_POINTER */
NULL, /* FC_TRANSMIT_AS */
NULL, /* FC_REPRESENT_AS */
NULL, /* FC_IP */
NdrContextHandleBufferSize, /* FC_BIND_CONTEXT */
NULL, /* FC_BIND_GENERIC */
NULL, /* FC_BIND_PRIMITIVE */
NULL, /* FC_AUTO_HANDLE */
NULL, /* FC_CALLBACK_HANDLE */
NULL, /* FC_UNUSED1 */
NULL, /* FC_POINTER */
NULL, /* FC_ALIGNM2 */
NULL, /* FC_ALIGNM4 */
NULL, /* FC_ALIGNM8 */
NULL, /* FC_UNUSED2 */
NULL, /* FC_UNUSED3 */
NULL, /* FC_UNUSED4 */
NULL, /* FC_STRUCTPAD1 */
NULL, /* FC_STRUCTPAD2 */
NULL, /* FC_STRUCTPAD3 */
NULL, /* FC_STRUCTPAD4 */
NULL, /* FC_STRUCTPAD5 */
NULL, /* FC_STRUCTPAD6 */
NULL, /* FC_STRUCTPAD7 */
NULL, /* FC_STRING_SIZED */
NULL, /* FC_UNUSED5 */
NULL, /* FC_NO_REPEAT */
NULL, /* FC_FIXED_REPEAT */
NULL, /* FC_VARIABLE_REPEAT */
NULL, /* FC_FIXED_OFFSET */
NULL, /* FC_VARIABLE_OFFSET */
NULL, /* FC_PP */
NULL, /* FC_EMBEDDED_COMPLEX */
NULL, /* FC_IN_PARAM */
NULL, /* FC_IN_PARAM_BASETYPE */
NULL, /* FC_IN_PARAM_NO_FREE_INST */
NULL, /* FC_IN_OUT_PARAM */
NULL, /* FC_OUT_PARAM */
NULL, /* FC_RETURN_PARAM */
NULL, /* FC_RETURN_PARAM_BASETYPE */
NULL, /* FC_DEREFERENCE */
NULL, /* FC_DIV_2 */
NULL, /* FC_MULT_2 */
NULL, /* FC_ADD_1 */
NULL, /* FC_SUB_1 */
NULL, /* FC_CALLBACK */
NULL, /* FC_CONSTANT_IID */
NULL, /* FC_END */
NULL, /* FC_PAD */
};
const NDR_TYPE_MARSHALL_ROUTINE pfnMarshallRoutines[] =
{
NULL, /* FC_ZERO */
NdrSimpleTypeMarshall, /* FC_BYTE */
NdrSimpleTypeMarshall, /* FC_CHAR */
NdrSimpleTypeMarshall, /* FC_SMALL */
NdrSimpleTypeMarshall, /* FC_USMALL */
NdrSimpleTypeMarshall, /* FC_WCHAR */
NdrSimpleTypeMarshall, /* FC_SHORT */
NdrSimpleTypeMarshall, /* FC_USHORT */
NdrSimpleTypeMarshall, /* FC_LONG */
NdrSimpleTypeMarshall, /* FC_ULONG */
NdrSimpleTypeMarshall, /* FC_FLOAT */
NdrSimpleTypeMarshall, /* FC_HYPER */
NdrSimpleTypeMarshall, /* FC_DOUBLE */
NdrSimpleTypeMarshall, /* FC_ENUM16 */
NdrSimpleTypeMarshall, /* FC_ENUM32 */
NdrSimpleTypeMarshall, /* FC_IGNORE */
NULL, /* FC_ERROR_STATUS_T */
NULL, /* FC_RP */
NULL, /* FC_UP */
NULL, /* FC_OP */
NULL, /* FC_FP */
NULL, /* FC_STRUCT */
NULL, /* FC_PSTRUCT */
NULL, /* FC_CSTRUCT */
NULL, /* FC_CPSTRUCT */
NULL, /* FC_CVSTRUCT */
NULL, /* FC_BOGUS_STRUCT */
NULL, /* FC_CARRAY */
NULL, /* FC_CVARRAY */
NULL, /* FC_SMFARRAY */
NULL, /* FC_LGFARRAY */
NULL, /* FC_SMVARRAY */
NULL, /* FC_LGVARRAY */
NULL, /* FC_BOGUS_ARRAY */
NULL, /* FC_C_CSTRING */
NULL, /* FC_C_BSTRING */
NULL, /* FC_C_SSTRING */
NULL, /* FC_C_WSTRING */
NULL, /* FC_CSTRING */
NULL, /* FC_BSTRING */
NULL, /* FC_SSTRING */
NULL, /* FC_WSTRING */
NULL, /* FC_ENCAPSULATED_UNION */
NULL, /* FC_NON_ENCAPSULATED_UNION */
NULL, /* FC_BYTE_COUNT_POINTER */
NULL, /* FC_TRANSMIT_AS */
NULL, /* FC_REPRESENT_AS */
NULL, /* FC_IP */
NULL, /* FC_BIND_CONTEXT */
NULL, /* FC_BIND_GENERIC */
NULL, /* FC_BIND_PRIMITIVE */
NULL, /* FC_AUTO_HANDLE */
NULL, /* FC_CALLBACK_HANDLE */
NULL, /* FC_UNUSED1 */
NULL, /* FC_POINTER */
NULL, /* FC_ALIGNM2 */
NULL, /* FC_ALIGNM4 */
NULL, /* FC_ALIGNM8 */
NULL, /* FC_UNUSED2 */
NULL, /* FC_UNUSED3 */
NULL, /* FC_UNUSED4 */
NULL, /* FC_STRUCTPAD1 */
NULL, /* FC_STRUCTPAD2 */
NULL, /* FC_STRUCTPAD3 */
NULL, /* FC_STRUCTPAD4 */
NULL, /* FC_STRUCTPAD5 */
NULL, /* FC_STRUCTPAD6 */
NULL, /* FC_STRUCTPAD7 */
NULL, /* FC_STRING_SIZED */
NULL, /* FC_UNUSED5 */
NULL, /* FC_NO_REPEAT */
NULL, /* FC_FIXED_REPEAT */
NULL, /* FC_VARIABLE_REPEAT */
NULL, /* FC_FIXED_OFFSET */
NULL, /* FC_VARIABLE_OFFSET */
NULL, /* FC_PP */
NULL, /* FC_EMBEDDED_COMPLEX */
NULL, /* FC_IN_PARAM */
NULL, /* FC_IN_PARAM_BASETYPE */
NULL, /* FC_IN_PARAM_NO_FREE_INST */
NULL, /* FC_IN_OUT_PARAM */
NULL, /* FC_OUT_PARAM */
NULL, /* FC_RETURN_PARAM */
NULL, /* FC_RETURN_PARAM_BASETYPE */
NULL, /* FC_DEREFERENCE */
NULL, /* FC_DIV_2 */
NULL, /* FC_MULT_2 */
NULL, /* FC_ADD_1 */
NULL, /* FC_SUB_1 */
NULL, /* FC_CALLBACK */
NULL, /* FC_CONSTANT_IID */
NULL, /* FC_END */
NULL, /* FC_PAD */
};
const NDR_TYPE_UNMARSHALL_ROUTINE pfnUnmarshallRoutines[] =
{
NULL, /* FC_ZERO */
NdrSimpleTypeUnmarshall, /* FC_BYTE */
NdrSimpleTypeUnmarshall, /* FC_CHAR */
NdrSimpleTypeUnmarshall, /* FC_SMALL */
NdrSimpleTypeUnmarshall, /* FC_USMALL */
NdrSimpleTypeUnmarshall, /* FC_WCHAR */
NdrSimpleTypeUnmarshall, /* FC_SHORT */
NdrSimpleTypeUnmarshall, /* FC_USHORT */
NdrSimpleTypeUnmarshall, /* FC_LONG */
NdrSimpleTypeUnmarshall, /* FC_ULONG */
NdrSimpleTypeUnmarshall, /* FC_FLOAT */
NdrSimpleTypeUnmarshall, /* FC_HYPER */
NdrSimpleTypeUnmarshall, /* FC_DOUBLE */
NdrSimpleTypeUnmarshall, /* FC_ENUM16 */
NdrSimpleTypeUnmarshall, /* FC_ENUM32 */
NdrSimpleTypeUnmarshall, /* FC_IGNORE */
NULL, /* FC_ERROR_STATUS_T */
NULL, /* FC_RP */
NULL, /* FC_UP */
NULL, /* FC_OP */
NULL, /* FC_FP */
NULL, /* FC_STRUCT */
NULL, /* FC_PSTRUCT */
NULL, /* FC_CSTRUCT */
NULL, /* FC_CPSTRUCT */
NULL, /* FC_CVSTRUCT */
NULL, /* FC_BOGUS_STRUCT */
NULL, /* FC_CARRAY */
NULL, /* FC_CVARRAY */
NULL, /* FC_SMFARRAY */
NULL, /* FC_LGFARRAY */
NULL, /* FC_SMVARRAY */
NULL, /* FC_LGVARRAY */
NULL, /* FC_BOGUS_ARRAY */
NULL, /* FC_C_CSTRING */
NULL, /* FC_C_BSTRING */
NULL, /* FC_C_SSTRING */
NULL, /* FC_C_WSTRING */
NULL, /* FC_CSTRING */
NULL, /* FC_BSTRING */
NULL, /* FC_SSTRING */
NULL, /* FC_WSTRING */
NULL, /* FC_ENCAPSULATED_UNION */
NULL, /* FC_NON_ENCAPSULATED_UNION */
NULL, /* FC_BYTE_COUNT_POINTER */
NULL, /* FC_TRANSMIT_AS */
NULL, /* FC_REPRESENT_AS */
NULL, /* FC_IP */
NULL, /* FC_BIND_CONTEXT */
NULL, /* FC_BIND_GENERIC */
NULL, /* FC_BIND_PRIMITIVE */
NULL, /* FC_AUTO_HANDLE */
NULL, /* FC_CALLBACK_HANDLE */
NULL, /* FC_UNUSED1 */
NULL, /* FC_POINTER */
NULL, /* FC_ALIGNM2 */
NULL, /* FC_ALIGNM4 */
NULL, /* FC_ALIGNM8 */
NULL, /* FC_UNUSED2 */
NULL, /* FC_UNUSED3 */
NULL, /* FC_UNUSED4 */
NULL, /* FC_STRUCTPAD1 */
NULL, /* FC_STRUCTPAD2 */
NULL, /* FC_STRUCTPAD3 */
NULL, /* FC_STRUCTPAD4 */
NULL, /* FC_STRUCTPAD5 */
NULL, /* FC_STRUCTPAD6 */
NULL, /* FC_STRUCTPAD7 */
NULL, /* FC_STRING_SIZED */
NULL, /* FC_UNUSED5 */
NULL, /* FC_NO_REPEAT */
NULL, /* FC_FIXED_REPEAT */
NULL, /* FC_VARIABLE_REPEAT */
NULL, /* FC_FIXED_OFFSET */
NULL, /* FC_VARIABLE_OFFSET */
NULL, /* FC_PP */
NULL, /* FC_EMBEDDED_COMPLEX */
NULL, /* FC_IN_PARAM */
NULL, /* FC_IN_PARAM_BASETYPE */
NULL, /* FC_IN_PARAM_NO_FREE_INST */
NULL, /* FC_IN_OUT_PARAM */
NULL, /* FC_OUT_PARAM */
NULL, /* FC_RETURN_PARAM */
NULL, /* FC_RETURN_PARAM_BASETYPE */
NULL, /* FC_DEREFERENCE */
NULL, /* FC_DIV_2 */
NULL, /* FC_MULT_2 */
NULL, /* FC_ADD_1 */
NULL, /* FC_SUB_1 */
NULL, /* FC_CALLBACK */
NULL, /* FC_CONSTANT_IID */
NULL, /* FC_END */
NULL, /* FC_PAD */
};
const NDR_TYPE_FREE_ROUTINE pfnFreeRoutines[] =
{
NULL, /* FC_ZERO */
NdrSimpleTypeFree, /* FC_BYTE */
NdrSimpleTypeFree, /* FC_CHAR */
NdrSimpleTypeFree, /* FC_SMALL */
NdrSimpleTypeFree, /* FC_USMALL */
NdrSimpleTypeFree, /* FC_WCHAR */
NdrSimpleTypeFree, /* FC_SHORT */
NdrSimpleTypeFree, /* FC_USHORT */
NdrSimpleTypeFree, /* FC_LONG */
NdrSimpleTypeFree, /* FC_ULONG */
NdrSimpleTypeFree, /* FC_FLOAT */
NdrSimpleTypeFree, /* FC_HYPER */
NdrSimpleTypeFree, /* FC_DOUBLE */
NdrSimpleTypeFree, /* FC_ENUM16 */
NdrSimpleTypeFree, /* FC_ENUM32 */
NdrSimpleTypeFree, /* FC_IGNORE */
NULL, /* FC_ERROR_STATUS_T */
NULL, /* FC_RP */
NULL, /* FC_UP */
NULL, /* FC_OP */
NULL, /* FC_FP */
NULL, /* FC_STRUCT */
NULL, /* FC_PSTRUCT */
NULL, /* FC_CSTRUCT */
NULL, /* FC_CPSTRUCT */
NULL, /* FC_CVSTRUCT */
NULL, /* FC_BOGUS_STRUCT */
NULL, /* FC_CARRAY */
NULL, /* FC_CVARRAY */
NULL, /* FC_SMFARRAY */
NULL, /* FC_LGFARRAY */
NULL, /* FC_SMVARRAY */
NULL, /* FC_LGVARRAY */
NULL, /* FC_BOGUS_ARRAY */
NULL, /* FC_C_CSTRING */
NULL, /* FC_C_BSTRING */
NULL, /* FC_C_SSTRING */
NULL, /* FC_C_WSTRING */
NULL, /* FC_CSTRING */
NULL, /* FC_BSTRING */
NULL, /* FC_SSTRING */
NULL, /* FC_WSTRING */
NULL, /* FC_ENCAPSULATED_UNION */
NULL, /* FC_NON_ENCAPSULATED_UNION */
NULL, /* FC_BYTE_COUNT_POINTER */
NULL, /* FC_TRANSMIT_AS */
NULL, /* FC_REPRESENT_AS */
NULL, /* FC_IP */
NULL, /* FC_BIND_CONTEXT */
NULL, /* FC_BIND_GENERIC */
NULL, /* FC_BIND_PRIMITIVE */
NULL, /* FC_AUTO_HANDLE */
NULL, /* FC_CALLBACK_HANDLE */
NULL, /* FC_UNUSED1 */
NULL, /* FC_POINTER */
NULL, /* FC_ALIGNM2 */
NULL, /* FC_ALIGNM4 */
NULL, /* FC_ALIGNM8 */
NULL, /* FC_UNUSED2 */
NULL, /* FC_UNUSED3 */
NULL, /* FC_UNUSED4 */
NULL, /* FC_STRUCTPAD1 */
NULL, /* FC_STRUCTPAD2 */
NULL, /* FC_STRUCTPAD3 */
NULL, /* FC_STRUCTPAD4 */
NULL, /* FC_STRUCTPAD5 */
NULL, /* FC_STRUCTPAD6 */
NULL, /* FC_STRUCTPAD7 */
NULL, /* FC_STRING_SIZED */
NULL, /* FC_UNUSED5 */
NULL, /* FC_NO_REPEAT */
NULL, /* FC_FIXED_REPEAT */
NULL, /* FC_VARIABLE_REPEAT */
NULL, /* FC_FIXED_OFFSET */
NULL, /* FC_VARIABLE_OFFSET */
NULL, /* FC_PP */
NULL, /* FC_EMBEDDED_COMPLEX */
NULL, /* FC_IN_PARAM */
NULL, /* FC_IN_PARAM_BASETYPE */
NULL, /* FC_IN_PARAM_NO_FREE_INST */
NULL, /* FC_IN_OUT_PARAM */
NULL, /* FC_OUT_PARAM */
NULL, /* FC_RETURN_PARAM */
NULL, /* FC_RETURN_PARAM_BASETYPE */
NULL, /* FC_DEREFERENCE */
NULL, /* FC_DIV_2 */
NULL, /* FC_MULT_2 */
NULL, /* FC_ADD_1 */
NULL, /* FC_SUB_1 */
NULL, /* FC_CALLBACK */
NULL, /* FC_CONSTANT_IID */
NULL, /* FC_END */
NULL, /* FC_PAD */
};

View File

@@ -0,0 +1,42 @@
/**
* WinPR: Windows Portable Runtime
* Microsoft Remote Procedure Call (MSRPC)
*
* 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_RPC_NDR_PRIVATE_H
#define WINPR_RPC_NDR_PRIVATE_H
#include <winpr/rpc.h>
void NdrpAlignLength(unsigned long* length, unsigned int alignment);
void NdrpIncrementLength(unsigned long* length, unsigned int size);
extern const NDR_TYPE_SIZE_ROUTINE pfnSizeRoutines[];
extern const NDR_TYPE_MARSHALL_ROUTINE pfnMarshallRoutines[];
extern const NDR_TYPE_UNMARSHALL_ROUTINE pfnUnmarshallRoutines[];
extern const NDR_TYPE_FREE_ROUTINE pfnFreeRoutines[];
extern const char SimpleTypeAlignment[];
extern const char SimpleTypeBufferSize[];
extern const char SimpleTypeMemorySize[];
extern const char NdrTypeFlags[];
extern const char* FC_TYPE_STRINGS[];
#include "ndr_correlation.h"
#endif /* WINPR_RPC_NDR_PRIVATE_H */

193
libwinpr-rpc/ndr_simple.c Normal file
View File

@@ -0,0 +1,193 @@
/**
* WinPR: Windows Portable Runtime
* Microsoft Remote Procedure Call (MSRPC)
*
* 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 <winpr/rpc.h>
#include "ndr_simple.h"
#include "ndr_private.h"
const char SimpleTypeAlignment[] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x07, 0x07, 0x01, 0x03, 0x03,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04, 0x08, 0x08, 0x02, 0x04, 0x04,
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
const char SimpleTypeBufferSize[] =
{
0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04, 0x08, 0x08, 0x02, 0x04, 0x04,
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04, 0x08, 0x08, 0x04, 0x04, 0x04,
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
const char SimpleTypeMemorySize[] =
{
0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04, 0x08, 0x08, 0x04, 0x04, 0x04,
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75,
0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75,
0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75,
0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75,
};
const char NdrTypeFlags[] =
{
0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x02, 0x02, 0x02, 0x02, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xA0, 0xA0, 0x00, 0xC0, 0xC0, 0x02,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x84, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x04, 0x00, 0x01,
0x03, 0x10, 0x01, 0x03, 0x2C, 0x01, 0x03, 0xE0, 0x90, 0x90, 0x8B, 0x57, 0x83, 0xE7, 0x6C, 0x01,
0x09, 0x70, 0x3B, 0x86, 0x00, 0x0F, 0x01, 0x5A, 0x00, 0x80, 0x00, 0x30, 0x8D, 0x30, 0x84, 0x00,
0x48, 0x6A, 0x00, 0x6A, 0x01, 0x06, 0xFF, 0x08, 0x5D, 0x90, 0x7D, 0x7D, 0x0F, 0x67, 0xBD, 0xAD,
0xAD, 0xAD, 0x9B, 0xBA, 0x9B, 0x9B, 0x0D, 0xB9, 0xAD, 0x19, 0x19, 0xBA, 0xDB, 0x09, 0x86, 0xB1,
};
char NdrGetSimpleTypeBufferAlignment(unsigned char FormatChar)
{
return SimpleTypeAlignment[FormatChar];
}
char NdrGetSimpleTypeBufferSize(unsigned char FormatChar)
{
return SimpleTypeAlignment[FormatChar];
}
char NdrGetSimpleTypeMemorySize(unsigned char FormatChar)
{
return SimpleTypeMemorySize[FormatChar];
}
int NdrGetTypeFlags(unsigned char FormatChar)
{
return NdrTypeFlags[FormatChar];
}
void NdrSimpleTypeBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
{
switch (*pFormat)
{
case FC_BYTE:
case FC_CHAR:
case FC_SMALL:
case FC_USMALL:
NdrpIncrementLength(&(pStubMsg->BufferLength), sizeof(BYTE));
break;
case FC_WCHAR:
case FC_SHORT:
case FC_USHORT:
case FC_ENUM16:
NdrpAlignLength(&(pStubMsg->BufferLength), sizeof(USHORT));
NdrpIncrementLength(&(pStubMsg->BufferLength), sizeof(USHORT));
break;
case FC_LONG:
case FC_ULONG:
case FC_ENUM32:
case FC_INT3264:
case FC_UINT3264:
NdrpAlignLength(&(pStubMsg->BufferLength), sizeof(ULONG));
NdrpIncrementLength(&(pStubMsg->BufferLength), sizeof(ULONG));
break;
case FC_FLOAT:
NdrpAlignLength(&(pStubMsg->BufferLength), sizeof(FLOAT));
NdrpIncrementLength(&(pStubMsg->BufferLength), sizeof(FLOAT));
break;
case FC_DOUBLE:
NdrpAlignLength(&(pStubMsg->BufferLength), sizeof(DOUBLE));
NdrpIncrementLength(&(pStubMsg->BufferLength), sizeof(DOUBLE));
break;
case FC_HYPER:
NdrpAlignLength(&(pStubMsg->BufferLength), sizeof(ULONGLONG));
NdrpIncrementLength(&(pStubMsg->BufferLength), sizeof(ULONGLONG));
break;
case FC_ERROR_STATUS_T:
NdrpAlignLength(&(pStubMsg->BufferLength), sizeof(error_status_t));
NdrpIncrementLength(&(pStubMsg->BufferLength), sizeof(error_status_t));
break;
case FC_IGNORE:
break;
}
}
void NdrSimpleTypeMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, unsigned char FormatChar)
{
}
void NdrSimpleTypeUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, unsigned char FormatChar)
{
}
void NdrSimpleTypeFree(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
{
}

35
libwinpr-rpc/ndr_simple.h Normal file
View File

@@ -0,0 +1,35 @@
/**
* WinPR: Windows Portable Runtime
* Microsoft Remote Procedure Call (MSRPC)
*
* 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_RPC_NDR_SIMPLE_H
#define WINPR_RPC_NDR_SIMPLE_H
#include <winpr/rpc.h>
void NdrSimpleTypeBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat);
void NdrSimpleTypeMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, unsigned char FormatChar);
void NdrSimpleTypeUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, unsigned char FormatChar);
void NdrSimpleTypeFree(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat);
char NdrGetSimpleTypeBufferAlignment(unsigned char FormatChar);
char NdrGetSimpleTypeBufferSize(unsigned char FormatChar);
char NdrGetSimpleTypeMemorySize(unsigned char FormatChar);
int NdrGetTypeFlags(unsigned char FormatChar);
#endif /* WINPR_RPC_NDR_SIMPLE_H */

35
libwinpr-rpc/ndr_string.c Normal file
View File

@@ -0,0 +1,35 @@
/**
* WinPR: Windows Portable Runtime
* Microsoft Remote Procedure Call (MSRPC)
*
* 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 <winpr/rpc.h>
#include "ndr_string.h"
void NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
{
printf("warning: NdrConformantStringBufferSize unimplemented\n");
}
void NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
{
printf("warning: NdrNonConformantStringBufferSize unimplemented\n");
}

28
libwinpr-rpc/ndr_string.h Normal file
View File

@@ -0,0 +1,28 @@
/**
* WinPR: Windows Portable Runtime
* Microsoft Remote Procedure Call (MSRPC)
*
* 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_RPC_NDR_STRING_H
#define WINPR_RPC_NDR_STRING_H
#include <winpr/rpc.h>
void NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat);
void NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat);
#endif /* WINPR_RPC_NDR_STRING_H */

View File

@@ -0,0 +1,313 @@
/**
* WinPR: Windows Portable Runtime
* Microsoft Remote Procedure Call (MSRPC)
*
* 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 <winpr/rpc.h>
#include "ndr_private.h"
#include "ndr_pointer.h"
#include "ndr_structure.h"
/* Structures: http://msdn.microsoft.com/en-us/library/windows/desktop/aa378695/ */
void NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
{
/**
* FC_STRUCT
* alignment<1>
* memory_size<2>
* member_layout<>
* FC_END
*/
/**
* FC_PSTRUCT
* alignment<1>
* memory_size<2>
* pointer_layout<>
* member_layout<>
* FC_END
*/
unsigned char type;
unsigned char alignment;
unsigned short memory_size;
type = pFormat[0];
alignment = pFormat[1] + 1;
memory_size = *(unsigned short*) &pFormat[2];
NdrpAlignLength(&(pStubMsg->BufferLength), alignment);
NdrpIncrementLength(&(pStubMsg->BufferLength), memory_size);
pFormat += 4;
if (*pFormat == FC_PSTRUCT)
NdrpEmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
printf("warning: NdrSimpleStructBufferSize unimplemented\n");
}
void NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
{
/**
* FC_CSTRUCT alignment<1>
* memory_size<2>
* offset_to_array_description<2>
* member_layout<>
* FC_END
*/
/**
* FC_CPSTRUCT alignment<1>
* memory_size<2>
* offset_to_array_description<2>
* pointer_layout<>
* member_layout<> FC_END
*/
printf("warning: NdrConformantStructBufferSize unimplemented\n");
}
void NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
{
/**
* FC_CVSTRUCT alignment<1>
* memory_size<2>
* offset_to_array_description<2>
* [pointer_layout<>]
* layout<>
* FC_END
*/
printf("warning: NdrConformantVaryingStructBufferSize unimplemented\n");
}
ULONG NdrComplexStructMemberSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
{
ULONG size = 0;
while (*pFormat != FC_END)
{
switch (*pFormat)
{
case FC_BYTE:
case FC_CHAR:
case FC_SMALL:
case FC_USMALL:
size += sizeof(BYTE);
break;
case FC_WCHAR:
case FC_SHORT:
case FC_USHORT:
case FC_ENUM16:
size += sizeof(USHORT);
break;
case FC_LONG:
case FC_ULONG:
case FC_ENUM32:
size += sizeof(ULONG);
break;
case FC_INT3264:
case FC_UINT3264:
size += sizeof(INT_PTR);
break;
case FC_FLOAT:
size += sizeof(FLOAT);
break;
case FC_DOUBLE:
size += sizeof(DOUBLE);
break;
case FC_HYPER:
size += sizeof(ULONGLONG);
break;
case FC_ERROR_STATUS_T:
size += sizeof(error_status_t);
break;
case FC_IGNORE:
break;
case FC_RP:
case FC_UP:
case FC_OP:
case FC_FP:
case FC_POINTER:
size += sizeof(void*);
if (*pFormat != FC_POINTER)
pFormat += 4;
break;
case FC_ALIGNM2:
NdrpAlignLength(&size, 2);
break;
case FC_ALIGNM4:
NdrpAlignLength(&size, 4);
break;
case FC_ALIGNM8:
NdrpAlignLength(&size, 8);
break;
case FC_STRUCTPAD1:
case FC_STRUCTPAD2:
case FC_STRUCTPAD3:
case FC_STRUCTPAD4:
case FC_STRUCTPAD5:
case FC_STRUCTPAD6:
case FC_STRUCTPAD7:
size += *pFormat - FC_STRUCTPAD1 + 1;
break;
case FC_PAD:
break;
case FC_EMBEDDED_COMPLEX:
printf("warning: NdrComplexStructMemberSize FC_EMBEDDED_COMPLEX unimplemented\n");
break;
default:
printf("warning: NdrComplexStructMemberSize 0x%02X unimplemented\n", *pFormat);
break;
}
pFormat++;
}
return size;
}
void NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
{
/**
* FC_BOGUS_STRUCT
* alignment<1>
* memory_size<2>
* offset_to_conformant_array_description<2>
* offset_to_pointer_layout<2>
* member_layout<>
* FC_END
* [pointer_layout<>]
*/
ULONG_PTR MaxCount;
unsigned long Offset;
unsigned long ActualCount;
unsigned char* pMemoryCopy;
unsigned char type;
unsigned char alignment;
unsigned short memory_size;
unsigned char* pointer_layout;
unsigned char* conformant_array_description;
unsigned short offset_to_pointer_layout;
unsigned short offset_to_conformant_array_description;
type = pFormat[0];
pMemoryCopy = pMemory;
pointer_layout = conformant_array_description = NULL;
if (type != FC_BOGUS_STRUCT)
{
printf("error: expected FC_BOGUS_STRUCT, got 0x%02X\n", type);
return;
}
alignment = pFormat[1] + 1;
memory_size = *(unsigned short*) &pFormat[2];
NdrpAlignLength(&(pStubMsg->BufferLength), alignment);
if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
{
unsigned long BufferLengthCopy = pStubMsg->BufferLength;
int IgnoreEmbeddedPointersCopy = pStubMsg->IgnoreEmbeddedPointers;
pStubMsg->IgnoreEmbeddedPointers = 1;
NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
pStubMsg->IgnoreEmbeddedPointers = IgnoreEmbeddedPointersCopy;
pStubMsg->PointerLength = pStubMsg->BufferLength;
pStubMsg->BufferLength = BufferLengthCopy;
}
pFormat += 4;
offset_to_conformant_array_description = *(unsigned short*) &pFormat[0];
if (offset_to_conformant_array_description)
conformant_array_description = (unsigned char*) pFormat + offset_to_conformant_array_description;
pFormat += 2;
offset_to_pointer_layout = *(unsigned short*) &pFormat[0];
if (offset_to_pointer_layout)
pointer_layout = (unsigned char*) pFormat + offset_to_pointer_layout;
pFormat += 2;
pStubMsg->Memory = pMemory;
if (conformant_array_description)
{
ULONG size;
unsigned char array_type;
array_type = conformant_array_description[0];
size = NdrComplexStructMemberSize(pStubMsg, pFormat);
printf("warning: NdrComplexStructBufferSize array_type: 0x%02X unimplemented\n", array_type);
NdrpComputeConformance(pStubMsg, pMemory + size, conformant_array_description);
NdrpComputeVariance(pStubMsg, pMemory + size, conformant_array_description);
MaxCount = pStubMsg->MaxCount;
ActualCount = pStubMsg->ActualCount;
Offset = pStubMsg->Offset;
}
if (conformant_array_description)
{
unsigned char array_type;
array_type = conformant_array_description[0];
pStubMsg->MaxCount = MaxCount;
pStubMsg->ActualCount = ActualCount;
pStubMsg->Offset = Offset;
printf("warning: NdrComplexStructBufferSize array_type: 0x%02X unimplemented\n", array_type);
}
pStubMsg->Memory = pMemoryCopy;
if (pStubMsg->PointerLength > 0)
{
pStubMsg->BufferLength = pStubMsg->PointerLength;
pStubMsg->PointerLength = 0;
}
}

View File

@@ -0,0 +1,30 @@
/**
* WinPR: Windows Portable Runtime
* Microsoft Remote Procedure Call (MSRPC)
*
* 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_RPC_NDR_STRUCTURE_H
#define WINPR_RPC_NDR_STRUCTURE_H
#include <winpr/rpc.h>
void NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat);
void NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat);
void NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat);
void NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat);
#endif /* WINPR_RPC_NDR_STRUCTURE_H */

35
libwinpr-rpc/ndr_union.c Normal file
View File

@@ -0,0 +1,35 @@
/**
* WinPR: Windows Portable Runtime
* Microsoft Remote Procedure Call (MSRPC)
*
* 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 <winpr/rpc.h>
#include "ndr_union.h"
void NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
{
printf("warning: NdrEncapsulatedUnionBufferSize unimplemented\n");
}
void NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
{
printf("warning: NdrNonEncapsulatedUnionBufferSize unimplemented\n");
}

28
libwinpr-rpc/ndr_union.h Normal file
View File

@@ -0,0 +1,28 @@
/**
* WinPR: Windows Portable Runtime
* Microsoft Remote Procedure Call (MSRPC)
*
* 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_RPC_NDR_UNION_H
#define WINPR_RPC_NDR_UNION_H
#include <winpr/rpc.h>
void NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat);
void NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat);
#endif /* WINPR_RPC_NDR_UNION_H */

27
libwinpr-rpc/rpc.c Normal file
View File

@@ -0,0 +1,27 @@
/**
* WinPR: Windows Portable Runtime
* Microsoft Remote Procedure Call (MSRPC)
*
* 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 <winpr/rpc.h>
void RpcRaiseException(RPC_STATUS exception)
{
printf("RpcRaiseException: 0x%08luX\n", exception);
}

View File

@@ -1,5 +1,5 @@
# FreeRDP: A Remote Desktop Protocol Client
# libfreerdp-sspi cmake build script
# WinPR: Windows Portable Runtime
# libwinpr-sspi cmake build script
#
# Copyright 2011 O.S. Systems Software Ltda.
# Copyright 2011 Otavio Salvador <otavio@ossystems.com.br>
@@ -17,7 +17,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
set(FREERDP_SSPI_NTLM_SRCS
set(WINPR_SSPI_NTLM_SRCS
NTLM/ntlm_av_pairs.c
NTLM/ntlm_av_pairs.h
NTLM/ntlm_compute.c
@@ -27,7 +27,7 @@ set(FREERDP_SSPI_NTLM_SRCS
NTLM/ntlm.c
NTLM/ntlm.h)
set(FREERDP_SSPI_KERBEROS_SRCS
set(WINPR_SSPI_KERBEROS_SRCS
Kerberos/kerberos_crypto.c
Kerberos/kerberos_crypto.h
Kerberos/kerberos_decode.c
@@ -37,36 +37,36 @@ set(FREERDP_SSPI_KERBEROS_SRCS
Kerberos/kerberos.c
Kerberos/kerberos.h)
set(FREERDP_SSPI_NEGOTIATE_SRCS
set(WINPR_SSPI_NEGOTIATE_SRCS
Negotiate/negotiate.c
Negotiate/negotiate.h)
set(FREERDP_SSPI_SRCS
set(WINPR_SSPI_SRCS
sspi.c
sspi.h
credssp.c)
if(NOT WITH_NATIVE_SSPI)
set(FREERDP_SSPI_SRCS
${FREERDP_SSPI_NTLM_SRCS}
${FREERDP_SSPI_KERBEROS_SRCS}
${FREERDP_SSPI_NEGOTIATE_SRCS}
${FREERDP_SSPI_SRCS})
set(WINPR_SSPI_SRCS
${WINPR_SSPI_NTLM_SRCS}
${WINPR_SSPI_KERBEROS_SRCS}
${WINPR_SSPI_NEGOTIATE_SRCS}
${WINPR_SSPI_SRCS})
else()
add_definitions(-DNATIVE_SSPI)
endif()
add_library(freerdp-sspi ${FREERDP_SSPI_SRCS})
add_library(winpr-sspi ${WINPR_SSPI_SRCS})
include_directories(${OPENSSL_INCLUDE_DIR})
include_directories(${ZLIB_INCLUDE_DIRS})
set_target_properties(freerdp-sspi PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib")
set_target_properties(winpr-sspi PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib")
target_link_libraries(freerdp-sspi freerdp-utils)
target_link_libraries(freerdp-sspi freerdp-crypto)
target_link_libraries(freerdp-sspi ${ZLIB_LIBRARIES})
target_link_libraries(winpr-sspi freerdp-utils)
target_link_libraries(winpr-sspi freerdp-crypto)
target_link_libraries(winpr-sspi ${ZLIB_LIBRARIES})
install(TARGETS freerdp-sspi DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(TARGETS winpr-sspi DESTINATION ${CMAKE_INSTALL_LIBDIR})

View File

@@ -37,7 +37,7 @@
#include "kerberos_encode.h"
#include "kerberos_decode.h"
#include <freerdp/sspi/sspi.h>
#include <winpr/sspi.h>
#include <freerdp/utils/tcp.h>
#include <freerdp/utils/time.h>

View File

@@ -34,11 +34,11 @@
#include <sys/types.h>
#include <winpr/sspi.h>
#include <freerdp/types.h>
#include <freerdp/settings.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/blob.h>
#include <freerdp/sspi/sspi.h>
#define MSKRB_OID "1.2.840.48018.1.2.2"
#define STDKRB_OID "1.2.840.113554.1.2.2"

View File

@@ -25,7 +25,7 @@
#include <openssl/engine.h>
#include <freerdp/utils/memory.h>
#include <freerdp/sspi/sspi.h>
#include <winpr/sspi.h>
#include "ntlm.h"
#include "../sspi.h"
@@ -390,6 +390,9 @@ SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextA(PCredHandle phCredenti
{
context = ntlm_ContextNew();
if (fContextReq & ISC_REQ_CONFIDENTIALITY)
context->confidentiality = true;
credentials = (CREDENTIALS*) sspi_SecureHandleGetLowerPointer(phCredential);
ntlm_SetContextIdentity(context, &credentials->identity);
@@ -565,7 +568,12 @@ SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext, uint32 fQOP
HMAC_CTX_cleanup(&hmac);
/* Encrypt message using with RC4, result overwrites original buffer */
crypto_rc4(context->SendRc4Seal, length, data, data_buffer->pvBuffer);
if (context->confidentiality)
crypto_rc4(context->SendRc4Seal, length, data, data_buffer->pvBuffer);
else
memcpy(data_buffer->pvBuffer, data, length);
xfree(data);
#ifdef WITH_DEBUG_NTLM

View File

@@ -20,7 +20,7 @@
#ifndef FREERDP_SSPI_NTLM_PRIVATE_H
#define FREERDP_SSPI_NTLM_PRIVATE_H
#include <freerdp/sspi/sspi.h>
#include <winpr/sspi.h>
#include <freerdp/crypto/crypto.h>
#include <freerdp/utils/unicode.h>
@@ -83,6 +83,7 @@ struct _NTLM_CONTEXT
UNICONV* uniconv;
int SendSeqNum;
int RecvSeqNum;
boolean confidentiality;
CryptoRc4 SendRc4Seal;
CryptoRc4 RecvRc4Seal;
uint8* SendSigningKey;

View File

@@ -241,7 +241,6 @@ SECURITY_STATUS ntlm_write_NegotiateMessage(NTLM_CONTEXT* context, PSecBuffer bu
NegotiateFlags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
NegotiateFlags |= NTLMSSP_NEGOTIATE_NTLM;
NegotiateFlags |= NTLMSSP_NEGOTIATE_LM_KEY;
NegotiateFlags |= NTLMSSP_NEGOTIATE_SEAL;
NegotiateFlags |= NTLMSSP_NEGOTIATE_SIGN;
NegotiateFlags |= NTLMSSP_REQUEST_TARGET;
NegotiateFlags |= NTLMSSP_NEGOTIATE_OEM;
@@ -254,12 +253,14 @@ SECURITY_STATUS ntlm_write_NegotiateMessage(NTLM_CONTEXT* context, PSecBuffer bu
NegotiateFlags |= NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY;
NegotiateFlags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
NegotiateFlags |= NTLMSSP_NEGOTIATE_NTLM;
NegotiateFlags |= NTLMSSP_NEGOTIATE_SEAL;
NegotiateFlags |= NTLMSSP_NEGOTIATE_SIGN;
NegotiateFlags |= NTLMSSP_REQUEST_TARGET;
NegotiateFlags |= NTLMSSP_NEGOTIATE_UNICODE;
}
if (context->confidentiality)
NegotiateFlags |= NTLMSSP_NEGOTIATE_SEAL;
context->NegotiateFlags = NegotiateFlags;
stream_write_uint32(s, NegotiateFlags); /* NegotiateFlags (4 bytes) */
@@ -964,7 +965,6 @@ SECURITY_STATUS ntlm_write_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
NegotiateFlags |= NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY;
NegotiateFlags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
NegotiateFlags |= NTLMSSP_NEGOTIATE_NTLM;
NegotiateFlags |= NTLMSSP_NEGOTIATE_SEAL;
NegotiateFlags |= NTLMSSP_NEGOTIATE_SIGN;
NegotiateFlags |= NTLMSSP_REQUEST_TARGET;
NegotiateFlags |= NTLMSSP_NEGOTIATE_UNICODE;
@@ -976,12 +976,14 @@ SECURITY_STATUS ntlm_write_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
NegotiateFlags |= NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY;
NegotiateFlags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
NegotiateFlags |= NTLMSSP_NEGOTIATE_NTLM;
NegotiateFlags |= NTLMSSP_NEGOTIATE_SEAL;
NegotiateFlags |= NTLMSSP_NEGOTIATE_SIGN;
NegotiateFlags |= NTLMSSP_REQUEST_TARGET;
NegotiateFlags |= NTLMSSP_NEGOTIATE_UNICODE;
}
if (context->confidentiality)
NegotiateFlags |= NTLMSSP_NEGOTIATE_SEAL;
if (context->ntlm_v2)
PayloadBufferOffset = 80; /* starting buffer offset */
else

View File

@@ -17,7 +17,7 @@
* limitations under the License.
*/
#include <freerdp/sspi/sspi.h>
#include <winpr//sspi.h>
#include <freerdp/utils/memory.h>
#include "negotiate.h"

View File

@@ -20,7 +20,7 @@
#ifndef FREERDP_SSPI_NEGOTIATE_PRIVATE_H
#define FREERDP_SSPI_NEGOTIATE_PRIVATE_H
#include <freerdp/sspi/sspi.h>
#include <winpr/sspi.h>
#include <freerdp/utils/unicode.h>
#include "../Kerberos/kerberos.h"

View File

@@ -26,8 +26,8 @@
#include <freerdp/crypto/tls.h>
#include <freerdp/utils/stream.h>
#include <freerdp/sspi/sspi.h>
#include <freerdp/sspi/credssp.h>
#include <winpr/sspi.h>
#include <winpr/credssp.h>
#include "sspi.h"

View File

@@ -19,7 +19,7 @@
#include <freerdp/utils/memory.h>
#include <freerdp/sspi/sspi.h>
#include <winpr/sspi.h>
#include "sspi.h"

View File

@@ -21,8 +21,9 @@
#define FREERDP_AUTH_SSPI_PRIVATE_H
#include "config.h"
#include <winpr/sspi.h>
#include <freerdp/types.h>
#include <freerdp/sspi/sspi.h>
struct _CREDENTIALS
{
@@ -33,9 +34,6 @@ typedef struct _CREDENTIALS CREDENTIALS;
CREDENTIALS* sspi_CredentialsNew();
void sspi_CredentialsFree(CREDENTIALS* credentials);
void sspi_SecBufferAlloc(PSecBuffer SecBuffer, size_t size);
void sspi_SecBufferFree(PSecBuffer SecBuffer);
SecHandle* sspi_SecureHandleAlloc();
void sspi_SecureHandleInit(SecHandle* handle);
void sspi_SecureHandleInvalidate(SecHandle* handle);