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