Blame view
net/ceph/auth.c
7.87 KB
b24413180
|
1 |
// SPDX-License-Identifier: GPL-2.0 |
3d14c5d2b
|
2 |
#include <linux/ceph/ceph_debug.h> |
4e7a5dcd1
|
3 4 5 |
#include <linux/module.h> #include <linux/err.h> |
d45d0d970
|
6 |
#include <linux/slab.h> |
4e7a5dcd1
|
7 |
|
3d14c5d2b
|
8 9 10 11 |
#include <linux/ceph/types.h> #include <linux/ceph/decode.h> #include <linux/ceph/libceph.h> #include <linux/ceph/messenger.h> |
4e7a5dcd1
|
12 |
#include "auth_none.h" |
ec0994e48
|
13 |
#include "auth_x.h" |
4e7a5dcd1
|
14 |
|
4e7a5dcd1
|
15 16 17 18 19 |
/* * get protocol handler */ static u32 supported_protocols[] = { |
ec0994e48
|
20 21 |
CEPH_AUTH_NONE, CEPH_AUTH_CEPHX |
4e7a5dcd1
|
22 |
}; |
cd84db6e4
|
23 |
static int ceph_auth_init_protocol(struct ceph_auth_client *ac, int protocol) |
4e7a5dcd1
|
24 25 26 27 |
{ switch (protocol) { case CEPH_AUTH_NONE: return ceph_auth_none_init(ac); |
ec0994e48
|
28 29 |
case CEPH_AUTH_CEPHX: return ceph_x_init(ac); |
4e7a5dcd1
|
30 31 32 33 34 35 36 37 |
default: return -ENOENT; } } /* * setup, teardown. */ |
8323c3aa7
|
38 |
struct ceph_auth_client *ceph_auth_init(const char *name, const struct ceph_crypto_key *key) |
4e7a5dcd1
|
39 40 41 |
{ struct ceph_auth_client *ac; int ret; |
8323c3aa7
|
42 43 |
dout("auth_init name '%s' ", name); |
4e7a5dcd1
|
44 45 46 47 48 |
ret = -ENOMEM; ac = kzalloc(sizeof(*ac), GFP_NOFS); if (!ac) goto out; |
e9966076c
|
49 |
mutex_init(&ac->mutex); |
4e7a5dcd1
|
50 51 52 53 54 |
ac->negotiating = true; if (name) ac->name = name; else ac->name = CEPH_AUTH_NAME_DEFAULT; |
8323c3aa7
|
55 56 57 |
dout("auth_init name %s ", ac->name); ac->key = key; |
4e7a5dcd1
|
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
return ac; out: return ERR_PTR(ret); } void ceph_auth_destroy(struct ceph_auth_client *ac) { dout("auth_destroy %p ", ac); if (ac->ops) ac->ops->destroy(ac); kfree(ac); } /* * Reset occurs when reconnecting to the monitor. */ void ceph_auth_reset(struct ceph_auth_client *ac) { |
e9966076c
|
78 |
mutex_lock(&ac->mutex); |
4e7a5dcd1
|
79 80 81 82 83 |
dout("auth_reset %p ", ac); if (ac->ops && !ac->negotiating) ac->ops->reset(ac); ac->negotiating = true; |
e9966076c
|
84 |
mutex_unlock(&ac->mutex); |
4e7a5dcd1
|
85 |
} |
f01d5cb24
|
86 87 88 89 |
/* * EntityName, not to be confused with entity_name_t */ int ceph_auth_entity_name_encode(const char *name, void **p, void *end) |
4e7a5dcd1
|
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
{ int len = strlen(name); if (*p + 2*sizeof(u32) + len > end) return -ERANGE; ceph_encode_32(p, CEPH_ENTITY_TYPE_CLIENT); ceph_encode_32(p, len); ceph_encode_copy(p, name, len); return 0; } /* * Initiate protocol negotiation with monitor. Include entity name * and list supported protocols. */ int ceph_auth_build_hello(struct ceph_auth_client *ac, void *buf, size_t len) { struct ceph_mon_request_header *monhdr = buf; void *p = monhdr + 1, *end = buf + len, *lenp; int i, num; int ret; |
e9966076c
|
111 |
mutex_lock(&ac->mutex); |
4e7a5dcd1
|
112 113 114 115 116 |
dout("auth_build_hello "); monhdr->have_version = 0; monhdr->session_mon = cpu_to_le16(-1); monhdr->session_mon_tid = 0; |
fdc723e77
|
117 |
ceph_encode_32(&p, CEPH_AUTH_UNKNOWN); /* no protocol, yet */ |
4e7a5dcd1
|
118 119 120 |
lenp = p; p += sizeof(u32); |
07c8739c5
|
121 122 |
ceph_decode_need(&p, end, 1 + sizeof(u32), bad); ceph_encode_8(&p, 1); |
4e7a5dcd1
|
123 124 |
num = ARRAY_SIZE(supported_protocols); ceph_encode_32(&p, num); |
07c8739c5
|
125 |
ceph_decode_need(&p, end, num * sizeof(u32), bad); |
4e7a5dcd1
|
126 127 |
for (i = 0; i < num; i++) ceph_encode_32(&p, supported_protocols[i]); |
f01d5cb24
|
128 |
ret = ceph_auth_entity_name_encode(ac->name, &p, end); |
4e7a5dcd1
|
129 |
if (ret < 0) |
e9966076c
|
130 |
goto out; |
4e7a5dcd1
|
131 132 133 134 |
ceph_decode_need(&p, end, sizeof(u64), bad); ceph_encode_64(&p, ac->global_id); ceph_encode_32(&lenp, p - lenp - sizeof(u32)); |
e9966076c
|
135 136 137 138 |
ret = p - buf; out: mutex_unlock(&ac->mutex); return ret; |
4e7a5dcd1
|
139 140 |
bad: |
e9966076c
|
141 142 |
ret = -ERANGE; goto out; |
4e7a5dcd1
|
143 |
} |
cd84db6e4
|
144 145 |
static int ceph_build_auth_request(struct ceph_auth_client *ac, void *msg_buf, size_t msg_len) |
9bd2e6f8b
|
146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
{ struct ceph_mon_request_header *monhdr = msg_buf; void *p = monhdr + 1; void *end = msg_buf + msg_len; int ret; monhdr->have_version = 0; monhdr->session_mon = cpu_to_le16(-1); monhdr->session_mon_tid = 0; ceph_encode_32(&p, ac->protocol); ret = ac->ops->build_request(ac, p + sizeof(u32), end); if (ret < 0) { |
559c1e007
|
160 161 162 |
pr_err("error %d building auth method %s request ", ret, ac->ops->name); |
e9966076c
|
163 |
goto out; |
9bd2e6f8b
|
164 165 166 167 |
} dout(" built request %d bytes ", ret); ceph_encode_32(&p, ret); |
e9966076c
|
168 169 170 |
ret = p + ret - msg_buf; out: return ret; |
9bd2e6f8b
|
171 |
} |
4e7a5dcd1
|
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
/* * Handle auth message from monitor. */ int ceph_handle_auth_reply(struct ceph_auth_client *ac, void *buf, size_t len, void *reply_buf, size_t reply_len) { void *p = buf; void *end = buf + len; int protocol; s32 result; u64 global_id; void *payload, *payload_end; int payload_len; char *result_msg; int result_msg_len; int ret = -EINVAL; |
e9966076c
|
189 |
mutex_lock(&ac->mutex); |
4e7a5dcd1
|
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
dout("handle_auth_reply %p %p ", p, end); ceph_decode_need(&p, end, sizeof(u32) * 3 + sizeof(u64), bad); protocol = ceph_decode_32(&p); result = ceph_decode_32(&p); global_id = ceph_decode_64(&p); payload_len = ceph_decode_32(&p); payload = p; p += payload_len; ceph_decode_need(&p, end, sizeof(u32), bad); result_msg_len = ceph_decode_32(&p); result_msg = p; p += result_msg_len; if (p != end) goto bad; dout(" result %d '%.*s' gid %llu len %d ", result, result_msg_len, result_msg, global_id, payload_len); payload_end = payload + payload_len; if (global_id && ac->global_id != global_id) { dout(" set global_id %lld -> %lld ", ac->global_id, global_id); ac->global_id = global_id; } if (ac->negotiating) { |
dc14657c9
|
219 220 221 222 223 |
/* server does not support our protocols? */ if (!protocol && result < 0) { ret = result; goto out; } |
4e7a5dcd1
|
224 225 226 227 228 229 230 231 232 |
/* set up (new) protocol handler? */ if (ac->protocol && ac->protocol != protocol) { ac->ops->destroy(ac); ac->protocol = 0; ac->ops = NULL; } if (ac->protocol != protocol) { ret = ceph_auth_init_protocol(ac, protocol); if (ret) { |
e95e9a7ae
|
233 234 235 |
pr_err("error %d on auth protocol %d init ", ret, protocol); |
4e7a5dcd1
|
236 237 238 |
goto out; } } |
9bd2e6f8b
|
239 240 |
ac->negotiating = false; |
4e7a5dcd1
|
241 242 243 244 |
} ret = ac->ops->handle_reply(ac, result, payload, payload_end); if (ret == -EAGAIN) { |
e9966076c
|
245 |
ret = ceph_build_auth_request(ac, reply_buf, reply_len); |
4e7a5dcd1
|
246 |
} else if (ret) { |
559c1e007
|
247 248 |
pr_err("auth method '%s' error %d ", ac->ops->name, ret); |
4e7a5dcd1
|
249 |
} |
4e7a5dcd1
|
250 |
|
4e7a5dcd1
|
251 |
out: |
e9966076c
|
252 |
mutex_unlock(&ac->mutex); |
4e7a5dcd1
|
253 |
return ret; |
e9966076c
|
254 255 256 257 258 259 |
bad: pr_err("failed to decode auth msg "); ret = -EINVAL; goto out; |
4e7a5dcd1
|
260 |
} |
9bd2e6f8b
|
261 262 263 |
int ceph_build_auth(struct ceph_auth_client *ac, void *msg_buf, size_t msg_len) { |
e9966076c
|
264 265 266 |
int ret = 0; mutex_lock(&ac->mutex); |
464691bd5
|
267 |
if (ac->ops->should_authenticate(ac)) |
e9966076c
|
268 269 270 |
ret = ceph_build_auth_request(ac, msg_buf, msg_len); mutex_unlock(&ac->mutex); return ret; |
9bd2e6f8b
|
271 |
} |
4e7a5dcd1
|
272 |
|
9bd2e6f8b
|
273 274 |
int ceph_auth_is_authenticated(struct ceph_auth_client *ac) { |
e9966076c
|
275 276 277 278 279 280 281 |
int ret = 0; mutex_lock(&ac->mutex); if (ac->ops) ret = ac->ops->is_authenticated(ac); mutex_unlock(&ac->mutex); return ret; |
9bd2e6f8b
|
282 |
} |
27859f977
|
283 284 285 286 287 288 |
EXPORT_SYMBOL(ceph_auth_is_authenticated); int ceph_auth_create_authorizer(struct ceph_auth_client *ac, int peer_type, struct ceph_auth_handshake *auth) { |
e9966076c
|
289 290 291 |
int ret = 0; mutex_lock(&ac->mutex); |
27859f977
|
292 |
if (ac->ops && ac->ops->create_authorizer) |
e9966076c
|
293 294 295 |
ret = ac->ops->create_authorizer(ac, peer_type, auth); mutex_unlock(&ac->mutex); return ret; |
27859f977
|
296 297 |
} EXPORT_SYMBOL(ceph_auth_create_authorizer); |
6c1ea260f
|
298 |
void ceph_auth_destroy_authorizer(struct ceph_authorizer *a) |
27859f977
|
299 |
{ |
6c1ea260f
|
300 |
a->destroy(a); |
27859f977
|
301 302 303 304 305 306 307 308 |
} EXPORT_SYMBOL(ceph_auth_destroy_authorizer); int ceph_auth_update_authorizer(struct ceph_auth_client *ac, int peer_type, struct ceph_auth_handshake *a) { int ret = 0; |
e9966076c
|
309 |
mutex_lock(&ac->mutex); |
27859f977
|
310 311 |
if (ac->ops && ac->ops->update_authorizer) ret = ac->ops->update_authorizer(ac, peer_type, a); |
e9966076c
|
312 |
mutex_unlock(&ac->mutex); |
27859f977
|
313 314 315 |
return ret; } EXPORT_SYMBOL(ceph_auth_update_authorizer); |
6daca13d2
|
316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 |
int ceph_auth_add_authorizer_challenge(struct ceph_auth_client *ac, struct ceph_authorizer *a, void *challenge_buf, int challenge_buf_len) { int ret = 0; mutex_lock(&ac->mutex); if (ac->ops && ac->ops->add_authorizer_challenge) ret = ac->ops->add_authorizer_challenge(ac, a, challenge_buf, challenge_buf_len); mutex_unlock(&ac->mutex); return ret; } EXPORT_SYMBOL(ceph_auth_add_authorizer_challenge); |
27859f977
|
331 |
int ceph_auth_verify_authorizer_reply(struct ceph_auth_client *ac, |
0dde58488
|
332 |
struct ceph_authorizer *a) |
27859f977
|
333 |
{ |
e9966076c
|
334 335 336 |
int ret = 0; mutex_lock(&ac->mutex); |
27859f977
|
337 |
if (ac->ops && ac->ops->verify_authorizer_reply) |
0dde58488
|
338 |
ret = ac->ops->verify_authorizer_reply(ac, a); |
e9966076c
|
339 340 |
mutex_unlock(&ac->mutex); return ret; |
27859f977
|
341 342 343 344 345 |
} EXPORT_SYMBOL(ceph_auth_verify_authorizer_reply); void ceph_auth_invalidate_authorizer(struct ceph_auth_client *ac, int peer_type) { |
e9966076c
|
346 |
mutex_lock(&ac->mutex); |
27859f977
|
347 348 |
if (ac->ops && ac->ops->invalidate_authorizer) ac->ops->invalidate_authorizer(ac, peer_type); |
e9966076c
|
349 |
mutex_unlock(&ac->mutex); |
27859f977
|
350 351 |
} EXPORT_SYMBOL(ceph_auth_invalidate_authorizer); |