]> git.pld-linux.org Git - packages/nfs-utils.git/blame - nfs-utils-1.0.8-CITI_NFS4_ALL-1.dif
- update NFS4
[packages/nfs-utils.git] / nfs-utils-1.0.8-CITI_NFS4_ALL-1.dif
CommitLineData
9cd6965a
JR
1
2
3The complete set of CITI nfs-utils patches rolled into one patch.
4
5Changes since 1.0.8-rc4-CITI_NFS4_ALL-3:
6
7 * Update to the final nfs-utils-1.0.8
8
9 * Check for problems with the gssapi library in gssd and svcgssd
10 early on, so we can give a good error message and bail out.
11
12 * Add temporary patch to svcgssd to use default values when the
13 mapping of the gss principal to uid/gid fails. This may need
14 to somehow coordinate with the anonuid/anongid values for the
15 export.
16
17
18---
19
20 nfs-utils-1.0.8-kwc/utils/gssd/context_mit.c | 507 ++++++++++++++++++++++++--
21 nfs-utils-1.0.8-kwc/utils/gssd/gss_util.c | 25 +
22 nfs-utils-1.0.8-kwc/utils/gssd/gss_util.h | 1
23 nfs-utils-1.0.8-kwc/utils/gssd/gssd.c | 5
24 nfs-utils-1.0.8-kwc/utils/gssd/krb5_util.c | 221 +++++++++--
25 nfs-utils-1.0.8-kwc/utils/gssd/krb5_util.h | 2
26 nfs-utils-1.0.8-kwc/utils/gssd/svcgssd.c | 5
27 nfs-utils-1.0.8-kwc/utils/gssd/svcgssd_proc.c | 17
28 nfs-utils-1.0.8-kwc/utils/gssd/write_bytes.h | 13
29 9 files changed, 714 insertions(+), 82 deletions(-)
30
31diff -puN utils/gssd/gssd.c~CITI_NFS4_ALL utils/gssd/gssd.c
32--- nfs-utils-1.0.8/utils/gssd/gssd.c~CITI_NFS4_ALL 2006-04-20 12:41:15.668400000 -0400
33+++ nfs-utils-1.0.8-kwc/utils/gssd/gssd.c 2006-04-20 12:41:16.486965000 -0400
34@@ -145,6 +145,9 @@ main(int argc, char *argv[])
35 "support setting debug level\n");
36 #endif
37
38+ if (gssd_check_mechs() != 0)
39+ errx(1, "Problem with gssapi library");
40+
41 if (!fg && daemon(0, 0) < 0)
42 errx(1, "fork");
43
44@@ -154,6 +157,8 @@ main(int argc, char *argv[])
45
46 /* Process keytab file and get machine credentials */
47 gssd_refresh_krb5_machine_creds();
48+ /* Determine Kerberos information from the kernel */
49+ gssd_obtain_kernel_krb5_info();
50
51 gssd_run();
52 printerr(0, "gssd_run returned!\n");
53diff -puN utils/gssd/gss_util.c~CITI_NFS4_ALL utils/gssd/gss_util.c
54--- nfs-utils-1.0.8/utils/gssd/gss_util.c~CITI_NFS4_ALL 2006-04-20 12:41:15.770298000 -0400
55+++ nfs-utils-1.0.8-kwc/utils/gssd/gss_util.c 2006-04-20 12:41:16.001067000 -0400
56@@ -224,3 +224,28 @@ gssd_acquire_cred(char *server_name)
57
58 return (maj_stat == GSS_S_COMPLETE);
59 }
60+
61+int gssd_check_mechs(void)
62+{
63+ u_int32_t maj_stat, min_stat;
64+ gss_OID_set supported_mechs = GSS_C_NO_OID_SET;
65+ int retval = -1;
66+
67+ maj_stat = gss_indicate_mechs(&min_stat, &supported_mechs);
68+ if (maj_stat != GSS_S_COMPLETE) {
69+ printerr(0, "Unable to obtain list of supported mechanisms. "
70+ "Check that gss library is properly configured.\n");
71+ goto out;
72+ }
73+ if (supported_mechs == GSS_C_NO_OID_SET ||
74+ supported_mechs->count == 0) {
75+ printerr(0, "Unable to obtain list of supported mechanisms. "
76+ "Check that gss library is properly configured.\n");
77+ goto out;
78+ }
79+ maj_stat = gss_release_oid_set(&min_stat, &supported_mechs);
80+ retval = 0;
81+out:
82+ return retval;
83+}
84+
85diff -puN utils/gssd/gss_util.h~CITI_NFS4_ALL utils/gssd/gss_util.h
86--- nfs-utils-1.0.8/utils/gssd/gss_util.h~CITI_NFS4_ALL 2006-04-20 12:41:15.865203000 -0400
87+++ nfs-utils-1.0.8-kwc/utils/gssd/gss_util.h 2006-04-20 12:41:16.011057000 -0400
88@@ -40,5 +40,6 @@ extern gss_cred_id_t gssd_creds;
89 int gssd_acquire_cred(char *server_name);
90 void pgsserr(char *msg, u_int32_t maj_stat, u_int32_t min_stat,
91 const gss_OID mech);
92+int gssd_check_mechs(void);
93
94 #endif /* _GSS_UTIL_H_ */
95diff -puN utils/gssd/svcgssd.c~CITI_NFS4_ALL utils/gssd/svcgssd.c
96--- nfs-utils-1.0.8/utils/gssd/svcgssd.c~CITI_NFS4_ALL 2006-04-20 12:41:15.961107000 -0400
97+++ nfs-utils-1.0.8-kwc/utils/gssd/svcgssd.c 2006-04-20 12:41:16.021047000 -0400
98@@ -204,6 +204,11 @@ main(int argc, char *argv[])
99 "support setting debug level\n");
100 #endif
101
102+ if (gssd_check_mechs() != 0) {
103+ printerr(0, "ERROR: Problem with gssapi library\n");
104+ exit(1);
105+ }
106+
107 if (!fg)
108 mydaemon(0, 0);
109
110diff -puN utils/gssd/krb5_util.c~CITI_NFS4_ALL utils/gssd/krb5_util.c
111--- nfs-utils-1.0.8/utils/gssd/krb5_util.c~CITI_NFS4_ALL 2006-04-20 12:41:16.230965000 -0400
112+++ nfs-utils-1.0.8-kwc/utils/gssd/krb5_util.c 2006-04-20 12:41:16.503965000 -0400
113@@ -97,6 +97,7 @@
114 #include "config.h"
115 #include <sys/param.h>
116 #include <rpc/rpc.h>
117+#include <sys/types.h>
118 #include <sys/stat.h>
119 #include <sys/socket.h>
120 #include <arpa/inet.h>
121@@ -105,6 +106,7 @@
122 #include <stdlib.h>
123 #include <string.h>
124 #include <dirent.h>
125+#include <fcntl.h>
126 #include <errno.h>
127 #include <time.h>
128 #include <gssapi/gssapi.h>
129@@ -123,6 +125,10 @@
130 /* Global list of principals/cache file names for machine credentials */
131 struct gssd_k5_kt_princ *gssd_k5_kt_princ_list = NULL;
132
133+/* Encryption types supported by the kernel rpcsec_gss code */
134+int num_krb5_enctypes = 0;
135+krb5_enctype *krb5_enctypes = NULL;
136+
137 /*==========================*/
138 /*=== Internal routines ===*/
139 /*==========================*/
140@@ -261,51 +267,6 @@ gssd_find_existing_krb5_ccache(uid_t uid
141 }
142
143
144-#ifdef HAVE_SET_ALLOWABLE_ENCTYPES
145-/*
146- * this routine obtains a credentials handle via gss_acquire_cred()
147- * then calls gss_krb5_set_allowable_enctypes() to limit the encryption
148- * types negotiated.
149- *
150- * XXX Should call some function to determine the enctypes supported
151- * by the kernel. (Only need to do that once!)
152- *
153- * Returns:
154- * 0 => all went well
155- * -1 => there was an error
156- */
157-
158-int
159-limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid)
160-{
161- u_int maj_stat, min_stat;
162- gss_cred_id_t credh;
163- krb5_enctype enctypes[] = { ENCTYPE_DES_CBC_CRC };
164- int num_enctypes = sizeof(enctypes) / sizeof(enctypes[0]);
165-
166- maj_stat = gss_acquire_cred(&min_stat, NULL, 0,
167- GSS_C_NULL_OID_SET, GSS_C_INITIATE,
168- &credh, NULL, NULL);
169-
170- if (maj_stat != GSS_S_COMPLETE) {
171- pgsserr("gss_acquire_cred",
172- maj_stat, min_stat, &krb5oid);
173- return -1;
174- }
175-
176- maj_stat = gss_set_allowable_enctypes(&min_stat, credh, &krb5oid,
177- num_enctypes, &enctypes);
178- if (maj_stat != GSS_S_COMPLETE) {
179- pgsserr("gss_set_allowable_enctypes",
180- maj_stat, min_stat, &krb5oid);
181- return -1;
182- }
183- sec->cred = credh;
184-
185- return 0;
186-}
187-#endif /* HAVE_SET_ALLOWABLE_ENCTYPES */
188-
189 /*
190 * Obtain credentials via a key in the keytab given
191 * a keytab handle and a gssd_k5_kt_princ structure.
192@@ -603,6 +564,56 @@ gssd_set_krb5_ccache_name(char *ccname)
193 #endif
194 }
195
196+/*
197+ * Parse the supported encryption type information
198+ */
199+static int
200+parse_enctypes(char *enctypes)
201+{
202+ int n = 0;
203+ char *curr, *comma;
204+ int i;
205+
206+ /* Just in case this ever gets called more than once */
207+ if (krb5_enctypes != NULL) {
208+ free(krb5_enctypes);
209+ krb5_enctypes = NULL;
210+ num_krb5_enctypes = 0;
211+ }
212+
213+ /* count the number of commas */
214+ for (curr = enctypes; curr && *curr != '\0'; curr = ++comma) {
215+ comma = strchr(curr, ',');
216+ if (comma != NULL)
217+ n++;
218+ else
219+ break;
220+ }
221+ /* If no more commas and we're not at the end, there's one more value */
222+ if (*curr != '\0')
223+ n++;
224+
225+ /* Empty string, return an error */
226+ if (n == 0)
227+ return ENOENT;
228+
229+ /* Allocate space for enctypes array */
230+ if ((krb5_enctypes = (int *) calloc(n, sizeof(int))) == NULL) {
231+ return ENOMEM;
232+ }
233+
234+ /* Now parse each value into the array */
235+ for (curr = enctypes, i = 0; curr && *curr != '\0'; curr = ++comma) {
236+ krb5_enctypes[i++] = atoi(curr);
237+ comma = strchr(curr, ',');
238+ if (comma == NULL)
239+ break;
240+ }
241+
242+ num_krb5_enctypes = n;
243+ return 0;
244+}
245+
246 /*==========================*/
247 /*=== External routines ===*/
248 /*==========================*/
249@@ -854,3 +865,123 @@ gssd_destroy_krb5_machine_creds(void)
250 krb5_free_context(context);
251 }
252
253+#ifdef HAVE_SET_ALLOWABLE_ENCTYPES
254+/*
255+ * this routine obtains a credentials handle via gss_acquire_cred()
256+ * then calls gss_krb5_set_allowable_enctypes() to limit the encryption
257+ * types negotiated.
258+ *
259+ * Returns:
260+ * 0 => all went well
261+ * -1 => there was an error
262+ */
263+
264+int
265+limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid)
266+{
267+ u_int maj_stat, min_stat;
268+ gss_cred_id_t credh;
269+ gss_OID_set_desc desired_mechs;
270+ krb5_enctype enctypes[] = {ENCTYPE_DES_CBC_CRC};
271+ int num_enctypes = sizeof(enctypes) / sizeof(enctypes[0]);
272+
273+ /* We only care about getting a krb5 cred */
274+ desired_mechs.count = 1;
275+ desired_mechs.elements = &krb5oid;
276+
277+ maj_stat = gss_acquire_cred(&min_stat, NULL, 0,
278+ &desired_mechs, GSS_C_INITIATE,
279+ &credh, NULL, NULL);
280+
281+ if (maj_stat != GSS_S_COMPLETE) {
282+ pgsserr("gss_acquire_cred",
283+ maj_stat, min_stat, &krb5oid);
284+ return -1;
285+ }
286+
287+ /*
288+ * If we failed for any reason to produce global
289+ * list of supported enctypes, use local default here.
290+ */
291+ if (krb5_enctypes == NULL)
292+ maj_stat = gss_set_allowable_enctypes(&min_stat, credh,
293+ &krb5oid, num_enctypes, &enctypes);
294+ else
295+ maj_stat = gss_set_allowable_enctypes(&min_stat, credh,
296+ &krb5oid, num_krb5_enctypes,
297+ krb5_enctypes);
298+ if (maj_stat != GSS_S_COMPLETE) {
299+ pgsserr("gss_set_allowable_enctypes",
300+ maj_stat, min_stat, &krb5oid);
301+ return -1;
302+ }
303+ sec->cred = credh;
304+
305+ return 0;
306+}
307+#endif /* HAVE_SET_ALLOWABLE_ENCTYPES */
308+
309+/*
310+ * Obtain supported enctypes from kernel.
311+ * Set defaults if info is not available.
312+ */
313+void
314+gssd_obtain_kernel_krb5_info(void)
315+{
316+ char enctype_file_name[128];
317+ char buf[1024];
318+ char enctypes[128];
319+ char extrainfo[1024];
320+ int fd;
321+ int use_default_enctypes = 0;
322+ int nbytes, numfields;
323+ char default_enctypes[] = "1,3,2";
324+ int code;
325+
326+ snprintf(enctype_file_name, sizeof(enctype_file_name),
327+ "%s/%s", pipefsdir, "krb5_info");
328+
329+ if ((fd = open(enctype_file_name, O_RDONLY)) == -1) {
330+ printerr(1, "WARNING: gssd_obtain_kernel_krb5_info: "
331+ "Unable to open '%s'. Unable to determine "
332+ "Kerberos encryption types supported by the "
333+ "kernel; using defaults (%s).\n",
334+ enctype_file_name, default_enctypes);
335+ use_default_enctypes = 1;
336+ goto do_the_parse;
337+ }
338+ if ((nbytes = read(fd, buf, sizeof(buf))) == -1) {
339+ printerr(0, "WARNING: gssd_obtain_kernel_krb5_info: "
340+ "Error reading Kerberos encryption type "
341+ "information file '%s'; using defaults (%s).\n",
342+ enctype_file_name, default_enctypes);
343+ use_default_enctypes = 1;
344+ goto do_the_parse;
345+ }
346+ numfields = sscanf(buf, "enctypes: %s\n%s", enctypes, extrainfo);
347+ if (numfields < 1) {
348+ printerr(0, "WARNING: gssd_obtain_kernel_krb5_info: "
349+ "error parsing Kerberos encryption type "
350+ "information from file '%s'; using defaults (%s).\n",
351+ enctype_file_name, default_enctypes);
352+ use_default_enctypes = 1;
353+ goto do_the_parse;
354+ }
355+ if (numfields > 1) {
356+ printerr(0, "WARNING: gssd_obtain_kernel_krb5_info: "
357+ "Extra information, '%s', from '%s' is ignored\n",
358+ enctype_file_name, extrainfo);
359+ use_default_enctypes = 1;
360+ goto do_the_parse;
361+ }
362+ do_the_parse:
363+ if (use_default_enctypes)
364+ strcpy(enctypes, default_enctypes);
365+
366+ if ((code = parse_enctypes(enctypes)) != 0) {
367+ printerr(0, "ERROR: gssd_obtain_kernel_krb5_info: "
368+ "parse_enctypes%s failed with code %d\n",
369+ use_default_enctypes ? " (with default enctypes)" : "",
370+ code);
371+ }
372+}
373diff -puN utils/gssd/krb5_util.h~CITI_NFS4_ALL utils/gssd/krb5_util.h
374--- nfs-utils-1.0.8/utils/gssd/krb5_util.h~CITI_NFS4_ALL 2006-04-20 12:41:16.461965000 -0400
375+++ nfs-utils-1.0.8-kwc/utils/gssd/krb5_util.h 2006-04-20 12:41:16.513965000 -0400
376@@ -22,6 +22,8 @@ int gssd_refresh_krb5_machine_creds(voi
377 void gssd_free_krb5_machine_cred_list(char **list);
378 void gssd_setup_krb5_machine_gss_ccache(char *servername);
379 void gssd_destroy_krb5_machine_creds(void);
380+void gssd_obtain_kernel_krb5_info(void);
381+
382
383 #ifdef HAVE_SET_ALLOWABLE_ENCTYPES
384 int limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid);
385diff -puN utils/gssd/context_mit.c~CITI_NFS4_ALL utils/gssd/context_mit.c
386--- nfs-utils-1.0.8/utils/gssd/context_mit.c~CITI_NFS4_ALL 2006-04-20 12:41:16.770847000 -0400
387+++ nfs-utils-1.0.8-kwc/utils/gssd/context_mit.c 2006-04-20 12:41:16.894723000 -0400
388@@ -32,6 +32,7 @@
389 #include <stdio.h>
390 #include <syslog.h>
391 #include <string.h>
392+#include <errno.h>
638697cf 393 #include <gssapi.h>
9cd6965a
JR
394 #include <rpc/rpc.h>
395 #include <rpc/auth_gss.h>
396@@ -43,9 +44,53 @@
397 #ifdef HAVE_KRB5
398 #include <krb5.h>
399
400+/* for 3DES */
401+#define KG_USAGE_SEAL 22
402+#define KG_USAGE_SIGN 23
403+#define KG_USAGE_SEQ 24
404+
405+/* for rfc???? */
406+#define KG_USAGE_ACCEPTOR_SEAL 22
407+#define KG_USAGE_ACCEPTOR_SIGN 23
408+#define KG_USAGE_INITIATOR_SEAL 24
409+#define KG_USAGE_INITIATOR_SIGN 25
410+
411+/* Lifted from mit src/lib/gssapi/krb5/gssapiP_krb5.h */
412+enum seal_alg {
413+ SEAL_ALG_NONE = 0xffff,
414+ SEAL_ALG_DES = 0x0000,
415+ SEAL_ALG_1 = 0x0001, /* not published */
416+ SEAL_ALG_MICROSOFT_RC4 = 0x0010, /* microsoft w2k; */
417+ SEAL_ALG_DES3KD = 0x0002
418+};
419+
420+#define KEY_USAGE_SEED_ENCRYPTION 0xAA
421+#define KEY_USAGE_SEED_INTEGRITY 0x55
422+#define KEY_USAGE_SEED_CHECKSUM 0x99
423+#define K5CLENGTH 5
424+
425+/* Flags for version 2 context flags */
426+#define KRB5_CTX_FLAG_INITIATOR 0x00000001
427+#define KRB5_CTX_FLAG_CFX 0x00000002
428+#define KRB5_CTX_FLAG_ACCEPTOR_SUBKEY 0x00000004
429+
430+/*
431+ * XXX Hack alert. We don't have "legal" access to these
432+ * structures located in libk5crypto
433+ */
434+extern void krb5int_enc_arcfour;
435+extern void krb5int_enc_des3;
436+extern void krb5int_enc_aes128;
437+extern void krb5int_enc_aes256;
438+extern int krb5_derive_key();
439+
440+void *get_enc_provider();
441+
442 /* XXX spkm3 seems to actually want it this big, yipes. */
443 #define MAX_CTX_LEN 4096
444
445+
446+
447 #ifdef HAVE_LUCID_CONTEXT_SUPPORT
448
449 /* Don't use the private structure, use the exported lucid structure */
450@@ -144,6 +189,96 @@ write_lucid_keyblock(char **p, char *end
451 return 0;
452 }
453
454+static void
455+key_lucid_to_krb5(const gss_krb5_lucid_key_t *lin, krb5_keyblock *kout)
456+{
457+ memset(kout, '\0', sizeof(kout));
458+ kout->enctype = lin->type;
459+ kout->length = lin->length;
460+ kout->contents = lin->data;
461+}
462+
463+static void
464+key_krb5_to_lucid(const krb5_keyblock *kin, gss_krb5_lucid_key_t *lout)
465+{
466+ memset(lout, '\0', sizeof(lout));
467+ lout->type = kin->enctype;
468+ lout->length = kin->length;
469+ lout->data = kin->contents;
470+}
471+
472+/*
473+ * Function to derive a new key from a given key and given constant data.
474+ */
475+static krb5_error_code
476+derive_key_lucid(const gss_krb5_lucid_key_t *in, gss_krb5_lucid_key_t *out,
477+ int usage, char extra)
478+{
479+ krb5_error_code code;
480+ unsigned char constant_data[K5CLENGTH];
481+ krb5_data datain;
482+ int keylength;
483+ void *enc;
484+ krb5_keyblock kin, kout; /* must send krb5_keyblock, not lucid! */
485+
486+ /*
487+ * XXX Hack alert. We don't have "legal" access to these
488+ * values and structures located in libk5crypto
489+ */
490+ switch (in->type) {
491+ case ENCTYPE_DES3_CBC_RAW:
492+ keylength = 24;
493+ enc = &krb5int_enc_des3;
494+ break;
495+ case ENCTYPE_AES128_CTS_HMAC_SHA1_96:
496+ keylength = 16;
497+ enc = &krb5int_enc_aes128;
498+ break;
499+ case ENCTYPE_AES256_CTS_HMAC_SHA1_96:
500+ keylength = 32;
501+ enc = &krb5int_enc_aes256;
502+ break;
503+ default:
504+ code = KRB5_BAD_ENCTYPE;
505+ goto out;
506+ }
507+
508+ /* allocate memory for output key */
509+ if ((out->data = malloc(keylength)) == NULL) {
510+ code = ENOMEM;
511+ goto out;
512+ }
513+ out->length = keylength;
514+ out->type = in->type;
515+
516+ /* Convert to correct format for call to krb5_derive_key */
517+ key_lucid_to_krb5(in, &kin);
518+ key_lucid_to_krb5(out, &kout);
519+
520+ datain.data = (char *) constant_data;
521+ datain.length = K5CLENGTH;
522+
523+ datain.data[0] = (usage>>24)&0xff;
524+ datain.data[1] = (usage>>16)&0xff;
525+ datain.data[2] = (usage>>8)&0xff;
526+ datain.data[3] = usage&0xff;
527+
528+ datain.data[4] = (char) extra;
529+
530+ if ((code = krb5_derive_key(enc, &kin, &kout, &datain))) {
531+ free(out->data);
532+ out->data = NULL;
533+ goto out;
534+ }
535+ key_krb5_to_lucid(&kout, out);
536+
537+ out:
538+ if (code)
539+ printerr(0, "ERROR: derive_key_lucid returning error %d (%s)\n",
540+ code, error_message(code));
541+ return (code);
542+}
543+
544 static int
545 prepare_krb5_rfc1964_buffer(gss_krb5_lucid_context_v1_t *lctx,
546 gss_buffer_desc *buf)
547@@ -183,7 +318,7 @@ prepare_krb5_rfc1964_buffer(gss_krb5_luc
548 if (WRITE_BYTES(&p, end, lctx->endtime)) goto out_err;
549 word_send_seq = lctx->send_seq; /* XXX send_seq is 64-bit */
550 if (WRITE_BYTES(&p, end, word_send_seq)) goto out_err;
551- if (write_buffer(&p, end, (gss_buffer_desc*)&krb5oid)) goto out_err;
552+ if (write_oid(&p, end, &krb5oid)) goto out_err;
553
554 printerr(2, "prepare_krb5_rfc1964_buffer: serializing keys with "
555 "enctype %d and length %d\n",
556@@ -212,17 +347,180 @@ prepare_krb5_rfc1964_buffer(gss_krb5_luc
557 return 0;
558 out_err:
559 printerr(0, "ERROR: failed serializing krb5 context for kernel\n");
560- if (buf->value) free(buf->value);
561+ if (buf->value) {
562+ free(buf->value);
563+ buf->value = NULL;
564+ }
565 buf->length = 0;
566- if (enc_key.data) free(enc_key.data);
567+ if (enc_key.data) {
568+ free(enc_key.data);
569+ enc_key.data = NULL;
570+ }
571 return -1;
572 }
573
574+/*
575+ * Prepare a new-style buffer to send to the kernel for newer encryption
576+ * types -- or for DES3.
577+ *
578+ * The new format is:
579+ *
580+ * u32 version; This is two (2)
581+ * s32 endtime;
582+ * u32 flags;
583+ * #define KRB5_CTX_FLAG_INITIATOR 0x00000001
584+ * #define KRB5_CTX_FLAG_CFX 0x00000002
585+ * #define KRB5_CTX_FLAG_ACCEPTOR_SUBKEY 0x00000004
586+ * u64 seq_send;
587+ * u32 enctype; ( encrption type of keys )
588+ * u32 size_of_each_key; ( size of each key in bytes )
589+ * u32 number_of_keys; ( N -- should always be 3 for now )
590+ * keydata-1; ( Ke )
591+ * keydata-2; ( Ki )
592+ * keydata-3; ( Kc )
593+ *
594+ */
595 static int
596-prepare_krb5_rfc_cfx_buffer(gss_krb5_lucid_context_v1_t *lctx,
597+prepare_krb5_ctx_v2_buffer(gss_krb5_lucid_context_v1_t *lctx,
598 gss_buffer_desc *buf)
599 {
600- printerr(0, "ERROR: prepare_krb5_rfc_cfx_buffer: not implemented\n");
601+ char *p, *end;
602+ static uint32_t version = 2;
603+ uint32_t v2_flags = 0;
604+ gss_krb5_lucid_key_t enc_key;
605+ gss_krb5_lucid_key_t derived_key;
606+ gss_buffer_desc fakeoid;
607+ uint32_t enctype;
608+ uint32_t keysize;
609+ uint32_t numkeys;
610+
611+ memset(&enc_key, 0, sizeof(enc_key));
612+ memset(&fakeoid, 0, sizeof(fakeoid));
613+
614+ if (!(buf->value = calloc(1, MAX_CTX_LEN)))
615+ goto out_err;
616+ p = buf->value;
617+ end = buf->value + MAX_CTX_LEN;
618+
619+ /* Version 2 */
620+ if (WRITE_BYTES(&p, end , version)) goto out_err;
621+ if (WRITE_BYTES(&p, end, lctx->endtime)) goto out_err;
622+
623+ if (lctx->initiate)
624+ v2_flags |= KRB5_CTX_FLAG_INITIATOR;
625+ if (lctx->protocol != 0)
626+ v2_flags |= KRB5_CTX_FLAG_CFX;
627+ if (lctx->protocol != 0 && lctx->cfx_kd.have_acceptor_subkey == 1)
628+ v2_flags |= KRB5_CTX_FLAG_ACCEPTOR_SUBKEY;
629+
630+ if (WRITE_BYTES(&p, end, v2_flags)) goto out_err;
631+
632+ if (WRITE_BYTES(&p, end, lctx->send_seq)) goto out_err;
633+
634+ /* Protocol 0 here implies DES3 or RC4 */
635+ if (lctx->protocol == 0) {
636+ enctype = lctx->rfc1964_kd.ctx_key.type;
637+ keysize = lctx->rfc1964_kd.ctx_key.length;
638+ numkeys = 3; /* XXX is always gonna be three? */
639+ } else {
640+ if (lctx->cfx_kd.have_acceptor_subkey) {
641+ enctype = lctx->cfx_kd.acceptor_subkey.type;
642+ keysize = lctx->cfx_kd.acceptor_subkey.length;
643+ } else {
644+ enctype = lctx->cfx_kd.ctx_key.type;
645+ keysize = lctx->cfx_kd.ctx_key.length;
646+ }
647+ numkeys = 3;
648+ }
649+ printerr(2, "prepare_krb5_ctx_v2_buffer: serializing %d keys with "
650+ "enctype %d and size %d\n", numkeys, enctype, keysize);
651+ if (WRITE_BYTES(&p, end, enctype)) goto out_err;
652+ if (WRITE_BYTES(&p, end, keysize)) goto out_err;
653+ if (WRITE_BYTES(&p, end, numkeys)) goto out_err;
654+
655+ if (lctx->protocol == 0) {
656+ /* derive and send down: Ke, Ki, and Kc */
657+ /* Ke */
658+ if (write_bytes(&p, end, lctx->rfc1964_kd.ctx_key.data,
659+ lctx->rfc1964_kd.ctx_key.length))
660+ goto out_err;
661+
662+ /* Ki */
663+ if (write_bytes(&p, end, lctx->rfc1964_kd.ctx_key.data,
664+ lctx->rfc1964_kd.ctx_key.length))
665+ goto out_err;
666+
667+ /* Kc */
668+ if (derive_key_lucid(&lctx->rfc1964_kd.ctx_key,
669+ &derived_key,
670+ KG_USAGE_SIGN, KEY_USAGE_SEED_CHECKSUM))
671+ goto out_err;
672+ if (write_bytes(&p, end, derived_key.data,
673+ derived_key.length))
674+ goto out_err;
675+ free(derived_key.data);
676+ } else {
677+ gss_krb5_lucid_key_t *keyptr;
678+ uint32_t sign_usage, seal_usage;
679+
680+ if (lctx->cfx_kd.have_acceptor_subkey)
681+ keyptr = &lctx->cfx_kd.acceptor_subkey;
682+ else
683+ keyptr = &lctx->cfx_kd.ctx_key;
684+
685+ if (lctx->initiate == 1) {
686+ sign_usage = KG_USAGE_INITIATOR_SIGN;
687+ seal_usage = KG_USAGE_INITIATOR_SEAL;
688+ } else {
689+ sign_usage = KG_USAGE_ACCEPTOR_SIGN;
690+ seal_usage = KG_USAGE_ACCEPTOR_SEAL;
691+ }
692+
693+ /* derive and send down: Ke, Ki, and Kc */
694+
695+ /* Ke */
696+ if (derive_key_lucid(keyptr, &derived_key,
697+ seal_usage, KEY_USAGE_SEED_ENCRYPTION))
698+ goto out_err;
699+ if (write_bytes(&p, end, derived_key.data,
700+ derived_key.length))
701+ goto out_err;
702+ free(derived_key.data);
703+
704+ /* Ki */
705+ if (derive_key_lucid(keyptr, &derived_key,
706+ seal_usage, KEY_USAGE_SEED_INTEGRITY))
707+ goto out_err;
708+ if (write_bytes(&p, end, derived_key.data,
709+ derived_key.length))
710+ goto out_err;
711+ free(derived_key.data);
712+
713+ /* Kc */
714+ if (derive_key_lucid(keyptr, &derived_key,
715+ sign_usage, KEY_USAGE_SEED_CHECKSUM))
716+ goto out_err;
717+ if (write_bytes(&p, end, derived_key.data,
718+ derived_key.length))
719+ goto out_err;
720+ free(derived_key.data);
721+ }
722+
723+ buf->length = p - (char *)buf->value;
724+ return 0;
725+
726+out_err:
727+ printerr(0, "ERROR: prepare_krb5_ctx_v2_buffer: "
728+ "failed serializing krb5 context for kernel\n");
729+ if (buf->value) {
730+ free(buf->value);
731+ buf->value = NULL;
732+ }
733+ buf->length = 0;
734+ if (enc_key.data) {
735+ free(enc_key.data);
736+ enc_key.data = NULL;
737+ }
738 return -1;
739 }
740
741@@ -258,11 +556,21 @@ serialize_krb5_ctx(gss_ctx_id_t ctx, gss
742 break;
743 }
744
745- /* Now lctx points to a lucid context that we can send down to kernel */
746- if (lctx->protocol == 0)
747+ /*
748+ * Now lctx points to a lucid context that we can send down to kernel
749+ *
750+ * Note: we send down different information to the kernel depending
751+ * on the protocol version and the enctyption type.
752+ * For protocol version 0 with all enctypes besides DES3, we use
753+ * the original format. For protocol version != 0 or DES3, we
754+ * send down the new style information.
755+ */
756+
757+ if (lctx->protocol == 0 &&
758+ lctx->rfc1964_kd.ctx_key.type == ENCTYPE_DES_CBC_RAW)
759 retcode = prepare_krb5_rfc1964_buffer(lctx, buf);
760 else
761- retcode = prepare_krb5_rfc_cfx_buffer(lctx, buf);
762+ retcode = prepare_krb5_ctx_v2_buffer(lctx, buf);
763
764 maj_stat = gss_free_lucid_sec_context(&min_stat, ctx, return_ctx);
765 if (maj_stat != GSS_S_COMPLETE) {
766@@ -300,6 +608,66 @@ write_keyblock(char **p, char *end, stru
767 }
768
769 /*
770+ * Function to derive a new key from a given key and given constant data.
771+ */
772+static krb5_error_code
773+derive_key(const krb5_keyblock *in, krb5_keyblock *out, int usage, char extra)
774+{
775+ krb5_error_code code;
776+ unsigned char constant_data[K5CLENGTH];
777+ krb5_data datain;
778+ int keylength;
779+ void *enc;
780+
781+ /*
782+ * XXX Hack alert. We don't have "legal" access to these
783+ * values and structures located in libk5crypto
784+ */
785+ switch (in->enctype) {
786+ case ENCTYPE_DES3_CBC_RAW:
787+ keylength = 24;
788+ enc = &krb5int_enc_des3;
789+ break;
790+ case ENCTYPE_ARCFOUR_HMAC:
791+ keylength = 16;
792+ enc = &krb5int_enc_arcfour;
793+ break;
794+ default:
795+ code = KRB5_BAD_ENCTYPE;
796+ goto out;
797+ }
798+
799+ /* allocate memory for output key */
800+ if ((out->contents = malloc(keylength)) == NULL) {
801+ code = ENOMEM;
802+ goto out;
803+ }
804+ out->length = keylength;
805+ out->enctype = in->enctype;
806+
807+ datain.data = (char *) constant_data;
808+ datain.length = K5CLENGTH;
809+
810+ datain.data[0] = (usage>>24)&0xff;
811+ datain.data[1] = (usage>>16)&0xff;
812+ datain.data[2] = (usage>>8)&0xff;
813+ datain.data[3] = usage&0xff;
814+
815+ datain.data[4] = (char) extra;
816+
817+ if ((code = krb5_derive_key(enc, in, out, &datain))) {
818+ free(out->contents);
819+ out->contents = NULL;
820+ }
821+
822+ out:
823+ if (code)
824+ printerr(0, "ERROR: derive_key returning error %d (%s)\n",
825+ code, error_message(code));
826+ return (code);
827+}
828+
829+/*
830 * We really shouldn't know about glue-layer context structure, but
831 * we need to get at the real krb5 context pointer. This should be
832 * removed as soon as we say there is no support for MIT Kerberos
833@@ -315,45 +683,114 @@ serialize_krb5_ctx(gss_ctx_id_t ctx, gss
834 {
835 krb5_gss_ctx_id_t kctx = ((gss_union_ctx_id_t)ctx)->internal_ctx_id;
836 char *p, *end;
837- static int constant_one = 1;
838 static int constant_zero = 0;
839+ static int constant_one = 1;
840+ static int constant_two = 2;
841 uint32_t word_seq_send;
842+ u_int64_t seq_send_64bit;
843+ uint32_t v2_flags = 0;
844+ krb5_keyblock derived_key;
845+ uint32_t numkeys;
846
847 if (!(buf->value = calloc(1, MAX_CTX_LEN)))
848 goto out_err;
849 p = buf->value;
850 end = buf->value + MAX_CTX_LEN;
851
852- if (kctx->initiate) {
853- if (WRITE_BYTES(&p, end, constant_one)) goto out_err;
854- }
855- else {
856- if (WRITE_BYTES(&p, end, constant_zero)) goto out_err;
857- }
858- if (kctx->seed_init) {
859- if (WRITE_BYTES(&p, end, constant_one)) goto out_err;
860- }
861- else {
862- if (WRITE_BYTES(&p, end, constant_zero)) goto out_err;
863- }
864- if (write_bytes(&p, end, &kctx->seed, sizeof(kctx->seed)))
865- goto out_err;
866- if (WRITE_BYTES(&p, end, kctx->signalg)) goto out_err;
867- if (WRITE_BYTES(&p, end, kctx->sealalg)) goto out_err;
868- if (WRITE_BYTES(&p, end, kctx->endtime)) goto out_err;
869- word_seq_send = kctx->seq_send;
870- if (WRITE_BYTES(&p, end, word_seq_send)) goto out_err;
871- if (write_buffer(&p, end, kctx->mech_used)) goto out_err;
872-
873- printerr(2, "serialize_krb5_ctx: serializing keys with "
874- "enctype %d and length %d\n",
875- kctx->enc->enctype, kctx->enc->length);
876+ switch (kctx->sealalg) {
877+ case SEAL_ALG_DES:
878+ /* Versions 0 and 1 */
879+ if (kctx->initiate) {
880+ if (WRITE_BYTES(&p, end, constant_one)) goto out_err;
881+ }
882+ else {
883+ if (WRITE_BYTES(&p, end, constant_zero)) goto out_err;
884+ }
885+ if (kctx->seed_init) {
886+ if (WRITE_BYTES(&p, end, constant_one)) goto out_err;
887+ }
888+ else {
889+ if (WRITE_BYTES(&p, end, constant_zero)) goto out_err;
890+ }
891+ if (write_bytes(&p, end, &kctx->seed, sizeof(kctx->seed)))
892+ goto out_err;
893+ if (WRITE_BYTES(&p, end, kctx->signalg)) goto out_err;
894+ if (WRITE_BYTES(&p, end, kctx->sealalg)) goto out_err;
895+ if (WRITE_BYTES(&p, end, kctx->endtime)) goto out_err;
896+ word_seq_send = kctx->seq_send;
897+ if (WRITE_BYTES(&p, end, word_seq_send)) goto out_err;
898+ if (write_buffer(&p, end, kctx->mech_used)) goto out_err;
899+
900+ printerr(2, "serialize_krb5_ctx: serializing keys with "
901+ "enctype %d and length %d\n",
902+ kctx->enc->enctype, kctx->enc->length);
903
904- if (write_keyblock(&p, end, kctx->enc)) goto out_err;
905- if (write_keyblock(&p, end, kctx->seq)) goto out_err;
906+ if (write_keyblock(&p, end, kctx->enc)) goto out_err;
907+ if (write_keyblock(&p, end, kctx->seq)) goto out_err;
908+ break;
909+ case SEAL_ALG_MICROSOFT_RC4:
910+ case SEAL_ALG_DES3KD:
911+ /* u32 version; ( 2 )
912+ * s32 endtime;
913+ * u32 flags;
914+ * #define KRB5_CTX_FLAG_INITIATOR 0x00000001
915+ * #define KRB5_CTX_FLAG_CFX 0x00000002
916+ * #define KRB5_CTX_FLAG_ACCEPTOR_SUBKEY 0x00000004
917+ * u64 seq_send;
918+ * u32 enctype;
919+ * u32 size_of_each_key; ( size in bytes )
920+ * u32 number_of_keys; ( N (assumed to be 3 for now) )
921+ * keydata-1; ( Ke (Kenc for DES3) )
922+ * keydata-2; ( Ki (Kseq for DES3) )
923+ * keydata-3; ( Kc (derived checksum key) )
924+ */
925+ /* Version 2 */
926+ if (WRITE_BYTES(&p, end , constant_two)) goto out_err;
927+ if (WRITE_BYTES(&p, end, kctx->endtime)) goto out_err;
928+
929+ /* Only applicable flag for is initiator */
930+ if (kctx->initiate) v2_flags |= KRB5_CTX_FLAG_INITIATOR;
931+ if (WRITE_BYTES(&p, end, v2_flags)) goto out_err;
932+
933+ seq_send_64bit = kctx->seq_send;
934+ if (WRITE_BYTES(&p, end, seq_send_64bit)) goto out_err;
935+
936+ if (WRITE_BYTES(&p, end, kctx->enc->enctype)) goto out_err;
937+ if (WRITE_BYTES(&p, end, kctx->enc->length)) goto out_err;
938+ numkeys = 3;
939+ if (WRITE_BYTES(&p, end, numkeys)) goto out_err;
940+ printerr(2, "serialize_krb5_ctx: serializing %d keys with "
941+ "enctype %d and size %d\n",
942+ numkeys, kctx->enc->enctype, kctx->enc->length);
943+
944+ /* Ke */
945+ if (write_bytes(&p, end, kctx->enc->contents,
946+ kctx->enc->length))
947+ goto out_err;
948+
949+ /* Ki */
950+ if (write_bytes(&p, end, kctx->enc->contents,
951+ kctx->enc->length))
952+ goto out_err;
953+
954+ /* Kc */
955+ if (derive_key(kctx->seq, &derived_key,
956+ KG_USAGE_SIGN, KEY_USAGE_SEED_CHECKSUM))
957+ goto out_err;
958+ if (write_bytes(&p, end, derived_key.contents,
959+ derived_key.length))
960+ goto out_err;
961+ free(derived_key.contents);
962+ break;
963+ default:
964+ printerr(0, "ERROR: serialize_krb5_ctx: unsupported seal "
965+ "algorithm %d\n", kctx->sealalg);
966+ goto out_err;
967+ }
968
969 buf->length = p - (char *)buf->value;
970 return 0;
971+
972 out_err:
973 printerr(0, "ERROR: failed serializing krb5 context for kernel\n");
974 if (buf->value) free(buf->value);
975diff -puN utils/gssd/write_bytes.h~CITI_NFS4_ALL utils/gssd/write_bytes.h
976--- nfs-utils-1.0.8/utils/gssd/write_bytes.h~CITI_NFS4_ALL 2006-04-20 12:41:16.867750000 -0400
977+++ nfs-utils-1.0.8-kwc/utils/gssd/write_bytes.h 2006-04-20 12:41:16.905712000 -0400
978@@ -63,6 +63,19 @@ write_buffer(char **p, char *end, gss_bu
979 return 0;
980 }
981
982+inline static int
983+write_oid(char **p, char *end, gss_OID_desc *arg)
984+{
985+ int len = (int)arg->length; /* make an int out of size_t */
986+ if (WRITE_BYTES(p, end, len))
987+ return -1;
988+ if (*p + arg->length > end)
989+ return -1;
990+ memcpy(*p, arg->elements, len);
991+ *p += len;
992+ return 0;
993+}
994+
995 static inline int
996 get_bytes(char **ptr, const char *end, void *res, int len)
997 {
998diff -puN utils/gssd/svcgssd_proc.c~CITI_NFS4_ALL utils/gssd/svcgssd_proc.c
999--- nfs-utils-1.0.8/utils/gssd/svcgssd_proc.c~CITI_NFS4_ALL 2006-04-20 12:41:17.109514000 -0400
1000+++ nfs-utils-1.0.8-kwc/utils/gssd/svcgssd_proc.c 2006-04-20 12:41:17.133514000 -0400
1001@@ -220,8 +220,21 @@ get_ids(gss_name_t client_name, gss_OID
1002 nfs4_init_name_mapping(NULL); /* XXX: should only do this once */
1003 res = nfs4_gss_princ_to_ids(secname, sname, &uid, &gid);
1004 if (res < 0) {
1005- printerr(0, "WARNING: get_ids: unable to map "
1006- "name '%s' to a uid\n", sname);
1007+ /*
1008+ * -ENOENT means there was no mapping, any other error
1009+ * value means there was an error trying to do the
1010+ * mapping.
1011+ */
1012+ if (res == -ENOENT) {
1013+ cred->cr_uid = -2; /* XXX */
1014+ cred->cr_gid = -2; /* XXX */
1015+ cred->cr_groups[0] = -2;/* XXX */
1016+ cred->cr_ngroups = 1;
1017+ res = 0;
1018+ goto out_free;
1019+ }
1020+ printerr(0, "WARNING: get_ids: failed to map name '%s' "
1021+ "to uid/gid: %s\n", sname, strerror(-res));
1022 goto out_free;
1023 }
1024 cred->cr_uid = uid;
1025
1026_
This page took 0.162558 seconds and 4 git commands to generate.