]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librgw: consolidate S3 bucket name validation
authorMatt Benjamin <mbenjamin@redhat.com>
Tue, 2 Feb 2016 14:38:51 +0000 (09:38 -0500)
committerMatt Benjamin <mbenjamin@redhat.com>
Fri, 12 Feb 2016 18:07:08 +0000 (13:07 -0500)
There is more cleanup potential here, but it is intrusive, as the
validators for bucket and object names have been factored through
the handler inheritance hierarchy.

This change just deletes the S3 validate_bucket_name for now, as
that method was large.  The corresponding object name validator was
not defined in RGWHandler_REST_S3, so I've left it as is, for now.

Signed-off-by: Matt Benjamin <mbenjamin@redhat.com>
src/rgw/rgw_file.cc
src/rgw/rgw_file.h
src/rgw/rgw_rest_s3.cc
src/rgw/rgw_rest_s3.h

index 9e1ce6808c9ca90f3f4a1d0d578b3b27093bafa6..60364be2b6906614ecb561733efdf7f0ed6c8983 100644 (file)
@@ -704,46 +704,6 @@ 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 -- create an empty regular file
 */
index fe70fa717909d0d5256f922b333e514633bfc4dc..1cafcfb04dd779bf35dbf97ab0ef9dff3a69c1d0 100644 (file)
@@ -1219,18 +1219,6 @@ public:
 
 }; /* RGWDeleteBucketRequest */
 
-static inline bool valid_s3_object_name(const string& name) {
-  if (name.size() > 1024) {
-    // Name too long
-    return false;
-  }
-  if (check_utf8(name.c_str(), name.size())) {
-    // Object names must be valid UTF-8.
-    return false;
-  }
-  return true;
-}
-
 /*
   put object
 */
index 7c798f36019b8ea1311053f436f78598b5bfa199..9cbbd860aace23c12b2af4b3d86e5b97a189f9d7 100644 (file)
@@ -2508,7 +2508,7 @@ int RGWHandler_REST_S3::postauth_init()
   ret = validate_tenant_name(s->bucket_tenant);
   if (ret)
     return ret;
-  ret = validate_bucket_name(s->bucket_name, relaxed_names);
+  ret = valid_s3_bucket_name(s->bucket_name, relaxed_names);
   if (ret)
     return ret;
   ret = validate_object_name(s->object.name);
@@ -2521,55 +2521,30 @@ int RGWHandler_REST_S3::postauth_init()
     ret = validate_tenant_name(s->src_tenant_name);
     if (ret)
       return ret;
-    ret = validate_bucket_name(s->src_bucket_name, relaxed_names);
+    ret = valid_s3_bucket_name(s->src_bucket_name, relaxed_names);
     if (ret)
       return ret;
   }
   return 0;
 }
 
-int RGWHandler_REST_S3::validate_bucket_name(const string& bucket,
-                                           bool relaxed_names)
-{
-  int ret = RGWHandler_REST::validate_bucket_name(bucket);
-  if (ret < 0)
-    return ret;
-
-  if (bucket.size() == 0)
-    return 0;
-
-  // bucket names must start with a number, letter, or underscore
-  if (!(isalpha(bucket[0]) || isdigit(bucket[0]))) {
-    if (!relaxed_names)
-      return -ERR_INVALID_BUCKET_NAME;
-    else if (!(bucket[0] == '_' || bucket[0] == '.' || bucket[0] == '-'))
-      return -ERR_INVALID_BUCKET_NAME;
-  }
-
-  for (const char *s = bucket.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(bucket.c_str()))
-    return -ERR_INVALID_BUCKET_NAME;
-
-  return 0;
-}
-
 int RGWHandler_REST_S3::init(RGWRados *store, struct req_state *s,
-                                RGWClientIO *cio)
+                           RGWClientIO *cio)
 {
   int ret;
 
   s->dialect = "s3";
+  
+  ret = validate_tenant_name(s->bucket_tenant);
+  if (ret)
+    return ret;
+  bool relaxed_names = s->cct->_conf->rgw_relaxed_s3_bucket_names;
+  ret = valid_s3_bucket_name(s->bucket_name, relaxed_names);
+  if (ret)
+    return ret;
+  ret = validate_object_name(s->object.name);
+  if (ret)
+    return ret;
 
   const char *cacl = s->info.env->get("HTTP_X_AMZ_ACL");
   if (cacl)
index e7b23d08b17e904232ab3594e66b88ccfca6aa66..129934a9fdb253377fc64b5eff9b6b638566f9de 100644 (file)
@@ -416,11 +416,9 @@ public:
   RGWHandler_REST_S3() : RGWHandler_REST() {}
   virtual ~RGWHandler_REST_S3() {}
 
-  int validate_bucket_name(const string& bucket, bool relaxed_names);
-  int get_errordoc(const string& errordoc_key, string* error_content);
+  int validate_bucket_name(const string& bucket, bool relaxed_names) = delete;
+  int get_errordoc(const string& errordoc_key, string* error_content);  
 
-  using RGWHandler_REST::validate_bucket_name;
-  
   virtual int init(RGWRados *store, struct req_state *s, RGWClientIO *cio);
   virtual int authorize() {
     return RGW_Auth_S3::authorize(store, s);
@@ -530,4 +528,53 @@ static inline bool looks_like_ip_address(const char *bucket)
   return (num_periods == 3);
 }
 
+static inline bool valid_s3_object_name(const string& name) {
+  if (name.size() > 1024) {
+    return false;
+  }
+  if (check_utf8(name.c_str(), name.size())) {
+    return false;
+  }
+  return true;
+}
+
+static inline 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;
+}
+
 #endif /* CEPH_RGW_REST_S3_H */