]> andersk Git - gssapi-openssh.git/commitdiff
merged OpenSSH 3.7p1 to trunk OPENSSH_3_7P1_GSSAPI_20030916
authorjbasney <jbasney>
Wed, 17 Sep 2003 04:20:34 +0000 (04:20 +0000)
committerjbasney <jbasney>
Wed, 17 Sep 2003 04:20:34 +0000 (04:20 +0000)
116 files changed:
openssh/Makefile.in
openssh/README.privsep
openssh/acconfig.h
openssh/auth-krb4.c [deleted file]
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-kbdint.c
openssh/auth2-none.c
openssh/auth2-pam.c [deleted file]
openssh/auth2-pam.h [deleted file]
openssh/auth2-passwd.c
openssh/auth2-pubkey.c
openssh/auth2.c
openssh/canohost.c
openssh/cipher.c
openssh/compat.c
openssh/compat.h
openssh/configure.ac
openssh/contrib/aix/README
openssh/contrib/aix/buildbff.sh
openssh/contrib/aix/inventory.sh
openssh/defines.h
openssh/gss-genr.c
openssh/gss-serv-gsi.c
openssh/gss-serv-krb5.c
openssh/gss-serv.c
openssh/includes.h
openssh/kex.c
openssh/key.c
openssh/key.h
openssh/log.c
openssh/mdoc2man.pl [deleted file]
openssh/misc.c
openssh/monitor.c
openssh/monitor.h
openssh/monitor_fdpass.c
openssh/monitor_mm.c
openssh/monitor_wrap.c
openssh/monitor_wrap.h
openssh/msg.c
openssh/openbsd-compat/basename.c
openssh/openbsd-compat/basename.h [deleted file]
openssh/openbsd-compat/bindresvport.h [deleted file]
openssh/openbsd-compat/bsd-arc4random.h [deleted file]
openssh/openbsd-compat/bsd-getpeereid.h [deleted file]
openssh/openbsd-compat/bsd-misc.h
openssh/openbsd-compat/bsd-snprintf.h [deleted file]
openssh/openbsd-compat/daemon.h [deleted file]
openssh/openbsd-compat/dirname.h [deleted file]
openssh/openbsd-compat/fake-gai-errnos.h [deleted file]
openssh/openbsd-compat/fake-getaddrinfo.c [deleted file]
openssh/openbsd-compat/fake-getaddrinfo.h [deleted file]
openssh/openbsd-compat/fake-getnameinfo.c [deleted file]
openssh/openbsd-compat/fake-getnameinfo.h [deleted file]
openssh/openbsd-compat/fake-socket.h [deleted file]
openssh/openbsd-compat/getcwd.h [deleted file]
openssh/openbsd-compat/getgrouplist.h [deleted file]
openssh/openbsd-compat/getopt.c
openssh/openbsd-compat/getopt.h [deleted file]
openssh/openbsd-compat/inet_aton.h [deleted file]
openssh/openbsd-compat/inet_ntoa.h [deleted file]
openssh/openbsd-compat/inet_ntop.h [deleted file]
openssh/openbsd-compat/mktemp.h [deleted file]
openssh/openbsd-compat/port-aix.c
openssh/openbsd-compat/port-aix.h
openssh/openbsd-compat/port-irix.c
openssh/openbsd-compat/port-irix.h
openssh/openbsd-compat/realpath.h [deleted file]
openssh/openbsd-compat/rresvport.h [deleted file]
openssh/openbsd-compat/setenv.h [deleted file]
openssh/openbsd-compat/setproctitle.h [deleted file]
openssh/openbsd-compat/strlcat.h [deleted file]
openssh/openbsd-compat/strlcpy.h [deleted file]
openssh/openbsd-compat/strmode.h [deleted file]
openssh/openbsd-compat/strsep.h [deleted file]
openssh/openbsd-compat/sys-queue.h
openssh/openbsd-compat/vis.c
openssh/openbsd-compat/vis.h
openssh/openbsd-compat/xmmap.c
openssh/openbsd-compat/xmmap.h [deleted file]
openssh/packet.c
openssh/packet.h
openssh/progressmeter.c
openssh/radix.c [deleted file]
openssh/radix.h [deleted file]
openssh/readconf.c
openssh/readconf.h
openssh/regress/authorized_keys_root [deleted file]
openssh/regress/copy.1 [deleted file]
openssh/regress/copy.2 [deleted file]
openssh/scard-opensc.c
openssh/servconf.c
openssh/servconf.h
openssh/session.c
openssh/session.h
openssh/ssh-agent.c
openssh/ssh-gss.h
openssh/ssh-keyscan.c
openssh/ssh-keysign.8
openssh/ssh-keysign.c
openssh/ssh-rand-helper.c
openssh/ssh.1
openssh/ssh.c
openssh/ssh_config.5
openssh/sshconnect1.c
openssh/sshconnect2.c
openssh/sshd.8
openssh/sshd.c
openssh/sshd_config
openssh/sshd_config.5

index e779819d68d95799f5d8223e6fd0c9e163651a4b..775fb19105b9742a5653553942814d3052fc8bd6 100644 (file)
@@ -46,6 +46,7 @@ LIBS=@LIBS@
 LIBPAM=@LIBPAM@
 LIBWRAP=@LIBWRAP@
 AR=@AR@
+AWK=@AWK@
 RANLIB=@RANLIB@
 INSTALL=@INSTALL@
 PERL=@PERL@
@@ -62,13 +63,14 @@ 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 compat.o compress.o crc32.o deattack.o fatal.o \
-       hostfile.o log.o match.o mpaux.o nchan.o packet.o radix.o readpass.o \
-       rsa.o tildexpand.o ttymodes.o xmalloc.o atomicio.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 \
        rijndael.o ssh-dss.o ssh-rsa.o dh.o kexdh.o kexgex.o \
-       kexdhc.o kexgexc.o scard.o msg.o progressmeter.o \
-       entropy.o kexgssc.o gss-genr.o
+       kexdhc.o kexgexc.o scard.o msg.o progressmeter.o dns.o \
+       entropy.o scard-opensc.o kexgssc.o gss-genr.o
 
 SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
        sshconnect.o sshconnect1.o sshconnect2.o
@@ -81,9 +83,9 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
        auth2-none.o auth2-passwd.o auth2-pubkey.o \
        monitor_mm.o monitor.o monitor_wrap.o monitor_fdpass.o \
        kexdhs.o kexgexs.o kexgsss.o \
-       auth-krb5.o auth-krb4.o auth2-gss.o \
-       gss-serv.o gss-serv-krb5.o gss-serv-gsi.o \
-       loginrec.o auth-pam.o auth2-pam.o auth-sia.o md5crypt.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
 
 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
@@ -111,11 +113,11 @@ PATHSUBS  = \
 
 FIXPATHSCMD    = $(SED) $(PATHSUBS)
 
-all: $(CONFIGFILES) $(MANPAGES) $(TARGETS)
+all: $(CONFIGFILES) ssh_prng_cmds.out $(MANPAGES) $(TARGETS)
 
-$(LIBSSH_OBJS): config.h
-$(SSHOBJS): config.h
-$(SSHDOBJS): config.h
+$(LIBSSH_OBJS): Makefile.in config.h
+$(SSHOBJS): Makefile.in config.h
+$(SSHDOBJS): Makefile.in config.h
 
 .c.o:
        $(CC) $(CFLAGS) $(CPPFLAGS) -c $<
@@ -173,7 +175,7 @@ $(MANPAGES): $(MANPAGES_IN)
                manpage=$(srcdir)/`echo $@ | sed 's/\.out$$//'`; \
        fi; \
        if test "$(MANTYPE)" = "man"; then \
-               $(FIXPATHSCMD) $${manpage} | $(PERL) $(srcdir)/mdoc2man.pl > $@; \
+               $(FIXPATHSCMD) $${manpage} | $(AWK) -f $(srcdir)/mdoc2man.awk > $@; \
        else \
                $(FIXPATHSCMD) $${manpage} > $@; \
        fi
@@ -182,10 +184,20 @@ $(CONFIGFILES): $(CONFIGFILES_IN)
        conffile=`echo $@ | sed 's/.out$$//'`; \
        $(FIXPATHSCMD) $(srcdir)/$${conffile} > $@
 
+ssh_prng_cmds.out:     ssh_prng_cmds
+       if test ! -z "$(INSTALL_SSH_PRNG_CMDS)"; then \
+               $(PERL) $(srcdir)/fixprogs ssh_prng_cmds $(ENT); \
+       fi
+
+# fake rule to stop make trying to compile moduli.o into a binary "modulo"
+moduli:
+       echo
+
 clean:
        rm -f *.o *.a $(TARGETS) logintest config.cache config.log 
        rm -f *.out core 
        (cd openbsd-compat && $(MAKE) clean)
+       (cd regress && $(MAKE) clean)
 
 distclean:
        rm -f *.o *.a $(TARGETS) logintest config.cache config.log 
@@ -194,16 +206,14 @@ distclean:
        rm -rf autom4te.cache
        (cd openbsd-compat && $(MAKE) distclean)
        (cd scard && $(MAKE) distclean)
+       (cd regress && $(MAKE) distclean)
 
-veryclean:
+veryclean: distclean
        rm -f configure config.h.in *.0
-       rm -f *.o *.a $(TARGETS) logintest config.cache config.log 
-       rm -f *.out core
-       rm -f Makefile config.h config.status ssh_prng_cmds *~
-       (cd openbsd-compat && $(MAKE) distclean)
-       (cd scard && $(MAKE) distclean)
 
-mrproper: distclean
+mrproper: veryclean
+
+realclean: veryclean
 
 catman-do:
        @for f in $(MANPAGES_IN) ; do \
@@ -217,8 +227,8 @@ distprep: catman-do
        $(AUTORECONF)
        (cd scard && $(MAKE) -f Makefile.in distprep)
 
-install: $(CONFIGFILES) $(MANPAGES) $(TARGETS) install-files host-key check-config
-install-nokeys: $(CONFIGFILES) $(MANPAGES) $(TARGETS) install-files
+install: $(CONFIGFILES) ssh_prng_cmds.out $(MANPAGES) $(TARGETS) install-files host-key check-config
+install-nokeys: $(CONFIGFILES) ssh_prng_cmds.out $(MANPAGES) $(TARGETS) install-files
 
 check-config:
        -$(DESTDIR)$(sbindir)/sshd -t -f $(DESTDIR)$(sysconfdir)/sshd_config
@@ -292,7 +302,6 @@ install-files: scard-install
                echo "$(DESTDIR)$(sysconfdir)/sshd_config already exists, install will not overwrite"; \
        fi
        @if [ -f ssh_prng_cmds -a ! -z "$(INSTALL_SSH_PRNG_CMDS)" ]; then \
-               $(PERL) $(srcdir)/fixprogs ssh_prng_cmds $(ENT); \
                if [ ! -f $(DESTDIR)$(sysconfdir)/ssh_prng_cmds ] ; then \
                        $(INSTALL) -m 644 ssh_prng_cmds.out $(DESTDIR)$(sysconfdir)/ssh_prng_cmds; \
                else \
@@ -379,3 +388,32 @@ uninstall:
        -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
        -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8
        -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
+
+tests: $(TARGETS)
+       BUILDDIR=`pwd`; \
+       [ -d `pwd`/regress ]  ||  mkdir -p `pwd`/regress; \
+       TEST_SSH_SSH="$${BUILDDIR}/ssh"; \
+       TEST_SSH_SSHD="$${BUILDDIR}/sshd"; \
+       TEST_SSH_SSHAGENT="$${BUILDDIR}/ssh-agent"; \
+       TEST_SSH_SSHADD="$${BUILDDIR}/ssh-add"; \
+       TEST_SSH_SSHKEYGEN="$${BUILDDIR}/ssh-keygen"; \
+       TEST_SSH_SSHKEYSCAN="$${BUILDDIR}/ssh-keyscan"; \
+       TEST_SSH_SFTP="$${BUILDDIR}/sftp"; \
+       TEST_SSH_SFTPSERVER="$${BUILDDIR}/sftp-server"; \
+       cd $(srcdir)/regress || exit $$?; \
+       $(MAKE) \
+               .OBJDIR="$${BUILDDIR}/regress" \
+               .CURDIR="`pwd`" \
+               BUILDDIR="$${BUILDDIR}" \
+               OBJ="$${BUILDDIR}/regress/" \
+               PATH="$${BUILDDIR}:$${PATH}" \
+               TEST_SSH_SSH="$${TEST_SSH_SSH}" \
+               TEST_SSH_SSHD="$${TEST_SSH_SSHD}" \
+               TEST_SSH_SSHAGENT="$${TEST_SSH_SSHAGENT}" \
+               TEST_SSH_SSHADD="$${TEST_SSH_SSHADD}" \
+               TEST_SSH_SSHKEYGEN="$${TEST_SSH_SSHKEYGEN}" \
+               TEST_SSH_SSHKEYSCAN="$${TEST_SSH_SSHKEYSCAN}" \
+               TEST_SSH_SFTP="$${TEST_SSH_SFTP}" \
+               TEST_SSH_SFTPSERVER="$${TEST_SSH_SFTPSERVER}" \
+               EXEEXT="$(EXEEXT)" \
+               $@
index 581bbefc414767b3cf77d9a38c2c57840fb96fae..2f60236dbe06ea82d1921b0fddab06a945ee97e5 100644 (file)
@@ -40,8 +40,7 @@ Compression will be disabled on systems without a working mmap MAP_ANON.
 
 PAM-enabled OpenSSH is known to function with privsep on Linux.  
 It does not function on HP-UX with a trusted system
-configuration.  PAMAuthenticationViaKbdInt does not function with
-privsep.
+configuration. 
 
 On Compaq Tru64 Unix, only the pre-authentication part of privsep is
 supported.  Post-authentication privsep is disabled automatically (so
index 68c393f07fed42eeb4d406ed1d781d6aecd8d890..617bdc98111dc4806e4e5da71d182fcb95afb6ab 100644 (file)
@@ -1,5 +1,29 @@
 /* $Id$ */
 
+/*
+ * Copyright (c) 1999-2003 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.
+ */
+
 #ifndef _CONFIG_H
 #define _CONFIG_H
 
@@ -8,9 +32,19 @@
 
 @TOP@
 
+/* Define if your platform breaks doing a seteuid before a setuid */
+#undef SETEUID_BREAKS_SETUID
+
+/* Define if your setreuid() is broken */
+#undef BROKEN_SETREUID
+
+/* Define if your setregid() is broken */
+#undef BROKEN_SETREGID
+
 /* Define to a Set Process Title type if your system is */
 /* supported by bsd-setproctitle.c */
 #undef SPT_TYPE
+#undef SPT_PADCHAR
 
 /* setgroups() NOOP allowed */
 #undef SETGROUPS_NOOP
 /* Define if you want to enable AIX4's authenticate function */
 #undef WITH_AIXAUTHENTICATE
 
+/* Define if your AIX loginfailed() function takes 4 arguments (AIX >= 5.2) */
+#undef AIX_LOGINFAILED_4ARG
+
 /* Define if you have/want arrays (cluster-wide session managment, not C arrays) */
 #undef WITH_IRIX_ARRAY
 
 /* Define this if you are using the Heimdal version of Kerberos V5 */
 #undef HEIMDAL
 
-/* Define if you want Kerberos 4 support */
-#undef KRB4
-
-/* Define if you want AFS support */
-#undef AFS
-
 /* Define this if you want to use AFS/Kerberos 5 option, which runs aklog. */
 #undef AFS_KRB5
 #undef AKLOG_PATH
 /* Specify location of ssh.pid */
 #undef _PATH_SSH_PIDDIR
 
-/* Use IPv4 for connection by default, IPv6 can still if explicity asked */
-#undef IPV4_DEFAULT
-
 /* getaddrinfo is broken (if present) */
 #undef BROKEN_GETADDRINFO
 
 /* Define in your struct dirent expects you to allocate extra space for d_name */
 #undef BROKEN_ONE_BYTE_DIRENT_D_NAME
 
+/* Define if your system has /etc/default/login */
+#undef HAVE_ETC_DEFAULT_LOGIN
+
 /* Define if your getopt(3) defines and uses optreset */
 #undef HAVE_GETOPT_OPTRESET
 
 /* Silly mkstemp() */
 #undef HAVE_STRICT_MKSTEMP
 
-/* Setproctitle emulation */
-#undef SETPROCTITLE_STRATEGY
-#undef SETPROCTITLE_PS_PADDING
-
 /* Some systems put this outside of libc */
 #undef HAVE_NANOSLEEP
 
-/* Pushing STREAMS modules incorrectly acquires a controlling TTY */
-#undef STREAMS_PUSH_ACQUIRES_CTTY
+/* Define if sshd somehow reacquires a controlling TTY after setsid() */
+#undef SSHD_ACQUIRES_CTTY
+
+/* Define if cmsg_type is not passed correctly */
+#undef BROKEN_CMSG_TYPE
+
+/* Strings used in /etc/passwd to denote locked account */
+#undef LOCKED_PASSWD_STRING
+#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
 
 @BOTTOM@
 
diff --git a/openssh/auth-krb4.c b/openssh/auth-krb4.c
deleted file mode 100644 (file)
index 031dcd3..0000000
+++ /dev/null
@@ -1,373 +0,0 @@
-/*
- * Copyright (c) 1999 Dug Song.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "includes.h"
-RCSID("$OpenBSD: auth-krb4.c,v 1.24 2001/06/26 16:15:22 dugsong Exp $");
-
-#include "ssh.h"
-#include "ssh1.h"
-#include "packet.h"
-#include "xmalloc.h"
-#include "log.h"
-#include "servconf.h"
-#include "uidswap.h"
-#include "auth.h"
-
-#ifdef AFS
-#include "radix.h"
-#endif
-
-#ifdef KRB4
-extern ServerOptions options;
-
-static int
-krb4_init(void *context)
-{
-       static int cleanup_registered = 0;
-       Authctxt *authctxt = (Authctxt *)context;
-       const char *tkt_root = TKT_ROOT;
-       struct stat st;
-       int fd;
-       
-       if (!authctxt->krb4_ticket_file) {
-               /* Set unique ticket string manually since we're still root. */
-               authctxt->krb4_ticket_file = xmalloc(MAXPATHLEN);
-#ifdef AFS
-               if (lstat("/ticket", &st) != -1)
-                       tkt_root = "/ticket/";
-#endif /* AFS */
-               snprintf(authctxt->krb4_ticket_file, MAXPATHLEN, "%s%u_%d",
-                   tkt_root, authctxt->pw->pw_uid, getpid());
-               krb_set_tkt_string(authctxt->krb4_ticket_file);
-       }
-       /* Register ticket cleanup in case of fatal error. */
-       if (!cleanup_registered) {
-               fatal_add_cleanup(krb4_cleanup_proc, authctxt);
-               cleanup_registered = 1;
-       }
-       /* Try to create our ticket file. */
-       if ((fd = mkstemp(authctxt->krb4_ticket_file)) != -1) {
-               close(fd);
-               return (1);
-       }
-       /* Ticket file exists - make sure user owns it (just passed ticket). */
-       if (lstat(authctxt->krb4_ticket_file, &st) != -1) {
-               if (st.st_mode == (S_IFREG | S_IRUSR | S_IWUSR) &&
-                   st.st_uid == authctxt->pw->pw_uid)
-                       return (1);
-       }
-       /* Failure - cancel cleanup function, leaving ticket for inspection. */
-       log("WARNING: bad ticket file %s", authctxt->krb4_ticket_file);
-       
-       fatal_remove_cleanup(krb4_cleanup_proc, authctxt);
-       cleanup_registered = 0;
-       
-       xfree(authctxt->krb4_ticket_file);
-       authctxt->krb4_ticket_file = NULL;
-       
-       return (0);
-}
-
-/*
- * try krb4 authentication,
- * return 1 on success, 0 on failure, -1 if krb4 is not available
- */
-int
-auth_krb4_password(Authctxt *authctxt, const char *password)
-{
-       AUTH_DAT adata;
-       KTEXT_ST tkt;
-       struct hostent *hp;
-       struct passwd *pw;
-       char localhost[MAXHOSTNAMELEN], phost[INST_SZ], realm[REALM_SZ];
-       u_int32_t faddr;
-       int r;
-       
-       if ((pw = authctxt->pw) == NULL)
-               return (0);
-       
-       /*
-        * Try Kerberos password authentication only for non-root
-        * users and only if Kerberos is installed.
-        */
-       if (pw->pw_uid != 0 && krb_get_lrealm(realm, 1) == KSUCCESS) {
-               /* Set up our ticket file. */
-               if (!krb4_init(authctxt)) {
-                       log("Couldn't initialize Kerberos ticket file for %s!",
-                           pw->pw_name);
-                       goto failure;
-               }
-               /* Try to get TGT using our password. */
-               r = krb_get_pw_in_tkt((char *) pw->pw_name, "", realm,
-                   "krbtgt", realm, DEFAULT_TKT_LIFE, (char *)password);
-               if (r != INTK_OK) {
-                       debug("Kerberos v4 password authentication for %s "
-                           "failed: %s", pw->pw_name, krb_err_txt[r]);
-                       goto failure;
-               }
-               /* Successful authentication. */
-               chown(tkt_string(), pw->pw_uid, pw->pw_gid);
-               
-               /*
-                * Now that we have a TGT, try to get a local
-                * "rcmd" ticket to ensure that we are not talking
-                * to a bogus Kerberos server.
-                */
-               gethostname(localhost, sizeof(localhost));
-               strlcpy(phost, (char *)krb_get_phost(localhost),
-                   sizeof(phost));
-               r = krb_mk_req(&tkt, KRB4_SERVICE_NAME, phost, realm, 33);
-               
-               if (r == KSUCCESS) {
-                       if ((hp = gethostbyname(localhost)) == NULL) {
-                               log("Couldn't get local host address!");
-                               goto failure;
-                       }
-                       memmove((void *)&faddr, (void *)hp->h_addr,
-                           sizeof(faddr));
-                       
-                       /* Verify our "rcmd" ticket. */
-                       r = krb_rd_req(&tkt, KRB4_SERVICE_NAME, phost,
-                           faddr, &adata, "");
-                       if (r == RD_AP_UNDEC) {
-                               /*
-                                * Probably didn't have a srvtab on
-                                * localhost. Disallow login.
-                                */
-                               log("Kerberos v4 TGT for %s unverifiable, "
-                                   "no srvtab installed? krb_rd_req: %s",
-                                   pw->pw_name, krb_err_txt[r]);
-                               goto failure;
-                       } else if (r != KSUCCESS) {
-                               log("Kerberos v4 %s ticket unverifiable: %s",
-                                   KRB4_SERVICE_NAME, krb_err_txt[r]);
-                               goto failure;
-                       }
-               } else if (r == KDC_PR_UNKNOWN) {
-                       /*
-                        * Disallow login if no rcmd service exists, and
-                        * log the error.
-                        */
-                       log("Kerberos v4 TGT for %s unverifiable: %s; %s.%s "
-                           "not registered, or srvtab is wrong?", pw->pw_name,
-                           krb_err_txt[r], KRB4_SERVICE_NAME, phost);
-                       goto failure;
-               } else {
-                       /*
-                        * TGT is bad, forget it. Possibly spoofed!
-                        */
-                       debug("WARNING: Kerberos v4 TGT possibly spoofed "
-                           "for %s: %s", pw->pw_name, krb_err_txt[r]);
-                       goto failure;
-               }
-               /* Authentication succeeded. */
-               return (1);
-       } else
-               /* Logging in as root or no local Kerberos realm. */
-               debug("Unable to authenticate to Kerberos.");
-       
- failure:
-       krb4_cleanup_proc(authctxt);
-       
-       if (!options.kerberos_or_local_passwd)
-               return (0);
-       
-       /* Fall back to ordinary passwd authentication. */
-       return (-1);
-}
-
-void
-krb4_cleanup_proc(void *context)
-{
-       Authctxt *authctxt = (Authctxt *)context;
-       debug("krb4_cleanup_proc called");
-       if (authctxt->krb4_ticket_file) {
-               (void) dest_tkt();
-               xfree(authctxt->krb4_ticket_file);
-               authctxt->krb4_ticket_file = NULL;
-       }
-}
-
-int
-auth_krb4(Authctxt *authctxt, KTEXT auth, char **client)
-{
-       AUTH_DAT adat = {0};
-       KTEXT_ST reply;
-       Key_schedule schedule;
-       struct sockaddr_in local, foreign;
-       char instance[INST_SZ];
-       socklen_t slen;
-       u_int cksum;
-       int r, s;
-       
-       s = packet_get_connection_in();
-       
-       slen = sizeof(local);
-       memset(&local, 0, sizeof(local));
-       if (getsockname(s, (struct sockaddr *) & local, &slen) < 0)
-               debug("getsockname failed: %.100s", strerror(errno));
-       slen = sizeof(foreign);
-       memset(&foreign, 0, sizeof(foreign));
-       if (getpeername(s, (struct sockaddr *) & foreign, &slen) < 0) {
-               debug("getpeername failed: %.100s", strerror(errno));
-               fatal_cleanup();
-       }
-       instance[0] = '*';
-       instance[1] = 0;
-       
-       /* Get the encrypted request, challenge, and session key. */
-       if ((r = krb_rd_req(auth, KRB4_SERVICE_NAME, instance,
-           0, &adat, ""))) {
-               debug("Kerberos v4 krb_rd_req: %.100s", krb_err_txt[r]);
-               return (0);
-       }
-       des_key_sched((des_cblock *) adat.session, schedule);
-       
-       *client = xmalloc(MAX_K_NAME_SZ);
-       (void) snprintf(*client, MAX_K_NAME_SZ, "%s%s%s@%s", adat.pname,
-           *adat.pinst ? "." : "", adat.pinst, adat.prealm);
-       
-       /* Check ~/.klogin authorization now. */
-       if (kuserok(&adat, authctxt->user) != KSUCCESS) {
-               log("Kerberos v4 .klogin authorization failed for %s to "
-                   "account %s", *client, authctxt->user);
-               xfree(*client);
-               return (0);
-       }
-       /* Increment the checksum, and return it encrypted with the
-          session key. */
-       cksum = adat.checksum + 1;
-       cksum = htonl(cksum);
-       
-       /* If we can't successfully encrypt the checksum, we send back an
-          empty message, admitting our failure. */
-       if ((r = krb_mk_priv((u_char *) & cksum, reply.dat, sizeof(cksum) + 1,
-           schedule, &adat.session, &local, &foreign)) < 0) {
-               debug("Kerberos v4 mk_priv: (%d) %s", r, krb_err_txt[r]);
-               reply.dat[0] = 0;
-               reply.length = 0;
-       } else
-               reply.length = r;
-       
-       /* Clear session key. */
-       memset(&adat.session, 0, sizeof(&adat.session));
-       
-       packet_start(SSH_SMSG_AUTH_KERBEROS_RESPONSE);
-       packet_put_string((char *) reply.dat, reply.length);
-       packet_send();
-       packet_write_wait();
-       return (1);
-}
-#endif /* KRB4 */
-
-#ifdef AFS
-int
-auth_krb4_tgt(Authctxt *authctxt, const char *string)
-{
-       CREDENTIALS creds;
-       struct passwd *pw;
-       
-       if ((pw = authctxt->pw) == NULL)
-               goto failure;
-       
-       temporarily_use_uid(pw);
-       
-       if (!radix_to_creds(string, &creds)) {
-               log("Protocol error decoding Kerberos v4 TGT");
-               goto failure;
-       }
-       if (strncmp(creds.service, "", 1) == 0) /* backward compatibility */
-               strlcpy(creds.service, "krbtgt", sizeof creds.service);
-       
-       if (strcmp(creds.service, "krbtgt")) {
-               log("Kerberos v4 TGT (%s%s%s@%s) rejected for %s",
-                   creds.pname, creds.pinst[0] ? "." : "", creds.pinst,
-                   creds.realm, pw->pw_name);
-               goto failure;
-       }
-       if (!krb4_init(authctxt))
-               goto failure;
-       
-       if (in_tkt(creds.pname, creds.pinst) != KSUCCESS)
-               goto failure;
-       
-       if (save_credentials(creds.service, creds.instance, creds.realm,
-           creds.session, creds.lifetime, creds.kvno, &creds.ticket_st,
-           creds.issue_date) != KSUCCESS) {
-               debug("Kerberos v4 TGT refused: couldn't save credentials");
-               goto failure;
-       }
-       /* Successful authentication, passed all checks. */
-       chown(tkt_string(), pw->pw_uid, pw->pw_gid);
-       
-       debug("Kerberos v4 TGT accepted (%s%s%s@%s)",
-           creds.pname, creds.pinst[0] ? "." : "", creds.pinst, creds.realm);
-       memset(&creds, 0, sizeof(creds));
-       
-       restore_uid();
-       
-       return (1);
-       
- failure:
-       krb4_cleanup_proc(authctxt);
-       memset(&creds, 0, sizeof(creds));
-       restore_uid();
-       
-       return (0);
-}
-
-int
-auth_afs_token(Authctxt *authctxt, const char *token_string)
-{
-       CREDENTIALS creds;
-       struct passwd *pw;
-       uid_t uid;
-       
-       if ((pw = authctxt->pw) == NULL)
-               return (0);
-       
-       if (!radix_to_creds(token_string, &creds)) {
-               log("Protocol error decoding AFS token");
-               return (0);
-       }
-       if (strncmp(creds.service, "", 1) == 0) /* backward compatibility */
-               strlcpy(creds.service, "afs", sizeof creds.service);
-       
-       if (strncmp(creds.pname, "AFS ID ", 7) == 0)
-               uid = atoi(creds.pname + 7);
-       else
-               uid = pw->pw_uid;
-       
-       if (kafs_settoken(creds.realm, uid, &creds)) {
-               log("AFS token (%s@%s) rejected for %s",
-                   creds.pname, creds.realm, pw->pw_name);
-               memset(&creds, 0, sizeof(creds));
-               return (0);
-       }
-       debug("AFS token accepted (%s@%s)", creds.pname, creds.realm);
-       memset(&creds, 0, sizeof(creds));
-       
-       return (1);
-}
-#endif /* AFS */
index e3e2d9751f0867018f58a57cc1abc782cec0a716..0aa5195b892f0a59cd92bd63990d3c868045272f 100644 (file)
@@ -28,7 +28,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth-krb5.c,v 1.10 2002/11/21 23:03:51 deraadt Exp $");
+RCSID("$OpenBSD: auth-krb5.c,v 1.12 2003/08/28 12:54:34 markus Exp $");
 
 #include "ssh.h"
 #include "ssh1.h"
@@ -40,10 +40,8 @@ RCSID("$OpenBSD: auth-krb5.c,v 1.10 2002/11/21 23:03:51 deraadt Exp $");
 #include "auth.h"
 
 #ifdef KRB5
+
 #include <krb5.h>
-#ifndef HEIMDAL
-#define krb5_get_err_text(context,code) error_message(code)
-#endif /* !HEIMDAL */
 
 extern ServerOptions    options;
 
@@ -67,193 +65,6 @@ krb5_init(void *context)
        return (0);
 }
 
-/*
- * Try krb5 authentication. server_user is passed for logging purposes
- * only, in auth is received ticket, in client is returned principal
- * from the ticket
- */
-int
-auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *reply)
-{
-       krb5_error_code problem;
-       krb5_principal server;
-       krb5_ticket *ticket;
-       int fd, ret;
-
-       ret = 0;
-       server = NULL;
-       ticket = NULL;
-       reply->length = 0;
-
-       problem = krb5_init(authctxt);
-       if (problem)
-               goto err;
-
-       problem = krb5_auth_con_init(authctxt->krb5_ctx,
-           &authctxt->krb5_auth_ctx);
-       if (problem)
-               goto err;
-
-       fd = packet_get_connection_in();
-#ifdef HEIMDAL
-       problem = krb5_auth_con_setaddrs_from_fd(authctxt->krb5_ctx,
-           authctxt->krb5_auth_ctx, &fd);
-#else
-       problem = krb5_auth_con_genaddrs(authctxt->krb5_ctx, 
-           authctxt->krb5_auth_ctx,fd,
-           KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR |
-           KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR);
-#endif
-       if (problem)
-               goto err;
-
-       problem = krb5_sname_to_principal(authctxt->krb5_ctx, NULL, NULL,
-           KRB5_NT_SRV_HST, &server);
-       if (problem)
-               goto err;
-
-       problem = krb5_rd_req(authctxt->krb5_ctx, &authctxt->krb5_auth_ctx,
-           auth, server, NULL, NULL, &ticket);
-       if (problem)
-               goto err;
-
-#ifdef HEIMDAL
-       problem = krb5_copy_principal(authctxt->krb5_ctx, ticket->client,
-           &authctxt->krb5_user);
-#else
-       problem = krb5_copy_principal(authctxt->krb5_ctx, 
-                                     ticket->enc_part2->client,
-                                     &authctxt->krb5_user);
-#endif
-       if (problem)
-               goto err;
-
-       /* if client wants mutual auth */
-       problem = krb5_mk_rep(authctxt->krb5_ctx, authctxt->krb5_auth_ctx,
-           reply);
-       if (problem)
-               goto err;
-
-       /* Check .k5login authorization now. */
-       if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user,
-           authctxt->pw->pw_name))
-               goto err;
-
-       if (client)
-               krb5_unparse_name(authctxt->krb5_ctx, authctxt->krb5_user,
-                   client);
-
-       ret = 1;
- err:
-       if (server)
-               krb5_free_principal(authctxt->krb5_ctx, server);
-       if (ticket)
-               krb5_free_ticket(authctxt->krb5_ctx, ticket);
-       if (!ret && reply->length) {
-               xfree(reply->data);
-               memset(reply, 0, sizeof(*reply));
-       }
-
-       if (problem) {
-               if (authctxt->krb5_ctx != NULL)
-                       debug("Kerberos v5 authentication failed: %s",
-                           krb5_get_err_text(authctxt->krb5_ctx, problem));
-               else
-                       debug("Kerberos v5 authentication failed: %d",
-                           problem);
-       }
-
-       return (ret);
-}
-
-int
-auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt)
-{
-       krb5_error_code problem;
-       krb5_ccache ccache = NULL;
-       char *pname;
-       krb5_creds **creds;
-
-       if (authctxt->pw == NULL || authctxt->krb5_user == NULL)
-               return (0);
-
-       temporarily_use_uid(authctxt->pw);
-
-#ifdef HEIMDAL
-       problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_fcc_ops, &ccache);
-#else
-{
-       char ccname[40];
-       int tmpfd;
-       
-       snprintf(ccname,sizeof(ccname),"FILE:/tmp/krb5cc_%d_XXXXXX",geteuid());
-       
-       if ((tmpfd = mkstemp(ccname+strlen("FILE:")))==-1) {
-               log("mkstemp(): %.100s", strerror(errno));
-               problem = errno;
-               goto fail;
-       }
-       if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) {
-               log("fchmod(): %.100s", strerror(errno));
-               close(tmpfd);
-               problem = errno;
-               goto fail;
-       }
-       close(tmpfd);
-       problem = krb5_cc_resolve(authctxt->krb5_ctx, ccname, &ccache);
-}
-#endif
-       if (problem)
-               goto fail;
-
-       problem = krb5_cc_initialize(authctxt->krb5_ctx, ccache,
-           authctxt->krb5_user);
-       if (problem)
-               goto fail;
-
-#ifdef HEIMDAL
-       problem = krb5_rd_cred2(authctxt->krb5_ctx, authctxt->krb5_auth_ctx,
-           ccache, tgt);
-       if (problem)
-               goto fail;
-#else
-       problem = krb5_rd_cred(authctxt->krb5_ctx, authctxt->krb5_auth_ctx,
-           tgt, &creds, NULL);
-       if (problem)
-               goto fail;
-       problem = krb5_cc_store_cred(authctxt->krb5_ctx, ccache, *creds);
-       if (problem)
-               goto fail;
-#endif
-
-       authctxt->krb5_fwd_ccache = ccache;
-       ccache = NULL;
-
-       authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
-
-       problem = krb5_unparse_name(authctxt->krb5_ctx, authctxt->krb5_user,
-           &pname);
-       if (problem)
-               goto fail;
-
-       debug("Kerberos v5 TGT accepted (%s)", pname);
-
-       restore_uid();
-
-       return (1);
-
- fail:
-       if (problem)
-               debug("Kerberos v5 TGT passing failed: %s",
-                   krb5_get_err_text(authctxt->krb5_ctx, problem));
-       if (ccache)
-               krb5_cc_destroy(authctxt->krb5_ctx, ccache);
-
-       restore_uid();
-
-       return (0);
-}
-
 int
 auth_krb5_password(Authctxt *authctxt, const char *password)
 {
@@ -264,6 +75,7 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
        int tmpfd;
 #endif 
        krb5_error_code problem;
+       krb5_ccache ccache = NULL;
 
        if (authctxt->pw == NULL)
                return (0);
@@ -280,23 +92,35 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
                goto out;
 
 #ifdef HEIMDAL
-       problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_mcc_ops,
-           &authctxt->krb5_fwd_ccache);
+       problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_mcc_ops, &ccache);
        if (problem)
                goto out;
 
-       problem = krb5_cc_initialize(authctxt->krb5_ctx,
-           authctxt->krb5_fwd_ccache, authctxt->krb5_user);
+       problem = krb5_cc_initialize(authctxt->krb5_ctx, ccache,
+               authctxt->krb5_user);
        if (problem)
                goto out;
 
        restore_uid();
+       
        problem = krb5_verify_user(authctxt->krb5_ctx, authctxt->krb5_user,
-           authctxt->krb5_fwd_ccache, password, 1, NULL);
+           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)
+               goto out;
+
+       problem = krb5_cc_copy_cache(authctxt->krb5_ctx, ccache,
+           authctxt->krb5_fwd_ccache);
+       krb5_cc_destroy(authctxt->krb5_ctx, ccache);
+       ccache = NULL;
+       if (problem)
+               goto out;
 
 #else
        problem = krb5_get_init_creds_password(authctxt->krb5_ctx, &creds,
@@ -326,13 +150,13 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
        snprintf(ccname,sizeof(ccname),"FILE:/tmp/krb5cc_%d_XXXXXX",geteuid());
        
        if ((tmpfd = mkstemp(ccname+strlen("FILE:")))==-1) {
-               log("mkstemp(): %.100s", strerror(errno));
+               logit("mkstemp(): %.100s", strerror(errno));
                problem = errno;
                goto out;
        }
        
        if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) {
-               log("fchmod(): %.100s", strerror(errno));
+               logit("fchmod(): %.100s", strerror(errno));
                close(tmpfd);
                problem = errno;
                goto out;
@@ -360,6 +184,9 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
        restore_uid();
 
        if (problem) {
+               if (ccache)
+                       krb5_cc_destroy(authctxt->krb5_ctx, ccache);
+
                if (authctxt->krb5_ctx != NULL && problem!=-1)
                        debug("Kerberos password authentication failed: %s",
                            krb5_get_err_text(authctxt->krb5_ctx, problem));
@@ -391,11 +218,6 @@ krb5_cleanup_proc(void *context)
                krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user);
                authctxt->krb5_user = NULL;
        }
-       if (authctxt->krb5_auth_ctx) {
-               krb5_auth_con_free(authctxt->krb5_ctx,
-                   authctxt->krb5_auth_ctx);
-               authctxt->krb5_auth_ctx = NULL;
-       }
        if (authctxt->krb5_ctx) {
                krb5_free_context(authctxt->krb5_ctx);
                authctxt->krb5_ctx = NULL;
index da74bc0a7f9b901ed30823f3c7dd21c57223e653..bc1af4663a007ec84ca2deedbcd2998ea962dbdf 100644 (file)
@@ -1,5 +1,11 @@
-/*
- * Copyright (c) 2000 Damien Miller.  All rights reserved.
+/*-
+ * Copyright (c) 2002 Networks Associates Technology, Inc.
+ * All rights reserved.
+ *
+ * This software was developed for the FreeBSD Project by ThinkSec AS and
+ * NAI Labs, the Security Research Division of Network Associates, Inc.
+ * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
+ * DARPA CHATS research program.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  *    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.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
+/* Based on $FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des Exp $ */
 #include "includes.h"
+RCSID("$Id$");
 
 #ifdef USE_PAM
-#include "xmalloc.h"
-#include "log.h"
+#include <security/pam_appl.h>
+
 #include "auth.h"
-#include "auth-options.h"
 #include "auth-pam.h"
-#include "servconf.h"
+#include "buffer.h"
+#include "bufaux.h"
 #include "canohost.h"
+#include "log.h"
+#include "monitor_wrap.h"
+#include "msg.h"
+#include "packet.h"
 #include "readpass.h"
+#include "servconf.h"
+#include "ssh2.h"
+#include "xmalloc.h"
+#include "auth-options.h"
 
-extern char *__progname;
+extern ServerOptions options;
 
-extern int use_privsep;
+#define __unused
 
-RCSID("$Id$");
+#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 
+ * (e.g. Linux)
+ */
+typedef pthread_t sp_pthread_t; 
+#else
+/*
+ * Simulate threads with processes.
+ */
+typedef pid_t sp_pthread_t;
 
-#define NEW_AUTHTOK_MSG \
-       "Warning: Your password has expired, please change it now."
-#define NEW_AUTHTOK_MSG_PRIVSEP \
-       "Your password has expired, the session cannot proceed."
+static void
+pthread_exit(void *value __unused)
+{
+       _exit(0);
+}
 
-static int do_pam_conversation(int num_msg, const struct pam_message **msg,
-       struct pam_response **resp, void *appdata_ptr);
+static int
+pthread_create(sp_pthread_t *thread, const void *attr __unused,
+    void *(*thread_start)(void *), void *arg)
+{
+       pid_t pid;
+
+       switch ((pid = fork())) {
+       case -1:
+               error("fork(): %s", strerror(errno));
+               return (-1);
+       case 0:
+               thread_start(arg);
+               _exit(1);
+       default:
+               *thread = pid;
+               return (0);
+       }
+}
 
-/* module-local variables */
-static struct pam_conv conv = {
-       (int (*)())do_pam_conversation,
-       NULL
-};
-static char *__pam_msg = NULL;
-static pam_handle_t *__pamh = NULL;
-static const char *__pampasswd = NULL;
-
-/* states for do_pam_conversation() */
-enum { INITIAL_LOGIN, OTHER } pamstate = INITIAL_LOGIN;
-/* remember whether pam_acct_mgmt() returned PAM_NEW_AUTHTOK_REQD */
-static int password_change_required = 0;
-/* remember whether the last pam_authenticate() succeeded or not */
-static int was_authenticated = 0;
-
-/* Remember what has been initialised */
-static int session_opened = 0;
-static int creds_set = 0;
-
-/* accessor which allows us to switch conversation structs according to
- * the authentication method being used */
-void do_pam_set_conv(struct pam_conv *conv)
+static int
+pthread_cancel(sp_pthread_t thread)
 {
-       pam_set_item(__pamh, PAM_CONV, conv);
+       return (kill(thread, SIGTERM));
 }
 
-/* start an authentication run */
-int do_pam_authenticate(int flags)
+static int
+pthread_join(sp_pthread_t thread, void **value __unused)
 {
-       int retval = pam_authenticate(__pamh, flags);
-       was_authenticated = (retval == PAM_SUCCESS);
-       return retval;
+       int status;
+
+       waitpid(thread, &status, 0);
+       return (status);
 }
+#endif
+
+
+static pam_handle_t *sshpam_handle;
+static int sshpam_err;
+static int sshpam_authenticated;
+static int sshpam_new_authtok_reqd;
+static int sshpam_session_open;
+static int sshpam_cred_established;
+
+struct pam_ctxt {
+       sp_pthread_t     pam_thread;
+       int              pam_psock;
+       int              pam_csock;
+       int              pam_done;
+};
+
+static void sshpam_free_ctx(void *);
 
 /*
- * PAM conversation function.
- * There are two states this can run in.
- *
- * INITIAL_LOGIN mode simply feeds the password from the client into
- * PAM in response to PAM_PROMPT_ECHO_OFF, and collects output
- * messages with into __pam_msg.  This is used during initial
- * authentication to bypass the normal PAM password prompt.
- *
- * OTHER mode handles PAM_PROMPT_ECHO_OFF with read_passphrase()
- * and outputs messages to stderr. This mode is used if pam_chauthtok()
- * is called to update expired passwords.
+ * Conversation function for authentication thread.
  */
-static int do_pam_conversation(int num_msg, const struct pam_message **msg,
-       struct pam_response **resp, void *appdata_ptr)
+static int
+sshpam_thread_conv(int n, const struct pam_message **msg,
+    struct pam_response **resp, void *data)
 {
-       struct pam_response *reply;
-       int count;
-       char buf[1024];
-
-       /* PAM will free this later */
-       reply = xmalloc(num_msg * sizeof(*reply));
-
-       for (count = 0; count < num_msg; count++) {
-               if (pamstate == INITIAL_LOGIN) {
-                       /*
-                        * We can't use stdio yet, queue messages for 
-                        * printing later
-                        */
-                       switch(PAM_MSG_MEMBER(msg, count, msg_style)) {
-                       case PAM_PROMPT_ECHO_ON:
-                               xfree(reply);
-                               return PAM_CONV_ERR;
-                       case PAM_PROMPT_ECHO_OFF:
-                               if (__pampasswd == NULL) {
-                                       xfree(reply);
-                                       return PAM_CONV_ERR;
-                               }
-                               reply[count].resp = xstrdup(__pampasswd);
-                               reply[count].resp_retcode = PAM_SUCCESS;
-                               break;
-                       case PAM_ERROR_MSG:
-                       case PAM_TEXT_INFO:
-                               if (PAM_MSG_MEMBER(msg, count, msg) != NULL) {
-                                       message_cat(&__pam_msg, 
-                                           PAM_MSG_MEMBER(msg, count, msg));
-                               }
-                               reply[count].resp = xstrdup("");
-                               reply[count].resp_retcode = PAM_SUCCESS;
-                               break;
-                       default:
-                               xfree(reply);
-                               return PAM_CONV_ERR;
-                       }
-               } else {
-                       /*
-                        * stdio is connected, so interact directly
-                        */
-                       switch(PAM_MSG_MEMBER(msg, count, msg_style)) {
-                       case PAM_PROMPT_ECHO_ON:
-                               fputs(PAM_MSG_MEMBER(msg, count, msg), stderr);
-                               fgets(buf, sizeof(buf), stdin);
-                               reply[count].resp = xstrdup(buf);
-                               reply[count].resp_retcode = PAM_SUCCESS;
-                               break;
-                       case PAM_PROMPT_ECHO_OFF:
-                               reply[count].resp = 
-                                   read_passphrase(PAM_MSG_MEMBER(msg, count,
-                                       msg), RP_ALLOW_STDIN);
-                               reply[count].resp_retcode = PAM_SUCCESS;
-                               break;
-                       case PAM_ERROR_MSG:
-                       case PAM_TEXT_INFO:
-                               if (PAM_MSG_MEMBER(msg, count, msg) != NULL)
-                                       fprintf(stderr, "%s\n", 
-                                           PAM_MSG_MEMBER(msg, count, msg));
-                               reply[count].resp = xstrdup("");
-                               reply[count].resp_retcode = PAM_SUCCESS;
-                               break;
-                       default:
-                               xfree(reply);
-                               return PAM_CONV_ERR;
-                       }
+       Buffer buffer;
+       struct pam_ctxt *ctxt;
+       int i;
+
+       ctxt = data;
+       if (n <= 0 || n > PAM_MAX_NUM_MSG)
+               return (PAM_CONV_ERR);
+       *resp = xmalloc(n * sizeof **resp);
+       buffer_init(&buffer);
+       for (i = 0; i < n; ++i) {
+               resp[i]->resp_retcode = 0;
+               resp[i]->resp = NULL;
+               switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
+               case PAM_PROMPT_ECHO_OFF:
+                       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 (buffer_get_char(&buffer) != PAM_AUTHTOK)
+                               goto fail;
+                       resp[i]->resp = buffer_get_string(&buffer, NULL);
+                       break;
+               case PAM_PROMPT_ECHO_ON:
+                       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 (buffer_get_char(&buffer) != PAM_AUTHTOK)
+                               goto fail;
+                       resp[i]->resp = buffer_get_string(&buffer, NULL);
+                       break;
+               case PAM_ERROR_MSG:
+                       buffer_put_cstring(&buffer, PAM_MSG_MEMBER(msg, i, msg));
+                       ssh_msg_send(ctxt->pam_csock, 
+                           PAM_MSG_MEMBER(msg, i, msg_style), &buffer);
+                       break;
+               case PAM_TEXT_INFO:
+                       buffer_put_cstring(&buffer, PAM_MSG_MEMBER(msg, i, msg));
+                       ssh_msg_send(ctxt->pam_csock, 
+                           PAM_MSG_MEMBER(msg, i, msg_style), &buffer);
+                       break;
+               default:
+                       goto fail;
                }
+               buffer_clear(&buffer);
        }
-
-       *resp = reply;
-
-       return PAM_SUCCESS;
+       buffer_free(&buffer);
+       return (PAM_SUCCESS);
+ fail:
+       while (i)
+               xfree(resp[--i]);
+       xfree(*resp);
+       *resp = NULL;
+       buffer_free(&buffer);
+       return (PAM_CONV_ERR);
 }
 
-/* Called at exit to cleanly shutdown PAM */
-void do_pam_cleanup_proc(void *context)
+/*
+ * Authentication thread.
+ */
+static void *
+sshpam_thread(void *ctxtp)
 {
-       int pam_retval = PAM_SUCCESS;
+       struct pam_ctxt *ctxt = ctxtp;
+       Buffer buffer;
+       struct pam_conv sshpam_conv;
+#ifndef USE_POSIX_THREADS
+       const char *pam_user;
+
+       pam_get_item(sshpam_handle, PAM_USER, (const void **)&pam_user);
+       setproctitle("%s [pam]", pam_user);
+#endif
 
-       if (__pamh && session_opened) {
-               pam_retval = pam_close_session(__pamh, 0);
-               if (pam_retval != PAM_SUCCESS)
-                       log("Cannot close PAM session[%d]: %.200s",
-                           pam_retval, PAM_STRERROR(__pamh, pam_retval));
-       }
+       sshpam_conv.conv = sshpam_thread_conv;
+       sshpam_conv.appdata_ptr = ctxt;
+
+       buffer_init(&buffer);
+       sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
+           (const void *)&sshpam_conv);
+       if (sshpam_err != PAM_SUCCESS)
+               goto auth_fail;
+       sshpam_err = pam_authenticate(sshpam_handle, 0);
+       if (sshpam_err != PAM_SUCCESS)
+               goto auth_fail;
+       buffer_put_cstring(&buffer, "OK");
+       ssh_msg_send(ctxt->pam_csock, sshpam_err, &buffer);
+       buffer_free(&buffer);
+       pthread_exit(NULL);
+
+ auth_fail:
+       buffer_put_cstring(&buffer,
+           pam_strerror(sshpam_handle, sshpam_err));
+       ssh_msg_send(ctxt->pam_csock, PAM_AUTH_ERR, &buffer);
+       buffer_free(&buffer);
+       pthread_exit(NULL);
+       
+       return (NULL); /* Avoid warning for non-pthread case */
+}
 
-       if (__pamh && creds_set) {
-               pam_retval = pam_setcred(__pamh, PAM_DELETE_CRED);
-               if (pam_retval != PAM_SUCCESS)
-                       debug("Cannot delete credentials[%d]: %.200s", 
-                           pam_retval, PAM_STRERROR(__pamh, pam_retval));
-       }
+static void
+sshpam_thread_cleanup(void *ctxtp)
+{
+       struct pam_ctxt *ctxt = ctxtp;
 
-       if (__pamh) {
-               pam_retval = pam_end(__pamh, pam_retval);
-               if (pam_retval != PAM_SUCCESS)
-                       log("Cannot release PAM authentication[%d]: %.200s",
-                           pam_retval, PAM_STRERROR(__pamh, pam_retval));
-       }
+       pthread_cancel(ctxt->pam_thread);
+       pthread_join(ctxt->pam_thread, NULL);
+       close(ctxt->pam_psock);
+       close(ctxt->pam_csock);
 }
 
-/* Attempt password authentication using PAM */
-int auth_pam_password(Authctxt *authctxt, const char *password)
+static int
+sshpam_null_conv(int n, const struct pam_message **msg,
+    struct pam_response **resp, void *data)
 {
-       extern ServerOptions options;
-       int pam_retval;
-       struct passwd *pw = authctxt->pw;
+       return (PAM_CONV_ERR);
+}
 
-       do_pam_set_conv(&conv);
+static struct pam_conv null_conv = { sshpam_null_conv, NULL };
 
-       __pampasswd = password;
+static void
+sshpam_cleanup(void *arg)
+{
+       (void)arg;
+       debug("PAM: cleanup");
+       pam_set_item(sshpam_handle, PAM_CONV, (const void *)&null_conv);
+       if (sshpam_cred_established) {
+               pam_setcred(sshpam_handle, PAM_DELETE_CRED);
+               sshpam_cred_established = 0;
+       }
+       if (sshpam_session_open) {
+               pam_close_session(sshpam_handle, PAM_SILENT);
+               sshpam_session_open = 0;
+       }
+       sshpam_authenticated = sshpam_new_authtok_reqd = 0;
+       pam_end(sshpam_handle, sshpam_err);
+       sshpam_handle = NULL;
+}
 
-       pamstate = INITIAL_LOGIN;
-       pam_retval = do_pam_authenticate(
-           options.permit_empty_passwd == 0 ? PAM_DISALLOW_NULL_AUTHTOK : 0);
-       if (pam_retval == PAM_SUCCESS && pw) {
-               debug("PAM password authentication accepted for "
-                   "%.100s", pw->pw_name);
-               return 1;
-       } else {
-               debug("PAM password authentication failed for "
-                   "%.100s: %s", pw ? pw->pw_name : "an illegal user",
-                   PAM_STRERROR(__pamh, pam_retval));
-               return 0;
+static int
+sshpam_init(const char *user)
+{
+       extern u_int utmp_len;
+       extern char *__progname;
+       const char *pam_rhost, *pam_user;
+
+       if (sshpam_handle != NULL) {
+               /* We already have a PAM context; check if the user matches */
+               sshpam_err = pam_get_item(sshpam_handle,
+                   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;
+       }
+       debug("PAM: initializing for \"%s\"", user);
+       sshpam_err =
+           pam_start(SSHD_PAM_SERVICE, user, &null_conv, &sshpam_handle);
+       if (sshpam_err != PAM_SUCCESS) {
+               pam_end(sshpam_handle, sshpam_err);
+               sshpam_handle = NULL;
+               return (-1);
        }
+       pam_rhost = get_remote_name_or_ip(utmp_len, options.use_dns);
+       debug("PAM: setting PAM_RHOST to \"%s\"", pam_rhost);
+       sshpam_err = pam_set_item(sshpam_handle, PAM_RHOST, pam_rhost);
+       if (sshpam_err != PAM_SUCCESS) {
+               pam_end(sshpam_handle, sshpam_err);
+               sshpam_handle = NULL;
+               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 
+        * 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) {
+               pam_end(sshpam_handle, sshpam_err);
+               sshpam_handle = NULL;
+               return (-1);
+       }
+#endif
+       fatal_add_cleanup(sshpam_cleanup, NULL);
+       return (0);
 }
 
-/* Do account management using PAM */
-int do_pam_account(char *username, char *remote_user)
+static void *
+sshpam_init_ctx(Authctxt *authctxt)
 {
-       int pam_retval;
+       struct pam_ctxt *ctxt;
+       int socks[2];
 
-       do_pam_set_conv(&conv);
+       /* Refuse to start if we don't have PAM enabled */
+       if (!options.use_pam)
+               return NULL;
 
-       if (remote_user) {
-               debug("PAM setting ruser to \"%.200s\"", remote_user);
-               pam_retval = pam_set_item(__pamh, PAM_RUSER, remote_user);
-               if (pam_retval != PAM_SUCCESS)
-                       fatal("PAM set ruser failed[%d]: %.200s", pam_retval, 
-                           PAM_STRERROR(__pamh, pam_retval));
+       /* Initialize PAM */
+       if (sshpam_init(authctxt->user) == -1) {
+               error("PAM: initialization failed");
+               return (NULL);
        }
 
-       pam_retval = pam_acct_mgmt(__pamh, 0);
-       debug2("pam_acct_mgmt() = %d", pam_retval);
-       switch (pam_retval) {
-               case PAM_SUCCESS:
-                       /* This is what we want */
-                       break;
-#if 0
-               case PAM_NEW_AUTHTOK_REQD:
-                       message_cat(&__pam_msg, use_privsep ?
-                           NEW_AUTHTOK_MSG_PRIVSEP : NEW_AUTHTOK_MSG);
-                       /* flag that password change is necessary */
-                       password_change_required = 1;
-                       /* disallow other functionality for now */
-                       no_port_forwarding_flag |= 2;
-                       no_agent_forwarding_flag |= 2;
-                       no_x11_forwarding_flag |= 2;
+       ctxt = xmalloc(sizeof *ctxt);
+       ctxt->pam_done = 0;
+
+       /* Start the authentication thread */
+       if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, socks) == -1) {
+               error("PAM: failed create sockets: %s", strerror(errno));
+               xfree(ctxt);
+               return (NULL);
+       }
+       ctxt->pam_psock = socks[0];
+       ctxt->pam_csock = socks[1];
+       if (pthread_create(&ctxt->pam_thread, NULL, sshpam_thread, ctxt) == -1) {
+               error("PAM: failed to start authentication thread: %s",
+                   strerror(errno));
+               close(socks[0]);
+               close(socks[1]);
+               xfree(ctxt);
+               return (NULL);
+       }
+       fatal_add_cleanup(sshpam_thread_cleanup, ctxt);
+       return (ctxt);
+}
+
+static int
+sshpam_query(void *ctx, char **name, char **info,
+    u_int *num, char ***prompts, u_int **echo_on)
+{
+       Buffer buffer;
+       struct pam_ctxt *ctxt = ctx;
+       size_t plen;
+       u_char type;
+       char *msg;
+       size_t len;
+
+       buffer_init(&buffer);
+       *name = xstrdup("");
+       *info = xstrdup("");
+       *prompts = xmalloc(sizeof(char *));
+       **prompts = NULL;
+       plen = 0;
+       *echo_on = xmalloc(sizeof(u_int));
+       while (ssh_msg_recv(ctxt->pam_psock, &buffer) == 0) {
+               type = buffer_get_char(&buffer);
+               msg = buffer_get_string(&buffer, NULL);
+               switch (type) {
+               case PAM_PROMPT_ECHO_ON:
+               case PAM_PROMPT_ECHO_OFF:
+                       *num = 1;
+                       len = plen + strlen(msg) + 1;
+                       **prompts = xrealloc(**prompts, len);
+                       plen += snprintf(**prompts + plen, len, "%s", msg);
+                       **echo_on = (type == PAM_PROMPT_ECHO_ON);
+                       xfree(msg);
+                       return (0);
+               case PAM_ERROR_MSG:
+               case PAM_TEXT_INFO:
+                       /* accumulate messages */
+                       len = plen + strlen(msg) + 1;
+                       **prompts = xrealloc(**prompts, len);
+                       plen += snprintf(**prompts + plen, len, "%s", 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
+                               xfree(**prompts);
+                               **prompts = NULL;
+                       }
+                       if (type == PAM_SUCCESS) {
+                               *num = 0;
+                               **echo_on = 0;
+                               ctxt->pam_done = 1;
+                               xfree(msg);
+                               return (0);
+                       }
+                       error("PAM: %s", msg);
                default:
-                       log("PAM rejected by account configuration[%d]: "
-                           "%.200s", pam_retval, PAM_STRERROR(__pamh, 
-                           pam_retval));
-                       return(0);
+                       *num = 0;
+                       **echo_on = 0;
+                       xfree(msg);
+                       ctxt->pam_done = -1;
+                       return (-1);
+               }
        }
-
-       return(1);
+       return (-1);
 }
 
-/* Do PAM-specific session initialisation */
-void do_pam_session(char *username, const char *ttyname)
+/* XXX - see also comment in auth-chall.c:verify_response */
+static int
+sshpam_respond(void *ctx, u_int num, char **resp)
 {
-       int pam_retval;
-
-       do_pam_set_conv(&conv);
-
-       if (ttyname != NULL) {
-               debug("PAM setting tty to \"%.200s\"", ttyname);
-               pam_retval = pam_set_item(__pamh, PAM_TTY, ttyname);
-               if (pam_retval != PAM_SUCCESS)
-                       fatal("PAM set tty failed[%d]: %.200s",
-                           pam_retval, PAM_STRERROR(__pamh, pam_retval));
+       Buffer buffer;
+       struct pam_ctxt *ctxt = ctx;
+
+       debug2("PAM: %s", __func__);
+       switch (ctxt->pam_done) {
+       case 1:
+               sshpam_authenticated = 1;
+               return (0);
+       case 0:
+               break;
+       default:
+               return (-1);
        }
-
-       pam_retval = pam_open_session(__pamh, 0);
-       if (pam_retval != PAM_SUCCESS)
-               fatal("PAM session setup failed[%d]: %.200s",
-                   pam_retval, PAM_STRERROR(__pamh, pam_retval));
-
-       session_opened = 1;
+       if (num != 1) {
+               error("PAM: expected one response, got %u", num);
+               return (-1);
+       }
+       buffer_init(&buffer);
+       buffer_put_cstring(&buffer, *resp);
+       ssh_msg_send(ctxt->pam_psock, PAM_AUTHTOK, &buffer);
+       buffer_free(&buffer);
+       return (1);
 }
 
-/* Set PAM credentials */
-void do_pam_setcred(int init)
+static void
+sshpam_free_ctx(void *ctxtp)
 {
-       int pam_retval;
-
-       if (__pamh == NULL)
-               return;
+       struct pam_ctxt *ctxt = ctxtp;
 
-       do_pam_set_conv(&conv);
-
-       debug("PAM establishing creds");
-       pam_retval = pam_setcred(__pamh, 
-           init ? PAM_ESTABLISH_CRED : PAM_REINITIALIZE_CRED);
-       if (pam_retval != PAM_SUCCESS) {
-               if (was_authenticated)
-                       fatal("PAM setcred failed[%d]: %.200s",
-                           pam_retval, PAM_STRERROR(__pamh, pam_retval));
-               else
-                       debug("PAM setcred failed[%d]: %.200s",
-                           pam_retval, PAM_STRERROR(__pamh, pam_retval));
-       } else
-               creds_set = 1;
+       fatal_remove_cleanup(sshpam_thread_cleanup, ctxt);
+       sshpam_thread_cleanup(ctxtp);
+       xfree(ctxt);
+       /*
+        * We don't call sshpam_cleanup() here because we may need the PAM
+        * handle at a later stage, e.g. when setting up a session.  It's
+        * still on the cleanup list, so pam_end() *will* be called before
+        * the server process terminates.
+        */
 }
 
-/* accessor function for file scope static variable */
-int is_pam_password_change_required(void)
-{
-       return password_change_required;
-}
+KbdintDevice sshpam_device = {
+       "pam",
+       sshpam_init_ctx,
+       sshpam_query,
+       sshpam_respond,
+       sshpam_free_ctx
+};
+
+KbdintDevice mm_sshpam_device = {
+       "pam",
+       mm_sshpam_init_ctx,
+       mm_sshpam_query,
+       mm_sshpam_respond,
+       mm_sshpam_free_ctx
+};
 
 /*
- * Have user change authentication token if pam_acct_mgmt() indicated
- * it was expired.  This needs to be called after an interactive
- * session is established and the user's pty is connected to
- * stdin/stdout/stderr.
+ * This replaces auth-pam.c
  */
-void do_pam_chauthtok(void)
+void
+start_pam(const char *user)
 {
-       int pam_retval;
-
-       do_pam_set_conv(&conv);
-
-       if (password_change_required) {
-               if (use_privsep)
-                       fatal("Password changing is currently unsupported"
-                           " with privilege separation");
-               pamstate = OTHER;
-               pam_retval = pam_chauthtok(__pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
-               if (pam_retval != PAM_SUCCESS)
-                       fatal("PAM pam_chauthtok failed[%d]: %.200s",
-                           pam_retval, PAM_STRERROR(__pamh, pam_retval));
-#if 0
-               /* XXX: This would need to be done in the parent process,
-                * but there's currently no way to pass such request. */
-               no_port_forwarding_flag &= ~2;
-               no_agent_forwarding_flag &= ~2;
-               no_x11_forwarding_flag &= ~2;
-               if (!no_port_forwarding_flag && options.allow_tcp_forwarding)
-                       channel_permit_all_opens();
-#endif
-       }
+       if (!options.use_pam)
+               fatal("PAM: initialisation requested when UsePAM=no");
+
+       if (sshpam_init(user) == -1)
+               fatal("PAM: initialisation failed");
 }
 
-/* Cleanly shutdown PAM */
-void finish_pam(void)
+void
+finish_pam(void)
 {
-       do_pam_cleanup_proc(NULL);
-       fatal_remove_cleanup(&do_pam_cleanup_proc, NULL);
+       fatal_remove_cleanup(sshpam_cleanup, NULL);
+       sshpam_cleanup(NULL);
 }
 
-/* Start PAM authentication for specified account */
-void start_pam(const char *user)
+u_int
+do_pam_account(void)
 {
-       int pam_retval;
-       extern ServerOptions options;
-       extern u_int utmp_len;
-       const char *rhost;
-
-       debug("Starting up PAM with username \"%.200s\"", user);
-
-       pam_retval = pam_start(SSHD_PAM_SERVICE, user, &conv, &__pamh);
+       sshpam_err = pam_acct_mgmt(sshpam_handle, 0);
+       debug3("%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 (pam_retval != PAM_SUCCESS)
-               fatal("PAM initialisation failed[%d]: %.200s",
-                   pam_retval, PAM_STRERROR(__pamh, pam_retval));
+       return (1);
+}
 
-       rhost = get_remote_name_or_ip(utmp_len, options.verify_reverse_mapping);
-       debug("PAM setting rhost to \"%.200s\"", rhost);
+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;
+}
 
-       pam_retval = pam_set_item(__pamh, PAM_RHOST, rhost);
-       if (pam_retval != PAM_SUCCESS)
-               fatal("PAM set rhost failed[%d]: %.200s", pam_retval,
-                   PAM_STRERROR(__pamh, pam_retval));
-#ifdef PAM_TTY_KLUDGE
-       /*
-        * Some PAM modules (e.g. pam_time) require a TTY to operate,
-        * and will fail in various stupid ways if they don't get one.
-        * sshd doesn't set the tty until too late in the auth process and may
-        * not even need one (for tty-less connections)
-        * Kludge: Set a fake PAM_TTY
-        */
-       pam_retval = pam_set_item(__pamh, PAM_TTY, "NODEVssh");
-       if (pam_retval != PAM_SUCCESS)
-               fatal("PAM set tty failed[%d]: %.200s",
-                   pam_retval, PAM_STRERROR(__pamh, pam_retval));
-#endif /* PAM_TTY_KLUDGE */
+void
+do_pam_set_tty(const char *tty)
+{
+       if (tty != NULL) {
+               debug("PAM: setting PAM_TTY to \"%s\"", tty);
+               sshpam_err = pam_set_item(sshpam_handle, PAM_TTY, tty);
+               if (sshpam_err != PAM_SUCCESS)
+                       fatal("PAM: failed to set PAM_TTY: %s",
+                           pam_strerror(sshpam_handle, sshpam_err));
+       }
+}
 
-       fatal_add_cleanup(&do_pam_cleanup_proc, NULL);
+void
+do_pam_setcred(int init)
+{
+       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));
+       if (init) {
+               debug("PAM: establishing credentials");
+               sshpam_err = pam_setcred(sshpam_handle, PAM_ESTABLISH_CRED);
+       } else {
+               debug("PAM: reinitializing credentials");
+               sshpam_err = pam_setcred(sshpam_handle, PAM_REINITIALIZE_CRED);
+       }
+       if (sshpam_err == PAM_SUCCESS) {
+               sshpam_cred_established = 1;
+               return;
+       }
+       if (sshpam_authenticated)
+               fatal("PAM: pam_setcred(): %s",
+                   pam_strerror(sshpam_handle, sshpam_err));
+       else
+               debug("PAM: pam_setcred(): %s",
+                   pam_strerror(sshpam_handle, sshpam_err));
 }
 
-/* Return list of PAM environment strings */
-char **fetch_pam_environment(void)
+int
+is_pam_password_change_required(void)
 {
-#ifdef HAVE_PAM_GETENVLIST
-       return(pam_getenvlist(__pamh));
-#else /* HAVE_PAM_GETENVLIST */
-       return(NULL);
-#endif /* HAVE_PAM_GETENVLIST */
+       return (sshpam_new_authtok_reqd);
 }
 
-void free_pam_environment(char **env)
+static int
+pam_chauthtok_conv(int n, const struct pam_message **msg,
+    struct pam_response **resp, void *data)
 {
+       char input[PAM_MAX_MSG_SIZE];
        int i;
 
-       if (env != NULL) {
-               for (i = 0; env[i] != NULL; i++)
-                       xfree(env[i]);
+       if (n <= 0 || n > PAM_MAX_NUM_MSG)
+               return (PAM_CONV_ERR);
+       *resp = xmalloc(n * sizeof **resp);
+       for (i = 0; i < n; ++i) {
+               switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
+               case PAM_PROMPT_ECHO_OFF:
+                       resp[i]->resp =
+                           read_passphrase(PAM_MSG_MEMBER(msg, i, msg), 
+                           RP_ALLOW_STDIN);
+                       resp[i]->resp_retcode = PAM_SUCCESS;
+                       break;
+               case PAM_PROMPT_ECHO_ON:
+                       fputs(PAM_MSG_MEMBER(msg, i, msg), stderr);
+                       fgets(input, sizeof input, stdin);
+                       resp[i]->resp = xstrdup(input);
+                       resp[i]->resp_retcode = PAM_SUCCESS;
+                       break;
+               case PAM_ERROR_MSG:
+               case PAM_TEXT_INFO:
+                       fputs(PAM_MSG_MEMBER(msg, i, msg), stderr);
+                       resp[i]->resp_retcode = PAM_SUCCESS;
+                       break;
+               default:
+                       goto fail;
+               }
        }
+       return (PAM_SUCCESS);
+ fail:
+       while (i)
+               xfree(resp[--i]);
+       xfree(*resp);
+       *resp = NULL;
+       return (PAM_CONV_ERR);
 }
 
-/* Set a PAM environment string. We need to do this so that the session
+/*
+ * XXX this should be done in the authentication phase, but ssh1 doesn't
+ * support that
+ */
+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);
+       if (sshpam_err != PAM_SUCCESS)
+               fatal("PAM: failed to set PAM_CONV: %s",
+                   pam_strerror(sshpam_handle, sshpam_err));
+       debug("PAM: changing password");
+       sshpam_err = pam_chauthtok(sshpam_handle, PAM_CHANGE_EXPIRED_AUTHTOK);
+       if (sshpam_err != PAM_SUCCESS)
+               fatal("PAM: pam_chauthtok(): %s",
+                   pam_strerror(sshpam_handle, sshpam_err));
+}
+
+/* 
+ * 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) {
+int
+do_pam_putenv(char *name, char *value) 
+{
+       int ret = 1;
+#ifdef HAVE_PAM_PUTENV 
        char *compound;
-       int ret=1;
+       size_t len;
 
-#ifdef HAVE_PAM_PUTENV 
-       compound=xmalloc(strlen(name)+strlen(value)+2);
-       if (compound) {
-               sprintf(compound,"%s=%s",name,value);
-               ret=pam_putenv(__pamh,compound);
-               xfree(compound);
-       }
+       len = strlen(name) + strlen(value) + 2;
+       compound = xmalloc(len);
+
+       snprintf(compound, len, "%s=%s", name, value);
+       ret = pam_putenv(sshpam_handle, compound);
+       xfree(compound);
 #endif
-       return(ret);
+
+       return (ret);
 }
 
-/* Print any messages that have been generated during authentication */
-/* or account checking to stderr */
-void print_pam_messages(void)
+void
+print_pam_messages(void)
 {
-       if (__pam_msg != NULL)
-               fputs(__pam_msg, stderr);
+       /* XXX */
 }
 
-/* Append a message to buffer */
-void message_cat(char **p, const char *a)
+char **
+fetch_pam_environment(void)
 {
-       char *cp;
-       size_t new_len;
-
-       new_len = strlen(a);
+#ifdef HAVE_PAM_GETENVLIST
+       debug("PAM: retrieving environment");
+       return (pam_getenvlist(sshpam_handle));
+#else
+       return (NULL);
+#endif
+}
 
-       if (*p) {
-               size_t len = strlen(*p);
+void
+free_pam_environment(char **env)
+{
+       char **envp;
 
-               *p = xrealloc(*p, new_len + len + 2);
-               cp = *p + len;
-       } else
-               *p = cp = xmalloc(new_len + 2);
+       if (env == NULL)
+               return;
 
-       memcpy(cp, a, new_len);
-       cp[new_len] = '\n';
-       cp[new_len + 1] = '\0';
+       for (envp = env; *envp; envp++)
+               xfree(*envp);
+       xfree(env);
 }
 
 #endif /* USE_PAM */
index 50bf8f3e21500ce4cf666a42ec929ae268332e00..6b77872d1919ac84e9de9a5c639e7431844ef38c 100644 (file)
 # define SSHD_PAM_SERVICE              __progname
 #endif
 
-void start_pam(const char *user);
+void start_pam(const char *);
 void finish_pam(void);
-int auth_pam_password(Authctxt *authctxt, const char *password);
-char **fetch_pam_environment(void);
-void free_pam_environment(char **env);
-int do_pam_authenticate(int flags);
-int do_pam_account(char *username, char *remote_user);
-void do_pam_session(char *username, const char *ttyname);
-void do_pam_setcred(int init);
-void print_pam_messages(void);
+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);
-void do_pam_set_conv(struct pam_conv *);
 int do_pam_putenv(char *, char *);
-void message_cat(char **p, const char *a);
+void print_pam_messages(void);
+char ** fetch_pam_environment(void);
+void free_pam_environment(char **);
 
 #endif /* USE_PAM */
index ccedf9dcb0f6163a803373a4b8e369760745e94d..2469b693a53e333eba7009ecaff544d9b44dd9e4 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth.c,v 1.46 2002/11/04 10:07:53 markus Exp $");
+RCSID("$OpenBSD: auth.c,v 1.49 2003/08/26 09:58:43 markus Exp $");
 
 #ifdef HAVE_LOGIN_H
 #include <login.h>
@@ -54,6 +54,7 @@ RCSID("$OpenBSD: auth.c,v 1.46 2002/11/04 10:07:53 markus Exp $");
 
 /* import */
 extern ServerOptions options;
+extern Buffer loginmsg;
 
 /* Debugging messages */
 Buffer auth_debug;
@@ -72,26 +73,25 @@ int
 allowed_user(struct passwd * pw)
 {
        struct stat st;
-       const char *hostname = NULL, *ipaddr = NULL;
+       const char *hostname = NULL, *ipaddr = NULL, *passwd = NULL;
        char *shell;
        int i;
-#ifdef WITH_AIXAUTHENTICATE
-       char *loginmsg;
-#endif /* WITH_AIXAUTHENTICATE */
-#if !defined(USE_PAM) && defined(HAVE_SHADOW_H) && \
-    !defined(DISABLE_SHADOW) && defined(HAS_SHADOW_EXPIRE)
-       struct spwd *spw;
-       time_t today;
+#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
+       struct spwd *spw = NULL;
 #endif
 
        /* Shouldn't be called if pw is NULL, but better safe than sorry... */
        if (!pw || !pw->pw_name)
                return 0;
 
-#if !defined(USE_PAM) && defined(HAVE_SHADOW_H) && \
-    !defined(DISABLE_SHADOW) && defined(HAS_SHADOW_EXPIRE)
+#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
+       if (!options.use_pam)
+               spw = getspnam(pw->pw_name);
+#ifdef HAS_SHADOW_EXPIRE
 #define        DAY             (24L * 60 * 60) /* 1 day in seconds */
-       if ((spw = getspnam(pw->pw_name)) != NULL) {
+       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,
@@ -102,25 +102,58 @@ allowed_user(struct passwd * pw)
                 * day after the day specified.
                 */
                if (spw->sp_expire != -1 && today > spw->sp_expire) {
-                       log("Account %.100s has expired", pw->pw_name);
+                       logit("Account %.100s has expired", pw->pw_name);
                        return 0;
                }
 
                if (spw->sp_lstchg == 0) {
-                       log("User %.100s password has expired (root forced)",
+                       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) {
-                       log("User %.100s password has expired (password aged)",
+                       logit("User %.100s password has expired (password aged)",
                            pw->pw_name);
                        return 0;
                }
        }
+#endif /* HAS_SHADOW_EXPIRE */
+#endif /* defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) */
+
+       /* grab passwd field for locked account check */
+#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
+       if (spw != NULL)
+               passwd = spw->sp_pwdp;
+#else
+       passwd = pw->pw_passwd;
 #endif
 
+       /* check for locked account */ 
+       if (!options.use_pam && passwd && *passwd) {
+               int locked = 0;
+
+#ifdef LOCKED_PASSWD_STRING
+               if (strcmp(passwd, LOCKED_PASSWD_STRING) == 0)
+                        locked = 1;
+#endif
+#ifdef LOCKED_PASSWD_PREFIX
+               if (strncmp(passwd, LOCKED_PASSWD_PREFIX,
+                   strlen(LOCKED_PASSWD_PREFIX)) == 0)
+                        locked = 1;
+#endif
+#ifdef LOCKED_PASSWD_SUBSTR
+               if (strstr(passwd, LOCKED_PASSWD_SUBSTR))
+                       locked = 1;
+#endif
+               if (locked) {
+                       logit("User %.100s not allowed because account is locked",
+                           pw->pw_name);
+                       return 0;
+               }
+       }
+
        /*
         * Get the shell from the password data.  An empty shell field is
         * legal, and means /bin/sh.
@@ -129,19 +162,19 @@ allowed_user(struct passwd * pw)
 
        /* deny if shell does not exists or is not executable */
        if (stat(shell, &st) != 0) {
-               log("User %.100s not allowed because shell %.100s does not exist",
+               logit("User %.100s not allowed because shell %.100s does not exist",
                    pw->pw_name, shell);
                return 0;
        }
        if (S_ISREG(st.st_mode) == 0 ||
            (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) {
-               log("User %.100s not allowed because shell %.100s is not executable",
+               logit("User %.100s not allowed because shell %.100s is not executable",
                    pw->pw_name, shell);
                return 0;
        }
 
        if (options.num_deny_users > 0 || options.num_allow_users > 0) {
-               hostname = get_canonical_hostname(options.verify_reverse_mapping);
+               hostname = get_canonical_hostname(options.use_dns);
                ipaddr = get_remote_ipaddr();
        }
 
@@ -150,7 +183,7 @@ allowed_user(struct passwd * pw)
                for (i = 0; i < options.num_deny_users; i++)
                        if (match_user(pw->pw_name, hostname, ipaddr,
                            options.deny_users[i])) {
-                               log("User %.100s not allowed because listed in DenyUsers",
+                               logit("User %.100s not allowed because listed in DenyUsers",
                                    pw->pw_name);
                                return 0;
                        }
@@ -163,7 +196,7 @@ allowed_user(struct passwd * pw)
                                break;
                /* i < options.num_allow_users iff we break for loop */
                if (i >= options.num_allow_users) {
-                       log("User %.100s not allowed because not listed in AllowUsers",
+                       logit("User %.100s not allowed because not listed in AllowUsers",
                            pw->pw_name);
                        return 0;
                }
@@ -171,7 +204,7 @@ allowed_user(struct passwd * pw)
        if (options.num_deny_groups > 0 || options.num_allow_groups > 0) {
                /* Get the user's group access list (primary and supplementary) */
                if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
-                       log("User %.100s not allowed because not in any group",
+                       logit("User %.100s not allowed because not in any group",
                            pw->pw_name);
                        return 0;
                }
@@ -181,7 +214,7 @@ allowed_user(struct passwd * pw)
                        if (ga_match(options.deny_groups,
                            options.num_deny_groups)) {
                                ga_free();
-                               log("User %.100s not allowed because a group is listed in DenyGroups",
+                               logit("User %.100s not allowed because a group is listed in DenyGroups",
                                    pw->pw_name);
                                return 0;
                        }
@@ -193,7 +226,7 @@ allowed_user(struct passwd * pw)
                        if (!ga_match(options.allow_groups,
                            options.num_allow_groups)) {
                                ga_free();
-                               log("User %.100s not allowed because none of user's groups are listed in AllowGroups",
+                               logit("User %.100s not allowed because none of user's groups are listed in AllowGroups",
                                    pw->pw_name);
                                return 0;
                        }
@@ -206,26 +239,23 @@ allowed_user(struct passwd * pw)
         * PermitRootLogin to control logins via ssh), or if running as
         * non-root user (since loginrestrictions will always fail).
         */
-       if ((pw->pw_uid != 0) && (geteuid() == 0) &&
-           loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &loginmsg) != 0) {
-               int loginrestrict_errno = errno;
-
-               if (loginmsg && *loginmsg) {
-                       /* Remove embedded newlines (if any) */
-                       char *p;
-                       for (p = loginmsg; *p; p++) {
-                               if (*p == '\n')
-                                       *p = ' ';
+       if ((pw->pw_uid != 0) && (geteuid() == 0)) {
+               char *msg;
+
+               if (loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &msg) != 0) {
+                       int loginrestrict_errno = errno;
+
+                       if (msg && *msg) {
+                               buffer_append(&loginmsg, msg, strlen(msg));
+                               aix_remove_embedded_newlines(msg);
+                               logit("Login restricted for %s: %.100s",
+                                   pw->pw_name, msg);
                        }
-                       /* Remove trailing newline */
-                       *--p = '\0';
-                       log("Login restricted for %s: %.100s", pw->pw_name, 
-                           loginmsg);
+                       /* Don't fail if /etc/nologin  set */
+                       if (!(loginrestrict_errno == EPERM && 
+                           stat(_PATH_NOLOGIN, &st) == 0))
+                               return 0;
                }
-               /* Don't fail if /etc/nologin  set */
-               if (!(loginrestrict_errno == EPERM && 
-                   stat(_PATH_NOLOGIN, &st) == 0))
-                       return 0;
        }
 #endif /* WITH_AIXAUTHENTICATE */
 
@@ -252,7 +282,7 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
            !authctxt->valid ||
            authctxt->failures >= AUTH_FAIL_LOG ||
            strcmp(method, "password") == 0)
-               authlog = log;
+               authlog = logit;
 
        if (authctxt->postponed)
                authmsg = "Postponed";
@@ -268,13 +298,10 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
            get_remote_port(),
            info);
 
-#ifdef WITH_AIXAUTHENTICATE
+#ifdef CUSTOM_FAILED_LOGIN
        if (authenticated == 0 && strcmp(method, "password") == 0)
-           loginfailed(authctxt->user,
-               get_canonical_hostname(options.verify_reverse_mapping),
-               "ssh");
-#endif /* WITH_AIXAUTHENTICATE */
-
+               record_failed_login(authctxt->user, "ssh");
+#endif
 }
 
 /*
@@ -293,12 +320,12 @@ auth_root_allowed(char *method)
                break;
        case PERMIT_FORCED_ONLY:
                if (forced_command) {
-                       log("Root login accepted for forced command.");
+                       logit("Root login accepted for forced command.");
                        return 1;
                }
                break;
        }
-       log("ROOT LOGIN REFUSED FROM %.200s", get_remote_ipaddr());
+       logit("ROOT LOGIN REFUSED FROM %.200s", get_remote_ipaddr());
        return 0;
 }
 
@@ -390,7 +417,7 @@ check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host,
                    (stat(user_hostfile, &st) == 0) &&
                    ((st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
                    (st.st_mode & 022) != 0)) {
-                       log("Authentication refused for %.100s: "
+                       logit("Authentication refused for %.100s: "
                            "bad owner or modes for %.200s",
                            pw->pw_name, user_hostfile);
                } else {
@@ -494,12 +521,10 @@ getpwnamallow(const char *user)
 
        pw = getpwnam(user);
        if (pw == NULL) {
-               log("Illegal user %.100s from %.100s",
+               logit("Illegal user %.100s from %.100s",
                    user, get_remote_ipaddr());
-#ifdef WITH_AIXAUTHENTICATE
-               loginfailed(user,
-                   get_canonical_hostname(options.verify_reverse_mapping),
-                   "ssh");
+#ifdef CUSTOM_FAILED_LOGIN
+               record_failed_login(user, "ssh");
 #endif
                return (NULL);
        }
@@ -564,3 +589,24 @@ auth_debug_reset(void)
                auth_debug_init = 1;
        }
 }
+
+struct passwd *
+fakepw(void)
+{
+       static struct passwd fake;
+
+       memset(&fake, 0, sizeof(fake));
+       fake.pw_name = "NOUSER";
+       fake.pw_passwd =
+           "$2a$06$r3.juUaHZDlIbQaO2dS9FuYxL1W9M81R1Tc92PoSNmzvpEqLkLGrK";     
+       fake.pw_gecos = "NOUSER";
+       fake.pw_uid = -1;
+       fake.pw_gid = -1;
+#ifdef HAVE_PW_CLASS_IN_PASSWD
+       fake.pw_class = "";
+#endif
+       fake.pw_dir = "/nonexist";
+       fake.pw_shell = "/nonexist";
+
+       return (&fake);
+}
index 2e351d6d15c92a40f507c97039c15b32af62181b..9a5c6577ad4fa6889a4d8d14fe7d2e4002452b1c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: auth.h,v 1.41 2002/09/26 11:38:43 markus Exp $        */
+/*     $OpenBSD: auth.h,v 1.46 2003/08/28 12:54:34 markus Exp $        */
 
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
@@ -41,6 +41,9 @@
 #ifdef KRB5
 #include <krb5.h>
 #endif
+#ifdef AFS_KRB5
+#include <krbafs.h>
+#endif
 
 typedef struct Authctxt Authctxt;
 typedef struct Authmethod Authmethod;
@@ -48,24 +51,20 @@ typedef struct KbdintDevice KbdintDevice;
 
 struct Authctxt {
        int              success;
-       int              postponed;
-       int              valid;
+       int              postponed;     /* authentication needs another step */
+       int              valid;         /* user exists and is allowed to login */
        int              attempt;
        int              failures;
-       char            *user;
+       char            *user;          /* username sent by the client */
        char            *service;
-       struct passwd   *pw;
+       struct passwd   *pw;            /* set if 'valid' */
        char            *style;
        void            *kbdintctxt;
 #ifdef BSD_AUTH
        auth_session_t  *as;
 #endif
-#ifdef KRB4
-       char            *krb4_ticket_file;
-#endif
 #ifdef KRB5
        krb5_context     krb5_ctx;
-       krb5_auth_context krb5_auth_ctx;
        krb5_ccache      krb5_fwd_ccache;
        krb5_principal   krb5_user;
        char            *krb5_ticket_file;
@@ -73,8 +72,14 @@ struct Authctxt {
 #ifdef SESSION_HOOKS
         char            *session_env_file;
 #endif
-       void *methoddata;
+       void            *methoddata;
 };
+/*
+ * Every authentication method has to handle authentication requests for
+ * non-existing users, or for users that are not allowed to login. In this
+ * case 'valid' is set to 0, but 'user' points to the username requested by
+ * the client.
+ */
 
 struct Authmethod {
        char    *name;
@@ -115,20 +120,6 @@ int         auth_rhosts_rsa_key_allowed(struct passwd *, char *, char *, Key *);
 int     hostbased_key_allowed(struct passwd *, const char *, char *, Key *);
 int     user_key_allowed(struct passwd *, Key *);
 
-#ifdef KRB4
-#include <krb.h>
-int     auth_krb4(Authctxt *, KTEXT, char **, KTEXT);
-int    auth_krb4_password(Authctxt *, const char *);
-void    krb4_cleanup_proc(void *);
-
-#ifdef AFS
-#include <kafs.h>
-int     auth_krb4_tgt(Authctxt *, const char *);
-int     auth_afs_token(Authctxt *, const char *);
-#endif /* AFS */
-
-#endif /* KRB4 */
-
 #ifdef KRB5
 int    auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *);
 int    auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt);
@@ -137,7 +128,6 @@ void        krb5_cleanup_proc(void *authctxt);
 #endif /* KRB5 */
 
 #include "auth-pam.h"
-#include "auth2-pam.h"
 
 Authctxt *do_authentication(void);
 Authctxt *do_authentication2(void);
@@ -163,6 +153,7 @@ struct passwd * getpwnamallow(const char *user);
 
 char   *get_challenge(Authctxt *);
 int    verify_response(Authctxt *, const char *);
+void   abandon_challenge_response(Authctxt *);
 
 struct passwd * auth_get_user(void);
 
@@ -188,6 +179,8 @@ void         auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2)));
 void    auth_debug_send(void);
 void    auth_debug_reset(void);
 
+struct passwd *fakepw(void);
+
 #define AUTH_FAIL_MAX 6
 #define AUTH_FAIL_LOG (AUTH_FAIL_MAX/2)
 #define AUTH_FAIL_MSG "Too many authentication failures for %.100s"
index 10d74dc3ebc166a47bfbf83e59d8e864f293cc7c..9e4a29352bb64b876e90c96aab7ec096b7582bf2 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth1.c,v 1.47 2003/02/06 21:22:42 markus Exp $");
+RCSID("$OpenBSD: auth1.c,v 1.52 2003/08/28 12:54:34 markus Exp $");
 
 #include "xmalloc.h"
 #include "rsa.h"
@@ -47,13 +47,13 @@ auth1_gss_protocol_error(int type, u_int32_t plen, void *ctxt)
   /* Other side told us to abort, dont need to tell him */ 
   /* maybe we can use some other method. */
   if (type == SSH_MSG_AUTH_GSSAPI_ABORT) {
-      log("auth1: GSSAPI aborting");
+      logit("auth1: GSSAPI aborting");
       dispatch_set(SSH_MSG_AUTH_GSSAPI_TOKEN, NULL);
       authctxt->success = 1; /* get out of loop*/
       return;
   }
 
-  log("auth1: protocol error: type %d plen %d", type, plen);
+  logit("auth1: protocol error: type %d plen %d", type, plen);
   packet_disconnect("Protocol error during GSSAPI authentication: "
           "Unknown packet type %d", type);
 }
@@ -176,10 +176,6 @@ get_authname(int type)
        case SSH_CMSG_AUTH_TIS:
        case SSH_CMSG_AUTH_TIS_RESPONSE:
                return "challenge-response";
-#if defined(KRB4) || defined(KRB5)
-       case SSH_CMSG_AUTH_KERBEROS:
-               return "kerberos";
-#endif
 #if defined(GSSAPI)
        case SSH_CMSG_AUTH_GSSAPI:
                return "gssapi";
@@ -204,7 +200,7 @@ do_authloop(Authctxt *authctxt)
        char info[1024];
        u_int dlen;
        u_int ulen;
-       int type = 0;
+       int prev, type = 0;
        struct passwd *pw = authctxt->pw;
 
        debug("Attempting authentication for %s%.100s.",
@@ -212,7 +208,7 @@ do_authloop(Authctxt *authctxt)
 
        /* If the user has no password, accept authentication immediately. */
        if (options.password_authentication &&
-#if defined(KRB4) || defined(KRB5)
+#ifdef KRB5
            (!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
 #endif
            PRIVSEP(auth_password(authctxt, ""))) {
@@ -234,72 +230,22 @@ do_authloop(Authctxt *authctxt)
                info[0] = '\0';
 
                /* Get a packet from the client. */
+               prev = type;
                type = packet_read();
 
+               /*
+                * If we started challenge-response authentication but the
+                * next packet is not a response to our challenge, release
+                * the resources allocated by get_challenge() (which would
+                * normally have been released by verify_response() had we
+                * received such a response)
+                */
+               if (prev == SSH_CMSG_AUTH_TIS &&
+                   type != SSH_CMSG_AUTH_TIS_RESPONSE)
+                       abandon_challenge_response(authctxt);
+
                /* Process the packet. */
                switch (type) {
-
-#if defined(KRB4) || defined(KRB5)
-               case SSH_CMSG_AUTH_KERBEROS:
-                       if (!options.kerberos_authentication) {
-                               verbose("Kerberos authentication disabled.");
-                       } else {
-                               char *kdata = packet_get_string(&dlen);
-                               packet_check_eom();
-
-                               if (kdata[0] == 4) { /* KRB_PROT_VERSION */
-#ifdef KRB4
-                                       KTEXT_ST tkt, reply;
-                                       tkt.length = dlen;
-                                       if (tkt.length < MAX_KTXT_LEN)
-                                               memcpy(tkt.dat, kdata, tkt.length);
-
-                                       if (PRIVSEP(auth_krb4(authctxt, &tkt,
-                                           &client_user, &reply))) {
-                                               authenticated = 1;
-                                               snprintf(info, sizeof(info),
-                                                   " tktuser %.100s",
-                                                   client_user);
-
-                                               packet_start(
-                                                   SSH_SMSG_AUTH_KERBEROS_RESPONSE);
-                                               packet_put_string((char *)
-                                                   reply.dat, reply.length);
-                                               packet_send();
-                                               packet_write_wait();
-                                       }
-#endif /* KRB4 */
-                               } else {
-#ifdef KRB5
-                                       krb5_data tkt, reply;
-                                       tkt.length = dlen;
-                                       tkt.data = kdata;
-
-                                       if (PRIVSEP(auth_krb5(authctxt, &tkt,
-                                           &client_user, &reply))) {
-                                               authenticated = 1;
-                                               snprintf(info, sizeof(info),
-                                                   " tktuser %.100s",
-                                                   client_user);
-
-                                               /* Send response to client */
-                                               packet_start(
-                                                   SSH_SMSG_AUTH_KERBEROS_RESPONSE);
-                                               packet_put_string((char *)
-                                                   reply.data, reply.length);
-                                               packet_send();
-                                               packet_write_wait();
-
-                                               if (reply.length)
-                                                       xfree(reply.data);
-                                       }
-#endif /* KRB5 */
-                               }
-                               xfree(kdata);
-                       }
-                       break;
-#endif /* KRB4 || KRB5 */
-
 #ifdef GSSAPI
                case SSH_CMSG_AUTH_GSSAPI:
                        if (!options.gss_authentication) {
@@ -337,38 +283,6 @@ do_authloop(Authctxt *authctxt)
                        authenticated = 1;
                        break;
 #endif /* GSSAPI */
-                       
-#if defined(AFS) || defined(KRB5)
-                       /* XXX - punt on backward compatibility here. */
-               case SSH_CMSG_HAVE_KERBEROS_TGT:
-                       packet_send_debug("Kerberos TGT passing disabled before authentication.");
-                       break;
-#ifdef AFS
-               case SSH_CMSG_HAVE_AFS_TOKEN:
-                       packet_send_debug("AFS token passing disabled before authentication.");
-                       break;
-#endif /* AFS */
-#endif /* AFS || KRB5 */
-
-               case SSH_CMSG_AUTH_RHOSTS:
-                       if (!options.rhosts_authentication) {
-                               verbose("Rhosts authentication disabled.");
-                               break;
-                       }
-                       /*
-                        * Get client user name.  Note that we just have to
-                        * trust the client; this is one reason why rhosts
-                        * authentication is insecure. (Another is
-                        * IP-spoofing on a local network.)
-                        */
-                       client_user = packet_get_string(&ulen);
-                       packet_check_eom();
-
-                       /* Try to authenticate using /etc/hosts.equiv and .rhosts. */
-                       authenticated = auth_rhosts(pw, client_user);
-
-                       snprintf(info, sizeof info, " ruser %.100s", client_user);
-                       break;
 
                case SSH_CMSG_AUTH_RHOSTS_RSA:
                        if (!options.rhosts_rsa_authentication) {
@@ -466,7 +380,7 @@ do_authloop(Authctxt *authctxt)
                         * Any unknown messages will be ignored (and failure
                         * returned) during authentication.
                         */
-                       log("Unknown message during authentication: type %d", type);
+                       logit("Unknown message during authentication: type %d", type);
                        break;
                }
 #ifdef BSD_AUTH
@@ -480,8 +394,6 @@ do_authloop(Authctxt *authctxt)
                            authctxt->user);
 
 #ifdef _UNICOS
-               if (type == SSH_CMSG_AUTH_PASSWORD && !authenticated)
-                       cray_login_failure(authctxt->user, IA_UDBERR);
                if (authenticated && cray_access_denied(authctxt->user)) {
                        authenticated = 0;
                        fatal("Access denied for user %s.",authctxt->user);
@@ -501,9 +413,10 @@ do_authloop(Authctxt *authctxt)
                    !auth_root_allowed(get_authname(type)))
                        authenticated = 0;
 #endif
+
 #ifdef USE_PAM
-               if (!use_privsep && authenticated && 
-                   !do_pam_account(pw->pw_name, client_user))
+               if (options.use_pam && authenticated && 
+                   !PRIVSEP(do_pam_account()))
                        authenticated = 0;
 #endif
 
@@ -518,9 +431,8 @@ do_authloop(Authctxt *authctxt)
                if (authenticated)
                        return;
 
-               if (authctxt->failures++ > AUTH_FAIL_MAX) {
+               if (authctxt->failures++ > AUTH_FAIL_MAX)
                        packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
-               }
 
                packet_start(SSH_SMSG_FAILURE);
                packet_send();
@@ -554,16 +466,6 @@ do_authentication(void)
        if ((style = strchr(user, ':')) != NULL)
                *style++ = '\0';
 
-#ifdef KRB5
-       /* XXX - SSH.com Kerberos v5 braindeath. */
-       if ((datafellows & SSH_BUG_K5USER) &&
-           options.kerberos_authentication) {
-               char *p;
-               if ((p = strchr(user, '@')) != NULL)
-                       *p = '\0';
-       }
-#endif
-
        authctxt = authctxt_new();
        authctxt->user = user;
        authctxt->style = style;
@@ -571,14 +473,17 @@ do_authentication(void)
        /* Verify that the user is a valid user. */
        if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL)
                authctxt->valid = 1;
-       else
+       else {
                debug("do_authentication: illegal user %s", user);
+               authctxt->pw = fakepw();
+       }
 
        setproctitle("%s%s", authctxt->pw ? user : "unknown",
            use_privsep ? " [net]" : "");
 
 #ifdef USE_PAM
-       PRIVSEP(start_pam(authctxt->pw == NULL ? "NOUSER" : user));
+       if (options.use_pam)
+               PRIVSEP(start_pam(user));
 #endif
 
        /*
index abbb3822a95285918ea59cdff5a5a5a2d6c0b2ae..252c1b927ff8504ee1dc8d4252d1a160c40bfc17 100644 (file)
@@ -1,3 +1,5 @@
+/*     $OpenBSD: auth2-gss.c,v 1.3 2003/09/01 20:44:54 markus Exp $    */
+
 /*
  * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
  *
@@ -25,6 +27,7 @@
 #include "includes.h"
 
 #ifdef GSSAPI
+
 #include "auth.h"
 #include "ssh2.h"
 #include "ssh1.h"
@@ -54,70 +57,64 @@ static void input_gssapi_token(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 *);
 
-/* We only support those mechanisms that we know about (ie ones that we know
+/*
+ * We only support those mechanisms that we know about (ie ones that we know
  * how to check local user kuserok and the like
  */
 static int
 userauth_gssapi(Authctxt *authctxt)
 {
-        gss_OID_desc    oid= {0,NULL};
-        Gssctxt         *ctxt = NULL;
-        int             mechs;
-        gss_OID_set     supported;
-        int             present;
-        OM_uint32       ms;
-        u_int           len;
-        char *         doid = NULL;
-        
-        if (!authctxt->valid || authctxt->user == NULL)
-                return 0;
-                
-        if (datafellows & SSH_OLD_GSSAPI) {
-                debug("Early drafts of GSSAPI userauth not supported");
-                return 0;
-        }
-        
-        mechs=packet_get_int();
-        if (mechs==0) {
-                debug("Mechanism negotiation is not supported");
-                return 0;
-        }
-
-        ssh_gssapi_supported_oids(&supported);
-        do {
-                mechs--;
-                
-                if (doid)
-                        xfree(doid);
-                
-                debug("Trying to get OID string");
-                doid = packet_get_string(&len);
-                debug("Got string");
-                
-                       if (doid[0]!=0x06 || doid[1]!=len-2) {
-                               log("Mechanism OID received using the old encoding form");
-                               oid.elements = doid;
-                               oid.length = len;
-                       } else {
-                               oid.elements = doid + 2;
-                               oid.length   = len - 2;
-                       }
-               gss_test_oid_set_member(&ms, &oid, supported, &present);
-        } while (mechs>0 && !present);
-        
-        if (!present) {
-                xfree(doid);
-                return(0);
-        }
-                
-       if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt,&oid)))) {
-               ssh_gssapi_userauth_error(ctxt);
-               return(0);
+       gss_OID_desc oid = {0, NULL};
+       Gssctxt *ctxt = NULL;
+       int mechs;
+       gss_OID_set supported;
+       int present;
+       OM_uint32 ms;
+       u_int len;
+       char *doid = NULL;
+
+       if (!authctxt->valid || authctxt->user == NULL)
+               return (0);
+
+       mechs = packet_get_int();
+       if (mechs == 0) {
+               debug("Mechanism negotiation is not supported");
+               return (0);
+       }
+
+       ssh_gssapi_supported_oids(&supported);
+       do {
+               mechs--;
+
+               if (doid)
+                       xfree(doid);
+
+               doid = packet_get_string(&len);
+
+               if (doid[0] != SSH_GSS_OIDTYPE || doid[1] != len-2) {
+                       logit("Mechanism OID received using the old encoding form");
+                       oid.elements = doid;
+                       oid.length = len;
+               } else {
+                       oid.elements = doid + 2;
+                       oid.length   = len - 2;
+               }
+               gss_test_oid_set_member(&ms, &oid, supported, &present);
+       } while (mechs > 0 && !present);
+
+       gss_release_oid_set(&ms, &supported);
+
+       if (!present) {
+               xfree(doid);
+               return (0);
+       }
+
+       if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, &oid)))) {
+               xfree(doid);
+               return (0);
        }
-       
-        authctxt->methoddata=(void *)ctxt;
 
-        /* Send SSH_MSG_USERAUTH_GSSAPI_RESPONSE */
+       authctxt->methoddata=(void *)ctxt;
 
        if (!compat20) {
 
@@ -126,132 +123,138 @@ userauth_gssapi(Authctxt *authctxt)
 
        } else {
 
-               packet_start(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE);
+       packet_start(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE);
 
-       /* Just return whatever they sent */
-       packet_put_string(doid,len);
+       /* Return OID in same format as we received it*/
+       packet_put_string(doid, len);
 
        } /* !compat20 */
-               
-        packet_send();
-        packet_write_wait();
-        xfree(doid);
+
+       packet_send();
+       xfree(doid);
 
        if (!compat20)
-       dispatch_set(SSH_MSG_AUTH_GSSAPI_TOKEN,
-                               &input_gssapi_token);
+       dispatch_set(SSH_MSG_AUTH_GSSAPI_TOKEN, &input_gssapi_token);
        else
-        dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, 
-                     &input_gssapi_token);
-        dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK,
-                    &input_gssapi_errtok);
-        authctxt->postponed = 1;
-        
-        return 0;
+       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token);
+       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok);
+       authctxt->postponed = 1;
+
+       return (0);
 }
 
 static void
 input_gssapi_token(int type, u_int32_t plen, void *ctxt)
 {
-        Authctxt *authctxt = ctxt;
-        Gssctxt *gssctxt;
-        gss_buffer_desc send_tok,recv_tok;
-        OM_uint32 maj_status, min_status;
-        u_int len;
-        
-        if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
-                fatal("No authentication or GSSAPI context");
-                
-        gssctxt=authctxt->methoddata;
-        recv_tok.value=packet_get_string(&len);
-        recv_tok.length=len; /* u_int vs. size_t */
-        
-        maj_status=PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok, 
-                                                &send_tok, NULL));
-        packet_check_eom();
-                        
-        if (GSS_ERROR(maj_status)) {
+       Authctxt *authctxt = ctxt;
+       Gssctxt *gssctxt;
+       gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
+       gss_buffer_desc recv_tok;
+       OM_uint32 maj_status, min_status;
+       u_int len;
+
+       if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
+               fatal("No authentication or GSSAPI context");
+
+       gssctxt = authctxt->methoddata;
+       recv_tok.value = packet_get_string(&len);
+       recv_tok.length = len; /* u_int vs. size_t */
+
+       packet_check_eom();
+
+       maj_status = PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok,
+           &send_tok, NULL));
+
+       xfree(recv_tok.value);
+
+       if (GSS_ERROR(maj_status)) {
                ssh_gssapi_userauth_error(gssctxt);
                if (send_tok.length != 0) {
-                   if (!compat20)
+                       if (!compat20)
                        packet_start(SSH_MSG_AUTH_GSSAPI_TOKEN);
-                   else
+                       else
                        packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK);
-                       packet_put_string(send_tok.value,send_tok.length);
-                       packet_send();
-                               packet_write_wait();
-                       }
-                authctxt->postponed = 0;
+                       packet_put_string(send_tok.value, send_tok.length);
+                       packet_send();
+               }
+               authctxt->postponed = 0;
                dispatch_set(SSH_MSG_AUTH_GSSAPI_TOKEN, NULL);
-                dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
-                userauth_finish(authctxt, 0, "gssapi");
-        } else {
-                       if (send_tok.length != 0) {
-                   if (!compat20)
+               dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
+               userauth_finish(authctxt, 0, "gssapi");
+       } else {
+               if (send_tok.length != 0) {
+                       if (!compat20)
                        packet_start(SSH_MSG_AUTH_GSSAPI_TOKEN);
-                   else
-                               packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
-                               packet_put_string(send_tok.value,send_tok.length);
-                               packet_send();
-                               packet_write_wait();
-                }
-               if (maj_status == GSS_S_COMPLETE) {
+                       else
+                       packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
+                       packet_put_string(send_tok.value, send_tok.length);
+                       packet_send();
+               }
+               if (maj_status == GSS_S_COMPLETE) {
                        dispatch_set(SSH_MSG_AUTH_GSSAPI_TOKEN, NULL);
-                       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN,NULL);
+                       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
                        if (!compat20)
                        input_gssapi_exchange_complete(0, 0, ctxt);
                        else
-                       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE,
-                                    &input_gssapi_exchange_complete);
-                }
-        }
-        
-        gss_release_buffer(&min_status, &send_tok);        
+                       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE,
+                                    &input_gssapi_exchange_complete);
+               }
+       }
+
+       gss_release_buffer(&min_status, &send_tok);
 }
 
 static void
 input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
 {
-        Authctxt *authctxt = ctxt;
-        Gssctxt *gssctxt;
-        gss_buffer_desc send_tok,recv_tok;
-        OM_uint32 maj_status;
-        
-        if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
-                fatal("No authentication or GSSAPI context");
-                
-        gssctxt=authctxt->methoddata;
-        recv_tok.value=packet_get_string(&recv_tok.length);
-        
-        /* Push the error token into GSSAPI to see what it says */
-        maj_status=PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok, 
-                                                &send_tok, NULL));
-        packet_check_eom();
+       Authctxt *authctxt = ctxt;
+       Gssctxt *gssctxt;
+       gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
+       gss_buffer_desc recv_tok;
+       OM_uint32 maj_status;
+       u_int len;
+
+       if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
+               fatal("No authentication or GSSAPI context");
+
+       gssctxt = authctxt->methoddata;
+       recv_tok.value = packet_get_string(&len);
+       recv_tok.length = len;
+
+       packet_check_eom();
+
+       /* Push the error token into GSSAPI to see what it says */
+       maj_status = PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok,
+           &send_tok, NULL));
+
+       xfree(recv_tok.value);
 
        /* We can't return anything to the client, even if we wanted to */
        dispatch_set(SSH_MSG_AUTH_GSSAPI_TOKEN, NULL);
        dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
-       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK,NULL);
+       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
 
        /* The client will have already moved on to the next auth */
-       
+
+       gss_release_buffer(&maj_status, &send_tok);
 }
 
-/* This is called when the client thinks we've completed authentication.
+/*
+ * This is called when the client thinks we've completed authentication.
  * It should only be enabled in the dispatch handler by the function above,
  * which only enables it once the GSSAPI exchange is complete.
  */
+
 static void
 input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt)
 {
-        Authctxt *authctxt = ctxt;
-        Gssctxt *gssctxt;
-        int authenticated;
-        
+       Authctxt *authctxt = ctxt;
+       Gssctxt *gssctxt;
+       int authenticated;
+
        if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
-                fatal("No authentication or GSSAPI context");
-                
+               fatal("No authentication or GSSAPI context");
+
        if ((strcmp(authctxt->user, "") == 0) && (authctxt->pw == NULL)) {
            char *lname = NULL;
            PRIVSEP(ssh_gssapi_localname(&lname));
@@ -274,8 +277,8 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt)
            goto finish;
        }
 
-        gssctxt=authctxt->methoddata;
-        
+       gssctxt = authctxt->methoddata;
+
        /* ssh1 needs to exchange the hash of the keys */
        if (!compat20) {
 
@@ -297,20 +300,22 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt)
                gss_release_buffer(&min_status,&msg_tok);
        }
 
-  
-       /* We don't need to check the status, because the stored credentials
+       /*
+        * 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.
         */
 
-        authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
+       packet_check_eom();
+
+       authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
 
 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_EXCHANGE_COMPLETE, NULL);
-        userauth_finish(authctxt, authenticated, "gssapi");
+       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_EXCHANGE_COMPLETE, NULL);
+       userauth_finish(authctxt, authenticated, "gssapi");
 }
 
 static void ssh_gssapi_userauth_error(Gssctxt *ctxt) {
@@ -341,9 +346,9 @@ Authmethod method_external = {
 };
        
 Authmethod method_gssapi = {
-        "gssapi",
-        userauth_gssapi,
-        &options.gss_authentication
+       "gssapi",
+       userauth_gssapi,
+       &options.gss_authentication
 };
 
 #endif /* GSSAPI */
index 2bde7bb79ec4d603d7bede610a65fa5bf93ee37f..505d3eff458758323cb9688f12692857c587b7f1 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth2-hostbased.c,v 1.2 2002/05/31 11:35:15 markus Exp $");
+RCSID("$OpenBSD: auth2-hostbased.c,v 1.5 2003/06/24 08:23:46 markus Exp $");
 
 #include "ssh2.h"
 #include "xmalloc.h"
@@ -42,7 +42,7 @@ RCSID("$OpenBSD: auth2-hostbased.c,v 1.2 2002/05/31 11:35:15 markus Exp $");
 /* import */
 extern ServerOptions options;
 extern u_char *session_id2;
-extern int session_id2_len;
+extern u_int session_id2_len;
 
 static int
 userauth_hostbased(Authctxt *authctxt)
@@ -77,7 +77,7 @@ userauth_hostbased(Authctxt *authctxt)
        pktype = key_type_from_name(pkalg);
        if (pktype == KEY_UNSPEC) {
                /* this is perfectly legal */
-               log("userauth_hostbased: unsupported "
+               logit("userauth_hostbased: unsupported "
                    "public key algorithm: %s", pkalg);
                goto done;
        }
@@ -136,7 +136,7 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
        HostStatus host_status;
        int len;
 
-       resolvedname = get_canonical_hostname(options.verify_reverse_mapping);
+       resolvedname = get_canonical_hostname(options.use_dns);
        ipaddr = get_remote_ipaddr();
 
        debug2("userauth_hostbased: chost %s resolvedname %s ipaddr %s",
@@ -152,7 +152,7 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
                        chost[len - 1] = '\0';
                }
                if (strcasecmp(resolvedname, chost) != 0)
-                       log("userauth_hostbased mismatch: "
+                       logit("userauth_hostbased mismatch: "
                            "client sends %s, but we resolve %s to %s",
                            chost, ipaddr, resolvedname);
                if (auth_rhosts2(pw, cuser, resolvedname, ipaddr) == 0)
index e609928815530ce6e1b9b2abbfde876bfa4de8fe..1696ef4d3b55cb318f63d8114c3a7a3747ac1131 100644 (file)
@@ -49,10 +49,6 @@ userauth_kbdint(Authctxt *authctxt)
        if (options.challenge_response_authentication)
                authenticated = auth2_challenge(authctxt, devs);
 
-#ifdef USE_PAM
-       if (authenticated == 0 && options.pam_authentication_via_kbd_int)
-               authenticated = auth2_pam(authctxt);
-#endif
        xfree(devs);
        xfree(lang);
 #ifdef HAVE_CYGWIN
index 692a2961f9e7b10cfbfd26d44c78cd725eed950d..c342addeca5ad43b9addfe0906e7506a09301a05 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth2-none.c,v 1.4 2002/06/27 10:35:47 deraadt Exp $");
+RCSID("$OpenBSD: auth2-none.c,v 1.6 2003/08/26 09:58:43 markus Exp $");
 
 #include "auth.h"
 #include "xmalloc.h"
@@ -100,7 +100,9 @@ userauth_none(Authctxt *authctxt)
        if (check_nt_auth(1, authctxt->pw) == 0)
                return(0);
 #endif
-       return PRIVSEP(auth_password(authctxt, "")) && authctxt->valid;
+       if (options.password_authentication)
+               return (PRIVSEP(auth_password(authctxt, "")));
+       return (0);
 }
 
 Authmethod method_none = {
diff --git a/openssh/auth2-pam.c b/openssh/auth2-pam.c
deleted file mode 100644 (file)
index b6eaf08..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-#include "includes.h"
-RCSID("$Id$");
-
-#ifdef USE_PAM
-#include <security/pam_appl.h>
-
-#include "ssh.h"
-#include "ssh2.h"
-#include "auth.h"
-#include "auth-pam.h"
-#include "packet.h"
-#include "xmalloc.h"
-#include "dispatch.h"
-#include "log.h"
-
-static int do_pam_conversation_kbd_int(int num_msg, 
-    const struct pam_message **msg, struct pam_response **resp, 
-    void *appdata_ptr);
-void input_userauth_info_response_pam(int type, int plen, void *ctxt);
-
-struct {
-       int finished, num_received, num_expected;
-       int *prompts;
-       struct pam_response *responses;
-} context_pam2 = {0, 0, 0, NULL};
-
-static struct pam_conv conv2 = {
-       do_pam_conversation_kbd_int,
-       NULL,
-};
-
-int
-auth2_pam(Authctxt *authctxt)
-{
-       int retval = -1;
-
-       if (authctxt->user == NULL)
-               fatal("auth2_pam: internal error: no user");
-
-       conv2.appdata_ptr = authctxt;
-       do_pam_set_conv(&conv2);
-
-       dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE,
-           &input_userauth_info_response_pam);
-       retval = (do_pam_authenticate(0) == PAM_SUCCESS);
-       dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL);
-
-       return retval;
-}
-
-static int
-do_pam_conversation_kbd_int(int num_msg, const struct pam_message **msg,
-    struct pam_response **resp, void *appdata_ptr)
-{
-       int i, j, done;
-       char *text;
-
-       context_pam2.finished = 0;
-       context_pam2.num_received = 0;
-       context_pam2.num_expected = 0;
-       context_pam2.prompts = xmalloc(sizeof(int) * num_msg);
-       context_pam2.responses = xmalloc(sizeof(struct pam_response) * num_msg);
-       memset(context_pam2.responses, 0, sizeof(struct pam_response) * num_msg);
-
-       text = NULL;
-       for (i = 0, context_pam2.num_expected = 0; i < num_msg; i++) {
-               int style = PAM_MSG_MEMBER(msg, i, msg_style);
-               switch (style) {
-               case PAM_PROMPT_ECHO_ON:
-               case PAM_PROMPT_ECHO_OFF:
-                       context_pam2.num_expected++;
-                       break;
-               case PAM_TEXT_INFO:
-               case PAM_ERROR_MSG:
-               default:
-                       /* Capture all these messages to be sent at once */
-                       message_cat(&text, PAM_MSG_MEMBER(msg, i, msg));
-                       break;
-               }
-       }
-
-       if (context_pam2.num_expected == 0)
-               return PAM_SUCCESS;
-
-       packet_start(SSH2_MSG_USERAUTH_INFO_REQUEST);
-       packet_put_cstring(""); /* Name */
-       packet_put_cstring(""); /* Instructions */
-       packet_put_cstring(""); /* Language */
-       packet_put_int(context_pam2.num_expected);
-       
-       for (i = 0, j = 0; i < num_msg; i++) {
-               int style = PAM_MSG_MEMBER(msg, i, msg_style);
-               
-               /* Skip messages which don't need a reply */
-               if (style != PAM_PROMPT_ECHO_ON && style != PAM_PROMPT_ECHO_OFF)
-                       continue;
-               
-               context_pam2.prompts[j++] = i;
-               if (text) {
-                       message_cat(&text, PAM_MSG_MEMBER(msg, i, msg));
-                       packet_put_cstring(text);
-                       text = NULL;
-               } else
-                       packet_put_cstring(PAM_MSG_MEMBER(msg, i, msg));
-               packet_put_char(style == PAM_PROMPT_ECHO_ON);
-       }
-       packet_send();
-       packet_write_wait();
-
-       /*
-        * Grabbing control of execution and spinning until we get what
-        * we want is probably rude, but it seems to work properly, and
-        * the client *should* be in lock-step with us, so the loop should
-        * only be traversed once.
-        */
-       while(context_pam2.finished == 0) {
-               done = 1;
-               dispatch_run(DISPATCH_BLOCK, &done, appdata_ptr);
-               if(context_pam2.finished == 0)
-                       debug("extra packet during conversation");
-       }
-
-       if(context_pam2.num_received == context_pam2.num_expected) {
-               *resp = context_pam2.responses;
-               return PAM_SUCCESS;
-       } else
-               return PAM_CONV_ERR;
-}
-
-void
-input_userauth_info_response_pam(int type, int plen, void *ctxt)
-{
-       Authctxt *authctxt = ctxt;
-       unsigned int nresp = 0, rlen = 0, i = 0;
-       char *resp;
-
-       if (authctxt == NULL)
-               fatal("input_userauth_info_response_pam: no authentication context");
-
-       nresp = packet_get_int();       /* Number of responses. */
-       debug("got %d responses", nresp);
-
-       for (i = 0; i < nresp; i++) {
-               int j = context_pam2.prompts[i];
-
-               resp = packet_get_string(&rlen);
-               context_pam2.responses[j].resp_retcode = PAM_SUCCESS;
-               context_pam2.responses[j].resp = xstrdup(resp);
-               xfree(resp);
-               context_pam2.num_received++;
-       }
-
-       context_pam2.finished = 1;
-
-       packet_done();
-}
-
-#endif
diff --git a/openssh/auth2-pam.h b/openssh/auth2-pam.h
deleted file mode 100644 (file)
index 7992803..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-/* $Id$ */
-
-#include "includes.h"
-#ifdef USE_PAM
-
-int    auth2_pam(Authctxt *authctxt);
-
-#endif /* USE_PAM */
index 5026969f89f0f39c637c3da67d3c278d56f345a6..67fb4c9216be4445e0e4200d58b6062342bc6f2b 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth2-passwd.c,v 1.2 2002/05/31 11:35:15 markus Exp $");
+RCSID("$OpenBSD: auth2-passwd.c,v 1.4 2003/08/26 09:58:43 markus Exp $");
 
 #include "xmalloc.h"
 #include "packet.h"
@@ -44,10 +44,10 @@ userauth_passwd(Authctxt *authctxt)
        u_int len;
        change = packet_get_char();
        if (change)
-               log("password change not supported");
+               logit("password change not supported");
        password = packet_get_string(&len);
        packet_check_eom();
-       if (PRIVSEP(auth_password(authctxt, password)) == 1 && authctxt->valid
+       if (PRIVSEP(auth_password(authctxt, password)) == 1
 #ifdef HAVE_CYGWIN
            && check_nt_auth(1, authctxt->pw)
 #endif
index 947bfed0bb47e3832e74dde2c3662240dc9471fb..d51e939f19d42ba087b0b56ff8860d085e6afe90 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth2-pubkey.c,v 1.2 2002/05/31 11:35:15 markus Exp $");
+RCSID("$OpenBSD: auth2-pubkey.c,v 1.4 2003/06/24 08:23:46 markus Exp $");
 
 #include "ssh2.h"
 #include "xmalloc.h"
@@ -44,7 +44,7 @@ RCSID("$OpenBSD: auth2-pubkey.c,v 1.2 2002/05/31 11:35:15 markus Exp $");
 /* import */
 extern ServerOptions options;
 extern u_char *session_id2;
-extern int session_id2_len;
+extern u_int session_id2_len;
 
 static int
 userauth_pubkey(Authctxt *authctxt)
@@ -78,7 +78,7 @@ userauth_pubkey(Authctxt *authctxt)
        pktype = key_type_from_name(pkalg);
        if (pktype == KEY_UNSPEC) {
                /* this is perfectly legal */
-               log("userauth_pubkey: unsupported public key algorithm: %s",
+               logit("userauth_pubkey: unsupported public key algorithm: %s",
                    pkalg);
                goto done;
        }
@@ -199,7 +199,7 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
        if (options.strict_modes &&
            secure_filename(f, file, pw, line, sizeof(line)) != 0) {
                fclose(f);
-               log("Authentication refused: %s", line);
+               logit("Authentication refused: %s", line);
                restore_uid();
                return 0;
        }
index 8827896b7bde89d695e45daeb8f3cfdaab423d0b..57b391fd3b358681a95530e8d1e7e32cea39793e 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth2.c,v 1.96 2003/02/06 21:22:43 markus Exp $");
+RCSID("$OpenBSD: auth2.c,v 1.102 2003/08/26 09:58:43 markus Exp $");
 
 #include "ssh2.h"
 #include "ssh1.h"
@@ -44,7 +44,7 @@ RCSID("$OpenBSD: auth2.c,v 1.96 2003/02/06 21:22:43 markus Exp $");
 /* import */
 extern ServerOptions options;
 extern u_char *session_id2;
-extern int session_id2_len;
+extern u_int session_id2_len;
 
 Authctxt *x_authctxt = NULL;
 
@@ -67,6 +67,9 @@ Authmethod *authmethods[] = {
        &method_gssapi,
 #endif
        &method_pubkey,
+#ifdef GSSAPI
+       &method_gssapi,
+#endif
        &method_passwd,
        &method_kbdint,
        &method_hostbased,
@@ -98,10 +101,6 @@ do_authentication2(void)
        /* challenge-response is implemented via keyboard interactive */
        if (options.challenge_response_authentication)
                options.kbd_interactive_authentication = 1;
-       if (options.pam_authentication_via_kbd_int)
-               options.kbd_interactive_authentication = 1;
-       if (use_privsep)
-               options.pam_authentication_via_kbd_int = 0;
 
        dispatch_init(&dispatch_protocol_error);
        dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request);
@@ -213,13 +212,15 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
                        authctxt->valid = 1;
                        debug2("input_userauth_request: setting up authctxt for %s", user);
 #ifdef USE_PAM
-                       PRIVSEP(start_pam(authctxt->pw->pw_name));
+                       if (options.use_pam)
+                               PRIVSEP(start_pam(authctxt->pw->pw_name));
 #endif
                } else {
-                       authctxt->valid = 0;
-                       log("input_userauth_request: illegal user %s", user);
+                       logit("input_userauth_request: illegal user %s", user);
+                       authctxt->pw = fakepw();
 #ifdef USE_PAM
-                       PRIVSEP(start_pam("NOUSER"));
+                       if (options.use_pam)
+                               PRIVSEP(start_pam(user));
 #endif
                }
 #ifdef GSSAPI
@@ -275,10 +276,9 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method)
                authenticated = 0;
 
 #ifdef USE_PAM
-       if (!use_privsep && authenticated && authctxt->user && 
-           !do_pam_account(authctxt->user, NULL))
+       if (options.use_pam && authenticated && !PRIVSEP(do_pam_account()))
                authenticated = 0;
-#endif /* USE_PAM */
+#endif
 
 #ifdef _UNICOS
        if (authenticated && cray_access_denied(authctxt->user)) {
@@ -308,9 +308,8 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method)
                /* now we can break out */
                authctxt->success = 1;
        } else {
-               if (authctxt->failures++ > AUTH_FAIL_MAX) {
+               if (authctxt->failures++ > AUTH_FAIL_MAX)
                        packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
-               }
                if (!compat20) {
                /*
                 * Break out of the dispatch loop now and go back to
@@ -321,10 +320,6 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method)
                */
                authctxt->success = authctxt->postponed = 1;
                } else {
-#ifdef _UNICOS
-               if (strcmp(method, "password") == 0)
-                       cray_login_failure(authctxt->user, IA_UDBERR);
-#endif /* _UNICOS */
                methods = authmethods_get();
                packet_start(SSH2_MSG_USERAUTH_FAILURE);
                packet_put_cstring(methods);
index 0d1eff96ed3c69715a1a7c2d346f5e32c6fdbaa5..db98b1ef8cbe25efb14af231565ecb54162bd06f 100644 (file)
@@ -12,7 +12,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: canohost.c,v 1.35 2002/11/26 02:38:54 stevesk Exp $");
+RCSID("$OpenBSD: canohost.c,v 1.37 2003/06/02 09:17:34 markus Exp $");
 
 #include "packet.h"
 #include "xmalloc.h"
@@ -27,7 +27,7 @@ static void check_ip_options(int, char *);
  */
 
 static char *
-get_remote_hostname(int socket, int verify_reverse_mapping)
+get_remote_hostname(int socket, int use_dns)
 {
        struct sockaddr_storage from;
        int i;
@@ -72,6 +72,9 @@ get_remote_hostname(int socket, int verify_reverse_mapping)
            NULL, 0, NI_NUMERICHOST) != 0)
                fatal("get_remote_hostname: getnameinfo NI_NUMERICHOST failed");
 
+       if (!use_dns)
+               return xstrdup(ntop);
+
        if (from.ss_family == AF_INET)
                check_ip_options(socket, ntop);
 
@@ -80,14 +83,24 @@ get_remote_hostname(int socket, int verify_reverse_mapping)
        if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name),
            NULL, 0, NI_NAMEREQD) != 0) {
                /* Host name not found.  Use ip address. */
-#if 0
-               log("Could not reverse map address %.100s.", ntop);
-#endif
                return xstrdup(ntop);
        }
 
-       /* Got host name. */
-       name[sizeof(name) - 1] = '\0';
+       /*
+        * if reverse lookup result looks like a numeric hostname,
+        * someone is trying to trick us by PTR record like following:
+        *      1.1.1.10.in-addr.arpa.  IN PTR  2.3.4.5
+        */
+       memset(&hints, 0, sizeof(hints));
+       hints.ai_socktype = SOCK_DGRAM; /*dummy*/
+       hints.ai_flags = AI_NUMERICHOST;
+       if (getaddrinfo(name, "0", &hints, &ai) == 0) {
+               logit("Nasty PTR record \"%s\" is set up for %s, ignoring",
+                   name, ntop);
+               freeaddrinfo(ai);
+               return xstrdup(ntop);
+       }
+
        /*
         * Convert it to all lowercase (which is expected by the rest
         * of this software).
@@ -95,9 +108,6 @@ get_remote_hostname(int socket, int verify_reverse_mapping)
        for (i = 0; name[i]; i++)
                if (isupper(name[i]))
                        name[i] = tolower(name[i]);
-
-       if (!verify_reverse_mapping)
-               return xstrdup(name);
        /*
         * Map it back to an IP address and check that the given
         * address actually is an address of this host.  This is
@@ -111,7 +121,7 @@ get_remote_hostname(int socket, int verify_reverse_mapping)
        hints.ai_family = from.ss_family;
        hints.ai_socktype = SOCK_STREAM;
        if (getaddrinfo(name, NULL, &hints, &aitop) != 0) {
-               log("reverse mapping checking getaddrinfo for %.700s "
+               logit("reverse mapping checking getaddrinfo for %.700s "
                    "failed - POSSIBLE BREAKIN ATTEMPT!", name);
                return xstrdup(ntop);
        }
@@ -126,7 +136,7 @@ get_remote_hostname(int socket, int verify_reverse_mapping)
        /* If we reached the end of the list, the address was not there. */
        if (!ai) {
                /* Address not found for the host name. */
-               log("Address %.100s maps to %.600s, but this does not "
+               logit("Address %.100s maps to %.600s, but this does not "
                    "map back to the address - POSSIBLE BREAKIN ATTEMPT!",
                    ntop, name);
                return xstrdup(ntop);
@@ -149,6 +159,7 @@ get_remote_hostname(int socket, int verify_reverse_mapping)
 static void
 check_ip_options(int socket, char *ipaddr)
 {
+#ifdef IP_OPTIONS
        u_char options[200];
        char text[sizeof(options) * 3 + 1];
        socklen_t option_size;
@@ -166,11 +177,12 @@ check_ip_options(int socket, char *ipaddr)
                for (i = 0; i < option_size; i++)
                        snprintf(text + i*3, sizeof(text) - i*3,
                            " %2.2x", options[i]);
-               log("Connection from %.100s with IP options:%.800s",
+               logit("Connection from %.100s with IP options:%.800s",
                    ipaddr, text);
                packet_disconnect("Connection from %.100s with IP options:%.800s",
                    ipaddr, text);
        }
+#endif /* IP_OPTIONS */
 }
 
 /*
@@ -180,14 +192,14 @@ check_ip_options(int socket, char *ipaddr)
  */
 
 const char *
-get_canonical_hostname(int verify_reverse_mapping)
+get_canonical_hostname(int use_dns)
 {
        static char *canonical_host_name = NULL;
-       static int verify_reverse_mapping_done = 0;
+       static int use_dns_done = 0;
 
        /* Check if we have previously retrieved name with same option. */
        if (canonical_host_name != NULL) {
-               if (verify_reverse_mapping_done != verify_reverse_mapping)
+               if (use_dns_done != use_dns)
                        xfree(canonical_host_name);
                else
                        return canonical_host_name;
@@ -196,11 +208,11 @@ get_canonical_hostname(int verify_reverse_mapping)
        /* Get the real hostname if socket; otherwise return UNKNOWN. */
        if (packet_connection_is_on_socket())
                canonical_host_name = get_remote_hostname(
-                   packet_get_connection_in(), verify_reverse_mapping);
+                   packet_get_connection_in(), use_dns);
        else
                canonical_host_name = xstrdup("UNKNOWN");
 
-       verify_reverse_mapping_done = verify_reverse_mapping;
+       use_dns_done = use_dns;
        return canonical_host_name;
 }
 
@@ -294,11 +306,11 @@ get_remote_ipaddr(void)
 }
 
 const char *
-get_remote_name_or_ip(u_int utmp_len, int verify_reverse_mapping)
+get_remote_name_or_ip(u_int utmp_len, int use_dns)
 {
        static const char *remote = "";
        if (utmp_len > 0)
-               remote = get_canonical_hostname(verify_reverse_mapping);
+               remote = get_canonical_hostname(use_dns);
        if (utmp_len == 0 || strlen(remote) > utmp_len)
                remote = get_remote_ipaddr();
        return remote;
index b5d38747ed8039124eb2a7ec61ee1f8db95da621..e7c3c5411e3d6d821c52b6b9aa410cae3ff16ed0 100644 (file)
@@ -35,7 +35,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: cipher.c,v 1.62 2002/11/21 22:45:31 markus Exp $");
+RCSID("$OpenBSD: cipher.c,v 1.65 2003/05/17 04:27:52 markus Exp $");
 
 #include "xmalloc.h"
 #include "log.h"
@@ -49,11 +49,14 @@ RCSID("$OpenBSD: cipher.c,v 1.62 2002/11/21 22:45:31 markus Exp $");
 #endif
 
 #if OPENSSL_VERSION_NUMBER < 0x00907000L
-#include "rijndael.h"
-static const EVP_CIPHER *evp_rijndael(void);
+extern const EVP_CIPHER *evp_rijndael(void);
+extern void ssh_rijndael_iv(EVP_CIPHER_CTX *, int, u_char *, u_int);
 #endif
-static const EVP_CIPHER *evp_ssh1_3des(void);
-static const EVP_CIPHER *evp_ssh1_bf(void);
+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);
+extern const EVP_CIPHER *evp_aes_128_ctr(void);
+extern void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int);
 
 struct Cipher {
        char    *name;
@@ -84,6 +87,9 @@ struct Cipher {
        { "rijndael-cbc@lysator.liu.se",
                                SSH_CIPHER_SSH2, 16, 32, EVP_aes_256_cbc },
 #endif
+       { "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 },
 
        { NULL,                 SSH_CIPHER_ILLEGAL, 0, 0, NULL }
 };
@@ -296,298 +302,6 @@ cipher_set_key_string(CipherContext *cc, Cipher *cipher,
        memset(&md, 0, sizeof(md));
 }
 
-/* Implementations for other non-EVP ciphers */
-
-/*
- * This is used by SSH1:
- *
- * What kind of triple DES are these 2 routines?
- *
- * Why is there a redundant initialization vector?
- *
- * If only iv3 was used, then, this would till effect have been
- * outer-cbc. However, there is also a private iv1 == iv2 which
- * perhaps makes differential analysis easier. On the other hand, the
- * private iv1 probably makes the CRC-32 attack ineffective. This is a
- * result of that there is no longer any known iv1 to use when
- * choosing the X block.
- */
-struct ssh1_3des_ctx
-{
-       EVP_CIPHER_CTX  k1, k2, k3;
-};
-
-static int
-ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
-    int enc)
-{
-       struct ssh1_3des_ctx *c;
-       u_char *k1, *k2, *k3;
-
-       if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
-               c = xmalloc(sizeof(*c));
-               EVP_CIPHER_CTX_set_app_data(ctx, c);
-       }
-       if (key == NULL)
-               return (1);
-       if (enc == -1)
-               enc = ctx->encrypt;
-       k1 = k2 = k3 = (u_char *) key;
-       k2 += 8;
-       if (EVP_CIPHER_CTX_key_length(ctx) >= 16+8) {
-               if (enc)
-                       k3 += 16;
-               else
-                       k1 += 16;
-       }
-       EVP_CIPHER_CTX_init(&c->k1);
-       EVP_CIPHER_CTX_init(&c->k2);
-       EVP_CIPHER_CTX_init(&c->k3);
-#ifdef SSH_OLD_EVP
-       EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc);
-       EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc);
-       EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc);
-#else
-       if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 ||
-           EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 ||
-           EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) {
-               memset(c, 0, sizeof(*c));
-               xfree(c);
-               EVP_CIPHER_CTX_set_app_data(ctx, NULL);
-               return (0);
-       }
-#endif
-       return (1);
-}
-
-static int
-ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, u_int len)
-{
-       struct ssh1_3des_ctx *c;
-
-       if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
-               error("ssh1_3des_cbc: no context");
-               return (0);
-       }
-#ifdef SSH_OLD_EVP
-       EVP_Cipher(&c->k1, dest, (u_char *)src, len);
-       EVP_Cipher(&c->k2, dest, dest, len);
-       EVP_Cipher(&c->k3, dest, dest, len);
-#else
-       if (EVP_Cipher(&c->k1, dest, (u_char *)src, len) == 0 ||
-           EVP_Cipher(&c->k2, dest, dest, len) == 0 ||
-           EVP_Cipher(&c->k3, dest, dest, len) == 0)
-               return (0);
-#endif
-       return (1);
-}
-
-static int
-ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx)
-{
-       struct ssh1_3des_ctx *c;
-
-       if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
-               memset(c, 0, sizeof(*c));
-               xfree(c);
-               EVP_CIPHER_CTX_set_app_data(ctx, NULL);
-       }
-       return (1);
-}
-
-static const EVP_CIPHER *
-evp_ssh1_3des(void)
-{
-       static EVP_CIPHER ssh1_3des;
-
-       memset(&ssh1_3des, 0, sizeof(EVP_CIPHER));
-       ssh1_3des.nid = NID_undef;
-       ssh1_3des.block_size = 8;
-       ssh1_3des.iv_len = 0;
-       ssh1_3des.key_len = 16;
-       ssh1_3des.init = ssh1_3des_init;
-       ssh1_3des.cleanup = ssh1_3des_cleanup;
-       ssh1_3des.do_cipher = ssh1_3des_cbc;
-#ifndef SSH_OLD_EVP
-       ssh1_3des.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH;
-#endif
-       return (&ssh1_3des);
-}
-
-/*
- * SSH1 uses a variation on Blowfish, all bytes must be swapped before
- * and after encryption/decryption. Thus the swap_bytes stuff (yuk).
- */
-static void
-swap_bytes(const u_char *src, u_char *dst, int n)
-{
-       u_char c[4];
-
-       /* Process 4 bytes every lap. */
-       for (n = n / 4; n > 0; n--) {
-               c[3] = *src++;
-               c[2] = *src++;
-               c[1] = *src++;
-               c[0] = *src++;
-
-               *dst++ = c[0];
-               *dst++ = c[1];
-               *dst++ = c[2];
-               *dst++ = c[3];
-       }
-}
-
-#ifdef SSH_OLD_EVP
-static void bf_ssh1_init (EVP_CIPHER_CTX * ctx, const unsigned char *key,
-                         const unsigned char *iv, int enc)
-{
-       if (iv != NULL)
-               memcpy (&(ctx->oiv[0]), iv, 8);
-       memcpy (&(ctx->iv[0]), &(ctx->oiv[0]), 8);
-       if (key != NULL)
-               BF_set_key (&(ctx->c.bf_ks), EVP_CIPHER_CTX_key_length (ctx),
-                           key);
-}
-#endif
-static int (*orig_bf)(EVP_CIPHER_CTX *, u_char *, const u_char *, u_int) = NULL;
-
-static int
-bf_ssh1_cipher(EVP_CIPHER_CTX *ctx, u_char *out, const u_char *in, u_int len)
-{
-       int ret;
-
-       swap_bytes(in, out, len);
-       ret = (*orig_bf)(ctx, out, out, len);
-       swap_bytes(out, out, len);
-       return (ret);
-}
-
-static const EVP_CIPHER *
-evp_ssh1_bf(void)
-{
-       static EVP_CIPHER ssh1_bf;
-
-       memcpy(&ssh1_bf, EVP_bf_cbc(), sizeof(EVP_CIPHER));
-       orig_bf = ssh1_bf.do_cipher;
-       ssh1_bf.nid = NID_undef;
-#ifdef SSH_OLD_EVP
-       ssh1_bf.init = bf_ssh1_init;
-#endif
-       ssh1_bf.do_cipher = bf_ssh1_cipher;
-       ssh1_bf.key_len = 32;
-       return (&ssh1_bf);
-}
-
-#if OPENSSL_VERSION_NUMBER < 0x00907000L
-/* RIJNDAEL */
-#define RIJNDAEL_BLOCKSIZE 16
-struct ssh_rijndael_ctx
-{
-       rijndael_ctx    r_ctx;
-       u_char          r_iv[RIJNDAEL_BLOCKSIZE];
-};
-
-static int
-ssh_rijndael_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
-    int enc)
-{
-       struct ssh_rijndael_ctx *c;
-
-       if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
-               c = xmalloc(sizeof(*c));
-               EVP_CIPHER_CTX_set_app_data(ctx, c);
-       }
-       if (key != NULL) {
-               if (enc == -1)
-                       enc = ctx->encrypt;
-               rijndael_set_key(&c->r_ctx, (u_char *)key,
-                   8*EVP_CIPHER_CTX_key_length(ctx), enc);
-       }
-       if (iv != NULL)
-               memcpy(c->r_iv, iv, RIJNDAEL_BLOCKSIZE);
-       return (1);
-}
-
-static int
-ssh_rijndael_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src,
-    u_int len)
-{
-       struct ssh_rijndael_ctx *c;
-       u_char buf[RIJNDAEL_BLOCKSIZE];
-       u_char *cprev, *cnow, *plain, *ivp;
-       int i, j, blocks = len / RIJNDAEL_BLOCKSIZE;
-
-       if (len == 0)
-               return (1);
-       if (len % RIJNDAEL_BLOCKSIZE)
-               fatal("ssh_rijndael_cbc: bad len %d", len);
-       if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
-               error("ssh_rijndael_cbc: no context");
-               return (0);
-       }
-       if (ctx->encrypt) {
-               cnow  = dest;
-               plain = (u_char *)src;
-               cprev = c->r_iv;
-               for (i = 0; i < blocks; i++, plain+=RIJNDAEL_BLOCKSIZE,
-                   cnow+=RIJNDAEL_BLOCKSIZE) {
-                       for (j = 0; j < RIJNDAEL_BLOCKSIZE; j++)
-                               buf[j] = plain[j] ^ cprev[j];
-                       rijndael_encrypt(&c->r_ctx, buf, cnow);
-                       cprev = cnow;
-               }
-               memcpy(c->r_iv, cprev, RIJNDAEL_BLOCKSIZE);
-       } else {
-               cnow  = (u_char *) (src+len-RIJNDAEL_BLOCKSIZE);
-               plain = dest+len-RIJNDAEL_BLOCKSIZE;
-
-               memcpy(buf, cnow, RIJNDAEL_BLOCKSIZE);
-               for (i = blocks; i > 0; i--, cnow-=RIJNDAEL_BLOCKSIZE,
-                   plain-=RIJNDAEL_BLOCKSIZE) {
-                       rijndael_decrypt(&c->r_ctx, cnow, plain);
-                       ivp = (i == 1) ? c->r_iv : cnow-RIJNDAEL_BLOCKSIZE;
-                       for (j = 0; j < RIJNDAEL_BLOCKSIZE; j++)
-                               plain[j] ^= ivp[j];
-               }
-               memcpy(c->r_iv, buf, RIJNDAEL_BLOCKSIZE);
-       }
-       return (1);
-}
-
-static int
-ssh_rijndael_cleanup(EVP_CIPHER_CTX *ctx)
-{
-       struct ssh_rijndael_ctx *c;
-
-       if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
-               memset(c, 0, sizeof(*c));
-               xfree(c);
-               EVP_CIPHER_CTX_set_app_data(ctx, NULL);
-       }
-       return (1);
-}
-
-static const EVP_CIPHER *
-evp_rijndael(void)
-{
-       static EVP_CIPHER rijndal_cbc;
-
-       memset(&rijndal_cbc, 0, sizeof(EVP_CIPHER));
-       rijndal_cbc.nid = NID_undef;
-       rijndal_cbc.block_size = RIJNDAEL_BLOCKSIZE;
-       rijndal_cbc.iv_len = RIJNDAEL_BLOCKSIZE;
-       rijndal_cbc.key_len = 16;
-       rijndal_cbc.init = ssh_rijndael_init;
-       rijndal_cbc.cleanup = ssh_rijndael_cleanup;
-       rijndal_cbc.do_cipher = ssh_rijndael_cbc;
-#ifndef SSH_OLD_EVP
-       rijndal_cbc.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH |
-           EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV;
-#endif
-       return (&rijndal_cbc);
-}
-#endif
-
 /*
  * Exports an IV from the CipherContext required to export the key
  * state back from the unprivileged child to the privileged parent
@@ -611,7 +325,6 @@ void
 cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len)
 {
        Cipher *c = cc->cipher;
-       u_char *civ = NULL;
        int evplen;
 
        switch (c->number) {
@@ -624,45 +337,28 @@ cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len)
                if (evplen != len)
                        fatal("%s: wrong iv length %d != %d", __func__,
                            evplen, len);
-
 #if OPENSSL_VERSION_NUMBER < 0x00907000L
-               if (c->evptype == evp_rijndael) {
-                       struct ssh_rijndael_ctx *aesc;
-
-                       aesc = EVP_CIPHER_CTX_get_app_data(&cc->evp);
-                       if (aesc == NULL)
-                               fatal("%s: no rijndael context", __func__);
-                       civ = aesc->r_iv;
-               } else
+               if (c->evptype == evp_rijndael)
+                       ssh_rijndael_iv(&cc->evp, 0, iv, len);
+               else
 #endif
-               {
-                       civ = cc->evp.iv;
-               }
+               if (c->evptype == evp_aes_128_ctr)
+                       ssh_aes_ctr_iv(&cc->evp, 0, iv, len);
+               else
+                       memcpy(iv, cc->evp.iv, len);
+               break;
+       case SSH_CIPHER_3DES:
+               ssh1_3des_iv(&cc->evp, 0, iv, 24);
                break;
-       case SSH_CIPHER_3DES: {
-               struct ssh1_3des_ctx *desc;
-               if (len != 24)
-                       fatal("%s: bad 3des iv length: %d", __func__, len);
-               desc = EVP_CIPHER_CTX_get_app_data(&cc->evp);
-               if (desc == NULL)
-                       fatal("%s: no 3des context", __func__);
-               debug3("%s: Copying 3DES IV", __func__);
-               memcpy(iv, desc->k1.iv, 8);
-               memcpy(iv + 8, desc->k2.iv, 8);
-               memcpy(iv + 16, desc->k3.iv, 8);
-               return;
-       }
        default:
                fatal("%s: bad cipher %d", __func__, c->number);
        }
-       memcpy(iv, civ, len);
 }
 
 void
 cipher_set_keyiv(CipherContext *cc, u_char *iv)
 {
        Cipher *c = cc->cipher;
-       u_char *div = NULL;
        int evplen = 0;
 
        switch (c->number) {
@@ -672,36 +368,22 @@ cipher_set_keyiv(CipherContext *cc, u_char *iv)
                evplen = EVP_CIPHER_CTX_iv_length(&cc->evp);
                if (evplen == 0)
                        return;
-
 #if OPENSSL_VERSION_NUMBER < 0x00907000L
-               if (c->evptype == evp_rijndael) {
-                       struct ssh_rijndael_ctx *aesc;
-
-                       aesc = EVP_CIPHER_CTX_get_app_data(&cc->evp);
-                       if (aesc == NULL)
-                               fatal("%s: no rijndael context", __func__);
-                       div = aesc->r_iv;
-               } else
+               if (c->evptype == evp_rijndael)
+                       ssh_rijndael_iv(&cc->evp, 1, iv, evplen);
+               else
 #endif
-               {
-                       div = cc->evp.iv;
-               }
+               if (c->evptype == evp_aes_128_ctr)
+                       ssh_aes_ctr_iv(&cc->evp, 1, iv, evplen);
+               else
+                       memcpy(cc->evp.iv, iv, evplen);
+               break;
+       case SSH_CIPHER_3DES:
+               ssh1_3des_iv(&cc->evp, 1, iv, 24);
                break;
-       case SSH_CIPHER_3DES: {
-               struct ssh1_3des_ctx *desc;
-               desc = EVP_CIPHER_CTX_get_app_data(&cc->evp);
-               if (desc == NULL)
-                       fatal("%s: no 3des context", __func__);
-               debug3("%s: Installed 3DES IV", __func__);
-               memcpy(desc->k1.iv, iv, 8);
-               memcpy(desc->k2.iv, iv + 8, 8);
-               memcpy(desc->k3.iv, iv + 16, 8);
-               return;
-       }
        default:
                fatal("%s: bad cipher %d", __func__, c->number);
        }
-       memcpy(div, iv, evplen);
 }
 
 #if OPENSSL_VERSION_NUMBER < 0x00907000L
index b3960b506fd50e4b3c0ddac8e241750edf088c58..6bc44d9f128cdfb592280b6eff56b85837dd8308 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: compat.c,v 1.66 2003/04/01 10:31:26 markus Exp $");
+RCSID("$OpenBSD: compat.c,v 1.69 2003/08/29 10:03:15 markus Exp $");
 
 #include "buffer.h"
 #include "packet.h"
@@ -139,12 +139,9 @@ compat_datafellows(const char *version)
                  "1.2.19*,"
                  "1.2.20*,"
                  "1.2.21*,"
-                 "1.2.22*",            SSH_BUG_IGNOREMSG|SSH_BUG_K5USER },
+                 "1.2.22*",            SSH_BUG_IGNOREMSG },
                { "1.3.2*",             /* F-Secure */
-                                       SSH_BUG_IGNOREMSG|SSH_BUG_K5USER },
-               { "1.2.1*,"
-                 "1.2.2*,"
-                 "1.2.3*",             SSH_BUG_K5USER },
+                                       SSH_BUG_IGNOREMSG },
                { "*SSH Compatible Server*",                    /* Netscreen */
                                        SSH_BUG_PASSWORDPAD },
                { "*OSU_0*,"
@@ -196,7 +193,7 @@ proto_spec(const char *spec)
                        ret |= SSH_PROTO_2;
                        break;
                default:
-                       log("ignoring bad proto spec: '%s'.", p);
+                       logit("ignoring bad proto spec: '%s'.", p);
                        break;
                }
        }
index b982d3e8f945ef9cf96641659dcdd747e900a1c1..2d875369e1affa136e9860a64844cf8b317dc209 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: compat.h,v 1.34 2003/04/01 10:31:26 markus Exp $      */
+/*     $OpenBSD: compat.h,v 1.36 2003/08/29 10:03:15 markus Exp $      */
 
 /*
  * Copyright (c) 1999, 2000, 2001 Markus Friedl.  All rights reserved.
 #define SSH_BUG_DERIVEKEY      0x00040000
 #define SSH_BUG_DUMMYCHAN      0x00100000
 #define SSH_BUG_EXTEOF         0x00200000
-#define SSH_BUG_K5USER         0x00400000
-#define SSH_BUG_PROBE          0x00800000
-#define SSH_BUG_FIRSTKEX       0x01000000
+#define SSH_BUG_PROBE          0x00400000
+#define SSH_BUG_FIRSTKEX       0x00800000
+#define SSH_BUG_GSSAPI_BER     0x01000000
 #define SSH_OLD_GSSAPI         0x02000000
-#define SSH_BUG_GSSAPI_BER     0x04000000
 #define SSH_BUG_GSS_EMPTYUSER  0x10000000
 
 void     enable_compat13(void);
index 439b34b92324b7da2f54437434fb6496465b30f4..308463dc0a1cc414aac7f02adfe65576575245ea 100644 (file)
@@ -9,6 +9,7 @@ AC_CANONICAL_HOST
 AC_C_BIGENDIAN
 
 # Checks for programs.
+AC_PROG_AWK
 AC_PROG_CPP
 AC_PROG_RANLIB
 AC_PROG_INSTALL
@@ -54,7 +55,6 @@ fi
 # Check for some target-specific stuff
 case "$host" in
 *-*-aix*)
-       AFS_LIBS="-lld"
        CPPFLAGS="$CPPFLAGS -I/usr/local/include"
        LDFLAGS="$LDFLAGS -L/usr/local/lib"
        AC_MSG_CHECKING([how to specify blibpath for linker ($LD)]) 
@@ -75,19 +75,36 @@ case "$host" in
                AC_MSG_RESULT($blibflags)
        fi
        LDFLAGS="$saved_LDFLAGS"
+       dnl Check for authenticate.  Might be in libs.a on older AIXes
        AC_CHECK_FUNC(authenticate, [AC_DEFINE(WITH_AIXAUTHENTICATE)],
                [AC_CHECK_LIB(s,authenticate,
                        [ AC_DEFINE(WITH_AIXAUTHENTICATE)
                                LIBS="$LIBS -ls"
                        ])
                ])
+       dnl Check if loginfailed is declared and takes 4 arguments (AIX >= 5.2)
+       AC_CHECK_DECL(loginfailed,
+                [AC_MSG_CHECKING(if loginfailed takes 4 arguments)
+                 AC_TRY_COMPILE(
+                       [#include <usersec.h>],
+                       [(void)loginfailed("user","host","tty",0);],
+                       [AC_MSG_RESULT(yes)
+                        AC_DEFINE(AIX_LOGINFAILED_4ARG)],
+                       [AC_MSG_RESULT(no)]
+               )],
+               [],
+               [#include <usersec.h>]
+       )
+       AC_CHECK_FUNCS(setauthdb)
        AC_DEFINE(BROKEN_GETADDRINFO)
        AC_DEFINE(BROKEN_REALPATH)
+       AC_DEFINE(SETEUID_BREAKS_SETUID)
+       AC_DEFINE(BROKEN_SETREUID)
+       AC_DEFINE(BROKEN_SETREGID)
        dnl AIX handles lastlog as part of its login message
        AC_DEFINE(DISABLE_LASTLOG)
        AC_DEFINE(LOGIN_NEEDS_UTMPX)
-       AC_DEFINE(SETPROCTITLE_STRATEGY,PS_USE_CLOBBER_ARGV)
-       AC_DEFINE(SETPROCTITLE_PS_PADDING, '\0')
+       AC_DEFINE(SPT_TYPE,SPT_REUSEARGV)
        ;;
 *-*-cygwin*)
        check_for_libcrypt_later=1
@@ -95,7 +112,6 @@ case "$host" in
        AC_DEFINE(HAVE_CYGWIN)
        AC_DEFINE(USE_PIPES)
        AC_DEFINE(DISABLE_SHADOW)
-       AC_DEFINE(IPV4_DEFAULT)
        AC_DEFINE(IP_TOS_IS_BROKEN)
        AC_DEFINE(NO_X11_UNIX_SOCKETS)
        AC_DEFINE(NO_IPPORT_RESERVED_CONCEPT)
@@ -129,7 +145,8 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
        AC_DEFINE(LOGIN_NEEDS_UTMPX)
        AC_DEFINE(DISABLE_SHADOW)
        AC_DEFINE(DISABLE_UTMP)
-       AC_DEFINE(SETPROCTITLE_STRATEGY,PS_USE_PSTAT)
+       AC_DEFINE(LOCKED_PASSWD_STRING, "*")
+       AC_DEFINE(SPT_TYPE,SPT_PSTAT)
        LIBS="$LIBS -lsec -lsecpw"
        AC_CHECK_LIB(xnet, t_error, ,AC_MSG_ERROR([*** -lxnet needed on HP-UX - check config.log ***]))
        disable_ptmx_check=yes
@@ -145,7 +162,8 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
        AC_DEFINE(LOGIN_NEEDS_UTMPX)
        AC_DEFINE(DISABLE_SHADOW)
        AC_DEFINE(DISABLE_UTMP)
-       AC_DEFINE(SETPROCTITLE_STRATEGY,PS_USE_PSTAT)
+       AC_DEFINE(LOCKED_PASSWD_STRING, "*")
+       AC_DEFINE(SPT_TYPE,SPT_PSTAT)
        LIBS="$LIBS -lsec"
        AC_CHECK_LIB(xnet, t_error, ,AC_MSG_ERROR([*** -lxnet needed on HP-UX - check config.log ***]))
        ;;
@@ -158,7 +176,8 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
        AC_DEFINE(LOGIN_NEEDS_UTMPX)
        AC_DEFINE(DISABLE_SHADOW)
        AC_DEFINE(DISABLE_UTMP)
-       AC_DEFINE(SETPROCTITLE_STRATEGY,PS_USE_PSTAT)
+       AC_DEFINE(LOCKED_PASSWD_STRING, "*")
+       AC_DEFINE(SPT_TYPE,SPT_PSTAT)
        LIBS="$LIBS -lsec"
        AC_CHECK_LIB(xnet, t_error, ,AC_MSG_ERROR([*** -lxnet needed on HP-UX - check config.log ***]))
        ;;
@@ -168,6 +187,7 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
        PATH="$PATH:/usr/etc"
        AC_DEFINE(BROKEN_INET_NTOA)
        AC_DEFINE(WITH_ABBREV_NO_TTY)
+       AC_DEFINE(LOCKED_PASSWD_STRING, "*LK*")
        ;;
 *-*-irix6*)
        CPPFLAGS="$CPPFLAGS -I/usr/local/include"
@@ -179,15 +199,22 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
        AC_CHECK_FUNC(jlimit_startjob, [AC_DEFINE(WITH_IRIX_JOBS)])
        AC_DEFINE(BROKEN_INET_NTOA)
        AC_DEFINE(WITH_ABBREV_NO_TTY)
+       AC_DEFINE(LOCKED_PASSWD_STRING, "*LK*")
        ;;
 *-*-linux*)
        no_dev_ptmx=1
        check_for_libcrypt_later=1
+       check_for_openpty_ctty_bug=1
        AC_DEFINE(DONT_TRY_OTHER_AF)
        AC_DEFINE(PAM_TTY_KLUDGE)
-       AC_DEFINE(SETPROCTITLE_STRATEGY,PS_USE_CLOBBER_ARGV)
-       AC_DEFINE(SETPROCTITLE_PS_PADDING, '\0')
+       AC_DEFINE(LOCKED_PASSWD_PREFIX, "!!")
+       AC_DEFINE(SPT_TYPE,SPT_REUSEARGV)
        inet6_default_4in6=yes
+       case `uname -r` in
+       1.*|2.0.*)
+               AC_DEFINE(BROKEN_CMSG_TYPE)
+               ;;
+       esac
        ;;
 mips-sony-bsd|mips-sony-newsos4)
        AC_DEFINE(HAVE_NEWS4)
@@ -220,7 +247,10 @@ mips-sony-bsd|mips-sony-newsos4)
        AC_DEFINE(LOGIN_NEEDS_UTMPX)
        AC_DEFINE(LOGIN_NEEDS_TERM)
        AC_DEFINE(PAM_TTY_KLUDGE)
-       AC_DEFINE(STREAMS_PUSH_ACQUIRES_CTTY)
+       AC_DEFINE(LOCKED_PASSWD_STRING, "*LK*")
+       # Pushing STREAMS modules will cause sshd to acquire a controlling tty.
+       AC_DEFINE(SSHD_ACQUIRES_CTTY)
+       external_path_file=/etc/default/login
        # hardwire lastlog location (can't detect it on some versions)
        conf_lastlog_location="/var/adm/lastlog"
        AC_MSG_CHECKING(for obsolete utmp and wtmp in solaris2.x)
@@ -247,6 +277,7 @@ mips-sony-bsd|mips-sony-newsos4)
        LDFLAGS="$LDFLAGS -L/usr/local/lib"
        LIBS="$LIBS -lc89"
        AC_DEFINE(USE_PIPES)
+       AC_DEFINE(SSHD_ACQUIRES_CTTY)
        ;;
 *-sni-sysv*)
        CPPFLAGS="$CPPFLAGS -I/usr/local/include"
@@ -255,6 +286,8 @@ mips-sony-bsd|mips-sony-newsos4)
        IPADDR_IN_DISPLAY=yes
        AC_DEFINE(USE_PIPES)
        AC_DEFINE(IP_TOS_IS_BROKEN)
+       AC_DEFINE(SSHD_ACQUIRES_CTTY)
+       external_path_file=/etc/default/login
        # /usr/ucblib/libucb.a no longer needed on ReliantUNIX
        # Attention: always take care to bind libsocket and libnsl before libc,
        # otherwise you will find lots of "SIOCGPGRP errno 22" on syslog
@@ -263,11 +296,17 @@ mips-sony-bsd|mips-sony-newsos4)
        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"
@@ -284,6 +323,7 @@ mips-sony-bsd|mips-sony-newsos4)
        AC_DEFINE(HAVE_SECUREWARE)
        AC_DEFINE(DISABLE_SHADOW)
        AC_DEFINE(BROKEN_SAVED_UIDS)
+       AC_DEFINE(WITH_ABBREV_NO_TTY)
        AC_CHECK_FUNCS(getluid setluid)
        MANTYPE=man
        do_sco3_extra_lib_check=yes
@@ -300,6 +340,10 @@ mips-sony-bsd|mips-sony-newsos4)
        AC_DEFINE(HAVE_SECUREWARE)
        AC_DEFINE(DISABLE_SHADOW)
        AC_DEFINE(DISABLE_FD_PASSING)
+       AC_DEFINE(SETEUID_BREAKS_SETUID)
+       AC_DEFINE(BROKEN_SETREUID)
+       AC_DEFINE(BROKEN_SETREGID)
+       AC_DEFINE(WITH_ABBREV_NO_TTY)
        AC_CHECK_FUNCS(getluid setluid)
        MANTYPE=man
        ;;
@@ -310,6 +354,14 @@ mips-sony-bsd|mips-sony-newsos4)
        LIBS="$LIBS -lgen -lrsc -lshare -luex -lacm"
        MANTYPE=cat
        ;;
+*-*-unicosmp*)
+       AC_DEFINE(WITH_ABBREV_NO_TTY)
+       AC_DEFINE(USE_PIPES)
+       AC_DEFINE(DISABLE_FD_PASSING)
+       LDFLAGS="$LDFLAGS"
+       LIBS="$LIBS -lgen -lacid"
+       MANTYPE=cat
+       ;;
 *-*-unicos*)
        AC_DEFINE(USE_PIPES)
        AC_DEFINE(DISABLE_FD_PASSING)
@@ -342,6 +394,8 @@ mips-sony-bsd|mips-sony-newsos4)
                fi
        fi
        AC_DEFINE(DISABLE_FD_PASSING)
+       AC_DEFINE(BROKEN_GETADDRINFO)
+       AC_DEFINE(LOCKED_PASSWD_SUBSTR, "Nologin")
        ;;
 
 *-*-nto-qnx)
@@ -387,14 +441,26 @@ AC_ARG_WITH(libs,
        ]       
 )
 
+AC_MSG_CHECKING(compiler and flags for sanity)
+AC_TRY_RUN([
+#include <stdio.h>
+int main(){exit(0);}
+       ],
+       [       AC_MSG_RESULT(yes) ],
+       [
+               AC_MSG_RESULT(no)
+               AC_MSG_ERROR([*** compiler cannot create working executables, check config.log ***])
+       ]
+)
+
 # Checks for header files.
-AC_CHECK_HEADERS(bstring.h crypt.h endian.h floatingpoint.h \
-       getopt.h glob.h ia.h lastlog.h libgen.h limits.h login.h \
+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 \
        rpc/types.h security/pam_appl.h shadow.h stddef.h stdint.h \
-       strings.h sys/bitypes.h sys/bsdtty.h sys/cdefs.h \
-       sys/mman.h sys/pstat.h sys/select.h sys/stat.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/un.h time.h tmpdir.h ttyent.h usersec.h \
        util.h utime.h utmp.h utmpx.h)
@@ -410,8 +476,46 @@ if test "x$with_tcp_wrappers" != "xno" ; then
     fi
 fi
 
+dnl IRIX and Solaris 2.5.1 have dirname() in libgen
+AC_CHECK_FUNCS(dirname, [AC_CHECK_HEADERS(libgen.h)] ,[
+       AC_CHECK_LIB(gen, dirname,[
+               AC_CACHE_CHECK([for broken dirname],
+                       ac_cv_have_broken_dirname, [
+                       save_LIBS="$LIBS"
+                       LIBS="$LIBS -lgen"
+                       AC_TRY_RUN(
+                               [
+#include <libgen.h>
+#include <string.h>
+
+int main(int argc, char **argv) {
+    char *s, buf[32];
+
+    strncpy(buf,"/etc", 32);
+    s = dirname(buf);
+    if (!s || strncmp(s, "/", 32) != 0) {
+       exit(1);
+    } else {
+       exit(0);
+    }
+}
+                               ],
+                               [ ac_cv_have_broken_dirname="no" ],
+                               [ ac_cv_have_broken_dirname="yes" ]
+                       )
+                       LIBS="$save_LIBS"
+               ])
+               if test "x$ac_cv_have_broken_dirname" = "xno" ; then
+                       LIBS="$LIBS -lgen"
+                       AC_DEFINE(HAVE_DIRNAME)
+                       AC_CHECK_HEADERS(libgen.h)
+               fi
+       ])
+])
+
 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],
@@ -727,64 +831,32 @@ 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 bcopy \
-       bindresvport_sa clock fchmod fchown freeaddrinfo futimes \
+       arc4random __b64_ntop b64_ntop __b64_pton b64_pton basename \
+       bcopy bindresvport_sa clock fchmod fchown freeaddrinfo futimes \
        gai_strerror getaddrinfo getcwd getgrouplist getnameinfo getopt \
-       getpeereid _getpty getrlimit getrusage getttyent glob inet_aton \
+       getpeereid _getpty getrlimit getttyent glob inet_aton \
        inet_ntoa inet_ntop innetgr login_getcapbool md5_crypt memmove \
-       mkdtemp mmap ngetaddrinfo nsleep ogetaddrinfo openpty pstat \
-       readpassphrase realpath recvmsg rresvport_af sendmsg setdtablesize \
-       setegid setenv seteuid setgroups setlogin setpcred setproctitle \
-       setresgid setreuid setrlimit setsid setvbuf sigaction sigvec \
-       snprintf socketpair strerror strlcat strlcpy strmode strnvis \
-       sysconf tcgetpgrp truncate utimes vhangup vsnprintf waitpid \
+       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 \
+       setsid setvbuf sigaction sigvec snprintf socketpair strerror \
+       strlcat strlcpy strmode strnvis sysconf tcgetpgrp \
+       truncate utimes vhangup vsnprintf waitpid \
 )
 
 AC_SEARCH_LIBS(nanosleep, rt posix4, AC_DEFINE(HAVE_NANOSLEEP))
-AC_SEARCH_LIBS(basename, gen, AC_DEFINE(HAVE_BASENAME))
 
-dnl IRIX has basename() in libgen
-AC_SEARCH_LIBS(basename, gen, AC_DEFINE(HAVE_BASENAME))
-
-dnl Make sure strsep prototype is defined before defining HAVE_STRSEP
+dnl Make sure prototypes are defined for these before using them.
 AC_CHECK_DECL(strsep, [AC_CHECK_FUNCS(strsep)])
+AC_CHECK_DECL(getrusage, [AC_CHECK_FUNCS(getrusage)])
 
-dnl IRIX and Solaris 2.5.1 have dirname() in libgen
-AC_CHECK_FUNCS(dirname, [AC_CHECK_HEADERS(libgen.h)] ,[
-       AC_CHECK_LIB(gen, dirname,[
-               AC_CACHE_CHECK([for broken dirname],
-                       ac_cv_have_broken_dirname, [
-                       save_LIBS="$LIBS"
-                       LIBS="$LIBS -lgen"
-                       AC_TRY_RUN(
-                               [
-#include <libgen.h>
-#include <string.h>
-
-int main(int argc, char **argv) {
-    char *s, buf[32];
-
-    strncpy(buf,"/etc", 32);
-    s = dirname(buf);
-    if (!s || strncmp(s, "/", 32) != 0) {
-       exit(1);
-    } else {
-       exit(0);
-    }
-}
-                               ],
-                               [ ac_cv_have_broken_dirname="no" ],
-                               [ ac_cv_have_broken_dirname="yes" ]
-                       )
-                       LIBS="$save_LIBS"
-               ])
-               if test "x$ac_cv_have_broken_dirname" = "xno" ; then
-                       LIBS="$LIBS -lgen"
-                       AC_DEFINE(HAVE_DIRNAME)
-                       AC_CHECK_HEADERS(libgen.h)
-               fi
-       ])
-])
+dnl tcsendbreak might be a macro
+AC_CHECK_DECL(tcsendbreak,
+       [AC_DEFINE(HAVE_TCSENDBREAK)],
+       [AC_CHECK_FUNCS(tcsendbreak)], 
+       [#include <termios.h>]
+)
 
 dnl    Checks for time functions
 AC_CHECK_FUNCS(gettimeofday time)
@@ -848,6 +920,53 @@ unlink(template); exit(0);
 )
 fi
 
+dnl make sure that openpty does not reacquire controlling terminal
+if test ! -z "$check_for_openpty_ctty_bug"; then
+       AC_MSG_CHECKING(if openpty correctly handles controlling tty)
+       AC_TRY_RUN(
+               [
+#include <stdio.h>
+#include <sys/fcntl.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+int
+main()
+{
+       pid_t pid;
+       int fd, ptyfd, ttyfd, status;
+
+       pid = fork();
+       if (pid < 0) {          /* failed */
+               exit(1);
+       } else if (pid > 0) {   /* parent */
+               waitpid(pid, &status, 0);
+               if (WIFEXITED(status)) 
+                       exit(WEXITSTATUS(status));
+               else
+                       exit(2);
+       } else {                /* child */
+               close(0); close(1); close(2);
+               setsid();
+               openpty(&ptyfd, &ttyfd, NULL, NULL, NULL);
+               fd = open("/dev/tty", O_RDWR | O_NOCTTY);
+               if (fd >= 0)
+                       exit(3);        /* Acquired ctty: broken */
+               else
+                       exit(0);        /* Did not acquire ctty: OK */
+       }
+}
+               ],
+               [
+                       AC_MSG_RESULT(yes)
+               ],
+               [
+                       AC_MSG_RESULT(no)
+                       AC_DEFINE(SSHD_ACQUIRES_CTTY)
+               ]
+       )
+fi
+
 AC_FUNC_GETPGRP
 
 # Check for PAM libs
@@ -1030,13 +1149,15 @@ int main(void) { exit(SSLeay() == OPENSSL_VERSION_NUMBER ? 0 : 1); }
        ],
        [
                AC_MSG_RESULT(no)
-               AC_MSG_ERROR(Your OpenSSL headers do not match your library)
+               AC_MSG_ERROR([Your OpenSSL headers do not match your library.
+Check config.log for details.
+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
-if test "x$PAM_MSG" = "xno" -a "x$check_for_libcrypt_later" = "x1"; then
+if test "x$check_for_libcrypt_later" = "x1"; then
        AC_CHECK_LIB(crypt, crypt, LIBS="$LIBS -lcrypt")
 fi
 
@@ -1877,7 +1998,6 @@ if test "x$ac_cv_libc_defines_sys_nerr" = "xyes" ; then
 fi
 
 SCARD_MSG="no" 
-
 # Check whether user wants sectok support
 AC_ARG_WITH(sectok,
        [  --with-sectok           Enable smartcard support using libsectok],
@@ -1927,6 +2047,29 @@ if test x$opensc_config_prefix != x ; then
   fi
 fi
 
+# Check whether user wants DNS support
+DNS_MSG="no" 
+AC_ARG_WITH(dns,
+       [  --with-dns              Support for fetching keys from DNS (experimental)],
+       [
+               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
+       ]
+)
+
 # Check whether user wants Kerberos 5 support
 KRB5_MSG="no" 
 AC_ARG_WITH(kerberos5,
@@ -1959,7 +2102,32 @@ AC_ARG_WITH(kerberos5,
                         if test ! -z "$blibpath" ; then
                                 blibpath="$blibpath:${KRB5ROOT}/lib"
                         fi
-                        AC_CHECK_LIB(resolv, dn_expand, , )
+                       AC_SEARCH_LIBS(dn_expand, resolv)
+
+                       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])
+                                 ) 
+                               ]
+                       )
+
+                       oldCPP="$CPPFLAGS"
+                       CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include/gssapi"
+                       AC_CHECK_HEADER(gssapi_krb5.h, ,
+                                       [ CPPFLAGS="$oldCPP" ])
 
                        # If we're using some other GSSAPI
                        if test "$GSSAPI" -a "$GSSAPI" != "mechglue"; then
@@ -2006,60 +2174,6 @@ AC_ARG_WITH(kerberos5,
                 fi
         ]
 )
-# Check whether user wants Kerberos 4 support
-KRB4_MSG="no" 
-AC_ARG_WITH(kerberos4,
-       [  --with-kerberos4=PATH   Enable Kerberos 4 support],
-       [
-               if test "x$withval" != "xno" ; then
-                       if test "x$withval" != "xyes" ; then
-                               CPPFLAGS="$CPPFLAGS -I${withval}/include"
-                               LDFLAGS="$LDFLAGS -L${withval}/lib"
-                               if test ! -z "$need_dash_r" ; then
-                                       LDFLAGS="$LDFLAGS -R${withval}/lib"
-                               fi
-                               if test ! -z "$blibpath" ; then
-                                       blibpath="$blibpath:${withval}/lib"
-                               fi
-                       else
-                               if test -d /usr/include/kerberosIV ; then
-                                       CPPFLAGS="$CPPFLAGS -I/usr/include/kerberosIV"
-                               fi
-                       fi
-
-                       AC_CHECK_HEADERS(krb.h)
-                       if test "$ac_cv_header_krb_h" != yes; then
-                               AC_MSG_WARN([Cannot find krb.h, build may fail])
-                       fi
-                       AC_CHECK_LIB(krb, main)
-                       if test "$ac_cv_lib_krb_main" != yes; then
-                               AC_CHECK_LIB(krb4, main)
-                               if test "$ac_cv_lib_krb4_main" != yes; then
-                                       AC_MSG_WARN([Cannot find libkrb nor libkrb4, build may fail])
-                               else
-                                       KLIBS="-lkrb4"
-                               fi
-                       else
-                               KLIBS="-lkrb"
-                       fi
-                       AC_CHECK_LIB(des, des_cbc_encrypt)
-                       if test "$ac_cv_lib_des_des_cbc_encrypt" != yes; then
-                               AC_CHECK_LIB(des425, des_cbc_encrypt)
-                               if test "$ac_cv_lib_des425_des_cbc_encrypt" != yes; then
-                                       AC_MSG_WARN([Cannot find libdes nor libdes425, build may fail])
-                               else
-                                       KLIBS="-ldes425"
-                               fi
-                       else
-                               KLIBS="-ldes"
-                       fi
-                       AC_CHECK_LIB(resolv, dn_expand, , )
-                       KRB4=yes
-                       KRB4_MSG="yes" 
-                       AC_DEFINE(KRB4)
-               fi
-       ]
-)
 
 # Check whether user wants AFS_KRB5 support
 AFS_KRB5_MSG="no"
@@ -2087,33 +2201,7 @@ AC_ARG_WITH(afs-krb5,
                fi
        ]
 )
-
-# Check whether user wants AFS support
-AFS_MSG="no" 
-AC_ARG_WITH(afs,
-       [  --with-afs=PATH         Enable AFS support],
-       [
-               if test "x$withval" != "xno" ; then
-
-                       if test "x$withval" != "xyes" ; then
-                               CPPFLAGS="$CPPFLAGS -I${withval}/include"
-                               LDFLAGS="$LDFLAGS -L${withval}/lib"
-                       fi
-
-                       if test -z "$KRB4" ; then
-                               AC_MSG_WARN([AFS requires Kerberos IV support, build may fail])
-                       fi
-
-                       LIBS="-lkafs $LIBS"
-                       if test ! -z "$AFS_LIBS" ; then
-                               LIBS="$LIBS $AFS_LIBS"
-                       fi
-                       AC_DEFINE(AFS)
-                       AFS_MSG="yes" 
-               fi
-       ]
-)
-LIBS="$LIBS $KLIBS $K5LIBS"
+LIBS="$LIBS $K5LIBS"
 
 AC_ARG_WITH(session-hooks,
         [  --with-session-hooks    Enable hooks for executing external commands                                       before/after a session],
@@ -2288,30 +2376,48 @@ else
        )
 fi
 
+# check for /etc/default/login and use it if present.
+AC_CHECK_FILE("/etc/default/login", [ external_path_file=/etc/default/login ])
+
+if test "x$external_path_file" = "x/etc/default/login"; then
+       AC_DEFINE(HAVE_ETC_DEFAULT_LOGIN)
+fi
+
 dnl BSD systems use /etc/login.conf so --with-default-path= has no effect
 if test $ac_cv_func_login_getcapbool = "yes" -a \
        $ac_cv_header_login_cap_h = "yes" ; then
-       USES_LOGIN_CONF=yes
+       external_path_file=/etc/login.conf
 fi
+
 # Whether to mess with the default path
 SERVER_PATH_MSG="(default)" 
 AC_ARG_WITH(default-path,
        [  --with-default-path=    Specify default \$PATH environment for server],
        [
-               if test "$USES_LOGIN_CONF" = "yes" ; then
+               if test "x$external_path_file" = "x/etc/login.conf" ; then
                        AC_MSG_WARN([
 --with-default-path=PATH has no effect on this system.
 Edit /etc/login.conf instead.])
                elif test "x$withval" != "xno" ; then   
+                       if test ! -z "$external_path_file" ; then
+                               AC_MSG_WARN([
+--with-default-path=PATH will only be used if PATH is not defined in
+$external_path_file .])
+                       fi
                        user_path="$withval"
                        SERVER_PATH_MSG="$withval" 
                fi
        ],
-       [ if test "$USES_LOGIN_CONF" = "yes" ; then
-       AC_MSG_WARN([Make sure the path to scp is in /etc/login.conf])
+       [ if test "x$external_path_file" = "x/etc/login.conf" ; then
+               AC_MSG_WARN([Make sure the path to scp is in /etc/login.conf])
        else
-       AC_TRY_RUN(
-               [
+               if test ! -z "$external_path_file" ; then
+                       AC_MSG_WARN([
+If PATH is defined in $external_path_file, ensure the path to scp is included,
+otherwise scp will not work.])
+               fi
+               AC_TRY_RUN(
+                       [
 /* find out what STDPATH is */
 #include <stdio.h>
 #ifdef HAVE_PATHS_H
@@ -2365,7 +2471,7 @@ main()
                fi
        fi ]
 )
-if test "$USES_LOGIN_CONF" != "yes" ; then
+if test "x$external_path_file" != "x/etc/login.conf" ; then
        AC_DEFINE_UNQUOTED(USER_PATH, "$user_path")
        AC_SUBST(user_path)
 fi
@@ -2382,18 +2488,6 @@ AC_ARG_WITH(superuser-path,
 )
 
 
-# Whether to force IPv4 by default (needed on broken glibc Linux)
-IPV4_HACK_MSG="no" 
-AC_ARG_WITH(ipv4-default,
-       [  --with-ipv4-default     Use IPv4 by connections unless '-6' specified],
-       [
-               if test "x$withval" != "xno" ; then     
-                       AC_DEFINE(IPV4_DEFAULT)
-                       IPV4_HACK_MSG="yes" 
-               fi
-       ]
-)
-
 AC_MSG_CHECKING([if we need to convert IPv4 in IPv6-mapped addresses])
 IPV4_IN6_HACK_MSG="no" 
 AC_ARG_WITH(4in6,
@@ -2457,35 +2551,67 @@ AC_SUBST(piddir)
 dnl allow user to disable some login recording features
 AC_ARG_ENABLE(lastlog,
        [  --disable-lastlog       disable use of lastlog even if detected [no]],
-       [ AC_DEFINE(DISABLE_LASTLOG) ]
+       [
+               if test "x$enableval" = "xno" ; then
+                       AC_DEFINE(DISABLE_LASTLOG)
+               fi
+       ]
 )
 AC_ARG_ENABLE(utmp,
        [  --disable-utmp          disable use of utmp even if detected [no]],
-       [ AC_DEFINE(DISABLE_UTMP) ]
+       [
+               if test "x$enableval" = "xno" ; then
+                       AC_DEFINE(DISABLE_UTMP)
+               fi
+       ]
 )
 AC_ARG_ENABLE(utmpx,
        [  --disable-utmpx         disable use of utmpx even if detected [no]],
-       [ AC_DEFINE(DISABLE_UTMPX) ]
+       [
+               if test "x$enableval" = "xno" ; then
+                       AC_DEFINE(DISABLE_UTMPX)
+               fi
+       ]
 )
 AC_ARG_ENABLE(wtmp,
        [  --disable-wtmp          disable use of wtmp even if detected [no]],
-       [ AC_DEFINE(DISABLE_WTMP) ]
+       [
+               if test "x$enableval" = "xno" ; then
+                       AC_DEFINE(DISABLE_WTMP)
+               fi
+       ]
 )
 AC_ARG_ENABLE(wtmpx,
        [  --disable-wtmpx         disable use of wtmpx even if detected [no]],
-       [ AC_DEFINE(DISABLE_WTMPX) ]
+       [
+               if test "x$enableval" = "xno" ; then
+                       AC_DEFINE(DISABLE_WTMPX)
+               fi
+       ]
 )
 AC_ARG_ENABLE(libutil,
        [  --disable-libutil       disable use of libutil (login() etc.) [no]],
-       [ AC_DEFINE(DISABLE_LOGIN) ]
+       [
+               if test "x$enableval" = "xno" ; then
+                       AC_DEFINE(DISABLE_LOGIN)
+               fi
+       ]
 )
 AC_ARG_ENABLE(pututline,
        [  --disable-pututline     disable use of pututline() etc. ([uw]tmp) [no]],
-       [ AC_DEFINE(DISABLE_PUTUTLINE) ]
+       [
+               if test "x$enableval" = "xno" ; then
+                       AC_DEFINE(DISABLE_PUTUTLINE) 
+               fi
+       ]
 )
 AC_ARG_ENABLE(pututxline,
        [  --disable-pututxline    disable use of pututxline() etc. ([uw]tmpx) [no]],
-       [ AC_DEFINE(DISABLE_PUTUTXLINE) ]
+       [
+               if test "x$enableval" = "xno" ; then
+                       AC_DEFINE(DISABLE_PUTUTXLINE)
+               fi
+       ]
 )
 AC_ARG_WITH(lastlog,
   [  --with-lastlog=FILE|DIR specify lastlog location [common locations]],
@@ -2715,25 +2841,28 @@ echo "                   Askpass program: $E"
 echo "                      Manual pages: $F"
 echo "                          PID file: $G"
 echo "  Privilege separation chroot path: $H"
-if test "$USES_LOGIN_CONF" = "yes" ; then
-echo "   At runtime, sshd will use the path defined in /etc/login.conf"
+if test "x$external_path_file" = "x/etc/login.conf" ; then
+echo "   At runtime, sshd will use the path defined in $external_path_file"
+echo "   Make sure the path to scp is present, otherwise scp will not work"
 else
 echo "            sshd default user PATH: $I"
+       if test ! -z "$external_path_file"; then
+echo "   (If PATH is set in $external_path_file it will be used instead. If"
+echo "   used, ensure the path to scp is present, otherwise scp will not work.)"
+       fi
 fi
 if test ! -z "$superuser_path" ; then
 echo "          sshd superuser user PATH: $J"
 fi
 echo "                    Manpage format: $MANTYPE"
-echo "                       PAM support: ${PAM_MSG}"
-echo "                KerberosIV support: $KRB4_MSG"
+echo "                       DNS support: $DNS_MSG"
+echo "                       PAM support: $PAM_MSG"
 echo "                 KerberosV support: $KRB5_MSG"
 echo "                 Smartcard support: $SCARD_MSG"
-echo "                       AFS support: $AFS_MSG"
 echo "                     S/KEY support: $SKEY_MSG"
 echo "              TCP Wrappers support: $TCPW_MSG"
 echo "              MD5 password support: $MD5_MSG"
 echo "       IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG"
-echo "          Use IPv4 by default hack: $IPV4_HACK_MSG"
 echo "           Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG"
 echo "                  BSD Auth support: $BSD_AUTH_MSG"
 echo "              Random number source: $RAND_MSG"
index 82fd8be1b12fdd62d6f0f1a01664217b947a64f3..3159b8c8aba9247c9af6178d07111a293634ffc4 100644 (file)
@@ -26,6 +26,7 @@ and for comparison with the output from this script, however no code
 from lppbuild is included and it is not required for operation.
 
 SRC support based on examples provided by Sandor Sklar and Maarten Kreuger.
+PrivSep account handling fixes contributed by W. Earl Allen.
 
 
 Other notes:
@@ -45,3 +46,5 @@ you get to keep both pieces.
 
        - Darren Tucker (dtucker at zip dot com dot au)
          2002/03/01
+
+$Id$
index 3b369966012b163e00e948ad6fee97ab0a13a9fc..8d1bc3cd8593f5a52b0650c12c015449a8bcc178 100755 (executable)
@@ -1,6 +1,7 @@
 #!/bin/sh
 #
 # buildbff.sh: Create AIX SMIT-installable OpenSSH packages
+# $Id$
 #
 # Author: Darren Tucker (dtucker at zip dot com dot au)
 # This file is placed in the public domain and comes with absolutely
@@ -14,9 +15,9 @@
 #      create a "config.local" in your build directory or set
 #      environment variables to override these.
 #
-[ -z "$PERMIT_ROOT_LOGIN" ] || PERMIT_ROOT_LOGIN=no
-[ -z "$X11_FORWARDING" ] || X11_FORWARDING=no
-[ -z "$AIX_SRC" ] || AIX_SRC=no
+[ -z "$PERMIT_ROOT_LOGIN" ] && PERMIT_ROOT_LOGIN=no
+[ -z "$X11_FORWARDING" ] && X11_FORWARDING=no
+[ -z "$AIX_SRC" ] && AIX_SRC=no
 
 umask 022
 
@@ -31,7 +32,7 @@ else
 fi
 
 #
-# We still support running from contrib/aix, but this is depreciated
+# We still support running from contrib/aix, but this is deprecated
 #
 if pwd | egrep 'contrib/aix$'
 then
@@ -121,7 +122,7 @@ cp $srcdir/README* $objdir/$PKGDIR/
 # Extract common info requires for the 'info' part of the package.
 #      AIX requires 4-part version numbers
 #
-VERSION=`./ssh -V 2>&1 | sed -e 's/,.*//' | cut -f 2 -d _`
+VERSION=`./ssh -V 2>&1 | cut -f 1 -d , | cut -f 2 -d _`
 MAJOR=`echo $VERSION | cut -f 1 -d p | cut -f 1 -d .`
 MINOR=`echo $VERSION | cut -f 1 -d p | cut -f 2 -d .`
 PATCH=`echo $VERSION | cut -f 1 -d p | cut -f 3 -d .`
@@ -218,7 +219,7 @@ else
        fi
 
        # Create user if required
-       if cut -f1 -d: /etc/passwd | egrep '^'$SSH_PRIVSEP_USER'\$' >/dev/null
+       if lsuser ALL | cut -f1 -d: | egrep '^'$SSH_PRIVSEP_USER'\$' >/dev/null
        then
                echo "PrivSep user $SSH_PRIVSEP_USER already exists."
        else
index 619493ae2af47de0183b7348d8ba47a14859811d..4d07e9a2a674a8dcdb55667ea8de17a42d7e7c4a 100755 (executable)
@@ -1,8 +1,10 @@
 #!/bin/sh
 #
 # inventory.sh
+# $Id$
 #
 # Originally written by Ben Lindstrom, modified by Darren Tucker to use perl
+# This file is placed into the public domain.
 #
 # This will produce an AIX package inventory file, which looks like:
 #
index e8d33b2478e11e3c46cf790722891d0de5c019e3..2a01853268a5a2e8314b9814f0afcb4645f4cf02 100644 (file)
@@ -1,3 +1,27 @@
+/*
+ * Copyright (c) 1999-2003 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.
+ */
+
 #ifndef _DEFINES_H
 #define _DEFINES_H
 
@@ -188,28 +212,21 @@ typedef unsigned long  u_int32_t;
 #ifndef HAVE_INT64_T
 # if (SIZEOF_LONG_INT == 8)
 typedef long int int64_t;
-#   define HAVE_INT64_T 1
 # else
 #  if (SIZEOF_LONG_LONG_INT == 8)
 typedef long long int int64_t;
-#   define HAVE_INT64_T 1
 #  endif
 # endif
 #endif
 #ifndef HAVE_U_INT64_T
 # if (SIZEOF_LONG_INT == 8)
 typedef unsigned long int u_int64_t;
-#   define HAVE_U_INT64_T 1
 # else
 #  if (SIZEOF_LONG_LONG_INT == 8)
 typedef unsigned long long int u_int64_t;
-#   define HAVE_U_INT64_T 1
 #  endif
 # endif
 #endif
-#if !defined(HAVE_LONG_LONG_INT) && (SIZEOF_LONG_LONG_INT == 8)
-# define HAVE_LONG_LONG_INT 1
-#endif
 
 #ifndef HAVE_U_CHAR
 typedef unsigned char u_char;
@@ -304,6 +321,10 @@ struct winsize {
 # define _PATH_STDPATH "/usr/bin:/bin:/usr/sbin:/sbin"
 #endif
 
+#ifndef SUPERUSER_PATH
+# define SUPERUSER_PATH        _PATH_STDPATH
+#endif
+
 #ifndef _PATH_DEVNULL
 # define _PATH_DEVNULL "/dev/null"
 #endif
@@ -420,6 +441,23 @@ struct winsize {
 #define        CMSG_SPACE(len) (__CMSG_ALIGN(sizeof(struct cmsghdr)) + __CMSG_ALIGN(len))
 #endif
 
+/* given pointer to struct cmsghdr, return pointer to data */
+#ifndef CMSG_DATA
+#define CMSG_DATA(cmsg) ((u_char *)(cmsg) + __CMSG_ALIGN(sizeof(struct cmsghdr)))
+#endif /* CMSG_DATA */
+
+/*
+ * RFC 2292 requires to check msg_controllen, in case that the kernel returns
+ * an empty list for some reasons.
+ */
+#ifndef CMSG_FIRSTHDR
+#define CMSG_FIRSTHDR(mhdr) \
+       ((mhdr)->msg_controllen >= sizeof(struct cmsghdr) ? \
+        (struct cmsghdr *)(mhdr)->msg_control : \
+        (struct cmsghdr *)NULL)
+#endif /* CMSG_FIRSTHDR */
+
+
 /* Function replacement / compatibility hacks */
 
 #if !defined(HAVE_GETADDRINFO) && (defined(HAVE_OGETADDRINFO) || defined(HAVE_NGETADDRINFO))
@@ -487,6 +525,10 @@ struct winsize {
 #  define __func__ ""
 #endif
 
+#if defined(KRB5) && !defined(HEIMDAL)
+#  define krb5_get_err_text(context,code) error_message(code)
+#endif
+
 /*
  * Define this to use pipes instead of socketpairs for communicating with the
  * client program.  Socketpairs do not seem to work on all systems.
index f0a160b965a116ff009907ba010327725bfa6080..5af081bb78059a84b521df95ef1a6033bc392360 100644 (file)
@@ -1,5 +1,8 @@
+/*     $OpenBSD: gss-genr.c,v 1.1 2003/08/22 10:56:09 markus Exp $     */
+
 /*
- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. *
+ * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -201,85 +204,91 @@ ssh_gssapi_client_id_kex(Gssctxt *ctx, char *name) {
 }
 
 /* Check that the OID in a data stream matches that in the context */
-int ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len) {
-  
-  return (ctx!=NULL && ctx->oid != GSS_C_NO_OID && 
-         ctx->oid->length == len &&
-         memcmp(ctx->oid->elements,data,len)==0);
+int
+ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len)
+{
+       return (ctx != NULL && ctx->oid != GSS_C_NO_OID &&
+           ctx->oid->length == len &&
+           memcmp(ctx->oid->elements, data, len) == 0);
 }
-       
+
 /* Set the contexts OID from a data stream */
-void ssh_gssapi_set_oid_data(Gssctxt *ctx, void *data, size_t len) { 
-  if (ctx->oid != GSS_C_NO_OID) {
-       xfree(ctx->oid->elements);
-       xfree(ctx->oid);
-  }
-  ctx->oid=xmalloc(sizeof(gss_OID_desc));
-  ctx->oid->length=len;
-  ctx->oid->elements=xmalloc(len);
-  memcpy(ctx->oid->elements,data,len);
+void
+ssh_gssapi_set_oid_data(Gssctxt *ctx, void *data, size_t len)
+{
+       if (ctx->oid != GSS_C_NO_OID) {
+               xfree(ctx->oid->elements);
+               xfree(ctx->oid);
+       }
+       ctx->oid = xmalloc(sizeof(gss_OID_desc));
+       ctx->oid->length = len;
+       ctx->oid->elements = xmalloc(len);
+       memcpy(ctx->oid->elements, data, len);
 }
 
 /* Set the contexts OID */
-void ssh_gssapi_set_oid(Gssctxt *ctx, gss_OID oid) {  
-  ssh_gssapi_set_oid_data(ctx,oid->elements,oid->length);
+void
+ssh_gssapi_set_oid(Gssctxt *ctx, gss_OID oid)
+{
+       ssh_gssapi_set_oid_data(ctx, oid->elements, oid->length);
 }
 
 /* All this effort to report an error ... */
-
 void
-ssh_gssapi_error(Gssctxt *ctxt) {
-       
-       debug(ssh_gssapi_last_error(ctxt,NULL,NULL));
+ssh_gssapi_error(Gssctxt *ctxt)
+{
+       debug("%s", ssh_gssapi_last_error(ctxt, NULL, NULL));
 }
 
 char *
-ssh_gssapi_last_error(Gssctxt *ctxt, 
-                     OM_uint32 *major_status, OM_uint32 *minor_status) {
+ssh_gssapi_last_error(Gssctxt *ctxt,
+                     OM_uint32 *major_status, OM_uint32 *minor_status)
+{
        OM_uint32 lmin;
-        gss_buffer_desc msg;
-        OM_uint32 ctx;
-        Buffer b;
-        char *ret;
-        
-        buffer_init(&b);
-
-       if (major_status!=NULL) *major_status=ctxt->major;
-       if (minor_status!=NULL) *minor_status=ctxt->minor;
-       
-        ctx = 0;
+       gss_buffer_desc msg = GSS_C_EMPTY_BUFFER;
+       OM_uint32 ctx;
+       Buffer b;
+       char *ret;
+
+       buffer_init(&b);
+
+       if (major_status != NULL)
+               *major_status = ctxt->major;
+       if (minor_status != NULL)
+               *minor_status = ctxt->minor;
+
+       ctx = 0;
        /* The GSSAPI error */
-        do {
-               gss_display_status(&lmin, ctxt->major,
-                                  GSS_C_GSS_CODE, ctxt->oid,
-                                  &ctx, &msg);
-
-               buffer_append(&b,msg.value,msg.length);
-               buffer_put_char(&b,'\n');
-               
-                       gss_release_buffer(&lmin, &msg);
-        } while (ctx!=0);
-
-        /* The mechanism specific error */
-        do {
-               gss_display_status(&lmin, ctxt->minor,
-                                  GSS_C_MECH_CODE, ctxt->oid,
-                                  &ctx, &msg);
-               
-               buffer_append(&b,msg.value,msg.length);
-               buffer_put_char(&b,'\n');
-               
-               gss_release_buffer(&lmin, &msg);
-        } while (ctx!=0);
-        
-        buffer_put_char(&b,'\0');
-        ret=xmalloc(buffer_len(&b));
-        buffer_get(&b,ret,buffer_len(&b));
-        buffer_free(&b);
-        return(ret);
+       do {
+               gss_display_status(&lmin, ctxt->major,
+                   GSS_C_GSS_CODE, ctxt->oid, &ctx, &msg);
+
+               buffer_append(&b, msg.value, msg.length);
+               buffer_put_char(&b, '\n');
+
+               gss_release_buffer(&lmin, &msg);
+       } while (ctx != 0);
+
+       /* The mechanism specific error */
+       do {
+               gss_display_status(&lmin, ctxt->minor,
+                   GSS_C_MECH_CODE, ctxt->oid, &ctx, &msg);
+
+               buffer_append(&b, msg.value, msg.length);
+               buffer_put_char(&b, '\n');
+
+               gss_release_buffer(&lmin, &msg);
+       } while (ctx != 0);
+
+       buffer_put_char(&b, '\0');
+       ret = xmalloc(buffer_len(&b));
+       buffer_get(&b, ret, buffer_len(&b));
+       buffer_free(&b);
+       return (ret);
 }
 
-/* Initialise our GSSAPI context. We use this opaque structure to contain all
+/*
+ * Initialise our GSSAPI context. We use this opaque structure to contain all
  * of the data which both the client and server need to persist across
  * {accept,init}_sec_context calls, so that when we do it from the userauth
  * stuff life is a little easier
@@ -287,15 +296,15 @@ ssh_gssapi_last_error(Gssctxt *ctxt,
 void
 ssh_gssapi_build_ctx(Gssctxt **ctx)
 {
-       *ctx=xmalloc(sizeof (Gssctxt));
-       (*ctx)->major=0;
-       (*ctx)->minor=0;
-       (*ctx)->context=GSS_C_NO_CONTEXT;
-       (*ctx)->name=GSS_C_NO_NAME;
-       (*ctx)->oid=GSS_C_NO_OID;
-       (*ctx)->creds=GSS_C_NO_CREDENTIAL;
-       (*ctx)->client=GSS_C_NO_NAME;
-       (*ctx)->client_creds=GSS_C_NO_CREDENTIAL;
+       *ctx = xmalloc(sizeof (Gssctxt));
+       (*ctx)->major = 0;
+       (*ctx)->minor = 0;
+       (*ctx)->context = GSS_C_NO_CONTEXT;
+       (*ctx)->name = GSS_C_NO_NAME;
+       (*ctx)->oid = GSS_C_NO_OID;
+       (*ctx)->creds = GSS_C_NO_CREDENTIAL;
+       (*ctx)->client = GSS_C_NO_NAME;
+       (*ctx)->client_creds = GSS_C_NO_CREDENTIAL;
 }
 
 /* Delete our context, providing it has been built correctly */
@@ -305,76 +314,66 @@ ssh_gssapi_delete_ctx(Gssctxt **ctx)
 #if !defined(MECHGLUE)
        OM_uint32 ms;
 #endif
-       
-       /* Return if there's no context */
-       if ((*ctx)==NULL)
+
+       if ((*ctx) == NULL)
                return;
-               
 #if !defined(MECHGLUE) /* mechglue has some memory management issues */
-       if ((*ctx)->context != GSS_C_NO_CONTEXT) 
-               gss_delete_sec_context(&ms,&(*ctx)->context,GSS_C_NO_BUFFER);
+       if ((*ctx)->context != GSS_C_NO_CONTEXT)
+               gss_delete_sec_context(&ms, &(*ctx)->context, GSS_C_NO_BUFFER);
        if ((*ctx)->name != GSS_C_NO_NAME)
-               gss_release_name(&ms,&(*ctx)->name);
+               gss_release_name(&ms, &(*ctx)->name);
        if ((*ctx)->oid != GSS_C_NO_OID) {
                xfree((*ctx)->oid->elements);
                xfree((*ctx)->oid);
                (*ctx)->oid = GSS_C_NO_OID;
        }
        if ((*ctx)->creds != GSS_C_NO_CREDENTIAL)
-               gss_release_cred(&ms,&(*ctx)->creds);
+               gss_release_cred(&ms, &(*ctx)->creds);
        if ((*ctx)->client != GSS_C_NO_NAME)
-               gss_release_name(&ms,&(*ctx)->client);  
+               gss_release_name(&ms, &(*ctx)->client);
        if ((*ctx)->client_creds != GSS_C_NO_CREDENTIAL)
-               gss_release_cred(&ms,&(*ctx)->client_creds);
+               gss_release_cred(&ms, &(*ctx)->client_creds);
 #endif
-       
+
        xfree(*ctx);
-       *ctx=NULL; 
+       *ctx = NULL;
 }
 
-/* Wrapper to init_sec_context 
+/*
+ * Wrapper to init_sec_context
  * Requires that the context contains:
  *     oid
- *     server name (from ssh_gssapi_import_name)
+ *     server name (from ssh_gssapi_import_name)
  */
-OM_uint32 
+OM_uint32
 ssh_gssapi_init_ctx(Gssctxt *ctx, int deleg_creds, gss_buffer_desc *recv_tok,
-                           gss_buffer_desc* send_tok, OM_uint32 *flags) 
+    gss_buffer_desc* send_tok, OM_uint32 *flags)
 {
        int deleg_flag = 0;
-       
+
        if (deleg_creds) {
-               deleg_flag=GSS_C_DELEG_FLAG;
+               deleg_flag = GSS_C_DELEG_FLAG;
                debug("Delegating credentials");
        }
-               
-       ctx->major=gss_init_sec_context(&ctx->minor,
-                                       GSS_C_NO_CREDENTIAL, /* def. cred */
-                                       &ctx->context,
-                                       ctx->name,
-                                       ctx->oid,
-                                       GSS_C_MUTUAL_FLAG |
-                                       GSS_C_INTEG_FLAG |
-                                       deleg_flag,
-                                       0, /* default lifetime */
-                                       NULL, /* no channel bindings */
-                                       recv_tok,
-                                       NULL,
-                                       send_tok,
-                                       flags,
-                                       NULL);
-       if (GSS_ERROR(ctx->major)) {
-               ssh_gssapi_error(ctx);
-       }
-       return(ctx->major);
+
+       ctx->major = gss_init_sec_context(&ctx->minor,
+           GSS_C_NO_CREDENTIAL, &ctx->context, ctx->name, ctx->oid,
+           GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag,
+           0, NULL, recv_tok, NULL, send_tok, flags, NULL);
+
+       if (GSS_ERROR(ctx->major))
+               ssh_gssapi_error(ctx);
+
+       return (ctx->major);
 }
 
 /* Create a service name for the given host */
 OM_uint32
-ssh_gssapi_import_name(Gssctxt *ctx, const char *host) {
+ssh_gssapi_import_name(Gssctxt *ctx, const char *host)
+{
        gss_buffer_desc gssbuf;
        char *xhost;
-       
+
        /* Make a copy of the host name, in case it was returned by a
         * previous call to gethostbyname(). */ 
        xhost = xstrdup(host);
@@ -383,61 +382,55 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) {
         * this for us themselves */
        resolve_localhost(&xhost);
        
-        gssbuf.length = sizeof("host@")+strlen(xhost);
-
-        gssbuf.value = xmalloc(gssbuf.length);
-        if (gssbuf.value == NULL) {
-               xfree(xhost);
-               return(-1);
-        }
-        snprintf(gssbuf.value,gssbuf.length,"host@%s",xhost);
-        if ((ctx->major=gss_import_name(&ctx->minor,
-                                       &gssbuf,
-                                        GSS_C_NT_HOSTBASED_SERVICE,
-                                        &ctx->name))) {
+       gssbuf.length = sizeof("host@") + strlen(xhost);
+       gssbuf.value = xmalloc(gssbuf.length);
+       snprintf(gssbuf.value, gssbuf.length, "host@%s", host);
+
+       if ((ctx->major = gss_import_name(&ctx->minor,
+           &gssbuf, GSS_C_NT_HOSTBASED_SERVICE, &ctx->name)))
                ssh_gssapi_error(ctx);
-       }
-       
+
        xfree(xhost);
        xfree(gssbuf.value);
-       return(ctx->major);
+       return (ctx->major);
 }
 
 /* Acquire credentials for a server running on the current host.
  * Requires that the context structure contains a valid OID
  */
+
 /* Returns a GSSAPI error code */
 OM_uint32
-ssh_gssapi_acquire_cred(Gssctxt *ctx) {
+ssh_gssapi_acquire_cred(Gssctxt *ctx)
+{
        OM_uint32 status;
        char lname[MAXHOSTNAMELEN];
        gss_OID_set oidset;
-       
-       gss_create_empty_oid_set(&status,&oidset);
-       gss_add_oid_set_member(&status,ctx->oid,&oidset);
-       
-        if (gethostname(lname, MAXHOSTNAMELEN)) {
-                return(-1);
-        }
 
-       if (GSS_ERROR(ssh_gssapi_import_name(ctx,lname))) {
-               return(ctx->major);
-       }
-       
-       if ((ctx->major=gss_acquire_cred(&ctx->minor,
-                                   ctx->name,
-                                   0,
-                                   oidset,
-                                   GSS_C_ACCEPT,
-                                   &ctx->creds,
-                                   NULL,
-                                   NULL))) {
+       gss_create_empty_oid_set(&status, &oidset);
+       gss_add_oid_set_member(&status, ctx->oid, &oidset);
+
+       if (gethostname(lname, MAXHOSTNAMELEN))
+               return (-1);
+
+       if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname)))
+               return (ctx->major);
+
+       if ((ctx->major = gss_acquire_cred(&ctx->minor,
+           ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, NULL, NULL)))
                ssh_gssapi_error(ctx);
-       }
-                               
+
        gss_release_oid_set(&status, &oidset);
-       return(ctx->major);
+       return (ctx->major);
+}
+
+OM_uint32
+ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) {
+       if (*ctx)
+               ssh_gssapi_delete_ctx(ctx);
+       ssh_gssapi_build_ctx(ctx);
+       ssh_gssapi_set_oid(*ctx, oid);
+       return (ssh_gssapi_acquire_cred(*ctx));
 }
 
 OM_uint32
@@ -464,14 +457,6 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *buffer, gss_buffer_desc *hash) {
        return(ctx->major);
 }
 
-OM_uint32
-ssh_gssapi_server_ctx(Gssctxt **ctx,gss_OID oid) {
-       if (*ctx) ssh_gssapi_delete_ctx(ctx);
-       ssh_gssapi_build_ctx(ctx);
-       ssh_gssapi_set_oid(*ctx,oid);
-       return(ssh_gssapi_acquire_cred(*ctx));
-}
-
 int
 ssh_gssapi_check_mechanism(gss_OID oid, char *host) {
        Gssctxt * ctx = NULL;
index dcf60e0c25ddee775401021a6035f644da42d43c..194e3a3ee0911238878f85f38c3c1851eaa1e158 100644 (file)
@@ -80,11 +80,11 @@ ssh_gssapi_gsi_userok(ssh_gssapi_client *client, char *name)
 #endif
 
     /* This returns 0 on success */
-    authorized = (globus_gss_assist_userok(client->name.value,
+    authorized = (globus_gss_assist_userok(client->displayname.value,
                                           name) == 0);
     
-    log("GSI user %s is%s authorized as target user %s",
-       (char *) client->name.value, (authorized ? "" : " not"), name);
+    logit("GSI user %s is%s authorized as target user %s",
+       (char *) client->displayname.value, (authorized ? "" : " not"), name);
     
     return authorized;
 }
@@ -100,7 +100,7 @@ ssh_gssapi_gsi_localname(ssh_gssapi_client *client, char **user)
        return 0;
     }
 #endif
-    return(globus_gss_assist_gridmap(client->name.value, user) == 0);
+    return(globus_gss_assist_gridmap(client->displayname.value, user) == 0);
 }
 
 /*
@@ -136,7 +136,7 @@ ssh_gssapi_gsi_storecreds(ssh_gssapi_client *client)
        
        p = strchr((char *) export_cred.value, '=');
        if (p == NULL) {
-           log("Failed to parse exported credentials string '%.100s'",
+           logit("Failed to parse exported credentials string '%.100s'",
                (char *)export_cred.value);
            gss_release_buffer(&minor_status, &export_cred);
            return;
index c7f3ad14103b4ed41a31ab9b546cc8329236df77..c1ae5d6063ea9eb7a075df782226a0c4ede58add 100644 (file)
@@ -1,3 +1,5 @@
+/*     $OpenBSD: gss-serv-krb5.c,v 1.1 2003/08/22 10:56:09 markus Exp $        */
+
 /*
  * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
  *
@@ -28,7 +30,6 @@
 #ifdef KRB5
 
 #include "auth.h"
-#include "auth-pam.h"
 #include "xmalloc.h"
 #include "log.h"
 #include "servconf.h"
@@ -41,89 +42,62 @@ extern ServerOptions options;
 #include <krb5.h>
 #else
 #include <gssapi_krb5.h>
-#define krb5_get_err_text(context,code) error_message(code)
 #endif
 
-static int ssh_gssapi_krb5_init();
-static int ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name);
-static int ssh_gssapi_krb5_localname(ssh_gssapi_client *client, char **user);
-static void ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client);
-
 static krb5_context krb_context = NULL;
 
-/* We've been using a wrongly encoded mechanism ID for yonks */
-
-ssh_gssapi_mech gssapi_kerberos_mech_old = {
-       "Se3H81ismmOC3OE+FwYCiQ==",
-       "Kerberos",
-       {9, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02"},
-       &ssh_gssapi_krb5_init,
-       &ssh_gssapi_krb5_userok,
-       &ssh_gssapi_krb5_localname,
-       &ssh_gssapi_krb5_storecreds
-};
-
-ssh_gssapi_mech gssapi_kerberos_mech = {
-       "toWM5Slw5Ew8Mqkay+al2g==",
-       "Kerberos",
-       {9, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02"},
-       NULL,
-       &ssh_gssapi_krb5_userok,
-       &ssh_gssapi_krb5_localname,
-       &ssh_gssapi_krb5_storecreds
-};
-       
-/* Initialise the krb5 library, so we can use it for those bits that
- * GSSAPI won't do */
+/* Initialise the krb5 library, for the stuff that GSSAPI won't do */
 
 static int 
-ssh_gssapi_krb5_init() {
+ssh_gssapi_krb5_init()
+{
        krb5_error_code problem;
-       
-       if (krb_context !=NULL)
+
+       if (krb_context != NULL)
                return 1;
-               
+
        problem = krb5_init_context(&krb_context);
        if (problem) {
-               log("Cannot initialize krb5 context");
+               logit("Cannot initialize krb5 context");
                return 0;
        }
        krb5_init_ets(krb_context);
 
-       return 1;       
-}                      
+       return 1;
+}
 
-/* Check if this user is OK to login. This only works with krb5 - other 
+/* Check if this user is OK to login. This only works with krb5 - other
  * GSSAPI mechanisms will need their own.
  * Returns true if the user is OK to log in, otherwise returns 0
  */
 
 static int
-ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) {
+ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name)
+{
        krb5_principal princ;
        int retval;
 
        if (ssh_gssapi_krb5_init() == 0)
                return 0;
-               
-       if ((retval=krb5_parse_name(krb_context, client->name.value, 
-                                   &princ))) {
-               log("krb5_parse_name(): %.100s", 
-                       krb5_get_err_text(krb_context,retval));
+
+       if ((retval = krb5_parse_name(krb_context, client->exportedname.value,
+           &princ))) {
+               logit("krb5_parse_name(): %.100s",
+                   krb5_get_err_text(krb_context, retval));
                return 0;
        }
        if (krb5_kuserok(krb_context, princ, name)) {
                retval = 1;
-               log("Authorized to %s, krb5 principal %s (krb5_kuserok)",name,
-                   (char *)client->name.value);
-       }
-       else
+               logit("Authorized to %s, krb5 principal %s (krb5_kuserok)",
+                   name, (char *)client->displayname.value);
+       } else
                retval = 0;
-       
+
        krb5_free_principal(krb_context, princ);
        return retval;
 }
 
+
 /* Retrieve the local username associated with a set of Kerberos 
  * credentials. Hopefully we can use this for the 'empty' username
  * logins discussed in the draft  */
@@ -135,9 +109,9 @@ ssh_gssapi_krb5_localname(ssh_gssapi_client *client, char **user) {
        if (ssh_gssapi_krb5_init() == 0)
                return 0;
 
-       if ((retval=krb5_parse_name(krb_context, client->name.value, 
+       if ((retval=krb5_parse_name(krb_context, client->displayname.value, 
                                    &princ))) {
-               log("krb5_parse_name(): %.100s", 
+               logit("krb5_parse_name(): %.100s", 
                        krb5_get_err_text(krb_context,retval));
                return 0;
        }
@@ -153,82 +127,78 @@ ssh_gssapi_krb5_localname(ssh_gssapi_client *client, char **user) {
        return(1);
 }
        
-/* Make sure that this is called _after_ we've setuid to the user */
-
-/* This writes out any forwarded credentials. Its specific to the Kerberos
- * GSSAPI mechanism
- *
- * We assume that our caller has made sure that the user has selected
- * delegated credentials, and that the client_creds structure is correctly
- * populated.
- */
+/* This writes out any forwarded credentials from the structure populated
+ * during userauth. Called after we have setuid to the user */
 
 static void
-ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) {
+ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
+{
        krb5_ccache ccache;
        krb5_error_code problem;
        krb5_principal princ;
-       char ccname[35];
-       static char name[40];
-       int tmpfd;
-       OM_uint32 maj_status,min_status;
+       OM_uint32 maj_status, min_status;
        gss_cred_id_t krb5_cred_handle;
 
-       if (client->creds==NULL) {
-               debug("No credentials stored"); 
+
+       if (client->creds == NULL) {
+               debug("No credentials stored");
                return;
        }
-               
+
        if (ssh_gssapi_krb5_init() == 0)
                return;
 
-       if (options.gss_use_session_ccache) {
-               snprintf(ccname,sizeof(ccname),"/tmp/krb5cc_%d_XXXXXX",geteuid());
-       
-               if ((tmpfd = mkstemp(ccname))==-1) {
-                       log("mkstemp(): %.100s", strerror(errno));
-                       return;
-               }
-               if (fchmod(tmpfd, S_IRUSR | S_IWUSR) == -1) {
-                       log("fchmod(): %.100s", strerror(errno));
-                       close(tmpfd);
-                       return;
-               }
-        } else {
-               snprintf(ccname,sizeof(ccname),"/tmp/krb5cc_%d",geteuid());
-               tmpfd = open(ccname, O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR);
-               if (tmpfd == -1) {
-                       log("open(): %.100s", strerror(errno));
-                       return;
-               }
-        }
-
-               close(tmpfd);
-        snprintf(name, sizeof(name), "FILE:%s",ccname);
-        if ((problem = krb5_cc_resolve(krb_context, name, &ccache))) {
-                log("krb5_cc_default(): %.100s", 
-                       krb5_get_err_text(krb_context,problem));
-                return;
-        }
-
-       if ((problem = krb5_parse_name(krb_context, client->name.value, 
-                                      &princ))) {
-               log("krb5_parse_name(): %.100s", 
-                       krb5_get_err_text(krb_context,problem));
-               krb5_cc_destroy(krb_context,ccache);
+#ifdef HEIMDAL
+       if ((problem = krb5_cc_gen_new(krb_context, &krb5_fcc_ops, &ccache))) {
+               logit("krb5_cc_gen_new(): %.100s",
+                   krb5_get_err_text(krb_context, problem));
                return;
        }
-       
+#else
+       {
+               int tmpfd;
+               char ccname[40];
+    
+               snprintf(ccname, sizeof(ccname), 
+                   "FILE:/tmp/krb5cc_%d_XXXXXX", geteuid());
+    
+               if ((tmpfd = mkstemp(ccname + strlen("FILE:"))) == -1) {
+                       logit("mkstemp(): %.100s", strerror(errno));
+                       problem = errno;
+                       return;
+               }
+               if (fchmod(tmpfd, S_IRUSR | S_IWUSR) == -1) {
+                       logit("fchmod(): %.100s", strerror(errno));
+                       close(tmpfd);
+                       problem = errno;
+                       return;
+               }
+               close(tmpfd);
+               if ((problem = krb5_cc_resolve(krb_context, ccname, &ccache))) {
+                       logit("krb5_cc_resolve(): %.100s",
+                           krb5_get_err_text(krb_context, problem));
+                       return;
+               }
+       }
+#endif /* #ifdef HEIMDAL */
+
+       if ((problem = krb5_parse_name(krb_context, 
+           client->exportedname.value, &princ))) {
+               logit("krb5_parse_name(): %.100s",
+                   krb5_get_err_text(krb_context, problem));
+               krb5_cc_destroy(krb_context, ccache);
+               return;
+       }
+
        if ((problem = krb5_cc_initialize(krb_context, ccache, princ))) {
-               log("krb5_cc_initialize(): %.100s", 
-                       krb5_get_err_text(krb_context,problem));
-               krb5_free_principal(krb_context,princ);
-               krb5_cc_destroy(krb_context,ccache);
+               logit("krb5_cc_initialize(): %.100s",
+                   krb5_get_err_text(krb_context, problem));
+               krb5_free_principal(krb_context, princ);
+               krb5_cc_destroy(krb_context, ccache);
                return;
        }
-       
-       krb5_free_principal(krb_context,princ);
+
+       krb5_free_principal(krb_context, princ);
 
 #ifdef MECHGLUE
        krb5_cred_handle =
@@ -239,26 +209,46 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) {
 #endif
 
        if ((maj_status = gss_krb5_copy_ccache(&min_status, 
-                                              client->creds, 
-                                              ccache))) {
-               log("gss_krb5_copy_ccache() failed");
-               krb5_cc_destroy(krb_context,ccache);
+           krb5_cred_handle, ccache))) {
+               logit("gss_krb5_copy_ccache() failed");
+               krb5_cc_destroy(krb_context, ccache);
                return;
        }
-       
-       krb5_cc_close(krb_context,ccache);
+
+       client->store.filename = xstrdup(krb5_cc_get_name(krb_context, ccache));
+       client->store.envvar = "KRB5CCNAME";
+       client->store.envval = xstrdup(client->store.filename);
 
 #ifdef USE_PAM
-       do_pam_putenv("KRB5CCNAME",name);
+       if (options.use_pam)
+               do_pam_putenv(client->store.envvar,client->store.envval);
 #endif
 
-       client->store.filename=strdup(ccname);
-       client->store.envvar="KRB5CCNAME";
-       client->store.envval=strdup(name);
+       krb5_cc_close(krb_context, ccache);
 
        return;
 }
 
+ssh_gssapi_mech gssapi_kerberos_mech = {
+       "toWM5Slw5Ew8Mqkay+al2g==",
+       "Kerberos",
+       {9, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02"},
+       NULL,
+       &ssh_gssapi_krb5_userok,
+       &ssh_gssapi_krb5_localname,
+       &ssh_gssapi_krb5_storecreds
+};
+
+ssh_gssapi_mech gssapi_kerberos_mech_old = {
+       "Se3H81ismmOC3OE+FwYCiQ==",
+       "Kerberos",
+       {9, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02"},
+       &ssh_gssapi_krb5_init,
+       &ssh_gssapi_krb5_userok,
+       &ssh_gssapi_krb5_localname,
+       &ssh_gssapi_krb5_storecreds
+};
+
 #endif /* KRB5 */
 
 #endif /* GSSAPI */
index 39cdb3f6933404040e6caae06e6736931ce06d81..40148b0760cde9556a66fe8c4e37f14e9edfa071 100644 (file)
@@ -1,3 +1,5 @@
+/*     $OpenBSD: gss-serv.c,v 1.3 2003/08/31 13:31:57 markus Exp $     */
+
 /*
  * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
  *
@@ -28,7 +30,6 @@
 
 #include "ssh.h"
 #include "ssh2.h"
-#include "xmalloc.h"
 #include "buffer.h"
 #include "bufaux.h"
 #include "packet.h"
@@ -44,6 +45,8 @@
 #include "servconf.h"
 #include "compat.h"
 #include "monitor_wrap.h"
+#include "xmalloc.h"
+#include "getput.h"
 
 #include "ssh-gss.h"
 
@@ -52,10 +55,11 @@ extern u_char *session_id2;
 extern int session_id2_len;
 
 static ssh_gssapi_client gssapi_client =
-       { {0,NULL}, GSS_C_NO_CREDENTIAL, NULL, {NULL,NULL,NULL}};
+    { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER,
+    GSS_C_NO_CREDENTIAL, NULL, {NULL, NULL, NULL}};
 
-ssh_gssapi_mech gssapi_null_mech 
-  = {NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL};
+ssh_gssapi_mech gssapi_null_mech =
+    { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL};
 
 #ifdef KRB5
 extern ssh_gssapi_mech gssapi_kerberos_mech;
@@ -68,16 +72,255 @@ extern ssh_gssapi_mech gssapi_gsi_mech_old;
 
 ssh_gssapi_mech* supported_mechs[]= {
 #ifdef KRB5
-  &gssapi_kerberos_mech,
-  &gssapi_kerberos_mech_old, /* Support for legacy clients */
+       &gssapi_kerberos_mech,
+       &gssapi_kerberos_mech_old, /* Support for legacy clients */
 #endif
 #ifdef GSI
-  &gssapi_gsi_mech,
-  &gssapi_gsi_mech_old,        /* Support for legacy clients */
+       &gssapi_gsi_mech,
+       &gssapi_gsi_mech_old,   /* Support for legacy clients */
 #endif
-  &gssapi_null_mech,
+       &gssapi_null_mech,
 };
 
+/* Unpriviledged */
+void
+ssh_gssapi_supported_oids(gss_OID_set *oidset)
+{
+       int i = 0;
+       OM_uint32 min_status;
+       int present;
+       gss_OID_set supported;
+
+       gss_create_empty_oid_set(&min_status, oidset);
+       gss_indicate_mechs(&min_status, &supported);
+
+       while (supported_mechs[i]->name != NULL) {
+               if (GSS_ERROR(gss_test_oid_set_member(&min_status,
+                   &supported_mechs[i]->oid, supported, &present)))
+                       present = 0;
+               if (present)
+                       gss_add_oid_set_member(&min_status,
+                           &supported_mechs[i]->oid, oidset);
+               i++;
+       }
+}
+
+
+/* Wrapper around accept_sec_context
+ * Requires that the context contains:
+ *    oid
+ *    credentials      (from ssh_gssapi_acquire_cred)
+ */
+/* Priviledged */
+OM_uint32
+ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *recv_tok,
+    gss_buffer_desc *send_tok, OM_uint32 *flags)
+{
+       OM_uint32 status;
+       gss_OID mech;
+
+       ctx->major = gss_accept_sec_context(&ctx->minor,
+           &ctx->context, ctx->creds, recv_tok,
+           GSS_C_NO_CHANNEL_BINDINGS, &ctx->client, &mech,
+           send_tok, flags, NULL, &ctx->client_creds);
+
+       if (GSS_ERROR(ctx->major))
+               ssh_gssapi_error(ctx);
+
+       if (ctx->client_creds)
+               debug("Received some client credentials");
+       else
+               debug("Got no client credentials");
+
+       status = ctx->major;
+
+       /* Now, if we're complete and we have the right flags, then
+        * we flag the user as also having been authenticated
+        */
+
+       if (((flags == NULL) || ((*flags & GSS_C_MUTUAL_FLAG) &&
+           (*flags & GSS_C_INTEG_FLAG))) && (ctx->major == GSS_S_COMPLETE)) {
+               if (ssh_gssapi_getclient(ctx, &gssapi_client))
+                       fatal("Couldn't convert client name");
+       }
+
+       return (status);
+}
+
+/*
+ * This parses an exported name, extracting the mechanism specific portion
+ * to use for ACL checking. It verifies that the name belongs the mechanism
+ * originally selected.
+ */
+static OM_uint32
+ssh_gssapi_parse_ename(Gssctxt *ctx, gss_buffer_t ename, gss_buffer_t name)
+{
+       char *tok;
+       OM_uint32 offset;
+       OM_uint32 oidl;
+
+       tok=ename->value;
+
+#ifdef GSI /* GSI gss_export_name() is broken. */
+       if ((ctx->oid->length == gssapi_gsi_mech.oid.length) &&
+           (memcmp(ctx->oid->elements, gssapi_gsi_mech.oid.elements,
+                   gssapi_gsi_mech.oid.length) == 0)) {
+           name->length = ename->length;
+           name->value = xmalloc(ename->length+1);
+           memcpy(name->value, ename->value, ename->length);
+           return GSS_S_COMPLETE;
+       }
+#endif
+
+       /*
+        * Check that ename is long enough for all of the fixed length
+        * header, and that the initial ID bytes are correct
+        */
+
+       if (ename->length<6 || memcmp(tok,"\x04\x01", 2)!=0)
+               return GSS_S_FAILURE;
+
+       /*
+        * Extract the OID, and check it. Here GSSAPI breaks with tradition
+        * and does use the OID type and length bytes. To confuse things
+        * there are two lengths - the first including these, and the
+        * second without.
+        */
+
+       oidl = GET_16BIT(tok+2); /* length including next two bytes */
+       oidl = oidl-2; /* turn it into the _real_ length of the variable OID */
+
+       /*
+        * Check the BER encoding for correct type and length, that the
+        * string is long enough and that the OID matches that in our context
+        */
+       if (tok[4] != 0x06 || tok[5] != oidl ||
+           ename->length < oidl+6 ||
+          !ssh_gssapi_check_oid(ctx,tok+6,oidl))
+               return GSS_S_FAILURE;
+
+       offset = oidl+6;
+
+       if (ename->length < offset+4)
+               return GSS_S_FAILURE;
+
+       name->length = GET_32BIT(tok+offset);
+       offset += 4;
+
+       if (ename->length < offset+name->length)
+               return GSS_S_FAILURE;
+
+       name->value = xmalloc(name->length+1);
+       memcpy(name->value,tok+offset,name->length);
+       ((char *)name->value)[name->length] = 0;
+
+       return GSS_S_COMPLETE;
+}
+
+/* Extract the client details from a given context. This can only reliably
+ * be called once for a context */
+
+/* Priviledged (called from accept_secure_ctx) */
+OM_uint32
+ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client)
+{
+       int i = 0;
+
+       gss_buffer_desc ename;
+
+       client->mech = NULL;
+
+       while (supported_mechs[i]->name != NULL) {
+               if (supported_mechs[i]->oid.length == ctx->oid->length &&
+                   (memcmp(supported_mechs[i]->oid.elements,
+                   ctx->oid->elements, ctx->oid->length) == 0))
+                       client->mech = supported_mechs[i];
+               i++;
+       }
+
+       if (client->mech == NULL)
+               return GSS_S_FAILURE;
+
+       if ((ctx->major = gss_display_name(&ctx->minor, ctx->client,
+           &client->displayname, NULL))) {
+               ssh_gssapi_error(ctx);
+               return (ctx->major);
+       }
+
+       if ((ctx->major = gss_export_name(&ctx->minor, ctx->client,
+           &ename))) {
+               ssh_gssapi_error(ctx);
+               return (ctx->major);
+       }
+
+       if ((ctx->major = ssh_gssapi_parse_ename(ctx,&ename,
+           &client->exportedname))) {
+               return (ctx->major);
+       }
+
+       /* We can't copy this structure, so we just move the pointer to it */
+       client->creds = ctx->client_creds;
+       ctx->client_creds = GSS_C_NO_CREDENTIAL;
+       return (ctx->major);
+}
+
+/* As user - called through fatal cleanup hook */
+void
+ssh_gssapi_cleanup_creds(void *ignored)
+{
+       if (gssapi_client.store.filename != NULL) {
+               /* Unlink probably isn't sufficient */
+               debug("removing gssapi cred file\"%s\"", gssapi_client.store.filename);
+               unlink(gssapi_client.store.filename);
+       }
+}
+
+/* As user */
+void
+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");
+}
+
+/* This allows GSSAPI methods to do things to the childs environment based
+ * on the passed authentication process and credentials.
+ */
+/* As user */
+void
+ssh_gssapi_do_child(char ***envp, u_int *envsizep)
+{
+
+       if (gssapi_client.store.envvar != NULL &&
+           gssapi_client.store.envval != NULL) {
+
+               debug("Setting %s to %s", gssapi_client.store.envvar,
+               gssapi_client.store.envval);
+               child_set_env(envp, envsizep, gssapi_client.store.envvar,
+                    gssapi_client.store.envval);
+       }
+}
+
+/* Priviledged */
+int
+ssh_gssapi_userok(char *user)
+{
+       if (gssapi_client.exportedname.length == 0 ||
+           gssapi_client.exportedname.value == NULL) {
+               debug("No suitable client data");
+               return 0;
+       }
+       if (gssapi_client.mech && gssapi_client.mech->userok)
+               return ((*gssapi_client.mech->userok)(&gssapi_client, user));
+       else
+               debug("ssh_gssapi_userok: Unknown GSSAPI mechanism");
+       return (0);
+}
+
 /* Return a list of the gss-group1-sha1-x mechanisms supported by this
  * program.
  *
@@ -157,52 +400,6 @@ ssh_gssapi_server_mechanisms() {
           return(mechs);
 }
 
-/* Unpriviledged */
-void ssh_gssapi_supported_oids(gss_OID_set *oidset) {
-       int i =0;
-       OM_uint32 maj_status,min_status;
-       int present;
-       gss_OID_set supported;
-       
-       gss_create_empty_oid_set(&min_status,oidset);
-       PRIVSEP(gss_indicate_mechs(&min_status, &supported));
-
-       while (supported_mechs[i]->name!=NULL) {
-               if ((maj_status=gss_test_oid_set_member(&min_status,
-                                                      &supported_mechs[i]->oid,
-                                                      supported,
-                                                      &present))) {
-                       present=0;
-               }
-               if (present) {
-                       gss_add_oid_set_member(&min_status,
-                                              &supported_mechs[i]->oid,
-                                              oidset); 
-               }
-               i++;
-       }
-}      
-
-/* Find out which GSS type (out of the list we define in ssh-gss.h) a
- * particular connection is using 
- */
-
-/* Priviledged (called ssh_gssapi_accept_ctx -> ssh_gssapi_getclient ->) */
-ssh_gssapi_mech *
-ssh_gssapi_get_ctype(Gssctxt *ctxt) {
-       int i=0;
-       
-       while(supported_mechs[i]->name!=NULL) {
-           if (supported_mechs[i]->oid.length == ctxt->oid->length &&
-               (memcmp(supported_mechs[i]->oid.elements,
-                       ctxt->oid->elements,ctxt->oid->length)==0)) {
-               return supported_mechs[i];
-           }
-           i++;
-       }
-       return NULL;
-}
-
 /* Return the OID that corresponds to the given context name */
  
 /* Unpriviledged */
@@ -230,151 +427,13 @@ ssh_gssapi_server_id_kex(char *name) {
   return &supported_mechs[i]->oid;
 }
 
-/* Wrapper around accept_sec_context
- * Requires that the context contains:
- *    oid              
- *    credentials      (from ssh_gssapi_acquire_cred)
- */
-/* Priviledged */
-OM_uint32 ssh_gssapi_accept_ctx(Gssctxt *ctx,gss_buffer_desc *recv_tok,
-                               gss_buffer_desc *send_tok, OM_uint32 *flags) 
-{
-       OM_uint32 status;
-       gss_OID mech;
-       
-       ctx->major=gss_accept_sec_context(&ctx->minor,
-                                         &ctx->context,
-                                         ctx->creds,
-                                         recv_tok,
-                                         GSS_C_NO_CHANNEL_BINDINGS,
-                                         &ctx->client,
-                                         &mech, /* read-only pointer */
-                                         send_tok,
-                                         flags,
-                                         NULL,
-                                         &ctx->client_creds);
-       if (GSS_ERROR(ctx->major)) {
-               ssh_gssapi_error(ctx);
-       }
-       
-       if (ctx->client_creds) {
-               debug("Received some client credentials");
-       } else {
-               debug("Got no client credentials");
-       }
-
-       /* FIXME: We should check that the me
-        * the one that we asked for (in ctx->oid) */
-
-       status=ctx->major;
-       
-       /* Now, if we're complete and we have the right flags, then
-        * we flag the user as also having been authenticated
-        */
-       
-       if (((flags==NULL) || ((*flags & GSS_C_MUTUAL_FLAG) && 
-                              (*flags & GSS_C_INTEG_FLAG))) &&
-           (ctx->major == GSS_S_COMPLETE)) {
-               if (ssh_gssapi_getclient(ctx,&gssapi_client.mech,
-                                        &gssapi_client.name,
-                                        &gssapi_client.creds))
-                       fatal("Couldn't convert client name");
-       }
-
-       /* Make sure that the getclient call hasn't stamped on this */
-       return(status);
-}
-
-/* Extract the client details from a given context. This can only reliably
- * be called once for a context */
-
-/* Priviledged (called from accept_secure_ctx) */
-OM_uint32 
-ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_mech **type,
-                    gss_buffer_desc *name, gss_cred_id_t *creds) {
-
-       *type=ssh_gssapi_get_ctype(ctx);
-       if ((ctx->major=gss_display_name(&ctx->minor,ctx->client,name,NULL))) {
-               ssh_gssapi_error(ctx);
-               return(ctx->major);
-       }
-       
-       /* This is icky. There appears to be no way to copy this structure,
-        * rather than the pointer to it, so we simply copy the pointer and
-        * mark the originator as empty so we don't destroy it. 
-        */
-       *creds=ctx->client_creds;
-       ctx->client_creds=GSS_C_NO_CREDENTIAL;
-       return(ctx->major);
-}
-
-/* As user - called through fatal cleanup hook */
-void
-ssh_gssapi_cleanup_creds(void *ignored)
-{
-       if (gssapi_client.store.filename!=NULL) {
-               /* Unlink probably isn't sufficient */
-               debug("removing gssapi cred file\"%s\"",gssapi_client.store.filename);
-               unlink(gssapi_client.store.filename);
-       }
-}
-
-/* As user */
-void 
-ssh_gssapi_storecreds()
-{
-       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");
-       }
-}
-
-/* This allows GSSAPI methods to do things to the childs environment based
- * on the passed authentication process and credentials.
- */
-/* As user */
-void 
-ssh_gssapi_do_child(char ***envp, u_int *envsizep) 
-{
-
-       if (gssapi_client.store.envvar!=NULL && 
-           gssapi_client.store.envval!=NULL) {
-           
-               debug("Setting %s to %s", gssapi_client.store.envvar,
-                                         gssapi_client.store.envval);                            
-               child_set_env(envp, envsizep, gssapi_client.store.envvar, 
-                                             gssapi_client.store.envval);
-       }
-}
-
-/* Priviledged */
-int
-ssh_gssapi_userok(char *user)
-{
-       if (gssapi_client.name.length==0 || 
-           gssapi_client.name.value==NULL) {
-               debug("No suitable client data");
-               return 0;
-       }
-       if (gssapi_client.mech && gssapi_client.mech->userok) {
-               return((*gssapi_client.mech->userok)(&gssapi_client,user));
-       } else {
-               debug("ssh_gssapi_userok: Unknown GSSAPI mechanism");
-       }
-       return(0);
-}
-
 /* Priviledged */
 int
 ssh_gssapi_localname(char **user)
 {
        *user = NULL;
-       if (gssapi_client.name.length==0 || 
-           gssapi_client.name.value==NULL) {
+       if (gssapi_client.displayname.length==0 || 
+           gssapi_client.displayname.value==NULL) {
                debug("No suitable client data");
                return(0);;
        }
index 37d402ef40d46aa4fb12954ff5894d9b4b2ebdac..033cd91fae6df2708a54d312e9e8da52131a5583 100644 (file)
@@ -50,9 +50,6 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg }
 #ifdef HAVE_NETGROUP_H
 # include <netgroup.h>
 #endif
-#if defined(HAVE_NETDB_H)
-# include <netdb.h>
-#endif
 #ifdef HAVE_ENDIAN_H
 # include <endian.h>
 #endif
@@ -68,6 +65,7 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg }
 #ifdef HAVE_NEXT
 #  include <libc.h>
 #endif
+#define __USE_GNU /* before unistd.h, activate extra prototypes for glibc */
 #include <unistd.h> /* For STDIN_FILENO, etc */
 #include <termios.h> /* Struct winsize */
 
@@ -133,12 +131,18 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg }
 #ifdef HAVE_SYS_MMAN_H
 #include <sys/mman.h> /* for MAP_ANONYMOUS */
 #endif
+#ifdef HAVE_SYS_STRTIO_H
+#include <sys/strtio.h>        /* for TIOCCBRK on HP-UX */
+#endif
 
 #include <netinet/in_systm.h> /* For typedefs */
 #include <netinet/in.h> /* For IPv6 macros */
 #include <netinet/ip.h> /* For IPTOS macros */
 #include <netinet/tcp.h>
 #include <arpa/inet.h>
+#if defined(HAVE_NETDB_H)
+# include <netdb.h>
+#endif
 #ifdef HAVE_RPC_TYPES_H
 # include <rpc/types.h> /* For INADDR_LOOPBACK */
 #endif
@@ -167,7 +171,6 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg }
 
 #include "version.h"
 #include "openbsd-compat/openbsd-compat.h"
-#include "openbsd-compat/bsd-cygwin_util.h"
 #include "openbsd-compat/bsd-nextstep.h"
 
 #include "entropy.h"
index 612b02f04e0e204e300c47cd0bc111e3f2d5b224..046b87a6e9cf2e2cc8a14bc2fc1622425e4d6f09 100644 (file)
@@ -294,7 +294,7 @@ choose_kex(Kex *k, char *client, char *server)
 {
        k->name = match_list(client, server, NULL);
        if (k->name == NULL)
-               fatal("No key exchange algorithm");
+               fatal("no kex alg");
        if (strcmp(k->name, KEX_DH1) == 0) {
                k->kex_type = KEX_DH_GRP1_SHA1;
        } else if (strcmp(k->name, KEX_DHGEX) == 0) {
index 22710045eca50f19184202258214c4189f6b4392..ad75542c25523c688336cc016d1d1bc63b0b4ea5 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.51 2003/02/12 09:33:04 markus Exp $");
+RCSID("$OpenBSD: key.c,v 1.54 2003/07/09 13:58:19 avsm Exp $");
 
 #include <openssl/evp.h>
 
@@ -169,7 +169,7 @@ key_equal(Key *a, Key *b)
        return 0;
 }
 
-static u_char *
+u_char*
 key_fingerprint_raw(Key *k, enum fp_type dgst_type, u_int *dgst_raw_length)
 {
        const EVP_MD *md = NULL;
@@ -236,8 +236,10 @@ key_fingerprint_hex(u_char *dgst_raw, u_int dgst_raw_len)
        for (i = 0; i < dgst_raw_len; i++) {
                char hex[4];
                snprintf(hex, sizeof(hex), "%02x:", dgst_raw[i]);
-               strlcat(retval, hex, dgst_raw_len * 3);
+               strlcat(retval, hex, dgst_raw_len * 3 + 1);
        }
+
+       /* Remove the trailing ':' character */
        retval[(dgst_raw_len * 3) - 1] = '\0';
        return retval;
 }
@@ -438,7 +440,7 @@ key_read(Key *ret, char **cpp)
                        xfree(blob);
                        return -1;
                }
-               k = key_from_blob(blob, n);
+               k = key_from_blob(blob, (u_int)n);
                xfree(blob);
                if (k == NULL) {
                        error("key_read: key_from_blob %s failed", cp);
@@ -676,7 +678,7 @@ key_names_valid2(const char *names)
 }
 
 Key *
-key_from_blob(u_char *blob, int blen)
+key_from_blob(u_char *blob, u_int blen)
 {
        Buffer b;
        char *ktype;
index 4ad321f7eca4f80349d5bde74af217ab64f65285..7ff4270e8c2b0e1e23e2be303b4defabd92b799b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: key.h,v 1.20 2003/02/12 09:33:04 markus Exp $ */
+/*     $OpenBSD: key.h,v 1.22 2003/06/24 08:23:46 markus Exp $ */
 
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
@@ -62,6 +62,7 @@ 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 **);
@@ -71,7 +72,7 @@ Key   *key_generate(int, u_int);
 Key    *key_from_private(Key *);
 int     key_type_from_name(char *);
 
-Key    *key_from_blob(u_char *, int);
+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 *);
index 84e4ce0ac105a2751bb1745e2097ae5049bbac64..58ce8e5dd63784c31ca075f3f645aa530be85e90 100644 (file)
@@ -34,7 +34,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: log.c,v 1.25 2003/01/11 18:29:43 markus Exp $");
+RCSID("$OpenBSD: log.c,v 1.28 2003/05/24 09:02:22 djm Exp $");
 
 #include "log.h"
 #include "xmalloc.h"
@@ -127,7 +127,7 @@ error(const char *fmt,...)
 /* Log this message (information that usually should go to the log). */
 
 void
-log(const char *fmt,...)
+logit(const char *fmt,...)
 {
        va_list args;
 
@@ -339,6 +339,9 @@ 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
+       struct syslog_data sdata = SYSLOG_DATA_INIT;
+#endif
        char msgbuf[MSGBUFSIZ];
        char fmtbuf[MSGBUFSIZ];
        char *txt = NULL;
@@ -387,14 +390,19 @@ do_log(LogLevel level, const char *fmt, va_list args)
        } else {
                vsnprintf(msgbuf, sizeof(msgbuf), fmt, args);
        }
-       /* Escape magic chars in output. */
-       strnvis(fmtbuf, msgbuf, sizeof(fmtbuf), VIS_OCTAL);
-       
+       strnvis(fmtbuf, msgbuf, sizeof(fmtbuf), VIS_SAFE|VIS_OCTAL);
        if (log_on_stderr) {
-               fprintf(stderr, "%s\r\n", fmtbuf);
+               snprintf(msgbuf, sizeof msgbuf, "%s\r\n", fmtbuf);
+               write(STDERR_FILENO, msgbuf, strlen(msgbuf));
        } else {
+#ifdef OPENLOG_R
+               openlog_r(argv0 ? argv0 : __progname, LOG_PID, log_facility, &sdata);
+               syslog_r(pri, &sdata, "%.500s", fmtbuf);
+               closelog_r(&sdata);
+#else
                openlog(argv0 ? argv0 : __progname, LOG_PID, log_facility);
                syslog(pri, "%.500s", fmtbuf);
                closelog();
+#endif
        }
 }
diff --git a/openssh/mdoc2man.pl b/openssh/mdoc2man.pl
deleted file mode 100644 (file)
index fddb2e0..0000000
+++ /dev/null
@@ -1,590 +0,0 @@
-#!/usr/bin/perl
-###
-### Quick usage:  mdoc2man.pl < mdoc_manpage.8 > man_manpage.8
-###
-###
-###  Copyright (c) 2001 University of Illinois Board of Trustees
-###  Copyright (c) 2001 Mark D. Roth
-###  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.
-###  3. All advertising materials mentioning features or use of this software
-###     must display the following acknowledgement:
-###     This product includes software developed by the University of
-###     Illinois at Urbana, and their contributors.
-###  4. The University nor the names of their
-###     contributors may be used to endorse or promote products derived from
-###     this software without specific prior written permission.
-### 
-###  THIS SOFTWARE IS PROVIDED BY THE TRUSTEES AND CONTRIBUTORS ``AS IS'' AND
-###  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-###  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-###  ARE DISCLAIMED.  IN NO EVENT SHALL THE TRUSTEES OR CONTRIBUTORS BE LIABLE
-###  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-###  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-###  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-###  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-###  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-###  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-###  SUCH DAMAGE.
-###
-
-use strict;
-
-my ($name, $date, $id);
-my ($line);
-my ($optlist, $oldoptlist, $nospace, $enum, $synopsis);
-my ($reference, $block, $ext, $extopt, $literal);
-my (@refauthors, $reftitle, $refissue, $refdate, $refopt);
-
-
-$optlist = 0;          ### 1 = bullet, 2 = enum, 3 = tag, 4 = item
-$oldoptlist = 0;
-$nospace = 0;
-$synopsis = 0;
-$reference = 0;
-$block = 0;
-$ext = 0;
-$extopt = 0;
-$literal = 0;
-
-while ($line = <STDIN>)
-{
-       if ($line !~ /^\./)
-       {
-               print $line;
-               print ".br\n"
-                       if ($literal);
-               next;
-       }
-
-       $line =~ s/^\.//;
-
-       next
-               if ($line =~ m/\\"/);
-
-       $line = ParseMacro($line);
-       print($line)
-               if (defined $line);
-}
-
-
-
-sub ParseMacro # ($line)
-{
-       my ($line) = @_;
-       my (@words, $retval, $option, $parens);
-
-       @words = split(/\s+/, $line);
-       $retval = '';
-       $option = 0;
-       $parens = 0;
-
-#      print('@words = ', scalar(@words), ': ', join(' ', @words), "\n");
-
-       while ($_ = shift @words)
-       {
-#              print "WORD: $_\n";
-
-               next
-                       if (/^(Li|Pf)$/);
-
-               if (/^Xo$/)
-               {
-                       $ext = 1;
-                       $retval .= ' '
-                               if ($retval ne '' && $retval !~ m/[\n ]$/);
-                       next;
-               }
-
-               if (/^Xc$/)
-               {
-                       $ext = 0;
-                       $retval .= "\n"
-                               if (! $extopt);
-                       last;
-               }
-
-               if (/^Bd$/)
-               {
-                       $literal = 1
-                               if ($words[0] eq '-literal');
-                       $retval .= "\n";
-                       last;
-               }
-
-               if (/^Ed$/)
-               {
-                       $literal = 0;
-                       last;
-               }
-
-               if (/^Ns$/)
-               {
-                       $nospace = 1
-                               if (! $nospace);
-                       $retval =~ s/ $//;
-                       next;
-               }
-
-               if (/^No$/)
-               {
-                       $retval =~ s/ $//;
-                       $retval .= shift @words;
-                       next;
-               }
-
-               if (/^Dq$/)
-               {
-                       $retval .= '``';
-                       do
-                       {
-                               $retval .= (shift @words) . ' ';
-                       }
-                       while (@words > 0 && $words[0] !~ m/^[\.,]/);
-                       $retval =~ s/ $//;
-                       $retval .= '\'\'';
-                       $nospace = 1
-                               if (! $nospace && $words[0] =~ m/^[\.,]/);
-                       next;
-               }
-
-               if (/^(Sq|Ql)$/)
-               {
-                       $retval .= '`' . (shift @words) . '\'';
-                       $nospace = 1
-                               if (! $nospace && $words[0] =~ m/^[\.,]/);
-                       next;
-               }
-
-#              if (/^Ic$/)
-#              {
-#                      $retval .= '\\fB' . shift(@words) . '\\fP';
-#                      next;
-#              }
-
-               if (/^Oo$/)
-               {
-#                      $retval .= "[\\c\n";
-                       $extopt = 1;
-                       $nospace = 1
-                               if (! $nospace);
-                       $retval .= '[';
-                       next;
-               }
-
-               if (/^Oc$/)
-               {
-                       $extopt = 0;
-                       $retval .= ']';
-                       next;
-               }
-
-               $retval .= ' '
-                       if (! $nospace && $retval ne '' && $retval !~ m/[\n ]$/);
-               $nospace = 0
-                       if ($nospace == 1);
-
-               if (/^Dd$/)
-               {
-                       $date = join(' ', @words);
-                       return undef;
-               }
-
-               if (/^Dt$/)
-               {
-                       $id = join(' ', @words);
-                       return undef;
-               }
-
-               if (/^Os$/)
-               {
-                       $retval .= '.TH '
-                               . $id
-                               . " \"$date\" \""
-                               . join(' ', @words)
-                               . "\"";
-                       last;
-               }
-
-               if (/^Sh$/)
-               {
-                       $retval .= '.SH';
-                       if ($words[0] eq 'SYNOPSIS')
-                       {
-                               $synopsis = 1;
-                       }
-                       else
-                       {
-                               $synopsis = 0;
-                       }
-                       next;
-               }
-
-               if (/^Xr$/)
-               {
-                       $retval .= '\\fB' . (shift @words) .
-                               '\\fP(' . (shift @words) . ')'
-                               . (shift @words);
-                       last;
-               }
-
-               if (/^Rs/)
-               {
-                       @refauthors = ();
-                       $reftitle = '';
-                       $refissue = '';
-                       $refdate = '';
-                       $refopt = '';
-                       $reference = 1;
-                       last;
-               }
-
-               if (/^Re/)
-               {
-                       $retval .= "\n";
-
-                       # authors
-                       while (scalar(@refauthors) > 1)
-                       {
-                               $retval .= shift(@refauthors) . ', ';
-                       }
-                       $retval .= 'and '
-                               if ($retval ne '');
-                       $retval .= shift(@refauthors);
-                       
-                       # title 
-                       $retval .= ', \\fI' . $reftitle . '\\fP';
-
-                       # issue
-                       $retval .= ', ' . $refissue
-                               if ($refissue ne '');
-
-                       # date
-                       $retval .= ', ' . $refdate
-                               if ($refdate ne '');
-
-                       # optional info
-                       $retval .= ', ' . $refopt
-                               if ($refopt ne '');
-
-                       $retval .= ".\n";
-
-                       $reference = 0;
-                       last;
-               }
-
-               if ($reference)
-               {
-                       if (/^%A$/)
-                       {
-                               unshift(@refauthors, join(' ', @words));
-                               last;
-                       }
-
-                       if (/^%T$/)
-                       {
-                               $reftitle = join(' ', @words);
-                               $reftitle =~ s/^"//;
-                               $reftitle =~ s/"$//;
-                               last;
-                       }
-
-                       if (/^%N$/)
-                       {
-                               $refissue = join(' ', @words);
-                               last;
-                       }
-
-                       if (/^%D$/)
-                       {
-                               $refdate = join(' ', @words);
-                               last;
-                       }
-
-                       if (/^%O$/)
-                       {
-                               $refopt = join(' ', @words);
-                               last;
-                       }
-               }
-
-               if (/^Nm$/)
-               {
-                       $name = shift @words
-                               if (@words > 0);
-                       $retval .= ".br\n"
-                               if ($synopsis);
-                       $retval .= "\\fB$name\\fP";
-                       $nospace = 1
-                               if (! $nospace && $words[0] =~ m/^[\.,]/);
-                       next;
-               }
-
-               if (/^Nd$/)
-               {
-                       $retval .= '\\-';
-                       next;
-               }
-
-               if (/^Fl$/)
-               {
-                       $retval .= '\\fB\\-' . (shift @words) . '\\fP';
-                       $nospace = 1
-                               if (! $nospace && $words[0] =~ m/^[\.,]/);
-                       next;
-               }
-
-               if (/^Ar$/)
-               {
-                       $retval .= '\\fI';
-                       if (! defined $words[0])
-                       {
-                               $retval .= 'file ...\\fP';
-                       }
-                       else
-                       {
-                               $retval .= shift(@words) . '\\fP';
-                               while ($words[0] eq '|')
-                               {
-                                       $retval .= ' ' . shift(@words);
-                                       $retval .= ' \\fI' . shift(@words);
-                                       $retval .= '\\fP';
-                               }
-                       }
-                       $nospace = 1
-                               if (! $nospace && $words[0] =~ m/^[\.,]/);
-                       next;
-               }
-
-               if (/^Cm$/)
-               {
-                       $retval .= '\\fB' . (shift @words) . '\\fP';
-                       while ($words[0] =~ m/^[\.,:)]$/)
-                       {
-                               $retval .= shift(@words);
-                       }
-                       next;
-               }
-
-               if (/^Op$/)
-               {
-                       $option = 1;
-                       $nospace = 1
-                               if (! $nospace);
-                       $retval .= '[';
-#                      my $tmp = pop(@words);
-#                      $tmp .= ']';
-#                      push(@words, $tmp);
-                       next;
-               }
-
-               if (/^Pp$/)
-               {
-                       $retval .= "\n";
-                       next;
-               }
-
-               if (/^Ss$/)
-               {
-                       $retval .= '.SS';
-                       next;
-               }
-
-               if (/^Pa$/ && ! $option)
-               {
-                       $retval .= '\\fI';
-                       $retval .= '\\&'
-                               if ($words[0] =~ m/^\./);
-                       $retval .= (shift @words) . '\\fP';
-                       while ($words[0] =~ m/^[\.,:;)]$/)
-                       {
-                               $retval .= shift(@words);
-                       }
-#                      $nospace = 1
-#                              if (! $nospace && $words[0] =~ m/^[\.,:)]/);
-                       next;
-               }
-
-               if (/^Dv$/)
-               {
-                       $retval .= '.BR';
-                       next;
-               }
-
-               if (/^(Em|Ev)$/)
-               {
-                       $retval .= '.IR';
-                       next;
-               }
-
-               if (/^Pq$/)
-               {
-                       $retval .= '(';
-                       $nospace = 1;
-                       $parens = 1;
-                       next;
-               }
-
-               if (/^(S[xy])$/)
-               {
-                       $retval .= '.B ' . join(' ', @words);
-                       last;
-               }
-
-               if (/^Ic$/)
-               {
-                       $retval .= '\\fB';
-                       while (defined $words[0]
-                               && $words[0] !~ m/^[\.,]/)
-                       {
-                               if ($words[0] eq 'Op')
-                               {
-                                       shift(@words);
-                                       $retval .= '[';
-                                       my $tmp = pop(@words);
-                                       $tmp .= ']';
-                                       push(@words, $tmp);
-                                       next;
-                               }
-                               if ($words[0] eq 'Ar')
-                               {
-                                       shift @words;
-                                       $retval .= '\\fI';
-                                       $retval .= shift @words;
-                                       $retval .= '\\fP';
-                               }
-                               else
-                               {
-                                       $retval .= shift @words;
-                               }
-                               $retval .= ' '
-                                       if (! $nospace);
-                       }
-                       $retval =~ s/ $//;
-                       $retval .= '\\fP';
-                       $retval .= shift @words
-                               if (defined $words[0]);
-                       last;
-               }
-
-               if (/^Bl$/)
-               {
-                       $oldoptlist = $optlist;
-                       if ($words[0] eq '-bullet')
-                       {
-                               $optlist = 1;
-                       }
-                       elsif ($words[0] eq '-enum')
-                       {
-                               $optlist = 2;
-                               $enum = 0;
-                       }
-                       elsif ($words[0] eq '-tag')
-                       {
-                               $optlist = 3;
-                       }
-                       elsif ($words[0] eq '-item')
-                       {
-                               $optlist = 4;
-                       }
-                       last;
-               }
-
-               if (/^El$/)
-               {
-                       $optlist = $oldoptlist;
-                       next;
-               }
-
-               if ($optlist && /^It$/)
-               {
-                       if ($optlist == 1)
-                       {
-                               # bullets
-                               $retval .= '.IP \\(bu';
-                               next;
-                       }
-
-                       if ($optlist == 2)
-                       {
-                               # enum
-                               $retval .= '.IP ' . (++$enum) . '.';
-                               next;
-                       }
-
-                       if ($optlist == 3)
-                       {
-                               # tags
-                               $retval .= ".TP\n";
-                               if ($words[0] =~ m/^(Pa|Ev)$/)
-                               {
-                                       shift @words;
-                                       $retval .= '.B';
-                               }
-                               next;
-                       }
-
-                       if ($optlist == 4)
-                       {
-                               # item
-                               $retval .= ".IP\n";
-                               next;
-                       }
-
-                       next;
-               }
-
-               if (/^Sm$/)
-               {
-                       if ($words[0] eq 'off')
-                       {
-                               $nospace = 2;
-                       }
-                       elsif ($words[0] eq 'on')
-                       {
-#                              $retval .= "\n";
-                               $nospace = 0;
-                       }
-                       shift @words;
-                       next;
-               }
-
-               $retval .= "$_";
-       }
-
-       return undef
-               if ($retval eq '.');
-
-       $retval =~ s/^\.([^a-zA-Z])/$1/;
-#      $retval =~ s/ $//;
-
-       $retval .= ')'
-               if ($parens == 1);
-
-       $retval .= ']'
-               if ($option == 1);
-
-#      $retval .= ' '
-#              if ($nospace && $retval ne '' && $retval !~ m/\n$/);
-
-#      $retval .= ' '
-#              if ($extended && $retval !~ m/ $/);
-
-       $retval .= ' '
-               if ($ext && ! $extopt && $retval !~ m/ $/);
-
-       $retval .= "\n"
-               if (! $ext && ! $extopt && $retval ne '' && $retval !~ m/\n$/);
-
-       return $retval;
-}
-
-
index eac6ccd5802fc95e318a54f8e7abd6ed5f6c2f02..8700ce6a31074e1f23cb60257022bcabf396d7d2 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: misc.c,v 1.20 2002/12/13 10:03:15 markus Exp $");
+RCSID("$OpenBSD: misc.c,v 1.21 2003/04/12 10:15:36 markus Exp $");
 
 #include "misc.h"
 #include "log.h"
@@ -60,7 +60,7 @@ set_nonblock(int fd)
                debug2("fd %d is O_NONBLOCK", fd);
                return;
        }
-       debug("fd %d setting O_NONBLOCK", fd);
+       debug2("fd %d setting O_NONBLOCK", fd);
        val |= O_NONBLOCK;
        if (fcntl(fd, F_SETFL, val) == -1)
                debug("fcntl(%d, F_SETFL, O_NONBLOCK): %s",
@@ -341,29 +341,3 @@ addargs(arglist *args, char *fmt, ...)
        args->list[args->num++] = xstrdup(buf);
        args->list[args->num] = NULL;
 }
-
-mysig_t
-mysignal(int sig, mysig_t act)
-{
-#ifdef HAVE_SIGACTION
-       struct sigaction sa, osa;
-
-       if (sigaction(sig, NULL, &osa) == -1)
-               return (mysig_t) -1;
-       if (osa.sa_handler != act) {
-               memset(&sa, 0, sizeof(sa));
-               sigemptyset(&sa.sa_mask);
-               sa.sa_flags = 0;
-#if defined(SA_INTERRUPT)
-               if (sig == SIGALRM)
-                       sa.sa_flags |= SA_INTERRUPT;
-#endif
-               sa.sa_handler = act;
-               if (sigaction(sig, &sa, NULL) == -1)
-                       return (mysig_t) -1;
-       }
-       return (osa.sa_handler);
-#else
-       return (signal(sig, act));
-#endif
-}
index 25fbd748629a35a6214bd90f4ab16c0ea895a933..b06e0f7c5216735591808add3a9217e2a1f8ad21 100644 (file)
@@ -25,7 +25,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: monitor.c,v 1.36 2003/04/01 10:22:21 markus Exp $");
+RCSID("$OpenBSD: monitor.c,v 1.49 2003/08/28 12:54:34 markus Exp $");
 
 #include <openssl/dh.h>
 
@@ -98,7 +98,7 @@ struct {
        u_int olen;
 } child_state;
 
-/* Functions on the montior that answer unprivileged requests */
+/* Functions on the monitor that answer unprivileged requests */
 
 int mm_answer_moduli(int, Buffer *);
 int mm_answer_sign(int, Buffer *);
@@ -123,13 +123,17 @@ int mm_answer_sessid(int, Buffer *);
 
 #ifdef USE_PAM
 int mm_answer_pam_start(int, Buffer *);
+int mm_answer_pam_account(int, Buffer *);
+int mm_answer_pam_init_ctx(int, Buffer *);
+int mm_answer_pam_query(int, Buffer *);
+int mm_answer_pam_respond(int, Buffer *);
+int mm_answer_pam_free_ctx(int, Buffer *);
 #endif
 
-#ifdef KRB4
-int mm_answer_krb4(int, Buffer *);
-#endif
-#ifdef KRB5
-int mm_answer_krb5(int, Buffer *);
+#ifdef GSSAPI
+int mm_answer_gss_setup_ctx(int, Buffer *);
+int mm_answer_gss_accept_ctx(int, Buffer *);
+int mm_answer_gss_userok(int, Buffer *);
 #endif
 
 #ifdef GSSAPI
@@ -156,8 +160,9 @@ static int key_blobtype = MM_NOKEY;
 static char *hostbased_cuser = NULL;
 static char *hostbased_chost = NULL;
 static char *auth_method = "unknown";
-static int session_id2_len = 0;
+static u_int session_id2_len = 0;
 static u_char *session_id2 = NULL;
+static pid_t monitor_child_pid;
 
 struct mon_table {
        enum monitor_reqtype type;
@@ -182,6 +187,11 @@ struct mon_table mon_dispatch_proto20[] = {
     {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
 #ifdef USE_PAM
     {MONITOR_REQ_PAM_START, MON_ISAUTH, mm_answer_pam_start},
+    {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account},
+    {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx},
+    {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query},
+    {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond},
+    {MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx},
 #endif
 #ifdef BSD_AUTH
     {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery},
@@ -191,17 +201,17 @@ struct mon_table mon_dispatch_proto20[] = {
     {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery},
     {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond},
 #endif
+    {MONITOR_REQ_KEYALLOWED, MON_ISAUTH, mm_answer_keyallowed},
+    {MONITOR_REQ_KEYVERIFY, MON_AUTH, mm_answer_keyverify},
 #ifdef GSSAPI
     {MONITOR_REQ_GSSSETUP, MON_ISAUTH, mm_answer_gss_setup_ctx},
     {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx},
+    {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok},
     {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign},
     {MONITOR_REQ_GSSERR, MON_ISAUTH | MON_ONCE, mm_answer_gss_error},
     {MONITOR_REQ_GSSMECHS, MON_ISAUTH, mm_answer_gss_indicate_mechs},
-    {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok},
     {MONITOR_REQ_GSSLOCALNAME, MON_ISAUTH, mm_answer_gss_localname},
 #endif
-    {MONITOR_REQ_KEYALLOWED, MON_ISAUTH, mm_answer_keyallowed},
-    {MONITOR_REQ_KEYVERIFY, MON_AUTH, mm_answer_keyverify},
     {0, 0, NULL}
 };
 
@@ -250,12 +260,11 @@ struct mon_table mon_dispatch_proto15[] = {
 #endif
 #ifdef USE_PAM
     {MONITOR_REQ_PAM_START, MON_ISAUTH, mm_answer_pam_start},
-#endif
-#ifdef KRB4
-    {MONITOR_REQ_KRB4, MON_ONCE|MON_AUTH, mm_answer_krb4},
-#endif
-#ifdef KRB5
-    {MONITOR_REQ_KRB5, MON_ONCE|MON_AUTH, mm_answer_krb5},
+    {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account},
+    {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx},
+    {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query},
+    {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond},
+    {MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx},
 #endif
     {0, 0, NULL}
 };
@@ -350,8 +359,16 @@ monitor_child_preauth(struct monitor *pmonitor)
                            !auth_root_allowed(auth_method))
                                authenticated = 0;
 #ifdef USE_PAM
-                       if (!do_pam_account(authctxt->pw->pw_name, NULL))
-                               authenticated = 0;
+                       /* PAM needs to perform account checks after auth */
+                       if (options.use_pam) {
+                               Buffer m;
+
+                               buffer_init(&m);
+                               mm_request_receive_expect(pmonitor->m_sendfd, 
+                                   MONITOR_REQ_PAM_ACCOUNT, &m);
+                               authenticated = mm_answer_pam_account(pmonitor->m_sendfd, &m);
+                               buffer_free(&m);
+                       }
 #endif
                }
 
@@ -374,9 +391,25 @@ monitor_child_preauth(struct monitor *pmonitor)
        return (authctxt);
 }
 
+static void
+monitor_set_child_handler(pid_t pid)
+{
+       monitor_child_pid = pid;
+}
+
+static void
+monitor_child_handler(int signal)
+{
+       kill(monitor_child_pid, signal);
+}
+
 void
 monitor_child_postauth(struct monitor *pmonitor)
 {
+       monitor_set_child_handler(pmonitor->m_pid);
+       signal(SIGHUP, &monitor_child_handler);
+       signal(SIGTERM, &monitor_child_handler);
+
        if (compat20) {
                mon_dispatch = mon_dispatch_postauth20;
 
@@ -628,7 +661,8 @@ mm_answer_pwnamallow(int socket, Buffer *m)
        }
 
 #ifdef USE_PAM
-       monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1);
+       if (options.use_pam)
+               monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1);
 #endif
 
        return (0);
@@ -678,7 +712,7 @@ mm_answer_authpassword(int socket, Buffer *m)
        passwd = buffer_get_string(m, &plen);
        /* Only authenticate if the context is valid */
        authenticated = options.password_authentication &&
-           auth_password(authctxt, passwd) && authctxt->valid;
+           auth_password(authctxt, passwd);
        memset(passwd, 0, strlen(passwd));
        xfree(passwd);
 
@@ -811,14 +845,133 @@ 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__);
+
        user = buffer_get_string(m, NULL);
 
        start_pam(user);
 
        xfree(user);
 
+       monitor_permit(mon_dispatch, MONITOR_REQ_PAM_ACCOUNT, 1);
+
        return (0);
 }
+
+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__);
+
+       ret = do_pam_account();
+
+       buffer_put_int(m, ret);
+
+       mm_request_send(socket, MONITOR_ANS_PAM_ACCOUNT, m);
+
+       return (ret);
+}
+
+static void *sshpam_ctxt, *sshpam_authok;
+extern KbdintDevice sshpam_device;
+
+int
+mm_answer_pam_init_ctx(int socket, Buffer *m)
+{
+
+       debug3("%s", __func__);
+       authctxt->user = buffer_get_string(m, NULL);
+       sshpam_ctxt = (sshpam_device.init_ctx)(authctxt);
+       sshpam_authok = NULL;
+       buffer_clear(m);
+       if (sshpam_ctxt != NULL) {
+               monitor_permit(mon_dispatch, MONITOR_REQ_PAM_FREE_CTX, 1);
+               buffer_put_int(m, 1);
+       } else {
+               buffer_put_int(m, 0);
+       }
+       mm_request_send(socket, MONITOR_ANS_PAM_INIT_CTX, m);
+       return (0);
+}
+
+int
+mm_answer_pam_query(int socket, Buffer *m)
+{
+       char *name, *info, **prompts;
+       u_int num, *echo_on;
+       int i, ret;
+
+       debug3("%s", __func__);
+       sshpam_authok = NULL;
+       ret = (sshpam_device.query)(sshpam_ctxt, &name, &info, &num, &prompts, &echo_on);
+       if (ret == 0 && num == 0)
+               sshpam_authok = sshpam_ctxt;
+       if (num > 1 || name == NULL || info == NULL)
+               ret = -1;
+       buffer_clear(m);
+       buffer_put_int(m, ret);
+       buffer_put_cstring(m, name);
+       xfree(name);
+       buffer_put_cstring(m, info);
+       xfree(info);
+       buffer_put_int(m, num);
+       for (i = 0; i < num; ++i) {
+               buffer_put_cstring(m, prompts[i]);
+               xfree(prompts[i]);
+               buffer_put_int(m, echo_on[i]);
+       }
+       if (prompts != NULL)
+               xfree(prompts);
+       if (echo_on != NULL)
+               xfree(echo_on);
+       mm_request_send(socket, MONITOR_ANS_PAM_QUERY, m);
+       return (0);
+}
+
+int
+mm_answer_pam_respond(int socket, Buffer *m)
+{
+       char **resp;
+       u_int num;
+       int i, ret;
+
+       debug3("%s", __func__);
+       sshpam_authok = NULL;
+       num = buffer_get_int(m);
+       if (num > 0) {
+               resp = xmalloc(num * sizeof(char *));
+               for (i = 0; i < num; ++i)
+                       resp[i] = buffer_get_string(m, NULL);
+               ret = (sshpam_device.respond)(sshpam_ctxt, num, resp);
+               for (i = 0; i < num; ++i)
+                       xfree(resp[i]);
+               xfree(resp);
+       } else {
+               ret = (sshpam_device.respond)(sshpam_ctxt, num, NULL);
+       }
+       buffer_clear(m);
+       buffer_put_int(m, ret);
+       mm_request_send(socket, MONITOR_ANS_PAM_RESPOND, m);
+       auth_method = "keyboard-interactive/pam";
+       if (ret == 0)
+               sshpam_authok = sshpam_ctxt;
+       return (0);
+}
+
+int
+mm_answer_pam_free_ctx(int socket, Buffer *m)
+{
+
+       debug3("%s", __func__);
+       (sshpam_device.free_ctx)(sshpam_ctxt);
+       buffer_clear(m);
+       mm_request_send(socket, MONITOR_ANS_PAM_FREE_CTX, m);
+       return (sshpam_authok == sshpam_ctxt);
+}
 #endif
 
 static void
@@ -942,7 +1095,7 @@ monitor_valid_userblob(u_char *data, u_int datalen)
                fail++;
        p = buffer_get_string(&b, NULL);
        if (strcmp(authctxt->user, p) != 0) {
-               log("wrong user name passed to monitor: expected %s != %.100s",
+               logit("wrong user name passed to monitor: expected %s != %.100s",
                    authctxt->user, p);
                fail++;
        }
@@ -990,7 +1143,7 @@ monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser,
                fail++;
        p = buffer_get_string(&b, NULL);
        if (strcmp(authctxt->user, p) != 0) {
-               log("wrong user name passed to monitor: expected %s != %.100s",
+               logit("wrong user name passed to monitor: expected %s != %.100s",
                    authctxt->user, p);
                fail++;
        }
@@ -1100,14 +1253,14 @@ mm_record_login(Session *s, struct passwd *pw)
        }
        /* Record that there was a login on that tty from the remote host. */
        record_login(s->pid, s->tty, pw->pw_name, pw->pw_uid,
-           get_remote_name_or_ip(utmp_len, options.verify_reverse_mapping),
+           get_remote_name_or_ip(utmp_len, options.use_dns),
            (struct sockaddr *)&from, fromlen);
 }
 
 static void
 mm_session_close(Session *s)
 {
-       debug3("%s: session %d pid %d", __func__, s->self, s->pid);
+       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);
@@ -1371,89 +1524,6 @@ mm_answer_rsa_response(int socket, Buffer *m)
        return (success);
 }
 
-#ifdef KRB4
-int
-mm_answer_krb4(int socket, Buffer *m)
-{
-       KTEXT_ST auth, reply;
-       char  *client, *p;
-       int success;
-       u_int alen;
-
-       reply.length = auth.length = 0;
-       p = buffer_get_string(m, &alen);
-       if (alen >=  MAX_KTXT_LEN)
-                fatal("%s: auth too large", __func__);
-       memcpy(auth.dat, p, alen);
-       auth.length = alen;
-       memset(p, 0, alen);
-       xfree(p);
-
-       success = options.kerberos_authentication &&
-           authctxt->valid &&
-           auth_krb4(authctxt, &auth, &client, &reply);
-
-       memset(auth.dat, 0, alen);
-       buffer_clear(m);
-       buffer_put_int(m, success);
-
-       if (success) {
-               buffer_put_cstring(m, client);
-               buffer_put_string(m, reply.dat, reply.length);
-               if (client)
-                       xfree(client);
-               if (reply.length)
-                       memset(reply.dat, 0, reply.length);
-       }
-
-       debug3("%s: sending result %d", __func__, success);
-       mm_request_send(socket, MONITOR_ANS_KRB4, m);
-
-       auth_method = "kerberos";
-
-       /* Causes monitor loop to terminate if authenticated */
-       return (success);
-}
-#endif
-
-#ifdef KRB5
-int
-mm_answer_krb5(int socket, Buffer *m)
-{
-       krb5_data tkt, reply;
-       char *client_user;
-       u_int len;
-       int success;
-
-       /* use temporary var to avoid size issues on 64bit arch */
-       tkt.data = buffer_get_string(m, &len);
-       tkt.length = len;
-
-       success = options.kerberos_authentication &&
-           authctxt->valid &&
-           auth_krb5(authctxt, &tkt, &client_user, &reply);
-
-       if (tkt.length)
-               xfree(tkt.data);
-
-       buffer_clear(m);
-       buffer_put_int(m, success);
-
-       if (success) {
-               buffer_put_cstring(m, client_user);
-               buffer_put_string(m, reply.data, reply.length);
-               if (client_user)
-                       xfree(client_user);
-               if (reply.length)
-                       xfree(reply.data);
-       }
-       mm_request_send(socket, MONITOR_ANS_KRB5, m);
-
-       return success;
-}
-#endif
-
 int
 mm_answer_term(int socket, Buffer *req)
 {
@@ -1541,7 +1611,7 @@ mm_get_kex(Buffer *m)
        kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
        kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
 #ifdef GSSAPI
-       kex->kex[KEX_GSS_GRP1_SHA1] =kexgss_server;
+       kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
 #endif
        kex->server = 1;
        kex->hostkey_type = buffer_get_int(m);
@@ -1572,6 +1642,8 @@ mm_get_keystate(struct monitor *pmonitor)
        Buffer m;
        u_char *blob, *p;
        u_int bloblen, plen;
+       u_int32_t seqnr, packets;
+       u_int64_t blocks;
 
        debug3("%s: Waiting for new keys", __func__);
 
@@ -1601,8 +1673,14 @@ mm_get_keystate(struct monitor *pmonitor)
        xfree(blob);
 
        /* Now get sequence numbers for the packets */
-       packet_set_seqnr(MODE_OUT, buffer_get_int(&m));
-       packet_set_seqnr(MODE_IN, buffer_get_int(&m));
+       seqnr = buffer_get_int(&m);
+       blocks = buffer_get_int64(&m);
+       packets = buffer_get_int(&m);
+       packet_set_state(MODE_OUT, seqnr, blocks, packets);
+       seqnr = buffer_get_int(&m);
+       blocks = buffer_get_int64(&m);
+       packets = buffer_get_int(&m);
+       packet_set_state(MODE_IN, seqnr, blocks, packets);
 
  skip:
        /* Get the key context */
@@ -1724,75 +1802,107 @@ monitor_reinit(struct monitor *mon)
        mon->m_sendfd = pair[1];
 }
 
-#ifdef GSSAPI
+#ifdef GSI
 
 int
-mm_answer_gss_setup_ctx(int socket, Buffer *m) {
-        gss_OID_desc oid;
-        OM_uint32 major;
-        u_int len;
+mm_answer_gsi_gridmap(int socket, Buffer *m) {
+    char *subject, *name;
+
+    subject = buffer_get_string(m, NULL);
+    
+    gsi_gridmap(subject, &name);
 
-        oid.elements=buffer_get_string(m,&len);
-       oid.length=len;
-                
-        major=ssh_gssapi_server_ctx(&gsscontext,&oid);
+    buffer_clear(m);
+    if (name) {
+       buffer_put_cstring(m, name);
+       debug3("%s: sending result %s", __func__, name);
+       xfree(name);
+    } else {
+       buffer_put_cstring(m, "");
+       debug3("%s: sending result \"\"", __func__);
+    }
 
-        xfree(oid.elements);
+    mm_request_send(socket, MONITOR_ANS_GSIGRIDMAP, m);
 
-        buffer_clear(m);
-        buffer_put_int(m,major);
+    return(0);
+}
+
+#endif /* GSI */
+
+#ifdef GSSAPI
+int
+mm_answer_gss_setup_ctx(int socket, Buffer *m)
+{
+       gss_OID_desc oid;
+       OM_uint32 major;
+       u_int len;
 
-        mm_request_send(socket,MONITOR_ANS_GSSSETUP,m);
+       oid.elements = buffer_get_string(m, &len);
+       oid.length = len;
 
-       /* Now we have a context, enable the step and sign */
-       monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP,1);
+       major = ssh_gssapi_server_ctx(&gsscontext, &oid);
 
-        return(0);
+       xfree(oid.elements);
+
+       buffer_clear(m);
+       buffer_put_int(m, major);
+
+       mm_request_send(socket,MONITOR_ANS_GSSSETUP, m);
+
+       /* Now we have a context, enable the step */
+       monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 1);
+
+       return (0);
 }
 
 int
-mm_answer_gss_accept_ctx(int socket, Buffer *m) {
-        gss_buffer_desc in,out;
-        OM_uint32 major,minor;
-        OM_uint32 flags = 0; /* GSI needs this */
+mm_answer_gss_accept_ctx(int socket, Buffer *m)
+{
+       gss_buffer_desc in;
+       gss_buffer_desc out = GSS_C_EMPTY_BUFFER;
+       OM_uint32 major,minor;
+       OM_uint32 flags = 0; /* GSI needs this */
+       u_int len;
 
-        in.value = buffer_get_string(m,&in.length);
-        major=ssh_gssapi_accept_ctx(gsscontext,&in,&out,&flags);
-        xfree(in.value);
+       in.value = buffer_get_string(m, &len);
+       in.length = len;
+       major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags);
+       xfree(in.value);
 
-        buffer_clear(m);
-        buffer_put_int(m, major);
-        buffer_put_string(m, out.value, out.length);
-        buffer_put_int(m, flags);
-        mm_request_send(socket,MONITOR_ANS_GSSSTEP,m);
+       buffer_clear(m);
+       buffer_put_int(m, major);
+       buffer_put_string(m, out.value, out.length);
+       buffer_put_int(m, flags);
+       mm_request_send(socket, MONITOR_ANS_GSSSTEP, m);
 
-        gss_release_buffer(&minor, &out);
+       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_GSSSIGN,1);            
+               monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0);
+               monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);
+               monitor_permit(mon_dispatch, MONITOR_REQ_GSSSIGN, 1);
        }
-        return(0);
+       return (0);
 }
 
 int
-mm_answer_gss_userok(int socket, Buffer *m) {
+mm_answer_gss_userok(int socket, Buffer *m)
+{
        int authenticated;
 
-        authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user);
+       authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user);
 
-        buffer_clear(m);
-        buffer_put_int(m, authenticated);
+       buffer_clear(m);
+       buffer_put_int(m, authenticated);
 
-        debug3("%s: sending result %d", __func__, authenticated);
-        mm_request_send(socket, MONITOR_ANS_GSSUSEROK, m);
+       debug3("%s: sending result %d", __func__, authenticated);
+       mm_request_send(socket, MONITOR_ANS_GSSUSEROK, m);
 
-       /* XXX - auth method could also be 'external' */
        auth_method="gssapi";
-       
-        /* Monitor loop will terminate if authenticated */
-        return(authenticated);
+
+       /* Monitor loop will terminate if authenticated */
+       return (authenticated);
 }
 
 int
@@ -1894,30 +2004,3 @@ mm_answer_gss_localname(int socket, Buffer *m) {
         return(0);
 }
 #endif /* GSSAPI */
-
-#ifdef GSI
-
-int
-mm_answer_gsi_gridmap(int socket, Buffer *m) {
-    char *subject, *name;
-
-    subject = buffer_get_string(m, NULL);
-    
-    gsi_gridmap(subject, &name);
-
-    buffer_clear(m);
-    if (name) {
-       buffer_put_cstring(m, name);
-       debug3("%s: sending result %s", __func__, name);
-       xfree(name);
-    } else {
-       buffer_put_cstring(m, "");
-       debug3("%s: sending result \"\"", __func__);
-    }
-
-    mm_request_send(socket, MONITOR_ANS_GSIGRIDMAP, m);
-
-    return(0);
-}
-
-#endif /* GSI */
index 06ade4f269bf58ba39ce62fb1c4a46edfd4a88bc..ac538d08ce13beb31e3d5e8d3596d38d667739fd 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: monitor.h,v 1.8 2002/09/26 11:38:43 markus Exp $      */
+/*     $OpenBSD: monitor.h,v 1.11 2003/08/28 12:54:34 markus Exp $     */
 
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
@@ -39,16 +39,6 @@ enum monitor_reqtype {
        MONITOR_REQ_BSDAUTHRESPOND, MONITOR_ANS_BSDAUTHRESPOND,
        MONITOR_REQ_SKEYQUERY, MONITOR_ANS_SKEYQUERY,
        MONITOR_REQ_SKEYRESPOND, MONITOR_ANS_SKEYRESPOND,
-#ifdef GSSAPI
-       MONITOR_REQ_GSSSETUP,MONITOR_ANS_GSSSETUP,
-       MONITOR_REQ_GSSSTEP,MONITOR_ANS_GSSSTEP,
-       MONITOR_REQ_GSSSIGN,MONITOR_ANS_GSSSIGN,
-       MONITOR_REQ_GSSUSEROK,MONITOR_ANS_GSSUSEROK,
-       MONITOR_REQ_GSSMECHS,MONITOR_ANS_GSSMECHS,
-       MONITOR_REQ_GSSLOCALNAME,MONITOR_ANS_GSSLOCALNAME,
-       MONITOR_REQ_GSIGRIDMAP,MONITOR_ANS_GSIGRIDMAP,
-       MONITOR_REQ_GSSERR,MONITOR_ANS_GSSERR,
-#endif
        MONITOR_REQ_KEYALLOWED, MONITOR_ANS_KEYALLOWED,
        MONITOR_REQ_KEYVERIFY, MONITOR_ANS_KEYVERIFY,
        MONITOR_REQ_KEYEXPORT,
@@ -59,9 +49,20 @@ enum monitor_reqtype {
        MONITOR_REQ_RSAKEYALLOWED, MONITOR_ANS_RSAKEYALLOWED,
        MONITOR_REQ_RSACHALLENGE, MONITOR_ANS_RSACHALLENGE,
        MONITOR_REQ_RSARESPONSE, MONITOR_ANS_RSARESPONSE,
-       MONITOR_REQ_KRB4, MONITOR_ANS_KRB4,
-       MONITOR_REQ_KRB5, MONITOR_ANS_KRB5,
+       MONITOR_REQ_GSSSETUP, MONITOR_ANS_GSSSETUP,
+       MONITOR_REQ_GSSSTEP, MONITOR_ANS_GSSSTEP,
+       MONITOR_REQ_GSSUSEROK, MONITOR_ANS_GSSUSEROK,
+       MONITOR_REQ_GSSSIGN, MONITOR_ANS_GSSSIGN,
+       MONITOR_REQ_GSSMECHS, MONITOR_ANS_GSSMECHS,
+       MONITOR_REQ_GSSLOCALNAME, MONITOR_ANS_GSSLOCALNAME,
+       MONITOR_REQ_GSIGRIDMAP, MONITOR_ANS_GSIGRIDMAP,
+       MONITOR_REQ_GSSERR, MONITOR_ANS_GSSERR,
        MONITOR_REQ_PAM_START,
+       MONITOR_REQ_PAM_ACCOUNT, MONITOR_ANS_PAM_ACCOUNT,
+       MONITOR_REQ_PAM_INIT_CTX, MONITOR_ANS_PAM_INIT_CTX,
+       MONITOR_REQ_PAM_QUERY, MONITOR_ANS_PAM_QUERY,
+       MONITOR_REQ_PAM_RESPOND, MONITOR_ANS_PAM_RESPOND,
+       MONITOR_REQ_PAM_FREE_CTX, MONITOR_ANS_PAM_FREE_CTX,
        MONITOR_REQ_TERM
 };
 
index 641ce721ef514b0fe85b900df5944258977a2d67..22b7882bd729f963f0df3c84dcdc2f93f4876c93 100644 (file)
@@ -113,9 +113,11 @@ mm_receive_fd(int socket)
                fatal("%s: no fd", __func__);
 #else
        cmsg = CMSG_FIRSTHDR(&msg);
+#ifndef BROKEN_CMSG_TYPE
        if (cmsg->cmsg_type != SCM_RIGHTS)
                fatal("%s: expected type %d got %d", __func__,
                    SCM_RIGHTS, cmsg->cmsg_type);
+#endif
        fd = (*(int *)CMSG_DATA(cmsg));
 #endif
        return fd;
index b4a6e40c90bfa7bd3a8477e2edbfbb0b8899dbe3..e57c87cc2a0c9150bf87f78477fcc4a6d36d2fe2 100644 (file)
@@ -30,7 +30,6 @@ RCSID("$OpenBSD: monitor_mm.c,v 1.8 2002/08/02 14:43:15 millert Exp $");
 #include <sys/mman.h>
 #endif
 
-#include "openbsd-compat/xmmap.h"
 #include "ssh.h"
 #include "xmalloc.h"
 #include "log.h"
index 6c16863f606e6627747abb8c57d00a9d52f344cd..08bac5edf9142de73c98492bf37e149a02339a91 100644 (file)
@@ -25,7 +25,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: monitor_wrap.c,v 1.24 2003/04/01 10:22:21 markus Exp $");
+RCSID("$OpenBSD: monitor_wrap.c,v 1.31 2003/08/28 12:54:34 markus Exp $");
 
 #include <openssl/bn.h>
 #include <openssl/dh.h>
@@ -47,6 +47,7 @@ RCSID("$OpenBSD: monitor_wrap.c,v 1.24 2003/04/01 10:22:21 markus Exp $");
 #include "atomicio.h"
 #include "monitor_fdpass.h"
 #include "getput.h"
+#include "servconf.h"
 
 #include "auth.h"
 #include "channels.h"
@@ -63,6 +64,7 @@ extern z_stream incoming_stream;
 extern z_stream outgoing_stream;
 extern struct monitor *pmonitor;
 extern Buffer input, output;
+extern ServerOptions options;
 
 void
 mm_request_send(int socket, enum monitor_reqtype type, Buffer *m)
@@ -74,9 +76,9 @@ mm_request_send(int socket, enum monitor_reqtype type, Buffer *m)
 
        PUT_32BIT(buf, mlen + 1);
        buf[4] = (u_char) type;         /* 1st byte of payload is mesg-type */
-       if (atomicio(write, socket, buf, sizeof(buf)) != sizeof(buf))
+       if (atomicio(vwrite, socket, buf, sizeof(buf)) != sizeof(buf))
                fatal("%s: write", __func__);
-       if (atomicio(write, socket, buffer_ptr(m), mlen) != mlen)
+       if (atomicio(vwrite, socket, buffer_ptr(m), mlen) != mlen)
                fatal("%s: write", __func__);
 }
 
@@ -524,6 +526,8 @@ mm_send_keystate(struct monitor *pmonitor)
        Buffer m;
        u_char *blob, *p;
        u_int bloblen, plen;
+       u_int32_t seqnr, packets;
+       u_int64_t blocks;
 
        buffer_init(&m);
 
@@ -572,8 +576,14 @@ mm_send_keystate(struct monitor *pmonitor)
        buffer_put_string(&m, blob, bloblen);
        xfree(blob);
 
-       buffer_put_int(&m, packet_get_seqnr(MODE_OUT));
-       buffer_put_int(&m, packet_get_seqnr(MODE_IN));
+       packet_get_state(MODE_OUT, &seqnr, &blocks, &packets);
+       buffer_put_int(&m, seqnr);
+       buffer_put_int64(&m, blocks);
+       buffer_put_int(&m, packets);
+       packet_get_state(MODE_IN, &seqnr, &blocks, &packets);
+       buffer_put_int(&m, seqnr);
+       buffer_put_int64(&m, blocks);
+       buffer_put_int(&m, packets);
 
        debug3("%s: New keys have been sent", __func__);
  skip:
@@ -665,6 +675,8 @@ mm_start_pam(char *user)
        Buffer m;
 
        debug3("%s entering", __func__);
+       if (!options.use_pam)
+               fatal("UsePAM=no, but ended up in %s anyway", __func__);
 
        buffer_init(&m);
        buffer_put_cstring(&m, user);
@@ -673,6 +685,112 @@ mm_start_pam(char *user)
 
        buffer_free(&m);
 }
+
+u_int
+mm_do_pam_account(void)
+{
+       Buffer m;
+       u_int ret;
+
+       debug3("%s entering", __func__);
+       if (!options.use_pam)
+               fatal("UsePAM=no, but ended up in %s anyway", __func__);
+
+       buffer_init(&m);
+       mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_ACCOUNT, &m);
+
+       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);
+}
+
+void *
+mm_sshpam_init_ctx(Authctxt *authctxt)
+{
+       Buffer m;
+       int success;
+
+       debug3("%s", __func__);
+       buffer_init(&m);
+       buffer_put_cstring(&m, authctxt->user);
+       mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_INIT_CTX, &m);
+       debug3("%s: waiting for MONITOR_ANS_PAM_INIT_CTX", __func__);
+       mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_INIT_CTX, &m);
+       success = buffer_get_int(&m);
+       if (success == 0) {
+               debug3("%s: pam_init_ctx failed", __func__);
+               buffer_free(&m);
+               return (NULL);
+       }
+       buffer_free(&m);
+       return (authctxt);
+}
+
+int
+mm_sshpam_query(void *ctx, char **name, char **info,
+    u_int *num, char ***prompts, u_int **echo_on)
+{
+       Buffer m;
+       int i, ret;
+
+       debug3("%s", __func__);
+       buffer_init(&m);
+       mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_QUERY, &m);
+       debug3("%s: waiting for MONITOR_ANS_PAM_QUERY", __func__);
+       mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_QUERY, &m);
+       ret = buffer_get_int(&m);
+       debug3("%s: pam_query returned %d", __func__, ret);
+       *name = buffer_get_string(&m, NULL);
+       *info = buffer_get_string(&m, NULL);
+       *num = buffer_get_int(&m);
+       *prompts = xmalloc((*num + 1) * sizeof(char *));
+       *echo_on = xmalloc((*num + 1) * sizeof(u_int));
+       for (i = 0; i < *num; ++i) {
+               (*prompts)[i] = buffer_get_string(&m, NULL);
+               (*echo_on)[i] = buffer_get_int(&m);
+       }
+       buffer_free(&m);
+       return (ret);
+}
+
+int
+mm_sshpam_respond(void *ctx, u_int num, char **resp)
+{
+       Buffer m;
+       int i, ret;
+
+       debug3("%s", __func__);
+       buffer_init(&m);
+       buffer_put_int(&m, num);
+       for (i = 0; i < num; ++i)
+               buffer_put_cstring(&m, resp[i]);
+       mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_RESPOND, &m);
+       debug3("%s: waiting for MONITOR_ANS_PAM_RESPOND", __func__);
+       mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_RESPOND, &m);
+       ret = buffer_get_int(&m);
+       debug3("%s: pam_respond returned %d", __func__, ret);
+       buffer_free(&m);
+       return (ret);
+}
+
+void
+mm_sshpam_free_ctx(void *ctxtp)
+{
+       Buffer m;
+
+       debug3("%s", __func__);
+       buffer_init(&m);
+       mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_FREE_CTX, &m);
+       debug3("%s: waiting for MONITOR_ANS_PAM_FREE_CTX", __func__);
+       mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_FREE_CTX, &m);
+       buffer_free(&m);
+}
 #endif /* USE_PAM */
 
 /* Request process termination */
@@ -953,135 +1071,70 @@ mm_auth_rsa_verify_response(Key *key, BIGNUM *p, u_char response[16])
        return (success);
 }
 
-#ifdef KRB4
-int
-mm_auth_krb4(Authctxt *authctxt, void *_auth, char **client, void *_reply)
+#ifdef GSSAPI
+OM_uint32
+mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid)
 {
-       KTEXT auth, reply;
-       Buffer m;
-       u_int rlen;
-       int success = 0;
-       char *p;
+       Buffer m;
+       OM_uint32 major;
 
-       debug3("%s entering", __func__);
-       auth = _auth;
-       reply = _reply;
+       /* Client doesn't get to see the context */
+       *ctx = NULL;
 
        buffer_init(&m);
-       buffer_put_string(&m, auth->dat, auth->length);
+       buffer_put_string(&m, oid->elements, oid->length);
 
-       mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KRB4, &m);
-       mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KRB4, &m);
+       mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSETUP, &m);
+       mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSETUP, &m);
+
+       major = buffer_get_int(&m);
 
-       success = buffer_get_int(&m);
-       if (success) {
-               *client = buffer_get_string(&m, NULL);
-               p = buffer_get_string(&m, &rlen);
-               if (rlen >= MAX_KTXT_LEN)
-                       fatal("%s: reply from monitor too large", __func__);
-               reply->length = rlen;
-               memcpy(reply->dat, p, rlen);
-               memset(p, 0, rlen);
-               xfree(p);
-       }
        buffer_free(&m);
-       return (success);
+       return (major);
 }
-#endif
 
-#ifdef KRB5
-int
-mm_auth_krb5(void *ctx, void *argp, char **userp, void *resp)
+OM_uint32
+mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in,
+    gss_buffer_desc *out, OM_uint32 *flags)
 {
-       krb5_data *tkt, *reply;
        Buffer m;
-       int success;
-
-       debug3("%s entering", __func__);
-       tkt = (krb5_data *) argp;
-       reply = (krb5_data *) resp;
+       OM_uint32 major;
+       u_int len;
 
        buffer_init(&m);
-       buffer_put_string(&m, tkt->data, tkt->length);
-
-       mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KRB5, &m);
-       mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KRB5, &m);
+       buffer_put_string(&m, in->value, in->length);
 
-       success = buffer_get_int(&m);
-       if (success) {
-               u_int len;
+       mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSTEP, &m);
+       mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSTEP, &m);
 
-               *userp = buffer_get_string(&m, NULL);
-               reply->data = buffer_get_string(&m, &len);
-               reply->length = len;
-       } else {
-               memset(reply, 0, sizeof(*reply));
-               *userp = NULL;
-       }
+       major = buffer_get_int(&m);
+       out->value = buffer_get_string(&m, &len);
+       out->length = len;
+       if (flags)
+               *flags = buffer_get_int(&m);
 
        buffer_free(&m);
-       return (success);
-}
-#endif
-#ifdef GSSAPI
-OM_uint32
-mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) {
-        Buffer m;
-        OM_uint32 major;
-                
-        /* Client doesn't get to see the context */
-        *ctx=NULL;
-
-        buffer_init(&m);
-        buffer_put_string(&m,oid->elements,oid->length);
-
-        mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSETUP, &m);
-        mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSETUP, &m);
-
-        major=buffer_get_int(&m);
 
-       buffer_free(&m);
-        return(major);
+       return (major);
 }
 
-OM_uint32
-mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in,
-                         gss_buffer_desc *out, OM_uint32 *flags) {
-        Buffer m;
-        OM_uint32 major;
+int
+mm_ssh_gssapi_userok(char *user)
+{
+       Buffer m;
+       int authenticated = 0;
 
-        buffer_init(&m);
-        buffer_put_string(&m, in->value, in->length);
+       buffer_init(&m);
 
-        mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSTEP, &m);
-        mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSTEP, &m);
+       mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, &m);
+       mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUSEROK,
+                                 &m);
 
-        major=buffer_get_int(&m);
-        out->value=buffer_get_string(&m,&out->length);
-        if (flags) *flags=buffer_get_int(&m);
+       authenticated = buffer_get_int(&m);
 
        buffer_free(&m);
-       
-        return(major);
-}
-
-int
-mm_ssh_gssapi_userok(char *user) {
-        Buffer m;
-        int authenticated = 0;
-
-        buffer_init(&m);
-        
-        mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, &m);
-        mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUSEROK,
-                                  &m);
-
-        authenticated = buffer_get_int(&m);
-
-        buffer_free(&m);
-        debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not ");
-        return(authenticated);
+       debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not ");
+       return (authenticated);
 }
 
 OM_uint32
@@ -1182,7 +1235,6 @@ mm_ssh_gssapi_localname(char **lname)
 #endif /* GSSAPI */
 
 #ifdef GSI
-
 int mm_gsi_gridmap(char *subject_name, char **lname)
 {
         Buffer m;
index 91e94d3549081a265274f86b1885f915f0eeed62..59aedbf810880c7a92b31513871a451fc4189257 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: monitor_wrap.h,v 1.8 2002/09/26 11:38:43 markus Exp $ */
+/*     $OpenBSD: monitor_wrap.h,v 1.11 2003/08/28 12:54:34 markus Exp $        */
 
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
@@ -55,8 +55,21 @@ int mm_auth_rsa_key_allowed(struct passwd *, BIGNUM *, Key **);
 int mm_auth_rsa_verify_response(Key *, BIGNUM *, u_char *);
 BIGNUM *mm_auth_rsa_generate_challenge(Key *);
 
+#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);
+int mm_ssh_gssapi_userok(char *user);
+#endif
+
 #ifdef USE_PAM
 void mm_start_pam(char *);
+u_int mm_do_pam_account(void);
+void *mm_sshpam_init_ctx(struct Authctxt *);
+int mm_sshpam_query(void *, char **, char **, u_int *, char ***, u_int **);
+int mm_sshpam_respond(void *, u_int, char **);
+void mm_sshpam_free_ctx(void *);
 #endif
 
 #ifdef GSSAPI
@@ -102,16 +115,6 @@ int mm_bsdauth_respond(void *, u_int, char **);
 int mm_skey_query(void *, char **, char **, u_int *, char ***, u_int **);
 int mm_skey_respond(void *, u_int, char **);
 
-/* auth_krb */
-#ifdef KRB4
-int mm_auth_krb4(struct Authctxt *, void *, char **, void *);
-#endif
-#ifdef KRB5
-/* auth and reply are really krb5_data objects, but we don't want to
- * include all of the krb5 headers here */
-int mm_auth_krb5(void *authctxt, void *auth, char **client, void *reply);
-#endif
-
 /* zlib allocation hooks */
 
 void *mm_zalloc(struct mm_master *, u_int, u_int);
index 5d266c207e57f5970e5f40d8f3135c3d2b50fbda..6a806c3f5a1fec68d9a8a25bec8fe00b4cd2cf92 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.5 2002/12/19 00:07:02 djm Exp $");
+RCSID("$OpenBSD: msg.c,v 1.6 2003/06/28 16:23:06 deraadt Exp $");
 
 #include "buffer.h"
 #include "getput.h"
@@ -40,9 +40,9 @@ 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(write, fd, buf, sizeof(buf)) != sizeof(buf))
+       if (atomicio(vwrite, fd, buf, sizeof(buf)) != sizeof(buf))
                fatal("ssh_msg_send: write");
-       if (atomicio(write, fd, buffer_ptr(m), mlen) != mlen)
+       if (atomicio(vwrite, fd, buffer_ptr(m), mlen) != mlen)
                fatal("ssh_msg_send: write");
 }
 
index 5a3823bc5153f131d218a31c746d3abe6dfdcfed..2054c806891b21d54464de4560085d069e29733a 100644 (file)
@@ -1,37 +1,26 @@
-/*     $OpenBSD: basename.c,v 1.8 2002/06/09 05:03:59 deraadt Exp $    */
+/*     $OpenBSD: basename.c,v 1.11 2003/06/17 21:56:23 millert Exp $   */
 
 /*
  * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
- * 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.
- * 3. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
+ * 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 ``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"
 
-#if !defined(HAVE_BASENAME)
+#include "includes.h"
+#ifndef HAVE_BASENAME
 
 #ifndef lint
-static char rcsid[] = "$OpenBSD: basename.c,v 1.8 2002/06/09 05:03:59 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: basename.c,v 1.11 2003/06/17 21:56:23 millert Exp $";
 #endif /* not lint */
 
 char *
diff --git a/openssh/openbsd-compat/basename.h b/openssh/openbsd-compat/basename.h
deleted file mode 100644 (file)
index 4909933..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-/* $Id$ */
-
-#ifndef _BASENAME_H 
-#define _BASENAME_H
-#include "config.h"
-
-#if !defined(HAVE_BASENAME)
-
-char *basename(const char *path);
-
-#endif /* !defined(HAVE_BASENAME) */
-#endif /* _BASENAME_H */
diff --git a/openssh/openbsd-compat/bindresvport.h b/openssh/openbsd-compat/bindresvport.h
deleted file mode 100644 (file)
index b56afd3..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-/* $Id$ */
-
-#ifndef _BSD_BINDRESVPORT_H
-#define _BSD_BINDRESVPORT_H
-
-#include "config.h"
-
-#ifndef HAVE_BINDRESVPORT_SA
-int bindresvport_sa(int sd, struct sockaddr *sa);
-#endif /* !HAVE_BINDRESVPORT_SA */
-
-#endif /* _BSD_BINDRESVPORT_H */
diff --git a/openssh/openbsd-compat/bsd-arc4random.h b/openssh/openbsd-compat/bsd-arc4random.h
deleted file mode 100644 (file)
index 3e913c3..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 1999-2000 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.
- */
-
-/* $Id$ */
-
-#ifndef _BSD_ARC4RANDOM_H
-#define _BSD_ARC4RANDOM_H
-
-#include "config.h"
-
-#ifndef HAVE_ARC4RANDOM
-unsigned int arc4random(void);
-void arc4random_stir(void);
-#endif /* !HAVE_ARC4RANDOM */
-
-#endif /* _BSD_ARC4RANDOM_H */
diff --git a/openssh/openbsd-compat/bsd-getpeereid.h b/openssh/openbsd-compat/bsd-getpeereid.h
deleted file mode 100644 (file)
index dec841b..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-/* $Id$ */
-
-#ifndef _BSD_GETPEEREID_H
-#define _BSD_GETPEEREID_H
-
-#include "config.h"
-
-#include <sys/types.h> /* For uid_t, gid_t */
-
-#ifndef HAVE_GETPEEREID
-int     getpeereid(int , uid_t *, gid_t *);
-#endif /* HAVE_GETPEEREID */
-
-#endif /* _BSD_GETPEEREID_H */
index 124cb7bcf9ab64f0680c11957b796d4b0c464d13..5f035d77c5f04252dc6469544d9a113002f480cb 100644 (file)
@@ -1,5 +1,7 @@
+/* $Id$ */
+
 /*
- * Copyright (c) 1999-2000 Damien Miller.  All rights reserved.
+ * Copyright (c) 1999-2003 Damien Miller.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/* $Id$ */
-
 #ifndef _BSD_MISC_H
 #define _BSD_MISC_H
 
-#include "config.h"
+#include "includes.h"
 
-#define get_progname bsd_get_progname
-char *get_progname(char *argv0);
+char *ssh_get_progname(char *);
 
 #ifndef HAVE_SETSID
 #define setsid() setpgrp(0, getpid())
 #endif /* !HAVE_SETSID */
 
 #ifndef HAVE_SETENV
-int setenv(const char *name, const char *value, int overwrite);
+int setenv(const char *, const char *, int);
 #endif /* !HAVE_SETENV */
 
 #ifndef HAVE_SETLOGIN
-int setlogin(const char *name);
+int setlogin(const char *);
 #endif /* !HAVE_SETLOGIN */
 
 #ifndef HAVE_INNETGR
-int innetgr(const char *netgroup, const char *host, 
-            const char *user, const char *domain);
+int innetgr(const char *, const char *, const char *, const char *);
 #endif /* HAVE_INNETGR */
 
 #if !defined(HAVE_SETEUID) && defined(HAVE_SETREUID)
-int seteuid(uid_t euid);
+int seteuid(uid_t);
 #endif /* !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) */
 
 #if !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID)
-int setegid(uid_t egid);
+int setegid(uid_t);
 #endif /* !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) */
 
 #if !defined(HAVE_STRERROR) && defined(HAVE_SYS_ERRLIST) && defined(HAVE_SYS_NERR)
-const char *strerror(int e);
+const char *strerror(int);
 #endif 
 
 
@@ -70,15 +68,15 @@ struct timeval {
 }
 #endif /* HAVE_STRUCT_TIMEVAL */
 
-int utimes(char *filename, struct timeval *tvp);
+int utimes(char *, struct timeval *);
 #endif /* HAVE_UTIMES */
 
 #ifndef HAVE_TRUNCATE
-int truncate (const char *path, off_t length);
+int truncate (const char *, off_t);
 #endif /* HAVE_TRUNCATE */
 
 #if !defined(HAVE_SETGROUPS) && defined(SETGROUPS_NOOP)
-int setgroups(size_t size, const gid_t *list);
+int setgroups(size_t, const gid_t *);
 #endif
 
 #if !defined(HAVE_NANOSLEEP) && !defined(HAVE_NSLEEP)
@@ -88,7 +86,21 @@ struct timespec {
        long    tv_nsec;
 };
 #endif
-int nanosleep(const struct timespec *req, struct timespec *rem);
+int nanosleep(const struct timespec *, struct timespec *);
+#endif
+
+#ifndef HAVE_TCGETPGRP
+pid_t tcgetpgrp(int);
+#endif
+
+#ifndef HAVE_TCSENDBREAK
+int tcsendbreak(int, int);
 #endif
 
+/* wrapper for signal interface */
+typedef void (*mysig_t)(int);
+mysig_t mysignal(int sig, mysig_t act);
+
+#define signal(a,b) mysignal(a,b)
+
 #endif /* _BSD_MISC_H */
diff --git a/openssh/openbsd-compat/bsd-snprintf.h b/openssh/openbsd-compat/bsd-snprintf.h
deleted file mode 100644 (file)
index ce5a1f4..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/* $Id$ */
-
-#ifndef _BSD_SNPRINTF_H
-#define _BSD_SNPRINTF_H
-
-#include "config.h"
-
-#include <sys/types.h> /* For size_t */
-
-#ifndef HAVE_SNPRINTF
-int snprintf(char *str, size_t count, const char *fmt, ...);
-#endif /* !HAVE_SNPRINTF */
-
-#ifndef HAVE_VSNPRINTF
-int vsnprintf(char *str, size_t count, const char *fmt, va_list args);
-#endif /* !HAVE_SNPRINTF */
-
-
-#endif /* _BSD_SNPRINTF_H */
diff --git a/openssh/openbsd-compat/daemon.h b/openssh/openbsd-compat/daemon.h
deleted file mode 100644 (file)
index 241867f..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-/* $Id$ */
-
-#ifndef _BSD_DAEMON_H
-#define _BSD_DAEMON_H
-
-#include "config.h"
-#ifndef HAVE_DAEMON
-int daemon(int nochdir, int noclose);
-#endif /* !HAVE_DAEMON */
-
-#endif /* _BSD_DAEMON_H */
diff --git a/openssh/openbsd-compat/dirname.h b/openssh/openbsd-compat/dirname.h
deleted file mode 100644 (file)
index 1d61dd0..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-#ifndef HAVE_DIRNAME
-
-char *dirname(const char *path);
-
-#endif
diff --git a/openssh/openbsd-compat/fake-gai-errnos.h b/openssh/openbsd-compat/fake-gai-errnos.h
deleted file mode 100644 (file)
index af51a1c..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * fake library for ssh
- *
- * This file is included in getaddrinfo.c and getnameinfo.c.
- * See getaddrinfo.c and getnameinfo.c.
- */
-
-/* $Id$ */
-
-/* for old netdb.h */
-#ifndef EAI_NODATA
-#define EAI_NODATA     1
-#define EAI_MEMORY     2
-#endif
diff --git a/openssh/openbsd-compat/fake-getaddrinfo.c b/openssh/openbsd-compat/fake-getaddrinfo.c
deleted file mode 100644 (file)
index 5a1ad97..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * fake library for ssh
- *
- * This file includes getaddrinfo(), freeaddrinfo() and gai_strerror().
- * These funtions are defined in rfc2133.
- *
- * But these functions are not implemented correctly. The minimum subset
- * is implemented for ssh use only. For exapmle, this routine assumes
- * that ai_family is AF_INET. Don't use it for another purpose.
- */
-
-#include "includes.h"
-#include "ssh.h"
-
-RCSID("$Id$");
-
-#ifndef HAVE_GAI_STRERROR
-char *gai_strerror(int ecode)
-{
-       switch (ecode) {
-               case EAI_NODATA:
-                       return "no address associated with hostname.";
-               case EAI_MEMORY:
-                       return "memory allocation failure.";
-               default:
-                       return "unknown error.";
-       }
-}    
-#endif /* !HAVE_GAI_STRERROR */
-
-#ifndef HAVE_FREEADDRINFO
-void freeaddrinfo(struct addrinfo *ai)
-{
-       struct addrinfo *next;
-
-       do {
-               next = ai->ai_next;
-               free(ai);
-       } while (NULL != (ai = next));
-}
-#endif /* !HAVE_FREEADDRINFO */
-
-#ifndef HAVE_GETADDRINFO
-static struct addrinfo *malloc_ai(int port, u_long addr)
-{
-       struct addrinfo *ai;
-
-       ai = malloc(sizeof(struct addrinfo) + sizeof(struct sockaddr_in));
-       if (ai == NULL)
-               return(NULL);
-       
-       memset(ai, 0, sizeof(struct addrinfo) + sizeof(struct sockaddr_in));
-       
-       ai->ai_addr = (struct sockaddr *)(ai + 1);
-       /* XXX -- ssh doesn't use sa_len */
-       ai->ai_addrlen = sizeof(struct sockaddr_in);
-       ai->ai_addr->sa_family = ai->ai_family = AF_INET;
-
-       ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port;
-       ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr;
-       
-       return(ai);
-}
-
-int getaddrinfo(const char *hostname, const char *servname, 
-                const struct addrinfo *hints, struct addrinfo **res)
-{
-       struct addrinfo *cur, *prev = NULL;
-       struct hostent *hp;
-       struct in_addr in;
-       int i, port;
-
-       if (servname)
-               port = htons(atoi(servname));
-       else
-               port = 0;
-
-       if (hints && hints->ai_flags & AI_PASSIVE) {
-               if (NULL != (*res = malloc_ai(port, htonl(0x00000000))))
-                       return 0;
-               else
-                       return EAI_MEMORY;
-       }
-               
-       if (!hostname) {
-               if (NULL != (*res = malloc_ai(port, htonl(0x7f000001))))
-                       return 0;
-               else
-                       return EAI_MEMORY;
-       }
-       
-       if (inet_aton(hostname, &in)) {
-               if (NULL != (*res = malloc_ai(port, in.s_addr)))
-                       return 0;
-               else
-                       return EAI_MEMORY;
-       }
-       
-       hp = gethostbyname(hostname);
-       if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) {
-               for (i = 0; hp->h_addr_list[i]; i++) {
-                       cur = malloc_ai(port, ((struct in_addr *)hp->h_addr_list[i])->s_addr);
-                       if (cur == NULL) {
-                               if (*res)
-                                       freeaddrinfo(*res);
-                               return EAI_MEMORY;
-                       }
-                       
-                       if (prev)
-                               prev->ai_next = cur;
-                       else
-                               *res = cur;
-
-                       prev = cur;
-               }
-               return 0;
-       }
-       
-       return EAI_NODATA;
-}
-#endif /* !HAVE_GETADDRINFO */
diff --git a/openssh/openbsd-compat/fake-getaddrinfo.h b/openssh/openbsd-compat/fake-getaddrinfo.h
deleted file mode 100644 (file)
index ba5e3fe..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/* $Id$ */
-
-#ifndef _FAKE_GETADDRINFO_H
-#define _FAKE_GETADDRINFO_H
-
-#include "config.h"
-
-#include "fake-gai-errnos.h"
-
-#ifndef AI_PASSIVE
-# define AI_PASSIVE        1
-# define AI_CANONNAME      2
-#endif
-
-#ifndef NI_NUMERICHOST
-# define NI_NUMERICHOST    2
-# define NI_NAMEREQD       4
-# define NI_NUMERICSERV    8
-#endif
-
-#ifndef HAVE_STRUCT_ADDRINFO
-struct addrinfo {
-       int     ai_flags;       /* AI_PASSIVE, AI_CANONNAME */
-       int     ai_family;      /* PF_xxx */
-       int     ai_socktype;    /* SOCK_xxx */
-       int     ai_protocol;    /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
-       size_t  ai_addrlen;     /* length of ai_addr */
-       char    *ai_canonname;  /* canonical name for hostname */
-       struct sockaddr *ai_addr;       /* binary address */
-       struct addrinfo *ai_next;       /* next structure in linked list */
-};
-#endif /* !HAVE_STRUCT_ADDRINFO */
-
-#ifndef HAVE_GETADDRINFO
-int getaddrinfo(const char *hostname, const char *servname, 
-                const struct addrinfo *hints, struct addrinfo **res);
-#endif /* !HAVE_GETADDRINFO */
-
-#ifndef HAVE_GAI_STRERROR
-char *gai_strerror(int ecode);
-#endif /* !HAVE_GAI_STRERROR */
-
-#ifndef HAVE_FREEADDRINFO
-void freeaddrinfo(struct addrinfo *ai);
-#endif /* !HAVE_FREEADDRINFO */
-
-#endif /* _FAKE_GETADDRINFO_H */
diff --git a/openssh/openbsd-compat/fake-getnameinfo.c b/openssh/openbsd-compat/fake-getnameinfo.c
deleted file mode 100644 (file)
index 8f6f19e..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * fake library for ssh
- *
- * This file includes getnameinfo().
- * These funtions are defined in rfc2133.
- *
- * But these functions are not implemented correctly. The minimum subset
- * is implemented for ssh use only. For exapmle, this routine assumes
- * that ai_family is AF_INET. Don't use it for another purpose.
- */
-
-#include "includes.h"
-#include "ssh.h"
-
-RCSID("$Id$");
-
-#ifndef HAVE_GETNAMEINFO
-int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, 
-                size_t hostlen, char *serv, size_t servlen, int flags)
-{
-       struct sockaddr_in *sin = (struct sockaddr_in *)sa;
-       struct hostent *hp;
-       char tmpserv[16];
-
-       if (serv) {
-               snprintf(tmpserv, sizeof(tmpserv), "%d", ntohs(sin->sin_port));
-               if (strlen(tmpserv) >= servlen)
-                       return EAI_MEMORY;
-               else
-                       strcpy(serv, tmpserv);
-       }
-
-       if (host) {
-               if (flags & NI_NUMERICHOST) {
-                       if (strlen(inet_ntoa(sin->sin_addr)) >= hostlen)
-                               return EAI_MEMORY;
-
-                       strcpy(host, inet_ntoa(sin->sin_addr));
-                       return 0;
-               } else {
-                       hp = gethostbyaddr((char *)&sin->sin_addr, 
-                               sizeof(struct in_addr), AF_INET);
-                       if (hp == NULL)
-                               return EAI_NODATA;
-                       
-                       if (strlen(hp->h_name) >= hostlen)
-                               return EAI_MEMORY;
-
-                       strcpy(host, hp->h_name);
-                       return 0;
-               }
-       }
-       return 0;
-}
-#endif /* !HAVE_GETNAMEINFO */
diff --git a/openssh/openbsd-compat/fake-getnameinfo.h b/openssh/openbsd-compat/fake-getnameinfo.h
deleted file mode 100644 (file)
index b91c791..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/* $Id$ */
-
-#ifndef _FAKE_GETNAMEINFO_H
-#define _FAKE_GETNAMEINFO_H
-
-#include "config.h"
-
-#ifndef HAVE_GETNAMEINFO
-int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, 
-                size_t hostlen, char *serv, size_t servlen, int flags);
-#endif /* !HAVE_GETNAMEINFO */
-
-#ifndef NI_MAXSERV
-# define NI_MAXSERV 32
-#endif /* !NI_MAXSERV */
-#ifndef NI_MAXHOST
-# define NI_MAXHOST 1025
-#endif /* !NI_MAXHOST */
-
-#endif /* _FAKE_GETNAMEINFO_H */
diff --git a/openssh/openbsd-compat/fake-socket.h b/openssh/openbsd-compat/fake-socket.h
deleted file mode 100644 (file)
index 79f8ed4..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/* $Id$ */
-
-#ifndef _FAKE_SOCKET_H
-#define _FAKE_SOCKET_H
-
-#include "config.h"
-#include "sys/types.h"
-
-#ifndef HAVE_STRUCT_SOCKADDR_STORAGE
-# define       _SS_MAXSIZE     128     /* Implementation specific max size */
-# define       _SS_PADSIZE     (_SS_MAXSIZE - sizeof (struct sockaddr))
-
-struct sockaddr_storage {
-       struct  sockaddr ss_sa;
-       char            __ss_pad2[_SS_PADSIZE];
-};
-# define ss_family ss_sa.sa_family
-#endif /* !HAVE_STRUCT_SOCKADDR_STORAGE */
-
-#ifndef IN6_IS_ADDR_LOOPBACK
-# define IN6_IS_ADDR_LOOPBACK(a) \
-       (((u_int32_t *) (a))[0] == 0 && ((u_int32_t *) (a))[1] == 0 && \
-        ((u_int32_t *) (a))[2] == 0 && ((u_int32_t *) (a))[3] == htonl (1))
-#endif /* !IN6_IS_ADDR_LOOPBACK */
-
-#ifndef HAVE_STRUCT_IN6_ADDR
-struct in6_addr {
-       u_int8_t                s6_addr[16];
-};
-#endif /* !HAVE_STRUCT_IN6_ADDR */
-
-#ifndef HAVE_STRUCT_SOCKADDR_IN6
-struct sockaddr_in6 {
-   unsigned short sin6_family;
-       u_int16_t sin6_port;
-       u_int32_t sin6_flowinfo;
-       struct in6_addr sin6_addr;
-};
-#endif /* !HAVE_STRUCT_SOCKADDR_IN6 */
-
-#ifndef AF_INET6
-/* Define it to something that should never appear */
-#define AF_INET6 AF_MAX
-#endif
-
-#endif /* !_FAKE_SOCKET_H */
-
diff --git a/openssh/openbsd-compat/getcwd.h b/openssh/openbsd-compat/getcwd.h
deleted file mode 100644 (file)
index bb41770..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-/* $Id$ */
-
-#ifndef _BSD_GETCWD_H 
-#define _BSD_GETCWD_H
-#include "config.h"
-
-#if !defined(HAVE_GETCWD)
-
-char *getcwd(char *pt, size_t size);
-
-#endif /* !defined(HAVE_GETCWD) */
-#endif /* _BSD_GETCWD_H */
diff --git a/openssh/openbsd-compat/getgrouplist.h b/openssh/openbsd-compat/getgrouplist.h
deleted file mode 100644 (file)
index 210dd41..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-/* $Id$ */
-
-#ifndef _BSD_GETGROUPLIST_H
-#define _BSD_GETGROUPLIST_H
-
-#include "config.h"
-
-#ifndef HAVE_GETGROUPLIST
-
-#include <grp.h>
-
-int getgrouplist(const char *, gid_t, gid_t *, int *);
-
-#endif
-
-#endif
index a3fe807ee402df0ce68dfc9af6b00529585ecc75..2136fbfcca609f85dd886815a401fd5e20f7eba9 100644 (file)
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -35,7 +31,7 @@
 #if !defined(HAVE_GETOPT) || !defined(HAVE_GETOPT_OPTRESET)
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static char *rcsid = "$OpenBSD: getopt.c,v 1.4 2002/12/08 22:57:14 millert Exp $";
+static char *rcsid = "$OpenBSD: getopt.c,v 1.5 2003/06/02 20:18:37 millert Exp $";
 #endif /* LIBC_SCCS and not lint */
 
 #include <stdio.h>
diff --git a/openssh/openbsd-compat/getopt.h b/openssh/openbsd-compat/getopt.h
deleted file mode 100644 (file)
index 3f0f163..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-/* $Id$ */
-
-#ifndef _BSDGETOPT_H
-#define _BSDGETOPT_H
-
-#include "config.h"
-
-#if !defined(HAVE_GETOPT) || !defined(HAVE_GETOPT_OPTRESET)
-
-int BSDgetopt(int argc, char * const *argv, const char *opts);
-
-#endif
-
-#endif /* _BSDGETOPT_H */
diff --git a/openssh/openbsd-compat/inet_aton.h b/openssh/openbsd-compat/inet_aton.h
deleted file mode 100644 (file)
index 4e4b9ac..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-/* $Id$ */
-
-#ifndef _BSD_INET_ATON_H
-#define _BSD_INET_ATON_H
-
-#include "config.h"
-
-#ifndef HAVE_INET_ATON
-int inet_aton(const char *cp, struct in_addr *addr);
-#endif /* HAVE_INET_ATON */
-
-#endif /* _BSD_INET_ATON_H */
diff --git a/openssh/openbsd-compat/inet_ntoa.h b/openssh/openbsd-compat/inet_ntoa.h
deleted file mode 100644 (file)
index c3a6bb9..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-/* $Id$ */
-
-#ifndef _BSD_INET_NTOA_H
-#define _BSD_INET_NTOA_H
-
-#include "config.h"
-
-#if defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA)
-char *inet_ntoa(struct in_addr in);
-#endif /* defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA) */
-
-#endif /* _BSD_INET_NTOA_H */
diff --git a/openssh/openbsd-compat/inet_ntop.h b/openssh/openbsd-compat/inet_ntop.h
deleted file mode 100644 (file)
index dc0eb99..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-/* $Id$ */
-
-#ifndef _BSD_INET_NTOP_H
-#define _BSD_INET_NTOP_H
-
-#include "config.h"
-
-#ifndef HAVE_INET_NTOP
-const char *                 
-inet_ntop(int af, const void *src, char *dst, size_t size);
-#endif /* !HAVE_INET_NTOP */
-
-#endif /* _BSD_INET_NTOP_H */
diff --git a/openssh/openbsd-compat/mktemp.h b/openssh/openbsd-compat/mktemp.h
deleted file mode 100644 (file)
index f799387..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-/* $Id$ */
-
-#ifndef _BSD_MKTEMP_H
-#define _BSD_MKTEMP_H
-
-#include "config.h"
-#ifndef HAVE_MKDTEMP
-int mkstemps(char *path, int slen);
-int mkstemp(char *path);
-char *mkdtemp(char *path);
-#endif /* !HAVE_MKDTEMP */
-
-#endif /* _BSD_MKTEMP_H */
index 4c96a3171b90caa1f9b10c3a766768431442ad4f..7a981634b1d236ff4fb67e256c0355664aeb8b52 100644 (file)
  *
  */
 #include "includes.h"
+#include "ssh.h"
+#include "log.h"
+#include "servconf.h"
 
 #ifdef _AIX
 
 #include <uinfo.h>
 #include <../xmalloc.h>
+#include "port-aix.h"
+
+extern ServerOptions options;
 
 /*
  * AIX has a "usrinfo" area where logname and other stuff is stored - 
@@ -41,16 +47,95 @@ void
 aix_usrinfo(struct passwd *pw)
 {
        u_int i;
+       size_t len;
        char *cp;
 
-       cp = xmalloc(16 + 2 * strlen(pw->pw_name));
-       i = sprintf(cp, "LOGNAME=%s%cNAME=%s%c", pw->pw_name, 0, 
-           pw->pw_name, 0);
+       len = sizeof("LOGNAME= NAME= ") + (2 * strlen(pw->pw_name));
+       cp = xmalloc(len);
+
+       i = snprintf(cp, len, "LOGNAME=%s%cNAME=%s%c", pw->pw_name, '\0', 
+           pw->pw_name, '\0');
        if (usrinfo(SETUINFO, cp, i) == -1)
                fatal("Couldn't set usrinfo: %s", strerror(errno));
        debug3("AIX/UsrInfo: set len %d", i);
+
        xfree(cp);
 }
 
+#ifdef WITH_AIXAUTHENTICATE
+/*
+ * Remove embedded newlines in string (if any).
+ * Used before logging messages returned by AIX authentication functions
+ * so the message is logged on one line.
+ */
+void
+aix_remove_embedded_newlines(char *p)
+{
+       if (p == NULL)
+               return;
+
+       for (; *p; p++) {
+               if (*p == '\n')
+                       *p = ' ';
+       }
+       /* Remove trailing whitespace */
+       if (*--p == ' ')
+               *p = '\0';
+}
+#endif /* WITH_AIXAUTHENTICATE */
+  
+# 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);
+
+       if (geteuid() != 0)
+               return;
+
+       aix_setauthdb(user);
+#  ifdef AIX_LOGINFAILED_4ARG
+       loginfailed((char *)user, hostname, (char *)ttyname, AUDIT_FAIL_AUTH);
+#  else
+       loginfailed((char *)user, hostname, (char *)ttyname);
+#  endif
+}
+
+/*
+ * 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.
+ */
+void
+aix_setauthdb(const char *user)
+{
+#  ifdef HAVE_SETAUTHDB
+       static char *registry = NULL;
+
+       if (registry != NULL)   /* have already done setauthdb */
+               return;
+
+       if (setuserdb(S_READ) == -1) {
+               debug3("%s: Could not open userdb to read", __func__);
+               return;
+       }
+       
+       if (getuserattr((char *)user, S_REGISTRY, &registry, SEC_CHAR) == 0) {
+               if (setauthdb(registry, NULL) == 0)
+                       debug3("%s: AIX/setauthdb set registry %s", __func__,
+                           registry);
+               else 
+                       debug3("%s: AIX/setauthdb set registry %s failed: %s",
+                           __func__, registry, strerror(errno));
+       } else
+               debug3("%s: Could not read S_REGISTRY for user: %s", __func__,
+                   strerror(errno));
+       enduserdb();
+#  endif
+}
+# endif /* CUSTOM_FAILED_LOGIN */
 #endif /* _AIX */
 
index 4abe003168b8dadc1c980ccc0096767b47120d8a..4f1bda1e5e926e76246a1d9a95e44e66eac4048c 100644 (file)
@@ -1,3 +1,5 @@
+/* $Id$ */
+
 /*
  *
  * Copyright (c) 2001 Gert Doering.  All rights reserved.
  * 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.
- *
  */
 
 #ifdef _AIX
 
+#ifdef WITH_AIXAUTHENTICATE
+# include <login.h>
+# include <userpw.h>
+# include <usersec.h>
+# ifdef HAVE_SYS_AUDIT_H
+#  include <sys/audit.h>
+# endif
+#endif
+
+/* Some versions define r_type in the above headers, which causes a conflict */
+#ifdef r_type
+# undef r_type
+#endif
+
 /* AIX 4.2.x doesn't have nanosleep but does have nsleep which is equivalent */
 #if !defined(HAVE_NANOSLEEP) && defined(HAVE_NSLEEP)
 # define nanosleep(a,b) nsleep(a,b)
 # include <sys/timers.h>
 #endif
 
-void aix_usrinfo(struct passwd *pw);
+#ifdef WITH_AIXAUTHENTICATE
+# 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_remove_embedded_newlines(char *);
 #endif /* _AIX */
index a63ec429a871824ea21a54861f729d1678ee6c29..aa6db1cf8c6153a3000e66445b7316f93ded3300 100644 (file)
@@ -1,15 +1,42 @@
+/*
+ * Copyright (c) 2000 Denis Parker.  All rights reserved.
+ * Copyright (c) 2000 Michael Stone.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
 #include "includes.h"
 
-#if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY)
+#if defined(WITH_IRIX_PROJECT) || \
+    defined(WITH_IRIX_JOBS) || \
+    defined(WITH_IRIX_ARRAY)
 
 #ifdef WITH_IRIX_PROJECT
-#include <proj.h>
+# include <proj.h>
 #endif /* WITH_IRIX_PROJECT */
 #ifdef WITH_IRIX_JOBS
-#include <sys/resource.h>
+# include <sys/resource.h>
 #endif
 #ifdef WITH_IRIX_AUDIT
-#include <sat.h>
+# include <sat.h>
 #endif /* WITH_IRIX_AUDIT */
 
 void
@@ -17,14 +44,12 @@ irix_setusercontext(struct passwd *pw)
 {
 #ifdef WITH_IRIX_PROJECT
         prid_t projid;
-#endif /* WITH_IRIX_PROJECT */
+#endif
 #ifdef WITH_IRIX_JOBS
         jid_t jid = 0;
-#else
-# ifdef WITH_IRIX_ARRAY
+#elif defined(WITH_IRIX_ARRAY)
         int jid = 0;
-# endif /* WITH_IRIX_ARRAY */
-#endif /* WITH_IRIX_JOBS */
+#endif
 
 #ifdef WITH_IRIX_JOBS
         jid = jlimit_startjob(pw->pw_name, pw->pw_uid, "interactive");
index 2dd3c2e25d84c54af62cfe1dc1506886572efa61..46c38a2a0ea803f6940c1177cbd85eeb24d3838b 100644 (file)
@@ -1,5 +1,39 @@
-#if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY)
+/* $Id$ */
+
+/*
+ * Copyright (c) 2000 Denis Parker.  All rights reserved.
+ * Copyright (c) 2000 Michael Stone.  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.
+ */
+
+#ifndef _PORT_IRIX_H
+#define _PORT_IRIX_H
+
+#if defined(WITH_IRIX_PROJECT) || \
+    defined(WITH_IRIX_JOBS) || \
+    defined(WITH_IRIX_ARRAY)
 
 void irix_setusercontext(struct passwd *pw);
 
 #endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */
+
+#endif /* ! _PORT_IRIX_H */
diff --git a/openssh/openbsd-compat/realpath.h b/openssh/openbsd-compat/realpath.h
deleted file mode 100644 (file)
index 0a2445d..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-/* $Id$ */
-
-#ifndef _BSD_REALPATH_H
-#define _BSD_REALPATH_H
-
-#include "config.h"
-
-#if !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH)
-
-char *realpath(const char *path, char *resolved);
-
-#endif /* !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) */
-#endif /* _BSD_REALPATH_H */
diff --git a/openssh/openbsd-compat/rresvport.h b/openssh/openbsd-compat/rresvport.h
deleted file mode 100644 (file)
index cd908e1..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-/* $Id$ */
-
-#ifndef _BSD_RRESVPORT_H
-#define _BSD_RRESVPORT_H
-
-#include "config.h"
-
-#ifndef HAVE_RRESVPORT_AF
-int rresvport_af(int *alport, sa_family_t af);
-#endif /* !HAVE_RRESVPORT_AF */
-
-#endif /* _BSD_RRESVPORT_H */
diff --git a/openssh/openbsd-compat/setenv.h b/openssh/openbsd-compat/setenv.h
deleted file mode 100644 (file)
index b938054..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-/* $Id$ */
-
-#ifndef _BSD_SETENV_H
-#define _BSD_SETENV_H
-
-#include "config.h"
-
-#ifndef HAVE_SETENV
-
-int setenv(register const char *name, register const char *value, int rewrite);
-
-#endif /* !HAVE_SETENV */
-
-#endif /* _BSD_SETENV_H */
diff --git a/openssh/openbsd-compat/setproctitle.h b/openssh/openbsd-compat/setproctitle.h
deleted file mode 100644 (file)
index 73ae9f9..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-/* $Id$ */
-
-#ifndef _BSD_SETPROCTITLE_H
-#define _BSD_SETPROCTITLE_H
-
-#include "config.h"
-
-#ifndef HAVE_SETPROCTITLE
-void setproctitle(const char *fmt, ...);
-#endif
-
-#endif /* _BSD_SETPROCTITLE_H */
diff --git a/openssh/openbsd-compat/strlcat.h b/openssh/openbsd-compat/strlcat.h
deleted file mode 100644 (file)
index 02fbc39..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-/* $Id$ */
-
-#ifndef _BSD_STRLCAT_H
-#define _BSD_STRLCAT_H
-
-#include "config.h"
-#ifndef HAVE_STRLCAT
-#include <sys/types.h>
-size_t strlcat(char *dst, const char *src, size_t siz);
-#endif /* !HAVE_STRLCAT */
-
-#endif /* _BSD_STRLCAT_H */
diff --git a/openssh/openbsd-compat/strlcpy.h b/openssh/openbsd-compat/strlcpy.h
deleted file mode 100644 (file)
index 7b33e4f..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-/* $Id$ */
-
-#ifndef _BSD_STRLCPY_H
-#define _BSD_STRLCPY_H
-
-#include "config.h"
-#ifndef HAVE_STRLCPY
-#include <sys/types.h>
-size_t strlcpy(char *dst, const char *src, size_t siz);
-#endif /* !HAVE_STRLCPY */
-
-#endif /* _BSD_STRLCPY_H */
diff --git a/openssh/openbsd-compat/strmode.h b/openssh/openbsd-compat/strmode.h
deleted file mode 100644 (file)
index 9166379..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-/* $Id$ */
-
-#ifndef HAVE_STRMODE
-
-void strmode(register mode_t mode, register char *p);
-
-#endif
diff --git a/openssh/openbsd-compat/strsep.h b/openssh/openbsd-compat/strsep.h
deleted file mode 100644 (file)
index 9e54e05..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-/* $Id$ */
-
-#ifndef _BSD_STRSEP_H
-#define _BSD_STRSEP_H
-
-#include "config.h"
-
-#ifndef HAVE_STRSEP
-char *strsep(char **stringp, const char *delim);
-#endif /* HAVE_STRSEP */
-
-#endif /* _BSD_STRSEP_H */
index 176fe31741c3f47386152efe365d9b320d87142c..dd5c47525112415268dc5cf517d5457936591199 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: queue.h,v 1.22 2001/06/23 04:39:35 angelos Exp $      */
+/*     $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 $       */
 
 /*
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
index fc57413907bdf537ec25372b3def9a6c190647d6..e6a2ce98d0a014aca51113544e5caf2bacffd685 100644 (file)
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-#include "config.h"
+#include "includes.h"
 #if !defined(HAVE_STRNVIS)
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static char rcsid[] = "$OpenBSD: vis.c,v 1.8 2002/02/19 19:39:36 millert Exp $";
+static char rcsid[] = "$OpenBSD: vis.c,v 1.12 2003/06/02 20:18:35 millert Exp $";
 #endif /* LIBC_SCCS and not lint */
 
 #include <ctype.h>
+#include <string.h>
 
 #include "vis.h"
 
@@ -47,8 +44,9 @@ static char rcsid[] = "$OpenBSD: vis.c,v 1.8 2002/02/19 19:39:36 millert Exp $";
                                ((flag & VIS_SP) == 0 && (c) == ' ') ||      \
                                ((flag & VIS_TAB) == 0 && (c) == '\t') ||    \
                                ((flag & VIS_NL) == 0 && (c) == '\n') ||     \
-                               ((flag & VIS_SAFE) &&                        \
-                               ((c) == '\b' || (c) == '\007' || (c) == '\r')))
+                               ((flag & VIS_SAFE) && ((c) == '\b' ||        \
+                               (c) == '\007' || (c) == '\r' ||              \
+                               isgraph((u_char)(c)))))
 
 /*
  * vis - visually encode characters
@@ -169,16 +167,20 @@ strvis(dst, src, flag)
 
 int
 strnvis(dst, src, siz, flag)
-       register char *dst;
-       register const char *src;
+       char *dst;
+       const char *src;
        size_t siz;
        int flag;
 {
-       register char c;
+       char c;
        char *start, *end;
+       char tbuf[5];
+       int  i;
 
+       i = 0;
        for (start = dst, end = start + siz - 1; (c = *src) && dst < end; ) {
                if (isvisible(c)) {
+                       i = 1;
                        *dst++ = c;
                        if (c == '\\' && (flag & VIS_NOSLASH) == 0) {
                                /* need space for the extra '\\' */
@@ -186,22 +188,25 @@ strnvis(dst, src, siz, flag)
                                        *dst++ = '\\';
                                else {
                                        dst--;
+                                       i = 2;
                                        break;
                                }
                        }
                        src++;
                } else {
-                       /* vis(3) requires up to 4 chars */
-                       if (dst + 3 < end)
-                               dst = vis(dst, c, flag, *++src);
-                       else
+                       i = vis(tbuf, c, flag, *++src) - tbuf;
+                       if (dst + i <= end) {
+                               memcpy(dst, tbuf, i);
+                               dst += i;
+                       } else {
+                               src--;
                                break;
+                       }
                }
        }
-       *dst = '\0';
-       if (dst >= end) {
-               char tbuf[5];
-
+       if (siz > 0)
+               *dst = '\0';
+       if (dst + i > end) {
                /* adjust return value for truncation */
                while ((c = *src))
                        dst += vis(tbuf, c, flag, *++src) - tbuf;
index 5df6f3694fce69790c7a01998bb0d75d79c0e10a..1c131cc8558d69fc41825ba98ee62f74a0d4153d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: vis.h,v 1.5 2002/02/16 21:27:17 millert Exp $ */
+/*     $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 $      */
 
 /*-
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -35,7 +31,8 @@
  *
  *     @(#)vis.h       5.9 (Berkeley) 4/3/91
  */
-#include "config.h"
+
+#include "includes.h"
 #if !defined(HAVE_STRNVIS)
 
 #ifndef _VIS_H_
index 8f1d2022cd4cbfb332e5b80d17f0c106cea1b0c3..0e22ec686710fe123812b0145ce590e352c800f4 100644 (file)
@@ -1,4 +1,7 @@
 /*
+ * Copyright (c) 2002 Tim Rice.  All rights reserved.
+ * MAP_FAILED code by Solar Designer.
+ * 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -20,6 +23,8 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+/* $Id$ */
+
 #include "includes.h"
 
 #ifdef HAVE_SYS_MMAN_H
diff --git a/openssh/openbsd-compat/xmmap.h b/openssh/openbsd-compat/xmmap.h
deleted file mode 100644 (file)
index c0fa04a..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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 *xmmap(size_t size);
index 23b5b71eab4af4b68c75b456bb32b6958ff684a0..21b91ecff3305120477d8b039717c812724ee60c 100644 (file)
@@ -37,7 +37,9 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: packet.c,v 1.104 2003/04/01 10:22:21 markus Exp $");
+RCSID("$OpenBSD: packet.c,v 1.109 2003/07/10 14:42:28 markus Exp $");
+
+#include "openbsd-compat/sys-queue.h"
 
 #include "xmalloc.h"
 #include "buffer.h"
@@ -106,7 +108,7 @@ static int compression_buffer_ready = 0;
 static int packet_compression = 0;
 
 /* default maximum packet size */
-int max_packet_size = 32768;
+u_int max_packet_size = 32768;
 
 /* Flag indicating whether this module has been initialized. */
 static int initialized = 0;
@@ -116,8 +118,14 @@ static int interactive_mode = 0;
 
 /* Session key information for Encryption and MAC */
 Newkeys *newkeys[MODE_MAX];
-static u_int32_t read_seqnr = 0;
-static u_int32_t send_seqnr = 0;
+static struct packet_state {
+       u_int32_t seqnr;
+       u_int32_t packets;
+       u_int64_t blocks;
+} p_read, p_send;
+
+static u_int64_t max_blocks_in, max_blocks_out;
+static u_int32_t rekey_limit;
 
 /* Session key for protocol v1 */
 static u_char ssh1_key[SSH_SESSION_KEY_LENGTH];
@@ -126,6 +134,13 @@ static u_int ssh1_keylen;
 /* roundup current message to extra_pad bytes */
 static u_char extra_pad = 0;
 
+struct packet {
+       TAILQ_ENTRY(packet) next;
+       u_char type;
+       Buffer payload;
+};
+TAILQ_HEAD(, packet) outgoing;
+
 /*
  * Sets the descriptors used for communication.  Disables encryption until
  * packet_set_encryption_key is called.
@@ -148,6 +163,7 @@ packet_set_connection(int fd_in, int fd_out)
                buffer_init(&output);
                buffer_init(&outgoing_packet);
                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);
@@ -249,27 +265,31 @@ packet_set_iv(int mode, u_char *dat)
        cipher_set_keyiv(cc, dat);
 }
 int
-packet_get_ssh1_cipher()
+packet_get_ssh1_cipher(void)
 {
        return (cipher_get_number(receive_context.cipher));
 }
 
-
-u_int32_t
-packet_get_seqnr(int mode)
+void
+packet_get_state(int mode, u_int32_t *seqnr, u_int64_t *blocks, u_int32_t *packets)
 {
-       return (mode == MODE_IN ? read_seqnr : send_seqnr);
+       struct packet_state *state;
+
+       state = (mode == MODE_IN) ? &p_read : &p_send;
+       *seqnr = state->seqnr;
+       *blocks = state->blocks;
+       *packets = state->packets;
 }
 
 void
-packet_set_seqnr(int mode, u_int32_t seqnr)
+packet_set_state(int mode, u_int32_t seqnr, u_int64_t blocks, u_int32_t packets)
 {
-       if (mode == MODE_IN)
-               read_seqnr = seqnr;
-       else if (mode == MODE_OUT)
-               send_seqnr = seqnr;
-       else
-               fatal("packet_set_seqnr: bad mode %d", mode);
+       struct packet_state *state;
+
+       state = (mode == MODE_IN) ? &p_read : &p_send;
+       state->seqnr = seqnr;
+       state->blocks = blocks;
+       state->packets = packets;
 }
 
 /* returns 1 if connection is via ipv4 */
@@ -562,6 +582,7 @@ set_newkeys(int mode)
        Mac *mac;
        Comp *comp;
        CipherContext *cc;
+       u_int64_t *max_blocks;
        int encrypt;
 
        debug2("set_newkeys: mode %d", mode);
@@ -569,9 +590,13 @@ set_newkeys(int mode)
        if (mode == MODE_OUT) {
                cc = &send_context;
                encrypt = CIPHER_ENCRYPT;
+               p_send.packets = p_send.blocks = 0;
+               max_blocks = &max_blocks_out;
        } else {
                cc = &receive_context;
                encrypt = CIPHER_DECRYPT;
+               p_read.packets = p_read.blocks = 0;
+               max_blocks = &max_blocks_in;
        }
        if (newkeys[mode] != NULL) {
                debug("set_newkeys: rekeying");
@@ -610,13 +635,23 @@ set_newkeys(int mode)
                        buffer_compress_init_recv();
                comp->enabled = 1;
        }
+       /*
+        * The 2^(blocksize*2) limit is too expensive for 3DES,
+        * blowfish, etc, so enforce a 1GB limit for small blocksizes.
+        */
+       if (enc->block_size >= 16)
+               *max_blocks = (u_int64_t)1 << (enc->block_size*2);
+       else
+               *max_blocks = ((u_int64_t)1 << 30) / enc->block_size;
+       if (rekey_limit)
+               *max_blocks = MIN(*max_blocks, rekey_limit / enc->block_size);
 }
 
 /*
  * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue)
  */
 static void
-packet_send2(void)
+packet_send2_wrapped(void)
 {
        u_char type, *cp, *macbuf = NULL;
        u_char padlen, pad;
@@ -698,10 +733,10 @@ packet_send2(void)
 
        /* compute MAC over seqnr and packet(length fields, payload, padding) */
        if (mac && mac->enabled) {
-               macbuf = mac_compute(mac, send_seqnr,
+               macbuf = mac_compute(mac, p_send.seqnr,
                    buffer_ptr(&outgoing_packet),
                    buffer_len(&outgoing_packet));
-               DBG(debug("done calc MAC out #%d", send_seqnr));
+               DBG(debug("done calc MAC out #%d", p_send.seqnr));
        }
        /* encrypt packet and append to output buffer. */
        cp = buffer_append_space(&output, buffer_len(&outgoing_packet));
@@ -715,14 +750,64 @@ packet_send2(void)
        buffer_dump(&output);
 #endif
        /* increment sequence number for outgoing packets */
-       if (++send_seqnr == 0)
-               log("outgoing seqnr wraps around");
+       if (++p_send.seqnr == 0)
+               logit("outgoing seqnr wraps around");
+       if (++p_send.packets == 0)
+               if (!(datafellows & SSH_BUG_NOREKEY))
+                       fatal("XXX too many packets with same key");
+       p_send.blocks += (packet_length + 4) / block_size;
        buffer_clear(&outgoing_packet);
 
        if (type == SSH2_MSG_NEWKEYS)
                set_newkeys(MODE_OUT);
 }
 
+static void
+packet_send2(void)
+{
+       static int rekeying = 0;
+       struct packet *p;
+       u_char type, *cp;
+
+       cp = buffer_ptr(&outgoing_packet);
+       type = cp[5];
+
+       /* during rekeying we can only send key exchange messages */
+       if (rekeying) {
+               if (!((type >= SSH2_MSG_TRANSPORT_MIN) &&
+                   (type <= SSH2_MSG_TRANSPORT_MAX))) {
+                       debug("enqueue packet: %u", type);
+                       p = xmalloc(sizeof(*p));
+                       p->type = type;
+                       memcpy(&p->payload, &outgoing_packet, sizeof(Buffer));
+                       buffer_init(&outgoing_packet);
+                       TAILQ_INSERT_TAIL(&outgoing, p, next);
+                       return;
+               }
+       }
+
+       /* rekeying starts with sending KEXINIT */
+       if (type == SSH2_MSG_KEXINIT)
+               rekeying = 1;
+
+       packet_send2_wrapped();
+
+       /* after a NEWKEYS message we can send the complete queue */
+       if (type == SSH2_MSG_NEWKEYS) {
+               rekeying = 0;
+               while ((p = TAILQ_FIRST(&outgoing))) {
+                       type = p->type;
+                       debug("dequeue packet: %u", type);
+                       buffer_free(&outgoing_packet);
+                       memcpy(&outgoing_packet, &p->payload,
+                           sizeof(Buffer));
+                       TAILQ_REMOVE(&outgoing, p, next);
+                       xfree(p);
+                       packet_send2_wrapped();
+               }
+       }
+}
+
 void
 packet_send(void)
 {
@@ -784,7 +869,7 @@ packet_read_seqnr(u_int32_t *seqnr_p)
                /* Read data from the socket. */
                len = read(connection_in, buf, sizeof(buf));
                if (len == 0) {
-                       log("Connection closed by %.200s", get_remote_ipaddr());
+                       logit("Connection closed by %.200s", get_remote_ipaddr());
                        fatal_cleanup();
                }
                if (len < 0)
@@ -966,18 +1051,22 @@ packet_read_poll2(u_int32_t *seqnr_p)
         * increment sequence number for incoming packet
         */
        if (mac && mac->enabled) {
-               macbuf = mac_compute(mac, read_seqnr,
+               macbuf = mac_compute(mac, p_read.seqnr,
                    buffer_ptr(&incoming_packet),
                    buffer_len(&incoming_packet));
                if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0)
                        packet_disconnect("Corrupted MAC on input.");
-               DBG(debug("MAC #%d ok", read_seqnr));
+               DBG(debug("MAC #%d ok", p_read.seqnr));
                buffer_consume(&input, mac->mac_len);
        }
        if (seqnr_p != NULL)
-               *seqnr_p = read_seqnr;
-       if (++read_seqnr == 0)
-               log("incoming seqnr wraps around");
+               *seqnr_p = p_read.seqnr;
+       if (++p_read.seqnr == 0)
+               logit("incoming seqnr wraps around");
+       if (++p_read.packets == 0)
+               if (!(datafellows & SSH_BUG_NOREKEY))
+                       fatal("XXX too many packets with same key");
+       p_read.blocks += (packet_length + 4) / block_size;
 
        /* get padlen */
        cp = buffer_ptr(&incoming_packet);
@@ -1042,7 +1131,7 @@ packet_read_poll_seqnr(u_int32_t *seqnr_p)
                        case SSH2_MSG_DISCONNECT:
                                reason = packet_get_int();
                                msg = packet_get_string(NULL);
-                               log("Received disconnect from %s: %u: %.400s",
+                               logit("Received disconnect from %s: %u: %.400s",
                                    get_remote_ipaddr(), reason, msg);
                                xfree(msg);
                                fatal_cleanup();
@@ -1068,7 +1157,7 @@ packet_read_poll_seqnr(u_int32_t *seqnr_p)
                                break;
                        case SSH_MSG_DISCONNECT:
                                msg = packet_get_string(NULL);
-                               log("Received disconnect from %s: %.400s",
+                               logit("Received disconnect from %s: %.400s",
                                    get_remote_ipaddr(), msg);
                                fatal_cleanup();
                                xfree(msg);
@@ -1234,7 +1323,7 @@ packet_disconnect(const char *fmt,...)
        va_end(args);
 
        /* Display the error locally */
-       log("Disconnecting: %.100s", buf);
+       logit("Disconnecting: %.100s", buf);
 
        /* Send the disconnect message to the other side, and wait for it to get sent. */
        if (compat20) {
@@ -1321,6 +1410,8 @@ packet_not_very_much_data_to_write(void)
                return buffer_len(&output) < 128 * 1024;
 }
 
+
+#if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN)
 static void
 packet_set_tos(int interactive)
 {
@@ -1334,6 +1425,7 @@ packet_set_tos(int interactive)
                error("setsockopt IP_TOS %d: %.100s:",
                    tos, strerror(errno));
 }
+#endif
 
 /* Informs that the current session is interactive.  Sets IP flags for that. */
 
@@ -1351,6 +1443,7 @@ packet_set_interactive(int interactive)
 
        /* Only set socket options if using a socket.  */
        if (!packet_connection_is_on_socket())
+               return;
        if (interactive)
                set_nodelay(connection_in);
 #if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN)
@@ -1367,18 +1460,18 @@ packet_is_interactive(void)
        return interactive_mode;
 }
 
-int
-packet_set_maxsize(int s)
+u_int
+packet_set_maxsize(u_int s)
 {
        static int called = 0;
 
        if (called) {
-               log("packet_set_maxsize: called twice: old %d new %d",
+               logit("packet_set_maxsize: called twice: old %d new %d",
                    max_packet_size, s);
                return -1;
        }
        if (s < 4 * 1024 || s > 1024 * 1024) {
-               log("packet_set_maxsize: bad size %d", s);
+               logit("packet_set_maxsize: bad size %d", s);
                return -1;
        }
        called = 1;
@@ -1420,3 +1513,22 @@ packet_send_ignore(int nbytes)
                rand >>= 8;
        }
 }
+
+#define MAX_PACKETS    (1<<31)
+int
+packet_need_rekeying(void)
+{
+       if (datafellows & SSH_BUG_NOREKEY)
+               return 0;
+       return
+           (p_send.packets > MAX_PACKETS) ||
+           (p_read.packets > MAX_PACKETS) ||
+           (max_blocks_out && (p_send.blocks > max_blocks_out)) ||
+           (max_blocks_in  && (p_read.blocks > max_blocks_in));
+}
+
+void
+packet_set_rekey_limit(u_int32_t bytes)
+{
+       rekey_limit = bytes;
+}
index 53c300394cb5ccbe3c4baf5c6de24a8aef79e9d9..1793030babf82fbb5ec812849a0eb39225424ef4 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: packet.h,v 1.37 2003/04/01 10:22:21 markus Exp $      */
+/*     $OpenBSD: packet.h,v 1.40 2003/06/24 08:23:46 markus Exp $      */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -63,8 +63,8 @@ int    packet_get_keyiv_len(int);
 void    packet_get_keyiv(int, u_char *, u_int);
 int     packet_get_keycontext(int, u_char *);
 void    packet_set_keycontext(int, u_char *);
-u_int32_t packet_get_seqnr(int);
-void    packet_set_seqnr(int, u_int32_t);
+void    packet_get_state(int, u_int32_t *, u_int64_t *, u_int32_t *);
+void    packet_set_state(int, u_int32_t, u_int64_t, u_int32_t);
 int     packet_get_ssh1_cipher(void);
 void    packet_set_iv(int, u_char *);
 
@@ -82,8 +82,8 @@ void   packet_add_padding(u_char);
 void    tty_make_modes(int, struct termios *);
 void    tty_parse_modes(int, int *);
 
-extern int max_packet_size;
-int      packet_set_maxsize(int);
+extern u_int max_packet_size;
+u_int   packet_set_maxsize(u_int);
 #define  packet_get_maxsize() max_packet_size
 
 /* don't allow remaining bytes after the end of the message */
@@ -91,10 +91,13 @@ int      packet_set_maxsize(int);
 do { \
        int _len = packet_remaining(); \
        if (_len > 0) { \
-               log("Packet integrity error (%d bytes remaining) at %s:%d", \
+               logit("Packet integrity error (%d bytes remaining) at %s:%d", \
                    _len ,__FILE__, __LINE__); \
                packet_disconnect("Packet integrity error."); \
        } \
 } while (0)
 
+int     packet_need_rekeying(void);
+void    packet_set_rekey_limit(u_int32_t);
+
 #endif                         /* PACKET_H */
index 90eb97f375f38bddb50e54da5abdf0c23fcc1c74..c315464ee73aa7fbf1b19b64c9fc8ee1c52ae76f 100644 (file)
@@ -1,6 +1,5 @@
 /*
- * Copyright (c) 1999 Theo de Raadt.  All rights reserved.
- * Copyright (c) 1999 Aaron Campbell.  All rights reserved.
+ * Copyright (c) 2003 Nils Nordman.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/*
- * Parts from:
- *
- * Copyright (c) 1983, 1990, 1992, 1993, 1995
- *     The Regents of the University of California.  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.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
-
 #include "includes.h"
-RCSID("$OpenBSD: progressmeter.c,v 1.3 2003/03/17 10:38:38 markus Exp $");
+RCSID("$OpenBSD: progressmeter.c,v 1.15 2003/08/31 12:14:22 markus Exp $");
 
-#ifdef HAVE_LIBGEN_H
-#include <libgen.h>
-#endif
-
-#include "atomicio.h"
 #include "progressmeter.h"
+#include "atomicio.h"
+#include "misc.h"
 
-/* Number of seconds before xfer considered "stalled". */
-#define STALLTIME      5
-/* alarm() interval for updating progress meter. */
-#define PROGRESSTIME   1
-
-/* Signal handler used for updating the progress meter. */
-static void update_progress_meter(int);
+#define DEFAULT_WINSIZE 80
+#define MAX_WINSIZE 512
+#define PADDING 1              /* padding between the progress indicators */
+#define UPDATE_INTERVAL 1      /* update the progress meter every second */
+#define STALL_TIME 5           /* we're stalled after this many seconds */
 
-/* Returns non-zero if we are the foreground process. */
-static int foregroundproc(void);
+/* determines whether we can output to the terminal */
+static int can_output(void);
 
-/* Returns width of the terminal (for progress meter calculations). */
-static int get_tty_width(void);
+/* formats and inserts the specified size into the given buffer */
+static void format_size(char *, int, off_t);
+static void format_rate(char *, int, off_t);
 
-/* Visual statistics about files as they are transferred. */
-static void draw_progress_meter(void);
+/* updates the progressmeter to reflect the current state of the transfer */
+void refresh_progress_meter(void);
 
-/* Time a transfer started. */
-static struct timeval start;
+/* signal handler for updating the progress meter */
+static void update_progress_meter(int);
 
-/* Number of bytes of current file transferred so far. */
-static volatile off_t *statbytes;
+static time_t start;           /* start progress */
+static time_t last_update;     /* last progress update */
+static char *file;             /* name of the file being transferred */
+static off_t end_pos;          /* ending position of transfer */
+static off_t cur_pos;          /* transfer position as of last refresh */
+static volatile off_t *counter;        /* progress counter */
+static long stalled;           /* how long we have been stalled */
+static int bytes_per_second;   /* current speed in bytes per second */
+static int win_size;           /* terminal window size */
 
-/* Total size of current file. */
-static off_t totalbytes;
+/* units for format_size */
+static const char unit[] = " KMGT";
 
-/* Name of current file being transferred. */
-static char *curfile;
+static int
+can_output(void)
+{
+       return (getpgrp() == tcgetpgrp(STDOUT_FILENO));
+}
 
-/* Time of last update. */
-static struct timeval lastupdate;
+static void
+format_rate(char *buf, int size, off_t bytes)
+{
+       int i;
+
+       bytes *= 100;
+       for (i = 0; bytes >= 100*1000 && unit[i] != 'T'; i++)
+               bytes = (bytes + 512) / 1024;
+       if (i == 0) {
+               i++;
+               bytes = (bytes + 512) / 1024;
+       }
+       snprintf(buf, size, "%3lld.%1lld%c%s",
+           (int64_t) bytes / 100,
+           (int64_t) (bytes + 5) / 10 % 10,
+           unit[i],
+           i ? "B" : " ");
+}
 
-/* Size at the time of the last update. */
-static off_t lastsize;
+static void
+format_size(char *buf, int size, off_t bytes)
+{
+       int i;
+
+       for (i = 0; bytes >= 10000 && unit[i] != 'T'; i++)
+               bytes = (bytes + 512) / 1024;
+       snprintf(buf, size, "%4lld%c%s",
+           (int64_t) bytes,
+           unit[i],
+           i ? "B" : " ");
+}
 
 void
-start_progress_meter(char *file, off_t filesize, off_t *counter)
+refresh_progress_meter(void)
 {
-       if ((curfile = basename(file)) == NULL)
-               curfile = file;
+       char buf[MAX_WINSIZE + 1];
+       time_t now;
+       off_t transferred;
+       double elapsed;
+       int percent;
+       int bytes_left;
+       int cur_speed;
+       int hours, minutes, seconds;
+       int i, len;
+       int file_len;
+
+       transferred = *counter - cur_pos;
+       cur_pos = *counter;
+       now = time(NULL);
+       bytes_left = end_pos - cur_pos;
+
+       if (bytes_left > 0)
+               elapsed = now - last_update;
+       else
+               elapsed = now - start;
 
-       totalbytes = filesize;
-       statbytes = counter;
-       (void) gettimeofday(&start, (struct timezone *) 0);
-       lastupdate = start;
-       lastsize = 0;
+       /* calculate speed */
+       if (elapsed != 0)
+               cur_speed = (transferred / elapsed);
+       else
+               cur_speed = 0;
 
-       draw_progress_meter();
-       signal(SIGALRM, update_progress_meter);
-       alarm(PROGRESSTIME);
-}
+#define AGE_FACTOR 0.9
+       if (bytes_per_second != 0) {
+               bytes_per_second = (bytes_per_second * AGE_FACTOR) +
+                   (cur_speed * (1.0 - AGE_FACTOR));
+       } else
+               bytes_per_second = cur_speed;
+
+       /* filename */
+       buf[0] = '\0';
+       file_len = win_size - 35;
+       if (file_len > 0) {
+               len = snprintf(buf, file_len + 1, "\r%s", file);
+               if (len < 0)
+                       len = 0;
+               for (i = len;  i < file_len; i++ )
+                       buf[i] = ' ';
+               buf[file_len] = '\0';
+       }
 
-void
-stop_progress_meter()
-{
-       alarm(0);
-       draw_progress_meter();
-       if (foregroundproc() != 0)
-               atomicio(write, fileno(stdout), "\n", 1);
+       /* percent of transfer done */
+       if (end_pos != 0)
+               percent = ((float)cur_pos / end_pos) * 100;
+       else
+               percent = 100;
+       snprintf(buf + strlen(buf), win_size - strlen(buf),
+           " %3d%% ", percent);
+
+       /* amount transferred */
+       format_size(buf + strlen(buf), win_size - strlen(buf),
+           cur_pos);
+       strlcat(buf, " ", win_size);
+
+       /* bandwidth usage */
+       format_rate(buf + strlen(buf), win_size - strlen(buf),
+           bytes_per_second);
+       strlcat(buf, "/s ", win_size);
+
+       /* ETA */
+       if (!transferred)
+               stalled += elapsed;
+       else
+               stalled = 0;
+
+       if (stalled >= STALL_TIME)
+               strlcat(buf, "- stalled -", win_size);
+       else if (bytes_per_second == 0 && bytes_left)
+               strlcat(buf, "  --:-- ETA", win_size);
+       else {
+               if (bytes_left > 0)
+                       seconds = bytes_left / bytes_per_second;
+               else
+                       seconds = elapsed;
+
+               hours = seconds / 3600;
+               seconds -= hours * 3600;
+               minutes = seconds / 60;
+               seconds -= minutes * 60;
+
+               if (hours != 0)
+                       snprintf(buf + strlen(buf), win_size - strlen(buf),
+                           "%d:%02d:%02d", hours, minutes, seconds);
+               else
+                       snprintf(buf + strlen(buf), win_size - strlen(buf),
+                           "  %02d:%02d", minutes, seconds);
+
+               if (bytes_left > 0)
+                       strlcat(buf, " ETA", win_size);
+               else
+                       strlcat(buf, "    ", win_size);
+       }
+
+       atomicio(vwrite, STDOUT_FILENO, buf, win_size);
+       last_update = now;
 }
 
 static void
 update_progress_meter(int ignore)
 {
-       int save_errno = errno;
+       int save_errno;
+
+       save_errno = errno;
+
+       if (can_output())
+               refresh_progress_meter();
 
-       draw_progress_meter();
        signal(SIGALRM, update_progress_meter);
-       alarm(PROGRESSTIME);
+       alarm(UPDATE_INTERVAL);
        errno = save_errno;
 }
 
-static int
-foregroundproc(void)
-{
-       static pid_t pgrp = -1;
-       int ctty_pgrp;
-
-       if (pgrp == -1)
-               pgrp = getpgrp();
-
-#ifdef HAVE_TCGETPGRP
-        return ((ctty_pgrp = tcgetpgrp(STDOUT_FILENO)) != -1 &&
-                       ctty_pgrp == pgrp);
-#else
-       return ((ioctl(STDOUT_FILENO, TIOCGPGRP, &ctty_pgrp) != -1 &&
-                ctty_pgrp == pgrp));
-#endif
-}
-
-static void
-draw_progress_meter()
+void
+start_progress_meter(char *f, off_t filesize, off_t *stat)
 {
-       static const char spaces[] = "                          "
-           "                                                   "
-           "                                                   "
-           "                                                   "
-           "                                                   "
-           "                                                   ";
-       static const char prefixes[] = " KMGTP";
-       struct timeval now, td, wait;
-       off_t cursize, abbrevsize, bytespersec;
-       double elapsed;
-       int ratio, remaining, i, ai, bi, nspaces;
-       char buf[512];
-
-       if (foregroundproc() == 0)
-               return;
+       struct winsize winsize;
 
-       (void) gettimeofday(&now, (struct timezone *) 0);
-       cursize = *statbytes;
-       if (totalbytes != 0) {
-               ratio = 100.0 * cursize / totalbytes;
-               ratio = MAX(ratio, 0);
-               ratio = MIN(ratio, 100);
+       start = last_update = time(NULL);
+       file = f;
+       end_pos = filesize;
+       cur_pos = 0;
+       counter = stat;
+       stalled = 0;
+       bytes_per_second = 0;
+
+       if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsize) != -1 &&
+           winsize.ws_col != 0) {
+               if (winsize.ws_col > MAX_WINSIZE)
+                       win_size = MAX_WINSIZE;
+               else
+                       win_size = winsize.ws_col;
        } else
-               ratio = 100;
-
-       abbrevsize = cursize;
-       for (ai = 0; abbrevsize >= 10000 && ai < sizeof(prefixes); ai++)
-               abbrevsize >>= 10;
+               win_size = DEFAULT_WINSIZE;
+       win_size += 1;                                  /* trailing \0 */
 
-       timersub(&now, &lastupdate, &wait);
-       if (cursize > lastsize) {
-               lastupdate = now;
-               lastsize = cursize;
-               wait.tv_sec = 0;
-       }
-       timersub(&now, &start, &td);
-       elapsed = td.tv_sec + (td.tv_usec / 1000000.0);
-
-       bytespersec = 0;
-       if (cursize > 0) {
-               bytespersec = cursize;
-               if (elapsed > 0.0)
-                       bytespersec /= elapsed;
-       }
-       for (bi = 1; bytespersec >= 1024000 && bi < sizeof(prefixes); bi++)
-               bytespersec >>= 10;
-
-       nspaces = MIN(get_tty_width() - 79, sizeof(spaces) - 1);
-
-#ifdef HAVE_LONG_LONG_INT
-       snprintf(buf, sizeof(buf),
-           "\r%-45.45s%.*s%3d%% %4lld%c%c %3lld.%01d%cB/s",
-           curfile,
-           nspaces,
-           spaces,
-           ratio,
-           (long long)abbrevsize,
-           prefixes[ai],
-           ai == 0 ? ' ' : 'B',
-           (long long)(bytespersec / 1024),
-           (int)((bytespersec % 1024) * 10 / 1024),
-           prefixes[bi]
-       );
-#else
-               /* XXX: Handle integer overflow? */
-       snprintf(buf, sizeof(buf),
-           "\r%-45.45s%.*s%3d%% %4lu%c%c %3lu.%01d%cB/s",
-           curfile,
-           nspaces,
-           spaces,
-           ratio,
-           (u_long)abbrevsize,
-           prefixes[ai],
-           ai == 0 ? ' ' : 'B',
-           (u_long)(bytespersec / 1024),
-           (int)((bytespersec % 1024) * 10 / 1024),
-           prefixes[bi]
-       );
-#endif
-
-       if (cursize <= 0 || elapsed <= 0.0 || cursize > totalbytes) {
-               snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
-                   "   --:-- ETA");
-       } else if (wait.tv_sec >= STALLTIME) {
-               snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
-                   " - stalled -");
-       } else {
-               if (cursize != totalbytes)
-                       remaining = (int)(totalbytes / (cursize / elapsed) -
-                           elapsed);
-               else
-                       remaining = elapsed;
+       if (can_output())
+               refresh_progress_meter();
 
-               i = remaining / 3600;
-               if (i)
-                       snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
-                           "%2d:", i);
-               else
-                       snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
-                           "   ");
-               i = remaining % 3600;
-               snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
-                   "%02d:%02d%s", i / 60, i % 60,
-                   (cursize != totalbytes) ? " ETA" : "    ");
-       }
-       atomicio(write, fileno(stdout), buf, strlen(buf));
+       signal(SIGALRM, update_progress_meter);
+       alarm(UPDATE_INTERVAL);
 }
 
-static int
-get_tty_width(void)
+void
+stop_progress_meter(void)
 {
-       struct winsize winsize;
+       alarm(0);
 
-       if (ioctl(fileno(stdout), TIOCGWINSZ, &winsize) != -1)
-               return (winsize.ws_col ? winsize.ws_col : 80);
-       else
-               return (80);
+       if (!can_output())
+               return;
+
+       /* Ensure we complete the progress */
+       if (cur_pos != end_pos)
+               refresh_progress_meter();
+
+       atomicio(vwrite, STDOUT_FILENO, "\n", 1);
 }
diff --git a/openssh/radix.c b/openssh/radix.c
deleted file mode 100644 (file)
index 26b1ebe..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (c) 1999 Dug Song.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "includes.h"
-#include "uuencode.h"
-
-RCSID("$OpenBSD: radix.c,v 1.16 2001/06/23 15:12:19 itojun Exp $");
-
-#ifdef AFS
-#include <krb.h>
-
-#include <radix.h>
-
-typedef u_char my_u_char;
-typedef u_int my_u_int32_t;
-typedef u_short my_u_short;
-
-/* Nasty macros from BIND-4.9.2 */
-
-#define GETSHORT(s, cp) { \
-       register my_u_char *t_cp = (my_u_char *)(cp); \
-       (s) = (((my_u_short)t_cp[0]) << 8) \
-           | (((my_u_short)t_cp[1])) \
-           ; \
-       (cp) += 2; \
-}
-
-#define GETLONG(l, cp) { \
-       register my_u_char *t_cp = (my_u_char *)(cp); \
-       (l) = (((my_u_int32_t)t_cp[0]) << 24) \
-           | (((my_u_int32_t)t_cp[1]) << 16) \
-           | (((my_u_int32_t)t_cp[2]) << 8) \
-           | (((my_u_int32_t)t_cp[3])) \
-           ; \
-       (cp) += 4; \
-}
-
-#define PUTSHORT(s, cp) { \
-       register my_u_short t_s = (my_u_short)(s); \
-       register my_u_char *t_cp = (my_u_char *)(cp); \
-       *t_cp++ = t_s >> 8; \
-       *t_cp   = t_s; \
-       (cp) += 2; \
-}
-
-#define PUTLONG(l, cp) { \
-       register my_u_int32_t t_l = (my_u_int32_t)(l); \
-       register my_u_char *t_cp = (my_u_char *)(cp); \
-       *t_cp++ = t_l >> 24; \
-       *t_cp++ = t_l >> 16; \
-       *t_cp++ = t_l >> 8; \
-       *t_cp   = t_l; \
-       (cp) += 4; \
-}
-
-#define GETSTRING(s, p, p_l) {                 \
-    register char *p_targ = (p) + p_l;         \
-    register char *s_c = (s);                  \
-    register char *p_c = (p);                  \
-    while (*p_c && (p_c < p_targ)) {           \
-       *s_c++ = *p_c++;                        \
-    }                                          \
-    if (p_c == p_targ) {                       \
-       return 1;                               \
-    }                                          \
-    *s_c = *p_c++;                             \
-    (p_l) = (p_l) - (p_c - (p));               \
-    (p) = p_c;                                 \
-}
-
-
-int
-creds_to_radix(CREDENTIALS *creds, u_char *buf, size_t buflen)
-{
-       char *p, *s;
-       int len;
-       char temp[2048];
-
-       p = temp;
-       *p++ = 1;               /* version */
-       s = creds->service;
-       while (*s)
-               *p++ = *s++;
-       *p++ = *s;
-       s = creds->instance;
-       while (*s)
-               *p++ = *s++;
-       *p++ = *s;
-       s = creds->realm;
-       while (*s)
-               *p++ = *s++;
-       *p++ = *s;
-
-       s = creds->pname;
-       while (*s)
-               *p++ = *s++;
-       *p++ = *s;
-       s = creds->pinst;
-       while (*s)
-               *p++ = *s++;
-       *p++ = *s;
-       /* Null string to repeat the realm. */
-       *p++ = '\0';
-
-       PUTLONG(creds->issue_date, p);
-       {
-               u_int endTime;
-               endTime = (u_int) krb_life_to_time(creds->issue_date,
-                                                         creds->lifetime);
-               PUTLONG(endTime, p);
-       }
-
-       memcpy(p, &creds->session, sizeof(creds->session));
-       p += sizeof(creds->session);
-
-       PUTSHORT(creds->kvno, p);
-       PUTLONG(creds->ticket_st.length, p);
-
-       memcpy(p, creds->ticket_st.dat, creds->ticket_st.length);
-       p += creds->ticket_st.length;
-       len = p - temp;
-
-       return (uuencode((u_char *)temp, len, (char *)buf, buflen));
-}
-
-int
-radix_to_creds(const char *buf, CREDENTIALS *creds)
-{
-
-       char *p;
-       int len, tl;
-       char version;
-       char temp[2048];
-
-       len = uudecode(buf, (u_char *)temp, sizeof(temp));
-       if (len < 0)
-               return 0;
-
-       p = temp;
-
-       /* check version and length! */
-       if (len < 1)
-               return 0;
-       version = *p;
-       p++;
-       len--;
-
-       GETSTRING(creds->service, p, len);
-       GETSTRING(creds->instance, p, len);
-       GETSTRING(creds->realm, p, len);
-
-       GETSTRING(creds->pname, p, len);
-       GETSTRING(creds->pinst, p, len);
-       /* Ignore possibly different realm. */
-       while (*p && len)
-               p++, len--;
-       if (len == 0)
-               return 0;
-       p++, len--;
-
-       /* Enough space for remaining fixed-length parts? */
-       if (len < (4 + 4 + sizeof(creds->session) + 2 + 4))
-               return 0;
-
-       GETLONG(creds->issue_date, p);
-       len -= 4;
-       {
-               u_int endTime;
-               GETLONG(endTime, p);
-               len -= 4;
-               creds->lifetime = krb_time_to_life(creds->issue_date, endTime);
-       }
-
-       memcpy(&creds->session, p, sizeof(creds->session));
-       p += sizeof(creds->session);
-       len -= sizeof(creds->session);
-
-       GETSHORT(creds->kvno, p);
-       len -= 2;
-       GETLONG(creds->ticket_st.length, p);
-       len -= 4;
-
-       tl = creds->ticket_st.length;
-       if (tl < 0 || tl > len || tl > sizeof(creds->ticket_st.dat))
-               return 0;
-
-       memcpy(creds->ticket_st.dat, p, tl);
-       p += tl;
-       len -= tl;
-
-       return 1;
-}
-#endif /* AFS */
diff --git a/openssh/radix.h b/openssh/radix.h
deleted file mode 100644 (file)
index e94e4ac..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*     $OpenBSD: radix.h,v 1.4 2001/06/26 17:27:24 markus Exp $        */
-
-/*
- * Copyright (c) 1999 Dug Song.  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.
- */
-
-int     creds_to_radix(CREDENTIALS *, u_char *, size_t);
-int     radix_to_creds(const char *, CREDENTIALS *);
index 81e9f934da2ec831003b4fe175f828d946a92b1d..9b46597fb2ebc31e28a51882561915b1fb007e17 100644 (file)
@@ -12,7 +12,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: readconf.c,v 1.104 2003/04/01 10:22:21 markus Exp $");
+RCSID("$OpenBSD: readconf.c,v 1.121 2003/09/01 18:15:50 markus Exp $");
 
 #include "ssh.h"
 #include "xmalloc.h"
@@ -57,7 +57,6 @@ RCSID("$OpenBSD: readconf.c,v 1.104 2003/04/01 10:22:21 markus Exp $");
    Host fascist.blob.com
      Port 23123
      User tylonen
-     RhostsAuthentication no
      PasswordAuthentication no
 
    Host puukko.hut.fi
@@ -75,7 +74,6 @@ RCSID("$OpenBSD: readconf.c,v 1.104 2003/04/01 10:22:21 markus Exp $");
    Host *
      ForwardAgent no
      ForwardX11 no
-     RhostsAuthentication yes
      PasswordAuthentication yes
      RSAAuthentication yes
      RhostsRSAAuthentication yes
@@ -91,24 +89,9 @@ RCSID("$OpenBSD: readconf.c,v 1.104 2003/04/01 10:22:21 markus Exp $");
 
 typedef enum {
        oBadOption,
-       oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication,
+       oForwardAgent, oForwardX11, oGatewayPorts,
        oPasswordAuthentication, oRSAAuthentication,
        oChallengeResponseAuthentication, oXAuthLocation,
-#if defined(KRB4) || defined(KRB5)
-       oKerberosAuthentication,
-#endif
-#ifdef GSSAPI
-       oGssAuthentication, oGssKeyEx, oGssDelegateCreds,
-#ifdef GSI
-       oGssGlobusDelegateLimitedCreds,
-#endif /* GSI */
-#endif /* GSSAPI */
-#if defined(AFS) || defined(KRB5)
-       oKerberosTgtPassing,
-#endif
-#ifdef AFS
-       oAFSTokenPassing,
-#endif
        oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
        oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
        oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
@@ -120,8 +103,9 @@ typedef enum {
        oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
        oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
        oClearAllForwardings, oNoHostAuthenticationForLocalhost,
-       oEnableSSHKeysign,
-       oDeprecated
+       oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
+       oAddressFamily, oGssAuthentication, oGssKeyEx, oGssDelegateCreds,
+       oDeprecated, oUnsupported
 } OpCodes;
 
 /* Textual representations of the tokens. */
@@ -135,7 +119,7 @@ static struct {
        { "xauthlocation", oXAuthLocation },
        { "gatewayports", oGatewayPorts },
        { "useprivilegedport", oUsePrivilegedPort },
-       { "rhostsauthentication", oRhostsAuthentication },
+       { "rhostsauthentication", oDeprecated },
        { "passwordauthentication", oPasswordAuthentication },
        { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
        { "kbdinteractivedevices", oKbdInteractiveDevices },
@@ -147,24 +131,17 @@ static struct {
        { "challengeresponseauthentication", oChallengeResponseAuthentication },
        { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
        { "tisauthentication", oChallengeResponseAuthentication },  /* alias */
-#if defined(KRB4) || defined(KRB5)
-       { "kerberosauthentication", oKerberosAuthentication },
-#endif
-#ifdef GSSAPI
+       { "kerberosauthentication", oUnsupported },
+       { "kerberostgtpassing", oUnsupported },
+       { "afstokenpassing", oUnsupported },
+#if defined(GSSAPI)
        { "gssapiauthentication", oGssAuthentication },
        { "gssapikeyexchange", oGssKeyEx },
        { "gssapidelegatecredentials", oGssDelegateCreds },
-#ifdef GSI
-       /* For backwards compatability with old 1.2.27 client code */
-       { "forwardgssapiglobusproxy", oGssDelegateCreds }, /* alias */
-       { "forwardgssapiglobuslimitedproxy", oGssGlobusDelegateLimitedCreds },
-#endif /* GSI */
-#endif /* GSSAPI */
-#if defined(AFS) || defined(KRB5)
-       { "kerberostgtpassing", oKerberosTgtPassing },
-#endif
-#ifdef AFS
-       { "afstokenpassing", oAFSTokenPassing },
+#else
+       { "gssapiauthentication", oUnsupported },
+       { "gssapikeyexchange", oUnsupported },
+       { "gssapidelegatecredentials", oUnsupported },
 #endif
        { "fallbacktorsh", oDeprecated },
        { "usersh", oDeprecated },
@@ -200,10 +177,22 @@ static struct {
        { "preferredauthentications", oPreferredAuthentications },
        { "hostkeyalgorithms", oHostKeyAlgorithms },
        { "bindaddress", oBindAddress },
+#ifdef SMARTCARD
        { "smartcarddevice", oSmartcardDevice },
+#else
+       { "smartcarddevice", oUnsupported },
+#endif
        { "clearallforwardings", oClearAllForwardings },
        { "enablesshkeysign", oEnableSSHKeysign },
+#ifdef DNS
+       { "verifyhostkeydns", oVerifyHostKeyDNS },
+#else
+       { "verifyhostkeydns", oUnsupported },
+#endif
        { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
+       { "rekeylimit", oRekeyLimit },
+       { "connecttimeout", oConnectTimeout },
+       { "addressfamily", oAddressFamily },
        { NULL, oBadOption }
 };
 
@@ -297,6 +286,13 @@ process_config_line(Options *options, const char *host,
        u_short fwd_port, fwd_host_port;
        char sfwd_host_port[6];
 
+       /* Strip trailing whitespace */
+       for(len = strlen(line) - 1; len > 0; len--) {
+               if (strchr(WHITESPACE, line[len]) == NULL)
+                       break;
+               line[len] = '\0';
+       }
+
        s = line;
        /* Get the keyword. (Each line is supposed to begin with a keyword). */
        keyword = strdelim(&s);
@@ -313,6 +309,20 @@ process_config_line(Options *options, const char *host,
                /* don't panic, but count bad options */
                return -1;
                /* NOTREACHED */
+       case oConnectTimeout:
+               intptr = &options->connection_timeout;
+/* parse_time: */
+               arg = strdelim(&s);
+               if (!arg || *arg == '\0')
+                       fatal("%s line %d: missing time value.",
+                           filename, linenum);
+               if ((value = convtime(arg)) == -1)
+                       fatal("%s line %d: invalid time value.",
+                           filename, linenum);
+               if (*intptr == -1)
+                       *intptr = value;
+               break;
+
        case oForwardAgent:
                intptr = &options->forward_agent;
 parse_flag:
@@ -342,10 +352,6 @@ parse_flag:
                intptr = &options->use_privileged_port;
                goto parse_flag;
 
-       case oRhostsAuthentication:
-               intptr = &options->rhosts_authentication;
-               goto parse_flag;
-
        case oPasswordAuthentication:
                intptr = &options->password_authentication;
                goto parse_flag;
@@ -377,16 +383,11 @@ parse_flag:
        case oChallengeResponseAuthentication:
                intptr = &options->challenge_response_authentication;
                goto parse_flag;
-#if defined(KRB4) || defined(KRB5)
-       case oKerberosAuthentication:
-               intptr = &options->kerberos_authentication;
-               goto parse_flag;
-#endif
-#ifdef GSSAPI
+
        case oGssAuthentication:
                intptr = &options->gss_authentication;
                goto parse_flag;
-      
+
        case oGssKeyEx:
                intptr = &options->gss_keyex;
                goto parse_flag;
@@ -394,25 +395,7 @@ parse_flag:
        case oGssDelegateCreds:
                intptr = &options->gss_deleg_creds;
                goto parse_flag;
-#ifdef GSI
-       case oGssGlobusDelegateLimitedCreds:
-               intptr = &options->gss_globus_deleg_limited_proxy;
-               goto parse_flag;
-#endif /* GSI */
-
-#endif /* GSSAPI */
 
-#if defined(AFS) || defined(KRB5)
-       case oKerberosTgtPassing:
-               intptr = &options->kerberos_tgt_passing;
-               goto parse_flag;
-#endif
-#ifdef AFS
-       case oAFSTokenPassing:
-               intptr = &options->afs_token_passing;
-               goto parse_flag;
-#endif
        case oBatchMode:
                intptr = &options->batch_mode;
                goto parse_flag;
@@ -421,6 +404,10 @@ parse_flag:
                intptr = &options->check_host_ip;
                goto parse_flag;
 
+       case oVerifyHostKeyDNS:
+               intptr = &options->verify_host_key_dns;
+               goto parse_flag;
+
        case oStrictHostKeyChecking:
                intptr = &options->strict_host_key_checking;
                arg = strdelim(&s);
@@ -460,6 +447,31 @@ parse_flag:
                intptr = &options->compression_level;
                goto parse_int;
 
+       case oRekeyLimit:
+               intptr = &options->rekey_limit;
+               arg = strdelim(&s);
+               if (!arg || *arg == '\0')
+                       fatal("%.200s line %d: Missing argument.", filename, linenum);
+               if (arg[0] < '0' || arg[0] > '9')
+                       fatal("%.200s line %d: Bad number.", filename, linenum);
+               value = strtol(arg, &endofnumber, 10);
+               if (arg == endofnumber)
+                       fatal("%.200s line %d: Bad number.", filename, linenum);
+               switch (toupper(*endofnumber)) {
+               case 'K':
+                       value *= 1<<10;
+                       break;
+               case 'M':
+                       value *= 1<<20;
+                       break;
+               case 'G':
+                       value *= 1<<30;
+                       break;
+               }
+               if (*activep && *intptr == -1)
+                       *intptr = value;
+               break;
+
        case oIdentityFile:
                arg = strdelim(&s);
                if (!arg || *arg == '\0')
@@ -526,6 +538,8 @@ parse_string:
                goto parse_string;
 
        case oProxyCommand:
+               if (s == NULL)
+                       fatal("%.200s line %d: Missing argument.", filename, linenum);
                charptr = &options->proxy_command;
                len = strspn(s, WHITESPACE "=");
                if (*activep && *charptr == NULL)
@@ -663,7 +677,7 @@ parse_int:
                        fatal("%.200s line %d: Badly formatted port number.",
                            filename, linenum);
                if (*activep)
-                       add_local_forward(options, fwd_port, "socks4", 0);
+                       add_local_forward(options, fwd_port, "socks", 0);
                break;
 
        case oClearAllForwardings:
@@ -703,6 +717,21 @@ parse_int:
                        *intptr = value;
                break;
 
+       case oAddressFamily:
+               arg = strdelim(&s);
+               intptr = &options->address_family;
+               if (strcasecmp(arg, "inet") == 0)
+                       value = AF_INET;
+               else if (strcasecmp(arg, "inet6") == 0)
+                       value = AF_INET6;
+               else if (strcasecmp(arg, "any") == 0)
+                       value = AF_UNSPEC;
+               else
+                       fatal("Unsupported AddressFamily \"%s\"", arg);
+               if (*activep && *intptr == -1)
+                       *intptr = value;
+               break;
+
        case oEnableSSHKeysign:
                intptr = &options->enable_ssh_keysign;
                goto parse_flag;
@@ -712,6 +741,11 @@ parse_int:
                    filename, linenum, keyword);
                return 0;
 
+       case oUnsupported:
+               error("%s line %d: Unsupported option \"%s\"",
+                   filename, linenum, keyword);
+               return 0;
+
        default:
                fatal("process_config_line: Unimplemented opcode %d", opcode);
        }
@@ -781,28 +815,12 @@ initialize_options(Options * options)
        options->xauth_location = NULL;
        options->gateway_ports = -1;
        options->use_privileged_port = -1;
-       options->rhosts_authentication = -1;
        options->rsa_authentication = -1;
        options->pubkey_authentication = -1;
        options->challenge_response_authentication = -1;
-#ifdef GSSAPI
-        options->gss_authentication = -1;
+       options->gss_authentication = -1;
        options->gss_keyex = -1;
-        options->gss_deleg_creds = -1;
-#ifdef GSI
-        options->gss_globus_deleg_limited_proxy = -1;
-#endif /* GSI */
-#endif /* GSSAPI */
-
-#if defined(KRB4) || defined(KRB5)
-       options->kerberos_authentication = -1;
-#endif
-#if defined(AFS) || defined(KRB5)
-       options->kerberos_tgt_passing = -1;
-#endif
-#ifdef AFS
-       options->afs_token_passing = -1;
-#endif
+       options->gss_deleg_creds = -1;
        options->password_authentication = -1;
        options->kbd_interactive_authentication = -1;
        options->kbd_interactive_devices = NULL;
@@ -815,7 +833,9 @@ initialize_options(Options * options)
        options->keepalives = -1;
        options->compression_level = -1;
        options->port = -1;
+       options->address_family = -1;
        options->connection_attempts = -1;
+       options->connection_timeout = -1;
        options->number_of_password_prompts = -1;
        options->cipher = -1;
        options->ciphers = NULL;
@@ -841,6 +861,8 @@ initialize_options(Options * options)
        options->smartcard_device = NULL;
        options->enable_ssh_keysign = - 1;
        options->no_host_authentication_for_localhost = - 1;
+       options->rekey_limit = - 1;
+       options->verify_host_key_dns = -1;
 }
 
 /*
@@ -863,38 +885,18 @@ fill_default_options(Options * options)
                options->gateway_ports = 0;
        if (options->use_privileged_port == -1)
                options->use_privileged_port = 0;
-       if (options->rhosts_authentication == -1)
-               options->rhosts_authentication = 0;
        if (options->rsa_authentication == -1)
                options->rsa_authentication = 1;
        if (options->pubkey_authentication == -1)
                options->pubkey_authentication = 1;
        if (options->challenge_response_authentication == -1)
                options->challenge_response_authentication = 1;
-#ifdef GSSAPI
        if (options->gss_authentication == -1)
                options->gss_authentication = 1;
        if (options->gss_keyex == -1)
                options->gss_keyex = 1;
        if (options->gss_deleg_creds == -1)
                options->gss_deleg_creds = 1;
-#ifdef GSI
-       if (options->gss_globus_deleg_limited_proxy == -1)
-               options->gss_globus_deleg_limited_proxy = 0;
-#endif /* GSI */
-#endif /* GSSAPI */
-#if defined(KRB4) || defined(KRB5)
-       if (options->kerberos_authentication == -1)
-               options->kerberos_authentication = 1;
-#endif
-#if defined(AFS) || defined(KRB5)
-       if (options->kerberos_tgt_passing == -1)
-               options->kerberos_tgt_passing = 1;
-#endif
-#ifdef AFS
-       if (options->afs_token_passing == -1)
-               options->afs_token_passing = 1;
-#endif
        if (options->password_authentication == -1)
                options->password_authentication = 1;
        if (options->kbd_interactive_authentication == -1)
@@ -917,6 +919,8 @@ fill_default_options(Options * options)
                options->compression_level = 6;
        if (options->port == -1)
                options->port = 0;      /* Filled in ssh_connect. */
+       if (options->address_family == -1)
+               options->address_family = AF_UNSPEC;
        if (options->connection_attempts == -1)
                options->connection_attempts = 1;
        if (options->number_of_password_prompts == -1)
@@ -969,6 +973,10 @@ fill_default_options(Options * options)
                options->no_host_authentication_for_localhost = 0;
        if (options->enable_ssh_keysign == -1)
                options->enable_ssh_keysign = 0;
+       if (options->rekey_limit == -1)
+               options->rekey_limit = 0;
+       if (options->verify_host_key_dns == -1)
+               options->verify_host_key_dns = 0;
        /* 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 851382d5321c4735ef269d4ed5b0c43303b8c376..61e0e3771e24a498fd45bda7e800aed6a6397758 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: readconf.h,v 1.46 2003/04/01 10:22:21 markus Exp $    */
+/*     $OpenBSD: readconf.h,v 1.55 2003/09/01 18:15:50 markus Exp $    */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -33,7 +33,6 @@ typedef struct {
        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. */
-       int     rhosts_authentication;  /* Try rhosts authentication. */
        int     rhosts_rsa_authentication;      /* Try rhosts with RSA
                                                 * authentication. */
        int     rsa_authentication;     /* Try RSA authentication. */
@@ -41,25 +40,9 @@ typedef struct {
        int     hostbased_authentication;       /* ssh2's rhosts_rsa */
        int     challenge_response_authentication;
                                        /* Try S/Key or TIS, authentication. */
-#if defined(KRB4) || defined(KRB5)
-       int     kerberos_authentication;        /* Try Kerberos authentication. */
-#endif
-#if defined(AFS) || defined(KRB5)
-       int     kerberos_tgt_passing;   /* Try Kerberos TGT passing. */
-#endif
-
-#ifdef GSSAPI
-       int     gss_authentication;
+       int     gss_authentication;     /* Try GSS authentication */
        int     gss_keyex;
-       int     gss_deleg_creds;
-#ifdef GSI
-       int     gss_globus_deleg_limited_proxy;
-#endif /* GSI */
-#endif /* GSSAPI */
-
-#ifdef AFS
-       int     afs_token_passing;      /* Try AFS token passing. */
-#endif
+       int     gss_deleg_creds;        /* Delegate GSS credentials */
        int     password_authentication;        /* Try password
                                                 * authentication. */
        int     kbd_interactive_authentication; /* Try keyboard-interactive auth. */
@@ -74,8 +57,11 @@ typedef struct {
        LogLevel log_level;     /* Level for logging. */
 
        int     port;           /* Port to connect. */
+       int     address_family;
        int     connection_attempts;    /* Max attempts (seconds) before
                                         * giving up */
+       int     connection_timeout;     /* Max time (seconds) before
+                                        * aborting connection attempt */
        int     number_of_password_prompts;     /* Max number of password
                                                 * prompts. */
        int     cipher;         /* Cipher to use. */
@@ -98,6 +84,7 @@ typedef struct {
        char   *preferred_authentications;
        char   *bind_address;   /* local socket address for connection to sshd */
        char   *smartcard_device; /* Smartcard reader device */
+       int     verify_host_key_dns;    /* Verify host key using DNS */
 
        int     num_identity_files;     /* Number of files for RSA/DSA identities. */
        char   *identity_files[SSH_MAX_IDENTITY_FILES];
@@ -113,6 +100,7 @@ typedef struct {
        int     clear_forwardings;
 
        int     enable_ssh_keysign;
+       int     rekey_limit;
        int     no_host_authentication_for_localhost;
 }       Options;
 
diff --git a/openssh/regress/authorized_keys_root b/openssh/regress/authorized_keys_root
deleted file mode 100644 (file)
index 3285371..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAt6ttBacbgvLPsF1VWWfT51t55/5Mj62Xp8EaoH5SNSaLiGIgrrja077lKEept75U4uKFUYU5JJX9GPE9A7Y43LXv+/A6Jm4rEj/U0s4H8tf0UmzVC3t6xh0sRK0hYVNILyoHnIAgdY8CmOiybw7p6DxJY8MRAehD3n9+kFcachU= root@xenon
-1024 35 132789427207755621599908461558918671787816692978751485815532032934821830960131244604702969298486352138126114080367609979552547448841583955126231410604842765726397407176910594168641969541792069550006878863592030567875913190224374005367884774859544943329148178663694126456638431428703289837638970464685771819219 root@xenon
diff --git a/openssh/regress/copy.1 b/openssh/regress/copy.1
deleted file mode 100755 (executable)
index 92d4d20..0000000
Binary files a/openssh/regress/copy.1 and /dev/null differ
diff --git a/openssh/regress/copy.2 b/openssh/regress/copy.2
deleted file mode 100755 (executable)
index 92d4d20..0000000
Binary files a/openssh/regress/copy.2 and /dev/null differ
index dd21de39ab296ed4b3a3a969f6b74352fb63349e..2489fec457da5f90e2a2b77fe3c3c12d0111e44f 100644 (file)
@@ -89,6 +89,12 @@ sc_init(void)
        r = sc_establish_context(&ctx, "openssh");
        if (r)
                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, 
+                   ctx->reader_count -1);
+               goto err;
+       }
        r = sc_connect_card(ctx->reader[sc_reader_id], 0, &card);
        if (r)
                goto err;
@@ -104,7 +110,8 @@ err:
 /* private key operations */
 
 static int
-sc_prkey_op_init(RSA *rsa, struct sc_pkcs15_object **key_obj_out)
+sc_prkey_op_init(RSA *rsa, struct sc_pkcs15_object **key_obj_out,
+       unsigned int usage)
 {
        int r;
        struct sc_priv_data *priv;
@@ -124,7 +131,8 @@ sc_prkey_op_init(RSA *rsa, struct sc_pkcs15_object **key_obj_out)
                        goto err;
                }
        }
-       r = sc_pkcs15_find_prkey_by_id(p15card, &priv->cert_id, &key_obj);
+       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",
                      sc_strerror(r));
@@ -133,7 +141,16 @@ sc_prkey_op_init(RSA *rsa, struct sc_pkcs15_object **key_obj_out)
        key = key_obj->data;
        r = sc_pkcs15_find_pin_by_auth_id(p15card, &key_obj->auth_id,
                                          &pin_obj);
-       if (r) {
+       if (r == SC_ERROR_OBJECT_NOT_FOUND) {
+               /* no pin required */
+               r = sc_lock(card);
+               if (r) {
+                       error("Unable to lock smartcard: %s", sc_strerror(r));
+                       goto err;
+               }
+               *key_obj_out = key_obj;
+               return 0;
+       } else if (r) {
                error("Unable to find PIN object from SmartCard: %s",
                      sc_strerror(r));
                goto err;
@@ -161,6 +178,9 @@ err:
        return -1;
 }
 
+#define SC_USAGE_DECRYPT       SC_PKCS15_PRKEY_USAGE_DECRYPT | \
+                               SC_PKCS15_PRKEY_USAGE_UNWRAP
+
 static int
 sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa,
     int padding)
@@ -170,10 +190,11 @@ sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa,
 
        if (padding != RSA_PKCS1_PADDING)
                return -1;      
-       r = sc_prkey_op_init(rsa, &key_obj);
+       r = sc_prkey_op_init(rsa, &key_obj, SC_USAGE_DECRYPT);
        if (r)
                return -1;
-       r = sc_pkcs15_decipher(p15card, key_obj, 0, from, flen, to, flen);
+       r = sc_pkcs15_decipher(p15card, key_obj, SC_ALGORITHM_RSA_PAD_PKCS1, 
+           from, flen, to, flen);
        sc_unlock(card);
        if (r < 0) {
                error("sc_pkcs15_decipher() failed: %s", sc_strerror(r));
@@ -185,6 +206,9 @@ err:
        return -1;
 }
 
+#define SC_USAGE_SIGN          SC_PKCS15_PRKEY_USAGE_SIGN | \
+                               SC_PKCS15_PRKEY_USAGE_SIGNRECOVER
+
 static int
 sc_sign(int type, u_char *m, unsigned int m_len,
        unsigned char *sigret, unsigned int *siglen, RSA *rsa)
@@ -193,7 +217,15 @@ sc_sign(int type, u_char *m, unsigned int m_len,
        int r;
        unsigned long flags = 0;
 
-       r = sc_prkey_op_init(rsa, &key_obj);
+       /* XXX: sc_prkey_op_init will search for a pkcs15 private
+        * key object with the sign or signrecover usage flag set.
+        * If the signing key has only the non-repudiation flag set
+        * 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. 
+        */
+       r = sc_prkey_op_init(rsa, &key_obj, SC_USAGE_SIGN);
        if (r)
                return -1;
        /* FIXME: length of sigret correct? */
@@ -321,7 +353,7 @@ sc_read_pubkey(Key * k, const struct sc_pkcs15_object *cert_obj)
        debug("sc_read_pubkey() with cert id %02X", cinfo->id.value[0]);
        r = sc_pkcs15_read_certificate(p15card, cinfo, &cert);
        if (r) {
-               log("Certificate read failed: %s", sc_strerror(r));
+               logit("Certificate read failed: %s", sc_strerror(r));
                goto err;
        }
        x509 = X509_new();
@@ -331,7 +363,7 @@ sc_read_pubkey(Key * k, const struct sc_pkcs15_object *cert_obj)
        }
        p = cert->data;
        if (!d2i_X509(&x509, &p, cert->data_len)) {
-               log("Unable to parse X.509 certificate");
+               logit("Unable to parse X.509 certificate");
                r = -1;
                goto err;
        }
@@ -341,7 +373,7 @@ sc_read_pubkey(Key * k, const struct sc_pkcs15_object *cert_obj)
        X509_free(x509);
        x509 = NULL;
        if (pubkey->type != EVP_PKEY_RSA) {
-               log("Public key is of unknown type");
+               logit("Public key is of unknown type");
                r = -1;
                goto err;
        }
@@ -413,7 +445,7 @@ sc_get_keys(const char *id, const char *pin)
                r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_CERT_X509,
                                          certs, 32);
                if (r == 0) {
-                       log("No certificates found on smartcard");
+                       logit("No certificates found on smartcard");
                        r = -1;
                        goto err;
                } else if (r < 0) {
@@ -423,9 +455,14 @@ sc_get_keys(const char *id, const char *pin)
                }
                key_count = r;
        }
-       /* FIXME: only keep entries with a corresponding private key */
        keys = xmalloc(sizeof(Key *) * (key_count*2+1));
        for (i = 0; i < key_count; i++) {
+               sc_pkcs15_object_t *tmp_obj = NULL;
+               cert_id = ((sc_pkcs15_cert_info_t *)(certs[i]->data))->id;
+               if (sc_pkcs15_find_prkey_by_id(p15card, &cert_id, &tmp_obj))
+                       /* skip the public key (certificate) if no
+                        * corresponding private key is present */
+                       continue;
                k = key_new(KEY_RSA);
                if (k == NULL)
                        break;
@@ -459,4 +496,30 @@ sc_put_key(Key *prv, const char *id)
        return -1;
 }
 
+char *
+sc_get_key_label(Key *key)
+{
+       int r;
+       const struct sc_priv_data *priv;
+       struct sc_pkcs15_object *key_obj;
+
+       priv = (const struct sc_priv_data *) RSA_get_app_data(key->rsa);
+       if (priv == NULL || p15card == NULL) {
+               logit("SmartCard key not loaded");
+               /* internal error => return default label */
+               return xstrdup("smartcard key");
+       }
+       r = sc_pkcs15_find_prkey_by_id(p15card, &priv->cert_id, &key_obj);
+       if (r) {
+               logit("Unable to find private key from SmartCard: %s",
+                     sc_strerror(r));
+               return xstrdup("smartcard key");
+       }
+       if (key_obj == NULL || key_obj->label == NULL)
+               /* the optional PKCS#15 label does not exists
+                * => return the default label */
+               return xstrdup("smartcard key");
+       return xstrdup(key_obj->label);
+}
+
 #endif /* SMARTCARD */
index 12b7b835d63d96cc84027599be5e5e61c931745c..56f5f446f3bc54527113d88aa14fc97ad81e9ac1 100644 (file)
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: servconf.c,v 1.116 2003/02/21 09:05:53 markus Exp $");
-
-#if defined(KRB4)
-#include <krb.h>
-#endif
-#if defined(KRB5)
-#ifdef HEIMDAL
-#else
-/* Bodge - but then, so is using the kerberos IV KEYFILE to get a Kerberos V
- * keytab */
-#define KEYFILE "/etc/krb5.keytab"
-#endif
-#endif
-#ifdef AFS
-#include <kafs.h>
-#endif
+RCSID("$OpenBSD: servconf.c,v 1.127 2003/09/01 18:15:50 markus Exp $");
 
 #include "ssh.h"
 #include "log.h"
@@ -55,7 +40,7 @@ initialize_server_options(ServerOptions *options)
        memset(options, 0, sizeof(*options));
 
        /* Portable-specific options */
-       options->pam_authentication_via_kbd_int = -1;
+       options->use_pam = -1;
 
        /* Standard Options */
        options->num_ports = 0;
@@ -79,34 +64,23 @@ initialize_server_options(ServerOptions *options)
        options->keepalives = -1;
        options->log_facility = SYSLOG_FACILITY_NOT_SET;
        options->log_level = SYSLOG_LEVEL_NOT_SET;
-       options->rhosts_authentication = -1;
        options->rhosts_rsa_authentication = -1;
        options->hostbased_authentication = -1;
        options->hostbased_uses_name_from_packet_only = -1;
        options->rsa_authentication = -1;
        options->pubkey_authentication = -1;
-#ifdef GSSAPI
-       options->gss_authentication=-1;
-       options->gss_keyex=-1;
-       options->gss_use_session_ccache = -1;
-       options->gss_cleanup_creds = -1;
-#endif
-#if defined(KRB4) || defined(KRB5)
        options->kerberos_authentication = -1;
        options->kerberos_or_local_passwd = -1;
        options->kerberos_ticket_cleanup = -1;
-#endif
-#if defined(AFS) || defined(KRB5)
-       options->kerberos_tgt_passing = -1;
-#endif
-#ifdef AFS
-       options->afs_token_passing = -1;
-#endif
 #ifdef  SESSION_HOOKS
         options->session_hooks_allow = -1;
         options->session_hooks_startup_cmd = NULL;
         options->session_hooks_shutdown_cmd = NULL;
 #endif
+       options->gss_authentication=-1;
+       options->gss_keyex=-1;
+       options->gss_use_session_ccache = -1;
+       options->gss_cleanup_creds = -1;
        options->password_authentication = -1;
        options->kbd_interactive_authentication = -1;
        options->challenge_response_authentication = -1;
@@ -128,7 +102,7 @@ initialize_server_options(ServerOptions *options)
        options->max_startups_rate = -1;
        options->max_startups = -1;
        options->banner = NULL;
-       options->verify_reverse_mapping = -1;
+       options->use_dns = -1;
        options->client_alive_interval = -1;
        options->client_alive_count_max = -1;
        options->authorized_keys_file = NULL;
@@ -142,8 +116,8 @@ void
 fill_default_server_options(ServerOptions *options)
 {
        /* Portable-specific options */
-       if (options->pam_authentication_via_kbd_int == -1)
-               options->pam_authentication_via_kbd_int = 0;
+       if (options->use_pam == -1)
+               options->use_pam = 1;
 
        /* Standard Options */
        if (options->protocol == SSH_PROTO_UNKNOWN)
@@ -198,8 +172,6 @@ fill_default_server_options(ServerOptions *options)
                options->log_facility = SYSLOG_FACILITY_AUTH;
        if (options->log_level == SYSLOG_LEVEL_NOT_SET)
                options->log_level = SYSLOG_LEVEL_INFO;
-       if (options->rhosts_authentication == -1)
-               options->rhosts_authentication = 0;
        if (options->rhosts_rsa_authentication == -1)
                options->rhosts_rsa_authentication = 0;
        if (options->hostbased_authentication == -1)
@@ -210,40 +182,20 @@ fill_default_server_options(ServerOptions *options)
                options->rsa_authentication = 1;
        if (options->pubkey_authentication == -1)
                options->pubkey_authentication = 1;
-#ifdef GSSAPI
+       if (options->kerberos_authentication == -1)
+               options->kerberos_authentication = 0;
+       if (options->kerberos_or_local_passwd == -1)
+               options->kerberos_or_local_passwd = 1;
+       if (options->kerberos_ticket_cleanup == -1)
+               options->kerberos_ticket_cleanup = 1;
        if (options->gss_authentication == -1)
                options->gss_authentication = 1;
        if (options->gss_keyex == -1)
-               options->gss_keyex =1;
+               options->gss_keyex = 1;
        if (options->gss_use_session_ccache == -1)
                options->gss_use_session_ccache = 1;
        if (options->gss_cleanup_creds == -1)
                options->gss_cleanup_creds = 1;
-#endif
-#if defined(KRB4) || defined(KRB5)
-       if (options->kerberos_authentication == -1)
-               options->kerberos_authentication = 0;
-       if (options->kerberos_or_local_passwd == -1)
-               options->kerberos_or_local_passwd = 1;
-       if (options->kerberos_ticket_cleanup == -1)
-               options->kerberos_ticket_cleanup = 1;
-#endif
-#if defined(AFS) || defined(KRB5)
-       if (options->kerberos_tgt_passing == -1)
-               options->kerberos_tgt_passing = 0;
-#endif
-#ifdef AFS
-       if (options->afs_token_passing == -1)
-               options->afs_token_passing = 0;
-#endif
-#ifdef SESSION_HOOKS
-        if (options->session_hooks_allow == -1)
-        {
-            options->session_hooks_allow = 0;
-            options->session_hooks_startup_cmd = NULL;
-            options->session_hooks_shutdown_cmd = NULL;
-        }
-#endif
        if (options->password_authentication == -1)
                options->password_authentication = 1;
        if (options->kbd_interactive_authentication == -1)
@@ -268,8 +220,8 @@ fill_default_server_options(ServerOptions *options)
                options->max_startups_rate = 100;               /* 100% */
        if (options->max_startups_begin == -1)
                options->max_startups_begin = options->max_startups;
-       if (options->verify_reverse_mapping == -1)
-               options->verify_reverse_mapping = 0;
+       if (options->use_dns == -1)
+               options->use_dns = 1;
        if (options->client_alive_interval == -1)
                options->client_alive_interval = 0;
        if (options->client_alive_count_max == -1)
@@ -303,27 +255,16 @@ fill_default_server_options(ServerOptions *options)
 typedef enum {
        sBadOption,             /* == unknown option */
        /* Portable-specific options */
-       sPAMAuthenticationViaKbdInt,
+       sUsePAM,
        /* Standard Options */
        sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
        sPermitRootLogin, sLogFacility, sLogLevel,
-       sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
-#ifdef GSSAPI
-       sGssAuthentication, sGssKeyEx, sGssUseSessionCredCache, sGssCleanupCreds,
-#endif
-#if defined(KRB4) || defined(KRB5)
+       sRhostsRSAAuthentication, sRSAAuthentication,
        sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
-#endif
-#if defined(AFS) || defined(KRB5)
-       sKerberosTgtPassing,
-#endif
-#ifdef AFS
-       sAFSTokenPassing,
-#endif
+       sKerberosTgtPassing, sChallengeResponseAuthentication,
 #ifdef SESSION_HOOKS
         sAllowSessionHooks, sSessionHookStartupCmd, sSessionHookShutdownCmd,
 #endif
-       sChallengeResponseAuthentication,
        sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
        sPrintMotd, sPrintLastLog, sIgnoreRhosts,
        sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
@@ -332,11 +273,12 @@ typedef enum {
        sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
        sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
        sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
-       sBanner, sVerifyReverseMapping, sHostbasedAuthentication,
+       sBanner, sUseDNS, sHostbasedAuthentication,
        sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
        sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
+       sGssAuthentication, sGssKeyEx, sGssUseSessionCredCache, sGssCleanupCreds,
        sUsePrivilegeSeparation,
-       sDeprecated
+       sDeprecated, sUnsupported
 } ServerOpCodes;
 
 /* Textual representation of the tokens. */
@@ -345,7 +287,12 @@ static struct {
        ServerOpCodes opcode;
 } keywords[] = {
        /* Portable-specific options */
-       { "PAMAuthenticationViaKbdInt", sPAMAuthenticationViaKbdInt },
+#ifdef USE_PAM
+       { "usepam", sUsePAM },
+#else
+       { "usepam", sUnsupported },
+#endif
+       { "pamauthenticationviakbdint", sDeprecated },
        /* Standard Options */
        { "port", sPort },
        { "hostkey", sHostKeyFile },
@@ -357,30 +304,36 @@ static struct {
        { "permitrootlogin", sPermitRootLogin },
        { "syslogfacility", sLogFacility },
        { "loglevel", sLogLevel },
-       { "rhostsauthentication", sRhostsAuthentication },
+       { "rhostsauthentication", sDeprecated },
        { "rhostsrsaauthentication", sRhostsRSAAuthentication },
        { "hostbasedauthentication", sHostbasedAuthentication },
        { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
        { "rsaauthentication", sRSAAuthentication },
        { "pubkeyauthentication", sPubkeyAuthentication },
        { "dsaauthentication", sPubkeyAuthentication },                 /* alias */
+#ifdef KRB5
+       { "kerberosauthentication", sKerberosAuthentication },
+       { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
+       { "kerberosticketcleanup", sKerberosTicketCleanup },
+#else
+       { "kerberosauthentication", sUnsupported },
+       { "kerberosorlocalpasswd", sUnsupported },
+       { "kerberosticketcleanup", sUnsupported },
+#endif
+       { "kerberostgtpassing", sUnsupported },
+       { "afstokenpassing", sUnsupported },
 #ifdef GSSAPI
        { "gssapiauthentication", sGssAuthentication },
        { "gssapikeyexchange", sGssKeyEx },
        { "gssusesessionccache", sGssUseSessionCredCache },
        { "gssapiusesessioncredcache", sGssUseSessionCredCache },
        { "gssapicleanupcreds", sGssCleanupCreds },
-#endif
-#if defined(KRB4) || defined(KRB5)
-       { "kerberosauthentication", sKerberosAuthentication },
-       { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
-       { "kerberosticketcleanup", sKerberosTicketCleanup },
-#endif
-#if defined(AFS) || defined(KRB5)
-       { "kerberostgtpassing", sKerberosTgtPassing },
-#endif
-#ifdef AFS
-       { "afstokenpassing", sAFSTokenPassing },
+#else
+       { "gssapiauthentication", sUnsupported },
+       { "gssapikeyexchange", sUnsupported },
+       { "gssusesessionccache", sUnsupported },
+       { "gssapiusesessioncredcache", sUnsupported },
+       { "gssapicleanupcreds", sUnsupported },
 #endif
 #ifdef SESSION_HOOKS
         { "allowsessionhooks", sAllowSessionHooks },
@@ -419,8 +372,9 @@ static struct {
        { "subsystem", sSubsystem },
        { "maxstartups", sMaxStartups },
        { "banner", sBanner },
-       { "verifyreversemapping", sVerifyReverseMapping },
-       { "reversemappingcheck", sVerifyReverseMapping },
+       { "usedns", sUseDNS },
+       { "verifyreversemapping", sDeprecated },
+       { "reversemappingcheck", sDeprecated },
        { "clientaliveinterval", sClientAliveInterval },
        { "clientalivecountmax", sClientAliveCountMax },
        { "authorizedkeysfile", sAuthorizedKeysFile },
@@ -504,8 +458,8 @@ process_server_config_line(ServerOptions *options, char *line,
        opcode = parse_token(arg, filename, linenum);
        switch (opcode) {
        /* Portable-specific options */
-       case sPAMAuthenticationViaKbdInt:
-               intptr = &options->pam_authentication_via_kbd_int;
+       case sUsePAM:
+               intptr = &options->use_pam;
                goto parse_flag;
 
        /* Standard Options */
@@ -668,10 +622,6 @@ parse_flag:
                intptr = &options->ignore_user_known_hosts;
                goto parse_flag;
 
-       case sRhostsAuthentication:
-               intptr = &options->rhosts_authentication;
-               goto parse_flag;
-
        case sRhostsRSAAuthentication:
                intptr = &options->rhosts_rsa_authentication;
                goto parse_flag;
@@ -691,21 +641,7 @@ parse_flag:
        case sPubkeyAuthentication:
                intptr = &options->pubkey_authentication;
                goto parse_flag;
-#ifdef GSSAPI
-       case sGssAuthentication:
-               intptr = &options->gss_authentication;
-               goto parse_flag;
-       case sGssKeyEx:
-               intptr = &options->gss_keyex;
-               goto parse_flag;
-       case sGssUseSessionCredCache:
-               intptr = &options->gss_use_session_ccache;
-               goto parse_flag;
-       case sGssCleanupCreds:
-               intptr = &options->gss_cleanup_creds;
-               goto parse_flag;
-#endif
-#if defined(KRB4) || defined(KRB5)
+
        case sKerberosAuthentication:
                intptr = &options->kerberos_authentication;
                goto parse_flag;
@@ -717,17 +653,23 @@ parse_flag:
        case sKerberosTicketCleanup:
                intptr = &options->kerberos_ticket_cleanup;
                goto parse_flag;
-#endif
-#if defined(AFS) || defined(KRB5)
-       case sKerberosTgtPassing:
-               intptr = &options->kerberos_tgt_passing;
+
+       case sGssAuthentication:
+               intptr = &options->gss_authentication;
                goto parse_flag;
-#endif
-#ifdef AFS
-       case sAFSTokenPassing:
-               intptr = &options->afs_token_passing;
+
+       case sGssKeyEx:
+               intptr = &options->gss_keyex;
                goto parse_flag;
-#endif
+
+       case sGssUseSessionCredCache:
+               intptr = &options->gss_use_session_ccache;
+               goto parse_flag;
+
+       case sGssCleanupCreds:
+               intptr = &options->gss_cleanup_creds;
+               goto parse_flag;
+
 #ifdef SESSION_HOOKS
         case sAllowSessionHooks:
                 intptr = &options->session_hooks_allow;
@@ -744,6 +686,7 @@ parse_flag:
                     options->session_hooks_shutdown_cmd = strdup(arg);
                 break;
 #endif                  
+
        case sPasswordAuthentication:
                intptr = &options->password_authentication;
                goto parse_flag;
@@ -808,8 +751,8 @@ parse_flag:
                intptr = &options->gateway_ports;
                goto parse_flag;
 
-       case sVerifyReverseMapping:
-               intptr = &options->verify_reverse_mapping;
+       case sUseDNS:
+               intptr = &options->use_dns;
                goto parse_flag;
 
        case sLogFacility:
@@ -985,7 +928,14 @@ parse_flag:
                goto parse_int;
 
        case sDeprecated:
-               log("%s line %d: Deprecated option %s",
+               logit("%s line %d: Deprecated option %s",
+                   filename, linenum, arg);
+               while (arg)
+                   arg = strdelim(&cp);
+               break;
+
+       case sUnsupported:
+               logit("%s line %d: Unsupported option %s",
                    filename, linenum, arg);
                while (arg)
                    arg = strdelim(&cp);
index 98cdda4c7a12db815f5693473ac7bf4fdc8ba2d7..c92c0e4cda3c8bd8b4a12e1fe8475b67e02578e0 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: servconf.h,v 1.59 2002/07/30 17:03:55 markus Exp $    */
+/*     $OpenBSD: servconf.h,v 1.65 2003/09/01 18:15:50 markus Exp $    */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -65,22 +65,12 @@ typedef struct {
        int     gateway_ports;  /* If true, allow remote connects to forwarded ports. */
        SyslogFacility log_facility;    /* Facility for system logging. */
        LogLevel log_level;     /* Level for system logging. */
-       int     rhosts_authentication;  /* If true, permit rhosts
-                                        * authentication. */
        int     rhosts_rsa_authentication;      /* If true, permit rhosts RSA
                                                 * authentication. */
        int     hostbased_authentication;       /* If true, permit ssh2 hostbased auth */
        int     hostbased_uses_name_from_packet_only; /* experimental */
        int     rsa_authentication;     /* If true, permit RSA authentication. */
        int     pubkey_authentication;  /* If true, permit ssh2 pubkey authentication. */
-       #ifdef GSSAPI
-       int     gss_authentication;
-       int     gss_keyex;
-       int     gss_use_session_ccache;        /* If true, delegated credentials are
-                                               * stored in a session specific cache */
-       int     gss_cleanup_creds;             /* If true, destroy cred cache on logout */
-#endif 
-#if defined(KRB4) || defined(KRB5)
        int     kerberos_authentication;        /* If true, permit Kerberos
                                                 * authentication. */
        int     kerberos_or_local_passwd;       /* If true, permit kerberos
@@ -90,19 +80,16 @@ typedef struct {
                                                 * /etc/passwd */
        int     kerberos_ticket_cleanup;        /* If true, destroy ticket
                                                 * file on logout. */
-#endif
-#if defined(AFS) || defined(KRB5)
-       int     kerberos_tgt_passing;   /* If true, permit Kerberos TGT
-                                        * passing. */
-#endif
-#ifdef AFS
-       int     afs_token_passing;      /* If true, permit AFS token passing. */
-#endif
 #ifdef SESSION_HOOKS
         int     session_hooks_allow;        /* If true, permit user hooks */
         char*   session_hooks_startup_cmd;  /* cmd to be executed before */
         char*   session_hooks_shutdown_cmd; /* cmd to be executed after */
 #endif
+       int     gss_authentication;     /* If true, permit GSSAPI authentication */
+       int     gss_keyex;
+       int     gss_use_session_ccache;        /* If true, delegated credentials are
+                                               * stored in a session specific cache */
+       int     gss_cleanup_creds;      /* If true, destroy cred cache on logout */
        int     password_authentication;        /* If true, permit password
                                                 * authentication. */
        int     kbd_interactive_authentication; /* If true, permit */
@@ -130,7 +117,7 @@ typedef struct {
        int     max_startups_rate;
        int     max_startups;
        char   *banner;                 /* SSH-2 banner message */
-       int     verify_reverse_mapping; /* cross-check ip and dns */
+       int     use_dns;
        int     client_alive_interval;  /*
                                         * poke the client this often to
                                         * see if it's still there
@@ -143,7 +130,7 @@ typedef struct {
 
        char   *authorized_keys_file;   /* File containing public keys */
        char   *authorized_keys_file2;
-       int     pam_authentication_via_kbd_int;
+       int     use_pam;                /* Enable auth via PAM */
 }       ServerOptions;
 
 void    initialize_server_options(ServerOptions *);
index e460dbc5c1c2607cc4bc6b5b555cb9b1f0fd294b..d79c6cb5455a025c05b6e0094f39b65fa02087c5 100644 (file)
@@ -33,7 +33,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: session.c,v 1.154 2003/03/05 22:33:43 markus Exp $");
+RCSID("$OpenBSD: session.c,v 1.163 2003/08/31 13:29:05 markus Exp $");
 
 #include "ssh.h"
 #include "ssh1.h"
@@ -62,12 +62,6 @@ RCSID("$OpenBSD: session.c,v 1.154 2003/03/05 22:33:43 markus Exp $");
 #include "ssh-gss.h"
 #endif
 
-#ifdef HAVE_CYGWIN
-#include <windows.h>
-#include <sys/cygwin.h>
-#define is_winnt       (GetVersion() < 0x80000000)
-#endif
-
 /* func */
 
 Session *session_new(void);
@@ -104,6 +98,7 @@ extern int debug_flag;
 extern u_int utmp_len;
 extern int startup_pipe;
 extern void destroy_sensitive_data(void);
+extern Buffer loginmsg;
 
 /* original command from peer. */
 const char *original_command = NULL;
@@ -112,10 +107,6 @@ const char *original_command = NULL;
 #define MAX_SESSIONS 10
 Session        sessions[MAX_SESSIONS];
 
-#ifdef WITH_AIXAUTHENTICATE
-char *aixloginmsg;
-#endif /* WITH_AIXAUTHENTICATE */
-
 #ifdef HAVE_LOGIN_CAP
 login_cap_t *lc;
 #endif
@@ -201,7 +192,7 @@ auth_input_request_forwarding(struct passwd * pw)
        nc = channel_new("auth socket",
            SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1,
            CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
-           0, xstrdup("auth socket"), 1);
+           0, "auth socket", 1);
        strlcpy(nc->path, auth_sock_name, sizeof(nc->path));
        return 1;
 }
@@ -234,7 +225,6 @@ do_authenticated(Authctxt *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)
@@ -249,10 +239,6 @@ do_authenticated(Authctxt *authctxt)
             }
         }
 #endif
-#ifdef KRB4
-       if (options.kerberos_ticket_cleanup)
-               krb4_cleanup_proc(authctxt);
-#endif
 #ifdef KRB5
        if (options.kerberos_ticket_cleanup)
                krb5_cleanup_proc(authctxt);
@@ -365,58 +351,6 @@ do_authenticated1(Authctxt *authctxt)
                                success = 1;
                        break;
 
-#if defined(AFS) || defined(KRB5)
-               case SSH_CMSG_HAVE_KERBEROS_TGT:
-                       if (!options.kerberos_tgt_passing) {
-                               verbose("Kerberos TGT passing disabled.");
-                       } else {
-                               char *kdata = packet_get_string(&dlen);
-                               packet_check_eom();
-
-                               /* XXX - 0x41, see creds_to_radix version */
-                               if (kdata[0] != 0x41) {
-#ifdef KRB5
-                                       krb5_data tgt;
-                                       tgt.data = kdata;
-                                       tgt.length = dlen;
-
-                                       if (auth_krb5_tgt(s->authctxt, &tgt))
-                                               success = 1;
-                                       else
-                                               verbose("Kerberos v5 TGT refused for %.100s", s->authctxt->user);
-#endif /* KRB5 */
-                               } else {
-#ifdef AFS
-                                       if (auth_krb4_tgt(s->authctxt, kdata))
-                                               success = 1;
-                                       else
-                                               verbose("Kerberos v4 TGT refused for %.100s", s->authctxt->user);
-#endif /* AFS */
-                               }
-                               xfree(kdata);
-                       }
-                       break;
-#endif /* AFS || KRB5 */
-
-#ifdef AFS
-               case SSH_CMSG_HAVE_AFS_TOKEN:
-                       if (!options.afs_token_passing || !k_hasafs()) {
-                               verbose("AFS token passing disabled.");
-                       } else {
-                               /* Accept AFS token. */
-                               char *token = packet_get_string(&dlen);
-                               packet_check_eom();
-
-                               if (auth_afs_token(s->authctxt, token))
-                                       success = 1;
-                               else
-                                       verbose("AFS token refused for %.100s",
-                                           s->authctxt->user);
-                               xfree(token);
-                       }
-                       break;
-#endif /* AFS */
-
                case SSH_CMSG_EXEC_SHELL:
                case SSH_CMSG_EXEC_CMD:
                        if (type == SSH_CMSG_EXEC_CMD) {
@@ -429,6 +363,10 @@ 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:
@@ -436,7 +374,7 @@ do_authenticated1(Authctxt *authctxt)
                         * Any unknown messages in this phase are ignored,
                         * and a failure message is returned.
                         */
-                       log("Unknown packet type received after authentication: %d", type);
+                       logit("Unknown packet type received after authentication: %d", type);
                }
                packet_start(success ? SSH_SMSG_SUCCESS : SSH_SMSG_FAILURE);
                packet_send();
@@ -479,18 +417,13 @@ do_exec_no_pty(Session *s, const char *command)
 
        session_proctitle(s);
 
-#if defined(GSSAPI)
-       temporarily_use_uid(s->pw);
-       ssh_gssapi_storecreds();
-       restore_uid();
-#endif
-
 #if defined(USE_PAM)
-       do_pam_session(s->pw->pw_name, NULL);
-       do_pam_setcred(1);
-       if (is_pam_password_change_required())
-               packet_disconnect("Password change required but no "
-                   "TTY available");
+       if (options.use_pam) {
+               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. */
@@ -612,15 +545,11 @@ do_exec_pty(Session *s, const char *command)
        ptyfd = s->ptyfd;
        ttyfd = s->ttyfd;
 
-#if defined(GSSAPI)
-       temporarily_use_uid(s->pw);
-       ssh_gssapi_storecreds();
-       restore_uid();
-#endif
-
 #if defined(USE_PAM)
-       do_pam_session(s->pw->pw_name, s->tty);
-       do_pam_setcred(1);
+       if (options.use_pam) {
+               do_pam_set_tty(s->tty);
+               do_pam_setcred(1);
+       }
 #endif
 
        /* Fork the child. */
@@ -726,7 +655,7 @@ do_pre_login(Session *s)
        }
 
        record_utmp_only(pid, s->tty, s->pw->pw_name,
-           get_remote_name_or_ip(utmp_len, options.verify_reverse_mapping),
+           get_remote_name_or_ip(utmp_len, options.use_dns),
            (struct sockaddr *)&from, fromlen);
 }
 #endif
@@ -738,31 +667,40 @@ do_pre_login(Session *s)
 void
 do_exec(Session *s, const char *command)
 {
-#if defined(SESSION_HOOKS)
-    if (options.session_hooks_allow &&
-        (options.session_hooks_startup_cmd ||
-         options.session_hooks_shutdown_cmd))
-    {
-        char env_file[1000];
-        struct stat st;
-        do
-        {
-            snprintf(env_file,
-                     sizeof(env_file),
-                     "/tmp/ssh_env_%d%d%d",
-                     getuid(),
-                     getpid(),
-                     rand());
-        } while (stat(env_file, &st)==0);
-        s->authctxt->session_env_file = strdup(env_file);
-    }
-#endif
        if (forced_command) {
                original_command = command;
                command = forced_command;
                debug("Forced command '%.900s'", command);
        }
 
+#if defined(SESSION_HOOKS)
+       if (options.session_hooks_allow &&
+           (options.session_hooks_startup_cmd ||
+            options.session_hooks_shutdown_cmd))
+       {
+               char env_file[1000];
+               struct stat st;
+               do
+               {
+                       snprintf(env_file,
+                                sizeof(env_file),
+                                "/tmp/ssh_env_%d%d%d",
+                                getuid(),
+                                getpid(),
+                                rand());
+               } while (stat(env_file, &st)==0);
+               s->authctxt->session_env_file = strdup(env_file);
+       }
+#endif
+
+#ifdef GSSAPI
+       if (options.gss_authentication) {
+               temporarily_use_uid(s->pw);
+               ssh_gssapi_storecreds();
+               restore_uid();
+       }
+#endif
+
        if (s->ttyfd != -1)
                do_exec_pty(s, command);
        else
@@ -800,7 +738,7 @@ do_login(Session *s, const char *command)
        if (!use_privsep)
                record_login(pid, s->tty, pw->pw_name, pw->pw_uid,
                    get_remote_name_or_ip(utmp_len,
-                   options.verify_reverse_mapping),
+                   options.use_dns),
                    (struct sockaddr *)&from, fromlen);
 
 #ifdef USE_PAM
@@ -808,9 +746,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 (is_pam_password_change_required()) {
+       if (options.use_pam && is_pam_password_change_required()) {
                print_pam_messages();
                do_pam_chauthtok();
+               /* XXX - signal [net] parent to enable forwardings */
        }
 #endif
 
@@ -818,13 +757,16 @@ do_login(Session *s, const char *command)
                return;
 
 #ifdef USE_PAM
-       if (!is_pam_password_change_required())
+       if (options.use_pam && !is_pam_password_change_required())
                print_pam_messages();
 #endif /* USE_PAM */
-#ifdef WITH_AIXAUTHENTICATE
-       if (aixloginmsg && *aixloginmsg)
-               printf("%s\n", aixloginmsg);
-#endif /* WITH_AIXAUTHENTICATE */
+
+       /* display post-login message */
+       if (buffer_len(&loginmsg) > 0) {
+               buffer_append(&loginmsg, "\0", 1);
+               printf("%s\n", (char *)buffer_ptr(&loginmsg));
+       }
+       buffer_free(&loginmsg);
 
 #ifndef NO_SSH_LASTLOG
        if (options.print_lastlog && s->last_login_time != 0) {
@@ -902,6 +844,16 @@ child_set_env(char ***envp, u_int *envsizep, const char *name,
        u_int i, namelen;
        char **env;
 
+       /*
+        * If we're passed an uninitialized list, allocate a single null
+        * entry before continuing.
+        */
+       if (*envp == NULL && *envsizep == 0) {
+               *envp = xmalloc(sizeof(char *));
+               *envp[0] = NULL;
+               *envsizep = 1;
+       }
+
        /*
         * Find the slot where the value should be stored.  If the variable
         * already exists, we reuse the slot; otherwise we append a new slot
@@ -1089,6 +1041,59 @@ void execute_session_hook(char* prog, Authctxt *authctxt,
 }
 #endif
 
+#ifdef HAVE_ETC_DEFAULT_LOGIN
+/*
+ * Return named variable from specified environment, or NULL if not present.
+ */
+static char *
+child_get_env(char **env, const char *name)
+{
+       int i;
+       size_t len;
+
+       len = strlen(name);
+       for (i=0; env[i] != NULL; i++)
+               if (strncmp(name, env[i], len) == 0 && env[i][len] == '=')
+                       return(env[i] + len + 1);
+       return NULL;
+}
+
+/*
+ * Read /etc/default/login.
+ * We pick up the PATH (or SUPATH for root) and UMASK.
+ */
+static void
+read_etc_default_login(char ***env, u_int *envsize, uid_t uid)
+{
+       char **tmpenv = NULL, *var;
+       u_int i;
+       size_t tmpenvsize = 0;
+       mode_t mask;
+
+       /*
+        * We don't want to copy the whole file to the child's environment,
+        * so we use a temporary environment and copy the variables we're
+        * interested in.
+        */
+       read_environment_file(&tmpenv, &tmpenvsize, "/etc/default/login");
+
+       if (uid == 0)
+               var = child_get_env(tmpenv, "SUPATH");
+       else
+               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);
+       
+       for (i = 0; tmpenv[i] != NULL; i++)
+               xfree(tmpenv[i]);
+       xfree(tmpenv);
+}
+#endif /* HAVE_ETC_DEFAULT_LOGIN */
+
 void copy_environment(char **source, char ***env, u_int *envsize)
 {
        char *var_name, *var_val;
@@ -1117,7 +1122,7 @@ do_setup_env(Session *s, const char *shell)
 {
        char buf[256];
        u_int i, envsize;
-       char **env, *laddr;
+       char **env, *laddr, *path = NULL;
        struct passwd *pw = s->pw;
 
        /* Initialize the environment. */
@@ -1137,7 +1142,7 @@ do_setup_env(Session *s, const char *shell)
        /* Allow any GSSAPI methods that we've used to alter 
         * the childs environment as they see fit
         */
-       ssh_gssapi_do_child(&env,&envsize);
+       ssh_gssapi_do_child(&env, &envsize);
 #endif
 
        if (!options.use_login) {
@@ -1161,15 +1166,18 @@ do_setup_env(Session *s, const char *shell)
                 * needed for loading shared libraries. So the path better
                 * remains intact here.
                 */
-#  ifdef SUPERUSER_PATH
-               child_set_env(&env, &envsize, "PATH", 
-                   s->pw->pw_uid == 0 ? SUPERUSER_PATH : _PATH_STDPATH);
-#  else 
-               child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);
-#  endif /* SUPERUSER_PATH */
                if (getenv("LD_LIBRARY_PATH"))
                        child_set_env(&env, &envsize, "LD_LIBRARY_PATH",
                                      getenv("LD_LIBRARY_PATH"));
+#  ifdef HAVE_ETC_DEFAULT_LOGIN
+               read_etc_default_login(&env, &envsize, pw->pw_uid);
+               path = child_get_env(env, "PATH");
+#  endif /* HAVE_ETC_DEFAULT_LOGIN */
+               if (path == NULL || *path == '\0') {
+                       child_set_env(&env, &envsize, "PATH", 
+                           s->pw->pw_uid == 0 ?
+                               SUPERUSER_PATH : _PATH_STDPATH);
+               }
 # endif /* HAVE_CYGWIN */
 #endif /* HAVE_LOGIN_CAP */
 
@@ -1238,11 +1246,6 @@ do_setup_env(Session *s, const char *shell)
                read_environment_file(&env, &envsize, "/etc/environment");
        }
 #endif
-#ifdef KRB4
-       if (s->authctxt->krb4_ticket_file)
-               child_set_env(&env, &envsize, "KRBTKFILE",
-                   s->authctxt->krb4_ticket_file);
-#endif
 #ifdef KRB5
        if (s->authctxt->krb5_ticket_file)
                child_set_env(&env, &envsize, "KRB5CCNAME",
@@ -1253,10 +1256,9 @@ do_setup_env(Session *s, const char *shell)
         * Pull in any environment variables that may have
         * been set by PAM.
         */
-       {
-               char **p;
+       if (options.use_pam) {
+               char **p = fetch_pam_environment();
 
-               p = fetch_pam_environment();
                copy_environment(p, &env, &envsize);
                free_pam_environment(p);
        }
@@ -1368,7 +1370,7 @@ do_nologin(struct passwd *pw)
 #endif
        if (f) {
                /* /etc/nologin exists.  Print its contents and exit. */
-               log("User %.100s not allowed because %s exists",
+               logit("User %.100s not allowed because %s exists",
                    pw->pw_name, _PATH_NOLOGIN);
                while (fgets(buf, sizeof(buf), f))
                        fputs(buf, stderr);
@@ -1388,7 +1390,8 @@ do_setusercontext(struct passwd *pw)
        {
 
 #ifdef HAVE_SETPCRED
-               setpcred(pw->pw_name);
+               if (setpcred(pw->pw_name, (char **)NULL) == -1)
+                       fatal("Failed to set process credentials");
 #endif /* HAVE_SETPCRED */
 #ifdef HAVE_LOGIN_CAP
 # ifdef __bsdi__
@@ -1424,7 +1427,10 @@ do_setusercontext(struct passwd *pw)
                 * These will have been wiped by the above initgroups() call.
                 * Reestablish them here.
                 */
-               do_pam_setcred(0);
+               if (options.use_pam) {
+                       do_pam_session();
+                       do_pam_setcred(0);
+               }
 # endif /* USE_PAM */
 # if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY)
                irix_setusercontext(pw);
@@ -1537,7 +1543,7 @@ do_child(Session *s, const char *command)
        /* we have to stash the hostname before we close our socket. */
        if (options.use_login)
                hostname = get_remote_name_or_ip(utmp_len,
-                   options.verify_reverse_mapping);
+                   options.use_dns);
        /*
         * Close the connection descriptors; note that this is the child, and
         * the server will still have the socket open, and it is important
@@ -1613,17 +1619,6 @@ do_child(Session *s, const char *command)
                                  options.session_hooks_shutdown_cmd != NULL);
         }
 #endif
-#ifdef AFS
-       /* Try to get AFS tokens for the local cell. */
-       if (k_hasafs()) {
-               char cell[64];
-
-               if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0)
-                       krb_afslog(cell, 0);
-
-               krb_afslog(0, 0);
-       }
-#endif /* AFS */
 
        /* Change current directory to the user\'s home directory. */
        if (chdir(pw->pw_dir) < 0) {
@@ -1894,7 +1889,7 @@ session_subsystem_req(Session *s)
        int i;
 
        packet_check_eom();
-       log("subsystem request for %.100s", subsys);
+       logit("subsystem request for %.100s", subsys);
 
        for (i = 0; i < options.num_subsystems; i++) {
                if (strcmp(subsys, options.subsystem_name[i]) == 0) {
@@ -1913,7 +1908,7 @@ session_subsystem_req(Session *s)
        }
 
        if (!success)
-               log("subsystem request for %.100s failed, subsystem not found",
+               logit("subsystem request for %.100s failed, subsystem not found",
                    subsys);
 
        xfree(subsys);
@@ -1960,6 +1955,20 @@ session_exec_req(Session *s)
        return 1;
 }
 
+static int
+session_break_req(Session *s)
+{
+       u_int break_length;
+
+       break_length = packet_get_int();        /* ignored */
+       packet_check_eom();
+
+       if (s->ttyfd == -1 ||
+           tcsendbreak(s->ttyfd, 0) < 0)
+               return 0;
+       return 1;
+}
+
 static int
 session_auth_agent_req(Session *s)
 {
@@ -1984,7 +1993,7 @@ session_input_channel_req(Channel *c, const char *rtype)
        Session *s;
 
        if ((s = session_by_channel(c->self)) == NULL) {
-               log("session_input_channel_req: no session %d req %.100s",
+               logit("session_input_channel_req: no session %d req %.100s",
                    c->self, rtype);
                return 0;
        }
@@ -2007,6 +2016,8 @@ session_input_channel_req(Channel *c, const char *rtype)
                        success = session_auth_agent_req(s);
                } else if (strcmp(rtype, "subsystem") == 0) {
                        success = session_subsystem_req(s);
+               } else if (strcmp(rtype, "break") == 0) {
+                       success = session_break_req(s);
                }
        }
        if (strcmp(rtype, "window-change") == 0) {
@@ -2344,6 +2355,7 @@ do_authenticated2(Authctxt *authctxt)
 {
        server_loop2(authctxt);
 #if defined(GSSAPI)
-       ssh_gssapi_cleanup_creds(NULL);
+       if (options.gss_cleanup_creds)
+               ssh_gssapi_cleanup_creds(NULL);
 #endif
 }
index 7fc3653cde92e42e8141ab4bcd25864ae0c22809..525e47f64ec88bfbc1e02717f97a64360b88eb30 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: session.h,v 1.19 2002/06/30 21:59:45 deraadt Exp $    */
+/*     $OpenBSD: session.h,v 1.20 2003/08/22 10:56:09 markus Exp $     */
 
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
@@ -68,7 +68,7 @@ Session       *session_new(void);
 Session        *session_by_tty(char *);
 void    session_close(Session *);
 void    do_setusercontext(struct passwd *);
-
 void    child_set_env(char ***envp, u_int *envsizep, const char *name,
                       const char *value);
+
 #endif
index eb593de73f12e7b86e064b12fa100e8298a1e54e..c05c61468c93e22ce0d62413b72acf12aadbb414 100644 (file)
@@ -35,7 +35,7 @@
 
 #include "includes.h"
 #include "openbsd-compat/sys-queue.h"
-RCSID("$OpenBSD: ssh-agent.c,v 1.108 2003/03/13 11:44:50 markus Exp $");
+RCSID("$OpenBSD: ssh-agent.c,v 1.111 2003/06/12 19:12:03 markus Exp $");
 
 #include <openssl/evp.h>
 #include <openssl/md5.h>
@@ -261,7 +261,7 @@ process_authentication_challenge1(SocketEntry *e)
                /* The response is MD5 of decrypted challenge plus session id. */
                len = BN_num_bytes(challenge);
                if (len <= 0 || len > 32) {
-                       log("process_authentication_challenge: bad challenge length %d", len);
+                       logit("process_authentication_challenge: bad challenge length %d", len);
                        goto failure;
                }
                memset(buf, 0, 32);
@@ -350,7 +350,7 @@ process_remove_identity(SocketEntry *e, int version)
                buffer_get_bignum(&e->request, key->rsa->n);
 
                if (bits != key_size(key))
-                       log("Warning: identity keysize mismatch: actual %u, announced %u",
+                       logit("Warning: identity keysize mismatch: actual %u, announced %u",
                            key_size(key), bits);
                break;
        case 2:
@@ -580,13 +580,29 @@ static void
 process_add_smartcard_key (SocketEntry *e)
 {
        char *sc_reader_id = NULL, *pin;
-       int i, version, success = 0;
+       int i, version, success = 0, death = 0, confirm = 0;
        Key **keys, *k;
        Identity *id;
        Idtab *tab;
 
        sc_reader_id = buffer_get_string(&e->request, NULL);
        pin = buffer_get_string(&e->request, NULL);
+
+       while (buffer_len(&e->request)) {
+               switch (buffer_get_char(&e->request)) {
+               case SSH_AGENT_CONSTRAIN_LIFETIME:
+                       death = time(NULL) + buffer_get_int(&e->request);
+                       break;
+               case SSH_AGENT_CONSTRAIN_CONFIRM:
+                       confirm = 1;
+                       break;
+               default:
+                       break;
+               }
+       }
+       if (lifetime && !death)
+               death = time(NULL) + lifetime;
+
        keys = sc_get_keys(sc_reader_id, pin);
        xfree(sc_reader_id);
        xfree(pin);
@@ -602,9 +618,9 @@ process_add_smartcard_key (SocketEntry *e)
                if (lookup_identity(k, version) == NULL) {
                        id = xmalloc(sizeof(Identity));
                        id->key = k;
-                       id->comment = xstrdup("smartcard key");
-                       id->death = 0;
-                       id->confirm = 0;
+                       id->comment = sc_get_key_label(k);
+                       id->death = death;
+                       id->confirm = confirm;
                        TAILQ_INSERT_TAIL(&tab->idlist, id, next);
                        tab->nentries++;
                        success = 1;
@@ -748,6 +764,7 @@ process_message(SocketEntry *e)
                break;
 #ifdef SMARTCARD
        case SSH_AGENTC_ADD_SMARTCARD_KEY:
+       case SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED:
                process_add_smartcard_key(e);
                break;
        case SSH_AGENTC_REMOVE_SMARTCARD_KEY:
@@ -962,7 +979,7 @@ check_parent_exists(int sig)
                /* printf("Parent has died - Authentication agent exiting.\n"); */
                cleanup_handler(sig); /* safe */
        }
-       signal(SIGALRM, check_parent_exists);
+       mysignal(SIGALRM, check_parent_exists);
        alarm(10);
        errno = save_errno;
 }
@@ -1007,7 +1024,7 @@ main(int ac, char **av)
 
        SSLeay_add_all_algorithms();
 
-       __progname = get_progname(av[0]);
+       __progname = ssh_get_progname(av[0]);
        init_rng();
        seed_rng();
 
@@ -1194,7 +1211,7 @@ skip:
        fatal_add_cleanup(cleanup_socket, NULL);
        new_socket(AUTH_SOCKET, sock);
        if (ac > 0) {
-               signal(SIGALRM, check_parent_exists);
+               mysignal(SIGALRM, check_parent_exists);
                alarm(10);
        }
        idtab_init();
index 87f6c491614999d24e19f0c1780575bfc0d26735..18ba713fe4eb86e84494ca56bd90b4464baf2380 100644 (file)
@@ -38,6 +38,7 @@
 #include <gssapi_generic.h>
 
 /* MIT Kerberos doesn't seem to define GSS_NT_HOSTBASED_SERVICE */
+
 #ifndef GSS_C_NT_HOSTBASED_SERVICE
 #define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name
 #endif /* GSS_C_NT_... */
 #endif /* KRB5 */
 #endif /* !MECHGLUE */
 
-/* draft-ietf-secsh-gsskeyex-03 */
+/* draft-ietf-secsh-gsskeyex-06 */
 #define SSH2_MSG_KEXGSS_INIT                           30
 #define SSH2_MSG_KEXGSS_CONTINUE                       31
 #define SSH2_MSG_KEXGSS_COMPLETE                       32
 #define SSH2_MSG_KEXGSS_HOSTKEY                                33
 #define SSH2_MSG_KEXGSS_ERROR                          34
-#define SSH2_MSG_USERAUTH_GSSAPI_RESPONSE              60
-#define SSH2_MSG_USERAUTH_GSSAPI_TOKEN                 61
-#define SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE     63    
-#define SSH2_MSG_USERAUTH_GSSAPI_ERROR                 64  
+#define SSH2_MSG_USERAUTH_GSSAPI_RESPONSE              60
+#define SSH2_MSG_USERAUTH_GSSAPI_TOKEN                 61
+#define SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE     63
+#define SSH2_MSG_USERAUTH_GSSAPI_ERROR                 64
 #define SSH2_MSG_USERAUTH_GSSAPI_ERRTOK                        65
 
+#define SSH_GSS_OIDTYPE 0x06
+
 #define KEX_GSS_SHA1                                   "gss-group1-sha1-"
 
 typedef struct {
-        char *filename;
-        char *envvar;
-        char *envval;
-        void *data;
+       char *filename;
+       char *envvar;
+       char *envval;
+       void *data;
 } ssh_gssapi_ccache;
 
 typedef struct {
-       gss_buffer_desc name;
-       gss_cred_id_t   creds;
+       gss_buffer_desc displayname;
+       gss_buffer_desc exportedname;
+       gss_cred_id_t creds;
        struct ssh_gssapi_mech_struct *mech;
        ssh_gssapi_ccache store;
 } ssh_gssapi_client;
 
 typedef struct ssh_gssapi_mech_struct {
-        char *enc_name;
-        char *name;
-        gss_OID_desc oid;
+       char *enc_name;
+       char *name;
+       gss_OID_desc oid;
        int (*dochild) (ssh_gssapi_client *);
        int (*userok) (ssh_gssapi_client *, char *);
        int (*localname) (ssh_gssapi_client *, char **);
        void (*storecreds) (ssh_gssapi_client *);
 } ssh_gssapi_mech;
 
-
-
 typedef struct {
        OM_uint32       major; /* both */
        OM_uint32       minor; /* both */
@@ -110,21 +112,15 @@ ssh_gssapi_mech *ssh_gssapi_get_ctype(Gssctxt *ctxt);
 OM_uint32 ssh_gssapi_import_name(Gssctxt *ctx, const char *host);
 OM_uint32 ssh_gssapi_acquire_cred(Gssctxt *ctx);
 OM_uint32 ssh_gssapi_init_ctx(Gssctxt *ctx, int deleg_creds,
-                             gss_buffer_desc *recv_tok, 
-                             gss_buffer_desc *send_tok, OM_uint32 *flags);
+    gss_buffer_desc *recv_tok, gss_buffer_desc *send_tok, OM_uint32 *flags);
 OM_uint32 ssh_gssapi_accept_ctx(Gssctxt *ctx,
-                               gss_buffer_desc *recv_tok,
-                               gss_buffer_desc *send_tok,
-                               OM_uint32 *flags);
-OM_uint32 ssh_gssapi_getclient(Gssctxt *ctx,
-                               ssh_gssapi_mech **mech,
-                               gss_buffer_desc *name,
-                               gss_cred_id_t *creds);
+    gss_buffer_desc *recv_tok, gss_buffer_desc *send_tok, OM_uint32 *flags);
+OM_uint32 ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *);
 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_server_ctx(Gssctxt **ctx,gss_OID oid);
+OM_uint32 ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid);
 
 int ssh_gssapi_check_mechanism(gss_OID oid, char *host);
 
@@ -138,9 +134,9 @@ void ssh_gssapi_server(Kex *kex, Buffer *client_kexinit,
 OM_uint32 ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *buffer, 
                                        gss_buffer_desc *hash);
 
-void ssh_gssapi_do_child(char ***envp, u_int *envsizep);                 
+void ssh_gssapi_do_child(char ***envp, u_int *envsizep);
 void ssh_gssapi_cleanup_creds(void *ignored);
-void ssh_gssapi_storecreds();
+void ssh_gssapi_storecreds(void);
 char *ssh_gssapi_server_mechanisms();
 
 #ifdef GSI
index 5b4eb82d1fc058011731af658be12ec504d832e1..9fa8aaebcab9a0b4a8794f374daf2dc2d2a39536 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: ssh-keyscan.c,v 1.41 2003/02/16 17:09:57 markus Exp $");
+RCSID("$OpenBSD: ssh-keyscan.c,v 1.44 2003/06/28 16:23:06 deraadt Exp $");
 
 #include "openbsd-compat/sys-queue.h"
 
@@ -31,11 +31,7 @@ RCSID("$OpenBSD: ssh-keyscan.c,v 1.41 2003/02/16 17:09:57 markus Exp $");
 
 /* Flag indicating whether IPv4 or IPv6.  This can be set on the command line.
    Default value is AF_UNSPEC means both IPv4 and IPv6. */
-#ifdef IPV4_DEFAULT
-int IPv4or6 = AF_INET;
-#else
 int IPv4or6 = AF_UNSPEC;
-#endif
 
 int ssh_port = SSH_DEFAULT_PORT;
 
@@ -397,7 +393,7 @@ tcpconnect(char *host)
        if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0)
                fatal("getaddrinfo %s: %s", host, gai_strerror(gaierr));
        for (ai = aitop; ai; ai = ai->ai_next) {
-               s = socket(ai->ai_family, SOCK_STREAM, 0);
+               s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
                if (s < 0) {
                        error("socket: %s", strerror(errno));
                        continue;
@@ -545,7 +541,7 @@ congreet(int s)
        n = snprintf(buf, sizeof buf, "SSH-%d.%d-OpenSSH-keyscan\r\n",
            c->c_keytype == KT_RSA1? PROTOCOL_MAJOR_1 : PROTOCOL_MAJOR_2,
            c->c_keytype == KT_RSA1? PROTOCOL_MINOR_1 : PROTOCOL_MINOR_2);
-       if (atomicio(write, s, buf, n) != n) {
+       if (atomicio(vwrite, s, buf, n) != n) {
                error("write (%s): %s", c->c_name, strerror(errno));
                confree(s);
                return;
@@ -685,7 +681,7 @@ fatal(const char *fmt,...)
 static void
 usage(void)
 {
-       fprintf(stderr, "usage: %s [-v46] [-p port] [-T timeout] [-f file]\n"
+       fprintf(stderr, "usage: %s [-v46] [-p port] [-T timeout] [-t type] [-f file]\n"
            "\t\t   [host | addrlist namelist] [...]\n",
            __progname);
        exit(1);
@@ -701,7 +697,7 @@ main(int argc, char **argv)
        extern int optind;
        extern char *optarg;
 
-       __progname = get_progname(argv[0]);
+       __progname = ssh_get_progname(argv[0]);
        init_rng();
        seed_rng();
        TAILQ_INIT(&tq);
index 2e3f8ff3ef759ecae43dafdc9adbbe0c5875b759..a17e8d5cf23430f4f35f27a288532cab7cc4c32b 100644 (file)
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ssh-keysign.8,v 1.6 2003/03/28 10:11:43 jmc Exp $
+.\" $OpenBSD: ssh-keysign.8,v 1.7 2003/06/10 09:12:11 jmc Exp $
 .\"
 .\" Copyright (c) 2002 Markus Friedl.  All rights reserved.
 .\"
@@ -74,9 +74,9 @@ must be set-uid root if hostbased authentication is used.
 .Xr ssh-keygen 1 ,
 .Xr ssh_config 5 ,
 .Xr sshd 8
-.Sh AUTHORS
-Markus Friedl <markus@openbsd.org>
 .Sh HISTORY
 .Nm
 first appeared in
 .Ox 3.2 .
+.Sh AUTHORS
+.An Markus Friedl Aq markus@openbsd.org
index 26c8faad249854e88fc318e92f6670c09c90515c..c7ca5c4e40094d35c5cf82fa4e291086a6c71d9f 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.10 2003/03/13 11:42:19 markus Exp $");
+RCSID("$OpenBSD: ssh-keysign.c,v 1.13 2003/07/03 08:09:06 djm Exp $");
 
 #include <openssl/evp.h>
 #include <openssl/rand.h>
@@ -42,7 +42,8 @@ RCSID("$OpenBSD: ssh-keysign.c,v 1.10 2003/03/13 11:42:19 markus Exp $");
 #include "pathnames.h"
 #include "readconf.h"
 
-uid_t original_real_uid;       /* XXX readconf.c needs this */
+/* XXX readconf.c needs these */
+uid_t original_real_uid;
 
 #ifdef HAVE___PROGNAME
 extern char *__progname;
@@ -55,7 +56,7 @@ valid_request(struct passwd *pw, char *host, Key **ret, u_char *data,
     u_int datalen)
 {
        Buffer b;
-       Key *key;
+       Key *key = NULL;
        u_char *pkblob;
        u_int blen, len;
        char *pkalg, *p;
index 125157083c7c43de404f51a85cc032fadc636f69..79f78d980b27df7c42cc228b724b091f97e0f9cc 100644 (file)
@@ -187,7 +187,7 @@ reopen:
        msg[0] = 0x02;
        msg[1] = len;
 
-       if (atomicio(write, fd, msg, sizeof(msg)) != sizeof(msg)) {
+       if (atomicio(vwrite, fd, msg, sizeof(msg)) != sizeof(msg)) {
                if (errno == EPIPE && errors < 10) {
                        close(fd);
                        errors++;
@@ -532,7 +532,7 @@ prng_check_seedfile(char *filename)
        /* mode 0600, owned by root or the current user? */
        if (((st.st_mode & 0177) != 0) || !(st.st_uid == getuid())) {
                debug("WARNING: PRNG seedfile %.100s must be mode 0600, "
-                   "owned by uid %d", filename, getuid());
+                   "owned by uid %li", filename, (long int)getuid());
                return 0;
        }
 
@@ -550,7 +550,7 @@ prng_write_seedfile(void)
        pw = getpwuid(getuid());
        if (pw == NULL)
                fatal("Couldn't get password entry for current user "
-                   "(%i): %s", getuid(), strerror(errno));
+                   "(%li): %s", (long int)getuid(), strerror(errno));
 
        /* Try to ensure that the parent directory is there */
        snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir,
@@ -572,7 +572,7 @@ prng_write_seedfile(void)
                debug("WARNING: couldn't access PRNG seedfile %.100s "
                    "(%.100s)", filename, strerror(errno));
        } else {
-               if (atomicio(write, fd, &seed, sizeof(seed)) < sizeof(seed))
+               if (atomicio(vwrite, fd, &seed, sizeof(seed)) < sizeof(seed))
                        fatal("problem writing PRNG seedfile %.100s "
                            "(%.100s)", filename, strerror(errno));
                close(fd);
@@ -589,7 +589,7 @@ prng_read_seedfile(void)
        pw = getpwuid(getuid());
        if (pw == NULL)
                fatal("Couldn't get password entry for current user "
-                   "(%i): %s", getuid(), strerror(errno));
+                   "(%li): %s", (long int)getuid(), strerror(errno));
 
        snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir,
                SSH_PRNG_SEED_FILE);
@@ -769,7 +769,7 @@ main(int argc, char **argv)
        extern char *optarg;
        LogLevel ll;
 
-       __progname = get_progname(argv[0]);
+       __progname = ssh_get_progname(argv[0]);
        log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1);
 
        ll = SYSLOG_LEVEL_INFO;
@@ -858,7 +858,7 @@ main(int argc, char **argv)
                        printf("%02x", (unsigned char)(buf[ret]));
                printf("\n");
        } else
-               ret = atomicio(write, STDOUT_FILENO, buf, bytes);
+               ret = atomicio(vwrite, STDOUT_FILENO, buf, bytes);
                
        memset(buf, '\0', bytes);
        xfree(buf);
index fd822bb3d38ba9fae5c66b22606a87fb438bfd1b..c81cb42c67f829dfafcc5ca977755528c7584d6a 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.168 2003/03/28 10:11:43 jmc Exp $
+.\" $OpenBSD: ssh.1,v 1.175 2003/07/22 13:35:22 markus Exp $
 .Dd September 25, 1999
 .Dt SSH 1
 .Os
@@ -49,7 +49,7 @@
 .Pp
 .Nm ssh
 .Bk -words
-.Op Fl afgknqstvxACNTX1246
+.Op Fl afgknqstvxACNTVX1246
 .Op Fl b Ar bind_address
 .Op Fl c Ar cipher_spec
 .Op Fl e Ar escape_char
@@ -301,6 +301,9 @@ Background ssh at logout when waiting for forwarded connection / X11 sessions
 to terminate
 .It Cm ~?
 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)
 .It Cm ~C
 Open command line (only useful for adding port forwardings using the
 .Fl L
@@ -485,13 +488,13 @@ It is possible to have multiple
 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
+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 and AFS tokens.
+Disables forwarding of Kerberos tickets.
 This may also be specified on a per-host basis in the configuration file.
 .It Fl l Ar login_name
 Specifies the user to log in as on the remote machine.
@@ -539,9 +542,10 @@ per-host basis in the configuration file.
 Quiet mode.
 Causes all warning and diagnostic messages to be suppressed.
 .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). The
-subsystem is specified as the remote command.
+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).
+The subsystem is specified as the remote command.
 .It Fl t
 Force pseudo-tty allocation.
 This can be used to execute arbitrary
@@ -563,8 +567,10 @@ This is helpful in
 debugging connection, authentication, and configuration problems.
 Multiple
 .Fl v
-options increases the verbosity.
-Maximum is 3.
+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
@@ -643,9 +649,9 @@ 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 protocol is supported, and
+Currently the SOCKS4 and SOCKS5 protocols are supported, and
 .Nm
-will act as a SOCKS4 server.
+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
@@ -916,7 +922,8 @@ or
 .Xr rsh 1 .
 .It Pa /etc/hosts.equiv
 This file is used during
-.Pa \&.rhosts authentication.
+.Pa \&.rhosts
+authentication.
 It contains
 canonical hosts names, one per line (the full format is described on
 the
@@ -958,15 +965,6 @@ above.
 .Nm
 exits with the exit status of the remote command or with 255
 if an error occurred.
-.Sh AUTHORS
-OpenSSH is a derivative of the original and free
-ssh 1.2.12 release by Tatu Ylonen.
-Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos,
-Theo de Raadt and Dug Song
-removed many bugs, re-added newer features and
-created OpenSSH.
-Markus Friedl contributed the support for SSH
-protocol versions 1.5 and 2.0.
 .Sh SEE ALSO
 .Xr rsh 1 ,
 .Xr scp 1 ,
@@ -989,3 +987,12 @@ protocol versions 1.5 and 2.0.
 .%D January 2002
 .%O work in progress material
 .Re
+.Sh AUTHORS
+OpenSSH is a derivative of the original and free
+ssh 1.2.12 release by Tatu Ylonen.
+Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos,
+Theo de Raadt and Dug Song
+removed many bugs, re-added newer features and
+created OpenSSH.
+Markus Friedl contributed the support for SSH
+protocol versions 1.5 and 2.0.
index ebf93dab85d5ea468d6640ccfb7d4de7c94d6502..06d1cb0e241a3c4f44cd64dd23bdc64453776650 100644 (file)
@@ -40,7 +40,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: ssh.c,v 1.190 2003/02/06 09:27:29 markus Exp $");
+RCSID("$OpenBSD: ssh.c,v 1.201 2003/09/01 18:15:50 markus Exp $");
 
 #include <openssl/evp.h>
 #include <openssl/err.h>
@@ -79,14 +79,6 @@ extern char *__progname;
 char *__progname;
 #endif
 
-/* Flag indicating whether IPv4 or IPv6.  This can be set on the command line.
-   Default value is AF_UNSPEC means both IPv4 and IPv6. */
-#ifdef IPV4_DEFAULT
-int IPv4or6 = AF_INET;
-#else
-int IPv4or6 = AF_UNSPEC;
-#endif
-
 /* Flag indicating whether debug mode is on.  This can be set on the command line. */
 int debug_flag = 0;
 
@@ -162,9 +154,6 @@ usage(void)
             _PATH_SSH_USER_CONFFILE);
        fprintf(stderr, "  -A          Enable authentication agent forwarding.\n");
        fprintf(stderr, "  -a          Disable authentication agent forwarding (default).\n");
-#ifdef AFS
-       fprintf(stderr, "  -k          Disable Kerberos ticket and AFS token forwarding.\n");
-#endif                         /* AFS */
        fprintf(stderr, "  -X          Enable X11 connection forwarding.\n");
        fprintf(stderr, "  -x          Disable X11 connection forwarding (default).\n");
        fprintf(stderr, "  -i file     Identity for public key authentication "
@@ -222,7 +211,7 @@ main(int ac, char **av)
        extern int optind, optreset;
        extern char *optarg;
 
-       __progname = get_progname(av[0]);
+       __progname = ssh_get_progname(av[0]);
        init_rng();
 
        /*
@@ -253,7 +242,7 @@ main(int ac, char **av)
        /* Get user data. */
        pw = getpwuid(original_real_uid);
        if (!pw) {
-               log("You don't exist, go away!");
+               logit("You don't exist, go away!");
                exit(1);
        }
        /* Take a copy of the returned structure. */
@@ -284,10 +273,10 @@ again:
                        options.protocol = SSH_PROTO_2;
                        break;
                case '4':
-                       IPv4or6 = AF_INET;
+                       options.address_family = AF_INET;
                        break;
                case '6':
-                       IPv4or6 = AF_INET6;
+                       options.address_family = AF_INET6;
                        break;
                case 'n':
                        stdin_null_flag = 1;
@@ -314,12 +303,9 @@ again:
                case 'A':
                        options.forward_agent = 1;
                        break;
-#ifdef AFS
                case 'k':
-                       options.kerberos_tgt_passing = 0;
-                       options.afs_token_passing = 0;
+                       /* ignored for backward compatibility */
                        break;
-#endif
                case 'i':
                        if (stat(optarg, &st) < 0) {
                                fprintf(stderr, "Warning: Identity file %s "
@@ -346,22 +332,22 @@ again:
                        tty_flag = 1;
                        break;
                case 'v':
-                       if (0 == debug_flag) {
+                       if (debug_flag == 0) {
                                debug_flag = 1;
                                options.log_level = SYSLOG_LEVEL_DEBUG1;
-                       } else if (options.log_level < SYSLOG_LEVEL_DEBUG3) {
-                               options.log_level++;
+                       } else {
+                               if (options.log_level < SYSLOG_LEVEL_DEBUG3)
+                                       options.log_level++;
                                break;
-                       } else
-                               fatal("Too high debugging level.");
+                       }
                        /* fallthrough */
                case 'V':
                        fprintf(stderr,
-                           "%s, SSH protocols %d.%d/%d.%d, OpenSSL 0x%8.8lx\n",
+                           "%s, SSH protocols %d.%d/%d.%d, %s\n",
                            SSH_VERSION,
                            PROTOCOL_MAJOR_1, PROTOCOL_MINOR_1,
                            PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2,
-                           SSLeay());
+                           SSLeay_version(SSLEAY_VERSION));
                        if (opt == 'V')
                                exit(0);
                        break;
@@ -427,9 +413,9 @@ again:
 
                case 'L':
                case 'R':
-                       if (sscanf(optarg, "%5[0-9]:%255[^:]:%5[0-9]",
+                       if (sscanf(optarg, "%5[0123456789]:%255[^:]:%5[0123456789]",
                            sfwd_port, buf, sfwd_host_port) != 3 &&
-                           sscanf(optarg, "%5[0-9]/%255[^/]/%5[0-9]",
+                           sscanf(optarg, "%5[0123456789]/%255[^/]/%5[0123456789]",
                            sfwd_port, buf, sfwd_host_port) != 3) {
                                fprintf(stderr,
                                    "Bad forwarding specification '%s'\n",
@@ -458,7 +444,7 @@ again:
                                    optarg);
                                exit(1);
                        }
-                       add_local_forward(&options, fwd_port, "socks4", 0);
+                       add_local_forward(&options, fwd_port, "socks", 0);
                        break;
 
                case 'C':
@@ -518,7 +504,6 @@ again:
 
        SSLeay_add_all_algorithms();
        ERR_load_crypto_strings();
-       channel_set_af(IPv4or6);
 
        /* Initialize the command to execute on remote host. */
        buffer_init(&command);
@@ -559,7 +544,7 @@ again:
        /* Do not allocate a tty if stdin is not a tty. */
        if (!isatty(fileno(stdin)) && !force_tty_flag) {
                if (tty_flag)
-                       log("Pseudo-terminal will not be allocated because stdin is not a terminal.");
+                       logit("Pseudo-terminal will not be allocated because stdin is not a terminal.");
                tty_flag = 0;
        }
 
@@ -596,16 +581,11 @@ again:
                    _PATH_SSH_USER_CONFFILE);
                (void)read_config_file(buf, host, &options);
 #endif
-#if defined(KRB4) || defined(KRB5)
+#if defined(KRB5)
                snprintf(buf, sizeof buf, "%.100s/%.100s.krb", pw->pw_dir,
                    _PATH_SSH_USER_CONFFILE);
                (void)read_config_file(buf, host, &options);
 #endif
-#ifdef AFS
-               snprintf(buf, sizeof buf, "%.100s/%.100s.afs", pw->pw_dir,
-                   _PATH_SSH_USER_CONFFILE);
-               (void)read_config_file(buf, host, &options);
-#endif
 #endif
                snprintf(buf, sizeof buf, "%.100s/%.100s", pw->pw_dir,
                    _PATH_SSH_USER_CONFFILE);
@@ -618,39 +598,36 @@ again:
        /* Fill configuration defaults. */
        fill_default_options(&options);
 
+       channel_set_af(options.address_family);
+
        /* reinit */
        log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, 1);
 
        seed_rng();
 
-        if (options.user == NULL) {
-                options.user = xstrdup(pw->pw_name);
-                options.implicit = 1;
-        }
+       if (options.user == NULL) {
+               options.user = xstrdup(pw->pw_name);
+               options.implicit = 1;
+       }
         else options.implicit = 0;
 
        if (options.hostname != NULL)
                host = options.hostname;
 
+       /* force lowercase for hostkey matching */
+       if (options.host_key_alias != NULL) {
+               for (p = options.host_key_alias; *p; p++)
+                       if (isupper(*p))
+                               *p = tolower(*p);
+       }
+
        if (options.proxy_command != NULL &&
            strcmp(options.proxy_command, "none") == 0)
                options.proxy_command = NULL;
 
-       /* Disable rhosts authentication if not running as root. */
-#ifdef HAVE_CYGWIN
-       /* Ignore uid if running under Windows */
-       if (!options.use_privileged_port) {
-#else
-       if (original_effective_uid != 0 || !options.use_privileged_port) {
-#endif
-               debug("Rhosts Authentication disabled, "
-                   "originating port will not be trusted.");
-               options.rhosts_authentication = 0;
-       }
        /* Open a connection to the remote host. */
-
-       if (ssh_connect(host, &hostaddr, options.port, IPv4or6,
-           options.connection_attempts,
+       if (ssh_connect(host, &hostaddr, options.port,
+           options.address_family, options.connection_attempts,
 #ifdef HAVE_CYGWIN
            options.use_privileged_port,
 #else
@@ -824,7 +801,7 @@ x11_get_proto(char **_proto, char **_data)
        if (!got_data) {
                u_int32_t rand = 0;
 
-               log("Warning: No xauth data; using fake authentication data for X11 forwarding.");
+               logit("Warning: No xauth data; using fake authentication data for X11 forwarding.");
                strlcpy(proto, "MIT-MAGIC-COOKIE-1", sizeof proto);
                for (i = 0; i < 16; i++) {
                        if (i % 4 == 0)
@@ -904,7 +881,7 @@ ssh_session(void)
                if (type == SSH_SMSG_SUCCESS)
                        packet_start_compression(options.compression_level);
                else if (type == SSH_SMSG_FAILURE)
-                       log("Warning: Remote host refused compression.");
+                       logit("Warning: Remote host refused compression.");
                else
                        packet_disconnect("Protocol error waiting for compression response.");
        }
@@ -943,7 +920,7 @@ ssh_session(void)
                        interactive = 1;
                        have_tty = 1;
                } else if (type == SSH_SMSG_FAILURE)
-                       log("Warning: Remote host failed or refused to allocate a pseudo tty.");
+                       logit("Warning: Remote host failed or refused to allocate a pseudo tty.");
                else
                        packet_disconnect("Protocol error waiting for pty request response.");
        }
@@ -961,7 +938,7 @@ ssh_session(void)
                if (type == SSH_SMSG_SUCCESS) {
                        interactive = 1;
                } else if (type == SSH_SMSG_FAILURE) {
-                       log("Warning: Remote host denied X11 forwarding.");
+                       logit("Warning: Remote host denied X11 forwarding.");
                } else {
                        packet_disconnect("Protocol error waiting for X11 forwarding");
                }
@@ -980,7 +957,7 @@ ssh_session(void)
                type = packet_read();
                packet_check_eom();
                if (type != SSH_SMSG_SUCCESS)
-                       log("Warning: Remote host denied authentication agent forwarding.");
+                       logit("Warning: Remote host denied authentication agent forwarding.");
        }
 
        /* Initiate port forwardings. */
@@ -1048,7 +1025,7 @@ client_global_request_reply(int type, u_int32_t seq, void *ctxt)
            options.remote_forwards[i].host,
            options.remote_forwards[i].host_port);
        if (type == SSH2_MSG_REQUEST_FAILURE)
-               log("Warning: remote port forwarding failed for listen port %d",
+               logit("Warning: remote port forwarding failed for listen port %d",
                    options.remote_forwards[i].port);
 }
 
@@ -1163,7 +1140,7 @@ ssh_session2_open(void)
        c = channel_new(
            "session", SSH_CHANNEL_OPENING, in, out, err,
            window, packetmax, CHAN_EXTENDED_WRITE,
-           xstrdup("client-session"), /*nonblock*/0);
+           "client-session", /*nonblock*/0);
 
        debug3("ssh_session2_open: channel_new: %d", c->self);
 
@@ -1215,7 +1192,7 @@ load_public_identity_files(void)
                            sizeof(Key *) * (SSH_MAX_IDENTITY_FILES - 1));
                        options.num_identity_files++;
                        options.identity_keys[0] = keys[i];
-                       options.identity_files[0] = xstrdup("smartcard key");;
+                       options.identity_files[0] = sc_get_key_label(keys[i]);
                }
                if (options.num_identity_files > SSH_MAX_IDENTITY_FILES)
                        options.num_identity_files = SSH_MAX_IDENTITY_FILES;
index b7058bab542d5779f2deda1a61029622e752d30b..e15dd9b0f2503f4ff02e7080cf6333c5dc3558b1 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.7 2003/03/28 10:11:43 jmc Exp $
+.\" $OpenBSD: ssh_config.5,v 1.20 2003/09/02 18:50:06 jmc Exp $
 .Dd September 25, 1999
 .Dt SSH_CONFIG 5
 .Os
@@ -63,9 +63,6 @@ GSSAPI configuration file
 Kerberos configuration file
 .Pq Pa $HOME/.ssh/config.krb
 .It
-AFS configuration file
-.Pq Pa $HOME/.ssh/config.afs
-.It
 system-wide configuration file
 .Pq Pa /etc/ssh/ssh_config
 .El
@@ -113,7 +110,7 @@ keyword) to be only for those hosts that match one of the patterns
 given after the keyword.
 .Ql \&*
 and
-.Ql ?
+.Ql \&?
 can be used as wildcards in the
 patterns.
 A single
@@ -124,13 +121,14 @@ The host is the
 .Ar hostname
 argument given on the command line (i.e., the name is not converted to
 a canonicalized host name before matching).
-.It Cm AFSTokenPassing
-Specifies whether to pass AFS tokens to remote host.
-The argument to this keyword must be
-.Dq yes
-or
-.Dq no .
-This option applies to protocol version 1 only.
+.It Cm AddressFamily
+Specifies which address family to use when connecting.
+Valid arguments are
+.Dq any ,
+.Dq inet
+(Use IPv4 only) or
+.Dq inet6
+(Use IPv6 only.)
 .It Cm BatchMode
 If set to
 .Dq yes ,
@@ -236,18 +234,41 @@ Specifies the number of tries (one per second) to make before exiting.
 The argument must be an integer.
 This may be useful in scripts if the connection sometimes fails.
 The default is 1.
+.It Cm ConnectTimeout
+Specifies the timeout (in seconds) used when connecting to the ssh
+server, instead of using the default system TCP timeout.
+This value is used only when the target is down or really unreachable,
+not when it refuses the connection.
 .It Cm DynamicForward
 Specifies that a TCP/IP port on the local machine be forwarded
 over the secure channel, and the application
 protocol is then used to determine where to connect to from the
 remote machine.
 The argument must be a port number.
-Currently the SOCKS4 protocol is supported, and
+Currently the SOCKS4 and SOCKS5 protocols are supported, and
 .Nm ssh
-will act as a SOCKS4 server.
+will act as a SOCKS server.
 Multiple forwardings may be specified, and
 additional forwardings can be given on the command line.
 Only the superuser can forward privileged ports.
+.It Cm EnableSSHKeysign
+Setting this option to
+.Dq yes
+in the global client configuration file
+.Pa /etc/ssh/ssh_config
+enables the use of the helper program
+.Xr ssh-keysign 8
+during
+.Cm HostbasedAuthentication .
+The argument must be
+.Dq yes
+or
+.Dq no .
+The default is
+.Dq no .
+See
+.Xr ssh-keysign 8
+for more information.
 .It Cm EscapeChar
 Sets the escape character (default:
 .Ql ~ ) .
@@ -316,18 +337,18 @@ The default is
 Specifies a file to use for the global
 host key database instead of
 .Pa /etc/ssh/ssh_known_hosts .
-.It Cm GssapiAuthentication
+.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.
 The default is 
 .Dq yes .
-.It Cm GssapiKeyExchange
+.It Cm GSSAPIKeyExchange
 Specifies whether key exchange based on GSSAPI may be used. When using
 GSSAPI key exchange the server need not have a host key.
 The default is
 .Dq yes .
-.It Cm GssapiDelegateCredentials
+.It Cm GSSAPIDelegateCredentials
 Specifies whether GSSAPI credentials will be delegated (forwarded) to
 the server.
 The default is
@@ -364,7 +385,8 @@ Numeric IP addresses are also permitted (both on the command line and in
 specifications).
 .It Cm IdentityFile
 Specifies a file from which the user's RSA or DSA authentication identity
-is read. The default is
+is read.
+The default is
 .Pa $HOME/.ssh/identity
 for protocol version 1, and
 .Pa $HOME/.ssh/id_rsa
@@ -395,19 +417,6 @@ 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 KerberosAuthentication
-Specifies whether Kerberos authentication will be used.
-The argument to this keyword must be
-.Dq yes
-or
-.Dq no .
-.It Cm KerberosTgtPassing
-Specifies whether a Kerberos TGT will be forwarded to the server.
-This will only work if the Kerberos server is actually an AFS kaserver.
-The argument to this keyword must be
-.Dq yes
-or
-.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.
@@ -461,7 +470,8 @@ Specifies the port number to connect on the remote host.
 Default is 22.
 .It Cm PreferredAuthentications
 Specifies the order in which the client should try protocol 2
-authentication methods. This allows a client to prefer one method (e.g.
+authentication methods.
+This allows a client to prefer one method (e.g.
 .Cm keyboard-interactive )
 over another method (e.g.
 .Cm password )
@@ -529,26 +539,6 @@ IPv6 addresses can be specified with an alternative syntax:
 Multiple forwardings may be specified, and additional
 forwardings can be given on the command line.
 Only the superuser can forward privileged ports.
-.It Cm RhostsAuthentication
-Specifies whether to try rhosts based authentication.
-Note that this
-declaration only affects the client side and has no effect whatsoever
-on security.
-Most servers do not permit RhostsAuthentication because it
-is not secure (see
-.Cm RhostsRSAAuthentication ) .
-The argument to this keyword must be
-.Dq yes
-or
-.Dq no .
-The default is
-.Dq no .
-This option applies to protocol version 1 only and requires
-.Nm ssh
-to be setuid root and
-.Cm UsePrivilegedPort
-to be set to
-.Dq yes .
 .It Cm RhostsRSAAuthentication
 Specifies whether to try rhosts based authentication with RSA host
 authentication.
@@ -574,12 +564,12 @@ The default is
 .Dq yes .
 Note that this option applies to protocol version 1 only.
 .It Cm SmartcardDevice
-Specifies which smartcard device to use. The argument to this keyword is
-the device
+Specifies which smartcard device to use.
+The argument to this keyword is the device
 .Nm ssh
 should use to communicate with a smartcard used for storing the user's
-private RSA key. By default, no device is specified and smartcard support
-is not activated.
+private RSA key.
+By default, no device is specified and smartcard support is not activated.
 .It Cm StrictHostKeyChecking
 If this flag is set to
 .Dq yes ,
@@ -629,11 +619,9 @@ If set to
 must be setuid root.
 Note that this option must be set to
 .Dq yes
-if
-.Cm RhostsAuthentication
-and
+for
 .Cm RhostsRSAAuthentication
-authentications are needed with older servers.
+with older servers.
 .It Cm User
 Specifies the user to log in as.
 This can be useful when a different user name is used on different machines.
@@ -643,6 +631,12 @@ having to remember to give the user name on the command line.
 Specifies a file to use for the user
 host key database instead of
 .Pa $HOME/.ssh/known_hosts .
+.It Cm VerifyHostKeyDNS
+Specifies whether to verify the remote key using DNS and SSHFP resource
+records.
+The default is
+.Dq no .
+Note that this option applies to protocol version 2 only.
 .It Cm XAuthLocation
 Specifies the full pathname of the
 .Xr xauth 1
@@ -668,6 +662,8 @@ values that are not specified in the user's configuration file, and
 for those users who do not have a configuration file.
 This file must be world-readable.
 .El
+.Sh SEE ALSO
+.Xr ssh 1
 .Sh AUTHORS
 OpenSSH is a derivative of the original and free
 ssh 1.2.12 release by Tatu Ylonen.
@@ -677,5 +673,3 @@ removed many bugs, re-added newer features and
 created OpenSSH.
 Markus Friedl contributed the support for SSH
 protocol versions 1.5 and 2.0.
-.Sh SEE ALSO
-.Xr ssh 1
index 9838cc3b0d42ec2cb723c871081ed5fe02c0e2e8..8d358e14c9a9da5d53388110e351b837cf5a03ba 100644 (file)
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshconnect1.c,v 1.52 2002/08/08 13:50:23 aaron Exp $");
+RCSID("$OpenBSD: sshconnect1.c,v 1.56 2003/08/28 12:54:34 markus Exp $");
 
 #include <openssl/bn.h>
 #include <openssl/md5.h>
 
-#ifdef KRB4
-#include <krb.h>
-#endif
-#ifdef KRB5
-#include <krb5.h>
-#ifndef HEIMDAL
-#define krb5_get_err_text(context,code) error_message(code)
-#endif /* !HEIMDAL */
-#endif
-#ifdef AFS
-#include <kafs.h>
-#include "radix.h"
-#endif
-
 #include "ssh.h"
 #include "ssh1.h"
 #include "xmalloc.h"
@@ -133,7 +119,7 @@ try_agent_authentication(void)
                         * although it advertised it supports this.  Just
                         * return a wrong value.
                         */
-                       log("Authentication agent failed to decrypt challenge.");
+                       logit("Authentication agent failed to decrypt challenge.");
                        memset(response, 0, sizeof(response));
                }
                key_free(key);
@@ -391,478 +377,6 @@ try_rhosts_rsa_authentication(const char *local_user, Key * host_key)
        return 0;
 }
 
-#ifdef KRB4
-static int
-try_krb4_authentication(void)
-{
-       KTEXT_ST auth;          /* Kerberos data */
-       char *reply;
-       char inst[INST_SZ];
-       char *realm;
-       CREDENTIALS cred;
-       int r, type;
-       socklen_t slen;
-       Key_schedule schedule;
-       u_long checksum, cksum;
-       MSG_DAT msg_data;
-       struct sockaddr_in local, foreign;
-       struct stat st;
-
-       /* Don't do anything if we don't have any tickets. */
-       if (stat(tkt_string(), &st) < 0)
-               return 0;
-
-       strlcpy(inst, (char *)krb_get_phost(get_canonical_hostname(1)),
-           INST_SZ);
-
-       realm = (char *)krb_realmofhost(get_canonical_hostname(1));
-       if (!realm) {
-               debug("Kerberos v4: no realm for %s", get_canonical_hostname(1));
-               return 0;
-       }
-       /* This can really be anything. */
-       checksum = (u_long)getpid();
-
-       r = krb_mk_req(&auth, KRB4_SERVICE_NAME, inst, realm, checksum);
-       if (r != KSUCCESS) {
-               debug("Kerberos v4 krb_mk_req failed: %s", krb_err_txt[r]);
-               return 0;
-       }
-       /* Get session key to decrypt the server's reply with. */
-       r = krb_get_cred(KRB4_SERVICE_NAME, inst, realm, &cred);
-       if (r != KSUCCESS) {
-               debug("get_cred failed: %s", krb_err_txt[r]);
-               return 0;
-       }
-       des_key_sched((des_cblock *) cred.session, schedule);
-
-       /* Send authentication info to server. */
-       packet_start(SSH_CMSG_AUTH_KERBEROS);
-       packet_put_string((char *) auth.dat, auth.length);
-       packet_send();
-       packet_write_wait();
-
-       /* Zero the buffer. */
-       (void) memset(auth.dat, 0, MAX_KTXT_LEN);
-
-       slen = sizeof(local);
-       memset(&local, 0, sizeof(local));
-       if (getsockname(packet_get_connection_in(),
-           (struct sockaddr *)&local, &slen) < 0)
-               debug("getsockname failed: %s", strerror(errno));
-
-       slen = sizeof(foreign);
-       memset(&foreign, 0, sizeof(foreign));
-       if (getpeername(packet_get_connection_in(),
-           (struct sockaddr *)&foreign, &slen) < 0) {
-               debug("getpeername failed: %s", strerror(errno));
-               fatal_cleanup();
-       }
-       /* Get server reply. */
-       type = packet_read();
-       switch (type) {
-       case SSH_SMSG_FAILURE:
-               /* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */
-               debug("Kerberos v4 authentication failed.");
-               return 0;
-               break;
-
-       case SSH_SMSG_AUTH_KERBEROS_RESPONSE:
-               /* SSH_SMSG_AUTH_KERBEROS_SUCCESS */
-               debug("Kerberos v4 authentication accepted.");
-
-               /* Get server's response. */
-               reply = packet_get_string((u_int *) &auth.length);
-               if (auth.length >= MAX_KTXT_LEN)
-                       fatal("Kerberos v4: Malformed response from server");
-               memcpy(auth.dat, reply, auth.length);
-               xfree(reply);
-
-               packet_check_eom();
-
-               /*
-                * If his response isn't properly encrypted with the session
-                * key, and the decrypted checksum fails to match, he's
-                * bogus. Bail out.
-                */
-               r = krb_rd_priv(auth.dat, auth.length, schedule, &cred.session,
-                   &foreign, &local, &msg_data);
-               if (r != KSUCCESS) {
-                       debug("Kerberos v4 krb_rd_priv failed: %s",
-                           krb_err_txt[r]);
-                       packet_disconnect("Kerberos v4 challenge failed!");
-               }
-               /* Fetch the (incremented) checksum that we supplied in the request. */
-               memcpy((char *)&cksum, (char *)msg_data.app_data,
-                   sizeof(cksum));
-               cksum = ntohl(cksum);
-
-               /* If it matches, we're golden. */
-               if (cksum == checksum + 1) {
-                       debug("Kerberos v4 challenge successful.");
-                       return 1;
-               } else
-                       packet_disconnect("Kerberos v4 challenge failed!");
-               break;
-
-       default:
-               packet_disconnect("Protocol error on Kerberos v4 response: %d", type);
-       }
-       return 0;
-}
-
-#endif /* KRB4 */
-
-#ifdef KRB5
-static int
-try_krb5_authentication(krb5_context *context, krb5_auth_context *auth_context)
-{
-       krb5_error_code problem;
-       const char *tkfile;
-       struct stat buf;
-       krb5_ccache ccache = NULL;
-       const char *remotehost;
-       krb5_data ap;
-       int type;
-       krb5_ap_rep_enc_part *reply = NULL;
-       int ret;
-
-       memset(&ap, 0, sizeof(ap));
-
-       problem = krb5_init_context(context);
-       if (problem) {
-               debug("Kerberos v5: krb5_init_context failed");
-               ret = 0;
-               goto out;
-       }
-       
-       problem = krb5_auth_con_init(*context, auth_context);
-       if (problem) {
-               debug("Kerberos v5: krb5_auth_con_init failed");
-               ret = 0;
-               goto out;
-       }
-
-#ifndef HEIMDAL
-       problem = krb5_auth_con_setflags(*context, *auth_context,
-                                        KRB5_AUTH_CONTEXT_RET_TIME);
-       if (problem) {
-               debug("Keberos v5: krb5_auth_con_setflags failed");
-               ret = 0;
-               goto out;
-       }
-#endif
-
-       tkfile = krb5_cc_default_name(*context);
-       if (strncmp(tkfile, "FILE:", 5) == 0)
-               tkfile += 5;
-
-       if (stat(tkfile, &buf) == 0 && getuid() != buf.st_uid) {
-               debug("Kerberos v5: could not get default ccache (permission denied).");
-               ret = 0;
-               goto out;
-       }
-
-       problem = krb5_cc_default(*context, &ccache);
-       if (problem) {
-               debug("Kerberos v5: krb5_cc_default failed: %s",
-                   krb5_get_err_text(*context, problem));
-               ret = 0;
-               goto out;
-       }
-
-       remotehost = get_canonical_hostname(1);
-
-       problem = krb5_mk_req(*context, auth_context, AP_OPTS_MUTUAL_REQUIRED,
-           "host", remotehost, NULL, ccache, &ap);
-       if (problem) {
-               debug("Kerberos v5: krb5_mk_req failed: %s",
-                   krb5_get_err_text(*context, problem));
-               ret = 0;
-               goto out;
-       }
-
-       packet_start(SSH_CMSG_AUTH_KERBEROS);
-       packet_put_string((char *) ap.data, ap.length);
-       packet_send();
-       packet_write_wait();
-
-       xfree(ap.data);
-       ap.length = 0;
-
-       type = packet_read();
-       switch (type) {
-       case SSH_SMSG_FAILURE:
-               /* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */
-               debug("Kerberos v5 authentication failed.");
-               ret = 0;
-               break;
-
-       case SSH_SMSG_AUTH_KERBEROS_RESPONSE:
-               /* SSH_SMSG_AUTH_KERBEROS_SUCCESS */
-               debug("Kerberos v5 authentication accepted.");
-
-               /* Get server's response. */
-               ap.data = packet_get_string((unsigned int *) &ap.length);
-               packet_check_eom();
-               /* XXX je to dobre? */
-
-               problem = krb5_rd_rep(*context, *auth_context, &ap, &reply);
-               if (problem) {
-                       ret = 0;
-               }
-               ret = 1;
-               break;
-
-       default:
-               packet_disconnect("Protocol error on Kerberos v5 response: %d",
-                   type);
-               ret = 0;
-               break;
-
-       }
-
- out:
-       if (ccache != NULL)
-               krb5_cc_close(*context, ccache);
-       if (reply != NULL)
-               krb5_free_ap_rep_enc_part(*context, reply);
-       if (ap.length > 0)
-#ifdef HEIMDAL
-               krb5_data_free(&ap);
-#else
-               krb5_free_data_contents(*context, &ap);
-#endif
-
-       return (ret);
-}
-
-static void
-send_krb5_tgt(krb5_context context, krb5_auth_context auth_context)
-{
-       int fd, type;
-       krb5_error_code problem;
-       krb5_data outbuf;
-       krb5_ccache ccache = NULL;
-       krb5_creds creds;
-#ifdef HEIMDAL
-       krb5_kdc_flags flags;
-#else
-       int forwardable;
-#endif
-       const char *remotehost;
-
-       memset(&creds, 0, sizeof(creds));
-       memset(&outbuf, 0, sizeof(outbuf));
-
-       fd = packet_get_connection_in();
-
-#ifdef HEIMDAL
-       problem = krb5_auth_con_setaddrs_from_fd(context, auth_context, &fd);
-#else
-       problem = krb5_auth_con_genaddrs(context, auth_context, fd,
-                       KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR |
-                       KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR);
-#endif
-       if (problem)
-               goto out;
-
-       problem = krb5_cc_default(context, &ccache);
-       if (problem)
-               goto out;
-
-       problem = krb5_cc_get_principal(context, ccache, &creds.client);
-       if (problem)
-               goto out;
-
-       remotehost = get_canonical_hostname(1);
-       
-#ifdef HEIMDAL
-       problem = krb5_build_principal(context, &creds.server,
-           strlen(creds.client->realm), creds.client->realm,
-           "krbtgt", creds.client->realm, NULL);
-#else
-       problem = krb5_build_principal(context, &creds.server,
-           creds.client->realm.length, creds.client->realm.data,
-           "host", remotehost, NULL);
-#endif
-       if (problem)
-               goto out;
-
-       creds.times.endtime = 0;
-
-#ifdef HEIMDAL
-       flags.i = 0;
-       flags.b.forwarded = 1;
-       flags.b.forwardable = krb5_config_get_bool(context,  NULL,
-           "libdefaults", "forwardable", NULL);
-       problem = krb5_get_forwarded_creds(context, auth_context,
-           ccache, flags.i, remotehost, &creds, &outbuf);
-#else
-       forwardable = 1;
-       problem = krb5_fwd_tgt_creds(context, auth_context, remotehost,
-           creds.client, creds.server, ccache, forwardable, &outbuf);
-#endif
-
-       if (problem)
-               goto out;
-
-       packet_start(SSH_CMSG_HAVE_KERBEROS_TGT);
-       packet_put_string((char *)outbuf.data, outbuf.length);
-       packet_send();
-       packet_write_wait();
-
-       type = packet_read();
-
-       if (type == SSH_SMSG_SUCCESS) {
-               char *pname;
-
-               krb5_unparse_name(context, creds.client, &pname);
-               debug("Kerberos v5 TGT forwarded (%s).", pname);
-               xfree(pname);
-       } else
-               debug("Kerberos v5 TGT forwarding failed.");
-
-       return;
-
- out:
-       if (problem)
-               debug("Kerberos v5 TGT forwarding failed: %s",
-                   krb5_get_err_text(context, problem));
-       if (creds.client)
-               krb5_free_principal(context, creds.client);
-       if (creds.server)
-               krb5_free_principal(context, creds.server);
-       if (ccache)
-               krb5_cc_close(context, ccache);
-       if (outbuf.data)
-               xfree(outbuf.data);
-}
-#endif /* KRB5 */
-
-#ifdef AFS
-static void
-send_krb4_tgt(void)
-{
-       CREDENTIALS *creds;
-       struct stat st;
-       char buffer[4096], pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ];
-       int problem, type;
-
-       /* Don't do anything if we don't have any tickets. */
-       if (stat(tkt_string(), &st) < 0)
-               return;
-
-       creds = xmalloc(sizeof(*creds));
-
-       problem = krb_get_tf_fullname(TKT_FILE, pname, pinst, prealm);
-       if (problem)
-               goto out;
-
-       problem = krb_get_cred("krbtgt", prealm, prealm, creds);
-       if (problem)
-               goto out;
-
-       if (time(0) > krb_life_to_time(creds->issue_date, creds->lifetime)) {
-               problem = RD_AP_EXP;
-               goto out;
-       }
-       creds_to_radix(creds, (u_char *)buffer, sizeof(buffer));
-
-       packet_start(SSH_CMSG_HAVE_KERBEROS_TGT);
-       packet_put_cstring(buffer);
-       packet_send();
-       packet_write_wait();
-
-       type = packet_read();
-
-       if (type == SSH_SMSG_SUCCESS)
-               debug("Kerberos v4 TGT forwarded (%s%s%s@%s).",
-                   creds->pname, creds->pinst[0] ? "." : "",
-                   creds->pinst, creds->realm);
-       else
-               debug("Kerberos v4 TGT rejected.");
-
-       xfree(creds);
-       return;
-
- out:
-       debug("Kerberos v4 TGT passing failed: %s", krb_err_txt[problem]);
-       xfree(creds);
-}
-
-static void
-send_afs_tokens(void)
-{
-       CREDENTIALS creds;
-       struct ViceIoctl parms;
-       struct ClearToken ct;
-       int i, type, len;
-       char buf[2048], *p, *server_cell;
-       char buffer[8192];
-
-       /* Move over ktc_GetToken, here's something leaner. */
-       for (i = 0; i < 100; i++) {     /* just in case */
-               parms.in = (char *) &i;
-               parms.in_size = sizeof(i);
-               parms.out = buf;
-               parms.out_size = sizeof(buf);
-               if (k_pioctl(0, VIOCGETTOK, &parms, 0) != 0)
-                       break;
-               p = buf;
-
-               /* Get secret token. */
-               memcpy(&creds.ticket_st.length, p, sizeof(u_int));
-               if (creds.ticket_st.length > MAX_KTXT_LEN)
-                       break;
-               p += sizeof(u_int);
-               memcpy(creds.ticket_st.dat, p, creds.ticket_st.length);
-               p += creds.ticket_st.length;
-
-               /* Get clear token. */
-               memcpy(&len, p, sizeof(len));
-               if (len != sizeof(struct ClearToken))
-                       break;
-               p += sizeof(len);
-               memcpy(&ct, p, len);
-               p += len;
-               p += sizeof(len);       /* primary flag */
-               server_cell = p;
-
-               /* Flesh out our credentials. */
-               strlcpy(creds.service, "afs", sizeof(creds.service));
-               creds.instance[0] = '\0';
-               strlcpy(creds.realm, server_cell, REALM_SZ);
-               memcpy(creds.session, ct.HandShakeKey, DES_KEY_SZ);
-               creds.issue_date = ct.BeginTimestamp;
-               creds.lifetime = krb_time_to_life(creds.issue_date,
-                   ct.EndTimestamp);
-               creds.kvno = ct.AuthHandle;
-               snprintf(creds.pname, sizeof(creds.pname), "AFS ID %d", ct.ViceId);
-               creds.pinst[0] = '\0';
-
-               /* Encode token, ship it off. */
-               if (creds_to_radix(&creds, (u_char *)buffer,
-                   sizeof(buffer)) <= 0)
-                       break;
-               packet_start(SSH_CMSG_HAVE_AFS_TOKEN);
-               packet_put_cstring(buffer);
-               packet_send();
-               packet_write_wait();
-
-               /* Roger, Roger. Clearance, Clarence. What's your vector,
-                  Victor? */
-               type = packet_read();
-
-               if (type == SSH_SMSG_FAILURE)
-                       debug("AFS token for cell %s rejected.", server_cell);
-               else if (type != SSH_SMSG_SUCCESS)
-                       packet_disconnect("Protocol error on AFS token response: %d", type);
-       }
-}
-
-#endif /* AFS */
-
 /*
  * Tries to authenticate with any string-based challenge/response system.
  * Note that the client code is not tied to s/key or TIS.
@@ -901,7 +415,7 @@ try_challenge_response_authentication(void)
                if (i != 0)
                        error("Permission denied, please try again.");
                if (options.cipher == SSH_CIPHER_NONE)
-                       log("WARNING: Encryption is disabled! "
+                       logit("WARNING: Encryption is disabled! "
                            "Response will be transmitted in clear text.");
                response = read_passphrase(prompt, 0);
                if (strcmp(response, "") == 0) {
@@ -936,7 +450,7 @@ try_password_authentication(char *prompt)
 
        debug("Doing password authentication.");
        if (options.cipher == SSH_CIPHER_NONE)
-               log("WARNING: Encryption is disabled! Password will be transmitted in clear text.");
+               logit("WARNING: Encryption is disabled! Password will be transmitted in clear text.");
        for (i = 0; i < options.number_of_password_prompts; i++) {
                if (i != 0)
                        error("Permission denied, please try again.");
@@ -1037,7 +551,7 @@ int try_gssapi_authentication(char *host, Options *options)
   gss_OID_desc mech_oid;
   gss_OID name_type;
   gss_OID_set gss_mechs, my_mechs;
-  int my_mech_num, i, present;
+  int my_mech_num, i;
   int ret_stat = 0;                             /* 1 == success */
   OM_uint32 req_flags = 0;
   OM_uint32 ret_flags;
@@ -1125,12 +639,16 @@ int try_gssapi_authentication(char *host, Options *options)
   packet_start(SSH_CMSG_AUTH_GSSAPI);
   packet_put_int(my_mechs->count); /* Number of mechs we're sending */
 #ifdef GSI
-  /* Send GSI before Kerberos, because if GSI fails, we can always fall
-     back and try regular Kerberos authentication with our Kerberos cred. */
-  ctx->major = gss_test_oid_set_member(&ctx->minor, &gsioid,
-                                      my_mechs, &present);
-  if (present) {
-      packet_put_string(gsioid.elements,gsioid.length);
+  {
+      int present;
+      /* Send GSI before Kerberos, because if GSI fails, we can always
+        fall back and try regular Kerberos authentication with our
+        Kerberos cred. */
+      ctx->major = gss_test_oid_set_member(&ctx->minor, &gsioid,
+                                          my_mechs, &present);
+      if (present) {
+         packet_put_string(gsioid.elements,gsioid.length);
+      }
   }
 #endif
   for (my_mech_num = 0; my_mech_num < my_mechs->count; my_mech_num++) {
@@ -1383,9 +901,9 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
 
        rbits = BN_num_bits(server_key->rsa->n);
        if (bits != rbits) {
-               log("Warning: Server lies about size of server public key: "
+               logit("Warning: Server lies about size of server public key: "
                    "actual size is %d bits vs. announced %d.", rbits, bits);
-               log("Warning: This may be due to an old implementation of ssh.");
+               logit("Warning: This may be due to an old implementation of ssh.");
        }
        /* Get the host key. */
        host_key = key_new(KEY_RSA1);
@@ -1395,9 +913,9 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
 
        rbits = BN_num_bits(host_key->rsa->n);
        if (bits != rbits) {
-               log("Warning: Server lies about size of server host key: "
+               logit("Warning: Server lies about size of server host key: "
                    "actual size is %d bits vs. announced %d.", rbits, bits);
-               log("Warning: This may be due to an old implementation of ssh.");
+               logit("Warning: This may be due to an old implementation of ssh.");
        }
 
 #ifdef GSSAPI
@@ -1527,7 +1045,7 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
                        options.cipher = ssh_cipher_default;
        } else if (options.cipher == SSH_CIPHER_ILLEGAL ||
            !(cipher_mask_ssh1(1) & (1 << options.cipher))) {
-               log("No valid SSH1 cipher, using %.100s instead.",
+               logit("No valid SSH1 cipher, using %.100s instead.",
                    cipher_name(ssh_cipher_default));
                options.cipher = ssh_cipher_default;
        }
@@ -1587,10 +1105,6 @@ ssh_userauth1(const char *local_user, const char *server_user, char *host,
 #endif /* GSI */
 #endif /* GSSAPI */
 
-#ifdef KRB5
-       krb5_context context = NULL;
-       krb5_auth_context auth_context = NULL;
-#endif
        int i, type;
 
        if (supported_authentications == 0)
@@ -1685,56 +1199,6 @@ ssh_userauth1(const char *local_user, const char *server_user, char *host,
     }
 #endif /* GSSAPI */
        
-#ifdef KRB5
-       if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) &&
-           options.kerberos_authentication) {
-               debug("Trying Kerberos v5 authentication.");
-
-               if (try_krb5_authentication(&context, &auth_context)) {
-                       type = packet_read();
-                       if (type == SSH_SMSG_SUCCESS)
-                               goto success;
-                       if (type != SSH_SMSG_FAILURE)
-                               packet_disconnect("Protocol error: got %d in response to Kerberos v5 auth", type);
-               }
-       }
-#endif /* KRB5 */
-
-#ifdef KRB4
-       if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) &&
-           options.kerberos_authentication) {
-               debug("Trying Kerberos v4 authentication.");
-
-               if (try_krb4_authentication()) {
-                       type = packet_read();
-                       if (type == SSH_SMSG_SUCCESS)
-                               goto success;
-                       if (type != SSH_SMSG_FAILURE)
-                               packet_disconnect("Protocol error: got %d in response to Kerberos v4 auth", type);
-               }
-       }
-#endif /* KRB4 */
-
-       /*
-        * Use rhosts authentication if running in privileged socket and we
-        * do not wish to remain anonymous.
-        */
-       if ((supported_authentications & (1 << SSH_AUTH_RHOSTS)) &&
-           options.rhosts_authentication) {
-               debug("Trying rhosts authentication.");
-               packet_start(SSH_CMSG_AUTH_RHOSTS);
-               packet_put_cstring(local_user);
-               packet_send();
-               packet_write_wait();
-
-               /* The server should respond with success or failure. */
-               type = packet_read();
-               if (type == SSH_SMSG_SUCCESS)
-                       goto success;
-               if (type != SSH_SMSG_FAILURE)
-                       packet_disconnect("Protocol error: got %d in response to rhosts auth",
-                                         type);
-       }
        /*
         * Try .rhosts or /etc/hosts.equiv authentication with RSA host
         * authentication.
@@ -1788,36 +1252,5 @@ ssh_userauth1(const char *local_user, const char *server_user, char *host,
        /* NOTREACHED */
 
  success:
-#ifdef KRB5
-       /* Try Kerberos v5 TGT passing. */
-       if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) &&
-           options.kerberos_tgt_passing && context && auth_context) {
-               if (options.cipher == SSH_CIPHER_NONE)
-                       log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!");
-               send_krb5_tgt(context, auth_context);
-       }
-       if (auth_context)
-               krb5_auth_con_free(context, auth_context);
-       if (context)
-               krb5_free_context(context);
-#endif
-
-#ifdef AFS
-       /* Try Kerberos v4 TGT passing if the server supports it. */
-       if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) &&
-           options.kerberos_tgt_passing) {
-               if (options.cipher == SSH_CIPHER_NONE)
-                       log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!");
-               send_krb4_tgt();
-       }
-       /* Try AFS token passing if the server supports it. */
-       if ((supported_authentications & (1 << SSH_PASS_AFS_TOKEN)) &&
-           options.afs_token_passing && k_hasafs()) {
-               if (options.cipher == SSH_CIPHER_NONE)
-                       log("WARNING: Encryption is disabled! Token will be transmitted in the clear!");
-               send_afs_tokens();
-       }
-#endif /* AFS */
-
        return; /* need statement after label */
 }
index 17c44e6235788e6f1beab7631a6a525ad2b91754..8da71b46d8d4c41398f091cf8d52996ab3b8d828 100644 (file)
@@ -23,7 +23,9 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshconnect2.c,v 1.114 2003/04/01 10:22:21 markus Exp $");
+RCSID("$OpenBSD: sshconnect2.c,v 1.124 2003/08/25 10:33:33 djm Exp $");
+
+#include "openbsd-compat/sys-queue.h"
 
 #include "ssh.h"
 #include "ssh2.h"
@@ -62,7 +64,7 @@ extern Options options;
  */
 
 u_char *session_id2 = NULL;
-int session_id2_len = 0;
+u_int session_id2_len = 0;
 
 char *xxx_host;
 struct sockaddr *xxx_hostaddr;
@@ -109,7 +111,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
 #endif
 
        if (options.ciphers == (char *)-1) {
-               log("No valid ciphers for protocol version 2 given, using defaults.");
+               logit("No valid ciphers for protocol version 2 given, using defaults.");
                options.ciphers = NULL;
        }
        if (options.ciphers != NULL) {
@@ -145,6 +147,10 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
                 snprintf(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS],len,"%s,null",orig);
        }
 #endif
+
+       if (options.rekey_limit)
+               packet_set_rekey_limit(options.rekey_limit);
+
        /* start key exchange */
        kex = kex_setup(myproposal);
        kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client;
@@ -158,6 +164,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
 #ifdef GSSAPI
        kex->options.gss_deleg_creds=options.gss_deleg_creds;
 #endif
+
        xxx_kex = kex;
 
        dispatch_run(DISPATCH_BLOCK, &kex->done, kex);
@@ -180,10 +187,18 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
 
 typedef struct Authctxt Authctxt;
 typedef struct Authmethod Authmethod;
-
-typedef int sign_cb_fn(
-    Authctxt *authctxt, Key *key,
-    u_char **sigp, u_int *lenp, u_char *data, u_int datalen);
+typedef struct identity Identity;
+typedef struct idlist Idlist;
+
+struct identity {
+       TAILQ_ENTRY(identity) next;
+       AuthenticationConnection *ac;   /* set if agent supports key */
+       Key     *key;                   /* public/private key */
+       char    *filename;              /* comment for agent-only keys */
+       int     tried;
+       int     isprivate;              /* key points to the private key */
+};
+TAILQ_HEAD(idlist, identity);
 
 struct Authctxt {
        const char *server_user;
@@ -194,9 +209,7 @@ struct Authctxt {
        int success;
        char *authlist;
        /* pubkey */
-       Key *last_key;
-       sign_cb_fn *last_key_sign;
-       int last_key_hint;
+       Idlist keys;
        AuthenticationConnection *agent;
        /* hostbased */
        Sensitive *sensitive;
@@ -225,6 +238,16 @@ int        userauth_pubkey(Authctxt *);
 int    userauth_passwd(Authctxt *);
 int    userauth_kbdint(Authctxt *);
 int    userauth_hostbased(Authctxt *);
+int    userauth_kerberos(Authctxt *);
+
+#ifdef GSSAPI
+int    userauth_gssapi(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 *);
+void   input_gssapi_error(int, u_int32_t, void *);
+void   input_gssapi_errtok(int, u_int32_t, void *);
+#endif
 
 #ifdef GSSAPI
 int    userauth_external(Authctxt *authctxt);
@@ -238,8 +261,10 @@ void       input_gssapi_errtok(int, u_int32_t, void *);
 
 void   userauth(Authctxt *, char *);
 
-static int sign_and_send_pubkey(Authctxt *, Key *, sign_cb_fn *);
-static void clear_auth_state(Authctxt *);
+static int sign_and_send_pubkey(Authctxt *, Identity *);
+static void pubkey_prepare(Authctxt *);
+static void pubkey_cleanup(Authctxt *);
+static Key *load_identity_file(char *);
 
 static Authmethod *authmethod_get(char *authlist);
 static Authmethod *authmethod_lookup(const char *name);
@@ -312,7 +337,7 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host,
 
        /* setup authentication context */
        memset(&authctxt, 0, sizeof(authctxt));
-       authctxt.agent = ssh_get_authentication_connection();
+       pubkey_prepare(&authctxt);
        authctxt.server_user = server_user;
        authctxt.local_user = local_user;
        authctxt.host = host;
@@ -335,19 +360,19 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host,
        dispatch_set(SSH2_MSG_USERAUTH_BANNER, &input_userauth_banner);
        dispatch_run(DISPATCH_BLOCK, &authctxt.success, &authctxt);     /* loop until success */
 
-       if (authctxt.agent != NULL)
-               ssh_close_authentication_connection(authctxt.agent);
+       pubkey_cleanup(&authctxt);
+       dispatch_range(SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL);
 
        debug("Authentication succeeded (%s).", authctxt.method->name);
 }
+
 void
 userauth(Authctxt *authctxt, char *authlist)
 {
-       if (authctxt->methoddata!=NULL) {
+       if (authctxt->methoddata) {
                xfree(authctxt->methoddata);
-               authctxt->methoddata=NULL;
+               authctxt->methoddata = NULL;
        }
-           
        if (authlist == NULL) {
                authlist = authctxt->authlist;
        } else {
@@ -360,6 +385,12 @@ userauth(Authctxt *authctxt, char *authlist)
                if (method == NULL)
                        fatal("Permission denied (%s).", authlist);
                authctxt->method = method;
+
+               /* reset the per method handler */
+               dispatch_range(SSH2_MSG_USERAUTH_PER_METHOD_MIN,
+                   SSH2_MSG_USERAUTH_PER_METHOD_MAX, NULL);
+
+               /* and try new method */
                if (method->userauth(authctxt) != 0) {
                        debug2("we sent a %s packet, wait for reply", method->name);
                        break;
@@ -384,7 +415,7 @@ input_userauth_banner(int type, u_int32_t seq, void *ctxt)
        debug3("input_userauth_banner");
        msg = packet_get_string(NULL);
        lang = packet_get_string(NULL);
-       fprintf(stderr, "%s", msg);
+       logit("%s", msg);
        xfree(msg);
        xfree(lang);
 }
@@ -399,7 +430,6 @@ input_userauth_success(int type, u_int32_t seq, void *ctxt)
                xfree(authctxt->authlist);
        if (authctxt->methoddata)
                xfree(authctxt->methoddata);
-       clear_auth_state(authctxt);
        authctxt->success = 1;                  /* break out */
 }
 
@@ -418,10 +448,9 @@ input_userauth_failure(int type, u_int32_t seq, void *ctxt)
        packet_check_eom();
 
        if (partial != 0)
-               log("Authenticated with partial success.");
+               logit("Authenticated with partial success.");
        debug("Authentications that can continue: %s", authlist);
 
-       clear_auth_state(authctxt);
        userauth(authctxt, authlist);
 }
 void
@@ -429,6 +458,7 @@ input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt)
 {
        Authctxt *authctxt = ctxt;
        Key *key = NULL;
+       Identity *id = NULL;
        Buffer b;
        int pktype, sent = 0;
        u_int alen, blen;
@@ -451,53 +481,41 @@ input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt)
        }
        packet_check_eom();
 
-       debug("Server accepts key: pkalg %s blen %u lastkey %p hint %d",
-           pkalg, blen, authctxt->last_key, authctxt->last_key_hint);
+       debug("Server accepts key: pkalg %s blen %u", pkalg, blen);
 
-       do {
-               if (authctxt->last_key == NULL ||
-                   authctxt->last_key_sign == NULL) {
-                       debug("no last key or no sign cb");
-                       break;
-               }
-               if ((pktype = key_type_from_name(pkalg)) == KEY_UNSPEC) {
-                       debug("unknown pkalg %s", pkalg);
-                       break;
-               }
-               if ((key = key_from_blob(pkblob, blen)) == NULL) {
-                       debug("no key from blob. pkalg %s", pkalg);
-                       break;
-               }
-               if (key->type != pktype) {
-                       error("input_userauth_pk_ok: type mismatch "
-                           "for decoded key (received %d, expected %d)",
-                           key->type, pktype);
-                       break;
-               }
-               fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
-               debug2("input_userauth_pk_ok: fp %s", fp);
-               xfree(fp);
-               if (!key_equal(key, authctxt->last_key)) {
-                       debug("key != last_key");
+       if ((pktype = key_type_from_name(pkalg)) == KEY_UNSPEC) {
+               debug("unknown pkalg %s", pkalg);
+               goto done;
+       }
+       if ((key = key_from_blob(pkblob, blen)) == NULL) {
+               debug("no key from blob. pkalg %s", pkalg);
+               goto done;
+       }
+       if (key->type != pktype) {
+               error("input_userauth_pk_ok: type mismatch "
+                   "for decoded key (received %d, expected %d)",
+                   key->type, pktype);
+               goto done;
+       }
+       fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
+       debug2("input_userauth_pk_ok: fp %s", fp);
+       xfree(fp);
+
+       TAILQ_FOREACH(id, &authctxt->keys, next) {
+               if (key_equal(key, id->key)) {
+                       sent = sign_and_send_pubkey(authctxt, id);
                        break;
                }
-               sent = sign_and_send_pubkey(authctxt, key,
-                  authctxt->last_key_sign);
-       } while (0);
-
+       }
+done:
        if (key != NULL)
                key_free(key);
        xfree(pkalg);
        xfree(pkblob);
 
-       /* unregister */
-       clear_auth_state(authctxt);
-       dispatch_set(SSH2_MSG_USERAUTH_PK_OK, NULL);
-
        /* try another method if we did not send a packet */
        if (sent == 0)
                userauth(authctxt, NULL);
-
 }
 
 #ifdef GSSAPI
@@ -506,143 +524,127 @@ userauth_gssapi(Authctxt *authctxt)
 {
        Gssctxt *gssctxt = NULL;
        static gss_OID_set supported = NULL;
-       static int mech=0;
+       static int mech = 0;
        OM_uint32 min;
-       int ok=0;
+       int ok = 0;
 
        if (!options.gss_authentication) {
                verbose("GSSAPI authentication disabled.");
                return 0;
        }
 
-       /* Things work better if we send one mechanism at a time, rather
-        * than them all at once. This means that if we fail at some point
-        * in the middle of a negotiation, we can come back and try something
-        * different. */
+       /* Try one GSSAPI method at a time, rather than sending them all at
+        * once. */
 
-       if (datafellows & SSH_OLD_GSSAPI) return 0;
-       
-       /* Before we offer a mechanism, check that we can support it. Don't
-        * bother trying to get credentials - as the standard fallback will
-        * deal with that kind of failure.
-        */
+       if (supported == NULL)
+               gss_indicate_mechs(&min, &supported);
 
-       if (supported==NULL) gss_indicate_mechs(&min, &supported);
-       
+       /* Check to see if the mechanism is usable before we offer it */
        while (mech<supported->count && !ok) {
-               if (gssctxt) ssh_gssapi_delete_ctx(&gssctxt);
+               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, &supported->elements[mech]);
 
-               /* The DER encoding below only works for lengths<128,
-                * so check this here 
-                */
-               if (supported->elements[mech].length<128 &&
+               /* My DER encoding requires length<128 */
+               if (supported->elements[mech].length < 128 &&
                    !GSS_ERROR(ssh_gssapi_import_name(gssctxt,
-                                                     authctxt->host))) {
-                       ok = 1; /* Mechanism works */
+                   authctxt->host))) {
+                       ok = 1; /* Mechanism works */
                } else {
                        mech++;
                }
        }
-       
+
        if (!ok) return 0;
-       
+
        authctxt->methoddata=(void *)gssctxt;
-               
+
        packet_start(SSH2_MSG_USERAUTH_REQUEST);
        packet_put_cstring(authctxt->server_user);
        packet_put_cstring(authctxt->service);
-        packet_put_cstring(authctxt->method->name);
-       
+       packet_put_cstring(authctxt->method->name);
+
        packet_put_int(1);
 
-       /* The newest gsskeyex draft stipulates that OIDs should
-        * be DER encoded, so we need to add the object type and
-        * length information back on */
+       /* 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);
+                   supported->elements[mech].length);
        } else {
                packet_put_int((supported->elements[mech].length)+2);
-               packet_put_char(0x06);
+               packet_put_char(SSH_GSS_OIDTYPE);
                packet_put_char(supported->elements[mech].length);
                packet_put_raw(supported->elements[mech].elements,
-                              supported->elements[mech].length);
+                   supported->elements[mech].length);
        }
 
-        packet_send();
-        packet_write_wait();
+       packet_send();
+
+       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE, &input_gssapi_response);
+       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token);
+       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERROR, &input_gssapi_error);
+       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok);
 
-        dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE,&input_gssapi_response);
-        dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN,&input_gssapi_token);
-       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERROR,&input_gssapi_error);
-       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK,&input_gssapi_errtok);
-       
        mech++; /* Move along to next candidate */
 
-        return 1;
+       return 1;
 }
 
 void
-input_gssapi_response(int type, u_int32_t plen, void *ctxt) 
+input_gssapi_response(int type, u_int32_t plen, void *ctxt)
 {
        Authctxt *authctxt = ctxt;
        Gssctxt *gssctxt;
-       OM_uint32 status,ms;
+       OM_uint32 status, ms;
        int oidlen;
        char *oidv;
-       gss_buffer_desc send_tok;
-       
+       gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
+
        if (authctxt == NULL)
                fatal("input_gssapi_response: no authentication context");
        gssctxt = authctxt->methoddata;
-       
+
        /* Setup our OID */
-       oidv=packet_get_string(&oidlen);
-       
+       oidv = packet_get_string(&oidlen);
+
        if (datafellows & SSH_BUG_GSSAPI_BER) {
-               if (!ssh_gssapi_check_oid(gssctxt,oidv,oidlen)) {
+               if (!ssh_gssapi_check_oid(gssctxt, oidv, oidlen))
                        fatal("Server returned different OID than expected");
-               }
-               ssh_gssapi_set_oid_data(gssctxt,oidv,oidlen);
        } else {
-               if(oidv[0]!=0x06 || oidv[1]!=oidlen-2) {
+               if(oidv[0] != SSH_GSS_OIDTYPE || oidv[1] != oidlen-2) {
                        debug("Badly encoded mechanism OID received");
-                       clear_auth_state(authctxt);
-                       userauth(authctxt,NULL);
+                       userauth(authctxt, NULL);
+                       xfree(oidv);
                        return;
                }
-               if (!ssh_gssapi_check_oid(gssctxt,oidv+2,oidlen-2)) {
+               if (!ssh_gssapi_check_oid(gssctxt, oidv+2, oidlen-2))
                        fatal("Server returned different OID than expected");
-               }
-               ssh_gssapi_set_oid_data(gssctxt,oidv+2,oidlen-2);
        }
-               
+
        packet_check_eom();
-       
+
+       xfree(oidv);
+
        status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
-                                    GSS_C_NO_BUFFER, &send_tok, 
-                                    NULL);
+           GSS_C_NO_BUFFER, &send_tok, NULL);
        if (GSS_ERROR(status)) {
-               if (send_tok.length>0) {
+               if (send_tok.length > 0) {
                        packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK);
-                       packet_put_string(send_tok.value,send_tok.length);
+                       packet_put_string(send_tok.value, send_tok.length);
                        packet_send();
-                       packet_write_wait();
+                       gss_release_buffer(&ms, &send_tok);
                }
                /* Start again with next method on list */
                debug("Trying to start again");
-               clear_auth_state(authctxt);
-               userauth(authctxt,NULL);
+               userauth(authctxt, NULL);
                return;
        }
 
-       /* We must have data to send */                                 
+       /* We must have data to send */
        packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
-       packet_put_string(send_tok.value,send_tok.length);
+       packet_put_string(send_tok.value, send_tok.length);
        packet_send();
-       packet_write_wait();
        gss_release_buffer(&ms, &send_tok);
 }
 
@@ -651,47 +653,48 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
 {
        Authctxt *authctxt = ctxt;
        Gssctxt *gssctxt;
-       gss_buffer_desc send_tok,recv_tok;
-       OM_uint32 status;
+       gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
+       gss_buffer_desc recv_tok;
+       OM_uint32 status, ms;
        u_int slen;
-       
+
        if (authctxt == NULL)
-               fatal("input_gssapi_token: no authentication context");
+               fatal("input_gssapi_response: no authentication context");
        gssctxt = authctxt->methoddata;
-       
-       recv_tok.value=packet_get_string(&slen);
-       recv_tok.length=slen;   /* safe typecast */
 
-       status=ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
-                                  &recv_tok, &send_tok, NULL);
+       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);
+
+       xfree(recv_tok.value);
+
        if (GSS_ERROR(status)) {
-               if (send_tok.length>0) {
+               if (send_tok.length > 0) {
                        packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK);
-                       packet_put_string(send_tok.value,send_tok.length);
+                       packet_put_string(send_tok.value, send_tok.length);
                        packet_send();
-                       packet_write_wait();
+                       gss_release_buffer(&ms, &send_tok);
                }
                /* Start again with the next method in the list */
-               clear_auth_state(authctxt);
-               userauth(authctxt,NULL);
+               userauth(authctxt, NULL);
                return;
        }
-       
-       if (send_tok.length>0) {
+
+       if (send_tok.length > 0) {
                packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
-               packet_put_string(send_tok.value,send_tok.length);
+               packet_put_string(send_tok.value, send_tok.length);
                packet_send();
-               packet_write_wait();
+               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();
-               packet_write_wait();
        }
 }
 
@@ -700,45 +703,45 @@ input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
 {
        Authctxt *authctxt = ctxt;
        Gssctxt *gssctxt;
-       gss_buffer_desc send_tok,recv_tok;
-       OM_uint32 status;
-       
+       gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
+       gss_buffer_desc recv_tok;
+       OM_uint32 status, ms;
+       u_int len;
+
        if (authctxt == NULL)
                fatal("input_gssapi_response: no authentication context");
        gssctxt = authctxt->methoddata;
-       
-       recv_tok.value=packet_get_string(&recv_tok.length);
 
-       /* Stick it into GSSAPI and see what it says */
-       status=ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
-                                  &recv_tok, &send_tok, NULL);
+       recv_tok.value = packet_get_string(&len);
+       recv_tok.length = len;
 
        packet_check_eom();
-       
-       /* We can't send a packet to the server */
-
-       /* The draft says that we should wait for the server to fail 
-        * before starting the next authentication. So, we clear the
-        * state, but don't do anything else */
-       clear_auth_state(authctxt);
-       return;
+
+       /* Stick it into GSSAPI and see what it says */
+       status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
+                                    &recv_tok, &send_tok, NULL);
+
+       xfree(recv_tok.value);
+       gss_release_buffer(&ms, &send_tok);
+
+       /* Server will be returning a failed packet after this one */
 }
 
 void
 input_gssapi_error(int type, u_int32_t plen, void *ctxt)
 {
-       OM_uint32 maj,min;
+       OM_uint32 maj, min;
        char *msg;
        char *lang;
-       
+
        maj=packet_get_int();
        min=packet_get_int();
        msg=packet_get_string(NULL);
        lang=packet_get_string(NULL);
 
        packet_check_eom();
-       
-       fprintf(stderr, "Server GSSAPI Error:\n%s\n", msg);
+
+       debug("Server GSSAPI Error:\n%s\n", msg);
        xfree(msg);
        xfree(lang);
 }
@@ -746,7 +749,7 @@ input_gssapi_error(int type, u_int32_t plen, void *ctxt)
 int
 userauth_external(Authctxt *authctxt)
 {
-        static int attempt =0;
+        static int attempt = 0;
         
         if (attempt++ >= 1)
                return 0;
@@ -780,7 +783,6 @@ userauth_none(Authctxt *authctxt)
        packet_put_cstring(authctxt->method->name);
        packet_send();
        return 1;
-
 }
 
 int
@@ -834,7 +836,7 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
        info = packet_get_string(NULL);
        lang = packet_get_string(NULL);
        if (strlen(info) > 0)
-               log("%s", info);
+               logit("%s", info);
        xfree(info);
        xfree(lang);
        packet_start(SSH2_MSG_USERAUTH_REQUEST);
@@ -866,7 +868,7 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
                if (strcmp(password, retype) != 0) {
                        memset(password, 0, strlen(password));
                        xfree(password);
-                       log("Mismatch; try again, EOF to quit.");
+                       logit("Mismatch; try again, EOF to quit.");
                        password = NULL;
                }
                memset(retype, 0, strlen(retype));
@@ -882,39 +884,44 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
            &input_userauth_passwd_changereq);
 }
 
-static void
-clear_auth_state(Authctxt *authctxt)
+static int
+identity_sign(Identity *id, u_char **sigp, u_int *lenp,
+    u_char *data, u_int datalen)
 {
-       /* XXX clear authentication state */
-       dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, NULL);
-#ifdef GSSAPI
-       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE,NULL);
-       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN,NULL);
-       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERROR,NULL);
-#endif
-       
-       if (authctxt->last_key != NULL && authctxt->last_key_hint == -1) {
-               debug3("clear_auth_state: key_free %p", authctxt->last_key);
-               key_free(authctxt->last_key);
-       }
-       authctxt->last_key = NULL;
-       authctxt->last_key_hint = -2;
-       authctxt->last_key_sign = NULL;
+       Key *prv;
+       int ret;
+
+       /* the agent supports this key */
+       if (id->ac)
+               return (ssh_agent_sign(id->ac, id->key, sigp, lenp,
+                   data, datalen));
+       /*
+        * we have already loaded the private key or
+        * the private key is stored in external hardware
+        */
+       if (id->isprivate || (id->key->flags & KEY_FLAG_EXT))
+               return (key_sign(id->key, sigp, lenp, data, datalen));
+       /* load the private key from the file */
+       if ((prv = load_identity_file(id->filename)) == NULL)
+               return (-1);
+       ret = key_sign(prv, sigp, lenp, data, datalen);
+       key_free(prv);
+       return (ret);
 }
 
 static int
-sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
+sign_and_send_pubkey(Authctxt *authctxt, Identity *id)
 {
        Buffer b;
        u_char *blob, *signature;
        u_int bloblen, slen;
-       int skip = 0;
+       u_int skip = 0;
        int ret = -1;
        int have_sig = 1;
 
        debug3("sign_and_send_pubkey");
 
-       if (key_to_blob(k, &blob, &bloblen) == 0) {
+       if (key_to_blob(id->key, &blob, &bloblen) == 0) {
                /* we cannot handle this key */
                debug3("sign_and_send_pubkey: cannot handle key");
                return 0;
@@ -939,12 +946,12 @@ sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
        } else {
                buffer_put_cstring(&b, authctxt->method->name);
                buffer_put_char(&b, have_sig);
-               buffer_put_cstring(&b, key_ssh_name(k));
+               buffer_put_cstring(&b, key_ssh_name(id->key));
        }
        buffer_put_string(&b, blob, bloblen);
 
        /* generate signature */
-       ret = (*sign_callback)(authctxt, k, &signature, &slen,
+       ret = identity_sign(id, &signature, &slen,
            buffer_ptr(&b), buffer_len(&b));
        if (ret == -1) {
                xfree(blob);
@@ -964,7 +971,7 @@ sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
                buffer_put_cstring(&b, authctxt->method->name);
                buffer_put_char(&b, have_sig);
                if (!(datafellows & SSH_BUG_PKAUTH))
-                       buffer_put_cstring(&b, key_ssh_name(k));
+                       buffer_put_cstring(&b, key_ssh_name(id->key));
                buffer_put_string(&b, blob, bloblen);
        }
        xfree(blob);
@@ -988,23 +995,19 @@ sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
 }
 
 static int
-send_pubkey_test(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback,
-    int hint)
+send_pubkey_test(Authctxt *authctxt, Identity *id)
 {
        u_char *blob;
        u_int bloblen, have_sig = 0;
 
        debug3("send_pubkey_test");
 
-       if (key_to_blob(k, &blob, &bloblen) == 0) {
+       if (key_to_blob(id->key, &blob, &bloblen) == 0) {
                /* we cannot handle this key */
                debug3("send_pubkey_test: cannot handle key");
                return 0;
        }
        /* register callback for USERAUTH_PK_OK message */
-       authctxt->last_key_sign = sign_callback;
-       authctxt->last_key_hint = hint;
-       authctxt->last_key = k;
        dispatch_set(SSH2_MSG_USERAUTH_PK_OK, &input_userauth_pk_ok);
 
        packet_start(SSH2_MSG_USERAUTH_REQUEST);
@@ -1013,7 +1016,7 @@ send_pubkey_test(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback,
        packet_put_cstring(authctxt->method->name);
        packet_put_char(have_sig);
        if (!(datafellows & SSH_BUG_PKAUTH))
-               packet_put_cstring(key_ssh_name(k));
+               packet_put_cstring(key_ssh_name(id->key));
        packet_put_string(blob, bloblen);
        xfree(blob);
        packet_send();
@@ -1058,103 +1061,134 @@ load_identity_file(char *filename)
        return private;
 }
 
-static int
-identity_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, u_int *lenp,
-    u_char *data, u_int datalen)
-{
-       Key *private;
-       int idx, ret;
-
-       idx = authctxt->last_key_hint;
-       if (idx < 0)
-               return -1;
-
-       /* private key is stored in external hardware */
-       if (options.identity_keys[idx]->flags & KEY_FLAG_EXT)
-               return key_sign(options.identity_keys[idx], sigp, lenp, data, datalen);
-
-       private = load_identity_file(options.identity_files[idx]);
-       if (private == NULL)
-               return -1;
-       ret = key_sign(private, sigp, lenp, data, datalen);
-       key_free(private);
-       return ret;
-}
-
-static int
-agent_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, u_int *lenp,
-    u_char *data, u_int datalen)
-{
-       return ssh_agent_sign(authctxt->agent, key, sigp, lenp, data, datalen);
-}
-
-static int
-key_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, u_int *lenp,
-    u_char *data, u_int datalen)
+/*
+ * try keys in the following order:
+ *     1. agent keys that are found in the config file
+ *     2. other agent keys
+ *     3. keys that are only listed in the config file
+ */
+static void
+pubkey_prepare(Authctxt *authctxt)
 {
-       return key_sign(key, sigp, lenp, data, datalen);
+       Identity *id;
+       Idlist agent, files, *preferred;
+       Key *key;
+       AuthenticationConnection *ac;
+       char *comment;
+       int i, found;
+
+       TAILQ_INIT(&agent);     /* keys from the agent */
+       TAILQ_INIT(&files);     /* keys from the config file */
+       preferred = &authctxt->keys;
+       TAILQ_INIT(preferred);  /* preferred order of keys */
+
+       /* list of keys stored in the filesystem */
+       for (i = 0; i < options.num_identity_files; i++) {
+               key = options.identity_keys[i];
+               if (key && key->type == KEY_RSA1)
+                       continue;
+               options.identity_keys[i] = NULL;
+               id = xmalloc(sizeof(*id));
+               memset(id, 0, sizeof(*id));
+               id->key = key;
+               id->filename = xstrdup(options.identity_files[i]);
+               TAILQ_INSERT_TAIL(&files, id, next);
+       }
+       /* list of keys supported by the agent */
+       if ((ac = ssh_get_authentication_connection())) {
+               for (key = ssh_get_first_identity(ac, &comment, 2);
+                   key != NULL;
+                   key = ssh_get_next_identity(ac, &comment, 2)) {
+                       found = 0;
+                       TAILQ_FOREACH(id, &files, next) {
+                               /* agent keys from the config file are preferred */ 
+                               if (key_equal(key, id->key)) {
+                                       key_free(key);
+                                       xfree(comment);
+                                       TAILQ_REMOVE(&files, id, next);
+                                       TAILQ_INSERT_TAIL(preferred, id, next);
+                                       id->ac = ac;
+                                       found = 1;
+                                       break;
+                               }
+                       }
+                       if (!found) {
+                               id = xmalloc(sizeof(*id));
+                               memset(id, 0, sizeof(*id));
+                               id->key = key;
+                               id->filename = comment;
+                               id->ac = ac;
+                               TAILQ_INSERT_TAIL(&agent, id, next);
+                       }
+               }
+               /* append remaining agent keys */
+               for (id = TAILQ_FIRST(&agent); id; id = TAILQ_FIRST(&agent)) {
+                       TAILQ_REMOVE(&agent, id, next);
+                       TAILQ_INSERT_TAIL(preferred, id, next);
+               }
+               authctxt->agent = ac;
+       }
+       /* append remaining keys from the config file */
+       for (id = TAILQ_FIRST(&files); id; id = TAILQ_FIRST(&files)) {
+               TAILQ_REMOVE(&files, id, next);
+               TAILQ_INSERT_TAIL(preferred, id, next);
+       }
+       TAILQ_FOREACH(id, preferred, next) {
+               debug2("key: %s (%p)", id->filename, id->key);
+       }
 }
 
-static int
-userauth_pubkey_agent(Authctxt *authctxt)
+static void
+pubkey_cleanup(Authctxt *authctxt)
 {
-       static int called = 0;
-       int ret = 0;
-       char *comment;
-       Key *k;
-
-       if (called == 0) {
-               if (ssh_get_num_identities(authctxt->agent, 2) == 0)
-                       debug2("userauth_pubkey_agent: no keys at all");
-               called = 1;
-       }
-       k = ssh_get_next_identity(authctxt->agent, &comment, 2);
-       if (k == NULL) {
-               debug2("userauth_pubkey_agent: no more keys");
-       } else {
-               debug("Offering agent key: %s", comment);
-               xfree(comment);
-               ret = send_pubkey_test(authctxt, k, agent_sign_cb, -1);
-               if (ret == 0)
-                       key_free(k);
+       Identity *id;
+
+       if (authctxt->agent != NULL)
+               ssh_close_authentication_connection(authctxt->agent);
+       for (id = TAILQ_FIRST(&authctxt->keys); id;
+           id = TAILQ_FIRST(&authctxt->keys)) {
+               TAILQ_REMOVE(&authctxt->keys, id, next);
+               if (id->key)
+                       key_free(id->key);
+               if (id->filename)
+                       xfree(id->filename);
+               xfree(id);
        }
-       if (ret == 0)
-               debug2("userauth_pubkey_agent: no message sent");
-       return ret;
 }
 
 int
 userauth_pubkey(Authctxt *authctxt)
 {
-       static int idx = 0;
+       Identity *id;
        int sent = 0;
-       Key *key;
-       char *filename;
 
-       if (authctxt->agent != NULL) {
-               do {
-                       sent = userauth_pubkey_agent(authctxt);
-               } while (!sent && authctxt->agent->howmany > 0);
-       }
-       while (!sent && idx < options.num_identity_files) {
-               key = options.identity_keys[idx];
-               filename = options.identity_files[idx];
-               if (key == NULL) {
-                       debug("Trying private key: %s", filename);
-                       key = load_identity_file(filename);
-                       if (key != NULL) {
-                               sent = sign_and_send_pubkey(authctxt, key,
-                                   key_sign_cb);
-                               key_free(key);
+       while ((id = TAILQ_FIRST(&authctxt->keys))) {
+               if (id->tried++)
+                       return (0);
+               TAILQ_REMOVE(&authctxt->keys, id, next);
+               TAILQ_INSERT_TAIL(&authctxt->keys, id, next);
+               /*
+                * send a test message if we have the public key. for
+                * encrypted keys we cannot do this and have to load the
+                * private key instead
+                */
+               if (id->key && id->key->type != KEY_RSA1) {
+                       debug("Offering public key: %s", id->filename);
+                       sent = send_pubkey_test(authctxt, id);
+               } else if (id->key == NULL) {
+                       debug("Trying private key: %s", id->filename);
+                       id->key = load_identity_file(id->filename);
+                       if (id->key != NULL) {
+                               id->isprivate = 1;
+                               sent = sign_and_send_pubkey(authctxt, id);
+                               key_free(id->key);
+                               id->key = NULL;
                        }
-               } else if (key->type != KEY_RSA1) {
-                       debug("Offering public key: %s", filename);
-                       sent = send_pubkey_test(authctxt, key,
-                           identity_sign_cb, idx);
                }
-               idx++;
+               if (sent)
+                       return (sent);
        }
-       return sent;
+       return (0);
 }
 
 /*
@@ -1210,9 +1244,9 @@ input_userauth_info_req(int type, u_int32_t seq, void *ctxt)
        inst = packet_get_string(NULL);
        lang = packet_get_string(NULL);
        if (strlen(name) > 0)
-               log("%s", name);
+               logit("%s", name);
        if (strlen(inst) > 0)
-               log("%s", inst);
+               logit("%s", inst);
        xfree(name);
        xfree(inst);
        xfree(lang);
index a99c4f16273b45b3c63032b1d570eca2787e8c83..0eeea666683e2eda69e7aebffe07e6b55890b278 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.194 2003/01/31 21:54:40 jmc Exp $
+.\" $OpenBSD: sshd.8,v 1.199 2003/08/13 08:46:31 markus Exp $
 .Dd September 25, 1999
 .Dt SSHD 8
 .Os
@@ -114,6 +114,29 @@ authentication combined with RSA host
 authentication, RSA challenge-response authentication, or password
 based authentication.
 .Pp
+Regardless of the authentication type, the account is checked to
+ensure that it is accessible.  An account is not accessible if it is
+locked, listed in
+.Cm DenyUsers
+or its group is listed in
+.Cm DenyGroups
+\&.  The definition of a locked account is system dependant. Some platforms
+have their own account database (eg AIX) and some modify the passwd field (
+.Ql \&*LK\&*
+on Solaris,
+.Ql \&*
+on HP-UX, containing
+.Ql Nologin
+on Tru64 and a leading
+.Ql \&!!
+on Linux).  If there is a requirement to disable password authentication
+for the account while allowing still public-key, then the passwd field
+should be set to something other than these values (eg
+.Ql NP
+or
+.Ql \&*NP\&*
+).
+.Pp
 Rhosts authentication is normally disabled
 because it is fundamentally insecure, but can be enabled in the server
 configuration file if desired.
@@ -292,7 +315,6 @@ may also be used to prevent
 from making DNS requests unless the authentication
 mechanism or configuration requires it.
 Authentication mechanisms that may require DNS include
-.Cm RhostsAuthentication ,
 .Cm RhostsRSAAuthentication ,
 .Cm HostbasedAuthentication
 and using a
@@ -429,13 +451,13 @@ that option keywords are case-insensitive):
 Specifies that in addition to public key authentication, the canonical name
 of the remote host must be present in the comma-separated list of
 patterns
-.Pf ( Ql *
+.Pf ( Ql \&*
 and
-.Ql ?
+.Ql \&?
 serve as wildcards).
 The list may also contain
 patterns negated by prefixing them with
-.Ql ! ;
+.Ql \&! ;
 if the canonical host name matches a negated pattern, the key is not accepted.
 The purpose
 of this option is to optionally increase security: public key authentication
@@ -497,9 +519,9 @@ IPv6 addresses can be specified with an alternative syntax:
 .Ar host/port .
 Multiple
 .Cm permitopen
-options may be applied separated by commas. No pattern matching is
-performed on the specified hostnames, they must be literal domains or
-addresses.
+options may be applied separated by commas.
+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
@@ -524,12 +546,16 @@ Each line in these files contains the following fields: hostnames,
 bits, exponent, modulus, comment.
 The fields are separated by spaces.
 .Pp
-Hostnames is a comma-separated list of patterns ('*' and '?' act as
+Hostnames is a comma-separated list of patterns
+.Pf ( Ql \&*
+and
+.Ql \&?
+act as
 wildcards); each pattern in turn is matched against the canonical host
 name (when authenticating a client) or against the user-supplied
 name (when authenticating a server).
 A pattern may also be preceded by
-.Ql !
+.Ql \&!
 to indicate negation: if the host name matches a negated
 pattern, it is not accepted (by that line) even if it matched another
 pattern on the line.
@@ -767,17 +793,6 @@ This can be used to specify
 machine-specific login-time initializations globally.
 This file should be writable only by root, and should be world-readable.
 .El
-.Sh AUTHORS
-OpenSSH is a derivative of the original and free
-ssh 1.2.12 release by Tatu Ylonen.
-Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos,
-Theo de Raadt and Dug Song
-removed many bugs, re-added newer features and
-created OpenSSH.
-Markus Friedl contributed the support for SSH
-protocol versions 1.5 and 2.0.
-Niels Provos and Markus Friedl contributed support
-for privilege separation.
 .Sh SEE ALSO
 .Xr scp 1 ,
 .Xr sftp 1 ,
@@ -809,3 +824,14 @@ for privilege separation.
 .%D January 2002
 .%O work in progress material
 .Re
+.Sh AUTHORS
+OpenSSH is a derivative of the original and free
+ssh 1.2.12 release by Tatu Ylonen.
+Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos,
+Theo de Raadt and Dug Song
+removed many bugs, re-added newer features and
+created OpenSSH.
+Markus Friedl contributed the support for SSH
+protocol versions 1.5 and 2.0.
+Niels Provos and Markus Friedl contributed support
+for privilege separation.
index baf31fd4cfdc869a6aaf0d4f9ecb485461010643..e4dcf89dd619c2bc69589fd7be82a62d74fe74d9 100644 (file)
@@ -42,7 +42,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshd.c,v 1.263 2003/02/16 17:09:57 markus Exp $");
+RCSID("$OpenBSD: sshd.c,v 1.276 2003/08/28 12:54:34 markus Exp $");
 
 #include <openssl/dh.h>
 #include <openssl/bn.h>
@@ -121,11 +121,7 @@ char *config_file_name = _PATH_SERVER_CONFIG_FILE;
  * Flag indicating whether IPv4 or IPv6.  This can be set on the command line.
  * Default value is AF_UNSPEC means both IPv4 and IPv6.
  */
-#ifdef IPV4_DEFAULT
-int IPv4or6 = AF_INET;
-#else
 int IPv4or6 = AF_UNSPEC;
-#endif
 
 /*
  * Debug mode flag.  This can be set on the command line.  If debug
@@ -201,7 +197,7 @@ u_char session_id[16];
 
 /* same for ssh2 */
 u_char *session_id2 = NULL;
-int session_id2_len = 0;
+u_int session_id2_len = 0;
 
 /* record remote hostname or ip */
 u_int utmp_len = MAXHOSTNAMELEN;
@@ -214,6 +210,9 @@ int startup_pipe;           /* in child */
 int use_privsep;
 struct monitor *pmonitor;
 
+/* message to be displayed after login */
+Buffer loginmsg;
+
 /* Prototypes for various functions defined later in this file. */
 void destroy_sensitive_data(void);
 void demote_sensitive_data(void);
@@ -267,11 +266,11 @@ sighup_handler(int sig)
 static void
 sighup_restart(void)
 {
-       log("Received SIGHUP; restarting.");
+       logit("Received SIGHUP; restarting.");
        close_listen_socks();
        close_startup_pipes();
        execv(saved_argv[0], saved_argv);
-       log("RESTART FAILED: av[0]='%.100s', error: %.100s.", saved_argv[0],
+       logit("RESTART FAILED: av[0]='%.100s', error: %.100s.", saved_argv[0],
            strerror(errno));
        exit(1);
 }
@@ -380,39 +379,37 @@ sshd_exchange_identification(int sock_in, int sock_out)
        snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, SSH_VERSION);
        server_version_string = xstrdup(buf);
 
-       if (client_version_string == NULL) {
-               /* Send our protocol version identification. */
-               if (atomicio(write, sock_out, server_version_string,
-                   strlen(server_version_string))
-                   != strlen(server_version_string)) {
-                       log("Could not write ident string to %s", get_remote_ipaddr());
+       /* Send our protocol version identification. */
+       if (atomicio(vwrite, sock_out, server_version_string,
+           strlen(server_version_string))
+           != strlen(server_version_string)) {
+               logit("Could not write ident string to %s", get_remote_ipaddr());
+               fatal_cleanup();
+       }
+
+       /* Read other sides version identification. */
+       memset(buf, 0, sizeof(buf));
+       for (i = 0; i < sizeof(buf) - 1; i++) {
+               if (atomicio(read, sock_in, &buf[i], 1) != 1) {
+                       logit("Did not receive identification string from %s",
+                           get_remote_ipaddr());
                        fatal_cleanup();
                }
-
-               /* Read other sides version identification. */
-               memset(buf, 0, sizeof(buf));
-               for (i = 0; i < sizeof(buf) - 1; i++) {
-                       if (atomicio(read, sock_in, &buf[i], 1) != 1) {
-                               log("Did not receive identification string from %s",
-                                   get_remote_ipaddr());
-                               fatal_cleanup();
-                       }
-                       if (buf[i] == '\r') {
-                               buf[i] = 0;
-                               /* Kludge for F-Secure Macintosh < 1.0.2 */
-                               if (i == 12 &&
-                                   strncmp(buf, "SSH-1.5-W1.0", 12) == 0)
-                                       break;
-                               continue;
-                       }
-                       if (buf[i] == '\n') {
-                               buf[i] = 0;
+               if (buf[i] == '\r') {
+                       buf[i] = 0;
+                       /* Kludge for F-Secure Macintosh < 1.0.2 */
+                       if (i == 12 &&
+                           strncmp(buf, "SSH-1.5-W1.0", 12) == 0)
                                break;
-                       }
+                       continue;
+               }
+               if (buf[i] == '\n') {
+                       buf[i] = 0;
+                       break;
                }
-               buf[sizeof(buf) - 1] = 0;
-               client_version_string = xstrdup(buf);
        }
+       buf[sizeof(buf) - 1] = 0;
+       client_version_string = xstrdup(buf);
 
        /*
         * Check that the versions match.  In future this might accept
@@ -421,10 +418,10 @@ sshd_exchange_identification(int sock_in, int sock_out)
        if (sscanf(client_version_string, "SSH-%d.%d-%[^\n]\n",
            &remote_major, &remote_minor, remote_version) != 3) {
                s = "Protocol mismatch.\n";
-               (void) atomicio(write, sock_out, s, strlen(s));
+               (void) atomicio(vwrite, sock_out, s, strlen(s));
                close(sock_in);
                close(sock_out);
-               log("Bad protocol version identification '%.100s' from %s",
+               logit("Bad protocol version identification '%.100s' from %s",
                    client_version_string, get_remote_ipaddr());
                fatal_cleanup();
        }
@@ -434,13 +431,13 @@ sshd_exchange_identification(int sock_in, int sock_out)
        compat_datafellows(remote_version);
 
        if (datafellows & SSH_BUG_PROBE) {
-               log("probed from %s with %s.  Don't panic.",
+               logit("probed from %s with %s.  Don't panic.",
                    get_remote_ipaddr(), client_version_string);
                fatal_cleanup();
        }
 
        if (datafellows & SSH_BUG_SCANNER) {
-               log("scanned from %s with %s.  Don't panic.",
+               logit("scanned from %s with %s.  Don't panic.",
                    get_remote_ipaddr(), client_version_string);
                fatal_cleanup();
        }
@@ -482,10 +479,10 @@ sshd_exchange_identification(int sock_in, int sock_out)
 
        if (mismatch) {
                s = "Protocol major versions differ.\n";
-               (void) atomicio(write, sock_out, s, strlen(s));
+               (void) atomicio(vwrite, sock_out, s, strlen(s));
                close(sock_in);
                close(sock_out);
-               log("Protocol major versions differ for %s: %.200s vs. %.200s",
+               logit("Protocol major versions differ for %s: %.200s vs. %.200s",
                    get_remote_ipaddr(),
                    server_version_string, client_version_string);
                fatal_cleanup();
@@ -577,8 +574,6 @@ privsep_preauth_child(void)
        do_setusercontext(pw);
 #else
        gidset[0] = pw->pw_gid;
-       if (setgid(pw->pw_gid) < 0)
-               fatal("setgid failed for %u", pw->pw_gid );
        if (setgroups(1, gidset) < 0)
                fatal("setgroups: %.100s", strerror(errno));
        permanently_set_uid(pw);
@@ -833,26 +828,27 @@ main(int ac, char **av)
 #ifdef HAVE_SECUREWARE
        (void)set_auth_parameters(ac, av);
 #endif
-       __progname = get_progname(av[0]);
+       __progname = ssh_get_progname(av[0]);
        init_rng();
 
        /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */
        saved_argc = ac;
-       saved_argv = av;
-       saved_argv = xmalloc(sizeof(*saved_argv) * ac);
+       saved_argv = xmalloc(sizeof(*saved_argv) * (ac + 1));
        for (i = 0; i < ac; i++)
                saved_argv[i] = xstrdup(av[i]);
+       saved_argv[i] = NULL;
 
 #ifndef HAVE_SETPROCTITLE
        /* Prepare for later setproctitle emulation */
        compat_init_setproctitle(ac, av);
+       av = saved_argv;
 #endif
 
        /* Initialize configuration options to their default values. */
        initialize_server_options(&options);
 
        /* Parse command-line arguments. */
-       while ((opt = getopt(ac, av, "f:p:b:k:h:g:V:u:o:dDeiqtQ46")) != -1) {
+       while ((opt = getopt(ac, av, "f:p:b:k:h:g:u:o:dDeiqtQ46")) != -1) {
                switch (opt) {
                case '4':
                        IPv4or6 = AF_INET;
@@ -864,15 +860,11 @@ main(int ac, char **av)
                        config_file_name = optarg;
                        break;
                case 'd':
-                       if (0 == debug_flag) {
+                       if (debug_flag == 0) {
                                debug_flag = 1;
                                options.log_level = SYSLOG_LEVEL_DEBUG1;
-                       } else if (options.log_level < SYSLOG_LEVEL_DEBUG3) {
+                       } else if (options.log_level < SYSLOG_LEVEL_DEBUG3)
                                options.log_level++;
-                       } else {
-                               fprintf(stderr, "Too high debugging level.\n");
-                               exit(1);
-                       }
                        break;
                case 'D':
                        no_daemon_flag = 1;
@@ -923,11 +915,6 @@ main(int ac, char **av)
                        }
                        options.host_key_files[options.num_host_key_files++] = optarg;
                        break;
-               case 'V':
-                       client_version_string = optarg;
-                       /* only makes sense with inetd_flag, i.e. no listen() */
-                       inetd_flag = 1;
-                       break;
                case 't':
                        test_flag = 1;
                        break;
@@ -1019,18 +1006,18 @@ main(int ac, char **av)
                    key_type(key));
        }
        if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) {
-               log("Disabling protocol version 1. Could not load host key");
+               logit("Disabling protocol version 1. Could not load host key");
                options.protocol &= ~SSH_PROTO_1;
        }
 #ifndef GSSAPI
        /* The GSSAPI key exchange can run without a host key */
        if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) {
-               log("Disabling protocol version 2. Could not load host key");
+               logit("Disabling protocol version 2. Could not load host key");
                options.protocol &= ~SSH_PROTO_2;
        }
 #endif
        if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) {
-               log("sshd: no hostkeys available -- exiting.");
+               logit("sshd: no hostkeys available -- exiting.");
                exit(1);
        }
 
@@ -1165,7 +1152,8 @@ main(int ac, char **av)
                                continue;
                        }
                        /* Create socket for listening. */
-                       listen_sock = socket(ai->ai_family, SOCK_STREAM, 0);
+                       listen_sock = socket(ai->ai_family, ai->ai_socktype,
+                           ai->ai_protocol);
                        if (listen_sock < 0) {
                                /* kernel may not support ipv6 */
                                verbose("socket: %.100s", strerror(errno));
@@ -1198,7 +1186,7 @@ main(int ac, char **av)
                        num_listen_socks++;
 
                        /* Start listening on the port. */
-                       log("Server listening on %s port %s.", ntop, strport);
+                       logit("Server listening on %s port %s.", ntop, strport);
                        if (listen(listen_sock, 5) < 0)
                                fatal("listen: %.100s", strerror(errno));
 
@@ -1233,7 +1221,10 @@ main(int ac, char **av)
                         * overwrite any old pid in the file.
                         */
                        f = fopen(options.pid_file, "wb");
-                       if (f) {
+                       if (f == NULL) {
+                               error("Couldn't create pid file \"%s\": %s",
+                                   options.pid_file, strerror(errno));
+                       } else {
                                fprintf(f, "%ld\n", (long) getpid());
                                fclose(f);
                        }
@@ -1274,7 +1265,7 @@ main(int ac, char **av)
                        if (ret < 0 && errno != EINTR)
                                error("select: %.100s", strerror(errno));
                        if (received_sigterm) {
-                               log("Received signal %d; terminating.",
+                               logit("Received signal %d; terminating.",
                                    (int) received_sigterm);
                                close_listen_socks();
                                unlink(options.pid_file);
@@ -1412,11 +1403,11 @@ main(int ac, char **av)
         * setlogin() affects the entire process group.  We don't
         * want the child to be able to affect the parent.
         */
-#if !defined(STREAMS_PUSH_ACQUIRES_CTTY)
+#if !defined(SSHD_ACQUIRES_CTTY)
        /*
-        * If setsid is called on Solaris, sshd will acquire the controlling
-        * terminal while pushing STREAMS modules. This will prevent the
-        * shell from acquiring it later.
+        * If setsid is called, on some platforms sshd will later acquire a
+        * controlling terminal which will result in "could not set
+        * controlling tty" errors.
         */
        if (!debug_flag && !inetd_flag && setsid() < 0)
                error("setsid: %.100s", strerror(errno));
@@ -1483,28 +1474,7 @@ main(int ac, char **av)
                alarm(options.login_grace_time);
 
        sshd_exchange_identification(sock_in, sock_out);
-       /*
-        * Check that the connection comes from a privileged port.
-        * Rhosts-Authentication only makes sense from privileged
-        * programs.  Of course, if the intruder has root access on his local
-        * machine, he can connect from any port.  So do not use these
-        * authentication methods from machines that you do not trust.
-        */
-       if (options.rhosts_authentication &&
-           (remote_port >= IPPORT_RESERVED ||
-           remote_port < IPPORT_RESERVED / 2)) {
-               debug("Rhosts Authentication disabled, "
-                   "originating port %d not trusted.", remote_port);
-               options.rhosts_authentication = 0;
-       }
-#if defined(KRB4) && !defined(KRB5)
-       if (!packet_connection_is_ipv4() &&
-           options.kerberos_authentication) {
-               debug("Kerberos Authentication disabled, only available for IPv4.");
-               options.kerberos_authentication = 0;
-       }
-#endif /* KRB4 && !KRB5 */
-#if defined(AFS) || defined(AFS_KRB5)
+#if defined(AFS_KRB5)
        /* If machine has AFS, set process authentication group. */
        if (k_hasafs()) {
                k_setpag();
@@ -1514,6 +1484,9 @@ main(int ac, char **av)
 
        packet_set_nonblocking();
 
+        /* prepare buffers to collect authentication messages */
+       buffer_init(&loginmsg);
+
        if (use_privsep)
                if ((authctxt = privsep_preauth()) != NULL)
                        goto authenticated;
@@ -1555,7 +1528,8 @@ main(int ac, char **av)
        verbose("Closing connection to %.100s", remote_ip);
 
 #ifdef USE_PAM
-       finish_pam();
+       if (options.use_pam)
+               finish_pam();
 #endif /* USE_PAM */
 
        packet_close();
@@ -1667,24 +1641,10 @@ do_ssh1_kex(void)
 
        /* Declare supported authentication types. */
        auth_mask = 0;
-       if (options.rhosts_authentication)
-               auth_mask |= 1 << SSH_AUTH_RHOSTS;
        if (options.rhosts_rsa_authentication)
                auth_mask |= 1 << SSH_AUTH_RHOSTS_RSA;
        if (options.rsa_authentication)
                auth_mask |= 1 << SSH_AUTH_RSA;
-#if defined(KRB4) || defined(KRB5)
-       if (options.kerberos_authentication)
-               auth_mask |= 1 << SSH_AUTH_KERBEROS;
-#endif
-#if defined(AFS) || defined(KRB5)
-       if (options.kerberos_tgt_passing)
-               auth_mask |= 1 << SSH_PASS_KERBEROS_TGT;
-#endif
-#ifdef AFS
-       if (options.afs_token_passing)
-               auth_mask |= 1 << SSH_PASS_AFS_TOKEN;
-#endif
 #ifdef GSSAPI
        if (options.gss_authentication)
                auth_mask |= 1 << SSH_AUTH_GSSAPI;
@@ -1766,7 +1726,7 @@ do_ssh1_kex(void)
                u_char *buf = xmalloc(bytes);
                MD5_CTX md;
 
-               log("do_connection: generating a fake encryption key");
+               logit("do_connection: generating a fake encryption key");
                BN_bn2bin(session_key_int, buf);
                MD5_Init(&md);
                MD5_Update(&md, buf, bytes);
index b9dda87b9fa6234734a5d35d52d3e4a3f30c0fc0..0fcff892b6165e3cecdef1090a6eaf33ae04490f 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: sshd_config,v 1.59 2002/09/25 11:17:16 markus Exp $
+#      $OpenBSD: sshd_config,v 1.65 2003/08/28 12:54:34 markus Exp $
 
 # This is the sshd server system-wide configuration file.  See
 # sshd_config(5) for more information.
@@ -22,7 +22,7 @@
 #HostKey /etc/ssh/ssh_host_dsa_key
 
 # Lifetime and size of ephemeral version 1 server key
-#KeyRegenerationInterval 3600
+#KeyRegenerationInterval 1h
 #ServerKeyBits 768
 
 # Logging
@@ -32,7 +32,7 @@
 
 # Authentication:
 
-#LoginGraceTime 120
+#LoginGraceTime 2m
 #PermitRootLogin yes
 #StrictModes yes
 
 #PubkeyAuthentication yes
 #AuthorizedKeysFile    .ssh/authorized_keys
 
-# rhosts authentication should not be used
-#RhostsAuthentication no
-# Don't read the user's ~/.rhosts and ~/.shosts files
-#IgnoreRhosts yes
 # For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
 #RhostsRSAAuthentication no
 # similar for protocol version 2
@@ -51,6 +47,8 @@
 # Change to yes if you don't trust ~/.ssh/known_hosts for
 # RhostsRSAAuthentication and HostbasedAuthentication
 #IgnoreUserKnownHosts no
+# Don't read the user's ~/.rhosts and ~/.shosts files
+#IgnoreRhosts yes
 
 # To disable tunneled clear text passwords, change to no here!
 #PasswordAuthentication yes
 #KerberosOrLocalPasswd yes
 #KerberosTicketCleanup yes
 
-#AFSTokenPassing no
-
-# Kerberos TGT Passing only works with the AFS kaserver
-#KerberosTgtPassing no
-
 # Session hooks: if allowed, specify the commands to execute
 #AllowSessionHooks yes
 #SessionHookStartupCmd /bin/true
 #SessionHookShutdownCmd /bin/true
 
-# Set this to 'yes' to enable PAM keyboard-interactive authentication 
-# Warning: enabling this may bypass the setting of 'PasswordAuthentication'
-#PAMAuthenticationViaKbdInt no
+# GSSAPI options
+#GSSAPIAuthentication yes
+#GSSAPICleanupCreds yes
+
+# 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
 
+#AllowTcpForwarding yes
+#GatewayPorts no
 #X11Forwarding no
 #X11DisplayOffset 10
 #X11UseLocalhost yes
 #UsePrivilegeSeparation yes
 #PermitUserEnvironment no
 #Compression yes
-
+#ClientAliveInterval 0
+#ClientAliveCountMax 3
+#UseDNS yes
+#PidFile /var/run/sshd.pid
 #MaxStartups 10
+
 # no default banner path
 #Banner /some/path
-#VerifyReverseMapping no
 
 # override default of no subsystems
 Subsystem      sftp    /usr/libexec/sftp-server
index b4d5fa1488d66201fad7dd03085034e411272d2c..13d5c80c1fa7201345a179de2667cf4f75e335f6 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.15 2003/03/28 10:11:43 jmc Exp $
+.\" $OpenBSD: sshd_config.5,v 1.25 2003/09/01 09:50:04 markus Exp $
 .Dd September 25, 1999
 .Dt SSHD_CONFIG 5
 .Os
@@ -61,10 +61,6 @@ The possible
 keywords and their meanings are as follows (note that
 keywords are case-insensitive and arguments are case-sensitive):
 .Bl -tag -width Ds
-.It Cm AFSTokenPassing
-Specifies whether an AFS token may be forwarded to the server.
-Default is
-.Dq no .
 .It Cm AllowGroups
 This keyword can be followed by a list of group name patterns, separated
 by spaces.
@@ -72,7 +68,7 @@ If specified, login is allowed only for users whose primary
 group or supplementary group list matches one of the patterns.
 .Ql \&*
 and
-.Ql ?
+.Ql \&?
 can be used as
 wildcards in the patterns.
 Only group names are valid; a numerical group ID is not recognized.
@@ -93,7 +89,7 @@ If specified, login is allowed only for user names that
 match one of the patterns.
 .Ql \&*
 and
-.Ql ?
+.Ql \&?
 can be used as
 wildcards in the patterns.
 Only user names are valid; a numerical user ID is not recognized.
@@ -107,7 +103,8 @@ Specifies the file that contains the public keys that can be used
 for user authentication.
 .Cm AuthorizedKeysFile
 may contain tokens of the form %T which are substituted during connection
-set-up. The following tokens are defined: %% is replaced by a literal '%',
+set-up.
+The following tokens are defined: %% is replaced by a literal '%',
 %h is replaced by the home directory of the user being authenticated and
 %u is replaced by the username of that user.
 After expansion,
@@ -138,7 +135,7 @@ The default is
 .Pp
 .Bd -literal
   ``aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,
-    aes192-cbc,aes256-cbc''
+    aes192-cbc,aes256-cbc,aes128-ctr,aes192-ctr,aes256-ctr''
 .Ed
 .It Cm ClientAliveInterval
 Sets a timeout interval in seconds after which if no data has been received
@@ -153,20 +150,24 @@ This option applies to protocol version 2 only.
 Sets the number of client alive messages (see above) which may be
 sent without
 .Nm sshd
-receiving any messages back from the client. If this threshold is
-reached while client alive messages are being sent,
+receiving any messages back from the client.
+If this threshold is reached while client alive messages are being sent,
 .Nm sshd
-will disconnect the client, terminating the session. It is important
-to note that the use of client alive messages is very different from
+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
-(below). The client alive messages are sent through the
-encrypted channel and therefore will not be spoofable. The TCP keepalive
-option enabled by
+(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
-is spoofable. The client alive mechanism is valuable when the client or
+is spoofable.
+The client 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
+The default value is 3.
+If
 .Cm ClientAliveInterval
 (above) is set to 15, and
 .Cm ClientAliveCountMax
@@ -187,7 +188,7 @@ Login is disallowed for users whose primary group or supplementary
 group list matches one of the patterns.
 .Ql \&*
 and
-.Ql ?
+.Ql \&?
 can be used as
 wildcards in the patterns.
 Only group names are valid; a numerical group ID is not recognized.
@@ -199,7 +200,7 @@ by spaces.
 Login is disallowed for user names that match one of the patterns.
 .Ql \&*
 and
-.Ql ?
+.Ql \&?
 can be used as wildcards in the patterns.
 Only user names are valid; a numerical user ID is not recognized.
 By default, login is allowed for all users.
@@ -224,6 +225,17 @@ or
 .Dq no .
 The default is
 .Dq no .
+.It Cm GSSAPIAuthentication
+Specifies whether user authentication based on GSSAPI is allowed.
+The default is 
+.Dq no .
+Note that this option applies to protocol version 2 only.
+.It Cm GSSAPICleanupCredentials
+Specifies whether to automatically destroy the user's credentials cache
+on logout.
+The default is
+.Dq yes .
+Note that this option applies to protocol version 2 only.
 .It Cm HostbasedAuthentication
 Specifies whether rhosts or /etc/hosts.equiv authentication together
 with successful public key client host authentication is allowed
@@ -280,7 +292,6 @@ Specifies that
 and
 .Pa .shosts
 files will not be used in
-.Cm RhostsAuthentication ,
 .Cm RhostsRSAAuthentication
 or
 .Cm HostbasedAuthentication .
@@ -324,11 +335,9 @@ This avoids infinitely hanging sessions.
 To disable keepalives, the value should be set to
 .Dq no .
 .It Cm KerberosAuthentication
-Specifies whether Kerberos authentication is allowed.
-This can be in the form of a Kerberos ticket, or if
+Specifies whether the password provided by the user for
 .Cm PasswordAuthentication
-is yes, the password provided by the user will be validated through
-the Kerberos KDC.
+will be validated through the Kerberos KDC.
 To use this option, the server needs a
 Kerberos servtab which allows the verification of the KDC's identity.
 Default is
@@ -340,11 +349,6 @@ such as
 .Pa /etc/passwd .
 Default is
 .Dq yes .
-.It Cm KerberosTgtPassing
-Specifies whether a Kerberos TGT may be forwarded to the server.
-Default is
-.Dq no ,
-as this only works when the Kerberos KDC is actually an AFS kaserver.
 .It Cm KerberosTicketCleanup
 Specifies whether to automatically destroy the user's ticket cache
 file on logout.
@@ -390,11 +394,12 @@ is not specified,
 .Nm sshd
 will listen on the address and all prior
 .Cm Port
-options specified. The default is to listen on all local
-addresses.
+options specified.
+The default is to listen on all local addresses.
 Multiple
 .Cm ListenAddress
-options are permitted. Additionally, any
+options are permitted.
+Additionally, any
 .Cm Port
 options must precede this option for non port qualified addresses.
 .It Cm LoginGraceTime
@@ -443,12 +448,6 @@ The probability increases linearly and all connection attempts
 are refused if the number of unauthenticated connections reaches
 .Dq full
 (60).
-.It Cm PAMAuthenticationViaKbdInt
-Specifies whether PAM challenge response authentication is allowed. This
-allows the use of most PAM challenge response authentication modules, but
-it will allow password authentication regardless of whether
-.Cm PasswordAuthentication
-is enabled.
 .It Cm PasswordAuthentication
 Specifies whether password authentication is allowed.
 The default is
@@ -481,8 +480,8 @@ but only if the
 .Ar command
 option has been specified
 (which may be useful for taking remote backups even if root login is
-normally not allowed). All other authentication methods are disabled
-for root.
+normally not allowed).
+All other authentication methods are disabled for root.
 .Pp
 If this option is set to
 .Dq no
@@ -555,10 +554,6 @@ Specifies whether public key authentication is allowed.
 The default is
 .Dq yes .
 Note that this option applies to protocol version 2 only.
-.It Cm RhostsAuthentication
-Specifies whether authentication using rhosts or /etc/hosts.equiv
-files is sufficient.
-Normally, this method should not be permitted because it is insecure.
 .Cm RhostsRSAAuthentication
 should be used
 instead, because it performs RSA-based host authentication in addition
@@ -606,6 +601,14 @@ 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 UseDNS
+Specifies whether
+.Nm sshd
+should lookup the remote host name and check that
+the resolved host name for the remote IP address maps back to the
+very same IP address.
+The default is
+.Dq yes .
 .It Cm UseLogin
 Specifies whether
 .Xr login 1
@@ -625,6 +628,13 @@ cookies.
 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 
+.Cm PasswordAuthentication .
+If you enable 
+.CM UsePAM
+then you will not be able to run sshd as a non-root user.
 .It Cm UsePrivilegeSeparation
 Specifies whether
 .Nm sshd
@@ -636,14 +646,6 @@ The goal of privilege separation is to prevent privilege
 escalation by containing any corruption within the unprivileged processes.
 The default is
 .Dq yes .
-.It Cm VerifyReverseMapping
-Specifies whether
-.Nm sshd
-should try to verify the remote host name and check that
-the resolved host name for the remote IP address maps back to the
-very same IP address.
-The default is
-.Dq no .
 .It Cm X11DisplayOffset
 Specifies the first display number available for
 .Nm sshd Ns 's
@@ -674,7 +676,7 @@ display server may be exposed to attack when the ssh client requests
 forwarding (see the warnings for
 .Cm ForwardX11
 in
-.Xr ssh_config 5 ).
+.Xr ssh_config 5 ) .
 A system administrator may have a stance in which they want to
 protect clients that may expose themselves to attack by unwittingly
 requesting X11 forwarding, which can warrant a
@@ -720,7 +722,6 @@ The default is
 .Pa /usr/X11R6/bin/xauth .
 .El
 .Ss Time Formats
-.Pp
 .Nm sshd
 command-line arguments and configuration file options that specify time
 may be expressed using a sequence of the form:
@@ -769,6 +770,8 @@ Contains configuration data for
 This file should be writable by root only, but it is recommended
 (though not necessary) that it be world-readable.
 .El
+.Sh SEE ALSO
+.Xr sshd 8
 .Sh AUTHORS
 OpenSSH is a derivative of the original and free
 ssh 1.2.12 release by Tatu Ylonen.
@@ -780,5 +783,3 @@ Markus Friedl contributed the support for SSH
 protocol versions 1.5 and 2.0.
 Niels Provos and Markus Friedl contributed support
 for privilege separation.
-.Sh SEE ALSO
-.Xr sshd 8
This page took 0.95883 seconds and 5 git commands to generate.