Blame view

net/ceph/auth.c 7.87 KB
b24413180   Greg Kroah-Hartman   License cleanup: ...
1
  // SPDX-License-Identifier: GPL-2.0
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
2
  #include <linux/ceph/ceph_debug.h>
4e7a5dcd1   Sage Weil   ceph: negotiate a...
3
4
5
  
  #include <linux/module.h>
  #include <linux/err.h>
d45d0d970   Sage Weil   ceph: add missing...
6
  #include <linux/slab.h>
4e7a5dcd1   Sage Weil   ceph: negotiate a...
7

3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
8
9
10
11
  #include <linux/ceph/types.h>
  #include <linux/ceph/decode.h>
  #include <linux/ceph/libceph.h>
  #include <linux/ceph/messenger.h>
4e7a5dcd1   Sage Weil   ceph: negotiate a...
12
  #include "auth_none.h"
ec0994e48   Sage Weil   ceph: add support...
13
  #include "auth_x.h"
4e7a5dcd1   Sage Weil   ceph: negotiate a...
14

4e7a5dcd1   Sage Weil   ceph: negotiate a...
15
16
17
18
19
  
  /*
   * get protocol handler
   */
  static u32 supported_protocols[] = {
ec0994e48   Sage Weil   ceph: add support...
20
21
  	CEPH_AUTH_NONE,
  	CEPH_AUTH_CEPHX
4e7a5dcd1   Sage Weil   ceph: negotiate a...
22
  };
cd84db6e4   Yehuda Sadeh   ceph: code cleanup
23
  static int ceph_auth_init_protocol(struct ceph_auth_client *ac, int protocol)
4e7a5dcd1   Sage Weil   ceph: negotiate a...
24
25
26
27
  {
  	switch (protocol) {
  	case CEPH_AUTH_NONE:
  		return ceph_auth_none_init(ac);
ec0994e48   Sage Weil   ceph: add support...
28
29
  	case CEPH_AUTH_CEPHX:
  		return ceph_x_init(ac);
4e7a5dcd1   Sage Weil   ceph: negotiate a...
30
31
32
33
34
35
36
37
  	default:
  		return -ENOENT;
  	}
  }
  
  /*
   * setup, teardown.
   */
8323c3aa7   Tommi Virtanen   ceph: Move secret...
38
  struct ceph_auth_client *ceph_auth_init(const char *name, const struct ceph_crypto_key *key)
4e7a5dcd1   Sage Weil   ceph: negotiate a...
39
40
41
  {
  	struct ceph_auth_client *ac;
  	int ret;
8323c3aa7   Tommi Virtanen   ceph: Move secret...
42
43
  	dout("auth_init name '%s'
  ", name);
4e7a5dcd1   Sage Weil   ceph: negotiate a...
44
45
46
47
48
  
  	ret = -ENOMEM;
  	ac = kzalloc(sizeof(*ac), GFP_NOFS);
  	if (!ac)
  		goto out;
e9966076c   Sage Weil   libceph: wrap aut...
49
  	mutex_init(&ac->mutex);
4e7a5dcd1   Sage Weil   ceph: negotiate a...
50
51
52
53
54
  	ac->negotiating = true;
  	if (name)
  		ac->name = name;
  	else
  		ac->name = CEPH_AUTH_NAME_DEFAULT;
8323c3aa7   Tommi Virtanen   ceph: Move secret...
55
56
57
  	dout("auth_init name %s
  ", ac->name);
  	ac->key = key;
4e7a5dcd1   Sage Weil   ceph: negotiate a...
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
  	return ac;
  
  out:
  	return ERR_PTR(ret);
  }
  
  void ceph_auth_destroy(struct ceph_auth_client *ac)
  {
  	dout("auth_destroy %p
  ", ac);
  	if (ac->ops)
  		ac->ops->destroy(ac);
  	kfree(ac);
  }
  
  /*
   * Reset occurs when reconnecting to the monitor.
   */
  void ceph_auth_reset(struct ceph_auth_client *ac)
  {
e9966076c   Sage Weil   libceph: wrap aut...
78
  	mutex_lock(&ac->mutex);
4e7a5dcd1   Sage Weil   ceph: negotiate a...
79
80
81
82
83
  	dout("auth_reset %p
  ", ac);
  	if (ac->ops && !ac->negotiating)
  		ac->ops->reset(ac);
  	ac->negotiating = true;
e9966076c   Sage Weil   libceph: wrap aut...
84
  	mutex_unlock(&ac->mutex);
4e7a5dcd1   Sage Weil   ceph: negotiate a...
85
  }
f01d5cb24   Ilya Dryomov   libceph: rename c...
86
87
88
89
  /*
   * EntityName, not to be confused with entity_name_t
   */
  int ceph_auth_entity_name_encode(const char *name, void **p, void *end)
4e7a5dcd1   Sage Weil   ceph: negotiate a...
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
  {
  	int len = strlen(name);
  
  	if (*p + 2*sizeof(u32) + len > end)
  		return -ERANGE;
  	ceph_encode_32(p, CEPH_ENTITY_TYPE_CLIENT);
  	ceph_encode_32(p, len);
  	ceph_encode_copy(p, name, len);
  	return 0;
  }
  
  /*
   * Initiate protocol negotiation with monitor.  Include entity name
   * and list supported protocols.
   */
  int ceph_auth_build_hello(struct ceph_auth_client *ac, void *buf, size_t len)
  {
  	struct ceph_mon_request_header *monhdr = buf;
  	void *p = monhdr + 1, *end = buf + len, *lenp;
  	int i, num;
  	int ret;
e9966076c   Sage Weil   libceph: wrap aut...
111
  	mutex_lock(&ac->mutex);
4e7a5dcd1   Sage Weil   ceph: negotiate a...
112
113
114
115
116
  	dout("auth_build_hello
  ");
  	monhdr->have_version = 0;
  	monhdr->session_mon = cpu_to_le16(-1);
  	monhdr->session_mon_tid = 0;
fdc723e77   Ilya Dryomov   libceph: use CEPH...
117
  	ceph_encode_32(&p, CEPH_AUTH_UNKNOWN);  /* no protocol, yet */
4e7a5dcd1   Sage Weil   ceph: negotiate a...
118
119
120
  
  	lenp = p;
  	p += sizeof(u32);
07c8739c5   Sage Weil   ceph: add struct ...
121
122
  	ceph_decode_need(&p, end, 1 + sizeof(u32), bad);
  	ceph_encode_8(&p, 1);
4e7a5dcd1   Sage Weil   ceph: negotiate a...
123
124
  	num = ARRAY_SIZE(supported_protocols);
  	ceph_encode_32(&p, num);
07c8739c5   Sage Weil   ceph: add struct ...
125
  	ceph_decode_need(&p, end, num * sizeof(u32), bad);
4e7a5dcd1   Sage Weil   ceph: negotiate a...
126
127
  	for (i = 0; i < num; i++)
  		ceph_encode_32(&p, supported_protocols[i]);
f01d5cb24   Ilya Dryomov   libceph: rename c...
128
  	ret = ceph_auth_entity_name_encode(ac->name, &p, end);
4e7a5dcd1   Sage Weil   ceph: negotiate a...
129
  	if (ret < 0)
e9966076c   Sage Weil   libceph: wrap aut...
130
  		goto out;
4e7a5dcd1   Sage Weil   ceph: negotiate a...
131
132
133
134
  	ceph_decode_need(&p, end, sizeof(u64), bad);
  	ceph_encode_64(&p, ac->global_id);
  
  	ceph_encode_32(&lenp, p - lenp - sizeof(u32));
e9966076c   Sage Weil   libceph: wrap aut...
135
136
137
138
  	ret = p - buf;
  out:
  	mutex_unlock(&ac->mutex);
  	return ret;
4e7a5dcd1   Sage Weil   ceph: negotiate a...
139
140
  
  bad:
e9966076c   Sage Weil   libceph: wrap aut...
141
142
  	ret = -ERANGE;
  	goto out;
4e7a5dcd1   Sage Weil   ceph: negotiate a...
143
  }
cd84db6e4   Yehuda Sadeh   ceph: code cleanup
144
145
  static int ceph_build_auth_request(struct ceph_auth_client *ac,
  				   void *msg_buf, size_t msg_len)
9bd2e6f8b   Sage Weil   ceph: allow renew...
146
147
148
149
150
151
152
153
154
155
156
157
158
159
  {
  	struct ceph_mon_request_header *monhdr = msg_buf;
  	void *p = monhdr + 1;
  	void *end = msg_buf + msg_len;
  	int ret;
  
  	monhdr->have_version = 0;
  	monhdr->session_mon = cpu_to_le16(-1);
  	monhdr->session_mon_tid = 0;
  
  	ceph_encode_32(&p, ac->protocol);
  
  	ret = ac->ops->build_request(ac, p + sizeof(u32), end);
  	if (ret < 0) {
559c1e007   Sage Weil   ceph: include aut...
160
161
162
  		pr_err("error %d building auth method %s request
  ", ret,
  		       ac->ops->name);
e9966076c   Sage Weil   libceph: wrap aut...
163
  		goto out;
9bd2e6f8b   Sage Weil   ceph: allow renew...
164
165
166
167
  	}
  	dout(" built request %d bytes
  ", ret);
  	ceph_encode_32(&p, ret);
e9966076c   Sage Weil   libceph: wrap aut...
168
169
170
  	ret = p + ret - msg_buf;
  out:
  	return ret;
9bd2e6f8b   Sage Weil   ceph: allow renew...
171
  }
4e7a5dcd1   Sage Weil   ceph: negotiate a...
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
  /*
   * Handle auth message from monitor.
   */
  int ceph_handle_auth_reply(struct ceph_auth_client *ac,
  			   void *buf, size_t len,
  			   void *reply_buf, size_t reply_len)
  {
  	void *p = buf;
  	void *end = buf + len;
  	int protocol;
  	s32 result;
  	u64 global_id;
  	void *payload, *payload_end;
  	int payload_len;
  	char *result_msg;
  	int result_msg_len;
  	int ret = -EINVAL;
e9966076c   Sage Weil   libceph: wrap aut...
189
  	mutex_lock(&ac->mutex);
4e7a5dcd1   Sage Weil   ceph: negotiate a...
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
  	dout("handle_auth_reply %p %p
  ", p, end);
  	ceph_decode_need(&p, end, sizeof(u32) * 3 + sizeof(u64), bad);
  	protocol = ceph_decode_32(&p);
  	result = ceph_decode_32(&p);
  	global_id = ceph_decode_64(&p);
  	payload_len = ceph_decode_32(&p);
  	payload = p;
  	p += payload_len;
  	ceph_decode_need(&p, end, sizeof(u32), bad);
  	result_msg_len = ceph_decode_32(&p);
  	result_msg = p;
  	p += result_msg_len;
  	if (p != end)
  		goto bad;
  
  	dout(" result %d '%.*s' gid %llu len %d
  ", result, result_msg_len,
  	     result_msg, global_id, payload_len);
  
  	payload_end = payload + payload_len;
  
  	if (global_id && ac->global_id != global_id) {
  		dout(" set global_id %lld -> %lld
  ", ac->global_id, global_id);
  		ac->global_id = global_id;
  	}
  
  	if (ac->negotiating) {
dc14657c9   Yehuda Sadeh   ceph: mount fails...
219
220
221
222
223
  		/* server does not support our protocols? */
  		if (!protocol && result < 0) {
  			ret = result;
  			goto out;
  		}
4e7a5dcd1   Sage Weil   ceph: negotiate a...
224
225
226
227
228
229
230
231
232
  		/* set up (new) protocol handler? */
  		if (ac->protocol && ac->protocol != protocol) {
  			ac->ops->destroy(ac);
  			ac->protocol = 0;
  			ac->ops = NULL;
  		}
  		if (ac->protocol != protocol) {
  			ret = ceph_auth_init_protocol(ac, protocol);
  			if (ret) {
e95e9a7ae   Sage Weil   ceph: avoid possi...
233
234
235
  				pr_err("error %d on auth protocol %d init
  ",
  				       ret, protocol);
4e7a5dcd1   Sage Weil   ceph: negotiate a...
236
237
238
  				goto out;
  			}
  		}
9bd2e6f8b   Sage Weil   ceph: allow renew...
239
240
  
  		ac->negotiating = false;
4e7a5dcd1   Sage Weil   ceph: negotiate a...
241
242
243
244
  	}
  
  	ret = ac->ops->handle_reply(ac, result, payload, payload_end);
  	if (ret == -EAGAIN) {
e9966076c   Sage Weil   libceph: wrap aut...
245
  		ret = ceph_build_auth_request(ac, reply_buf, reply_len);
4e7a5dcd1   Sage Weil   ceph: negotiate a...
246
  	} else if (ret) {
559c1e007   Sage Weil   ceph: include aut...
247
248
  		pr_err("auth method '%s' error %d
  ", ac->ops->name, ret);
4e7a5dcd1   Sage Weil   ceph: negotiate a...
249
  	}
4e7a5dcd1   Sage Weil   ceph: negotiate a...
250

4e7a5dcd1   Sage Weil   ceph: negotiate a...
251
  out:
e9966076c   Sage Weil   libceph: wrap aut...
252
  	mutex_unlock(&ac->mutex);
4e7a5dcd1   Sage Weil   ceph: negotiate a...
253
  	return ret;
e9966076c   Sage Weil   libceph: wrap aut...
254
255
256
257
258
259
  
  bad:
  	pr_err("failed to decode auth msg
  ");
  	ret = -EINVAL;
  	goto out;
4e7a5dcd1   Sage Weil   ceph: negotiate a...
260
  }
9bd2e6f8b   Sage Weil   ceph: allow renew...
261
262
263
  int ceph_build_auth(struct ceph_auth_client *ac,
  		    void *msg_buf, size_t msg_len)
  {
e9966076c   Sage Weil   libceph: wrap aut...
264
265
266
  	int ret = 0;
  
  	mutex_lock(&ac->mutex);
464691bd5   Ilya Dryomov   libceph: ceph_bui...
267
  	if (ac->ops->should_authenticate(ac))
e9966076c   Sage Weil   libceph: wrap aut...
268
269
270
  		ret = ceph_build_auth_request(ac, msg_buf, msg_len);
  	mutex_unlock(&ac->mutex);
  	return ret;
9bd2e6f8b   Sage Weil   ceph: allow renew...
271
  }
4e7a5dcd1   Sage Weil   ceph: negotiate a...
272

9bd2e6f8b   Sage Weil   ceph: allow renew...
273
274
  int ceph_auth_is_authenticated(struct ceph_auth_client *ac)
  {
e9966076c   Sage Weil   libceph: wrap aut...
275
276
277
278
279
280
281
  	int ret = 0;
  
  	mutex_lock(&ac->mutex);
  	if (ac->ops)
  		ret = ac->ops->is_authenticated(ac);
  	mutex_unlock(&ac->mutex);
  	return ret;
9bd2e6f8b   Sage Weil   ceph: allow renew...
282
  }
27859f977   Sage Weil   libceph: wrap aut...
283
284
285
286
287
288
  EXPORT_SYMBOL(ceph_auth_is_authenticated);
  
  int ceph_auth_create_authorizer(struct ceph_auth_client *ac,
  				int peer_type,
  				struct ceph_auth_handshake *auth)
  {
e9966076c   Sage Weil   libceph: wrap aut...
289
290
291
  	int ret = 0;
  
  	mutex_lock(&ac->mutex);
27859f977   Sage Weil   libceph: wrap aut...
292
  	if (ac->ops && ac->ops->create_authorizer)
e9966076c   Sage Weil   libceph: wrap aut...
293
294
295
  		ret = ac->ops->create_authorizer(ac, peer_type, auth);
  	mutex_unlock(&ac->mutex);
  	return ret;
27859f977   Sage Weil   libceph: wrap aut...
296
297
  }
  EXPORT_SYMBOL(ceph_auth_create_authorizer);
6c1ea260f   Ilya Dryomov   libceph: make aut...
298
  void ceph_auth_destroy_authorizer(struct ceph_authorizer *a)
27859f977   Sage Weil   libceph: wrap aut...
299
  {
6c1ea260f   Ilya Dryomov   libceph: make aut...
300
  	a->destroy(a);
27859f977   Sage Weil   libceph: wrap aut...
301
302
303
304
305
306
307
308
  }
  EXPORT_SYMBOL(ceph_auth_destroy_authorizer);
  
  int ceph_auth_update_authorizer(struct ceph_auth_client *ac,
  				int peer_type,
  				struct ceph_auth_handshake *a)
  {
  	int ret = 0;
e9966076c   Sage Weil   libceph: wrap aut...
309
  	mutex_lock(&ac->mutex);
27859f977   Sage Weil   libceph: wrap aut...
310
311
  	if (ac->ops && ac->ops->update_authorizer)
  		ret = ac->ops->update_authorizer(ac, peer_type, a);
e9966076c   Sage Weil   libceph: wrap aut...
312
  	mutex_unlock(&ac->mutex);
27859f977   Sage Weil   libceph: wrap aut...
313
314
315
  	return ret;
  }
  EXPORT_SYMBOL(ceph_auth_update_authorizer);
6daca13d2   Ilya Dryomov   libceph: add auth...
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
  int ceph_auth_add_authorizer_challenge(struct ceph_auth_client *ac,
  				       struct ceph_authorizer *a,
  				       void *challenge_buf,
  				       int challenge_buf_len)
  {
  	int ret = 0;
  
  	mutex_lock(&ac->mutex);
  	if (ac->ops && ac->ops->add_authorizer_challenge)
  		ret = ac->ops->add_authorizer_challenge(ac, a, challenge_buf,
  							challenge_buf_len);
  	mutex_unlock(&ac->mutex);
  	return ret;
  }
  EXPORT_SYMBOL(ceph_auth_add_authorizer_challenge);
27859f977   Sage Weil   libceph: wrap aut...
331
  int ceph_auth_verify_authorizer_reply(struct ceph_auth_client *ac,
0dde58488   Ilya Dryomov   libceph: drop len...
332
  				      struct ceph_authorizer *a)
27859f977   Sage Weil   libceph: wrap aut...
333
  {
e9966076c   Sage Weil   libceph: wrap aut...
334
335
336
  	int ret = 0;
  
  	mutex_lock(&ac->mutex);
27859f977   Sage Weil   libceph: wrap aut...
337
  	if (ac->ops && ac->ops->verify_authorizer_reply)
0dde58488   Ilya Dryomov   libceph: drop len...
338
  		ret = ac->ops->verify_authorizer_reply(ac, a);
e9966076c   Sage Weil   libceph: wrap aut...
339
340
  	mutex_unlock(&ac->mutex);
  	return ret;
27859f977   Sage Weil   libceph: wrap aut...
341
342
343
344
345
  }
  EXPORT_SYMBOL(ceph_auth_verify_authorizer_reply);
  
  void ceph_auth_invalidate_authorizer(struct ceph_auth_client *ac, int peer_type)
  {
e9966076c   Sage Weil   libceph: wrap aut...
346
  	mutex_lock(&ac->mutex);
27859f977   Sage Weil   libceph: wrap aut...
347
348
  	if (ac->ops && ac->ops->invalidate_authorizer)
  		ac->ops->invalidate_authorizer(ac, peer_type);
e9966076c   Sage Weil   libceph: wrap aut...
349
  	mutex_unlock(&ac->mutex);
27859f977   Sage Weil   libceph: wrap aut...
350
351
  }
  EXPORT_SYMBOL(ceph_auth_invalidate_authorizer);