Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) #include <linux/ceph/ceph_debug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/random.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/ceph/decode.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/ceph/auth.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/ceph/ceph_features.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/ceph/libceph.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/ceph/messenger.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include "crypto.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include "auth_x.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include "auth_x_protocol.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) static void ceph_x_validate_tickets(struct ceph_auth_client *ac, int *pneed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) static int ceph_x_is_authenticated(struct ceph_auth_client *ac)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	struct ceph_x_info *xi = ac->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	int need;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	ceph_x_validate_tickets(ac, &need);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	dout("ceph_x_is_authenticated want=%d need=%d have=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	     ac->want_keys, need, xi->have_keys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	return (ac->want_keys & xi->have_keys) == ac->want_keys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) static int ceph_x_should_authenticate(struct ceph_auth_client *ac)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	struct ceph_x_info *xi = ac->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	int need;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	ceph_x_validate_tickets(ac, &need);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	dout("ceph_x_should_authenticate want=%d need=%d have=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	     ac->want_keys, need, xi->have_keys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	return need != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) static int ceph_x_encrypt_offset(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	return sizeof(u32) + sizeof(struct ceph_x_encrypt_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) static int ceph_x_encrypt_buflen(int ilen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	return ceph_x_encrypt_offset() + ilen + 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) static int ceph_x_encrypt(struct ceph_crypto_key *secret, void *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 			  int buf_len, int plaintext_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	struct ceph_x_encrypt_header *hdr = buf + sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	int ciphertext_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	hdr->struct_v = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	hdr->magic = cpu_to_le64(CEPHX_ENC_MAGIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	ret = ceph_crypt(secret, true, buf + sizeof(u32), buf_len - sizeof(u32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 			 plaintext_len + sizeof(struct ceph_x_encrypt_header),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 			 &ciphertext_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	ceph_encode_32(&buf, ciphertext_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	return sizeof(u32) + ciphertext_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) static int __ceph_x_decrypt(struct ceph_crypto_key *secret, void *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 			    int ciphertext_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	struct ceph_x_encrypt_header *hdr = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	int plaintext_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	ret = ceph_crypt(secret, false, p, ciphertext_len, ciphertext_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 			 &plaintext_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	if (le64_to_cpu(hdr->magic) != CEPHX_ENC_MAGIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		pr_err("%s bad magic\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	return plaintext_len - sizeof(*hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) static int ceph_x_decrypt(struct ceph_crypto_key *secret, void **p, void *end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	int ciphertext_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	ceph_decode_32_safe(p, end, ciphertext_len, e_inval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	ceph_decode_need(p, end, ciphertext_len, e_inval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	ret = __ceph_x_decrypt(secret, *p, ciphertext_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	*p += ciphertext_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) e_inval:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)  * get existing (or insert new) ticket handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static struct ceph_x_ticket_handler *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) get_ticket_handler(struct ceph_auth_client *ac, int service)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	struct ceph_x_ticket_handler *th;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	struct ceph_x_info *xi = ac->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	struct rb_node *parent = NULL, **p = &xi->ticket_handlers.rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	while (*p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		parent = *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		th = rb_entry(parent, struct ceph_x_ticket_handler, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		if (service < th->service)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 			p = &(*p)->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		else if (service > th->service)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 			p = &(*p)->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 			return th;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	/* add it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	th = kzalloc(sizeof(*th), GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	if (!th)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	th->service = service;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	rb_link_node(&th->node, parent, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	rb_insert_color(&th->node, &xi->ticket_handlers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	return th;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static void remove_ticket_handler(struct ceph_auth_client *ac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 				  struct ceph_x_ticket_handler *th)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	struct ceph_x_info *xi = ac->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	dout("remove_ticket_handler %p %d\n", th, th->service);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	rb_erase(&th->node, &xi->ticket_handlers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	ceph_crypto_key_destroy(&th->session_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	if (th->ticket_blob)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		ceph_buffer_put(th->ticket_blob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	kfree(th);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static int process_one_ticket(struct ceph_auth_client *ac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 			      struct ceph_crypto_key *secret,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 			      void **p, void *end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	struct ceph_x_info *xi = ac->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	int type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	u8 tkt_struct_v, blob_struct_v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	struct ceph_x_ticket_handler *th;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	void *dp, *dend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	int dlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	char is_enc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	struct timespec64 validity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	void *tp, *tpend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	void **ptp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	struct ceph_crypto_key new_session_key = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	struct ceph_buffer *new_ticket_blob;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	time64_t new_expires, new_renew_after;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	u64 new_secret_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	ceph_decode_need(p, end, sizeof(u32) + 1, bad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	type = ceph_decode_32(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	dout(" ticket type %d %s\n", type, ceph_entity_type_name(type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	tkt_struct_v = ceph_decode_8(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	if (tkt_struct_v != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	th = get_ticket_handler(ac, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	if (IS_ERR(th)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 		ret = PTR_ERR(th);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	/* blob for me */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	dp = *p + ceph_x_encrypt_offset();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	ret = ceph_x_decrypt(secret, p, end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	dout(" decrypted %d bytes\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	dend = dp + ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	tkt_struct_v = ceph_decode_8(&dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	if (tkt_struct_v != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	ret = ceph_crypto_key_decode(&new_session_key, &dp, dend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	ceph_decode_timespec64(&validity, dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	dp += sizeof(struct ceph_timespec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	new_expires = ktime_get_real_seconds() + validity.tv_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	new_renew_after = new_expires - (validity.tv_sec / 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	dout(" expires=%llu renew_after=%llu\n", new_expires,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	     new_renew_after);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	/* ticket blob for service */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	ceph_decode_8_safe(p, end, is_enc, bad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	if (is_enc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		/* encrypted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		tp = *p + ceph_x_encrypt_offset();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		ret = ceph_x_decrypt(&th->session_key, p, end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		dout(" encrypted ticket, decrypted %d bytes\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		ptp = &tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		tpend = tp + ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		/* unencrypted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		ptp = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		tpend = end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	ceph_decode_32_safe(ptp, tpend, dlen, bad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	dout(" ticket blob is %d bytes\n", dlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	ceph_decode_need(ptp, tpend, 1 + sizeof(u64), bad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	blob_struct_v = ceph_decode_8(ptp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	if (blob_struct_v != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	new_secret_id = ceph_decode_64(ptp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	ret = ceph_decode_buffer(&new_ticket_blob, ptp, tpend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	/* all is well, update our ticket */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	ceph_crypto_key_destroy(&th->session_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	if (th->ticket_blob)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		ceph_buffer_put(th->ticket_blob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	th->session_key = new_session_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	th->ticket_blob = new_ticket_blob;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	th->secret_id = new_secret_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	th->expires = new_expires;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	th->renew_after = new_renew_after;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	th->have_key = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	dout(" got ticket service %d (%s) secret_id %lld len %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	     type, ceph_entity_type_name(type), th->secret_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	     (int)th->ticket_blob->vec.iov_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	xi->have_keys |= th->service;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) bad:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	ceph_crypto_key_destroy(&new_session_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 				    struct ceph_crypto_key *secret,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 				    void *buf, void *end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	void *p = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	u8 reply_struct_v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	u32 num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	ceph_decode_8_safe(&p, end, reply_struct_v, bad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	if (reply_struct_v != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	ceph_decode_32_safe(&p, end, num, bad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	dout("%d tickets\n", num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	while (num--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		ret = process_one_ticket(ac, secret, &p, end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) bad:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)  * Encode and encrypt the second part (ceph_x_authorize_b) of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)  * authorizer.  The first part (ceph_x_authorize_a) should already be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)  * encoded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) static int encrypt_authorizer(struct ceph_x_authorizer *au,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 			      u64 *server_challenge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	struct ceph_x_authorize_a *msg_a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	struct ceph_x_authorize_b *msg_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	void *p, *end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	msg_a = au->buf->vec.iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	WARN_ON(msg_a->ticket_blob.secret_id != cpu_to_le64(au->secret_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	p = (void *)(msg_a + 1) + le32_to_cpu(msg_a->ticket_blob.blob_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	end = au->buf->vec.iov_base + au->buf->vec.iov_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	msg_b = p + ceph_x_encrypt_offset();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	msg_b->struct_v = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	msg_b->nonce = cpu_to_le64(au->nonce);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	if (server_challenge) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 		msg_b->have_challenge = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		msg_b->server_challenge_plus_one =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 		    cpu_to_le64(*server_challenge + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		msg_b->have_challenge = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		msg_b->server_challenge_plus_one = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	ret = ceph_x_encrypt(&au->session_key, p, end - p, sizeof(*msg_b));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	p += ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	if (server_challenge) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		WARN_ON(p != end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 		WARN_ON(p > end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 		au->buf->vec.iov_len = p - au->buf->vec.iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static void ceph_x_authorizer_cleanup(struct ceph_x_authorizer *au)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	ceph_crypto_key_destroy(&au->session_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	if (au->buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		ceph_buffer_put(au->buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 		au->buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) static int ceph_x_build_authorizer(struct ceph_auth_client *ac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 				   struct ceph_x_ticket_handler *th,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 				   struct ceph_x_authorizer *au)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	int maxlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	struct ceph_x_authorize_a *msg_a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	struct ceph_x_authorize_b *msg_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	int ticket_blob_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 		(th->ticket_blob ? th->ticket_blob->vec.iov_len : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	dout("build_authorizer for %s %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	     ceph_entity_type_name(th->service), au);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	ceph_crypto_key_destroy(&au->session_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	ret = ceph_crypto_key_clone(&au->session_key, &th->session_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 		goto out_au;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	maxlen = sizeof(*msg_a) + ticket_blob_len +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 		ceph_x_encrypt_buflen(sizeof(*msg_b));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	dout("  need len %d\n", maxlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	if (au->buf && au->buf->alloc_len < maxlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 		ceph_buffer_put(au->buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 		au->buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	if (!au->buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 		au->buf = ceph_buffer_new(maxlen, GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		if (!au->buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 			ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 			goto out_au;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	au->service = th->service;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	au->secret_id = th->secret_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	msg_a = au->buf->vec.iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	msg_a->struct_v = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	msg_a->global_id = cpu_to_le64(ac->global_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	msg_a->service_id = cpu_to_le32(th->service);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	msg_a->ticket_blob.struct_v = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	msg_a->ticket_blob.secret_id = cpu_to_le64(th->secret_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	msg_a->ticket_blob.blob_len = cpu_to_le32(ticket_blob_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	if (ticket_blob_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 		memcpy(msg_a->ticket_blob.blob, th->ticket_blob->vec.iov_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 		       th->ticket_blob->vec.iov_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	dout(" th %p secret_id %lld %lld\n", th, th->secret_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	     le64_to_cpu(msg_a->ticket_blob.secret_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	get_random_bytes(&au->nonce, sizeof(au->nonce));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	ret = encrypt_authorizer(au, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 		pr_err("failed to encrypt authorizer: %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 		goto out_au;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	dout(" built authorizer nonce %llx len %d\n", au->nonce,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	     (int)au->buf->vec.iov_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) out_au:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	ceph_x_authorizer_cleanup(au);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) static int ceph_x_encode_ticket(struct ceph_x_ticket_handler *th,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 				void **p, void *end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	ceph_decode_need(p, end, 1 + sizeof(u64), bad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	ceph_encode_8(p, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	ceph_encode_64(p, th->secret_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	if (th->ticket_blob) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 		const char *buf = th->ticket_blob->vec.iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 		u32 len = th->ticket_blob->vec.iov_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 		ceph_encode_32_safe(p, end, len, bad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 		ceph_encode_copy_safe(p, end, buf, len, bad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 		ceph_encode_32_safe(p, end, 0, bad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) bad:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) static bool need_key(struct ceph_x_ticket_handler *th)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	if (!th->have_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	return ktime_get_real_seconds() >= th->renew_after;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) static bool have_key(struct ceph_x_ticket_handler *th)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	if (th->have_key) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 		if (ktime_get_real_seconds() >= th->expires)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 			th->have_key = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	return th->have_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) static void ceph_x_validate_tickets(struct ceph_auth_client *ac, int *pneed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	int want = ac->want_keys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	struct ceph_x_info *xi = ac->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	int service;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	*pneed = ac->want_keys & ~(xi->have_keys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	for (service = 1; service <= want; service <<= 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 		struct ceph_x_ticket_handler *th;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 		if (!(ac->want_keys & service))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 		if (*pneed & service)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 		th = get_ticket_handler(ac, service);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 		if (IS_ERR(th)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 			*pneed |= service;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 		if (need_key(th))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 			*pneed |= service;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 		if (!have_key(th))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 			xi->have_keys &= ~service;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) static int ceph_x_build_request(struct ceph_auth_client *ac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 				void *buf, void *end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	struct ceph_x_info *xi = ac->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	int need;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	struct ceph_x_request_header *head = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	struct ceph_x_ticket_handler *th =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 		get_ticket_handler(ac, CEPH_ENTITY_TYPE_AUTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	if (IS_ERR(th))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 		return PTR_ERR(th);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	ceph_x_validate_tickets(ac, &need);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	dout("build_request want %x have %x need %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	     ac->want_keys, xi->have_keys, need);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	if (need & CEPH_ENTITY_TYPE_AUTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 		struct ceph_x_authenticate *auth = (void *)(head + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 		void *p = auth + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 		void *enc_buf = xi->auth_authorizer.enc_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 		struct ceph_x_challenge_blob *blob = enc_buf +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 							ceph_x_encrypt_offset();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 		u64 *u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 		if (p > end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 			return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 		dout(" get_auth_session_key\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 		head->op = cpu_to_le16(CEPHX_GET_AUTH_SESSION_KEY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 		/* encrypt and hash */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 		get_random_bytes(&auth->client_challenge, sizeof(u64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 		blob->client_challenge = auth->client_challenge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 		blob->server_challenge = cpu_to_le64(xi->server_challenge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 		ret = ceph_x_encrypt(&xi->secret, enc_buf, CEPHX_AU_ENC_BUF_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 				     sizeof(*blob));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 		auth->struct_v = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 		auth->key = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 		for (u = (u64 *)enc_buf; u + 1 <= (u64 *)(enc_buf + ret); u++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 			auth->key ^= *(__le64 *)u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 		dout(" server_challenge %llx client_challenge %llx key %llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 		     xi->server_challenge, le64_to_cpu(auth->client_challenge),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 		     le64_to_cpu(auth->key));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 		/* now encode the old ticket if exists */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 		ret = ceph_x_encode_ticket(th, &p, end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 		return p - buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	if (need) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 		void *p = head + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 		struct ceph_x_service_ticket_request *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 		if (p > end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 			return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 		head->op = cpu_to_le16(CEPHX_GET_PRINCIPAL_SESSION_KEY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 		ret = ceph_x_build_authorizer(ac, th, &xi->auth_authorizer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 		ceph_encode_copy(&p, xi->auth_authorizer.buf->vec.iov_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 				 xi->auth_authorizer.buf->vec.iov_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 		req = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 		req->keys = cpu_to_le32(need);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 		p += sizeof(*req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 		return p - buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) static int ceph_x_handle_reply(struct ceph_auth_client *ac, int result,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 			       void *buf, void *end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	struct ceph_x_info *xi = ac->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	struct ceph_x_reply_header *head = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	struct ceph_x_ticket_handler *th;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	int len = end - buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 	int op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 	if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 		return result;  /* XXX hmm? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 	if (xi->starting) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 		/* it's a hello */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 		struct ceph_x_server_challenge *sc = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 		if (len != sizeof(*sc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 		xi->server_challenge = le64_to_cpu(sc->server_challenge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 		dout("handle_reply got server challenge %llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 		     xi->server_challenge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 		xi->starting = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 		xi->have_keys &= ~CEPH_ENTITY_TYPE_AUTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 		return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	op = le16_to_cpu(head->op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	result = le32_to_cpu(head->result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	dout("handle_reply op %d result %d\n", op, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	switch (op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	case CEPHX_GET_AUTH_SESSION_KEY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 		/* verify auth key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 		ret = ceph_x_proc_ticket_reply(ac, &xi->secret,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 					       buf + sizeof(*head), end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	case CEPHX_GET_PRINCIPAL_SESSION_KEY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 		th = get_ticket_handler(ac, CEPH_ENTITY_TYPE_AUTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 		if (IS_ERR(th))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 			return PTR_ERR(th);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 		ret = ceph_x_proc_ticket_reply(ac, &th->session_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 					       buf + sizeof(*head), end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	if (ac->want_keys == xi->have_keys)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 	return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) static void ceph_x_destroy_authorizer(struct ceph_authorizer *a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 	struct ceph_x_authorizer *au = (void *)a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 	ceph_x_authorizer_cleanup(au);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 	kfree(au);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) static int ceph_x_create_authorizer(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 	struct ceph_auth_client *ac, int peer_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 	struct ceph_auth_handshake *auth)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	struct ceph_x_authorizer *au;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	struct ceph_x_ticket_handler *th;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	th = get_ticket_handler(ac, peer_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 	if (IS_ERR(th))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 		return PTR_ERR(th);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 	au = kzalloc(sizeof(*au), GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	if (!au)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 	au->base.destroy = ceph_x_destroy_authorizer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	ret = ceph_x_build_authorizer(ac, th, au);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 		kfree(au);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 	auth->authorizer = (struct ceph_authorizer *) au;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 	auth->authorizer_buf = au->buf->vec.iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 	auth->authorizer_buf_len = au->buf->vec.iov_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 	auth->authorizer_reply_buf = au->enc_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 	auth->authorizer_reply_buf_len = CEPHX_AU_ENC_BUF_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 	auth->sign_message = ac->ops->sign_message;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 	auth->check_message_signature = ac->ops->check_message_signature;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) static int ceph_x_update_authorizer(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	struct ceph_auth_client *ac, int peer_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 	struct ceph_auth_handshake *auth)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 	struct ceph_x_authorizer *au;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 	struct ceph_x_ticket_handler *th;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 	th = get_ticket_handler(ac, peer_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 	if (IS_ERR(th))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 		return PTR_ERR(th);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 	au = (struct ceph_x_authorizer *)auth->authorizer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 	if (au->secret_id < th->secret_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 		dout("ceph_x_update_authorizer service %u secret %llu < %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 		     au->service, au->secret_id, th->secret_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 		return ceph_x_build_authorizer(ac, th, au);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) static int decrypt_authorize_challenge(struct ceph_x_authorizer *au,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 				       void *challenge_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 				       int challenge_buf_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 				       u64 *server_challenge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 	struct ceph_x_authorize_challenge *ch =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 	    challenge_buf + sizeof(struct ceph_x_encrypt_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 	/* no leading len */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 	ret = __ceph_x_decrypt(&au->session_key, challenge_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 			       challenge_buf_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 	if (ret < sizeof(*ch)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 		pr_err("bad size %d for ceph_x_authorize_challenge\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 	*server_challenge = le64_to_cpu(ch->server_challenge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) static int ceph_x_add_authorizer_challenge(struct ceph_auth_client *ac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 					   struct ceph_authorizer *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 					   void *challenge_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 					   int challenge_buf_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 	struct ceph_x_authorizer *au = (void *)a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 	u64 server_challenge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 	ret = decrypt_authorize_challenge(au, challenge_buf, challenge_buf_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 					  &server_challenge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 		pr_err("failed to decrypt authorize challenge: %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 	ret = encrypt_authorizer(au, &server_challenge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 		pr_err("failed to encrypt authorizer w/ challenge: %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) static int ceph_x_verify_authorizer_reply(struct ceph_auth_client *ac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 					  struct ceph_authorizer *a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 	struct ceph_x_authorizer *au = (void *)a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 	void *p = au->enc_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 	struct ceph_x_authorize_reply *reply = p + ceph_x_encrypt_offset();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	ret = ceph_x_decrypt(&au->session_key, &p, p + CEPHX_AU_ENC_BUF_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 	if (ret < sizeof(*reply)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 		pr_err("bad size %d for ceph_x_authorize_reply\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 	if (au->nonce + 1 != le64_to_cpu(reply->nonce_plus_one))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 		ret = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 		ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 	dout("verify_authorizer_reply nonce %llx got %llx ret %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 	     au->nonce, le64_to_cpu(reply->nonce_plus_one), ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) static void ceph_x_reset(struct ceph_auth_client *ac)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 	struct ceph_x_info *xi = ac->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 	dout("reset\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 	xi->starting = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 	xi->server_challenge = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) static void ceph_x_destroy(struct ceph_auth_client *ac)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 	struct ceph_x_info *xi = ac->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 	struct rb_node *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 	dout("ceph_x_destroy %p\n", ac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 	ceph_crypto_key_destroy(&xi->secret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 	while ((p = rb_first(&xi->ticket_handlers)) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 		struct ceph_x_ticket_handler *th =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 			rb_entry(p, struct ceph_x_ticket_handler, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 		remove_ticket_handler(ac, th);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 	ceph_x_authorizer_cleanup(&xi->auth_authorizer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 	kfree(ac->private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 	ac->private = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) static void invalidate_ticket(struct ceph_auth_client *ac, int peer_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 	struct ceph_x_ticket_handler *th;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 	th = get_ticket_handler(ac, peer_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 	if (!IS_ERR(th))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 		th->have_key = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) static void ceph_x_invalidate_authorizer(struct ceph_auth_client *ac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) 					 int peer_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 	 * We are to invalidate a service ticket in the hopes of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 	 * getting a new, hopefully more valid, one.  But, we won't get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 	 * it unless our AUTH ticket is good, so invalidate AUTH ticket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 	 * as well, just in case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 	invalidate_ticket(ac, peer_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 	invalidate_ticket(ac, CEPH_ENTITY_TYPE_AUTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) static int calc_signature(struct ceph_x_authorizer *au, struct ceph_msg *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 			  __le64 *psig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 	void *enc_buf = au->enc_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 	if (!CEPH_HAVE_FEATURE(msg->con->peer_features, CEPHX_V2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 		struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 			__le32 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 			__le32 header_crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 			__le32 front_crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 			__le32 middle_crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 			__le32 data_crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) 		} __packed *sigblock = enc_buf + ceph_x_encrypt_offset();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 		sigblock->len = cpu_to_le32(4*sizeof(u32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 		sigblock->header_crc = msg->hdr.crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) 		sigblock->front_crc = msg->footer.front_crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) 		sigblock->middle_crc = msg->footer.middle_crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) 		sigblock->data_crc =  msg->footer.data_crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 		ret = ceph_x_encrypt(&au->session_key, enc_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) 				     CEPHX_AU_ENC_BUF_LEN, sizeof(*sigblock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) 		*psig = *(__le64 *)(enc_buf + sizeof(u32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 		struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) 			__le32 header_crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) 			__le32 front_crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) 			__le32 front_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) 			__le32 middle_crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) 			__le32 middle_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) 			__le32 data_crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) 			__le32 data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) 			__le32 seq_lower_word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 		} __packed *sigblock = enc_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) 		struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) 			__le64 a, b, c, d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) 		} __packed *penc = enc_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) 		int ciphertext_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) 		sigblock->header_crc = msg->hdr.crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) 		sigblock->front_crc = msg->footer.front_crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) 		sigblock->front_len = msg->hdr.front_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) 		sigblock->middle_crc = msg->footer.middle_crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) 		sigblock->middle_len = msg->hdr.middle_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) 		sigblock->data_crc =  msg->footer.data_crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) 		sigblock->data_len = msg->hdr.data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) 		sigblock->seq_lower_word = *(__le32 *)&msg->hdr.seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) 		/* no leading len, no ceph_x_encrypt_header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) 		ret = ceph_crypt(&au->session_key, true, enc_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) 				 CEPHX_AU_ENC_BUF_LEN, sizeof(*sigblock),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) 				 &ciphertext_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) 		*psig = penc->a ^ penc->b ^ penc->c ^ penc->d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) static int ceph_x_sign_message(struct ceph_auth_handshake *auth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) 			       struct ceph_msg *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) 	__le64 sig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) 	if (ceph_test_opt(from_msgr(msg->con->msgr), NOMSGSIGN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) 	ret = calc_signature((struct ceph_x_authorizer *)auth->authorizer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) 			     msg, &sig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) 	msg->footer.sig = sig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) 	msg->footer.flags |= CEPH_MSG_FOOTER_SIGNED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) static int ceph_x_check_message_signature(struct ceph_auth_handshake *auth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) 					  struct ceph_msg *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) 	__le64 sig_check;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) 	if (ceph_test_opt(from_msgr(msg->con->msgr), NOMSGSIGN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) 	ret = calc_signature((struct ceph_x_authorizer *)auth->authorizer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) 			     msg, &sig_check);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) 	if (sig_check == msg->footer.sig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) 	if (msg->footer.flags & CEPH_MSG_FOOTER_SIGNED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) 		dout("ceph_x_check_message_signature %p has signature %llx "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) 		     "expect %llx\n", msg, msg->footer.sig, sig_check);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) 		dout("ceph_x_check_message_signature %p sender did not set "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) 		     "CEPH_MSG_FOOTER_SIGNED\n", msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) 	return -EBADMSG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) static const struct ceph_auth_client_ops ceph_x_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) 	.name = "x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) 	.is_authenticated = ceph_x_is_authenticated,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) 	.should_authenticate = ceph_x_should_authenticate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) 	.build_request = ceph_x_build_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) 	.handle_reply = ceph_x_handle_reply,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) 	.create_authorizer = ceph_x_create_authorizer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) 	.update_authorizer = ceph_x_update_authorizer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) 	.add_authorizer_challenge = ceph_x_add_authorizer_challenge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) 	.verify_authorizer_reply = ceph_x_verify_authorizer_reply,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) 	.invalidate_authorizer = ceph_x_invalidate_authorizer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) 	.reset =  ceph_x_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) 	.destroy = ceph_x_destroy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) 	.sign_message = ceph_x_sign_message,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) 	.check_message_signature = ceph_x_check_message_signature,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) int ceph_x_init(struct ceph_auth_client *ac)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) 	struct ceph_x_info *xi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) 	dout("ceph_x_init %p\n", ac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) 	ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) 	xi = kzalloc(sizeof(*xi), GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) 	if (!xi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) 	ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) 	if (!ac->key) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) 		pr_err("no secret set (for auth_x protocol)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) 		goto out_nomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) 	ret = ceph_crypto_key_clone(&xi->secret, ac->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) 		pr_err("cannot clone key: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) 		goto out_nomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) 	xi->starting = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) 	xi->ticket_handlers = RB_ROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) 	ac->protocol = CEPH_AUTH_CEPHX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) 	ac->private = xi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) 	ac->ops = &ceph_x_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) out_nomem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) 	kfree(xi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) }