]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mount.ceph: add name and secret to ceph_mount_info
authorJeff Layton <jlayton@redhat.com>
Tue, 20 Aug 2019 18:25:55 +0000 (14:25 -0400)
committerJeff Layton <jlayton@redhat.com>
Fri, 13 Sep 2019 12:14:48 +0000 (08:14 -0400)
...and move the length defines into mount.ceph.h. Note that we use a
fixed-length buffer for the secret, as it cuts down a copy when we
read_secret_from_file.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
src/mount/mount.ceph.c
src/mount/mount.ceph.h

index 8ca17c38baf73cc384c16f0eea34a4c1bdc10b14..83eeb30723add7b5bf9ab02aa0e9c38b1805e8d3 100644 (file)
@@ -13,9 +13,6 @@
 # define MS_RELATIME (1<<21)
 #endif
 
-#define MAX_SECRET_LEN 1000
-#define MAX_SECRET_OPTION_LEN (MAX_SECRET_LEN + 7)
-
 bool verboseflag = false;
 bool skip_mtab_flag = false;
 static const char * const EMPTY_STRING = "";
@@ -27,8 +24,10 @@ static const char * const EMPTY_STRING = "";
 
 struct ceph_mount_info {
        unsigned long   cmi_flags;
+       char            *cmi_name;
        char            *cmi_opts;
        int             cmi_opts_len;
+       char            cmi_secret[SECRET_BUFSIZE];
 };
 
 static void block_signals (int how)
@@ -108,9 +107,6 @@ static int parse_options(const char *data, struct ceph_mount_info *cmi)
        char *name = NULL;
        int name_len = 0;
        int name_pos = 0;
-       char secret[MAX_SECRET_LEN];
-       char *saw_name = NULL;
-       char *saw_secret = NULL;
 
        mount_ceph_debug("parsing options: %s\n", data);
 
@@ -172,53 +168,36 @@ static int parse_options(const char *data, struct ceph_mount_info *cmi)
                        /* ignore */
                } else if (strncmp(data, "nofail", 6) == 0) {
                        /* ignore */
-
                } else if (strncmp(data, "secretfile", 10) == 0) {
+                       int ret;
+
                        if (!value || !*value) {
                                fprintf(stderr, "keyword secretfile found, but no secret file specified\n");
-                               free(saw_name);
                                return -EINVAL;
                        }
-
-                       if (read_secret_from_file(value, secret, sizeof(secret)) < 0) {
-                               fprintf(stderr, "error reading secret file\n");
-                               return -EIO;
+                       ret = read_secret_from_file(value, cmi->cmi_secret, sizeof(cmi->cmi_secret));
+                       if (ret < 0) {
+                               fprintf(stderr, "error reading secret file: %d\n", ret);
+                               return ret;
                        }
-
-                       /* see comment for "secret" */
-                       saw_secret = secret;
-                       skip = true;
                } else if (strncmp(data, "secret", 6) == 0) {
+                       size_t len;
+
                        if (!value || !*value) {
                                fprintf(stderr, "mount option secret requires a value.\n");
-                               free(saw_name);
                                return -EINVAL;
                        }
 
-                       /* secret is only added to kernel options as
-                          backwards compatibility, if add_key doesn't
-                          recognize our keytype; hence, it is skipped
-                          here and appended to options on add_key
-                          failure */
-                       size_t len = sizeof(secret);
-                       strncpy(secret, value, len-1);
-                       secret[len-1] = '\0';
-                       saw_secret = secret;
-                       skip = true;
+                       len = strnlen(value, sizeof(cmi->cmi_secret)) + 1;
+                       if (len <= sizeof(cmi->cmi_secret))
+                               memcpy(cmi->cmi_secret, value, len);
                } else if (strncmp(data, "name", 4) == 0) {
                        if (!value || !*value) {
                                fprintf(stderr, "mount option name requires a value.\n");
                                return -EINVAL;
                        }
-
-                       /* take a copy of the name, to be used for
-                          naming the keys that we add to kernel; */
-                       free(saw_name);
-                       saw_name = strdup(value);
-                       if (!saw_name) {
-                               fprintf(stderr, "out of memory.\n");
-                               return -ENOMEM;
-                       }
+                       /* keep pointer to value */
+                       name = value;
                        skip = false;
                } else {
                        skip = false;
@@ -243,25 +222,10 @@ static int parse_options(const char *data, struct ceph_mount_info *cmi)
                data = next_keyword;
        } while (data);
 
-       name_pos = safe_cat(&name, &name_len, name_pos, "client.");
-       name_pos = safe_cat(&name, &name_len, name_pos,
-                           saw_name ? saw_name : CEPH_AUTH_NAME_DEFAULT);
-       if (saw_secret || is_kernel_secret(name)) {
-               int ret;
-               char secret_option[MAX_SECRET_OPTION_LEN];
-               ret = get_secret_option(saw_secret, name, secret_option, sizeof(secret_option));
-               if (ret < 0) {
-                       free(saw_name);
-                       return ret;
-               } else {
-                       if (pos) {
-                               pos = safe_cat(&cmi->cmi_opts, &cmi->cmi_opts_len, pos, ",");
-                       }
-                       pos = safe_cat(&cmi->cmi_opts, &cmi->cmi_opts_len, pos, secret_option);
-               }
-       }
+       name_pos = safe_cat(&cmi->cmi_name, &name_len, name_pos, "client.");
+       name_pos = safe_cat(&cmi->cmi_name, &name_len, name_pos,
+                           name ? name : CEPH_AUTH_NAME_DEFAULT);
 
-       free(saw_name);
        if (!cmi->cmi_opts) {
                cmi->cmi_opts = strdup(EMPTY_STRING);
                if (!cmi->cmi_opts)
@@ -346,6 +310,28 @@ static void usage(const char *prog_name)
 static void ceph_mount_info_free(struct ceph_mount_info *cmi)
 {
        free(cmi->cmi_opts);
+       free(cmi->cmi_name);
+}
+
+static int finalize_options(struct ceph_mount_info *cmi)
+{
+       int pos;
+
+       if (cmi->cmi_secret[0] || is_kernel_secret(cmi->cmi_name)) {
+               int ret;
+               char secret_option[SECRET_OPTION_BUFSIZE];
+
+               ret = get_secret_option(cmi->cmi_secret, cmi->cmi_name,
+                                       secret_option, sizeof(secret_option));
+               if (ret < 0)
+                       return ret;
+
+               pos = strlen(cmi->cmi_opts);
+               if (pos)
+                       pos = safe_cat(&cmi->cmi_opts, &cmi->cmi_opts_len, pos, ",");
+               pos = safe_cat(&cmi->cmi_opts, &cmi->cmi_opts_len, pos, secret_option);
+       }
+       return 0;
 }
 
 int main(int argc, char *argv[])
@@ -369,12 +355,19 @@ int main(int argc, char *argv[])
                goto out;
        }
 
+       retval = parse_options(opts, &cmi);
+       if (retval) {
+               fprintf(stderr, "failed to parse ceph_options: %d\n", retval);
+               retval = EX_USAGE;
+               goto out;
+       }
+
        /* Ensure the ceph key_type is available */
        modprobe();
 
-       retval = parse_options(opts, &cmi);
+       retval = finalize_options(&cmi);
        if (retval) {
-               fprintf(stderr, "failed to parse ceph_options: %d\n", retval);
+               fprintf(stderr, "couldn't finalize options: %d\n", retval);
                retval = EX_USAGE;
                goto out;
        }
index d31c375b679b454150e85127bf14ae0c921d1c2f..2c07cb7443530aca708f52e302923130e313e8bc 100644 (file)
@@ -5,6 +5,25 @@
 extern "C" {
 #endif
 
+/*
+ * See class CryptoKey
+ *
+ * 2 (for the type of secret) +
+ * 8 (for the timestamp) +
+ * 2 (for the length of secret) +
+ * 16 (for an AES-128 key)
+ */
+#define MAX_RAW_SECRET_LEN (2 + 8 + 2 + 16)
+
+/* Max length of base64 encoded secret. 4/3 original size (rounded up) */
+#define MAX_SECRET_LEN ((MAX_RAW_SECRET_LEN + (3 - 1)) * 4 / 3)
+
+/* Max Including null terminator */
+#define SECRET_BUFSIZE (MAX_SECRET_LEN + 1)
+
+/* Buffer size for secret= option */
+#define SECRET_OPTION_BUFSIZE (sizeof("secret=") + MAX_SECRET_LEN + 1)
+
 void mount_ceph_debug(const char *fmt, ...);
 
 #ifdef __cplusplus