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

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
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -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/
+0 −8
Original line number Diff line number Diff line
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
+0 −179
Original line number Diff line number Diff line
/*
 * 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_ */
+0 −84
Original line number Diff line number Diff line
/*
 * 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);
+0 −505
Original line number Diff line number Diff line
/*
 * 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.
 */
/*
 * This file is part of Lustre, http://www.lustre.org/
 * Lustre is a trademark of Sun Microsystems, Inc.
 *
 * lustre/ptlrpc/gss/gss_bulk.c
 *
 * Author: Eric Mei <eric.mei@sun.com>
 */

#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 <linux/crypto.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"

int gss_cli_ctx_wrap_bulk(struct ptlrpc_cli_ctx *ctx,
			  struct ptlrpc_request *req,
			  struct ptlrpc_bulk_desc *desc)
{
	struct gss_cli_ctx	      *gctx;
	struct lustre_msg	       *msg;
	struct ptlrpc_bulk_sec_desc     *bsd;
	rawobj_t			 token;
	__u32			    maj;
	int			      offset;
	int			      rc;

	LASSERT(req->rq_pack_bulk);
	LASSERT(req->rq_bulk_read || req->rq_bulk_write);

	gctx = container_of(ctx, struct gss_cli_ctx, gc_base);
	LASSERT(gctx->gc_mechctx);

	switch (SPTLRPC_FLVR_SVC(req->rq_flvr.sf_rpc)) {
	case SPTLRPC_SVC_NULL:
		LASSERT(req->rq_reqbuf->lm_bufcount >= 3);
		msg = req->rq_reqbuf;
		offset = msg->lm_bufcount - 1;
		break;
	case SPTLRPC_SVC_AUTH:
	case SPTLRPC_SVC_INTG:
		LASSERT(req->rq_reqbuf->lm_bufcount >= 4);
		msg = req->rq_reqbuf;
		offset = msg->lm_bufcount - 2;
		break;
	case SPTLRPC_SVC_PRIV:
		LASSERT(req->rq_clrbuf->lm_bufcount >= 2);
		msg = req->rq_clrbuf;
		offset = msg->lm_bufcount - 1;
		break;
	default:
		LBUG();
	}

	bsd = lustre_msg_buf(msg, offset, sizeof(*bsd));
	bsd->bsd_version = 0;
	bsd->bsd_flags = 0;
	bsd->bsd_type = SPTLRPC_BULK_DEFAULT;
	bsd->bsd_svc = SPTLRPC_FLVR_BULK_SVC(req->rq_flvr.sf_rpc);

	if (bsd->bsd_svc == SPTLRPC_BULK_SVC_NULL)
		return 0;

	LASSERT(bsd->bsd_svc == SPTLRPC_BULK_SVC_INTG ||
		bsd->bsd_svc == SPTLRPC_BULK_SVC_PRIV);

	if (req->rq_bulk_read) {
		/*
		 * bulk read: prepare receiving pages only for privacy mode.
		 */
		if (bsd->bsd_svc == SPTLRPC_BULK_SVC_PRIV)
			return gss_cli_prep_bulk(req, desc);
	} else {
		/*
		 * bulk write: sign or encrypt bulk pages.
		 */
		bsd->bsd_nob = desc->bd_nob;

		if (bsd->bsd_svc == SPTLRPC_BULK_SVC_INTG) {
			/* integrity mode */
			token.data = bsd->bsd_data;
			token.len = lustre_msg_buflen(msg, offset) -
				    sizeof(*bsd);

			maj = lgss_get_mic(gctx->gc_mechctx, 0, NULL,
					   desc->bd_iov_count, desc->bd_iov,
					   &token);
			if (maj != GSS_S_COMPLETE) {
				CWARN("failed to sign bulk data: %x\n", maj);
				return -EACCES;
			}
		} else {
			/* privacy mode */
			if (desc->bd_iov_count == 0)
				return 0;

			rc = sptlrpc_enc_pool_get_pages(desc);
			if (rc) {
				CERROR("bulk write: failed to allocate "
				       "encryption pages: %d\n", rc);
				return rc;
			}

			token.data = bsd->bsd_data;
			token.len = lustre_msg_buflen(msg, offset) -
				    sizeof(*bsd);

			maj = lgss_wrap_bulk(gctx->gc_mechctx, desc, &token, 0);
			if (maj != GSS_S_COMPLETE) {
				CWARN("fail to encrypt bulk data: %x\n", maj);
				return -EACCES;
			}
		}
	}

	return 0;
}

int gss_cli_ctx_unwrap_bulk(struct ptlrpc_cli_ctx *ctx,
			    struct ptlrpc_request *req,
			    struct ptlrpc_bulk_desc *desc)
{
	struct gss_cli_ctx	      *gctx;
	struct lustre_msg	       *rmsg, *vmsg;
	struct ptlrpc_bulk_sec_desc     *bsdr, *bsdv;
	rawobj_t			 token;
	__u32			    maj;
	int			      roff, voff;

	LASSERT(req->rq_pack_bulk);
	LASSERT(req->rq_bulk_read || req->rq_bulk_write);

	switch (SPTLRPC_FLVR_SVC(req->rq_flvr.sf_rpc)) {
	case SPTLRPC_SVC_NULL:
		vmsg = req->rq_repdata;
		LASSERT(vmsg != NULL && vmsg->lm_bufcount >= 3);
		voff = vmsg->lm_bufcount - 1;

		rmsg = req->rq_reqbuf;
		LASSERT(rmsg != NULL && rmsg->lm_bufcount >= 3);
		roff = rmsg->lm_bufcount - 1; /* last segment */
		break;
	case SPTLRPC_SVC_AUTH:
	case SPTLRPC_SVC_INTG:
		vmsg = req->rq_repdata;
		LASSERT(vmsg != NULL && vmsg->lm_bufcount >= 4);
		voff = vmsg->lm_bufcount - 2;

		rmsg = req->rq_reqbuf;
		LASSERT(rmsg != NULL && rmsg->lm_bufcount >= 4);
		roff = rmsg->lm_bufcount - 2; /* second last segment */
		break;
	case SPTLRPC_SVC_PRIV:
		vmsg = req->rq_repdata;
		LASSERT(vmsg != NULL && vmsg->lm_bufcount >= 2);
		voff = vmsg->lm_bufcount - 1;

		rmsg = req->rq_clrbuf;
		LASSERT(rmsg != NULL && rmsg->lm_bufcount >= 2);
		roff = rmsg->lm_bufcount - 1; /* last segment */
		break;
	default:
		LBUG();
	}

	bsdr = lustre_msg_buf(rmsg, roff, sizeof(*bsdr));
	bsdv = lustre_msg_buf(vmsg, voff, sizeof(*bsdv));
	LASSERT(bsdr && bsdv);

	if (bsdr->bsd_version != bsdv->bsd_version ||
	    bsdr->bsd_type != bsdv->bsd_type ||
	    bsdr->bsd_svc != bsdv->bsd_svc) {
		CERROR("bulk security descriptor mismatch: "
		       "(%u,%u,%u) != (%u,%u,%u)\n",
		       bsdr->bsd_version, bsdr->bsd_type, bsdr->bsd_svc,
		       bsdv->bsd_version, bsdv->bsd_type, bsdv->bsd_svc);
		return -EPROTO;
	}

	LASSERT(bsdv->bsd_svc == SPTLRPC_BULK_SVC_NULL ||
		bsdv->bsd_svc == SPTLRPC_BULK_SVC_INTG ||
		bsdv->bsd_svc == SPTLRPC_BULK_SVC_PRIV);

	/*
	 * in privacy mode if return success, make sure bd_nob_transferred
	 * is the actual size of the clear text, otherwise upper layer
	 * may be surprised.
	 */
	if (req->rq_bulk_write) {
		if (bsdv->bsd_flags & BSD_FL_ERR) {
			CERROR("server reported bulk i/o failure\n");
			return -EIO;
		}

		if (bsdv->bsd_svc == SPTLRPC_BULK_SVC_PRIV)
			desc->bd_nob_transferred = desc->bd_nob;
	} else {
		/*
		 * bulk read, upon return success, bd_nob_transferred is
		 * the size of plain text actually received.
		 */
		gctx = container_of(ctx, struct gss_cli_ctx, gc_base);
		LASSERT(gctx->gc_mechctx);

		if (bsdv->bsd_svc == SPTLRPC_BULK_SVC_INTG) {
			int i, nob;

			/* fix the actual data size */
			for (i = 0, nob = 0; i < desc->bd_iov_count; i++) {
				if (desc->bd_iov[i].kiov_len + nob >
				    desc->bd_nob_transferred) {
					desc->bd_iov[i].kiov_len =
						desc->bd_nob_transferred - nob;
				}
				nob += desc->bd_iov[i].kiov_len;
			}

			token.data = bsdv->bsd_data;
			token.len = lustre_msg_buflen(vmsg, voff) -
				    sizeof(*bsdv);

			maj = lgss_verify_mic(gctx->gc_mechctx, 0, NULL,
					      desc->bd_iov_count, desc->bd_iov,
					      &token);
			if (maj != GSS_S_COMPLETE) {
				CERROR("failed to verify bulk read: %x\n", maj);
				return -EACCES;
			}
		} else if (bsdv->bsd_svc == SPTLRPC_BULK_SVC_PRIV) {
			desc->bd_nob = bsdv->bsd_nob;
			if (desc->bd_nob == 0)
				return 0;

			token.data = bsdv->bsd_data;
			token.len = lustre_msg_buflen(vmsg, voff) -
				    sizeof(*bsdr);

			maj = lgss_unwrap_bulk(gctx->gc_mechctx, desc,
					       &token, 1);
			if (maj != GSS_S_COMPLETE) {
				CERROR("failed to decrypt bulk read: %x\n",
				       maj);
				return -EACCES;
			}

			desc->bd_nob_transferred = desc->bd_nob;
		}
	}

	return 0;
}

static int gss_prep_bulk(struct ptlrpc_bulk_desc *desc,
			 struct gss_ctx *mechctx)
{
	int     rc;

	if (desc->bd_iov_count == 0)
		return 0;

	rc = sptlrpc_enc_pool_get_pages(desc);
	if (rc)
		return rc;

	if (lgss_prep_bulk(mechctx, desc) != GSS_S_COMPLETE)
		return -EACCES;

	return 0;
}

int gss_cli_prep_bulk(struct ptlrpc_request *req,
		      struct ptlrpc_bulk_desc *desc)
{
	int	     rc;

	LASSERT(req->rq_cli_ctx);
	LASSERT(req->rq_pack_bulk);
	LASSERT(req->rq_bulk_read);

	if (SPTLRPC_FLVR_BULK_SVC(req->rq_flvr.sf_rpc) != SPTLRPC_BULK_SVC_PRIV)
		return 0;

	rc = gss_prep_bulk(desc, ctx2gctx(req->rq_cli_ctx)->gc_mechctx);
	if (rc)
		CERROR("bulk read: failed to prepare encryption "
		       "pages: %d\n", rc);

	return rc;
}

int gss_svc_prep_bulk(struct ptlrpc_request *req,
		      struct ptlrpc_bulk_desc *desc)
{
	struct gss_svc_reqctx	*grctx;
	struct ptlrpc_bulk_sec_desc  *bsd;
	int			   rc;

	LASSERT(req->rq_svc_ctx);
	LASSERT(req->rq_pack_bulk);
	LASSERT(req->rq_bulk_write);

	grctx = gss_svc_ctx2reqctx(req->rq_svc_ctx);
	LASSERT(grctx->src_reqbsd);
	LASSERT(grctx->src_repbsd);
	LASSERT(grctx->src_ctx);
	LASSERT(grctx->src_ctx->gsc_mechctx);

	bsd = grctx->src_reqbsd;
	if (bsd->bsd_svc != SPTLRPC_BULK_SVC_PRIV)
		return 0;

	rc = gss_prep_bulk(desc, grctx->src_ctx->gsc_mechctx);
	if (rc)
		CERROR("bulk write: failed to prepare encryption "
		       "pages: %d\n", rc);

	return rc;
}

int gss_svc_unwrap_bulk(struct ptlrpc_request *req,
			struct ptlrpc_bulk_desc *desc)
{
	struct gss_svc_reqctx	*grctx;
	struct ptlrpc_bulk_sec_desc  *bsdr, *bsdv;
	rawobj_t		      token;
	__u32			 maj;

	LASSERT(req->rq_svc_ctx);
	LASSERT(req->rq_pack_bulk);
	LASSERT(req->rq_bulk_write);

	grctx = gss_svc_ctx2reqctx(req->rq_svc_ctx);

	LASSERT(grctx->src_reqbsd);
	LASSERT(grctx->src_repbsd);
	LASSERT(grctx->src_ctx);
	LASSERT(grctx->src_ctx->gsc_mechctx);

	bsdr = grctx->src_reqbsd;
	bsdv = grctx->src_repbsd;

	/* bsdr has been sanity checked during unpacking */
	bsdv->bsd_version = 0;
	bsdv->bsd_type = SPTLRPC_BULK_DEFAULT;
	bsdv->bsd_svc = bsdr->bsd_svc;
	bsdv->bsd_flags = 0;

	switch (bsdv->bsd_svc) {
	case SPTLRPC_BULK_SVC_INTG:
		token.data = bsdr->bsd_data;
		token.len = grctx->src_reqbsd_size - sizeof(*bsdr);

		maj = lgss_verify_mic(grctx->src_ctx->gsc_mechctx, 0, NULL,
				      desc->bd_iov_count, desc->bd_iov, &token);
		if (maj != GSS_S_COMPLETE) {
			bsdv->bsd_flags |= BSD_FL_ERR;
			CERROR("failed to verify bulk signature: %x\n", maj);
			return -EACCES;
		}
		break;
	case SPTLRPC_BULK_SVC_PRIV:
		if (bsdr->bsd_nob != desc->bd_nob) {
			bsdv->bsd_flags |= BSD_FL_ERR;
			CERROR("prepared nob %d doesn't match the actual "
			       "nob %d\n", desc->bd_nob, bsdr->bsd_nob);
			return -EPROTO;
		}

		if (desc->bd_iov_count == 0) {
			LASSERT(desc->bd_nob == 0);
			break;
		}

		token.data = bsdr->bsd_data;
		token.len = grctx->src_reqbsd_size - sizeof(*bsdr);

		maj = lgss_unwrap_bulk(grctx->src_ctx->gsc_mechctx,
				       desc, &token, 0);
		if (maj != GSS_S_COMPLETE) {
			bsdv->bsd_flags |= BSD_FL_ERR;
			CERROR("failed decrypt bulk data: %x\n", maj);
			return -EACCES;
		}
		break;
	}

	return 0;
}

int gss_svc_wrap_bulk(struct ptlrpc_request *req,
		      struct ptlrpc_bulk_desc *desc)
{
	struct gss_svc_reqctx	*grctx;
	struct ptlrpc_bulk_sec_desc  *bsdr, *bsdv;
	rawobj_t		      token;
	__u32			 maj;
	int			   rc;

	LASSERT(req->rq_svc_ctx);
	LASSERT(req->rq_pack_bulk);
	LASSERT(req->rq_bulk_read);

	grctx = gss_svc_ctx2reqctx(req->rq_svc_ctx);

	LASSERT(grctx->src_reqbsd);
	LASSERT(grctx->src_repbsd);
	LASSERT(grctx->src_ctx);
	LASSERT(grctx->src_ctx->gsc_mechctx);

	bsdr = grctx->src_reqbsd;
	bsdv = grctx->src_repbsd;

	/* bsdr has been sanity checked during unpacking */
	bsdv->bsd_version = 0;
	bsdv->bsd_type = SPTLRPC_BULK_DEFAULT;
	bsdv->bsd_svc = bsdr->bsd_svc;
	bsdv->bsd_flags = 0;

	switch (bsdv->bsd_svc) {
	case SPTLRPC_BULK_SVC_INTG:
		token.data = bsdv->bsd_data;
		token.len = grctx->src_repbsd_size - sizeof(*bsdv);

		maj = lgss_get_mic(grctx->src_ctx->gsc_mechctx, 0, NULL,
				   desc->bd_iov_count, desc->bd_iov, &token);
		if (maj != GSS_S_COMPLETE) {
			bsdv->bsd_flags |= BSD_FL_ERR;
			CERROR("failed to sign bulk data: %x\n", maj);
			return -EACCES;
		}
		break;
	case SPTLRPC_BULK_SVC_PRIV:
		bsdv->bsd_nob = desc->bd_nob;

		if (desc->bd_iov_count == 0) {
			LASSERT(desc->bd_nob == 0);
			break;
		}

		rc = sptlrpc_enc_pool_get_pages(desc);
		if (rc) {
			bsdv->bsd_flags |= BSD_FL_ERR;
			CERROR("bulk read: failed to allocate encryption "
			       "pages: %d\n", rc);
			return rc;
		}

		token.data = bsdv->bsd_data;
		token.len = grctx->src_repbsd_size - sizeof(*bsdv);

		maj = lgss_wrap_bulk(grctx->src_ctx->gsc_mechctx,
				     desc, &token, 1);
		if (maj != GSS_S_COMPLETE) {
			bsdv->bsd_flags |= BSD_FL_ERR;
			CERROR("failed to encrypt bulk data: %x\n", maj);
			return -EACCES;
		}
		break;
	}

	return 0;
}
Loading