Re: [PATCH 07/19] cifs: break out decoding of security blob into separate function

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



2013/5/23 Jeff Layton <jlayton@xxxxxxxxxx>:
> ...cleanup.
>
> Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx>
> ---
>  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
> --
> 1.8.1.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

Acked-by: Pavel Shilovsky <piastry@xxxxxxxxxxx>

--
Best regards,
Pavel Shilovsky.
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux