diff --git a/.cvsignore b/.cvsignore index 28fd036..c7df7d7 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1 +1,2 @@ openssh-5.3p1-noacss.tar.bz2 +pam_ssh_agent_auth-0.9.tar.bz2 diff --git a/openssh.spec b/openssh.spec index 59315bc..e87ebb3 100644 --- a/openssh.spec +++ b/openssh.spec @@ -32,6 +32,9 @@ # Whether or not /sbin/nologin exists. %define nologin 1 +# Whether to build pam_ssh_agent_auth +%define pam_ssh_agent 1 + # Reserve options to override askpass settings with: # rpm -ba|--rebuild --define 'skip_xxx 1' %{?skip_gnome_askpass:%define no_gnome_askpass 1} @@ -58,12 +61,15 @@ %if %{rescue} %define kerberos5 0 %define libedit 0 +%define pam_ssh_agent 0 %endif +%define pam_ssh_agent_ver 0.9 + Summary: An open source implementation of SSH protocol versions 1 and 2 Name: openssh Version: 5.3p1 -Release: 3%{?dist}%{?rescue_rel} +Release: 4%{?dist}%{?rescue_rel} URL: http://www.openssh.com/portable.html #Source0: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz #Source1: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz.asc @@ -74,9 +80,12 @@ Source0: openssh-%{version}-noacss.tar.bz2 Source1: openssh-nukeacss.sh Source2: sshd.pam Source3: sshd.init +Source4: http://prdownloads.sourceforge.net/pamsshagentauth/pam_ssh_agent_auth/pam_ssh_agent_auth-%{pam_ssh_agent_ver}.tar.bz2 +Source5: pam_ssh_agent-rmheaders Patch0: openssh-5.2p1-redhat.patch Patch2: openssh-5.3p1-skip-initial.patch Patch4: openssh-5.2p1-vendor.patch +Patch10: pam_ssh_agent_auth-0.9-build.patch Patch12: openssh-5.2p1-selinux.patch Patch13: openssh-5.3p1-mls.patch Patch16: openssh-5.3p1-audit.patch @@ -168,6 +177,14 @@ Requires: openssh = %{version}-%{release} Obsoletes: openssh-askpass-gnome Provides: openssh-askpass-gnome +%package -n pam_ssh_agent_auth +Summary: PAM module for authentication with ssh-agent +Group: System Environment/Base +Version: %{pam_ssh_agent_ver} +# There is special exception added to the GPLv3+ license to +# permit linking with OpenSSL licensed code +License: GPLv3+ and OpenSSL and BSD + %description SSH (Secure SHell) is a program for logging into and executing commands on a remote machine. SSH is intended to replace rlogin and @@ -198,12 +215,28 @@ OpenSSH is a free version of SSH (Secure SHell), a program for logging into and executing commands on a remote machine. This package contains an X11 passphrase dialog for OpenSSH. +%description -n pam_ssh_agent_auth +This package contains a PAM module which can be used to authenticate +users using ssh keys stored in a ssh-agent. Through the use of the +forwarding of ssh-agent connection it also allows to authenticate with +remote ssh-agent instance. + +The module is most useful for su and sudo service stacks. + %prep -%setup -q +%setup -q -a 4 %patch0 -p1 -b .redhat %patch2 -p1 -b .skip-initial %patch4 -p1 -b .vendor +%if %{pam_ssh_agent} +pushd pam_ssh_agent_auth-%{pam_ssh_agent_ver} +%patch10 -p1 -b .psaa-build +# Remove duplicate headers +rm -f $(cat %{SOURCE5}) +popd +%endif + %if %{WITH_SELINUX} #SELinux %patch12 -p1 -b .selinux @@ -238,11 +271,12 @@ CFLAGS="$CFLAGS -Os" %endif %if %{pie} %ifarch s390 s390x sparc sparcv9 sparc64 -CFLAGS="$CFLAGS -fPIE" +CFLAGS="$CFLAGS -fPIC" %else -CFLAGS="$CFLAGS -fpie" +CFLAGS="$CFLAGS -fpic" %endif export CFLAGS +SAVE_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -pie"; export LDFLAGS %endif %if %{kerberos5} @@ -322,6 +356,14 @@ fi popd %endif +%if %{pam_ssh_agent} +pushd pam_ssh_agent_auth-%{pam_ssh_agent_ver} +LDFLAGS="$SAVE_LDFLAGS" +%configure --with-selinux --libexecdir=/%{_lib}/security +make +popd +%endif + # Add generation of HMAC checksums of the final stripped binaries %define __spec_install_post \ %{?__debug_package:%{__debug_install_post}} \ @@ -371,6 +413,12 @@ rm -f README.nss.nss-keys %if ! %{nss} rm -f README.nss %endif + +%if %{pam_ssh_agent} +pushd pam_ssh_agent_auth-%{pam_ssh_agent_ver} +make install DESTDIR=$RPM_BUILD_ROOT +popd +%endif %clean rm -rf $RPM_BUILD_ROOT @@ -461,7 +509,20 @@ fi %attr(0755,root,root) %{_libexecdir}/openssh/ssh-askpass %endif +%if %{pam_ssh_agent} +%files -n pam_ssh_agent_auth +%defattr(-,root,root) +%doc pam_ssh_agent_auth-%{pam_ssh_agent_ver}/GPL_LICENSE +%doc pam_ssh_agent_auth-%{pam_ssh_agent_ver}/OPENSSH_LICENSE +%doc pam_ssh_agent_auth-%{pam_ssh_agent_ver}/LICENSE.OpenSSL +%attr(0755,root,root) /%{_lib}/security/pam_ssh_agent_auth.so +%attr(0644,root,root) %{_mandir}/man8/pam_ssh_agent_auth.8* +%endif + %changelog +* Mon Oct 19 2009 Tomas Mraz - 5.3p1-4 +- Add pam_ssh_agent_auth module to a subpackage. + * Fri Oct 16 2009 Jan F. Chadima - 5.3p1-3 - Reenable audit. diff --git a/pam_ssh_agent-rmheaders b/pam_ssh_agent-rmheaders new file mode 100644 index 0000000..5f036cc --- /dev/null +++ b/pam_ssh_agent-rmheaders @@ -0,0 +1,20 @@ +atomicio.h +authfd.h +buffer.h +cipher.h +compat.h +defines.h +entropy.h +includes.h +kex.h +key.h +log.h +match.h +misc.h +pathnames.h +platform.h +rsa.h +ssh.h +ssh2.h +uuencode.h +xmalloc.h diff --git a/pam_ssh_agent_auth-0.9-build.patch b/pam_ssh_agent_auth-0.9-build.patch new file mode 100644 index 0000000..ddacff6 --- /dev/null +++ b/pam_ssh_agent_auth-0.9-build.patch @@ -0,0 +1,190 @@ +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/sources b/sources index 7d28e2e..add7e47 100644 --- a/sources +++ b/sources @@ -1 +1,2 @@ 89f85c1da83c24ca0b10c05344f7c93c openssh-5.3p1-noacss.tar.bz2 +1868cb825393678489b1d48c97819f76 pam_ssh_agent_auth-0.9.tar.bz2