#define TAG FREERDP_TAG("core.gateway.ntlm")
-wStream* rpc_ntlm_http_request(rdpRpc* rpc, SecBuffer* ntlm_token, int content_length, TSG_CHANNEL channel)
+wStream* rpc_ntlm_http_request(rdpRpc* rpc, HttpContext* http, SecBuffer* ntlmToken, int contentLength, TSG_CHANNEL channel)
{
wStream* s;
- HttpContext* http_context;
- HttpRequest* http_request;
- char* base64_ntlm_token = NULL;
+ HttpRequest* request;
+ char* base64NtlmToken = NULL;
- http_request = http_request_new();
+ request = http_request_new();
- if (ntlm_token)
- base64_ntlm_token = crypto_base64_encode(ntlm_token->pvBuffer, ntlm_token->cbBuffer);
+ if (ntlmToken)
+ base64NtlmToken = crypto_base64_encode(ntlmToken->pvBuffer, ntlmToken->cbBuffer);
if (channel == TSG_CHANNEL_IN)
- {
- http_context = rpc->NtlmHttpIn->context;
- http_request_set_method(http_request, "RPC_IN_DATA");
- }
+ http_request_set_method(request, "RPC_IN_DATA");
else if (channel == TSG_CHANNEL_OUT)
- {
- http_context = rpc->NtlmHttpOut->context;
- http_request_set_method(http_request, "RPC_OUT_DATA");
- }
- else
- {
- return NULL;
- }
+ http_request_set_method(request, "RPC_OUT_DATA");
- http_request->ContentLength = content_length;
- http_request_set_uri(http_request, http_context->URI);
+ request->ContentLength = contentLength;
+ http_request_set_uri(request, http->URI);
- if (base64_ntlm_token)
+ if (base64NtlmToken)
{
- http_request_set_auth_scheme(http_request, "NTLM");
- http_request_set_auth_param(http_request, base64_ntlm_token);
+ http_request_set_auth_scheme(request, "NTLM");
+ http_request_set_auth_param(request, base64NtlmToken);
}
- s = http_request_write(http_context, http_request);
- http_request_free(http_request);
+ s = http_request_write(http, request);
+ http_request_free(request);
- free(base64_ntlm_token);
+ free(base64NtlmToken);
return s;
}
-int rpc_ncacn_http_send_in_channel_request(rdpRpc* rpc)
+int rpc_ncacn_http_send_in_channel_request(rdpRpc* rpc, RpcInChannel* inChannel)
{
wStream* s;
int status;
int contentLength;
BOOL continueNeeded;
- rdpNtlm* ntlm = rpc->NtlmHttpIn->ntlm;
+ rdpNtlm* ntlm = inChannel->ntlm;
+ HttpContext* http = inChannel->http;
continueNeeded = ntlm_authenticate(ntlm);
contentLength = (continueNeeded) ? 0 : 0x40000000;
- s = rpc_ntlm_http_request(rpc, &ntlm->outputBuffer[0], contentLength, TSG_CHANNEL_IN);
+ s = rpc_ntlm_http_request(rpc, http, &ntlm->outputBuffer[0], contentLength, TSG_CHANNEL_IN);
if (!s)
return -1;
return (status > 0) ? 1 : -1;
}
-int rpc_ncacn_http_recv_in_channel_response(rdpRpc* rpc, HttpResponse* response)
+int rpc_ncacn_http_recv_in_channel_response(rdpRpc* rpc, RpcInChannel* inChannel, HttpResponse* response)
{
char* token64 = NULL;
int ntlmTokenLength = 0;
BYTE* ntlmTokenData = NULL;
- rdpNtlm* ntlm = rpc->NtlmHttpIn->ntlm;
+ rdpNtlm* ntlm = inChannel->ntlm;
if (ListDictionary_Contains(response->Authenticates, "NTLM"))
{
if (channel == TSG_CHANNEL_IN)
{
- ntlm = rpc->NtlmHttpIn->ntlm;
tls = rpc->VirtualConnection->DefaultInChannel->tls;
+ ntlm = rpc->VirtualConnection->DefaultInChannel->ntlm;
}
else if (channel == TSG_CHANNEL_OUT)
{
- ntlm = rpc->NtlmHttpOut->ntlm;
tls = rpc->VirtualConnection->DefaultOutChannel->tls;
+ ntlm = rpc->VirtualConnection->DefaultOutChannel->ntlm;
}
if (!settings->GatewayPassword || !settings->GatewayUsername ||
{
if (channel == TSG_CHANNEL_IN)
{
- ntlm_client_uninit(rpc->NtlmHttpIn->ntlm);
- ntlm_free(rpc->NtlmHttpIn->ntlm);
- rpc->NtlmHttpIn->ntlm = NULL;
+ RpcInChannel* inChannel = rpc->VirtualConnection->DefaultInChannel;
+ ntlm_client_uninit(inChannel->ntlm);
+ ntlm_free(inChannel->ntlm);
+ inChannel->ntlm = NULL;
}
else if (channel == TSG_CHANNEL_OUT)
{
- ntlm_client_uninit(rpc->NtlmHttpOut->ntlm);
- ntlm_free(rpc->NtlmHttpOut->ntlm);
- rpc->NtlmHttpOut->ntlm = NULL;
+ RpcOutChannel* outChannel = rpc->VirtualConnection->DefaultOutChannel;
+ ntlm_client_uninit(outChannel->ntlm);
+ ntlm_free(outChannel->ntlm);
+ outChannel->ntlm = NULL;
}
}
-int rpc_ncacn_http_send_out_channel_request(rdpRpc* rpc)
+int rpc_ncacn_http_send_out_channel_request(rdpRpc* rpc, RpcOutChannel* outChannel)
{
wStream* s;
int status;
int contentLength;
BOOL continueNeeded;
- rdpNtlm* ntlm = rpc->NtlmHttpOut->ntlm;
+ rdpNtlm* ntlm = outChannel->ntlm;
+ HttpContext* http = outChannel->http;
continueNeeded = ntlm_authenticate(ntlm);
contentLength = (continueNeeded) ? 0 : 76;
- s = rpc_ntlm_http_request(rpc, &ntlm->outputBuffer[0], contentLength, TSG_CHANNEL_OUT);
+ s = rpc_ntlm_http_request(rpc, http, &ntlm->outputBuffer[0], contentLength, TSG_CHANNEL_OUT);
if (!s)
return -1;
return (status > 0) ? 1 : -1;
}
-int rpc_ncacn_http_recv_out_channel_response(rdpRpc* rpc, HttpResponse* response)
+int rpc_ncacn_http_recv_out_channel_response(rdpRpc* rpc, RpcOutChannel* outChannel, HttpResponse* response)
{
char* token64 = NULL;
int ntlmTokenLength = 0;
BYTE* ntlmTokenData = NULL;
- rdpNtlm* ntlm = rpc->NtlmHttpOut->ntlm;
+ rdpNtlm* ntlm = outChannel->ntlm;
if (ListDictionary_Contains(response->Authenticates, "NTLM"))
{
return 1;
}
-int rpc_http_send_replacement_out_channel_request(rdpRpc* rpc)
-{
- int status;
- wStream* s;
-
- s = rpc_ntlm_http_request(rpc, NULL, 120, TSG_CHANNEL_OUT);
-
- if (!s)
- return -1;
-
- WLog_DBG(TAG, "\n%s", Stream_Buffer(s));
-
- status = rpc_out_write(rpc, Stream_Buffer(s), Stream_Length(s));
-
- Stream_Free(s, TRUE);
-
- return (status > 0) ? 1 : -1;
-}
-
-void rpc_ntlm_http_init_channel(rdpRpc* rpc, rdpNtlmHttp* ntlm_http, TSG_CHANNEL channel)
+void rpc_ntlm_http_init_channel(rdpRpc* rpc, HttpContext* http, TSG_CHANNEL channel)
{
if (channel == TSG_CHANNEL_IN)
- http_context_set_method(ntlm_http->context, "RPC_IN_DATA");
+ http_context_set_method(http, "RPC_IN_DATA");
else if (channel == TSG_CHANNEL_OUT)
- http_context_set_method(ntlm_http->context, "RPC_OUT_DATA");
+ http_context_set_method(http, "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->GatewayHostname);
+ 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(ntlm_http->context,
+ http_context_set_pragma(http,
"ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729");
}
else if (channel == TSG_CHANNEL_OUT)
{
- http_context_set_pragma(ntlm_http->context,
+ http_context_set_pragma(http,
"ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729, "
"SessionId=fbd9c34f-397d-471d-a109-1b08cc554624");
}
}
-
-rdpNtlmHttp* ntlm_http_new()
-{
- rdpNtlmHttp* ntlm_http;
-
- ntlm_http = (rdpNtlmHttp*) calloc(1, sizeof(rdpNtlmHttp));
-
- if (!ntlm_http)
- return NULL;
-
- ntlm_http->ntlm = ntlm_new();
-
- if (!ntlm_http->ntlm)
- goto out_free;
-
- ntlm_http->context = http_context_new();
-
- if (!ntlm_http->context)
- goto out_free_ntlm;
-
- return ntlm_http;
-
-out_free_ntlm:
- ntlm_free(ntlm_http->ntlm);
-out_free:
- free(ntlm_http);
- return NULL;
-}
-
-void ntlm_http_free(rdpNtlmHttp* ntlm_http)
-{
- if (!ntlm_http)
- return;
-
- ntlm_free(ntlm_http->ntlm);
- http_context_free(ntlm_http->context);
-
- free(ntlm_http);
-}
/* Send IN Channel Request */
- if (rpc_ncacn_http_send_in_channel_request(rpc) < 0)
+ if (rpc_ncacn_http_send_in_channel_request(rpc, inChannel) < 0)
{
WLog_ERR(TAG, "rpc_ncacn_http_send_in_channel_request failure");
return FALSE;
/* Send OUT Channel Request */
- if (rpc_ncacn_http_send_out_channel_request(rpc) < 0)
+ if (rpc_ncacn_http_send_out_channel_request(rpc, outChannel) < 0)
{
WLog_ERR(TAG, "rpc_ncacn_http_send_out_channel_request failure");
return FALSE;
return status;
}
+int rpc_client_in_channel_rpch_init(rdpRpc* rpc, RpcInChannel* inChannel)
+{
+ inChannel->ntlm = ntlm_new();
+
+ if (!inChannel->ntlm)
+ return -1;
+
+ inChannel->http = http_context_new();
+
+ if (!inChannel->http)
+ return -1;
+
+ rpc_ntlm_http_init_channel(rpc, inChannel->http, TSG_CHANNEL_IN);
+
+ return 1;
+}
+
+void rpc_client_in_channel_rpch_uninit(RpcInChannel* inChannel)
+{
+ if (inChannel->ntlm)
+ {
+ ntlm_free(inChannel->ntlm);
+ inChannel->ntlm = NULL;
+ }
+
+ if (inChannel->http)
+ {
+ http_context_free(inChannel->http);
+ inChannel->http = NULL;
+ }
+}
+
+RpcInChannel* rpc_client_in_channel_new(rdpRpc* rpc)
+{
+ RpcInChannel* inChannel = NULL;
+
+ inChannel = (RpcInChannel*) calloc(1, sizeof(RpcInChannel));
+
+ if (inChannel)
+ {
+
+ }
+
+ return inChannel;
+}
+
+void rpc_client_in_channel_free(RpcInChannel* inChannel)
+{
+ if (!inChannel)
+ return;
+
+ rpc_client_in_channel_rpch_uninit(inChannel);
+
+ free(inChannel);
+}
+
int rpc_client_out_channel_transition_to_state(RpcOutChannel* outChannel, CLIENT_OUT_CHANNEL_STATE state)
{
int status = 1;
return status;
}
+int rpc_client_out_channel_rpch_init(rdpRpc* rpc, RpcOutChannel* outChannel)
+{
+ outChannel->ntlm = ntlm_new();
+
+ if (!outChannel->ntlm)
+ return -1;
+
+ outChannel->http = http_context_new();
+
+ if (!outChannel->http)
+ return -1;
+
+ rpc_ntlm_http_init_channel(rpc, outChannel->http, TSG_CHANNEL_OUT);
+
+ return 1;
+}
+
+void rpc_client_out_channel_rpch_uninit(RpcOutChannel* outChannel)
+{
+ if (outChannel->ntlm)
+ {
+ ntlm_free(outChannel->ntlm);
+ outChannel->ntlm = NULL;
+ }
+
+ if (outChannel->http)
+ {
+ http_context_free(outChannel->http);
+ outChannel->http = NULL;
+ }
+}
+
+RpcOutChannel* rpc_client_out_channel_new(rdpRpc* rpc)
+{
+ RpcOutChannel* outChannel = NULL;
+
+ outChannel = (RpcOutChannel*) calloc(1, sizeof(RpcOutChannel));
+
+ if (outChannel)
+ {
+
+ }
+
+ return outChannel;
+}
+
+void rpc_client_out_channel_free(RpcOutChannel* outChannel)
+{
+ if (!outChannel)
+ return;
+
+ rpc_client_out_channel_rpch_uninit(outChannel);
+
+ free(outChannel);
+}
+
int rpc_client_virtual_connection_transition_to_state(rdpRpc* rpc,
RpcVirtualConnection* connection, VIRTUAL_CONNECTION_STATE state)
{
connection->DefaultInChannel->PingOriginator.KeepAliveInterval = 0;
rts_generate_cookie((BYTE*) &(connection->DefaultInChannelCookie));
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->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)
connection->State = VIRTUAL_CONNECTION_STATE_INITIAL;
- connection->DefaultInChannel = (RpcInChannel*) calloc(1, sizeof(RpcInChannel));
+ connection->DefaultInChannel = rpc_client_in_channel_new(rpc);
if (!connection->DefaultInChannel)
goto out_free;
- connection->DefaultOutChannel = (RpcOutChannel*) calloc(1, sizeof(RpcOutChannel));
+ connection->DefaultOutChannel = rpc_client_out_channel_new(rpc);
if (!connection->DefaultOutChannel)
goto out_default_in;
void rpc_client_virtual_connection_free(RpcVirtualConnection* virtualConnection)
{
- if (virtualConnection)
- {
- free(virtualConnection->DefaultInChannel);
- free(virtualConnection->DefaultOutChannel);
- free(virtualConnection);
- }
+ if (!virtualConnection)
+ return;
+
+ rpc_client_in_channel_free(virtualConnection->DefaultInChannel);
+ rpc_client_out_channel_free(virtualConnection->DefaultOutChannel);
+
+ free(virtualConnection);
}
rdpRpc* rpc_new(rdpTransport* transport)
if (!rpc->ntlm)
goto out_free;
- rpc->NtlmHttpIn = ntlm_http_new();
-
- if (!rpc->NtlmHttpIn)
- goto out_free_ntlm;
-
- rpc->NtlmHttpOut = ntlm_http_new();
-
- if (!rpc->NtlmHttpOut)
- goto out_free_ntlm_http_in;
-
- rpc_ntlm_http_init_channel(rpc, rpc->NtlmHttpIn, TSG_CHANNEL_IN);
- rpc_ntlm_http_init_channel(rpc, rpc->NtlmHttpOut, TSG_CHANNEL_OUT);
-
rpc->PipeCallId = 0;
rpc->StubCallId = 0;
rpc->StubFragCount = 0;
rpc->VirtualConnection = rpc_client_virtual_connection_new(rpc);
if (!rpc->VirtualConnection)
- goto out_free_ntlm_http_out;
-
- rpc->VirtualConnectionCookieTable = ArrayList_New(TRUE);
-
- if (!rpc->VirtualConnectionCookieTable)
goto out_free_virtual_connection;
rpc->CallId = 2;
if (rpc_client_new(rpc) < 0)
- goto out_free_virtualConnectionCookieTable;
+ goto out_free_rpc_client;
return rpc;
-out_free_virtualConnectionCookieTable:
+out_free_rpc_client:
rpc_client_free(rpc);
- ArrayList_Free(rpc->VirtualConnectionCookieTable);
out_free_virtual_connection:
rpc_client_virtual_connection_free(rpc->VirtualConnection);
-out_free_ntlm_http_out:
- ntlm_http_free(rpc->NtlmHttpOut);
-out_free_ntlm_http_in:
- ntlm_http_free(rpc->NtlmHttpIn);
-out_free_ntlm:
- ntlm_free(rpc->ntlm);
out_free:
free(rpc);
return NULL;
rpc->ntlm = NULL;
}
- if (rpc->NtlmHttpIn)
- {
- ntlm_http_free(rpc->NtlmHttpIn);
- rpc->NtlmHttpIn = NULL;
- }
-
- if (rpc->NtlmHttpOut)
- {
- ntlm_http_free(rpc->NtlmHttpOut);
- rpc->NtlmHttpOut = NULL;
- }
-
rpc_client_virtual_connection_free(rpc->VirtualConnection);
- ArrayList_Clear(rpc->VirtualConnectionCookieTable);
- ArrayList_Free(rpc->VirtualConnectionCookieTable);
free(rpc);
}