]> andersk Git - gssapi-openssh.git/commitdiff
merge OpenSSH 3.8p1 with trunk OPENSSH_3_8P1_GSSAPI_20040224
authorjbasney <jbasney>
Wed, 25 Feb 2004 02:43:33 +0000 (02:43 +0000)
committerjbasney <jbasney>
Wed, 25 Feb 2004 02:43:33 +0000 (02:43 +0000)
- new gssapi-with-mic userauth method: added flag to support both new
  method and old gssapi method for backward compat
- new USE_AFS code needs to be merged with old AFS_KRB5 code

91 files changed:
openssh/Makefile.in
openssh/README.dns
openssh/README.privsep
openssh/acconfig.h
openssh/auth-krb5.c
openssh/auth-pam.c
openssh/auth-pam.h
openssh/auth.c
openssh/auth.h
openssh/auth1.c
openssh/auth2-gss.c
openssh/auth2-hostbased.c
openssh/auth2-passwd.c
openssh/auth2-pubkey.c
openssh/auth2.c
openssh/canohost.c
openssh/cipher-3des1.c
openssh/cipher-aes.c
openssh/cipher-ctr.c
openssh/cipher.c
openssh/compat.c
openssh/compat.h
openssh/configure.ac
openssh/contrib/aix/buildbff.sh
openssh/contrib/aix/inventory.sh
openssh/contrib/findssl.sh
openssh/contrib/gnome-ssh-askpass1.c
openssh/contrib/gnome-ssh-askpass2.c
openssh/defines.h
openssh/dns.c
openssh/dns.h
openssh/fatal.c
openssh/gss-genr.c
openssh/gss-serv-krb5.c
openssh/gss-serv.c
openssh/includes.h
openssh/kex.c
openssh/kexgexc.c
openssh/key.c
openssh/key.h
openssh/log.c
openssh/mdoc2man.awk
openssh/misc.c
openssh/moduli.c
openssh/monitor.c
openssh/monitor.h
openssh/monitor_wrap.c
openssh/monitor_wrap.h
openssh/msg.c
openssh/msg.h
openssh/openbsd-compat/basename.c
openssh/openbsd-compat/bsd-getpeereid.c
openssh/openbsd-compat/bsd-misc.h
openssh/openbsd-compat/fake-rfc2553.h
openssh/openbsd-compat/getopt.c
openssh/openbsd-compat/getrrsetbyname.c
openssh/openbsd-compat/getrrsetbyname.h
openssh/openbsd-compat/port-aix.c
openssh/openbsd-compat/port-aix.h
openssh/openbsd-compat/sys-queue.h
openssh/openbsd-compat/sys-tree.h
openssh/openbsd-compat/vis.c
openssh/openbsd-compat/vis.h
openssh/openbsd-compat/xcrypt.c
openssh/packet.c
openssh/progressmeter.c
openssh/readconf.c
openssh/readconf.h
openssh/scard-opensc.c
openssh/servconf.c
openssh/servconf.h
openssh/session.c
openssh/session.h
openssh/sftp-glob.h [deleted file]
openssh/sftp-int.c [deleted file]
openssh/sftp-int.h [deleted file]
openssh/ssh-agent.c
openssh/ssh-gss.h
openssh/ssh-keyscan.c
openssh/ssh-keysign.c
openssh/ssh-rand-helper.8
openssh/ssh-rand-helper.c
openssh/ssh.1
openssh/ssh.c
openssh/ssh_config.5
openssh/sshconnect2.c
openssh/sshd.8
openssh/sshd.c
openssh/sshd_config
openssh/sshd_config.5
openssh/version.h

index ea22f76f8749563227ad846eb08a3b8de5222b0b..b29472741dae28faed84d6cb15b919259ed285e5 100644 (file)
@@ -62,12 +62,13 @@ INSTALL_GSISSH=@INSTALL_GSISSH@
 
 TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-agent$(EXEEXT) scp$(EXEEXT) ssh-rand-helper${EXEEXT} sftp-server$(EXEEXT) sftp$(EXEEXT)
 
-LIBSSH_OBJS=authfd.o authfile.o bufaux.o buffer.o canohost.o channels.o \
-       cipher.o  cipher-aes.o cipher-bf1.o cipher-ctr.o cipher-3des1.o \
-       compat.o compress.o crc32.o deattack.o fatal.o \
-       hostfile.o log.o match.o moduli.o mpaux.o nchan.o packet.o \
-       readpass.o rsa.o tildexpand.o ttymodes.o xmalloc.o atomicio.o \
-       key.o dispatch.o kex.o mac.o uuencode.o misc.o \
+LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o buffer.o \
+       canohost.o channels.o cipher.o cipher-acss.o cipher-aes.o \
+       cipher-bf1.o cipher-ctr.o cipher-3des1.o cleanup.o \
+       compat.o compress.o crc32.o deattack.o fatal.o hostfile.o \
+       log.o match.o moduli.o mpaux.o nchan.o packet.o \
+       readpass.o rsa.o tildexpand.o ttymodes.o xmalloc.o \
+       atomicio.o key.o dispatch.o kex.o mac.o uuencode.o misc.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 kexgssc.o gss-genr.o
@@ -85,7 +86,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
        kexdhs.o kexgexs.o kexgsss.o \
        auth-krb5.o \
        auth2-gss.o gss-serv.o gss-serv-krb5.o gss-serv-gsi.o \
-       loginrec.o auth-pam.o auth-sia.o md5crypt.o
+       loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.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
@@ -141,25 +142,25 @@ scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o
        $(LD) -o $@ scp.o progressmeter.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) 
+       $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
 
 ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o
-       $(LD) -o $@ ssh-agent.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) 
+       $(LD) -o $@ ssh-agent.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
 
 ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o
-       $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) 
+       $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
 
 ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o
-       $(LD) -o $@ ssh-keysign.o readconf.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) 
+       $(LD) -o $@ ssh-keysign.o readconf.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
 
 ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o
-       $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) 
+       $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
 
 sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o
-       $(LD) -o $@ sftp-server.o sftp-common.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) 
+       $(LD) -o $@ sftp-server.o sftp-common.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
 
-sftp$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-client.o sftp-int.o sftp-common.o sftp-glob.o progressmeter.o
-       $(LD) -o $@ progressmeter.o sftp.o sftp-client.o sftp-common.o sftp-int.o sftp-glob.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
+sftp$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-client.o sftp-common.o sftp-glob.o progressmeter.o
+       $(LD) -o $@ progressmeter.o sftp.o sftp-client.o sftp-common.o sftp-glob.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
 
 ssh-rand-helper${EXEEXT}: $(LIBCOMPAT) libssh.a ssh-rand-helper.o
        $(LD) -o $@ ssh-rand-helper.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
@@ -194,12 +195,12 @@ moduli:
        echo
 
 clean: regressclean
-       rm -f *.o *.a $(TARGETS) logintest config.cache config.log 
-       rm -f *.out core 
+       rm -f *.o *.a $(TARGETS) logintest config.cache config.log
+       rm -f *.out core
        (cd openbsd-compat && $(MAKE) clean)
 
 distclean:     regressclean
-       rm -f *.o *.a $(TARGETS) logintest config.cache config.log 
+       rm -f *.o *.a $(TARGETS) logintest config.cache config.log
        rm -f *.out core
        rm -f Makefile config.h config.status ssh_prng_cmds *~
        rm -rf autom4te.cache
@@ -223,6 +224,7 @@ catman-do:
 
 distprep: catman-do
        $(AUTORECONF)
+       -rm -rf autom4te.cache
        (cd scard && $(MAKE) -f Makefile.in distprep)
 
 install: $(CONFIGFILES) ssh_prng_cmds.out $(MANPAGES) $(TARGETS) install-files host-key check-config
@@ -357,7 +359,7 @@ uninstallall:       uninstall
        -rmdir $(DESTDIR)$(mandir)
        -rmdir $(DESTDIR)$(libexecdir)
 
-uninstall: 
+uninstall:
        -rm -f $(DESTDIR)$(bindir)/slogin
        if [ ! -z "$(INSTALL_GSISSH)" ]; then \
                rm -f $(DESTDIR)$(bindir)/gsiscp; \
@@ -398,6 +400,7 @@ tests:      $(TARGETS)
        [ -d `pwd`/regress ]  ||  mkdir -p `pwd`/regress; \
        [ -f `pwd`/regress/Makefile ]  || \
            ln -s $(srcdir)/regress/Makefile `pwd`/regress/Makefile ; \
+       TEST_SHELL="@TEST_MINUS_S_SH@"; \
        TEST_SSH_SSH="$${BUILDDIR}/ssh"; \
        TEST_SSH_SSHD="$${BUILDDIR}/sshd"; \
        TEST_SSH_SSHAGENT="$${BUILDDIR}/ssh-agent"; \
@@ -413,6 +416,7 @@ tests:      $(TARGETS)
                BUILDDIR="$${BUILDDIR}" \
                OBJ="$${BUILDDIR}/regress/" \
                PATH="$${BUILDDIR}:$${PATH}" \
+               TEST_SHELL="$${TEST_SHELL}" \
                TEST_SSH_SSH="$${TEST_SSH_SSH}" \
                TEST_SSH_SSHD="$${TEST_SSH_SSHD}" \
                TEST_SSH_SSHAGENT="$${TEST_SSH_SSHAGENT}" \
index e24092e03d1c4c0d934122435527b0ffa8c25004..97879183e396059b88f675246ac47e0144f772ca 100644 (file)
@@ -1,17 +1,13 @@
 How to verify host keys using OpenSSH and DNS
 ---------------------------------------------
 
-OpenSSH contains experimental support for verifying host keys using DNS
-as described in draft-ietf-secsh-dns-xx.txt. The document contains
-very brief instructions on how to test this feature. Configuring DNS
-and DNSSEC is out of the scope of this document.
+OpenSSH contains support for verifying host keys using DNS as described in
+draft-ietf-secsh-dns-05.txt. The document contains very brief instructions
+on how to use this feature. Configuring DNS is out of the scope of this
+document.
 
 
-(1) Enable DNS fingerprint support in OpenSSH
-
-       configure --with-dns
-
-(2) Generate and publish the DNS RR
+(1) Server: Generate and publish the DNS RR
 
 To create a DNS resource record (RR) containing a fingerprint of the
 public host key, use the following command:
@@ -24,15 +20,14 @@ you should generate one RR for each key.
 
 In the example above, ssh-keygen will print the fingerprint in a
 generic DNS RR format parsable by most modern name server
-implementations. If your nameserver has support for the SSHFP RR, as
-defined by the draft, you can omit the -g flag and ssh-keygen will
-print a standard RR.
+implementations. If your nameserver has support for the SSHFP RR
+you can omit the -g flag and ssh-keygen will print a standard SSHFP RR.
 
 To publish the fingerprint using the DNS you must add the generated RR
 to your DNS zone file and sign your zone.
 
 
-(3) Enable the ssh client to verify host keys using DNS
+(2) Client: Enable ssh to verify host keys using DNS
 
 To enable the ssh client to verify host keys using DNS, you have to
 add the following option to the ssh configuration file
@@ -49,4 +44,4 @@ the remote host key, the user will be notified.
        Wesley Griffin
 
 
-$OpenBSD: README.dns,v 1.1 2003/05/14 18:16:20 jakob Exp $
+$OpenBSD: README.dns,v 1.2 2003/10/14 19:43:23 jakob Exp $
index 2f60236dbe06ea82d1921b0fddab06a945ee97e5..fcbae9a05180d2dabbf25dc090c74a74542efd2d 100644 (file)
@@ -1,15 +1,15 @@
 Privilege separation, or privsep, is method in OpenSSH by which
 operations that require root privilege are performed by a separate
 privileged monitor process.  Its purpose is to prevent privilege
-escalation by containing corruption to an unprivileged process.  
+escalation by containing corruption to an unprivileged process.
 More information is available at:
        http://www.citi.umich.edu/u/provos/ssh/privsep.html
 
 Privilege separation is now enabled by default; see the
 UsePrivilegeSeparation option in sshd_config(5).
 
-On systems which lack mmap or anonymous (MAP_ANON) memory mapping, 
-compression must be disabled in order for privilege separation to 
+On systems which lack mmap or anonymous (MAP_ANON) memory mapping,
+compression must be disabled in order for privilege separation to
 function.
 
 When privsep is enabled, during the pre-authentication phase sshd will
@@ -38,9 +38,9 @@ privsep user and chroot directory:
 Privsep requires operating system support for file descriptor passing.
 Compression will be disabled on systems without a working mmap MAP_ANON.
 
-PAM-enabled OpenSSH is known to function with privsep on Linux.  
+PAM-enabled OpenSSH is known to function with privsep on Linux.
 It does not function on HP-UX with a trusted system
-configuration. 
+configuration.
 
 On Compaq Tru64 Unix, only the pre-authentication part of privsep is
 supported.  Post-authentication privsep is disabled automatically (so
index 617bdc98111dc4806e4e5da71d182fcb95afb6ab..77e0322adfc094d5b63fb15b6282aee4f2d9bb42 100644 (file)
 /* Define if your setregid() is broken */
 #undef BROKEN_SETREGID
 
+/* Define if your setresuid() is broken */
+#undef BROKEN_SETRESUID
+
+/* Define if your setresgid() is broken */
+#undef BROKEN_SETRESGID
+
 /* Define to a Set Process Title type if your system is */
 /* supported by bsd-setproctitle.c */
 #undef SPT_TYPE
@@ -59,6 +65,9 @@
 /* from environment and PATH */
 #undef LOGIN_PROGRAM_FALLBACK
 
+/* Full path of your "passwd" program */
+#undef _PATH_PASSWD_PROG
+
 /* Define if your password has a pw_class field */
 #undef HAVE_PW_CLASS_IN_PASSWD
 
@@ -89,6 +98,9 @@
 /* Define if you have the getuserattr function.  */
 #undef HAVE_GETUSERATTR
 
+/* Define if you have the basename function. */
+#undef HAVE_BASENAME
+
 /* Work around problematic Linux PAM modules handling of PAM_TTY */
 #undef PAM_TTY_KLUDGE
 
 /* Define this if you want support for startup/shutdown hooks */
 #undef SESSION_HOOKS
 
+/* Define this if you want to use libkafs' AFS support */
+#undef USE_AFS
+
 /* Define if you want S/Key support */
 #undef SKEY
 
 #undef LOCKED_PASSWD_PREFIX
 #undef LOCKED_PASSWD_SUBSTR
 
-/* Define if DNS support is to be activated */
-#undef DNS
-
 /* Define if getrrsetbyname() exists */
 #undef HAVE_GETRRSETBYNAME
 
 /* Define if HEADER.ad exists in arpa/nameser.h */
 #undef HAVE_HEADER_AD
 
+/* Define if your resolver libs need this for getrrsetbyname */
+#undef BIND_8_COMPAT
+
 @BOTTOM@
 
 /* ******************* Shouldn't need to edit below this line ************** */
index 0aa5195b892f0a59cd92bd63990d3c868045272f..85949247836df32607f558f0aaa16345ebd9e66b 100644 (file)
@@ -28,7 +28,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth-krb5.c,v 1.12 2003/08/28 12:54:34 markus Exp $");
+RCSID("$OpenBSD: auth-krb5.c,v 1.15 2003/11/21 11:57:02 djm Exp $");
 
 #include "ssh.h"
 #include "ssh1.h"
@@ -40,7 +40,6 @@ RCSID("$OpenBSD: auth-krb5.c,v 1.12 2003/08/28 12:54:34 markus Exp $");
 #include "auth.h"
 
 #ifdef KRB5
-
 #include <krb5.h>
 
 extern ServerOptions    options;
@@ -50,7 +49,6 @@ krb5_init(void *context)
 {
        Authctxt *authctxt = (Authctxt *)context;
        krb5_error_code problem;
-       static int cleanup_registered = 0;
 
        if (authctxt->krb5_ctx == NULL) {
                problem = krb5_init_context(&authctxt->krb5_ctx);
@@ -58,10 +56,6 @@ krb5_init(void *context)
                        return (problem);
                krb5_init_ets(authctxt->krb5_ctx);
        }
-       if (!cleanup_registered) {
-               fatal_add_cleanup(krb5_cleanup_proc, authctxt);
-               cleanup_registered = 1;
-       }
        return (0);
 }
 
@@ -73,11 +67,11 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
        krb5_principal server;
        char ccname[40];
        int tmpfd;
-#endif 
+#endif
        krb5_error_code problem;
        krb5_ccache ccache = NULL;
 
-       if (authctxt->pw == NULL)
+       if (!authctxt->valid)
                return (0);
 
        temporarily_use_uid(authctxt->pw);
@@ -102,14 +96,15 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
                goto out;
 
        restore_uid();
-       
+
        problem = krb5_verify_user(authctxt->krb5_ctx, authctxt->krb5_user,
            ccache, password, 1, NULL);
-       
+
        temporarily_use_uid(authctxt->pw);
 
        if (problem)
                goto out;
+
        problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_fcc_ops,
            &authctxt->krb5_fwd_ccache);
        if (problem)
@@ -140,21 +135,21 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
        temporarily_use_uid(authctxt->pw);
        if (problem)
                goto out;
-       
-       if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, 
+
+       if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user,
                          authctxt->pw->pw_name)) {
                problem = -1;
                goto out;
-       } 
+       }
 
        snprintf(ccname,sizeof(ccname),"FILE:/tmp/krb5cc_%d_XXXXXX",geteuid());
-       
+
        if ((tmpfd = mkstemp(ccname+strlen("FILE:")))==-1) {
                logit("mkstemp(): %.100s", strerror(errno));
                problem = errno;
                goto out;
        }
-       
+
        if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) {
                logit("fchmod(): %.100s", strerror(errno));
                close(tmpfd);
@@ -171,12 +166,12 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
                                     authctxt->krb5_user);
        if (problem)
                goto out;
-                               
+
        problem= krb5_cc_store_cred(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache,
                                 &creds);
        if (problem)
                goto out;
-#endif         
+#endif
 
        authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
 
@@ -205,10 +200,8 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
 }
 
 void
-krb5_cleanup_proc(void *context)
+krb5_cleanup_proc(Authctxt *authctxt)
 {
-       Authctxt *authctxt = (Authctxt *)context;
-
        debug("krb5_cleanup_proc called");
        if (authctxt->krb5_fwd_ccache) {
                krb5_cc_destroy(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
index 6d55b758f55a23e9a50d301fa030272b2c47b86c..7157e726420a7bdedc72abfcf955bc8333926d80 100644 (file)
 RCSID("$Id$");
 
 #ifdef USE_PAM
+#if defined(HAVE_SECURITY_PAM_APPL_H)
 #include <security/pam_appl.h>
+#elif defined (HAVE_PAM_PAM_APPL_H)
+#include <pam/pam_appl.h>
+#endif
 
 #include "auth.h"
 #include "auth-pam.h"
@@ -52,22 +56,54 @@ RCSID("$Id$");
 #include "auth-options.h"
 
 extern ServerOptions options;
-
-#define __unused
+extern Buffer loginmsg;
+extern int compat20;
 
 #ifdef USE_POSIX_THREADS
 #include <pthread.h>
 /*
- * Avoid namespace clash when *not* using pthreads for systems *with* 
- * pthreads, which unconditionally define pthread_t via sys/types.h 
+ * Avoid namespace clash when *not* using pthreads for systems *with*
+ * pthreads, which unconditionally define pthread_t via sys/types.h
  * (e.g. Linux)
  */
-typedef pthread_t sp_pthread_t; 
+typedef pthread_t sp_pthread_t;
 #else
+typedef pid_t sp_pthread_t;
+#endif
+
+struct pam_ctxt {
+       sp_pthread_t     pam_thread;
+       int              pam_psock;
+       int              pam_csock;
+       int              pam_done;
+};
+
+static void sshpam_free_ctx(void *);
+static struct pam_ctxt *cleanup_ctxt;
+
+#ifndef USE_POSIX_THREADS
 /*
  * Simulate threads with processes.
  */
-typedef pid_t sp_pthread_t;
+
+static int sshpam_thread_status = -1;
+static mysig_t sshpam_oldsig;
+
+static void 
+sshpam_sigchld_handler(int sig)
+{
+       if (cleanup_ctxt == NULL)
+               return; /* handler called after PAM cleanup, shouldn't happen */
+       if (waitpid(cleanup_ctxt->pam_thread, &sshpam_thread_status, 0) == -1)
+               return; /* couldn't wait for process */
+       if (WIFSIGNALED(sshpam_thread_status) &&
+           WTERMSIG(sshpam_thread_status) == SIGTERM)
+               return; /* terminated by pthread_cancel */
+       if (!WIFEXITED(sshpam_thread_status))
+               fatal("PAM: authentication thread exited unexpectedly");
+       if (WEXITSTATUS(sshpam_thread_status) != 0)
+               fatal("PAM: authentication thread exited uncleanly");
+}
 
 static void
 pthread_exit(void *value __unused)
@@ -90,6 +126,7 @@ pthread_create(sp_pthread_t *thread, const void *attr __unused,
                _exit(1);
        default:
                *thread = pid;
+               sshpam_oldsig = signal(SIGCHLD, sshpam_sigchld_handler);
                return (0);
        }
 }
@@ -97,6 +134,7 @@ pthread_create(sp_pthread_t *thread, const void *attr __unused,
 static int
 pthread_cancel(sp_pthread_t thread)
 {
+       signal(SIGCHLD, sshpam_oldsig);
        return (kill(thread, SIGTERM));
 }
 
@@ -105,6 +143,9 @@ pthread_join(sp_pthread_t thread, void **value __unused)
 {
        int status;
 
+       if (sshpam_thread_status != -1)
+               return (sshpam_thread_status);
+       signal(SIGCHLD, sshpam_oldsig);
        waitpid(thread, &status, 0);
        return (status);
 }
@@ -114,18 +155,80 @@ pthread_join(sp_pthread_t thread, void **value __unused)
 static pam_handle_t *sshpam_handle = NULL;
 static int sshpam_err = 0;
 static int sshpam_authenticated = 0;
-static int sshpam_new_authtok_reqd = 0;
 static int sshpam_session_open = 0;
 static int sshpam_cred_established = 0;
+static int sshpam_account_status = -1;
+static char **sshpam_env = NULL;
+static int *force_pwchange;
+
+/* Some PAM implementations don't implement this */
+#ifndef HAVE_PAM_GETENVLIST
+static char **
+pam_getenvlist(pam_handle_t *pamh)
+{
+       /*
+        * XXX - If necessary, we can still support envrionment passing
+        * for platforms without pam_getenvlist by searching for known
+        * env vars (e.g. KRB5CCNAME) from the PAM environment.
+        */
+        return NULL;
+}
+#endif
 
-struct pam_ctxt {
-       sp_pthread_t     pam_thread;
-       int              pam_psock;
-       int              pam_csock;
-       int              pam_done;
-};
+void
+pam_password_change_required(int reqd)
+{
+       debug3("%s %d", __func__, reqd);
+       *force_pwchange = reqd;
+       if (reqd) {
+               no_port_forwarding_flag |= 2;
+               no_agent_forwarding_flag |= 2;
+               no_x11_forwarding_flag |= 2;
+       } else {
+               no_port_forwarding_flag &= ~2;
+               no_agent_forwarding_flag &= ~2;
+               no_x11_forwarding_flag &= ~2;
+       }
+}
 
-static void sshpam_free_ctx(void *);
+/* Import regular and PAM environment from subprocess */
+static void
+import_environments(Buffer *b)
+{
+       char *env;
+       u_int i, num_env;
+       int err;
+
+       debug3("PAM: %s entering", __func__);
+
+       /* Import variables set by do_pam_account */
+       sshpam_account_status = buffer_get_int(b);
+       pam_password_change_required(buffer_get_int(b));
+
+       /* Import environment from subprocess */
+       num_env = buffer_get_int(b);
+       sshpam_env = xmalloc((num_env + 1) * sizeof(*sshpam_env));
+       debug3("PAM: num env strings %d", num_env);
+       for(i = 0; i < num_env; i++)
+               sshpam_env[i] = buffer_get_string(b, NULL);
+
+       sshpam_env[num_env] = NULL;
+
+       /* Import PAM environment from subprocess */
+       num_env = buffer_get_int(b);
+       debug("PAM: num PAM env strings %d", num_env);
+       for(i = 0; i < num_env; i++) {
+               env = buffer_get_string(b, NULL);
+
+#ifdef HAVE_PAM_PUTENV
+               /* Errors are not fatal here */
+               if ((err = pam_putenv(sshpam_handle, env)) != PAM_SUCCESS) {
+                       error("PAM: pam_putenv: %s",
+                           pam_strerror(sshpam_handle, sshpam_err));
+               }
+#endif
+       }
+}
 
 /*
  * Conversation function for authentication thread.
@@ -139,6 +242,7 @@ sshpam_thread_conv(int n, const struct pam_message **msg,
        struct pam_response *reply;
        int i;
 
+       debug3("PAM: %s entering, %d messages", __func__, n);
        *resp = NULL;
 
        ctxt = data;
@@ -153,36 +257,42 @@ sshpam_thread_conv(int n, const struct pam_message **msg,
        for (i = 0; i < n; ++i) {
                switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
                case PAM_PROMPT_ECHO_OFF:
-                       buffer_put_cstring(&buffer, 
+                       buffer_put_cstring(&buffer,
                            PAM_MSG_MEMBER(msg, i, msg));
-                       ssh_msg_send(ctxt->pam_csock, 
-                           PAM_MSG_MEMBER(msg, i, msg_style), &buffer);
-                       ssh_msg_recv(ctxt->pam_csock, &buffer);
+                       if (ssh_msg_send(ctxt->pam_csock,
+                           PAM_MSG_MEMBER(msg, i, msg_style), &buffer) == -1)
+                               goto fail;
+                       if (ssh_msg_recv(ctxt->pam_csock, &buffer) == -1)
+                               goto fail;
                        if (buffer_get_char(&buffer) != PAM_AUTHTOK)
                                goto fail;
                        reply[i].resp = buffer_get_string(&buffer, NULL);
                        break;
                case PAM_PROMPT_ECHO_ON:
-                       buffer_put_cstring(&buffer, 
+                       buffer_put_cstring(&buffer,
                            PAM_MSG_MEMBER(msg, i, msg));
-                       ssh_msg_send(ctxt->pam_csock, 
-                           PAM_MSG_MEMBER(msg, i, msg_style), &buffer);
-                       ssh_msg_recv(ctxt->pam_csock, &buffer);
+                       if (ssh_msg_send(ctxt->pam_csock,
+                           PAM_MSG_MEMBER(msg, i, msg_style), &buffer) == -1)
+                               goto fail;
+                       if (ssh_msg_recv(ctxt->pam_csock, &buffer) == -1)
+                               goto fail;
                        if (buffer_get_char(&buffer) != PAM_AUTHTOK)
                                goto fail;
                        reply[i].resp = buffer_get_string(&buffer, NULL);
                        break;
                case PAM_ERROR_MSG:
-                       buffer_put_cstring(&buffer, 
+                       buffer_put_cstring(&buffer,
                            PAM_MSG_MEMBER(msg, i, msg));
-                       ssh_msg_send(ctxt->pam_csock, 
-                           PAM_MSG_MEMBER(msg, i, msg_style), &buffer);
+                       if (ssh_msg_send(ctxt->pam_csock,
+                           PAM_MSG_MEMBER(msg, i, msg_style), &buffer) == -1)
+                               goto fail;
                        break;
                case PAM_TEXT_INFO:
-                       buffer_put_cstring(&buffer, 
+                       buffer_put_cstring(&buffer,
                            PAM_MSG_MEMBER(msg, i, msg));
-                       ssh_msg_send(ctxt->pam_csock, 
-                           PAM_MSG_MEMBER(msg, i, msg_style), &buffer);
+                       if (ssh_msg_send(ctxt->pam_csock,
+                           PAM_MSG_MEMBER(msg, i, msg_style), &buffer) == -1)
+                               goto fail;
                        break;
                default:
                        goto fail;
@@ -213,10 +323,14 @@ sshpam_thread(void *ctxtp)
        Buffer buffer;
        struct pam_conv sshpam_conv;
 #ifndef USE_POSIX_THREADS
+       extern char **environ;
+       char **env_from_pam;
+       u_int i;
        const char *pam_user;
 
        pam_get_item(sshpam_handle, PAM_USER, (const void **)&pam_user);
        setproctitle("%s [pam]", pam_user);
+       environ[0] = NULL;
 #endif
 
        sshpam_conv.conv = sshpam_thread_conv;
@@ -230,7 +344,43 @@ sshpam_thread(void *ctxtp)
        sshpam_err = pam_authenticate(sshpam_handle, 0);
        if (sshpam_err != PAM_SUCCESS)
                goto auth_fail;
+
+       if (compat20) {
+               if (!do_pam_account())
+                       goto auth_fail;
+               if (*force_pwchange) {
+                       sshpam_err = pam_chauthtok(sshpam_handle,
+                           PAM_CHANGE_EXPIRED_AUTHTOK);
+                       if (sshpam_err != PAM_SUCCESS)
+                               goto auth_fail;
+                       pam_password_change_required(0);
+               }
+       }
+
        buffer_put_cstring(&buffer, "OK");
+
+#ifndef USE_POSIX_THREADS
+       /* Export variables set by do_pam_account */
+       buffer_put_int(&buffer, sshpam_account_status);
+       buffer_put_int(&buffer, *force_pwchange);
+
+       /* Export any environment strings set in child */
+       for(i = 0; environ[i] != NULL; i++)
+               ; /* Count */
+       buffer_put_int(&buffer, i);
+       for(i = 0; environ[i] != NULL; i++)
+               buffer_put_cstring(&buffer, environ[i]);
+
+       /* Export any environment strings set by PAM in child */
+       env_from_pam = pam_getenvlist(sshpam_handle);
+       for(i = 0; env_from_pam != NULL && env_from_pam[i] != NULL; i++)
+               ; /* Count */
+       buffer_put_int(&buffer, i);
+       for(i = 0; env_from_pam != NULL && env_from_pam[i] != NULL; i++)
+               buffer_put_cstring(&buffer, env_from_pam[i]);
+#endif /* USE_POSIX_THREADS */
+
+       /* XXX - can't do much about an error here */
        ssh_msg_send(ctxt->pam_csock, sshpam_err, &buffer);
        buffer_free(&buffer);
        pthread_exit(NULL);
@@ -238,37 +388,43 @@ sshpam_thread(void *ctxtp)
  auth_fail:
        buffer_put_cstring(&buffer,
            pam_strerror(sshpam_handle, sshpam_err));
+       /* XXX - can't do much about an error here */
        ssh_msg_send(ctxt->pam_csock, PAM_AUTH_ERR, &buffer);
        buffer_free(&buffer);
        pthread_exit(NULL);
-       
+
        return (NULL); /* Avoid warning for non-pthread case */
 }
 
-static void
-sshpam_thread_cleanup(void *ctxtp)
+void
+sshpam_thread_cleanup(void)
 {
-       struct pam_ctxt *ctxt = ctxtp;
-
-       pthread_cancel(ctxt->pam_thread);
-       pthread_join(ctxt->pam_thread, NULL);
-       close(ctxt->pam_psock);
-       close(ctxt->pam_csock);
+       struct pam_ctxt *ctxt = cleanup_ctxt;
+
+       debug3("PAM: %s entering", __func__);
+       if (ctxt != NULL && ctxt->pam_thread != 0) {
+               pthread_cancel(ctxt->pam_thread);
+               pthread_join(ctxt->pam_thread, NULL);
+               close(ctxt->pam_psock);
+               close(ctxt->pam_csock);
+               memset(ctxt, 0, sizeof(*ctxt));
+               cleanup_ctxt = NULL;
+       }
 }
 
 static int
 sshpam_null_conv(int n, const struct pam_message **msg,
     struct pam_response **resp, void *data)
 {
+       debug3("PAM: %s entering, %d messages", __func__, n);
        return (PAM_CONV_ERR);
 }
 
 static struct pam_conv null_conv = { sshpam_null_conv, NULL };
 
-static void
-sshpam_cleanup(void *arg)
+void
+sshpam_cleanup(void)
 {
-       (void)arg;
        debug("PAM: cleanup");
        if (sshpam_handle == NULL)
                return;
@@ -281,7 +437,7 @@ sshpam_cleanup(void *arg)
                pam_close_session(sshpam_handle, PAM_SILENT);
                sshpam_session_open = 0;
        }
-       sshpam_authenticated = sshpam_new_authtok_reqd = 0;
+       sshpam_authenticated = 0;
        pam_end(sshpam_handle, sshpam_err);
        sshpam_handle = NULL;
 }
@@ -299,7 +455,6 @@ sshpam_init(const char *user)
                    PAM_USER, (const void **)&pam_user);
                if (sshpam_err == PAM_SUCCESS && strcmp(user, pam_user) == 0)
                        return (0);
-               fatal_remove_cleanup(sshpam_cleanup, NULL);
                pam_end(sshpam_handle, sshpam_err);
                sshpam_handle = NULL;
        }
@@ -320,11 +475,11 @@ sshpam_init(const char *user)
                return (-1);
        }
 #ifdef PAM_TTY_KLUDGE
-        /*
-         * Some silly PAM modules (e.g. pam_time) require a TTY to operate.
-         * sshd doesn't set the tty until too late in the auth process and 
+       /*
+        * Some silly PAM modules (e.g. pam_time) require a TTY to operate.
+        * sshd doesn't set the tty until too late in the auth process and
         * may not even set one (for tty-less connections)
-         */
+        */
        debug("PAM: setting PAM_TTY to \"ssh\"");
        sshpam_err = pam_set_item(sshpam_handle, PAM_TTY, "ssh");
        if (sshpam_err != PAM_SUCCESS) {
@@ -333,7 +488,6 @@ sshpam_init(const char *user)
                return (-1);
        }
 #endif
-       fatal_add_cleanup(sshpam_cleanup, NULL);
        return (0);
 }
 
@@ -343,6 +497,7 @@ sshpam_init_ctx(Authctxt *authctxt)
        struct pam_ctxt *ctxt;
        int socks[2];
 
+       debug3("PAM: %s entering", __func__);
        /* Refuse to start if we don't have PAM enabled */
        if (!options.use_pam)
                return NULL;
@@ -354,7 +509,9 @@ sshpam_init_ctx(Authctxt *authctxt)
        }
 
        ctxt = xmalloc(sizeof *ctxt);
-       ctxt->pam_done = 0;
+       memset(ctxt, 0, sizeof(*ctxt));
+
+       force_pwchange = &(authctxt->force_pwchange);
 
        /* Start the authentication thread */
        if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, socks) == -1) {
@@ -372,7 +529,7 @@ sshpam_init_ctx(Authctxt *authctxt)
                xfree(ctxt);
                return (NULL);
        }
-       fatal_add_cleanup(sshpam_thread_cleanup, ctxt);
+       cleanup_ctxt = ctxt;
        return (ctxt);
 }
 
@@ -387,6 +544,7 @@ sshpam_query(void *ctx, char **name, char **info,
        char *msg;
        size_t len;
 
+       debug3("PAM: %s entering", __func__);
        buffer_init(&buffer);
        *name = xstrdup("");
        *info = xstrdup("");
@@ -410,26 +568,23 @@ sshpam_query(void *ctx, char **name, char **info,
                case PAM_ERROR_MSG:
                case PAM_TEXT_INFO:
                        /* accumulate messages */
-                       len = plen + strlen(msg) + 1;
+                       len = plen + strlen(msg) + 2;
                        **prompts = xrealloc(**prompts, len);
-                       plen += snprintf(**prompts + plen, len, "%s", msg);
+                       plen += snprintf(**prompts + plen, len, "%s\n", msg);
                        xfree(msg);
                        break;
                case PAM_SUCCESS:
                case PAM_AUTH_ERR:
                        if (**prompts != NULL) {
                                /* drain any accumulated messages */
-#if 0 /* XXX - not compatible with privsep */
-                               packet_start(SSH2_MSG_USERAUTH_BANNER);
-                               packet_put_cstring(**prompts);
-                               packet_put_cstring("");
-                               packet_send();
-                               packet_write_wait();
-#endif
+                               debug("PAM: %s", **prompts);
+                               buffer_append(&loginmsg, **prompts,
+                                   strlen(**prompts));
                                xfree(**prompts);
                                **prompts = NULL;
                        }
                        if (type == PAM_SUCCESS) {
+                               import_environments(&buffer);
                                *num = 0;
                                **echo_on = 0;
                                ctxt->pam_done = 1;
@@ -437,6 +592,7 @@ sshpam_query(void *ctx, char **name, char **info,
                                return (0);
                        }
                        error("PAM: %s", msg);
+                       /* FALLTHROUGH */
                default:
                        *num = 0;
                        **echo_on = 0;
@@ -455,7 +611,7 @@ sshpam_respond(void *ctx, u_int num, char **resp)
        Buffer buffer;
        struct pam_ctxt *ctxt = ctx;
 
-       debug2("PAM: %s", __func__);
+       debug2("PAM: %s entering, %d responses", __func__, num);
        switch (ctxt->pam_done) {
        case 1:
                sshpam_authenticated = 1;
@@ -471,7 +627,10 @@ sshpam_respond(void *ctx, u_int num, char **resp)
        }
        buffer_init(&buffer);
        buffer_put_cstring(&buffer, *resp);
-       ssh_msg_send(ctxt->pam_psock, PAM_AUTHTOK, &buffer);
+       if (ssh_msg_send(ctxt->pam_psock, PAM_AUTHTOK, &buffer) == -1) {
+               buffer_free(&buffer);
+               return (-1);
+       }
        buffer_free(&buffer);
        return (1);
 }
@@ -481,8 +640,8 @@ sshpam_free_ctx(void *ctxtp)
 {
        struct pam_ctxt *ctxt = ctxtp;
 
-       fatal_remove_cleanup(sshpam_thread_cleanup, ctxt);
-       sshpam_thread_cleanup(ctxtp);
+       debug3("PAM: %s entering", __func__);
+       sshpam_thread_cleanup();
        xfree(ctxt);
        /*
         * We don't call sshpam_cleanup() here because we may need the PAM
@@ -524,44 +683,28 @@ start_pam(const char *user)
 void
 finish_pam(void)
 {
-       fatal_remove_cleanup(sshpam_cleanup, NULL);
-       sshpam_cleanup(NULL);
+       sshpam_cleanup();
 }
 
 u_int
 do_pam_account(void)
 {
+       if (sshpam_account_status != -1)
+               return (sshpam_account_status);
+
        sshpam_err = pam_acct_mgmt(sshpam_handle, 0);
-       debug3("%s: pam_acct_mgmt = %d", __func__, sshpam_err);
+       debug3("PAM: %s pam_acct_mgmt = %d", __func__, sshpam_err);
        
-       if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD)
-               return (0);
-
-       if (sshpam_err == PAM_NEW_AUTHTOK_REQD) {
-               sshpam_new_authtok_reqd = 1;
-
-               /* Prevent forwardings until password changed */
-               no_port_forwarding_flag |= 2;
-               no_agent_forwarding_flag |= 2;
-               no_x11_forwarding_flag |= 2;
+       if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) {
+               sshpam_account_status = 0;
+               return (sshpam_account_status);
        }
 
-       return (1);
-}
+       if (sshpam_err == PAM_NEW_AUTHTOK_REQD)
+               pam_password_change_required(1);
 
-void
-do_pam_session(void)
-{
-       sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, 
-           (const void *)&null_conv);
-       if (sshpam_err != PAM_SUCCESS)
-               fatal("PAM: failed to set PAM_CONV: %s",
-                   pam_strerror(sshpam_handle, sshpam_err));
-       sshpam_err = pam_open_session(sshpam_handle, 0);
-       if (sshpam_err != PAM_SUCCESS)
-               fatal("PAM: pam_open_session(): %s",
-                   pam_strerror(sshpam_handle, sshpam_err));
-       sshpam_session_open = 1;
+       sshpam_account_status = 1;
+       return (sshpam_account_status);
 }
 
 void
@@ -603,23 +746,19 @@ do_pam_setcred(int init)
                    pam_strerror(sshpam_handle, sshpam_err));
 }
 
-int
-is_pam_password_change_required(void)
-{
-       return (sshpam_new_authtok_reqd);
-}
-
 static int
-pam_chauthtok_conv(int n, const struct pam_message **msg,
+pam_tty_conv(int n, const struct pam_message **msg,
     struct pam_response **resp, void *data)
 {
        char input[PAM_MAX_MSG_SIZE];
        struct pam_response *reply;
        int i;
 
+       debug3("PAM: %s called with %d messages", __func__, n);
+
        *resp = NULL;
 
-       if (n <= 0 || n > PAM_MAX_NUM_MSG)
+       if (n <= 0 || n > PAM_MAX_NUM_MSG || !isatty(STDIN_FILENO))
                return (PAM_CONV_ERR);
 
        if ((reply = malloc(n * sizeof(*reply))) == NULL)
@@ -630,19 +769,19 @@ pam_chauthtok_conv(int n, const struct pam_message **msg,
                switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
                case PAM_PROMPT_ECHO_OFF:
                        reply[i].resp =
-                           read_passphrase(PAM_MSG_MEMBER(msg, i, msg), 
+                           read_passphrase(PAM_MSG_MEMBER(msg, i, msg),
                            RP_ALLOW_STDIN);
                        reply[i].resp_retcode = PAM_SUCCESS;
                        break;
                case PAM_PROMPT_ECHO_ON:
-                       fputs(PAM_MSG_MEMBER(msg, i, msg), stderr);
+                       fprintf(stderr, "%s\n", PAM_MSG_MEMBER(msg, i, msg));
                        fgets(input, sizeof input, stdin);
                        reply[i].resp = xstrdup(input);
                        reply[i].resp_retcode = PAM_SUCCESS;
                        break;
                case PAM_ERROR_MSG:
                case PAM_TEXT_INFO:
-                       fputs(PAM_MSG_MEMBER(msg, i, msg), stderr);
+                       fprintf(stderr, "%s\n", PAM_MSG_MEMBER(msg, i, msg));
                        reply[i].resp_retcode = PAM_SUCCESS;
                        break;
                default:
@@ -661,6 +800,8 @@ pam_chauthtok_conv(int n, const struct pam_message **msg,
        return (PAM_CONV_ERR);
 }
 
+static struct pam_conv tty_conv = { pam_tty_conv, NULL };
+
 /*
  * XXX this should be done in the authentication phase, but ssh1 doesn't
  * support that
@@ -668,15 +809,10 @@ pam_chauthtok_conv(int n, const struct pam_message **msg,
 void
 do_pam_chauthtok(void)
 {
-       struct pam_conv pam_conv;
-
-       pam_conv.conv = pam_chauthtok_conv;
-       pam_conv.appdata_ptr = NULL;
-
        if (use_privsep)
                fatal("Password expired (unable to change with privsep)");
        sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
-           (const void *)&pam_conv);
+           (const void *)&tty_conv);
        if (sshpam_err != PAM_SUCCESS)
                fatal("PAM: failed to set PAM_CONV: %s",
                    pam_strerror(sshpam_handle, sshpam_err));
@@ -687,17 +823,77 @@ do_pam_chauthtok(void)
                    pam_strerror(sshpam_handle, sshpam_err));
 }
 
-/* 
+static int
+pam_store_conv(int n, const struct pam_message **msg,
+    struct pam_response **resp, void *data)
+{
+       struct pam_response *reply;
+       int i;
+       size_t len;
+
+       debug3("PAM: %s called with %d messages", __func__, n);
+       *resp = NULL;
+
+       if (n <= 0 || n > PAM_MAX_NUM_MSG)
+               return (PAM_CONV_ERR);
+
+       if ((reply = malloc(n * sizeof(*reply))) == NULL)
+               return (PAM_CONV_ERR);
+       memset(reply, 0, n * sizeof(*reply));
+
+       for (i = 0; i < n; ++i) {
+               switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
+               case PAM_ERROR_MSG:
+               case PAM_TEXT_INFO:
+                       len = strlen(PAM_MSG_MEMBER(msg, i, msg));
+                       buffer_append(&loginmsg, PAM_MSG_MEMBER(msg, i, msg), len);
+                       buffer_append(&loginmsg, "\n", 1 );
+                       reply[i].resp_retcode = PAM_SUCCESS;
+                       break;
+               default:
+                       goto fail;
+               }
+       }
+       *resp = reply;
+       return (PAM_SUCCESS);
+
+ fail:
+       for(i = 0; i < n; i++) {
+               if (reply[i].resp != NULL)
+                       xfree(reply[i].resp);
+       }
+       xfree(reply);
+       return (PAM_CONV_ERR);
+}
+
+static struct pam_conv store_conv = { pam_store_conv, NULL };
+
+void
+do_pam_session(void)
+{
+       debug3("PAM: opening session");
+       sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
+           (const void *)&store_conv);
+       if (sshpam_err != PAM_SUCCESS)
+               fatal("PAM: failed to set PAM_CONV: %s",
+                   pam_strerror(sshpam_handle, sshpam_err));
+       sshpam_err = pam_open_session(sshpam_handle, 0);
+       if (sshpam_err != PAM_SUCCESS)
+               fatal("PAM: pam_open_session(): %s",
+                   pam_strerror(sshpam_handle, sshpam_err));
+       sshpam_session_open = 1;
+}
+
+/*
  * Set a PAM environment string. We need to do this so that the session
  * modules can handle things like Kerberos/GSI credentials that appear
  * during the ssh authentication process.
  */
-
 int
-do_pam_putenv(char *name, char *value) 
+do_pam_putenv(char *name, char *value)
 {
        int ret = 1;
-#ifdef HAVE_PAM_PUTENV 
+#ifdef HAVE_PAM_PUTENV
        char *compound;
        size_t len;
 
@@ -712,21 +908,16 @@ do_pam_putenv(char *name, char *value)
        return (ret);
 }
 
-void
-print_pam_messages(void)
+char **
+fetch_pam_child_environment(void)
 {
-       /* XXX */
+       return sshpam_env;
 }
 
 char **
 fetch_pam_environment(void)
 {
-#ifdef HAVE_PAM_GETENVLIST
-       debug("PAM: retrieving environment");
        return (pam_getenvlist(sshpam_handle));
-#else
-       return (NULL);
-#endif
 }
 
 void
index 6b77872d1919ac84e9de9a5c639e7431844ef38c..0682ca09bcb3967e0adb0af7addcc03067ba2cb4 100644 (file)
@@ -37,11 +37,12 @@ u_int do_pam_account(void);
 void do_pam_session(void);
 void do_pam_set_tty(const char *);
 void do_pam_setcred(int );
-int is_pam_password_change_required(void);
 void do_pam_chauthtok(void);
 int do_pam_putenv(char *, char *);
-void print_pam_messages(void);
 char ** fetch_pam_environment(void);
+char ** fetch_pam_child_environment(void);
 void free_pam_environment(char **);
+void sshpam_thread_cleanup(void);
+void sshpam_cleanup(void);
 
 #endif /* USE_PAM */
index 72c224b6dbe38d821297cad547f46cfdf75e8255..5d3bb1d1b14c6c1de0429a65937ea35ce2a8838f 100644 (file)
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth.c,v 1.49 2003/08/26 09:58:43 markus Exp $");
+RCSID("$OpenBSD: auth.c,v 1.51 2003/11/21 11:57:02 djm Exp $");
 
 #ifdef HAVE_LOGIN_H
 #include <login.h>
 #endif
-#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
+#ifdef USE_SHADOW
 #include <shadow.h>
-#endif /* defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) */
+#endif
 
 #ifdef HAVE_LIBGEN_H
 #include <libgen.h>
@@ -76,7 +76,7 @@ allowed_user(struct passwd * pw)
        const char *hostname = NULL, *ipaddr = NULL, *passwd = NULL;
        char *shell;
        int i;
-#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
+#ifdef USE_SHADOW
        struct spwd *spw = NULL;
 #endif
 
@@ -84,53 +84,24 @@ allowed_user(struct passwd * pw)
        if (!pw || !pw->pw_name)
                return 0;
 
-#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
+#ifdef USE_SHADOW
        if (!options.use_pam)
                spw = getspnam(pw->pw_name);
 #ifdef HAS_SHADOW_EXPIRE
-#define        DAY             (24L * 60 * 60) /* 1 day in seconds */
-       if (!options.use_pam && spw != NULL) {
-               time_t today;
-
-               today = time(NULL) / DAY;
-               debug3("allowed_user: today %d sp_expire %d sp_lstchg %d"
-                   " sp_max %d", (int)today, (int)spw->sp_expire,
-                   (int)spw->sp_lstchg, (int)spw->sp_max);
-
-               /*
-                * We assume account and password expiration occurs the
-                * day after the day specified.
-                */
-               if (spw->sp_expire != -1 && today > spw->sp_expire) {
-                       logit("Account %.100s has expired", pw->pw_name);
-                       return 0;
-               }
-
-               if (spw->sp_lstchg == 0) {
-                       logit("User %.100s password has expired (root forced)",
-                           pw->pw_name);
-                       return 0;
-               }
-
-               if (spw->sp_max != -1 &&
-                   today > spw->sp_lstchg + spw->sp_max) {
-                       logit("User %.100s password has expired (password aged)",
-                           pw->pw_name);
-                       return 0;
-               }
-       }
+       if (!options.use_pam && spw != NULL && auth_shadow_acctexpired(spw))
+               return 0;
 #endif /* HAS_SHADOW_EXPIRE */
-#endif /* defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) */
+#endif /* USE_SHADOW */
 
-       /* grab passwd field for locked account check */
-#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
+       /* grab passwd field for locked account check */
+#ifdef USE_SHADOW
        if (spw != NULL)
                passwd = spw->sp_pwdp;
 #else
        passwd = pw->pw_passwd;
 #endif
 
-       /* check for locked account */ 
+       /* check for locked account */
        if (!options.use_pam && passwd && *passwd) {
                int locked = 0;
 
@@ -242,7 +213,7 @@ allowed_user(struct passwd * pw)
        if ((pw->pw_uid != 0) && (geteuid() == 0)) {
                char *msg;
 
-               if (loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &msg) != 0) {
+               if (loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &msg) != 0) {
                        int loginrestrict_errno = errno;
 
                        if (msg && *msg) {
@@ -252,7 +223,7 @@ allowed_user(struct passwd * pw)
                                    pw->pw_name, msg);
                        }
                        /* Don't fail if /etc/nologin  set */
-                       if (!(loginrestrict_errno == EPERM && 
+                       if (!(loginrestrict_errno == EPERM &&
                            stat(_PATH_NOLOGIN, &st) == 0))
                                return 0;
                }
@@ -263,14 +234,6 @@ allowed_user(struct passwd * pw)
        return 1;
 }
 
-Authctxt *
-authctxt_new(void)
-{
-       Authctxt *authctxt = xmalloc(sizeof(*authctxt));
-       memset(authctxt, 0, sizeof(*authctxt));
-       return authctxt;
-}
-
 void
 auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
 {
@@ -599,7 +562,7 @@ fakepw(void)
        memset(&fake, 0, sizeof(fake));
        fake.pw_name = "NOUSER";
        fake.pw_passwd =
-           "$2a$06$r3.juUaHZDlIbQaO2dS9FuYxL1W9M81R1Tc92PoSNmzvpEqLkLGrK";     
+           "$2a$06$r3.juUaHZDlIbQaO2dS9FuYxL1W9M81R1Tc92PoSNmzvpEqLkLGrK";
        fake.pw_gecos = "NOUSER";
        fake.pw_uid = -1;
        fake.pw_gid = -1;
index 9a5c6577ad4fa6889a4d8d14fe7d2e4002452b1c..7e7562b6e0d4c31628c03627a9f6f0c9d35b3769 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: auth.h,v 1.46 2003/08/28 12:54:34 markus Exp $        */
+/*     $OpenBSD: auth.h,v 1.49 2004/01/30 09:48:57 markus Exp $        */
 
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
@@ -55,6 +55,7 @@ struct Authctxt {
        int              valid;         /* user exists and is allowed to login */
        int              attempt;
        int              failures;
+       int              force_pwchange;
        char            *user;          /* username sent by the client */
        char            *service;
        struct passwd   *pw;            /* set if 'valid' */
@@ -108,9 +109,9 @@ int      auth_rhosts(struct passwd *, const char *);
 int
 auth_rhosts2(struct passwd *, const char *, const char *, const char *);
 
-int     auth_rhosts_rsa(struct passwd *, char *, Key *);
+int     auth_rhosts_rsa(Authctxt *, char *, Key *);
 int      auth_password(Authctxt *, const char *);
-int      auth_rsa(struct passwd *, BIGNUM *);
+int      auth_rsa(Authctxt *, BIGNUM *);
 int      auth_rsa_challenge_dialog(Key *);
 BIGNUM *auth_rsa_generate_challenge(Key *);
 int     auth_rsa_verify_response(Key *, BIGNUM *, u_char[]);
@@ -124,15 +125,21 @@ int        user_key_allowed(struct passwd *, Key *);
 int    auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *);
 int    auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt);
 int    auth_krb5_password(Authctxt *authctxt, const char *password);
-void   krb5_cleanup_proc(void *authctxt);
+void   krb5_cleanup_proc(Authctxt *authctxt);
 #endif /* KRB5 */
 
+#if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE)
+#include <shadow.h>
+int auth_shadow_acctexpired(struct spwd *);
+int auth_shadow_pwexpired(Authctxt *);
+#endif
+
 #include "auth-pam.h"
+void disable_forwarding(void);
 
-Authctxt *do_authentication(void);
-Authctxt *do_authentication2(void);
+void   do_authentication(Authctxt *);
+void   do_authentication2(Authctxt *);
 
-Authctxt *authctxt_new(void);
 void   auth_log(Authctxt *, int, char *, char *);
 void   userauth_finish(Authctxt *, int, char *);
 int    auth_root_allowed(char *);
@@ -155,8 +162,6 @@ char        *get_challenge(Authctxt *);
 int    verify_response(Authctxt *, const char *);
 void   abandon_challenge_response(Authctxt *);
 
-struct passwd * auth_get_user(void);
-
 char   *expand_filename(const char *, struct passwd *);
 char   *authorized_keys_file(struct passwd *);
 char   *authorized_keys_file2(struct passwd *);
index dfe944dd1acd6c6e3822fbed63f0302cf4474511..82fe5fb80c2a642a680b83e20fff19b7528ed80a 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth1.c,v 1.52 2003/08/28 12:54:34 markus Exp $");
+RCSID("$OpenBSD: auth1.c,v 1.55 2003/11/08 16:02:40 jakob Exp $");
 
 #include "xmalloc.h"
 #include "rsa.h"
@@ -139,7 +139,7 @@ do_authloop(Authctxt *authctxt)
                                    BN_num_bits(client_host_key->rsa->n), bits);
                        packet_check_eom();
 
-                       authenticated = auth_rhosts_rsa(pw, client_user,
+                       authenticated = auth_rhosts_rsa(authctxt, client_user,
                            client_host_key);
                        key_free(client_host_key);
 
@@ -156,7 +156,7 @@ do_authloop(Authctxt *authctxt)
                                fatal("do_authloop: BN_new failed");
                        packet_get_bignum(n);
                        packet_check_eom();
-                       authenticated = auth_rsa(pw, n);
+                       authenticated = auth_rsa(authctxt, n);
                        BN_clear_free(n);
                        break;
 
@@ -235,7 +235,7 @@ do_authloop(Authctxt *authctxt)
                if (authenticated &&
                    !check_nt_auth(type == SSH_CMSG_AUTH_PASSWORD, pw)) {
                        packet_disconnect("Authentication rejected for uid %d.",
-                       pw == NULL ? -1 : pw->pw_uid);
+                           pw == NULL ? -1 : pw->pw_uid);
                        authenticated = 0;
                }
 #else
@@ -246,7 +246,7 @@ do_authloop(Authctxt *authctxt)
 #endif
 
 #ifdef USE_PAM
-               if (options.use_pam && authenticated && 
+               if (options.use_pam && authenticated &&
                    !PRIVSEP(do_pam_account()))
                        authenticated = 0;
 #endif
@@ -275,10 +275,9 @@ do_authloop(Authctxt *authctxt)
  * Performs authentication of an incoming connection.  Session key has already
  * been exchanged and encryption is enabled.
  */
-Authctxt *
-do_authentication(void)
+void
+do_authentication(Authctxt *authctxt)
 {
-       Authctxt *authctxt;
        u_int ulen;
        char *user, *style = NULL;
 
@@ -292,7 +291,6 @@ do_authentication(void)
        if ((style = strchr(user, ':')) != NULL)
                *style++ = '\0';
 
-       authctxt = authctxt_new();
        authctxt->user = user;
        authctxt->style = style;
 
@@ -332,6 +330,4 @@ do_authentication(void)
        packet_start(SSH_SMSG_SUCCESS);
        packet_send();
        packet_write_wait();
-
-       return (authctxt);
 }
index 559dac49e0620557d07201a3eb45c104de4695d8..f2fab9e26ace86a51b00dc204edc85a7a7486a4c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: auth2-gss.c,v 1.3 2003/09/01 20:44:54 markus Exp $    */
+/*     $OpenBSD: auth2-gss.c,v 1.7 2003/11/21 11:57:03 djm Exp $       */
 
 /*
  * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
@@ -52,9 +52,13 @@ userauth_external(Authctxt *authctxt)
 
 static void ssh_gssapi_userauth_error(Gssctxt *ctxt);
 static void input_gssapi_token(int type, u_int32_t plen, void *ctxt);
+static void input_gssapi_mic(int type, u_int32_t plen, void *ctxt);
 static void input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt);
 static void input_gssapi_errtok(int, u_int32_t, void *);
 
+static int gssapi_with_mic = 1;        /* flag to toggle "gssapi-with-mic" vs.
+                                  "gssapi" */
+
 /*
  * We only support those mechanisms that we know about (ie ones that we know
  * how to check local user kuserok and the like
@@ -87,6 +91,7 @@ userauth_gssapi(Authctxt *authctxt)
                if (doid)
                        xfree(doid);
 
+               present = 0;
                doid = packet_get_string(&len);
 
                if (doid[0] != SSH_GSS_OIDTYPE || doid[1] != len-2) {
@@ -116,7 +121,7 @@ userauth_gssapi(Authctxt *authctxt)
 
        packet_start(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE);
 
-       /* Return OID in same format as we received it*/
+       /* Return the OID that we received */
        packet_put_string(doid, len);
 
        packet_send();
@@ -136,7 +141,7 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
        Gssctxt *gssctxt;
        gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
        gss_buffer_desc recv_tok;
-       OM_uint32 maj_status, min_status;
+       OM_uint32 maj_status, min_status, flags;
        u_int len;
 
        if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
@@ -149,7 +154,7 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
        packet_check_eom();
 
        maj_status = PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok,
-           &send_tok, NULL));
+           &send_tok, &flags));
 
        xfree(recv_tok.value);
 
@@ -162,7 +167,9 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
                }
                authctxt->postponed = 0;
                dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
-               userauth_finish(authctxt, 0, "gssapi");
+               userauth_finish(authctxt, 0,
+                               gssapi_with_mic ? "gssapi-with-mic" :
+                                                 "gssapi");
        } else {
                if (send_tok.length != 0) {
                        packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
@@ -171,8 +178,13 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
                }
                if (maj_status == GSS_S_COMPLETE) {
                        dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
-                       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE,
-                                    &input_gssapi_exchange_complete);
+                       if (flags & GSS_C_INTEG_FLAG && gssapi_with_mic)
+                               dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC,
+                                   &input_gssapi_mic);
+                       else
+                               dispatch_set(
+                                   SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE,
+                                   &input_gssapi_exchange_complete);
                }
        }
 
@@ -213,6 +225,28 @@ input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
        gss_release_buffer(&maj_status, &send_tok);
 }
 
+static void
+gssapi_set_implicit_username(Authctxt *authctxt)
+{
+    if ((strcmp(authctxt->user, "") == 0) && (authctxt->pw == NULL)) {
+       char *lname = NULL;
+       PRIVSEP(ssh_gssapi_localname(&lname));
+       if (lname && lname[0] != '\0') {
+           xfree(authctxt->user);
+           authctxt->user = lname;
+           debug("set username to %s from gssapi context", lname);
+           authctxt->pw = PRIVSEP(getpwnamallow(authctxt->user));
+       } else {
+           debug("failed to set username from gssapi context");
+       }
+    }
+    if (authctxt->pw) {
+#ifdef USE_PAM
+       PRIVSEP(start_pam(authctxt->pw->pw_name));
+#endif
+    }
+}
+
 /*
  * This is called when the client thinks we've completed authentication.
  * It should only be enabled in the dispatch handler by the function above,
@@ -229,46 +263,91 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt)
        if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
                fatal("No authentication or GSSAPI context");
 
-       if ((strcmp(authctxt->user, "") == 0) && (authctxt->pw == NULL)) {
-           char *lname = NULL;
-           PRIVSEP(ssh_gssapi_localname(&lname));
-           if (lname && lname[0] != '\0') {
-               xfree(authctxt->user);
-               authctxt->user = lname;
-               debug("set username to %s from gssapi context", lname);
-               authctxt->pw = PRIVSEP(getpwnamallow(authctxt->user));
-           } else {
-               debug("failed to set username from gssapi context");
-           }
-       }
-       if (authctxt->pw) {
-#ifdef USE_PAM
-           PRIVSEP(start_pam(authctxt->pw->pw_name));
-#endif
-       } else {
-           authctxt->valid = 0;
-           authenticated = 0;
-           goto finish;
-       }
+       gssapi_set_implicit_username(authctxt);
 
        gssctxt = authctxt->methoddata;
 
        /*
-        * We don't need to check the status, because the stored credentials
-        * which userok uses are only populated once the context init step
-        * has returned complete.
+        * We don't need to check the status, because we're only enabled in
+        * the dispatcher once the exchange is complete
         */
 
        packet_check_eom();
 
-       authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
+       if (strcmp(authctxt->user, "") != 0) {
+           authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
+       } else {
+           authenticated = 0;
+       }
 
 finish:
        authctxt->postponed = 0;
        dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
        dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
+       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
        dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
-       userauth_finish(authctxt, authenticated, "gssapi");
+       userauth_finish(authctxt, authenticated,
+                       gssapi_with_mic ? "gssapi-with-mic" : "gssapi");
+}
+
+static int
+userauth_gssapi_with_mic(Authctxt *authctxt)
+{
+    gssapi_with_mic = 1;
+    return userauth_gssapi(authctxt);
+}
+
+static int
+userauth_gssapi_without_mic(Authctxt *authctxt)
+{
+    gssapi_with_mic = 0;
+    return userauth_gssapi(authctxt);
+}
+
+static void
+input_gssapi_mic(int type, u_int32_t plen, void *ctxt)
+{
+       Authctxt *authctxt = ctxt;
+       Gssctxt *gssctxt;
+       int authenticated = 0;
+       Buffer b;
+       gss_buffer_desc mic, gssbuf;
+       u_int len;
+
+       if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
+               fatal("No authentication or GSSAPI context");
+
+       gssapi_set_implicit_username(authctxt);
+
+       gssctxt = authctxt->methoddata;
+
+       mic.value = packet_get_string(&len);
+       mic.length = len;
+
+       ssh_gssapi_buildmic(&b, authctxt->user, authctxt->service,
+           "gssapi-with-mic");
+
+       gssbuf.value = buffer_ptr(&b);
+       gssbuf.length = buffer_len(&b);
+
+       if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic))))
+           if (strcmp(authctxt->user, "") != 0) {
+               authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
+           } else {
+               authenticated = 0;
+           }
+       else
+               logit("GSSAPI MIC check failed");
+
+       buffer_free(&b);
+       xfree(mic.value);
+
+       authctxt->postponed = 0;
+       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
+       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
+       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
+       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
+       userauth_finish(authctxt, authenticated, "gssapi-with-mic");
 }
 
 static void ssh_gssapi_userauth_error(Gssctxt *ctxt) {
@@ -295,8 +374,14 @@ Authmethod method_external = {
 };
        
 Authmethod method_gssapi = {
+       "gssapi-with-mic",
+       userauth_gssapi_with_mic,
+       &options.gss_authentication
+};
+
+Authmethod method_gssapi_compat = {
        "gssapi",
-       userauth_gssapi,
+       userauth_gssapi_without_mic,
        &options.gss_authentication
 };
 
index 505d3eff458758323cb9688f12692857c587b7f1..1111ed67a643223635f25ae73b528213a74a4099 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth2-hostbased.c,v 1.5 2003/06/24 08:23:46 markus Exp $");
+RCSID("$OpenBSD: auth2-hostbased.c,v 1.6 2004/01/19 21:25:15 markus Exp $");
 
 #include "ssh2.h"
 #include "xmalloc.h"
@@ -114,7 +114,7 @@ userauth_hostbased(Authctxt *authctxt)
                        buffer_len(&b))) == 1)
                authenticated = 1;
 
-       buffer_clear(&b);
+       buffer_free(&b);
 done:
        debug2("userauth_hostbased: authenticated %d", authenticated);
        if (key != NULL)
index 67fb4c9216be4445e0e4200d58b6062342bc6f2b..a4f482d2e287fc3fabab717791df4c7db37997de 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth2-passwd.c,v 1.4 2003/08/26 09:58:43 markus Exp $");
+RCSID("$OpenBSD: auth2-passwd.c,v 1.5 2003/12/31 00:24:50 dtucker Exp $");
 
 #include "xmalloc.h"
 #include "packet.h"
@@ -38,16 +38,24 @@ extern ServerOptions options;
 static int
 userauth_passwd(Authctxt *authctxt)
 {
-       char *password;
+       char *password, *newpass;
        int authenticated = 0;
        int change;
-       u_int len;
+       u_int len, newlen;
+
        change = packet_get_char();
-       if (change)
-               logit("password change not supported");
        password = packet_get_string(&len);
+       if (change) {
+               /* discard new password from packet */
+               newpass = packet_get_string(&newlen);
+               memset(newpass, 0, newlen);
+               xfree(newpass);
+       }
        packet_check_eom();
-       if (PRIVSEP(auth_password(authctxt, password)) == 1
+
+       if (change)
+               logit("password change not supported");
+       else if (PRIVSEP(auth_password(authctxt, password)) == 1
 #ifdef HAVE_CYGWIN
            && check_nt_auth(1, authctxt->pw)
 #endif
index d51e939f19d42ba087b0b56ff8860d085e6afe90..3063eecc3974d63c6cc50f11a0aec81dde57ae4c 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth2-pubkey.c,v 1.4 2003/06/24 08:23:46 markus Exp $");
+RCSID("$OpenBSD: auth2-pubkey.c,v 1.6 2004/01/19 21:25:15 markus Exp $");
 
 #include "ssh2.h"
 #include "xmalloc.h"
@@ -123,9 +123,9 @@ userauth_pubkey(Authctxt *authctxt)
                authenticated = 0;
                if (PRIVSEP(user_key_allowed(authctxt->pw, key)) &&
                    PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
-                               buffer_len(&b))) == 1)
+                   buffer_len(&b))) == 1)
                        authenticated = 1;
-               buffer_clear(&b);
+               buffer_free(&b);
                xfree(sig);
        } else {
                debug("test whether pkalg/pkblob are acceptable");
@@ -175,9 +175,6 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
        Key *found;
        char *fp;
 
-       if (pw == NULL)
-               return 0;
-
        /* Temporarily use the user's uid. */
        temporarily_use_uid(pw);
 
index 5144e57a612ac4d8047c00861a9820c19c9baa75..1ec009562cfa97cf259b6b6a3397784d2410b1f8 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth2.c,v 1.102 2003/08/26 09:58:43 markus Exp $");
+RCSID("$OpenBSD: auth2.c,v 1.104 2003/11/04 08:54:09 djm Exp $");
 
 #include "ssh2.h"
 #include "xmalloc.h"
@@ -44,8 +44,6 @@ extern ServerOptions options;
 extern u_char *session_id2;
 extern u_int session_id2_len;
 
-Authctxt *x_authctxt = NULL;
-
 /* methods */
 
 extern Authmethod method_none;
@@ -56,17 +54,16 @@ extern Authmethod method_hostbased;
 #ifdef GSSAPI
 extern Authmethod method_external;
 extern Authmethod method_gssapi;
+extern Authmethod method_gssapi_compat;
 #endif
 
 Authmethod *authmethods[] = {
        &method_none,
-#ifdef GSSAPI
-       &method_external,
-       &method_gssapi,
-#endif
        &method_pubkey,
 #ifdef GSSAPI
+       &method_external,
        &method_gssapi,
+       &method_gssapi_compat,
 #endif
        &method_passwd,
        &method_kbdint,
@@ -83,19 +80,14 @@ static void input_userauth_request(int, u_int32_t, void *);
 static Authmethod *authmethod_lookup(const char *);
 static char *authmethods_get(void);
 int user_key_allowed(struct passwd *, Key *);
-int hostbased_key_allowed(struct passwd *, const char *, char *, Key *);
 
 /*
  * loop until authctxt->success == TRUE
  */
 
-Authctxt *
-do_authentication2(void)
+void
+do_authentication2(Authctxt *authctxt)
 {
-       Authctxt *authctxt = authctxt_new();
-
-       x_authctxt = authctxt;          /*XXX*/
-
        /* challenge-response is implemented via keyboard interactive */
        if (options.challenge_response_authentication)
                options.kbd_interactive_authentication = 1;
@@ -103,8 +95,6 @@ do_authentication2(void)
        dispatch_init(&dispatch_protocol_error);
        dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request);
        dispatch_run(DISPATCH_BLOCK, &authctxt->success, authctxt);
-
-       return (authctxt);
 }
 
 static void
@@ -316,14 +306,6 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method)
        }
 }
 
-/* get current user */
-
-struct passwd*
-auth_get_user(void)
-{
-       return (x_authctxt != NULL && x_authctxt->valid) ? x_authctxt->pw : NULL;
-}
-
 #define        DELIM   ","
 
 static char *
index db98b1ef8cbe25efb14af231565ecb54162bd06f..0bb27c906e38b7da593b30af09c3d4029cc43f6e 100644 (file)
@@ -12,7 +12,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: canohost.c,v 1.37 2003/06/02 09:17:34 markus Exp $");
+RCSID("$OpenBSD: canohost.c,v 1.38 2003/09/23 20:17:11 markus Exp $");
 
 #include "packet.h"
 #include "xmalloc.h"
@@ -20,6 +20,7 @@ RCSID("$OpenBSD: canohost.c,v 1.37 2003/06/02 09:17:34 markus Exp $");
 #include "canohost.h"
 
 static void check_ip_options(int, char *);
+static void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *);
 
 /*
  * Return the canonical name of the host at the other end of the socket. The
@@ -40,31 +41,11 @@ get_remote_hostname(int socket, int use_dns)
        memset(&from, 0, sizeof(from));
        if (getpeername(socket, (struct sockaddr *)&from, &fromlen) < 0) {
                debug("getpeername failed: %.100s", strerror(errno));
-               fatal_cleanup();
+               cleanup_exit(255);
        }
-#ifdef IPV4_IN_IPV6
-       if (from.ss_family == AF_INET6) {
-               struct sockaddr_in6 *from6 = (struct sockaddr_in6 *)&from;
-
-               /* Detect IPv4 in IPv6 mapped address and convert it to */
-               /* plain (AF_INET) IPv4 address */
-               if (IN6_IS_ADDR_V4MAPPED(&from6->sin6_addr)) {
-                       struct sockaddr_in *from4 = (struct sockaddr_in *)&from;
-                       struct in_addr addr;
-                       u_int16_t port;
-
-                       memcpy(&addr, ((char *)&from6->sin6_addr) + 12, sizeof(addr));
-                       port = from6->sin6_port;
-
-                       memset(&from, 0, sizeof(from));
-
-                       from4->sin_family = AF_INET;
-                       fromlen = sizeof(*from4);
-                       memcpy(&from4->sin_addr, &addr, sizeof(addr));
-                       from4->sin_port = port;
-               }
-       }
-#endif
+
+       ipv64_normalise_mapped(&from, &fromlen);
+
        if (from.ss_family == AF_INET6)
                fromlen = sizeof(struct sockaddr_in6);
 
@@ -185,6 +166,31 @@ check_ip_options(int socket, char *ipaddr)
 #endif /* IP_OPTIONS */
 }
 
+static void
+ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len)
+{
+       struct sockaddr_in6 *a6 = (struct sockaddr_in6 *)addr;
+       struct sockaddr_in *a4 = (struct sockaddr_in *)addr;
+       struct in_addr inaddr;
+       u_int16_t port;
+
+       if (addr->ss_family != AF_INET6 || 
+           !IN6_IS_ADDR_V4MAPPED(&a6->sin6_addr))
+               return;
+
+       debug3("Normalising mapped IPv4 in IPv6 address");
+
+       memcpy(&inaddr, ((char *)&a6->sin6_addr) + 12, sizeof(inaddr));
+       port = a6->sin6_port;
+
+       memset(addr, 0, sizeof(*a4));
+
+       a4->sin_family = AF_INET;
+       *len = sizeof(*a4);
+       memcpy(&a4->sin_addr, &inaddr, sizeof(inaddr));
+       a4->sin_port = port;
+}
+
 /*
  * Return the canonical name of the host in the other side of the current
  * connection.  The host name is cached, so it is efficient to call this
@@ -296,7 +302,7 @@ get_remote_ipaddr(void)
                        canonical_host_ip =
                            get_peer_ipaddr(packet_get_connection_in());
                        if (canonical_host_ip == NULL)
-                               fatal_cleanup();
+                               cleanup_exit(255);
                } else {
                        /* If not on socket, return UNKNOWN. */
                        canonical_host_ip = xstrdup("UNKNOWN");
@@ -336,7 +342,7 @@ get_sock_port(int sock, int local)
        } else {
                if (getpeername(sock, (struct sockaddr *)&from, &fromlen) < 0) {
                        debug("getpeername failed: %.100s", strerror(errno));
-                       fatal_cleanup();
+                       cleanup_exit(255);
                }
        }
 
index 6f9f5dd6b5d48b405b185e38af9aa7d466baf258..f815e8ae524e786439da56a5f59fa940ef3f5732 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: cipher-3des1.c,v 1.1 2003/05/15 03:08:29 markus Exp $");
+RCSID("$OpenBSD: cipher-3des1.c,v 1.2 2003/12/22 20:29:55 markus Exp $");
 
 #include <openssl/evp.h>
 #include "xmalloc.h"
@@ -126,6 +126,9 @@ ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx)
        struct ssh1_3des_ctx *c;
 
        if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
+               EVP_CIPHER_CTX_cleanup(&c->k1);
+               EVP_CIPHER_CTX_cleanup(&c->k2);
+               EVP_CIPHER_CTX_cleanup(&c->k3);
                memset(c, 0, sizeof(*c));
                xfree(c);
                EVP_CIPHER_CTX_set_app_data(ctx, NULL);
index 7ba950191169cad64fa8cbc6aa3463bd3f7d6fde..22d500d4290ab47cdd48bab52fde278d8dc8005c 100644 (file)
@@ -24,7 +24,7 @@
 
 #include "includes.h"
 #if OPENSSL_VERSION_NUMBER < 0x00907000L
-RCSID("$OpenBSD: cipher-aes.c,v 1.1 2003/05/15 03:08:29 markus Exp $");
+RCSID("$OpenBSD: cipher-aes.c,v 1.2 2003/11/26 21:44:29 djm Exp $");
 
 #include <openssl/evp.h>
 #include "rijndael.h"
index 4f0814b22d285432d43bfead9c10237ed88a0615..395dabedd554403b8211e5b6e74bdee8d2817d18 100644 (file)
@@ -14,7 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 #include "includes.h"
-RCSID("$OpenBSD: cipher-ctr.c,v 1.2 2003/06/17 18:14:23 markus Exp $");
+RCSID("$OpenBSD: cipher-ctr.c,v 1.4 2004/02/06 23:41:13 dtucker Exp $");
 
 #include <openssl/evp.h>
 
@@ -94,7 +94,8 @@ ssh_aes_ctr_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
                EVP_CIPHER_CTX_set_app_data(ctx, c);
        }
        if (key != NULL)
-                AES_set_encrypt_key(key, ctx->key_len * 8, &c->aes_ctx);
+               AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
+                    &c->aes_ctx);
        if (iv != NULL)
                memcpy(c->aes_counter, iv, AES_BLOCK_SIZE);
        return (1);
index ce533670b85a10220eb2b52f0625942ed9f3adc7..c13ff58621eacdf15907fcfd8e46dfbad0b436eb 100644 (file)
@@ -35,7 +35,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: cipher.c,v 1.65 2003/05/17 04:27:52 markus Exp $");
+RCSID("$OpenBSD: cipher.c,v 1.68 2004/01/23 19:26:33 hshoexer Exp $");
 
 #include "xmalloc.h"
 #include "log.h"
@@ -52,6 +52,17 @@ RCSID("$OpenBSD: cipher.c,v 1.65 2003/05/17 04:27:52 markus Exp $");
 extern const EVP_CIPHER *evp_rijndael(void);
 extern void ssh_rijndael_iv(EVP_CIPHER_CTX *, int, u_char *, u_int);
 #endif
+
+#if !defined(EVP_CTRL_SET_ACSS_MODE)
+# if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
+extern const EVP_CIPHER *evp_acss(void);
+#  define EVP_acss evp_acss
+#  define EVP_CTRL_SET_ACSS_MODE xxx   /* used below */
+# else
+#  define EVP_acss NULL /* Don't try to support ACSS on older OpenSSL */
+# endif /* (OPENSSL_VERSION_NUMBER >= 0x00906000L) */
+#endif /* !defined(EVP_CTRL_SET_ACSS_MODE) */
+
 extern const EVP_CIPHER *evp_ssh1_bf(void);
 extern const EVP_CIPHER *evp_ssh1_3des(void);
 extern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);
@@ -87,31 +98,33 @@ struct Cipher {
        { "rijndael-cbc@lysator.liu.se",
                                SSH_CIPHER_SSH2, 16, 32, EVP_aes_256_cbc },
 #endif
-#if OPENSSL_VERSION_NUMBER >= 0x00906000L
+#if OPENSSL_VERSION_NUMBER >= 0x00905000L
        { "aes128-ctr",         SSH_CIPHER_SSH2, 16, 16, evp_aes_128_ctr },
        { "aes192-ctr",         SSH_CIPHER_SSH2, 16, 24, evp_aes_128_ctr },
        { "aes256-ctr",         SSH_CIPHER_SSH2, 16, 32, evp_aes_128_ctr },
 #endif
-
+#if defined(EVP_CTRL_SET_ACSS_MODE)
+       { "acss@openssh.org",   SSH_CIPHER_SSH2, 16, 5, EVP_acss },
+#endif
        { NULL,                 SSH_CIPHER_ILLEGAL, 0, 0, NULL }
 };
 
 /*--*/
 
 u_int
-cipher_blocksize(Cipher *c)
+cipher_blocksize(const Cipher *c)
 {
        return (c->block_size);
 }
 
 u_int
-cipher_keylen(Cipher *c)
+cipher_keylen(const Cipher *c)
 {
        return (c->key_len);
 }
 
 u_int
-cipher_get_number(Cipher *c)
+cipher_get_number(const Cipher *c)
 {
        return (c->number);
 }
@@ -311,7 +324,7 @@ cipher_set_key_string(CipherContext *cc, Cipher *cipher,
  */
 
 int
-cipher_get_keyiv_len(CipherContext *cc)
+cipher_get_keyiv_len(const CipherContext *cc)
 {
        Cipher *c = cc->cipher;
        int ivlen;
@@ -397,12 +410,12 @@ cipher_set_keyiv(CipherContext *cc, u_char *iv)
 #endif
 
 int
-cipher_get_keycontext(CipherContext *cc, u_char *dat)
+cipher_get_keycontext(const CipherContext *cc, u_char *dat)
 {
        Cipher *c = cc->cipher;
        int plen = 0;
 
-       if (c->evptype == EVP_rc4) {
+       if (c->evptype == EVP_rc4 || c->evptype == EVP_acss) {
                plen = EVP_X_STATE_LEN(cc->evp);
                if (dat == NULL)
                        return (plen);
@@ -417,7 +430,7 @@ cipher_set_keycontext(CipherContext *cc, u_char *dat)
        Cipher *c = cc->cipher;
        int plen;
 
-       if (c->evptype == EVP_rc4) {
+       if (c->evptype == EVP_rc4 || c->evptype == EVP_acss) {
                plen = EVP_X_STATE_LEN(cc->evp);
                memcpy(EVP_X_STATE(cc->evp), dat, plen);
        }
index 6bc44d9f128cdfb592280b6eff56b85837dd8308..4e1c58422dc0c10a137000635692959addbb6b6b 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: compat.c,v 1.69 2003/08/29 10:03:15 markus Exp $");
+RCSID("$OpenBSD: compat.c,v 1.70 2003/11/02 11:01:03 markus Exp $");
 
 #include "buffer.h"
 #include "packet.h"
index 2d875369e1affa136e9860a64844cf8b317dc209..99ae7ab2111124465eb39701614d61f044e8b389 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: compat.h,v 1.36 2003/08/29 10:03:15 markus Exp $      */
+/*     $OpenBSD: compat.h,v 1.37 2003/11/02 11:01:03 markus Exp $      */
 
 /*
  * Copyright (c) 1999, 2000, 2001 Markus Friedl.  All rights reserved.
index f925b5f5397e7f7d7396fc1669e0ee628309c643..7a254b90ada8ac959ba16f4a6f9f53bb185adff6 100644 (file)
@@ -42,24 +42,39 @@ else
        fi
 fi
 
+AC_PATH_PROG(PATH_PASSWD_PROG, passwd)
+if test ! -z "$PATH_PASSWD_PROG" ; then
+       AC_DEFINE_UNQUOTED(_PATH_PASSWD_PROG, "$PATH_PASSWD_PROG")
+fi
+
 if test -z "$LD" ; then
        LD=$CC
 fi
 AC_SUBST(LD)
        
 AC_C_INLINE
-if test "$GCC" = "yes" || test "$GCC" = "egcs"; then 
+if test "$GCC" = "yes" || test "$GCC" = "egcs"; then
        CFLAGS="$CFLAGS -Wall -Wpointer-arith -Wno-uninitialized"
 fi
 
+AC_ARG_WITH(rpath,
+       [  --without-rpath         Disable auto-added -R linker paths],
+       [
+               if test "x$withval" = "xno" ; then      
+                       need_dash_r=""
+               fi
+               if test "x$withval" = "xyes" ; then
+                       need_dash_r=1
+               fi
+       ]
+)
+
 # Check for some target-specific stuff
 case "$host" in
 *-*-aix*)
-       CPPFLAGS="$CPPFLAGS -I/usr/local/include"
-       LDFLAGS="$LDFLAGS -L/usr/local/lib"
-       AC_MSG_CHECKING([how to specify blibpath for linker ($LD)]) 
+       AC_MSG_CHECKING([how to specify blibpath for linker ($LD)])
        if (test -z "$blibpath"); then
-               blibpath="/usr/lib:/lib:/usr/local/lib"
+               blibpath="/usr/lib:/lib"
        fi
        saved_LDFLAGS="$LDFLAGS"
        for tryflags in -blibpath: -Wl,-blibpath: -Wl,-rpath, ;do
@@ -120,6 +135,9 @@ case "$host" in
        ;;
 *-*-dgux*)
        AC_DEFINE(IP_TOS_IS_BROKEN)
+       AC_DEFINE(SETEUID_BREAKS_SETUID)
+       AC_DEFINE(BROKEN_SETREUID)
+       AC_DEFINE(BROKEN_SETREGID)
        ;;
 *-*-darwin*)
        AC_MSG_CHECKING(if we have working getaddrinfo)
@@ -135,6 +153,7 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
        AC_DEFINE(SETEUID_BREAKS_SETUID)
        AC_DEFINE(BROKEN_SETREUID)
        AC_DEFINE(BROKEN_SETREGID)
+       AC_DEFINE_UNQUOTED(BIND_8_COMPAT, 1)
        ;;
 *-*-hpux10.26)
        if test -z "$GCC"; then
@@ -146,8 +165,6 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
        AC_DEFINE(USE_PIPES)
        AC_DEFINE(LOGIN_NO_ENDOPT)
        AC_DEFINE(LOGIN_NEEDS_UTMPX)
-       AC_DEFINE(DISABLE_SHADOW)
-       AC_DEFINE(DISABLE_UTMP)
        AC_DEFINE(LOCKED_PASSWD_STRING, "*")
        AC_DEFINE(SPT_TYPE,SPT_PSTAT)
        LIBS="$LIBS -lsec -lsecpw"
@@ -163,8 +180,6 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
        AC_DEFINE(USE_PIPES)
        AC_DEFINE(LOGIN_NO_ENDOPT)
        AC_DEFINE(LOGIN_NEEDS_UTMPX)
-       AC_DEFINE(DISABLE_SHADOW)
-       AC_DEFINE(DISABLE_UTMP)
        AC_DEFINE(LOCKED_PASSWD_STRING, "*")
        AC_DEFINE(SPT_TYPE,SPT_PSTAT)
        LIBS="$LIBS -lsec"
@@ -177,24 +192,26 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
        AC_DEFINE(USE_PIPES)
        AC_DEFINE(LOGIN_NO_ENDOPT)
        AC_DEFINE(LOGIN_NEEDS_UTMPX)
-       AC_DEFINE(DISABLE_SHADOW)
        AC_DEFINE(DISABLE_UTMP)
        AC_DEFINE(LOCKED_PASSWD_STRING, "*")
        AC_DEFINE(SPT_TYPE,SPT_PSTAT)
+       case "$host" in
+       *-*-hpux11.11*)
+               AC_DEFINE(BROKEN_GETADDRINFO);;
+       esac
        LIBS="$LIBS -lsec"
        AC_CHECK_LIB(xnet, t_error, ,AC_MSG_ERROR([*** -lxnet needed on HP-UX - check config.log ***]))
        ;;
 *-*-irix5*)
-       CPPFLAGS="$CPPFLAGS -I/usr/local/include"
-       LDFLAGS="$LDFLAGS"
        PATH="$PATH:/usr/etc"
        AC_DEFINE(BROKEN_INET_NTOA)
+       AC_DEFINE(SETEUID_BREAKS_SETUID)
+       AC_DEFINE(BROKEN_SETREUID)
+       AC_DEFINE(BROKEN_SETREGID)
        AC_DEFINE(WITH_ABBREV_NO_TTY)
        AC_DEFINE(LOCKED_PASSWD_STRING, "*LK*")
        ;;
 *-*-irix6*)
-       CPPFLAGS="$CPPFLAGS -I/usr/local/include"
-       LDFLAGS="$LDFLAGS"
        PATH="$PATH:/usr/etc"
        AC_DEFINE(WITH_IRIX_ARRAY)
        AC_DEFINE(WITH_IRIX_PROJECT)
@@ -228,7 +245,9 @@ mips-sony-bsd|mips-sony-newsos4)
        ;;
 *-*-netbsd*)
        check_for_libcrypt_before=1
-       need_dash_r=1
+       if test "x$withval" != "xno" ; then     
+               need_dash_r=1
+       fi
        ;;
 *-*-freebsd*)
        check_for_libcrypt_later=1
@@ -247,13 +266,8 @@ mips-sony-bsd|mips-sony-newsos4)
        AC_DEFINE(BROKEN_REALPATH)
        AC_DEFINE(USE_PIPES)
        AC_DEFINE(BROKEN_SAVED_UIDS)
-       CPPFLAGS="$CPPFLAGS -I/usr/local/include"
-       CFLAGS="$CFLAGS"
        ;;
 *-*-solaris*)
-       CPPFLAGS="$CPPFLAGS -I/usr/local/include"
-       LDFLAGS="$LDFLAGS -L/usr/local/lib -R/usr/local/lib" 
-       need_dash_r=1
        AC_DEFINE(PAM_SUN_CODEBASE)
        AC_DEFINE(LOGIN_NEEDS_UTMPX)
        AC_DEFINE(LOGIN_NEEDS_TERM)
@@ -284,8 +298,6 @@ mips-sony-bsd|mips-sony-newsos4)
        AC_DEFINE(USE_PIPES)
        ;;
 *-ncr-sysv*)
-       CPPFLAGS="$CPPFLAGS -I/usr/local/include"
-       LDFLAGS="$LDFLAGS -L/usr/local/lib"
        LIBS="$LIBS -lc89"
        AC_DEFINE(USE_PIPES)
        AC_DEFINE(SSHD_ACQUIRES_CTTY)
@@ -294,12 +306,14 @@ mips-sony-bsd|mips-sony-newsos4)
        AC_DEFINE(BROKEN_SETREGID)
        ;;
 *-sni-sysv*)
-       CPPFLAGS="$CPPFLAGS -I/usr/local/include"
        # /usr/ucblib MUST NOT be searched on ReliantUNIX
-       LDFLAGS="$LDFLAGS -L/usr/local/lib"
+       AC_CHECK_LIB(dl, dlsym, ,)
        IPADDR_IN_DISPLAY=yes
        AC_DEFINE(USE_PIPES)
        AC_DEFINE(IP_TOS_IS_BROKEN)
+       AC_DEFINE(SETEUID_BREAKS_SETUID)
+       AC_DEFINE(BROKEN_SETREUID)
+       AC_DEFINE(BROKEN_SETREGID)
        AC_DEFINE(SSHD_ACQUIRES_CTTY)
        external_path_file=/etc/default/login
        # /usr/ucblib/libucb.a no longer needed on ReliantUNIX
@@ -307,29 +321,22 @@ mips-sony-bsd|mips-sony-newsos4)
        # otherwise you will find lots of "SIOCGPGRP errno 22" on syslog
        ;;
 *-*-sysv4.2*)
-       CPPFLAGS="$CPPFLAGS -I/usr/local/include"
-       LDFLAGS="$LDFLAGS -L/usr/local/lib"
        AC_DEFINE(USE_PIPES)
        AC_DEFINE(SETEUID_BREAKS_SETUID)
        AC_DEFINE(BROKEN_SETREUID)
        AC_DEFINE(BROKEN_SETREGID)
        ;;
 *-*-sysv5*)
-       CPPFLAGS="$CPPFLAGS -I/usr/local/include"
-       LDFLAGS="$LDFLAGS -L/usr/local/lib"
        AC_DEFINE(USE_PIPES)
        AC_DEFINE(SETEUID_BREAKS_SETUID)
        AC_DEFINE(BROKEN_SETREUID)
        AC_DEFINE(BROKEN_SETREGID)
        ;;
 *-*-sysv*)
-       CPPFLAGS="$CPPFLAGS -I/usr/local/include"
-       LDFLAGS="$LDFLAGS -L/usr/local/lib"
        ;;
 *-*-sco3.2v4*)
-       CPPFLAGS="$CPPFLAGS -Dftruncate=chsize -I/usr/local/include"
-       LDFLAGS="$LDFLAGS -L/usr/local/lib"
-       LIBS="$LIBS -los -lprot -lx -ltinfo -lm"
+       CPPFLAGS="$CPPFLAGS -Dftruncate=chsize"
+       LIBS="$LIBS -los -lprot -lcrypt_i -lx -ltinfo -lm"
        RANLIB=true
        no_dev_ptmx=1
        AC_DEFINE(BROKEN_SYS_TERMIO_H)
@@ -346,8 +353,6 @@ mips-sony-bsd|mips-sony-newsos4)
        if test -z "$GCC"; then
                CFLAGS="$CFLAGS -belf"
        fi
-       CPPFLAGS="$CPPFLAGS -I/usr/local/include"
-       LDFLAGS="$LDFLAGS -L/usr/local/lib"
        LIBS="$LIBS -lprot -lx -ltinfo -lm"
        no_dev_ptmx=1
        AC_DEFINE(USE_PIPES)
@@ -362,6 +367,10 @@ mips-sony-bsd|mips-sony-newsos4)
        MANTYPE=man
        ;;
 *-*-unicosmk*)
+       AC_DEFINE(NO_SSH_LASTLOG)
+       AC_DEFINE(SETEUID_BREAKS_SETUID)
+       AC_DEFINE(BROKEN_SETREUID)
+       AC_DEFINE(BROKEN_SETREGID)
        AC_DEFINE(USE_PIPES)
        AC_DEFINE(DISABLE_FD_PASSING)
        LDFLAGS="$LDFLAGS"
@@ -369,14 +378,20 @@ mips-sony-bsd|mips-sony-newsos4)
        MANTYPE=cat
        ;;
 *-*-unicosmp*)
+       AC_DEFINE(SETEUID_BREAKS_SETUID)
+       AC_DEFINE(BROKEN_SETREUID)
+       AC_DEFINE(BROKEN_SETREGID)
        AC_DEFINE(WITH_ABBREV_NO_TTY)
        AC_DEFINE(USE_PIPES)
        AC_DEFINE(DISABLE_FD_PASSING)
        LDFLAGS="$LDFLAGS"
-       LIBS="$LIBS -lgen -lacid"
+       LIBS="$LIBS -lgen -lacid -ldb"
        MANTYPE=cat
        ;;
 *-*-unicos*)
+       AC_DEFINE(SETEUID_BREAKS_SETUID)
+       AC_DEFINE(BROKEN_SETREUID)
+       AC_DEFINE(BROKEN_SETREGID)
        AC_DEFINE(USE_PIPES)
        AC_DEFINE(DISABLE_FD_PASSING)
        AC_DEFINE(NO_SSH_LASTLOG)
@@ -405,14 +420,13 @@ mips-sony-bsd|mips-sony-newsos4)
                        LIBS="$LIBS -lsecurity -ldb -lm -laud"
                else
                        AC_MSG_RESULT(no)
+                       AC_DEFINE(LOCKED_PASSWD_SUBSTR, "Nologin")
                fi
        fi
-       AC_DEFINE(DISABLE_FD_PASSING)
        AC_DEFINE(BROKEN_GETADDRINFO)
        AC_DEFINE(SETEUID_BREAKS_SETUID)
        AC_DEFINE(BROKEN_SETREUID)
        AC_DEFINE(BROKEN_SETREGID)
-       AC_DEFINE(LOCKED_PASSWD_SUBSTR, "Nologin")
        ;;
 
 *-*-nto-qnx)
@@ -474,11 +488,11 @@ int main(){exit(0);}
 AC_CHECK_HEADERS(bstring.h crypt.h endian.h features.h floatingpoint.h \
        getopt.h glob.h ia.h lastlog.h limits.h login.h \
        login_cap.h maillock.h netdb.h netgroup.h \
-       netinet/in_systm.h paths.h pty.h readpassphrase.h \
+       netinet/in_systm.h pam/pam_appl.h paths.h pty.h readpassphrase.h \
        rpc/types.h security/pam_appl.h shadow.h stddef.h stdint.h \
        strings.h sys/strtio.h sys/audit.h sys/bitypes.h sys/bsdtty.h \
-       sys/cdefs.h sys/mman.h sys/pstat.h sys/select.h sys/stat.h \
-       sys/stropts.h sys/sysmacros.h sys/time.h sys/timers.h \
+       sys/cdefs.h sys/mman.h sys/pstat.h sys/ptms.h sys/select.h sys/stat.h \
+       sys/stream.h sys/stropts.h sys/sysmacros.h sys/time.h sys/timers.h \
        sys/un.h time.h tmpdir.h ttyent.h usersec.h \
        util.h utime.h utmp.h utmpx.h vis.h)
 
@@ -534,18 +548,6 @@ AC_CHECK_FUNC(getspnam, ,
        AC_CHECK_LIB(gen, getspnam, LIBS="$LIBS -lgen"))
 AC_SEARCH_LIBS(basename, gen, AC_DEFINE(HAVE_BASENAME))
 
-AC_ARG_WITH(rpath,
-       [  --without-rpath         Disable auto-added -R linker paths],
-       [
-               if test "x$withval" = "xno" ; then      
-                       need_dash_r=""
-               fi
-               if test "x$withval" = "xyes" ; then
-                       need_dash_r=1
-               fi
-       ]
-)
-
 dnl zlib is required
 AC_ARG_WITH(zlib,
        [  --with-zlib=PATH        Use zlib in PATH],
@@ -574,13 +576,70 @@ AC_ARG_WITH(zlib,
        ]
 )
 
-AC_CHECK_LIB(z, deflate, ,AC_MSG_ERROR([*** zlib missing - please install first or check config.log ***]))
+AC_CHECK_LIB(z, deflate, ,
+       [
+               saved_CPPFLAGS="$CPPFLAGS"
+               saved_LDFLAGS="$LDFLAGS"
+               save_LIBS="$LIBS"
+               dnl Check default zlib install dir
+               if test -n "${need_dash_r}"; then
+                       LDFLAGS="-L/usr/local/lib -R/usr/local/lib ${saved_LDFLAGS}"
+               else
+                       LDFLAGS="-L/usr/local/lib ${saved_LDFLAGS}"
+               fi
+               CPPFLAGS="-I/usr/local/include ${saved_CPPFLAGS}"
+               LIBS="$LIBS -lz"
+               AC_TRY_LINK_FUNC(deflate, AC_DEFINE(HAVE_LIBZ),
+                       [
+                               AC_MSG_ERROR([*** zlib missing - please install first or check config.log ***])
+                       ]
+               )
+       ]
+)
+AC_CHECK_HEADER([zlib.h], ,AC_MSG_ERROR([*** zlib.h missing - please install first or check config.log ***]))
+
+AC_ARG_WITH(zlib-version-check,
+       [  --without-zlib-version-check Disable zlib version check],
+       [  if test "x$withval" = "xno" ; then
+               zlib_check_nonfatal=1
+          fi
+       ]
+)
+
+AC_MSG_CHECKING(for zlib 1.1.4 or greater)
+AC_TRY_RUN([
+#include <zlib.h>
+int main()
+{
+       int a, b, c, v;
+       if (sscanf(ZLIB_VERSION, "%d.%d.%d", &a, &b, &c) != 3)
+               exit(1);
+       v = a*1000000 + b*1000 + c;
+       if (v >= 1001004)
+               exit(0);
+       exit(2);
+}
+       ],
+       AC_MSG_RESULT(yes),
+       [ AC_MSG_RESULT(no)
+         if test -z "$zlib_check_nonfatal" ; then
+               AC_MSG_ERROR([*** zlib too old - check config.log ***
+Your reported zlib version has known security problems.  It's possible your
+vendor has fixed these problems without changing the version number.  If you
+are sure this is the case, you can disable the check by running
+"./configure --without-zlib-version-check".
+If you are in doubt, upgrade zlib to version 1.1.4 or greater.])
+         else
+               AC_MSG_WARN([zlib version may have security problems])
+         fi
+       ]
+)
 
 dnl UnixWare 2.x
-AC_CHECK_FUNC(strcasecmp, 
+AC_CHECK_FUNC(strcasecmp,
        [], [ AC_CHECK_LIB(resolv, strcasecmp, LIBS="$LIBS -lresolv") ]
 )
-AC_CHECK_FUNC(utimes, 
+AC_CHECK_FUNC(utimes,
        [], [ AC_CHECK_LIB(c89, utimes, [AC_DEFINE(HAVE_UTIMES)
                                        LIBS="$LIBS -lc89"]) ]
 )
@@ -600,7 +659,7 @@ AC_EGREP_CPP(FOUNDIT,
                #ifdef GLOB_ALTDIRFUNC
                FOUNDIT
                #endif
-       ], 
+       ],
        [
                AC_DEFINE(GLOB_HAS_ALTDIRFUNC)
                AC_MSG_RESULT(yes)
@@ -613,17 +672,17 @@ AC_EGREP_CPP(FOUNDIT,
 # Check for g.gl_matchc glob() extension
 AC_MSG_CHECKING(for gl_matchc field in glob_t)
 AC_EGREP_CPP(FOUNDIT,
-        [
-                #include <glob.h>
+       [
+               #include <glob.h>
                int main(void){glob_t g; g.gl_matchc = 1;}
-        ],
-        [
-                AC_DEFINE(GLOB_HAS_GL_MATCHC)
-                AC_MSG_RESULT(yes)
-        ],
-        [
-                AC_MSG_RESULT(no)
-        ]
+       ],
+       [
+               AC_DEFINE(GLOB_HAS_GL_MATCHC)
+               AC_MSG_RESULT(yes)
+       ],
+       [
+               AC_MSG_RESULT(no)
+       ]
 )
 
 AC_MSG_CHECKING([whether struct dirent allocates space for d_name])
@@ -633,7 +692,7 @@ AC_TRY_RUN(
 #include <dirent.h>
 int main(void){struct dirent d;exit(sizeof(d.d_name)<=sizeof(char));}
        ],
-       [AC_MSG_RESULT(yes)], 
+       [AC_MSG_RESULT(yes)],
        [
                AC_MSG_RESULT(no)
                AC_DEFINE(BROKEN_ONE_BYTE_DIRENT_D_NAME)
@@ -762,6 +821,8 @@ if test "x$gsi_path" != "xno" ; then
                AC_MSG_ERROR(globus-makefile-header failed)
        fi
 
+       AC_DEFINE(HAVE_GSSAPI_H)
+
        LIBS="$LIBS $GSI_LIBS"
        LDFLAGS="$LDFLAGS $GSI_LDFLAGS"
        CPPFLAGS="$CPPFLAGS $GSI_CPPFLAGS"
@@ -785,10 +846,10 @@ AC_SUBST(INSTALL_GSISSH)
 # End Globus/GSI section
 
 # Check whether user wants S/Key support
-SKEY_MSG="no" 
+SKEY_MSG="no"
 AC_ARG_WITH(skey,
        [  --with-skey[[=PATH]]      Enable S/Key support
-                            (optionally in PATH)],
+                           (optionally in PATH)],
        [
                if test "x$withval" != "xno" ; then
 
@@ -799,7 +860,7 @@ AC_ARG_WITH(skey,
 
                        AC_DEFINE(SKEY)
                        LIBS="-lskey $LIBS"
-                       SKEY_MSG="yes" 
+                       SKEY_MSG="yes"
        
                        AC_MSG_CHECKING([for s/key support])
                        AC_TRY_RUN(
@@ -821,7 +882,7 @@ int main() { char *ff = skey_keyinfo(""); ff=""; exit(0); }
 TCPW_MSG="no"
 AC_ARG_WITH(tcp-wrappers,
        [  --with-tcp-wrappers[[=PATH]]      Enable tcpwrappers support
-                            (optionally in PATH)],
+                           (optionally in PATH)],
        [
                if test "x$withval" != "xno" ; then
                        saved_LIBS="$LIBS"
@@ -873,7 +934,7 @@ AC_ARG_WITH(tcp-wrappers,
 
 dnl    Checks for library functions. Please keep in alphabetical order
 AC_CHECK_FUNCS(\
-       arc4random __b64_ntop b64_ntop __b64_pton b64_pton basename \
+       arc4random __b64_ntop b64_ntop __b64_pton b64_pton \
        bcopy bindresvport_sa clock fchmod fchown freeaddrinfo futimes \
        getaddrinfo getcwd getgrouplist getnameinfo getopt \
        getpeereid _getpty getrlimit getttyent glob inet_aton \
@@ -881,10 +942,10 @@ AC_CHECK_FUNCS(\
        mkdtemp mmap ngetaddrinfo nsleep ogetaddrinfo openlog_r openpty \
        pstat readpassphrase realpath recvmsg rresvport_af sendmsg \
        setdtablesize setegid setenv seteuid setgroups setlogin setpcred \
-       setproctitle setregid setresgid setresuid setreuid setrlimit \
+       setproctitle setregid setreuid setrlimit \
        setsid setvbuf sigaction sigvec snprintf socketpair strerror \
-       strlcat strlcpy strmode strnvis sysconf tcgetpgrp \
-       truncate utimes vhangup vsnprintf waitpid \
+       strlcat strlcpy strmode strnvis strtoul sysconf tcgetpgrp \
+       truncate updwtmpx utimes vhangup vsnprintf waitpid \
 )
 
 # IRIX has a const char return value for gai_strerror()
@@ -911,10 +972,38 @@ AC_CHECK_DECL(getrusage, [AC_CHECK_FUNCS(getrusage)])
 dnl tcsendbreak might be a macro
 AC_CHECK_DECL(tcsendbreak,
        [AC_DEFINE(HAVE_TCSENDBREAK)],
-       [AC_CHECK_FUNCS(tcsendbreak)], 
+       [AC_CHECK_FUNCS(tcsendbreak)],
        [#include <termios.h>]
 )
 
+AC_CHECK_FUNCS(setresuid, [
+       dnl Some platorms have setresuid that isn't implemented, test for this
+       AC_MSG_CHECKING(if setresuid seems to work)
+       AC_TRY_RUN([
+#include <stdlib.h>
+#include <errno.h>
+int main(){errno=0; setresuid(0,0,0); if (errno==ENOSYS) exit(1); else exit(0);}
+               ],
+               [AC_MSG_RESULT(yes)],
+               [AC_DEFINE(BROKEN_SETRESUID)
+                AC_MSG_RESULT(not implemented)]
+       )
+])
+
+AC_CHECK_FUNCS(setresgid, [
+       dnl Some platorms have setresgid that isn't implemented, test for this
+       AC_MSG_CHECKING(if setresgid seems to work)
+       AC_TRY_RUN([
+#include <stdlib.h>
+#include <errno.h>
+int main(){errno=0; setresgid(0,0,0); if (errno==ENOSYS) exit(1); else exit(0);}
+               ],
+               [AC_MSG_RESULT(yes)],
+               [AC_DEFINE(BROKEN_SETRESGID)
+                AC_MSG_RESULT(not implemented)]
+       )
+])
+
 dnl    Checks for time functions
 AC_CHECK_FUNCS(gettimeofday time)
 dnl    Checks for utmp functions
@@ -924,12 +1013,12 @@ dnl    Checks for utmpx functions
 AC_CHECK_FUNCS(endutxent getutxent getutxid getutxline pututxline )
 AC_CHECK_FUNCS(setutxent utmpxname)
 
-AC_CHECK_FUNC(daemon, 
+AC_CHECK_FUNC(daemon,
        [AC_DEFINE(HAVE_DAEMON)],
        [AC_CHECK_LIB(bsd, daemon, [LIBS="$LIBS -lbsd"; AC_DEFINE(HAVE_DAEMON)])]
 )
 
-AC_CHECK_FUNC(getpagesize, 
+AC_CHECK_FUNC(getpagesize,
        [AC_DEFINE(HAVE_GETPAGESIZE)],
        [AC_CHECK_LIB(ucb, getpagesize, [LIBS="$LIBS -lucb"; AC_DEFINE(HAVE_GETPAGESIZE)])]
 )
@@ -942,7 +1031,7 @@ if test "x$ac_cv_func_snprintf" = "xyes" ; then
 #include <stdio.h>
 int main(void){char b[5];snprintf(b,5,"123456789");exit(b[4]!='\0');}
                ],
-               [AC_MSG_RESULT(yes)], 
+               [AC_MSG_RESULT(yes)],
                [
                        AC_MSG_RESULT(no)
                        AC_DEFINE(BROKEN_SNPRINTF)
@@ -966,14 +1055,14 @@ unlink(template); exit(0);
        [
                AC_MSG_RESULT(no)
        ],
-       [ 
+       [
                AC_MSG_RESULT(yes)
                AC_DEFINE(HAVE_STRICT_MKSTEMP)
        ],
        [
                AC_MSG_RESULT(yes)
                AC_DEFINE(HAVE_STRICT_MKSTEMP)
-       ] 
+       ]
 )
 fi
 
@@ -998,7 +1087,7 @@ main()
                exit(1);
        } else if (pid > 0) {   /* parent */
                waitpid(pid, &status, 0);
-               if (WIFEXITED(status)) 
+               if (WIFEXITED(status))
                        exit(WEXITSTATUS(status));
                else
                        exit(2);
@@ -1032,7 +1121,8 @@ AC_ARG_WITH(pam,
        [  --with-pam              Enable PAM support ],
        [
                if test "x$withval" != "xno" ; then
-                       if test "x$ac_cv_header_security_pam_appl_h" != "xyes" ; then
+                       if test "x$ac_cv_header_security_pam_appl_h" != "xyes" && \
+                          test "x$ac_cv_header_pam_pam_appl_h" != "xyes" ; then
                                AC_MSG_ERROR([PAM headers not found])
                        fi
 
@@ -1041,7 +1131,6 @@ AC_ARG_WITH(pam,
                        AC_CHECK_FUNCS(pam_getenvlist)
                        AC_CHECK_FUNCS(pam_putenv)
 
-                       disable_shadow=yes
                        PAM_MSG="yes"
 
                        AC_DEFINE(USE_PAM)
@@ -1062,9 +1151,13 @@ if test "x$PAM_MSG" = "xyes" ; then
        AC_TRY_COMPILE(
                [
 #include <stdlib.h>
+#if defined(HAVE_SECURITY_PAM_APPL_H)
 #include <security/pam_appl.h>
-               ], 
-               [(void)pam_strerror((pam_handle_t *)NULL, -1);], 
+#elif defined (HAVE_PAM_PAM_APPL_H)
+#include <pam/pam_appl.h>
+#endif
+               ],
+               [(void)pam_strerror((pam_handle_t *)NULL, -1);],
                [AC_MSG_RESULT(no)],
                [
                        AC_DEFINE(HAVE_OLD_PAM)
@@ -1074,12 +1167,6 @@ if test "x$PAM_MSG" = "xyes" ; then
        )
 fi
 
-# Some systems want crypt() from libcrypt, *not* the version in OpenSSL,
-# because the system crypt() is more featureful.
-if test "x$check_for_libcrypt_before" = "x1"; then
-       AC_CHECK_LIB(crypt, crypt)
-fi
-
 # Search for OpenSSL
 saved_CPPFLAGS="$CPPFLAGS"
 saved_LDFLAGS="$LDFLAGS"
@@ -1109,7 +1196,7 @@ AC_ARG_WITH(ssl-dir,
        ]
 )
 if test -z "$GSI_LIBS" ; then
-LIBS="$LIBS -lcrypto"
+LIBS="-lcrypto $LIBS"
 fi
 AC_TRY_LINK_FUNC(RAND_add, AC_DEFINE(HAVE_OPENSSL),
        [
@@ -1137,12 +1224,12 @@ AC_TRY_RUN(
 #include <openssl/opensslv.h>
 #define DATA "conftest.sslincver"
 int main(void) {
-        FILE *fd;
-        int rc;
+       FILE *fd;
+       int rc;
 
-        fd = fopen(DATA,"w");
-        if(fd == NULL)
-                exit(1);
+       fd = fopen(DATA,"w");
+       if(fd == NULL)
+               exit(1);
 
        if ((rc = fprintf(fd ,"%x (%s)\n", OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_TEXT)) <0)
                exit(1);
@@ -1170,12 +1257,12 @@ AC_TRY_RUN(
 #include <openssl/crypto.h>
 #define DATA "conftest.ssllibver"
 int main(void) {
-        FILE *fd;
-        int rc;
+       FILE *fd;
+       int rc;
 
-        fd = fopen(DATA,"w");
-        if(fd == NULL)
-                exit(1);
+       fd = fopen(DATA,"w");
+       if(fd == NULL)
+               exit(1);
 
        if ((rc = fprintf(fd ,"%x (%s)\n", SSLeay(), SSLeay_version(SSLEAY_VERSION))) <0)
                exit(1);
@@ -1212,8 +1299,14 @@ Also see contrib/findssl.sh for help identifying header/library mismatches.])
        ]
 )
 
-# Some Linux systems (Slackware) need crypt() from libcrypt, *not* the 
-# version in OpenSSL. Skip this for PAM
+# Some systems want crypt() from libcrypt, *not* the version in OpenSSL,
+# because the system crypt() is more featureful.
+if test "x$check_for_libcrypt_before" = "x1"; then
+       AC_CHECK_LIB(crypt, crypt)
+fi
+
+# Some Linux systems (Slackware) need crypt() from libcrypt, *not* the
+# version in OpenSSL.
 if test "x$check_for_libcrypt_later" = "x1"; then
        AC_CHECK_LIB(crypt, crypt, LIBS="$LIBS -lcrypt")
 fi
@@ -1247,7 +1340,7 @@ AC_ARG_WITH(rand-helper,
        [  --with-rand-helper      Use subprocess to gather strong randomness ],
        [
                if test "x$withval" = "xno" ; then
-                       # Force use of OpenSSL's internal RNG, even if 
+                       # Force use of OpenSSL's internal RNG, even if
                        # the previous test showed it to be unseeded.
                        if test -z "$OPENSSL_SEEDS_ITSELF" ; then
                                AC_MSG_WARN([*** Forcing use of OpenSSL's non-self-seeding PRNG])
@@ -1384,7 +1477,7 @@ test -d /sbin && PATH=$PATH:/sbin
 test -d /usr/sbin && PATH=$PATH:/usr/sbin
 PATH=$PATH:/etc:$OPATH
 
-# These programs are used by the command hashing source to gather entropy 
+# These programs are used by the command hashing source to gather entropy
 OSSH_PATH_ENTROPY_PROG(PROG_LS, ls)
 OSSH_PATH_ENTROPY_PROG(PROG_NETSTAT, netstat)
 OSSH_PATH_ENTROPY_PROG(PROG_ARP, arp)
@@ -1440,8 +1533,8 @@ fi
 # More checks for data types
 AC_CACHE_CHECK([for u_int type], ac_cv_have_u_int, [
        AC_TRY_COMPILE(
-               [ #include <sys/types.h> ], 
-               [ u_int a; a = 1;], 
+               [ #include <sys/types.h> ],
+               [ u_int a; a = 1;],
                [ ac_cv_have_u_int="yes" ],
                [ ac_cv_have_u_int="no" ]
        )
@@ -1453,8 +1546,8 @@ fi
 
 AC_CACHE_CHECK([for intXX_t types], ac_cv_have_intxx_t, [
        AC_TRY_COMPILE(
-               [ #include <sys/types.h> ], 
-               [ int8_t a; int16_t b; int32_t c; a = b = c = 1;], 
+               [ #include <sys/types.h> ],
+               [ int8_t a; int16_t b; int32_t c; a = b = c = 1;],
                [ ac_cv_have_intxx_t="yes" ],
                [ ac_cv_have_intxx_t="no" ]
        )
@@ -1465,12 +1558,12 @@ if test "x$ac_cv_have_intxx_t" = "xyes" ; then
 fi
 
 if (test -z "$have_intxx_t" && \
-           test "x$ac_cv_header_stdint_h" = "xyes")
+          test "x$ac_cv_header_stdint_h" = "xyes")
 then
     AC_MSG_CHECKING([for intXX_t types in stdint.h])
        AC_TRY_COMPILE(
-               [ #include <stdint.h> ], 
-               [ int8_t a; int16_t b; int32_t c; a = b = c = 1;], 
+               [ #include <stdint.h> ],
+               [ int8_t a; int16_t b; int32_t c; a = b = c = 1;],
                [
                        AC_DEFINE(HAVE_INTXX_T)
                        AC_MSG_RESULT(yes)
@@ -1490,8 +1583,8 @@ AC_CACHE_CHECK([for int64_t type], ac_cv_have_int64_t, [
 #ifdef HAVE_SYS_BITYPES_H
 # include <sys/bitypes.h>
 #endif
-               ], 
-               [ int64_t a; a = 1;], 
+               ],
+               [ int64_t a; a = 1;],
                [ ac_cv_have_int64_t="yes" ],
                [ ac_cv_have_int64_t="no" ]
        )
@@ -1502,8 +1595,8 @@ fi
 
 AC_CACHE_CHECK([for u_intXX_t types], ac_cv_have_u_intxx_t, [
        AC_TRY_COMPILE(
-               [ #include <sys/types.h> ], 
-               [ u_int8_t a; u_int16_t b; u_int32_t c; a = b = c = 1;], 
+               [ #include <sys/types.h> ],
+               [ u_int8_t a; u_int16_t b; u_int32_t c; a = b = c = 1;],
                [ ac_cv_have_u_intxx_t="yes" ],
                [ ac_cv_have_u_intxx_t="no" ]
        )
@@ -1516,8 +1609,8 @@ fi
 if test -z "$have_u_intxx_t" ; then
     AC_MSG_CHECKING([for u_intXX_t types in sys/socket.h])
        AC_TRY_COMPILE(
-               [ #include <sys/socket.h> ], 
-               [ u_int8_t a; u_int16_t b; u_int32_t c; a = b = c = 1;], 
+               [ #include <sys/socket.h> ],
+               [ u_int8_t a; u_int16_t b; u_int32_t c; a = b = c = 1;],
                [
                        AC_DEFINE(HAVE_U_INTXX_T)
                        AC_MSG_RESULT(yes)
@@ -1528,8 +1621,8 @@ fi
 
 AC_CACHE_CHECK([for u_int64_t types], ac_cv_have_u_int64_t, [
        AC_TRY_COMPILE(
-               [ #include <sys/types.h> ], 
-               [ u_int64_t a; a = 1;], 
+               [ #include <sys/types.h> ],
+               [ u_int64_t a; a = 1;],
                [ ac_cv_have_u_int64_t="yes" ],
                [ ac_cv_have_u_int64_t="no" ]
        )
@@ -1542,7 +1635,7 @@ fi
 if test -z "$have_u_int64_t" ; then
     AC_MSG_CHECKING([for u_int64_t type in sys/bitypes.h])
        AC_TRY_COMPILE(
-               [ #include <sys/bitypes.h> ], 
+               [ #include <sys/bitypes.h> ],
                [ u_int64_t a; a = 1],
                [
                        AC_DEFINE(HAVE_U_INT64_T)
@@ -1557,8 +1650,8 @@ if test -z "$have_u_intxx_t" ; then
                AC_TRY_COMPILE(
                        [
 #include <sys/types.h>
-                       ], 
-                       [ uint8_t a; uint16_t b; uint32_t c; a = b = c = 1; ], 
+                       ],
+                       [ uint8_t a; uint16_t b; uint32_t c; a = b = c = 1; ],
                        [ ac_cv_have_uintxx_t="yes" ],
                        [ ac_cv_have_uintxx_t="no" ]
                )
@@ -1571,8 +1664,8 @@ fi
 if test -z "$have_uintxx_t" ; then
     AC_MSG_CHECKING([for uintXX_t types in stdint.h])
        AC_TRY_COMPILE(
-               [ #include <stdint.h> ], 
-               [ uint8_t a; uint16_t b; uint32_t c; a = b = c = 1;], 
+               [ #include <stdint.h> ],
+               [ uint8_t a; uint16_t b; uint32_t c; a = b = c = 1;],
                [
                        AC_DEFINE(HAVE_UINTXX_T)
                        AC_MSG_RESULT(yes)
@@ -1582,25 +1675,25 @@ if test -z "$have_uintxx_t" ; then
 fi
 
 if (test -z "$have_u_intxx_t" || test -z "$have_intxx_t" && \
-           test "x$ac_cv_header_sys_bitypes_h" = "xyes")
+          test "x$ac_cv_header_sys_bitypes_h" = "xyes")
 then
        AC_MSG_CHECKING([for intXX_t and u_intXX_t types in sys/bitypes.h])
        AC_TRY_COMPILE(
                [
 #include <sys/bitypes.h>
-               ], 
+               ],
                [
                        int8_t a; int16_t b; int32_t c;
                        u_int8_t e; u_int16_t f; u_int32_t g;
                        a = b = c = e = f = g = 1;
-               ], 
+               ],
                [
                        AC_DEFINE(HAVE_U_INTXX_T)
                        AC_DEFINE(HAVE_INTXX_T)
                        AC_MSG_RESULT(yes)
                ],
                [AC_MSG_RESULT(no)]
-       ) 
+       )
 fi
 
 
@@ -1781,8 +1874,8 @@ fi
 
 AC_CACHE_CHECK([for struct timeval], ac_cv_have_struct_timeval, [
        AC_TRY_COMPILE(
-               [ #include <sys/time.h> ], 
-               [ struct timeval tv; tv.tv_sec = 1;], 
+               [ #include <sys/time.h> ],
+               [ struct timeval tv; tv.tv_sec = 1;],
                [ ac_cv_have_struct_timeval="yes" ],
                [ ac_cv_have_struct_timeval="no" ]
        )
@@ -1822,7 +1915,7 @@ main()
        strcpy(expected_out, "9223372036854775807");
        snprintf(buf, mazsize, "%lld", num);
        if(strcmp(buf, expected_out) != 0)
-               exit(1);
+               exit(1);
        exit(0);
 }
 #else
@@ -1980,8 +2073,8 @@ if test "x$ac_cv_have_control_in_msghdr" = "xyes" ; then
 fi
 
 AC_CACHE_CHECK([if libc defines __progname], ac_cv_libc_defines___progname, [
-       AC_TRY_LINK([], 
-               [ extern char *__progname; printf("%s", __progname); ], 
+       AC_TRY_LINK([],
+               [ extern char *__progname; printf("%s", __progname); ],
                [ ac_cv_libc_defines___progname="yes" ],
                [ ac_cv_libc_defines___progname="no" ]
        )
@@ -1993,8 +2086,8 @@ fi
 AC_CACHE_CHECK([whether $CC implements __FUNCTION__], ac_cv_cc_implements___FUNCTION__, [
        AC_TRY_LINK([
 #include <stdio.h>
-], 
-               [ printf("%s", __FUNCTION__); ], 
+],
+               [ printf("%s", __FUNCTION__); ],
                [ ac_cv_cc_implements___FUNCTION__="yes" ],
                [ ac_cv_cc_implements___FUNCTION__="no" ]
        )
@@ -2006,8 +2099,8 @@ fi
 AC_CACHE_CHECK([whether $CC implements __func__], ac_cv_cc_implements___func__, [
        AC_TRY_LINK([
 #include <stdio.h>
-], 
-               [ printf("%s", __func__); ], 
+],
+               [ printf("%s", __func__); ],
                [ ac_cv_cc_implements___func__="yes" ],
                [ ac_cv_cc_implements___func__="no" ]
        )
@@ -2032,8 +2125,8 @@ if test "x$ac_cv_have_getopt_optreset" = "xyes" ; then
 fi
 
 AC_CACHE_CHECK([if libc defines sys_errlist], ac_cv_libc_defines_sys_errlist, [
-       AC_TRY_LINK([], 
-               [ extern const char *const sys_errlist[]; printf("%s", sys_errlist[0]);], 
+       AC_TRY_LINK([],
+               [ extern const char *const sys_errlist[]; printf("%s", sys_errlist[0]);],
                [ ac_cv_libc_defines_sys_errlist="yes" ],
                [ ac_cv_libc_defines_sys_errlist="no" ]
        )
@@ -2044,8 +2137,8 @@ fi
 
 
 AC_CACHE_CHECK([if libc defines sys_nerr], ac_cv_libc_defines_sys_nerr, [
-       AC_TRY_LINK([], 
-               [ extern int sys_nerr; printf("%i", sys_nerr);], 
+       AC_TRY_LINK([],
+               [ extern int sys_nerr; printf("%i", sys_nerr);],
                [ ac_cv_libc_defines_sys_nerr="yes" ],
                [ ac_cv_libc_defines_sys_nerr="no" ]
        )
@@ -2054,7 +2147,7 @@ if test "x$ac_cv_libc_defines_sys_nerr" = "xyes" ; then
        AC_DEFINE(HAVE_SYS_NERR)
 fi
 
-SCARD_MSG="no" 
+SCARD_MSG="no"
 # Check whether user wants sectok support
 AC_ARG_WITH(sectok,
        [  --with-sectok           Enable smartcard support using libsectok],
@@ -2080,7 +2173,7 @@ AC_ARG_WITH(sectok,
                        fi
                        AC_DEFINE(SMARTCARD)
                        AC_DEFINE(USE_SECTOK)
-                       SCARD_MSG="yes, using sectok" 
+                       SCARD_MSG="yes, using sectok"
                fi
        ]
 )
@@ -2100,65 +2193,76 @@ if test x$opensc_config_prefix != x ; then
     LDFLAGS="$LDFLAGS $LIBOPENSC_LIBS"
     AC_DEFINE(SMARTCARD)
     AC_DEFINE(USE_OPENSC)
-    SCARD_MSG="yes, using OpenSC" 
+    SCARD_MSG="yes, using OpenSC"
   fi
 fi
 
-# Check whether user wants DNS support
-DNS_MSG="no" 
-AC_ARG_WITH(dns,
-       [  --with-dns              Support for fetching keys from DNS (experimental)],
+# Check libraries needed by DNS fingerprint support
+AC_SEARCH_LIBS(getrrsetbyname, resolv,
+       [AC_DEFINE(HAVE_GETRRSETBYNAME)],
        [
-               if test "x$withval" != "xno" ; then
-                       DNS_MSG="yes"
-                       AC_DEFINE(DNS)
-                       AC_SEARCH_LIBS(getrrsetbyname, resolv, 
-                               [AC_DEFINE(HAVE_GETRRSETBYNAME)],
-                               [
-                                       # Needed by our getrrsetbyname()
-                                       AC_SEARCH_LIBS(res_query, resolv)
-                                       AC_SEARCH_LIBS(dn_expand, resolv)
-                                       AC_CHECK_FUNCS(_getshort _getlong)
-                                       AC_CHECK_MEMBER(HEADER.ad,
-                                               [AC_DEFINE(HAVE_HEADER_AD)],,
-                                               [#include <arpa/nameser.h>])
-                               ])
-               fi
-       ]
-)
+               # Needed by our getrrsetbyname()
+               AC_SEARCH_LIBS(res_query, resolv)
+               AC_SEARCH_LIBS(dn_expand, resolv)
+               AC_CHECK_FUNCS(_getshort _getlong)
+               AC_CHECK_MEMBER(HEADER.ad,
+                       [AC_DEFINE(HAVE_HEADER_AD)],,
+                       [#include <arpa/nameser.h>])
+       ])
 
 # Check whether user wants Kerberos 5 support
-KRB5_MSG="no" 
+KRB5_MSG="no"
 AC_ARG_WITH(kerberos5,
-        [  --with-kerberos5=PATH   Enable Kerberos 5 support],
-        [
-                if test "x$withval" != "xno" ; then
-                        if test "x$withval" = "xyes" ; then
-                                KRB5ROOT="/usr/local"
-                        else
-                                KRB5ROOT=${withval}
-                        fi
+       [  --with-kerberos5=PATH   Enable Kerberos 5 support],
+       [ if test "x$withval" != "xno" ; then
+               if test "x$withval" = "xyes" ; then
+                       KRB5ROOT="/usr/local"
+               else
+                       KRB5ROOT=${withval}
+               fi
+
+               AC_DEFINE(KRB5)
+               KRB5_MSG="yes"
+
+               AC_MSG_CHECKING(for krb5-config)
+               if test -x  $KRB5ROOT/bin/krb5-config ; then
+                       KRB5CONF=$KRB5ROOT/bin/krb5-config
+                       AC_MSG_RESULT($KRB5CONF)
+
+                       AC_MSG_CHECKING(for gssapi support)
+                       if $KRB5CONF | grep gssapi >/dev/null ; then
+                               AC_MSG_RESULT(yes)
+                               AC_DEFINE(GSSAPI)
+                               k5confopts=gssapi
+                       else
+                               AC_MSG_RESULT(no)
+                               k5confopts=""
+                       fi
+                       K5CFLAGS="`$KRB5CONF --cflags $k5confopts`"
+                       K5LIBS="`$KRB5CONF --libs $k5confopts`"
+                       CPPFLAGS="$CPPFLAGS $K5CFLAGS"
+                       AC_MSG_CHECKING(whether we are using Heimdal)
+                       AC_TRY_COMPILE([ #include <krb5.h> ],
+                                      [ char *tmp = heimdal_version; ],
+                                      [ AC_MSG_RESULT(yes)
+                                        AC_DEFINE(HEIMDAL) ],
+                                        AC_MSG_RESULT(no)
+                       )
+               else
+                       AC_MSG_RESULT(no)
                        CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include"
-                        LDFLAGS="$LDFLAGS -L${KRB5ROOT}/lib"
-                        AC_DEFINE(KRB5)
-                       KRB5_MSG="yes"
-                        AC_MSG_CHECKING(whether we are using Heimdal)
-                        AC_TRY_COMPILE([ #include <krb5.h> ],
-                                       [ char *tmp = heimdal_version; ],
-                                       [ AC_MSG_RESULT(yes)
-                                         AC_DEFINE(HEIMDAL)
-                                         K5LIBS="-lkrb5 -ldes -lcom_err -lasn1 -lroken"
-                                       ],
-                                       [ AC_MSG_RESULT(no)
-                                         K5LIBS="-lkrb5 -lk5crypto -lcom_err"
-                                       ]
-                        )
-                        if test ! -z "$need_dash_r" ; then
-                                LDFLAGS="$LDFLAGS -R${KRB5ROOT}/lib"
-                        fi
-                        if test ! -z "$blibpath" ; then
-                                blibpath="$blibpath:${KRB5ROOT}/lib"
-                        fi
+                       LDFLAGS="$LDFLAGS -L${KRB5ROOT}/lib"
+                       AC_MSG_CHECKING(whether we are using Heimdal)
+                       AC_TRY_COMPILE([ #include <krb5.h> ],
+                                      [ char *tmp = heimdal_version; ],
+                                      [ AC_MSG_RESULT(yes)
+                                        AC_DEFINE(HEIMDAL)
+                                        K5LIBS="-lkrb5 -ldes -lcom_err -lasn1 -lroken"
+                                      ],
+                                      [ AC_MSG_RESULT(no)
+                                        K5LIBS="-lkrb5 -lk5crypto -lcom_err"
+                                      ]
+                       )
                        AC_SEARCH_LIBS(dn_expand, resolv)
 
                        AC_CHECK_LIB(gssapi,gss_init_sec_context,
@@ -2166,7 +2270,7 @@ AC_ARG_WITH(kerberos5,
                                  K5LIBS="-lgssapi $K5LIBS" ],
                                [ AC_CHECK_LIB(gssapi_krb5,gss_init_sec_context,
                                        [ AC_DEFINE(GSSAPI)
-                                         K5LIBS="-lgssapi_krb5 $K5LIBS" ],
+                                         K5LIBS="-lgssapi_krb5 $K5LIBS" ],
                                        AC_MSG_WARN([Cannot find any suitable gss-api library - build may fail]),
                                        $K5LIBS)
                                ],
@@ -2174,10 +2278,10 @@ AC_ARG_WITH(kerberos5,
                        
                        AC_CHECK_HEADER(gssapi.h, ,
                                [ unset ac_cv_header_gssapi_h
-                                 CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include/gssapi" 
+                                 CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include/gssapi"
                                  AC_CHECK_HEADERS(gssapi.h, ,
                                        AC_MSG_WARN([Cannot find any suitable gss-api header - build may fail])
-                                 ) 
+                                 )
                                ]
                        )
 
@@ -2190,46 +2294,32 @@ AC_ARG_WITH(kerberos5,
                        if test "$GSSAPI" -a "$GSSAPI" != "mechglue"; then
                                AC_MSG_ERROR([$GSSAPI GSSAPI library conflicts with Kerberos support.  Use mechglue instead.])
                        fi
-                       AC_CHECK_LIB(gssapi,gss_init_sec_context,
-                               [ AC_DEFINE(GSSAPI)
-                                 K5LIBS="-lgssapi $K5LIBS" ],
-                               [ AC_CHECK_LIB(gssapi_krb5,gss_init_sec_context,
-                                       [ AC_DEFINE(GSSAPI)
-                                         K5LIBS="-lgssapi_krb5 $K5LIBS" ],
-                                       AC_MSG_WARN([Cannot find any suitable gss-api library - build may fail]),
-                                       $K5LIBS)
-                               ],
-                               $K5LIBS)
-               
-                       AC_CHECK_HEADER(gssapi.h, ,
-                               [ unset ac_cv_header_gssapi_h
-                                 CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include/gssapi" 
-                                 AC_CHECK_HEADERS(gssapi.h, ,
-                                       AC_MSG_WARN([Cannot find any suitable gss-api header - build may fail])
-                                 ) 
-                               ]
-                       )
 
-                       AC_CHECK_LIB(gssapi, gss_krb5_copy_ccache, /bin/true,
-                               [ K5LIBS="-lgssapi_krb5 $K5LIBS"
-                                 AC_CHECK_LIB(gssapi_krb5, gss_krb5_copy_ccache, /bin/true,
-                                       AC_MSG_WARN([Cannot find gss_krb5_copy_ccache -- build may fail]),
-                                       $K5LIBS)
-                               ],
-                               $K5LIBS)
+                       if test -z "$GSSAPI"; then
+                               GSSAPI="KRB5";
+                       fi
 
                        oldCPP="$CPPFLAGS"
                        CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include/gssapi"
                        AC_CHECK_HEADER(gssapi_krb5.h, ,
                                        [ CPPFLAGS="$oldCPP" ])
 
-                       if test -z "$GSSAPI"; then
-                               GSSAPI="KRB5";
-                       fi
-
-                        KRB5=yes
                 fi
-        ]
+               if test ! -z "$need_dash_r" ; then
+                       LDFLAGS="$LDFLAGS -R${KRB5ROOT}/lib"
+               fi
+               if test ! -z "$blibpath" ; then
+                       blibpath="$blibpath:${KRB5ROOT}/lib"
+               fi
+       fi
+
+       AC_CHECK_HEADERS(gssapi.h gssapi/gssapi.h)
+       AC_CHECK_HEADERS(gssapi_krb5.h gssapi/gssapi_krb5.h)
+       AC_CHECK_HEADERS(gssapi_generic.h gssapi/gssapi_generic.h)
+
+       LIBS="$LIBS $K5LIBS"
+       AC_SEARCH_LIBS(k_hasafs, kafs, AC_DEFINE(USE_AFS))
+       ]
 )
 
 # Check whether user wants AFS_KRB5 support
@@ -2245,7 +2335,7 @@ AC_ARG_WITH(afs-krb5,
                                AC_DEFINE_UNQUOTED(AKLOG_PATH, "/usr/bin/aklog")
                        fi
 
-                       if test -z "$KRB5" ; then
+                       if test -z "$KRB5ROOT" ; then
                                AC_MSG_WARN([AFS_KRB5 requires Kerberos 5 support, build may fail])
                        fi
 
@@ -2258,7 +2348,6 @@ AC_ARG_WITH(afs-krb5,
                fi
        ]
 )
-LIBS="$LIBS $K5LIBS"
 
 AC_ARG_WITH(session-hooks,
         [  --with-session-hooks    Enable hooks for executing external commands                                       before/after a session],
@@ -2326,7 +2415,7 @@ fi
 
 if test -z "$no_dev_ptmx" ; then
        if test "x$disable_ptmx_check" != "xyes" ; then
-               AC_CHECK_FILE("/dev/ptmx", 
+               AC_CHECK_FILE("/dev/ptmx",
                        [
                                AC_DEFINE_UNQUOTED(HAVE_DEV_PTMX)
                                have_dev_ptmx=1
@@ -2334,7 +2423,7 @@ if test -z "$no_dev_ptmx" ; then
                )
        fi
 fi
-AC_CHECK_FILE("/dev/ptc", 
+AC_CHECK_FILE("/dev/ptc",
        [
                AC_DEFINE_UNQUOTED(HAVE_DEV_PTS_AND_PTC)
                have_dev_ptc=1
@@ -2375,13 +2464,13 @@ fi
 AC_SUBST(mansubdir)
 
 # Check whether to enable MD5 passwords
-MD5_MSG="no" 
+MD5_MSG="no"
 AC_ARG_WITH(md5-passwords,
        [  --with-md5-passwords    Enable use of MD5 passwords],
        [
                if test "x$withval" != "xno" ; then
                        AC_DEFINE(HAVE_MD5_PASSWORDS)
-                       MD5_MSG="yes" 
+                       MD5_MSG="yes"
                fi
        ]
 )
@@ -2421,13 +2510,13 @@ if test ! -z "$IPADDR_IN_DISPLAY" ; then
        DISPLAY_HACK_MSG="yes"
        AC_DEFINE(IPADDR_IN_DISPLAY)
 else
-       DISPLAY_HACK_MSG="no" 
+       DISPLAY_HACK_MSG="no"
        AC_ARG_WITH(ipaddr-display,
                [  --with-ipaddr-display   Use ip address instead of hostname in \$DISPLAY],
                [
                        if test "x$withval" != "xno" ; then     
                                AC_DEFINE(IPADDR_IN_DISPLAY)
-                               DISPLAY_HACK_MSG="yes" 
+                               DISPLAY_HACK_MSG="yes"
                        fi
                ]
        )
@@ -2451,7 +2540,7 @@ if test $ac_cv_func_login_getcapbool = "yes" -a \
 fi
 
 # Whether to mess with the default path
-SERVER_PATH_MSG="(default)" 
+SERVER_PATH_MSG="(default)"
 AC_ARG_WITH(default-path,
        [  --with-default-path=    Specify default \$PATH environment for server],
        [
@@ -2466,7 +2555,7 @@ Edit /etc/login.conf instead.])
 $external_path_file .])
                        fi
                        user_path="$withval"
-                       SERVER_PATH_MSG="$withval" 
+                       SERVER_PATH_MSG="$withval"
                fi
        ],
        [ if test "x$external_path_file" = "x/etc/login.conf" ; then
@@ -2550,14 +2639,14 @@ AC_ARG_WITH(superuser-path,
 
 
 AC_MSG_CHECKING([if we need to convert IPv4 in IPv6-mapped addresses])
-IPV4_IN6_HACK_MSG="no" 
+IPV4_IN6_HACK_MSG="no"
 AC_ARG_WITH(4in6,
        [  --with-4in6             Check for and convert IPv4 in IPv6 mapped addresses],
        [
                if test "x$withval" != "xno" ; then
                        AC_MSG_RESULT(yes)
                        AC_DEFINE(IPV4_IN_IPV6)
-                       IPV4_IN6_HACK_MSG="yes" 
+                       IPV4_IN6_HACK_MSG="yes"
                else
                        AC_MSG_RESULT(no)
                fi
@@ -2565,7 +2654,7 @@ AC_ARG_WITH(4in6,
                if test "x$inet6_default_4in6" = "xyes"; then
                        AC_MSG_RESULT([yes (default)])
                        AC_DEFINE(IPV4_IN_IPV6)
-                       IPV4_IN6_HACK_MSG="yes" 
+                       IPV4_IN6_HACK_MSG="yes"
                else
                        AC_MSG_RESULT([no (default)])
                fi
@@ -2590,7 +2679,7 @@ piddir=/var/run
 if test ! -d $piddir ; then    
        piddir=`eval echo ${sysconfdir}`
        case $piddir in
-               NONE/*) piddir=`echo $piddir | sed "s~NONE~$ac_default_prefix~"` ;;
+               NONE/*) piddir=`echo $piddir | sed "s~NONE~$ac_default_prefix~"` ;;
        esac
 fi
 
@@ -2662,7 +2751,7 @@ AC_ARG_ENABLE(pututline,
        [  --disable-pututline     disable use of pututline() etc. ([uw]tmp) [no]],
        [
                if test "x$enableval" = "xno" ; then
-                       AC_DEFINE(DISABLE_PUTUTLINE) 
+                       AC_DEFINE(DISABLE_PUTUTLINE)
                fi
        ]
 )
@@ -2916,7 +3005,6 @@ if test ! -z "$superuser_path" ; then
 echo "          sshd superuser user PATH: $J"
 fi
 echo "                    Manpage format: $MANTYPE"
-echo "                       DNS support: $DNS_MSG"
 echo "                       PAM support: $PAM_MSG"
 echo "                 KerberosV support: $KRB5_MSG"
 echo "                 Smartcard support: $SCARD_MSG"
@@ -2945,7 +3033,7 @@ echo ""
 if test "x$PAM_MSG" = "xyes" ; then
        echo "PAM is enabled. You may need to install a PAM control file "
        echo "for sshd, otherwise password authentication may fail. "
-       echo "Example PAM control files can be found in the contrib/ " 
+       echo "Example PAM control files can be found in the contrib/ "
        echo "subdirectory"
        echo ""
 fi
index 8d1bc3cd8593f5a52b0650c12c015449a8bcc178..4b5d71bb36c8390a3ec1bd4e9019e7130df1ea19 100755 (executable)
@@ -6,7 +6,7 @@
 # Author: Darren Tucker (dtucker at zip dot com dot au)
 # This file is placed in the public domain and comes with absolutely
 # no warranty.
-# 
+#
 # Based originally on Ben Lindstrom's buildpkg.sh for Solaris
 #
 
@@ -45,7 +45,7 @@ fi
 if [ ! -f Makefile ]
 then
        echo "Makefile not found (did you run configure?)"
-       exit 1 
+       exit 1
 fi
 
 #
@@ -96,12 +96,12 @@ then
        PRIVSEP_PATH=/var/empty
 fi
 
-# Clean package build directory 
+# Clean package build directory
 rm -rf $objdir/$PKGDIR
 FAKE_ROOT=$objdir/$PKGDIR/root
 mkdir -p $FAKE_ROOT
 
-# Start by faking root install 
+# Start by faking root install
 echo "Faking root install..."
 cd $objdir
 make install-nokeys DESTDIR=$FAKE_ROOT
@@ -136,15 +136,15 @@ echo "Building BFF for $PKGNAME $VERSION (package version $BFFVERSION)"
 #
 # Set ssh and sshd parameters as per config.local
 #
-if [ "${PERMIT_ROOT_LOGIN}" = no ] 
+if [ "${PERMIT_ROOT_LOGIN}" = no ]
 then
-        perl -p -i -e "s/#PermitRootLogin yes/PermitRootLogin no/" \
-                $FAKE_ROOT/${sysconfdir}/sshd_config
+       perl -p -i -e "s/#PermitRootLogin yes/PermitRootLogin no/" \
+               $FAKE_ROOT/${sysconfdir}/sshd_config
 fi
 if [ "${X11_FORWARDING}" = yes ]
 then
-        perl -p -i -e "s/#X11Forwarding no/X11Forwarding yes/" \
-                $FAKE_ROOT/${sysconfdir}/sshd_config
+       perl -p -i -e "s/#X11Forwarding no/X11Forwarding yes/" \
+               $FAKE_ROOT/${sysconfdir}/sshd_config
 fi
 
 
@@ -190,13 +190,13 @@ cat <<EOF >>../openssh.post_i
 echo Creating configs from defaults if necessary.
 for cfgfile in ssh_config sshd_config ssh_prng_cmds
 do
-        if [ ! -f $sysconfdir/\$cfgfile ]
-        then
-                echo "Creating \$cfgfile from default"
-                cp $sysconfdir/\$cfgfile.default $sysconfdir/\$cfgfile
-        else
-                echo "\$cfgfile already exists."
-        fi
+       if [ ! -f $sysconfdir/\$cfgfile ]
+       then
+               echo "Creating \$cfgfile from default"
+               cp $sysconfdir/\$cfgfile.default $sysconfdir/\$cfgfile
+       else
+               echo "\$cfgfile already exists."
+       fi
 done
 echo
 
@@ -244,19 +244,19 @@ echo
 # Generate keys unless they already exist
 echo Creating host keys if required.
 if [ -f "$sysconfdir/ssh_host_key" ] ; then
-        echo "$sysconfdir/ssh_host_key already exists, skipping."
+       echo "$sysconfdir/ssh_host_key already exists, skipping."
 else
-        $bindir/ssh-keygen -t rsa1 -f $sysconfdir/ssh_host_key -N ""
+       $bindir/ssh-keygen -t rsa1 -f $sysconfdir/ssh_host_key -N ""
 fi
 if [ -f $sysconfdir/ssh_host_dsa_key ] ; then
-        echo "$sysconfdir/ssh_host_dsa_key already exists, skipping."
+       echo "$sysconfdir/ssh_host_dsa_key already exists, skipping."
 else
-        $bindir/ssh-keygen -t dsa -f $sysconfdir/ssh_host_dsa_key -N ""
+       $bindir/ssh-keygen -t dsa -f $sysconfdir/ssh_host_dsa_key -N ""
 fi
 if [ -f $sysconfdir/ssh_host_rsa_key ] ; then
-        echo "$sysconfdir/ssh_host_rsa_key already exists, skipping."
-else 
-        $bindir/ssh-keygen -t rsa -f $sysconfdir/ssh_host_rsa_key -N ""
+       echo "$sysconfdir/ssh_host_rsa_key already exists, skipping."
+else
+       $bindir/ssh-keygen -t rsa -f $sysconfdir/ssh_host_rsa_key -N ""
 fi
 echo
 
@@ -369,7 +369,7 @@ echo Creating $PKGNAME-$VERSION.bff with backup...
 rm -f $PKGNAME-$VERSION.bff
 (
        echo "./lpp_name"
-       find . ! -name lpp_name -a ! -name . -print 
+       find . ! -name lpp_name -a ! -name . -print
 ) | backup  -i -q -f ../$PKGNAME-$VERSION.bff $filelist
 
 #
index 4d07e9a2a674a8dcdb55667ea8de17a42d7e7c4a..44f59a4130dd8997afe93fd8fe06be4be1d3aa62 100755 (executable)
@@ -59,5 +59,5 @@ find . ! -name . -print | perl -ne '{
        } elsif ( -d $_ ) {
                # Entry is Directory
                print "\ttype=DIRECTORY\n";
-       } 
+       }
 }'
index 271870f9221dd086788aedd3e02788b100b6df22..c01f35a5ccfe5cb96755869de7e11f97da9721d5 100644 (file)
 #      2002-08-04: Added public domain notice.
 #      2003-06-24: Incorporated readme, set library paths. First cvs version.
 #
-# "OpenSSL headers do not match your library" are usually caused by 
+# "OpenSSL headers do not match your library" are usually caused by
 # OpenSSH's configure picking up an older version of OpenSSL headers
 # or libraries.  You can use the following # procedure to help identify
 # the cause.
-# 
+#
 # The  output  of  configure  will  tell you the versions of the OpenSSL
 # headers and libraries that were picked up, for example:
-# 
+#
 # checking OpenSSL header version... 90604f (OpenSSL 0.9.6d 9 May 2002)
 # checking OpenSSL library version... 90602f (OpenSSL 0.9.6b [engine] 9 Jul 2001)
 # checking whether OpenSSL's headers match the library... no
 # configure: error: Your OpenSSL headers do not match your library
-# 
+#
 # Now run findssl.sh. This should identify the headers and libraries
 # present  and  their  versions.  You  should  be  able  to identify the
 # libraries  and headers used and adjust your CFLAGS or remove incorrect
@@ -37,7 +37,7 @@
 # Searching for OpenSSL header files.
 # 0x0090604fL /usr/include/openssl/opensslv.h
 # 0x0090604fL /usr/local/ssl/include/openssl/opensslv.h
-# 
+#
 # Searching for OpenSSL shared library files.
 # 0x0090602fL /lib/libcrypto.so.0.9.6b
 # 0x0090602fL /lib/libcrypto.so.2
 # 0x0090581fL /usr/lib/libcrypto.so.0.9.5a
 # 0x0090600fL /usr/lib/libcrypto.so.0.9.6
 # 0x0090600fL /usr/lib/libcrypto.so.1
-# 
+#
 # Searching for OpenSSL static library files.
 # 0x0090602fL /usr/lib/libcrypto.a
 # 0x0090604fL /usr/local/ssl/lib/libcrypto.a
-# 
+#
 # In  this  example, I gave configure no extra flags, so it's picking up
 # the  OpenSSL header from /usr/include/openssl (90604f) and the library
 # from /usr/lib/ (90602f).
index b6b342b8404bbf552c8f8d456e85a011561323e5..4d51032d1d369afe1b17c9118b11b7911e5440f5 100644 (file)
  */
 
 /*
- * This is a simple GNOME SSH passphrase grabber. To use it, set the 
- * environment variable SSH_ASKPASS to point to the location of 
- * gnome-ssh-askpass before calling "ssh-add < /dev/null". 
+ * This is a simple GNOME SSH passphrase grabber. To use it, set the
+ * environment variable SSH_ASKPASS to point to the location of
+ * gnome-ssh-askpass before calling "ssh-add < /dev/null".
  *
  * There is only two run-time options: if you set the environment variable
  * "GNOME_SSH_ASKPASS_GRAB_SERVER=true" then gnome-ssh-askpass will grab
- * the X server. If you set "GNOME_SSH_ASKPASS_GRAB_POINTER=true", then the 
- * pointer will be grabbed too. These may have some benefit to security if 
+ * the X server. If you set "GNOME_SSH_ASKPASS_GRAB_POINTER=true", then the
+ * pointer will be grabbed too. These may have some benefit to security if
  * you don't trust your X server. We grab the keyboard always.
  */
 
@@ -87,7 +87,7 @@ passphrase_dialog(char *message)
                }
 
        entry = gtk_entry_new();
-       gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dialog)->vbox), entry, FALSE, 
+       gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dialog)->vbox), entry, FALSE,
            FALSE, 0);
        gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
        gtk_widget_grab_focus(entry);
@@ -105,7 +105,7 @@ passphrase_dialog(char *message)
        /* Grab focus */
        if (grab_server)
                XGrabServer(GDK_DISPLAY());
-       if (grab_pointer && gdk_pointer_grab(dialog->window, TRUE, 0, 
+       if (grab_pointer && gdk_pointer_grab(dialog->window, TRUE, 0,
            NULL, NULL, GDK_CURRENT_TIME))
                goto nograb;
        if (gdk_keyboard_grab(dialog->window, FALSE, GDK_CURRENT_TIME))
index 9e8eaf920144f5bce4854f46f9e0568e29008dd1..0ce8daec9b144f653464216ccf6fadec26820ccc 100644 (file)
 /* GTK2 support by Nalin Dahyabhai <nalin@redhat.com> */
 
 /*
- * This is a simple GNOME SSH passphrase grabber. To use it, set the 
- * environment variable SSH_ASKPASS to point to the location of 
- * gnome-ssh-askpass before calling "ssh-add < /dev/null". 
+ * This is a simple GNOME SSH passphrase grabber. To use it, set the
+ * environment variable SSH_ASKPASS to point to the location of
+ * gnome-ssh-askpass before calling "ssh-add < /dev/null".
  *
  * There is only two run-time options: if you set the environment variable
  * "GNOME_SSH_ASKPASS_GRAB_SERVER=true" then gnome-ssh-askpass will grab
- * the X server. If you set "GNOME_SSH_ASKPASS_GRAB_POINTER=true", then the 
- * pointer will be grabbed too. These may have some benefit to security if 
+ * the X server. If you set "GNOME_SSH_ASKPASS_GRAB_POINTER=true", then the
+ * pointer will be grabbed too. These may have some benefit to security if
  * you don't trust your X server. We grab the keyboard always.
  */
 
@@ -103,7 +103,7 @@ passphrase_dialog(char *message)
                                        message);
 
        entry = gtk_entry_new();
-       gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), entry, FALSE, 
+       gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), entry, FALSE,
            FALSE, 0);
        gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
        gtk_widget_grab_focus(entry);
@@ -124,7 +124,7 @@ passphrase_dialog(char *message)
        if (grab_pointer) {
                for(;;) {
                        status = gdk_pointer_grab(
-                          (GTK_WIDGET(dialog))->window, TRUE, 0, NULL, 
+                          (GTK_WIDGET(dialog))->window, TRUE, 0, NULL,
                           NULL, GDK_CURRENT_TIME);
                        if (status == GDK_GRAB_SUCCESS)
                                break;
index 2a01853268a5a2e8314b9814f0afcb4645f4cf02..3d6b688f8253b6246f4bd48d2e29e13c2333270c 100644 (file)
@@ -84,7 +84,7 @@ enum
 # define S_ISDIR(mode) (((mode) & (_S_IFMT)) == (_S_IFDIR))
 #endif /* S_ISDIR */
 
-#ifndef S_ISREG 
+#ifndef S_ISREG
 # define S_ISREG(mode) (((mode) & (_S_IFMT)) == (_S_IFREG))
 #endif /* S_ISREG */
 
@@ -129,6 +129,10 @@ including rpc/rpc.h breaks Solaris 6
 #define INADDR_LOOPBACK ((u_long)0x7f000001)
 #endif
 
+#ifndef __unused
+#define __unused
+#endif
+
 /* Types */
 
 /* If sys/types.h does not supply intXX_t, supply them ourselves */
@@ -240,6 +244,7 @@ typedef unsigned char u_char;
 #ifndef HAVE_SIZE_T
 typedef unsigned int size_t;
 # define HAVE_SIZE_T
+# define SIZE_T_MAX UINT_MAX
 #endif /* HAVE_SIZE_T */
 
 #ifndef HAVE_SSIZE_T
@@ -529,6 +534,14 @@ struct winsize {
 #  define krb5_get_err_text(context,code) error_message(code)
 #endif
 
+/* Maximum number of file descriptors available */
+#ifdef HAVE_SYSCONF
+# define SSH_SYSFDMAX sysconf(_SC_OPEN_MAX)
+#else
+# define SSH_SYSFDMAX 10000
+#endif
+
+
 /*
  * Define this to use pipes instead of socketpairs for communicating with the
  * client program.  Socketpairs do not seem to work on all systems.
@@ -572,6 +585,9 @@ struct winsize {
 #  endif
 #endif
 
+#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
+# define USE_SHADOW
+#endif
 
 /* The login() library function in libutil is first choice */
 #if defined(HAVE_LOGIN) && !defined(DISABLE_LOGIN)
index 90ab5601a5429acf0fadb841780825414b990cd0..ad634f1f75a758a6326c7c5661104bc4ccd1bf85 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dns.c,v 1.6 2003/06/11 10:18:47 jakob Exp $   */
+/*     $OpenBSD: dns.c,v 1.9 2003/11/21 11:57:03 djm Exp $     */
 
 /*
  * Copyright (c) 2003 Wesley Griffin. All rights reserved.
@@ -28,7 +28,6 @@
 
 #include "includes.h"
 
-#ifdef DNS
 #include <openssl/bn.h>
 #ifdef LWRES
 #include <lwres/netdb.h>
@@ -44,7 +43,7 @@
 #include "uuencode.h"
 
 extern char *__progname;
-RCSID("$OpenBSD: dns.c,v 1.6 2003/06/11 10:18:47 jakob Exp $");
+RCSID("$OpenBSD: dns.c,v 1.9 2003/11/21 11:57:03 djm Exp $");
 
 #ifndef LWRES
 static const char *errset_text[] = {
@@ -84,7 +83,7 @@ dns_result_totext(unsigned int error)
  */
 static int
 dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type,
-    u_char **digest, u_int *digest_len, Key *key)
+    u_char **digest, u_int *digest_len, const Key *key)
 {
        int success = 0;
 
@@ -146,16 +145,15 @@ dns_read_rdata(u_int8_t *algorithm, u_int8_t *digest_type,
 
 /*
  * Verify the given hostname, address and host key using DNS.
- * Returns 0 if key verifies or -1 if key does NOT verify
+ * Returns 0 if lookup succeeds, -1 otherwise
  */
 int
 verify_host_key_dns(const char *hostname, struct sockaddr *address,
-    Key *hostkey)
+    const Key *hostkey, int *flags)
 {
        int counter;
        int result;
        struct rrsetinfo *fingerprints = NULL;
-       int failures = 0;
 
        u_int8_t hostkey_algorithm;
        u_int8_t hostkey_digest_type;
@@ -167,6 +165,7 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address,
        u_char *dnskey_digest;
        u_int dnskey_digest_len;
 
+       *flags = 0;
 
        debug3("verify_hostkey_dns");
        if (hostkey == NULL)
@@ -176,28 +175,29 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address,
            DNS_RDATATYPE_SSHFP, 0, &fingerprints);
        if (result) {
                verbose("DNS lookup error: %s", dns_result_totext(result));
-               return DNS_VERIFY_ERROR;
+               return -1;
        }
 
-#ifdef DNSSEC
-       /* Only accept validated answers */
-       if (!fingerprints->rri_flags & RRSET_VALIDATED) {
-               error("Ignored unvalidated fingerprint from DNS.");
-               freerrset(fingerprints);
-               return DNS_VERIFY_ERROR;
+       if (fingerprints->rri_flags & RRSET_VALIDATED) {
+               *flags |= DNS_VERIFY_SECURE;
+               debug("found %d secure fingerprints in DNS",
+                   fingerprints->rri_nrdatas);
+       } else {
+               debug("found %d insecure fingerprints in DNS",
+                   fingerprints->rri_nrdatas);
        }
-#endif
-
-       debug("found %d fingerprints in DNS", fingerprints->rri_nrdatas);
 
        /* Initialize host key parameters */
        if (!dns_read_key(&hostkey_algorithm, &hostkey_digest_type,
            &hostkey_digest, &hostkey_digest_len, hostkey)) {
                error("Error calculating host key fingerprint.");
                freerrset(fingerprints);
-               return DNS_VERIFY_ERROR;
+               return -1;
        }
 
+       if (fingerprints->rri_nrdatas)
+               *flags |= DNS_VERIFY_FOUND;
+
        for (counter = 0 ; counter < fingerprints->rri_nrdatas ; counter++)  {
                /*
                 * Extract the key from the answer. Ignore any badly
@@ -219,35 +219,22 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address,
                            memcmp(hostkey_digest, dnskey_digest,
                            hostkey_digest_len) == 0) {
 
-                               /* Matching algoritm and digest. */
-                               freerrset(fingerprints);
-                               debug("matching host key fingerprint found in DNS");
-                               return DNS_VERIFY_OK;
-                       } else {
-                               /* Correct algorithm but bad digest */
-                               debug("verify_hostkey_dns: failed");
-                               failures++;
+                               *flags |= DNS_VERIFY_MATCH;
                        }
                }
        }
 
        freerrset(fingerprints);
 
-       if (failures) {
-               error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
-               error("@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @");
-               error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
-               error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!");
-               error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!");
-               error("It is also possible that the %s host key has just been changed.",
-                   key_type(hostkey));
-               error("Please contact your system administrator.");
-               return DNS_VERIFY_FAILED;
-       }
-
-       debug("fingerprints found in DNS, but none of them matched");
+       if (*flags & DNS_VERIFY_FOUND)
+               if (*flags & DNS_VERIFY_MATCH)
+                       debug("matching host key fingerprint found in DNS");
+               else
+                       debug("mismatching host key fingerprint found in DNS");
+       else
+               debug("no host key fingerprint found in DNS");
 
-       return DNS_VERIFY_ERROR;
+       return 0;
 }
 
 
@@ -255,7 +242,7 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address,
  * Export the fingerprint of a key as a DNS resource record
  */
 int
-export_dns_rr(const char *hostname, Key *key, FILE *f, int generic)
+export_dns_rr(const char *hostname, const Key *key, FILE *f, int generic)
 {
        u_int8_t rdata_pubkey_algorithm = 0;
        u_int8_t rdata_digest_type = SSHFP_HASH_SHA1;
@@ -286,5 +273,3 @@ export_dns_rr(const char *hostname, Key *key, FILE *f, int generic)
 
        return success;
 }
-
-#endif /* DNS */
index ba0ea9fb4786760d49bcd2a1059a7761e3d33b5d..c5da22ef61a4de067f53a3a5851fe68b7dcf5947 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dns.h,v 1.3 2003/05/14 22:56:51 jakob Exp $   */
+/*     $OpenBSD: dns.h,v 1.5 2003/11/12 16:39:58 jakob Exp $   */
 
 /*
  * Copyright (c) 2003 Wesley Griffin. All rights reserved.
@@ -28,7 +28,6 @@
 
 #include "includes.h"
 
-#ifdef DNS
 #ifndef DNS_H
 #define DNS_H
 
@@ -46,12 +45,12 @@ enum sshfp_hashes {
 #define DNS_RDATACLASS_IN      1
 #define DNS_RDATATYPE_SSHFP    44
 
-#define DNS_VERIFY_FAILED      -1
-#define DNS_VERIFY_OK          0
-#define DNS_VERIFY_ERROR       1
+#define DNS_VERIFY_FOUND       0x00000001
+#define DNS_VERIFY_MATCH       0x00000002
+#define DNS_VERIFY_SECURE      0x00000004
 
-int    verify_host_key_dns(const char *, struct sockaddr *, Key *);
-int    export_dns_rr(const char *, Key *, FILE *, int);
+
+int    verify_host_key_dns(const char *, struct sockaddr *, const Key *, int *);
+int    export_dns_rr(const char *, const Key *, FILE *, int);
 
 #endif /* DNS_H */
-#endif /* DNS */
index 9e7d1600073f341fd1dcf903f56dc6f81b00baeb..ae1aaac6edd0c6b491f6f8bd708fc99c776c08b1 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: fatal.c,v 1.1 2002/02/22 12:20:34 markus Exp $");
+RCSID("$OpenBSD: fatal.c,v 1.2 2003/09/23 20:17:11 markus Exp $");
 
 #include "log.h"
 
@@ -36,5 +36,5 @@ fatal(const char *fmt,...)
        va_start(args, fmt);
        do_log(SYSLOG_LEVEL_FATAL, fmt, args);
        va_end(args);
-       fatal_cleanup();
+       cleanup_exit(255);
 }
index a6b721a4e68af8559bee085c989f9628230b9692..7c68741d43a6037fcf5f039786b936e2e6921ef6 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: gss-genr.c,v 1.1 2003/08/22 10:56:09 markus Exp $     */
+/*     $OpenBSD: gss-genr.c,v 1.3 2003/11/21 11:57:03 djm Exp $        */
 
 /*
  * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
 #include "compat.h"
 #include "monitor_wrap.h"
 #include "canohost.h"
-
-#include <netdb.h>
+#include "ssh2.h"
 
 #include "ssh-gss.h"
 
+extern u_char *session_id2;
+extern u_int session_id2_len;
+
 typedef struct {
        char *encoded;
        gss_OID oid;
@@ -424,6 +426,28 @@ ssh_gssapi_acquire_cred(Gssctxt *ctx)
        return (ctx->major);
 }
 
+OM_uint32
+ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash)
+{
+       if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context,
+           GSS_C_QOP_DEFAULT, buffer, hash)))
+               ssh_gssapi_error(ctx);
+
+       return (ctx->major);
+}
+
+void
+ssh_gssapi_buildmic(Buffer *b, const char *user, const char *service,
+    const char *context)
+{
+       buffer_init(b);
+       buffer_put_string(b, session_id2, session_id2_len);
+       buffer_put_char(b, SSH2_MSG_USERAUTH_REQUEST);
+       buffer_put_cstring(b, user);
+       buffer_put_cstring(b, service);
+       buffer_put_cstring(b, context);
+}
+
 OM_uint32
 ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) {
        if (*ctx)
@@ -433,17 +457,6 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) {
        return (ssh_gssapi_acquire_cred(*ctx));
 }
 
-OM_uint32
-ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *buffer, gss_buffer_desc *hash) {
-       
-       if ((ctx->major=gss_get_mic(&ctx->minor,ctx->context,
-                                   GSS_C_QOP_DEFAULT, buffer, hash))) {
-               ssh_gssapi_error(ctx);
-       }
-       
-       return(ctx->major);
-}
-
 int
 ssh_gssapi_check_mechanism(gss_OID oid, char *host) {
        Gssctxt * ctx = NULL;
index c1ae5d6063ea9eb7a075df782226a0c4ede58add..dbe2b0bf0ba24810658c7ac7a3a1ab32fb4a3ee0 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: gss-serv-krb5.c,v 1.1 2003/08/22 10:56:09 markus Exp $        */
+/*     $OpenBSD: gss-serv-krb5.c,v 1.2 2003/11/21 11:57:03 djm Exp $   */
 
 /*
  * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
 extern ServerOptions options;
 
 #ifdef HEIMDAL
-#include <krb5.h>
+# include <krb5.h>
 #else
-#include <gssapi_krb5.h>
+# ifdef HAVE_GSSAPI_KRB5
+#  include <gssapi_krb5.h>
+# elif HAVE_GSSAPI_GSSAPI_KRB5
+#  include <gssapi/gssapi_krb5.h>
+# endif
 #endif
 
 static krb5_context krb_context = NULL;
 
 /* Initialise the krb5 library, for the stuff that GSSAPI won't do */
 
-static int 
+static int
 ssh_gssapi_krb5_init()
 {
        krb5_error_code problem;
@@ -138,7 +142,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
        krb5_principal princ;
        OM_uint32 maj_status, min_status;
        gss_cred_id_t krb5_cred_handle;
-
+       int len;
 
        if (client->creds == NULL) {
                debug("No credentials stored");
@@ -158,10 +162,10 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
        {
                int tmpfd;
                char ccname[40];
-    
-               snprintf(ccname, sizeof(ccname), 
+
+               snprintf(ccname, sizeof(ccname),
                    "FILE:/tmp/krb5cc_%d_XXXXXX", geteuid());
-    
+
                if ((tmpfd = mkstemp(ccname + strlen("FILE:"))) == -1) {
                        logit("mkstemp(): %.100s", strerror(errno));
                        problem = errno;
@@ -182,7 +186,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
        }
 #endif /* #ifdef HEIMDAL */
 
-       if ((problem = krb5_parse_name(krb_context, 
+       if ((problem = krb5_parse_name(krb_context,
            client->exportedname.value, &princ))) {
                logit("krb5_parse_name(): %.100s",
                    krb5_get_err_text(krb_context, problem));
@@ -217,11 +221,13 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
 
        client->store.filename = xstrdup(krb5_cc_get_name(krb_context, ccache));
        client->store.envvar = "KRB5CCNAME";
-       client->store.envval = xstrdup(client->store.filename);
+       len = strlen(client->store.filename) + 6;
+       client->store.envval = xmalloc(len);
+       snprintf(client->store.envval, len, "FILE:%s", client->store.filename);
 
 #ifdef USE_PAM
        if (options.use_pam)
-               do_pam_putenv(client->store.envvar,client->store.envval);
+               do_pam_putenv(client->store.envvar, client->store.envval);
 #endif
 
        krb5_cc_close(krb_context, ccache);
index 40148b0760cde9556a66fe8c4e37f14e9edfa071..c8aebeb51888898e20e33ca9a2e798fa10e42e89 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: gss-serv.c,v 1.3 2003/08/31 13:31:57 markus Exp $     */
+/*     $OpenBSD: gss-serv.c,v 1.5 2003/11/17 11:06:07 markus Exp $     */
 
 /*
  * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
@@ -264,9 +264,9 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client)
        return (ctx->major);
 }
 
-/* As user - called through fatal cleanup hook */
+/* As user - called on fatal/exit */
 void
-ssh_gssapi_cleanup_creds(void *ignored)
+ssh_gssapi_cleanup_creds(void)
 {
        if (gssapi_client.store.filename != NULL) {
                /* Unlink probably isn't sufficient */
@@ -281,8 +281,6 @@ ssh_gssapi_storecreds(void)
 {
        if (gssapi_client.mech && gssapi_client.mech->storecreds) {
                (*gssapi_client.mech->storecreds)(&gssapi_client);
-               if (options.gss_cleanup_creds)
-                       fatal_add_cleanup(ssh_gssapi_cleanup_creds, NULL);
        } else
                debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism");
 }
@@ -444,4 +442,15 @@ ssh_gssapi_localname(char **user)
        }
        return(0);
 }
+
+/* Priviledged */
+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 033cd91fae6df2708a54d312e9e8da52131a5583..ca943c7e657b30b4bb3648e887bf63a28fd762f2 100644 (file)
@@ -134,6 +134,12 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg }
 #ifdef HAVE_SYS_STRTIO_H
 #include <sys/strtio.h>        /* for TIOCCBRK on HP-UX */
 #endif
+#if defined(HAVE_SYS_PTMS_H) && defined(HAVE_DEV_PTMX)
+# if defined(HAVE_SYS_STREAM_H)
+#  include <sys/stream.h>      /* reqd for queue_t on Solaris 2.5.1 */
+# endif
+#include <sys/ptms.h>  /* for grantpt() and friends */
+#endif
 
 #include <netinet/in_systm.h> /* For typedefs */
 #include <netinet/in.h> /* For IPv6 macros */
@@ -147,7 +153,11 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg }
 # include <rpc/types.h> /* For INADDR_LOOPBACK */
 #endif
 #ifdef USE_PAM
+#if defined(HAVE_SECURITY_PAM_APPL_H)
 # include <security/pam_appl.h>
+#elif defined (HAVE_PAM_PAM_APPL_H)
+# include <pam/pam_appl.h>
+#endif
 #endif
 #ifdef HAVE_READPASSPHRASE_H
 # include <readpassphrase.h>
@@ -165,6 +175,11 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg }
 # include <libutil.h> /* Openpty on FreeBSD at least */
 #endif
 
+#if defined(KRB5) && defined(USE_AFS)
+# include <krb5.h>
+# include <kafs.h>
+#endif
+
 #include <openssl/opensslv.h> /* For OPENSSL_VERSION_NUMBER */
 
 #include "defines.h"
index 046b87a6e9cf2e2cc8a14bc2fc1622425e4d6f09..183044cf6419dc4a851fc4cb7467c20685f79c20 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: kex.c,v 1.55 2003/04/01 10:31:26 markus Exp $");
+RCSID("$OpenBSD: kex.c,v 1.56 2003/11/21 11:57:03 djm Exp $");
 
 #include <openssl/crypto.h>
 
@@ -318,7 +318,7 @@ choose_hostkeyalg(Kex *k, char *client, char *server)
        xfree(hostkeyalg);
 }
 
-static int 
+static int
 proposals_match(char *my[PROPOSAL_MAX], char *peer[PROPOSAL_MAX])
 {
        static int check[] = {
@@ -400,7 +400,7 @@ kex_choose_conf(Kex *kex)
        kex->we_need = need;
 
        /* ignore the next message if the proposals do not match */
-       if (first_kex_follows && !proposals_match(my, peer) && 
+       if (first_kex_follows && !proposals_match(my, peer) &&
           !(datafellows & SSH_BUG_FIRSTKEX)) {
                type = packet_read();
                debug2("skipping next packet (type %u)", type);
index f14ac44ca04321eb4eb85efdcdb9c11833e92392..0193183b954aa0307632e78b10f87b753748467b 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: kexgexc.c,v 1.1 2003/02/16 17:09:57 markus Exp $");
+RCSID("$OpenBSD: kexgexc.c,v 1.2 2003/12/08 11:00:47 markus Exp $");
 
 #include "xmalloc.h"
 #include "key.h"
@@ -49,16 +49,14 @@ kexgex_client(Kex *kex)
        nbits = dh_estimate(kex->we_need * 8);
 
        if (datafellows & SSH_OLD_DHGEX) {
-               debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD sent");
-
                /* Old GEX request */
                packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST_OLD);
                packet_put_int(nbits);
                min = DH_GRP_MIN;
                max = DH_GRP_MAX;
-       } else {
-               debug("SSH2_MSG_KEX_DH_GEX_REQUEST sent");
 
+               debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD(%u) sent", nbits);
+       } else {
                /* New GEX request */
                min = DH_GRP_MIN;
                max = DH_GRP_MAX;
@@ -66,6 +64,9 @@ kexgex_client(Kex *kex)
                packet_put_int(min);
                packet_put_int(nbits);
                packet_put_int(max);
+
+               debug("SSH2_MSG_KEX_DH_GEX_REQUEST(%u<%u<%u) sent",
+                   min, nbits, max);
        }
 #ifdef DEBUG_KEXDH
        fprintf(stderr, "\nmin = %d, nbits = %d, max = %d\n",
index ad75542c25523c688336cc016d1d1bc63b0b4ea5..f5fe5822d36864a2948e6d7f2eeaf92dca8a4298 100644 (file)
@@ -32,7 +32,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include "includes.h"
-RCSID("$OpenBSD: key.c,v 1.54 2003/07/09 13:58:19 avsm Exp $");
+RCSID("$OpenBSD: key.c,v 1.55 2003/11/10 16:23:41 jakob Exp $");
 
 #include <openssl/evp.h>
 
@@ -143,8 +143,9 @@ key_free(Key *k)
        }
        xfree(k);
 }
+
 int
-key_equal(Key *a, Key *b)
+key_equal(const Key *a, const Key *b)
 {
        if (a == NULL || b == NULL || a->type != b->type)
                return 0;
@@ -170,7 +171,8 @@ key_equal(Key *a, Key *b)
 }
 
 u_char*
-key_fingerprint_raw(Key *k, enum fp_type dgst_type, u_int *dgst_raw_length)
+key_fingerprint_raw(const Key *k, enum fp_type dgst_type,
+    u_int *dgst_raw_length)
 {
        const EVP_MD *md = NULL;
        EVP_MD_CTX ctx;
@@ -292,7 +294,7 @@ key_fingerprint_bubblebabble(u_char *dgst_raw, u_int dgst_raw_len)
 }
 
 char *
-key_fingerprint(Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep)
+key_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep)
 {
        char *retval = NULL;
        u_char *dgst_raw;
@@ -490,7 +492,7 @@ key_read(Key *ret, char **cpp)
 }
 
 int
-key_write(Key *key, FILE *f)
+key_write(const Key *key, FILE *f)
 {
        int n, success = 0;
        u_int len, bits = 0;
@@ -522,8 +524,8 @@ key_write(Key *key, FILE *f)
        return success;
 }
 
-char *
-key_type(Key *k)
+const char *
+key_type(const Key *k)
 {
        switch (k->type) {
        case KEY_RSA1:
@@ -539,8 +541,8 @@ key_type(Key *k)
        return "unknown";
 }
 
-char *
-key_ssh_name(Key *k)
+const char *
+key_ssh_name(const Key *k)
 {
        switch (k->type) {
        case KEY_RSA:
@@ -554,7 +556,7 @@ key_ssh_name(Key *k)
 }
 
 u_int
-key_size(Key *k)
+key_size(const Key *k)
 {
        switch (k->type) {
        case KEY_RSA1:
@@ -611,7 +613,7 @@ key_generate(int type, u_int bits)
 }
 
 Key *
-key_from_private(Key *k)
+key_from_private(const Key *k)
 {
        Key *n = NULL;
        switch (k->type) {
@@ -678,7 +680,7 @@ key_names_valid2(const char *names)
 }
 
 Key *
-key_from_blob(u_char *blob, u_int blen)
+key_from_blob(const u_char *blob, u_int blen)
 {
        Buffer b;
        char *ktype;
@@ -728,7 +730,7 @@ key_from_blob(u_char *blob, u_int blen)
 }
 
 int
-key_to_blob(Key *key, u_char **blobp, u_int *lenp)
+key_to_blob(const Key *key, u_char **blobp, u_int *lenp)
 {
        Buffer b;
        int len;
@@ -770,9 +772,9 @@ key_to_blob(Key *key, u_char **blobp, u_int *lenp)
 
 int
 key_sign(
-    Key *key,
+    const Key *key,
     u_char **sigp, u_int *lenp,
-    u_char *data, u_int datalen)
+    const u_char *data, u_int datalen)
 {
        switch (key->type) {
        case KEY_DSA:
@@ -794,9 +796,9 @@ key_sign(
  */
 int
 key_verify(
-    Key *key,
-    u_char *signature, u_int signaturelen,
-    u_char *data, u_int datalen)
+    const Key *key,
+    const u_char *signature, u_int signaturelen,
+    const u_char *data, u_int datalen)
 {
        if (signaturelen == 0)
                return -1;
@@ -817,7 +819,7 @@ key_verify(
 
 /* Converts a private to a public key */
 Key *
-key_demote(Key *k)
+key_demote(const Key *k)
 {
        Key *pk;
 
index 7ff4270e8c2b0e1e23e2be303b4defabd92b799b..6358e955fc56829d7daace6c399475cc242ed5ff 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: key.h,v 1.22 2003/06/24 08:23:46 markus Exp $ */
+/*     $OpenBSD: key.h,v 1.23 2003/11/10 16:23:41 jakob Exp $  */
 
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
@@ -56,33 +56,33 @@ struct Key {
        DSA     *dsa;
 };
 
-Key    *key_new(int);
-Key    *key_new_private(int);
-void    key_free(Key *);
-Key    *key_demote(Key *);
-int     key_equal(Key *, Key *);
-char   *key_fingerprint(Key *, enum fp_type, enum fp_rep);
-u_char *key_fingerprint_raw(Key *, enum fp_type, u_int *);
-char   *key_type(Key *);
-int     key_write(Key *, FILE *);
-int     key_read(Key *, char **);
-u_int   key_size(Key *);
+Key            *key_new(int);
+Key            *key_new_private(int);
+void            key_free(Key *);
+Key            *key_demote(const Key *);
+int             key_equal(const Key *, const Key *);
+char           *key_fingerprint(const Key *, enum fp_type, enum fp_rep);
+u_char         *key_fingerprint_raw(const Key *, enum fp_type, u_int *);
+const char     *key_type(const Key *);
+int             key_write(const Key *, FILE *);
+int             key_read(Key *, char **);
+u_int           key_size(const Key *);
 
 Key    *key_generate(int, u_int);
-Key    *key_from_private(Key *);
+Key    *key_from_private(const Key *);
 int     key_type_from_name(char *);
 
-Key    *key_from_blob(u_char *, u_int);
-int     key_to_blob(Key *, u_char **, u_int *);
-char   *key_ssh_name(Key *);
-int     key_names_valid2(const char *);
+Key            *key_from_blob(const u_char *, u_int);
+int             key_to_blob(const Key *, u_char **, u_int *);
+const char     *key_ssh_name(const Key *);
+int             key_names_valid2(const char *);
 
-int     key_sign(Key *, u_char **, u_int *, u_char *, u_int);
-int     key_verify(Key *, u_char *, u_int, u_char *, u_int);
+int     key_sign(const Key *, u_char **, u_int *, const u_char *, u_int);
+int     key_verify(const Key *, const u_char *, u_int, const u_char *, u_int);
 
-int     ssh_dss_sign(Key *, u_char **, u_int *, u_char *, u_int);
-int     ssh_dss_verify(Key *, u_char *, u_int, u_char *, u_int);
-int     ssh_rsa_sign(Key *, u_char **, u_int *, u_char *, u_int);
-int     ssh_rsa_verify(Key *, u_char *, u_int, u_char *, u_int);
+int     ssh_dss_sign(const Key *, u_char **, u_int *, const u_char *, u_int);
+int     ssh_dss_verify(const Key *, const u_char *, u_int, const u_char *, u_int);
+int     ssh_rsa_sign(const Key *, u_char **, u_int *, const u_char *, u_int);
+int     ssh_rsa_verify(const Key *, const u_char *, u_int, const u_char *, u_int);
 
 #endif
index 9bce2555baa9f55c50578b2943b3844941733dce..0c4d5123a63bc1086a07826ece393cacabb73de2 100644 (file)
@@ -34,7 +34,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: log.c,v 1.28 2003/05/24 09:02:22 djm Exp $");
+RCSID("$OpenBSD: log.c,v 1.29 2003/09/23 20:17:11 markus Exp $");
 
 #include "log.h"
 #include "xmalloc.h"
@@ -183,83 +183,6 @@ debug3(const char *fmt,...)
        va_end(args);
 }
 
-/* Fatal cleanup */
-
-struct fatal_cleanup {
-       struct fatal_cleanup *next;
-       void (*proc) (void *);
-       void *context;
-};
-
-static struct fatal_cleanup *fatal_cleanups = NULL;
-
-/* Registers a cleanup function to be called by fatal() before exiting. */
-
-void
-fatal_add_cleanup(void (*proc) (void *), void *context)
-{
-       struct fatal_cleanup *cu;
-
-       cu = xmalloc(sizeof(*cu));
-       cu->proc = proc;
-       cu->context = context;
-       cu->next = fatal_cleanups;
-       fatal_cleanups = cu;
-}
-
-/* Removes a cleanup frunction to be called at fatal(). */
-
-void
-fatal_remove_cleanup(void (*proc) (void *context), void *context)
-{
-       struct fatal_cleanup **cup, *cu;
-
-       for (cup = &fatal_cleanups; *cup; cup = &cu->next) {
-               cu = *cup;
-               if (cu->proc == proc && cu->context == context) {
-                       *cup = cu->next;
-                       xfree(cu);
-                       return;
-               }
-       }
-       fatal("fatal_remove_cleanup: no such cleanup function: 0x%lx 0x%lx",
-           (u_long) proc, (u_long) context);
-}
-
-/* Remove all cleanups, to be called after fork() */
-void
-fatal_remove_all_cleanups(void)
-{
-       struct fatal_cleanup *cu, *next_cu;
-
-       for (cu = fatal_cleanups; cu; cu = next_cu) {
-               next_cu = cu->next;
-               xfree(cu);
-       }
-       fatal_cleanups = NULL;
-}
-
-/* Cleanup and exit */
-void
-fatal_cleanup(void)
-{
-       struct fatal_cleanup *cu, *next_cu;
-       static int called = 0;
-
-       if (called)
-               exit(255);
-       called = 1;
-       /* Call cleanup functions. */
-       for (cu = fatal_cleanups; cu; cu = next_cu) {
-               next_cu = cu->next;
-               debug("Calling cleanup 0x%lx(0x%lx)",
-                   (u_long) cu->proc, (u_long) cu->context);
-               (*cu->proc) (cu->context);
-       }
-       exit(255);
-}
-
-
 /*
  * Initialize the log.
  */
@@ -342,7 +265,7 @@ log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr)
 void
 do_log(LogLevel level, const char *fmt, va_list args)
 {
-#ifdef OPENLOG_R
+#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT)
        struct syslog_data sdata = SYSLOG_DATA_INIT;
 #endif
        char msgbuf[MSGBUFSIZ];
@@ -398,7 +321,7 @@ do_log(LogLevel level, const char *fmt, va_list args)
                snprintf(msgbuf, sizeof msgbuf, "%s\r\n", fmtbuf);
                write(STDERR_FILENO, msgbuf, strlen(msgbuf));
        } else {
-#ifdef OPENLOG_R
+#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT)
                openlog_r(argv0 ? argv0 : __progname, LOG_PID, log_facility, &sdata);
                syslog_r(pri, &sdata, "%.500s", fmtbuf);
                closelog_r(&sdata);
index 856e2d7c5aea8bf1e6ad123a18c5e8463a4587dc..9135af07e0ee557b50fb039e5dff64cb3ea6c916 100644 (file)
@@ -76,19 +76,19 @@ function add(str) {
       skip=1
       ext=1
       if(length(line)&&!(match(line," $")||prenl))
-        add(OFS)
+       add(OFS)
     } else if(match(words[w],"^Xc$")) {
       skip=1
       ext=0
       if(!extopt)
-        prenl++
+       prenl++
       w=nwords
     } else if(match(words[w],"^Bd$")) {
       skip=1
       if(match(words[w+1],"-literal")) {
-        literal=1
-        prenl++
-        w=nwords
+       literal=1
+       prenl++
+       w=nwords
       }
     } else if(match(words[w],"^Ed$")) {
       skip=1
@@ -96,7 +96,7 @@ function add(str) {
     } else if(match(words[w],"^Ns$")) {
       skip=1
       if(!nospace)
-        nospace=1
+       nospace=1
       sub(" $","",line)
     } else if(match(words[w],"^No$")) {
       skip=1
@@ -107,20 +107,20 @@ function add(str) {
       add("``")
       add(words[++w])
       while(w<nwords&&!match(words[w+1],"^[\\.,]"))
-        add(OFS words[++w])
+       add(OFS words[++w])
       add("''")
       if(!nospace&&match(words[w+1],"^[\\.,]"))
-        nospace=1
+       nospace=1
     } else if(match(words[w],"^Sq|Ql$")) {
       skip=1
       add("`" words[++w] "'")
       if(!nospace&&match(words[w+1],"^[\\.,]"))
-        nospace=1
+       nospace=1
     } else if(match(words[w],"^Oo$")) {
       skip=1
       extopt=1
       if(!nospace)
-        nospace=1
+       nospace=1
       add("[")
     } else if(match(words[w],"^Oc$")) {
       skip=1
@@ -129,9 +129,9 @@ function add(str) {
     }
     if(!skip) {
       if(!nospace&&length(line)&&!(match(line," $")||prenl))
-        add(OFS)
+       add(OFS)
       if(nospace==1)
-        nospace=0
+       nospace=0
     }
     if(match(words[w],"^Dd$")) {
       date=wtail()
@@ -158,69 +158,69 @@ function add(str) {
     } else if(match(words[w],"^Re$")) {
       prenl++
       for(i=nrefauthors-1;i>0;i--) {
-        add(refauthors[i])
-        if(i>1)
-          add(", ")
+       add(refauthors[i])
+       if(i>1)
+         add(", ")
       }
       if(nrefauthors>1)
-        add(" and ")
+       add(" and ")
       add(refauthors[0] ", \\fI" reftitle "\\fP")
       if(length(refissue))
-        add(", " refissue)
+       add(", " refissue)
       if(length(refdate))
-        add(", " refdate)
+       add(", " refdate)
       if(length(refopt))
-        add(", " refopt)
+       add(", " refopt)
       add(".")
       reference=0
     } else if(reference) {
       if(match(words[w],"^%A$")) { refauthors[nrefauthors++]=wtail() }
       if(match(words[w],"^%T$")) {
-        reftitle=wtail()
-        sub("^\"","",reftitle)
-        sub("\"$","",reftitle)
+       reftitle=wtail()
+       sub("^\"","",reftitle)
+       sub("\"$","",reftitle)
       }
       if(match(words[w],"^%N$")) { refissue=wtail() }
       if(match(words[w],"^%D$")) { refdate=wtail() }
       if(match(words[w],"^%O$")) { refopt=wtail() }
     } else if(match(words[w],"^Nm$")) {
       if(synopsis) {
-        add(".br")
-        prenl++
+       add(".br")
+       prenl++
       }
       n=words[++w]
       if(!length(name))
-        name=n
+       name=n
       if(!length(n))
-        n=name
+       n=name
       add("\\fB" n "\\fP")
       if(!nospace&&match(words[w+1],"^[\\.,]"))
-        nospace=1
+       nospace=1
     } else if(match(words[w],"^Nd$")) {
       add("\\- " wtail())
     } else if(match(words[w],"^Fl$")) {
       add("\\fB\\-" words[++w] "\\fP")
       if(!nospace&&match(words[w+1],"^[\\.,]"))
-        nospace=1
+       nospace=1
     } else if(match(words[w],"^Ar$")) {
       add("\\fI")
       if(w==nwords)
-        add("file ...\\fP")
+       add("file ...\\fP")
       else {
-        add(words[++w] "\\fP")
-        while(match(words[w+1],"^\\|$"))
-          add(OFS words[++w] " \\fI" words[++w] "\\fP")
+       add(words[++w] "\\fP")
+       while(match(words[w+1],"^\\|$"))
+         add(OFS words[++w] " \\fI" words[++w] "\\fP")
       }
       if(!nospace&&match(words[w+1],"^[\\.,]"))
-        nospace=1
+       nospace=1
     } else if(match(words[w],"^Cm$")) {
       add("\\fB" words[++w] "\\fP")
       while(w<nwords&&match(words[w+1],"^[\\.,:;)]"))
-        add(words[++w])
+       add(words[++w])
     } else if(match(words[w],"^Op$")) {
       option=1
       if(!nospace)
-        nospace=1
+       nospace=1
       add("[")
     } else if(match(words[w],"^Pp$")) {
       prenl++
@@ -232,10 +232,10 @@ function add(str) {
       add("\\fI")
       w++
       if(match(words[w],"^\\."))
-        add("\\&")
+       add("\\&")
       add(words[w] "\\fP")
       while(w<nwords&&match(words[w+1],"^[\\.,:;)]"))
-        add(words[++w])
+       add(words[++w])
     } else if(match(words[w],"^Dv$")) {
       add(".BR")
     } else if(match(words[w],"^Em|Ev$")) {
@@ -254,69 +254,69 @@ function add(str) {
       plain=1
       add("\\fB")
       while(w<nwords) {
-        w++
-        if(match(words[w],"^Op$")) {
-          w++
-          add("[")
-          words[nwords]=words[nwords] "]"
-        }
-        if(match(words[w],"^Ar$")) {
-          add("\\fI" words[++w] "\\fP")
-        } else if(match(words[w],"^[\\.,]")) {
-          sub(" $","",line)
-          if(plain) {
-            add("\\fP")
-            plain=0
-          }
-          add(words[w])
-        } else {
-          if(!plain) {
-            add("\\fB")
-            plain=1
-          }
-          add(words[w])
-        }
-        if(!nospace)
-          add(OFS)
+       w++
+       if(match(words[w],"^Op$")) {
+         w++
+         add("[")
+         words[nwords]=words[nwords] "]"
+       }
+       if(match(words[w],"^Ar$")) {
+         add("\\fI" words[++w] "\\fP")
+       } else if(match(words[w],"^[\\.,]")) {
+         sub(" $","",line)
+         if(plain) {
+           add("\\fP")
+           plain=0
+         }
+         add(words[w])
+       } else {
+         if(!plain) {
+           add("\\fB")
+           plain=1
+         }
+         add(words[w])
+       }
+       if(!nospace)
+         add(OFS)
       }
       sub(" $","",line)
       if(plain)
-        add("\\fP")
+       add("\\fP")
     } else if(match(words[w],"^Bl$")) {
       oldoptlist=optlist
       if(match(words[w+1],"-bullet"))
-        optlist=1
+       optlist=1
       else if(match(words[w+1],"-enum")) {
-        optlist=2
-        enum=0
+       optlist=2
+       enum=0
       } else if(match(words[w+1],"-tag"))
-        optlist=3
+       optlist=3
       else if(match(words[w+1],"-item"))
-        optlist=4
+       optlist=4
       else if(match(words[w+1],"-bullet"))
-        optlist=1
+       optlist=1
       w=nwords
     } else if(match(words[w],"^El$")) {
       optlist=oldoptlist
     } else if(match(words[w],"^It$")&&optlist) {
       if(optlist==1)
-        add(".IP \\(bu")
+       add(".IP \\(bu")
       else if(optlist==2)
-        add(".IP " ++enum ".")
+       add(".IP " ++enum ".")
       else if(optlist==3) {
-        add(".TP")
-        prenl++
-        if(match(words[w+1],"^Pa|Ev$")) {
-          add(".B")
-          w++
-        }
+       add(".TP")
+       prenl++
+       if(match(words[w+1],"^Pa|Ev$")) {
+         add(".B")
+         w++
+       }
       } else if(optlist==4)
-        add(".IP")
+       add(".IP")
     } else if(match(words[w],"^Sm$")) {
       if(match(words[w+1],"off"))
-        nospace=2
+       nospace=2
       else if(match(words[w+1],"on"))
-        nospace=0
+       nospace=0
       w++
     } else if(!skip) {
       add(words[w])
index b28e99c43147b1c50d7351a0811c0b6e34cb249e..36e5057a454069f6b84b1738d0ce8cf4b01a8ead 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: misc.c,v 1.22 2003/09/18 08:49:45 markus Exp $");
+RCSID("$OpenBSD: misc.c,v 1.23 2003/10/28 09:08:06 markus Exp $");
 
 #include "misc.h"
 #include "log.h"
@@ -97,7 +97,7 @@ set_nodelay(int fd)
 
        optlen = sizeof opt;
        if (getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, &optlen) == -1) {
-               error("getsockopt TCP_NODELAY: %.100s", strerror(errno));
+               debug("getsockopt TCP_NODELAY: %.100s", strerror(errno));
                return;
        }
        if (opt == 1) {
index eb2c0fd18e8a27e28e842436a465d496e2c86cfb..a09073aedbc5326e088f3232509fcc6c192caea5 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: moduli.c,v 1.1 2003/07/28 09:49:56 djm Exp $ */
+/* $OpenBSD: moduli.c,v 1.5 2003/12/22 09:16:57 djm Exp $ */
 /*
  * Copyright 1994 Phil Karn <karn@qualcomm.com>
  * Copyright 1996-1998, 2003 William Allen Simpson <wsimpson@greendragon.com>
 
 #include <openssl/bn.h>
 
-
-/*
- * Debugging defines 
- */
-
-/* define DEBUG_LARGE 1 */
-/* define DEBUG_SMALL 1 */
-/* define DEBUG_TEST  1 */
-
 /*
  * File output defines
  */
 #define QTEST_JACOBI            (0x08)
 #define QTEST_ELLIPTIC          (0x10)
 
-/* Size: decimal.
+/*
+ * Size: decimal.
  * Specifies the number of the most significant bit (0 to M).
- ** WARNING: internally, usually 1 to N.
+ * WARNING: internally, usually 1 to N.
  */
 #define QSIZE_MINIMUM           (511)
 
@@ -151,7 +143,7 @@ qfileout(FILE * ofile, u_int32_t otype, u_int32_t otests, u_int32_t otries,
 
        time(&time_now);
        gtm = gmtime(&time_now);
-       
+
        res = fprintf(ofile, "%04d%02d%02d%02d%02d%02d %u %u %u %u %x ",
            gtm->tm_year + 1900, gtm->tm_mon + 1, gtm->tm_mday,
            gtm->tm_hour, gtm->tm_min, gtm->tm_sec,
@@ -178,7 +170,7 @@ sieve_large(u_int32_t s)
 {
        u_int32_t r, u;
 
-       debug2("sieve_large %u", s);
+       debug3("sieve_large %u", s);
        largetries++;
        /* r = largebase mod s */
        r = BN_mod_word(largebase, s);
@@ -244,9 +236,9 @@ gen_candidates(FILE *out, int memory, int power, BIGNUM *start)
        largememory = memory;
 
        /*
-         * Set power to the length in bits of the prime to be generated.
-         * This is changed to 1 less than the desired safe prime moduli p.
-         */
+        * Set power to the length in bits of the prime to be generated.
+        * This is changed to 1 less than the desired safe prime moduli p.
+        */
        if (power > TEST_MAXIMUM) {
                error("Too many bits: %u > %lu", power, TEST_MAXIMUM);
                return (-1);
@@ -257,16 +249,16 @@ gen_candidates(FILE *out, int memory, int power, BIGNUM *start)
        power--; /* decrement before squaring */
 
        /*
-         * The density of ordinary primes is on the order of 1/bits, so the
-         * density of safe primes should be about (1/bits)**2. Set test range
-         * to something well above bits**2 to be reasonably sure (but not
-         * guaranteed) of catching at least one safe prime.
+        * The density of ordinary primes is on the order of 1/bits, so the
+        * density of safe primes should be about (1/bits)**2. Set test range
+        * to something well above bits**2 to be reasonably sure (but not
+        * guaranteed) of catching at least one safe prime.
         */
        largewords = ((power * power) >> (SHIFT_WORD - TEST_POWER));
 
        /*
-         * Need idea of how much memory is available. We don't have to use all
-         * of it.
+        * Need idea of how much memory is available. We don't have to use all
+        * of it.
         */
        if (largememory > LARGE_MAXIMUM) {
                logit("Limited memory: %u MB; limit %lu MB",
@@ -315,8 +307,8 @@ gen_candidates(FILE *out, int memory, int power, BIGNUM *start)
        q = BN_new();
 
        /*
-         * Generate random starting point for subprime search, or use
-         * specified parameter.
+        * Generate random starting point for subprime search, or use
+        * specified parameter.
         */
        largebase = BN_new();
        if (start == NULL)
@@ -329,13 +321,13 @@ gen_candidates(FILE *out, int memory, int power, BIGNUM *start)
 
        time(&time_start);
 
-       logit("%.24s Sieve next %u plus %u-bit", ctime(&time_start), 
+       logit("%.24s Sieve next %u plus %u-bit", ctime(&time_start),
            largenumbers, power);
        debug2("start point: 0x%s", BN_bn2hex(largebase));
 
        /*
-         * TinySieve
-         */
+        * TinySieve
+        */
        for (i = 0; i < tinybits; i++) {
                if (BIT_TEST(TinySieve, i))
                        continue; /* 2*i+3 is composite */
@@ -351,9 +343,9 @@ gen_candidates(FILE *out, int memory, int power, BIGNUM *start)
        }
 
        /*
-         * Start the small block search at the next possible prime. To avoid
-         * fencepost errors, the last pass is skipped.
-         */
+        * Start the small block search at the next possible prime. To avoid
+        * fencepost errors, the last pass is skipped.
+        */
        for (smallbase = TINY_NUMBER + 3;
             smallbase < (SMALL_MAXIMUM - TINY_NUMBER);
             smallbase += TINY_NUMBER) {
@@ -386,8 +378,8 @@ gen_candidates(FILE *out, int memory, int power, BIGNUM *start)
                }
 
                /*
-                 * SmallSieve
-                 */
+                * SmallSieve
+                */
                for (i = 0; i < smallbits; i++) {
                        if (BIT_TEST(SmallSieve, i))
                                continue; /* 2*i+smallbase is composite */
@@ -438,7 +430,7 @@ gen_candidates(FILE *out, int memory, int power, BIGNUM *start)
  * The result is a list of so-call "safe" primes
  */
 int
-prime_test(FILE *in, FILE *out, u_int32_t trials, 
+prime_test(FILE *in, FILE *out, u_int32_t trials,
     u_int32_t generator_wanted)
 {
        BIGNUM *q, *p, *a;
@@ -483,6 +475,7 @@ prime_test(FILE *in, FILE *out, u_int32_t trials,
                        debug2("%10u: known composite", count_in);
                        continue;
                }
+
                /* tries */
                in_tries = strtoul(cp, &cp, 10);
 
@@ -507,13 +500,20 @@ prime_test(FILE *in, FILE *out, u_int32_t trials,
                        in_size += 1;
                        generator_known = 0;
                        break;
-               default:
+               case QTYPE_UNSTRUCTURED:
+               case QTYPE_SAFE:
+               case QTYPE_SCHNOOR:
+               case QTYPE_STRONG:
+               case QTYPE_UNKNOWN:
                        debug2("%10u: (%u)", count_in, in_type);
                        a = p;
                        BN_hex2bn(&a, cp);
                        /* q = (p-1) / 2 */
                        BN_rshift(q, p, 1);
                        break;
+               default:
+                       debug2("Unknown prime type");
+                       break;
                }
 
                /*
@@ -533,6 +533,7 @@ prime_test(FILE *in, FILE *out, u_int32_t trials,
                        in_tries += trials;
                else
                        in_tries = trials;
+
                /*
                 * guess unknown generator
                 */
@@ -544,9 +545,8 @@ prime_test(FILE *in, FILE *out, u_int32_t trials,
                        else {
                                u_int32_t r = BN_mod_word(p, 10);
 
-                               if (r == 3 || r == 7) {
+                               if (r == 3 || r == 7)
                                        generator_known = 5;
-                               }
                        }
                }
                /*
@@ -559,30 +559,39 @@ prime_test(FILE *in, FILE *out, u_int32_t trials,
                        continue;
                }
 
+               /*
+                * Primes with no known generator are useless for DH, so
+                * skip those.
+                */
+               if (generator_known == 0) {
+                       debug2("%10u: no known generator", count_in);
+                       continue;
+               }
+
                count_possible++;
 
                /*
-                * The (1/4)^N performance bound on Miller-Rabin is 
-                * extremely pessimistic, so don't spend a lot of time 
-                * really verifying that q is prime until after we know 
-                * that p is also prime. A single pass will weed out the 
+                * The (1/4)^N performance bound on Miller-Rabin is
+                * extremely pessimistic, so don't spend a lot of time
+                * really verifying that q is prime until after we know
+                * that p is also prime. A single pass will weed out the
                 * vast majority of composite q's.
                 */
                if (BN_is_prime(q, 1, NULL, ctx, NULL) <= 0) {
-                       debug2("%10u: q failed first possible prime test",
+                       debug("%10u: q failed first possible prime test",
                            count_in);
                        continue;
                }
-       
+
                /*
-                * q is possibly prime, so go ahead and really make sure 
-                * that p is prime. If it is, then we can go back and do 
-                * the same for q. If p is composite, chances are that 
+                * q is possibly prime, so go ahead and really make sure
+                * that p is prime. If it is, then we can go back and do
+                * the same for q. If p is composite, chances are that
                 * will show up on the first Rabin-Miller iteration so it
                 * doesn't hurt to specify a high iteration count.
                 */
                if (!BN_is_prime(p, trials, NULL, ctx, NULL)) {
-                       debug2("%10u: p is not prime", count_in);
+                       debug("%10u: p is not prime", count_in);
                        continue;
                }
                debug("%10u: p is almost certainly prime", count_in);
@@ -594,7 +603,7 @@ prime_test(FILE *in, FILE *out, u_int32_t trials,
                }
                debug("%10u: q is almost certainly prime", count_in);
 
-               if (qfileout(out, QTYPE_SAFE, (in_tests | QTEST_MILLER_RABIN), 
+               if (qfileout(out, QTYPE_SAFE, (in_tests | QTEST_MILLER_RABIN),
                    in_tries, in_size, generator_known, p)) {
                        res = -1;
                        break;
@@ -610,7 +619,7 @@ prime_test(FILE *in, FILE *out, u_int32_t trials,
        BN_CTX_free(ctx);
 
        logit("%.24s Found %u safe primes of %u candidates in %ld seconds",
-           ctime(&time_stop), count_out, count_possible, 
+           ctime(&time_stop), count_out, count_possible,
            (long) (time_stop - time_start));
 
        return (res);
index 21fd6810c59a2f3b0e65b476261387862d6f6f0f..b43205073b0d9846e0f653c71979599ebb0053db 100644 (file)
@@ -25,7 +25,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: monitor.c,v 1.49 2003/08/28 12:54:34 markus Exp $");
+RCSID("$OpenBSD: monitor.c,v 1.55 2004/02/05 05:37:17 dtucker Exp $");
 
 #include <openssl/dh.h>
 
@@ -134,6 +134,7 @@ int mm_answer_pam_free_ctx(int, Buffer *);
 int mm_answer_gss_setup_ctx(int, Buffer *);
 int mm_answer_gss_accept_ctx(int, Buffer *);
 int mm_answer_gss_userok(int, Buffer *);
+int mm_answer_gss_checkmic(int, Buffer *);
 #endif
 
 #ifdef GSSAPI
@@ -207,6 +208,7 @@ struct mon_table mon_dispatch_proto20[] = {
     {MONITOR_REQ_GSSERR, MON_ISAUTH | MON_ONCE, mm_answer_gss_error},
     {MONITOR_REQ_GSSMECHS, MON_ISAUTH, mm_answer_gss_indicate_mechs},
     {MONITOR_REQ_GSSLOCALNAME, MON_ISAUTH, mm_answer_gss_localname},
+    {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic},
 #endif
     {0, 0, NULL}
 };
@@ -300,14 +302,17 @@ monitor_permit_authentications(int permit)
        }
 }
 
-Authctxt *
-monitor_child_preauth(struct monitor *pmonitor)
+void
+monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
 {
        struct mon_table *ent;
        int authenticated = 0;
 
        debug3("preauth child monitor started");
 
+       authctxt = _authctxt;
+       memset(authctxt, 0, sizeof(*authctxt));
+
        if (compat20) {
                mon_dispatch = mon_dispatch_proto20;
 
@@ -326,8 +331,6 @@ monitor_child_preauth(struct monitor *pmonitor)
                monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1);
        }
 
-       authctxt = authctxt_new();
-
        /* The first few requests do not require asynchronous access */
        while (!authenticated) {
                authenticated = monitor_read(pmonitor, mon_dispatch, &ent);
@@ -340,11 +343,11 @@ monitor_child_preauth(struct monitor *pmonitor)
                                authenticated = 0;
 #ifdef USE_PAM
                        /* PAM needs to perform account checks after auth */
-                       if (options.use_pam) {
+                       if (options.use_pam && authenticated) {
                                Buffer m;
 
                                buffer_init(&m);
-                               mm_request_receive_expect(pmonitor->m_sendfd, 
+                               mm_request_receive_expect(pmonitor->m_sendfd,
                                    MONITOR_REQ_PAM_ACCOUNT, &m);
                                authenticated = mm_answer_pam_account(pmonitor->m_sendfd, &m);
                                buffer_free(&m);
@@ -367,8 +370,6 @@ monitor_child_preauth(struct monitor *pmonitor)
            __func__, authctxt->user);
 
        mm_get_keystate(pmonitor);
-
-       return (authctxt);
 }
 
 static void
@@ -609,6 +610,7 @@ mm_answer_pwnamallow(int socket, Buffer *m)
 
        if (pwent == NULL) {
                buffer_put_char(m, 0);
+               authctxt->pw = fakepw();
                goto out;
        }
 
@@ -824,7 +826,7 @@ int
 mm_answer_pam_start(int socket, Buffer *m)
 {
        char *user;
-       
+
        if (!options.use_pam)
                fatal("UsePAM not set, but ended up in %s anyway", __func__);
 
@@ -843,7 +845,7 @@ int
 mm_answer_pam_account(int socket, Buffer *m)
 {
        u_int ret;
-       
+
        if (!options.use_pam)
                fatal("UsePAM not set, but ended up in %s anyway", __func__);
 
@@ -990,7 +992,7 @@ mm_answer_keyallowed(int socket, Buffer *m)
 
        debug3("%s: key_from_blob: %p", __func__, key);
 
-       if (key != NULL && authctxt->pw != NULL) {
+       if (key != NULL && authctxt->valid) {
                switch(type) {
                case MM_USERKEY:
                        allowed = options.pubkey_authentication &&
@@ -1228,7 +1230,7 @@ mm_record_login(Session *s, struct passwd *pw)
                if (getpeername(packet_get_connection_in(),
                        (struct sockaddr *) & from, &fromlen) < 0) {
                        debug("getpeername: %.100s", strerror(errno));
-                       fatal_cleanup();
+                       cleanup_exit(255);
                }
        }
        /* Record that there was a login on that tty from the remote host. */
@@ -1243,7 +1245,6 @@ mm_session_close(Session *s)
        debug3("%s: session %d pid %ld", __func__, s->self, (long)s->pid);
        if (s->ttyfd != -1) {
                debug3("%s: tty %s ptyfd %d",  __func__, s->tty, s->ptyfd);
-               fatal_remove_cleanup(session_pty_cleanup2, (void *)s);
                session_pty_cleanup2(s);
        }
        s->used = 0;
@@ -1268,7 +1269,6 @@ mm_answer_pty(int socket, Buffer *m)
        res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty));
        if (res == 0)
                goto error;
-       fatal_add_cleanup(session_pty_cleanup2, (void *)s);
        pty_setowner(authctxt->pw, s->tty);
 
        buffer_put_int(m, 1);
@@ -1754,6 +1754,7 @@ monitor_init(void)
 
        mon = xmalloc(sizeof(*mon));
 
+       mon->m_pid = 0;
        monitor_socketpair(pair);
 
        mon->m_recvfd = pair[0];
@@ -1830,15 +1831,43 @@ mm_answer_gss_accept_ctx(int socket, Buffer *m)
 
        gss_release_buffer(&minor, &out);
 
-       /* Complete - now we can do signing */
        if (major==GSS_S_COMPLETE) {
                monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0);
                monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);
                monitor_permit(mon_dispatch, MONITOR_REQ_GSSSIGN, 1);
+               monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1);
        }
        return (0);
 }
 
+int
+mm_answer_gss_checkmic(int socket, Buffer *m)
+{
+       gss_buffer_desc gssbuf, mic;
+       OM_uint32 ret;
+       u_int len;
+
+       gssbuf.value = buffer_get_string(m, &len);
+       gssbuf.length = len;
+       mic.value = buffer_get_string(m, &len);
+       mic.length = len;
+
+       ret = ssh_gssapi_checkmic(gsscontext, &gssbuf, &mic);
+
+       xfree(gssbuf.value);
+       xfree(mic.value);
+
+       buffer_clear(m);
+       buffer_put_int(m, ret);
+
+       mm_request_send(socket, MONITOR_ANS_GSSCHECKMIC, m);
+
+       if (!GSS_ERROR(ret))
+               monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);
+
+       return (0);
+}
+
 int
 mm_answer_gss_userok(int socket, Buffer *m)
 {
@@ -1852,7 +1881,7 @@ mm_answer_gss_userok(int socket, Buffer *m)
        debug3("%s: sending result %d", __func__, authenticated);
        mm_request_send(socket, MONITOR_ANS_GSSUSEROK, m);
 
-       auth_method="gssapi";
+       auth_method="gssapi-with-mic";
 
        /* Monitor loop will terminate if authenticated */
        return (authenticated);
index ce76ab6ed82d6d96fc05c280611d43ce98edc5bb..705d86df7aa2cecea7131623eda0093de5470777 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: monitor.h,v 1.11 2003/08/28 12:54:34 markus Exp $     */
+/*     $OpenBSD: monitor.h,v 1.13 2003/11/17 11:06:07 markus Exp $     */
 
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
@@ -56,6 +56,7 @@ enum monitor_reqtype {
        MONITOR_REQ_GSSMECHS, MONITOR_ANS_GSSMECHS,
        MONITOR_REQ_GSSLOCALNAME, MONITOR_ANS_GSSLOCALNAME,
        MONITOR_REQ_GSSERR, MONITOR_ANS_GSSERR,
+       MONITOR_REQ_GSSCHECKMIC, MONITOR_ANS_GSSCHECKMIC,
        MONITOR_REQ_PAM_START,
        MONITOR_REQ_PAM_ACCOUNT, MONITOR_ANS_PAM_ACCOUNT,
        MONITOR_REQ_PAM_INIT_CTX, MONITOR_ANS_PAM_INIT_CTX,
@@ -80,7 +81,7 @@ void monitor_reinit(struct monitor *);
 void monitor_sync(struct monitor *);
 
 struct Authctxt;
-struct Authctxt *monitor_child_preauth(struct monitor *);
+void monitor_child_preauth(struct Authctxt *, struct monitor *);
 void monitor_child_postauth(struct monitor *);
 
 struct mon_table;
index 3137b4840c9704580b1c251846a7f4143937a97a..567c9c630531b62eb53a23152fdb1075283f8e43 100644 (file)
@@ -25,7 +25,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: monitor_wrap.c,v 1.31 2003/08/28 12:54:34 markus Exp $");
+RCSID("$OpenBSD: monitor_wrap.c,v 1.35 2003/11/17 11:06:07 markus Exp $");
 
 #include <openssl/bn.h>
 #include <openssl/dh.h>
@@ -66,6 +66,16 @@ extern struct monitor *pmonitor;
 extern Buffer input, output;
 extern ServerOptions options;
 
+int
+mm_is_monitor(void)
+{
+       /*
+        * m_pid is only set in the privileged part, and
+        * points to the unprivileged child.
+        */
+       return (pmonitor && pmonitor->m_pid > 0);
+}
+
 void
 mm_request_send(int socket, enum monitor_reqtype type, Buffer *m)
 {
@@ -94,7 +104,7 @@ mm_request_receive(int socket, Buffer *m)
        res = atomicio(read, socket, buf, sizeof(buf));
        if (res != sizeof(buf)) {
                if (res == 0)
-                       fatal_cleanup();
+                       cleanup_exit(255);
                fatal("%s: read: %ld", __func__, (long)res);
        }
        msg_len = GET_32BIT(buf);
@@ -214,7 +224,8 @@ mm_getpwnamallow(const char *login)
        return (pw);
 }
 
-char *mm_auth2_read_banner(void)
+char *
+mm_auth2_read_banner(void)
 {
        Buffer m;
        char *banner;
@@ -225,10 +236,16 @@ char *mm_auth2_read_banner(void)
        mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTH2_READ_BANNER, &m);
        buffer_clear(&m);
 
-       mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUTH2_READ_BANNER, &m);
+       mm_request_receive_expect(pmonitor->m_recvfd,
+           MONITOR_ANS_AUTH2_READ_BANNER, &m);
        banner = buffer_get_string(&m, NULL);
        buffer_free(&m);
 
+       /* treat empty banner as missing banner */
+       if (strlen(banner) == 0) {
+               xfree(banner);
+               banner = NULL;
+       }
        return (banner);
 }
 
@@ -648,9 +665,8 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
 }
 
 void
-mm_session_pty_cleanup2(void *session)
+mm_session_pty_cleanup2(Session *s)
 {
-       Session *s = session;
        Buffer m;
 
        if (s->ttyfd == -1)
@@ -699,12 +715,12 @@ mm_do_pam_account(void)
        buffer_init(&m);
        mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_ACCOUNT, &m);
 
-       mm_request_receive_expect(pmonitor->m_recvfd, 
+       mm_request_receive_expect(pmonitor->m_recvfd,
            MONITOR_ANS_PAM_ACCOUNT, &m);
        ret = buffer_get_int(&m);
 
        buffer_free(&m);
-       
+
        debug3("%s returning %d", __func__, ret);
 
        return (ret);
@@ -1118,6 +1134,25 @@ mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in,
        return (major);
 }
 
+OM_uint32
+mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
+{
+       Buffer m;
+       OM_uint32 major;
+
+       buffer_init(&m);
+       buffer_put_string(&m, gssbuf->value, gssbuf->length);
+       buffer_put_string(&m, gssmic->value, gssmic->length);
+
+       mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSCHECKMIC, &m);
+       mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSCHECKMIC,
+           &m);
+
+       major = buffer_get_int(&m);
+       buffer_free(&m);
+       return(major);
+}
+
 int
 mm_ssh_gssapi_userok(char *user)
 {
index 19c75e482a591ae9847782771cf01b3ceb80a796..c4e8f3021326ee5d18982be9eaa7eaffeab1469d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: monitor_wrap.h,v 1.11 2003/08/28 12:54:34 markus Exp $        */
+/*     $OpenBSD: monitor_wrap.h,v 1.13 2003/11/17 11:06:07 markus Exp $        */
 
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
@@ -40,6 +40,7 @@ struct mm_master;
 struct passwd;
 struct Authctxt;
 
+int mm_is_monitor(void);
 DH *mm_choose_dh(int, int, int);
 int mm_key_sign(Key *, u_char **, u_int *, u_char *, u_int);
 void mm_inform_authserv(char *, char *);
@@ -61,6 +62,13 @@ OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **ctxt, gss_OID oid);
 OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *ctxt,
    gss_buffer_desc *recv, gss_buffer_desc *send, OM_uint32 *flags);
 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 *ctxt, gss_buffer_desc *buffer,
+                            gss_buffer_desc *hash);
+int mm_ssh_gssapi_localname(char **user);
+OM_uint32 mm_gss_indicate_mechs(OM_uint32 *minor_status,
+                               gss_OID_set *mech_set);
+char *mm_ssh_gssapi_last_error(Gssctxt *ctxt, OM_uint32 *maj, OM_uint32 *min);
 #endif
 
 #ifdef USE_PAM
@@ -72,24 +80,10 @@ int mm_sshpam_respond(void *, u_int, char **);
 void mm_sshpam_free_ctx(void *);
 #endif
 
-#ifdef GSSAPI
-#include "ssh-gss.h"
-OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **ctxt, gss_OID oid);
-OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *ctxt, gss_buffer_desc *recv,
-                                  gss_buffer_desc *send, OM_uint32 *flags);
-OM_uint32 mm_ssh_gssapi_sign(Gssctxt *ctxt, gss_buffer_desc *buffer,
-                            gss_buffer_desc *hash);
-int mm_ssh_gssapi_userok(char *user);
-int mm_ssh_gssapi_localname(char **user);
-OM_uint32 mm_gss_indicate_mechs(OM_uint32 *minor_status,
-                               gss_OID_set *mech_set);
-char *mm_ssh_gssapi_last_error(Gssctxt *ctxt, OM_uint32 *maj, OM_uint32 *min);
-
-#endif
-
+struct Session;
 void mm_terminate(void);
 int mm_pty_allocate(int *, int *, char *, int);
-void mm_session_pty_cleanup2(void *);
+void mm_session_pty_cleanup2(struct Session *);
 
 /* SSHv1 interfaces */
 void mm_ssh1_session_id(u_char *);
index 6a806c3f5a1fec68d9a8a25bec8fe00b4cd2cf92..30bc3f1076385c8a599544342b870b0e684dbbbb 100644 (file)
@@ -22,7 +22,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include "includes.h"
-RCSID("$OpenBSD: msg.c,v 1.6 2003/06/28 16:23:06 deraadt Exp $");
+RCSID("$OpenBSD: msg.c,v 1.7 2003/11/17 09:45:39 djm Exp $");
 
 #include "buffer.h"
 #include "getput.h"
@@ -30,7 +30,7 @@ RCSID("$OpenBSD: msg.c,v 1.6 2003/06/28 16:23:06 deraadt Exp $");
 #include "atomicio.h"
 #include "msg.h"
 
-void
+int
 ssh_msg_send(int fd, u_char type, Buffer *m)
 {
        u_char buf[5];
@@ -40,10 +40,15 @@ ssh_msg_send(int fd, u_char type, Buffer *m)
 
        PUT_32BIT(buf, mlen + 1);
        buf[4] = type;          /* 1st byte of payload is mesg-type */
-       if (atomicio(vwrite, fd, buf, sizeof(buf)) != sizeof(buf))
-               fatal("ssh_msg_send: write");
-       if (atomicio(vwrite, fd, buffer_ptr(m), mlen) != mlen)
-               fatal("ssh_msg_send: write");
+       if (atomicio(vwrite, fd, buf, sizeof(buf)) != sizeof(buf)) {
+               error("ssh_msg_send: write");
+               return (-1);
+       }
+       if (atomicio(vwrite, fd, buffer_ptr(m), mlen) != mlen) {
+               error("ssh_msg_send: write");
+               return (-1);
+       }
+       return (0);
 }
 
 int
@@ -57,17 +62,21 @@ ssh_msg_recv(int fd, Buffer *m)
 
        res = atomicio(read, fd, buf, sizeof(buf));
        if (res != sizeof(buf)) {
-               if (res == 0)
-                       return -1;
-               fatal("ssh_msg_recv: read: header %ld", (long)res);
+               if (res != 0)
+                       error("ssh_msg_recv: read: header %ld", (long)res);
+               return (-1);
        }
        msg_len = GET_32BIT(buf);
-       if (msg_len > 256 * 1024)
-               fatal("ssh_msg_recv: read: bad msg_len %u", msg_len);
+       if (msg_len > 256 * 1024) {
+               error("ssh_msg_recv: read: bad msg_len %u", msg_len);
+               return (-1);
+       }
        buffer_clear(m);
        buffer_append_space(m, msg_len);
        res = atomicio(read, fd, buffer_ptr(m), msg_len);
-       if (res != msg_len)
-               fatal("ssh_msg_recv: read: %ld != msg_len", (long)res);
-       return 0;
+       if (res != msg_len) {
+               error("ssh_msg_recv: read: %ld != msg_len", (long)res);
+               return (-1);
+       }
+       return (0);
 }
index c07df88a7acd4b66ad6627ff80481f04ab68513a..0d3ea065826ca4eb28d6a123e548999a85fcd09d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: msg.h,v 1.2 2002/12/19 00:07:02 djm Exp $     */
+/*     $OpenBSD: msg.h,v 1.3 2003/11/17 09:45:39 djm Exp $     */
 /*
  * Copyright (c) 2002 Markus Friedl.  All rights reserved.
  *
@@ -25,7 +25,7 @@
 #ifndef SSH_MSG_H
 #define SSH_MSG_H
 
-void    ssh_msg_send(int, u_char, Buffer *);
+int     ssh_msg_send(int, u_char, Buffer *);
 int     ssh_msg_recv(int, Buffer *);
 
 #endif
index 2054c806891b21d54464de4560085d069e29733a..552dc1e1cde732f396fe5d6d7b90b86b2ae3e8b7 100644 (file)
@@ -1,3 +1,5 @@
+/* OPENBSD ORIGINAL: lib/libc/gen/basename.c */
+
 /*     $OpenBSD: basename.c,v 1.11 2003/06/17 21:56:23 millert Exp $   */
 
 /*
index 71225f7ec2165f70bf8b1984f34e27a53d58577a..8a3779f3aa91f6e8b7abd4bb39f2d91bbf556364 100644 (file)
@@ -1,25 +1,17 @@
 /*
- * Copyright (c) 2002 Damien Miller.  All rights reserved.
+ * Copyright (c) 2002,2004 Damien Miller <djm@mindrot.org>
  *
- * 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.
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
  *
- * 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.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
 #include "includes.h"
index 5f035d77c5f04252dc6469544d9a113002f480cb..aabc3955670af1f49d0306836c6bebcb53daca31 100644 (file)
@@ -1,27 +1,19 @@
 /* $Id$ */
 
 /*
- * Copyright (c) 1999-2003 Damien Miller.  All rights reserved.
+ * Copyright (c) 1999-2004 Damien Miller <djm@mindrot.org>
  *
- * 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.
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
  *
- * 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.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
 #ifndef _BSD_MISC_H
index 955986b50218d3f6bd81162e22f0d6bcf5101cb6..47b790f4e3e5e2828cae2ad76889b9fd5e0a7980 100644 (file)
@@ -133,19 +133,23 @@ struct addrinfo {
 #endif /* !HAVE_STRUCT_ADDRINFO */
 
 #ifndef HAVE_GETADDRINFO
+#define getaddrinfo(a,b,c,d)   (ssh_getaddrinfo(a,b,c,d))
 int getaddrinfo(const char *, const char *, 
     const struct addrinfo *, struct addrinfo **);
 #endif /* !HAVE_GETADDRINFO */
 
 #if !defined(HAVE_GAI_STRERROR) && !defined(HAVE_CONST_GAI_STRERROR_PROTO)
+#define gai_strerror(a)                (ssh_gai_strerror(a))
 char *gai_strerror(int);
 #endif /* !HAVE_GAI_STRERROR */
 
 #ifndef HAVE_FREEADDRINFO
+#define freeaddrinfo(a)                (ssh_freeaddrinfo(a))
 void freeaddrinfo(struct addrinfo *);
 #endif /* !HAVE_FREEADDRINFO */
 
 #ifndef HAVE_GETNAMEINFO
+#define getnameinfo(a,b,c,d,e,f,g) (ssh_getnameinfo(a,b,c,d,e,f,g))
 int getnameinfo(const struct sockaddr *, size_t, char *, size_t, 
     char *, size_t, int);
 #endif /* !HAVE_GETNAMEINFO */
index 2136fbfcca609f85dd886815a401fd5e20f7eba9..f5ee6778da41d16852ea234660ac70a85d413185 100644 (file)
@@ -1,3 +1,5 @@
+/* OPENBSD ORIGINAL: lib/libc/stdlib/getopt.c */
+
 /*
  * Copyright (c) 1987, 1993, 1994
  *     The Regents of the University of California.  All rights reserved.
index 44fa2755b6bb26201f6086a13cd558cdcdb6e1c5..66d18142e0de63aa423d2b5731adfad606f07879 100644 (file)
@@ -1,3 +1,5 @@
+/* OPENBSD ORIGINAL: lib/libc/net/getrrsetbyname.c */
+
 /* $OpenBSD: getrrsetbyname.c,v 1.7 2003/03/07 07:34:14 itojun Exp $ */
 
 /*
 
 #include "includes.h"
 
-#if defined(DNS) && !defined(HAVE_GETRRSETBYNAME)
+#ifndef HAVE_GETRRSETBYNAME
 
 #include "getrrsetbyname.h"
 
-/* #include "thread_private.h" */
-
 #define ANSWER_BUFFER_SIZE 1024*64
 
 struct dns_query {
@@ -159,7 +159,6 @@ getrrsetbyname(const char *hostname, unsigned int rdclass,
     unsigned int rdtype, unsigned int flags,
     struct rrsetinfo **res)
 {
-       struct __res_state *_resp = &_res;
        int result;
        struct rrsetinfo *rrset = NULL;
        struct dns_response *response;
@@ -188,19 +187,19 @@ getrrsetbyname(const char *hostname, unsigned int rdclass,
        }
 
        /* initialize resolver */
-       if ((_resp->options & RES_INIT) == 0 && res_init() == -1) {
+       if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
                result = ERRSET_FAIL;
                goto fail;
        }
 
 #ifdef DEBUG
-       _resp->options |= RES_DEBUG;
+       _res.options |= RES_DEBUG;
 #endif /* DEBUG */
 
 #ifdef RES_USE_DNSSEC
        /* turn on DNSSEC if EDNS0 is configured */
-       if (_resp->options & RES_USE_EDNS0)
-               _resp->options |= RES_USE_DNSSEC;
+       if (_res.options & RES_USE_EDNS0)
+               _res.options |= RES_USE_DNSSEC;
 #endif /* RES_USE_DNSEC */
 
        /* make query */
@@ -575,4 +574,4 @@ count_dns_rr(struct dns_rr *p, u_int16_t class, u_int16_t type)
        return (n);
 }
 
-#endif /* defined(DNS) && !defined(HAVE_GETRRSETBYNAME) */
+#endif /* !defined(HAVE_GETRRSETBYNAME) */
index 6466a54d6fbcc20658c06ef176079b3ce6f5fef0..39995b63fc0333b9383565d6de4e3720ab04e802 100644 (file)
@@ -1,3 +1,5 @@
+/* OPENBSD BASED ON : include/netdb.h */
+
 /* $OpenBSD: getrrsetbyname.c,v 1.4 2001/08/16 18:16:43 ho Exp $ */
 
 /*
@@ -48,7 +50,7 @@
 
 #include "includes.h"
 
-#if defined(DNS) && !defined(HAVE_GETRRSETBYNAME)
+#ifndef HAVE_GETRRSETBYNAME
 
 #include <sys/types.h>
 #include <netinet/in.h>
 #include <netdb.h>
 #include <resolv.h>
 
+#ifndef HFIXEDSZ
+#define HFIXEDSZ 12
+#endif
+
+#ifndef T_SIG
+#define T_SIG 24
+#endif
+
 /*
  * Flags for getrrsetbyname()
  */
@@ -95,6 +105,6 @@ struct rrsetinfo {
 int            getrrsetbyname(const char *, unsigned int, unsigned int, unsigned int, struct rrsetinfo **);
 void           freerrset(struct rrsetinfo *);
 
-#endif /* defined(DNS) && !defined(HAVE_GETRRSETBYNAME) */
+#endif /* !defined(HAVE_GETRRSETBYNAME) */
 
 #endif /* _GETRRSETBYNAME_H */
index 9fbcce936d4d5af0a3099c35b27d7fb59a47d1c3..2895f0d441c63d6b91f76dd7ea724380c1c09612 100644 (file)
  *
  */
 #include "includes.h"
+#include "auth.h"
 #include "ssh.h"
 #include "log.h"
 #include "servconf.h"
 #include "canohost.h"
 #include "xmalloc.h"
+#include "buffer.h"
 
 #ifdef _AIX
 
 #include "port-aix.h"
 
 extern ServerOptions options;
+extern Buffer loginmsg;
+
+# ifdef HAVE_SETAUTHDB
+static char old_registry[REGISTRY_SIZE] = "";
+# endif
 
 /*
  * AIX has a "usrinfo" area where logname and other stuff is stored - 
@@ -63,7 +70,7 @@ aix_usrinfo(struct passwd *pw)
        xfree(cp);
 }
 
-#ifdef WITH_AIXAUTHENTICATE
+# ifdef WITH_AIXAUTHENTICATE
 /*
  * Remove embedded newlines in string (if any).
  * Used before logging messages returned by AIX authentication functions
@@ -83,41 +90,113 @@ aix_remove_embedded_newlines(char *p)
        if (*--p == ' ')
                *p = '\0';
 }
-#endif /* WITH_AIXAUTHENTICATE */
+
+/*
+ * Do authentication via AIX's authenticate routine.  We loop until the
+ * reenter parameter is 0, but normally authenticate is called only once.
+ *
+ * Note: this function returns 1 on success, whereas AIX's authenticate()
+ * returns 0.
+ */
+int
+sys_auth_passwd(Authctxt *ctxt, const char *password)
+{
+       char *authmsg = NULL, *host, *msg, *name = ctxt->pw->pw_name;
+       int authsuccess = 0, expired, reenter, result;
+
+       do {
+               result = authenticate((char *)name, (char *)password, &reenter,
+                   &authmsg);
+               aix_remove_embedded_newlines(authmsg);  
+               debug3("AIX/authenticate result %d, msg %.100s", result,
+                   authmsg);
+       } while (reenter);
+
+       if (result == 0) {
+               authsuccess = 1;
+
+               host = (char *)get_canonical_hostname(options.use_dns);
+
+               /*
+                * Record successful login.  We don't have a pty yet, so just
+                * label the line as "ssh"
+                */
+               aix_setauthdb(name);
+               if (loginsuccess((char *)name, (char *)host, "ssh", &msg) == 0) {
+                       if (msg != NULL) {
+                               debug("%s: msg %s", __func__, msg);
+                               buffer_append(&loginmsg, msg, strlen(msg));
+                               xfree(msg);
+                       }
+               }
+
+               /*
+                * Check if the user's password is expired.
+                */
+                expired = passwdexpired(name, &msg);
+                if (msg && *msg) {
+                        buffer_append(&loginmsg, msg, strlen(msg));
+                        aix_remove_embedded_newlines(msg);
+                }
+                debug3("AIX/passwdexpired returned %d msg %.100s", expired, msg);
+
+               switch (expired) {
+               case 0: /* password not expired */
+                       break;
+               case 1: /* expired, password change required */
+                       ctxt->force_pwchange = 1;
+                       disable_forwarding();
+                       break;
+               default: /* user can't change(2) or other error (-1) */
+                       logit("Password can't be changed for user %s: %.100s",
+                           name, msg);
+                       if (msg)
+                               xfree(msg);
+                       authsuccess = 0;
+               }
+
+               aix_restoreauthdb();
+       }
+
+       if (authmsg != NULL)
+               xfree(authmsg);
+
+       return authsuccess;
+}
   
-# ifdef CUSTOM_FAILED_LOGIN
+#  ifdef CUSTOM_FAILED_LOGIN
 /*
  * record_failed_login: generic "login failed" interface function
  */
 void
 record_failed_login(const char *user, const char *ttyname)
 {
-       char *hostname = get_canonical_hostname(options.use_dns);
+       char *hostname = (char *)get_canonical_hostname(options.use_dns);
 
        if (geteuid() != 0)
                return;
 
        aix_setauthdb(user);
-#  ifdef AIX_LOGINFAILED_4ARG
+#   ifdef AIX_LOGINFAILED_4ARG
        loginfailed((char *)user, hostname, (char *)ttyname, AUDIT_FAIL_AUTH);
-#  else
+#   else
        loginfailed((char *)user, hostname, (char *)ttyname);
-#  endif
+#   endif
+       aix_restoreauthdb();
 }
+#  endif /* CUSTOM_FAILED_LOGIN */
 
 /*
  * If we have setauthdb, retrieve the password registry for the user's
- * account then feed it to setauthdb.  This may load registry-specific method
- * code.  If we don't have setauthdb or have already called it this is a no-op.
+ * account then feed it to setauthdb.  This will mean that subsequent AIX auth
+ * functions will only use the specified loadable module.  If we don't have
+ * setauthdb this is a no-op.
  */
 void
 aix_setauthdb(const char *user)
 {
 #  ifdef HAVE_SETAUTHDB
-       static char *registry = NULL;
-
-       if (registry != NULL)   /* have already done setauthdb */
-               return;
+       char *registry;
 
        if (setuserdb(S_READ) == -1) {
                debug3("%s: Could not open userdb to read", __func__);
@@ -125,18 +204,37 @@ aix_setauthdb(const char *user)
        }
        
        if (getuserattr((char *)user, S_REGISTRY, &registry, SEC_CHAR) == 0) {
-               if (setauthdb(registry, NULL) == 0)
-                       debug3("%s: AIX/setauthdb set registry %s", __func__,
-                           registry);
+               if (setauthdb(registry, old_registry) == 0)
+                       debug3("AIX/setauthdb set registry '%s'", registry);
                else 
-                       debug3("%s: AIX/setauthdb set registry %s failed: %s",
-                           __func__, registry, strerror(errno));
+                       debug3("AIX/setauthdb set registry '%s' failed: %s",
+                           registry, strerror(errno));
        } else
                debug3("%s: Could not read S_REGISTRY for user: %s", __func__,
                    strerror(errno));
        enduserdb();
-#  endif
+#  endif /* HAVE_SETAUTHDB */
 }
-# endif /* CUSTOM_FAILED_LOGIN */
-#endif /* _AIX */
 
+/*
+ * Restore the user's registry settings from old_registry.
+ * Note that if the first aix_setauthdb fails, setauthdb("") is still safe
+ * (it restores the system default behaviour).  If we don't have setauthdb,
+ * this is a no-op.
+ */
+void
+aix_restoreauthdb(void)
+{
+#  ifdef HAVE_SETAUTHDB
+       if (setauthdb(old_registry, NULL) == 0)
+               debug3("%s: restoring old registry '%s'", __func__,
+                   old_registry);
+       else
+               debug3("%s: failed to restore old registry %s", __func__,
+                   old_registry);
+#  endif /* HAVE_SETAUTHDB */
+}
+
+# endif /* WITH_AIXAUTHENTICATE */
+
+#endif /* _AIX */
index 8a95816db123411c555c6637f50379d5d297a1c5..f6bed988db39d8f64e14a27c66e77ecb03b642f3 100644 (file)
 # include <sys/timers.h>
 #endif
 
+/*
+ * According to the setauthdb man page, AIX password registries must be 15
+ * chars or less plus terminating NUL.
+ */
+#ifdef HAVE_SETAUTHDB
+# define REGISTRY_SIZE 16
+#endif
+
+void aix_usrinfo(struct passwd *);
+
 #ifdef WITH_AIXAUTHENTICATE
+# define CUSTOM_SYS_AUTH_PASSWD 1
 # define CUSTOM_FAILED_LOGIN 1
 void record_failed_login(const char *, const char *);
-void aix_setauthdb(const char *);
 #endif
 
-void aix_usrinfo(struct passwd *);
+void aix_setauthdb(const char *);
+void aix_restoreauthdb(void);
 void aix_remove_embedded_newlines(char *);
 #endif /* _AIX */
index dd5c47525112415268dc5cf517d5457936591199..8ff19e45234d0250e40a92e6560622b9c686afba 100644 (file)
@@ -1,3 +1,5 @@
+/* OPENBSD ORIGINAL: sys/sys/queue.h */
+
 /*     $OpenBSD: queue.h,v 1.23 2003/06/02 23:28:21 millert Exp $      */
 /*     $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $       */
 
index 927ca04cd76b30e76948ad5ba21a760b5406dc32..73cfbe72a6618c442240bc6848e14d9a89ee81d8 100644 (file)
@@ -1,3 +1,5 @@
+/* OPENBSD ORIGINAL: sys/sys/tree.h */
+
 /*     $OpenBSD: tree.h,v 1.7 2002/10/17 21:51:54 art Exp $    */
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
index e6a2ce98d0a014aca51113544e5caf2bacffd685..1fb7a01e3a9592771f15faed902ea6674eca3814 100644 (file)
@@ -1,3 +1,5 @@
+/* OPENBSD ORIGINAL: lib/libc/gen/vis.c */
+
 /*-
  * Copyright (c) 1989, 1993
  *     The Regents of the University of California.  All rights reserved.
index 1c131cc8558d69fc41825ba98ee62f74a0d4153d..663355a240f0566339928f86b7d3abedeb768f18 100644 (file)
@@ -1,3 +1,5 @@
+/* OPENBSD ORIGINAL: include/vis.h */
+
 /*     $OpenBSD: vis.h,v 1.6 2003/06/02 19:34:12 millert Exp $ */
 /*     $NetBSD: vis.h,v 1.4 1994/10/26 00:56:41 cgd Exp $      */
 
index 5b5d69c72efc95fce67864843119b76aaba6ddbe..a0fe6c62009d0a433b70998a4daee349831c0a1c 100644 (file)
@@ -104,10 +104,6 @@ shadow_pw(struct passwd *pw)
 
        if (spw != NULL)
                pw_password = spw->ufld.fd_encrypt;
-# elif defined(__hpux) && !defined(HAVE_SECUREWARE)
-       struct pr_passwd *spw;
-        if (iscomsec() && (spw = getprpwnam(pw->pw_name)) != NULL)
-                pw_password = spw->ufld.fd_encrypt;
 # endif
 
        return pw_password;
index 02b629f30f6ec5358248fa8b26a262527c29fd11..daae9ffaaa2ad06d2b27c1f2ac53849477e1545e 100644 (file)
@@ -37,7 +37,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: packet.c,v 1.110 2003/09/19 09:02:02 markus Exp $");
+RCSID("$OpenBSD: packet.c,v 1.112 2003/09/23 20:17:11 markus Exp $");
 
 #include "openbsd-compat/sys-queue.h"
 
@@ -165,8 +165,6 @@ packet_set_connection(int fd_in, int fd_out)
                buffer_init(&incoming_packet);
                TAILQ_INIT(&outgoing);
        }
-       /* Kludge: arrange the close function to be called from fatal(). */
-       fatal_add_cleanup((void (*) (void *)) packet_close, NULL);
 }
 
 /* Returns 1 if remote host is connected via socket, 0 if not. */
@@ -306,7 +304,7 @@ packet_connection_is_ipv4(void)
        if (to.ss_family == AF_INET)
                return 1;
 #ifdef IPV4_IN_IPV6
-       if (to.ss_family == AF_INET6 && 
+       if (to.ss_family == AF_INET6 &&
            IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&to)->sin6_addr))
                return 1;
 #endif
@@ -870,7 +868,7 @@ packet_read_seqnr(u_int32_t *seqnr_p)
                len = read(connection_in, buf, sizeof(buf));
                if (len == 0) {
                        logit("Connection closed by %.200s", get_remote_ipaddr());
-                       fatal_cleanup();
+                       cleanup_exit(255);
                }
                if (len < 0)
                        fatal("Read from socket failed: %.100s", strerror(errno));
@@ -1136,7 +1134,7 @@ packet_read_poll_seqnr(u_int32_t *seqnr_p)
                                logit("Received disconnect from %s: %u: %.400s",
                                    get_remote_ipaddr(), reason, msg);
                                xfree(msg);
-                               fatal_cleanup();
+                               cleanup_exit(255);
                                break;
                        case SSH2_MSG_UNIMPLEMENTED:
                                seqnr = packet_get_int();
@@ -1161,7 +1159,7 @@ packet_read_poll_seqnr(u_int32_t *seqnr_p)
                                msg = packet_get_string(NULL);
                                logit("Received disconnect from %s: %.400s",
                                    get_remote_ipaddr(), msg);
-                               fatal_cleanup();
+                               cleanup_exit(255);
                                xfree(msg);
                                break;
                        default:
@@ -1338,8 +1336,7 @@ packet_disconnect(const char *fmt,...)
 
        /* Close the connection. */
        packet_close();
-
-       fatal_cleanup();
+       cleanup_exit(255);
 }
 
 /* Checks if there is any buffered output, and tries to write some of the output. */
@@ -1406,10 +1403,10 @@ packet_not_very_much_data_to_write(void)
 }
 
 
-#if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN)
 static void
 packet_set_tos(int interactive)
 {
+#if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN)
        int tos = interactive ? IPTOS_LOWDELAY : IPTOS_THROUGHPUT;
 
        if (!packet_connection_is_on_socket() ||
@@ -1419,8 +1416,8 @@ packet_set_tos(int interactive)
            sizeof(tos)) < 0)
                error("setsockopt IP_TOS %d: %.100s:",
                    tos, strerror(errno));
-}
 #endif
+}
 
 /* Informs that the current session is interactive.  Sets IP flags for that. */
 
@@ -1441,10 +1438,7 @@ packet_set_interactive(int interactive)
                return;
        if (interactive)
                set_nodelay(connection_in);
-#if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN)
        packet_set_tos(interactive);
-#endif
-
 }
 
 /* Returns true if the current connection is interactive. */
index c315464ee73aa7fbf1b19b64c9fc8ee1c52ae76f..f42668526c268852c587409b5b2abe2ada974e37 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: progressmeter.c,v 1.15 2003/08/31 12:14:22 markus Exp $");
+RCSID("$OpenBSD: progressmeter.c,v 1.19 2004/02/05 15:33:33 markus Exp $");
 
 #include "progressmeter.h"
 #include "atomicio.h"
@@ -80,7 +80,7 @@ format_rate(char *buf, int size, off_t bytes)
                bytes = (bytes + 512) / 1024;
        }
        snprintf(buf, size, "%3lld.%1lld%c%s",
-           (int64_t) bytes / 100,
+           (int64_t) (bytes + 5) / 100,
            (int64_t) (bytes + 5) / 10 % 10,
            unit[i],
            i ? "B" : " ");
@@ -107,7 +107,7 @@ refresh_progress_meter(void)
        off_t transferred;
        double elapsed;
        int percent;
-       int bytes_left;
+       off_t bytes_left;
        int cur_speed;
        int hours, minutes, seconds;
        int i, len;
@@ -120,14 +120,18 @@ refresh_progress_meter(void)
 
        if (bytes_left > 0)
                elapsed = now - last_update;
-       else
+       else {
                elapsed = now - start;
+               /* Calculate true total speed when done */
+               transferred = end_pos;
+               bytes_per_second = 0;
+       }
 
        /* calculate speed */
        if (elapsed != 0)
                cur_speed = (transferred / elapsed);
        else
-               cur_speed = 0;
+               cur_speed = transferred;
 
 #define AGE_FACTOR 0.9
        if (bytes_per_second != 0) {
@@ -200,7 +204,7 @@ refresh_progress_meter(void)
                        strlcat(buf, "    ", win_size);
        }
 
-       atomicio(vwrite, STDOUT_FILENO, buf, win_size);
+       atomicio(vwrite, STDOUT_FILENO, buf, win_size - 1);
        last_update = now;
 }
 
index 9b46597fb2ebc31e28a51882561915b1fb007e17..b2278e3993b66bad3d1a29bbc1022a3fbdc3058e 100644 (file)
@@ -12,7 +12,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: readconf.c,v 1.121 2003/09/01 18:15:50 markus Exp $");
+RCSID("$OpenBSD: readconf.c,v 1.127 2003/12/16 15:49:51 markus Exp $");
 
 #include "ssh.h"
 #include "xmalloc.h"
@@ -78,7 +78,7 @@ RCSID("$OpenBSD: readconf.c,v 1.121 2003/09/01 18:15:50 markus Exp $");
      RSAAuthentication yes
      RhostsRSAAuthentication yes
      StrictHostKeyChecking yes
-     KeepAlives no
+     TcpKeepAlive no
      IdentityFile ~/.ssh/identity
      Port 22
      EscapeChar ~
@@ -89,14 +89,14 @@ RCSID("$OpenBSD: readconf.c,v 1.121 2003/09/01 18:15:50 markus Exp $");
 
 typedef enum {
        oBadOption,
-       oForwardAgent, oForwardX11, oGatewayPorts,
+       oForwardAgent, oForwardX11, oForwardX11Trusted, oGatewayPorts,
        oPasswordAuthentication, oRSAAuthentication,
        oChallengeResponseAuthentication, oXAuthLocation,
        oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
        oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
        oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
        oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
-       oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts,
+       oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
        oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
        oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
        oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
@@ -105,6 +105,7 @@ typedef enum {
        oClearAllForwardings, oNoHostAuthenticationForLocalhost,
        oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
        oAddressFamily, oGssAuthentication, oGssKeyEx, oGssDelegateCreds,
+       oServerAliveInterval, oServerAliveCountMax,
        oDeprecated, oUnsupported
 } OpCodes;
 
@@ -116,6 +117,7 @@ static struct {
 } keywords[] = {
        { "forwardagent", oForwardAgent },
        { "forwardx11", oForwardX11 },
+       { "forwardx11trusted", oForwardX11Trusted },
        { "xauthlocation", oXAuthLocation },
        { "gatewayports", oGatewayPorts },
        { "useprivilegedport", oUsePrivilegedPort },
@@ -170,7 +172,8 @@ static struct {
        { "stricthostkeychecking", oStrictHostKeyChecking },
        { "compression", oCompression },
        { "compressionlevel", oCompressionLevel },
-       { "keepalive", oKeepAlives },
+       { "tcpkeepalive", oTCPKeepAlive },
+       { "keepalive", oTCPKeepAlive },                         /* obsolete */
        { "numberofpasswordprompts", oNumberOfPasswordPrompts },
        { "loglevel", oLogLevel },
        { "dynamicforward", oDynamicForward },
@@ -184,15 +187,13 @@ static struct {
 #endif
        { "clearallforwardings", oClearAllForwardings },
        { "enablesshkeysign", oEnableSSHKeysign },
-#ifdef DNS
        { "verifyhostkeydns", oVerifyHostKeyDNS },
-#else
-       { "verifyhostkeydns", oUnsupported },
-#endif
        { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
        { "rekeylimit", oRekeyLimit },
        { "connecttimeout", oConnectTimeout },
        { "addressfamily", oAddressFamily },
+       { "serveraliveinterval", oServerAliveInterval },
+       { "serveralivecountmax", oServerAliveCountMax },
        { NULL, oBadOption }
 };
 
@@ -311,7 +312,7 @@ process_config_line(Options *options, const char *host,
                /* NOTREACHED */
        case oConnectTimeout:
                intptr = &options->connection_timeout;
-/* parse_time: */
+parse_time:
                arg = strdelim(&s);
                if (!arg || *arg == '\0')
                        fatal("%s line %d: missing time value.",
@@ -344,6 +345,10 @@ parse_flag:
                intptr = &options->forward_x11;
                goto parse_flag;
 
+       case oForwardX11Trusted:
+               intptr = &options->forward_x11_trusted;
+               goto parse_flag;
+
        case oGatewayPorts:
                intptr = &options->gateway_ports;
                goto parse_flag;
@@ -406,10 +411,11 @@ parse_flag:
 
        case oVerifyHostKeyDNS:
                intptr = &options->verify_host_key_dns;
-               goto parse_flag;
+               goto parse_yesnoask;
 
        case oStrictHostKeyChecking:
                intptr = &options->strict_host_key_checking;
+parse_yesnoask:
                arg = strdelim(&s);
                if (!arg || *arg == '\0')
                        fatal("%.200s line %d: Missing yes/no/ask argument.",
@@ -431,8 +437,8 @@ parse_flag:
                intptr = &options->compression;
                goto parse_flag;
 
-       case oKeepAlives:
-               intptr = &options->keepalives;
+       case oTCPKeepAlive:
+               intptr = &options->tcp_keep_alive;
                goto parse_flag;
 
        case oNoHostAuthenticationForLocalhost:
@@ -736,6 +742,14 @@ parse_int:
                intptr = &options->enable_ssh_keysign;
                goto parse_flag;
 
+       case oServerAliveInterval:
+               intptr = &options->server_alive_interval;
+               goto parse_time;
+
+       case oServerAliveCountMax:
+               intptr = &options->server_alive_count_max;
+               goto parse_int;
+
        case oDeprecated:
                debug("%s line %d: Deprecated option \"%s\"",
                    filename, linenum, keyword);
@@ -812,6 +826,7 @@ initialize_options(Options * options)
        memset(options, 'X', sizeof(*options));
        options->forward_agent = -1;
        options->forward_x11 = -1;
+       options->forward_x11_trusted = -1;
        options->xauth_location = NULL;
        options->gateway_ports = -1;
        options->use_privileged_port = -1;
@@ -830,7 +845,7 @@ initialize_options(Options * options)
        options->check_host_ip = -1;
        options->strict_host_key_checking = -1;
        options->compression = -1;
-       options->keepalives = -1;
+       options->tcp_keep_alive = -1;
        options->compression_level = -1;
        options->port = -1;
        options->address_family = -1;
@@ -863,6 +878,8 @@ initialize_options(Options * options)
        options->no_host_authentication_for_localhost = - 1;
        options->rekey_limit = - 1;
        options->verify_host_key_dns = -1;
+       options->server_alive_interval = -1;
+       options->server_alive_count_max = -1;
 }
 
 /*
@@ -879,6 +896,8 @@ fill_default_options(Options * options)
                options->forward_agent = 0;
        if (options->forward_x11 == -1)
                options->forward_x11 = 0;
+       if (options->forward_x11_trusted == -1)
+               options->forward_x11_trusted = 0;
        if (options->xauth_location == NULL)
                options->xauth_location = _PATH_XAUTH;
        if (options->gateway_ports == -1)
@@ -913,8 +932,8 @@ fill_default_options(Options * options)
                options->strict_host_key_checking = 2;  /* 2 is default */
        if (options->compression == -1)
                options->compression = 0;
-       if (options->keepalives == -1)
-               options->keepalives = 1;
+       if (options->tcp_keep_alive == -1)
+               options->tcp_keep_alive = 1;
        if (options->compression_level == -1)
                options->compression_level = 6;
        if (options->port == -1)
@@ -977,6 +996,10 @@ fill_default_options(Options * options)
                options->rekey_limit = 0;
        if (options->verify_host_key_dns == -1)
                options->verify_host_key_dns = 0;
+       if (options->server_alive_interval == -1)
+               options->server_alive_interval = 0;
+       if (options->server_alive_count_max == -1)
+               options->server_alive_count_max = 3;
        /* options->proxy_command should not be set by default */
        /* options->user will be set in the main program if appropriate */
        /* options->hostname will be set in the main program if appropriate */
index 61e0e3771e24a498fd45bda7e800aed6a6397758..d0ac6713becfe7730e370d42a68ad191d257b151 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: readconf.h,v 1.55 2003/09/01 18:15:50 markus Exp $    */
+/*     $OpenBSD: readconf.h,v 1.59 2003/12/16 15:49:51 markus Exp $    */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -30,6 +30,7 @@ typedef struct {
 typedef struct {
        int     forward_agent;  /* Forward authentication agent. */
        int     forward_x11;    /* Forward X11 display. */
+       int     forward_x11_trusted;    /* Trust Forward X11 display. */
        char   *xauth_location; /* Location for xauth program */
        int     gateway_ports;  /* Allow remote connects to forwarded ports. */
        int     use_privileged_port;    /* Don't use privileged port if false. */
@@ -53,7 +54,7 @@ typedef struct {
        int     compression;    /* Compress packets in both directions. */
        int     compression_level;      /* Compression level 1 (fast) to 9
                                         * (best). */
-       int     keepalives;     /* Set SO_KEEPALIVE. */
+       int     tcp_keep_alive; /* Set SO_KEEPALIVE. */
        LogLevel log_level;     /* Level for logging. */
 
        int     port;           /* Port to connect. */
@@ -61,7 +62,7 @@ typedef struct {
        int     connection_attempts;    /* Max attempts (seconds) before
                                         * giving up */
        int     connection_timeout;     /* Max time (seconds) before
-                                        * aborting connection attempt */
+                                        * aborting connection attempt */
        int     number_of_password_prompts;     /* Max number of password
                                                 * prompts. */
        int     cipher;         /* Cipher to use. */
@@ -102,6 +103,8 @@ typedef struct {
        int     enable_ssh_keysign;
        int     rekey_limit;
        int     no_host_authentication_for_localhost;
+       int     server_alive_interval; 
+       int     server_alive_count_max;
 }       Options;
 
 
index 2489fec457da5f90e2a2b77fe3c3c12d0111e44f..a9b7ebc618151daff0fa1640dd0ff92a03d36317 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2002 Juha Yrjölä.  All rights reserved.
  * Copyright (c) 2001 Markus Friedl.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -81,7 +81,7 @@ sc_close(void)
        }
 }
 
-static int 
+static int
 sc_init(void)
 {
        int r;
@@ -91,7 +91,7 @@ sc_init(void)
                goto err;
        if (sc_reader_id >= ctx->reader_count) {
                r = SC_ERROR_NO_READERS_FOUND;
-               error("Illegal reader number %d (max %d)", sc_reader_id, 
+               error("Illegal reader number %d (max %d)", sc_reader_id,
                    ctx->reader_count -1);
                goto err;
        }
@@ -131,7 +131,7 @@ sc_prkey_op_init(RSA *rsa, struct sc_pkcs15_object **key_obj_out,
                        goto err;
                }
        }
-       r = sc_pkcs15_find_prkey_by_id_usage(p15card, &priv->cert_id, 
+       r = sc_pkcs15_find_prkey_by_id_usage(p15card, &priv->cert_id,
                usage, &key_obj);
        if (r) {
                error("Unable to find private key from SmartCard: %s",
@@ -189,11 +189,11 @@ sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa,
        int r;
 
        if (padding != RSA_PKCS1_PADDING)
-               return -1;      
+               return -1;
        r = sc_prkey_op_init(rsa, &key_obj, SC_USAGE_DECRYPT);
        if (r)
                return -1;
-       r = sc_pkcs15_decipher(p15card, key_obj, SC_ALGORITHM_RSA_PAD_PKCS1, 
+       r = sc_pkcs15_decipher(p15card, key_obj, SC_ALGORITHM_RSA_PAD_PKCS1,
            from, flen, to, flen);
        sc_unlock(card);
        if (r < 0) {
@@ -223,7 +223,7 @@ sc_sign(int type, u_char *m, unsigned int m_len,
         * the key will be rejected as using a non-repudiation key
         * for authentication is not recommended. Note: This does not
         * prevent the use of a non-repudiation key for authentication
-        * if the sign or signrecover flag is set as well. 
+        * if the sign or signrecover flag is set as well.
         */
        r = sc_prkey_op_init(rsa, &key_obj, SC_USAGE_SIGN);
        if (r)
@@ -325,7 +325,7 @@ static void
 convert_rsa_to_rsa1(Key * in, Key * out)
 {
        struct sc_priv_data *priv;
-       
+
        out->rsa->flags = in->rsa->flags;
        out->flags = in->flags;
        RSA_set_method(out->rsa, RSA_get_method(in->rsa));
@@ -337,7 +337,7 @@ convert_rsa_to_rsa1(Key * in, Key * out)
        return;
 }
 
-static int 
+static int
 sc_read_pubkey(Key * k, const struct sc_pkcs15_object *cert_obj)
 {
        int r;
@@ -349,7 +349,7 @@ sc_read_pubkey(Key * k, const struct sc_pkcs15_object *cert_obj)
        EVP_PKEY *pubkey = NULL;
        u8 *p;
        char *tmp;
-       
+
        debug("sc_read_pubkey() with cert id %02X", cinfo->id.value[0]);
        r = sc_pkcs15_read_certificate(p15card, cinfo, &cert);
        if (r) {
@@ -358,7 +358,7 @@ sc_read_pubkey(Key * k, const struct sc_pkcs15_object *cert_obj)
        }
        x509 = X509_new();
        if (x509 == NULL) {
-               r = -1; 
+               r = -1;
                goto err;
        }
        p = cert->data;
@@ -391,7 +391,7 @@ sc_read_pubkey(Key * k, const struct sc_pkcs15_object *cert_obj)
        tmp = key_fingerprint(k, SSH_FP_MD5, SSH_FP_HEX);
        debug("fingerprint %d %s", key_size(k), tmp);
        xfree(tmp);
-       
+
        return 0;
 err:
        if (cert)
index 4ac396e446328a50956d9c5a8bed1b0a3124577c..fb680b91f6227eb8654aa49e4f8292f02ede5772 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: servconf.c,v 1.127 2003/09/01 18:15:50 markus Exp $");
+RCSID("$OpenBSD: servconf.c,v 1.130 2003/12/23 16:12:10 jakob Exp $");
 
 #include "ssh.h"
 #include "log.h"
@@ -61,7 +61,7 @@ initialize_server_options(ServerOptions *options)
        options->x11_use_localhost = -1;
        options->xauth_location = NULL;
        options->strict_modes = -1;
-       options->keepalives = -1;
+       options->tcp_keep_alive = -1;
        options->log_facility = SYSLOG_FACILITY_NOT_SET;
        options->log_level = SYSLOG_LEVEL_NOT_SET;
        options->rhosts_rsa_authentication = -1;
@@ -77,6 +77,7 @@ initialize_server_options(ServerOptions *options)
         options->session_hooks_startup_cmd = NULL;
         options->session_hooks_shutdown_cmd = NULL;
 #endif
+       options->kerberos_get_afs_token = -1;
        options->gss_authentication=-1;
        options->gss_keyex=-1;
        options->gss_use_session_ccache = -1;
@@ -166,8 +167,8 @@ fill_default_server_options(ServerOptions *options)
                options->xauth_location = _PATH_XAUTH;
        if (options->strict_modes == -1)
                options->strict_modes = 1;
-       if (options->keepalives == -1)
-               options->keepalives = 1;
+       if (options->tcp_keep_alive == -1)
+               options->tcp_keep_alive = 1;
        if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
                options->log_facility = SYSLOG_FACILITY_AUTH;
        if (options->log_level == SYSLOG_LEVEL_NOT_SET)
@@ -188,6 +189,8 @@ fill_default_server_options(ServerOptions *options)
                options->kerberos_or_local_passwd = 1;
        if (options->kerberos_ticket_cleanup == -1)
                options->kerberos_ticket_cleanup = 1;
+       if (options->kerberos_get_afs_token == -1)
+               options->kerberos_get_afs_token = 0;
        if (options->gss_authentication == -1)
                options->gss_authentication = 1;
        if (options->gss_keyex == -1)
@@ -261,6 +264,7 @@ typedef enum {
        sPermitRootLogin, sLogFacility, sLogLevel,
        sRhostsRSAAuthentication, sRSAAuthentication,
        sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
+       sKerberosGetAFSToken,
        sKerberosTgtPassing, sChallengeResponseAuthentication,
 #ifdef SESSION_HOOKS
         sAllowSessionHooks, sSessionHookStartupCmd, sSessionHookShutdownCmd,
@@ -268,7 +272,7 @@ typedef enum {
        sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
        sPrintMotd, sPrintLastLog, sIgnoreRhosts,
        sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
-       sStrictModes, sEmptyPasswd, sKeepAlives,
+       sStrictModes, sEmptyPasswd, sTCPKeepAlive,
        sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
        sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
        sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
@@ -315,10 +319,16 @@ static struct {
        { "kerberosauthentication", sKerberosAuthentication },
        { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
        { "kerberosticketcleanup", sKerberosTicketCleanup },
+#ifdef USE_AFS
+       { "kerberosgetafstoken", sKerberosGetAFSToken },
+#else
+       { "kerberosgetafstoken", sUnsupported },
+#endif
 #else
        { "kerberosauthentication", sUnsupported },
        { "kerberosorlocalpasswd", sUnsupported },
        { "kerberosticketcleanup", sUnsupported },
+       { "kerberosgetafstoken", sUnsupported },
 #endif
        { "kerberostgtpassing", sUnsupported },
        { "afstokenpassing", sUnsupported },
@@ -327,13 +337,13 @@ static struct {
        { "gssapikeyexchange", sGssKeyEx },
        { "gssusesessionccache", sGssUseSessionCredCache },
        { "gssapiusesessioncredcache", sGssUseSessionCredCache },
-       { "gssapicleanupcreds", sGssCleanupCreds },
+       { "gssapicleanupcredentials", sGssCleanupCreds },
 #else
        { "gssapiauthentication", sUnsupported },
        { "gssapikeyexchange", sUnsupported },
        { "gssusesessionccache", sUnsupported },
        { "gssapiusesessioncredcache", sUnsupported },
-       { "gssapicleanupcreds", sUnsupported },
+       { "gssapicleanupcredentials", sUnsupported },
 #endif
 #ifdef SESSION_HOOKS
         { "allowsessionhooks", sAllowSessionHooks },
@@ -359,7 +369,8 @@ static struct {
        { "permituserenvironment", sPermitUserEnvironment },
        { "uselogin", sUseLogin },
        { "compression", sCompression },
-       { "keepalive", sKeepAlives },
+       { "tcpkeepalive", sTCPKeepAlive },
+       { "keepalive", sTCPKeepAlive },                         /* obsolete alias */
        { "allowtcpforwarding", sAllowTcpForwarding },
        { "allowusers", sAllowUsers },
        { "denyusers", sDenyUsers },
@@ -654,6 +665,10 @@ parse_flag:
                intptr = &options->kerberos_ticket_cleanup;
                goto parse_flag;
 
+       case sKerberosGetAFSToken:
+               intptr = &options->kerberos_get_afs_token;
+               goto parse_flag;
+
        case sGssAuthentication:
                intptr = &options->gss_authentication;
                goto parse_flag;
@@ -727,8 +742,8 @@ parse_flag:
                intptr = &options->strict_modes;
                goto parse_flag;
 
-       case sKeepAlives:
-               intptr = &options->keepalives;
+       case sTCPKeepAlive:
+               intptr = &options->tcp_keep_alive;
                goto parse_flag;
 
        case sEmptyPasswd:
index c92c0e4cda3c8bd8b4a12e1fe8475b67e02578e0..bc1590da7767a169c2fca1ccbba1b3e6a6ffb5de 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: servconf.h,v 1.65 2003/09/01 18:15:50 markus Exp $    */
+/*     $OpenBSD: servconf.h,v 1.67 2003/12/23 16:12:10 jakob Exp $     */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -58,7 +58,7 @@ typedef struct {
        int     x11_use_localhost;      /* If true, use localhost for fake X11 server. */
        char   *xauth_location; /* Location of xauth program */
        int     strict_modes;   /* If true, require string home dir modes. */
-       int     keepalives;     /* If true, set SO_KEEPALIVE. */
+       int     tcp_keep_alive; /* If true, set SO_KEEPALIVE. */
        char   *ciphers;        /* Supported SSH2 ciphers. */
        char   *macs;           /* Supported SSH2 macs. */
        int     protocol;       /* Supported protocol versions. */
@@ -85,6 +85,8 @@ typedef struct {
         char*   session_hooks_startup_cmd;  /* cmd to be executed before */
         char*   session_hooks_shutdown_cmd; /* cmd to be executed after */
 #endif
+       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;
        int     gss_use_session_ccache;        /* If true, delegated credentials are
index 5be007e65651c9755236b9768a8b8e8a965f81e6..67017b2136ae73e056699e309acd01e180d27174 100644 (file)
@@ -33,7 +33,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: session.c,v 1.164 2003/09/18 08:49:45 markus Exp $");
+RCSID("$OpenBSD: session.c,v 1.172 2004/01/30 09:48:57 markus Exp $");
 
 #include "ssh.h"
 #include "ssh1.h"
@@ -58,6 +58,10 @@ RCSID("$OpenBSD: session.c,v 1.164 2003/09/18 08:49:45 markus Exp $");
 #include "session.h"
 #include "monitor_wrap.h"
 
+#if defined(KRB5) && defined(USE_AFS)
+#include <kafs.h>
+#endif
+
 #ifdef GSSAPI
 #include "ssh-gss.h"
 #endif
@@ -66,7 +70,7 @@ RCSID("$OpenBSD: session.c,v 1.164 2003/09/18 08:49:45 markus Exp $");
 
 Session *session_new(void);
 void   session_set_fds(Session *, int, int, int);
-void   session_pty_cleanup(void *);
+void   session_pty_cleanup(Session *);
 void   session_proctitle(Session *);
 int    session_setup_x11fwd(Session *);
 void   do_exec_pty(Session *, const char *);
@@ -111,6 +115,8 @@ Session     sessions[MAX_SESSIONS];
 login_cap_t *lc;
 #endif
 
+static int is_child = 0;
+
 /* Name and directory of socket for authentication agent forwarding. */
 static char *auth_sock_name = NULL;
 static char *auth_sock_dir = NULL;
@@ -118,10 +124,8 @@ static char *auth_sock_dir = NULL;
 /* removes the agent forwarding socket */
 
 static void
-auth_sock_cleanup_proc(void *_pw)
+auth_sock_cleanup_proc(struct passwd *pw)
 {
-       struct passwd *pw = _pw;
-
        if (auth_sock_name != NULL) {
                temporarily_use_uid(pw);
                unlink(auth_sock_name);
@@ -149,7 +153,7 @@ auth_input_request_forwarding(struct passwd * pw)
        /* Allocate a buffer for the socket name, and format the name. */
        auth_sock_name = xmalloc(MAXPATHLEN);
        auth_sock_dir = xmalloc(MAXPATHLEN);
-       strlcpy(auth_sock_dir, "/tmp/ssh-XXXXXXXX", MAXPATHLEN);
+       strlcpy(auth_sock_dir, "/tmp/ssh-XXXXXXXXXX", MAXPATHLEN);
 
        /* Create private directory for socket */
        if (mkdtemp(auth_sock_dir) == NULL) {
@@ -165,9 +169,6 @@ auth_input_request_forwarding(struct passwd * pw)
        snprintf(auth_sock_name, MAXPATHLEN, "%s/agent.%ld",
                 auth_sock_dir, (long) getpid());
 
-       /* delete agent socket on fatal() */
-       fatal_add_cleanup(auth_sock_cleanup_proc, pw);
-
        /* Create the socket. */
        sock = socket(AF_UNIX, SOCK_STREAM, 0);
        if (sock < 0)
@@ -185,7 +186,7 @@ auth_input_request_forwarding(struct passwd * pw)
        restore_uid();
 
        /* Start listening on the socket. */
-       if (listen(sock, 5) < 0)
+       if (listen(sock, SSH_LISTEN_BACKLOG) < 0)
                packet_disconnect("listen: %.100s", strerror(errno));
 
        /* Allocate a channel for the authentication agent socket. */
@@ -197,6 +198,15 @@ auth_input_request_forwarding(struct passwd * pw)
        return 1;
 }
 
+static void
+display_loginmsg(void)
+{
+       if (buffer_len(&loginmsg) > 0) {
+               buffer_append(&loginmsg, "\0", 1);
+               printf("%s\n", (char *)buffer_ptr(&loginmsg));
+               buffer_clear(&loginmsg);
+       }
+}
 
 void
 do_authenticated(Authctxt *authctxt)
@@ -212,7 +222,6 @@ do_authenticated(Authctxt *authctxt)
                close(startup_pipe);
                startup_pipe = -1;
        }
-
        /* setup the channel layer */
        if (!no_port_forwarding_flag && options.allow_tcp_forwarding)
                channel_permit_all_opens();
@@ -222,9 +231,6 @@ do_authenticated(Authctxt *authctxt)
        else
                do_authenticated1(authctxt);
 
-       /* remove agent socket */
-       if (auth_sock_name != NULL)
-               auth_sock_cleanup_proc(authctxt->pw);
 #ifdef SESSION_HOOKS
         if (options.session_hooks_allow &&
             options.session_hooks_shutdown_cmd)
@@ -243,6 +249,8 @@ do_authenticated(Authctxt *authctxt)
        if (options.kerberos_ticket_cleanup)
                krb5_cleanup_proc(authctxt);
 #endif
+
+       do_cleanup(authctxt);
 }
 
 /*
@@ -363,10 +371,6 @@ do_authenticated1(Authctxt *authctxt)
                        }
                        packet_check_eom();
                        session_close(s);
-#if defined(GSSAPI)
-                       if (options.gss_cleanup_creds)
-                               ssh_gssapi_cleanup_creds(NULL);
-#endif
                        return;
 
                default:
@@ -418,17 +422,13 @@ do_exec_no_pty(Session *s, const char *command)
        session_proctitle(s);
 
 #if defined(USE_PAM)
-       if (options.use_pam) {
+       if (options.use_pam && !use_privsep)
                do_pam_setcred(1);
-               if (is_pam_password_change_required())
-                       packet_disconnect("Password change required but no "
-                           "TTY available");
-       }
 #endif /* USE_PAM */
 
        /* Fork the child. */
        if ((pid = fork()) == 0) {
-               fatal_remove_all_cleanups();
+               is_child = 1;
 
                /* Child.  Reinitialize the log since the pid has changed. */
                log_init(__progname, options.log_level, options.log_facility, log_stderr);
@@ -548,13 +548,14 @@ do_exec_pty(Session *s, const char *command)
 #if defined(USE_PAM)
        if (options.use_pam) {
                do_pam_set_tty(s->tty);
-               do_pam_setcred(1);
+               if (!use_privsep)
+                       do_pam_setcred(1);
        }
 #endif
 
        /* Fork the child. */
        if ((pid = fork()) == 0) {
-               fatal_remove_all_cleanups();
+               is_child = 1;
 
                /* Child.  Reinitialize the log because the pid has changed. */
                log_init(__progname, options.log_level, options.log_facility, log_stderr);
@@ -650,7 +651,7 @@ do_pre_login(Session *s)
                if (getpeername(packet_get_connection_in(),
                    (struct sockaddr *) & from, &fromlen) < 0) {
                        debug("getpeername: %.100s", strerror(errno));
-                       fatal_cleanup();
+                       cleanup_exit(255);
                }
        }
 
@@ -730,7 +731,7 @@ do_login(Session *s, const char *command)
                if (getpeername(packet_get_connection_in(),
                    (struct sockaddr *) & from, &fromlen) < 0) {
                        debug("getpeername: %.100s", strerror(errno));
-                       fatal_cleanup();
+                       cleanup_exit(255);
                }
        }
 
@@ -746,9 +747,10 @@ do_login(Session *s, const char *command)
         * If password change is needed, do it now.
         * This needs to occur before the ~/.hushlogin check.
         */
-       if (options.use_pam && is_pam_password_change_required()) {
-               print_pam_messages();
+       if (options.use_pam && !use_privsep && s->authctxt->force_pwchange) {
+               display_loginmsg();
                do_pam_chauthtok();
+               s->authctxt->force_pwchange = 0;
                /* XXX - signal [net] parent to enable forwardings */
        }
 #endif
@@ -756,17 +758,7 @@ do_login(Session *s, const char *command)
        if (check_quietlogin(s, command))
                return;
 
-#ifdef USE_PAM
-       if (options.use_pam && !is_pam_password_change_required())
-               print_pam_messages();
-#endif /* USE_PAM */
-
-       /* display post-login message */
-       if (buffer_len(&loginmsg) > 0) {
-               buffer_append(&loginmsg, "\0", 1);
-               printf("%s\n", (char *)buffer_ptr(&loginmsg));
-       }
-       buffer_free(&loginmsg);
+       display_loginmsg();
 
 #ifndef NO_SSH_LASTLOG
        if (options.print_lastlog && s->last_login_time != 0) {
@@ -1069,7 +1061,7 @@ read_etc_default_login(char ***env, u_int *envsize, uid_t uid)
 {
        char **tmpenv = NULL, *var;
        u_int i, tmpenvsize = 0;
-       mode_t mask;
+       u_long mask;
 
        /*
         * We don't want to copy the whole file to the child's environment,
@@ -1087,11 +1079,11 @@ read_etc_default_login(char ***env, u_int *envsize, uid_t uid)
                var = child_get_env(tmpenv, "PATH");
        if (var != NULL)
                child_set_env(env, envsize, "PATH", var);
-       
+
        if ((var = child_get_env(tmpenv, "UMASK")) != NULL)
                if (sscanf(var, "%5lo", &mask) == 1)
-                       umask(mask);
-       
+                       umask((mode_t)mask);
+
        for (i = 0; tmpenv[i] != NULL; i++)
                xfree(tmpenv[i]);
        xfree(tmpenv);
@@ -1116,7 +1108,7 @@ void copy_environment(char **source, char ***env, u_int *envsize)
 
                debug3("Copy environment: %s=%s", var_name, var_val);
                child_set_env(env, envsize, var_name, var_val);
-               
+
                xfree(var_name);
        }
 }
@@ -1143,7 +1135,7 @@ do_setup_env(Session *s, const char *shell)
 #endif
 
 #ifdef GSSAPI
-       /* Allow any GSSAPI methods that we've used to alter 
+       /* Allow any GSSAPI methods that we've used to alter
         * the childs environment as they see fit
         */
        ssh_gssapi_do_child(&env, &envsize);
@@ -1178,7 +1170,7 @@ do_setup_env(Session *s, const char *shell)
                path = child_get_env(env, "PATH");
 #  endif /* HAVE_ETC_DEFAULT_LOGIN */
                if (path == NULL || *path == '\0') {
-                       child_set_env(&env, &envsize, "PATH", 
+                       child_set_env(&env, &envsize, "PATH",
                            s->pw->pw_uid == 0 ?
                                SUPERUSER_PATH : _PATH_STDPATH);
                }
@@ -1261,8 +1253,13 @@ do_setup_env(Session *s, const char *shell)
         * been set by PAM.
         */
        if (options.use_pam) {
-               char **p = fetch_pam_environment();
+               char **p;
 
+               p = fetch_pam_child_environment();
+               copy_environment(p, &env, &envsize);
+               free_pam_environment(p);
+
+               p = fetch_pam_environment();
                copy_environment(p, &env, &envsize);
                free_pam_environment(p);
        }
@@ -1335,7 +1332,7 @@ do_rc_files(Session *s, const char *shell)
                if (debug_flag) {
                        fprintf(stderr,
                            "Running %.500s remove %.100s\n",
-                           options.xauth_location, s->auth_display);
+                           options.xauth_location, s->auth_display);
                        fprintf(stderr,
                            "%.500s add %.100s %.100s %.100s\n",
                            options.xauth_location, s->auth_display,
@@ -1401,6 +1398,12 @@ do_setusercontext(struct passwd *pw)
 # ifdef __bsdi__
                setpgid(0, 0);
 # endif
+# ifdef USE_PAM
+               if (options.use_pam) {
+                       do_pam_session();
+                       do_pam_setcred(0);
+               }
+# endif /* USE_PAM */
                if (setusercontext(lc, pw, pw->pw_uid,
                    (LOGIN_SETALL & ~LOGIN_SETPATH)) < 0) {
                        perror("unable to set user context");
@@ -1427,7 +1430,7 @@ do_setusercontext(struct passwd *pw)
                endgrent();
 # ifdef USE_PAM
                /*
-                * PAM credentials may take the form of supplementary groups. 
+                * PAM credentials may take the form of supplementary groups.
                 * These will have been wiped by the above initgroups() call.
                 * Reestablish them here.
                 */
@@ -1454,6 +1457,22 @@ do_setusercontext(struct passwd *pw)
                fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);
 }
 
+static void
+do_pwchange(Session *s)
+{
+       fprintf(stderr, "WARNING: Your password has expired.\n");
+       if (s->ttyfd != -1) {
+               fprintf(stderr,
+                   "You must change your password now and login again!\n");
+               execl(_PATH_PASSWD_PROG, "passwd", (char *)NULL);
+               perror("passwd");
+       } else {
+               fprintf(stderr,
+                   "Password change required but no TTY available.\n");
+       }
+       exit(1);
+}
+
 static void
 launch_login(struct passwd *pw, const char *hostname)
 {
@@ -1475,6 +1494,40 @@ launch_login(struct passwd *pw, const char *hostname)
        exit(1);
 }
 
+static void
+child_close_fds(void)
+{
+       int i;
+
+       if (packet_get_connection_in() == packet_get_connection_out())
+               close(packet_get_connection_in());
+       else {
+               close(packet_get_connection_in());
+               close(packet_get_connection_out());
+       }
+       /*
+        * Close all descriptors related to channels.  They will still remain
+        * open in the parent.
+        */
+       /* XXX better use close-on-exec? -markus */
+       channel_close_all();
+
+       /*
+        * Close any extra file descriptors.  Note that there may still be
+        * descriptors left by system functions.  They will be closed later.
+        */
+       endpwent();
+
+       /*
+        * Close any extra open file descriptors so that we don\'t have them
+        * hanging around in clients.  Note that we want to do this after
+        * initgroups, because at least on Solaris 2.3 it leaves file
+        * descriptors open.
+        */
+       for (i = 3; i < 64; i++)
+               close(i);
+}
+
 /*
  * Performs common processing for the child, such as setting up the
  * environment, closing extra file descriptors, setting the user and group
@@ -1488,7 +1541,6 @@ do_child(Session *s, const char *command)
        char *argv[10];
        const char *shell, *shell0, *hostname = NULL;
        struct passwd *pw = s->pw;
-       u_int i;
 
 #ifdef AFS_KRB5
 /* Default place to look for aklog. */
@@ -1505,6 +1557,14 @@ do_child(Session *s, const char *command)
        /* remove hostkey from the child's memory */
        destroy_sensitive_data();
 
+       /* Force a password change */
+       if (s->authctxt->force_pwchange) {
+               do_setusercontext(pw);
+               child_close_fds();
+               do_pwchange(s);
+               exit(1);
+       }
+
        /* login(1) is only called if we execute the login shell */
        if (options.use_login && command != NULL)
                options.use_login = 0;
@@ -1555,39 +1615,39 @@ do_child(Session *s, const char *command)
         * closed before building the environment, as we call
         * get_remote_ipaddr there.
         */
-       if (packet_get_connection_in() == packet_get_connection_out())
-               close(packet_get_connection_in());
-       else {
-               close(packet_get_connection_in());
-               close(packet_get_connection_out());
-       }
-       /*
-        * Close all descriptors related to channels.  They will still remain
-        * open in the parent.
-        */
-       /* XXX better use close-on-exec? -markus */
-       channel_close_all();
+       child_close_fds();
 
        /*
-        * Close any extra file descriptors.  Note that there may still be
-        * descriptors left by system functions.  They will be closed later.
+        * Must take new environment into use so that .ssh/rc,
+        * /etc/ssh/sshrc and xauth are run in the proper environment.
         */
-       endpwent();
+       environ = env;
 
+#if defined(KRB5) && defined(USE_AFS)
        /*
-        * Close any extra open file descriptors so that we don\'t have them
-        * hanging around in clients.  Note that we want to do this after
-        * initgroups, because at least on Solaris 2.3 it leaves file
-        * descriptors open.
+        * At this point, we check to see if AFS is active and if we have
+        * a valid Kerberos 5 TGT. If so, it seems like a good idea to see
+        * if we can (and need to) extend the ticket into an AFS token. If
+        * we don't do this, we run into potential problems if the user's
+        * home directory is in AFS and it's not world-readable.
         */
-       for (i = 3; i < 64; i++)
-               close(i);
 
-       /*
-        * Must take new environment into use so that .ssh/rc,
-        * /etc/ssh/sshrc and xauth are run in the proper environment.
-        */
-       environ = env;
+       if (options.kerberos_get_afs_token && k_hasafs() &&
+            (s->authctxt->krb5_ctx != NULL)) {
+               char cell[64];
+
+               debug("Getting AFS token");
+
+               k_setpag();
+
+               if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0)
+                       krb5_afslog(s->authctxt->krb5_ctx,
+                           s->authctxt->krb5_fwd_ccache, cell, NULL);
+
+               krb5_afslog_home(s->authctxt->krb5_ctx,
+                   s->authctxt->krb5_fwd_ccache, NULL, NULL, pw->pw_dir);
+       }
+#endif
 
 #ifdef AFS_KRB5
 
@@ -1745,7 +1805,7 @@ session_open(Authctxt *authctxt, int chanid)
        }
        s->authctxt = authctxt;
        s->pw = authctxt->pw;
-       if (s->pw == NULL)
+       if (s->pw == NULL || !authctxt->valid)
                fatal("no user for session %d", s->self);
        debug("session_open: session %d: link with channel %d", s->self, chanid);
        s->chanid = chanid;
@@ -1867,11 +1927,6 @@ session_pty_req(Session *s)
                n_bytes = packet_remaining();
        tty_parse_modes(s->ttyfd, &n_bytes);
 
-       /*
-        * Add a cleanup function to clear the utmp entry and record logout
-        * time in case we call fatal() (e.g., the connection gets closed).
-        */
-       fatal_add_cleanup(session_pty_cleanup, (void *)s);
        if (!use_privsep)
                pty_setowner(s->pw, s->tty);
 
@@ -2053,10 +2108,8 @@ session_set_fds(Session *s, int fdin, int fdout, int fderr)
  * (e.g., due to a dropped connection).
  */
 void
-session_pty_cleanup2(void *session)
+session_pty_cleanup2(Session *s)
 {
-       Session *s = session;
-
        if (s == NULL) {
                error("session_pty_cleanup: no session");
                return;
@@ -2087,9 +2140,9 @@ session_pty_cleanup2(void *session)
 }
 
 void
-session_pty_cleanup(void *session)
+session_pty_cleanup(Session *s)
 {
-       PRIVSEP(session_pty_cleanup2(session));
+       PRIVSEP(session_pty_cleanup2(s));
 }
 
 static char *
@@ -2162,10 +2215,8 @@ void
 session_close(Session *s)
 {
        debug("session_close: session %d pid %ld", s->self, (long)s->pid);
-       if (s->ttyfd != -1) {
-               fatal_remove_cleanup(session_pty_cleanup, (void *)s);
+       if (s->ttyfd != -1)
                session_pty_cleanup(s);
-       }
        if (s->term)
                xfree(s->term);
        if (s->display)
@@ -2214,10 +2265,8 @@ session_close_by_channel(int id, void *arg)
                 * delay detach of session, but release pty, since
                 * the fd's to the child are already closed
                 */
-               if (s->ttyfd != -1) {
-                       fatal_remove_cleanup(session_pty_cleanup, (void *)s);
+               if (s->ttyfd != -1)
                        session_pty_cleanup(s);
-               }
                return;
        }
        /* detach by removing callback */
@@ -2252,13 +2301,13 @@ session_tty_list(void)
        for (i = 0; i < MAX_SESSIONS; i++) {
                Session *s = &sessions[i];
                if (s->used && s->ttyfd != -1) {
-                       
+
                        if (strncmp(s->tty, "/dev/", 5) != 0) {
                                cp = strrchr(s->tty, '/');
                                cp = (cp == NULL) ? s->tty : cp + 1;
                        } else
                                cp = s->tty + 5;
-                       
+
                        if (buf[0] != '\0')
                                strlcat(buf, ",", sizeof buf);
                        strlcat(buf, cp, sizeof buf);
@@ -2358,8 +2407,51 @@ static void
 do_authenticated2(Authctxt *authctxt)
 {
        server_loop2(authctxt);
-#if defined(GSSAPI)
-       if (options.gss_cleanup_creds)
-               ssh_gssapi_cleanup_creds(NULL);
+}
+
+void
+do_cleanup(Authctxt *authctxt)
+{
+       static int called = 0;
+
+       debug("do_cleanup");
+
+       /* no cleanup if we're in the child for login shell */
+       if (is_child)
+               return;
+
+       /* avoid double cleanup */
+       if (called)
+               return;
+       called = 1;
+
+       if (authctxt == NULL)
+               return;
+#ifdef KRB5
+       if (options.kerberos_ticket_cleanup &&
+           authctxt->krb5_ctx)
+               krb5_cleanup_proc(authctxt);
 #endif
+
+#ifdef GSSAPI
+       if (compat20 && options.gss_cleanup_creds)
+               ssh_gssapi_cleanup_creds();
+#endif
+
+#ifdef USE_PAM
+       if (options.use_pam) {
+               sshpam_cleanup();
+               sshpam_thread_cleanup();
+       }
+#endif
+
+       /* remove agent socket */
+       auth_sock_cleanup_proc(authctxt->pw);
+
+       /*
+        * Cleanup ptys/utmp only if privsep is disabled,
+        * or if running in monitor.
+        */
+       if (!use_privsep || mm_is_monitor())
+               session_destroy_all(session_pty_cleanup2);
 }
index 525e47f64ec88bfbc1e02717f97a64360b88eb30..405b8fe8a917dde46916db83580d0350a31381b7 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: session.h,v 1.20 2003/08/22 10:56:09 markus Exp $     */
+/*     $OpenBSD: session.h,v 1.21 2003/09/23 20:17:11 markus Exp $     */
 
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
@@ -56,13 +56,14 @@ struct Session {
 };
 
 void    do_authenticated(Authctxt *);
+void    do_cleanup(Authctxt *);
 
 int     session_open(Authctxt *, int);
 int     session_input_channel_req(Channel *, const char *);
 void    session_close_by_pid(pid_t, int);
 void    session_close_by_channel(int, void *);
 void    session_destroy_all(void (*)(Session *));
-void    session_pty_cleanup2(void *);
+void    session_pty_cleanup2(Session *);
 
 Session        *session_new(void);
 Session        *session_by_tty(char *);
diff --git a/openssh/sftp-glob.h b/openssh/sftp-glob.h
deleted file mode 100644 (file)
index 2885044..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/* $OpenBSD: sftp-glob.h,v 1.5 2001/06/26 17:27:24 markus Exp $ */
-
-/*
- * Copyright (c) 2001 Damien Miller.  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.
- */
-
-/* Remote sftp filename globbing */
-
-int
-remote_glob(int, int, const char *, int, int (*)(const char *, int), glob_t *);
diff --git a/openssh/sftp-int.c b/openssh/sftp-int.c
deleted file mode 100644 (file)
index 841e562..0000000
+++ /dev/null
@@ -1,922 +0,0 @@
-/*
- * Copyright (c) 2001 Damien Miller.  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.
- */
-
-/* XXX: globbed ls */
-/* XXX: recursive operations */
-
-#include "includes.h"
-RCSID("$OpenBSD: sftp-int.c,v 1.40 2001/08/14 09:23:02 markus Exp $");
-
-#include "buffer.h"
-#include "xmalloc.h"
-#include "log.h"
-#include "pathnames.h"
-
-#include "sftp.h"
-#include "sftp-common.h"
-#include "sftp-glob.h"
-#include "sftp-client.h"
-#include "sftp-int.h"
-
-/* File to read commands from */
-extern FILE *infile;
-
-/* Version of server we are speaking to */
-int version;
-
-/* Seperators for interactive commands */
-#define WHITESPACE " \t\r\n"
-
-/* Commands for interactive mode */
-#define I_CHDIR                1
-#define I_CHGRP                2
-#define I_CHMOD                3
-#define I_CHOWN                4
-#define I_GET          5
-#define I_HELP         6
-#define I_LCHDIR       7
-#define I_LLS          8
-#define I_LMKDIR       9
-#define I_LPWD         10
-#define I_LS           11
-#define I_LUMASK       12
-#define I_MKDIR                13
-#define I_PUT          14
-#define I_PWD          15
-#define I_QUIT         16
-#define I_RENAME       17
-#define I_RM           18
-#define I_RMDIR                19
-#define I_SHELL                20
-#define I_SYMLINK      21
-#define I_VERSION      22
-
-struct CMD {
-       const char *c;
-       const int n;
-};
-
-const struct CMD cmds[] = {
-       { "bye",        I_QUIT },
-       { "cd",         I_CHDIR },
-       { "chdir",      I_CHDIR },
-       { "chgrp",      I_CHGRP },
-       { "chmod",      I_CHMOD },
-       { "chown",      I_CHOWN },
-       { "dir",        I_LS },
-       { "exit",       I_QUIT },
-       { "get",        I_GET },
-       { "mget",       I_GET },
-       { "help",       I_HELP },
-       { "lcd",        I_LCHDIR },
-       { "lchdir",     I_LCHDIR },
-       { "lls",        I_LLS },
-       { "lmkdir",     I_LMKDIR },
-       { "ln",         I_SYMLINK },
-       { "lpwd",       I_LPWD },
-       { "ls",         I_LS },
-       { "lumask",     I_LUMASK },
-       { "mkdir",      I_MKDIR },
-       { "put",        I_PUT },
-       { "mput",       I_PUT },
-       { "pwd",        I_PWD },
-       { "quit",       I_QUIT },
-       { "rename",     I_RENAME },
-       { "rm",         I_RM },
-       { "rmdir",      I_RMDIR },
-       { "symlink",    I_SYMLINK },
-       { "version",    I_VERSION },
-       { "!",          I_SHELL },
-       { "?",          I_HELP },
-       { NULL,                 -1}
-};
-
-static void
-help(void)
-{
-       printf("Available commands:\n");
-       printf("cd path                       Change remote directory to 'path'\n");
-       printf("lcd path                      Change local directory to 'path'\n");
-       printf("chgrp grp path                Change group of file 'path' to 'grp'\n");
-       printf("chmod mode path               Change permissions of file 'path' to 'mode'\n");
-       printf("chown own path                Change owner of file 'path' to 'own'\n");
-       printf("help                          Display this help text\n");
-       printf("get remote-path [local-path]  Download file\n");
-       printf("lls [ls-options [path]]       Display local directory listing\n");
-       printf("ln oldpath newpath            Symlink remote file\n");
-       printf("lmkdir path                   Create local directory\n");
-       printf("lpwd                          Print local working directory\n");
-       printf("ls [path]                     Display remote directory listing\n");
-       printf("lumask umask                  Set local umask to 'umask'\n");
-       printf("mkdir path                    Create remote directory\n");
-       printf("put local-path [remote-path]  Upload file\n");
-       printf("pwd                           Display remote working directory\n");
-       printf("exit                          Quit sftp\n");
-       printf("quit                          Quit sftp\n");
-       printf("rename oldpath newpath        Rename remote file\n");
-       printf("rmdir path                    Remove remote directory\n");
-       printf("rm path                       Delete remote file\n");
-       printf("symlink oldpath newpath       Symlink remote file\n");
-       printf("version                       Show SFTP version\n");
-       printf("!command                      Execute 'command' in local shell\n");
-       printf("!                             Escape to local shell\n");
-       printf("?                             Synonym for help\n");
-}
-
-static void
-local_do_shell(const char *args)
-{
-       int status;
-       char *shell;
-       pid_t pid;
-
-       if (!*args)
-               args = NULL;
-
-       if ((shell = getenv("SHELL")) == NULL)
-               shell = _PATH_BSHELL;
-
-       if ((pid = fork()) == -1)
-               fatal("Couldn't fork: %s", strerror(errno));
-
-       if (pid == 0) {
-               /* XXX: child has pipe fds to ssh subproc open - issue? */
-               if (args) {
-                       debug3("Executing %s -c \"%s\"", shell, args);
-                       execl(shell, shell, "-c", args, (char *)NULL);
-               } else {
-                       debug3("Executing %s", shell);
-                       execl(shell, shell, (char *)NULL);
-               }
-               fprintf(stderr, "Couldn't execute \"%s\": %s\n", shell,
-                   strerror(errno));
-               _exit(1);
-       }
-       if (waitpid(pid, &status, 0) == -1)
-               fatal("Couldn't wait for child: %s", strerror(errno));
-       if (!WIFEXITED(status))
-               error("Shell exited abormally");
-       else if (WEXITSTATUS(status))
-               error("Shell exited with status %d", WEXITSTATUS(status));
-}
-
-static void
-local_do_ls(const char *args)
-{
-       if (!args || !*args)
-               local_do_shell(_PATH_LS);
-       else {
-               int len = strlen(_PATH_LS " ") + strlen(args) + 1;
-               char *buf = xmalloc(len);
-
-               /* XXX: quoting - rip quoting code from ftp? */
-               snprintf(buf, len, _PATH_LS " %s", args);
-               local_do_shell(buf);
-               xfree(buf);
-       }
-}
-
-static char *
-path_append(char *p1, char *p2)
-{
-       char *ret;
-       int len = strlen(p1) + strlen(p2) + 2;
-
-       ret = xmalloc(len);
-       strlcpy(ret, p1, len);
-       if (strcmp(p1, "/") != 0) 
-               strlcat(ret, "/", len);
-       strlcat(ret, p2, len);
-
-       return(ret);
-}
-
-static char *
-make_absolute(char *p, char *pwd)
-{
-       char *abs;
-
-       /* Derelativise */
-       if (p && p[0] != '/') {
-               abs = path_append(pwd, p);
-               xfree(p);
-               return(abs);
-       } else
-               return(p);
-}
-
-static int
-infer_path(const char *p, char **ifp)
-{
-       char *cp;
-
-       cp = strrchr(p, '/');
-       if (cp == NULL) {
-               *ifp = xstrdup(p);
-               return(0);
-       }
-
-       if (!cp[1]) {
-               error("Invalid path");
-               return(-1);
-       }
-
-       *ifp = xstrdup(cp + 1);
-       return(0);
-}
-
-static int
-parse_getput_flags(const char **cpp, int *pflag)
-{
-       const char *cp = *cpp;
-
-       /* Check for flags */
-       if (cp[0] == '-' && cp[1] && strchr(WHITESPACE, cp[2])) {
-               switch (cp[1]) {
-               case 'p':
-               case 'P':
-                       *pflag = 1;
-                       break;
-               default:
-                       error("Invalid flag -%c", cp[1]);
-                       return(-1);
-               }
-               cp += 2;
-               *cpp = cp + strspn(cp, WHITESPACE);
-       }
-
-       return(0);
-}
-
-static int
-get_pathname(const char **cpp, char **path)
-{
-       const char *cp = *cpp, *end;
-       char quot;
-       int i;
-
-       cp += strspn(cp, WHITESPACE);
-       if (!*cp) {
-               *cpp = cp;
-               *path = NULL;
-               return (0);
-       }
-
-       /* Check for quoted filenames */
-       if (*cp == '\"' || *cp == '\'') {
-               quot = *cp++;
-
-               end = strchr(cp, quot);
-               if (end == NULL) {
-                       error("Unterminated quote");
-                       goto fail;
-               }
-               if (cp == end) {
-                       error("Empty quotes");
-                       goto fail;
-               }
-               *cpp = end + 1 + strspn(end + 1, WHITESPACE);
-       } else {
-               /* Read to end of filename */
-               end = strpbrk(cp, WHITESPACE);
-               if (end == NULL)
-                       end = strchr(cp, '\0');
-               *cpp = end + strspn(end, WHITESPACE);
-       }
-
-       i = end - cp;
-
-       *path = xmalloc(i + 1);
-       memcpy(*path, cp, i);
-       (*path)[i] = '\0';
-       return(0);
-
- fail:
-       *path = NULL;
-       return (-1);
-}
-
-static int
-is_dir(char *path)
-{
-       struct stat sb;
-
-       /* XXX: report errors? */
-       if (stat(path, &sb) == -1)
-               return(0);
-
-       return(sb.st_mode & S_IFDIR);
-}
-
-static int
-remote_is_dir(int in, int out, char *path)
-{
-       Attrib *a;
-
-       /* XXX: report errors? */
-       if ((a = do_stat(in, out, path, 1)) == NULL)
-               return(0);
-       if (!(a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS))
-               return(0);
-       return(a->perm & S_IFDIR);
-}
-
-static int
-process_get(int in, int out, char *src, char *dst, char *pwd, int pflag)
-{
-       char *abs_src = NULL;
-       char *abs_dst = NULL;
-       char *tmp;
-       glob_t g;
-       int err = 0;
-       int i;
-
-       abs_src = xstrdup(src);
-       abs_src = make_absolute(abs_src, pwd);
-
-       memset(&g, 0, sizeof(g));
-       debug3("Looking up %s", abs_src);
-       if (remote_glob(in, out, abs_src, 0, NULL, &g)) {
-               error("File \"%s\" not found.", abs_src);
-               err = -1;
-               goto out;
-       }
-
-       /* Only one match, dst may be file, directory or unspecified */
-       if (g.gl_pathv[0] && g.gl_matchc == 1) {
-               if (dst) {
-                       /* If directory specified, append filename */
-                       if (is_dir(dst)) {
-                               if (infer_path(g.gl_pathv[0], &tmp)) {
-                                       err = 1;
-                                       goto out;
-                               }
-                               abs_dst = path_append(dst, tmp);
-                               xfree(tmp);
-                       } else
-                               abs_dst = xstrdup(dst);
-               } else if (infer_path(g.gl_pathv[0], &abs_dst)) {
-                       err = -1;
-                       goto out;
-               }
-               printf("Fetching %s to %s\n", g.gl_pathv[0], abs_dst);
-               err = do_download(in, out, g.gl_pathv[0], abs_dst, pflag);
-               goto out;
-       }
-
-       /* Multiple matches, dst may be directory or unspecified */
-       if (dst && !is_dir(dst)) {
-               error("Multiple files match, but \"%s\" is not a directory",
-                   dst);
-               err = -1;
-               goto out;
-       }
-
-       for(i = 0; g.gl_pathv[i]; i++) {
-               if (infer_path(g.gl_pathv[i], &tmp)) {
-                       err = -1;
-                       goto out;
-               }
-               if (dst) {
-                       abs_dst = path_append(dst, tmp);
-                       xfree(tmp);
-               } else
-                       abs_dst = tmp;
-
-               printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst);
-               if (do_download(in, out, g.gl_pathv[i], abs_dst, pflag) == -1)
-                       err = -1;
-               xfree(abs_dst);
-               abs_dst = NULL;
-       }
-
-out:
-       xfree(abs_src);
-       if (abs_dst)
-               xfree(abs_dst);
-       globfree(&g);
-       return(err);
-}
-
-static int
-process_put(int in, int out, char *src, char *dst, char *pwd, int pflag)
-{
-       char *tmp_dst = NULL;
-       char *abs_dst = NULL;
-       char *tmp;
-       glob_t g;
-       int err = 0;
-       int i;
-
-       if (dst) {
-               tmp_dst = xstrdup(dst);
-               tmp_dst = make_absolute(tmp_dst, pwd);
-       }
-
-       memset(&g, 0, sizeof(g));
-       debug3("Looking up %s", src);
-       if (glob(src, 0, NULL, &g)) {
-               error("File \"%s\" not found.", src);
-               err = -1;
-               goto out;
-       }
-
-       /* Only one match, dst may be file, directory or unspecified */
-       if (g.gl_pathv[0] && g.gl_matchc == 1) {
-               if (tmp_dst) {
-                       /* If directory specified, append filename */
-                       if (remote_is_dir(in, out, tmp_dst)) {
-                               if (infer_path(g.gl_pathv[0], &tmp)) {
-                                       err = 1;
-                                       goto out;
-                               }
-                               abs_dst = path_append(tmp_dst, tmp);
-                               xfree(tmp);
-                       } else
-                               abs_dst = xstrdup(tmp_dst);
-               } else {
-                       if (infer_path(g.gl_pathv[0], &abs_dst)) {
-                               err = -1;
-                               goto out;
-                       }
-                       abs_dst = make_absolute(abs_dst, pwd);
-               }
-               printf("Uploading %s to %s\n", g.gl_pathv[0], abs_dst);
-               err = do_upload(in, out, g.gl_pathv[0], abs_dst, pflag);
-               goto out;
-       }
-
-       /* Multiple matches, dst may be directory or unspecified */
-       if (tmp_dst && !remote_is_dir(in, out, tmp_dst)) {
-               error("Multiple files match, but \"%s\" is not a directory",
-                   tmp_dst);
-               err = -1;
-               goto out;
-       }
-
-       for(i = 0; g.gl_pathv[i]; i++) {
-               if (infer_path(g.gl_pathv[i], &tmp)) {
-                       err = -1;
-                       goto out;
-               }
-               if (tmp_dst) {
-                       abs_dst = path_append(tmp_dst, tmp);
-                       xfree(tmp);
-               } else
-                       abs_dst = make_absolute(tmp, pwd);
-
-               printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst);
-               if (do_upload(in, out, g.gl_pathv[i], abs_dst, pflag) == -1)
-                       err = -1;
-       }
-
-out:
-       if (abs_dst)
-               xfree(abs_dst);
-       if (tmp_dst)
-               xfree(tmp_dst);
-       return(err);
-}
-
-static int
-parse_args(const char **cpp, int *pflag, unsigned long *n_arg,
-    char **path1, char **path2)
-{
-       const char *cmd, *cp = *cpp;
-       char *cp2;
-       int base = 0;
-       long l;
-       int i, cmdnum;
-
-       /* Skip leading whitespace */
-       cp = cp + strspn(cp, WHITESPACE);
-
-       /* Ignore blank lines */
-       if (!*cp)
-               return(-1);
-
-       /* Figure out which command we have */
-       for(i = 0; cmds[i].c; i++) {
-               int cmdlen = strlen(cmds[i].c);
-
-               /* Check for command followed by whitespace */
-               if (!strncasecmp(cp, cmds[i].c, cmdlen) &&
-                   strchr(WHITESPACE, cp[cmdlen])) {
-                       cp += cmdlen;
-                       cp = cp + strspn(cp, WHITESPACE);
-                       break;
-               }
-       }
-       cmdnum = cmds[i].n;
-       cmd = cmds[i].c;
-
-       /* Special case */
-       if (*cp == '!') {
-               cp++;
-               cmdnum = I_SHELL;
-       } else if (cmdnum == -1) {
-               error("Invalid command.");
-               return(-1);
-       }
-
-       /* Get arguments and parse flags */
-       *pflag = *n_arg = 0;
-       *path1 = *path2 = NULL;
-       switch (cmdnum) {
-       case I_GET:
-       case I_PUT:
-               if (parse_getput_flags(&cp, pflag))
-                       return(-1);
-               /* Get first pathname (mandatory) */
-               if (get_pathname(&cp, path1))
-                       return(-1);
-               if (*path1 == NULL) {
-                       error("You must specify at least one path after a "
-                           "%s command.", cmd);
-                       return(-1);
-               }
-               /* Try to get second pathname (optional) */
-               if (get_pathname(&cp, path2))
-                       return(-1);
-               break;
-       case I_RENAME:
-       case I_SYMLINK:
-               if (get_pathname(&cp, path1))
-                       return(-1);
-               if (get_pathname(&cp, path2))
-                       return(-1);
-               if (!*path1 || !*path2) {
-                       error("You must specify two paths after a %s "
-                           "command.", cmd);
-                       return(-1);
-               }
-               break;
-       case I_RM:
-       case I_MKDIR:
-       case I_RMDIR:
-       case I_CHDIR:
-       case I_LCHDIR:
-       case I_LMKDIR:
-               /* Get pathname (mandatory) */
-               if (get_pathname(&cp, path1))
-                       return(-1);
-               if (*path1 == NULL) {
-                       error("You must specify a path after a %s command.",
-                           cmd);
-                       return(-1);
-               }
-               break;
-       case I_LS:
-               /* Path is optional */
-               if (get_pathname(&cp, path1))
-                       return(-1);
-               break;
-       case I_LLS:
-       case I_SHELL:
-               /* Uses the rest of the line */
-               break;
-       case I_LUMASK:
-               base = 8;
-       case I_CHMOD:
-               base = 8;
-       case I_CHOWN:
-       case I_CHGRP:
-               /* Get numeric arg (mandatory) */
-               l = strtol(cp, &cp2, base);
-               if (cp2 == cp || ((l == LONG_MIN || l == LONG_MAX) &&
-                   errno == ERANGE) || l < 0) {
-                       error("You must supply a numeric argument "
-                           "to the %s command.", cmd);
-                       return(-1);
-               }
-               cp = cp2;
-               *n_arg = l;
-               if (cmdnum == I_LUMASK && strchr(WHITESPACE, *cp))
-                       break;
-               if (cmdnum == I_LUMASK || !strchr(WHITESPACE, *cp)) {
-                       error("You must supply a numeric argument "
-                           "to the %s command.", cmd);
-                       return(-1);
-               }
-               cp += strspn(cp, WHITESPACE);
-
-               /* Get pathname (mandatory) */
-               if (get_pathname(&cp, path1))
-                       return(-1);
-               if (*path1 == NULL) {
-                       error("You must specify a path after a %s command.",
-                           cmd);
-                       return(-1);
-               }
-               break;
-       case I_QUIT:
-       case I_PWD:
-       case I_LPWD:
-       case I_HELP:
-       case I_VERSION:
-               break;
-       default:
-               fatal("Command not implemented");
-       }
-
-       *cpp = cp;
-       return(cmdnum);
-}
-
-static int
-parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
-{
-       char *path1, *path2, *tmp;
-       int pflag, cmdnum, i;
-       unsigned long n_arg;
-       Attrib a, *aa;
-       char path_buf[MAXPATHLEN];
-       int err = 0;
-       glob_t g;
-
-       path1 = path2 = NULL;
-       cmdnum = parse_args(&cmd, &pflag, &n_arg, &path1, &path2);
-
-       memset(&g, 0, sizeof(g));
-
-       /* Perform command */
-       switch (cmdnum) {
-       case -1:
-               break;
-       case I_GET:
-               err = process_get(in, out, path1, path2, *pwd, pflag);
-               break;
-       case I_PUT:
-               err = process_put(in, out, path1, path2, *pwd, pflag);
-               break;
-       case I_RENAME:
-               path1 = make_absolute(path1, *pwd);
-               path2 = make_absolute(path2, *pwd);
-               err = do_rename(in, out, path1, path2);
-               break;
-       case I_SYMLINK:
-               if (version < 3) {
-                       error("The server (version %d) does not support "
-                           "this operation", version);
-                       err = -1;
-               } else {
-                       path2 = make_absolute(path2, *pwd);
-                       err = do_symlink(in, out, path1, path2);
-               }
-               break;
-       case I_RM:
-               path1 = make_absolute(path1, *pwd);
-               remote_glob(in, out, path1, GLOB_NOCHECK, NULL, &g);
-               for(i = 0; g.gl_pathv[i]; i++) {
-                       printf("Removing %s\n", g.gl_pathv[i]);
-                       if (do_rm(in, out, g.gl_pathv[i]) == -1)
-                               err = -1;
-               }
-               break;
-       case I_MKDIR:
-               path1 = make_absolute(path1, *pwd);
-               attrib_clear(&a);
-               a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
-               a.perm = 0777;
-               err = do_mkdir(in, out, path1, &a);
-               break;
-       case I_RMDIR:
-               path1 = make_absolute(path1, *pwd);
-               err = do_rmdir(in, out, path1);
-               break;
-       case I_CHDIR:
-               path1 = make_absolute(path1, *pwd);
-               if ((tmp = do_realpath(in, out, path1)) == NULL) {
-                       err = 1;
-                       break;
-               }
-               if ((aa = do_stat(in, out, tmp, 0)) == NULL) {
-                       xfree(tmp);
-                       err = 1;
-                       break;
-               }
-               if (!(aa->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) {
-                       error("Can't change directory: Can't check target");
-                       xfree(tmp);
-                       err = 1;
-                       break;
-               }
-               if (!S_ISDIR(aa->perm)) {
-                       error("Can't change directory: \"%s\" is not "
-                           "a directory", tmp);
-                       xfree(tmp);
-                       err = 1;
-                       break;
-               }
-               xfree(*pwd);
-               *pwd = tmp;
-               break;
-       case I_LS:
-               if (!path1) {
-                       do_ls(in, out, *pwd);
-                       break;
-               }
-               path1 = make_absolute(path1, *pwd);
-               if ((tmp = do_realpath(in, out, path1)) == NULL)
-                       break;
-               xfree(path1);
-               path1 = tmp;
-               if ((aa = do_stat(in, out, path1, 0)) == NULL)
-                       break;
-               if ((aa->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) &&
-                   !S_ISDIR(aa->perm)) {
-                       error("Can't ls: \"%s\" is not a directory", path1);
-                       break;
-               }
-               do_ls(in, out, path1);
-               break;
-       case I_LCHDIR:
-               if (chdir(path1) == -1) {
-                       error("Couldn't change local directory to "
-                           "\"%s\": %s", path1, strerror(errno));
-                       err = 1;
-               }
-               break;
-       case I_LMKDIR:
-               if (mkdir(path1, 0777) == -1) {
-                       error("Couldn't create local directory "
-                           "\"%s\": %s", path1, strerror(errno));
-                       err = 1;
-               }
-               break;
-       case I_LLS:
-               local_do_ls(cmd);
-               break;
-       case I_SHELL:
-               local_do_shell(cmd);
-               break;
-       case I_LUMASK:
-               umask(n_arg);
-               printf("Local umask: %03lo\n", n_arg);
-               break;
-       case I_CHMOD:
-               path1 = make_absolute(path1, *pwd);
-               attrib_clear(&a);
-               a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
-               a.perm = n_arg;
-               remote_glob(in, out, path1, GLOB_NOCHECK, NULL, &g);
-               for(i = 0; g.gl_pathv[i]; i++) {
-                       printf("Changing mode on %s\n", g.gl_pathv[i]);
-                       do_setstat(in, out, g.gl_pathv[i], &a);
-               }
-               break;
-       case I_CHOWN:
-               path1 = make_absolute(path1, *pwd);
-               remote_glob(in, out, path1, GLOB_NOCHECK, NULL, &g);
-               for(i = 0; g.gl_pathv[i]; i++) {
-                       if (!(aa = do_stat(in, out, g.gl_pathv[i], 0)))
-                               continue;
-                       if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) {
-                               error("Can't get current ownership of "
-                                   "remote file \"%s\"", g.gl_pathv[i]);
-                               continue;
-                       }
-                       printf("Changing owner on %s\n", g.gl_pathv[i]);
-                       aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
-                       aa->uid = n_arg;
-                       do_setstat(in, out, g.gl_pathv[i], aa);
-               }
-               break;
-       case I_CHGRP:
-               path1 = make_absolute(path1, *pwd);
-               remote_glob(in, out, path1, GLOB_NOCHECK, NULL, &g);
-               for(i = 0; g.gl_pathv[i]; i++) {
-                       if (!(aa = do_stat(in, out, g.gl_pathv[i], 0)))
-                               continue;
-                       if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) {
-                               error("Can't get current ownership of "
-                                   "remote file \"%s\"", g.gl_pathv[i]);
-                               continue;
-                       }
-                       printf("Changing group on %s\n", g.gl_pathv[i]);
-                       aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
-                       aa->gid = n_arg;
-                       do_setstat(in, out, g.gl_pathv[i], aa);
-               }
-               break;
-       case I_PWD:
-               printf("Remote working directory: %s\n", *pwd);
-               break;
-       case I_LPWD:
-               if (!getcwd(path_buf, sizeof(path_buf)))
-                       error("Couldn't get local cwd: %s",
-                           strerror(errno));
-               else
-                       printf("Local working directory: %s\n",
-                           path_buf);
-               break;
-       case I_QUIT:
-               return(-1);
-       case I_HELP:
-               help();
-               break;
-       case I_VERSION:
-               printf("SFTP protocol version %d\n", version);
-               break;
-       default:
-               fatal("%d is not implemented", cmdnum);
-       }
-
-       if (g.gl_pathc)
-               globfree(&g);
-       if (path1)
-               xfree(path1);
-       if (path2)
-               xfree(path2);
-
-       /* If an error occurs in batch mode we should abort. */
-       if (infile != stdin && err > 0)
-               return -1;
-
-       return(0);
-}
-
-void
-interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
-{
-       char *pwd;
-       char *dir = NULL;
-       char cmd[2048];
-
-       version = do_init(fd_in, fd_out);
-       if (version == -1)
-               fatal("Couldn't initialise connection to server");
-
-       pwd = do_realpath(fd_in, fd_out, ".");
-       if (pwd == NULL)
-               fatal("Need cwd");
-
-       if (file1 != NULL) {
-               dir = xstrdup(file1);
-               dir = make_absolute(dir, pwd);
-
-               if (remote_is_dir(fd_in, fd_out, dir) && file2 == NULL) {
-                       printf("Changing to: %s\n", dir);
-                       snprintf(cmd, sizeof cmd, "cd \"%s\"", dir);
-                       parse_dispatch_command(fd_in, fd_out, cmd, &pwd);
-               } else {
-                       if (file2 == NULL)
-                               snprintf(cmd, sizeof cmd, "get %s", dir);
-                       else
-                               snprintf(cmd, sizeof cmd, "get %s %s", dir,
-                                   file2);
-
-                       parse_dispatch_command(fd_in, fd_out, cmd, &pwd);
-                       return;
-               }
-       }
-#if HAVE_SETVBUF
-       setvbuf(stdout, NULL, _IOLBF, 0);
-       setvbuf(infile, NULL, _IOLBF, 0);
-#else
-       setlinebuf(stdout);
-       setlinebuf(infile);
-#endif
-
-       for(;;) {
-               char *cp;
-
-               printf("sftp> ");
-
-               /* XXX: use libedit */
-               if (fgets(cmd, sizeof(cmd), infile) == NULL) {
-                       printf("\n");
-                       break;
-               } else if (infile != stdin) /* Bluff typing */
-                       printf("%s", cmd);
-
-               cp = strrchr(cmd, '\n');
-               if (cp)
-                       *cp = '\0';
-
-               if (parse_dispatch_command(fd_in, fd_out, cmd, &pwd))
-                       break;
-       }
-       xfree(pwd);
-}
diff --git a/openssh/sftp-int.h b/openssh/sftp-int.h
deleted file mode 100644 (file)
index 699e758..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/* $OpenBSD: sftp-int.h,v 1.4 2001/06/26 17:27:25 markus Exp $ */
-
-/*
- * Copyright (c) 2001 Damien Miller.  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.
- */
-
-void    interactive_loop(int, int, char *, char *);
index e1e6cae9b29f268fc7eef5082db78ee0ec5a4c5e..e5232fc9b70a76343f378209a89674e492ed0b5a 100644 (file)
@@ -35,7 +35,7 @@
 
 #include "includes.h"
 #include "openbsd-compat/sys-queue.h"
-RCSID("$OpenBSD: ssh-agent.c,v 1.112 2003/09/18 08:49:45 markus Exp $");
+RCSID("$OpenBSD: ssh-agent.c,v 1.117 2003/12/02 17:01:15 markus Exp $");
 
 #include <openssl/evp.h>
 #include <openssl/md5.h>
@@ -179,7 +179,7 @@ confirm_key(Identity *id)
        p = read_passphrase(prompt, RP_ALLOW_EOF);
        if (p != NULL) {
                /*
-                * Accept empty responses and responses consisting 
+                * Accept empty responses and responses consisting
                 * of the word "yes" as affirmative.
                 */
                if (*p == '\0' || *p == '\n' || strcasecmp(p, "yes") == 0)
@@ -949,7 +949,7 @@ after_select(fd_set *readset, fd_set *writeset)
 }
 
 static void
-cleanup_socket(void *p)
+cleanup_socket(void)
 {
        if (socket_name[0])
                unlink(socket_name);
@@ -957,17 +957,17 @@ cleanup_socket(void *p)
                rmdir(socket_dir);
 }
 
-static void
+void
 cleanup_exit(int i)
 {
-       cleanup_socket(NULL);
-       exit(i);
+       cleanup_socket();
+       _exit(i);
 }
 
 static void
 cleanup_handler(int sig)
 {
-       cleanup_socket(NULL);
+       cleanup_socket();
        _exit(2);
 }
 
@@ -1100,7 +1100,7 @@ main(int ac, char **av)
 
        if (agentsocket == NULL) {
                /* Create private directory for agent socket */
-               strlcpy(socket_dir, "/tmp/ssh-XXXXXXXX", sizeof socket_dir);
+               strlcpy(socket_dir, "/tmp/ssh-XXXXXXXXXX", sizeof socket_dir);
                if (mkdtemp(socket_dir) == NULL) {
                        perror("mkdtemp: private socket dir");
                        exit(1);
@@ -1138,7 +1138,7 @@ main(int ac, char **av)
 #ifdef HAVE_CYGWIN
        umask(prev_mask);
 #endif
-       if (listen(sock, 128) < 0) {
+       if (listen(sock, SSH_LISTEN_BACKLOG) < 0) {
                perror("listen");
                cleanup_exit(1);
        }
@@ -1209,7 +1209,6 @@ main(int ac, char **av)
 #endif
 
 skip:
-       fatal_add_cleanup(cleanup_socket, NULL);
        new_socket(AUTH_SOCKET, sock);
        if (ac > 0) {
                mysignal(SIGALRM, check_parent_exists);
index 08d102ab04b9003e0f811bcab2d26767f114661c..7831e26f2e2b5a16195141dadf899f9ce8d9c533 100644 (file)
@@ -1,3 +1,4 @@
+/*     $OpenBSD: ssh-gss.h,v 1.4 2003/11/17 11:06:07 markus Exp $      */
 /*
  * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
  *
 #include "kex.h"
 #include "buffer.h"
 
+#ifdef HAVE_GSSAPI_H
 #include <gssapi.h>
+#elif defined(HAVE_GSSAPI_GSSAPI_H)
+#include <gssapi/gssapi.h>
+#endif
 
 #ifndef MECHGLUE
 #ifdef KRB5
-#ifndef HEIMDAL
-#include <gssapi_generic.h>
+# ifndef HEIMDAL
+#  ifdef HAVE_GSSAPI_GENERIC_H
+#   include <gssapi_generic.h>
+#  elif defined(HAVE_GSSAPI_GSSAPI_GENERIC_H)
+#   include <gssapi/gssapi_generic.h>
+#  endif
 
 /* MIT Kerberos doesn't seem to define GSS_NT_HOSTBASED_SERVICE */
 
@@ -57,6 +66,7 @@
 #define SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE     63
 #define SSH2_MSG_USERAUTH_GSSAPI_ERROR                 64
 #define SSH2_MSG_USERAUTH_GSSAPI_ERRTOK                        65
+#define SSH2_MSG_USERAUTH_GSSAPI_MIC                   66
 
 #define SSH_GSS_OIDTYPE 0x06
 
@@ -120,7 +130,9 @@ void ssh_gssapi_error(Gssctxt *ctx);
 char *ssh_gssapi_last_error(Gssctxt *ctxt, OM_uint32 *maj, OM_uint32 *min);
 void ssh_gssapi_build_ctx(Gssctxt **ctx);
 void ssh_gssapi_delete_ctx(Gssctxt **ctx);
+OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t);
 OM_uint32 ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid);
+void ssh_gssapi_buildmic(Buffer *, const char *, const char *, const char *);
 
 int ssh_gssapi_check_mechanism(gss_OID oid, char *host);
 
@@ -128,14 +140,9 @@ int ssh_gssapi_check_mechanism(gss_OID oid, char *host);
 gss_OID ssh_gssapi_server_id_kex(char *name);
 int ssh_gssapi_userok(char *name);
 int ssh_gssapi_localname(char **name);
-void ssh_gssapi_server(Kex *kex, Buffer *client_kexinit, 
-                      Buffer *server_kexinit);
-
-OM_uint32 ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *buffer, 
-                                       gss_buffer_desc *hash);
-
+OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t);
 void ssh_gssapi_do_child(char ***envp, u_int *envsizep);
-void ssh_gssapi_cleanup_creds(void *ignored);
+void ssh_gssapi_cleanup_creds(void);
 void ssh_gssapi_storecreds(void);
 char *ssh_gssapi_server_mechanisms();
 
index 9fa8aaebcab9a0b4a8794f374daf2dc2d2a39536..68b6a0ad1c98d1371c1dd0997c4d4a402daa35ef 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: ssh-keyscan.c,v 1.44 2003/06/28 16:23:06 deraadt Exp $");
+RCSID("$OpenBSD: ssh-keyscan.c,v 1.46 2003/11/23 23:17:34 djm Exp $");
 
 #include "openbsd-compat/sys-queue.h"
 
@@ -214,13 +214,11 @@ fdlim_get(int hard)
        if (getrlimit(RLIMIT_NOFILE, &rlfd) < 0)
                return (-1);
        if ((hard ? rlfd.rlim_max : rlfd.rlim_cur) == RLIM_INFINITY)
-               return 10000;
+               return SSH_SYSFDMAX;
        else
                return hard ? rlfd.rlim_max : rlfd.rlim_cur;
-#elif defined (HAVE_SYSCONF)
-       return sysconf (_SC_OPEN_MAX);
 #else
-       return 10000;
+       return SSH_SYSFDMAX;
 #endif
 }
 
@@ -675,7 +673,7 @@ fatal(const char *fmt,...)
        if (nonfatal_fatal)
                longjmp(kexjmp, -1);
        else
-               fatal_cleanup();
+               exit(255);
 }
 
 static void
index c7ca5c4e40094d35c5cf82fa4e291086a6c71d9f..9e9ebe2f1717328db9c2d7ceaa6d5bd844e275be 100644 (file)
@@ -22,7 +22,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include "includes.h"
-RCSID("$OpenBSD: ssh-keysign.c,v 1.13 2003/07/03 08:09:06 djm Exp $");
+RCSID("$OpenBSD: ssh-keysign.c,v 1.15 2004/01/19 21:25:15 markus Exp $");
 
 #include <openssl/evp.h>
 #include <openssl/rand.h>
@@ -126,6 +126,7 @@ valid_request(struct passwd *pw, char *host, Key **ret, u_char *data,
        /* end of message */
        if (buffer_len(&b) != 0)
                fail++;
+       buffer_free(&b);
 
        debug3("valid_request: fail %d", fail);
 
@@ -233,7 +234,8 @@ main(int argc, char **argv)
        /* send reply */
        buffer_clear(&b);
        buffer_put_string(&b, signature, slen);
-       ssh_msg_send(STDOUT_FILENO, version, &b);
+       if (ssh_msg_send(STDOUT_FILENO, version, &b) == -1)
+               fatal("ssh_msg_send failed");
 
        return (0);
 }
index bcf542eda864b6962d208dfcf829c6b1854785dc..59c1e0b3d0643a22d8a129b4d505503d0acc6678 100644 (file)
 .Op Fl b Ar bytes
 .Sh DESCRIPTION
 .Nm
-is a small helper program used by 
+is a small helper program used by
 .Xr ssh 1 ,
 .Xr ssh-add 1 ,
 .Xr ssh-agent 1 ,
 .Xr ssh-keygen 1 ,
-.Xr ssh-keyscan 1 
+.Xr ssh-keyscan 1
 and
 .Xr sshd 8
-to gather random numbers of cryptographic quality if the 
+to gather random numbers of cryptographic quality if the
 .Xr openssl 4
 library has not been configured to provide them itself.
 .Pp
-Normally 
+Normally
 .Nm
 will generate a strong random seed and provide it to the calling
-program via standard output. If standard output is a tty, 
+program via standard output. If standard output is a tty,
 .Nm
 will instead print the seed in hexidecimal format unless told otherwise.
 .Pp
@@ -57,19 +57,19 @@ will instead print the seed in hexidecimal format unless told otherwise.
 will by default gather random numbers from the system commands listed
 in
 .Pa /etc/ssh/ssh_prng_cmds .
-The output of each of the commands listed will be hashed and used to 
-generate a random seed for the calling program. 
+The output of each of the commands listed will be hashed and used to
+generate a random seed for the calling program.
 .Nm
-will also store seed files in 
+will also store seed files in
 .Pa ~/.ssh/prng_seed
 between executions.
 .Pp
-Alternately, 
+Alternately,
 .Nm
-may be configured at build time to collect random numbers from a 
+may be configured at build time to collect random numbers from a
 EGD/PRNGd server via a unix domain or localhost tcp socket.
 .Pp
-This program is not intended to be run by the end-user, so the few 
+This program is not intended to be run by the end-user, so the few
 commandline options are for debugging purposes only.
 .Bl -tag -width Ds
 .It Fl b Ar bytes
index 79f78d980b27df7c42cc228b724b091f97e0f9cc..9c9c49560c4c89e94a2b7210026898cdcc457437 100644 (file)
@@ -115,19 +115,19 @@ double stir_gettimeofday(double entropy_estimate);
 double stir_clock(double entropy_estimate);
 double stir_rusage(int who, double entropy_estimate);
 double hash_command_output(entropy_cmd_t *src, unsigned char *hash);
-int get_random_bytes_prngd(unsigned char *buf, int len, 
+int get_random_bytes_prngd(unsigned char *buf, int len,
     unsigned short tcp_port, char *socket_path);
 
 /*
  * Collect 'len' bytes of entropy into 'buf' from PRNGD/EGD daemon
  * listening either on 'tcp_port', or via Unix domain socket at *
  * 'socket_path'.
- * Either a non-zero tcp_port or a non-null socket_path must be 
+ * Either a non-zero tcp_port or a non-null socket_path must be
  * supplied.
  * Returns 0 on success, -1 on error
  */
 int
-get_random_bytes_prngd(unsigned char *buf, int len, 
+get_random_bytes_prngd(unsigned char *buf, int len,
     unsigned short tcp_port, char *socket_path)
 {
        int fd, addr_len, rval, errors;
@@ -289,7 +289,7 @@ hash_command_output(entropy_cmd_t *src, unsigned char *hash)
        if (devnull == -1) {
                devnull = open("/dev/null", O_RDWR);
                if (devnull == -1)
-                       fatal("Couldn't open /dev/null: %s", 
+                       fatal("Couldn't open /dev/null: %s",
                            strerror(errno));
        }
 
@@ -314,7 +314,7 @@ hash_command_output(entropy_cmd_t *src, unsigned char *hash)
 
                        execv(src->path, (char**)(src->args));
 
-                       debug("(child) Couldn't exec '%s': %s", 
+                       debug("(child) Couldn't exec '%s': %s",
                            src->cmdstring, strerror(errno));
                        _exit(-1);
                default: /* Parent */
@@ -376,7 +376,7 @@ hash_command_output(entropy_cmd_t *src, unsigned char *hash)
                case -1:
                default:
                        /* error */
-                       debug("Command '%s': select() failed: %s", 
+                       debug("Command '%s': select() failed: %s",
                            src->cmdstring, strerror(errno));
                        error_abort = 1;
                        break;
@@ -400,8 +400,8 @@ hash_command_output(entropy_cmd_t *src, unsigned char *hash)
        if (error_abort) {
                /*
                 * Closing p[0] on timeout causes the entropy command to
-                * SIGPIPE. Take whatever output we got, and mark this 
-                * command as slow 
+                * SIGPIPE. Take whatever output we got, and mark this
+                * command as slow
                 */
                debug2("Command '%s' timed out", src->cmdstring);
                src->sticky_badness *= 2;
@@ -479,7 +479,7 @@ stir_from_programs(void)
                        /* Stir it in */
                        RAND_add(hash, sizeof(hash), entropy);
 
-                       debug3("Got %0.2f bytes of entropy from '%s'", 
+                       debug3("Got %0.2f bytes of entropy from '%s'",
                            entropy, entropy_cmds[c].cmdstring);
 
                        total_entropy += entropy;
@@ -491,7 +491,7 @@ stir_from_programs(void)
                        total_entropy += stir_rusage(RUSAGE_CHILDREN, 0.1);
                } else {
                        debug2("Command '%s' disabled (badness %d)",
-                           entropy_cmds[c].cmdstring, 
+                           entropy_cmds[c].cmdstring,
                            entropy_cmds[c].badness);
 
                        if (entropy_cmds[c].badness > 0)
@@ -511,8 +511,8 @@ prng_check_seedfile(char *filename)
        struct stat st;
 
        /*
-        * XXX raceable: eg replace seed between this stat and subsequent 
-        * open. Not such a problem because we don't really trust the 
+        * XXX raceable: eg replace seed between this stat and subsequent
+        * open. Not such a problem because we don't really trust the
         * seed file anyway.
         * XXX: use secure path checking as elsewhere in OpenSSH
         */
@@ -563,7 +563,7 @@ prng_write_seedfile(void)
        debug("writing PRNG seed to file %.100s", filename);
 
        if (RAND_bytes(seed, sizeof(seed)) <= 0)
-               fatal("PRNG seed extration failed");
+               fatal("PRNG seed extraction failed");
 
        /* Don't care if the seed doesn't exist */
        prng_check_seedfile(filename);
@@ -651,7 +651,7 @@ prng_read_commands(char *cmdfilename)
                        continue; /* done with this line */
 
                /*
-                * The first non-whitespace char should be a double quote 
+                * The first non-whitespace char should be a double quote
                 * delimiting the commandline
                 */
                if (*cp != '"') {
@@ -726,7 +726,7 @@ prng_read_commands(char *cmdfilename)
 
                /*
                 * If we've filled the array, reallocate it twice the size
-                * Do this now because even if this we're on the last 
+                * Do this now because even if this we're on the last
                 * command we need another slot to mark the last entry
                 */
                if (cur_cmd == num_cmds) {
@@ -761,7 +761,7 @@ usage(void)
            OUTPUT_SEED_SIZE);
 }
 
-int 
+int
 main(int argc, char **argv)
 {
        unsigned char *buf;
@@ -779,7 +779,7 @@ main(int argc, char **argv)
        /* Don't write binary data to a tty, unless we are forced to */
        if (isatty(STDOUT_FILENO))
                output_hex = 1;
-       
+
        while ((ch = getopt(argc, argv, "vxXhb:")) != -1) {
                switch (ch) {
                case 'v':
@@ -806,7 +806,7 @@ main(int argc, char **argv)
        }
 
        log_init(argv[0], ll, SYSLOG_FACILITY_USER, 1);
-       
+
 #ifdef USE_SEED_FILES
        prng_read_seedfile();
 #endif
@@ -816,11 +816,11 @@ main(int argc, char **argv)
        /*
         * Seed the RNG from wherever we can
         */
-        
+
        /* Take whatever is on the stack, but don't credit it */
        RAND_add(buf, bytes, 0);
 
-       debug("Seeded RNG with %i bytes from system calls", 
+       debug("Seeded RNG with %i bytes from system calls",
            (int)stir_from_system());
 
 #ifdef PRNGD_PORT
@@ -835,7 +835,7 @@ main(int argc, char **argv)
        /* Read in collection commands */
        if (prng_read_commands(SSH_PRNG_COMMAND_FILE) == -1)
                fatal("PRNG initialisation failed -- exiting.");
-       debug("Seeded RNG with %i bytes from programs", 
+       debug("Seeded RNG with %i bytes from programs",
            (int)stir_from_programs());
 #endif
 
@@ -859,9 +859,9 @@ main(int argc, char **argv)
                printf("\n");
        } else
                ret = atomicio(vwrite, STDOUT_FILENO, buf, bytes);
-               
+
        memset(buf, '\0', bytes);
        xfree(buf);
-       
+
        return ret == bytes ? 0 : 1;
 }
index c81cb42c67f829dfafcc5ca977755528c7584d6a..e2cd5d343877ea31f767a3e7f7c2da22ec765f32 100644 (file)
@@ -34,7 +34,7 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.\" $OpenBSD: ssh.1,v 1.175 2003/07/22 13:35:22 markus Exp $
+.\" $OpenBSD: ssh.1,v 1.181 2003/12/16 15:49:51 markus Exp $
 .Dd September 25, 1999
 .Dt SSH 1
 .Os
 .Nd OpenSSH SSH client (remote login program)
 .Sh SYNOPSIS
 .Nm ssh
-.Op Fl l Ar login_name
-.Ar hostname | user@hostname
-.Op Ar command
-.Pp
-.Nm ssh
-.Bk -words
-.Op Fl afgknqstvxACNTVX1246
+.Op Fl 1246AaCfgkNnqsTtVvXxY
 .Op Fl b Ar bind_address
 .Op Fl c Ar cipher_spec
+.Op Fl D Ar port
 .Op Fl e Ar escape_char
-.Op Fl i Ar identity_file
-.Op Fl l Ar login_name
-.Op Fl m Ar mac_spec
-.Op Fl o Ar option
-.Op Fl p Ar port
 .Op Fl F Ar configfile
+.Op Fl i Ar identity_file
+.Bk -words
 .Oo Fl L Xo
 .Sm off
 .Ar port :
 .Xc
 .Oc
 .Ek
+.Op Fl l Ar login_name
+.Op Fl m Ar mac_spec
+.Op Fl o Ar option
 .Bk -words
+.Op Fl p Ar port
+.Ek
 .Oo Fl R Xo
 .Sm off
 .Ar port :
 .Sm on
 .Xc
 .Oc
-.Op Fl D Ar port
-.Ar hostname | user@hostname
+.Oo Ar user Ns @ Oc Ns Ar hostname
 .Op Ar command
-.Ek
 .Sh DESCRIPTION
 .Nm
 (SSH client) is a program for logging into a remote machine and for
 executing commands on a remote machine.
-It is intended to replace
-rlogin and rsh, and provide secure encrypted communications between
+It is intended to replace rlogin and rsh,
+and provide secure encrypted communications between
 two untrusted hosts over an insecure network.
-X11 connections and
-arbitrary TCP/IP ports can also be forwarded over the secure channel.
+X11 connections and arbitrary TCP/IP ports
+can also be forwarded over the secure channel.
 .Pp
 .Nm
 connects and logs into the specified
-.Ar hostname .
+.Ar hostname
+(with optional
+.Ar user
+name).
 The user must prove
 his/her identity to the remote machine using one of several methods
-depending on the protocol version used:
+depending on the protocol version used.
 .Pp
+If
+.Ar command
+is specified,
+.Ar command
+is executed on the remote host instead of a login shell.
 .Ss SSH protocol version 1
-.Pp
 First, if the machine the user logs in from is listed in
 .Pa /etc/hosts.equiv
 or
@@ -107,9 +109,9 @@ or
 on the remote machine, and the user names are
 the same on both sides, the user is immediately permitted to log in.
 Second, if
-.Pa \&.rhosts
+.Pa .rhosts
 or
-.Pa \&.shosts
+.Pa .shosts
 exists in the user's home directory on the
 remote machine and contains a line containing the name of the client
 machine and the name of the user on that machine, the user is
@@ -118,9 +120,9 @@ This form of authentication alone is normally not
 allowed by the server because it is not secure.
 .Pp
 The second authentication method is the
-.Pa rhosts
+.Em rhosts
 or
-.Pa hosts.equiv
+.Em hosts.equiv
 method combined with RSA-based host authentication.
 It means that if the login would be permitted by
 .Pa $HOME/.rhosts ,
@@ -135,7 +137,7 @@ and
 .Pa $HOME/.ssh/known_hosts
 in the
 .Sx FILES
-section), only then login is permitted.
+section), only then is login permitted.
 This authentication method closes security holes due to IP
 spoofing, DNS spoofing and routing spoofing.
 [Note to the administrator:
@@ -154,24 +156,23 @@ RSA is one such system.
 The idea is that each user creates a public/private
 key pair for authentication purposes.
 The server knows the public key, and only the user knows the private key.
+.Pp
 The file
 .Pa $HOME/.ssh/authorized_keys
-lists the public keys that are permitted for logging
-in.
+lists the public keys that are permitted for logging in.
 When the user logs in, the
 .Nm
 program tells the server which key pair it would like to use for
 authentication.
-The server checks if this key is permitted, and if
-so, sends the user (actually the
+The server checks if this key is permitted, and if so,
+sends the user (actually the
 .Nm
 program running on behalf of the user) a challenge, a random number,
 encrypted by the user's public key.
-The challenge can only be
-decrypted using the proper private key.
-The user's client then decrypts the
-challenge using the private key, proving that he/she knows the private
-key but without disclosing it to the server.
+The challenge can only be decrypted using the proper private key.
+The user's client then decrypts the challenge using the private key,
+proving that he/she knows the private key
+but without disclosing it to the server.
 .Pp
 .Nm
 implements the RSA authentication protocol automatically.
@@ -179,7 +180,7 @@ The user creates his/her RSA key pair by running
 .Xr ssh-keygen 1 .
 This stores the private key in
 .Pa $HOME/.ssh/identity
-and the public key in
+and stores the public key in
 .Pa $HOME/.ssh/identity.pub
 in the user's home directory.
 The user should then copy the
@@ -193,8 +194,9 @@ file corresponds to the conventional
 file, and has one key
 per line, though the lines can be very long).
 After this, the user can log in without giving the password.
-RSA authentication is much
-more secure than rhosts authentication.
+RSA authentication is much more secure than
+.Em rhosts
+authentication.
 .Pp
 The most convenient way to use RSA authentication may be with an
 authentication agent.
@@ -208,16 +210,14 @@ prompts the user for a password.
 The password is sent to the remote
 host for checking; however, since all communications are encrypted,
 the password cannot be seen by someone listening on the network.
-.Pp
 .Ss SSH protocol version 2
-.Pp
-When a user connects using protocol version 2
+When a user connects using protocol version 2,
 similar authentication methods are available.
 Using the default values for
 .Cm PreferredAuthentications ,
 the client will try to authenticate first using the hostbased method;
-if this method fails public key authentication is attempted,
-and finally if this method fails keyboard-interactive and
+if this method fails, public key authentication is attempted,
+and finally if this method fails, keyboard-interactive and
 password authentication are tried.
 .Pp
 The public key method is similar to RSA authentication described
@@ -233,8 +233,8 @@ and grants access if both the key is found and the signature is correct.
 The session identifier is derived from a shared Diffie-Hellman value
 and is only known to the client and the server.
 .Pp
-If public key authentication fails or is not available a password
-can be sent encrypted to the remote host for proving the user's identity.
+If public key authentication fails or is not available, a password
+can be sent encrypted to the remote host to prove the user's identity.
 .Pp
 Additionally,
 .Nm
@@ -245,9 +245,7 @@ Protocol 2 provides additional mechanisms for confidentiality
 and integrity (hmac-md5, hmac-sha1).
 Note that protocol 1 lacks a strong mechanism for ensuring the
 integrity of the connection.
-.Pp
 .Ss Login session and remote execution
-.Pp
 When the user's identity has been accepted by the server, the server
 either executes the given command, or logs into the machine and gives
 the user a normal shell on the remote machine.
@@ -257,23 +255,20 @@ the remote command or shell will be automatically encrypted.
 If a pseudo-terminal has been allocated (normal login session), the
 user may use the escape characters noted below.
 .Pp
-If no pseudo tty has been allocated, the
-session is transparent and can be used to reliably transfer binary
-data.
+If no pseudo-tty has been allocated,
+the session is transparent and can be used to reliably transfer binary data.
 On most systems, setting the escape character to
 .Dq none
 will also make the session transparent even if a tty is used.
 .Pp
 The session terminates when the command or shell on the remote
 machine exits and all X11 and TCP/IP connections have been closed.
-The exit status of the remote program is returned as the exit status
-of
+The exit status of the remote program is returned as the exit status of
 .Nm ssh .
-.Pp
 .Ss Escape Characters
-.Pp
-When a pseudo terminal has been requested, ssh supports a number of functions
-through the use of an escape character.
+When a pseudo-terminal has been requested,
+.Nm
+supports a number of functions through the use of an escape character.
 .Pp
 A single tilde character can be sent as
 .Ic ~~
@@ -291,37 +286,37 @@ The supported escapes (assuming the default
 are:
 .Bl -tag -width Ds
 .It Cm ~.
-Disconnect
+Disconnect.
 .It Cm ~^Z
-Background ssh
+Background
+.Nm ssh .
 .It Cm ~#
-List forwarded connections
+List forwarded connections.
 .It Cm ~&
-Background ssh at logout when waiting for forwarded connection / X11 sessions
-to terminate
+Background
+.Nm
+at logout when waiting for forwarded connection / X11 sessions to terminate.
 .It Cm ~?
-Display a list of escape characters
+Display a list of escape characters.
 .It Cm ~B
-Send a BREAK to the remote system (only useful for SSH protocol version 2
-and if the peer supports it)
+Send a BREAK to the remote system
+(only useful for SSH protocol version 2 and if the peer supports it).
 .It Cm ~C
 Open command line (only useful for adding port forwardings using the
 .Fl L
 and
 .Fl R
-options)
+options).
 .It Cm ~R
-Request rekeying of the connection (only useful for SSH protocol version 2
-and if the peer supports it)
+Request rekeying of the connection
+(only useful for SSH protocol version 2 and if the peer supports it).
 .El
-.Pp
 .Ss X11 and TCP forwarding
-.Pp
 If the
 .Cm ForwardX11
 variable is set to
 .Dq yes
-(or, see the description of the
+(or see the description of the
 .Fl X
 and
 .Fl x
@@ -342,8 +337,7 @@ The
 .Ev DISPLAY
 value set by
 .Nm
-will point to the server machine, but with a display number greater
-than zero.
+will point to the server machine, but with a display number greater than zero.
 This is normal, and happens because
 .Nm
 creates a
@@ -364,7 +358,7 @@ If the
 .Cm ForwardAgent
 variable is set to
 .Dq yes
-(or, see the description of the
+(or see the description of the
 .Fl A
 and
 .Fl a
@@ -376,9 +370,7 @@ Forwarding of arbitrary TCP/IP connections over the secure channel can
 be specified either on the command line or in a configuration file.
 One possible application of TCP/IP forwarding is a secure connection to an
 electronic purse; another is going through firewalls.
-.Pp
 .Ss Server authentication
-.Pp
 .Nm
 automatically maintains and checks a database containing
 identifications for all hosts it has ever been used with.
@@ -389,14 +381,12 @@ Additionally, the file
 .Pa /etc/ssh/ssh_known_hosts
 is automatically checked for known hosts.
 Any new hosts are automatically added to the user's file.
-If a host's identification
-ever changes,
+If a host's identification ever changes,
 .Nm
 warns about this and disables password authentication to prevent a
 trojan horse from getting the user's password.
-Another purpose of
-this mechanism is to prevent man-in-the-middle attacks which could
-otherwise be used to circumvent the encryption.
+Another purpose of this mechanism is to prevent man-in-the-middle attacks
+which could otherwise be used to circumvent the encryption.
 The
 .Cm StrictHostKeyChecking
 option can be used to prevent logins to machines whose
@@ -404,8 +394,22 @@ host key is not known or has changed.
 .Pp
 The options are as follows:
 .Bl -tag -width Ds
-.It Fl a
-Disables forwarding of the authentication agent connection.
+.It Fl 1
+Forces
+.Nm
+to try protocol version 1 only.
+.It Fl 2
+Forces
+.Nm
+to try protocol version 2 only.
+.It Fl 4
+Forces
+.Nm
+to use IPv4 addresses only.
+.It Fl 6
+Forces
+.Nm
+to use IPv6 addresses only.
 .It Fl A
 Enables forwarding of the authentication agent connection.
 This can also be specified on a per-host basis in a configuration file.
@@ -417,10 +421,28 @@ can access the local agent through the forwarded connection.
 An attacker cannot obtain key material from the agent,
 however they can perform operations on the keys that enable them to
 authenticate using the identities loaded into the agent.
+.It Fl a
+Disables forwarding of the authentication agent connection.
 .It Fl b Ar bind_address
 Specify the interface to transmit from on machines with multiple
 interfaces or aliased addresses.
-.It Fl c Ar blowfish|3des|des
+.It Fl C
+Requests compression of all data (including stdin, stdout, stderr, and
+data for forwarded X11 and TCP/IP connections).
+The compression algorithm is the same used by
+.Xr gzip 1 ,
+and the
+.Dq level
+can be controlled by the
+.Cm CompressionLevel
+option for protocol version 1.
+Compression is desirable on modem lines and other
+slow connections, but will only slow down things on fast networks.
+The default value can be set on a host-by-host basis in the
+configuration files; see the
+.Cm Compression
+option.
+.It Fl c Ar blowfish | 3des | des
 Selects the cipher to use for encrypting the session.
 .Ar 3des
 is used by default.
@@ -428,7 +450,7 @@ It is believed to be secure.
 .Ar 3des
 (triple-des) is an encrypt-decrypt-encrypt triple with three different keys.
 .Ar blowfish
-is a fast block cipher, it appears very secure and is much faster than
+is a fast block cipher; it appears very secure and is much faster than
 .Ar 3des .
 .Ar des
 is only supported in the
@@ -444,18 +466,41 @@ be specified in order of preference.
 See
 .Cm Ciphers
 for more information.
-.It Fl e Ar ch|^ch|none
+.It Fl D Ar port
+Specifies a local
+.Dq dynamic
+application-level port forwarding.
+This works by allocating a socket to listen to
+.Ar port
+on the local side, and whenever a connection is made to this port, the
+connection is forwarded over the secure channel, and the application
+protocol is then used to determine where to connect to from the
+remote machine.
+Currently the SOCKS4 and SOCKS5 protocols are supported, and
+.Nm
+will act as a SOCKS server.
+Only root can forward privileged ports.
+Dynamic port forwardings can also be specified in the configuration file.
+.It Fl e Ar ch | ^ch | none
 Sets the escape character for sessions with a pty (default:
 .Ql ~ ) .
 The escape character is only recognized at the beginning of a line.
 The escape character followed by a dot
 .Pq Ql \&.
-closes the connection, followed
-by control-Z suspends the connection, and followed by itself sends the
-escape character once.
+closes the connection;
+followed by control-Z suspends the connection;
+and followed by itself sends the escape character once.
 Setting the character to
 .Dq none
 disables any escapes and makes the session fully transparent.
+.It Fl F Ar configfile
+Specifies an alternative per-user configuration file.
+If a configuration file is given on the command line,
+the system-wide configuration file
+.Pq Pa /etc/ssh/ssh_config
+will be ignored.
+The default for the per-user configuration file is
+.Pa $HOME/.ssh/config .
 .It Fl f
 Requests
 .Nm
@@ -471,6 +516,12 @@ something like
 .Ic ssh -f host xterm .
 .It Fl g
 Allows remote hosts to connect to local forwarded ports.
+.It Fl I Ar smartcard_device
+Specifies which smartcard device to use.
+The argument is the device
+.Nm
+should use to communicate with a smartcard used for storing the user's
+private RSA key.
 .It Fl i Ar identity_file
 Selects a file from which the identity (private key) for
 RSA or DSA authentication is read.
@@ -487,15 +538,33 @@ It is possible to have multiple
 .Fl i
 options (and multiple identities specified in
 configuration files).
-.It Fl I Ar smartcard_device
-Specifies which smartcard device to use.
-The argument is the device
-.Nm
-should use to communicate with a smartcard used for storing the user's
-private RSA key.
 .It Fl k
-Disables forwarding of Kerberos tickets.
-This may also be specified on a per-host basis in the configuration file.
+Disables forwarding (delegation) of GSSAPI credentials to the server.
+.It Fl L Xo
+.Sm off
+.Ar port : host : hostport
+.Sm on
+.Xc
+Specifies that the given port on the local (client) host is to be
+forwarded to the given host and port on the remote side.
+This works by allocating a socket to listen to
+.Ar port
+on the local side, and whenever a connection is made to this port, the
+connection is forwarded over the secure channel, and a connection is
+made to
+.Ar host
+port
+.Ar hostport
+from the remote machine.
+Port forwardings can also be specified in the configuration file.
+Only root can forward privileged ports.
+IPv6 addresses can be specified with an alternative syntax:
+.Sm off
+.Xo
+.Ar port No / Ar host No /
+.Ar hostport .
+.Xc
+.Sm on
 .It Fl l Ar login_name
 Specifies the user to log in as on the remote machine.
 This also may be specified on a per-host basis in the configuration file.
@@ -506,6 +575,10 @@ be specified in order of preference.
 See the
 .Cm MACs
 keyword for more information.
+.It Fl N
+Do not execute a remote command.
+This is useful for just forwarding ports
+(protocol version 2 only).
 .It Fl n
 Redirects stdin from
 .Pa /dev/null
@@ -526,14 +599,66 @@ program will be put in the background.
 needs to ask for a password or passphrase; see also the
 .Fl f
 option.)
-.It Fl N
-Do not execute a remote command.
-This is useful for just forwarding ports
-(protocol version 2 only).
 .It Fl o Ar option
 Can be used to give options in the format used in the configuration file.
 This is useful for specifying options for which there is no separate
 command-line flag.
+For full details of the options listed below, and their possible values, see
+.Xr ssh_config 5 .
+.Pp
+.Bl -tag -width Ds -offset indent -compact
+.It AddressFamily
+.It BatchMode
+.It BindAddress
+.It ChallengeResponseAuthentication
+.It CheckHostIP
+.It Cipher
+.It Ciphers
+.It ClearAllForwardings
+.It Compression
+.It CompressionLevel
+.It ConnectionAttempts
+.It ConnectionTimeout
+.It DynamicForward
+.It EscapeChar
+.It ForwardAgent
+.It ForwardX11
+.It ForwardX11Trusted
+.It GatewayPorts
+.It GlobalKnownHostsFile
+.It GSSAPIAuthentication
+.It GSSAPIDelegateCredentials
+.It Host
+.It HostbasedAuthentication
+.It HostKeyAlgorithms
+.It HostKeyAlias
+.It HostName
+.It IdentityFile
+.It LocalForward
+.It LogLevel
+.It MACs
+.It NoHostAuthenticationForLocalhost
+.It NumberOfPasswordPrompts
+.It PasswordAuthentication
+.It Port
+.It PreferredAuthentications
+.It Protocol
+.It ProxyCommand
+.It PubkeyAuthentication
+.It RemoteForward
+.It RhostsRSAAuthentication
+.It RSAAuthentication
+.It ServerAliveInterval
+.It ServerAliveCountMax
+.It SmartcardDevice
+.It StrictHostKeyChecking
+.It TCPKeepAlive
+.It UsePrivilegedPort
+.It User
+.It UserKnownHostsFile
+.It VerifyHostKeyDNS
+.It XAuthLocation
+.El
 .It Fl p Ar port
 Port to connect to on the remote host.
 This can be specified on a
@@ -541,11 +666,40 @@ per-host basis in the configuration file.
 .It Fl q
 Quiet mode.
 Causes all warning and diagnostic messages to be suppressed.
+.It Fl R Xo
+.Sm off
+.Ar port : host : hostport
+.Sm on
+.Xc
+Specifies that the given port on the remote (server) host is to be
+forwarded to the given host and port on the local side.
+This works by allocating a socket to listen to
+.Ar port
+on the remote side, and whenever a connection is made to this port, the
+connection is forwarded over the secure channel, and a connection is
+made to
+.Ar host
+port
+.Ar hostport
+from the local machine.
+Port forwardings can also be specified in the configuration file.
+Privileged ports can be forwarded only when
+logging in as root on the remote machine.
+IPv6 addresses can be specified with an alternative syntax:
+.Sm off
+.Xo
+.Ar port No / Ar host No /
+.Ar hostport .
+.Xc
+.Sm on
 .It Fl s
 May be used to request invocation of a subsystem on the remote system.
 Subsystems are a feature of the SSH2 protocol which facilitate the use
-of SSH as a secure transport for other applications (eg. sftp).
+of SSH as a secure transport for other applications (eg.\&
+.Xr sftp 1 ) .
 The subsystem is specified as the remote command.
+.It Fl T
+Disable pseudo-tty allocation.
 .It Fl t
 Force pseudo-tty allocation.
 This can be used to execute arbitrary
@@ -556,8 +710,8 @@ Multiple
 options force tty allocation, even if
 .Nm
 has no local tty.
-.It Fl T
-Disable pseudo-tty allocation.
+.It Fl V
+Display the version number and exit.
 .It Fl v
 Verbose mode.
 Causes
@@ -569,10 +723,6 @@ Multiple
 .Fl v
 options increase the verbosity.
 The maximum is 3.
-.It Fl V
-Display the version number and exit.
-.It Fl x
-Disables X11 forwarding.
 .It Fl X
 Enables X11 forwarding.
 This can also be specified on a per-host basis in a configuration file.
@@ -582,94 +732,10 @@ Users with the ability to bypass file permissions on the remote host
 (for the user's X authorization database)
 can access the local X11 display through the forwarded connection.
 An attacker may then be able to perform activities such as keystroke monitoring.
-.It Fl C
-Requests compression of all data (including stdin, stdout, stderr, and
-data for forwarded X11 and TCP/IP connections).
-The compression algorithm is the same used by
-.Xr gzip 1 ,
-and the
-.Dq level
-can be controlled by the
-.Cm CompressionLevel
-option for protocol version 1.
-Compression is desirable on modem lines and other
-slow connections, but will only slow down things on fast networks.
-The default value can be set on a host-by-host basis in the
-configuration files; see the
-.Cm Compression
-option.
-.It Fl F Ar configfile
-Specifies an alternative per-user configuration file.
-If a configuration file is given on the command line,
-the system-wide configuration file
-.Pq Pa /etc/ssh/ssh_config
-will be ignored.
-The default for the per-user configuration file is
-.Pa $HOME/.ssh/config .
-.It Fl L Ar port:host:hostport
-Specifies that the given port on the local (client) host is to be
-forwarded to the given host and port on the remote side.
-This works by allocating a socket to listen to
-.Ar port
-on the local side, and whenever a connection is made to this port, the
-connection is forwarded over the secure channel, and a connection is
-made to
-.Ar host
-port
-.Ar hostport
-from the remote machine.
-Port forwardings can also be specified in the configuration file.
-Only root can forward privileged ports.
-IPv6 addresses can be specified with an alternative syntax:
-.Ar port/host/hostport
-.It Fl R Ar port:host:hostport
-Specifies that the given port on the remote (server) host is to be
-forwarded to the given host and port on the local side.
-This works by allocating a socket to listen to
-.Ar port
-on the remote side, and whenever a connection is made to this port, the
-connection is forwarded over the secure channel, and a connection is
-made to
-.Ar host
-port
-.Ar hostport
-from the local machine.
-Port forwardings can also be specified in the configuration file.
-Privileged ports can be forwarded only when
-logging in as root on the remote machine.
-IPv6 addresses can be specified with an alternative syntax:
-.Ar port/host/hostport
-.It Fl D Ar port
-Specifies a local
-.Dq dynamic
-application-level port forwarding.
-This works by allocating a socket to listen to
-.Ar port
-on the local side, and whenever a connection is made to this port, the
-connection is forwarded over the secure channel, and the application
-protocol is then used to determine where to connect to from the
-remote machine.
-Currently the SOCKS4 and SOCKS5 protocols are supported, and
-.Nm
-will act as a SOCKS server.
-Only root can forward privileged ports.
-Dynamic port forwardings can also be specified in the configuration file.
-.It Fl 1
-Forces
-.Nm
-to try protocol version 1 only.
-.It Fl 2
-Forces
-.Nm
-to try protocol version 2 only.
-.It Fl 4
-Forces
-.Nm
-to use IPv4 addresses only.
-.It Fl 6
-Forces
-.Nm
-to use IPv6 addresses only.
+.It Fl x
+Disables X11 forwarding.
+.It Fl Y
+Enables trusted X11 forwarding.
 .El
 .Sh CONFIGURATION FILES
 .Nm
@@ -680,7 +746,7 @@ The file format and configuration options are described in
 .Sh ENVIRONMENT
 .Nm
 will normally set the following environment variables:
-.Bl -tag -width Ds
+.Bl -tag -width LOGNAME
 .It Ev DISPLAY
 The
 .Ev DISPLAY
@@ -690,7 +756,7 @@ It is automatically set by
 to point to a value of the form
 .Dq hostname:n
 where hostname indicates
-the host where the shell runs, and n is an integer >= 1.
+the host where the shell runs, and n is an integer \*(Ge 1.
 .Nm
 uses this special value to forward X11 connections over the secure
 channel.
@@ -768,7 +834,7 @@ and adds lines of the format
 .Dq VARNAME=value
 to the environment if the file exists and if users are allowed to
 change their environment.
-See the
+For more information, see the
 .Cm PermitUserEnvironment
 option in
 .Xr sshd_config 5 .
@@ -797,7 +863,7 @@ Contains the public key for authentication (public part of the
 identity file in human-readable form).
 The contents of the
 .Pa $HOME/.ssh/identity.pub
-file should be added to
+file should be added to the file
 .Pa $HOME/.ssh/authorized_keys
 on all machines
 where the user wishes to log in using protocol version 1 RSA authentication.
@@ -823,7 +889,8 @@ Lists the public keys (RSA/DSA) that can be used for logging in as this user.
 The format of this file is described in the
 .Xr sshd 8
 manual page.
-In the simplest form the format is the same as the .pub
+In the simplest form the format is the same as the
+.Pa .pub
 identity files.
 This file is not highly sensitive, but the recommended
 permissions are read/write for the user, and not accessible by others.
@@ -839,7 +906,7 @@ by spaces): system name, public key and optional comment field.
 When different names are used
 for the same machine, all such names should be listed, separated by
 commas.
-The format is described on the
+The format is described in the
 .Xr sshd 8
 manual page.
 .Pp
@@ -879,7 +946,7 @@ By default
 is not setuid root.
 .It Pa $HOME/.rhosts
 This file is used in
-.Pa \&.rhosts
+.Em rhosts
 authentication to list the
 host/user pairs that are permitted to log in.
 (Note that this file is
@@ -901,7 +968,9 @@ accessible by others.
 Note that by default
 .Xr sshd 8
 will be installed so that it requires successful RSA host
-authentication before permitting \s+2.\s0rhosts authentication.
+authentication before permitting
+.Em rhosts
+authentication.
 If the server machine does not have the client's host key in
 .Pa /etc/ssh/ssh_known_hosts ,
 it can be stored in
@@ -912,21 +981,20 @@ will automatically add the host key to
 .Pa $HOME/.ssh/known_hosts .
 .It Pa $HOME/.shosts
 This file is used exactly the same way as
-.Pa \&.rhosts .
+.Pa .rhosts .
 The purpose for
 having this file is to be able to use rhosts authentication with
 .Nm
 without permitting login with
-.Nm rlogin
+.Xr rlogin
 or
 .Xr rsh 1 .
 .It Pa /etc/hosts.equiv
 This file is used during
-.Pa \&.rhosts
+.Em rhosts
 authentication.
 It contains
-canonical hosts names, one per line (the full format is described on
-the
+canonical hosts names, one per line (the full format is described in the
 .Xr sshd 8
 manual page).
 If the client host is found in this file, login is
@@ -966,6 +1034,7 @@ above.
 exits with the exit status of the remote command or with 255
 if an error occurred.
 .Sh SEE ALSO
+.Xr gzip 1 ,
 .Xr rsh 1 ,
 .Xr scp 1 ,
 .Xr sftp 1 ,
@@ -973,6 +1042,7 @@ if an error occurred.
 .Xr ssh-agent 1 ,
 .Xr ssh-keygen 1 ,
 .Xr telnet 1 ,
+.Xr hosts.equiv 5 ,
 .Xr ssh_config 5 ,
 .Xr ssh-keysign 8 ,
 .Xr sshd 8
index 06d1cb0e241a3c4f44cd64dd23bdc64453776650..a229db1c8618b0df3609fd1ca63ef51972849001 100644 (file)
@@ -13,7 +13,7 @@
  * called by a name other than "ssh" or "Secure Shell".
  *
  * Copyright (c) 1999 Niels Provos.  All rights reserved.
- * Copyright (c) 2000, 2001, 2002 Markus Friedl.  All rights reserved.
+ * Copyright (c) 2000, 2001, 2002, 2003 Markus Friedl.  All rights reserved.
  *
  * Modified to work with SSL by Niels Provos <provos@citi.umich.edu>
  * in Canada (German citizen).
@@ -40,7 +40,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: ssh.c,v 1.201 2003/09/01 18:15:50 markus Exp $");
+RCSID("$OpenBSD: ssh.c,v 1.206 2003/12/16 15:49:51 markus Exp $");
 
 #include <openssl/evp.h>
 #include <openssl/err.h>
@@ -155,6 +155,7 @@ usage(void)
        fprintf(stderr, "  -A          Enable authentication agent forwarding.\n");
        fprintf(stderr, "  -a          Disable authentication agent forwarding (default).\n");
        fprintf(stderr, "  -X          Enable X11 connection forwarding.\n");
+       fprintf(stderr, "  -Y          Enable trusted X11 connection forwarding.\n");
        fprintf(stderr, "  -x          Disable X11 connection forwarding (default).\n");
        fprintf(stderr, "  -i file     Identity for public key authentication "
            "(default: ~/.ssh/identity)\n");
@@ -204,7 +205,7 @@ main(int ac, char **av)
        int i, opt, exit_status;
        u_short fwd_port, fwd_host_port;
        char sfwd_port[6], sfwd_host_port[6];
-       char *p, *cp, buf[256];
+       char *p, *cp, *line, buf[256];
        struct stat st;
        struct passwd *pw;
        int dummy;
@@ -220,7 +221,7 @@ main(int ac, char **av)
         */
        original_real_uid = getuid();
        original_effective_uid = geteuid();
+
        /*
         * Use uid-swapping to give up root privileges for the duration of
         * option processing.  We will re-instantiate the rights when we are
@@ -264,7 +265,7 @@ main(int ac, char **av)
 
 again:
        while ((opt = getopt(ac, av,
-           "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:NPR:TVX")) != -1) {
+           "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:NPR:TVXY")) != -1) {
                switch (opt) {
                case '1':
                        options.protocol = SSH_PROTO_1;
@@ -291,6 +292,10 @@ again:
                case 'X':
                        options.forward_x11 = 1;
                        break;
+               case 'Y':
+                       options.forward_x11 = 1;
+                       options.forward_x11_trusted = 1;
+                       break;
                case 'g':
                        options.gateway_ports = 1;
                        break;
@@ -304,7 +309,7 @@ again:
                        options.forward_agent = 1;
                        break;
                case 'k':
-                       /* ignored for backward compatibility */
+                       options.gss_deleg_creds = 0;
                        break;
                case 'i':
                        if (stat(optarg, &st) < 0) {
@@ -459,9 +464,11 @@ again:
                        break;
                case 'o':
                        dummy = 1;
+                       line = xstrdup(optarg);
                        if (process_config_line(&options, host ? host : "",
-                           optarg, "command-line", 0, &dummy) != 0)
+                           line, "command-line", 0, &dummy) != 0)
                                exit(1);
+                       xfree(line);
                        break;
                case 's':
                        subsystem_flag = 1;
@@ -738,7 +745,7 @@ again:
        packet_close();
 
        /*
-        * Send SIGHUP to proxy command if used. We don't wait() in 
+        * Send SIGHUP to proxy command if used. We don't wait() in
         * case it hangs and instead rely on init to reap the child
         */
        if (proxy_command_pid > 1)
@@ -747,19 +754,25 @@ again:
        return exit_status;
 }
 
+#define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1"
+
 static void
 x11_get_proto(char **_proto, char **_data)
 {
+       char cmd[1024];
        char line[512];
+       char xdisplay[512];
        static char proto[512], data[512];
        FILE *f;
-       int got_data = 0, i;
-       char *display;
+       int got_data = 0, generated = 0, do_unlink = 0, i;
+       char *display, *xauthdir, *xauthfile;
        struct stat st;
 
+       xauthdir = xauthfile = NULL;
        *_proto = proto;
        *_data = data;
        proto[0] = data[0] = '\0';
+
        if (!options.xauth_location ||
            (stat(options.xauth_location, &st) == -1)) {
                debug("No xauth program.");
@@ -768,28 +781,59 @@ x11_get_proto(char **_proto, char **_data)
                        debug("x11_get_proto: DISPLAY not set");
                        return;
                }
-               /* Try to get Xauthority information for the display. */
-               if (strncmp(display, "localhost:", 10) == 0)
-                       /*
-                        * Handle FamilyLocal case where $DISPLAY does
-                        * not match an authorization entry.  For this we
-                        * just try "xauth list unix:displaynum.screennum".
-                        * XXX: "localhost" match to determine FamilyLocal
-                        *      is not perfect.
-                        */
-                       snprintf(line, sizeof line, "%s list unix:%s 2>"
-                           _PATH_DEVNULL, options.xauth_location, display+10);
-               else
-                       snprintf(line, sizeof line, "%s list %.200s 2>"
-                           _PATH_DEVNULL, options.xauth_location, display);
-               debug2("x11_get_proto: %s", line);
-               f = popen(line, "r");
+               /*
+                * Handle FamilyLocal case where $DISPLAY does
+                * not match an authorization entry.  For this we
+                * just try "xauth list unix:displaynum.screennum".
+                * XXX: "localhost" match to determine FamilyLocal
+                *      is not perfect.
+                */
+               if (strncmp(display, "localhost:", 10) == 0) {
+                       snprintf(xdisplay, sizeof(xdisplay), "unix:%s",
+                           display + 10);
+                       display = xdisplay;
+               }
+               if (options.forward_x11_trusted == 0) {
+                       xauthdir = xmalloc(MAXPATHLEN);
+                       xauthfile = xmalloc(MAXPATHLEN);
+                       strlcpy(xauthdir, "/tmp/ssh-XXXXXXXXXX", MAXPATHLEN);
+                       if (mkdtemp(xauthdir) != NULL) {
+                               do_unlink = 1;
+                               snprintf(xauthfile, MAXPATHLEN, "%s/xauthfile",
+                                   xauthdir);
+                               snprintf(cmd, sizeof(cmd),
+                                   "%s -f %s generate %s " SSH_X11_PROTO
+                                   " untrusted timeout 120 2>" _PATH_DEVNULL,
+                                   options.xauth_location, xauthfile, display);
+                               debug2("x11_get_proto: %s", cmd);
+                               if (system(cmd) == 0)
+                                       generated = 1;
+                       }
+               }
+               snprintf(cmd, sizeof(cmd),
+                   "%s %s%s list %s . 2>" _PATH_DEVNULL,
+                   options.xauth_location,
+                   generated ? "-f " : "" ,
+                   generated ? xauthfile : "",
+                   display);
+               debug2("x11_get_proto: %s", cmd);
+               f = popen(cmd, "r");
                if (f && fgets(line, sizeof(line), f) &&
                    sscanf(line, "%*s %511s %511s", proto, data) == 2)
                        got_data = 1;
                if (f)
                        pclose(f);
        }
+
+       if (do_unlink) {
+               unlink(xauthfile);
+               rmdir(xauthdir);
+       }
+       if (xauthdir)
+               xfree(xauthdir);
+       if (xauthfile)
+               xfree(xauthfile);
+
        /*
         * If we didn't get authentication data, just make up some
         * data.  The forwarding code will check the validity of the
@@ -801,12 +845,14 @@ x11_get_proto(char **_proto, char **_data)
        if (!got_data) {
                u_int32_t rand = 0;
 
-               logit("Warning: No xauth data; using fake authentication data for X11 forwarding.");
-               strlcpy(proto, "MIT-MAGIC-COOKIE-1", sizeof proto);
+               logit("Warning: No xauth data; "
+                   "using fake authentication data for X11 forwarding.");
+               strlcpy(proto, SSH_X11_PROTO, sizeof proto);
                for (i = 0; i < 16; i++) {
                        if (i % 4 == 0)
                                rand = arc4random();
-                       snprintf(data + 2 * i, sizeof data - 2 * i, "%02x", rand & 0xff);
+                       snprintf(data + 2 * i, sizeof data - 2 * i, "%02x",
+                           rand & 0xff);
                        rand >>= 8;
                }
        }
@@ -1009,16 +1055,13 @@ client_subsystem_reply(int type, u_int32_t seq, void *ctxt)
 }
 
 void
-client_global_request_reply(int type, u_int32_t seq, void *ctxt)
+client_global_request_reply_fwd(int type, u_int32_t seq, void *ctxt)
 {
        int i;
 
        i = client_global_request_id++;
-       if (i >= options.num_remote_forwards) {
-               debug("client_global_request_reply: too many replies %d > %d",
-                   i, options.num_remote_forwards);
+       if (i >= options.num_remote_forwards)
                return;
-       }
        debug("remote forward %s for: listen %d, connect %s:%d",
            type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
            options.remote_forwards[i].port,
index f38622bb91553ac9abf7a62cfefa69aa6d19980a..95c3fe288254073860aa951aca1fd0e57aae497d 100644 (file)
@@ -34,7 +34,7 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.\" $OpenBSD: ssh_config.5,v 1.20 2003/09/02 18:50:06 jmc Exp $
+.\" $OpenBSD: ssh_config.5,v 1.28 2003/12/16 15:49:51 markus Exp $
 .Dd September 25, 1999
 .Dt SSH_CONFIG 5
 .Os
@@ -192,7 +192,6 @@ Specifies the ciphers allowed for protocol version 2
 in order of preference.
 Multiple ciphers must be comma-separated.
 The default is
-.Pp
 .Bd -literal
   ``aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,
     aes192-cbc,aes256-cbc''
@@ -266,6 +265,7 @@ or
 .Dq no .
 The default is
 .Dq no .
+This option should be placed in the non-hostspecific section.
 See
 .Xr ssh-keysign 8
 for more information.
@@ -312,9 +312,27 @@ The default is
 .Pp
 X11 forwarding should be enabled with caution.
 Users with the ability to bypass file permissions on the remote host
-(for the user's X authorization database)
+(for the user's X11 authorization database)
 can access the local X11 display through the forwarded connection.
-An attacker may then be able to perform activities such as keystroke monitoring.
+An attacker may then be able to perform activities such as keystroke monitoring
+if the
+.Cm ForwardX11Trusted
+option is also enabled.
+.It Cm ForwardX11Trusted
+If the this option is set to
+.Dq yes
+then remote X11 clients will have full access to the original X11 display.
+If this option is set to
+.Dq no
+then remote X11 clients will be considered untrusted and prevented
+from stealing or tampering with data belonging to trusted X11
+clients.
+.Pp
+The default is
+.Dq no .
+.Pp
+See the X11 SECURITY extension specification for full details on
+the restrictions imposed on untrusted clients.
 .It Cm GatewayPorts
 Specifies whether remote hosts are allowed to connect to local
 forwarded ports.
@@ -338,9 +356,7 @@ Specifies a file to use for the global
 host key database instead of
 .Pa /etc/ssh/ssh_known_hosts .
 .It Cm GSSAPIAuthentication
-Specifies whether authentication based on GSSAPI may be used, either using
-the result of a successful key exchange, or using GSSAPI user
-authentication.
+Specifies whether user authentication based on GSSAPI is allowed.
 The default is 
 .Dq yes .
 Note that this option applies to protocol version 2 only.
@@ -402,23 +418,6 @@ syntax to refer to a user's home directory.
 It is possible to have
 multiple identity files specified in configuration files; all these
 identities will be tried in sequence.
-.It Cm KeepAlive
-Specifies whether the system should send TCP keepalive messages to the
-other side.
-If they are sent, death of the connection or crash of one
-of the machines will be properly noticed.
-However, this means that
-connections will die if the route is down temporarily, and some people
-find it annoying.
-.Pp
-The default is
-.Dq yes
-(to send keepalives), and the client will notice
-if the network goes down or the remote host dies.
-This is important in scripts, and many users want it too.
-.Pp
-To disable keepalives, the value should be set to
-.Dq no .
 .It Cm LocalForward
 Specifies that a TCP/IP port on the local machine be forwarded over
 the secure channel to the specified host and port from the remote machine.
@@ -478,7 +477,7 @@ This allows a client to prefer one method (e.g.
 over another method (e.g.
 .Cm password )
 The default for this option is:
-.Dq hostbased,external-keyx,gssapi,publickey,keyboard-interactive,password .
+.Dq hostbased,external-keyx,gssapi-with-mic,gssapi,publickey,keyboard-interactive,password .
 .It Cm Protocol
 Specifies the protocol versions
 .Nm ssh
@@ -565,6 +564,42 @@ running.
 The default is
 .Dq yes .
 Note that this option applies to protocol version 1 only.
+.It Cm ServerAliveInterval
+Sets a timeout interval in seconds after which if no data has been received
+from the server,
+.Nm ssh
+will send a message through the encrypted
+channel to request a response from the server.
+The default
+is 0, indicating that these messages will not be sent to the server.
+This option applies to protocol version 2 only.
+.It Cm ServerAliveCountMax
+Sets the number of server alive messages (see above) which may be
+sent without
+.Nm ssh
+receiving any messages back from the server.
+If this threshold is reached while server alive messages are being sent,
+.Nm ssh
+will disconnect from the server, terminating the session.
+It is important to note that the use of server alive messages is very
+different from
+.Cm TCPKeepAlive
+(below).
+The server alive messages are sent through the encrypted channel
+and therefore will not be spoofable.
+The TCP keepalive option enabled by
+.Cm TCPKeepAlive
+is spoofable.
+The server alive mechanism is valuable when the client or
+server depend on knowing when a connection has become inactive.
+.Pp
+The default value is 3.
+If, for example,
+.Cm ServerAliveInterval
+(above) is set to 15, and
+.Cm ServerAliveCountMax
+is left at the default, if the server becomes unresponsive ssh
+will disconnect after approximately 45 seconds.
 .It Cm SmartcardDevice
 Specifies which smartcard device to use.
 The argument to this keyword is the device
@@ -607,6 +642,23 @@ or
 .Dq ask .
 The default is
 .Dq ask .
+.It Cm TCPKeepAlive
+Specifies whether the system should send TCP keepalive messages to the
+other side.
+If they are sent, death of the connection or crash of one
+of the machines will be properly noticed.
+However, this means that
+connections will die if the route is down temporarily, and some people
+find it annoying.
+.Pp
+The default is
+.Dq yes
+(to send TCP keepalive messages), and the client will notice
+if the network goes down or the remote host dies.
+This is important in scripts, and many users want it too.
+.Pp
+To disable TCP keepalive messages, the value should be set to
+.Dq no .
 .It Cm UsePrivilegedPort
 Specifies whether to use a privileged port for outgoing connections.
 The argument must be
@@ -636,6 +688,23 @@ host key database instead of
 .It Cm VerifyHostKeyDNS
 Specifies whether to verify the remote key using DNS and SSHFP resource
 records.
+If this option is set to
+.Dq yes ,
+the client will implicitly trust keys that match a secure fingerprint
+from DNS.
+Insecure fingerprints will be handled as if this option was set to
+.Dq ask .
+If this option is set to
+.Dq ask ,
+information on fingerprint match will be displayed, but the user will still
+need to confirm new host keys according to the
+.Cm StrictHostKeyChecking
+option.
+The argument must be
+.Dq yes ,
+.Dq no
+or
+.Dq ask .
 The default is
 .Dq no .
 Note that this option applies to protocol version 2 only.
index e2acc7a173abf39e0264efea11e8608120418f05..c9605d11696bb643e9c93d0dfb4cda3c78220fee 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshconnect2.c,v 1.124 2003/08/25 10:33:33 djm Exp $");
+RCSID("$OpenBSD: sshconnect2.c,v 1.134 2004/01/19 21:25:15 markus Exp $");
 
 #include "openbsd-compat/sys-queue.h"
 
@@ -247,6 +247,8 @@ void        input_gssapi_errtok(int, u_int32_t, void *);
 #ifdef GSSAPI
 int    userauth_external(Authctxt *authctxt);
 int    userauth_gssapi(Authctxt *authctxt);
+int    userauth_gssapi_with_mic(Authctxt *authctxt);
+int    userauth_gssapi_without_mic(Authctxt *authctxt);
 void   input_gssapi_response(int type, u_int32_t, void *);
 void   input_gssapi_token(int type, u_int32_t, void *);
 void   input_gssapi_hash(int type, u_int32_t, void *);
@@ -265,14 +267,21 @@ static Authmethod *authmethod_get(char *authlist);
 static Authmethod *authmethod_lookup(const char *name);
 static char *authmethods_get(void);
 
+static int gssapi_with_mic = 1;        /* flag to toggle "gssapi-with-mic" vs.
+                                  "gssapi" */
+
 Authmethod authmethods[] = {
 #ifdef GSSAPI
        {"external-keyx",
                userauth_external,
                &options.gss_authentication,
                NULL},
+       {"gssapi-with-mic",
+               userauth_gssapi_with_mic,
+               &options.gss_authentication,
+               NULL},
        {"gssapi",
-               userauth_gssapi,
+               userauth_gssapi_without_mic,
                &options.gss_authentication,
                NULL},
 #endif
@@ -407,10 +416,12 @@ void
 input_userauth_banner(int type, u_int32_t seq, void *ctxt)
 {
        char *msg, *lang;
+
        debug3("input_userauth_banner");
        msg = packet_get_string(NULL);
        lang = packet_get_string(NULL);
-       logit("%s", msg);
+       if (options.log_level > SYSLOG_LEVEL_QUIET)
+               fprintf(stderr, "%s", msg);
        xfree(msg);
        xfree(lang);
 }
@@ -421,10 +432,14 @@ input_userauth_success(int type, u_int32_t seq, void *ctxt)
        Authctxt *authctxt = ctxt;
        if (authctxt == NULL)
                fatal("input_userauth_success: no authentication context");
-       if (authctxt->authlist)
+       if (authctxt->authlist) {
                xfree(authctxt->authlist);
-       if (authctxt->methoddata)
+               authctxt->authlist = NULL;
+       }
+       if (authctxt->methoddata) {
                xfree(authctxt->methoddata);
+               authctxt->methoddata = NULL;
+       }
        authctxt->success = 1;                  /* break out */
 }
 
@@ -496,7 +511,12 @@ input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt)
        debug2("input_userauth_pk_ok: fp %s", fp);
        xfree(fp);
 
-       TAILQ_FOREACH(id, &authctxt->keys, next) {
+       /*
+        * search keys in the reverse order, because last candidate has been
+        * moved to the end of the queue.  this also avoids confusion by
+        * duplicate keys
+        */
+       TAILQ_FOREACH_REVERSE(id, &authctxt->keys, next, idlist) {
                if (key_equal(key, id->key)) {
                        sent = sign_and_send_pubkey(authctxt, id);
                        break;
@@ -514,11 +534,11 @@ done:
 }
 
 #ifdef GSSAPI
-int 
+int
 userauth_gssapi(Authctxt *authctxt)
 {
        Gssctxt *gssctxt = NULL;
-       static gss_OID_set supported = NULL;
+       static gss_OID_set gss_supported = NULL;
        static int mech = 0;
        OM_uint32 min;
        int ok = 0;
@@ -531,18 +551,18 @@ userauth_gssapi(Authctxt *authctxt)
        /* Try one GSSAPI method at a time, rather than sending them all at
         * once. */
 
-       if (supported == NULL)
-               gss_indicate_mechs(&min, &supported);
+       if (gss_supported == NULL)
+               gss_indicate_mechs(&min, &gss_supported);
 
        /* Check to see if the mechanism is usable before we offer it */
-       while (mech<supported->count && !ok) {
+       while (mech < gss_supported->count && !ok) {
                if (gssctxt)
                        ssh_gssapi_delete_ctx(&gssctxt);
                ssh_gssapi_build_ctx(&gssctxt);
-               ssh_gssapi_set_oid(gssctxt, &supported->elements[mech]);
+               ssh_gssapi_set_oid(gssctxt, &gss_supported->elements[mech]);
 
                /* My DER encoding requires length<128 */
-               if (supported->elements[mech].length < 128 &&
+               if (gss_supported->elements[mech].length < 128 &&
                    !GSS_ERROR(ssh_gssapi_import_name(gssctxt,
                    authctxt->host))) {
                        ok = 1; /* Mechanism works */
@@ -564,14 +584,14 @@ userauth_gssapi(Authctxt *authctxt)
 
        /* Some servers encode the OID incorrectly (as we used to) */
        if (datafellows & SSH_BUG_GSSAPI_BER) {
-               packet_put_string(supported->elements[mech].elements,
-                   supported->elements[mech].length);
+               packet_put_string(gss_supported->elements[mech].elements,
+                   gss_supported->elements[mech].length);
        } else {
-               packet_put_int((supported->elements[mech].length)+2);
+               packet_put_int((gss_supported->elements[mech].length)+2);
                packet_put_char(SSH_GSS_OIDTYPE);
-               packet_put_char(supported->elements[mech].length);
-               packet_put_raw(supported->elements[mech].elements,
-                   supported->elements[mech].length);
+               packet_put_char(gss_supported->elements[mech].length);
+               packet_put_raw(gss_supported->elements[mech].elements,
+                   gss_supported->elements[mech].length);
        }
 
        packet_send();
@@ -586,15 +606,80 @@ userauth_gssapi(Authctxt *authctxt)
        return 1;
 }
 
+int
+userauth_gssapi_with_mic(Authctxt *authctxt)
+{
+    gssapi_with_mic = 1;
+    return userauth_gssapi(authctxt);
+}
+
+int
+userauth_gssapi_without_mic(Authctxt *authctxt)
+{
+    gssapi_with_mic = 0;
+    return userauth_gssapi(authctxt);
+}
+
+static OM_uint32
+process_gssapi_token(void *ctxt, gss_buffer_t recv_tok)
+{
+       Authctxt *authctxt = ctxt;
+       Gssctxt *gssctxt = authctxt->methoddata;
+       gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
+       gss_buffer_desc gssbuf, mic;
+       OM_uint32 status, ms, flags;
+       Buffer b;
+
+       status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
+           recv_tok, &send_tok, &flags);
+
+       if (send_tok.length > 0) {
+               if (GSS_ERROR(status))
+                       packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK);
+               else
+                       packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
+
+               packet_put_string(send_tok.value, send_tok.length);
+               packet_send();
+               gss_release_buffer(&ms, &send_tok);
+       }
+
+       if (status == GSS_S_COMPLETE) {
+               /* send either complete or MIC, depending on mechanism */
+               if (!(flags & GSS_C_INTEG_FLAG) || !gssapi_with_mic) {
+                       packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE);
+                       packet_send();
+               } else {
+                       ssh_gssapi_buildmic(&b, authctxt->server_user,
+                           authctxt->service, "gssapi-with-mic");
+
+                       gssbuf.value = buffer_ptr(&b);
+                       gssbuf.length = buffer_len(&b);
+
+                       status = ssh_gssapi_sign(gssctxt, &gssbuf, &mic);
+
+                       if (!GSS_ERROR(status)) {
+                               packet_start(SSH2_MSG_USERAUTH_GSSAPI_MIC);
+                               packet_put_string(mic.value, mic.length);
+
+                               packet_send();
+                       }
+
+                       buffer_free(&b);
+                       gss_release_buffer(&ms, &mic);
+               }
+       }
+
+       return status;
+}
+
 void
 input_gssapi_response(int type, u_int32_t plen, void *ctxt)
 {
        Authctxt *authctxt = ctxt;
        Gssctxt *gssctxt;
-       OM_uint32 status, ms;
        int oidlen;
        char *oidv;
-       gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
 
        if (authctxt == NULL)
                fatal("input_gssapi_response: no authentication context");
@@ -621,76 +706,39 @@ input_gssapi_response(int type, u_int32_t plen, void *ctxt)
 
        xfree(oidv);
 
-       status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
-           GSS_C_NO_BUFFER, &send_tok, NULL);
-       if (GSS_ERROR(status)) {
-               if (send_tok.length > 0) {
-                       packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK);
-                       packet_put_string(send_tok.value, send_tok.length);
-                       packet_send();
-                       gss_release_buffer(&ms, &send_tok);
-               }
+       if (GSS_ERROR(process_gssapi_token(ctxt, GSS_C_NO_BUFFER))) {
                /* Start again with next method on list */
                debug("Trying to start again");
                userauth(authctxt, NULL);
                return;
        }
-
-       /* We must have data to send */
-       packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
-       packet_put_string(send_tok.value, send_tok.length);
-       packet_send();
-       gss_release_buffer(&ms, &send_tok);
 }
 
 void
 input_gssapi_token(int type, u_int32_t plen, void *ctxt)
 {
        Authctxt *authctxt = ctxt;
-       Gssctxt *gssctxt;
-       gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
        gss_buffer_desc recv_tok;
-       OM_uint32 status, ms;
+       OM_uint32 status;
        u_int slen;
 
        if (authctxt == NULL)
                fatal("input_gssapi_response: no authentication context");
-       gssctxt = authctxt->methoddata;
 
        recv_tok.value = packet_get_string(&slen);
        recv_tok.length = slen; /* safe typecast */
 
        packet_check_eom();
 
-       status=ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
-           &recv_tok, &send_tok, NULL);
+       status = process_gssapi_token(ctxt, &recv_tok);
 
        xfree(recv_tok.value);
 
        if (GSS_ERROR(status)) {
-               if (send_tok.length > 0) {
-                       packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK);
-                       packet_put_string(send_tok.value, send_tok.length);
-                       packet_send();
-                       gss_release_buffer(&ms, &send_tok);
-               }
                /* Start again with the next method in the list */
                userauth(authctxt, NULL);
                return;
        }
-
-       if (send_tok.length > 0) {
-               packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
-               packet_put_string(send_tok.value, send_tok.length);
-               packet_send();
-               gss_release_buffer(&ms, &send_tok);
-       }
-
-       if (status == GSS_S_COMPLETE) {
-               /* If that succeeded, send a exchange complete message */
-               packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE);
-               packet_send();
-       }
 }
 
 void
@@ -1104,7 +1152,7 @@ pubkey_prepare(Authctxt *authctxt)
                    key = ssh_get_next_identity(ac, &comment, 2)) {
                        found = 0;
                        TAILQ_FOREACH(id, &files, next) {
-                               /* agent keys from the config file are preferred */ 
+                               /* agent keys from the config file are preferred */
                                if (key_equal(key, id->key)) {
                                        key_free(key);
                                        xfree(comment);
@@ -1168,6 +1216,7 @@ userauth_pubkey(Authctxt *authctxt)
        while ((id = TAILQ_FIRST(&authctxt->keys))) {
                if (id->tried++)
                        return (0);
+               /* move key to the end of the queue */
                TAILQ_REMOVE(&authctxt->keys, id, next);
                TAILQ_INSERT_TAIL(&authctxt->keys, id, next);
                /*
@@ -1332,11 +1381,12 @@ ssh_keysign(Key *key, u_char **sigp, u_int *lenp,
        buffer_init(&b);
        buffer_put_int(&b, packet_get_connection_in()); /* send # of socket */
        buffer_put_string(&b, data, datalen);
-       ssh_msg_send(to[1], version, &b);
+       if (ssh_msg_send(to[1], version, &b) == -1)
+               fatal("ssh_keysign: couldn't send request");
 
        if (ssh_msg_recv(from[0], &b) < 0) {
                error("ssh_keysign: no reply");
-               buffer_clear(&b);
+               buffer_free(&b);
                return -1;
        }
        close(from[0]);
@@ -1348,11 +1398,11 @@ ssh_keysign(Key *key, u_char **sigp, u_int *lenp,
 
        if (buffer_get_char(&b) != version) {
                error("ssh_keysign: bad version");
-               buffer_clear(&b);
+               buffer_free(&b);
                return -1;
        }
        *sigp = buffer_get_string(&b, lenp);
-       buffer_clear(&b);
+       buffer_free(&b);
 
        return 0;
 }
index 0eeea666683e2eda69e7aebffe07e6b55890b278..34413e2a7f2388cfd05aefcbfab3e12108798657 100644 (file)
@@ -34,7 +34,7 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.\" $OpenBSD: sshd.8,v 1.199 2003/08/13 08:46:31 markus Exp $
+.\" $OpenBSD: sshd.8,v 1.200 2003/10/08 08:27:36 jmc Exp $
 .Dd September 25, 1999
 .Dt SSHD 8
 .Os
@@ -44,7 +44,7 @@
 .Sh SYNOPSIS
 .Nm sshd
 .Bk -words
-.Op Fl deiqtD46
+.Op Fl 46Ddeiqt
 .Op Fl b Ar bits
 .Op Fl f Ar config_file
 .Op Fl g Ar login_grace_time
@@ -78,9 +78,7 @@ This implementation of
 supports both SSH protocol version 1 and 2 simultaneously.
 .Nm
 works as follows:
-.Pp
 .Ss SSH protocol version 1
-.Pp
 Each host has a host-specific RSA key
 (normally 1024 bits) used to identify the host.
 Additionally, when
@@ -92,7 +90,7 @@ Whenever a client connects, the daemon responds with its public
 host and server keys.
 The client compares the
 RSA host key against its own database to verify that it has not changed.
-The client then generates a 256 bit random number.
+The client then generates a 256-bit random number.
 It encrypts this
 random number using both the host key and the server key, and sends
 the encrypted number to the server.
@@ -107,9 +105,9 @@ to use from those offered by the server.
 .Pp
 Next, the server and the client enter an authentication dialog.
 The client tries to authenticate itself using
-.Pa .rhosts
+.Em .rhosts
 authentication,
-.Pa .rhosts
+.Em .rhosts
 authentication combined with RSA host
 authentication, RSA challenge-response authentication, or password
 based authentication.
@@ -137,7 +135,8 @@ or
 .Ql \&*NP\&*
 ).
 .Pp
-Rhosts authentication is normally disabled
+.Em rhosts
+authentication is normally disabled
 because it is fundamentally insecure, but can be enabled in the server
 configuration file if desired.
 System security is not improved unless
@@ -150,9 +149,7 @@ are disabled (thus completely disabling
 and
 .Xr rsh
 into the machine).
-.Pp
 .Ss SSH protocol version 2
-.Pp
 Version 2 works similarly:
 Each host has a host-specific key (RSA or DSA) used to identify the host.
 However, when the daemon starts, it does not generate a server key.
@@ -160,7 +157,7 @@ Forward security is provided through a Diffie-Hellman key agreement.
 This key agreement results in a shared session key.
 .Pp
 The rest of the session is encrypted using a symmetric cipher, currently
-128 bit AES, Blowfish, 3DES, CAST128, Arcfour, 192 bit AES, or 256 bit AES.
+128-bit AES, Blowfish, 3DES, CAST128, Arcfour, 192-bit AES, or 256-bit AES.
 The client selects the encryption algorithm
 to use from those offered by the server.
 Additionally, session integrity is provided
@@ -171,9 +168,7 @@ Protocol version 2 provides a public key based
 user (PubkeyAuthentication) or
 client host (HostbasedAuthentication) authentication method,
 conventional password authentication and challenge response based methods.
-.Pp
 .Ss Command execution and data forwarding
-.Pp
 If the client successfully authenticates itself, a dialog for
 preparing the session is entered.
 At this time the client may request
@@ -192,8 +187,9 @@ connections have been closed, the server sends command exit status to
 the client, and both sides exit.
 .Pp
 .Nm
-can be configured using command-line options or a configuration
-file.
+can be configured using command-line options or a configuration file
+(by default
+.Xr sshd_config 5 ) .
 Command-line options override values specified in the
 configuration file.
 .Pp
@@ -205,9 +201,23 @@ by executing itself with the name it was started as, i.e.,
 .Pp
 The options are as follows:
 .Bl -tag -width Ds
+.It Fl 4
+Forces
+.Nm
+to use IPv4 addresses only.
+.It Fl 6
+Forces
+.Nm
+to use IPv6 addresses only.
 .It Fl b Ar bits
 Specifies the number of bits in the ephemeral protocol version 1
 server key (default 768).
+.It Fl D
+When this option is specified,
+.Nm
+will not detach and does not become a daemon.
+This allows easy monitoring of
+.Nm sshd .
 .It Fl d
 Debug mode.
 The server sends verbose debug output to the system
@@ -267,7 +277,7 @@ be feasible.
 Specifies how often the ephemeral protocol version 1 server key is
 regenerated (default 3600 seconds, or one hour).
 The motivation for regenerating the key fairly
-often is that the key is not stored anywhere, and after about an hour,
+often is that the key is not stored anywhere, and after about an hour
 it becomes impossible to recover the key for decrypting intercepted
 communications even if the machine is cracked into or physically
 seized.
@@ -276,6 +286,8 @@ A value of zero indicates that the key will never be regenerated.
 Can be used to give options in the format used in the configuration file.
 This is useful for specifying options for which there is no separate
 command-line flag.
+For full details of the options, and their values, see
+.Xr sshd_config 5 .
 .It Fl p Ar port
 Specifies the port on which the server listens for connections
 (default 22).
@@ -325,20 +337,6 @@ USER@HOST pattern in
 .Cm AllowUsers
 or
 .Cm DenyUsers .
-.It Fl D
-When this option is specified
-.Nm
-will not detach and does not become a daemon.
-This allows easy monitoring of
-.Nm sshd .
-.It Fl 4
-Forces
-.Nm
-to use IPv4 addresses only.
-.It Fl 6
-Forces
-.Nm
-to use IPv6 addresses only.
 .El
 .Sh CONFIGURATION FILE
 .Nm
@@ -375,9 +373,9 @@ Changes to run with normal user privileges.
 .It
 Sets up basic environment.
 .It
-Reads
-.Pa $HOME/.ssh/environment
-if it exists and users are allowed to change their environment.
+Reads the file
+.Pa $HOME/.ssh/environment ,
+if it exists, and users are allowed to change their environment.
 See the
 .Cm PermitUserEnvironment
 option in
@@ -516,7 +514,7 @@ Limit local
 port forwarding such that it may only connect to the specified host and
 port.
 IPv6 addresses can be specified with an alternative syntax:
-.Ar host/port .
+.Ar host Ns / Ns Ar port .
 Multiple
 .Cm permitopen
 options may be applied separated by commas.
@@ -524,13 +522,13 @@ No pattern matching is performed on the specified hostnames,
 they must be literal domains or addresses.
 .El
 .Ss Examples
-1024 33 12121.\|.\|.\|312314325 ylo@foo.bar
+1024 33 12121...312314325 ylo@foo.bar
 .Pp
-from="*.niksula.hut.fi,!pc.niksula.hut.fi" 1024 35 23.\|.\|.\|2334 ylo@niksula
+from="*.niksula.hut.fi,!pc.niksula.hut.fi" 1024 35 23...2334 ylo@niksula
 .Pp
-command="dump /home",no-pty,no-port-forwarding 1024 33 23.\|.\|.\|2323 backup.hut.fi
+command="dump /home",no-pty,no-port-forwarding 1024 33 23...2323 backup.hut.fi
 .Pp
-permitopen="10.2.1.55:80",permitopen="10.2.1.56:25" 1024 33 23.\|.\|.\|2323
+permitopen="10.2.1.55:80",permitopen="10.2.1.56:25" 1024 33 23...2323
 .Sh SSH_KNOWN_HOSTS FILE FORMAT
 The
 .Pa /etc/ssh/ssh_known_hosts
@@ -588,7 +586,7 @@ or by taking
 and adding the host names at the front.
 .Ss Examples
 .Bd -literal
-closenet,.\|.\|.\|,130.233.208.41 1024 37 159.\|.\|.93 closenet.hut.fi
+closenet,...,130.233.208.41 1024 37 159...93 closenet.hut.fi
 cvs.openbsd.org,199.185.137.3 ssh-rsa AAAA1234.....=
 .Ed
 .Sh FILES
@@ -647,7 +645,7 @@ and/or
 .Pa id_rsa.pub
 files into this file, as described in
 .Xr ssh-keygen 1 .
-.It Pa "/etc/ssh/ssh_known_hosts" and "$HOME/.ssh/known_hosts"
+.It Pa "/etc/ssh/ssh_known_hosts", "$HOME/.ssh/known_hosts"
 These files are consulted when using rhosts with RSA host
 authentication or protocol version 2 hostbased authentication
 to check the public key of the host.
@@ -681,7 +679,7 @@ The file must
 be writable only by the user; it is recommended that it not be
 accessible by others.
 .Pp
-If is also possible to use netgroups in the file.
+It is also possible to use netgroups in the file.
 Either host or user
 name may be of the form +@groupname to specify all hosts or all users
 in the group.
@@ -693,7 +691,7 @@ However, this file is
 not used by rlogin and rshd, so using this permits access using SSH only.
 .It Pa /etc/hosts.equiv
 This file is used during
-.Pa .rhosts
+.Em rhosts
 authentication.
 In the simplest form, this file contains host names, one per line.
 Users on
@@ -800,9 +798,12 @@ This file should be writable only by root, and should be world-readable.
 .Xr ssh-add 1 ,
 .Xr ssh-agent 1 ,
 .Xr ssh-keygen 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
 .Rs
 .%A T. Ylonen
index b0e6ed64265585ffc524e43bd14af2f7db4dc61d..e20adcd09e1dc6424979eb8ccc4bf0c0ce8300e5 100644 (file)
@@ -42,7 +42,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshd.c,v 1.276 2003/08/28 12:54:34 markus Exp $");
+RCSID("$OpenBSD: sshd.c,v 1.286 2004/02/23 12:02:33 markus Exp $");
 
 #include <openssl/dh.h>
 #include <openssl/bn.h>
@@ -110,6 +110,7 @@ extern char *__progname;
 #else
 char *__progname;
 #endif
+extern char **environ;
 
 /* Server configuration options. */
 ServerOptions options;
@@ -208,11 +209,14 @@ int startup_pipe;         /* in child */
 
 /* variables used for privilege separation */
 int use_privsep;
-struct monitor *pmonitor;
+struct monitor *pmonitor = NULL;
 
 /* message to be displayed after login */
 Buffer loginmsg;
 
+/* global authentication context */
+Authctxt *the_authctxt = NULL;
+
 /* Prototypes for various functions defined later in this file. */
 void destroy_sensitive_data(void);
 void demote_sensitive_data(void);
@@ -311,6 +315,9 @@ grace_alarm_handler(int sig)
 {
        /* XXX no idea how fix this signal handler */
 
+       if (use_privsep && pmonitor != NULL && pmonitor->m_pid > 0)
+               kill(pmonitor->m_pid, SIGALRM);
+
        /* Log error and exit. */
        fatal("Timeout before authentication for %s", get_remote_ipaddr());
 }
@@ -384,7 +391,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
            strlen(server_version_string))
            != strlen(server_version_string)) {
                logit("Could not write ident string to %s", get_remote_ipaddr());
-               fatal_cleanup();
+               cleanup_exit(255);
        }
 
        /* Read other sides version identification. */
@@ -393,7 +400,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
                if (atomicio(read, sock_in, &buf[i], 1) != 1) {
                        logit("Did not receive identification string from %s",
                            get_remote_ipaddr());
-                       fatal_cleanup();
+                       cleanup_exit(255);
                }
                if (buf[i] == '\r') {
                        buf[i] = 0;
@@ -423,7 +430,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
                close(sock_out);
                logit("Bad protocol version identification '%.100s' from %s",
                    client_version_string, get_remote_ipaddr());
-               fatal_cleanup();
+               cleanup_exit(255);
        }
        debug("Client protocol version %d.%d; client software version %.100s",
            remote_major, remote_minor, remote_version);
@@ -433,13 +440,13 @@ sshd_exchange_identification(int sock_in, int sock_out)
        if (datafellows & SSH_BUG_PROBE) {
                logit("probed from %s with %s.  Don't panic.",
                    get_remote_ipaddr(), client_version_string);
-               fatal_cleanup();
+               cleanup_exit(255);
        }
 
        if (datafellows & SSH_BUG_SCANNER) {
                logit("scanned from %s with %s.  Don't panic.",
                    get_remote_ipaddr(), client_version_string);
-               fatal_cleanup();
+               cleanup_exit(255);
        }
 
        mismatch = 0;
@@ -485,7 +492,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
                logit("Protocol major versions differ for %s: %.200s vs. %.200s",
                    get_remote_ipaddr(),
                    server_version_string, client_version_string);
-               fatal_cleanup();
+               cleanup_exit(255);
        }
 }
 
@@ -580,10 +587,9 @@ privsep_preauth_child(void)
 #endif
 }
 
-static Authctxt *
-privsep_preauth(void)
+static int
+privsep_preauth(Authctxt *authctxt)
 {
-       Authctxt *authctxt = NULL;
        int status;
        pid_t pid;
 
@@ -596,12 +602,11 @@ privsep_preauth(void)
        if (pid == -1) {
                fatal("fork of unprivileged child failed");
        } else if (pid != 0) {
-               fatal_remove_cleanup((void (*) (void *)) packet_close, NULL);
-
                debug2("Network child is on pid %ld", (long)pid);
 
                close(pmonitor->m_recvfd);
-               authctxt = monitor_child_preauth(pmonitor);
+               pmonitor->m_pid = pid;
+               monitor_child_preauth(authctxt, pmonitor);
                close(pmonitor->m_sendfd);
 
                /* Sync memory */
@@ -611,11 +616,7 @@ privsep_preauth(void)
                while (waitpid(pid, &status, 0) < 0)
                        if (errno != EINTR)
                                break;
-
-               /* Reinstall, since the child has finished */
-               fatal_add_cleanup((void (*) (void *)) packet_close, NULL);
-
-               return (authctxt);
+               return (1);
        } else {
                /* child */
 
@@ -626,17 +627,12 @@ privsep_preauth(void)
                        privsep_preauth_child();
                setproctitle("%s", "[net]");
        }
-       return (NULL);
+       return (0);
 }
 
 static void
 privsep_postauth(Authctxt *authctxt)
 {
-       extern Authctxt *x_authctxt;
-
-       /* XXX - Remote port forwarding */
-       x_authctxt = authctxt;
-
 #ifdef DISABLE_FD_PASSING
        if (1) {
 #else
@@ -662,8 +658,6 @@ privsep_postauth(Authctxt *authctxt)
        if (pmonitor->m_pid == -1)
                fatal("fork of unprivileged child failed");
        else if (pmonitor->m_pid != 0) {
-               fatal_remove_cleanup((void (*) (void *)) packet_close, NULL);
-
                debug2("User child is on pid %ld", (long)pmonitor->m_pid);
                close(pmonitor->m_recvfd);
                monitor_child_postauth(pmonitor);
@@ -688,7 +682,8 @@ static char *
 list_hostkey_types(void)
 {
        Buffer b;
-       char *p;
+       const char *p;
+       char *ret;
        int i;
 
        buffer_init(&b);
@@ -707,10 +702,10 @@ list_hostkey_types(void)
                }
        }
        buffer_append(&b, "\0", 1);
-       p = xstrdup(buffer_ptr(&b));
+       ret = xstrdup(buffer_ptr(&b));
        buffer_free(&b);
-       debug("list_hostkey_types: %s", p);
-       return p;
+       debug("list_hostkey_types: %s", ret);
+       return ret;
 }
 
 Key *
@@ -778,7 +773,8 @@ drop_connection(int startups)
 static void
 usage(void)
 {
-       fprintf(stderr, "sshd version %s\n", SSH_VERSION);
+       fprintf(stderr, "sshd version %s, %s\n",
+           SSH_VERSION, SSLeay_version(SSLEAY_VERSION));
        fprintf(stderr, "Usage: %s [options]\n", __progname);
        fprintf(stderr, "Options:\n");
        fprintf(stderr, "  -f file    Configuration file (default %s)\n", _PATH_SERVER_CONFIG_FILE);
@@ -818,11 +814,12 @@ main(int ac, char **av)
        FILE *f;
        struct addrinfo *ai;
        char ntop[NI_MAXHOST], strport[NI_MAXSERV];
+       char *line;
        int listen_sock, maxfd;
        int startup_p[2];
        int startups = 0;
-       Authctxt *authctxt;
        Key *key;
+       Authctxt *authctxt;
        int ret, key_used = 0;
 
 #ifdef HAVE_SECUREWARE
@@ -926,9 +923,11 @@ main(int ac, char **av)
                        }
                        break;
                case 'o':
-                       if (process_server_config_line(&options, optarg,
+                       line = xstrdup(optarg);
+                       if (process_server_config_line(&options, line,
                            "command-line", 0) != 0)
                                exit(1);
+                       xfree(line);
                        break;
                case '?':
                default:
@@ -1076,8 +1075,8 @@ main(int ac, char **av)
        /*
         * Clear out any supplemental groups we may have inherited.  This
         * prevents inadvertent creation of files with bad modes (in the
-        * portable version at least, it's certainly possible for PAM 
-        * to create a file, and we can't control the code in every 
+        * portable version at least, it's certainly possible for PAM
+        * to create a file, and we can't control the code in every
         * module which might be used).
         */
        if (setgroups(0, NULL) < 0)
@@ -1119,6 +1118,11 @@ main(int ac, char **av)
           unmounted if desired. */
        chdir("/");
 
+#ifndef HAVE_CYGWIN
+       /* Clear environment */
+       environ[0] = NULL;
+#endif
+
        /* ignore SIGPIPE */
        signal(SIGPIPE, SIG_IGN);
 
@@ -1187,7 +1191,7 @@ main(int ac, char **av)
 
                        /* Start listening on the port. */
                        logit("Server listening on %s port %s.", ntop, strport);
-                       if (listen(listen_sock, 5) < 0)
+                       if (listen(listen_sock, SSH_LISTEN_BACKLOG) < 0)
                                fatal("listen: %.100s", strerror(errno));
 
                }
@@ -1426,8 +1430,8 @@ main(int ac, char **av)
        signal(SIGCHLD, SIG_DFL);
        signal(SIGINT, SIG_DFL);
 
-       /* Set keepalives if requested. */
-       if (options.keepalives &&
+       /* Set SO_KEEPALIVE if requested. */
+       if (options.tcp_keep_alive &&
            setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, &on,
            sizeof(on)) < 0)
                error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
@@ -1484,21 +1488,28 @@ main(int ac, char **av)
 
        packet_set_nonblocking();
 
-        /* prepare buffers to collect authentication messages */
+       /* prepare buffers to collect authentication messages */
        buffer_init(&loginmsg);
 
+       /* allocate authentication context */
+       authctxt = xmalloc(sizeof(*authctxt));
+       memset(authctxt, 0, sizeof(*authctxt));
+
+       /* XXX global for cleanup, access from other modules */
+       the_authctxt = authctxt;
+
        if (use_privsep)
-               if ((authctxt = privsep_preauth()) != NULL)
+               if (privsep_preauth(authctxt) == 1)
                        goto authenticated;
 
        /* perform the key exchange */
        /* authenticate user and start session */
        if (compat20) {
                do_ssh2_kex();
-               authctxt = do_authentication2();
+               do_authentication2(authctxt);
        } else {
                do_ssh1_kex();
-               authctxt = do_authentication();
+               do_authentication(authctxt);
        }
        /*
         * If we use privilege separation, the unprivileged child transfers
@@ -1521,7 +1532,7 @@ main(int ac, char **av)
                        destroy_sensitive_data();
        }
 
-       /* Perform session preparation. */
+       /* Start session. */
        do_authenticated(authctxt);
 
        /* The connection has been terminated. */
@@ -1856,3 +1867,12 @@ do_ssh2_kex(void)
 #endif
        debug("KEX done");
 }
+
+/* server specific fatal cleanup */
+void
+cleanup_exit(int i)
+{
+       if (the_authctxt)
+               do_cleanup(the_authctxt);
+       _exit(i);
+}
index 0fcff892b6165e3cecdef1090a6eaf33ae04490f..d6f3e3ed858b24337bcbcc35f027bdab06ba9cb0 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: sshd_config,v 1.65 2003/08/28 12:54:34 markus Exp $
+#      $OpenBSD: sshd_config,v 1.68 2003/12/29 16:39:50 millert Exp $
 
 # This is the sshd server system-wide configuration file.  See
 # sshd_config(5) for more information.
@@ -61,6 +61,7 @@
 #KerberosAuthentication no
 #KerberosOrLocalPasswd yes
 #KerberosTicketCleanup yes
+#KerberosGetAFSToken no
 
 # Session hooks: if allowed, specify the commands to execute
 #AllowSessionHooks yes
@@ -73,8 +74,8 @@
 
 # Set this to 'yes' to enable PAM authentication (via challenge-response)
 # and session processing. Depending on your PAM configuration, this may
-# bypass the setting of 'PasswordAuthentication'
-#UsePAM yes
+# bypass the setting of 'PasswordAuthentication' and 'PermitEmptyPasswords'
+#UsePAM no
 
 #AllowTcpForwarding yes
 #GatewayPorts no
@@ -83,7 +84,7 @@
 #X11UseLocalhost yes
 #PrintMotd yes
 #PrintLastLog yes
-#KeepAlive yes
+#TCPKeepAlive yes
 #UseLogin no
 #UsePrivilegeSeparation yes
 #PermitUserEnvironment no
index bd0aec487aa7eab46061f67be7d01cca61f6b5a1..f961e73c095c5ee2b2131a552456b9fc6b76e532 100644 (file)
@@ -34,7 +34,7 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.\" $OpenBSD: sshd_config.5,v 1.25 2003/09/01 09:50:04 markus Exp $
+.\" $OpenBSD: sshd_config.5,v 1.28 2004/02/17 19:35:21 jmc Exp $
 .Dd September 25, 1999
 .Dt SSHD_CONFIG 5
 .Os
@@ -156,12 +156,12 @@ If this threshold is reached while client alive messages are being sent,
 will disconnect the client, terminating the session.
 It is important to note that the use of client alive messages is very
 different from
-.Cm KeepAlive
+.Cm TCPKeepAlive
 (below).
 The client alive messages are sent through the encrypted channel
 and therefore will not be spoofable.
 The TCP keepalive option enabled by
-.Cm KeepAlive
+.Cm TCPKeepAlive
 is spoofable.
 The client alive mechanism is valuable when the client or
 server depend on knowing when a connection has become inactive.
@@ -227,7 +227,7 @@ The default is
 .Dq no .
 .It Cm GSSAPIAuthentication
 Specifies whether user authentication based on GSSAPI is allowed.
-The default is 
+The default is
 .Dq yes .
 Note that this option applies to protocol version 2 only.
 .It Cm GSSAPICleanupCreds
@@ -304,27 +304,6 @@ or
 .Cm HostbasedAuthentication .
 The default is
 .Dq no .
-.It Cm KeepAlive
-Specifies whether the system should send TCP keepalive messages to the
-other side.
-If they are sent, death of the connection or crash of one
-of the machines will be properly noticed.
-However, this means that
-connections will die if the route is down temporarily, and some people
-find it annoying.
-On the other hand, if keepalives are not sent,
-sessions may hang indefinitely on the server, leaving
-.Dq ghost
-users and consuming server resources.
-.Pp
-The default is
-.Dq yes
-(to send keepalives), and the server will notice
-if the network goes down or the client host crashes.
-This avoids infinitely hanging sessions.
-.Pp
-To disable keepalives, the value should be set to
-.Dq no .
 .It Cm KerberosAuthentication
 Specifies whether the password provided by the user for
 .Cm PasswordAuthentication
@@ -545,13 +524,6 @@ Specifies whether public key authentication is allowed.
 The default is
 .Dq yes .
 Note that this option applies to protocol version 2 only.
-.Cm RhostsRSAAuthentication
-should be used
-instead, because it performs RSA-based host authentication in addition
-to normal rhosts or /etc/hosts.equiv authentication.
-The default is
-.Dq no .
-This option applies to protocol version 1 only.
 .It Cm RhostsRSAAuthentication
 Specifies whether rhosts or /etc/hosts.equiv authentication together
 with successful RSA host authentication is allowed.
@@ -592,6 +564,27 @@ Gives the facility code that is used when logging messages from
 The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2,
 LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.
 The default is AUTH.
+.It Cm TCPKeepAlive
+Specifies whether the system should send TCP keepalive messages to the
+other side.
+If they are sent, death of the connection or crash of one
+of the machines will be properly noticed.
+However, this means that
+connections will die if the route is down temporarily, and some people
+find it annoying.
+On the other hand, if TCP keepalives are not sent,
+sessions may hang indefinitely on the server, leaving
+.Dq ghost
+users and consuming server resources.
+.Pp
+The default is
+.Dq yes
+(to send TCP keepalive messages), and the server will notice
+if the network goes down or the client host crashes.
+This avoids infinitely hanging sessions.
+.Pp
+To disable TCP keepalive messages, the value should be set to
+.Dq no .
 .It Cm UseDNS
 Specifies whether
 .Nm sshd
@@ -620,12 +613,13 @@ If
 .Cm UsePrivilegeSeparation
 is specified, it will be disabled after authentication.
 .It Cm UsePAM
-Enables PAM authentication (via challenge-response) and session set up. 
-If you enable this, you should probably disable 
+Enables PAM authentication (via challenge-response) and session set up.
+If you enable this, you should probably disable
 .Cm PasswordAuthentication .
-If you enable 
+If you enable
 .CM UsePAM
-then you will not be able to run sshd as a non-root user.
+then you will not be able to run sshd as a non-root user.  The default is
+.Dq no .
 .It Cm UsePrivilegeSeparation
 Specifies whether
 .Nm sshd
index 3cdb3c02dd560bc7485aea8156d457e4cba4af64..318665902d3e6e44355d4793a4f8458487c20639 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: version.h,v 1.39 2003/09/16 21:02:40 markus Exp $ */
+/* $OpenBSD: version.h,v 1.40 2004/02/23 15:16:46 markus Exp $ */
 
 #ifdef GSI
 #define GSI_VERSION    " GSI"
@@ -18,6 +18,6 @@
 #define MGLUE_VERSION  ""
 #endif
 
-#define SSH_VERSION    "OpenSSH_3.7.1p2"       \
-                       " NCSA_GSSAPI_20040119" \
+#define SSH_VERSION    "OpenSSH_3.8p1"         \
+                       " NCSA_GSSAPI_20040224" \
                        GSI_VERSION KRB5_VERSION MGLUE_VERSION
This page took 0.634231 seconds and 5 git commands to generate.