]> git.pld-linux.org Git - packages/nfs-utils.git/blame - nfs-utils-CITI_NFS4.patch
- full ac/am rebuild
[packages/nfs-utils.git] / nfs-utils-CITI_NFS4.patch
CommitLineData
97cc26d8
JB
1
2
14bcaf3a 3The complete set of CITI nfs-utils patches rolled into one patch.
97cc26d8 4
0ac65518 5Changes since 1.1.0-CITI_NFS4_ALL-2:
97cc26d8 6
0ac65518 7 * Update to nfs-utils-1.1.1
71f23813 8
0ac65518
JB
9 * Patch from Steve Langasek <vorlon@debian.org> and
10 Steinar H. Gunderson <sesse@debian.org> fixing segfault problem on
11 64-bit platforms introduced by the xlog cleanup (re-using va_list).
71f23813 12
97cc26d8 13
97cc26d8
JB
14
15
16---
17
0ac65518
JB
18-nfs-utils-1.1.1-kwc/aclocal.m4 | 569 +++--------
19-nfs-utils-1.1.1-kwc/config.guess | 34
20-nfs-utils-1.1.1-kwc/config.sub | 24
21-nfs-utils-1.1.1-kwc/configure | 1195 ++++++++++--------------
22-nfs-utils-1.1.1-kwc/ltmain.sh | 147 +-
23 nfs-utils-1.1.1-kwc/support/nfs/xlog.c | 8
24 nfs-utils-1.1.1-kwc/utils/gssd/context.h | 6
25 nfs-utils-1.1.1-kwc/utils/gssd/context_lucid.c | 391 +++++++
26 nfs-utils-1.1.1-kwc/utils/gssd/context_mit.c | 256 ++++-
27 nfs-utils-1.1.1-kwc/utils/gssd/gssd.c | 8
28 nfs-utils-1.1.1-kwc/utils/gssd/gssd.h | 3
29 nfs-utils-1.1.1-kwc/utils/gssd/gssd_main_loop.c | 20
30 nfs-utils-1.1.1-kwc/utils/gssd/gssd_proc.c | 119 +-
31 nfs-utils-1.1.1-kwc/utils/gssd/krb5_util.c | 231 +++-
32 nfs-utils-1.1.1-kwc/utils/gssd/krb5_util.h | 2
33 nfs-utils-1.1.1-kwc/utils/gssd/svcgssd_proc.c | 84 +
34 16 files changed, 1786 insertions(+), 1311 deletions(-)
97cc26d8 35
0ac65518
JB
36diff -puN support/nfs/xlog.c~CITI_NFS4_ALL support/nfs/xlog.c
37--- nfs-utils-1.1.1/support/nfs/xlog.c~CITI_NFS4_ALL 2007-10-23 14:17:18.316202000 -0400
38+++ nfs-utils-1.1.1-kwc/support/nfs/xlog.c 2007-10-23 14:17:18.385133000 -0400
39@@ -133,9 +133,13 @@ xlog_enabled(int fac)
40 void
41 xlog_backend(int kind, const char *fmt, va_list args)
42 {
43+ va_list args2;
44+
45 if (!(kind & (L_ALL)) && !(logging && (kind & logmask)))
46 return;
47
48+ va_copy(args2, args);
49+
50 if (log_syslog) {
51 switch (kind) {
52 case L_FATAL:
53@@ -172,10 +176,12 @@ xlog_backend(int kind, const char *fmt,
54 fprintf(stderr, "%s: ", log_name);
55 #endif
56
57- vfprintf(stderr, fmt, args);
58+ vfprintf(stderr, fmt, args2);
59 fprintf(stderr, "\n");
14bcaf3a 60 }
0ac65518
JB
61
62+ va_end(args2);
63+
64 if (kind == L_FATAL)
65 exit(1);
14bcaf3a 66 }
0ac65518
JB
67diff -puN utils/gssd/svcgssd_proc.c~CITI_NFS4_ALL utils/gssd/svcgssd_proc.c
68--- nfs-utils-1.1.1/utils/gssd/svcgssd_proc.c~CITI_NFS4_ALL 2007-10-23 14:17:18.488030000 -0400
69+++ nfs-utils-1.1.1-kwc/utils/gssd/svcgssd_proc.c 2007-10-23 14:17:18.505013000 -0400
70@@ -51,6 +51,7 @@
71 #include "gss_util.h"
72 #include "err_util.h"
73 #include "context.h"
74+#include "gss_oids.h"
97cc26d8 75
0ac65518
JB
76 extern char * mech2file(gss_OID mech);
77 #define SVCGSSD_CONTEXT_CHANNEL "/proc/net/rpc/auth.rpcsec.context/channel"
78@@ -66,8 +67,30 @@ struct svc_cred {
79 };
80
81 static int
82+get_krb5_hostbased_name (gss_buffer_desc name, char **hostbased_name)
83+{
84+ char *p, *sname = NULL;
85+ if (strchr(name.value, '@') && strchr(name.value, '/')) {
86+ if (!(sname = calloc(name.length, 1))) {
87+ printerr(0, "ERROR: get_krb5_hostbased_name failed "
88+ "to allocate %d bytes\n", name.length);
89+ goto out_err;
90+ }
91+ /* read in name and instance and replace '/' with '@' */
92+ sscanf(name.value, "%[^@]", sname);
93+ p = strchr(sname, '/');
94+ p[0] = '@';
95+ }
96+ *hostbased_name = sname;
97+ return 0;
98+out_err:
99+ return -1;
100+}
101+
102+static int
103 do_svc_downcall(gss_buffer_desc *out_handle, struct svc_cred *cred,
104- gss_OID mech, gss_buffer_desc *context_token)
105+ gss_OID mech, gss_buffer_desc *context_token,
106+ char *client_name)
14bcaf3a 107 {
0ac65518
JB
108 FILE *f;
109 int i;
110@@ -91,8 +114,9 @@ do_svc_downcall(gss_buffer_desc *out_han
111 qword_printint(f, cred->cr_gid);
112 qword_printint(f, cred->cr_ngroups);
113 printerr(2, "mech: %s, hndl len: %d, ctx len %d, timeout: %d, "
114- "uid: %d, gid: %d, num aux grps: %d:\n",
115+ "clnt: %s, uid: %d, gid: %d, num aux grps: %d:\n",
116 fname, out_handle->length, context_token->length, 0x7fffffff,
117+ client_name ? client_name : "<null>",
118 cred->cr_uid, cred->cr_gid, cred->cr_ngroups);
119 for (i=0; i < cred->cr_ngroups; i++) {
120 qword_printint(f, cred->cr_groups[i]);
121@@ -100,6 +124,8 @@ do_svc_downcall(gss_buffer_desc *out_han
14bcaf3a 122 }
0ac65518
JB
123 qword_print(f, fname);
124 qword_printhex(f, context_token->value, context_token->length);
125+ if (client_name)
126+ qword_print(f, client_name);
127 err = qword_eol(f);
128 fclose(f);
129 return err;
130@@ -294,6 +320,45 @@ print_hexl(const char *description, unsi
14bcaf3a 131 }
0ac65518
JB
132 #endif
133
134+static int
135+get_hostbased_client_name(gss_name_t client_name, gss_OID mech,
136+ char **hostbased_name)
14bcaf3a 137+{
0ac65518
JB
138+ u_int32_t maj_stat, min_stat;
139+ gss_buffer_desc name;
140+ gss_OID name_type = GSS_C_NO_OID;
141+ char *cname;
142+ int res = -1;
97cc26d8 143+
0ac65518
JB
144+ /* get the client name and for service principals only
145+ * add it after the context (service name used for
146+ * authenticating callbacks) */
147+ maj_stat = gss_display_name(&min_stat, client_name, &name, &name_type);
148+ if (maj_stat != GSS_S_COMPLETE) {
149+ pgsserr("get_hostbased_client_name: gss_display_name",
150+ maj_stat, min_stat, mech);
151+ goto out_err;
14bcaf3a 152+ }
0ac65518
JB
153+ if (name.length >= 0xffff) { /* be certain name.length+1 doesn't overflow */
154+ printerr(0, "ERROR: get_hostbased_client_name: "
155+ "received gss_name is too long (%d bytes)\n",
156+ name.length);
157+ goto out_rel_buf;
14bcaf3a 158+ }
0ac65518
JB
159+ /* For Kerberos, transform the NT_KRB5_PRINCIPAL to
160+ * NT_HOSTBASED_SERVICE */
161+ if (g_OID_equal(&krb5oid, mech)) {
162+ if (!get_krb5_hostbased_name(name, &cname))
163+ *hostbased_name = cname;
14bcaf3a 164+ }
0ac65518
JB
165+ /* For SPKM3, do ??? */
166+ res = 0;
167+out_rel_buf:
168+ gss_release_buffer(&min_stat, &name);
169+out_err:
170+ return res;
14bcaf3a 171+}
0ac65518
JB
172+
173 void
174 handle_nullreq(FILE *f) {
175 /* XXX initialize to a random integer to reduce chances of unnecessary
176@@ -320,6 +385,7 @@ handle_nullreq(FILE *f) {
177 static char *lbuf = NULL;
178 static int lbuflen = 0;
179 static char *cp;
180+ char *hostbased_name = NULL;
181
182 printerr(1, "handling null request\n");
183
184@@ -385,8 +451,12 @@ handle_nullreq(FILE *f) {
185 gss_release_name(&ignore_min_stat, &client_name);
186 goto out_err;
187 }
188- gss_release_name(&ignore_min_stat, &client_name);
189-
190+ if (get_hostbased_client_name(client_name, mech, &hostbased_name)) {
191+ /* get_hostbased_client_name() prints error msg */
192+ maj_stat = GSS_S_BAD_NAME; /* XXX ? */
193+ gss_release_name(&ignore_min_stat, &client_name);
194+ goto out_err;
195+ }
71f23813 196
0ac65518
JB
197 /* Context complete. Pass handle_seq in out_handle to use
198 * for context lookup in the kernel. */
199@@ -400,12 +470,14 @@ handle_nullreq(FILE *f) {
200 printerr(0, "WARNING: handle_nullreq: "
201 "serialize_context_for_kernel failed\n");
202 maj_stat = GSS_S_FAILURE;
203+ gss_release_name(&ignore_min_stat, &client_name);
204 goto out_err;
14bcaf3a 205 }
0ac65518
JB
206 /* We no longer need the gss context */
207 gss_delete_sec_context(&ignore_min_stat, &ctx, &ignore_out_tok);
208
209- do_svc_downcall(&out_handle, &cred, mech, &ctx_token);
210+ do_svc_downcall(&out_handle, &cred, mech, &ctx_token, hostbased_name);
211+ gss_release_name(&ignore_min_stat, &client_name);
212 continue_needed:
213 send_response(f, &in_handle, &in_tok, maj_stat, min_stat,
214 &out_handle, &out_tok);
215@@ -414,6 +486,8 @@ out:
216 free(ctx_token.value);
217 if (out_tok.value != NULL)
218 gss_release_buffer(&ignore_min_stat, &out_tok);
219+ if (hostbased_name)
220+ free(hostbased_name);
221 printerr(1, "finished handling null request\n");
222 return;
223
224diff -puN utils/gssd/gssd_main_loop.c~CITI_NFS4_ALL utils/gssd/gssd_main_loop.c
225--- nfs-utils-1.1.1/utils/gssd/gssd_main_loop.c~CITI_NFS4_ALL 2007-10-23 14:17:18.606911000 -0400
226+++ nfs-utils-1.1.1-kwc/utils/gssd/gssd_main_loop.c 2007-10-23 14:17:18.878793000 -0400
227@@ -98,7 +98,7 @@ gssd_run()
228 {
229 int ret;
230 struct sigaction dn_act;
231- int fd;
232+ int fd, fd_cb;
97cc26d8 233
0ac65518
JB
234 /* Taken from linux/Documentation/dnotify.txt: */
235 dn_act.sa_sigaction = dir_notify_handler;
236@@ -114,6 +114,19 @@ gssd_run()
237 fcntl(fd, F_SETSIG, DNOTIFY_SIGNAL);
238 fcntl(fd, F_NOTIFY, DN_CREATE|DN_DELETE|DN_MODIFY|DN_MULTISHOT);
239
240+ if ((fd_cb = open(pipefs_nfscbdir, O_RDONLY)) == -1) {
241+ /* could be an older kernel or a newer one doing NFS 4.1 */
242+ if (errno != ENOENT)
243+ printerr(0, "WARNING: failed to open %s: %s\n",
244+ pipefs_nfscbdir, strerror(errno));
245+ /* ignore processing callback directory */
246+ memset(pipefs_nfscbdir, '\0', sizeof(pipefs_nfscbdir));
247+ } else {
248+ fcntl(fd_cb, F_SETSIG, DNOTIFY_SIGNAL);
249+ fcntl(fd_cb, F_NOTIFY,
250+ DN_CREATE|DN_DELETE|DN_MODIFY|DN_MULTISHOT);
251+ }
14bcaf3a 252+
0ac65518 253 init_client_list();
14bcaf3a 254
0ac65518
JB
255 printerr(1, "beginning poll\n");
256@@ -121,8 +134,7 @@ gssd_run()
257 while (dir_changed) {
258 dir_changed = 0;
259 if (update_client_list()) {
260- printerr(0, "ERROR: couldn't update "
261- "client list\n");
262+ /* Error msg is already printed */
263 exit(1);
264 }
265 }
266@@ -141,5 +153,7 @@ gssd_run()
14bcaf3a
JR
267 }
268 }
0ac65518
JB
269 close(fd);
270+ if (fd_cb != -1)
271+ close(fd_cb);
272 return;
14bcaf3a 273 }
0ac65518
JB
274diff -puN utils/gssd/gssd_proc.c~CITI_NFS4_ALL utils/gssd/gssd_proc.c
275--- nfs-utils-1.1.1/utils/gssd/gssd_proc.c~CITI_NFS4_ALL 2007-10-23 14:17:18.662855000 -0400
276+++ nfs-utils-1.1.1-kwc/utils/gssd/gssd_proc.c 2007-10-23 14:17:19.021793000 -0400
277@@ -102,7 +102,7 @@ int pollsize; /* the size of pollaray (
278 /* XXX buffer problems: */
279 static int
280 read_service_info(char *info_file_name, char **servicename, char **servername,
281- int *prog, int *vers, char **protocol) {
282+ int *prog, int *vers, char **protocol, int *port) {
283 #define INFOBUFLEN 256
284 char buf[INFOBUFLEN];
285 static char dummy[128];
286@@ -112,6 +112,9 @@ read_service_info(char *info_file_name,
287 char program[16];
288 char version[16];
289 char protoname[16];
290+ char princname[128];
291+ char cb_port[128];
292+ char *p;
293 in_addr_t inaddr;
294 int fd = -1;
295 struct hostent *ent = NULL;
296@@ -136,19 +139,33 @@ read_service_info(char *info_file_name,
297 service, program, version,
298 address,
299 protoname);
300-
301 if (numfields == 5) {
302 strcpy(protoname, "tcp");
303 } else if (numfields != 6) {
304 goto fail;
305 }
306
307+ princname[0] = '\0';
308+ if ((p = strstr(buf, "principal name:")) != NULL)
309+ sscanf(p, "principal name: %127s\n", princname);
310+ cb_port[0] = '\0';
311+ if ((p = strstr(buf, "port")) != NULL)
312+ sscanf(p, "port: %127s\n", cb_port);
14bcaf3a 313+
0ac65518
JB
314 /* check service, program, and version */
315- if(memcmp(service, "nfs", 3)) return -1;
316+ if (memcmp(service, "nfs", 3))
317+ return -1;
318 *prog = atoi(program + 1); /* skip open paren */
319 *vers = atoi(version);
320- if((*prog != 100003) || ((*vers != 2) && (*vers != 3) && (*vers != 4)))
321- goto fail;
14bcaf3a 322+
0ac65518
JB
323+ if (strlen(service) == 3 && !memcmp(service, "nfs", 3)) {
324+ if ((*prog != 100003) || ((*vers != 2) && (*vers != 3) &&
325+ (*vers != 4)))
326+ goto fail;
327+ } else if (!memcmp(service, "nfs4_cb", 7)) {
328+ if (*vers != 1)
329+ goto fail;
330+ }
331
332 /* create service name */
333 inaddr = inet_addr(address);
334@@ -159,7 +176,12 @@ read_service_info(char *info_file_name,
335 if (!(*servername = calloc(strlen(ent->h_name) + 1, 1)))
336 goto fail;
337 memcpy(*servername, ent->h_name, strlen(ent->h_name));
338- snprintf(buf, INFOBUFLEN, "%s@%s", service, ent->h_name);
339+ if (princname[0] != '\0')
340+ printerr(2, "info file contains princname=%s\n", princname);
341+
342+ snprintf(buf, INFOBUFLEN, "nfs@%s", ent->h_name);
343+ if (cb_port[0] != '\0')
344+ *port = atoi(cb_port);
345 if (!(*servicename = calloc(strlen(buf) + 1, 1)))
346 goto fail;
347 memcpy(*servicename, buf, strlen(buf));
348@@ -219,9 +241,9 @@ out:
349 static int
350 process_clnt_dir_files(struct clnt_info * clp)
351 {
352- char kname[32];
353- char sname[32];
354- char info_file_name[32];
355+ char kname[PATH_MAX];
356+ char sname[PATH_MAX];
357+ char info_file_name[PATH_MAX];
358
359 if (clp->krb5_fd == -1) {
360 snprintf(kname, sizeof(kname), "%s/krb5", clp->dirname);
361@@ -231,14 +253,14 @@ process_clnt_dir_files(struct clnt_info
362 snprintf(sname, sizeof(sname), "%s/spkm3", clp->dirname);
363 clp->spkm3_fd = open(sname, O_RDWR);
364 }
365- if((clp->krb5_fd == -1) && (clp->spkm3_fd == -1))
366+ if ((clp->krb5_fd == -1) && (clp->spkm3_fd == -1))
367 return -1;
368 snprintf(info_file_name, sizeof(info_file_name), "%s/info",
369 clp->dirname);
370 if ((clp->servicename == NULL) &&
371 read_service_info(info_file_name, &clp->servicename,
372 &clp->servername, &clp->prog, &clp->vers,
373- &clp->protocol))
374+ &clp->protocol, &clp->port))
375 return -1;
376 return 0;
377 }
378@@ -288,17 +310,17 @@ insert_clnt_poll(struct clnt_info *clp)
379 }
380
381 static void
382-process_clnt_dir(char *dir)
383+process_clnt_dir(char *dir, char *pdir)
384 {
385 struct clnt_info * clp;
386
387 if (!(clp = insert_new_clnt()))
388 goto fail_destroy_client;
389
390- if (!(clp->dirname = calloc(strlen(dir) + 1, 1))) {
391+ if (!(clp->dirname = calloc(strlen(dir) + strlen(pdir) + 1, 1))) {
392 goto fail_destroy_client;
393 }
394- memcpy(clp->dirname, dir, strlen(dir));
395+ sprintf(clp->dirname, "%s/%s", pdir, dir);
396 if ((clp->dir_fd = open(clp->dirname, O_RDONLY)) == -1) {
397 printerr(0, "ERROR: can't open %s: %s\n",
398 clp->dirname, strerror(errno));
399@@ -342,16 +364,24 @@ init_client_list(void)
400 * directories, since the DNOTIFY could have been in there.
401 */
402 static void
403-update_old_clients(struct dirent **namelist, int size)
404+update_old_clients(struct dirent **namelist, int size, char *pdir)
405 {
406 struct clnt_info *clp;
407 void *saveprev;
408 int i, stillhere;
409+ char fname[PATH_MAX];
410
411 for (clp = clnt_list.tqh_first; clp != NULL; clp = clp->list.tqe_next) {
412+ /* only compare entries in the global list that are from the
413+ * same pipefs parent directory as "pdir"
414+ */
415+ if (strncmp(clp->dirname, pdir, strlen(pdir)) != 0) break;
14bcaf3a 416+
0ac65518
JB
417 stillhere = 0;
418 for (i=0; i < size; i++) {
419- if (!strcmp(clp->dirname, namelist[i]->d_name)) {
420+ snprintf(fname, sizeof(fname), "%s/%s",
421+ pdir, namelist[i]->d_name);
422+ if (strcmp(clp->dirname, fname) == 0) {
423 stillhere = 1;
424 break;
425 }
426@@ -372,47 +402,72 @@ update_old_clients(struct dirent **namel
14bcaf3a 427
0ac65518
JB
428 /* Search for a client by directory name, return 1 if found, 0 otherwise */
429 static int
430-find_client(char *dirname)
431+find_client(char *dirname, char *pdir)
432 {
433 struct clnt_info *clp;
434+ char fname[PATH_MAX];
97cc26d8 435
0ac65518
JB
436- for (clp = clnt_list.tqh_first; clp != NULL; clp = clp->list.tqe_next)
437- if (!strcmp(clp->dirname, dirname))
438+ for (clp = clnt_list.tqh_first; clp != NULL; clp = clp->list.tqe_next) {
439+ snprintf(fname, sizeof(fname), "%s/%s", pdir, dirname);
440+ if (strcmp(clp->dirname, fname) == 0)
441 return 1;
442+ }
443 return 0;
97cc26d8
JB
444 }
445
0ac65518
JB
446-/* Used to read (and re-read) list of clients, set up poll array. */
447-int
448-update_client_list(void)
449+static int
450+process_pipedir(char *pipe_name)
451 {
452 struct dirent **namelist;
453 int i, j;
454
455- if (chdir(pipefs_nfsdir) < 0) {
456+ if (chdir(pipe_name) < 0) {
457 printerr(0, "ERROR: can't chdir to %s: %s\n",
458- pipefs_nfsdir, strerror(errno));
459+ pipe_name, strerror(errno));
460 return -1;
461 }
462
463- j = scandir(pipefs_nfsdir, &namelist, NULL, alphasort);
464+ j = scandir(pipe_name, &namelist, NULL, alphasort);
465 if (j < 0) {
466 printerr(0, "ERROR: can't scandir %s: %s\n",
467- pipefs_nfsdir, strerror(errno));
468+ pipe_name, strerror(errno));
469 return -1;
470 }
471- update_old_clients(namelist, j);
472+
473+ update_old_clients(namelist, j, pipe_name);
474 for (i=0; i < j; i++) {
475 if (i < FD_ALLOC_BLOCK
476 && !strncmp(namelist[i]->d_name, "clnt", 4)
477- && !find_client(namelist[i]->d_name))
478- process_clnt_dir(namelist[i]->d_name);
479+ && !find_client(namelist[i]->d_name, pipe_name))
480+ process_clnt_dir(namelist[i]->d_name, pipe_name);
481 free(namelist[i]);
482 }
483
484 free(namelist);
485+
486 return 0;
487 }
488+/* Used to read (and re-read) list of clients, set up poll array. */
489+int
490+update_client_list(void)
97cc26d8 491+{
0ac65518 492+ int retval = -1;
14bcaf3a 493+
0ac65518
JB
494+ retval = process_pipedir(pipefs_nfsdir);
495+ if (retval)
496+ printerr(0, "ERROR: processing %s\n", pipefs_nfsdir);
14bcaf3a 497+
0ac65518
JB
498+ /* if we successfully processed nfsdir and callback directory exists
499+ * process any events in the callback directory
500+ */
501+ if (retval == 0 && pipefs_nfscbdir[0] != '\0') {
502+ retval = process_pipedir(pipefs_nfscbdir);
503+ if (retval)
504+ printerr(0, "ERROR: processing %s\n", pipefs_nfscbdir);
97cc26d8 505+ }
97cc26d8 506+
0ac65518
JB
507+ return retval;
508+}
509
510 static int
511 do_downcall(int k5_fd, uid_t uid, struct authgss_private_data *pd,
512@@ -587,6 +642,8 @@ int create_auth_rpc_client(struct clnt_i
513 clp->servername, uid);
514 goto out_fail;
97cc26d8 515 }
0ac65518
JB
516+ if (clp->port)
517+ ((struct sockaddr_in *)a->ai_addr)->sin_port = htons(clp->port);
518 if (a->ai_protocol == IPPROTO_TCP) {
519 if ((rpc_clnt = clnttcp_create(
520 (struct sockaddr_in *) a->ai_addr,
521@@ -677,7 +734,7 @@ handle_krb5_upcall(struct clnt_info *clp
522 char **ccname;
523 int create_resp = -1;
97cc26d8 524
0ac65518
JB
525- printerr(1, "handling krb5 upcall\n");
526+ printerr(1, "handling krb5 upcall (%s)\n", clp->dirname);
527
528 token.length = 0;
529 token.value = NULL;
530@@ -787,7 +844,7 @@ handle_spkm3_upcall(struct clnt_info *cl
531 struct authgss_private_data pd;
532 gss_buffer_desc token;
533
534- printerr(2, "handling spkm3 upcall\n");
535+ printerr(2, "handling spkm3 upcall (%s)\n", clp->dirname);
536
537 token.length = 0;
538 token.value = NULL;
539diff -puN utils/gssd/gssd.c~CITI_NFS4_ALL utils/gssd/gssd.c
540--- nfs-utils-1.1.1/utils/gssd/gssd.c~CITI_NFS4_ALL 2007-10-23 14:17:18.789793000 -0400
541+++ nfs-utils-1.1.1-kwc/utils/gssd/gssd.c 2007-10-23 14:17:19.183793000 -0400
542@@ -55,6 +55,7 @@
543
544 char pipefs_dir[PATH_MAX] = GSSD_PIPEFS_DIR;
545 char pipefs_nfsdir[PATH_MAX] = GSSD_PIPEFS_DIR;
546+char pipefs_nfscbdir[PATH_MAX] = GSSD_PIPEFS_DIR;
547 char keytabfile[PATH_MAX] = GSSD_DEFAULT_KEYTAB_FILE;
548 char ccachedir[PATH_MAX] = GSSD_DEFAULT_CRED_DIR;
549 int use_memcache = 0;
550@@ -140,6 +141,10 @@ main(int argc, char *argv[])
551 pipefs_dir, GSSD_SERVICE_NAME);
552 if (pipefs_nfsdir[sizeof(pipefs_nfsdir)-1] != '\0')
553 errx(1, "pipefs_nfsdir path name too long");
554+ snprintf(pipefs_nfscbdir, sizeof(pipefs_nfscbdir), "%s/%s",
555+ pipefs_dir, GSSD_NFSCB_NAME);
556+ if (pipefs_nfscbdir[sizeof(pipefs_nfscbdir)-1] != '\0')
557+ errx(1, "pipefs_nfscbdir path name too long");
558
559 if ((progname = strrchr(argv[0], '/')))
560 progname++;
561@@ -165,6 +170,9 @@ main(int argc, char *argv[])
562 signal(SIGTERM, sig_die);
563 signal(SIGHUP, sig_hup);
564
565+ /* Determine Kerberos information from the kernel */
566+ gssd_obtain_kernel_krb5_info();
567+
568 gssd_run();
569 printerr(0, "gssd_run returned!\n");
570 abort();
571diff -puN utils/gssd/gssd.h~CITI_NFS4_ALL utils/gssd/gssd.h
572--- nfs-utils-1.1.1/utils/gssd/gssd.h~CITI_NFS4_ALL 2007-10-23 14:17:18.846794000 -0400
573+++ nfs-utils-1.1.1-kwc/utils/gssd/gssd.h 2007-10-23 14:17:18.957793000 -0400
574@@ -49,6 +49,7 @@
575 #define GSSD_DEFAULT_MACHINE_CRED_SUFFIX "machine"
576 #define GSSD_DEFAULT_KEYTAB_FILE "/etc/krb5.keytab"
577 #define GSSD_SERVICE_NAME "nfs"
578+#define GSSD_NFSCB_NAME "nfsd4_cb"
579 #define GSSD_SERVICE_NAME_LEN 3
580
581 /*
582@@ -60,6 +61,7 @@ enum {AUTHTYPE_KRB5, AUTHTYPE_SPKM3, AUT
583
584 extern char pipefs_dir[PATH_MAX];
585 extern char pipefs_nfsdir[PATH_MAX];
586+extern char pipefs_nfscbdir[PATH_MAX];
587 extern char keytabfile[PATH_MAX];
588 extern char ccachedir[PATH_MAX];
589 extern int use_memcache;
590@@ -80,6 +82,7 @@ struct clnt_info {
591 int krb5_poll_index;
592 int spkm3_fd;
593 int spkm3_poll_index;
594+ int port;
595 };
596
597 void init_client_list(void);
598diff -puN utils/gssd/krb5_util.c~CITI_NFS4_ALL utils/gssd/krb5_util.c
599--- nfs-utils-1.1.1/utils/gssd/krb5_util.c~CITI_NFS4_ALL 2007-10-23 14:17:19.109793000 -0400
600+++ nfs-utils-1.1.1-kwc/utils/gssd/krb5_util.c 2007-10-23 14:17:19.198793000 -0400
601@@ -97,6 +97,7 @@
602 #include "config.h"
603 #include <sys/param.h>
604 #include <rpc/rpc.h>
605+#include <sys/types.h>
606 #include <sys/stat.h>
607 #include <sys/socket.h>
608 #include <arpa/inet.h>
609@@ -108,6 +109,7 @@
610 #include <dirent.h>
611 #include <netdb.h>
612 #include <ctype.h>
613+#include <fcntl.h>
614 #include <errno.h>
615 #include <time.h>
616 #include <gssapi/gssapi.h>
617@@ -126,6 +128,10 @@
618 /* Global list of principals/cache file names for machine credentials */
619 struct gssd_k5_kt_princ *gssd_k5_kt_princ_list = NULL;
620
621+/* Encryption types supported by the kernel rpcsec_gss code */
622+int num_krb5_enctypes = 0;
623+krb5_enctype *krb5_enctypes = NULL;
624+
625 /*==========================*/
626 /*=== Internal routines ===*/
627 /*==========================*/
628@@ -256,58 +262,6 @@ gssd_find_existing_krb5_ccache(uid_t uid
629 return found;
97cc26d8
JB
630 }
631
0ac65518
JB
632-
633-#ifdef HAVE_SET_ALLOWABLE_ENCTYPES
634-/*
635- * this routine obtains a credentials handle via gss_acquire_cred()
636- * then calls gss_krb5_set_allowable_enctypes() to limit the encryption
637- * types negotiated.
638- *
639- * XXX Should call some function to determine the enctypes supported
640- * by the kernel. (Only need to do that once!)
641- *
642- * Returns:
643- * 0 => all went well
644- * -1 => there was an error
645- */
646-
647-int
648-limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid)
649-{
650- u_int maj_stat, min_stat;
651- gss_cred_id_t credh;
652- gss_OID_set_desc desired_mechs;
653- krb5_enctype enctypes[] = { ENCTYPE_DES_CBC_CRC };
654- int num_enctypes = sizeof(enctypes) / sizeof(enctypes[0]);
655-
656- /* We only care about getting a krb5 cred */
657- desired_mechs.count = 1;
658- desired_mechs.elements = &krb5oid;
659-
660- maj_stat = gss_acquire_cred(&min_stat, NULL, 0,
661- &desired_mechs, GSS_C_INITIATE,
662- &credh, NULL, NULL);
663-
664- if (maj_stat != GSS_S_COMPLETE) {
665- pgsserr("gss_acquire_cred",
666- maj_stat, min_stat, &krb5oid);
667- return -1;
668- }
669-
670- maj_stat = gss_set_allowable_enctypes(&min_stat, credh, &krb5oid,
671- num_enctypes, &enctypes);
672- if (maj_stat != GSS_S_COMPLETE) {
673- pgsserr("gss_set_allowable_enctypes",
674- maj_stat, min_stat, &krb5oid);
675- gss_release_cred(&min_stat, &credh);
676- return -1;
677- }
678- sec->cred = credh;
679-
680- return 0;
681-}
682-#endif /* HAVE_SET_ALLOWABLE_ENCTYPES */
683-
14bcaf3a 684 /*
0ac65518
JB
685 * Obtain credentials via a key in the keytab given
686 * a keytab handle and a gssd_k5_kt_princ structure.
687@@ -879,6 +833,56 @@ out:
688 return retval;
689 }
690
691+/*
692+ * Parse the supported encryption type information
14bcaf3a 693+ */
0ac65518
JB
694+static int
695+parse_enctypes(char *enctypes)
97cc26d8 696+{
0ac65518
JB
697+ int n = 0;
698+ char *curr, *comma;
699+ int i;
14bcaf3a 700+
0ac65518
JB
701+ /* Just in case this ever gets called more than once */
702+ if (krb5_enctypes != NULL) {
703+ free(krb5_enctypes);
704+ krb5_enctypes = NULL;
705+ num_krb5_enctypes = 0;
97cc26d8 706+ }
0ac65518
JB
707+
708+ /* count the number of commas */
709+ for (curr = enctypes; curr && *curr != '\0'; curr = ++comma) {
710+ comma = strchr(curr, ',');
711+ if (comma != NULL)
712+ n++;
713+ else
714+ break;
14bcaf3a 715+ }
0ac65518
JB
716+ /* If no more commas and we're not at the end, there's one more value */
717+ if (*curr != '\0')
718+ n++;
97cc26d8 719+
0ac65518
JB
720+ /* Empty string, return an error */
721+ if (n == 0)
722+ return ENOENT;
723+
724+ /* Allocate space for enctypes array */
725+ if ((krb5_enctypes = (int *) calloc(n, sizeof(int))) == NULL) {
726+ return ENOMEM;
727+ }
728+
729+ /* Now parse each value into the array */
730+ for (curr = enctypes, i = 0; curr && *curr != '\0'; curr = ++comma) {
731+ krb5_enctypes[i++] = atoi(curr);
732+ comma = strchr(curr, ',');
733+ if (comma == NULL)
734+ break;
735+ }
736+
737+ num_krb5_enctypes = n;
738+ return 0;
97cc26d8
JB
739+}
740+
0ac65518
JB
741 /*==========================*/
742 /*=== External routines ===*/
743 /*==========================*/
744@@ -1129,3 +1133,126 @@ gssd_k5_err_msg(krb5_context context, kr
745 return error_message(code);
746 #endif
747 }
748+
749+#ifdef HAVE_SET_ALLOWABLE_ENCTYPES
750+/*
751+ * this routine obtains a credentials handle via gss_acquire_cred()
752+ * then calls gss_krb5_set_allowable_enctypes() to limit the encryption
753+ * types negotiated.
754+ *
755+ * Returns:
756+ * 0 => all went well
757+ * -1 => there was an error
97cc26d8 758+ */
0ac65518
JB
759+
760+int
761+limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid)
97cc26d8 762+{
0ac65518
JB
763+ u_int maj_stat, min_stat;
764+ gss_cred_id_t credh;
765+ gss_OID_set_desc desired_mechs;
766+ krb5_enctype enctypes[] = {ENCTYPE_DES_CBC_CRC};
767+ int num_enctypes = sizeof(enctypes) / sizeof(enctypes[0]);
768+
769+ /* We only care about getting a krb5 cred */
770+ desired_mechs.count = 1;
771+ desired_mechs.elements = &krb5oid;
772+
773+ maj_stat = gss_acquire_cred(&min_stat, NULL, 0,
774+ &desired_mechs, GSS_C_INITIATE,
775+ &credh, NULL, NULL);
776+
777+ if (maj_stat != GSS_S_COMPLETE) {
778+ pgsserr("gss_acquire_cred",
779+ maj_stat, min_stat, &krb5oid);
780+ return -1;
97cc26d8 781+ }
0ac65518
JB
782+
783+ /*
784+ * If we failed for any reason to produce global
785+ * list of supported enctypes, use local default here.
786+ */
787+ if (krb5_enctypes == NULL)
788+ maj_stat = gss_set_allowable_enctypes(&min_stat, credh,
789+ &krb5oid, num_enctypes, &enctypes);
790+ else
791+ maj_stat = gss_set_allowable_enctypes(&min_stat, credh,
792+ &krb5oid, num_krb5_enctypes,
793+ krb5_enctypes);
794+ if (maj_stat != GSS_S_COMPLETE) {
795+ pgsserr("gss_set_allowable_enctypes",
796+ maj_stat, min_stat, &krb5oid);
797+ return -1;
798+ }
799+ sec->cred = credh;
800+
801+ return 0;
97cc26d8 802+}
0ac65518 803+#endif /* HAVE_SET_ALLOWABLE_ENCTYPES */
97cc26d8 804+
0ac65518
JB
805+/*
806+ * Obtain supported enctypes from kernel.
807+ * Set defaults if info is not available.
808+ */
809+void
810+gssd_obtain_kernel_krb5_info(void)
97cc26d8 811+{
0ac65518
JB
812+ char enctype_file_name[128];
813+ char buf[1024];
814+ char enctypes[128];
815+ int nscanned;
816+ int fd;
817+ int use_default_enctypes = 0;
818+ int nbytes, numfields;
819+ char default_enctypes[] = "1,3,2";
820+ int code;
14bcaf3a 821+
0ac65518
JB
822+ snprintf(enctype_file_name, sizeof(enctype_file_name),
823+ "%s/%s", pipefs_dir, "krb5_info");
824+
825+ if ((fd = open(enctype_file_name, O_RDONLY)) == -1) {
826+ printerr(1, "WARNING: gssd_obtain_kernel_krb5_info: "
827+ "Unable to open '%s'. Unable to determine "
828+ "Kerberos encryption types supported by the "
829+ "kernel; using defaults (%s).\n",
830+ enctype_file_name, default_enctypes);
831+ use_default_enctypes = 1;
832+ goto do_the_parse;
833+ }
834+ memset(buf, 0, sizeof(buf));
835+ if ((nbytes = read(fd, buf, sizeof(buf)-1)) == -1) {
836+ printerr(0, "WARNING: gssd_obtain_kernel_krb5_info: "
837+ "Error reading Kerberos encryption type "
838+ "information file '%s'; using defaults (%s).\n",
839+ enctype_file_name, default_enctypes);
840+ use_default_enctypes = 1;
841+ close(fd);
842+ goto do_the_parse;
843+ }
844+ close(fd);
845+ numfields = sscanf(buf, "enctypes: %s\n%n", enctypes, &nscanned);
846+ if (numfields < 1) {
847+ printerr(0, "WARNING: gssd_obtain_kernel_krb5_info: "
848+ "error parsing Kerberos encryption type "
849+ "information from file '%s'; using defaults (%s).\n",
850+ enctype_file_name, default_enctypes);
851+ use_default_enctypes = 1;
852+ goto do_the_parse;
853+ }
854+ if (nbytes > nscanned) {
855+ printerr(2, "gssd_obtain_kernel_krb5_info: "
856+ "Ignoring extra information, '%s', from '%s'\n",
857+ buf+nscanned, enctype_file_name);
858+ goto do_the_parse;
859+ }
860+ do_the_parse:
861+ if (use_default_enctypes)
862+ strcpy(enctypes, default_enctypes);
14bcaf3a 863+
0ac65518
JB
864+ if ((code = parse_enctypes(enctypes)) != 0) {
865+ printerr(0, "ERROR: gssd_obtain_kernel_krb5_info: "
866+ "parse_enctypes%s failed with code %d\n",
867+ use_default_enctypes ? " (with default enctypes)" : "",
868+ code);
97cc26d8
JB
869+ }
870+}
0ac65518
JB
871diff -puN utils/gssd/krb5_util.h~CITI_NFS4_ALL utils/gssd/krb5_util.h
872--- nfs-utils-1.1.1/utils/gssd/krb5_util.h~CITI_NFS4_ALL 2007-10-23 14:17:19.166793000 -0400
873+++ nfs-utils-1.1.1-kwc/utils/gssd/krb5_util.h 2007-10-23 14:17:19.206793000 -0400
874@@ -26,6 +26,8 @@ int gssd_refresh_krb5_machine_credentia
875 struct gssd_k5_kt_princ *ple);
876 const char *
877 gssd_k5_err_msg(krb5_context context, krb5_error_code code);
878+void gssd_obtain_kernel_krb5_info(void);
879+
880
881 #ifdef HAVE_SET_ALLOWABLE_ENCTYPES
882 int limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid);
883diff -puN utils/gssd/context.h~CITI_NFS4_ALL utils/gssd/context.h
884--- nfs-utils-1.1.1/utils/gssd/context.h~CITI_NFS4_ALL 2007-10-23 14:17:19.330737000 -0400
885+++ nfs-utils-1.1.1-kwc/utils/gssd/context.h 2007-10-23 14:17:19.458609000 -0400
886@@ -1,5 +1,5 @@
887 /*
888- Copyright (c) 2004 The Regents of the University of Michigan.
889+ Copyright (c) 2004-2006 The Regents of the University of Michigan.
890 All rights reserved.
891
892 Redistribution and use in source and binary forms, with or without
893@@ -36,6 +36,10 @@
894 /* Hopefully big enough to hold any serialized context */
895 #define MAX_CTX_LEN 4096
896
897+/* New context format flag values */
898+#define KRB5_CTX_FLAG_INITIATOR 0x00000001
899+#define KRB5_CTX_FLAG_CFX 0x00000002
900+#define KRB5_CTX_FLAG_ACCEPTOR_SUBKEY 0x00000004
901
902 int serialize_context_for_kernel(gss_ctx_id_t ctx, gss_buffer_desc *buf,
903 gss_OID mech);
904diff -puN utils/gssd/context_lucid.c~CITI_NFS4_ALL utils/gssd/context_lucid.c
905--- nfs-utils-1.1.1/utils/gssd/context_lucid.c~CITI_NFS4_ALL 2007-10-23 14:17:19.386681000 -0400
906+++ nfs-utils-1.1.1-kwc/utils/gssd/context_lucid.c 2007-10-23 14:17:19.465602000 -0400
907@@ -40,6 +40,7 @@
908 #include <stdio.h>
909 #include <syslog.h>
910 #include <string.h>
911+#include <errno.h>
912 #include "gss_util.h"
913 #include "gss_oids.h"
914 #include "err_util.h"
915@@ -113,15 +114,13 @@ prepare_krb5_rfc1964_buffer(gss_krb5_luc
916 * Note that the rfc1964 version only supports DES enctypes.
917 */
918 if (lctx->rfc1964_kd.ctx_key.type != 4) {
919- printerr(1, "prepare_krb5_rfc1964_buffer: "
920- "overriding heimdal keytype (%d => %d)\n",
921- lctx->rfc1964_kd.ctx_key.type, 4);
922+ printerr(2, "%s: overriding heimdal keytype (%d => %d)\n",
923+ __FUNCTION__, lctx->rfc1964_kd.ctx_key.type, 4);
924 lctx->rfc1964_kd.ctx_key.type = 4;
925 }
926 #endif
927- printerr(2, "prepare_krb5_rfc1964_buffer: serializing keys with "
928- "enctype %d and length %d\n",
929- lctx->rfc1964_kd.ctx_key.type,
930+ printerr(2, "%s: serializing keys with enctype %d and length %d\n",
931+ __FUNCTION__, lctx->rfc1964_kd.ctx_key.type,
932 lctx->rfc1964_kd.ctx_key.length);
933
934 /* derive the encryption key and copy it into buffer */
935@@ -152,15 +151,361 @@ out_err:
936 return -1;
937 }
938
939-static int
940-prepare_krb5_rfc_cfx_buffer(gss_krb5_lucid_context_v1_t *lctx,
941- gss_buffer_desc *buf)
942+/* XXX Hack alert! XXX Do NOT submit upstream! XXX */
943+/* XXX Hack alert! XXX Do NOT submit upstream! XXX */
944+
945+/* for 3DES */
946+#define KG_USAGE_SEAL 22
947+#define KG_USAGE_SIGN 23
948+#define KG_USAGE_SEQ 24
949+
950+/* for rfc???? */
951+#define KG_USAGE_ACCEPTOR_SEAL 22
952+#define KG_USAGE_ACCEPTOR_SIGN 23
953+#define KG_USAGE_INITIATOR_SEAL 24
954+#define KG_USAGE_INITIATOR_SIGN 25
955+
956+/* Lifted from mit src/lib/gssapi/krb5/gssapiP_krb5.h */
957+enum seal_alg {
958+ SEAL_ALG_NONE = 0xffff,
959+ SEAL_ALG_DES = 0x0000,
960+ SEAL_ALG_1 = 0x0001, /* not published */
961+ SEAL_ALG_MICROSOFT_RC4 = 0x0010, /* microsoft w2k; */
962+ SEAL_ALG_DES3KD = 0x0002
963+};
964+
965+#define KEY_USAGE_SEED_ENCRYPTION 0xAA
966+#define KEY_USAGE_SEED_INTEGRITY 0x55
967+#define KEY_USAGE_SEED_CHECKSUM 0x99
968+#define K5CLENGTH 5
97cc26d8 969+
0ac65518
JB
970+/* Flags for version 2 context flags */
971+#define KRB5_CTX_FLAG_INITIATOR 0x00000001
972+#define KRB5_CTX_FLAG_CFX 0x00000002
973+#define KRB5_CTX_FLAG_ACCEPTOR_SUBKEY 0x00000004
974+
975+/* XXX Hack alert! XXX Do NOT submit upstream! XXX */
976+/* XXX Hack alert! XXX Do NOT submit upstream! XXX */
977+/*
978+ * We don't have "legal" access to these MIT-only
979+ * structures located in libk5crypto
980+ */
981+extern void krb5int_enc_arcfour;
982+extern void krb5int_enc_des3;
983+extern void krb5int_enc_aes128;
984+extern void krb5int_enc_aes256;
985+extern int krb5_derive_key();
986+
987+static void
988+key_lucid_to_krb5(const gss_krb5_lucid_key_t *lin, krb5_keyblock *kout)
989 {
990- printerr(0, "ERROR: prepare_krb5_rfc_cfx_buffer: not implemented\n");
991- return -1;
992+ memset(kout, '\0', sizeof(kout));
993+#ifdef HAVE_KRB5
994+ kout->enctype = lin->type;
995+ kout->length = lin->length;
996+ kout->contents = lin->data;
997+#else
998+ kout->keytype = lin->type;
999+ kout->keyvalue.length = lin->length;
1000+ kout->keyvalue.data = lin->data;
1001+#endif
1002 }
1003
1004+static void
1005+key_krb5_to_lucid(const krb5_keyblock *kin, gss_krb5_lucid_key_t *lout)
1006+{
1007+ memset(lout, '\0', sizeof(lout));
1008+#ifdef HAVE_KRB5
1009+ lout->type = kin->enctype;
1010+ lout->length = kin->length;
1011+ lout->data = kin->contents;
1012+#else
1013+ lout->type = kin->keytype;
1014+ lout->length = kin->keyvalue.length;
1015+ memcpy(lout->data, kin->keyvalue.data, kin->keyvalue.length);
1016+#endif
1017+}
1018
1019+/* XXX Hack alert! XXX Do NOT submit upstream! XXX */
1020+/* XXX Hack alert! XXX Do NOT submit upstream! XXX */
1021+/* XXX Hack alert! XXX Do NOT submit upstream! XXX */
1022+/* XXX Hack alert! XXX Do NOT submit upstream! XXX */
1023+/*
1024+ * Function to derive a new key from a given key and given constant data.
1025+ */
1026+static krb5_error_code
1027+derive_key_lucid(const gss_krb5_lucid_key_t *in, gss_krb5_lucid_key_t *out,
1028+ int usage, char extra)
97cc26d8 1029+{
0ac65518
JB
1030+ krb5_error_code code;
1031+ unsigned char constant_data[K5CLENGTH];
1032+ krb5_data datain;
1033+ int keylength;
1034+ void *enc;
1035+ krb5_keyblock kin, kout; /* must send krb5_keyblock, not lucid! */
1036+#ifdef HAVE_HEIMDAL
1037+ krb5_context kcontext;
1038+ krb5_keyblock *outkey;
1039+#endif
14bcaf3a 1040+
0ac65518
JB
1041+ /*
1042+ * XXX Hack alert. We don't have "legal" access to these
1043+ * values and structures located in libk5crypto
1044+ */
1045+ switch (in->type) {
1046+ case ENCTYPE_DES3_CBC_SHA1:
1047+#ifdef HAVE_KRB5
1048+ case ENCTYPE_DES3_CBC_RAW:
1049+#endif
1050+ keylength = 24;
1051+#ifdef HAVE_KRB5
1052+ enc = &krb5int_enc_des3;
1053+#endif
1054+ break;
1055+ case ENCTYPE_AES128_CTS_HMAC_SHA1_96:
1056+ keylength = 16;
1057+#ifdef HAVE_KRB5
1058+ enc = &krb5int_enc_aes128;
1059+#endif
1060+ break;
1061+ case ENCTYPE_AES256_CTS_HMAC_SHA1_96:
1062+ keylength = 32;
1063+#ifdef HAVE_KRB5
1064+ enc = &krb5int_enc_aes256;
1065+#endif
1066+ break;
1067+ default:
1068+ code = KRB5_BAD_ENCTYPE;
1069+ goto out;
1070+ }
14bcaf3a 1071+
0ac65518
JB
1072+ /* allocate memory for output key */
1073+ if ((out->data = malloc(keylength)) == NULL) {
1074+ code = ENOMEM;
1075+ goto out;
97cc26d8 1076+ }
0ac65518
JB
1077+ out->length = keylength;
1078+ out->type = in->type;
1079+
1080+ /* Convert to correct format for call to krb5_derive_key */
1081+ key_lucid_to_krb5(in, &kin);
1082+ key_lucid_to_krb5(out, &kout);
1083+
1084+ datain.data = (char *) constant_data;
1085+ datain.length = K5CLENGTH;
1086+
1087+ ((char *)(datain.data))[0] = (usage>>24)&0xff;
1088+ ((char *)(datain.data))[1] = (usage>>16)&0xff;
1089+ ((char *)(datain.data))[2] = (usage>>8)&0xff;
1090+ ((char *)(datain.data))[3] = usage&0xff;
1091+
1092+ ((char *)(datain.data))[4] = (char) extra;
1093+
1094+#ifdef HAVE_KRB5
1095+ code = krb5_derive_key(enc, &kin, &kout, &datain);
1096+#else
1097+ if ((code = krb5_init_context(&kcontext))) {
1098+ }
1099+ code = krb5_derive_key(kcontext, &kin, in->type, constant_data, K5CLENGTH, &outkey);
1100+#endif
1101+ if (code) {
1102+ free(out->data);
1103+ out->data = NULL;
1104+ goto out;
1105+ }
1106+#ifdef HAVE_KRB5
1107+ key_krb5_to_lucid(&kout, out);
1108+#else
1109+ key_krb5_to_lucid(outkey, out);
1110+ krb5_free_keyblock(kcontext, outkey);
1111+ krb5_free_context(kcontext);
1112+#endif
1113+
1114+ out:
1115+ if (code)
1116+ printerr(0, "ERROR: %s: returning error %d (%s)\n",
1117+ __FUNCTION__, code, error_message(code));
1118+ return (code);
97cc26d8 1119+}
97cc26d8 1120+
14bcaf3a
JR
1121+
1122+/*
0ac65518
JB
1123+ * Prepare a new-style buffer, as defined in rfc4121 (a.k.a. cfx),
1124+ * to send to the kernel for newer encryption types -- or for DES3.
1125+ *
1126+ * The new format is:
1127+ *
1128+ * u32 initiate; ( whether we are the initiator or not )
1129+ * s32 endtime;
1130+ * u32 flags;
1131+ * #define KRB5_CTX_FLAG_INITIATOR 0x00000001
1132+ * #define KRB5_CTX_FLAG_CFX 0x00000002
1133+ * #define KRB5_CTX_FLAG_ACCEPTOR_SUBKEY 0x00000004
1134+ * u64 seq_send;
1135+ * u32 enctype; ( encrption type of keys )
1136+ * u32 size_of_each_key; ( size of each key in bytes )
1137+ * u32 number_of_keys; ( N -- should always be 3 for now )
1138+ * keydata-1; ( Ke )
1139+ * keydata-2; ( Ki )
1140+ * keydata-3; ( Kc )
1141+ *
1142+ */
1143+static int
1144+prepare_krb5_rfc4121_buffer(gss_krb5_lucid_context_v1_t *lctx,
1145+ gss_buffer_desc *buf)
1146+{
1147+ char *p, *end;
1148+ uint32_t v2_flags = 0;
1149+ gss_krb5_lucid_key_t enc_key;
1150+ gss_krb5_lucid_key_t derived_key;
1151+ gss_buffer_desc fakeoid;
1152+ uint32_t enctype;
1153+ uint32_t keysize;
1154+ uint32_t numkeys;
1155+
1156+ memset(&enc_key, 0, sizeof(enc_key));
1157+ memset(&fakeoid, 0, sizeof(fakeoid));
1158+
1159+ if (!(buf->value = calloc(1, MAX_CTX_LEN)))
1160+ goto out_err;
1161+ p = buf->value;
1162+ end = buf->value + MAX_CTX_LEN;
1163+
1164+ /* Version 2 */
1165+ if (WRITE_BYTES(&p, end, lctx->initiate)) goto out_err;
1166+ if (WRITE_BYTES(&p, end, lctx->endtime)) goto out_err;
1167+
1168+ if (lctx->initiate)
1169+ v2_flags |= KRB5_CTX_FLAG_INITIATOR;
1170+ if (lctx->protocol != 0)
1171+ v2_flags |= KRB5_CTX_FLAG_CFX;
1172+ if (lctx->protocol != 0 && lctx->cfx_kd.have_acceptor_subkey == 1)
1173+ v2_flags |= KRB5_CTX_FLAG_ACCEPTOR_SUBKEY;
1174+
1175+ if (WRITE_BYTES(&p, end, v2_flags)) goto out_err;
1176+
1177+ if (WRITE_BYTES(&p, end, lctx->send_seq)) goto out_err;
1178+
1179+ /* Protocol 0 here implies DES3 or RC4 */
1180+ printerr(2, "%s: protocol %d\n", __FUNCTION__, lctx->protocol);
1181+ if (lctx->protocol == 0) {
1182+ enctype = lctx->rfc1964_kd.ctx_key.type;
1183+#ifdef HAVE_HEIMDAL
1184+ /*
1185+ * The kernel gss code expects ENCTYPE_DES3_CBC_RAW (6) for
1186+ * 3des keys, but Heimdal key has ENCTYPE_DES3_CBC_SHA1 (16).
1187+ * Force the Heimdal enctype to 6.
1188+ */
1189+ if (enctype == ENCTYPE_DES3_CBC_SHA1) {
1190+ printerr(2, "%s: overriding heimdal keytype (%d => %d)\n",
1191+ __FUNCTION__, enctype, 6);
1192+
1193+ enctype = 6;
1194+ }
1195+#endif
1196+ keysize = lctx->rfc1964_kd.ctx_key.length;
1197+ numkeys = 3; /* XXX is always gonna be three? */
1198+ } else {
1199+ if (lctx->cfx_kd.have_acceptor_subkey) {
1200+ enctype = lctx->cfx_kd.acceptor_subkey.type;
1201+ keysize = lctx->cfx_kd.acceptor_subkey.length;
1202+ } else {
1203+ enctype = lctx->cfx_kd.ctx_key.type;
1204+ keysize = lctx->cfx_kd.ctx_key.length;
1205+ }
1206+ numkeys = 3;
1207+ }
1208+ printerr(2, "%s: serializing %d keys with enctype %d and size %d\n",
1209+ __FUNCTION__, numkeys, enctype, keysize);
1210+ if (WRITE_BYTES(&p, end, enctype)) goto out_err;
1211+ if (WRITE_BYTES(&p, end, keysize)) goto out_err;
1212+ if (WRITE_BYTES(&p, end, numkeys)) goto out_err;
1213+
1214+ if (lctx->protocol == 0) {
1215+ /* derive and send down: Ke, Ki, and Kc */
1216+ /* Ke */
1217+ if (write_bytes(&p, end, lctx->rfc1964_kd.ctx_key.data,
1218+ lctx->rfc1964_kd.ctx_key.length))
1219+ goto out_err;
1220+
1221+ /* Ki */
1222+ if (write_bytes(&p, end, lctx->rfc1964_kd.ctx_key.data,
1223+ lctx->rfc1964_kd.ctx_key.length))
1224+ goto out_err;
1225+
1226+ /* Kc */
1227+ if (derive_key_lucid(&lctx->rfc1964_kd.ctx_key,
1228+ &derived_key,
1229+ KG_USAGE_SIGN, KEY_USAGE_SEED_CHECKSUM))
1230+ goto out_err;
1231+ if (write_bytes(&p, end, derived_key.data,
1232+ derived_key.length))
1233+ goto out_err;
1234+ free(derived_key.data);
1235+ } else {
1236+ gss_krb5_lucid_key_t *keyptr;
1237+ uint32_t sign_usage, seal_usage;
1238+
1239+ if (lctx->cfx_kd.have_acceptor_subkey)
1240+ keyptr = &lctx->cfx_kd.acceptor_subkey;
1241+ else
1242+ keyptr = &lctx->cfx_kd.ctx_key;
1243+
1244+ if (lctx->initiate == 1) {
1245+ sign_usage = KG_USAGE_INITIATOR_SIGN;
1246+ seal_usage = KG_USAGE_INITIATOR_SEAL;
1247+ } else {
1248+ sign_usage = KG_USAGE_ACCEPTOR_SIGN;
1249+ seal_usage = KG_USAGE_ACCEPTOR_SEAL;
1250+ }
1251+
1252+ /* derive and send down: Ke, Ki, and Kc */
1253+
1254+ /* Ke */
1255+ if (derive_key_lucid(keyptr, &derived_key,
1256+ seal_usage, KEY_USAGE_SEED_ENCRYPTION))
1257+ goto out_err;
1258+ if (write_bytes(&p, end, derived_key.data,
1259+ derived_key.length))
1260+ goto out_err;
1261+ free(derived_key.data);
1262+
1263+ /* Ki */
1264+ if (derive_key_lucid(keyptr, &derived_key,
1265+ seal_usage, KEY_USAGE_SEED_INTEGRITY))
1266+ goto out_err;
1267+ if (write_bytes(&p, end, derived_key.data,
1268+ derived_key.length))
1269+ goto out_err;
1270+ free(derived_key.data);
1271+
1272+ /* Kc */
1273+ if (derive_key_lucid(keyptr, &derived_key,
1274+ sign_usage, KEY_USAGE_SEED_CHECKSUM))
1275+ goto out_err;
1276+ if (write_bytes(&p, end, derived_key.data,
1277+ derived_key.length))
1278+ goto out_err;
1279+ free(derived_key.data);
1280+ }
1281+
1282+ buf->length = p - (char *)buf->value;
1283+ return 0;
1284+
1285+out_err:
1286+ printerr(0, "ERROR: %s: failed serializing krb5 context for kernel\n",
1287+ __FUNCTION__);
1288+ if (buf->value) {
1289+ free(buf->value);
1290+ buf->value = NULL;
1291+ }
1292+ buf->length = 0;
1293+ if (enc_key.data) {
1294+ free(enc_key.data);
1295+ enc_key.data = NULL;
1296+ }
1297+ return -1;
1298+}
1299 int
1300 serialize_krb5_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf)
97cc26d8 1301 {
0ac65518
JB
1302@@ -170,7 +515,7 @@ serialize_krb5_ctx(gss_ctx_id_t ctx, gss
1303 gss_krb5_lucid_context_v1_t *lctx = 0;
1304 int retcode = 0;
97cc26d8 1305
0ac65518
JB
1306- printerr(2, "DEBUG: serialize_krb5_ctx: lucid version!\n");
1307+ printerr(2, "DEBUG: %s: lucid version!\n", __FUNCTION__);
1308 maj_stat = gss_export_lucid_sec_context(&min_stat, &ctx,
1309 1, &return_ctx);
1310 if (maj_stat != GSS_S_COMPLETE) {
1311@@ -192,11 +537,20 @@ serialize_krb5_ctx(gss_ctx_id_t ctx, gss
1312 break;
1313 }
97cc26d8 1314
0ac65518
JB
1315- /* Now lctx points to a lucid context that we can send down to kernel */
1316- if (lctx->protocol == 0)
1317+ /*
1318+ * Now lctx points to a lucid context that we can send down to kernel
1319+ *
1320+ * Note: we send down different information to the kernel depending
1321+ * on the protocol version and the enctyption type.
1322+ * For protocol version 0 with all enctypes besides DES3, we use
1323+ * the original format. For protocol version != 0 or DES3, we
1324+ * send down the new style information.
1325+ */
1326+
1327+ if (lctx->protocol == 0 && lctx->rfc1964_kd.ctx_key.type <= 4)
1328 retcode = prepare_krb5_rfc1964_buffer(lctx, buf);
1329 else
1330- retcode = prepare_krb5_rfc_cfx_buffer(lctx, buf);
1331+ retcode = prepare_krb5_rfc4121_buffer(lctx, buf);
97cc26d8 1332
0ac65518
JB
1333 maj_stat = gss_free_lucid_sec_context(&min_stat, ctx, return_ctx);
1334 if (maj_stat != GSS_S_COMPLETE) {
1335@@ -206,8 +560,8 @@ serialize_krb5_ctx(gss_ctx_id_t ctx, gss
1336 }
97cc26d8 1337
0ac65518
JB
1338 if (retcode) {
1339- printerr(1, "serialize_krb5_ctx: prepare_krb5_*_buffer "
1340- "failed (retcode = %d)\n", retcode);
1341+ printerr(1, "%s: prepare_krb5_*_buffer failed (retcode = %d)\n",
1342+ __FUNCTION__, retcode);
1343 goto out_err;
1344 }
97cc26d8 1345
0ac65518
JB
1346@@ -217,4 +571,7 @@ out_err:
1347 printerr(0, "ERROR: failed serializing krb5 context for kernel\n");
1348 return -1;
1349 }
97cc26d8 1350+
97cc26d8 1351+
0ac65518
JB
1352+
1353 #endif /* HAVE_LUCID_CONTEXT_SUPPORT */
1354diff -puN utils/gssd/context_mit.c~CITI_NFS4_ALL utils/gssd/context_mit.c
1355--- nfs-utils-1.1.1/utils/gssd/context_mit.c~CITI_NFS4_ALL 2007-10-23 14:17:19.441626000 -0400
1356+++ nfs-utils-1.1.1-kwc/utils/gssd/context_mit.c 2007-10-23 14:17:19.473594000 -0400
1357@@ -1,5 +1,5 @@
97cc26d8 1358 /*
0ac65518
JB
1359- Copyright (c) 2004 The Regents of the University of Michigan.
1360+ Copyright (c) 2004-2006 The Regents of the University of Michigan.
1361 All rights reserved.
97cc26d8 1362
0ac65518
JB
1363 Redistribution and use in source and binary forms, with or without
1364@@ -36,6 +36,7 @@
1365 #include <stdio.h>
1366 #include <syslog.h>
1367 #include <string.h>
1368+#include <errno.h>
1369 #include <gssapi/gssapi.h>
1370 #include <rpc/rpc.h>
1371 #include <rpc/auth_gss.h>
1372@@ -50,8 +51,7 @@
1373 /* XXX argggg, there's gotta be a better way than just duplicating this
1374 * whole struct. Unfortunately, this is in a "private" header file,
1375 * so this is our best choice at this point :-/
1376- *
1377- * XXX Does this match the Heimdal definition? */
1378+ */
1379
1380 typedef struct _krb5_gss_ctx_id_rec {
1381 unsigned int initiate : 1; /* nonzero if initiating, zero if accepting */
1382@@ -139,6 +139,124 @@ write_keyblock(char **p, char *end, stru
97cc26d8
JB
1383 }
1384
0ac65518
JB
1385 /*
1386+ * XXX Hack alert! XXX Do NOT submit upstream!
1387+ * XXX Hack alert! XXX Do NOT submit upstream!
1388+ *
1389+ * We shouldn't be using these definitions
1390+ *
1391+ * XXX Hack alert! XXX Do NOT submit upstream!
1392+ * XXX Hack alert! XXX Do NOT submit upstream!
1393+ */
1394+/* for 3DES */
1395+#define KG_USAGE_SEAL 22
1396+#define KG_USAGE_SIGN 23
1397+#define KG_USAGE_SEQ 24
1398+
1399+/* for rfc???? */
1400+#define KG_USAGE_ACCEPTOR_SEAL 22
1401+#define KG_USAGE_ACCEPTOR_SIGN 23
1402+#define KG_USAGE_INITIATOR_SEAL 24
1403+#define KG_USAGE_INITIATOR_SIGN 25
1404+
1405+/* Lifted from mit src/lib/gssapi/krb5/gssapiP_krb5.h */
1406+enum seal_alg {
1407+ SEAL_ALG_NONE = 0xffff,
1408+ SEAL_ALG_DES = 0x0000,
1409+ SEAL_ALG_1 = 0x0001, /* not published */
1410+ SEAL_ALG_MICROSOFT_RC4 = 0x0010, /* microsoft w2k; */
1411+ SEAL_ALG_DES3KD = 0x0002
1412+};
1413+
1414+#define KEY_USAGE_SEED_ENCRYPTION 0xAA
1415+#define KEY_USAGE_SEED_INTEGRITY 0x55
1416+#define KEY_USAGE_SEED_CHECKSUM 0x99
1417+#define K5CLENGTH 5
1418+
1419+extern void krb5_enc_des3;
1420+extern void krb5int_enc_des3;
1421+extern void krb5int_enc_arcfour;
1422+extern void krb5int_enc_aes128;
1423+extern void krb5int_enc_aes256;
1424+extern int krb5_derive_key();
1425+
1426+/*
1427+ * XXX Hack alert! XXX Do NOT submit upstream!
1428+ * XXX Hack alert! XXX Do NOT submit upstream!
1429+ *
1430+ * We should be passing down a single key to the kernel
1431+ * and it should be deriving the other keys. We cannot
1432+ * depend on any of this stuff being accessible in the
1433+ * future.
1434+ *
1435+ * XXX Hack alert! XXX Do NOT submit upstream!
1436+ * XXX Hack alert! XXX Do NOT submit upstream!
1437+ */
1438+/*
1439+ * Function to derive a new key from a given key and given constant data.
1440+ */
1441+static krb5_error_code
1442+derive_key(const krb5_keyblock *in, krb5_keyblock *out, int usage, char extra)
97cc26d8 1443+{
0ac65518
JB
1444+ krb5_error_code code;
1445+ unsigned char constant_data[K5CLENGTH];
1446+ krb5_data datain;
1447+ int keylength;
1448+ void *enc;
97cc26d8 1449+
0ac65518
JB
1450+ switch (in->enctype) {
1451+#ifdef ENCTYPE_DES3_CBC_RAW
1452+ case ENCTYPE_DES3_CBC_RAW:
1453+ keylength = 24;
1454+/* Extra hack, the structure was renamed as rc4 was added... */
1455+#if defined(ENCTYPE_ARCFOUR_HMAC)
1456+ enc = &krb5int_enc_des3;
1457+#else
1458+ enc = &krb5_enc_des3;
1459+#endif
1460+ break;
1461+#endif
1462+#ifdef ENCTYPE_ARCFOUR_HMAC
1463+ case ENCTYPE_ARCFOUR_HMAC:
1464+ keylength = 16;
1465+ enc = &krb5int_enc_arcfour;
1466+ break;
1467+#endif
1468+ default:
1469+ code = KRB5_BAD_ENCTYPE;
1470+ goto out;
97cc26d8 1471+ }
0ac65518
JB
1472+
1473+ /* allocate memory for output key */
1474+ if ((out->contents = malloc(keylength)) == NULL) {
1475+ code = ENOMEM;
1476+ goto out;
1477+ }
1478+ out->length = keylength;
1479+ out->enctype = in->enctype;
1480+
1481+ datain.data = (char *) constant_data;
1482+ datain.length = K5CLENGTH;
1483+
1484+ datain.data[0] = (usage>>24)&0xff;
1485+ datain.data[1] = (usage>>16)&0xff;
1486+ datain.data[2] = (usage>>8)&0xff;
1487+ datain.data[3] = usage&0xff;
1488+
1489+ datain.data[4] = (char) extra;
1490+
1491+ if ((code = krb5_derive_key(enc, in, out, &datain))) {
1492+ free(out->contents);
1493+ out->contents = NULL;
97cc26d8
JB
1494+ }
1495+
0ac65518
JB
1496+ out:
1497+ if (code)
1498+ printerr(0, "ERROR: derive_key returning error %d (%s)\n",
1499+ code, error_message(code));
1500+ return (code);
97cc26d8
JB
1501+}
1502+
0ac65518
JB
1503+/*
1504 * We really shouldn't know about glue-layer context structure, but
1505 * we need to get at the real krb5 context pointer. This should be
1506 * removed as soon as we say there is no support for MIT Kerberos
1507@@ -154,48 +272,124 @@ serialize_krb5_ctx(gss_ctx_id_t ctx, gss
97cc26d8 1508 {
0ac65518
JB
1509 krb5_gss_ctx_id_t kctx = ((gss_union_ctx_id_t)ctx)->internal_ctx_id;
1510 char *p, *end;
1511- static int constant_one = 1;
1512 static int constant_zero = 0;
1513+ static int constant_one = 1;
1514+ static int constant_two = 2;
1515 uint32_t word_seq_send;
1516+ u_int64_t seq_send_64bit;
1517+ uint32_t v2_flags = 0;
1518+ krb5_keyblock derived_key;
1519+ uint32_t numkeys;
1520
1521 if (!(buf->value = calloc(1, MAX_CTX_LEN)))
1522 goto out_err;
1523 p = buf->value;
1524 end = buf->value + MAX_CTX_LEN;
1525
1526- if (kctx->initiate) {
1527- if (WRITE_BYTES(&p, end, constant_one)) goto out_err;
1528- }
1529- else {
1530- if (WRITE_BYTES(&p, end, constant_zero)) goto out_err;
1531- }
1532- if (kctx->seed_init) {
1533- if (WRITE_BYTES(&p, end, constant_one)) goto out_err;
1534- }
1535- else {
1536- if (WRITE_BYTES(&p, end, constant_zero)) goto out_err;
1537- }
1538- if (write_bytes(&p, end, &kctx->seed, sizeof(kctx->seed)))
1539+ switch (kctx->sealalg) {
1540+ case SEAL_ALG_DES:
1541+ /* Old format of context to the kernel */
1542+ if (kctx->initiate) {
1543+ if (WRITE_BYTES(&p, end, constant_one)) goto out_err;
1544+ }
1545+ else {
1546+ if (WRITE_BYTES(&p, end, constant_zero)) goto out_err;
1547+ }
1548+ if (kctx->seed_init) {
1549+ if (WRITE_BYTES(&p, end, constant_one)) goto out_err;
1550+ }
1551+ else {
1552+ if (WRITE_BYTES(&p, end, constant_zero)) goto out_err;
1553+ }
1554+ if (write_bytes(&p, end, &kctx->seed, sizeof(kctx->seed)))
1555+ goto out_err;
1556+ if (WRITE_BYTES(&p, end, kctx->signalg)) goto out_err;
1557+ if (WRITE_BYTES(&p, end, kctx->sealalg)) goto out_err;
1558+ if (WRITE_BYTES(&p, end, kctx->endtime)) goto out_err;
1559+ word_seq_send = kctx->seq_send;
1560+ if (WRITE_BYTES(&p, end, word_seq_send)) goto out_err;
1561+ if (write_oid(&p, end, kctx->mech_used)) goto out_err;
1562+
1563+ printerr(2, "serialize_krb5_ctx: serializing keys with "
1564+ "enctype %d and length %d\n",
1565+ kctx->enc->enctype, kctx->enc->length);
1566+
1567+ if (write_keyblock(&p, end, kctx->enc)) goto out_err;
1568+ if (write_keyblock(&p, end, kctx->seq)) goto out_err;
1569+ break;
1570+ case SEAL_ALG_MICROSOFT_RC4:
1571+ case SEAL_ALG_DES3KD:
1572+ /* New format of context to the kernel */
1573+ /* s32 endtime;
1574+ * u32 flags;
1575+ * #define KRB5_CTX_FLAG_INITIATOR 0x00000001
1576+ * #define KRB5_CTX_FLAG_CFX 0x00000002
1577+ * #define KRB5_CTX_FLAG_ACCEPTOR_SUBKEY 0x00000004
1578+ * u64 seq_send;
1579+ * u32 enctype;
1580+ * u32 size_of_each_key; ( size in bytes )
1581+ * u32 number_of_keys; ( N (assumed to be 3 for now) )
1582+ * keydata-1; ( Ke (Kenc for DES3) )
1583+ * keydata-2; ( Ki (Kseq for DES3) )
1584+ * keydata-3; ( Kc (derived checksum key) )
1585+ */
1586+ if (kctx->initiate) {
1587+ if (WRITE_BYTES(&p, end, constant_one)) goto out_err;
1588+ }
1589+ else {
1590+ if (WRITE_BYTES(&p, end, constant_zero)) goto out_err;
1591+ }
1592+ if (WRITE_BYTES(&p, end, kctx->endtime)) goto out_err;
1593+
1594+ /* Only applicable flag for this is initiator */
1595+ if (kctx->initiate) v2_flags |= KRB5_CTX_FLAG_INITIATOR;
1596+ if (WRITE_BYTES(&p, end, v2_flags)) goto out_err;
1597+
1598+ seq_send_64bit = kctx->seq_send;
1599+ if (WRITE_BYTES(&p, end, seq_send_64bit)) goto out_err;
1600+
1601+ if (WRITE_BYTES(&p, end, kctx->enc->enctype)) goto out_err;
1602+ if (WRITE_BYTES(&p, end, kctx->enc->length)) goto out_err;
1603+ numkeys = 3;
1604+ if (WRITE_BYTES(&p, end, numkeys)) goto out_err;
1605+ printerr(2, "serialize_krb5_ctx: serializing %d keys with "
1606+ "enctype %d and size %d\n",
1607+ numkeys, kctx->enc->enctype, kctx->enc->length);
1608+
1609+ /* Ke */
1610+ if (write_bytes(&p, end, kctx->enc->contents,
1611+ kctx->enc->length))
1612+ goto out_err;
1613+
1614+ /* Ki */
1615+ if (write_bytes(&p, end, kctx->enc->contents,
1616+ kctx->enc->length))
1617+ goto out_err;
1618+
1619+ /* Kc */
1620+ if (derive_key(kctx->seq, &derived_key,
1621+ KG_USAGE_SIGN, KEY_USAGE_SEED_CHECKSUM))
1622+ goto out_err;
1623+ if (write_bytes(&p, end, derived_key.contents,
1624+ derived_key.length))
1625+ goto out_err;
1626+ free(derived_key.contents);
1627+ break;
1628+ default:
1629+ printerr(0, "ERROR: serialize_krb5_ctx: unsupported seal "
1630+ "algorithm %d\n", kctx->sealalg);
1631 goto out_err;
1632- if (WRITE_BYTES(&p, end, kctx->signalg)) goto out_err;
1633- if (WRITE_BYTES(&p, end, kctx->sealalg)) goto out_err;
1634- if (WRITE_BYTES(&p, end, kctx->endtime)) goto out_err;
1635- word_seq_send = kctx->seq_send;
1636- if (WRITE_BYTES(&p, end, word_seq_send)) goto out_err;
1637- if (write_oid(&p, end, kctx->mech_used)) goto out_err;
1638-
1639- printerr(2, "serialize_krb5_ctx: serializing keys with "
1640- "enctype %d and length %d\n",
1641- kctx->enc->enctype, kctx->enc->length);
1642-
1643- if (write_keyblock(&p, end, kctx->enc)) goto out_err;
1644- if (write_keyblock(&p, end, kctx->seq)) goto out_err;
1645+ }
1646
1647 buf->length = p - (char *)buf->value;
1648 return 0;
1649+
1650 out_err:
1651 printerr(0, "ERROR: failed serializing krb5 context for kernel\n");
1652- if (buf->value) free(buf->value);
1653+ if (buf->value) {
1654+ free(buf->value);
1655+ }
1656+ buf->value = NULL;
1657 buf->length = 0;
1658 return -1;
1659 }
This page took 0.217763 seconds and 4 git commands to generate.