root/net/ceph/auth.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ceph_auth_init_protocol
  2. ceph_auth_init
  3. ceph_auth_destroy
  4. ceph_auth_reset
  5. ceph_auth_entity_name_encode
  6. ceph_auth_build_hello
  7. ceph_build_auth_request
  8. ceph_handle_auth_reply
  9. ceph_build_auth
  10. ceph_auth_is_authenticated
  11. ceph_auth_create_authorizer
  12. ceph_auth_destroy_authorizer
  13. ceph_auth_update_authorizer
  14. ceph_auth_add_authorizer_challenge
  15. ceph_auth_verify_authorizer_reply
  16. ceph_auth_invalidate_authorizer

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

/* [<][>][^][v][top][bottom][index][help] */