aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/auth.c
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2009-11-18 19:19:57 -0500
committerSage Weil <sage@newdream.net>2009-11-18 19:19:57 -0500
commit4e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bc (patch)
treea77e9b4563022340361ca673ef2e1beebb538e2f /fs/ceph/auth.c
parent5f44f142601bf94c448e2d463f0f18fd159da164 (diff)
ceph: negotiate authentication protocol; implement AUTH_NONE protocol
When we open a monitor session, we send an initial AUTH message listing the auth protocols we support, our entity name, and (possibly) a previously assigned global_id. The monitor chooses a protocol and responds with an initial message. Initially implement AUTH_NONE, a dummy protocol that provides no security, but works within the new framework. It generates 'authorizers' that are used when connecting to (mds, osd) services that simply state our entity name and global_id. This is a wire protocol change. Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'fs/ceph/auth.c')
-rw-r--r--fs/ceph/auth.c220
1 files changed, 220 insertions, 0 deletions
diff --git a/fs/ceph/auth.c b/fs/ceph/auth.c
new file mode 100644
index 000000000000..c4d1eee827a3
--- /dev/null
+++ b/fs/ceph/auth.c
@@ -0,0 +1,220 @@
1#include "ceph_debug.h"
2
3#include <linux/module.h>
4#include <linux/err.h>
5
6#include "types.h"
7#include "auth_none.h"
8#include "decode.h"
9#include "super.h"
10
11#include "messenger.h"
12
13/*
14 * get protocol handler
15 */
16static u32 supported_protocols[] = {
17 CEPH_AUTH_NONE
18};
19
20int ceph_auth_init_protocol(struct ceph_auth_client *ac, int protocol)
21{
22 switch (protocol) {
23 case CEPH_AUTH_NONE:
24 return ceph_auth_none_init(ac);
25 default:
26 return -ENOENT;
27 }
28}
29
30/*
31 * setup, teardown.
32 */
33struct ceph_auth_client *ceph_auth_init(const char *name, const char *secret)
34{
35 struct ceph_auth_client *ac;
36 int ret;
37
38 dout("auth_init name '%s' secret '%s'\n", name, secret);
39
40 ret = -ENOMEM;
41 ac = kzalloc(sizeof(*ac), GFP_NOFS);
42 if (!ac)
43 goto out;
44
45 ac->negotiating = true;
46 if (name)
47 ac->name = name;
48 else
49 ac->name = CEPH_AUTH_NAME_DEFAULT;
50 dout("auth_init name %s secret %s\n", ac->name, secret);
51 ac->secret = secret;
52 return ac;
53
54out:
55 return ERR_PTR(ret);
56}
57
58void ceph_auth_destroy(struct ceph_auth_client *ac)
59{
60 dout("auth_destroy %p\n", ac);
61 if (ac->ops)
62 ac->ops->destroy(ac);
63 kfree(ac);
64}
65
66/*
67 * Reset occurs when reconnecting to the monitor.
68 */
69void ceph_auth_reset(struct ceph_auth_client *ac)
70{
71 dout("auth_reset %p\n", ac);
72 if (ac->ops && !ac->negotiating)
73 ac->ops->reset(ac);
74 ac->negotiating = true;
75}
76
77int ceph_entity_name_encode(const char *name, void **p, void *end)
78{
79 int len = strlen(name);
80
81 if (*p + 2*sizeof(u32) + len > end)
82 return -ERANGE;
83 ceph_encode_32(p, CEPH_ENTITY_TYPE_CLIENT);
84 ceph_encode_32(p, len);
85 ceph_encode_copy(p, name, len);
86 return 0;
87}
88
89/*
90 * Initiate protocol negotiation with monitor. Include entity name
91 * and list supported protocols.
92 */
93int ceph_auth_build_hello(struct ceph_auth_client *ac, void *buf, size_t len)
94{
95 struct ceph_mon_request_header *monhdr = buf;
96 void *p = monhdr + 1, *end = buf + len, *lenp;
97 int i, num;
98 int ret;
99
100 dout("auth_build_hello\n");
101 monhdr->have_version = 0;
102 monhdr->session_mon = cpu_to_le16(-1);
103 monhdr->session_mon_tid = 0;
104
105 ceph_encode_32(&p, 0); /* no protocol, yet */
106
107 lenp = p;
108 p += sizeof(u32);
109
110 num = ARRAY_SIZE(supported_protocols);
111 ceph_encode_32(&p, num);
112 for (i = 0; i < num; i++)
113 ceph_encode_32(&p, supported_protocols[i]);
114
115 ret = ceph_entity_name_encode(ac->name, &p, end);
116 if (ret < 0)
117 return ret;
118 ceph_decode_need(&p, end, sizeof(u64), bad);
119 ceph_encode_64(&p, ac->global_id);
120
121 ceph_encode_32(&lenp, p - lenp - sizeof(u32));
122 return p - buf;
123
124bad:
125 return -ERANGE;
126}
127
128/*
129 * Handle auth message from monitor.
130 */
131int ceph_handle_auth_reply(struct ceph_auth_client *ac,
132 void *buf, size_t len,
133 void *reply_buf, size_t reply_len)
134{
135 void *p = buf;
136 void *end = buf + len;
137 int protocol;
138 s32 result;
139 u64 global_id;
140 void *payload, *payload_end;
141 int payload_len;
142 char *result_msg;
143 int result_msg_len;
144 int ret = -EINVAL;
145
146 dout("handle_auth_reply %p %p\n", p, end);
147 ceph_decode_need(&p, end, sizeof(u32) * 3 + sizeof(u64), bad);
148 protocol = ceph_decode_32(&p);
149 result = ceph_decode_32(&p);
150 global_id = ceph_decode_64(&p);
151 payload_len = ceph_decode_32(&p);
152 payload = p;
153 p += payload_len;
154 ceph_decode_need(&p, end, sizeof(u32), bad);
155 result_msg_len = ceph_decode_32(&p);
156 result_msg = p;
157 p += result_msg_len;
158 if (p != end)
159 goto bad;
160
161 dout(" result %d '%.*s' gid %llu len %d\n", result, result_msg_len,
162 result_msg, global_id, payload_len);
163
164 payload_end = payload + payload_len;
165
166 if (global_id && ac->global_id != global_id) {
167 dout(" set global_id %lld -> %lld\n", ac->global_id, global_id);
168 ac->global_id = global_id;
169 }
170
171 if (ac->negotiating) {
172 /* set up (new) protocol handler? */
173 if (ac->protocol && ac->protocol != protocol) {
174 ac->ops->destroy(ac);
175 ac->protocol = 0;
176 ac->ops = NULL;
177 }
178 if (ac->protocol != protocol) {
179 ret = ceph_auth_init_protocol(ac, protocol);
180 if (ret) {
181 pr_err("error %d on auth protocol %d init\n",
182 ret, protocol);
183 goto out;
184 }
185 }
186 }
187
188 ret = ac->ops->handle_reply(ac, result, payload, payload_end);
189 if (ret == -EAGAIN) {
190 struct ceph_mon_request_header *monhdr = reply_buf;
191 void *p = reply_buf + 1;
192 void *end = reply_buf + reply_len;
193
194 monhdr->have_version = 0;
195 monhdr->session_mon = cpu_to_le16(-1);
196 monhdr->session_mon_tid = 0;
197
198 ceph_encode_32(&p, ac->protocol);
199
200 ret = ac->ops->build_request(ac, p + sizeof(u32), end);
201 if (ret < 0) {
202 pr_err("error %d building request\n", ret);
203 goto out;
204 }
205 dout(" built request %d bytes\n", ret);
206 ceph_encode_32(&p, ret);
207 return p + ret - reply_buf;
208 } else if (ret) {
209 pr_err("authentication error %d\n", ret);
210 return ret;
211 }
212 return 0;
213
214bad:
215 pr_err("failed to decode auth msg\n");
216out:
217 return ret;
218}
219
220