From: Christophe Courtaut Date: Wed, 3 Jul 2013 18:48:12 +0000 (+0200) Subject: rgw: Adds passwd alternative to keystone admin token X-Git-Tag: v0.73~53^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=bd04a775a89d7ce7581408d2befe5ebb6462adb5;p=ceph.git 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 --- diff --git a/src/common/config_opts.h b/src/common/config_opts.h index 0b3938ecb9e5..6d9ce4ae183c 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 24e09051320d..d68dbe882285 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 3f0bd1619460..97347e806918 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;