summaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/ChangeLog28
-rw-r--r--src/lib/crypto/ChangeLog4
-rw-r--r--src/lib/crypto/Makefile.in4
-rw-r--r--src/lib/crypto/dk/ChangeLog14
-rw-r--r--src/lib/crypto/dk/derive.c4
-rw-r--r--src/lib/crypto/dk/dk_decrypt.c20
-rw-r--r--src/lib/crypto/dk/dk_encrypt.c30
-rw-r--r--src/lib/crypto/old/ChangeLog6
-rw-r--r--src/lib/crypto/old/old_decrypt.c19
-rw-r--r--src/lib/crypto/old/old_encrypt.c9
-rw-r--r--src/lib/crypto/prng.c2
-rw-r--r--src/lib/gssapi/ChangeLog4
-rw-r--r--src/lib/gssapi/Makefile.in2
-rw-r--r--src/lib/gssapi/krb5/ChangeLog61
-rw-r--r--src/lib/gssapi/krb5/accept_sec_context.c396
-rw-r--r--src/lib/gssapi/krb5/acquire_cred.c41
-rw-r--r--src/lib/gssapi/krb5/add_cred.c42
-rw-r--r--src/lib/gssapi/krb5/gssapiP_krb5.h77
-rw-r--r--src/lib/gssapi/krb5/init_sec_context.c476
-rw-r--r--src/lib/gssapi/krb5/inq_cred.c28
-rw-r--r--src/lib/gssapi/krb5/k5seal.c852
-rw-r--r--src/lib/gssapi/krb5/k5unseal.c1084
-rw-r--r--src/lib/gssapi/krb5/ser_sctx.c5
-rw-r--r--src/lib/gssapi/krb5/util_cksum.c5
-rw-r--r--src/lib/gssapi/krb5/util_crypt.c38
-rw-r--r--src/lib/gssapi/krb5/util_seed.c6
-rw-r--r--src/lib/gssapi/krb5/util_seqnum.c4
-rw-r--r--src/lib/gssapi/krb5/wrap_size_limit.c133
-rw-r--r--src/lib/kadm5/ChangeLog20
-rw-r--r--src/lib/kadm5/admin.h3
-rw-r--r--src/lib/kadm5/admin_internal.h3
-rw-r--r--src/lib/kadm5/alt_prof.c4
-rw-r--r--src/lib/kadm5/chpass_util.c64
-rw-r--r--src/lib/kadm5/clnt/ChangeLog14
-rw-r--r--src/lib/kadm5/clnt/client_init.c14
-rw-r--r--src/lib/kadm5/clnt/clnt_chpass_util.c5
-rw-r--r--src/lib/kadm5/logger.c5
-rw-r--r--src/lib/kadm5/ovsec_glue.c6
-rw-r--r--src/lib/kadm5/srv/ChangeLog8
-rw-r--r--src/lib/kadm5/srv/adb_openclose.c15
-rw-r--r--src/lib/kadm5/srv/svr_chpass_util.c5
-rw-r--r--src/lib/kadm5/unit-test/ChangeLog7
-rw-r--r--src/lib/kadm5/unit-test/api.2/chpass-principal-v2.exp4
-rw-r--r--src/lib/kadm5/unit-test/api.2/get-principal-v2.exp4
-rw-r--r--src/lib/kadm5/unit-test/api.2/randkey-principal-v2.exp4
-rw-r--r--src/lib/kdb/ChangeLog23
-rw-r--r--src/lib/kdb/fetch_mkey.c2
-rw-r--r--src/lib/kdb/setup_mkey.c2
-rw-r--r--src/lib/kdb/store_mkey.c2
-rw-r--r--src/lib/kdb/t_kdb.c47
-rw-r--r--src/lib/krb4/ChangeLog83
-rw-r--r--src/lib/krb4/Password.c9
-rw-r--r--src/lib/krb4/configure.in2
-rw-r--r--src/lib/krb4/cr_auth_repl.c10
-rw-r--r--src/lib/krb4/cr_ciph.c11
-rw-r--r--src/lib/krb4/cr_death_pkt.c5
-rw-r--r--src/lib/krb4/cr_err_repl.c9
-rw-r--r--src/lib/krb4/cr_tkt.c23
-rw-r--r--src/lib/krb4/decomp_tkt.c10
-rw-r--r--src/lib/krb4/dest_tkt.c5
-rw-r--r--src/lib/krb4/g_ad_tkt.c45
-rw-r--r--src/lib/krb4/g_in_tkt.c14
-rw-r--r--src/lib/krb4/g_krbhst.c8
-rw-r--r--src/lib/krb4/g_krbrlm.c3
-rw-r--r--src/lib/krb4/g_pw_in_tkt.c1
-rw-r--r--src/lib/krb4/in_tkt.c5
-rw-r--r--src/lib/krb4/kntoln.c7
-rw-r--r--src/lib/krb4/kparse.c73
-rw-r--r--src/lib/krb4/kuserok.c7
-rw-r--r--src/lib/krb4/mk_auth.c6
-rw-r--r--src/lib/krb4/mk_err.c8
-rw-r--r--src/lib/krb4/mk_req.c13
-rw-r--r--src/lib/krb4/rd_req.c44
-rw-r--r--src/lib/krb4/realmofhost.c8
-rw-r--r--src/lib/krb4/recvauth.c7
-rw-r--r--src/lib/krb4/send_to_kdc.c3
-rw-r--r--src/lib/krb4/sendauth.c3
-rw-r--r--src/lib/krb4/tf_util.c5
-rw-r--r--src/lib/krb4/win_store.c20
-rw-r--r--src/lib/krb5/ChangeLog8
-rw-r--r--src/lib/krb5/Makefile.in6
-rw-r--r--src/lib/krb5/krb/ChangeLog115
-rw-r--r--src/lib/krb5/krb/Makefile.in2
-rw-r--r--src/lib/krb5/krb/chk_trans.c17
-rw-r--r--src/lib/krb5/krb/conv_princ.c113
-rw-r--r--src/lib/krb5/krb/get_creds.c21
-rw-r--r--src/lib/krb5/krb/get_in_tkt.c35
-rw-r--r--src/lib/krb5/krb/init_ctx.c30
-rw-r--r--src/lib/krb5/krb/kfree.c129
-rw-r--r--src/lib/krb5/krb/mk_priv.c8
-rw-r--r--src/lib/krb5/krb/mk_req_ext.c16
-rw-r--r--src/lib/krb5/krb/rd_priv.c7
-rw-r--r--src/lib/krb5/krb/recvauth.c68
-rw-r--r--src/lib/krb5/krb/sendauth.c29
-rw-r--r--src/lib/krb5/krb/t_kerb.c32
-rw-r--r--src/lib/krb5/krb/t_krb5.conf6
-rw-r--r--src/lib/krb5/krb/t_ref_kerb.out2
-rw-r--r--src/lib/krb5/os/ChangeLog47
-rw-r--r--src/lib/krb5/os/an_to_ln.c20
-rw-r--r--src/lib/krb5/os/ccdefname.c2
-rw-r--r--src/lib/krb5/os/changepw.c6
-rw-r--r--src/lib/krb5/os/def_realm.c2
-rw-r--r--src/lib/krb5/os/hst_realm.c6
-rw-r--r--src/lib/krb5/os/init_os_ctx.c137
-rw-r--r--src/lib/krb5/os/kuserok.c5
-rw-r--r--src/lib/krb5/os/localaddr.c79
-rw-r--r--src/lib/krb5/os/locate_kdc.c64
-rw-r--r--src/lib/krb5/posix/ChangeLog7
-rw-r--r--src/lib/krb5/posix/syslog.c10
-rw-r--r--src/lib/krb5/rcache/ChangeLog5
-rw-r--r--src/lib/krb5/rcache/rc_io.c5
-rw-r--r--src/lib/krb5_32.def61
-rw-r--r--src/lib/krb5util/ChangeLog5
-rw-r--r--src/lib/krb5util/compat_recv.c145
-rw-r--r--src/lib/rpc/ChangeLog33
-rw-r--r--src/lib/rpc/auth_gssapi_misc.c16
-rw-r--r--src/lib/rpc/clnt_perror.c84
-rw-r--r--src/lib/rpc/clnt_simple.c5
-rw-r--r--src/lib/rpc/clnt_tcp.c2
-rw-r--r--src/lib/rpc/clnt_udp.c2
-rw-r--r--src/lib/rpc/get_myaddress.c2
-rw-r--r--src/lib/rpc/pmap_rmt.c11
-rw-r--r--src/lib/rpc/svc_auth_gssapi.c14
-rw-r--r--src/lib/rpc/unit-test/ChangeLog6
-rw-r--r--src/lib/rpc/unit-test/lib/helpers.exp6
-rw-r--r--src/lib/win_glue.c34
126 files changed, 2906 insertions, 2661 deletions
diff --git a/src/lib/ChangeLog b/src/lib/ChangeLog
index b54a4476f..66d1fd6e5 100644
--- a/src/lib/ChangeLog
+++ b/src/lib/ChangeLog
@@ -1,10 +1,36 @@
+2000-06-02 Danilo Almeida <dalmeida@mit.edu>
+
+ * win_glue.c (GetCallingAppVerInfo, krb5_vercheck): Use
+ APPVERINFO_SIZE-sized buffers instead of hard-coding a number
+ everywhere. Document the buffer size in funciton documentation.
+
+ * krb5_32.def: Add krb5int_cc_default for the benefit of GSS API DLL.
+
+2000-05-23 Nalin Dahyabhai <nalin@redhat.com>
+
+ * win_glue.c (GetCallingAppVerInfo): Don't overfill buffers
+ "AppTitle", "AppVer", and "AppIni".
+
2000-05-15 Jeffrey Altman <jaltman@columbia.edu>
- * krb5_32.def Added exports for new public functions
+ * krb5_32.def -- Added exports for new public functions
krb5_appdefault_string
krb5_appdefault_boolean
+2000-05-04 Danilo Almeida <dalmeida@mit.edu>
+
+ * krb5_32.def: Reflect something closer to the reality of
+ what we would like to do for 1.3.
+
+2000-05-03 Nalin Dahyabhai <nalin@redhat.com>
+
+ * win_glue.c (do_timebomb): Don't overflow buffer "buf".
+
+2000-04-29 Jeffrey Altman <jaltman@columbia.edu>
+
+ * krb5_32.def: Add krb5_get_tgs_ktypes, krb5_free_ktypes for gssapi
+
2000-03-15 Danilo Almeida <dalmeida@mit.edu>
* krb5_32.def: Add krb5_get_prompt_types.
diff --git a/src/lib/crypto/ChangeLog b/src/lib/crypto/ChangeLog
index f451cbe0d..f1fbfff04 100644
--- a/src/lib/crypto/ChangeLog
+++ b/src/lib/crypto/ChangeLog
@@ -1,3 +1,7 @@
+2000-06-03 Tom Yu <tlyu@mit.edu>
+
+ * Makefile.in(LIBMAJOR, LIBMINOR): Bump library version.
+
2000-05-31 Wilfredo Sanchez <tritan@mit.edu>
* configure.in, nfold.c: Check for existance of <memory.h>.
diff --git a/src/lib/crypto/Makefile.in b/src/lib/crypto/Makefile.in
index 71bddf5c4..64f19d18e 100644
--- a/src/lib/crypto/Makefile.in
+++ b/src/lib/crypto/Makefile.in
@@ -106,8 +106,8 @@ SRCS=\
LIB=k5crypto
-LIBMAJOR=2
-LIBMINOR=1
+LIBMAJOR=3
+LIBMINOR=0
RELDIR=crypto
STOBJLISTS=crc32/OBJS.ST des/OBJS.ST dk/OBJS.ST enc_provider/OBJS.ST \
diff --git a/src/lib/crypto/dk/ChangeLog b/src/lib/crypto/dk/ChangeLog
index a9bdafe99..1929ff6a1 100644
--- a/src/lib/crypto/dk/ChangeLog
+++ b/src/lib/crypto/dk/ChangeLog
@@ -1,3 +1,17 @@
+2000-06-03 Tom Yu <tlyu@mit.edu>
+
+ * dk_encrypt.c (krb5_dk_encrypt, krb5_marc_dk_encrypt): Chain
+ ivecs.
+
+ * dk_decrypt.c (krb5_dk_decrypt, krb5_marc_dk_decrypt): Chain
+ ivecs.
+
+2000-04-28 Ken Raeburn <raeburn@mit.edu>
+
+ * derive.c (krb5_derive_key): If memory allocation fails, release
+ other allocated blocks before returning, instead of trying to
+ release them after returning.
+
2000-01-21 Ken Raeburn <raeburn@mit.edu>
* checksum.c (krb5_dk_make_checksum): enc_providers are now
diff --git a/src/lib/crypto/dk/derive.c b/src/lib/crypto/dk/derive.c
index 8765605fb..dbd4a2a2d 100644
--- a/src/lib/crypto/dk/derive.c
+++ b/src/lib/crypto/dk/derive.c
@@ -51,14 +51,14 @@ krb5_derive_key(enc, inkey, outkey, in_constant)
return(ENOMEM);
if ((outblockdata = (unsigned char *) malloc(blocksize)) == NULL) {
- return(ENOMEM);
free(inblockdata);
+ return(ENOMEM);
}
if ((rawkey = (unsigned char *) malloc(keybytes)) == NULL) {
- return(ENOMEM);
free(outblockdata);
free(inblockdata);
+ return(ENOMEM);
}
inblock.data = inblockdata;
diff --git a/src/lib/crypto/dk/dk_decrypt.c b/src/lib/crypto/dk/dk_decrypt.c
index d3077615f..d6e7c0db3 100644
--- a/src/lib/crypto/dk/dk_decrypt.c
+++ b/src/lib/crypto/dk/dk_decrypt.c
@@ -41,7 +41,7 @@ krb5_dk_decrypt(enc, hash, key, usage, ivec, input, output)
{
krb5_error_code ret;
size_t hashsize, blocksize, keybytes, keylength, enclen, plainlen;
- unsigned char *plaindata, *kedata, *kidata, *cksum;
+ unsigned char *plaindata, *kedata, *kidata, *cksum, *cn;
krb5_keyblock ke, ki;
krb5_data d1, d2;
unsigned char constantdata[K5CLENGTH];
@@ -108,6 +108,11 @@ krb5_dk_decrypt(enc, hash, key, usage, ivec, input, output)
if ((ret = ((*(enc->decrypt))(&ke, ivec, &d1, &d2))) != 0)
goto cleanup;
+ if (ivec != NULL && ivec->length == blocksize)
+ cn = d1.data + d1.length - blocksize;
+ else
+ cn = NULL;
+
/* verify the hash */
d1.length = hashsize;
@@ -134,6 +139,9 @@ krb5_dk_decrypt(enc, hash, key, usage, ivec, input, output)
memcpy(output->data, d2.data+blocksize, output->length);
+ if (cn != NULL)
+ memcpy(ivec->data, cn, blocksize);
+
ret = 0;
cleanup:
@@ -163,7 +171,7 @@ krb5_marc_dk_decrypt(enc, hash, key, usage, ivec, input, output)
{
krb5_error_code ret;
size_t hashsize, blocksize, keybytes, keylength, enclen, plainlen;
- unsigned char *plaindata, *kedata, *kidata, *cksum;
+ unsigned char *plaindata, *kedata, *kidata, *cksum, *cn;
krb5_keyblock ke, ki;
krb5_data d1, d2;
unsigned char constantdata[K5CLENGTH];
@@ -230,6 +238,11 @@ krb5_marc_dk_decrypt(enc, hash, key, usage, ivec, input, output)
if ((ret = ((*(enc->decrypt))(&ke, ivec, &d1, &d2))) != 0)
goto cleanup;
+ if (ivec != NULL && ivec->length == blocksize)
+ cn = d1.data + d1.length - blocksize;
+ else
+ cn = NULL;
+
/* verify the hash */
d1.length = hashsize;
@@ -264,6 +277,9 @@ krb5_marc_dk_decrypt(enc, hash, key, usage, ivec, input, output)
memcpy(output->data, d2.data+4+blocksize, output->length);
+ if (cn != NULL)
+ memcpy(ivec->data, cn, blocksize);
+
ret = 0;
cleanup:
diff --git a/src/lib/crypto/dk/dk_encrypt.c b/src/lib/crypto/dk/dk_encrypt.c
index 8627353db..2bc2b6ba4 100644
--- a/src/lib/crypto/dk/dk_encrypt.c
+++ b/src/lib/crypto/dk/dk_encrypt.c
@@ -65,7 +65,7 @@ krb5_dk_encrypt(enc, hash, key, usage, ivec, input, output)
krb5_error_code ret;
unsigned char constantdata[K5CLENGTH];
krb5_data d1, d2;
- unsigned char *plaintext, *kedata, *kidata;
+ unsigned char *plaintext, *kedata, *kidata, *cn;
krb5_keyblock ke, ki;
/* allocate and set up plaintext and to-be-derived keys */
@@ -142,6 +142,11 @@ krb5_dk_encrypt(enc, hash, key, usage, ivec, input, output)
if ((ret = ((*(enc->encrypt))(&ke, ivec, &d1, &d2))))
goto cleanup;
+ if (ivec != NULL && ivec->length == blocksize)
+ cn = d2.data + d2.length - blocksize;
+ else
+ cn = NULL;
+
/* hash the plaintext */
d2.length = enclen - plainlen;
@@ -149,8 +154,14 @@ krb5_dk_encrypt(enc, hash, key, usage, ivec, input, output)
output->length = enclen;
- if ((ret = krb5_hmac(hash, &ki, 1, &d1, &d2)))
+ if ((ret = krb5_hmac(hash, &ki, 1, &d1, &d2))) {
memset(d2.data, 0, d2.length);
+ goto cleanup;
+ }
+
+ /* update ivec */
+ if (cn != NULL)
+ memcpy(ivec->data, cn, blocksize);
/* ret is set correctly by the prior call */
@@ -196,7 +207,7 @@ krb5_marc_dk_encrypt(enc, hash, key, usage, ivec, input, output)
krb5_error_code ret;
unsigned char constantdata[K5CLENGTH];
krb5_data d1, d2;
- unsigned char *plaintext, *kedata, *kidata;
+ unsigned char *plaintext, *kedata, *kidata, *cn;
krb5_keyblock ke, ki;
/* allocate and set up plaintext and to-be-derived keys */
@@ -278,6 +289,11 @@ krb5_marc_dk_encrypt(enc, hash, key, usage, ivec, input, output)
if ((ret = ((*(enc->encrypt))(&ke, ivec, &d1, &d2))))
goto cleanup;
+ if (ivec != NULL && ivec->length == blocksize)
+ cn = d2.data + d2.length - blocksize;
+ else
+ cn = NULL;
+
/* hash the plaintext */
d2.length = enclen - plainlen;
@@ -285,8 +301,14 @@ krb5_marc_dk_encrypt(enc, hash, key, usage, ivec, input, output)
output->length = enclen;
- if ((ret = krb5_hmac(hash, &ki, 1, &d1, &d2)))
+ if ((ret = krb5_hmac(hash, &ki, 1, &d1, &d2))) {
memset(d2.data, 0, d2.length);
+ goto cleanup;
+ }
+
+ /* update ivec */
+ if (cn != NULL)
+ memcpy(ivec->data, cn, blocksize);
/* ret is set correctly by the prior call */
diff --git a/src/lib/crypto/old/ChangeLog b/src/lib/crypto/old/ChangeLog
index 0bee167d1..7446daa2c 100644
--- a/src/lib/crypto/old/ChangeLog
+++ b/src/lib/crypto/old/ChangeLog
@@ -1,3 +1,9 @@
+2000-06-03 Tom Yu <tlyu@mit.edu>
+
+ * old_encrypt.c (krb5_old_encrypt): Chain ivecs.
+
+ * old_decrypt.c (krb5_old_decrypt): Chain ivecs.
+
2000-01-21 Ken Raeburn <raeburn@mit.edu>
* des_stringtokey.c (mit_des_string_to_key_int): Declare.
diff --git a/src/lib/crypto/old/old_decrypt.c b/src/lib/crypto/old/old_decrypt.c
index 1bcb0d38b..bfbe56a10 100644
--- a/src/lib/crypto/old/old_decrypt.c
+++ b/src/lib/crypto/old/old_decrypt.c
@@ -45,7 +45,7 @@ krb5_old_decrypt(enc, hash, key, usage, ivec, input, arg_output)
{
krb5_error_code ret;
size_t blocksize, hashsize, plainsize;
- unsigned char *cksumdata;
+ unsigned char *cksumdata, *cn;
krb5_data output, cksum, crcivec;
int alloced;
@@ -82,6 +82,17 @@ krb5_old_decrypt(enc, hash, key, usage, ivec, input, arg_output)
/* decrypt it */
+ /* save last ciphertext block in case we decrypt in place */
+ if (ivec != NULL && ivec->length == blocksize) {
+ cn = malloc(blocksize);
+ if (cn == NULL) {
+ ret = ENOMEM;
+ goto cleanup;
+ }
+ memcpy(cn, input->data + input->length - blocksize, blocksize);
+ } else
+ cn = NULL;
+
/* XXX this is gross, but I don't have much choice */
if ((key->enctype == ENCTYPE_DES_CBC_CRC) && (ivec == 0)) {
crcivec.length = key->length;
@@ -119,6 +130,10 @@ krb5_old_decrypt(enc, hash, key, usage, ivec, input, arg_output)
}
arg_output->length = plainsize;
+ /* update ivec */
+ if (cn != NULL)
+ memcpy(ivec->data, cn, blocksize);
+
ret = 0;
cleanup:
@@ -127,6 +142,8 @@ cleanup:
free(output.data);
}
+ if (cn != NULL)
+ free(cn);
memset(cksumdata, 0, hashsize);
free(cksumdata);
return(ret);
diff --git a/src/lib/crypto/old/old_encrypt.c b/src/lib/crypto/old/old_encrypt.c
index d90d0f885..8860ba5ff 100644
--- a/src/lib/crypto/old/old_encrypt.c
+++ b/src/lib/crypto/old/old_encrypt.c
@@ -55,6 +55,7 @@ krb5_old_encrypt(enc, hash, key, usage, ivec, input, output)
krb5_error_code ret;
size_t blocksize, hashsize, enclen;
krb5_data datain, crcivec;
+ int real_ivec;
(*(enc->block_size))(&blocksize);
(*(hash->hash_size))(&hashsize);
@@ -92,11 +93,17 @@ krb5_old_encrypt(enc, hash, key, usage, ivec, input, output)
crcivec.length = key->length;
crcivec.data = key->contents;
ivec = &crcivec;
- }
+ real_ivec = 0;
+ } else
+ real_ivec = 1;
if ((ret = ((*(enc->encrypt))(key, ivec, output, output))))
goto cleanup;
+ /* update ivec */
+ if (real_ivec && ivec != NULL && ivec->length == blocksize)
+ memcpy(ivec->data, output->data + output->length - blocksize,
+ blocksize);
cleanup:
if (ret)
memset(output->data, 0, output->length);
diff --git a/src/lib/crypto/prng.c b/src/lib/crypto/prng.c
index 6d401a9bf..b22131e0f 100644
--- a/src/lib/crypto/prng.c
+++ b/src/lib/crypto/prng.c
@@ -158,4 +158,4 @@ void prng_cleanup (void)
{
free (random_state);
inited = 0;
-} \ No newline at end of file
+}
diff --git a/src/lib/gssapi/ChangeLog b/src/lib/gssapi/ChangeLog
index 7dc9b00e7..b8da27165 100644
--- a/src/lib/gssapi/ChangeLog
+++ b/src/lib/gssapi/ChangeLog
@@ -1,3 +1,7 @@
+2000-06-03 Tom Yu <tlyu@mit.edu>
+
+ * Makefile.in(LIBMINOR): Bump library version.
+
2000-05-31 Wilfredo Sanchez <tritan@mit.edu>
* configure.in: Check for existance of <memory.h>.
diff --git a/src/lib/gssapi/Makefile.in b/src/lib/gssapi/Makefile.in
index bee2b8593..20936da19 100644
--- a/src/lib/gssapi/Makefile.in
+++ b/src/lib/gssapi/Makefile.in
@@ -24,7 +24,7 @@ SRCS=\
LIB=gssapi_krb5
LIBMAJOR=2
-LIBMINOR=1
+LIBMINOR=2
STOBJLISTS=OBJS.ST generic/OBJS.ST krb5/OBJS.ST
SHLIB_EXPDEPS=\
$(TOPLIBD)/libkrb5$(SHLIBEXT) \
diff --git a/src/lib/gssapi/krb5/ChangeLog b/src/lib/gssapi/krb5/ChangeLog
index ccb16f49a..087104e70 100644
--- a/src/lib/gssapi/krb5/ChangeLog
+++ b/src/lib/gssapi/krb5/ChangeLog
@@ -1,3 +1,62 @@
+2000-06-09 Tom Yu <tlyu@mit.edu>
+ Ken Raeburn <raeburn@mit.edu>
+
+ * accept_sec_context.c (krb5_gss_accept_sec_context): Remove
+ explicit check of mech OID against credential.
+
+ * util_crypt.c (kg_encrypt): Copy ivec, since c_encrypt() now
+ updates ivecs.
+ (kg_decrypt): Copy ivec, since c_decrypt() now updates ivecs.
+
+ * init_sec_context.c (get_credentials): Don't check each enctype
+ against a list from the krb5 library; instead, just try to use it,
+ and go on to the next if the error code indicates we can't use it.
+
+ * gssapiP_krb5.h (enum qop): New type, derived from spec but
+ currently not used.
+ * util_crypt.c (kg_encrypt, kg_decrypt): Added key derivation
+ usage value as an argument. Prototypes and callers updated; all
+ callers use KG_USAGE_SEAL, except KG_USAGE_SEQ when encrypting
+ sequence numbers.
+ * 3des.txt: New file.
+
+ * gssapiP_krb5.h (struct _krb5_gss_ctx_id_rec): Delete field
+ gsskrb5_version.
+ (struct _krb5_gss_cred_id_rec): Delete field rfcv2_mech.
+ * accept_sec_context.c, acquire_cred.c, add_cred.c, inq_cred.c,
+ k5seal.c, k5unseal.c, ser_ctx.c:
+ Delete krb5-mech2 support.
+
+ * init_sec_context.c (get_credentials): Enctype argument is now a
+ pointer to a list of enctypes. Explicitly try each in order until
+ success or an error other than cryptosystem not being supported.
+ (krb5_gss_init_sec_context): Pass list of cryptosystems, starting
+ with 3DES.
+
+ * gssapiP_krb5.h (enum sgn_alg, enum seal_alg): New types,
+ giving symbolic names for values from RFC 1964, a Microsoft win2k
+ I-D, and our proposed 3des-sha1 values.
+ (KG_USAGE_SEAL, KG_USAGE_SIGN, KG_USAGE_SEQ): New macros.
+
+ * accept_sec_context.c (rd_req_keyproc): Already-disabled routine
+ deleted.
+ (krb5_gss_accept_sec_context): Use sgn_alg and seal_alg symbolic
+ names. Add a case for des3-hmac-sha1.
+ * k5seal.c (make_seal_token_v1): Likewise. Do key derivation for
+ checksums.
+ * k5unseal.c (kg_unseal_v1): Likewise.
+ * util_crypt.c (kg_encrypt, kg_decrypt): Do key derivation for
+ encryption.
+
+ * util_crypt.c (zeros): Unused variable deleted.
+
+ * wrap_size_limit.c: Remove mech2 support. Add MIT copyright.
+
+2000-06-09 Nalin Dahyabhai <nalin@redhat.com>
+
+ * add_cred.c (krb5_gss_add_cred): Don't overflow buffers "ktboth"
+ or "ccboth".
+
2000-05-31 Wilfredo Sanchez <tritan@mit.edu>
* accept_sec_context.c, gssapiP_krb5.h, init_sec_context.c,
@@ -21,7 +80,7 @@
The rfc1964 mech always pads and confounds regardless of whether
confidentiality is requested.
-2000-01-27 Ken Raeburn <raeburn@raeburn.org>
+2000-01-27 Ken Raeburn <raeburn@mit.edu>
* init_sec_context.c (krb5_gss_init_sec_context): Default to
des-cbc-crc.
diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c
index 075d0e4c8..0d2aaa5ea 100644
--- a/src/lib/gssapi/krb5/accept_sec_context.c
+++ b/src/lib/gssapi/krb5/accept_sec_context.c
@@ -1,4 +1,28 @@
/*
+ * Copyright 2000 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. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * 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.
+ *
+ */
+/*
* Copyright 1993 by OpenVision Technologies, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
@@ -51,38 +75,7 @@
#ifdef HAVE_MEMORY_H
#include <memory.h>
#endif
-
-/*
- * $Id$
- */
-
-#if 0
-
-/* XXXX This widen/narrow stuff is bletcherous, but it seems to be
- necessary. Perhaps there is a "better" way, but I don't know what it
- is */
-
-#include <krb5/widen.h>
-static krb5_error_code
-rd_req_keyproc(krb5_pointer keyprocarg, krb5_principal server,
- krb5_kvno kvno, krb5_keyblock **keyblock)
-#include <krb5/narrow.h>
-{
- krb5_error_code code;
- krb5_keytab_entry ktentry;
-
- if (code = krb5_kt_get_entry((krb5_keytab) keyprocarg, server, kvno,
- &ktentry))
- return(code);
-
- code = krb5_copy_keyblock(&ktentry.key, keyblock);
-
- (void) krb5_kt_free_entry(&ktentry);
-
- return(code);
-}
-
-#endif
+#include <assert.h>
/* Decode, decrypt and store the forwarded creds in the local ccache. */
static krb5_error_code
@@ -147,7 +140,6 @@ rd_and_store_for_creds(context, inbuf, out_cred)
/* cred->princ already set */
cred->prerfc_mech = 1; /* this cred will work with all three mechs */
cred->rfc_mech = 1;
- cred->rfcv2_mech = 1;
cred->keytab = NULL; /* no keytab associated with this... */
cred->ccache = ccache; /* but there is a credential cache */
cred->tgt_expire = creds[0]->times.endtime; /* store the end time */
@@ -208,11 +200,10 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
krb5_ui_4 gss_flags = 0;
int decode_req_message = 0;
krb5_gss_ctx_id_rec *ctx = 0;
-#if 0
krb5_enctype enctype;
-#endif
krb5_timestamp now;
gss_buffer_desc token;
+ int err;
krb5_auth_context auth_context = NULL;
krb5_ticket * ticket = NULL;
int option_id;
@@ -224,7 +215,6 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
gss_cred_id_t cred_handle = NULL;
krb5_gss_cred_id_t deleg_cred = NULL;
int token_length;
- int gsskrb5_vers;
int nctypes;
krb5_cksumtype *ctypes = 0;
struct kg2_option fwcred;
@@ -298,13 +288,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
&(ap_req.length),
&ptr, KG_TOK_CTX_AP_REQ,
input_token->length))) {
- if (! cred->rfc_mech) {
- code = G_WRONG_MECH;
- major_status = GSS_S_DEFECTIVE_TOKEN;
- goto fail;
- }
mech_used = gss_mech_krb5;
- gsskrb5_vers = 1000;
} else if ((code == G_WRONG_MECH) &&
!(code = g_verify_token_header((gss_OID) gss_mech_krb5_old,
&(ap_req.length),
@@ -317,56 +301,15 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
* compatibility, and use it to decide when to use the
* old behavior.
*/
- if (! cred->prerfc_mech) {
- code = G_WRONG_MECH;
- major_status = GSS_S_DEFECTIVE_TOKEN;
- goto fail;
- }
mech_used = gss_mech_krb5_old;
- gsskrb5_vers = 1000;
- } else if ((code == G_WRONG_MECH) &&
- !(code = g_verify_token_header((gss_OID) gss_mech_krb5_v2,
- &token_length,
- &ptr, KG2_TOK_INITIAL,
- input_token->length))) {
- if (! cred->rfcv2_mech) {
- code = G_WRONG_MECH;
- major_status = GSS_S_DEFECTIVE_TOKEN;
- goto fail;
- }
- mech_used = gss_mech_krb5_v2;
- gsskrb5_vers = 2000;
} else {
major_status = GSS_S_DEFECTIVE_TOKEN;
goto fail;
}
- if (gsskrb5_vers == 2000) {
- /* gss krb5 v2 */
-
- fwcred.option_id = KRB5_GSS_FOR_CREDS_OPTION;
- fwcred.data = NULL;
-
- if (GSS_ERROR(major_status =
- kg2_parse_token(&code, ptr, token_length,
- &gss_flags, &nctypes, &ctypes,
- delegated_cred_handle?1:0,
- &fwcred, &ap_req, NULL))) {
- goto fail;
- }
-
- gss_flags = (ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3];
-
- gss_flags &= ~GSS_C_DELEG_FLAG; /* mask out the delegation flag;
- if there's a delegation, we'll
- set it below */
- } else {
- /* gss krb5 v1 */
-
- sptr = (char *) ptr;
- TREAD_STR(sptr, ap_req.data, ap_req.length);
- decode_req_message = 1;
- }
+ sptr = (char *) ptr;
+ TREAD_STR(sptr, ap_req.data, ap_req.length);
+ decode_req_message = 1;
/* construct the sender_addr */
@@ -418,9 +361,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
}
#endif
- if (gsskrb5_vers == 2000) {
- bigend = 1;
- } else {
+ {
/* gss krb5 v1 */
/* stash this now, for later. */
@@ -559,7 +500,6 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
ctx->gss_flags = KG_IMPLFLAGS(gss_flags);
ctx->seed_init = 0;
ctx->big_endian = bigend;
- ctx->gsskrb5_version = gsskrb5_vers;
/* Intern the ctx pointer so that delete_sec_context works */
if (! kg_save_ctx_id((gss_ctx_id_t) ctx)) {
@@ -605,114 +545,37 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
goto fail;
}
- if (gsskrb5_vers == 2000) {
- int cblen;
- krb5_boolean valid;
-
- /* intersect the token ctypes with the local ctypes */
-
- if (code = krb5_c_keyed_checksum_types(context, ctx->subkey->enctype,
- &ctx->nctypes, &ctx->ctypes))
- goto fail;
-
- if (nctypes == 0) {
- code = KRB5_CRYPTO_INTERNAL;
- goto fail;
- }
-
- kg2_intersect_ctypes(&ctx->nctypes, ctx->ctypes, nctypes, ctypes);
+ switch(ctx->subkey->enctype) {
+ case ENCTYPE_DES_CBC_MD5:
+ case ENCTYPE_DES_CBC_CRC:
+ ctx->subkey->enctype = ENCTYPE_DES_CBC_RAW;
+ ctx->signalg = SGN_ALG_DES_MAC_MD5;
+ ctx->cksum_size = 8;
+ ctx->sealalg = SEAL_ALG_DES;
- if (nctypes == 0) {
- code = KG_NO_CTYPES;
- goto fail;
- }
-
- /* process the delegated cred, if any */
-
- if (fwcred.data) {
- krb5_data option;
-
- option.length = fwcred.length;
- option.data = fwcred.data;
-
- if (code = rd_and_store_for_creds(context, &option, &deleg_cred)) {
- major_status = GSS_S_FAILURE;
- goto fail;
- }
-
- gss_flags |= GSS_C_DELEG_FLAG; /* got a delegation */
- }
-
- /* construct the checksum buffer */
-
- cblen = 4*5;
- if (input_chan_bindings)
- cblen += (input_chan_bindings->initiator_address.length+
- input_chan_bindings->acceptor_address.length+
- input_chan_bindings->application_data.length);
-
- cksumdata.length = cblen + ((char *)(ap_req.data-2) - (char *)(ptr-2));
+ /* fill in the encryption descriptors */
- if ((cksumdata.data = (char *) malloc(cksumdata.length)) == NULL) {
- code = ENOMEM;
+ if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc))) {
major_status = GSS_S_FAILURE;
goto fail;
}
- ptr2 = cksumdata.data;
-
- if (input_chan_bindings) {
- TWRITE_INT(ptr2, input_chan_bindings->initiator_addrtype, 1);
- TWRITE_BUF(ptr2, input_chan_bindings->initiator_address, 1);
- TWRITE_INT(ptr2, input_chan_bindings->acceptor_addrtype, 1);
- TWRITE_BUF(ptr2, input_chan_bindings->acceptor_address, 1);
- TWRITE_BUF(ptr2, input_chan_bindings->application_data, 1);
- } else {
- memset(ptr2, 0, cblen);
- ptr2 += cblen;
- }
-
- memcpy(ptr2, ptr-2, ((char *)(ap_req.data-2) - (char *)(ptr-2)));
+ for (i=0; i<ctx->enc->length; i++)
+ /*SUPPRESS 113*/
+ ctx->enc->contents[i] ^= 0xf0;
- if (code = krb5_c_verify_checksum(context, ctx->subkey,
- KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM,
- &cksumdata, authdat->checksum,
- &valid)) {
+ if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq))) {
major_status = GSS_S_FAILURE;
goto fail;
}
- free(cksumdata.data);
- cksumdata.data = 0;
+ break;
- if (!valid) {
- code = 0;
- major_status = GSS_S_BAD_SIG;
- goto fail;
- }
- } else {
- /* gss krb5 v1 */
-
- switch(ctx->subkey->enctype) {
- case ENCTYPE_DES_CBC_MD5:
- case ENCTYPE_DES_CBC_CRC:
- ctx->subkey->enctype = ENCTYPE_DES_CBC_RAW;
- ctx->signalg = 0;
- ctx->cksum_size = 8;
- ctx->sealalg = 0;
- break;
-#if 0
- case ENCTYPE_DES3_CBC_MD5:
- enctype = ENCTYPE_DES3_CBC_RAW;
- ctx->signalg = 3;
- ctx->cksum_size = 16;
- ctx->sealalg = 1;
- break;
-#endif
- default:
- code = KRB5_BAD_ENCTYPE;
- goto fail;
- }
+ case ENCTYPE_DES3_CBC_SHA1:
+ ctx->subkey->enctype = ENCTYPE_DES3_CBC_RAW;
+ ctx->signalg = SGN_ALG_HMAC_SHA1_DES3_KD;
+ ctx->cksum_size = 20;
+ ctx->sealalg = SEAL_ALG_DES3KD;
/* fill in the encryption descriptors */
@@ -721,14 +584,16 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
goto fail;
}
- for (i=0; i<ctx->enc->length; i++)
- /*SUPPRESS 113*/
- ctx->enc->contents[i] ^= 0xf0;
-
if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq))) {
major_status = GSS_S_FAILURE;
goto fail;
}
+
+ break;
+
+ default:
+ code = KRB5_BAD_ENCTYPE;
+ goto fail;
}
ctx->endtime = ticket->enc_part2->times.endtime;
@@ -771,122 +636,22 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
/* the reply token hasn't been sent yet, but that's ok. */
ctx->established = 1;
- if (ctx->gsskrb5_version == 2000) {
- krb5_ui_4 tok_flags;
-
- tok_flags =
- (ctx->gss_flags & GSS_C_DELEG_FLAG)?KG2_RESP_FLAG_DELEG_OK:0;
-
- cksumdata.length = 8 + 4*ctx->nctypes + 4;
-
- if ((cksumdata.data = (char *) malloc(cksumdata.length)) == NULL) {
- code = ENOMEM;
- major_status = GSS_S_FAILURE;
- goto fail;
- }
-
- /* construct the token fields */
-
- ptr = cksumdata.data;
-
- ptr[0] = (KG2_TOK_RESPONSE >> 8) & 0xff;
- ptr[1] = KG2_TOK_RESPONSE & 0xff;
-
- ptr[2] = (tok_flags >> 24) & 0xff;
- ptr[3] = (tok_flags >> 16) & 0xff;
- ptr[4] = (tok_flags >> 8) & 0xff;
- ptr[5] = tok_flags & 0xff;
-
- ptr[6] = (ctx->nctypes >> 8) & 0xff;
- ptr[7] = ctx->nctypes & 0xff;
-
- ptr += 8;
-
- for (i=0; i<ctx->nctypes; i++) {
- ptr[i] = (ctx->ctypes[i] >> 24) & 0xff;
- ptr[i+1] = (ctx->ctypes[i] >> 16) & 0xff;
- ptr[i+2] = (ctx->ctypes[i] >> 8) & 0xff;
- ptr[i+3] = ctx->ctypes[i] & 0xff;
-
- ptr += 4;
- }
-
- memset(ptr, 0, 4);
-
- /* make the MIC token */
+ token.length = g_token_size((gss_OID) mech_used, ap_rep.length);
- {
- gss_buffer_desc text, token;
-
- text.length = cksumdata.length;
- text.value = cksumdata.data;
-
- /* ctx->seq_send must be set before this call */
-
- if (GSS_ERROR(major_status =
- krb5_gss_get_mic(&code, ctx,
- GSS_C_QOP_DEFAULT,
- &text, &token)))
- goto fail;
-
- mic.length = token.length;
- mic.data = token.value;
- }
-
- token.length = g_token_size((gss_OID) mech_used,
- (cksumdata.length-2)+4+ap_rep.length+
- mic.length);
-
- if ((token.value = (unsigned char *) xmalloc(token.length))
- == NULL) {
- code = ENOMEM;
- major_status = GSS_S_FAILURE;
- goto fail;
- }
- ptr = token.value;
- g_make_token_header((gss_OID) mech_used,
- (cksumdata.length-2)+4+ap_rep.length+mic.length,
- &ptr, KG2_TOK_RESPONSE);
-
- memcpy(ptr, cksumdata.data+2, cksumdata.length-2);
- ptr += cksumdata.length-2;
-
- ptr[0] = (ap_rep.length >> 8) & 0xff;
- ptr[1] = ap_rep.length & 0xff;
- memcpy(ptr+2, ap_rep.data, ap_rep.length);
-
- ptr += (2+ap_rep.length);
-
- ptr[0] = (mic.length >> 8) & 0xff;
- ptr[1] = mic.length & 0xff;
- memcpy(ptr+2, mic.data, mic.length);
-
- ptr += (2+mic.length);
-
- free(cksumdata.data);
- cksumdata.data = 0;
-
- /* gss krb5 v2 */
- } else {
- /* gss krb5 v1 */
-
- token.length = g_token_size((gss_OID) mech_used, ap_rep.length);
-
- if ((token.value = (unsigned char *) xmalloc(token.length))
- == NULL) {
- major_status = GSS_S_FAILURE;
- code = ENOMEM;
- goto fail;
- }
- ptr = token.value;
- g_make_token_header((gss_OID) mech_used, ap_rep.length,
- &ptr, KG_TOK_CTX_AP_REP);
+ if ((token.value = (unsigned char *) xmalloc(token.length))
+ == NULL) {
+ major_status = GSS_S_FAILURE;
+ code = ENOMEM;
+ goto fail;
+ }
+ ptr = token.value;
+ g_make_token_header((gss_OID) mech_used, ap_rep.length,
+ &ptr, KG_TOK_CTX_AP_REP);
- TWRITE_STR(ptr, ap_rep.data, ap_rep.length);
+ TWRITE_STR(ptr, ap_rep.data, ap_rep.length);
- ctx->established = 1;
+ ctx->established = 1;
- }
} else {
token.length = 0;
token.value = NULL;
@@ -1016,13 +781,8 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
if (code)
return (major_status);
- if (gsskrb5_vers == 2000) {
- tmsglen = 12+scratch.length;
- toktype = KG2_TOK_RESPONSE;
- } else {
- tmsglen = scratch.length;
- toktype = KG_TOK_CTX_ERROR;
- }
+ tmsglen = scratch.length;
+ toktype = KG_TOK_CTX_ERROR;
token.length = g_token_size((gss_OID) mech_used, tmsglen);
token.value = (unsigned char *) xmalloc(token.length);
@@ -1032,24 +792,6 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
ptr = token.value;
g_make_token_header((gss_OID) mech_used, tmsglen, &ptr, toktype);
- if (gsskrb5_vers == 2000) {
- krb5_ui_4 flags;
-
- flags = KG2_RESP_FLAG_ERROR;
-
- ptr[0] = (flags << 24) & 0xff;
- ptr[1] = (flags << 16) & 0xff;
- ptr[2] = (flags << 8) & 0xff;
- ptr[3] = flags & 0xff;
-
- memset(ptr+4, 0, 6);
-
- ptr[10] = (scratch.length << 8) & 0xff;
- ptr[11] = scratch.length & 0xff;
-
- ptr += 12;
- }
-
TWRITE_STR(ptr, scratch.data, scratch.length);
xfree(scratch.data);
diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c
index 78e8c29dc..33946e767 100644
--- a/src/lib/gssapi/krb5/acquire_cred.c
+++ b/src/lib/gssapi/krb5/acquire_cred.c
@@ -1,4 +1,28 @@
/*
+ * Copyright 2000 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. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * 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.
+ *
+ */
+/*
* Copyright 1993 by OpenVision Technologies, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
@@ -53,10 +77,6 @@
#include <strings.h>
#endif
-/*
- * $Id$
- */
-
/* get credentials corresponding to a key in the krb5 keytab.
If the default name is requested, return the name in output_princ.
If output_princ is non-NULL, the caller will use or free it, regardless
@@ -283,7 +303,7 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req,
size_t i;
krb5_gss_cred_id_t cred;
gss_OID_set ret_mechs;
- int req_old, req_new, req_v2;
+ int req_old, req_new;
OM_uint32 ret;
krb5_error_code code;
@@ -313,22 +333,18 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req,
if (desired_mechs == GSS_C_NULL_OID_SET) {
req_old = 1;
req_new = 1;
- req_v2 = 1;
} else {
req_old = 0;
req_new = 0;
- req_v2 = 0;
for (i=0; i<desired_mechs->count; i++) {
if (g_OID_equal(gss_mech_krb5_old, &(desired_mechs->elements[i])))
req_old++;
if (g_OID_equal(gss_mech_krb5, &(desired_mechs->elements[i])))
req_new++;
- if (g_OID_equal(gss_mech_krb5_v2, &(desired_mechs->elements[i])))
- req_v2++;
}
- if (!req_old && !req_new && !req_v2) {
+ if (!req_old && !req_new) {
*minor_status = 0;
return(GSS_S_BAD_MECH);
}
@@ -347,7 +363,6 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req,
cred->princ = NULL;
cred->prerfc_mech = req_old;
cred->rfc_mech = req_new;
- cred->rfcv2_mech = req_v2;
cred->keytab = NULL;
cred->ccache = NULL;
@@ -447,10 +462,6 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req,
(cred->rfc_mech &&
GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status,
gss_mech_krb5,
- &ret_mechs))) ||
- (cred->rfcv2_mech &&
- GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status,
- gss_mech_krb5_v2,
&ret_mechs)))) {
if (cred->ccache)
(void)krb5_cc_close(context, cred->ccache);
diff --git a/src/lib/gssapi/krb5/add_cred.c b/src/lib/gssapi/krb5/add_cred.c
index 2a6fdb47b..918c26412 100644
--- a/src/lib/gssapi/krb5/add_cred.c
+++ b/src/lib/gssapi/krb5/add_cred.c
@@ -1,4 +1,28 @@
/*
+ * Copyright 2000 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. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * 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.
+ *
+ */
+/*
* Copyright (C) 1998 by the FundsXpress, INC.
*
* All rights reserved.
@@ -110,8 +134,7 @@ krb5_gss_add_cred(minor_status, input_cred_handle,
/* check that desired_mech isn't already in the credential */
if ((g_OID_equal(desired_mech, gss_mech_krb5_old) && cred->prerfc_mech) ||
- (g_OID_equal(desired_mech, gss_mech_krb5) && cred->rfc_mech) ||
- (g_OID_equal(desired_mech, gss_mech_krb5_v2) && cred->rfcv2_mech)) {
+ (g_OID_equal(desired_mech, gss_mech_krb5) && cred->rfc_mech)) {
*minor_status = 0;
return(GSS_S_DUPLICATE_ELEMENT);
}
@@ -156,7 +179,6 @@ krb5_gss_add_cred(minor_status, input_cred_handle,
new_cred->usage = cred_usage;
new_cred->prerfc_mech = cred->prerfc_mech;
new_cred->rfc_mech = cred->rfc_mech;
- new_cred->rfcv2_mech = cred->rfcv2_mech;
new_cred->tgt_expire = cred->tgt_expire;
if (code = krb5_copy_principal(context, cred->princ,
@@ -177,8 +199,9 @@ krb5_gss_add_cred(minor_status, input_cred_handle,
return(GSS_S_FAILURE);
}
- strcpy(ktboth, kttype);
- strcat(ktboth, ":");
+ strncpy(ktboth, kttype, sizeof(ktboth) - 1);
+ ktboth[sizeof(ktboth) - 1] = '\0';
+ strncat(ktboth, ":", sizeof(ktboth) - 1 - strlen(ktboth));
if (code = krb5_kt_get_name(context, cred->keytab,
ktboth+strlen(ktboth),
@@ -234,9 +257,10 @@ krb5_gss_add_cred(minor_status, input_cred_handle,
return(GSS_S_FAILURE);
}
- strcpy(ccboth, cctype);
- strcat(ccboth, ":");
- strcat(ccboth, ccname);
+ strncpy(ccboth, cctype, sizeof(ccboth) - 1);
+ ccboth[sizeof(ccboth) - 1] = '\0';
+ strncat(ccboth, ":", sizeof(ccboth) - 1 - strlen(ccboth));
+ strncat(ccboth, ccname, sizeof(ccboth) - 1 - strlen(ccboth));
if (code = krb5_cc_resolve(context, ccboth, &new_cred->ccache)) {
if (new_cred->rcache)
@@ -280,8 +304,6 @@ krb5_gss_add_cred(minor_status, input_cred_handle,
cred->prerfc_mech = 1;
else if (g_OID_equal(desired_mech, gss_mech_krb5))
cred->rfc_mech = 1;
- else if (g_OID_equal(desired_mech, gss_mech_krb5_v2))
- cred->rfcv2_mech = 1;
/* set the outputs */
diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h
index a22cd8ddd..ed0956999 100644
--- a/src/lib/gssapi/krb5/gssapiP_krb5.h
+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h
@@ -1,4 +1,28 @@
/*
+ * Copyright 2000 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. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * 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.
+ *
+ */
+/*
* Copyright 1993 by OpenVision Technologies, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
@@ -23,10 +47,6 @@
#ifndef _GSSAPIP_KRB5_H_
#define _GSSAPIP_KRB5_H_
-/*
- * $Id$
- */
-
#include <krb5.h>
#ifdef HAVE_MEMORY_H
#include <memory.h>
@@ -81,6 +101,39 @@
#define KG2_RESP_FLAG_ERROR 0x0001
#define KG2_RESP_FLAG_DELEG_OK 0x0002
+/* These are to be stored in little-endian order, i.e., des-mac is
+ stored as 02 00. */
+enum sgn_alg {
+ SGN_ALG_DES_MAC_MD5 = 0x0000,
+ SGN_ALG_MD2_5 = 0x0001,
+ SGN_ALG_DES_MAC = 0x0002,
+ SGN_ALG_3 = 0x0003, /* not published */
+ SGN_ALG_HMAC_MD5 = 0x0011, /* microsoft w2k; no support */
+ SGN_ALG_HMAC_SHA1_DES3_KD = 0x0004
+};
+enum seal_alg {
+ SEAL_ALG_NONE = 0xffff,
+ SEAL_ALG_DES = 0x0000,
+ SEAL_ALG_1 = 0x0001, /* not published */
+ SEAL_ALG_MICROSOFT_RC4 = 0x0010, /* microsoft w2k; no support */
+ SEAL_ALG_DES3KD = 0x0002
+};
+
+#define KG_USAGE_SEAL 22
+#define KG_USAGE_SIGN 23
+#define KG_USAGE_SEQ 24
+
+enum qop {
+ GSS_KRB5_INTEG_C_QOP_MD5 = 0x0001, /* *partial* MD5 = "MD2.5" */
+ GSS_KRB5_INTEG_C_QOP_DES_MD5 = 0x0002,
+ GSS_KRB5_INTEG_C_QOP_DES_MAC = 0x0003,
+ GSS_KRB5_INTEG_C_QOP_HMAC_SHA1 = 0x0004,
+ GSS_KRB5_INTEG_C_QOP_MASK = 0x00ff,
+ GSS_KRB5_CONF_C_QOP_DES = 0x0100,
+ GSS_KRB5_CONF_C_QOP_DES3_KD = 0x0200,
+ GSS_KRB5_CONF_C_QOP_MASK = 0xff00
+};
+
/** internal types **/
typedef krb5_principal krb5_gss_name_t;
@@ -91,7 +144,6 @@ typedef struct _krb5_gss_cred_id_rec {
krb5_principal princ; /* this is not interned as a gss_name_t */
int prerfc_mech;
int rfc_mech;
- int rfcv2_mech;
/* keytab (accept) data */
krb5_keytab keytab;
@@ -127,7 +179,6 @@ typedef struct _krb5_gss_ctx_id_rec {
int big_endian;
krb5_auth_context auth_context;
gss_OID_desc *mech_used;
- int gsskrb5_version;
int nctypes;
krb5_cksumtype *ctypes;
} krb5_gss_ctx_id_rec, *krb5_gss_ctx_id_t;
@@ -192,12 +243,18 @@ int kg_encrypt_size PROTOTYPE((krb5_context context,
krb5_keyblock *key, int n));
krb5_error_code kg_encrypt PROTOTYPE((krb5_context context,
- krb5_keyblock *key,
- krb5_pointer iv, krb5_pointer in, krb5_pointer out, int length));
+ krb5_keyblock *key, int usage,
+ krb5_pointer iv,
+ krb5_pointer in,
+ krb5_pointer out,
+ int length));
krb5_error_code kg_decrypt PROTOTYPE((krb5_context context,
- krb5_keyblock *key,
- krb5_pointer iv, krb5_pointer in, krb5_pointer out, int length));
+ krb5_keyblock *key, int usage,
+ krb5_pointer iv,
+ krb5_pointer in,
+ krb5_pointer out,
+ int length));
OM_uint32 kg_seal PROTOTYPE((krb5_context context,
OM_uint32 *minor_status,
diff --git a/src/lib/gssapi/krb5/init_sec_context.c b/src/lib/gssapi/krb5/init_sec_context.c
index 8baad8c05..13a971ffa 100644
--- a/src/lib/gssapi/krb5/init_sec_context.c
+++ b/src/lib/gssapi/krb5/init_sec_context.c
@@ -1,4 +1,28 @@
/*
+ * Copyright 2000 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. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * 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.
+ *
+ */
+/*
* Copyright 1993 by OpenVision Technologies, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
@@ -51,10 +75,7 @@
#include <memory.h>
#endif
#include <stdlib.h>
-
-/*
- * $Id$
- */
+#include <assert.h>
/* XXX This is for debugging only!!! Should become a real bitfield
at some point */
@@ -65,17 +86,18 @@ int krb5_gss_dbg_client_expcreds = 0;
* ccache.
*/
static krb5_error_code get_credentials(context, cred, server, now,
- endtime, enctype, out_creds)
+ endtime, enctypes, out_creds)
krb5_context context;
krb5_gss_cred_id_t cred;
krb5_principal server;
krb5_timestamp now;
krb5_timestamp endtime;
- krb5_enctype enctype;
+ const krb5_enctype *enctypes;
krb5_creds **out_creds;
{
krb5_error_code code;
krb5_creds in_creds;
+ int i;
memset((char *) &in_creds, 0, sizeof(krb5_creds));
@@ -84,10 +106,21 @@ static krb5_error_code get_credentials(context, cred, server, now,
if ((code = krb5_copy_principal(context, server, &in_creds.server)))
goto cleanup;
in_creds.times.endtime = endtime;
- in_creds.keyblock.enctype = enctype;
- if ((code = krb5_get_credentials(context, 0, cred->ccache,
- &in_creds, out_creds)))
+ in_creds.keyblock.enctype = 0;
+
+ for (i = 0; enctypes[i]; i++) {
+ in_creds.keyblock.enctype = enctypes[i];
+ code = krb5_get_credentials(context, 0, cred->ccache,
+ &in_creds, out_creds);
+ if (code != KRB5_CC_NOT_KTYPE && code != KRB5KDC_ERR_ETYPE_NOSUPP)
+ break;
+ }
+ if (enctypes[i] == 0) {
+ code = KRB5_CONFIG_ETYPE_NOSUPP;
+ goto cleanup;
+ }
+ if (code)
goto cleanup;
/*
@@ -95,7 +128,8 @@ static krb5_error_code get_credentials(context, cred, server, now,
* boundaries) because accept_sec_context code is also similarly
* non-forgiving.
*/
- if (!krb5_gss_dbg_client_expcreds && (*out_creds)->times.endtime < now) {
+ if (!krb5_gss_dbg_client_expcreds && *out_creds != NULL &&
+ (*out_creds)->times.endtime < now) {
code = KRB5KRB_AP_ERR_TKT_EXPIRED;
goto cleanup;
}
@@ -119,196 +153,8 @@ make_ap_req_v2(context, ctx, cred, k_cred, chan_bindings, mech_type, token)
gss_OID mech_type;
gss_buffer_t token;
{
- krb5_flags mk_req_flags = 0;
- krb5_int32 con_flags;
- krb5_error_code code;
- krb5_data credmsg, cksumdata, ap_req;
- int i, tlen, cblen, nctypes;
- krb5_cksumtype *ctypes;
- unsigned char *t, *ptr;
-
- credmsg.data = 0;
- cksumdata.data = 0;
- ap_req.data = 0;
- ctypes = 0;
-
- /* create the option data if necessary */
- if (ctx->gss_flags & GSS_C_DELEG_FLAG) {
- /* first get KRB_CRED message, so we know its length */
-
- /* clear the time check flag that was set in krb5_auth_con_init() */
- krb5_auth_con_getflags(context, ctx->auth_context, &con_flags);
- krb5_auth_con_setflags(context, ctx->auth_context,
- con_flags & ~KRB5_AUTH_CONTEXT_DO_TIME);
-
- code = krb5_fwd_tgt_creds(context, ctx->auth_context, 0,
- cred->princ, ctx->there, cred->ccache, 1,
- &credmsg);
-
- /* turn KRB5_AUTH_CONTEXT_DO_TIME back on */
- krb5_auth_con_setflags(context, ctx->auth_context, con_flags);
-
- if (code) {
- /* don't fail here; just don't accept/do the delegation
- request */
- ctx->gss_flags &= ~GSS_C_DELEG_FLAG;
- } else {
- if (credmsg.length > KRB5_INT16_MAX) {
- krb5_free_data_contents(context, &credmsg);
- return(KRB5KRB_ERR_FIELD_TOOLONG);
- }
- }
- } else {
- credmsg.length = 0;
- }
-
- /* construct the list of compatible cksum types */
-
- if ((code = krb5_c_keyed_checksum_types(context,
- k_cred->keyblock.enctype,
- &nctypes, &ctypes)))
- goto cleanup;
-
- if (nctypes == 0) {
- code = KRB5_CRYPTO_INTERNAL;
- goto cleanup;
- }
-
- /* construct the checksum fields */
-
- cblen = 4*5;
- if (chan_bindings)
- cblen += (chan_bindings->initiator_address.length+
- chan_bindings->acceptor_address.length+
- chan_bindings->application_data.length);
-
- cksumdata.length = cblen + 8 + 4*nctypes + 4;
- if (credmsg.length)
- cksumdata.length += 4 + credmsg.length;
-
- if ((cksumdata.data = (char *) malloc(cksumdata.length)) == NULL)
- goto cleanup;
-
- /* helper macros. This code currently depends on a long being 32
- bits, and htonl dtrt. */
-
- ptr = cksumdata.data;
-
- if (chan_bindings) {
- TWRITE_INT(ptr, chan_bindings->initiator_addrtype, 1);
- TWRITE_BUF(ptr, chan_bindings->initiator_address, 1);
- TWRITE_INT(ptr, chan_bindings->acceptor_addrtype, 1);
- TWRITE_BUF(ptr, chan_bindings->acceptor_address, 1);
- TWRITE_BUF(ptr, chan_bindings->application_data, 1);
- } else {
- memset(ptr, 0, cblen);
- ptr += cblen;
- }
-
- /* construct the token fields */
-
- ptr[0] = (KG2_TOK_INITIAL >> 8) & 0xff;
- ptr[1] = KG2_TOK_INITIAL & 0xff;
-
- ptr[2] = (ctx->gss_flags >> 24) & 0xff;
- ptr[3] = (ctx->gss_flags >> 16) & 0xff;
- ptr[4] = (ctx->gss_flags >> 8) & 0xff;
- ptr[5] = ctx->gss_flags & 0xff;
-
- ptr[6] = (nctypes >> 8) & 0xff;
- ptr[7] = nctypes & 0xff;
-
- ptr += 8;
-
- for (i=0; i<nctypes; i++) {
- ptr[0] = (ctypes[i] >> 24) & 0xff;
- ptr[1] = (ctypes[i] >> 16) & 0xff;
- ptr[2] = (ctypes[i] >> 8) & 0xff;
- ptr[3] = ctypes[i] & 0xff;
-
- ptr += 4;
- }
-
- if (credmsg.length) {
- ptr[0] = (KRB5_GSS_FOR_CREDS_OPTION >> 8) & 0xff;
- ptr[1] = KRB5_GSS_FOR_CREDS_OPTION & 0xff;
-
- ptr[2] = (credmsg.length >> 8) & 0xff;
- ptr[3] = credmsg.length & 0xff;
-
- ptr += 4;
-
- memcpy(ptr, credmsg.data, credmsg.length);
-
- ptr += credmsg.length;
- }
-
- memset(ptr, 0, 4);
-
- /* call mk_req. subkey and ap_req need to be used or destroyed */
-
- mk_req_flags = AP_OPTS_USE_SUBKEY;
-
- if (ctx->gss_flags & GSS_C_MUTUAL_FLAG)
- mk_req_flags |= AP_OPTS_MUTUAL_REQUIRED;
-
- if ((code = krb5_mk_req_extended(context, &ctx->auth_context, mk_req_flags,
- &cksumdata, k_cred, &ap_req)))
- goto cleanup;
-
- /* store the interesting stuff from creds and authent */
- ctx->endtime = k_cred->times.endtime;
- ctx->krb_flags = k_cred->ticket_flags;
-
- /* build up the token */
-
- /* allocate space for the token */
- tlen = g_token_size((gss_OID) mech_type,
- (cksumdata.length-(2+cblen))+2+ap_req.length);
-
- if ((t = (unsigned char *) xmalloc(tlen)) == NULL) {
- code = ENOMEM;
- goto cleanup;
- }
-
- ptr = t;
-
- g_make_token_header((gss_OID) mech_type,
- (cksumdata.length-(2+cblen))+2+ap_req.length,
- &ptr, KG2_TOK_INITIAL);
-
- /* skip over the channel bindings and the token id */
- memcpy(ptr, cksumdata.data+cblen+2, cksumdata.length-(cblen+2));
- ptr += cksumdata.length-(cblen+2);
- ptr[0] = (ap_req.length >> 8) & 0xff;
- ptr[1] = ap_req.length & 0xff;
- ptr += 2;
- memcpy(ptr, ap_req.data, ap_req.length);
-
- /* pass allocated data back */
-
- ctx->nctypes = nctypes;
- ctx->ctypes = ctypes;
-
- token->length = tlen;
- token->value = (void *) t;
-
- code = 0;
-
-cleanup:
- if (code) {
- if (ctypes)
- krb5_free_cksumtypes(context, ctypes);
- }
-
- if (credmsg.data)
- free(credmsg.data);
- if (ap_req.data)
- free(ap_req.data);
- if (cksumdata.data)
- free(cksumdata.data);
-
- return(code);
+ int krb5_mech2_supported = 0;
+ assert(krb5_mech2_supported);
}
static krb5_error_code
@@ -482,13 +328,19 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
krb5_context context;
krb5_gss_cred_id_t cred;
krb5_creds *k_cred = 0;
- krb5_enctype enctype = ENCTYPE_DES_CBC_CRC;
+ static const krb5_enctype wanted_enctypes[] = {
+#if 1
+ ENCTYPE_DES3_CBC_SHA1,
+#endif
+ ENCTYPE_DES_CBC_CRC,
+ ENCTYPE_DES_CBC_MD5, ENCTYPE_DES_CBC_MD4,
+ 0
+ };
krb5_error_code code;
krb5_gss_ctx_id_rec *ctx, *ctx_free;
krb5_timestamp now;
gss_buffer_desc token;
- int gsskrb5_vers = 0;
- int i, err;
+ int i, j, err;
int default_mech = 0;
krb5_ui_4 resp_flags;
OM_uint32 major_status;
@@ -530,32 +382,19 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
err = 0;
if (mech_type == GSS_C_NULL_OID) {
default_mech = 1;
- if (cred->rfcv2_mech) {
- mech_type = gss_mech_krb5_v2;
- gsskrb5_vers = 2000;
- } else if (cred->rfc_mech) {
+ if (cred->rfc_mech) {
mech_type = gss_mech_krb5;
- gsskrb5_vers = 1000;
- enctype = ENCTYPE_DES_CBC_CRC;
} else if (cred->prerfc_mech) {
mech_type = gss_mech_krb5_old;
- gsskrb5_vers = 1000;
- enctype = ENCTYPE_DES_CBC_CRC;
} else {
err = 1;
}
- } else if (g_OID_equal(mech_type, gss_mech_krb5_v2)) {
- if (!cred->rfcv2_mech)
- err = 1;
- gsskrb5_vers = 2000;
} else if (g_OID_equal(mech_type, gss_mech_krb5)) {
if (!cred->rfc_mech)
err = 1;
- gsskrb5_vers = 1000;
} else if (g_OID_equal(mech_type, gss_mech_krb5_old)) {
if (!cred->prerfc_mech)
err = 1;
- gsskrb5_vers = 1000;
} else {
err = 1;
}
@@ -609,7 +448,6 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
ctx->seed_init = 0;
ctx->big_endian = 0; /* all initiators do little-endian, as per spec */
ctx->seqstate = 0;
- ctx->gsskrb5_version = gsskrb5_vers;
ctx->nctypes = 0;
ctx->ctypes = 0;
@@ -630,27 +468,12 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
goto fail;
if ((code = get_credentials(context, cred, ctx->there, now,
- ctx->endtime, enctype, &k_cred)))
+ ctx->endtime, wanted_enctypes, &k_cred)))
goto fail;
- /*
- * If the default mechanism was requested, and the keytype is
- * DES_CBC, force the old mechanism
- */
- if (default_mech &&
- ((k_cred->keyblock.enctype == ENCTYPE_DES_CBC_CRC) ||
- (k_cred->keyblock.enctype == ENCTYPE_DES_CBC_MD4) ||
- (k_cred->keyblock.enctype == ENCTYPE_DES_CBC_MD5))) {
- ctx->gsskrb5_version = gsskrb5_vers = 1000;
+ if (default_mech) {
mech_type = gss_mech_krb5;
- if (k_cred->keyblock.enctype != ENCTYPE_DES_CBC_CRC) {
- krb5_free_creds(context, k_cred);
- enctype = ENCTYPE_DES_CBC_CRC;
- if ((code = get_credentials(context, cred, ctx->there, now,
- ctx->endtime, enctype, &k_cred)))
- goto fail;
- }
- }
+ }
if (generic_gss_copy_oid(minor_status, mech_type, &ctx->mech_used)
!= GSS_S_COMPLETE) {
@@ -662,24 +485,7 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
*/
ctx->mech_used = krb5_gss_convert_static_mech_oid(ctx->mech_used);
- if (ctx->gsskrb5_version == 2000) {
- /* gsskrb5 v2 */
- if ((code = make_ap_req_v2(context, ctx,
- cred, k_cred, input_chan_bindings,
- mech_type, &token))) {
- if ((code == KRB5_FCC_NOFILE) || (code == KRB5_CC_NOTFOUND) ||
- (code == KG_EMPTY_CCACHE))
- major_status = GSS_S_NO_CRED;
- if (code == KRB5KRB_AP_ERR_TKT_EXPIRED)
- major_status = GSS_S_CREDENTIALS_EXPIRED;
- goto fail;
- }
-
- krb5_auth_con_getlocalseqnumber(context, ctx->auth_context,
- &ctx->seq_send);
- krb5_auth_con_getlocalsubkey(context, ctx->auth_context,
- &ctx->subkey);
- } else {
+ {
/* gsskrb5 v1 */
if ((code = make_ap_req_v1(context, ctx,
cred, k_cred, input_chan_bindings,
@@ -701,11 +507,41 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
switch(ctx->subkey->enctype) {
case ENCTYPE_DES_CBC_MD5:
+ case ENCTYPE_DES_CBC_MD4:
case ENCTYPE_DES_CBC_CRC:
ctx->subkey->enctype = ENCTYPE_DES_CBC_RAW;
- ctx->signalg = 0;
+ ctx->signalg = SGN_ALG_DES_MAC_MD5;
ctx->cksum_size = 8;
- ctx->sealalg = 0;
+ ctx->sealalg = SEAL_ALG_DES;
+
+ /* The encryption key is the session key XOR
+ 0xf0f0f0f0f0f0f0f0. */
+ if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc)))
+ goto fail;
+
+ for (i=0; i<ctx->enc->length; i++)
+ /*SUPPRESS 113*/
+ ctx->enc->contents[i] ^= 0xf0;
+
+ if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq)))
+ goto fail;
+
+ break;
+
+ case ENCTYPE_DES3_CBC_SHA1:
+ ctx->subkey->enctype = ENCTYPE_DES3_CBC_RAW;
+ ctx->signalg = SGN_ALG_HMAC_SHA1_DES3_KD;
+ ctx->cksum_size = 20;
+ ctx->sealalg = SEAL_ALG_DES3KD;
+
+ code = krb5_copy_keyblock (context, ctx->subkey, &ctx->enc);
+ if (code)
+ goto fail;
+ code = krb5_copy_keyblock (context, ctx->subkey, &ctx->seq);
+ if (code) {
+ krb5_free_keyblock (context, ctx->enc);
+ goto fail;
+ }
break;
#if 0
case ENCTYPE_DES3_CBC_MD5:
@@ -716,20 +552,10 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
break;
#endif
default:
+ *minor_status = KRB5_BAD_ENCTYPE;
return GSS_S_FAILURE;
}
- /* the encryption key is the session key XOR 0xf0f0f0f0f0f0f0f0 */
-
- if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc)))
- goto fail;
-
- for (i=0; i<ctx->enc->length; i++)
- /*SUPPRESS 113*/
- ctx->enc->contents[i] ^= 0xf0;
-
- if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq)))
- goto fail;
}
if (k_cred) {
@@ -826,94 +652,38 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
ptr = (unsigned char *) input_token->value;
- if (ctx->gsskrb5_version == 2000) {
- int token_length;
- int nctypes;
- krb5_cksumtype *ctypes = 0;
-
- /* gsskrb5 v2 */
-
- if ((code = g_verify_token_header((gss_OID) ctx->mech_used,
- &token_length,
- &ptr, KG2_TOK_RESPONSE,
- input_token->length))) {
- major_status = GSS_S_DEFECTIVE_TOKEN;
- goto fail;
- }
-
- if (GSS_ERROR(major_status =
- kg2_parse_token(minor_status, ptr, token_length,
- &resp_flags, &nctypes, &ctypes,
- 0, NULL, &ap_rep, &mic))) {
- if (ctypes)
- free(ctypes);
- code = *minor_status;
- goto fail;
- }
- major_status = GSS_S_FAILURE;
-
- kg2_intersect_ctypes(&ctx->nctypes, ctx->ctypes, nctypes, ctypes);
-
- free(ctypes);
+ if ((err = g_verify_token_header((gss_OID) ctx->mech_used,
+ &(ap_rep.length),
+ &ptr, KG_TOK_CTX_AP_REP,
+ input_token->length))) {
+ if (g_verify_token_header((gss_OID) ctx->mech_used,
+ &(ap_rep.length),
+ &ptr, KG_TOK_CTX_ERROR,
+ input_token->length) == 0) {
- if (ctx->nctypes == 0) {
- code = KG_NO_CTYPES;
- goto fail;
- }
+ /* Handle a KRB_ERROR message from the server */
- if (resp_flags & KG2_RESP_FLAG_ERROR) {
- if ((code = krb5_rd_error(context, &ap_rep, &krb_error)))
+ sptr = (char *) ptr; /* PC compiler bug */
+ TREAD_STR(sptr, ap_rep.data, ap_rep.length);
+
+ code = krb5_rd_error(context, &ap_rep, &krb_error);
+ if (code)
goto fail;
-
if (krb_error->error)
code = krb_error->error + ERROR_TABLE_BASE_krb5;
else
code = 0;
-
krb5_free_error(context, krb_error);
goto fail;
+ } else {
+ *minor_status = 0;
+ return(GSS_S_DEFECTIVE_TOKEN);
}
-
- if (resp_flags & KG2_RESP_FLAG_DELEG_OK)
- ctx->gss_flags |= GSS_C_DELEG_FLAG;
-
- /* drop through to ap_rep handling */
- } else {
- /* gsskrb5 v1 */
-
- if ((err = g_verify_token_header((gss_OID) ctx->mech_used,
- &(ap_rep.length),
- &ptr, KG_TOK_CTX_AP_REP,
- input_token->length))) {
- if (g_verify_token_header((gss_OID) ctx->mech_used,
- &(ap_rep.length),
- &ptr, KG_TOK_CTX_ERROR,
- input_token->length) == 0) {
-
- /* Handle a KRB_ERROR message from the server */
-
- sptr = (char *) ptr; /* PC compiler bug */
- TREAD_STR(sptr, ap_rep.data, ap_rep.length);
-
- code = krb5_rd_error(context, &ap_rep, &krb_error);
- if (code)
- goto fail;
- if (krb_error->error)
- code = krb_error->error + ERROR_TABLE_BASE_krb5;
- else
- code = 0;
- krb5_free_error(context, krb_error);
- goto fail;
- } else {
- *minor_status = 0;
- return(GSS_S_DEFECTIVE_TOKEN);
- }
- }
-
- sptr = (char *) ptr; /* PC compiler bug */
- TREAD_STR(sptr, ap_rep.data, ap_rep.length);
}
+ sptr = (char *) ptr; /* PC compiler bug */
+ TREAD_STR(sptr, ap_rep.data, ap_rep.length);
+
/* decode the ap_rep */
if ((code = krb5_rd_rep(context, ctx->auth_context, &ap_rep,
&ap_rep_data))) {
@@ -940,26 +710,6 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
/* set established */
ctx->established = 1;
- if (ctx->gsskrb5_version == 2000) {
- gss_buffer_desc mic_data, mic_token;
-
- /* start with the token id */
- mic_data.value = ptr-2;
- /* end before the ap-rep length */
- mic_data.length = ((char*)(ap_rep.data-2)-(char*)(ptr-2));
-
- mic_token.length = mic.length;
- mic_token.value = mic.data;
-
- if (GSS_ERROR(major_status =
- krb5_gss_verify_mic(minor_status, *context_handle,
- &mic_data, &mic_token, NULL))) {
- code = *minor_status;
- goto fail;
- }
- major_status = GSS_S_FAILURE;
- }
-
/* set returns */
if (time_rec) {
diff --git a/src/lib/gssapi/krb5/inq_cred.c b/src/lib/gssapi/krb5/inq_cred.c
index c800012c8..6da0a5213 100644
--- a/src/lib/gssapi/krb5/inq_cred.c
+++ b/src/lib/gssapi/krb5/inq_cred.c
@@ -1,4 +1,28 @@
/*
+ * Copyright 2000 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. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * 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.
+ *
+ */
+/*
* Copyright 1993 by OpenVision Technologies, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
@@ -121,10 +145,6 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret,
(cred->rfc_mech &&
GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status,
gss_mech_krb5,
- &mechs))) ||
- (cred->rfcv2_mech &&
- GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status,
- gss_mech_krb5_v2,
&mechs)))) {
krb5_free_principal(context, ret_name);
/* *minor_status set above */
diff --git a/src/lib/gssapi/krb5/k5seal.c b/src/lib/gssapi/krb5/k5seal.c
index ae8cc7590..1ca108e65 100644
--- a/src/lib/gssapi/krb5/k5seal.c
+++ b/src/lib/gssapi/krb5/k5seal.c
@@ -1,6 +1,6 @@
/*
* Copyright 1993 by OpenVision Technologies, Inc.
- *
+ *
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appears in all copies and
@@ -10,7 +10,7 @@
* without specific, written prior permission. OpenVision makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
- *
+ *
* OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
@@ -22,14 +22,14 @@
/*
* 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
@@ -40,7 +40,7 @@
* 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.
@@ -49,196 +49,280 @@
#include "gssapiP_krb5.h"
static krb5_error_code
-make_priv_token_v2 PROTOTYPE((krb5_context context,
- krb5_keyblock *subkey,
+make_seal_token_v1 PROTOTYPE((krb5_context context,
+ krb5_keyblock *enc,
+ krb5_keyblock *seq,
krb5_int32 *seqnum,
int direction,
gss_buffer_t text,
gss_buffer_t token,
+ int signalg,
+ int cksum_size,
+ int sealalg,
+ int encrypt,
+ int toktype,
+ int bigend,
gss_OID oid));
static krb5_error_code
-make_priv_token_v2(context, subkey, seqnum, direction, text, token, oid)
- krb5_context context;
- krb5_keyblock *subkey;
- krb5_int32 *seqnum;
- int direction;
- gss_buffer_t text;
- gss_buffer_t token;
- gss_OID oid;
-{
- krb5_data plain;
- krb5_enc_data cipher;
- krb5_error_code code;
- size_t enclen;
- int tlen;
- unsigned char *t, *ptr;
-
- plain.data = 0;
- cipher.ciphertext.data = 0;
- t = 0;
-
- plain.length = 7+text->length;
- if ((plain.data = (void *) malloc(plain.length)) == NULL) {
- code = ENOMEM;
- goto cleanup;
- }
-
- plain.data[0] = (*seqnum >> 24) & 0xff;
- plain.data[1] = (*seqnum >> 16) & 0xff;
- plain.data[2] = (*seqnum >> 8) & 0xff;
- plain.data[3] = *seqnum & 0xff;
-
- plain.data[4] = direction?0:0xff;
-
- plain.data[5] = (text->length >> 8) & 0xff;
- plain.data[6] = text->length & 0xff;
-
- memcpy(plain.data+7, text->value, text->length);
-
- if (code = krb5_c_encrypt_length(context, subkey->enctype,
- plain.length, &enclen))
- goto cleanup;
-
- tlen = g_token_size((gss_OID) oid, 2+enclen);
-
- if ((t = (unsigned char *) xmalloc(tlen)) == NULL)
- return(ENOMEM);
-
- ptr = t;
-
- g_make_token_header((gss_OID) oid, 2+enclen, &ptr,
- KG2_TOK_WRAP_PRIV);
-
- ptr[0] = (enclen >> 8) & 0xff;
- ptr[1] = enclen & 0xff;
-
- cipher.ciphertext.length = enclen;
- cipher.ciphertext.data = ptr+2;
-
- if (code = krb5_c_encrypt(context, subkey,
- KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV,
- 0, &plain, &cipher))
- goto cleanup;
-
- /* that's it. return the token */
-
- (*seqnum)++;
-
- token->length = tlen;
- token->value = (void *) t;
-
- code = 0;
-
-cleanup:
- if (plain.data)
- free(plain.data);
- if (code) {
- if (t)
- free(t);
- }
-
- return(code);
-}
-
-static krb5_error_code
-make_integ_token_v2 PROTOTYPE((krb5_context context,
- krb5_keyblock *subkey,
- krb5_cksumtype ctype,
- krb5_int32 *seqnum,
- int direction,
- gss_buffer_t text,
- gss_buffer_t token,
- int toktype,
- gss_OID oid));
-
-static krb5_error_code
-make_integ_token_v2(context, subkey, ctype, seqnum, direction, text, token,
- toktype, oid)
- krb5_context context;
- krb5_keyblock *subkey;
- krb5_cksumtype ctype;
- krb5_int32 *seqnum;
- int direction;
- gss_buffer_t text;
- gss_buffer_t token;
- int toktype;
- gss_OID oid;
+make_seal_token_v1(context, enc, seq, seqnum, direction, text, token,
+ signalg, cksum_size, sealalg, encrypt, toktype,
+ bigend, oid)
+ krb5_context context;
+ krb5_keyblock *enc;
+ krb5_keyblock *seq;
+ krb5_int32 *seqnum;
+ int direction;
+ gss_buffer_t text;
+ gss_buffer_t token;
+ int signalg;
+ int cksum_size;
+ int sealalg;
+ int encrypt;
+ int toktype;
+ int bigend;
+ gss_OID oid;
{
krb5_error_code code;
- int tmp, tlen;
- unsigned char *t, *ptr;
- krb5_data plain;
+ size_t sumlen;
+ char *data_ptr;
+ krb5_data plaind;
+ krb5_checksum md5cksum;
krb5_checksum cksum;
+ int conflen=0, tmsglen, tlen;
+ unsigned char *t, *ptr;
- plain.data = 0;
- t = 0;
- cksum.contents = 0;
+ int encblksize, sumblksize;
+
+ switch (signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ case SGN_ALG_MD2_5:
+ case SGN_ALG_HMAC_MD5:
+ sumblksize = 1;
+ break;
+ case SGN_ALG_DES_MAC:
+ sumblksize = 8;
+ break;
+ case SGN_ALG_HMAC_SHA1_DES3_KD:
+ sumblksize = 1;
+ break;
+ default:
+ abort ();
+ return 123; /* find error code */
+ }
- /* assemble the checksum buffer and compute the checksum */
+ switch (sealalg) {
+ case SEAL_ALG_NONE:
+ case SEAL_ALG_DES:
+ case SEAL_ALG_DES3KD:
+ encblksize = 8;
+ break;
+ default:
+ abort ();
+ return 12345654321;
+ }
- plain.length = 7+text->length;
+ /* create the token buffer */
- if ((plain.data = (char *) malloc(plain.length)) == NULL) {
- code = errno;
- goto cleanup;
+ if (toktype == KG_TOK_SEAL_MSG) {
+ if (bigend && !encrypt) {
+ tmsglen = text->length;
+ } else {
+ conflen = kg_confounder_size(context, enc);
+ /* XXX knows that des block size is 8 */
+ tmsglen = (conflen+text->length+8)&(~7);
+ }
+ } else {
+ tmsglen = 0;
}
- plain.data[0] = (*seqnum >> 24) & 0xff;
- plain.data[1] = (*seqnum >> 16) & 0xff;
- plain.data[2] = (*seqnum >> 8) & 0xff;
- plain.data[3] = *seqnum & 0xff;
+ tlen = g_token_size((gss_OID) oid, 14+cksum_size+tmsglen);
- plain.data[4] = direction?0:0xff;
+ if ((t = (unsigned char *) xmalloc(tlen)) == NULL)
+ return(ENOMEM);
- plain.data[5] = (text->length >> 8) & 0xff;
- plain.data[6] = text->length & 0xff;
+ /*** fill in the token */
- memcpy(plain.data+7, text->value, text->length);
+ ptr = t;
- if (code = krb5_c_make_checksum(context, ctype, subkey,
- (toktype == KG2_TOK_WRAP_INTEG)?
- KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG:
- KRB5_KEYUSAGE_GSS_TOK_MIC,
- &plain, &cksum))
- goto cleanup;
+ g_make_token_header((gss_OID) oid, 14+cksum_size+tmsglen, &ptr, toktype);
- /* assemble the token itself */
+ /* 0..1 SIGN_ALG */
- if (toktype == KG2_TOK_WRAP_INTEG)
- tmp = 4+(7+text->length)+2+cksum.length;
- else
- tmp = 4+(5)+2+cksum.length;
+ ptr[0] = signalg & 0xff;
+ ptr[1] = (signalg >> 8) & 0xff;
- tlen = g_token_size((gss_OID) oid, tmp);
+ /* 2..3 SEAL_ALG or Filler */
- if ((t = (unsigned char *) xmalloc(tlen)) == NULL)
- return(ENOMEM);
+ if ((toktype == KG_TOK_SEAL_MSG) && encrypt) {
+ ptr[2] = sealalg & 0xff;
+ ptr[3] = (sealalg >> 8) & 0xff;
+ } else {
+ /* No seal */
+ ptr[2] = 0xff;
+ ptr[3] = 0xff;
+ }
- ptr = t;
+ /* 4..5 Filler */
+
+ ptr[4] = 0xff;
+ ptr[5] = 0xff;
+
+ /* pad the plaintext, encrypt if needed, and stick it in the token */
+
+ /* initialize the the cksum */
+ switch (signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ case SGN_ALG_MD2_5:
+ case SGN_ALG_HMAC_MD5:
+ md5cksum.checksum_type = CKSUMTYPE_RSA_MD5;
+ break;
+ case SGN_ALG_HMAC_SHA1_DES3_KD:
+ md5cksum.checksum_type = CKSUMTYPE_HMAC_SHA1_DES3;
+ break;
+ default:
+ case SGN_ALG_DES_MAC:
+ abort ();
+ }
- g_make_token_header((gss_OID) oid, tmp, &ptr, toktype);
+ if (code = krb5_c_checksum_length(context, md5cksum.checksum_type, &sumlen))
+ return(code);
+ md5cksum.length = sumlen;
+
+ if (toktype == KG_TOK_SEAL_MSG) {
+ unsigned char *plain;
+ unsigned char pad;
+
+ if (!bigend || encrypt) {
+ if ((plain = (unsigned char *) xmalloc(tmsglen)) == NULL) {
+ xfree(t);
+ return(ENOMEM);
+ }
+
+ if ((code = kg_make_confounder(context, enc, plain))) {
+ xfree(plain);
+ xfree(t);
+ return(code);
+ }
+
+ memcpy(plain+conflen, text->value, text->length);
+
+ /* XXX 8 is DES cblock size */
+ pad = 8-(text->length%8);
+
+ memset(plain+conflen+text->length, pad, pad);
+ } else {
+ /* plain is never used in the bigend && !encrypt case */
+ plain = NULL;
+ }
+
+ if (encrypt) {
+ if ((code = kg_encrypt(context, enc, KG_USAGE_SEAL, NULL,
+ (krb5_pointer) plain,
+ (krb5_pointer) (ptr+cksum_size+14),
+ tmsglen))) {
+ if (plain)
+ xfree(plain);
+ xfree(t);
+ return(code);
+ }
+ } else {
+ if (bigend)
+ memcpy(ptr+14+cksum_size, text->value, text->length);
+ else
+ memcpy(ptr+14+cksum_size, plain, tmsglen);
+ }
+
+ /* compute the checksum */
+
+ /* 8 = head of token body as specified by mech spec */
+ if (! (data_ptr =
+ (char *) xmalloc(8 + (bigend ? text->length : tmsglen)))) {
+ if (plain)
+ xfree(plain);
+ xfree(t);
+ return(ENOMEM);
+ }
+ (void) memcpy(data_ptr, ptr-2, 8);
+ if (bigend)
+ (void) memcpy(data_ptr+8, text->value, text->length);
+ else
+ (void) memcpy(data_ptr+8, plain, tmsglen);
+ plaind.length = 8 + (bigend ? text->length : tmsglen);
+ plaind.data = data_ptr;
+ code = krb5_c_make_checksum(context, md5cksum.checksum_type, seq,
+ KG_USAGE_SIGN, &plaind, &md5cksum);
+ xfree(data_ptr);
+
+ if (code) {
+ if (plain)
+ xfree(plain);
+ xfree(t);
+ return(code);
+ }
- ptr[0] = (ctype >> 24) & 0xff;
- ptr[1] = (ctype >> 16) & 0xff;
- ptr[2] = (ctype >> 8) & 0xff;
- ptr[3] = ctype & 0xff;
+ if (plain)
+ xfree(plain);
+ } else {
+ /* Sign only. */
+ /* compute the checksum */
- ptr += 4;
+ if (! (data_ptr = (char *) xmalloc(8 + text->length))) {
+ xfree(t);
+ return(ENOMEM);
+ }
+ (void) memcpy(data_ptr, ptr-2, 8);
+ (void) memcpy(data_ptr+8, text->value, text->length);
+ plaind.length = 8 + text->length;
+ plaind.data = data_ptr;
+ code = krb5_c_make_checksum(context, md5cksum.checksum_type, seq,
+ KG_USAGE_SIGN, &plaind, &md5cksum);
+ xfree(data_ptr);
+ if (code) {
+ xfree(t);
+ return(code);
+ }
+ }
- if (toktype == KG2_TOK_WRAP_INTEG) {
- memcpy(ptr, plain.data, 7+text->length);
- ptr += 7+text->length;
- } else {
- memcpy(ptr, plain.data, 5);
- ptr += 5;
+ switch(signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ case 3:
+
+ if ((code = kg_encrypt(context, seq, KG_USAGE_SEAL,
+ (g_OID_equal(oid, gss_mech_krb5_old) ?
+ seq->contents : NULL),
+ md5cksum.contents, md5cksum.contents, 16))) {
+ xfree(md5cksum.contents);
+ xfree(t);
+ return code;
+ }
+
+ cksum.length = cksum_size;
+ cksum.contents = md5cksum.contents + 16 - cksum.length;
+
+ memcpy(ptr+14, cksum.contents, cksum.length);
+ break;
+
+ case SGN_ALG_HMAC_SHA1_DES3_KD:
+ /*
+ * Using key derivation, the call to krb5_c_make_checksum
+ * already dealt with encrypting.
+ */
+ if (md5cksum.length != cksum_size)
+ abort ();
+ memcpy (ptr+14, md5cksum.contents, md5cksum.length);
+ break;
}
- ptr[0] = (cksum.length >> 8) & 0xff;
- ptr[1] = cksum.length & 0xff;
- ptr += 2;
+ xfree(md5cksum.contents);
+
+ /* create the seq_num */
- memcpy(ptr, cksum.contents, cksum.length);
+ if ((code = kg_make_seq_num(context, seq, direction?0:0xff, *seqnum,
+ ptr+14, ptr+6))) {
+ xfree(t);
+ return(code);
+ }
/* that's it. return the token */
@@ -247,372 +331,110 @@ make_integ_token_v2(context, subkey, ctype, seqnum, direction, text, token,
token->length = tlen;
token->value = (void *) t;
- code = 0;
-
-cleanup:
- if (plain.data)
- free(plain.data);
- if (cksum.contents)
- krb5_free_checksum_contents(context, &cksum);
- if (code) {
- if (t)
- free(t);
- }
-
- return(code);
+ return(0);
}
-static krb5_error_code
-make_seal_token_v1 PROTOTYPE((krb5_context context,
- krb5_keyblock *enc,
- krb5_keyblock *seq,
- krb5_int32 *seqnum,
- int direction,
- gss_buffer_t text,
- gss_buffer_t token,
- int signalg,
- int cksum_size,
- int sealalg,
- int encrypt,
- int toktype,
- int bigend,
- gss_OID oid));
+/* if signonly is true, ignore conf_req, conf_state,
+ and do not encode the ENC_TYPE, MSG_LENGTH, or MSG_TEXT fields */
-static krb5_error_code
-make_seal_token_v1(context, enc, seq, seqnum, direction, text, token,
- signalg, cksum_size, sealalg, encrypt, toktype,
- bigend, oid)
- krb5_context context;
- krb5_keyblock *enc;
- krb5_keyblock *seq;
- krb5_int32 *seqnum;
- int direction;
- gss_buffer_t text;
- gss_buffer_t token;
- int signalg;
- int cksum_size;
- int sealalg;
- int encrypt;
- int toktype;
- int bigend;
- gss_OID oid;
+OM_uint32
+kg_seal(context, minor_status, context_handle, conf_req_flag, qop_req,
+ input_message_buffer, conf_state, output_message_buffer, toktype)
+ krb5_context context;
+ OM_uint32 *minor_status;
+ gss_ctx_id_t context_handle;
+ int conf_req_flag;
+ int qop_req;
+ gss_buffer_t input_message_buffer;
+ int *conf_state;
+ gss_buffer_t output_message_buffer;
+ int toktype;
{
- krb5_error_code code;
- size_t sumlen;
- char *data_ptr;
- krb5_data plaind;
- krb5_checksum md5cksum;
- krb5_checksum cksum;
- int conflen=0, tmsglen, tlen;
- unsigned char *t, *ptr;
-
- /* create the token buffer */
-
- if (toktype == KG_TOK_SEAL_MSG) {
- if (bigend && !encrypt) {
- tmsglen = text->length;
- } else {
- conflen = kg_confounder_size(context, enc);
- /* XXX knows that des block size is 8 */
- tmsglen = (conflen+text->length+8)&(~7);
- }
- } else {
- tmsglen = 0;
- }
-
- tlen = g_token_size((gss_OID) oid, 14+cksum_size+tmsglen);
-
- if ((t = (unsigned char *) xmalloc(tlen)) == NULL)
- return(ENOMEM);
-
- /*** fill in the token */
-
- ptr = t;
-
- g_make_token_header((gss_OID) oid, 14+cksum_size+tmsglen, &ptr, toktype);
-
- /* 0..1 SIGN_ALG */
-
- ptr[0] = signalg;
- ptr[1] = 0;
-
- /* 2..3 SEAL_ALG or Filler */
-
- if ((toktype == KG_TOK_SEAL_MSG) && encrypt) {
- ptr[2] = sealalg;
- ptr[3] = 0;
- } else {
- /* No seal */
- ptr[2] = 0xff;
- ptr[3] = 0xff;
- }
-
- /* 4..5 Filler */
-
- ptr[4] = 0xff;
- ptr[5] = 0xff;
-
- /* pad the plaintext, encrypt if needed, and stick it in the token */
-
- /* initialize the the cksum */
- if (code = krb5_c_checksum_length(context, CKSUMTYPE_RSA_MD5, &sumlen))
- return(code);
-
- md5cksum.checksum_type = CKSUMTYPE_RSA_MD5;
- md5cksum.length = sumlen;
- if (toktype == KG_TOK_SEAL_MSG) {
- unsigned char *plain;
- unsigned char pad;
-
- if (!bigend || encrypt) {
- if ((plain = (unsigned char *) xmalloc(tmsglen)) == NULL) {
- xfree(t);
- return(ENOMEM);
- }
-
- if ((code = kg_make_confounder(context, enc, plain))) {
- xfree(plain);
- xfree(t);
- return(code);
- }
-
- memcpy(plain+conflen, text->value, text->length);
-
- /* XXX 8 is DES cblock size */
- pad = 8-(text->length%8);
-
- memset(plain+conflen+text->length, pad, pad);
- } else {
- /* plain is never used in the bigend && !encrypt case */
- plain = NULL;
- }
+ krb5_gss_ctx_id_rec *ctx;
+ krb5_error_code code;
+ krb5_timestamp now;
- if (encrypt) {
- if ((code = kg_encrypt(context, enc, NULL, (krb5_pointer) plain,
- (krb5_pointer) (ptr+cksum_size+14),
- tmsglen))) {
- if (plain)
- xfree(plain);
- xfree(t);
- return(code);
- }
- } else {
- if (bigend)
- memcpy(ptr+14+cksum_size, text->value, text->length);
- else
- memcpy(ptr+14+cksum_size, plain, tmsglen);
- }
-
- /* compute the checksum */
-
- /* 8 = head of token body as specified by mech spec */
- if (! (data_ptr =
- (char *) xmalloc(8 + (bigend ? text->length : tmsglen)))) {
- if (plain)
- xfree(plain);
- xfree(t);
- return(ENOMEM);
- }
- (void) memcpy(data_ptr, ptr-2, 8);
- if (bigend)
- (void) memcpy(data_ptr+8, text->value, text->length);
- else
- (void) memcpy(data_ptr+8, plain, tmsglen);
- plaind.length = 8 + (bigend ? text->length : tmsglen);
- plaind.data = data_ptr;
- code = krb5_c_make_checksum(context, md5cksum.checksum_type,
- 0, 0, &plaind, &md5cksum);
- xfree(data_ptr);
-
- if (code) {
- if (plain)
- xfree(plain);
- xfree(t);
- return(code);
- memcpy(ptr+14+cksum_size, plain, tmsglen);
- }
-
- if (plain)
- xfree(plain);
- } else {
- /* compute the checksum */
-
- if (! (data_ptr = (char *) xmalloc(8 + text->length))) {
- xfree(t);
- return(ENOMEM);
- }
- (void) memcpy(data_ptr, ptr-2, 8);
- (void) memcpy(data_ptr+8, text->value, text->length);
- plaind.length = 8 + text->length;
- plaind.data = data_ptr;
- code = krb5_c_make_checksum(context, md5cksum.checksum_type, 0, 0,
- &plaind, &md5cksum);
- xfree(data_ptr);
- if (code) {
- xfree(t);
- return(code);
- }
- }
-
- switch(signalg) {
- case 0:
- case 3:
+ output_message_buffer->length = 0;
+ output_message_buffer->value = NULL;
+ /* only default qop or matching established cryptosystem is allowed */
+
#if 0
- /* XXX this depends on the key being a single-des key */
-
- /* DES CBC doesn't use a zero IV like it should in some
- krb5 implementations (beta5+). So we just do the
- DES encryption the long way, and keep the last block
- as the MAC */
-
- /* XXX not converted to new api since it's inside an #if 0 */
-
- /* initialize the the cksum and allocate the contents buffer */
- cksum.checksum_type = CKSUMTYPE_DESCBC;
- cksum.length = krb5_checksum_size(context, CKSUMTYPE_DESCBC);
- if ((cksum.contents = (krb5_octet *) xmalloc(cksum.length)) == NULL)
- return(ENOMEM);
-
- /* XXX not converted to new api since it's inside an #if 0 */
- if (code = krb5_calculate_checksum(context, cksum.checksum_type,
- md5cksum.contents, 16,
- seq->contents,
- seq->length,
- &cksum)) {
- xfree(cksum.contents);
- xfree(md5cksum.contents);
- xfree(t);
- return(code);
- }
-
- memcpy(ptr+14, cksum.contents, 8);
-
- xfree(cksum.contents);
+ switch (qop_req & GSS_KRB5_CONF_C_QOP_MASK) {
+ case GSS_C_QOP_DEFAULT:
+ break;
+ default:
+ unknown_qop:
+ *minor_status = (OM_uint32) G_UNKNOWN_QOP;
+ return GSS_S_FAILURE;
+ case GSS_KRB5_CONF_C_QOP_DES:
+ if (ctx->sealalg != SEAL_ALG_DES) {
+ bad_qop:
+ *minor_status = (OM_uint32) G_BAD_QOP;
+ return GSS_S_FAILURE;
+ }
+ break;
+ case GSS_KRB5_CONF_C_QOP_DES3:
+ if (ctx->sealalg != SEAL_ALG_DES3)
+ goto bad_qop;
+ break;
+ }
+ switch (qop_req & GSS_KRB5_INTEG_C_QOP_MASK) {
+ case GSS_C_QOP_DEFAULT:
+ break;
+ default:
+ goto unknown_qop;
+ case GSS_KRB5_INTEG_C_QOP_MD5:
+ case GSS_KRB5_INTEG_C_QOP_DES_MD5:
+ case GSS_KRB5_INTEG_C_QOP_DES_MAC:
+ if (ctx->sealalg != SEAL_ALG_DES)
+ goto bad_qop;
+ break;
+ case GSS_KRB5_INTEG_C_QOP_HMAC_SHA1:
+ if (ctx->sealalg != SEAL_ALG_DES3KD)
+ goto bad_qop;
+ break;
+ }
#else
- if ((code = kg_encrypt(context, seq,
- (g_OID_equal(oid, gss_mech_krb5_old) ?
- seq->contents : NULL),
- md5cksum.contents, md5cksum.contents, 16))) {
- xfree(md5cksum.contents);
- xfree(t);
- return code;
- }
-
- cksum.length = cksum_size;
- cksum.contents = md5cksum.contents + 16 - cksum.length;
-
- memcpy(ptr+14, cksum.contents, cksum.length);
+ if (qop_req != 0) {
+ *minor_status = (OM_uint32) G_UNKNOWN_QOP;
+ return GSS_S_FAILURE;
+ }
#endif
- break;
- }
-
- xfree(md5cksum.contents);
-
- /* create the seq_num */
+ /* validate the context handle */
+ if (! kg_validate_ctx_id(context_handle)) {
+ *minor_status = (OM_uint32) G_VALIDATE_FAILED;
+ return(GSS_S_NO_CONTEXT);
+ }
- if ((code = kg_make_seq_num(context, seq, direction?0:0xff, *seqnum,
- ptr+14, ptr+6))) {
- xfree(t);
- return(code);
- }
+ ctx = (krb5_gss_ctx_id_rec *) context_handle;
- /* that's it. return the token */
+ if (! ctx->established) {
+ *minor_status = KG_CTX_INCOMPLETE;
+ return(GSS_S_NO_CONTEXT);
+ }
- (*seqnum)++;
+ if ((code = krb5_timeofday(context, &now))) {
+ *minor_status = code;
+ return(GSS_S_FAILURE);
+ }
- token->length = tlen;
- token->value = (void *) t;
+ code = make_seal_token_v1(context, ctx->enc, ctx->seq,
+ &ctx->seq_send, ctx->initiate,
+ input_message_buffer, output_message_buffer,
+ ctx->signalg, ctx->cksum_size, ctx->sealalg,
+ conf_req_flag, toktype, ctx->big_endian,
+ ctx->mech_used);
- return(0);
-}
+ if (code) {
+ *minor_status = code;
+ return(GSS_S_FAILURE);
+ }
-/* if signonly is true, ignore conf_req, conf_state,
- and do not encode the ENC_TYPE, MSG_LENGTH, or MSG_TEXT fields */
+ if (conf_state)
+ *conf_state = conf_req_flag;
-OM_uint32
-kg_seal(context, minor_status, context_handle, conf_req_flag, qop_req,
- input_message_buffer, conf_state, output_message_buffer, toktype)
- krb5_context context;
- OM_uint32 *minor_status;
- gss_ctx_id_t context_handle;
- int conf_req_flag;
- int qop_req;
- gss_buffer_t input_message_buffer;
- int *conf_state;
- gss_buffer_t output_message_buffer;
- int toktype;
-{
- krb5_gss_ctx_id_rec *ctx;
- krb5_error_code code;
- krb5_timestamp now;
-
- output_message_buffer->length = 0;
- output_message_buffer->value = NULL;
-
- /* only default qop is allowed */
- if (qop_req != GSS_C_QOP_DEFAULT) {
- *minor_status = (OM_uint32) G_UNKNOWN_QOP;
- return(GSS_S_FAILURE);
- }
-
- /* validate the context handle */
- if (! kg_validate_ctx_id(context_handle)) {
- *minor_status = (OM_uint32) G_VALIDATE_FAILED;
- return(GSS_S_NO_CONTEXT);
- }
-
- ctx = (krb5_gss_ctx_id_rec *) context_handle;
-
- if (! ctx->established) {
- *minor_status = KG_CTX_INCOMPLETE;
- return(GSS_S_NO_CONTEXT);
- }
-
- if ((code = krb5_timeofday(context, &now))) {
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
- if (ctx->gsskrb5_version == 2000) {
- if (toktype == KG_TOK_WRAP_MSG) {
- if (conf_req_flag)
- toktype = KG2_TOK_WRAP_PRIV;
- else
- toktype = KG2_TOK_WRAP_INTEG;
- } else {
- toktype = KG2_TOK_MIC;
- }
-
- if (conf_req_flag) {
- code = make_priv_token_v2(context, ctx->subkey, &ctx->seq_send,
- ctx->initiate, input_message_buffer,
- output_message_buffer, ctx->mech_used);
- } else {
- code = make_integ_token_v2(context, ctx->subkey, ctx->ctypes[0],
- &ctx->seq_send, ctx->initiate,
- input_message_buffer,
- output_message_buffer, toktype,
- ctx->mech_used);
- }
- } else {
- code = make_seal_token_v1(context, ctx->enc, ctx->seq,
- &ctx->seq_send, ctx->initiate,
- input_message_buffer, output_message_buffer,
- ctx->signalg, ctx->cksum_size, ctx->sealalg,
- conf_req_flag, toktype, ctx->big_endian,
- ctx->mech_used);
- }
-
- if (code) {
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
- if (conf_state)
- *conf_state = conf_req_flag;
-
- *minor_status = 0;
- return((ctx->endtime < now)?GSS_S_CONTEXT_EXPIRED:GSS_S_COMPLETE);
+ *minor_status = 0;
+ return((ctx->endtime < now)?GSS_S_CONTEXT_EXPIRED:GSS_S_COMPLETE);
}
diff --git a/src/lib/gssapi/krb5/k5unseal.c b/src/lib/gssapi/krb5/k5unseal.c
index da5966f23..bc35e7021 100644
--- a/src/lib/gssapi/krb5/k5unseal.c
+++ b/src/lib/gssapi/krb5/k5unseal.c
@@ -1,6 +1,6 @@
/*
* Copyright 1993 by OpenVision Technologies, Inc.
- *
+ *
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appears in all copies and
@@ -10,7 +10,7 @@
* without specific, written prior permission. OpenVision makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
- *
+ *
* OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
@@ -22,14 +22,14 @@
/*
* 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
@@ -40,7 +40,7 @@
* 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.
@@ -51,838 +51,438 @@
#include <memory.h>
#endif
-/*
- * $Id$
- */
+/* message_buffer is an input if SIGN, output if SEAL, and ignored if DEL_CTX
+ conf_state is only valid if SEAL. */
-static OM_uint32
-kg2_verify_mic(context, minor_status, ctx, ptr, bodysize,
- text, qop_state)
- krb5_context context;
- OM_uint32 *minor_status;
- krb5_gss_ctx_id_rec *ctx;
- unsigned char *ptr;
- int bodysize;
- gss_buffer_t text;
- gss_qop_t *qop_state;
+OM_uint32
+kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
+ conf_state, qop_state, toktype)
+ krb5_context context;
+ OM_uint32 *minor_status;
+ krb5_gss_ctx_id_rec *ctx;
+ unsigned char *ptr;
+ int bodysize;
+ gss_buffer_t message_buffer;
+ int *conf_state;
+ int *qop_state;
+ int toktype;
{
- size_t cksumlen;
krb5_error_code code;
- krb5_data plain;
- krb5_cksumtype tctype;
- krb5_ui_4 tseqnum;
- int tdirection;
+ int tmsglen;
+ int conflen = 0;
+ int signalg;
+ int sealalg;
+ gss_buffer_desc token;
krb5_checksum cksum;
- krb5_boolean ckvalid;
+ krb5_checksum md5cksum;
+ krb5_data plaind;
+ char *data_ptr;
krb5_timestamp now;
+ unsigned char *plain;
+ int cksum_len = 0;
+ int plainlen;
+ int direction;
+ krb5_int32 seqnum;
OM_uint32 retval;
+ size_t sumlen;
- plain.data = 0;
- cksum.contents = 0;
-
- /* verify the header */
-
- if (bodysize < 11) {
- free(plain.data);
- *minor_status = G_TOK_TRUNC;
- return(GSS_S_DEFECTIVE_TOKEN);
+ if (toktype == KG_TOK_SEAL_MSG) {
+ message_buffer->length = 0;
+ message_buffer->value = NULL;
}
- /* allocate the checksum buffer */
-
- plain.length = 7+text->length;
+ /* get the sign and seal algorithms */
- if ((plain.data = (char *) malloc(plain.length)) == NULL) {
- *minor_status = ENOMEM;
- return(GSS_S_FAILURE);
- }
+ signalg = ptr[0] + (ptr[1]<<8);
+ sealalg = ptr[2] + (ptr[3]<<8);
- /* suck out the body parts from the token */
+ /* Sanity checks */
- tctype = (krb5_cksumtype) ((ptr[0]<<24) | (ptr[1]<<16) |
- (ptr[2]<<8) | ptr[3]);
- ptr += 4;
-
- memcpy(plain.data, ptr, 5);
- tseqnum = ((ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]);
- ptr += 4;
- tdirection = ptr[0];
- ptr += 1;
-
- cksum.length = (ptr[0]<<8) | ptr[1];
- ptr += 2;
- bodysize -= 11;
-
- if (cksum.length != bodysize) {
- free(plain.data);
- *minor_status = G_TOK_TRUNC;
- return(GSS_S_DEFECTIVE_TOKEN);
+ if ((ptr[4] != 0xff) || (ptr[5] != 0xff)) {
+ *minor_status = 0;
+ return GSS_S_DEFECTIVE_TOKEN;
}
- cksum.contents = ptr;
- cksum.checksum_type = tctype;
+ if ((toktype != KG_TOK_SEAL_MSG) &&
+ (sealalg != 0xffff)) {
+ *minor_status = 0;
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
- /* finish assembling the checksum buffer and compute the checksum */
+ /* in the current spec, there is only one valid seal algorithm per
+ key type, so a simple comparison is ok */
- plain.data[5] = (text->length >> 8) & 0xff;
- plain.data[6] = text->length & 0xff;
+ if ((toktype == KG_TOK_SEAL_MSG) &&
+ !((sealalg == 0xffff) ||
+ (sealalg == ctx->sealalg))) {
+ *minor_status = 0;
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
- memcpy(plain.data+7, text->value, text->length);
+ /* there are several mappings of seal algorithms to sign algorithms,
+ but few enough that we can try them all. */
- if (code = krb5_c_verify_checksum(context, ctx->subkey,
- KRB5_KEYUSAGE_GSS_TOK_MIC,
- &plain, &cksum, &ckvalid)) {
- free(plain.data);
- *minor_status = code;
- return(GSS_S_FAILURE);
+ if ((ctx->sealalg == SEAL_ALG_NONE && signalg > 1) ||
+ (ctx->sealalg == SEAL_ALG_1 && signalg != SGN_ALG_3) ||
+ (ctx->sealalg == SEAL_ALG_DES3KD &&
+ signalg != SGN_ALG_HMAC_SHA1_DES3_KD)) {
+ *minor_status = 0;
+ return GSS_S_DEFECTIVE_TOKEN;
}
- if (!ckvalid) {
- free(plain.data);
+ switch (signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ case SGN_ALG_MD2_5:
+ cksum_len = 8;
+ break;
+ case SGN_ALG_3:
+ cksum_len = 16;
+ break;
+ case SGN_ALG_HMAC_SHA1_DES3_KD:
+ cksum_len = 20;
+ break;
+ default:
*minor_status = 0;
- return(GSS_S_BAD_SIG);
+ return GSS_S_DEFECTIVE_TOKEN;
}
- /* check context expiry */
+ if (toktype == KG_TOK_SEAL_MSG)
+ tmsglen = bodysize-(14+cksum_len);
- if ((code = krb5_timeofday(context, &now))) {
- free(plain.data);
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
+ /* get the token parameters */
- if (now > ctx->endtime) {
- free(plain.data);
- *minor_status = 0;
- return(GSS_S_CONTEXT_EXPIRED);
- }
+ /* decode the message, if SEAL */
- /* do sequencing checks */
+ if (toktype == KG_TOK_SEAL_MSG) {
+ if (sealalg != 0xffff) {
+ if ((plain = (unsigned char *) xmalloc(tmsglen)) == NULL) {
+ *minor_status = ENOMEM;
+ return(GSS_S_FAILURE);
+ }
- if ((ctx->initiate && tdirection != 0xff) ||
- (!ctx->initiate && tdirection != 0)) {
- free(plain.data);
- *minor_status = G_BAD_DIRECTION;
- return(GSS_S_BAD_SIG);
- }
+ if ((code = kg_decrypt(context, ctx->enc, KG_USAGE_SEAL, NULL,
+ ptr+14+cksum_len, plain, tmsglen))) {
+ xfree(plain);
+ *minor_status = code;
+ return(GSS_S_FAILURE);
+ }
+ } else {
+ plain = ptr+14+cksum_len;
+ }
- retval = g_order_check(&(ctx->seqstate), tseqnum);
+ plainlen = tmsglen;
- free(plain.data);
+ if ((sealalg == 0xffff) && ctx->big_endian) {
+ token.length = tmsglen;
+ } else {
+ conflen = kg_confounder_size(context, ctx->enc);
+ token.length = tmsglen - conflen - plain[tmsglen-1];
+ }
- if (retval) {
- *minor_status = 0;
- return(retval);
- }
+ if (token.length) {
+ if ((token.value = (void *) xmalloc(token.length)) == NULL) {
+ if (sealalg != 0xffff)
+ xfree(plain);
+ *minor_status = ENOMEM;
+ return(GSS_S_FAILURE);
+ }
+ memcpy(token.value, plain+conflen, token.length);
+ }
+ } else if (toktype == KG_TOK_SIGN_MSG) {
+ token = *message_buffer;
+ plain = token.value;
+ plainlen = token.length;
+ } else {
+ token.length = 0;
+ token.value = NULL;
+ plain = token.value;
+ plainlen = token.length;
+ }
- if (qop_state)
- *qop_state = GSS_C_QOP_DEFAULT;
+ /* compute the checksum of the message */
+
+ /* initialize the the cksum */
+ switch (signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ case SGN_ALG_MD2_5:
+ case SGN_ALG_HMAC_MD5:
+ case SGN_ALG_DES_MAC:
+ case SGN_ALG_3:
+ md5cksum.checksum_type = CKSUMTYPE_RSA_MD5;
+ break;
+ case SGN_ALG_HMAC_SHA1_DES3_KD:
+ md5cksum.checksum_type = CKSUMTYPE_HMAC_SHA1_DES3;
+ break;
+ default:
+ abort ();
+ }
- *minor_status = 0;
- return(GSS_S_COMPLETE);
-}
+ if (code = krb5_c_checksum_length(context, md5cksum.checksum_type, &sumlen))
+ return(code);
+ md5cksum.length = sumlen;
-static OM_uint32
-kg2_unwrap_integ(context, minor_status, ctx, ptr, bodysize, output, qop_state)
- krb5_context context;
- OM_uint32 *minor_status;
- krb5_gss_ctx_id_rec *ctx;
- unsigned char *ptr;
- int bodysize;
- gss_buffer_t output;
- gss_qop_t *qop_state;
-{
- krb5_error_code code;
- OM_uint32 retval;
- krb5_ui_4 tseqnum;
- int tdirection;
- int tmsglen;
- unsigned char *tmsg;
- krb5_data plain;
- krb5_checksum tcksum;
- krb5_boolean ckvalid;
- krb5_timestamp now;
+ switch (signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ case SGN_ALG_3:
+ /* compute the checksum of the message */
- output->length = 0;
- output->value = NULL;
+ /* 8 = bytes of token body to be checksummed according to spec */
- /* read the body parts out of the message */
+ if (! (data_ptr = (void *)
+ xmalloc(8 + (ctx->big_endian ? token.length : plainlen)))) {
+ if (sealalg != 0xffff)
+ xfree(plain);
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = ENOMEM;
+ return(GSS_S_FAILURE);
+ }
- if (bodysize < 11) {
- *minor_status = G_TOK_TRUNC;
- return(GSS_S_DEFECTIVE_TOKEN);
- }
+ (void) memcpy(data_ptr, ptr-2, 8);
+
+ if (ctx->big_endian)
+ (void) memcpy(data_ptr+8, token.value, token.length);
+ else
+ (void) memcpy(data_ptr+8, plain, plainlen);
- tcksum.checksum_type = (krb5_cksumtype) ((ptr[0]<<24) | (ptr[1]<<16) |
- (ptr[2]<<8) | ptr[3]);
- ptr += 4;
+ plaind.length = 8 + (ctx->big_endian ? token.length : plainlen);
+ plaind.data = data_ptr;
+ code = krb5_c_make_checksum(context, md5cksum.checksum_type,
+ ctx->seq, KG_USAGE_SIGN,
+ &plaind, &md5cksum);
+ xfree(data_ptr);
- plain.data = ptr;
+ if (code) {
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = code;
+ return(GSS_S_FAILURE);
+ }
- tseqnum = ((ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]);
- ptr += 4;
- tdirection = ptr[0];
- ptr += 1;
+ if ((code = kg_encrypt(context, ctx->seq, KG_USAGE_SEAL,
+ (g_OID_equal(ctx->mech_used, gss_mech_krb5_old) ?
+ ctx->seq->contents : NULL),
+ md5cksum.contents, md5cksum.contents, 16))) {
+ xfree(md5cksum.contents);
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = code;
+ return GSS_S_FAILURE;
+ }
- tmsglen = (ptr[0]<<8) | ptr[1];
- ptr += 2;
- bodysize -= 11;
+ if (signalg == 0)
+ cksum.length = 8;
+ else
+ cksum.length = 16;
+ cksum.contents = md5cksum.contents + 16 - cksum.length;
- if (bodysize < tmsglen) {
- *minor_status = G_TOK_TRUNC;
- return(GSS_S_DEFECTIVE_TOKEN);
- }
+ code = memcmp(cksum.contents, ptr+14, cksum.length);
+ break;
- tmsg = ptr;
- ptr += tmsglen;
- bodysize -= tmsglen;
+ case SGN_ALG_MD2_5:
+ if (!ctx->seed_init &&
+ (code = kg_make_seed(context, ctx->subkey, ctx->seed))) {
+ xfree(md5cksum.contents);
+ if (sealalg != 0xffff)
+ xfree(plain);
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = code;
+ return GSS_S_FAILURE;
+ }
- plain.length = ((char*)ptr) - ((char *)plain.data);
+ if (! (data_ptr = (void *)
+ xmalloc(sizeof(ctx->seed) + 8 +
+ (ctx->big_endian ? token.length : plainlen)))) {
+ xfree(md5cksum.contents);
+ if (sealalg == 0)
+ xfree(plain);
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = ENOMEM;
+ return(GSS_S_FAILURE);
+ }
+ (void) memcpy(data_ptr, ptr-2, 8);
+ (void) memcpy(data_ptr+8, ctx->seed, sizeof(ctx->seed));
+ if (ctx->big_endian)
+ (void) memcpy(data_ptr+8+sizeof(ctx->seed),
+ token.value, token.length);
+ else
+ (void) memcpy(data_ptr+8+sizeof(ctx->seed),
+ plain, plainlen);
+ plaind.length = 8 + sizeof(ctx->seed) +
+ (ctx->big_endian ? token.length : plainlen);
+ plaind.data = data_ptr;
+ xfree(md5cksum.contents);
+ code = krb5_c_make_checksum(context, md5cksum.checksum_type,
+ ctx->seq, KG_USAGE_SIGN,
+ &plaind, &md5cksum);
+ xfree(data_ptr);
+
+ if (code) {
+ if (sealalg == 0)
+ xfree(plain);
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = code;
+ return(GSS_S_FAILURE);
+ }
- tcksum.length = (ptr[0]<<8) | ptr[1];
- ptr += 2;
- bodysize -= 2;
+ code = memcmp(md5cksum.contents, ptr+14, 8);
+ /* Falls through to defective-token?? */
- if (bodysize != tcksum.length) {
- *minor_status = G_TOK_TRUNC;
+ default:
+ *minor_status = 0;
return(GSS_S_DEFECTIVE_TOKEN);
- }
- tcksum.contents = ptr;
+ case SGN_ALG_HMAC_SHA1_DES3_KD:
+ /* compute the checksum of the message */
- /* verify the MIC */
+ /* 8 = bytes of token body to be checksummed according to spec */
- if (code = krb5_c_verify_checksum(context, ctx->subkey,
- KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG,
- &plain, &tcksum, &ckvalid)) {
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
- if (!ckvalid) {
- *minor_status = 0;
- return(GSS_S_BAD_SIG);
- }
+ if (! (data_ptr = (void *)
+ xmalloc(8 + (ctx->big_endian ? token.length : plainlen)))) {
+ if (sealalg != 0xffff)
+ xfree(plain);
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = ENOMEM;
+ return(GSS_S_FAILURE);
+ }
- /* check context expiry */
-
- if ((code = krb5_timeofday(context, &now))) {
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
- if (now > ctx->endtime) {
- *minor_status = 0;
- return(GSS_S_CONTEXT_EXPIRED);
- }
-
- /* do sequencing checks */
-
- if ((ctx->initiate && tdirection != 0xff) ||
- (!ctx->initiate && tdirection != 0)) {
- *minor_status = G_BAD_DIRECTION;
- return(GSS_S_BAD_SIG);
- }
-
- if (retval = g_order_check(&(ctx->seqstate), tseqnum)) {
- *minor_status = 0;
- return(retval);
- }
-
- if (tmsglen) {
- if ((output->value = (void *) malloc(tmsglen)) == NULL) {
- *minor_status = ENOMEM;
- return(GSS_S_FAILURE);
- }
- memcpy(output->value, tmsg, tmsglen);
- output->length = tmsglen;
- }
-
- if (qop_state)
- *qop_state = GSS_C_QOP_DEFAULT;
-
- *minor_status = 0;
- return(GSS_S_COMPLETE);
-}
+ (void) memcpy(data_ptr, ptr-2, 8);
-static OM_uint32
-kg2_unwrap_priv(context, minor_status, ctx, ptr, bodysize, output, qop_state)
- krb5_context context;
- OM_uint32 *minor_status;
- krb5_gss_ctx_id_rec *ctx;
- unsigned char *ptr;
- int bodysize;
- gss_buffer_t output;
- gss_qop_t *qop_state;
-{
- krb5_error_code code;
- OM_uint32 retval;
- krb5_enc_data cipher;
- krb5_data plain;
- krb5_ui_4 tseqnum;
- int tdirection;
- int tmsglen;
- unsigned char *tmsg;
- krb5_timestamp now;
+ if (ctx->big_endian)
+ (void) memcpy(data_ptr+8, token.value, token.length);
+ else
+ (void) memcpy(data_ptr+8, plain, plainlen);
- output->length = 0;
- output->value = NULL;
+ plaind.length = 8 + (ctx->big_endian ? token.length : plainlen);
+ plaind.data = data_ptr;
+ code = krb5_c_make_checksum(context, md5cksum.checksum_type,
+ ctx->seq, KG_USAGE_SIGN,
+ &plaind, &md5cksum);
+ xfree(data_ptr);
- /* read the body parts out of the message */
+ if (code) {
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = code;
+ return(GSS_S_FAILURE);
+ }
- if (bodysize < 2) {
- *minor_status = G_TOK_TRUNC;
- return(GSS_S_DEFECTIVE_TOKEN);
+ code = memcmp(md5cksum.contents, ptr+14, md5cksum.length);
+ break;
}
- cipher.ciphertext.length = (ptr[0]<<8) | ptr[1];
- ptr += 2;
- bodysize -= 2;
-
- if (bodysize != cipher.ciphertext.length) {
- *minor_status = G_TOK_TRUNC;
- return(GSS_S_DEFECTIVE_TOKEN);
- }
+ xfree(md5cksum.contents);
+ if (sealalg != 0xffff)
+ xfree(plain);
- cipher.ciphertext.data = ptr;
- cipher.enctype = ENCTYPE_UNKNOWN;
+ /* compare the computed checksum against the transmitted checksum */
- plain.length = cipher.ciphertext.length;
- if ((plain.data = (char *) malloc(plain.length)) == NULL) {
+ if (code) {
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
*minor_status = 0;
- return(GSS_S_FAILURE);
- }
-
- /* decrypt (and implicitly verify) the encrypted data */
-
- if (code = krb5_c_decrypt(context, ctx->subkey,
- KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV,
- 0, &cipher, &plain)) {
- free(plain.data);
- *minor_status = code;
- return(GSS_S_FAILURE);
+ return(GSS_S_BAD_SIG);
}
- /* parse out the encrypted fields */
- ptr = plain.data;
- bodysize = plain.length;
+ /* it got through unscathed. Make sure the context is unexpired */
- if (bodysize < 7) {
- free(plain.data);
- *minor_status = G_TOK_TRUNC;
- return(GSS_S_DEFECTIVE_TOKEN);
- }
-
- tseqnum = ((ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]);
- ptr += 4;
- tdirection = ptr[0];
- ptr += 1;
+ if (toktype == KG_TOK_SEAL_MSG)
+ *message_buffer = token;
- tmsglen = (ptr[0]<<8) | ptr[1];
- ptr += 2;
- bodysize -= 7;
+ if (conf_state)
+ *conf_state = (sealalg != 0xffff);
- /* check context expiry */
+ if (qop_state)
+ *qop_state = GSS_C_QOP_DEFAULT;
if ((code = krb5_timeofday(context, &now))) {
- free(plain.data);
*minor_status = code;
return(GSS_S_FAILURE);
}
if (now > ctx->endtime) {
- free(plain.data);
*minor_status = 0;
return(GSS_S_CONTEXT_EXPIRED);
}
/* do sequencing checks */
- if ((ctx->initiate && tdirection != 0xff) ||
- (!ctx->initiate && tdirection != 0)) {
- free(plain.data);
- *minor_status = G_BAD_DIRECTION;
+ if ((code = kg_get_seq_num(context, ctx->seq, ptr+14, ptr+6, &direction,
+ &seqnum))) {
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = code;
return(GSS_S_BAD_SIG);
}
- if (retval = g_order_check(&(ctx->seqstate), tseqnum)) {
- free(plain.data);
- *minor_status = 0;
- return(retval);
- }
-
- /* now copy out the data. can't do a strict equality check here,
- since the output could be padded. */
-
- if (bodysize < tmsglen) {
- free(plain.data);
- *minor_status = G_TOK_TRUNC;
- return(GSS_S_DEFECTIVE_TOKEN);
- }
-
- tmsg = ptr;
-
- if (tmsglen) {
- if ((output->value = (void *) malloc(tmsglen)) == NULL) {
- free(plain.data);
- *minor_status = ENOMEM;
- return(GSS_S_FAILURE);
- }
- memcpy(output->value, tmsg, tmsglen);
- output->length = tmsglen;
+ if ((ctx->initiate && direction != 0xff) ||
+ (!ctx->initiate && direction != 0)) {
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = G_BAD_DIRECTION;
+ return(GSS_S_BAD_SIG);
}
- if (qop_state)
- *qop_state = GSS_C_QOP_DEFAULT;
+ retval = g_order_check(&(ctx->seqstate), seqnum);
- free(plain.data);
+ /* success or ordering violation */
*minor_status = 0;
- return(GSS_S_COMPLETE);
+ return(retval);
}
/* message_buffer is an input if SIGN, output if SEAL, and ignored if DEL_CTX
conf_state is only valid if SEAL. */
OM_uint32
-kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
- conf_state, qop_state, toktype)
- krb5_context context;
- OM_uint32 *minor_status;
- krb5_gss_ctx_id_rec *ctx;
- unsigned char *ptr;
- int bodysize;
- gss_buffer_t message_buffer;
- int *conf_state;
- int *qop_state;
- int toktype;
+kg_unseal(context, minor_status, context_handle, input_token_buffer,
+ message_buffer, conf_state, qop_state, toktype)
+ krb5_context context;
+ OM_uint32 *minor_status;
+ gss_ctx_id_t context_handle;
+ gss_buffer_t input_token_buffer;
+ gss_buffer_t message_buffer;
+ int *conf_state;
+ int *qop_state;
+ int toktype;
{
- krb5_error_code code;
- int tmsglen;
- int conflen = 0;
- int signalg;
- int sealalg;
- gss_buffer_desc token;
- krb5_checksum cksum;
- krb5_checksum desmac;
- krb5_checksum md5cksum;
- krb5_data plaind;
- char *data_ptr;
- krb5_timestamp now;
- unsigned char *plain;
- int cksum_len = 0;
- int plainlen;
- int err;
- int direction;
- krb5_int32 seqnum;
- OM_uint32 retval;
- size_t sumlen;
-
- if (toktype == KG_TOK_SEAL_MSG) {
- message_buffer->length = 0;
- message_buffer->value = NULL;
- }
-
- /* get the sign and seal algorithms */
-
- signalg = ptr[0] + (ptr[1]<<8);
- sealalg = ptr[2] + (ptr[3]<<8);
-
- /* Sanity checks */
-
- if ((ptr[4] != 0xff) || (ptr[5] != 0xff)) {
- *minor_status = 0;
- return GSS_S_DEFECTIVE_TOKEN;
- }
-
- if ((toktype != KG_TOK_SEAL_MSG) &&
- (sealalg != 0xffff)) {
- *minor_status = 0;
- return GSS_S_DEFECTIVE_TOKEN;
- }
-
- /* in the current spec, there is only one valid seal algorithm per
- key type, so a simple comparison is ok */
-
- if ((toktype == KG_TOK_SEAL_MSG) &&
- !((sealalg == 0xffff) ||
- (sealalg == ctx->sealalg))) {
- *minor_status = 0;
- return GSS_S_DEFECTIVE_TOKEN;
- }
-
- /* there are several mappings of seal algorithms to sign algorithms,
- but few enough that we can try them all. */
-
- if (((ctx->sealalg == 0) &&
- (signalg > 1)) ||
- ((ctx->sealalg == 1) &&
- (signalg != 3))) {
- *minor_status = 0;
- return GSS_S_DEFECTIVE_TOKEN;
- }
-
- switch (signalg) {
- case 0:
- case 1:
- cksum_len = 8;
- break;
- case 3:
- cksum_len = 16;
- break;
- }
-
- if (toktype == KG_TOK_SEAL_MSG)
- tmsglen = bodysize-(14+cksum_len);
-
- /* get the token parameters */
-
- /* decode the message, if SEAL */
-
- if (toktype == KG_TOK_SEAL_MSG) {
- if (sealalg != 0xffff) {
- if ((plain = (unsigned char *) xmalloc(tmsglen)) == NULL) {
- *minor_status = ENOMEM;
- return(GSS_S_FAILURE);
- }
+ krb5_gss_ctx_id_rec *ctx;
+ unsigned char *ptr;
+ int bodysize;
+ int err;
+
+ /* validate the context handle */
+ if (! kg_validate_ctx_id(context_handle)) {
+ *minor_status = (OM_uint32) G_VALIDATE_FAILED;
+ return(GSS_S_NO_CONTEXT);
+ }
- if ((code = kg_decrypt(context, ctx->enc, NULL,
- ptr+14+cksum_len, plain, tmsglen))) {
- xfree(plain);
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
- } else {
- plain = ptr+14+cksum_len;
- }
-
- plainlen = tmsglen;
-
- if ((sealalg == 0xffff) && ctx->big_endian) {
- token.length = tmsglen;
- } else {
- conflen = kg_confounder_size(context, ctx->enc);
- token.length = tmsglen - conflen - plain[tmsglen-1];
- }
-
- if (token.length) {
- if ((token.value = (void *) xmalloc(token.length)) == NULL) {
- if (sealalg != 0xffff)
- xfree(plain);
- *minor_status = ENOMEM;
- return(GSS_S_FAILURE);
- }
- memcpy(token.value, plain+conflen, token.length);
- }
- } else if (toktype == KG_TOK_SIGN_MSG) {
- token = *message_buffer;
- plain = token.value;
- plainlen = token.length;
- } else {
- token.length = 0;
- token.value = NULL;
- plain = token.value;
- plainlen = token.length;
- }
-
- /* compute the checksum of the message */
-
- /* initialize the the cksum */
- if (code = krb5_c_checksum_length(context, CKSUMTYPE_RSA_MD5, &sumlen))
- return(code);
-
- md5cksum.checksum_type = CKSUMTYPE_RSA_MD5;
- md5cksum.length = sumlen;
-
- switch (signalg) {
- case 0:
- case 3:
- /* compute the checksum of the message */
-
- /* 8 = bytes of token body to be checksummed according to spec */
-
- if (! (data_ptr = (void *)
- xmalloc(8 + (ctx->big_endian ? token.length : plainlen)))) {
- if (sealalg != 0xffff)
- xfree(plain);
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = ENOMEM;
- return(GSS_S_FAILURE);
- }
-
- (void) memcpy(data_ptr, ptr-2, 8);
-
- if (ctx->big_endian)
- (void) memcpy(data_ptr+8, token.value, token.length);
- else
- (void) memcpy(data_ptr+8, plain, plainlen);
-
- plaind.length = 8 + (ctx->big_endian ? token.length : plainlen);
- plaind.data = data_ptr;
- code = krb5_c_make_checksum(context, md5cksum.checksum_type, 0, 0,
- &plaind, &md5cksum);
- xfree(data_ptr);
-
- if (code) {
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
-#if 0
- /* XXX this depends on the key being a single-des key, but that's
- all that kerberos supports right now */
-
- /* initialize the the cksum and allocate the contents buffer */
- cksum.checksum_type = CKSUMTYPE_DESCBC;
- cksum.length = krb5_checksum_size(context, CKSUMTYPE_DESCBC);
- if ((cksum.contents = (krb5_octet *) xmalloc(cksum.length)) == NULL) {
- xfree(md5cksum.contents);
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = ENOMEM;
- return(GSS_S_FAILURE);
- }
-
- /* XXX not converted to new api since it's inside an #if 0 */
- if (code = krb5_calculate_checksum(context, cksum.checksum_type,
- md5cksum.contents, 16,
- ctx->seq.key->contents,
- ctx->seq.key->length,
- &cksum)) {
- xfree(cksum.contents);
- xfree(md5cksum.contents);
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
- code = memcmp(cksum.contents, ptr+14, cksum.length);
-
- xfree(cksum.contents);
-#else
- if ((code = kg_encrypt(context, ctx->seq,
- (g_OID_equal(ctx->mech_used, gss_mech_krb5_old) ?
- ctx->seq->contents : NULL),
- md5cksum.contents, md5cksum.contents, 16))) {
- xfree(md5cksum.contents);
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = code;
- return GSS_S_FAILURE;
- }
+ ctx = (krb5_gss_ctx_id_rec *) context_handle;
- if (signalg == 0)
- cksum.length = 8;
- else
- cksum.length = 16;
- cksum.contents = md5cksum.contents + 16 - cksum.length;
+ if (! ctx->established) {
+ *minor_status = KG_CTX_INCOMPLETE;
+ return(GSS_S_NO_CONTEXT);
+ }
- code = memcmp(cksum.contents, ptr+14, cksum.length);
-#endif
- break;
-
- case 1:
- if (!ctx->seed_init &&
- (code = kg_make_seed(context, ctx->subkey, ctx->seed))) {
- xfree(md5cksum.contents);
- if (sealalg != 0xffff)
- xfree(plain);
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = code;
- return GSS_S_FAILURE;
- }
-
- if (! (data_ptr = (void *)
- xmalloc(sizeof(ctx->seed) + 8 +
- (ctx->big_endian ? token.length : plainlen)))) {
- xfree(md5cksum.contents);
- if (sealalg == 0)
- xfree(plain);
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = ENOMEM;
- return(GSS_S_FAILURE);
- }
- (void) memcpy(data_ptr, ptr-2, 8);
- (void) memcpy(data_ptr+8, ctx->seed, sizeof(ctx->seed));
- if (ctx->big_endian)
- (void) memcpy(data_ptr+8+sizeof(ctx->seed),
- token.value, token.length);
- else
- (void) memcpy(data_ptr+8+sizeof(ctx->seed),
- plain, plainlen);
- plaind.length = 8 + sizeof(ctx->seed) +
- (ctx->big_endian ? token.length : plainlen);
- plaind.data = data_ptr;
- xfree(md5cksum.contents);
- code = krb5_c_make_checksum(context, md5cksum.checksum_type, 0, 0,
- &plaind, &md5cksum);
- xfree(data_ptr);
-
- if (code) {
- if (sealalg == 0)
- xfree(plain);
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
- code = memcmp(md5cksum.contents, ptr+14, 8);
-
- default:
- *minor_status = 0;
- return(GSS_S_DEFECTIVE_TOKEN);
- }
-
- xfree(md5cksum.contents);
- if (sealalg != 0xffff)
- xfree(plain);
-
- /* compare the computed checksum against the transmitted checksum */
-
- if (code) {
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = 0;
- return(GSS_S_BAD_SIG);
- }
-
-
- /* it got through unscathed. Make sure the context is unexpired */
-
- if (toktype == KG_TOK_SEAL_MSG)
- *message_buffer = token;
-
- if (conf_state)
- *conf_state = (sealalg != 0xffff);
-
- if (qop_state)
- *qop_state = GSS_C_QOP_DEFAULT;
-
- if ((code = krb5_timeofday(context, &now))) {
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
- if (now > ctx->endtime) {
- *minor_status = 0;
- return(GSS_S_CONTEXT_EXPIRED);
- }
-
- /* do sequencing checks */
-
- if ((code = kg_get_seq_num(context, ctx->seq, ptr+14, ptr+6, &direction,
- &seqnum))) {
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = code;
- return(GSS_S_BAD_SIG);
- }
-
- if ((ctx->initiate && direction != 0xff) ||
- (!ctx->initiate && direction != 0)) {
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = G_BAD_DIRECTION;
- return(GSS_S_BAD_SIG);
- }
-
- retval = g_order_check(&(ctx->seqstate), seqnum);
-
- /* success or ordering violation */
-
- *minor_status = 0;
- return(retval);
-}
+ /* parse the token, leave the data in message_buffer, setting conf_state */
-/* message_buffer is an input if SIGN, output if SEAL, and ignored if DEL_CTX
- conf_state is only valid if SEAL. */
+ /* verify the header */
-OM_uint32
-kg_unseal(context, minor_status, context_handle, input_token_buffer,
- message_buffer, conf_state, qop_state, toktype)
- krb5_context context;
- OM_uint32 *minor_status;
- gss_ctx_id_t context_handle;
- gss_buffer_t input_token_buffer;
- gss_buffer_t message_buffer;
- int *conf_state;
- int *qop_state;
- int toktype;
-{
- krb5_gss_ctx_id_rec *ctx;
- unsigned char *ptr;
- int bodysize;
- int err;
- OM_uint32 retval;
-
- /* validate the context handle */
- if (! kg_validate_ctx_id(context_handle)) {
- *minor_status = (OM_uint32) G_VALIDATE_FAILED;
- return(GSS_S_NO_CONTEXT);
- }
-
- ctx = (krb5_gss_ctx_id_rec *) context_handle;
-
- if (! ctx->established) {
- *minor_status = KG_CTX_INCOMPLETE;
- return(GSS_S_NO_CONTEXT);
- }
-
- /* parse the token, leave the data in message_buffer, setting conf_state */
-
- /* verify the header */
-
- ptr = (unsigned char *) input_token_buffer->value;
-
- if (ctx->gsskrb5_version == 2000) {
- if (!(err = g_verify_token_header((gss_OID) ctx->mech_used,
- &bodysize, &ptr, KG2_TOK_MIC,
- input_token_buffer->length))) {
- return(kg2_verify_mic(context, minor_status, ctx, ptr, bodysize,
- message_buffer, qop_state));
- } else if (!(err = g_verify_token_header((gss_OID) ctx->mech_used,
- &bodysize, &ptr,
- KG2_TOK_WRAP_INTEG,
- input_token_buffer->length))) {
- if (GSS_ERROR(retval = kg2_unwrap_integ(context, minor_status,
- ctx, ptr, bodysize,
- message_buffer, qop_state)))
- return(retval);
-
- if (conf_state)
- *conf_state = 0;
- return(GSS_S_COMPLETE);
- } else if (!(err = g_verify_token_header((gss_OID) ctx->mech_used,
- &bodysize, &ptr,
- KG2_TOK_WRAP_PRIV,
- input_token_buffer->length))) {
- if (GSS_ERROR(retval = kg2_unwrap_priv(context, minor_status,
- ctx, ptr, bodysize,
- message_buffer, qop_state)))
- return(retval);
-
- if (conf_state)
- *conf_state = 1;
- return(GSS_S_COMPLETE);
- }
- } else {
- if (!(err = g_verify_token_header((gss_OID) ctx->mech_used,
- &bodysize, &ptr, toktype,
- input_token_buffer->length))) {
- return(kg_unseal_v1(context, minor_status, ctx, ptr, bodysize,
- message_buffer, conf_state, qop_state,
- toktype));
- }
- }
-
- *minor_status = err;
- return(GSS_S_DEFECTIVE_TOKEN);
+ ptr = (unsigned char *) input_token_buffer->value;
+
+ if (!(err = g_verify_token_header((gss_OID) ctx->mech_used,
+ &bodysize, &ptr, toktype,
+ input_token_buffer->length))) {
+ return(kg_unseal_v1(context, minor_status, ctx, ptr, bodysize,
+ message_buffer, conf_state, qop_state,
+ toktype));
+ }
+
+ *minor_status = err;
+ return(GSS_S_DEFECTIVE_TOKEN);
}
diff --git a/src/lib/gssapi/krb5/ser_sctx.c b/src/lib/gssapi/krb5/ser_sctx.c
index 2a6231ee7..1989a7d55 100644
--- a/src/lib/gssapi/krb5/ser_sctx.c
+++ b/src/lib/gssapi/krb5/ser_sctx.c
@@ -233,7 +233,6 @@ kg_ctx_size(kcontext, arg, sizep)
* krb5_int32 for seq_recv.
* krb5_int32 for established.
* krb5_int32 for big_endian.
- * krb5_int32 for gsskrb5_version.
* krb5_int32 for nctypes.
* krb5_int32 for trailer.
*/
@@ -349,8 +348,6 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain)
&bp, &remain);
(void) krb5_ser_pack_int32((krb5_int32) ctx->big_endian,
&bp, &remain);
- (void) krb5_ser_pack_int32((krb5_int32) ctx->gsskrb5_version,
- &bp, &remain);
(void) krb5_ser_pack_int32((krb5_int32) ctx->nctypes,
&bp, &remain);
@@ -477,8 +474,6 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain)
(void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
ctx->big_endian = (int) ibuf;
(void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
- ctx->gsskrb5_version = (int) ibuf;
- (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
ctx->nctypes = (int) ibuf;
if ((kret = kg_oid_internalize(kcontext, &ctx->mech_used, &bp,
diff --git a/src/lib/gssapi/krb5/util_cksum.c b/src/lib/gssapi/krb5/util_cksum.c
index 61fbc666d..77feade73 100644
--- a/src/lib/gssapi/krb5/util_cksum.c
+++ b/src/lib/gssapi/krb5/util_cksum.c
@@ -20,15 +20,12 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/*
- * $Id$
- */
-
#include "gssapiP_krb5.h"
#ifdef HAVE_MEMORY_H
#include <memory.h>
#endif
+/* Checksumming the channel bindings always uses plain MD5. */
krb5_error_code
kg_checksum_channel_bindings(context, cb, cksum, bigend)
krb5_context context;
diff --git a/src/lib/gssapi/krb5/util_crypt.c b/src/lib/gssapi/krb5/util_crypt.c
index 8792e5fed..3e40236c8 100644
--- a/src/lib/gssapi/krb5/util_crypt.c
+++ b/src/lib/gssapi/krb5/util_crypt.c
@@ -52,12 +52,6 @@
#include <memory.h>
#endif
-/*
- * $Id$
- */
-
-static unsigned char zeros[8] = {0,0,0,0,0,0,0,0};
-
int
kg_confounder_size(context, key)
krb5_context context;
@@ -107,9 +101,10 @@ kg_encrypt_size(context, key, n)
}
krb5_error_code
-kg_encrypt(context, key, iv, in, out, length)
+kg_encrypt(context, key, usage, iv, in, out, length)
krb5_context context;
krb5_keyblock *key;
+ int usage;
krb5_pointer iv;
krb5_pointer in;
krb5_pointer out;
@@ -125,7 +120,10 @@ kg_encrypt(context, key, iv, in, out, length)
return(code);
ivd.length = blocksize;
- ivd.data = iv;
+ ivd.data = malloc(ivd.length);
+ if (ivd.data == NULL)
+ return ENOMEM;
+ memcpy(ivd.data, iv, ivd.length);
pivd = &ivd;
} else {
pivd = NULL;
@@ -137,18 +135,19 @@ kg_encrypt(context, key, iv, in, out, length)
outputd.ciphertext.length = length;
outputd.ciphertext.data = out;
- return(krb5_c_encrypt(context, key,
- /* XXX this routine is only used for the old
- bare-des stuff which doesn't use the
- key usage */ 0, pivd, &inputd, &outputd));
+ code = krb5_c_encrypt(context, key, usage, pivd, &inputd, &outputd);
+ if (pivd != NULL)
+ krb5_free_data_contents(context, pivd);
+ return code;
}
/* length is the length of the cleartext. */
krb5_error_code
-kg_decrypt(context, key, iv, in, out, length)
+kg_decrypt(context, key, usage, iv, in, out, length)
krb5_context context;
krb5_keyblock *key;
+ int usage;
krb5_pointer iv;
krb5_pointer in;
krb5_pointer out;
@@ -164,7 +163,10 @@ kg_decrypt(context, key, iv, in, out, length)
return(code);
ivd.length = blocksize;
- ivd.data = iv;
+ ivd.data = malloc(ivd.length);
+ if (ivd.data == NULL)
+ return ENOMEM;
+ memcpy(ivd.data, iv, ivd.length);
pivd = &ivd;
} else {
pivd = NULL;
@@ -177,8 +179,8 @@ kg_decrypt(context, key, iv, in, out, length)
outputd.length = length;
outputd.data = out;
- return(krb5_c_decrypt(context, key,
- /* XXX this routine is only used for the old
- bare-des stuff which doesn't use the
- key usage */ 0, pivd, &inputd, &outputd));
+ code = krb5_c_decrypt(context, key, usage, pivd, &inputd, &outputd);
+ if (pivd != NULL)
+ krb5_free_data_contents(context, pivd);
+ return code;
}
diff --git a/src/lib/gssapi/krb5/util_seed.c b/src/lib/gssapi/krb5/util_seed.c
index 24ae7f3f4..3f6eb4713 100644
--- a/src/lib/gssapi/krb5/util_seed.c
+++ b/src/lib/gssapi/krb5/util_seed.c
@@ -25,10 +25,6 @@
#include <memory.h>
#endif
-/*
- * $Id$
- */
-
static unsigned char zeros[16] = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0};
krb5_error_code
@@ -49,7 +45,7 @@ kg_make_seed(context, key, seed)
for (i=0; i<tmpkey->length; i++)
tmpkey->contents[i] = key->contents[key->length - 1 - i];
- code = kg_encrypt(context, tmpkey, NULL, zeros, seed, 16);
+ code = kg_encrypt(context, tmpkey, KG_USAGE_SEAL, NULL, zeros, seed, 16);
krb5_free_keyblock(context, tmpkey);
diff --git a/src/lib/gssapi/krb5/util_seqnum.c b/src/lib/gssapi/krb5/util_seqnum.c
index e14b2f3fe..b8f2b389a 100644
--- a/src/lib/gssapi/krb5/util_seqnum.c
+++ b/src/lib/gssapi/krb5/util_seqnum.c
@@ -47,7 +47,7 @@ kg_make_seq_num(context, key, direction, seqnum, cksum, buf)
plain[6] = direction;
plain[7] = direction;
- return(kg_encrypt(context, key, cksum, plain, buf, 8));
+ return(kg_encrypt(context, key, KG_USAGE_SEQ, cksum, plain, buf, 8));
}
krb5_error_code kg_get_seq_num(context, key, cksum, buf, direction, seqnum)
@@ -61,7 +61,7 @@ krb5_error_code kg_get_seq_num(context, key, cksum, buf, direction, seqnum)
krb5_error_code code;
unsigned char plain[8];
- if (code = kg_decrypt(context, key, cksum, buf, plain, 8))
+ if (code = kg_decrypt(context, key, KG_USAGE_SEQ, cksum, buf, plain, 8))
return(code);
if ((plain[4] != plain[5]) ||
diff --git a/src/lib/gssapi/krb5/wrap_size_limit.c b/src/lib/gssapi/krb5/wrap_size_limit.c
index d71a3f864..a3c05df4f 100644
--- a/src/lib/gssapi/krb5/wrap_size_limit.c
+++ b/src/lib/gssapi/krb5/wrap_size_limit.c
@@ -1,4 +1,28 @@
/*
+ * Copyright 2000 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. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * 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.
+ *
+ */
+/*
* Copyright 1993 by OpenVision Technologies, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
@@ -48,10 +72,6 @@
#include "gssapiP_krb5.h"
-/*
- * $Id$
- */
-
/* V2 interface */
OM_uint32
krb5_gss_wrap_size_limit(minor_status, context_handle, conf_req_flag,
@@ -66,6 +86,9 @@ krb5_gss_wrap_size_limit(minor_status, context_handle, conf_req_flag,
krb5_context context;
krb5_gss_ctx_id_rec *ctx;
krb5_error_code code;
+ OM_uint32 data_size, conflen;
+ OM_uint32 ohlen;
+ int overhead;
if (GSS_ERROR(kg_get_context(minor_status, &context)))
return(GSS_S_FAILURE);
@@ -88,91 +111,23 @@ krb5_gss_wrap_size_limit(minor_status, context_handle, conf_req_flag,
return(GSS_S_NO_CONTEXT);
}
- if (ctx->gsskrb5_version == 2000) {
- if (conf_req_flag) {
- /* this is pretty gross. take the max output, and call
- krb5_c_encrypt_length to see how much overhead is added
- on. subtract that much, and see if it fits in the
- requested space. If not, start subtracting 1 until it
- does. This doesn't necessarily give us the optimal
- packing, but I think that's ok (I could start adding 1
- until I went over, but that seems like it's not worth
- the effort). This is probably O(blocksize), but that's
- never going to be large. */
-
- OM_uint32 headerlen, plainlen;
- size_t enclen;
-
- headerlen = g_token_size((gss_OID) ctx->mech_used, 2);
- plainlen = req_output_size - headerlen;
-
- if (code = krb5_c_encrypt_length(context, ctx->enc->enctype,
- plainlen, &enclen)) {
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
- plainlen -= plainlen - (enclen - plainlen);
-
- if (code = krb5_c_encrypt_length(context, ctx->enc->enctype,
- plainlen, &enclen)) {
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
- while (headerlen + enclen > req_output_size) {
- plainlen--;
-
- if (code = krb5_c_encrypt_length(context, ctx->enc->enctype,
- plainlen, &enclen)) {
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
- }
-
- /* subtract off the fixed size inside the encrypted part */
-
- plainlen -= 7;
-
- *max_input_size = plainlen;
- } else {
- size_t cksumlen;
- OM_uint32 headerlen;
-
- if (code = krb5_c_checksum_length(context, ctx->ctypes[0],
- &cksumlen)) {
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
- headerlen = g_token_size((gss_OID) ctx->mech_used, 13 + cksumlen);
-
- *max_input_size = req_output_size - headerlen;
- }
- } else {
- OM_uint32 data_size, conflen;
- OM_uint32 ohlen;
- int overhead;
-
- /* Calculate the token size and subtract that from the output size */
- overhead = 7 + ctx->mech_used->length;
- data_size = req_output_size;
- conflen = kg_confounder_size(context, ctx->enc);
- data_size = (conflen + data_size + 8) & (~(OM_uint32)7);
- ohlen = g_token_size((gss_OID) ctx->mech_used,
- (unsigned int) (data_size + ctx->cksum_size + 14))
- - req_output_size;
-
- if (ohlen+overhead < req_output_size)
- /*
- * Cannot have trailer length that will cause us to pad over
- * our length
- */
- *max_input_size = (req_output_size - ohlen - overhead)
- & (~(OM_uint32)7);
- else
- *max_input_size = 0;
- }
+ /* Calculate the token size and subtract that from the output size */
+ overhead = 7 + ctx->mech_used->length;
+ data_size = req_output_size;
+ conflen = kg_confounder_size(context, ctx->enc);
+ data_size = (conflen + data_size + 8) & (~(OM_uint32)7);
+ ohlen = g_token_size((gss_OID) ctx->mech_used,
+ (unsigned int) (data_size + ctx->cksum_size + 14))
+ - req_output_size;
+
+ if (ohlen+overhead < req_output_size)
+ /*
+ * Cannot have trailer length that will cause us to pad over our
+ * length.
+ */
+ *max_input_size = (req_output_size - ohlen - overhead) & (~(OM_uint32)7);
+ else
+ *max_input_size = 0;
*minor_status = 0;
return(GSS_S_COMPLETE);
diff --git a/src/lib/kadm5/ChangeLog b/src/lib/kadm5/ChangeLog
index b8dedb276..59ea4aecd 100644
--- a/src/lib/kadm5/ChangeLog
+++ b/src/lib/kadm5/ChangeLog
@@ -1,3 +1,23 @@
+2000-06-23 Ken Raeburn <raeburn@mit.edu>
+
+ * alt_prof.c (kadm5_get_config_params): Include des3 in supported
+ enctypes by default.
+
+ * ovsec_glue.c (ovsec_kadm_chpass_principal_util): Use 1024 for
+ hard-coded length, to match existing callers.
+
+2000-06-23 Nalin Dahyabhai <nalin@redhat.com>
+
+ * admin.h: Add a length parameter to kadm5_chpass_principal_util().
+ * admin_internal.h: Add a length parameter to
+ _kadm5_chpass_principal_util().
+ * chpass_util.c (_kadm5_chpass_principal_util): Add a length parameter,
+ and use it to avoid overflowing "msg_ret".
+ * ovsec_glue.c (ovsec_kadm_chpass_principal_util): Adjust for new
+ parameter in kadm5_chpass_principal_util().
+
+ * logger.c (klog_com_err_proc): Don't overflow buffer "outbuf".
+
2000-05-31 Wilfredo Sanchez <tritan@mit.edu>
* configure.in, chpass_util.c, server_internal.h: Check for
diff --git a/src/lib/kadm5/admin.h b/src/lib/kadm5/admin.h
index 159c7fb58..2164e1e16 100644
--- a/src/lib/kadm5/admin.h
+++ b/src/lib/kadm5/admin.h
@@ -411,7 +411,8 @@ kadm5_ret_t kadm5_chpass_principal_util(void *server_handle,
krb5_principal princ,
char *new_pw,
char **ret_pw,
- char *msg_ret);
+ char *msg_ret,
+ int msg_len);
kadm5_ret_t kadm5_free_principal_ent(void *server_handle,
kadm5_principal_ent_t
diff --git a/src/lib/kadm5/admin_internal.h b/src/lib/kadm5/admin_internal.h
index d2d1533bc..97cb5e52e 100644
--- a/src/lib/kadm5/admin_internal.h
+++ b/src/lib/kadm5/admin_internal.h
@@ -62,7 +62,8 @@ kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle,
krb5_principal princ,
char *new_pw,
char **ret_pw,
- char *msg_ret);
+ char *msg_ret,
+ int msg_len);
/* this is needed by the alt_prof code I stole. The functions
maybe shouldn't be named krb5_*, but they are. */
diff --git a/src/lib/kadm5/alt_prof.c b/src/lib/kadm5/alt_prof.c
index 5582df090..4d1e76920 100644
--- a/src/lib/kadm5/alt_prof.c
+++ b/src/lib/kadm5/alt_prof.c
@@ -644,8 +644,8 @@ krb5_error_code kadm5_get_config_params(context, kdcprofile, kdcenv,
if (aprofile)
krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue);
if (svalue == NULL)
- svalue = strdup("des-cbc-crc:normal");
-
+ svalue = strdup("des3-hmac-sha1:normal des-cbc-crc:normal");
+
params.keysalts = NULL;
params.num_keysalts = 0;
krb5_string_to_keysalts(svalue,
diff --git a/src/lib/kadm5/chpass_util.c b/src/lib/kadm5/chpass_util.c
index 367d8f201..a991ca00a 100644
--- a/src/lib/kadm5/chpass_util.c
+++ b/src/lib/kadm5/chpass_util.c
@@ -1,9 +1,5 @@
/*
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved.
- *
- * $Header$
- *
- *
*/
@@ -63,7 +59,8 @@ kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle,
krb5_principal princ,
char *new_pw,
char **ret_pw,
- char *msg_ret)
+ char *msg_ret,
+ int msg_len)
{
int code, code2, pwsize;
static char buffer[255];
@@ -96,12 +93,18 @@ kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle,
memset(buffer, 0, sizeof(buffer));
#endif
if (code == KRB5_LIBOS_BADPWDMATCH) {
- strcpy(msg_ret, string_text(CHPASS_UTIL_NEW_PASSWORD_MISMATCH));
+ strncpy(msg_ret, string_text(CHPASS_UTIL_NEW_PASSWORD_MISMATCH),
+ msg_len - 1);
+ msg_ret[msg_len - 1] = '\0';
return(code);
} else {
- sprintf(msg_ret, "%s %s\n%s\n", error_message(code),
- string_text(CHPASS_UTIL_WHILE_READING_PASSWORD),
- string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED));
+ strncpy(msg_ret, error_message(code), msg_len - 1);
+ strncat(msg_ret, " ", msg_len - 1);
+ strncat(msg_ret, string_text(CHPASS_UTIL_WHILE_READING_PASSWORD),
+ msg_len - 1);
+ strncat(msg_ret, string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED),
+ msg_len - 1);
+ msg_ret[msg_len - 1] = '\0';
return(code);
}
}
@@ -109,7 +112,8 @@ kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle,
#ifdef ZEROPASSWD
memset(buffer, 0, sizeof(buffer));
#endif
- strcpy(msg_ret, string_text(CHPASS_UTIL_NO_PASSWORD_READ));
+ strncpy(msg_ret, string_text(CHPASS_UTIL_NO_PASSWORD_READ), msg_len - 1);
+ msg_ret[msg_len - 1] = '\0';
return(KRB5_LIBOS_CANTREADPWD); /* could do better */
}
}
@@ -125,7 +129,8 @@ kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle,
#endif
if (code == KADM5_OK) {
- strcpy(msg_ret, string_text(CHPASS_UTIL_PASSWORD_CHANGED));
+ strncpy(msg_ret, string_text(CHPASS_UTIL_PASSWORD_CHANGED), msg_len - 1);
+ msg_ret[msg_len - 1] = '\0';
return(0);
}
@@ -143,12 +148,15 @@ kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle,
/* Ok, we have a password quality error. Return a good message */
if (code == KADM5_PASS_REUSE) {
- strcpy(msg_ret, string_text(CHPASS_UTIL_PASSWORD_REUSE));
+ strncpy(msg_ret, string_text(CHPASS_UTIL_PASSWORD_REUSE), msg_len - 1);
+ msg_ret[msg_len - 1] = '\0';
return(code);
}
if (code == KADM5_PASS_Q_DICT) {
- strcpy(msg_ret, string_text(CHPASS_UTIL_PASSWORD_IN_DICTIONARY));
+ strncpy(msg_ret, string_text(CHPASS_UTIL_PASSWORD_IN_DICTIONARY),
+ msg_len - 1);
+ msg_ret[msg_len - 1] = '\0';
return(code);
}
@@ -157,18 +165,32 @@ kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle,
code2 = kadm5_get_principal (lhandle, princ, &princ_ent,
KADM5_PRINCIPAL_NORMAL_MASK);
if (code2 != 0) {
- sprintf(msg_ret, "%s %s\n%s %s\n\n%s\n ", error_message(code2),
- string_text(CHPASS_UTIL_GET_PRINC_INFO),
- error_message(code),
- string_text(CHPASS_UTIL_WHILE_TRYING_TO_CHANGE),
- string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED));
+ strncpy(msg_ret, error_message(code2), msg_len - 1);
+ strncat(msg_ret, " ", msg_len - 1 - strlen(msg_ret));
+ strncat(msg_ret, string_text(CHPASS_UTIL_GET_PRINC_INFO), msg_len - 1 - strlen(msg_ret));
+ strncat(msg_ret, "\n", msg_len - 1 - strlen(msg_ret));
+ strncat(msg_ret, error_message(code), msg_len - 1 - strlen(msg_ret));
+ strncat(msg_ret, " ", msg_len - 1 - strlen(msg_ret));
+ strncat(msg_ret, string_text(CHPASS_UTIL_WHILE_TRYING_TO_CHANGE),
+ msg_len - 1 - strlen(msg_ret));
+ strncat(msg_ret, "\n\n", msg_len - 1 - strlen(msg_ret));
+ strncat(msg_ret, string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED),
+ msg_len - 1 - strlen(msg_ret));
+ strncat(msg_ret, "\n", msg_len - 1 - strlen(msg_ret));
+ msg_ret[msg_len - 1] = '\0';
return(code);
}
if ((princ_ent.aux_attributes & KADM5_POLICY) == 0) {
- sprintf(msg_ret, "%s %s\n\n%s", error_message(code),
- string_text(CHPASS_UTIL_NO_POLICY_YET_Q_ERROR),
- string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED));
+ strncpy(msg_ret, error_message(code), msg_len - 1 - strlen(msg_ret));
+ strncat(msg_ret, " ", msg_len - 1 - strlen(msg_ret));
+ strncpy(msg_ret, string_text(CHPASS_UTIL_NO_POLICY_YET_Q_ERROR),
+ msg_len - 1 - strlen(msg_ret));
+ strncat(msg_ret, "\n\n", msg_len - 1 - strlen(msg_ret));
+ strncpy(msg_ret, string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED),
+ msg_len - 1 - strlen(msg_ret));
+ msg_ret[msg_len - 1] = '\0';
+
(void) kadm5_free_principal_ent(lhandle, &princ_ent);
return(code);
}
diff --git a/src/lib/kadm5/clnt/ChangeLog b/src/lib/kadm5/clnt/ChangeLog
index 167294257..0e47993d5 100644
--- a/src/lib/kadm5/clnt/ChangeLog
+++ b/src/lib/kadm5/clnt/ChangeLog
@@ -1,3 +1,17 @@
+2000-06-23 Nalin Dahyabhai <nalin@redhat.com>
+
+ * clnt_chpass_util.c (kadm5_chpass_principal_util): Adjust for new
+ length parameter in both kadm5_chpass_principal_util() and in
+ _kadm5_chpass_principal_util().
+
+ * client_init.c (_kadm5_init_any): Fix determination of client
+ name length for overflow checking.
+
+2000-06-23 Ken Raeburn <raeburn@mit.edu>
+
+ * client_init.c (enctypes): Add des3 and des-md5 to the list of
+ permitted enctypes.
+
2000-05-31 Wilfredo Sanchez <tritan@mit.edu>
* client_init.c, client_principal.c, client_rpc.c: Check for
diff --git a/src/lib/kadm5/clnt/client_init.c b/src/lib/kadm5/clnt/client_init.c
index 53d6e15af..56fbfcd72 100644
--- a/src/lib/kadm5/clnt/client_init.c
+++ b/src/lib/kadm5/clnt/client_init.c
@@ -1,7 +1,5 @@
/*
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
- *
- * $Header$
*/
/*
@@ -30,10 +28,6 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#if !defined(lint) && !defined(__CODECENTER__)
-static char *rcsid = "$Header$";
-#endif
-
#include <stdio.h>
#include <netdb.h>
#ifdef HAVE_MEMORY_H
@@ -136,6 +130,8 @@ static int preauth_search_list[] = {
};
static krb5_enctype enctypes[] = {
+ ENCTYPE_DES3_CBC_SHA1,
+ ENCTYPE_DES_CBC_MD5,
ENCTYPE_DES_CBC_CRC,
0,
};
@@ -284,9 +280,15 @@ static kadm5_ret_t _kadm5_init_any(char *client_name,
goto error;
if (realm) {
+ if(strlen(service_name) + strlen(realm) + 1 >= sizeof(full_service_name)) {
+ goto error;
+ }
sprintf(full_service_name, "%s@%s", service_name, realm);
} else {
/* krb5_princ_realm(creds.client) is not null terminated */
+ if(strlen(service_name) + krb5_princ_realm(handle->context, creds.client)->length + 1 >= sizeof(full_service_name)) {
+ goto error;
+ }
strcpy(full_service_name, service_name);
strcat(full_service_name, "@");
strncat(full_service_name, krb5_princ_realm(handle->context,
diff --git a/src/lib/kadm5/clnt/clnt_chpass_util.c b/src/lib/kadm5/clnt/clnt_chpass_util.c
index d6c7f0bfb..ae9ced082 100644
--- a/src/lib/kadm5/clnt/clnt_chpass_util.c
+++ b/src/lib/kadm5/clnt/clnt_chpass_util.c
@@ -5,11 +5,12 @@ kadm5_ret_t kadm5_chpass_principal_util(void *server_handle,
krb5_principal princ,
char *new_pw,
char **ret_pw,
- char *msg_ret)
+ char *msg_ret,
+ int msg_len)
{
kadm5_server_handle_t handle = server_handle;
CHECK_HANDLE(server_handle);
return _kadm5_chpass_principal_util(handle, handle->lhandle, princ,
- new_pw, ret_pw, msg_ret);
+ new_pw, ret_pw, msg_ret, msg_len);
}
diff --git a/src/lib/kadm5/logger.c b/src/lib/kadm5/logger.c
index 4f2ad2005..bf6bbfd00 100644
--- a/src/lib/kadm5/logger.c
+++ b/src/lib/kadm5/logger.c
@@ -199,8 +199,9 @@ klog_com_err_proc(whoami, code, format, ap)
/* If reporting an error message, separate it. */
if (code) {
- strcat(outbuf, error_message(code));
- strcat(outbuf, " - ");
+ outbuf[sizeof(outbuf) - 1] = '\0';
+ strncat(outbuf, error_message(code), sizeof(outbuf) - 1 - strlen(outbuf));
+ strncat(outbuf, " - ", sizeof(outbuf) - 1 - strlen(outbuf));
}
cp = &outbuf[strlen(outbuf)];
diff --git a/src/lib/kadm5/ovsec_glue.c b/src/lib/kadm5/ovsec_glue.c
index 6118282df..ce818934f 100644
--- a/src/lib/kadm5/ovsec_glue.c
+++ b/src/lib/kadm5/ovsec_glue.c
@@ -102,8 +102,10 @@ ovsec_kadm_ret_t ovsec_kadm_chpass_principal_util(void *server_handle,
char **ret_pw,
char *msg_ret)
{
- return kadm5_chpass_principal_util(server_handle, princ, new_pw,
- ret_pw, msg_ret);
+ /* Oh crap. Can't change the API without bumping the API version... */
+ memset(msg_ret, '\0', 1024);
+ return kadm5_chpass_principal_util(server_handle, princ, new_pw,
+ ret_pw, msg_ret, 1024);
}
ovsec_kadm_ret_t ovsec_kadm_randkey_principal(void *server_handle,
diff --git a/src/lib/kadm5/srv/ChangeLog b/src/lib/kadm5/srv/ChangeLog
index 1864a733f..d39760428 100644
--- a/src/lib/kadm5/srv/ChangeLog
+++ b/src/lib/kadm5/srv/ChangeLog
@@ -1,3 +1,11 @@
+2000-06-23 Nalin Dahyabhai <nalin@redhat.com>
+
+ * adb_openclose.c (osa_adb_create_db): Open lock files using O_EXCL
+ and fdopen() the descriptor instead of using fopen().
+ * svr_chpass_util.c (kadm5_chpass_principal_util): Adjust for new
+ length parameter in both kadm5_chpass_principal_util() and in
+ _kadm5_chpass_principal_util().
+
2000-05-31 Wilfredo Sanchez <tritan@mit.edu>
* adb_free.c, adb_xdr.c, server_dict.c: Check for existance
diff --git a/src/lib/kadm5/srv/adb_openclose.c b/src/lib/kadm5/srv/adb_openclose.c
index e776192c2..2a9bba8f6 100644
--- a/src/lib/kadm5/srv/adb_openclose.c
+++ b/src/lib/kadm5/srv/adb_openclose.c
@@ -24,7 +24,7 @@ struct _locklist {
osa_adb_ret_t osa_adb_create_db(char *filename, char *lockfilename,
int magic)
{
- FILE *lf;
+ int lf;
DB *db;
HASHINFO info;
@@ -41,10 +41,10 @@ osa_adb_ret_t osa_adb_create_db(char *filename, char *lockfilename,
return errno;
/* only create the lock file if we successfully created the db */
- lf = fopen(lockfilename, "w+");
- if (lf == NULL)
+ lf = THREEPARAMOPEN(lockfilename, O_RDWR | O_CREAT | O_EXCL, 0600);
+ if (lf == -1)
return errno;
- (void) fclose(lf);
+ (void) close(lf);
return OSA_ADB_OK;
}
@@ -333,7 +333,7 @@ osa_adb_ret_t osa_adb_get_lock(osa_adb_db_t db, int mode)
osa_adb_ret_t osa_adb_release_lock(osa_adb_db_t db)
{
- int ret;
+ int ret, fd;
if (!db->lock->lockcnt) /* lock already unlocked */
return OSA_ADB_NOTLOCKED;
@@ -341,8 +341,9 @@ osa_adb_ret_t osa_adb_release_lock(osa_adb_db_t db)
if (--db->lock->lockcnt == 0) {
if (db->lock->lockmode == OSA_ADB_PERMANENT) {
/* now we need to create the file since it does not exist */
- if ((db->lock->lockfile = fopen(db->lock->filename,
- "w+")) == NULL)
+ fd = THREEPARAMOPEN(db->lock->filename,O_RDWR | O_CREAT | O_EXCL,
+ 0600);
+ if ((db->lock->lockfile = fdopen(fd, "w+")) == NULL)
return OSA_ADB_NOLOCKFILE;
} else if (ret = krb5_lock_file(db->lock->context,
fileno(db->lock->lockfile),
diff --git a/src/lib/kadm5/srv/svr_chpass_util.c b/src/lib/kadm5/srv/svr_chpass_util.c
index df2bf4c47..4c4c6bbe6 100644
--- a/src/lib/kadm5/srv/svr_chpass_util.c
+++ b/src/lib/kadm5/srv/svr_chpass_util.c
@@ -5,11 +5,12 @@ kadm5_ret_t kadm5_chpass_principal_util(void *server_handle,
krb5_principal princ,
char *new_pw,
char **ret_pw,
- char *msg_ret)
+ char *msg_ret,
+ int msg_len)
{
kadm5_server_handle_t handle = server_handle;
CHECK_HANDLE(server_handle);
return _kadm5_chpass_principal_util(handle, handle->lhandle, princ,
- new_pw, ret_pw, msg_ret);
+ new_pw, ret_pw, msg_ret, msg_len);
}
diff --git a/src/lib/kadm5/unit-test/ChangeLog b/src/lib/kadm5/unit-test/ChangeLog
index 15c4bad59..f195831d6 100644
--- a/src/lib/kadm5/unit-test/ChangeLog
+++ b/src/lib/kadm5/unit-test/ChangeLog
@@ -1,3 +1,10 @@
+2000-05-09 Ken Raeburn <raeburn@mit.edu>
+
+ * api.2/chpass-principal-v2.exp (test200): Expect an additional
+ key to be reported, since des3 has been added to the list.
+ * api.2/get-principal-v2.exp (test101_102): Likewise.
+ * api.2/randkey-principal-v2.exp (test100): Likewise.
+
2000-02-08 Tom Yu <tlyu@mit.edu>
* api.1/lock.exp: Since a "wait" directive to the command list of
diff --git a/src/lib/kadm5/unit-test/api.2/chpass-principal-v2.exp b/src/lib/kadm5/unit-test/api.2/chpass-principal-v2.exp
index 40a78c985..ef45510a2 100644
--- a/src/lib/kadm5/unit-test/api.2/chpass-principal-v2.exp
+++ b/src/lib/kadm5/unit-test/api.2/chpass-principal-v2.exp
@@ -53,10 +53,10 @@ proc test200 {} {
}
# XXX Perhaps I should actually check the key type returned.
- if {$num_keys == 2} {
+ if {$num_keys == 3} {
pass "$test"
} else {
- fail "$test: $num_keys keys, should be 2"
+ fail "$test: $num_keys keys, should be 3"
}
if { ! [cmd {kadm5_destroy $server_handle}]} {
error "$test: unexpected failure in destroy"
diff --git a/src/lib/kadm5/unit-test/api.2/get-principal-v2.exp b/src/lib/kadm5/unit-test/api.2/get-principal-v2.exp
index 0e3e1b5a8..d2eb85a90 100644
--- a/src/lib/kadm5/unit-test/api.2/get-principal-v2.exp
+++ b/src/lib/kadm5/unit-test/api.2/get-principal-v2.exp
@@ -143,8 +143,8 @@ proc test101_102 {rpc} {
}
set failed 0
- if {$num_keys != 2} {
- fail "$test: num_keys $num_keys should be 2"
+ if {$num_keys != 3} {
+ fail "$test: num_keys $num_keys should be 3"
set failed 1
}
for {set i 0} {$i < $num_keys} {incr i} {
diff --git a/src/lib/kadm5/unit-test/api.2/randkey-principal-v2.exp b/src/lib/kadm5/unit-test/api.2/randkey-principal-v2.exp
index 5c8fdc5e5..d9cc9718a 100644
--- a/src/lib/kadm5/unit-test/api.2/randkey-principal-v2.exp
+++ b/src/lib/kadm5/unit-test/api.2/randkey-principal-v2.exp
@@ -47,10 +47,10 @@ proc test100 {} {
}
# XXX Perhaps I should actually check the key type returned.
- if {$num_keys == 1} {
+ if {$num_keys == 2} {
pass "$test"
} else {
- fail "$test: $num_keys keys, should be 1"
+ fail "$test: $num_keys keys, should be 2"
}
if { ! [cmd {kadm5_destroy $server_handle}]} {
error "$test: unexpected failure in destroy"
diff --git a/src/lib/kdb/ChangeLog b/src/lib/kdb/ChangeLog
index 7d7368cc6..b72e64248 100644
--- a/src/lib/kdb/ChangeLog
+++ b/src/lib/kdb/ChangeLog
@@ -1,3 +1,26 @@
+2000-05-11 Nalin Dahyabhai <nalin@redhat.com>
+
+ * t_kdb.c (gen_principal): Don't overflow "pnamebuf" if bad data was
+ passed in.
+
+2000-05-03 Nalin Dahyabhai <nalin@redhat.com>
+
+ * setup_mkey.c (krb5_db_setup_mkey_name): Use REALM_SEP_STRING
+ when computing size of buffer that is to include it.
+
+ * fetch_mkey.c (krb5_db_fetch_mkey): Make sure "defkeyfile" is
+ null terminated after construction.
+ * store_mkey.c (krb5_db_store_mkey): Likewise.
+
+2000-04-27 Ken Raeburn <raeburn@mit.edu>
+ Ezra Peisach <epeisach@mit.edu>
+
+ * t_kdb.c (gen_principal): Force argument to isalnum to be in
+ range 0..255.
+ (do_testing): Cast pid_t to long before passing to fprintf, and
+ use %ld format. Fix argument lists to find_principal and
+ delete_principal.
+
2000-03-16 Ezra Peisach <epeisach@mit.edu>
* kdb_xdr.c (krb5_dbe_lookup_mod_princ_data): Get rid of
diff --git a/src/lib/kdb/fetch_mkey.c b/src/lib/kdb/fetch_mkey.c
index 2ff5c2942..7ae26bbb9 100644
--- a/src/lib/kdb/fetch_mkey.c
+++ b/src/lib/kdb/fetch_mkey.c
@@ -133,7 +133,7 @@ krb5_db_fetch_mkey(context, mname, etype, fromkeyboard, twice, keyfile,
(void) strncat(defkeyfile, realm->data,
min(sizeof(defkeyfile)-sizeof(DEFAULT_KEYFILE_STUB)-1,
realm->length));
- (void) strcat(defkeyfile, "");
+ defkeyfile[sizeof(defkeyfile) - 1] = '\0';
#ifdef ANSI_STDIO
if (!(kf = fopen((keyfile) ? keyfile : defkeyfile, "rb")))
diff --git a/src/lib/kdb/setup_mkey.c b/src/lib/kdb/setup_mkey.c
index 0898a6311..1788ecdd8 100644
--- a/src/lib/kdb/setup_mkey.c
+++ b/src/lib/kdb/setup_mkey.c
@@ -56,7 +56,7 @@ krb5_db_setup_mkey_name(context, keyname, realm, fullname, principal)
keylen = strlen(keyname);
- fname = malloc(keylen+rlen+2);
+ fname = malloc(keylen+rlen+strlen(REALM_SEP_STRING)+1);
if (!fname)
return ENOMEM;
diff --git a/src/lib/kdb/store_mkey.c b/src/lib/kdb/store_mkey.c
index d18630ac0..47e0bc9c0 100644
--- a/src/lib/kdb/store_mkey.c
+++ b/src/lib/kdb/store_mkey.c
@@ -68,7 +68,7 @@ krb5_db_store_mkey(context, keyfile, mname, key)
(void) strncat(defkeyfile, realm->data,
min(sizeof(defkeyfile)-sizeof(DEFAULT_KEYFILE_STUB)-1,
realm->length));
- (void) strcat(defkeyfile, "");
+ defkeyfile[sizeof(defkeyfile) - 1] = '\0';
keyfile = defkeyfile;
}
diff --git a/src/lib/kdb/t_kdb.c b/src/lib/kdb/t_kdb.c
index 8358088d2..10e6163fb 100644
--- a/src/lib/kdb/t_kdb.c
+++ b/src/lib/kdb/t_kdb.c
@@ -363,15 +363,23 @@ gen_principal(kcontext, realm, do_rand, n, princp, namep)
complen = RANDOM(1,MAX_COMP_SIZE);
for (j=0; j<complen; j++) {
*cp = (char) RANDOM(0,256);
- while (!isalnum(*cp))
+ while (!isalnum(*cp & 0xff))
*cp = (char) RANDOM(0,256);
cp++;
+ if(cp + strlen(realm) >= pnamebuf + sizeof(pnamebuf))
+ break;
}
+ if(cp + strlen(realm) >= pnamebuf + sizeof(pnamebuf))
+ break;
*cp = '/';
cp++;
}
- cp[-1] = '@';
- strcpy(cp, realm);
+ if(cp + strlen(realm) < pnamebuf + sizeof(pnamebuf)) {
+ cp[-1] = '@';
+ strcpy(cp, realm);
+ } else {
+ strcpy(cp , "");
+ }
}
else {
instname = instnames[n % (sizeof(instnames)/sizeof(instnames[0]))];
@@ -894,45 +902,40 @@ do_testing(db, passes, verbose, timing, rcases, check, save_db, dontclean,
&stat_kb,
rseed))) {
fprintf(stderr,
- "%d: (%d,%d) Failed add of %s with %s\n",
- getpid(), i, j, playback_name(base+j),
+ "%ld: (%d,%d) Failed add of %s with %s\n",
+ (long) getpid(), i, j, playback_name(base+j),
error_message(kret));
break;
}
if (verbose > 4)
- fprintf(stderr, "*A[%d](%s)\n", getpid(),
+ fprintf(stderr, "*A[%ld](%s)\n", (long) getpid(),
playback_name(base+j));
}
for (j=0; (j<nper) && (!kret); j++) {
if ((kret = find_principal(ccontext,
playback_principal(base+j),
- &master_encblock,
- &stat_kb,
- rseed))) {
+ check))) {
fprintf(stderr,
- "%d: (%d,%d) Failed lookup of %s with %s\n",
- getpid(), i, j, playback_name(base+j),
+ "%ld: (%d,%d) Failed lookup of %s with %s\n",
+ (long) getpid(), i, j, playback_name(base+j),
error_message(kret));
break;
}
if (verbose > 4)
- fprintf(stderr, "-S[%d](%s)\n", getpid(),
+ fprintf(stderr, "-S[%ld](%s)\n", (long) getpid(),
playback_name(base+j));
}
for (j=0; (j<nper) && (!kret); j++) {
if ((kret = delete_principal(ccontext,
- playback_principal(base+j),
- &master_encblock,
- &stat_kb,
- rseed))) {
+ playback_principal(base+j)))) {
fprintf(stderr,
- "%d: (%d,%d) Failed delete of %s with %s\n",
- getpid(), i, j, playback_name(base+j),
+ "%ld: (%d,%d) Failed delete of %s with %s\n",
+ (long) getpid(), i, j, playback_name(base+j),
error_message(kret));
break;
}
if (verbose > 4)
- fprintf(stderr, "XD[%d](%s)\n", getpid(),
+ fprintf(stderr, "XD[%ld](%s)\n", (long) getpid(),
playback_name(base+j));
}
krb5_db_fini(ccontext);
@@ -949,13 +952,13 @@ do_testing(db, passes, verbose, timing, rcases, check, save_db, dontclean,
for (i=0; i<nprocs; i++) {
if (waitpid(children[i], &existat, 0) == children[i]) {
if (verbose)
- fprintf(stderr, "%d finished with %d\n", children[i],
- existat);
+ fprintf(stderr, "%ld finished with %d\n",
+ (long) children[i], existat);
if (existat)
kret = KRB5KRB_ERR_GENERIC;
}
else
- fprintf(stderr, "Wait for %d failed\n", children[i]);
+ fprintf(stderr, "Wait for %ld failed\n", (long) children[i]);
}
}
diff --git a/src/lib/krb4/ChangeLog b/src/lib/krb4/ChangeLog
index 29d985f31..c1d81d3b4 100644
--- a/src/lib/krb4/ChangeLog
+++ b/src/lib/krb4/ChangeLog
@@ -1,3 +1,86 @@
+2000-06-09 Tom Yu <tlyu@mit.edu>
+
+ * configure.in: Check for strdup().
+
+ * kparse.c: Remove strsave() and replace with an inlined static
+ version of strdup() if HAVE_STRDUP is not defined.
+
+ * g_ad_tkt.c (get_ad_tkt): ptr may be signed; cast while
+ assigning to larger types. [from Charles Hannum by way of
+ ghudson]
+
+2000-05-23 Ken Raeburn <raeburn@mit.edu>
+
+ * decomp_tkt.c (dcmp_tkt_int): Add a couple more length checks.
+ Reject names that are exactly ANAME_SZ (etc) bytes long without
+ the trailing nul, because krb.h says the *_SZ macros are "maximum
+ sizes ... +1".
+ * mk_auth.c (krb_mk_auth): Force nul termination of inst.
+ * sendauth.c (krb_sendauth): Force nul termination of srv_inst.
+
+2000-05-11 Nalin Dahyabhai <nalin@redhat.com>
+
+ * Password.c (GetUserInfo): Truncate user name if it's too long
+ to fit.
+ * cr_auth_repl.c (cr_auth_reply): Bail if the reply packet won't
+ fit into its buffer.
+ * cr_ciph.c (create_ciph): Ditto.
+ * cr_death_pkt.c (krb_create_death_packet): Truncate "aname" to
+ make it fit into the packet's data buffer.
+ * cr_err_repl.c (cr_err_reply): Bail if the reply packet won't
+ fit into its buffer.
+ * cr_tkt.c (krb_create_ticket): Ditto.
+ * g_ad_tkt.c (get_ad_tkt): Stop if data being added to buffer
+ would overflow it. Add more sanity checks when decomposing the
+ credential received.
+ * g_in_tkt.c (krb_mk_in_tkt_preauth): Bail if the request packet
+ won't fit into its buffer.
+ * g_krbhst.c (get_krbhst_default): Truncate the guessed KDC's
+ hostname if it is too long.
+ * g_pw_in_tkt.c: Remove useless strcpy() prototype.
+ * kntoln.c (krb_kntoln): Don't overflow buffer "lname".
+ * mk_err.c (krb_mk_err): Return the needed buffer length if the
+ pointer passed in is NULL.
+ * mk_req.c (krb_mk_req): Bail if the reply packet won't
+ fit into its buffer.
+ * rd_req.c (krb_rd_req): Sanity check the realm name being read,
+ and truncate the service name, nstance, and realm from credential
+ read from keytab.
+ * realmofhost.c (krb_realmofhost): Truncate realm names read
+ from file if they are too long.
+ * send_to_kdc.c (send_to_kdc): Truncate passed-in realm name.
+
+2000-05-08 Ken Raeburn <raeburn@mit.edu>
+
+ * rd_req.c (krb_rd_req): Mask length byte with 0xff in case the
+ length is over 127 and char is signed.
+
+ * recvauth.c (krb_recvauth): If the number of bytes to be read
+ from the net is not positive, just return an error.
+
+2000-05-03 Tom Yu <tlyu@mit.edu>
+
+ * cr_tkt.c: Delete prototype for krb_cr_tkt_int(), since the
+ definition is K&R style and contains narrow types. Thank you
+ HP/UX for having a compiler that actually makes this a fatal
+ error.
+
+2000-04-28 Ken Raeburn <raeburn@mit.edu>
+ Nalin Dahyabhai <nalin@redhat.com>
+
+ * dest_tkt.c (dest_tkt): Don't overflow buffer "shmidname".
+ * in_tkt.c (in_tkt): Don't overflow buffer "shmidname".
+ * kuserok.c (kuserok): Don't overflow buffer "pbuf".
+ * tf_util.c (tf_init): Don't overflow buffer "shmidname".
+ * win_store.c (krb__get_cnffile): Don't overflow buffers "defname"
+ and "cnfname".
+ (krb__get_realmsfile): Don't overflow buffers "defname" and
+ "realmsname".
+
+2000-04-28 Tom Yu <tlyu@mit.edu>
+
+ * rd_req.c (krb_rd_req): Fix some uses of strcpy().
+
2000-03-12 Ezra Peisach <epeisach@mit.edu>
* cr_tkt.c (krb_cr_tkt_int): Add static prototype.
diff --git a/src/lib/krb4/Password.c b/src/lib/krb4/Password.c
index b29663006..5862e0e65 100644
--- a/src/lib/krb4/Password.c
+++ b/src/lib/krb4/Password.c
@@ -177,7 +177,8 @@ OSErr GetUserInfo( char *password )
// already got a password, just get the initial ticket
//////////////////////////////////////////////////////
if (*gPassword) {
- strcpy (UserName, krb_get_default_user( ));
+ strncpy (UserName, krb_get_default_user( ), sizeof(UserName)-1);
+ UserName[sizeof(UserName) - 1] = '\0';
/* FIXME jcm - if we have a password then no dialog
comes up for setting the uinstance. */
rc = kname_parse(uname, uinst, realm, UserName);
@@ -201,7 +202,8 @@ OSErr GetUserInfo( char *password )
}
// Insert user's name in dialog
- strcpy (UserName, krb_get_default_user( ));
+ strncpy (UserName, krb_get_default_user( ), sizeof(UserName) - 1);
+ UserName[sizeof(UserName) - 1] = '\0';
if (*UserName) {
tempStr[0] = strlen(UserName);
memcpy( &(tempStr[1]), UserName, tempStr[0]);
@@ -417,7 +419,8 @@ CacheInitialTicket( serviceName )
if (!serviceName || (serviceName[0] == '\0'))
return err;
- strcpy (UserName, krb_get_default_user());
+ strncpy (UserName, krb_get_default_user(), sizeof(UserName) - 1);
+ UserName[sizeof(UserName) - 1] = '\0';
err = kname_parse(uname, uinst, urealm, UserName);
if (err) return err;
diff --git a/src/lib/krb4/configure.in b/src/lib/krb4/configure.in
index 0434c7d0e..59937e1ac 100644
--- a/src/lib/krb4/configure.in
+++ b/src/lib/krb4/configure.in
@@ -38,7 +38,7 @@ else
AC_DEFINE(BITS32)
fi
AC_DEFINE(KRB4_USE_KEYTAB)
-AC_HAVE_FUNCS(strsave seteuid setreuid setresuid)
+AC_HAVE_FUNCS(strdup seteuid setreuid setresuid)
AC_PROG_AWK
KRB5_BUILD_LIBOBJS
KRB5_BUILD_LIBRARY_WITH_DEPS
diff --git a/src/lib/krb4/cr_auth_repl.c b/src/lib/krb4/cr_auth_repl.c
index 5203506d3..a0562d96f 100644
--- a/src/lib/krb4/cr_auth_repl.c
+++ b/src/lib/krb4/cr_auth_repl.c
@@ -83,6 +83,16 @@ create_auth_reply(pname,pinst,prealm,time_ws,n,x_date,kvno,cipher)
if (n != 0)
*v = 3;
+ /* Make sure the response will actually fit into its buffer. */
+ if(sizeof(pkt->dat) < 3 + strlen(pname) +
+ 1 + strlen(pinst) +
+ 1 + strlen(prealm) +
+ 4 + 1 + 4 +
+ 1 + 2 + cipher->length) {
+ pkt->length = 0;
+ return NULL;
+ }
+
/* Add the basic info */
(void) strcpy((char *) (pkt->dat+2), pname);
pkt->length = 3 + strlen(pname);
diff --git a/src/lib/krb4/cr_ciph.c b/src/lib/krb4/cr_ciph.c
index d15a4e0fd..d9c751271 100644
--- a/src/lib/krb4/cr_ciph.c
+++ b/src/lib/krb4/cr_ciph.c
@@ -71,6 +71,17 @@ create_ciph(c, session, service, instance, realm, life, kvno, tkt,
ptr = (char *) c->dat;
+ if(sizeof(c->dat) / 8 < (8 +
+ strlen(service) + 1 +
+ strlen(instance) + 1 +
+ strlen(realm) + 1 +
+ 1 + 1 + 1 +
+ tkt->length + 4 +
+ 7) / 8) {
+ c->length = 0;
+ return(KFAILURE);
+ }
+
memcpy(ptr, (char *) session, 8);
ptr += 8;
diff --git a/src/lib/krb4/cr_death_pkt.c b/src/lib/krb4/cr_death_pkt.c
index 8daa2d688..c3562675d 100644
--- a/src/lib/krb4/cr_death_pkt.c
+++ b/src/lib/krb4/cr_death_pkt.c
@@ -52,8 +52,9 @@ krb_create_death_packet(a_name)
*v = (unsigned char) KRB_PROT_VERSION;
*t = (unsigned char) AUTH_MSG_DIE;
*t |= HOST_BYTE_ORDER;
- (void) strcpy((char *) (pkt->dat+2),a_name);
- pkt->length = 3 + strlen(a_name);
+ (void) strncpy((char *) (pkt->dat+2),a_name,sizeof(pkt->dat) - 3);
+ pkt->dat[sizeof(pkt->dat) - 1] = '\0';
+ pkt->length = 3 + strlen(pkt->dat+2);
return pkt;
}
#endif /* DEBUG */
diff --git a/src/lib/krb4/cr_err_repl.c b/src/lib/krb4/cr_err_repl.c
index 7f68bda76..54e87d82e 100644
--- a/src/lib/krb4/cr_err_repl.c
+++ b/src/lib/krb4/cr_err_repl.c
@@ -78,6 +78,15 @@ cr_err_reply(pkt,pname,pinst,prealm,time_ws,e,e_string)
*t = (unsigned char) AUTH_MSG_ERR_REPLY;
*t |= HOST_BYTE_ORDER;
+ /* Make sure the reply will fit into the buffer. */
+ if(sizeof(pkt->dat) < 3 + strlen(pname) +
+ 1 + strlen(pinst) +
+ 1 + strlen(prealm) +
+ 4 + 4 +
+ 1 + strlen(e_string)) {
+ pkt->length = 0;
+ return;
+ }
/* Add the basic info */
(void) strcpy((char *) (pkt->dat+2),pname);
pkt->length = 3 + strlen(pname);
diff --git a/src/lib/krb4/cr_tkt.c b/src/lib/krb4/cr_tkt.c
index 0293e105f..34bec4801 100644
--- a/src/lib/krb4/cr_tkt.c
+++ b/src/lib/krb4/cr_tkt.c
@@ -15,12 +15,6 @@
#include <string.h>
#include <krb5.h>
-static int krb_cr_tkt_int PROTOTYPE((KTEXT tkt, unsigned char flags,
- char *pname, char *pinstance,
- char *prealm, long paddress,
- char *session, short life, long time_sec,
- char *sname, char *sinstance,
- C_Block key, krb5_keyblock *k5key));
/*
* Create ticket takes as arguments information that should be in a
* ticket, and the KTEXT object in which the ticket should be
@@ -141,6 +135,23 @@ krb_cr_tkt_int(tkt, flags, pname, pinstance, prealm, paddress,
register char *data; /* running index into ticket */
tkt->length = 0; /* Clear previous data */
+
+ /* Check length of ticket */
+ if (sizeof(tkt->dat) < (sizeof(flags) +
+ 1 + strlen(pname) +
+ 1 + strlen(pinstance) +
+ 1 + strlen(prealm) +
+ 4 + /* address */
+ 8 + /* session */
+ 1 + /* life */
+ 4 + /* issue time */
+ 1 + strlen(sname) +
+ 1 + strlen(sinstance) +
+ 7) / 8) { /* roundoff */
+ memset(tkt->dat, 0, sizeof(tkt->dat));
+ return KFAILURE /* XXX */;
+ }
+
flags |= HOST_BYTE_ORDER; /* ticket byte order */
memcpy((char *) (tkt->dat), (char *) &flags, sizeof(flags));
data = ((char *)tkt->dat) + sizeof(flags);
diff --git a/src/lib/krb4/decomp_tkt.c b/src/lib/krb4/decomp_tkt.c
index 04d3298ad..06e9e316c 100644
--- a/src/lib/krb4/decomp_tkt.c
+++ b/src/lib/krb4/decomp_tkt.c
@@ -192,17 +192,17 @@ dcmp_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, session,
if (HOST_BYTE_ORDER != ((*flags >> K_FLAG_ORDER)& 1))
tkt_swap_bytes++;
- if (strlen(ptr) > ANAME_SZ)
+ if (strlen(ptr) >= ANAME_SZ)
return(KFAILURE);
(void) strcpy(pname,ptr); /* pname */
ptr += strlen(pname) + 1;
- if (strlen(ptr) > INST_SZ)
+ if (strlen(ptr) >= INST_SZ)
return(KFAILURE);
(void) strcpy(pinstance,ptr); /* instance */
ptr += strlen(pinstance) + 1;
- if (strlen(ptr) > REALM_SZ)
+ if (strlen(ptr) >= REALM_SZ)
return(KFAILURE);
(void) strcpy(prealm,ptr); /* realm */
ptr += strlen(prealm) + 1;
@@ -229,9 +229,13 @@ dcmp_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, session,
if (tkt_swap_bytes)
*time_sec = krb4_swab32(*time_sec);
+ if (strlen(ptr) >= ANAME_SZ)
+ return KFAILURE;
(void) strcpy(sname,ptr); /* service name */
ptr += 1 + strlen(sname);
+ if (strlen (ptr) >= INST_SZ)
+ return KFAILURE;
(void) strcpy(sinstance,ptr); /* instance */
ptr += 1 + strlen(sinstance);
diff --git a/src/lib/krb4/dest_tkt.c b/src/lib/krb4/dest_tkt.c
index 70578183e..50c1352b2 100644
--- a/src/lib/krb4/dest_tkt.c
+++ b/src/lib/krb4/dest_tkt.c
@@ -87,8 +87,9 @@ out:
/*
* handle the shared memory case
*/
- (void) strcpy(shmidname, file);
- (void) strcat(shmidname, ".shm");
+ (void) strncpy(shmidname, file, sizeof(shmidname) - 1);
+ shmidname[sizeof(shmidname) - 1] = '\0';
+ (void) strcat(shmidname, ".shm", sizeof(shmidname) - 1 - strlen(shmidname));
if ((i = krb_shm_dest(shmidname)) != KSUCCESS)
return(i);
#endif /* TKT_SHMEM */
diff --git a/src/lib/krb4/g_ad_tkt.c b/src/lib/krb4/g_ad_tkt.c
index b3abb2ddc..afcd0c6f8 100644
--- a/src/lib/krb4/g_ad_tkt.c
+++ b/src/lib/krb4/g_ad_tkt.c
@@ -19,6 +19,19 @@
extern int krb_debug;
extern int swap_bytes;
+/* Return the length of the string if a NUL is found within the first
+ * max_len bytes, otherwise, -1. */
+static int krb_strnlen(const char *str, int max_len)
+{
+ int i;
+ for(i = 0; i < max_len; i++) {
+ if(str[i] == '\0') {
+ return i;
+ }
+ }
+ return -1;
+}
+
/*
* get_ad_tkt obtains a new service ticket from Kerberos, using
* the ticket-granting ticket which must be in the ticket file.
@@ -136,11 +149,22 @@ get_ad_tkt(service,sinstance,realm,lifetime)
return(AD_NOTGT);
/* timestamp */ /* FIXME -- always 0 now, should we fill it in??? */
+ if(pkt->length + 4 > sizeof(pkt->dat))
+ return(INTK_ERR);
memcpy((char *) (pkt->dat+pkt->length), (char *) &time_ws, 4);
pkt->length += 4;
+
+ if(pkt->length + 1 > sizeof(pkt->dat))
+ return(INTK_ERR);
*(pkt->dat+(pkt->length)++) = (char) lifetime;
+
+ if(pkt->length + 1 + strlen(service) > sizeof(pkt->dat))
+ return(INTK_ERR);
(void) strcpy((char *) (pkt->dat+pkt->length),service);
pkt->length += 1 + strlen(service);
+
+ if(pkt->length + 1 + strlen(sinstance) > sizeof(pkt->dat))
+ return(INTK_ERR);
(void) strcpy((char *)(pkt->dat+pkt->length),sinstance);
pkt->length += 1 + strlen(sinstance);
@@ -199,18 +223,27 @@ get_ad_tkt(service,sinstance,realm,lifetime)
memcpy((char *)ses, ptr, 8);
ptr += 8;
- (void) strcpy(s_name,ptr);
+ if(krb_strnlen(ptr, sizeof(s_name)) < 0)
+ return RD_AP_MODIFIED;
+ (void) strncpy(s_name,ptr,sizeof(s_name) - 1);
+ s_name[sizeof(s_name) - 1] = '\0';
ptr += strlen(s_name) + 1;
- (void) strcpy(s_instance,ptr);
+ if(krb_strnlen(ptr, sizeof(s_instance)) < 0)
+ return RD_AP_MODIFIED;
+ (void) strncpy(s_instance,ptr,sizeof(s_instance)-1);
+ s_instance[sizeof(s_instance)-1] = '\0';
ptr += strlen(s_instance) + 1;
- (void) strcpy(rlm,ptr);
+ if(krb_strnlen(ptr, sizeof(rlm)) < 0)
+ return RD_AP_MODIFIED;
+ (void) strncpy(rlm,ptr,sizeof(rlm) - 1);
+ rlm[sizeof(rlm)-1];
ptr += strlen(rlm) + 1;
- lifetime = (unsigned long) ptr[0];
- kvno = (unsigned long) ptr[1];
- tkt->length = (int) ptr[2];
+ lifetime = (unsigned char) ptr[0];
+ kvno = (unsigned char) ptr[1];
+ tkt->length = (unsigned char) ptr[2];
ptr += 3;
memcpy((char *)(tkt->dat), ptr, tkt->length);
ptr += tkt->length;
diff --git a/src/lib/krb4/g_in_tkt.c b/src/lib/krb4/g_in_tkt.c
index c9d618382..361273c9d 100644
--- a/src/lib/krb4/g_in_tkt.c
+++ b/src/lib/krb4/g_in_tkt.c
@@ -152,6 +152,20 @@ krb_mk_in_tkt_preauth(user, instance, realm, service, sinstance, life,
*t = (unsigned char) AUTH_MSG_KDC_REQUEST;
*t |= HOST_BYTE_ORDER;
+ /* Make sure the ticket data will fit into the buffer. */
+ if(sizeof(pkt->dat) < 2 + /* protocol version + flags */
+ 3 + strlen(user) +
+ 1 + strlen(instance) +
+ 1 + strlen(realm) +
+ 4 + /* timestamp */
+ 1 + /* lifetime */
+ 1 + strlen(service) +
+ 1 + strlen(sinstance) +
+ preauth_len) {
+ pkt->length = 0;
+ return INTK_ERR;
+ }
+
/* Now for the variable info */
(void) strcpy((char *)(pkt->dat+2),user); /* aname */
pkt->length = 3 + strlen(user);
diff --git a/src/lib/krb4/g_krbhst.c b/src/lib/krb4/g_krbhst.c
index 529ac0769..4e0fd6d76 100644
--- a/src/lib/krb4/g_krbhst.c
+++ b/src/lib/krb4/g_krbhst.c
@@ -52,9 +52,11 @@ get_krbhst_default(h, r, n)
int n;
{
if (n==1) {
- (void) strcpy(h,KRB_HOST);
- (void) strcat(h,".");
- (void) strcat(h,r); /* KRB_HOST.REALM (ie. kerberos.CYGNUS.COM) */
+ (void) strncpy(h,KRB_HOST,MAXHOSTNAMELEN-1);
+ h[MAXHOSTNAMELEN-1] = '\0';
+ (void) strncat(h,".",MAXHOSTNAMELEN-1-strlen(h));
+ (void) strncat(h,r,MAXHOSTNAMELEN-1-strlen(h));
+ /* KRB_HOST.REALM (ie. kerberos.CYGNUS.COM) */
return(KSUCCESS);
}
else
diff --git a/src/lib/krb4/g_krbrlm.c b/src/lib/krb4/g_krbrlm.c
index 983150ce4..c75023176 100644
--- a/src/lib/krb4/g_krbrlm.c
+++ b/src/lib/krb4/g_krbrlm.c
@@ -44,7 +44,8 @@ krb_get_lrealm(r,n)
cnffile = krb__get_cnffile();
if (!cnffile) {
if (n == 1) {
- (void) strcpy(r, KRB_REALM);
+ (void) strncpy(r, KRB_REALM, REALM_SZ);
+ r[REALM_SZ - 1] = '\0';
return(KSUCCESS);
}
else
diff --git a/src/lib/krb4/g_pw_in_tkt.c b/src/lib/krb4/g_pw_in_tkt.c
index 6723df87e..13f762b01 100644
--- a/src/lib/krb4/g_pw_in_tkt.c
+++ b/src/lib/krb4/g_pw_in_tkt.c
@@ -176,7 +176,6 @@ krb_get_pw_in_tkt_preauth(user,instance,realm,service,sinstance,life,password)
#include <signal.h>
#include <setjmp.h>
#else
-char *strcpy();
int strcmp();
#endif
#if defined(__svr4__) || defined(__SVR4)
diff --git a/src/lib/krb4/in_tkt.c b/src/lib/krb4/in_tkt.c
index ea17be820..4e220f913 100644
--- a/src/lib/krb4/in_tkt.c
+++ b/src/lib/krb4/in_tkt.c
@@ -159,8 +159,9 @@ in_tkt(pname,pinst)
}
(void) close(tktfile);
#ifdef TKT_SHMEM
- (void) strcpy(shmidname, file);
- (void) strcat(shmidname, ".shm");
+ (void) strncpy(shmidname, file, sizeof(shmidname) - 1);
+ shmidname[sizeof(shmidname) - 1] = '\0';
+ (void) strncat(shmidname, ".shm", sizeof(shmidname) - 1 - strlen(shmidname));
return(krb_shm_create(shmidname));
#else /* !TKT_SHMEM */
return(KSUCCESS);
diff --git a/src/lib/krb4/kntoln.c b/src/lib/krb4/kntoln.c
index 8b6cdfe0e..f86599cce 100644
--- a/src/lib/krb4/kntoln.c
+++ b/src/lib/krb4/kntoln.c
@@ -38,6 +38,10 @@
* KSUCCESS if all goes well, otherwise KFAILURE.
*/
+/* The definition of MAX_USERNAME here MUST agree with kuserok.c, or bad
+ * things will happen. */
+#define MAX_USERNAME 10
+
krb_kntoln(ad,lname)
AUTH_DAT *ad;
char *lname;
@@ -51,6 +55,7 @@ krb_kntoln(ad,lname)
return(KFAILURE);
if (strcmp(ad->prealm,lrealm))
return(KFAILURE);
- (void) strcpy(lname,ad->pname);
+ (void) strncpy(lname,ad->pname,MAX_USERNAME-1);
+ lname[MAX_USERNAME - 1] = '\0';
return(KSUCCESS);
}
diff --git a/src/lib/krb4/kparse.c b/src/lib/krb4/kparse.c
index 98e48fbd9..e72295c48 100644
--- a/src/lib/krb4/kparse.c
+++ b/src/lib/krb4/kparse.c
@@ -54,8 +54,8 @@
static char *strutol();
-#ifndef HAVE_STRSAVE
-static char *strsave();
+#ifndef HAVE_STRDUP
+static char *strdup();
#endif
#ifndef HAVE_STDLIB_H
extern char *malloc();
@@ -104,7 +104,7 @@ int fGetParameterSet( fp,parm,parmcount )
keyword);
return(PS_BAD_KEYWORD);
}
- parm[i].value = strsave( value );
+ parm[i].value = strdup(value);
break;
}
}
@@ -552,34 +552,6 @@ int fGetChar(fp)
return(ch);
}
-
-/*
- * Routine Name: strsave
- *
- * Function: return a pointer to a saved copy of the
- * input string. the copy will be allocated
- * as large as necessary.
- *
- * Explicit Parameters: pointer to string to save
- *
- * Implicit Parameters: None
- *
- * External Procedures: malloc,strcpy,strlen
- *
- * Side Effects: None
- *
- * Return Value: pointer to copied string
- *
- */
-#ifndef HAVE_STRSAVE
-static char * strsave(p)
- char *p;
-{
- return(strcpy(malloc(strlen(p)+1),p));
-}
-#endif
-
-
/*
* strutol changes all characters in a string to lower case, in place.
* the pointer to the beginning of the string is returned.
@@ -770,3 +742,42 @@ main(argc,argv)
exit(0);
}
#endif
+
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that: (1) source distributions retain this entire copyright
+ * notice and comment, and (2) distributions including binaries display
+ * the following acknowledgement: ``This product includes software
+ * developed by the University of California, Berkeley and its contributors''
+ * in the documentation or other materials provided with the distribution
+ * and in all advertising materials mentioning features or use of this
+ * software. Neither the name of the University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/* based on @(#)strdup.c 5.3 (Berkeley) 6/1/90 */
+
+#ifndef HAVE_STRDUP
+static char *
+strdup(str)
+ const char *str;
+{
+ int len;
+ char *copy;
+
+ if (!str)
+ return((char *)0);
+ len = strlen(str) + 1;
+ if (!(copy = malloc((u_int)len)))
+ return((char *)0);
+ memcpy(copy, str, len);
+ return(copy);
+}
+#endif
diff --git a/src/lib/krb4/kuserok.c b/src/lib/krb4/kuserok.c
index 0aee8934a..20587cb5b 100644
--- a/src/lib/krb4/kuserok.c
+++ b/src/lib/krb4/kuserok.c
@@ -118,8 +118,11 @@ kuserok(kdata, luser)
if ((pwd = getpwnam(luser)) == NULL) {
return(NOTOK);
}
- (void) strcpy(pbuf, pwd->pw_dir);
- (void) strcat(pbuf, "/.klogin");
+ if (strlen (pwd->pw_dir) + sizeof ("/.klogin") >= sizeof (pbuf))
+ return NOTOK;
+ (void) strncpy(pbuf, pwd->pw_dir, sizeof(pbuf) - 1);
+ pbuf[sizeof(pbuf) - 1] = '\0';
+ (void) strncat(pbuf, "/.klogin", sizeof(pbuf) - 1 - strlen(pbuf));
if (access(pbuf, F_OK)) { /* not accessible */
/*
diff --git a/src/lib/krb4/mk_auth.c b/src/lib/krb4/mk_auth.c
index 39a2e2f68..a94a25d85 100644
--- a/src/lib/krb4/mk_auth.c
+++ b/src/lib/krb4/mk_auth.c
@@ -124,8 +124,10 @@ krb_mk_auth(options, ticket, service, inst, realm, checksum, version, buf)
realm = krb_realm;
}
- if (!(options & KOPT_DONT_CANON))
- (void) strncpy(inst, krb_get_phost(inst), INST_SZ);
+ if (!(options & KOPT_DONT_CANON)) {
+ (void) strncpy(inst, krb_get_phost(inst), INST_SZ - 1);
+ inst[INST_SZ-1] = 0;
+ }
/* get the ticket if desired */
if (!(options & KOPT_DONT_MK_REQ)) {
diff --git a/src/lib/krb4/mk_err.c b/src/lib/krb4/mk_err.c
index e30e299bc..029aa9f9c 100644
--- a/src/lib/krb4/mk_err.c
+++ b/src/lib/krb4/mk_err.c
@@ -41,6 +41,14 @@ krb_mk_err(p,e,e_string)
{
u_char *start;
+ /* Just return the buffer length if p is NULL, because writing to the
+ * buffer would be a bad idea. Note that this feature is a change from
+ * previous versions, and can therefore only be used safely in this
+ * source tree, where we know this function supports it. */
+ if(p == NULL) {
+ return 2 + sizeof(e) + strlen(e_string);
+ }
+
start = p;
/* Create fixed part of packet */
diff --git a/src/lib/krb4/mk_req.c b/src/lib/krb4/mk_req.c
index 1936cb287..468dccdb6 100644
--- a/src/lib/krb4/mk_req.c
+++ b/src/lib/krb4/mk_req.c
@@ -130,6 +130,19 @@ krb_mk_req(authent,service,instance,realm,checksum)
if (retval != KSUCCESS) return (retval);
+ if(sizeof(authent->dat) / 8 < (3 +
+ strlen(realm) + 1 + 2 +
+ 3 + ticket->length +
+ strlen(cr.pname) + 1 +
+ strlen(cr.pinst) + 1 +
+ strlen(myrealm) + 1 +
+ 4 + /* checksum */
+ 4 + /* timestamp */
+ 7) / 8) { /* round-up */
+ authent->length = 0;
+ return KFAILURE;
+ }
+
if (krb_ap_req_debug)
DEB (("%s %s %s %s %s\n", service, instance, realm,
cr.pname, cr.pinst));
diff --git a/src/lib/krb4/rd_req.c b/src/lib/krb4/rd_req.c
index c9b6ac734..09f914d8a 100644
--- a/src/lib/krb4/rd_req.c
+++ b/src/lib/krb4/rd_req.c
@@ -108,6 +108,19 @@ krb_clear_key_krb5(ctx)
krb5_key = 0;
}
+/* A helper function to let us see if a buffer is properly terminated. */
+static int
+krb_strnlen(const char *str, size_t max_len)
+{
+ int i = 0;
+ for(i = 0; i < max_len; i++) {
+ if(str[i] == '\0') {
+ return i;
+ }
+ }
+ return -1;
+}
+
/*
* krb_rd_req() takes an AUTH_MSG_APPL_REQUEST or
* AUTH_MSG_APPL_REQUEST_MUTUAL message created by krb_mk_req(),
@@ -184,6 +197,8 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn)
krb5_keyblock keyblock;
int status;
+ tkt->mbz = req_id->mbz = 0;
+
if (authent->length <= 0)
return(RD_AP_MODIFIED);
@@ -219,8 +234,13 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn)
mutual = 0;
#endif /* lint */
s_kvno = *ptr++; /* get server key version */
- (void) strcpy(realm,ptr); /* And the realm of the issuing KDC */
- ptr += strlen(ptr) + 1; /* skip the realm "hint" */
+ if(krb_strnlen(ptr, sizeof(realm)) < 0) {
+ return RD_AP_MODIFIED; /* must have been modified, the client wouldn't
+ try to trick us with wacky data */
+ }
+ (void) strncpy(realm,ptr,REALM_SZ); /* And the realm of the issuing KDC */
+ realm[REALM_SZ-1] = '\0';
+ ptr += strlen(realm) + 1; /* skip the realm "hint" */
/*
* If "fn" is NULL, key info should already be set; don't
@@ -249,13 +269,16 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn)
return(RD_AP_UNDEC);
#endif /* !NOENCRYPTION */
- (void) strcpy(st_rlm,realm);
- (void) strcpy(st_nam,service);
- (void) strcpy(st_inst,instance);
+ (void) strncpy(st_rlm,realm, sizeof(st_rlm) - 1);
+ st_rlm[sizeof(st_rlm) - 1] = '\0';
+ (void) strncpy(st_nam,service, sizeof(st_nam) - 1);
+ st_nam[sizeof(st_nam) - 1] = '\0';
+ (void) strncpy(st_inst,instance, sizeof(st_inst) - 1);
+ st_inst[sizeof(st_inst) - 1] = '\0';
}
/* Get ticket from authenticator */
- tkt->length = (int) *ptr++;
+ tkt->length = (int) *ptr++ & 0xff;
if ((tkt->length + (ptr+1 - (char *) authent->dat)) > authent->length)
return(RD_AP_MODIFIED);
memcpy((char *)(tkt->dat), ptr+1, tkt->length);
@@ -324,13 +347,16 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn)
#define check_ptr() if ((ptr - (char *) req_id->dat) > req_id->length) return(RD_AP_MODIFIED);
ptr = (char *) req_id->dat;
- (void) strcpy(r_aname,ptr); /* Authentication name */
+ (void) strncpy(r_aname,ptr,ANAME_SZ); /* Authentication name */
+ r_aname[ANAME_SZ-1] = '\0';
ptr += strlen(r_aname)+1;
check_ptr();
- (void) strcpy(r_inst,ptr); /* Authentication instance */
+ (void) strncpy(r_inst,ptr,INST_SZ); /* Authentication instance */
+ r_inst[INST_SZ-1] = '\0';
ptr += strlen(r_inst)+1;
check_ptr();
- (void) strcpy(r_realm,ptr); /* Authentication name */
+ (void) strncpy(r_realm,ptr,REALM_SZ); /* Authentication name */
+ r_realm[REALM_SZ-1] = '\0';
ptr += strlen(r_realm)+1;
check_ptr();
memcpy((char *)&ad->checksum, ptr, 4); /* Checksum */
diff --git a/src/lib/krb4/realmofhost.c b/src/lib/krb4/realmofhost.c
index 90e01bb34..1e4b78601 100644
--- a/src/lib/krb4/realmofhost.c
+++ b/src/lib/krb4/realmofhost.c
@@ -131,14 +131,18 @@ krb_realmofhost(host)
if (domain && (strlen(trans_host) == strlen(domain))
&& !strcasecmp (trans_host, domain)) {
/* got domain match, save for later */
- (void) strcpy (ret_realm, trans_realm);
+ (void) strncpy (ret_realm, trans_realm,
+ sizeof(ret_realm) - 1);
+ ret_realm[sizeof(ret_realm) - 1] = '\0';
continue;
}
} else {
/* want exact match of hostname */
if ((strlen(lhost) == strlen(trans_host)) &&
!strcasecmp (trans_host, lhost)) {
- (void) strcpy (ret_realm, trans_realm);
+ (void) strncpy (ret_realm, trans_realm,
+ sizeof(ret_realm) - 1);
+ ret_realm[sizeof(ret_realm) - 1] = '\0';
break;
}
}
diff --git a/src/lib/krb4/recvauth.c b/src/lib/krb4/recvauth.c
index e62e3f954..2a6665648 100644
--- a/src/lib/krb4/recvauth.c
+++ b/src/lib/krb4/recvauth.c
@@ -188,9 +188,12 @@ krb_recvauth(options, fd, ticket, service, instance, faddr, laddr, kdata,
if (i < KRB_SENDAUTH_VLEN) {
/* since we already got the space, and part of the ticket,
we read fewer bytes to get the rest of the ticket */
+ int len_to_read = tkt_len - KRB_SENDAUTH_VLEN + 1 + i;
+ if (len_to_read <= 0)
+ return KFAILURE;
if (krb_net_read(fd, (char *)(tmp_buf+KRB_SENDAUTH_VLEN),
- (int) (tkt_len - KRB_SENDAUTH_VLEN + 1 + i))
- != (int)(tkt_len - KRB_SENDAUTH_VLEN + 1 + i))
+ len_to_read)
+ != len_to_read)
return(errno);
} else {
if (krb_net_read(fd, (char *)(tmp_buf+i), (int)tkt_len) !=
diff --git a/src/lib/krb4/send_to_kdc.c b/src/lib/krb4/send_to_kdc.c
index c7e0fb33b..f93b9d079 100644
--- a/src/lib/krb4/send_to_kdc.c
+++ b/src/lib/krb4/send_to_kdc.c
@@ -94,12 +94,13 @@ send_to_kdc(pkt,rpkt,realm)
* local realm.
*/
if (realm)
- (void) strcpy(lrealm, realm);
+ (void) strncpy(lrealm, realm, sizeof(lrealm) - 1);
else
if (krb_get_lrealm(lrealm,1)) {
DEB (("%s: can't get local realm\n", prog));
return(SKDC_CANT);
}
+ lrealm[sizeof(lrealm) - 1] = '\0';
DEB (("lrealm is %s\n", lrealm));
if (SOCKET_INITIALIZE()) {
diff --git a/src/lib/krb4/sendauth.c b/src/lib/krb4/sendauth.c
index 9b8fb3904..76c470c20 100644
--- a/src/lib/krb4/sendauth.c
+++ b/src/lib/krb4/sendauth.c
@@ -208,7 +208,8 @@ krb_sendauth(options, fd, ticket, service, inst, realm, checksum,
}
/* copy instance into local storage, so mk_auth can canonicalize */
- (void) strncpy(srv_inst, inst, INST_SZ);
+ (void) strncpy(srv_inst, inst, INST_SZ-1);
+ srv_inst[INST_SZ-1] = 0;
rem = krb_mk_auth (options, ticket, service, srv_inst, realm, checksum,
version, packet);
if (rem != KSUCCESS)
diff --git a/src/lib/krb4/tf_util.c b/src/lib/krb4/tf_util.c
index ebf500bf2..0d69719cf 100644
--- a/src/lib/krb4/tf_util.c
+++ b/src/lib/krb4/tf_util.c
@@ -181,8 +181,9 @@ int tf_init(tf_name, rw)
tf_name = tkt_string();
#ifdef TKT_SHMEM
- (void) strcpy(shmidname, tf_name);
- (void) strcat(shmidname, ".shm");
+ (void) strncpy(shmidname, tf_name, sizeof(shmidname) - 1);
+ shmidname[sizeof(shmidname) - 1] = '\0';
+ (void) strncat(shmidname, ".shm", sizeof(shmidname) - 1 - strlen(shmidname));
#endif /* TKT_SHMEM */
/*
diff --git a/src/lib/krb4/win_store.c b/src/lib/krb4/win_store.c
index 50507aa12..28d11bd85 100644
--- a/src/lib/krb4/win_store.c
+++ b/src/lib/krb4/win_store.c
@@ -62,15 +62,17 @@ krb__get_cnffile()
char defname[FILENAME_MAX];
UINT rc;
- rc = GetWindowsDirectory(defname, sizeof(defname));
+ defname[sizeof(defname) - 1] = '\0';
+ rc = GetWindowsDirectory(defname, sizeof(defname) - 1);
assert(rc > 0);
- strcat(defname, "\\");
+ strncat(defname, "\\", sizeof(defname) - 1 - strlen(defname));
- strcat(defname, DEF_KRB_CONF);
+ strncat(defname, DEF_KRB_CONF, sizeof(defname) - 1 - strlen(defname));
+ cnfname[sizeof(cnfname) - 1] = '\0';
GetPrivateProfileString(INI_FILES, INI_KRB_CONF, defname,
- cnfname, sizeof(cnfname), KERBEROS_INI);
+ cnfname, sizeof(cnfname) - 1, KERBEROS_INI);
cnffile = fopen(cnfname, "r");
@@ -94,15 +96,17 @@ krb__get_realmsfile()
char defname[FILENAME_MAX];
UINT rc;
- rc = GetWindowsDirectory(defname, sizeof(defname));
+ defname[sizeof(defname) - 1] = '\0';
+ rc = GetWindowsDirectory(defname, sizeof(defname) - 1);
assert(rc > 0);
- strcat(defname, "\\");
+ strncat(defname, "\\", sizeof(defname) - 1 - strlen(defname));
- strcat(defname, DEF_KRB_REALMS);
+ strncat(defname, DEF_KRB_REALMS, sizeof(defname) - 1 - strlen(defname));
+ defname[sizeof(defname) - 1] = '\0';
GetPrivateProfileString(INI_FILES, INI_KRB_REALMS, defname,
- realmsname, sizeof(realmsname), KERBEROS_INI);
+ realmsname, sizeof(realmsname) - 1, KERBEROS_INI);
realmsfile = fopen(realmsname, "r");
diff --git a/src/lib/krb5/ChangeLog b/src/lib/krb5/ChangeLog
index 89f7f2ea1..061080371 100644
--- a/src/lib/krb5/ChangeLog
+++ b/src/lib/krb5/ChangeLog
@@ -1,3 +1,11 @@
+2000-06-23 Tom Yu <tlyu@mit.edu>
+
+ * Makefile.in (LIBMAJOR, LIBMINOR): Bump version.
+
+2000-06-23 Ken Raeburn <raeburn@mit.edu>
+
+ * Makefile.in (SHLIB_EXPLIBS): Add @RESOLV_LIB@.
+
2000-05-31 Wilfredo Sanchez <tritan@mit.edu>
* configure.in: Check for existance of <memory.h>.
diff --git a/src/lib/krb5/Makefile.in b/src/lib/krb5/Makefile.in
index 0dab1f3a9..68e354c6f 100644
--- a/src/lib/krb5/Makefile.in
+++ b/src/lib/krb5/Makefile.in
@@ -32,8 +32,8 @@ LIBDONE= error_tables/DONE asn.1/DONE ccache/DONE ccache/stdio/DONE \
STLIBOBJS=krb5_libinit.o
LIB=krb5
-LIBMAJOR=2
-LIBMINOR=2
+LIBMAJOR=3
+LIBMINOR=0
STOBJLISTS= \
OBJS.ST \
@@ -58,7 +58,7 @@ RELDIR=krb5
SHLIB_EXPDEPS = \
$(TOPLIBD)/libk5crypto$(SHLIBEXT) \
$(TOPLIBD)/libcom_err$(SHLIBEXT)
-SHLIB_EXPLIBS=-lk5crypto -lcom_err @GEN_LIB@
+SHLIB_EXPLIBS=-lk5crypto -lcom_err @GEN_LIB@ @RESOLV_LIB@
SHLIB_DIRS=-L$(TOPLIBD)
SHLIB_RDIRS=$(KRB5_LIBDIR)
diff --git a/src/lib/krb5/krb/ChangeLog b/src/lib/krb5/krb/ChangeLog
index 14fa9c3d8..80f24ebfb 100644
--- a/src/lib/krb5/krb/ChangeLog
+++ b/src/lib/krb5/krb/ChangeLog
@@ -1,3 +1,102 @@
+2000-06-23 Miro Jurisic <meeroh@mit.edu>
+
+ * conv_princ.c (krb5_425_conv_principal): Fixed v4->v5 realm
+ name conversion
+
+ * conv_princ.c (krb5_425_conv_principal): Honor v4/v5 realm name
+ differences when convertion from v4 principals to v5.
+
+2000-06-23 Tom Yu <tlyu@mit.edu>
+
+ * get_creds.c (krb5_get_credentials): Translate KRB5_CC_NOTFOUND
+ returned from krb5_get_cred_from_kdc() if a prior call to
+ krb5_cc_retrieve_cred() returned KRB5_CC_NOT_KTYPE.
+
+ * rd_priv.c (krb5_rd_priv_basic): Delete code that was incorrectly
+ doing explicit ivec chaining; c_decrypt() does it now.
+
+ * mk_priv.c (krb5_mk_priv_basic): Delete code that was incorrectly
+ doing explicit ivec chaining; c_encrypt() does it now.
+
+ * conv_princ.c (krb5_524_conv_principal): Make a copy of the krb5
+ realm that is nul-terminated to avoid falling off the end of the
+ krb5 realm, which is not necessarily nul-terminated.
+
+2000-06-23 Danilo Almeida <dalmeida@mit.edu>
+
+ * init_ctx.c (krb5_get_tgs_ktypes, krb5_free_ktypes): Fix linkage to
+ be KRB5_CALLCONV.
+
+2000-06-23 Ken Raeburn <raeburn@mit.edu>
+
+ * get_in_tkt.c (krb5_get_in_tkt): If enctypes are specified, send
+ the server the intersection of that list and the supported types,
+ in the order requested.
+
+ * recvauth.c (krb5_recvauth_version): New routine, takes a
+ krb5_data in which to store the client's application version
+ string.
+ (recvauth_common): Renamed from krb5_recvauth, added above
+ functionality depending on extra argument values.
+ (krb5_recvauth): New stub, calls above routine with extra dummy
+ values.
+
+ * kfree.c: Remove unneeded "return" statements at the end of many
+ functions.
+ (krb5_free_*_content, krb5_free_*_contents,
+ krb5_free_cred_enc_part, krb5_free_pwd_sequences): Set freed
+ pointer members to null when containing structure isn't being
+ freed.
+
+ * t_kerb.c (test_524_conv_principal): New test code, to exercise
+ bbense's code addition.
+ (main, usage): Updated.
+ * t_krb5.conf: Added stanford.edu->IR.STANFORD.EDU mapping, and a
+ test case for improperly long v4 realm names.
+ * Makefile.in (check-unix): Run 524 conversion test for some test
+ Athena and Stanford names.
+ * t_ref_kerb.out: Updated.
+
+ * init_ctx.c (init_common): Feed current-microsecond time and
+ process-id into PRNG, instead of just current-second time.
+ * mk_req_ext.c (krb5_mk_req_extended): Feed current time into
+ PRNG if a subkey will be generated.
+ * sendauth.c (krb5_sendauth): Feed local and remote addresses of
+ socket, if they can be determined, into the PRNG if a subkey will
+ be used.
+
+ * init_ctx.c (krb5_free_ktypes): New routine, to free values
+ returned by krb5_get_tgs_ktypes, krb5_get_permitted_enctypes, and
+ krb5_get_default_in_tkt_ktypes.
+ (krb5_set_default_tgs_ktypes, krb5_is_permitted_enctype): Use it.
+ (get_profile_etype_list): Use passed-in enctype list if the
+ passed-in count is non-zero, instead of checking the
+ in_tkt_ktype_count value in the context.
+
+2000-06-23 Ken Raeburn <raeburn@mit.edu>
+ Nalin Dahyabhai <nalin@redhat.com>
+
+ * conv_princ.c (krb5_524_conv_principal): Return an error if name
+ is too long. Use memcpy for character data since we already know
+ the length.
+
+2000-06-23 Nalin Dahyabhai <nalin@redhat.com>
+
+ * kfree.c (krb5_free_keyblock_contents): Set contents pointer to
+ null after freeing.
+
+ * chk_trans.c (krb5_check_transited_list): Don't overflow buffers
+ "prev" and "next".
+ * conv_princ.c (krb5_425_conv_principal): Don't overflow buffer
+ "buf".
+
+2000-06-23 Ken Raeburn <raeburn@mit.edu>
+ Booker C. Bense <bbense@networking.stanford.edu>
+
+ * conv_princ.c (krb5_524_conv_principal): Look up v4_realm in
+ config file, in case site's krb4 realm name isn't the same as the
+ krb5 realm name.
+
2000-05-31 Wilfredo Sanchez <tritan@mit.edu>
* fwd_tgt.c: Check for existance of <memory.h>.
@@ -22,8 +121,9 @@
2000-04-28 Alexandra Ellwood <lxs@mit.edu>
- * gic_pwd.c (krb5_init_creds_password) added code to return to login library if
- the password is expired (login library handles this error appropriately).
+ * gic_pwd.c (krb5_init_creds_password) added code to return to
+ login library if the password is expired (login library handles
+ this error appropriately).
2000-04-08 Tom Yu <tlyu@mit.edu>
@@ -32,11 +132,12 @@
2000-04-07 Jeffrey Altman <jaltman@columbia.edu>
- * gic_pwd.c (krb5_get_init_creds_keytab), gic_pwd.c (krb5_get_init_creds_password)
- when determining whether or not to retry with a "master kdc" do not retry if
- the return value from the first attempt was KRB5_REALM_CANT_RESOLV. Also, do
- not overwrite the return code if the return value from the access to the "master
- kdc" was KRB5_REALM_CANT_RESOLV.
+ * gic_pwd.c (krb5_get_init_creds_keytab), gic_pwd.c
+ (krb5_get_init_creds_password) when determining whether or not to
+ retry with a "master kdc" do not retry if the return value from
+ the first attempt was KRB5_REALM_CANT_RESOLV. Also, do not
+ overwrite the return code if the return value from the access to
+ the "master kdc" was KRB5_REALM_CANT_RESOLV.
2000-03-15 Danilo Almeida <dalmeida@mit.edu>
diff --git a/src/lib/krb5/krb/Makefile.in b/src/lib/krb5/krb/Makefile.in
index 8aeb398d0..19c1da40c 100644
--- a/src/lib/krb5/krb/Makefile.in
+++ b/src/lib/krb5/krb/Makefile.in
@@ -327,6 +327,8 @@ check-unix:: $(TEST_PROGS)
425_conv_principal rcmd uunet UU.NET \
425_conv_principal zephyr zephyr ATHENA.MIT.EDU \
425_conv_principal kadmin ATHENA.MIT.EDU ATHENA.MIT.EDU \
+ 524_conv_principal host/e40-po.mit.edu@ATHENA.MIT.EDU \
+ 524_conv_principal host/foobar.stanford.edu@stanford.edu \
set_realm marc@MIT.EDU CYGNUS.COM \
> test.out
cmp test.out $(srcdir)/t_ref_kerb.out
diff --git a/src/lib/krb5/krb/chk_trans.c b/src/lib/krb5/krb/chk_trans.c
index c2ac716c8..eee55c8c5 100644
--- a/src/lib/krb5/krb/chk_trans.c
+++ b/src/lib/krb5/krb/chk_trans.c
@@ -56,13 +56,13 @@ krb5_data *realm2;
return(retval);
}
- memset(prev, 0, MAX_REALM_LN + 1);
- memset(next, 0, MAX_REALM_LN + 1), nextp = next;
+ memset(prev, 0, sizeof(prev));
+ memset(next, 0, sizeof(next)), nextp = next;
for (i = 0; i < trans_length; i++) {
if (i < trans_length-1 && trans->data[i] == '\\') {
i++;
*nextp++ = trans->data[i];
- if (nextp - next > MAX_REALM_LN) {
+ if (nextp - next >= sizeof(next)) {
retval = KRB5KRB_AP_ERR_ILL_CR_TKT;
goto finish;
}
@@ -70,16 +70,17 @@ krb5_data *realm2;
}
if (i < trans_length && trans->data[i] != ',') {
*nextp++ = trans->data[i];
- if (nextp - next > MAX_REALM_LN) {
+ if (nextp - next >= sizeof(next)) {
retval = KRB5KRB_AP_ERR_ILL_CR_TKT;
goto finish;
}
continue;
}
+ next[sizeof(next) - 1] = '\0';
if (strlen(next) > 0) {
if (next[0] != '/') {
if (*(nextp-1) == '.' && strlen(next) + strlen(prev) <= MAX_REALM_LN)
- strcat(next, prev);
+ strncat(next, prev, sizeof(next) - 1 - strlen(next));
retval = KRB5KRB_AP_ERR_ILL_CR_TKT;
for (j = 0; tgs_list[j]; j++) {
if (strlen(next) == (size_t) krb5_princ_realm(context, tgs_list[j])->length &&
@@ -93,12 +94,12 @@ krb5_data *realm2;
}
if (i+1 < trans_length && trans->data[i+1] == ' ') {
i++;
- memset(next, 0, MAX_REALM_LN + 1), nextp = next;
+ memset(next, 0, sizeof(next)), nextp = next;
continue;
}
if (i+1 < trans_length && trans->data[i+1] != '/') {
- strcpy(prev, next);
- memset(next, 0, MAX_REALM_LN + 1), nextp = next;
+ strncpy(prev, next, sizeof(prev) - 1);
+ memset(next, 0, sizeof(next)), nextp = next;
continue;
}
}
diff --git a/src/lib/krb5/krb/conv_princ.c b/src/lib/krb5/krb/conv_princ.c
index b90289ab5..36e2bbd0a 100644
--- a/src/lib/krb5/krb/conv_princ.c
+++ b/src/lib/krb5/krb/conv_princ.c
@@ -137,7 +137,8 @@ krb5_524_conv_principal(context, princ, name, inst, realm)
{
const struct krb_convert *p;
krb5_data *compo;
- char *c;
+ char *c, *tmp_realm, *tmp_prealm;
+ int tmp_realm_len, retval;
*name = *inst = '\0';
switch (krb5_princ_size(context, princ)) {
@@ -147,18 +148,22 @@ krb5_524_conv_principal(context, princ, name, inst, realm)
p = sconv_list;
while (p->v4_str) {
if (strncmp(p->v5_str, compo->data, compo->length) == 0) {
- /* It is, so set the new name now, and chop off */
- /* instance's domain name if requested */
- strcpy(name, p->v4_str);
- if (p->flags & DO_REALM_CONVERSION) {
- compo = krb5_princ_component(context, princ, 1);
- c = strnchr(compo->data, '.', compo->length);
- if (!c || (c - compo->data) > INST_SZ - 1)
- return KRB5_INVALID_PRINCIPAL;
- strncpy(inst, compo->data, c - compo->data);
- inst[c - compo->data] = '\0';
- }
- break;
+ /*
+ * It is, so set the new name now, and chop off
+ * instance's domain name if requested.
+ */
+ if (strlen (p->v4_str) > ANAME_SZ - 1)
+ return KRB5_INVALID_PRINCIPAL;
+ strcpy(name, p->v4_str);
+ if (p->flags & DO_REALM_CONVERSION) {
+ compo = krb5_princ_component(context, princ, 1);
+ c = strnchr(compo->data, '.', compo->length);
+ if (!c || (c - compo->data) >= INST_SZ - 1)
+ return KRB5_INVALID_PRINCIPAL;
+ memcpy(inst, compo->data, c - compo->data);
+ inst[c - compo->data] = '\0';
+ }
+ break;
}
p++;
}
@@ -168,7 +173,7 @@ krb5_524_conv_principal(context, princ, name, inst, realm)
compo = krb5_princ_component(context, princ, 1);
if (compo->length >= INST_SZ - 1)
return KRB5_INVALID_PRINCIPAL;
- strncpy(inst, compo->data, compo->length);
+ memcpy(inst, compo->data, compo->length);
inst[compo->length] = '\0';
}
/* fall through */
@@ -178,7 +183,7 @@ krb5_524_conv_principal(context, princ, name, inst, realm)
compo = krb5_princ_component(context, princ, 0);
if (compo->length >= ANAME_SZ)
return KRB5_INVALID_PRINCIPAL;
- strncpy(name, compo->data, compo->length);
+ memcpy(name, compo->data, compo->length);
name[compo->length] = '\0';
}
break;
@@ -187,11 +192,39 @@ krb5_524_conv_principal(context, princ, name, inst, realm)
}
compo = krb5_princ_realm(context, princ);
- if (compo->length > REALM_SZ - 1)
- return KRB5_INVALID_PRINCIPAL;
- strncpy(realm, compo->data, compo->length);
- realm[compo->length] = '\0';
+ tmp_prealm = malloc(compo->length + 1);
+ if (tmp_prealm == NULL)
+ return ENOMEM;
+ strncpy(tmp_prealm, compo->data, compo->length);
+ tmp_prealm[compo->length] = '\0';
+
+ /* Ask for v4_realm corresponding to
+ krb5 principal realm from krb5.conf realms stanza */
+
+ if (context->profile == 0)
+ return KRB5_CONFIG_CANTOPEN;
+ retval = profile_get_string(context->profile, "realms",
+ tmp_prealm, "v4_realm", 0,
+ &tmp_realm);
+ free(tmp_prealm);
+ if (retval) {
+ return retval;
+ } else {
+ if (tmp_realm == 0) {
+ if (compo->length > REALM_SZ - 1)
+ return KRB5_INVALID_PRINCIPAL;
+ strncpy(realm, compo->data, compo->length);
+ realm[compo->length] = '\0';
+ } else {
+ tmp_realm_len = strlen(tmp_realm);
+ if (tmp_realm_len > REALM_SZ - 1)
+ return KRB5_INVALID_PRINCIPAL;
+ strncpy(realm, tmp_realm, tmp_realm_len);
+ realm[tmp_realm_len] = '\0';
+ profile_release_string(tmp_realm);
+ }
+ }
return 0;
}
@@ -209,6 +242,37 @@ krb5_425_conv_principal(context, name, instance, realm, princ)
char *domain, *cp;
char **full_name = 0, **cpp;
const char *names[5];
+ void* iterator = NULL;
+ char** v4realms = NULL;
+ char* realm_name = NULL;
+ char* dummy_value = NULL;
+
+ /* First, convert the realm, since the v4 realm is not necessarily the same as the v5 realm
+ To do that, iterate over all the realms in the config file, looking for a matching
+ v4_realm line */
+ names [0] = "realms";
+ names [1] = NULL;
+ retval = profile_iterator_create (context -> profile, names, PROFILE_ITER_LIST_SECTION | PROFILE_ITER_SECTIONS_ONLY, &iterator);
+ while (retval == 0) {
+ retval = profile_iterator (&iterator, &realm_name, &dummy_value);
+ if ((retval == 0) && (realm_name != NULL)) {
+ names [0] = "realms";
+ names [1] = realm_name;
+ names [2] = "v4_realm";
+ names [3] = NULL;
+
+ retval = profile_get_values (context -> profile, names, &v4realms);
+ if ((retval == 0) && (v4realms != NULL) && (v4realms [0] != NULL) && (strcmp (v4realms [0], realm) == 0)) {
+ realm = realm_name;
+ break;
+ } else if (retval == PROF_NO_RELATION) {
+ /* If it's not found, just keep going */
+ retval = 0;
+ }
+ } else if ((retval == 0) && (realm_name == NULL)) {
+ break;
+ }
+ }
if (instance) {
if (instance[0] == '\0') {
@@ -234,7 +298,8 @@ krb5_425_conv_principal(context, name, instance, realm, princ)
if (retval == 0 && full_name && full_name[0]) {
instance = full_name[0];
} else {
- strcpy(buf, instance);
+ strncpy(buf, instance, sizeof(buf));
+ buf[sizeof(buf) - 1] = '\0';
retval = krb5_get_realm_domain(context, realm, &domain);
if (retval)
return retval;
@@ -242,8 +307,8 @@ krb5_425_conv_principal(context, name, instance, realm, princ)
for (cp = domain; *cp; cp++)
if (isupper(*cp))
*cp = tolower(*cp);
- strcat(buf, ".");
- strcat(buf, domain);
+ strncat(buf, ".", sizeof(buf) - 1 - strlen(buf));
+ strncat(buf, domain, sizeof(buf) - 1 - strlen(buf));
krb5_xfree(domain);
}
instance = buf;
@@ -254,6 +319,10 @@ krb5_425_conv_principal(context, name, instance, realm, princ)
not_service:
retval = krb5_build_principal(context, princ, strlen(realm), realm, name,
instance, 0);
+ profile_iterator_free (&iterator);
profile_free_list(full_name);
+ profile_free_list(v4realms);
+ profile_release_string (realm_name);
+ profile_release_string (dummy_value);
return retval;
}
diff --git a/src/lib/krb5/krb/get_creds.c b/src/lib/krb5/krb/get_creds.c
index 3bcaa0be2..6d764d329 100644
--- a/src/lib/krb5/krb/get_creds.c
+++ b/src/lib/krb5/krb/get_creds.c
@@ -102,6 +102,7 @@ krb5_get_credentials(context, options, ccache, in_creds, out_creds)
krb5_creds *ncreds;
krb5_creds **tgts;
krb5_flags fields;
+ int not_ktype;
retval = krb5_get_credentials_core(context, options, ccache,
in_creds, out_creds,
@@ -128,6 +129,11 @@ krb5_get_credentials(context, options, ccache, in_creds, out_creds)
|| options & KRB5_GC_CACHED)
return retval;
+ if (retval == KRB5_CC_NOT_KTYPE)
+ not_ktype = 1;
+ else
+ not_ktype = 0;
+
retval = krb5_get_cred_from_kdc(context, ccache, ncreds, out_creds, &tgts);
if (tgts) {
register int i = 0;
@@ -141,6 +147,21 @@ krb5_get_credentials(context, options, ccache, in_creds, out_creds)
}
krb5_free_tgt_creds(context, tgts);
}
+ /*
+ * Translate KRB5_CC_NOTFOUND if we previously got
+ * KRB5_CC_NOT_KTYPE from krb5_cc_retrieve_cred(), in order to
+ * handle the case where there is no TGT in the ccache and the
+ * input enctype didn't match. This handling is necessary because
+ * some callers, such as GSSAPI, iterate through enctypes and
+ * KRB5_CC_NOTFOUND passed through from the
+ * krb5_get_cred_from_kdc() is semantically incorrect, since the
+ * actual failure was the non-existence of a ticket of the correct
+ * enctype rather than the missing TGT.
+ */
+ if ((retval == KRB5_CC_NOTFOUND || retval == KRB5_CC_NOT_KTYPE)
+ && not_ktype)
+ retval = KRB5_CC_NOT_KTYPE;
+
if (!retval)
retval = krb5_cc_store_cred(context, ccache, *out_creds);
return retval;
diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
index 9686f578a..298f1528f 100644
--- a/src/lib/krb5/krb/get_in_tkt.c
+++ b/src/lib/krb5/krb/get_in_tkt.c
@@ -457,12 +457,35 @@ krb5_get_in_tkt(context, options, addrs, ktypes, ptypes, key_proc, keyseed,
request.from = creds->times.starttime;
request.till = creds->times.endtime;
request.rtime = creds->times.renew_till;
- if (ktypes)
- request.ktype = ktypes;
- else
- if ((retval = krb5_get_default_in_tkt_ktypes(context, &request.ktype)))
- goto cleanup;
+ if ((retval = krb5_get_default_in_tkt_ktypes(context, &request.ktype)))
+ goto cleanup;
for (request.nktypes = 0;request.ktype[request.nktypes];request.nktypes++);
+ if (ktypes) {
+ int i, req, next = 0;
+ for (req = 0; ktypes[req]; req++) {
+ if (ktypes[req] == request.ktype[next]) {
+ next++;
+ continue;
+ }
+ for (i = next + 1; i < request.nktypes; i++)
+ if (ktypes[req] == request.ktype[i]) {
+ /* Found the enctype we want, but not in the
+ position we want. Move it, but keep the old
+ one from the desired slot around in case it's
+ later in our requested-ktypes list. */
+ krb5_enctype t;
+ t = request.ktype[next];
+ request.ktype[next] = request.ktype[i];
+ request.ktype[i] = t;
+ next++;
+ break;
+ }
+ /* If we didn't find it, don't do anything special, just
+ drop it. */
+ }
+ request.ktype[next] = 0;
+ request.nktypes = next;
+ }
request.authorization_data.ciphertext.length = 0;
request.authorization_data.ciphertext.data = 0;
request.unenc_authdata = 0;
@@ -538,7 +561,7 @@ krb5_get_in_tkt(context, options, addrs, ktypes, ptypes, key_proc, keyseed,
goto cleanup;
cleanup:
- if (!ktypes && request.ktype)
+ if (request.ktype)
free(request.ktype);
if (!addrs && request.addresses)
krb5_free_addresses(context, request.addresses);
diff --git a/src/lib/krb5/krb/init_ctx.c b/src/lib/krb5/krb/init_ctx.c
index e2eccc402..c10c6f7e2 100644
--- a/src/lib/krb5/krb/init_ctx.c
+++ b/src/lib/krb5/krb/init_ctx.c
@@ -1,7 +1,7 @@
/*
* lib/krb5/krb/init_ctx.c
*
- * Copyright 1994 by the Massachusetts Institute of Technology.
+ * Copyright 1994,1999,2000 by the Massachusetts Institute of Technology.
* All Rights Reserved.
*
* Export of this software from the United States of America may
@@ -84,7 +84,10 @@ init_common (context, secure)
{
krb5_context ctx = 0;
krb5_error_code retval;
- krb5_timestamp now;
+ struct {
+ krb5_int32 now, now_usec;
+ long pid;
+ } seed_data;
krb5_data seed;
int tmp;
@@ -129,10 +132,11 @@ init_common (context, secure)
goto cleanup;
/* initialize the prng (not well, but passable) */
- if ((retval = krb5_timeofday(ctx, &now)))
+ if ((retval = krb5_crypto_us_timeofday(&seed_data.now, &seed_data.now_usec)))
goto cleanup;
- seed.length = sizeof(now);
- seed.data = (char *) &now;
+ seed_data.pid = getpid ();
+ seed.length = sizeof(seed_data);
+ seed.data = (char *) &seed_data;
if ((retval = krb5_c_random_seed(ctx, &seed)))
goto cleanup;
@@ -281,7 +285,7 @@ get_profile_etype_list(context, ktypes, profstr, ctx_count, ctx_list)
{
krb5_enctype *old_ktypes;
- if (context->in_tkt_ktype_count) {
+ if (ctx_count) {
/* application-set defaults */
if ((old_ktypes =
(krb5_enctype *)malloc(sizeof(krb5_enctype) *
@@ -396,13 +400,23 @@ krb5_set_default_tgs_ktypes(context, ktypes)
}
if (context->tgs_ktypes)
- free(context->tgs_ktypes);
+ krb5_free_ktypes(context, context->tgs_ktypes);
context->tgs_ktypes = new_ktypes;
context->tgs_ktype_count = i;
return 0;
}
+void
+KRB5_CALLCONV
+krb5_free_ktypes (context, val)
+ krb5_context context;
+ krb5_enctype FAR *val;
+{
+ free (val);
+}
+
krb5_error_code
+KRB5_CALLCONV
krb5_get_tgs_ktypes(context, princ, ktypes)
krb5_context context;
krb5_const_principal princ;
@@ -441,7 +455,7 @@ krb5_is_permitted_enctype(context, etype)
if (*ptr == etype)
ret = 1;
- krb5_xfree(list);
+ krb5_free_ktypes (context, list);
return(ret);
}
diff --git a/src/lib/krb5/krb/kfree.c b/src/lib/krb5/krb/kfree.c
index 24d8aaff9..8e57f8391 100644
--- a/src/lib/krb5/krb/kfree.c
+++ b/src/lib/krb5/krb/kfree.c
@@ -36,7 +36,6 @@ krb5_free_address(context, val)
if (val->contents)
krb5_xfree(val->contents);
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -52,7 +51,6 @@ krb5_free_addresses(context, val)
krb5_xfree(*temp);
}
krb5_xfree(val);
- return;
}
@@ -64,7 +62,6 @@ krb5_free_ap_rep(context, val)
if (val->enc_part.ciphertext.data)
krb5_xfree(val->enc_part.ciphertext.data);
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -77,7 +74,6 @@ krb5_free_ap_req(context, val)
if (val->authenticator.ciphertext.data)
krb5_xfree(val->authenticator.ciphertext.data);
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -88,7 +84,6 @@ krb5_free_ap_rep_enc_part(context, val)
if (val->subkey)
krb5_free_keyblock(context, val->subkey);
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -96,15 +91,22 @@ krb5_free_authenticator_contents(context, val)
krb5_context context;
krb5_authenticator FAR *val;
{
- if (val->checksum)
+ if (val->checksum) {
krb5_free_checksum(context, val->checksum);
- if (val->client)
+ val->checksum = 0;
+ }
+ if (val->client) {
krb5_free_principal(context, val->client);
- if (val->subkey)
+ val->client = 0;
+ }
+ if (val->subkey) {
krb5_free_keyblock(context, val->subkey);
- if (val->authorization_data)
- krb5_free_authdata(context, val->authorization_data);
- return;
+ val->subkey = 0;
+ }
+ if (val->authorization_data) {
+ krb5_free_authdata(context, val->authorization_data);
+ val->authorization_data = 0;
+ }
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -120,7 +122,6 @@ krb5_free_authdata(context, val)
krb5_xfree(*temp);
}
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -128,16 +129,8 @@ krb5_free_authenticator(context, val)
krb5_context context;
krb5_authenticator FAR *val;
{
- if (val->checksum)
- krb5_free_checksum(context, val->checksum);
- if (val->client)
- krb5_free_principal(context, val->client);
- if (val->subkey)
- krb5_free_keyblock(context, val->subkey);
- if (val->authorization_data)
- krb5_free_authdata(context, val->authorization_data);
+ krb5_free_authenticator_contents(context, val);
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -145,10 +138,8 @@ krb5_free_checksum(context, val)
krb5_context context;
register krb5_checksum *val;
{
- if (val->contents)
- krb5_xfree(val->contents);
+ krb5_free_checksum_contents(context, val);
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -156,9 +147,10 @@ krb5_free_checksum_contents(context, val)
krb5_context context;
register krb5_checksum *val;
{
- if (val->contents)
+ if (val->contents) {
krb5_xfree(val->contents);
- return;
+ val->contents = 0;
+ }
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -171,7 +163,6 @@ krb5_free_cred(context, val)
if (val->enc_part.ciphertext.data)
krb5_xfree(val->enc_part.ciphertext.data);
krb5_xfree(val);
- return;
}
/*
@@ -184,23 +175,35 @@ krb5_free_cred_contents(context, val)
krb5_context context;
krb5_creds FAR *val;
{
- if (val->client)
+ if (val->client) {
krb5_free_principal(context, val->client);
- if (val->server)
+ val->client = 0;
+ }
+ if (val->server) {
krb5_free_principal(context, val->server);
+ val->server = 0;
+ }
if (val->keyblock.contents) {
memset((char *)val->keyblock.contents, 0, val->keyblock.length);
krb5_xfree(val->keyblock.contents);
+ val->keyblock.contents = 0;
}
- if (val->ticket.data)
+ if (val->ticket.data) {
krb5_xfree(val->ticket.data);
- if (val->second_ticket.data)
+ val->ticket.data = 0;
+ }
+ if (val->second_ticket.data) {
krb5_xfree(val->second_ticket.data);
- if (val->addresses)
+ val->second_ticket.data = 0;
+ }
+ if (val->addresses) {
krb5_free_addresses(context, val->addresses);
- if (val->authdata)
+ val->addresses = 0;
+ }
+ if (val->authdata) {
krb5_free_authdata(context, val->authdata);
- return;
+ val->authdata = 0;
+ }
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -210,10 +213,14 @@ krb5_free_cred_enc_part(context, val)
{
register krb5_cred_info **temp;
- if (val->r_address)
- krb5_free_address(context, val->r_address);
- if (val->s_address)
- krb5_free_address(context, val->s_address);
+ if (val->r_address) {
+ krb5_free_address(context, val->r_address);
+ val->r_address = 0;
+ }
+ if (val->s_address) {
+ krb5_free_address(context, val->s_address);
+ val->s_address = 0;
+ }
if (val->ticket_info) {
for (temp = val->ticket_info; *temp; temp++) {
@@ -228,8 +235,8 @@ krb5_free_cred_enc_part(context, val)
krb5_xfree((*temp));
}
krb5_xfree(val->ticket_info);
+ val->ticket_info = 0;
}
- return;
}
@@ -240,7 +247,6 @@ krb5_free_creds(context, val)
{
krb5_free_cred_contents(context, val);
krb5_xfree(val);
- return;
}
@@ -252,7 +258,6 @@ krb5_free_data(context, val)
if (val->data)
krb5_xfree(val->data);
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -260,9 +265,10 @@ krb5_free_data_contents(context, val)
krb5_context context;
krb5_data FAR * val;
{
- if (val->data)
+ if (val->data) {
krb5_xfree(val->data);
- return;
+ val->data = 0;
+ }
}
void krb5_free_etype_info(context, info)
@@ -294,7 +300,6 @@ krb5_free_enc_kdc_rep_part(context, val)
if (val->caddrs)
krb5_free_addresses(context, val->caddrs);
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -313,7 +318,6 @@ krb5_free_enc_tkt_part(context, val)
if (val->authorization_data)
krb5_free_authdata(context, val->authorization_data);
krb5_xfree(val);
- return;
}
@@ -331,7 +335,6 @@ krb5_free_error(context, val)
if (val->e_data.data)
krb5_xfree(val->e_data.data);
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -350,7 +353,6 @@ krb5_free_kdc_rep(context, val)
if (val->enc_part2)
krb5_free_enc_kdc_rep_part(context, val->enc_part2);
krb5_xfree(val);
- return;
}
@@ -376,7 +378,6 @@ krb5_free_kdc_req(context, val)
if (val->second_ticket)
krb5_free_tickets(context, val->second_ticket);
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -387,8 +388,8 @@ krb5_free_keyblock_contents(context, key)
if (key->contents) {
memset(key->contents, 0, key->length);
krb5_xfree(key->contents);
+ key->contents = 0;
}
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -398,7 +399,6 @@ krb5_free_keyblock(context, val)
{
krb5_free_keyblock_contents(context, val);
krb5_xfree(val);
- return;
}
@@ -413,7 +413,6 @@ krb5_free_last_req(context, val)
for (temp = val; *temp; temp++)
krb5_xfree(*temp);
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -429,7 +428,6 @@ krb5_free_pa_data(context, val)
krb5_xfree(*temp);
}
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -451,7 +449,6 @@ krb5_free_principal(context, val)
if (val->realm.data)
krb5_xfree(val->realm.data);
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -462,7 +459,6 @@ krb5_free_priv(context, val)
if (val->enc_part.ciphertext.data)
krb5_xfree(val->enc_part.ciphertext.data);
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -477,7 +473,6 @@ krb5_free_priv_enc_part(context, val)
if (val->s_address)
krb5_free_address(context, val->s_address);
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -488,7 +483,6 @@ krb5_free_pwd_data(context, val)
if (val->element)
krb5_free_pwd_sequences(context, val->element);
krb5_xfree(val);
- return;
}
@@ -497,11 +491,14 @@ krb5_free_pwd_sequences(context, val)
krb5_context context;
passwd_phrase_element FAR * FAR *val;
{
- if ((*val)->passwd)
+ if ((*val)->passwd) {
krb5_xfree((*val)->passwd);
- if ((*val)->phrase)
+ (*val)->passwd = 0;
+ }
+ if ((*val)->phrase) {
krb5_xfree((*val)->phrase);
- return;
+ (*val)->phrase = 0;
+ }
}
@@ -519,7 +516,6 @@ krb5_free_safe(context, val)
if (val->checksum)
krb5_free_checksum(context, val->checksum);
krb5_xfree(val);
- return;
}
@@ -535,7 +531,6 @@ krb5_free_ticket(context, val)
if (val->enc_part2)
krb5_free_enc_tkt_part(context, val->enc_part2);
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -548,7 +543,6 @@ krb5_free_tickets(context, val)
for (temp = val; *temp; temp++)
krb5_free_ticket(context, *temp);
krb5_xfree(val);
- return;
}
@@ -573,7 +567,6 @@ krb5_free_tkt_authent(context, val)
if (val->authenticator)
krb5_free_authenticator(context, val->authenticator);
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -583,7 +576,6 @@ krb5_free_unparsed_name(context, val)
{
if (val)
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -612,8 +604,10 @@ krb5_free_sam_challenge_contents(krb5_context ctx, krb5_sam_challenge FAR *sc)
krb5_free_data_contents(ctx, &sc->sam_response_prompt);
if (sc->sam_pk_for_sad.data)
krb5_free_data_contents(ctx, &sc->sam_pk_for_sad);
- if (sc->sam_cksum.contents)
+ if (sc->sam_cksum.contents) {
krb5_xfree(sc->sam_cksum.contents);
+ sc->sam_cksum.contents = 0;
+ }
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -656,8 +650,10 @@ krb5_free_predicted_sam_response_contents(krb5_context ctx,
return;
if (psr->sam_key.contents)
krb5_free_keyblock_contents(ctx, &psr->sam_key);
- if (psr->client)
+ if (psr->client) {
krb5_free_principal(ctx, psr->client);
+ psr->client = 0;
+ }
if (psr->msd.data)
krb5_free_data_contents(ctx, &psr->msd);
}
@@ -689,4 +685,3 @@ krb5_free_pa_enc_ts(krb5_context ctx, krb5_pa_enc_ts FAR *pa_enc_ts)
return;
krb5_xfree(pa_enc_ts);
}
-
diff --git a/src/lib/krb5/krb/mk_priv.c b/src/lib/krb5/krb/mk_priv.c
index 768581750..d72f6b2ac 100644
--- a/src/lib/krb5/krb/mk_priv.c
+++ b/src/lib/krb5/krb/mk_priv.c
@@ -93,14 +93,6 @@ krb5_mk_priv_basic(context, userdata, keyblock, replaydata, local_addr,
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 - blocksize),
- blocksize);
-
if ((retval = encode_krb5_priv(&privmsg, &scratch2)))
goto clean_encpart;
diff --git a/src/lib/krb5/krb/mk_req_ext.c b/src/lib/krb5/krb/mk_req_ext.c
index a8b20ebcb..88daab567 100644
--- a/src/lib/krb5/krb/mk_req_ext.c
+++ b/src/lib/krb5/krb/mk_req_ext.c
@@ -126,10 +126,24 @@ krb5_mk_req_extended(context, auth_context, ap_req_options, in_data, in_creds,
/* generate subkey if needed */
- if ((ap_req_options & AP_OPTS_USE_SUBKEY)&&(!(*auth_context)->local_subkey))
+ if ((ap_req_options & AP_OPTS_USE_SUBKEY)&&(!(*auth_context)->local_subkey)) {
+ /* Provide some more fodder for random number code.
+ This isn't strong cryptographically; the point here is not
+ to guarantee randomness, but to make it less likely that multiple
+ sessions could pick the same subkey. */
+ struct {
+ krb5_int32 sec, usec;
+ } rnd_data;
+ krb5_data d;
+ krb5_crypto_us_timeofday (&rnd_data.sec, &rnd_data.usec);
+ d.length = sizeof (rnd_data);
+ d.data = (char *) &rnd_data;
+ (void) krb5_c_random_seed (context, &d);
+
if ((retval = krb5_generate_subkey(context, &(in_creds)->keyblock,
&(*auth_context)->local_subkey)))
goto cleanup;
+ }
if (in_data) {
if ((*auth_context)->req_cksumtype == 0x8003) {
diff --git a/src/lib/krb5/krb/rd_priv.c b/src/lib/krb5/krb/rd_priv.c
index 9629b0c19..ab6a5312d 100644
--- a/src/lib/krb5/krb/rd_priv.c
+++ b/src/lib/krb5/krb/rd_priv.c
@@ -101,13 +101,6 @@ krb5_rd_priv_basic(context, inbuf, keyblock, local_addr, remote_addr,
&privmsg->enc_part, &scratch)))
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 - blocksize),
- blocksize);
-
/* now decode the decrypted stuff */
if ((retval = decode_krb5_enc_priv_part(&scratch, &privmsg_enc_part)))
goto cleanup_scratch;
diff --git a/src/lib/krb5/krb/recvauth.c b/src/lib/krb5/krb/recvauth.c
index 3d5bce491..f74041c59 100644
--- a/src/lib/krb5/krb/recvauth.c
+++ b/src/lib/krb5/krb/recvauth.c
@@ -37,20 +37,18 @@
static char *sendauth_version = "KRB5_SENDAUTH_V1.0";
-KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
-krb5_recvauth(context, auth_context,
- /* IN */
- fd, appl_version, server, flags, keytab,
- /* OUT */
- ticket)
- krb5_context context;
- krb5_auth_context FAR * auth_context;
- krb5_pointer fd;
- char FAR * appl_version;
- krb5_principal server;
- krb5_int32 flags;
- krb5_keytab keytab;
- krb5_ticket FAR * FAR * ticket;
+krb5_error_code
+recvauth_common(krb5_context context,
+ krb5_auth_context FAR * auth_context,
+ /* IN */
+ krb5_pointer fd,
+ char FAR *appl_version,
+ krb5_principal server,
+ krb5_int32 flags,
+ krb5_keytab keytab,
+ /* OUT */
+ krb5_ticket FAR * FAR * ticket,
+ krb5_data FAR *version)
{
krb5_auth_context new_auth_context;
krb5_flags ap_option;
@@ -91,12 +89,15 @@ krb5_recvauth(context, auth_context,
*/
if ((retval = krb5_read_message(context, fd, &inbuf)))
return(retval);
- if (strcmp(inbuf.data, appl_version)) {
+ if (appl_version && strcmp(inbuf.data, appl_version)) {
krb5_xfree(inbuf.data);
if (!problem)
problem = KRB5_SENDAUTH_BADAPPLVERS;
}
- krb5_xfree(inbuf.data);
+ if (version && !problem)
+ *version = inbuf;
+ else
+ krb5_xfree(inbuf.data);
/*
* OK, now check the problem variable. If it's zero, we're
* fine and we can continue. Otherwise, we have to signal an
@@ -243,3 +244,38 @@ cleanup:;
}
return retval;
}
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+krb5_recvauth(context, auth_context,
+ /* IN */
+ fd, appl_version, server, flags, keytab,
+ /* OUT */
+ ticket)
+ krb5_context context;
+ krb5_auth_context FAR * auth_context;
+ krb5_pointer fd;
+ char FAR * appl_version;
+ krb5_principal server;
+ krb5_int32 flags;
+ krb5_keytab keytab;
+ krb5_ticket FAR * FAR * ticket;
+{
+ return recvauth_common (context, auth_context, fd, appl_version,
+ server, flags, keytab, ticket, 0);
+}
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+krb5_recvauth_version(krb5_context context,
+ krb5_auth_context FAR *auth_context,
+ /* IN */
+ krb5_pointer fd,
+ krb5_principal server,
+ krb5_int32 flags,
+ krb5_keytab keytab,
+ /* OUT */
+ krb5_ticket FAR * FAR *ticket,
+ krb5_data FAR *version)
+{
+ return recvauth_common (context, auth_context, fd, 0,
+ server, flags, keytab, ticket, version);
+}
diff --git a/src/lib/krb5/krb/sendauth.c b/src/lib/krb5/krb/sendauth.c
index 1e6b726a2..b19afdb7e 100644
--- a/src/lib/krb5/krb/sendauth.c
+++ b/src/lib/krb5/krb/sendauth.c
@@ -152,9 +152,32 @@ krb5_sendauth(context, auth_context,
credsp = in_creds;
}
- if ((retval = krb5_mk_req_extended(context, auth_context, ap_req_options,
- in_data, credsp, &outbuf)))
- goto error_return;
+ if (ap_req_options & AP_OPTS_USE_SUBKEY) {
+ /* Provide some more fodder for random number code.
+ This isn't strong cryptographically; the point here is
+ not to guarantee randomness, but to make it less likely
+ that multiple sessions could pick the same subkey. */
+ char rnd_data[1024];
+ size_t len;
+ krb5_data d;
+ d.length = sizeof (rnd_data);
+ d.data = rnd_data;
+ len = sizeof (rnd_data);
+ if (getpeername (*(int*)fd, (struct sockaddr *) rnd_data, &len) == 0) {
+ d.length = len;
+ (void) krb5_c_random_seed (context, &d);
+ }
+ len = sizeof (rnd_data);
+ if (getsockname (*(int*)fd, (struct sockaddr *) rnd_data, &len) == 0) {
+ d.length = len;
+ (void) krb5_c_random_seed (context, &d);
+ }
+ }
+
+ if ((retval = krb5_mk_req_extended(context, auth_context,
+ ap_req_options, in_data, credsp,
+ &outbuf)))
+ goto error_return;
/*
* First write the length of the AP_REQ message, then write
diff --git a/src/lib/krb5/krb/t_kerb.c b/src/lib/krb5/krb/t_kerb.c
index 2feef39dd..458015d1c 100644
--- a/src/lib/krb5/krb/t_kerb.c
+++ b/src/lib/krb5/krb/t_kerb.c
@@ -4,6 +4,7 @@
*/
#include "krb5.h"
+#include "kerberosIV/krb.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -56,6 +57,32 @@ void test_425_conv_principal(ctx, name, inst, realm)
krb5_free_principal(ctx, princ);
}
+void test_524_conv_principal(ctx, name)
+ krb5_context ctx;
+ char *name;
+{
+ krb5_principal princ = 0;
+ krb5_error_code retval;
+ char aname[ANAME_SZ+1], inst[INST_SZ+1], realm[REALM_SZ+1];
+
+ aname[ANAME_SZ] = inst[INST_SZ] = realm[REALM_SZ] = 0;
+ retval = krb5_parse_name(ctx, name, &princ);
+ if (retval) {
+ com_err("krb5_parse_name", retval, 0);
+ goto fail;
+ }
+ retval = krb5_524_conv_principal(ctx, princ, aname, inst, realm);
+ if (retval) {
+ com_err("krb5_524_conv_principal", retval, 0);
+ goto fail;
+ }
+ printf("524_converted_principal(%s): '%s' '%s' '%s'\n",
+ name, aname, inst, realm);
+ fail:
+ if (princ)
+ krb5_free_principal (ctx, princ);
+}
+
void test_parse_name(ctx, name)
krb5_context ctx;
const char *name;
@@ -131,6 +158,7 @@ void usage(progname)
{
fprintf(stderr, "%s: Usage: %s 425_conv_principal <name> <inst> <realm\n",
progname, progname);
+ fprintf(stderr, "\t%s 524_conv_principal <name>\n", progname);
fprintf(stderr, "\t%s parse_name <name>\n", progname);
fprintf(stderr, "\t%s set_realm <name> <realm>\n", progname);
fprintf(stderr, "\t%s string_to_timestamp <time>\n", progname);
@@ -186,6 +214,10 @@ main(argc, argv)
argc--; argv++;
if (!argc) usage(progname);
test_string_to_timestamp(ctx, *argv);
+ } else if (strcmp(*argv, "524_conv_principal") == 0) {
+ argc--; argv++;
+ if (!argc) usage(progname);
+ test_524_conv_principal(ctx, *argv);
}
else
usage(progname);
diff --git a/src/lib/krb5/krb/t_krb5.conf b/src/lib/krb5/krb/t_krb5.conf
index 5882d9770..8d7a4d975 100644
--- a/src/lib/krb5/krb/t_krb5.conf
+++ b/src/lib/krb5/krb/t_krb5.conf
@@ -19,6 +19,12 @@
kdc = KERBEROS.CYGNUS.COM
admin_server = KERBEROS.MIT.EDU
}
+ stanford.edu = {
+ v4_realm = IR.STANFORD.EDU
+ }
+ LONGNAMES.COM = {
+ v4_realm = SOME-REALLY-LONG-REALM-NAME-V4-CANNOT-HANDLE.COM
+ }
[domain_realm]
.mit.edu = ATHENA.MIT.EDU
diff --git a/src/lib/krb5/krb/t_ref_kerb.out b/src/lib/krb5/krb/t_ref_kerb.out
index 942394453..08a53343f 100644
--- a/src/lib/krb5/krb/t_ref_kerb.out
+++ b/src/lib/krb5/krb/t_ref_kerb.out
@@ -14,4 +14,6 @@ parsed (and unparsed) principal(\/slash/\@atsign/octa\/thorpe@\/slash\@at\/sign)
425_converted principal(rcmd, uunet, UU.NET): 'host/uunet.uu.net@UU.NET'
425_converted principal(zephyr, zephyr, ATHENA.MIT.EDU): 'zephyr/zephyr@ATHENA.MIT.EDU'
425_converted principal(kadmin, ATHENA.MIT.EDU, ATHENA.MIT.EDU): 'kadmin/ATHENA.MIT.EDU@ATHENA.MIT.EDU'
+524_converted_principal(host/e40-po.mit.edu@ATHENA.MIT.EDU): 'rcmd' 'e40-po' 'ATHENA.MIT.EDU'
+524_converted_principal(host/foobar.stanford.edu@stanford.edu): 'rcmd' 'foobar' 'IR.STANFORD.EDU'
old principal: marc@MIT.EDU, modified principal: marc@CYGNUS.COM
diff --git a/src/lib/krb5/os/ChangeLog b/src/lib/krb5/os/ChangeLog
index adf1c5d27..33f80180c 100644
--- a/src/lib/krb5/os/ChangeLog
+++ b/src/lib/krb5/os/ChangeLog
@@ -1,3 +1,50 @@
+2000-06-23 Miro Jurisic <meeroh@mit.edu>
+
+ * init_os_ctx.c (os_get_default_config_files): Return ENOENT when
+ file is not found on MacOS (not ENFILE). Use Kerberos Preferences
+ library to locate the config files on Mac OS. Eliminated some
+ dead code.
+
+2000-06-23 Nalin Dahyabhai <nalin@redhat.com>
+
+ * an_to_ln.c (do_replacement): Don't overflow buffers "in" or "out".
+ * hst_realm.c (krb5_try_realm_txt_rr): Don't overfill "host" when
+ malformed DNS responses are received.
+
+ * ccdefname.c (get_from_os): Don't overflow buffer "name_buf".
+ * kuserok.c (krb5_kuserok): Don't overflow buffer "pbuf".
+
+2000-06-23 Ken Raeburn <raeburn@mit.edu>
+
+ * localaddr.c: Include stddef.h.
+ (foreach_localaddr): Check each address against previously used
+ addresses, and skip duplicates, in case multiple interfaces have
+ the same address. If called functions fail, drop out of loop and
+ return nonzero. Use SIOCGSIZIFCONF ioctl if available to get the
+ buffer size needed for SIOCGIFCONF, and skip the silly heuristics
+ if it returns a reasonable value.
+ (krb5_os_localaddr): Increment count of addresses to include null
+ pointer terminator. Delete check for zero count.
+
+ * locate_kdc.c (maybe_use_dns): Renamed from _krb5_use_dns. Now
+ takes an arg to indicate a key to look up in krb5.conf, falling
+ back to "dns_fallback", and an arg indicating the default value if
+ no config file entries match.
+ (_krb5_use_dns_realm): New routine; use "dns_lookup_realm" and
+ KRB5_DNS_LOOKUP_REALM setting.
+ (_krb5_use_dns_kdc): New routine; use "dns_lookup_kdc" and
+ KRB5_DNS_LOOKUP_KDC.
+ (krb5_locate_kdc): Call _krb5_use_dns_kdc.
+ * changepw.c (krb5_locate_kpasswd): Call _krb5_use_dns_kdc.
+ * def_realm.c (krb5_get_default_realm): Call _krb5_use_dns_realm.
+ * hst_realm.c (krb5_get_host_realm): Call _krb5_use_dns_realm.
+
+2000-06-23 Alexandra Ellwood <lxs@mit.edu>
+
+ * ccdefname.c: Added support to store a krb5_principal in the os_context
+ along with the default ccache name (if known, this principal is the same
+ as the last time we looked at the ccache.
+
2000-05-09 Alexandra Ellwood <lxs@mit.edu>
*localaddr.c: Fixed the local_addr_fallback_kludge so that it actually does something.
diff --git a/src/lib/krb5/os/an_to_ln.c b/src/lib/krb5/os/an_to_ln.c
index 3c721fb87..02e68fb04 100644
--- a/src/lib/krb5/os/an_to_ln.c
+++ b/src/lib/krb5/os/an_to_ln.c
@@ -298,15 +298,15 @@ do_replacement(regexp, repl, doall, in, out)
strncpy(op, cp, match_match.rm_so);
op += match_match.rm_so;
}
- strcpy(op, repl);
- op += strlen(repl);
+ strncpy(op, repl, MAX_FORMAT_BUFFER - 1 - (op - out));
+ op += strlen(op);
cp += match_match.rm_eo;
if (!doall)
- strcpy(op, cp);
+ strncpy(op, cp, MAX_FORMAT_BUFFER - 1 - (op - out));
matched = 1;
}
else {
- strcpy(op, cp);
+ strncpy(op, cp, MAX_FORMAT_BUFFER - 1 - (op - out));
matched = 0;
}
} while (doall && matched);
@@ -333,20 +333,20 @@ do_replacement(regexp, repl, doall, in, out)
strncpy(op, cp, sdispl);
op += sdispl;
}
- strcpy(op, repl);
+ strncpy(op, repl, MAX_FORMAT_BUFFER - 1 - (op - out));
op += strlen(repl);
cp += edispl;
if (!doall)
- strcpy(op, cp);
+ strncpy(op, cp, MAX_FORMAT_BUFFER - 1 - (op - out));
matched = 1;
}
else {
- strcpy(op, cp);
+ strncpy(op, cp, MAX_FORMAT_BUFFER - 1 - (op - out));
matched = 0;
}
} while (doall && matched);
#else /* HAVE_REGEXP_H */
- strcpy(out, in);
+ memcpy(out, in, MAX_FORMAT_BUFFER);
#endif /* HAVE_REGCOMP */
}
@@ -379,7 +379,8 @@ aname_replacer(string, contextp, result)
* Prime the buffers. Copy input string to "out" to simulate it
* being the result of an initial iteration.
*/
- strcpy(out, string);
+ strncpy(out, string, MAX_FORMAT_BUFFER - 1);
+ out[MAX_FORMAT_BUFFER - 1] = '\0';
in[0] = '\0';
kret = 0;
/*
@@ -421,6 +422,7 @@ aname_replacer(string, contextp, result)
out = ep;
/* Do the replacemenbt */
+ memset(out, '\0', MAX_FORMAT_BUFFER);
do_replacement(rule, repl, doglobal, in, out);
free(rule);
free(repl);
diff --git a/src/lib/krb5/os/ccdefname.c b/src/lib/krb5/os/ccdefname.c
index 3bc2546cb..6b00e5286 100644
--- a/src/lib/krb5/os/ccdefname.c
+++ b/src/lib/krb5/os/ccdefname.c
@@ -160,7 +160,7 @@ static krb5_error_code get_from_os(char *name_buf, int name_size)
if (get_from_registry_indirect(name_buf, name_size) != 0)
return 0;
- strncpy(name_buf, prefix, name_size);
+ strncpy(name_buf, prefix, name_size - 1);
name_buf[name_size - 1] = 0;
size = name_size - strlen(prefix);
if (size > 0)
diff --git a/src/lib/krb5/os/changepw.c b/src/lib/krb5/os/changepw.c
index 597351619..575866e2a 100644
--- a/src/lib/krb5/os/changepw.c
+++ b/src/lib/krb5/os/changepw.c
@@ -66,10 +66,10 @@ krb5_locate_kpasswd(context, realm, addr_pp, naddrs)
* We always try the local file first
*/
- code = krb5_locate_srv_conf( context, realm, "kpasswd_server",
+ code = krb5_locate_srv_conf(context, realm, "kpasswd_server",
addr_pp, naddrs, 0);
if (code) {
- code = krb5_locate_srv_conf( context, realm, "admin_server",
+ code = krb5_locate_srv_conf(context, realm, "admin_server",
addr_pp, naddrs, 0);
if ( !code ) {
/* success with admin_server but now we need to change the port */
@@ -83,7 +83,7 @@ krb5_locate_kpasswd(context, realm, addr_pp, naddrs)
#ifdef KRB5_DNS_LOOKUP
if (code) {
- int use_dns = _krb5_use_dns(context);
+ int use_dns = _krb5_use_dns_kdc(context);
if ( use_dns ) {
code = krb5_locate_srv_dns(realm, "_kpasswd", "_udp",
addr_pp, naddrs);
diff --git a/src/lib/krb5/os/def_realm.c b/src/lib/krb5/os/def_realm.c
index d3c031f5b..d9bd017ad 100644
--- a/src/lib/krb5/os/def_realm.c
+++ b/src/lib/krb5/os/def_realm.c
@@ -104,7 +104,7 @@ krb5_get_default_realm(context, lrealm)
#ifdef KRB5_DNS_LOOKUP
if (context->default_realm == 0) {
- int use_dns = _krb5_use_dns(context);
+ int use_dns = _krb5_use_dns_realm(context);
if ( use_dns ) {
/*
* Since this didn't appear in our config file, try looking
diff --git a/src/lib/krb5/os/hst_realm.c b/src/lib/krb5/os/hst_realm.c
index 1e8923f4c..965a991c3 100644
--- a/src/lib/krb5/os/hst_realm.c
+++ b/src/lib/krb5/os/hst_realm.c
@@ -117,6 +117,8 @@ krb5_try_realm_txt_rr(prefix, name, realm)
*/
if (name == NULL || name[0] == '\0') {
+ if (strlen (prefix) >= sizeof(host)-1)
+ return KRB5_ERR_HOST_REALM_UNKNOWN;
strcpy(host,prefix);
} else {
if ( strlen(prefix) + strlen(name) + 3 > MAX_DNS_NAMELEN )
@@ -134,7 +136,7 @@ krb5_try_realm_txt_rr(prefix, name, realm)
*/
h = host + strlen (host);
- if (h > host && h[-1] != '.')
+ if ((h > host) && (h[-1] != '.') && ((h - host + 1) < sizeof(host)))
strcpy (h, ".");
}
size = res_search(host, C_IN, T_TXT, answer.bytes, sizeof(answer.bytes));
@@ -312,7 +314,7 @@ krb5_get_host_realm(context, host, realmsp)
#ifdef KRB5_DNS_LOOKUP
if (realm == (char *)NULL) {
- int use_dns = _krb5_use_dns(context);
+ int use_dns = _krb5_use_dns_realm(context);
if ( use_dns ) {
/*
* Since this didn't appear in our config file, try looking
diff --git a/src/lib/krb5/os/init_os_ctx.c b/src/lib/krb5/os/init_os_ctx.c
index 5222e6af8..f59969714 100644
--- a/src/lib/krb5/os/init_os_ctx.c
+++ b/src/lib/krb5/os/init_os_ctx.c
@@ -30,22 +30,7 @@
#include "k5-int.h"
#ifdef macintosh
-OSErr
-GetMacProfileFileSpec (FSSpec* outFileSpec, StringPtr inName, UInt32 whichFolder)
-{
- OSErr err;
-
-
-
- err = FindFolder (kOnSystemDisk, whichFolder, kCreateFolder,
- &(outFileSpec -> vRefNum) , &(outFileSpec -> parID));
-
- if (err == noErr) {
- BlockMoveData (inName, &(outFileSpec -> name), strlen (inName) + 1);
- }
-
- return err;
-}
+#include <PreferencesLib.h>
#endif /* macintosh */
#if defined(_MSDOS) || defined(_WIN32)
@@ -204,42 +189,94 @@ os_get_default_config_files(pfiles, secure)
{
profile_filespec_t* files;
#ifdef macintosh
- files = malloc(7 * sizeof(FSSpec));
-
- if (files != 0) {
- OSErr err = GetMacProfileFileSpec(&(files [3]), "\pKerberos Preferences", kApplicationSupportFolderType);
- if (err == noErr) {
- err = GetMacProfileFileSpec( &(files [4]), "\pkrb5.ini", kApplicationSupportFolderType);
- }
- if (err == noErr) {
- err = GetMacProfileFileSpec( &(files [5]), "\pKerberos5 Configuration", kApplicationSupportFolderType);
- }
-
- if (err == noErr) {
- files[6].vRefNum = 0;
- files[6].parID = 0;
- files[6].name[0] = '\0';
- } else {
- files[3].vRefNum = 0;
- files[3].parID = 0;
- files[3].name[0] = '\0';
+ FSSpec* preferencesFiles = nil;
+ UInt32 numPreferencesFiles;
+ FSSpec* preferencesFilesToInit = nil;
+ UInt32 numPreferencesFilesToInit;
+ UInt32 i;
+ Boolean foundPreferences = false;
+ Boolean writtenPreferences = false;
+ SInt16 refNum = -1;
+ SInt32 length = 0;
+
+ OSErr err = KPGetListOfPreferencesFiles (
+ secure ? kpSystemPreferences : kpUserPreferences | kpSystemPreferences,
+ &preferencesFiles,
+ &numPreferencesFiles);
+
+ if (err == noErr) {
+ /* After we get the list of files, check whether any of them contain any useful information */
+ for (i = 0; i < numPreferencesFiles; i++) {
+ if (KPPreferencesFileIsReadable (&preferencesFiles [i]) == noErr) {
+ /* It's readable, check if it has anything in the data fork */
+ err = FSpOpenDF (&preferencesFiles [i], fsRdPerm, &refNum);
+ if (err == noErr) {
+ err = GetEOF (refNum, &length);
+ }
+
+ if (refNum != -1) {
+ FSClose (refNum);
+ }
+
+ if (length != 0) {
+ foundPreferences = true;
+ break;
+ }
+ }
}
- err = GetMacProfileFileSpec(&(files [0]), "\pKerberos Preferences", kPreferencesFolderType);
- if (err == noErr) {
- err = GetMacProfileFileSpec( &(files [1]), "\pkrb5.ini", kPreferencesFolderType);
- }
- if (err == noErr) {
- err = GetMacProfileFileSpec( &(files [2]), "\pKerberos5 Configuration", kPreferencesFolderType);
+ if (!foundPreferences) {
+ /* We found no profile data in any of those files; try to initialize one */
+ /* If we are running "secure" do not try to initialize preferences */
+ if (!secure) {
+ err = KPGetListOfPreferencesFiles (kpUserPreferences, &preferencesFilesToInit, &numPreferencesFilesToInit);
+ if (err == noErr) {
+ for (i = 0; i < numPreferencesFilesToInit; i++) {
+ if (KPPreferencesFileIsWritable (&preferencesFilesToInit [i]) == noErr) {
+ err = noErr;
+ /* If not readable, create it */
+ if (KPPreferencesFileIsReadable (&preferencesFilesToInit [i]) != noErr) {
+ err = KPCreatePreferencesFile (&preferencesFilesToInit [i]);
+ }
+ /* Initialize it */
+ if (err == noErr) {
+ err = KPInitializeWithDefaultKerberosLibraryPreferences (&preferencesFilesToInit [i]);
+ }
+ break;
+ }
+ }
+ }
+ }
}
+ }
+
+ if (err == noErr) {
+ files = malloc ((numPreferencesFiles + 1) * sizeof (FSSpec));
+ if (files == NULL)
+ err = memFullErr;
+ }
+
+ if (err == noErr) {
+ for (i = 0; i < numPreferencesFiles; i++) {
+ files [i] = preferencesFiles [i];
+ }
+
+ files [numPreferencesFiles].vRefNum = 0;
+ files [numPreferencesFiles].parID = 0;
+ files [numPreferencesFiles].name[0] = '\0';
+ }
+
+ if (preferencesFiles != nil)
+ KPFreeListOfPreferencesFiles (preferencesFiles);
+
+ if (preferencesFilesToInit != nil)
+ KPFreeListOfPreferencesFiles (preferencesFilesToInit);
- if (err != noErr) {
- free (files);
- return ENFILE;
- }
- } else {
+ if (err == memFullErr)
return ENOMEM;
- }
+ else if (err != noErr)
+ return ENOENT;
+
#else /* !macintosh */
#if defined(_MSDOS) || defined(_WIN32)
krb5_error_code retval = 0;
@@ -405,7 +442,7 @@ krb5_os_init_context(ctx)
os_ctx->os_flags = 0;
os_ctx->default_ccname = 0;
os_ctx->default_ccprincipal = 0;
-
+
krb5_cc_set_default_name(ctx, NULL);
retval = os_init_paths(ctx);
@@ -522,8 +559,8 @@ krb5_os_free_context(ctx)
if (os_ctx->default_ccname) {
free(os_ctx->default_ccname);
- os_ctx->default_ccname = 0;
- }
+ os_ctx->default_ccname = 0;
+ }
if (os_ctx->default_ccprincipal) {
krb5_free_principal (ctx, os_ctx->default_ccprincipal);
diff --git a/src/lib/krb5/os/kuserok.c b/src/lib/krb5/os/kuserok.c
index ef0803744..6d2adb126 100644
--- a/src/lib/krb5/os/kuserok.c
+++ b/src/lib/krb5/os/kuserok.c
@@ -80,8 +80,9 @@ krb5_kuserok(context, principal, luser)
if ((pwd = getpwnam(luser)) == NULL) {
return(FALSE);
}
- (void) strcpy(pbuf, pwd->pw_dir);
- (void) strcat(pbuf, "/.k5login");
+ (void) strncpy(pbuf, pwd->pw_dir, sizeof(pbuf) - 1);
+ pbuf[sizeof(pbuf) - 1] = '\0';
+ (void) strncat(pbuf, "/.k5login", sizeof(pbuf) - 1 - strlen(pbuf));
if (access(pbuf, F_OK)) { /* not accessible */
/*
diff --git a/src/lib/krb5/os/localaddr.c b/src/lib/krb5/os/localaddr.c
index f0f1a29ec..d5b46b664 100644
--- a/src/lib/krb5/os/localaddr.c
+++ b/src/lib/krb5/os/localaddr.c
@@ -1,7 +1,7 @@
/*
* lib/krb5/os/localaddr.c
*
- * Copyright 1990,1991 by the Massachusetts Institute of Technology.
+ * Copyright 1990,1991,2000 by the Massachusetts Institute of Technology.
* All Rights Reserved.
*
* Export of this software from the United States of America may
@@ -39,6 +39,7 @@
#include <sys/ioctl.h>
#include <sys/time.h>
#include <errno.h>
+#include <stddef.h>
/*
* The SIOCGIF* ioctls require a socket.
@@ -255,13 +256,17 @@ foreach_localaddr (data, pass1fn, betweenfn, pass2fn)
int (*betweenfn) (void *);
int (*pass2fn) (void *, struct sockaddr *);
{
- struct ifreq *ifr, ifreq;
+ struct ifreq *ifr, ifreq, *ifr2;
struct ifconf ifc;
- int s, code, n, i;
+ int s, code, n, i, j;
int est_if_count = 8, est_ifreq_size;
char *buf = 0;
size_t current_buf_size = 0;
-
+ int fail = 0;
+#ifdef SIOCGSIZIFCONF
+ int ifconfsize = -1;
+#endif
+
s = socket (USE_AF, USE_TYPE, USE_PROTO);
if (s < 0)
return SOCKET_ERRNO;
@@ -270,7 +275,15 @@ foreach_localaddr (data, pass1fn, betweenfn, pass2fn)
isn't big enough for an IPv6 or ethernet address. So add a
little more space. */
est_ifreq_size = sizeof (struct ifreq) + 8;
- current_buf_size = est_ifreq_size * est_if_count;
+#ifdef SIOCGSIZIFCONF
+ code = ioctl (s, SIOCGSIZIFCONF, &ifconfsize);
+ if (!code) {
+ current_buf_size = ifconfsize;
+ est_if_count = ifconfsize / est_ifreq_size;
+ }
+#endif
+ if (current_buf_size == 0)
+ current_buf_size = est_ifreq_size * est_if_count;
buf = malloc (current_buf_size);
ask_again:
@@ -289,7 +302,11 @@ foreach_localaddr (data, pass1fn, betweenfn, pass2fn)
the only indication we get, complicated by the fact that the
associated address may make the required storage a little
bigger than the size of an ifreq. */
- if (current_buf_size - ifc.ifc_len < sizeof (struct ifreq) + 40) {
+ if (current_buf_size - ifc.ifc_len < sizeof (struct ifreq) + 40
+#ifdef SIOCGSIZIFCONF
+ && ifconfsize <= 0
+#endif
+ ) {
int new_size;
char *newbuf;
@@ -312,26 +329,49 @@ foreach_localaddr (data, pass1fn, betweenfn, pass2fn)
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
-#ifdef IFF_LOOPBACK
- /* None of the current callers want loopback addresses. */
- || (ifreq.ifr_flags & IFF_LOOPBACK)
-#endif
- /* Ignore interfaces that are down. */
- || !(ifreq.ifr_flags & IFF_UP)) {
+ if (ioctl (s, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
+ skip:
/* mark for next pass */
ifr->ifr_name[0] = 0;
continue;
}
+#ifdef IFF_LOOPBACK
+ /* None of the current callers want loopback addresses. */
+ if (ifreq.ifr_flags & IFF_LOOPBACK)
+ goto skip;
+#endif
+ /* Ignore interfaces that are down. */
+ if (!(ifreq.ifr_flags & IFF_UP))
+ goto skip;
+
+ /* Make sure we didn't process this address already. */
+ for (j = 0; j < i; j += ifreq_size(*ifr2)) {
+ ifr2 = (struct ifreq *)((caddr_t) ifc.ifc_buf+j);
+ if (ifr2->ifr_name[0] == 0)
+ continue;
+ if (ifr2->ifr_addr.sa_family == ifr->ifr_addr.sa_family
+ && ifreq_size (*ifr) == ifreq_size (*ifr2)
+ /* Compare address info. If this isn't good enough --
+ i.e., if random padding bytes turn out to differ
+ when the addresses are the same -- then we'll have
+ to do it on a per address family basis. */
+ && !memcmp (&ifr2->ifr_addr.sa_data, &ifr->ifr_addr.sa_data,
+ (ifreq_size (*ifr)
+ - offsetof (struct ifreq, ifr_addr.sa_data))))
+ goto skip;
+ }
+
if ((*pass1fn) (data, &ifr->ifr_addr)) {
- abort ();
+ fail = 1;
+ goto punt;
}
}
if (betweenfn && (*betweenfn)(data)) {
- abort ();
+ fail = 1;
+ goto punt;
}
if (pass2fn)
@@ -343,13 +383,15 @@ foreach_localaddr (data, pass1fn, betweenfn, pass2fn)
continue;
if ((*pass2fn) (data, &ifr->ifr_addr)) {
- abort ();
+ fail = 1;
+ goto punt;
}
}
+ punt:
closesocket(s);
free (buf);
- return 0;
+ return fail;
}
@@ -376,10 +418,9 @@ krb5_os_localaddr(context, addr)
return r;
}
+ data.cur_idx++; /* null termination */
if (data.mem_err)
return ENOMEM;
- else if (data.cur_idx == 0)
- abort ();
else if (data.cur_idx == data.count)
*addr = data.addr_temp;
else {
diff --git a/src/lib/krb5/os/locate_kdc.c b/src/lib/krb5/os/locate_kdc.c
index 1139fb338..53f36d835 100644
--- a/src/lib/krb5/os/locate_kdc.c
+++ b/src/lib/krb5/os/locate_kdc.c
@@ -53,29 +53,57 @@
#define KPASSWD_PORTNAME "kpasswd"
#endif
-int
-_krb5_use_dns(context)
- krb5_context context;
+#if KRB5_DNS_LOOKUP_KDC
+#define DEFAULT_LOOKUP_KDC 1
+#else
+#define DEFAULT_LOOKUP_KDC 0
+#endif
+#if KRB5_DNS_LOOKUP_REALM
+#define DEFAULT_LOOKUP_REALM 1
+#else
+#define DEFAULT_LOOKUP_REALM 0
+#endif
+
+static int
+maybe_use_dns (context, name, defalt)
+ krb5_context context;
+ const char *name;
+ int defalt;
{
krb5_error_code code;
char * value = NULL;
int use_dns = 0;
code = profile_get_string(context->profile, "libdefaults",
- "dns_fallback", 0,
- context->profile_in_memory?"1":"0",
- &value);
+ name, 0, 0, &value);
+ if (value == 0 && code == 0)
+ code = profile_get_string(context->profile, "libdefaults",
+ "dns_fallback", 0, 0, &value);
if (code)
- return(code);
+ return defalt;
- if (value) {
- use_dns = _krb5_conf_boolean(value);
- profile_release_string(value);
- }
+ if (value == 0)
+ return defalt;
+ use_dns = _krb5_conf_boolean(value);
+ profile_release_string(value);
return use_dns;
}
+int
+_krb5_use_dns_kdc(context)
+ krb5_context context;
+{
+ return maybe_use_dns (context, "dns_lookup_kdc", DEFAULT_LOOKUP_KDC);
+}
+
+int
+_krb5_use_dns_realm(context)
+ krb5_context context;
+{
+ return maybe_use_dns (context, "dns_lookup_realm", DEFAULT_LOOKUP_REALM);
+}
+
#endif /* KRB5_DNS_LOOKUP */
/*
@@ -205,9 +233,9 @@ krb5_locate_srv_conf(context, realm, name, addr_pp, naddrs, get_masters)
addr_p = (struct sockaddr *)malloc (sizeof (struct sockaddr) * count);
if (addr_p == NULL) {
- if ( hostlist )
+ if (hostlist)
profile_free_list(hostlist);
- if ( masterlist )
+ if (masterlist)
profile_free_list(masterlist);
return ENOMEM;
}
@@ -281,9 +309,9 @@ krb5_locate_srv_conf(context, realm, name, addr_pp, naddrs, get_masters)
}
}
- if ( hostlist )
+ if (hostlist)
profile_free_list(hostlist);
- if ( masterlist )
+ if (masterlist)
profile_free_list(masterlist);
if (out == 0) { /* Couldn't resolve any KDC names */
@@ -582,11 +610,11 @@ krb5_locate_kdc(context, realm, addr_pp, naddrs, get_masters)
#ifdef KRB5_DNS_LOOKUP
if (code) {
- int use_dns = _krb5_use_dns(context);
+ int use_dns = _krb5_use_dns_kdc(context);
if ( use_dns ) {
code = krb5_locate_srv_dns(realm,
- get_masters ? "_kerberos-master" : "_kerberos",
- "_udp", addr_pp, naddrs);
+ get_masters ? "_kerberos-master" : "_kerberos",
+ "_udp", addr_pp, naddrs);
}
}
#endif /* KRB5_DNS_LOOKUP */
diff --git a/src/lib/krb5/posix/ChangeLog b/src/lib/krb5/posix/ChangeLog
index 813ec3120..118c02832 100644
--- a/src/lib/krb5/posix/ChangeLog
+++ b/src/lib/krb5/posix/ChangeLog
@@ -1,3 +1,10 @@
+2000-04-28 Ken Raeburn <raeburn@mit.edu>
+ Nalin Dahyabhai <nalin@redhat.com>
+
+ * syslog.c (vsyslog): Use strncpy and strncat instead of strcpy
+ and strcat when adding to buffer "tbuf". If calling vsprintf,
+ abort if it appears to have overrun the buffer.
+
1999-10-26 Wilfredo Sanchez <tritan@mit.edu>
* Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES,
diff --git a/src/lib/krb5/posix/syslog.c b/src/lib/krb5/posix/syslog.c
index 31e787493..f7ddbff16 100644
--- a/src/lib/krb5/posix/syslog.c
+++ b/src/lib/krb5/posix/syslog.c
@@ -115,7 +115,7 @@ vsyslog(pri, fmt, ap)
(void)sprintf(tbuf, "<%d>%.15s ", pri, ctime(&now) + 4);
for (p = tbuf; *p; ++p);
if (LogTag) {
- (void)strcpy(p, LogTag);
+ (void)strncpy(p, LogTag, sizeof(tbuf) - 1 - (p - tbuf));
for (; *p; ++p);
}
if (LogStat & LOG_PID) {
@@ -146,6 +146,11 @@ vsyslog(pri, fmt, ap)
}
(void)vsprintf(p, fmt_cpy, ap);
+ /* Bounds checking?? If a system doesn't have syslog, we
+ probably can't rely on it having vsnprintf either. Try not
+ to let a buffer overrun be exploited. */
+ if (strlen (tbuf) >= sizeof (tbuf))
+ abort ();
/* output the message to the local logger */
if (send(LogFile, tbuf, cnt = strlen(tbuf), 0) >= 0 ||
@@ -169,7 +174,8 @@ vsyslog(pri, fmt, ap)
if ((fd = open(CONSOLE, O_WRONLY, 0)) < 0)
return;
(void)alarm((u_int)0);
- (void)strcat(tbuf, "\r");
+ tbuf[sizeof(tbuf) - 1] = '\0';
+ (void)strncat(tbuf, "\r", sizeof(tbuf) - 1 - strlen(tbuf));
p = strchr(tbuf, '>') + 1;
(void)write(fd, p, cnt + 1 - (p - tbuf));
(void)close(fd);
diff --git a/src/lib/krb5/rcache/ChangeLog b/src/lib/krb5/rcache/ChangeLog
index 52f9db9cd..f58e8773a 100644
--- a/src/lib/krb5/rcache/ChangeLog
+++ b/src/lib/krb5/rcache/ChangeLog
@@ -1,3 +1,8 @@
+2000-04-28 Nalin Dahyabhai <nalin@redhat.com>
+
+ * rc_io.c (getdir): Don't check dirlen again, the call sites
+ always do. Fix dirlen calculation.
+
1999-10-26 Wilfredo Sanchez <tritan@mit.edu>
* Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES,
diff --git a/src/lib/krb5/rcache/rc_io.c b/src/lib/krb5/rcache/rc_io.c
index d45c7a1fb..b4291bcad 100644
--- a/src/lib/krb5/rcache/rc_io.c
+++ b/src/lib/krb5/rcache/rc_io.c
@@ -57,8 +57,6 @@ static char *dir;
static void getdir()
{
- if (!dirlen)
- {
if (!(dir = getenv("KRB5RCACHEDIR")))
#if defined(_MSDOS) || defined(_WIN32)
if (!(dir = getenv("TEMP")))
@@ -72,8 +70,7 @@ static void getdir()
dir = "/tmp";
#endif
#endif
- dirlen = strlen(dir) + 1;
- }
+ dirlen = strlen(dir) + sizeof(PATH_SEPARATOR);
}
krb5_error_code krb5_rc_io_creat (context, d, fn)
diff --git a/src/lib/krb5_32.def b/src/lib/krb5_32.def
index 6604060e2..5506c422e 100644
--- a/src/lib/krb5_32.def
+++ b/src/lib/krb5_32.def
@@ -13,10 +13,6 @@
; !CALLCONV - entrypoint that should have used KRB5_CALLCONV, but did not due
; developer error
-;LIBRARY KRB5
-DESCRIPTION 'DLL for Kerberos 5'
-HEAPSIZE 8192
-
EXPORTS
; Kerberos 5
krb5_build_principal
@@ -42,7 +38,7 @@ EXPORTS
krb5_free_authenticator
krb5_free_authenticator_contents
krb5_free_checksum
- krb5_free_config_files
+ krb5_free_config_files
krb5_free_context
krb5_free_cred
krb5_free_cred_contents
@@ -76,7 +72,7 @@ EXPORTS
krb5_get_credentials
krb5_get_credentials_renew
krb5_get_credentials_validate
- krb5_get_default_config_files
+ krb5_get_default_config_files
krb5_get_default_realm
krb5_get_host_realm
krb5_get_realm_domain
@@ -208,18 +204,18 @@ EXPORTS
krb5_change_password
;
- krb5_write_message
- krb5_read_message
- krb5_net_write
- krb5_net_read
- krb5_encrypt
- krb5_decrypt
- krb5_encrypt_size
+ krb5_write_message
+ krb5_read_message
+ krb5_net_write
+ krb5_net_read
+ krb5_encrypt
+ krb5_decrypt
+ krb5_encrypt_size
;
; Added for Kermit 95
- krb5_address_search ; !CALLCONV
- krb5_auth_con_getrcache ; !CALLCONV
- krb5_c_enctype_compare
+ krb5_address_search ; !CALLCONV
+ krb5_auth_con_getrcache ; !CALLCONV
+ krb5_c_enctype_compare
;
krb5_kuserok
;
@@ -227,29 +223,30 @@ EXPORTS
krb5_decode_ticket
krb5_appdefault_string
krb5_appdefault_boolean
-
+;
; Temporary exports (DO NOT USE)
-; decode_krb5_ticket -- no longer in library
des_ecb_encrypt
des_new_random_key
des_key_sched
des_pcbc_encrypt
des_quad_cksum
des_string_to_key
-; des_set_random_generator_seed -- no longer in library
des_init_random_number_generator
krb5_random_confounder
- krb5_size_opaque
- krb5_internalize_opaque
- krb5_externalize_opaque
- krb5_ser_pack_int32
- krb5_ser_unpack_int32
- krb5_ser_pack_bytes
- krb5_ser_unpack_bytes
- krb5_ser_auth_context_init
- krb5_ser_context_init
- krb5_ser_ccache_init
- krb5_ser_keytab_init
- krb5_ser_rcache_init
+ krb5_size_opaque ; gssapi
+ krb5_internalize_opaque ; gssapi
+ krb5_externalize_opaque ; gssapi
+ krb5_ser_pack_int32 ; gssapi
+ krb5_ser_unpack_int32 ; gssapi
+ krb5_ser_pack_bytes ; gssapi
+ krb5_ser_unpack_bytes ; gssapi
+ krb5_ser_auth_context_init ; gssapi
+ krb5_ser_context_init ; gssapi
+ krb5_ser_ccache_init ; gssapi
+ krb5_ser_keytab_init ; gssapi
+ krb5_ser_rcache_init ; gssapi
decode_krb5_ap_req ; gssapi
- krb5_mcc_ops
+ krb5_mcc_ops ; gssapi
+ krb5_get_tgs_ktypes ; gssapi
+ krb5_free_ktypes ; gssapi
+ krb5int_cc_default ; gssapi
diff --git a/src/lib/krb5util/ChangeLog b/src/lib/krb5util/ChangeLog
index cde0c8a6e..d00bc4894 100644
--- a/src/lib/krb5util/ChangeLog
+++ b/src/lib/krb5util/ChangeLog
@@ -1,3 +1,8 @@
+2000-05-31 Ken Raeburn <raeburn@mit.edu>
+
+ * compat_recv.c (krb5_compat_recvauth_version): Variant of
+ krb5_compat_recvauth, similar to krb5_recvauth_version.
+
1999-10-26 Wilfredo Sanchez <tritan@mit.edu>
* Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES,
diff --git a/src/lib/krb5util/compat_recv.c b/src/lib/krb5util/compat_recv.c
index ec6b15114..ee7df2434 100644
--- a/src/lib/krb5util/compat_recv.c
+++ b/src/lib/krb5util/compat_recv.c
@@ -193,6 +193,151 @@ krb5_compat_recvauth(context, auth_context,
return retval;
}
+krb5_error_code
+krb5_compat_recvauth_version(context, auth_context,
+ /* IN */
+ fdp, server, flags, keytab,
+ v4_options, v4_service, v4_instance, v4_faddr,
+ v4_laddr,
+ v4_filename,
+ /* OUT */
+ ticket,
+ auth_sys, v4_kdata, v4_schedule,
+ version)
+ krb5_context context;
+ krb5_auth_context *auth_context;
+ krb5_pointer fdp;
+ krb5_principal server;
+ krb5_int32 flags;
+ krb5_keytab keytab;
+ krb5_ticket ** ticket;
+ krb5_int32 *auth_sys;
+
+ /*
+ * Version 4 arguments
+ */
+ krb5_int32 v4_options; /* bit-pattern of options */
+ char *v4_service; /* service expected */
+ char *v4_instance; /* inst expected (may be filled in) */
+ struct sockaddr_in *v4_faddr; /* foreign address */
+ struct sockaddr_in *v4_laddr; /* local address */
+ AUTH_DAT **v4_kdata; /* kerberos data (returned) */
+ char *v4_filename; /* name of file with service keys */
+ Key_schedule v4_schedule; /* key schedule (return) */
+ krb5_data *version; /* application version filled in */
+{
+ union verslen {
+ krb5_int32 len;
+ char vers[4];
+ } vers;
+ char *buf;
+ int len, length;
+ krb5_int32 retval;
+ int fd = *( (int *) fdp);
+#ifdef KRB5_KRB4_COMPAT
+ KTEXT v4_ticket; /* storage for client's ticket */
+#endif
+
+ if ((retval = krb5_net_read(context, fd, vers.vers, 4)) != 4)
+ return((retval < 0) ? errno : ECONNABORTED);
+
+#ifdef KRB5_KRB4_COMPAT
+ if (!strncmp(vers.vers, KRB_V4_SENDAUTH_VERS, 4)) {
+ /*
+ * We must be talking to a V4 sendauth; read in the
+ * rest of the version string and make sure.
+ */
+ if ((retval = krb5_net_read(context, fd, vers.vers, 4)) != 4)
+ return((retval < 0) ? errno : ECONNABORTED);
+
+ if (strncmp(vers.vers, KRB_V4_SENDAUTH_VERS+4, 4))
+ return KRB5_SENDAUTH_BADAUTHVERS;
+
+ *auth_sys = KRB5_RECVAUTH_V4;
+
+ *v4_kdata = (AUTH_DAT *) malloc( sizeof(AUTH_DAT) );
+ v4_ticket = (KTEXT) malloc(sizeof(KTEXT_ST));
+
+ version->length = KRB_SENDAUTH_VLEN; /* no trailing \0! */
+ version->data = malloc (KRB_SENDAUTH_VLEN + 1);
+ version->data[KRB_SENDAUTH_VLEN] = 0;
+ if (version->data == 0)
+ return errno;
+ retval = krb_v4_recvauth(v4_options, fd, v4_ticket,
+ v4_service, v4_instance, v4_faddr,
+ v4_laddr, *v4_kdata, v4_filename,
+ v4_schedule, version->data);
+ krb5_xfree(v4_ticket);
+ /*
+ * XXX error code translation?
+ */
+ switch (retval) {
+ case RD_AP_OK:
+ return 0;
+ case RD_AP_TIME:
+ return KRB5KRB_AP_ERR_SKEW;
+ case RD_AP_EXP:
+ return KRB5KRB_AP_ERR_TKT_EXPIRED;
+ case RD_AP_NYV:
+ return KRB5KRB_AP_ERR_TKT_NYV;
+ case RD_AP_NOT_US:
+ return KRB5KRB_AP_ERR_NOT_US;
+ case RD_AP_UNDEC:
+ return KRB5KRB_AP_ERR_BAD_INTEGRITY;
+ case RD_AP_REPEAT:
+ return KRB5KRB_AP_ERR_REPEAT;
+ case RD_AP_MSG_TYPE:
+ return KRB5KRB_AP_ERR_MSG_TYPE;
+ case RD_AP_MODIFIED:
+ return KRB5KRB_AP_ERR_MODIFIED;
+ case RD_AP_ORDER:
+ return KRB5KRB_AP_ERR_BADORDER;
+ case RD_AP_BADD:
+ return KRB5KRB_AP_ERR_BADADDR;
+ default:
+ return KRB5_SENDAUTH_BADRESPONSE;
+ }
+ }
+#endif
+
+ /*
+ * Assume that we're talking to a V5 recvauth; read in the
+ * the version string, and make sure it matches.
+ */
+
+ len = (int) ntohl(vers.len);
+
+ if (len < 0 || len > 255)
+ return KRB5_SENDAUTH_BADAUTHVERS;
+
+ buf = malloc(len);
+ if (!buf)
+ return ENOMEM;
+
+ length = krb5_net_read(context, fd, buf, len);
+ if (len != length) {
+ krb5_xfree(buf);
+ if (len < 0)
+ return errno;
+ else
+ return ECONNABORTED;
+ }
+
+ if (strcmp(buf, KRB_V5_SENDAUTH_VERS)) {
+ krb5_xfree(buf);
+ return KRB5_SENDAUTH_BADAUTHVERS;
+ }
+ krb5_xfree(buf);
+
+ *auth_sys = KRB5_RECVAUTH_V5;
+
+ retval = krb5_recvauth_version(context, auth_context, fdp, server,
+ flags | KRB5_RECVAUTH_SKIP_VERSION,
+ keytab, ticket, version);
+
+ return retval;
+}
+
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
diff --git a/src/lib/rpc/ChangeLog b/src/lib/rpc/ChangeLog
index 392e7d9fa..7d0aa318a 100644
--- a/src/lib/rpc/ChangeLog
+++ b/src/lib/rpc/ChangeLog
@@ -1,3 +1,36 @@
+2000-05-31 Ken Raeburn <raeburn@mit.edu>
+
+ * pmap_rmt.c (GIFCONF_BUFSIZE): New macro.
+ (getbroadcastnets): Use it for buffer size.
+ (clnt_broadcast): Make buffer at least that big.
+
+ * get_myaddress.c (get_myaddress): Increase buffer size.
+
+2000-05-18 Ken Raeburn <raeburn@mit.edu>
+
+ * auth_gssapi_misc.c (auth_gssapi_display_status_1): Don't pass a
+ gss_buffer_desc to fprintf.
+
+ * clnt_tcp.c (clnttcp_create): Initialize "ct".
+ * clnt_udp.c (clntudp_bufcreate): Initialize "cu".
+
+ * svc_auth_gssapi.c (_svcauth_gssapi, create_client,
+ destroy_client, dump_db, clean_client): Use %p format for
+ displaying pointers. Remove unused variables.
+
+2000-05-17 Ken Raeburn <raeburn@mit.edu>
+ Nalin Dahyabhai <nalin@redhat.com>
+
+ * clnt_perror.c (clnt_sperror): Don't overflow buffer "str" beyond
+ known allocation size.
+ * clnt_simple.c (gssrpc_callrpc): Don't overfill buffer "crp->oldhost".
+
+2000-05-03 Nalin Dahyabhai <nalin@redhat.com>
+
+ * clnt_perror.c (_buf): Use bigger buffer.
+ (clnt_spcreateerror): Don't overflow buffer "buf" beyond known
+ allocation size.
+
2000-02-22 Donn Cave <donn@u.washington.edu>
* Makefile.in (includes): Extract basename of header file to be
diff --git a/src/lib/rpc/auth_gssapi_misc.c b/src/lib/rpc/auth_gssapi_misc.c
index fd9393c32..e7c38a820 100644
--- a/src/lib/rpc/auth_gssapi_misc.c
+++ b/src/lib/rpc/auth_gssapi_misc.c
@@ -162,15 +162,17 @@ static void auth_gssapi_display_status_1(m, code, type, rec)
auth_gssapi_display_status_1(m,gssstat,GSS_C_GSS_CODE,1);
auth_gssapi_display_status_1(m, minor_stat,
GSS_C_MECH_CODE, 1);
- } else
- fprintf(stderr,
- "GSS-API authentication error %s: recursive failure!\n",
- msg);
+ } else {
+ fputs ("GSS-API authentication error ", stderr);
+ fwrite (msg.value, msg.length, 1, stderr);
+ fputs (": recursive failure!\n", stderr);
+ }
return;
}
-
- fprintf(stderr, "GSS-API authentication error %s: %s\n", m,
- (char *)msg.value);
+
+ fprintf (stderr, "GSS-API authentication error %s: ", m);
+ fwrite (msg.value, msg.length, 1, stderr);
+ putc ('\n', stderr);
(void) gss_release_buffer(&minor_stat, &msg);
if (!msg_ctx)
diff --git a/src/lib/rpc/clnt_perror.c b/src/lib/rpc/clnt_perror.c
index 560cb27b7..06dd22e96 100644
--- a/src/lib/rpc/clnt_perror.c
+++ b/src/lib/rpc/clnt_perror.c
@@ -57,9 +57,8 @@ static char *buf;
static char *
_buf()
{
-
- if (buf == 0)
- buf = (char *)malloc(256);
+ if (buf == NULL)
+ buf = (char *)malloc(BUFSIZ);
return (buf);
}
@@ -74,17 +73,20 @@ clnt_sperror(rpch, s)
struct rpc_err e;
void clnt_perrno();
char *err;
- char *str = _buf();
+ char *bufstart = _buf();
+ char *str = bufstart;
char *strstart = str;
if (str == 0)
return (0);
CLNT_GETERR(rpch, &e);
- (void) sprintf(str, "%s: ", s);
+ strncpy (str, s, BUFSIZ - 1);
+ str[BUFSIZ - 1] = 0;
+ strncat (str, ": ", BUFSIZ - 1 - strlen (bufstart));
str += strlen(str);
-
- (void) strcpy(str, clnt_sperrno(e.re_status));
+ strncat (str, clnt_sperrno(e.re_status), BUFSIZ - 1 - strlen (bufstart));
+ str[BUFSIZ - 1] = '\0';
str += strlen(str);
switch (e.re_status) {
@@ -105,47 +107,64 @@ clnt_sperror(rpch, s)
case RPC_CANTSEND:
case RPC_CANTRECV:
- (void) sprintf(str, "; errno = %s",
- sys_errlist[e.re_errno]);
+ /* 10 for the string */
+ if(str - bufstart + 10 + strlen(sys_errlist[e.re_errno]) < BUFSIZ)
+ (void) sprintf(str, "; errno = %s",
+ sys_errlist[e.re_errno]);
str += strlen(str);
break;
case RPC_VERSMISMATCH:
- (void) sprintf(str,
- "; low version = %lu, high version = %lu",
- e.re_vers.low, e.re_vers.high);
+ /* 33 for the string, 22 for the numbers */
+ if(str - bufstart + 33 + 22 < BUFSIZ)
+ (void) sprintf(str,
+ "; low version = %lu, high version = %lu",
+ (unsigned long) e.re_vers.low,
+ (unsigned long) e.re_vers.high);
str += strlen(str);
break;
case RPC_AUTHERROR:
err = auth_errmsg(e.re_why);
- (void) sprintf(str,"; why = ");
+ /* 8 for the string */
+ if(str - bufstart + 8 < BUFSIZ)
+ (void) sprintf(str,"; why = ");
str += strlen(str);
if (err != NULL) {
- (void) sprintf(str, "%s",err);
+ if(str - bufstart + strlen(err) < BUFSIZ)
+ (void) sprintf(str, "%s",err);
} else {
+ /* 33 for the string, 11 for the number */
+ if(str - bufstart + 33 + 11 < BUFSIZ)
(void) sprintf(str,
- "(unknown authentication error - %d)",
- (int) e.re_why);
+ "(unknown authentication error - %d)",
+ (int) e.re_why);
}
str += strlen(str);
break;
case RPC_PROGVERSMISMATCH:
- (void) sprintf(str,
- "; low version = %lu, high version = %lu",
- e.re_vers.low, e.re_vers.high);
+ /* 33 for the string, 22 for the numbers */
+ if(str - bufstart + 33 + 22 < BUFSIZ)
+ (void) sprintf(str,
+ "; low version = %lu, high version = %lu",
+ (unsigned long) e.re_vers.low,
+ (unsigned long) e.re_vers.high);
str += strlen(str);
break;
default: /* unknown */
- (void) sprintf(str,
- "; s1 = %lu, s2 = %lu",
- e.re_lb.s1, e.re_lb.s2);
+ /* 14 for the string, 22 for the numbers */
+ if(str - bufstart + 14 + 22 < BUFSIZ)
+ (void) sprintf(str,
+ "; s1 = %lu, s2 = %lu",
+ (unsigned long) e.re_lb.s1,
+ (unsigned long) e.re_lb.s2);
str += strlen(str);
break;
}
- (void) sprintf(str, "\n");
+ if(str - bufstart + 1 < BUFSIZ)
+ (void) sprintf(str, "\n");
return(strstart) ;
}
@@ -238,26 +257,29 @@ clnt_spcreateerror(s)
if (str == 0)
return(0);
(void) sprintf(str, "%s: ", s);
- (void) strcat(str, clnt_sperrno(rpc_createerr.cf_stat));
+ str[BUFSIZ - 1] = '\0';
+ (void) strncat(str, clnt_sperrno(rpc_createerr.cf_stat), BUFSIZ - 1);
switch (rpc_createerr.cf_stat) {
case RPC_PMAPFAILURE:
- (void) strcat(str, " - ");
- (void) strcat(str,
- clnt_sperrno(rpc_createerr.cf_error.re_status));
+ (void) strncat(str, " - ", BUFSIZ - 1 - strlen(str));
+ (void) strncat(str,
+ clnt_sperrno(rpc_createerr.cf_error.re_status),
+ BUFSIZ - 1 - strlen(str));
break;
case RPC_SYSTEMERROR:
- (void) strcat(str, " - ");
+ (void) strncat(str, " - ", BUFSIZ - 1 - strlen(str));
if (rpc_createerr.cf_error.re_errno > 0
&& rpc_createerr.cf_error.re_errno < sys_nerr)
- (void) strcat(str,
- sys_errlist[rpc_createerr.cf_error.re_errno]);
+ (void) strncat(str,
+ sys_errlist[rpc_createerr.cf_error.re_errno],
+ BUFSIZ - 1 - strlen(str));
else
(void) sprintf(&str[strlen(str)], "Error %d",
rpc_createerr.cf_error.re_errno);
break;
}
- (void) strcat(str, "\n");
+ (void) strncat(str, "\n", BUFSIZ - 1 - strlen(str));
return (str);
}
diff --git a/src/lib/rpc/clnt_simple.c b/src/lib/rpc/clnt_simple.c
index b3d2eb330..2f203d73f 100644
--- a/src/lib/rpc/clnt_simple.c
+++ b/src/lib/rpc/clnt_simple.c
@@ -70,6 +70,8 @@ gssrpc_callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out)
}
if (crp->oldhost == NULL) {
crp->oldhost = mem_alloc(256);
+ if (crp->oldhost == 0)
+ return 0;
crp->oldhost[0] = 0;
crp->socket = RPC_ANYSOCK;
}
@@ -98,7 +100,8 @@ gssrpc_callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out)
crp->valid = 1;
crp->oldprognum = prognum;
crp->oldversnum = versnum;
- (void) strcpy(crp->oldhost, host);
+ (void) strncpy(crp->oldhost, host, 255);
+ crp->oldhost[255] = '\0';
}
tottimeout.tv_sec = 25;
tottimeout.tv_usec = 0;
diff --git a/src/lib/rpc/clnt_tcp.c b/src/lib/rpc/clnt_tcp.c
index 4e10a489f..f87da78b1 100644
--- a/src/lib/rpc/clnt_tcp.c
+++ b/src/lib/rpc/clnt_tcp.c
@@ -116,7 +116,7 @@ clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
unsigned int recvsz;
{
CLIENT *h;
- register struct ct_data *ct;
+ register struct ct_data *ct = 0;
struct timeval now;
struct rpc_msg call_msg;
diff --git a/src/lib/rpc/clnt_udp.c b/src/lib/rpc/clnt_udp.c
index 60469429d..df3945a48 100644
--- a/src/lib/rpc/clnt_udp.c
+++ b/src/lib/rpc/clnt_udp.c
@@ -117,7 +117,7 @@ clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz)
unsigned int recvsz;
{
CLIENT *cl;
- register struct cu_data *cu;
+ register struct cu_data *cu = 0;
struct timeval now;
struct rpc_msg call_msg;
diff --git a/src/lib/rpc/get_myaddress.c b/src/lib/rpc/get_myaddress.c
index 4c9bf29ac..13bafa009 100644
--- a/src/lib/rpc/get_myaddress.c
+++ b/src/lib/rpc/get_myaddress.c
@@ -81,7 +81,7 @@ get_myaddress(addr)
struct sockaddr_in *addr;
{
int s;
- char buf[BUFSIZ];
+ char buf[256 * sizeof (struct ifconf)];
struct ifconf ifc;
struct ifreq ifreq, *ifr;
int len;
diff --git a/src/lib/rpc/pmap_rmt.c b/src/lib/rpc/pmap_rmt.c
index 7cafe6e01..dc9735d84 100644
--- a/src/lib/rpc/pmap_rmt.c
+++ b/src/lib/rpc/pmap_rmt.c
@@ -165,6 +165,8 @@ xdr_rmtcallres(xdrs, crp)
* routines which only support udp/ip .
*/
+#define GIFCONF_BUFSIZE (256 * sizeof (struct ifconf))
+
static int
getbroadcastnets(addrs, sock, buf)
struct in_addr *addrs;
@@ -176,8 +178,9 @@ getbroadcastnets(addrs, sock, buf)
struct sockaddr_in *sin;
int n, i;
- ifc.ifc_len = UDPMSGSIZE;
+ ifc.ifc_len = GIFCONF_BUFSIZE;
ifc.ifc_buf = buf;
+ memset (buf, 0, GIFCONF_BUFSIZE);
if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
perror("broadcast: ioctl (get interface configuration)");
return (0);
@@ -255,7 +258,11 @@ clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
struct rmtcallres r;
struct rpc_msg msg;
struct timeval t;
- char outbuf[MAX_BROADCAST_SIZE], inbuf[UDPMSGSIZE];
+ char outbuf[MAX_BROADCAST_SIZE];
+#ifndef MAX
+#define MAX(A,B) ((A)<(B)?(B):(A))
+#endif
+ char inbuf[MAX (UDPMSGSIZE, GIFCONF_BUFSIZE)];
/*
* initialization: create a socket, a broadcast address, and
diff --git a/src/lib/rpc/svc_auth_gssapi.c b/src/lib/rpc/svc_auth_gssapi.c
index 827596a3b..34ee0ef11 100644
--- a/src/lib/rpc/svc_auth_gssapi.c
+++ b/src/lib/rpc/svc_auth_gssapi.c
@@ -134,7 +134,6 @@ enum auth_stat _svcauth_gssapi(rqst, msg, no_dispatch)
svc_auth_gssapi_data *client_data;
int ret_flags, ret, i;
rpc_u_int32 seq_num;
- int flag;
PRINTF(("svcauth_gssapi: starting\n"));
@@ -307,8 +306,6 @@ enum auth_stat _svcauth_gssapi(rqst, msg, no_dispatch)
#endif
if (call_arg.version >= 3) {
- int len;
-
memset(&bindings, 0, sizeof(bindings));
bindings.application_data.length = 0;
bindings.initiator_addrtype = GSS_C_AF_INET;
@@ -657,7 +654,6 @@ static svc_auth_gssapi_data *create_client()
client_list *c;
svc_auth_gssapi_data *client_data;
static int client_key = 1;
- int ret;
PRINTF(("svcauth_gssapi: empty creds, creating\n"));
@@ -665,7 +661,7 @@ static svc_auth_gssapi_data *create_client()
if (client_data == NULL)
return NULL;
memset((char *) client_data, 0, sizeof(*client_data));
- L_PRINTF(2, ("create_client: new client_data = %#x\n", client_data));
+ L_PRINTF(2, ("create_client: new client_data = %p\n", client_data));
/* set up client data structure */
client_data->established = 0;
@@ -783,10 +779,9 @@ static void destroy_client(client_data)
OM_uint32 gssstat, minor_stat;
gss_buffer_desc out_buf;
client_list *c, *c2;
- int ret;
PRINTF(("destroy_client: destroying client_data\n"));
- L_PRINTF(2, ("destroy_client: client_data = %#x\n", client_data));
+ L_PRINTF(2, ("destroy_client: client_data = %p\n", client_data));
#ifdef DEBUG_GSSAPI
if (svc_debug_gssapi >= 3)
@@ -852,7 +847,7 @@ static void dump_db(msg)
c = clients;
while (c) {
client_data = c->client;
- L_PRINTF(3, ("\tclient_data = %#x, exp = %d\n",
+ L_PRINTF(3, ("\tclient_data = %p, exp = %d\n",
client_data, client_data->expiration));
c = c->next;
}
@@ -871,7 +866,7 @@ static void clean_client()
while (c) {
client_data = c->client;
- L_PRINTF(2, ("clean_client: client_data = %#x\n",
+ L_PRINTF(2, ("clean_client: client_data = %p\n",
client_data));
if (client_data->expiration < time(0)) {
@@ -884,7 +879,6 @@ static void clean_client()
}
}
-done:
PRINTF(("clean_client: done\n"));
}
diff --git a/src/lib/rpc/unit-test/ChangeLog b/src/lib/rpc/unit-test/ChangeLog
index aa14bfc87..0a21776c3 100644
--- a/src/lib/rpc/unit-test/ChangeLog
+++ b/src/lib/rpc/unit-test/ChangeLog
@@ -1,3 +1,9 @@
+2000-06-08 Tom Yu <tlyu@mit.edu>
+
+ * lib/helpers.exp (kinit): Move "expect eof" into the commands
+ that send the prompt. Don't "expect eof" outside of the main
+ expect, as the main expect may have already read eof.
+
2000-02-15 Tom Yu <tlyu@mit.edu>
* server.c: Add code to set a signal handler for SIGHUP and a few
diff --git a/src/lib/rpc/unit-test/lib/helpers.exp b/src/lib/rpc/unit-test/lib/helpers.exp
index 3d7b167fc..c4b76aa0c 100644
--- a/src/lib/rpc/unit-test/lib/helpers.exp
+++ b/src/lib/rpc/unit-test/lib/helpers.exp
@@ -23,10 +23,10 @@ proc kinit {princ pass lifetime} {
spawn -noecho $kinit -5 -l $lifetime $princ
expect {
- -re "Password for $princ.*: " { send "$pass\n" }
+ -re "Password for $princ.*: " { send "$pass\n"; expect eof }
timeout { perror "Timeout waiting for kinit"; close }
+ eof
}
- expect { eof {} }
set ret [wait]
if {[lindex $ret $wait_error_index] == -1} {
@@ -117,7 +117,7 @@ proc wait_client {testname ccname id status} {
set env(KRB5CCNAME) FILE:/tmp/krb5cc_rpc_test_$ccname
if {[catch "exec $kdestroy -5"] != 0} {
- error "$testname: cannot destroy client $ccname ccache"
+ perror "$testname: cannot destroy client $ccname ccache"
}
unset env(KRB5CCNAME)
diff --git a/src/lib/win_glue.c b/src/lib/win_glue.c
index ab3e1a1be..6dc9e1014 100644
--- a/src/lib/win_glue.c
+++ b/src/lib/win_glue.c
@@ -90,8 +90,13 @@ extern void krb5_stdcc_shutdown();
* arbitrary third party applications. If there is an error, or we
* decide that we should not version check the calling application
* then VSflag will be FALSE when the function returns.
+ *
+ * The buffers passed into this function must be at least
+ * APPVERINFO_SIZE bytes long.
*/
-
+
+#define APPVERINFO_SIZE 256
+
void GetCallingAppVerInfo( char *AppTitle, char *AppVer, char *AppIni,
BOOL *VSflag)
{
@@ -187,11 +192,15 @@ void GetCallingAppVerInfo( char *AppTitle, char *AppVer, char *AppIni,
* We don't have a way to determine that INI file of the
* application at the moment so let's just use krb5.ini
*/
- strcpy( locAppIni, KERBEROS_INI );
+ strncpy( locAppIni, KERBEROS_INI, sizeof(locAppIni) - 1 );
+ locAppIni[ sizeof(locAppIni) - 1 ] = '\0';
- strcpy( AppTitle, locAppTitle);
- strcpy( AppVer, locAppVer);
- strcpy( AppIni, locAppIni);
+ strncpy( AppTitle, locAppTitle, APPVERINFO_SIZE);
+ AppTitle[APPVERINFO_SIZE - 1] = '\0';
+ strncpy( AppVer, locAppVer, APPVERINFO_SIZE);
+ AppVer[APPVERINFO_SIZE - 1] = '\0';
+ strncpy( AppIni, locAppIni, APPVERINFO_SIZE);
+ AppIni[APPVERINFO_SIZE - 1] = '\0';
/*
* We also need to determine if we want to suppress version
@@ -271,9 +280,10 @@ static krb5_error_code do_timebomb()
if (first_time) {
sprintf(buf, "Your version of %s has expired.\n",
TIMEBOMB_PRODUCT);
- strcat(buf, "Please upgrade it.");
+ buf[sizeof(buf) - 1] = '\0';
+ strncat(buf, "Please upgrade it.", sizeof(buf) - 1 - strlen(buf));
#ifdef TIMEBOMB_INFO
- strcat(buf, TIMEBOMB_INFO);
+ strncat(buf, TIMEBOMB_INFO, sizeof(buf) - 1 - strlen(buf));
#endif
MessageBox(NULL, buf, "", MB_OK);
first_time = 0;
@@ -285,9 +295,9 @@ static krb5_error_code do_timebomb()
if (first_time) {
sprintf(buf, "Your version of %s will expire in %ld days.\n",
TIMEBOMB_PRODUCT, timeleft);
- strcat(buf, "Please upgrade it soon.");
+ strncat(buf, "Please upgrade it soon.", sizeof(buf) - 1 - strlen(buf));
#ifdef TIMEBOMB_INFO
- strcat(buf, TIMEBOMB_INFO);
+ strncat(buf, TIMEBOMB_INFO, sizeof(buf) - 1 - strlen(buf));
#endif
MessageBox(NULL, buf, "", MB_OK);
first_time = 0;
@@ -323,9 +333,9 @@ krb5_error_code krb5_vercheck()
if (CallVersionServer(APP_TITLE, APP_VER, APP_INI, NULL))
return VERSERV_ERROR;
#else
- char AppTitle[256];
- char AppVer[256];
- char AppIni[256];
+ char AppTitle[APPVERINFO_SIZE];
+ char AppVer[APPVERINFO_SIZE];
+ char AppIni[APPVERINFO_SIZE];
BOOL VSflag=TRUE;
GetCallingAppVerInfo( AppTitle, AppVer, AppIni, &VSflag);