From 6323d52abfe4cf1eda06b4ac3a5b325d9fa13276 Mon Sep 17 00:00:00 2001 From: Andrew Korty Date: Thu, 19 Dec 2013 14:13:17 -0800 Subject: [PATCH] LU-3289 gss: Shared key mechanism & flavors Implement security flavors and GSSAPI mechanism to perform shared key authentication (ski) and encryption (skpi). Signed-off-by: Andrew Korty Change-Id: I48855c098965fcf527b3949c6dfb181d457b4ca5 Reviewed-on: http://review.whamcloud.com/8629 Reviewed-by: Andreas Dilger Tested-by: Jenkins Reviewed-by: Ken Hornstein Tested-by: Maloo --- lustre/include/lustre_sec.h | 17 +++ lustre/ptlrpc/gss/gss_internal.h | 3 + lustre/ptlrpc/gss/gss_sk_mech.c | 230 +++++++++++++++++++++++++++++++++++++++ lustre/ptlrpc/gss/sec_gss.c | 38 ++++--- lustre/ptlrpc/sec.c | 14 ++- lustre/utils/gss/gss_oids.c | 4 + lustre/utils/gss/gss_oids.h | 1 + 7 files changed, 288 insertions(+), 19 deletions(-) create mode 100644 lustre/ptlrpc/gss/gss_sk_mech.c diff --git a/lustre/include/lustre_sec.h b/lustre/include/lustre_sec.h index 23652c2..5954292 100644 --- a/lustre/include/lustre_sec.h +++ b/lustre/include/lustre_sec.h @@ -103,6 +103,7 @@ enum sptlrpc_mech_plain { enum sptlrpc_mech_gss { SPTLRPC_MECH_GSS_NULL = 0, SPTLRPC_MECH_GSS_KRB5 = 1, + SPTLRPC_MECH_GSS_SK = 2, 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) +#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 @@ -226,6 +231,18 @@ enum sptlrpc_bulk_service { 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 diff --git a/lustre/ptlrpc/gss/gss_internal.h b/lustre/ptlrpc/gss/gss_internal.h index a844e65..6ab961c 100644 --- a/lustre/ptlrpc/gss/gss_internal.h +++ b/lustre/ptlrpc/gss/gss_internal.h @@ -512,6 +512,9 @@ void cleanup_null_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 diff --git a/lustre/ptlrpc/gss/gss_sk_mech.c b/lustre/ptlrpc/gss/gss_sk_mech.c new file mode 100644 index 0000000..ae9a11f --- /dev/null +++ b/lustre/ptlrpc/gss/gss_sk_mech.c @@ -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 + */ + +#define DEBUG_SUBSYSTEM S_SEC +#ifdef __KERNEL__ +#include +#include +#include +#include +#include +#else +#include +#endif + +#include +#include +#include + +#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); +} diff --git a/lustre/ptlrpc/gss/sec_gss.c b/lustre/ptlrpc/gss/sec_gss.c index 377e367..e7d2b22 100644 --- a/lustre/ptlrpc/gss/sec_gss.c +++ b/lustre/ptlrpc/gss/sec_gss.c @@ -2871,34 +2871,40 @@ int __init sptlrpc_gss_init(void) 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: - gss_exit_keyring(); + gss_exit_keyring(); +out_sk: + cleanup_sk_module(); out_kerberos: - cleanup_kerberos_module(); + cleanup_kerberos_module(); out_null: cleanup_null_module(); out_svc_upcall: - gss_exit_svc_upcall(); + gss_exit_svc_upcall(); out_cli_upcall: - gss_exit_cli_upcall(); + gss_exit_cli_upcall(); out_lproc: - gss_exit_lproc(); - return rc; + gss_exit_lproc(); + return rc; } static void __exit sptlrpc_gss_exit(void) diff --git a/lustre/ptlrpc/sec.c b/lustre/ptlrpc/sec.c index fbea227..897b8fc 100644 --- a/lustre/ptlrpc/sec.c +++ b/lustre/ptlrpc/sec.c @@ -172,8 +172,12 @@ __u32 sptlrpc_name2flavor_base(const char *name) 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); @@ -195,9 +199,13 @@ const char *sptlrpc_flavor2name_base(__u32 flvr) 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); diff --git a/lustre/utils/gss/gss_oids.c b/lustre/utils/gss/gss_oids.c index 0c839c8..cf669ab 100644 --- a/lustre/utils/gss/gss_oids.c +++ b/lustre/utils/gss/gss_oids.c @@ -45,6 +45,10 @@ gss_OID_desc nulloid = { 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, diff --git a/lustre/utils/gss/gss_oids.h b/lustre/utils/gss/gss_oids.h index 8234ef2..f73f0f5 100644 --- a/lustre/utils/gss/gss_oids.h +++ b/lustre/utils/gss/gss_oids.h @@ -35,6 +35,7 @@ extern gss_OID_desc krb5oid; extern gss_OID_desc nulloid; +extern gss_OID_desc skoid; extern gss_OID_desc spkm3oid; #ifndef g_OID_equal -- 1.8.3.1