summaryrefslogtreecommitdiff
path: root/src/nu_server.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nu_server.c')
-rwxr-xr-xsrc/nu_server.c131
1 files changed, 80 insertions, 51 deletions
diff --git a/src/nu_server.c b/src/nu_server.c
index ddd555e..d79967c 100755
--- a/src/nu_server.c
+++ b/src/nu_server.c
@@ -32,30 +32,58 @@ static void netbios_read( SMB_HEADER **buf) {
32 bailout( "Short read." ); 32 bailout( "Short read." );
33} 33}
34 34
35static void netbios_write( SMB_COMMAND cmd, 35static void netbios_write( SMB_HEADER *buf,
36 SMB_HEADER *buf, 36 SMB_DATA *data,
37 SMB_PARAMS *buf2, 37 int datacount ) {
38 SMB_BYTES *buf3 ) { 38 struct iovec iov[1 + 2 * SMB_MAXREQUEST] = { {buf , sizeof(SMB_HEADER) } };
39 BYTE buf_[4] = { 0, 0, 0, 0 }; 39 int i, sizeout = sizeof( SMB_HEADER );
40 if(!buf2 ) buf2 = (SMB_PARAMS*)buf_; 40
41 if(!buf3 ) buf3 = (SMB_BYTES*)buf_; 41 for( i=0; i < datacount; ++i )
42 42 iov[1+2*i].iov_base = data[i].params,
43 struct iovec iov[16] = { {buf , sizeof(SMB_HEADER) }, 43 sizeout += iov[1+2*i].iov_len = 1 + data[i].params->WordCount * 2,
44 {buf2, 1 + buf2->WordCount * 2}, 44 iov[2+2*i].iov_base = data[i].bytes,
45 {buf3, 2 + buf3->ByteCount } }; 45 sizeout += iov[2+2*i].iov_len = 2 + data[i].bytes->ByteCount;
46 46
47 buf->netbios_command = cmd; 47 buf->netbios_command = buf->netbios_flags = 0;
48 buf->netbios_flags = 0; 48 buf->netbios_size = htons( sizeout );
49 buf->netbios_size = htons( sizeof(SMB_HEADER) - 4 +
50 1 + buf2->WordCount * 2 +
51 2 + buf3->ByteCount );
52 buf->Flags = 0x88; 49 buf->Flags = 0x88;
53 buf->Flags2 = 0x4001; 50 buf->Flags2 = 0x4001;
54 51
55 if( writev( childsock, iov, 3 ) < htons( buf->netbios_size ) + 4 ) 52 if( writev( childsock, iov, 1 + 2 * datacount ) < sizeout + 4 )
56 bailout( "Write failed." ); 53 bailout( "Write failed." );
57} 54}
58 55
56static const BYTE SMB_COM_NEGOTIATE_bytes[] = { 8,0,0x67,0x61,0x74,0x6c,0x69,0x6e,0x67,0 };
57static WORD SMB_COM_NEGOTIATE_params[] = {
580x0511, 0x0000, 0x0001, 0x0001, 0x0000, 0x0100, 0x0000, 0x0100, 0x0000,
590x0000, 0xC049, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };
60
61static SMB_STATUS handle_SMB_COM_NEGOTIATE( SMB_DATA *data ) {
62 struct timeval t; gettimeofday( &t, NULL );
63 SMB_COM_NEGOTIATE_params[8] = getpid();
64 SMB_COM_NEGOTIATE_params[9] = getppid();
65 *(QWORD*)(SMB_COM_NEGOTIATE_params+12) = getnttime( &t );
66
67 data->params = SMB_COM_NEGOTIATE_bytes; data->bytes = SMB_COM_NEGOTIATE_params;
68 return STATUS_SUCCESS;
69}
70
71static const BYTE SMB_SESSION_SETUP_ANDX_bytes[] = {
7219,0,'O','S',0,'g','a','t','l','i','n','g',0,'g','a','t','l','i','n','g',0};
73static BYTE SMB_SESSION_SETUP_ANDX_params[] = { 4, 0, 0, 23, 0, 1, 0, 0, 0 };
74
75static SMB_STATUS handle_SMB_SESSION_SETUP_ANDX( SMB_DATA *data ) {
76 data->params = SMB_SESSION_SETUP_ANDX_bytes; data->bytes = SMB_SESSION_SETUP_ANDX_params;
77 return STATUS_SUCCESS;
78}
79
80static‰int command_handler_match( const void *a, const void *b ) { return *(BYTE*)a - *(BYTE*)b; }
81static SMB_COMMAND_HANDLER command_handler[] = {
82 { { SMB_COM_NEGOTIATE, 0x00, handle_SMB_COM_NEGOTIATE },
83 { SMB_COM_SESSION_SETUP_ANDX, 0x01, handle_SMB_COM_SESSION_SETUP_ANDX }
84 }
85};
86
59static void child( ) { 87static void child( ) {
60 SMB_HEADER *inpacket = NULL; 88 SMB_HEADER *inpacket = NULL;
61 89
@@ -69,6 +97,12 @@ static void child( ) {
69 write( childsock, inpacket, 4); 97 write( childsock, inpacket, 4);
70 98
71 while( 1 ) { 99 while( 1 ) {
100 SMB_COMMAND cmd;
101 SMB_DATA requests[ 1 + SMB_MAXREQUESTS ];
102 SMB_STATUS status = STATUS_SUCCESS;
103 WORD sizeout = sizeof( SMB_HEADER );
104 int num_requests = 0;
105
72 netbios_read( &inpacket ); 106 netbios_read( &inpacket );
73 107
74 if( inpacket->netbios_command != 0 ) 108 if( inpacket->netbios_command != 0 )
@@ -76,46 +110,41 @@ static void child( ) {
76 if( inpacket->Protocol != SMB_HEADER_PROTOCOL_MAGIC ) 110 if( inpacket->Protocol != SMB_HEADER_PROTOCOL_MAGIC )
77 bailout( "Protocol identifier mismatch"); 111 bailout( "Protocol identifier mismatch");
78 112
79 switch( inpacket->Command ) { 113 cmd = inpacket->Command;
80 case SMB_COM_NEGOTIATE: 114 requests[ 0 ].params = (SMB_PARAMS*)(inpacket+1);
81 { 115
82 const BYTE bytes[] = { 8,0,0x67,0x61,0x74,0x6c,0x69,0x6e,0x67,0 }; 116 while( (status == STATUS_SUCCESS) && (cmd != 0xff) ) {
83 WORD params[] = { 0x0511, 0x0000, 0x0001, 0x0001, 0x0000, 0x0100, 117 SMB_COMMAND_HANDLER *handler = (SMB_COMMAND_HANDLER*)bsearch( cmd, command_handler,
84 0x0000, 0x0100, 0x0000, 0x0000, 0xC049, 0x0000, 118 sizeof(command_handler)/sizeof(*command_handler), sizeof(*command_handler), command_handler_match);
85 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }; 119
86 struct timeval t; gettimeofday( &t, NULL ); 120 requests[ num_request ].bytes = 2 + *((WORD*)requests[ num_request ].params) + (BYTE*)requests[ num_request ].params;
87 121 if( handler ) {
88 *(DWORD*)&inpacket->Status = STATUS_SUCCESS; 122 if( handler->flags & SMB_COMMAND_FLAG_ANDX ) {
89 params[8] = getpid(); params[9] = getppid(); 123 cmd = ((BYTE*)requests[ num_requests ].params)[3];
90 *(QWORD*)&params[12] = getnttime( &t ); 124 requests[ num_requests+1 ].params = ((BYTE*)inpacket) + ((WORD*)requests[ num_requests ].params)[2];
91 netbios_write( 0, inpacket, (SMB_PARAMS*)params, (SMB_BYTES*)bytes); 125 }
92 break; 126
93 } 127 status = handler->handler( &requests( num_requests ) );
94/* case SMB_COM_SESSION_SETUP_ANDX: 128
95 { 129 if( (status == STATUS_SUCCESS) && (handler->flags & SMB_COMMAND_FLAG_ANDX) ) {
96 const BYTE bytes[] = { 19, 0, 'O', 'S', 0, 'g', 'a', 't', 'l', 130 sizeout += 3 + 2 * requests[ num_requests ].params->WordCount + requests[ num_requests ].bytes->ByteCount;
97 'i', 'n', 'g', 0, 'g', 'a', 't', 'l', 'i', 131 ((WORD*)requests[ num_requests ].params)[2] = sizeout;
98 'n', 'g', 0}; 132 ((BYTE*)requests[ num_requests ].params)[3] = cmd;
99 BYTE params[] = { 4, 0, 0, 23, 0, 1, 0, 0, 0 }; 133 }
100 134 num_requests++;
101 } */ 135 } else
102 default: 136 status = 0x00400002;
103 {
104 fprintf( stderr, "Got message: %02X\n", inpacket->Command );
105 *(DWORD*)&inpacket->Status = 0x00400002;
106 netbios_write( 0, inpacket, NULL, NULL );
107 break;
108 }
109 } 137 }
110 138
139 memcpy( inpacket->status, &status, 4 ); /* not aligned, maybe we might do a store DWORD on x86 */
140 netbios_write( inpacket, requests, num_requests );
111 } /* End main loop */ 141 } /* End main loop */
112} 142}
113 143
114int main() 144int main() {
115{
116 struct sockaddr_in sa; 145 struct sockaddr_in sa;
117 int l=1; 146 int l=1;
118 147
119 signal( SIGINT, sigint); 148 signal( SIGINT, sigint);
120 149
121 bzero( &sa, sizeof( sa)); 150 bzero( &sa, sizeof( sa));