summaryrefslogtreecommitdiffstats
path: root/src/lib/krb5
diff options
context:
space:
mode:
authorMarc Horowitz <marc@mit.edu>1998-10-30 02:56:35 +0000
committerMarc Horowitz <marc@mit.edu>1998-10-30 02:56:35 +0000
commit1440ab035ba04550ddbbfbff1ee9b5571e3d95db (patch)
tree9d5e8d2e151a930e044c7d0f7c64053d244577a0 /src/lib/krb5
parent61ddbf948ba6ee70c1bc049268c3dfa73bc9983e (diff)
downloadkrb5-1440ab035ba04550ddbbfbff1ee9b5571e3d95db.tar.gz
krb5-1440ab035ba04550ddbbfbff1ee9b5571e3d95db.tar.xz
krb5-1440ab035ba04550ddbbfbff1ee9b5571e3d95db.zip
pull up 3des implementation from the marc-3des branch
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@11001 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib/krb5')
-rw-r--r--src/lib/krb5/ChangeLog8
-rw-r--r--src/lib/krb5/Makefile.in4
-rw-r--r--src/lib/krb5/asn.1/ChangeLog7
-rw-r--r--src/lib/krb5/asn.1/asn1buf.c2
-rw-r--r--src/lib/krb5/ccache/ChangeLog4
-rw-r--r--src/lib/krb5/ccache/ccapi/Makefile.in21
-rw-r--r--src/lib/krb5/ccache/ccapi/stdcc.c394
-rw-r--r--src/lib/krb5/ccache/ccapi/stdcc.h73
-rw-r--r--src/lib/krb5/ccache/ccapi/stdcc_util.c368
-rw-r--r--src/lib/krb5/ccache/ccapi/stdcc_util.h25
-rw-r--r--src/lib/krb5/ccache/ccbase.c6
-rw-r--r--src/lib/krb5/configure.in1
-rw-r--r--src/lib/krb5/error_tables/krb5_err.et2
-rw-r--r--src/lib/krb5/keytab/file/ChangeLog5
-rw-r--r--src/lib/krb5/keytab/file/ktf_g_ent.c87
-rw-r--r--src/lib/krb5/krb/ChangeLog36
-rw-r--r--src/lib/krb5/krb/Makefile.in3
-rw-r--r--src/lib/krb5/krb/auth_con.c70
-rw-r--r--src/lib/krb5/krb/auth_con.h1
-rw-r--r--src/lib/krb5/krb/decode_kdc.c18
-rw-r--r--src/lib/krb5/krb/decrypt_tk.c24
-rw-r--r--src/lib/krb5/krb/enc_helper.c53
-rw-r--r--src/lib/krb5/krb/encode_kdc.c66
-rw-r--r--src/lib/krb5/krb/encrypt_tk.c61
-rw-r--r--src/lib/krb5/krb/gen_seqnum.c70
-rw-r--r--src/lib/krb5/krb/gen_subkey.c27
-rw-r--r--src/lib/krb5/krb/get_creds.c107
-rw-r--r--src/lib/krb5/krb/gic_pwd.c8
-rw-r--r--src/lib/krb5/krb/in_tkt_pwd.c9
-rw-r--r--src/lib/krb5/krb/init_ctx.c183
-rw-r--r--src/lib/krb5/krb/kdc_rep_dc.c29
-rw-r--r--src/lib/krb5/krb/kfree.c11
-rw-r--r--src/lib/krb5/krb/mk_cred.c47
-rw-r--r--src/lib/krb5/krb/mk_priv.c59
-rw-r--r--src/lib/krb5/krb/mk_rep.c44
-rw-r--r--src/lib/krb5/krb/mk_req_ext.c65
-rw-r--r--src/lib/krb5/krb/mk_safe.c15
-rw-r--r--src/lib/krb5/krb/preauth.c16
-rw-r--r--src/lib/krb5/krb/preauth2.c23
-rw-r--r--src/lib/krb5/krb/rd_cred.c26
-rw-r--r--src/lib/krb5/krb/rd_priv.c41
-rw-r--r--src/lib/krb5/krb/rd_rep.c27
-rw-r--r--src/lib/krb5/krb/rd_req_dec.c93
-rw-r--r--src/lib/krb5/krb/rd_safe.c11
-rw-r--r--src/lib/krb5/krb/send_tgs.c100
-rw-r--r--src/lib/krb5/krb/ser_actx.c39
-rw-r--r--src/lib/krb5/krb/ser_eblk.c4
-rw-r--r--src/lib/krb5/krb/str_conv.c148
-rw-r--r--src/lib/krb5/krb/vfy_increds.c104
-rw-r--r--src/lib/krb5/os/ChangeLog13
-rw-r--r--src/lib/krb5/os/Makefile.in3
-rw-r--r--src/lib/krb5/os/c_ustime.c316
-rw-r--r--src/lib/krb5/os/ktdefname.c22
-rw-r--r--src/lib/krb5/os/localaddr.c317
-rw-r--r--src/lib/krb5/os/locate_kdc.c31
55 files changed, 1451 insertions, 1896 deletions
diff --git a/src/lib/krb5/ChangeLog b/src/lib/krb5/ChangeLog
index f7922150e..f1e1e81f9 100644
--- a/src/lib/krb5/ChangeLog
+++ b/src/lib/krb5/ChangeLog
@@ -1,3 +1,11 @@
+Thu Jul 30 13:12:57 1998 Sam Hartman <hartmans@utwig.mesas.com>
+
+ * configure.in: Test for sa_len so localaddr works on NetBSD.
+
+Sun Jul 26 17:46:47 1998 Sam Hartman <hartmans@utwig.mesas.com>
+
+ * Makefile.in (LIBMAJOR): bump to 2
+
Wed Apr 15 18:07:20 1998 Tom Yu <tlyu@mit.edu>
* Makefile.in (SHLIB_EXPDEPS):
diff --git a/src/lib/krb5/Makefile.in b/src/lib/krb5/Makefile.in
index 4864a2f94..12ce18512 100644
--- a/src/lib/krb5/Makefile.in
+++ b/src/lib/krb5/Makefile.in
@@ -28,8 +28,8 @@ LIBDONE= error_tables/DONE asn.1/DONE ccache/DONE ccache/stdio/DONE \
#SHLIB_LIBDIRS= @SHLIB_LIBDIRS@
LIB=krb5
-LIBMAJOR=1
-LIBMINOR=2
+LIBMAJOR=2
+LIBMINOR=1
STOBJLISTS= \
error_tables/OBJS.ST \
diff --git a/src/lib/krb5/asn.1/ChangeLog b/src/lib/krb5/asn.1/ChangeLog
index a42ad235c..ca3f679f5 100644
--- a/src/lib/krb5/asn.1/ChangeLog
+++ b/src/lib/krb5/asn.1/ChangeLog
@@ -1,3 +1,10 @@
+1998-10-27 Marc Horowitz <marc@mit.edu>
+
+ * asn1buf.c (asn1buf_sync): interoperation testing against heimdal
+ revealed a bug. if extra fields are present in a SEQUENCE, they
+ are not ignored and skipped. This caused the decoder to get out
+ of sync.
+
Thu Jul 2 15:30:25 1998 Theodore Y. Ts'o <tytso@mit.edu>
* asn1_encode.c: Make the magic Macintosh EPOCH offset be 70 years
diff --git a/src/lib/krb5/asn.1/asn1buf.c b/src/lib/krb5/asn.1/asn1buf.c
index 30dad8b49..52ac387d5 100644
--- a/src/lib/krb5/asn.1/asn1buf.c
+++ b/src/lib/krb5/asn.1/asn1buf.c
@@ -93,7 +93,7 @@ void asn1buf_sync(buf, subbuf)
asn1buf * buf;
asn1buf * subbuf;
{
- buf->next = subbuf->next;
+ buf->next = subbuf->bound + 1;
}
asn1_error_code asn1buf_destroy(buf)
diff --git a/src/lib/krb5/ccache/ChangeLog b/src/lib/krb5/ccache/ChangeLog
index 2a4d39551..71aa06dc8 100644
--- a/src/lib/krb5/ccache/ChangeLog
+++ b/src/lib/krb5/ccache/ChangeLog
@@ -7,6 +7,10 @@ Fri Aug 20 18:30:00 1998 Miro Jurisic <meeroh@mit.edu>
* Added Frank's CCache API cache implementation and made
it default on the Mac
+Thu Jul 30 13:12:30 1998 Sam Hartman <hartmans@utwig.mesas.com>
+
+ * ccbase.c: Enable memory ccache (merge adapted from Kerbnet)
+
1998-05-27 Theodore Ts'o <tytso@rsts-11.mit.edu>
* Makefile.in: Add ccache/memory as a directory to be recursively
diff --git a/src/lib/krb5/ccache/ccapi/Makefile.in b/src/lib/krb5/ccache/ccapi/Makefile.in
deleted file mode 100644
index e47ded443..000000000
--- a/src/lib/krb5/ccache/ccapi/Makefile.in
+++ /dev/null
@@ -1,21 +0,0 @@
-thisconfigdir=./../..
-BUILDTOP=$(REL)$(U)$(S)$(U)$(S)$(U)$(S)$(U)
-CFLAGS = $(CCOPTS) $(DEFS)
-
-##DOS##BUILDTOP = ..\..\..\..
-##DOS##PREFIXDIR = ccache\file
-##DOS##OBJFILE = file.lst
-##WIN16##LIBNAME=..\..\krb5.lib
-
-STLIBOBJS = \
- stdcc.o \
- stdcc_util.o
-
-OBJS = stdcc.${OBJEXT} stdcc_util.${OBJEXT}
-
-SRCS = $(srcdir)/stdcc.c $(srcdir)/stdcc_util.c
-
-##DOS##LIBOBJS = $(OBJS)
-
-all-unix:: all-libobjs
-clean-unix:: clean-libobjs
diff --git a/src/lib/krb5/ccache/ccapi/stdcc.c b/src/lib/krb5/ccache/ccapi/stdcc.c
deleted file mode 100644
index 2b9007bf8..000000000
--- a/src/lib/krb5/ccache/ccapi/stdcc.c
+++ /dev/null
@@ -1,394 +0,0 @@
-/**********************************************************
- *
- * stdcc.c - additions to the Kerberos 5 library to support the memory credentical cache API
- *
- * Revision 1.1.1.1 - Frank Dabek July 1998
- *
- **********************************************************/
-
-#include "stdcc.h"
-#include "string.h"
-
-//declare our global object wanna-be
-//must be installed in ccdefops.c
-krb5_cc_ops krb5_cc_stdcc_ops = {
- 0,
- "API",
- krb5_stdcc_get_name,
- krb5_stdcc_resolve,
- krb5_stdcc_generate_new,
- krb5_stdcc_initialize,
- krb5_stdcc_destroy,
- krb5_stdcc_close,
- krb5_stdcc_store,
- krb5_stdcc_retrieve,
- krb5_stdcc_get_principal,
- krb5_stdcc_start_seq_get,
- krb5_stdcc_next_cred,
- krb5_stdcc_end_seq_get,
- krb5_stdcc_remove,
- krb5_stdcc_set_flags,
-};
-
-// -- generate_new --------------------------------
-// - create a new cache with a unique name, corresponds to creating a named cache
-// - iniitialize the API here if we have to.
-krb5_error_code krb5_stdcc_generate_new
- (krb5_context context, krb5_ccache *id )
-
- {
-
- krb5_ccache newCache;
- char name[kStringLiteralLen];
- cc_time_t time;
- int err;
-
- //make sure the API has been intialized
- if (gCntrlBlock == NULL) {
- err = cc_initialize(&gCntrlBlock, CC_API_VER_1, NULL, NULL);
- if (err != CC_NOERROR) return err;
- }
-
- //allocate the cache structure
- newCache = (krb5_ccache) malloc(sizeof(struct _krb5_ccache));
- if (newCache == NULL) return KRB5_CC_NOMEM;
-
- //create a unique name
- cc_get_change_time(gCntrlBlock, &time);
- sprintf(name, "gen_new_cache%d", time);
-
- //create the new cache
- err = cc_create(gCntrlBlock, name, CC_CRED_V5,
- name, 0L, &(((stdccCacheDataPtr)(newCache->data))->NamedCache) );
- if (err != CC_NOERROR) return err;
-
- //setup some fields
- newCache->ops = &krb5_cc_stdcc_ops;
- newCache->data = (stdccCacheDataPtr)malloc(sizeof(stdccCacheData));
-
- //return a pointer to the new cache
- *id = newCache;
-
- return CC_NOERROR;
- }
-
-// -- resolve ------------------------------
-//
-// - create a new cache with the name stored in residual
-krb5_error_code krb5_stdcc_resolve
- (krb5_context context, krb5_ccache *id , const char *residual ) {
-
- krb5_ccache newCache;
- int err,pos;
- char *cName;
-
- //make sure the API has been intialized
- if (gCntrlBlock == NULL) {
- err = cc_initialize(&gCntrlBlock, CC_API_VER_1, NULL, NULL);
- if (err != CC_NOERROR) return err;
- }
-
- newCache = (krb5_ccache) malloc(sizeof(struct _krb5_ccache));
- if (newCache == NULL) return KRB5_CC_NOMEM;
-
- newCache->ops = &krb5_cc_stdcc_ops;
- newCache->data = (stdccCacheDataPtr)malloc(sizeof(stdccCacheData));
- if (newCache->data == NULL) return KRB5_CC_NOMEM;
-
- cName = residual;
- //attempt to find a cache by the same name before creating it
- err = cc_open(gCntrlBlock, cName, CC_CRED_V5, 0L, &(((stdccCacheDataPtr)(newCache->data))->NamedCache));
- //we didn't find it.. create it.
- if (err) {
- err = cc_create(gCntrlBlock, cName, CC_CRED_V5, cName,
- 0L, &(((stdccCacheDataPtr)(newCache->data))->NamedCache) );
- if (err != CC_NOERROR) return err; //still an error, return it
- }
-
- //return new cache structure
- *id = newCache;
- return CC_NOERROR;
- }
-
- // -- initialize --------------------------------
- //-initialize the cache, check to see if one already exists for this principal
- // if not set our principal to this principal. This searching enables ticket sharing
- krb5_error_code krb5_stdcc_initialize
- (krb5_context context, krb5_ccache id, krb5_principal princ)
-
- {
-
- int err, err1, found;
- //char cName[kStringLiteralLen];
- char *cName = nil;
- ccache_p *testNC = NULL;
- ccache_it *it;
- char *p = NULL, *targetName = NULL;
-
- //test id for null
- if (id == NULL) return KRB5_CC_NOMEM;
-
- //test for initialized API
- if (gCntrlBlock == NULL)
- return CC_NO_EXIST;
-
- //create a principal name for the named cache
- err = krb5_unparse_name(context, princ, &cName);
- if (err)
- return(err);
-
- //sprintf(cName, "%s@%s", krb5_princ_name(context, princ)->data, krb5_princ_realm(context, princ)->data);
-
- //look for a cache already extant for this principal
- it = NULL;
- found = err = 0;
- while ((err != CC_END) && (!found)) {
- err = cc_seq_fetch_NCs(gCntrlBlock, &testNC, &it);
- if (err == CC_NOERROR) {
- cc_get_principal(gCntrlBlock, testNC, &p);
- if (strcmp(p, cName) == 0) {
- found = 1;
- cc_get_name(gCntrlBlock, testNC, &targetName);
- }
- cc_free_principal(gCntrlBlock, p);
- err1 = cc_close(gCntrlBlock, &testNC);
- }
- }
-
- if (!found)
- //we didn't find one with the name we were looking for, use the one we had and change the name
- cc_set_principal(gCntrlBlock, (((stdccCacheDataPtr)(id->data))->NamedCache), CC_CRED_V5, cName);
- else {
- //we found a cache for this guy, lets trash ours and use that one - let's not; sgm 10/7/98
- //cc_destroy(gCntrlBlock, &(((stdccCacheDataPtr)(id->data))->NamedCache));
- err = cc_open(gCntrlBlock, targetName, CC_CRED_V5, 0L, &(((stdccCacheDataPtr)(id->data))->NamedCache));
- if (err != CC_NOERROR) return err; //error opening
- cc_free_name(gCntrlBlock, targetName);
- }
-
- free(cName);
-
- return CC_NOERROR;
-
- }
-
-
-// -- store ----------------------------------
-// - store some credentials in our cache
- krb5_error_code krb5_stdcc_store
- (krb5_context context, krb5_ccache id , krb5_creds *creds ) {
-
- cred_union *cu = NULL;
- int err;
-
-
- //copy the fields from the almost identical structures
- dupK52cc(context, creds, &cu);
-
- //finally store the credential
- //store will copy (that is duplicate) everything
- err = cc_store(gCntrlBlock, ((stdccCacheDataPtr)(id->data))->NamedCache, *cu);
- if (err != CC_NOERROR) return err;
-
- //free the cred union
- err = cc_free_creds(gCntrlBlock, &cu);
-
- return err;
-}
-
-
-// -- start_seq_get --------------------------
-// - begin an iterator call to get all of the credentials in the cache
-krb5_error_code krb5_stdcc_start_seq_get
-(krb5_context context, krb5_ccache id , krb5_cc_cursor *cursor ) {
-
- //all we have to do is initialize the cursor
- *cursor = NULL;
- return CC_NOERROR;
-}
-
-// -- next cred ---------------------------
-// - get the next credential in the cache as part of an iterator call
-// - this maps to call to cc_seq_fetch_creds
-krb5_error_code krb5_stdcc_next_cred
- (krb5_context context,
- krb5_ccache id ,
- krb5_cc_cursor *cursor ,
- krb5_creds *creds ) {
-
- int err;
- cred_union *credU = NULL;
- cc_creds *c = NULL;
-
- err = cc_seq_fetch_creds(gCntrlBlock, ((stdccCacheDataPtr)(id->data))->NamedCache,
- &credU, (ccache_it **)cursor);
-
- if (err != CC_NOERROR)
- return err;
-
- //copy data (with translation)
- dupCCtoK5(context, credU->cred.pV5Cred, creds);
-
- //free our version of the cred
- cc_free_creds(gCntrlBlock, &credU);
-
- return CC_NOERROR;
-
-}
-
-
-// -- retreive -------------------
-// - try to find a matching credential in the cache
-krb5_error_code krb5_stdcc_retrieve
- (krb5_context context,
- krb5_ccache id,
- krb5_flags whichfields,
- krb5_creds *mcreds,
- krb5_creds *creds ) {
-
- krb5_cc_cursor curs = NULL;
- krb5_creds *fetchcreds;
-
- fetchcreds = (krb5_creds *)malloc(sizeof(krb5_creds));
- if (fetchcreds == NULL) return KRB5_CC_NOMEM;
-
- //we're going to use the iterators
- krb5_stdcc_start_seq_get(context, id, &curs);
-
- while (krb5_stdcc_next_cred(context, id, &curs, fetchcreds) == CC_NOERROR) {
- //look at each credential for a match
- //use this match routine since it takes the whichfields and the API doesn't
- if (stdccCredsMatch(context, fetchcreds, mcreds, whichfields)) {
- //we found it, copy and exit
- *creds = *fetchcreds;
- krb5_stdcc_end_seq_get(context, id, &curs);
- return CC_NOERROR;
- }
- //free copy allocated by next_cred
- krb5_free_cred_contents(context, fetchcreds);
- }
-
- //no luck, end get and exti
- krb5_stdcc_end_seq_get(context, id, &curs);
-
- return KRB5_CC_NOTFOUND;
-}
-
-// -- end seq ------------------------
-// - just free up the storage assoicated with the cursor (if we could)
- krb5_error_code krb5_stdcc_end_seq_get
- (krb5_context context, krb5_ccache id , krb5_cc_cursor *cursor ) {
-
- //the limitation of the Ccache api and the seq calls
- //causes trouble. cursor might have already been freed
- //and anyways it is in the mac's heap so we need FreePtr
- //but all i have is free
- // FreePtr(*cursor);
-
- //LEAK IT!
- *cursor = NULL;
- }
-
-// -- close ---------------------------
-// - free our pointers to the NC
-krb5_error_code
-krb5_stdcc_close(context, id, princ)
- krb5_context context;
- krb5_ccache id;
- krb5_principal princ;
-{
-
- //free it
- free((stdccCacheDataPtr)(id->data));
- //null it out
- (stdccCacheDataPtr)(id->data) = NULL;
-
- return CC_NOERROR;
-}
-
-// -- destroy -------------
-// - free our storage and the cache
-krb5_error_code
-krb5_stdcc_destroy (krb5_context context, krb5_ccache id ) {
-
- int err;
-
- //destroy the named cache
- err = cc_destroy(gCntrlBlock, &(((stdccCacheDataPtr)(id->data))->NamedCache));
- //free the pointer to the record that held the pointer to the cache
- free((stdccCacheDataPtr)(id->data));
- //null it out
- (stdccCacheDataPtr)(id->data) = NULL;
-
- return err;
-}
-
-
-// -- getname ---------------------------
-// - return the name of the named cache
-char * krb5_stdcc_get_name
- (krb5_context context, krb5_ccache id ) {
-
- char *ret = NULL;
- int err;
-
- //just a wrapper
- err = cc_get_name(gCntrlBlock, (((stdccCacheDataPtr)(id->data))->NamedCache), &ret);
-
- if (err != CC_NOERROR)
- return ret;
- else
- return NULL;
-
-}
-
-// -- get_principal ---------------------------
-// - return the principal associated with the named cache
-krb5_error_code
-krb5_stdcc_get_principal (krb5_context context, krb5_ccache id , krb5_principal *princ ) {
-
- int err;
- char *name = NULL;
-
- //another wrapper
- err = cc_get_principal(gCntrlBlock, (((stdccCacheDataPtr)(id->data))->NamedCache), &name);
-
- if (err != CC_NOERROR)
- return err;
-
- //turn it into a krb principal
- err = krb5_parse_name(context, name, princ);
-
- return err;
-}
-
-// -- set_flags ---------------------------
-// - currently a NOP since we don't store any flags in the NC
-krb5_error_code krb5_stdcc_set_flags
- (krb5_context context, krb5_ccache id , krb5_flags flags ) {
-
- return CC_NOERROR;
-}
-
-// - remove ---------------------------
-// - remove the specified credentials from the NC
-krb5_error_code krb5_stdcc_remove
- (krb5_context context, krb5_ccache id , krb5_flags flags, krb5_creds *creds ) {
-
- cred_union *cu = NULL;
- int err;
-
- //convert to a cred union
- dupK52cc(context, creds, &cu);
-
- //remove it
- err = cc_remove_cred(gCntrlBlock, (((stdccCacheDataPtr)(id->data))->NamedCache), *cu);
- if (err != CC_NOERROR) return err;
-
- //free the temp cred union
- err = cc_free_creds(gCntrlBlock, &cu);
- if (err != CC_NOERROR) return err;
-
- return CC_NOERROR;
- }
- \ No newline at end of file
diff --git a/src/lib/krb5/ccache/ccapi/stdcc.h b/src/lib/krb5/ccache/ccapi/stdcc.h
deleted file mode 100644
index c157770c4..000000000
--- a/src/lib/krb5/ccache/ccapi/stdcc.h
+++ /dev/null
@@ -1,73 +0,0 @@
-//#include "k5-int.h"
-#include "krb5.h"
-
-#if defined(macintosh)
-#include "CCache.h"
-#endif
-
-#if defined(_MSDOS) || defined(_WIN32)
-#include "cacheapi.h"
-#endif
-
-#define kStringLiteralLen 255
-
-//globals to be exported
-extern krb5_cc_ops krb5_cc_stdcc_ops;
-
-//structure to stash in the cache's data field
-//only holds another pointer to the actual cache right now
-typedef struct _stdccCacheData {
- ccache_p *NamedCache;
-} stdccCacheData, *stdccCacheDataPtr;
-
-
-//function protoypes complete with bogus windowsesque macros..
-
-KRB5_DLLIMP krb5_error_code krb5_stdcc_close
- KRB5_PROTOTYPE((krb5_context, krb5_ccache id ));
-
-KRB5_DLLIMP krb5_error_code krb5_stdcc_destroy
- KRB5_PROTOTYPE((krb5_context, krb5_ccache id ));
-
-KRB5_DLLIMP krb5_error_code krb5_stdcc_end_seq_get
- KRB5_PROTOTYPE((krb5_context, krb5_ccache id , krb5_cc_cursor *cursor ));
-
-KRB5_DLLIMP krb5_error_code krb5_stdcc_generate_new
- KRB5_PROTOTYPE((krb5_context, krb5_ccache *id ));
-
-KRB5_DLLIMP char * krb5_stdcc_get_name
- KRB5_PROTOTYPE((krb5_context, krb5_ccache id ));
-
-KRB5_DLLIMP krb5_error_code krb5_stdcc_get_principal
- KRB5_PROTOTYPE((krb5_context, krb5_ccache id , krb5_principal *princ ));
-
-KRB5_DLLIMP krb5_error_code krb5_stdcc_initialize
- KRB5_PROTOTYPE((krb5_context, krb5_ccache id , krb5_principal princ ));
-
-KRB5_DLLIMP krb5_error_code krb5_stdcc_next_cred
- KRB5_PROTOTYPE((krb5_context,
- krb5_ccache id ,
- krb5_cc_cursor *cursor ,
- krb5_creds *creds ));
-
-KRB5_DLLIMP krb5_error_code krb5_stdcc_resolve
- KRB5_PROTOTYPE((krb5_context, krb5_ccache *id , const char *residual ));
-
-KRB5_DLLIMP krb5_error_code krb5_stdcc_retrieve
- KRB5_PROTOTYPE((krb5_context,
- krb5_ccache id ,
- krb5_flags whichfields ,
- krb5_creds *mcreds ,
- krb5_creds *creds ));
-
-KRB5_DLLIMP krb5_error_code krb5_stdcc_start_seq_get
- KRB5_PROTOTYPE((krb5_context, krb5_ccache id , krb5_cc_cursor *cursor ));
-
-KRB5_DLLIMP krb5_error_code krb5_stdcc_store
- KRB5_PROTOTYPE((krb5_context, krb5_ccache id , krb5_creds *creds ));
-
-KRB5_DLLIMP krb5_error_code krb5_stdcc_set_flags
- KRB5_PROTOTYPE((krb5_context, krb5_ccache id , krb5_flags flags ));
-
-KRB5_DLLIMP krb5_error_code krb5_stdcc_remove
- KRB5_PROTOTYPE((krb5_context, krb5_ccache id , krb5_flags flags, krb5_creds *creds));
diff --git a/src/lib/krb5/ccache/ccapi/stdcc_util.c b/src/lib/krb5/ccache/ccapi/stdcc_util.c
deleted file mode 100644
index 4f4fcfc50..000000000
--- a/src/lib/krb5/ccache/ccapi/stdcc_util.c
+++ /dev/null
@@ -1,368 +0,0 @@
-// stdcc_util.c
-// utility functions used in implementing the ccache api for krb5
-// not publicly exported
-// Frank Dabek, July 1998
-
-#include <stdlib.h>
-#include <string.h>
-#include "stdcc_util.h"
-#include "krb5.h"
-#include "kv5m_err.h"
-
-#define fieldSize 255
-
-/* on the Mac, we need the calls which allocate memory for the Credentials Cache to use
- Ptr's in the system help, so that they stay global and so that bad things don't happen
- when we call DisposePtr() on them. However, on other systems, malloc is probably the
- right thing to use.
- So for any place where we allocate memory for the Credentials Cache, use sys_alloc() and
- define it accordingly.
-*/
-
-#if defined(macintosh)
-#define sys_alloc(size) NewSafePtrSys(size)
-#else
-#define sys_alloc(size) malloc(size)
-#endif
-
-#if defined(macintosh)
-//stolen from CCacheUtils.c
-// -- NewSafePtrSys -----------------
-// - analagous to NewSafePtr but memory is allocated in the system heap
-Ptr NewSafePtrSys(long size) {
-
- Ptr retPtr;
-
- retPtr = NewPtrSys(size);
-
- if (retPtr != NULL)
- HoldMemory(retPtr, size);
-
- return retPtr;
-}
-#endif
-
-// CopyCCDataArrayToK5
-// - copy and translate the null terminated arrays of data records
-// used in k5 tickets
-int copyCCDataArrayToK5(cc_creds *cc, krb5_creds *kc, char whichArray) {
-
- cc_data *ccAdr, **cbase;
- krb5_address *kAdr, **kbase, **constKBase;
- int numRecords = 0;
-
-
- if (whichArray == kAddressArray) {
- //check pointer
- if (cc->addresses == NULL) {
- kc->addresses = NULL;
- return 0; }
- } else if (whichArray == kAuthDataArray) {
- //check pointer
- if (cc->authdata == NULL) {
- kc->authdata = NULL;
- return 0; }
- } else return -1;
-
-
- cbase = (whichArray == kAddressArray) ? cc->addresses : cc->authdata;
- //calc number of records
- while (*cbase++ != NULL) numRecords++;
- //allocate new array
- constKBase = kbase = (krb5_address **)malloc((numRecords+1)*sizeof(char *));
- //reset base
- cbase = (whichArray == kAddressArray) ? cc->addresses : cc->authdata;
-
-
- //copy records
- while (*cbase != NULL) {
- *kbase = (krb5_address *)malloc(sizeof(krb5_address));
- kAdr = *kbase;
- ccAdr = *cbase;
- kAdr->magic = (whichArray == kAddressArray) ? KV5M_ADDRESS : KV5M_AUTHDATA;
- kAdr->addrtype = ccAdr->type;
- kAdr->length = ccAdr->length;
- kAdr->contents = (krb5_octet *)malloc(kAdr->length);
- memcpy(kAdr->contents, ccAdr->data, kAdr->length);
- //next element please
- kbase++; cbase++;
- }
-
- //write terminator
- *kbase = NULL;
- if (whichArray == kAddressArray) kc->addresses = constKBase;
- else kc->authdata = (krb5_authdata **)constKBase;
-
- return 0;
-}
-
-// copyK5DataArrayToCC
-// - analagous to above, but in the other direction
-int copyK5DataArrayToCC(krb5_creds *kc, cc_creds *cc, char whichArray) {
-
- cc_data *ccAdr, **cbase, **constCBase;
- krb5_address *kAdr, **kbase;
- int numRecords = 0;
-
-
- if (whichArray == kAddressArray) {
- //check pointer
- if (kc->addresses == NULL) {
- cc->addresses = NULL;
- return 0; }
- } else if (whichArray == kAuthDataArray) {
- //check pointer
- if (kc->authdata == NULL) {
- cc->authdata = NULL;
- return 0; }
- } else return -1;
-
-
- kbase = (whichArray == kAddressArray) ? kc->addresses : (krb5_address **)kc->authdata;
- //calc number of records
- while (*kbase++ != NULL) numRecords++;
- //allocate new array
- constCBase = cbase = (cc_data **)sys_alloc((numRecords+1)*sizeof(char *));
- //reset base
- kbase = (whichArray == kAddressArray) ? kc->addresses : (krb5_address **)kc->authdata;
-
-
- //copy records
- while (*kbase != NULL) {
- *cbase = (cc_data *)sys_alloc(sizeof(krb5_address));
- kAdr = *kbase;
- ccAdr = *cbase;
- ccAdr->type = kAdr->addrtype;
- ccAdr->length = kAdr->length;
- ccAdr->data = (unsigned char *)sys_alloc(ccAdr->length);
- memcpy(ccAdr->data, kAdr->contents, kAdr->length);
- //next element please
- kbase++; cbase++;
- }
-
- //write terminator
- *cbase = NULL;
- if (whichArray == kAddressArray) cc->addresses = (cc_data **)constCBase;
- else cc->authdata = (cc_data **)constCBase;
-
- return 0;
-}
-
-
-// dupcctok5
-// - allocate an empty k5 style ticket and copy info from the cc_creds ticket
-void dupCCtoK5(krb5_context context, cc_creds *src, krb5_creds *dest) {
-
- int err;
-
- //allocate and copy
- //copy all of those damn fields back
- err = krb5_parse_name(context, src->client, &(dest->client));
- err = krb5_parse_name(context, src->server, &(dest->server));
- if (err) return; //parsename fails w/o krb5.ini for example
-
- //copy keyblock
- dest->keyblock.enctype = src->keyblock.type;
- dest->keyblock.length = src->keyblock.length;
- dest->keyblock.contents = (krb5_octet *)malloc(dest->keyblock.length);
- memcpy(dest->keyblock.contents, src->keyblock.data, dest->keyblock.length);
-
- //copy times
- dest->times.authtime = src->authtime;
- dest->times.starttime = src->starttime;
- dest->times.endtime = src->endtime;
- dest->times.renew_till = src->renew_till;
- dest->is_skey = src->is_skey;
- dest->ticket_flags = src->ticket_flags;
-
- //more branching fields
- copyCCDataArrayToK5(src, dest, kAddressArray);
- dest->ticket.length = src->ticket.length;
- dest->ticket.data = (char *)malloc(src->ticket.length);
- memcpy(dest->ticket.data, src->ticket.data, src->ticket.length);
- dest->second_ticket.length = src->second_ticket.length;
- (dest->second_ticket).data = ( char *)malloc(src->second_ticket.length);
- memcpy(dest->second_ticket.data, src->second_ticket.data, src->second_ticket.length);
-
- //zero out magic number
- dest->magic = 0;
- //later
- //copyCCDataArrayToK5(src, dest, kAuthDataArray);
- //krb5 docs say that authdata can be nulled out if we
- //only want default behavior
- dest->authdata = NULL;
-
- return;
-}
-
-// dupK52CC
-// - analagous to above but in the reverse direction
-void dupK52cc(krb5_context context, krb5_creds *creds, cred_union **cu) {
-
- krb5_address **tA;
- krb5_authdata **tAd;
- cc_creds *c;
- int err;
- #ifdef macintosh
- char *tempname = NULL;
- #endif
-
- if (cu == NULL) return;
-
- //allocate the cred_union
- *cu = (cred_union *)sys_alloc(sizeof(cred_union));
- if ((*cu) == NULL) return;
- (*cu)->cred_type = CC_CRED_V5;
-
- //allocate creds structure (and install)
- c = (cc_creds *)sys_alloc(sizeof(cc_creds));
- if (c == NULL) return;
- (*cu)->cred.pV5Cred = c;
-
- //convert krb5 principals to flat principals
- #ifdef macintosh
- //and make sure the memory for c->client and c->server is on the system heap with NewPtr
- //for the Mac (krb5_unparse_name puts it in appl heap with malloc)
- err = krb5_unparse_name(context, creds->client, &tempname);
- c->client = sys_alloc(strlen(tempname));
- if (c->client != NULL)
- strcpy(c->client,tempname);
- free(tempname);
- tempname = NULL;
-
- err = krb5_unparse_name(context, creds->server, &tempname);
- c->server = sys_alloc(strlen(tempname));
- if (c->server != NULL)
- strcpy(c->server,tempname);
- free(tempname);
- #else
- err = krb5_unparse_name(context, creds->client, &(c->client));
- err = krb5_unparse_name(context, creds->server, &(c->server));
- #endif
- if (err) return;
-
- //copy more fields
- c->keyblock.type = creds->keyblock.enctype;
- c->keyblock.length = creds->keyblock.length;
-
- if (creds->keyblock.contents != NULL) {
- c->keyblock.data = (unsigned char *)sys_alloc(creds->keyblock.length);
- memcpy(c->keyblock.data, creds->keyblock.contents, creds->keyblock.length);
- } else {
- c->keyblock.data = NULL;
- }
-
- c->authtime = creds->times.authtime;
- c->starttime = creds->times.starttime;
- c->endtime = creds->times.endtime;
- c->renew_till = creds->times.renew_till;
- c->is_skey = creds->is_skey;
- c->ticket_flags = creds->ticket_flags;
-
- copyK5DataArrayToCC(creds, c, kAddressArray);
-
- c->ticket.length = creds->ticket.length;
- if (creds->ticket.data != NULL) {
- c->ticket.data = (unsigned char *)sys_alloc(creds->ticket.length);
- memcpy(c->ticket.data, creds->ticket.data, creds->ticket.length);
- } else {
- c->ticket.data = NULL;
- }
-
- c->second_ticket.length = creds->second_ticket.length;
- if (creds->second_ticket.data != NULL) {
- c->second_ticket.data = (unsigned char *)sys_alloc(creds->second_ticket.length);
- memcpy(c->second_ticket.data, creds->second_ticket.data, creds->second_ticket.length);
- } else {
- c->second_ticket.data = NULL;
- }
-
- c->authdata = NULL;
-
- return;
-}
-
-
-// bitTst
-// - utility function for below function
-int bitTst(int var, int mask) {
-
- return var & mask;
-}
-
-// stdccCredsMatch
-// - check to see if the creds match based on the whichFields variable
-// NOTE: if whichfields is zero we are now comparing 'standard fields.'
-// This is the bug that was killing fetch for a week. The behaviour
-// is what krb5 expects, however.
-int stdccCredsMatch(krb5_context context, krb5_creds *base, krb5_creds *match, int whichfields) {
-
- krb5_ticket_times b, m;
- krb5_authdata **bp, **mp;
- krb5_boolean retval;
- krb5_principal_data p1, p2;
-
-
- //always check the standard fields
- if ((krb5_principal_compare(context, base->client, match->client) &&
- krb5_principal_compare(context, base->server, match->server)) == false)
- return FALSE;
-
- if (bitTst(whichfields, KRB5_TC_MATCH_TIMES)) {
- //test for matching times
- //according to the file cache implementation we do:
- if (match->times.renew_till) {
- if (match->times.renew_till > base->times.renew_till)
- return FALSE; /* this one expires too late */
- }
- if (match->times.endtime) {
- if (match->times.endtime > base->times.endtime)
- return FALSE; /* this one expires too late */
- }
- } //continue search
-
- if (bitTst(whichfields, KRB5_TC_MATCH_IS_SKEY))
- if (base->is_skey != match->is_skey) return false;
-
- if (bitTst(whichfields, KRB5_TC_MATCH_FLAGS))
- if (base->ticket_flags != match->ticket_flags) return false;
-
- if (bitTst(whichfields, KRB5_TC_MATCH_TIMES_EXACT)) {
- b = base->times; m = match->times;
- if ((b.authtime != m.authtime) ||
- (b.starttime != m.starttime) ||
- (b.endtime != m.endtime) ||
- (b.renew_till != m.renew_till)) return false;
- }
-
- if (bitTst(whichfields, KRB5_TC_MATCH_AUTHDATA)) {
- bp = base->authdata;
- mp = match->authdata;
- if ((bp != NULL) && (mp != NULL)) {
- while ( (bp) && (*bp != NULL) ){
- if (( (*bp)->ad_type != (*mp)->ad_type) ||
- ( (*bp)->length != (*mp)->length) ||
- ( memcmp( (*bp)->contents, (*mp)->contents, (*bp)->length) != 0)) return false;
- mp++; bp++;
- }
- }
- }
-
- if (bitTst(whichfields, KRB5_TC_MATCH_SRV_NAMEONLY)) {
- //taken from cc_retrv.c
- retval = krb5_principal_compare(context, base->client,match->client);
- if (!retval) return false;
-
- }
-
- if (bitTst(whichfields, KRB5_TC_MATCH_2ND_TKT))
- if ( (base->second_ticket.length != match->second_ticket.length) ||
- (memcmp(base->second_ticket.data, match->second_ticket.data, base->second_ticket.length) != 0))
- return false;
-
- if (bitTst(whichfields, KRB5_TC_MATCH_KTYPE))
- if (base->keyblock.enctype != match->keyblock.enctype) return false;
-
- //if we fall through to here, they must match
- return true;
-}
diff --git a/src/lib/krb5/ccache/ccapi/stdcc_util.h b/src/lib/krb5/ccache/ccapi/stdcc_util.h
deleted file mode 100644
index 7d0af3dcb..000000000
--- a/src/lib/krb5/ccache/ccapi/stdcc_util.h
+++ /dev/null
@@ -1,25 +0,0 @@
-//stdcc_util.h
-//
-// Frank Dabek, July 1998
-
-#if defined(macintosh)
-#include "CCache.h"
-#endif
-
-#if defined(_MSDOS) || defined(_WIN32)
-#include "cacheapi.h"
-#endif
-
-#include "krb5.h"
-
-//protoypes for private functions declared in stdcc_util.c
-int copyCCDataArrayToK5(cc_creds *cc, krb5_creds *kc, char whichArray);
-int copyK5DataArrayToCC(krb5_creds *kc, cc_creds *cc, char whichArray);
-void dupCCtoK5(krb5_context context, cc_creds *src, krb5_creds *dest);
-void dupK52cc(krb5_context context, krb5_creds *creds, cred_union **cu);
-int stdccCredsMatch(krb5_context context, krb5_creds *base, krb5_creds *match, int whichfields);
-int bitTst(int var, int mask);
-void typeK52cc(krb5_context context, krb5_creds *creds, cc_creds *c, char **client, char **server);
-#define kAddressArray 4
-#define kAuthDataArray 5
-
diff --git a/src/lib/krb5/ccache/ccbase.c b/src/lib/krb5/ccache/ccbase.c
index 4570f8053..ae89334a0 100644
--- a/src/lib/krb5/ccache/ccbase.c
+++ b/src/lib/krb5/ccache/ccbase.c
@@ -31,7 +31,11 @@ struct krb5_cc_typelist
krb5_cc_ops *ops;
struct krb5_cc_typelist *next;
};
-static struct krb5_cc_typelist *cc_typehead = 0;
+extern krb5_cc_ops krb5_mcc_ops;
+
+static struct krb5_cc_typelist cc_entry = { &krb5_mcc_ops, NULL };
+
+static struct krb5_cc_typelist *cc_typehead = &cc_entry;
/*
* Register a new credentials cache type
diff --git a/src/lib/krb5/configure.in b/src/lib/krb5/configure.in
index 1f924319a..b42fbf0ce 100644
--- a/src/lib/krb5/configure.in
+++ b/src/lib/krb5/configure.in
@@ -12,6 +12,7 @@ AC_CHECK_FUNCS(flock fchmod chmod strftime strptime geteuid setenv unsetenv gete
AC_REPLACE_FUNCS(vfprintf vsprintf strdup strcasecmp strerror memmove daemon getuid sscanf syslog)
KRB5_AC_REGEX_FUNCS
dnl
+KRB5_SOCKADDR_SA_LEN
KRB5_BUILD_LIBRARY_WITH_DEPS
KRB5_BUILD_LIBOBJS
KRB5_BUILD_PROGRAM
diff --git a/src/lib/krb5/error_tables/krb5_err.et b/src/lib/krb5/error_tables/krb5_err.et
index d8f8533c8..b483116e1 100644
--- a/src/lib/krb5/error_tables/krb5_err.et
+++ b/src/lib/krb5/error_tables/krb5_err.et
@@ -315,4 +315,6 @@ error_code KRB5_CHPW_PWDNULL, "New password cannot be zero length"
error_code KRB5_CHPW_FAIL, "Password change failed"
error_code KRB5_KT_FORMAT, "Bad format in keytab"
+error_code KRB5_NOPERM_ETYPE, "Encryption type not permitted"
+
end
diff --git a/src/lib/krb5/keytab/file/ChangeLog b/src/lib/krb5/keytab/file/ChangeLog
index 2120127db..4e575b651 100644
--- a/src/lib/krb5/keytab/file/ChangeLog
+++ b/src/lib/krb5/keytab/file/ChangeLog
@@ -1,3 +1,8 @@
+1998-10-27 Marc Horowitz <marc@mit.edu>
+
+ * ktf_g_ent.c (krb5_ktfile_get_entry): restructure the code to use
+ the compare_enctypes function and not leak memory
+
Fri Feb 27 18:03:33 1998 Theodore Ts'o <tytso@rsts-11.mit.edu>
* Makefile.in: Changed thisconfigdir to point at the lib/krb5
diff --git a/src/lib/krb5/keytab/file/ktf_g_ent.c b/src/lib/krb5/keytab/file/ktf_g_ent.c
index 7122cb41d..57d6edabd 100644
--- a/src/lib/krb5/keytab/file/ktf_g_ent.c
+++ b/src/lib/krb5/keytab/file/ktf_g_ent.c
@@ -41,6 +41,7 @@ krb5_ktfile_get_entry(context, id, principal, kvno, enctype, entry)
krb5_keytab_entry cur_entry, new_entry;
krb5_error_code kerror = 0;
int found_wrong_kvno = 0;
+ krb5_boolean similar;
/* Open the keyfile for reading */
if ((kerror = krb5_ktfileint_openr(context, id)))
@@ -53,53 +54,69 @@ krb5_ktfile_get_entry(context, id, principal, kvno, enctype, entry)
cur_entry.principal = 0;
cur_entry.vno = 0;
cur_entry.key.contents = 0;
+
while (TRUE) {
- krb5_enctype entry_type;
-
if ((kerror = krb5_ktfileint_read_entry(context, id, &new_entry)))
break;
- switch (enctype) {
- case ENCTYPE_DES_CBC_CRC:
- case ENCTYPE_DES_CBC_MD5:
- case ENCTYPE_DES_CBC_MD4:
- case ENCTYPE_DES_CBC_RAW:
- enctype = ENCTYPE_DES_CBC_CRC;
- break;
+ /* by the time this loop exits, it must either free cur_entry,
+ and copy new_entry there, or free new_entry. Otherwise, it
+ leaks. */
+
+ /* if the enctype is not ignored and doesn't match, free new_entry
+ and continue to the next */
+
+ if (enctype != IGNORE_ENCTYPE) {
+ if ((kerror = krb5_c_enctype_compare(context, enctype,
+ new_entry.key.enctype,
+ &similar))) {
+ krb5_kt_free_entry(context, &new_entry);
+ break;
+ }
+
+ if (!similar) {
+ krb5_kt_free_entry(context, &new_entry);
+ continue;
+ }
}
- entry_type = new_entry.key.enctype;
- switch(entry_type) {
- case ENCTYPE_DES_CBC_CRC:
- case ENCTYPE_DES_CBC_MD5:
- case ENCTYPE_DES_CBC_MD4:
- case ENCTYPE_DES_CBC_RAW:
- entry_type = ENCTYPE_DES_CBC_CRC;
- break;
+ /* if the principal isn't the one requested, free new_entry
+ and continue to the next. */
+
+ if (!krb5_principal_compare(context, principal, new_entry.principal)) {
+ krb5_kt_free_entry(context, &new_entry);
+ continue;
}
- if (((enctype == IGNORE_ENCTYPE)||
- (entry_type == enctype))&&
- krb5_principal_compare(context, principal, new_entry.principal)) {
- if (kvno == IGNORE_VNO) {
- if (! cur_entry.principal ||
- (cur_entry.vno < new_entry.vno))
- {
- krb5_kt_free_entry(context, &cur_entry);
- cur_entry = new_entry;
- }
- } else {
- if (new_entry.vno == kvno) {
- krb5_kt_free_entry(context, &cur_entry);
- cur_entry = new_entry;
- break;
- } else
- found_wrong_kvno++;
- }
+ if (kvno == IGNORE_VNO) {
+ /* if this is the first match, or if the new vno is
+ bigger, free the current and keep the new. Otherwise,
+ free the new. */
+
+ if (! cur_entry.principal ||
+ (new_entry.vno > cur_entry.vno)) {
+ krb5_kt_free_entry(context, &cur_entry);
+ cur_entry = new_entry;
+ } else {
+ krb5_kt_free_entry(context, &new_entry);
+ }
} else {
+ /* if this kvno matches, free the current (will there ever
+ be one?), keep the new, and break out. Otherwise, remember
+ that we were here so we can return the right error, and
+ free the new */
+
+ if (new_entry.vno == kvno) {
+ krb5_kt_free_entry(context, &cur_entry);
+ cur_entry = new_entry;
+ break;
+ } else {
+ found_wrong_kvno++;
krb5_kt_free_entry(context, &new_entry);
+ }
}
}
+
if (kerror == KRB5_KT_END) {
if (cur_entry.principal)
kerror = 0;
diff --git a/src/lib/krb5/krb/ChangeLog b/src/lib/krb5/krb/ChangeLog
index 49d6ef3bb..9d1cfb02a 100644
--- a/src/lib/krb5/krb/ChangeLog
+++ b/src/lib/krb5/krb/ChangeLog
@@ -1,3 +1,39 @@
+1998-10-27 Marc Horowitz <marc@mit.edu>
+
+ * vfy_increds.c: rearrange the code a bit to make it more clear
+ that the logic is correct.
+
+ * str_conv.c: remove enctype and cksumtype string converstions.
+ They're in the crypto library now, since the information drops
+ right into the enctype table.
+
+ * ser_eblk.c: ifdef the whole file out, since it's not used
+ anywhere. it should probably be deleted, but I'm not sure about
+ backward-compatibility issues yet.
+
+ * rd_req_dec.c: check the auth_context permit-all flag and
+ permitted_enctypes list, and reject the request if the policy
+ check fails.
+
+ * init_ctx.c: add code to initialize the prng. It's not great,
+ but can be improved, and the prng is reseeded when new keys are
+ processed. Read permitted_enctypes from the krb5.conf file, and
+ provide accessor functions for it. Make the various etype list
+ parsers share code as a side effect.
+
+ * get_creds.c: add krb5_get_{validat,renew}ed_creds functions,
+ which are part of the new init_creds api. The prototypes were
+ already in, krb5.hin but there was no implementing code.
+
+ * auth_con.c, auth_con.h: add a list of permitted enctypes to the
+ auth_context for rd_req to check, and create accessor functions
+ for this list.
+
+ * Makefile.in, enc_helper.c: add enc_helper.c. This provides a
+ wrapper around the conventional way the library encrypts and wraps
+ encoded asn.1 structures, so the code isn't repeated in a dozen
+ places.
+
Wed Aug 19 17:27:51 1998 Tom Yu <tlyu@mit.edu>
* conv_princ.c: Add some additional entries to sconv_list that
diff --git a/src/lib/krb5/krb/Makefile.in b/src/lib/krb5/krb/Makefile.in
index ec6384e07..3c734210c 100644
--- a/src/lib/krb5/krb/Makefile.in
+++ b/src/lib/krb5/krb/Makefile.in
@@ -32,6 +32,7 @@ STLIBOBJS= \
cp_key_cnt.o \
decode_kdc.o \
decrypt_tk.o \
+ enc_helper.o \
encode_kdc.o \
encrypt_tk.o \
free_rtree.o \
@@ -114,6 +115,7 @@ OBJS= addr_comp.$(OBJEXT) \
cp_key_cnt.$(OBJEXT) \
decode_kdc.$(OBJEXT) \
decrypt_tk.$(OBJEXT) \
+ enc_helper.$(OBJEXT) \
encode_kdc.$(OBJEXT) \
encrypt_tk.$(OBJEXT) \
free_rtree.$(OBJEXT) \
@@ -197,6 +199,7 @@ SRCS= $(srcdir)/addr_comp.c \
$(srcdir)/cp_key_cnt.c \
$(srcdir)/decode_kdc.c \
$(srcdir)/decrypt_tk.c \
+ $(srcdir)/enc_helper.c \
$(srcdir)/encode_kdc.c \
$(srcdir)/encrypt_tk.c \
$(srcdir)/free_rtree.c \
diff --git a/src/lib/krb5/krb/auth_con.c b/src/lib/krb5/krb/auth_con.c
index 379508623..335f7ae7d 100644
--- a/src/lib/krb5/krb/auth_con.c
+++ b/src/lib/krb5/krb/auth_con.c
@@ -1,4 +1,3 @@
-
#include "k5-int.h"
#include "auth_con.h"
@@ -71,6 +70,8 @@ krb5_auth_con_free(context, auth_context)
krb5_free_keyblock(context, auth_context->remote_subkey);
if (auth_context->rcache)
krb5_rc_close(context, auth_context->rcache);
+ if (auth_context->permitted_etypes)
+ krb5_xfree(auth_context->permitted_etypes);
free(auth_context);
return 0;
}
@@ -274,12 +275,16 @@ krb5_auth_con_initivector(context, auth_context)
krb5_context context;
krb5_auth_context auth_context;
{
+ krb5_error_code ret;
+
if (auth_context->keyblock) {
- int size = krb5_enctype_array[auth_context->keyblock->enctype]->
- system->block_length;
+ size_t blocksize;
- if ((auth_context->i_vector = (krb5_pointer)malloc(size))) {
- memset(auth_context->i_vector, 0, size);
+ if ((ret = krb5_c_block_size(context, auth_context->keyblock->enctype,
+ &blocksize)))
+ return(ret);
+ if ((auth_context->i_vector = (krb5_pointer)malloc(blocksize))) {
+ memset(auth_context->i_vector, 0, blocksize);
return 0;
}
return ENOMEM;
@@ -347,3 +352,58 @@ krb5_auth_con_getrcache(context, auth_context, rcache)
return 0;
}
+krb5_error_code
+krb5_auth_con_setpermetypes(context, auth_context, permetypes)
+ krb5_context context;
+ krb5_auth_context auth_context;
+ const krb5_enctype * permetypes;
+{
+ krb5_enctype * newpe;
+ int i;
+
+ for (i=0; permetypes[i]; i++)
+ ;
+ i++; /* include the zero */
+
+ if ((newpe = (krb5_enctype *) malloc(i*sizeof(krb5_enctype)))
+ == NULL)
+ return(ENOMEM);
+
+ if (auth_context->permitted_etypes)
+ krb5_xfree(auth_context->permitted_etypes);
+
+ auth_context->permitted_etypes = newpe;
+
+ memcpy(newpe, permetypes, i*sizeof(krb5_enctype));
+
+ return 0;
+}
+
+krb5_error_code
+krb5_auth_con_getpermetypes(context, auth_context, permetypes)
+ krb5_context context;
+ krb5_auth_context auth_context;
+ krb5_enctype ** permetypes;
+{
+ krb5_enctype * newpe;
+ int i;
+
+ if (! auth_context->permitted_etypes) {
+ *permetypes = NULL;
+ return(0);
+ }
+
+ for (i=0; auth_context->permitted_etypes[i]; i++)
+ ;
+ i++; /* include the zero */
+
+ if ((newpe = (krb5_enctype *) malloc(i*sizeof(krb5_enctype)))
+ == NULL)
+ return(ENOMEM);
+
+ *permetypes = newpe;
+
+ memcpy(newpe, auth_context->permitted_etypes, i*sizeof(krb5_enctype));
+
+ return(0);
+}
diff --git a/src/lib/krb5/krb/auth_con.h b/src/lib/krb5/krb/auth_con.h
index 9d9df0e86..e6704169e 100644
--- a/src/lib/krb5/krb/auth_con.h
+++ b/src/lib/krb5/krb/auth_con.h
@@ -20,6 +20,7 @@ struct _krb5_auth_context {
krb5_cksumtype safe_cksumtype; /* mk_safe, ... */
krb5_pointer i_vector; /* mk_priv, rd_priv only */
krb5_rcache rcache;
+ krb5_enctype * permitted_etypes; /* rd_req */
};
diff --git a/src/lib/krb5/krb/decode_kdc.c b/src/lib/krb5/krb/decode_kdc.c
index 71e01a811..60c983878 100644
--- a/src/lib/krb5/krb/decode_kdc.c
+++ b/src/lib/krb5/krb/decode_kdc.c
@@ -48,18 +48,28 @@ krb5_decode_kdc_rep(context, enc_rep, key, dec_rep)
{
krb5_error_code retval;
krb5_kdc_rep *local_dec_rep;
+ krb5_keyusage usage;
- if (krb5_is_as_rep(enc_rep))
+ if (krb5_is_as_rep(enc_rep)) {
+ usage = KRB5_KEYUSAGE_AS_REP_ENCPART;
retval = decode_krb5_as_rep(enc_rep, &local_dec_rep);
- else if (krb5_is_tgs_rep(enc_rep))
+ } else if (krb5_is_tgs_rep(enc_rep)) {
+ usage = KRB5_KEYUSAGE_TGS_REP_ENCPART_SESSKEY;
+ /* KRB5_KEYUSAGE_TGS_REP_ENCPART_SUBKEY would go here, except
+ that this client code base doesn't ever put a subkey in the
+ tgs_req authenticator, so the tgs_rep is never encrypted in
+ one. (Check send_tgs.c:krb5_send_tgs_basic(), near the top
+ where authent.subkey is set to 0) */
retval = decode_krb5_tgs_rep(enc_rep, &local_dec_rep);
- else
+ } else {
return KRB5KRB_AP_ERR_MSG_TYPE;
+ }
if (retval)
return retval;
- if (retval = krb5_kdc_rep_decrypt_proc(context, key, 0, local_dec_rep))
+ if (retval = krb5_kdc_rep_decrypt_proc(context, key, &usage,
+ local_dec_rep))
krb5_free_kdc_rep(context, local_dec_rep);
else
*dec_rep = local_dec_rep;
diff --git a/src/lib/krb5/krb/decrypt_tk.c b/src/lib/krb5/krb/decrypt_tk.c
index 354a3f2a0..47f675591 100644
--- a/src/lib/krb5/krb/decrypt_tk.c
+++ b/src/lib/krb5/krb/decrypt_tk.c
@@ -42,43 +42,27 @@ krb5_decrypt_tkt_part(context, srv_key, ticket)
register krb5_ticket FAR *ticket;
{
krb5_enc_tkt_part *dec_tkt_part;
- krb5_encrypt_block eblock;
krb5_data scratch;
krb5_error_code retval;
if (!valid_enctype(ticket->enc_part.enctype))
return KRB5_PROG_ETYPE_NOSUPP;
- /* put together an eblock for this encryption */
- krb5_use_enctype(context, &eblock, ticket->enc_part.enctype);
-
scratch.length = ticket->enc_part.ciphertext.length;
if (!(scratch.data = malloc(ticket->enc_part.ciphertext.length)))
return(ENOMEM);
- /* do any necessary key pre-processing */
- if (retval = krb5_process_key(context, &eblock, srv_key)) {
- free(scratch.data);
- return(retval);
- }
-
/* call the encryption routine */
- if (retval = krb5_decrypt(context,
- (krb5_pointer) ticket->enc_part.ciphertext.data,
- (krb5_pointer) scratch.data, scratch.length,
- &eblock, 0)) {
- (void) krb5_finish_key(context, &eblock);
+ if (retval = krb5_c_decrypt(context, srv_key,
+ KRB5_KEYUSAGE_KDC_REP_TICKET, 0,
+ &ticket->enc_part, &scratch)) {
free(scratch.data);
return retval;
}
+
#define clean_scratch() {memset(scratch.data, 0, scratch.length); \
free(scratch.data);}
- retval = krb5_finish_key(context, &eblock);
- if (retval) {
- clean_scratch();
- return retval;
- }
/* now decode the decrypted stuff */
retval = decode_krb5_enc_tkt_part(&scratch, &dec_tkt_part);
if (!retval) {
diff --git a/src/lib/krb5/krb/enc_helper.c b/src/lib/krb5/krb/enc_helper.c
new file mode 100644
index 000000000..ff4214937
--- /dev/null
+++ b/src/lib/krb5/krb/enc_helper.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 1998 by the FundsXpress, INC.
+ *
+ * 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 FundsXpress. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. FundsXpress makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include "k5-int.h"
+
+krb5_error_code
+krb5_encrypt_helper(context, key, usage, plain, cipher)
+ krb5_context context;
+ krb5_const krb5_keyblock *key;
+ krb5_keyusage usage;
+ krb5_const krb5_data *plain;
+ krb5_enc_data *cipher;
+{
+ krb5_error_code ret;
+ size_t enclen;
+
+ if (ret = krb5_c_encrypt_length(context, key->enctype, plain->length,
+ &enclen))
+ return(ret);
+
+ cipher->ciphertext.length = enclen;
+ if ((cipher->ciphertext.data = (char *) malloc(enclen)) == NULL)
+ return(ret);
+
+ if (ret = krb5_c_encrypt(context, key, usage, 0, plain, cipher))
+ free(cipher->ciphertext.data);
+
+ return(ret);
+}
+
diff --git a/src/lib/krb5/krb/encode_kdc.c b/src/lib/krb5/krb/encode_kdc.c
index bb9311f6a..e20c1f536 100644
--- a/src/lib/krb5/krb/encode_kdc.c
+++ b/src/lib/krb5/krb/encode_kdc.c
@@ -41,10 +41,12 @@
/* due to argument promotion rules, we need to use the DECLARG/OLDDECLARG
stuff... */
krb5_error_code
-krb5_encode_kdc_rep(context, type, encpart, client_key, dec_rep, enc_rep)
+krb5_encode_kdc_rep(context, type, encpart, using_subkey, client_key,
+ dec_rep, enc_rep)
krb5_context context;
const krb5_msgtype type;
const krb5_enc_kdc_rep_part * encpart;
+ int using_subkey;
const krb5_keyblock * client_key;
krb5_kdc_rep * dec_rep;
krb5_data ** enc_rep;
@@ -52,14 +54,20 @@ krb5_encode_kdc_rep(context, type, encpart, client_key, dec_rep, enc_rep)
krb5_data *scratch;
krb5_error_code retval;
krb5_enc_kdc_rep_part tmp_encpart;
- krb5_encrypt_block eblock;
+ krb5_keyusage usage;
if (!valid_enctype(dec_rep->enc_part.enctype))
return KRB5_PROG_ETYPE_NOSUPP;
switch (type) {
case KRB5_AS_REP:
+ usage = KRB5_KEYUSAGE_AS_REP_ENCPART;
+ break;
case KRB5_TGS_REP:
+ if (using_subkey)
+ usage = KRB5_KEYUSAGE_TGS_REP_ENCPART_SUBKEY;
+ else
+ usage = KRB5_KEYUSAGE_TGS_REP_ENCPART_SESSKEY;
break;
default:
return KRB5_BADMSGTYPE;
@@ -89,23 +97,8 @@ krb5_encode_kdc_rep(context, type, encpart, client_key, dec_rep, enc_rep)
#define cleanup_scratch() { (void) memset(scratch->data, 0, scratch->length); \
krb5_free_data(context, scratch); }
- krb5_use_enctype(context, &eblock, client_key->enctype);
- dec_rep->enc_part.ciphertext.length =
- krb5_encrypt_size(scratch->length, eblock.crypto_entry);
- /* add padding area, and zero it */
- if (!(scratch->data = realloc(scratch->data,
- dec_rep->enc_part.ciphertext.length))) {
- /* may destroy scratch->data */
- krb5_xfree(scratch);
- return ENOMEM;
- }
- memset(scratch->data + scratch->length, 0,
- dec_rep->enc_part.ciphertext.length - scratch->length);
- if (!(dec_rep->enc_part.ciphertext.data =
- malloc(dec_rep->enc_part.ciphertext.length))) {
- retval = ENOMEM;
- goto clean_scratch;
- }
+ retval = krb5_encrypt_helper(context, client_key, usage, scratch,
+ &dec_rep->enc_part);
#define cleanup_encpart() { \
(void) memset(dec_rep->enc_part.ciphertext.data, 0, \
@@ -114,30 +107,10 @@ free(dec_rep->enc_part.ciphertext.data); \
dec_rep->enc_part.ciphertext.length = 0; \
dec_rep->enc_part.ciphertext.data = 0;}
- retval = krb5_process_key(context, &eblock, client_key);
- if (retval) {
- goto clean_encpart;
- }
-
-#define cleanup_prockey() {(void) krb5_finish_key(context, &eblock);}
-
- retval = krb5_encrypt(context, (krb5_pointer) scratch->data,
- (krb5_pointer) dec_rep->enc_part.ciphertext.data,
- scratch->length, &eblock, 0);
- if (retval) {
- goto clean_prockey;
- }
-
- dec_rep->enc_part.enctype = krb5_eblock_enctype(context, &eblock);
-
- /* do some cleanup */
cleanup_scratch();
- retval = krb5_finish_key(context, &eblock);
- if (retval) {
- cleanup_encpart();
- return retval;
- }
+ if (retval)
+ return(retval);
/* now it's ready to be encoded for the wire! */
@@ -149,18 +122,9 @@ dec_rep->enc_part.ciphertext.data = 0;}
retval = encode_krb5_tgs_rep(dec_rep, enc_rep);
break;
}
+
if (retval)
cleanup_encpart();
- return retval;
-
- clean_prockey:
- cleanup_prockey();
- clean_encpart:
- cleanup_encpart();
- clean_scratch:
- cleanup_scratch();
return retval;
}
-
-
diff --git a/src/lib/krb5/krb/encrypt_tk.c b/src/lib/krb5/krb/encrypt_tk.c
index cb1fb28b9..e1a1b1850 100644
--- a/src/lib/krb5/krb/encrypt_tk.c
+++ b/src/lib/krb5/krb/encrypt_tk.c
@@ -44,7 +44,6 @@ krb5_encrypt_tkt_part(context, srv_key, dec_ticket)
const krb5_keyblock *srv_key;
register krb5_ticket *dec_ticket;
{
- krb5_encrypt_block eblock;
krb5_data *scratch;
krb5_error_code retval;
register krb5_enc_tkt_part *dec_tkt_part = dec_ticket->enc_part2;
@@ -57,64 +56,12 @@ krb5_encrypt_tkt_part(context, srv_key, dec_ticket)
#define cleanup_scratch() { (void) memset(scratch->data, 0, scratch->length); \
krb5_free_data(context, scratch); }
- krb5_use_enctype(context, &eblock, srv_key->enctype);
-
- dec_ticket->enc_part.ciphertext.length =
- krb5_encrypt_size(scratch->length, eblock.crypto_entry);
- /* add padding area, and zero it */
- if (!(scratch->data = realloc(scratch->data,
- dec_ticket->enc_part.ciphertext.length))) {
- /* may destroy scratch->data */
- krb5_xfree(scratch);
- return ENOMEM;
- }
- memset(scratch->data + scratch->length, 0,
- dec_ticket->enc_part.ciphertext.length - scratch->length);
- if (!(dec_ticket->enc_part.ciphertext.data =
- malloc(dec_ticket->enc_part.ciphertext.length))) {
- retval = ENOMEM;
- goto clean_scratch;
- }
-
-#define cleanup_encpart() {\
-(void) memset(dec_ticket->enc_part.ciphertext.data, 0,\
- dec_ticket->enc_part.ciphertext.length); \
-free(dec_ticket->enc_part.ciphertext.data); \
-dec_ticket->enc_part.ciphertext.length = 0; \
-dec_ticket->enc_part.ciphertext.data = 0;}
-
- /* do any necessary key pre-processing */
- if ((retval = krb5_process_key(context, &eblock, srv_key))) {
- goto clean_encpart;
- }
-
-#define cleanup_prockey() {(void) krb5_finish_key(context, &eblock);}
-
/* call the encryption routine */
- if ((retval = krb5_encrypt(context, (krb5_pointer) scratch->data,
- (krb5_pointer) dec_ticket->enc_part.ciphertext.data,
- scratch->length, &eblock, 0))) {
- goto clean_prockey;
- }
-
- dec_ticket->enc_part.enctype = srv_key->enctype;
-
- /* ticket is now assembled-- do some cleanup */
- cleanup_scratch();
-
- if ((retval = krb5_finish_key(context, &eblock))) {
- cleanup_encpart();
- return retval;
- }
-
- return 0;
+ retval = krb5_encrypt_helper(context, srv_key,
+ KRB5_KEYUSAGE_KDC_REP_TICKET, scratch,
+ &dec_ticket->enc_part);
- clean_prockey:
- cleanup_prockey();
- clean_encpart:
- cleanup_encpart();
- clean_scratch:
cleanup_scratch();
- return retval;
+ return(retval);
}
diff --git a/src/lib/krb5/krb/gen_seqnum.c b/src/lib/krb5/krb/gen_seqnum.c
index 3694d2cd0..4b3cd6fe6 100644
--- a/src/lib/krb5/krb/gen_seqnum.c
+++ b/src/lib/krb5/krb/gen_seqnum.c
@@ -38,71 +38,15 @@ krb5_generate_seq_number(context, key, seqno)
const krb5_keyblock *key;
krb5_int32 *seqno;
{
- krb5_pointer random_state;
- krb5_encrypt_block eblock;
- krb5_keyblock *subkey = 0;
+ krb5_data seed;
krb5_error_code retval;
- struct tval {
- krb5_int32 seconds;
- krb5_int32 microseconds;
- } timenow;
- krb5_octet *intmp = 0, *outtmp = 0;
- int esize;
- if (!valid_enctype(key->enctype))
- return KRB5_PROG_ETYPE_NOSUPP;
-
- krb5_use_enctype(context, &eblock, key->enctype);
-
- if ((retval = krb5_init_random_key(context, &eblock, key, &random_state)))
+ seed.length = key->length;
+ seed.data = key->contents;
+ if ((retval = krb5_c_random_seed(context, &seed)))
return(retval);
-
- if ((retval = krb5_random_key(context, &eblock, random_state, &subkey))) {
- (void) krb5_finish_random_key(context, &eblock, &random_state);
- return retval;
- }
- /* ignore the error if any, since we've already gotten the key out */
- if ((retval = krb5_finish_random_key(context, &eblock, &random_state))) {
- krb5_free_keyblock(context, subkey);
- return retval;
- }
-
- esize = krb5_encrypt_size(sizeof(timenow), eblock.crypto_entry);
- intmp = (krb5_octet *)malloc(esize);
- if (!intmp) {
- retval = ENOMEM;
- goto cleanup;
- }
- outtmp = (krb5_octet *)malloc(esize);
- if (!outtmp) {
- retval = ENOMEM;
- goto cleanup;
- }
- if ((retval = krb5_process_key(context, &eblock, subkey))) {
- goto cleanup;
- }
- if ((retval = krb5_us_timeofday(context, &timenow.seconds,
- &timenow.microseconds))) {
- goto cleanup;
- }
- memcpy((char *)intmp, (char *)&timenow, sizeof(timenow));
-
- retval = krb5_encrypt(context, (krb5_pointer)intmp, (krb5_pointer)outtmp,
- sizeof(timenow), &eblock, 0);
- (void) krb5_finish_key(context, &eblock);
- if (retval)
- goto cleanup;
-
- memcpy((char *) seqno, (char *)outtmp, sizeof(krb5_int32));
-
-cleanup:
- if (subkey)
- krb5_free_keyblock(context, subkey);
- if (intmp)
- krb5_xfree(intmp);
- if (outtmp)
- krb5_xfree(outtmp);
- return retval;
+ seed.length = sizeof(*seqno);
+ seed.data = (char *) seqno;
+ return(krb5_c_random_make_octets(context, &seed));
}
-
diff --git a/src/lib/krb5/krb/gen_subkey.c b/src/lib/krb5/krb/gen_subkey.c
index 89e21a1b7..861d61e72 100644
--- a/src/lib/krb5/krb/gen_subkey.c
+++ b/src/lib/krb5/krb/gen_subkey.c
@@ -32,24 +32,21 @@ krb5_generate_subkey(context, key, subkey)
const krb5_keyblock *key;
krb5_keyblock **subkey;
{
- krb5_pointer random_state;
- krb5_encrypt_block eblock;
krb5_error_code retval;
+ krb5_data seed;
- if (!valid_enctype(key->enctype))
- return KRB5_PROG_ETYPE_NOSUPP;
+ seed.length = key->length;
+ seed.data = key->contents;
+ if ((retval = krb5_c_random_seed(context, &seed)))
+ return(retval);
- krb5_use_enctype(context, &eblock, key->enctype);
+ if ((*subkey = (krb5_keyblock *) malloc(sizeof(krb5_keyblock))) == NULL)
+ return(ENOMEM);
- if ((retval = krb5_init_random_key(context, &eblock, key, &random_state)))
- return(retval);
- if ((retval = krb5_random_key(context, &eblock, random_state, subkey))) {
- (void) krb5_finish_random_key(context, &eblock, &random_state);
+ if ((retval = krb5_c_make_random_key(context, key->enctype, *subkey))) {
krb5_xfree(*subkey);
- return retval;
- }
- /* ignore the error if any, since we've already gotten the key out */
- (void) krb5_finish_random_key(context, &eblock, &random_state);
- return 0;
-}
+ return(retval);
+ }
+ return(0);
+}
diff --git a/src/lib/krb5/krb/get_creds.c b/src/lib/krb5/krb/get_creds.c
index 3a1ec526b..37f2bb5a9 100644
--- a/src/lib/krb5/krb/get_creds.c
+++ b/src/lib/krb5/krb/get_creds.c
@@ -160,12 +160,6 @@ krb5_get_credentials_val_renew_core(context, options, ccache,
krb5_creds **tgts = 0;
krb5_flags fields;
- retval = krb5_get_credentials_core(context, options, ccache,
- in_creds, out_creds,
- &mcreds, &fields);
-
- if (retval) return retval;
-
switch(which) {
case INT_GC_VALIDATE:
retval = krb5_get_cred_from_kdc_validate(context, ccache,
@@ -219,3 +213,104 @@ krb5_get_credentials_renew(context, options, ccache, in_creds, out_creds)
in_creds, out_creds,
INT_GC_RENEW));
}
+
+static krb5_error_code
+krb5_validate_or_renew_creds(context, creds, client, ccache, in_tkt_service,
+ validate)
+ krb5_context context;
+ krb5_creds *creds;
+ krb5_principal client;
+ krb5_ccache ccache;
+ char *in_tkt_service;
+ int validate;
+{
+ krb5_error_code ret;
+ krb5_creds in_creds; /* only client and server need to be filled in */
+ krb5_creds *out_creds;
+ krb5_creds **tgts;
+
+ memset((char *)&in_creds, 0, sizeof(krb5_creds));
+
+ in_creds.server = NULL;
+ tgts = NULL;
+
+ in_creds.client = client;
+
+ if (in_tkt_service) {
+ /* this is ugly, because so are the data structures involved. I'm
+ in the library, so I'm going to manipulate the data structures
+ directly, otherwise, it will be worse. */
+
+ if (ret = krb5_parse_name(context, in_tkt_service, &in_creds.server))
+ goto cleanup;
+
+ /* stuff the client realm into the server principal.
+ realloc if necessary */
+ if (in_creds.server->realm.length < in_creds.client->realm.length)
+ if ((in_creds.server->realm.data =
+ (char *) realloc(in_creds.server->realm.data,
+ in_creds.client->realm.length)) == NULL) {
+ ret = ENOMEM;
+ goto cleanup;
+ }
+
+ in_creds.server->realm.length = in_creds.client->realm.length;
+ memcpy(in_creds.server->realm.data, in_creds.client->realm.data,
+ in_creds.client->realm.length);
+ } else {
+ if (ret = krb5_build_principal_ext(context, &in_creds.server,
+ in_creds.client->realm.length,
+ in_creds.client->realm.data,
+ KRB5_TGS_NAME_SIZE,
+ KRB5_TGS_NAME,
+ in_creds.client->realm.length,
+ in_creds.client->realm.data,
+ 0))
+ goto cleanup;
+ }
+
+ if (validate)
+ ret = krb5_get_cred_from_kdc_validate(context, ccache,
+ &in_creds, &out_creds, &tgts);
+ else
+ ret = krb5_get_cred_from_kdc_renew(context, ccache,
+ &in_creds, &out_creds, &tgts);
+
+ /* ick. copy the struct contents, free the container */
+
+ *creds = *out_creds;
+ krb5_xfree(out_creds);
+
+cleanup:
+
+ if (in_creds.server)
+ krb5_free_principal(context, in_creds.server);
+ if (tgts)
+ krb5_free_tgt_creds(context, tgts);
+
+ return(ret);
+}
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+krb5_get_validated_creds(context, creds, client, ccache, in_tkt_service)
+ krb5_context context;
+ krb5_creds *creds;
+ krb5_principal client;
+ krb5_ccache ccache;
+ char *in_tkt_service;
+{
+ return(krb5_validate_or_renew_creds(context, creds, client, ccache,
+ in_tkt_service, 1));
+}
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+krb5_get_renewed_creds(context, creds, client, ccache, in_tkt_service)
+ krb5_context context;
+ krb5_creds *creds;
+ krb5_principal client;
+ krb5_ccache ccache;
+ char *in_tkt_service;
+{
+ return(krb5_validate_or_renew_creds(context, creds, client, ccache,
+ in_tkt_service, 0));
+}
diff --git a/src/lib/krb5/krb/gic_pwd.c b/src/lib/krb5/krb/gic_pwd.c
index 45a076246..c517062f8 100644
--- a/src/lib/krb5/krb/gic_pwd.c
+++ b/src/lib/krb5/krb/gic_pwd.c
@@ -16,7 +16,6 @@ krb5_get_as_key_password(context, client, etype, prompter, prompter_data,
krb5_data *password;
krb5_error_code ret;
krb5_data defsalt;
- krb5_encrypt_block eblock;
char *clientstr;
char promptstr[1024];
krb5_prompt prompt;
@@ -35,11 +34,6 @@ krb5_get_as_key_password(context, client, etype, prompter, prompter_data,
as_key->length = 0;
}
- if (!valid_enctype(etype))
- return(KRB5_PROG_ETYPE_NOSUPP);
-
- krb5_use_enctype(context, &eblock, etype);
-
if (password->data[0] == '\0') {
if (prompter == NULL)
return(EIO);
@@ -70,7 +64,7 @@ krb5_get_as_key_password(context, client, etype, prompter, prompter_data,
defsalt.length = 0;
}
- ret = krb5_string_to_key(context, &eblock, as_key, password, salt);
+ ret = krb5_c_string_to_key(context, etype, password, salt, as_key);
if (defsalt.length)
krb5_xfree(defsalt.data);
diff --git a/src/lib/krb5/krb/in_tkt_pwd.c b/src/lib/krb5/krb/in_tkt_pwd.c
index 7373f62f1..e03883e9d 100644
--- a/src/lib/krb5/krb/in_tkt_pwd.c
+++ b/src/lib/krb5/krb/in_tkt_pwd.c
@@ -47,15 +47,9 @@ pwd_keyproc(context, type, salt, keyseed, key)
krb5_keyblock ** key;
{
krb5_error_code retval;
- krb5_encrypt_block eblock;
krb5_data * password;
int pwsize;
- if (!valid_enctype(type))
- return KRB5_PROG_ETYPE_NOSUPP;
-
- krb5_use_enctype(context, &eblock, type);
-
password = (krb5_data *)keyseed;
if (!password->length) {
@@ -73,8 +67,9 @@ pwd_keyproc(context, type, salt, keyseed, key)
if (!(*key = (krb5_keyblock *)malloc(sizeof(**key))))
return ENOMEM;
- if ((retval = krb5_string_to_key(context, &eblock, *key, password, salt)))
+ if ((retval = krb5_c_string_to_key(context, type, password, salt, *key)))
krb5_xfree(*key);
+
return(retval);
}
diff --git a/src/lib/krb5/krb/init_ctx.c b/src/lib/krb5/krb/init_ctx.c
index daa9fd95f..2285b0f42 100644
--- a/src/lib/krb5/krb/init_ctx.c
+++ b/src/lib/krb5/krb/init_ctx.c
@@ -23,6 +23,32 @@
* krb5_init_contex()
*/
+/*
+ * Copyright (C) 1998 by the FundsXpress, INC.
+ *
+ * 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 FundsXpress. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. FundsXpress makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
#include "k5-int.h"
#include <ctype.h>
#include "brand.c"
@@ -37,6 +63,8 @@ krb5_init_context(context)
{
krb5_context ctx = 0;
krb5_error_code retval;
+ krb5_timestamp now;
+ krb5_data seed;
int tmp;
/* Initialize error tables */
@@ -70,6 +98,14 @@ krb5_init_context(context)
if ((retval = krb5_os_init_context(ctx)))
goto cleanup;
+ /* initialize the prng (not well, but passable) */
+ if ((retval = krb5_timeofday(ctx, &now)))
+ goto cleanup;
+ seed.length = sizeof(now);
+ seed.data = (char *) &now;
+ if ((retval = krb5_c_random_seed(ctx, &seed)))
+ goto cleanup;
+
ctx->default_realm = 0;
profile_get_integer(ctx->profile, "libdefaults", "clockskew",
0, 5 * 60, &tmp);
@@ -197,26 +233,27 @@ krb5_set_default_in_tkt_ktypes(context, ktypes)
return 0;
}
-krb5_error_code
-krb5_get_default_in_tkt_ktypes(context, ktypes)
- krb5_context context;
- krb5_enctype **ktypes;
+static krb5_error_code
+get_profile_etype_list(context, ktypes, profstr, ctx_count, ctx_list)
+ krb5_context context;
+ krb5_enctype **ktypes;
+ char *profstr;
+ int ctx_count;
+ krb5_enctype FAR *ctx_list;
{
- krb5_enctype * old_ktypes;
+ krb5_enctype *old_ktypes;
if (context->in_tkt_ktype_count) {
- /* application-set defaults */
- if ((old_ktypes =
- (krb5_enctype *)malloc(sizeof(krb5_enctype) *
- (context->in_tkt_ktype_count + 1)))) {
- memcpy(old_ktypes, context->in_tkt_ktypes, sizeof(krb5_enctype) *
- context->in_tkt_ktype_count);
- old_ktypes[context->in_tkt_ktype_count] = 0;
- } else {
- return ENOMEM;
- }
+ /* application-set defaults */
+ if ((old_ktypes =
+ (krb5_enctype *)malloc(sizeof(krb5_enctype) *
+ (ctx_count + 1)))) {
+ memcpy(old_ktypes, ctx_list, sizeof(krb5_enctype) * ctx_count);
+ old_ktypes[ctx_count] = 0;
+ } else {
+ return ENOMEM;
+ }
} else {
- /* taken directly from krb5_get_tgs_ktypes... */
/*
XXX - For now, we only support libdefaults
Perhaps this should be extended to allow for per-host / per-realm
@@ -228,9 +265,9 @@ krb5_get_default_in_tkt_ktypes(context, ktypes)
int i, j, count;
krb5_error_code code;
- code = profile_get_string(context->profile,
- "libdefaults", "default_tkt_enctypes", NULL,
- "des-cbc-md5 des-cbc-crc",
+ code = profile_get_string(context->profile, "libdefaults", profstr,
+ NULL,
+ "des3-hmac-sha1 des-cbc-md5 des-cbc-crc",
&retval);
if (code)
return code;
@@ -280,6 +317,16 @@ krb5_get_default_in_tkt_ktypes(context, ktypes)
}
krb5_error_code
+krb5_get_default_in_tkt_ktypes(context, ktypes)
+ krb5_context context;
+ krb5_enctype **ktypes;
+{
+ return(get_profile_etype_list(context, ktypes, "default_tkt_enctypes",
+ context->in_tkt_ktype_count,
+ context->in_tkt_ktypes));
+}
+
+krb5_error_code
krb5_set_default_tgs_ktypes(context, ktypes)
krb5_context context;
const krb5_enctype *ktypes;
@@ -317,80 +364,40 @@ krb5_get_tgs_ktypes(context, princ, ktypes)
krb5_const_principal princ;
krb5_enctype **ktypes;
{
- krb5_enctype * old_ktypes;
-
- if (context->tgs_ktype_count) {
-
- /* Application-set defaults */
-
- if ((old_ktypes =
- (krb5_enctype *)malloc(sizeof(krb5_enctype) *
- (context->tgs_ktype_count + 1)))) {
- memcpy(old_ktypes, context->tgs_ktypes, sizeof(krb5_enctype) *
- context->tgs_ktype_count);
- old_ktypes[context->tgs_ktype_count] = 0;
- } else {
- return ENOMEM;
- }
- } else {
- /*
- XXX - For now, we only support libdefaults
- Perhaps this should be extended to allow for per-host / per-realm
- session key types.
- */
-
- char *retval;
- char *sp, *ep;
- int i, j, count;
- krb5_error_code code;
+ return(get_profile_etype_list(context, ktypes, "default_tgs_enctypes",
+ context->tgs_ktype_count,
+ context->tgs_ktypes));
+}
- code = profile_get_string(context->profile,
- "libdefaults", "default_tgs_enctypes", NULL,
- "des-cbc-md5 des-cbc-crc",
- &retval);
- if (code)
- return code;
+krb5_error_code
+krb5_get_permitted_enctypes(context, ktypes)
+ krb5_context context;
+ krb5_enctype **ktypes;
+{
+ return(get_profile_etype_list(context, ktypes, "permitted_enctypes",
+ context->tgs_ktype_count,
+ context->tgs_ktypes));
+}
- count = 0;
- sp = retval;
- while (sp) {
- for (ep = sp; *ep && (*ep != ',') && !isspace(*ep); ep++)
- ;
- if (*ep) {
- *ep++ = '\0';
- while (isspace(*ep))
- ep++;
- } else
- ep = (char *) NULL;
+krb5_boolean
+krb5_is_permitted_enctype(context, etype)
+ krb5_context context;
+ krb5_enctype etype;
+{
+ krb5_enctype *list, *ptr;
+ krb5_boolean ret;
- count++;
- sp = ep;
- }
-
- if ((old_ktypes =
- (krb5_enctype *)malloc(sizeof(krb5_enctype) * (count + 1))) ==
- (krb5_enctype *) NULL)
- return ENOMEM;
-
- sp = retval;
- j = 0;
- i = 1;
- while (1) {
- if (! krb5_string_to_enctype(sp, &old_ktypes[j]))
- j++;
+ if (krb5_get_permitted_enctypes(context, &list))
+ return(0);
- if (i++ >= count)
- break;
+
+ ret = 0;
- /* skip to next token */
- while (*sp) sp++;
- while (! *sp) sp++;
- }
+ for (ptr = list; *ptr; ptr++)
+ if (*ptr == etype)
+ ret = 1;
- old_ktypes[j] = (krb5_enctype) 0;
- free(retval);
- }
+ krb5_xfree(list);
- *ktypes = old_ktypes;
- return 0;
+ return(ret);
}
diff --git a/src/lib/krb5/krb/kdc_rep_dc.c b/src/lib/krb5/krb/kdc_rep_dc.c
index e9431aef9..a9cbcf39b 100644
--- a/src/lib/krb5/krb/kdc_rep_dc.c
+++ b/src/lib/krb5/krb/kdc_rep_dc.c
@@ -41,12 +41,15 @@ krb5_kdc_rep_decrypt_proc(context, key, decryptarg, dec_rep)
krb5_kdc_rep * dec_rep;
{
krb5_error_code retval;
- krb5_encrypt_block eblock;
krb5_data scratch;
krb5_enc_kdc_rep_part *local_encpart;
+ krb5_keyusage usage;
- if (!valid_enctype(dec_rep->enc_part.enctype))
- return KRB5_PROG_ETYPE_NOSUPP;
+ if (decryptarg) {
+ usage = *(const krb5_keyusage *) decryptarg;
+ } else {
+ usage = KRB5_KEYUSAGE_AS_REP_ENCPART;
+ }
/* set up scratch decrypt/decode area */
@@ -55,30 +58,16 @@ krb5_kdc_rep_decrypt_proc(context, key, decryptarg, dec_rep)
return(ENOMEM);
}
- /* put together an eblock for this encryption */
-
- krb5_use_enctype(context, &eblock, dec_rep->enc_part.enctype);
+ dec_rep->enc_part.enctype;
- /* do any necessary key pre-processing */
- if ((retval = krb5_process_key(context, &eblock, key))) {
+ if ((retval = krb5_c_decrypt(context, key, usage, 0, &dec_rep->enc_part,
+ &scratch))) {
free(scratch.data);
return(retval);
}
- /* call the decryption routine */
- if ((retval = krb5_decrypt(context, (krb5_pointer) dec_rep->enc_part.ciphertext.data,
- (krb5_pointer) scratch.data,
- scratch.length, &eblock, 0))) {
- (void) krb5_finish_key(context, &eblock);
- free(scratch.data);
- return retval;
- }
#define clean_scratch() {memset(scratch.data, 0, scratch.length); \
free(scratch.data);}
- if ((retval = krb5_finish_key(context, &eblock))) {
- clean_scratch();
- return retval;
- }
/* and do the decode */
retval = decode_krb5_enc_kdc_rep_part(&scratch, &local_encpart);
diff --git a/src/lib/krb5/krb/kfree.c b/src/lib/krb5/krb/kfree.c
index 17c4f8c7f..87eeca961 100644
--- a/src/lib/krb5/krb/kfree.c
+++ b/src/lib/krb5/krb/kfree.c
@@ -149,6 +149,16 @@ krb5_free_checksum(context, val)
}
KRB5_DLLIMP void KRB5_CALLCONV
+krb5_free_checksum_contents(context, val)
+ krb5_context context;
+ register krb5_checksum *val;
+{
+ if (val->contents)
+ krb5_xfree(val->contents);
+ return;
+}
+
+KRB5_DLLIMP void KRB5_CALLCONV
krb5_free_cred(context, val)
krb5_context context;
register krb5_cred FAR *val;
@@ -572,3 +582,4 @@ krb5_free_unparsed_name(context, val)
krb5_xfree(val);
return;
}
+
diff --git a/src/lib/krb5/krb/mk_cred.c b/src/lib/krb5/krb/mk_cred.c
index 23545fb61..cdda80d06 100644
--- a/src/lib/krb5/krb/mk_cred.c
+++ b/src/lib/krb5/krb/mk_cred.c
@@ -28,12 +28,8 @@ encrypt_credencpart(context, pcredpart, pkeyblock, pencdata)
krb5_enc_data * pencdata;
{
krb5_error_code retval;
- krb5_encrypt_block eblock;
krb5_data * scratch;
- if (pkeyblock && !valid_enctype(pkeyblock->enctype))
- return KRB5_PROG_ETYPE_NOSUPP;
-
/* start by encoding to-be-encrypted part of the message */
if ((retval = encode_krb5_enc_cred_part(pcredpart, &scratch)))
return retval;
@@ -49,47 +45,11 @@ encrypt_credencpart(context, pcredpart, pkeyblock, pencdata)
return 0;
}
- /* put together an eblock for this encryption */
-
- pencdata->kvno = 0;
- pencdata->enctype = pkeyblock->enctype;
-
- krb5_use_enctype(context, &eblock, pkeyblock->enctype);
- pencdata->ciphertext.length = krb5_encrypt_size(scratch->length,
- eblock.crypto_entry);
-
- /* add padding area, and zero it */
- if (!(scratch->data = (char *)realloc(scratch->data,
- pencdata->ciphertext.length))) {
- /* may destroy scratch->data */
- krb5_xfree(scratch);
- return ENOMEM;
- }
-
- memset(scratch->data + scratch->length, 0,
- pencdata->ciphertext.length - scratch->length);
- if (!(pencdata->ciphertext.data =
- (char *)malloc(pencdata->ciphertext.length))) {
- retval = ENOMEM;
- goto clean_scratch;
- }
-
- /* do any necessary key pre-processing */
- if ((retval = krb5_process_key(context, &eblock, pkeyblock))) {
- goto clean_encpart;
- }
-
/* call the encryption routine */
- if ((retval = krb5_encrypt(context, (krb5_pointer)scratch->data,
- (krb5_pointer)pencdata->ciphertext.data,
- scratch->length, &eblock, 0))) {
- krb5_finish_key(context, &eblock);
- goto clean_encpart;
- }
-
- retval = krb5_finish_key(context, &eblock);
+ retval = krb5_encrypt_helper(context, pkeyblock,
+ KRB5_KEYUSAGE_KRB_CRED_ENCPART,
+ scratch, pencdata);
-clean_encpart:
if (retval) {
memset(pencdata->ciphertext.data, 0, pencdata->ciphertext.length);
free(pencdata->ciphertext.data);
@@ -97,7 +57,6 @@ clean_encpart:
pencdata->ciphertext.data = 0;
}
-clean_scratch:
memset(scratch->data, 0, scratch->length);
krb5_free_data(context, scratch);
diff --git a/src/lib/krb5/krb/mk_priv.c b/src/lib/krb5/krb/mk_priv.c
index 7986e1856..2e7f2ce25 100644
--- a/src/lib/krb5/krb/mk_priv.c
+++ b/src/lib/krb5/krb/mk_priv.c
@@ -41,13 +41,10 @@ krb5_mk_priv_basic(context, userdata, keyblock, replaydata, local_addr,
krb5_data * outbuf;
{
krb5_error_code retval;
- krb5_encrypt_block eblock;
krb5_priv privmsg;
krb5_priv_enc_part privmsg_enc_part;
- krb5_data *scratch1, *scratch2;
-
- if (!valid_enctype(keyblock->enctype))
- return KRB5_PROG_ETYPE_NOSUPP;
+ krb5_data *scratch1, *scratch2, ivdata;
+ size_t blocksize, enclen;
privmsg.enc_part.kvno = 0; /* XXX allow user-set? */
privmsg.enc_part.enctype = keyblock->enctype;
@@ -66,52 +63,42 @@ krb5_mk_priv_basic(context, userdata, keyblock, replaydata, local_addr,
return retval;
/* put together an eblock for this encryption */
- krb5_use_enctype(context, &eblock, keyblock->enctype);
- privmsg.enc_part.ciphertext.length = krb5_encrypt_size(scratch1->length,
- eblock.crypto_entry);
- /* add padding area, and zero it */
- if (!(scratch1->data = realloc(scratch1->data,
- privmsg.enc_part.ciphertext.length))) {
- /* may destroy scratch1->data */
- krb5_xfree(scratch1);
- return ENOMEM;
- }
+ if ((retval = krb5_c_encrypt_length(context, keyblock->enctype,
+ scratch1->length, &enclen)))
+ goto clean_scratch;
- memset(scratch1->data + scratch1->length, 0,
- privmsg.enc_part.ciphertext.length - scratch1->length);
+ privmsg.enc_part.ciphertext.length = enclen;
if (!(privmsg.enc_part.ciphertext.data =
malloc(privmsg.enc_part.ciphertext.length))) {
retval = ENOMEM;
goto clean_scratch;
}
- /* do any necessary key pre-processing */
- if ((retval = krb5_process_key(context, &eblock, keyblock)))
- goto clean_encpart;
-
/* call the encryption routine */
- if ((retval = krb5_encrypt(context, (krb5_pointer) scratch1->data,
- (krb5_pointer) privmsg.enc_part.ciphertext.data,
- scratch1->length, &eblock, i_vector))) {
- krb5_finish_key(context, &eblock);
- goto clean_encpart;
+ if (i_vector) {
+ if ((retval = krb5_c_block_size(context, keyblock->enctype,
+ &blocksize)))
+ goto clean_encpart;
+
+ ivdata.length = blocksize;
+ ivdata.data = i_vector;
}
+ if ((retval = krb5_c_encrypt(context, keyblock,
+ KRB5_KEYUSAGE_KRB_PRIV_ENCPART,
+ i_vector?&ivdata:0,
+ scratch1, &privmsg.enc_part)))
+ goto clean_encpart;
+
/* put last block into the i_vector */
+
if (i_vector)
memcpy(i_vector,
privmsg.enc_part.ciphertext.data +
- (privmsg.enc_part.ciphertext.length -
- eblock.crypto_entry->block_length),
- eblock.crypto_entry->block_length);
+ (privmsg.enc_part.ciphertext.length - blocksize),
+ blocksize);
- if ((retval = encode_krb5_priv(&privmsg, &scratch2))) {
- krb5_finish_key(context, &eblock);
- goto clean_encpart;
- }
-
- /* encode private message */
- if ((retval = krb5_finish_key(context, &eblock)))
+ if ((retval = encode_krb5_priv(&privmsg, &scratch2)))
goto clean_encpart;
*outbuf = *scratch2;
diff --git a/src/lib/krb5/krb/mk_rep.c b/src/lib/krb5/krb/mk_rep.c
index 45784284c..f0398475f 100644
--- a/src/lib/krb5/krb/mk_rep.c
+++ b/src/lib/krb5/krb/mk_rep.c
@@ -45,14 +45,11 @@ krb5_mk_rep(context, auth_context, outbuf)
krb5_error_code retval;
krb5_enctype enctype;
krb5_ap_rep_enc_part repl;
- krb5_encrypt_block eblock;
krb5_ap_rep reply;
krb5_data * scratch;
krb5_data * toutbuf;
- /* verify a valid enctype is available */
- if (!valid_enctype(enctype = auth_context->keyblock->enctype))
- return KRB5_PROG_ETYPE_NOSUPP;
+ enctype = auth_context->keyblock->enctype;
/* Make the reply */
if (((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) ||
@@ -72,49 +69,16 @@ krb5_mk_rep(context, auth_context, outbuf)
if ((retval = encode_krb5_ap_rep_enc_part(&repl, &scratch)))
return retval;
- /* put together an eblock for this encryption */
- krb5_use_enctype(context, &eblock, enctype);
- reply.enc_part.enctype = enctype;
- reply.enc_part.kvno = 0; /* XXX user set? */
-
- reply.enc_part.ciphertext.length = krb5_encrypt_size(scratch->length,
- eblock.crypto_entry);
- /* add padding area, and zero it */
- if (!(scratch->data = realloc(scratch->data,
- reply.enc_part.ciphertext.length))) {
- /* may destroy scratch->data */
- krb5_xfree(scratch);
- return ENOMEM;
- }
- memset(scratch->data + scratch->length, 0,
- reply.enc_part.ciphertext.length - scratch->length);
- if (!(reply.enc_part.ciphertext.data =
- malloc(reply.enc_part.ciphertext.length))) {
- retval = ENOMEM;
+ if ((retval = krb5_encrypt_helper(context, auth_context->keyblock,
+ KRB5_KEYUSAGE_AP_REP_ENCPART,
+ scratch, &reply.enc_part)))
goto cleanup_scratch;
- }
-
- /* do any necessary key pre-processing */
- if ((retval = krb5_process_key(context, &eblock, auth_context->keyblock)))
- goto cleanup_encpart;
-
- /* call the encryption routine */
- if ((retval = krb5_encrypt(context, (krb5_pointer) scratch->data,
- (krb5_pointer) reply.enc_part.ciphertext.data,
- scratch->length, &eblock, 0))) {
- krb5_finish_key(context, &eblock);
- goto cleanup_encpart;
- }
-
- if ((retval = krb5_finish_key(context, &eblock)))
- goto cleanup_encpart;
if (!(retval = encode_krb5_ap_rep(&reply, &toutbuf))) {
*outbuf = *toutbuf;
krb5_xfree(toutbuf);
}
-cleanup_encpart:
memset(reply.enc_part.ciphertext.data, 0, reply.enc_part.ciphertext.length);
free(reply.enc_part.ciphertext.data);
reply.enc_part.ciphertext.length = 0;
diff --git a/src/lib/krb5/krb/mk_req_ext.c b/src/lib/krb5/krb/mk_req_ext.c
index 726bb434b..1530f7961 100644
--- a/src/lib/krb5/krb/mk_req_ext.c
+++ b/src/lib/krb5/krb/mk_req_ext.c
@@ -84,7 +84,6 @@ krb5_mk_req_extended(context, auth_context, ap_req_options, in_data, in_creds,
krb5_ap_req request;
krb5_data *scratch = 0;
- krb5_encrypt_block eblock;
krb5_data *toutbuf;
request.ap_options = ap_req_options & AP_OPTS_WIRE_MASK;
@@ -98,12 +97,6 @@ krb5_mk_req_extended(context, auth_context, ap_req_options, in_data, in_creds,
if ((retval = decode_krb5_ticket(&(in_creds)->ticket, &request.ticket)))
return(retval);
- /* verify a valid enctype is available */
- if (!valid_enctype(in_creds->keyblock.enctype)) {
- retval = KRB5_PROG_ETYPE_NOSUPP;
- goto cleanup;
- }
-
/* verify that the ticket is not expired */
if ((retval = krb5_validate_times(context, &in_creds->times)) != 0)
goto cleanup;
@@ -135,27 +128,18 @@ krb5_mk_req_extended(context, auth_context, ap_req_options, in_data, in_creds,
&(*auth_context)->local_subkey)))
goto cleanup;
-
if (in_data) {
if ((*auth_context)->req_cksumtype == 0x8003) {
/* XXX Special hack for GSSAPI */
checksum.checksum_type = 0x8003;
checksum.length = in_data->length;
checksum.contents = (krb5_octet *) in_data->data;
- } else {
- /* Generate checksum, XXX What should the seed be? */
- checksum.length =
- krb5_checksum_size(context, (*auth_context)->req_cksumtype);
- if ((checksum.contents = (krb5_octet *)malloc(checksum.length)) == NULL) {
- retval = ENOMEM;
- goto cleanup;
- }
- if ((retval = krb5_calculate_checksum(context,
- (*auth_context)->req_cksumtype,
- in_data->data, in_data->length,
- (*auth_context)->keyblock->contents,
- (*auth_context)->keyblock->length,
- &checksum)))
+ } else {
+ if ((retval = krb5_c_make_checksum(context,
+ (*auth_context)->req_cksumtype,
+ (*auth_context)->keyblock,
+ KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM,
+ in_data, &checksum)))
goto cleanup_cksum;
}
checksump = &checksum;
@@ -188,43 +172,12 @@ krb5_mk_req_extended(context, auth_context, ap_req_options, in_data, in_creds,
(*auth_context)->authentp->checksum = NULL;
(*auth_context)->authentp->authorization_data = NULL;
- /* put together an eblock for this encryption */
-
- krb5_use_enctype(context, &eblock, in_creds->keyblock.enctype);
- request.authenticator.enctype = in_creds->keyblock.enctype;
- request.authenticator.kvno = 0;
- request.authenticator.ciphertext.length =
- krb5_encrypt_size(scratch->length, eblock.crypto_entry);
- /* add padding area, and zero it */
- if (!(scratch->data = realloc(scratch->data,
- request.authenticator.ciphertext.length))) {
- /* may destroy scratch->data */
- retval = ENOMEM;
- goto cleanup_cksum;
- }
- memset(scratch->data + scratch->length, 0,
- request.authenticator.ciphertext.length - scratch->length);
- if (!(request.authenticator.ciphertext.data =
- malloc(request.authenticator.ciphertext.length))) {
- retval = ENOMEM;
- goto cleanup_cksum;
- }
-
- /* do any necessary key pre-processing */
- if ((retval = krb5_process_key(context, &eblock, &(in_creds)->keyblock)))
- goto cleanup;
-
/* call the encryption routine */
- if ((retval = krb5_encrypt(context, (krb5_pointer) scratch->data,
- (krb5_pointer) request.authenticator.ciphertext.data,
- scratch->length, &eblock, 0))) {
- krb5_finish_key(context, &eblock);
+ if ((retval = krb5_encrypt_helper(context, &in_creds->keyblock,
+ KRB5_KEYUSAGE_AP_REQ_AUTH,
+ scratch, &request.authenticator)))
goto cleanup_cksum;
- }
- if ((retval = krb5_finish_key(context, &eblock)))
- goto cleanup_cksum;
-
if ((retval = encode_krb5_ap_req(&request, &toutbuf)))
goto cleanup_cksum;
#ifdef HAVE_C_STRUCTURE_ASSIGNMENT
diff --git a/src/lib/krb5/krb/mk_safe.c b/src/lib/krb5/krb/mk_safe.c
index 1a44a75e5..0d5a49080 100644
--- a/src/lib/krb5/krb/mk_safe.c
+++ b/src/lib/krb5/krb/mk_safe.c
@@ -90,18 +90,11 @@ krb5_mk_safe_basic(context, userdata, keyblock, replaydata, local_addr,
if ((retval = encode_krb5_safe(&safemsg, &scratch1)))
return retval;
- safe_checksum.length = krb5_checksum_size(context, sumtype);
- if (!(safe_checksum.contents = (krb5_octet *) malloc(safe_checksum.length))) {
-
- retval = ENOMEM;
- goto cleanup_scratch;
- }
- if ((retval = krb5_calculate_checksum(context, sumtype, scratch1->data,
- scratch1->length,
- (krb5_pointer) keyblock->contents,
- keyblock->length, &safe_checksum))) {
+ if ((retval = krb5_c_make_checksum(context, sumtype, keyblock,
+ KRB5_KEYUSAGE_KRB_SAFE_CKSUM,
+ scratch1, &safe_checksum)))
goto cleanup_checksum;
- }
+
safemsg.checksum = &safe_checksum;
if ((retval = encode_krb5_safe(&safemsg, &scratch2))) {
goto cleanup_checksum;
diff --git a/src/lib/krb5/krb/preauth.c b/src/lib/krb5/krb/preauth.c
index c106dd15a..ab1432fdb 100644
--- a/src/lib/krb5/krb/preauth.c
+++ b/src/lib/krb5/krb/preauth.c
@@ -160,6 +160,10 @@ krb5_error_code krb5_obtain_padata(context, preauth_to_use, key_proc,
for (pa = preauth_to_use, size=0; *pa; pa++, size++) {
if ((*pa)->pa_type == KRB5_PADATA_ETYPE_INFO) {
+ /* XXX use the first one. Is there another way to disambiguate? */
+ if (etype_info)
+ continue;
+
scratch.length = (*pa)->length;
scratch.data = (char *) (*pa)->contents;
retval = decode_krb5_etype_info(&scratch, &etype_info);
@@ -219,6 +223,8 @@ krb5_error_code krb5_obtain_padata(context, preauth_to_use, key_proc,
}
cleanup:
+ if (etype_info)
+ krb5_free_etype_info(context, etype_info);
if (f_salt)
krb5_xfree(salt.data);
if (send_pa_list)
@@ -294,9 +300,6 @@ obtain_enc_ts_padata(context, in_padata, etype_info, def_enc_key,
krb5_data * scratch;
krb5_enc_data enc_data;
krb5_pa_data * pa;
-
-
- enc_data.ciphertext.data = 0;
retval = krb5_us_timeofday(context, &pa_enc.patimestamp, &pa_enc.pausec);
if (retval)
@@ -305,8 +308,11 @@ obtain_enc_ts_padata(context, in_padata, etype_info, def_enc_key,
if ((retval = encode_krb5_pa_enc_ts(&pa_enc, &scratch)) != 0)
return retval;
- if ((retval = krb5_encrypt_data(context, def_enc_key, 0, scratch,
- &enc_data)))
+ enc_data.ciphertext.data = 0;
+
+ if ((retval = krb5_encrypt_helper(context, def_enc_key,
+ KRB5_KEYUSAGE_AS_REQ_PA_ENC_TS,
+ scratch, &enc_data)))
goto cleanup;
krb5_free_data(context, scratch);
diff --git a/src/lib/krb5/krb/preauth2.c b/src/lib/krb5/krb/preauth2.c
index 0a154f6e1..86d325d7b 100644
--- a/src/lib/krb5/krb/preauth2.c
+++ b/src/lib/krb5/krb/preauth2.c
@@ -117,12 +117,16 @@ krb5_error_code pa_enc_timestamp(krb5_context context,
if (ret = encode_krb5_pa_enc_ts(&pa_enc, &tmp))
return(ret);
- ret = krb5_encrypt_data(context, as_key, 0, tmp, &enc_data);
+ ret = krb5_encrypt_helper(context, as_key,
+ KRB5_KEYUSAGE_AS_REQ_PA_ENC_TS,
+ tmp, &enc_data);
krb5_free_data(context, tmp);
- if (ret)
+ if (ret) {
+ krb5_xfree(enc_data.ciphertext.data);
return(ret);
+ }
ret = encode_krb5_enc_data(&enc_data, &tmp);
@@ -215,7 +219,6 @@ krb5_error_code pa_sam(krb5_context context,
char banner[100], prompt[100], response[100];
krb5_data response_data;
krb5_prompt kprompt;
- krb5_encrypt_block eblock;
krb5_data defsalt;
krb5_sam_challenge *sam_challenge = 0;
krb5_sam_response sam_response;
@@ -281,13 +284,6 @@ krb5_error_code pa_sam(krb5_context context,
as_key->length = 0;
}
- /* XXX the server uses this fixed enctype, so we will, too. */
-
- if (!valid_enctype(ENCTYPE_DES_CBC_MD5))
- return(KRB5_PROG_ETYPE_NOSUPP);
-
- krb5_use_enctype(context, &eblock, ENCTYPE_DES_CBC_MD5);
-
#if 0
if ((salt->length == -1) && (salt->data == NULL)) {
if (ret = krb5_principal2salt(context, request->client,
@@ -305,8 +301,11 @@ krb5_error_code pa_sam(krb5_context context,
salt = NULL;
#endif
- ret = krb5_string_to_key(context, &eblock, as_key,
- &response_data, salt);
+ /* XXX the server uses this fixed enctype, so we will, too. */
+
+ ret = krb5_c_string_to_key(context, ENCTYPE_DES_CBC_MD5,
+ &response_data, salt, as_key);
+
if (defsalt.length)
krb5_xfree(defsalt.data);
diff --git a/src/lib/krb5/krb/rd_cred.c b/src/lib/krb5/krb/rd_cred.c
index 7537ac990..86c5ccf72 100644
--- a/src/lib/krb5/krb/rd_cred.c
+++ b/src/lib/krb5/krb/rd_cred.c
@@ -19,7 +19,6 @@ decrypt_credencdata(context, pcred, pkeyblock, pcredenc)
krb5_cred_enc_part * pcredenc;
{
krb5_cred_enc_part * ppart;
- krb5_encrypt_block eblock;
krb5_error_code retval;
krb5_data scratch;
@@ -28,28 +27,9 @@ decrypt_credencdata(context, pcred, pkeyblock, pcredenc)
return ENOMEM;
if (pkeyblock != NULL) {
- if (!valid_enctype(pcred->enc_part.enctype)) {
- free(scratch.data);
- return KRB5_PROG_ETYPE_NOSUPP;
- }
-
- /* put together an eblock for this decryption */
- krb5_use_enctype(context, &eblock, pcred->enc_part.enctype);
-
- /* do any necessary key pre-processing */
- if ((retval = krb5_process_key(context, &eblock, pkeyblock)))
- goto cleanup;
-
- /* call the decryption routine */
- if ((retval = krb5_decrypt(context,
- (krb5_pointer) pcred->enc_part.ciphertext.data,
- (krb5_pointer) scratch.data,
- scratch.length, &eblock, 0))) {
- (void)krb5_finish_key(context, &eblock);
- goto cleanup;
- }
-
- if ((retval = krb5_finish_key(context, &eblock)))
+ if ((retval = krb5_c_decrypt(context, pkeyblock,
+ KRB5_KEYUSAGE_KRB_CRED_ENCPART, 0,
+ &pcred->enc_part, &scratch)))
goto cleanup;
} else {
memcpy(scratch.data, pcred->enc_part.ciphertext.data, scratch.length);
diff --git a/src/lib/krb5/krb/rd_priv.c b/src/lib/krb5/krb/rd_priv.c
index c4e1ed0b6..f08975f22 100644
--- a/src/lib/krb5/krb/rd_priv.c
+++ b/src/lib/krb5/krb/rd_priv.c
@@ -66,8 +66,9 @@ krb5_rd_priv_basic(context, inbuf, keyblock, local_addr, remote_addr,
krb5_error_code retval;
krb5_priv * privmsg;
krb5_data scratch;
- krb5_encrypt_block eblock;
krb5_priv_enc_part * privmsg_enc_part;
+ size_t blocksize;
+ krb5_data ivdata;
if (!krb5_is_krb_priv(inbuf))
return KRB5KRB_AP_ERR_MSG_TYPE;
@@ -76,43 +77,33 @@ krb5_rd_priv_basic(context, inbuf, keyblock, local_addr, remote_addr,
if ((retval = decode_krb5_priv(inbuf, &privmsg)))
return retval;
- if (!valid_enctype(privmsg->enc_part.enctype)) {
- retval = KRB5_PROG_ETYPE_NOSUPP;
- goto cleanup_privmsg;
+ if (i_vector) {
+ if ((retval = krb5_c_block_size(context, keyblock->enctype,
+ &blocksize)))
+ goto cleanup_privmsg;
+
+ ivdata.length = blocksize;
+ ivdata.data = i_vector;
}
-
- /* put together an eblock for this decryption */
- krb5_use_enctype(context, &eblock, privmsg->enc_part.enctype);
+
scratch.length = privmsg->enc_part.ciphertext.length;
-
if (!(scratch.data = malloc(scratch.length))) {
retval = ENOMEM;
goto cleanup_privmsg;
}
- /* do any necessary key pre-processing */
- if ((retval = krb5_process_key(context, &eblock, keyblock)))
+ if ((retval = krb5_c_decrypt(context, keyblock,
+ KRB5_KEYUSAGE_KRB_PRIV_ENCPART,
+ i_vector?&ivdata:0,
+ &privmsg->enc_part, &scratch)))
goto cleanup_scratch;
- /* call the decryption routine */
- if ((retval = krb5_decrypt(context,
- (krb5_pointer) privmsg->enc_part.ciphertext.data,
- (krb5_pointer) scratch.data,
- scratch.length, &eblock, i_vector))) {
- krb5_finish_key(context, &eblock);
- goto cleanup_scratch;
- }
-
/* if i_vector is set, put last block into the i_vector */
if (i_vector)
memcpy(i_vector,
privmsg->enc_part.ciphertext.data +
- (privmsg->enc_part.ciphertext.length -
- eblock.crypto_entry->block_length),
- eblock.crypto_entry->block_length);
-
- if ((retval = krb5_finish_key(context, &eblock)))
- goto cleanup_scratch;
+ (privmsg->enc_part.ciphertext.length - blocksize),
+ blocksize);
/* now decode the decrypted stuff */
if ((retval = decode_krb5_enc_priv_part(&scratch, &privmsg_enc_part)))
diff --git a/src/lib/krb5/krb/rd_rep.c b/src/lib/krb5/krb/rd_rep.c
index d4d559d14..411a61ddb 100644
--- a/src/lib/krb5/krb/rd_rep.c
+++ b/src/lib/krb5/krb/rd_rep.c
@@ -47,7 +47,6 @@ krb5_rd_rep(context, auth_context, inbuf, repl)
{
krb5_error_code retval;
krb5_ap_rep * reply;
- krb5_encrypt_block eblock;
krb5_data scratch;
if (!krb5_is_ap_rep(inbuf))
@@ -60,35 +59,15 @@ krb5_rd_rep(context, auth_context, inbuf, repl)
/* put together an eblock for this encryption */
- if (!valid_enctype(reply->enc_part.enctype)) {
- krb5_free_ap_rep(context, reply);
- return KRB5_PROG_ETYPE_NOSUPP;
- }
- krb5_use_enctype(context, &eblock, reply->enc_part.enctype);
-
scratch.length = reply->enc_part.ciphertext.length;
if (!(scratch.data = malloc(scratch.length))) {
krb5_free_ap_rep(context, reply);
return(ENOMEM);
}
- /* do any necessary key pre-processing */
- if ((retval = krb5_process_key(context, &eblock,
- auth_context->keyblock))) {
- goto errout;
- }
-
- /* call the encryption routine */
- if ((retval = krb5_decrypt(context,
- (krb5_pointer) reply->enc_part.ciphertext.data,
- (krb5_pointer) scratch.data,
- scratch.length, &eblock, 0))) {
- (void) krb5_finish_key(context, &eblock);
- goto errout;
- }
-
- /* finished with the top-level encoding of the ap_rep */
- if ((retval = krb5_finish_key(context, &eblock)))
+ if ((retval = krb5_c_decrypt(context, auth_context->keyblock,
+ KRB5_KEYUSAGE_AP_REP_ENCPART, 0,
+ &reply->enc_part, &scratch)))
goto clean_scratch;
/* now decode the decrypted stuff */
diff --git a/src/lib/krb5/krb/rd_req_dec.c b/src/lib/krb5/krb/rd_req_dec.c
index 0c62c19df..cdbdc81df 100644
--- a/src/lib/krb5/krb/rd_req_dec.c
+++ b/src/lib/krb5/krb/rd_req_dec.c
@@ -57,7 +57,8 @@
*/
static krb5_error_code decrypt_authenticator
- PROTOTYPE((krb5_context, const krb5_ap_req *, krb5_authenticator **));
+ PROTOTYPE((krb5_context, const krb5_ap_req *, krb5_authenticator **,
+ int));
#define in_clock_skew(date) (labs((date)-currenttime) < context->clockskew)
@@ -119,8 +120,12 @@ krb5_rd_req_decoded_opt(context, auth_context, req, server, keytab,
return retval;
}
+ /* XXX this is an evil hack. check_valid_flag is set iff the call
+ is not from inside the kdc. we can use this to determine which
+ key usage to use */
if ((retval = decrypt_authenticator(context, req,
- &((*auth_context)->authentp))))
+ &((*auth_context)->authentp),
+ check_valid_flag)))
goto cleanup;
if (!krb5_principal_compare(context, (*auth_context)->authentp->client,
@@ -243,14 +248,66 @@ krb5_rd_req_decoded_opt(context, auth_context, req, server, keytab,
}
}
+ /* check if the various etypes are permitted */
+
+ if ((*auth_context)->auth_context_flags & KRB5_AUTH_CONTEXT_PERMIT_ALL) {
+ /* no etype check needed */;
+ } else if ((*auth_context)->permitted_etypes == NULL) {
+ /* check against the default set */
+ if ((!krb5_is_permitted_enctype(context,
+ req->ticket->enc_part.enctype)) ||
+ (!krb5_is_permitted_enctype(context,
+ req->ticket->enc_part2->session->enctype)) ||
+ (((*auth_context)->authentp->subkey) &&
+ !krb5_is_permitted_enctype(context,
+ (*auth_context)->authentp->subkey->enctype))) {
+ retval = KRB5_NOPERM_ETYPE;
+ goto cleanup;
+ }
+ } else {
+ /* check against the set in the auth_context */
+ int i;
+
+ for (i=0; (*auth_context)->permitted_etypes[i]; i++)
+ if ((*auth_context)->permitted_etypes[i] ==
+ req->ticket->enc_part.enctype)
+ break;
+ if (!(*auth_context)->permitted_etypes[i]) {
+ retval = KRB5_NOPERM_ETYPE;
+ goto cleanup;
+ }
+
+ for (i=0; (*auth_context)->permitted_etypes[i]; i++)
+ if ((*auth_context)->permitted_etypes[i] ==
+ req->ticket->enc_part2->session->enctype)
+ break;
+ if (!(*auth_context)->permitted_etypes[i]) {
+ retval = KRB5_NOPERM_ETYPE;
+ goto cleanup;
+ }
+
+ if ((*auth_context)->authentp->subkey) {
+ for (i=0; (*auth_context)->permitted_etypes[i]; i++)
+ if ((*auth_context)->permitted_etypes[i] ==
+ (*auth_context)->authentp->subkey->enctype)
+ break;
+ if (!(*auth_context)->permitted_etypes[i]) {
+ retval = KRB5_NOPERM_ETYPE;
+ goto cleanup;
+ }
+ }
+ }
+
(*auth_context)->remote_seq_number = (*auth_context)->authentp->seq_number;
if ((*auth_context)->authentp->subkey) {
if ((retval = krb5_copy_keyblock(context,
(*auth_context)->authentp->subkey,
&((*auth_context)->remote_subkey))))
goto cleanup;
- } else
+ } else {
(*auth_context)->remote_subkey = 0;
+ }
+
if ((retval = krb5_copy_keyblock(context, req->ticket->enc_part2->session,
&((*auth_context)->keyblock))))
goto cleanup;
@@ -322,52 +379,34 @@ krb5_rd_req_decoded_anyflag(context, auth_context, req, server, keytab,
}
static krb5_error_code
-decrypt_authenticator(context, request, authpp)
+decrypt_authenticator(context, request, authpp, is_ap_req)
krb5_context context;
const krb5_ap_req *request;
krb5_authenticator **authpp;
+ int is_ap_req;
{
krb5_authenticator *local_auth;
krb5_error_code retval;
- krb5_encrypt_block eblock;
krb5_data scratch;
krb5_keyblock *sesskey;
sesskey = request->ticket->enc_part2->session;
- if (!valid_enctype(sesskey->enctype))
- return KRB5_PROG_ETYPE_NOSUPP;
-
- /* put together an eblock for this encryption */
-
- krb5_use_enctype(context, &eblock, request->authenticator.enctype);
-
scratch.length = request->authenticator.ciphertext.length;
if (!(scratch.data = malloc(scratch.length)))
return(ENOMEM);
- /* do any necessary key pre-processing */
- if ((retval = krb5_process_key(context, &eblock, sesskey))) {
+ if ((retval = krb5_c_decrypt(context, sesskey,
+ is_ap_req?KRB5_KEYUSAGE_AP_REQ_AUTH:
+ KRB5_KEYUSAGE_TGS_REQ_AUTH, 0,
+ &request->authenticator, &scratch))) {
free(scratch.data);
return(retval);
}
- /* call the encryption routine */
- if ((retval = krb5_decrypt(context,
- (krb5_pointer)request->authenticator.ciphertext.data,
- (krb5_pointer)scratch.data,
- scratch.length, &eblock, 0))) {
- (void) krb5_finish_key(context, &eblock);
- free(scratch.data);
- return retval;
- }
#define clean_scratch() {memset(scratch.data, 0, scratch.length); \
free(scratch.data);}
- if ((retval = krb5_finish_key(context, &eblock))) {
- clean_scratch();
- return retval;
- }
/* now decode the decrypted stuff */
if (!(retval = decode_krb5_authenticator(&scratch, &local_auth))) {
*authpp = local_auth;
diff --git a/src/lib/krb5/krb/rd_safe.c b/src/lib/krb5/krb/rd_safe.c
index 5f0fcd6ca..1c5aca21c 100644
--- a/src/lib/krb5/krb/rd_safe.c
+++ b/src/lib/krb5/krb/rd_safe.c
@@ -59,6 +59,7 @@ krb5_rd_safe_basic(context, inbuf, keyblock, recv_addr, sender_addr,
krb5_checksum our_cksum, *his_cksum;
krb5_octet zero_octet = 0;
krb5_data *scratch;
+ krb5_boolean valid;
if (!krb5_is_krb_safe(inbuf))
return KRB5KRB_AP_ERR_MSG_TYPE;
@@ -122,14 +123,14 @@ krb5_rd_safe_basic(context, inbuf, keyblock, recv_addr, sender_addr,
message->checksum = his_cksum;
- retval = krb5_verify_checksum(context, his_cksum->checksum_type,
- his_cksum, scratch->data, scratch->length,
- (krb5_pointer) keyblock->contents,
- keyblock->length);
+ retval = krb5_c_verify_checksum(context, keyblock,
+ KRB5_KEYUSAGE_KRB_SAFE_CKSUM,
+ scratch, his_cksum, &valid);
+
(void) memset((char *)scratch->data, 0, scratch->length);
krb5_free_data(context, scratch);
- if (retval) {
+ if (!valid) {
retval = KRB5KRB_AP_ERR_MODIFIED;
goto cleanup;
}
diff --git a/src/lib/krb5/krb/send_tgs.c b/src/lib/krb5/krb/send_tgs.c
index b06ef2bfc..19de14e1a 100644
--- a/src/lib/krb5/krb/send_tgs.c
+++ b/src/lib/krb5/krb/send_tgs.c
@@ -55,21 +55,15 @@ krb5_send_tgs_basic(context, in_data, in_cred, outbuf)
krb5_checksum checksum;
krb5_authenticator authent;
krb5_ap_req request;
- krb5_encrypt_block eblock;
krb5_data * scratch;
krb5_data * toutbuf;
/* Generate checksum */
- checksum.length = krb5_checksum_size(context, context->kdc_req_sumtype);
- if ((checksum.contents = (krb5_octet *) malloc(checksum.length)) == NULL)
- return(ENOMEM);
-
- if ((retval = krb5_calculate_checksum(context, context->kdc_req_sumtype,
- in_data->data, in_data->length,
- (krb5_pointer) in_cred->keyblock.contents,
- in_cred->keyblock.length,
- &checksum))) {
- free(checksum.contents);
+ if ((retval = krb5_c_make_checksum(context, context->kdc_req_sumtype,
+ &in_cred->keyblock,
+ KRB5_KEYUSAGE_TGS_REQ_AUTH_CKSUM,
+ in_data, &checksum))) {
+ free(checksum.contents);
return(retval);
}
@@ -102,43 +96,11 @@ krb5_send_tgs_basic(context, in_data, in_cred, outbuf)
/* Cleanup scratch and scratch data */
goto cleanup_data;
- /* put together an eblock for this encryption */
- krb5_use_enctype(context, &eblock, in_cred->keyblock.enctype);
- request.authenticator.enctype = in_cred->keyblock.enctype;
- request.authenticator.ciphertext.length =
- krb5_encrypt_size(scratch->length, eblock.crypto_entry);
-
- /* add padding area, and zero it */
- if (!(scratch->data = realloc(scratch->data,
- request.authenticator.ciphertext.length))) {
- /* may destroy scratch->data */
- krb5_free_ticket(context, request.ticket);
- retval = ENOMEM;
- goto cleanup_scratch;
- }
- memset(scratch->data + scratch->length, 0,
- request.authenticator.ciphertext.length - scratch->length);
-
- if (!(request.authenticator.ciphertext.data =
- malloc(request.authenticator.ciphertext.length))) {
- retval = ENOMEM;
- goto cleanup_ticket;
- }
-
- /* do any necessary key pre-processing */
- if ((retval = krb5_process_key(context, &eblock, &(in_cred)->keyblock)))
- goto cleanup;
-
/* call the encryption routine */
- if ((retval=krb5_encrypt(context, (krb5_pointer) scratch->data,
- (krb5_pointer)request.authenticator.ciphertext.data,
- scratch->length, &eblock, 0))) {
- krb5_finish_key(context, &eblock);
- goto cleanup;
- }
-
- if ((retval = krb5_finish_key(context, &eblock)))
- goto cleanup;
+ if ((retval = krb5_encrypt_helper(context, &in_cred->keyblock,
+ KRB5_KEYUSAGE_TGS_REQ_AUTH,
+ scratch, &request.authenticator)))
+ goto cleanup_ticket;
retval = encode_krb5_ap_req(&request, &toutbuf);
*outbuf = *toutbuf;
@@ -185,6 +147,7 @@ krb5_send_tgs(context, kdcoptions, timestruct, ktypes, sname, addrs,
krb5_timestamp time_now;
krb5_pa_data **combined_padata;
krb5_pa_data ap_req_padata;
+ size_t enclen;
/*
* in_creds MUST be a valid credential NOT just a partially filled in
@@ -212,50 +175,21 @@ krb5_send_tgs(context, kdcoptions, timestruct, ktypes, sname, addrs,
if (authorization_data) {
/* need to encrypt it in the request */
- krb5_encrypt_block eblock;
if ((retval = encode_krb5_authdata((const krb5_authdata**)authorization_data,
&scratch)))
return(retval);
- krb5_use_enctype(context, &eblock, in_cred->keyblock.enctype);
- tgsreq.authorization_data.enctype = in_cred->keyblock.enctype;
- tgsreq.authorization_data.kvno = 0; /* ticket session key has */
- /* no version */
- tgsreq.authorization_data.ciphertext.length =
- krb5_encrypt_size(scratch->length, eblock.crypto_entry);
- /* add padding area, and zero it */
- if (!(scratch->data = realloc(scratch->data,
- tgsreq.authorization_data.ciphertext.length))) {
- /* may destroy scratch->data */
- krb5_xfree(scratch);
- return ENOMEM;
- }
- memset(scratch->data + scratch->length, 0,
- tgsreq.authorization_data.ciphertext.length - scratch->length);
- if (!(tgsreq.authorization_data.ciphertext.data =
- malloc(tgsreq.authorization_data.ciphertext.length))) {
- krb5_free_data(context, scratch);
- return ENOMEM;
- }
- if ((retval = krb5_process_key(context, &eblock,
- &in_cred->keyblock))) {
- krb5_free_data(context, scratch);
- return retval;
- }
- /* call the encryption routine */
- if ((retval = krb5_encrypt(context, (krb5_pointer) scratch->data,
- (krb5_pointer) tgsreq.authorization_data.ciphertext.data,
- scratch->length, &eblock, 0))) {
- (void) krb5_finish_key(context, &eblock);
+
+ if ((retval = krb5_encrypt_helper(context, &in_cred->keyblock,
+ KRB5_KEYUSAGE_TGS_REQ_AD_SESSKEY,
+ scratch,
+ &tgsreq.authorization_data))) {
krb5_xfree(tgsreq.authorization_data.ciphertext.data);
krb5_free_data(context, scratch);
return retval;
- }
- krb5_free_data(context, scratch);
- if ((retval = krb5_finish_key(context, &eblock))) {
- krb5_xfree(tgsreq.authorization_data.ciphertext.data);
- return retval;
}
+
+ krb5_free_data(context, scratch);
}
/* Get the encryption types list */
diff --git a/src/lib/krb5/krb/ser_actx.c b/src/lib/krb5/krb/ser_actx.c
index 5705b711f..42b9bfeb6 100644
--- a/src/lib/krb5/krb/ser_actx.c
+++ b/src/lib/krb5/krb/ser_actx.c
@@ -56,7 +56,6 @@ krb5_error_code krb5_ser_authdata_init KRB5_PROTOTYPE((krb5_context));
krb5_error_code krb5_ser_address_init KRB5_PROTOTYPE((krb5_context));
krb5_error_code krb5_ser_authenticator_init KRB5_PROTOTYPE((krb5_context));
krb5_error_code krb5_ser_checksum_init KRB5_PROTOTYPE((krb5_context));
-krb5_error_code krb5_ser_encrypt_block_init KRB5_PROTOTYPE((krb5_context));
krb5_error_code krb5_ser_keyblock_init KRB5_PROTOTYPE((krb5_context));
krb5_error_code krb5_ser_principal_init KRB5_PROTOTYPE((krb5_context));
@@ -95,17 +94,20 @@ krb5_auth_context_size(kcontext, arg, sizep)
*/
kret = EINVAL;
if ((auth_context = (krb5_auth_context) arg)) {
- required = sizeof(krb5_int32)*8;
-
kret = 0;
+
/* Calculate size required by i_vector - ptooey */
- if (auth_context->i_vector && auth_context->keyblock)
- required += (size_t)
- krb5_enctype_array[auth_context->keyblock->enctype]->
- system->block_length;
+ if (auth_context->i_vector && auth_context->keyblock) {
+ kret = krb5_c_block_size(kcontext, auth_context->keyblock->enctype,
+ &required);
+ } else {
+ required = 0;
+ }
+
+ required += sizeof(krb5_int32)*8;
/* Calculate size required by remote_addr, if appropriate */
- if (auth_context->remote_addr) {
+ if (!kret && auth_context->remote_addr) {
kret = krb5_size_opaque(kcontext,
KV5M_ADDRESS,
(krb5_pointer) auth_context->remote_addr,
@@ -226,18 +228,25 @@ krb5_auth_context_externalize(kcontext, arg, buffer, lenremain)
(void) krb5_ser_pack_int32((krb5_int32) auth_context->safe_cksumtype,
&bp, &remain);
+ kret = 0;
+
/* Now figure out the number of bytes for i_vector and write it */
- obuf = (!auth_context->i_vector) ? 0 : (krb5_int32)
- krb5_enctype_array[auth_context->keyblock->enctype]->
- system->block_length;
- (void) krb5_ser_pack_int32(obuf, &bp, &remain);
+ if (auth_context->i_vector) {
+ kret = krb5_c_block_size(kcontext,
+ auth_context->keyblock->enctype,
+ &obuf);
+ } else {
+ obuf = 0;
+ }
+
+ if (!kret)
+ (void) krb5_ser_pack_int32(obuf, &bp, &remain);
/* Now copy i_vector */
- if (auth_context->i_vector)
+ if (!kret && auth_context->i_vector)
(void) krb5_ser_pack_bytes(auth_context->i_vector,
(size_t) obuf,
&bp, &remain);
- kret = 0;
/* Now handle remote_addr, if appropriate */
if (!kret && auth_context->remote_addr) {
@@ -556,8 +565,6 @@ krb5_ser_auth_context_init(kcontext)
if (!kret)
kret = krb5_ser_checksum_init(kcontext);
if (!kret)
- kret = krb5_ser_encrypt_block_init(kcontext);
- if (!kret)
kret = krb5_ser_keyblock_init(kcontext);
if (!kret)
kret = krb5_ser_principal_init(kcontext);
diff --git a/src/lib/krb5/krb/ser_eblk.c b/src/lib/krb5/krb/ser_eblk.c
index 20b3da672..04e21faab 100644
--- a/src/lib/krb5/krb/ser_eblk.c
+++ b/src/lib/krb5/krb/ser_eblk.c
@@ -22,6 +22,8 @@
*
*/
+#if 0 /* i don't believe this is used anywhere --marc */
+
/*
* ser_eblk.c - Serialize a krb5_encblock structure.
*/
@@ -249,3 +251,5 @@ krb5_ser_encrypt_block_init(kcontext)
{
return(krb5_register_serializer(kcontext, &krb5_encrypt_block_ser_entry));
}
+
+#endif
diff --git a/src/lib/krb5/krb/str_conv.c b/src/lib/krb5/krb/str_conv.c
index 6346aef23..b30638d4f 100644
--- a/src/lib/krb5/krb/str_conv.c
+++ b/src/lib/krb5/krb/str_conv.c
@@ -31,17 +31,13 @@
*
* String decoding:
* ----------------
- * krb5_string_to_enctype() - Convert string to krb5_enctype.
* krb5_string_to_salttype() - Convert string to salttype (krb5_int32)
- * krb5_string_to_cksumtype() - Convert string to krb5_cksumtype;
* krb5_string_to_timestamp() - Convert string to krb5_timestamp.
* krb5_string_to_deltat() - Convert string to krb5_deltat.
*
* String encoding:
* ----------------
- * krb5_enctype_to_string() - Convert krb5_enctype to string.
* krb5_salttype_to_string() - Convert salttype (krb5_int32) to string.
- * krb5_cksumtype_to_string() - Convert krb5_cksumtype to string.
* krb5_timestamp_to_string() - Convert krb5_timestamp to string.
* krb5_timestamp_to_sfstring() - Convert krb5_timestamp to short filled string
* krb5_deltat_to_string() - Convert krb5_deltat to string.
@@ -52,24 +48,12 @@
/*
* Local data structures.
*/
-struct enctype_lookup_entry {
- krb5_enctype ktt_enctype; /* Keytype */
- const char * ktt_specifier; /* How to recognize it */
- const char * ktt_output; /* How to spit it out */
-};
-
struct salttype_lookup_entry {
krb5_int32 stt_enctype; /* Salt type */
const char * stt_specifier; /* How to recognize it */
const char * stt_output; /* How to spit it out */
};
-struct cksumtype_lookup_entry {
- krb5_cksumtype cst_cksumtype; /* Checksum type */
- const char * cst_specifier; /* How to recognize it */
- const char * cst_output; /* How to spit it out */
-};
-
struct deltat_match_entry {
const char * dt_scan_format; /* sscanf format */
int dt_nmatch; /* Number to match */
@@ -83,21 +67,6 @@ struct deltat_match_entry {
* Local strings
*/
-/* Keytype strings */
-static const char enctype_des_in[] = "des";
-static const char enctype_null_in[] = "null";
-static const char enctype_descbccrc_in[] = "des-cbc-crc";
-static const char enctype_descbcmd4_in[] = "des-cbc-md4";
-static const char enctype_descbcmd5_in[] = "des-cbc-md5";
-static const char enctype_des3cbcsha_in[] = "des3-cbc-sha";
-static const char enctype_descbcraw_in[] = "des-cbc-raw";
-static const char enctype_null_out[] = "Null";
-static const char enctype_descbccrc_out[] = "DES cbc mode with CRC-32";
-static const char enctype_descbcmd4_out[] = "DES cbc mode with RSA-MD4";
-static const char enctype_descbcmd5_out[] = "DES cbc mode with RSA-MD5";
-static const char enctype_des3cbcsha_out[] = "DES-3 cbc mode with NIST-SHA";
-static const char enctype_descbcraw_out[] = "DES cbc mode raw";
-
/* Salttype strings */
static const char stype_v5_in[] = "normal";
static const char stype_v4_in[] = "v4";
@@ -112,24 +81,6 @@ static const char stype_olrealm_out[] = "Version 5 - Realm Only";
static const char stype_special_out[] = "Special";
static const char stype_afs3_out[] = "AFS version 3";
-/* Checksum type strings */
-static const char cstype_crc32_in[] = "crc32";
-static const char cstype_md4_in[] = "md4";
-static const char cstype_md4des_in[] = "md4-des";
-static const char cstype_descbc_in[] = "des-cbc";
-static const char cstype_md5_in[] = "md5";
-static const char cstype_md5des_in[] = "md5-des";
-static const char cstype_sha_in[] = "sha";
-static const char cstype_hmacsha_in[] = "hmac-sha";
-static const char cstype_crc32_out[] = "CRC-32";
-static const char cstype_md4_out[] = "RSA-MD4";
-static const char cstype_md4des_out[] = "RSA-MD4 with DES cbc mode";
-static const char cstype_descbc_out[] = "DES cbc mode";
-static const char cstype_md5_out[] = "RSA-MD5";
-static const char cstype_md5des_out[] = "RSA-MD5 with DES cbc mode";
-static const char cstype_sha_out[] = "NIST-SHA";
-static const char cstype_hmacsha_out[] = "HMAC-SHA";
-
/* Absolute time strings */
static const char atime_full_digits[] = "%y%m%d%H%M%S";
static const char atime_full_digits_d[] = "%y.%m.%d.%H.%M.%S";
@@ -184,20 +135,6 @@ static const char dt_output_hms[] = "%d:%02d:%02d";
* Lookup tables.
*/
-static const struct enctype_lookup_entry enctype_table[] = {
-/* krb5_enctype input specifier output string */
-/*------------- ----------------------- ------------------------*/
-{ ENCTYPE_NULL, enctype_null_in, enctype_null_out },
-{ ENCTYPE_DES_CBC_MD5, enctype_des_in, enctype_descbcmd5_out },
-{ ENCTYPE_DES_CBC_CRC, enctype_descbccrc_in, enctype_descbccrc_out },
-{ ENCTYPE_DES_CBC_MD4, enctype_descbcmd4_in, enctype_descbcmd4_out },
-{ ENCTYPE_DES_CBC_MD5, enctype_descbcmd5_in, enctype_descbcmd5_out },
-{ ENCTYPE_DES3_CBC_SHA, enctype_des3cbcsha_in, enctype_des3cbcsha_out },
-{ ENCTYPE_DES_CBC_RAW, enctype_descbcraw_in, enctype_descbcraw_out }
-};
-static const int enctype_table_nents = sizeof(enctype_table)/
- sizeof(enctype_table[0]);
-
static const struct salttype_lookup_entry salttype_table[] = {
/* salt type input specifier output string */
/*----------------------------- ----------------------- ------------------*/
@@ -211,21 +148,6 @@ static const struct salttype_lookup_entry salttype_table[] = {
static const int salttype_table_nents = sizeof(salttype_table)/
sizeof(salttype_table[0]);
-static const struct cksumtype_lookup_entry cksumtype_table[] = {
-/* krb5_cksumtype input specifier output string */
-/*----------------------- --------------------- ------------------------*/
-{ CKSUMTYPE_CRC32, cstype_crc32_in, cstype_crc32_out },
-{ CKSUMTYPE_RSA_MD4, cstype_md4_in, cstype_md4_out },
-{ CKSUMTYPE_RSA_MD4_DES, cstype_md4des_in, cstype_md4des_out },
-{ CKSUMTYPE_DESCBC, cstype_descbc_in, cstype_descbc_out },
-{ CKSUMTYPE_RSA_MD5, cstype_md5_in, cstype_md5_out },
-{ CKSUMTYPE_RSA_MD5_DES, cstype_md5des_in, cstype_md5des_out },
-{ CKSUMTYPE_NIST_SHA, cstype_sha_in, cstype_sha_out },
-{ CKSUMTYPE_HMAC_SHA, cstype_hmacsha_in, cstype_hmacsha_out }
-};
-static const int cksumtype_table_nents = sizeof(cksumtype_table)/
- sizeof(cksumtype_table[0]);
-
static const char * const atime_format_table[] = {
atime_full_digits_Y, /* yyyymmddhhmmss */
atime_full_digits_Yd, /* yyyy.mm.dd.hh.mm.ss */
@@ -403,30 +325,6 @@ strptime(buf, format, tm)
}
#endif /* HAVE_STRPTIME */
-/*
- * String to internal datatype routines.
- *
- * These routines return 0 for success, EINVAL for invalid entry.
- */
-KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
-krb5_string_to_enctype(string, enctypep)
- char FAR * string;
- krb5_enctype FAR * enctypep;
-{
- int i;
- int found;
-
- found = 0;
- for (i=0; i<enctype_table_nents; i++) {
- if (!strcasecmp(string, enctype_table[i].ktt_specifier)) {
- found = 1;
- *enctypep = enctype_table[i].ktt_enctype;
- break;
- }
- }
- return((found) ? 0 : EINVAL);
-}
-
KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
krb5_string_to_salttype(string, salttypep)
char FAR * string;
@@ -447,25 +345,6 @@ krb5_string_to_salttype(string, salttypep)
}
KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
-krb5_string_to_cksumtype(string, cksumtypep)
- char FAR * string;
- krb5_cksumtype FAR * cksumtypep;
-{
- int i;
- int found;
-
- found = 0;
- for (i=0; i<cksumtype_table_nents; i++) {
- if (!strcasecmp(string, cksumtype_table[i].cst_specifier)) {
- found = 1;
- *cksumtypep = cksumtype_table[i].cst_cksumtype;
- break;
- }
- }
- return((found) ? 0 : EINVAL);
-}
-
-KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
krb5_string_to_timestamp(string, timestampp)
char FAR * string;
krb5_timestamp FAR * timestampp;
@@ -545,33 +424,6 @@ krb5_string_to_deltat(string, deltatp)
* if the supplied buffer/length will not contain the output.
*/
KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
-krb5_enctype_to_string(enctype, buffer, buflen)
- krb5_enctype enctype;
- char FAR * buffer;
- size_t buflen;
-{
- int i;
- const char *out;
-
- out = (char *) NULL;
- for (i=0; i<enctype_table_nents; i++) {
- if (enctype == enctype_table[i].ktt_enctype) {
- out = enctype_table[i].ktt_output;
- break;
- }
- }
- if (out) {
- if (buflen > strlen(out))
- strcpy(buffer, out);
- else
- out = (char *) NULL;
- return((out) ? 0 : ENOMEM);
- }
- else
- return(EINVAL);
-}
-
-KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
krb5_salttype_to_string(salttype, buffer, buflen)
krb5_int32 salttype;
char FAR * buffer;
diff --git a/src/lib/krb5/krb/vfy_increds.c b/src/lib/krb5/krb/vfy_increds.c
index bb8ea349b..85a846503 100644
--- a/src/lib/krb5/krb/vfy_increds.c
+++ b/src/lib/krb5/krb/vfy_increds.c
@@ -68,12 +68,7 @@ krb5_verify_init_creds(krb5_context context,
krb5_creds in_creds, *out_creds;
krb5_auth_context authcon;
krb5_data ap_req;
- int keytab_key_exists, rd_req_succeeds, nofail;
- keytab_key_exists = 0;
- rd_req_succeeds = 0;
- nofail = 0;
-
/* KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN */
server = NULL;
@@ -103,11 +98,31 @@ krb5_verify_init_creds(krb5_context context,
goto cleanup;
}
- if (ret = krb5_kt_get_entry(context, keytab, server, 0, 0, &kte))
- goto cleanup;
+ if (ret = krb5_kt_get_entry(context, keytab, server, 0, 0, &kte)) {
+ /* this means there is no keying material. This is ok, as long as
+ it is not prohibited by the configuration */
+
+ krb5_error_code ret2;
+ int nofail;
+
+ if (options &&
+ (options->flags & KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL)) {
+ if (options->ap_req_nofail)
+ goto cleanup;
+ } else if ((ret2 = krb5_appdefault_boolean(context,
+ &creds->client->realm,
+ "verify_ap_req_nofail",
+ &nofail))
+ == 0) {
+ if (nofail)
+ goto cleanup;
+ }
+
+ ret = 0;
+ goto cleanup;
+ }
krb5_kt_free_entry(context, &kte);
- keytab_key_exists = 1;
/* If the creds are for the server principal, we're set, just do
a mk_req. Otherwise, do a get_credentials first. */
@@ -166,61 +181,37 @@ krb5_verify_init_creds(krb5_context context,
NULL, NULL))
goto cleanup;
- rd_req_succeeds = 1;
-
-cleanup:
- /* I could test the error case first, but then there would be a
- chance that the verification would succeed when there was
- actually a significant failure (some transient condition could
- make rd_req fail, and this would not be a problem if nofail was
- not set */
-
- if (!keytab_key_exists) {
- krb5_error_code ret2;
-
- if (options &&
- (options->flags & KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL))
- nofail = options->ap_req_nofail;
- else if ((ret2 = krb5_appdefault_boolean(context, &creds->client->realm,
- "verify_ap_req_nofail",
- &nofail))
- == 0)
- ;
- else
- nofail = 0;
- }
-
- if ((keytab_key_exists && rd_req_succeeds) ||
- (!keytab_key_exists && !nofail)) {
- ret = 0;
+ /* if we get this far, then the verification succeeded. We can
+ still fail if the library stuff here fails, but that's it */
- if (ccache_arg && ccache) {
- if (*ccache_arg == NULL) {
- krb5_ccache retcc;
+ if (ccache_arg && ccache) {
+ if (*ccache_arg == NULL) {
+ krb5_ccache retcc;
- retcc = NULL;
+ retcc = NULL;
- if ((ret = krb5_cc_resolve(context, "MEMORY:rd_req2", &retcc)) ||
- (ret = krb5_cc_initialize(context, retcc, creds->client)) ||
- (ret = krb5_cc_copy_creds_except(context, ccache, retcc,
- creds->server))) {
+ if ((ret = krb5_cc_resolve(context, "MEMORY:rd_req2", &retcc)) ||
+ (ret = krb5_cc_initialize(context, retcc, creds->client)) ||
+ (ret = krb5_cc_copy_creds_except(context, ccache, retcc,
+ creds->server))) {
if (retcc)
- krb5_cc_destroy(context, retcc);
- } else {
+ krb5_cc_destroy(context, retcc);
+ } else {
*ccache_arg = retcc;
- }
- } else {
- /* if this returns an error, then that's the return
- from this function */
- ret = krb5_cc_copy_creds_except(context, ccache, *ccache_arg,
- server);
- }
- }
+ }
+ } else {
+ ret = krb5_cc_copy_creds_except(context, ccache, *ccache_arg,
+ server);
+ }
}
- if (!server_arg)
+ /* if any of the above paths returned an errors, then ret is set
+ accordingly. either that, or it's zero, which is fine, too */
+
+cleanup:
+ if (!server_arg && server)
krb5_free_principal(context, server);
- if (!keytab_arg)
+ if (!keytab_arg && keytab)
krb5_kt_close(context, keytab);
if (ccache)
krb5_cc_destroy(context, ccache);
@@ -233,6 +224,3 @@ cleanup:
return(ret);
}
-
-
-
diff --git a/src/lib/krb5/os/ChangeLog b/src/lib/krb5/os/ChangeLog
index 0ee4a7192..84f0dec67 100644
--- a/src/lib/krb5/os/ChangeLog
+++ b/src/lib/krb5/os/ChangeLog
@@ -1,3 +1,16 @@
+1998-10-27 Marc Horowitz <marc@mit.edu>
+
+ * c_ustime.c, localaddr.c: moved here from lib/crypto
+
+ * ktdefname.c (krb5_kt_default_name): there is code in the tree
+ (notably, the admin server code) which uses globals to set the
+ keytab which will be used by gssapi. this is gross, and we need a
+ better answer. However, even that didn't work if there was an env
+ var or krb5.conf variable, since those override krb5_defkeyname.
+ Add a new global, krb5_overridekeyname, which really does override
+ all the other keytab locators. While I'm at it, make the buffer
+ overflow checks sane.
+
Fri Sep 25 22:32:16 1998 Theodore Y. Ts'o <tytso@mit.edu>
* ccdefname.c: We shouldn't try to use the CCache API on Unix
diff --git a/src/lib/krb5/os/Makefile.in b/src/lib/krb5/os/Makefile.in
index 9e132dbc8..56edfac36 100644
--- a/src/lib/krb5/os/Makefile.in
+++ b/src/lib/krb5/os/Makefile.in
@@ -12,6 +12,7 @@ PROG_RPATH=$(KRB5_LIBDIR)
STLIBOBJS= \
an_to_ln.o \
+ c_ustime.o \
def_realm.o \
DNR.o \
ccdefname.o \
@@ -54,6 +55,7 @@ STLIBOBJS= \
OBJS= \
an_to_ln.$(OBJEXT) \
+ c_ustime.$(OBJEXT) \
def_realm.$(OBJEXT) \
DNR.$(OBJEXT) \
ccdefname.$(OBJEXT) \
@@ -96,6 +98,7 @@ OBJS= \
SRCS= \
$(srcdir)/an_to_ln.c \
+ $(srcdir)/c_ustime.c \
$(srcdir)/def_realm.c \
$(srcdir)/DNR.c \
$(srcdir)/ccdefname.c \
diff --git a/src/lib/krb5/os/c_ustime.c b/src/lib/krb5/os/c_ustime.c
new file mode 100644
index 000000000..350c1aa5c
--- /dev/null
+++ b/src/lib/krb5/os/c_ustime.c
@@ -0,0 +1,316 @@
+/*
+ * lib/crypto/os/c_ustime.c
+ *
+ * Copyright 1990,1991 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.
+ *
+ *
+ * krb5_mstimeofday for BSD 4.3
+ */
+
+#define NEED_SOCKETS
+#include "k5-int.h"
+
+#ifdef _MACINTOSH
+
+/* We're a Macintosh -- do Mac time things. */
+
+/*
+ * This code is derived from kerberos/src/lib/des/mac_time.c from
+ * the Cygnus Support release of Kerberos V4:
+ *
+ * mac_time.c
+ * (Originally time_stuff.c)
+ * Copyright 1989 by the Massachusetts Institute of Technology.
+ * Macintosh ooperating system interface for Kerberos.
+ */
+
+#include "AddressXlation.h" /* for ip_addr, for #if 0'd net-time stuff */
+
+#include <script.h> /* Defines MachineLocation, used by getTimeZoneOffset */
+#include <ToolUtils.h> /* Defines BitTst(), called by getTimeZoneOffset() */
+#include <OSUtils.h> /* Defines GetDateTime */
+
+/* Mac Cincludes */
+#include <string.h>
+#include <stddef.h>
+
+static krb5_int32 last_sec = 0, last_usec = 0;
+
+/*
+ * The Unix epoch is 1/1/70, the Mac epoch is 1/1/04.
+ *
+ * 70 - 4 = 66 year differential
+ *
+ * Thus the offset is:
+ *
+ * (66 yrs) * (365 days/yr) * (24 hours/day) * (60 mins/hour) * (60 secs/min)
+ * plus
+ * (17 leap days) * (24 hours/day) * (60 mins/hour) * (60 secs/min)
+ *
+ * Don't forget the offset from GMT.
+ */
+
+/* returns the offset in hours between the mac local time and the GMT */
+/* unsigned krb5_int32 */
+krb5_int32
+getTimeZoneOffset()
+{
+ MachineLocation macLocation;
+ long gmtDelta;
+
+ macLocation.u.gmtDelta=0L;
+ ReadLocation(&macLocation);
+ gmtDelta=macLocation.u.gmtDelta & 0x00FFFFFF;
+ if (BitTst((void *)&gmtDelta,23L))
+ gmtDelta |= 0xFF000000;
+ gmtDelta /= 3600L;
+ return(gmtDelta);
+}
+
+/* Returns the GMT in seconds (and fake microseconds) using the Unix epoch */
+
+krb5_error_code
+krb5_crypto_us_timeofday(seconds, microseconds)
+ krb5_int32 *seconds, *microseconds;
+{
+ krb5_int32 sec, usec;
+ time_t the_time;
+
+ GetDateTime (&the_time);
+
+ sec = the_time -
+ ((66 * 365 * 24 * 60 * 60) + (17 * 24 * 60 * 60) +
+ (getTimeZoneOffset() * 60 * 60));
+
+ usec = 0; /* Mac is too slow to count faster than once a second */
+
+ if ((sec == last_sec) && (usec == last_usec)) {
+ if (++last_usec >= 1000000) {
+ last_usec = 0;
+ last_sec++;
+ }
+ sec = last_sec;
+ usec = last_usec;
+ }
+ else {
+ last_sec = sec;
+ last_usec = usec;
+ }
+
+ *seconds = sec;
+ *microseconds = usec;
+
+ return 0;
+}
+
+
+#elif defined(_WIN32)
+
+ /* Microsoft Windows NT and 95 (32bit) */
+ /* This one works for WOW (Windows on Windows, ntvdm on Win-NT) */
+
+#include <time.h>
+#include <sys/timeb.h>
+#include <string.h>
+
+krb5_error_code
+krb5_crypto_us_timeofday(seconds, microseconds)
+register krb5_int32 *seconds, *microseconds;
+{
+ struct _timeb timeptr;
+ krb5_int32 sec, usec;
+ static krb5_int32 last_sec = 0;
+ static krb5_int32 last_usec = 0;
+
+ _ftime(&timeptr); /* Get the current time */
+ sec = timeptr.time;
+ usec = timeptr.millitm * 1000;
+
+ if ((sec == last_sec) && (usec <= last_usec)) { /* Same as last time??? */
+ usec = ++last_usec;
+ if (usec >= 1000000) {
+ ++sec;
+ usec = 0;
+ }
+ }
+ last_sec = sec; /* Remember for next time */
+ last_usec = usec;
+
+ *seconds = sec; /* Return the values */
+ *microseconds = usec;
+
+ return 0;
+}
+
+#elif defined (_MSDOS)
+
+
+/*
+ * Originally written by John Gilmore, Cygnus Support, May '94.
+ * Public Domain.
+ */
+
+#include <time.h>
+#include <sys/timeb.h>
+#include <dos.h>
+#include <string.h>
+
+/*
+ * Time handling. Translate Unix time calls into Kerberos internal
+ * procedure calls.
+ *
+ * Due to the fact that DOS time can be unreliable we have reverted
+ * to using the AT hardware clock and converting it to Unix time.
+ */
+
+static time_t win_gettime ();
+static long win_time_get_epoch(); /* Adjust for MSC 7.00 bug */
+
+krb5_error_code
+krb5_crypto_us_timeofday(seconds, microseconds)
+register krb5_int32 *seconds, *microseconds;
+{
+ krb5_int32 sec, usec;
+ static krb5_int32 last_sec = 0;
+ static krb5_int32 last_usec = 0;
+
+ sec = win_gettime (); /* Get the current time */
+ usec = 0; /* Can't do microseconds */
+
+ if (sec == last_sec) { /* Same as last time??? */
+ usec = ++last_usec; /* Yep, so do microseconds */
+ if (usec >= 1000000) {
+ ++sec;
+ usec = 0;
+ }
+ }
+ last_sec = sec; /* Remember for next time */
+ last_usec = usec;
+
+ *seconds = sec; /* Return the values */
+ *microseconds = usec;
+
+ return 0;
+}
+
+
+static time_t
+win_gettime () {
+ struct tm tm;
+ union _REGS inregs; /* For calling BIOS */
+ union _REGS outregs;
+ struct _timeb now;
+ time_t time;
+ long convert; /* MSC 7.00 bug work around */
+
+ _ftime(&now); /* Daylight savings time */
+
+ /* Get time from AT hardware clock INT 0x1A, AH=2 */
+ memset(&inregs, 0, sizeof(inregs));
+ inregs.h.ah = 2;
+ _int86(0x1a, &inregs, &outregs);
+
+ /* 0x13 = decimal 13, hence the decoding below */
+ tm.tm_sec = 10 * ((outregs.h.dh & 0xF0) >> 4) + (outregs.h.dh & 0x0F);
+ tm.tm_min = 10 * ((outregs.h.cl & 0xF0) >> 4) + (outregs.h.cl & 0x0F);
+ tm.tm_hour = 10 * ((outregs.h.ch & 0xF0) >> 4) + (outregs.h.ch & 0x0F);
+
+ /* Get date from AT hardware clock INT 0x1A, AH=4 */
+ memset(&inregs, 0, sizeof(inregs));
+ inregs.h.ah = 4;
+ _int86(0x1a, &inregs, &outregs);
+
+ tm.tm_mday = 10 * ((outregs.h.dl & 0xF0) >> 4) + (outregs.h.dl & 0x0F);
+ tm.tm_mon = 10 * ((outregs.h.dh & 0xF0) >> 4) + (outregs.h.dh & 0x0F) - 1;
+ tm.tm_year = 10 * ((outregs.h.cl & 0xF0) >> 4) + (outregs.h.cl & 0x0F);
+ tm.tm_year += 100 * ((10 * (outregs.h.ch & 0xF0) >> 4)
+ + (outregs.h.ch & 0x0F) - 19);
+
+ tm.tm_wday = 0;
+ tm.tm_yday = 0;
+ tm.tm_isdst = now.dstflag;
+
+ time = mktime(&tm);
+
+ convert = win_time_get_epoch();
+ return time + convert;
+
+}
+
+
+/*
+ * This routine figures out the current time epoch and returns the
+ * conversion factor. It exists because
+ * Microloss screwed the pooch on the time() and _ftime() calls in
+ * its release 7.0 libraries. They changed the epoch to Dec 31, 1899!
+ * Idiots... We try to cope.
+ */
+
+static struct tm jan_1_70 = {0, 0, 0, 1, 0, 70};
+static long epoch = 0;
+static int epoch_set = 0;
+
+long
+win_time_get_epoch()
+{
+
+ if (!epoch_set) {
+ epoch = 0 - mktime (&jan_1_70); /* Seconds til 1970 localtime */
+ epoch += _timezone; /* Seconds til 1970 GMT */
+ epoch_set = 1;
+ }
+ return epoch;
+}
+
+
+#else
+
+
+/* We're a Unix machine -- do Unix time things. */
+
+extern int errno;
+
+static struct timeval last_tv = {0, 0};
+
+krb5_error_code
+krb5_crypto_us_timeofday(seconds, microseconds)
+ register krb5_int32 *seconds, *microseconds;
+{
+ struct timeval tv;
+
+ if (gettimeofday(&tv, (struct timezone *)0) == -1) {
+ /* failed, return errno */
+ return (krb5_error_code) errno;
+ }
+ if ((tv.tv_sec == last_tv.tv_sec) && (tv.tv_usec == last_tv.tv_usec)) {
+ if (++last_tv.tv_usec >= 1000000) {
+ last_tv.tv_usec = 0;
+ last_tv.tv_sec++;
+ }
+ tv = last_tv;
+ } else
+ last_tv = tv;
+
+ *seconds = tv.tv_sec;
+ *microseconds = tv.tv_usec;
+ return 0;
+}
+
+#endif
diff --git a/src/lib/krb5/os/ktdefname.c b/src/lib/krb5/os/ktdefname.c
index c645635ab..0493244f6 100644
--- a/src/lib/krb5/os/ktdefname.c
+++ b/src/lib/krb5/os/ktdefname.c
@@ -30,6 +30,9 @@
extern char *krb5_defkeyname;
+/* this is a an exceedinly gross thing. */
+char *krb5_overridekeyname = NULL;
+
KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
krb5_kt_default_name(context, name, namesize)
krb5_context context;
@@ -40,19 +43,24 @@ krb5_kt_default_name(context, name, namesize)
krb5_error_code code;
char *retval;
- if ((context->profile_secure == FALSE) &&
+ if (krb5_overridekeyname) {
+ if ((size_t) namesize < (strlen(krb5_overridekeyname)+1))
+ return KRB5_CONFIG_NOTENUFSPACE;
+ strcpy(name, krb5_overridekeyname);
+ } else if ((context->profile_secure == FALSE) &&
(cp = getenv("KRB5_KTNAME"))) {
- strncpy(name, cp, namesize);
- if (strlen(cp) >= (size_t) namesize)
+ if ((size_t) namesize < (strlen(cp)+1))
return KRB5_CONFIG_NOTENUFSPACE;
+ strcpy(name, cp);
} else if (((code = profile_get_string(context->profile,
"libdefaults",
"default_keytab_name", NULL,
NULL, &retval)) == 0) &&
retval) {
- strncpy(name, retval, namesize);
- if ((size_t) namesize < strlen(retval))
+ if ((size_t) namesize < (strlen(retval)+1))
return KRB5_CONFIG_NOTENUFSPACE;
+ strcpy(name, retval);
+ free(retval);
} else {
#if defined (_MSDOS) || defined(_WIN32)
{
@@ -66,9 +74,9 @@ krb5_kt_default_name(context, name, namesize)
sprintf(name, krb5_defkeyname, defname);
}
#else
- strncpy(name, krb5_defkeyname, namesize);
- if ((size_t) namesize < strlen(krb5_defkeyname))
+ if ((size_t) namesize < (strlen(krb5_defkeyname)+1))
return KRB5_CONFIG_NOTENUFSPACE;
+ strcpy(name, krb5_defkeyname);
#endif
}
return 0;
diff --git a/src/lib/krb5/os/localaddr.c b/src/lib/krb5/os/localaddr.c
index cb204b597..9f33e5d98 100644
--- a/src/lib/krb5/os/localaddr.c
+++ b/src/lib/krb5/os/localaddr.c
@@ -20,16 +20,329 @@
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
*
- * Just a stub that calls krb5_crypto_os_localaddr().
*
+ * Return the protocol addresses supported by this host.
+ *
+ * XNS support is untested, but "Should just work".
*/
+#define NEED_SOCKETS
#include "k5-int.h"
+#if !defined(HAVE_MACSOCK_H) && !defined(_MSDOS) && !defined(_WIN32)
+
+/* needed for solaris, harmless elsewhere... */
+#define BSD_COMP
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <errno.h>
+
+/*
+ * The SIOCGIF* ioctls require a socket.
+ * It doesn't matter *what* kind of socket they use, but it has to be
+ * a socket.
+ *
+ * Of course, you can't just ask the kernel for a socket of arbitrary
+ * type; you have to ask for one with a valid type.
+ *
+ */
+#ifdef HAVE_NETINET_IN_H
+
+#include <netinet/in.h>
+
+#ifndef USE_AF
+#define USE_AF AF_INET
+#define USE_TYPE SOCK_DGRAM
+#define USE_PROTO 0
+#endif
+
+#endif
+
+#ifdef KRB5_USE_NS
+
+#include <netns/ns.h>
+
+#ifndef USE_AF
+#define USE_AF AF_NS
+#define USE_TYPE SOCK_DGRAM
+#define USE_PROTO 0 /* guess */
+#endif
+
+#endif
+/*
+ * Add more address families here.
+ */
+
+/*
+ * BSD 4.4 defines the size of an ifreq to be
+ * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len
+ * However, under earlier systems, sa_len isn't present, so the size is
+ * just sizeof(struct ifreq)
+ */
+#ifdef HAVE_SA_LEN
+#ifndef max
+#define max(a,b) ((a) > (b) ? (a) : (b))
+#endif
+#define ifreq_size(i) max(sizeof(struct ifreq),\
+ sizeof((i).ifr_name)+(i).ifr_addr.sa_len)
+#else
+#define ifreq_size(i) sizeof(struct ifreq)
+#endif /* HAVE_SA_LEN*/
+
+
+
+extern int errno;
+
+/*
+ * Return all the protocol addresses of this host.
+ *
+ * We could kludge up something to return all addresses, assuming that
+ * they're valid kerberos protocol addresses, but we wouldn't know the
+ * real size of the sockaddr or know which part of it was actually the
+ * host part.
+ *
+ * This uses the SIOCGIFCONF, SIOCGIFFLAGS, and SIOCGIFADDR ioctl's.
+ */
+
KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
krb5_os_localaddr(context, addr)
krb5_context context;
krb5_address FAR * FAR * FAR *addr;
{
- return krb5_crypto_os_localaddr(addr);
+ struct ifreq *ifr, ifreq;
+ struct ifconf ifc;
+ int s, code, n, i;
+ char buf[1024];
+ krb5_address *addr_temp [ 1024/sizeof(struct ifreq) ];
+ int n_found;
+ int mem_err = 0;
+
+ memset(buf, 0, sizeof(buf));
+ ifc.ifc_len = sizeof(buf);
+ ifc.ifc_buf = buf;
+
+ s = socket (USE_AF, USE_TYPE, USE_PROTO);
+ if (s < 0)
+ return errno;
+
+ code = ioctl (s, SIOCGIFCONF, (char *)&ifc);
+ if (code < 0) {
+ int retval = errno;
+ closesocket (s);
+ return retval;
+ }
+ n = ifc.ifc_len;
+
+n_found = 0;
+ for (i = 0; i < n; i+= ifreq_size(*ifr) ) {
+ krb5_address *address;
+ ifr = (struct ifreq *)((caddr_t) ifc.ifc_buf+i);
+
+ strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof (ifreq.ifr_name));
+ if (ioctl (s, SIOCGIFFLAGS, (char *)&ifreq) < 0)
+ continue;
+
+#ifdef IFF_LOOPBACK
+ if (ifreq.ifr_flags & IFF_LOOPBACK)
+ continue;
+#endif
+
+ if (!(ifreq.ifr_flags & IFF_UP))
+ /* interface is down; skip */
+ continue;
+
+ /* ifr->ifr_addr has what we want! */
+ switch (ifr->ifr_addr.sa_family) {
+#ifdef HAVE_NETINET_IN_H
+ case AF_INET:
+ {
+ struct sockaddr_in *in =
+ (struct sockaddr_in *)&ifr->ifr_addr;
+
+ address = (krb5_address *)
+ malloc (sizeof(krb5_address));
+ if (address) {
+ address->magic = KV5M_ADDRESS;
+ address->addrtype = ADDRTYPE_INET;
+ address->length = sizeof(struct in_addr);
+ address->contents = (unsigned char *)malloc(address->length);
+ if (!address->contents) {
+ krb5_xfree(address);
+ address = 0;
+ mem_err++;
+ } else {
+ memcpy ((char *)address->contents,
+ (char *)&in->sin_addr,
+ address->length);
+ break;
+ }
+ } else mem_err++;
+ }
+#endif
+#ifdef KRB5_USE_NS
+ case AF_XNS:
+ {
+ struct sockaddr_ns *ns =
+ (struct sockaddr_ns *)&ifr->ifr_addr;
+ address = (krb5_address *)
+ malloc (sizeof (krb5_address) + sizeof (struct ns_addr));
+ if (address) {
+ address->magic = KV5M_ADDRESS;
+ address->addrtype = ADDRTYPE_XNS;
+
+ /* XXX should we perhaps use ns_host instead? */
+
+ address->length = sizeof(struct ns_addr);
+ address->contents = (unsigned char *)malloc(address->length);
+ if (!address->contents) {
+ krb5_xfree(address);
+ address = 0;
+ mem_err++;
+ } else {
+ memcpy ((char *)address->contents,
+ (char *)&ns->sns_addr,
+ address->length);
+ break;
+ }
+ } else mem_err++;
+ break;
+ }
+#endif
+ /*
+ * Add more address families here..
+ */
+ default:
+ continue;
+ }
+ if (address)
+ addr_temp[n_found++] = address;
+ address = 0;
+ }
+ closesocket(s);
+
+ *addr = (krb5_address **)malloc (sizeof (krb5_address *) * (n_found+1));
+ if (*addr == 0)
+ mem_err++;
+
+ if (mem_err) {
+ for (i=0; i<n_found; i++) {
+ krb5_xfree(addr_temp[i]);
+ addr_temp[i] = 0;
+ }
+ return ENOMEM;
+ }
+
+ for (i=0; i<n_found; i++) {
+ (*addr)[i] = addr_temp[i];
+ }
+ (*addr)[n_found] = 0;
+ return 0;
+}
+
+#else /* Windows/Mac version */
+
+/*
+ * Hold on to your lunch! Backup kludge method of obtaining your
+ * local IP address, courtesy of Windows Socket Network Programming,
+ * by Robert Quinn
+ */
+#if defined(_MSDOS) || defined(_WIN32)
+static struct hostent *local_addr_fallback_kludge()
+{
+ static struct hostent host;
+ static SOCKADDR_IN addr;
+ static char * ip_ptrs[2];
+ SOCKET sock;
+ int size = sizeof(SOCKADDR);
+ int err;
+
+ sock = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sock == INVALID_SOCKET)
+ return NULL;
+
+ /* connect to arbitrary port and address (NOT loopback) */
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(IPPORT_ECHO);
+ addr.sin_addr.s_addr = inet_addr("204.137.220.51");
+
+ err = connect(sock, (LPSOCKADDR) &addr, sizeof(SOCKADDR));
+ if (err == SOCKET_ERROR)
+ return NULL;
+
+ err = getsockname(sock, (LPSOCKADDR) &addr, (int FAR *) size);
+ if (err == SOCKET_ERROR)
+ return NULL;
+
+ closesocket(sock);
+
+ host.h_name = 0;
+ host.h_aliases = 0;
+ host.h_addrtype = AF_INET;
+ host.h_length = 4;
+ host.h_addr_list = ip_ptrs;
+ ip_ptrs[0] = (char *) &addr.sin_addr.s_addr;
+ ip_ptrs[1] = NULL;
+
+ return &host;
+}
+#endif
+
+/* No ioctls in winsock so we just assume there is only one networking
+ * card per machine, so gethostent is good enough.
+ */
+krb5_error_code
+krb5_os_localaddr (krb5_context context, krb5_address ***addr) {
+ char host[64]; /* Name of local machine */
+ struct hostent *hostrec;
+ int err;
+
+ *addr = calloc (2, sizeof (krb5_address *));
+ if (*addr == NULL)
+ return ENOMEM;
+
+#ifdef HAVE_MACSOCK_H
+ hostrec = getmyipaddr();
+#else /* HAVE_MACSOCK_H */
+ err = 0;
+
+ if (gethostname (host, sizeof(host))) {
+ err = WSAGetLastError();
+ }
+
+ if (!err) {
+ hostrec = gethostbyname (host);
+ if (hostrec == NULL) {
+ err = WSAGetLastError();
+ }
+ }
+
+ if (err) {
+ hostrec = local_addr_fallback_kludge();
+ if (!hostrec)
+ return err;
+ }
+#endif /* HAVE_MACSOCK_H */
+
+ (*addr)[0] = calloc (1, sizeof(krb5_address));
+ if ((*addr)[0] == NULL) {
+ free (*addr);
+ return ENOMEM;
+ }
+ (*addr)[0]->magic = KV5M_ADDRESS;
+ (*addr)[0]->addrtype = hostrec->h_addrtype;
+ (*addr)[0]->length = hostrec->h_length;
+ (*addr)[0]->contents = (unsigned char *)malloc((*addr)[0]->length);
+ if (!(*addr)[0]->contents) {
+ free((*addr)[0]);
+ free(*addr);
+ return ENOMEM;
+ } else {
+ memcpy ((*addr)[0]->contents,
+ hostrec->h_addr,
+ (*addr)[0]->length);
+ }
+ /* FIXME, deal with the case where gethostent returns multiple addrs */
+
+ return(0);
}
+#endif
diff --git a/src/lib/krb5/os/locate_kdc.c b/src/lib/krb5/os/locate_kdc.c
index c0ccf7e38..d8187ac3a 100644
--- a/src/lib/krb5/os/locate_kdc.c
+++ b/src/lib/krb5/os/locate_kdc.c
@@ -46,7 +46,7 @@ krb5_locate_kdc(context, realm, addr_pp, naddrs, master_index, nmasters)
const char *realm_kdc_names[4];
char **masterlist, **hostlist, *host, *port, *cp;
krb5_error_code code;
- int i, j, out, count;
+ int i, j, out, count, ismaster;
struct sockaddr *addr_p;
struct sockaddr_in *sin_p;
struct hostent *hp;
@@ -103,6 +103,9 @@ krb5_locate_kdc(context, realm, addr_pp, naddrs, master_index, nmasters)
}
if (master_index) {
+ *master_index = 0;
+ *nmasters = 0;
+
realm_kdc_names[0] = "realms";
realm_kdc_names[1] = host;
realm_kdc_names[2] = "admin_server";
@@ -113,10 +116,7 @@ krb5_locate_kdc(context, realm, addr_pp, naddrs, master_index, nmasters)
krb5_xfree(host);
- if (code) {
- *master_index = 0;
- *nmasters = 0;
- } else {
+ if (code == 0) {
for (i=0; masterlist[i]; i++) {
host = masterlist[i];
@@ -138,11 +138,10 @@ krb5_locate_kdc(context, realm, addr_pp, naddrs, master_index, nmasters)
krb5_xfree(host);
}
- /* at this point, is master is non-NULL, then either the master kdc
+ /* at this point, if master is non-NULL, then either the master kdc
is required, and there is one, or the master kdc is not required,
and there may or may not be one. */
-
#ifdef HAVE_NETINET_IN_H
if (sec_udpport)
count = count * 2;
@@ -175,10 +174,15 @@ krb5_locate_kdc(context, realm, addr_pp, naddrs, master_index, nmasters)
continue;
}
- if (masterlist)
- for (j=0; masterlist[j]; j++)
- if (strcasecmp(hostlist[i], masterlist[j]) == 0)
+ ismaster = 0;
+ if (masterlist) {
+ for (j=0; masterlist[j]; j++) {
+ if (strcasecmp(hostlist[i], masterlist[j]) == 0) {
*master_index = out;
+ ismaster = 1;
+ }
+ }
+ }
switch (hp->h_addrtype) {
@@ -211,7 +215,7 @@ krb5_locate_kdc(context, realm, addr_pp, naddrs, master_index, nmasters)
default:
break;
}
- if (masterlist)
+ if (ismaster)
*nmasters = out - *master_index;
/* Free the hostlist entry we are looping over. */
@@ -219,6 +223,11 @@ krb5_locate_kdc(context, realm, addr_pp, naddrs, master_index, nmasters)
hostlist[i] = 0;
}
+ if (masterlist) {
+ for (i=0; masterlist[i]; i++)
+ free(masterlist[i]);
+ free(masterlist);
+ }
free ((char *)hostlist);