* cnv_tkt_skey.c (krb524_convert_tkt_skey): Take both a v5 and v4
authorSam Hartman <hartmans@mit.edu>
Thu, 25 Jan 1996 20:06:28 +0000 (20:06 +0000)
committerSam Hartman <hartmans@mit.edu>
Thu, 25 Jan 1996 20:06:28 +0000 (20:06 +0000)
  service key.  Use the v5 service key to decrypt the v5 ticket, and
  the v4 service key to encrypt the v4 ticket.

* krb524d.c (do_connection): Use a separate v5 and v4 service key
  so that if the KDC chooses to encrypt the v5 ticket in something
  besides ENCTYPE_DES_CBC_CRC, we don't lose.  Also, make sure we
  free keyblock contents and tickets on error.
(lookup_service_key): Pass enctype to kdc_get_server_key

(kdc_get_server_key):  Only try for v4 salt if the enctype is
DES_CRC.  Take enctype as an argument.  This creates a problem
if the server key has a normal and v4 salt of ENCTYPE_DES_CBC_CRC
but I can't think of a good answer to this.

* k524init.c (main):  Use crc32 not md5.

Wed Jan 24 20:05:47 1996  Sam Hartman  <hartmans@tertius.mit.edu>

* krb524d.c (kdc_get_server_key): Try to find a v4 salt type key,
  else try any des_crc32 key, else fail.
(do_connection): Lookup a crc32 key not an md5 key.
(init_master): Handle reading kdc profile.

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@7386 dc483132-0cff-0310-8789-dd5450dbe970

src/krb524/ChangeLog
src/krb524/cnv_tkt_skey.c
src/krb524/configure.in
src/krb524/k524init.c
src/krb524/krb524.h
src/krb524/krb524d.c

index 0155f98ee578053acd61a6d52b7b17217d44eb1a..d95aa09c570fe67bf04130f7cf0c09815b0c7101 100644 (file)
@@ -1,3 +1,30 @@
+Thu Jan 25 02:07:46 1996  Sam Hartman  <hartmans@tertius.mit.edu>
+
+       * cnv_tkt_skey.c (krb524_convert_tkt_skey): Take both a v5 and v4
+       service key.  Use the v5 service key to decrypt the v5 ticket, and
+       the v4 service key to encrypt the v4 ticket.
+
+       * krb524d.c (do_connection): Use a separate v5 and v4 service key
+       so that if the KDC chooses to encrypt the v5 ticket in something
+       besides ENCTYPE_DES_CBC_CRC, we don't lose.  Also, make sure we
+       free keyblock contents and tickets on error.
+       (lookup_service_key): Pass enctype to kdc_get_server_key
+
+       (kdc_get_server_key):  Only try for v4 salt if the enctype is
+       DES_CRC.  Take enctype as an argument.  This creates a problem
+       if the server key has a normal and v4 salt of ENCTYPE_DES_CBC_CRC
+       but I can't think of a good answer to this.
+
+
+       * k524init.c (main):  Use crc32 not md5.
+
+Wed Jan 24 20:05:47 1996  Sam Hartman  <hartmans@tertius.mit.edu>
+
+       * krb524d.c (kdc_get_server_key): Try to find a v4 salt type key,
+       else try any des_crc32 key, else fail.
+       (do_connection): Lookup a crc32 key not an md5 key.
+       (init_master): Handle reading kdc profile.
+
 Sun Nov 12 04:29:08 1995  Mark W. Eichin  <eichin@cygnus.com>
 
        * conv_creds.c (krb524_convert_creds_kdc): loop through all of the
index f433e540716a4870906b7811b4a619ee62f0fe70..8423197705a4d2af13bed215fc2c72c53ebef5d4 100644 (file)
  * Convert a v5 ticket for server to a v4 ticket, using service key
  * skey for both.
  */
-int krb524_convert_tkt_skey(context, v5tkt, v4tkt, skey)
+int krb524_convert_tkt_skey(context, v5tkt, v4tkt, v5_skey, v4_skey)
      krb5_context context;
      krb5_ticket *v5tkt;
      KTEXT_ST *v4tkt;
-     krb5_keyblock *skey;
+     krb5_keyblock *v5_skey, *v4_skey;
 {
      char pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ];
      char sname[ANAME_SZ], sinst[INST_SZ];
@@ -46,7 +46,7 @@ int krb524_convert_tkt_skey(context, v5tkt, v4tkt, skey)
      int ret, lifetime;
 
      v5tkt->enc_part2 = NULL;
-     if ((ret = krb5_decrypt_tkt_part(context, skey, v5tkt))) {
+     if ((ret = krb5_decrypt_tkt_part(context, v5_skey, v5tkt))) {
          krb5_free_ticket(context, v5tkt);
          return ret;
      }
@@ -110,7 +110,7 @@ int krb524_convert_tkt_skey(context, v5tkt, v4tkt, skey)
                             v5etkt->times.starttime,
                             sname,
                             sinst,
-                            skey->contents);
+                            v4_skey->contents);
 
      krb5_free_enc_tkt_part(context, v5etkt);
      v5tkt->enc_part2 = NULL;
index 15780020c1a2fc2dbac7444b71593aabd5878ce4..7f7e783565efe918dd2bae9d70a062873c56d624 100644 (file)
@@ -6,6 +6,7 @@ AC_PROG_RANLIB
 AC_PROG_INSTALL
 AC_TYPE_SIGNAL
 ET_RULES
+USE_KADM_LIBRARY
 USE_KDB5_LIBRARY
 USE_KRB4_LIBRARY
 KRB5_LIBRARIES
index 61c180aa4786e502ab14e0a1885340876584d323..79651f521004128ac6fe4d82aea1b0072427d58a 100644 (file)
@@ -108,7 +108,7 @@ int main(argc, argv)
      increds.client = client;
      increds.server = server;
      increds.times.endtime = 0;
-     increds.keyblock.enctype = ENCTYPE_DES_CBC_MD5;
+     increds.keyblock.enctype = ENCTYPE_DES_CBC_CRC;
      if ((code = krb5_get_credentials(context, 0, cc, &increds, &v5creds))) {
          com_err("k524init", code, "getting V5 credentials");
          exit(1);
index 8eee85cec00426b8f4078c4c31b7ad6b268b1399..7ed942c1a5d41cb8d366096660c4ebdd244ca693 100644 (file)
@@ -32,7 +32,7 @@ extern int krb524_debug;
 
 int krb524_convert_tkt_skey
        PROTOTYPE((krb5_context context, krb5_ticket *v5tkt, KTEXT_ST *v4tkt, 
-                  krb5_keyblock *skey));
+                  krb5_keyblock *v5_skey, krb5_keyblock *v4_skey));
 
 /* conv_princ.c */
 
index 6522e75516607d699fe686886dc94dfe9cef2daa..e062a3392d7a64cea39b4c157fbaf1fa3044495e 100644 (file)
@@ -92,7 +92,8 @@ int main(argc, argv)
      int ret, s;
      fd_set rfds;
      krb5_context context;
-     
+     krb5_realm_params *rparams;
+     char *realm = 0;
      krb5_init_context(&context);
      krb524_init_ets(context);
 
@@ -116,6 +117,11 @@ int main(argc, argv)
      signal(SIGINT, request_exit);
      signal(SIGHUP, request_exit);
      signal(SIGTERM, request_exit);
+     if (!realm&&(ret = krb5_get_default_realm(context, &realm)))
+       {
+com_err(whoami, ret, "Getting default realm");
+exit(1);
+}
 
      if (use_keytab)
          init_keytab(context);
@@ -212,57 +218,94 @@ void init_master(context)
      krb5_context context;
 {
      int ret;
-     char *realm;
-     
-     if ((ret = krb5_get_default_realm(context, &realm))) {
+krb5_realm_params *rparams;
+     char *realm = 0;
+     char *key_name =0, *dbname = 0;
+     char *stash_file = 0;
+
+     /* Use the stashed enctype */
+     master_keyblock.enctype = ENCTYPE_UNKNOWN;
+
+     if (!realm&&(ret = krb5_get_default_realm(context, &realm))) {
          com_err(whoami, ret, "getting default realm");
          cleanup_and_exit(1, context);
      }
-     if ((ret = krb5_db_setup_mkey_name(context, NULL, realm, (char **) 0,
-                                      &master_princ))) {
-          free(realm);
-         com_err(whoami, ret, "while setting up master key name");
-         cleanup_and_exit(1, context);
-     } else {
-          free(realm);
+     if ((ret = krb5_read_realm_params(context,
+                                       realm,
+                                       (char *) NULL, (char *) NULL,
+                                       &rparams))) {
+       com_err(whoami, ret, "Reading KDC profile");
+krb5_xfree(realm);
+       cleanup_and_exit(1,context);
      }
+     
+       /* Get the value for the database */
+       if (rparams->realm_dbname && !dbname)
+           dbname = strdup(rparams->realm_dbname);
 
-     /* Use the stashed enctype */
-     master_keyblock.enctype = ENCTYPE_UNKNOWN;
+       /* Get the value for the master key name */
+       if (rparams->realm_mkey_name && !key_name)
+         key_name = strdup(rparams->realm_mkey_name);
 
+       /* Get the value for the master key type */
+       if (rparams->realm_enctype_valid  ) 
+         master_keyblock.enctype = rparams->realm_enctype;
+     
+     /* Get the value for the stashfile */
+     if (rparams->realm_stash_file)
+       stash_file = strdup(rparams->realm_stash_file);
+     
+     if ((ret = krb5_db_set_name(context, dbname))) {
+                                                     com_err(whoami, ret, "Setting database name");
+                                                     cleanup_and_exit(1,context);
+                                                   }
+     
+     if ((ret = krb5_db_setup_mkey_name(context, key_name, realm, (char **) 0,
+                                       &master_princ))) {
+       free(realm);
+       com_err(whoami, ret, "while setting up master key name");
+       cleanup_and_exit(1, context);
+     } else {
+       free(realm);
+     }
+     
+     
      if ((ret = krb5_db_fetch_mkey(context, master_princ, &master_encblock,
-                                 FALSE, /* non-manual type-in */
-                                 FALSE, /* irrelevant, given prev. arg */
-                                 (char *) NULL,
-                                 0, &master_keyblock))) {
-         com_err(whoami, ret, "while fetching master key");
-         cleanup_and_exit(1, context);
+                                  FALSE, /* non-manual type-in */
+                                  FALSE, /* irrelevant, given prev. arg */
+                                  stash_file,
+                                  0, &master_keyblock))) {
+       com_err(whoami, ret, "while fetching master key");
+       cleanup_and_exit(1, context);
      }
-
+     
      if ((ret = krb5_db_init(context))) {
-         com_err(whoami, ret, "while initializing master database");
-         cleanup_and_exit(1, context);
-     }
+                                         com_err(whoami, ret, "while initializing master database");
+                                         cleanup_and_exit(1, context);
+                                       }
      if ((ret = krb5_process_key(context, &master_encblock, 
                                 &master_keyblock))) {
-         krb5_db_fini(context);
-         com_err(whoami, ret, "while processing master key");
-         cleanup_and_exit(1, context);
+       krb5_db_fini(context);
+       com_err(whoami, ret, "while processing master key");
+       cleanup_and_exit(1, context);
      }
-}
+   }
 
 krb5_error_code do_connection(s, context)
      int s;
      krb5_context context;
 {
      struct sockaddr saddr;
-     krb5_ticket *v5tkt;
+     krb5_ticket *v5tkt = 0;
      KTEXT_ST v4tkt;
-     krb5_keyblock service_key;
+     krb5_keyblock v5_service_key, v4_service_key;
      krb5_data msgdata, tktdata;
      char msgbuf[MSGSIZE], tktbuf[TKT_BUFSIZ], *p;
      int n, ret, saddrlen;
-     
+
+     /* Clear out keyblock contents so we don't accidentally free the stack.*/
+     v5_service_key.contents = v4_service_key.contents = 0;
+
      msgdata.data = msgbuf;
      msgdata.length = MSGSIZE;
 
@@ -297,18 +340,25 @@ krb5_error_code do_connection(s, context)
      if (debug)
          printf("V5 ticket decoded\n");
      
-     /* XXX ENCTYPE_DES_CBC_MD5 shouldn't be hardcoded here.  Should be
-        derived from the ticket. */
-     if ((ret = lookup_service_key(context, v5tkt->server, ENCTYPE_DES_CBC_MD5, 
-                                 &service_key)))
+     if ((ret = lookup_service_key(context, v5tkt->server,
+                                  v5tkt->enc_part.enctype, 
+                                  &v5_service_key)))
+         goto error;
+
+     if ((ret = lookup_service_key(context, v5tkt->server,
+                                  ENCTYPE_DES_CBC_CRC,
+                                  &v4_service_key)))
          goto error;
+
      if (debug)
          printf("service key retrieved\n");
 
-     ret = krb524_convert_tkt_skey(context, v5tkt, &v4tkt, &service_key);
+     ret = krb524_convert_tkt_skey(context, v5tkt, &v4tkt, &v5_service_key,
+                                  &v4_service_key);
      if (ret)
          goto error;
-     krb5_free_keyblock_contents(context, &service_key);
+     krb5_free_keyblock_contents(context, &v5_service_key);
+     krb5_free_keyblock_contents(context, &v4_service_key);
      krb5_free_ticket(context, v5tkt);
      if (debug)
          printf("credentials converted\n");
@@ -351,6 +401,14 @@ write_msg:
               ret = errno;
      if (debug)
          printf("reply written\n");
+/* If we have keys to clean up, do so.*/
+     if (v5_service_key.contents)
+       krb5_free_keyblock_contents(context, &v5_service_key);
+     if (v4_service_key.contents)
+       krb5_free_keyblock_contents(context, &v4_service_key);
+     if (v5tkt)
+       krb5_free_ticket(context, v5tkt);
+     
               
      return ret;
 }
@@ -372,24 +430,25 @@ krb5_error_code lookup_service_key(context, p, ktype, key)
      } else if (use_master) {
          if ((ret = krb5_db_init(context)))
               return ret;
-         return kdc_get_server_key(context, p, key, NULL);
+         return kdc_get_server_key(context, p, key, NULL, ktype);
      }
      return 0;
 }
 
 /* taken from kdc/kdc_util.c, and modified somewhat */
-krb5_error_code kdc_get_server_key(context, service, key, kvno)
+krb5_error_code kdc_get_server_key(context, service, key, kvno, ktype)
     krb5_context context;
     krb5_principal service;
     krb5_keyblock *key;
     krb5_kvno *kvno;
+krb5_enctype ktype;
 {
     krb5_error_code ret;
     int nprincs;
     krb5_db_entry server;
     krb5_boolean more;
     int i, vno, ok_key;
-
+    krb5_key_data *pkey;
     nprincs = 1;
     if ((ret = krb5_db_get_principal(context, service, &server, 
                                     &nprincs, &more))) 
@@ -402,19 +461,37 @@ krb5_error_code kdc_get_server_key(context, service, key, kvno)
        krb5_db_free_principal(context, &server, nprincs);
        return(KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN);
     }
-
-    /* convert server key into a real key (it is encrypted in the database) */
-    for (vno = i = 0; i < server.n_key_data; i++) {
-       if (vno < server.key_data[i].key_data_kvno) {
-           vno = server.key_data[i].key_data_kvno;
-           ok_key = i;
-       }
-    }
+/* We use krb5_dbe_find_enctype twice because
+   * in the case of a ENCTYPE_DES_CBC_CRC key, we prefer to find a krb4
+   * salt type over a normal key..  Note this may create a problem if the
+   * server key is passworded and has both a normal and v4 salt.  There is
+   * no good solution to this.*/
+    
+    if (krb5_dbe_find_enctype(context,
+                             &server,
+                             ktype,
+                             (ktype == ENCTYPE_DES_CBC_CRC)?
+                             KRB5_KDB_SALTTYPE_V4:-1,
+                             -1,
+                             &pkey) &&
+       krb5_dbe_find_enctype(context,
+                             &server,
+                             -1,
+                             -1,
+                             -1,
+                             &pkey))
+      {
+       krb5_db_free_principal(context, &server, nprincs);
+       return (KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN);
+      }
+if (kvno)
+    *kvno = pkey->key_data_kvno;
     ret = krb5_dbekd_decrypt_key_data(context, &master_encblock, 
-                                      &server.key_data[ok_key], key, NULL);
+                                     pkey, key, NULL);
     krb5_db_free_principal(context, &server, nprincs);
-    if (kvno)
-       *kvno = vno;
+
+
+
     return ret;
 }