| From: |
| Trond Myklebust <trond.myklebust@fys.uio.no> |
| To: |
| Linus Torvalds <torvalds@transmeta.com>,
NFS maillist <nfs@lists.sourceforge.net>,nfsv4-wg@citi.umich.edu |
| Subject: |
| [NFS] [PATCH] Kerberos 5 security framework for RPCSEC_GSS |
| Date: |
| Thu, 31 Oct 2002 22:14:08 +0100 |
The following patch applys on top of the RPCSEC_GSS patches, and adds
the client side framework needed in order to authenticate users to
servers running NFSv2, NFSv3, or NFSv4 with RPCSEC_GSS + Kerberos 5.
Cheers,
Trond
diff -u --recursive --new-file linux-2.5.45-07-auth_upcall2/fs/Kconfig linux-2.5.45-08-krb5/fs/Kconfig
--- linux-2.5.45-07-auth_upcall2/fs/Kconfig 2002-10-31 12:44:13.000000000 -0500
+++ linux-2.5.45-08-krb5/fs/Kconfig 2002-10-31 15:45:10.000000000 -0500
@@ -1266,6 +1266,10 @@
tristate "Provide RPCSEC_GSS authentication (EXPERIMENTAL)"
depends on SUNRPC && EXPERIMENTAL
+config RPCSEC_GSS_KRB5
+ tristate "Kerberos mechanism for RPCSEC_GSS (EXPERIMENTAL)"
+ depends on SUNRPC_GSS
+
config LOCKD
tristate
default m if NFS_FS!=y && NFSD!=y && (NFS_FS=m || NFSD=m)
diff -u --recursive --new-file linux-2.5.45-07-auth_upcall2/include/linux/sunrpc/gss_krb5_types.h linux-2.5.45-08-krb5/include/linux/sunrpc/gss_krb5_types.h
--- linux-2.5.45-07-auth_upcall2/include/linux/sunrpc/gss_krb5_types.h 1969-12-31 19:00:00.000000000 -0500
+++ linux-2.5.45-08-krb5/include/linux/sunrpc/gss_krb5_types.h 2002-10-31 15:50:28.000000000 -0500
@@ -0,0 +1,383 @@
+/*
+ * linux/include/linux/sunrpc/gss_krb5_types.h
+ *
+ * krb5 types mapped to linux kernel types
+ *
+ * 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.
+ *
+ */
+
+
+#include <linux/sunrpc/auth_gss.h>
+#include <linux/sunrpc/gss_err.h>
+#include <linux/sunrpc/gss_asn1.h>
+
+typedef struct _krb5_data {
+ s32 magic;
+ int length;
+ char *data;
+} krb5_data;
+
+/* krb5 principal (krb5.h) */
+typedef struct krb5_principal_data {
+ s32 magic;
+ krb5_data realm;
+ krb5_data *data; /* An array of strings */
+ s32 length;
+ s32 type;
+} krb5_principal_data;
+
+typedef krb5_principal_data *krb5_principal;
+
+/* krb5 keyblock */
+
+typedef struct _krb5_keyblock {
+ s32 magic;
+ s32 enctype;
+ int length;
+ unsigned char *contents;
+} krb5_keyblock;
+
+struct krb5_keyhash_provider {
+ void (*hash_size)
+ (size_t * output);
+
+ s32(*hash)
+ (krb5_keyblock * key, krb5_data * ivec,
+ krb5_data * input, krb5_data * output);
+
+ s32(*verify)
+ (krb5_keyblock * key, krb5_data * ivec,
+ krb5_data * input, krb5_data * hash, unsigned int *valid);
+};
+
+struct krb5_hash_provider {
+ void (*hash_size)
+ (size_t * output);
+
+ void (*block_size)
+ (size_t * output);
+
+ /* this takes multiple inputs to avoid lots of copying. */
+ s32(*hash)
+ (unsigned int icount, krb5_data * input, krb5_data * output);
+};
+
+typedef struct _krb5_2_linux_digest {
+ s32 ctype;
+ char *digest_name;
+ struct krb5_hash_provider *hash;
+ struct krb5_keyhash_provider *keyhash;
+} krb5_2_linux_digest;
+
+typedef struct _krb5_2_linux_keytypes {
+ s32 enctype;
+ char *seal_name;
+ unsigned int seal_mode;
+ char *sign_name;
+} krb5_2_linux_keytypes;
+
+/* structure for address */
+typedef struct _krb5_address {
+ s32 magic;
+ s32 addrtype;
+ int length;
+ unsigned char *contents;
+} krb5_address;
+
+/* structure for auth data */
+typedef struct _krb5_authdata {
+ s32 magic;
+ s32 ad_type;
+ int length;
+ unsigned char *contents;
+} krb5_authdata;
+
+typedef struct _krb5_checksum {
+ s32 magic;
+ s32 checksum_type; /* checksum type */
+ int length;
+ unsigned char *contents;
+} krb5_checksum;
+
+
+/* the unencrypted version */
+typedef struct _krb5_authenticator {
+ s32 magic;
+ krb5_principal client; /* client name/realm */
+ krb5_checksum *checksum; /* checksum, includes type, optional */
+ s32 cusec; /* client usec portion */
+ s32 ctime; /* client sec portion */
+ krb5_keyblock *subkey; /* true session key, optional */
+ s32 seq_number; /* sequence #, optional */
+ krb5_authdata **authorization_data; /* New add by Ari, auth data */
+} krb5_authenticator;
+
+
+typedef struct krb5_rc_st {
+ s32 magic;
+ struct _krb5_rc_ops *ops;
+ void *data;
+} *krb5_rcache;
+
+
+/* from auth_con.h */
+struct _krb5_auth_context {
+ s32 magic;
+ krb5_address *remote_addr;
+ krb5_address *remote_port;
+ krb5_address *local_addr;
+ krb5_address *local_port;
+ krb5_keyblock *keyblock;
+ krb5_keyblock *local_subkey;
+ krb5_keyblock *remote_subkey;
+
+ s32 auth_context_flags;
+ s32 remote_seq_number;
+ s32 local_seq_number;
+ krb5_authenticator *authentp; /* mk_req, rd_req, mk_rep, ... */
+ s32 req_cksumtype; /* mk_safe, ... */
+ s32 safe_cksumtype; /* mk_safe, ... */
+ void *i_vector; /* mk_priv, rd_priv only */
+ krb5_rcache rcache;
+ s32 *permitted_etypes; /* rd_req */
+};
+typedef struct _krb5_auth_context *krb5_auth_context;
+
+
+/* the krb5 gss context that is stored in userland */
+typedef struct _krb5_gss_ctx_id_rec {
+ int initiate; /* nonzero if initiating, zero if accepting */
+ u32 gss_flags;
+ int seed_init;
+ unsigned char seed[16];
+ krb5_principal here;
+ krb5_principal there;
+ krb5_keyblock *subkey;
+ int signalg;
+ int cksum_size;
+ int sealalg;
+ krb5_keyblock *enc;
+ krb5_keyblock *seq;
+ s32 endtime;
+ s32 krb_flags;
+ /* XXX these used to be signed. the old spec is inspecific, and
+ the new spec specifies unsigned. I don't believe that the change
+ affects the wire encoding. */
+ u32 seq_send;
+ u32 seq_recv;
+ int big_endian;
+ krb5_auth_context auth_context;
+ GSS_OID *mech_used;
+ int nctypes;
+ s32 *ctypes;
+} krb5_gss_ctx_id_rec, *krb5_gss_ctx_id_t;
+
+#define KG_TOK_SIGN_MSG 0x0101
+#define KG_TOK_SEAL_MSG 0x0201
+#define KG_TOK_MIC_MSG 0x0101
+#define KG_TOK_WRAP_MSG 0x0201
+
+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 RSA_MD5_CKSUM_LENGTH 16
+
+/* 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 KG_USAGE_SEAL 22
+#define KG_USAGE_SIGN 23
+#define KG_USAGE_SEQ 24
+
+/* 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)
+
+#define KV5M_PRINCIPAL (-1760647423L)
+#define KV5M_KEYBLOCK (-1760647421L)
+#define KV5M_CHECKSUM (-1760647420L)
+#define KV5M_ADDRESS (-1760647390L)
+#define KV5M_AUTHENTICATOR (-1760647410L)
+#define KV5M_AUTH_CONTEXT (-1760647383L)
+#define KV5M_AUTHDATA (-1760647414L)
+#define KV5M_GSS_OID (-1760647372L)
+#define KV5M_GSS_QUEUE (-1760647371L)
+
+#define krb5_princ_realm(context, princ) (&(princ)->realm)
+#define krb5_princ_size(context, princ) (princ)->length
+#define krb5_princ_component(context, princ,i) ((princ)->data + i)
+
+ /* 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_UNKNOWN 0x01ff
+/* local crud */
+/* marc's DES-3 with 32-bit length */
+#define ENCTYPE_LOCAL_DES3_HMAC_SHA1 0x7007
+
+#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 */
+
+s32
+krb5_ser_pack_bytes(unsigned char *ostring,
+ size_t osize, unsigned char **bufp, size_t * remainp);
+
+s32
+krb5_ser_unpack_bytes(unsigned char *istring,
+ size_t isize,
+ unsigned char **bufp, size_t * remainp);
+
+s32 krb5_ser_pack_int32(s32 iarg, unsigned char **bufp, size_t * remainp);
+
+s32
+krb5_ser_unpack_int32(s32 * intp, unsigned char **bufp, size_t * remainp);
+
+u32
+g_queue_internalize(void **vqueue,
+ unsigned char **buf, size_t * lenremain);
+
+s32 krb5_principal_skip(unsigned char **buffer, size_t * lenremain);
+
+s32 krb5_principal_size(void *arg, size_t * sizep);
+
+s32 krb5_keyblock_size(void *arg, size_t * sizep);
+
+s32
+krb5_keyblock_internalize(void **argp,
+ unsigned char **buffer, size_t * lenremain);
+
+void krb5_free_keyblock(register krb5_keyblock * key);
+
+s32
+kg_oid_internalize(void **argp,
+ unsigned char **buffer, size_t * lenremain);
+
+s32
+kg_queue_internalize(void **argp,
+ unsigned char **buffer, size_t * lenremain);
+
+s32
+kg_ctx_internalize(void **argp,
+ unsigned char **buffer, size_t * lenremain);
+
+void print_krb5_gss_ctx_id_rec(krb5_gss_ctx_id_t ctx);
+
+u32
+k5_gss_import_sec_context(GSS_BUFFER_T * inbuf, void **ctx_handle);
+
+int k5_get_blocksize(s32 enctype, size_t * blocksize);
+
+int k5_get_checksum_length(s32 cksmtype, size_t * length);
+
+int find_digest(s32 type);
+
+int find_enctype(s32 enctype);
+
+s32
+krb5_c_make_checksum(s32 cksumtype,
+ krb5_keyblock * key,
+ s32 usage, krb5_data * input, krb5_checksum * cksum);
+
+u32
+kg_seal(GSS_CTX_ID_T context_handle,
+ int conf_req_flag,
+ int qop_req,
+ GSS_BUFFER_T * input_message_buffer,
+ int *conf_state,
+ GSS_BUFFER_T * output_message_buffer, int toktype);
+
+u32
+kg_unseal(GSS_CTX_ID_T context_handle,
+ GSS_BUFFER_T * input_token_buffer,
+ GSS_BUFFER_T * message_buffer,
+ int *conf_state, int *qop_state, int toktype);
+
+u32
+gss_k5encrypt(krb5_keyblock * key,
+ int usage, void *iv, void *in, void *out, int length);
+
+u32
+gss_k5decrypt(krb5_keyblock * key,
+ int usage, void *iv, void *in, void *out, int length);
+
+s32
+kg_make_seq_num(krb5_keyblock * key,
+ int direction,
+ s32 seqnum, unsigned char *cksum, unsigned char *buf);
+
+s32 kg_get_seq_num(krb5_keyblock * key,
+ unsigned char *cksum,
+ unsigned char *buf, int *direction, s32 * seqnum);
diff -u --recursive --new-file linux-2.5.45-07-auth_upcall2/net/sunrpc/Makefile linux-2.5.45-08-krb5/net/sunrpc/Makefile
--- linux-2.5.45-07-auth_upcall2/net/sunrpc/Makefile 2002-10-31 10:23:24.000000000 -0500
+++ linux-2.5.45-08-krb5/net/sunrpc/Makefile 2002-10-31 15:45:10.000000000 -0500
@@ -19,4 +19,10 @@
auth_rpcgss-objs := auth_gss.o gss_pseudoflavors.o gss_generic_token.o \
sunrpcgss_syms.o gss_mech_switch.o gss_delete_sec_context.o
+rpcsec_gss_krb5-objs := gss_krb5_mech.o gss_krb5_cksum.o gss_krb5_md5.o \
+ gss_krb5_seal.o gss_krb5_unseal.o gss_krb5_encrypt.o \
+ gss_krb5_seqnum.o gss_krb5_decrypt.o \
+ gss_krb5_crypto_utils.o
+obj-$(CONFIG_RPCSEC_GSS_KRB5) += rpcsec_gss_krb5.o
+
include $(TOPDIR)/Rules.make
diff -u --recursive --new-file linux-2.5.45-07-auth_upcall2/net/sunrpc/gss_krb5_cksum.c linux-2.5.45-08-krb5/net/sunrpc/gss_krb5_cksum.c
--- linux-2.5.45-07-auth_upcall2/net/sunrpc/gss_krb5_cksum.c 1969-12-31 19:00:00.000000000 -0500
+++ linux-2.5.45-08-krb5/net/sunrpc/gss_krb5_cksum.c 2002-10-31 15:45:10.000000000 -0500
@@ -0,0 +1,106 @@
+/*
+ * linux/net/sunrpc/gss_krb5_cksum.c
+ *
+ * Adapted from MIT Kerberos 5-1.2.1 lib/gssapi/krb5/k5seal.c
+ *
+ * Copyright (c) 2000 The Regents of the University of Michigan.
+ * All rights reserved.
+ *
+ * Andy Adamson <andros@umich.edu>
+ */
+
+/*
+ * Copyright (C) 1998 by the FundsXpress, INC.
+ *
+ * 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 FundsXpress. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. FundsXpress makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/sunrpc/gss_krb5_types.h>
+
+
+#ifdef RPC_DEBUG
+# define RPCDBG_FACILITY RPCDBG_AUTH
+#endif
+
+
+extern const krb5_2_linux_digest digest_list[];
+
+s32
+krb5_c_make_checksum(s32 cksumtype,
+ krb5_keyblock * key,
+ s32 usage,
+ krb5_data * input, krb5_checksum * cksum)
+{
+ int i;
+ krb5_data data;
+ s32 ret = 0;
+ size_t cksumlen;
+
+ /* the checksum length was just set in make_seal_token_v1
+ * so, either we remove that code, or remove this code....*/
+
+ if ((i = find_digest(cksumtype)) == -1)
+ return (-EINVAL);
+
+ if (digest_list[i].keyhash)
+ (*(digest_list[i].keyhash->hash_size)) (&cksumlen);
+ else if (digest_list[i].hash)
+ (*(digest_list[i].hash->hash_size)) (&cksumlen);
+ else
+ return (-EINVAL);
+
+ cksum->length = cksumlen;
+
+ if ((cksum->contents =
+ (unsigned char *) rpc_allocate(0, cksum->length)) == NULL)
+ return (ENOMEM);
+
+ data.length = cksum->length;
+ data.data = cksum->contents;
+
+
+ dprintk
+ ("RPC: krb5_c_make_checksum cksum->length %d input->length %d\n",
+ cksum->length, input->length);
+
+ if (digest_list[i].keyhash)
+ ret =
+ (*(digest_list[i].keyhash->hash)) (key, 0, input,
+ &data);
+ else if (digest_list[i].hash)
+ ret = (*(digest_list[i].hash->hash)) (1, input, &data);
+
+ if (!ret) {
+ cksum->magic = KV5M_CHECKSUM;
+ cksum->checksum_type = cksumtype;
+ }
+ if (ret) {
+ memset(cksum->contents, 0, cksum->length);
+ rpc_free(cksum->contents);
+ }
+
+ dprintk("RPC: gss_k5cksum: returning %d\n", ret);
+ return (ret);
+}
diff -u --recursive --new-file linux-2.5.45-07-auth_upcall2/net/sunrpc/gss_krb5_crypto_utils.c linux-2.5.45-08-krb5/net/sunrpc/gss_krb5_crypto_utils.c
--- linux-2.5.45-07-auth_upcall2/net/sunrpc/gss_krb5_crypto_utils.c 1969-12-31 19:00:00.000000000 -0500
+++ linux-2.5.45-08-krb5/net/sunrpc/gss_krb5_crypto_utils.c 2002-10-31 15:45:10.000000000 -0500
@@ -0,0 +1,148 @@
+/*
+ * linux/net/sunrpc/gss_util_crypto.c
+ *
+ * Copyright (c) 2001 The Regents of the University of Michigan.
+ * All rights reserved.
+ *
+ * Andy Adamson <andros@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.
+ *
+ */
+
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/sunrpc/auth.h>
+#include <linux/sunrpc/gss_krb5_types.h>
+#include <linux/crypto.h>
+
+#ifdef RPC_DEBUG
+# define RPCDBG_FACILITY RPCDBG_AUTH
+#endif
+
+/* from crypto/api.c */
+extern struct crypto_alg *crypto_alg_lookup(char *name);
+
+/* linux crypto framework uses names to lookup supported ciphers and
+ * digests. these structures map the kerberos5 digest and cipher types
+ * to the linux crypto specific names.
+ */
+
+extern struct krb5_hash_provider krb5_hash_md5;
+
+/* name mapping for digests */
+const krb5_2_linux_digest digest_list[] = {
+ { CKSUMTYPE_RSA_MD5,
+ "md5",
+ &krb5_hash_md5,
+ (struct krb5_keyhash_provider *)NULL}
+};
+const int digest_list_length =
+ sizeof(digest_list)/sizeof(krb5_2_linux_digest);
+
+/* name mapping for encryption algorithms */
+const krb5_2_linux_keytypes cipher_list[] = {
+ { ENCTYPE_DES_CBC_RAW, "des", CRYPTO_TFM_MODE_CBC ,"NULL"}
+};
+const int keytype_length =
+ sizeof(cipher_list)/sizeof(krb5_2_linux_keytypes);
+
+int
+find_digest(s32 type)
+{
+ int i;
+
+ dprintk("RPC:find_digest type %d\n",type);
+ for(i=0;i<digest_list_length;i++){
+ if(digest_list[i].ctype == type){
+ dprintk("RPC:find_digest loop i %d ctype %d\n",i,
+ digest_list[i].ctype);
+ break;
+ }
+ }
+ if(i == digest_list_length)
+ return -1;
+ return i;
+}
+
+int
+find_enctype(s32 enctype)
+{
+int i;
+
+ dprintk("RPC:find_enctype type %d\n",enctype);
+ for(i=0;i<keytype_length;i++){
+ if(cipher_list[i].enctype == enctype)
+ break;
+ }
+ if(i == keytype_length)
+ return -1;
+ return i;
+}
+
+int
+k5_get_blocksize(s32 enctype, size_t *blocksize)
+{
+ int i;
+ struct crypto_alg *alg = NULL;
+
+ dprintk("RPC: k5_get_blocksize type %d \n",enctype);
+ i = find_enctype(enctype);
+ if(i < 0)
+ return(-EINVAL);
+
+ if(cipher_list[i].seal_name)
+ alg = crypto_alg_lookup(cipher_list[i].seal_name);
+ if(!alg)
+ return(-EINVAL);
+
+ *blocksize = alg->cra_blocksize;
+ dprintk("RPC: k5_get_blocksize blocksize %d\n",*blocksize);
+ return 0;
+}
+
+int
+k5_get_checksum_length(s32 cksmtype, size_t *length)
+{
+ int i;
+ struct crypto_alg *alg = NULL;
+
+ dprintk("RPC: k5_get_checksum_length type %d\n",cksmtype);
+ i = find_digest(cksmtype);
+ if(i < 0)
+ return(-EINVAL);
+
+ dprintk("RPC: k5_get_checksum_length calling crypto_alg_lookup on %s\n",
+ digest_list[i].digest_name);
+ if(digest_list[i].digest_name)
+ alg = crypto_alg_lookup(digest_list[i].digest_name);
+ if(!alg)
+ return(-EINVAL);
+ *length = alg->cra_blocksize;
+ dprintk("RPC: k5_get_checksum_length length %d\n",*length);
+ return 0;
+}
diff -u --recursive --new-file linux-2.5.45-07-auth_upcall2/net/sunrpc/gss_krb5_decrypt.c linux-2.5.45-08-krb5/net/sunrpc/gss_krb5_decrypt.c
--- linux-2.5.45-07-auth_upcall2/net/sunrpc/gss_krb5_decrypt.c 1969-12-31 19:00:00.000000000 -0500
+++ linux-2.5.45-08-krb5/net/sunrpc/gss_krb5_decrypt.c 2002-10-31 15:45:11.000000000 -0500
@@ -0,0 +1,149 @@
+/*
+ * linux/net/sunrpc/gss_krb5_decrypt.c
+ *
+ * Adapted from MIT Kerberos 5-1.2.1 lib/crypto/raw/raw_decrypt.c
+ *
+ * Copyright (c) 2000 The Regents of the University of Michigan.
+ * All rights reserved.
+ *
+ * Andy Adamson <andros@umich.edu>
+ */
+
+/*
+ * Copyright (C) 1998 by the FundsXpress, INC.
+ *
+ * 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 FundsXpress. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. FundsXpress makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+
+/* combines functionality of kg_decrypt(), krb5_c_decrypt(), and
+ * krb5_raw_decrypt()
+ */
+
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <asm/scatterlist.h>
+#include <linux/highmem.h>
+#include <linux/sunrpc/gss_krb5_types.h>
+#include <linux/crypto.h>
+
+
+#ifdef RPC_DEBUG
+# define RPCDBG_FACILITY RPCDBG_AUTH
+#endif
+
+
+extern const krb5_2_linux_keytypes cipher_list[];
+
+u32
+gss_k5decrypt(
+ krb5_keyblock *key,
+ int usage,
+ void * iv,
+ void * in,
+ void * out,
+ int length)
+{
+ u32 ret = 0;
+ int i = -1;
+ char *p;
+ struct crypto_tfm *tfm;
+ struct scatterlist sg[1]; /* XXX will need to dynamically allocate */
+ u32 local_iv[4] = {0,0,0,0};
+
+ dprintk("gss_k5decrypt: TOP in %p out %p\n",in,out);
+ dprintk("gss_k5decrypt: in data:\n");
+ print_hexl((u32 *)in,length,0);
+
+ /* key->enctype was checked by the caller */
+
+ if (key->length != 8)
+ return(-EINVAL); /*KRB5_BAD_KEYSIZE*/
+ if ((length%8) != 0)
+ return(-EINVAL); /*KRB5_BAD_MSIZE*/
+
+
+ if((i = find_enctype(key->enctype)) == -1)
+ return( -EINVAL);
+
+ ret = -ENOMEM;
+ tfm = crypto_alloc_tfm(cipher_list[i].seal_name,
+ cipher_list[i].seal_mode);
+ if (!tfm)
+ goto out;
+
+ /* set initialization vector as per rfc1510 */
+ ret = -EINVAL;
+ if (crypto_tfm_alg_ivsize(tfm) != 8 ) {
+ dprintk("RPC: gss_k5encrypt: tfm iv size to large %d\n",
+ crypto_tfm_alg_ivsize(tfm));
+ goto out_free;
+ }
+ if (iv) {
+ memcpy(local_iv,iv, crypto_tfm_alg_ivsize(tfm));
+ } else {
+ memset(local_iv,0,crypto_tfm_alg_ivsize(tfm));
+ }
+ crypto_cipher_set_iv(tfm, iv, crypto_tfm_alg_blocksize(tfm));
+
+
+ /*XXX need to check key parity here*/
+
+ dprintk("RPC: gss_k5decrypt :setkey args: \n");
+ dprintk(" key->contents %p, key->length %d\n",
+ key->contents,key->length);
+
+ dprintk("RPC: gss_k5decrypt: key data:\n");
+ print_hexl((u32 *)key->contents, key->length, 0);
+
+ ret = crypto_cipher_setkey(tfm, key->contents, key->length);
+ if (ret) {
+ dprintk("RPC: setkey failed. ret: %d\n",ret);
+ goto out_free;
+ }
+
+ memcpy(out, in, length);
+ sg[0].page = virt_to_page(out);
+ sg[0].offset = ((long)out & ~PAGE_MASK);
+ sg[0].length = length;
+
+ ret = crypto_cipher_decrypt(tfm, sg, 1);
+ if (ret) {
+ printk("des_cbc_decrypt() failed flags=%x\n",
+ tfm->crt_flags);
+ goto out_free;
+ }
+
+
+#if 0
+ dprintk("RPC: gss_k5decrypt: out: ");
+ print_hexl((u32 *)out, length, 0);
+#endif
+
+out_free:
+ crypto_free_tfm(tfm);
+out:
+ dprintk("gss_k5decrypt returns %d\n",ret);
+ return(ret);
+}
diff -u --recursive --new-file linux-2.5.45-07-auth_upcall2/net/sunrpc/gss_krb5_encrypt.c linux-2.5.45-08-krb5/net/sunrpc/gss_krb5_encrypt.c
--- linux-2.5.45-07-auth_upcall2/net/sunrpc/gss_krb5_encrypt.c 1969-12-31 19:00:00.000000000 -0500
+++ linux-2.5.45-08-krb5/net/sunrpc/gss_krb5_encrypt.c 2002-10-31 15:45:11.000000000 -0500
@@ -0,0 +1,158 @@
+/*
+ * linux/net/sunrpc/gss_krb5_encrypt.c
+ *
+ * Adapted from MIT Kerberos 5-1.2.1 lib/crypto/raw/raw_encrypt.c
+ *
+ * Copyright (c) 2000 The Regents of the University of Michigan.
+ * All rights reserved.
+ *
+ * Andy Adamson <andros@umich.edu>
+ */
+
+/*
+ * Copyright (C) 1998 by the FundsXpress, INC.
+ *
+ * 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 FundsXpress. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. FundsXpress makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/* combines functionality of kg_encrypt(), krb5_c_encrypt(), and
+ * krb5_raw_encrypt()
+ */
+
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <asm/scatterlist.h>
+#include <linux/highmem.h>
+#include <linux/sunrpc/gss_krb5_types.h>
+#include <linux/crypto.h>
+
+
+#ifdef RPC_DEBUG
+# define RPCDBG_FACILITY RPCDBG_AUTH
+#endif
+
+
+extern const krb5_2_linux_keytypes cipher_list[];
+
+u32
+gss_k5encrypt(
+ krb5_keyblock *key,
+ int usage,
+ void * iv,
+ void * in,
+ void * out,
+ int length)
+{
+ u32 ret = 0;
+ int i = -1;
+ char *p;
+ struct crypto_tfm *tfm;
+ struct scatterlist sg[1]; /* XXX when do i need more than 1? */
+ u32 local_iv[8] = {0,0,0,0,0,0,0,0};
+
+ dprintk("gss_k5encrypt:\n");
+
+ dprintk("RPC: gss_k5encrypt: TOP out %p in %p in data:\n",out,in);
+ print_hexl((u32 *)in,length,0);
+
+ /* key->enctype was checked by the caller */
+
+ if (key->length != 8)
+ return(-EINVAL); /*KRB5_BAD_KEYSIZE*/
+ if ((length%8) != 0)
+ return(-EINVAL); /*KRB5_BAD_MSIZE*/
+
+ if((i = find_enctype(key->enctype)) == -1)
+ return( -EINVAL);
+
+ ret = -ENOMEM;
+ dprintk("RPC: gss_k5encrypt calling crypto_alloc_tfm for: %s\n",
+ cipher_list[i].seal_name);
+ tfm = crypto_alloc_tfm(cipher_list[i].seal_name,
+ cipher_list[i].seal_mode);
+ if (!tfm)
+ goto out;
+
+ if (crypto_tfm_alg_ivsize(tfm) != 8 ) {
+ dprintk("RPC: gss_k5encrypt: tfm iv size to large %d\n",
+ crypto_tfm_alg_ivsize(tfm));
+ goto out_free;
+ }
+
+ /* set initialization vector as per rfc1510
+ * local_iv is set to zero unless input iv is set..
+ */
+ if (iv) {
+ dprintk("RPC: gss_k5encrypt : iv %p: \n",iv);
+ memcpy(local_iv, iv, crypto_tfm_alg_ivsize(tfm));
+ }
+
+
+ /*XXX need to check key parity ?*/
+
+ dprintk("RPC: gss_k5encrypt : setkey args: \n");
+ dprintk(" key->contents %p, key->length %d\n",
+ key->contents,key->length);
+
+ dprintk("RPC: gss_k5encrypt: key data:\n");
+ print_hexl((u32 *)key->contents, key->length, 0);
+
+ ret = crypto_cipher_setkey(tfm, key->contents, key->length);
+ if (ret) {
+ dprintk("RPC: setkey failed. ret: %d\n",ret);
+ goto out_free;
+ }
+
+#if 0
+ dprintk("RPC: gss_k5encrypt : calling encrypt:\n");
+ dprintk(" in:%p in data:\n",in);
+ print_hexl(in,length,0);
+ dprintk(" out %p\n",out);
+ dprintk(" blocksize %d\n",crypto_tfm_alg_blocksize(tfm));
+ dprintk(" local_iv %p local_iv data:\n",local_iv);
+ print_hexl((u32 *)local_iv,8,0);
+#endif
+ memcpy(out, in, length);
+ sg[0].page = virt_to_page(out);
+ sg[0].offset = ((long)out & ~PAGE_MASK);
+ sg[0].length = length;
+
+ ret = crypto_cipher_encrypt(tfm, sg, 1);
+ if (ret) {
+ printk("des_cbc_decrypt() failed flags=%x\n", tfm->crt_flags);
+ goto out_free;
+ }
+
+#if 0
+ dprintk("RPC: gss_k5encrypt : after ci->encrypt:\n");
+ dprintk(" out:%p out data:\n",out);
+ print_hexl(out,8,0);
+#endif
+
+out_free:
+ crypto_free_tfm(tfm);
+out:
+ dprintk("gss_k5encrypt returns %d\n",ret);
+ return(ret);
+}
diff -u --recursive --new-file linux-2.5.45-07-auth_upcall2/net/sunrpc/gss_krb5_md5.c linux-2.5.45-08-krb5/net/sunrpc/gss_krb5_md5.c
--- linux-2.5.45-07-auth_upcall2/net/sunrpc/gss_krb5_md5.c 1969-12-31 19:00:00.000000000 -0500
+++ linux-2.5.45-08-krb5/net/sunrpc/gss_krb5_md5.c 2002-10-31 15:45:11.000000000 -0500
@@ -0,0 +1,116 @@
+/*
+ * linux/net/sunrpc/gss_krb5_md5.c
+ *
+ * Adapted from MIT Kerberos 5-1.2.1 lib/crypto/hash_provider/hash_md5.c
+ *
+ * Copyright (c) 2000 The Regents of the University of Michigan.
+ * All rights reserved.
+ *
+ * Andy Adamson <andros@umich.edu>
+ */
+
+/*
+ * Copyright (C) 1998 by the FundsXpress, INC.
+ *
+ * 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 FundsXpress. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. FundsXpress makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <asm/scatterlist.h>
+#include <linux/sunrpc/gss_krb5_types.h>
+#include <linux/crypto.h>
+
+
+#ifdef RPC_DEBUG
+# define RPCDBG_FACILITY RPCDBG_AUTH
+#endif
+
+
+static void gss_k5_md5_hash_size(size_t * output)
+{
+ *output = RSA_MD5_CKSUM_LENGTH;
+}
+
+static void gss_k5_md5_block_size(size_t * output)
+{
+ *output = 64;
+}
+
+static s32
+gss_k5_md5_hash(unsigned int icount, krb5_data * input, krb5_data * output)
+{
+ char *p;
+ int i, ret = 0;
+ struct scatterlist sg[1]; /*XXX when do i need more than 1? */
+ struct crypto_tfm *tfm;
+ char digest_out[128]; /*XXX dynamic memory ? */
+
+ dprintk("RPC: gss_k5_md5_hash\n");
+ if (output->length != RSA_MD5_CKSUM_LENGTH)
+ return (-EINVAL);
+
+ /* initialize the kernel hash interface */
+ ret = -ENOMEM;
+ tfm = crypto_alloc_tfm("md5", 0);
+ if (!tfm)
+ goto out;
+
+ memset(digest_out, 0, sizeof(digest_out));
+ p = input->data;
+ sg[0].page = virt_to_page(p);
+ sg[0].offset = ((long) p & ~PAGE_MASK);
+ sg[0].length = input->length;
+
+ crypto_digest_init(tfm);
+
+ for (i = 0; i < icount; i++) {
+ dprintk("gss_k5_md5_hash: INPUT TEXT: u8 len %d\n",
+ input[i].length);
+ print_hexl((u32 *) input[i].data, input[i].length, 0);
+ crypto_digest_update(tfm, sg, 1);
+ }
+ crypto_digest_final(tfm, digest_out);
+
+/*XXX use crypto_tfm_alg_digestsize(tfm) instead of RSA_MD5_CKSUM_LENGTH? */
+ memcpy(output->data, digest_out, RSA_MD5_CKSUM_LENGTH);
+#if 0
+ dprintk("gss_k5_md5_hash: digest buffer HASH RESULT byte len %d\n",
+ RSA_MD5_CKSUM_LENGTH);
+ print_hexl((u32 *) digest_out, RSA_MD5_CKSUM_LENGTH, 0);
+ dprintk("gss_k5_md5_hash: output buffer HASH RESULT byte len %d\n",
+ RSA_MD5_CKSUM_LENGTH);
+ print_hexl((u32 *) output->data, RSA_MD5_CKSUM_LENGTH, 0);
+#endif /*0 */
+ ret = 0;
+ crypto_free_tfm(tfm);
+ out:
+ return (ret);
+}
+
+const struct krb5_hash_provider krb5_hash_md5 = {
+ gss_k5_md5_hash_size,
+ gss_k5_md5_block_size,
+ gss_k5_md5_hash
+};
diff -u --recursive --new-file linux-2.5.45-07-auth_upcall2/net/sunrpc/gss_krb5_mech.c linux-2.5.45-08-krb5/net/sunrpc/gss_krb5_mech.c
--- linux-2.5.45-07-auth_upcall2/net/sunrpc/gss_krb5_mech.c 1969-12-31 19:00:00.000000000 -0500
+++ linux-2.5.45-08-krb5/net/sunrpc/gss_krb5_mech.c 2002-10-31 15:50:48.000000000 -0500
@@ -0,0 +1,297 @@
+/*
+ * linux/net/sunrpc/gss_krb5_mech.c
+ *
+ * Copyright (c) 2001 The Regents of the University of Michigan.
+ * All rights reserved.
+ *
+ * Andy Adamson <andros@umich.edu>
+ * 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.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/sunrpc/auth.h>
+#include <linux/sunrpc/gss_krb5_types.h>
+#include <linux/sunrpc/xdr.h>
+#include <linux/crypto.h>
+
+#ifdef RPC_DEBUG
+# define RPCDBG_FACILITY RPCDBG_AUTH
+#endif
+
+GSS_OID gss_mech_krb5_oid =
+ {9, "\052\206\110\206\367\022\001\002\002"};
+
+void
+print_krb5_gss_ctx_id_rec(krb5_gss_ctx_id_t k5_ctx)
+{
+ dprintk("some of krb5_gss_ctx_id_rec: \n");
+ if (!k5_ctx) return;
+ dprintk(" initiate: %d\n",k5_ctx->initiate);
+ dprintk(" gss_flags: 0x%x\n",k5_ctx->gss_flags);
+ dprintk(" seed_init: %d\n",k5_ctx->seed_init);
+ dprintk(" signalg: %d\n",k5_ctx->signalg);
+ dprintk(" cksum_size: %d\n",k5_ctx->cksum_size);
+ dprintk(" sealalg: %d\n",k5_ctx->sealalg);
+ dprintk(" ENC types: \n");
+ if (k5_ctx->enc) {
+ dprintk(" enc->enctype: %d\n",k5_ctx->enc->enctype);
+ dprintk(" enc->length: %d\n",k5_ctx->enc->length);
+ }else
+ dprintk(" NULL ENC\n");
+ if (k5_ctx->seq) {
+ dprintk(" seq->enctype: %d\n",k5_ctx->seq->enctype);
+ dprintk(" seq->length: %d\n",k5_ctx->seq->length);
+ }else
+ dprintk(" NULL SEQ\n");
+}
+
+static inline int
+get_bytes(char **ptr, const char *end, void *res, int len)
+{
+ char *p, *q;
+ p = *ptr;
+ q = p + len;
+ if (q > end || q < p)
+ return -1;
+ memcpy(res, p, len);
+ *ptr = q;
+ return 0;
+}
+
+static inline int
+get_netobj(char **ptr, const char *end, struct xdr_netobj *res)
+{
+ char *p, *q;
+ p = *ptr;
+ if (get_bytes(&p, end, &res->len, sizeof(res->len)))
+ return -1;
+ q = p + res->len;
+ if (q > end || q < p)
+ return -1;
+ if (!(res->data = rpc_allocate(0, res->len)))
+ return -1;
+ memcpy(res->data, p, res->len);
+ *ptr = q;
+ return 0;
+}
+
+static inline int
+get_keyblock(char **p, char *end, struct _krb5_keyblock **res)
+{
+ struct xdr_netobj tmp;
+
+ if (!(*res = rpc_allocate(0, sizeof(struct _krb5_keyblock))))
+ goto out_err;
+ if (!get_bytes(p, end, &(*res)->magic, sizeof((*res)->magic)))
+ goto out_free;
+ if (!get_bytes(p, end, &(*res)->enctype, sizeof((*res)->enctype)))
+ goto out_free;
+ if (!get_bytes(p, end, &(*res)->length, sizeof((*res)->length)))
+ goto out_free;
+ if (!(get_netobj(p, end, &tmp)))
+ goto out_free;
+ (*res)->length = tmp.len;
+ (*res)->contents = tmp.data;
+ return 0;
+out_free:
+ rpc_free(*res);
+out_err:
+ return -1;
+}
+
+static int
+krb5_ctx_internalize(struct _krb5_gss_ctx_id_rec **ctxp, char **p, int len)
+{
+ char *end = *p + len;
+ struct _krb5_gss_ctx_id_rec *ctx;
+
+ if (!(*ctxp = rpc_allocate(0, sizeof(**ctxp))))
+ goto out_err;
+ ctx = *ctxp;
+ memset(ctx, 0, sizeof(*ctx));
+
+ if (!get_bytes(p, end, &ctx->initiate, sizeof(ctx->initiate)))
+ goto out_err_free_ctx;
+ if (!get_bytes(p, end, &ctx->seed_init, sizeof(ctx->seed_init)))
+ goto out_err_free_ctx;
+ if (!get_bytes(p, end, ctx->seed, sizeof(ctx->seed)))
+ goto out_err_free_ctx;
+ if (!get_bytes(p, end, &ctx->signalg, sizeof(ctx->signalg)))
+ goto out_err_free_ctx;
+ if (!get_bytes(p, end, &ctx->cksum_size, sizeof(ctx->cksum_size)))
+ goto out_err_free_ctx;
+ if (!get_bytes(p, end, &ctx->sealalg, sizeof(ctx->sealalg)))
+ goto out_err_free_ctx;
+ if (!get_bytes(p, end, &ctx->endtime, sizeof(ctx->endtime)))
+ goto out_err_free_ctx;
+ if (!get_bytes(p, end, &ctx->seq_send, sizeof(ctx->seq_send)))
+ goto out_err_free_ctx;
+ if (!get_bytes(p, end, &ctx->big_endian, sizeof(ctx->big_endian)))
+ goto out_err_free_ctx;
+ if (!get_netobj(p, end, (struct xdr_netobj *)&ctx->mech_used))
+ goto out_err_free_ctx;
+ if (!get_keyblock(p, end, &ctx->enc))
+ goto out_err_free_mech;
+ if (!get_keyblock(p, end, &ctx->seq))
+ goto out_err_free_keyblock1;
+ if (*p != end)
+ goto out_err_free_keyblock2;
+ return 0;
+out_err_free_keyblock2:
+ rpc_free(ctx->seq->contents);
+ rpc_free(ctx->seq);
+out_err_free_keyblock1:
+ rpc_free(ctx->enc->contents);
+ rpc_free(ctx->enc);
+out_err_free_mech:
+ rpc_free(ctx->mech_used);
+out_err_free_ctx:
+ rpc_free(ctx);
+ *ctxp = NULL;
+out_err:
+ return -1;
+}
+
+u32
+gss_import_sec_context_kerberos(GSS_BUFFER_T *inbuf,
+ GSS_CTX_ID_T ctx_id)
+{
+ krb5_gss_ctx_id_t ctx;
+ int length;
+ char *p;
+
+ dprintk("RPC: k5_gss_import_sec_context inbuf: %p:%d\n",
+ inbuf->data,inbuf->len);
+ /* Skipping the mech oid; we don't really need it, but it might
+ * be useful as a sanity check. */
+ p = inbuf->data;
+ length = *p++;
+ length = (length << 8) + *p++;
+ length = (length << 8) + *p++;
+ length = (length << 8) + *p++;
+ if (length > inbuf->len) {
+ dprintk("RPC: k5_gss_import_sec_context mech oid length"
+ " too large %d:\n", length);
+ return(KG_BAD_LENGTH);
+ }
+ p += length;
+
+ if (krb5_ctx_internalize(&ctx, &p, inbuf->len))
+ return(GSS_S_FAILURE);
+ ctx_id->internal_ctx_id = ctx;
+
+ print_krb5_gss_ctx_id_rec(ctx);
+ return(0);
+}
+
+u32
+gss_verify_mic_kerberos( GSS_CTX_ID_T contextid,
+ GSS_BUFFER_T *signbuf,
+ GSS_BUFFER_T *checksum,
+ u32 *qstate) {
+ u32 maj_stat = 0;
+ int qop_state;
+
+ dprintk("GSS_VERIFY_MIC\n");
+
+ print_krb5_gss_ctx_id_rec(contextid->internal_ctx_id);
+
+ dprintk("VERIFY MIC calling kg_unseal\n");
+
+ maj_stat = kg_unseal(contextid, checksum,signbuf,
+ NULL, &qop_state, KG_TOK_MIC_MSG);
+ if (!maj_stat && qop_state)
+ *qstate = qop_state;
+
+ dprintk("VERIFY MIC returning err %d\n", maj_stat);
+ return maj_stat;
+}
+
+u32
+gss_get_mic_kerberos(GSS_CTX_ID_T contextid,
+ u32 qop,
+ GSS_BUFFER_T *message_buffer,
+ GSS_BUFFER_T *message_token) {
+ u32 err = 0,i;
+ unsigned char *pp;
+
+ dprintk("GSS_GETMIC\n");
+
+ print_krb5_gss_ctx_id_rec(contextid->internal_ctx_id);
+
+ if (!message_buffer->data) return -EINVAL;
+
+ dprintk("GSS_GETMIC: message_buffer->len %d\n",message_buffer->len);
+ pp = message_buffer->data;
+ for(i=0;i<message_buffer->len;i++)
+ dprintk("%02x",*pp++);
+ dprintk("\n");
+
+ dprintk("GETMIC calling kg_seal\n");
+ err = kg_seal(contextid, 0, qop, message_buffer, NULL,
+ message_token, KG_TOK_SIGN_MSG);
+
+ dprintk("GETMIC kg_seal return: %d \n",err);
+
+ return err;
+}
+
+static struct gss_api_ops gss_kerberos_ops = {
+ .name = "krb5",
+ NULL,
+ .gss_import_sec_context = gss_import_sec_context_kerberos,
+ .gss_get_mic = gss_get_mic_kerberos,
+ .gss_verify_mic = gss_verify_mic_kerberos,
+ .gss_delete_sec_context = gss_delete_sec_context_generic,
+};
+
+/* XXX error checking? reference counting? */
+static int __init init_kerberos_module(void)
+{
+ struct gss_api_mech *gm;
+
+ if (gss_mech_register(&gss_mech_krb5_oid, &gss_kerberos_ops))
+ printk("Failed to register kerberos gss mechanism!\n");
+ gm = gss_mech_get_by_OID(&gss_mech_krb5_oid);
+ gss_register_triple(RPC_AUTH_GSS_KRB5 , gm, 0, RPC_GSS_SVC_NONE);
+ gss_mech_put(gm);
+ return 0;
+}
+
+static void __exit cleanup_kerberos_module(void)
+{
+ gss_unregister_triple(RPC_AUTH_GSS_KRB5);
+}
+
+MODULE_LICENSE("GPL");
+module_init(init_kerberos_module);
+module_exit(cleanup_kerberos_module);
diff -u --recursive --new-file linux-2.5.45-07-auth_upcall2/net/sunrpc/gss_krb5_seal.c linux-2.5.45-08-krb5/net/sunrpc/gss_krb5_seal.c
--- linux-2.5.45-07-auth_upcall2/net/sunrpc/gss_krb5_seal.c 1969-12-31 19:00:00.000000000 -0500
+++ linux-2.5.45-08-krb5/net/sunrpc/gss_krb5_seal.c 2002-10-31 15:53:25.000000000 -0500
@@ -0,0 +1,366 @@
+/*
+ * linux/net/sunrpc/gss_krb5_seal.c
+ *
+ * Adapted from MIT Kerberos 5-1.2.1 lib/gssapi/krb5/k5seal.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.
+ */
+
+/*
+ * Copyright (C) 1998 by the FundsXpress, INC.
+ *
+ * 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 FundsXpress. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. FundsXpress makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/sunrpc/gss_krb5_types.h>
+#include <linux/random.h>
+
+#ifdef RPC_DEBUG
+# define RPCDBG_FACILITY RPCDBG_AUTH
+#endif
+
+
+
+static s32
+make_seal_token_v1(krb5_keyblock * enc,
+ krb5_keyblock * seq,
+ s32 * seqnum,
+ int direction,
+ GSS_BUFFER_T * text,
+ GSS_BUFFER_T * token,
+ int signalg,
+ int cksum_size,
+ int sealalg,
+ int encrypt, int toktype, int bigend, GSS_OID * oid)
+{
+ s32 code = 0;
+ size_t sumlen;
+ char *data_ptr;
+ krb5_data plaind;
+ krb5_checksum md5cksum;
+ krb5_checksum cksum;
+ int conflen = 0, tmsglen, tlen;
+ unsigned char *t, *ptr;
+ int encblksize, sumblksize;
+
+ /* will eventually add support for other algorithms */
+ dprintk("RPC: gss_krb5_seal");
+ switch (signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ sumblksize = 1;
+ break;
+ default:
+ dprintk("RPC: gss_krb5_seal: bad signalg %d\n", signalg);
+ return KG_BAD_SIGN_TYPE;
+ }
+ dprintk("RPC: gss_k5seal: sealalg %d\n", sealalg);
+ switch (sealalg) {
+ case SEAL_ALG_NONE:
+ case SEAL_ALG_DES:
+ encblksize = 8;
+ break;
+ default:
+ dprintk("RPC: gss_krb5_seal: bad sealalg %d\n", sealalg);
+ return KG_BAD_SIGN_TYPE;
+ }
+
+ /* create the token buffer */
+
+ if (toktype == KG_TOK_SEAL_MSG) {
+ if (bigend && !encrypt) {
+ tmsglen = text->len;
+ } else {
+ code = k5_get_blocksize(enc->enctype, &conflen);
+ if (code)
+ return code;
+ /* XXX knows that des block size is 8 */
+ tmsglen = (conflen + text->len + 8) & (~7);
+ dprintk("RPC:make_seal_token_v1: tmsglen: %d \n",
+ tmsglen);
+ }
+ } else {
+ tmsglen = 0;
+ }
+
+ tlen = g_token_size((GSS_OID *) oid, 14 + cksum_size + tmsglen);
+
+ if ((t = (unsigned char *) rpc_allocate(0, tlen)) == NULL)
+ return GSS_S_FAILURE;
+
+ /*** fill in the token */
+
+ ptr = t;
+
+ g_make_token_header((GSS_OID *) oid, 14 + cksum_size + tmsglen,
+ &ptr, toktype);
+ /* 0..1 SIGN_ALG */
+
+ ptr[0] = signalg & 0xff;
+ ptr[1] = (signalg >> 8) & 0xff;
+
+ /* 2..3 SEAL_ALG or Filler */
+
+ if ((toktype == KG_TOK_SEAL_MSG) && encrypt) {
+ ptr[2] = sealalg & 0xff;
+ ptr[3] = (sealalg >> 8) & 0xff;
+ } else {
+ /* No seal */
+ ptr[2] = 0xff;
+ ptr[3] = 0xff;
+ }
+
+ ptr[4] = 0xff;
+ ptr[5] = 0xff;
+
+ /* pad the plaintext, encrypt if needed, and stick it in the token */
+
+ /* initialize the the cksum */
+ switch (signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ md5cksum.checksum_type = CKSUMTYPE_RSA_MD5;
+ break;
+ default:
+ return KG_BAD_SIGN_TYPE;
+ }
+
+ if ((code = k5_get_checksum_length(md5cksum.checksum_type, &sumlen)))
+ return code;
+ md5cksum.length = sumlen;
+
+ if (toktype == KG_TOK_SEAL_MSG) {
+ unsigned char *plain;
+ unsigned char pad;
+
+ if (!bigend || encrypt) {
+ if ((plain =
+ (unsigned char *) rpc_allocate(0,
+ tmsglen)) ==
+ NULL) {
+ rpc_free(t);
+ return GSS_S_FAILURE;
+ }
+ get_random_bytes(plain, conflen); /* "confounder" */
+ memcpy(plain + conflen, text->data, text->len);
+
+ /* XXX 8 is DES cblock size */
+ pad = 8 - (text->len % 8);
+
+ memset(plain + conflen + text->len, pad, pad);
+ } else {
+ /* plain is never used in the bigend && !encrypt case */
+ plain = NULL;
+ }
+
+ if (encrypt) {
+ if ((code = gss_k5encrypt(enc, KG_USAGE_SEAL,
+ NULL,
+ plain,
+ ptr + cksum_size + 14,
+ tmsglen))) {
+ if (plain)
+ rpc_free(plain);
+ rpc_free(t);
+ return code;
+ }
+ } else {
+ if (bigend)
+ memcpy(ptr + 14 + cksum_size, text->data,
+ text->len);
+ else
+ memcpy(ptr + 14 + cksum_size, plain,
+ tmsglen);
+ }
+
+ /* compute the checksum */
+
+ /* 8 = head of token body as specified by mech spec */
+ if (!(data_ptr = (char *) rpc_allocate(0,
+ 8 + (bigend ? text->len: tmsglen)))) {
+ if (plain)
+ rpc_free(plain);
+ rpc_free(t);
+ return GSS_S_FAILURE;
+ }
+ memcpy(data_ptr, ptr - 2, 8);
+ if (bigend)
+ memcpy(data_ptr + 8, text->data, text->len);
+ else
+ memcpy(data_ptr + 8, plain, tmsglen);
+ plaind.length = 8 + (bigend ? text->len : tmsglen);
+ plaind.data = data_ptr;
+ code = krb5_c_make_checksum(md5cksum.checksum_type, seq,
+ KG_USAGE_SIGN, &plaind, &md5cksum);
+ rpc_free(data_ptr);
+
+ if (code) {
+ if (plain)
+ rpc_free(plain);
+ rpc_free(t);
+ return code;
+ }
+
+ if (plain)
+ rpc_free(plain);
+ } else {
+ /* Sign only. */
+ /* compute the checksum */
+
+ if (!(data_ptr = (char *) rpc_allocate(0, 8 + text->len))) {
+ rpc_free(t);
+ return GSS_S_FAILURE;
+ }
+ memcpy(data_ptr, ptr - 2, 8);
+ memcpy(data_ptr + 8, text->data, text->len);
+ plaind.length = 8 + text->len;
+ plaind.data = data_ptr;
+ code = krb5_c_make_checksum(md5cksum.checksum_type, seq,
+ KG_USAGE_SIGN, &plaind, &md5cksum);
+ rpc_free(data_ptr);
+ if (code) {
+ rpc_free(t);
+ return code;
+ }
+ }
+
+ switch (signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ dprintk("RPC: make_seal_token:SGN_ALG_DES_MAC_MD5:"
+ " calling gss_k5encrypt CBC MAC\n");
+ if ((code = gss_k5encrypt(seq, KG_USAGE_SEAL,
+ NULL,
+ md5cksum.contents,
+ md5cksum.contents, 16))) {
+ dprintk("make_seal_token: gss_k5encrypt FAILED"
+ " returns code %d\n", code);
+ rpc_free(md5cksum.contents);
+ rpc_free(t);
+ return code;
+ }
+ dprintk("RPC: make_seal_token: gss_k5encrypt returns"
+ " %d OUTPUT:\n", code);
+ print_hexl((u32 *) md5cksum.contents, 16, 0);
+
+ cksum.length = cksum_size;
+ cksum.contents = md5cksum.contents + 16 - cksum.length;
+ memcpy(ptr + 14, cksum.contents, cksum.length);
+
+ dprintk("make_seal_token: ptr with cksum data: \n");
+ print_hexl((u32 *) ptr, 14 + 8, 0);
+ break;
+ default:
+ return KG_BAD_SIGN_TYPE;
+ }
+
+ rpc_free(md5cksum.contents);
+
+ /* create the seq_num */
+
+ dprintk("RPC: make_seal_token: calling kg_make_seq_num\n");
+ if ((code = kg_make_seq_num(seq, direction ? 0 : 0xff, *seqnum,
+ ptr + 14, ptr + 6))) {
+ rpc_free(t);
+ return code;
+ }
+ dprintk("RPC: make_seal_token: kg_make_seq_num returns %d\n",
+ code);
+
+ /* that's it. return the token */
+ (*seqnum)++;
+ token->len = tlen;
+ token->data = (void *) t;
+
+#if 0
+ dprintk("RPC: kg_seal: DONE! token:\n");
+ print_hexl((u32 *) token->data, token->len, 0);
+#endif
+
+ return GSS_S_COMPLETE;
+}
+
+/* if signonly is true, ignore conf_req, conf_state,
+ and do not encode the ENC_TYPE, MSG_LENGTH, or MSG_TEXT fields */
+
+/* NOTE: caller validates the context_handle*/
+u32
+kg_seal(GSS_CTX_ID_T context_handle,
+ int encrypt,
+ int qop_req,
+ GSS_BUFFER_T * input_message_buffer,
+ int *conf_state, GSS_BUFFER_T * output_message_buffer, int toktype)
+{
+ krb5_gss_ctx_id_rec *ctx = context_handle->internal_ctx_id;
+ s32 code;
+ s32 now;
+
+ output_message_buffer->len = 0;
+ output_message_buffer->data = NULL;
+
+ if (qop_req != 0)
+ return GSS_S_FAILURE;
+
+ now = jiffies;
+
+ code = make_seal_token_v1(ctx->enc, ctx->seq,
+ &ctx->seq_send, ctx->initiate,
+ input_message_buffer,
+ output_message_buffer, ctx->signalg,
+ ctx->cksum_size, ctx->sealalg,
+ encrypt, toktype, ctx->big_endian,
+ ctx->mech_used);
+
+ if (code)
+ return (GSS_S_FAILURE);
+
+ if (conf_state)
+ *conf_state = encrypt;
+
+ return ((ctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE);
+}
diff -u --recursive --new-file linux-2.5.45-07-auth_upcall2/net/sunrpc/gss_krb5_seqnum.c linux-2.5.45-08-krb5/net/sunrpc/gss_krb5_seqnum.c
--- linux-2.5.45-07-auth_upcall2/net/sunrpc/gss_krb5_seqnum.c 1969-12-31 19:00:00.000000000 -0500
+++ linux-2.5.45-08-krb5/net/sunrpc/gss_krb5_seqnum.c 2002-10-31 15:45:11.000000000 -0500
@@ -0,0 +1,91 @@
+/*
+ * linux/net/sunrpc/gss_krb5_seqnum.c
+ *
+ * Adapted from MIT Kerberos 5-1.2.1 lib/gssapi/krb5/util_seqnum.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.
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/sunrpc/gss_krb5_types.h>
+
+#ifdef RPC_DEBUG
+# define RPCDBG_FACILITY RPCDBG_AUTH
+#endif
+
+
+s32
+kg_make_seq_num(krb5_keyblock * key,
+ int direction,
+ s32 seqnum,
+ unsigned char *cksum, unsigned char *buf)
+{
+ unsigned char plain[8];
+
+ plain[0] = (unsigned char) (seqnum & 0xff);
+ plain[1] = (unsigned char) ((seqnum >> 8) & 0xff);
+ plain[2] = (unsigned char) ((seqnum >> 16) & 0xff);
+ plain[3] = (unsigned char) ((seqnum >> 24) & 0xff);
+
+ plain[4] = direction;
+ plain[5] = direction;
+ plain[6] = direction;
+ plain[7] = direction;
+
+ return (gss_k5encrypt(key, KG_USAGE_SEQ, cksum, plain, buf, 8));
+}
+
+s32 kg_get_seq_num(krb5_keyblock * key,
+ unsigned char *cksum,
+ unsigned char *buf,
+ int *direction, s32 * seqnum)
+{
+ s32 code;
+ unsigned char plain[8];
+
+ dprintk("kg_get_seq_num: \n");
+
+ if ((code =
+ gss_k5decrypt(key, KG_USAGE_SEQ, cksum, buf, plain, 8))) {
+ printk("kg_get_seq_num: gss_k5decrypt failed with return: %d\n",
+ code);
+ return (code);
+ }
+
+ if ((plain[4] != plain[5]) || (plain[4] != plain[6])
+ || (plain[4] != plain[7]))
+ return ((s32) KG_BAD_SEQ);
+
+ *direction = plain[4];
+
+ *seqnum = ((plain[0]) |
+ (plain[1] << 8) | (plain[2] << 16) | (plain[3] << 24));
+
+ return (0);
+}
diff -u --recursive --new-file linux-2.5.45-07-auth_upcall2/net/sunrpc/gss_krb5_unseal.c linux-2.5.45-08-krb5/net/sunrpc/gss_krb5_unseal.c
--- linux-2.5.45-07-auth_upcall2/net/sunrpc/gss_krb5_unseal.c 1969-12-31 19:00:00.000000000 -0500
+++ linux-2.5.45-08-krb5/net/sunrpc/gss_krb5_unseal.c 2002-10-31 15:53:42.000000000 -0500
@@ -0,0 +1,374 @@
+/*
+ * linux/net/sunrpc/gss_krb5_unseal.c
+ *
+ * Adapted from MIT Kerberos 5-1.2.1 lib/gssapi/krb5/k5unseal.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.
+ */
+
+/*
+ * Copyright (C) 1998 by the FundsXpress, INC.
+ *
+ * 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 FundsXpress. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. FundsXpress makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/sunrpc/gss_krb5_types.h>
+
+
+#ifdef RPC_DEBUG
+# define RPCDBG_FACILITY RPCDBG_AUTH
+#endif
+
+
+/* message_buffer is an input if SIGN, output if SEAL, and ignored if DEL_CTX
+ conf_state is only valid if SEAL. */
+
+u32
+kg_unseal_v1(krb5_gss_ctx_id_rec * ctx,
+ unsigned char *ptr,
+ int bodysize,
+ GSS_BUFFER_T * message_buffer,
+ int *conf_state, int *qop_state, int toktype)
+{
+ s32 code;
+ int tmsglen = 0;
+ int conflen = 0;
+ int signalg;
+ int sealalg;
+ GSS_BUFFER_T token;
+ krb5_checksum cksum;
+ krb5_checksum md5cksum;
+ krb5_data plaind;
+ char *data_ptr;
+ s32 now;
+ unsigned char *plain = NULL;
+ int cksum_len = 0;
+ int plainlen = 0;
+ int direction;
+ s32 seqnum;
+ size_t sumlen;
+
+ dprintk("RPC: kg_unseal_v1\n");
+ if (toktype == KG_TOK_SEAL_MSG) {
+ message_buffer->len = 0;
+ message_buffer->data = NULL;
+ }
+
+ /* get the sign and seal algorithms */
+
+ signalg = ptr[0] + (ptr[1] << 8);
+ sealalg = ptr[2] + (ptr[3] << 8);
+
+ /* Sanity checks */
+
+ if ((ptr[4] != 0xff) || (ptr[5] != 0xff))
+ return GSS_S_DEFECTIVE_TOKEN;
+
+ if ((toktype != KG_TOK_SEAL_MSG) && (sealalg != 0xffff))
+ return GSS_S_DEFECTIVE_TOKEN;
+
+ /* in the current spec, there is only one valid seal algorithm per
+ key type, so a simple comparison is ok */
+
+ if ((toktype == KG_TOK_SEAL_MSG) &&
+ !((sealalg == 0xffff) || (sealalg == ctx->sealalg)))
+ return GSS_S_DEFECTIVE_TOKEN;
+ /* there are several mappings of seal algorithms to sign algorithms,
+ but few enough that we can try them all. */
+
+ if ((ctx->sealalg == SEAL_ALG_NONE && signalg > 1) ||
+ (ctx->sealalg == SEAL_ALG_1 && signalg != SGN_ALG_3) ||
+ (ctx->sealalg == SEAL_ALG_DES3KD &&
+ signalg != SGN_ALG_HMAC_SHA1_DES3_KD))
+ return GSS_S_DEFECTIVE_TOKEN;
+
+ /* starting with a single alg */
+ switch (signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ cksum_len = 8;
+ break;
+ default:
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
+
+ if (toktype == KG_TOK_SEAL_MSG)
+ tmsglen = bodysize - (14 + cksum_len);
+
+ /* get the token parameters */
+
+ /* decode the message, if SEAL */
+
+ if (toktype == KG_TOK_SEAL_MSG) {
+ dprintk("RPC: kg_unseal_v1 KG_TOK_SEAL_MSG\n");
+
+
+ if (sealalg != 0xffff) {
+ plain = (unsigned char *) rpc_allocate(0, tmsglen);
+ if (plain == NULL)
+ return (GSS_S_FAILURE);
+
+ code = gss_k5decrypt(ctx->enc, KG_USAGE_SEAL, NULL,
+ ptr + 14 + cksum_len, plain,
+ tmsglen);
+ if (code) {
+ rpc_free(plain);
+ return (GSS_S_FAILURE);
+ }
+ } else {
+ plain = ptr + 14 + cksum_len;
+ }
+
+ plainlen = tmsglen;
+
+ if ((sealalg == 0xffff) && ctx->big_endian) {
+ token.len = tmsglen;
+ } else {
+ code =
+ k5_get_blocksize(ctx->enc->enctype, &conflen);
+ if (code)
+ return code;
+ token.len = tmsglen - conflen - plain[tmsglen - 1];
+ }
+
+ if (token.len) {
+ token.data = (void *) rpc_allocate(0, token.len);
+ if (token.data == NULL) {
+ if (sealalg != 0xffff)
+ rpc_free(plain);
+ return (GSS_S_FAILURE);
+ }
+ memcpy(token.data, plain + conflen, token.len);
+ }
+
+ } else if (toktype == KG_TOK_SIGN_MSG) {
+ dprintk("RPC: kg_unseal_v1 KG_TOK_SIGN_MSG\n");
+ token = *message_buffer;
+ plain = token.data;
+ plainlen = token.len;
+ } else {
+ token.len = 0;
+ token.data = NULL;
+ plain = token.data;
+ plainlen = token.len;
+ }
+
+ dprintk("RPC kg_unseal_v1: token.len %d plainlen %d\n", token.len,
+ plainlen);
+
+ /* compute the checksum of the message */
+
+ /* initialize the the cksum */
+ switch (signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ md5cksum.checksum_type = CKSUMTYPE_RSA_MD5;
+ break;
+ default:
+ return (GSS_S_DEFECTIVE_TOKEN);
+ }
+
+ if ((code =
+ k5_get_checksum_length(md5cksum.checksum_type, &sumlen)))
+ return (code);
+ md5cksum.length = sumlen;
+
+ switch (signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ dprintk("RPC kg_unseal_v1 SGN_ALG_DES_MAC_MD5\n");
+ /* compute the checksum of the message.
+ * 8 = bytes of token body to be checksummed according to spec
+ */
+
+ data_ptr = (void *) rpc_allocate(0, 8 + (ctx->big_endian ? token.len : plainlen));
+ if (!data_ptr) {
+ if (sealalg != 0xffff)
+ rpc_free(plain);
+ if (toktype == KG_TOK_SEAL_MSG)
+ rpc_free(token.data);
+ return (GSS_S_FAILURE);
+ }
+
+ memcpy(data_ptr, ptr - 2, 8);
+ if (ctx->big_endian)
+ memcpy(data_ptr + 8, token.data, token.len);
+ else
+ memcpy(data_ptr + 8, plain, plainlen);
+
+ plaind.length = 8 + (ctx->big_endian ? token.len : plainlen);
+ plaind.data = data_ptr;
+
+ dprintk
+ ("RPC:kg_unseal calling make_checksum with PLAIN TEXT\n");
+ print_hexl((u32 *) plaind.data, plaind.length, 0);
+
+ code = krb5_c_make_checksum(md5cksum.checksum_type,
+ ctx->seq, KG_USAGE_SIGN,
+ &plaind, &md5cksum);
+
+ rpc_free(data_ptr);
+
+ if (code) {
+ if (toktype == KG_TOK_SEAL_MSG)
+ rpc_free(token.data);
+ return (GSS_S_FAILURE);
+ }
+
+ code = gss_k5encrypt(ctx->seq, KG_USAGE_SEAL, NULL,
+ md5cksum.contents,
+ md5cksum.contents, 16);
+ if (code) {
+ rpc_free(md5cksum.contents);
+ if (toktype == KG_TOK_SEAL_MSG)
+ rpc_free(token.data);
+ return GSS_S_FAILURE;
+ }
+
+
+ if (signalg == 0)
+ cksum.length = 8;
+ else
+ cksum.length = 16;
+ cksum.contents = md5cksum.contents + 16 - cksum.length;
+
+ dprintk
+ ("RPC: kg_unseal_v1: memcmp digest cksum.length %d:\n",
+ cksum.length);
+ dprintk(" md5cksum.contents\n");
+ print_hexl((u32 *) md5cksum.contents, 16, 0);
+ dprintk(" cksum.contents:\n");
+ print_hexl((u32 *) cksum.contents, cksum.length, 0);
+ {
+ u32 *p;
+
+ (u8 *) p = ptr + 14;
+ dprintk(" ptr+14:\n");
+ print_hexl(p, cksum.length, 0);
+ }
+
+ code = memcmp(cksum.contents, ptr + 14, cksum.length);
+ break;
+ default:
+ return (GSS_S_DEFECTIVE_TOKEN);
+ }
+
+ rpc_free(md5cksum.contents);
+ if (sealalg != 0xffff)
+ rpc_free(plain);
+
+ /* compare the computed checksum against the transmitted checksum */
+
+ if (code) {
+ if (toktype == KG_TOK_SEAL_MSG)
+ rpc_free(token.data);
+ return (GSS_S_BAD_SIG);
+ }
+
+ /* it got through unscathed. Make sure the context is unexpired */
+
+ if (toktype == KG_TOK_SEAL_MSG)
+ *message_buffer = token;
+
+ if (conf_state)
+ *conf_state = (sealalg != 0xffff);
+
+ if (qop_state)
+ *qop_state = GSS_C_QOP_DEFAULT;
+
+ now = jiffies;
+
+ if (now > ctx->endtime) {
+ return (GSS_S_CONTEXT_EXPIRED);
+ }
+
+ /* do sequencing checks */
+
+ if ((code = kg_get_seq_num(ctx->seq, ptr + 14, ptr + 6, &direction,
+ &seqnum))) {
+ if (toktype == KG_TOK_SEAL_MSG)
+ rpc_free(token.data);
+ return (GSS_S_BAD_SIG);
+ }
+
+ if ((ctx->initiate && direction != 0xff) ||
+ (!ctx->initiate && direction != 0)) {
+ if (toktype == KG_TOK_SEAL_MSG)
+ rpc_free(token.data);
+ return (GSS_S_BAD_SIG);
+ }
+
+ return (GSS_S_COMPLETE);
+}
+
+/* message_buffer is an input if SIGN, output if SEAL, and ignored if DEL_CTX
+ conf_state is only valid if SEAL. */
+
+u32
+kg_unseal(GSS_CTX_ID_T context_handle,
+ GSS_BUFFER_T * input_token_buffer,
+ GSS_BUFFER_T * message_buffer,
+ int *conf_state, int *qop_state, int toktype)
+{
+ krb5_gss_ctx_id_rec *ctx = context_handle->internal_ctx_id;
+ unsigned char *ptr;
+ int bodysize;
+ int err;
+
+ ptr = (unsigned char *) input_token_buffer->data;
+
+ /* parse the token, leave the data in message_buffer, setting conf_state */
+ if ((err = g_verify_token_header((GSS_OID *) ctx->mech_used,
+ &bodysize, &ptr, toktype,
+ input_token_buffer->len)) != 0)
+ return (GSS_S_DEFECTIVE_TOKEN);
+ err = kg_unseal_v1(ctx, ptr, bodysize,
+ message_buffer, conf_state, qop_state, toktype);
+ dprintk("kg_unseal_v1 returned %d\n", err);
+ return (err);
+}
-------------------------------------------------------
This sf.net email is sponsored by: Influence the future
of Java(TM) technology. Join the Java Community
Process(SM) (JCP(SM)) program now.
http://ads.sourceforge.net/cgi-bin/redirect.pl?sunm0004en
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs