From 7ab310da9c846eb93f7adb06f46e71eb95024b58 Mon Sep 17 00:00:00 2001 From: Paul Park Date: Tue, 29 Aug 1995 18:34:36 +0000 Subject: [PATCH] Add keytab serialization support git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@6616 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/krb5/keytab/ChangeLog | 6 + src/lib/krb5/keytab/file/.Sanitize | 1 + src/lib/krb5/keytab/file/ChangeLog | 8 + src/lib/krb5/keytab/file/Makefile.in | 6 +- src/lib/krb5/keytab/file/ktf_defops.c | 2 + src/lib/krb5/keytab/file/ktf_ops.c | 2 + src/lib/krb5/keytab/file/ktf_resolv.c | 2 +- src/lib/krb5/keytab/file/ktf_wops.c | 2 + src/lib/krb5/keytab/file/ktf_wreslv.c | 2 +- src/lib/krb5/keytab/file/ser_ktf.c | 321 ++++++++++++++++++++++++++ src/lib/krb5/keytab/ktbase.c | 86 +++++++ 11 files changed, 434 insertions(+), 4 deletions(-) create mode 100644 src/lib/krb5/keytab/file/ser_ktf.c diff --git a/src/lib/krb5/keytab/ChangeLog b/src/lib/krb5/keytab/ChangeLog index 28c40dce2..4a853fdb7 100644 --- a/src/lib/krb5/keytab/ChangeLog +++ b/src/lib/krb5/keytab/ChangeLog @@ -1,3 +1,9 @@ + +Tue Aug 29 13:37:56 EDT 1995 Paul Park (pjpark@mit.edu) + * ktbase.c - Add routines to deal with externalizing krb5_keytab. These + search the registered keytab types for a match and dispatch + via the serializer handle. + Fri Aug 4 21:48:41 1995 Tom Yu * read_servi.c (krb5_kt_read_service_key): add more parens to shut diff --git a/src/lib/krb5/keytab/file/.Sanitize b/src/lib/krb5/keytab/file/.Sanitize index 4851eb8cc..7cb34b349 100644 --- a/src/lib/krb5/keytab/file/.Sanitize +++ b/src/lib/krb5/keytab/file/.Sanitize @@ -43,6 +43,7 @@ ktf_util.c ktf_wops.c ktf_wreslv.c ktfile.h +ser_ktf.c Things-to-lose: diff --git a/src/lib/krb5/keytab/file/ChangeLog b/src/lib/krb5/keytab/file/ChangeLog index 7f22f2710..789ac1321 100644 --- a/src/lib/krb5/keytab/file/ChangeLog +++ b/src/lib/krb5/keytab/file/ChangeLog @@ -1,3 +1,11 @@ + +Tue Aug 29 13:38:58 EDT 1995 Paul Park (pjpark@mit.edu) + * Makefile.in, .Sanitize, ser_ktf.c - Add new module to support + serialization of [WR]FILE keytabs. + * ktf_{defops,ops,wops}.c - Add serializer entry. + * ktf_{resolv,wreslv}.c - Set magic number in successfully resolved + keytab. + Wed Aug 16 02:45:19 1995 Chris Provenzano * ktf_util.c: Pass fds to krb5_lock_file() and krb5_unlock_file() diff --git a/src/lib/krb5/keytab/file/Makefile.in b/src/lib/krb5/keytab/file/Makefile.in index 39e2af5f3..267a29de1 100644 --- a/src/lib/krb5/keytab/file/Makefile.in +++ b/src/lib/krb5/keytab/file/Makefile.in @@ -22,7 +22,8 @@ SRCS= \ $(srcdir)/ktf_defops.c \ $(srcdir)/ktf_g_name.c \ $(srcdir)/ktf_remove.c \ - $(srcdir)/ktf_util.c + $(srcdir)/ktf_util.c \ + $(srcdir)/ser_ktf.c OBJS = \ ktf_add.$(OBJEXT) \ @@ -38,7 +39,8 @@ OBJS = \ ktf_ops.$(OBJEXT) \ ktf_wops.$(OBJEXT) \ ktf_wreslv.$(OBJEXT) \ - ktf_defops.$(OBJEXT) + ktf_defops.$(OBJEXT) \ + ser_ktf.$(OBJEXT) all:: all-$(WHAT) diff --git a/src/lib/krb5/keytab/file/ktf_defops.c b/src/lib/krb5/keytab/file/ktf_defops.c index 315860b07..7b905b97a 100644 --- a/src/lib/krb5/keytab/file/ktf_defops.c +++ b/src/lib/krb5/keytab/file/ktf_defops.c @@ -27,6 +27,7 @@ #include "k5-int.h" #include "ktfile.h" +extern krb5_ser_entry krb5_ktfile_ser_entry; krb5_kt_ops krb5_kt_dfl_ops = { 0, "FILE", /* Prefix -- this string should not appear anywhere else! */ @@ -39,4 +40,5 @@ krb5_kt_ops krb5_kt_dfl_ops = { krb5_ktfile_end_get, 0, 0, + (void *) &krb5_ktfile_ser_entry }; diff --git a/src/lib/krb5/keytab/file/ktf_ops.c b/src/lib/krb5/keytab/file/ktf_ops.c index 9883de938..bc9d03882 100644 --- a/src/lib/krb5/keytab/file/ktf_ops.c +++ b/src/lib/krb5/keytab/file/ktf_ops.c @@ -27,6 +27,7 @@ #include "k5-int.h" #include "ktfile.h" +extern krb5_ser_entry krb5_ktfile_ser_entry; struct _krb5_kt_ops krb5_ktf_ops = { 0, "FILE", /* Prefix -- this string should not appear anywhere else! */ @@ -39,4 +40,5 @@ struct _krb5_kt_ops krb5_ktf_ops = { krb5_ktfile_end_get, 0, 0, + (void *) &krb5_ktfile_ser_entry }; diff --git a/src/lib/krb5/keytab/file/ktf_resolv.c b/src/lib/krb5/keytab/file/ktf_resolv.c index e9e3827a6..415f3c5f3 100644 --- a/src/lib/krb5/keytab/file/ktf_resolv.c +++ b/src/lib/krb5/keytab/file/ktf_resolv.c @@ -55,7 +55,7 @@ krb5_ktfile_resolve(context, name, id) data->openf = 0; (*id)->data = (krb5_pointer)data; - + (*id)->magic = KV5M_KEYTAB; return(0); } diff --git a/src/lib/krb5/keytab/file/ktf_wops.c b/src/lib/krb5/keytab/file/ktf_wops.c index 98edcbf87..d55f9808c 100644 --- a/src/lib/krb5/keytab/file/ktf_wops.c +++ b/src/lib/krb5/keytab/file/ktf_wops.c @@ -27,6 +27,7 @@ #include "k5-int.h" #include "ktfile.h" +extern krb5_ser_entry krb5_ktfile_ser_entry; struct _krb5_kt_ops krb5_ktf_writable_ops = { 0, "WRFILE", /* Prefix -- this string should not appear anywhere else! */ @@ -39,4 +40,5 @@ struct _krb5_kt_ops krb5_ktf_writable_ops = { krb5_ktfile_end_get, krb5_ktfile_add, krb5_ktfile_remove, + (void *) &krb5_ktfile_ser_entry }; diff --git a/src/lib/krb5/keytab/file/ktf_wreslv.c b/src/lib/krb5/keytab/file/ktf_wreslv.c index 684f8d558..9df5922a9 100644 --- a/src/lib/krb5/keytab/file/ktf_wreslv.c +++ b/src/lib/krb5/keytab/file/ktf_wreslv.c @@ -55,7 +55,7 @@ krb5_ktfile_wresolve(context, name, id) data->openf = 0; (*id)->data = (krb5_pointer)data; - + (*id)->magic = KV5M_KEYTAB; return(0); } diff --git a/src/lib/krb5/keytab/file/ser_ktf.c b/src/lib/krb5/keytab/file/ser_ktf.c new file mode 100644 index 000000000..2be7b708a --- /dev/null +++ b/src/lib/krb5/keytab/file/ser_ktf.c @@ -0,0 +1,321 @@ +/* + * lib/krb5/keytab/file/ser_ktf.c + * + * Copyright 1995 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + */ + +/* + * ser_ktf.c - Serialize keytab file context for subsequent reopen. + */ +#include "k5-int.h" +#include "ktfile.h" + +static const char ktfile_def_name[] = "."; + +/* + * Routines to deal with externalizing krb5_keytab for [WR]FILE: variants. + * krb5_ktf_keytab_size(); + * krb5_ktf_keytab_externalize(); + * krb5_ktf_keytab_internalize(); + */ +static krb5_error_code krb5_ktf_keytab_size + KRB5_PROTOTYPE((krb5_context, krb5_pointer, size_t *)); +static krb5_error_code krb5_ktf_keytab_externalize + KRB5_PROTOTYPE((krb5_context, krb5_pointer, krb5_octet **, size_t *)); +static krb5_error_code krb5_ktf_keytab_internalize + KRB5_PROTOTYPE((krb5_context,krb5_pointer *, krb5_octet **, size_t *)); + +/* + * Serialization entry for this type. + */ +const krb5_ser_entry krb5_ktfile_ser_entry = { + KV5M_KEYTAB, /* Type */ + krb5_ktf_keytab_size, /* Sizer routine */ + krb5_ktf_keytab_externalize, /* Externalize routine */ + krb5_ktf_keytab_internalize /* Internalize routine */ +}; + +/* + * krb5_ktf_keytab_size() - Determine the size required to externalize + * this krb5_keytab variant. + */ +static krb5_error_code +krb5_ktf_keytab_size(kcontext, arg, sizep) + krb5_context kcontext; + krb5_pointer arg; + size_t *sizep; +{ + krb5_error_code kret; + krb5_keytab keytab; + size_t required; + krb5_ktfile_data *ktdata; + + kret = EINVAL; + if ((keytab = (krb5_keytab) arg)) { + /* + * Saving FILE: variants of krb5_keytab requires at minimum: + * krb5_int32 for KV5M_KEYTAB + * krb5_int32 for length of keytab name. + * krb5_int32 for file status. + * krb5_int32 for file position. + * krb5_int32 for file position. + * krb5_int32 for version. + * krb5_int32 for KV5M_KEYTAB + */ + required = sizeof(krb5_int32) * 7; + if (keytab->ops && keytab->ops->prefix) + required += (strlen(keytab->ops->prefix)+1); + + /* + * The keytab name is formed as follows: + * : + * If there's no name, we use a default name so that we have something + * to call krb5_keytab_resolve with. + */ + ktdata = (krb5_ktfile_data *) keytab->data; + required += strlen((ktdata && ktdata->name) ? + ktdata->name : ktfile_def_name); + kret = 0; + + if (!kret) + *sizep += required; + } + return(kret); +} + +/* + * krb5_ktf_keytab_externalize() - Externalize the krb5_keytab. + */ +static krb5_error_code +krb5_ktf_keytab_externalize(kcontext, arg, buffer, lenremain) + krb5_context kcontext; + krb5_pointer arg; + krb5_octet **buffer; + size_t *lenremain; +{ + krb5_error_code kret; + krb5_keytab keytab; + size_t required; + krb5_octet *bp; + size_t remain; + krb5_ktfile_data *ktdata; + krb5_int32 file_is_open; + krb5_int32 file_pos[2]; + char *ktname; + size_t namelen; + char *fnamep; + + required = 0; + bp = *buffer; + remain = *lenremain; + kret = EINVAL; + if ((keytab = (krb5_keytab) arg)) { + kret = ENOMEM; + if (!krb5_ktf_keytab_size(kcontext, arg, &required) && + (required <= remain)) { + /* Our identifier */ + (void) krb5_ser_pack_int32(KV5M_KEYTAB, &bp, &remain); + + ktdata = (krb5_ktfile_data *) keytab->data; + file_is_open = 0; + file_pos[0] = 0; + file_pos[1] = 0; + + /* Calculate the length of the name */ + namelen = (keytab->ops && keytab->ops->prefix) ? + strlen(keytab->ops->prefix)+1 : 0; + if (ktdata && ktdata->name) + fnamep = ktdata->name; + else + fnamep = (char *) ktfile_def_name; + namelen += (strlen(fnamep)+1); + + if ((ktname = (char *) malloc(namelen))) { + /* Format the keytab name. */ + if (keytab->ops && keytab->ops->prefix) + sprintf(ktname, "%s:%s", keytab->ops->prefix, fnamep); + + else + strcpy(ktname, fnamep); + + /* Fill in the file-specific keytab information. */ + if (ktdata) { + if (ktdata->openf) { + long fpos; + int fflags; + + file_is_open = 1; + fflags = fcntl(fileno(ktdata->openf), F_GETFL, 0); + if (fflags > 0) + file_is_open |= ((fflags & O_ACCMODE) << 1); + fpos = ftell(ktdata->openf); +#if SIZEOF_LONG == 4 + file_pos[0] = fpos; +#else /* SIZEOF_LONG == 4 */ + file_pos[0] = fpos & 0xffffffff; + file_pos[1] = (fpos >> 32) & 0xffffffff; +#endif /* SIZEOF_LONG == 4 */ + } + } + + /* Put the length of the file name */ + (void) krb5_ser_pack_int32((krb5_int32) strlen(ktname), + &bp, &remain); + + /* Put the name */ + (void) krb5_ser_pack_bytes((krb5_octet *) ktname, + strlen(ktname), + &bp, &remain); + + /* Put the file open flag */ + (void) krb5_ser_pack_int32(file_is_open, &bp, &remain); + + /* Put the file position */ + (void) krb5_ser_pack_int32(file_pos[0], &bp, &remain); + (void) krb5_ser_pack_int32(file_pos[1], &bp, &remain); + + /* Put the version */ + (void) krb5_ser_pack_int32((krb5_int32) ((ktdata) ? + ktdata->version : 0), + &bp, &remain); + + /* Put the trailer */ + (void) krb5_ser_pack_int32(KV5M_KEYTAB, &bp, &remain); + kret = 0; + *buffer = bp; + *lenremain = remain; + free(ktname); + } + } + } + return(kret); +} + +/* + * krb5_ktf_keytab_internalize() - Internalize the krb5_ktf_keytab. + */ +static krb5_error_code +krb5_ktf_keytab_internalize(kcontext, argp, buffer, lenremain) + krb5_context kcontext; + krb5_pointer *argp; + krb5_octet **buffer; + size_t *lenremain; +{ + krb5_error_code kret; + krb5_keytab keytab; + krb5_int32 ibuf; + krb5_octet *bp; + size_t remain; + char *ktname; + krb5_ktfile_data *ktdata; + krb5_int32 file_is_open; + krb5_int32 foffbuf[2]; + + bp = *buffer; + remain = *lenremain; + kret = EINVAL; + /* Read our magic number */ + if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) + ibuf = 0; + if (ibuf == KV5M_KEYTAB) { + kret = ENOMEM; + + /* Get the length of the keytab name */ + kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); + + if (!kret && + (ktname = (char *) malloc((size_t) (ibuf+1))) && + !(kret = krb5_ser_unpack_bytes((krb5_octet *) ktname, + (size_t) ibuf, + &bp, &remain))) { + ktname[ibuf] = '\0'; + kret = krb5_kt_resolve(kcontext, ktname, &keytab); + if (!kret) { + kret = ENOMEM; + ktdata = (krb5_ktfile_data *) keytab->data; + if (!ktdata) { + /* XXX */ + keytab->data = (void *) malloc(sizeof(krb5_ktfile_data)); + ktdata = (krb5_ktfile_data *) keytab->data; + memset(ktdata, 0, sizeof(krb5_ktfile_data)); + if (strchr(ktname, (int) ':')) + ktdata->name = strdup(strchr(ktname, (int) ':')+1); + else + ktdata->name = strdup(ktname); + } + if (ktdata) { + if (remain >= (sizeof(krb5_int32)*5)) { + (void) krb5_ser_unpack_int32(&file_is_open, + &bp, &remain); + (void) krb5_ser_unpack_int32(&foffbuf[0], + &bp, &remain); + (void) krb5_ser_unpack_int32(&foffbuf[1], + &bp, &remain); + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + ktdata->version = ibuf; + + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + if (ibuf == KV5M_KEYTAB) { + if (file_is_open) { + int fmode; + long fpos; + + fmode = (file_is_open >> 1) & O_ACCMODE; + if (fmode) + kret = krb5_ktfileint_openw(kcontext, + keytab); + else + kret = krb5_ktfileint_openr(kcontext, + keytab); + if (!kret) { +#if SIZEOF_LONG == 4 + fpos = foffbuf[0]; +#else /* SIZEOF_LONG == 4 */ + fpos = foffbuf[0] | (foffbuf[1] << 32); +#endif /* SIZEOF_LONG == 4 */ + fseek(KTFILEP(keytab), fpos, SEEK_SET); + } + } + kret = 0; + } + else + kret = EINVAL; + } + } + if (kret) { + if (keytab->data) { + if (KTFILENAME(keytab)) + krb5_xfree(KTFILENAME(keytab)); + krb5_xfree(keytab->data); + } + krb5_xfree(keytab); + } + else { + *buffer = bp; + *lenremain = remain; + *argp = (krb5_pointer) keytab; + } + } + free(ktname); + } + } + return(kret); +} diff --git a/src/lib/krb5/keytab/ktbase.c b/src/lib/krb5/keytab/ktbase.c index 4f9869d17..e78c3dc71 100644 --- a/src/lib/krb5/keytab/ktbase.c +++ b/src/lib/krb5/keytab/ktbase.c @@ -104,3 +104,89 @@ krb5_kt_resolve (context, name, ktid) free(pfx); return KRB5_KT_UNKNOWN_TYPE; } + +/* + * Routines to deal with externalizingt krb5_keytab. + * krb5_keytab_size(); + * krb5_keytab_externalize(); + * krb5_keytab_internalize(); + */ +static krb5_error_code krb5_keytab_size + KRB5_PROTOTYPE((krb5_context, krb5_pointer, size_t *)); +static krb5_error_code krb5_keytab_externalize + KRB5_PROTOTYPE((krb5_context, krb5_pointer, krb5_octet **, size_t *)); +static krb5_error_code krb5_keytab_internalize + KRB5_PROTOTYPE((krb5_context,krb5_pointer *, krb5_octet **, size_t *)); + +/* + * Serialization entry for this type. + */ +static const krb5_ser_entry krb5_keytab_ser_entry = { + KV5M_KEYTAB, /* Type */ + krb5_keytab_size, /* Sizer routine */ + krb5_keytab_externalize, /* Externalize routine */ + krb5_keytab_internalize /* Internalize routine */ +}; + +static krb5_error_code +krb5_keytab_size(kcontext, arg, sizep) + krb5_context kcontext; + krb5_pointer arg; + size_t *sizep; +{ + krb5_error_code kret; + krb5_keytab keytab; + krb5_ser_handle shandle; + + kret = EINVAL; + if ((keytab = (krb5_keytab) arg) && + keytab->ops && + (shandle = (krb5_ser_handle) keytab->ops->serializer) && + shandle->sizer) + kret = (*shandle->sizer)(kcontext, arg, sizep); + return(kret); +} + +static krb5_error_code +krb5_keytab_externalize(kcontext, arg, buffer, lenremain) + krb5_context kcontext; + krb5_pointer arg; + krb5_octet **buffer; + size_t *lenremain; +{ + krb5_error_code kret; + krb5_keytab keytab; + krb5_ser_handle shandle; + + kret = EINVAL; + if ((keytab = (krb5_keytab) arg) && + keytab->ops && + (shandle = (krb5_ser_handle) keytab->ops->serializer) && + shandle->externalizer) + kret = (*shandle->externalizer)(kcontext, arg, buffer, lenremain); + return(kret); +} + +static krb5_error_code +krb5_keytab_internalize(kcontext, argp, buffer, lenremain) + krb5_context kcontext; + krb5_pointer *argp; + krb5_octet **buffer; + size_t *lenremain; +{ + krb5_error_code kret; + krb5_ser_handle shandle; + + kret = EINVAL; + if ((shandle = (krb5_ser_handle) krb5_kt_dfl_ops.serializer) && + shandle->internalizer) + kret = (*shandle->internalizer)(kcontext, argp, buffer, lenremain); + return(kret); +} + +krb5_error_code +krb5_ser_keytab_init(kcontext) + krb5_context kcontext; +{ + return(krb5_register_serializer(kcontext, &krb5_keytab_ser_entry)); +} -- 2.26.2