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