Commit b7856020 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

staging: lustre: ptlrpc: gss: delete unused code

The gss code has never been built, there is no Kconfig option for it, so
delete it as code that can not build goes bad really fast.

If someone wants it back, they can revert this and fix any build errors
that might be in it.

Cc: Andreas Dilger <andreas.dilger@intel.com>
Cc: Oleg Drokin <oleg.drokin@intel.com>
Cc: hpdd-discuss <hpdd-discuss@lists.01.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent e27db149
......@@ -18,5 +18,3 @@ ptlrpc_objs += sec_null.o sec_plain.o nrs.o nrs_fifo.o
ptlrpc-y := $(ldlm_objs) $(ptlrpc_objs)
ptlrpc-$(CONFIG_PROC_FS) += sec_lproc.o
ptlrpc-$(CONFIG_LUSTRE_TRANSLATE_ERRNOS) += errno.o
obj-$(CONFIG_PTLRPC_GSS) += gss/
obj-$(CONFIG_LUSTRE_FS) := ptlrpc_gss.o
ptlrpc_gss-y := sec_gss.o gss_bulk.o gss_cli_upcall.o gss_svc_upcall.o \
gss_rawobj.o lproc_gss.o gss_generic_token.o \
gss_mech_switch.o gss_krb5_mech.o
ccflags-y := -I$(src)/../include
/*
* Modifications for Lustre
*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*
* Author: Eric Mei <ericm@clusterfs.com>
*/
/*
* Somewhat simplified version of the gss api.
*
* Dug Song <dugsong@monkey.org>
* Andy Adamson <andros@umich.edu>
* Bruce Fields <bfields@umich.edu>
* Copyright (c) 2000 The Regents of the University of Michigan
*
*/
#ifndef __PTLRPC_GSS_GSS_API_H_
#define __PTLRPC_GSS_GSS_API_H_
struct gss_api_mech;
/* The mechanism-independent gss-api context: */
struct gss_ctx {
struct gss_api_mech *mech_type;
void *internal_ctx_id;
};
#define GSS_C_NO_BUFFER ((rawobj_t) 0)
#define GSS_C_NO_CONTEXT ((struct gss_ctx *) 0)
#define GSS_C_NULL_OID ((rawobj_t) 0)
/*
* gss-api prototypes; note that these are somewhat simplified versions of
* the prototypes specified in RFC 2744.
*/
__u32 lgss_import_sec_context(
rawobj_t *input_token,
struct gss_api_mech *mech,
struct gss_ctx **ctx);
__u32 lgss_copy_reverse_context(
struct gss_ctx *ctx,
struct gss_ctx **ctx_new);
__u32 lgss_inquire_context(
struct gss_ctx *ctx,
unsigned long *endtime);
__u32 lgss_get_mic(
struct gss_ctx *ctx,
int msgcnt,
rawobj_t *msgs,
int iovcnt,
lnet_kiov_t *iovs,
rawobj_t *mic_token);
__u32 lgss_verify_mic(
struct gss_ctx *ctx,
int msgcnt,
rawobj_t *msgs,
int iovcnt,
lnet_kiov_t *iovs,
rawobj_t *mic_token);
__u32 lgss_wrap(
struct gss_ctx *ctx,
rawobj_t *gsshdr,
rawobj_t *msg,
int msg_buflen,
rawobj_t *out_token);
__u32 lgss_unwrap(
struct gss_ctx *ctx,
rawobj_t *gsshdr,
rawobj_t *token,
rawobj_t *out_msg);
__u32 lgss_prep_bulk(
struct gss_ctx *gctx,
struct ptlrpc_bulk_desc *desc);
__u32 lgss_wrap_bulk(
struct gss_ctx *gctx,
struct ptlrpc_bulk_desc *desc,
rawobj_t *token,
int adj_nob);
__u32 lgss_unwrap_bulk(
struct gss_ctx *gctx,
struct ptlrpc_bulk_desc *desc,
rawobj_t *token,
int adj_nob);
__u32 lgss_delete_sec_context(
struct gss_ctx **ctx);
int lgss_display(
struct gss_ctx *ctx,
char *buf,
int bufsize);
struct subflavor_desc {
__u32 sf_subflavor;
__u32 sf_qop;
__u32 sf_service;
char *sf_name;
};
/* Each mechanism is described by the following struct: */
struct gss_api_mech {
struct list_head gm_list;
struct module *gm_owner;
char *gm_name;
rawobj_t gm_oid;
atomic_t gm_count;
struct gss_api_ops *gm_ops;
int gm_sf_num;
struct subflavor_desc *gm_sfs;
};
/* and must provide the following operations: */
struct gss_api_ops {
__u32 (*gss_import_sec_context)(
rawobj_t *input_token,
struct gss_ctx *ctx);
__u32 (*gss_copy_reverse_context)(
struct gss_ctx *ctx,
struct gss_ctx *ctx_new);
__u32 (*gss_inquire_context)(
struct gss_ctx *ctx,
unsigned long *endtime);
__u32 (*gss_get_mic)(
struct gss_ctx *ctx,
int msgcnt,
rawobj_t *msgs,
int iovcnt,
lnet_kiov_t *iovs,
rawobj_t *mic_token);
__u32 (*gss_verify_mic)(
struct gss_ctx *ctx,
int msgcnt,
rawobj_t *msgs,
int iovcnt,
lnet_kiov_t *iovs,
rawobj_t *mic_token);
__u32 (*gss_wrap)(
struct gss_ctx *ctx,
rawobj_t *gsshdr,
rawobj_t *msg,
int msg_buflen,
rawobj_t *out_token);
__u32 (*gss_unwrap)(
struct gss_ctx *ctx,
rawobj_t *gsshdr,
rawobj_t *token,
rawobj_t *out_msg);
__u32 (*gss_prep_bulk)(
struct gss_ctx *gctx,
struct ptlrpc_bulk_desc *desc);
__u32 (*gss_wrap_bulk)(
struct gss_ctx *gctx,
struct ptlrpc_bulk_desc *desc,
rawobj_t *token,
int adj_nob);
__u32 (*gss_unwrap_bulk)(
struct gss_ctx *gctx,
struct ptlrpc_bulk_desc *desc,
rawobj_t *token,
int adj_nob);
void (*gss_delete_sec_context)(
void *ctx);
int (*gss_display)(
struct gss_ctx *ctx,
char *buf,
int bufsize);
};
int lgss_mech_register(struct gss_api_mech *mech);
void lgss_mech_unregister(struct gss_api_mech *mech);
struct gss_api_mech * lgss_OID_to_mech(rawobj_t *oid);
struct gss_api_mech * lgss_name_to_mech(char *name);
struct gss_api_mech * lgss_subflavor_to_mech(__u32 subflavor);
struct gss_api_mech * lgss_mech_get(struct gss_api_mech *mech);
void lgss_mech_put(struct gss_api_mech *mech);
#endif /* __PTLRPC_GSS_GSS_API_H_ */
/*
* Modifications for Lustre
*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*
* Author: Eric Mei <ericm@clusterfs.com>
*/
/*
* minimal asn1 for generic encoding/decoding of gss tokens
*
* Adapted from MIT Kerberos 5-1.2.1 lib/include/krb5.h,
* lib/gssapi/krb5/gssapiP_krb5.h, and others
*
* Copyright (c) 2000 The Regents of the University of Michigan.
* All rights reserved.
*
* Andy Adamson <andros@umich.edu>
*/
/*
* Copyright 1995 by the Massachusetts Institute of Technology.
* All Rights Reserved.
*
* Export of this software from the United States of America may
* require a specific license from the United States Government.
* It is the responsibility of any person or organization contemplating
* export to obtain such a license before exporting.
*
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
* distribute this software and its documentation for any purpose and
* without fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright notice and
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
* permission. Furthermore if you modify this software you must label
* your software as modified software and not distribute it in such a
* fashion that it might be confused with the original M.I.T. software.
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
*
*/
#define SIZEOF_INT 4
/* from gssapi_err_generic.h */
#define G_BAD_SERVICE_NAME (-2045022976L)
#define G_BAD_STRING_UID (-2045022975L)
#define G_NOUSER (-2045022974L)
#define G_VALIDATE_FAILED (-2045022973L)
#define G_BUFFER_ALLOC (-2045022972L)
#define G_BAD_MSG_CTX (-2045022971L)
#define G_WRONG_SIZE (-2045022970L)
#define G_BAD_USAGE (-2045022969L)
#define G_UNKNOWN_QOP (-2045022968L)
#define G_NO_HOSTNAME (-2045022967L)
#define G_BAD_HOSTNAME (-2045022966L)
#define G_WRONG_MECH (-2045022965L)
#define G_BAD_TOK_HEADER (-2045022964L)
#define G_BAD_DIRECTION (-2045022963L)
#define G_TOK_TRUNC (-2045022962L)
#define G_REFLECT (-2045022961L)
#define G_WRONG_TOKID (-2045022960L)
#define g_OID_equal(o1, o2) \
(((o1)->len == (o2)->len) && \
(memcmp((o1)->data, (o2)->data, (int) (o1)->len) == 0))
__u32 g_verify_token_header(rawobj_t *mech,
int *body_size,
unsigned char **buf_in,
int toksize);
__u32 g_get_mech_oid(rawobj_t *mech,
rawobj_t *in_buf);
int g_token_size(rawobj_t *mech,
unsigned int body_size);
void g_make_token_header(rawobj_t *mech,
int body_size,
unsigned char **buf);
This diff is collapsed.
/*
* Modifications for Lustre
*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*
* Author: Eric Mei <ericm@clusterfs.com>
*/
/*
* Adapted from MIT Kerberos 5-1.2.1 include/gssapi/gssapi.h
*
* Copyright (c) 2002 The Regents of the University of Michigan.
* All rights reserved.
*
* Andy Adamson <andros@umich.edu>
*/
/*
* Copyright 1993 by OpenVision Technologies, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appears in all copies and
* that both that copyright notice and this permission notice appear in
* supporting documentation, and that the name of OpenVision not be used
* in advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. OpenVision makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
* OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __PTLRPC_GSS_GSS_ERR_H_
#define __PTLRPC_GSS_GSS_ERR_H_
typedef unsigned int OM_uint32;
/*
* Flag bits for context-level services.
*/
#define GSS_C_DELEG_FLAG (1)
#define GSS_C_MUTUAL_FLAG (2)
#define GSS_C_REPLAY_FLAG (4)
#define GSS_C_SEQUENCE_FLAG (8)
#define GSS_C_CONF_FLAG (16)
#define GSS_C_INTEG_FLAG (32)
#define GSS_C_ANON_FLAG (64)
#define GSS_C_PROT_READY_FLAG (128)
#define GSS_C_TRANS_FLAG (256)
/*
* Credential usage options
*/
#define GSS_C_BOTH (0)
#define GSS_C_INITIATE (1)
#define GSS_C_ACCEPT (2)
/*
* Status code types for gss_display_status
*/
#define GSS_C_GSS_CODE (1)
#define GSS_C_MECH_CODE (2)
/*
* Define the default Quality of Protection for per-message services. Note
* that an implementation that offers multiple levels of QOP may either reserve
* a value (for example zero, as assumed here) to mean "default protection", or
* alternatively may simply equate GSS_C_QOP_DEFAULT to a specific explicit
* QOP value. However a value of 0 should always be interpreted by a GSSAPI
* implementation as a request for the default protection level.
*/
#define GSS_C_QOP_DEFAULT (0)
/*
* Expiration time of 2^32-1 seconds means infinite lifetime for a
* credential or security context
*/
#define GSS_C_INDEFINITE ((OM_uint32) 0xfffffffful)
/* Major status codes */
#define GSS_S_COMPLETE (0)
/*
* Some "helper" definitions to make the status code macros obvious.
*/
#define GSS_C_CALLING_ERROR_OFFSET (24)
#define GSS_C_ROUTINE_ERROR_OFFSET (16)
#define GSS_C_SUPPLEMENTARY_OFFSET (0)
#define GSS_C_CALLING_ERROR_MASK ((OM_uint32) 0377ul)
#define GSS_C_ROUTINE_ERROR_MASK ((OM_uint32) 0377ul)
#define GSS_C_SUPPLEMENTARY_MASK ((OM_uint32) 0177777ul)
/*
* The macros that test status codes for error conditions. Note that the
* GSS_ERROR() macro has changed slightly from the V1 GSSAPI so that it now
* evaluates its argument only once.
*/
#define GSS_CALLING_ERROR(x) \
((x) & (GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET))
#define GSS_ROUTINE_ERROR(x) \
((x) & (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET))
#define GSS_SUPPLEMENTARY_INFO(x) \
((x) & (GSS_C_SUPPLEMENTARY_MASK << GSS_C_SUPPLEMENTARY_OFFSET))
#define GSS_ERROR(x) \
((x) & ((GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET) | \
(GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET)))
/*
* Now the actual status code definitions
*/
/*
* Calling errors:
*/
#define GSS_S_CALL_INACCESSIBLE_READ \
(((OM_uint32) 1ul) << GSS_C_CALLING_ERROR_OFFSET)
#define GSS_S_CALL_INACCESSIBLE_WRITE \
(((OM_uint32) 2ul) << GSS_C_CALLING_ERROR_OFFSET)
#define GSS_S_CALL_BAD_STRUCTURE \
(((OM_uint32) 3ul) << GSS_C_CALLING_ERROR_OFFSET)
/*
* Routine errors:
*/
#define GSS_S_BAD_MECH \
(((OM_uint32) 1ul) << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_BAD_NAME \
(((OM_uint32) 2ul) << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_BAD_NAMETYPE \
(((OM_uint32) 3ul) << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_BAD_BINDINGS \
(((OM_uint32) 4ul) << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_BAD_STATUS \
(((OM_uint32) 5ul) << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_BAD_SIG \
(((OM_uint32) 6ul) << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_NO_CRED \
(((OM_uint32) 7ul) << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_NO_CONTEXT \
(((OM_uint32) 8ul) << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_DEFECTIVE_TOKEN \
(((OM_uint32) 9ul) << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_DEFECTIVE_CREDENTIAL \
(((OM_uint32) 10ul) << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_CREDENTIALS_EXPIRED \
(((OM_uint32) 11ul) << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_CONTEXT_EXPIRED \
(((OM_uint32) 12ul) << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_FAILURE \
(((OM_uint32) 13ul) << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_BAD_QOP \
(((OM_uint32) 14ul) << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_UNAUTHORIZED \
(((OM_uint32) 15ul) << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_UNAVAILABLE \
(((OM_uint32) 16ul) << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_DUPLICATE_ELEMENT \
(((OM_uint32) 17ul) << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_NAME_NOT_MN \
(((OM_uint32) 18ul) << GSS_C_ROUTINE_ERROR_OFFSET)
/*
* Supplementary info bits:
*/
#define GSS_S_CONTINUE_NEEDED (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 0))
#define GSS_S_DUPLICATE_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 1))
#define GSS_S_OLD_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 2))
#define GSS_S_UNSEQ_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 3))
#define GSS_S_GAP_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 4))
/* XXXX these are not part of the GSSAPI C bindings! (but should be) */
#define GSS_CALLING_ERROR_FIELD(x) \
(((x) >> GSS_C_CALLING_ERROR_OFFSET) & GSS_C_CALLING_ERROR_MASK)
#define GSS_ROUTINE_ERROR_FIELD(x) \
(((x) >> GSS_C_ROUTINE_ERROR_OFFSET) & GSS_C_ROUTINE_ERROR_MASK)
#define GSS_SUPPLEMENTARY_INFO_FIELD(x) \
(((x) >> GSS_C_SUPPLEMENTARY_OFFSET) & GSS_C_SUPPLEMENTARY_MASK)
/* XXXX This is a necessary evil until the spec is fixed */
#define GSS_S_CRED_UNAVAIL GSS_S_FAILURE
#endif /* __PTLRPC_GSS_GSS_ERR_H_ */
/*
* Modifications for Lustre
*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*
* Copyright (c) 2011, Intel Corporation.
*
* Author: Eric Mei <ericm@clusterfs.com>
*/
/*
* linux/net/sunrpc/gss_generic_token.c
*
* Adapted from MIT Kerberos 5-1.2.1 lib/gssapi/generic/util_token.c
*
* Copyright (c) 2000 The Regents of the University of Michigan.
* All rights reserved.
*
* Andy Adamson <andros@umich.edu>
*/
/*
* Copyright 1993 by OpenVision Technologies, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appears in all copies and
* that both that copyright notice and this permission notice appear in
* supporting documentation, and that the name of OpenVision not be used
* in advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. OpenVision makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
* OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#define DEBUG_SUBSYSTEM S_SEC
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/mutex.h>
#include <obd.h>
#include <obd_class.h>
#include <obd_support.h>
#include <lustre/lustre_idl.h>
#include <lustre_net.h>
#include <lustre_import.h>
#include <lustre_sec.h>
#include "gss_err.h"
#include "gss_internal.h"
#include "gss_api.h"
#include "gss_krb5.h"
#include "gss_asn1.h"
/* TWRITE_STR from gssapiP_generic.h */
#define TWRITE_STR(ptr, str, len) \
memcpy((ptr), (char *) (str), (len)); \
(ptr) += (len);
/* XXXX this code currently makes the assumption that a mech oid will
never be longer than 127 bytes. This assumption is not inherent in
the interfaces, so the code can be fixed if the OSI namespace
balloons unexpectedly. */
/* Each token looks like this:
0x60 tag for APPLICATION 0, SEQUENCE
(constructed, definite-length)
<length> possible multiple bytes, need to parse/generate
0x06 tag for OBJECT IDENTIFIER
<moid_length> compile-time constant string (assume 1 byte)
<moid_bytes> compile-time constant string
<inner_bytes> the ANY containing the application token
bytes 0,1 are the token type
bytes 2,n are the token data
For the purposes of this abstraction, the token "header" consists of
the sequence tag and length octets, the mech OID DER encoding, and the
first two inner bytes, which indicate the token type. The token
"body" consists of everything else.
*/
static
int der_length_size(int length)
{
if (length < (1 << 7))
return 1;
else if (length < (1 << 8))
return 2;
#if (SIZEOF_INT == 2)
else
return 3;
#else
else if (length < (1 << 16))
return 3;
else if (length < (1 << 24))
return 4;
else
return 5;
#endif
}
static
void der_write_length(unsigned char **buf, int length)
{
if (length < (1 << 7)) {
*(*buf)++ = (unsigned char) length;
} else {
*(*buf)++ = (unsigned char) (der_length_size(length) + 127);
#if (SIZEOF_INT > 2)
if (length >= (1 << 24))
*(*buf)++ = (unsigned char) (length >> 24);
if (length >= (1 << 16))
*(*buf)++ = (unsigned char) ((length >> 16) & 0xff);
#endif
if (length >= (1 << 8))
*(*buf)++ = (unsigned char) ((length >> 8) & 0xff);
*(*buf)++ = (unsigned char) (length & 0xff);
}
}
/*
* returns decoded length, or < 0 on failure. Advances buf and
* decrements bufsize
*/
static
int der_read_length(unsigned char **buf, int *bufsize)
{
unsigned char sf;
int ret;
if (*bufsize < 1)
return -1;
sf = *(*buf)++;
(*bufsize)--;
if (sf & 0x80) {
sf &= 0x7f;
if (((*bufsize) - 1) < sf)
return -1;
if (sf > SIZEOF_INT)
return -1;
ret = 0;
for (; sf; sf--) {
ret = (ret << 8) + (*(*buf)++);
(*bufsize)--;
}
} else {
ret = sf;
}
return ret;
}
/*
* returns the length of a token, given the mech oid and the body size
*/
int g_token_size(rawobj_t *mech, unsigned int body_size)
{
/* set body_size to sequence contents size */
body_size += 4 + (int) mech->len; /* NEED overflow check */
return (1 + der_length_size(body_size) + body_size);
}
/*
* fills in a buffer with the token header. The buffer is assumed to
* be the right size. buf is advanced past the token header
*/
void g_make_token_header(rawobj_t *mech, int body_size, unsigned char **buf)
{
*(*buf)++ = 0x60;
der_write_length(buf, 4 + mech->len + body_size);
*(*buf)++ = 0x06;
*(*buf)++ = (unsigned char) mech->len;
TWRITE_STR(*buf, mech->data, ((int) mech->len));
}
/*
* Given a buffer containing a token, reads and verifies the token,
* leaving buf advanced past the token header, and setting body_size
* to the number of remaining bytes. Returns 0 on success,
* G_BAD_TOK_HEADER for a variety of errors, and G_WRONG_MECH if the
* mechanism in the token does not match the mech argument. buf and
* *body_size are left unmodified on error.
*/
__u32 g_verify_token_header(rawobj_t *mech, int *body_size,
unsigned char **buf_in, int toksize)
{
unsigned char *buf = *buf_in;
int seqsize;
rawobj_t toid;
int ret = 0;
toksize -= 1;
if (0 > toksize)
return (G_BAD_TOK_HEADER);
if (*buf++ != 0x60)
return (G_BAD_TOK_HEADER);
seqsize = der_read_length(&buf, &toksize);
if (seqsize < 0)
return(G_BAD_TOK_HEADER);
if (seqsize != toksize)
return (G_BAD_TOK_HEADER);
toksize -= 1;
if (0 > toksize)
return (G_BAD_TOK_HEADER);
if (*buf++ != 0x06)
return (G_BAD_TOK_HEADER);
toksize -= 1;
if (0 > toksize)
return (G_BAD_TOK_HEADER);
toid.len = *buf++;
toksize -= toid.len;
if (0 > toksize)
return (G_BAD_TOK_HEADER);
toid.data = buf;
buf += toid.len;
if (!g_OID_equal(&toid, mech))
ret = G_WRONG_MECH;
/* G_WRONG_MECH is not returned immediately because it's more
* important to return G_BAD_TOK_HEADER if the token header is
* in fact bad
*/
toksize -= 2;
if (0 > toksize)
return (G_BAD_TOK_HEADER);
if (ret)
return (ret);
if (!ret) {
*buf_in = buf;
*body_size = toksize;
}
return (ret);
}
/*
* Given a buffer containing a token, returns a copy of the mech oid in
* the parameter mech.
*/
__u32 g_get_mech_oid(rawobj_t *mech, rawobj_t *in_buf)
{
unsigned char *buf = in_buf->data;
int len = in_buf->len;
int ret = 0;
int seqsize;
len -= 1;
if (0 > len)
return (G_BAD_TOK_HEADER);
if (*buf++ != 0x60)
return (G_BAD_TOK_HEADER);
seqsize = der_read_length(&buf, &len);
if (seqsize < 0)
return (G_BAD_TOK_HEADER);
len -= 1;
if (0 > len)
return (G_BAD_TOK_HEADER);
if (*buf++ != 0x06)
return (G_BAD_TOK_HEADER);
len -= 1;
if (0 > len)
return (G_BAD_TOK_HEADER);
mech->len = *buf++;
len -= mech->len;
if (0 > len)
return (G_BAD_TOK_HEADER);
OBD_ALLOC_LARGE(mech->data, mech->len);
if (!mech->data)
return (G_BUFFER_ALLOC);
memcpy(mech->data, buf, mech->len);
return ret;
}
This diff is collapsed.
/*
* Modifications for Lustre
*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*
* Author: Eric Mei <ericm@clusterfs.com>
*/
/*
* linux/include/linux/sunrpc/gss_krb5_types.h
*
* Adapted from MIT Kerberos 5-1.2.1 lib/include/krb5.h,
* lib/gssapi/krb5/gssapiP_krb5.h, and others
*
* Copyright (c) 2000 The Regents of the University of Michigan.
* All rights reserved.
*
* Andy Adamson <andros@umich.edu>
* Bruce Fields <bfields@umich.edu>
*/
/*
* Copyright 1995 by the Massachusetts Institute of Technology.
* All Rights Reserved.
*
* Export of this software from the United States of America may
* require a specific license from the United States Government.
* It is the responsibility of any person or organization contemplating
* export to obtain such a license before exporting.
*
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
* distribute this software and its documentation for any purpose and
* without fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright notice and
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
* permission. Furthermore if you modify this software you must label
* your software as modified software and not distribute it in such a
* fashion that it might be confused with the original M.I.T. software.
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
*
*/
#ifndef PTLRPC_GSS_KRB5_H
#define PTLRPC_GSS_KRB5_H
/*
* RFC 4142
*/
#define KG_USAGE_ACCEPTOR_SEAL 22
#define KG_USAGE_ACCEPTOR_SIGN 23
#define KG_USAGE_INITIATOR_SEAL 24
#define KG_USAGE_INITIATOR_SIGN 25
#define KG_TOK_MIC_MSG 0x0404
#define KG_TOK_WRAP_MSG 0x0504
#define FLAG_SENDER_IS_ACCEPTOR 0x01
#define FLAG_WRAP_CONFIDENTIAL 0x02
#define FLAG_ACCEPTOR_SUBKEY 0x04
struct krb5_header {
__u16 kh_tok_id; /* token id */
__u8 kh_flags; /* acceptor flags */
__u8 kh_filler; /* 0xff */
__u16 kh_ec; /* extra count */
__u16 kh_rrc; /* right rotation count */
__u64 kh_seq; /* sequence number */
__u8 kh_cksum[0]; /* checksum */
};
struct krb5_keyblock {
rawobj_t kb_key;
struct ll_crypto_cipher *kb_tfm;
};
struct krb5_ctx {
unsigned int kc_initiate:1,
kc_cfx:1,
kc_seed_init:1,
kc_have_acceptor_subkey:1;
__s32 kc_endtime;
__u8 kc_seed[16];
__u64 kc_seq_send;
__u64 kc_seq_recv;
__u32 kc_enctype;
struct krb5_keyblock kc_keye; /* encryption */
struct krb5_keyblock kc_keyi; /* integrity */
struct krb5_keyblock kc_keyc; /* checksum */
rawobj_t kc_mech_used;
};
enum sgn_alg {
SGN_ALG_DES_MAC_MD5 = 0x0000,
SGN_ALG_MD2_5 = 0x0001,
SGN_ALG_DES_MAC = 0x0002,
SGN_ALG_3 = 0x0003, /* not published */
SGN_ALG_HMAC_MD5 = 0x0011, /* microsoft w2k; no support */
SGN_ALG_HMAC_SHA1_DES3_KD = 0x0004
};
enum seal_alg {
SEAL_ALG_NONE = 0xffff,
SEAL_ALG_DES = 0x0000,
SEAL_ALG_1 = 0x0001, /* not published */
SEAL_ALG_MICROSOFT_RC4 = 0x0010, /* microsoft w2k; no support */
SEAL_ALG_DES3KD = 0x0002
};
#define CKSUMTYPE_CRC32 0x0001
#define CKSUMTYPE_RSA_MD4 0x0002
#define CKSUMTYPE_RSA_MD4_DES 0x0003
#define CKSUMTYPE_DESCBC 0x0004
/* des-mac-k */
/* rsa-md4-des-k */
#define CKSUMTYPE_RSA_MD5 0x0007
#define CKSUMTYPE_RSA_MD5_DES 0x0008
#define CKSUMTYPE_NIST_SHA 0x0009
#define CKSUMTYPE_HMAC_SHA1_DES3 0x000c
#define CKSUMTYPE_HMAC_SHA1_96_AES128 0x000f
#define CKSUMTYPE_HMAC_SHA1_96_AES256 0x0010
#define CKSUMTYPE_HMAC_MD5_ARCFOUR -138
/* from gssapi_err_krb5.h */
#define KG_CCACHE_NOMATCH (39756032L)
#define KG_KEYTAB_NOMATCH (39756033L)
#define KG_TGT_MISSING (39756034L)
#define KG_NO_SUBKEY (39756035L)
#define KG_CONTEXT_ESTABLISHED (39756036L)
#define KG_BAD_SIGN_TYPE (39756037L)
#define KG_BAD_LENGTH (39756038L)
#define KG_CTX_INCOMPLETE (39756039L)
#define KG_CONTEXT (39756040L)
#define KG_CRED (39756041L)
#define KG_ENC_DESC (39756042L)
#define KG_BAD_SEQ (39756043L)
#define KG_EMPTY_CCACHE (39756044L)
#define KG_NO_CTYPES (39756045L)
/* per Kerberos v5 protocol spec crypto types from the wire.
* these get mapped to linux kernel crypto routines.
*/
#define ENCTYPE_NULL 0x0000
#define ENCTYPE_DES_CBC_CRC 0x0001 /* DES cbc mode with CRC-32 */
#define ENCTYPE_DES_CBC_MD4 0x0002 /* DES cbc mode with RSA-MD4 */
#define ENCTYPE_DES_CBC_MD5 0x0003 /* DES cbc mode with RSA-MD5 */
#define ENCTYPE_DES_CBC_RAW 0x0004 /* DES cbc mode raw */
/* XXX deprecated? */
#define ENCTYPE_DES3_CBC_SHA 0x0005 /* DES-3 cbc mode with NIST-SHA */
#define ENCTYPE_DES3_CBC_RAW 0x0006 /* DES-3 cbc mode raw */
#define ENCTYPE_DES_HMAC_SHA1 0x0008
#define ENCTYPE_DES3_CBC_SHA1 0x0010
#define ENCTYPE_AES128_CTS_HMAC_SHA1_96 0x0011
#define ENCTYPE_AES256_CTS_HMAC_SHA1_96 0x0012
#define ENCTYPE_ARCFOUR_HMAC 0x0017
#define ENCTYPE_ARCFOUR_HMAC_EXP 0x0018
#define ENCTYPE_UNKNOWN 0x01ff
#endif /* PTLRPC_GSS_KRB5_H */
/*
* Modifications for Lustre
*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*
* Copyright (c) 2012, Intel Corporation.
*
* Author: Eric Mei <ericm@clusterfs.com>
*/
/*
* linux/net/sunrpc/gss_mech_switch.c
*
* Copyright (c) 2001 The Regents of the University of Michigan.
* All rights reserved.
*
* J. Bruce Fields <bfields@umich.edu>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#define DEBUG_SUBSYSTEM S_SEC
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/mutex.h>
#include <obd.h>
#include <obd_class.h>
#include <obd_support.h>
#include <lustre/lustre_idl.h>
#include <lustre_net.h>
#include <lustre_import.h>
#include <lustre_sec.h>
#include "gss_err.h"
#include "gss_internal.h"
#include "gss_api.h"
static LIST_HEAD(registered_mechs);
static DEFINE_SPINLOCK(registered_mechs_lock);
int lgss_mech_register(struct gss_api_mech *gm)
{
spin_lock(&registered_mechs_lock);
list_add(&gm->gm_list, &registered_mechs);
spin_unlock(&registered_mechs_lock);
CWARN("Register %s mechanism\n", gm->gm_name);
return 0;
}
void lgss_mech_unregister(struct gss_api_mech *gm)
{
spin_lock(&registered_mechs_lock);
list_del(&gm->gm_list);
spin_unlock(&registered_mechs_lock);
CWARN("Unregister %s mechanism\n", gm->gm_name);
}
struct gss_api_mech *lgss_mech_get(struct gss_api_mech *gm)
{
__module_get(gm->gm_owner);
return gm;
}
struct gss_api_mech *lgss_name_to_mech(char *name)
{
struct gss_api_mech *pos, *gm = NULL;
spin_lock(&registered_mechs_lock);
list_for_each_entry(pos, &registered_mechs, gm_list) {
if (0 == strcmp(name, pos->gm_name)) {
if (!try_module_get(pos->gm_owner))
continue;
gm = pos;
break;
}
}
spin_unlock(&registered_mechs_lock);
return gm;
}
static inline
int mech_supports_subflavor(struct gss_api_mech *gm, __u32 subflavor)
{
int i;
for (i = 0; i < gm->gm_sf_num; i++) {
if (gm->gm_sfs[i].sf_subflavor == subflavor)
return 1;
}
return 0;
}
struct gss_api_mech *lgss_subflavor_to_mech(__u32 subflavor)
{
struct gss_api_mech *pos, *gm = NULL;
spin_lock(&registered_mechs_lock);
list_for_each_entry(pos, &registered_mechs, gm_list) {
if (!try_module_get(pos->gm_owner))
continue;
if (!mech_supports_subflavor(pos, subflavor)) {
module_put(pos->gm_owner);
continue;
}
gm = pos;
break;
}
spin_unlock(&registered_mechs_lock);
return gm;
}
void lgss_mech_put(struct gss_api_mech *gm)
{
module_put(gm->gm_owner);
}
/* The mech could probably be determined from the token instead, but it's just
* as easy for now to pass it in. */
__u32 lgss_import_sec_context(rawobj_t *input_token,
struct gss_api_mech *mech,
struct gss_ctx **ctx_id)
{
OBD_ALLOC_PTR(*ctx_id);
if (*ctx_id == NULL)
return GSS_S_FAILURE;
(*ctx_id)->mech_type = lgss_mech_get(mech);
LASSERT(mech);
LASSERT(mech->gm_ops);
LASSERT(mech->gm_ops->gss_import_sec_context);
return mech->gm_ops->gss_import_sec_context(input_token, *ctx_id);
}
__u32 lgss_copy_reverse_context(struct gss_ctx *ctx_id,
struct gss_ctx **ctx_id_new)
{
struct gss_api_mech *mech = ctx_id->mech_type;
__u32 major;
LASSERT(mech);
OBD_ALLOC_PTR(*ctx_id_new);
if (*ctx_id_new == NULL)
return GSS_S_FAILURE;
(*ctx_id_new)->mech_type = lgss_mech_get(mech);
LASSERT(mech);
LASSERT(mech->gm_ops);
LASSERT(mech->gm_ops->gss_copy_reverse_context);
major = mech->gm_ops->gss_copy_reverse_context(ctx_id, *ctx_id_new);
if (major != GSS_S_COMPLETE) {
lgss_mech_put(mech);
OBD_FREE_PTR(*ctx_id_new);
*ctx_id_new = NULL;
}
return major;
}
/*
* this interface is much simplified, currently we only need endtime.
*/
__u32 lgss_inquire_context(struct gss_ctx *context_handle,
unsigned long *endtime)
{
LASSERT(context_handle);
LASSERT(context_handle->mech_type);
LASSERT(context_handle->mech_type->gm_ops);
LASSERT(context_handle->mech_type->gm_ops->gss_inquire_context);
return context_handle->mech_type->gm_ops
->gss_inquire_context(context_handle,
endtime);
}
/* gss_get_mic: compute a mic over message and return mic_token. */
__u32 lgss_get_mic(struct gss_ctx *context_handle,
int msgcnt,
rawobj_t *msg,
int iovcnt,
lnet_kiov_t *iovs,
rawobj_t *mic_token)
{
LASSERT(context_handle);
LASSERT(context_handle->mech_type);
LASSERT(context_handle->mech_type->gm_ops);
LASSERT(context_handle->mech_type->gm_ops->gss_get_mic);
return context_handle->mech_type->gm_ops
->gss_get_mic(context_handle,
msgcnt,
msg,
iovcnt,
iovs,
mic_token);
}
/* gss_verify_mic: check whether the provided mic_token verifies message. */
__u32 lgss_verify_mic(struct gss_ctx *context_handle,
int msgcnt,
rawobj_t *msg,
int iovcnt,
lnet_kiov_t *iovs,
rawobj_t *mic_token)
{
LASSERT(context_handle);
LASSERT(context_handle->mech_type);
LASSERT(context_handle->mech_type->gm_ops);
LASSERT(context_handle->mech_type->gm_ops->gss_verify_mic);
return context_handle->mech_type->gm_ops
->gss_verify_mic(context_handle,
msgcnt,
msg,
iovcnt,
iovs,
mic_token);
}
__u32 lgss_wrap(struct gss_ctx *context_handle,
rawobj_t *gsshdr,
rawobj_t *msg,
int msg_buflen,
rawobj_t *out_token)
{
LASSERT(context_handle);
LASSERT(context_handle->mech_type);
LASSERT(context_handle->mech_type->gm_ops);
LASSERT(context_handle->mech_type->gm_ops->gss_wrap);
return context_handle->mech_type->gm_ops
->gss_wrap(context_handle, gsshdr, msg, msg_buflen, out_token);
}
__u32 lgss_unwrap(struct gss_ctx *context_handle,
rawobj_t *gsshdr,
rawobj_t *token,
rawobj_t *out_msg)
{
LASSERT(context_handle);
LASSERT(context_handle->mech_type);
LASSERT(context_handle->mech_type->gm_ops);
LASSERT(context_handle->mech_type->gm_ops->gss_unwrap);
return context_handle->mech_type->gm_ops
->gss_unwrap(context_handle, gsshdr, token, out_msg);
}
__u32 lgss_prep_bulk(struct gss_ctx *context_handle,
struct ptlrpc_bulk_desc *desc)
{
LASSERT(context_handle);
LASSERT(context_handle->mech_type);
LASSERT(context_handle->mech_type->gm_ops);
LASSERT(context_handle->mech_type->gm_ops->gss_prep_bulk);
return context_handle->mech_type->gm_ops
->gss_prep_bulk(context_handle, desc);
}
__u32 lgss_wrap_bulk(struct gss_ctx *context_handle,
struct ptlrpc_bulk_desc *desc,
rawobj_t *token,
int adj_nob)
{
LASSERT(context_handle);
LASSERT(context_handle->mech_type);
LASSERT(context_handle->mech_type->gm_ops);
LASSERT(context_handle->mech_type->gm_ops->gss_wrap_bulk);
return context_handle->mech_type->gm_ops
->gss_wrap_bulk(context_handle, desc, token, adj_nob);
}
__u32 lgss_unwrap_bulk(struct gss_ctx *context_handle,
struct ptlrpc_bulk_desc *desc,
rawobj_t *token,
int adj_nob)
{
LASSERT(context_handle);
LASSERT(context_handle->mech_type);
LASSERT(context_handle->mech_type->gm_ops);
LASSERT(context_handle->mech_type->gm_ops->gss_unwrap_bulk);
return context_handle->mech_type->gm_ops
->gss_unwrap_bulk(context_handle, desc, token, adj_nob);
}
/* gss_delete_sec_context: free all resources associated with context_handle.
* Note this differs from the RFC 2744-specified prototype in that we don't
* bother returning an output token, since it would never be used anyway. */
__u32 lgss_delete_sec_context(struct gss_ctx **context_handle)
{
struct gss_api_mech *mech;
CDEBUG(D_SEC, "deleting %p\n", *context_handle);
if (!*context_handle)
return(GSS_S_NO_CONTEXT);
mech = (*context_handle)->mech_type;
if ((*context_handle)->internal_ctx_id != 0) {
LASSERT(mech);
LASSERT(mech->gm_ops);
LASSERT(mech->gm_ops->gss_delete_sec_context);
mech->gm_ops->gss_delete_sec_context(
(*context_handle)->internal_ctx_id);
}
if (mech)
lgss_mech_put(mech);
OBD_FREE_PTR(*context_handle);
*context_handle=NULL;
return GSS_S_COMPLETE;
}
int lgss_display(struct gss_ctx *ctx,
char *buf,
int bufsize)
{
LASSERT(ctx);
LASSERT(ctx->mech_type);
LASSERT(ctx->mech_type->gm_ops);
LASSERT(ctx->mech_type->gm_ops->gss_display);
return ctx->mech_type->gm_ops->gss_display(ctx, buf, bufsize);
}
This diff is collapsed.
/*
* 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.sun.com/software/products/lustre/docs/GPLv2.pdf
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
* GPL HEADER END
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
* Copyright (c) 2011, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
* Lustre is a trademark of Sun Microsystems, Inc.
*
* lustre/ptlrpc/gss/gss_rawobj.c
*
* Author: Eric Mei <ericm@clusterfs.com>
*/
#define DEBUG_SUBSYSTEM S_SEC
#include <linux/mutex.h>
#include <obd.h>
#include <obd_class.h>
#include <obd_support.h>
#include <lustre_sec.h>
#include "gss_internal.h"
int rawobj_empty(rawobj_t *obj)
{
LASSERT(equi(obj->len, obj->data));
return (obj->len == 0);
}
int rawobj_alloc(rawobj_t *obj, char *buf, int len)
{
LASSERT(obj);
LASSERT(len >= 0);
obj->len = len;
if (len) {
OBD_ALLOC_LARGE(obj->data, len);
if (!obj->data) {
obj->len = 0;
return -ENOMEM;
}
memcpy(obj->data, buf, len);
} else
obj->data = NULL;
return 0;
}
void rawobj_free(rawobj_t *obj)
{
LASSERT(obj);
if (obj->len) {
LASSERT(obj->data);
OBD_FREE_LARGE(obj->data, obj->len);
obj->len = 0;
obj->data = NULL;
} else
LASSERT(!obj->data);
}
int rawobj_equal(rawobj_t *a, rawobj_t *b)
{
LASSERT(a && b);
return (a->len == b->len &&
(!a->len || !memcmp(a->data, b->data, a->len)));
}
int rawobj_dup(rawobj_t *dest, rawobj_t *src)
{
LASSERT(src && dest);
dest->len = src->len;
if (dest->len) {
OBD_ALLOC_LARGE(dest->data, dest->len);
if (!dest->data) {
dest->len = 0;
return -ENOMEM;
}
memcpy(dest->data, src->data, dest->len);
} else
dest->data = NULL;
return 0;
}
int rawobj_serialize(rawobj_t *obj, __u32 **buf, __u32 *buflen)
{
__u32 len;
LASSERT(obj);
LASSERT(buf);
LASSERT(buflen);
len = cfs_size_round4(obj->len);
if (*buflen < 4 + len) {
CERROR("buflen %u < %u\n", *buflen, 4 + len);
return -EINVAL;
}
*(*buf)++ = cpu_to_le32(obj->len);
memcpy(*buf, obj->data, obj->len);
*buf += (len >> 2);
*buflen -= (4 + len);
return 0;
}
static int __rawobj_extract(rawobj_t *obj, __u32 **buf, __u32 *buflen,
int alloc, int local)
{
__u32 len;
if (*buflen < sizeof(__u32)) {
CERROR("buflen %u\n", *buflen);
return -EINVAL;
}
obj->len = *(*buf)++;
if (!local)
obj->len = le32_to_cpu(obj->len);
*buflen -= sizeof(__u32);
if (!obj->len) {
obj->data = NULL;
return 0;
}
len = local ? obj->len : cfs_size_round4(obj->len);
if (*buflen < len) {
CERROR("buflen %u < %u\n", *buflen, len);
obj->len = 0;
return -EINVAL;
}
if (!alloc)
obj->data = (__u8 *) *buf;
else {
OBD_ALLOC_LARGE(obj->data, obj->len);
if (!obj->data) {
CERROR("fail to alloc %u bytes\n", obj->len);
obj->len = 0;
return -ENOMEM;
}
memcpy(obj->data, *buf, obj->len);
}
*((char **)buf) += len;
*buflen -= len;
return 0;
}
int rawobj_extract(rawobj_t *obj, __u32 **buf, __u32 *buflen)
{
return __rawobj_extract(obj, buf, buflen, 0, 0);
}
int rawobj_extract_alloc(rawobj_t *obj, __u32 **buf, __u32 *buflen)
{
return __rawobj_extract(obj, buf, buflen, 1, 0);
}
int rawobj_extract_local(rawobj_t *obj, __u32 **buf, __u32 *buflen)
{
return __rawobj_extract(obj, buf, buflen, 0, 1);
}
int rawobj_extract_local_alloc(rawobj_t *obj, __u32 **buf, __u32 *buflen)
{
return __rawobj_extract(obj, buf, buflen, 1, 1);
}
int rawobj_from_netobj(rawobj_t *rawobj, netobj_t *netobj)
{
rawobj->len = netobj->len;
rawobj->data = netobj->data;
return 0;
}
int rawobj_from_netobj_alloc(rawobj_t *rawobj, netobj_t *netobj)
{
rawobj->len = 0;
rawobj->data = NULL;
if (netobj->len == 0)
return 0;
OBD_ALLOC_LARGE(rawobj->data, netobj->len);
if (rawobj->data == NULL)
return -ENOMEM;
rawobj->len = netobj->len;
memcpy(rawobj->data, netobj->data, netobj->len);
return 0;
}
/****************************************
* misc more *
****************************************/
int buffer_extract_bytes(const void **buf, __u32 *buflen,
void *res, __u32 reslen)
{
if (*buflen < reslen) {
CERROR("buflen %u < %u\n", *buflen, reslen);
return -EINVAL;
}
memcpy(res, *buf, reslen);
*buf += reslen;
*buflen -= reslen;
return 0;
}
/*
* 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.sun.com/software/products/lustre/docs/GPLv2.pdf
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
* GPL HEADER END
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
* Copyright (c) 2012, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
* Lustre is a trademark of Sun Microsystems, Inc.
*/
#define DEBUG_SUBSYSTEM S_SEC
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/dcache.h>
#include <linux/fs.h>
#include <linux/mutex.h>
#include <obd.h>
#include <obd_class.h>
#include <obd_support.h>
#include <lustre/lustre_idl.h>
#include <lustre_net.h>
#include <lustre_import.h>
#include <lprocfs_status.h>
#include <lustre_sec.h>
#include "gss_err.h"
#include "gss_internal.h"
#include "gss_api.h"
static struct proc_dir_entry *gss_proc_root = NULL;
static struct proc_dir_entry *gss_proc_lk = NULL;
/*
* statistic of "out-of-sequence-window"
*/
static struct {
spinlock_t oos_lock;
atomic_t oos_cli_count; /* client occurrence */
int oos_cli_behind; /* client max seqs behind */
atomic_t oos_svc_replay[3]; /* server replay detected */
atomic_t oos_svc_pass[3]; /* server verified ok */
} gss_stat_oos = {
.oos_cli_count = ATOMIC_INIT(0),
.oos_cli_behind = 0,
.oos_svc_replay = { ATOMIC_INIT(0), },
.oos_svc_pass = { ATOMIC_INIT(0), },
};
void gss_stat_oos_record_cli(int behind)
{
atomic_inc(&gss_stat_oos.oos_cli_count);
spin_lock(&gss_stat_oos.oos_lock);
if (behind > gss_stat_oos.oos_cli_behind)
gss_stat_oos.oos_cli_behind = behind;
spin_unlock(&gss_stat_oos.oos_lock);
}
void gss_stat_oos_record_svc(int phase, int replay)
{
LASSERT(phase >= 0 && phase <= 2);
if (replay)
atomic_inc(&gss_stat_oos.oos_svc_replay[phase]);
else
atomic_inc(&gss_stat_oos.oos_svc_pass[phase]);
}
static int gss_proc_oos_seq_show(struct seq_file *m, void *v)
{
return seq_printf(m,
"seqwin: %u\n"
"backwin: %u\n"
"client fall behind seqwin\n"
" occurrence: %d\n"
" max seq behind: %d\n"
"server replay detected:\n"
" phase 0: %d\n"
" phase 1: %d\n"
" phase 2: %d\n"
"server verify ok:\n"
" phase 2: %d\n",
GSS_SEQ_WIN_MAIN,
GSS_SEQ_WIN_BACK,
atomic_read(&gss_stat_oos.oos_cli_count),
gss_stat_oos.oos_cli_behind,
atomic_read(&gss_stat_oos.oos_svc_replay[0]),
atomic_read(&gss_stat_oos.oos_svc_replay[1]),
atomic_read(&gss_stat_oos.oos_svc_replay[2]),
atomic_read(&gss_stat_oos.oos_svc_pass[2]));
}
LPROC_SEQ_FOPS_RO(gss_proc_oos);
static int gss_proc_write_secinit(struct file *file, const char *buffer,
size_t count, off_t *off)
{
int rc;
rc = gss_do_ctx_init_rpc((char *) buffer, count);
if (rc) {
LASSERT(rc < 0);
return rc;
}
return count;
}
static const struct file_operations gss_proc_secinit = {
.write = gss_proc_write_secinit,
};
static struct lprocfs_vars gss_lprocfs_vars[] = {
{ "replays", &gss_proc_oos_fops },
{ "init_channel", &gss_proc_secinit, NULL, 0222 },
{ NULL }
};
/*
* for userspace helper lgss_keyring.
*
* debug_level: [0, 4], defined in utils/gss/lgss_utils.h
*/
static int gss_lk_debug_level = 1;
static int gss_lk_proc_dl_seq_show(struct seq_file *m, void *v)
{
return seq_printf(m, "%u\n", gss_lk_debug_level);
}
static int gss_lk_proc_dl_seq_write(struct file *file, const char *buffer,
size_t count, off_t *off)
{
int val, rc;
rc = lprocfs_write_helper(buffer, count, &val);
if (rc < 0)
return rc;
if (val < 0 || val > 4)
return -ERANGE;
gss_lk_debug_level = val;
return count;
}
LPROC_SEQ_FOPS(gss_lk_proc_dl);
static struct lprocfs_vars gss_lk_lprocfs_vars[] = {
{ "debug_level", &gss_lk_proc_dl_fops },
{ NULL }
};
void gss_exit_lproc(void)
{
if (gss_proc_lk) {
lprocfs_remove(&gss_proc_lk);
gss_proc_lk = NULL;
}
if (gss_proc_root) {
lprocfs_remove(&gss_proc_root);
gss_proc_root = NULL;
}
}
int gss_init_lproc(void)
{
int rc;
spin_lock_init(&gss_stat_oos.oos_lock);
gss_proc_root = lprocfs_register("gss", sptlrpc_proc_root,
gss_lprocfs_vars, NULL);
if (IS_ERR(gss_proc_root)) {
rc = PTR_ERR(gss_proc_root);
gss_proc_root = NULL;
GOTO(err_out, rc);
}
gss_proc_lk = lprocfs_register("lgss_keyring", gss_proc_root,
gss_lk_lprocfs_vars, NULL);
if (IS_ERR(gss_proc_lk)) {
rc = PTR_ERR(gss_proc_lk);
gss_proc_lk = NULL;
GOTO(err_out, rc);
}
return 0;
err_out:
CERROR("failed to initialize gss lproc entries: %d\n", rc);
gss_exit_lproc();
return rc;
}
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment