Blame view

net/ceph/auth.c 7.56 KB
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
1
  #include <linux/ceph/ceph_debug.h>
4e7a5dcd1   Sage Weil   ceph: negotiate a...
2
3
4
  
  #include <linux/module.h>
  #include <linux/err.h>
d45d0d970   Sage Weil   ceph: add missing...
5
  #include <linux/slab.h>
4e7a5dcd1   Sage Weil   ceph: negotiate a...
6

3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
7
8
9
10
  #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...
11
  #include "auth_none.h"
ec0994e48   Sage Weil   ceph: add support...
12
  #include "auth_x.h"
4e7a5dcd1   Sage Weil   ceph: negotiate a...
13

4e7a5dcd1   Sage Weil   ceph: negotiate a...
14
15
16
17
18
  
  /*
   * get protocol handler
   */
  static u32 supported_protocols[] = {
ec0994e48   Sage Weil   ceph: add support...
19
20
  	CEPH_AUTH_NONE,
  	CEPH_AUTH_CEPHX
4e7a5dcd1   Sage Weil   ceph: negotiate a...
21
  };
cd84db6e4   Yehuda Sadeh   ceph: code cleanup
22
  static int ceph_auth_init_protocol(struct ceph_auth_client *ac, int protocol)
4e7a5dcd1   Sage Weil   ceph: negotiate a...
23
24
25
26
  {
  	switch (protocol) {
  	case CEPH_AUTH_NONE:
  		return ceph_auth_none_init(ac);
ec0994e48   Sage Weil   ceph: add support...
27
28
  	case CEPH_AUTH_CEPHX:
  		return ceph_x_init(ac);
4e7a5dcd1   Sage Weil   ceph: negotiate a...
29
30
31
32
33
34
35
36
  	default:
  		return -ENOENT;
  	}
  }
  
  /*
   * setup, teardown.
   */
8323c3aa7   Tommi Virtanen   ceph: Move secret...
37
  struct ceph_auth_client *ceph_auth_init(const char *name, const struct ceph_crypto_key *key)
4e7a5dcd1   Sage Weil   ceph: negotiate a...
38
39
40
  {
  	struct ceph_auth_client *ac;
  	int ret;
8323c3aa7   Tommi Virtanen   ceph: Move secret...
41
42
  	dout("auth_init name '%s'
  ", name);
4e7a5dcd1   Sage Weil   ceph: negotiate a...
43
44
45
46
47
  
  	ret = -ENOMEM;
  	ac = kzalloc(sizeof(*ac), GFP_NOFS);
  	if (!ac)
  		goto out;
e9966076c   Sage Weil   libceph: wrap aut...
48
  	mutex_init(&ac->mutex);
4e7a5dcd1   Sage Weil   ceph: negotiate a...
49
50
51
52
53
  	ac->negotiating = true;
  	if (name)
  		ac->name = name;
  	else
  		ac->name = CEPH_AUTH_NAME_DEFAULT;
8323c3aa7   Tommi Virtanen   ceph: Move secret...
54
55
56
  	dout("auth_init name %s
  ", ac->name);
  	ac->key = key;
4e7a5dcd1   Sage Weil   ceph: negotiate a...
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
  	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...
77
  	mutex_lock(&ac->mutex);
4e7a5dcd1   Sage Weil   ceph: negotiate a...
78
79
80
81
82
  	dout("auth_reset %p
  ", ac);
  	if (ac->ops && !ac->negotiating)
  		ac->ops->reset(ac);
  	ac->negotiating = true;
e9966076c   Sage Weil   libceph: wrap aut...
83
  	mutex_unlock(&ac->mutex);
4e7a5dcd1   Sage Weil   ceph: negotiate a...
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
  }
  
  int ceph_entity_name_encode(const char *name, void **p, void *end)
  {
  	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...
108
  	mutex_lock(&ac->mutex);
4e7a5dcd1   Sage Weil   ceph: negotiate a...
109
110
111
112
113
114
115
116
117
118
  	dout("auth_build_hello
  ");
  	monhdr->have_version = 0;
  	monhdr->session_mon = cpu_to_le16(-1);
  	monhdr->session_mon_tid = 0;
  
  	ceph_encode_32(&p, 0);  /* no protocol, yet */
  
  	lenp = p;
  	p += sizeof(u32);
07c8739c5   Sage Weil   ceph: add struct ...
119
120
  	ceph_decode_need(&p, end, 1 + sizeof(u32), bad);
  	ceph_encode_8(&p, 1);
4e7a5dcd1   Sage Weil   ceph: negotiate a...
121
122
  	num = ARRAY_SIZE(supported_protocols);
  	ceph_encode_32(&p, num);
07c8739c5   Sage Weil   ceph: add struct ...
123
  	ceph_decode_need(&p, end, num * sizeof(u32), bad);
4e7a5dcd1   Sage Weil   ceph: negotiate a...
124
125
126
127
128
  	for (i = 0; i < num; i++)
  		ceph_encode_32(&p, supported_protocols[i]);
  
  	ret = ceph_entity_name_encode(ac->name, &p, end);
  	if (ret < 0)
e9966076c   Sage Weil   libceph: wrap aut...
129
  		goto out;
4e7a5dcd1   Sage Weil   ceph: negotiate a...
130
131
132
133
  	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...
134
135
136
137
  	ret = p - buf;
  out:
  	mutex_unlock(&ac->mutex);
  	return ret;
4e7a5dcd1   Sage Weil   ceph: negotiate a...
138
139
  
  bad:
e9966076c   Sage Weil   libceph: wrap aut...
140
141
  	ret = -ERANGE;
  	goto out;
4e7a5dcd1   Sage Weil   ceph: negotiate a...
142
  }
cd84db6e4   Yehuda Sadeh   ceph: code cleanup
143
144
  static int ceph_build_auth_request(struct ceph_auth_client *ac,
  				   void *msg_buf, size_t msg_len)
9bd2e6f8b   Sage Weil   ceph: allow renew...
145
146
147
148
149
150
151
152
153
154
155
156
157
158
  {
  	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...
159
160
161
  		pr_err("error %d building auth method %s request
  ", ret,
  		       ac->ops->name);
e9966076c   Sage Weil   libceph: wrap aut...
162
  		goto out;
9bd2e6f8b   Sage Weil   ceph: allow renew...
163
164
165
166
  	}
  	dout(" built request %d bytes
  ", ret);
  	ceph_encode_32(&p, ret);
e9966076c   Sage Weil   libceph: wrap aut...
167
168
169
  	ret = p + ret - msg_buf;
  out:
  	return ret;
9bd2e6f8b   Sage Weil   ceph: allow renew...
170
  }
4e7a5dcd1   Sage Weil   ceph: negotiate a...
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
  /*
   * 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...
188
  	mutex_lock(&ac->mutex);
4e7a5dcd1   Sage Weil   ceph: negotiate a...
189
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
  	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...
218
219
220
221
222
  		/* server does not support our protocols? */
  		if (!protocol && result < 0) {
  			ret = result;
  			goto out;
  		}
4e7a5dcd1   Sage Weil   ceph: negotiate a...
223
224
225
226
227
228
229
230
231
  		/* 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...
232
233
234
  				pr_err("error %d on auth protocol %d init
  ",
  				       ret, protocol);
4e7a5dcd1   Sage Weil   ceph: negotiate a...
235
236
237
  				goto out;
  			}
  		}
9bd2e6f8b   Sage Weil   ceph: allow renew...
238
239
  
  		ac->negotiating = false;
4e7a5dcd1   Sage Weil   ceph: negotiate a...
240
241
242
243
  	}
  
  	ret = ac->ops->handle_reply(ac, result, payload, payload_end);
  	if (ret == -EAGAIN) {
e9966076c   Sage Weil   libceph: wrap aut...
244
  		ret = ceph_build_auth_request(ac, reply_buf, reply_len);
4e7a5dcd1   Sage Weil   ceph: negotiate a...
245
  	} else if (ret) {
559c1e007   Sage Weil   ceph: include aut...
246
247
  		pr_err("auth method '%s' error %d
  ", ac->ops->name, ret);
4e7a5dcd1   Sage Weil   ceph: negotiate a...
248
  	}
4e7a5dcd1   Sage Weil   ceph: negotiate a...
249

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

9bd2e6f8b   Sage Weil   ceph: allow renew...
274
275
  int ceph_auth_is_authenticated(struct ceph_auth_client *ac)
  {
e9966076c   Sage Weil   libceph: wrap aut...
276
277
278
279
280
281
282
  	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...
283
  }
27859f977   Sage Weil   libceph: wrap aut...
284
285
286
287
288
289
  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...
290
291
292
  	int ret = 0;
  
  	mutex_lock(&ac->mutex);
27859f977   Sage Weil   libceph: wrap aut...
293
  	if (ac->ops && ac->ops->create_authorizer)
e9966076c   Sage Weil   libceph: wrap aut...
294
295
296
  		ret = ac->ops->create_authorizer(ac, peer_type, auth);
  	mutex_unlock(&ac->mutex);
  	return ret;
27859f977   Sage Weil   libceph: wrap aut...
297
298
299
300
301
302
  }
  EXPORT_SYMBOL(ceph_auth_create_authorizer);
  
  void ceph_auth_destroy_authorizer(struct ceph_auth_client *ac,
  				  struct ceph_authorizer *a)
  {
e9966076c   Sage Weil   libceph: wrap aut...
303
  	mutex_lock(&ac->mutex);
27859f977   Sage Weil   libceph: wrap aut...
304
305
  	if (ac->ops && ac->ops->destroy_authorizer)
  		ac->ops->destroy_authorizer(ac, a);
e9966076c   Sage Weil   libceph: wrap aut...
306
  	mutex_unlock(&ac->mutex);
27859f977   Sage Weil   libceph: wrap aut...
307
308
309
310
311
312
313
314
  }
  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...
315
  	mutex_lock(&ac->mutex);
27859f977   Sage Weil   libceph: wrap aut...
316
317
  	if (ac->ops && ac->ops->update_authorizer)
  		ret = ac->ops->update_authorizer(ac, peer_type, a);
e9966076c   Sage Weil   libceph: wrap aut...
318
  	mutex_unlock(&ac->mutex);
27859f977   Sage Weil   libceph: wrap aut...
319
320
321
322
323
324
325
  	return ret;
  }
  EXPORT_SYMBOL(ceph_auth_update_authorizer);
  
  int ceph_auth_verify_authorizer_reply(struct ceph_auth_client *ac,
  				      struct ceph_authorizer *a, size_t len)
  {
e9966076c   Sage Weil   libceph: wrap aut...
326
327
328
  	int ret = 0;
  
  	mutex_lock(&ac->mutex);
27859f977   Sage Weil   libceph: wrap aut...
329
  	if (ac->ops && ac->ops->verify_authorizer_reply)
e9966076c   Sage Weil   libceph: wrap aut...
330
331
332
  		ret = ac->ops->verify_authorizer_reply(ac, a, len);
  	mutex_unlock(&ac->mutex);
  	return ret;
27859f977   Sage Weil   libceph: wrap aut...
333
334
335
336
337
  }
  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...
338
  	mutex_lock(&ac->mutex);
27859f977   Sage Weil   libceph: wrap aut...
339
340
  	if (ac->ops && ac->ops->invalidate_authorizer)
  		ac->ops->invalidate_authorizer(ac, peer_type);
e9966076c   Sage Weil   libceph: wrap aut...
341
  	mutex_unlock(&ac->mutex);
27859f977   Sage Weil   libceph: wrap aut...
342
343
  }
  EXPORT_SYMBOL(ceph_auth_invalidate_authorizer);