]> git.proxmox.com Git - ceph.git/blob - ceph/src/auth/cephx/CephxKeyServer.h
update sources to ceph Nautilus 14.2.1
[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
23 class CephContext;
24
25 struct KeyServerData {
26 version_t version;
27
28 /* for each entity */
29 map<EntityName, EntityAuth> secrets;
30 KeyRing *extra_secrets;
31
32 /* for each service type */
33 version_t rotating_ver;
34 map<uint32_t, RotatingSecrets> rotating_secrets;
35
36 explicit KeyServerData(KeyRing *extra)
37 : version(0),
38 extra_secrets(extra),
39 rotating_ver(0) {}
40
41 void encode(bufferlist& bl) const {
42 __u8 struct_v = 1;
43 using ceph::encode;
44 encode(struct_v, bl);
45 encode(version, bl);
46 encode(rotating_ver, bl);
47 encode(secrets, bl);
48 encode(rotating_secrets, bl);
49 }
50 void decode(bufferlist::const_iterator& bl) {
51 using ceph::decode;
52 __u8 struct_v;
53 decode(struct_v, bl);
54 decode(version, bl);
55 decode(rotating_ver, bl);
56 decode(secrets, bl);
57 decode(rotating_secrets, bl);
58 }
59
60 void encode_rotating(bufferlist& bl) const {
61 using ceph::encode;
62 __u8 struct_v = 1;
63 encode(struct_v, bl);
64 encode(rotating_ver, bl);
65 encode(rotating_secrets, bl);
66 }
67 void decode_rotating(bufferlist& rotating_bl) {
68 using ceph::decode;
69 auto iter = rotating_bl.cbegin();
70 __u8 struct_v;
71 decode(struct_v, iter);
72 decode(rotating_ver, iter);
73 decode(rotating_secrets, iter);
74 }
75
76 bool contains(const EntityName& name) const {
77 return (secrets.find(name) != secrets.end());
78 }
79
80 void clear_secrets() {
81 secrets.clear();
82 }
83
84 void add_auth(const EntityName& name, EntityAuth& auth) {
85 secrets[name] = auth;
86 }
87
88 void remove_secret(const EntityName& name) {
89 map<EntityName, EntityAuth>::iterator iter = secrets.find(name);
90 if (iter == secrets.end())
91 return;
92 secrets.erase(iter);
93 }
94
95 bool get_service_secret(CephContext *cct, uint32_t service_id,
96 ExpiringCryptoKey& secret, uint64_t& secret_id) const;
97 bool get_service_secret(CephContext *cct, uint32_t service_id,
98 CryptoKey& secret, uint64_t& secret_id) 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 map<EntityName, EntityAuth>::iterator secrets_begin()
107 { return secrets.begin(); }
108 map<EntityName, EntityAuth>::const_iterator secrets_begin() const
109 { return secrets.begin(); }
110 map<EntityName, EntityAuth>::iterator secrets_end()
111 { return secrets.end(); }
112 map<EntityName, EntityAuth>::const_iterator secrets_end() const
113 { return secrets.end(); }
114 map<EntityName, EntityAuth>::iterator find_name(const EntityName& name)
115 { return secrets.find(name); }
116 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 bufferlist rotating_bl; // if SET_ROTATING. otherwise,
131 EntityName name;
132 EntityAuth auth;
133
134 void encode(bufferlist& 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(bufferlist::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);
199 bool _check_rotating_secrets();
200 void _dump_rotating_secrets();
201 int _build_session_auth_info(uint32_t service_id,
202 const AuthTicket& parent_ticket,
203 CephXSessionAuthInfo& info);
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 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 int build_session_auth_info(uint32_t service_id,
218 const AuthTicket& parent_ticket,
219 CephXSessionAuthInfo& info);
220 int build_session_auth_info(uint32_t service_id,
221 const AuthTicket& parent_ticket,
222 CephXSessionAuthInfo& info,
223 CryptoKey& service_secret,
224 uint64_t secret_id);
225
226 /* get current secret for specific service type */
227 bool get_service_secret(uint32_t service_id, CryptoKey& service_key,
228 uint64_t& secret_id) const;
229 bool get_service_secret(uint32_t service_id, uint64_t secret_id,
230 CryptoKey& secret) const override;
231
232 bool generate_secret(EntityName& name, CryptoKey& secret);
233
234 void encode(bufferlist& bl) const {
235 using ceph::encode;
236 encode(data, bl);
237 }
238 void decode(bufferlist::const_iterator& bl) {
239 std::scoped_lock l{lock};
240 using ceph::decode;
241 decode(data, bl);
242 }
243 bool contains(const EntityName& name) const;
244 int encode_secrets(Formatter *f, stringstream *ds) const;
245 void encode_formatted(string label, Formatter *f, bufferlist &bl);
246 void encode_plaintext(bufferlist &bl);
247 int list_secrets(stringstream& ds) const {
248 return encode_secrets(NULL, &ds);
249 }
250 version_t get_ver() const {
251 std::scoped_lock l{lock};
252 return data.version;
253 }
254
255 void clear_secrets() {
256 std::scoped_lock l{lock};
257 data.clear_secrets();
258 }
259
260 void apply_data_incremental(KeyServerData::Incremental& inc) {
261 std::scoped_lock l{lock};
262 data.apply_incremental(inc);
263 }
264 void set_ver(version_t ver) {
265 std::scoped_lock l{lock};
266 data.version = ver;
267 }
268
269 void add_auth(const EntityName& name, EntityAuth& auth) {
270 std::scoped_lock l{lock};
271 data.add_auth(name, auth);
272 }
273
274 void remove_secret(const EntityName& name) {
275 std::scoped_lock l{lock};
276 data.remove_secret(name);
277 }
278
279 bool has_secrets() {
280 map<EntityName, EntityAuth>::const_iterator b = data.secrets_begin();
281 return (b != data.secrets_end());
282 }
283 int get_num_secrets() {
284 std::scoped_lock l{lock};
285 return data.secrets.size();
286 }
287
288 void clone_to(KeyServerData& dst) const {
289 std::scoped_lock l{lock};
290 dst = data;
291 }
292 void export_keyring(KeyRing& keyring) {
293 std::scoped_lock l{lock};
294 for (map<EntityName, EntityAuth>::iterator p = data.secrets.begin();
295 p != data.secrets.end();
296 ++p) {
297 keyring.add(p->first, p->second);
298 }
299 }
300
301 bool updated_rotating(bufferlist& rotating_bl, version_t& rotating_ver);
302
303 bool get_rotating_encrypted(const EntityName& name, bufferlist& 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 map<EntityName, EntityAuth>::iterator secrets_begin()
310 { return data.secrets_begin(); }
311 map<EntityName, EntityAuth>::iterator secrets_end()
312 { return data.secrets_end(); }
313 };
314 WRITE_CLASS_ENCODER(KeyServer)
315
316
317 #endif