1/*
2 * Copyright (c) 2007-2013 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29#ifndef _NFS_NFS_GSS_H_
30#define _NFS_NFS_GSS_H_
31
32#include <gssd/gssd_mach.h>
33#include <sys/param.h>
34#include <nfs/nfs_ioctl.h>
35#include <libkern/crypto/des.h>
36
37#define RPCSEC_GSS			6
38#define	RPCSEC_GSS_VERS_1		1
39
40enum rpcsec_gss_proc {
41	RPCSEC_GSS_DATA			= 0,
42	RPCSEC_GSS_INIT			= 1,
43	RPCSEC_GSS_CONTINUE_INIT	= 2,
44	RPCSEC_GSS_DESTROY		= 3
45};
46
47enum rpcsec_gss_service {
48	RPCSEC_GSS_SVC_NONE		= 1,	// sec=krb5
49	RPCSEC_GSS_SVC_INTEGRITY	= 2,	// sec=krb5i
50	RPCSEC_GSS_SVC_PRIVACY		= 3,	// sec=krb5p
51	RPCSEC_GSS_SVC_SYS		= 4	// sec=sys (fallback)
52};
53
54/* encoded krb5 OID */
55extern u_char krb5_mech[11];
56
57/*
58 * GSS-API things
59 */
60typedef uint32_t OM_uint32;
61
62#define GSS_S_COMPLETE			0
63#define GSS_S_CONTINUE_NEEDED		1
64
65/*
66 * Some "helper" definitions to make the status code macros obvious.
67 * From gssapi.h:
68 */
69#define GSS_C_CALLING_ERROR_OFFSET 24
70#define GSS_C_ROUTINE_ERROR_OFFSET 16
71#define GSS_C_SUPPLEMENTARY_OFFSET 0
72#define GSS_C_CALLING_ERROR_MASK ((OM_uint32) 0377ul)
73#define GSS_C_ROUTINE_ERROR_MASK ((OM_uint32) 0377ul)
74#define GSS_C_SUPPLEMENTARY_MASK ((OM_uint32) 0177777ul)
75
76/*
77 * The macros that test status codes for error conditions.  Note that the
78 * GSS_ERROR() macro has changed slightly from the V1 GSSAPI so that it now
79 * evaluates its argument only once.
80 */
81#define GSS_CALLING_ERROR(x) \
82	((x) & (GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET))
83#define GSS_ROUTINE_ERROR(x) \
84	((x) & (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET))
85#define GSS_SUPPLEMENTARY_INFO(x) \
86	((x) & (GSS_C_SUPPLEMENTARY_MASK << GSS_C_SUPPLEMENTARY_OFFSET))
87#define GSS_ERROR(x) \
88	((x) & ((GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET) | \
89		(GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET)))
90
91#define GSS_MAXSEQ			0x80000000	// The biggest sequence number
92#define GSS_SVC_MAXCONTEXTS		500000		// Max contexts supported
93#define GSS_SVC_SEQWINDOW		256		// Server's sequence window
94#define GSS_CLNT_SEQLISTMAX		32		// Max length of req seq num list
95#define GSS_CLNT_SYS_VALID		300		// Valid time (sec) for failover ctx
96
97#define SKEYLEN	8			// length of DES key
98#define SKEYLEN3 24			// length of DES3 keyboard
99#define MAX_SKEYLEN	SKEYLEN3
100
101typedef struct {
102	uint32_t type; 		// See defines below
103	uint32_t keybytes; 	// Session key length bytes;
104	uint32_t hash_len;
105	u_char   skey[MAX_SKEYLEN];	   	// Session key;
106	union {
107		struct {
108			des_cblock  *key;
109			des_cbc_key_schedule gss_sched;
110			des_cbc_key_schedule gss_sched_Ke;
111		} des;
112		struct {
113			des_cblock		(*key)[3];
114			des_cblock		ckey[3];
115			des3_cbc_key_schedule	gss_sched;
116		} des3;
117	} ks_u;
118} gss_key_info;
119
120#define NFS_GSS_0DES	0 // Not DES or uninitialized
121#define NFS_GSS_1DES	1 // Single DES with DES_MAC_MD5
122#define NFS_GSS_3DES	2 // Triple EDE DES KD with SHA1
123
124/*
125 * The client's RPCSEC_GSS context information
126 */
127struct nfs_gss_clnt_ctx {
128	lck_mtx_t		*gss_clnt_mtx;
129	thread_t		gss_clnt_thread;	// Thread creating context
130	TAILQ_ENTRY(nfs_gss_clnt_ctx)	gss_clnt_entries;
131	uint32_t		gss_clnt_flags;		// Flag bits - see below
132	uint32_t		gss_clnt_refcnt;	// Reference count
133	kauth_cred_t		gss_clnt_cred;		// Owner of this context
134	uint8_t			*gss_clnt_principal;	// Principal to use for this credential
135	uint32_t		gss_clnt_prinlen;	// Length of principal
136	gssd_nametype		gss_clnt_prinnt;	// Name type of principal
137	char			*gss_clnt_display;	// display name of principal
138	uint32_t		gss_clnt_proc;		// Current GSS proc for cred
139	uint32_t		gss_clnt_seqnum;	// GSS sequence number
140	uint32_t		gss_clnt_service;	// Indicates krb5, krb5i or krb5p
141	uint8_t			*gss_clnt_handle;	// Identifies server context
142	uint32_t		gss_clnt_handle_len;	// Size of server's ctx handle
143	time_t			gss_clnt_ctime;		// When context was created
144	uint32_t		gss_clnt_seqwin;	// Server's seq num window
145	uint32_t		*gss_clnt_seqbits;	// Bitmap to track seq numbers in use
146	mach_port_t		gss_clnt_mport;		// Mach port for gssd upcall
147	uint8_t			*gss_clnt_verf;		// RPC verifier from server
148	uint8_t			*gss_clnt_svcname;	// Service name e.g. "nfs/big.apple.com"
149	uint32_t		gss_clnt_svcnamlen;	// Service name length
150	gssd_nametype		gss_clnt_svcnt;		// Service name type
151	gssd_cred		gss_clnt_cred_handle;	// Opaque cred handle from gssd
152	gssd_ctx		gss_clnt_context;	// Opaque context handle from gssd
153	uint8_t			*gss_clnt_token;	// GSS token exchanged via gssd & server
154	uint32_t		gss_clnt_tokenlen;	// Length of token
155	gss_key_info		gss_clnt_kinfo;		// GSS key info
156	uint32_t		gss_clnt_gssd_flags;	// Special flag bits to gssd
157	uint32_t		gss_clnt_major;		// GSS major result from gssd or server
158	uint32_t		gss_clnt_minor;		// GSS minor result from gssd or server
159};
160
161/*
162 * gss_clnt_flags
163 */
164#define GSS_CTX_COMPLETE	0x00000001	// Context is complete
165#define GSS_CTX_INVAL		0x00000002	// Context is invalid
166#define GSS_CTX_INCOMPLETE	0x00000004	// Context needs to be inited
167#define GSS_NEEDSEQ		0x00000008	// Need a sequence number
168#define GSS_NEEDCTX		0x00000010	// Need the context
169
170/*
171 * The server's RPCSEC_GSS context information
172 */
173struct nfs_gss_svc_ctx {
174	lck_mtx_t		*gss_svc_mtx;
175	LIST_ENTRY(nfs_gss_svc_ctx)	gss_svc_entries;
176	uint32_t		gss_svc_handle;		// Identifies server context to client
177	uint32_t		gss_svc_refcnt;		// Reference count
178	uint32_t		gss_svc_proc;		// Current GSS proc from cred
179	uid_t			gss_svc_uid;		// UID of this user
180	gid_t			gss_svc_gids[NGROUPS];	// GIDs of this user
181	uint32_t		gss_svc_ngroups;	// Count of gids
182	uint64_t		gss_svc_incarnation;	// Delete ctx if we exceed this + ttl value
183	uint32_t		gss_svc_seqmax;		// Current max GSS sequence number
184	uint32_t		gss_svc_seqwin;		// GSS sequence number window
185	uint32_t		*gss_svc_seqbits;	// Bitmap to track seq numbers
186	gssd_cred		gss_svc_cred_handle;	// Opaque cred handle from gssd
187	gssd_ctx		gss_svc_context;	// Opaque context handle from gssd
188	u_char			*gss_svc_token;		// GSS token exchanged via gssd & client
189	uint32_t		gss_svc_tokenlen;	// Length of token
190	gss_key_info		gss_svc_kinfo;		// Session key info
191	uint32_t		gss_svc_major;		// GSS major result from gssd
192	uint32_t		gss_svc_minor;		// GSS minor result from gssd
193};
194
195#define SVC_CTX_HASHSZ	64
196#define SVC_CTX_HASH(handle)	((handle) % SVC_CTX_HASHSZ)
197LIST_HEAD(nfs_gss_svc_ctx_hashhead, nfs_gss_svc_ctx);
198
199/*
200 * Macros to manipulate bits in the sequence window
201 */
202#define win_getbit(bits, bit)      ((bits[(bit) / 32] &   (1 << (bit) % 32)) != 0)
203#define win_setbit(bits, bit)   do { bits[(bit) / 32] |=  (1 << (bit) % 32); } while (0)
204#define win_resetbit(bits, bit) do { bits[(bit) / 32] &= ~(1 << (bit) % 32); } while (0)
205
206/*
207 * Server context stale times
208 */
209#define GSS_CTX_PEND		5 		// seconds
210#define GSS_CTX_EXPIRE		(8 * 3600)	// seconds
211#define GSS_CTX_TTL_MIN		1		// seconds
212#define GSS_TIMER_PERIOD	300		// seconds
213#define MSECS_PER_SEC		1000
214
215__BEGIN_DECLS
216
217void	nfs_gss_init(void);
218int	nfs_gss_clnt_cred_put(struct nfsreq *, struct nfsm_chain *, mbuf_t);
219int	nfs_gss_clnt_verf_get(struct nfsreq *, struct nfsm_chain *,
220		uint32_t, uint32_t, uint32_t *);
221void	nfs_gss_clnt_rpcdone(struct nfsreq *);
222int	nfs_gss_clnt_args_restore(struct nfsreq *);
223int	nfs_gss_clnt_ctx_renew(struct nfsreq *);
224void	nfs_gss_clnt_ctx_ref(struct nfsreq *, struct nfs_gss_clnt_ctx *);
225void	nfs_gss_clnt_ctx_unref(struct nfsreq *);
226void	nfs_gss_clnt_ctx_unmount(struct nfsmount *);
227int	nfs_gss_clnt_ctx_destroy(struct nfsmount *, kauth_cred_t cred);
228int	nfs_gss_svc_cred_get(struct nfsrv_descript *, struct nfsm_chain *);
229int	nfs_gss_svc_verf_put(struct nfsrv_descript *, struct nfsm_chain *);
230int	nfs_gss_svc_ctx_init(struct nfsrv_descript *, struct nfsrv_sock *, mbuf_t *);
231int	nfs_gss_svc_prepare_reply(struct nfsrv_descript *, struct nfsm_chain *);
232int	nfs_gss_svc_protect_reply(struct nfsrv_descript *, mbuf_t);
233void	nfs_gss_svc_ctx_deref(struct nfs_gss_svc_ctx *);
234void	nfs_gss_svc_cleanup(void);
235
236__END_DECLS
237#endif /* _NFS_NFS_GSS_H_ */
238