cifs: remove support for NTLM and weaker authentication algorithms
authorRonnie Sahlberg <lsahlber@redhat.com>
Thu, 19 Aug 2021 10:34:58 +0000 (20:34 +1000)
committerSteve French <stfrench@microsoft.com>
Wed, 25 Aug 2021 20:47:06 +0000 (15:47 -0500)
for SMB1.
This removes the dependency to DES.

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
14 files changed:
fs/cifs/Kconfig
fs/cifs/cifs_debug.c
fs/cifs/cifs_swn.c
fs/cifs/cifsencrypt.c
fs/cifs/cifsfs.c
fs/cifs/cifsglob.h
fs/cifs/cifspdu.h
fs/cifs/cifsproto.h
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/fs_context.c
fs/cifs/fs_context.h
fs/cifs/sess.c
fs/cifs/smbencrypt.c

index 7364950..2e8b132 100644 (file)
@@ -16,7 +16,6 @@ config CIFS
        select CRYPTO_GCM
        select CRYPTO_ECB
        select CRYPTO_AES
-       select CRYPTO_LIB_DES
        select KEYS
        select DNS_RESOLVER
        select ASN1
@@ -85,33 +84,6 @@ config CIFS_ALLOW_INSECURE_LEGACY
 
          If unsure, say Y.
 
-config CIFS_WEAK_PW_HASH
-       bool "Support legacy servers which use weaker LANMAN security"
-       depends on CIFS && CIFS_ALLOW_INSECURE_LEGACY
-       help
-         Modern CIFS servers including Samba and most Windows versions
-         (since 1997) support stronger NTLM (and even NTLMv2 and Kerberos)
-         security mechanisms. These hash the password more securely
-         than the mechanisms used in the older LANMAN version of the
-         SMB protocol but LANMAN based authentication is needed to
-         establish sessions with some old SMB servers.
-
-         Enabling this option allows the cifs module to mount to older
-         LANMAN based servers such as OS/2 and Windows 95, but such
-         mounts may be less secure than mounts using NTLM or more recent
-         security mechanisms if you are on a public network.  Unless you
-         have a need to access old SMB servers (and are on a private
-         network) you probably want to say N.  Even if this support
-         is enabled in the kernel build, LANMAN authentication will not be
-         used automatically. At runtime LANMAN mounts are disabled but
-         can be set to required (or optional) either in
-         /proc/fs/cifs (see Documentation/admin-guide/cifs/usage.rst for
-         more detail) or via an option on the mount command. This support
-         is disabled by default in order to reduce the possibility of a
-         downgrade attack.
-
-         If unsure, say N.
-
 config CIFS_UPCALL
        bool "Kerberos/SPNEGO advanced session setup"
        depends on CIFS
index 8857ac7..51a824f 100644 (file)
@@ -250,9 +250,6 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
 #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
        seq_printf(m, ",ALLOW_INSECURE_LEGACY");
 #endif
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
-       seq_printf(m, ",WEAK_PW_HASH");
-#endif
 #ifdef CONFIG_CIFS_POSIX
        seq_printf(m, ",CIFS_POSIX");
 #endif
@@ -929,14 +926,6 @@ cifs_security_flags_handle_must_flags(unsigned int *flags)
                *flags = CIFSSEC_MUST_NTLMSSP;
        else if ((*flags & CIFSSEC_MUST_NTLMV2) == CIFSSEC_MUST_NTLMV2)
                *flags = CIFSSEC_MUST_NTLMV2;
-       else if ((*flags & CIFSSEC_MUST_NTLM) == CIFSSEC_MUST_NTLM)
-               *flags = CIFSSEC_MUST_NTLM;
-       else if (CIFSSEC_MUST_LANMAN &&
-                (*flags & CIFSSEC_MUST_LANMAN) == CIFSSEC_MUST_LANMAN)
-               *flags = CIFSSEC_MUST_LANMAN;
-       else if (CIFSSEC_MUST_PLNTXT &&
-                (*flags & CIFSSEC_MUST_PLNTXT) == CIFSSEC_MUST_PLNTXT)
-               *flags = CIFSSEC_MUST_PLNTXT;
 
        *flags |= signflags;
 }
index 93b4781..12bde7b 100644 (file)
@@ -147,8 +147,6 @@ static int cifs_swn_send_register_message(struct cifs_swn_reg *swnreg)
                        goto nlmsg_fail;
                }
                break;
-       case LANMAN:
-       case NTLM:
        case NTLMv2:
        case RawNTLMSSP:
                ret = cifs_swn_auth_info_ntlm(swnreg->tcon, skb);
index ecf15d8..7680e0a 100644 (file)
@@ -250,87 +250,6 @@ int cifs_verify_signature(struct smb_rqst *rqst,
 
 }
 
-/* first calculate 24 bytes ntlm response and then 16 byte session key */
-int setup_ntlm_response(struct cifs_ses *ses, const struct nls_table *nls_cp)
-{
-       int rc = 0;
-       unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE;
-       char temp_key[CIFS_SESS_KEY_SIZE];
-
-       if (!ses)
-               return -EINVAL;
-
-       ses->auth_key.response = kmalloc(temp_len, GFP_KERNEL);
-       if (!ses->auth_key.response)
-               return -ENOMEM;
-
-       ses->auth_key.len = temp_len;
-
-       rc = SMBNTencrypt(ses->password, ses->server->cryptkey,
-                       ses->auth_key.response + CIFS_SESS_KEY_SIZE, nls_cp);
-       if (rc) {
-               cifs_dbg(FYI, "%s Can't generate NTLM response, error: %d\n",
-                        __func__, rc);
-               return rc;
-       }
-
-       rc = E_md4hash(ses->password, temp_key, nls_cp);
-       if (rc) {
-               cifs_dbg(FYI, "%s Can't generate NT hash, error: %d\n",
-                        __func__, rc);
-               return rc;
-       }
-
-       rc = mdfour(ses->auth_key.response, temp_key, CIFS_SESS_KEY_SIZE);
-       if (rc)
-               cifs_dbg(FYI, "%s Can't generate NTLM session key, error: %d\n",
-                        __func__, rc);
-
-       return rc;
-}
-
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
-int calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
-                       char *lnm_session_key)
-{
-       int i, len;
-       int rc;
-       char password_with_pad[CIFS_ENCPWD_SIZE] = {0};
-
-       if (password) {
-               for (len = 0; len < CIFS_ENCPWD_SIZE; len++)
-                       if (!password[len])
-                               break;
-
-               memcpy(password_with_pad, password, len);
-       }
-
-       if (!encrypt && global_secflags & CIFSSEC_MAY_PLNTXT) {
-               memcpy(lnm_session_key, password_with_pad,
-                       CIFS_ENCPWD_SIZE);
-               return 0;
-       }
-
-       /* calculate old style session key */
-       /* calling toupper is less broken than repeatedly
-       calling nls_toupper would be since that will never
-       work for UTF8, but neither handles multibyte code pages
-       but the only alternative would be converting to UCS-16 (Unicode)
-       (using a routine something like UniStrupr) then
-       uppercasing and then converting back from Unicode - which
-       would only worth doing it if we knew it were utf8. Basically
-       utf8 and other multibyte codepages each need their own strupper
-       function since a byte at a time will ont work. */
-
-       for (i = 0; i < CIFS_ENCPWD_SIZE; i++)
-               password_with_pad[i] = toupper(password_with_pad[i]);
-
-       rc = SMBencrypt(password_with_pad, cryptkey, lnm_session_key);
-
-       return rc;
-}
-#endif /* CIFS_WEAK_PW_HASH */
-
 /* Build a proper attribute value/target info pairs blob.
  * Fill in netbios and dns domain name and workstation name
  * and client time (total five av pairs and + one end of fields indicator.
index 6e4fc42..b1b175f 100644 (file)
@@ -437,15 +437,9 @@ cifs_show_security(struct seq_file *s, struct cifs_ses *ses)
        seq_puts(s, ",sec=");
 
        switch (ses->sectype) {
-       case LANMAN:
-               seq_puts(s, "lanman");
-               break;
        case NTLMv2:
                seq_puts(s, "ntlmv2");
                break;
-       case NTLM:
-               seq_puts(s, "ntlm");
-               break;
        case Kerberos:
                seq_puts(s, "krb5");
                break;
index c6a9542..c068f7d 100644 (file)
@@ -114,8 +114,6 @@ enum statusEnum {
 
 enum securityEnum {
        Unspecified = 0,        /* not specified */
-       LANMAN,                 /* Legacy LANMAN auth */
-       NTLM,                   /* Legacy NTLM012 auth with NTLM hash */
        NTLMv2,                 /* Legacy NTLM auth with NTLMv2 hash */
        RawNTLMSSP,             /* NTLMSSP without SPNEGO, NTLMv2 hash */
        Kerberos,               /* Kerberos via SPNEGO */
@@ -634,7 +632,6 @@ struct TCP_Server_Info {
        struct session_key session_key;
        unsigned long lstrp; /* when we got last response from this server */
        struct cifs_secmech secmech; /* crypto sec mech functs, descriptors */
-#define        CIFS_NEGFLAVOR_LANMAN   0       /* wct == 13, LANMAN */
 #define        CIFS_NEGFLAVOR_UNENCAP  1       /* wct == 17, but no ext_sec */
 #define        CIFS_NEGFLAVOR_EXTENDED 2       /* wct == 17, ext_sec bit set */
        char    negflavor;      /* NEGOTIATE response flavor */
@@ -1734,16 +1731,8 @@ static inline bool is_retryable_error(int error)
 
 /* Security Flags: indicate type of session setup needed */
 #define   CIFSSEC_MAY_SIGN     0x00001
-#define   CIFSSEC_MAY_NTLM     0x00002
 #define   CIFSSEC_MAY_NTLMV2   0x00004
 #define   CIFSSEC_MAY_KRB5     0x00008
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
-#define   CIFSSEC_MAY_LANMAN   0x00010
-#define   CIFSSEC_MAY_PLNTXT   0x00020
-#else
-#define   CIFSSEC_MAY_LANMAN    0
-#define   CIFSSEC_MAY_PLNTXT    0
-#endif /* weak passwords */
 #define   CIFSSEC_MAY_SEAL     0x00040 /* not supported yet */
 #define   CIFSSEC_MAY_NTLMSSP  0x00080 /* raw ntlmssp with ntlmv2 */
 
@@ -1751,32 +1740,19 @@ static inline bool is_retryable_error(int error)
 /* note that only one of the following can be set so the
 result of setting MUST flags more than once will be to
 require use of the stronger protocol */
-#define   CIFSSEC_MUST_NTLM    0x02002
 #define   CIFSSEC_MUST_NTLMV2  0x04004
 #define   CIFSSEC_MUST_KRB5    0x08008
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
-#define   CIFSSEC_MUST_LANMAN  0x10010
-#define   CIFSSEC_MUST_PLNTXT  0x20020
-#ifdef CONFIG_CIFS_UPCALL
-#define   CIFSSEC_MASK          0xBF0BF /* allows weak security but also krb5 */
-#else
-#define   CIFSSEC_MASK          0xB70B7 /* current flags supported if weak */
-#endif /* UPCALL */
-#else /* do not allow weak pw hash */
-#define   CIFSSEC_MUST_LANMAN  0
-#define   CIFSSEC_MUST_PLNTXT  0
 #ifdef CONFIG_CIFS_UPCALL
 #define   CIFSSEC_MASK          0x8F08F /* flags supported if no weak allowed */
 #else
 #define          CIFSSEC_MASK          0x87087 /* flags supported if no weak allowed */
 #endif /* UPCALL */
-#endif /* WEAK_PW_HASH */
 #define   CIFSSEC_MUST_SEAL    0x40040 /* not supported yet */
 #define   CIFSSEC_MUST_NTLMSSP 0x80080 /* raw ntlmssp with ntlmv2 */
 
 #define   CIFSSEC_DEF (CIFSSEC_MAY_SIGN | CIFSSEC_MAY_NTLMV2 | CIFSSEC_MAY_NTLMSSP)
-#define   CIFSSEC_MAX (CIFSSEC_MUST_SIGN | CIFSSEC_MUST_NTLMV2)
-#define   CIFSSEC_AUTH_MASK (CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2 | CIFSSEC_MAY_LANMAN | CIFSSEC_MAY_PLNTXT | CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP)
+#define   CIFSSEC_MAX (CIFSSEC_MUST_NTLMV2)
+#define   CIFSSEC_AUTH_MASK (CIFSSEC_MAY_NTLMV2 | CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP)
 /*
  *****************************************************************
  * All constants go here
@@ -1940,10 +1916,6 @@ static inline char *get_security_type_str(enum securityEnum sectype)
                return "Kerberos";
        case NTLMv2:
                return "NTLMv2";
-       case NTLM:
-               return "NTLM";
-       case LANMAN:
-               return "LANMAN";
        default:
                return "Unknown";
        }
index f6e2350..dc920e2 100644 (file)
 #include <asm/unaligned.h>
 #include "smbfsctl.h"
 
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
-#define LANMAN_PROT 0
-#define LANMAN2_PROT 1
-#define CIFS_PROT   2
-#else
 #define CIFS_PROT   0
-#endif
 #define POSIX_PROT  (CIFS_PROT+1)
 #define BAD_PROT 0xFFFF
 
@@ -505,30 +499,8 @@ typedef struct negotiate_req {
        unsigned char DialectsArray[1];
 } __attribute__((packed)) NEGOTIATE_REQ;
 
-/* Dialect index is 13 for LANMAN */
-
 #define MIN_TZ_ADJ (15 * 60) /* minimum grid for timezones in seconds */
 
-typedef struct lanman_neg_rsp {
-       struct smb_hdr hdr;     /* wct = 13 */
-       __le16 DialectIndex;
-       __le16 SecurityMode;
-       __le16 MaxBufSize;
-       __le16 MaxMpxCount;
-       __le16 MaxNumberVcs;
-       __le16 RawMode;
-       __le32 SessionKey;
-       struct {
-               __le16 Time;
-               __le16 Date;
-       } __attribute__((packed)) SrvTime;
-       __le16 ServerTimeZone;
-       __le16 EncryptionKeyLength;
-       __le16 Reserved;
-       __u16  ByteCount;
-       unsigned char EncryptionKey[1];
-} __attribute__((packed)) LANMAN_NEG_RSP;
-
 #define READ_RAW_ENABLE 1
 #define WRITE_RAW_ENABLE 2
 #define RAW_ENABLE (READ_RAW_ENABLE | WRITE_RAW_ENABLE)
index e0def0f..f9740c2 100644 (file)
@@ -498,19 +498,12 @@ extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *, __u32 *);
 extern int cifs_verify_signature(struct smb_rqst *rqst,
                                 struct TCP_Server_Info *server,
                                __u32 expected_sequence_number);
-extern int SMBNTencrypt(unsigned char *, unsigned char *, unsigned char *,
-                       const struct nls_table *);
-extern int setup_ntlm_response(struct cifs_ses *, const struct nls_table *);
 extern int setup_ntlmv2_rsp(struct cifs_ses *, const struct nls_table *);
 extern void cifs_crypto_secmech_release(struct TCP_Server_Info *server);
 extern int calc_seckey(struct cifs_ses *);
 extern int generate_smb30signingkey(struct cifs_ses *);
 extern int generate_smb311signingkey(struct cifs_ses *);
 
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
-extern int calc_lanman_hash(const char *password, const char *cryptkey,
-                               bool encrypt, char *lnm_session_key);
-#endif /* CIFS_WEAK_PW_HASH */
 extern int CIFSSMBCopy(unsigned int xid,
                        struct cifs_tcon *source_tcon,
                        const char *fromName,
@@ -547,11 +540,8 @@ extern int check_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
                              struct cifs_sb_info *cifs_sb,
                              struct cifs_fattr *fattr,
                              const unsigned char *path);
-extern int mdfour(unsigned char *, unsigned char *, int);
 extern int E_md4hash(const unsigned char *passwd, unsigned char *p16,
                        const struct nls_table *codepage);
-extern int SMBencrypt(unsigned char *passwd, const unsigned char *c8,
-                       unsigned char *p24);
 
 extern int
 cifs_setup_volume_info(struct smb3_fs_context *ctx, const char *mntopts, const char *devname);
index f207de8..a8e41c1 100644 (file)
@@ -42,10 +42,6 @@ static struct {
        int index;
        char *name;
 } protocols[] = {
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
-       {LANMAN_PROT, "\2LM1.2X002"},
-       {LANMAN2_PROT, "\2LANMAN2.1"},
-#endif /* weak password hashing for legacy clients */
        {CIFS_PROT, "\2NT LM 0.12"},
        {POSIX_PROT, "\2POSIX 2"},
        {BAD_PROT, "\2"}
@@ -55,10 +51,6 @@ static struct {
        int index;
        char *name;
 } protocols[] = {
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
-       {LANMAN_PROT, "\2LM1.2X002"},
-       {LANMAN2_PROT, "\2LANMAN2.1"},
-#endif /* weak password hashing for legacy clients */
        {CIFS_PROT, "\2NT LM 0.12"},
        {BAD_PROT, "\2"}
 };
@@ -66,17 +58,9 @@ static struct {
 
 /* define the number of elements in the cifs dialect array */
 #ifdef CONFIG_CIFS_POSIX
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
-#define CIFS_NUM_PROT 4
-#else
 #define CIFS_NUM_PROT 2
-#endif /* CIFS_WEAK_PW_HASH */
 #else /* not posix */
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
-#define CIFS_NUM_PROT 3
-#else
 #define CIFS_NUM_PROT 1
-#endif /* CONFIG_CIFS_WEAK_PW_HASH */
 #endif /* CIFS_POSIX */
 
 /*
@@ -475,89 +459,6 @@ cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required)
        return 0;
 }
 
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
-static int
-decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr)
-{
-       __s16 tmp;
-       struct lanman_neg_rsp *rsp = (struct lanman_neg_rsp *)pSMBr;
-
-       if (server->dialect != LANMAN_PROT && server->dialect != LANMAN2_PROT)
-               return -EOPNOTSUPP;
-
-       server->sec_mode = le16_to_cpu(rsp->SecurityMode);
-       server->maxReq = min_t(unsigned int,
-                              le16_to_cpu(rsp->MaxMpxCount),
-                              cifs_max_pending);
-       set_credits(server, server->maxReq);
-       server->maxBuf = le16_to_cpu(rsp->MaxBufSize);
-       /* set up max_read for readpages check */
-       server->max_read = server->maxBuf;
-       /* even though we do not use raw we might as well set this
-       accurately, in case we ever find a need for it */
-       if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) {
-               server->max_rw = 0xFF00;
-               server->capabilities = CAP_MPX_MODE | CAP_RAW_MODE;
-       } else {
-               server->max_rw = 0;/* do not need to use raw anyway */
-               server->capabilities = CAP_MPX_MODE;
-       }
-       tmp = (__s16)le16_to_cpu(rsp->ServerTimeZone);
-       if (tmp == -1) {
-               /* OS/2 often does not set timezone therefore
-                * we must use server time to calc time zone.
-                * Could deviate slightly from the right zone.
-                * Smallest defined timezone difference is 15 minutes
-                * (i.e. Nepal).  Rounding up/down is done to match
-                * this requirement.
-                */
-               int val, seconds, remain, result;
-               struct timespec64 ts;
-               time64_t utc = ktime_get_real_seconds();
-               ts = cnvrtDosUnixTm(rsp->SrvTime.Date,
-                                   rsp->SrvTime.Time, 0);
-               cifs_dbg(FYI, "SrvTime %lld sec since 1970 (utc: %lld) diff: %lld\n",
-                        ts.tv_sec, utc,
-                        utc - ts.tv_sec);
-               val = (int)(utc - ts.tv_sec);
-               seconds = abs(val);
-               result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ;
-               remain = seconds % MIN_TZ_ADJ;
-               if (remain >= (MIN_TZ_ADJ / 2))
-                       result += MIN_TZ_ADJ;
-               if (val < 0)
-                       result = -result;
-               server->timeAdj = result;
-       } else {
-               server->timeAdj = (int)tmp;
-               server->timeAdj *= 60; /* also in seconds */
-       }
-       cifs_dbg(FYI, "server->timeAdj: %d seconds\n", server->timeAdj);
-
-
-       /* BB get server time for time conversions and add
-       code to use it and timezone since this is not UTC */
-
-       if (rsp->EncryptionKeyLength ==
-                       cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
-               memcpy(server->cryptkey, rsp->EncryptionKey,
-                       CIFS_CRYPTO_KEY_SIZE);
-       } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
-               return -EIO; /* need cryptkey unless plain text */
-       }
-
-       cifs_dbg(FYI, "LANMAN negotiated\n");
-       return 0;
-}
-#else
-static inline int
-decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr)
-{
-       cifs_dbg(VFS, "mount failed, cifs module not built with CIFS_WEAK_PW_HASH support\n");
-       return -EOPNOTSUPP;
-}
-#endif
-
 static bool
 should_set_ext_sec_flag(enum securityEnum sectype)
 {
@@ -626,16 +527,12 @@ CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
        server->dialect = le16_to_cpu(pSMBr->DialectIndex);
        cifs_dbg(FYI, "Dialect: %d\n", server->dialect);
        /* Check wct = 1 error case */
-       if ((pSMBr->hdr.WordCount < 13) || (server->dialect == BAD_PROT)) {
+       if ((pSMBr->hdr.WordCount <= 13) || (server->dialect == BAD_PROT)) {
                /* core returns wct = 1, but we do not ask for core - otherwise
                small wct just comes when dialect index is -1 indicating we
                could not negotiate a common dialect */
                rc = -EOPNOTSUPP;
                goto neg_err_exit;
-       } else if (pSMBr->hdr.WordCount == 13) {
-               server->negflavor = CIFS_NEGFLAVOR_LANMAN;
-               rc = decode_lanman_negprot_rsp(server, pSMBr);
-               goto signing_check;
        } else if (pSMBr->hdr.WordCount != 17) {
                /* unknown wct */
                rc = -EOPNOTSUPP;
@@ -677,7 +574,6 @@ CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
                server->capabilities &= ~CAP_EXTENDED_SECURITY;
        }
 
-signing_check:
        if (!rc)
                rc = cifs_enable_signing(server, ses->sign);
 neg_err_exit:
index 3781eee..0db3448 100644 (file)
@@ -3684,38 +3684,6 @@ CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
                *bcc_ptr = 0; /* password is null byte */
                bcc_ptr++;              /* skip password */
                /* already aligned so no need to do it below */
-       } else {
-               pSMB->PasswordLength = cpu_to_le16(CIFS_AUTH_RESP_SIZE);
-               /* BB FIXME add code to fail this if NTLMv2 or Kerberos
-                  specified as required (when that support is added to
-                  the vfs in the future) as only NTLM or the much
-                  weaker LANMAN (which we do not send by default) is accepted
-                  by Samba (not sure whether other servers allow
-                  NTLMv2 password here) */
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
-               if ((global_secflags & CIFSSEC_MAY_LANMAN) &&
-                   (ses->sectype == LANMAN))
-                       calc_lanman_hash(tcon->password, ses->server->cryptkey,
-                                        ses->server->sec_mode &
-                                           SECMODE_PW_ENCRYPT ? true : false,
-                                        bcc_ptr);
-               else
-#endif /* CIFS_WEAK_PW_HASH */
-               rc = SMBNTencrypt(tcon->password, ses->server->cryptkey,
-                                       bcc_ptr, nls_codepage);
-               if (rc) {
-                       cifs_dbg(FYI, "%s Can't generate NTLM rsp. Error: %d\n",
-                                __func__, rc);
-                       cifs_buf_release(smb_buffer);
-                       return rc;
-               }
-
-               bcc_ptr += CIFS_AUTH_RESP_SIZE;
-               if (ses->capabilities & CAP_UNICODE) {
-                       /* must align unicode strings */
-                       *bcc_ptr = 0; /* null byte password */
-                       bcc_ptr++;
-               }
        }
 
        if (ses->server->sign)
index 727c883..3109def 100644 (file)
@@ -57,12 +57,9 @@ static const match_table_t cifs_secflavor_tokens = {
        { Opt_sec_krb5p, "krb5p" },
        { Opt_sec_ntlmsspi, "ntlmsspi" },
        { Opt_sec_ntlmssp, "ntlmssp" },
-       { Opt_ntlm, "ntlm" },
-       { Opt_sec_ntlmi, "ntlmi" },
        { Opt_sec_ntlmv2, "nontlm" },
        { Opt_sec_ntlmv2, "ntlmv2" },
        { Opt_sec_ntlmv2i, "ntlmv2i" },
-       { Opt_sec_lanman, "lanman" },
        { Opt_sec_none, "none" },
 
        { Opt_sec_err, NULL }
@@ -221,23 +218,12 @@ cifs_parse_security_flavors(struct fs_context *fc, char *value, struct smb3_fs_c
        case Opt_sec_ntlmssp:
                ctx->sectype = RawNTLMSSP;
                break;
-       case Opt_sec_ntlmi:
-               ctx->sign = true;
-               fallthrough;
-       case Opt_ntlm:
-               ctx->sectype = NTLM;
-               break;
        case Opt_sec_ntlmv2i:
                ctx->sign = true;
                fallthrough;
        case Opt_sec_ntlmv2:
                ctx->sectype = NTLMv2;
                break;
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
-       case Opt_sec_lanman:
-               ctx->sectype = LANMAN;
-               break;
-#endif
        case Opt_sec_none:
                ctx->nullauth = 1;
                break;
index b624397..a42ba71 100644 (file)
@@ -47,11 +47,8 @@ enum cifs_sec_param {
        Opt_sec_krb5p,
        Opt_sec_ntlmsspi,
        Opt_sec_ntlmssp,
-       Opt_ntlm,
-       Opt_sec_ntlmi,
        Opt_sec_ntlmv2,
        Opt_sec_ntlmv2i,
-       Opt_sec_lanman,
        Opt_sec_none,
 
        Opt_sec_err
index 606fd7d..118403f 100644 (file)
@@ -799,30 +799,16 @@ cifs_select_sectype(struct TCP_Server_Info *server, enum securityEnum requested)
                }
        case CIFS_NEGFLAVOR_UNENCAP:
                switch (requested) {
-               case NTLM:
                case NTLMv2:
                        return requested;
                case Unspecified:
                        if (global_secflags & CIFSSEC_MAY_NTLMV2)
                                return NTLMv2;
-                       if (global_secflags & CIFSSEC_MAY_NTLM)
-                               return NTLM;
                        break;
                default:
                        break;
                }
-               fallthrough;    /* to attempt LANMAN authentication next */
-       case CIFS_NEGFLAVOR_LANMAN:
-               switch (requested) {
-               case LANMAN:
-                       return requested;
-               case Unspecified:
-                       if (global_secflags & CIFSSEC_MAY_LANMAN)
-                               return LANMAN;
-                       fallthrough;
-               default:
-                       return Unspecified;
-               }
+               fallthrough;
        default:
                return Unspecified;
        }
@@ -947,230 +933,6 @@ sess_sendreceive(struct sess_data *sess_data)
        return rc;
 }
 
-/*
- * LANMAN and plaintext are less secure and off by default.
- * So we make this explicitly be turned on in kconfig (in the
- * build) and turned on at runtime (changed from the default)
- * in proc/fs/cifs or via mount parm.  Unfortunately this is
- * needed for old Win (e.g. Win95), some obscure NAS and OS/2
- */
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
-static void
-sess_auth_lanman(struct sess_data *sess_data)
-{
-       int rc = 0;
-       struct smb_hdr *smb_buf;
-       SESSION_SETUP_ANDX *pSMB;
-       char *bcc_ptr;
-       struct cifs_ses *ses = sess_data->ses;
-       char lnm_session_key[CIFS_AUTH_RESP_SIZE];
-       __u16 bytes_remaining;
-
-       /* lanman 2 style sessionsetup */
-       /* wct = 10 */
-       rc = sess_alloc_buffer(sess_data, 10);
-       if (rc)
-               goto out;
-
-       pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
-       bcc_ptr = sess_data->iov[2].iov_base;
-       (void)cifs_ssetup_hdr(ses, pSMB);
-
-       pSMB->req.hdr.Flags2 &= ~SMBFLG2_UNICODE;
-
-       if (ses->user_name != NULL) {
-               /* no capabilities flags in old lanman negotiation */
-               pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_AUTH_RESP_SIZE);
-
-               /* Calculate hash with password and copy into bcc_ptr.
-                * Encryption Key (stored as in cryptkey) gets used if the
-                * security mode bit in Negotiate Protocol response states
-                * to use challenge/response method (i.e. Password bit is 1).
-                */
-               rc = calc_lanman_hash(ses->password, ses->server->cryptkey,
-                                     ses->server->sec_mode & SECMODE_PW_ENCRYPT ?
-                                     true : false, lnm_session_key);
-               if (rc)
-                       goto out;
-
-               memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_AUTH_RESP_SIZE);
-               bcc_ptr += CIFS_AUTH_RESP_SIZE;
-       } else {
-               pSMB->old_req.PasswordLength = 0;
-       }
-
-       /*
-        * can not sign if LANMAN negotiated so no need
-        * to calculate signing key? but what if server
-        * changed to do higher than lanman dialect and
-        * we reconnected would we ever calc signing_key?
-        */
-
-       cifs_dbg(FYI, "Negotiating LANMAN setting up strings\n");
-       /* Unicode not allowed for LANMAN dialects */
-       ascii_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp);
-
-       sess_data->iov[2].iov_len = (long) bcc_ptr -
-                       (long) sess_data->iov[2].iov_base;
-
-       rc = sess_sendreceive(sess_data);
-       if (rc)
-               goto out;
-
-       pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
-       smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
-
-       /* lanman response has a word count of 3 */
-       if (smb_buf->WordCount != 3) {
-               rc = -EIO;
-               cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
-               goto out;
-       }
-
-       if (le16_to_cpu(pSMB->resp.Action) & GUEST_LOGIN)
-               cifs_dbg(FYI, "Guest login\n"); /* BB mark SesInfo struct? */
-
-       ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */
-       cifs_dbg(FYI, "UID = %llu\n", ses->Suid);
-
-       bytes_remaining = get_bcc(smb_buf);
-       bcc_ptr = pByteArea(smb_buf);
-
-       /* BB check if Unicode and decode strings */
-       if (bytes_remaining == 0) {
-               /* no string area to decode, do nothing */
-       } else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
-               /* unicode string area must be word-aligned */
-               if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) {
-                       ++bcc_ptr;
-                       --bytes_remaining;
-               }
-               decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses,
-                                     sess_data->nls_cp);
-       } else {
-               decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,
-                                   sess_data->nls_cp);
-       }
-
-       rc = sess_establish_session(sess_data);
-out:
-       sess_data->result = rc;
-       sess_data->func = NULL;
-       sess_free_buffer(sess_data);
-}
-
-#endif
-
-static void
-sess_auth_ntlm(struct sess_data *sess_data)
-{
-       int rc = 0;
-       struct smb_hdr *smb_buf;
-       SESSION_SETUP_ANDX *pSMB;
-       char *bcc_ptr;
-       struct cifs_ses *ses = sess_data->ses;
-       __u32 capabilities;
-       __u16 bytes_remaining;
-
-       /* old style NTLM sessionsetup */
-       /* wct = 13 */
-       rc = sess_alloc_buffer(sess_data, 13);
-       if (rc)
-               goto out;
-
-       pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
-       bcc_ptr = sess_data->iov[2].iov_base;
-       capabilities = cifs_ssetup_hdr(ses, pSMB);
-
-       pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
-       if (ses->user_name != NULL) {
-               pSMB->req_no_secext.CaseInsensitivePasswordLength =
-                               cpu_to_le16(CIFS_AUTH_RESP_SIZE);
-               pSMB->req_no_secext.CaseSensitivePasswordLength =
-                               cpu_to_le16(CIFS_AUTH_RESP_SIZE);
-
-               /* calculate ntlm response and session key */
-               rc = setup_ntlm_response(ses, sess_data->nls_cp);
-               if (rc) {
-                       cifs_dbg(VFS, "Error %d during NTLM authentication\n",
-                                        rc);
-                       goto out;
-               }
-
-               /* copy ntlm response */
-               memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
-                               CIFS_AUTH_RESP_SIZE);
-               bcc_ptr += CIFS_AUTH_RESP_SIZE;
-               memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
-                               CIFS_AUTH_RESP_SIZE);
-               bcc_ptr += CIFS_AUTH_RESP_SIZE;
-       } else {
-               pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
-               pSMB->req_no_secext.CaseSensitivePasswordLength = 0;
-       }
-
-       if (ses->capabilities & CAP_UNICODE) {
-               /* unicode strings must be word aligned */
-               if (sess_data->iov[0].iov_len % 2) {
-                       *bcc_ptr = 0;
-                       bcc_ptr++;
-               }
-               unicode_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp);
-       } else {
-               ascii_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp);
-       }
-
-
-       sess_data->iov[2].iov_len = (long) bcc_ptr -
-                       (long) sess_data->iov[2].iov_base;
-
-       rc = sess_sendreceive(sess_data);
-       if (rc)
-               goto out;
-
-       pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
-       smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
-
-       if (smb_buf->WordCount != 3) {
-               rc = -EIO;
-               cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
-               goto out;
-       }
-
-       if (le16_to_cpu(pSMB->resp.Action) & GUEST_LOGIN)
-               cifs_dbg(FYI, "Guest login\n"); /* BB mark SesInfo struct? */
-
-       ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */
-       cifs_dbg(FYI, "UID = %llu\n", ses->Suid);
-
-       bytes_remaining = get_bcc(smb_buf);
-       bcc_ptr = pByteArea(smb_buf);
-
-       /* BB check if Unicode and decode strings */
-       if (bytes_remaining == 0) {
-               /* no string area to decode, do nothing */
-       } else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
-               /* unicode string area must be word-aligned */
-               if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) {
-                       ++bcc_ptr;
-                       --bytes_remaining;
-               }
-               decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses,
-                                     sess_data->nls_cp);
-       } else {
-               decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,
-                                   sess_data->nls_cp);
-       }
-
-       rc = sess_establish_session(sess_data);
-out:
-       sess_data->result = rc;
-       sess_data->func = NULL;
-       sess_free_buffer(sess_data);
-       kfree(ses->auth_key.response);
-       ses->auth_key.response = NULL;
-}
-
 static void
 sess_auth_ntlmv2(struct sess_data *sess_data)
 {
@@ -1675,21 +1437,6 @@ static int select_sec(struct cifs_ses *ses, struct sess_data *sess_data)
        }
 
        switch (type) {
-       case LANMAN:
-               /* LANMAN and plaintext are less secure and off by default.
-                * So we make this explicitly be turned on in kconfig (in the
-                * build) and turned on at runtime (changed from the default)
-                * in proc/fs/cifs or via mount parm.  Unfortunately this is
-                * needed for old Win (e.g. Win95), some obscure NAS and OS/2 */
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
-               sess_data->func = sess_auth_lanman;
-               break;
-#else
-               return -EOPNOTSUPP;
-#endif
-       case NTLM:
-               sess_data->func = sess_auth_ntlm;
-               break;
        case NTLMv2:
                sess_data->func = sess_auth_ntlmv2;
                break;
index 39a9384..5da7eea 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/random.h>
-#include <crypto/des.h>
 #include "cifs_fs_sb.h"
 #include "cifs_unicode.h"
 #include "cifspdu.h"
 #define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8)
 #define SSVAL(buf,pos,val) SSVALX((buf),(pos),((__u16)(val)))
 
-static void
-str_to_key(unsigned char *str, unsigned char *key)
-{
-       int i;
-
-       key[0] = str[0] >> 1;
-       key[1] = ((str[0] & 0x01) << 6) | (str[1] >> 2);
-       key[2] = ((str[1] & 0x03) << 5) | (str[2] >> 3);
-       key[3] = ((str[2] & 0x07) << 4) | (str[3] >> 4);
-       key[4] = ((str[3] & 0x0F) << 3) | (str[4] >> 5);
-       key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6);
-       key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7);
-       key[7] = str[6] & 0x7F;
-       for (i = 0; i < 8; i++)
-               key[i] = (key[i] << 1);
-}
-
-static int
-smbhash(unsigned char *out, const unsigned char *in, unsigned char *key)
-{
-       unsigned char key2[8];
-       struct des_ctx ctx;
-
-       str_to_key(key, key2);
-
-       if (fips_enabled) {
-               cifs_dbg(VFS, "FIPS compliance enabled: DES not permitted\n");
-               return -ENOENT;
-       }
-
-       des_expand_key(&ctx, key2, DES_KEY_SIZE);
-       des_encrypt(&ctx, out, in);
-       memzero_explicit(&ctx, sizeof(ctx));
-
-       return 0;
-}
-
-static int
-E_P16(unsigned char *p14, unsigned char *p16)
-{
-       int rc;
-       unsigned char sp8[8] =
-           { 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
-
-       rc = smbhash(p16, sp8, p14);
-       if (rc)
-               return rc;
-       rc = smbhash(p16 + 8, sp8, p14 + 7);
-       return rc;
-}
-
-static int
-E_P24(unsigned char *p21, const unsigned char *c8, unsigned char *p24)
-{
-       int rc;
-
-       rc = smbhash(p24, c8, p21);
-       if (rc)
-               return rc;
-       rc = smbhash(p24 + 8, c8, p21 + 7);
-       if (rc)
-               return rc;
-       rc = smbhash(p24 + 16, c8, p21 + 14);
-       return rc;
-}
-
 /* produce a md4 message digest from data of length n bytes */
-int
+static int
 mdfour(unsigned char *md4_hash, unsigned char *link_str, int link_len)
 {
        int rc;
@@ -135,32 +68,6 @@ mdfour_err:
        return rc;
 }
 
-/*
-   This implements the X/Open SMB password encryption
-   It takes a password, a 8 byte "crypt key" and puts 24 bytes of
-   encrypted password into p24 */
-/* Note that password must be uppercased and null terminated */
-int
-SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24)
-{
-       int rc;
-       unsigned char p14[14], p16[16], p21[21];
-
-       memset(p14, '\0', 14);
-       memset(p16, '\0', 16);
-       memset(p21, '\0', 21);
-
-       memcpy(p14, passwd, 14);
-       rc = E_P16(p14, p16);
-       if (rc)
-               return rc;
-
-       memcpy(p21, p16, 16);
-       rc = E_P24(p21, c8, p24);
-
-       return rc;
-}
-
 /*
  * Creates the MD4 Hash of the users password in NT UNICODE.
  */
@@ -186,25 +93,3 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16,
 
        return rc;
 }
-
-/* Does the NT MD4 hash then des encryption. */
-int
-SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24,
-               const struct nls_table *codepage)
-{
-       int rc;
-       unsigned char p16[16], p21[21];
-
-       memset(p16, '\0', 16);
-       memset(p21, '\0', 21);
-
-       rc = E_md4hash(passwd, p16, codepage);
-       if (rc) {
-               cifs_dbg(FYI, "%s Can't generate NT hash, error: %d\n",
-                        __func__, rc);
-               return rc;
-       }
-       memcpy(p21, p16, 16);
-       rc = E_P24(p21, c8, p24);
-       return rc;
-}