]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
libcli/smb: add helpers to parse client/server smb3 encryption algorithms into struct...
authorStefan Metzmacher <metze@samba.org>
Tue, 13 Jul 2021 16:00:59 +0000 (18:00 +0200)
committerStefan Metzmacher <metze@samba.org>
Thu, 15 Jul 2021 00:06:31 +0000 (00:06 +0000)
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
libcli/smb/smb2_negotiate_context.h
libcli/smb/util.c

index a671d8a0ebfc5f5f6930500cf99cf6d49020ef63..a7e94b50681b1933f209220e3d3fa20f19147ac6 100644 (file)
@@ -66,4 +66,9 @@ struct smb311_capabilities {
        struct smb3_encryption_capabilities encryption;
 };
 
+const char *smb3_encryption_algorithm_name(uint16_t algo);
+
+struct smb311_capabilities smb311_capabilities_parse(const char *role,
+                               const char * const *encryption_algos);
+
 #endif /* _LIBCLI_SMB_SMB2_NEGOTIATE_BLOB_H_ */
index 6d35c244a32c49cc89ffa6f869342146f5a69b54..c2fa2f0d2447254df644ecbef83c988b0bdfa88a 100644 (file)
@@ -23,6 +23,8 @@
 #include "libcli/smb/smb_common.h"
 #include "system/filesys.h"
 #include "lib/param/loadparm.h"
+#include "lib/param/param.h"
+#include "libcli/smb/smb2_negotiate_context.h"
 
 const char *smb_protocol_types_string(enum protocol_types protocol)
 {
@@ -462,3 +464,101 @@ enum smb_encryption_setting smb_encryption_setting_translate(const char *str)
 
        return encryption_state;
 }
+
+static const struct enum_list enum_smb3_encryption_algorithms[] = {
+       {SMB2_ENCRYPTION_AES128_GCM, "aes-128-gcm"},
+       {SMB2_ENCRYPTION_AES128_CCM, "aes-128-ccm"},
+       {-1, NULL}
+};
+
+const char *smb3_encryption_algorithm_name(uint16_t algo)
+{
+       size_t i;
+
+       for (i = 0; i < ARRAY_SIZE(enum_smb3_encryption_algorithms); i++) {
+               if (enum_smb3_encryption_algorithms[i].value != algo) {
+                       continue;
+               }
+
+               return enum_smb3_encryption_algorithms[i].name;
+       }
+
+       return NULL;
+}
+
+static int32_t parse_enum_val(const struct enum_list *e,
+                             const char *param_name,
+                             const char *param_value)
+{
+       struct parm_struct parm = {
+               .label = param_name,
+               .type = P_LIST,
+               .p_class = P_GLOBAL,
+               .enum_list = e,
+       };
+       int32_t ret = INT32_MIN;
+       bool ok;
+
+       ok = lp_set_enum_parm(&parm, param_value, &ret);
+       if (!ok) {
+               return INT32_MIN;
+       }
+
+       return ret;
+}
+
+struct smb311_capabilities smb311_capabilities_parse(const char *role,
+                               const char * const *encryption_algos)
+{
+       struct smb311_capabilities c = {
+               .encryption = {
+                       .num_algos = 0,
+               },
+       };
+       char enc_param[64] = { 0, };
+       size_t ai;
+
+       snprintf(enc_param, sizeof(enc_param),
+                "%s smb3 encryption algorithms", role);
+
+       for (ai = 0; encryption_algos != NULL && encryption_algos[ai] != NULL; ai++) {
+               const char *algoname = encryption_algos[ai];
+               int32_t v32;
+               uint16_t algo;
+               size_t di;
+               bool ignore = false;
+
+               if (c.encryption.num_algos >= SMB3_ENCRYTION_CAPABILITIES_MAX_ALGOS) {
+                       DBG_ERR("WARNING: Ignoring trailing value '%s' for parameter '%s'\n",
+                                 algoname, enc_param);
+                       continue;
+               }
+
+               v32 = parse_enum_val(enum_smb3_encryption_algorithms,
+                                    enc_param, algoname);
+               if (v32 == INT32_MAX) {
+                       continue;
+               }
+               algo = v32;
+
+               for (di = 0; di < c.encryption.num_algos; di++) {
+                       if (algo != c.encryption.algos[di]) {
+                               continue;
+                       }
+
+                       ignore = true;
+                       break;
+               }
+
+               if (ignore) {
+                       DBG_ERR("WARNING: Ignoring duplicate value '%s' for parameter '%s'\n",
+                                 algoname, enc_param);
+                       continue;
+               }
+
+               c.encryption.algos[c.encryption.num_algos] = algo;
+               c.encryption.num_algos += 1;
+       }
+
+       return c;
+}