initial code repo
[stor4nfv.git] / src / 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