Print this page
12513 SMB 3.1.1 support for server
@@ -19,10 +19,11 @@
* CDDL HEADER END
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2018 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2020 RackTop Systems, Inc.
*/
/*
* CIFS configuration management library
*/
@@ -148,10 +149,11 @@
{SMB_CI_MAX_PROTOCOL, "max_protocol", SCF_TYPE_ASTRING, 0},
{SMB_CI_ENCRYPT, "encrypt", SCF_TYPE_ASTRING, 0},
{SMB_CI_MIN_PROTOCOL, "min_protocol", SCF_TYPE_ASTRING, 0},
{SMB_CI_BYPASS_TRAVERSE_CHECKING,
"bypass_traverse_checking", SCF_TYPE_BOOLEAN, 0},
+ {SMB_CI_ENCRYPT_CIPHER, "encrypt_cipher", SCF_TYPE_ASTRING, 0},
/* SMB_CI_MAX */
};
/*
@@ -163,18 +165,29 @@
* except for how we represent "1" (for SMB1) which is an
* arbitrary value below SMB2_VERS_BASE.
*/
static struct str_val
smb_versions[] = {
+ { "3.11", SMB_VERS_3_11 },
{ "3.02", SMB_VERS_3_02 },
{ "3.0", SMB_VERS_3_0 },
{ "2.1", SMB_VERS_2_1 },
{ "2.002", SMB_VERS_2_002 },
{ "1", SMB_VERS_1 },
{ NULL, 0 }
};
+/*
+ * Supported encryption ciphers.
+ */
+static struct str_val
+smb31_encrypt_ciphers[] = {
+ { "aes128-ccm", SMB3_CIPHER_AES128_CCM }, /* SMB 3.x */
+ { "aes128-gcm", SMB3_CIPHER_AES128_GCM }, /* SMB 3.1.1 */
+ { NULL, 0 }
+};
+
static smb_cfg_param_t *smb_config_getent(smb_cfg_id_t);
static boolean_t smb_is_base64(unsigned char c);
static char *smb_base64_encode(char *str_to_encode);
static char *smb_base64_decode(char *encoded_str);
@@ -1222,11 +1235,11 @@
* max_protocol. The expectation is that when those values are empty, we don't
* constrain the range of supported protocol versions (and allow use of the
* whole range that we implement). For that reason, this should usually be the
* highest protocol version we implement.
*/
-uint32_t max_protocol_default = SMB_VERS_3_02;
+uint32_t max_protocol_default = SMB_VERS_3_11;
uint32_t
smb_config_get_max_protocol(void)
{
uint32_t max;
@@ -1261,10 +1274,38 @@
return (-1);
}
/*
+ * Only SMB 3.x supports encryption.
+ * SMB 3.0.2 uses AES128-CCM only.
+ * SMB 3.1.1 - AES128-CCM or AES128-GCM.
+ */
+uint16_t
+smb31_config_get_encrypt_cipher(void)
+{
+ uint32_t max_proto = smb_config_get_max_protocol();
+ uint16_t cipher = SMB3_CIPHER_AES128_GCM; /* by default AES128-GCM */
+ char str[12];
+ int i;
+
+ if (max_proto < SMB_VERS_3_11)
+ return (SMB3_CIPHER_NONE);
+
+ /* SMB 3.1.1 */
+ if (smb_config_getstr(SMB_CI_ENCRYPT_CIPHER, str, sizeof (str))
+ == SMBD_SMF_OK) {
+ for (i = 0; smb31_encrypt_ciphers[i].str != NULL; i++) {
+ if (strcmp(str, smb31_encrypt_ciphers[i].str) == 0)
+ cipher = smb31_encrypt_ciphers[i].val;
+ }
+ }
+
+ return (cipher);
+}
+
+/*
* If smb2_enable is present and max_protocol is empty,
* set max_protocol. Delete smb2_enable.
*/
static void
upgrade_smb2_enable()