]> git.proxmox.com Git - ceph.git/blob - ceph/src/auth/cephx/CephxKeyServer.h
945a7f4dcd8979f64643e6924173c22104c5d687
[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 "common/ceph_mutex.h"
21 #include "include/common_fwd.h"
22
23 struct KeyServerData {
24 version_t version;
25
26 /* for each entity */
27 std::map<EntityName, EntityAuth> secrets;
28 KeyRing *extra_secrets;
29
30 /* for each service type */
31 version_t rotating_ver;
32 std::map<uint32_t, RotatingSecrets> rotating_secrets;
33
34 explicit KeyServerData(KeyRing *extra)
35 : version(0),
36 extra_secrets(extra),
37 rotating_ver(0) {}
38
39 void encode(ceph::buffer::list& bl) const {
40 __u8 struct_v = 1;
41 using ceph::encode;
42 encode(struct_v, bl);
43 encode(version, bl);
44 encode(rotating_ver, bl);
45 encode(secrets, bl);
46 encode(rotating_secrets, bl);
47 }
48 void decode(ceph::buffer::list::const_iterator& bl) {
49 using ceph::decode;
50 __u8 struct_v;
51 decode(struct_v, bl);
52 decode(version, bl);
53 decode(rotating_ver, bl);
54 decode(secrets, bl);
55 decode(rotating_secrets, bl);
56 }
57
58 void encode_rotating(ceph::buffer::list& bl) const {
59 using ceph::encode;
60 __u8 struct_v = 1;
61 encode(struct_v, bl);
62 encode(rotating_ver, bl);
63 encode(rotating_secrets, bl);
64 }
65 void decode_rotating(ceph::buffer::list& rotating_bl) {
66 using ceph::decode;
67 auto iter = rotating_bl.cbegin();
68 __u8 struct_v;
69 decode(struct_v, iter);
70 decode(rotating_ver, iter);
71 decode(rotating_secrets, iter);
72 }
73
74 bool contains(const EntityName& name) const {
75 return (secrets.find(name) != secrets.end());
76 }
77
78 void clear_secrets() {
79 version = 0;
80 secrets.clear();
81 rotating_ver = 0;
82 rotating_secrets.clear();
83 }
84
85 void add_auth(const EntityName& name, EntityAuth& auth) {
86 secrets[name] = auth;
87 }
88
89 void remove_secret(const EntityName& name) {
90 auto iter = secrets.find(name);
91 if (iter == secrets.end())
92 return;
93 secrets.erase(iter);
94 }
95
96 bool get_service_secret(CephContext *cct, uint32_t service_id,
97 CryptoKey& secret, uint64_t& secret_id,
98 double& ttl) const;
99 bool get_service_secret(CephContext *cct, uint32_t service_id,
100 uint64_t secret_id, CryptoKey& secret) const;
101 bool get_auth(const EntityName& name, EntityAuth& auth) const;
102 bool get_secret(const EntityName& name, CryptoKey& secret) const;
103 bool get_caps(CephContext *cct, const EntityName& name,
104 const std::string& type, AuthCapsInfo& caps) const;
105
106 std::map<EntityName, EntityAuth>::iterator secrets_begin()
107 { return secrets.begin(); }
108 std::map<EntityName, EntityAuth>::const_iterator secrets_begin() const
109 { return secrets.begin(); }
110 std::map<EntityName, EntityAuth>::iterator secrets_end()
111 { return secrets.end(); }
112 std::map<EntityName, EntityAuth>::const_iterator secrets_end() const
113 { return secrets.end(); }
114 std::map<EntityName, EntityAuth>::iterator find_name(const EntityName& name)
115 { return secrets.find(name); }
116 std::map<EntityName, EntityAuth>::const_iterator find_name(const EntityName& name) const
117 { return secrets.find(name); }
118
119
120 // -- incremental updates --
121 typedef enum {
122 AUTH_INC_NOP,
123 AUTH_INC_ADD,
124 AUTH_INC_DEL,
125 AUTH_INC_SET_ROTATING,
126 } IncrementalOp;
127
128 struct Incremental {
129 IncrementalOp op;
130 ceph::buffer::list rotating_bl; // if SET_ROTATING. otherwise,
131 EntityName name;
132 EntityAuth auth;
133
134 void encode(ceph::buffer::list& bl) const {
135 using ceph::encode;
136 __u8 struct_v = 1;
137 encode(struct_v, bl);
138 __u32 _op = (__u32)op;
139 encode(_op, bl);
140 if (op == AUTH_INC_SET_ROTATING) {
141 encode(rotating_bl, bl);
142 } else {
143 encode(name, bl);
144 encode(auth, bl);
145 }
146 }
147 void decode(ceph::buffer::list::const_iterator& bl) {
148 using ceph::decode;
149 __u8 struct_v;
150 decode(struct_v, bl);
151 __u32 _op;
152 decode(_op, bl);
153 op = (IncrementalOp)_op;
154 ceph_assert(op >= AUTH_INC_NOP && op <= AUTH_INC_SET_ROTATING);
155 if (op == AUTH_INC_SET_ROTATING) {
156 decode(rotating_bl, bl);
157 } else {
158 decode(name, bl);
159 decode(auth, bl);
160 }
161 }
162 };
163
164 void apply_incremental(Incremental& inc) {
165 switch (inc.op) {
166 case AUTH_INC_ADD:
167 add_auth(inc.name, inc.auth);
168 break;
169
170 case AUTH_INC_DEL:
171 remove_secret(inc.name);
172 break;
173
174 case AUTH_INC_SET_ROTATING:
175 decode_rotating(inc.rotating_bl);
176 break;
177
178 case AUTH_INC_NOP:
179 break;
180
181 default:
182 ceph_abort();
183 }
184 }
185
186 };
187 WRITE_CLASS_ENCODER(KeyServerData)
188 WRITE_CLASS_ENCODER(KeyServerData::Incremental)
189
190
191
192
193 class KeyServer : public KeyStore {
194 CephContext *cct;
195 KeyServerData data;
196 mutable ceph::mutex lock;
197
198 int _rotate_secret(uint32_t service_id, KeyServerData &pending_data);
199 void _dump_rotating_secrets();
200 int _build_session_auth_info(uint32_t service_id,
201 const AuthTicket& parent_ticket,
202 CephXSessionAuthInfo& info,
203 double ttl);
204 bool _get_service_caps(const EntityName& name, uint32_t service_id,
205 AuthCapsInfo& caps) const;
206 public:
207 KeyServer(CephContext *cct_, KeyRing *extra_secrets);
208 bool generate_secret(CryptoKey& secret);
209
210 bool get_secret(const EntityName& name, CryptoKey& secret) const override;
211 bool get_auth(const EntityName& name, EntityAuth& auth) const;
212 bool get_caps(const EntityName& name, const std::string& type, AuthCapsInfo& caps) const;
213 bool get_active_rotating_secret(const EntityName& name, CryptoKey& secret) const;
214 int start_server();
215 void rotate_timeout(double timeout);
216
217 void dump();
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 const CryptoKey& service_secret,
225 uint64_t secret_id,
226 CephXSessionAuthInfo& info);
227
228 /* get current secret for specific service type */
229 bool get_service_secret(uint32_t service_id, CryptoKey& secret,
230 uint64_t& secret_id, double& ttl) 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(ceph::buffer::list& bl) const {
237 using ceph::encode;
238 encode(data, bl);
239 }
240 void decode(ceph::buffer::list::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(ceph::Formatter *f, std::stringstream *ds) const;
247 void encode_formatted(std::string label, ceph::Formatter *f, ceph::buffer::list &bl);
248 void encode_plaintext(ceph::buffer::list &bl);
249 int list_secrets(std::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 auto 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 (auto p = data.secrets.begin(); p != data.secrets.end(); ++p) {
297 keyring.add(p->first, p->second);
298 }
299 }
300
301 bool prepare_rotating_update(ceph::buffer::list& rotating_bl);
302
303 bool get_rotating_encrypted(const EntityName& name, ceph::buffer::list& enc_bl) const;
304
305 ceph::mutex& get_lock() const { return lock; }
306 bool get_service_caps(const EntityName& name, uint32_t service_id,
307 AuthCapsInfo& caps) const;
308
309 std::map<EntityName, EntityAuth>::iterator secrets_begin()
310 { return data.secrets_begin(); }
311 std::map<EntityName, EntityAuth>::iterator secrets_end()
312 { return data.secrets_end(); }
313 };
314 WRITE_CLASS_ENCODER(KeyServer)
315
316
317 #endif