[core,gateway] rpc use generated session id

This commit is contained in:
Armin Novak 2023-11-02 10:57:47 +01:00 committed by akallabeth
parent f1ddc19806
commit e451b4cad1
6 changed files with 123 additions and 41 deletions

View File

@ -302,18 +302,64 @@ BOOL http_context_set_connection(HttpContext* context, const char* Connection)
return TRUE;
}
BOOL http_context_set_pragma(HttpContext* context, const char* Pragma)
WINPR_ATTR_FORMAT_ARG(2, 0)
static BOOL list_append(HttpContext* context, WINPR_FORMAT_ARG const char* str, va_list ap)
{
BOOL rc = FALSE;
va_list vat;
char* Pragma = NULL;
size_t PragmaSize = 0;
va_copy(vat, ap);
const int size = winpr_vasprintf(&Pragma, &PragmaSize, str, ap);
va_end(vat);
if (size <= 0)
goto fail;
char* sstr = NULL;
size_t slen = 0;
if (context->Pragma)
{
winpr_asprintf(&sstr, &slen, "%s, %s", context->Pragma, Pragma);
free(Pragma);
}
else
sstr = Pragma;
free(context->Pragma);
context->Pragma = sstr;
rc = TRUE;
fail:
va_end(ap);
return rc;
}
WINPR_ATTR_FORMAT_ARG(2, 3)
BOOL http_context_set_pragma(HttpContext* context, WINPR_FORMAT_ARG const char* Pragma, ...)
{
if (!context || !Pragma)
return FALSE;
free(context->Pragma);
context->Pragma = _strdup(Pragma);
context->Pragma = NULL;
if (!context->Pragma)
va_list ap;
va_start(ap, Pragma);
return list_append(context, Pragma, ap);
}
WINPR_ATTR_FORMAT_ARG(2, 3)
BOOL http_context_append_pragma(HttpContext* context, const char* Pragma, ...)
{
if (!context || !Pragma)
return FALSE;
return TRUE;
va_list ap;
va_start(ap, Pragma);
return list_append(context, Pragma, ap);
}
static char* guid2str(const GUID* guid)
@ -325,7 +371,7 @@ static char* guid2str(const GUID* guid)
RPC_STATUS rpcStatus = UuidToStringA(guid, &strguid);
if (rpcStatus == RPC_S_OUT_OF_MEMORY)
if (rpcStatus != RPC_S_OK)
return NULL;
sprintf_s(bracedGuid, sizeof(bracedGuid), "{%s}", strguid);

View File

@ -65,7 +65,10 @@ FREERDP_LOCAL BOOL http_context_set_host(HttpContext* context, const char* Host)
FREERDP_LOCAL BOOL http_context_set_accept(HttpContext* context, const char* Accept);
FREERDP_LOCAL BOOL http_context_set_cache_control(HttpContext* context, const char* CacheControl);
FREERDP_LOCAL BOOL http_context_set_connection(HttpContext* context, const char* Connection);
FREERDP_LOCAL BOOL http_context_set_pragma(HttpContext* context, const char* Pragma);
FREERDP_LOCAL BOOL http_context_set_pragma(HttpContext* context,
WINPR_FORMAT_ARG const char* Pragma, ...);
FREERDP_LOCAL BOOL http_context_append_pragma(HttpContext* context,
WINPR_FORMAT_ARG const char* Pragma, ...);
FREERDP_LOCAL BOOL http_context_set_cookie(HttpContext* context, const char* CookieName,
const char* CookieValue);
FREERDP_LOCAL BOOL http_context_set_rdg_connection_id(HttpContext* context,

View File

@ -491,10 +491,12 @@ BOOL rpc_in_channel_transition_to_state(RpcInChannel* inChannel, CLIENT_IN_CHANN
return TRUE;
}
static int rpc_channel_rpch_init(RpcClient* client, RpcChannel* channel, const char* inout)
static int rpc_channel_rpch_init(RpcClient* client, RpcChannel* channel, const char* inout,
const GUID* guid)
{
HttpContext* http;
rdpSettings* settings;
UINT32 timeout = 0;
if (!client || !channel || !inout || !client->context || !client->context->settings)
return -1;
@ -514,21 +516,49 @@ static int rpc_channel_rpch_init(RpcClient* client, RpcChannel* channel, const c
http = channel->http;
{
if (!http_context_set_pragma(http, "ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729"))
return -1;
if (guid)
{
char bracedguid[64] = { 0 };
char* strguid = NULL;
RPC_STATUS rpcStatus = UuidToStringA(guid, &strguid);
if (rpcStatus != RPC_S_OK)
return -1;
const BOOL rc = http_context_append_pragma(http, "SessionId=%s", strguid);
RpcStringFreeA(&strguid);
if (!rc)
return -1;
}
if (timeout)
{
if (!http_context_append_pragma(http, "MinConnTimeout=%" PRIu32, timeout))
return -1;
}
if (!http_context_set_rdg_correlation_id(http, guid) ||
!http_context_set_rdg_connection_id(http, guid))
return -1;
}
/* TODO: "/rpcwithcert/rpcproxy.dll". */
if (!http_context_set_method(http, inout) ||
!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, settings->GatewayHostname) ||
!http_context_set_pragma(http, "ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729, "
"SessionId=fbd9c34f-397d-471d-a109-1b08cc554624"))
!http_context_set_host(http, settings->GatewayHostname))
return -1;
return 1;
}
static int rpc_in_channel_init(rdpRpc* rpc, RpcInChannel* inChannel)
static int rpc_in_channel_init(rdpRpc* rpc, RpcInChannel* inChannel, const GUID* guid)
{
WINPR_ASSERT(rpc);
WINPR_ASSERT(inChannel);
@ -540,19 +570,19 @@ static int rpc_in_channel_init(rdpRpc* rpc, RpcInChannel* inChannel)
inChannel->PingOriginator.ConnectionTimeout = 30;
inChannel->PingOriginator.KeepAliveInterval = 0;
if (rpc_channel_rpch_init(rpc->client, &inChannel->common, "RPC_IN_DATA") < 0)
if (rpc_channel_rpch_init(rpc->client, &inChannel->common, "RPC_IN_DATA", guid) < 0)
return -1;
return 1;
}
static RpcInChannel* rpc_in_channel_new(rdpRpc* rpc)
static RpcInChannel* rpc_in_channel_new(rdpRpc* rpc, const GUID* guid)
{
RpcInChannel* inChannel = (RpcInChannel*)calloc(1, sizeof(RpcInChannel));
if (inChannel)
{
rpc_in_channel_init(rpc, inChannel);
rpc_in_channel_init(rpc, inChannel, guid);
}
return inChannel;
@ -579,7 +609,7 @@ BOOL rpc_out_channel_transition_to_state(RpcOutChannel* outChannel, CLIENT_OUT_C
return TRUE;
}
static int rpc_out_channel_init(rdpRpc* rpc, RpcOutChannel* outChannel)
static int rpc_out_channel_init(rdpRpc* rpc, RpcOutChannel* outChannel, const GUID* guid)
{
WINPR_ASSERT(rpc);
WINPR_ASSERT(outChannel);
@ -592,19 +622,19 @@ static int rpc_out_channel_init(rdpRpc* rpc, RpcOutChannel* outChannel)
outChannel->ReceiveWindowSize = rpc->ReceiveWindow;
outChannel->AvailableWindowAdvertised = rpc->ReceiveWindow;
if (rpc_channel_rpch_init(rpc->client, &outChannel->common, "RPC_OUT_DATA") < 0)
if (rpc_channel_rpch_init(rpc->client, &outChannel->common, "RPC_OUT_DATA", guid) < 0)
return -1;
return 1;
}
RpcOutChannel* rpc_out_channel_new(rdpRpc* rpc)
RpcOutChannel* rpc_out_channel_new(rdpRpc* rpc, const GUID* guid)
{
RpcOutChannel* outChannel = (RpcOutChannel*)calloc(1, sizeof(RpcOutChannel));
if (outChannel)
{
rpc_out_channel_init(rpc, outChannel);
rpc_out_channel_init(rpc, outChannel, guid);
}
return outChannel;
@ -622,6 +652,22 @@ BOOL rpc_virtual_connection_transition_to_state(rdpRpc* rpc, RpcVirtualConnectio
return TRUE;
}
static void rpc_virtual_connection_free(RpcVirtualConnection* connection)
{
if (!connection)
return;
if (connection->DefaultInChannel)
rpc_channel_free(&connection->DefaultInChannel->common);
if (connection->NonDefaultInChannel)
rpc_channel_free(&connection->NonDefaultInChannel->common);
if (connection->DefaultOutChannel)
rpc_channel_free(&connection->DefaultOutChannel->common);
if (connection->NonDefaultOutChannel)
rpc_channel_free(&connection->NonDefaultOutChannel->common);
free(connection);
}
static RpcVirtualConnection* rpc_virtual_connection_new(rdpRpc* rpc)
{
WINPR_ASSERT(rpc);
@ -635,36 +681,23 @@ static RpcVirtualConnection* rpc_virtual_connection_new(rdpRpc* rpc)
rts_generate_cookie((BYTE*)&(connection->Cookie));
rts_generate_cookie((BYTE*)&(connection->AssociationGroupId));
connection->State = VIRTUAL_CONNECTION_STATE_INITIAL;
connection->DefaultInChannel = rpc_in_channel_new(rpc);
connection->DefaultInChannel = rpc_in_channel_new(rpc, &connection->Cookie);
if (!connection->DefaultInChannel)
goto out_free;
goto fail;
connection->DefaultOutChannel = rpc_out_channel_new(rpc);
connection->DefaultOutChannel = rpc_out_channel_new(rpc, &connection->Cookie);
if (!connection->DefaultOutChannel)
goto out_default_in;
goto fail;
return connection;
out_default_in:
free(connection->DefaultInChannel);
out_free:
free(connection);
fail:
rpc_virtual_connection_free(connection);
return NULL;
}
static void rpc_virtual_connection_free(RpcVirtualConnection* connection)
{
if (!connection)
return;
rpc_channel_free(&connection->DefaultInChannel->common);
rpc_channel_free(&connection->NonDefaultInChannel->common);
rpc_channel_free(&connection->DefaultOutChannel->common);
rpc_channel_free(&connection->NonDefaultOutChannel->common);
free(connection);
}
static BOOL rpc_channel_tls_connect(RpcChannel* channel, UINT32 timeout)
{
int sockfd;

View File

@ -769,7 +769,7 @@ FREERDP_LOCAL SSIZE_T rpc_channel_read(RpcChannel* channel, wStream* s, size_t l
FREERDP_LOCAL void rpc_channel_free(RpcChannel* channel);
FREERDP_LOCAL RpcOutChannel* rpc_out_channel_new(rdpRpc* rpc);
FREERDP_LOCAL RpcOutChannel* rpc_out_channel_new(rdpRpc* rpc, const GUID* guid);
FREERDP_LOCAL int rpc_out_channel_replacement_connect(RpcOutChannel* outChannel, int timeout);
FREERDP_LOCAL BOOL rpc_in_channel_transition_to_state(RpcInChannel* inChannel,

View File

@ -2176,7 +2176,7 @@ static int rts_recv_OUT_R1_A2_pdu(rdpRpc* rpc, wStream* buffer)
if (status < 0)
return status;
connection->NonDefaultOutChannel = rpc_out_channel_new(rpc);
connection->NonDefaultOutChannel = rpc_out_channel_new(rpc, &connection->Cookie);
if (!connection->NonDefaultOutChannel)
return -1;

View File

@ -1008,7 +1008,7 @@ static BOOL tsg_packet_quarenc_response_to_string(char** buffer, size_t* length,
" flags=0x%08" PRIx32 ", certChain[%" PRIu32 "]=%s, nonce=%s, versionCaps=%s",
caps->flags, caps->certChainLen, strdata, uuid, tbuffer);
free(strdata);
free(uuid);
RpcStringFreeA(&uuid);
if (!rc)
return FALSE;