]> git.proxmox.com Git - ceph.git/blame - ceph/src/auth/cephx/CephxKeyServer.h
bump version to 19.2.0-pve1
[ceph.git] / ceph / src / auth / cephx / CephxKeyServer.h
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3/*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2004-2009 Sage Weil <sage@newdream.net>
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14
15#ifndef CEPH_KEYSSERVER_H
16#define CEPH_KEYSSERVER_H
17
18#include "auth/KeyRing.h"
19#include "CephxProtocol.h"
11fdf7f2 20#include "common/ceph_mutex.h"
9f95a23c 21#include "include/common_fwd.h"
7c673cae
FG
22
23struct KeyServerData {
f51cf556 24 version_t version{0};
7c673cae
FG
25
26 /* for each entity */
f67539c2 27 std::map<EntityName, EntityAuth> secrets;
f51cf556 28 KeyRing *extra_secrets = nullptr;
7c673cae
FG
29
30 /* for each service type */
f51cf556 31 version_t rotating_ver{0};
f67539c2 32 std::map<uint32_t, RotatingSecrets> rotating_secrets;
f51cf556 33 KeyServerData() {}
7c673cae
FG
34
35 explicit KeyServerData(KeyRing *extra)
36 : version(0),
37 extra_secrets(extra),
38 rotating_ver(0) {}
39
f67539c2 40 void encode(ceph::buffer::list& bl) const {
7c673cae 41 __u8 struct_v = 1;
11fdf7f2
TL
42 using ceph::encode;
43 encode(struct_v, bl);
44 encode(version, bl);
45 encode(rotating_ver, bl);
46 encode(secrets, bl);
47 encode(rotating_secrets, bl);
7c673cae 48 }
f67539c2 49 void decode(ceph::buffer::list::const_iterator& bl) {
11fdf7f2 50 using ceph::decode;
7c673cae 51 __u8 struct_v;
11fdf7f2
TL
52 decode(struct_v, bl);
53 decode(version, bl);
54 decode(rotating_ver, bl);
55 decode(secrets, bl);
56 decode(rotating_secrets, bl);
7c673cae
FG
57 }
58
f67539c2 59 void encode_rotating(ceph::buffer::list& bl) const {
11fdf7f2 60 using ceph::encode;
7c673cae 61 __u8 struct_v = 1;
11fdf7f2
TL
62 encode(struct_v, bl);
63 encode(rotating_ver, bl);
64 encode(rotating_secrets, bl);
7c673cae 65 }
f67539c2 66 void decode_rotating(ceph::buffer::list& rotating_bl) {
11fdf7f2
TL
67 using ceph::decode;
68 auto iter = rotating_bl.cbegin();
7c673cae 69 __u8 struct_v;
11fdf7f2
TL
70 decode(struct_v, iter);
71 decode(rotating_ver, iter);
72 decode(rotating_secrets, iter);
7c673cae 73 }
f51cf556
TL
74 void dump(ceph::Formatter *f) const {
75 f->dump_unsigned("version", version);
76 f->dump_unsigned("rotating_version", rotating_ver);
77 encode_json("secrets", secrets, f);
78 encode_json("rotating_secrets", rotating_secrets, f);
79 }
80 static void generate_test_instances(std::list<KeyServerData*>& ls) {
81 ls.push_back(new KeyServerData);
82 ls.push_back(new KeyServerData);
83 ls.back()->version = 1;
84 }
7c673cae
FG
85 bool contains(const EntityName& name) const {
86 return (secrets.find(name) != secrets.end());
87 }
88
89 void clear_secrets() {
494da23a 90 version = 0;
7c673cae 91 secrets.clear();
494da23a
TL
92 rotating_ver = 0;
93 rotating_secrets.clear();
7c673cae
FG
94 }
95
96 void add_auth(const EntityName& name, EntityAuth& auth) {
97 secrets[name] = auth;
98 }
99
100 void remove_secret(const EntityName& name) {
f67539c2 101 auto iter = secrets.find(name);
7c673cae
FG
102 if (iter == secrets.end())
103 return;
104 secrets.erase(iter);
105 }
106
107 bool get_service_secret(CephContext *cct, uint32_t service_id,
c5c27e9a
TL
108 CryptoKey& secret, uint64_t& secret_id,
109 double& ttl) const;
7c673cae
FG
110 bool get_service_secret(CephContext *cct, uint32_t service_id,
111 uint64_t secret_id, CryptoKey& secret) const;
112 bool get_auth(const EntityName& name, EntityAuth& auth) const;
113 bool get_secret(const EntityName& name, CryptoKey& secret) const;
114 bool get_caps(CephContext *cct, const EntityName& name,
115 const std::string& type, AuthCapsInfo& caps) const;
116
f67539c2 117 std::map<EntityName, EntityAuth>::iterator secrets_begin()
7c673cae 118 { return secrets.begin(); }
f67539c2 119 std::map<EntityName, EntityAuth>::const_iterator secrets_begin() const
7c673cae 120 { return secrets.begin(); }
f67539c2 121 std::map<EntityName, EntityAuth>::iterator secrets_end()
7c673cae 122 { return secrets.end(); }
f67539c2 123 std::map<EntityName, EntityAuth>::const_iterator secrets_end() const
7c673cae 124 { return secrets.end(); }
f67539c2 125 std::map<EntityName, EntityAuth>::iterator find_name(const EntityName& name)
7c673cae 126 { return secrets.find(name); }
f67539c2 127 std::map<EntityName, EntityAuth>::const_iterator find_name(const EntityName& name) const
7c673cae
FG
128 { return secrets.find(name); }
129
130
131 // -- incremental updates --
132 typedef enum {
133 AUTH_INC_NOP,
134 AUTH_INC_ADD,
135 AUTH_INC_DEL,
136 AUTH_INC_SET_ROTATING,
137 } IncrementalOp;
138
139 struct Incremental {
140 IncrementalOp op;
f67539c2 141 ceph::buffer::list rotating_bl; // if SET_ROTATING. otherwise,
7c673cae
FG
142 EntityName name;
143 EntityAuth auth;
f67539c2
TL
144
145 void encode(ceph::buffer::list& bl) const {
11fdf7f2 146 using ceph::encode;
7c673cae 147 __u8 struct_v = 1;
11fdf7f2 148 encode(struct_v, bl);
7c673cae 149 __u32 _op = (__u32)op;
11fdf7f2 150 encode(_op, bl);
7c673cae 151 if (op == AUTH_INC_SET_ROTATING) {
11fdf7f2 152 encode(rotating_bl, bl);
7c673cae 153 } else {
11fdf7f2
TL
154 encode(name, bl);
155 encode(auth, bl);
7c673cae
FG
156 }
157 }
f67539c2 158 void decode(ceph::buffer::list::const_iterator& bl) {
11fdf7f2 159 using ceph::decode;
7c673cae 160 __u8 struct_v;
11fdf7f2 161 decode(struct_v, bl);
7c673cae 162 __u32 _op;
11fdf7f2 163 decode(_op, bl);
7c673cae 164 op = (IncrementalOp)_op;
11fdf7f2 165 ceph_assert(op >= AUTH_INC_NOP && op <= AUTH_INC_SET_ROTATING);
7c673cae 166 if (op == AUTH_INC_SET_ROTATING) {
11fdf7f2 167 decode(rotating_bl, bl);
7c673cae 168 } else {
11fdf7f2
TL
169 decode(name, bl);
170 decode(auth, bl);
7c673cae
FG
171 }
172 }
f51cf556
TL
173 void dump(ceph::Formatter *f) const {
174 f->dump_unsigned("op", op);
175 f->dump_object("name", name);
176 f->dump_object("auth", auth);
177 }
178 static void generate_test_instances(std::list<Incremental*>& ls) {
179 ls.push_back(new Incremental);
180 ls.back()->op = AUTH_INC_DEL;
181 ls.push_back(new Incremental);
182 ls.back()->op = AUTH_INC_ADD;
183 ls.push_back(new Incremental);
184 ls.back()->op = AUTH_INC_SET_ROTATING;
185 }
7c673cae 186 };
f51cf556 187
7c673cae
FG
188 void apply_incremental(Incremental& inc) {
189 switch (inc.op) {
190 case AUTH_INC_ADD:
191 add_auth(inc.name, inc.auth);
192 break;
193
194 case AUTH_INC_DEL:
195 remove_secret(inc.name);
196 break;
197
198 case AUTH_INC_SET_ROTATING:
199 decode_rotating(inc.rotating_bl);
200 break;
201
202 case AUTH_INC_NOP:
203 break;
204
205 default:
206 ceph_abort();
207 }
208 }
209
210};
211WRITE_CLASS_ENCODER(KeyServerData)
212WRITE_CLASS_ENCODER(KeyServerData::Incremental)
213
214
7c673cae
FG
215class KeyServer : public KeyStore {
216 CephContext *cct;
217 KeyServerData data;
39ae355f 218 std::map<EntityName, CryptoKey> used_pending_keys;
11fdf7f2 219 mutable ceph::mutex lock;
7c673cae 220
a4b75251 221 int _rotate_secret(uint32_t service_id, KeyServerData &pending_data);
7c673cae
FG
222 void _dump_rotating_secrets();
223 int _build_session_auth_info(uint32_t service_id,
11fdf7f2 224 const AuthTicket& parent_ticket,
c5c27e9a
TL
225 CephXSessionAuthInfo& info,
226 double ttl);
7c673cae
FG
227 bool _get_service_caps(const EntityName& name, uint32_t service_id,
228 AuthCapsInfo& caps) const;
229public:
f51cf556 230 KeyServer() : lock{ceph::make_mutex("KeyServer::lock")} {}
7c673cae 231 KeyServer(CephContext *cct_, KeyRing *extra_secrets);
f51cf556 232 KeyServer& operator=(const KeyServer&) = delete;
7c673cae
FG
233 bool generate_secret(CryptoKey& secret);
234
235 bool get_secret(const EntityName& name, CryptoKey& secret) const override;
236 bool get_auth(const EntityName& name, EntityAuth& auth) const;
f67539c2 237 bool get_caps(const EntityName& name, const std::string& type, AuthCapsInfo& caps) const;
7c673cae 238 bool get_active_rotating_secret(const EntityName& name, CryptoKey& secret) const;
39ae355f
TL
239
240 void note_used_pending_key(const EntityName& name, const CryptoKey& key);
241 void clear_used_pending_keys();
242 std::map<EntityName,CryptoKey> get_used_pending_keys();
243
7c673cae
FG
244 int start_server();
245 void rotate_timeout(double timeout);
246
a4b75251
TL
247 void dump();
248
11fdf7f2
TL
249 int build_session_auth_info(uint32_t service_id,
250 const AuthTicket& parent_ticket,
251 CephXSessionAuthInfo& info);
252 int build_session_auth_info(uint32_t service_id,
253 const AuthTicket& parent_ticket,
c5c27e9a
TL
254 const CryptoKey& service_secret,
255 uint64_t secret_id,
256 CephXSessionAuthInfo& info);
7c673cae
FG
257
258 /* get current secret for specific service type */
c5c27e9a
TL
259 bool get_service_secret(uint32_t service_id, CryptoKey& secret,
260 uint64_t& secret_id, double& ttl) const;
7c673cae
FG
261 bool get_service_secret(uint32_t service_id, uint64_t secret_id,
262 CryptoKey& secret) const override;
263
264 bool generate_secret(EntityName& name, CryptoKey& secret);
265
f67539c2 266 void encode(ceph::buffer::list& bl) const {
11fdf7f2
TL
267 using ceph::encode;
268 encode(data, bl);
7c673cae 269 }
f67539c2 270 void decode(ceph::buffer::list::const_iterator& bl) {
11fdf7f2
TL
271 std::scoped_lock l{lock};
272 using ceph::decode;
273 decode(data, bl);
7c673cae 274 }
f51cf556
TL
275 void dump(ceph::Formatter *f) const;
276 static void generate_test_instances(std::list<KeyServer*>& ls);
7c673cae 277 bool contains(const EntityName& name) const;
f67539c2
TL
278 int encode_secrets(ceph::Formatter *f, std::stringstream *ds) const;
279 void encode_formatted(std::string label, ceph::Formatter *f, ceph::buffer::list &bl);
280 void encode_plaintext(ceph::buffer::list &bl);
281 int list_secrets(std::stringstream& ds) const {
7c673cae
FG
282 return encode_secrets(NULL, &ds);
283 }
284 version_t get_ver() const {
11fdf7f2 285 std::scoped_lock l{lock};
f67539c2 286 return data.version;
7c673cae
FG
287 }
288
289 void clear_secrets() {
11fdf7f2 290 std::scoped_lock l{lock};
7c673cae
FG
291 data.clear_secrets();
292 }
293
294 void apply_data_incremental(KeyServerData::Incremental& inc) {
11fdf7f2 295 std::scoped_lock l{lock};
7c673cae
FG
296 data.apply_incremental(inc);
297 }
298 void set_ver(version_t ver) {
11fdf7f2 299 std::scoped_lock l{lock};
7c673cae
FG
300 data.version = ver;
301 }
302
303 void add_auth(const EntityName& name, EntityAuth& auth) {
11fdf7f2 304 std::scoped_lock l{lock};
7c673cae
FG
305 data.add_auth(name, auth);
306 }
307
308 void remove_secret(const EntityName& name) {
11fdf7f2 309 std::scoped_lock l{lock};
7c673cae
FG
310 data.remove_secret(name);
311 }
312
313 bool has_secrets() {
f67539c2 314 auto b = data.secrets_begin();
7c673cae
FG
315 return (b != data.secrets_end());
316 }
317 int get_num_secrets() {
11fdf7f2 318 std::scoped_lock l{lock};
7c673cae
FG
319 return data.secrets.size();
320 }
321
322 void clone_to(KeyServerData& dst) const {
11fdf7f2 323 std::scoped_lock l{lock};
7c673cae
FG
324 dst = data;
325 }
326 void export_keyring(KeyRing& keyring) {
11fdf7f2 327 std::scoped_lock l{lock};
f67539c2 328 for (auto p = data.secrets.begin(); p != data.secrets.end(); ++p) {
7c673cae
FG
329 keyring.add(p->first, p->second);
330 }
331 }
332
a4b75251 333 bool prepare_rotating_update(ceph::buffer::list& rotating_bl);
7c673cae 334
f67539c2 335 bool get_rotating_encrypted(const EntityName& name, ceph::buffer::list& enc_bl) const;
7c673cae 336
11fdf7f2 337 ceph::mutex& get_lock() const { return lock; }
7c673cae
FG
338 bool get_service_caps(const EntityName& name, uint32_t service_id,
339 AuthCapsInfo& caps) const;
340
f67539c2 341 std::map<EntityName, EntityAuth>::iterator secrets_begin()
7c673cae 342 { return data.secrets_begin(); }
f67539c2 343 std::map<EntityName, EntityAuth>::iterator secrets_end()
7c673cae
FG
344 { return data.secrets_end(); }
345};
346WRITE_CLASS_ENCODER(KeyServer)
347
348
349#endif