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_server.c | 106 ++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 76 insertions(+), 30 deletions(-) (limited to 'src/nu_server.c') 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; -- cgit v1.2.3