[1434] in Kerberos-V5-bugs
Configurable Authentication Paths - Suggestion for K5 beta 5
daemon@ATHENA.MIT.EDU (Doug Engert)
Wed May 24 12:45:07 1995
Date: Wed, 24 May 95 11:44:44 CDT
From: "Doug Engert" <DEEngert@anl.gov>
To: <krb5-bugs@MIT.EDU>, <kerberos@MIT.EDU>, <authtf@es.net>
Ted,
I would like to resubmit the Configurable Authentication Path
modification for Kerberos 5 beta 5. The modification allows the
system administrators to define the path of intermediate realms
to be used in cross-realm authentication. This allows for greater
flexibility in setting up cross-realm authentication.
This is a major rewrite of the previous versions of this
modification which had not changed over the K5.3, K5.4, K5.4.1,
K5.4.2 and K5.4.3. The new version uses the krb5.conf file with a
[capaths] section. The subsections are the names of the
client-realms, with the subsubsections being server-realm. The
values are the intermediate realms which should be on the path.
If a client-realm server-realm combination is not found, the
standard hierarchical path is returned.
For example, ANL, PNL, NERSC all want to use the ESnet realm as
the intermediate realm. Each wants its realm name based on the
DNS domain name, anl.gov, pnl.gov, nersc,gov, and es.net.
The krb5.conf file used at the ANL would contain the following:
[capaths]
anl.gov = {
es.net = .
nersc.gov = es.net
pnl.gov = es.net
}
es.net = {
anl.gov = .
}
nersc.gov = {
anl.gov = es.net
}
pnl.gov = {
anl.gov = es.net
}
The profile_get_values() routine is used, with the names array
consisting of: "capaths", <client's realm>, <server's realm>, 0.
The returned values are the intermediate realms. An intermediate
realm of "." is mean to mean directly connected, since the
profile_get routines don't seam to allow a null value.
With N realms there are N**2 paths which may need to be defined.
But each realms krb5.conf only needs 2*(N-1) paths, (N-1) paths
the clients used to get to the servers realms, and (N-1) paths
which the servers use to check the transited fields when
processing foreign clients. (Intermediate realms may need more
entries, see below.)
The previous version of this modification was more sophisticated
in that the table used provided the non-hierarchical part of the
path, and would start with the hierarchical path, then modify it.
The new version is a simple table lookup of the client's and
server's realms.
The modification is solely contained within the walk_rtree.c
module. This module is used by the client to get the list of TGTs
which it will need to get a ticket in the server's realm. It is
also used be servers from the rd_req_dec.c via the chk_trans.c
routines. It is used here to get a list of intermediate realms.
This version of the modification has been tested using the
authentication. This allows for greater flexibility in setting up
cross-realm authentication.
This is a major rewrite of the previous versions of this modification
which had not changed over the K5.3, K5.4, K5.4.1, K5.4.2 and K5.4.3.
The new version uses the krb5.conf file with a [capaths] section.
The subsections are the names of the client-realms, with the
subsubsections being server-realm. The values are the intermediate
realms which should be on the path.
For example, ANL, PNL, NERSC all want to use the ESnet realm as
the intermediate realm. Each wants its realm name based on the
DNS domain name, anl.gov, pnl.gov, nersc,gov, and es.net.
The krb5.conf file used at the ANL would contain the following:
With N realms there are N**2 paths which may need to be defined.
But each realms krb5.conf only needs 2*(N-1) paths, (N-1) paths
the clients used to get to the servers realms, and (N-1) paths
which the servers use to check the transited fields when
processing foreign clients. (Intermediate realms may need more
entries, see below.)
The modification has been tested with the t_walk_rtree.c routine
provided with K5.5. It has not been tested as of yet in a real
cross-realm situation. The K5.4.2 version of the modification was
used in our Cross Realm Authentication Pilot Project
successfully, and the function of the walk_rtree.c has not
changed. ANL, PNL, NERSC and Sandia will be testing this code
soon, but will be using DCE Security servers as the KDCs with K5
beta 5 clients and servers with this modification.
Above I said that the [capaths] sections in the intermediate
realm's KDC would have to be larger. This is caused the
rd_req_dec.c routines checking the transited field of every
request. I would argue that only requests which are for non TGTs
in the local realm need to be checked. If this is true, then the
intermediate realms [capaths] section would not need all the
intermediate paths. I would like to encourage discussion in this
area.
A copy of the diff file for the modification can be found at
ftp://achilles.ctd.anl.gov/pub/kerberos.v5/k543.cross.950524 I
have also placed a modified copy of walk_rtree.c for easier
reading in the same directory named k55.cross.walk_rtree.c
If you have any questions, please let me know.
Thanks
Doug
Douglas E. Engert
Systems Programming
Argonne National Laboratory
9700 South Cass Avenue
Argonne, Illinois 60439
(708) 252-5444
Internet: DEEngert@anl.gov
*** ./lib/krb5/krb/,walk_rtree.c Thu Apr 13 19:55:04 1995
--- ./lib/krb5/krb/walk_rtree.c Wed May 24 11:35:44 1995
***************
*** 24,29 ****
--- 24,87 ----
* krb5_walk_realm_tree()
*/
+ /* ANL - Modified to allow Configurable Authentication Paths.
+ * This modification removes the restriction on the choice of realm
+ * names, i.e. they nolonger have to be hierarchical. This
+ * is allowed by RFC 1510: "If a hierarchical orginization is not used
+ * it may be necessary to consult some database in order to construct
+ * an authentication path between realms." The database is contained
+ * in the [capath] section of the krb5.conf file.
+ * Client to server paths are defined. There are n**2 possible
+ * entries, but only those entries which are needed by the client
+ * or server need be present in its krb5.conf file. (n entries or 2*n
+ * entries if the same krb5.conf is used for clients and servers)
+ *
+ * for example: ESnet will be running a KDC which will share
+ * inter-realm keys with its many orginizations which include among
+ * other ANL, NERSC and PNL. Each of these orginizations wants to
+ * use its DNS name in the realm, ANL.GOV. In addition ANL wants
+ * to authenticatite to HAL.COM via a K5.MOON and K5.JUPITER
+ * A [capath] section of the krb5.conf file for the ANL.GOV clients
+ * and servers would look like:
+ *
+ * [capath]
+ * ANL.GOV = {
+ * NERSC.GOV = ES.NET
+ * PNL.GOV = ES.NET
+ * ES.NET = .
+ * HAL.COM = K5.MOON
+ * HAL.COM = K5.JUPITER
+ * }
+ * NERSC.GOV = {
+ * ANL.GOV = ES.NET
+ * }
+ * PNL.GOV = {
+ * ANL.GOV = ES.NET
+ * }
+ * ES.NET = {
+ * ANL.GOV = .
+ * }
+ * HAL.COM = {
+ * ANL.GOV = K5.JUPITER
+ * ANL.GOV = K5.MOON
+ * }
+ *
+ * In the above a "." is used to mean directly connected since the
+ * the profile routines cannot handle a null entry.
+ *
+ * If no client-to-server path is found, the default hierarchical path
+ * is still generated.
+ *
+ * This version of the Configurable Authentication Path modification
+ * differs from the previous versions prior to K5 beta 5 in that
+ * the profile routines are used, and the explicite path from
+ * client's realm to server's realm must be given. The modifications
+ * will work together.
+ * DEE - 5/23/95
+ */
+
+ #define CONFIGURABLE_AUTHENTICATION_PATH
+
#include "k5-int.h"
#include "int-proto.h"
***************
*** 51,56 ****
--- 109,156 ----
krb5_data tmpcrealm, tmpsrealm;
int nocommon = 1;
+ #ifdef CONFIGURABLE_AUTHENTICATION_PATH
+ const char *cap_names[4];
+ char *cap_client, *cap_server;
+ char **cap_nodes;
+ int cap_code;
+
+ if ((cap_client = (char *)malloc(client->length + 1)) == NULL)
+ return ENOMEM;
+ strncpy(cap_client, client->data, client->length);
+ cap_client[client->length] = '\0';
+
+ if ((cap_server = (char *)malloc(server->length + 1)) == NULL) {
+ krb5_xfree(cap_client);
+ return ENOMEM;
+ }
+ strncpy(cap_server, server->data, server->length);
+ cap_server[server->length] = '\0';
+
+ cap_names[0] = "capaths";
+ cap_names[1] = cap_client;
+ cap_names[2] = cap_server;
+ cap_names[3] = 0;
+
+ cap_code = profile_get_values(context->profile, cap_names, &cap_nodes);
+
+ krb5_xfree(cap_names[1]); /* done with client string */
+
+ if (cap_code == 0) { /* found a path, so lets use it */
+ links = 0;
+ if (*cap_nodes[0] != '.') { /* a link of . means direct */
+ while(cap_nodes[links]) {
+ links++;
+ }
+ }
+ cap_nodes[links] = cap_server; /* put server on end of list */
+ /* this simplifies the code later and make */
+ /* cleanup eaiser as well */
+
+ } else { /* no path use hierarchical method */
+ krb5_xfree(cap_names[2]); /* failed, don't need server string */
+ #endif
+
clen = client->length;
slen = server->length;
***************
*** 123,128 ****
--- 223,231 ----
if(com_sdot == server->data + server->length -1)
com_sdot = server->data - 1 ;
}
+ #ifdef CONFIGURABLE_AUTHENTICATION_PATH
+ } /* end of if use hierarchical method */
+ #endif
if (!(rettree = (krb5_principal *)calloc(links+2,
sizeof(krb5_principal)))) {
***************
*** 134,139 ****
--- 237,280 ----
krb5_xfree(rettree);
return retval;
}
+
+ #ifdef CONFIGURABLE_AUTHENTICATION_PATH
+ if (cap_code == 0) { /* found a path above */
+ tmpcrealm.data = client->data;
+ tmpcrealm.length = client->length;
+
+ while( i-1 <= links) {
+
+ tmpsrealm.data = cap_nodes[i-1];
+ /* don't count trailing whitespace from profile_get */
+ tmpsrealm.length = strcspn(cap_nodes[i-1],"\t ");
+
+ if (retval = krb5_tgtname(context,
+ &tmpsrealm, &tmpcrealm, &rettree[i])) {
+ while (i) {
+ krb5_free_principal(context, rettree[i-1]);
+ i--;
+ }
+ krb5_xfree(rettree);
+ /* cleanup the cap_nodes from profile_get */
+ for (i = 0; i<=links; i++) {
+ krb5_xfree(cap_nodes[i]);
+ }
+ krb5_xfree((char *)cap_nodes);
+ return retval;
+ }
+ tmpcrealm.data = tmpsrealm.data;
+ tmpcrealm.length = tmpsrealm.length;
+ i++;
+ }
+ /* cleanup the cap_nodes from profile_get last one has server */
+ for (i = 0; i<=links; i++) {
+ krb5_xfree(cap_nodes[i]);
+ }
+ krb5_xfree((char *)cap_nodes);
+
+ } else { /* if not cap then use hierarchical method */
+ #endif
for (prevccp = ccp = client->data;
ccp <= com_cdot;
ccp++) {
***************
*** 217,222 ****
--- 358,366 ----
return retval;
}
}
+ #ifdef CONFIGURABLE_AUTHENTICATION_PATH
+ }
+ #endif
*tree = rettree;
return 0;
}