Whamcloud - gitweb
current branches now use lnet from HEAD
[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         if (!tmp_mac)
247                 RETURN(-ENOMEM);
248         crypto_get_gks_mac(req, kperm, tmp_mac);
249
250         if (!memcmp(tmp_mac, key->ck_mac, MAC_SIZE)) {
251                 OBD_FREE(tmp_mac, MAC_SIZE);
252                 RETURN(0); 
253         }
254         CERROR("new_created %s EA is %s \n", tmp_mac, key->ck_mac);
255         OBD_FREE(tmp_mac, MAC_SIZE);
256         RETURN(-EPERM);
257 }
258
259 static int gks_permission_check(struct key_context *kctxt,
260                                 struct key_perm *kperm)
261 {
262         RETURN(0); 
263 }
264
265 static int gks_decrypt_key(struct ptlrpc_request *req, int offset)
266 {
267         struct key_context *kctxt;
268         struct key_perm    *kperm;
269         struct crypto_key  *ckey;
270         int                rc = 0;
271
272         kctxt = lustre_swab_reqbuf(req, offset, sizeof(*kctxt),
273                                    lustre_swab_key_context);
274         
275         /*authiticating the ops of the mac*/
276         rc = gks_mac_verification(req, &kctxt->kc_ck, &kctxt->kc_perm);
277         if (rc != 0) {
278                 CERROR("Not my authorization mac %s\n", kctxt->kc_ck.ck_mac);
279                 RETURN(rc);
280         }
281
282         kperm = lustre_swab_reqbuf(req, offset + 1, sizeof(*kperm),
283                                    lustre_swab_key_perms);
284
285         rc = gks_permission_check(kctxt, kperm);
286         if (rc != 0) {
287                 CERROR("permssion check failed\n");
288                 RETURN(rc);
289         }
290         ckey = (struct crypto_key *)lustre_msg_buf(req->rq_repmsg, 0, 
291                                                    sizeof (*ckey));
292         memcpy(ckey, &kctxt->kc_ck, sizeof(*ckey));
293         
294         CDEBUG(D_INFO, "encrypt key %s mac %s \n", ckey->ck_key, ckey->ck_mac);
295         rc = crypto_decrypt_gks_key(req, ckey->ck_key, KEY_SIZE);
296         if (rc != 0) {
297                 CERROR("permssion check failed\n");
298                 RETURN(rc);
299         }
300         CDEBUG(D_INFO, "decrypt key %s mac %s \n", ckey->ck_key, ckey->ck_mac);
301         
302         RETURN(0); 
303 }
304
305 static int gks_get_mac(struct ptlrpc_request *req, int offset)
306 {
307         struct key_context *kctxt;
308         struct key_perm    *kperm;
309         struct crypto_key  *ckey;
310         int                rc = 0;
311
312         kctxt = lustre_swab_reqbuf(req, offset, sizeof(*kctxt),
313                                    lustre_swab_key_context);
314         
315         /*authiticating the ops of the mac*/
316         rc = gks_mac_verification(req, &kctxt->kc_ck, &kctxt->kc_perm);
317         if (rc != 0) {
318                 CERROR("Not my authorization mac %s\n", kctxt->kc_ck.ck_mac);
319                 RETURN(rc);
320         }
321
322         kperm = lustre_swab_reqbuf(req, offset + 1, sizeof(*kperm),
323                                    lustre_swab_key_perms);
324
325         rc = gks_permission_check(kctxt, kperm);
326         if (rc != 0) {
327                 CERROR("permssion check failed\n");
328                 RETURN(rc);
329         }
330         ckey = (struct crypto_key *)lustre_msg_buf(req->rq_repmsg, 0, 
331                                                    sizeof (*ckey));
332
333         memcpy(ckey, &kctxt->kc_ck, sizeof(*ckey));
334
335         ckey->ck_type = GKS_TYPE;
336         rc = crypto_get_gks_mac(req, kperm, ckey->ck_mac);
337         if (rc != 0) {
338                 CERROR("get new mac error %d \n", rc);
339                 RETURN(rc);
340         }
341
342         RETURN(rc);
343 }
344
345 int gks_handle(struct ptlrpc_request *req)
346 {
347         int fail = OBD_FAIL_MDS_ALL_REPLY_NET;
348         int rc;
349         ENTRY;
350
351         rc = gks_msg_check_version(req->rq_reqmsg);
352         if (rc) {
353                 CERROR("GKS drop mal-formed request\n");
354                 RETURN(rc);
355         }
356         switch (req->rq_reqmsg->opc) {
357         case GKS_CONNECT:
358                 DEBUG_REQ(D_INODE, req, "connect");
359                 rc = target_handle_connect(req);
360                 req->rq_status = rc;            /* superfluous? */
361                 break;
362         case GKS_DISCONNECT:
363                 DEBUG_REQ(D_INODE, req, "disconnect");
364                 rc = target_handle_disconnect(req);
365                 req->rq_status = rc;            /* superfluous? */
366                 break;
367
368         case GKS_GET_KEY: {
369                 int size[1] = {sizeof(struct crypto_key)};
370                 int bufcount = 1;
371  
372                 DEBUG_REQ(D_INODE, req, "get_key");
373                 lustre_pack_reply(req, bufcount, size, NULL);
374                 rc = gks_create_key(req, MDS_REQ_REC_OFF);      
375                 req->rq_status = rc;            /* superfluous? */
376                 break;     
377         }  
378         case GKS_DECRYPT_KEY: {
379                 int size[1] = {sizeof(struct crypto_key)};
380                 int bufcount = 1;
381  
382                 DEBUG_REQ(D_INODE, req, "decrypt_key");
383                 lustre_pack_reply(req, bufcount, size, NULL);
384                 rc = gks_decrypt_key(req, MDS_REQ_REC_OFF);      
385                 req->rq_status = rc;            /* superfluous? */
386                 break;     
387         }  
388         case GKS_GET_MAC: {
389                 int size[1] = {sizeof(struct crypto_key)};
390                 int bufcount = 1;
391                   
392                 DEBUG_REQ(D_INODE, req, "get_mac");
393                 lustre_pack_reply(req, bufcount, size, NULL);
394                 rc = gks_get_mac(req, MDS_REQ_REC_OFF);      
395                 req->rq_status = rc;            /* superfluous? */
396                 break;
397         }
398         default:
399                 req->rq_status = -ENOTSUPP;
400                 rc = ptlrpc_error(req);
401                 RETURN(rc);
402         } 
403         target_send_reply(req, rc, fail);
404         RETURN(rc);
405 }
406
407 static int gkt_setup(struct obd_device *obd, obd_count len, void *buf)
408 {
409         struct gks_obd *gks = &obd->u.gks;
410         int rc = 0;
411         ENTRY;
412
413         gks->gks_service =
414                 ptlrpc_init_svc(GKS_NBUFS, GKS_BUFSIZE, GKS_MAXREQSIZE,
415                                 GKS_REQUEST_PORTAL, GKC_REPLY_PORTAL,
416                                 GKS_SERVICE_WATCHDOG_TIMEOUT,
417                                 gks_handle, "gks", obd->obd_proc_entry);
418         if (!gks->gks_service) {
419                 CERROR("failed to start service\n");
420                 RETURN(-ENOMEM);
421         }
422
423         rc = ptlrpc_start_n_threads(obd, gks->gks_service, GKT_NUM_THREADS,
424                                     "ll_gkt");
425         
426         RETURN(rc);
427 }
428
429 static int gkt_cleanup(struct obd_device *obd, int flags)
430 {
431         struct gks_obd *gks = &obd->u.gks;
432
433         ptlrpc_stop_all_threads(gks->gks_service);
434         ptlrpc_unregister_service(gks->gks_service);
435         RETURN(0);
436 }
437
438 int gks_attach(struct obd_device *dev, obd_count len, void *data)
439 {
440         struct lprocfs_static_vars lvars;
441
442         lprocfs_init_vars(gks, &lvars);
443         return lprocfs_obd_attach(dev, lvars.obd_vars);
444 }
445
446 int gks_detach(struct obd_device *dev)
447 {
448         return lprocfs_obd_detach(dev);
449 }
450
451 int gkt_attach(struct obd_device *dev, obd_count len, void *data)
452 {
453         struct lprocfs_static_vars lvars;
454
455         lprocfs_init_vars(gkt, &lvars);
456         return lprocfs_obd_attach(dev, lvars.obd_vars);
457 }
458
459 int gkt_detach(struct obd_device *dev)
460 {
461         return lprocfs_obd_detach(dev);
462 }
463
464 static struct obd_ops gks_obd_ops = {
465         .o_owner           = THIS_MODULE,
466         .o_attach          = gks_attach,
467         .o_detach          = gks_detach,
468         .o_setup           = gks_setup,
469         .o_cleanup         = gks_cleanup,
470         .o_connect         = gks_connect,
471         .o_disconnect         = gks_disconnect,
472 };
473
474 static struct obd_ops gkt_obd_ops = {
475         .o_owner           = THIS_MODULE,
476         .o_attach          = gkt_attach,
477         .o_detach          = gkt_detach,
478         .o_setup           = gkt_setup,
479         .o_cleanup         = gkt_cleanup,
480 };
481
482 static int __init gks_init(void)
483 {
484         struct lprocfs_static_vars lvars;
485
486         lprocfs_init_vars(gks, &lvars);
487         class_register_type(&gks_obd_ops, NULL, lvars.module_vars,
488                             LUSTRE_GKS_NAME);
489         
490         lprocfs_init_vars(gkt, &lvars);
491         class_register_type(&gkt_obd_ops, NULL, lvars.module_vars,
492                             LUSTRE_GKT_NAME);
493         RETURN(0);
494 }
495
496 static void gks_exit(void)
497 {
498         class_unregister_type(LUSTRE_GKS_NAME);
499         class_unregister_type(LUSTRE_GKT_NAME);
500 }
501
502 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
503 MODULE_DESCRIPTION("Lustre GS Server (GS)");
504 MODULE_LICENSE("GPL");
505
506 module_init(gks_init);
507 module_exit(gks_exit);
508