libcli/smb: pass hdr/len to smb_signing_check/sign_pdu() and skip the nbt header
authorStefan Metzmacher <metze@samba.org>
Fri, 3 Aug 2012 07:58:29 +0000 (09:58 +0200)
committerStefan Metzmacher <metze@samba.org>
Sat, 4 Aug 2012 07:10:21 +0000 (09:10 +0200)
metze

libcli/smb/smbXcli_base.c
libcli/smb/smb_signing.c
libcli/smb/smb_signing.h
source3/smbd/signing.c

index 37c738ebb662e8274f799bb41a60963518ad967d..29dba8cbc042efa3e1ae92128d20ef6f82cae13b 100644 (file)
@@ -633,7 +633,10 @@ bool smb1cli_conn_activate_signing(struct smbXcli_conn *conn,
 bool smb1cli_conn_check_signing(struct smbXcli_conn *conn,
                                const uint8_t *buf, uint32_t seqnum)
 {
-       return smb_signing_check_pdu(conn->smb1.signing, buf, seqnum);
+       const uint8_t *hdr = buf + NBT_HDR_SIZE;
+       size_t len = smb_len_nbt(buf);
+
+       return smb_signing_check_pdu(conn->smb1.signing, hdr, len, seqnum);
 }
 
 bool smb1cli_conn_signing_is_active(struct smbXcli_conn *conn)
@@ -1339,15 +1342,17 @@ static NTSTATUS smb1cli_conn_signv(struct smbXcli_conn *conn,
 
        frame = talloc_stackframe();
 
-       buf = smbXcli_iov_concat(frame, iov, iov_count);
+       buf = smbXcli_iov_concat(frame, &iov[1], iov_count - 1);
        if (buf == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
 
        *seqnum = smb_signing_next_seqnum(conn->smb1.signing,
                                          one_way_seqnum);
-       smb_signing_sign_pdu(conn->smb1.signing, buf, *seqnum);
-       memcpy(iov[1].iov_base, buf+4, iov[1].iov_len);
+       smb_signing_sign_pdu(conn->smb1.signing,
+                            buf, talloc_get_size(buf),
+                            *seqnum);
+       memcpy(iov[1].iov_base, buf, iov[1].iov_len);
 
        TALLOC_FREE(frame);
        return NT_STATUS_OK;
@@ -1776,7 +1781,8 @@ static NTSTATUS smb1cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
        uint8_t cmd;
        uint16_t mid;
        bool oplock_break;
-       const uint8_t *inhdr = inbuf + NBT_HDR_SIZE;
+       uint8_t *inhdr = inbuf + NBT_HDR_SIZE;
+       size_t len = smb_len_nbt(inbuf);
        struct iovec *iov = NULL;
        int num_iov = 0;
        struct tevent_req **chain = NULL;
@@ -1804,8 +1810,8 @@ static NTSTATUS smb1cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
                        }
                }
 
-               state->smb1.recv_iov[0].iov_base = (void *)(inbuf + NBT_HDR_SIZE);
-               state->smb1.recv_iov[0].iov_len = smb_len_nbt(inbuf);
+               state->smb1.recv_iov[0].iov_base = (void *)(inhdr);
+               state->smb1.recv_iov[0].iov_len = len;
                ZERO_STRUCT(state->smb1.recv_iov[1]);
                ZERO_STRUCT(state->smb1.recv_iov[2]);
 
@@ -1852,6 +1858,8 @@ static NTSTATUS smb1cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
                                   nt_errstr(status)));
                        return status;
                }
+               inhdr = inbuf + NBT_HDR_SIZE;
+               len = smb_len_nbt(inbuf);
        }
 
        mid = SVAL(inhdr, HDR_MID);
@@ -1873,7 +1881,7 @@ static NTSTATUS smb1cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
                /*
                 * Paranoia checks that this is really an oplock break request.
                 */
-               oplock_break = (smb_len_nbt(inbuf) == 51); /* hdr + 8 words */
+               oplock_break = (len == 51); /* hdr + 8 words */
                oplock_break &= ((CVAL(inhdr, HDR_FLG) & FLAG_REPLY) == 0);
                oplock_break &= (CVAL(inhdr, HDR_COM) == SMBlockingX);
                oplock_break &= (SVAL(inhdr, HDR_VWV+VWV(6)) == 0);
@@ -1890,7 +1898,7 @@ static NTSTATUS smb1cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
 
        if (!oplock_break /* oplock breaks are not signed */
            && !smb_signing_check_pdu(conn->smb1.signing,
-                                     inbuf, state->smb1.seqnum+1)) {
+                                     inhdr, len, state->smb1.seqnum+1)) {
                DEBUG(10, ("cli_check_sign_mac failed\n"));
                return NT_STATUS_ACCESS_DENIED;
        }
index 6c598f50f7b23d52e0270c8c34d2e45e4ddec285..2f7e8702ba1a239abb6686c353a5849e4d904f0b 100644 (file)
@@ -216,13 +216,12 @@ void smb_signing_cancel_reply(struct smb_signing_state *si, bool oneway)
 }
 
 void smb_signing_sign_pdu(struct smb_signing_state *si,
-                         uint8_t *outbuf, uint32_t seqnum)
+                         uint8_t *outhdr, size_t len,
+                         uint32_t seqnum)
 {
        uint8_t calc_md5_mac[16];
        uint8_t com;
        uint8_t flags;
-       uint8_t *outhdr = outbuf + NBT_HDR_SIZE;
-       size_t len = smb_len_nbt(outbuf);
 
        if (si->mac_key.length == 0) {
                if (!si->negotiated) {
@@ -279,13 +278,12 @@ void smb_signing_sign_pdu(struct smb_signing_state *si,
 }
 
 bool smb_signing_check_pdu(struct smb_signing_state *si,
-                          const uint8_t *inbuf, uint32_t seqnum)
+                          const uint8_t *inhdr, size_t len,
+                          uint32_t seqnum)
 {
        bool good;
        uint8_t calc_md5_mac[16];
        const uint8_t *reply_sent_mac;
-       const uint8_t *inhdr = inbuf + NBT_HDR_SIZE;
-       size_t len = smb_len_nbt(inbuf);
 
        if (si->mac_key.length == 0) {
                return true;
index b5deec6cde3e8bd47f65b4edf9611972ae30d30b..1e9e1dd8128122b2234c96465b4720befb842349 100644 (file)
@@ -37,9 +37,11 @@ struct smb_signing_state *smb_signing_init_ex(TALLOC_CTX *mem_ctx,
 uint32_t smb_signing_next_seqnum(struct smb_signing_state *si, bool oneway);
 void smb_signing_cancel_reply(struct smb_signing_state *si, bool oneway);
 void smb_signing_sign_pdu(struct smb_signing_state *si,
-                         uint8_t *outbuf, uint32_t seqnum);
+                         uint8_t *outhdr, size_t len,
+                         uint32_t seqnum);
 bool smb_signing_check_pdu(struct smb_signing_state *si,
-                          const uint8_t *inbuf, uint32_t seqnum);
+                          const uint8_t *inhdr, size_t len,
+                          uint32_t seqnum);
 bool smb_signing_activate(struct smb_signing_state *si,
                          const DATA_BLOB user_session_key,
                          const DATA_BLOB response);
index 1661b1bebf9a16e5dc337e340261e49ce17505a0..2b622244c9f8d22fc38d9a05b324e120e1b0e27b 100644 (file)
@@ -66,7 +66,7 @@ bool srv_check_sign_mac(struct smbd_server_connection *conn,
 
        *seqnum = smb_signing_next_seqnum(conn->smb1.signing_state, false);
        return smb_signing_check_pdu(conn->smb1.signing_state,
-                                    (const uint8_t *)inbuf,
+                                    inhdr, len,
                                     *seqnum);
 }
 
@@ -77,12 +77,18 @@ bool srv_check_sign_mac(struct smbd_server_connection *conn,
 void srv_calculate_sign_mac(struct smbd_server_connection *conn,
                            char *outbuf, uint32_t seqnum)
 {
+       uint8_t *outhdr;
+       size_t len;
+
        /* Check if it's a non-session message. */
        if(CVAL(outbuf,0)) {
                return;
        }
 
-       smb_signing_sign_pdu(conn->smb1.signing_state, (uint8_t *)outbuf, seqnum);
+       len = smb_len(outbuf);
+       outhdr = (uint8_t *)outbuf + NBT_HDR_SIZE;
+
+       smb_signing_sign_pdu(conn->smb1.signing_state, outhdr, len, seqnum);
 }