summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsrc/nu_defines.h32
-rwxr-xr-xsrc/nu_server.c106
-rwxr-xr-xsrc/nu_server.h24
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 {
99} SMB_COMMAND; 99} SMB_COMMAND;
100 100
101typedef enum { 101typedef enum {
102 SMB_TRANS2_OPEN2 = 0x00, 102 SMB_TRANS2_OPEN2 = 0x0000,
103 SMB_TRANS2_FIND_FIRST2 = 0x01, 103 SMB_TRANS2_FIND_FIRST2 = 0x0001,
104 SMB_TRANS2_FIND_NEXT2 = 0x02, 104 SMB_TRANS2_FIND_NEXT2 = 0x0002,
105 SMB_TRANS2_QUERY_FS_INFORMATION = 0x03, 105 SMB_TRANS2_QUERY_FS_INFORMATION = 0x0003,
106 /* Reserved */ 106 /* Reserved */
107 SMB_TRANS2_QUERY_PATH_INFORMATION = 0x05, 107 SMB_TRANS2_QUERY_PATH_INFORMATION = 0x0005,
108 SMB_TRANS2_SET_PATH_INFORMATION = 0x06, 108 SMB_TRANS2_SET_PATH_INFORMATION = 0x0006,
109 SMB_TRANS2_QUERY_FILE_INFORMATION = 0x07, 109 SMB_TRANS2_QUERY_FILE_INFORMATION = 0x0007,
110 SMB_TRANS2_SET_FILE_INFORMATION = 0x08, 110 SMB_TRANS2_SET_FILE_INFORMATION = 0x0008,
111 SMB_TRANS2_FSCTL = 0x09, 111 SMB_TRANS2_FSCTL = 0x0009,
112 SMB_TRANS2_IOCTL2 = 0x0A, 112 SMB_TRANS2_IOCTL2 = 0x000A,
113 SMB_TRANS2_FIND_NOTIFY_FIRST = 0x0B, 113 SMB_TRANS2_FIND_NOTIFY_FIRST = 0x000B,
114 SMB_TRANS2_FIND_NOTIFY_NEXT = 0x0C, 114 SMB_TRANS2_FIND_NOTIFY_NEXT = 0x000C,
115 SMB_TRANS2_CREATE_DIRECTORY = 0x0D, 115 SMB_TRANS2_CREATE_DIRECTORY = 0x000D,
116 SMB_TRANS2_SESSION_SETUP = 0x0E, 116 SMB_TRANS2_SESSION_SETUP = 0x000E,
117 SMB_TRANS2_GET_DFS_REFERRAL = 0x10, 117 SMB_TRANS2_GET_DFS_REFERRAL = 0x0010,
118 SMB_TRANS2_REPORT_DFS_INCONSISTENCY = 0x11, 118 SMB_TRANS2_REPORT_DFS_INCONSISTENCY = 0x0011,
119} SMB_TRANS2_SUBCOMMAND; 119} SMB_TRANS2_SUBCOMMAND;
120 120
121typedef enum { 121typedef 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." ); }
6static mainsock = -1; 6static mainsock = -1;
7static childsock = -1; 7static childsock = -1;
8 8
9SMB_COMMAND g_transact; /* If set to != 0x00, we are waiting for some data bytes
10 to complete a transaction request. This variable tells
11 us, which request we're waiting for. */
12
9static QWORD getnttime( struct timeval *t ) { 13static QWORD getnttime( struct timeval *t ) {
10 return 10000000ll * ( t->tv_sec + 11644473600ll ) + t->tv_usec * 10ll; 14 return 10000000ll * ( t->tv_sec + 11644473600ll ) + t->tv_usec * 10ll;
11} 15}
@@ -50,7 +54,7 @@ static WORD SMB_COM_NEGOTIATE_params[] = {
500x0511, 0x0000, 0x0001, 0x0001, 0x0000, 0x0100, 0x0000, 0x0100, 0x0000, 540x0511, 0x0000, 0x0001, 0x0001, 0x0000, 0x0100, 0x0000, 0x0100, 0x0000,
510x0000, 0xC049, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }; 550x0000, 0xC049, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };
52 56
53static SMB_STATUS handle_SMB_COM_NEGOTIATE( SMB_HEADER *header, SMB_DATA *data ) { 57static SMB_STATUS handle_SMB_COM_NEGOTIATE( SMB_HEADER **header, SMB_DATA *data ) {
54 struct timeval t; gettimeofday( &t, NULL ); 58 struct timeval t; gettimeofday( &t, NULL );
55 int i = 3; 59 int i = 3;
56 /* Assign uniqe session id, don't know whether spreading our 60 /* Assign uniqe session id, don't know whether spreading our
@@ -75,7 +79,7 @@ static const BYTE SMB_COM_SESSION_SETUP_ANDX_bytes[] = {
7519,0,'O','S',0,'g','a','t','l','i','n','g',0,'g','a','t','l','i','n','g',0}; 7919,0,'O','S',0,'g','a','t','l','i','n','g',0,'g','a','t','l','i','n','g',0};
76static BYTE SMB_COM_SESSION_SETUP_ANDX_params[] = { 4, 255, 0, 0, 0, 1, 0, 0, 0 }; 80static BYTE SMB_COM_SESSION_SETUP_ANDX_params[] = { 4, 255, 0, 0, 0, 1, 0, 0, 0 };
77 81
78static SMB_STATUS handle_SMB_COM_SESSION_SETUP_ANDX( SMB_HEADER *header, SMB_DATA *data ) { 82static SMB_STATUS handle_SMB_COM_SESSION_SETUP_ANDX( SMB_HEADER **header, SMB_DATA *data ) {
79 data->params = (SMB_PARAMS*)SMB_COM_SESSION_SETUP_ANDX_params; 83 data->params = (SMB_PARAMS*)SMB_COM_SESSION_SETUP_ANDX_params;
80 data->bytes = (SMB_BYTES *)SMB_COM_SESSION_SETUP_ANDX_bytes; 84 data->bytes = (SMB_BYTES *)SMB_COM_SESSION_SETUP_ANDX_bytes;
81 return STATUS_SUCCESS; 85 return STATUS_SUCCESS;
@@ -84,50 +88,87 @@ static SMB_STATUS handle_SMB_COM_SESSION_SETUP_ANDX( SMB_HEADER *header, SMB_DAT
84static const BYTE SMB_COM_TREE_CONNECT_ANDX_bytes[] = { 9, 0, 'A', ':', 0, 'F', 'A', 'T', '3', '2', 0 }; 88static const BYTE SMB_COM_TREE_CONNECT_ANDX_bytes[] = { 9, 0, 'A', ':', 0, 'F', 'A', 'T', '3', '2', 0 };
85static BYTE SMB_COM_TREE_CONNECT_ANDX_params[] = { 3, 255, 0, 0, 0, 0, 0 }; 89static BYTE SMB_COM_TREE_CONNECT_ANDX_params[] = { 3, 255, 0, 0, 0, 0, 0 };
86 90
87static SMB_STATUS handle_SMB_COM_TREE_CONNECT_ANDX( SMB_HEADER *header, SMB_DATA *data ){ 91static SMB_STATUS handle_SMB_COM_TREE_CONNECT_ANDX( SMB_HEADER **header, SMB_DATA *data ){
88 header->TreeID = 5; 92 (*header)->TreeID = 5;
89 data->params = (SMB_PARAMS*)SMB_COM_TREE_CONNECT_ANDX_params; 93 data->params = (SMB_PARAMS*)SMB_COM_TREE_CONNECT_ANDX_params;
90 data->bytes = (SMB_BYTES *)SMB_COM_TREE_CONNECT_ANDX_bytes; 94 data->bytes = (SMB_BYTES *)SMB_COM_TREE_CONNECT_ANDX_bytes;
91 return STATUS_SUCCESS; 95 return STATUS_SUCCESS;
92} 96}
93 97
94//static SMB_STATUS handle_SMB_COM_TRANSACTION( SMB_HEADER *header, SMB_DATA *data ) { 98/*static SMB_STATUS handle_SMB_COM_TRANSACTION( SMB_HEADER **header, SMB_DATA *data ) {
95// if( !strcmp( (char*)&data->bytes[1], "\\PIPE\\LANMAN")) 99 if( !strcmp( (char*)&data->bytes[1], "\\PIPE\\LANMAN"))
96// { 100 {
97// /* TODO: Sanity Check on DataCount vs. ByteCount */ 101 /* TODO: Sanity Check on DataCount vs. ByteCount * /
98// SMB_PARAMS_TRANSACTION *params = (SMB_PARAMS_TRANSACTION *)data->params; 102 SMB_PARAMS_TRANSACTION *params = (SMB_PARAMS_TRANSACTION *)data->params;
99// SMB_TRANSACTION_BYTES bytes; 103 SMB_TRANSACTION_BYTES bytes;
100// 104
101// bytes.params = ((BYTE*)&header->Protocol) + GETNWORD( params->ParameterOffset ); 105 bytes.params = ((BYTE*)&((*header)->Protocol)) + GETNWORD( params->ParameterOffset );
102// bytes.paramc = GETNWORD( params->ParameterCount ); 106 bytes.paramc = GETNWORD( params->ParameterCount );
103// bytes.data = ((BYTE*)&header->Protocol) + GETNWORD( params->DataOffset ); 107 bytes.data = ((BYTE*)&((*header)->Protocol)) + GETNWORD( params->DataOffset );
104// bytes.datac = GETNWORD( params->DataCount ); 108 bytes.datac = GETNWORD( params->DataCount );
105// 109
106// return handle_LANMAN( header, data, &bytes ); 110 return handle_LANMAN( *header, data, &bytes );
107// } 111 }
108// else 112 else
109// return 0x00400002; 113 return 0x00400002;
110//} 114} */
111 115
112//static SMB_STATUS handle_SMB_COM_TRANSACTION2( SMB_HEADER *header, SMB_DATA *data ) { 116static SMB_STATUS handle_SMB_COM_TRANSACTION2( SMB_HEADER **header, SMB_DATA *data ) {
113// return 0x00400002; /* No handler yet */ 117 SMB_PARAMS_TRANSACTION2 *params = (SMB_PARAMS_TRANSACTION2 *)data->params;
114//} 118 SMB_TRANSACTION_BYTES bytes;
119 int i;
120
121 printf( "%d %d %d %d\n", GETNWORD(params->TotalParameterCount), GETNWORD(params->ParameterCount),
122 GETNWORD(params->TotalDataCount ), GETNWORD(params->DataCount ));
123
124// for( i=0; i<sizeof( SMB_PARAMS_TRANSACTION2 ); ++i )
125// printf( "%02x ", ((BYTE*)data->params)[i] );
126
127 if( ( GETNWORD(params->TotalParameterCount) != GETNWORD(params->ParameterCount)) ||
128 ( GETNWORD(params->TotalDataCount ) != GETNWORD(params->DataCount )))
129 {
130 /* Handle and or reassemble split packets later */
131 bailout( "One missing feature detected.");
132 }
133
134 bytes.params = ((BYTE*)&((*header)->Protocol)) + GETNWORD( params->ParameterOffset );
135 bytes.paramc = GETNWORD( params->ParameterCount );
136 bytes.data = ((BYTE*)&((*header)->Protocol)) + GETNWORD( params->DataOffset );
137 bytes.datac = GETNWORD( params->DataCount );
138
139 switch( GETNWORD( &params->Setup )) { /* Transaction2 Command Code */
140 case SMB_TRANS2_FIND_FIRST2:
141 printf( "Attributes:\t%d\nCount:\t\t%d\nFlags:\t\t%02x\nLevel:\t\t%d\nType:\t\t%d\nPattern:\t%s\n",
142 GETNWORD( bytes.params ),
143 GETNWORD( 2 + bytes.params ),
144 GETNWORD( 4 + bytes.params ),
145 GETNWORD( 6 + bytes.params ),
146 GETNWORD( 8 + bytes.params ),
147 bytes.params + 12 );
148 break;
149 default:
150 return 0x00400002; /* No sub command handler yet */
151 break;
152 }
153
154 return STATUS_SUCCESS;
155}
115 156
116static int command_handler_match(const void *a, const void *b ) { return *(BYTE*)a - *(BYTE*)b; } 157static int command_handler_match(const void *a, const void *b ) { return *(BYTE*)a - *(BYTE*)b; }
117 158
118/* If you add command handlers, please insert them in the right position, 159/* If you add command handlers, please insert them in the right position,
119 this list is sorted by command, for later bsearch*/ 160 this list is sorted by command, for later bsearch*/
120static SMB_COMMAND_HANDLER command_handler[] = { 161static SMB_COMMAND_HANDLER command_handler[] = {
121// { SMB_COM_TRANSACTION, 0x00, handle_SMB_COM_TRANSACTION }, 162/*{ SMB_COM_TRANSACTION, 0x00, handle_SMB_COM_TRANSACTION }, */
122// { SMB_COM_TRANSACTION2, 0x00, handle_SMB_COM_TRANSACTION2 }, 163 { SMB_COM_TRANSACTION2, 0x00, handle_SMB_COM_TRANSACTION2 },
123 { SMB_COM_NEGOTIATE, 0x00, handle_SMB_COM_NEGOTIATE }, 164 { SMB_COM_NEGOTIATE, 0x00, handle_SMB_COM_NEGOTIATE },
124 { SMB_COM_SESSION_SETUP_ANDX, 0x01, handle_SMB_COM_SESSION_SETUP_ANDX }, 165 { SMB_COM_SESSION_SETUP_ANDX, 0x01, handle_SMB_COM_SESSION_SETUP_ANDX },
125 { SMB_COM_TREE_CONNECT_ANDX, 0x01, handle_SMB_COM_TREE_CONNECT_ANDX } 166 { SMB_COM_TREE_CONNECT_ANDX, 0x01, handle_SMB_COM_TREE_CONNECT_ANDX }
126}; 167};
127 168
128static void child( ) { 169static void child( ) {
129 SMB_HEADER *inpacket = NULL; 170 SMB_HEADER *inpacket = NULL;
130 DWORD netbios_ack = 0x00000082; 171 DWORD netbios_ack = 0x00000082;
131 172
132 /* I should spare that code... */ 173 /* I should spare that code... */
133 if( mainsock != -1 ) { close( mainsock ); mainsock = -1; } 174 if( mainsock != -1 ) { close( mainsock ); mainsock = -1; }
@@ -138,6 +179,8 @@ static void child( ) {
138 bailout( "No session request"); 179 bailout( "No session request");
139 write( childsock, &netbios_ack, 4); 180 write( childsock, &netbios_ack, 4);
140 181
182 g_transact = 0x00; /* No transaction waiting for bytes */
183
141 while( 1 ) { 184 while( 1 ) {
142 SMB_COMMAND cmd; 185 SMB_COMMAND cmd;
143 SMB_DATA requests[ 1 + SMB_MAXREQUESTS ]; 186 SMB_DATA requests[ 1 + SMB_MAXREQUESTS ];
@@ -156,6 +199,9 @@ static void child( ) {
156 cmd = inpacket->Command; 199 cmd = inpacket->Command;
157 requests[ 0 ].params = (SMB_PARAMS*)(inpacket+1); 200 requests[ 0 ].params = (SMB_PARAMS*)(inpacket+1);
158 201
202 if( g_transact && (g_transact != cmd) )
203 bailout( "Transaction interrupted by other SMB command.");
204
159 while( (status == STATUS_SUCCESS) && (cmd != 0xff) ) { 205 while( (status == STATUS_SUCCESS) && (cmd != 0xff) ) {
160 SMB_COMMAND_HANDLER *handler = (SMB_COMMAND_HANDLER*)bsearch( &cmd, command_handler, 206 SMB_COMMAND_HANDLER *handler = (SMB_COMMAND_HANDLER*)bsearch( &cmd, command_handler,
161 sizeof(command_handler)/sizeof(*command_handler), sizeof(*command_handler), command_handler_match); 207 sizeof(command_handler)/sizeof(*command_handler), sizeof(*command_handler), command_handler_match);
@@ -171,7 +217,7 @@ static void child( ) {
171 } 217 }
172 218
173 /* <---------- Calling handler here -----> */ 219 /* <---------- Calling handler here -----> */
174 if( (status = handler->handler( inpacket, requests + num_requests )) != STATUS_SUCCESS ) 220 if( (status = handler->handler( &inpacket, requests + num_requests )) != STATUS_SUCCESS )
175 cmd = 0xff; 221 cmd = 0xff;
176 if( handler->flags & SMB_COMMAND_FLAG_ANDX ) { 222 if( handler->flags & SMB_COMMAND_FLAG_ANDX ) {
177 sizeout += 3 + 2 * requests[ num_requests ].params->WordCount + requests[ num_requests ].bytes->ByteCount; 223 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;
16typedef int64_t QWORD; 16typedef int64_t QWORD;
17 17
18#define SKIPSTRING( str ) ((BYTE*)(str)) + 1 + strlen( (str) ) 18#define SKIPSTRING( str ) ((BYTE*)(str)) + 1 + strlen( (str) )
19// Get Network byte order half word
19#define GETNWORD(addr) (*((BYTE*)(addr)) | 256 * ((BYTE*)(addr))[1] ) 20#define GETNWORD(addr) (*((BYTE*)(addr)) | 256 * ((BYTE*)(addr))[1] )
20 21
21#include "nu_defines.h" 22#include "nu_defines.h"
@@ -81,9 +82,30 @@ typedef struct {
81} SMB_TRANSACTION_BYTES; 82} SMB_TRANSACTION_BYTES;
82 83
83typedef struct { 84typedef struct {
85 BYTE WordCount; /* 14 + SetupCount */
86 BYTE TotalParameterCount [2];
87 BYTE TotalDataCount [2];
88 BYTE MaxParameterCount [2];
89 BYTE MaxDataCount [2];
90 BYTE MaxSetupCount;
91 BYTE Reserved;
92 BYTE Flags [2];
93 BYTE Timeout [4];
94 BYTE Reserved2 [2];
95
96 BYTE ParameterCount [2];
97 BYTE ParameterOffset [2];
98 BYTE DataCount [2];
99 BYTE DataOffset [2];
100 BYTE SetupCount;
101 BYTE Reserved3;
102 BYTE Setup [0];
103} SMB_PARAMS_TRANSACTION2;
104
105typedef struct {
84 BYTE cmd; 106 BYTE cmd;
85 SMB_COMMAND_FLAG flags; 107 SMB_COMMAND_FLAG flags;
86 SMB_STATUS (*handler)(SMB_HEADER *header, SMB_DATA *data); 108 SMB_STATUS (*handler)(SMB_HEADER **header, SMB_DATA *data);
87} SMB_COMMAND_HANDLER; 109} SMB_COMMAND_HANDLER;
88 110
89#endif 111#endif