mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
Merge pull request #579 from FreeRDP/tsg
Terminal Server Gateway (Round 1)
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <freerdp/utils/windows.h>
|
||||
#include <winpr/windows.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
28
include/winpr/midl.h
Normal 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
530
include/winpr/ndr.h
Normal 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
45
include/winpr/rpc.h
Normal 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 */
|
||||
@@ -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 */
|
||||
@@ -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
52
include/winpr/winpr.h
Normal 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 */
|
||||
@@ -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 */
|
||||
@@ -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})
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
432
libfreerdp-core/http.c
Normal 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
101
libfreerdp-core/http.h
Normal 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
990
libfreerdp-core/rpc.c
Normal 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
703
libfreerdp-core/rpc.h
Normal 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
709
libfreerdp-core/rts.c
Normal 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
168
libfreerdp-core/rts.h
Normal 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 */
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
2032
libfreerdp-core/tsg.c
Normal file
File diff suppressed because it is too large
Load Diff
279
libfreerdp-core/tsg.h
Normal file
279
libfreerdp-core/tsg.h
Normal 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 */
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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++;
|
||||
|
||||
@@ -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 "/"
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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__
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <freerdp/utils/windows.h>
|
||||
#include <winpr/windows.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef _MSC_VER
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
49
libwinpr-rpc/CMakeLists.txt
Normal file
49
libwinpr-rpc/CMakeLists.txt
Normal 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
33
libwinpr-rpc/midl.c
Normal 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
342
libwinpr-rpc/ndr.c
Normal 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 = ¶m->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, ¶ms[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
137
libwinpr-rpc/ndr_array.c
Normal 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
31
libwinpr-rpc/ndr_array.h
Normal 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 */
|
||||
66
libwinpr-rpc/ndr_context.c
Normal file
66
libwinpr-rpc/ndr_context.c
Normal 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);
|
||||
}
|
||||
}
|
||||
27
libwinpr-rpc/ndr_context.h
Normal file
27
libwinpr-rpc/ndr_context.h
Normal 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 */
|
||||
187
libwinpr-rpc/ndr_correlation.c
Normal file
187
libwinpr-rpc/ndr_correlation.c
Normal 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;
|
||||
}
|
||||
29
libwinpr-rpc/ndr_correlation.h
Normal file
29
libwinpr-rpc/ndr_correlation.h
Normal 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
322
libwinpr-rpc/ndr_pointer.c
Normal 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");
|
||||
}
|
||||
37
libwinpr-rpc/ndr_pointer.h
Normal file
37
libwinpr-rpc/ndr_pointer.h
Normal 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
552
libwinpr-rpc/ndr_private.c
Normal 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 */
|
||||
};
|
||||
42
libwinpr-rpc/ndr_private.h
Normal file
42
libwinpr-rpc/ndr_private.h
Normal 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
193
libwinpr-rpc/ndr_simple.c
Normal 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
35
libwinpr-rpc/ndr_simple.h
Normal 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
35
libwinpr-rpc/ndr_string.c
Normal 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
28
libwinpr-rpc/ndr_string.h
Normal 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 */
|
||||
313
libwinpr-rpc/ndr_structure.c
Normal file
313
libwinpr-rpc/ndr_structure.c
Normal 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;
|
||||
}
|
||||
}
|
||||
30
libwinpr-rpc/ndr_structure.h
Normal file
30
libwinpr-rpc/ndr_structure.h
Normal 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
35
libwinpr-rpc/ndr_union.c
Normal 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
28
libwinpr-rpc/ndr_union.h
Normal 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
27
libwinpr-rpc/rpc.c
Normal 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);
|
||||
}
|
||||
@@ -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})
|
||||
|
||||
@@ -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>
|
||||
@@ -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"
|
||||
@@ -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
|
||||
@@ -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;
|
||||
@@ -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
|
||||
@@ -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"
|
||||
@@ -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"
|
||||
@@ -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"
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#include <freerdp/utils/memory.h>
|
||||
|
||||
#include <freerdp/sspi/sspi.h>
|
||||
#include <winpr/sspi.h>
|
||||
|
||||
#include "sspi.h"
|
||||
|
||||
@@ -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);
|
||||
Reference in New Issue
Block a user