mirror of
https://github.com/ceph/ceph
synced 2025-03-31 16:25:56 +00:00
librgw: consolidate S3 bucket name validation
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>
This commit is contained in:
parent
cfb8c81eee
commit
2f706ef084
@ -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
|
||||
*/
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user