[PATCH] implementation of getpeereid() for Solaris

Jan Pechanec Jan.Pechanec at Sun.COM
Tue Sep 26 01:38:04 EST 2006


	hi, Solaris doesn't have getpeereid() or SO_PEERCRED. However, 
getpeerucred() is perfectly usable for that; and it's in Solaris 10 and 
OpenSolaris. So, ssh-agent(1) security there so far depends only on 
permissions of the socket directory and with this patch it checks peer's 
credentials, too. I patched following files using a snapshot from 20060921:

openssh/config.h.in
openssh/configure.ac
openssh/includes.h
openssh/openbsd-compat/bsd-getpeereid.c
openssh/regress/agent-getpeereid.sh

	which implements getpeereid() function in OpenSSH with 
getpeerucred() in case that ucred.h and getpeerucred() are present. I then 
generated new configure script via autoconf, configured and built on Solaris 
and FreeBSD. It seems fine.

	I changed regress/agent-getpeereid.sh to accept existence of 
HAVE_GETPEERUCRED and added missing check for HAVE_SO_PEERCRED.

	I also suggest this change:

        < /dev/null ${SUDO} -S -u ${UNPRIV} ssh-add -l > /dev/null 2>&1
        r=$?
-       if [ $r -lt 2 ]; then
+       if [ $r -le 2 ]; then
                fail "ssh-add did not fail for ${UNPRIV}: $r < 2"
        fi


	-> ie. to change less-then to less-or-equal. Reason behind that is 
if a user running regression tests uses 0700 umask then agent-getpeereid.sh 
test can PASS even if getpeereid() functionality wasn't checked at all 
because the path to socket is unreachable which means 2 is returned. Or it 
could be changed to greater-then 128.

	proposed change is already present in OpenSolaris.

	regards, Jan.

-- 
Jan Pechanec
-------------- next part --------------
diff -ur openssh/config.h.in openssh-SNAP-20060921-patched//config.h.in
--- openssh/config.h.in	Wed Sep 20 16:30:40 2006
+++ openssh-SNAP-20060921-patched//config.h.in	Mon Sep 25 11:49:06 2006
@@ -354,6 +354,9 @@
 /* Define to 1 if you have the `getpeereid' function. */
 #undef HAVE_GETPEEREID
 
+/* Define to 1 if you have the `getpeerucred' function. */
+#define HAVE_GETPEERUCRED
+
 /* Define to 1 if you have the `getpwanam' function. */
 #undef HAVE_GETPWANAM
 
@@ -375,6 +378,9 @@
 /* Define to 1 if you have the `getttyent' function. */
 #undef HAVE_GETTTYENT
 
+/* Define to 1 if you have the <ucred.h> header file. */
+#define HAVE_UCRED_H
+
 /* Define to 1 if you have the `getutent' function. */
 #undef HAVE_GETUTENT
 
diff -ur openssh/configure.ac openssh-SNAP-20060921-patched//configure.ac
--- openssh/configure.ac	Mon Sep 18 15:17:41 2006
+++ openssh-SNAP-20060921-patched//configure.ac	Mon Sep 25 11:58:41 2006
@@ -1242,6 +1242,7 @@
 	getnameinfo \
 	getopt \
 	getpeereid \
+	getpeerucred \
 	_getpty \
 	getrlimit \
 	getttyent \
@@ -1490,7 +1491,7 @@
 
 # Check for missing getpeereid (or equiv) support
 NO_PEERCHECK=""
-if test "x$ac_cv_func_getpeereid" != "xyes" ; then
+if test "x$ac_cv_func_getpeereid" != "xyes" -a "x$ac_cv_func_getpeerucred" != "xyes"; then
 	AC_MSG_CHECKING([whether system supports SO_PEERCRED getsockopt])
 	AC_TRY_COMPILE(
 		[#include <sys/types.h>
@@ -4011,12 +4012,12 @@
 fi
 
 if test ! -z "$NO_PEERCHECK" ; then
-	echo "WARNING: the operating system that you are using does not "
-	echo "appear to support either the getpeereid() API nor the "
-	echo "SO_PEERCRED getsockopt() option. These facilities are used to "
-	echo "enforce security checks to prevent unauthorised connections to "
-	echo "ssh-agent. Their absence increases the risk that a malicious "
-	echo "user can connect to your agent. "
+	echo "WARNING: the operating system that you are using does not"
+	echo "appear to support either the getpeereid() or getpeerucred() API"
+	echo "nor the SO_PEERCRED getsockopt() option. These facilities are"
+	echo "used to enforce security checks to prevent unauthorised"
+	echo "connections to ssh-agent. Their absence increases the risk that"
+	echo "a malicious user can connect to your agent."
 	echo ""
 fi
 
diff -ur openssh/includes.h openssh-SNAP-20060921-patched//includes.h
--- openssh/includes.h	Fri Sep  1 12:29:11 2006
+++ openssh-SNAP-20060921-patched//includes.h	Mon Sep 25 11:50:02 2006
@@ -63,6 +63,10 @@
 # include <login.h>
 #endif
 
+#ifdef HAVE_UCRED_H
+#  include <ucred.h>
+#endif
+
 #ifdef HAVE_UTMP_H
 #  include <utmp.h>
 #endif
diff -ur openssh/openbsd-compat/bsd-getpeereid.c openssh-SNAP-20060921-patched//openbsd-compat/bsd-getpeereid.c
--- openssh/openbsd-compat/bsd-getpeereid.c	Mon Aug  7 03:26:38 2006
+++ openssh-SNAP-20060921-patched//openbsd-compat/bsd-getpeereid.c	Mon Sep 25 11:54:31 2006
@@ -37,6 +37,23 @@
 
 	return (0);
 }
+#elif defined(HAVE_GETPEERUCRED)
+int
+getpeereid(int s, uid_t *euid, gid_t *gid)
+{
+	ucred_t *ucred = NULL;
+
+	if (getpeerucred(s, &ucred) == -1)
+		return (-1);
+	if ((*euid = ucred_geteuid(ucred)) == -1)
+		return (-1);
+	if ((*gid = ucred_getrgid(ucred)) == -1)
+		return (-1);
+
+	ucred_free(ucred);
+
+	return (0);
+}
 #else
 int
 getpeereid(int s, uid_t *euid, gid_t *gid)
diff -ur openssh/regress/agent-getpeereid.sh openssh-SNAP-20060921-patched//regress/agent-getpeereid.sh
--- openssh/regress/agent-getpeereid.sh	Mon Jul 24 07:31:42 2006
+++ openssh-SNAP-20060921-patched//regress/agent-getpeereid.sh	Mon Sep 25 12:33:47 2006
@@ -7,7 +7,9 @@
 ASOCK=${OBJ}/agent
 SSH_AUTH_SOCK=/nonexistant
 
-if grep "#undef.*HAVE_GETPEEREID" ${BUILDDIR}/config.h >/dev/null 2>&1
+if grep "#undef.*HAVE_GETPEEREID" ${BUILDDIR}/config.h >/dev/null 2>&1 && \
+	grep "#undef.*HAVE_GETPEERUCRED" ${BUILDDIR}/config.h >/dev/null && \
+	grep "#undef.*HAVE_SO_PEERCRED" ${BUILDDIR}/config.h >/dev/null
 then
 	echo "skipped (not supported on this platform)"
 	exit 0
@@ -34,7 +36,7 @@
 
 	< /dev/null ${SUDO} -S -u ${UNPRIV} ssh-add -l > /dev/null 2>&1
 	r=$?
-	if [ $r -lt 2 ]; then
+	if [ $r -le 2 ]; then
 		fail "ssh-add did not fail for ${UNPRIV}: $r < 2"
 	fi
 
@@ -42,4 +44,4 @@
 	${SSHAGENT} -k > /dev/null
 fi
 
-rm -f ${OBJ}/agent
+rm -f $ASOCK


More information about the openssh-unix-dev mailing list