diff options
author | Stefan Metzmacher <metze@samba.org> | 2012-07-23 09:16:05 +0200 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2012-07-23 18:19:36 +0200 |
commit | be8e33ec5416ebc57114dd2c1472ed0faffd05bb (patch) | |
tree | 62cd56d7674ef46c393b47c178cf8c01c4f56da5 | |
parent | c2b0a485136925ba8c9661d2b97b69dfeed5d5de (diff) | |
download | samba-be8e33ec5416ebc57114dd2c1472ed0faffd05bb.tar.gz samba-be8e33ec5416ebc57114dd2c1472ed0faffd05bb.tar.bz2 samba-be8e33ec5416ebc57114dd2c1472ed0faffd05bb.zip |
libcli/smb: parse the SMB2_TRANSFORM header and decrypt the SMB2 pdu
metze
-rw-r--r-- | libcli/smb/smbXcli_base.c | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c index 8458fdeaa6..67d5f6a0ea 100644 --- a/libcli/smb/smbXcli_base.c +++ b/libcli/smb/smbXcli_base.c @@ -2760,6 +2760,58 @@ static NTSTATUS smb2cli_inbuf_parse_compound(struct smbXcli_conn *conn, uint16_t body_size; struct iovec *iov_tmp; + if (len < 4) { + DEBUG(10, ("%d bytes left, expected at least %d\n", + (int)len, 4)); + goto inval; + } + if (IVAL(hdr, 0) == SMB2_TF_MAGIC) { + struct smbXcli_session *s; + uint64_t uid; + struct iovec tf_iov[2]; + NTSTATUS status; + + if (len < SMB2_TF_HDR_SIZE) { + DEBUG(10, ("%d bytes left, expected at least %d\n", + (int)len, SMB2_TF_HDR_SIZE)); + goto inval; + } + tf = hdr; + tf_len = SMB2_TF_HDR_SIZE; + taken += tf_len; + + hdr = first_hdr + taken; + len = IVAL(tf, SMB2_TF_MSG_SIZE); + uid = BVAL(tf, SMB2_TF_SESSION_ID); + + s = conn->sessions; + for (; s; s = s->next) { + if (s->smb2.session_id != uid) { + continue; + } + break; + } + + if (s == NULL) { + DEBUG(10, ("unknown session_id %llu\n", + (unsigned long long)uid)); + goto inval; + } + + tf_iov[0].iov_base = (void *)tf; + tf_iov[0].iov_len = tf_len; + tf_iov[1].iov_base = (void *)hdr; + tf_iov[1].iov_len = len; + + status = smb2_signing_decrypt_pdu(s->smb2.decryption_key, + conn->protocol, + tf_iov, 2); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(iov); + return status; + } + } + /* * We need the header plus the body length field */ @@ -2791,6 +2843,9 @@ static NTSTATUS smb2cli_inbuf_parse_compound(struct smbXcli_conn *conn, if (next_command_ofs > full_size) { goto inval; } + if (tf && next_command_ofs < len) { + goto inval; + } full_size = next_command_ofs; } if (body_size < 2) { @@ -2950,6 +3005,14 @@ static NTSTATUS smb2cli_conn_dispatch_incoming(struct smbXcli_conn *conn, } } + /* + * If we have a SMB2_TRANSFORM header we already verified + * a signature. + */ + if (cur[0].iov_len == SMB2_TF_HDR_SIZE) { + should_sign = false; + } + if (should_sign) { if (!(flags & SMB2_HDR_FLAG_SIGNED)) { return NT_STATUS_ACCESS_DENIED; |