From hartmans@MIT.EDU Sun Nov 10 00:21:38 1996 Received: from MIT.EDU (PACIFIC-CARRIER-ANNEX.MIT.EDU [18.69.0.28]) by rt-11.MIT.EDU (8.7.5/8.7.3) with SMTP id AAA11556 for ; Sun, 10 Nov 1996 00:21:37 -0500 Received: from PLANET-ZORP.MIT.EDU by MIT.EDU with SMTP id AA21983; Sun, 10 Nov 96 00:21:36 EST Received: (from hartmans@localhost) by planet-zorp.MIT.EDU (8.6.12/8.6.12) id AAA04105; Sun, 10 Nov 1996 00:21:34 -0500 Message-Id: <199611100521.AAA04105@planet-zorp.MIT.EDU> Date: Sun, 10 Nov 1996 00:21:34 -0500 From: Sam Hartman Reply-To: hartmans@MIT.EDU, fastcart@MIT.EDU To: krb5-bugs@MIT.EDU Cc: fastcart@MIT.EDU Subject: add function to cannonicalize hostname for use by telnet and other apps X-Send-Pr-Version: 3.99 >Number: 170 >Category: krb5-libs >Synopsis: add function to cannonicalize hostname for use by telnet and other apps >Confidential: no >Severity: critical >Priority: medium >Responsible: hartmans >State: open >Class: sw-bug >Submitter-Id: unknown >Arrival-Date: Sun Nov 10 00:22:01 EST 1996 >Last-Modified: Sun Nov 10 19:05:00 EST 1996 >Originator: Sam Hartman >Organization: >Release: 1.0-development >Environment: System: NetBSD planet-zorp 1.1 NetBSD 1.1 (ATHENAOTHER) #4: Thu Jan 18 03:29:37 EST 1996 ghudson@zygorthian-space-raiders:/u1/build/sys/arch/i386/compile/ATHENAOTHER i386 >Description: This is the old athena.dialup problem revisited. Basically, our telnet is significantly worse than the current Athena release; we don't even try to reverse resolve this. If I can implement this tonight, I will check it in; as I will demonstrate with attatchments, the problem is well understood and the solution has been hashed out fairly well in the past. >How-To-Repeat: >Fix: >Audit-Trail: From: Sam Hartman To: krb5-bugs@MIT.EDU Cc: Subject: krb5-libs/170: [daemon@ATHENA.MIT.EDU : full explanation of proposed krb5_sname_to_princ change] Date: Sun, 10 Nov 1996 01:44:18 -0500 ------- Forwarded transaction [1044] daemon@ATHENA.MIT.EDU (Sam Hartman) Kerberos_V5_Development 04/01/96 11:50 (63 lines) Subject: full explanation of proposed krb5_sname_to_princ change To: krbdev@MIT.EDU From: Sam Hartman Date: 01 Apr 1996 11:50:22 -0500 Ted asked me to go through the background of my proposed change, then to fully explain what I was trying to do. Basically, I'm trying to solve the problem of machines that have multiple A records in DNS--machines like athena.dialup.mit.edu, et al. Newer versions of Bind tend to round-robbin these addresses, so you are likely to get different answers if you call gethostbyname() on the same domain twice in a row. The current model works as follows: * gethostbyname() to decide what to connect to. * connect * in krb5_sname_to_princ, call gethostbyname() again to get the cannonical name to use for the Kerberos principal. So, if you connect to vongole, you are likely to get marinara tickets. This confuses users significantly, because it never works. My proposal is to somehow save the address you actually connect to, and do a gethostbyaddr on this address. The cannonicalization of this address should be the specific name of the host you actually connected to. It is important to note that this will still work if you actually use the name athena.dialup.mit.edu as the official name for multiple hosts, although you will have to have a host/athena.dialup.mit.edu key on each host. The case in which my proposal works worse than the current system is if you have multiple different PTR records for the same IP address. Honestly, I think multiple A records is so much more useful than multiple PTR records for the same name (is that even legal?) that this is a minor concern. It may also create a problem if you try to connect to a host that doesn't support reverse-resolution correctly, but I think several other things break in this situation as well. Another problem with the proposal is that GSS_NT_SERVICE names in GSSAPI are not dealt with. I do not have a solution for GSSAPI; I suspect that there is not a good answer. As far as actual interface changes, I don't want to take a sockaddr_in on a krb5 call. Instead, I would rather take a krb5_address. Unfortunately, there isn't a good API to generate these from a sockaddr_in. Also, as I was thinking about things, I realized that you normally want to set up an auth context,call krb5_sname_to_princ, call krb5_mk_req or krb5_sendauth, etc. As part of setting up the context, you call krb5_genfulladdrs. So, it sounds reasonable to me for there to be a version of krb5_sname_to_princ that took an authcontext instead of a hostname; it would get the IP address from the authcontext. --Sam --[1044]-- ------- End forwarded transaction From: Sam Hartman To: krb5-bugs@MIT.EDU Cc: Subject: krb5-libs/170: [daemon@ATHENA.MIT.EDU : Re: full explanation of proposed krb5_sname_to_princ change] Date: Sun, 10 Nov 1996 01:45:03 -0500 ------- Forwarded transaction [1045] daemon@ATHENA.MIT.EDU (Sam Hartman) Kerberos_V5_Development 04/01/96 22:12 (26 lines) Subject: Re: full explanation of proposed krb5_sname_to_princ change To: Sam Hartman Cc: krbdev@MIT.EDU From: Sam Hartman Date: 01 Apr 1996 22:12:24 -0500 In-Reply-To: Sam Hartman's message of 01 Apr 1996 11:50:22 -0500 Sam Hartman writes: > My proposal is to somehow save the address you actually > connect to, and do a gethostbyaddr on this address. The > cannonicalization of this address should be the specific name of the > host you actually connected to. It is important to note that this > will still work if you actually use the name athena.dialup.mit.edu as > the official name for multiple hosts, although you will have to have a > host/athena.dialup.mit.edu key on each host. > Marc was confused by this so others will probably be as well. You only need host/athena.dialup.mit.edu keys if the cannonical name of all your dialups was athena.dialup.mit.edu. I.E. you ahve multiple machines that have different IPs and share the same cannonical name. We don't have this at MIT, so you would only need host/vongole.mit.edu tickets on vongole. --Sam --[1045]-- ------- End forwarded transaction From: Sam Hartman To: krb5-bugs@MIT.EDU Cc: Subject: krb5-libs/170: [daemon@ATHENA.MIT.EDU : Re: full explanation of proposed krb5_sname_to_princ change] Date: Sun, 10 Nov 1996 01:45:47 -0500 ------- Forwarded transaction [1046] daemon@ATHENA.MIT.EDU (Theodore Ts'o) Kerberos_V5_Development 04/08/96 20:05 (54 lines) Subject: Re: full explanation of proposed krb5_sname_to_princ change Date: Mon, 8 Apr 1996 20:05:26 -0400 From: Theodore Ts'o To: Sam Hartman Cc: krbdev@MIT.EDU In-Reply-To: Sam Hartman's message of 01 Apr 1996 11:50:22 -0500, From: Sam Hartman Date: 01 Apr 1996 11:50:22 -0500 Ted asked me to go through the background of my proposed change, then to fully explain what I was trying to do. Basically, I'm trying to solve the problem of machines that have multiple A records in DNS--machines like athena.dialup.mit.edu, et al. Newer versions of Bind tend to round-robbin these addresses, so you are likely to get different answers if you call gethostbyname() on the same domain twice in a row. My proposal is to somehow save the address you actually connect to, and do a gethostbyaddr on this address. The cannonicalization of this address should be the specific name of the host you actually connected to. It is important to note that this will still work if you actually use the name athena.dialup.mit.edu as the official name for multiple hosts, although you will have to have a host/athena.dialup.mit.edu key on each host. Sam, Sorry for the delay in getting back to you. I've been rather swamped lately. Instead of changing krb5_sname_to_princ, or creating a new version of krb5_sname_to_princ, what about simply having a new function, krb5_os_cannonicalize_hostname(), which takes as input a hostname, and calls gethostyaddr(gethostbyname()) on the input hostname and returns the resulting hostname? Then we simply have to change those programs which might have to call krb5_os_cannonicalize_hostname() first, and then using the resulting hostname for krb5_sname_to_princ() as well as using that hostname to call gethostbyname(), followed by connect(). This solution makes the same assumptions as your proposal (there must be one PTR record for a given IP address), and it avoids needing to use addresses in a krb5 interface which (as you point out) is a real pain to do. We avoid the whole morass of sockaddr_in vs. krb5_addresses, and the easy or non-ease of generating them by simply using a char * for the canonicalized hostname. It does have the disadvantage of an additional DNS resolver call, but that seems like a minor price to pay. - Ted --[1046]-- ------- End forwarded transaction From: Sam Hartman To: krb5-bugs@MIT.EDU Cc: Subject: krb5-libs/170: [daemon@ATHENA.MIT.EDU : Re: full explanation of proposed krb5_sname_to_princ change] Date: Sun, 10 Nov 1996 01:47:03 -0500 ------- Forwarded transaction [1050] daemon@ATHENA.MIT.EDU (Sam Hartman) Kerberos_V5_Development 04/10/96 22:56 (30 lines) Subject: Re: full explanation of proposed krb5_sname_to_princ change To: "Theodore Ts'o" Cc: Sam Hartman , krbdev@MIT.EDU From: Sam Hartman Date: 10 Apr 1996 22:55:55 -0400 In-Reply-To: Theodore Ts'o's message of Mon, 8 Apr 1996 20:05:26 -0400 Theodore Ts'o writes: > > Instead of changing krb5_sname_to_princ, or creating a new > version of krb5_sname_to_princ, what about simply having a new function, > krb5_os_cannonicalize_hostname(), which takes as input a hostname, and calls > gethostyaddr(gethostbyname()) on the input hostname and returns the > resulting hostname? > > Then we simply have to change those programs which might have to > call krb5_os_cannonicalize_hostname() first, and then using the > resulting hostname for krb5_sname_to_princ() as well as using that > hostname to call gethostbyname(), followed by connect(). The RFC does not require a unique name exist for each host. I > can call all the dialups athena.dialup.mit.edu and give them > different IP addresses, or more likely to happen in the real world, > call one of the the dialups athena.dialup.mit.edu, the secondary > dialup athena-2.dailup.mit.edu, etc. My original solution would > work in this case, correctly using athena-2.dialup.mit.edu only if > you end up connecting to that machine. Your solution breaks if you > connect to athena.dialup.mit.edu but then krb5_sname_to_princ > re-cannonicalizes athena.dialup.mit.edu and gets > athena-2.dialup.mit.edu. --[1050]-- ------- End forwarded transaction From: Sam Hartman To: krb5-bugs@MIT.EDU Cc: Subject: krb5-libs/170: [daemon@ATHENA.MIT.EDU : Re: full explanation of proposed krb5_sname_to_princ change] Date: Sun, 10 Nov 1996 01:47:44 -0500 ------- Forwarded transaction [1051] daemon@ATHENA.MIT.EDU (Theodore Ts'o) Kerberos_V5_Development 04/11/96 12:15 (33 lines) Subject: Re: full explanation of proposed krb5_sname_to_princ change Date: Thu, 11 Apr 1996 12:15:33 -0400 From: Theodore Ts'o To: Sam Hartman Cc: "Theodore Ts'o" , Sam Hartman , krbdev@MIT.EDU In-Reply-To: Sam Hartman's message of 10 Apr 1996 22:55:55 -0400, Err no. I don't think so. Consider the following situation. athena.dialup.mit.edu resolves to 3 ip address 18.172.0.2, 18.172.0.3, and 18.172.0.4. Each of these address have a reverse pointer to dialup-1.mit.edu, dialup-2.mit.edu, dialup-3.mit.edu. My solution is to have a canonicalization function which resolves athena.dialup.mit.edu, gets an IP address, and then does a reverse-resolve to get one of dialup-[123].mit.edu. This is an address which when forward resolved, gets you one and only one IP address. Alternatively, 18.172.0.2, 18.172.0.3, and 18.172.04 could all reverse resolve back to athena.dialup.mit.edu. But in that case, your solution won't work either, unless the three machines share a srvtab key for host/athena.dialup.mit.edu. If the three machines share a srvtab key, then everything works fine. The only case where your solution would work and mine would fail is if athena.dialup.mit.edu resolves one of the above three addresses --- but so do dialup-1.mit.edu, dialup-2.mit.edu, and dialup-3.mit.edu. But I'd just as soon consider that a pathalogical case, and not deal with it. I can't think of a good excuse for doing anything like that. - Ted --[1051]-- ------- End forwarded transaction From: Sam Hartman To: krb5-bugs@MIT.EDU Cc: Subject: krb5-libs/170: [daemon@ATHENA.MIT.EDU : Re: full explanation of proposed krb5_sname_to_princ change] Date: Sun, 10 Nov 1996 01:48:17 -0500 ------- Forwarded transaction [1052] daemon@ATHENA.MIT.EDU (Sam Hartman) Kerberos_V5_Development 04/13/96 14:52 (47 lines) Subject: Re: full explanation of proposed krb5_sname_to_princ change To: "Theodore Ts'o" Cc: Sam Hartman , krbdev@MIT.EDU From: Sam Hartman Date: 13 Apr 1996 14:52:39 -0400 In-Reply-To: Theodore Ts'o's message of Thu, 11 Apr 1996 12:15:33 -0400 >>>>> "Theodore" == Theodore Ts'o writes: First of all, sorry about the incredibly broken quoting on my last message. Emacs 19.30 does interesting things with adaptive-fill that I didn't expect. Theodore> The only case where your solution would work and mine Theodore> would fail is if athena.dialup.mit.edu resolves one of Theodore> the above three addresses --- but so do Theodore> dialup-1.mit.edu, dialup-2.mit.edu, and Theodore> dialup-3.mit.edu. But I'd just as soon consider that a Theodore> pathalogical case, and not deal with it. I can't think Theodore> of a good excuse for doing anything like that. Agreed that this is the only different case. One other DNS question before I go ahead an implement the cannonicalization function. How do we (medium-term, before secure DNS is deployed) want to handle the problem of deciding whether the server principal we are mutually authenticating to is a reasonable principal for the input the user gave. This wasn't a major problem before forwarded tickets started working enough of the time to be useful. However, it's all too easy to spoof DNS. Picture the following scenerio: * an administrator does something along the lines of rlogin moira2.mit.edu -l root -x -f * The DNS query returns moira2.mit.edu is a cname for charon.mit.edu. * The system cannonicalizes charon, finding it resolves to itself (charon.mit.edu) * The client forwards tickets to charon.mit.edu I don't really see that these problems need to be related, but we might as well decide how to deal with all DNS issues then implement as time permit, so that if there are any interactions we can deal with them. --Sam --[1052]-- ------- End forwarded transaction From: Sam Hartman To: krb5-bugs@MIT.EDU Cc: Subject: krb5-libs/170: [daemon@ATHENA.MIT.EDU : Re: full explanation of proposed krb5_sname_to_princ change] Date: Sun, 10 Nov 1996 01:51:58 -0500 ------- Forwarded transaction [1065] daemon@ATHENA.MIT.EDU (Theodore Y. Ts'o) Kerberos_V5_Development 04/15/96 14:12 (24 lines) Subject: Re: full explanation of proposed krb5_sname_to_princ change Date: Mon, 15 Apr 1996 14:12:55 -0400 From: "Theodore Y. Ts'o" To: Sam Hartman Cc: "Theodore Ts'o" , Sam Hartman , krbdev@MIT.EDU In-Reply-To: Sam Hartman's message of 13 Apr 1996 14:52:39 -0400, Well, here's a straw-man proposal to deal with the problem that you've mentioned. If after passing the result returned by hostname canonicalization function does not "reasonably" match the input name (where reasonable means allowing for case differences and tacking on of the default realm), the pair of (user-input-hostname, canonicalized-hostname) must appear on either a system-wide default list, or a per-user list of acceptable hostname cannonicalizations. If the canonicalized hostname isn't on the "OK" list, then rlogin will abort with an error. There will be an option to override this error condition. This is not a particular pretty solution, but it does solve the problem that you raised. Secure DNS is a much more elegant solution.... - Ted --[1065]-- ------- End forwarded transaction From: Sam Hartman To: krb5-bugs@MIT.EDU, krb5-bugs-redist@MIT.EDU, fastcart@MIT.EDU Cc: Subject: krb5-libs/170: What I'm doing Date: Sun, 10 Nov 1996 02:28:56 -0500 This summary is presented for people who don't actually want to to take the time to read through the transactions from krbdev I appended to the PR. Basically, the problem is that applications like telnet call gethostbyname twice on hosts like athena.dialup.mit.edu and with round-robbin name servers, you can lose significantly because you get different tickets than you actually connect to. The solution that Ted eventually suggested is as follows: Instead of changing krb5_sname_to_princ, or creating a new version of krb5_sname_to_princ, what about simply having a new function, krb5_os_cannonicalize_hostname(), which takes as input a hostname, and calls gethostyaddr(gethostbyname()) on the input hostname and returns the resulting hostname? Then we simply have to change those programs which might have to call krb5_os_cannonicalize_hostname() first, and then using the resulting hostname for krb5_sname_to_princ() as well as using that hostname to call gethostbyname(), followed by connect(). This solution makes the same assumptions as your proposal (there must be one PTR record for a given IP address), and it avoids needing to use addresses in a krb5 interface which (as you point out) is a real pain to do. We avoid the whole morass of sockaddr_in vs. krb5_addresses, and the easy or non-ease of generating them by simply using a char * for the canonicalized hostname. It does have the disadvantage of an additional DNS resolver call, but that seems like a minor price to pay. From: John Hawkinson To: Sam Hartman Cc: krb5-bugs@MIT.EDU, krb5-prs@RT-11.MIT.EDU Subject: Re: krb5-libs/170: What I'm doing Date: Sun, 10 Nov 1996 07:14:37 -0500 > This summary is presented for people who don't actually want > to to take the time to read through the transactions from krbdev I > appended to the PR. Basically, the problem is that applications like What you appended never arrived on krb5-prs. The How-To-Repeat and Fix sections of he PR were empty, and the Description had one paragraph. --jhawk From: Sam Hartman To: Sam Hartman Cc: krb5-bugs@MIT.EDU, krb5-bugs-redist@MIT.EDU, fastcart@MIT.EDU Subject: Re: krb5-libs/170: What I'm doing Date: 10 Nov 1996 16:34:34 -0500 There is one minor problem with my proposal to adopt Ted's solution: it doesn't actually work for telnet, which was the primary program I was trying to fix. Basically, the problem is that telnet will try to connect to all the IP addresses for a machine once it receives a response to the gethostbyname request. Unfortunately, if I cannonicalize a hostname before connecting, I will only try connecting to one of the IP addresses. Because any real solution to the problem will require some actual thought and discussion, it would be inappropriate to work on at this point in the release process. Instead, I will solve the problem for the special case of telnet. I will do this by doing a gethostbyaddr after connecting to the remote system. If I am successful, then I will save the hostname from this call to be used for Kerberos authentication. Otherwise, I will use the hostname that I received from the earlier gethostbyname call. In all the situations jhawk and I thought of, this worked at least as well as the current scheme. Also, I beleive it is similar to a patch adopted by SIPB for SIPB Athena. --Samn From: Sam Hartman To: explorer@MIT.EDU Cc: krb5-bugs@MIT.EDU Subject: krb5-libs/170: Calling gethostbyaddr on connected host in Windows telnet Date: Sun, 10 Nov 1996 19:03:07 -0500 Hi. I'm not sure if you're the right person to talk to, but you probably at least know if you aren't. I recently fixed an annoying bug in the MIT telnet code that caused service pools like athena.dialup.mit.edu to fail to work with k5telnet. Basically, the problem is that when you forward resolve the hostname to get the IP address and the cannonical hostname, you will end up with something like athena.dialup.mit.edu having a IP address of 18.71.0.x. The problem is that when you call the krb4 version of krb5_sname_to_princ (sorry, I don't remember my krb4 library functions), you will try to get tickets for rcmd.athena@DIALUP.MIT.EDU. (If MIT were using krb5, you would try to get tickets for host/athena.dialup.mit.edu@ATHENA.MIT.EDU.) However, the actual host you connect to will be some random host such as vongole.mit.edu. If you do an extra gethostbyaddr after you make the connection, then much better things will happen. (The MIT dialups actually do have rcmd.athena tickets, and the krb.realms file ideally make sure that they end up in the ATHENA.MIT.EDU realm. However, for people using krb5, you want to make sure people only request tickets for the actual host not the pool name. If you request tickets for the service pool, you can have problems with authenticator replay: I can watch your authenticator going over the net, connect to another server in the pool, and use the fact that they share a key but not a replay cache to gain authenticated access.) I have included the patch to the Unix telnet sources below; I doubt the Windows code is similar, but I wanted to clearly communicate what changes I had made. If you ned more details on the issues involved, you can look at PR 170 in the MIT database (you are on the ACL). Ideally, MIT would like to get a patch from Cygnus to deal with this. However, even if you can't or don't have time to give us the patch, we would like to start the process of squashing dependencies on shared keys between hosts, so it would be great if Cygnus would fix it internally. Thanks, --Sam Index: commands.c =================================================================== RCS file: /mit/krbdev/.cvsroot/src/appl/telnet/telnet/commands.c,v retrieving revision 5.23 retrieving revision 5.24 diff -c -r5.23 -r5.24 *** commands.c 1996/11/02 01:46:31 5.23 --- commands.c 1996/11/10 23:48:51 5.24 *************** *** 2554,2559 **** --- 2554,2566 ---- return 0; } connected++; + host = gethostbyaddr((char *) &sin.sin_addr, sizeof(struct in_addr), sin.sin_family); + if (host) { + strncpy(_hostname, host->h_name, sizeof(_hostname)); + _hostname[sizeof(_hostname)-1] = '\0'; + hostname = _hostname; + } + #if defined(AUTHENTICATION) || defined(ENCRYPTION) auth_encrypt_connect(connected); #endif /* defined(AUTHENTICATION) || defined(ENCRYPTION) */ From: Sam Hartman To: krb5-prs@RT-11.MIT.EDU Cc: krb5-bugs@MIT.EDU Subject: krb5-libs/170: Interum fix for telnet Date: Sun, 10 Nov 1996 19:04:18 -0500 The patch ends up being incredibly trivial. This should help people avoid dependence on having multiple hosts that share the same key. Index: commands.c =================================================================== RCS file: /mit/krbdev/.cvsroot/src/appl/telnet/telnet/commands.c,v retrieving revision 5.23 retrieving revision 5.24 diff -c -r5.23 -r5.24 *** commands.c 1996/11/02 01:46:31 5.23 --- commands.c 1996/11/10 23:48:51 5.24 *************** *** 2554,2559 **** --- 2554,2566 ---- return 0; } connected++; + host = gethostbyaddr((char *) &sin.sin_addr, sizeof(struct in_addr), sin.sin_family); + if (host) { + strncpy(_hostname, host->h_name, sizeof(_hostname)); + _hostname[sizeof(_hostname)-1] = '\0'; + hostname = _hostname; + } + #if defined(AUTHENTICATION) || defined(ENCRYPTION) auth_encrypt_connect(connected); #endif /* defined(AUTHENTICATION) || defined(ENCRYPTION) */ >Unformatted: