Whamcloud - gitweb
LU-3289 gss: Shared key mechanism & flavors 29/8629/5
authorAndrew Korty <ajk@iu.edu>
Thu, 19 Dec 2013 22:13:17 +0000 (14:13 -0800)
committerOleg Drokin <oleg.drokin@intel.com>
Wed, 12 Feb 2014 06:15:24 +0000 (06:15 +0000)
Implement security flavors and GSSAPI mechanism to perform shared key
authentication (ski) and encryption (skpi).

Signed-off-by: Andrew Korty <ajk@iu.edu>
Change-Id: I48855c098965fcf527b3949c6dfb181d457b4ca5
Reviewed-on: http://review.whamcloud.com/8629
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Tested-by: Jenkins
Reviewed-by: Ken Hornstein <kenh@cmf.nrl.navy.mil>
Tested-by: Maloo <hpdd-maloo@intel.com>
lustre/include/lustre_sec.h
lustre/ptlrpc/gss/gss_internal.h
lustre/ptlrpc/gss/gss_sk_mech.c [new file with mode: 0644]
lustre/ptlrpc/gss/sec_gss.c
lustre/ptlrpc/sec.c
lustre/utils/gss/gss_oids.c
lustre/utils/gss/gss_oids.h

index 23652c2..5954292 100644 (file)
@@ -103,6 +103,7 @@ enum sptlrpc_mech_plain {
 enum sptlrpc_mech_gss {
         SPTLRPC_MECH_GSS_NULL           = 0,
         SPTLRPC_MECH_GSS_KRB5           = 1,
 enum sptlrpc_mech_gss {
         SPTLRPC_MECH_GSS_NULL           = 0,
         SPTLRPC_MECH_GSS_KRB5           = 1,
+       SPTLRPC_MECH_GSS_SK             = 2,
         SPTLRPC_MECH_GSS_MAX,
 };
 
         SPTLRPC_MECH_GSS_MAX,
 };
 
@@ -180,6 +181,10 @@ enum sptlrpc_bulk_service {
         MAKE_BASE_SUBFLVR(SPTLRPC_MECH_GSS_KRB5, SPTLRPC_SVC_INTG)
 #define SPTLRPC_SUBFLVR_KRB5P                                           \
         MAKE_BASE_SUBFLVR(SPTLRPC_MECH_GSS_KRB5, SPTLRPC_SVC_PRIV)
         MAKE_BASE_SUBFLVR(SPTLRPC_MECH_GSS_KRB5, SPTLRPC_SVC_INTG)
 #define SPTLRPC_SUBFLVR_KRB5P                                           \
         MAKE_BASE_SUBFLVR(SPTLRPC_MECH_GSS_KRB5, SPTLRPC_SVC_PRIV)
+#define SPTLRPC_SUBFLVR_SKI                                             \
+       MAKE_BASE_SUBFLVR(SPTLRPC_MECH_GSS_SK, SPTLRPC_SVC_INTG)
+#define SPTLRPC_SUBFLVR_SKPI                                            \
+       MAKE_BASE_SUBFLVR(SPTLRPC_MECH_GSS_SK, SPTLRPC_SVC_PRIV)
 
 /*
  * "end user" flavors
 
 /*
  * "end user" flavors
@@ -226,6 +231,18 @@ enum sptlrpc_bulk_service {
                   SPTLRPC_SVC_PRIV,                     \
                   SPTLRPC_BULK_DEFAULT,                 \
                   SPTLRPC_BULK_SVC_PRIV)
                   SPTLRPC_SVC_PRIV,                     \
                   SPTLRPC_BULK_DEFAULT,                 \
                   SPTLRPC_BULK_SVC_PRIV)
+#define SPTLRPC_FLVR_SKI                                \
+       MAKE_FLVR(SPTLRPC_POLICY_GSS,                   \
+                 SPTLRPC_MECH_GSS_SK,                  \
+                 SPTLRPC_SVC_INTG,                     \
+                 SPTLRPC_BULK_DEFAULT,                 \
+                 SPTLRPC_BULK_SVC_PRIV)
+#define SPTLRPC_FLVR_SKPI                               \
+       MAKE_FLVR(SPTLRPC_POLICY_GSS,                   \
+                 SPTLRPC_MECH_GSS_SK,                  \
+                 SPTLRPC_SVC_PRIV,                     \
+                 SPTLRPC_BULK_DEFAULT,                 \
+                 SPTLRPC_BULK_SVC_PRIV)
 
 #define SPTLRPC_FLVR_DEFAULT            SPTLRPC_FLVR_NULL
 
 
 #define SPTLRPC_FLVR_DEFAULT            SPTLRPC_FLVR_NULL
 
index a844e65..6ab961c 100644 (file)
@@ -512,6 +512,9 @@ void cleanup_null_module(void);
 int __init init_kerberos_module(void);
 void cleanup_kerberos_module(void);
 
 int __init init_kerberos_module(void);
 void cleanup_kerberos_module(void);
 
+/* gss_sk_mech.c */
+int __init init_sk_module(void);
+void cleanup_sk_module(void);
 
 /* debug */
 static inline
 
 /* debug */
 static inline
diff --git a/lustre/ptlrpc/gss/gss_sk_mech.c b/lustre/ptlrpc/gss/gss_sk_mech.c
new file mode 100644 (file)
index 0000000..ae9a11f
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (C) 2013, Trustees of Indiana University
+ * Author: Andrew Korty <ajk@iu.edu>
+ */
+
+#define DEBUG_SUBSYSTEM S_SEC
+#ifdef __KERNEL__
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/crypto.h>
+#include <linux/mutex.h>
+#else
+#include <liblustre.h>
+#endif
+
+#include <obd.h>
+#include <obd_class.h>
+#include <obd_support.h>
+
+#include "gss_err.h"
+#include "gss_internal.h"
+#include "gss_api.h"
+#include "gss_asn1.h"
+
+struct sk_ctx {
+};
+
+static
+__u32 gss_import_sec_context_sk(rawobj_t *inbuf, struct gss_ctx *gss_context)
+{
+       struct sk_ctx *sk_context;
+
+       if (inbuf == NULL || inbuf->data == NULL)
+               return GSS_S_FAILURE;
+
+       OBD_ALLOC_PTR(sk_context);
+       if (sk_context == NULL)
+               return GSS_S_FAILURE;
+
+       gss_context->internal_ctx_id = sk_context;
+       CDEBUG(D_SEC, "succesfully imported sk context\n");
+
+       return GSS_S_COMPLETE;
+}
+
+static
+__u32 gss_copy_reverse_context_sk(struct gss_ctx *gss_context_old,
+                                   struct gss_ctx *gss_context_new)
+{
+       struct sk_ctx *sk_context_old;
+       struct sk_ctx *sk_context_new;
+
+       OBD_ALLOC_PTR(sk_context_new);
+       if (sk_context_new == NULL)
+               return GSS_S_FAILURE;
+
+       sk_context_old = gss_context_old->internal_ctx_id;
+       memcpy(sk_context_new, sk_context_old, sizeof *sk_context_new);
+       gss_context_new->internal_ctx_id = sk_context_new;
+       CDEBUG(D_SEC, "succesfully copied reverse sk context\n");
+
+       return GSS_S_COMPLETE;
+}
+
+static
+__u32 gss_inquire_context_sk(struct gss_ctx *gss_context,
+                              unsigned long *endtime)
+{
+       *endtime = 0;
+       return GSS_S_COMPLETE;
+}
+
+static
+__u32 gss_get_mic_sk(struct gss_ctx *gss_context,
+                    int message_count,
+                    rawobj_t *messages,
+                    int iov_count,
+                    lnet_kiov_t *iovs,
+                    rawobj_t *token)
+{
+       token->data = NULL;
+       token->len = 0;
+
+       return GSS_S_COMPLETE;
+}
+
+static
+__u32 gss_verify_mic_sk(struct gss_ctx *gss_context,
+                       int message_count,
+                       rawobj_t *messages,
+                       int iov_count,
+                       lnet_kiov_t *iovs,
+                       rawobj_t *token)
+{
+       return GSS_S_COMPLETE;
+}
+
+static
+__u32 gss_wrap_sk(struct gss_ctx *gss_context, rawobj_t *gss_header,
+                   rawobj_t *message, int message_buffer_length,
+                   rawobj_t *token)
+{
+       return GSS_S_COMPLETE;
+}
+
+static
+__u32 gss_unwrap_sk(struct gss_ctx *gss_context, rawobj_t *gss_header,
+                     rawobj_t *token, rawobj_t *message)
+{
+       return GSS_S_COMPLETE;
+}
+
+static
+__u32 gss_prep_bulk_sk(struct gss_ctx *gss_context,
+                        struct ptlrpc_bulk_desc *desc)
+{
+       return GSS_S_COMPLETE;
+}
+
+static
+__u32 gss_wrap_bulk_sk(struct gss_ctx *gss_context,
+                        struct ptlrpc_bulk_desc *desc, rawobj_t *token,
+                        int adj_nob)
+{
+       return GSS_S_COMPLETE;
+}
+
+static
+__u32 gss_unwrap_bulk_sk(struct gss_ctx *gss_context,
+                          struct ptlrpc_bulk_desc *desc,
+                          rawobj_t *token, int adj_nob)
+{
+       return GSS_S_COMPLETE;
+}
+
+static
+void gss_delete_sec_context_sk(void *internal_context)
+{
+       struct sk_ctx *sk_context = internal_context;
+
+       OBD_FREE_PTR(sk_context);
+}
+
+int gss_display_sk(struct gss_ctx *gss_context, char *buf, int bufsize)
+{
+       return snprintf(buf, bufsize, "sk");
+}
+
+static struct gss_api_ops gss_sk_ops = {
+       .gss_import_sec_context     = gss_import_sec_context_sk,
+       .gss_copy_reverse_context   = gss_copy_reverse_context_sk,
+       .gss_inquire_context        = gss_inquire_context_sk,
+       .gss_get_mic                = gss_get_mic_sk,
+       .gss_verify_mic             = gss_verify_mic_sk,
+       .gss_wrap                   = gss_wrap_sk,
+       .gss_unwrap                 = gss_unwrap_sk,
+       .gss_prep_bulk              = gss_prep_bulk_sk,
+       .gss_wrap_bulk              = gss_wrap_bulk_sk,
+       .gss_unwrap_bulk            = gss_unwrap_bulk_sk,
+       .gss_delete_sec_context     = gss_delete_sec_context_sk,
+       .gss_display                = gss_display_sk,
+};
+
+static struct subflavor_desc gss_sk_sfs[] = {
+       {
+               .sf_subflavor   = SPTLRPC_SUBFLVR_SKI,
+               .sf_qop         = 0,
+               .sf_service     = SPTLRPC_SVC_INTG,
+               .sf_name        = "ski"
+       },
+       {
+               .sf_subflavor   = SPTLRPC_SUBFLVR_SKPI,
+               .sf_qop         = 0,
+               .sf_service     = SPTLRPC_SVC_PRIV,
+               .sf_name        = "skpi"
+       },
+};
+
+/*
+ * currently we leave module owner NULL
+ */
+static struct gss_api_mech gss_sk_mech = {
+       .gm_owner       = NULL, /*THIS_MODULE, */
+       .gm_name        = "sk",
+       .gm_oid         = (rawobj_t) {
+               12,
+               "\053\006\001\004\001\311\146\215\126\001\000\001",
+       },
+       .gm_ops         = &gss_sk_ops,
+       .gm_sf_num      = 2,
+       .gm_sfs         = gss_sk_sfs,
+};
+
+int __init init_sk_module(void)
+{
+       int status;
+
+       status = lgss_mech_register(&gss_sk_mech);
+       if (status)
+               CERROR("Failed to register sk gss mechanism!\n");
+
+       return status;
+}
+
+void cleanup_sk_module(void)
+{
+       lgss_mech_unregister(&gss_sk_mech);
+}
index 377e367..e7d2b22 100644 (file)
@@ -2871,34 +2871,40 @@ int __init sptlrpc_gss_init(void)
        if (rc)
                goto out_null;
 
        if (rc)
                goto out_null;
 
-        /* register policy after all other stuff be intialized, because it
-         * might be in used immediately after the registration. */
+       rc = init_sk_module();
+       if (rc)
+               goto out_kerberos;
 
 
-        rc = gss_init_keyring();
-        if (rc)
-                goto out_kerberos;
+       /* register policy after all other stuff be intialized, because it
+        * might be in used immediately after the registration. */
 
 
-        rc = gss_init_pipefs();
-        if (rc)
-                goto out_keyring;
+       rc = gss_init_keyring();
+       if (rc)
+               goto out_sk;
 
 
-        gss_init_at_reply_offset();
+       rc = gss_init_pipefs();
+       if (rc)
+               goto out_keyring;
 
 
-        return 0;
+       gss_init_at_reply_offset();
+
+       return 0;
 
 out_keyring:
 
 out_keyring:
-        gss_exit_keyring();
+       gss_exit_keyring();
+out_sk:
+       cleanup_sk_module();
 out_kerberos:
 out_kerberos:
-        cleanup_kerberos_module();
+       cleanup_kerberos_module();
 out_null:
        cleanup_null_module();
 out_svc_upcall:
 out_null:
        cleanup_null_module();
 out_svc_upcall:
-        gss_exit_svc_upcall();
+       gss_exit_svc_upcall();
 out_cli_upcall:
 out_cli_upcall:
-        gss_exit_cli_upcall();
+       gss_exit_cli_upcall();
 out_lproc:
 out_lproc:
-        gss_exit_lproc();
-        return rc;
+       gss_exit_lproc();
+       return rc;
 }
 
 static void __exit sptlrpc_gss_exit(void)
 }
 
 static void __exit sptlrpc_gss_exit(void)
index fbea227..897b8fc 100644 (file)
@@ -172,8 +172,12 @@ __u32 sptlrpc_name2flavor_base(const char *name)
                 return SPTLRPC_FLVR_KRB5I;
         if (!strcmp(name, "krb5p"))
                 return SPTLRPC_FLVR_KRB5P;
                 return SPTLRPC_FLVR_KRB5I;
         if (!strcmp(name, "krb5p"))
                 return SPTLRPC_FLVR_KRB5P;
+       if (!strcmp(name, "ski"))
+               return SPTLRPC_FLVR_SKI;
+       if (!strcmp(name, "skpi"))
+               return SPTLRPC_FLVR_SKPI;
 
 
-        return SPTLRPC_FLVR_INVALID;
+       return SPTLRPC_FLVR_INVALID;
 }
 EXPORT_SYMBOL(sptlrpc_name2flavor_base);
 
 }
 EXPORT_SYMBOL(sptlrpc_name2flavor_base);
 
@@ -195,9 +199,13 @@ const char *sptlrpc_flavor2name_base(__u32 flvr)
                 return "krb5i";
         else if (base == SPTLRPC_FLVR_BASE(SPTLRPC_FLVR_KRB5P))
                 return "krb5p";
                 return "krb5i";
         else if (base == SPTLRPC_FLVR_BASE(SPTLRPC_FLVR_KRB5P))
                 return "krb5p";
+       else if (base == SPTLRPC_FLVR_BASE(SPTLRPC_FLVR_SKI))
+               return "ski";
+       else if (base == SPTLRPC_FLVR_BASE(SPTLRPC_FLVR_SKPI))
+               return "skpi";
 
 
-        CERROR("invalid wire flavor 0x%x\n", flvr);
-        return "invalid";
+       CERROR("invalid wire flavor 0x%x\n", flvr);
+       return "invalid";
 }
 EXPORT_SYMBOL(sptlrpc_flavor2name_base);
 
 }
 EXPORT_SYMBOL(sptlrpc_flavor2name_base);
 
index 0c839c8..cf669ab 100644 (file)
@@ -45,6 +45,10 @@ gss_OID_desc nulloid = {
        12,
        "\053\006\001\004\001\311\146\215\126\001\000\000",
 };
        12,
        "\053\006\001\004\001\311\146\215\126\001\000\000",
 };
+gss_OID_desc skoid = {
+       12,
+       "\053\006\001\004\001\311\146\215\126\001\000\001",
+};
 
 gss_OID_desc spkm3oid = {
        7,
 
 gss_OID_desc spkm3oid = {
        7,
index 8234ef2..f73f0f5 100644 (file)
@@ -35,6 +35,7 @@
 
 extern gss_OID_desc krb5oid;
 extern gss_OID_desc nulloid;
 
 extern gss_OID_desc krb5oid;
 extern gss_OID_desc nulloid;
+extern gss_OID_desc skoid;
 extern gss_OID_desc spkm3oid;
 
 #ifndef g_OID_equal
 extern gss_OID_desc spkm3oid;
 
 #ifndef g_OID_equal