summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRalph Boehme <slow@samba.org>2015-11-15 11:12:34 +0100
committerRalph Boehme <slow@samba.org>2016-01-22 07:52:21 +0100
commit9d284431fc478bc6e19ac2d98b3c330800521ad3 (patch)
treea27dd36a20a87fab9facec69813bb296269f40e1
parentfe5353c82ee41ef620aa8340acd4748dd3bc795f (diff)
downloadsamba-9d284431fc478bc6e19ac2d98b3c330800521ad3.tar.gz
s3:smb2_server: add signing state tracking flags
Add flags that track the signing state of all incoming and outgoing SMB2 packets and a helper function that can be used to determine whether a session of tcon can be considered "signed". Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
-rw-r--r--source3/librpc/idl/smbXsrv.idl5
-rw-r--r--source3/smbd/globals.h2
-rw-r--r--source3/smbd/smb2_server.c33
3 files changed, 38 insertions, 2 deletions
diff --git a/source3/librpc/idl/smbXsrv.idl b/source3/librpc/idl/smbXsrv.idl
index f6a5fd98c36..852877096ae 100644
--- a/source3/librpc/idl/smbXsrv.idl
+++ b/source3/librpc/idl/smbXsrv.idl
@@ -124,7 +124,9 @@ interface smbXsrv
} smbXsrv_encrpytion_flags;
typedef [public,bitmap8bit] bitmap {
- SMBXSRV_SIGNING_REQUIRED = 0x01
+ SMBXSRV_SIGNING_REQUIRED = 0x01,
+ SMBXSRV_PROCESSED_SIGNED_PACKET = 0x02,
+ SMBXSRV_PROCESSED_UNSIGNED_PACKET = 0x04
} smbXsrv_signing_flags;
typedef struct {
@@ -275,6 +277,7 @@ interface smbXsrv
* for SMB1 this is the session that the tcon was opened on
*/
uint32 session_global_id;
+ smbXsrv_signing_flags signing_flags;
} smbXsrv_tcon_global0;
typedef union {
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 676ab75b2f4..90d8dccfa09 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -639,6 +639,8 @@ NTSTATUS smbXsrv_open_cleanup(uint64_t persistent_id);
bool smbXsrv_is_encrypted(uint8_t encryption_flags);
bool smbXsrv_is_partially_encrypted(uint8_t encryption_flags);
bool smbXsrv_set_crypto_flag(uint8_t *flags, uint8_t flag);
+bool smbXsrv_is_signed(uint8_t signing_flags);
+bool smbXsrv_is_partially_signed(uint8_t signing_flags);
struct smbd_smb2_send_queue {
struct smbd_smb2_send_queue *prev, *next;
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index a9916cca2a8..9adbb996067 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -2039,23 +2039,37 @@ static void smb2srv_update_crypto_flags(struct smbd_smb2_request *req,
bool *update_session_globalp,
bool *update_tcon_globalp)
{
- /* Default: assume unecrypted */
+ /* Default: assume unecrypted and unsigned */
struct smbXsrv_session *session = req->session;
struct smbXsrv_tcon *tcon = req->tcon;
uint8_t encrypt_flag = SMBXSRV_PROCESSED_UNENCRYPTED_PACKET;
+ uint8_t sign_flag = SMBXSRV_PROCESSED_UNSIGNED_PACKET;
bool update_session = false;
bool update_tcon = false;
if (req->was_encrypted && req->do_encryption) {
encrypt_flag = SMBXSRV_PROCESSED_ENCRYPTED_PACKET;
+ sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
+ } else {
+ /* Unencrypted packet, can be signed */
+ if (req->do_signing) {
+ sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
+ } else if (opcode == SMB2_OP_CANCEL) {
+ /* Cancel requests are allowed to skip signing */
+ sign_flag &= ~SMBXSRV_PROCESSED_UNSIGNED_PACKET;
+ }
}
update_session |= smbXsrv_set_crypto_flag(
&session->global->encryption_flags, encrypt_flag);
+ update_session |= smbXsrv_set_crypto_flag(
+ &session->global->signing_flags, sign_flag);
if (tcon) {
update_tcon |= smbXsrv_set_crypto_flag(
&tcon->global->encryption_flags, encrypt_flag);
+ update_tcon |= smbXsrv_set_crypto_flag(
+ &tcon->global->signing_flags, sign_flag);
}
*update_session_globalp = update_session;
@@ -2063,6 +2077,23 @@ static void smb2srv_update_crypto_flags(struct smbd_smb2_request *req,
return;
}
+bool smbXsrv_is_signed(uint8_t signing_flags)
+{
+ /*
+ * Signing is always enabled, so unless we got an unsigned
+ * packet and at least one signed packet that was not
+ * encrypted, the session or tcon is "signed".
+ */
+ return (!(signing_flags & SMBXSRV_PROCESSED_UNSIGNED_PACKET) &&
+ (signing_flags & SMBXSRV_PROCESSED_SIGNED_PACKET));
+}
+
+bool smbXsrv_is_partially_signed(uint8_t signing_flags)
+{
+ return ((signing_flags & SMBXSRV_PROCESSED_UNSIGNED_PACKET) &&
+ (signing_flags & SMBXSRV_PROCESSED_SIGNED_PACKET));
+}
+
NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
{
struct smbXsrv_connection *xconn = req->xconn;