]> git.proxmox.com Git - ceph.git/blob - ceph/src/auth/Auth.h
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / auth / Auth.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_AUTHTYPES_H
16 #define CEPH_AUTHTYPES_H
17
18 #include "Crypto.h"
19 #include "common/entity_name.h"
20
21 // The _MAX values are a bit wonky here because we are overloading the first
22 // byte of the auth payload to identify both the type of authentication to be
23 // used *and* the encoding version for the authenticator. So, we define a
24 // range.
25 enum {
26 AUTH_MODE_NONE = 0,
27 AUTH_MODE_AUTHORIZER = 1,
28 AUTH_MODE_AUTHORIZER_MAX = 9,
29 AUTH_MODE_MON = 10,
30 AUTH_MODE_MON_MAX = 19,
31 };
32
33 class Cond;
34
35 struct EntityAuth {
36 CryptoKey key;
37 map<string, bufferlist> caps;
38
39 void encode(bufferlist& bl) const {
40 __u8 struct_v = 2;
41 using ceph::encode;
42 encode(struct_v, bl);
43 encode((uint64_t)CEPH_AUTH_UID_DEFAULT, bl);
44 encode(key, bl);
45 encode(caps, bl);
46 }
47 void decode(bufferlist::const_iterator& bl) {
48 using ceph::decode;
49 __u8 struct_v;
50 decode(struct_v, bl);
51 if (struct_v >= 2) {
52 uint64_t old_auid;
53 decode(old_auid, bl);
54 }
55 decode(key, bl);
56 decode(caps, bl);
57 }
58 };
59 WRITE_CLASS_ENCODER(EntityAuth)
60
61 static inline ostream& operator<<(ostream& out, const EntityAuth& a) {
62 return out << "auth(key=" << a.key << ")";
63 }
64
65 struct AuthCapsInfo {
66 bool allow_all;
67 bufferlist caps;
68
69 AuthCapsInfo() : allow_all(false) {}
70
71 void encode(bufferlist& bl) const {
72 using ceph::encode;
73 __u8 struct_v = 1;
74 encode(struct_v, bl);
75 __u8 a = (__u8)allow_all;
76 encode(a, bl);
77 encode(caps, bl);
78 }
79 void decode(bufferlist::const_iterator& bl) {
80 using ceph::decode;
81 __u8 struct_v;
82 decode(struct_v, bl);
83 __u8 a;
84 decode(a, bl);
85 allow_all = (bool)a;
86 decode(caps, bl);
87 }
88 };
89 WRITE_CLASS_ENCODER(AuthCapsInfo)
90
91 /*
92 * The ticket (if properly validated) authorizes the principal use
93 * services as described by 'caps' during the specified validity
94 * period.
95 */
96 struct AuthTicket {
97 EntityName name;
98 uint64_t global_id; /* global instance id */
99 utime_t created, renew_after, expires;
100 AuthCapsInfo caps;
101 __u32 flags;
102
103 AuthTicket() : global_id(0), flags(0){}
104
105 void init_timestamps(utime_t now, double ttl) {
106 created = now;
107 expires = now;
108 expires += ttl;
109 renew_after = now;
110 renew_after += ttl / 2.0;
111 }
112
113 void encode(bufferlist& bl) const {
114 using ceph::encode;
115 __u8 struct_v = 2;
116 encode(struct_v, bl);
117 encode(name, bl);
118 encode(global_id, bl);
119 encode((uint64_t)CEPH_AUTH_UID_DEFAULT, bl);
120 encode(created, bl);
121 encode(expires, bl);
122 encode(caps, bl);
123 encode(flags, bl);
124 }
125 void decode(bufferlist::const_iterator& bl) {
126 using ceph::decode;
127 __u8 struct_v;
128 decode(struct_v, bl);
129 decode(name, bl);
130 decode(global_id, bl);
131 if (struct_v >= 2) {
132 uint64_t old_auid;
133 decode(old_auid, bl);
134 }
135 decode(created, bl);
136 decode(expires, bl);
137 decode(caps, bl);
138 decode(flags, bl);
139 }
140 };
141 WRITE_CLASS_ENCODER(AuthTicket)
142
143
144 /*
145 * abstract authorizer class
146 */
147 struct AuthAuthorizer {
148 __u32 protocol;
149 bufferlist bl;
150 CryptoKey session_key;
151
152 explicit AuthAuthorizer(__u32 p) : protocol(p) {}
153 virtual ~AuthAuthorizer() {}
154 virtual bool verify_reply(bufferlist::const_iterator& reply,
155 std::string *connection_secret) = 0;
156 virtual bool add_challenge(CephContext *cct, const bufferlist& challenge) = 0;
157 };
158
159 struct AuthAuthorizerChallenge {
160 virtual ~AuthAuthorizerChallenge() {}
161 };
162
163 struct AuthConnectionMeta {
164 uint32_t auth_method = CEPH_AUTH_UNKNOWN; //< CEPH_AUTH_*
165
166 /// client: initial empty, but populated if server said bad method
167 std::vector<uint32_t> allowed_methods;
168
169 int auth_mode = AUTH_MODE_NONE; ///< AUTH_MODE_*
170
171 int con_mode = 0; ///< negotiated mode
172
173 bool is_mode_crc() const {
174 return con_mode == CEPH_CON_MODE_CRC;
175 }
176 bool is_mode_secure() const {
177 return con_mode == CEPH_CON_MODE_SECURE;
178 }
179
180 CryptoKey session_key; ///< per-ticket key
181
182 size_t get_connection_secret_length() const {
183 switch (con_mode) {
184 case CEPH_CON_MODE_CRC:
185 return 0;
186 case CEPH_CON_MODE_SECURE:
187 return 16 * 4;
188 }
189 return 0;
190 }
191 std::string connection_secret; ///< per-connection key
192
193 std::unique_ptr<AuthAuthorizer> authorizer;
194 std::unique_ptr<AuthAuthorizerChallenge> authorizer_challenge;
195 };
196
197 /*
198 * Key management
199 */
200 #define KEY_ROTATE_NUM 3 /* prev, current, next */
201
202 struct ExpiringCryptoKey {
203 CryptoKey key;
204 utime_t expiration;
205
206 void encode(bufferlist& bl) const {
207 using ceph::encode;
208 __u8 struct_v = 1;
209 encode(struct_v, bl);
210 encode(key, bl);
211 encode(expiration, bl);
212 }
213 void decode(bufferlist::const_iterator& bl) {
214 using ceph::decode;
215 __u8 struct_v;
216 decode(struct_v, bl);
217 decode(key, bl);
218 decode(expiration, bl);
219 }
220 };
221 WRITE_CLASS_ENCODER(ExpiringCryptoKey)
222
223 static inline ostream& operator<<(ostream& out, const ExpiringCryptoKey& c)
224 {
225 return out << c.key << " expires " << c.expiration;
226 }
227
228 struct RotatingSecrets {
229 map<uint64_t, ExpiringCryptoKey> secrets;
230 version_t max_ver;
231
232 RotatingSecrets() : max_ver(0) {}
233
234 void encode(bufferlist& bl) const {
235 using ceph::encode;
236 __u8 struct_v = 1;
237 encode(struct_v, bl);
238 encode(secrets, bl);
239 encode(max_ver, bl);
240 }
241 void decode(bufferlist::const_iterator& bl) {
242 using ceph::decode;
243 __u8 struct_v;
244 decode(struct_v, bl);
245 decode(secrets, bl);
246 decode(max_ver, bl);
247 }
248
249 uint64_t add(ExpiringCryptoKey& key) {
250 secrets[++max_ver] = key;
251 while (secrets.size() > KEY_ROTATE_NUM)
252 secrets.erase(secrets.begin());
253 return max_ver;
254 }
255
256 bool need_new_secrets() const {
257 return secrets.size() < KEY_ROTATE_NUM;
258 }
259 bool need_new_secrets(utime_t now) const {
260 return secrets.size() < KEY_ROTATE_NUM || current().expiration <= now;
261 }
262
263 ExpiringCryptoKey& previous() {
264 return secrets.begin()->second;
265 }
266 ExpiringCryptoKey& current() {
267 map<uint64_t, ExpiringCryptoKey>::iterator p = secrets.begin();
268 ++p;
269 return p->second;
270 }
271 const ExpiringCryptoKey& current() const {
272 map<uint64_t, ExpiringCryptoKey>::const_iterator p = secrets.begin();
273 ++p;
274 return p->second;
275 }
276 ExpiringCryptoKey& next() {
277 return secrets.rbegin()->second;
278 }
279 bool empty() {
280 return secrets.empty();
281 }
282
283 void dump();
284 };
285 WRITE_CLASS_ENCODER(RotatingSecrets)
286
287
288
289 class KeyStore {
290 public:
291 virtual ~KeyStore() {}
292 virtual bool get_secret(const EntityName& name, CryptoKey& secret) const = 0;
293 virtual bool get_service_secret(uint32_t service_id, uint64_t secret_id,
294 CryptoKey& secret) const = 0;
295 };
296
297 inline bool auth_principal_needs_rotating_keys(EntityName& name)
298 {
299 uint32_t ty(name.get_type());
300 return ((ty == CEPH_ENTITY_TYPE_OSD)
301 || (ty == CEPH_ENTITY_TYPE_MDS)
302 || (ty == CEPH_ENTITY_TYPE_MGR));
303 }
304
305 #endif