X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/39236c6e673c41db228275375ab7fdb0f837b292..ea3f04195ba4a5034c9c8e9b726d4f7ce96f1832:/bsd/nfs/nfs_gss.h?ds=inline diff --git a/bsd/nfs/nfs_gss.h b/bsd/nfs/nfs_gss.h index 7c7b245dd..302489486 100644 --- a/bsd/nfs/nfs_gss.h +++ b/bsd/nfs/nfs_gss.h @@ -1,8 +1,8 @@ /* - * Copyright (c) 2007-2013 Apple Inc. All rights reserved. + * Copyright (c) 2007-2015 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -11,10 +11,10 @@ * unlawful or unlicensed copies of an Apple operating system, or to * circumvent, violate, or enable the circumvention or violation of, any * terms of an Apple operating system software license agreement. - * + * * Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -22,178 +22,141 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ #ifndef _NFS_NFS_GSS_H_ #define _NFS_NFS_GSS_H_ +#include "gss/gss_krb5_mech.h" #include #include #include -#include -#define RPCSEC_GSS 6 -#define RPCSEC_GSS_VERS_1 1 +#define RPCSEC_GSS 6 +#define RPCSEC_GSS_VERS_1 1 enum rpcsec_gss_proc { - RPCSEC_GSS_DATA = 0, - RPCSEC_GSS_INIT = 1, - RPCSEC_GSS_CONTINUE_INIT = 2, - RPCSEC_GSS_DESTROY = 3 + RPCSEC_GSS_DATA = 0, + RPCSEC_GSS_INIT = 1, + RPCSEC_GSS_CONTINUE_INIT = 2, + RPCSEC_GSS_DESTROY = 3 }; enum rpcsec_gss_service { - RPCSEC_GSS_SVC_NONE = 1, // sec=krb5 - RPCSEC_GSS_SVC_INTEGRITY = 2, // sec=krb5i - RPCSEC_GSS_SVC_PRIVACY = 3, // sec=krb5p - RPCSEC_GSS_SVC_SYS = 4 // sec=sys (fallback) + RPCSEC_GSS_SVC_NONE = 1, // sec=krb5 + RPCSEC_GSS_SVC_INTEGRITY = 2, // sec=krb5i + RPCSEC_GSS_SVC_PRIVACY = 3, // sec=krb5p }; /* encoded krb5 OID */ -extern u_char krb5_mech[11]; +extern u_char krb5_mech_oid[11]; + /* - * GSS-API things + * RFC 2203 and friends don't define maximums for token lengths + * and context handles. We try to pick reasonable values here. + * + * N.B. Kerberos mech tokens can be quite large from the output + * of a gss_init_sec_context if it includes a large PAC. */ -typedef uint32_t OM_uint32; -#define GSS_S_COMPLETE 0 -#define GSS_S_CONTINUE_NEEDED 1 +#define GSS_MAX_CTX_HANDLE_LEN 256 +#define GSS_MAX_TOKEN_LEN 64*1024 /* - * Some "helper" definitions to make the status code macros obvious. - * From gssapi.h: + * Put a "reasonble" bound on MIC lengths */ -#define GSS_C_CALLING_ERROR_OFFSET 24 -#define GSS_C_ROUTINE_ERROR_OFFSET 16 -#define GSS_C_SUPPLEMENTARY_OFFSET 0 -#define GSS_C_CALLING_ERROR_MASK ((OM_uint32) 0377ul) -#define GSS_C_ROUTINE_ERROR_MASK ((OM_uint32) 0377ul) -#define GSS_C_SUPPLEMENTARY_MASK ((OM_uint32) 0177777ul) +#define GSS_MAX_MIC_LEN 2048 -/* - * The macros that test status codes for error conditions. Note that the - * GSS_ERROR() macro has changed slightly from the V1 GSSAPI so that it now - * evaluates its argument only once. - */ -#define GSS_CALLING_ERROR(x) \ - ((x) & (GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET)) -#define GSS_ROUTINE_ERROR(x) \ - ((x) & (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET)) -#define GSS_SUPPLEMENTARY_INFO(x) \ - ((x) & (GSS_C_SUPPLEMENTARY_MASK << GSS_C_SUPPLEMENTARY_OFFSET)) -#define GSS_ERROR(x) \ - ((x) & ((GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET) | \ - (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET))) - -#define GSS_MAXSEQ 0x80000000 // The biggest sequence number -#define GSS_SVC_MAXCONTEXTS 500000 // Max contexts supported -#define GSS_SVC_SEQWINDOW 256 // Server's sequence window -#define GSS_CLNT_SEQLISTMAX 32 // Max length of req seq num list -#define GSS_CLNT_SYS_VALID 300 // Valid time (sec) for failover ctx - -#define SKEYLEN 8 // length of DES key -#define SKEYLEN3 24 // length of DES3 keyboard -#define MAX_SKEYLEN SKEYLEN3 - -typedef struct { - uint32_t type; // See defines below - uint32_t keybytes; // Session key length bytes; - uint32_t hash_len; - u_char skey[MAX_SKEYLEN]; // Session key; - union { - struct { - des_cblock *key; - des_cbc_key_schedule gss_sched; - des_cbc_key_schedule gss_sched_Ke; - } des; - struct { - des_cblock (*key)[3]; - des_cblock ckey[3]; - des3_cbc_key_schedule gss_sched; - } des3; - } ks_u; -} gss_key_info; - -#define NFS_GSS_0DES 0 // Not DES or uninitialized -#define NFS_GSS_1DES 1 // Single DES with DES_MAC_MD5 -#define NFS_GSS_3DES 2 // Triple EDE DES KD with SHA1 +#define GSS_MAXSEQ 0x80000000 // The biggest sequence number +#define GSS_SVC_MAXCONTEXTS 500000 // Max contexts supported +#define GSS_SVC_SEQWINDOW 256 // Server's sequence window +#define GSS_CLNT_SEQLISTMAX 32 // Max length of req seq num list + +#define MAX_SKEYLEN 32 +#define MAX_LUCIDLEN (sizeof (lucid_context) + MAX_SKEYLEN) +#define GSS_MAX_NEG_CACHE_ENTRIES 16 +#define GSS_NEG_CACHE_TO 3 +#define GSS_PRINT_DELAY (8 * 3600) // Wait day before printing the same error message /* * The client's RPCSEC_GSS context information */ struct nfs_gss_clnt_ctx { - lck_mtx_t *gss_clnt_mtx; - thread_t gss_clnt_thread; // Thread creating context - TAILQ_ENTRY(nfs_gss_clnt_ctx) gss_clnt_entries; - uint32_t gss_clnt_flags; // Flag bits - see below - uint32_t gss_clnt_refcnt; // Reference count - kauth_cred_t gss_clnt_cred; // Owner of this context - uint8_t *gss_clnt_principal; // Principal to use for this credential - uint32_t gss_clnt_prinlen; // Length of principal - gssd_nametype gss_clnt_prinnt; // Name type of principal - char *gss_clnt_display; // display name of principal - uint32_t gss_clnt_proc; // Current GSS proc for cred - uint32_t gss_clnt_seqnum; // GSS sequence number - uint32_t gss_clnt_service; // Indicates krb5, krb5i or krb5p - uint8_t *gss_clnt_handle; // Identifies server context - uint32_t gss_clnt_handle_len; // Size of server's ctx handle - time_t gss_clnt_ctime; // When context was created - uint32_t gss_clnt_seqwin; // Server's seq num window - uint32_t *gss_clnt_seqbits; // Bitmap to track seq numbers in use - mach_port_t gss_clnt_mport; // Mach port for gssd upcall - uint8_t *gss_clnt_verf; // RPC verifier from server - uint8_t *gss_clnt_svcname; // Service name e.g. "nfs/big.apple.com" - uint32_t gss_clnt_svcnamlen; // Service name length - gssd_nametype gss_clnt_svcnt; // Service name type - gssd_cred gss_clnt_cred_handle; // Opaque cred handle from gssd - gssd_ctx gss_clnt_context; // Opaque context handle from gssd - uint8_t *gss_clnt_token; // GSS token exchanged via gssd & server - uint32_t gss_clnt_tokenlen; // Length of token - gss_key_info gss_clnt_kinfo; // GSS key info - uint32_t gss_clnt_gssd_flags; // Special flag bits to gssd - uint32_t gss_clnt_major; // GSS major result from gssd or server - uint32_t gss_clnt_minor; // GSS minor result from gssd or server + lck_mtx_t *gss_clnt_mtx; + thread_t gss_clnt_thread; // Thread creating context + TAILQ_ENTRY(nfs_gss_clnt_ctx) gss_clnt_entries; + uint32_t gss_clnt_flags; // Flag bits - see below + int32_t gss_clnt_refcnt; // Reference count + kauth_cred_t gss_clnt_cred; // Owner of this context + uint8_t *gss_clnt_principal; // Principal to use for this credential + uint32_t gss_clnt_prinlen; // Length of principal + gssd_nametype gss_clnt_prinnt; // Name type of principal + char *gss_clnt_display; // display name of principal + uint32_t gss_clnt_proc; // Current GSS proc for cred + uint32_t gss_clnt_seqnum; // GSS sequence number + uint32_t gss_clnt_service; // Indicates krb5, krb5i or krb5p + uint8_t *gss_clnt_handle; // Identifies server context + uint32_t gss_clnt_handle_len; // Size of server's ctx handle + time_t gss_clnt_nctime; // When context was put in the negative cache + uint32_t gss_clnt_seqwin; // Server's seq num window + uint32_t *gss_clnt_seqbits; // Bitmap to track seq numbers in use + mach_port_t gss_clnt_mport; // Mach port for gssd upcall + uint32_t gss_clnt_verflen; // RPC verifier length from server + uint8_t *gss_clnt_verf; // RPC verifier from server + uint8_t *gss_clnt_svcname; // Service name e.g. "nfs/big.apple.com" + uint32_t gss_clnt_svcnamlen; // Service name length + gssd_nametype gss_clnt_svcnt; // Service name type + gssd_cred gss_clnt_cred_handle; // Opaque cred handle from gssd + gssd_ctx gss_clnt_context; // Opaque context handle from gssd + gss_ctx_id_t gss_clnt_ctx_id; // Underlying gss context + uint8_t *gss_clnt_token; // GSS token exchanged via gssd & server + uint32_t gss_clnt_tokenlen; // Length of token + uint32_t gss_clnt_gssd_flags; // Special flag bits to gssd + uint32_t gss_clnt_major; // GSS major result from gssd or server + uint32_t gss_clnt_minor; // GSS minor result from gssd or server + time_t gss_clnt_ptime; // When last error message was printed }; /* * gss_clnt_flags */ -#define GSS_CTX_COMPLETE 0x00000001 // Context is complete -#define GSS_CTX_INVAL 0x00000002 // Context is invalid -#define GSS_CTX_INCOMPLETE 0x00000004 // Context needs to be inited -#define GSS_NEEDSEQ 0x00000008 // Need a sequence number -#define GSS_NEEDCTX 0x00000010 // Need the context +#define GSS_CTX_COMPLETE 0x00000001 // Context is complete +#define GSS_CTX_INVAL 0x00000002 // Context is invalid +#define GSS_CTX_STICKY 0x00000004 // Context has been set by user +#define GSS_NEEDSEQ 0x00000008 // Need a sequence number +#define GSS_NEEDCTX 0x00000010 // Need the context +#define GSS_CTX_DESTROY 0x00000020 // Context is being destroyed, don't cache /* * The server's RPCSEC_GSS context information */ struct nfs_gss_svc_ctx { - lck_mtx_t *gss_svc_mtx; - LIST_ENTRY(nfs_gss_svc_ctx) gss_svc_entries; - uint32_t gss_svc_handle; // Identifies server context to client - uint32_t gss_svc_refcnt; // Reference count - uint32_t gss_svc_proc; // Current GSS proc from cred - uid_t gss_svc_uid; // UID of this user - gid_t gss_svc_gids[NGROUPS]; // GIDs of this user - uint32_t gss_svc_ngroups; // Count of gids - uint64_t gss_svc_incarnation; // Delete ctx if we exceed this + ttl value - uint32_t gss_svc_seqmax; // Current max GSS sequence number - uint32_t gss_svc_seqwin; // GSS sequence number window - uint32_t *gss_svc_seqbits; // Bitmap to track seq numbers - gssd_cred gss_svc_cred_handle; // Opaque cred handle from gssd - gssd_ctx gss_svc_context; // Opaque context handle from gssd - u_char *gss_svc_token; // GSS token exchanged via gssd & client - uint32_t gss_svc_tokenlen; // Length of token - gss_key_info gss_svc_kinfo; // Session key info - uint32_t gss_svc_major; // GSS major result from gssd - uint32_t gss_svc_minor; // GSS minor result from gssd + lck_mtx_t *gss_svc_mtx; + LIST_ENTRY(nfs_gss_svc_ctx) gss_svc_entries; + uint32_t gss_svc_handle; // Identifies server context to client + uint32_t gss_svc_refcnt; // Reference count + uint32_t gss_svc_proc; // Current GSS proc from cred + uid_t gss_svc_uid; // UID of this user + gid_t gss_svc_gids[NGROUPS]; // GIDs of this user + uint32_t gss_svc_ngroups; // Count of gids + uint64_t gss_svc_incarnation; // Delete ctx if we exceed this + ttl value + uint32_t gss_svc_seqmax; // Current max GSS sequence number + uint32_t gss_svc_seqwin; // GSS sequence number window + uint32_t *gss_svc_seqbits; // Bitmap to track seq numbers + gssd_cred gss_svc_cred_handle; // Opaque cred handle from gssd + gssd_ctx gss_svc_context; // Opaque context handle from gssd + gss_ctx_id_t gss_svc_ctx_id; // Underlying gss context + u_char *gss_svc_token; // GSS token exchanged via gssd & client + uint32_t gss_svc_tokenlen; // Length of token + uint32_t gss_svc_major; // GSS major result from gssd + uint32_t gss_svc_minor; // GSS minor result from gssd }; -#define SVC_CTX_HASHSZ 64 -#define SVC_CTX_HASH(handle) ((handle) % SVC_CTX_HASHSZ) +#define SVC_CTX_HASHSZ 64 +#define SVC_CTX_HASH(handle) ((handle) % SVC_CTX_HASHSZ) LIST_HEAD(nfs_gss_svc_ctx_hashhead, nfs_gss_svc_ctx); /* @@ -206,32 +169,40 @@ LIST_HEAD(nfs_gss_svc_ctx_hashhead, nfs_gss_svc_ctx); /* * Server context stale times */ -#define GSS_CTX_PEND 5 // seconds -#define GSS_CTX_EXPIRE (8 * 3600) // seconds -#define GSS_CTX_TTL_MIN 1 // seconds -#define GSS_TIMER_PERIOD 300 // seconds -#define MSECS_PER_SEC 1000 +#define GSS_CTX_PEND 5 // seconds +#define GSS_CTX_EXPIRE (8 * 3600) // seconds +#define GSS_CTX_TTL_MIN 1 // seconds +#define GSS_TIMER_PERIOD 300 // seconds +#define MSECS_PER_SEC 1000 + +#define auth_is_kerberized(auth) \ + (auth == RPCAUTH_KRB5 || \ + auth == RPCAUTH_KRB5I || \ + auth == RPCAUTH_KRB5P) __BEGIN_DECLS -void nfs_gss_init(void); -int nfs_gss_clnt_cred_put(struct nfsreq *, struct nfsm_chain *, mbuf_t); -int nfs_gss_clnt_verf_get(struct nfsreq *, struct nfsm_chain *, - uint32_t, uint32_t, uint32_t *); -void nfs_gss_clnt_rpcdone(struct nfsreq *); -int nfs_gss_clnt_args_restore(struct nfsreq *); -int nfs_gss_clnt_ctx_renew(struct nfsreq *); -void nfs_gss_clnt_ctx_ref(struct nfsreq *, struct nfs_gss_clnt_ctx *); -void nfs_gss_clnt_ctx_unref(struct nfsreq *); -void nfs_gss_clnt_ctx_unmount(struct nfsmount *); -int nfs_gss_clnt_ctx_destroy(struct nfsmount *, kauth_cred_t cred); -int nfs_gss_svc_cred_get(struct nfsrv_descript *, struct nfsm_chain *); -int nfs_gss_svc_verf_put(struct nfsrv_descript *, struct nfsm_chain *); -int nfs_gss_svc_ctx_init(struct nfsrv_descript *, struct nfsrv_sock *, mbuf_t *); -int nfs_gss_svc_prepare_reply(struct nfsrv_descript *, struct nfsm_chain *); -int nfs_gss_svc_protect_reply(struct nfsrv_descript *, mbuf_t); -void nfs_gss_svc_ctx_deref(struct nfs_gss_svc_ctx *); -void nfs_gss_svc_cleanup(void); +void nfs_gss_init(void); +uid_t nfs_cred_getasid2uid(kauth_cred_t); +int nfs_gss_clnt_cred_put(struct nfsreq *, struct nfsm_chain *, mbuf_t); +int nfs_gss_clnt_verf_get(struct nfsreq *, struct nfsm_chain *, + uint32_t, uint32_t, uint32_t *); +void nfs_gss_clnt_rpcdone(struct nfsreq *); +int nfs_gss_clnt_args_restore(struct nfsreq *); +int nfs_gss_clnt_ctx_renew(struct nfsreq *); +void nfs_gss_clnt_ctx_ref(struct nfsreq *, struct nfs_gss_clnt_ctx *); +void nfs_gss_clnt_ctx_unref(struct nfsreq *); +void nfs_gss_clnt_ctx_unmount(struct nfsmount *); +int nfs_gss_clnt_ctx_remove(struct nfsmount *, kauth_cred_t); +int nfs_gss_clnt_ctx_set_principal(struct nfsmount *, vfs_context_t, uint8_t *, uint32_t, uint32_t); +int nfs_gss_clnt_ctx_get_principal(struct nfsmount *, vfs_context_t, struct user_nfs_gss_principal *); +int nfs_gss_svc_cred_get(struct nfsrv_descript *, struct nfsm_chain *); +int nfs_gss_svc_verf_put(struct nfsrv_descript *, struct nfsm_chain *); +int nfs_gss_svc_ctx_init(struct nfsrv_descript *, struct nfsrv_sock *, mbuf_t *); +int nfs_gss_svc_prepare_reply(struct nfsrv_descript *, struct nfsm_chain *); +int nfs_gss_svc_protect_reply(struct nfsrv_descript *, mbuf_t); +void nfs_gss_svc_ctx_deref(struct nfs_gss_svc_ctx *); +void nfs_gss_svc_cleanup(void); __END_DECLS #endif /* _NFS_NFS_GSS_H_ */