]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librgw: enforce S3 bucket name restrictions
authorMatt Benjamin <mbenjamin@redhat.com>
Sat, 9 Jan 2016 22:45:45 +0000 (17:45 -0500)
committerMatt Benjamin <mbenjamin@redhat.com>
Fri, 12 Feb 2016 17:07:42 +0000 (12:07 -0500)
Signed-off-by: Matt Benjamin <mbenjamin@redhat.com>
src/rgw/rgw_file.cc
src/rgw/rgw_rest_s3.cc
src/rgw/rgw_rest_s3.h
src/test/librgw_file_nfsns.cc

index e0d7430bc946863bfb096cc2f2b74552eabdbff1..405ee11a96e13767791cd4018276118cc586d9f7 100644 (file)
@@ -588,6 +588,46 @@ int rgw_statfs(struct rgw_fs *rgw_fs,
   return 0;
 }
 
+/* XXX can't call these virtual methods from non-REST handler */
+static int valid_s3_bucket_name(const string& name, bool relaxed=false)
+{
+  // This function enforces Amazon's spec for bucket names.
+  // (The requirements, not the recommendations.)
+  int len = name.size();
+  if (len < 3) {
+    // Name too short
+    return -ERR_INVALID_BUCKET_NAME;
+  } else if (len > 255) {
+    // Name too long
+    return -ERR_INVALID_BUCKET_NAME;
+  }
+
+  // bucket names must start with a number, letter, or underscore
+  if (!(isalpha(name[0]) || isdigit(name[0]))) {
+    if (!relaxed)
+      return -ERR_INVALID_BUCKET_NAME;
+    else if (!(name[0] == '_' || name[0] == '.' || name[0] == '-'))
+      return -ERR_INVALID_BUCKET_NAME;
+  }
+
+  for (const char *s = name.c_str(); *s; ++s) {
+    char c = *s;
+    if (isdigit(c) || (c == '.'))
+      continue;
+    if (isalpha(c))
+      continue;
+    if ((c == '-') || (c == '_'))
+      continue;
+    // Invalid character
+    return -ERR_INVALID_BUCKET_NAME;
+  }
+
+  if (looks_like_ip_address(name.c_str()))
+    return -ERR_INVALID_BUCKET_NAME;
+
+  return 0;
+}
+
 /*
   generic create -- creates a regular file
 */
@@ -658,8 +698,12 @@ int rgw_mkdir(struct rgw_fs *rgw_fs,
 
   if (parent->is_root()) {
     /* bucket */
-    string uri = "/"; /* XXX get rid of URI some day soon */
-    uri += name;
+    string bname{name};
+    /* enforce S3 name restrictions */
+    rc = valid_s3_bucket_name(bname, false /* relaxed */);
+    if (rc != 0)
+      return -EINVAL;
+    string uri = "/" + bname; /* XXX get rid of URI some day soon */
     RGWCreateBucketRequest req(cct, fs->get_user(), uri);
     rc = rgwlib.get_fe()->execute_req(&req);
     rc2 = req.get_ret();
index be535c73c34b33988ddc0f61ca6457825f292ba8..7c798f36019b8ea1311053f436f78598b5bfa199 100644 (file)
@@ -2528,31 +2528,8 @@ int RGWHandler_REST_S3::postauth_init()
   return 0;
 }
 
-static bool looks_like_ip_address(const char *bucket)
-{
-  int num_periods = 0;
-  bool expect_period = false;
-  for (const char *b = bucket; *b; ++b) {
-    if (*b == '.') {
-      if (!expect_period)
-       return false;
-      ++num_periods;
-      if (num_periods > 3)
-       return false;
-      expect_period = false;
-    }
-    else if (isdigit(*b)) {
-      expect_period = true;
-    }
-    else {
-      return false;
-    }
-  }
-  return (num_periods == 3);
-}
-
 int RGWHandler_REST_S3::validate_bucket_name(const string& bucket,
-                                                bool relaxed_names)
+                                           bool relaxed_names)
 {
   int ret = RGWHandler_REST::validate_bucket_name(bucket);
   if (ret < 0)
index cde8581ef88b03d87b95ca83f33dbaff6714760b..e7b23d08b17e904232ab3594e66b88ccfca6aa66 100644 (file)
@@ -2,6 +2,7 @@
 // vim: ts=8 sw=2 smarttab
 
 #ifndef CEPH_RGW_REST_S3_H
+
 #define CEPH_RGW_REST_S3_H
 #define TIME_BUF_SIZE 128
 
@@ -506,4 +507,27 @@ public:
 
 class RGWHandler_REST_Obj_S3Website;
 
-#endif
+static inline bool looks_like_ip_address(const char *bucket)
+{
+  int num_periods = 0;
+  bool expect_period = false;
+  for (const char *b = bucket; *b; ++b) {
+    if (*b == '.') {
+      if (!expect_period)
+       return false;
+      ++num_periods;
+      if (num_periods > 3)
+       return false;
+      expect_period = false;
+    }
+    else if (isdigit(*b)) {
+      expect_period = true;
+    }
+    else {
+      return false;
+    }
+  }
+  return (num_periods == 3);
+}
+
+#endif /* CEPH_RGW_REST_S3_H */
index 9f72014b65c27d626355b9f45b15aa7d45dc2d62..470240c73982dd199aec4706f04c7626c45f1277 100644 (file)
@@ -44,7 +44,7 @@ namespace {
   CephContext* cct = nullptr;
 
   string bucket_name("nfsroot");
-  string dirs1_bucket_name("b1");
+  string dirs1_bucket_name("bdirs1");
 
   class obj_rec
   {