| Author | Tokens | Token Proportion | Commits | Commit Proportion |
|---|---|---|---|---|
| Chuck Lever | 618 | 40.50% | 26 | 44.83% |
| Trond Myklebust | 446 | 29.23% | 8 | 13.79% |
| Kevin Coffman | 222 | 14.55% | 6 | 10.34% |
| J. Bruce Fields | 76 | 4.98% | 5 | 8.62% |
| Andrew Morton | 66 | 4.33% | 3 | 5.17% |
| Zhipeng Lu | 29 | 1.90% | 1 | 1.72% |
| Arnd Bergmann | 16 | 1.05% | 1 | 1.72% |
| Simo Sorce | 15 | 0.98% | 1 | 1.72% |
| Paul Burton | 11 | 0.72% | 1 | 1.72% |
| Usha Ketineni | 9 | 0.59% | 1 | 1.72% |
| Jeff Layton | 6 | 0.39% | 1 | 1.72% |
| Breno Leitão | 5 | 0.33% | 1 | 1.72% |
| Herbert Xu | 3 | 0.20% | 1 | 1.72% |
| Dave Wysochanski | 3 | 0.20% | 1 | 1.72% |
| Kees Cook | 1 | 0.07% | 1 | 1.72% |
| Total | 1526 | 58 |
// SPDX-License-Identifier: BSD-3-Clause /* * linux/net/sunrpc/gss_krb5_mech.c * * Copyright (c) 2001-2008 The Regents of the University of Michigan. * All rights reserved. * * Andy Adamson <andros@umich.edu> * J. Bruce Fields <bfields@umich.edu> */ #include <linux/err.h> #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.h> #include <linux/sunrpc/xdr.h> #include "auth_gss_internal.h" #include "gss_krb5_internal.h" #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) # define RPCDBG_FACILITY RPCDBG_AUTH #endif static struct gss_api_mech gss_kerberos_mech; /* * Candidate enctypes in order of most preferred to least. * Each is probed against crypto/krb5 at module init; only * enctypes that crypto/krb5 supports are advertised. */ static const u32 gss_krb5_enctypes[] = { KRB5_ENCTYPE_AES256_CTS_HMAC_SHA384_192, KRB5_ENCTYPE_AES128_CTS_HMAC_SHA256_128, KRB5_ENCTYPE_CAMELLIA256_CTS_CMAC, KRB5_ENCTYPE_CAMELLIA128_CTS_CMAC, KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96, KRB5_ENCTYPE_AES128_CTS_HMAC_SHA1_96, }; static char gss_krb5_enctype_priority_list[64]; static void gss_krb5_prepare_enctype_priority_list(void) { size_t total, i; char buf[16]; char *sep; int n; sep = ""; gss_krb5_enctype_priority_list[0] = '\0'; for (total = 0, i = 0; i < ARRAY_SIZE(gss_krb5_enctypes); i++) { if (!crypto_krb5_find_enctype(gss_krb5_enctypes[i])) continue; n = sprintf(buf, "%s%u", sep, gss_krb5_enctypes[i]); if (n < 0) break; if (total + n >= sizeof(gss_krb5_enctype_priority_list)) break; strcat(gss_krb5_enctype_priority_list, buf); sep = ","; total += n; } } static int gss_krb5_import_ctx_v2(struct krb5_ctx *ctx, gfp_t gfp_mask) { struct krb5_buffer TK = { .len = ctx->krb5e->key_len, .data = ctx->Ksess, }; int ret; ctx->initiator_enc_aead = crypto_krb5_prepare_encryption(ctx->krb5e, &TK, KG_USAGE_INITIATOR_SEAL, gfp_mask); if (IS_ERR(ctx->initiator_enc_aead)) { ret = PTR_ERR(ctx->initiator_enc_aead); goto out_free; } ctx->acceptor_enc_aead = crypto_krb5_prepare_encryption(ctx->krb5e, &TK, KG_USAGE_ACCEPTOR_SEAL, gfp_mask); if (IS_ERR(ctx->acceptor_enc_aead)) { ret = PTR_ERR(ctx->acceptor_enc_aead); goto out_free; } ctx->initiator_sign_shash = crypto_krb5_prepare_checksum(ctx->krb5e, &TK, KG_USAGE_INITIATOR_SIGN, gfp_mask); if (IS_ERR(ctx->initiator_sign_shash)) { ret = PTR_ERR(ctx->initiator_sign_shash); goto out_free; } ctx->acceptor_sign_shash = crypto_krb5_prepare_checksum(ctx->krb5e, &TK, KG_USAGE_ACCEPTOR_SIGN, gfp_mask); if (IS_ERR(ctx->acceptor_sign_shash)) { ret = PTR_ERR(ctx->acceptor_sign_shash); goto out_free; } return 0; out_free: crypto_free_shash(ctx->acceptor_sign_shash); crypto_free_shash(ctx->initiator_sign_shash); crypto_free_aead(ctx->acceptor_enc_aead); crypto_free_aead(ctx->initiator_enc_aead); return ret; } static int gss_import_v2_context(const void *p, const void *end, struct krb5_ctx *ctx, gfp_t gfp_mask) { u64 seq_send64; int keylen; u32 time32; int ret; p = simple_get_bytes(p, end, &ctx->flags, sizeof(ctx->flags)); if (IS_ERR(p)) goto out_err; ctx->initiate = ctx->flags & KRB5_CTX_FLAG_INITIATOR; p = simple_get_bytes(p, end, &time32, sizeof(time32)); if (IS_ERR(p)) goto out_err; /* unsigned 32-bit time overflows in year 2106 */ ctx->endtime = (time64_t)time32; p = simple_get_bytes(p, end, &seq_send64, sizeof(seq_send64)); if (IS_ERR(p)) goto out_err; atomic64_set(&ctx->seq_send64, seq_send64); p = simple_get_bytes(p, end, &ctx->enctype, sizeof(ctx->enctype)); if (IS_ERR(p)) goto out_err; ctx->krb5e = crypto_krb5_find_enctype(ctx->enctype); if (!ctx->krb5e) { dprintk("gss_kerberos_mech: unsupported krb5 enctype %u\n", ctx->enctype); p = ERR_PTR(-EINVAL); goto out_err; } keylen = ctx->krb5e->key_len; p = simple_get_bytes(p, end, ctx->Ksess, keylen); if (IS_ERR(p)) goto out_err; if (p != end) { p = ERR_PTR(-EINVAL); goto out_err; } ctx->mech_used.data = kmemdup(gss_kerberos_mech.gm_oid.data, gss_kerberos_mech.gm_oid.len, gfp_mask); if (unlikely(ctx->mech_used.data == NULL)) { p = ERR_PTR(-ENOMEM); goto out_err; } ctx->mech_used.len = gss_kerberos_mech.gm_oid.len; ret = gss_krb5_import_ctx_v2(ctx, gfp_mask); if (ret) { p = ERR_PTR(ret); goto out_free; } return 0; out_free: kfree(ctx->mech_used.data); out_err: return PTR_ERR(p); } static int gss_krb5_import_sec_context(const void *p, size_t len, struct gss_ctx *ctx_id, time64_t *endtime, gfp_t gfp_mask) { const void *end = (const void *)((const char *)p + len); struct krb5_ctx *ctx; int ret; ctx = kzalloc_obj(*ctx, gfp_mask); if (ctx == NULL) return -ENOMEM; ret = gss_import_v2_context(p, end, ctx, gfp_mask); memzero_explicit(&ctx->Ksess, sizeof(ctx->Ksess)); if (ret) { kfree(ctx); return ret; } ctx_id->internal_ctx_id = ctx; if (endtime) *endtime = ctx->endtime; return 0; } static void gss_krb5_delete_sec_context(void *internal_ctx) { struct krb5_ctx *kctx = internal_ctx; crypto_free_shash(kctx->acceptor_sign_shash); crypto_free_shash(kctx->initiator_sign_shash); crypto_free_aead(kctx->acceptor_enc_aead); crypto_free_aead(kctx->initiator_enc_aead); kfree(kctx->mech_used.data); kfree(kctx); } /** * gss_krb5_errno_to_status - Map a negative errno to a GSS major status * @err: negative errno value, or zero * * Returns: * %GSS_S_COMPLETE if @err is zero * %GSS_S_BAD_SIG if @err is -EBADMSG (integrity check failure) * %GSS_S_DEFECTIVE_TOKEN if @err is -EPROTO (malformed token) * %GSS_S_FAILURE for all other negative values */ u32 gss_krb5_errno_to_status(int err) { switch (err) { case 0: return GSS_S_COMPLETE; case -EBADMSG: return GSS_S_BAD_SIG; case -EPROTO: return GSS_S_DEFECTIVE_TOKEN; default: return GSS_S_FAILURE; } } /** * gss_krb5_get_mic - get_mic for the Kerberos GSS mechanism * @gctx: GSS context * @text: plaintext to checksum * @token: buffer into which to write the computed checksum * * Return values: * %GSS_S_COMPLETE - success, and @token is filled in * %GSS_S_FAILURE - checksum could not be generated * %GSS_S_CONTEXT_EXPIRED - Kerberos context is no longer valid */ static u32 gss_krb5_get_mic(struct gss_ctx *gctx, struct xdr_buf *text, struct xdr_netobj *token) { struct krb5_ctx *kctx = gctx->internal_ctx_id; return gss_krb5_get_mic_v2(kctx, text, token); } /** * gss_krb5_verify_mic - verify_mic for the Kerberos GSS mechanism * @gctx: GSS context * @message_buffer: plaintext to check * @read_token: received checksum to check * * Return values: * %GSS_S_COMPLETE - computed and received checksums match * %GSS_S_DEFECTIVE_TOKEN - received checksum is not valid * %GSS_S_BAD_SIG - computed and received checksums do not match * %GSS_S_FAILURE - received checksum could not be checked * %GSS_S_CONTEXT_EXPIRED - Kerberos context is no longer valid */ static u32 gss_krb5_verify_mic(struct gss_ctx *gctx, struct xdr_buf *message_buffer, struct xdr_netobj *read_token) { struct krb5_ctx *kctx = gctx->internal_ctx_id; return gss_krb5_verify_mic_v2(kctx, message_buffer, read_token); } /** * gss_krb5_wrap - gss_wrap for the Kerberos GSS mechanism * @gctx: initialized GSS context * @offset: byte offset in @buf to start writing the cipher text * @buf: OUT: send buffer * @pages: plaintext to wrap * * Return values: * %GSS_S_COMPLETE - success, @buf has been updated * %GSS_S_FAILURE - @buf could not be wrapped * %GSS_S_CONTEXT_EXPIRED - Kerberos context is no longer valid */ static u32 gss_krb5_wrap(struct gss_ctx *gctx, int offset, struct xdr_buf *buf, struct page **pages) { struct krb5_ctx *kctx = gctx->internal_ctx_id; return gss_krb5_wrap_v2(kctx, offset, buf, pages); } /** * gss_krb5_unwrap - gss_unwrap for the Kerberos GSS mechanism * @gctx: initialized GSS context * @offset: starting byte offset into @buf * @len: size of ciphertext to unwrap * @buf: ciphertext to unwrap * * Return values: * %GSS_S_COMPLETE - success, @buf has been updated * %GSS_S_DEFECTIVE_TOKEN - received blob is not valid * %GSS_S_BAD_SIG - computed and received checksums do not match * %GSS_S_FAILURE - @buf could not be unwrapped * %GSS_S_CONTEXT_EXPIRED - Kerberos context is no longer valid */ static u32 gss_krb5_unwrap(struct gss_ctx *gctx, int offset, int len, struct xdr_buf *buf) { struct krb5_ctx *kctx = gctx->internal_ctx_id; return gss_krb5_unwrap_v2(kctx, offset, len, buf, &gctx->slack, &gctx->align); } static const struct gss_api_ops gss_kerberos_ops = { .gss_import_sec_context = gss_krb5_import_sec_context, .gss_get_mic = gss_krb5_get_mic, .gss_verify_mic = gss_krb5_verify_mic, .gss_wrap = gss_krb5_wrap, .gss_unwrap = gss_krb5_unwrap, .gss_delete_sec_context = gss_krb5_delete_sec_context, }; static struct pf_desc gss_kerberos_pfs[] = { [0] = { .pseudoflavor = RPC_AUTH_GSS_KRB5, .qop = GSS_C_QOP_DEFAULT, .service = RPC_GSS_SVC_NONE, .name = "krb5", }, [1] = { .pseudoflavor = RPC_AUTH_GSS_KRB5I, .qop = GSS_C_QOP_DEFAULT, .service = RPC_GSS_SVC_INTEGRITY, .name = "krb5i", .datatouch = true, }, [2] = { .pseudoflavor = RPC_AUTH_GSS_KRB5P, .qop = GSS_C_QOP_DEFAULT, .service = RPC_GSS_SVC_PRIVACY, .name = "krb5p", .datatouch = true, }, }; MODULE_ALIAS("rpc-auth-gss-krb5"); MODULE_ALIAS("rpc-auth-gss-krb5i"); MODULE_ALIAS("rpc-auth-gss-krb5p"); MODULE_ALIAS("rpc-auth-gss-390003"); MODULE_ALIAS("rpc-auth-gss-390004"); MODULE_ALIAS("rpc-auth-gss-390005"); MODULE_ALIAS("rpc-auth-gss-1.2.840.113554.1.2.2"); static struct gss_api_mech gss_kerberos_mech = { .gm_name = "krb5", .gm_owner = THIS_MODULE, .gm_oid = { 9, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02" }, .gm_ops = &gss_kerberos_ops, .gm_pf_num = ARRAY_SIZE(gss_kerberos_pfs), .gm_pfs = gss_kerberos_pfs, .gm_upcall_enctypes = gss_krb5_enctype_priority_list, }; static int __init init_kerberos_module(void) { int status; gss_krb5_prepare_enctype_priority_list(); status = gss_mech_register(&gss_kerberos_mech); if (status) printk("Failed to register kerberos gss mechanism!\n"); return status; } static void __exit cleanup_kerberos_module(void) { gss_mech_unregister(&gss_kerberos_mech); } MODULE_DESCRIPTION("Sun RPC Kerberos 5 module"); MODULE_LICENSE("GPL"); module_init(init_kerberos_module); module_exit(cleanup_kerberos_module);
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with Cregit http://github.com/cregit/cregit
Version 2.0-RC1