{NULL, NULL},
};
+#define SSE_C_GROUP 1
+#define KMS_GROUP 2
+
+int get_encryption_defaults(req_state *s)
+{
+ int meta_sse_group = 0;
+ constexpr auto sse_c_prefix = "x-amz-server-side-encryption-customer-";
+ constexpr auto encrypt_attr = "x-amz-server-side-encryption";
+ constexpr auto context_attr = "x-amz-server-side-encryption-context";
+ constexpr auto kms_attr = "x-amz-server-side-encryption-aws-kms-key-id";
+ constexpr auto bucket_key_attr = "x-amz-server-side-encryption-bucket-key-enabled";
+ bool bucket_configuration_found { false };
+
+ for (auto& kv : s->info.crypt_attribute_map) {
+ if (kv.first.find(sse_c_prefix) == 0)
+ meta_sse_group |= SSE_C_GROUP;
+ else if (kv.first.find(encrypt_attr) == 0)
+ meta_sse_group |= KMS_GROUP;
+ }
+ if (meta_sse_group == (SSE_C_GROUP|KMS_GROUP)) {
+ s->err.message = "Server side error - can't do sse-c & sse-kms|sse-s3";
+ return -EINVAL;
+ }
+
+ const auto& buck_attrs = s->bucket_attrs;
+ auto aiter = buck_attrs.find(RGW_ATTR_BUCKET_ENCRYPTION_POLICY);
+ RGWBucketEncryptionConfig bucket_encryption_conf;
+ if (aiter != buck_attrs.end()) {
+ ldpp_dout(s, 5) << "Found RGW_ATTR_BUCKET_ENCRYPTION_POLICY on "
+ << s->bucket_name << dendl;
+
+ bufferlist::const_iterator iter{&aiter->second};
+
+ try {
+ bucket_encryption_conf.decode(iter);
+ bucket_configuration_found = true;
+ } catch (const buffer::error& e) {
+ s->err.message = "Server side error - can't decode bucket_encryption_conf";
+ ldpp_dout(s, 5) << __func__ << "decode bucket_encryption_conf failed" << dendl;
+ return -EINVAL;
+ }
+ }
+ if (meta_sse_group & SSE_C_GROUP) {
+ ldpp_dout(s, 20) << "get_encryption_defaults: no defaults cause sse-c forced"
+ << dendl;
+ return 0; // sse-c: no defaults here
+ }
+ std::string sse_algorithm { bucket_encryption_conf.sse_algorithm() };
+ auto kms_master_key_id { bucket_encryption_conf.kms_master_key_id() };
+ bool bucket_key_enabled { bucket_encryption_conf.bucket_key_enabled() };
+ bool kms_attr_seen = false;
+ if (bucket_configuration_found) {
+ ldpp_dout(s, 5) << "RGW_ATTR_BUCKET_ENCRYPTION ALGO: "
+ << sse_algorithm << dendl;
+ }
+
+ auto iter = s->info.crypt_attribute_map.find(kms_attr);
+ if (iter != s->info.crypt_attribute_map.end()) {
+ldpp_dout(s, 20) << "get_encryption_defaults: found kms_attr " << kms_attr << " = " << iter->second << ", setting kms_attr_seen" << dendl;
+ kms_attr_seen = true;
+ } else if (kms_master_key_id != "") {
+ldpp_dout(s, 20) << "get_encryption_defaults: no kms_attr, but kms_master_key_id = " << kms_master_key_id << ", settig kms_attr_seen" << dendl;
+ kms_attr_seen = true;
+ rgw_set_amz_meta_header(s->info.crypt_attribute_map, kms_attr, kms_master_key_id, OVERWRITE);
+ }
+
+ iter = s->info.crypt_attribute_map.find(bucket_key_attr);
+ if (iter != s->info.crypt_attribute_map.end()) {
+ldpp_dout(s, 20) << "get_encryption_defaults: found bucket_key_attr " << bucket_key_attr << " = " << iter->second << ", setting kms_attr_seen" << dendl;
+ kms_attr_seen = true;
+ } else if (bucket_key_enabled) {
+ldpp_dout(s, 20) << "get_encryption_defaults: no bucket_key_attr, but bucket_key_enabled, setting kms_attr_seen" << dendl;
+ kms_attr_seen = true;
+ rgw_set_amz_meta_header(s->info.crypt_attribute_map, bucket_key_attr, "true", OVERWRITE);
+ }
+
+ iter = s->info.crypt_attribute_map.find(context_attr);
+ if (iter != s->info.crypt_attribute_map.end()) {
+ldpp_dout(s, 20) << "get_encryption_defaults: found context_attr " << context_attr << " = " << iter->second << ", setting kms_attr_seen" << dendl;
+ kms_attr_seen = true;
+ }
+
+ if (kms_attr_seen && sse_algorithm == "") {
+ldpp_dout(s, 20) << "get_encryption_defaults: kms_attr but no algorithm, defaulting to aws_kms" << dendl;
+ sse_algorithm = "aws:kms";
+ }
+
+ iter = s->info.crypt_attribute_map.find(encrypt_attr);
+ if (iter != s->info.crypt_attribute_map.end()) {
+ldpp_dout(s, 20) << "get_encryption_defaults: found encrypt_attr " << encrypt_attr << " = " << iter->second << ", setting sse_algorithm to that" << dendl;
+ sse_algorithm = iter->second;
+ } else if (sse_algorithm != "") {
+ rgw_set_amz_meta_header(s->info.crypt_attribute_map, encrypt_attr, sse_algorithm, OVERWRITE);
+ }
+for (const auto& kv: s->info.crypt_attribute_map) {
+ldpp_dout(s, 20) << "get_encryption_defaults: final map: " << kv.first << " = " << kv.second << dendl;
+}
+ldpp_dout(s, 20) << "get_encryption_defaults: kms_attr_seen is " << kms_attr_seen << " and sse_algorithm is " << sse_algorithm << dendl;
+ if (kms_attr_seen && sse_algorithm != "aws:kms") {
+ s->err.message = "algorithm <" + sse_algorithm + "> but got sse-kms attributes";
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
int RGWGetObj_ObjStore_S3Website::send_response_data(bufferlist& bl, off_t bl_ofs, off_t bl_len) {
map<string, bufferlist>::iterator iter;
iter = attrs.find(RGW_ATTR_AMZ_WEBSITE_REDIRECT_LOCATION);
end_header(s, this);
}
-static inline void map_qs_metadata(struct req_state* s)
+static inline void map_qs_metadata(struct req_state* s, bool crypto_too)
{
/* merge S3 valid user metadata from the query-string into
* x_meta_map, which maps them to attributes */
if (k.find("x-amz-meta-") == /* offset */ 0) {
rgw_add_amz_meta_header(s->info.x_meta_map, k, elt.second);
}
+ if (crypto_too && k.find("x-amz-server-side-encryption") == /* offset */ 0) {
+ rgw_set_amz_meta_header(s->info.crypt_attribute_map, k, elt.second, OVERWRITE);
+ }
}
}
int ret;
- map_qs_metadata(s);
+ map_qs_metadata(s, true);
+ ret = get_encryption_defaults(s);
+ if (ret < 0) {
+ ldpp_dout(this, 5) << __func__ << "(): get_encryption_defaults() returned ret=" << ret << dendl;
+ return ret;
+ }
RGWAccessControlPolicy_S3 s3policy(s->cct);
ret = create_s3_policy(s, store, s3policy, s->owner);
return op_ret;
}
- map_qs_metadata(s);
+ map_qs_metadata(s, false);
ldpp_dout(this, 20) << "adding bucket to policy env: " << s->bucket->get_name()
<< dendl;
env.add_var(part.name, part_str);
} while (!done);
+ for (auto &p: parts) {
+ if (! boost::istarts_with(p.first, "x-amz-server-side-encryption")) {
+ continue;
+ }
+ bufferlist &d { p.second.data };
+ std::string v { rgw_trim_whitespace(std::string_view(d.c_str(), d.length())) };
+ rgw_set_amz_meta_header(s->info.crypt_attribute_map, p.first, v, OVERWRITE);
+ }
+ int r = get_encryption_defaults(s);
+ if (r < 0) {
+ ldpp_dout(this, 5) << __func__ << "(): get_encryption_defaults() returned ret=" << r << dendl;
+ return r;
+ }
+
string object_str;
if (!part_str(parts, "key", &object_str)) {
err_msg = "Key not specified";
attrs[attr_name] = attr_bl;
}
- int r = get_policy(y);
+ r = get_policy(y);
if (r < 0)
return r;
return ret;
}
- map_qs_metadata(s);
+ map_qs_metadata(s, true);
return do_aws4_auth_completion();
}