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