]> git.proxmox.com Git - ceph.git/blob - ceph/src/auth/cephx/CephxKeyServer.h
import 15.2.0 Octopus source
[ceph.git] / ceph / src / auth / cephx / CephxKeyServer.h
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"
20 #include "CephxKeyServer.h"
21 #include "common/ceph_mutex.h"
22 #include "include/common_fwd.h"
23
24 struct KeyServerData {
25 version_t version;
26
27 /* for each entity */
28 map<EntityName, EntityAuth> secrets;
29 KeyRing *extra_secrets;
30
31 /* for each service type */
32 version_t rotating_ver;
33 map<uint32_t, RotatingSecrets> rotating_secrets;
34
35 explicit KeyServerData(KeyRing *extra)
36 : version(0),
37 extra_secrets(extra),
38 rotating_ver(0) {}
39
40 void encode(bufferlist& bl) const {
41 __u8 struct_v = 1;
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);
48 }
49 void decode(bufferlist::const_iterator& bl) {
50 using ceph::decode;
51 __u8 struct_v;
52 decode(struct_v, bl);
53 decode(version, bl);
54 decode(rotating_ver, bl);
55 decode(secrets, bl);
56 decode(rotating_secrets, bl);
57 }
58
59 void encode_rotating(bufferlist& bl) const {
60 using ceph::encode;
61 __u8 struct_v = 1;
62 encode(struct_v, bl);
63 encode(rotating_ver, bl);
64 encode(rotating_secrets, bl);
65 }
66 void decode_rotating(bufferlist& rotating_bl) {
67 using ceph::decode;
68 auto iter = rotating_bl.cbegin();
69 __u8 struct_v;
70 decode(struct_v, iter);
71 decode(rotating_ver, iter);
72 decode(rotating_secrets, iter);
73 }
74
75 bool contains(const EntityName& name) const {
76 return (secrets.find(name) != secrets.end());
77 }
78
79 void clear_secrets() {
80 version = 0;
81 secrets.clear();
82 rotating_ver = 0;
83 rotating_secrets.clear();
84 }
85
86 void add_auth(const EntityName& name, EntityAuth& auth) {
87 secrets[name] = auth;
88 }
89
90 void remove_secret(const EntityName& name) {
91 map<EntityName, EntityAuth>::iterator iter = secrets.find(name);
92 if (iter == secrets.end())
93 return;
94 secrets.erase(iter);
95 }
96
97 bool get_service_secret(CephContext *cct, uint32_t service_id,
98 ExpiringCryptoKey& secret, uint64_t& secret_id) const;
99 bool get_service_secret(CephContext *cct, uint32_t service_id,
100 CryptoKey& secret, uint64_t& secret_id) const;
101 bool get_service_secret(CephContext *cct, uint32_t service_id,
102 uint64_t secret_id, CryptoKey& secret) const;
103 bool get_auth(const EntityName& name, EntityAuth& auth) const;
104 bool get_secret(const EntityName& name, CryptoKey& secret) const;
105 bool get_caps(CephContext *cct, const EntityName& name,
106 const std::string& type, AuthCapsInfo& caps) const;
107
108 map<EntityName, EntityAuth>::iterator secrets_begin()
109 { return secrets.begin(); }
110 map<EntityName, EntityAuth>::const_iterator secrets_begin() const
111 { return secrets.begin(); }
112 map<EntityName, EntityAuth>::iterator secrets_end()
113 { return secrets.end(); }
114 map<EntityName, EntityAuth>::const_iterator secrets_end() const
115 { return secrets.end(); }
116 map<EntityName, EntityAuth>::iterator find_name(const EntityName& name)
117 { return secrets.find(name); }
118 map<EntityName, EntityAuth>::const_iterator find_name(const EntityName& name) const
119 { return secrets.find(name); }
120
121
122 // -- incremental updates --
123 typedef enum {
124 AUTH_INC_NOP,
125 AUTH_INC_ADD,
126 AUTH_INC_DEL,
127 AUTH_INC_SET_ROTATING,
128 } IncrementalOp;
129
130 struct Incremental {
131 IncrementalOp op;
132 bufferlist rotating_bl; // if SET_ROTATING. otherwise,
133 EntityName name;
134 EntityAuth auth;
135
136 void encode(bufferlist& bl) const {
137 using ceph::encode;
138 __u8 struct_v = 1;
139 encode(struct_v, bl);
140 __u32 _op = (__u32)op;
141 encode(_op, bl);
142 if (op == AUTH_INC_SET_ROTATING) {
143 encode(rotating_bl, bl);
144 } else {
145 encode(name, bl);
146 encode(auth, bl);
147 }
148 }
149 void decode(bufferlist::const_iterator& bl) {
150 using ceph::decode;
151 __u8 struct_v;
152 decode(struct_v, bl);
153 __u32 _op;
154 decode(_op, bl);
155 op = (IncrementalOp)_op;
156 ceph_assert(op >= AUTH_INC_NOP && op <= AUTH_INC_SET_ROTATING);
157 if (op == AUTH_INC_SET_ROTATING) {
158 decode(rotating_bl, bl);
159 } else {
160 decode(name, bl);
161 decode(auth, bl);
162 }
163 }
164 };
165
166 void apply_incremental(Incremental& inc) {
167 switch (inc.op) {
168 case AUTH_INC_ADD:
169 add_auth(inc.name, inc.auth);
170 break;
171
172 case AUTH_INC_DEL:
173 remove_secret(inc.name);
174 break;
175
176 case AUTH_INC_SET_ROTATING:
177 decode_rotating(inc.rotating_bl);
178 break;
179
180 case AUTH_INC_NOP:
181 break;
182
183 default:
184 ceph_abort();
185 }
186 }
187
188 };
189 WRITE_CLASS_ENCODER(KeyServerData)
190 WRITE_CLASS_ENCODER(KeyServerData::Incremental)
191
192
193
194
195 class KeyServer : public KeyStore {
196 CephContext *cct;
197 KeyServerData data;
198 mutable ceph::mutex lock;
199
200 int _rotate_secret(uint32_t service_id);
201 bool _check_rotating_secrets();
202 void _dump_rotating_secrets();
203 int _build_session_auth_info(uint32_t service_id,
204 const AuthTicket& parent_ticket,
205 CephXSessionAuthInfo& info);
206 bool _get_service_caps(const EntityName& name, uint32_t service_id,
207 AuthCapsInfo& caps) const;
208 public:
209 KeyServer(CephContext *cct_, KeyRing *extra_secrets);
210 bool generate_secret(CryptoKey& secret);
211
212 bool get_secret(const EntityName& name, CryptoKey& secret) const override;
213 bool get_auth(const EntityName& name, EntityAuth& auth) const;
214 bool get_caps(const EntityName& name, const string& type, AuthCapsInfo& caps) const;
215 bool get_active_rotating_secret(const EntityName& name, CryptoKey& secret) const;
216 int start_server();
217 void rotate_timeout(double timeout);
218
219 int build_session_auth_info(uint32_t service_id,
220 const AuthTicket& parent_ticket,
221 CephXSessionAuthInfo& info);
222 int build_session_auth_info(uint32_t service_id,
223 const AuthTicket& parent_ticket,
224 CephXSessionAuthInfo& info,
225 CryptoKey& service_secret,
226 uint64_t secret_id);
227
228 /* get current secret for specific service type */
229 bool get_service_secret(uint32_t service_id, CryptoKey& service_key,
230 uint64_t& secret_id) const;
231 bool get_service_secret(uint32_t service_id, uint64_t secret_id,
232 CryptoKey& secret) const override;
233
234 bool generate_secret(EntityName& name, CryptoKey& secret);
235
236 void encode(bufferlist& bl) const {
237 using ceph::encode;
238 encode(data, bl);
239 }
240 void decode(bufferlist::const_iterator& bl) {
241 std::scoped_lock l{lock};
242 using ceph::decode;
243 decode(data, bl);
244 }
245 bool contains(const EntityName& name) const;
246 int encode_secrets(Formatter *f, stringstream *ds) const;
247 void encode_formatted(string label, Formatter *f, bufferlist &bl);
248 void encode_plaintext(bufferlist &bl);
249 int list_secrets(stringstream& ds) const {
250 return encode_secrets(NULL, &ds);
251 }
252 version_t get_ver() const {
253 std::scoped_lock l{lock};
254 return data.version;
255 }
256
257 void clear_secrets() {
258 std::scoped_lock l{lock};
259 data.clear_secrets();
260 }
261
262 void apply_data_incremental(KeyServerData::Incremental& inc) {
263 std::scoped_lock l{lock};
264 data.apply_incremental(inc);
265 }
266 void set_ver(version_t ver) {
267 std::scoped_lock l{lock};
268 data.version = ver;
269 }
270
271 void add_auth(const EntityName& name, EntityAuth& auth) {
272 std::scoped_lock l{lock};
273 data.add_auth(name, auth);
274 }
275
276 void remove_secret(const EntityName& name) {
277 std::scoped_lock l{lock};
278 data.remove_secret(name);
279 }
280
281 bool has_secrets() {
282 map<EntityName, EntityAuth>::const_iterator b = data.secrets_begin();
283 return (b != data.secrets_end());
284 }
285 int get_num_secrets() {
286 std::scoped_lock l{lock};
287 return data.secrets.size();
288 }
289
290 void clone_to(KeyServerData& dst) const {
291 std::scoped_lock l{lock};
292 dst = data;
293 }
294 void export_keyring(KeyRing& keyring) {
295 std::scoped_lock l{lock};
296 for (map<EntityName, EntityAuth>::iterator p = data.secrets.begin();
297 p != data.secrets.end();
298 ++p) {
299 keyring.add(p->first, p->second);
300 }
301 }
302
303 bool updated_rotating(bufferlist& rotating_bl, version_t& rotating_ver);
304
305 bool get_rotating_encrypted(const EntityName& name, bufferlist& enc_bl) const;
306
307 ceph::mutex& get_lock() const { return lock; }
308 bool get_service_caps(const EntityName& name, uint32_t service_id,
309 AuthCapsInfo& caps) const;
310
311 map<EntityName, EntityAuth>::iterator secrets_begin()
312 { return data.secrets_begin(); }
313 map<EntityName, EntityAuth>::iterator secrets_end()
314 { return data.secrets_end(); }
315 };
316 WRITE_CLASS_ENCODER(KeyServer)
317
318
319 #endif