diff options
Diffstat (limited to 'src/nu_server.c')
| -rwxr-xr-x | src/nu_server.c | 131 |
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 | ||
| 35 | static void netbios_write( SMB_COMMAND cmd, | 35 | static 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 | ||
| 56 | static const BYTE SMB_COM_NEGOTIATE_bytes[] = { 8,0,0x67,0x61,0x74,0x6c,0x69,0x6e,0x67,0 }; | ||
| 57 | static WORD SMB_COM_NEGOTIATE_params[] = { | ||
| 58 | 0x0511, 0x0000, 0x0001, 0x0001, 0x0000, 0x0100, 0x0000, 0x0100, 0x0000, | ||
| 59 | 0x0000, 0xC049, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }; | ||
| 60 | |||
| 61 | static 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 | |||
| 71 | static const BYTE SMB_SESSION_SETUP_ANDX_bytes[] = { | ||
| 72 | 19,0,'O','S',0,'g','a','t','l','i','n','g',0,'g','a','t','l','i','n','g',0}; | ||
| 73 | static BYTE SMB_SESSION_SETUP_ANDX_params[] = { 4, 0, 0, 23, 0, 1, 0, 0, 0 }; | ||
| 74 | |||
| 75 | static 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 | |||
| 80 | static‰int command_handler_match( const void *a, const void *b ) { return *(BYTE*)a - *(BYTE*)b; } | ||
| 81 | static 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 | |||
| 59 | static void child( ) { | 87 | static 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*)¶ms[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 | ||
| 114 | int main() | 144 | int 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)); |
