Cleanups to the socket code, its still not perfect, but much more usable now

git-svn-id: file:///home/svn/framework3/trunk@7750 4d416f70-5f16-0410-b530-b9f4589650da
unstable
HD Moore 2009-12-08 14:52:07 +00:00
parent 0961ce3523
commit 792724c3f3
6 changed files with 144 additions and 115 deletions

View File

@ -1,5 +1,5 @@
#include "common.h"
extern THREAD serverThread;
/*
* core_migrate
@ -254,5 +254,5 @@ DWORD remote_request_core_migrate(Remote *remote, Packet *packet)
return result;
}

View File

@ -21,7 +21,7 @@ extern DWORD remote_response_core_console_write(Remote *remote, Packet *packet);
extern DWORD remote_response_core_channel_open(Remote *remote, Packet *packet);
extern DWORD remote_response_core_channel_close(Remote *remote, Packet *packet);
DWORD remote_request_core_console_write(Remote *remote, Packet *packet)
{
return ERROR_SUCCESS;
@ -32,7 +32,7 @@ DWORD remote_response_core_console_write(Remote *remote, Packet *packet)
return ERROR_SUCCESS;
}
/*
* Base RPC dispatch table

View File

@ -391,6 +391,9 @@ DWORD _channel_packet_completion_routine(Remote *remote, Packet *packet,
Channel *channel = channel_find_by_id(channelId);
DWORD res = ERROR_NOT_FOUND;
dprintf( "[CHANNEL] _channel_packet_completion_routine. channel=0x%08X method=%s", channel, method );
// If the channel was not found and it isn't an open request, return failure
if (!channel && strcmp(method, "core_channel_open"))
return ERROR_NOT_FOUND;
@ -665,6 +668,8 @@ DWORD channel_close(Channel *channel, Remote *remote, Tlv *addend,
realRequestCompletion = &requestCompletion;
}
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);

View File

@ -31,6 +31,7 @@
#include "list.h"
#ifdef DEBUGTRACE
#define dprintf(...) real_dprintf(__VA_ARGS__)
#else

View File

@ -86,16 +86,33 @@ static DWORD tcp_channel_client_local_notify(Remote *remote,
FD_SET(ctx->fd, &set);
// Read data from the client connection
if (((bytesRead = recv(ctx->fd, buf, sizeof(buf), 0))
== SOCKET_ERROR) ||
(bytesRead == 0))
{
channel_close(ctx->channel, ctx->remote, NULL, 0, NULL);
bytesRead = recv(ctx->fd, buf, sizeof(buf), 0);
// Not sure why we get these with pending data
if(bytesRead == SOCKET_ERROR) {
printf( "[TCP] tcp_channel_client_local_notify. [error] channel=0x%08X read=0x%.8x (ignored)", ctx->channel, bytesRead );
continue;
}
if (bytesRead == 0) {
dprintf( "[TCP] tcp_channel_client_local_notify. [closed] channel=0x%08X read=0x%.8x", ctx->channel, bytesRead );
// Set the native channel operations context to NULL
channel_set_native_io_context(ctx->channel, NULL);
// Free the context
free_tcp_client_context(ctx);
// Stop processing
break;
}
else if (ctx->channel)
if (ctx->channel) {
dprintf( "[TCP] tcp_channel_client_local_notify. [data] channel=0x%08X read=0x%.8x", ctx->channel, bytesRead );
channel_write(ctx->channel, ctx->remote, NULL, 0, buf, bytesRead, 0);
} else {
dprintf( "[TCP] tcp_channel_client_local_notify. [data] channel=<invalid> read=0x%.8x", bytesRead );
}
} while (select(0, &set, NULL, NULL, &tv) > 0);
@ -270,17 +287,23 @@ VOID free_socket_context(SocketContext *ctx)
dprintf( "[TCP] free_socket_context. ctx=0x%08X", ctx );
// Close the socket and notification handle
if (ctx->fd)
if (ctx->fd){
closesocket(ctx->fd);
ctx->fd = NULL;
}
if (ctx->notify)
{
scheduler_remove_waitable(ctx->notify);
WSACloseEvent(ctx->notify);
// XXX: Leaving this triggers an invalid handle in another thread?
// WSACloseEvent(ctx->notify);
ctx->notify = NULL;
}
if (ctx->channel)
if (ctx->channel) {
channel_close(ctx->channel, ctx->remote, NULL, 0, NULL);
ctx->channel = NULL;
}
// Free the context
free(ctx);

View File

@ -1,6 +1,6 @@
#include "metsrv.h"
#ifdef _WIN32
#ifdef _WIN32
#include <windows.h> // for EXCEPTION_ACCESS_VIOLATION
#include <excpt.h>
@ -9,42 +9,42 @@
// include the Reflectiveloader() function
#include "../ReflectiveDLLInjection/ReflectiveLoader.c"
int exceptionfilter(unsigned int code, struct _EXCEPTION_POINTERS *ep)
{
return EXCEPTION_EXECUTE_HANDLER;
}
#define InitAppInstance() do { \
if( hAppInstance == NULL ) \
hAppInstance = GetModuleHandle( NULL ); \
} while (0)
#else
#define InitAppInstance()
#define exceptionfilter(a, b)
#define SetHandleInformation(a, b, c)
#define ExitThread(x) exit((x))
#endif
int exceptionfilter(unsigned int code, struct _EXCEPTION_POINTERS *ep)
{
return EXCEPTION_EXECUTE_HANDLER;
}
#define InitAppInstance() do { \
if( hAppInstance == NULL ) \
hAppInstance = GetModuleHandle( NULL ); \
} while (0)
#else
#define InitAppInstance()
#define exceptionfilter(a, b)
#define SetHandleInformation(a, b, c)
#define ExitThread(x) exit((x))
#endif
#define PREPEND_ERROR "### Error: "
#define PREPEND_INFO "### Info : "
#define PREPEND_WARN "### Warn : "
/*
* This thread is the main server thread which we use to syncronize a gracefull
* shutdown of the server during process migration.
*/
THREAD serverThread = {0};
/*
* This thread is the main server thread which we use to syncronize a gracefull
* shutdown of the server during process migration.
*/
THREAD serverThread = {0};
/*
* An array of locks for use by OpenSSL.
*/
static LOCK ** ssl_locks = NULL;
/*
* A callback function used by OpenSSL to leverage native system locks.
*/
static LOCK ** ssl_locks = NULL;
/*
* A callback function used by OpenSSL to leverage native system locks.
*/
static VOID server_locking_callback( int mode, int type, const char * file, int line )
{
if( mode & CRYPTO_LOCK )
@ -53,9 +53,9 @@ static VOID server_locking_callback( int mode, int type, const char * file, int
lock_release( ssl_locks[type] );
}
/*
* A callback function used by OpenSSL to get the current threads id.
* While not needed on windows this must be used for posix meterpreter.
/*
* A callback function used by OpenSSL to get the current threads id.
* While not needed on windows this must be used for posix meterpreter.
*/
static DWORD server_threadid_callback( VOID )
{
@ -126,8 +126,8 @@ static VOID server_socket_flush( Remote * remote )
}
lock_release( remote->lock );
}
}
/*
* Poll a socket for data to recv and block when none available.
*/
@ -153,17 +153,17 @@ static LONG server_socket_poll( Remote * remote, long timeout )
lock_release( remote->lock );
return result;
}
}
/*
* Initialize the OpenSSL subsystem for use in a multi threaded enviroment.
*/
static BOOL server_initialize_ssl( Remote * remote )
{
int i = 0;
lock_acquire( remote->lock );
*/
static BOOL server_initialize_ssl( Remote * remote )
{
int i = 0;
lock_acquire( remote->lock );
// Begin to bring up the OpenSSL subsystem...
CRYPTO_malloc_init();
SSL_load_error_strings();
@ -184,25 +184,25 @@ static BOOL server_initialize_ssl( Remote * remote )
CRYPTO_set_locking_callback( server_locking_callback );
CRYPTO_set_dynlock_create_callback( server_dynamiclock_create );
CRYPTO_set_dynlock_lock_callback( server_dynamiclock_lock );
CRYPTO_set_dynlock_destroy_callback( server_dynamiclock_destroy );
lock_release( remote->lock );
return TRUE;
}
CRYPTO_set_dynlock_destroy_callback( server_dynamiclock_destroy );
lock_release( remote->lock );
return TRUE;
}
/*
* Bring down the OpenSSL subsystem
*/
static BOOL server_destroy_ssl( Remote * remote )
{
int i = 0;
if( remote == NULL )
return FALSE;
lock_acquire( remote->lock );
*/
static BOOL server_destroy_ssl( Remote * remote )
{
int i = 0;
if( remote == NULL )
return FALSE;
lock_acquire( remote->lock );
SSL_free( remote->ssl );
SSL_CTX_free( remote->ctx );
@ -216,12 +216,12 @@ static BOOL server_destroy_ssl( Remote * remote )
for( i=0 ; i<CRYPTO_num_locks() ; i++ )
lock_destroy( ssl_locks[i] );
free( ssl_locks );
lock_release( remote->lock );
return TRUE;
}
free( ssl_locks );
lock_release( remote->lock );
return TRUE;
}
/*
* Negotiate SSL on the socket.
*/
@ -244,20 +244,20 @@ static BOOL server_negotiate_ssl(Remote *remote)
remote->ssl = SSL_new(remote->ctx);
SSL_set_verify(remote->ssl, SSL_VERIFY_NONE, NULL);
if( SSL_set_fd(remote->ssl, remote->fd) == 0 )
{
dprintf("[SERVER] set fd failed");
success = FALSE;
break;
}
if( (ret = SSL_connect(remote->ssl)) != 1 )
{
dprintf("[SERVER] connect failed %d\n", SSL_get_error(remote->ssl, ret));
success = FALSE;
break;
}
if( SSL_set_fd(remote->ssl, remote->fd) == 0 )
{
dprintf("[SERVER] set fd failed");
success = FALSE;
break;
}
if( (ret = SSL_connect(remote->ssl)) != 1 )
{
dprintf("[SERVER] connect failed %d\n", SSL_get_error(remote->ssl, ret));
success = FALSE;
break;
}
dprintf("[SERVER] Sending a HTTP GET request to the remote side...");
@ -276,8 +276,8 @@ static BOOL server_negotiate_ssl(Remote *remote)
success = FALSE;
return success;
}
}
/*
* The servers main dispatch loop for incoming requests.
*/
@ -331,25 +331,25 @@ static DWORD server_dispatch( Remote * remote )
dprintf( "[DISPATCH] leaving server_dispatch." );
return result;
}
/*
* Setup and run the server. This is called from Init via the loader.
*/
DWORD server_setup( SOCKET fd )
{
}
/*
* Setup and run the server. This is called from Init via the loader.
*/
DWORD server_setup( SOCKET fd )
{
Remote *remote = NULL;
DWORD res = 0;
#ifdef _UNIX
int local_error = 0;
#endif
DWORD res = 0;
#ifdef _UNIX
int local_error = 0;
#endif
// if hAppInstance is still == NULL it means that we havent been
// reflectivly loaded so we must patch in the hAppInstance value
// for use with loading server extensions later.
InitAppInstance();
InitAppInstance();
srand( (unsigned int)time(NULL) );
__try
@ -411,7 +411,7 @@ DWORD server_setup( SOCKET fd )
thread_kill( &serverThread );
}
dprintf("[SERVER] Finished.");
dprintf("[SERVER] Finished.");
return res;
}
}