Return-Path: Received: from pch.mit.edu (PCH.MIT.EDU [18.7.21.90]) by krbdev.mit.edu (Postfix) with ESMTP id C5A8D3DEDA; Tue, 15 May 2012 23:12:20 -0400 (EDT) Received: from pch.mit.edu (pch.mit.edu [127.0.0.1]) by pch.mit.edu (8.13.6/8.12.8) with ESMTP id q4G3CKD8004593; Tue, 15 May 2012 23:12:20 -0400 Received: from mailhub-dmz-3.mit.edu (MAILHUB-DMZ-3.MIT.EDU [18.9.21.42]) by pch.mit.edu (8.13.6/8.12.8) with ESMTP id q4G0u1gp020156 for ; Tue, 15 May 2012 20:56:01 -0400 Received: from dmz-mailsec-scanner-1.mit.edu (DMZ-MAILSEC-SCANNER-1.MIT.EDU [18.9.25.12]) by mailhub-dmz-3.mit.edu (8.13.8/8.9.2) with ESMTP id q4G0u1F8027599 for ; Tue, 15 May 2012 20:56:01 -0400 X-Auditid: 1209190c-b7fad6d000000920-38-4fb2fb2065ee Authentication-Results: symauth.service.identifier Received: from sumac.math.ucla.edu (sumac.math.ucla.edu [128.97.4.21]) by dmz-mailsec-scanner-1.mit.edu (Symantec Messaging Gateway) with SMTP id C9.38.02336.12BF2BF4; Tue, 15 May 2012 20:56:01 -0400 (EDT) Received: by sumac.math.ucla.edu (Postfix, from userid 1886) id 42CC141C66; Tue, 15 May 2012 17:56:00 -0700 (PDT) X-Mathnet-Spam-Score: 1.3/5.0 X-RCVD-Authsender: from xena.cft.ca.us (pool-71-107-51-237.lsanca.dsl-w.verizon.net [71.107.51.237]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) (Authenticated sender: jimc@math.ucla.edu) by sumac.math.ucla.edu (Postfix) with ESMTPSA id DF22441C5D for ; Tue, 15 May 2012 17:55:58 -0700 (PDT) Date: Tue, 15 May 2012 17:55:56 -0700 (PDT) From: Jim Carter To: krb5-bugs@mit.edu Subject: Reverse DNS happens despite rdns=false Message-ID: User-Agent: Alpine 2.00 (LNX 1167 2008-08-23) MIME-Version: 1.0 Content-Type: TEXT/PLAIN; format=flowed; charset=US-ASCII X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrPIsWRWlGSWpSXmKPExsXSkMgiqqv4e5O/waQWWYuGh8fZHRg9ms4c ZQ5gjOKySUnNySxLLdK3S+DKWDptLnPBK62K7yuOszYwbpPvYuTkkBAwkXjU2cEGYjMKGEns PveKFSIuJnHh3nqgOBeHkMB5RolD/3eygCSEBIolbizbzgJRpCfxatphJpAiCYHvTBLLH6xn B0mwCGhL9E+YAjaVTUBV4sXFh2ANIgKiEi//HgOzhQX0JRa/b2TuYuTg4BWwl5j/NxkkLCqg K9G++DsjiM0rIChxcuYTsHJmAUuJf2t/sU5g5J+FJDULSWoBI9MqRtmU3Crd3MTMnOLUZN3i 5MS8vNQiXUO93MwSvdSU0k2MwBAT4pTk2cH45qDSIUYBDkYlHl6jpk3+QqyJZcWVuYcYJTmY lER5p/8ECvEl5adUZiQWZ8QXleakFh9ilOBgVhLhdXkKlONNSaysSi3Kh0lJc7AoifOqaL3z ExJITyxJzU5NLUgtgskycbAfYpTh4FCS4M34BdQtWJSanlqRlplTgqyGE0RwgazhAVqTC1LI W1yQmFucmQ5RdIpRl+PPw0XXGIVY8vLzUqXEeSNAigRAijJK8+CGgdJF/f///y8xykoJ8zIy MDAI8QBdAwwEhDwo3bxiFAcGgDBvGcgUnsy8ErhNr4COYAI6oiwX7IiSRISUVAOj9fIJa6bc dFrz3u6eytrSz/zp644W3854NPG8zR31195KmosWX7ofFvJrdePpHN1geckfL8vmeRvcDb2e d+u04qFVMdfddDasuMyz89Q/D+GQ9Nkzfs389UNgyoknPrxH9vtM8N9euaHK3qN6T5GH4IRf 57eaKyyZs0IhMK3jdsAKAcn+06KpX5RYijMSDbWYi4oTATMHF8ESAwAA X-Mailman-Approved-At: Tue, 15 May 2012 23:12:19 -0400 X-Beenthere: krb5-bugs-incoming@mailman.mit.edu X-Mailman-Version: 2.1.6 Precedence: list Sender: krb5-bugs-incoming-bounces@PCH.mit.edu Errors-To: krb5-bugs-incoming-bounces@PCH.mit.edu X-RT-Original-Encoding: us-ascii Content-Length: 5370 Distro: OpenSuSE 11.4 Version: krb5-1.8.3-16.19.2.x86_64 Library: /usr/lib64/libkrb5.so.3.3 Subroutine: sn2princ() I have a server whose wild side is on a residential DSL line. Its IP address changes randomly and the "A" record for its wild-side name is updated by dynamic DNS (dyndns.com). The ISP has PTR records for the DHCP addresses, which are not under my control. I want to use Kerberos for outside clients (my work machine and laptop) to authenticate, using the dyndns "A" record as the server name. The current services are XMPP/GSSAPI (Prosody) and HTTPS/SPNEGO (Apache proxy for SOGo). Other use-cases for rdns=false are where the clients use a CNAME for the server, and where there are multiple "A" records with the same name, for load sharing among multiple servers. I've set /etc/krb5.conf [libdefaults] rdns=false on both the server and the client, but even so, both the server and the client are seen to retrieve the PTR record for the IP address, and fail to do Kerberos authentication (GSSAPI). If I hijack the ISP's realm and create a principal for the wild-side canonical name (PTR value), they can authenticate, but obviously this is not a satsifactory solution. The reason RDNS is still happening is that getaddrinfo is being asked (with the AI_CANONNAME flag) to determine the server's canonical name, and the subroutine uses it unconditionally. The included patch makes that behavior conditional on the rdns configuration variable. With the patched library (client and server) the client gets a service ticket for the correct wild-side name, the server knows its correct name and finds its key in the keytab, the server believes in my service ticket, and it lets me on. The Prosody XMPP server had to be hacked to use a configured name rather than inferring it from gethostname() which gives the name on the local LAN. I think Apache's mod_kerb needs the same treatment but I haven't finished the hack yet. The existing conditionalized reverse lookup may actually not be needed, since getaddrinfo has already done it (per AI_CANONNAME if given), but I didn't mess with code that wasn't actually broken. If a string representation of a numeric IP address is passed in, we want to always get the canonical name. The test I used to recognize a numeric address is kind of lameass; it would consider deadbeef.adb.be to be numeric. (As well as fe80::210:60ff:fe15:85f4 as it should.) If someone knows a neat test for a numeric IP, this is where it's needed. James F. Carter Voice 310 825 2897 FAX 310 206 6673 UCLA-Mathnet; 6115 MSA; 405 Hilgard Ave.; Los Angeles, CA, USA 90095-1555 Email: jimc@math.ucla.edu http://www.math.ucla.edu/~jimc (q.v. for PGP key) The patch: If rdns (reverse DNS lookup) is false, use the caller-provided server name and head off getaddrinfo() from looking up the PTR record to get the server's canonical name. Except if given a numerical IP address. Index: src/lib/krb5/os/sn2princ.c =================================================================== --- src/lib/krb5/os/sn2princ.c.orig 2012-05-10 19:47:03.177952712 -0700 +++ src/lib/krb5/os/sn2princ.c 2012-05-14 13:08:19.954180561 -0700 @@ -67,6 +67,7 @@ { char **hrealms, *realm, *remote_host; krb5_error_code retval; + int use_rdns, numeric_ip; register char *cp; char localname[MAXHOSTNAMELEN]; @@ -95,6 +96,12 @@ struct addrinfo *ai, hints; int err; char hnamebuf[NI_MAXHOST]; + /* Always use RDNS if hostname is numeric. Will getaddrinfo + return AI_NUMERICHOST, so this lameass test is not needed? + The man page doesn't say so. (Example: deadbeef.aed.be) */ + use_rdns = maybe_use_reverse_dns(context, DEFAULT_RDNS_LOOKUP) || + (strspn(hostname, "0123456789.:abcdefABCDEF") == + strlen(hostname)); /* Note that the old code would accept numeric addresses, and if the gethostbyaddr step could convert them to @@ -108,7 +115,12 @@ memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; - hints.ai_flags = AI_CANONNAME|AI_ADDRCONFIG; + /* + * In DNS, the canonical name is what the PTR record says. + * If we suppress RDNS, we want to see our CNAME, not the + * canonical name, and can do without an unwanted PTR lookup. + */ + hints.ai_flags = AI_ADDRCONFIG | (use_rdns ? AI_CANONNAME : 0); try_getaddrinfo_again: err = getaddrinfo(hostname, 0, &hints, &ai); if (err) { @@ -122,13 +134,13 @@ } return KRB5_ERR_BAD_HOSTNAME; } - remote_host = strdup(ai->ai_canonname ? ai->ai_canonname : hostname); + remote_host = strdup((use_rdns && ai->ai_canonname) ? ai->ai_canonname : hostname); if (!remote_host) { freeaddrinfo(ai); return ENOMEM; } - if (maybe_use_reverse_dns(context, DEFAULT_RDNS_LOOKUP)) { + if (use_rdns) { /* * Do a reverse resolution to get the full name, just in * case there's some funny business going on. If there