#define TAG FREERDP_TAG("core.gateway.ntlm")
-wStream* rpc_ntlm_http_request(rdpRpc* rpc, HttpContext* http, SecBuffer* ntlmToken, int contentLength, TSG_CHANNEL channel)
+wStream* rpc_ntlm_http_request(rdpRpc* rpc, HttpContext* http, const char* method, int contentLength, SecBuffer* ntlmToken)
{
wStream* s;
HttpRequest* request;
if (ntlmToken)
base64NtlmToken = crypto_base64_encode(ntlmToken->pvBuffer, ntlmToken->cbBuffer);
- if (channel == TSG_CHANNEL_IN)
- http_request_set_method(request, "RPC_IN_DATA");
- else if (channel == TSG_CHANNEL_OUT)
- http_request_set_method(request, "RPC_OUT_DATA");
+ http_request_set_method(request, method);
request->ContentLength = contentLength;
http_request_set_uri(request, http->URI);
contentLength = (continueNeeded) ? 0 : 0x40000000;
- s = rpc_ntlm_http_request(rpc, http, &ntlm->outputBuffer[0], contentLength, TSG_CHANNEL_IN);
+ s = rpc_ntlm_http_request(rpc, http, "RPC_IN_DATA", contentLength, &ntlm->outputBuffer[0]);
if (!s)
return -1;
return 1;
}
-int rpc_ncacn_http_ntlm_init(rdpRpc* rpc, TSG_CHANNEL channel)
+int rpc_ncacn_http_ntlm_init(rdpRpc* rpc, RpcChannel* channel)
{
- rdpTls* tls = NULL;
- rdpNtlm* ntlm = NULL;
+ rdpTls* tls = channel->tls;
+ rdpNtlm* ntlm = channel->ntlm;
rdpContext* context = rpc->context;
rdpSettings* settings = rpc->settings;
freerdp* instance = context->instance;
- if (channel == TSG_CHANNEL_IN)
- {
- tls = rpc->VirtualConnection->DefaultInChannel->tls;
- ntlm = rpc->VirtualConnection->DefaultInChannel->ntlm;
- }
- else if (channel == TSG_CHANNEL_OUT)
- {
- tls = rpc->VirtualConnection->DefaultOutChannel->tls;
- ntlm = rpc->VirtualConnection->DefaultOutChannel->ntlm;
- }
-
if (!settings->GatewayPassword || !settings->GatewayUsername ||
!strlen(settings->GatewayPassword) || !strlen(settings->GatewayUsername))
{
return 1;
}
-void rpc_ncacn_http_ntlm_uninit(rdpRpc* rpc, TSG_CHANNEL channel)
+void rpc_ncacn_http_ntlm_uninit(rdpRpc* rpc, RpcChannel* channel)
{
- if (channel == TSG_CHANNEL_IN)
- {
- RpcInChannel* inChannel = rpc->VirtualConnection->DefaultInChannel;
- ntlm_client_uninit(inChannel->ntlm);
- ntlm_free(inChannel->ntlm);
- inChannel->ntlm = NULL;
- }
- else if (channel == TSG_CHANNEL_OUT)
- {
- RpcOutChannel* outChannel = rpc->VirtualConnection->DefaultOutChannel;
- ntlm_client_uninit(outChannel->ntlm);
- ntlm_free(outChannel->ntlm);
- outChannel->ntlm = NULL;
- }
+ ntlm_client_uninit(channel->ntlm);
+ ntlm_free(channel->ntlm);
+ channel->ntlm = NULL;
}
-int rpc_ncacn_http_send_out_channel_request(rdpRpc* rpc, RpcOutChannel* outChannel)
+int rpc_ncacn_http_send_out_channel_request(rdpRpc* rpc, RpcOutChannel* outChannel, BOOL replacement)
{
wStream* s;
int status;
continueNeeded = ntlm_authenticate(ntlm);
- contentLength = (continueNeeded) ? 0 : 76;
+ if (!replacement)
+ contentLength = (continueNeeded) ? 0 : 76;
+ else
+ contentLength = (continueNeeded) ? 0 : 120;
- s = rpc_ntlm_http_request(rpc, http, &ntlm->outputBuffer[0], contentLength, TSG_CHANNEL_OUT);
+ s = rpc_ntlm_http_request(rpc, http, "RPC_OUT_DATA", contentLength, &ntlm->outputBuffer[0]);
if (!s)
return -1;
return 1;
}
-
-void rpc_ntlm_http_init_channel(rdpRpc* rpc, HttpContext* http, TSG_CHANNEL channel)
-{
- if (channel == TSG_CHANNEL_IN)
- http_context_set_method(http, "RPC_IN_DATA");
- else if (channel == TSG_CHANNEL_OUT)
- http_context_set_method(http, "RPC_OUT_DATA");
-
- http_context_set_uri(http, "/rpc/rpcproxy.dll?localhost:3388");
- http_context_set_accept(http, "application/rpc");
- http_context_set_cache_control(http, "no-cache");
- http_context_set_connection(http, "Keep-Alive");
- http_context_set_user_agent(http, "MSRPC");
- http_context_set_host(http, rpc->settings->GatewayHostname);
-
- if (channel == TSG_CHANNEL_IN)
- {
- http_context_set_pragma(http,
- "ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729");
- }
- else if (channel == TSG_CHANNEL_OUT)
- {
- http_context_set_pragma(http,
- "ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729, "
- "SessionId=fbd9c34f-397d-471d-a109-1b08cc554624");
- }
-}
#include "rpc.h"
#include "http.h"
-int rpc_ncacn_http_ntlm_init(rdpRpc* rpc, TSG_CHANNEL channel);
-void rpc_ncacn_http_ntlm_uninit(rdpRpc* rpc, TSG_CHANNEL channel);
+int rpc_ncacn_http_ntlm_init(rdpRpc* rpc, RpcChannel* channel);
+void rpc_ncacn_http_ntlm_uninit(rdpRpc* rpc, RpcChannel* channel);
int rpc_ncacn_http_send_in_channel_request(rdpRpc* rpc, RpcInChannel* inChannel);
int rpc_ncacn_http_recv_in_channel_response(rdpRpc* rpc, RpcInChannel* inChannel, HttpResponse* response);
-int rpc_ncacn_http_send_out_channel_request(rdpRpc* rpc, RpcOutChannel* outChannel);
+int rpc_ncacn_http_send_out_channel_request(rdpRpc* rpc, RpcOutChannel* outChannel, BOOL replacement);
int rpc_ncacn_http_recv_out_channel_response(rdpRpc* rpc, RpcOutChannel* outChannel, HttpResponse* response);
-void rpc_ntlm_http_init_channel(rdpRpc* rpc, HttpContext* http, TSG_CHANNEL channel);
-
#endif
rpc_client_in_channel_transition_to_state(inChannel, CLIENT_IN_CHANNEL_STATE_CONNECTED);
- if (rpc_ncacn_http_ntlm_init(rpc, TSG_CHANNEL_IN) < 0)
+ if (rpc_ncacn_http_ntlm_init(rpc, (RpcChannel*) inChannel) < 0)
return FALSE;
/* Send IN Channel Request */
rpc_client_out_channel_transition_to_state(outChannel, CLIENT_OUT_CHANNEL_STATE_CONNECTED);
- if (rpc_ncacn_http_ntlm_init(rpc, TSG_CHANNEL_OUT) < 0)
+ if (rpc_ncacn_http_ntlm_init(rpc, (RpcChannel*) outChannel) < 0)
return FALSE;
/* Send OUT Channel Request */
- if (rpc_ncacn_http_send_out_channel_request(rpc, outChannel) < 0)
+ if (rpc_ncacn_http_send_out_channel_request(rpc, outChannel, FALSE) < 0)
{
WLog_ERR(TAG, "rpc_ncacn_http_send_out_channel_request failure");
return FALSE;
int rpc_client_in_channel_rpch_init(rdpRpc* rpc, RpcInChannel* inChannel)
{
+ HttpContext* http;
+
inChannel->ntlm = ntlm_new();
if (!inChannel->ntlm)
if (!inChannel->http)
return -1;
- rpc_ntlm_http_init_channel(rpc, inChannel->http, TSG_CHANNEL_IN);
+ http = inChannel->http;
+
+ http_context_set_method(http, "RPC_IN_DATA");
+
+ http_context_set_uri(http, "/rpc/rpcproxy.dll?localhost:3388");
+ http_context_set_accept(http, "application/rpc");
+ http_context_set_cache_control(http, "no-cache");
+ http_context_set_connection(http, "Keep-Alive");
+ http_context_set_user_agent(http, "MSRPC");
+ http_context_set_host(http, rpc->settings->GatewayHostname);
+
+ http_context_set_pragma(http, "ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729");
+
+ return 1;
+}
+
+int rpc_client_in_channel_init(rdpRpc* rpc, RpcInChannel* inChannel)
+{
+ rts_generate_cookie((BYTE*) &inChannel->Cookie);
+
+ inChannel->State = CLIENT_IN_CHANNEL_STATE_INITIAL;
+ inChannel->BytesSent = 0;
+ inChannel->SenderAvailableWindow = rpc->ReceiveWindow;
+ inChannel->PingOriginator.ConnectionTimeout = 30;
+ inChannel->PingOriginator.KeepAliveInterval = 0;
+
+ if (rpc_client_in_channel_rpch_init(rpc, inChannel) < 0)
+ return -1;
return 1;
}
int rpc_client_out_channel_rpch_init(rdpRpc* rpc, RpcOutChannel* outChannel)
{
+ HttpContext* http;
+
outChannel->ntlm = ntlm_new();
if (!outChannel->ntlm)
if (!outChannel->http)
return -1;
- rpc_ntlm_http_init_channel(rpc, outChannel->http, TSG_CHANNEL_OUT);
+ http = outChannel->http;
+
+ http_context_set_method(http, "RPC_OUT_DATA");
+
+ http_context_set_uri(http, "/rpc/rpcproxy.dll?localhost:3388");
+ http_context_set_accept(http, "application/rpc");
+ http_context_set_cache_control(http, "no-cache");
+ http_context_set_connection(http, "Keep-Alive");
+ http_context_set_user_agent(http, "MSRPC");
+ http_context_set_host(http, rpc->settings->GatewayHostname);
+
+ http_context_set_pragma(http,
+ "ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729, "
+ "SessionId=fbd9c34f-397d-471d-a109-1b08cc554624");
+
+ return 1;
+}
+
+int rpc_client_out_channel_init(rdpRpc* rpc, RpcOutChannel* outChannel)
+{
+ rts_generate_cookie((BYTE*) &outChannel->Cookie);
+
+ outChannel->State = CLIENT_OUT_CHANNEL_STATE_INITIAL;
+ outChannel->BytesReceived = 0;
+ outChannel->ReceiverAvailableWindow = rpc->ReceiveWindow;
+ outChannel->ReceiveWindow = rpc->ReceiveWindow;
+ outChannel->ReceiveWindowSize = rpc->ReceiveWindow;
+ outChannel->AvailableWindowAdvertised = rpc->ReceiveWindow;
+
+ if (rpc_client_out_channel_rpch_init(rpc, outChannel) < 0)
+ return -1;
return 1;
}
rts_generate_cookie((BYTE*) &(connection->Cookie));
rts_generate_cookie((BYTE*) &(connection->AssociationGroupId));
- connection->DefaultInChannel->State = CLIENT_IN_CHANNEL_STATE_INITIAL;
- connection->DefaultInChannel->BytesSent = 0;
- connection->DefaultInChannel->SenderAvailableWindow = rpc->ReceiveWindow;
- connection->DefaultInChannel->PingOriginator.ConnectionTimeout = 30;
- connection->DefaultInChannel->PingOriginator.KeepAliveInterval = 0;
- rts_generate_cookie((BYTE*) &(connection->DefaultInChannelCookie));
+ rpc_client_in_channel_init(rpc, connection->DefaultInChannel);
+ rpc_client_out_channel_init(rpc, connection->DefaultOutChannel);
+
rts_generate_cookie((BYTE*) &(connection->NonDefaultInChannelCookie));
- rpc_client_in_channel_rpch_init(rpc, connection->DefaultInChannel);
-
- connection->DefaultOutChannel->State = CLIENT_OUT_CHANNEL_STATE_INITIAL;
- connection->DefaultOutChannel->BytesReceived = 0;
- connection->DefaultOutChannel->ReceiverAvailableWindow = rpc->ReceiveWindow;
- connection->DefaultOutChannel->ReceiveWindow = rpc->ReceiveWindow;
- connection->DefaultOutChannel->ReceiveWindowSize = rpc->ReceiveWindow;
- connection->DefaultOutChannel->AvailableWindowAdvertised = rpc->ReceiveWindow;
- rts_generate_cookie((BYTE*) &(connection->DefaultOutChannelCookie));
rts_generate_cookie((BYTE*) &(connection->NonDefaultOutChannelCookie));
- rpc_client_out_channel_rpch_init(rpc, connection->DefaultOutChannel);
}
RpcVirtualConnection* rpc_client_virtual_connection_new(rdpRpc* rpc)
};
typedef struct rpc_client_call RpcClientCall;
-enum _TSG_CHANNEL
+#define RPC_CHANNEL_COMMON() \
+ rdpTcp* tcp; \
+ rdpTls* tls; \
+ rdpNtlm* ntlm; \
+ HttpContext* http; \
+ BYTE Cookie[16]
+
+struct rpc_channel
{
- TSG_CHANNEL_IN,
- TSG_CHANNEL_OUT
+ RPC_CHANNEL_COMMON();
};
-typedef enum _TSG_CHANNEL TSG_CHANNEL;
+typedef struct rpc_channel RpcChannel;
/* Ping Originator */
{
/* Sending Channel */
- rdpTcp* tcp;
- rdpTls* tls;
- rdpNtlm* ntlm;
- HttpContext* http;
+ RPC_CHANNEL_COMMON();
CLIENT_IN_CHANNEL_STATE State;
struct rpc_out_channel
{
- rdpTcp* tcp;
- rdpTls* tls;
- rdpNtlm* ntlm;
- HttpContext* http;
-
/* Receiving Channel */
+ RPC_CHANNEL_COMMON();
+
CLIENT_OUT_CHANNEL_STATE State;
UINT32 ReceiveWindow;
struct rpc_virtual_connection
{
BYTE Cookie[16]; /* Virtual Connection Cookie */
+ BYTE AssociationGroupId[16]; /* AssociationGroupId */
VIRTUAL_CONNECTION_STATE State; /* Virtual Connection State */
RpcInChannel* DefaultInChannel; /* Default IN Channel */
RpcInChannel* NonDefaultInChannel; /* Non-Default IN Channel */
- BYTE DefaultInChannelCookie[16]; /* Default IN Channel Cookie */
BYTE NonDefaultInChannelCookie[16]; /* Non-Default Default IN Channel Cookie */
RpcOutChannel* DefaultOutChannel; /* Default OUT Channel */
RpcOutChannel* NonDefaultOutChannel; /* Non-Default OUT Channel */
- BYTE DefaultOutChannelCookie[16]; /* Default OUT Channel Cookie */
BYTE NonDefaultOutChannelCookie[16]; /* Non-Default Default OUT Channel Cookie */
- BYTE AssociationGroupId[16]; /* AssociationGroupId */
};
typedef struct rpc_virtual_connection RpcVirtualConnection;
/* Send OUT Channel Request */
- if (rpc_ncacn_http_send_out_channel_request(rpc, outChannel) < 0)
+ if (rpc_ncacn_http_send_out_channel_request(rpc, outChannel, FALSE) < 0)
{
WLog_ERR(TAG, "rpc_ncacn_http_send_out_channel_request failure");
return -1;
}
- rpc_ncacn_http_ntlm_uninit(rpc, TSG_CHANNEL_OUT);
+ rpc_ncacn_http_ntlm_uninit(rpc, (RpcChannel*) outChannel);
rpc_client_out_channel_transition_to_state(outChannel,
CLIENT_OUT_CHANNEL_STATE_NEGOTIATED);
return -1;
}
- rpc_ncacn_http_ntlm_uninit(rpc, TSG_CHANNEL_IN);
+ rpc_ncacn_http_ntlm_uninit(rpc, (RpcChannel*) inChannel);
rpc_client_in_channel_transition_to_state(inChannel,
CLIENT_IN_CHANNEL_STATE_NEGOTIATED);
WLog_DBG(TAG, "Sending CONN_A1 RTS PDU");
VirtualConnectionCookie = (BYTE*) &(rpc->VirtualConnection->Cookie);
- OUTChannelCookie = (BYTE*) &(rpc->VirtualConnection->DefaultOutChannelCookie);
+ OUTChannelCookie = (BYTE*) &(rpc->VirtualConnection->DefaultOutChannel->Cookie);
ReceiveWindowSize = rpc->VirtualConnection->DefaultOutChannel->ReceiveWindow;
buffer = (BYTE*) malloc(header.frag_length);
WLog_DBG(TAG, "Sending CONN_B1 RTS PDU");
VirtualConnectionCookie = (BYTE*) &(rpc->VirtualConnection->Cookie);
- INChannelCookie = (BYTE*) &(rpc->VirtualConnection->DefaultInChannelCookie);
+ INChannelCookie = (BYTE*) &(rpc->VirtualConnection->DefaultInChannel->Cookie);
AssociationGroupId = (BYTE*) &(rpc->VirtualConnection->AssociationGroupId);
buffer = (BYTE*) malloc(header.frag_length);
BytesReceived = rpc->VirtualConnection->DefaultOutChannel->BytesReceived;
AvailableWindow = rpc->VirtualConnection->DefaultOutChannel->AvailableWindowAdvertised;
- ChannelCookie = (BYTE*) &(rpc->VirtualConnection->DefaultOutChannelCookie);
+ ChannelCookie = (BYTE*) &(rpc->VirtualConnection->DefaultOutChannel->Cookie);
rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow =
rpc->VirtualConnection->DefaultOutChannel->AvailableWindowAdvertised;
WLog_DBG(TAG, "Sending OUT R1/A3 RTS PDU");
VirtualConnectionCookie = (BYTE*) &(rpc->VirtualConnection->Cookie);
- PredecessorChannelCookie = (BYTE*) &(rpc->VirtualConnection->DefaultOutChannelCookie);
+ PredecessorChannelCookie = (BYTE*) &(rpc->VirtualConnection->DefaultOutChannel->Cookie);
SuccessorChannelCookie = (BYTE*) &(rpc->VirtualConnection->NonDefaultOutChannelCookie);
ReceiveWindowSize = rpc->VirtualConnection->DefaultOutChannel->ReceiveWindow;