xref: /xnu-8020.121.3/bsd/nfs/nfs_gss.h (revision fdd8201d7b966f0c3ea610489d29bd841d358941)
1 /*
2  * Copyright (c) 2007-2015 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 "gss/gss_krb5_mech.h"
33 #include <gssd/gssd_mach.h>
34 #include <sys/param.h>
35 #include <nfs/nfs_ioctl.h>
36 
37 #define RPCSEC_GSS                      6
38 #define RPCSEC_GSS_VERS_1               1
39 
40 enum 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 
47 enum 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 };
52 
53 /* encoded krb5 OID */
54 extern u_char krb5_mech_oid[11];
55 
56 
57 /*
58  * RFC 2203 and friends don't define maximums for token lengths
59  * and context handles. We try to pick reasonable values here.
60  *
61  * N.B. Kerberos mech tokens can be quite large from the output
62  * of a gss_init_sec_context if it includes a large PAC.
63  */
64 
65 #define GSS_MAX_CTX_HANDLE_LEN          256
66 #define GSS_MAX_TOKEN_LEN               64*1024
67 
68 /*
69  * Put a "reasonble" bound on MIC lengths
70  */
71 #define GSS_MAX_MIC_LEN                 2048
72 
73 #define GSS_MAXSEQ                      0x80000000      // The biggest sequence number
74 #define GSS_SVC_MAXCONTEXTS             500000          // Max contexts supported
75 #define GSS_SVC_SEQWINDOW               256             // Server's sequence window
76 #define GSS_CLNT_SEQLISTMAX             32              // Max length of req seq num list
77 
78 #define MAX_SKEYLEN     32
79 #define MAX_LUCIDLEN    (sizeof (lucid_context) + MAX_SKEYLEN)
80 #define GSS_MAX_NEG_CACHE_ENTRIES 16
81 #define GSS_NEG_CACHE_TO 3
82 #define GSS_PRINT_DELAY  (8 * 3600)     // Wait day before printing the same error message
83 
84 /*
85  * The client's RPCSEC_GSS context information
86  */
87 struct nfs_gss_clnt_ctx {
88 	lck_mtx_t               gss_clnt_mtx;
89 	thread_t                gss_clnt_thread;        // Thread creating context
90 	TAILQ_ENTRY(nfs_gss_clnt_ctx)   gss_clnt_entries;
91 	uint32_t                gss_clnt_flags;         // Flag bits - see below
92 	int32_t                 gss_clnt_refcnt;        // Reference count
93 	kauth_cred_t            gss_clnt_cred;          // Owner of this context
94 	uint8_t                 *gss_clnt_principal;    // Principal to use for this credential
95 	size_t                  gss_clnt_prinlen;       // Length of principal
96 	gssd_nametype           gss_clnt_prinnt;        // Name type of principal
97 	char                    *gss_clnt_display;      // display name of principal
98 	uint32_t                gss_clnt_proc;          // Current GSS proc for cred
99 	uint32_t                gss_clnt_seqnum;        // GSS sequence number
100 	uint32_t                gss_clnt_service;       // Indicates krb5, krb5i or krb5p
101 	uint8_t                 *gss_clnt_handle;       // Identifies server context
102 	uint32_t                gss_clnt_handle_len;    // Size of server's ctx handle
103 	time_t                  gss_clnt_nctime;        // When context was put in the negative cache
104 	uint32_t                gss_clnt_seqwin;        // Server's seq num window
105 	uint32_t                *gss_clnt_seqbits;      // Bitmap to track seq numbers in use
106 	mach_port_t             gss_clnt_mport;         // Mach port for gssd upcall
107 	uint32_t                gss_clnt_verflen;       // RPC verifier length from server
108 	uint8_t                 *gss_clnt_verf;         // RPC verifier from server
109 	uint8_t                 *gss_clnt_svcname;      // Service name e.g. "nfs/big.apple.com"
110 	size_t                  gss_clnt_svcnamlen;     // Service name length
111 	gssd_nametype           gss_clnt_svcnt;         // Service name type
112 	gssd_cred               gss_clnt_cred_handle;   // Opaque cred handle from gssd
113 	gssd_ctx                gss_clnt_context;       // Opaque context handle from gssd
114 	gss_ctx_id_t            gss_clnt_ctx_id;        // Underlying gss context
115 	uint8_t                 *gss_clnt_token;        // GSS token exchanged via gssd & server
116 	uint32_t                gss_clnt_tokenlen;      // Length of token
117 	uint32_t                gss_clnt_gssd_flags;    // Special flag bits to gssd
118 	uint32_t                gss_clnt_major;         // GSS major result from gssd or server
119 	uint32_t                gss_clnt_minor;         // GSS minor result from gssd or server
120 	time_t                  gss_clnt_ptime;         // When last error message was printed
121 };
122 
123 /*
124  * gss_clnt_flags
125  */
126 #define GSS_CTX_COMPLETE        0x00000001      // Context is complete
127 #define GSS_CTX_INVAL           0x00000002      // Context is invalid
128 #define GSS_CTX_STICKY          0x00000004      // Context has been set by user
129 #define GSS_NEEDSEQ             0x00000008      // Need a sequence number
130 #define GSS_NEEDCTX             0x00000010      // Need the context
131 #define GSS_CTX_DESTROY         0x00000020      // Context is being destroyed, don't cache
132 #define GSS_CTX_USECOUNT        0x00000040      // Mount vnode's user count has been updated
133 
134 /*
135  * The server's RPCSEC_GSS context information
136  */
137 struct nfs_gss_svc_ctx {
138 	lck_mtx_t               gss_svc_mtx;
139 	LIST_ENTRY(nfs_gss_svc_ctx)     gss_svc_entries;
140 	uint32_t                gss_svc_handle;         // Identifies server context to client
141 	uint32_t                gss_svc_refcnt;         // Reference count
142 	uint32_t                gss_svc_proc;           // Current GSS proc from cred
143 	uid_t                   gss_svc_uid;            // UID of this user
144 	gid_t                   gss_svc_gids[NGROUPS];  // GIDs of this user
145 	uint32_t                gss_svc_ngroups;        // Count of gids
146 	uint64_t                gss_svc_incarnation;    // Delete ctx if we exceed this + ttl value
147 	uint32_t                gss_svc_seqmax;         // Current max GSS sequence number
148 	uint32_t                gss_svc_seqwin;         // GSS sequence number window
149 	uint32_t                *gss_svc_seqbits;       // Bitmap to track seq numbers
150 	gssd_cred               gss_svc_cred_handle;    // Opaque cred handle from gssd
151 	gssd_ctx                gss_svc_context;        // Opaque context handle from gssd
152 	gss_ctx_id_t            gss_svc_ctx_id;         // Underlying gss context
153 	u_char                  *gss_svc_token;         // GSS token exchanged via gssd & client
154 	uint32_t                gss_svc_tokenlen;       // Length of token
155 	uint32_t                gss_svc_major;          // GSS major result from gssd
156 	uint32_t                gss_svc_minor;          // GSS minor result from gssd
157 };
158 
159 #define SVC_CTX_HASHSZ  64
160 #define SVC_CTX_HASH(handle)    ((handle) % SVC_CTX_HASHSZ)
161 LIST_HEAD(nfs_gss_svc_ctx_hashhead, nfs_gss_svc_ctx);
162 
163 /*
164  * Macros to manipulate bits in the sequence window
165  */
166 #define win_getbit(bits, bit)      ((bits[(bit) / 32] &   (1 << (bit) % 32)) != 0)
167 #define win_setbit(bits, bit)   do { bits[(bit) / 32] |=  (1 << (bit) % 32); } while (0)
168 #define win_resetbit(bits, bit) do { bits[(bit) / 32] &= ~(1 << (bit) % 32); } while (0)
169 
170 /*
171  * Server context stale times
172  */
173 #define GSS_CTX_PEND            5               // seconds
174 #define GSS_CTX_EXPIRE          (8 * 3600)      // seconds
175 #define GSS_CTX_TTL_MIN         1               // seconds
176 #define GSS_TIMER_PERIOD        300             // seconds
177 #define MSECS_PER_SEC           1000
178 
179 #define auth_is_kerberized(auth) \
180 	(auth == RPCAUTH_KRB5 || \
181 	 auth == RPCAUTH_KRB5I || \
182 	 auth == RPCAUTH_KRB5P)
183 
184 __BEGIN_DECLS
185 
186 uid_t   nfs_cred_getasid2uid(kauth_cred_t);
187 int     nfs_gss_clnt_cred_put(struct nfsreq *, struct nfsm_chain *, mbuf_t);
188 int     nfs_gss_clnt_verf_get(struct nfsreq *, struct nfsm_chain *,
189     uint32_t, uint32_t, uint32_t *);
190 void    nfs_gss_clnt_rpcdone(struct nfsreq *);
191 int     nfs_gss_clnt_args_restore(struct nfsreq *);
192 int     nfs_gss_clnt_ctx_renew(struct nfsreq *);
193 void    nfs_gss_clnt_ctx_ref(struct nfsreq *, struct nfs_gss_clnt_ctx *);
194 void    nfs_gss_clnt_ctx_unref(struct nfsreq *);
195 void    nfs_gss_clnt_ctx_unmount(struct nfsmount *);
196 int     nfs_gss_clnt_ctx_remove(struct nfsmount *, kauth_cred_t);
197 int     nfs_gss_clnt_ctx_set_principal(struct nfsmount *, vfs_context_t, uint8_t *, size_t, uint32_t);
198 int     nfs_gss_clnt_ctx_get_principal(struct nfsmount *, vfs_context_t, struct user_nfs_gss_principal *);
199 void    nfs_gss_svc_init(void);
200 int     nfs_gss_svc_cred_get(struct nfsrv_descript *, struct nfsm_chain *);
201 int     nfs_gss_svc_verf_put(struct nfsrv_descript *, struct nfsm_chain *);
202 int     nfs_gss_svc_ctx_init(struct nfsrv_descript *, struct nfsrv_sock *, mbuf_t *);
203 int     nfs_gss_svc_prepare_reply(struct nfsrv_descript *, struct nfsm_chain *);
204 int     nfs_gss_svc_protect_reply(struct nfsrv_descript *, mbuf_t);
205 void    nfs_gss_svc_ctx_deref(struct nfs_gss_svc_ctx *);
206 void    nfs_gss_svc_cleanup(void);
207 
208 __END_DECLS
209 #endif /* _NFS_NFS_GSS_H_ */
210