diff options
author | Ralph Boehme <slow@samba.org> | 2015-11-15 11:12:34 +0100 |
---|---|---|
committer | Ralph Boehme <slow@samba.org> | 2016-01-22 07:52:21 +0100 |
commit | 9d284431fc478bc6e19ac2d98b3c330800521ad3 (patch) | |
tree | a27dd36a20a87fab9facec69813bb296269f40e1 | |
parent | fe5353c82ee41ef620aa8340acd4748dd3bc795f (diff) | |
download | samba-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.idl | 5 | ||||
-rw-r--r-- | source3/smbd/globals.h | 2 | ||||
-rw-r--r-- | source3/smbd/smb2_server.c | 33 |
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; |