[38526] trunk/dports/net/openssh
William Siegrist
wsiegrist at apple.com
Thu Jul 24 10:03:53 PDT 2008
I've backed out the new patches to openssh since most of the fixes do
not work. I'll try to get some updated patches next week to hopefully
actually fix keychain, kerberos, and PAM.
Sorry for the churn.
-Bill
On Jul 23, 2008, at 9:33 PM, wsiegrist at apple.com wrote:
> Revision38526Authorwsiegrist at apple.comDate2008-07-23 21:33:03 -0700
> (Wed, 23 Jul 2008)Log Message
> Adding patches from Apple for various fixes. Primarily this commit
> fixes keychain integration.
> Modified Paths
> • trunk/dports/net/openssh/Portfile
> Added Paths
> • trunk/dports/net/openssh/files/
> AJ-5229538+5383306+5446006+5567447+5806868_keychain.patch
> • trunk/dports/net/openssh/files/AJ-5491854-
> fix_unsafe_usage_of_getpwuid.patch
> • trunk/dports/net/openssh/files/DVG-3977221_manpage_tweaks.patch
> • trunk/dports/net/openssh/files/DVG-4122722+5277818_new_EA.patch
> • trunk/dports/net/openssh/files/
> DVG-4135812_add_SACLSupport_to_sshd_conf_manpage.patch
> • trunk/dports/net/openssh/files/
> DVG-4157448+4920695_corrected_UsePAM_comment.patch
> • trunk/dports/net/openssh/files/
> DVG-4212542_auth_error_logging_fix.patch
> • trunk/dports/net/openssh/files/DVG-4648874_preserve_EA_mtime.patch
> • trunk/dports/net/openssh/files/DVG-4694589_16_group_limit_fix.patch
> • trunk/dports/net/openssh/files/DVG-4748610+4897588_ssh-
> agent_via_launchd.patch
> • trunk/dports/net/openssh/files/DVG-4853931_enable_GSSAPI.patch
> • trunk/dports/net/openssh/files/DVG-4853931_enable_GSSAPI_for_pre-
> Leopard---BuildPhase.patch
> • trunk/dports/net/openssh/files/
> DVG-4920695_remove_nullok_comment_for_pre-Leopard---BuildPhase.patch
> • trunk/dports/net/openssh/files/
> DVG-5142987_launchd_DISPLAY_for_X11.patch
> • trunk/dports/net/openssh/files/DVG-5258734_pty_permission_fix.patch
> • trunk/dports/net/openssh/files/DVG-5462402_enable_SSH1_for_pre-
> Leopard---BuildPhase.patch
> • trunk/dports/net/openssh/files/
> DVG-5755519_use_GSS_C_NO_NAME_with_gss_acquire_cred.patch
> • trunk/dports/net/openssh/files/lastlog.patch
> • trunk/dports/net/openssh/files/openssh-5.0p1-gsskex-20080404.patch
> • trunk/dports/net/openssh/files/pam.patch
> • trunk/dports/net/openssh/files/sacl.patch
> Diff
> Modified: trunk/dports/net/openssh/Portfile (38525 => 38526)
> --- trunk/dports/net/openssh/Portfile 2008-07-24 03:33:34 UTC (rev
> 38525)
> +++ trunk/dports/net/openssh/Portfile 2008-07-24 04:33:03 UTC (rev
> 38526)
> @@ -4,6 +4,7 @@
>
> name openssh
> version 5.0p1
> +revision 1
> categories net
> maintainers wms
> description OpenSSH secure login server
> @@ -20,9 +21,9 @@
> homepage http://www.openssh.com/
> platforms darwin
> checksums ${distfiles} \
> - md5 1f1dfaa775f33dd3328169de9bdc292a \
> - sha1 121cea3a730c0b0353334b6f46f438de30ab4928 \
> - rmd160 b813234014e339fe2d9d10a5adad9f8e065918fc
> + md5 1f1dfaa775f33dd3328169de9bdc292a \
> + sha1 121cea3a730c0b0353334b6f46f438de30ab4928 \
> + rmd160 b813234014e339fe2d9d10a5adad9f8e065918fc
>
> master_sites openbsd:OpenSSH/portable \
> http://mirror.mcs.anl.gov/openssh/portable/ \
> @@ -34,6 +35,24 @@
> ftp://openbsd.secsup.org/pub/openbsd/OpenSSH/portable/
> depends_lib port:openssl port:zlib
>
> +patchfiles pam.patch \
> + sacl.patch \
> + DVG-4122722+5277818_new_EA.patch \
> + DVG-3977221_manpage_tweaks.patch \
> + DVG-4212542_auth_error_logging_fix.patch \
> + DVG-4157448+4920695_corrected_UsePAM_comment.patch \
> + lastlog.patch \
> + openssh-5.0p1-gsskex-20080404.patch \
> + DVG-4853931_enable_GSSAPI.patch \
> + DVG-4648874_preserve_EA_mtime.patch \
> + DVG-4748610+4897588_ssh-agent_via_launchd.patch \
> + DVG-4694589_16_group_limit_fix.patch \
> + DVG-5142987_launchd_DISPLAY_for_X11.patch \
> + DVG-5258734_pty_permission_fix.patch \
> + AJ-5491854-fix_unsafe_usage_of_getpwuid.patch \
> + DVG-4135812_add_SACLSupport_to_sshd_conf_manpage.patch \
> + DVG-5755519_use_GSS_C_NO_NAME_with_gss_acquire_cred.patch
> +
> # Specified -fno-builtin because GCC 3.3 has log() as a builtin
> # (from math.h) while OpenSSH has its own log() function
> # -- from fink.
> @@ -43,8 +62,9 @@
> --with-pid-dir=${prefix}/var/run --with-tcp-wrappers \
> --with-pam --disable-suid-ssh --with-random=/dev/urandom \
> --mandir=${prefix}/share/man --with-zlib=${prefix} \
> - --with-kerberos5=/usr
> + --with-kerberos5
>
> +
> destroot.target install-nokeys
>
> post-destroot {
> @@ -81,13 +101,18 @@
> }
> }
>
> +set keychain_patch
> AJ-5229538+5383306+5446006+5567447+5806868_keychain.patch
> +
> platform darwin 9 {
> - patch_sites-append http://www.opensource.apple.com/darwinsource/10.5/OpenSSH-87/patches/
> - patchfiles-append DVG-5142987_launchd_DISPLAY_for_X11.patch
> - checksums-append DVG-5142987_launchd_DISPLAY_for_X11.patch \
> - md5 e188ebbba95c4cde61e0e1b2edc9f992 \
> - sha1
> 62735c5bfbbe1fa41433993435ded7767cc5f1f9 \
> - rmd160
> eb5262f554583f4925f6f91f6a6d0034c70098ad
> + pre-patch {
> + reinplace "s|/usr/bin/|${prefix}/bin/|g" "${filespath}/$
> {keychain_patch}"
> + }
> + patchfiles-append ${keychain_patch}
> + configure.args-append --with-keychain=apple
> + configure.cflags-append -fPIE -Wl,-pie -D_FORTIFY_SOURCE=2
> + configure.ldflags-append -L. -Lopenbsd-compat -Wl,-pie
> + configure.cppflags-append -D__APPLE_SACL__ -D_UTMPX_COMPAT -
> D__APPLE_UTMPX__ -DUSE_CCAPI \
> + -D__APPLE_LAUNCHD__ -
> D__APPLE_PRIVPTY__ -D__BROKEN_GLOB__ -Dcannot_audit
> }
>
> startupitem.create yes
> Added: trunk/dports/net/openssh/files/
> AJ-5229538+5383306+5446006+5567447+5806868_keychain.patch (0 => 38526)
> --- trunk/dports/net/openssh/files/
> AJ
> -5229538
> +
> 5383306
> +5446006+5567447+5806868_keychain.patch (rev
> 0)
> +++ trunk/dports/net/openssh/files/
> AJ-5229538+5383306+5446006+5567447+5806868_keychain.patch 2008-07-24
> 04:33:03 UTC (rev 38526)
> @@ -0,0 +1,1457 @@
> +diff -uNr ../openssh-5.0p1.orig/Makefile.in ./Makefile.in
> +--- ../openssh-5.0p1.orig/Makefile.in 2008-03-12 18:41:31.000000000
> -0700
> ++++ ./Makefile.in 2008-04-15 18:32:47.000000000 -0700
> +@@ -56,6 +56,7 @@
> + XAUTH_PATH=@XAUTH_PATH@
> + LDFLAGS=-L. -Lopenbsd-compat/ @LDFLAGS@
> + EXEEXT=@EXEEXT@
> ++KEYCHAIN_LDFLAGS=@KEYCHAIN_LDFLAGS@
> +
> + INSTALL_SSH_PRNG_CMDS=@INSTALL_SSH_PRNG_CMDS@
> + INSTALL_SSH_RAND_HELPER=@INSTALL_SSH_RAND_HELPER@
> +@@ -88,6 +89,8 @@
> + loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \
> + audit.o audit-bsm.o platform.o sftp-server.o sftp-common.o
> +
> ++KEYCHAINOBJS=keychain.o
> ++
> + MANPAGES = scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.
> 1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.
> 1.out ssh-rand-helper.8.out ssh-keysign.8.out sshd_config.5.out
> ssh_config.5.out
> + MANPAGES_IN = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.
> 1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-rand-helper.8 ssh-keysign.8
> sshd_config.5 ssh_config.5
> + MANTYPE = @MANTYPE@
> +@@ -119,6 +122,7 @@
> + $(LIBSSH_OBJS): Makefile.in config.h
> + $(SSHOBJS): Makefile.in config.h
> + $(SSHDOBJS): Makefile.in config.h
> ++$(KEYCHAINOBJS): Makefile.in config.h
> +
> + .c.o:
> + $(CC) $(CFLAGS) $(CPPFLAGS) -c $<
> +@@ -132,8 +136,8 @@
> + $(AR) rv $@ $(LIBSSH_OBJS)
> + $(RANLIB) $@
> +
> +-ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS)
> +- $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
> ++ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS) $(KEYCHAINOBJS)
> ++ $(LD) -o $@ $(SSHOBJS) $(KEYCHAINOBJS) $(LDFLAGS) $
> (KEYCHAIN_LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
> +
> + sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS)
> + $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $
> (SSHDLIBS) $(LIBS)
> +@@ -141,11 +145,11 @@
> + scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o
> + $(LD) -o $@ scp.o progressmeter.o bufaux.o $(LDFLAGS) -lssh -
> lopenbsd-compat $(LIBS)
> +
> +-ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-add.o
> +- $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
> ++ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-add.o $(KEYCHAINOBJS)
> ++ $(LD) -o $@ ssh-add.o $(KEYCHAINOBJS) $(LDFLAGS) $
> (KEYCHAIN_LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
> +
> +-ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o
> +- $(LD) -o $@ ssh-agent.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
> ++ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o $
> (KEYCHAINOBJS)
> ++ $(LD) -o $@ ssh-agent.o $(KEYCHAINOBJS) $(LDFLAGS) $
> (KEYCHAIN_LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
> +
> + ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o
> + $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
> +diff -uNr ../openssh-5.0p1.orig/authfd.c ./authfd.c
> +--- ../openssh-5.0p1.orig/authfd.c 2006-08-31 22:38:36.000000000
> -0700
> ++++ ./authfd.c 2008-04-15 18:32:47.000000000 -0700
> +@@ -652,6 +652,29 @@
> + return decode_reply(type);
> + }
> +
> ++/*
> ++ * Adds identities using passphrases stored in the keychain. This
> call is not
> ++ * meant to be used by normal applications.
> ++ */
> ++
> ++int
> ++ssh_add_from_keychain(AuthenticationConnection *auth)
> ++{
> ++ Buffer msg;
> ++ int type;
> ++
> ++ buffer_init(&msg);
> ++ buffer_put_char(&msg, SSH_AGENTC_ADD_FROM_KEYCHAIN);
> ++
> ++ if (ssh_request_reply(auth, &msg, &msg) == 0) {
> ++ buffer_free(&msg);
> ++ return 0;
> ++ }
> ++ type = buffer_get_char(&msg);
> ++ buffer_free(&msg);
> ++ return decode_reply(type);
> ++}
> ++
> + int
> + decode_reply(int type)
> + {
> +diff -uNr ../openssh-5.0p1.orig/authfd.h ./authfd.h
> +--- ../openssh-5.0p1.orig/authfd.h 2006-08-04 19:39:39.000000000
> -0700
> ++++ ./authfd.h 2008-04-15 18:32:47.000000000 -0700
> +@@ -49,6 +49,9 @@
> + #define SSH2_AGENTC_ADD_ID_CONSTRAINED 25
> + #define SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED 26
> +
> ++/* keychain */
> ++#define SSH_AGENTC_ADD_FROM_KEYCHAIN 27
> ++
> + #define SSH_AGENT_CONSTRAIN_LIFETIME 1
> + #define SSH_AGENT_CONSTRAIN_CONFIRM 2
> +
> +diff -uNr ../openssh-5.0p1.orig/configure ./configure
> +--- ../openssh-5.0p1.orig/configure 2008-04-03 03:01:50.000000000
> -0700
> ++++ ./configure 2008-04-15 18:32:47.000000000 -0700
> +@@ -723,6 +723,7 @@
> + mansubdir
> + user_path
> + piddir
> ++KEYCHAIN_LDFLAGS
> + LIBOBJS
> + LTLIBOBJS'
> + ac_subst_files=''
> +@@ -1364,6 +1365,7 @@
> + --with-bsd-auth Enable BSD auth support
> + --with-pid-dir=PATH Specify location of ssh.pid file
> + --with-lastlog=FILE|DIR specify lastlog location common locations
> ++ --with-keychain=apple Use Mac OS X Keychain
> +
> + Some influential environment variables:
> + CC C compiler command
> +@@ -7133,6 +7135,7 @@
> + #define DISABLE_FD_PASSING 1
> + _ACEOF
> +
> ++ KEYCHAIN="apple"
> + ;;
> + *-*-dgux*)
> + cat >>confdefs.h <<\_ACEOF
> +@@ -28605,6 +28608,181 @@
> + echo "$as_me: WARNING: Please check and edit blibpath in LDFLAGS
> in Makefile" >&2;}
> + fi
> +
> ++# Check whether --with-keychain was given.
> ++if test "${with_keychain+set}" = set; then
> ++ withval=$with_keychain;
> ++ case "$withval" in
> ++ apple|no)
> ++ KEYCHAIN=$withval
> ++ ;;
> ++ *)
> ++ { { echo "$as_me:$LINENO: error: invalid keychain type:
> $withval" >&5
> ++echo "$as_me: error: invalid keychain type: $withval" >&2;}
> ++ { (exit 1); exit 1; }; }
> ++ ;;
> ++ esac
> ++
> ++
> ++fi
> ++
> ++if test ! -z "$KEYCHAIN" -a "$KEYCHAIN" != "no"; then
> ++ case "$KEYCHAIN" in
> ++ apple)
> ++
> ++for ac_header in Security/Security.h
> ++do
> ++as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
> ++if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" =
> set"; }; then
> ++ { echo "$as_me:$LINENO: checking for $ac_header" >&5
> ++echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
> ++if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" =
> set"; }; then
> ++ echo $ECHO_N "(cached) $ECHO_C" >&6
> ++fi
> ++ac_res=`eval echo '${'$as_ac_Header'}'`
> ++ { echo "$as_me:$LINENO: result: $ac_res" >&5
> ++echo "${ECHO_T}$ac_res" >&6; }
> ++else
> ++ # Is the header compilable?
> ++{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
> ++echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
> ++cat >conftest.$ac_ext <<_ACEOF
> ++/* confdefs.h. */
> ++_ACEOF
> ++cat confdefs.h >>conftest.$ac_ext
> ++cat >>conftest.$ac_ext <<_ACEOF
> ++/* end confdefs.h. */
> ++$ac_includes_default
> ++#include <$ac_header>
> ++_ACEOF
> ++rm -f conftest.$ac_objext
> ++if { (ac_try="$ac_compile"
> ++case "(($ac_try" in
> ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
> ++ *) ac_try_echo=$ac_try;;
> ++esac
> ++eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
> ++ (eval "$ac_compile") 2>conftest.er1
> ++ ac_status=$?
> ++ grep -v '^ *+' conftest.er1 >conftest.err
> ++ rm -f conftest.er1
> ++ cat conftest.err >&5
> ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
> ++ (exit $ac_status); } && {
> ++ test -z "$ac_c_werror_flag" ||
> ++ test ! -s conftest.err
> ++ } && test -s conftest.$ac_objext; then
> ++ ac_header_compiler=yes
> ++else
> ++ echo "$as_me: failed program was:" >&5
> ++sed 's/^/| /' conftest.$ac_ext >&5
> ++
> ++ ac_header_compiler=no
> ++fi
> ++
> ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
> ++{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
> ++echo "${ECHO_T}$ac_header_compiler" >&6; }
> ++
> ++# Is the header present?
> ++{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
> ++echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
> ++cat >conftest.$ac_ext <<_ACEOF
> ++/* confdefs.h. */
> ++_ACEOF
> ++cat confdefs.h >>conftest.$ac_ext
> ++cat >>conftest.$ac_ext <<_ACEOF
> ++/* end confdefs.h. */
> ++#include <$ac_header>
> ++_ACEOF
> ++if { (ac_try="$ac_cpp conftest.$ac_ext"
> ++case "(($ac_try" in
> ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
> ++ *) ac_try_echo=$ac_try;;
> ++esac
> ++eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
> ++ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
> ++ ac_status=$?
> ++ grep -v '^ *+' conftest.er1 >conftest.err
> ++ rm -f conftest.er1
> ++ cat conftest.err >&5
> ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
> ++ (exit $ac_status); } >/dev/null && {
> ++ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
> ++ test ! -s conftest.err
> ++ }; then
> ++ ac_header_preproc=yes
> ++else
> ++ echo "$as_me: failed program was:" >&5
> ++sed 's/^/| /' conftest.$ac_ext >&5
> ++
> ++ ac_header_preproc=no
> ++fi
> ++
> ++rm -f conftest.err conftest.$ac_ext
> ++{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
> ++echo "${ECHO_T}$ac_header_preproc" >&6; }
> ++
> ++# So? What about this header?
> ++case $ac_header_compiler:$ac_header_preproc:
> $ac_c_preproc_warn_flag in
> ++ yes:no: )
> ++ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the
> compiler, rejected by the preprocessor!" >&5
> ++echo "$as_me: WARNING: $ac_header: accepted by the compiler,
> rejected by the preprocessor!" >&2;}
> ++ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with
> the compiler's result" >&5
> ++echo "$as_me: WARNING: $ac_header: proceeding with the compiler's
> result" >&2;}
> ++ ac_header_preproc=yes
> ++ ;;
> ++ no:yes:* )
> ++ { echo "$as_me:$LINENO: WARNING: $ac_header: present but
> cannot be compiled" >&5
> ++echo "$as_me: WARNING: $ac_header: present but cannot be compiled"
> >&2;}
> ++ { echo "$as_me:$LINENO: WARNING: $ac_header: check for
> missing prerequisite headers?" >&5
> ++echo "$as_me: WARNING: $ac_header: check for missing
> prerequisite headers?" >&2;}
> ++ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf
> documentation" >&5
> ++echo "$as_me: WARNING: $ac_header: see the Autoconf documentation"
> >&2;}
> ++ { echo "$as_me:$LINENO: WARNING: $ac_header: section
> \"Present But Cannot Be Compiled\"" >&5
> ++echo "$as_me: WARNING: $ac_header: section \"Present But
> Cannot Be Compiled\"" >&2;}
> ++ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with
> the preprocessor's result" >&5
> ++echo "$as_me: WARNING: $ac_header: proceeding with the
> preprocessor's result" >&2;}
> ++ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future,
> the compiler will take precedence" >&5
> ++echo "$as_me: WARNING: $ac_header: in the future, the compiler
> will take precedence" >&2;}
> ++ ( cat <<\_ASBOX
> ++## ------------------------------------------- ##
> ++## Report this to openssh-unix-dev at mindrot.org ##
> ++## ------------------------------------------- ##
> ++_ASBOX
> ++ ) | sed "s/^/$as_me: WARNING: /" >&2
> ++ ;;
> ++esac
> ++{ echo "$as_me:$LINENO: checking for $ac_header" >&5
> ++echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
> ++if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" =
> set"; }; then
> ++ echo $ECHO_N "(cached) $ECHO_C" >&6
> ++else
> ++ eval "$as_ac_Header=\$ac_header_preproc"
> ++fi
> ++ac_res=`eval echo '${'$as_ac_Header'}'`
> ++ { echo "$as_me:$LINENO: result: $ac_res" >&5
> ++echo "${ECHO_T}$ac_res" >&6; }
> ++
> ++fi
> ++if test `eval echo '${'$as_ac_Header'}'` = yes; then
> ++ cat >>confdefs.h <<_ACEOF
> ++#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
> ++_ACEOF
> ++
> ++ CPPFLAGS="$CPPFLAGS -D__APPLE_KEYCHAIN__"
> ++ KEYCHAIN_LDFLAGS="-framework Security -framework CoreFoundation"
> ++
> ++
> ++else
> ++ { echo "$as_me:$LINENO: WARNING: Security framework not found.
> Disabling Mac OS X Keychain support." >&5
> ++echo "$as_me: WARNING: Security framework not found. Disabling Mac
> OS X Keychain support." >&2;}
> ++fi
> ++
> ++done
> ++
> ++ ;;
> ++ esac
> ++fi
> + CFLAGS="$CFLAGS $werror_flags"
> +
> +
> +@@ -29230,7 +29408,6 @@
> + _ACEOF
> +
> +
> +-
> + ac_delim='%!_!# '
> + for ac_last_try in false false false false false :; do
> + cat >conf$$subs.sed <<_ACEOF
> +@@ -29382,11 +29559,12 @@
> + mansubdir!$mansubdir$ac_delim
> + user_path!$user_path$ac_delim
> + piddir!$piddir$ac_delim
> ++KEYCHAIN_LDFLAGS!$KEYCHAIN_LDFLAGS$ac_delim
> + LIBOBJS!$LIBOBJS$ac_delim
> + LTLIBOBJS!$LTLIBOBJS$ac_delim
> + _ACEOF
> +
> +- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c
> X` = 12; then
> ++ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c
> X` = 13; then
> + break
> + elif $ac_last_try; then
> + { { echo "$as_me:$LINENO: error: could not make
> $CONFIG_STATUS" >&5
> +diff -uNr ../openssh-5.0p1.orig/configure.ac ./configure.ac
> +--- ../openssh-5.0p1.orig/configure.ac 2008-03-26
> 18:33:07.000000000 -0700
> ++++ ./configure.ac 2008-04-15 18:32:47.000000000 -0700
> +@@ -594,6 +594,7 @@
> + AC_DEFINE(SSH_TUN_NO_L2, 1, [No layer 2 tunnel support]))
> + AC_DEFINE(SSH_TUN_PREPEND_AF, 1,
> + [Prepend the address family to IP tunnel traffic])
> ++ KEYCHAIN="apple"
> + ;;
> + *-*-freebsd*)
> + check_for_libcrypt_later=1
> +@@ -4035,6 +4036,33 @@
> + AC_MSG_WARN([Please check and edit blibpath in LDFLAGS in
> Makefile])
> + fi
> +
> ++dnl Keychain support
> ++AC_ARG_WITH(keychain,
> ++ [ --with-keychain=apple Use Mac OS X Keychain],
> ++ [
> ++ case "$withval" in
> ++ apple|no)
> ++ KEYCHAIN=$withval
> ++ ;;
> ++ *)
> ++ AC_MSG_ERROR(invalid keychain type: $withval)
> ++ ;;
> ++ esac
> ++ ]
> ++)
> ++if test ! -z "$KEYCHAIN" -a "$KEYCHAIN" != "no"; then
> ++ case "$KEYCHAIN" in
> ++ apple)
> ++ AC_CHECK_HEADERS(Security/Security.h, [
> ++ CPPFLAGS="$CPPFLAGS -D__APPLE_KEYCHAIN__"
> ++ KEYCHAIN_LDFLAGS="-framework Security -framework CoreFoundation"
> ++ AC_SUBST(KEYCHAIN_LDFLAGS)
> ++ ],
> ++ AC_MSG_WARN([Security framework not found. Disabling Mac OS X
> Keychain support.]))
> ++ ;;
> ++ esac
> ++fi
> ++
> + dnl Adding -Werror to CFLAGS early prevents configure tests from
> running.
> + dnl Add now.
> + CFLAGS="$CFLAGS $werror_flags"
> +diff -uNr ../openssh-5.0p1.orig/keychain.c ./keychain.c
> +--- ../openssh-5.0p1.orig/keychain.c 1969-12-31 16:00:00.000000000
> -0800
> ++++ ./keychain.c 2008-04-15 18:32:47.000000000 -0700
> +@@ -0,0 +1,675 @@
> ++/*
> ++ * Copyright (c) 2007 Apple Inc. All rights reserved.
> ++ *
> ++ * @APPLE_BSD_LICENSE_HEADER_START@
> ++ *
> ++ * Redistribution and use in source and binary forms, with or
> without
> ++ * modification, are permitted provided that the following
> conditions
> ++ * are met:
> ++ *
> ++ * 1. Redistributions of source code must retain the above
> copyright
> ++ * notice, this list of conditions and the following disclaimer.
> ++ * 2. Redistributions in binary form must reproduce the above
> copyright
> ++ * notice, this list of conditions and the following
> disclaimer in the
> ++ * documentation and/or other materials provided with the
> distribution.
> ++ * 3. Neither the name of Apple Inc. ("Apple") nor the names of its
> ++ * contributors may be used to endorse or promote products
> derived from
> ++ * this software without specific prior written permission.
> ++ *
> ++ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS"
> AND ANY
> ++ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE IMPLIED
> ++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE ARE
> ++ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE
> LIABLE FOR ANY
> ++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> CONSEQUENTIAL DAMAGES
> ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
> OR SERVICES;
> ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> HOWEVER CAUSED AND
> ++ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
> LIABILITY, OR TORT
> ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
> THE USE OF
> ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> ++ *
> ++ * @APPLE_BSD_LICENSE_HEADER_END@
> ++ */
> ++
> ++#include "includes.h"
> ++
> ++#include <stdio.h>
> ++#include <string.h>
> ++
> ++#include "xmalloc.h"
> ++#include "key.h"
> ++#include "authfd.h"
> ++
> ++#if defined(__APPLE_KEYCHAIN__)
> ++
> ++#include <CoreFoundation/CoreFoundation.h>
> ++#include <Security/Security.h>
> ++#include <Security/SecPassword.h>
> ++
> ++#endif
> ++
> ++/*
> ++ * Platform-specific helper functions.
> ++ */
> ++
> ++#if defined(__APPLE_KEYCHAIN__)
> ++
> ++static int get_boolean_preference(const char *key, int
> default_value,
> ++ int foreground)
> ++{
> ++ int value = default_value;
> ++ CFStringRef keyRef = NULL;
> ++ CFPropertyListRef valueRef = NULL;
> ++
> ++ keyRef = CFStringCreateWithCString(NULL, key,
> kCFStringEncodingUTF8);
> ++ if (keyRef != NULL)
> ++ valueRef = CFPreferencesCopyAppValue(keyRef,
> ++ CFSTR("org.openbsd.openssh"));
> ++ if (valueRef != NULL)
> ++ if (CFGetTypeID(valueRef) == CFBooleanGetTypeID())
> ++ value = CFBooleanGetValue(valueRef);
> ++ else if (foreground)
> ++ fprintf(stderr, "Ignoring nonboolean %s preference.\n", key);
> ++
> ++ if (keyRef)
> ++ CFRelease(keyRef);
> ++ if (valueRef)
> ++ CFRelease(valueRef);
> ++
> ++ return value;
> ++}
> ++
> ++#endif
> ++
> ++/*
> ++ * Store the passphrase for a given identity in the keychain.
> ++ */
> ++void
> ++store_in_keychain(const char *filename, const char *passphrase)
> ++{
> ++
> ++#if defined(__APPLE_KEYCHAIN__)
> ++
> ++ /*
> ++ * store_in_keychain
> ++ * Mac OS X implementation
> ++ */
> ++
> ++ CFStringRef cfstr_relative_filename = NULL;
> ++ CFURLRef cfurl_relative_filename = NULL, cfurl_filename = NULL;
> ++ CFStringRef cfstr_filename = NULL;
> ++ CFDataRef cfdata_filename = NULL;
> ++ CFIndex filename_len;
> ++ UInt8 *label = NULL;
> ++ UInt8 *utf8_filename;
> ++ OSStatus rv;
> ++ SecKeychainItemRef itemRef = NULL;
> ++ SecTrustedApplicationRef apps[] = {NULL, NULL, NULL};
> ++ CFArrayRef trustedlist = NULL;
> ++ SecAccessRef initialAccess = NULL;
> ++
> ++ /* Bail out if KeychainIntegration preference is -bool NO */
> ++ if (get_boolean_preference("KeychainIntegration", 1, 1) == 0) {
> ++ fprintf(stderr, "Keychain integration is disabled.\n");
> ++ goto err;
> ++ }
> ++
> ++ /* Interpret filename with the correct encoding. */
> ++ if ((cfstr_relative_filename =
> ++ CFStringCreateWithFileSystemRepresentation(NULL, filename))
> == NULL)
> ++ {
> ++ fprintf(stderr, "CFStringCreateWithFileSystemRepresentation
> failed\n");
> ++ goto err;
> ++ }
> ++ if ((cfurl_relative_filename = CFURLCreateWithFileSystemPath(NULL,
> ++ cfstr_relative_filename, kCFURLPOSIXPathStyle, false)) ==
> NULL) {
> ++ fprintf(stderr, "CFURLCreateWithFileSystemPath failed\n");
> ++ goto err;
> ++ }
> ++ if ((cfurl_filename =
> CFURLCopyAbsoluteURL(cfurl_relative_filename)) ==
> ++ NULL) {
> ++ fprintf(stderr, "CFURLCopyAbsoluteURL failed\n");
> ++ goto err;
> ++ }
> ++ if ((cfstr_filename = CFURLCopyFileSystemPath(cfurl_filename,
> ++ kCFURLPOSIXPathStyle)) == NULL) {
> ++ fprintf(stderr, "CFURLCopyFileSystemPath failed\n");
> ++ goto err;
> ++ }
> ++ if ((cfdata_filename = CFStringCreateExternalRepresentation(NULL,
> ++ cfstr_filename, kCFStringEncodingUTF8, 0)) == NULL) {
> ++ fprintf(stderr, "CFStringCreateExternalRepresentation failed\n");
> ++ goto err;
> ++ }
> ++ filename_len = CFDataGetLength(cfdata_filename);
> ++ if ((label = xmalloc(filename_len + 5)) == NULL) {
> ++ fprintf(stderr, "xmalloc failed\n");
> ++ goto err;
> ++ }
> ++ memcpy(label, "SSH: ", 5);
> ++ utf8_filename = label + 5;
> ++ CFDataGetBytes(cfdata_filename, CFRangeMake(0, filename_len),
> ++ utf8_filename);
> ++
> ++ /* Check if we already have this passphrase. */
> ++ rv = SecKeychainFindGenericPassword(NULL, 3, "SSH", filename_len,
> ++ (char *)utf8_filename, NULL, NULL, &itemRef);
> ++ if (rv == errSecItemNotFound) {
> ++ /* Add a new keychain item. */
> ++ SecKeychainAttribute attrs[] = {
> ++ {kSecLabelItemAttr, filename_len + 5, label},
> ++ {kSecServiceItemAttr, 3, "SSH"},
> ++ {kSecAccountItemAttr, filename_len, utf8_filename}
> ++ };
> ++ SecKeychainAttributeList attrList =
> ++ {sizeof(attrs) / sizeof(attrs[0]), attrs};
> ++ if (SecTrustedApplicationCreateFromPath("/opt/local/bin/ssh-
> agent",
> ++ &apps[0]) != noErr ||
> ++ SecTrustedApplicationCreateFromPath("/opt/local/bin/ssh-add",
> ++ &apps[1]) != noErr ||
> ++ SecTrustedApplicationCreateFromPath("/opt/local/bin/ssh",
> ++ &apps[2]) != noErr) {
> ++ fprintf(stderr, "SecTrustedApplicationCreateFromPath failed\n");
> ++ goto err;
> ++ }
> ++ if ((trustedlist = CFArrayCreate(NULL, (const void **)apps,
> ++ sizeof(apps) / sizeof(apps[0]), &kCFTypeArrayCallBacks)) ==
> ++ NULL) {
> ++ fprintf(stderr, "CFArrayCreate failed\n");
> ++ goto err;
> ++ }
> ++ if (SecAccessCreate(cfstr_filename, trustedlist,
> ++ &initialAccess) != noErr) {
> ++ fprintf(stderr, "SecAccessCreate failed\n");
> ++ goto err;
> ++ }
> ++ if (SecKeychainItemCreateFromContent(
> ++ kSecGenericPasswordItemClass, &attrList, strlen(passphrase),
> ++ passphrase, NULL, initialAccess, NULL) == noErr)
> ++ fprintf(stderr, "Passphrase stored in keychain: %s\n", filename);
> ++ else
> ++ fprintf(stderr, "Could not create keychain item\n");
> ++ } else if (rv == noErr) {
> ++ /* Update an existing keychain item. */
> ++ if (SecKeychainItemModifyAttributesAndData(itemRef, NULL,
> ++ strlen(passphrase), passphrase) == noErr)
> ++ fprintf(stderr, "Passphrase updated in keychain: %s\n",
> filename);
> ++ else
> ++ fprintf(stderr, "Could not modify keychain item\n");
> ++ } else
> ++ fprintf(stderr, "Could not access keychain\n");
> ++
> ++err: /* Clean up. */
> ++ if (cfstr_relative_filename)
> ++ CFRelease(cfstr_relative_filename);
> ++ if (cfurl_relative_filename)
> ++ CFRelease(cfurl_relative_filename);
> ++ if (cfurl_filename)
> ++ CFRelease(cfurl_filename);
> ++ if (cfstr_filename)
> ++ CFRelease(cfstr_filename);
> ++ if (cfdata_filename)
> ++ CFRelease(cfdata_filename);
> ++ if (label)
> ++ xfree(label);
> ++ if (itemRef)
> ++ CFRelease(itemRef);
> ++ if (apps[0])
> ++ CFRelease(apps[0]);
> ++ if (apps[1])
> ++ CFRelease(apps[1]);
> ++ if (apps[2])
> ++ CFRelease(apps[2]);
> ++ if (trustedlist)
> ++ CFRelease(trustedlist);
> ++ if (initialAccess)
> ++ CFRelease(initialAccess);
> ++
> ++#else
> ++
> ++ /*
> ++ * store_in_keychain
> ++ * no keychain implementation
> ++ */
> ++
> ++ fprintf(stderr, "Keychain is not available on this system\n");
> ++
> ++#endif
> ++
> ++}
> ++
> ++/*
> ++ * Remove the passphrase for a given identity from the keychain.
> ++ */
> ++void
> ++remove_from_keychain(const char *filename)
> ++{
> ++
> ++#if defined(__APPLE_KEYCHAIN__)
> ++
> ++ /*
> ++ * remove_from_keychain
> ++ * Mac OS X implementation
> ++ */
> ++
> ++ CFStringRef cfstr_relative_filename = NULL;
> ++ CFURLRef cfurl_relative_filename = NULL, cfurl_filename = NULL;
> ++ CFStringRef cfstr_filename = NULL;
> ++ CFDataRef cfdata_filename = NULL;
> ++ CFIndex filename_len;
> ++ const UInt8 *utf8_filename;
> ++ OSStatus rv;
> ++ SecKeychainItemRef itemRef = NULL;
> ++
> ++ /* Bail out if KeychainIntegration preference is -bool NO */
> ++ if (get_boolean_preference("KeychainIntegration", 1, 1) == 0) {
> ++ fprintf(stderr, "Keychain integration is disabled.\n");
> ++ goto err;
> ++ }
> ++
> ++ /* Interpret filename with the correct encoding. */
> ++ if ((cfstr_relative_filename =
> ++ CFStringCreateWithFileSystemRepresentation(NULL, filename))
> == NULL)
> ++ {
> ++ fprintf(stderr, "CFStringCreateWithFileSystemRepresentation
> failed\n");
> ++ goto err;
> ++ }
> ++ if ((cfurl_relative_filename = CFURLCreateWithFileSystemPath(NULL,
> ++ cfstr_relative_filename, kCFURLPOSIXPathStyle, false)) ==
> NULL) {
> ++ fprintf(stderr, "CFURLCreateWithFileSystemPath failed\n");
> ++ goto err;
> ++ }
> ++ if ((cfurl_filename =
> CFURLCopyAbsoluteURL(cfurl_relative_filename)) ==
> ++ NULL) {
> ++ fprintf(stderr, "CFURLCopyAbsoluteURL failed\n");
> ++ goto err;
> ++ }
> ++ if ((cfstr_filename = CFURLCopyFileSystemPath(cfurl_filename,
> ++ kCFURLPOSIXPathStyle)) == NULL) {
> ++ fprintf(stderr, "CFURLCopyFileSystemPath failed\n");
> ++ goto err;
> ++ }
> ++ if ((cfdata_filename = CFStringCreateExternalRepresentation(NULL,
> ++ cfstr_filename, kCFStringEncodingUTF8, 0)) == NULL) {
> ++ fprintf(stderr, "CFStringCreateExternalRepresentation failed\n");
> ++ goto err;
> ++ }
> ++ filename_len = CFDataGetLength(cfdata_filename);
> ++ utf8_filename = CFDataGetBytePtr(cfdata_filename);
> ++
> ++ /* Check if we already have this passphrase. */
> ++ rv = SecKeychainFindGenericPassword(NULL, 3, "SSH", filename_len,
> ++ (const char *)utf8_filename, NULL, NULL, &itemRef);
> ++ if (rv == noErr) {
> ++ /* Remove the passphrase from the keychain. */
> ++ if (SecKeychainItemDelete(itemRef) == noErr)
> ++ fprintf(stderr, "Passphrase removed from keychain: %s\n",
> filename);
> ++ else
> ++ fprintf(stderr, "Could not remove keychain item\n");
> ++ } else if (rv != errSecItemNotFound)
> ++ fprintf(stderr, "Could not access keychain\n");
> ++
> ++err: /* Clean up. */
> ++ if (cfstr_relative_filename)
> ++ CFRelease(cfstr_relative_filename);
> ++ if (cfurl_relative_filename)
> ++ CFRelease(cfurl_relative_filename);
> ++ if (cfurl_filename)
> ++ CFRelease(cfurl_filename);
> ++ if (cfstr_filename)
> ++ CFRelease(cfstr_filename);
> ++ if (cfdata_filename)
> ++ CFRelease(cfdata_filename);
> ++ if (itemRef)
> ++ CFRelease(itemRef);
> ++
> ++#else
> ++
> ++ /*
> ++ * remove_from_keychain
> ++ * no keychain implementation
> ++ */
> ++
> ++ fprintf(stderr, "Keychain is not available on this system\n");
> ++
> ++#endif
> ++
> ++}
> ++
> ++/*
> ++ * Add identities to ssh-agent using passphrases stored in the
> keychain.
> ++ * Returns zero on success and nonzero on failure.
> ++ * add_identity is a callback into ssh-agent. It takes a filename
> and a
> ++ * passphrase, and attempts to add the identity to the agent. It
> returns
> ++ * zero on success and nonzero on failure.
> ++ */
> ++int
> ++add_identities_using_keychain(int (*add_identity)(const char *,
> const char *))
> ++{
> ++
> ++#if defined(__APPLE_KEYCHAIN__)
> ++
> ++ /*
> ++ * add_identities_using_keychain
> ++ * Mac OS X implementation
> ++ */
> ++
> ++ OSStatus rv;
> ++ SecKeychainSearchRef searchRef;
> ++ SecKeychainItemRef itemRef;
> ++ UInt32 length;
> ++ void *data;
> ++ CFIndex maxsize;
> ++
> ++ /* Bail out if KeychainIntegration preference is -bool NO */
> ++ if (get_boolean_preference("KeychainIntegration", 1, 0) == 0)
> ++ return 0;
> ++
> ++ /* Search for SSH passphrases in the keychain */
> ++ SecKeychainAttribute attrs[] = {
> ++ {kSecServiceItemAttr, 3, "SSH"}
> ++ };
> ++ SecKeychainAttributeList attrList =
> ++ {sizeof(attrs) / sizeof(attrs[0]), attrs};
> ++ if ((rv = SecKeychainSearchCreateFromAttributes(NULL,
> ++ kSecGenericPasswordItemClass, &attrList, &searchRef)) != noErr)
> ++ return 0;
> ++
> ++ /* Iterate through the search results. */
> ++ while ((rv = SecKeychainSearchCopyNext(searchRef, &itemRef)) ==
> noErr) {
> ++ UInt32 tag = kSecAccountItemAttr;
> ++ UInt32 format = kSecFormatUnknown;
> ++ SecKeychainAttributeInfo info = {1, &tag, &format};
> ++ SecKeychainAttributeList *itemAttrList = NULL;
> ++ CFStringRef cfstr_filename = NULL;
> ++ char *filename = NULL;
> ++ char *passphrase = NULL;
> ++
> ++ /* Retrieve filename and passphrase. */
> ++ if ((rv = SecKeychainItemCopyAttributesAndData(itemRef, &info,
> ++ NULL, &itemAttrList, &length, &data)) != noErr)
> ++ goto err;
> ++ if (itemAttrList->count != 1)
> ++ goto err;
> ++ cfstr_filename = CFStringCreateWithBytes(NULL,
> ++ itemAttrList->attr->data, itemAttrList->attr->length,
> ++ kCFStringEncodingUTF8, true);
> ++ maxsize = CFStringGetMaximumSizeOfFileSystemRepresentation(
> ++ cfstr_filename);
> ++ if ((filename = xmalloc(maxsize)) == NULL)
> ++ goto err;
> ++ if (CFStringGetFileSystemRepresentation(cfstr_filename,
> ++ filename, maxsize) == false)
> ++ goto err;
> ++ if ((passphrase = xmalloc(length + 1)) == NULL)
> ++ goto err;
> ++ memcpy(passphrase, data, length);
> ++ passphrase[length] = '\0';
> ++
> ++ /* Add the identity. */
> ++ add_identity(filename, passphrase);
> ++
> ++err: /* Clean up. */
> ++ if (itemRef)
> ++ CFRelease(itemRef);
> ++ if (cfstr_filename)
> ++ CFRelease(cfstr_filename);
> ++ if (filename)
> ++ xfree(filename);
> ++ if (passphrase)
> ++ xfree(passphrase);
> ++ if (itemAttrList)
> ++ SecKeychainItemFreeAttributesAndData(itemAttrList,
> ++ data);
> ++ }
> ++
> ++ CFRelease(searchRef);
> ++
> ++ return 0;
> ++
> ++#else
> ++
> ++ /*
> ++ * add_identities_using_keychain
> ++ * no implementation
> ++ */
> ++
> ++ return 1;
> ++
> ++#endif
> ++
> ++}
> ++
> ++/*
> ++ * Prompt the user for a key's passphrase. The user will be
> offered the option
> ++ * of storing the passphrase in their keychain. Returns the
> passphrase
> ++ * (which the caller is responsible for xfreeing), or NULL if this
> function
> ++ * fails or is not implemented. If this function is not
> implemented, ssh will
> ++ * fall back on the standard read_passphrase function, and the
> user will need
> ++ * to use ssh-add -K to add their keys to the keychain.
> ++ */
> ++char *
> ++keychain_read_passphrase(const char *filename)
> ++{
> ++
> ++#if defined(__APPLE_KEYCHAIN__)
> ++
> ++ /*
> ++ * keychain_read_passphrase
> ++ * Mac OS X implementation
> ++ */
> ++
> ++ CFStringRef cfstr_relative_filename = NULL;
> ++ CFURLRef cfurl_relative_filename = NULL, cfurl_filename = NULL;
> ++ CFStringRef cfstr_filename = NULL;
> ++ CFDataRef cfdata_filename = NULL;
> ++ CFIndex filename_len;
> ++ UInt8 *label = NULL;
> ++ UInt8 *utf8_filename;
> ++ SecPasswordRef passRef = NULL;
> ++ SecTrustedApplicationRef apps[] = {NULL, NULL, NULL};
> ++ CFArrayRef trustedlist = NULL;
> ++ SecAccessRef initialAccess = NULL;
> ++ CFURLRef path = NULL;
> ++ CFStringRef pathFinal = NULL;
> ++ CFURLRef bundle_url = NULL;
> ++ CFBundleRef bundle = NULL;
> ++ CFStringRef promptTemplate = NULL, prompt = NULL;
> ++ UInt32 length;
> ++ const void *data;
> ++ AuthenticationConnection *ac = NULL;
> ++ char *result = NULL;
> ++
> ++ /* Bail out if KeychainIntegration preference is -bool NO */
> ++ if (get_boolean_preference("KeychainIntegration", 1, 1) == 0)
> ++ goto err;
> ++
> ++ /* Bail out if the user set AskPassGUI preference to -bool NO */
> ++ if (get_boolean_preference("AskPassGUI", 1, 1) == 0)
> ++ goto err;
> ++
> ++ /* Bail out if we can't communicate with ssh-agent */
> ++ if ((ac = ssh_get_authentication_connection()) == NULL)
> ++ goto err;
> ++
> ++ /* Interpret filename with the correct encoding. */
> ++ if ((cfstr_relative_filename =
> ++ CFStringCreateWithFileSystemRepresentation(NULL, filename))
> == NULL)
> ++ {
> ++ fprintf(stderr, "CFStringCreateWithFileSystemRepresentation
> failed\n");
> ++ goto err;
> ++ }
> ++ if ((cfurl_relative_filename = CFURLCreateWithFileSystemPath(NULL,
> ++ cfstr_relative_filename, kCFURLPOSIXPathStyle, false)) ==
> NULL) {
> ++ fprintf(stderr, "CFURLCreateWithFileSystemPath failed\n");
> ++ goto err;
> ++ }
> ++ if ((cfurl_filename =
> CFURLCopyAbsoluteURL(cfurl_relative_filename)) ==
> ++ NULL) {
> ++ fprintf(stderr, "CFURLCopyAbsoluteURL failed\n");
> ++ goto err;
> ++ }
> ++ if ((cfstr_filename = CFURLCopyFileSystemPath(cfurl_filename,
> ++ kCFURLPOSIXPathStyle)) == NULL) {
> ++ fprintf(stderr, "CFURLCopyFileSystemPath failed\n");
> ++ goto err;
> ++ }
> ++ if ((cfdata_filename = CFStringCreateExternalRepresentation(NULL,
> ++ cfstr_filename, kCFStringEncodingUTF8, 0)) == NULL) {
> ++ fprintf(stderr, "CFStringCreateExternalRepresentation failed\n");
> ++ goto err;
> ++ }
> ++ filename_len = CFDataGetLength(cfdata_filename);
> ++ if ((label = xmalloc(filename_len + 5)) == NULL) {
> ++ fprintf(stderr, "xmalloc failed\n");
> ++ goto err;
> ++ }
> ++ memcpy(label, "SSH: ", 5);
> ++ utf8_filename = label + 5;
> ++ CFDataGetBytes(cfdata_filename, CFRangeMake(0, filename_len),
> ++ utf8_filename);
> ++
> ++ /* Build a SecPasswordRef. */
> ++ SecKeychainAttribute searchAttrs[] = {
> ++ {kSecServiceItemAttr, 3, "SSH"},
> ++ {kSecAccountItemAttr, filename_len, utf8_filename}
> ++ };
> ++ SecKeychainAttributeList searchAttrList =
> ++ {sizeof(searchAttrs) / sizeof(searchAttrs[0]), searchAttrs};
> ++ SecKeychainAttribute attrs[] = {
> ++ {kSecLabelItemAttr, filename_len + 5, label},
> ++ {kSecServiceItemAttr, 3, "SSH"},
> ++ {kSecAccountItemAttr, filename_len, utf8_filename}
> ++ };
> ++ SecKeychainAttributeList attrList =
> ++ {sizeof(attrs) / sizeof(attrs[0]), attrs};
> ++ if (SecGenericPasswordCreate(&searchAttrList, &attrList,
> &passRef) !=
> ++ noErr) {
> ++ fprintf(stderr, "SecGenericPasswordCreate failed\n");
> ++ goto err;
> ++ }
> ++ if (SecTrustedApplicationCreateFromPath("/opt/local/bin/ssh-
> agent", &apps[0])
> ++ != noErr ||
> ++ SecTrustedApplicationCreateFromPath("/opt/local/bin/ssh-add",
> &apps[1])
> ++ != noErr ||
> ++ SecTrustedApplicationCreateFromPath("/opt/local/bin/ssh",
> &apps[2])
> ++ != noErr) {
> ++ fprintf(stderr, "SecTrustedApplicationCreateFromPath failed\n");
> ++ goto err;
> ++ }
> ++ if ((trustedlist = CFArrayCreate(NULL, (const void **)apps,
> ++ sizeof(apps) / sizeof(apps[0]), &kCFTypeArrayCallBacks)) ==
> NULL) {
> ++ fprintf(stderr, "CFArrayCreate failed\n");
> ++ goto err;
> ++ }
> ++ if (SecAccessCreate(cfstr_filename, trustedlist, &initialAccess)
> ++ != noErr) {
> ++ fprintf(stderr, "SecAccessCreate failed\n");
> ++ goto err;
> ++ }
> ++ if (SecPasswordSetInitialAccess(passRef, initialAccess) != noErr) {
> ++ fprintf(stderr, "SecPasswordSetInitialAccess failed\n");
> ++ goto err;
> ++ }
> ++
> ++ /* Request the passphrase from the user. */
> ++ if ((path = CFURLCreateFromFileSystemRepresentation(NULL,
> ++ (UInt8 *)filename, strlen(filename), false)) == NULL) {
> ++ fprintf(stderr, "CFURLCreateFromFileSystemRepresentation failed
> \n");
> ++ goto err;
> ++ }
> ++ if ((pathFinal = CFURLCopyLastPathComponent(path)) == NULL) {
> ++ fprintf(stderr, "CFURLCopyLastPathComponent failed\n");
> ++ goto err;
> ++ }
> ++ if (!((bundle_url = CFURLCreateWithFileSystemPath(NULL,
> ++ CFSTR("/System/Library/CoreServices/"), kCFURLPOSIXPathStyle,
> true))
> ++ != NULL && (bundle = CFBundleCreate(NULL, bundle_url)) !=
> NULL &&
> ++ (promptTemplate = CFCopyLocalizedStringFromTableInBundle(
> ++ CFSTR("Enter your password for the SSH key \"%@\"."),
> ++ CFSTR("OpenSSH"), bundle, "Text of the dialog asking the user
> for"
> ++ "their passphrase. The %@ will be replaced with the filename
> of a"
> ++ "specific key.")) != NULL) &&
> ++ (promptTemplate = CFStringCreateCopy(NULL,
> ++ CFSTR("Enter your password for the SSH key \"%@\"."))) ==
> NULL) {
> ++ fprintf(stderr, "CFStringCreateCopy failed\n");
> ++ goto err;
> ++ }
> ++ if ((prompt = CFStringCreateWithFormat(NULL, NULL, promptTemplate,
> ++ pathFinal)) == NULL) {
> ++ fprintf(stderr, "CFStringCreateWithFormat failed\n");
> ++ goto err;
> ++ }
> ++ switch (SecPasswordAction(passRef, prompt,
> ++ kSecPasswordGet|kSecPasswordFail, &length, &data)) {
> ++ case noErr:
> ++ result = xmalloc(length + 1);
> ++ memcpy(result, data, length);
> ++ result[length] = '\0';
> ++
> ++ /* Save password in keychain if requested. */
> ++ if (SecPasswordAction(passRef, CFSTR(""), kSecPasswordSet,
> ++ &length, &data) == noErr)
> ++ ssh_add_from_keychain(ac);
> ++ break;
> ++ case errAuthorizationCanceled:
> ++ result = xmalloc(1);
> ++ *result = '\0';
> ++ break;
> ++ default:
> ++ goto err;
> ++ }
> ++
> ++err: /* Clean up. */
> ++ if (cfstr_relative_filename)
> ++ CFRelease(cfstr_relative_filename);
> ++ if (cfurl_relative_filename)
> ++ CFRelease(cfurl_relative_filename);
> ++ if (cfurl_filename)
> ++ CFRelease(cfurl_filename);
> ++ if (cfstr_filename)
> ++ CFRelease(cfstr_filename);
> ++ if (cfdata_filename)
> ++ CFRelease(cfdata_filename);
> ++ if (label)
> ++ xfree(label);
> ++ if (passRef)
> ++ CFRelease(passRef);
> ++ if (apps[0])
> ++ CFRelease(apps[0]);
> ++ if (apps[1])
> ++ CFRelease(apps[1]);
> ++ if (apps[2])
> ++ CFRelease(apps[2]);
> ++ if (trustedlist)
> ++ CFRelease(trustedlist);
> ++ if (initialAccess)
> ++ CFRelease(initialAccess);
> ++ if (path)
> ++ CFRelease(path);
> ++ if (pathFinal)
> ++ CFRelease(pathFinal);
> ++ if (bundle_url)
> ++ CFRelease(bundle_url);
> ++ if (bundle)
> ++ CFRelease(bundle);
> ++ if (promptTemplate)
> ++ CFRelease(promptTemplate);
> ++ if (prompt)
> ++ CFRelease(prompt);
> ++ if (ac)
> ++ ssh_close_authentication_connection(ac);
> ++
> ++ return result;
> ++
> ++#else
> ++
> ++ /*
> ++ * keychain_read_passphrase
> ++ * no implementation
> ++ */
> ++
> ++ return NULL;
> ++
> ++#endif
> ++
> ++}
> +diff -uNr ../openssh-5.0p1.orig/keychain.h ./keychain.h
> +--- ../openssh-5.0p1.orig/keychain.h 1969-12-31 16:00:00.000000000
> -0800
> ++++ ./keychain.h 2008-04-15 18:32:47.000000000 -0700
> +@@ -0,0 +1,45 @@
> ++/*
> ++ * Copyright (c) 2007 Apple Inc. All rights reserved.
> ++ *
> ++ * @APPLE_BSD_LICENSE_HEADER_START@
> ++ *
> ++ * Redistribution and use in source and binary forms, with or
> without
> ++ * modification, are permitted provided that the following
> conditions
> ++ * are met:
> ++ *
> ++ * 1. Redistributions of source code must retain the above
> copyright
> ++ * notice, this list of conditions and the following disclaimer.
> ++ * 2. Redistributions in binary form must reproduce the above
> copyright
> ++ * notice, this list of conditions and the following
> disclaimer in the
> ++ * documentation and/or other materials provided with the
> distribution.
> ++ * 3. Neither the name of Apple Inc. ("Apple") nor the names of its
> ++ * contributors may be used to endorse or promote products
> derived from
> ++ * this software without specific prior written permission.
> ++ *
> ++ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS"
> AND ANY
> ++ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE IMPLIED
> ++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE ARE
> ++ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE
> LIABLE FOR ANY
> ++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> CONSEQUENTIAL DAMAGES
> ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
> OR SERVICES;
> ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> HOWEVER CAUSED AND
> ++ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
> LIABILITY, OR TORT
> ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
> THE USE OF
> ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> ++ *
> ++ * @APPLE_BSD_LICENSE_HEADER_END@
> ++ */
> ++
> ++/*
> ++ * KEYCHAIN indicates that keychain functionality is present.
> ++ * KEYCHAIN_* indicates the implementation to use, and implies
> KEYCHAIN.
> ++ */
> ++#if defined(__APPLE_KEYCHAIN__)
> ++#define KEYCHAIN
> ++#endif
> ++
> ++void store_in_keychain(const char *filename, const char
> *passphrase);
> ++void remove_from_keychain(const char *filename);
> ++int add_identities_using_keychain(
> ++ int (*add_identity)(const char *, const char *));
> ++char *keychain_read_passphrase(const char *filename);
> +diff -uNr ../openssh-5.0p1.orig/ssh-add.0 ./ssh-add.0
> +--- ../openssh-5.0p1.orig/ssh-add.0 2008-04-03 03:01:50.000000000
> -0700
> ++++ ./ssh-add.0 2008-04-15 18:35:24.000000000 -0700
> +@@ -1,10 +1,10 @@
> + SSH-ADD(1) OpenBSD Reference
> Manual SSH-ADD(1)
> +
> + NAME
> +- ssh-add - adds RSA or DSA identities to the authentication
> agent
> ++ ssh-add -- adds RSA or DSA identities to the authentication
> agent
> +
> + SYNOPSIS
> +- ssh-add [-cDdLlXx] [-t life] [file ...]
> ++ ssh-add [-cDdLlXxKk] [-t life] [file ...]
> + ssh-add -s reader
> + ssh-add -e reader
> +
> +@@ -58,6 +58,13 @@
> +
> + -x Lock the agent with a password.
> +
> ++ -K When adding identities, each passphrase will also be
> stored in
> ++ your keychain. When removing identities with -d,
> each passphrase
> ++ will be removed from your keychain.
> ++
> ++ -k Add identities to the agent using any passphrases
> stored in your
> ++ keychain.
> ++
> + ENVIRONMENT
> + DISPLAY and SSH_ASKPASS
> + If ssh-add needs a passphrase, it will read the
> passphrase from
> +diff -uNr ../openssh-5.0p1.orig/ssh-add.1 ./ssh-add.1
> +--- ../openssh-5.0p1.orig/ssh-add.1 2007-06-12 07:00:27.000000000
> -0700
> ++++ ./ssh-add.1 2008-04-15 18:32:47.000000000 -0700
> +@@ -45,7 +45,7 @@
> + .Nd adds RSA or DSA identities to the authentication agent
> + .Sh SYNOPSIS
> + .Nm ssh-add
> +-.Op Fl cDdLlXx
> ++.Op Fl cDdLlXxKk
> + .Op Fl t Ar life
> + .Op Ar
> + .Nm ssh-add
> +@@ -121,6 +121,12 @@
> + Unlock the agent.
> + .It Fl x
> + Lock the agent with a password.
> ++.It Fl K
> ++When adding identities, each passphrase will also be stored in your
> ++keychain. When removing identities with -d, each passphrase will be
> ++removed from your keychain.
> ++.It Fl k
> ++Add identities to the agent using any passphrases stored in your
> keychain.
> + .El
> + .Sh ENVIRONMENT
> + .Bl -tag -width Ds
> +diff -uNr ../openssh-5.0p1.orig/ssh-add.c ./ssh-add.c
> +--- ../openssh-5.0p1.orig/ssh-add.c 2008-02-28 00:13:52.000000000
> -0800
> ++++ ./ssh-add.c 2008-04-15 18:32:47.000000000 -0700
> +@@ -62,6 +62,7 @@
> + #include "authfile.h"
> + #include "pathnames.h"
> + #include "misc.h"
> ++#include "keychain.h"
> +
> + /* argv0 */
> + extern char *__progname;
> +@@ -93,12 +94,24 @@
> + }
> +
> + static int
> +-delete_file(AuthenticationConnection *ac, const char *filename)
> ++add_from_keychain(AuthenticationConnection *ac)
> ++{
> ++ if (ssh_add_from_keychain(ac) == 0)
> ++ return -1;
> ++
> ++ fprintf(stderr, "Added keychain identities.\n");
> ++ return 0;
> ++}
> ++
> ++static int
> ++delete_file(AuthenticationConnection *ac, int keychain, const char
> *filename)
> + {
> + Key *public;
> + char *comment = NULL;
> + int ret = -1;
> +
> ++ if (keychain)
> ++ remove_from_keychain(filename);
> + public = key_load_public(filename, &comment);
> + if (public == NULL) {
> + printf("Bad key file %s\n", filename);
> +@@ -136,7 +149,7 @@
> + }
> +
> + static int
> +-add_file(AuthenticationConnection *ac, const char *filename)
> ++add_file(AuthenticationConnection *ac, int keychain, const char
> *filename)
> + {
> + Key *private;
> + char *comment = NULL;
> +@@ -159,11 +172,16 @@
> +
> + /* At first, try empty passphrase */
> + private = key_load_private(filename, "", &comment);
> ++ if (keychain && private != NULL)
> ++ store_in_keychain(filename, "");
> + if (comment == NULL)
> + comment = xstrdup(filename);
> + /* try last */
> +- if (private == NULL && pass != NULL)
> ++ if (private == NULL && pass != NULL) {
> + private = key_load_private(filename, pass, NULL);
> ++ if (keychain && private != NULL)
> ++ store_in_keychain(filename, pass);
> ++ }
> + if (private == NULL) {
> + /* clear passphrase since it did not work */
> + clear_pass();
> +@@ -177,8 +195,11 @@
> + return -1;
> + }
> + private = key_load_private(filename, pass, &comment);
> +- if (private != NULL)
> ++ if (private != NULL) {
> ++ if (keychain)
> ++ store_in_keychain(filename, pass);
> + break;
> ++ }
> + clear_pass();
> + snprintf(msg, sizeof msg,
> + "Bad passphrase, try again for %.200s: ", comment);
> +@@ -295,13 +316,13 @@
> + }
> +
> + static int
> +-do_file(AuthenticationConnection *ac, int deleting, char *file)
> ++do_file(AuthenticationConnection *ac, int deleting, int keychain,
> char *file)
> + {
> + if (deleting) {
> +- if (delete_file(ac, file) == -1)
> ++ if (delete_file(ac, keychain, file) == -1)
> + return -1;
> + } else {
> +- if (add_file(ac, file) == -1)
> ++ if (add_file(ac, keychain, file) == -1)
> + return -1;
> + }
> + return 0;
> +@@ -324,6 +345,11 @@
> + fprintf(stderr, " -s reader Add key in smartcard reader.\n");
> + fprintf(stderr, " -e reader Remove key in smartcard reader.\n");
> + #endif
> ++#ifdef KEYCHAIN
> ++ fprintf(stderr, " -k Add all identities stored in your
> keychain.\n");
> ++ fprintf(stderr, " -K Store passphrases in your keychain.
> \n");
> ++ fprintf(stderr, " With -d, remove passphrases from
> your keychain.\n");
> ++#endif
> + }
> +
> + int
> +@@ -334,6 +360,7 @@
> + AuthenticationConnection *ac = NULL;
> + char *sc_reader_id = NULL;
> + int i, ch, deleting = 0, ret = 0;
> ++ int keychain = 0;
> +
> + /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
> + sanitise_stdfd();
> +@@ -351,7 +378,7 @@
> + "Could not open a connection to your authentication agent.
> \n");
> + exit(2);
> + }
> +- while ((ch = getopt(argc, argv, "lLcdDxXe:s:t:")) != -1) {
> ++ while ((ch = getopt(argc, argv, "lLcdDxXe:s:kKt:")) != -1) {
> + switch (ch) {
> + case 'l':
> + case 'L':
> +@@ -373,6 +400,13 @@
> + if (delete_all(ac) == -1)
> + ret = 1;
> + goto done;
> ++ case 'k':
> ++ if (add_from_keychain(ac) == -1)
> ++ ret = 1;
> ++ goto done;
> ++ case 'K':
> ++ keychain = 1;
> ++ break;
> + case 's':
> + sc_reader_id = optarg;
> + break;
> +@@ -418,7 +452,7 @@
> + default_files[i]);
> + if (stat(buf, &st) < 0)
> + continue;
> +- if (do_file(ac, deleting, buf) == -1)
> ++ if (do_file(ac, deleting, keychain, buf) == -1)
> + ret = 1;
> + else
> + count++;
> +@@ -427,7 +461,7 @@
> + ret = 1;
> + } else {
> + for (i = 0; i < argc; i++) {
> +- if (do_file(ac, deleting, argv[i]) == -1)
> ++ if (do_file(ac, deleting, keychain, argv[i]) == -1)
> + ret = 1;
> + }
> + }
> +diff -uNr ../openssh-5.0p1.orig/ssh-agent.c ./ssh-agent.c
> +--- ../openssh-5.0p1.orig/ssh-agent.c 2008-02-28 00:13:52.000000000
> -0800
> ++++ ./ssh-agent.c 2008-04-15 18:32:47.000000000 -0700
> +@@ -72,9 +72,11 @@
> + #include "buffer.h"
> + #include "key.h"
> + #include "authfd.h"
> ++#include "authfile.h"
> + #include "compat.h"
> + #include "log.h"
> + #include "misc.h"
> ++#include "keychain.h"
> +
> + #ifdef SMARTCARD
> + #include "scard.h"
> +@@ -703,6 +705,61 @@
> + }
> + #endif /* SMARTCARD */
> +
> ++static int
> ++add_identity_callback(const char *filename, const char *passphrase)
> ++{
> ++ Key *k;
> ++ int version;
> ++ Idtab *tab;
> ++
> ++ if ((k = key_load_private(filename, passphrase, NULL)) == NULL)
> ++ return 1;
> ++ switch (k->type) {
> ++ case KEY_RSA:
> ++ case KEY_RSA1:
> ++ if (RSA_blinding_on(k->rsa, NULL) != 1) {
> ++ key_free(k);
> ++ return 1;
> ++ }
> ++ break;
> ++ }
> ++ version = k->type == KEY_RSA1 ? 1 : 2;
> ++ tab = idtab_lookup(version);
> ++ if (lookup_identity(k, version) == NULL) {
> ++ Identity *id = xmalloc(sizeof(Identity));
> ++ id->key = k;
> ++ id->comment = xstrdup(filename);
> ++ if (id->comment == NULL) {
> ++ key_free(k);
> ++ return 1;
> ++ }
> ++ id->death = 0;
> ++ id->confirm = 0;
> ++ TAILQ_INSERT_TAIL(&tab->idlist, id, next);
> ++ tab->nentries++;
> ++ } else {
> ++ key_free(k);
> ++ return 1;
> ++ }
> ++
> ++ return 0;
> ++}
> ++
> ++static void
> ++process_add_from_keychain(SocketEntry *e)
> ++{
> ++ int result;
> ++
> ++ result = add_identities_using_keychain(&add_identity_callback);
> ++
> ++ /* e will be NULL when ssh-agent adds keys on its own at startup */
> ++ if (e) {
> ++ buffer_put_int(&e->output, 1);
> ++ buffer_put_char(&e->output,
> ++ result ? SSH_AGENT_FAILURE : SSH_AGENT_SUCCESS);
> ++ }
> ++}
> ++
> + /* dispatch incoming messages */
> +
> + static void
> +@@ -795,6 +852,9 @@
> + process_remove_smartcard_key(e);
> + break;
> + #endif /* SMARTCARD */
> ++ case SSH_AGENTC_ADD_FROM_KEYCHAIN:
> ++ process_add_from_keychain(e);
> ++ break;
> + default:
> + /* Unknown message. Respond with failure. */
> + error("Unknown message %d", type);
> +@@ -1258,6 +1318,10 @@
> + signal(SIGTERM, cleanup_handler);
> + nalloc = 0;
> +
> ++#ifdef KEYCHAIN
> ++ process_add_from_keychain(NULL);
> ++#endif
> ++
> + while (1) {
> + prepare_select(&readsetp, &writesetp, &max_fd, &nalloc, &tvp);
> + result = select(max_fd + 1, readsetp, writesetp, NULL, tvp);
> +diff -uNr ../openssh-5.0p1.orig/sshconnect1.c ./sshconnect1.c
> +--- ../openssh-5.0p1.orig/sshconnect1.c 2006-11-07
> 04:14:42.000000000 -0800
> ++++ ./sshconnect1.c 2008-04-15 18:32:47.000000000 -0700
> +@@ -47,6 +47,7 @@
> + #include "canohost.h"
> + #include "hostfile.h"
> + #include "auth.h"
> ++#include "keychain.h"
> +
> + /* Session id for the current session. */
> + u_char session_id[16];
> +@@ -260,7 +261,9 @@
> + snprintf(buf, sizeof(buf),
> + "Enter passphrase for RSA key '%.100s': ", comment);
> + for (i = 0; i < options.number_of_password_prompts; i++) {
> +- passphrase = read_passphrase(buf, 0);
> ++ passphrase = keychain_read_passphrase(comment);
> ++ if (passphrase == NULL)
> ++ passphrase = read_passphrase(buf, 0);
> + if (strcmp(passphrase, "") != 0) {
> + private = key_load_private_type(KEY_RSA1,
> + authfile, passphrase, NULL, NULL);
> +diff -uNr ../openssh-5.0p1.orig/sshconnect2.c ./sshconnect2.c
> +--- ../openssh-5.0p1.orig/sshconnect2.c 2008-02-10
> 03:25:53.000000000 -0800
> ++++ ./sshconnect2.c 2008-04-15 18:32:47.000000000 -0700
> +@@ -64,6 +64,7 @@
> + #include "msg.h"
> + #include "pathnames.h"
> + #include "uidswap.h"
> ++#include "keychain.h"
> +
> + #ifdef GSSAPI
> + #include "ssh-gss.h"
> +@@ -990,7 +991,9 @@
> + snprintf(prompt, sizeof prompt,
> + "Enter passphrase for key '%.100s': ", filename);
> + for (i = 0; i < options.number_of_password_prompts; i++) {
> +- passphrase = read_passphrase(prompt, 0);
> ++ passphrase = keychain_read_passphrase(filename);
> ++ if (passphrase == NULL)
> ++ passphrase = read_passphrase(prompt, 0);
> + if (strcmp(passphrase, "") != 0) {
> + private = key_load_private_type(KEY_UNSPEC,
> + filename, passphrase, NULL, NULL);
> Added: trunk/dports/net/openssh/files/AJ-5491854-
> fix_unsafe_usage_of_getpwuid.patch (0 => 38526)
> --- trunk/dports/net/openssh/files/AJ-5491854-
> fix_unsafe_usage_of_getpwuid.patch (rev 0)
> +++ trunk/dports/net/openssh/files/AJ-5491854-
> fix_unsafe_usage_of_getpwuid.patch 2008-07-24 04:33:03 UTC (rev 38526)
> @@ -0,0 +1,32 @@
> +diff -ru ../openssh-4.5p1.old/ssh-add.c ./ssh-add.c
> +--- ../openssh-4.5p1.old/ssh-add.c 2006-08-31 22:38:37.000000000
> -0700
> ++++ ./ssh-add.c 2007-09-21 13:11:56.000000000 -0700
> +@@ -402,6 +402,7 @@
> + if (argc == 0) {
> + char buf[MAXPATHLEN];
> + struct passwd *pw;
> ++ char *pw_dir;
> + struct stat st;
> + int count = 0;
> +
> +@@ -412,8 +413,10 @@
> + goto done;
> + }
> +
> ++ pw_dir = xstrdup(pw->pw_dir);
> ++
> + for (i = 0; default_files[i]; i++) {
> +- snprintf(buf, sizeof(buf), "%s/%s", pw->pw_dir,
> ++ snprintf(buf, sizeof(buf), "%s/%s", pw_dir,
> + default_files[i]);
> + if (stat(buf, &st) < 0)
> + continue;
> +@@ -424,6 +427,8 @@
> + }
> + if (count == 0)
> + ret = 1;
> ++
> ++ xfree(pw_dir);
> + } else {
> + for (i = 0; i < argc; i++) {
> + if (do_file(ac, deleting, argv[i]) == -1)
> Added: trunk/dports/net/openssh/files/
> DVG-3977221_manpage_tweaks.patch (0 => 38526)
> --- trunk/dports/net/openssh/files/
> DVG-3977221_manpage_tweaks.patch (rev 0)
> +++ trunk/dports/net/openssh/files/DVG-3977221_manpage_tweaks.patch
> 2008-07-24 04:33:03 UTC (rev 38526)
> @@ -0,0 +1,54 @@
> +diff -uNr ../openssh-4.7p1.orig/sshd.0 ./sshd.0
> +--- ../openssh-4.7p1.orig/sshd.0 2007-09-03 23:50:10.000000000 -0700
> ++++ ./sshd.0 2007-09-05 20:44:16.000000000 -0700
> +@@ -527,8 +527,8 @@
> +
> + SEE ALSO
> + scp(1), sftp(1), ssh(1), ssh-add(1), ssh-agent(1), ssh-
> keygen(1),
> +- ssh-keyscan(1), chroot(2), hosts_access(5), login.conf(5),
> moduli(5),
> +- sshd_config(5), inetd(8), sftp-server(8)
> ++ ssh-keyscan(1), chroot(2), hosts_access(5), sshd_config(5)
> ++ sftp-server(8)
> +
> + AUTHORS
> + OpenSSH is a derivative of the original and free ssh 1.2.12
> release by
> +diff -uNr ../openssh-4.7p1.orig/sshd.8 ./sshd.8
> +--- ../openssh-4.7p1.orig/sshd.8 2007-08-16 16:42:33.000000000 -0700
> ++++ ./sshd.8 2007-09-05 20:43:10.000000000 -0700
> +@@ -833,10 +833,7 @@
> + .Xr ssh-keyscan 1 ,
> + .Xr chroot 2 ,
> + .Xr hosts_access 5 ,
> +-.Xr login.conf 5 ,
> +-.Xr moduli 5 ,
> + .Xr sshd_config 5 ,
> +-.Xr inetd 8 ,
> + .Xr sftp-server 8
> + .Sh AUTHORS
> + OpenSSH is a derivative of the original and free
> +diff -uNr ../openssh-4.7p1.orig/sshd_config.0 ./sshd_config.0
> +--- ../openssh-4.7p1.orig/sshd_config.0 2007-09-03
> 23:50:11.000000000 -0700
> ++++ ./sshd_config.0 2007-09-05 20:44:58.000000000 -0700
> +@@ -84,8 +84,7 @@
> +
> + ChallengeResponseAuthentication
> + Specifies whether challenge-response authentication
> is allowed.
> +- All authentication styles from login.conf(5) are
> supported. The
> +- default is ``yes''.
> ++ The default is ``yes''.
> +
> + Ciphers
> + Specifies the ciphers allowed for protocol version
> 2. Multiple
> +diff -uNr ../openssh-4.7p1.orig/sshd_config.5 ./sshd_config.5
> +--- ../openssh-4.7p1.orig/sshd_config.5 2007-06-10
> 21:07:13.000000000 -0700
> ++++ ./sshd_config.5 2007-09-05 20:45:25.000000000 -0700
> +@@ -167,9 +167,6 @@
> + By default, no banner is displayed.
> + .It Cm ChallengeResponseAuthentication
> + Specifies whether challenge-response authentication is allowed.
> +-All authentication styles from
> +-.Xr login.conf 5
> +-are supported.
> + The default is
> + .Dq yes .
> + .It Cm Ciphers
> Added: trunk/dports/net/openssh/files/
> DVG-4122722+5277818_new_EA.patch (0 => 38526)
> --- trunk/dports/net/openssh/files/
> DVG-4122722+5277818_new_EA.patch (rev 0)
> +++ trunk/dports/net/openssh/files/DVG-4122722+5277818_new_EA.patch
> 2008-07-24 04:33:03 UTC (rev 38526)
> @@ -0,0 +1,537 @@
> +diff -ruN ../openssh-4.7p1/config.h.in ./config.h.in
> +--- ../openssh-4.7p1/config.h.in 2007-09-03 23:50:04.000000000 -0700
> ++++ ./config.h.in 2007-10-01 20:02:51.000000000 -0700
> +@@ -56,6 +56,18 @@
> + /* Define if your snprintf is busted */
> + #undef BROKEN_SNPRINTF
> +
> ++/* platform uses an in-memory credentials cache */
> ++#undef USE_CCAPI
> ++
> ++/* platform has a Security Authorization Session API */
> ++#undef USE_SECURITY_SESSION_API
> ++
> ++/* Define to 1 if you have the `copyfile' function. */
> ++#undef HAVE_COPYFILE
> ++
> ++/* Define to 1 if you have the <copyfile.h> header file. */
> ++#undef HAVE_COPYFILE_H
> ++
> + /* updwtmpx is broken (if present) */
> + #undef BROKEN_UPDWTMPX
> +
> +diff -ruN ../openssh-4.7p1/configure ./configure
> +--- ../openssh-4.7p1/configure 2007-09-03 23:50:09.000000000 -0700
> ++++ ./configure 2007-10-01 20:02:51.000000000 -0700
> +@@ -28390,6 +28390,259 @@
> + CFLAGS="$CFLAGS $werror_flags"
> +
> +
> ++for ac_func in copyfile
> ++do
> ++as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
> ++echo "$as_me:$LINENO: checking for $ac_func" >&5
> ++echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
> ++if eval "test \"\${$as_ac_var+set}\" = set"; then
> ++ echo $ECHO_N "(cached) $ECHO_C" >&6
> ++else
> ++ cat >conftest.$ac_ext <<_ACEOF
> ++/* confdefs.h. */
> ++_ACEOF
> ++cat confdefs.h >>conftest.$ac_ext
> ++cat >>conftest.$ac_ext <<_ACEOF
> ++/* end confdefs.h. */
> ++/* Define $ac_func to an innocuous variant, in case <limits.h>
> declares $ac_func.
> ++ For example, HP-UX 11i <limits.h> declares gettimeofday. */
> ++#define $ac_func innocuous_$ac_func
> ++
> ++/* System header to define __stub macros and hopefully few
> prototypes,
> ++ which can conflict with char $ac_func (); below.
> ++ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
> ++ <limits.h> exists even on freestanding compilers. */
> ++
> ++#ifdef __STDC__
> ++# include <limits.h>
> ++#else
> ++# include <assert.h>
> ++#endif
> ++
> ++#undef $ac_func
> ++
> ++/* Override any gcc2 internal prototype to avoid an error. */
> ++#ifdef __cplusplus
> ++extern "C"
> ++{
> ++#endif
> ++/* We use char because int might match the return type of a gcc2
> ++ builtin and then its argument prototype would still apply. */
> ++char $ac_func ();
> ++/* The GNU C library defines this for functions which it implements
> ++ to always fail with ENOSYS. Some functions are actually named
> ++ something starting with __ and the normal name is an alias. */
> ++#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
> ++choke me
> ++#else
> ++char (*f) () = $ac_func;
> ++#endif
> ++#ifdef __cplusplus
> ++}
> ++#endif
> ++
> ++int
> ++main ()
> ++{
> ++return f != $ac_func;
> ++ ;
> ++ return 0;
> ++}
> ++_ACEOF
> ++rm -f conftest.$ac_objext conftest$ac_exeext
> ++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
> ++ (eval $ac_link) 2>conftest.er1
> ++ ac_status=$?
> ++ grep -v '^ *+' conftest.er1 >conftest.err
> ++ rm -f conftest.er1
> ++ cat conftest.err >&5
> ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
> ++ (exit $ac_status); } &&
> ++ { ac_try='test -z "$ac_c_werror_flag"
> ++ || test ! -s conftest.err'
> ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
> ++ (eval $ac_try) 2>&5
> ++ ac_status=$?
> ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
> ++ (exit $ac_status); }; } &&
> ++ { ac_try='test -s conftest$ac_exeext'
> ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
> ++ (eval $ac_try) 2>&5
> ++ ac_status=$?
> ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
> ++ (exit $ac_status); }; }; then
> ++ eval "$as_ac_var=yes"
> ++else
> ++ echo "$as_me: failed program was:" >&5
> ++sed 's/^/| /' conftest.$ac_ext >&5
> ++
> ++eval "$as_ac_var=no"
> ++fi
> ++rm -f conftest.err conftest.$ac_objext \
> ++ conftest$ac_exeext conftest.$ac_ext
> ++fi
> ++echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
> ++echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
> ++if test `eval echo '${'$as_ac_var'}'` = yes; then
> ++ cat >>confdefs.h <<_ACEOF
> ++#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
> ++_ACEOF
> ++
> ++fi
> ++done
> ++
> ++
> ++for ac_header in copyfile.h
> ++do
> ++as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
> ++if eval "test \"\${$as_ac_Header+set}\" = set"; then
> ++ echo "$as_me:$LINENO: checking for $ac_header" >&5
> ++echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
> ++if eval "test \"\${$as_ac_Header+set}\" = set"; then
> ++ echo $ECHO_N "(cached) $ECHO_C" >&6
> ++fi
> ++echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
> ++echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
> ++else
> ++ # Is the header compilable?
> ++echo "$as_me:$LINENO: checking $ac_header usability" >&5
> ++echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
> ++cat >conftest.$ac_ext <<_ACEOF
> ++/* confdefs.h. */
> ++_ACEOF
> ++cat confdefs.h >>conftest.$ac_ext
> ++cat >>conftest.$ac_ext <<_ACEOF
> ++/* end confdefs.h. */
> ++$ac_includes_default
> ++#include <$ac_header>
> ++_ACEOF
> ++rm -f conftest.$ac_objext
> ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
> ++ (eval $ac_compile) 2>conftest.er1
> ++ ac_status=$?
> ++ grep -v '^ *+' conftest.er1 >conftest.err
> ++ rm -f conftest.er1
> ++ cat conftest.err >&5
> ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
> ++ (exit $ac_status); } &&
> ++ { ac_try='test -z "$ac_c_werror_flag"
> ++ || test ! -s conftest.err'
> ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
> ++ (eval $ac_try) 2>&5
> ++ ac_status=$?
> ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
> ++ (exit $ac_status); }; } &&
> ++ { ac_try='test -s conftest.$ac_objext'
> ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
> ++ (eval $ac_try) 2>&5
> ++ ac_status=$?
> ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
> ++ (exit $ac_status); }; }; then
> ++ ac_header_compiler=yes
> ++else
> ++ echo "$as_me: failed program was:" >&5
> ++sed 's/^/| /' conftest.$ac_ext >&5
> ++
> ++ac_header_compiler=no
> ++fi
> ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
> ++echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
> ++echo "${ECHO_T}$ac_header_compiler" >&6
> ++
> ++# Is the header present?
> ++echo "$as_me:$LINENO: checking $ac_header presence" >&5
> ++echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
> ++cat >conftest.$ac_ext <<_ACEOF
> ++/* confdefs.h. */
> ++_ACEOF
> ++cat confdefs.h >>conftest.$ac_ext
> ++cat >>conftest.$ac_ext <<_ACEOF
> ++/* end confdefs.h. */
> ++#include <$ac_header>
> ++_ACEOF
> ++if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
> ++ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
> ++ ac_status=$?
> ++ grep -v '^ *+' conftest.er1 >conftest.err
> ++ rm -f conftest.er1
> ++ cat conftest.err >&5
> ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
> ++ (exit $ac_status); } >/dev/null; then
> ++ if test -s conftest.err; then
> ++ ac_cpp_err=$ac_c_preproc_warn_flag
> ++ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
> ++ else
> ++ ac_cpp_err=
> ++ fi
> ++else
> ++ ac_cpp_err=yes
> ++fi
> ++if test -z "$ac_cpp_err"; then
> ++ ac_header_preproc=yes
> ++else
> ++ echo "$as_me: failed program was:" >&5
> ++sed 's/^/| /' conftest.$ac_ext >&5
> ++
> ++ ac_header_preproc=no
> ++fi
> ++rm -f conftest.err conftest.$ac_ext
> ++echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
> ++echo "${ECHO_T}$ac_header_preproc" >&6
> ++
> ++# So? What about this header?
> ++case $ac_header_compiler:$ac_header_preproc:
> $ac_c_preproc_warn_flag in
> ++ yes:no: )
> ++ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the
> compiler, rejected by the preprocessor!" >&5
> ++echo "$as_me: WARNING: $ac_header: accepted by the compiler,
> rejected by the preprocessor!" >&2;}
> ++ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with
> the compiler's result" >&5
> ++echo "$as_me: WARNING: $ac_header: proceeding with the compiler's
> result" >&2;}
> ++ ac_header_preproc=yes
> ++ ;;
> ++ no:yes:* )
> ++ { echo "$as_me:$LINENO: WARNING: $ac_header: present but
> cannot be compiled" >&5
> ++echo "$as_me: WARNING: $ac_header: present but cannot be compiled"
> >&2;}
> ++ { echo "$as_me:$LINENO: WARNING: $ac_header: check for
> missing prerequisite headers?" >&5
> ++echo "$as_me: WARNING: $ac_header: check for missing
> prerequisite headers?" >&2;}
> ++ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf
> documentation" >&5
> ++echo "$as_me: WARNING: $ac_header: see the Autoconf documentation"
> >&2;}
> ++ { echo "$as_me:$LINENO: WARNING: $ac_header: section
> \"Present But Cannot Be Compiled\"" >&5
> ++echo "$as_me: WARNING: $ac_header: section \"Present But
> Cannot Be Compiled\"" >&2;}
> ++ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with
> the preprocessor's result" >&5
> ++echo "$as_me: WARNING: $ac_header: proceeding with the
> preprocessor's result" >&2;}
> ++ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future,
> the compiler will take precedence" >&5
> ++echo "$as_me: WARNING: $ac_header: in the future, the compiler
> will take precedence" >&2;}
> ++ (
> ++ cat <<\_ASBOX
> ++## ------------------------------------------- ##
> ++## Report this to openssh-unix-dev at mindrot.org ##
> ++## ------------------------------------------- ##
> ++_ASBOX
> ++ ) |
> ++ sed "s/^/$as_me: WARNING: /" >&2
> ++ ;;
> ++esac
> ++echo "$as_me:$LINENO: checking for $ac_header" >&5
> ++echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
> ++if eval "test \"\${$as_ac_Header+set}\" = set"; then
> ++ echo $ECHO_N "(cached) $ECHO_C" >&6
> ++else
> ++ eval "$as_ac_Header=\$ac_header_preproc"
> ++fi
> ++echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
> ++echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
> ++
> ++fi
> ++if test `eval echo '${'$as_ac_Header'}'` = yes; then
> ++ cat >>confdefs.h <<_ACEOF
> ++#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
> ++_ACEOF
> ++
> ++fi
> ++
> ++done
> ++
> ++
> ++
> + ac_config_files="$ac_config_files Makefile buildpkg.sh
> opensshd.init openssh.xml openbsd-compat/Makefile openbsd-compat/
> regress/Makefile scard/Makefile ssh_prng_cmds survey.sh"
> +
> + cat >confcache <<\_ACEOF
> +diff -ruN ../openssh-4.7p1/configure.ac ./configure.ac
> +--- ../openssh-4.7p1/configure.ac 2007-08-09 21:36:12.000000000 -0700
> ++++ ./configure.ac 2007-10-01 20:02:51.000000000 -0700
> +@@ -3982,6 +3982,9 @@
> + dnl Add now.
> + CFLAGS="$CFLAGS $werror_flags"
> +
> ++AC_CHECK_FUNCS(copyfile)
> ++AC_CHECK_HEADERS(copyfile.h)
> ++
> + AC_EXEEXT
> + AC_CONFIG_FILES([Makefile buildpkg.sh opensshd.init openssh.xml \
> + openbsd-compat/Makefile openbsd-compat/regress/Makefile \
> +diff -ruN ../openssh-4.7p1/scp.1 ./scp.1
> +--- ../openssh-4.7p1/scp.1 2007-08-07 21:29:58.000000000 -0700
> ++++ ./scp.1 2007-10-01 20:02:51.000000000 -0700
> +@@ -20,7 +20,7 @@
> + .Sh SYNOPSIS
> + .Nm scp
> + .Bk -words
> +-.Op Fl 1246BCpqrv
> ++.Op Fl 1246BCEpqrv
> + .Op Fl c Ar cipher
> + .Op Fl F Ar ssh_config
> + .Op Fl i Ar identity_file
> +@@ -87,6 +87,8 @@
> + flag to
> + .Xr ssh 1
> + to enable compression.
> ++.It Fl E
> ++Preserves extended attributes, resource forks, and ACLs. Requires
> both ends to be running Mac OS X 10.4 or later.
> + .It Fl c Ar cipher
> + Selects the cipher to use for encrypting the data transfer.
> + This option is directly passed to
> +diff -ruN ../openssh-4.7p1/scp.c ./scp.c
> +--- ../openssh-4.7p1/scp.c 2007-08-07 21:29:58.000000000 -0700
> ++++ ./scp.c 2007-10-01 20:29:54.000000000 -0700
> +@@ -107,6 +107,11 @@
> + #include "misc.h"
> + #include "progressmeter.h"
> +
> ++#ifdef HAVE_COPYFILE_H
> ++#include <libgen.h>
> ++#include <copyfile.h>
> ++#endif
> ++
> + extern char *__progname;
> +
> + int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int
> *fdout);
> +@@ -134,6 +139,12 @@
> + /* This is used to store the pid of ssh_program */
> + pid_t do_cmd_pid = -1;
> +
> ++#ifdef HAVE_COPYFILE
> ++int copy_xattr = 0;
> ++int md_flag = 0;
> ++#endif
> ++
> ++
> + static void
> + killchild(int signo)
> + {
> +@@ -313,7 +324,11 @@
> + addargs(&args, "-oClearAllForwardings yes");
> +
> + fflag = tflag = 0;
> ++#if HAVE_COPYFILE
> ++ while ((ch = getopt(argc, argv, "dfl:prtvBCEc:i:P:q1246S:o:F:")) !
> = -1)
> ++#else
> + while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246S:o:F:")) !
> = -1)
> ++#endif
> + switch (ch) {
> + /* User-visible flags. */
> + case '1':
> +@@ -359,6 +374,11 @@
> + showprogress = 0;
> + break;
> +
> ++#ifdef HAVE_COPYFILE
> ++ case 'E':
> ++ copy_xattr = 1;
> ++ break;
> ++#endif
> + /* Server options. */
> + case 'd':
> + targetshouldbedirectory = 1;
> +@@ -408,7 +428,12 @@
> + remin = remout = -1;
> + do_cmd_pid = -1;
> + /* Command to be executed on remote system using "ssh". */
> ++#if HAVE_COPYFILE
> ++ (void) snprintf(cmd, sizeof cmd, "scp%s%s%s%s%s",
> ++ copy_xattr ? " -E" : "",
> ++#else
> + (void) snprintf(cmd, sizeof cmd, "scp%s%s%s%s",
> ++#endif
> + verbose_mode ? " -v" : "",
> + iamrecursive ? " -r" : "", pflag ? " -p" : "",
> + targetshouldbedirectory ? " -d" : "");
> +@@ -587,6 +612,10 @@
> + int fd = -1, haderr, indx;
> + char *last, *name, buf[2048], encname[MAXPATHLEN];
> + int len;
> ++#if HAVE_COPYFILE
> ++ char md_name[MAXPATHLEN];
> ++ char *md_tmp;
> ++#endif
> +
> + for (indx = 0; indx < argc; ++indx) {
> + name = argv[indx];
> +@@ -594,12 +623,26 @@
> + len = strlen(name);
> + while (len > 1 && name[len-1] == '/')
> + name[--len] = '\0';
> ++#if HAVE_COPYFILE
> ++md_next:
> ++ statbytes = 0;
> ++ if (md_flag) {
> ++ fd = open(md_tmp, O_RDONLY, 0);
> ++ unlink(md_tmp);
> ++ free(md_tmp);
> ++ if (fd < 0)
> ++ goto syserr;
> ++ } else {
> ++#endif
> + if ((fd = open(name, O_RDONLY|O_NONBLOCK, 0)) < 0)
> + goto syserr;
> + if (strchr(name, '\n') != NULL) {
> + strnvis(encname, name, sizeof(encname), VIS_NL);
> + name = encname;
> + }
> ++#if HAVE_COPYFILE
> ++ }
> ++#endif
> + if (fstat(fd, &stb) < 0) {
> + syserr: run_err("%s: %s", name, strerror(errno));
> + goto next;
> +@@ -688,6 +731,36 @@
> + else
> + run_err("%s: %s", name, strerror(haderr));
> + (void) response();
> ++#ifdef HAVE_COPYFILE
> ++ if (copy_xattr && md_flag == 0)
> ++ {
> ++ if (!copyfile(name, NULL, 0,
> ++ COPYFILE_ACL | COPYFILE_XATTR | COPYFILE_CHECK))
> ++ continue;
> ++
> ++ /*
> ++ * this file will hold the actual metadata
> ++ * to be transferred
> ++ */
> ++ md_tmp = strdup("/tmp/scp.md.XXXXXX");
> ++ md_tmp = mktemp(md_tmp);
> ++
> ++ if(copyfile(name, md_tmp, 0,
> ++ COPYFILE_ACL | COPYFILE_XATTR | COPYFILE_PACK) == 0)
> ++ {
> ++ /*
> ++ * this is the fake name to display
> ++ */
> ++ snprintf(md_name, sizeof md_name, "%s/._%s", dirname(name),
> basename(name));
> ++ name = md_name;
> ++ md_flag = 1;
> ++ if (verbose_mode)
> ++ fprintf(stderr, "copyfile(%s, %s, PACK)\n", name, md_tmp);
> ++ goto md_next;
> ++ }
> ++ } else
> ++ md_flag = 0;
> ++#endif
> + }
> + }
> +
> +@@ -836,6 +909,10 @@
> + if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode))
> + targisdir = 1;
> + for (first = 1;; first = 0) {
> ++#if HAVE_COPYFILE
> ++ char md_src[MAXPATHLEN];
> ++ char md_dst[MAXPATHLEN];
> ++#endif
> + cp = buf;
> + if (atomicio(read, remin, cp, 1) != 1)
> + return;
> +@@ -969,6 +1046,32 @@
> + }
> + omode = mode;
> + mode |= S_IWRITE;
> ++
> ++#if HAVE_COPYFILE
> ++ if (copy_xattr && !strncmp(basename(curfile), "._", 2))
> ++ {
> ++ int mdfd;
> ++ if (targisdir)
> ++ {
> ++ snprintf(md_src, sizeof md_src, "%s.XXXXXX", np);
> ++ snprintf(md_dst, sizeof md_dst, "%s/%s",
> ++ dirname(np), basename(np) + 2);
> ++ if((mdfd = mkstemp(md_src)) < 0)
> ++ continue;
> ++ }
> ++ else
> ++ {
> ++ snprintf(md_src, sizeof md_src, "%s/._%s.XXXXXX",
> ++ dirname(np), basename(np));
> ++ snprintf(md_dst, sizeof md_dst, "%s", np);
> ++ if((mdfd = mkstemp(md_src)) < 0)
> ++ continue;
> ++ }
> ++ if (mdfd >= 0)
> ++ close(mdfd);
> ++ np = md_src;
> ++ }
> ++#endif
> + if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) < 0) {
> + bad: run_err("%s: %s", np, strerror(errno));
> + continue;
> +@@ -1057,6 +1160,21 @@
> + wrerrno = errno;
> + }
> + (void) response();
> ++#ifdef HAVE_COPYFILE
> ++ if (copy_xattr && strncmp(basename(np), "._", 2) == 0)
> ++ {
> ++ if (verbose_mode)
> ++ fprintf(stderr, "copyfile(%s, %s, UNPACK)\n", md_src,
> md_dst);
> ++ if(!copyfile(md_src, md_dst, 0,
> ++ COPYFILE_ACL | COPYFILE_XATTR | COPYFILE_UNPACK) < 0)
> ++ {
> ++ snprintf(md_dst, sizeof md_dst, "%s/._%s",
> ++ dirname(md_dst), basename(md_dst));
> ++ rename(md_src, md_dst);
> ++ } else
> ++ unlink(md_src);
> ++ } else
> ++#endif
> + if (setimes && wrerr == NO) {
> + setimes = 0;
> + if (utimes(np, tv) < 0) {
> +@@ -1118,7 +1236,11 @@
> + usage(void)
> + {
> + (void) fprintf(stderr,
> ++#if HAVE_COPYFILE
> ++ "usage: scp [-1246BCEpqrv] [-c cipher] [-F ssh_config] [-i
> identity_file]\n"
> ++#else
> + "usage: scp [-1246BCpqrv] [-c cipher] [-F ssh_config] [-i
> identity_file]\n"
> ++#endif
> + " [-l limit] [-o ssh_option] [-P port] [-S program]
> \n"
> + " [[user@]host1:]file1 ... [[user@]host2:]file2\n");
> + exit(1);
> Added: trunk/dports/net/openssh/files/
> DVG-4135812_add_SACLSupport_to_sshd_conf_manpage.patch (0 => 38526)
> --- trunk/dports/net/openssh/files/
> DVG
> -4135812_add_SACLSupport_to_sshd_conf_manpage
> .patch (rev 0)
> +++ trunk/dports/net/openssh/files/
> DVG-4135812_add_SACLSupport_to_sshd_conf_manpage.patch 2008-07-24
> 04:33:03 UTC (rev 38526)
> @@ -0,0 +1,25 @@
> +diff -uNr ../openssh-4.7p1.orig/sshd_config.0 ./sshd_config.0
> +--- ../openssh-4.7p1.orig/sshd_config.0 2007-09-03
> 23:50:11.000000000 -0700
> ++++ ./sshd_config.0 2008-01-31 17:32:40.000000000 -0800
> +@@ -414,6 +414,9 @@
> + fault is ``yes''. This option applies to protocol
> version 1 on-
> + ly.
> +
> ++ SACLSupport
> ++ Enables use of Service ACLs on Mac OS X.
> ++
> + ServerKeyBits
> + Defines the number of bits in the ephemeral protocol
> version 1
> + server key. The minimum value is 512, and the
> default is 768.
> +diff -uNr ../openssh-4.7p1.orig/sshd_config.5 ./sshd_config.5
> +--- ../openssh-4.7p1.orig/sshd_config.5 2007-06-10
> 21:07:13.000000000 -0700
> ++++ ./sshd_config.5 2008-01-31 17:33:17.000000000 -0800
> +@@ -722,6 +722,8 @@
> + The default is
> + .Dq yes .
> + This option applies to protocol version 1 only.
> ++.It Cm SACLSupport
> ++Enables use of Service ACLs on Mac OS X.
> + .It Cm ServerKeyBits
> + Defines the number of bits in the ephemeral protocol version 1
> server key.
> + The minimum value is 512, and the default is 768.
> Added: trunk/dports/net/openssh/files/
> DVG-4157448+4920695_corrected_UsePAM_comment.patch (0 => 38526)
> --- trunk/dports/net/openssh/files/
> DVG
> -4157448
> +4920695_corrected_UsePAM_comment.patch (rev
> 0)
> +++ trunk/dports/net/openssh/files/
> DVG-4157448+4920695_corrected_UsePAM_comment.patch 2008-07-24
> 04:33:03 UTC (rev 38526)
> @@ -0,0 +1,25 @@
> +diff -uNr ../openssh-4.5p1.orig/sshd_config ./sshd_config
> +--- ../openssh-4.5p1.orig/sshd_config 2006-07-23 21:06:47.000000000
> -0700
> ++++ ./sshd_config 2007-01-11 17:05:47.000000000 -0800
> +@@ -52,7 +52,8 @@
> + # Don't read the user's ~/.rhosts and ~/.shosts files
> + #IgnoreRhosts yes
> +
> +-# To disable tunneled clear text passwords, change to no here!
> ++# To disable tunneled clear text passwords, change to no here! Also,
> ++# remember to set the UsePAM setting to 'no'.
> + #PasswordAuthentication yes
> + #PermitEmptyPasswords no
> +
> +@@ -78,7 +79,10 @@
> + # If you just want the PAM account and session checks to run without
> + # PAM authentication, then enable this but set
> PasswordAuthentication
> + # and ChallengeResponseAuthentication to 'no'.
> +-#UsePAM no
> ++# Also, PAM will deny null passwords by default. If you need to
> allow
> ++# null passwords, add the " nullok" option to the end of the
> ++# securityserver.so line in /etc/pam.d/sshd.
> ++#UsePAM yes
> +
> + #AllowTcpForwarding yes
> + #GatewayPorts no
> Added: trunk/dports/net/openssh/files/
> DVG-4212542_auth_error_logging_fix.patch (0 => 38526)
> --- trunk/dports/net/openssh/files/
> DVG-4212542_auth_error_logging_fix.patch
> (rev 0)
> +++ trunk/dports/net/openssh/files/
> DVG-4212542_auth_error_logging_fix.patch 2008-07-24 04:33:03 UTC
> (rev 38526)
> @@ -0,0 +1,12 @@
> +diff -uNr ../openssh-4.3p2.orig/sshd_config ./sshd_config
> +--- ../openssh-4.3p2.orig/sshd_config 2005-12-13 00:29:03.000000000
> -0800
> ++++ ./sshd_config 2006-10-18 16:47:04.000000000 -0700
> +@@ -28,7 +28,7 @@
> +
> + # Logging
> + # obsoletes QuietMode and FascistLogging
> +-#SyslogFacility AUTH
> ++SyslogFacility AUTHPRIV
> + #LogLevel INFO
> +
> + # Authentication:
> Added: trunk/dports/net/openssh/files/
> DVG-4648874_preserve_EA_mtime.patch (0 => 38526)
> --- trunk/dports/net/openssh/files/
> DVG-4648874_preserve_EA_mtime.patch (rev 0)
> +++ trunk/dports/net/openssh/files/
> DVG-4648874_preserve_EA_mtime.patch 2008-07-24 04:33:03 UTC (rev
> 38526)
> @@ -0,0 +1,18 @@
> +diff -uNr ../openssh-4.5p1.orig/scp.c ./scp.c
> +--- ../openssh-4.5p1.orig/scp.c 2006-12-12 13:08:35.000000000 -0800
> ++++ ./scp.c 2006-12-12 15:53:57.000000000 -0800
> +@@ -1163,6 +1163,14 @@
> + rename(md_src, md_dst);
> + } else
> + unlink(md_src);
> ++ if (setimes && wrerr == NO) {
> ++ setimes = 0;
> ++ if (utimes(md_dst, tv) < 0) {
> ++ run_err("%s: set times: %s",
> ++ np, strerror(errno));
> ++ wrerr = DISPLAYED;
> ++ }
> ++ }
> + } else
> + #endif
> + if (setimes && wrerr == NO) {
> Added: trunk/dports/net/openssh/files/
> DVG-4694589_16_group_limit_fix.patch (0 => 38526)
> --- trunk/dports/net/openssh/files/
> DVG-4694589_16_group_limit_fix.patch (rev 0)
> +++ trunk/dports/net/openssh/files/
> DVG-4694589_16_group_limit_fix.patch 2008-07-24 04:33:03 UTC (rev
> 38526)
> @@ -0,0 +1,13 @@
> +diff -uNr ../openssh-4.5p1.orig/uidswap.c ./uidswap.c
> +--- ../openssh-4.5p1.orig/uidswap.c 2006-08-04 19:39:41.000000000
> -0700
> ++++ ./uidswap.c 2007-01-12 19:26:22.000000000 -0800
> +@@ -233,6 +239,9 @@
> + fatal("setgid %u: %.100s", (u_int)pw->pw_gid, strerror(errno));
> + #endif
> +
> ++ if (initgroups(pw->pw_name, pw->pw_gid) < 0)
> ++ fatal("setgid %.100s %u: %.100s", pw->pw_name, (u_int)pw-
> >pw_gid, strerror(errno));
> ++
> + #if defined(HAVE_SETRESUID) && !defined(BROKEN_SETRESUID)
> + if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) < 0)
> + fatal("setresuid %u: %.100s", (u_int)pw->pw_uid, strerror(errno));
> Added: trunk/dports/net/openssh/files/DVG-4748610+4897588_ssh-
> agent_via_launchd.patch (0 => 38526)
> --- trunk/dports/net/openssh/files/DVG-4748610+4897588_ssh-
> agent_via_launchd.patch (rev 0)
> +++ trunk/dports/net/openssh/files/DVG-4748610+4897588_ssh-
> agent_via_launchd.patch 2008-07-24 04:33:03 UTC (rev 38526)
> @@ -0,0 +1,146 @@
> +diff -ru ../openssh-4.7p1.old/ssh-agent.c ./ssh-agent.c
> +--- ../openssh-4.7p1.old/ssh-agent.c 2007-03-21 02:45:07.000000000
> -0700
> ++++ ./ssh-agent.c 2007-10-01 01:01:39.000000000 -0700
> +@@ -64,6 +64,9 @@
> + #include <time.h>
> + #include <string.h>
> + #include <unistd.h>
> ++#ifdef __APPLE_LAUNCHD__
> ++#include <launch.h>
> ++#endif
> +
> + #include "xmalloc.h"
> + #include "ssh.h"
> +@@ -1031,7 +1034,11 @@
> + int
> + main(int ac, char **av)
> + {
> ++#ifdef __APPLE_LAUNCHD__
> ++ int c_flag = 0, d_flag = 0, k_flag = 0, s_flag = 0, l_flag = 0;
> ++#else
> + int c_flag = 0, d_flag = 0, k_flag = 0, s_flag = 0;
> ++#endif
> + int sock, fd, ch, result, saved_errno;
> + u_int nalloc;
> + char *shell, *format, *pidstr, *agentsocket = NULL;
> +@@ -1065,7 +1072,11 @@
> + init_rng();
> + seed_rng();
> +
> ++#ifdef __APPLE_LAUNCHD__
> ++ while ((ch = getopt(ac, av, "cdklsa:t:")) != -1) {
> ++#else
> + while ((ch = getopt(ac, av, "cdksa:t:")) != -1) {
> ++#endif
> + switch (ch) {
> + case 'c':
> + if (s_flag)
> +@@ -1075,6 +1086,11 @@
> + case 'k':
> + k_flag++;
> + break;
> ++#ifdef __APPLE_LAUNCHD__
> ++ case 'l':
> ++ l_flag++;
> ++ break;
> ++#endif
> + case 's':
> + if (c_flag)
> + usage();
> +@@ -1101,7 +1117,11 @@
> + ac -= optind;
> + av += optind;
> +
> ++#ifdef __APPPLE_LAUNCHD__
> ++ if (ac > 0 && (c_flag || k_flag || s_flag || d_flag || l_flag))
> ++#else
> + if (ac > 0 && (c_flag || k_flag || s_flag || d_flag))
> ++#endif
> + usage();
> +
> + if (ac == 0 && !c_flag && !s_flag) {
> +@@ -1157,6 +1177,53 @@
> + * Create socket early so it will exist before command gets run
> from
> + * the parent.
> + */
> ++#ifdef __APPLE_LAUNCHD__
> ++ if (l_flag) {
> ++ launch_data_t resp, msg, tmp;
> ++ size_t listeners_i;
> ++
> ++ msg = launch_data_new_string(LAUNCH_KEY_CHECKIN);
> ++
> ++ resp = launch_msg(msg);
> ++
> ++ if (NULL == resp) {
> ++ perror("launch_msg");
> ++ exit(1);
> ++ }
> ++ launch_data_free(msg);
> ++ switch (launch_data_get_type(resp)) {
> ++ case LAUNCH_DATA_ERRNO:
> ++ errno = launch_data_get_errno(resp);
> ++ perror("launch_msg response");
> ++ exit(1);
> ++ case LAUNCH_DATA_DICTIONARY:
> ++ break;
> ++ default:
> ++ fprintf(stderr, "launch_msg unknown response");
> ++ exit(1);
> ++ }
> ++ tmp = launch_data_dict_lookup(resp, LAUNCH_JOBKEY_SOCKETS);
> ++
> ++ if (NULL == tmp) {
> ++ fprintf(stderr, "no sockets\n");
> ++ exit(1);
> ++ }
> ++
> ++ tmp = launch_data_dict_lookup(tmp, "Listeners");
> ++
> ++ if (NULL == tmp) {
> ++ fprintf(stderr, "no known listeners\n");
> ++ exit(1);
> ++ }
> ++
> ++ for (listeners_i = 0; listeners_i <
> launch_data_array_get_count(tmp); listeners_i++) {
> ++ launch_data_t obj_at_ind = launch_data_array_get_index(tmp,
> listeners_i);
> ++ new_socket(AUTH_SOCKET, launch_data_get_fd(obj_at_ind));
> ++ }
> ++
> ++ launch_data_free(resp);
> ++ } else {
> ++#endif
> + sock = socket(AF_UNIX, SOCK_STREAM, 0);
> + if (sock < 0) {
> + perror("socket");
> +@@ -1178,6 +1245,9 @@
> + perror("listen");
> + cleanup_exit(1);
> + }
> ++#ifdef __APPLE_LAUNCHD__
> ++ }
> ++#endif
> +
> + /*
> + * Fork, and have the parent execute the command, if any, or
> present
> +@@ -1191,6 +1261,12 @@
> + printf("echo Agent pid %ld;\n", (long)parent_pid);
> + goto skip;
> + }
> ++
> ++#ifdef __APPLE_LAUNCHD__
> ++ if (l_flag)
> ++ goto skip2;
> ++#endif
> ++
> + pid = fork();
> + if (pid == -1) {
> + perror("fork");
> +@@ -1246,6 +1322,7 @@
> +
> + skip:
> + new_socket(AUTH_SOCKET, sock);
> ++skip2:
> + if (ac > 0)
> + parent_alive_interval = 10;
> + idtab_init();
> Added: trunk/dports/net/openssh/files/
> DVG-4853931_enable_GSSAPI.patch (0 => 38526)
> --- trunk/dports/net/openssh/files/
> DVG-4853931_enable_GSSAPI.patch (rev 0)
> +++ trunk/dports/net/openssh/files/DVG-4853931_enable_GSSAPI.patch
> 2008-07-24 04:33:03 UTC (rev 38526)
> @@ -0,0 +1,42 @@
> +diff -uNr ../openssh-4.5p1.orig/readconf.c ./readconf.c
> +--- ../openssh-4.5p1.orig/readconf.c 2006-12-05 21:05:28.000000000
> -0800
> ++++ ./readconf.c 2006-12-05 21:10:59.000000000 -0800
> +@@ -1113,10 +1113,17 @@
> + options->pubkey_authentication = 1;
> + if (options->challenge_response_authentication == -1)
> + options->challenge_response_authentication = 1;
> ++#ifdef __APPLE_GSSAPI_ENABLE__
> ++ if (options->gss_authentication == -1)
> ++ options->gss_authentication = 1;
> ++ if (options->gss_keyex == -1)
> ++ options->gss_keyex = 1;
> ++#else
> + if (options->gss_authentication == -1)
> + options->gss_authentication = 0;
> + if (options->gss_keyex == -1)
> + options->gss_keyex = 0;
> ++#endif
> + if (options->gss_deleg_creds == -1)
> + options->gss_deleg_creds = 0;
> + if (options->gss_trust_dns == -1)
> +diff -uNr ../openssh-4.5p1.orig/servconf.c ./servconf.c
> +--- ../openssh-4.5p1.orig/servconf.c 2006-12-05 21:05:28.000000000
> -0800
> ++++ ./servconf.c 2006-12-05 21:08:44.000000000 -0800
> +@@ -204,10 +204,17 @@
> + options->kerberos_ticket_cleanup = 1;
> + if (options->kerberos_get_afs_token == -1)
> + options->kerberos_get_afs_token = 0;
> ++#ifdef __APPLE_GSSAPI_ENABLE__
> ++ if (options->gss_authentication == -1)
> ++ options->gss_authentication = 1;
> ++ if (options->gss_keyex == -1)
> ++ options->gss_keyex = 1;
> ++#else
> + if (options->gss_authentication == -1)
> + options->gss_authentication = 0;
> + if (options->gss_keyex == -1)
> + options->gss_keyex = 0;
> ++#endif
> + if (options->gss_cleanup_creds == -1)
> + options->gss_cleanup_creds = 1;
> + if (options->gss_strict_acceptor == -1)
> Added: trunk/dports/net/openssh/files/
> DVG-4853931_enable_GSSAPI_for_pre-Leopard---BuildPhase.patch (0 =>
> 38526)
> --- trunk/dports/net/openssh/files/DVG-4853931_enable_GSSAPI_for_pre-
> Leopard---BuildPhase.patch (rev 0)
> +++ trunk/dports/net/openssh/files/DVG-4853931_enable_GSSAPI_for_pre-
> Leopard---BuildPhase.patch 2008-07-24 04:33:03 UTC (rev 38526)
> @@ -0,0 +1,69 @@
> +diff -ur ../OpenSSH-5729681~obj.orig/ssh_config.5.out ./ssh_config.
> 5.out
> +--- ../OpenSSH-5729681~obj.orig/ssh_config.5.out 2008-02-07
> 13:25:33.000000000 -0800
> ++++ ./ssh_config.5.out 2008-02-07 13:31:16.000000000 -0800
> +@@ -475,13 +475,13 @@
> + .It Cm GSSAPIAuthentication
> + Specifies whether user authentication based on GSSAPI is allowed.
> + The default is
> +-.Dq no .
> ++.Dq yes .
> + Note that this option applies to protocol version 2 only.
> + .It Cm GSSAPIKeyExchange
> + Specifies whether key exchange based on GSSAPI may be used. When
> using
> + GSSAPI key exchange the server need not have a host key.
> + The default is
> +-.Dq no .
> ++.Dq yes .
> + Note that this option applies to protocol version 2 only.
> + .It Cm GSSAPIDelegateCredentials
> + Forward (delegate) credentials to the server.
> +diff -ur ../OpenSSH-5729681~obj.orig/ssh_config.out ./ssh_config.out
> +--- ../OpenSSH-5729681~obj.orig/ssh_config.out 2008-02-07
> 13:25:32.000000000 -0800
> ++++ ./ssh_config.out 2008-02-07 13:29:57.000000000 -0800
> +@@ -24,9 +24,9 @@
> + # RSAAuthentication yes
> + # PasswordAuthentication yes
> + # HostbasedAuthentication no
> +-# GSSAPIAuthentication no
> ++# GSSAPIAuthentication yes
> + # GSSAPIDelegateCredentials no
> +-# GSSAPIKeyExchange no
> ++# GSSAPIKeyExchange yes
> + # GSSAPITrustDNS no
> + # BatchMode no
> + # CheckHostIP yes
> +diff -ur ../OpenSSH-5729681~obj.orig/sshd_config.5.out ./
> sshd_config.5.out
> +--- ../OpenSSH-5729681~obj.orig/sshd_config.5.out 2008-02-07
> 13:25:33.000000000 -0800
> ++++ ./sshd_config.5.out 2008-02-07 13:31:43.000000000 -0800
> +@@ -313,13 +313,13 @@
> + .It Cm GSSAPIAuthentication
> + Specifies whether user authentication based on GSSAPI is allowed.
> + The default is
> +-.Dq no .
> ++.Dq yes .
> + Note that this option applies to protocol version 2 only.
> + .It Cm GSSAPIKeyExchange
> + Specifies whether key exchange based on GSSAPI is allowed. GSSAPI
> key exchange
> + doesn't rely on ssh keys to verify host identity.
> + The default is
> +-.Dq no .
> ++.Dq yes .
> + Note that this option applies to protocol version 2 only.
> + .It Cm GSSAPICleanupCredentials
> + Specifies whether to automatically destroy the user's credentials
> cache
> +diff -ur ../OpenSSH-5729681~obj.orig/sshd_config.out ./
> sshd_config.out
> +--- ../OpenSSH-5729681~obj.orig/sshd_config.out 2008-02-07
> 13:26:28.000000000 -0800
> ++++ ./sshd_config.out 2008-02-07 13:30:22.000000000 -0800
> +@@ -70,10 +70,10 @@
> + #KerberosGetAFSToken no
> +
> + # GSSAPI options
> +-#GSSAPIAuthentication no
> ++#GSSAPIAuthentication yes
> + #GSSAPICleanupCredentials yes
> + #GSSAPIStrictAcceptorCheck yes
> +-#GSSAPIKeyExchange no
> ++#GSSAPIKeyExchange yes
> +
> + # Set this to 'yes' to enable PAM authentication, account
> processing,
> + # and session processing. If this is enabled, PAM authentication
> will
> Added: trunk/dports/net/openssh/files/
> DVG-4920695_remove_nullok_comment_for_pre-Leopard---BuildPhase.patch
> (0 => 38526)
> --- trunk/dports/net/openssh/files/
> DVG-4920695_remove_nullok_comment_for_pre-Leopard---
> BuildPhase.patch (rev 0)
> +++ trunk/dports/net/openssh/files/
> DVG-4920695_remove_nullok_comment_for_pre-Leopard---BuildPhase.patch
> 2008-07-24 04:33:03 UTC (rev 38526)
> @@ -0,0 +1,13 @@
> +diff -uNr ../openssh-4.7p1.orig/sshd_config ./sshd_config
> +--- ../openssh-4.7p1.orig/sshd_config.out 2008-02-06
> 10:27:36.000000000 -0800
> ++++ ./sshd_config.out 2008-02-06 10:26:39.000000000 -0800
> +@@ -83,9 +83,6 @@
> + # If you just want the PAM account and session checks to run without
> + # PAM authentication, then enable this but set
> PasswordAuthentication
> + # and ChallengeResponseAuthentication to 'no'.
> +-# Also, PAM will deny null passwords by default. If you need to
> allow
> +-# null passwords, add the " nullok" option to the end of the
> +-# securityserver.so line in /etc/pam.d/sshd.
> + #UsePAM yes
> +
> + #AllowTcpForwarding yes
> Added: trunk/dports/net/openssh/files/
> DVG-5142987_launchd_DISPLAY_for_X11.patch (0 => 38526)
> --- trunk/dports/net/openssh/files/
> DVG-5142987_launchd_DISPLAY_for_X11.patch
> (rev 0)
> +++ trunk/dports/net/openssh/files/
> DVG-5142987_launchd_DISPLAY_for_X11.patch 2008-07-24 04:33:03 UTC
> (rev 38526)
> @@ -0,0 +1,55 @@
> +diff -uNr ../openssh-4.5p1.orig/channels.c ./channels.c
> +--- ../openssh-4.5p1.orig/channels.c 2006-08-29 18:07:40.000000000
> -0700
> ++++ ./channels.c 2007-04-19 18:59:28.000000000 -0700
> +@@ -2954,7 +2954,7 @@
> + }
> +
> + static int
> +-connect_local_xsocket(u_int dnr)
> ++connect_local_xsocket_path(const char *pathname)
> + {
> + int sock;
> + struct sockaddr_un addr;
> +@@ -2964,7 +2964,7 @@
> + error("socket: %.100s", strerror(errno));
> + memset(&addr, 0, sizeof(addr));
> + addr.sun_family = AF_UNIX;
> +- snprintf(addr.sun_path, sizeof addr.sun_path, _PATH_UNIX_X, dnr);
> ++ strlcpy(addr.sun_path, pathname, sizeof addr.sun_path);
> + if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0)
> + return sock;
> + close(sock);
> +@@ -2972,6 +2972,14 @@
> + return -1;
> + }
> +
> ++static int
> ++connect_local_xsocket(u_int dnr)
> ++{
> ++ char buf[1024];
> ++ snprintf(buf, sizeof buf, _PATH_UNIX_X, dnr);
> ++ return connect_local_xsocket_path(buf);
> ++}
> ++
> + int
> + x11_connect_display(void)
> + {
> +@@ -2994,9 +3002,18 @@
> + */
> +
> + /*
> ++ * Check if the display is from launchd, then...
> + * Check if it is a unix domain socket. Unix domain displays are
> in
> + * one of the following formats: unix:d[.s], :d[.s], ::d[.s]
> + */
> ++ if (strncmp(display, "/tmp/launch", 11) == 0) {
> ++ sock = connect_local_xsocket_path(display);
> ++ if (sock < 0)
> ++ return -1;
> ++
> ++ /* OK, we now have a connection to the display. */
> ++ return sock;
> ++ }
> + if (strncmp(display, "unix:", 5) == 0 ||
> + display[0] == ':') {
> + /* Connect to the unix domain socket. */
> Added: trunk/dports/net/openssh/files/
> DVG-5258734_pty_permission_fix.patch (0 => 38526)
> --- trunk/dports/net/openssh/files/
> DVG-5258734_pty_permission_fix.patch (rev 0)
> +++ trunk/dports/net/openssh/files/
> DVG-5258734_pty_permission_fix.patch 2008-07-24 04:33:03 UTC (rev
> 38526)
> @@ -0,0 +1,26 @@
> +diff -uNr ../openssh-4.5p1.orig/session.c ./session.c
> +--- ../openssh-4.5p1.orig/session.c 2006-10-23 10:01:56.000000000
> -0700
> ++++ ./session.c 2007-06-15 11:23:17.000000000 -0700
> +@@ -1846,8 +1846,10 @@
> + n_bytes = packet_remaining();
> + tty_parse_modes(s->ttyfd, &n_bytes);
> +
> ++#ifndef __APPLE_PRIVPTY__
> + if (!use_privsep)
> + pty_setowner(s->pw, s->tty);
> ++#endif
> +
> + /* Set window size from the packet. */
> + pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s-
> >ypixel);
> +@@ -2085,9 +2087,11 @@
> + if (s->pid != 0)
> + record_logout(s->pid, s->tty, s->pw->pw_name);
> +
> ++#ifndef __APPLE_PRIVPTY__
> + /* Release the pseudo-tty. */
> + if (getuid() == 0)
> + pty_release(s->tty);
> ++#endif
> +
> + /*
> + * Close the server side of the socket pairs. We must do this
> after
> Added: trunk/dports/net/openssh/files/
> DVG-5462402_enable_SSH1_for_pre-Leopard---BuildPhase.patch (0 =>
> 38526)
> --- trunk/dports/net/openssh/files/DVG-5462402_enable_SSH1_for_pre-
> Leopard---BuildPhase.patch (rev 0)
> +++ trunk/dports/net/openssh/files/DVG-5462402_enable_SSH1_for_pre-
> Leopard---BuildPhase.patch 2008-07-24 04:33:03 UTC (rev 38526)
> @@ -0,0 +1,19 @@
> +--- ../openssh-4.7p1/sshd_config.out 2007-03-21 02:42:25.000000000
> -0700
> ++++ ./sshd_config.out 2006-07-23 21:06:47.000000000 -0700
> +@@ -11,15 +11,11 @@
> + # default value.
> +
> + #Port 22
> ++#Protocol 2,1
> + #AddressFamily any
> + #ListenAddress 0.0.0.0
> + #ListenAddress ::
> +
> +-# Disable legacy (protocol version 1) support in the server for new
> +-# installations. In future the default will change to require
> explicit
> +-# activation of protocol 1
> +-Protocol 2
> +-
> + # HostKey for protocol version 1
> + #HostKey /etc/ssh/ssh_host_key
> + # HostKeys for protocol version 2
> Added: trunk/dports/net/openssh/files/
> DVG-5755519_use_GSS_C_NO_NAME_with_gss_acquire_cred.patch (0 => 38526)
> --- trunk/dports/net/openssh/files/
> DVG
> -5755519_use_GSS_C_NO_NAME_with_gss_acquire_cred
> .patch (rev 0)
> +++ trunk/dports/net/openssh/files/
> DVG-5755519_use_GSS_C_NO_NAME_with_gss_acquire_cred.patch 2008-07-24
> 04:33:03 UTC (rev 38526)
> @@ -0,0 +1,12 @@
> +diff -uNr ../openssh-5.0p1.orig/gss-serv.c ./gss-serv.c
> +--- ../openssh-5.0p1.orig/gss-serv.c 2008-04-15 17:48:41.000000000
> -0700
> ++++ ./gss-serv.c 2008-04-15 17:49:27.000000000 -0700
> +@@ -99,7 +99,7 @@
> + }
> +
> + if ((ctx->major = gss_acquire_cred(&ctx->minor,
> +- ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds,
> ++ GSS_C_NO_NAME, 0, oidset, GSS_C_ACCEPT, &ctx->creds,
> + NULL, NULL)))
> + ssh_gssapi_error(ctx);
> +
> Added: trunk/dports/net/openssh/files/lastlog.patch (0 => 38526)
> --- trunk/dports/net/openssh/files/
> lastlog.patch (rev 0)
> +++ trunk/dports/net/openssh/files/lastlog.patch 2008-07-24 04:33:03
> UTC (rev 38526)
> @@ -0,0 +1,50 @@
> +diff -uNr ../openssh-5.0p1.orig/loginrec.c ./loginrec.c
> +--- ../openssh-5.0p1.orig/loginrec.c 2007-04-28 19:10:58.000000000
> -0700
> ++++ ./loginrec.c 2008-04-17 12:43:18.000000000 -0700
> +@@ -1456,6 +1456,38 @@
> + **/
> +
> + #ifdef USE_LASTLOG
> ++#ifdef __APPLE_UTMPX__
> ++int
> ++lastlog_write_entry(struct logininfo *li)
> ++{
> ++ switch(li->type) {
> ++ case LTYPE_LOGIN:
> ++ return 1; /* lastlog written by pututxline */
> ++ default:
> ++ logit("lastlog_write_entry: Invalid type field");
> ++ return 0;
> ++ }
> ++}
> ++
> ++int
> ++lastlog_get_entry(struct logininfo *li)
> ++{
> ++ struct lastlogx l, *ll;
> ++
> ++ if ((ll = getlastlogxbyname(li->username, &l)) == NULL) {
> ++ memset(&l, '\0', sizeof(l));
> ++ ll = &l;
> ++ }
> ++ line_fullname(li->line, ll->ll_line, sizeof(li->line));
> ++ strlcpy(li->hostname, ll->ll_host,
> ++ MIN_SIZEOF(li->hostname, ll->ll_host));
> ++ li->tv_sec = ll->ll_tv.tv_sec;
> ++ li->tv_usec = ll->ll_tv.tv_usec;
> ++ return (1);
> ++}
> ++
> ++#else /* !__APPLE_UTMPX__ */
> ++
> + #define LL_FILE 1
> + #define LL_DIR 2
> + #define LL_OTHER 3
> +@@ -1613,6 +1645,7 @@
> + /* NOTREACHED */
> + return (0);
> + }
> ++#endif /* __APPLE_UTMPX__ */
> + #endif /* USE_LASTLOG */
> +
> + #ifdef USE_BTMP
> Added: trunk/dports/net/openssh/files/openssh-5.0p1-
> gsskex-20080404.patch (0 => 38526)
> --- trunk/dports/net/openssh/files/openssh-5.0p1-
> gsskex-20080404.patch (rev 0)
> +++ trunk/dports/net/openssh/files/openssh-5.0p1-
> gsskex-20080404.patch 2008-07-24 04:33:03 UTC (rev 38526)
> @@ -0,0 +1,2295 @@
> +? gss-genr.c.pre14
> +? kex.c.pre14
> +? kex.h.pre14
> +? kexgssc.c.pre14
> +? kexgsss.c.pre14
> +? monitor.c.pre14
> +? new.patch
> +? ssh-gss.h.pre14
> +? sshconnect2.c.pre14
> +? sshd.c.pre14
> +Index: ChangeLog.gssapi
> +===================================================================
> +RCS file: ChangeLog.gssapi
> +diff -N ChangeLog.gssapi
> +--- /dev/null 1 Jan 1970 00:00:00 -0000
> ++++ ChangeLog.gssapi 4 Apr 2008 12:52:27 -0000
> +@@ -0,0 +1,75 @@
> ++20080404
> ++ - [ gss-serv.c ]
> ++ Add code to actually implement GSSAPIStrictAcceptCheck, which
> had somehow
> ++ been omitted from a previous version of this patch. Reported
> by Borislav
> ++ Stoichkov
> ++
> ++20070317
> ++ - [ gss-serv-krb5.c ]
> ++ Remove C99ism, where new_ccname was being declared in the
> middle of a
> ++ function
> ++
> ++20061220
> ++ - [ servconf.c ]
> ++ Make default for GSSAPIStrictAcceptorCheck be Yes, to match
> previous, and
> ++ documented, behaviour. Reported by Dan Watson.
> ++
> ++20060910
> ++ - [ gss-genr.c kexgssc.c kexgsss.c kex.h monitor.c sshconnect2.c
> sshd.c
> ++ ssh-gss.h ]
> ++ add support for gss-group14-sha1 key exchange mechanisms
> ++ - [ gss-serv.c servconf.c servconf.h sshd_config sshd_config.5 ]
> ++ Add GSSAPIStrictAcceptorCheck option to allow the disabling of
> ++ acceptor principal checking on multi-homed machines.
> ++ <Bugzilla #928>
> ++ - [ sshd_config ssh_config ]
> ++ Add settings for GSSAPIKeyExchange and GSSAPITrustDNS to the
> sample
> ++ configuration files
> ++ - [ kexgss.c kegsss.c sshconnect2.c sshd.c ]
> ++ Code cleanup. Replace strlen/xmalloc/snprintf sequences with
> xasprintf()
> ++ Limit length of error messages displayed by client
> ++
> ++20060909
> ++ - [ gss-genr.c gss-serv.c ]
> ++ move ssh_gssapi_acquire_cred() and ssh_gssapi_server_ctx to be
> server
> ++ only, where they belong
> ++ <Bugzilla #1225>
> ++
> ++20060829
> ++ - [ gss-serv-krb5.c ]
> ++ Fix CCAPI credentials cache name when creating KRB5CCNAME
> environment
> ++ variable
> ++
> ++20060828
> ++ - [ gss-genr.c ]
> ++ Avoid Heimdal context freeing problem
> ++ <Fixed upstream 20060829>
> ++
> ++20060818
> ++ - [ gss-genr.c ssh-gss.h sshconnect2.c ]
> ++ Make sure that SPENGO is disabled
> ++ <Bugzilla #1218 - Fixed upstream 20060818>
> ++
> ++20060421
> ++ - [ gssgenr.c, sshconnect2.c ]
> ++ a few type changes (signed versus unsigned, int versus size_t)
> to
> ++ fix compiler errors/warnings
> ++ (from jbasney AT ncsa.uiuc.edu)
> ++ - [ kexgssc.c, sshconnect2.c ]
> ++ fix uninitialized variable warnings
> ++ (from jbasney AT ncsa.uiuc.edu)
> ++ - [ gssgenr.c ]
> ++ pass oid to gss_display_status (helpful when using GSSAPI
> mechglue)
> ++ (from jbasney AT ncsa.uiuc.edu)
> ++ <Bugzilla #1220 >
> ++ - [ gss-serv-krb5.c ]
> ++ #ifdef HAVE_GSSAPI_KRB5 should be #ifdef HAVE_GSSAPI_KRB5_H
> ++ (from jbasney AT ncsa.uiuc.edu)
> ++ <Fixed upstream 20060304>
> ++ - [ readconf.c, readconf.h, ssh_config.5, sshconnect2.c
> ++ add client-side GssapiKeyExchange option
> ++ (from jbasney AT ncsa.uiuc.edu)
> ++ - [ sshconnect2.c ]
> ++ add support for GssapiTrustDns option for gssapi-with-mic
> ++ (from jbasney AT ncsa.uiuc.edu)
> ++ <gssapi-with-mic support is Bugzilla #1008>
> +Index: Makefile.in
> +===================================================================
> +RCS file: /cvs/openssh/Makefile.in,v
> +retrieving revision 1.289
> +diff -u -r1.289 Makefile.in
> +--- Makefile.in 13 Mar 2008 01:41:31 -0000 1.289
> ++++ Makefile.in 4 Apr 2008 12:52:27 -0000
> +@@ -71,7 +71,7 @@
> + atomicio.o key.o dispatch.o kex.o mac.o uidswap.o uuencode.o
> misc.o \
> + monitor_fdpass.o rijndael.o ssh-dss.o ssh-rsa.o dh.o kexdh.o \
> + kexgex.o kexdhc.o kexgexc.o scard.o msg.o progressmeter.o dns.o \
> +- entropy.o scard-opensc.o gss-genr.o umac.o
> ++ entropy.o scard-opensc.o gss-genr.o umac.o kexgssc.o
> +
> + SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
> + sshconnect.o sshconnect1.o sshconnect2.o
> +@@ -84,7 +84,7 @@
> + auth2-none.o auth2-passwd.o auth2-pubkey.o \
> + monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o \
> + auth-krb5.o \
> +- auth2-gss.o gss-serv.o gss-serv-krb5.o \
> ++ auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o\
> + loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \
> + audit.o audit-bsm.o platform.o sftp-server.o sftp-common.o
> +
> +Index: auth-krb5.c
> +===================================================================
> +RCS file: /cvs/openssh/auth-krb5.c,v
> +retrieving revision 1.35
> +diff -u -r1.35 auth-krb5.c
> +--- auth-krb5.c 5 Aug 2006 02:39:39 -0000 1.35
> ++++ auth-krb5.c 4 Apr 2008 12:52:28 -0000
> +@@ -166,8 +166,13 @@
> +
> + len = strlen(authctxt->krb5_ticket_file) + 6;
> + authctxt->krb5_ccname = xmalloc(len);
> ++#ifdef USE_CCAPI
> ++ snprintf(authctxt->krb5_ccname, len, "API:%s",
> ++ authctxt->krb5_ticket_file);
> ++#else
> + snprintf(authctxt->krb5_ccname, len, "FILE:%s",
> + authctxt->krb5_ticket_file);
> ++#endif
> +
> + #ifdef USE_PAM
> + if (options.use_pam)
> +@@ -219,15 +224,22 @@
> + #ifndef HEIMDAL
> + krb5_error_code
> + ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) {
> +- int tmpfd, ret;
> ++ int ret;
> + char ccname[40];
> + mode_t old_umask;
> ++#ifdef USE_CCAPI
> ++ char cctemplate[] = "API:krb5cc_%d";
> ++#else
> ++ char cctemplate[] = "FILE:/tmp/krb5cc_%d_XXXXXXXXXX";
> ++ int tmpfd;
> ++#endif
> +
> + ret = snprintf(ccname, sizeof(ccname),
> +- "FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid());
> ++ cctemplate, geteuid());
> + if (ret < 0 || (size_t)ret >= sizeof(ccname))
> + return ENOMEM;
> +
> ++#ifndef USE_CCAPI
> + old_umask = umask(0177);
> + tmpfd = mkstemp(ccname + strlen("FILE:"));
> + umask(old_umask);
> +@@ -242,6 +254,7 @@
> + return errno;
> + }
> + close(tmpfd);
> ++#endif
> +
> + return (krb5_cc_resolve(ctx, ccname, ccache));
> + }
> +Index: auth.h
> +===================================================================
> +RCS file: /cvs/openssh/auth.h,v
> +retrieving revision 1.78
> +diff -u -r1.78 auth.h
> +--- auth.h 26 Oct 2007 04:25:13 -0000 1.78
> ++++ auth.h 4 Apr 2008 12:52:28 -0000
> +@@ -53,6 +53,7 @@
> + int valid; /* user exists and is allowed to login */
> + int attempt;
> + int failures;
> ++ int server_caused_failure;
> + int force_pwchange;
> + char *user; /* username sent by the client */
> + char *service;
> +Index: auth2-gss.c
> +===================================================================
> +RCS file: /cvs/openssh/auth2-gss.c,v
> +retrieving revision 1.19
> +diff -u -r1.19 auth2-gss.c
> +--- auth2-gss.c 2 Dec 2007 11:59:45 -0000 1.19
> ++++ auth2-gss.c 4 Apr 2008 12:52:28 -0000
> +@@ -52,6 +52,39 @@
> + static void input_gssapi_exchange_complete(int type, u_int32_t
> plen, void *ctxt);
> + static void input_gssapi_errtok(int, u_int32_t, void *);
> +
> ++/*
> ++ * The 'gssapi_keyex' userauth mechanism.
> ++ */
> ++static int
> ++userauth_gsskeyex(Authctxt *authctxt)
> ++{
> ++ int authenticated = 0;
> ++ Buffer b;
> ++ gss_buffer_desc mic, gssbuf;
> ++ u_int len;
> ++
> ++ mic.value = packet_get_string(&len);
> ++ mic.length = len;
> ++
> ++ packet_check_eom();
> ++
> ++ ssh_gssapi_buildmic(&b, authctxt->user, authctxt->service,
> ++ "gssapi-keyex");
> ++
> ++ gssbuf.value = buffer_ptr(&b);
> ++ gssbuf.length = buffer_len(&b);
> ++
> ++ /* gss_kex_context is NULL with privsep, so we can't check it
> here */
> ++ if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gss_kex_context,
> ++ &gssbuf, &mic))))
> ++ authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
> ++
> ++ buffer_free(&b);
> ++ xfree(mic.value);
> ++
> ++ return (authenticated);
> ++}
> ++
> + /*
> + * We only support those mechanisms that we know about (ie ones
> that we know
> + * how to check local user kuserok and the like)
> +@@ -102,6 +135,7 @@
> +
> + if (!present) {
> + xfree(doid);
> ++ authctxt->server_caused_failure = 1;
> + return (0);
> + }
> +
> +@@ -109,6 +143,7 @@
> + if (ctxt != NULL)
> + ssh_gssapi_delete_ctx(&ctxt);
> + xfree(doid);
> ++ authctxt->server_caused_failure = 1;
> + return (0);
> + }
> +
> +@@ -291,6 +326,12 @@
> + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
> + userauth_finish(authctxt, authenticated, "gssapi-with-mic");
> + }
> ++
> ++Authmethod method_gsskeyex = {
> ++ "gssapi-keyex",
> ++ userauth_gsskeyex,
> ++ &options.gss_authentication
> ++};
> +
> + Authmethod method_gssapi = {
> + "gssapi-with-mic",
> +Index: auth2.c
> +===================================================================
> +RCS file: /cvs/openssh/auth2.c,v
> +retrieving revision 1.145
> +diff -u -r1.145 auth2.c
> +--- auth2.c 26 Oct 2007 04:26:16 -0000 1.145
> ++++ auth2.c 4 Apr 2008 12:52:28 -0000
> +@@ -64,6 +64,7 @@
> + extern Authmethod method_kbdint;
> + extern Authmethod method_hostbased;
> + #ifdef GSSAPI
> ++extern Authmethod method_gsskeyex;
> + extern Authmethod method_gssapi;
> + #endif
> +
> +@@ -71,6 +72,7 @@
> + &method_none,
> + &method_pubkey,
> + #ifdef GSSAPI
> ++ &method_gsskeyex,
> + &method_gssapi,
> + #endif
> + &method_passwd,
> +@@ -194,6 +196,7 @@
> + #endif
> +
> + authctxt->postponed = 0;
> ++ authctxt->server_caused_failure = 0;
> +
> + /* try to authenticate user */
> + m = authmethod_lookup(method);
> +@@ -264,7 +267,9 @@
> + /* now we can break out */
> + authctxt->success = 1;
> + } else {
> +- if (authctxt->failures++ > options.max_authtries) {
> ++ /* Dont count server configuration issues against the client */
> ++ if (!authctxt->server_caused_failure &&
> ++ authctxt->failures++ > options.max_authtries) {
> + #ifdef SSH_AUDIT_EVENTS
> + PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES));
> + #endif
> +Index: configure.ac
> +===================================================================
> +RCS file: /cvs/openssh/configure.ac,v
> +retrieving revision 1.397
> +diff -u -r1.397 configure.ac
> +--- configure.ac 27 Mar 2008 01:33:07 -0000 1.397
> ++++ configure.ac 4 Apr 2008 12:52:29 -0000
> +@@ -459,6 +459,30 @@
> + [Use tunnel device compatibility to OpenBSD])
> + AC_DEFINE(SSH_TUN_PREPEND_AF, 1,
> + [Prepend the address family to IP tunnel traffic])
> ++ AC_MSG_CHECKING(if we have the Security Authorization Session API)
> ++ AC_TRY_COMPILE([#include <Security/AuthSession.h>],
> ++ [SessionCreate(0, 0);],
> ++ [ac_cv_use_security_session_api="yes"
> ++ AC_DEFINE(USE_SECURITY_SESSION_API, 1,
> ++ [platform has the Security Authorization Session API])
> ++ LIBS="$LIBS -framework Security"
> ++ AC_MSG_RESULT(yes)],
> ++ [ac_cv_use_security_session_api="no"
> ++ AC_MSG_RESULT(no)])
> ++ AC_MSG_CHECKING(if we have an in-memory credentials cache)
> ++ AC_TRY_COMPILE(
> ++ [#include <Kerberos/Kerberos.h>],
> ++ [cc_context_t c;
> ++ (void) cc_initialize (&c, 0, NULL, NULL);],
> ++ [AC_DEFINE(USE_CCAPI, 1,
> ++ [platform uses an in-memory credentials cache])
> ++ LIBS="$LIBS -framework Security"
> ++ AC_MSG_RESULT(yes)
> ++ if test "x$ac_cv_use_security_session_api" = "xno"; then
> ++ AC_MSG_ERROR(*** Need a security framework to use the
> credentials cache API ***)
> ++ fi],
> ++ [AC_MSG_RESULT(no)]
> ++ )
> + m4_pattern_allow(AU_IPv)
> + AC_CHECK_DECL(AU_IPv4, [],
> + AC_DEFINE(AU_IPv4, 0, [System only supports IPv4 audit
> records])
> +Index: gss-genr.c
> +===================================================================
> +RCS file: /cvs/openssh/gss-genr.c,v
> +retrieving revision 1.21
> +diff -u -r1.21 gss-genr.c
> +--- gss-genr.c 12 Jun 2007 13:44:36 -0000 1.21
> ++++ gss-genr.c 4 Apr 2008 12:52:29 -0000
> +@@ -39,12 +39,160 @@
> + #include "buffer.h"
> + #include "log.h"
> + #include "ssh2.h"
> ++#include "cipher.h"
> ++#include "key.h"
> ++#include "kex.h"
> ++#include <openssl/evp.h>
> +
> + #include "ssh-gss.h"
> +
> + extern u_char *session_id2;
> + extern u_int session_id2_len;
> +
> ++typedef struct {
> ++ char *encoded;
> ++ gss_OID oid;
> ++} ssh_gss_kex_mapping;
> ++
> ++/*
> ++ * XXX - It would be nice to find a more elegant way of handling the
> ++ * XXX passing of the key exchange context to the userauth
> routines
> ++ */
> ++
> ++Gssctxt *gss_kex_context = NULL;
> ++
> ++static ssh_gss_kex_mapping *gss_enc2oid = NULL;
> ++
> ++int
> ++ssh_gssapi_oid_table_ok() {
> ++ return (gss_enc2oid != NULL);
> ++}
> ++
> ++/*
> ++ * Return a list of the gss-group1-sha1 mechanisms supported by
> this program
> ++ *
> ++ * We test mechanisms to ensure that we can use them, to avoid
> starting
> ++ * a key exchange with a bad mechanism
> ++ */
> ++
> ++char *
> ++ssh_gssapi_client_mechanisms(const char *host) {
> ++ gss_OID_set gss_supported;
> ++ OM_uint32 min_status;
> ++
> ++ gss_indicate_mechs(&min_status, &gss_supported);
> ++
> ++ return(ssh_gssapi_kex_mechs(gss_supported,
> ssh_gssapi_check_mechanism,
> ++ host));
> ++}
> ++
> ++char *
> ++ssh_gssapi_kex_mechs(gss_OID_set gss_supported,
> ssh_gssapi_check_fn *check,
> ++ const char *data) {
> ++ Buffer buf;
> ++ size_t i;
> ++ int oidpos, enclen;
> ++ char *mechs, *encoded;
> ++ u_char digest[EVP_MAX_MD_SIZE];
> ++ char deroid[2];
> ++ const EVP_MD *evp_md = EVP_md5();
> ++ EVP_MD_CTX md;
> ++
> ++ if (gss_enc2oid != NULL) {
> ++ for (i = 0; gss_enc2oid[i].encoded != NULL; i++)
> ++ xfree(gss_enc2oid[i].encoded);
> ++ xfree(gss_enc2oid);
> ++ }
> ++
> ++ gss_enc2oid = xmalloc(sizeof(ssh_gss_kex_mapping) *
> ++ (gss_supported->count + 1));
> ++
> ++ buffer_init(&buf);
> ++
> ++ oidpos = 0;
> ++ for (i = 0; i < gss_supported->count; i++) {
> ++ if (gss_supported->elements[i].length < 128 &&
> ++ (*check)(NULL, &(gss_supported->elements[i]), data)) {
> ++
> ++ deroid[0] = SSH_GSS_OIDTYPE;
> ++ deroid[1] = gss_supported->elements[i].length;
> ++
> ++ EVP_DigestInit(&md, evp_md);
> ++ EVP_DigestUpdate(&md, deroid, 2);
> ++ EVP_DigestUpdate(&md,
> ++ gss_supported->elements[i].elements,
> ++ gss_supported->elements[i].length);
> ++ EVP_DigestFinal(&md, digest, NULL);
> ++
> ++ encoded = xmalloc(EVP_MD_size(evp_md) * 2);
> ++ enclen = __b64_ntop(digest, EVP_MD_size(evp_md),
> ++ encoded, EVP_MD_size(evp_md) * 2);
> ++
> ++ if (oidpos != 0)
> ++ buffer_put_char(&buf, ',');
> ++
> ++ buffer_append(&buf, KEX_GSS_GEX_SHA1_ID,
> ++ sizeof(KEX_GSS_GEX_SHA1_ID) - 1);
> ++ buffer_append(&buf, encoded, enclen);
> ++ buffer_put_char(&buf, ',');
> ++ buffer_append(&buf, KEX_GSS_GRP1_SHA1_ID,
> ++ sizeof(KEX_GSS_GRP1_SHA1_ID) - 1);
> ++ buffer_append(&buf, encoded, enclen);
> ++ buffer_put_char(&buf, ',');
> ++ buffer_append(&buf, KEX_GSS_GRP14_SHA1_ID,
> ++ sizeof(KEX_GSS_GRP14_SHA1_ID) - 1);
> ++ buffer_append(&buf, encoded, enclen);
> ++
> ++ gss_enc2oid[oidpos].oid = &(gss_supported->elements[i]);
> ++ gss_enc2oid[oidpos].encoded = encoded;
> ++ oidpos++;
> ++ }
> ++ }
> ++ gss_enc2oid[oidpos].oid = NULL;
> ++ gss_enc2oid[oidpos].encoded = NULL;
> ++
> ++ buffer_put_char(&buf, '\0');
> ++
> ++ mechs = xmalloc(buffer_len(&buf));
> ++ buffer_get(&buf, mechs, buffer_len(&buf));
> ++ buffer_free(&buf);
> ++
> ++ if (strlen(mechs) == 0) {
> ++ xfree(mechs);
> ++ mechs = NULL;
> ++ }
> ++
> ++ return (mechs);
> ++}
> ++
> ++gss_OID
> ++ssh_gssapi_id_kex(Gssctxt *ctx, char *name, int kex_type) {
> ++ int i = 0;
> ++
> ++ switch (kex_type) {
> ++ case KEX_GSS_GRP1_SHA1:
> ++ name += sizeof(KEX_GSS_GRP1_SHA1_ID) - 1;
> ++ break;
> ++ case KEX_GSS_GRP14_SHA1:
> ++ name += sizeof(KEX_GSS_GRP14_SHA1_ID) - 1;
> ++ break;
> ++ case KEX_GSS_GEX_SHA1:
> ++ name += sizeof(KEX_GSS_GEX_SHA1_ID) - 1;
> ++ break;
> ++ default:
> ++ return GSS_C_NO_OID;
> ++ }
> ++
> ++ while (gss_enc2oid[i].encoded != NULL &&
> ++ strcmp(name, gss_enc2oid[i].encoded) != 0)
> ++ i++;
> ++
> ++ if (gss_enc2oid[i].oid != NULL && ctx != NULL)
> ++ ssh_gssapi_set_oid(ctx, gss_enc2oid[i].oid);
> ++
> ++ return gss_enc2oid[i].oid;
> ++}
> ++
> + /* Check that the OID in a data stream matches that in the context
> */
> + int
> + ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len)
> +@@ -229,6 +377,9 @@
> + OM_uint32
> + ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t
> hash)
> + {
> ++ if (ctx == NULL)
> ++ return -1;
> ++
> + if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context,
> + GSS_C_QOP_DEFAULT, buffer, hash)))
> + ssh_gssapi_error(ctx);
> +@@ -236,6 +387,19 @@
> + return (ctx->major);
> + }
> +
> ++/* Priviledged when used by server */
> ++OM_uint32
> ++ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf,
> gss_buffer_t gssmic)
> ++{
> ++ if (ctx == NULL)
> ++ return -1;
> ++
> ++ ctx->major = gss_verify_mic(&ctx->minor, ctx->context,
> ++ gssbuf, gssmic, NULL);
> ++
> ++ return (ctx->major);
> ++}
> ++
> + void
> + ssh_gssapi_buildmic(Buffer *b, const char *user, const char
> *service,
> + const char *context)
> +@@ -254,6 +418,10 @@
> + gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
> + OM_uint32 major, minor;
> + gss_OID_desc spnego_oid = {6, (void *)"\x2B\x06\x01\x05\x05\x02"};
> ++ Gssctxt *intctx = NULL;
> ++
> ++ if (ctx == NULL)
> ++ ctx = &intctx;
> +
> + /* RFC 4462 says we MUST NOT do SPNEGO */
> + if (oid->length == spnego_oid.length &&
> +@@ -272,7 +440,7 @@
> + GSS_C_NO_BUFFER);
> + }
> +
> +- if (GSS_ERROR(major))
> ++ if (GSS_ERROR(major) || intctx != NULL)
> + ssh_gssapi_delete_ctx(ctx);
> +
> + return (!GSS_ERROR(major));
> +Index: gss-serv-krb5.c
> +===================================================================
> +RCS file: /cvs/openssh/gss-serv-krb5.c,v
> +retrieving revision 1.17
> +diff -u -r1.17 gss-serv-krb5.c
> +--- gss-serv-krb5.c 1 Sep 2006 05:38:36 -0000 1.17
> ++++ gss-serv-krb5.c 4 Apr 2008 12:52:29 -0000
> +@@ -120,6 +120,7 @@
> + krb5_principal princ;
> + OM_uint32 maj_status, min_status;
> + int len;
> ++ const char *new_ccname;
> +
> + if (client->creds == NULL) {
> + debug("No credentials stored");
> +@@ -168,11 +169,16 @@
> + return;
> + }
> +
> +- client->store.filename = xstrdup(krb5_cc_get_name(krb_context,
> ccache));
> ++ new_ccname = krb5_cc_get_name(krb_context, ccache);
> ++
> + client->store.envvar = "KRB5CCNAME";
> +- len = strlen(client->store.filename) + 6;
> +- client->store.envval = xmalloc(len);
> +- snprintf(client->store.envval, len, "FILE:%s", client-
> >store.filename);
> ++#ifdef USE_CCAPI
> ++ xasprintf(&client->store.envval, "API:%s", new_ccname);
> ++ client->store.filename = NULL;
> ++#else
> ++ xasprintf(&client->store.envval, "FILE:%s", new_ccname);
> ++ client->store.filename = xstrdup(new_ccname);
> ++#endif
> +
> + #ifdef USE_PAM
> + if (options.use_pam)
> +Index: gss-serv.c
> +===================================================================
> +RCS file: /cvs/openssh/gss-serv.c,v
> +retrieving revision 1.23
> +diff -u -r1.23 gss-serv.c
> +--- gss-serv.c 12 Jun 2007 13:40:39 -0000 1.23
> ++++ gss-serv.c 4 Apr 2008 12:52:29 -0000
> +@@ -1,7 +1,7 @@
> + /* $OpenBSD: gss-serv.c,v 1.21 2007/06/12 08:20:00 djm Exp $ */
> +
> + /*
> +- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
> ++ * Copyright (c) 2001-2008 Simon Wilkinson. All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or
> without
> + * modification, are permitted provided that the following
> conditions
> +@@ -44,8 +44,12 @@
> + #include "channels.h"
> + #include "session.h"
> + #include "misc.h"
> ++#include "servconf.h"
> +
> + #include "ssh-gss.h"
> ++#include "monitor_wrap.h"
> ++
> ++extern ServerOptions options;
> +
> + static ssh_gssapi_client gssapi_client =
> + { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER,
> +@@ -80,25 +84,32 @@
> + char lname[MAXHOSTNAMELEN];
> + gss_OID_set oidset;
> +
> +- gss_create_empty_oid_set(&status, &oidset);
> +- gss_add_oid_set_member(&status, ctx->oid, &oidset);
> ++ if (options.gss_strict_acceptor) {
> ++ gss_create_empty_oid_set(&status, &oidset);
> ++ gss_add_oid_set_member(&status, ctx->oid, &oidset);
> ++
> ++ if (gethostname(lname, MAXHOSTNAMELEN)) {
> ++ gss_release_oid_set(&status, &oidset);
> ++ return (-1);
> ++ }
> +
> +- if (gethostname(lname, MAXHOSTNAMELEN)) {
> +- gss_release_oid_set(&status, &oidset);
> +- return (-1);
> +- }
> ++ if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) {
> ++ gss_release_oid_set(&status, &oidset);
> ++ return (ctx->major);
> ++ }
> ++
> ++ if ((ctx->major = gss_acquire_cred(&ctx->minor,
> ++ ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds,
> ++ NULL, NULL)))
> ++ ssh_gssapi_error(ctx);
> +
> +- if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) {
> + gss_release_oid_set(&status, &oidset);
> + return (ctx->major);
> ++ } else {
> ++ ctx->name = GSS_C_NO_NAME;
> ++ ctx->creds = GSS_C_NO_CREDENTIAL;
> + }
> +-
> +- if ((ctx->major = gss_acquire_cred(&ctx->minor,
> +- ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, NULL, NULL)))
> +- ssh_gssapi_error(ctx);
> +-
> +- gss_release_oid_set(&status, &oidset);
> +- return (ctx->major);
> ++ return GSS_S_COMPLETE;
> + }
> +
> + /* Privileged */
> +@@ -113,6 +124,28 @@
> + }
> +
> + /* Unprivileged */
> ++char *
> ++ssh_gssapi_server_mechanisms() {
> ++ gss_OID_set supported;
> ++
> ++ ssh_gssapi_supported_oids(&supported);
> ++ return (ssh_gssapi_kex_mechs(supported,
> &ssh_gssapi_server_check_mech,
> ++ NULL));
> ++}
> ++
> ++/* Unprivileged */
> ++int
> ++ssh_gssapi_server_check_mech(Gssctxt **dum, gss_OID oid, const
> char *data) {
> ++ Gssctxt *ctx = NULL;
> ++ int res;
> ++
> ++ res = !GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctx, oid)));
> ++ ssh_gssapi_delete_ctx(&ctx);
> ++
> ++ return (res);
> ++}
> ++
> ++/* Unprivileged */
> + void
> + ssh_gssapi_supported_oids(gss_OID_set *oidset)
> + {
> +@@ -349,16 +382,6 @@
> + else
> + debug("ssh_gssapi_userok: Unknown GSSAPI mechanism");
> + return (0);
> +-}
> +-
> +-/* Privileged */
> +-OM_uint32
> +-ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf,
> gss_buffer_t gssmic)
> +-{
> +- ctx->major = gss_verify_mic(&ctx->minor, ctx->context,
> +- gssbuf, gssmic, NULL);
> +-
> +- return (ctx->major);
> + }
> +
> + #endif
> +Index: kex.c
> +===================================================================
> +RCS file: /cvs/openssh/kex.c,v
> +retrieving revision 1.86
> +diff -u -r1.86 kex.c
> +--- kex.c 5 Jun 2007 08:30:18 -0000 1.86
> ++++ kex.c 4 Apr 2008 12:52:29 -0000
> +@@ -49,6 +49,10 @@
> + #include "dispatch.h"
> + #include "monitor.h"
> +
> ++#ifdef GSSAPI
> ++#include "ssh-gss.h"
> ++#endif
> ++
> + #define KEX_COOKIE_LEN 16
> +
> + #if OPENSSL_VERSION_NUMBER >= 0x00907000L
> +@@ -326,6 +330,20 @@
> + } else if (strcmp(k->name, KEX_DHGEX_SHA256) == 0) {
> + k->kex_type = KEX_DH_GEX_SHA256;
> + k->evp_md = evp_ssh_sha256();
> ++#endif
> ++#ifdef GSSAPI
> ++ } else if (strncmp(k->name, KEX_GSS_GEX_SHA1_ID,
> ++ sizeof(KEX_GSS_GEX_SHA1_ID) - 1) == 0) {
> ++ k->kex_type = KEX_GSS_GEX_SHA1;
> ++ k->evp_md = EVP_sha1();
> ++ } else if (strncmp(k->name, KEX_GSS_GRP1_SHA1_ID,
> ++ sizeof(KEX_GSS_GRP1_SHA1_ID) - 1) == 0) {
> ++ k->kex_type = KEX_GSS_GRP1_SHA1;
> ++ k->evp_md = EVP_sha1();
> ++ } else if (strncmp(k->name, KEX_GSS_GRP14_SHA1_ID,
> ++ sizeof(KEX_GSS_GRP14_SHA1_ID) - 1) == 0) {
> ++ k->kex_type = KEX_GSS_GRP14_SHA1;
> ++ k->evp_md = EVP_sha1();
> + #endif
> + } else
> + fatal("bad kex alg %s", k->name);
> +Index: kex.h
> +===================================================================
> +RCS file: /cvs/openssh/kex.h,v
> +retrieving revision 1.49
> +diff -u -r1.49 kex.h
> +--- kex.h 11 Jun 2007 04:01:42 -0000 1.49
> ++++ kex.h 4 Apr 2008 12:52:29 -0000
> +@@ -64,6 +64,9 @@
> + KEX_DH_GRP14_SHA1,
> + KEX_DH_GEX_SHA1,
> + KEX_DH_GEX_SHA256,
> ++ KEX_GSS_GRP1_SHA1,
> ++ KEX_GSS_GRP14_SHA1,
> ++ KEX_GSS_GEX_SHA1,
> + KEX_MAX
> + };
> +
> +@@ -119,6 +122,11 @@
> + sig_atomic_t done;
> + int flags;
> + const EVP_MD *evp_md;
> ++#ifdef GSSAPI
> ++ int gss_deleg_creds;
> ++ int gss_trust_dns;
> ++ char *gss_host;
> ++#endif
> + char *client_version_string;
> + char *server_version_string;
> + int (*verify_host_key)(Key *);
> +@@ -140,6 +148,11 @@
> + void kexdh_server(Kex *);
> + void kexgex_client(Kex *);
> + void kexgex_server(Kex *);
> ++
> ++#ifdef GSSAPI
> ++void kexgss_client(Kex *);
> ++void kexgss_server(Kex *);
> ++#endif
> +
> + void
> + kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int,
> +Index: kexgssc.c
> +===================================================================
> +RCS file: kexgssc.c
> +diff -N kexgssc.c
> +--- /dev/null 1 Jan 1970 00:00:00 -0000
> ++++ kexgssc.c 4 Apr 2008 12:52:29 -0000
> +@@ -0,0 +1,319 @@
> ++/*
> ++ * Copyright (c) 2001-2006 Simon Wilkinson. All rights reserved.
> ++ *
> ++ * Redistribution and use in source and binary forms, with or
> without
> ++ * modification, are permitted provided that the following
> conditions
> ++ * are met:
> ++ * 1. Redistributions of source code must retain the above copyright
> ++ * notice, this list of conditions and the following disclaimer.
> ++ * 2. Redistributions in binary form must reproduce the above
> copyright
> ++ * notice, this list of conditions and the following disclaimer
> in the
> ++ * documentation and/or other materials provided with the
> distribution.
> ++ *
> ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY
> EXPRESS OR
> ++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
> WARRANTIES
> ++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> DISCLAIMED.
> ++ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
> ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
> (INCLUDING, BUT
> ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> LOSS OF USE,
> ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> ON ANY
> ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
> TORT
> ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
> THE USE OF
> ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> ++ */
> ++
> ++#include "includes.h"
> ++
> ++#ifdef GSSAPI
> ++
> ++#include "includes.h"
> ++
> ++#include <openssl/crypto.h>
> ++#include <openssl/bn.h>
> ++
> ++#include <string.h>
> ++
> ++#include "xmalloc.h"
> ++#include "buffer.h"
> ++#include "ssh2.h"
> ++#include "key.h"
> ++#include "cipher.h"
> ++#include "kex.h"
> ++#include "log.h"
> ++#include "packet.h"
> ++#include "dh.h"
> ++
> ++#include "ssh-gss.h"
> ++
> ++void
> ++kexgss_client(Kex *kex) {
> ++ gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
> ++ gss_buffer_desc recv_tok, gssbuf, msg_tok, *token_ptr;
> ++ Gssctxt *ctxt;
> ++ OM_uint32 maj_status, min_status, ret_flags;
> ++ u_int klen, kout, slen = 0, hashlen, strlen;
> ++ DH *dh;
> ++ BIGNUM *dh_server_pub = NULL;
> ++ BIGNUM *shared_secret = NULL;
> ++ BIGNUM *p = NULL;
> ++ BIGNUM *g = NULL;
> ++ u_char *kbuf, *hash;
> ++ u_char *serverhostkey = NULL;
> ++ char *msg;
> ++ char *lang;
> ++ int type = 0;
> ++ int first = 1;
> ++ int nbits = 0, min = DH_GRP_MIN, max = DH_GRP_MAX;
> ++
> ++ /* Initialise our GSSAPI world */
> ++ ssh_gssapi_build_ctx(&ctxt);
> ++ if (ssh_gssapi_id_kex(ctxt, kex->name, kex->kex_type)
> ++ == GSS_C_NO_OID)
> ++ fatal("Couldn't identify host exchange");
> ++
> ++ if (ssh_gssapi_import_name(ctxt, kex->gss_host))
> ++ fatal("Couldn't import hostname");
> ++
> ++ switch (kex->kex_type) {
> ++ case KEX_GSS_GRP1_SHA1:
> ++ dh = dh_new_group1();
> ++ break;
> ++ case KEX_GSS_GRP14_SHA1:
> ++ dh = dh_new_group14();
> ++ break;
> ++ case KEX_GSS_GEX_SHA1:
> ++ debug("Doing group exchange\n");
> ++ nbits = dh_estimate(kex->we_need * 8);
> ++ packet_start(SSH2_MSG_KEXGSS_GROUPREQ);
> ++ packet_put_int(min);
> ++ packet_put_int(nbits);
> ++ packet_put_int(max);
> ++
> ++ packet_send();
> ++
> ++ packet_read_expect(SSH2_MSG_KEXGSS_GROUP);
> ++
> ++ if ((p = BN_new()) == NULL)
> ++ fatal("BN_new() failed");
> ++ packet_get_bignum2(p);
> ++ if ((g = BN_new()) == NULL)
> ++ fatal("BN_new() failed");
> ++ packet_get_bignum2(g);
> ++ packet_check_eom();
> ++
> ++ if (BN_num_bits(p) < min || BN_num_bits(p) > max)
> ++ fatal("GSSGRP_GEX group out of range: %d !< %d !< %d",
> ++ min, BN_num_bits(p), max);
> ++
> ++ dh = dh_new_group(g, p);
> ++ break;
> ++ default:
> ++ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
> ++ }
> ++
> ++ /* Step 1 - e is dh->pub_key */
> ++ dh_gen_key(dh, kex->we_need * 8);
> ++
> ++ /* This is f, we initialise it now to make life easier */
> ++ dh_server_pub = BN_new();
> ++ if (dh_server_pub == NULL)
> ++ fatal("dh_server_pub == NULL");
> ++
> ++ token_ptr = GSS_C_NO_BUFFER;
> ++
> ++ do {
> ++ debug("Calling gss_init_sec_context");
> ++
> ++ maj_status = ssh_gssapi_init_ctx(ctxt,
> ++ kex->gss_deleg_creds, token_ptr, &send_tok,
> ++ &ret_flags);
> ++
> ++ if (GSS_ERROR(maj_status)) {
> ++ if (send_tok.length != 0) {
> ++ packet_start(SSH2_MSG_KEXGSS_CONTINUE);
> ++ packet_put_string(send_tok.value,
> ++ send_tok.length);
> ++ }
> ++ fatal("gss_init_context failed");
> ++ }
> ++
> ++ /* If we've got an old receive buffer get rid of it */
> ++ if (token_ptr != GSS_C_NO_BUFFER)
> ++ xfree(recv_tok.value);
> ++
> ++ if (maj_status == GSS_S_COMPLETE) {
> ++ /* If mutual state flag is not true, kex fails */
> ++ if (!(ret_flags & GSS_C_MUTUAL_FLAG))
> ++ fatal("Mutual authentication failed");
> ++
> ++ /* If integ avail flag is not true kex fails */
> ++ if (!(ret_flags & GSS_C_INTEG_FLAG))
> ++ fatal("Integrity check failed");
> ++ }
> ++
> ++ /*
> ++ * If we have data to send, then the last message that we
> ++ * received cannot have been a 'complete'.
> ++ */
> ++ if (send_tok.length != 0) {
> ++ if (first) {
> ++ packet_start(SSH2_MSG_KEXGSS_INIT);
> ++ packet_put_string(send_tok.value,
> ++ send_tok.length);
> ++ packet_put_bignum2(dh->pub_key);
> ++ first = 0;
> ++ } else {
> ++ packet_start(SSH2_MSG_KEXGSS_CONTINUE);
> ++ packet_put_string(send_tok.value,
> ++ send_tok.length);
> ++ }
> ++ packet_send();
> ++ gss_release_buffer(&min_status, &send_tok);
> ++
> ++ /* If we've sent them data, they should reply */
> ++ do {
> ++ type = packet_read();
> ++ if (type == SSH2_MSG_KEXGSS_HOSTKEY) {
> ++ debug("Received KEXGSS_HOSTKEY");
> ++ if (serverhostkey)
> ++ fatal("Server host key received more than once");
> ++ serverhostkey =
> ++ packet_get_string(&slen);
> ++ }
> ++ } while (type == SSH2_MSG_KEXGSS_HOSTKEY);
> ++
> ++ switch (type) {
> ++ case SSH2_MSG_KEXGSS_CONTINUE:
> ++ debug("Received GSSAPI_CONTINUE");
> ++ if (maj_status == GSS_S_COMPLETE)
> ++ fatal("GSSAPI Continue received from server when complete");
> ++ recv_tok.value = packet_get_string(&strlen);
> ++ recv_tok.length = strlen;
> ++ break;
> ++ case SSH2_MSG_KEXGSS_COMPLETE:
> ++ debug("Received GSSAPI_COMPLETE");
> ++ packet_get_bignum2(dh_server_pub);
> ++ msg_tok.value = packet_get_string(&strlen);
> ++ msg_tok.length = strlen;
> ++
> ++ /* Is there a token included? */
> ++ if (packet_get_char()) {
> ++ recv_tok.value=
> ++ packet_get_string(&strlen);
> ++ recv_tok.length = strlen;
> ++ /* If we're already complete - protocol error */
> ++ if (maj_status == GSS_S_COMPLETE)
> ++ packet_disconnect("Protocol error: received token when
> complete");
> ++ } else {
> ++ /* No token included */
> ++ if (maj_status != GSS_S_COMPLETE)
> ++ packet_disconnect("Protocol error: did not receive final
> token");
> ++ }
> ++ break;
> ++ case SSH2_MSG_KEXGSS_ERROR:
> ++ debug("Received Error");
> ++ maj_status = packet_get_int();
> ++ min_status = packet_get_int();
> ++ msg = packet_get_string(NULL);
> ++ lang = packet_get_string(NULL);
> ++ fatal("GSSAPI Error: \n%.400s",msg);
> ++ default:
> ++ packet_disconnect("Protocol error: didn't expect packet type
> %d",
> ++ type);
> ++ }
> ++ token_ptr = &recv_tok;
> ++ } else {
> ++ /* No data, and not complete */
> ++ if (maj_status != GSS_S_COMPLETE)
> ++ fatal("Not complete, and no token output");
> ++ }
> ++ } while (maj_status & GSS_S_CONTINUE_NEEDED);
> ++
> ++ /*
> ++ * We _must_ have received a COMPLETE message in reply from the
> ++ * server, which will have set dh_server_pub and msg_tok
> ++ */
> ++
> ++ if (type != SSH2_MSG_KEXGSS_COMPLETE)
> ++ fatal("Didn't receive a SSH2_MSG_KEXGSS_COMPLETE when I expected
> it");
> ++
> ++ /* Check f in range [1, p-1] */
> ++ if (!dh_pub_is_valid(dh, dh_server_pub))
> ++ packet_disconnect("bad server public DH value");
> ++
> ++ /* compute K=f^x mod p */
> ++ klen = DH_size(dh);
> ++ kbuf = xmalloc(klen);
> ++ kout = DH_compute_key(kbuf, dh_server_pub, dh);
> ++
> ++ shared_secret = BN_new();
> ++ BN_bin2bn(kbuf,kout, shared_secret);
> ++ memset(kbuf, 0, klen);
> ++ xfree(kbuf);
> ++
> ++ switch (kex->kex_type) {
> ++ case KEX_GSS_GRP1_SHA1:
> ++ case KEX_GSS_GRP14_SHA1:
> ++ kex_dh_hash( kex->client_version_string,
> ++ kex->server_version_string,
> ++ buffer_ptr(&kex->my), buffer_len(&kex->my),
> ++ buffer_ptr(&kex->peer), buffer_len(&kex->peer),
> ++ serverhostkey, slen, /* server host key */
> ++ dh->pub_key, /* e */
> ++ dh_server_pub, /* f */
> ++ shared_secret, /* K */
> ++ &hash, &hashlen
> ++ );
> ++ break;
> ++ case KEX_GSS_GEX_SHA1:
> ++ kexgex_hash(
> ++ kex->evp_md,
> ++ kex->client_version_string,
> ++ kex->server_version_string,
> ++ buffer_ptr(&kex->my), buffer_len(&kex->my),
> ++ buffer_ptr(&kex->peer), buffer_len(&kex->peer),
> ++ serverhostkey, slen,
> ++ min, nbits, max,
> ++ dh->p, dh->g,
> ++ dh->pub_key,
> ++ dh_server_pub,
> ++ shared_secret,
> ++ &hash, &hashlen
> ++ );
> ++ break;
> ++ default:
> ++ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
> ++ }
> ++
> ++ gssbuf.value = hash;
> ++ gssbuf.length = hashlen;
> ++
> ++ /* Verify that the hash matches the MIC we just got. */
> ++ if (GSS_ERROR(ssh_gssapi_checkmic(ctxt, &gssbuf, &msg_tok)))
> ++ packet_disconnect("Hash's MIC didn't verify");
> ++
> ++ xfree(msg_tok.value);
> ++
> ++ DH_free(dh);
> ++ if (serverhostkey)
> ++ xfree(serverhostkey);
> ++ BN_clear_free(dh_server_pub);
> ++
> ++ /* save session id */
> ++ if (kex->session_id == NULL) {
> ++ kex->session_id_len = hashlen;
> ++ kex->session_id = xmalloc(kex->session_id_len);
> ++ memcpy(kex->session_id, hash, kex->session_id_len);
> ++ }
> ++
> ++ if (gss_kex_context == NULL)
> ++ gss_kex_context = ctxt;
> ++ else
> ++ ssh_gssapi_delete_ctx(&ctxt);
> ++
> ++ kex_derive_keys(kex, hash, hashlen, shared_secret);
> ++ BN_clear_free(shared_secret);
> ++ kex_finish(kex);
> ++}
> ++
> ++#endif /* GSSAPI */
> +Index: kexgsss.c
> +===================================================================
> +RCS file: kexgsss.c
> +diff -N kexgsss.c
> +--- /dev/null 1 Jan 1970 00:00:00 -0000
> ++++ kexgsss.c 4 Apr 2008 12:52:29 -0000
> +@@ -0,0 +1,271 @@
> ++/*
> ++ * Copyright (c) 2001-2006 Simon Wilkinson. All rights reserved.
> ++ *
> ++ * Redistribution and use in source and binary forms, with or
> without
> ++ * modification, are permitted provided that the following
> conditions
> ++ * are met:
> ++ * 1. Redistributions of source code must retain the above copyright
> ++ * notice, this list of conditions and the following disclaimer.
> ++ * 2. Redistributions in binary form must reproduce the above
> copyright
> ++ * notice, this list of conditions and the following disclaimer
> in the
> ++ * documentation and/or other materials provided with the
> distribution.
> ++ *
> ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY
> EXPRESS OR
> ++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
> WARRANTIES
> ++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> DISCLAIMED.
> ++ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
> ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
> (INCLUDING, BUT
> ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> LOSS OF USE,
> ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> ON ANY
> ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
> TORT
> ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
> THE USE OF
> ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> ++ */
> ++
> ++#include "includes.h"
> ++
> ++#ifdef GSSAPI
> ++
> ++#include <string.h>
> ++
> ++#include <openssl/crypto.h>
> ++#include <openssl/bn.h>
> ++
> ++#include "xmalloc.h"
> ++#include "buffer.h"
> ++#include "ssh2.h"
> ++#include "key.h"
> ++#include "cipher.h"
> ++#include "kex.h"
> ++#include "log.h"
> ++#include "packet.h"
> ++#include "dh.h"
> ++#include "ssh-gss.h"
> ++#include "monitor_wrap.h"
> ++
> ++void
> ++kexgss_server(Kex *kex)
> ++{
> ++ OM_uint32 maj_status, min_status;
> ++
> ++ /*
> ++ * Some GSSAPI implementations use the input value of ret_flags (an
> ++ * output variable) as a means of triggering mechanism specific
> ++ * features. Initializing it to zero avoids inadvertently
> ++ * activating this non-standard behaviour.
> ++ */
> ++
> ++ OM_uint32 ret_flags = 0;
> ++ gss_buffer_desc gssbuf, recv_tok, msg_tok;
> ++ gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
> ++ Gssctxt *ctxt = NULL;
> ++ u_int slen, klen, kout, hashlen;
> ++ u_char *kbuf, *hash;
> ++ DH *dh;
> ++ int min = -1, max = -1, nbits = -1;
> ++ BIGNUM *shared_secret = NULL;
> ++ BIGNUM *dh_client_pub = NULL;
> ++ int type = 0;
> ++ gss_OID oid;
> ++
> ++ /* Initialise GSSAPI */
> ++
> ++ /* If we're rekeying, privsep means that some of the private
> structures
> ++ * in the GSSAPI code are no longer available. This kludges them
> back
> ++ * into life
> ++ */
> ++ if (!ssh_gssapi_oid_table_ok())
> ++ ssh_gssapi_server_mechanisms();
> ++
> ++ debug2("%s: Identifying %s", __func__, kex->name);
> ++ oid = ssh_gssapi_id_kex(NULL, kex->name, kex->kex_type);
> ++ if (oid == GSS_C_NO_OID)
> ++ fatal("Unknown gssapi mechanism");
> ++
> ++ debug2("%s: Acquiring credentials", __func__);
> ++
> ++ if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid))))
> ++ fatal("Unable to acquire credentials for the server");
> ++
> ++ switch (kex->kex_type) {
> ++ case KEX_GSS_GRP1_SHA1:
> ++ dh = dh_new_group1();
> ++ break;
> ++ case KEX_GSS_GRP14_SHA1:
> ++ dh = dh_new_group14();
> ++ break;
> ++ case KEX_GSS_GEX_SHA1:
> ++ debug("Doing group exchange");
> ++ packet_read_expect(SSH2_MSG_KEXGSS_GROUPREQ);
> ++ min = packet_get_int();
> ++ nbits = packet_get_int();
> ++ max = packet_get_int();
> ++ min = MAX(DH_GRP_MIN, min);
> ++ max = MIN(DH_GRP_MAX, max);
> ++ packet_check_eom();
> ++ if (max < min || nbits < min || max < nbits)
> ++ fatal("GSS_GEX, bad parameters: %d !< %d !< %d",
> ++ min, nbits, max);
> ++ dh = PRIVSEP(choose_dh(min, nbits, max));
> ++ if (dh == NULL)
> ++ packet_disconnect("Protocol error: no matching group found");
> ++
> ++ packet_start(SSH2_MSG_KEXGSS_GROUP);
> ++ packet_put_bignum2(dh->p);
> ++ packet_put_bignum2(dh->g);
> ++ packet_send();
> ++
> ++ packet_write_wait();
> ++ break;
> ++ default:
> ++ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
> ++ }
> ++
> ++ dh_gen_key(dh, kex->we_need * 8);
> ++
> ++ do {
> ++ debug("Wait SSH2_MSG_GSSAPI_INIT");
> ++ type = packet_read();
> ++ switch(type) {
> ++ case SSH2_MSG_KEXGSS_INIT:
> ++ if (dh_client_pub != NULL)
> ++ fatal("Received KEXGSS_INIT after initialising");
> ++ recv_tok.value = packet_get_string(&slen);
> ++ recv_tok.length = slen;
> ++
> ++ if ((dh_client_pub = BN_new()) == NULL)
> ++ fatal("dh_client_pub == NULL");
> ++
> ++ packet_get_bignum2(dh_client_pub);
> ++
> ++ /* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */
> ++ break;
> ++ case SSH2_MSG_KEXGSS_CONTINUE:
> ++ recv_tok.value = packet_get_string(&slen);
> ++ recv_tok.length = slen;
> ++ break;
> ++ default:
> ++ packet_disconnect(
> ++ "Protocol error: didn't expect packet type %d",
> ++ type);
> ++ }
> ++
> ++ maj_status = PRIVSEP(ssh_gssapi_accept_ctx(ctxt, &recv_tok,
> ++ &send_tok, &ret_flags));
> ++
> ++ xfree(recv_tok.value);
> ++
> ++ if (maj_status != GSS_S_COMPLETE && send_tok.length == 0)
> ++ fatal("Zero length token output when incomplete");
> ++
> ++ if (dh_client_pub == NULL)
> ++ fatal("No client public key");
> ++
> ++ if (maj_status & GSS_S_CONTINUE_NEEDED) {
> ++ debug("Sending GSSAPI_CONTINUE");
> ++ packet_start(SSH2_MSG_KEXGSS_CONTINUE);
> ++ packet_put_string(send_tok.value, send_tok.length);
> ++ packet_send();
> ++ gss_release_buffer(&min_status, &send_tok);
> ++ }
> ++ } while (maj_status & GSS_S_CONTINUE_NEEDED);
> ++
> ++ if (GSS_ERROR(maj_status)) {
> ++ if (send_tok.length > 0) {
> ++ packet_start(SSH2_MSG_KEXGSS_CONTINUE);
> ++ packet_put_string(send_tok.value, send_tok.length);
> ++ packet_send();
> ++ }
> ++ fatal("accept_ctx died");
> ++ }
> ++
> ++ if (!(ret_flags & GSS_C_MUTUAL_FLAG))
> ++ fatal("Mutual Authentication flag wasn't set");
> ++
> ++ if (!(ret_flags & GSS_C_INTEG_FLAG))
> ++ fatal("Integrity flag wasn't set");
> ++
> ++ if (!dh_pub_is_valid(dh, dh_client_pub))
> ++ packet_disconnect("bad client public DH value");
> ++
> ++ klen = DH_size(dh);
> ++ kbuf = xmalloc(klen);
> ++ kout = DH_compute_key(kbuf, dh_client_pub, dh);
> ++
> ++ shared_secret = BN_new();
> ++ BN_bin2bn(kbuf, kout, shared_secret);
> ++ memset(kbuf, 0, klen);
> ++ xfree(kbuf);
> ++
> ++ switch (kex->kex_type) {
> ++ case KEX_GSS_GRP1_SHA1:
> ++ case KEX_GSS_GRP14_SHA1:
> ++ kex_dh_hash(
> ++ kex->client_version_string, kex->server_version_string,
> ++ buffer_ptr(&kex->peer), buffer_len(&kex->peer),
> ++ buffer_ptr(&kex->my), buffer_len(&kex->my),
> ++ NULL, 0, /* Change this if we start sending host keys */
> ++ dh_client_pub, dh->pub_key, shared_secret,
> ++ &hash, &hashlen
> ++ );
> ++ break;
> ++ case KEX_GSS_GEX_SHA1:
> ++ kexgex_hash(
> ++ kex->evp_md,
> ++ kex->client_version_string, kex->server_version_string,
> ++ buffer_ptr(&kex->peer), buffer_len(&kex->peer),
> ++ buffer_ptr(&kex->my), buffer_len(&kex->my),
> ++ NULL, 0,
> ++ min, nbits, max,
> ++ dh->p, dh->g,
> ++ dh_client_pub,
> ++ dh->pub_key,
> ++ shared_secret,
> ++ &hash, &hashlen
> ++ );
> ++ break;
> ++ default:
> ++ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
> ++ }
> ++
> ++ BN_free(dh_client_pub);
> ++
> ++ if (kex->session_id == NULL) {
> ++ kex->session_id_len = hashlen;
> ++ kex->session_id = xmalloc(kex->session_id_len);
> ++ memcpy(kex->session_id, hash, kex->session_id_len);
> ++ }
> ++
> ++ gssbuf.value = hash;
> ++ gssbuf.length = hashlen;
> ++
> ++ if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(ctxt,&gssbuf,&msg_tok))))
> ++ fatal("Couldn't get MIC");
> ++
> ++ packet_start(SSH2_MSG_KEXGSS_COMPLETE);
> ++ packet_put_bignum2(dh->pub_key);
> ++ packet_put_string(msg_tok.value,msg_tok.length);
> ++
> ++ if (send_tok.length != 0) {
> ++ packet_put_char(1); /* true */
> ++ packet_put_string(send_tok.value, send_tok.length);
> ++ } else {
> ++ packet_put_char(0); /* false */
> ++ }
> ++ packet_send();
> ++
> ++ gss_release_buffer(&min_status, &send_tok);
> ++ gss_release_buffer(&min_status, &msg_tok);
> ++
> ++ if (gss_kex_context == NULL)
> ++ gss_kex_context = ctxt;
> ++ else
> ++ ssh_gssapi_delete_ctx(&ctxt);
> ++
> ++ DH_free(dh);
> ++
> ++ kex_derive_keys(kex, hash, hashlen, shared_secret);
> ++ BN_clear_free(shared_secret);
> ++ kex_finish(kex);
> ++}
> ++#endif /* GSSAPI */
> +Index: key.c
> +===================================================================
> +RCS file: /cvs/openssh/key.c,v
> +retrieving revision 1.72
> +diff -u -r1.72 key.c
> +--- key.c 28 Feb 2008 08:22:04 -0000 1.72
> ++++ key.c 4 Apr 2008 12:52:29 -0000
> +@@ -649,6 +649,8 @@
> + return KEY_RSA;
> + } else if (strcmp(name, "ssh-dss") == 0) {
> + return KEY_DSA;
> ++ } else if (strcmp(name, "null") == 0) {
> ++ return KEY_NULL;
> + }
> + debug2("key_type_from_name: unknown key type '%s'", name);
> + return KEY_UNSPEC;
> +Index: key.h
> +===================================================================
> +RCS file: /cvs/openssh/key.h,v
> +retrieving revision 1.28
> +diff -u -r1.28 key.h
> +--- key.h 5 Aug 2006 02:39:40 -0000 1.28
> ++++ key.h 4 Apr 2008 12:52:29 -0000
> +@@ -34,6 +34,7 @@
> + KEY_RSA1,
> + KEY_RSA,
> + KEY_DSA,
> ++ KEY_NULL,
> + KEY_UNSPEC
> + };
> + enum fp_type {
> +Index: monitor.c
> +===================================================================
> +RCS file: /cvs/openssh/monitor.c,v
> +retrieving revision 1.127
> +diff -u -r1.127 monitor.c
> +--- monitor.c 11 Mar 2008 11:58:25 -0000 1.127
> ++++ monitor.c 4 Apr 2008 12:52:29 -0000
> +@@ -163,6 +163,7 @@
> + int mm_answer_gss_accept_ctx(int, Buffer *);
> + int mm_answer_gss_userok(int, Buffer *);
> + int mm_answer_gss_checkmic(int, Buffer *);
> ++int mm_answer_gss_sign(int, Buffer *);
> + #endif
> +
> + #ifdef SSH_AUDIT_EVENTS
> +@@ -232,11 +233,17 @@
> + {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx},
> + {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok},
> + {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic},
> ++ {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign},
> + #endif
> + {0, 0, NULL}
> + };
> +
> + struct mon_table mon_dispatch_postauth20[] = {
> ++#ifdef GSSAPI
> ++ {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx},
> ++ {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx},
> ++ {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign},
> ++#endif
> + {MONITOR_REQ_MODULI, 0, mm_answer_moduli},
> + {MONITOR_REQ_SIGN, 0, mm_answer_sign},
> + {MONITOR_REQ_PTY, 0, mm_answer_pty},
> +@@ -341,6 +348,10 @@
> + /* Permit requests for moduli and signatures */
> + monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
> + monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
> ++#ifdef GSSAPI
> ++ /* and for the GSSAPI key exchange */
> ++ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1);
> ++#endif
> + } else {
> + mon_dispatch = mon_dispatch_proto15;
> +
> +@@ -418,6 +429,10 @@
> + monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
> + monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
> + monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
> ++#ifdef GSSAPI
> ++ /* and for the GSSAPI key exchange */
> ++ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1);
> ++#endif
> + } else {
> + mon_dispatch = mon_dispatch_postauth15;
> + monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
> +@@ -1670,6 +1685,11 @@
> + kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server;
> + kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
> + kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
> ++#ifdef GSSAPI
> ++ kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
> ++ kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
> ++ kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
> ++#endif
> + kex->server = 1;
> + kex->hostkey_type = buffer_get_int(m);
> + kex->kex_type = buffer_get_int(m);
> +@@ -1911,6 +1931,7 @@
> + monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0);
> + monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);
> + monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1);
> ++ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSIGN, 1);
> + }
> + return (0);
> + }
> +@@ -1961,4 +1982,42 @@
> + /* Monitor loop will terminate if authenticated */
> + return (authenticated);
> + }
> ++
> ++int
> ++mm_answer_gss_sign(int socket, Buffer *m)
> ++{
> ++ gss_buffer_desc data;
> ++ gss_buffer_desc hash = GSS_C_EMPTY_BUFFER;
> ++ OM_uint32 major, minor;
> ++ u_int len;
> ++
> ++ data.value = buffer_get_string(m, &len);
> ++ data.length = len;
> ++ if (data.length != 20)
> ++ fatal("%s: data length incorrect: %d", __func__, data.length);
> ++
> ++ /* Save the session ID on the first time around */
> ++ if (session_id2_len == 0) {
> ++ session_id2_len = data.length;
> ++ session_id2 = xmalloc(session_id2_len);
> ++ memcpy(session_id2, data.value, session_id2_len);
> ++ }
> ++ major = ssh_gssapi_sign(gsscontext, &data, &hash);
> ++
> ++ xfree(data.value);
> ++
> ++ buffer_clear(m);
> ++ buffer_put_int(m, major);
> ++ buffer_put_string(m, hash.value, hash.length);
> ++
> ++ mm_request_send(socket, MONITOR_ANS_GSSSIGN, m);
> ++
> ++ gss_release_buffer(&minor, &hash);
> ++
> ++ /* Turn on getpwnam permissions */
> ++ monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1);
> ++
> ++ return (0);
> ++}
> ++
> + #endif /* GSSAPI */
> +Index: monitor.h
> +===================================================================
> +RCS file: /cvs/openssh/monitor.h,v
> +retrieving revision 1.21
> +diff -u -r1.21 monitor.h
> +--- monitor.h 26 Mar 2006 03:30:02 -0000 1.21
> ++++ monitor.h 4 Apr 2008 12:52:29 -0000
> +@@ -53,6 +53,7 @@
> + MONITOR_REQ_GSSSTEP, MONITOR_ANS_GSSSTEP,
> + MONITOR_REQ_GSSUSEROK, MONITOR_ANS_GSSUSEROK,
> + MONITOR_REQ_GSSCHECKMIC, MONITOR_ANS_GSSCHECKMIC,
> ++ MONITOR_REQ_GSSSIGN, MONITOR_ANS_GSSSIGN,
> + MONITOR_REQ_PAM_START,
> + MONITOR_REQ_PAM_ACCOUNT, MONITOR_ANS_PAM_ACCOUNT,
> + MONITOR_REQ_PAM_INIT_CTX, MONITOR_ANS_PAM_INIT_CTX,
> +Index: monitor_wrap.c
> +===================================================================
> +RCS file: /cvs/openssh/monitor_wrap.c,v
> +retrieving revision 1.76
> +diff -u -r1.76 monitor_wrap.c
> +--- monitor_wrap.c 2 Dec 2007 12:02:15 -0000 1.76
> ++++ monitor_wrap.c 4 Apr 2008 12:52:29 -0000
> +@@ -1238,4 +1238,27 @@
> + debug3("%s: user %sauthenticated",__func__, authenticated ? "" :
> "not ");
> + return (authenticated);
> + }
> ++
> ++OM_uint32
> ++mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data,
> gss_buffer_desc *hash)
> ++{
> ++ Buffer m;
> ++ OM_uint32 major;
> ++ u_int len;
> ++
> ++ buffer_init(&m);
> ++ buffer_put_string(&m, data->value, data->length);
> ++
> ++ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSIGN, &m);
> ++ mm_request_receive_expect(pmonitor->m_recvfd,
> MONITOR_ANS_GSSSIGN, &m);
> ++
> ++ major = buffer_get_int(&m);
> ++ hash->value = buffer_get_string(&m, &len);
> ++ hash->length = len;
> ++
> ++ buffer_free(&m);
> ++
> ++ return(major);
> ++}
> ++
> + #endif /* GSSAPI */
> +Index: monitor_wrap.h
> +===================================================================
> +RCS file: /cvs/openssh/monitor_wrap.h,v
> +retrieving revision 1.27
> +diff -u -r1.27 monitor_wrap.h
> +--- monitor_wrap.h 5 Aug 2006 02:39:40 -0000 1.27
> ++++ monitor_wrap.h 4 Apr 2008 12:52:29 -0000
> +@@ -59,6 +59,7 @@
> + gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *);
> + int mm_ssh_gssapi_userok(char *user);
> + OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t,
> gss_buffer_t);
> ++OM_uint32 mm_ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t);
> + #endif
> +
> + #ifdef USE_PAM
> +Index: readconf.c
> +===================================================================
> +RCS file: /cvs/openssh/readconf.c,v
> +retrieving revision 1.142
> +diff -u -r1.142 readconf.c
> +--- readconf.c 10 Feb 2008 11:25:52 -0000 1.142
> ++++ readconf.c 4 Apr 2008 12:52:29 -0000
> +@@ -127,6 +127,8 @@
> + oClearAllForwardings, oNoHostAuthenticationForLocalhost,
> + oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
> + oAddressFamily, oGssAuthentication, oGssDelegateCreds,
> ++ oGssKeyEx,
> ++ oGssTrustDns,
> + oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
> + oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
> + oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
> +@@ -163,10 +165,14 @@
> + { "afstokenpassing", oUnsupported },
> + #if defined(GSSAPI)
> + { "gssapiauthentication", oGssAuthentication },
> ++ { "gssapikeyexchange", oGssKeyEx },
> + { "gssapidelegatecredentials", oGssDelegateCreds },
> ++ { "gssapitrustdns", oGssTrustDns },
> + #else
> + { "gssapiauthentication", oUnsupported },
> ++ { "gssapikeyexchange", oUnsupported },
> + { "gssapidelegatecredentials", oUnsupported },
> ++ { "gssapitrustdns", oUnsupported },
> + #endif
> + { "fallbacktorsh", oDeprecated },
> + { "usersh", oDeprecated },
> +@@ -442,10 +448,18 @@
> + intptr = &options->gss_authentication;
> + goto parse_flag;
> +
> ++ case oGssKeyEx:
> ++ intptr = &options->gss_keyex;
> ++ goto parse_flag;
> ++
> + case oGssDelegateCreds:
> + intptr = &options->gss_deleg_creds;
> + goto parse_flag;
> +
> ++ case oGssTrustDns:
> ++ intptr = &options->gss_trust_dns;
> ++ goto parse_flag;
> ++
> + case oBatchMode:
> + intptr = &options->batch_mode;
> + goto parse_flag;
> +@@ -1010,7 +1024,9 @@
> + options->pubkey_authentication = -1;
> + options->challenge_response_authentication = -1;
> + options->gss_authentication = -1;
> ++ options->gss_keyex = -1;
> + options->gss_deleg_creds = -1;
> ++ options->gss_trust_dns = -1;
> + options->password_authentication = -1;
> + options->kbd_interactive_authentication = -1;
> + options->kbd_interactive_devices = NULL;
> +@@ -1099,8 +1115,12 @@
> + options->challenge_response_authentication = 1;
> + if (options->gss_authentication == -1)
> + options->gss_authentication = 0;
> ++ if (options->gss_keyex == -1)
> ++ options->gss_keyex = 0;
> + if (options->gss_deleg_creds == -1)
> + options->gss_deleg_creds = 0;
> ++ if (options->gss_trust_dns == -1)
> ++ options->gss_trust_dns = 0;
> + if (options->password_authentication == -1)
> + options->password_authentication = 1;
> + if (options->kbd_interactive_authentication == -1)
> +Index: readconf.h
> +===================================================================
> +RCS file: /cvs/openssh/readconf.h,v
> +retrieving revision 1.64
> +diff -u -r1.64 readconf.h
> +--- readconf.h 10 Feb 2008 11:25:52 -0000 1.64
> ++++ readconf.h 4 Apr 2008 12:52:29 -0000
> +@@ -44,7 +44,9 @@
> + int challenge_response_authentication;
> + /* Try S/Key or TIS, authentication. */
> + int gss_authentication; /* Try GSS authentication */
> ++ int gss_keyex; /* Try GSS key exchange */
> + int gss_deleg_creds; /* Delegate GSS credentials */
> ++ int gss_trust_dns; /* Trust DNS for GSS canonicalization */
> + int password_authentication; /* Try password
> + * authentication. */
> + int kbd_interactive_authentication; /* Try keyboard-
> interactive auth. */
> +Index: servconf.c
> +===================================================================
> +RCS file: /cvs/openssh/servconf.c,v
> +retrieving revision 1.168
> +diff -u -r1.168 servconf.c
> +--- servconf.c 10 Feb 2008 11:48:55 -0000 1.168
> ++++ servconf.c 4 Apr 2008 12:52:30 -0000
> +@@ -90,7 +90,9 @@
> + options->kerberos_ticket_cleanup = -1;
> + options->kerberos_get_afs_token = -1;
> + options->gss_authentication=-1;
> ++ options->gss_keyex = -1;
> + options->gss_cleanup_creds = -1;
> ++ options->gss_strict_acceptor = -1;
> + options->password_authentication = -1;
> + options->kbd_interactive_authentication = -1;
> + options->challenge_response_authentication = -1;
> +@@ -205,8 +207,12 @@
> + options->kerberos_get_afs_token = 0;
> + if (options->gss_authentication == -1)
> + options->gss_authentication = 0;
> ++ if (options->gss_keyex == -1)
> ++ options->gss_keyex = 0;
> + if (options->gss_cleanup_creds == -1)
> + options->gss_cleanup_creds = 1;
> ++ if (options->gss_strict_acceptor == -1)
> ++ options->gss_strict_acceptor = 1;
> + if (options->password_authentication == -1)
> + options->password_authentication = 1;
> + if (options->kbd_interactive_authentication == -1)
> +@@ -291,7 +297,9 @@
> + sBanner, sUseDNS, sHostbasedAuthentication,
> + sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
> + sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
> +- sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
> ++ sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
> ++ sGssKeyEx,
> ++ sAcceptEnv, sPermitTunnel,
> + sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
> + sUsePrivilegeSeparation,
> + sDeprecated, sUnsupported
> +@@ -352,9 +360,13 @@
> + #ifdef GSSAPI
> + { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
> + { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
> ++ { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL },
> ++ { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL },
> + #else
> + { "gssapiauthentication", sUnsupported, SSHCFG_ALL },
> + { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
> ++ { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
> ++ { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL },
> + #endif
> + { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
> + { "kbdinteractiveauthentication", sKbdInteractiveAuthentication,
> SSHCFG_ALL },
> +@@ -875,8 +887,16 @@
> + intptr = &options->gss_authentication;
> + goto parse_flag;
> +
> ++ case sGssKeyEx:
> ++ intptr = &options->gss_keyex;
> ++ goto parse_flag;
> ++
> + case sGssCleanupCreds:
> + intptr = &options->gss_cleanup_creds;
> ++ goto parse_flag;
> ++
> ++ case sGssStrictAcceptor:
> ++ intptr = &options->gss_strict_acceptor;
> + goto parse_flag;
> +
> + case sPasswordAuthentication:
> +Index: servconf.h
> +===================================================================
> +RCS file: /cvs/openssh/servconf.h,v
> +retrieving revision 1.74
> +diff -u -r1.74 servconf.h
> +--- servconf.h 7 Mar 2008 07:31:24 -0000 1.74
> ++++ servconf.h 4 Apr 2008 12:52:30 -0000
> +@@ -90,7 +90,9 @@
> + int kerberos_get_afs_token; /* If true, try to get AFS token
> if
> + * authenticated with Kerberos. */
> + int gss_authentication; /* If true, permit GSSAPI
> authentication */
> ++ int gss_keyex; /* If true, permit GSSAPI key exchange */
> + int gss_cleanup_creds; /* If true, destroy cred cache on
> logout */
> ++ int gss_strict_acceptor; /* If true, restrict the GSSAPI
> acceptor name */
> + int password_authentication; /* If true, permit password
> + * authentication. */
> + int kbd_interactive_authentication; /* If true, permit */
> +Index: ssh-gss.h
> +===================================================================
> +RCS file: /cvs/openssh/ssh-gss.h,v
> +retrieving revision 1.12
> +diff -u -r1.12 ssh-gss.h
> +--- ssh-gss.h 12 Jun 2007 13:40:39 -0000 1.12
> ++++ ssh-gss.h 4 Apr 2008 12:52:30 -0000
> +@@ -60,6 +60,17 @@
> +
> + #define SSH_GSS_OIDTYPE 0x06
> +
> ++#define SSH2_MSG_KEXGSS_INIT 30
> ++#define SSH2_MSG_KEXGSS_CONTINUE 31
> ++#define SSH2_MSG_KEXGSS_COMPLETE 32
> ++#define SSH2_MSG_KEXGSS_HOSTKEY 33
> ++#define SSH2_MSG_KEXGSS_ERROR 34
> ++#define SSH2_MSG_KEXGSS_GROUPREQ 40
> ++#define SSH2_MSG_KEXGSS_GROUP 41
> ++#define KEX_GSS_GRP1_SHA1_ID "gss-group1-sha1-"
> ++#define KEX_GSS_GRP14_SHA1_ID "gss-group14-sha1-"
> ++#define KEX_GSS_GEX_SHA1_ID "gss-gex-sha1-"
> ++
> + typedef struct {
> + char *filename;
> + char *envvar;
> +@@ -97,6 +108,7 @@
> + } Gssctxt;
> +
> + extern ssh_gssapi_mech *supported_mechs[];
> ++extern Gssctxt *gss_kex_context;
> +
> + int ssh_gssapi_check_oid(Gssctxt *, void *, size_t);
> + void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t);
> +@@ -119,6 +131,11 @@
> + int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *);
> +
> + /* In the server */
> ++typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *);
> ++char *ssh_gssapi_client_mechanisms(const char *host);
> ++char *ssh_gssapi_kex_mechs(gss_OID_set, ssh_gssapi_check_fn *,
> const char *);
> ++gss_OID ssh_gssapi_id_kex(Gssctxt *, char *, int);
> ++int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *);
> + OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID);
> + int ssh_gssapi_userok(char *name);
> + OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t,
> gss_buffer_t);
> +@@ -126,6 +143,8 @@
> + void ssh_gssapi_cleanup_creds(void);
> + void ssh_gssapi_storecreds(void);
> +
> ++char *ssh_gssapi_server_mechanisms(void);
> ++int ssh_gssapi_oid_table_ok();
> + #endif /* GSSAPI */
> +
> + #endif /* _SSH_GSS_H */
> +Index: ssh_config
> +===================================================================
> +RCS file: /cvs/openssh/ssh_config,v
> +retrieving revision 1.25
> +diff -u -r1.25 ssh_config
> +--- ssh_config 11 Jun 2007 04:04:42 -0000 1.25
> ++++ ssh_config 4 Apr 2008 12:52:30 -0000
> +@@ -26,6 +26,8 @@
> + # HostbasedAuthentication no
> + # GSSAPIAuthentication no
> + # GSSAPIDelegateCredentials no
> ++# GSSAPIKeyExchange no
> ++# GSSAPITrustDNS no
> + # BatchMode no
> + # CheckHostIP yes
> + # AddressFamily any
> +Index: ssh_config.5
> +===================================================================
> +RCS file: /cvs/openssh/ssh_config.5,v
> +retrieving revision 1.105
> +diff -u -r1.105 ssh_config.5
> +--- ssh_config.5 2 Dec 2007 12:09:30 -0000 1.105
> ++++ ssh_config.5 4 Apr 2008 12:52:30 -0000
> +@@ -477,11 +477,28 @@
> + The default is
> + .Dq no .
> + Note that this option applies to protocol version 2 only.
> ++.It Cm GSSAPIKeyExchange
> ++Specifies whether key exchange based on GSSAPI may be used. When
> using
> ++GSSAPI key exchange the server need not have a host key.
> ++The default is
> ++.Dq no .
> ++Note that this option applies to protocol version 2 only.
> + .It Cm GSSAPIDelegateCredentials
> + Forward (delegate) credentials to the server.
> + The default is
> + .Dq no .
> + Note that this option applies to protocol version 2 only.
> ++.It Cm GSSAPITrustDns
> ++Set to
> ++.Dq yes
> ++to indicate that the DNS is trusted to securely canonicalize
> ++the name of the host being connected to. If
> ++.Dq no ,
> ++the hostname entered on the
> ++command line will be passed untouched to the GSSAPI library.
> ++The default is
> ++.Dq no .
> ++This option only applies to protocol version 2 connections using
> GSSAPI.
> + .It Cm HashKnownHosts
> + Indicates that
> + .Xr ssh 1
> +Index: sshconnect2.c
> +===================================================================
> +RCS file: /cvs/openssh/sshconnect2.c,v
> +retrieving revision 1.156
> +diff -u -r1.156 sshconnect2.c
> +--- sshconnect2.c 10 Feb 2008 11:25:53 -0000 1.156
> ++++ sshconnect2.c 4 Apr 2008 12:52:30 -0000
> +@@ -99,9 +99,34 @@
> + {
> + Kex *kex;
> +
> ++#ifdef GSSAPI
> ++ char *orig = NULL, *gss = NULL;
> ++ char *gss_host = NULL;
> ++#endif
> ++
> + xxx_host = host;
> + xxx_hostaddr = hostaddr;
> +
> ++#ifdef GSSAPI
> ++ if (options.gss_keyex) {
> ++ /* Add the GSSAPI mechanisms currently supported on this
> ++ * client to the key exchange algorithm proposal */
> ++ orig = myproposal[PROPOSAL_KEX_ALGS];
> ++
> ++ if (options.gss_trust_dns)
> ++ gss_host = (char *)get_canonical_hostname(1);
> ++ else
> ++ gss_host = host;
> ++
> ++ gss = ssh_gssapi_client_mechanisms(gss_host);
> ++ if (gss) {
> ++ debug("Offering GSSAPI proposal: %s", gss);
> ++ xasprintf(&myproposal[PROPOSAL_KEX_ALGS],
> ++ "%s,%s", gss, orig);
> ++ }
> ++ }
> ++#endif
> ++
> + if (options.ciphers == (char *)-1) {
> + logit("No valid ciphers for protocol version 2 given, using
> defaults.");
> + options.ciphers = NULL;
> +@@ -129,6 +154,16 @@
> + myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
> + options.hostkeyalgorithms;
> +
> ++#ifdef GSSAPI
> ++ /* If we've got GSSAPI algorithms, then we also support the
> ++ * 'null' hostkey, as a last resort */
> ++ if (options.gss_keyex && gss) {
> ++ orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS];
> ++ xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS],
> ++ "%s,null", orig);
> ++ }
> ++#endif
> ++
> + if (options.rekey_limit)
> + packet_set_rekey_limit((u_int32_t)options.rekey_limit);
> +
> +@@ -138,10 +173,21 @@
> + kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client;
> + kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
> + kex->kex[KEX_DH_GEX_SHA256] = kexgex_client;
> ++#ifdef GSSAPI
> ++ kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client;
> ++ kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_client;
> ++ kex->kex[KEX_GSS_GEX_SHA1] = kexgss_client;
> ++#endif
> + kex->client_version_string=client_version_string;
> + kex->server_version_string=server_version_string;
> + kex->verify_host_key=&verify_host_key_callback;
> +
> ++#ifdef GSSAPI
> ++ kex->gss_deleg_creds = options.gss_deleg_creds;
> ++ kex->gss_trust_dns = options.gss_trust_dns;
> ++ kex->gss_host = gss_host;
> ++#endif
> ++
> + xxx_kex = kex;
> +
> + dispatch_run(DISPATCH_BLOCK, &kex->done, kex);
> +@@ -224,6 +270,7 @@
> + void input_gssapi_hash(int type, u_int32_t, void *);
> + void input_gssapi_error(int, u_int32_t, void *);
> + void input_gssapi_errtok(int, u_int32_t, void *);
> ++int userauth_gsskeyex(Authctxt *authctxt);
> + #endif
> +
> + void userauth(Authctxt *, char *);
> +@@ -239,6 +286,10 @@
> +
> + Authmethod authmethods[] = {
> + #ifdef GSSAPI
> ++ {"gssapi-keyex",
> ++ userauth_gsskeyex,
> ++ &options.gss_authentication,
> ++ NULL},
> + {"gssapi-with-mic",
> + userauth_gssapi,
> + &options.gss_authentication,
> +@@ -501,6 +552,12 @@
> + static u_int mech = 0;
> + OM_uint32 min;
> + int ok = 0;
> ++ char *gss_host = NULL;
> ++
> ++ if (options.gss_trust_dns)
> ++ gss_host = (char *)get_canonical_hostname(1);
> ++ else
> ++ gss_host = (char *)authctxt->host;
> +
> + /* Try one GSSAPI method at a time, rather than sending them all at
> + * once. */
> +@@ -513,7 +570,7 @@
> + /* My DER encoding requires length<128 */
> + if (gss_supported->elements[mech].length < 128 &&
> + ssh_gssapi_check_mechanism(&gssctxt,
> +- &gss_supported->elements[mech], authctxt->host)) {
> ++ &gss_supported->elements[mech], gss_host)) {
> + ok = 1; /* Mechanism works */
> + } else {
> + mech++;
> +@@ -609,8 +666,8 @@
> + {
> + Authctxt *authctxt = ctxt;
> + Gssctxt *gssctxt;
> +- int oidlen;
> +- char *oidv;
> ++ u_int oidlen;
> ++ u_char *oidv;
> +
> + if (authctxt == NULL)
> + fatal("input_gssapi_response: no authentication context");
> +@@ -717,6 +774,48 @@
> + xfree(msg);
> + xfree(lang);
> + }
> ++
> ++int
> ++userauth_gsskeyex(Authctxt *authctxt)
> ++{
> ++ Buffer b;
> ++ gss_buffer_desc gssbuf;
> ++ gss_buffer_desc mic = GSS_C_EMPTY_BUFFER;
> ++ OM_uint32 ms;
> ++
> ++ static int attempt = 0;
> ++ if (attempt++ >= 1)
> ++ return (0);
> ++
> ++ if (gss_kex_context == NULL) {
> ++ debug("No valid Key exchange context");
> ++ return (0);
> ++ }
> ++
> ++ ssh_gssapi_buildmic(&b, authctxt->server_user, authctxt->service,
> ++ "gssapi-keyex");
> ++
> ++ gssbuf.value = buffer_ptr(&b);
> ++ gssbuf.length = buffer_len(&b);
> ++
> ++ if (GSS_ERROR(ssh_gssapi_sign(gss_kex_context, &gssbuf, &mic))) {
> ++ buffer_free(&b);
> ++ return (0);
> ++ }
> ++
> ++ packet_start(SSH2_MSG_USERAUTH_REQUEST);
> ++ packet_put_cstring(authctxt->server_user);
> ++ packet_put_cstring(authctxt->service);
> ++ packet_put_cstring(authctxt->method->name);
> ++ packet_put_string(mic.value, mic.length);
> ++ packet_send();
> ++
> ++ buffer_free(&b);
> ++ gss_release_buffer(&ms, &mic);
> ++
> ++ return (1);
> ++}
> ++
> + #endif /* GSSAPI */
> +
> + int
> +Index: sshd.c
> +===================================================================
> +RCS file: /cvs/openssh/sshd.c,v
> +retrieving revision 1.372
> +diff -u -r1.372 sshd.c
> +--- sshd.c 11 Mar 2008 11:58:25 -0000 1.372
> ++++ sshd.c 4 Apr 2008 12:52:30 -0000
> +@@ -119,6 +119,10 @@
> + #include "monitor_fdpass.h"
> + #include "version.h"
> +
> ++#ifdef USE_SECURITY_SESSION_API
> ++#include <Security/AuthSession.h>
> ++#endif
> ++
> + #ifdef LIBWRAP
> + #include <tcpd.h>
> + #include <syslog.h>
> +@@ -1501,10 +1505,13 @@
> + logit("Disabling protocol version 1. Could not load host key");
> + options.protocol &= ~SSH_PROTO_1;
> + }
> ++#ifndef GSSAPI
> ++ /* The GSSAPI key exchange can run without a host key */
> + if ((options.protocol & SSH_PROTO_2) && !
> sensitive_data.have_ssh2_key) {
> + logit("Disabling protocol version 2. Could not load host key");
> + options.protocol &= ~SSH_PROTO_2;
> + }
> ++#endif
> + if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) {
> + logit("sshd: no hostkeys available -- exiting.");
> + exit(1);
> +@@ -1777,6 +1784,60 @@
> + /* Log the connection. */
> + verbose("Connection from %.500s port %d", remote_ip, remote_port);
> +
> ++#ifdef USE_SECURITY_SESSION_API
> ++ /*
> ++ * Create a new security session for use by the new user login if
> ++ * the current session is the root session or we are not launched
> ++ * by inetd (eg: debugging mode or server mode). We do not
> ++ * necessarily need to create a session if we are launched from
> ++ * inetd because Panther xinetd will create a session for us.
> ++ *
> ++ * The only case where this logic will fail is if there is an
> ++ * inetd running in a non-root session which is not creating
> ++ * new sessions for us. Then all the users will end up in the
> ++ * same session (bad).
> ++ *
> ++ * When the client exits, the session will be destroyed for us
> ++ * automatically.
> ++ *
> ++ * We must create the session before any credentials are stored
> ++ * (including AFS pags, which happens a few lines below).
> ++ */
> ++ {
> ++ OSStatus err = 0;
> ++ SecuritySessionId sid = 0;
> ++ SessionAttributeBits sattrs = 0;
> ++
> ++ err = SessionGetInfo(callerSecuritySession, &sid, &sattrs);
> ++ if (err)
> ++ error("SessionGetInfo() failed with error %.8X",
> ++ (unsigned) err);
> ++ else
> ++ debug("Current Session ID is %.8X / Session Attributes are %.8X",
> ++ (unsigned) sid, (unsigned) sattrs);
> ++
> ++ if (inetd_flag && !(sattrs & sessionIsRoot))
> ++ debug("Running in inetd mode in a non-root session... "
> ++ "assuming inetd created the session for us.");
> ++ else {
> ++ debug("Creating new security session...");
> ++ err = SessionCreate(0, sessionHasTTY | sessionIsRemote);
> ++ if (err)
> ++ error("SessionCreate() failed with error %.8X",
> ++ (unsigned) err);
> ++
> ++ err = SessionGetInfo(callerSecuritySession, &sid,
> ++ &sattrs);
> ++ if (err)
> ++ error("SessionGetInfo() failed with error %.8X",
> ++ (unsigned) err);
> ++ else
> ++ debug("New Session ID is %.8X / Session Attributes are %.8X",
> ++ (unsigned) sid, (unsigned) sattrs);
> ++ }
> ++ }
> ++#endif
> ++
> + /*
> + * We don't want to listen forever unless the other side
> + * successfully authenticates itself. So we set up an alarm
> which is
> +@@ -2153,12 +2214,59 @@
> +
> + myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types();
> +
> ++#ifdef GSSAPI
> ++ {
> ++ char *orig;
> ++ char *gss = NULL;
> ++ char *newstr = NULL;
> ++ orig = myproposal[PROPOSAL_KEX_ALGS];
> ++
> ++ /*
> ++ * If we don't have a host key, then there's no point advertising
> ++ * the other key exchange algorithms
> ++ */
> ++
> ++ if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0)
> ++ orig = NULL;
> ++
> ++ if (options.gss_keyex)
> ++ gss = ssh_gssapi_server_mechanisms();
> ++ else
> ++ gss = NULL;
> ++
> ++ if (gss && orig)
> ++ xasprintf(&newstr, "%s,%s", gss, orig);
> ++ else if (gss)
> ++ newstr = gss;
> ++ else if (orig)
> ++ newstr = orig;
> ++
> ++ /*
> ++ * If we've got GSSAPI mechanisms, then we've got the 'null' host
> ++ * key alg, but we can't tell people about it unless its the only
> ++ * host key algorithm we support
> ++ */
> ++ if (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) ==
> 0)
> ++ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = "null";
> ++
> ++ if (newstr)
> ++ myproposal[PROPOSAL_KEX_ALGS] = newstr;
> ++ else
> ++ fatal("No supported key exchange algorithms");
> ++ }
> ++#endif
> ++
> + /* start key exchange */
> + kex = kex_setup(myproposal);
> + kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
> + kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server;
> + kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
> + kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
> ++#ifdef GSSAPI
> ++ kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
> ++ kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
> ++ kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
> ++#endif
> + kex->server = 1;
> + kex->client_version_string=client_version_string;
> + kex->server_version_string=server_version_string;
> +Index: sshd_config
> +===================================================================
> +RCS file: /cvs/openssh/sshd_config,v
> +retrieving revision 1.79
> +diff -u -r1.79 sshd_config
> +--- sshd_config 10 Feb 2008 11:40:12 -0000 1.79
> ++++ sshd_config 4 Apr 2008 12:52:30 -0000
> +@@ -72,6 +72,8 @@
> + # GSSAPI options
> + #GSSAPIAuthentication no
> + #GSSAPICleanupCredentials yes
> ++#GSSAPIStrictAcceptorCheck yes
> ++#GSSAPIKeyExchange no
> +
> + # Set this to 'yes' to enable PAM authentication, account
> processing,
> + # and session processing. If this is enabled, PAM authentication
> will
> +Index: sshd_config.5
> +===================================================================
> +RCS file: /cvs/openssh/sshd_config.5,v
> +retrieving revision 1.90
> +diff -u -r1.90 sshd_config.5
> +--- sshd_config.5 27 Mar 2008 00:02:02 -0000 1.90
> ++++ sshd_config.5 4 Apr 2008 12:52:30 -0000
> +@@ -365,12 +365,35 @@
> + The default is
> + .Dq no .
> + Note that this option applies to protocol version 2 only.
> ++.It Cm GSSAPIKeyExchange
> ++Specifies whether key exchange based on GSSAPI is allowed. GSSAPI
> key exchange
> ++doesn't rely on ssh keys to verify host identity.
> ++The default is
> ++.Dq no .
> ++Note that this option applies to protocol version 2 only.
> + .It Cm GSSAPICleanupCredentials
> + Specifies whether to automatically destroy the user's credentials
> cache
> + on logout.
> + The default is
> + .Dq yes .
> + Note that this option applies to protocol version 2 only.
> ++.It Cm GSSAPIStrictAcceptorCheck
> ++Determines whether to be strict about the identity of the GSSAPI
> acceptor
> ++a client authenticates against. If
> ++.Dq yes
> ++then the client must authenticate against the
> ++.Pa host
> ++service on the current hostname. If
> ++.Dq no
> ++then the client may authenticate against any service key stored in
> the
> ++machine's default store. This facility is provided to assist with
> operation
> ++on multi homed machines.
> ++The default is
> ++.Dq yes .
> ++Note that this option applies only to protocol version 2 GSSAPI
> connections,
> ++and setting it to
> ++.Dq no
> ++may only work with recent Kerberos GSSAPI libraries.
> + .It Cm HostbasedAuthentication
> + Specifies whether rhosts or /etc/hosts.equiv authentication together
> + with successful public key client host authentication is allowed
> Added: trunk/dports/net/openssh/files/pam.patch (0 => 38526)
> --- trunk/dports/net/openssh/files/pam.patch
> (rev 0)
> +++ trunk/dports/net/openssh/files/pam.patch 2008-07-24 04:33:03 UTC
> (rev 38526)
> @@ -0,0 +1,12 @@
> +diff -Naur ../openssh-4.4p1.orig/servconf.c ./servconf.c
> +--- ../openssh-4.4p1.orig/servconf.c 2006-08-18 07:23:15.000000000
> -0700
> ++++ ./servconf.c 2006-10-19 17:12:43.000000000 -0700
> +@@ -129,7 +129,7 @@
> + {
> + /* Portable-specific options */
> + if (options->use_pam == -1)
> +- options->use_pam = 0;
> ++ options->use_pam = 1;
> +
> + /* Standard Options */
> + if (options->protocol == SSH_PROTO_UNKNOWN)
> Added: trunk/dports/net/openssh/files/sacl.patch (0 => 38526)
> --- trunk/dports/net/openssh/files/
> sacl.patch (rev 0)
> +++ trunk/dports/net/openssh/files/sacl.patch 2008-07-24 04:33:03
> UTC (rev 38526)
> @@ -0,0 +1,124 @@
> +diff -Naur ../openssh-4.4p1.orig/auth.c ./auth.c
> +--- ../openssh-4.4p1.orig/auth.c 2006-09-06 17:36:43.000000000 -0700
> ++++ ./auth.c 2006-10-19 17:22:43.000000000 -0700
> +@@ -45,6 +45,11 @@
> + #ifdef HAVE_LIBGEN_H
> + #include <libgen.h>
> + #endif
> ++
> ++#ifdef __APPLE_SACL__
> ++#include <membershipPriv.h>
> ++#endif
> ++
> + #include <stdarg.h>
> + #include <stdio.h>
> + #include <string.h>
> +@@ -233,6 +238,46 @@
> + }
> + ga_free();
> + }
> ++
> ++ if( options.sacl_support )
> ++ {
> ++#ifdef __APPLE_SACL__
> ++ /*
> ++ * Here we check with memberd if the Service ACLs allow this
> user to
> ++ * use the ssh service.
> ++ */
> ++
> ++ debug("Checking with Service ACLs for ssh login restrictions");
> ++
> ++ uuid_t user_uuid;
> ++ int isMember = 0;
> ++ int mbrErr = 0;
> ++
> ++ // get the uuid
> ++ if ( mbr_user_name_to_uuid(pw->pw_name, user_uuid) )
> ++ {
> ++ debug("call to mbr_user_name_to_uuid with <%s> failed to
> retrieve user_uuid", pw->pw_name);
> ++ return 0;
> ++ }
> ++ debug("call to mbr_user_name_to_uuid with <%s> suceeded to
> retrieve user_uuid", pw->pw_name);
> ++
> ++ // check the sacl
> ++ if((mbrErr = mbr_check_service_membership(user_uuid, "ssh",
> &isMember)))
> ++ {
> ++ debug("Called mbr_check_service_membership with isMember <%d>
> with status <%d>", isMember, mbrErr);
> ++ if(mbrErr == ENOENT) // no ACL exists
> ++ {
> ++ return 1;
> ++ } else {
> ++ return 0;
> ++ }
> ++ }
> ++ debug("Call to mbr_check_service_membership failed with status <
> %d>", mbrErr);
> ++ return isMember;
> ++#endif /* __APPLE_SACL__ */
> ++ }
> ++
> ++
> +
> + #ifdef CUSTOM_SYS_AUTH_ALLOWED_USER
> + if (!sys_auth_allowed_user(pw, &loginmsg))
> +diff -Naur ../openssh-4.4p1.orig/servconf.c ./servconf.c
> +--- ../openssh-4.4p1.orig/servconf.c 2006-08-18 07:23:15.000000000
> -0700
> ++++ ./servconf.c 2006-10-19 17:24:47.000000000 -0700
> +@@ -97,6 +97,7 @@
> + options->permit_empty_passwd = -1;
> + options->permit_user_env = -1;
> + options->use_login = -1;
> ++ options->sacl_support = -1;
> + options->compression = -1;
> + options->allow_tcp_forwarding = -1;
> + options->num_allow_users = 0;
> +@@ -293,6 +294,7 @@
> + sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
> + sMatch, sPermitOpen, sForceCommand,
> + sUsePrivilegeSeparation,
> ++ sSACLSupport,
> + sDeprecated, sUnsupported
> + } ServerOpCodes;
> +
> +@@ -398,6 +400,7 @@
> + { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
> + { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
> + { "useprivilegeseparation", sUsePrivilegeSeparation,
> SSHCFG_GLOBAL },
> ++ { "saclsupport", sSACLSupport },
> + { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
> + { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
> + { "match", sMatch, SSHCFG_ALL },
> +@@ -912,6 +915,10 @@
> + charptr = &options->xauth_location;
> + goto parse_filename;
> +
> ++ case sSACLSupport:
> ++ intptr = &options->sacl_support;
> ++ goto parse_flag;
> ++
> + case sStrictModes:
> + intptr = &options->strict_modes;
> + goto parse_flag;
> +diff -Naur ../openssh-4.4p1.orig/servconf.h ./servconf.h
> +--- ../openssh-4.4p1.orig/servconf.h 2006-08-18 07:23:15.000000000
> -0700
> ++++ ./servconf.h 2006-10-19 17:25:18.000000000 -0700
> +@@ -137,6 +137,7 @@
> + char *adm_forced_command;
> +
> + int use_pam; /* Enable auth via PAM */
> ++ int sacl_support; /* Enable use of SACLs */
> +
> + int permit_tun;
> +
> +diff -Naur ../openssh-4.4p1.orig/sshd_config ./sshd_config
> +--- ../openssh-4.4p1.orig/sshd_config 2006-07-23 21:06:47.000000000
> -0700
> ++++ ./sshd_config 2006-10-19 17:26:01.000000000 -0700
> +@@ -56,6 +56,9 @@
> + #PasswordAuthentication yes
> + #PermitEmptyPasswords no
> +
> ++# SACL options
> ++#SACLSupport yes
> ++
> + # Change to no to disable s/key passwords
> + #ChallengeResponseAuthentication yes
> +
> _______________________________________________
> macports-changes mailing list
> macports-changes at lists.macosforge.org
> http://lists.macosforge.org/mailman/listinfo.cgi/macports-changes
----
William Siegrist
Mac OS Forge
http://macosforge.org/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 2421 bytes
Desc: not available
Url : http://lists.macosforge.org/pipermail/macports-dev/attachments/20080724/a5fe278a/attachment-0001.bin
More information about the macports-dev
mailing list