mirror of
https://github.com/ceph/ceph
synced 2024-12-19 01:46:00 +00:00
librgw: enforce S3 bucket name restrictions
Signed-off-by: Matt Benjamin <mbenjamin@redhat.com>
This commit is contained in:
parent
54149b06c1
commit
66b6b1fd3e
@ -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();
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user