Whamcloud - gitweb
ecea3a38984b02c6cb47cdfc096658c21f821ab5
[fs/lustre-release.git] / lustre / sec / gks / gks_server.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * lustre GS server
5  *  Copyright (c) 2001-2003 Cluster File Systems, Inc.
6  *
7  *   This file is part of Lustre, http://www.lustre.org.
8  *
9  *   Lustre is free software; you can redistribute it and/or
10  *   modify it under the terms of version 2 of the GNU General Public
11  *   License as published by the Free Software Foundation.
12  *
13  *   Lustre is distributed in the hope that it will be useful,
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *   GNU General Public License for more details.
17  *
18  *   You should have received a copy of the GNU General Public License
19  *   along with Lustre; if not, write to the Free Software
20  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22 #ifndef EXPORT_SYMTAB
23 # define EXPORT_SYMTAB
24 #endif
25 #define DEBUG_SUBSYSTEM S_GKS
26
27 #include <linux/module.h>
28 #include <linux/crypto.h>
29 #include <linux/random.h>
30 #include <linux/init.h>
31 #include <linux/obd_class.h>
32 #include <linux/lustre_gs.h>
33
34 #include "gks_internal.h"
35
36 #define GKS_KEY "19760218"
37 #define GKS_KEY_LEN 8 
38 #define GKS_MAC_ALG "sha1"
39 #define GKS_KEY_ALG "des"
40 #define GKS_KEY_ALG_MODE CRYPTO_TFM_MODE_CBC
41
42 static int gks_cleanup(struct obd_device *obd, int flags)
43 {
44         struct gks_obd *gks = &obd->u.gks;
45         ENTRY;     
46
47         if (gks->gks_mac_tfm) {
48                 crypto_free_tfm(gks->gks_mac_tfm);
49         }
50         if (gks->gks_key.key) {
51                 OBD_FREE(gks->gks_key.key, gks->gks_key.len);
52         }  
53         if (gks->gks_key_tfm) {
54                 crypto_free_tfm(gks->gks_key_tfm);
55         }
56
57         RETURN(0);
58 }
59
60 static int gks_setup(struct obd_device *obd, obd_count len, void *buf)
61 {
62         struct gks_obd *gks = &obd->u.gks;
63         int rc = 0;
64
65         gks->gks_mac_tfm = crypto_alloc_tfm(GKS_MAC_ALG, 0);
66         if (!gks->gks_mac_tfm)
67                 RETURN(-ENOSYS);
68         /*Now: we only keep an unchanged key in the whole system*/
69         gks->gks_key.len = GKS_KEY_LEN;
70         
71         OBD_ALLOC(gks->gks_key.key, GKS_KEY_LEN);
72
73         LASSERT(gks->gks_key.key);
74         
75         memcpy(gks->gks_key.key, GKS_KEY, GKS_KEY_LEN); 
76         /*set gks cipher type*/
77
78         gks->gks_key_tfm = crypto_alloc_tfm(GKS_KEY_ALG, GKS_KEY_ALG_MODE);
79         if (!gks->gks_key_tfm)
80                 GOTO(out, rc = -ENOSYS);                
81         if (crypto_cipher_setkey(gks->gks_key_tfm, gks->gks_key.key, 
82                                  gks->gks_key.len))
83                 GOTO(out, rc = -ENOSYS);
84 out:
85         if (rc) {
86                 gks_cleanup(obd, 0);
87         }
88         RETURN(rc);
89 }
90
91 static int gks_connect(struct lustre_handle *conn, struct obd_device *obd,
92                        struct obd_uuid *cluuid, struct obd_connect_data *data,
93                        unsigned long flags)
94 {
95         int rc;
96         ENTRY;
97
98         if (!conn || !obd || !cluuid)
99                 RETURN(-EINVAL);
100
101         rc = class_connect(conn, obd, cluuid);
102
103         RETURN(rc);
104 }
105
106 static int gks_disconnect(struct obd_export *exp, unsigned long flags)
107 {
108         int rc = 0;
109         ENTRY;
110
111         rc = class_disconnect(exp, flags);
112         
113         target_destroy_export(exp);
114         
115         RETURN(rc);
116 }
117
118 static int gks_msg_check_version(struct lustre_msg *msg)
119 {
120         int rc = 0;
121         ENTRY;
122
123         switch (msg->opc) {
124         case GKS_CONNECT:
125         case GKS_DISCONNECT:
126                 rc = lustre_msg_check_version(msg, LUSTRE_OBD_VERSION);
127                 if (rc)
128                         CERROR("bad opc %u version %08x, expecting %08x\n",
129                                msg->opc, msg->version, LUSTRE_OBD_VERSION);
130                 break;
131         case GKS_GET_KEY:
132         case GKS_DECRYPT_KEY:
133         case GKS_GET_MAC:
134                 rc = lustre_msg_check_version(msg, LUSTRE_GKS_VERSION);
135                 if (rc)
136                         CERROR("bad opc %u version %08x, expecting %08x\n",
137                                msg->opc, msg->version, LUSTRE_GKS_VERSION);
138                 break;
139         default:
140                 CERROR("GKS unknown opcode %d\n", msg->opc);
141                 rc = -ENOTSUPP;
142                 break;
143         }
144
145         RETURN(rc);
146 }
147
148 static int crypto_get_gks_mac(struct ptlrpc_request *req, 
149                               struct key_perm *kperm, 
150                               __u8 *hmac)
151 {
152         struct obd_device *obd = req->rq_export->exp_obd;
153         struct gks_obd *gks = &obd->u.gks;
154         int perm_size = crypto_kperm_size(kperm->kp_acl_count);
155         struct scatterlist sl = {
156                 .page   = virt_to_page(kperm),
157                 .offset = (unsigned long)(kperm) % PAGE_SIZE,
158                 .length = perm_size 
159         };
160         __u8 *key = gks->gks_key.key; 
161         int keylen = gks->gks_key.len;
162         struct crypto_tfm *tfm = gks->gks_mac_tfm;
163
164         ENTRY;
165         LASSERT(tfm);
166         
167         crypto_hmac(tfm, key, &keylen, &sl, 1, hmac);
168        
169         CDEBUG(D_INFO, "compute mac mac %s by uid %d gid %d" 
170                "mode %d acl_count %d acl %p perm_size %d\n",
171                hmac, kperm->kp_uid, kperm->kp_gid, kperm->kp_mode, 
172                kperm->kp_acl_count, kperm->kp_acls, perm_size);
173         
174         RETURN(0); 
175 }
176 #define crypto_decrypt_gks_key(req, data, len) \
177 crypto_crypt_gks_key(req, data, len, DECRYPT_DATA)
178
179 #define crypto_encrypt_gks_key(req, data, len) \
180 crypto_crypt_gks_key(req, data, len, ENCRYPT_DATA)
181
182 static int crypto_crypt_gks_key(struct ptlrpc_request *req, 
183                                 __u8 *data, int len, int mode) 
184 {
185         struct obd_device *obd = req->rq_export->exp_obd;
186         struct gks_obd *gks = &obd->u.gks;
187         struct scatterlist sl = {
188                 .page   = virt_to_page(data),
189                 .offset = (unsigned long)(data) % PAGE_SIZE,
190                 .length = len 
191         };
192         struct crypto_tfm *tfm = gks->gks_key_tfm;
193         __u8 local_iv[16] = {0};
194
195         ENTRY;
196         LASSERT(tfm);
197        
198         if (mode == ENCRYPT_DATA) 
199                 crypto_cipher_encrypt_iv(tfm, &sl, &sl, (unsigned int)len, 
200                                          local_iv);
201         else
202                 crypto_cipher_decrypt_iv(tfm, &sl, &sl, (unsigned int)len, 
203                                          local_iv);
204  
205         RETURN(0); 
206 }
207
208 static int gks_create_key(struct ptlrpc_request *req, int offset)
209 {
210         struct key_context *kctxt;
211         struct crypto_key  *ckey;
212
213         kctxt = lustre_swab_reqbuf(req, offset, sizeof (*kctxt),
214                                    lustre_swab_key_context);
215      
216         ckey = (struct crypto_key *)lustre_msg_buf(req->rq_repmsg, 0, 
217                                                    sizeof (*ckey));
218         
219         crypto_get_gks_mac(req, &kctxt->kc_perm, ckey->ck_mac);
220
221         CDEBUG(D_INFO, "compute mac mac %s by uid %d gid %d mode %d \n",
222                ckey->ck_mac, kctxt->kc_perm.kp_uid, kctxt->kc_perm.kp_gid,
223                kctxt->kc_perm.kp_mode);
224        
225         get_random_bytes(ckey->ck_key, KEY_SIZE);        
226         
227         ckey->ck_type = GKS_TYPE;
228         
229         CDEBUG(D_INFO, "original decrypt key %s\n", ckey->ck_key);
230
231         crypto_encrypt_gks_key(req, ckey->ck_key, KEY_SIZE);
232
233         CDEBUG(D_INFO, "encrypt key %s\n", ckey->ck_key);
234         
235         RETURN(0); 
236 }
237
238 static int gks_mac_verification(struct ptlrpc_request *req, 
239                                 struct crypto_key *key, 
240                                 struct key_perm *kperm)
241 {
242         __u8 *tmp_mac;
243         ENTRY;
244
245         OBD_ALLOC(tmp_mac, MAC_SIZE);
246
247         crypto_get_gks_mac(req, kperm, tmp_mac);
248
249         if (!memcmp(tmp_mac, key->ck_mac, MAC_SIZE)) {
250                 OBD_FREE(tmp_mac, MAC_SIZE);
251                 RETURN(0); 
252         }
253         CERROR("new_created %s EA is %s \n", tmp_mac, key->ck_mac);
254         OBD_FREE(tmp_mac, MAC_SIZE);
255         RETURN(-EPERM);
256 }
257
258 static int gks_permission_check(struct key_context *kctxt,
259                                 struct key_perm *kperm)
260 {
261         RETURN(0); 
262 }
263
264 static int gks_decrypt_key(struct ptlrpc_request *req, int offset)
265 {
266         struct key_context *kctxt;
267         struct key_perm    *kperm;
268         struct crypto_key  *ckey;
269         int                rc = 0;
270
271         kctxt = lustre_swab_reqbuf(req, offset, sizeof(*kctxt),
272                                    lustre_swab_key_context);
273         
274         /*authiticating the ops of the mac*/
275         rc = gks_mac_verification(req, &kctxt->kc_ck, &kctxt->kc_perm);
276         if (rc != 0) {
277                 CERROR("Not my authorization mac %s\n", kctxt->kc_ck.ck_mac);
278                 RETURN(rc);
279         }
280
281         kperm = lustre_swab_reqbuf(req, offset + 1, sizeof(*kperm),
282                                    lustre_swab_key_perms);
283
284         rc = gks_permission_check(kctxt, kperm);
285         if (rc != 0) {
286                 CERROR("permssion check failed\n");
287                 RETURN(rc);
288         }
289         ckey = (struct crypto_key *)lustre_msg_buf(req->rq_repmsg, 0, 
290                                                    sizeof (*ckey));
291         memcpy(ckey, &kctxt->kc_ck, sizeof(*ckey));
292         
293         CDEBUG(D_INFO, "encrypt key %s mac %s \n", ckey->ck_key, ckey->ck_mac);
294         rc = crypto_decrypt_gks_key(req, ckey->ck_key, KEY_SIZE);
295         if (rc != 0) {
296                 CERROR("permssion check failed\n");
297                 RETURN(rc);
298         }
299         CDEBUG(D_INFO, "decrypt key %s mac %s \n", ckey->ck_key, ckey->ck_mac);
300         
301         RETURN(0); 
302 }
303
304 static int gks_get_mac(struct ptlrpc_request *req, int offset)
305 {
306         struct key_context *kctxt;
307         struct key_perm    *kperm;
308         struct crypto_key  *ckey;
309         int                rc = 0;
310
311         kctxt = lustre_swab_reqbuf(req, offset, sizeof(*kctxt),
312                                    lustre_swab_key_context);
313         
314         /*authiticating the ops of the mac*/
315         rc = gks_mac_verification(req, &kctxt->kc_ck, &kctxt->kc_perm);
316         if (rc != 0) {
317                 CERROR("Not my authorization mac %s\n", kctxt->kc_ck.ck_mac);
318                 RETURN(rc);
319         }
320
321         kperm = lustre_swab_reqbuf(req, offset + 1, sizeof(*kperm),
322                                    lustre_swab_key_perms);
323
324         rc = gks_permission_check(kctxt, kperm);
325         if (rc != 0) {
326                 CERROR("permssion check failed\n");
327                 RETURN(rc);
328         }
329         ckey = (struct crypto_key *)lustre_msg_buf(req->rq_repmsg, 0, 
330                                                    sizeof (*ckey));
331
332         memcpy(ckey, &kctxt->kc_ck, sizeof(*ckey));
333
334         ckey->ck_type = GKS_TYPE;
335         rc = crypto_get_gks_mac(req, kperm, ckey->ck_mac);
336         if (rc != 0) {
337                 CERROR("get new mac error %d \n", rc);
338                 RETURN(rc);
339         }
340
341         RETURN(rc);
342 }
343
344 int gks_handle(struct ptlrpc_request *req)
345 {
346         int fail = OBD_FAIL_MDS_ALL_REPLY_NET;
347         int rc;
348         ENTRY;
349
350         rc = gks_msg_check_version(req->rq_reqmsg);
351         if (rc) {
352                 CERROR("GKS drop mal-formed request\n");
353                 RETURN(rc);
354         }
355         switch (req->rq_reqmsg->opc) {
356         case GKS_CONNECT:
357                 DEBUG_REQ(D_INODE, req, "connect");
358                 rc = target_handle_connect(req);
359                 req->rq_status = rc;            /* superfluous? */
360                 break;
361         case GKS_DISCONNECT:
362                 DEBUG_REQ(D_INODE, req, "disconnect");
363                 rc = target_handle_disconnect(req);
364                 req->rq_status = rc;            /* superfluous? */
365                 break;
366
367         case GKS_GET_KEY: {
368                 int size[1] = {sizeof(struct crypto_key)};
369                 int bufcount = 1;
370  
371                 DEBUG_REQ(D_INODE, req, "get_key");
372                 lustre_pack_reply(req, bufcount, size, NULL);
373                 rc = gks_create_key(req, MDS_REQ_REC_OFF);      
374                 req->rq_status = rc;            /* superfluous? */
375                 break;     
376         }  
377         case GKS_DECRYPT_KEY: {
378                 int size[1] = {sizeof(struct crypto_key)};
379                 int bufcount = 1;
380  
381                 DEBUG_REQ(D_INODE, req, "decrypt_key");
382                 lustre_pack_reply(req, bufcount, size, NULL);
383                 rc = gks_decrypt_key(req, MDS_REQ_REC_OFF);      
384                 req->rq_status = rc;            /* superfluous? */
385                 break;     
386         }  
387         case GKS_GET_MAC: {
388                 int size[1] = {sizeof(struct crypto_key)};
389                 int bufcount = 1;
390                   
391                 DEBUG_REQ(D_INODE, req, "get_mac");
392                 lustre_pack_reply(req, bufcount, size, NULL);
393                 rc = gks_get_mac(req, MDS_REQ_REC_OFF);      
394                 req->rq_status = rc;            /* superfluous? */
395                 break;
396         }
397         default:
398                 req->rq_status = -ENOTSUPP;
399                 rc = ptlrpc_error(req);
400                 RETURN(rc);
401         } 
402         target_send_reply(req, rc, fail);
403         RETURN(rc);
404 }
405
406 static int gkt_setup(struct obd_device *obd, obd_count len, void *buf)
407 {
408         struct gks_obd *gks = &obd->u.gks;
409         int rc = 0;
410         ENTRY;
411
412         gks->gks_service =
413                 ptlrpc_init_svc(GKS_NBUFS, GKS_BUFSIZE, GKS_MAXREQSIZE,
414                                 GKS_REQUEST_PORTAL, GKC_REPLY_PORTAL,
415                                 GKS_SERVICE_WATCHDOG_TIMEOUT,
416                                 gks_handle, "gks", obd->obd_proc_entry);
417         if (!gks->gks_service) {
418                 CERROR("failed to start service\n");
419                 RETURN(-ENOMEM);
420         }
421
422         rc = ptlrpc_start_n_threads(obd, gks->gks_service, GKT_NUM_THREADS,
423                                     "ll_gkt");
424         
425         RETURN(rc);
426 }
427
428 static int gkt_cleanup(struct obd_device *obd, int flags)
429 {
430         struct gks_obd *gks = &obd->u.gks;
431
432         ptlrpc_stop_all_threads(gks->gks_service);
433         ptlrpc_unregister_service(gks->gks_service);
434         RETURN(0);
435 }
436
437 int gks_attach(struct obd_device *dev, obd_count len, void *data)
438 {
439         struct lprocfs_static_vars lvars;
440
441         lprocfs_init_vars(gks, &lvars);
442         return lprocfs_obd_attach(dev, lvars.obd_vars);
443 }
444
445 int gks_detach(struct obd_device *dev)
446 {
447         return lprocfs_obd_detach(dev);
448 }
449
450 int gkt_attach(struct obd_device *dev, obd_count len, void *data)
451 {
452         struct lprocfs_static_vars lvars;
453
454         lprocfs_init_vars(gkt, &lvars);
455         return lprocfs_obd_attach(dev, lvars.obd_vars);
456 }
457
458 int gkt_detach(struct obd_device *dev)
459 {
460         return lprocfs_obd_detach(dev);
461 }
462
463 static struct obd_ops gks_obd_ops = {
464         .o_owner           = THIS_MODULE,
465         .o_attach          = gks_attach,
466         .o_detach          = gks_detach,
467         .o_setup           = gks_setup,
468         .o_cleanup         = gks_cleanup,
469         .o_connect         = gks_connect,
470         .o_disconnect         = gks_disconnect,
471 };
472
473 static struct obd_ops gkt_obd_ops = {
474         .o_owner           = THIS_MODULE,
475         .o_attach          = gkt_attach,
476         .o_detach          = gkt_detach,
477         .o_setup           = gkt_setup,
478         .o_cleanup         = gkt_cleanup,
479 };
480
481 static int __init gks_init(void)
482 {
483         struct lprocfs_static_vars lvars;
484
485         lprocfs_init_vars(gks, &lvars);
486         class_register_type(&gks_obd_ops, NULL, lvars.module_vars,
487                             LUSTRE_GKS_NAME);
488         
489         lprocfs_init_vars(gkt, &lvars);
490         class_register_type(&gkt_obd_ops, NULL, lvars.module_vars,
491                             LUSTRE_GKT_NAME);
492         RETURN(0);
493 }
494
495 static void gks_exit(void)
496 {
497         class_unregister_type(LUSTRE_GKS_NAME);
498         class_unregister_type(LUSTRE_GKT_NAME);
499 }
500
501 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
502 MODULE_DESCRIPTION("Lustre GS Server (GS)");
503 MODULE_LICENSE("GPL");
504
505 module_init(gks_init);
506 module_exit(gks_exit);
507