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