From b74bef8f7d3452f9a5aee4c934c9ff62afc2b2bd Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Mon, 30 Nov 2015 17:03:26 +0100 Subject: [PATCH] smbstatus: add support for SMB1 signing and CIFS UNIX extensions encryption MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison Autobuild-User(master): Ralph Böhme Autobuild-Date(master): Fri Jan 22 11:06:05 CET 2016 on sn-devel-144 --- source3/smbd/process.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++ source3/utils/status.c | 12 ++++++++ 2 files changed, 89 insertions(+) diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 79ca91fe820..e5c52bebdd0 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -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; } diff --git a/source3/utils/status.c b/source3/utils/status.c index 4717234304a..9aefd5eb97f 100644 --- a/source3/utils/status.c +++ b/source3/utils/status.c @@ -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)"; } } -- 2.11.4.GIT