restructure smb message writing

This commit is contained in:
Kelvin Sherlock 2014-08-21 15:42:41 -04:00
parent 1c381e5a23
commit 4ee72e3ef8
1 changed files with 132 additions and 29 deletions

161
smb.c
View File

@ -23,9 +23,51 @@
#include "prototypes.h"
#include "smb.h"
static struct smb2_header_sync header;
static void dump_header(const smb2_header_sync *header)
{
fprintf(stderr, " protocol_id: %08lx\n", header->protocol_id);
fprintf(stderr, "structure_size: %04x\n", header->structure_size);
fprintf(stderr, " credit_charge: %04x\n", header->credit_charge);
fprintf(stderr, " status: %08lx\n", header->status);
fprintf(stderr, " command: %04x\n", header->command);
fprintf(stderr, " credit: %04x\n", header->credit);
fprintf(stderr, " flags: %08lx\n", header->flags);
fprintf(stderr, " next_command: %08lx\n", header->next_command);
fprintf(stderr, " message_id: %08lx%08lx\n", header->message_id[1], header->message_id[0]);
fprintf(stderr, " reserved: %08lx\n", header->reserved);
fprintf(stderr, " tree_id: %08lx\n", header->tree_id);
fprintf(stderr, " session_id: %08lx%08lx\n", header->session_id[1], header->session_id[0]);
fprintf(stderr, " signature:\n");
hexdump(header->signature, 16);
}
static void write_message(Word ipid, const void *data1, unsigned size1, const void *data2, unsigned size2)
{
uint8_t nbthead[4];
uint32_t size;
size = sizeof(header) + size1 + size2;
// http://support.microsoft.com/kb/204279
nbthead[0] = 0;
nbthead[1] = size >> 16;
nbthead[2] = size >> 8;
nbthead[3] = size;
if (++header.message_id[0] == 0)
++header.message_id[1];
TCPIPWriteTCP(ipid, (dataPtr)nbthead, sizeof(nbthead), false, false);
TCPIPWriteTCP(ipid, (dataPtr)header, sizeof(header), false, false);
TCPIPWriteTCP(ipid, (dataPtr)data1, size1, false, false);
TCPIPWriteTCP(ipid, (dataPtr)data2, size2, true, false);
}
static Handle read_response(Word ipid)
{
static srBuff sr;
@ -66,7 +108,10 @@ static Handle read_response(Word ipid)
terr = TCPIPReadTCP(ipid, 0, (Ref)&nbthead, 4, &rb);
if (nbthead[0] != 0) return (Handle)0;
if (nbthead[0] != 0) {
fprintf(stderr, "Bad NBT Header\n");
return (Handle)0;
}
size = nbthead[3];
size |= nbthead[2] << 8;
size |= nbthead[1] << 16;
@ -96,46 +141,123 @@ static Handle read_response(Word ipid)
int negotiate(Word ipid)
{
static struct smb2_negotiate_request req;
static struct smb2_negotiate_request negotiate_req;
static struct smb2_session_setup_request setup_req;
static uint16_t dialects[] = { 0x0202 };
smb2_header_sync *headerPtr;
void *responsePtr;
Handle h;
uint8_t nbthead[4];
uint32_t size = 0;
memset(&header, 0, sizeof(header));
memset(&req, 0, sizeof(req));
memset(&negotiate_req, 0, sizeof(negotiate_req));
memset(&setup_req, 0, sizeof(setup_req));
header.protocol_id = SMB2_MAGIC; // '\xfeSMB';
header.structure_size = 64;
header.command = SMB2_NEGOTIATE;
req.structure_size = 36;
req.dialect_count = 1; // ?
req.security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED;
req.capabilities = 0;
negotiate_req.structure_size = 36;
negotiate_req.dialect_count = 1; // ?
negotiate_req.security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED;
negotiate_req.capabilities = 0;
//req.dialects[0] = 0x202; // smb 2.002
//negotiate_req.dialects[0] = 0x202; // smb 2.002
#if 0
// http://support.microsoft.com/kb/204279
size = sizeof(header) + sizeof(req) + sizeof(dialects);
size = sizeof(header) + sizeof(negotiate_req) + sizeof(dialects);
nbthead[0] = 0;
nbthead[1] = size >> 16;
nbthead[2] = size >> 8;
nbthead[3] = size;
next_message();
TCPIPWriteTCP(ipid, (dataPtr)nbthead, sizeof(nbthead), false, false);
TCPIPWriteTCP(ipid, (dataPtr)&header, sizeof(header), false, false);
TCPIPWriteTCP(ipid, (dataPtr)&req, sizeof(req), false, false);
TCPIPWriteTCP(ipid, (dataPtr)&negotiate_req, sizeof(negotiate_req), false, false);
TCPIPWriteTCP(ipid, (dataPtr)&dialects, sizeof(dialects), true, false);
// push.
#endif
write_message(ipid, &negotiate_req, sizeof(negotiate_req), dialects, sizeof(dialects));
// read a response...
h = read_response(ipid);
if (!h) return -1;
HLock(h);
hexdump(*h, GetHandleSize(h));
headerPtr = *(smb2_header_sync **)h;
responsePtr = (uint8_t *)headerPtr + sizeof(smb2_header_sync);
dump_header(headerPtr);
if (headerPtr->protocol_id != SMB2_MAGIC || headerPtr->structure_size != 64)
{
DisposeHandle(h);
fprintf(stderr, "Invalid SMB2 header\n");
return -1;
}
if (headerPtr->command != SMB2_NEGOTIATE)
{
DisposeHandle(h);
fprintf(stderr, "Unexpected SMB2 command\n");
return -1;
}
DisposeHandle(h);
//
header.command = SMB2_SESSION_SETUP;
setup_req.structure_size = 25;
setup_req.flags = 0;
setup_req.security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED;
setup_req.capabilities = 0;
write_message(ipid, &setup_req, sizeof(setup_req), NULL, 0);
h = read_response(ipid);
if (!h) return -1;
HLock(h);
hexdump(*h, GetHandleSize(h));
headerPtr = *(smb2_header_sync **)h;
responsePtr = (uint8_t *)headerPtr + sizeof(smb2_header_sync);
dump_header(headerPtr);
if (headerPtr->protocol_id != SMB2_MAGIC || headerPtr->structure_size != 64)
{
DisposeHandle(h);
fprintf(stderr, "Invalid SMB2 header\n");
return -1;
}
if (headerPtr->command != SMB2_SESSION_SETUP)
{
DisposeHandle(h);
fprintf(stderr, "Unexpected SMB2 command\n");
return -1;
}
DisposeHandle(h);
return 0;
}
@ -174,25 +296,6 @@ int do_smb(char *url, URLComponents *components)
if (ok) return ok;
qtick = GetTick() + 30 * 60;
for(;;)
{
static srBuff sr;
TCPIPPoll();
terr = TCPIPStatusTCP(connection.ipid, &sr);
if (sr.srRcvQueued > 0) break;
if (GetTick() >= qtick)
{
fprintf(stderr, "Read timed out.\n");
return -1;
}
}
CloseLoop(&connection);