From bd04a775a89d7ce7581408d2befe5ebb6462adb5 Mon Sep 17 00:00:00 2001 From: Christophe Courtaut Date: Wed, 3 Jul 2013 20:48:12 +0200 Subject: [PATCH] rgw: Adds passwd alternative to keystone admin token http://tracker.ceph.com/issues/5374 Fixes #5374 This adds options parsing to have a user, password and tenant, to be able to ask for a token. This token is then used to authenticate against keystone, instead of relying on the admin token. Otherwise, you can still use the admin token to authenticate. This doesn't change the existing behaviour. Signed-off-by: Christophe Courtaut --- src/common/config_opts.h | 3 ++ src/rgw/rgw_swift.cc | 92 +++++++++++++++++++++++++++++++++------- src/rgw/rgw_swift.h | 2 + 3 files changed, 81 insertions(+), 16 deletions(-) diff --git a/src/common/config_opts.h b/src/common/config_opts.h index 0b3938ecb9e..6d9ce4ae183 100644 --- a/src/common/config_opts.h +++ b/src/common/config_opts.h @@ -661,6 +661,9 @@ OPTION(rgw_swift_auth_url, OPT_STR, "") // default URL to go and verify t OPTION(rgw_swift_auth_entry, OPT_STR, "auth") // entry point for which a url is considered a swift auth url OPTION(rgw_keystone_url, OPT_STR, "") // url for keystone server OPTION(rgw_keystone_admin_token, OPT_STR, "") // keystone admin token (shared secret) +OPTION(rgw_keystone_admin_user, OPT_STR, "") // keystone admin user name +OPTION(rgw_keystone_admin_password, OPT_STR, "") // keystone admin user password +OPTION(rgw_keystone_admin_tenant, OPT_STR, "") // keystone admin user tenant OPTION(rgw_keystone_accepted_roles, OPT_STR, "Member, admin") // roles required to serve requests OPTION(rgw_keystone_token_cache_size, OPT_INT, 10000) // max number of entries in keystone token cache OPTION(rgw_keystone_revocation_interval, OPT_INT, 15 * 60) // seconds between tokens revocation check diff --git a/src/rgw/rgw_swift.cc b/src/rgw/rgw_swift.cc index 24e09051320..d68dbe88228 100644 --- a/src/rgw/rgw_swift.cc +++ b/src/rgw/rgw_swift.cc @@ -104,32 +104,44 @@ int RGWSwift::validate_token(const char *token, struct rgw_swift_auth_info *info return 0; } - - -class RGWValidateKeystoneToken : public RGWHTTPClient { +class RGWPostHTTPData : public RGWHTTPClient { bufferlist *bl; + std::string post_data; + size_t post_data_index; public: - RGWValidateKeystoneToken(CephContext *_cct, bufferlist *_bl) : RGWHTTPClient(_cct), bl(_bl) {} + RGWPostHTTPData(CephContext *_cct, bufferlist *_bl) : RGWHTTPClient(_cct), bl(_bl), post_data_index(0) {} + + void set_post_data(const std::string& _post_data) { + this->post_data = _post_data; + } + + int send_data(void* ptr, size_t len) { + int length_to_copy = 0; + if (post_data_index < post_data.length()) { + length_to_copy = min(post_data.length() - post_data_index, len); + memcpy(ptr, post_data.data() + post_data_index, length_to_copy); + post_data_index += length_to_copy; + } + return length_to_copy; + } int receive_data(void *ptr, size_t len) { bl->append((char *)ptr, len); return 0; } + int receive_header(void *ptr, size_t len) { return 0; } - int send_data(void *ptr, size_t len) { - return 0; - } - }; -static RGWKeystoneTokenCache *keystone_token_cache = NULL; +typedef RGWPostHTTPData RGWGetKeystoneAdminToken; +typedef RGWPostHTTPData RGWGetRevokedTokens; -class RGWGetRevokedTokens : public RGWHTTPClient { +class RGWValidateKeystoneToken : public RGWHTTPClient { bufferlist *bl; public: - RGWGetRevokedTokens(CephContext *_cct, bufferlist *_bl) : RGWHTTPClient(_cct), bl(_bl) {} + RGWValidateKeystoneToken(CephContext *_cct, bufferlist *_bl) : RGWHTTPClient(_cct), bl(_bl) {} int receive_data(void *ptr, size_t len) { bl->append((char *)ptr, len); @@ -141,8 +153,11 @@ public: int send_data(void *ptr, size_t len) { return 0; } + }; +static RGWKeystoneTokenCache *keystone_token_cache = NULL; + static int open_cms_envelope(CephContext *cct, string& src, string& dst) { #define BEGIN_CMS "-----BEGIN CMS-----" @@ -211,23 +226,68 @@ static int decode_b64_cms(CephContext *cct, const string& signed_b64, bufferlist return 0; } - -int RGWSwift::check_revoked() +int RGWSwift::get_keystone_url(std::string& url) { bufferlist bl; RGWGetRevokedTokens req(cct, &bl); - string url = g_conf->rgw_keystone_url; + url = cct->_conf->rgw_keystone_url; if (url.empty()) { ldout(cct, 0) << "ERROR: keystone url is not configured" << dendl; return -EINVAL; } if (url[url.size() - 1] != '/') url.append("/"); - url.append("v2.0/tokens/revoked"); + return 0; +} - req.append_header("X-Auth-Token", g_conf->rgw_keystone_admin_token); +int RGWSwift::get_keystone_admin_token(std::string& token) +{ + std::string token_url; + + if (get_keystone_url(token_url) < 0) + return -EINVAL; + if (cct->_conf->rgw_keystone_admin_token.empty()) { + token_url.append("v2.0/tokens"); + KeystoneToken t; + bufferlist token_bl; + RGWGetKeystoneAdminToken token_req(cct, &token_bl); + std::ostringstream os; + os << "{ \"auth\":{ \"passwordCredentials\":{ \"username\":\""; + os << cct->_conf->rgw_keystone_admin_user; + os << "\", \"password\":\""; + os << cct->_conf->rgw_keystone_admin_password; + os << "\"}, \"tenantName\":\""; + os << cct->_conf->rgw_keystone_admin_tenant; + os << "\"}}"; + token_req.set_post_data(os.str()); + int ret = token_req.process(token_url.c_str()); + if (ret < 0) + return ret; + if (t.parse(cct, token_bl) != 0) + return -EINVAL; + token = t.token.id; + } else { + token = cct->_conf->rgw_keystone_admin_token; + } + return 0; +} + +int RGWSwift::check_revoked() +{ + string url; + string token; + + bufferlist bl; + RGWGetRevokedTokens req(cct, &bl); + + if (get_keystone_admin_token(token) < 0) + return -EINVAL; + if (get_keystone_url(url) < 0) + return -EINVAL; + url.append("v2.0/tokens/revoked"); + req.append_header("X-Auth-Token", token); int ret = req.process(url.c_str()); if (ret < 0) return ret; diff --git a/src/rgw/rgw_swift.h b/src/rgw/rgw_swift.h index 3f0bd161946..97347e80691 100644 --- a/src/rgw/rgw_swift.h +++ b/src/rgw/rgw_swift.h @@ -29,6 +29,8 @@ class RGWSwift { int parse_keystone_token_response(const string& token, bufferlist& bl, struct rgw_swift_auth_info *info, KeystoneToken& t); int update_user_info(RGWRados *store, struct rgw_swift_auth_info *info, RGWUserInfo& user_info); + int get_keystone_url(std::string& url); + int get_keystone_admin_token(std::string& token); class KeystoneRevokeThread : public Thread { CephContext *cct; -- 2.47.3