All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Avoid PTR lookups when possible
@ 2013-04-02 13:45 Simo Sorce
  2013-04-02 14:17 ` Jeff Layton
                   ` (2 more replies)
  0 siblings, 3 replies; 21+ messages in thread
From: Simo Sorce @ 2013-04-02 13:45 UTC (permalink / raw)
  To: linux-nfs; +Cc: Steve Dickson, Jeffrey Layton

[-- Attachment #1: Type: text/plain, Size: 1448 bytes --]

The attached patch adds a new command line switch to rpc.gssd to avoid
PTR resolution when possible.

The current code *depends* on PTR resolution for GSSAPI authentication
and this is *bad*.
It imposes an annoying, and unnecessary, constraint on the correctness
of DNS resolution, which prevents mounts from working in networks where
the PTR record cannot be easily controlled (for example networks where
the forward name is reasonable while the PTR is set to some artificial
name based on the IP address or so that is not the canonical name or
where no PTR exist at all).

Depending on PTR resolution for GSSAPI is also very bad practice because
it opens up DNS spoofing attacks where an attacker can try to redirect a
user to the wrong server fooling mutual authentication, and induce a
user to trust improper data or disclose (by copying on the impostor
server) data that should be confidential.

Ideally people will always use the -N switch, however I added an actual
switch to avoid breaking existing configuration where someone may
intentionally or inadvertently be using multiple A names instead of
using CNAMEs but relying on PTR records to find the "canonical name".

It would be probably nice to switch the behavior on by default in
future.

Jeff in CC as he also implemented a similar switch for cifs.upcall
(there it is called -t|--trust-dns, but in rpc.gsssd -t is already
taken ...).

Simo.

-- 
Simo Sorce * Red Hat, Inc * New York

[-- Attachment #2: 0001-Avoid-forced-reverse-resolution-for-server-name.patch --]
[-- Type: text/x-patch, Size: 5483 bytes --]

>From 53dade1e5d22eee06a08ace2684257292514cb49 Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Mon, 1 Apr 2013 21:00:55 -0400
Subject: [PATCH] Avoid forced reverse resolution for server name

A NFS client should be able to work properly even if the PTR record for the
server is not set. there is no excuse to forcefully prevent that from working
when it can.
So, use some heuristics to see if the server is a FQDN or an IP address.
If it is an IP address or a shortname (no '.' in name) then do a PTR lookup,
otherwise avoid it.

This is enabled by the new -N flag which is off by default for now, ideally we
will turn this on by default after a transition period.
---
 utils/gssd/gss_util.h  |  2 ++
 utils/gssd/gssd.c      |  4 +++-
 utils/gssd/gssd.man    |  7 ++++++-
 utils/gssd/gssd_proc.c | 31 +++++++++++++++++++++++++++----
 4 files changed, 38 insertions(+), 6 deletions(-)

diff --git a/utils/gssd/gss_util.h b/utils/gssd/gss_util.h
index aa9f77806075f9ab67a7763a75a010369ba2d1b9..663fb0998bede6144118f890b9311ee8687176e3 100644
--- a/utils/gssd/gss_util.h
+++ b/utils/gssd/gss_util.h
@@ -52,4 +52,6 @@ int gssd_check_mechs(void);
 		gss_krb5_set_allowable_enctypes(min, cred, num, types)
 #endif
 
+extern int avoid_ptr;
+
 #endif /* _GSS_UTIL_H_ */
diff --git a/utils/gssd/gssd.c b/utils/gssd/gssd.c
index 0be251781bacaa562270f773341126bc95ca6b45..2a98e94812a662f0fd868fce8dc3419f65648a4d 100644
--- a/utils/gssd/gssd.c
+++ b/utils/gssd/gssd.c
@@ -85,7 +85,7 @@ sig_hup(int signal)
 static void
 usage(char *progname)
 {
-	fprintf(stderr, "usage: %s [-f] [-l] [-M] [-n] [-v] [-r] [-p pipefsdir] [-k keytab] [-d ccachedir] [-t timeout] [-R preferred realm]\n",
+	fprintf(stderr, "usage: %s [-f] [-l] [-M] [-n] [-v] [-r] [-p pipefsdir] [-k keytab] [-d ccachedir] [-t timeout] [-R preferred realm] [-N]\n",
 		progname);
 	exit(1);
 }
@@ -150,6 +150,8 @@ main(int argc, char *argv[])
 				errx(1, "Encryption type limits not supported by Kerberos libraries.");
 #endif
 				break;
+			case 'N':
+				avoid_ptr = 1;
 			default:
 				usage(argv[0]);
 				break;
diff --git a/utils/gssd/gssd.man b/utils/gssd/gssd.man
index 79d9bf91ac6b976c57d167e60d07f828a3ff5b1f..09253b43ba6502202c17bbc84bd6bcf9dec85e9b 100644
--- a/utils/gssd/gssd.man
+++ b/utils/gssd/gssd.man
@@ -8,7 +8,7 @@
 rpc.gssd \- RPCSEC_GSS daemon
 .SH SYNOPSIS
 .B rpc.gssd
-.RB [ \-fMnlvr ]
+.RB [ \-fMnlvrN ]
 .RB [ \-k
 .IR keytab ]
 .RB [ \-p
@@ -266,6 +266,11 @@ new kernel contexts to be negotiated after
 seconds, which allows changing Kerberos tickets and identities frequently.
 The default is no explicit timeout, which means the kernel context will live
 the lifetime of the Kerberos service ticket used in its creation.
+.TP
+.B -N
+Tries to avoid PTR lookups for resolving the server name, if the name used at 
+mount looks like a Fully Qualified Domain Name. This is import to avoid GSSAPI 
+issues when PTR records are set and to help avoid some kind of MITM attack.
 .SH SEE ALSO
 .BR rpc.svcgssd (8),
 .BR kerberos (1),
diff --git a/utils/gssd/gssd_proc.c b/utils/gssd/gssd_proc.c
index ea01e92e4565670b97dea1a936d2f0dbdc7c4610..0a584d2084d626ee98a8ad6ff56da95464b882fe 100644
--- a/utils/gssd/gssd_proc.c
+++ b/utils/gssd/gssd_proc.c
@@ -67,6 +67,7 @@
 #include <errno.h>
 #include <gssapi/gssapi.h>
 #include <netdb.h>
+#include <ctype.h>
 
 #include "gssd.h"
 #include "err_util.h"
@@ -107,6 +108,8 @@ struct pollfd * pollarray;
 
 unsigned long pollsize;  /* the size of pollaray (in pollfd's) */
 
+int avoid_ptr = 0;
+
 /*
  * convert a presentation address string to a sockaddr_storage struct. Returns
  * true on success or false on failure.
@@ -165,12 +168,32 @@ addrstr_to_sockaddr(struct sockaddr *sa, const char *node, const char *port)
  * convert a sockaddr to a hostname
  */
 static char *
-sockaddr_to_hostname(const struct sockaddr *sa, const char *addr)
+get_servername(const char *name, const struct sockaddr *sa, const char *addr)
 {
 	socklen_t		addrlen;
 	int			err;
 	char			*hostname;
 	char			hbuf[NI_MAXHOST];
+	const char		*p;
+	int			do_ptr_lookup = 0;
+
+	if (avoid_ptr) {
+		/* try to determine if this is FQDN, or an IP address with
+		 * basic heuristics, if they fail try a PTR lookup */
+		p = strrchr(name, '.');
+		if (!p || strchr(name, ':'))
+			do_ptr_lookup = 1; /* non-FQDN, or IPv6 */
+		else {
+			for (++p; *p; p++)
+				if (!isdigit(*p))
+					break;
+			if (!*p)
+				do_ptr_lookup = 1; /* IPv4 */
+		}
+		if (!do_ptr_lookup) {
+			return strdup(name);
+		}
+	}
 
 	switch (sa->sa_family) {
 	case AF_INET:
@@ -208,7 +231,7 @@ read_service_info(char *info_file_name, char **servicename, char **servername,
 		  struct sockaddr *addr) {
 #define INFOBUFLEN 256
 	char		buf[INFOBUFLEN + 1];
-	static char	dummy[128];
+	static char	server[128];
 	int		nbytes;
 	static char	service[128];
 	static char	address[128];
@@ -236,7 +259,7 @@ read_service_info(char *info_file_name, char **servicename, char **servername,
 		   "service: %127s %15s version %15s\n"
 		   "address: %127s\n"
 		   "protocol: %15s\n",
-		   dummy,
+		   server,
 		   service, program, version,
 		   address,
 		   protoname);
@@ -258,7 +281,7 @@ read_service_info(char *info_file_name, char **servicename, char **servername,
 	if (!addrstr_to_sockaddr(addr, address, port))
 		goto fail;
 
-	*servername = sockaddr_to_hostname(addr, address);
+	*servername = get_servername(server, addr, address);
 	if (*servername == NULL)
 		goto fail;
 
-- 
1.8.1.4


^ permalink raw reply related	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2013-04-03 18:20 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-04-02 13:45 [PATCH] Avoid PTR lookups when possible Simo Sorce
2013-04-02 14:17 ` Jeff Layton
2013-04-02 15:00 ` Jim Rees
2013-04-02 16:26   ` Simo Sorce
2013-04-02 16:46     ` Jim Rees
2013-04-02 17:03       ` Simo Sorce
2013-04-02 18:39         ` Jim Rees
2013-04-02 18:48           ` Simo Sorce
2013-04-02 18:53             ` Jim Rees
2013-04-02 19:02               ` Simo Sorce
2013-04-03 13:44             ` J. Bruce Fields
2013-04-03 14:40               ` Jim Rees
2013-04-03 16:03                 ` Simo Sorce
2013-04-03 17:12                   ` J. Bruce Fields
2013-04-03 18:12                     ` Simo Sorce
2013-04-03 18:20                       ` J. Bruce Fields
2013-04-02 15:18 ` Steve Dickson
2013-04-02 15:51   ` Chuck Lever
2013-04-02 16:29     ` Simo Sorce
2013-04-02 20:21       ` Chuck Lever
2013-04-02 20:33         ` Simo Sorce

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.