smbstatus: add support for SMB1 signing and CIFS UNIX extensions encryption
authorRalph Boehme <slow@samba.org>
Mon, 30 Nov 2015 16:03:26 +0000 (17:03 +0100)
committerRalph Boehme <slow@samba.org>
Fri, 22 Jan 2016 10:06:05 +0000 (11:06 +0100)
Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Ralph Böhme <slow@samba.org>
Autobuild-Date(master): Fri Jan 22 11:06:05 CET 2016 on sn-devel-144

source3/smbd/process.c
source3/utils/status.c

index 79ca91fe820892b37cd0993c85e8f033a9a14ed5..e5c52bebdd0edfe43549fbd6c0302cdfc0a97458 100644 (file)
@@ -1431,6 +1431,54 @@ static void smb_dump(const char *name, int type, const char *data)
        TALLOC_FREE(fname);
 }
 
+static void smb1srv_update_crypto_flags(struct smbXsrv_session *session,
+                                       struct smb_request *req,
+                                       uint8_t type,
+                                       bool *update_session_globalp,
+                                       bool *update_tcon_globalp)
+{
+       connection_struct *conn = req->conn;
+       struct smbXsrv_tcon *tcon = conn ? conn->tcon : NULL;
+       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->encrypted) {
+               encrypt_flag = SMBXSRV_PROCESSED_ENCRYPTED_PACKET;
+       }
+
+       if (srv_is_signing_active(req->xconn)) {
+               sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
+       } else if ((type == SMBecho) || (type == SMBsesssetupX)) {
+               /*
+                * echo can be unsigned. Sesssion setup except final
+                * session setup response too
+                */
+               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);
+       }
+
+       if (update_session) {
+               session->global->channels[0].encryption_cipher = SMB_ENCRYPTION_GSSAPI;
+       }
+
+       *update_session_globalp = update_session;
+       *update_tcon_globalp = update_tcon;
+       return;
+}
+
 /****************************************************************************
  Prepare everything for calling the actual request function, and potentially
  call the request function via the "new" interface.
@@ -1647,6 +1695,35 @@ static connection_struct *switch_message(uint8_t type, struct smb_request *req)
                }
        }
 
+       /*
+        * Update encryption and signing state tracking flags that are
+        * used by smbstatus to display signing and encryption status.
+        */
+       if (session != NULL) {
+               bool update_session_global = false;
+               bool update_tcon_global = false;
+
+               smb1srv_update_crypto_flags(session, req, type,
+                                           &update_session_global,
+                                           &update_tcon_global);
+
+               if (update_session_global) {
+                       status = smbXsrv_session_update(session);
+                       if (!NT_STATUS_IS_OK(status)) {
+                               reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
+                               return conn;
+                       }
+               }
+
+               if (update_tcon_global) {
+                       status = smbXsrv_tcon_update(req->conn->tcon);
+                       if (!NT_STATUS_IS_OK(status)) {
+                               reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
+                               return conn;
+                       }
+               }
+       }
+
        smb_messages[type].fn(req);
        return req->conn;
 }
index 4717234304a20e18c8b2d4df2c3f212ee73ec9e4..9aefd5eb97fc571a59796b29b7388049dce41042 100644 (file)
@@ -322,6 +322,9 @@ static int traverse_connections(const struct connections_key *key,
 
        if (smbXsrv_is_encrypted(crec->encryption_flags)) {
                switch (crec->cipher) {
+               case SMB_ENCRYPTION_GSSAPI:
+                       encryption = "GSSAPI";
+                       break;
                case SMB2_ENCRYPTION_AES128_CCM:
                        encryption = "AES-128-CCM";
                        break;
@@ -340,6 +343,8 @@ static int traverse_connections(const struct connections_key *key,
                        signing = "AES-128-CMAC";
                } else if (crec->dialect >= SMB2_DIALECT_REVISION_202) {
                        signing = "HMAC-SHA256";
+               } else {
+                       signing = "HMAC-MD5";
                }
        }
 
@@ -416,6 +421,9 @@ static int traverse_sessionid(const char *key, struct sessionid *session,
                }
        } else if (smbXsrv_is_partially_encrypted(session->encryption_flags)) {
                switch (session->cipher) {
+               case SMB_ENCRYPTION_GSSAPI:
+                       encryption = "partial(GSSAPI)";
+                       break;
                case SMB2_ENCRYPTION_AES128_CCM:
                        encryption = "partial(AES-128-CCM)";
                        break;
@@ -434,12 +442,16 @@ static int traverse_sessionid(const char *key, struct sessionid *session,
                        signing = "AES-128-CMAC";
                } else if (session->connection_dialect >= SMB2_DIALECT_REVISION_202) {
                        signing = "HMAC-SHA256";
+               } else {
+                       signing = "HMAC-MD5";
                }
        } else if (smbXsrv_is_partially_signed(session->signing_flags)) {
                if (session->connection_dialect >= SMB3_DIALECT_REVISION_302) {
                        signing = "partial(AES-128-CMAC)";
                } else if (session->connection_dialect >= SMB2_DIALECT_REVISION_202) {
                        signing = "partial(HMAC-SHA256)";
+               } else {
+                       signing = "partial(HMAC-MD5)";
                }
        }