From: Radoslaw Zarzynski Date: Fri, 21 Apr 2017 15:28:32 +0000 (+0200) Subject: rgw: drop the old AWSv4 code. X-Git-Tag: v12.1.0~155^2~34 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=36e1c34e9e4f70d9962cba5aea7fedcaa789755c;p=ceph.git rgw: drop the old AWSv4 code. Signed-off-by: Radoslaw Zarzynski --- diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index df336e9db5ea..4849d0bf1f48 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -3391,322 +3391,6 @@ int RGW_Auth_S3::authorize(RGWRados* const store, return authorize_v2(store, auth_registry, s); } -int RGW_Auth_S3::authorize_aws4_auth_complete(RGWRados *store, struct req_state *s) -{ - return authorize_v4_complete(store, s, "", false); -} - -int RGW_Auth_S3::authorize_v4_complete(RGWRados *store, struct req_state *s, const string& request_payload, bool unsigned_payload) -{ - const char *expected_request_payload_hash = \ - rgw::auth::s3::get_v4_exp_payload_hash(s->info); - - /* In AWSv4 the hash of real, transfered payload IS NOT necessary to form - * a Canonical Request, and thus verify a Signature. x-amz-content-sha256 - * header lets get the information very early -- before seeing first byte - * of HTTP body. As a consequence, we can decouple Signature verification - * from payload's fingerprint check. */ - std::string payload_hash; - if (unsigned_payload) { - payload_hash = "UNSIGNED-PAYLOAD"; - } else { - if (s->aws4_auth_needs_complete) { - payload_hash = AWS_AUTHv4_IO(s)->grab_aws4_sha256_hash(); - } else { - if (s->aws4_auth_streaming_mode) { - payload_hash = "STREAMING-AWS4-HMAC-SHA256-PAYLOAD"; - } else { - payload_hash = \ - rgw::auth::s3::hash_string_sha256(request_payload.c_str(), - request_payload.size()); - } - } - } - - /* Validate x-amz-sha256 */ - if (s->aws4_auth_needs_complete) { - if (payload_hash.compare(expected_request_payload_hash) != 0) { - ldout(s->cct, 10) << "ERROR: x-amz-content-sha256 does not match" << dendl; - return -ERR_AMZ_CONTENT_SHA256_MISMATCH; - } - } - - return 0; - -} - -static inline bool is_base64_for_content_md5(unsigned char c) { - return (isalnum(c) || isspace(c) || (c == '+') || (c == '/') || (c == '=')); -} - -/* - * handle v4 signatures (rados auth only) - */ -int RGW_Auth_S3::authorize_v4(RGWRados *store, struct req_state *s, bool force_boto2_compat /* = true */) -{ - string::size_type pos; - bool using_qs; - - /* v4 requires rados auth */ - if (!store->ctx()->_conf->rgw_s3_auth_use_rados) { - return -EPERM; - } - - try { - s->aws4_auth = std::unique_ptr(new rgw_aws4_auth); - } catch (std::bad_alloc&) { - return -ENOMEM; - } - - std::string access_key_id; - std::string signed_hdrs; - std::string client_signature; - int ret = rgw::auth::s3::parse_credentials(s->info, - access_key_id, - s->aws4_auth->credential_scope, - signed_hdrs, - client_signature, - s->aws4_auth->date, - using_qs); - if (ret < 0) { - return ret; - } - - /* grab user information */ - - if (rgw_get_user_info_by_access_key(store, access_key_id, *s->user) < 0) { - dout(10) << "error reading user info, uid=" << access_key_id - << " can't authenticate" << dendl; - return -ERR_INVALID_ACCESS_KEY; - } - - /* - * create a canonical request - * - * http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html - */ - - /* craft canonical uri */ - const auto canonical_uri = rgw::auth::s3::get_v4_canonical_uri(s->info); - - /* craft canonical query string */ - const auto canonical_qs = rgw::auth::s3::get_v4_canonical_qs(s->info, - using_qs); - - /* craft canonical headers */ - boost::optional canonical_headers = \ - rgw::auth::s3::get_v4_canonical_headers(s->info, - signed_hdrs, - using_qs, - force_boto2_compat); - if (canonical_headers) { - ldout(s->cct, 10) << "canonical headers format = " << *canonical_headers - << dendl; - } else { - return -EPERM; - } - - /* handle request payload */ - - string request_payload; - - bool unsigned_payload = false; - s->aws4_auth_streaming_mode = false; - - if (using_qs) { - /* query parameters auth */ - unsigned_payload = true; - } else { - /* header auth */ - const char *request_payload_hash = s->info.env->get("HTTP_X_AMZ_CONTENT_SHA256"); - if (request_payload_hash) { - unsigned_payload = string("UNSIGNED-PAYLOAD").compare(request_payload_hash) == 0; - if (!unsigned_payload) { - s->aws4_auth_streaming_mode = string("STREAMING-AWS4-HMAC-SHA256-PAYLOAD").compare(request_payload_hash) == 0; - } - } - } - - /* Get the expected hash. */ - auto exp_payload_hash = rgw::auth::s3::get_v4_exp_payload_hash(s->info); - - /* craft canonical request */ - std::string canonical_req_hash = \ - rgw::auth::s3::get_v4_canon_req_hash(s->cct, - s->info.method, - canonical_uri, - canonical_qs, - *canonical_headers, - signed_hdrs, - exp_payload_hash); - - /* - * create a string to sign - * - * http://docs.aws.amazon.com/general/latest/gr/sigv4-create-string-to-sign.html - */ - - std::string string_to_sign = \ - rgw::auth::s3::get_v4_string_to_sign(s->cct, "AWS4-HMAC-SHA256", - s->aws4_auth->date, - s->aws4_auth->credential_scope, - canonical_req_hash); - - /* - * calculate the AWS signature - * - * http://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html - */ - - const auto iter = s->user->access_keys.find(access_key_id); - if (iter == std::end(s->user->access_keys)) { - ldout(s->cct, 10) << "ERROR: access key not encoded in user info" << dendl; - return -EPERM; - } - const RGWAccessKey& k = iter->second; - - s->aws4_auth->signing_key = \ - rgw::auth::s3::get_v4_signing_key(s->cct, - s->aws4_auth->credential_scope, k.key); - const std::string server_signature = \ - rgw::auth::s3::get_v4_signature(s->cct, s->aws4_auth->signing_key, - string_to_sign); - - - ldout(s->cct, 10) << "----------------------------- Verifying signatures" << dendl; - ldout(s->cct, 10) << "Signature = " << client_signature << dendl; - ldout(s->cct, 10) << "New Signature = " << server_signature << dendl; - ldout(s->cct, 10) << "-----------------------------" << dendl; - - /* verify signature */ - if (client_signature != server_signature) { - ret = -ERR_SIGNATURE_NO_MATCH; - ldout(s->cct, 20) << "delayed aws4 auth failed" << dendl; - return ret; - } - - s->aws4_auth->seed_signature = server_signature; - - /* from rfc2616 - 4.3 Message Body - * - * "The presence of a message-body in a request is signaled by the inclusion of a - * Content-Length or Transfer-Encoding header field in the request's message-headers." - */ - bool body_available = s->content_length != 0 || s->info.env->get("HTTP_TRANSFER_ENCODING") != NULL; - - if (unsigned_payload || !body_available) { - - /* requests lacking of body or shipping with 'UNSIGNED-PAYLOAD' are authenticated now */ - - /* complete aws4 auth */ - - int err = authorize_v4_complete(store, s, request_payload, unsigned_payload); - if (err) { - return err; - } - - /* authorization ok */ - dout(10) << "v4 auth ok" << dendl; - - /* aws4 auth completed */ - - s->aws4_auth_needs_complete = false; - - } else { - - /* aws4 auth not completed... delay aws4 auth */ - - if (!s->aws4_auth_streaming_mode) { - - dout(10) << "delaying v4 auth" << dendl; - - /* payload in a single chunk */ - - switch (s->op_type) - { - case RGW_OP_CREATE_BUCKET: - case RGW_OP_PUT_OBJ: - case RGW_OP_PUT_ACLS: - case RGW_OP_PUT_CORS: - case RGW_OP_COMPLETE_MULTIPART: - case RGW_OP_SET_BUCKET_VERSIONING: - case RGW_OP_DELETE_MULTI_OBJ: - case RGW_OP_ADMIN_SET_METADATA: - case RGW_OP_SET_BUCKET_WEBSITE: - case RGW_OP_PUT_BUCKET_POLICY: - break; - default: - dout(10) << "ERROR: AWS4 completion for this operation NOT IMPLEMENTED" << dendl; - return -ERR_NOT_IMPLEMENTED; - } - - s->aws4_auth_needs_complete = true; - - } else { - - dout(10) << "body content detected in multiple chunks" << dendl; - - /* payload in multiple chunks */ - - switch(s->op_type) - { - case RGW_OP_PUT_OBJ: - break; - default: - dout(10) << "ERROR: AWS4 completion for this operation NOT IMPLEMENTED (streaming mode)" << dendl; - return -ERR_NOT_IMPLEMENTED; - } - - /* calculate seed */ - - int err = authorize_v4_complete(store, s, "", unsigned_payload); - if (err) { - return err; - } - - dout(10) << "aws4 seed signature ok... delaying v4 auth" << dendl; - - s->aws4_auth_needs_complete = false; - - } - - } - - if (!k.subuser.empty()) { - map::iterator uiter = s->user->subusers.find(k.subuser); - if (uiter == s->user->subusers.end()) { - dout(0) << "NOTICE: could not find subuser: " << k.subuser << dendl; - return -EPERM; - } - RGWSubUser& subuser = uiter->second; - s->perm_mask = subuser.perm_mask; - } else { - s->perm_mask = RGW_PERM_FULL_CONTROL; - } - - if (s->user->system) { - s->system_request = true; - dout(20) << "system request" << dendl; - s->info.args.set_system(); - string euid = s->info.args.get(RGW_SYS_PARAM_PREFIX "uid"); - rgw_user effective_uid(euid); - RGWUserInfo effective_user; - if (!effective_uid.empty()) { - int ret = rgw_get_user_info_by_uid(store, effective_uid, effective_user); - if (ret < 0) { - ldout(s->cct, 0) << "User lookup failed!" << dendl; - return -EACCES; - } - *(s->user) = effective_user; - } - } - - // populate the owner info - s->owner.set_id(s->user->user_id); - s->owner.set_name(s->user->display_name); - - return 0; -} /* * handle v2 signatures diff --git a/src/rgw/rgw_rest_s3.h b/src/rgw/rgw_rest_s3.h index 8b4007656adf..edaf306a69b9 100644 --- a/src/rgw/rgw_rest_s3.h +++ b/src/rgw/rgw_rest_s3.h @@ -448,15 +448,10 @@ private: static int authorize_v2(RGWRados *store, const rgw::auth::StrategyRegistry& auth_registry, struct req_state *s); - static int authorize_v4(RGWRados *store, struct req_state *s, bool force_boto2_compat = true); - static int authorize_v4_complete(RGWRados *store, struct req_state *s, - const string& request_payload, - bool unsigned_payload); public: static int authorize(RGWRados *store, const rgw::auth::StrategyRegistry& auth_registry, struct req_state *s); - static int authorize_aws4_auth_complete(RGWRados *store, struct req_state *s); }; class RGWHandler_Auth_S3 : public RGWHandler_REST {