diff options
-rwxr-xr-x | src/nu_defines.h | 32 | ||||
-rwxr-xr-x | src/nu_server.c | 106 | ||||
-rwxr-xr-x | 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 { | |||
99 | } SMB_COMMAND; | 99 | } SMB_COMMAND; |
100 | 100 | ||
101 | typedef enum { | 101 | typedef 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 | ||
121 | typedef enum { | 121 | 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." ); } | |||
6 | static mainsock = -1; | 6 | static mainsock = -1; |
7 | static childsock = -1; | 7 | static childsock = -1; |
8 | 8 | ||
9 | SMB_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 | |||
9 | static QWORD getnttime( struct timeval *t ) { | 13 | static 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[] = { | |||
50 | 0x0511, 0x0000, 0x0001, 0x0001, 0x0000, 0x0100, 0x0000, 0x0100, 0x0000, | 54 | 0x0511, 0x0000, 0x0001, 0x0001, 0x0000, 0x0100, 0x0000, 0x0100, 0x0000, |
51 | 0x0000, 0xC049, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }; | 55 | 0x0000, 0xC049, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }; |
52 | 56 | ||
53 | static SMB_STATUS handle_SMB_COM_NEGOTIATE( SMB_HEADER *header, SMB_DATA *data ) { | 57 | static 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[] = { | |||
75 | 19,0,'O','S',0,'g','a','t','l','i','n','g',0,'g','a','t','l','i','n','g',0}; | 79 | 19,0,'O','S',0,'g','a','t','l','i','n','g',0,'g','a','t','l','i','n','g',0}; |
76 | static BYTE SMB_COM_SESSION_SETUP_ANDX_params[] = { 4, 255, 0, 0, 0, 1, 0, 0, 0 }; | 80 | static BYTE SMB_COM_SESSION_SETUP_ANDX_params[] = { 4, 255, 0, 0, 0, 1, 0, 0, 0 }; |
77 | 81 | ||
78 | static SMB_STATUS handle_SMB_COM_SESSION_SETUP_ANDX( SMB_HEADER *header, SMB_DATA *data ) { | 82 | static 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 | |||
84 | static const BYTE SMB_COM_TREE_CONNECT_ANDX_bytes[] = { 9, 0, 'A', ':', 0, 'F', 'A', 'T', '3', '2', 0 }; | 88 | static const BYTE SMB_COM_TREE_CONNECT_ANDX_bytes[] = { 9, 0, 'A', ':', 0, 'F', 'A', 'T', '3', '2', 0 }; |
85 | static BYTE SMB_COM_TREE_CONNECT_ANDX_params[] = { 3, 255, 0, 0, 0, 0, 0 }; | 89 | static BYTE SMB_COM_TREE_CONNECT_ANDX_params[] = { 3, 255, 0, 0, 0, 0, 0 }; |
86 | 90 | ||
87 | static SMB_STATUS handle_SMB_COM_TREE_CONNECT_ANDX( SMB_HEADER *header, SMB_DATA *data ){ | 91 | static 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 ) { | 116 | static 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( ¶ms->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 | ||
116 | static int command_handler_match(const void *a, const void *b ) { return *(BYTE*)a - *(BYTE*)b; } | 157 | static 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*/ |
120 | static SMB_COMMAND_HANDLER command_handler[] = { | 161 | static 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 | ||
128 | static void child( ) { | 169 | static 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; | |||
16 | typedef int64_t QWORD; | 16 | typedef 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 | ||
83 | typedef struct { | 84 | typedef 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 | |||
105 | typedef 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 |