1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/ceph/ceph_debug.h>
4 #include <linux/module.h>
6 #include <linux/slab.h>
8 #include <linux/ceph/types.h>
9 #include <linux/ceph/decode.h>
10 #include <linux/ceph/libceph.h>
11 #include <linux/ceph/messenger.h>
12 #include "auth_none.h"
17 * get protocol handler
19 static u32 supported_protocols
[] = {
24 static int ceph_auth_init_protocol(struct ceph_auth_client
*ac
, int protocol
)
28 return ceph_auth_none_init(ac
);
30 return ceph_x_init(ac
);
39 struct ceph_auth_client
*ceph_auth_init(const char *name
, const struct ceph_crypto_key
*key
)
41 struct ceph_auth_client
*ac
;
44 dout("auth_init name '%s'\n", name
);
47 ac
= kzalloc(sizeof(*ac
), GFP_NOFS
);
51 mutex_init(&ac
->mutex
);
52 ac
->negotiating
= true;
56 ac
->name
= CEPH_AUTH_NAME_DEFAULT
;
57 dout("auth_init name %s\n", ac
->name
);
65 void ceph_auth_destroy(struct ceph_auth_client
*ac
)
67 dout("auth_destroy %p\n", ac
);
74 * Reset occurs when reconnecting to the monitor.
76 void ceph_auth_reset(struct ceph_auth_client
*ac
)
78 mutex_lock(&ac
->mutex
);
79 dout("auth_reset %p\n", ac
);
80 if (ac
->ops
&& !ac
->negotiating
)
82 ac
->negotiating
= true;
83 mutex_unlock(&ac
->mutex
);
87 * EntityName, not to be confused with entity_name_t
89 int ceph_auth_entity_name_encode(const char *name
, void **p
, void *end
)
91 int len
= strlen(name
);
93 if (*p
+ 2*sizeof(u32
) + len
> end
)
95 ceph_encode_32(p
, CEPH_ENTITY_TYPE_CLIENT
);
96 ceph_encode_32(p
, len
);
97 ceph_encode_copy(p
, name
, len
);
102 * Initiate protocol negotiation with monitor. Include entity name
103 * and list supported protocols.
105 int ceph_auth_build_hello(struct ceph_auth_client
*ac
, void *buf
, size_t len
)
107 struct ceph_mon_request_header
*monhdr
= buf
;
108 void *p
= monhdr
+ 1, *end
= buf
+ len
, *lenp
;
112 mutex_lock(&ac
->mutex
);
113 dout("auth_build_hello\n");
114 monhdr
->have_version
= 0;
115 monhdr
->session_mon
= cpu_to_le16(-1);
116 monhdr
->session_mon_tid
= 0;
118 ceph_encode_32(&p
, CEPH_AUTH_UNKNOWN
); /* no protocol, yet */
123 ceph_decode_need(&p
, end
, 1 + sizeof(u32
), bad
);
124 ceph_encode_8(&p
, 1);
125 num
= ARRAY_SIZE(supported_protocols
);
126 ceph_encode_32(&p
, num
);
127 ceph_decode_need(&p
, end
, num
* sizeof(u32
), bad
);
128 for (i
= 0; i
< num
; i
++)
129 ceph_encode_32(&p
, supported_protocols
[i
]);
131 ret
= ceph_auth_entity_name_encode(ac
->name
, &p
, end
);
134 ceph_decode_need(&p
, end
, sizeof(u64
), bad
);
135 ceph_encode_64(&p
, ac
->global_id
);
137 ceph_encode_32(&lenp
, p
- lenp
- sizeof(u32
));
140 mutex_unlock(&ac
->mutex
);
148 static int ceph_build_auth_request(struct ceph_auth_client
*ac
,
149 void *msg_buf
, size_t msg_len
)
151 struct ceph_mon_request_header
*monhdr
= msg_buf
;
152 void *p
= monhdr
+ 1;
153 void *end
= msg_buf
+ msg_len
;
156 monhdr
->have_version
= 0;
157 monhdr
->session_mon
= cpu_to_le16(-1);
158 monhdr
->session_mon_tid
= 0;
160 ceph_encode_32(&p
, ac
->protocol
);
162 ret
= ac
->ops
->build_request(ac
, p
+ sizeof(u32
), end
);
164 pr_err("error %d building auth method %s request\n", ret
,
168 dout(" built request %d bytes\n", ret
);
169 ceph_encode_32(&p
, ret
);
170 ret
= p
+ ret
- msg_buf
;
176 * Handle auth message from monitor.
178 int ceph_handle_auth_reply(struct ceph_auth_client
*ac
,
179 void *buf
, size_t len
,
180 void *reply_buf
, size_t reply_len
)
183 void *end
= buf
+ len
;
187 void *payload
, *payload_end
;
193 mutex_lock(&ac
->mutex
);
194 dout("handle_auth_reply %p %p\n", p
, end
);
195 ceph_decode_need(&p
, end
, sizeof(u32
) * 3 + sizeof(u64
), bad
);
196 protocol
= ceph_decode_32(&p
);
197 result
= ceph_decode_32(&p
);
198 global_id
= ceph_decode_64(&p
);
199 payload_len
= ceph_decode_32(&p
);
202 ceph_decode_need(&p
, end
, sizeof(u32
), bad
);
203 result_msg_len
= ceph_decode_32(&p
);
209 dout(" result %d '%.*s' gid %llu len %d\n", result
, result_msg_len
,
210 result_msg
, global_id
, payload_len
);
212 payload_end
= payload
+ payload_len
;
214 if (global_id
&& ac
->global_id
!= global_id
) {
215 dout(" set global_id %lld -> %lld\n", ac
->global_id
, global_id
);
216 ac
->global_id
= global_id
;
219 if (ac
->negotiating
) {
220 /* server does not support our protocols? */
221 if (!protocol
&& result
< 0) {
225 /* set up (new) protocol handler? */
226 if (ac
->protocol
&& ac
->protocol
!= protocol
) {
227 ac
->ops
->destroy(ac
);
231 if (ac
->protocol
!= protocol
) {
232 ret
= ceph_auth_init_protocol(ac
, protocol
);
234 pr_err("error %d on auth protocol %d init\n",
240 ac
->negotiating
= false;
243 ret
= ac
->ops
->handle_reply(ac
, result
, payload
, payload_end
);
244 if (ret
== -EAGAIN
) {
245 ret
= ceph_build_auth_request(ac
, reply_buf
, reply_len
);
247 pr_err("auth method '%s' error %d\n", ac
->ops
->name
, ret
);
251 mutex_unlock(&ac
->mutex
);
255 pr_err("failed to decode auth msg\n");
260 int ceph_build_auth(struct ceph_auth_client
*ac
,
261 void *msg_buf
, size_t msg_len
)
265 mutex_lock(&ac
->mutex
);
266 if (ac
->ops
->should_authenticate(ac
))
267 ret
= ceph_build_auth_request(ac
, msg_buf
, msg_len
);
268 mutex_unlock(&ac
->mutex
);
272 int ceph_auth_is_authenticated(struct ceph_auth_client
*ac
)
276 mutex_lock(&ac
->mutex
);
278 ret
= ac
->ops
->is_authenticated(ac
);
279 mutex_unlock(&ac
->mutex
);
282 EXPORT_SYMBOL(ceph_auth_is_authenticated
);
284 int ceph_auth_create_authorizer(struct ceph_auth_client
*ac
,
286 struct ceph_auth_handshake
*auth
)
290 mutex_lock(&ac
->mutex
);
291 if (ac
->ops
&& ac
->ops
->create_authorizer
)
292 ret
= ac
->ops
->create_authorizer(ac
, peer_type
, auth
);
293 mutex_unlock(&ac
->mutex
);
296 EXPORT_SYMBOL(ceph_auth_create_authorizer
);
298 void ceph_auth_destroy_authorizer(struct ceph_authorizer
*a
)
302 EXPORT_SYMBOL(ceph_auth_destroy_authorizer
);
304 int ceph_auth_update_authorizer(struct ceph_auth_client
*ac
,
306 struct ceph_auth_handshake
*a
)
310 mutex_lock(&ac
->mutex
);
311 if (ac
->ops
&& ac
->ops
->update_authorizer
)
312 ret
= ac
->ops
->update_authorizer(ac
, peer_type
, a
);
313 mutex_unlock(&ac
->mutex
);
316 EXPORT_SYMBOL(ceph_auth_update_authorizer
);
318 int ceph_auth_add_authorizer_challenge(struct ceph_auth_client
*ac
,
319 struct ceph_authorizer
*a
,
321 int challenge_buf_len
)
325 mutex_lock(&ac
->mutex
);
326 if (ac
->ops
&& ac
->ops
->add_authorizer_challenge
)
327 ret
= ac
->ops
->add_authorizer_challenge(ac
, a
, challenge_buf
,
329 mutex_unlock(&ac
->mutex
);
332 EXPORT_SYMBOL(ceph_auth_add_authorizer_challenge
);
334 int ceph_auth_verify_authorizer_reply(struct ceph_auth_client
*ac
,
335 struct ceph_authorizer
*a
)
339 mutex_lock(&ac
->mutex
);
340 if (ac
->ops
&& ac
->ops
->verify_authorizer_reply
)
341 ret
= ac
->ops
->verify_authorizer_reply(ac
, a
);
342 mutex_unlock(&ac
->mutex
);
345 EXPORT_SYMBOL(ceph_auth_verify_authorizer_reply
);
347 void ceph_auth_invalidate_authorizer(struct ceph_auth_client
*ac
, int peer_type
)
349 mutex_lock(&ac
->mutex
);
350 if (ac
->ops
&& ac
->ops
->invalidate_authorizer
)
351 ac
->ops
->invalidate_authorizer(ac
, peer_type
);
352 mutex_unlock(&ac
->mutex
);
354 EXPORT_SYMBOL(ceph_auth_invalidate_authorizer
);