^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) }