From 8a25a51e42cdaed2c66dc25a6c6d0245441123a3 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Fri, 30 Jan 2015 07:03:30 -0800 Subject: [PATCH] rgw: fail s3 POST auth if keystone not configured Fixes: #10698 This fixes issue introduced in 8b3dfc9472022ea45ad24e02e0aa21dfdad798f8, where if user does not exist, we try keystone authentication. However, if keystone is not configured we justt fall through without failing. This would have failed later on due to bucket permissions, unless bucket had a public write permissions. Backports: Firefly Reported-by: Valery Tschopp Signed-off-by: Yehuda Sadeh Conflicts: src/rgw/rgw_rest_s3.cc --- src/rgw/rgw_rest_s3.cc | 86 +++++++++++++++++++++++++++--------------- 1 file changed, 56 insertions(+), 30 deletions(-) diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 6fcecf7ac54..900431dcec2 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -960,38 +960,64 @@ int RGWPostObj_ObjStore_S3::get_policy() ret = rgw_get_user_info_by_access_key(store, s3_access_key, user_info); if (ret < 0) { - ldout(s->cct, 0) << "User lookup failed!" << dendl; - err_msg = "Bad access key / signature"; - return -EACCES; - } + // Try keystone authentication as well + int keystone_result = -EINVAL; + if (!store->ctx()->_conf->rgw_s3_auth_use_keystone || + store->ctx()->_conf->rgw_keystone_url.empty()) { + return -EACCES; + } + dout(20) << "s3 keystone: trying keystone auth" << dendl; - map access_keys = user_info.access_keys; + RGW_Auth_S3_Keystone_ValidateToken keystone_validator(store->ctx()); + keystone_result = keystone_validator.validate_s3token(s3_access_key,string(encoded_policy.c_str(),encoded_policy.length()),received_signature_str); - map::const_iterator iter = access_keys.find(s3_access_key); - // We know the key must exist, since the user was returned by - // rgw_get_user_info_by_access_key, but it doesn't hurt to check! - if (iter == access_keys.end()) { - ldout(s->cct, 0) << "Secret key lookup failed!" << dendl; - err_msg = "No secret key for matching access key"; - return -EACCES; - } - string s3_secret_key = (iter->second).key; - - char expected_signature_char[CEPH_CRYPTO_HMACSHA1_DIGESTSIZE]; - - calc_hmac_sha1(s3_secret_key.c_str(), s3_secret_key.size(), encoded_policy.c_str(), encoded_policy.length(), expected_signature_char); - bufferlist expected_signature_hmac_raw; - bufferlist expected_signature_hmac_encoded; - expected_signature_hmac_raw.append(expected_signature_char, CEPH_CRYPTO_HMACSHA1_DIGESTSIZE); - expected_signature_hmac_raw.encode_base64(expected_signature_hmac_encoded); - expected_signature_hmac_encoded.append((char)0); /* null terminate */ - - if (received_signature_str.compare(expected_signature_hmac_encoded.c_str()) != 0) { - ldout(s->cct, 0) << "Signature verification failed!" << dendl; - ldout(s->cct, 0) << "received: " << received_signature_str.c_str() << dendl; - ldout(s->cct, 0) << "expected: " << expected_signature_hmac_encoded.c_str() << dendl; - err_msg = "Bad access key / signature"; - return -EACCES; + if (keystone_result < 0) { + ldout(s->cct, 0) << "User lookup failed!" << dendl; + err_msg = "Bad access key / signature"; + return -EACCES; + } + + user_info.user_id = keystone_validator.response.token.tenant.id; + user_info.display_name = keystone_validator.response.token.tenant.name; + + /* try to store user if it not already exists */ + if (rgw_get_user_info_by_uid(store, keystone_validator.response.token.tenant.id, user_info) < 0) { + int ret = rgw_store_user_info(store, user_info, NULL, NULL, 0, true); + if (ret < 0) { + dout(10) << "NOTICE: failed to store new user's info: ret=" << ret << dendl; + } + + s->perm_mask = RGW_PERM_FULL_CONTROL; + } + } else { + map access_keys = user_info.access_keys; + + map::const_iterator iter = access_keys.find(s3_access_key); + // We know the key must exist, since the user was returned by + // rgw_get_user_info_by_access_key, but it doesn't hurt to check! + if (iter == access_keys.end()) { + ldout(s->cct, 0) << "Secret key lookup failed!" << dendl; + err_msg = "No secret key for matching access key"; + return -EACCES; + } + string s3_secret_key = (iter->second).key; + + char expected_signature_char[CEPH_CRYPTO_HMACSHA1_DIGESTSIZE]; + + calc_hmac_sha1(s3_secret_key.c_str(), s3_secret_key.size(), encoded_policy.c_str(), encoded_policy.length(), expected_signature_char); + bufferlist expected_signature_hmac_raw; + bufferlist expected_signature_hmac_encoded; + expected_signature_hmac_raw.append(expected_signature_char, CEPH_CRYPTO_HMACSHA1_DIGESTSIZE); + expected_signature_hmac_raw.encode_base64(expected_signature_hmac_encoded); + expected_signature_hmac_encoded.append((char)0); /* null terminate */ + + if (received_signature_str.compare(expected_signature_hmac_encoded.c_str()) != 0) { + ldout(s->cct, 0) << "Signature verification failed!" << dendl; + ldout(s->cct, 0) << "received: " << received_signature_str.c_str() << dendl; + ldout(s->cct, 0) << "expected: " << expected_signature_hmac_encoded.c_str() << dendl; + err_msg = "Bad access key / signature"; + return -EACCES; + } } ldout(s->cct, 0) << "Successful Signature Verification!" << dendl; bufferlist decoded_policy; -- 2.47.3