diff --git a/.gitignore b/.gitignore index 2cf244c..57ab32a 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ pam_ssh_agent_auth-0.9.2.tar.bz2 /openssh-5.8p1-noacss.tar.bz2 /openssh-5.8p2-noacss.tar.bz2 /openssh-5.9p1-noacss.tar.bz2 +/pam_ssh_agent_auth-0.9.3.tar.bz2 diff --git a/openssh.spec b/openssh.spec index 1d97131..95f9f99 100644 --- a/openssh.spec +++ b/openssh.spec @@ -75,9 +75,9 @@ # Do not forget to bump pam_ssh_agent_auth release if you rewind the main package release to 1 %define openssh_ver 5.9p1 -%define openssh_rel 22 -%define pam_ssh_agent_ver 0.9.2 -%define pam_ssh_agent_rel 32 +%define openssh_rel 23 +%define pam_ssh_agent_ver 0.9.3 +%define pam_ssh_agent_rel 1 Summary: An open source implementation of SSH protocol versions 1 and 2 Name: openssh @@ -134,8 +134,12 @@ Patch204: openssh-5.9p1-audit4.patch Patch205: openssh-5.9p1-audit5.patch # --- pam_ssh-agent --- -Patch300: pam_ssh_agent_auth-0.9-build.patch +# make it build reusing the openssh sources +Patch300: pam_ssh_agent_auth-0.9.3-build.patch +# check return value of seteuid() Patch301: pam_ssh_agent_auth-0.9.2-seteuid.patch +# explicitly make pam callbacks visible +Patch302: pam_ssh_agent_auth-0.9.2-visibility.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1641 (WONTFIX) Patch400: openssh-5.9p1-role.patch @@ -410,6 +414,7 @@ The module is most useful for su and sudo service stacks. pushd pam_ssh_agent_auth-%{pam_ssh_agent_ver} %patch300 -p1 -b .psaa-build %patch301 -p1 -b .psaa-seteuid +%patch302 -p1 -b .psaa-visibility # Remove duplicate headers rm -f $(cat %{SOURCE5}) popd @@ -471,7 +476,9 @@ autoreconf popd %build -CFLAGS="$RPM_OPT_FLAGS"; export CFLAGS +# the -fvisibility=hidden is needed for clean build of the pam_ssh_agent_auth +# and it makes the ssh build more clean and even optimized better +CFLAGS="$RPM_OPT_FLAGS -fvisibility=hidden"; export CFLAGS %if %{rescue} CFLAGS="$CFLAGS -Os" %endif @@ -796,6 +803,11 @@ fi %endif %changelog +* Fri Jun 22 2012 Tomas Mraz 5.9p1-23 + 0.9.3-1 +- fix segfault in su when pam_ssh_agent_auth is used and the ssh-agent + is not running, most probably not exploitable +- update pam_ssh_agent_auth to 0.9.3 upstream version + * Fri Apr 06 2012 Petr Lautrbach 5.9p1-22 + 0.9.2-32 - don't create RSA1 key in FIPS mode - don't install sshd-keygen.service (#810419) diff --git a/pam_ssh_agent_auth-0.9-build.patch b/pam_ssh_agent_auth-0.9-build.patch deleted file mode 100644 index ddacff6..0000000 --- a/pam_ssh_agent_auth-0.9-build.patch +++ /dev/null @@ -1,190 +0,0 @@ -diff -up pam_ssh_agent_auth-0.9/iterate_ssh_agent_keys.c.psaa-build pam_ssh_agent_auth-0.9/iterate_ssh_agent_keys.c ---- pam_ssh_agent_auth-0.9/iterate_ssh_agent_keys.c.psaa-build 2009-08-08 11:51:04.000000000 +0200 -+++ pam_ssh_agent_auth-0.9/iterate_ssh_agent_keys.c 2009-10-16 15:20:55.000000000 +0200 -@@ -41,7 +41,16 @@ - #include "buffer.h" - #include "key.h" - #include "authfd.h" -+#include "ssh.h" - #include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include - #include - - #include "userauth_pubkey_from_id.h" -@@ -73,6 +82,96 @@ session_id2_gen() - return cookie; - } - -+/* -+ * Added by Jamie Beverly, ensure socket fd points to a socket owned by the user -+ * A cursory check is done, but to avoid race conditions, it is necessary -+ * to drop effective UID when connecting to the socket. -+ * -+ * If the cause of error is EACCES, because we verified we would not have that -+ * problem initially, we can safely assume that somebody is attempting to find a -+ * race condition; so a more "direct" log message is generated. -+ */ -+ -+int -+ssh_get_authentication_socket_for_uid(uid_t uid) -+{ -+ const char *authsocket; -+ int sock; -+ struct sockaddr_un sunaddr; -+ struct stat sock_st; -+ -+ authsocket = getenv(SSH_AUTHSOCKET_ENV_NAME); -+ if (!authsocket) -+ return -1; -+ -+ /* Advisory only; seteuid ensures no race condition; but will only log if we see EACCES */ -+ if( stat(authsocket,&sock_st) == 0) { -+ if(uid != 0 && sock_st.st_uid != uid) { -+ fatal("uid %lu attempted to open an agent socket owned by uid %lu", (unsigned long) uid, (unsigned long) sock_st.st_uid); -+ return -1; -+ } -+ } -+ -+ /* -+ * Ensures that the EACCES tested for below can _only_ happen if somebody -+ * is attempting to race the stat above to bypass authentication. -+ */ -+ if( (sock_st.st_mode & S_IWUSR) != S_IWUSR || (sock_st.st_mode & S_IRUSR) != S_IRUSR) { -+ error("ssh-agent socket has incorrect permissions for owner"); -+ return -1; -+ } -+ -+ sunaddr.sun_family = AF_UNIX; -+ strlcpy(sunaddr.sun_path, authsocket, sizeof(sunaddr.sun_path)); -+ -+ sock = socket(AF_UNIX, SOCK_STREAM, 0); -+ if (sock < 0) -+ return -1; -+ -+ /* close on exec */ -+ if (fcntl(sock, F_SETFD, 1) == -1) { -+ close(sock); -+ return -1; -+ } -+ -+ errno = 0; -+ seteuid(uid); /* To ensure a race condition is not used to circumvent the stat -+ above, we will temporarily drop UID to the caller */ -+ if (connect(sock, (struct sockaddr *)&sunaddr, sizeof sunaddr) < 0) { -+ close(sock); -+ if(errno == EACCES) -+ fatal("MAJOR SECURITY WARNING: uid %lu made a deliberate and malicious attempt to open an agent socket owned by another user", (unsigned long) uid); -+ return -1; -+ } -+ -+ seteuid(0); /* we now continue the regularly scheduled programming */ -+ -+ return sock; -+} -+ -+AuthenticationConnection * -+ssh_get_authentication_connection_for_uid(uid_t uid) -+{ -+ AuthenticationConnection *auth; -+ int sock; -+ -+ sock = ssh_get_authentication_socket_for_uid(uid); -+ -+ /* -+ * Fail if we couldn't obtain a connection. This happens if we -+ * exited due to a timeout. -+ */ -+ if (sock < 0) -+ return NULL; -+ -+ auth = xmalloc(sizeof(*auth)); -+ auth->fd = sock; -+ buffer_init(&auth->identities); -+ auth->howmany = 0; -+ -+ return auth; -+} -+ - int - find_authorized_keys(uid_t uid) - { -@@ -85,7 +184,7 @@ find_authorized_keys(uid_t uid) - OpenSSL_add_all_digests(); - session_id2 = session_id2_gen(); - -- if ((ac = ssh_get_authentication_connection(uid))) { -+ if ((ac = ssh_get_authentication_connection_for_uid(uid))) { - verbose("Contacted ssh-agent of user %s (%u)", getpwuid(uid)->pw_name, uid); - for (key = ssh_get_first_identity(ac, &comment, 2); key != NULL; key = ssh_get_next_identity(ac, &comment, 2)) - { -@@ -113,3 +212,4 @@ find_authorized_keys(uid_t uid) - EVP_cleanup(); - return retval; - } -+ -diff -up pam_ssh_agent_auth-0.9/Makefile.in.psaa-build pam_ssh_agent_auth-0.9/Makefile.in ---- pam_ssh_agent_auth-0.9/Makefile.in.psaa-build 2009-08-06 07:40:16.000000000 +0200 -+++ pam_ssh_agent_auth-0.9/Makefile.in 2009-10-16 15:20:55.000000000 +0200 -@@ -28,7 +28,7 @@ PATHS= - CC=@CC@ - LD=@LD@ - CFLAGS=@CFLAGS@ --CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@ -+CPPFLAGS=-I.. -I$(srcdir) -I/usr/include/nss3 -I/usr/include/nspr4 @CPPFLAGS@ $(PATHS) @DEFS@ - LIBS=@LIBS@ - AR=@AR@ - AWK=@AWK@ -@@ -37,7 +37,7 @@ INSTALL=@INSTALL@ - PERL=@PERL@ - SED=@SED@ - ENT=@ENT@ --LDFLAGS=-L. -Lopenbsd-compat/ @LDFLAGS@ -+LDFLAGS=-L.. -L../openbsd-compat/ @LDFLAGS@ - LDFLAGS_SHARED = @LDFLAGS_SHARED@ - EXEEXT=@EXEEXT@ - -@@ -48,7 +48,7 @@ PAM_MODULES=pam_ssh_agent_auth.so - - SSHOBJS=xmalloc.o atomicio.o authfd.o bufaux.o bufbn.o buffer.o cleanup.o entropy.o fatal.o key.o log.o misc.o secure_filename.o ssh-dss.o ssh-rsa.o uuencode.o compat.o - --PAM_SSH_AGENT_AUTH_OBJS=pam_user_key_allowed2.o iterate_ssh_agent_keys.o userauth_pubkey_from_id.o pam_user_authorized_keys.o -+PAM_SSH_AGENT_AUTH_OBJS=pam_user_key_allowed2.o iterate_ssh_agent_keys.o userauth_pubkey_from_id.o pam_user_authorized_keys.o secure_filename.o - - - MANPAGES_IN = pam_ssh_agent_auth.pod -@@ -67,13 +67,13 @@ $(PAM_MODULES): Makefile.in config.h - .c.o: - $(CC) $(CFLAGS) $(CPPFLAGS) -c $< - --LIBCOMPAT=openbsd-compat/libopenbsd-compat.a -+LIBCOMPAT=../openbsd-compat/libopenbsd-compat.a - $(LIBCOMPAT): always - (cd openbsd-compat && $(MAKE)) - always: - --pam_ssh_agent_auth.so: $(LIBCOMPAT) $(SSHOBJS) $(PAM_SSH_AGENT_AUTH_OBJS) pam_ssh_agent_auth.o -- $(LD) $(LDFLAGS_SHARED) -o $@ $(SSHOBJS) $(PAM_SSH_AGENT_AUTH_OBJS) $(LDFLAGS) -lopenbsd-compat $(LIBS) -lpam pam_ssh_agent_auth.o -+pam_ssh_agent_auth.so: $(PAM_SSH_AGENT_AUTH_OBJS) pam_ssh_agent_auth.o -+ $(LD) $(LDFLAGS_SHARED) -o $@ $(PAM_SSH_AGENT_AUTH_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -lpam -lnss3 pam_ssh_agent_auth.o - - $(MANPAGES): $(MANPAGES_IN) - pod2man --section=8 --release=v0.8 --name=pam_ssh_agent_auth --official --center "PAM" pam_ssh_agent_auth.pod > pam_ssh_agent_auth.8 -diff -up pam_ssh_agent_auth-0.9/pam_user_authorized_keys.c.psaa-build pam_ssh_agent_auth-0.9/pam_user_authorized_keys.c ---- pam_ssh_agent_auth-0.9/pam_user_authorized_keys.c.psaa-build 2009-07-29 02:46:38.000000000 +0200 -+++ pam_ssh_agent_auth-0.9/pam_user_authorized_keys.c 2009-10-16 15:50:36.000000000 +0200 -@@ -94,7 +94,7 @@ parse_authorized_key_file(const char *us - /* - * temporary copy, so that both tilde expansion and percent expansion both get to apply to the path - */ -- strncat(auth_keys_file_buf, authorized_keys_file_input, 4096); -+ strncat(auth_keys_file_buf, authorized_keys_file_input, sizeof(auth_keys_file_buf)-1); - - if(allow_user_owned_authorized_keys_file) - authorized_keys_file_allowed_owner_uid = getpwnam(user)->pw_uid; diff --git a/pam_ssh_agent_auth-0.9.2-visibility.patch b/pam_ssh_agent_auth-0.9.2-visibility.patch new file mode 100644 index 0000000..f229144 --- /dev/null +++ b/pam_ssh_agent_auth-0.9.2-visibility.patch @@ -0,0 +1,21 @@ +diff -up pam_ssh_agent_auth-0.9.2/pam_ssh_agent_auth.c.visibility pam_ssh_agent_auth-0.9.2/pam_ssh_agent_auth.c +--- pam_ssh_agent_auth-0.9.2/pam_ssh_agent_auth.c.visibility 2009-12-21 20:57:34.000000000 +0100 ++++ pam_ssh_agent_auth-0.9.2/pam_ssh_agent_auth.c 2012-06-21 20:01:31.356259429 +0200 +@@ -68,7 +68,7 @@ char *__progname; + extern char *__progname; + #endif + +-PAM_EXTERN int ++PAM_EXTERN int __attribute__ ((visibility ("default"))) + pam_sm_authenticate(pam_handle_t * pamh, int flags, int argc, const char **argv) + { + char **argv_ptr; +@@ -184,7 +184,7 @@ pam_sm_authenticate(pam_handle_t * pamh, + } + + +-PAM_EXTERN int ++PAM_EXTERN int __attribute__ ((visibility ("default"))) + pam_sm_setcred(pam_handle_t * pamh, int flags, int argc, const char **argv) + { + return PAM_SUCCESS; diff --git a/pam_ssh_agent_auth-0.9.3-build.patch b/pam_ssh_agent_auth-0.9.3-build.patch new file mode 100644 index 0000000..40ab19d --- /dev/null +++ b/pam_ssh_agent_auth-0.9.3-build.patch @@ -0,0 +1,179 @@ +diff -up pam_ssh_agent_auth-0.9.3/iterate_ssh_agent_keys.c.psaa-build pam_ssh_agent_auth-0.9.3/iterate_ssh_agent_keys.c +--- pam_ssh_agent_auth-0.9.3/iterate_ssh_agent_keys.c.psaa-build 2010-01-13 03:17:01.000000000 +0100 ++++ pam_ssh_agent_auth-0.9.3/iterate_ssh_agent_keys.c 2012-06-21 20:14:56.432527764 +0200 +@@ -37,7 +37,16 @@ + #include "buffer.h" + #include "key.h" + #include "authfd.h" ++#include "ssh.h" + #include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + #include + + #include "userauth_pubkey_from_id.h" +@@ -69,6 +78,96 @@ session_id2_gen() + return cookie; + } + ++/* ++ * Added by Jamie Beverly, ensure socket fd points to a socket owned by the user ++ * A cursory check is done, but to avoid race conditions, it is necessary ++ * to drop effective UID when connecting to the socket. ++ * ++ * If the cause of error is EACCES, because we verified we would not have that ++ * problem initially, we can safely assume that somebody is attempting to find a ++ * race condition; so a more "direct" log message is generated. ++ */ ++ ++int ++ssh_get_authentication_socket_for_uid(uid_t uid) ++{ ++ const char *authsocket; ++ int sock; ++ struct sockaddr_un sunaddr; ++ struct stat sock_st; ++ ++ authsocket = getenv(SSH_AUTHSOCKET_ENV_NAME); ++ if (!authsocket) ++ return -1; ++ ++ /* Advisory only; seteuid ensures no race condition; but will only log if we see EACCES */ ++ if( stat(authsocket,&sock_st) == 0) { ++ if(uid != 0 && sock_st.st_uid != uid) { ++ fatal("uid %lu attempted to open an agent socket owned by uid %lu", (unsigned long) uid, (unsigned long) sock_st.st_uid); ++ return -1; ++ } ++ } ++ ++ /* ++ * Ensures that the EACCES tested for below can _only_ happen if somebody ++ * is attempting to race the stat above to bypass authentication. ++ */ ++ if( (sock_st.st_mode & S_IWUSR) != S_IWUSR || (sock_st.st_mode & S_IRUSR) != S_IRUSR) { ++ error("ssh-agent socket has incorrect permissions for owner"); ++ return -1; ++ } ++ ++ sunaddr.sun_family = AF_UNIX; ++ strlcpy(sunaddr.sun_path, authsocket, sizeof(sunaddr.sun_path)); ++ ++ sock = socket(AF_UNIX, SOCK_STREAM, 0); ++ if (sock < 0) ++ return -1; ++ ++ /* close on exec */ ++ if (fcntl(sock, F_SETFD, 1) == -1) { ++ close(sock); ++ return -1; ++ } ++ ++ errno = 0; ++ seteuid(uid); /* To ensure a race condition is not used to circumvent the stat ++ above, we will temporarily drop UID to the caller */ ++ if (connect(sock, (struct sockaddr *)&sunaddr, sizeof sunaddr) < 0) { ++ close(sock); ++ if(errno == EACCES) ++ fatal("MAJOR SECURITY WARNING: uid %lu made a deliberate and malicious attempt to open an agent socket owned by another user", (unsigned long) uid); ++ return -1; ++ } ++ ++ seteuid(0); /* we now continue the regularly scheduled programming */ ++ ++ return sock; ++} ++ ++AuthenticationConnection * ++ssh_get_authentication_connection_for_uid(uid_t uid) ++{ ++ AuthenticationConnection *auth; ++ int sock; ++ ++ sock = ssh_get_authentication_socket_for_uid(uid); ++ ++ /* ++ * Fail if we couldn't obtain a connection. This happens if we ++ * exited due to a timeout. ++ */ ++ if (sock < 0) ++ return NULL; ++ ++ auth = xmalloc(sizeof(*auth)); ++ auth->fd = sock; ++ buffer_init(&auth->identities); ++ auth->howmany = 0; ++ ++ return auth; ++} ++ + int + find_authorized_keys(uid_t uid) + { +@@ -81,7 +180,7 @@ find_authorized_keys(uid_t uid) + OpenSSL_add_all_digests(); + session_id2 = session_id2_gen(); + +- if ((ac = ssh_get_authentication_connection(uid))) { ++ if ((ac = ssh_get_authentication_connection_for_uid(uid))) { + verbose("Contacted ssh-agent of user %s (%u)", getpwuid(uid)->pw_name, uid); + for (key = ssh_get_first_identity(ac, &comment, 2); key != NULL; key = ssh_get_next_identity(ac, &comment, 2)) + { +@@ -109,3 +208,4 @@ find_authorized_keys(uid_t uid) + EVP_cleanup(); + return retval; + } ++ +diff -up pam_ssh_agent_auth-0.9.3/Makefile.in.psaa-build pam_ssh_agent_auth-0.9.3/Makefile.in +--- pam_ssh_agent_auth-0.9.3/Makefile.in.psaa-build 2009-10-27 21:19:41.000000000 +0100 ++++ pam_ssh_agent_auth-0.9.3/Makefile.in 2012-06-21 20:14:56.432527764 +0200 +@@ -28,7 +28,7 @@ PATHS= + CC=@CC@ + LD=@LD@ + CFLAGS=@CFLAGS@ +-CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@ ++CPPFLAGS=-I.. -I$(srcdir) -I/usr/include/nss3 -I/usr/include/nspr4 @CPPFLAGS@ $(PATHS) @DEFS@ + LIBS=@LIBS@ + AR=@AR@ + AWK=@AWK@ +@@ -37,7 +37,7 @@ INSTALL=@INSTALL@ + PERL=@PERL@ + SED=@SED@ + ENT=@ENT@ +-LDFLAGS=-L. -Lopenbsd-compat/ @LDFLAGS@ ++LDFLAGS=-L.. -L../openbsd-compat/ @LDFLAGS@ + LDFLAGS_SHARED = @LDFLAGS_SHARED@ + EXEEXT=@EXEEXT@ + +@@ -48,7 +48,7 @@ PAM_MODULES=pam_ssh_agent_auth.so + + SSHOBJS=xmalloc.o atomicio.o authfd.o bufaux.o bufbn.o buffer.o cleanup.o entropy.o fatal.o key.o log.o misc.o secure_filename.o ssh-dss.o ssh-rsa.o uuencode.o compat.o + +-PAM_SSH_AGENT_AUTH_OBJS=pam_user_key_allowed2.o iterate_ssh_agent_keys.o userauth_pubkey_from_id.o pam_user_authorized_keys.o ++PAM_SSH_AGENT_AUTH_OBJS=pam_user_key_allowed2.o iterate_ssh_agent_keys.o userauth_pubkey_from_id.o pam_user_authorized_keys.o secure_filename.o + + + MANPAGES_IN = pam_ssh_agent_auth.pod +@@ -67,13 +67,13 @@ $(PAM_MODULES): Makefile.in config.h + .c.o: + $(CC) $(CFLAGS) $(CPPFLAGS) -c $< + +-LIBCOMPAT=openbsd-compat/libopenbsd-compat.a ++LIBCOMPAT=../openbsd-compat/libopenbsd-compat.a + $(LIBCOMPAT): always + (cd openbsd-compat && $(MAKE)) + always: + +-pam_ssh_agent_auth.so: $(LIBCOMPAT) $(SSHOBJS) $(PAM_SSH_AGENT_AUTH_OBJS) pam_ssh_agent_auth.o +- $(LD) $(LDFLAGS_SHARED) -o $@ $(SSHOBJS) $(PAM_SSH_AGENT_AUTH_OBJS) $(LDFLAGS) -lopenbsd-compat $(LIBS) -lpam pam_ssh_agent_auth.o ++pam_ssh_agent_auth.so: $(PAM_SSH_AGENT_AUTH_OBJS) pam_ssh_agent_auth.o ++ $(LD) $(LDFLAGS_SHARED) -o $@ $(PAM_SSH_AGENT_AUTH_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -lpam -lnss3 pam_ssh_agent_auth.o + + $(MANPAGES): $(MANPAGES_IN) + pod2man --section=8 --release=v0.8 --name=pam_ssh_agent_auth --official --center "PAM" pam_ssh_agent_auth.pod > pam_ssh_agent_auth.8 +diff -up pam_ssh_agent_auth-0.9.3/pam_user_authorized_keys.c.psaa-build pam_ssh_agent_auth-0.9.3/pam_user_authorized_keys.c diff --git a/sources b/sources index 3245ab1..96ec085 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ 085cfbb262f1b8b875aadea6fba60b1b openssh-5.9p1-noacss.tar.bz2 -b68f1c385d7885fbe2c3626bf77aa3d6 pam_ssh_agent_auth-0.9.2.tar.bz2 +9872ca1983e566ff5a89c240529e223d pam_ssh_agent_auth-0.9.3.tar.bz2