summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYehuda Sadeh <yehuda@inktank.com>2012-10-10 12:39:34 -0700
committerYehuda Sadeh <yehuda@inktank.com>2012-10-23 10:43:09 -0700
commit52b78d511b78dc8aa27c161e6e57c992c0e954ac (patch)
tree8384076522898573c86c3d110a186194a4e97f14
parent86b06f12a97e48b6db9bfb8dbd0e121a34a2847e (diff)
downloadceph-52b78d511b78dc8aa27c161e6e57c992c0e954ac.tar.gz
rgw: verify that request variables are in policy
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
-rw-r--r--src/rgw/rgw_policy_s3.cc35
-rw-r--r--src/rgw/rgw_policy_s3.h8
-rw-r--r--src/rgw/rgw_rest_s3.cc4
3 files changed, 40 insertions, 7 deletions
diff --git a/src/rgw/rgw_policy_s3.cc b/src/rgw/rgw_policy_s3.cc
index 4edaa94fe14..7dae34325e9 100644
--- a/src/rgw/rgw_policy_s3.cc
+++ b/src/rgw/rgw_policy_s3.cc
@@ -25,10 +25,11 @@ public:
v2 = _v2;
}
- bool check(RGWPolicyEnv *env) {
+ bool check(RGWPolicyEnv *env, map<string, bool>& checked_vars) {
string first, second;
- env->get_value(v1, first);
- env->get_value(v2, second);
+ env->get_value(v1, first, checked_vars);
+ env->get_value(v2, second, checked_vars);
+
dout(1) << "policy condition check " << v1 << " [" << first << "] " << v2 << " [" << second << "]" << dendl;
return check(first, second);
}
@@ -66,17 +67,32 @@ bool RGWPolicyEnv::get_var(const string& name, string& val)
return true;
}
-bool RGWPolicyEnv::get_value(const string& s, string& val)
+bool RGWPolicyEnv::get_value(const string& s, string& val, map<string, bool>& checked_vars)
{
if (s.empty() || s[0] != '$') {
val = s;
return true;
}
- return get_var(s.substr(1), val);
+ const string& var = s.substr(1);
+ checked_vars[var] = true;
+
+ return get_var(var, val);
}
+bool RGWPolicyEnv::match_policy_vars(map<string, bool>& policy_vars)
+{
+ map<string, string>::iterator iter;
+ for (iter = vars.begin(); iter != vars.end(); ++iter) {
+ if (policy_vars.count(iter->first) == 0) {
+ dout(1) << "env var missing in policy: " << iter->first << dendl;
+ return false;
+ }
+ }
+ return true;
+}
+
RGWPolicy::~RGWPolicy()
{
list<RGWPolicyCondition *>::iterator citer;
@@ -115,6 +131,8 @@ bool RGWPolicy::check(RGWPolicyEnv *env)
if (!env->get_var(name, val))
return false;
+ set_var_checked(name);
+
dout(20) << "comparing " << name << " [" << val << "], " << check_val << dendl;
if (val.compare(check_val) != 0) {
dout(1) << "policy check failed, val=" << val << " != " << check_val << dendl;
@@ -125,10 +143,15 @@ bool RGWPolicy::check(RGWPolicyEnv *env)
list<RGWPolicyCondition *>::iterator citer;
for (citer = conditions.begin(); citer != conditions.end(); ++citer) {
RGWPolicyCondition *cond = *citer;
- if (!cond->check(env)) {
+ if (!cond->check(env, checked_vars)) {
return false;
}
}
+
+ if (!env->match_policy_vars(checked_vars)) {
+ dout(1) << "missing policy condition" << dendl;
+ return false;
+ }
return true;
}
diff --git a/src/rgw/rgw_policy_s3.h b/src/rgw/rgw_policy_s3.h
index 5461642fb13..2a8e75407e3 100644
--- a/src/rgw/rgw_policy_s3.h
+++ b/src/rgw/rgw_policy_s3.h
@@ -14,7 +14,8 @@ class RGWPolicyEnv {
public:
void add_var(const string& name, const string& value);
bool get_var(const string& name, string& val);
- bool get_value(const string& s, string& val);
+ bool get_value(const string& s, string& val, std::map<std::string, bool>& checked_vars);
+ bool match_policy_vars(map<string, bool>& policy_vars);
};
class RGWPolicyCondition;
@@ -24,12 +25,17 @@ class RGWPolicy {
utime_t expires;
std::list<RGWPolicyCondition *> conditions;
std::list<pair<std::string, std::string> > var_checks;
+ std::map<std::string, bool> checked_vars;
public:
RGWPolicy() {}
~RGWPolicy();
void set_expires(utime_t& e) { expires = e; }
+ void set_var_checked(const std::string& var) {
+ checked_vars[var] = true;
+ }
+
int add_condition(const std::string& op, const std::string& first, const std::string& second);
void add_simple_check(const std::string& var, const std::string& value) {
var_checks.push_back(pair<string, string>(var, value));
diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc
index 0850fd425d9..ec8b711c87d 100644
--- a/src/rgw/rgw_rest_s3.cc
+++ b/src/rgw/rgw_rest_s3.cc
@@ -853,6 +853,10 @@ int RGWPostObj_ObjStore_S3::get_policy()
return -EINVAL;
}
+ post_policy.set_var_checked("AWSAccessKeyId");
+ post_policy.set_var_checked("policy");
+ post_policy.set_var_checked("signature");
+
if (!post_policy.check(&env)) {
ldout(s->cct, 0) << "policy check failed" << dendl;
return -EINVAL;