From b32e3a02523394fd7794f8a106f35a89c4b20f39 Mon Sep 17 00:00:00 2001 From: erdgeist <> Date: Wed, 21 Apr 2004 15:25:23 +0000 Subject: started transaction2 handler --- src/nu_defines.h | 32 ++++++++--------- src/nu_server.c | 106 +++++++++++++++++++++++++++++++++++++++---------------- src/nu_server.h | 24 ++++++++++++- 3 files changed, 115 insertions(+), 47 deletions(-) diff --git a/src/nu_defines.h b/src/nu_defines.h index 36bbb56..0b6316f 100755 --- a/src/nu_defines.h +++ b/src/nu_defines.h @@ -99,23 +99,23 @@ typedef enum { } SMB_COMMAND; typedef enum { - SMB_TRANS2_OPEN2 = 0x00, - SMB_TRANS2_FIND_FIRST2 = 0x01, - SMB_TRANS2_FIND_NEXT2 = 0x02, - SMB_TRANS2_QUERY_FS_INFORMATION = 0x03, + SMB_TRANS2_OPEN2 = 0x0000, + SMB_TRANS2_FIND_FIRST2 = 0x0001, + SMB_TRANS2_FIND_NEXT2 = 0x0002, + SMB_TRANS2_QUERY_FS_INFORMATION = 0x0003, /* Reserved */ - SMB_TRANS2_QUERY_PATH_INFORMATION = 0x05, - SMB_TRANS2_SET_PATH_INFORMATION = 0x06, - SMB_TRANS2_QUERY_FILE_INFORMATION = 0x07, - SMB_TRANS2_SET_FILE_INFORMATION = 0x08, - SMB_TRANS2_FSCTL = 0x09, - SMB_TRANS2_IOCTL2 = 0x0A, - SMB_TRANS2_FIND_NOTIFY_FIRST = 0x0B, - SMB_TRANS2_FIND_NOTIFY_NEXT = 0x0C, - SMB_TRANS2_CREATE_DIRECTORY = 0x0D, - SMB_TRANS2_SESSION_SETUP = 0x0E, - SMB_TRANS2_GET_DFS_REFERRAL = 0x10, - SMB_TRANS2_REPORT_DFS_INCONSISTENCY = 0x11, + SMB_TRANS2_QUERY_PATH_INFORMATION = 0x0005, + SMB_TRANS2_SET_PATH_INFORMATION = 0x0006, + SMB_TRANS2_QUERY_FILE_INFORMATION = 0x0007, + SMB_TRANS2_SET_FILE_INFORMATION = 0x0008, + SMB_TRANS2_FSCTL = 0x0009, + SMB_TRANS2_IOCTL2 = 0x000A, + SMB_TRANS2_FIND_NOTIFY_FIRST = 0x000B, + SMB_TRANS2_FIND_NOTIFY_NEXT = 0x000C, + SMB_TRANS2_CREATE_DIRECTORY = 0x000D, + SMB_TRANS2_SESSION_SETUP = 0x000E, + SMB_TRANS2_GET_DFS_REFERRAL = 0x0010, + SMB_TRANS2_REPORT_DFS_INCONSISTENCY = 0x0011, } SMB_TRANS2_SUBCOMMAND; typedef enum { diff --git a/src/nu_server.c b/src/nu_server.c index 5112f1e..3017cdc 100755 --- a/src/nu_server.c +++ b/src/nu_server.c @@ -6,6 +6,10 @@ static void sigint( int reason ) { bailout( "User interrupt." ); } static mainsock = -1; static childsock = -1; +SMB_COMMAND g_transact; /* If set to != 0x00, we are waiting for some data bytes + to complete a transaction request. This variable tells + us, which request we're waiting for. */ + static QWORD getnttime( struct timeval *t ) { return 10000000ll * ( t->tv_sec + 11644473600ll ) + t->tv_usec * 10ll; } @@ -50,7 +54,7 @@ static WORD SMB_COM_NEGOTIATE_params[] = { 0x0511, 0x0000, 0x0001, 0x0001, 0x0000, 0x0100, 0x0000, 0x0100, 0x0000, 0x0000, 0xC049, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }; -static SMB_STATUS handle_SMB_COM_NEGOTIATE( SMB_HEADER *header, SMB_DATA *data ) { +static SMB_STATUS handle_SMB_COM_NEGOTIATE( SMB_HEADER **header, SMB_DATA *data ) { struct timeval t; gettimeofday( &t, NULL ); int i = 3; /* Assign uniqe session id, don't know whether spreading our @@ -75,7 +79,7 @@ static const BYTE SMB_COM_SESSION_SETUP_ANDX_bytes[] = { 19,0,'O','S',0,'g','a','t','l','i','n','g',0,'g','a','t','l','i','n','g',0}; static BYTE SMB_COM_SESSION_SETUP_ANDX_params[] = { 4, 255, 0, 0, 0, 1, 0, 0, 0 }; -static SMB_STATUS handle_SMB_COM_SESSION_SETUP_ANDX( SMB_HEADER *header, SMB_DATA *data ) { +static SMB_STATUS handle_SMB_COM_SESSION_SETUP_ANDX( SMB_HEADER **header, SMB_DATA *data ) { data->params = (SMB_PARAMS*)SMB_COM_SESSION_SETUP_ANDX_params; data->bytes = (SMB_BYTES *)SMB_COM_SESSION_SETUP_ANDX_bytes; return STATUS_SUCCESS; @@ -84,50 +88,87 @@ static SMB_STATUS handle_SMB_COM_SESSION_SETUP_ANDX( SMB_HEADER *header, SMB_DAT static const BYTE SMB_COM_TREE_CONNECT_ANDX_bytes[] = { 9, 0, 'A', ':', 0, 'F', 'A', 'T', '3', '2', 0 }; static BYTE SMB_COM_TREE_CONNECT_ANDX_params[] = { 3, 255, 0, 0, 0, 0, 0 }; -static SMB_STATUS handle_SMB_COM_TREE_CONNECT_ANDX( SMB_HEADER *header, SMB_DATA *data ){ - header->TreeID = 5; +static SMB_STATUS handle_SMB_COM_TREE_CONNECT_ANDX( SMB_HEADER **header, SMB_DATA *data ){ + (*header)->TreeID = 5; data->params = (SMB_PARAMS*)SMB_COM_TREE_CONNECT_ANDX_params; data->bytes = (SMB_BYTES *)SMB_COM_TREE_CONNECT_ANDX_bytes; return STATUS_SUCCESS; } -//static SMB_STATUS handle_SMB_COM_TRANSACTION( SMB_HEADER *header, SMB_DATA *data ) { -// if( !strcmp( (char*)&data->bytes[1], "\\PIPE\\LANMAN")) -// { -// /* TODO: Sanity Check on DataCount vs. ByteCount */ -// SMB_PARAMS_TRANSACTION *params = (SMB_PARAMS_TRANSACTION *)data->params; -// SMB_TRANSACTION_BYTES bytes; -// -// bytes.params = ((BYTE*)&header->Protocol) + GETNWORD( params->ParameterOffset ); -// bytes.paramc = GETNWORD( params->ParameterCount ); -// bytes.data = ((BYTE*)&header->Protocol) + GETNWORD( params->DataOffset ); -// bytes.datac = GETNWORD( params->DataCount ); -// -// return handle_LANMAN( header, data, &bytes ); -// } -// else -// return 0x00400002; -//} - -//static SMB_STATUS handle_SMB_COM_TRANSACTION2( SMB_HEADER *header, SMB_DATA *data ) { -// return 0x00400002; /* No handler yet */ -//} +/*static SMB_STATUS handle_SMB_COM_TRANSACTION( SMB_HEADER **header, SMB_DATA *data ) { + if( !strcmp( (char*)&data->bytes[1], "\\PIPE\\LANMAN")) + { + /* TODO: Sanity Check on DataCount vs. ByteCount * / + SMB_PARAMS_TRANSACTION *params = (SMB_PARAMS_TRANSACTION *)data->params; + SMB_TRANSACTION_BYTES bytes; + + bytes.params = ((BYTE*)&((*header)->Protocol)) + GETNWORD( params->ParameterOffset ); + bytes.paramc = GETNWORD( params->ParameterCount ); + bytes.data = ((BYTE*)&((*header)->Protocol)) + GETNWORD( params->DataOffset ); + bytes.datac = GETNWORD( params->DataCount ); + + return handle_LANMAN( *header, data, &bytes ); + } + else + return 0x00400002; +} */ + +static SMB_STATUS handle_SMB_COM_TRANSACTION2( SMB_HEADER **header, SMB_DATA *data ) { + SMB_PARAMS_TRANSACTION2 *params = (SMB_PARAMS_TRANSACTION2 *)data->params; + SMB_TRANSACTION_BYTES bytes; + int i; + + printf( "%d %d %d %d\n", GETNWORD(params->TotalParameterCount), GETNWORD(params->ParameterCount), + GETNWORD(params->TotalDataCount ), GETNWORD(params->DataCount )); + +// for( i=0; iparams)[i] ); + + if( ( GETNWORD(params->TotalParameterCount) != GETNWORD(params->ParameterCount)) || + ( GETNWORD(params->TotalDataCount ) != GETNWORD(params->DataCount ))) + { + /* Handle and or reassemble split packets later */ + bailout( "One missing feature detected."); + } + + bytes.params = ((BYTE*)&((*header)->Protocol)) + GETNWORD( params->ParameterOffset ); + bytes.paramc = GETNWORD( params->ParameterCount ); + bytes.data = ((BYTE*)&((*header)->Protocol)) + GETNWORD( params->DataOffset ); + bytes.datac = GETNWORD( params->DataCount ); + + switch( GETNWORD( ¶ms->Setup )) { /* Transaction2 Command Code */ + case SMB_TRANS2_FIND_FIRST2: + printf( "Attributes:\t%d\nCount:\t\t%d\nFlags:\t\t%02x\nLevel:\t\t%d\nType:\t\t%d\nPattern:\t%s\n", + GETNWORD( bytes.params ), + GETNWORD( 2 + bytes.params ), + GETNWORD( 4 + bytes.params ), + GETNWORD( 6 + bytes.params ), + GETNWORD( 8 + bytes.params ), + bytes.params + 12 ); + break; + default: + return 0x00400002; /* No sub command handler yet */ + break; + } + + return STATUS_SUCCESS; +} static int command_handler_match(const void *a, const void *b ) { return *(BYTE*)a - *(BYTE*)b; } /* If you add command handlers, please insert them in the right position, this list is sorted by command, for later bsearch*/ static SMB_COMMAND_HANDLER command_handler[] = { -// { SMB_COM_TRANSACTION, 0x00, handle_SMB_COM_TRANSACTION }, -// { SMB_COM_TRANSACTION2, 0x00, handle_SMB_COM_TRANSACTION2 }, +/*{ SMB_COM_TRANSACTION, 0x00, handle_SMB_COM_TRANSACTION }, */ + { SMB_COM_TRANSACTION2, 0x00, handle_SMB_COM_TRANSACTION2 }, { SMB_COM_NEGOTIATE, 0x00, handle_SMB_COM_NEGOTIATE }, { SMB_COM_SESSION_SETUP_ANDX, 0x01, handle_SMB_COM_SESSION_SETUP_ANDX }, { SMB_COM_TREE_CONNECT_ANDX, 0x01, handle_SMB_COM_TREE_CONNECT_ANDX } }; static void child( ) { - SMB_HEADER *inpacket = NULL; - DWORD netbios_ack = 0x00000082; + SMB_HEADER *inpacket = NULL; + DWORD netbios_ack = 0x00000082; /* I should spare that code... */ if( mainsock != -1 ) { close( mainsock ); mainsock = -1; } @@ -138,6 +179,8 @@ static void child( ) { bailout( "No session request"); write( childsock, &netbios_ack, 4); + g_transact = 0x00; /* No transaction waiting for bytes */ + while( 1 ) { SMB_COMMAND cmd; SMB_DATA requests[ 1 + SMB_MAXREQUESTS ]; @@ -156,6 +199,9 @@ static void child( ) { cmd = inpacket->Command; requests[ 0 ].params = (SMB_PARAMS*)(inpacket+1); + if( g_transact && (g_transact != cmd) ) + bailout( "Transaction interrupted by other SMB command."); + while( (status == STATUS_SUCCESS) && (cmd != 0xff) ) { SMB_COMMAND_HANDLER *handler = (SMB_COMMAND_HANDLER*)bsearch( &cmd, command_handler, sizeof(command_handler)/sizeof(*command_handler), sizeof(*command_handler), command_handler_match); @@ -171,7 +217,7 @@ static void child( ) { } /* <---------- Calling handler here -----> */ - if( (status = handler->handler( inpacket, requests + num_requests )) != STATUS_SUCCESS ) + if( (status = handler->handler( &inpacket, requests + num_requests )) != STATUS_SUCCESS ) cmd = 0xff; if( handler->flags & SMB_COMMAND_FLAG_ANDX ) { sizeout += 3 + 2 * requests[ num_requests ].params->WordCount + requests[ num_requests ].bytes->ByteCount; diff --git a/src/nu_server.h b/src/nu_server.h index 89fe2e9..f305430 100755 --- a/src/nu_server.h +++ b/src/nu_server.h @@ -16,6 +16,7 @@ typedef unsigned long DWORD; typedef int64_t QWORD; #define SKIPSTRING( str ) ((BYTE*)(str)) + 1 + strlen( (str) ) +// Get Network byte order half word #define GETNWORD(addr) (*((BYTE*)(addr)) | 256 * ((BYTE*)(addr))[1] ) #include "nu_defines.h" @@ -80,10 +81,31 @@ typedef struct { DWORD datac; } SMB_TRANSACTION_BYTES; +typedef struct { + BYTE WordCount; /* 14 + SetupCount */ + BYTE TotalParameterCount [2]; + BYTE TotalDataCount [2]; + BYTE MaxParameterCount [2]; + BYTE MaxDataCount [2]; + BYTE MaxSetupCount; + BYTE Reserved; + BYTE Flags [2]; + BYTE Timeout [4]; + BYTE Reserved2 [2]; + + BYTE ParameterCount [2]; + BYTE ParameterOffset [2]; + BYTE DataCount [2]; + BYTE DataOffset [2]; + BYTE SetupCount; + BYTE Reserved3; + BYTE Setup [0]; +} SMB_PARAMS_TRANSACTION2; + typedef struct { BYTE cmd; SMB_COMMAND_FLAG flags; - SMB_STATUS (*handler)(SMB_HEADER *header, SMB_DATA *data); + SMB_STATUS (*handler)(SMB_HEADER **header, SMB_DATA *data); } SMB_COMMAND_HANDLER; #endif -- cgit v1.2.3