pullup from 1.2 branch
authorraeburn <raeburn@dc483132-0cff-0310-8789-dd5450dbe970>
Tue, 27 Jun 2000 21:00:02 +0000 (21:00 +0000)
committerraeburn <raeburn@dc483132-0cff-0310-8789-dd5450dbe970>
Tue, 27 Jun 2000 21:00:02 +0000 (21:00 +0000)
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@12442 dc483132-0cff-0310-8789-dd5450dbe970

126 files changed:
src/lib/ChangeLog
src/lib/crypto/ChangeLog
src/lib/crypto/Makefile.in
src/lib/crypto/dk/ChangeLog
src/lib/crypto/dk/derive.c
src/lib/crypto/dk/dk_decrypt.c
src/lib/crypto/dk/dk_encrypt.c
src/lib/crypto/old/ChangeLog
src/lib/crypto/old/old_decrypt.c
src/lib/crypto/old/old_encrypt.c
src/lib/crypto/prng.c
src/lib/gssapi/ChangeLog
src/lib/gssapi/Makefile.in
src/lib/gssapi/krb5/ChangeLog
src/lib/gssapi/krb5/accept_sec_context.c
src/lib/gssapi/krb5/acquire_cred.c
src/lib/gssapi/krb5/add_cred.c
src/lib/gssapi/krb5/gssapiP_krb5.h
src/lib/gssapi/krb5/init_sec_context.c
src/lib/gssapi/krb5/inq_cred.c
src/lib/gssapi/krb5/k5seal.c
src/lib/gssapi/krb5/k5unseal.c
src/lib/gssapi/krb5/ser_sctx.c
src/lib/gssapi/krb5/util_cksum.c
src/lib/gssapi/krb5/util_crypt.c
src/lib/gssapi/krb5/util_seed.c
src/lib/gssapi/krb5/util_seqnum.c
src/lib/gssapi/krb5/wrap_size_limit.c
src/lib/kadm5/ChangeLog
src/lib/kadm5/admin.h
src/lib/kadm5/admin_internal.h
src/lib/kadm5/alt_prof.c
src/lib/kadm5/chpass_util.c
src/lib/kadm5/clnt/ChangeLog
src/lib/kadm5/clnt/client_init.c
src/lib/kadm5/clnt/clnt_chpass_util.c
src/lib/kadm5/logger.c
src/lib/kadm5/ovsec_glue.c
src/lib/kadm5/srv/ChangeLog
src/lib/kadm5/srv/adb_openclose.c
src/lib/kadm5/srv/svr_chpass_util.c
src/lib/kadm5/unit-test/ChangeLog
src/lib/kadm5/unit-test/api.2/chpass-principal-v2.exp
src/lib/kadm5/unit-test/api.2/get-principal-v2.exp
src/lib/kadm5/unit-test/api.2/randkey-principal-v2.exp
src/lib/kdb/ChangeLog
src/lib/kdb/fetch_mkey.c
src/lib/kdb/setup_mkey.c
src/lib/kdb/store_mkey.c
src/lib/kdb/t_kdb.c
src/lib/krb4/ChangeLog
src/lib/krb4/Password.c
src/lib/krb4/configure.in
src/lib/krb4/cr_auth_repl.c
src/lib/krb4/cr_ciph.c
src/lib/krb4/cr_death_pkt.c
src/lib/krb4/cr_err_repl.c
src/lib/krb4/cr_tkt.c
src/lib/krb4/decomp_tkt.c
src/lib/krb4/dest_tkt.c
src/lib/krb4/g_ad_tkt.c
src/lib/krb4/g_in_tkt.c
src/lib/krb4/g_krbhst.c
src/lib/krb4/g_krbrlm.c
src/lib/krb4/g_pw_in_tkt.c
src/lib/krb4/in_tkt.c
src/lib/krb4/kntoln.c
src/lib/krb4/kparse.c
src/lib/krb4/kuserok.c
src/lib/krb4/mk_auth.c
src/lib/krb4/mk_err.c
src/lib/krb4/mk_req.c
src/lib/krb4/rd_req.c
src/lib/krb4/realmofhost.c
src/lib/krb4/recvauth.c
src/lib/krb4/send_to_kdc.c
src/lib/krb4/sendauth.c
src/lib/krb4/tf_util.c
src/lib/krb4/win_store.c
src/lib/krb5/ChangeLog
src/lib/krb5/Makefile.in
src/lib/krb5/krb/ChangeLog
src/lib/krb5/krb/Makefile.in
src/lib/krb5/krb/chk_trans.c
src/lib/krb5/krb/conv_princ.c
src/lib/krb5/krb/get_creds.c
src/lib/krb5/krb/get_in_tkt.c
src/lib/krb5/krb/init_ctx.c
src/lib/krb5/krb/kfree.c
src/lib/krb5/krb/mk_priv.c
src/lib/krb5/krb/mk_req_ext.c
src/lib/krb5/krb/rd_priv.c
src/lib/krb5/krb/recvauth.c
src/lib/krb5/krb/sendauth.c
src/lib/krb5/krb/t_kerb.c
src/lib/krb5/krb/t_krb5.conf
src/lib/krb5/krb/t_ref_kerb.out
src/lib/krb5/os/ChangeLog
src/lib/krb5/os/an_to_ln.c
src/lib/krb5/os/ccdefname.c
src/lib/krb5/os/changepw.c
src/lib/krb5/os/def_realm.c
src/lib/krb5/os/hst_realm.c
src/lib/krb5/os/init_os_ctx.c
src/lib/krb5/os/kuserok.c
src/lib/krb5/os/localaddr.c
src/lib/krb5/os/locate_kdc.c
src/lib/krb5/posix/ChangeLog
src/lib/krb5/posix/syslog.c
src/lib/krb5/rcache/ChangeLog
src/lib/krb5/rcache/rc_io.c
src/lib/krb5_32.def
src/lib/krb5util/ChangeLog
src/lib/krb5util/compat_recv.c
src/lib/rpc/ChangeLog
src/lib/rpc/auth_gssapi_misc.c
src/lib/rpc/clnt_perror.c
src/lib/rpc/clnt_simple.c
src/lib/rpc/clnt_tcp.c
src/lib/rpc/clnt_udp.c
src/lib/rpc/get_myaddress.c
src/lib/rpc/pmap_rmt.c
src/lib/rpc/svc_auth_gssapi.c
src/lib/rpc/unit-test/ChangeLog
src/lib/rpc/unit-test/lib/helpers.exp
src/lib/win_glue.c

index b54a4476f2152e7f8245acb21fa6c513bd6ff474..66d1fd6e5fca539be5b432238e33d65b54fc54c5 100644 (file)
@@ -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.
index f451cbe0d09eb7c3bbcf0898eec1c2f4000fbb47..f1fbfff045c10f8374f4991da72df9a4d73f9f6d 100644 (file)
@@ -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>.
index 71bddf5c4bb695582c3d1787d1491b79de698649..64f19d18e1c0b2fee7e24e892e734c0bc9477bee 100644 (file)
@@ -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 \
index a9bdafe99cfb4e2b18bb45eddfd9c4463d664048..1929ff6a1adb4f8d5125fabc641bbf735a2c88b8 100644 (file)
@@ -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
index 8765605fbcadf1f54fe0915dae9804c384435a06..dbd4a2a2d84bdd9fc977380852a5117b3f4edba0 100644 (file)
@@ -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;
index d3077615f8c6b6856e9920697f224f278708a992..d6e7c0db304b37ffac19a7aa200b942c2e4e5d3c 100644 (file)
@@ -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:
index 8627353dbc52b2c7d1ef5d11c76ceee2398051e0..2bc2b6ba421202ac49f061bba8f81e2de79dcfcb 100644 (file)
@@ -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 */
 
index 0bee167d1fb6d6fbbc8fa8a7f31df3cc33dce3ce..7446daa2c0f02600b22c371c3cf110ad5d6f9cd6 100644 (file)
@@ -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.
index 1bcb0d38b0c2167ca9c7be94204414291f9a4556..bfbe56a109dd079c4e11c593f61b92e71c67d6e6 100644 (file)
@@ -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);
index d90d0f8852f9b299664e5854bb00e1b9ef47ebfb..8860ba5ff99af8baf029c5f1736a6595b2c04955 100644 (file)
@@ -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);
index 6d401a9bf06220d6ac2f9f703094082480951796..b22131e0f4ab8b702fccdb5ffdabdb2f5bfd986f 100644 (file)
@@ -158,4 +158,4 @@ void prng_cleanup (void)
 {
        free (random_state);
        inited = 0;
-}
\ No newline at end of file
+}
index 7dc9b00e7148ee09ec70eef6569e545267f7960f..b8da27165bdfcb237b72e8c9a4cafe63b1c914b9 100644 (file)
@@ -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>.
index bee2b8593bf5db4198e4c6491fbb2ae89f96e5c9..20936da1984782d332acc856e3064a65c5e706ee 100644 (file)
@@ -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) \
index ccb16f49a0de59f957fc332ad6e4f3b5e2971d35..087104e703808e97597cd38bbff942b589306dfe 100644 (file)
@@ -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.
index 075d0e4c8983fe834f3932b46342284bd2dfc974..0d2aaa5eade3a35c187600b9924961fa432b7b85 100644 (file)
@@ -1,3 +1,27 @@
+/*
+ * 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.
  * 
 #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);
 
index 78e8c29dc1ab65df8d7571def085ffa585ececc7..33946e767496cb0722e1bffe9a53a75bf2012233 100644 (file)
@@ -1,3 +1,27 @@
+/*
+ * 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.
  * 
 #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);
index 2a6fdb47b5c27ced856064fcdd39004e8cfe6637..918c2641205bc6547638908cb31a6559ff2fcc17 100644 (file)
@@ -1,3 +1,27 @@
+/*
+ * 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.
  * 
@@ -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 */
 
index a22cd8dddcd5105ff10da85d924a6108e7bb4211..ed0956999a7724e5a821d82681a5a07a77fb1297 100644 (file)
@@ -1,3 +1,27 @@
+/*
+ * 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.
  * 
 #ifndef _GSSAPIP_KRB5_H_
 #define _GSSAPIP_KRB5_H_
 
-/*
- * $Id$
- */
-
 #include <krb5.h>
 #ifdef HAVE_MEMORY_H
 #include <memory.h>
 #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,
index 8baad8c058e67ea6b237ed75a3f81a257f2de51a..13a971ffa61f22d26c877618505576a0bf995c03 100644 (file)
@@ -1,3 +1,27 @@
+/*
+ * 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.
  * 
 #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) {
index c800012c84d946596546205d9fc56393c7071e4d..6da0a5213557a321043d2c3eb04e7b67842298fc 100644 (file)
@@ -1,3 +1,27 @@
+/*
+ * 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.
  * 
@@ -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 */
index ae8cc759054f435c53175a539f13700e98c91e36..1ca108e653471967c4dae5b3d02228cf54e4157c 100644 (file)
@@ -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
 
 /*
  * 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.
 #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);
 }
index da5966f238bac88430d7369cf3a227f3bbdb20bb..bc35e7021504f3d3479157671ccf219d1d886450 100644 (file)
@@ -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
 
 /*
  * 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.
 #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);
 }
index 2a6231ee79f5ad6623e69c9a290f417fdc36efda..1989a7d558c76f8ca41153a16aa176467f06925a 100644 (file)
@@ -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,
index 61fbc666d719e73210e632e62377ff5089bc8ada..77feade7367043945deeadce1577e37f1f38326a 100644 (file)
  * 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;
index 8792e5fed50404987af8d8fbe843435e88d88ab7..3e40236c8dfd52c53c85a8e4de53d82144cff0fa 100644 (file)
 #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;
 }
index 24ae7f3f4cef8085a510c0ba75e8d313e0b837a7..3f6eb4713d60c326b4d1bf130979578a17570155 100644 (file)
 #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);
 
index e14b2f3fec89a29b14b33d943618f561f2a2fe64..b8f2b389a916343f334c4e0f37eac553cadd7b63 100644 (file)
@@ -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]) ||
index d71a3f864718bd1c2bf67dc56aa0a6ddddbf4a16..a3c05df4fd3a82a46231bacba410203b067af3a6 100644 (file)
@@ -1,3 +1,27 @@
+/*
+ * 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.
  * 
 
 #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);
index b8dedb2768c1054f8ffed20a0a22fd13d2fe7bfe..59ea4aecda4d7c2881499a0c0db0a4496c549fdc 100644 (file)
@@ -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
index 159c7fb58a242aa38ee4937b988442feb096dc6d..2164e1e16c8dcdc4595c0a41d59e8cf35db8a851 100644 (file)
@@ -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
index d2d1533bc287d09d9be4e4e862181834ad4868b7..97cb5e52e22564b11c03c2e6d1712e4d9d63ca42 100644 (file)
@@ -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. */
index 5582df090522b6e793b8fb2151644d9df18dc814..4d1e7692092e2113efcd0a3c2a3d13d1425d32b4 100644 (file)
@@ -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,
index 367d8f2010f301c49797e2215a7950c5c09e8970..a991ca00a6f69e531b544e42b1646bd5e9602586 100644 (file)
@@ -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);
   }
index 1672942579f8ce63f54f311033b77ddcd422bedf..0e47993d543c4ce58e4297daa9adf77d268fed37 100644 (file)
@@ -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
index 53d6e15af671fdde6fe18b22b5f8c5405d7637af..56fbfcd72348fa6997a2f2f8d3f68349a306cf67 100644 (file)
@@ -1,7 +1,5 @@
 /*
  * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
- *
- * $Header$
  */
 
 /*
  * 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,
index d6c7f0bfb2ee0418fb124addbea736d6bb43abd0..ae9ced08250d38734da1b47bafa5f19503592889 100644 (file)
@@ -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);
 }
index 4f2ad200581f3ba45afaeaf88fcb80793b0ecb0b..bf6bbfd0021981235490fa5ea5a5c5c9abae1072 100644 (file)
@@ -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)];
     
index 6118282df3232aa78e8b34ec8343967a682e167c..ce818934f27d86531e3065761c745901047348b7 100644 (file)
@@ -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,
index 1864a733f91ca56d9704b4fd2f65049eb4e4c544..d39760428faef7d00f02872cbc3ee9b15820e3dc 100644 (file)
@@ -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
index e776192c2eaff490c67140353747ed4653b77ae2..2a9bba8f638cb3872d50a5bd564c38ed1018e3a3 100644 (file)
@@ -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),
index df2bf4c47b751d6acfdb18278829e41a284e2db0..4c4c6bbe60da971420866d819c8d62556e137856 100644 (file)
@@ -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);
 }
index 15c4bad59c752a9f5e6f105ceea0dd712904c980..f195831d6346cea216e412f14cc6bbac7752704b 100644 (file)
@@ -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
index 40a78c9858a7d36a5d7f6f09bac7eb61f43f640a..ef45510a238899b746de45621fb7e92576e32255 100644 (file)
@@ -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"
index 0e3e1b5a8fd1696071bdd827f3899a16b4e952cd..d2eb85a9060cd8a820d8dc940ed74e1c6e0c5937 100644 (file)
@@ -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} {
index 5c8fdc5e50e2bbf34104d6f7ae825956eefdb631..d9cc9718a1c005f8aaadabd20d1fc852c85860d7 100644 (file)
@@ -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"
index 7d7368cc6f4a523618d88c254d9fc60071774b33..b72e64248ddc2a4803bcbbd1627836ccd12e54c3 100644 (file)
@@ -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
index 2ff5c2942a5e690cc3108000c613e741f0d599b2..7ae26bbb9ccc706d703515f499a42f23fd357996 100644 (file)
@@ -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")))
index 0898a631158917503e6b73ef09760ef2056f1523..1788ecdd875ee4851c9d2c1624e97a5701a22b49 100644 (file)
@@ -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;
 
index d18630ac0b037353615a6674cdcb4d7e68cdbc84..47e0bc9c0d535a6f198c19631941825984fdad26 100644 (file)
@@ -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;
     }
 
index 8358088d2f5297415984b94d66e035c527609d2a..10e6163fb2caf0b13f9eefb86947d2f3bf17247f 100644 (file)
@@ -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]);
        }
     }
 
index 29d985f31581037c2e7da65a428be4d890238f1e..c1d81d3b46b00bde6742de298db9f3e2abefc392 100644 (file)
@@ -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.
index b29663006877357bbd042c872b74590e103ece5f..5862e0e655c4389d8a2cb7168cc6ad2ca6cd75d8 100644 (file)
@@ -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;
index 0434c7d0e034e2d6ab480a425a29e5bb2b37ac61..59937e1ace18cb2266c6e224d59ca0faec30f051 100644 (file)
@@ -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
index 5203506d34e51a193d895b1b811d971a6f8b2b5f..a0562d96f359a37e10928c90257a84b73cb4dfec 100644 (file)
@@ -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);
index d15a4e0fd26609713fabf398513ac645e895bcc9..d9c751271f077667db31bfbc5d07c034bed762de 100644 (file)
@@ -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;
 
index 8daa2d6881c3de862a07fc83372cb45a3a0a9905..c3562675dca529ad2e74dd6e3f3e69ede3af6ce7 100644 (file)
@@ -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 */
index 7f68bda76f784b62a5555306b3b891ea2412ca81..54e87d82ed6898f880c8cb27c59d7168a79bbed8 100644 (file)
@@ -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);
index 0293e105f7c928b2e38651dc0f17268ebc4d3a1d..34bec48012a1ace61e515a48f75998ed55abcaa3 100644 (file)
 #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);
index 04d3298adee81f89e472c696eab240a8da29483a..06e9e316c516a400f5680f0f37bd260023c87c4b 100644 (file)
@@ -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);
 
index 70578183e3f426cc04e107627c6c70856a2b6eff..50c1352b2371787f80af2db449fd171ced78b129 100644 (file)
@@ -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 */
index b3abb2ddc6913c76ff79af284e67178d8f19056a..afcd0c6f8b301581f6a7201f7a2116392dcb61ab 100644 (file)
 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;
index c9d6183820a92e0ac9fd8dde0a647af3288abde7..361273c9d73fc5cdd43161c7b99e6a5d016ae063 100644 (file)
@@ -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);
index 529ac07694932ba3b7c5b12e3bc391e8fbbdf608..4e0fd6d7644a4f334ffc0cf322a3f03b446ed068 100644 (file)
@@ -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
index 983150ce40390e9f38668d327ff8f4a36d36ca70..c75023176bf717f343f145519973140103d8c243 100644 (file)
@@ -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
index 6723df87e37f62a36f8990b32f67b2db137c7893..13f762b0110a3a755f6b8e3a88e252d11e8e2c2e 100644 (file)
@@ -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)
index ea17be8201541da6a6f0c0d8719afe2bd0d81cc2..4e220f913144a10ef8551294e61614f9fca6c9d0 100644 (file)
@@ -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);
index 8b6cdfe0e5811c7080a6c8c34d14bbde25970f7b..f86599ccea3d71a13f763d3ec34b6e5ed1450db1 100644 (file)
  * 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);
 }
index 98e48fbd90d73e7aa6ae4c029ca9765f1c86d3f5..e72295c48fcd0f6b3a6c9eaaedf355dab847155b 100644 (file)
@@ -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
index 0aee8934a095a1bf0f184afb1c0062d125664360..20587cb5be8ae1b40fda3ee60f4bb94fb68cf756 100644 (file)
@@ -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 */
        /*
index 39a2e2f68b7b0811cb7b2de74cec6765c7012913..a94a25d85f44e5777a1aafea4399e5f68782cdba 100644 (file)
@@ -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)) {
index e30e299bc436823614a32a1c70d8ec7cfdfcf505..029aa9f9c70e1c4ddca8d65bfaaa0ccb292e246d 100644 (file)
@@ -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 */
index 1936cb287d3e051fc45fa9d0046951cc9940a24b..468dccdb6df5d673aa304cb293861cbdffc6f1aa 100644 (file)
@@ -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));
index c9b6ac73445e67c73018a7ee66cac7aa67cc3eb8..09f914d8a0bab3c99b2dc5bc90641b39041be274 100644 (file)
@@ -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 */
index 90e01bb3487608060f61d20dec81f31b3ae91be7..1e4b78601a62311b6eec5922054d8fb374d5b4a3 100644 (file)
@@ -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;
                  }
                }
index e62e3f954c8b41df47dcd604d33ae0030fb6b53d..2a6665648e1bfaf3cc8ca303c75d3fc8700cade2 100644 (file)
@@ -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) !=
index c7e0fb33b8e4466ee473e21c7f695d9215e2e000..f93b9d0793cedbb9d2eb958e2e04f69114e4fcb2 100644 (file)
@@ -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()) {
index 9b8fb390487a9190928f0e7cb4690dc6a6a8b2e1..76c470c20f669a86ab3f96efe2c0c864c1c1d86c 100644 (file)
@@ -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)
index ebf500bf2955b0d540624c798d75b151abaa98e6..0d69719cf26fb659f306197316e3495896210122 100644 (file)
@@ -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 */
 
     /*
index 50507aa12762b35fb29abc5cfc969c54a6c972ad..28d11bd85dfccbaaaa3040840cac883e7534783f 100644 (file)
@@ -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");
 
index 89f7f2ea1599f8dfaead02d881df7486fc95262d..061080371e1ea90af8fe7f98f047631ae3ca7948 100644 (file)
@@ -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>.
index 0dab1f3a9816e0188b6791b4536e34503c147f1c..68e354c6f11d7606320fc164084f08932d3f0ac5 100644 (file)
@@ -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)
 
index 14fa9c3d8a9c0b1c84c0e800b36f5ed2849b1375..80f24ebfba8a082641d279c6d82ff3e021a764fe 100644 (file)
@@ -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>.
 
 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>
 
 
 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>
 
index 8aeb398d0694fa577a8a9561917a8ca25da0f06d..19c1da40cd7bef41d60b80f648cb8ea03c4dca16 100644 (file)
@@ -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
index c2ac716c880f096c2072c81b0ae33a208eb77d22..eee55c8c543ce04c0c268e2a2fd989508caf00a3 100644 (file)
@@ -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;
       }
     }
index b90289ab5a5ecb7299e2160948cad52f09f98a7e..36e2bbd0add27ea5d5e4c893c6ecb425dd55b1b8 100644 (file)
@@ -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;
 }
index 3bcaa0be2b3b5d066c4f1ed4bdffe0c5a0381f2d..6d764d3290bb32201fb36295d5398b8273075344 100644 (file)
@@ -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;
index 9686f578a83961b173fd2d3c3eca9a646713cb08..298f1528f025f8a5fb6861d941a8c7a0f2fc29f6 100644 (file)
@@ -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);
index e2eccc4021fab5c0c66a4a2f398c6373c5a02bf7..c10c6f7e239df47a8e9d385195cf7e63d234c67f 100644 (file)
@@ -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);
 }
index 24d8aaff9044892bd6e457142696088926729caf..8e57f8391743470f4b85f0c2c7a69c564b02d47f 100644 (file)
@@ -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);
 }
-
index 76858175089c15154888551b4eab38c286c7b7ba..d72f6b2aca710eaaf39bca32a824751d686df06b 100644 (file)
@@ -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;
 
index a8b20ebcb877b87b8aa5e9590b71bcd26b97c9d2..88daab56704bd2d734af8da6004204e412a30260 100644 (file)
@@ -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) {
index 9629b0c1947ea02ca84fdfe654b68f40b25c1d86..ab6a5312d71b6f1400f6ae260c0b220abc5190b0 100644 (file)
@@ -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;
index 3d5bce4917e5ec3275cb4a4e4eecbc7ab98b67d9..f74041c59c2490a927a35251c92e1e222000e0ae 100644 (file)
 
 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);
+}
index 1e6b726a2f1e7eb3e9dc382d54846b3b6528eba4..b19afdb7ed1ef342bc2eb9551fa30c0d6178eb70 100644 (file)
@@ -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
index 2feef39dd6e0f57d87e5abb90c5f62c13ae0b802..458015d1c665a9be2d957ac6466c8184fd1878af 100644 (file)
@@ -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);
index 5882d9770a9ad6fcf6f9ae4c8061e6c77f3bdbfd..8d7a4d9759f925635cfa91a4acdbdb50e96c01f5 100644 (file)
                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
index 9423944534ff08b22ed4d4c899234fc599896cc8..08a53343fcb6b88fb6a010a3c3eee354ae7d8aca 100644 (file)
@@ -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
index adf1c5d271bc7b4319b3d65bcb5e2d0eee911f82..33f80180cc5842689bf57aedf549ba8ee1bdc912 100644 (file)
@@ -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.
index 3c721fb879356eb4af3c84a83b96517789c74d6c..02e68fb04da985f51e99a610dc59c21915e1ce9c 100644 (file)
@@ -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);
index 3bc2546cbb910018e64ba4f5e297d3d5d6d5a7c4..6b00e5286eae93e890146e53c15ee346e5aba651 100644 (file)
@@ -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)
index 597351619de7a16712c2c3f27998e2302aba871b..575866e2afb2266377ac429329745cba69383f96 100644 (file)
@@ -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);
index d3c031f5b60315133680fa67af3774bc340fecfb..d9bd017ad472fc86999585535959b53c76de3202 100644 (file)
@@ -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
index 1e8923f4c75f38f71baf06703c189350b0d6c13a..965a991c3b4ea1dab42e433d17b78b645d72a818 100644 (file)
@@ -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
index 5222e6af8a639abb3e74823c94b221af0e5dd6ad..f599697142f98739c8efd8fca649b8688a20802c 100644 (file)
 #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);
index ef080374495ea5eeb0f465a8e0c0ddc2a5372e79..6d2adb126e9790beb6dd1f48f4473dc64a5112a5 100644 (file)
@@ -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 */
        /*
index f0f1a29ecefa184b1a7a094883240e942d0f31e4..d5b46b664157bcd2b974169003b7a054009cc4d6 100644 (file)
@@ -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 {
index 1139fb338e271bf8849ba8ac11f3a31334865a6e..53f36d835447217033374b2feb8710d75f5a099e 100644 (file)
 #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 */
index 813ec312052ba54624a4e89bea7e1ca011b81b8c..118c028325583b85d653ace6b100bf5a8153cd37 100644 (file)
@@ -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,
index 31e787493e2034004588eace49686fbc2009b269..f7ddbff16c6ba2d37920f9040321b5a5ab209fa6 100644 (file)
@@ -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);
index 52f9db9cd38bddc9765a35de93fcd99348eef24c..f58e8773a36e391887eefd581e651a370736548b 100644 (file)
@@ -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,
index d45c7a1fb53407d020c9c5224cef7d8056840e36..b4291bcad25e19a172546c75a5d2ccab82fa2c94 100644 (file)
@@ -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)
index 6604060e26d0921ba3fa0a5266c2c47b150bd4cd..5506c422ef904147ff654e897ca94b39a1540a2d 100644 (file)
 ; !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
index cde0c8a6e7f07093ae2ef5467b67d256aff2a974..d00bc48946c9edce8822c21c268ad4990a88de01 100644 (file)
@@ -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,
index ec6b151149a6999be9203f2d6d0406c6d72e7b11..ee7df24340906b197302eb8154c862ba954ba21f 100644 (file)
@@ -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))
index 392e7d9faa2b7b3763f0e2ae472292d857f9a7d2..7d0aa318ad2db4115ddac792c9e066c7f8061c0e 100644 (file)
@@ -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
index fd9393c3278a9c63c889c5e818a56965b2a31fab..e7c38a8208a1a520290e742580f1a861a91871c0 100644 (file)
@@ -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)
index 560cb27b79ab602061c15ce49aecfc3f529d11f3..06dd22e962cbd48be0dc4e62e9a60fbca3eb6e6a 100644 (file)
@@ -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);
 }
 
index b3d2eb33042f080c7447938e35cbbefd1932a3f3..2f203d73fc9248e7d1dbb580a768f5ac55b724d0 100644 (file)
@@ -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;
index 4e10a489f75eb859f155ab6c93575391bd98af80..f87da78b1988af2ecb77402c9b17a192c8591ff4 100644 (file)
@@ -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;
 
index 60469429dd046c1fb8c4cafcab02368e9bf5eb02..df3945a4868cbc79033832d8c0d8dea01bf5bd8c 100644 (file)
@@ -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;
 
index 4c9bf29ac0ccaaf23ad04b38aea8e4d6836828a8..13bafa00917e0d7d3c0f95b3ee1339d89a7cc06b 100644 (file)
@@ -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;
index 7cafe6e012ea92157a07dd1f4ccb2eec272e6b2f..dc9735d846deab93ee1c0711d682854073595928 100644 (file)
@@ -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
index 827596a3b6f0a8137ebf68e9579f0f3b10c91484..34ee0ef11a053a50cae36e7f6f17be65c8f5a5d1 100644 (file)
@@ -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"));
 }
 
index aa14bfc87cf672af6ae2f36c4ad85accd8ae2782..0a21776c38ec8b56c04974e605e6d6a73878cf1d 100644 (file)
@@ -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
index 3d7b167fc50ee0cc3c6cefe4fa8a95fb98102245..c4b76aa0ce2fb36188e1bf35a408098688a34dba 100644 (file)
@@ -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)
index ab3e1a1be10b5a4460256b5f89ef822b0709a04a..6dc9e101422e0cbbf7e3442df6d566bec17a1e65 100644 (file)
@@ -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);