From patchwork Thu May 23 15:05:51 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 2607531 Return-Path: X-Original-To: patchwork-cifs-client@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 37290DFF69 for ; Thu, 23 May 2013 15:06:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758002Ab3EWPGX (ORCPT ); Thu, 23 May 2013 11:06:23 -0400 Received: from mail-qa0-f46.google.com ([209.85.216.46]:53657 "EHLO mail-qa0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1759301Ab3EWPGS (ORCPT ); Thu, 23 May 2013 11:06:18 -0400 Received: by mail-qa0-f46.google.com with SMTP id bv4so3475849qab.19 for ; Thu, 23 May 2013 08:06:17 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references:x-gm-message-state; bh=STwXDNwTmFrYPNAktCKfbzAQ2xbCHP42MBSjkfkoH9U=; b=Muo8lgzG+4RjhcizN2L5hn9R3RWOp/RguiFlAbGZTW44mtxRV9ZMlaS3VVcYr50rDG 7bWDrgQOG0U+u6/C4ouvl19qgl/D330HfkieLeZ3FIcl3kPlKNfD3PGdIfwE2yLT2EEu gjYqrO0mbVT8YeFmNL5C4fiA63l3Gslqxc5K3Sl+WqTa91pTbgADR2+A4Czd+Mw2O9ka /vf2IOStcsmEaJMqSeNHwRAdCyXhOJSvkm3hjI+UednkEWE45FzJsXsePy5B99k5WkuK yvq3ttZt2GKk2rPvNeqPiGTIz6li4IoKJndMYycG/SNMh7BZ/q4hBwi6aWTGzvoiA2Vw 8PIQ== X-Received: by 10.229.164.79 with SMTP id d15mr4597636qcy.3.1369321577021; Thu, 23 May 2013 08:06:17 -0700 (PDT) Received: from salusa.poochiereds.net (cpe-107-015-113-143.nc.res.rr.com. [107.15.113.143]) by mx.google.com with ESMTPSA id y1sm12688520qad.5.2013.05.23.08.06.15 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Thu, 23 May 2013 08:06:16 -0700 (PDT) From: Jeff Layton To: smfrench@gmail.com Cc: linux-cifs@vger.kernel.org, idra@samba.org Subject: [PATCH 07/19] cifs: break out decoding of security blob into separate function Date: Thu, 23 May 2013 11:05:51 -0400 Message-Id: <1369321563-16893-8-git-send-email-jlayton@redhat.com> X-Mailer: git-send-email 1.8.1.4 In-Reply-To: <1369321563-16893-1-git-send-email-jlayton@redhat.com> References: <1369321563-16893-1-git-send-email-jlayton@redhat.com> X-Gm-Message-State: ALoCoQksE/jdgxqQVceBO8PKUN5m29Znxoy/6LnUq6TCci9Rg15M34P+XbEXn8QIuqCoSFsC/e1G Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org ...cleanup. Signed-off-by: Jeff Layton Acked-by: Pavel Shilovsky --- fs/cifs/cifspdu.h | 4 +- fs/cifs/cifssmb.c | 109 ++++++++++++++++++++++++++++++------------------------ 2 files changed, 62 insertions(+), 51 deletions(-) diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index e996ff6..4e6135a 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h @@ -531,7 +531,7 @@ typedef struct lanman_neg_rsp { #define READ_RAW_ENABLE 1 #define WRITE_RAW_ENABLE 2 #define RAW_ENABLE (READ_RAW_ENABLE | WRITE_RAW_ENABLE) - +#define SMB1_CLIENT_GUID_SIZE (16) typedef struct negotiate_rsp { struct smb_hdr hdr; /* wct = 17 */ __le16 DialectIndex; /* 0xFFFF = no dialect acceptable */ @@ -553,7 +553,7 @@ typedef struct negotiate_rsp { /* followed by 16 bytes of server GUID */ /* then security blob if cap_extended_security negotiated */ struct { - unsigned char GUID[16]; + unsigned char GUID[SMB1_CLIENT_GUID_SIZE]; unsigned char SecurityBlob[1]; } __attribute__((packed)) extended_response; } __attribute__((packed)) u; diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index c1c2006..9b4aea8 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -367,6 +367,56 @@ vt2_err: return -EINVAL; } +static int +decode_ext_sec_blob(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr) +{ + int rc = 0; + u16 count; + char *guid = pSMBr->u.extended_response.GUID; + + count = get_bcc(&pSMBr->hdr); + if (count < SMB1_CLIENT_GUID_SIZE) + return -EIO; + + spin_lock(&cifs_tcp_ses_lock); + if (server->srv_count > 1) { + spin_unlock(&cifs_tcp_ses_lock); + if (memcmp(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE) != 0) { + cifs_dbg(FYI, "server UID changed\n"); + memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE); + } + } else { + spin_unlock(&cifs_tcp_ses_lock); + memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE); + } + + if (count == SMB1_CLIENT_GUID_SIZE) { + server->secType = RawNTLMSSP; + } else { + count -= SMB1_CLIENT_GUID_SIZE; + rc = decode_negTokenInit( + pSMBr->u.extended_response.SecurityBlob, count, server); + if (rc != 1) + return -EINVAL; + + /* Make sure server supports what we want to use */ + switch(server->secType) { + case Kerberos: + if (!server->sec_kerberos && !server->sec_mskerberos) + return -EOPNOTSUPP; + break; + case RawNTLMSSP: + if (!server->sec_ntlmssp) + return -EOPNOTSUPP; + break; + default: + return -EOPNOTSUPP; + } + } + + return 0; +} + int CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses) { @@ -568,61 +618,22 @@ CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses) server->capabilities = le32_to_cpu(pSMBr->Capabilities); server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone); server->timeAdj *= 60; - if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) { + + if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey, CIFS_CRYPTO_KEY_SIZE); - } else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC || + else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC || server->capabilities & CAP_EXTENDED_SECURITY) && - (pSMBr->EncryptionKeyLength == 0)) { - /* decode security blob */ - count = get_bcc(&pSMBr->hdr); - if (count < 16) { - rc = -EIO; - goto neg_err_exit; - } - spin_lock(&cifs_tcp_ses_lock); - if (server->srv_count > 1) { - spin_unlock(&cifs_tcp_ses_lock); - if (memcmp(server->server_GUID, - pSMBr->u.extended_response. - GUID, 16) != 0) { - cifs_dbg(FYI, "server UID changed\n"); - memcpy(server->server_GUID, - pSMBr->u.extended_response.GUID, - 16); - } - } else { - spin_unlock(&cifs_tcp_ses_lock); - memcpy(server->server_GUID, - pSMBr->u.extended_response.GUID, 16); - } - - if (count == 16) { - server->secType = RawNTLMSSP; - } else { - rc = decode_negTokenInit(pSMBr->u.extended_response. - SecurityBlob, count - 16, - server); - if (rc == 1) - rc = 0; - else - rc = -EINVAL; - if (server->secType == Kerberos) { - if (!server->sec_kerberos && - !server->sec_mskerberos) - rc = -EOPNOTSUPP; - } else if (server->secType == RawNTLMSSP) { - if (!server->sec_ntlmssp) - rc = -EOPNOTSUPP; - } else - rc = -EOPNOTSUPP; - } - } else if (server->sec_mode & SECMODE_PW_ENCRYPT) { + (pSMBr->EncryptionKeyLength == 0)) + rc = decode_ext_sec_blob(server, pSMBr); + else if (server->sec_mode & SECMODE_PW_ENCRYPT) rc = -EIO; /* no crypt key only if plain text pwd */ - goto neg_err_exit; - } else + else server->capabilities &= ~CAP_EXTENDED_SECURITY; + if (rc) + goto neg_err_exit; + #ifdef CONFIG_CIFS_WEAK_PW_HASH signing_check: #endif