summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYehuda Sadeh <yehuda@inktank.com>2012-11-05 17:29:52 -0800
committerYehuda Sadeh <yehuda@inktank.com>2012-11-08 13:24:29 -0800
commitff8c2380b37b853975fa64a71ab8bad5daed6515 (patch)
tree29a328becabcc97926847e70eccd60a38036dbb8
parentb69da4b8dbc5dedcbe13991c856d3b7be259ff78 (diff)
downloadceph-ff8c2380b37b853975fa64a71ab8bad5daed6515.tar.gz
rgw: keystone tokens revocation thread
Use a thread to invalidate revoked tokens. Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
-rw-r--r--src/common/config_opts.h1
-rw-r--r--src/rgw/rgw_rest_swift.cc2
-rw-r--r--src/rgw/rgw_swift.cc226
-rw-r--r--src/rgw/rgw_swift.h64
4 files changed, 196 insertions, 97 deletions
diff --git a/src/common/config_opts.h b/src/common/config_opts.h
index 6a3117947c6..c9c5b4943b6 100644
--- a/src/common/config_opts.h
+++ b/src/common/config_opts.h
@@ -428,6 +428,7 @@ 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_operator_roles, OPT_STR, "swiftoperator, 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
OPTION(rgw_admin_entry, OPT_STR, "admin") // entry point for which a url is considered an admin request
OPTION(rgw_enforce_swift_acls, OPT_BOOL, true)
OPTION(rgw_print_continue, OPT_BOOL, true) // enable if 100-Continue works
diff --git a/src/rgw/rgw_rest_swift.cc b/src/rgw/rgw_rest_swift.cc
index d3d45e5525c..753adc86e42 100644
--- a/src/rgw/rgw_rest_swift.cc
+++ b/src/rgw/rgw_rest_swift.cc
@@ -610,7 +610,7 @@ RGWOp *RGWHandler_ObjStore_Obj_SWIFT::op_copy()
int RGWHandler_ObjStore_SWIFT::authorize()
{
- bool authorized = rgw_verify_swift_token(store, s);
+ bool authorized = rgw_swift->verify_swift_token(store, s);
if (!authorized)
return -EPERM;
diff --git a/src/rgw/rgw_swift.cc b/src/rgw/rgw_swift.cc
index df075e97b7e..060b435dfa4 100644
--- a/src/rgw/rgw_swift.cc
+++ b/src/rgw/rgw_swift.cc
@@ -21,12 +21,13 @@ static list<string> roles_list;
class RGWKeystoneTokenCache;
class RGWValidateSwiftToken : public RGWHTTPClient {
+ CephContext *cct;
struct rgw_swift_auth_info *info;
protected:
- RGWValidateSwiftToken() {}
+ RGWValidateSwiftToken() : cct(NULL), info(NULL) {}
public:
- RGWValidateSwiftToken(struct rgw_swift_auth_info *_info) : info(_info) {}
+ RGWValidateSwiftToken(CephContext *_cct, struct rgw_swift_auth_info *_info) : cct(_cct), info(_info) {}
int read_header(void *ptr, size_t len);
@@ -39,7 +40,7 @@ int RGWValidateSwiftToken::read_header(void *ptr, size_t len)
char *s = (char *)ptr, *end = (char *)ptr + len;
char *p = line;
- dout(10) << "read_http_header" << dendl;
+ ldout(cct, 10) << "read_http_header" << dendl;
while (s != end) {
if (*s == '\r') {
@@ -48,7 +49,7 @@ int RGWValidateSwiftToken::read_header(void *ptr, size_t len)
}
if (*s == '\n') {
*p = '\0';
- dout(10) << "os_auth:" << line << dendl;
+ ldout(cct, 10) << "os_auth:" << line << dendl;
// TODO: fill whatever data required here
char *l = line;
char *tok = strsep(&l, " \t:");
@@ -76,7 +77,7 @@ int RGWValidateSwiftToken::read_header(void *ptr, size_t len)
return 0;
}
-static int rgw_swift_validate_token(const char *token, struct rgw_swift_auth_info *info)
+int RGWSwift::validate_token(const char *token, struct rgw_swift_auth_info *info)
{
if (g_conf->rgw_swift_auth_url.empty())
return -EINVAL;
@@ -88,9 +89,9 @@ static int rgw_swift_validate_token(const char *token, struct rgw_swift_auth_inf
char url_buf[auth_url.size() + 1 + strlen(token) + 1];
sprintf(url_buf, "%s/%s", auth_url.c_str(), token);
- RGWValidateSwiftToken validate(info);
+ RGWValidateSwiftToken validate(cct, info);
- dout(10) << "rgw_swift_validate_token url=" << url_buf << dendl;
+ ldout(cct, 10) << "rgw_swift_validate_token url=" << url_buf << dendl;
int ret = validate.process(url_buf);
if (ret < 0)
@@ -99,74 +100,55 @@ static int rgw_swift_validate_token(const char *token, struct rgw_swift_auth_inf
return 0;
}
-class KeystoneToken {
-public:
- string tenant_name;
- string tenant_id;
- string user_name;
- time_t expiration;
-
- map<string, bool> roles;
-
- KeystoneToken() {}
-
- int parse(bufferlist& bl);
-
- bool expired() {
- uint64_t now = ceph_clock_now(NULL).sec();
- return (now < (uint64_t)expiration);
- }
-};
-
-int KeystoneToken::parse(bufferlist& bl)
+int KeystoneToken::parse(CephContext *cct, bufferlist& bl)
{
RGWJSONParser parser;
if (!parser.parse(bl.c_str(), bl.length())) {
- dout(0) << "malformed json" << dendl;
+ ldout(cct, 0) << "malformed json" << dendl;
return -EINVAL;
}
JSONObjIter iter = parser.find_first("access");
if (iter.end()) {
- dout(0) << "token response is missing access section" << dendl;
+ ldout(cct, 0) << "token response is missing access section" << dendl;
return -EINVAL;
}
JSONObj *access_obj = *iter;
JSONObj *user = access_obj->find_obj("user");
if (!user) {
- dout(0) << "token response is missing user section" << dendl;
+ ldout(cct, 0) << "token response is missing user section" << dendl;
return -EINVAL;
}
if (!user->get_data("username", &user_name)) {
- dout(0) << "token response is missing user username field" << dendl;
+ ldout(cct, 0) << "token response is missing user username field" << dendl;
return -EINVAL;
}
JSONObj *roles_obj = user->find_obj("roles");
if (!roles_obj) {
- dout(0) << "token response is missing roles section, or section empty" << dendl;
+ ldout(cct, 0) << "token response is missing roles section, or section empty" << dendl;
return -EINVAL;
}
JSONObjIter riter = roles_obj->find_first();
if (riter.end()) {
- dout(0) << "token response has an empty roles list" << dendl;
+ ldout(cct, 0) << "token response has an empty roles list" << dendl;
return -EINVAL;
}
for (; !riter.end(); ++riter) {
JSONObj *role_obj = *riter;
if (!role_obj) {
- dout(0) << "ERROR: role object is NULL" << dendl;
+ ldout(cct, 0) << "ERROR: role object is NULL" << dendl;
return -EINVAL;
}
JSONObj *role_name = role_obj->find_obj("name");
if (!role_name) {
- dout(0) << "token response is missing role name section" << dendl;
+ ldout(cct, 0) << "token response is missing role name section" << dendl;
return -EINVAL;
}
string role = role_name->get_data();
@@ -175,20 +157,20 @@ int KeystoneToken::parse(bufferlist& bl)
JSONObj *token = access_obj->find_obj("token");
if (!token) {
- dout(0) << "missing token section in response" << dendl;
+ ldout(cct, 0) << "missing token section in response" << dendl;
return -EINVAL;
}
string expires;
if (!token->get_data("expires", &expires)) {
- dout(0) << "token response is missing expiration field" << dendl;
+ ldout(cct, 0) << "token response is missing expiration field" << dendl;
return -EINVAL;
}
struct tm t;
if (!parse_iso8601(expires.c_str(), &t)) {
- dout(0) << "failed to parse token expiration (" << expires << ")" << dendl;
+ ldout(cct, 0) << "failed to parse token expiration (" << expires << ")" << dendl;
return -EINVAL;
}
@@ -196,18 +178,18 @@ int KeystoneToken::parse(bufferlist& bl)
JSONObj *tenant = token->find_obj("tenant");
if (!tenant) {
- dout(0) << "token response is missing tenant section" << dendl;
+ ldout(cct, 0) << "token response is missing tenant section" << dendl;
return -EINVAL;
}
if (!tenant->get_data("id", &tenant_id)) {
- dout(0) << "tenant is missing id field" << dendl;
+ ldout(cct, 0) << "tenant is missing id field" << dendl;
return -EINVAL;
}
if (!tenant->get_data("name", &tenant_name)) {
- dout(0) << "tenant is missing name field" << dendl;
+ ldout(cct, 0) << "tenant is missing name field" << dendl;
return -EINVAL;
}
@@ -220,6 +202,8 @@ struct token_entry {
};
class RGWKeystoneTokenCache {
+ CephContext *cct;
+
map<string, token_entry> tokens;
list<string> tokens_lru;
@@ -228,7 +212,7 @@ class RGWKeystoneTokenCache {
size_t max;
public:
- RGWKeystoneTokenCache(int _max) : lock("RGWKeystoneTokenCache"), max(_max) {}
+ RGWKeystoneTokenCache(CephContext *_cct, int _max) : cct(_cct), lock("RGWKeystoneTokenCache"), max(_max) {}
bool find(const string& token_id, KeystoneToken& token);
void add(const string& token_id, KeystoneToken& token);
@@ -297,7 +281,7 @@ void RGWKeystoneTokenCache::invalidate(const string& token_id)
if (iter == tokens.end())
return;
- dout(20) << "invalidating revoked token id=" << token_id << dendl;
+ ldout(cct, 20) << "invalidating revoked token id=" << token_id << dendl;
token_entry& e = iter->second;
tokens_lru.erase(e.lru_iter);
tokens.erase(iter);
@@ -326,21 +310,22 @@ public:
return 0;
}
};
-static int open_cms_envelope(string& src, string& dst)
+
+static int open_cms_envelope(CephContext *cct, string& src, string& dst)
{
#define BEGIN_CMS "-----BEGIN CMS-----"
#define END_CMS "-----END CMS-----"
int start = src.find(BEGIN_CMS);
if (start < 0) {
- dout(0) << "failed to find " << BEGIN_CMS << " in response" << dendl;
+ ldout(cct, 0) << "failed to find " << BEGIN_CMS << " in response" << dendl;
return -EINVAL;
}
start += sizeof(BEGIN_CMS) - 1;
int end = src.find(END_CMS);
if (end < 0) {
- dout(0) << "failed to find " << END_CMS << " in response" << dendl;
+ ldout(cct, 0) << "failed to find " << END_CMS << " in response" << dendl;
return -EINVAL;
}
@@ -362,7 +347,7 @@ static int open_cms_envelope(string& src, string& dst)
return 0;
}
-static int decode_b64_cms(const string& signed_b64, bufferlist& bl)
+static int decode_b64_cms(CephContext *cct, const string& signed_b64, bufferlist& bl)
{
bufferptr signed_ber(signed_b64.size() * 2);
char *dest = signed_ber.c_str();
@@ -378,7 +363,7 @@ static int decode_b64_cms(const string& signed_b64, bufferlist& bl)
}
int ret = ceph_unarmor(dest, dest + signed_ber.length(), buf, buf + signed_b64.size());
if (ret < 0) {
- dout(0) << "ceph_unarmor() failed, ret=" << ret << dendl;
+ ldout(cct, 0) << "ceph_unarmor() failed, ret=" << ret << dendl;
return ret;
}
@@ -387,7 +372,7 @@ static int decode_b64_cms(const string& signed_b64, bufferlist& bl)
ret = ceph_decode_cms(signed_ber_bl, bl);
if (ret < 0) {
- dout(0) << "ceph_decode_cms returned " << ret << dendl;
+ ldout(cct, 0) << "ceph_decode_cms returned " << ret << dendl;
return ret;
}
@@ -395,14 +380,14 @@ static int decode_b64_cms(const string& signed_b64, bufferlist& bl)
}
-static int rgw_check_revoked()
+int RGWSwift::check_revoked()
{
bufferlist bl;
RGWGetRevokedTokens req(&bl);
string url = g_conf->rgw_keystone_url;
if (url.empty()) {
- dout(0) << "ERROR: keystone url is not configured" << dendl;
+ ldout(cct, 0) << "ERROR: keystone url is not configured" << dendl;
return -EINVAL;
}
if (url[url.size() - 1] != '/')
@@ -417,18 +402,18 @@ static int rgw_check_revoked()
bl.append((char)0); // NULL terminate for debug output
- dout(10) << "request returned " << bl.c_str() << dendl;
+ ldout(cct, 10) << "request returned " << bl.c_str() << dendl;
RGWJSONParser parser;
if (!parser.parse(bl.c_str(), bl.length())) {
- dout(0) << "malformed json" << dendl;
+ ldout(cct, 0) << "malformed json" << dendl;
return -EINVAL;
}
JSONObjIter iter = parser.find_first("signed");
if (iter.end()) {
- dout(0) << "revoked tokens response is missing signed section" << dendl;
+ ldout(cct, 0) << "revoked tokens response is missing signed section" << dendl;
return -EINVAL;
}
@@ -436,32 +421,32 @@ static int rgw_check_revoked()
string signed_str = signed_obj->get_data();
- dout(10) << "signed=" << signed_str << dendl;
+ ldout(cct, 10) << "signed=" << signed_str << dendl;
string signed_b64;
- ret = open_cms_envelope(signed_str, signed_b64);
+ ret = open_cms_envelope(cct, signed_str, signed_b64);
if (ret < 0)
return ret;
- dout(10) << "content=" << signed_b64 << dendl;
+ ldout(cct, 10) << "content=" << signed_b64 << dendl;
bufferlist json;
- ret = decode_b64_cms(signed_b64, json);
+ ret = decode_b64_cms(cct, signed_b64, json);
if (ret < 0) {
return ret;
}
- dout(10) << "ceph_decode_cms: decoded: " << json.c_str() << dendl;
+ ldout(cct, 10) << "ceph_decode_cms: decoded: " << json.c_str() << dendl;
RGWJSONParser list_parser;
if (!list_parser.parse(json.c_str(), json.length())) {
- dout(0) << "malformed json" << dendl;
+ ldout(cct, 0) << "malformed json" << dendl;
return -EINVAL;
}
JSONObjIter revoked_iter = list_parser.find_first("revoked");
if (revoked_iter.end()) {
- dout(0) << "no revoked section in json" << dendl;
+ ldout(cct, 0) << "no revoked section in json" << dendl;
return -EINVAL;
}
@@ -473,7 +458,7 @@ static int rgw_check_revoked()
JSONObj *token = o->find_obj("id");
if (!token) {
- dout(0) << "bad token in array, missing id" << dendl;
+ ldout(cct, 0) << "bad token in array, missing id" << dendl;
continue;
}
@@ -491,10 +476,9 @@ static void rgw_set_keystone_token_auth_info(KeystoneToken& token, struct rgw_sw
info->status = 200;
}
-static int rgw_parse_keystone_token_response(const string& token, bufferlist& bl, struct rgw_swift_auth_info *info)
+int RGWSwift::parse_keystone_token_response(const string& token, bufferlist& bl, struct rgw_swift_auth_info *info, KeystoneToken& t)
{
- KeystoneToken t;
- int ret = t.parse(bl);
+ int ret = t.parse(cct, bl);
if (ret < 0)
return ret;
@@ -509,27 +493,27 @@ static int rgw_parse_keystone_token_response(const string& token, bufferlist& bl
}
if (!found) {
- dout(0) << "user does not hold a matching role; required roles: " << g_conf->rgw_keystone_operator_roles << dendl;
+ ldout(cct, 0) << "user does not hold a matching role; required roles: " << g_conf->rgw_keystone_operator_roles << dendl;
return -EPERM;
}
- dout(0) << "validated token: " << t.tenant_name << ":" << t.user_name << " expires: " << t.expiration << dendl;
+ ldout(cct, 0) << "validated token: " << t.tenant_name << ":" << t.user_name << " expires: " << t.expiration << dendl;
rgw_set_keystone_token_auth_info(t, info);
return 0;
}
-static int update_user_info(RGWRados *store, struct rgw_swift_auth_info *info, RGWUserInfo& user_info)
+int RGWSwift::update_user_info(RGWRados *store, struct rgw_swift_auth_info *info, RGWUserInfo& user_info)
{
if (rgw_get_user_info_by_uid(store, info->user, user_info) < 0) {
- dout(0) << "NOTICE: couldn't map swift user" << dendl;
+ ldout(cct, 0) << "NOTICE: couldn't map swift user" << dendl;
user_info.user_id = info->user;
user_info.display_name = info->display_name;
int ret = rgw_store_user_info(store, user_info, true);
if (ret < 0) {
- dout(0) << "ERROR: failed to store new user's info: ret=" << ret << dendl;
+ ldout(cct, 0) << "ERROR: failed to store new user's info: ret=" << ret << dendl;
return ret;
}
}
@@ -560,36 +544,37 @@ static void get_token_id(const string& token, string& token_id)
char calc_md5[CEPH_CRYPTO_MD5_DIGESTSIZE * 2 + 1];
buf_to_hex(m, CEPH_CRYPTO_MD5_DIGESTSIZE, calc_md5);
token_id = calc_md5;
-
- dout(0) << "token_id=" << token_id << dendl;
}
-static bool decode_pki_token(const string& token, bufferlist& bl)
+static bool decode_pki_token(CephContext *cct, const string& token, bufferlist& bl)
{
if (!is_pki_token(token))
return false;
- int ret = decode_b64_cms(token, bl);
+ int ret = decode_b64_cms(cct, token, bl);
if (ret < 0)
return false;
- dout(20) << "successfully decoded pki token" << dendl;
+ ldout(cct, 20) << "successfully decoded pki token" << dendl;
return true;
}
-static int rgw_swift_validate_keystone_token(RGWRados *store, const string& token, struct rgw_swift_auth_info *info,
- RGWUserInfo& rgw_user)
+int RGWSwift::validate_keystone_token(RGWRados *store, const string& token, struct rgw_swift_auth_info *info,
+ RGWUserInfo& rgw_user)
{
KeystoneToken t;
- rgw_check_revoked();
-
string token_id;
get_token_id(token, token_id);
+ ldout(cct, 20) << "token_id=" << token_id << dendl;
+
if (keystone_token_cache->find(token_id, t)) {
rgw_set_keystone_token_auth_info(t, info);
+
+ ldout(cct, 20) << "cached token.tenant_id=" << t.tenant_id << dendl;
+
int ret = update_user_info(store, info, rgw_user);
if (ret < 0)
return ret;
@@ -599,12 +584,12 @@ static int rgw_swift_validate_keystone_token(RGWRados *store, const string& toke
bufferlist bl;
- if (!decode_pki_token(token, bl)) {
+ if (!decode_pki_token(cct, token, bl)) {
RGWValidateKeystoneToken validate(&bl);
string url = g_conf->rgw_keystone_url;
if (url.empty()) {
- dout(0) << "ERROR: keystone url is not configured" << dendl;
+ ldout(cct, 0) << "ERROR: keystone url is not configured" << dendl;
return -EINVAL;
}
if (url[url.size() - 1] != '/')
@@ -621,14 +606,12 @@ static int rgw_swift_validate_keystone_token(RGWRados *store, const string& toke
bl.append((char)0); // NULL terminate for debug output
- dout(20) << "received response: " << bl.c_str() << dendl;
+ ldout(cct, 20) << "received response: " << bl.c_str() << dendl;
- int ret = rgw_parse_keystone_token_response(token, bl, info);
+ int ret = parse_keystone_token_response(token, bl, info, t);
if (ret < 0)
return ret;
- keystone_token_cache->add(token_id, t);
-
ret = update_user_info(store, info, rgw_user);
if (ret < 0)
return ret;
@@ -637,7 +620,7 @@ static int rgw_swift_validate_keystone_token(RGWRados *store, const string& toke
}
-bool rgw_verify_swift_token(RGWRados *store, req_state *s)
+bool RGWSwift::verify_swift_token(RGWRados *store, req_state *s)
{
if (!s->os_auth_token)
return false;
@@ -657,16 +640,16 @@ bool rgw_verify_swift_token(RGWRados *store, req_state *s)
int ret;
if (g_conf->rgw_swift_use_keystone) {
- ret = rgw_swift_validate_keystone_token(store, s->os_auth_token, &info, s->user);
+ ret = validate_keystone_token(store, s->os_auth_token, &info, s->user);
return (ret >= 0);
}
- ret = rgw_swift_validate_token(s->os_auth_token, &info);
+ ret = validate_token(s->os_auth_token, &info);
if (ret < 0)
return ret;
if (info.user.empty()) {
- dout(5) << "swift auth didn't authorize a user" << dendl;
+ ldout(cct, 5) << "swift auth didn't authorize a user" << dendl;
return false;
}
@@ -675,29 +658,82 @@ bool rgw_verify_swift_token(RGWRados *store, req_state *s)
string swift_user = s->swift_user;
- dout(10) << "swift user=" << s->swift_user << dendl;
+ ldout(cct, 10) << "swift user=" << s->swift_user << dendl;
if (rgw_get_user_info_by_swift(store, swift_user, s->user) < 0) {
- dout(0) << "NOTICE: couldn't map swift user" << dendl;
+ ldout(cct, 0) << "NOTICE: couldn't map swift user" << dendl;
return false;
}
- dout(10) << "user_id=" << s->user.user_id << dendl;
+ ldout(cct, 10) << "user_id=" << s->user.user_id << dendl;
return true;
}
-void swift_init(CephContext *cct)
+void RGWSwift::init()
{
get_str_list(cct->_conf->rgw_keystone_operator_roles, roles_list);
- keystone_token_cache = new RGWKeystoneTokenCache(cct->_conf->rgw_keystone_token_cache_size);
+ keystone_token_cache = new RGWKeystoneTokenCache(cct, cct->_conf->rgw_keystone_token_cache_size);
+
+ keystone_revoke_thread = new KeystoneRevokeThread(cct, this);
+ keystone_revoke_thread->create();
}
-void swift_finalize()
+void RGWSwift::finalize()
{
delete keystone_token_cache;
keystone_token_cache = NULL;
+
+ down_flag.set(1);
+ if (keystone_revoke_thread) {
+ keystone_revoke_thread->stop();
+ keystone_revoke_thread->join();
+ }
+ delete keystone_revoke_thread;
+ keystone_revoke_thread = NULL;
+}
+
+RGWSwift *rgw_swift = NULL;
+
+void swift_init(CephContext *cct)
+{
+ rgw_swift = new RGWSwift(cct);
+}
+
+void swift_finalize()
+{
+ delete rgw_swift;
+}
+
+bool RGWSwift::going_down()
+{
+ return (down_flag.read() != 0);
+}
+
+void *RGWSwift::KeystoneRevokeThread::entry() {
+ do {
+ dout(2) << "keystone revoke thread: start" << dendl;
+ int r = swift->check_revoked();
+ if (r < 0) {
+ dout(0) << "ERROR: keystone revocation processing returned error r=" << r << dendl;
+ }
+
+ if (swift->going_down())
+ break;
+
+ lock.Lock();
+ cond.WaitInterval(cct, lock, utime_t(cct->_conf->rgw_keystone_revocation_interval, 0));
+ lock.Unlock();
+ } while (!swift->going_down());
+
+ return NULL;
+}
+
+void RGWSwift::KeystoneRevokeThread::stop()
+{
+ Mutex::Locker l(lock);
+ cond.Signal();
}
diff --git a/src/rgw/rgw_swift.h b/src/rgw/rgw_swift.h
index 80149b62393..bdca5b46283 100644
--- a/src/rgw/rgw_swift.h
+++ b/src/rgw/rgw_swift.h
@@ -3,6 +3,7 @@
#define CEPH_RGW_SWIFT_H
#include "rgw_common.h"
+#include "common/Cond.h"
class RGWRados;
@@ -16,8 +17,69 @@ struct rgw_swift_auth_info {
rgw_swift_auth_info() : status(0), ttl(0) {}
};
-bool rgw_verify_swift_token(RGWRados *store, req_state *s);
+class KeystoneToken {
+public:
+ string tenant_name;
+ string tenant_id;
+ string user_name;
+ time_t expiration;
+ map<string, bool> roles;
+
+ KeystoneToken() {}
+
+ int parse(CephContext *cct, bufferlist& bl);
+
+ bool expired() {
+ uint64_t now = ceph_clock_now(NULL).sec();
+ return (now < (uint64_t)expiration);
+ }
+};
+
+class RGWSwift {
+ CephContext *cct;
+ atomic_t down_flag;
+
+ int validate_token(const char *token, struct rgw_swift_auth_info *info);
+ int validate_keystone_token(RGWRados *store, const string& token, struct rgw_swift_auth_info *info,
+ RGWUserInfo& rgw_user);
+
+ 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);
+
+ class KeystoneRevokeThread : public Thread {
+ CephContext *cct;
+ RGWSwift *swift;
+ Mutex lock;
+ Cond cond;
+
+ public:
+ KeystoneRevokeThread(CephContext *_cct, RGWSwift *_swift) : cct(_cct), swift(_swift), lock("KeystoneRevokeThread") {}
+ void *entry();
+ void stop();
+ };
+
+ KeystoneRevokeThread *keystone_revoke_thread;
+
+ void init();
+ void finalize();
+protected:
+ int check_revoked();
+public:
+
+ RGWSwift(CephContext *_cct) : cct(_cct) {
+ init();
+ }
+ ~RGWSwift() {
+ finalize();
+ }
+
+ bool verify_swift_token(RGWRados *store, req_state *s);
+ bool going_down();
+};
+
+extern RGWSwift *rgw_swift;
void swift_init(CephContext *cct);
void swift_finalize();