]> git.proxmox.com Git - ceph.git/blob - ceph/src/auth/Auth.h
845f56c9bd662424e39bdf952846308994c244ec
[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
34 struct EntityAuth {
35 CryptoKey key;
36 std::map<std::string, ceph::buffer::list> caps;
37
38 void encode(ceph::buffer::list& bl) const {
39 __u8 struct_v = 2;
40 using ceph::encode;
41 encode(struct_v, bl);
42 encode((uint64_t)CEPH_AUTH_UID_DEFAULT, bl);
43 encode(key, bl);
44 encode(caps, bl);
45 }
46 void decode(ceph::buffer::list::const_iterator& bl) {
47 using ceph::decode;
48 __u8 struct_v;
49 decode(struct_v, bl);
50 if (struct_v >= 2) {
51 uint64_t old_auid;
52 decode(old_auid, bl);
53 }
54 decode(key, bl);
55 decode(caps, bl);
56 }
57 };
58 WRITE_CLASS_ENCODER(EntityAuth)
59
60 inline std::ostream& operator<<(std::ostream& out, const EntityAuth& a) {
61 return out << "auth(key=" << a.key << ")";
62 }
63
64 struct AuthCapsInfo {
65 bool allow_all;
66 ceph::buffer::list caps;
67
68 AuthCapsInfo() : allow_all(false) {}
69
70 void encode(ceph::buffer::list& bl) const {
71 using ceph::encode;
72 __u8 struct_v = 1;
73 encode(struct_v, bl);
74 __u8 a = (__u8)allow_all;
75 encode(a, bl);
76 encode(caps, bl);
77 }
78 void decode(ceph::buffer::list::const_iterator& bl) {
79 using ceph::decode;
80 __u8 struct_v;
81 decode(struct_v, bl);
82 __u8 a;
83 decode(a, bl);
84 allow_all = (bool)a;
85 decode(caps, bl);
86 }
87 };
88 WRITE_CLASS_ENCODER(AuthCapsInfo)
89
90 /*
91 * The ticket (if properly validated) authorizes the principal use
92 * services as described by 'caps' during the specified validity
93 * period.
94 */
95 struct AuthTicket {
96 EntityName name;
97 uint64_t global_id; /* global instance id */
98 utime_t created, renew_after, expires;
99 AuthCapsInfo caps;
100 __u32 flags;
101
102 AuthTicket() : global_id(0), flags(0){}
103
104 void init_timestamps(utime_t now, double ttl) {
105 created = now;
106 expires = now;
107 expires += ttl;
108 renew_after = now;
109 renew_after += ttl / 2.0;
110 }
111
112 void encode(ceph::buffer::list& bl) const {
113 using ceph::encode;
114 __u8 struct_v = 2;
115 encode(struct_v, bl);
116 encode(name, bl);
117 encode(global_id, bl);
118 encode((uint64_t)CEPH_AUTH_UID_DEFAULT, bl);
119 encode(created, bl);
120 encode(expires, bl);
121 encode(caps, bl);
122 encode(flags, bl);
123 }
124 void decode(ceph::buffer::list::const_iterator& bl) {
125 using ceph::decode;
126 __u8 struct_v;
127 decode(struct_v, bl);
128 decode(name, bl);
129 decode(global_id, bl);
130 if (struct_v >= 2) {
131 uint64_t old_auid;
132 decode(old_auid, bl);
133 }
134 decode(created, bl);
135 decode(expires, bl);
136 decode(caps, bl);
137 decode(flags, bl);
138 }
139 };
140 WRITE_CLASS_ENCODER(AuthTicket)
141
142
143 /*
144 * abstract authorizer class
145 */
146 struct AuthAuthorizer {
147 __u32 protocol;
148 ceph::buffer::list bl;
149 CryptoKey session_key;
150
151 explicit AuthAuthorizer(__u32 p) : protocol(p) {}
152 virtual ~AuthAuthorizer() {}
153 virtual bool verify_reply(ceph::buffer::list::const_iterator& reply,
154 std::string *connection_secret) = 0;
155 virtual bool add_challenge(CephContext *cct,
156 const ceph::buffer::list& 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 ///< set if msgr1 peer doesn't support CEPHX_V2
197 bool skip_authorizer_challenge = false;
198 };
199
200 /*
201 * Key management
202 */
203 #define KEY_ROTATE_NUM 3 /* prev, current, next */
204
205 struct ExpiringCryptoKey {
206 CryptoKey key;
207 utime_t expiration;
208
209 void encode(ceph::buffer::list& bl) const {
210 using ceph::encode;
211 __u8 struct_v = 1;
212 encode(struct_v, bl);
213 encode(key, bl);
214 encode(expiration, bl);
215 }
216 void decode(ceph::buffer::list::const_iterator& bl) {
217 using ceph::decode;
218 __u8 struct_v;
219 decode(struct_v, bl);
220 decode(key, bl);
221 decode(expiration, bl);
222 }
223 };
224 WRITE_CLASS_ENCODER(ExpiringCryptoKey)
225
226 inline std::ostream& operator<<(std::ostream& out, const ExpiringCryptoKey& c)
227 {
228 return out << c.key << " expires " << c.expiration;
229 }
230
231 struct RotatingSecrets {
232 std::map<uint64_t, ExpiringCryptoKey> secrets;
233 version_t max_ver;
234
235 RotatingSecrets() : max_ver(0) {}
236
237 void encode(ceph::buffer::list& bl) const {
238 using ceph::encode;
239 __u8 struct_v = 1;
240 encode(struct_v, bl);
241 encode(secrets, bl);
242 encode(max_ver, bl);
243 }
244 void decode(ceph::buffer::list::const_iterator& bl) {
245 using ceph::decode;
246 __u8 struct_v;
247 decode(struct_v, bl);
248 decode(secrets, bl);
249 decode(max_ver, bl);
250 }
251
252 uint64_t add(ExpiringCryptoKey& key) {
253 secrets[++max_ver] = key;
254 while (secrets.size() > KEY_ROTATE_NUM)
255 secrets.erase(secrets.begin());
256 return max_ver;
257 }
258
259 bool need_new_secrets() const {
260 return secrets.size() < KEY_ROTATE_NUM;
261 }
262 bool need_new_secrets(const utime_t& now) const {
263 return secrets.size() < KEY_ROTATE_NUM || current().expiration <= now;
264 }
265
266 ExpiringCryptoKey& previous() {
267 return secrets.begin()->second;
268 }
269 ExpiringCryptoKey& current() {
270 auto p = secrets.begin();
271 ++p;
272 return p->second;
273 }
274 const ExpiringCryptoKey& current() const {
275 auto p = secrets.begin();
276 ++p;
277 return p->second;
278 }
279 ExpiringCryptoKey& next() {
280 return secrets.rbegin()->second;
281 }
282 bool empty() {
283 return secrets.empty();
284 }
285
286 void dump();
287 };
288 WRITE_CLASS_ENCODER(RotatingSecrets)
289
290
291
292 class KeyStore {
293 public:
294 virtual ~KeyStore() {}
295 virtual bool get_secret(const EntityName& name, CryptoKey& secret) const = 0;
296 virtual bool get_service_secret(uint32_t service_id, uint64_t secret_id,
297 CryptoKey& secret) const = 0;
298 };
299
300 inline bool auth_principal_needs_rotating_keys(EntityName& name)
301 {
302 uint32_t ty(name.get_type());
303 return ((ty == CEPH_ENTITY_TYPE_OSD)
304 || (ty == CEPH_ENTITY_TYPE_MDS)
305 || (ty == CEPH_ENTITY_TYPE_MGR));
306 }
307
308 #endif