]> git.pld-linux.org Git - packages/nfs-utils.git/blob - nfs-utils-CITI_NFS4.patch
- outdated it seems
[packages/nfs-utils.git] / nfs-utils-CITI_NFS4.patch
1
2
3 The complete set of CITI nfs-utils patches rolled into one patch.
4
5 Changes since 1.1.0-CITI_NFS4_ALL-2:
6
7  * Update to nfs-utils-1.1.1
8
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).
12
13
14
15
16 ---
17
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(-)
35
36 diff -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");
60         }
61  
62 +       va_end(args2);
63 +
64         if (kind == L_FATAL)
65                 exit(1);
66  }
67 diff -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"
75  
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)
107  {
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
122         }
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
131  }
132  #endif
133  
134 +static int
135 +get_hostbased_client_name(gss_name_t client_name, gss_OID mech,
136 +                         char **hostbased_name)
137 +{
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;
143 +
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;
152 +       }
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;
158 +       }
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;
164 +       }
165 +       /* For SPKM3, do ??? */
166 +       res = 0;
167 +out_rel_buf:
168 +       gss_release_buffer(&min_stat, &name);
169 +out_err:
170 +       return res;
171 +}
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 +       }
196  
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;
205         }
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  
224 diff -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;
233  
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 +       }
252 +
253         init_client_list();
254  
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()
267                 }
268         }
269         close(fd);
270 +       if (fd_cb != -1)
271 +               close(fd_cb);
272         return;
273  }
274 diff -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);
313 +
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;
322 +
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;
416 +
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
427  
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];
435  
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;
444  }
445  
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)
491 +{
492 +       int retval = -1;
493 +
494 +       retval = process_pipedir(pipefs_nfsdir);
495 +       if (retval)
496 +               printerr(0, "ERROR: processing %s\n", pipefs_nfsdir);
497 +
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);
505 +       }
506 +
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;
515         }
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;
524  
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;
539 diff -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();
571 diff -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);
598 diff -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;
630  }
631  
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 -
684  /*
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
693 + */
694 +static int
695 +parse_enctypes(char *enctypes)
696 +{
697 +       int n = 0;
698 +       char *curr, *comma;
699 +       int i;
700 +
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;
706 +       }
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;
715 +       }
716 +       /* If no more commas and we're not at the end, there's one more value */
717 +       if (*curr != '\0')
718 +               n++;
719 +
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;
739 +}
740 +
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
758 + */
759 +
760 +int
761 +limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid)
762 +{
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;
781 +       }
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;
802 +}
803 +#endif /* HAVE_SET_ALLOWABLE_ENCTYPES */
804 +
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)
811 +{
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;
821 +
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);
863 +
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);
869 +       }
870 +}
871 diff -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);
883 diff -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);
904 diff -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
969 +
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)
1029 +{
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
1040 +
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 +       }
1071 +
1072 +       /* allocate memory for output key */
1073 +       if ((out->data = malloc(keylength)) == NULL) {
1074 +               code = ENOMEM;
1075 +               goto out;
1076 +       }
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);
1119 +}
1120 +
1121 +
1122 +/*
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)
1301  {
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;
1305  
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         }
1314  
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);
1332  
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         }
1337  
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         }
1345  
1346 @@ -217,4 +571,7 @@ out_err:
1347         printerr(0, "ERROR: failed serializing krb5 context for kernel\n");
1348         return -1;
1349  }
1350 +
1351 +
1352 +
1353  #endif /* HAVE_LUCID_CONTEXT_SUPPORT */
1354 diff -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 @@
1358  /*
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.
1362  
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
1383  }
1384  
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)
1443 +{
1444 +       krb5_error_code code;
1445 +       unsigned char constant_data[K5CLENGTH];
1446 +       krb5_data datain;
1447 +       int keylength;
1448 +       void *enc;
1449 +
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;
1471 +       }
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;
1494 +       }
1495 +
1496 +  out:
1497 +       if (code)
1498 +               printerr(0, "ERROR: derive_key returning error %d (%s)\n",
1499 +                        code, error_message(code));
1500 +       return (code);
1501 +}
1502 +
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
1508  {
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.600338 seconds and 3 git commands to generate.