summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2012-07-23 09:16:05 +0200
committerStefan Metzmacher <metze@samba.org>2012-07-23 18:19:36 +0200
commitbe8e33ec5416ebc57114dd2c1472ed0faffd05bb (patch)
tree62cd56d7674ef46c393b47c178cf8c01c4f56da5
parentc2b0a485136925ba8c9661d2b97b69dfeed5d5de (diff)
downloadsamba-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.c63
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;