]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/rgw_keystone.h
bump version to 18.2.4-pve3
[ceph.git] / ceph / src / rgw / rgw_keystone.h
CommitLineData
7c673cae 1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
9f95a23c 2// vim: ts=8 sw=2 smarttab ft=cpp
7c673cae 3
1e59de90 4#pragma once
7c673cae 5
1e59de90 6#include <atomic>
f67539c2 7#include <string_view>
1e59de90
TL
8#include <type_traits>
9#include <utility>
7c673cae
FG
10
11#include <boost/optional.hpp>
7c673cae
FG
12
13#include "rgw_common.h"
14#include "rgw_http_client.h"
9f95a23c 15#include "common/ceph_mutex.h"
c07f9fc5 16#include "global/global_init.h"
7c673cae 17
7c673cae 18
20effc67
TL
19bool rgw_is_pki_token(const std::string& token);
20void rgw_get_token_id(const std::string& token, std::string& token_id);
21static inline std::string rgw_get_token_id(const std::string& token)
7c673cae
FG
22{
23 std::string token_id;
24 rgw_get_token_id(token, token_id);
25
26 return token_id;
27}
7c673cae
FG
28
29namespace rgw {
30namespace keystone {
31
32enum class ApiVersion {
33 VER_2,
34 VER_3
35};
36
37
38class Config {
39protected:
40 Config() = default;
41 virtual ~Config() = default;
42
43public:
44 virtual std::string get_endpoint_url() const noexcept = 0;
45 virtual ApiVersion get_api_version() const noexcept = 0;
46
11fdf7f2 47 virtual std::string get_admin_token() const noexcept = 0;
f67539c2 48 virtual std::string_view get_admin_user() const noexcept = 0;
11fdf7f2 49 virtual std::string get_admin_password() const noexcept = 0;
f67539c2
TL
50 virtual std::string_view get_admin_tenant() const noexcept = 0;
51 virtual std::string_view get_admin_project() const noexcept = 0;
52 virtual std::string_view get_admin_domain() const noexcept = 0;
7c673cae
FG
53};
54
55class CephCtxConfig : public Config {
56protected:
57 CephCtxConfig() = default;
58 virtual ~CephCtxConfig() = default;
59
11fdf7f2
TL
60 const static std::string empty;
61
7c673cae
FG
62public:
63 static CephCtxConfig& get_instance() {
64 static CephCtxConfig instance;
65 return instance;
66 }
67
68 std::string get_endpoint_url() const noexcept override;
69 ApiVersion get_api_version() const noexcept override;
70
11fdf7f2 71 std::string get_admin_token() const noexcept override;
7c673cae 72
f67539c2 73 std::string_view get_admin_user() const noexcept override {
7c673cae
FG
74 return g_ceph_context->_conf->rgw_keystone_admin_user;
75 }
76
11fdf7f2 77 std::string get_admin_password() const noexcept override;
7c673cae 78
f67539c2 79 std::string_view get_admin_tenant() const noexcept override {
7c673cae
FG
80 return g_ceph_context->_conf->rgw_keystone_admin_tenant;
81 }
82
f67539c2 83 std::string_view get_admin_project() const noexcept override {
7c673cae
FG
84 return g_ceph_context->_conf->rgw_keystone_admin_project;
85 }
86
f67539c2 87 std::string_view get_admin_domain() const noexcept override {
7c673cae
FG
88 return g_ceph_context->_conf->rgw_keystone_admin_domain;
89 }
90};
91
92
93class TokenEnvelope;
94class TokenCache;
95
96class Service {
97public:
98 class RGWKeystoneHTTPTransceiver : public RGWHTTPTransceiver {
99 public:
100 RGWKeystoneHTTPTransceiver(CephContext * const cct,
20effc67
TL
101 const std::string& method,
102 const std::string& url,
7c673cae 103 bufferlist * const token_body_bl)
11fdf7f2 104 : RGWHTTPTransceiver(cct, method, url, token_body_bl,
7c673cae
FG
105 cct->_conf->rgw_keystone_verify_ssl,
106 { "X-Subject-Token" }) {
107 }
108
109 const header_value_t& get_subject_token() const {
110 try {
111 return get_header_value("X-Subject-Token");
112 } catch (std::out_of_range&) {
113 static header_value_t empty_val;
114 return empty_val;
115 }
116 }
117 };
118
119 typedef RGWKeystoneHTTPTransceiver RGWValidateKeystoneToken;
120 typedef RGWKeystoneHTTPTransceiver RGWGetKeystoneAdminToken;
7c673cae 121
20effc67
TL
122 static int get_admin_token(const DoutPrefixProvider *dpp,
123 CephContext* const cct,
7c673cae
FG
124 TokenCache& token_cache,
125 const Config& config,
126 std::string& token);
20effc67
TL
127 static int issue_admin_token_request(const DoutPrefixProvider *dpp,
128 CephContext* const cct,
7c673cae
FG
129 const Config& config,
130 TokenEnvelope& token);
20effc67
TL
131 static int get_keystone_barbican_token(const DoutPrefixProvider *dpp,
132 CephContext * const cct,
7c673cae
FG
133 std::string& token);
134};
135
136
137class TokenEnvelope {
138public:
139 class Domain {
140 public:
20effc67
TL
141 std::string id;
142 std::string name;
7c673cae
FG
143 void decode_json(JSONObj *obj);
144 };
145 class Project {
146 public:
147 Domain domain;
20effc67
TL
148 std::string id;
149 std::string name;
7c673cae
FG
150 void decode_json(JSONObj *obj);
151 };
152
153 class Token {
154 public:
155 Token() : expires(0) { }
20effc67 156 std::string id;
7c673cae
FG
157 time_t expires;
158 Project tenant_v2;
159 void decode_json(JSONObj *obj);
160 };
161
162 class Role {
163 public:
20effc67
TL
164 std::string id;
165 std::string name;
7c673cae
FG
166 void decode_json(JSONObj *obj);
167 };
168
169 class User {
170 public:
20effc67
TL
171 std::string id;
172 std::string name;
7c673cae 173 Domain domain;
20effc67 174 std::list<Role> roles_v2;
7c673cae
FG
175 void decode_json(JSONObj *obj);
176 };
177
178 Token token;
179 Project project;
180 User user;
20effc67 181 std::list<Role> roles;
7c673cae
FG
182
183 void decode_v3(JSONObj* obj);
184 void decode_v2(JSONObj* obj);
185
186public:
187 /* We really need the default ctor because of the internals of TokenCache. */
188 TokenEnvelope() = default;
189
1e59de90 190 void set_expires(time_t expires) { token.expires = expires; }
7c673cae
FG
191 time_t get_expires() const { return token.expires; }
192 const std::string& get_domain_id() const {return project.domain.id;};
193 const std::string& get_domain_name() const {return project.domain.name;};
194 const std::string& get_project_id() const {return project.id;};
195 const std::string& get_project_name() const {return project.name;};
196 const std::string& get_user_id() const {return user.id;};
197 const std::string& get_user_name() const {return user.name;};
20effc67 198 bool has_role(const std::string& r) const;
7c673cae
FG
199 bool expired() const {
200 const uint64_t now = ceph_clock_now().sec();
1e59de90 201 return std::cmp_greater_equal(now, get_expires());
7c673cae 202 }
20effc67 203 int parse(const DoutPrefixProvider *dpp, CephContext* cct,
7c673cae
FG
204 const std::string& token_str,
205 ceph::buffer::list& bl /* in */,
206 ApiVersion version);
207};
208
209
210class TokenCache {
211 struct token_entry {
212 TokenEnvelope token;
20effc67 213 std::list<std::string>::iterator lru_iter;
7c673cae
FG
214 };
215
216 std::atomic<bool> down_flag = { false };
c07f9fc5 217 const boost::intrusive_ptr<CephContext> cct;
7c673cae
FG
218
219 std::string admin_token_id;
220 std::string barbican_token_id;
221 std::map<std::string, token_entry> tokens;
1e59de90 222 std::map<std::string, token_entry> service_tokens;
7c673cae 223 std::list<std::string> tokens_lru;
1e59de90 224 std::list<std::string> service_tokens_lru;
7c673cae 225
9f95a23c 226 ceph::mutex lock = ceph::make_mutex("rgw::keystone::TokenCache");
7c673cae
FG
227
228 const size_t max;
229
11fdf7f2 230 explicit TokenCache(const rgw::keystone::Config& config)
9f95a23c 231 : cct(g_ceph_context),
7c673cae 232 max(cct->_conf->rgw_keystone_token_cache_size) {
7c673cae
FG
233 }
234
235 ~TokenCache() {
236 down_flag = true;
7c673cae
FG
237 }
238
239public:
240 TokenCache(const TokenCache&) = delete;
241 void operator=(const TokenCache&) = delete;
242
243 template<class ConfigT>
244 static TokenCache& get_instance() {
245 static_assert(std::is_base_of<rgw::keystone::Config, ConfigT>::value,
246 "ConfigT must be a subclass of rgw::keystone::Config");
247
248 /* In C++11 this is thread safe. */
249 static TokenCache instance(ConfigT::get_instance());
250 return instance;
251 }
252
253 bool find(const std::string& token_id, TokenEnvelope& token);
1e59de90 254 bool find_service(const std::string& token_id, TokenEnvelope& token);
7c673cae
FG
255 boost::optional<TokenEnvelope> find(const std::string& token_id) {
256 TokenEnvelope token_envlp;
257 if (find(token_id, token_envlp)) {
258 return token_envlp;
259 }
260 return boost::none;
261 }
1e59de90
TL
262 boost::optional<TokenEnvelope> find_service(const std::string& token_id) {
263 TokenEnvelope token_envlp;
264 if (find_service(token_id, token_envlp)) {
265 return token_envlp;
266 }
267 return boost::none;
268 }
7c673cae
FG
269 bool find_admin(TokenEnvelope& token);
270 bool find_barbican(TokenEnvelope& token);
271 void add(const std::string& token_id, const TokenEnvelope& token);
1e59de90 272 void add_service(const std::string& token_id, const TokenEnvelope& token);
7c673cae
FG
273 void add_admin(const TokenEnvelope& token);
274 void add_barbican(const TokenEnvelope& token);
20effc67 275 void invalidate(const DoutPrefixProvider *dpp, const std::string& token_id);
7c673cae
FG
276 bool going_down() const;
277private:
1e59de90
TL
278 void add_locked(const std::string& token_id, const TokenEnvelope& token,
279 std::map<std::string, token_entry>& tokens, std::list<std::string>& tokens_lru);
280 bool find_locked(const std::string& token_id, TokenEnvelope& token,
281 std::map<std::string, token_entry>& tokens, std::list<std::string>& tokens_lru);
7c673cae
FG
282};
283
284
285class AdminTokenRequest {
286public:
287 virtual ~AdminTokenRequest() = default;
288 virtual void dump(Formatter* f) const = 0;
289};
290
291class AdminTokenRequestVer2 : public AdminTokenRequest {
292 const Config& conf;
293
294public:
11fdf7f2 295 explicit AdminTokenRequestVer2(const Config& conf)
7c673cae
FG
296 : conf(conf) {
297 }
298 void dump(Formatter *f) const override;
299};
300
301class AdminTokenRequestVer3 : public AdminTokenRequest {
302 const Config& conf;
303
304public:
11fdf7f2 305 explicit AdminTokenRequestVer3(const Config& conf)
7c673cae
FG
306 : conf(conf) {
307 }
308 void dump(Formatter *f) const override;
309};
310
311class BarbicanTokenRequestVer2 : public AdminTokenRequest {
312 CephContext *cct;
313
314public:
11fdf7f2 315 explicit BarbicanTokenRequestVer2(CephContext * const _cct)
7c673cae
FG
316 : cct(_cct) {
317 }
11fdf7f2 318 void dump(Formatter *f) const override;
7c673cae
FG
319};
320
321class BarbicanTokenRequestVer3 : public AdminTokenRequest {
322 CephContext *cct;
323
324public:
11fdf7f2 325 explicit BarbicanTokenRequestVer3(CephContext * const _cct)
7c673cae
FG
326 : cct(_cct) {
327 }
11fdf7f2 328 void dump(Formatter *f) const override;
7c673cae
FG
329};
330
331
332}; /* namespace keystone */
333}; /* namespace rgw */