summaryrefslogtreecommitdiff
path: root/source4/libcli/smb2/transport.c
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2008-05-30 17:03:54 +1000
committerAndrew Tridgell <tridge@samba.org>2008-05-30 17:03:54 +1000
commitbeaa01e403dda7557a6acdf0181d79d58a33bbbe (patch)
tree88c5930b546271d0bb9700096bdcdb6d97448e33 /source4/libcli/smb2/transport.c
parent27f465619b2d8e01397b6d15434c9f2c577c5457 (diff)
downloadsamba-beaa01e403dda7557a6acdf0181d79d58a33bbbe.tar.gz
samba-beaa01e403dda7557a6acdf0181d79d58a33bbbe.tar.bz2
samba-beaa01e403dda7557a6acdf0181d79d58a33bbbe.zip
implemented client side SMB2 signing
This doessn't work against Windows yet, and I've submitted a WSPP request for clarification of the docs to try and find out why. Meanwhile this is no worse than what we had, as it only gets used when the server demands signing, and we didn't work then anyway. (This used to be commit b788096add3586d7277efcd3bf5ca7f3a604cb7a)
Diffstat (limited to 'source4/libcli/smb2/transport.c')
-rw-r--r--source4/libcli/smb2/transport.c49
1 files changed, 31 insertions, 18 deletions
diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c
index 8eb60a06f1..561b6e528e 100644
--- a/source4/libcli/smb2/transport.c
+++ b/source4/libcli/smb2/transport.c
@@ -74,7 +74,8 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob);
create a transport structure based on an established socket
*/
struct smb2_transport *smb2_transport_init(struct smbcli_socket *sock,
- TALLOC_CTX *parent_ctx)
+ TALLOC_CTX *parent_ctx,
+ struct smbcli_options *options)
{
struct smb2_transport *transport;
@@ -82,6 +83,7 @@ struct smb2_transport *smb2_transport_init(struct smbcli_socket *sock,
if (!transport) return NULL;
transport->socket = talloc_steal(transport, sock);
+ transport->options = *options;
/* setup the stream -> packet parser */
transport->packet = packet_init(transport);
@@ -112,8 +114,6 @@ struct smb2_transport *smb2_transport_init(struct smbcli_socket *sock,
talloc_set_destructor(transport, transport_destructor);
- transport->options.timeout = 30;
-
return transport;
}
@@ -140,27 +140,24 @@ void smb2_transport_dead(struct smb2_transport *transport, NTSTATUS status)
}
}
-static bool smb2_handle_oplock_break(struct smb2_transport *transport,
- const DATA_BLOB *blob)
+static NTSTATUS smb2_handle_oplock_break(struct smb2_transport *transport,
+ const DATA_BLOB *blob)
{
uint8_t *hdr;
uint16_t opcode;
- uint64_t seqnum;
hdr = blob->data+NBT_HDR_SIZE;
if (blob->length < (SMB2_MIN_SIZE+0x18)) {
DEBUG(1,("Discarding smb2 oplock reply of size %u\n",
- blob->length));
- return false;
+ (unsigned)blob->length));
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
}
opcode = SVAL(hdr, SMB2_HDR_OPCODE);
- seqnum = BVAL(hdr, SMB2_HDR_MESSAGE_ID);
- if ((opcode != SMB2_OP_BREAK) ||
- (seqnum != UINT64_MAX)) {
- return false;
+ if (opcode != SMB2_OP_BREAK) {
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
}
if (transport->oplock.handler) {
@@ -173,9 +170,11 @@ static bool smb2_handle_oplock_break(struct smb2_transport *transport,
transport->oplock.handler(transport, &h, level,
transport->oplock.private_data);
+ } else {
+ DEBUG(5,("Got SMB2 oplock break with no handler\n"));
}
- return true;
+ return NT_STATUS_OK;
}
/*
@@ -194,6 +193,7 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob)
uint16_t buffer_code;
uint32_t dynamic_size;
uint32_t i;
+ NTSTATUS status;
buffer = blob.data;
len = blob.length;
@@ -205,14 +205,20 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob)
goto error;
}
- if (smb2_handle_oplock_break(transport, &blob)) {
+ status = smb2_check_signature(transport, buffer, len);
+ if (!NT_STATUS_IS_OK(status)) {
talloc_free(buffer);
- return NT_STATUS_OK;
+ return status;
}
-
+
flags = IVAL(hdr, SMB2_HDR_FLAGS);
seqnum = BVAL(hdr, SMB2_HDR_MESSAGE_ID);
+ /* see MS-SMB2 3.2.5.19 */
+ if (seqnum == UINT64_MAX) {
+ return smb2_handle_oplock_break(transport, &blob);
+ }
+
/* match the incoming request against the list of pending requests */
for (req=transport->pending_recv; req; req=req->next) {
if (req->seqnum == seqnum) break;
@@ -340,6 +346,13 @@ void smb2_transport_send(struct smb2_request *req)
return;
}
+ status = smb2_sign_message(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ req->state = SMB2_REQUEST_ERROR;
+ req->status = status;
+ return;
+ }
+
blob = data_blob_const(req->out.buffer, req->out.size);
status = packet_send(req->transport->packet, blob);
if (!NT_STATUS_IS_OK(status)) {
@@ -352,9 +365,9 @@ void smb2_transport_send(struct smb2_request *req)
DLIST_ADD(req->transport->pending_recv, req);
/* add a timeout */
- if (req->transport->options.timeout) {
+ if (req->transport->options.request_timeout) {
event_add_timed(req->transport->socket->event.ctx, req,
- timeval_current_ofs(req->transport->options.timeout, 0),
+ timeval_current_ofs(req->transport->options.request_timeout, 0),
smb2_timeout_handler, req);
}