]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/rgw_auth_keystone.h
import 15.2.0 Octopus source
[ceph.git] / ceph / src / rgw / rgw_auth_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
FG
3
4
5#ifndef CEPH_RGW_AUTH_KEYSTONE_H
6#define CEPH_RGW_AUTH_KEYSTONE_H
7
8#include <utility>
9#include <boost/optional.hpp>
31f18b77 10#include <boost/utility/string_view.hpp>
7c673cae
FG
11
12#include "rgw_auth.h"
13#include "rgw_rest_s3.h"
14#include "rgw_common.h"
15#include "rgw_keystone.h"
16
17namespace rgw {
18namespace auth {
19namespace keystone {
20
21/* Dedicated namespace for Keystone-related auth engines. We need it because
22 * Keystone offers three different authentication mechanisms (token, EC2 and
23 * regular user/pass). RadosGW actually does support the first two. */
24
25class TokenEngine : public rgw::auth::Engine {
26 CephContext* const cct;
27
28 using acl_strategy_t = rgw::auth::RemoteApplier::acl_strategy_t;
29 using auth_info_t = rgw::auth::RemoteApplier::AuthInfo;
30 using result_t = rgw::auth::Engine::result_t;
31 using token_envelope_t = rgw::keystone::TokenEnvelope;
32
33 const rgw::auth::TokenExtractor* const extractor;
34 const rgw::auth::RemoteApplier::Factory* const apl_factory;
35 rgw::keystone::Config& config;
36 rgw::keystone::TokenCache& token_cache;
37
38 /* Helper methods. */
39 bool is_applicable(const std::string& token) const noexcept;
7c673cae
FG
40
41 boost::optional<token_envelope_t>
11fdf7f2 42 get_from_keystone(const DoutPrefixProvider* dpp, const std::string& token) const;
7c673cae
FG
43
44 acl_strategy_t get_acl_strategy(const token_envelope_t& token) const;
45 auth_info_t get_creds_info(const token_envelope_t& token,
46 const std::vector<std::string>& admin_roles
47 ) const noexcept;
11fdf7f2
TL
48 result_t authenticate(const DoutPrefixProvider* dpp,
49 const std::string& token,
7c673cae
FG
50 const req_state* s) const;
51
52public:
53 TokenEngine(CephContext* const cct,
54 const rgw::auth::TokenExtractor* const extractor,
55 const rgw::auth::RemoteApplier::Factory* const apl_factory,
56 rgw::keystone::Config& config,
57 rgw::keystone::TokenCache& token_cache)
58 : cct(cct),
59 extractor(extractor),
60 apl_factory(apl_factory),
61 config(config),
62 token_cache(token_cache) {
63 }
64
65 const char* get_name() const noexcept override {
66 return "rgw::auth::keystone::TokenEngine";
67 }
68
11fdf7f2
TL
69 result_t authenticate(const DoutPrefixProvider* dpp, const req_state* const s) const override {
70 return authenticate(dpp, extractor->get_token(s), s);
7c673cae
FG
71 }
72}; /* class TokenEngine */
73
9f95a23c
TL
74class SecretCache {
75 using token_envelope_t = rgw::keystone::TokenEnvelope;
76
77 struct secret_entry {
78 token_envelope_t token;
79 std::string secret;
80 utime_t expires;
81 list<std::string>::iterator lru_iter;
82 };
83
84 const boost::intrusive_ptr<CephContext> cct;
85
86 std::map<std::string, secret_entry> secrets;
87 std::list<std::string> secrets_lru;
88
89 std::mutex lock;
90
91 const size_t max;
92
93 const utime_t s3_token_expiry_length;
94
95 SecretCache()
96 : cct(g_ceph_context),
97 lock(),
98 max(cct->_conf->rgw_keystone_token_cache_size),
99 s3_token_expiry_length(300, 0) {
100 }
101
102 ~SecretCache() {}
103
104public:
105 SecretCache(const SecretCache&) = delete;
106 void operator=(const SecretCache&) = delete;
107
108 static SecretCache& get_instance() {
109 /* In C++11 this is thread safe. */
110 static SecretCache instance;
111 return instance;
112 }
113
114 bool find(const std::string& token_id, token_envelope_t& token, std::string& secret);
115 boost::optional<boost::tuple<token_envelope_t, std::string>> find(const std::string& token_id) {
116 token_envelope_t token_envlp;
117 std::string secret;
118 if (find(token_id, token_envlp, secret)) {
119 return boost::make_tuple(token_envlp, secret);
120 }
121 return boost::none;
122 }
123 void add(const std::string& token_id, const token_envelope_t& token, const std::string& secret);
124}; /* class SecretCache */
7c673cae 125
31f18b77 126class EC2Engine : public rgw::auth::s3::AWSEngine {
7c673cae
FG
127 using acl_strategy_t = rgw::auth::RemoteApplier::acl_strategy_t;
128 using auth_info_t = rgw::auth::RemoteApplier::AuthInfo;
129 using result_t = rgw::auth::Engine::result_t;
130 using token_envelope_t = rgw::keystone::TokenEnvelope;
131
132 const rgw::auth::RemoteApplier::Factory* const apl_factory;
133 rgw::keystone::Config& config;
134 rgw::keystone::TokenCache& token_cache;
9f95a23c 135 rgw::auth::keystone::SecretCache& secret_cache;
7c673cae
FG
136
137 /* Helper methods. */
138 acl_strategy_t get_acl_strategy(const token_envelope_t& token) const;
139 auth_info_t get_creds_info(const token_envelope_t& token,
140 const std::vector<std::string>& admin_roles
141 ) const noexcept;
142 std::pair<boost::optional<token_envelope_t>, int>
9f95a23c
TL
143 get_from_keystone(const DoutPrefixProvider* dpp,
144 const boost::string_view& access_key_id,
7c673cae 145 const std::string& string_to_sign,
31f18b77 146 const boost::string_view& signature) const;
9f95a23c
TL
147 std::pair<boost::optional<token_envelope_t>, int>
148 get_access_token(const DoutPrefixProvider* dpp,
149 const boost::string_view& access_key_id,
150 const std::string& string_to_sign,
151 const boost::string_view& signature,
152 const signature_factory_t& signature_factory) const;
11fdf7f2
TL
153 result_t authenticate(const DoutPrefixProvider* dpp,
154 const boost::string_view& access_key_id,
31f18b77 155 const boost::string_view& signature,
11fdf7f2 156 const boost::string_view& session_token,
31f18b77 157 const string_to_sign_t& string_to_sign,
9f95a23c 158 const signature_factory_t& signature_factory,
31f18b77 159 const completer_factory_t& completer_factory,
7c673cae 160 const req_state* s) const override;
9f95a23c
TL
161 std::pair<boost::optional<std::string>, int> get_secret_from_keystone(const DoutPrefixProvider* dpp,
162 const std::string& user_id,
163 const boost::string_view& access_key_id) const;
7c673cae
FG
164public:
165 EC2Engine(CephContext* const cct,
31f18b77 166 const rgw::auth::s3::AWSEngine::VersionAbstractor* const ver_abstractor,
7c673cae
FG
167 const rgw::auth::RemoteApplier::Factory* const apl_factory,
168 rgw::keystone::Config& config,
169 /* The token cache is used ONLY for the retrieving admin token.
170 * Due to the architecture of AWS Auth S3 credentials cannot be
171 * cached at all. */
9f95a23c
TL
172 rgw::keystone::TokenCache& token_cache,
173 rgw::auth::keystone::SecretCache& secret_cache)
31f18b77 174 : AWSEngine(cct, *ver_abstractor),
7c673cae
FG
175 apl_factory(apl_factory),
176 config(config),
9f95a23c
TL
177 token_cache(token_cache),
178 secret_cache(secret_cache) {
7c673cae
FG
179 }
180
31f18b77 181 using AWSEngine::authenticate;
7c673cae
FG
182
183 const char* get_name() const noexcept override {
184 return "rgw::auth::keystone::EC2Engine";
185 }
186
187}; /* class EC2Engine */
188
189}; /* namespace keystone */
190}; /* namespace auth */
191}; /* namespace rgw */
192
193#endif /* CEPH_RGW_AUTH_KEYSTONE_H */