ac4818
From: Paul Moore <paul.moore@hp.com>
ac4818
Subject: OpenSSH: fix option handling on incoming connections
ac4818
ac4818
OpenSSH rejects incoming connections if any IP options are present when the
ac4818
comments state that they are only concerned with source routing options.  This
ac4818
connection rejection causes problems with CIPSO which uses IP options to tag
ac4818
packets with security attributes.
ac4818
ac4818
This patch modifies the check_ip_options() function to only fail if loose or
ac4818
strict source routing options are present, all other options are allowed.
ac4818
ac4818
Signed-off-by: Paul Moore <paul.moore@hp.com>
ac4818
ac4818
---
ac4818
 canohost.c |   23 +++++++++++++++++------
ac4818
 1 file changed, 17 insertions(+), 6 deletions(-)
ac4818
ac4818
Index: openssh-4.3p2/canohost.c
ac4818
===================================================================
ac4818
--- openssh-4.3p2.orig/canohost.c
ac4818
+++ openssh-4.3p2/canohost.c
ac4818
@@ -146,6 +146,7 @@ check_ip_options(int sock, char *ipaddr)
ac4818
 	u_int i;
ac4818
 	int ipproto;
ac4818
 	struct protoent *ip;
ac4818
+	u_int opt_iter;
ac4818
 
ac4818
 	if ((ip = getprotobyname("ip")) != NULL)
ac4818
 		ipproto = ip->p_proto;
ac4818
@@ -154,13 +155,23 @@ check_ip_options(int sock, char *ipaddr)
ac4818
 	option_size = sizeof(options);
ac4818
 	if (getsockopt(sock, ipproto, IP_OPTIONS, options,
ac4818
 	    &option_size) >= 0 && option_size != 0) {
ac4818
-		text[0] = '\0';
ac4818
-		for (i = 0; i < option_size; i++)
ac4818
-			snprintf(text + i*3, sizeof(text) - i*3,
ac4818
-			    " %2.2x", options[i]);
ac4818
-		fatal("Connection from %.100s with IP options:%.800s",
ac4818
-		    ipaddr, text);
ac4818
+		opt_iter = 0;
ac4818
+		do {
ac4818
+			/* Fail, fatally, if we detect either loose or strict
ac4818
+			 * source routing options. */
ac4818
+			if (options[opt_iter] == 131 ||
ac4818
+			    options[opt_iter] == 137)
ac4818
+				goto fail;
ac4818
+			opt_iter += options[opt_iter + 1] + 2;
ac4818
+		} while (opt_iter < option_size);
ac4818
 	}
ac4818
+	return;
ac4818
+
ac4818
+fail:
ac4818
+	text[0] = '\0';
ac4818
+	for (i = 0; i < option_size; i++)
ac4818
+		snprintf(text + i*3, sizeof(text) - i*3, " %2.2x", options[i]);
ac4818
+	fatal("Connection from %.100s with IP options:%.800s", ipaddr, text);
ac4818
 #endif /* IP_OPTIONS */
ac4818
 }
ac4818