From c9f39d2c2cb442069d6568c47f70168e1f255e15 Mon Sep 17 00:00:00 2001 From: jbasney Date: Wed, 18 Aug 2004 18:01:40 +0000 Subject: [PATCH] Import of OpenSSH 3.9p1 --- openssh/.cvsignore | 1 + openssh/CREDITS | 5 +- openssh/ChangeLog | 673 +++++++++++++++++++++++- openssh/INSTALL | 2 +- openssh/Makefile.in | 26 +- openssh/OVERVIEW | 1 - openssh/README | 18 +- openssh/README.platform | 8 + openssh/README.privsep | 6 +- openssh/acconfig.h | 12 + openssh/auth-krb5.c | 6 +- openssh/auth-pam.c | 204 ++++++- openssh/auth-pam.h | 1 + openssh/auth-passwd.c | 6 + openssh/auth-rsa.c | 11 +- openssh/auth.c | 42 +- openssh/auth.h | 4 +- openssh/auth1.c | 26 +- openssh/auth2-chall.c | 3 +- openssh/auth2-gss.c | 12 +- openssh/auth2-none.c | 11 +- openssh/auth2-pubkey.c | 8 +- openssh/auth2.c | 8 +- openssh/authfd.c | 19 +- openssh/authfile.c | 24 +- openssh/buildpkg.sh.in | 562 ++++++++++++++++++++ openssh/canohost.c | 38 +- openssh/channels.c | 198 +++++-- openssh/channels.h | 11 +- openssh/cipher.c | 52 +- openssh/cipher.h | 4 +- openssh/clientloop.c | 478 +++++++++++++++-- openssh/clientloop.h | 4 +- openssh/compat.h | 4 +- openssh/config.guess | 441 +++++++++------- openssh/config.sub | 135 +++-- openssh/configure.ac | 101 +++- openssh/contrib/README | 28 +- openssh/contrib/caldera/openssh.spec | 8 +- openssh/contrib/cygwin/README | 4 +- openssh/contrib/redhat/openssh.spec | 4 +- openssh/contrib/redhat/sshd.pam | 2 - openssh/contrib/solaris/README | 10 +- openssh/contrib/suse/openssh.spec | 2 +- openssh/defines.h | 7 + openssh/dh.c | 30 +- openssh/dh.h | 3 +- openssh/dns.c | 8 +- openssh/envpass.sh | 44 ++ openssh/gss-serv-krb5.c | 10 +- openssh/includes.h | 13 +- openssh/kex.c | 45 +- openssh/kex.h | 7 +- openssh/kexdhc.c | 13 +- openssh/kexdhs.c | 13 +- openssh/key.c | 6 +- openssh/log.c | 6 +- openssh/log.h | 6 +- openssh/loginrec.c | 34 +- openssh/logintest.c | 4 - openssh/mdoc2man.awk | 10 +- openssh/misc.c | 36 +- openssh/misc.h | 25 +- openssh/moduli.c | 86 ++- openssh/monitor.c | 156 +++--- openssh/monitor_fdpass.c | 12 +- openssh/monitor_mm.c | 2 +- openssh/monitor_wrap.c | 41 +- openssh/monitor_wrap.h | 8 +- openssh/myproposal.h | 6 +- openssh/nchan.c | 20 +- openssh/openbsd-compat/Makefile.in | 2 +- openssh/openbsd-compat/bsd-arc4random.c | 10 +- openssh/openbsd-compat/bsd-closefrom.c | 100 ++++ openssh/openbsd-compat/bsd-misc.c | 5 + openssh/openbsd-compat/getrrsetbyname.c | 4 + openssh/openbsd-compat/openbsd-compat.h | 4 + openssh/openbsd-compat/port-aix.c | 88 +++- openssh/openbsd-compat/port-aix.h | 4 + openssh/openbsd-compat/sys-queue.h | 19 +- openssh/openbsd-compat/xmmap.c | 9 +- openssh/opensshd.init.in | 82 +++ openssh/packet.c | 53 +- openssh/packet.h | 4 +- openssh/pathnames.h | 4 +- openssh/progressmeter.c | 24 +- openssh/readconf.c | 48 +- openssh/readconf.h | 14 +- openssh/readpass.c | 11 +- openssh/regress/Makefile | 12 +- openssh/regress/README.regress | 29 +- openssh/regress/dynamic-forward.sh | 4 +- openssh/regress/envpass.sh | 51 ++ openssh/regress/login-timeout.sh | 4 +- openssh/regress/multiplex.sh | 74 +++ openssh/regress/reexec.sh | 87 +++ openssh/regress/scp-ssh-wrapper.sh | 54 ++ openssh/regress/scp.sh | 82 +++ openssh/regress/test-exec.sh | 35 +- openssh/regress/try-ciphers.sh | 4 +- openssh/rijndael.c | 6 +- openssh/scard-opensc.c | 2 +- openssh/scard.c | 4 +- openssh/scp.1 | 7 +- openssh/scp.c | 41 +- openssh/servconf.c | 77 ++- openssh/servconf.h | 14 +- openssh/serverloop.c | 18 +- openssh/session.c | 118 +++-- openssh/session.h | 10 +- openssh/sftp-client.c | 39 +- openssh/sftp-server.c | 48 +- openssh/sftp.1 | 25 +- openssh/sftp.c | 188 +++++-- openssh/ssh-add.c | 9 +- openssh/ssh-agent.1 | 22 +- openssh/ssh-agent.c | 15 +- openssh/ssh-gss.h | 40 +- openssh/ssh-keygen.1 | 11 +- openssh/ssh-keygen.c | 32 +- openssh/ssh-keyscan.1 | 4 +- openssh/ssh-keyscan.c | 15 +- openssh/ssh-keysign.c | 20 +- openssh/ssh-rand-helper.c | 8 - openssh/ssh.1 | 103 +++- openssh/ssh.c | 315 ++++++++--- openssh/ssh1.h | 8 +- openssh/ssh_config.5 | 75 ++- openssh/sshconnect.c | 13 +- openssh/sshconnect1.c | 18 +- openssh/sshconnect2.c | 7 +- openssh/sshd.8 | 4 +- openssh/sshd.c | 279 ++++++++-- openssh/sshd_config | 14 +- openssh/sshd_config.5 | 73 ++- openssh/sshlogin.c | 51 +- openssh/sshpty.c | 40 +- openssh/sshpty.h | 6 +- openssh/sshtty.c | 4 +- openssh/tildexpand.c | 4 +- openssh/ttymodes.h | 18 +- openssh/version.h | 4 +- 142 files changed, 5257 insertions(+), 1347 deletions(-) create mode 100644 openssh/buildpkg.sh.in create mode 100644 openssh/envpass.sh create mode 100644 openssh/openbsd-compat/bsd-closefrom.c create mode 100755 openssh/opensshd.init.in create mode 100644 openssh/regress/envpass.sh create mode 100644 openssh/regress/multiplex.sh create mode 100644 openssh/regress/reexec.sh create mode 100644 openssh/regress/scp-ssh-wrapper.sh create mode 100644 openssh/regress/scp.sh diff --git a/openssh/.cvsignore b/openssh/.cvsignore index 12de9ef..e38a50b 100644 --- a/openssh/.cvsignore +++ b/openssh/.cvsignore @@ -20,5 +20,6 @@ ssh_prng_cmds *.out *.0 buildit.sh +buildpkg.sh autom4te.cache ssh-rand-helper diff --git a/openssh/CREDITS b/openssh/CREDITS index 0e50e6a..e387768 100644 --- a/openssh/CREDITS +++ b/openssh/CREDITS @@ -31,6 +31,7 @@ David Agraz - Build fixes David Del Piero - bug fixes David Hesprich - Configure fixes David Rankin - libwrap, AIX, NetBSD fixes +Dag-Erling Smørgrav - Challenge-Response PAM code. Ed Eden - configure fixes Garrick James - configure fixes Gary E. Miller - SCO support @@ -43,7 +44,7 @@ Holger Trapp - KRB4/AFS config patch IWAMURO Motonori - bugfixes Jani Hakala - Patches Jarno Huuskonen - Bugfixes -Jim Knoble - Many patches +Jim Knoble - Many patches Jonchen (email unknown) - the original author of PAM support of SSH Juergen Keil - scp bugfixing KAMAHARA Junzo - Configure fixes @@ -61,6 +62,7 @@ Martin Johansson - Linux fixes Mark D. Roth - Features, bug fixes Mark Miller - Bugfixes Matt Richards - AIX patches +Michael Steffens - HP-UX fixes Michael Stone - Irix enhancements Nakaji Hiroyuki - Sony News-OS patch Nalin Dahyabhai - PAM environment patch @@ -76,6 +78,7 @@ Phil Karn - Autoconf fixes Philippe WILLEM - Bugfixes Phill Camp - login code fix Rip Loomis - Solaris package support, fixes +Robert Dahlem - Reliant Unix fixes Roumen Petrov - Compile & configure fixes SAKAI Kiyotaka - Multiple bugfixes Simon Wilkinson - PAM fixes, Compat with MIT KrbV diff --git a/openssh/ChangeLog b/openssh/ChangeLog index a8a7781..09ffd7d 100644 --- a/openssh/ChangeLog +++ b/openssh/ChangeLog @@ -1,10 +1,681 @@ +20040817 + - (dtucker) [regress/README.regress] Note compatibility issues with GNU head. + - (djm) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2004/08/16 08:17:01 + [version.h] + 3.9 + - (djm) Crank RPM spec version numbers + - (djm) Release 3.9p1 + +20040816 + - (dtucker) [acconfig.h auth-pam.c configure.ac] Set real uid to non-root + to convince Solaris PAM to honour password complexity rules. ok djm@ + +20040815 + - (dtucker) [Makefile.in ssh-keysign.c ssh.c] Use permanently_set_uid() since + it does the right thing on all platforms. ok djm@ + - (djm) [acconfig.h configure.ac openbsd-compat/Makefile.in + openbsd-compat/bsd-closefrom.c openbsd-compat/bsd-misc.c + openbsd-compat/bsd-misc.h openbsd-compat/openbsd-compat.h] Use smarter + closefrom() replacement from sudo; ok dtucker@ + - (djm) [loginrec.c] Check that seek succeeded here too; ok dtucker + - (dtucker) [Makefile.in] Fix typo. + +20040814 + - (dtucker) [auth-krb5.c gss-serv-krb5.c openbsd-compat/xmmap.c] + Explicitly set umask for mkstemp; ok djm@ + - (dtucker) [includes.h] Undef _INCLUDE__STDC__ on HP-UX, otherwise + prot.h and shadow.h provide conflicting declarations of getspnam. ok djm@ + - (dtucker) [loginrec.c openbsd-compat/port-aix.c openbsd-compat/port-aix.h] + Plug AIX login recording into login_write so logins will be recorded for + all auth types. + +20040813 + - (dtucker) [openbsd-compat/bsd-misc.c] Typo in #ifdef; from vinschen at + redhat.com +- (dtucker) OpenBSD CVS Sync + - avsm@cvs.openbsd.org 2004/08/11 21:43:05 + [channels.c channels.h clientloop.c misc.c misc.h serverloop.c ssh-agent.c] + some signed/unsigned int comparison cleanups; markus@ ok + - avsm@cvs.openbsd.org 2004/08/11 21:44:32 + [authfd.c scp.c ssh-keyscan.c] + use atomicio instead of homegrown equivalents or read/write. + markus@ ok + - djm@cvs.openbsd.org 2004/08/12 09:18:24 + [sshlogin.c] + typo in error message, spotted by moritz AT jodeit.org (Id sync only) + - jakob@cvs.openbsd.org 2004/08/12 21:41:13 + [ssh-keygen.1 ssh.1] + improve SSHFP documentation; ok deraadt@ + - jmc@cvs.openbsd.org 2004/08/13 00:01:43 + [ssh-keygen.1] + kill whitespace at eol; + - djm@cvs.openbsd.org 2004/08/13 02:51:48 + [monitor_fdpass.c] + extra check for no message case; ok markus, deraadt, hshoexer, henning + - dtucker@cvs.openbsd.org 2004/08/13 11:09:24 + [servconf.c] + Fix line numbers off-by-one in error messages, from tortay at cc.in2p3.fr + ok markus@, djm@ + +20040812 + - (dtucker) [sshd.c] Remove duplicate variable imported during sync. + - (dtucker) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2004/07/28 08:56:22 + [sshd.c] + call setsid() _before_ re-exec + - markus@cvs.openbsd.org 2004/07/28 09:40:29 + [auth.c auth1.c auth2.c cipher.c cipher.h key.c session.c ssh.c + sshconnect1.c] + more s/illegal/invalid/ + - djm@cvs.openbsd.org 2004/08/04 10:37:52 + [dh.c] + return group14 when no primes found - fixes hang on empty /etc/moduli; + ok markus@ + - dtucker@cvs.openbsd.org 2004/08/11 11:09:54 + [servconf.c] + Fix minor leak; "looks right" deraadt@ + - dtucker@cvs.openbsd.org 2004/08/11 11:50:09 + [sshd.c] + Don't try to close startup_pipe if it's not open; ok djm@ + - djm@cvs.openbsd.org 2004/08/11 11:59:22 + [sshlogin.c] + check that lseek went were we told it to; ok markus@ + (Id sync only, but similar changes are needed in loginrec.c) + - djm@cvs.openbsd.org 2004/08/11 12:01:16 + [sshlogin.c] + make store_lastlog_message() static to appease -Wall; ok markus + - (dtucker) [sshd.c] Clear loginmsg in postauth monitor, prevents doubling + messages generated before the postauth privsep split. + +20040720 + - (djm) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2004/07/21 08:56:12 + [auth.c] + s/Illegal user/Invalid user/; many requests; ok djm, millert, niklas, + miod, ... + - djm@cvs.openbsd.org 2004/07/21 10:33:31 + [auth1.c auth2.c] + bz#899: Don't display invalid usernames in setproctitle + from peak AT argo.troja.mff.cuni.cz; ok markus@ + - djm@cvs.openbsd.org 2004/07/21 10:36:23 + [gss-serv-krb5.c] + fix function declaration + - djm@cvs.openbsd.org 2004/07/21 11:51:29 + [canohost.c] + bz#902: cache remote port so we don't fatal() in auth_log when remote + connection goes away quickly. from peak AT argo.troja.mff.cuni.cz; + ok markus@ + - (djm) [auth-pam.c] Portable parts of bz#899: Don't display invalid + usernames in setproctitle from peak AT argo.troja.mff.cuni.cz; + +20040720 + - (djm) [log.c] bz #111: Escape more control characters when sending data + to syslog; from peak AT argo.troja.mff.cuni.cz + - (djm) [contrib/redhat/sshd.pam] bz #903: Remove redundant entries; from + peak AT argo.troja.mff.cuni.cz + - (djm) [regress/README.regress] Remove caveat regarding TCP wrappers, now + that sshd is fixed to behave better; suggested by tim + +20040719 + - (djm) [openbsd-compat/bsd-arc4random.c] Discard early keystream, like OpenBSD + ok dtucker@ + - (djm) [auth-pam.c] Avoid use of xstrdup and friends in conversation function, + instead return PAM_CONV_ERR, avoiding another path to fatal(); ok dtucker@ + - (tim) [configure.ac] updwtmpx() on OpenServer seems to add duplicate entry. + Report by rac AT tenzing.org + +20040717 + - (dtucker) [logintest.c scp.c sftp-server.c sftp.c ssh-add.c ssh-agent.c + ssh-keygen.c ssh-keyscan.c ssh-keysign.c ssh-rand-helper.c ssh.c sshd.c + openbsd-compat/bsd-misc.c] Move "char *__progname" to bsd-misc.c. Reduces + diff vs OpenBSD; ok mouring@, tested by tim@ too. + - (dtucker) OpenBSD CVS Sync + - deraadt@cvs.openbsd.org 2004/07/11 17:48:47 + [channels.c cipher.c clientloop.c clientloop.h compat.h moduli.c + readconf.c nchan.c pathnames.h progressmeter.c readconf.h servconf.c + session.c sftp-client.c sftp.c ssh-agent.1 ssh-keygen.c ssh.c ssh1.h + sshd.c ttymodes.h] + spaces + - brad@cvs.openbsd.org 2004/07/12 23:34:25 + [ssh-keyscan.1] + Fix incorrect macro, .I -> .Em + From: Eric S. Raymond + ok jmc@ + - dtucker@cvs.openbsd.org 2004/07/17 05:31:41 + [monitor.c monitor_wrap.c session.c session.h sshd.c sshlogin.c] + Move "Last logged in at.." message generation to the monitor, right + before recording the new login. Fixes missing lastlog message when + /var/log/lastlog is not world-readable and incorrect datestamp when + multiple sessions are used (bz #463); much assistance & ok markus@ + +20040711 + - (dtucker) [auth-pam.c] Check for zero from waitpid() too, which allows + the monitor to properly clean up the PAM thread (Debian bug #252676). + +20040709 + - (tim) [contrib/cygwin/README] add minires-devel requirement. Patch from + vinschen AT redhat.com + +20040708 + - (dtucker) OpenBSD CVS Sync + - dtucker@cvs.openbsd.org 2004/07/03 05:11:33 + [sshlogin.c] (RCSID sync only, the corresponding code is not in Portable) + Use '\0' not 0 for string; ok djm@, deraadt@ + - dtucker@cvs.openbsd.org 2004/07/03 11:02:25 + [monitor_wrap.c] + Put s/key functions inside #ifdef SKEY same as monitor.c, + from des@freebsd via bz #330, ok markus@ + - dtucker@cvs.openbsd.org 2004/07/08 12:47:21 + [scp.c] + Prevent scp from skipping the file following a double-error. + bz #863, ok markus@ + +20040702 + - (dtucker) [mdoc2man.awk] Teach it to ignore .Bk -words, reported by + strube at physik3.gwdg.de a long time ago. + +20040701 + - (dtucker) [session.c] Call display_loginmsg again after do_pam_session. + Ensures messages from PAM modules are displayed when privsep=no. + - (dtucker) [auth-pam.c] Bug #705: Make arguments match PAM specs, fixes + warnings on compliant platforms. From paul.a.bolton at bt.com. ok djm@ + - (dtucker) [auth-pam.c] Bug #559 (last piece): Pass DISALLOW_NULL_AUTHTOK + to pam_authenticate for challenge-response auth too. Originally from + fcusack at fcusack.com, ok djm@ + - (tim) [buildpkg.sh.in] Add $REV to bump the package revision within + the same version. Handle the case where someone uses --with-privsep-user= + and the user name does not match the group name. ok dtucker@ + +20040630 + - (dtucker) [auth-pam.c] Check for buggy PAM modules that return a NULL + appdata_ptr to the conversation function. ok djm@ + - (djm) OpenBSD CVS Sync + - jmc@cvs.openbsd.org 2004/06/26 09:03:21 + [ssh.1] + - remove double word + - rearrange .Bk to keep SYNOPSIS nice + - -M before -m in options description + - jmc@cvs.openbsd.org 2004/06/26 09:11:14 + [ssh_config.5] + punctuation and grammar fixes. also, keep the options in order. + - jmc@cvs.openbsd.org 2004/06/26 09:14:40 + [sshd_config.5] + new sentence, new line; + - avsm@cvs.openbsd.org 2004/06/26 20:07:16 + [sshd.c] + initialise some fd variables to -1, djm@ ok + - djm@cvs.openbsd.org 2004/06/30 08:36:59 + [session.c] + unbreak TTY break, diagnosed by darren AT dazwin.com; ok markus@ + +20040627 + - (tim) update README files. + - (dtucker) [mdoc2man.awk] Bug #883: correctly recognise .Pa and .Ev macros. + - (dtucker) [regress/README.regress] Document new variables. + - (dtucker) [acconfig.h configure.ac sftp-server.c] Bug #823: add sftp + rename handling for Linux which returns EPERM for link() on (at least some) + filesystems that do not support hard links. sftp-server will fall back to + stat+rename() in such cases. + - (dtucker) [openbsd-compat/port-aix.c] Missing __func__. + +20040626 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2004/06/25 18:43:36 + [sshd.c] + fix broken fd handling in the re-exec fallback path, particularly when + /dev/crypto is in use; ok deraadt@ markus@ + - djm@cvs.openbsd.org 2004/06/25 23:21:38 + [sftp.c] + bz #875: fix bad escape char error message; reported by f_mohr AT yahoo.de + +20040625 + - (dtucker) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2004/06/24 19:30:54 + [servconf.c servconf.h sshd.c] + re-exec sshd on accept(); initial work, final debugging and ok markus@ + - djm@cvs.openbsd.org 2004/06/25 01:16:09 + [sshd.c] + only perform tcp wrappers checks when the incoming connection is on a + socket. silences useless warnings from regress tests that use + proxycommand="sshd -i". prompted by david@ ok markus@ + - djm@cvs.openbsd.org 2004/06/24 19:32:00 + [regress/Makefile regress/test-exec.sh, added regress/reexec.sh] + regress test for re-exec corner cases + - djm@cvs.openbsd.org 2004/06/25 01:25:12 + [regress/test-exec.sh] + clean reexec-specific junk out of text-exec.sh and simplify; idea markus@ + - dtucker@cvs.openbsd.org 2004/06/25 05:38:48 + [sftp-server.c] + Fall back to stat+rename if filesystem doesn't doesn't support hard + links. bz#823, ok djm@ + - (dtucker) [configure.ac openbsd-compat/misc.c [openbsd-compat/misc.h] + Add closefrom() for platforms that don't have it. + - (dtucker) [sshd.c] add line missing from reexec sync. + +20040623 + - (dtucker) [auth1.c] Ensure do_pam_account is called for Protocol 1 + connections with empty passwords. Patch from davidwu at nbttech.com, + ok djm@ + - (dtucker) OpenBSD CVS Sync + - dtucker@cvs.openbsd.org 2004/06/22 22:42:02 + [regress/envpass.sh] + Add quoting for test -z; ok markus@ + - dtucker@cvs.openbsd.org 2004/06/22 22:45:52 + [regress/test-exec.sh] + Add TEST_SSH_SSHD_CONFOPTS and TEST_SSH_SSH_CONFOPTS to allow adding + arbitary options to sshd_config and ssh_config during tests. ok markus@ + - dtucker@cvs.openbsd.org 2004/06/22 22:55:56 + [regress/dynamic-forward.sh regress/test-exec.sh] + Allow setting of port for regress from TEST_SSH_PORT variable; ok markus@ + - mouring@cvs.openbsd.org 2004/06/23 00:39:38 + [rijndael.c] + -Wshadow fix up s/encrypt/do_encrypt/. OK djm@, markus@ + - dtucker@cvs.openbsd.org 2004/06/23 14:31:01 + [ssh.c] + Fix counting in master/slave when passing environment variables; ok djm@ + - (dtucker) [cipher.c] encrypt->do_encrypt inside SSH_OLD_EVP to match + -Wshadow change. + - (bal) [Makefile.in] Remove opensshd.init on 'make distclean' + - (dtucker) [auth.c openbsd-compat/port-aix.c openbsd-compat/port-aix.h] + Move loginrestrictions test to port-aix.c, replace with a generic hook. + - (tim) [regress/try-ciphers.sh] "if ! some_command" is not portable. + - (bal) [contrib/README] Removed "mdoc2man.pl" reference and added + reference to "findssl.sh" + +20040622 + - (dtucker) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2004/06/20 17:36:59 + [ssh.c] + filter passed env vars at slave in connection sharing case; ok markus@ + - djm@cvs.openbsd.org 2004/06/20 18:53:39 + [sftp.c] + make "ls -l" listings print user/group names, add "ls -n" to show uid/gid + (like /bin/ls); idea & ok markus@ + - djm@cvs.openbsd.org 2004/06/20 19:28:12 + [sftp.1] + mention new -n flag + - avsm@cvs.openbsd.org 2004/06/21 17:36:31 + [auth-rsa.c auth2-gss.c auth2-pubkey.c authfile.c canohost.c channels.c + cipher.c dns.c kex.c monitor.c monitor_fdpass.c monitor_wrap.c + monitor_wrap.h nchan.c packet.c progressmeter.c scp.c sftp-server.c sftp.c + ssh-gss.h ssh-keygen.c ssh.c sshconnect.c sshconnect1.c sshlogin.c + sshpty.c] + make ssh -Wshadow clean, no functional changes + markus@ ok + - djm@cvs.openbsd.org 2004/06/21 17:53:03 + [session.c] + fix fd leak for multiple subsystem connections; with markus@ + - djm@cvs.openbsd.org 2004/06/21 22:02:58 + [log.h] + mark fatal and cleanup exit as __dead; ok markus@ + - djm@cvs.openbsd.org 2004/06/21 22:04:50 + [sftp.c] + introduce sorting for ls, same options as /bin/ls; ok markus@ + - djm@cvs.openbsd.org 2004/06/21 22:30:45 + [sftp.c] + prefix ls option flags with LS_ + - djm@cvs.openbsd.org 2004/06/21 22:41:31 + [sftp.1] + document sort options + - djm@cvs.openbsd.org 2004/06/22 01:16:39 + [sftp.c] + don't show .files by default in ls, add -a option to turn them back on; + ok markus + - markus@cvs.openbsd.org 2004/06/22 03:12:13 + [regress/envpass.sh regress/multiplex.sh] + more portable env passing tests + - dtucker@cvs.openbsd.org 2004/06/22 05:05:45 + [monitor.c monitor_wrap.c] + Change login->username, will prevent -Wshadow errors in Portable; + ok markus@ + - (dtucker) [monitor.c] Fix Portable-specific -Wshadow warnings on "socket". + - (dtucker) [defines.h] Define __dead if not already defined. + - (bal) [auth-passwd.c auth1.c] Clean up unused variables. + +20040620 + - (tim) [configure.ac Makefile.in] Only change TEST_SHELL on broken platforms. + +20040619 + - (dtucker) [auth-pam.c] Don't use PAM namespace for + pam_password_change_required either. + - (tim) [configure.ac buildpkg.sh.in contrib/solaris/README] move opensshd + init script to top level directory. Add opensshd.init.in. + Remove contrib/solaris/buildpkg.sh, contrib/solaris/opensshd.in + +20040618 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2004/06/17 14:52:48 + [clientloop.c clientloop.h ssh.c] + support environment passing over shared connections; ok markus@ + - djm@cvs.openbsd.org 2004/06/17 15:10:14 + [clientloop.c misc.h readconf.c readpass.c ssh.c ssh_config.5] + Add option for confirmation (ControlMaster=ask) via ssh-askpass before + opening shared connections; ok markus@ + - djm@cvs.openbsd.org 2004/06/17 14:53:27 + [regress/multiplex.sh] + shared connection env passing regress test + - (dtucker) [regress/README.regress] Add detail on how to run a single + test from the top-level Makefile. + - (dtucker) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2004/06/17 23:56:57 + [ssh.1 ssh.c] + sync usage() and SYNPOSIS with connection sharing changes + - dtucker@cvs.openbsd.org 2004/06/18 06:13:25 + [sftp.c] + Use execvp instead of execv so sftp -S ssh works. "makes sense" markus@ + - dtucker@cvs.openbsd.org 2004/06/18 06:15:51 + [multiplex.sh] + Use -S for scp/sftp to force the use of the ssh being tested. + ok djm@,markus@ + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2004/06/18 10:40:19 + [ssh.c] + delay signal handler setup until we have finished talking to the master. + allow interrupting of setup (e.g. if master is stuck); ok markus@ + - markus@cvs.openbsd.org 2004/06/18 10:55:43 + [ssh.1 ssh.c] + trim synopsis for -S, allow -S and -oControlMaster, -MM means 'ask'; + ok djm + - djm@cvs.openbsd.org 2004/06/18 11:11:54 + [channels.c clientloop.c] + Don't explode in clientloop when we receive a bogus channel id, but + also don't generate them to begin with; ok markus@ + +20040617 + - (dtucker) [regress/scp.sh] diff -N is not portable (but needed for some + platforms), so test if diff understands it. Pointed out by tim@, ok djm@ + - (dtucker) OpenBSD CVS Sync regress/ + - dtucker@cvs.openbsd.org 2004/06/17 05:51:59 + [regress/multiplex.sh] + Remove datafile between and after tests, kill sshd rather than wait; + ok djm@ + - dtucker@cvs.openbsd.org 2004/06/17 06:00:05 + [regress/multiplex.sh] + Use DATA and COPY for test data rather than hard-coded paths; ok djm@ + - dtucker@cvs.openbsd.org 2004/06/17 06:19:06 + [regress/multiplex.sh] + Add small description of failing test to failure message; ok djm@ + - (dtucker) [regress/multiplex.sh] add EXEEXT for those platforms that need + it. + - (dtucker) [regress/multiplex.sh] Increase sleep time to 120 sec (60 is not + enough for slow systems, especially if they don't have a kernel RNG). + +20040616 + - (dtucker) [openbsd-compat/port-aix.c] Expand whitespace -> tabs. No + code changes. + - (dtucker) OpenBSD CVS Sync regress/ + - djm@cvs.openbsd.org 2004/04/27 09:47:30 + [regress/Makefile regress/test-exec.sh, added regress/envpass.sh] + regress test for environment passing, SendEnv & AcceptEnv options; + ok markus@ + - dtucker@cvs.openbsd.org 2004/06/13 13:51:02 + [regress/Makefile regress/test-exec.sh, added regress/scp-ssh-wrapper.sh + regress/scp.sh] + Add scp regression test; with & ok markus@ + - djm@cvs.openbsd.org 2004/06/13 15:04:08 + [regress/Makefile regress/test-exec.sh, added regress/envpass.sh] + regress test for client multiplexing; ok markus@ + - djm@cvs.openbsd.org 2004/06/13 15:16:54 + [regress/test-exec.sh] + remove duplicate setting of $SCP; spotted by markus@ + - dtucker@cvs.openbsd.org 2004/06/16 13:15:09 + [regress/scp.sh] + Make scp -r tests use diff -rN not cmp (which won't do dirs. ok markus@ + - dtucker@cvs.openbsd.org 2004/06/16 13:16:40 + [regress/multiplex.sh] + Silence multiplex sftp and scp tests. ok markus@ + - (dtucker) [regress/test-exec.sh] + Move Portable-only StrictModes to top of list to make syncs easier. + - (dtucker) [regress/README.regress] + Add $TEST_SHELL to readme. + +20040615 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2004/05/26 08:59:57 + [sftp.c] + exit -> _exit in forked child on error; from andrushock AT korovino.net + - markus@cvs.openbsd.org 2004/05/26 23:02:39 + [channels.c] + missing freeaddrinfo; Andrey Matveev + - dtucker@cvs.openbsd.org 2004/05/27 00:50:13 + [readconf.c] + Kill dead code after fatal(); ok djm@ + - dtucker@cvs.openbsd.org 2004/06/01 14:20:45 + [auth2-chall.c] + Remove redundant #include; ok markus@ + - pedro@cvs.openbsd.org 2004/06/03 12:22:20 + [sftp-client.c sftp.c] + initialize pointers, ok markus@ + - djm@cvs.openbsd.org 2004/06/13 12:53:24 + [dh.c dh.h kex.c kex.h kexdhc.c kexdhs.c monitor.c myproposal.h] + [ssh-keyscan.c sshconnect2.c sshd.c] + implement diffie-hellman-group14-sha1 kex method (trivial extension to + existing diffie-hellman-group1-sha1); ok markus@ + - dtucker@cvs.openbsd.org 2004/06/13 14:01:42 + [ssh.1 ssh_config.5 sshd_config.5] + List supported ciphers in man pages, tidy up ssh -c; + "looks fine" jmc@, ok markus@ + - djm@cvs.openbsd.org 2004/06/13 15:03:02 + [channels.c channels.h clientloop.c clientloop.h includes.h readconf.c] + [readconf.h scp.1 sftp.1 ssh.1 ssh.c ssh_config.5] + implement session multiplexing in the client (the server has supported + this since 2.0); ok markus@ + - djm@cvs.openbsd.org 2004/06/14 01:44:39 + [channels.c clientloop.c misc.c misc.h packet.c ssh-agent.c ssh-keyscan.c] + [sshd.c] + set_nonblock() instead of fnctl(...,O_NONBLOCK); "looks sane" deraadt@ + - djm@cvs.openbsd.org 2004/06/15 05:45:04 + [clientloop.c] + missed one unset_nonblock; spotted by Tim Rice + - (djm) Fix Makefile.in for connection sharing changes + - (djm) [ssh.c] Use separate var for address length + +20040603 + - (dtucker) [auth-pam.c] Don't use pam_* namespace for sshd's PAM functions. + ok djm@ + +20040601 + - (djm) [auth-pam.c] Add copyright for local changes + +20040530 + - (dtucker) [auth-pam.c auth-pam.h auth-passwd.c] Bug #874: Re-add PAM + support for PasswordAuthentication=yes. ok djm@ + - (dtucker) [auth-pam.c] Use an invalid password for root if + PermitRootLogin != yes or the login is invalid, to prevent leaking + information. Based on Openwall's owl-always-auth patch. ok djm@ + - (tim) [configure.ac Makefile.in] Add support for "make package" ok djm@ + - (tim) [buildpkg.sh.in] New file. A more flexible version of + contrib/solaris/buildpkg.sh used for "make package". + - (tim) [buildpkg.sh.in] Last minute fix didn't make it in the .in file. + +20040527 + - (dtucker) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec + contrib/README CREDITS INSTALL] Bug #873: Correct URLs for x11-ssh-askpass + and Jim Knoble's email address , from Jim himself. + +20040524 + - (dtucker) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2004/05/19 12:17:33 + [sftp-client.c sftp.c] + gracefully abort transfers on receipt of SIGINT, also ignore SIGINT while + waiting for a command; ok markus@ + - dtucker@cvs.openbsd.org 2004/05/20 10:58:05 + [clientloop.c] + Trivial type fix 0 -> '\0'; ok markus@ + - markus@cvs.openbsd.org 2004/05/21 08:43:03 + [kex.h moduli.c tildexpand.c] + add prototypes for -Wall; ok djm + - djm@cvs.openbsd.org 2004/05/21 11:33:11 + [channels.c channels.h clientloop.c serverloop.c ssh.1] + bz #756: add support for the cancel-tcpip-forward request for the server + and the client (through the ~C commandline). reported by z3p AT + twistedmatrix.com; ok markus@ + - djm@cvs.openbsd.org 2004/05/22 06:32:12 + [clientloop.c ssh.1] + use '-h' for help in ~C commandline instead of '-?'; inspired by jmc@ + - jmc@cvs.openbsd.org 2004/05/22 16:01:05 + [ssh.1] + kill whitespace at eol; + - dtucker@cvs.openbsd.org 2004/05/23 23:59:53 + [auth.c auth.h auth1.c auth2.c servconf.c servconf.h sshd_config + sshd_config.5] + Add MaxAuthTries sshd config option; ok markus@ + - (dtucker) [auth-pam.c] Bug #839: Ensure that pam authentication "thread" + is terminated if the privsep slave exits during keyboard-interactive + authentication. ok djm@ + - (dtucker) [sshd.c] Fix typo in comment. + +20040523 + - (djm) [sshd_config] Explain consequences of UsePAM=yes a little better in + sshd_config; ok dtucker@ + - (djm) [configure.ac] Warn if the system has no known way of figuring out + which user is on the other end of a Unix domain socket; ok dtucker@ + - (bal) [openbsd-compat/sys-queue.h] Reintroduce machinary to handle + old/broken/incomplete . + +20040513 + - (dtucker) [configure.ac] Bug #867: Additional tests for res_query in + libresolv, fixes problems detecting it on some platforms + (eg Linux/x86-64). From Kurt Roeckx via Debian, ok mouring@ + - (dtucker) OpenBSD CVS Sync + - jmc@cvs.openbsd.org 2004/05/04 18:36:07 + [scp.1] + SendEnv here too; + - jmc@cvs.openbsd.org 2004/05/06 11:24:23 + [ssh_config.5] + typo from John Cosimano (PR 3770); + - deraadt@cvs.openbsd.org 2004/05/08 00:01:37 + [auth.c clientloop.c misc.h servconf.c ssh.c sshpty.h sshtty.c + tildexpand.c], removed: sshtty.h tildexpand.h + make two tiny header files go away; djm ok + - djm@cvs.openbsd.org 2004/05/08 00:21:31 + [clientloop.c misc.h readpass.c scard.c ssh-add.c ssh-agent.c ssh-keygen.c + sshconnect.c sshconnect1.c sshconnect2.c] removed: readpass.h + kill a tiny header; ok deraadt@ + - djm@cvs.openbsd.org 2004/05/09 00:06:47 + [moduli.c ssh-keygen.c] removed: moduli.h + zap another tiny header; ok deraadt@ + - djm@cvs.openbsd.org 2004/05/09 01:19:28 + [OVERVIEW auth-rsa.c auth1.c kex.c monitor.c session.c sshconnect1.c + sshd.c] removed: mpaux.c mpaux.h + kill some more tiny files; ok deraadt@ + - djm@cvs.openbsd.org 2004/05/09 01:26:48 + [kex.c] + don't overwrite what we are trying to compute + - deraadt@cvs.openbsd.org 2004/05/11 19:01:43 + [auth.c auth2-none.c authfile.c channels.c monitor.c monitor_mm.c + packet.c packet.h progressmeter.c session.c openbsd-compat/xmmap.c] + improve some code lint did not like; djm millert ok + - dtucker@cvs.openbsd.org 2004/05/13 02:47:50 + [ssh-agent.1] + Add examples to ssh-agent.1, bz#481 from Ralf Hauser; ok deraadt@ + - (dtucker) [sshd.8] Bug #843: Add warning about PasswordAuthentication to + UsePAM section. Parts from djm@ and jmc@. + - (dtucker) [auth-pam.c scard-opensc.c] Tinderbox says auth-pam.c uses + readpass.h, grep says scard-opensc.c does too. Replace with misc.h. + - (dtucker) [openbsd-compat/getrrsetbyname.c] Check that HAVE_DECL_H_ERROR + is defined before using. + - (dtucker) [openbsd-compat/getrrsetbyname.c] Fix typo too: HAVE_DECL_H_ERROR + -> HAVE_DECL_H_ERRNO. + +20040502 + - (dtucker) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2004/04/22 11:56:57 + [moduli.c] + Bugzilla #850: Sophie Germain is the correct name of the French + mathematician, "Sophie Germaine" isn't; from Luc.Maisonobe@c-s.fr + - djm@cvs.openbsd.org 2004/04/27 09:46:37 + [readconf.c readconf.h servconf.c servconf.h session.c session.h ssh.c + ssh_config.5 sshd_config.5] + bz #815: implement ability to pass specified environment variables from + the client to the server; ok markus@ + - djm@cvs.openbsd.org 2004/04/28 05:17:10 + [ssh_config.5 sshd_config.5] + manpage fixes in envpass stuff from Brian Poole (raj AT cerias.purdue.edu) + - jmc@cvs.openbsd.org 2004/04/28 07:02:56 + [sshd_config.5] + remove unnecessary .Pp; + - jmc@cvs.openbsd.org 2004/04/28 07:13:42 + [sftp.1 ssh.1] + add SendEnv to -o list; + - dtucker@cvs.openbsd.org 2004/05/02 11:54:31 + [sshd.8] + Man page grammar fix (bz #858), from damerell at chiark.greenend.org.uk + via Debian; ok djm@ + - dtucker@cvs.openbsd.org 2004/05/02 11:57:52 + [ssh.1] + ConnectionTimeout -> ConnectTimeout, from m.a.ellis at ncl.ac.uk via + Debian. ok djm@ + - dtucker@cvs.openbsd.org 2004/05/02 23:02:17 + [sftp.1] + ConnectionTimeout -> ConnectTimeout here too, pointed out by jmc@ + - dtucker@cvs.openbsd.org 2004/05/02 23:17:51 + [scp.1] + ConnectionTimeout -> ConnectTimeout for scp.1 too. + +20040423 + - (dtucker) [configure.ac openbsd-compat/getrrsetbyname.c] Declare h_errno + as extern int if not already declared. Fixes compile errors on old SCO + platforms. ok tim@ + - (dtucker) [README.platform] List prereqs for building on Cygwin. + +20040421 + - (djm) Update config.guess and config.sub to autoconf-2.59 versions; ok tim@ + +20040420 + - (djm) OpenBSD CVS Sync + - henning@cvs.openbsd.org 2004/04/08 16:08:21 + [sshconnect2.c] + swap the last two parameters to TAILQ_FOREACH_REVERSE. matches what + FreeBSD and NetBSD do. + ok millert@ mcbride@ markus@ ho@, checked to not affect ports by naddy@ + - djm@cvs.openbsd.org 2004/04/18 23:10:26 + [readconf.c readconf.h ssh-keysign.c ssh.c] + perform strict ownership and modes checks for ~/.ssh/config files, + as these can be used to execute arbitrary programs; ok markus@ + NB. ssh will now exit when it detects a config with poor permissions + - djm@cvs.openbsd.org 2004/04/19 13:02:40 + [ssh.1 ssh_config.5] + document strict permission checks on ~/.ssh/config; prompted by, + with & ok jmc@ + - jmc@cvs.openbsd.org 2004/04/19 16:12:14 + [ssh_config.5] + kill whitespace at eol; + - djm@cvs.openbsd.org 2004/04/19 21:51:49 + [ssh.c] + fix idiot typo that i introduced in my last commit; + spotted by cschneid AT cschneid.com + - (djm) [openbsd-compat/sys-queue.h] Sync with OpenBSD, needed for + above change + - (djm) [configure.ac] Check whether libroken is required when building + with Heimdal + +20040419 + - (dtucker) OpenBSD CVS Sync + - dtucker@cvs.openbsd.org 2004/02/29 22:04:45 + [regress/login-timeout.sh] + Use sudo when restarting daemon during test. ok markus@ + - dtucker@cvs.openbsd.org 2004/03/08 10:17:12 + [regress/login-timeout.sh] + Missing OBJ, from tim@. ok markus@ (Already fixed, ID sync only) + - djm@cvs.openbsd.org 2004/03/30 12:41:56 + [sftp-client.c] + sync comment with reality + - djm@cvs.openbsd.org 2004/03/31 21:58:47 + [canohost.c] + don't skip ip options check when UseDNS=no; ok markus@ (ID sync only) + - markus@cvs.openbsd.org 2004/04/01 12:19:57 + [scp.c] + limit trust between local and remote rcp/scp process, + noticed by lcamtuf; ok deraadt@, djm@ + 20040418 - (dtucker) [auth-pam.c] Log username and source host for failed PAM authentication attempts. With & ok djm@ - (djm) [openbsd-compat/bsd-cygwin_util.c] Recent versions of Cygwin allow change of user context without a password, so relax auth method restrictions; from vinschen AT redhat.com; ok dtucker@ - - Release 3.8.1p1 20040416 - (dtucker) [regress/sftp-cmds.sh] Skip quoting test on Cygwin, since diff --git a/openssh/INSTALL b/openssh/INSTALL index eecc386..0fa4a6d 100644 --- a/openssh/INSTALL +++ b/openssh/INSTALL @@ -30,7 +30,7 @@ libraries and headers. GNOME: http://www.gnome.org/ -Alternatively, Jim Knoble has written an excellent X11 +Alternatively, Jim Knoble has written an excellent X11 passphrase requester. This is maintained separately at: http://www.jmknoble.net/software/x11-ssh-askpass/ diff --git a/openssh/Makefile.in b/openssh/Makefile.in index 576bac2..27e6b10 100644 --- a/openssh/Makefile.in +++ b/openssh/Makefile.in @@ -67,22 +67,21 @@ LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o buffer.o \ compat.o compress.o crc32.o deattack.o fatal.o hostfile.o \ log.o match.o moduli.o mpaux.o nchan.o packet.o \ readpass.o rsa.o tildexpand.o ttymodes.o xmalloc.o \ - atomicio.o key.o dispatch.o kex.o mac.o uuencode.o misc.o \ - rijndael.o ssh-dss.o ssh-rsa.o dh.o kexdh.o kexgex.o \ - kexdhc.o kexgexc.o scard.o msg.o progressmeter.o dns.o \ + atomicio.o key.o dispatch.o kex.o mac.o uidswap.o uuencode.o misc.o \ + monitor_fdpass.o rijndael.o ssh-dss.o ssh-rsa.o dh.o kexdh.o \ + kexgex.o kexdhc.o kexgexc.o scard.o msg.o progressmeter.o dns.o \ entropy.o scard-opensc.o gss-genr.o SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ sshconnect.o sshconnect1.o sshconnect2.o SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ - sshpty.o sshlogin.o servconf.o serverloop.o uidswap.o \ + sshpty.o sshlogin.o servconf.o serverloop.o \ auth.o auth1.o auth2.o auth-options.o session.o \ auth-chall.o auth2-chall.o groupaccess.o \ auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.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 \ + monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o \ auth-krb5.o \ auth2-gss.o gss-serv.o gss-serv-krb5.o \ loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o @@ -200,11 +199,14 @@ clean: regressclean distclean: regressclean rm -f *.o *.a $(TARGETS) logintest config.cache config.log - rm -f *.out core - rm -f Makefile config.h config.status ssh_prng_cmds *~ + rm -f *.out core opensshd.init + rm -f Makefile buildpkg.sh config.h config.status ssh_prng_cmds *~ rm -rf autom4te.cache (cd openbsd-compat && $(MAKE) distclean) (cd scard && $(MAKE) distclean) + if test -d pkg ; then \ + rm -fr pkg ; \ + fi veryclean: distclean rm -f configure config.h.in *.0 @@ -375,7 +377,7 @@ tests: $(TARGETS) [ -d `pwd`/regress ] || mkdir -p `pwd`/regress; \ [ -f `pwd`/regress/Makefile ] || \ ln -s $(srcdir)/regress/Makefile `pwd`/regress/Makefile ; \ - TEST_SHELL="@TEST_MINUS_S_SH@"; \ + TEST_SHELL="@TEST_SHELL@"; \ TEST_SSH_SSH="$${BUILDDIR}/ssh"; \ TEST_SSH_SSHD="$${BUILDDIR}/sshd"; \ TEST_SSH_SSHAGENT="$${BUILDDIR}/ssh-agent"; \ @@ -407,3 +409,9 @@ regressclean: if [ -f regress/Makefile -a -r regress/Makefile ]; then \ (cd regress && $(MAKE) clean) \ fi + +package: $(CONFIGFILES) ssh_prng_cmds.out $(MANPAGES) $(TARGETS) + if [ "@MAKE_PACKAGE_SUPPORTED@" = yes ]; then \ + sh buildpkg.sh; \ + fi + diff --git a/openssh/OVERVIEW b/openssh/OVERVIEW index df46ec2..d1a768c 100644 --- a/openssh/OVERVIEW +++ b/openssh/OVERVIEW @@ -40,7 +40,6 @@ these programs. Multiple Precision Integer Library - Uses the SSLeay BIGNUM sublibrary. - - Some auxiliary functions for mp-int manipulation are in mpaux.c. Random Numbers diff --git a/openssh/README b/openssh/README index d70edb7..4788215 100644 --- a/openssh/README +++ b/openssh/README @@ -15,10 +15,11 @@ Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo de Raadt, and Dug Song. It has a homepage at http://www.openssh.com/ This port consists of the re-introduction of autoconf support, PAM -support (for Linux and Solaris), EGD[1]/PRNGD[2] support and replacements -for OpenBSD library functions that are (regrettably) absent from other -unices. This port has been best tested on Linux, Solaris, HP-UX, NetBSD, -Irix and AIX. Support for SCO, NeXT and other Unices is underway. +support, EGD[1]/PRNGD[2] support and replacements for OpenBSD library +functions that are (regrettably) absent from other unices. This port +has been best tested on AIX, Cygwin, HP-UX, Linux, MacOS/X, +NetBSD, OpenBSD, OpenServer, Solaris, Unicos, and UnixWare. + This version actively tracks changes in the OpenBSD CVS repository. The PAM support is now more functional than the popular packages of @@ -32,13 +33,8 @@ refer to http://www.openssh.com/list.html for details on how to join. Please send bug reports and patches to the mailing list openssh-unix-dev@mindrot.org. The list is open to posting by -unsubscribed users. - -If you are a citizen of an USA-embargoed country to which export of -cryptographic products is restricted, then please refrain from sending -crypto-related code or patches to the list. We cannot accept them. -Other code contribution are accepted, but please follow the OpenBSD -style guidelines[6]. +unsubscribed users.Code contribution are welcomed, but please follow the +OpenBSD style guidelines[6]. Please refer to the INSTALL document for information on how to install OpenSSH on your system. There are a number of differences between this diff --git a/openssh/README.platform b/openssh/README.platform index f9318b7..d07b2c3 100644 --- a/openssh/README.platform +++ b/openssh/README.platform @@ -13,6 +13,14 @@ Accounts in this state must have their passwords reset manually by the administrator. As a precaution, it is recommended that the administrative passwords be reset before upgrading from OpenSSH <3.8. + +Cygwin +------ +To build on Cygwin, OpenSSH requires the following packages: +gcc, gcc-mingw-core, mingw-runtime, binutils, make, openssl, +openssl-devel, zlib, minres, minires-devel. + + Solaris ------- Currently, sshd does not support BSM auditting. This can show up as errors diff --git a/openssh/README.privsep b/openssh/README.privsep index fcbae9a..ba8345c 100644 --- a/openssh/README.privsep +++ b/openssh/README.privsep @@ -42,9 +42,9 @@ PAM-enabled OpenSSH is known to function with privsep on Linux. It does not function on HP-UX with a trusted system configuration. -On Compaq Tru64 Unix, only the pre-authentication part of privsep is -supported. Post-authentication privsep is disabled automatically (so -you won't see the additional process mentioned below). +On Cygwin, Tru64 Unix, OpenServer, and Unicos only the pre-authentication +part of privsep is supported. Post-authentication privsep is disabled +automatically (so you won't see the additional process mentioned below). Note that for a normal interactive login with a shell, enabling privsep will require 1 additional process per login session. diff --git a/openssh/acconfig.h b/openssh/acconfig.h index 7c03e26..6be585e 100644 --- a/openssh/acconfig.h +++ b/openssh/acconfig.h @@ -104,6 +104,9 @@ /* Work around problematic Linux PAM modules handling of PAM_TTY */ #undef PAM_TTY_KLUDGE +/* Define if pam_chauthtok wants real uid set to the unpriv'ed user */ +#undef SSHPAM_CHAUTHTOK_NEEDS_RUID + /* Use PIPES instead of a socketpair() */ #undef USE_PIPES @@ -434,6 +437,12 @@ /* Define if cmsg_type is not passed correctly */ #undef BROKEN_CMSG_TYPE +/* + * Define to whatever link() returns for "not supported" if it doesn't + * return EOPNOTSUPP. + */ +#undef LINK_OPNOTSUPP_ERRNO + /* Strings used in /etc/passwd to denote locked account */ #undef LOCKED_PASSWD_STRING #undef LOCKED_PASSWD_PREFIX @@ -448,6 +457,9 @@ /* Define if your resolver libs need this for getrrsetbyname */ #undef BIND_8_COMPAT +/* Define if you have /proc/$pid/fd */ +#undef HAVE_PROC_PID + @BOTTOM@ /* ******************* Shouldn't need to edit below this line ************** */ diff --git a/openssh/auth-krb5.c b/openssh/auth-krb5.c index a728eba..a324ff1 100644 --- a/openssh/auth-krb5.c +++ b/openssh/auth-krb5.c @@ -69,6 +69,7 @@ auth_krb5_password(Authctxt *authctxt, const char *password) krb5_principal server; char ccname[40]; int tmpfd; + mode_t old_umask; #endif krb5_error_code problem; krb5_ccache ccache = NULL; @@ -147,7 +148,10 @@ 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) { + old_umask = umask(0177); + tmpfd = mkstemp(ccname + strlen("FILE:")); + umask(old_umask); + if (tmpfd == -1) { logit("mkstemp(): %.100s", strerror(errno)); problem = errno; goto out; diff --git a/openssh/auth-pam.c b/openssh/auth-pam.c index 9eb3174..63908a7 100644 --- a/openssh/auth-pam.c +++ b/openssh/auth-pam.c @@ -28,6 +28,22 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ +/* + * Copyright (c) 2003,2004 Damien Miller + * Copyright (c) 2003,2004 Darren Tucker + * + * 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. + * + * 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. + */ /* Based on $FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des Exp $ */ #include "includes.h" @@ -49,7 +65,7 @@ RCSID("$Id$"); #include "monitor_wrap.h" #include "msg.h" #include "packet.h" -#include "readpass.h" +#include "misc.h" #include "servconf.h" #include "ssh2.h" #include "xmalloc.h" @@ -93,10 +109,17 @@ static mysig_t sshpam_oldsig; static void sshpam_sigchld_handler(int sig) { + signal(SIGCHLD, SIG_DFL); if (cleanup_ctxt == NULL) return; /* handler called after PAM cleanup, shouldn't happen */ - if (waitpid(cleanup_ctxt->pam_thread, &sshpam_thread_status, 0) == -1) - return; /* couldn't wait for process */ + if (waitpid(cleanup_ctxt->pam_thread, &sshpam_thread_status, WNOHANG) + <= 0) { + /* PAM thread has not exitted, privsep slave must have */ + kill(cleanup_ctxt->pam_thread, SIGTERM); + if (waitpid(cleanup_ctxt->pam_thread, &sshpam_thread_status, 0) + <= 0) + return; /* could not wait */ + } if (WIFSIGNALED(sshpam_thread_status) && WTERMSIG(sshpam_thread_status) == SIGTERM) return; /* terminated by pthread_cancel */ @@ -162,6 +185,7 @@ static int sshpam_cred_established = 0; static int sshpam_account_status = -1; static char **sshpam_env = NULL; static Authctxt *sshpam_authctxt = NULL; +static const char *sshpam_password = NULL; /* Some PAM implementations don't implement this */ #ifndef HAVE_PAM_GETENVLIST @@ -177,8 +201,33 @@ pam_getenvlist(pam_handle_t *pamh) } #endif +/* + * Some platforms, notably Solaris, do not enforce password complexity + * rules during pam_chauthtok() if the real uid of the calling process + * is 0, on the assumption that it's being called by "passwd" run by root. + * This wraps pam_chauthtok and sets/restore the real uid so PAM will do + * the right thing. + */ +#ifdef SSHPAM_CHAUTHTOK_NEEDS_RUID +static int +sshpam_chauthtok_ruid(pam_handle_t *pamh, int flags) +{ + int result; + + if (sshpam_authctxt == NULL) + fatal("PAM: sshpam_authctxt not initialized"); + if (setreuid(sshpam_authctxt->pw->pw_uid, -1) == -1) + fatal("%s: setreuid failed: %s", __func__, strerror(errno)); + result = pam_chauthtok(pamh, flags); + if (setreuid(0, -1) == -1) + fatal("%s: setreuid failed: %s", __func__, strerror(errno)); + return result; +} +# define pam_chauthtok(a,b) (sshpam_chauthtok_ruid((a), (b))) +#endif + void -pam_password_change_required(int reqd) +sshpam_password_change_required(int reqd) { debug3("%s %d", __func__, reqd); if (sshpam_authctxt == NULL) @@ -208,7 +257,7 @@ import_environments(Buffer *b) #ifndef USE_POSIX_THREADS /* Import variables set by do_pam_account */ sshpam_account_status = buffer_get_int(b); - pam_password_change_required(buffer_get_int(b)); + sshpam_password_change_required(buffer_get_int(b)); /* Import environment from subprocess */ num_env = buffer_get_int(b); @@ -240,7 +289,7 @@ import_environments(Buffer *b) * Conversation function for authentication thread. */ static int -sshpam_thread_conv(int n, const struct pam_message **msg, +sshpam_thread_conv(int n, struct pam_message **msg, struct pam_response **resp, void *data) { Buffer buffer; @@ -251,6 +300,10 @@ sshpam_thread_conv(int n, const struct pam_message **msg, debug3("PAM: %s entering, %d messages", __func__, n); *resp = NULL; + if (data == NULL) { + error("PAM: conversation function passed a null context"); + return (PAM_CONV_ERR); + } ctxt = data; if (n <= 0 || n > PAM_MAX_NUM_MSG) return (PAM_CONV_ERR); @@ -328,15 +381,21 @@ sshpam_thread(void *ctxtp) struct pam_ctxt *ctxt = ctxtp; Buffer buffer; struct pam_conv sshpam_conv; + int flags = (options.permit_empty_passwd == 0 ? + PAM_DISALLOW_NULL_AUTHTOK : 0); #ifndef USE_POSIX_THREADS extern char **environ; char **env_from_pam; u_int i; const char *pam_user; - pam_get_item(sshpam_handle, PAM_USER, (const void **)&pam_user); - setproctitle("%s [pam]", pam_user); + pam_get_item(sshpam_handle, PAM_USER, (void **)&pam_user); environ[0] = NULL; + + if (sshpam_authctxt != NULL) { + setproctitle("%s [pam]", + sshpam_authctxt->valid ? pam_user : "unknown"); + } #endif sshpam_conv.conv = sshpam_thread_conv; @@ -350,7 +409,7 @@ sshpam_thread(void *ctxtp) (const void *)&sshpam_conv); if (sshpam_err != PAM_SUCCESS) goto auth_fail; - sshpam_err = pam_authenticate(sshpam_handle, 0); + sshpam_err = pam_authenticate(sshpam_handle, flags); if (sshpam_err != PAM_SUCCESS) goto auth_fail; @@ -362,7 +421,7 @@ sshpam_thread(void *ctxtp) PAM_CHANGE_EXPIRED_AUTHTOK); if (sshpam_err != PAM_SUCCESS) goto auth_fail; - pam_password_change_required(0); + sshpam_password_change_required(0); } } @@ -422,7 +481,7 @@ sshpam_thread_cleanup(void) } static int -sshpam_null_conv(int n, const struct pam_message **msg, +sshpam_null_conv(int n, struct pam_message **msg, struct pam_response **resp, void *data) { debug3("PAM: %s entering, %d messages", __func__, n); @@ -460,7 +519,7 @@ sshpam_init(Authctxt *authctxt) 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); + PAM_USER, (void **)&pam_user); if (sshpam_err == PAM_SUCCESS && strcmp(user, pam_user) == 0) return (0); pam_end(sshpam_handle, sshpam_err); @@ -712,7 +771,7 @@ do_pam_account(void) } if (sshpam_err == PAM_NEW_AUTHTOK_REQD) - pam_password_change_required(1); + sshpam_password_change_required(1); sshpam_account_status = 1; return (sshpam_account_status); @@ -758,7 +817,7 @@ do_pam_setcred(int init) } static int -pam_tty_conv(int n, const struct pam_message **msg, +sshpam_tty_conv(int n, struct pam_message **msg, struct pam_response **resp, void *data) { char input[PAM_MAX_MSG_SIZE]; @@ -787,7 +846,8 @@ pam_tty_conv(int n, const struct pam_message **msg, case PAM_PROMPT_ECHO_ON: fprintf(stderr, "%s\n", PAM_MSG_MEMBER(msg, i, msg)); fgets(input, sizeof input, stdin); - reply[i].resp = xstrdup(input); + if ((reply[i].resp = strdup(input)) == NULL) + goto fail; reply[i].resp_retcode = PAM_SUCCESS; break; case PAM_ERROR_MSG: @@ -811,7 +871,7 @@ pam_tty_conv(int n, const struct pam_message **msg, return (PAM_CONV_ERR); } -static struct pam_conv tty_conv = { pam_tty_conv, NULL }; +static struct pam_conv tty_conv = { sshpam_tty_conv, NULL }; /* * XXX this should be done in the authentication phase, but ssh1 doesn't @@ -835,7 +895,7 @@ do_pam_chauthtok(void) } static int -pam_store_conv(int n, const struct pam_message **msg, +sshpam_store_conv(int n, struct pam_message **msg, struct pam_response **resp, void *data) { struct pam_response *reply; @@ -877,7 +937,7 @@ pam_store_conv(int n, const struct pam_message **msg, return (PAM_CONV_ERR); } -static struct pam_conv store_conv = { pam_store_conv, NULL }; +static struct pam_conv store_conv = { sshpam_store_conv, NULL }; void do_pam_session(void) @@ -944,4 +1004,112 @@ free_pam_environment(char **env) xfree(env); } +/* + * "Blind" conversation function for password authentication. Assumes that + * echo-off prompts are for the password and stores messages for later + * display. + */ +static int +sshpam_passwd_conv(int n, struct pam_message **msg, + struct pam_response **resp, void *data) +{ + struct pam_response *reply; + int i; + size_t len; + + debug3("PAM: %s called with %d messages", __func__, n); + + *resp = NULL; + + if (n <= 0 || n > PAM_MAX_NUM_MSG) + return (PAM_CONV_ERR); + + if ((reply = malloc(n * sizeof(*reply))) == NULL) + return (PAM_CONV_ERR); + memset(reply, 0, n * sizeof(*reply)); + + for (i = 0; i < n; ++i) { + switch (PAM_MSG_MEMBER(msg, i, msg_style)) { + case PAM_PROMPT_ECHO_OFF: + if (sshpam_password == NULL) + goto fail; + if ((reply[i].resp = strdup(sshpam_password)) == NULL) + goto fail; + reply[i].resp_retcode = PAM_SUCCESS; + break; + case PAM_ERROR_MSG: + case PAM_TEXT_INFO: + len = strlen(PAM_MSG_MEMBER(msg, i, msg)); + if (len > 0) { + buffer_append(&loginmsg, + PAM_MSG_MEMBER(msg, i, msg), len); + buffer_append(&loginmsg, "\n", 1); + } + if ((reply[i].resp = strdup("")) == NULL) + goto fail; + reply[i].resp_retcode = PAM_SUCCESS; + break; + default: + goto fail; + } + } + *resp = reply; + return (PAM_SUCCESS); + + fail: + for(i = 0; i < n; i++) { + if (reply[i].resp != NULL) + xfree(reply[i].resp); + } + xfree(reply); + return (PAM_CONV_ERR); +} + +static struct pam_conv passwd_conv = { sshpam_passwd_conv, NULL }; + +/* + * Attempt password authentication via PAM + */ +int +sshpam_auth_passwd(Authctxt *authctxt, const char *password) +{ + int flags = (options.permit_empty_passwd == 0 ? + PAM_DISALLOW_NULL_AUTHTOK : 0); + static char badpw[] = "\b\n\r\177INCORRECT"; + + if (!options.use_pam || sshpam_handle == NULL) + fatal("PAM: %s called when PAM disabled or failed to " + "initialise.", __func__); + + sshpam_password = password; + sshpam_authctxt = authctxt; + + /* + * If the user logging in is invalid, or is root but is not permitted + * by PermitRootLogin, use an invalid password to prevent leaking + * information via timing (eg if the PAM config has a delay on fail). + */ + if (!authctxt->valid || (authctxt->pw->pw_uid == 0 && + options.permit_root_login != PERMIT_YES)) + sshpam_password = badpw; + + sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, + (const void *)&passwd_conv); + if (sshpam_err != PAM_SUCCESS) + fatal("PAM: %s: failed to set PAM_CONV: %s", __func__, + pam_strerror(sshpam_handle, sshpam_err)); + + sshpam_err = pam_authenticate(sshpam_handle, flags); + sshpam_password = NULL; + if (sshpam_err == PAM_SUCCESS && authctxt->valid) { + debug("PAM: password authentication accepted for %.100s", + authctxt->user); + return 1; + } else { + debug("PAM: password authentication failed for %.100s: %s", + authctxt->valid ? authctxt->user : "an illegal user", + pam_strerror(sshpam_handle, sshpam_err)); + return 0; + } +} #endif /* USE_PAM */ diff --git a/openssh/auth-pam.h b/openssh/auth-pam.h index ff501f6..f756b31 100644 --- a/openssh/auth-pam.h +++ b/openssh/auth-pam.h @@ -44,5 +44,6 @@ char ** fetch_pam_child_environment(void); void free_pam_environment(char **); void sshpam_thread_cleanup(void); void sshpam_cleanup(void); +int sshpam_auth_passwd(Authctxt *, const char *); #endif /* USE_PAM */ diff --git a/openssh/auth-passwd.c b/openssh/auth-passwd.c index beaf0fa..7a68e05 100644 --- a/openssh/auth-passwd.c +++ b/openssh/auth-passwd.c @@ -64,7 +64,9 @@ auth_password(Authctxt *authctxt, const char *password) { struct passwd * pw = authctxt->pw; int ok = authctxt->valid; +#if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE) static int expire_checked = 0; +#endif #ifndef HAVE_CYGWIN if (pw->pw_uid == 0 && options.permit_root_login != PERMIT_YES) @@ -91,6 +93,10 @@ auth_password(Authctxt *authctxt, const char *password) return ok; } #endif +#ifdef USE_PAM + if (options.use_pam) + return (sshpam_auth_passwd(authctxt, password) && ok); +#endif #if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE) if (!expire_checked) { expire_checked = 1; diff --git a/openssh/auth-rsa.c b/openssh/auth-rsa.c index 2f0746b..16369d4 100644 --- a/openssh/auth-rsa.c +++ b/openssh/auth-rsa.c @@ -14,7 +14,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth-rsa.c,v 1.58 2003/11/04 08:54:09 djm Exp $"); +RCSID("$OpenBSD: auth-rsa.c,v 1.60 2004/06/21 17:36:31 avsm Exp $"); #include #include @@ -23,7 +23,6 @@ RCSID("$OpenBSD: auth-rsa.c,v 1.58 2003/11/04 08:54:09 djm Exp $"); #include "packet.h" #include "xmalloc.h" #include "ssh1.h" -#include "mpaux.h" #include "uidswap.h" #include "match.h" #include "auth-options.h" @@ -204,7 +203,7 @@ auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey) */ while (fgets(line, sizeof(line), f)) { char *cp; - char *options; + char *key_options; linenum++; @@ -222,7 +221,7 @@ auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey) */ if (*cp < '0' || *cp > '9') { int quoted = 0; - options = cp; + key_options = cp; for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) { if (*cp == '\\' && cp[1] == '"') cp++; /* Skip both */ @@ -230,7 +229,7 @@ auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey) quoted = !quoted; } } else - options = NULL; + key_options = NULL; /* Parse the key from the line. */ if (hostfile_read_key(&cp, &bits, key) == 0) { @@ -255,7 +254,7 @@ auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey) * If our options do not allow this key to be used, * do not send challenge. */ - if (!auth_parse_options(pw, options, file, linenum)) + if (!auth_parse_options(pw, key_options, file, linenum)) continue; /* break out, this key is allowed */ diff --git a/openssh/auth.c b/openssh/auth.c index 6d99922..0956b0b 100644 --- a/openssh/auth.c +++ b/openssh/auth.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth.c,v 1.51 2003/11/21 11:57:02 djm Exp $"); +RCSID("$OpenBSD: auth.c,v 1.56 2004/07/28 09:40:29 markus Exp $"); #ifdef HAVE_LOGIN_H #include @@ -47,7 +47,6 @@ RCSID("$OpenBSD: auth.c,v 1.51 2003/11/21 11:57:02 djm Exp $"); #include "buffer.h" #include "bufaux.h" #include "uidswap.h" -#include "tildexpand.h" #include "misc.h" #include "bufaux.h" #include "packet.h" @@ -204,31 +203,10 @@ allowed_user(struct passwd * pw) ga_free(); } -#ifdef WITH_AIXAUTHENTICATE - /* - * Don't check loginrestrictions() for root account (use - * 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)) { - 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); - } - /* Don't fail if /etc/nologin set */ - if (!(loginrestrict_errno == EPERM && - stat(_PATH_NOLOGIN, &st) == 0)) - return 0; - } - } -#endif /* WITH_AIXAUTHENTICATE */ +#ifdef CUSTOM_SYS_AUTH_ALLOWED_USER + if (!sys_auth_allowed_user(pw)) + return 0; +#endif /* We found no reason not to let this user try to log on... */ return 1; @@ -243,7 +221,7 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info) /* Raise logging level */ if (authenticated == 1 || !authctxt->valid || - authctxt->failures >= AUTH_FAIL_LOG || + authctxt->failures >= options.max_authtries / 2 || strcmp(method, "password") == 0) authlog = logit; @@ -255,7 +233,7 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info) authlog("%s %s for %s%.100s from %.200s port %d%s", authmsg, method, - authctxt->valid ? "" : "illegal user ", + authctxt->valid ? "" : "invalid user ", authctxt->user, get_remote_ipaddr(), get_remote_port(), @@ -484,7 +462,7 @@ getpwnamallow(const char *user) pw = getpwnam(user); if (pw == NULL) { - logit("Illegal user %.100s from %.100s", + logit("Invalid user %.100s from %.100s", user, get_remote_ipaddr()); #ifdef CUSTOM_FAILED_LOGIN record_failed_login(user, "ssh"); @@ -563,8 +541,8 @@ fakepw(void) fake.pw_passwd = "$2a$06$r3.juUaHZDlIbQaO2dS9FuYxL1W9M81R1Tc92PoSNmzvpEqLkLGrK"; fake.pw_gecos = "NOUSER"; - fake.pw_uid = -1; - fake.pw_gid = -1; + fake.pw_uid = (uid_t)-1; + fake.pw_gid = (gid_t)-1; #ifdef HAVE_PW_CLASS_IN_PASSWD fake.pw_class = ""; #endif diff --git a/openssh/auth.h b/openssh/auth.h index 3a7d222..2f09440 100644 --- a/openssh/auth.h +++ b/openssh/auth.h @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.h,v 1.49 2004/01/30 09:48:57 markus Exp $ */ +/* $OpenBSD: auth.h,v 1.50 2004/05/23 23:59:53 dtucker Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -181,8 +181,6 @@ 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" #define SKEY_PROMPT "\nS/Key Password: " diff --git a/openssh/auth1.c b/openssh/auth1.c index f145cf0..3f93b98 100644 --- a/openssh/auth1.c +++ b/openssh/auth1.c @@ -10,14 +10,13 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth1.c,v 1.55 2003/11/08 16:02:40 jakob Exp $"); +RCSID("$OpenBSD: auth1.c,v 1.59 2004/07/28 09:40:29 markus Exp $"); #include "xmalloc.h" #include "rsa.h" #include "ssh1.h" #include "packet.h" #include "buffer.h" -#include "mpaux.h" #include "log.h" #include "servconf.h" #include "compat.h" @@ -70,10 +69,9 @@ do_authloop(Authctxt *authctxt) u_int dlen; u_int ulen; int prev, type = 0; - struct passwd *pw = authctxt->pw; debug("Attempting authentication for %s%.100s.", - authctxt->valid ? "" : "illegal user ", authctxt->user); + authctxt->valid ? "" : "invalid user ", authctxt->user); /* If the user has no password, accept authentication immediately. */ if (options.password_authentication && @@ -81,8 +79,13 @@ do_authloop(Authctxt *authctxt) (!options.kerberos_authentication || options.kerberos_or_local_passwd) && #endif PRIVSEP(auth_password(authctxt, ""))) { - auth_log(authctxt, 1, "without authentication", ""); - return; +#ifdef USE_PAM + if (options.use_pam && (PRIVSEP(do_pam_account()))) +#endif + { + auth_log(authctxt, 1, "without authentication", ""); + return; + } } /* Indicate that authentication is needed. */ @@ -233,9 +236,10 @@ do_authloop(Authctxt *authctxt) #ifdef HAVE_CYGWIN if (authenticated && - !check_nt_auth(type == SSH_CMSG_AUTH_PASSWORD, pw)) { + !check_nt_auth(type == SSH_CMSG_AUTH_PASSWORD, + authctxt->pw)) { packet_disconnect("Authentication rejected for uid %d.", - pw == NULL ? -1 : pw->pw_uid); + authctxt->pw == NULL ? -1 : authctxt->pw->pw_uid); authenticated = 0; } #else @@ -262,7 +266,7 @@ do_authloop(Authctxt *authctxt) if (authenticated) return; - if (authctxt->failures++ > AUTH_FAIL_MAX) + if (authctxt->failures++ > options.max_authtries) packet_disconnect(AUTH_FAIL_MSG, authctxt->user); packet_start(SSH_SMSG_FAILURE); @@ -298,11 +302,11 @@ do_authentication(Authctxt *authctxt) if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL) authctxt->valid = 1; else { - debug("do_authentication: illegal user %s", user); + debug("do_authentication: invalid user %s", user); authctxt->pw = fakepw(); } - setproctitle("%s%s", authctxt->pw ? user : "unknown", + setproctitle("%s%s", authctxt->valid ? user : "unknown", use_privsep ? " [net]" : ""); #ifdef USE_PAM diff --git a/openssh/auth2-chall.c b/openssh/auth2-chall.c index aacbf0b..486baaa 100644 --- a/openssh/auth2-chall.c +++ b/openssh/auth2-chall.c @@ -23,7 +23,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$OpenBSD: auth2-chall.c,v 1.20 2002/06/30 21:59:45 deraadt Exp $"); +RCSID("$OpenBSD: auth2-chall.c,v 1.21 2004/06/01 14:20:45 dtucker Exp $"); #include "ssh2.h" #include "auth.h" @@ -31,7 +31,6 @@ RCSID("$OpenBSD: auth2-chall.c,v 1.20 2002/06/30 21:59:45 deraadt Exp $"); #include "packet.h" #include "xmalloc.h" #include "dispatch.h" -#include "auth.h" #include "log.h" static int auth2_challenge_start(Authctxt *); diff --git a/openssh/auth2-gss.c b/openssh/auth2-gss.c index 9249988..3289ba1 100644 --- a/openssh/auth2-gss.c +++ b/openssh/auth2-gss.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-gss.c,v 1.7 2003/11/21 11:57:03 djm Exp $ */ +/* $OpenBSD: auth2-gss.c,v 1.8 2004/06/21 17:36:31 avsm Exp $ */ /* * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -54,7 +54,7 @@ static void input_gssapi_errtok(int, u_int32_t, void *); static int userauth_gssapi(Authctxt *authctxt) { - gss_OID_desc oid = {0, NULL}; + gss_OID_desc goid = {0, NULL}; Gssctxt *ctxt = NULL; int mechs; gss_OID_set supported; @@ -85,9 +85,9 @@ userauth_gssapi(Authctxt *authctxt) if (len > 2 && doid[0] == SSH_GSS_OIDTYPE && doid[1] == len - 2) { - oid.elements = doid + 2; - oid.length = len - 2; - gss_test_oid_set_member(&ms, &oid, supported, + goid.elements = doid + 2; + goid.length = len - 2; + gss_test_oid_set_member(&ms, &goid, supported, &present); } else { logit("Badly formed OID received"); @@ -101,7 +101,7 @@ userauth_gssapi(Authctxt *authctxt) return (0); } - if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, &oid)))) { + if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, &goid)))) { xfree(doid); return (0); } diff --git a/openssh/auth2-none.c b/openssh/auth2-none.c index c342add..2bf5b5c 100644 --- a/openssh/auth2-none.c +++ b/openssh/auth2-none.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth2-none.c,v 1.6 2003/08/26 09:58:43 markus Exp $"); +RCSID("$OpenBSD: auth2-none.c,v 1.7 2004/05/11 19:01:43 deraadt Exp $"); #include "auth.h" #include "xmalloc.h" @@ -46,7 +46,7 @@ auth2_read_banner(void) { struct stat st; char *banner = NULL; - off_t len, n; + size_t len, n; int fd; if ((fd = open(options.banner, O_RDONLY)) == -1) @@ -55,7 +55,12 @@ auth2_read_banner(void) close(fd); return (NULL); } - len = st.st_size; + if (st.st_size > 1*1024*1024) { + close(fd); + return (NULL); + } + + len = (size_t)st.st_size; /* truncate */ banner = xmalloc(len + 1); n = atomicio(read, fd, banner, len); close(fd); diff --git a/openssh/auth2-pubkey.c b/openssh/auth2-pubkey.c index 3063eec..9898d4a 100644 --- a/openssh/auth2-pubkey.c +++ b/openssh/auth2-pubkey.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth2-pubkey.c,v 1.6 2004/01/19 21:25:15 markus Exp $"); +RCSID("$OpenBSD: auth2-pubkey.c,v 1.7 2004/06/21 17:36:31 avsm Exp $"); #include "ssh2.h" #include "xmalloc.h" @@ -205,7 +205,7 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file) found = key_new(key->type); while (fgets(line, sizeof(line), f)) { - char *cp, *options = NULL; + char *cp, *key_options = NULL; linenum++; /* Skip leading whitespace, empty and comment lines. */ for (cp = line; *cp == ' ' || *cp == '\t'; cp++) @@ -217,7 +217,7 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file) /* no key? check if there are options for this key */ int quoted = 0; debug2("user_key_allowed: check options: '%s'", cp); - options = cp; + key_options = cp; for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) { if (*cp == '\\' && cp[1] == '"') cp++; /* Skip both */ @@ -234,7 +234,7 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file) } } if (key_equal(found, key) && - auth_parse_options(pw, options, file, linenum) == 1) { + auth_parse_options(pw, key_options, file, linenum) == 1) { found_key = 1; debug("matching key found: file %s, line %lu", file, linenum); diff --git a/openssh/auth2.c b/openssh/auth2.c index 1177efa..b983095 100644 --- a/openssh/auth2.c +++ b/openssh/auth2.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth2.c,v 1.104 2003/11/04 08:54:09 djm Exp $"); +RCSID("$OpenBSD: auth2.c,v 1.107 2004/07/28 09:40:29 markus Exp $"); #include "ssh2.h" #include "xmalloc.h" @@ -159,14 +159,14 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) PRIVSEP(start_pam(authctxt)); #endif } else { - logit("input_userauth_request: illegal user %s", user); + logit("input_userauth_request: invalid user %s", user); authctxt->pw = fakepw(); #ifdef USE_PAM if (options.use_pam) PRIVSEP(start_pam(authctxt)); #endif } - setproctitle("%s%s", authctxt->pw ? user : "unknown", + setproctitle("%s%s", authctxt->valid ? user : "unknown", use_privsep ? " [net]" : ""); authctxt->service = xstrdup(service); authctxt->style = style ? xstrdup(style) : NULL; @@ -243,7 +243,7 @@ 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++ > options.max_authtries) packet_disconnect(AUTH_FAIL_MSG, authctxt->user); methods = authmethods_get(); packet_start(SSH2_MSG_USERAUTH_FAILURE); diff --git a/openssh/authfd.c b/openssh/authfd.c index 42ca082..662350c 100644 --- a/openssh/authfd.c +++ b/openssh/authfd.c @@ -35,7 +35,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: authfd.c,v 1.63 2003/11/21 11:57:03 djm Exp $"); +RCSID("$OpenBSD: authfd.c,v 1.64 2004/08/11 21:44:31 avsm Exp $"); #include @@ -133,16 +133,9 @@ ssh_request_reply(AuthenticationConnection *auth, Buffer *request, Buffer *reply * Wait for response from the agent. First read the length of the * response packet. */ - len = 4; - while (len > 0) { - l = read(auth->fd, buf + 4 - len, len); - if (l == -1 && (errno == EAGAIN || errno == EINTR)) - continue; - if (l <= 0) { - error("Error reading response length from authentication socket."); - return 0; - } - len -= l; + if (atomicio(read, auth->fd, buf, 4) != 4) { + error("Error reading response length from authentication socket."); + return 0; } /* Extract the length, and check it for sanity. */ @@ -156,9 +149,7 @@ ssh_request_reply(AuthenticationConnection *auth, Buffer *request, Buffer *reply l = len; if (l > sizeof(buf)) l = sizeof(buf); - l = read(auth->fd, buf, l); - if (l == -1 && (errno == EAGAIN || errno == EINTR)) - continue; + l = atomicio(read, auth->fd, buf, l); if (l <= 0) { error("Error reading response from authentication socket."); return 0; diff --git a/openssh/authfile.c b/openssh/authfile.c index 83ddd63..76a60d0 100644 --- a/openssh/authfile.c +++ b/openssh/authfile.c @@ -36,7 +36,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: authfile.c,v 1.55 2003/09/18 07:56:05 markus Exp $"); +RCSID("$OpenBSD: authfile.c,v 1.57 2004/06/21 17:36:31 avsm Exp $"); #include #include @@ -72,7 +72,7 @@ key_save_private_rsa1(Key *key, const char *filename, const char *passphrase, int fd, i, cipher_num; CipherContext ciphercontext; Cipher *cipher; - u_int32_t rand; + u_int32_t rnd; /* * If the passphrase is empty, use SSH_CIPHER_NONE to ease converting @@ -87,9 +87,9 @@ key_save_private_rsa1(Key *key, const char *filename, const char *passphrase, buffer_init(&buffer); /* Put checkbytes for checking passphrase validity. */ - rand = arc4random(); - buf[0] = rand & 0xff; - buf[1] = (rand >> 8) & 0xff; + rnd = arc4random(); + buf[0] = rnd & 0xff; + buf[1] = (rnd >> 8) & 0xff; buf[2] = buf[0]; buf[3] = buf[1]; buffer_append(&buffer, buf, 4); @@ -236,14 +236,16 @@ key_load_public_rsa1(int fd, const char *filename, char **commentp) struct stat st; char *cp; int i; - off_t len; + size_t len; if (fstat(fd, &st) < 0) { error("fstat for key file %.200s failed: %.100s", filename, strerror(errno)); return NULL; } - len = st.st_size; + if (st.st_size > 1*1024*1024) + close(fd); + len = (size_t)st.st_size; /* truncated */ buffer_init(&buffer); cp = buffer_append_space(&buffer, len); @@ -318,7 +320,7 @@ key_load_private_rsa1(int fd, const char *filename, const char *passphrase, char **commentp) { int i, check1, check2, cipher_type; - off_t len; + size_t len; Buffer buffer, decrypted; u_char *cp; CipherContext ciphercontext; @@ -332,7 +334,11 @@ key_load_private_rsa1(int fd, const char *filename, const char *passphrase, close(fd); return NULL; } - len = st.st_size; + if (st.st_size > 1*1024*1024) { + close(fd); + return (NULL); + } + len = (size_t)st.st_size; /* truncated */ buffer_init(&buffer); cp = buffer_append_space(&buffer, len); diff --git a/openssh/buildpkg.sh.in b/openssh/buildpkg.sh.in new file mode 100644 index 0000000..f243e90 --- /dev/null +++ b/openssh/buildpkg.sh.in @@ -0,0 +1,562 @@ +#!/bin/sh +# +# Fake Root Solaris/SVR4/SVR5 Build System - Prototype +# +# The following code has been provide under Public Domain License. I really +# don't care what you use it for. Just as long as you don't complain to me +# nor my employer if you break it. - Ben Lindstrom (mouring@eviladmin.org) +# +umask 022 +# +# Options for building the package +# You can create a openssh-config.local with your customized options +# +REMOVE_FAKE_ROOT_WHEN_DONE=yes +# +# uncommenting TEST_DIR and using +# configure --prefix=/var/tmp --with-privsep-path=/var/tmp/empty +# and +# PKGNAME=tOpenSSH should allow testing a package without interfering +# with a real OpenSSH package on a system. This is not needed on systems +# that support the -R option to pkgadd. +#TEST_DIR=/var/tmp # leave commented out for production build +PKGNAME=OpenSSH +# revisions within the same version (REV=a) +#REV= +SYSVINIT_NAME=opensshd +MAKE=${MAKE:="make"} +SSHDUID=67 # Default privsep uid +SSHDGID=67 # Default privsep gid +# uncomment these next three as needed +#PERMIT_ROOT_LOGIN=no +#X11_FORWARDING=yes +#USR_LOCAL_IS_SYMLINK=yes +# System V init run levels +SYSVINITSTART=S98 +SYSVINITSTOPT=K30 +# We will source these if they exist +POST_MAKE_INSTALL_FIXES=./pkg_post_make_install_fixes.sh +POST_PROTOTYPE_EDITS=./pkg-post-prototype-edit.sh +# We'll be one level deeper looking for these +PKG_PREINSTALL_LOCAL=../pkg-preinstall.local +PKG_POSTINSTALL_LOCAL=../pkg-postinstall.local +PKG_PREREMOVE_LOCAL=../pkg-preremove.local +PKG_POSTREMOVE_LOCAL=../pkg-postremove.local +PKG_REQUEST_LOCAL=../pkg-request.local +# end of sourced files +# +OPENSSHD=opensshd.init + +PATH_GROUPADD_PROG=@PATH_GROUPADD_PROG@ +PATH_USERADD_PROG=@PATH_USERADD_PROG@ +PATH_PASSWD_PROG=@PATH_PASSWD_PROG@ +# +# list of system directories we do NOT want to change owner/group/perms +# when installing our package +SYSTEM_DIR="/etc \ +/etc/init.d \ +/etc/rcS.d \ +/etc/rc0.d \ +/etc/rc1.d \ +/etc/rc2.d \ +/etc/opt \ +/opt \ +/opt/bin \ +/usr \ +/usr/bin \ +/usr/lib \ +/usr/sbin \ +/usr/share \ +/usr/share/man \ +/usr/share/man/man1 \ +/usr/share/man/man8 \ +/usr/local \ +/usr/local/bin \ +/usr/local/etc \ +/usr/local/libexec \ +/usr/local/man \ +/usr/local/man/man1 \ +/usr/local/man/man8 \ +/usr/local/sbin \ +/usr/local/share \ +/var \ +/var/opt \ +/var/run \ +/var/tmp \ +/tmp" + +# We may need to build as root so we make sure PATH is set up +# only set the path if it's not set already +[ -d /opt/bin ] && { + echo $PATH | grep ":/opt/bin" > /dev/null 2>&1 + [ $? -ne 0 ] && PATH=$PATH:/opt/bin +} +[ -d /usr/local/bin ] && { + echo $PATH | grep ":/usr/local/bin" > /dev/null 2>&1 + [ $? -ne 0 ] && PATH=$PATH:/usr/local/bin +} +[ -d /usr/ccs/bin ] && { + echo $PATH | grep ":/usr/ccs/bin" > /dev/null 2>&1 + [ $? -ne 0 ] && PATH=$PATH:/usr/ccs/bin +} +export PATH +# + +[ -f Makefile ] || { + echo "Please run this script from your build directory" + exit 1 +} + +# we will look for openssh-config.local to override the above options +[ -s ./openssh-config.local ] && . ./openssh-config.local + +START=`pwd` +FAKE_ROOT=$START/pkg + +## Fill in some details, like prefix and sysconfdir +for confvar in prefix exec_prefix bindir sbindir libexecdir datadir mandir sysconfdir piddir srcdir +do + eval $confvar=`grep "^$confvar=" Makefile | cut -d = -f 2` +done + + +## Collect value of privsep user +for confvar in SSH_PRIVSEP_USER +do + eval $confvar=`awk '/#define[ \t]'$confvar'/{print $3}' config.h` +done + +## Set privsep defaults if not defined +if [ -z "$SSH_PRIVSEP_USER" ] +then + SSH_PRIVSEP_USER=sshd +fi + +## Extract common info requires for the 'info' part of the package. +VERSION=`./ssh -V 2>&1 | sed -e 's/,.*//'` + +ARCH=`uname -m` +DEF_MSG="\n" +OS_VER=`uname -v` +SCRIPT_SHELL=/sbin/sh +UNAME_S=`uname -s` +case ${UNAME_S} in + SunOS) UNAME_S=Solaris + ARCH=`uname -p` + RCS_D=yes + DEF_MSG="(default: n)" + ;; + SCO_SV) UNAME_S=OpenServer + OS_VER=`uname -X | grep Release | sed -e 's/^Rel.*3.2v//'` + SCRIPT_SHELL=/bin/sh + RC1_D=no + DEF_MSG="(default: n)" + ;; +esac + +case `basename $0` in + buildpkg.sh) +## Start by faking root install +echo "Faking root install..." +[ -d $FAKE_ROOT ] && rm -fr $FAKE_ROOT +mkdir $FAKE_ROOT +${MAKE} install-nokeys DESTDIR=$FAKE_ROOT +if [ $? -gt 0 ] +then + echo "Fake root install failed, stopping." + exit 1 +fi + +## Setup our run level stuff while we are at it. +mkdir -p $FAKE_ROOT${TEST_DIR}/etc/init.d + +cp ${OPENSSHD} $FAKE_ROOT${TEST_DIR}/etc/init.d/${SYSVINIT_NAME} +chmod 744 $FAKE_ROOT${TEST_DIR}/etc/init.d/${SYSVINIT_NAME} + +[ "${PERMIT_ROOT_LOGIN}" = no ] && \ + perl -p -i -e "s/#PermitRootLogin yes/PermitRootLogin no/" \ + $FAKE_ROOT/${sysconfdir}/sshd_config +[ "${X11_FORWARDING}" = yes ] && \ + perl -p -i -e "s/#X11Forwarding no/X11Forwarding yes/" \ + $FAKE_ROOT/${sysconfdir}/sshd_config +# fix PrintMotd +perl -p -i -e "s/#PrintMotd yes/PrintMotd no/" \ + $FAKE_ROOT/${sysconfdir}/sshd_config + +# We don't want to overwrite config files on multiple installs +mv $FAKE_ROOT/${sysconfdir}/ssh_config $FAKE_ROOT/${sysconfdir}/ssh_config.default +mv $FAKE_ROOT/${sysconfdir}/sshd_config $FAKE_ROOT/${sysconfdir}/sshd_config.default +[ -f $FAKE_ROOT/${sysconfdir}/ssh_prng_cmds ] && \ +mv $FAKE_ROOT/${sysconfdir}/ssh_prng_cmds $FAKE_ROOT/${sysconfdir}/ssh_prng_cmds.default + +# local tweeks here +[ -s "${POST_MAKE_INSTALL_FIXES}" ] && . ${POST_MAKE_INSTALL_FIXES} + +cd $FAKE_ROOT + +## Ok, this is outright wrong, but it will work. I'm tired of pkgmk +## whining. +for i in *; do + PROTO_ARGS="$PROTO_ARGS $i=/$i"; +done + +## Build info file +echo "Building pkginfo file..." +cat > pkginfo << _EOF +PKG=$PKGNAME +NAME="OpenSSH Portable for ${UNAME_S}" +DESC="Secure Shell remote access utility; replaces telnet and rlogin/rsh." +VENDOR="OpenSSH Portable Team - http://www.openssh.com/portable.html" +ARCH=$ARCH +VERSION=$VERSION$REV +CATEGORY="Security,application" +BASEDIR=/ +CLASSES="none" +PSTAMP="${UNAME_S} ${OS_VER} ${ARCH} `date '+%d%b%Y %H:%M'`" +_EOF + +## Build empty depend file that may get updated by $POST_PROTOTYPE_EDITS +echo "Building depend file..." +touch depend + +## Build space file +echo "Building space file..." +cat > space << _EOF +# extra space required by start/stop links added by installf in postinstall +$TEST_DIR/etc/rc0.d/${SYSVINITSTOPT}${SYSVINIT_NAME} 0 1 +$TEST_DIR/etc/rc2.d/${SYSVINITSTART}${SYSVINIT_NAME} 0 1 +_EOF +[ "$RC1_D" = no ] || \ +echo "$TEST_DIR/etc/rc1.d/${SYSVINITSTOPT}${SYSVINIT_NAME} 0 1" >> space +[ "$RCS_D" = yes ] && \ +echo "$TEST_DIR/etc/rcS.d/${SYSVINITSTOPT}${SYSVINIT_NAME} 0 1" >> space + +## Build preinstall file +echo "Building preinstall file..." +cat > preinstall << _EOF +#! ${SCRIPT_SHELL} +# +_EOF + +# local preinstall changes here +[ -s "${PKG_PREINSTALL_LOCAL}" ] && . ${PKG_PREINSTALL_LOCAL} + +cat >> preinstall << _EOF +# +[ "\${PRE_INS_STOP}" = "yes" ] && ${TEST_DIR}/etc/init.d/${SYSVINIT_NAME} stop +exit 0 +_EOF + +## Build postinstall file +echo "Building postinstall file..." +cat > postinstall << _EOF +#! ${SCRIPT_SHELL} +# +[ -f \${PKG_INSTALL_ROOT}${sysconfdir}/ssh_config ] || \\ + cp -p \${PKG_INSTALL_ROOT}${sysconfdir}/ssh_config.default \\ + \${PKG_INSTALL_ROOT}${sysconfdir}/ssh_config +[ -f \${PKG_INSTALL_ROOT}${sysconfdir}/sshd_config ] || \\ + cp -p \${PKG_INSTALL_ROOT}${sysconfdir}/sshd_config.default \\ + \${PKG_INSTALL_ROOT}${sysconfdir}/sshd_config +[ -f \${PKG_INSTALL_ROOT}${sysconfdir}/ssh_prng_cmds.default ] && { + [ -f \${PKG_INSTALL_ROOT}${sysconfdir}/ssh_prng_cmds ] || \\ + cp -p \${PKG_INSTALL_ROOT}${sysconfdir}/ssh_prng_cmds.default \\ + \${PKG_INSTALL_ROOT}${sysconfdir}/ssh_prng_cmds +} + +# make rc?.d dirs only if we are doing a test install +[ -n "${TEST_DIR}" ] && { + [ "$RCS_D" = yes ] && mkdir -p ${TEST_DIR}/etc/rcS.d + mkdir -p ${TEST_DIR}/etc/rc0.d + [ "$RC1_D" = no ] || mkdir -p ${TEST_DIR}/etc/rc1.d + mkdir -p ${TEST_DIR}/etc/rc2.d +} + +if [ "\${USE_SYM_LINKS}" = yes ] +then + [ "$RCS_D" = yes ] && \ +installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rcS.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc0.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s + [ "$RC1_D" = no ] || \ + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc1.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc2.d/${SYSVINITSTART}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s +else + [ "$RCS_D" = yes ] && \ +installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rcS.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc0.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l + [ "$RC1_D" = no ] || \ + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc1.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc2.d/${SYSVINITSTART}${SYSVINIT_NAME}=$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l +fi + +# If piddir doesn't exist we add it. (Ie. --with-pid-dir=/var/opt/ssh) +[ -d $piddir ] || installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR$piddir d 0755 root sys + +_EOF + +# local postinstall changes here +[ -s "${PKG_POSTINSTALL_LOCAL}" ] && . ${PKG_POSTINSTALL_LOCAL} + +cat >> postinstall << _EOF +installf -f ${PKGNAME} + +# Use chroot to handle PKG_INSTALL_ROOT +if [ ! -z "\${PKG_INSTALL_ROOT}" ] +then + chroot="chroot \${PKG_INSTALL_ROOT}" +fi +# If this is a test build, we will skip the groupadd/useradd/passwd commands +if [ ! -z "${TEST_DIR}" ] +then + chroot=echo +fi + +if egrep '^[ \t]*UsePrivilegeSeparation[ \t]+no' \${PKG_INSTALL_ROOT}/$sysconfdir/sshd_config >/dev/null +then + echo "UsePrivilegeSeparation disabled in config, not creating PrivSep user" + echo "or group." +else + echo "UsePrivilegeSeparation enabled in config (or defaulting to on)." + + # user required? + if cut -f1 -d: \${PKG_INSTALL_ROOT}/etc/passwd | egrep '^'$SSH_PRIVSEP_USER'\$' >/dev/null + then + echo "PrivSep user $SSH_PRIVSEP_USER already exists." + SSH_PRIVSEP_GROUP=\`grep "^$SSH_PRIVSEP_USER:" \${PKG_INSTALL_ROOT}/etc/passwd | awk -F: '{print \$4}'\` + SSH_PRIVSEP_GROUP=\`grep ":\$SSH_PRIVSEP_GROUP:" \${PKG_INSTALL_ROOT}/etc/group | awk -F: '{print \$1}'\` + else + DO_PASSWD=yes + fi + [ -z "\$SSH_PRIVSEP_GROUP" ] && SSH_PRIVSEP_GROUP=$SSH_PRIVSEP_USER + + # group required? + if cut -f1 -d: \${PKG_INSTALL_ROOT}/etc/group | egrep '^'\$SSH_PRIVSEP_GROUP'\$' >/dev/null + then + echo "PrivSep group \$SSH_PRIVSEP_GROUP already exists." + else + DO_GROUP=yes + fi + + # create group if required + [ "\$DO_GROUP" = yes ] && { + # Use gid of 67 if possible + if cut -f3 -d: \${PKG_INSTALL_ROOT}/etc/group | egrep '^'$SSHDGID'\$' >/dev/null + then + : + else + sshdgid="-g $SSHDGID" + fi + echo "Creating PrivSep group \$SSH_PRIVSEP_GROUP." + \$chroot ${PATH_GROUPADD_PROG} \$sshdgid \$SSH_PRIVSEP_GROUP + } + + # Create user if required + [ "\$DO_PASSWD" = yes ] && { + # Use uid of 67 if possible + if cut -f3 -d: \${PKG_INSTALL_ROOT}/etc/passwd | egrep '^'$SSHDGID'\$' >/dev/null + then + : + else + sshduid="-u $SSHDUID" + fi + echo "Creating PrivSep user $SSH_PRIVSEP_USER." + \$chroot ${PATH_USERADD_PROG} -c 'SSHD PrivSep User' -s /bin/false -g $SSH_PRIVSEP_USER \$sshduid $SSH_PRIVSEP_USER + \$chroot ${PATH_PASSWD_PROG} -l $SSH_PRIVSEP_USER + } +fi + +[ "\${POST_INS_START}" = "yes" ] && ${TEST_DIR}/etc/init.d/${SYSVINIT_NAME} start +exit 0 +_EOF + +## Build preremove file +echo "Building preremove file..." +cat > preremove << _EOF +#! ${SCRIPT_SHELL} +# +${TEST_DIR}/etc/init.d/${SYSVINIT_NAME} stop +_EOF + +# local preremove changes here +[ -s "${PKG_PREREMOVE_LOCAL}" ] && . ${PKG_PREREMOVE_LOCAL} + +cat >> preremove << _EOF +exit 0 +_EOF + +## Build postremove file +echo "Building postremove file..." +cat > postremove << _EOF +#! ${SCRIPT_SHELL} +# +_EOF + +# local postremove changes here +[ -s "${PKG_POSTREMOVE_LOCAL}" ] && . ${PKG_POSTREMOVE_LOCAL} + +cat >> postremove << _EOF +exit 0 +_EOF + +## Build request file +echo "Building request file..." +cat > request << _EOF +trap 'exit 3' 15 + +_EOF + +[ -x /usr/bin/ckyorn ] || cat >> request << _EOF + +ckyorn() { +# for some strange reason OpenServer has no ckyorn +# We build a striped down version here + +DEFAULT=n +PROMPT="Yes or No [yes,no,?,quit]" +HELP_PROMPT=" Enter y or yes if your answer is yes; n or no if your answer is no." +USAGE="usage: ckyorn [options] +where options may include: + -d default + -h help + -p prompt +" + +if [ \$# != 0 ] +then + while getopts d:p:h: c + do + case \$c in + h) HELP_PROMPT="\$OPTARG" ;; + d) DEFAULT=\$OPTARG ;; + p) PROMPT=\$OPTARG ;; + \\?) echo "\$USAGE" 1>&2 + exit 1 ;; + esac + done + shift \`expr \$OPTIND - 1\` +fi + +while true +do + echo "\${PROMPT}\\c " 1>&2 + read key + [ -z "\$key" ] && key=\$DEFAULT + case \$key in + [n,N]|[n,N][o,O]|[y,Y]|[y,Y][e,E][s,S]) echo "\${key}\\c" + exit 0 ;; + \\?) echo \$HELP_PROMPT 1>&2 ;; + q|quit) echo "q\\c" 1>&2 + exit 3 ;; + esac +done + +} + +_EOF + +cat >> request << _EOF +USE_SYM_LINKS=no +PRE_INS_STOP=no +POST_INS_START=no +# Use symbolic links? +ans=\`ckyorn -d n \ +-p "Do you want symbolic links for the start/stop scripts? ${DEF_MSG}"\` || exit \$? +case \$ans in + [y,Y]*) USE_SYM_LINKS=yes ;; +esac + +# determine if should restart the daemon +if [ -s ${piddir}/sshd.pid -a -f ${TEST_DIR}/etc/init.d/${SYSVINIT_NAME} ] +then + ans=\`ckyorn -d n \ +-p "Should the running sshd daemon be restarted? ${DEF_MSG}"\` || exit \$? + case \$ans in + [y,Y]*) PRE_INS_STOP=yes + POST_INS_START=yes + ;; + esac + +else + +# determine if we should start sshd + ans=\`ckyorn -d n \ +-p "Start the sshd daemon after installing this package? ${DEF_MSG}"\` || exit \$? + case \$ans in + [y,Y]*) POST_INS_START=yes ;; + esac +fi + +# make parameters available to installation service, +# and so to any other packaging scripts +cat >\$1 <> request << _EOF +exit 0 + +_EOF + +## Next Build our prototype +echo "Building prototype file..." +cat >mk-proto.awk << _EOF + BEGIN { print "i pkginfo"; print "i depend"; \\ + print "i preinstall"; print "i postinstall"; \\ + print "i preremove"; print "i postremove"; \\ + print "i request"; print "i space"; \\ + split("$SYSTEM_DIR",sys_files); } + { + for (dir in sys_files) { if ( \$3 != sys_files[dir] ) + { if ( \$1 == "s" ) + { \$5=""; \$6=""; } + else + { \$5="root"; \$6="sys"; } + } + else + { \$4="?"; \$5="?"; \$6="?"; break;} + } } + { print; } +_EOF + +find . | egrep -v "prototype|pkginfo|mk-proto.awk" | sort | \ + pkgproto $PROTO_ARGS | nawk -f mk-proto.awk > prototype + +# /usr/local is a symlink on some systems +[ "${USR_LOCAL_IS_SYMLINK}" = yes ] && { + grep -v "^d none /usr/local ? ? ?$" prototype > prototype.new + mv prototype.new prototype +} + +## Step back a directory and now build the package. +cd .. +# local prototype tweeks here +[ -s "${POST_PROTOTYPE_EDITS}" ] && . ${POST_PROTOTYPE_EDITS} + +echo "Building package.." +pkgmk -d ${FAKE_ROOT} -f $FAKE_ROOT/prototype -o +echo | pkgtrans -os ${FAKE_ROOT} ${START}/$PKGNAME-$VERSION$REV-$UNAME_S-$ARCH.pkg + ;; + + justpkg.sh) +rm -fr ${FAKE_ROOT}/${PKGNAME} +grep -v "^PSTAMP=" $FAKE_ROOT/pkginfo > $$tmp +mv $$tmp $FAKE_ROOT/pkginfo +cat >> $FAKE_ROOT/pkginfo << _EOF +PSTAMP="${UNAME_S} ${OS_VER} ${ARCH} `date '+%d%b%Y %H:%M'`" +_EOF +pkgmk -d ${FAKE_ROOT} -f $FAKE_ROOT/prototype -o +echo | pkgtrans -os ${FAKE_ROOT} ${START}/$PKGNAME-$VERSION$REV-$UNAME_S-$ARCH.pkg + ;; + +esac + +[ "${REMOVE_FAKE_ROOT_WHEN_DONE}" = yes ] && rm -rf $FAKE_ROOT +exit 0 + diff --git a/openssh/canohost.c b/openssh/canohost.c index a0067af..8ad684d 100644 --- a/openssh/canohost.c +++ b/openssh/canohost.c @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: canohost.c,v 1.38 2003/09/23 20:17:11 markus Exp $"); +RCSID("$OpenBSD: canohost.c,v 1.41 2004/07/21 11:51:29 djm Exp $"); #include "packet.h" #include "xmalloc.h" @@ -28,7 +28,7 @@ static void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); */ static char * -get_remote_hostname(int socket, int use_dns) +get_remote_hostname(int sock, int use_dns) { struct sockaddr_storage from; int i; @@ -39,13 +39,13 @@ get_remote_hostname(int socket, int use_dns) /* Get IP address of client. */ fromlen = sizeof(from); memset(&from, 0, sizeof(from)); - if (getpeername(socket, (struct sockaddr *)&from, &fromlen) < 0) { + if (getpeername(sock, (struct sockaddr *)&from, &fromlen) < 0) { debug("getpeername failed: %.100s", strerror(errno)); cleanup_exit(255); } if (from.ss_family == AF_INET) - check_ip_options(socket, ntop); + check_ip_options(sock, ntop); ipv64_normalise_mapped(&from, &fromlen); @@ -138,7 +138,7 @@ get_remote_hostname(int socket, int use_dns) */ /* IPv4 only */ static void -check_ip_options(int socket, char *ipaddr) +check_ip_options(int sock, char *ipaddr) { #ifdef IP_OPTIONS u_char options[200]; @@ -152,7 +152,7 @@ check_ip_options(int socket, char *ipaddr) else ipproto = IPPROTO_IP; option_size = sizeof(options); - if (getsockopt(socket, ipproto, IP_OPTIONS, options, + if (getsockopt(sock, ipproto, IP_OPTIONS, options, &option_size) >= 0 && option_size != 0) { text[0] = '\0'; for (i = 0; i < option_size; i++) @@ -227,7 +227,7 @@ get_canonical_hostname(int use_dns) * The returned string must be freed. */ static char * -get_socket_address(int socket, int remote, int flags) +get_socket_address(int sock, int remote, int flags) { struct sockaddr_storage addr; socklen_t addrlen; @@ -238,11 +238,11 @@ get_socket_address(int socket, int remote, int flags) memset(&addr, 0, sizeof(addr)); if (remote) { - if (getpeername(socket, (struct sockaddr *)&addr, &addrlen) + if (getpeername(sock, (struct sockaddr *)&addr, &addrlen) < 0) return NULL; } else { - if (getsockname(socket, (struct sockaddr *)&addr, &addrlen) + if (getsockname(sock, (struct sockaddr *)&addr, &addrlen) < 0) return NULL; } @@ -261,29 +261,29 @@ get_socket_address(int socket, int remote, int flags) } char * -get_peer_ipaddr(int socket) +get_peer_ipaddr(int sock) { char *p; - if ((p = get_socket_address(socket, 1, NI_NUMERICHOST)) != NULL) + if ((p = get_socket_address(sock, 1, NI_NUMERICHOST)) != NULL) return p; return xstrdup("UNKNOWN"); } char * -get_local_ipaddr(int socket) +get_local_ipaddr(int sock) { char *p; - if ((p = get_socket_address(socket, 0, NI_NUMERICHOST)) != NULL) + if ((p = get_socket_address(sock, 0, NI_NUMERICHOST)) != NULL) return p; return xstrdup("UNKNOWN"); } char * -get_local_name(int socket) +get_local_name(int sock) { - return get_socket_address(socket, 0, NI_NAMEREQD); + return get_socket_address(sock, 0, NI_NAMEREQD); } /* @@ -382,7 +382,13 @@ get_peer_port(int sock) int get_remote_port(void) { - return get_port(0); + static int port = -1; + + /* Cache to avoid getpeername() on a dead connection */ + if (port == -1) + port = get_port(0); + + return port; } int diff --git a/openssh/channels.c b/openssh/channels.c index e663c21..1f6984a 100644 --- a/openssh/channels.c +++ b/openssh/channels.c @@ -39,7 +39,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: channels.c,v 1.200 2004/01/19 09:24:21 markus Exp $"); +RCSID("$OpenBSD: channels.c,v 1.209 2004/08/11 21:43:04 avsm Exp $"); #include "ssh.h" #include "ssh1.h" @@ -68,7 +68,7 @@ static Channel **channels = NULL; * Size of the channel array. All slots of the array must always be * initialized (at least the type field); unused slots set to NULL */ -static int channels_alloc = 0; +static u_int channels_alloc = 0; /* * Maximum file descriptor value used in any of the channels. This is @@ -141,7 +141,7 @@ channel_lookup(int id) { Channel *c; - if (id < 0 || id >= channels_alloc) { + if (id < 0 || (u_int)id >= channels_alloc) { logit("channel_lookup: %d: bad id", id); return NULL; } @@ -172,6 +172,7 @@ channel_register_fds(Channel *c, int rfd, int wfd, int efd, c->rfd = rfd; c->wfd = wfd; c->sock = (rfd == wfd) ? rfd : -1; + c->ctl_fd = -1; /* XXX: set elsewhere */ c->efd = efd; c->extended_usage = extusage; @@ -208,7 +209,8 @@ Channel * channel_new(char *ctype, int type, int rfd, int wfd, int efd, u_int window, u_int maxpack, int extusage, char *remote_name, int nonblock) { - int i, found; + int found; + u_int i; Channel *c; /* Do initial allocation if this is the first call. */ @@ -222,10 +224,10 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd, for (found = -1, i = 0; i < channels_alloc; i++) if (channels[i] == NULL) { /* Found a free slot. */ - found = i; + found = (int)i; break; } - if (found == -1) { + if (found < 0) { /* There are no free slots. Take last+1 slot and expand the array. */ found = channels_alloc; if (channels_alloc > 10000) @@ -263,6 +265,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd, c->single_connection = 0; c->detach_user = NULL; c->confirm = NULL; + c->confirm_ctx = NULL; c->input_filter = NULL; debug("channel %d: new [%s]", found, remote_name); return c; @@ -271,7 +274,8 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd, static int channel_find_maxfd(void) { - int i, max = 0; + u_int i; + int max = 0; Channel *c; for (i = 0; i < channels_alloc; i++) { @@ -304,10 +308,11 @@ channel_close_fd(int *fdp) static void channel_close_fds(Channel *c) { - debug3("channel %d: close_fds r %d w %d e %d", - c->self, c->rfd, c->wfd, c->efd); + debug3("channel %d: close_fds r %d w %d e %d c %d", + c->self, c->rfd, c->wfd, c->efd, c->ctl_fd); channel_close_fd(&c->sock); + channel_close_fd(&c->ctl_fd); channel_close_fd(&c->rfd); channel_close_fd(&c->wfd); channel_close_fd(&c->efd); @@ -319,12 +324,12 @@ void channel_free(Channel *c) { char *s; - int i, n; + u_int i, n; for (n = 0, i = 0; i < channels_alloc; i++) if (channels[i]) n++; - debug("channel %d: free: %s, nchannels %d", c->self, + debug("channel %d: free: %s, nchannels %u", c->self, c->remote_name ? c->remote_name : "???", n); s = channel_open_message(); @@ -333,6 +338,8 @@ channel_free(Channel *c) if (c->sock != -1) shutdown(c->sock, SHUT_RDWR); + if (c->ctl_fd != -1) + shutdown(c->ctl_fd, SHUT_RDWR); channel_close_fds(c); buffer_free(&c->input); buffer_free(&c->output); @@ -348,7 +355,7 @@ channel_free(Channel *c) void channel_free_all(void) { - int i; + u_int i; for (i = 0; i < channels_alloc; i++) if (channels[i] != NULL) @@ -363,7 +370,7 @@ channel_free_all(void) void channel_close_all(void) { - int i; + u_int i; for (i = 0; i < channels_alloc; i++) if (channels[i] != NULL) @@ -377,7 +384,7 @@ channel_close_all(void) void channel_stop_listening(void) { - int i; + u_int i; Channel *c; for (i = 0; i < channels_alloc; i++) { @@ -434,7 +441,7 @@ channel_not_very_much_buffered_data(void) int channel_still_open(void) { - int i; + u_int i; Channel *c; for (i = 0; i < channels_alloc; i++) { @@ -477,12 +484,12 @@ channel_still_open(void) int channel_find_open(void) { - int i; + u_int i; Channel *c; for (i = 0; i < channels_alloc; i++) { c = channels[i]; - if (c == NULL) + if (c == NULL || c->remote_id < 0) continue; switch (c->type) { case SSH_CHANNEL_CLOSED: @@ -525,7 +532,7 @@ channel_open_message(void) Buffer buffer; Channel *c; char buf[1024], *cp; - int i; + u_int i; buffer_init(&buffer); snprintf(buf, sizeof buf, "The following connections are open:\r\n"); @@ -550,12 +557,13 @@ channel_open_message(void) case SSH_CHANNEL_X11_OPEN: case SSH_CHANNEL_INPUT_DRAINING: case SSH_CHANNEL_OUTPUT_DRAINING: - snprintf(buf, sizeof buf, " #%d %.300s (t%d r%d i%d/%d o%d/%d fd %d/%d)\r\n", + snprintf(buf, sizeof buf, + " #%d %.300s (t%d r%d i%d/%d o%d/%d fd %d/%d cfd %d)\r\n", c->self, c->remote_name, c->type, c->remote_id, c->istate, buffer_len(&c->input), c->ostate, buffer_len(&c->output), - c->rfd, c->wfd); + c->rfd, c->wfd, c->ctl_fd); buffer_append(&buffer, buf, strlen(buf)); continue; default: @@ -596,14 +604,14 @@ channel_request_start(int id, char *service, int wantconfirm) logit("channel_request_start: %d: unknown channel id", id); return; } - debug2("channel %d: request %s", id, service) ; + debug2("channel %d: request %s confirm %d", id, service, wantconfirm); packet_start(SSH2_MSG_CHANNEL_REQUEST); packet_put_int(c->remote_id); packet_put_cstring(service); packet_put_char(wantconfirm); } void -channel_register_confirm(int id, channel_callback_fn *fn) +channel_register_confirm(int id, channel_callback_fn *fn, void *ctx) { Channel *c = channel_lookup(id); @@ -612,6 +620,7 @@ channel_register_confirm(int id, channel_callback_fn *fn) return; } c->confirm = fn; + c->confirm_ctx = ctx; } void channel_register_cleanup(int id, channel_callback_fn *fn) @@ -729,6 +738,10 @@ channel_pre_open(Channel *c, fd_set * readset, fd_set * writeset) buffer_len(&c->extended) < c->remote_window) FD_SET(c->efd, readset); } + /* XXX: What about efd? races? */ + if (compat20 && c->ctl_fd != -1 && + c->istate == CHAN_INPUT_OPEN && c->ostate == CHAN_OUTPUT_OPEN) + FD_SET(c->ctl_fd, readset); } static void @@ -1031,7 +1044,7 @@ channel_decode_socks5(Channel *c, fd_set * readset, fd_set * writeset) buffer_get(&c->input, (char *)&dest_port, 2); dest_addr[addrlen] = '\0'; if (s5_req.atyp == SSH_SOCKS5_DOMAIN) - strlcpy(c->path, dest_addr, sizeof(c->path)); + strlcpy(c->path, (char *)dest_addr, sizeof(c->path)); else if (inet_ntop(af, dest_addr, c->path, sizeof(c->path)) == NULL) return -1; c->host_port = ntohs(dest_port); @@ -1482,6 +1495,33 @@ channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset) return 1; } static int +channel_handle_ctl(Channel *c, fd_set * readset, fd_set * writeset) +{ + char buf[16]; + int len; + + /* Monitor control fd to detect if the slave client exits */ + if (c->ctl_fd != -1 && FD_ISSET(c->ctl_fd, readset)) { + len = read(c->ctl_fd, buf, sizeof(buf)); + if (len < 0 && (errno == EINTR || errno == EAGAIN)) + return 1; + if (len <= 0) { + debug2("channel %d: ctl read<=0", c->self); + if (c->type != SSH_CHANNEL_OPEN) { + debug2("channel %d: not open", c->self); + chan_mark_dead(c); + return -1; + } else { + chan_read_failed(c); + chan_write_failed(c); + } + return -1; + } else + fatal("%s: unexpected data on ctl fd", __func__); + } + return 1; +} +static int channel_check_window(Channel *c) { if (c->type == SSH_CHANNEL_OPEN && @@ -1511,6 +1551,7 @@ channel_post_open(Channel *c, fd_set * readset, fd_set * writeset) if (!compat20) return; channel_handle_efd(c, readset, writeset); + channel_handle_ctl(c, readset, writeset); channel_check_window(c); } @@ -1635,7 +1676,7 @@ static void channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset) { static int did_init = 0; - int i; + u_int i; Channel *c; if (!did_init) { @@ -1658,10 +1699,9 @@ channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset) */ void channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp, - int *nallocp, int rekeying) + u_int *nallocp, int rekeying) { - int n; - u_int sz; + u_int n, sz; n = MAX(*maxfdp, channel_max_fd); @@ -1697,8 +1737,7 @@ void channel_output_poll(void) { Channel *c; - int i; - u_int len; + u_int i, len; for (i = 0; i < channels_alloc; i++) { c = channels[i]; @@ -2011,7 +2050,7 @@ channel_input_open_confirmation(int type, u_int32_t seq, void *ctxt) c->remote_maxpacket = packet_get_int(); if (c->confirm) { debug2("callback start"); - c->confirm(c->self, NULL); + c->confirm(c->self, c->confirm_ctx); debug2("callback done"); } debug2("channel %d: open confirm rwindow %u rmax %u", c->self, @@ -2228,6 +2267,27 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por return success; } +int +channel_cancel_rport_listener(const char *host, u_short port) +{ + u_int i; + int found = 0; + + for(i = 0; i < channels_alloc; i++) { + Channel *c = channels[i]; + + if (c != NULL && c->type == SSH_CHANNEL_RPORT_LISTENER && + strncmp(c->path, host, sizeof(c->path)) == 0 && + c->listening_port == port) { + debug2("%s: close clannel %d", __func__, i); + channel_free(c); + found = 1; + } + } + + return (found); +} + /* protocol local port fwd, used by ssh (and sshd in v1) */ int channel_setup_local_fwd_listener(u_short listen_port, @@ -2304,6 +2364,41 @@ channel_request_remote_forwarding(u_short listen_port, } } +/* + * Request cancellation of remote forwarding of connection host:port from + * local side. + */ +void +channel_request_rforward_cancel(u_short port) +{ + int i; + const char *address_to_bind = "0.0.0.0"; + + if (!compat20) + return; + + for (i = 0; i < num_permitted_opens; i++) { + if (permitted_opens[i].host_to_connect != NULL && + permitted_opens[i].listen_port == port) + break; + } + if (i >= num_permitted_opens) { + debug("%s: requested forward not found", __func__); + return; + } + packet_start(SSH2_MSG_GLOBAL_REQUEST); + packet_put_cstring("cancel-tcpip-forward"); + packet_put_char(0); + packet_put_cstring(address_to_bind); + packet_put_int(port); + packet_send(); + + permitted_opens[i].listen_port = 0; + permitted_opens[i].port_to_connect = 0; + free(permitted_opens[i].host_to_connect); + permitted_opens[i].host_to_connect = NULL; +} + /* * This is called after receiving CHANNEL_FORWARDING_REQUEST. This initates * listening for the port, and sends back a success reply (or disconnect @@ -2373,7 +2468,8 @@ channel_clear_permitted_opens(void) int i; for (i = 0; i < num_permitted_opens; i++) - xfree(permitted_opens[i].host_to_connect); + if (permitted_opens[i].host_to_connect != NULL) + xfree(permitted_opens[i].host_to_connect); num_permitted_opens = 0; } @@ -2413,8 +2509,8 @@ connect_to(const char *host, u_short port) verbose("socket: %.100s", strerror(errno)); continue; } - if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) - fatal("connect_to: F_SETFL: %s", strerror(errno)); + if (set_nonblock(sock) == -1) + fatal("%s: set_nonblock(%d)", __func__, sock); if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0 && errno != EINPROGRESS) { error("connect_to %.100s port %s: %.100s", ntop, strport, @@ -2441,7 +2537,8 @@ channel_connect_by_listen_address(u_short listen_port) int i; for (i = 0; i < num_permitted_opens; i++) - if (permitted_opens[i].listen_port == listen_port) + if (permitted_opens[i].host_to_connect != NULL && + permitted_opens[i].listen_port == listen_port) return connect_to( permitted_opens[i].host_to_connect, permitted_opens[i].port_to_connect); @@ -2459,7 +2556,8 @@ channel_connect_to(const char *host, u_short port) permit = all_opens_permitted; if (!permit) { for (i = 0; i < num_permitted_opens; i++) - if (permitted_opens[i].port_to_connect == port && + if (permitted_opens[i].host_to_connect != NULL && + permitted_opens[i].port_to_connect == port && strcmp(permitted_opens[i].host_to_connect, host) == 0) permit = 1; @@ -2472,6 +2570,27 @@ channel_connect_to(const char *host, u_short port) return connect_to(host, port); } +void +channel_send_window_changes(void) +{ + u_int i; + struct winsize ws; + + for (i = 0; i < channels_alloc; i++) { + if (channels[i] == NULL || + channels[i]->type != SSH_CHANNEL_OPEN) + continue; + if (ioctl(channels[i]->rfd, TIOCGWINSZ, &ws) < 0) + continue; + channel_request_start(i, "window-change", 0); + packet_put_int(ws.ws_col); + packet_put_int(ws.ws_row); + packet_put_int(ws.ws_xpixel); + packet_put_int(ws.ws_ypixel); + packet_send(); + } +} + /* -- X11 forwarding */ /* @@ -2511,6 +2630,7 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost, if (sock < 0) { if ((errno != EINVAL) && (errno != EAFNOSUPPORT)) { error("socket: %.100s", strerror(errno)); + freeaddrinfo(aitop); return -1; } else { debug("x11_create_display_inet: Socket family %d not supported", @@ -2783,7 +2903,7 @@ x11_request_forwarding_with_spoofing(int client_session_id, char *new_data; int screen_number; const char *cp; - u_int32_t rand = 0; + u_int32_t rnd = 0; cp = getenv("DISPLAY"); if (cp) @@ -2808,10 +2928,10 @@ x11_request_forwarding_with_spoofing(int client_session_id, if (sscanf(data + 2 * i, "%2x", &value) != 1) fatal("x11_request_forwarding: bad authentication data: %.100s", data); if (i % 4 == 0) - rand = arc4random(); + rnd = arc4random(); x11_saved_data[i] = value; - x11_fake_data[i] = rand & 0xff; - rand >>= 8; + x11_fake_data[i] = rnd & 0xff; + rnd >>= 8; } x11_saved_data_len = data_len; x11_fake_data_len = data_len; diff --git a/openssh/channels.h b/openssh/channels.h index 7d98147..f8dc824 100644 --- a/openssh/channels.h +++ b/openssh/channels.h @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.h,v 1.71 2003/09/23 20:41:11 markus Exp $ */ +/* $OpenBSD: channels.h,v 1.74 2004/08/11 21:43:04 avsm Exp $ */ /* * Author: Tatu Ylonen @@ -76,6 +76,7 @@ struct Channel { int wfd; /* write fd */ int efd; /* extended fd */ int sock; /* sock fd */ + int ctl_fd; /* control fd (client sharing) */ int isatty; /* rfd is a tty */ int wfd_isatty; /* wfd is a tty */ int force_drain; /* force close on iEOF */ @@ -105,6 +106,7 @@ struct Channel { /* callback */ channel_callback_fn *confirm; channel_callback_fn *detach_user; + void *confirm_ctx; /* filter */ channel_filter_fn *input_filter; @@ -161,10 +163,11 @@ void channel_stop_listening(void); void channel_send_open(int); void channel_request_start(int, char *, int); void channel_register_cleanup(int, channel_callback_fn *); -void channel_register_confirm(int, channel_callback_fn *); +void channel_register_confirm(int, channel_callback_fn *, void *); void channel_register_filter(int, channel_filter_fn *); void channel_cancel_cleanup(int); int channel_close_fd(int *); +void channel_send_window_changes(void); /* protocol handler */ @@ -181,7 +184,7 @@ void channel_input_window_adjust(int, u_int32_t, void *); /* file descriptor handling (read/write) */ -void channel_prepare_select(fd_set **, fd_set **, int *, int*, int); +void channel_prepare_select(fd_set **, fd_set **, int *, u_int*, int); void channel_after_select(fd_set *, fd_set *); void channel_output_poll(void); @@ -200,8 +203,10 @@ void channel_input_port_forward_request(int, int); int channel_connect_to(const char *, u_short); int channel_connect_by_listen_address(u_short); void channel_request_remote_forwarding(u_short, const char *, u_short); +void channel_request_rforward_cancel(u_short port); int channel_setup_local_fwd_listener(u_short, const char *, u_short, int); int channel_setup_remote_fwd_listener(const char *, u_short, int); +int channel_cancel_rport_listener(const char *, u_short); /* x11 forwarding */ diff --git a/openssh/cipher.c b/openssh/cipher.c index c13ff58..075a4c5 100644 --- a/openssh/cipher.c +++ b/openssh/cipher.c @@ -35,7 +35,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: cipher.c,v 1.68 2004/01/23 19:26:33 hshoexer Exp $"); +RCSID("$OpenBSD: cipher.c,v 1.71 2004/07/28 09:40:29 markus Exp $"); #include "xmalloc.h" #include "log.h" @@ -76,19 +76,19 @@ struct Cipher { u_int key_len; const EVP_CIPHER *(*evptype)(void); } ciphers[] = { - { "none", SSH_CIPHER_NONE, 8, 0, EVP_enc_null }, - { "des", SSH_CIPHER_DES, 8, 8, EVP_des_cbc }, - { "3des", SSH_CIPHER_3DES, 8, 16, evp_ssh1_3des }, - { "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, evp_ssh1_bf }, - - { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, EVP_des_ede3_cbc }, - { "blowfish-cbc", SSH_CIPHER_SSH2, 8, 16, EVP_bf_cbc }, - { "cast128-cbc", SSH_CIPHER_SSH2, 8, 16, EVP_cast5_cbc }, - { "arcfour", SSH_CIPHER_SSH2, 8, 16, EVP_rc4 }, + { "none", SSH_CIPHER_NONE, 8, 0, EVP_enc_null }, + { "des", SSH_CIPHER_DES, 8, 8, EVP_des_cbc }, + { "3des", SSH_CIPHER_3DES, 8, 16, evp_ssh1_3des }, + { "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, evp_ssh1_bf }, + + { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, EVP_des_ede3_cbc }, + { "blowfish-cbc", SSH_CIPHER_SSH2, 8, 16, EVP_bf_cbc }, + { "cast128-cbc", SSH_CIPHER_SSH2, 8, 16, EVP_cast5_cbc }, + { "arcfour", SSH_CIPHER_SSH2, 8, 16, EVP_rc4 }, #if OPENSSL_VERSION_NUMBER < 0x00907000L - { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, evp_rijndael }, - { "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, evp_rijndael }, - { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, evp_rijndael }, + { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, evp_rijndael }, + { "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, evp_rijndael }, + { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, evp_rijndael }, { "rijndael-cbc@lysator.liu.se", SSH_CIPHER_SSH2, 16, 32, evp_rijndael }, #else @@ -99,14 +99,14 @@ struct Cipher { SSH_CIPHER_SSH2, 16, 32, EVP_aes_256_cbc }, #endif #if OPENSSL_VERSION_NUMBER >= 0x00905000L - { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, evp_aes_128_ctr }, - { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, evp_aes_128_ctr }, - { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, evp_aes_128_ctr }, + { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, evp_aes_128_ctr }, + { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, evp_aes_128_ctr }, + { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, evp_aes_128_ctr }, #endif #if defined(EVP_CTRL_SET_ACSS_MODE) { "acss@openssh.org", SSH_CIPHER_SSH2, 16, 5, EVP_acss }, #endif - { NULL, SSH_CIPHER_ILLEGAL, 0, 0, NULL } + { NULL, SSH_CIPHER_INVALID, 0, 0, NULL } }; /*--*/ @@ -166,25 +166,25 @@ int ciphers_valid(const char *names) { Cipher *c; - char *ciphers, *cp; + char *cipher_list, *cp; char *p; if (names == NULL || strcmp(names, "") == 0) return 0; - ciphers = cp = xstrdup(names); + cipher_list = cp = xstrdup(names); for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0'; (p = strsep(&cp, CIPHER_SEP))) { c = cipher_by_name(p); if (c == NULL || c->number != SSH_CIPHER_SSH2) { debug("bad cipher %s [%s]", p, names); - xfree(ciphers); + xfree(cipher_list); return 0; } else { debug3("cipher ok: %s [%s]", p, names); } } debug3("ciphers ok: [%s]", names); - xfree(ciphers); + xfree(cipher_list); return 1; } @@ -213,7 +213,7 @@ cipher_name(int id) void cipher_init(CipherContext *cc, Cipher *cipher, const u_char *key, u_int keylen, const u_char *iv, u_int ivlen, - int encrypt) + int do_encrypt) { static int dowarn = 1; #ifdef SSH_OLD_EVP @@ -252,10 +252,10 @@ cipher_init(CipherContext *cc, Cipher *cipher, type->key_len = keylen; } EVP_CipherInit(&cc->evp, type, (u_char *)key, (u_char *)iv, - (encrypt == CIPHER_ENCRYPT)); + (do_encrypt == CIPHER_ENCRYPT)); #else if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv, - (encrypt == CIPHER_ENCRYPT)) == 0) + (do_encrypt == CIPHER_ENCRYPT)) == 0) fatal("cipher_init: EVP_CipherInit failed for %s", cipher->name); klen = EVP_CIPHER_CTX_key_length(&cc->evp); @@ -302,7 +302,7 @@ cipher_cleanup(CipherContext *cc) void cipher_set_key_string(CipherContext *cc, Cipher *cipher, - const char *passphrase, int encrypt) + const char *passphrase, int do_encrypt) { MD5_CTX md; u_char digest[16]; @@ -311,7 +311,7 @@ cipher_set_key_string(CipherContext *cc, Cipher *cipher, MD5_Update(&md, (const u_char *)passphrase, strlen(passphrase)); MD5_Final(digest, &md); - cipher_init(cc, cipher, digest, 16, NULL, 0, encrypt); + cipher_init(cc, cipher, digest, 16, NULL, 0, do_encrypt); memset(digest, 0, sizeof(digest)); memset(&md, 0, sizeof(md)); diff --git a/openssh/cipher.h b/openssh/cipher.h index 74b3669..6bb5719 100644 --- a/openssh/cipher.h +++ b/openssh/cipher.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cipher.h,v 1.34 2003/11/10 16:23:41 jakob Exp $ */ +/* $OpenBSD: cipher.h,v 1.35 2004/07/28 09:40:29 markus Exp $ */ /* * Author: Tatu Ylonen @@ -43,7 +43,7 @@ * be removed for compatibility. The maximum allowed value is 31. */ #define SSH_CIPHER_SSH2 -3 -#define SSH_CIPHER_ILLEGAL -2 /* No valid cipher selected. */ +#define SSH_CIPHER_INVALID -2 /* No valid cipher selected. */ #define SSH_CIPHER_NOT_SET -1 /* None selected (invalid number). */ #define SSH_CIPHER_NONE 0 /* no encryption */ #define SSH_CIPHER_IDEA 1 /* IDEA CFB */ diff --git a/openssh/clientloop.c b/openssh/clientloop.c index 626b29a..0b9a0fb 100644 --- a/openssh/clientloop.c +++ b/openssh/clientloop.c @@ -59,7 +59,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: clientloop.c,v 1.117 2003/12/16 15:49:51 markus Exp $"); +RCSID("$OpenBSD: clientloop.c,v 1.130 2004/08/11 21:43:04 avsm Exp $"); #include "ssh.h" #include "ssh1.h" @@ -79,9 +79,11 @@ RCSID("$OpenBSD: clientloop.c,v 1.117 2003/12/16 15:49:51 markus Exp $"); #include "clientloop.h" #include "authfd.h" #include "atomicio.h" -#include "sshtty.h" +#include "sshpty.h" #include "misc.h" -#include "readpass.h" +#include "monitor_fdpass.h" +#include "match.h" +#include "msg.h" /* import options */ extern Options options; @@ -92,6 +94,9 @@ extern int stdin_null_flag; /* Flag indicating that no shell has been requested */ extern int no_shell_flag; +/* Control socket */ +extern int control_fd; + /* * Name of the host we are connecting to. This is the name given on the * command line, or the HostName specified for the user-supplied name in a @@ -132,16 +137,27 @@ static int server_alive_timeouts = 0; static void client_init_dispatch(void); int session_ident = -1; +struct confirm_ctx { + int want_tty; + int want_subsys; + Buffer cmd; + char *term; + struct termios tio; + char **env; +}; + /*XXX*/ extern Kex *xxx_kex; +void ssh_process_session2_setup(int, int, int, Buffer *); + /* Restores stdin to blocking mode. */ static void leave_non_blocking(void) { if (in_non_blocking_mode) { - (void) fcntl(fileno(stdin), F_SETFL, 0); + unset_nonblock(fileno(stdin)); in_non_blocking_mode = 0; } } @@ -152,7 +168,7 @@ static void enter_non_blocking(void) { in_non_blocking_mode = 1; - (void) fcntl(fileno(stdin), F_SETFL, O_NONBLOCK); + set_nonblock(fileno(stdin)); } /* @@ -292,19 +308,13 @@ client_check_window_change(void) /** XXX race */ received_window_change_signal = 0; - if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) - return; - debug2("client_check_window_change: changed"); if (compat20) { - channel_request_start(session_ident, "window-change", 0); - packet_put_int(ws.ws_col); - packet_put_int(ws.ws_row); - packet_put_int(ws.ws_xpixel); - packet_put_int(ws.ws_ypixel); - packet_send(); + channel_send_window_changes(); } else { + if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) + return; packet_start(SSH_CMSG_WINDOW_SIZE); packet_put_int(ws.ws_row); packet_put_int(ws.ws_col); @@ -336,10 +346,9 @@ server_alive_check(void) * Waits until the client can do something (some data becomes available on * one of the file descriptors). */ - static void client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, - int *maxfdp, int *nallocp, int rekeying) + int *maxfdp, u_int *nallocp, int rekeying) { struct timeval tv, *tvp; int ret; @@ -382,6 +391,9 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, if (packet_have_data_to_write()) FD_SET(connection_out, *writesetp); + if (control_fd != -1) + FD_SET(control_fd, *readsetp); + /* * Wait for something to happen. This will suspend the process until * some selected descriptor can be read, written, or has some other @@ -390,7 +402,7 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, if (options.server_alive_interval == 0 || !compat20) tvp = NULL; - else { + else { tv.tv_sec = options.server_alive_interval; tv.tv_usec = 0; tvp = &tv; @@ -500,6 +512,222 @@ client_process_net_input(fd_set * readset) } } +static void +client_subsystem_reply(int type, u_int32_t seq, void *ctxt) +{ + int id; + Channel *c; + + id = packet_get_int(); + packet_check_eom(); + + if ((c = channel_lookup(id)) == NULL) { + error("%s: no channel for id %d", __func__, id); + return; + } + + if (type == SSH2_MSG_CHANNEL_SUCCESS) + debug2("Request suceeded on channel %d", id); + else if (type == SSH2_MSG_CHANNEL_FAILURE) { + error("Request failed on channel %d", id); + channel_free(c); + } +} + +static void +client_extra_session2_setup(int id, void *arg) +{ + struct confirm_ctx *cctx = arg; + Channel *c; + int i; + + if (cctx == NULL) + fatal("%s: cctx == NULL", __func__); + if ((c = channel_lookup(id)) == NULL) + fatal("%s: no channel for id %d", __func__, id); + + client_session2_setup(id, cctx->want_tty, cctx->want_subsys, + cctx->term, &cctx->tio, c->rfd, &cctx->cmd, cctx->env, + client_subsystem_reply); + + c->confirm_ctx = NULL; + buffer_free(&cctx->cmd); + xfree(cctx->term); + if (cctx->env != NULL) { + for (i = 0; cctx->env[i] != NULL; i++) + xfree(cctx->env[i]); + xfree(cctx->env); + } + xfree(cctx); +} + +static void +client_process_control(fd_set * readset) +{ + Buffer m; + Channel *c; + int client_fd, new_fd[3], ver, i, allowed; + socklen_t addrlen; + struct sockaddr_storage addr; + struct confirm_ctx *cctx; + char *cmd; + u_int len, env_len; + uid_t euid; + gid_t egid; + + /* + * Accept connection on control socket + */ + if (control_fd == -1 || !FD_ISSET(control_fd, readset)) + return; + + memset(&addr, 0, sizeof(addr)); + addrlen = sizeof(addr); + if ((client_fd = accept(control_fd, + (struct sockaddr*)&addr, &addrlen)) == -1) { + error("%s accept: %s", __func__, strerror(errno)); + return; + } + + if (getpeereid(client_fd, &euid, &egid) < 0) { + error("%s getpeereid failed: %s", __func__, strerror(errno)); + close(client_fd); + return; + } + if ((euid != 0) && (getuid() != euid)) { + error("control mode uid mismatch: peer euid %u != uid %u", + (u_int) euid, (u_int) getuid()); + close(client_fd); + return; + } + + allowed = 1; + if (options.control_master == 2) { + char *p, prompt[1024]; + + allowed = 0; + snprintf(prompt, sizeof(prompt), + "Allow shared connection to %s? ", host); + p = read_passphrase(prompt, RP_USE_ASKPASS|RP_ALLOW_EOF); + if (p != NULL) { + /* + * Accept empty responses and responses consisting + * of the word "yes" as affirmative. + */ + if (*p == '\0' || *p == '\n' || + strcasecmp(p, "yes") == 0) + allowed = 1; + xfree(p); + } + } + + unset_nonblock(client_fd); + + buffer_init(&m); + + buffer_put_int(&m, allowed); + buffer_put_int(&m, getpid()); + if (ssh_msg_send(client_fd, /* version */0, &m) == -1) { + error("%s: client msg_send failed", __func__); + close(client_fd); + buffer_free(&m); + return; + } + buffer_clear(&m); + + if (!allowed) { + error("Refused control connection"); + close(client_fd); + buffer_free(&m); + return; + } + + if (ssh_msg_recv(client_fd, &m) == -1) { + error("%s: client msg_recv failed", __func__); + close(client_fd); + buffer_free(&m); + return; + } + + if ((ver = buffer_get_char(&m)) != 0) { + error("%s: wrong client version %d", __func__, ver); + buffer_free(&m); + close(client_fd); + return; + } + + cctx = xmalloc(sizeof(*cctx)); + memset(cctx, 0, sizeof(*cctx)); + + cctx->want_tty = buffer_get_int(&m); + cctx->want_subsys = buffer_get_int(&m); + cctx->term = buffer_get_string(&m, &len); + + cmd = buffer_get_string(&m, &len); + buffer_init(&cctx->cmd); + buffer_append(&cctx->cmd, cmd, strlen(cmd)); + + env_len = buffer_get_int(&m); + env_len = MIN(env_len, 4096); + debug3("%s: receiving %d env vars", __func__, env_len); + if (env_len != 0) { + cctx->env = xmalloc(sizeof(*cctx->env) * (env_len + 1)); + for (i = 0; i < env_len; i++) + cctx->env[i] = buffer_get_string(&m, &len); + cctx->env[i] = NULL; + } + + debug2("%s: accepted tty %d, subsys %d, cmd %s", __func__, + cctx->want_tty, cctx->want_subsys, cmd); + + /* Gather fds from client */ + new_fd[0] = mm_receive_fd(client_fd); + new_fd[1] = mm_receive_fd(client_fd); + new_fd[2] = mm_receive_fd(client_fd); + + debug2("%s: got fds stdin %d, stdout %d, stderr %d", __func__, + new_fd[0], new_fd[1], new_fd[2]); + + /* Try to pick up ttymodes from client before it goes raw */ + if (cctx->want_tty && tcgetattr(new_fd[0], &cctx->tio) == -1) + error("%s: tcgetattr: %s", __func__, strerror(errno)); + + buffer_clear(&m); + if (ssh_msg_send(client_fd, /* version */0, &m) == -1) { + error("%s: client msg_send failed", __func__); + close(client_fd); + close(new_fd[0]); + close(new_fd[1]); + close(new_fd[2]); + buffer_free(&m); + return; + } + buffer_free(&m); + + /* enable nonblocking unless tty */ + if (!isatty(new_fd[0])) + set_nonblock(new_fd[0]); + if (!isatty(new_fd[1])) + set_nonblock(new_fd[1]); + if (!isatty(new_fd[2])) + set_nonblock(new_fd[2]); + + set_nonblock(client_fd); + + c = channel_new("session", SSH_CHANNEL_OPENING, + new_fd[0], new_fd[1], new_fd[2], + CHAN_SES_WINDOW_DEFAULT, CHAN_SES_PACKET_DEFAULT, + CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0); + + /* XXX */ + c->ctl_fd = client_fd; + + debug3("%s: channel_new: %d", __func__, c->self); + + channel_send_open(c->self); + channel_register_confirm(c->self, client_extra_session2_setup, cctx); +} + static void process_cmdline(void) { @@ -507,6 +735,7 @@ process_cmdline(void) char *s, *cmd; u_short fwd_port, fwd_host_port; char buf[1024], sfwd_port[6], sfwd_host_port[6]; + int delete = 0; int local = 0; leave_raw_mode(); @@ -516,44 +745,77 @@ process_cmdline(void) goto out; while (*s && isspace(*s)) s++; - if (*s == 0) + if (*s == '-') + s++; /* Skip cmdline '-', if any */ + if (*s == '\0') + goto out; + + if (*s == 'h' || *s == 'H' || *s == '?') { + logit("Commands:"); + logit(" -Lport:host:hostport Request local forward"); + logit(" -Rport:host:hostport Request remote forward"); + logit(" -KRhostport Cancel remote forward"); goto out; - if (strlen(s) < 2 || s[0] != '-' || !(s[1] == 'L' || s[1] == 'R')) { + } + + if (*s == 'K') { + delete = 1; + s++; + } + if (*s != 'L' && *s != 'R') { logit("Invalid command."); goto out; } - if (s[1] == 'L') + if (*s == 'L') local = 1; - if (!local && !compat20) { + if (local && delete) { + logit("Not supported."); + goto out; + } + if ((!local || delete) && !compat20) { logit("Not supported for SSH protocol version 1."); goto out; } - s += 2; + + s++; while (*s && isspace(*s)) s++; - if (sscanf(s, "%5[0-9]:%255[^:]:%5[0-9]", - sfwd_port, buf, sfwd_host_port) != 3 && - sscanf(s, "%5[0-9]/%255[^/]/%5[0-9]", - sfwd_port, buf, sfwd_host_port) != 3) { - logit("Bad forwarding specification."); - goto out; - } - if ((fwd_port = a2port(sfwd_port)) == 0 || - (fwd_host_port = a2port(sfwd_host_port)) == 0) { - logit("Bad forwarding port(s)."); - goto out; - } - if (local) { - if (channel_setup_local_fwd_listener(fwd_port, buf, - fwd_host_port, options.gateway_ports) < 0) { - logit("Port forwarding failed."); + if (delete) { + if (sscanf(s, "%5[0-9]", sfwd_host_port) != 1) { + logit("Bad forwarding specification."); + goto out; + } + if ((fwd_host_port = a2port(sfwd_host_port)) == 0) { + logit("Bad forwarding port(s)."); + goto out; + } + channel_request_rforward_cancel(fwd_host_port); + } else { + if (sscanf(s, "%5[0-9]:%255[^:]:%5[0-9]", + sfwd_port, buf, sfwd_host_port) != 3 && + sscanf(s, "%5[0-9]/%255[^/]/%5[0-9]", + sfwd_port, buf, sfwd_host_port) != 3) { + logit("Bad forwarding specification."); + goto out; + } + if ((fwd_port = a2port(sfwd_port)) == 0 || + (fwd_host_port = a2port(sfwd_host_port)) == 0) { + logit("Bad forwarding port(s)."); goto out; } - } else - channel_request_remote_forwarding(fwd_port, buf, - fwd_host_port); - logit("Forwarding port."); + if (local) { + if (channel_setup_local_fwd_listener(fwd_port, buf, + fwd_host_port, options.gateway_ports) < 0) { + logit("Port forwarding failed."); + goto out; + } + } else + channel_request_remote_forwarding(fwd_port, buf, + fwd_host_port); + logit("Forwarding port."); + } + out: signal(SIGINT, handler); enter_raw_mode(); @@ -868,9 +1130,6 @@ simple_escape_filter(Channel *c, char *buf, int len) static void client_channel_closed(int id, void *arg) { - if (id != session_ident) - error("client_channel_closed: id %d != session_ident %d", - id, session_ident); channel_cancel_cleanup(id); session_closed = 1; leave_raw_mode(); @@ -888,7 +1147,8 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) { fd_set *readset = NULL, *writeset = NULL; double start_time, total_time; - int max_fd = 0, max_fd2 = 0, len, rekeying = 0, nalloc = 0; + int max_fd = 0, max_fd2 = 0, len, rekeying = 0; + u_int nalloc = 0; char buf[100]; debug("Entering interactive session."); @@ -904,6 +1164,8 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) connection_in = packet_get_connection_in(); connection_out = packet_get_connection_out(); max_fd = MAX(connection_in, connection_out); + if (control_fd != -1) + max_fd = MAX(max_fd, control_fd); if (!compat20) { /* enable nonblocking unless tty */ @@ -1021,6 +1283,9 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) /* Buffer input from the connection. */ client_process_net_input(readset); + /* Accept control connections. */ + client_process_control(readset); + if (quit_pending) break; @@ -1352,7 +1617,7 @@ static void client_input_channel_req(int type, u_int32_t seq, void *ctxt) { Channel *c = NULL; - int id, reply, success = 0; + int exitval, id, reply, success = 0; char *rtype; id = packet_get_int(); @@ -1362,24 +1627,28 @@ client_input_channel_req(int type, u_int32_t seq, void *ctxt) debug("client_input_channel_req: channel %d rtype %s reply %d", id, rtype, reply); - if (session_ident == -1) { - error("client_input_channel_req: no channel %d", session_ident); - } else if (id != session_ident) { - error("client_input_channel_req: channel %d: wrong channel: %d", - session_ident, id); - } - c = channel_lookup(id); - if (c == NULL) { + if (id == -1) { + error("client_input_channel_req: request for channel -1"); + } else if ((c = channel_lookup(id)) == NULL) { error("client_input_channel_req: channel %d: unknown channel", id); } else if (strcmp(rtype, "exit-status") == 0) { - success = 1; - exit_status = packet_get_int(); + exitval = packet_get_int(); + if (id == session_ident) { + success = 1; + exit_status = exitval; + } else if (c->ctl_fd == -1) { + error("client_input_channel_req: unexpected channel %d", + session_ident); + } else { + atomicio(vwrite, c->ctl_fd, &exitval, sizeof(exitval)); + success = 1; + } packet_check_eom(); } if (reply) { packet_start(success ? SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); - packet_put_int(c->remote_id); + packet_put_int(id); packet_send(); } xfree(rtype); @@ -1404,6 +1673,97 @@ client_input_global_request(int type, u_int32_t seq, void *ctxt) xfree(rtype); } +void +client_session2_setup(int id, int want_tty, int want_subsystem, + const char *term, struct termios *tiop, int in_fd, Buffer *cmd, char **env, + dispatch_fn *subsys_repl) +{ + int len; + + debug2("%s: id %d", __func__, id); + + if (want_tty) { + struct winsize ws; + struct termios tio; + + /* Store window size in the packet. */ + if (ioctl(in_fd, TIOCGWINSZ, &ws) < 0) + memset(&ws, 0, sizeof(ws)); + + channel_request_start(id, "pty-req", 0); + packet_put_cstring(term != NULL ? term : ""); + packet_put_int(ws.ws_col); + packet_put_int(ws.ws_row); + packet_put_int(ws.ws_xpixel); + packet_put_int(ws.ws_ypixel); + tio = get_saved_tio(); + tty_make_modes(-1, tiop != NULL ? tiop : &tio); + packet_send(); + /* XXX wait for reply */ + } + + /* Transfer any environment variables from client to server */ + if (options.num_send_env != 0 && env != NULL) { + int i, j, matched; + char *name, *val; + + debug("Sending environment."); + for (i = 0; env[i] != NULL; i++) { + /* Split */ + name = xstrdup(env[i]); + if ((val = strchr(name, '=')) == NULL) { + free(name); + continue; + } + *val++ = '\0'; + + matched = 0; + for (j = 0; j < options.num_send_env; j++) { + if (match_pattern(name, options.send_env[j])) { + matched = 1; + break; + } + } + if (!matched) { + debug3("Ignored env %s", name); + free(name); + continue; + } + + debug("Sending env %s = %s", name, val); + channel_request_start(id, "env", 0); + packet_put_cstring(name); + packet_put_cstring(val); + packet_send(); + free(name); + } + } + + len = buffer_len(cmd); + if (len > 0) { + if (len > 900) + len = 900; + if (want_subsystem) { + debug("Sending subsystem: %.*s", len, (u_char*)buffer_ptr(cmd)); + channel_request_start(id, "subsystem", subsys_repl != NULL); + if (subsys_repl != NULL) { + /* register callback for reply */ + /* XXX we assume that client_loop has already been called */ + dispatch_set(SSH2_MSG_CHANNEL_FAILURE, subsys_repl); + dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, subsys_repl); + } + } else { + debug("Sending command: %.*s", len, (u_char*)buffer_ptr(cmd)); + channel_request_start(id, "exec", 0); + } + packet_put_string(buffer_ptr(cmd), buffer_len(cmd)); + packet_send(); + } else { + channel_request_start(id, "shell", 0); + packet_send(); + } +} + static void client_init_dispatch_20(void) { @@ -1470,5 +1830,7 @@ cleanup_exit(int i) { leave_raw_mode(); leave_non_blocking(); + if (options.control_path != NULL && control_fd != -1) + unlink(options.control_path); _exit(i); } diff --git a/openssh/clientloop.h b/openssh/clientloop.h index 56af06b..9992d59 100644 --- a/openssh/clientloop.h +++ b/openssh/clientloop.h @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.h,v 1.8 2003/12/16 15:49:51 markus Exp $ */ +/* $OpenBSD: clientloop.h,v 1.11 2004/07/11 17:48:47 deraadt Exp $ */ /* * Author: Tatu Ylonen @@ -38,3 +38,5 @@ /* Client side main loop for the interactive session. */ int client_loop(int, int, int); void client_global_request_reply_fwd(int, u_int32_t, void *); +void client_session2_setup(int, int, int, const char *, struct termios *, + int, Buffer *, char **, dispatch_fn *); diff --git a/openssh/compat.h b/openssh/compat.h index efa0f08..5efb5c2 100644 --- a/openssh/compat.h +++ b/openssh/compat.h @@ -1,4 +1,4 @@ -/* $OpenBSD: compat.h,v 1.37 2003/11/02 11:01:03 markus Exp $ */ +/* $OpenBSD: compat.h,v 1.38 2004/07/11 17:48:47 deraadt Exp $ */ /* * Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved. @@ -27,7 +27,7 @@ #ifndef COMPAT_H #define COMPAT_H -#define SSH_PROTO_UNKNOWN 0x00 +#define SSH_PROTO_UNKNOWN 0x00 #define SSH_PROTO_1 0x01 #define SSH_PROTO_1_PREFERRED 0x02 #define SSH_PROTO_2 0x04 diff --git a/openssh/config.guess b/openssh/config.guess index 3fe4d4f..500ee74 100755 --- a/openssh/config.guess +++ b/openssh/config.guess @@ -1,9 +1,9 @@ #! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002 Free Software Foundation, Inc. +# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. -timestamp='2002-07-23' +timestamp='2003-10-03' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -98,30 +98,32 @@ trap 'exit 1' 1 2 15 # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. -# This shell variable is my proudest work .. or something. --bje +# Portable tmp directory creation inspired by the Autoconf team. -set_cc_for_build='tmpdir=${TMPDIR-/tmp}/config-guess-$$ ; -(old=`umask` && umask 077 && mkdir $tmpdir && umask $old && unset old) - || (echo "$me: cannot create $tmpdir" >&2 && exit 1) ; -dummy=$tmpdir/dummy ; -files="$dummy.c $dummy.o $dummy.rel $dummy" ; -trap '"'"'rm -f $files; rmdir $tmpdir; exit 1'"'"' 1 2 15 ; +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do - if ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ; then + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; - rm -f $files ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ; -unset files' +esac ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) @@ -174,11 +176,22 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in fi ;; *) - os=netbsd + os=netbsd ;; esac # The OS release - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. @@ -227,68 +240,52 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in if test $UNAME_RELEASE = "V4.0"; then UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` fi + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. - eval $set_cc_for_build - cat <$dummy.s - .data -\$Lformat: - .byte 37,100,45,37,120,10,0 # "%d-%x\n" - - .text - .globl main - .align 4 - .ent main -main: - .frame \$30,16,\$26,0 - ldgp \$29,0(\$27) - .prologue 1 - .long 0x47e03d80 # implver \$0 - lda \$2,-1 - .long 0x47e20c21 # amask \$2,\$1 - lda \$16,\$Lformat - mov \$0,\$17 - not \$1,\$18 - jsr \$26,printf - ldgp \$29,0(\$26) - mov 0,\$16 - jsr \$26,exit - .end main -EOF - $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null - if test "$?" = 0 ; then - case `$dummy` in - 0-0) - UNAME_MACHINE="alpha" - ;; - 1-0) - UNAME_MACHINE="alphaev5" - ;; - 1-1) - UNAME_MACHINE="alphaev56" - ;; - 1-101) - UNAME_MACHINE="alphapca56" - ;; - 2-303) - UNAME_MACHINE="alphaev6" - ;; - 2-307) - UNAME_MACHINE="alphaev67" - ;; - 2-1307) - UNAME_MACHINE="alphaev68" - ;; - 3-1307) - UNAME_MACHINE="alphaev7" - ;; - esac - fi - rm -f $dummy.s $dummy && rmdir $tmpdir echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` exit 0 ;; + Alpha*:OpenVMS:*:*) + echo alpha-hp-vms + exit 0 ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead @@ -327,6 +324,9 @@ EOF NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit 0 ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit 0 ;; DRS?6000:UNIX_SV:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7 && exit 0 ;; @@ -382,23 +382,23 @@ EOF # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; + exit 0 ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit 0 ;; + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit 0 ;; + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit 0 ;; + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit 0 ;; @@ -437,16 +437,18 @@ EOF exit (-1); } EOF - $CC_FOR_BUILD $dummy.c -o $dummy \ + $CC_FOR_BUILD -o $dummy $dummy.c \ && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ - && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0 - rm -f $dummy.c $dummy && rmdir $tmpdir + && exit 0 echo mips-mips-riscos${UNAME_RELEASE} exit 0 ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit 0 ;; - Night_Hawk:*:*:PowerMAX_OS) + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit 0 ;; Night_Hawk:Power_UNIX:*:*) @@ -462,8 +464,8 @@ EOF echo m88k-motorola-sysv3 exit 0 ;; AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ @@ -476,7 +478,7 @@ EOF else echo i586-dg-dgux${UNAME_RELEASE} fi - exit 0 ;; + exit 0 ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit 0 ;; @@ -521,8 +523,7 @@ EOF exit(0); } EOF - $CC_FOR_BUILD $dummy.c -o $dummy && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0 - rm -f $dummy.c $dummy && rmdir $tmpdir + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 echo rs6000-ibm-aix3.2.5 elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 @@ -573,58 +574,68 @@ EOF 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 - esac ;; - esac + esac ;; + esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c - #define _HPUX_SOURCE - #include - #include + #define _HPUX_SOURCE + #include + #include - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } EOF - (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null) && HP_ARCH=`$dummy` - if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi - rm -f $dummy.c $dummy && rmdir $tmpdir + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + # avoid double evaluation of $set_cc_for_build + test -n "$CC_FOR_BUILD" || eval $set_cc_for_build + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit 0 ;; ia64:HP-UX:*:*) @@ -658,8 +669,7 @@ EOF exit (0); } EOF - $CC_FOR_BUILD $dummy.c -o $dummy && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0 - rm -f $dummy.c $dummy && rmdir $tmpdir + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 echo unknown-hitachi-hiuxwe2 exit 0 ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) @@ -689,22 +699,22 @@ EOF exit 0 ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd - exit 0 ;; + exit 0 ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi - exit 0 ;; + exit 0 ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd - exit 0 ;; + exit 0 ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd - exit 0 ;; + exit 0 ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd - exit 0 ;; + exit 0 ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; @@ -717,9 +727,6 @@ EOF CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; - CRAY*T3D:*:*:*) - echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; @@ -727,14 +734,14 @@ EOF echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; *:UNICOS/mp:*:*) - echo nv1-cray-unicosmp | sed -e 's/\.[^.]*$/.X/' + echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit 0 ;; + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit 0 ;; @@ -744,7 +751,7 @@ EOF *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit 0 ;; - *:FreeBSD:*:*) + *:FreeBSD:*:*|*:GNU/FreeBSD:*:*) # Determine whether the default compiler uses glibc. eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c @@ -756,8 +763,10 @@ EOF #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` - rm -f $dummy.c && rmdir $tmpdir - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC} + # GNU/FreeBSD systems have a "k" prefix to indicate we are using + # FreeBSD's kernel, but not the complete OS. + case ${LIBC} in gnu) kernel_only='k' ;; esac + echo ${UNAME_MACHINE}-unknown-${kernel_only}freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC} exit 0 ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin @@ -768,14 +777,17 @@ EOF i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit 0 ;; - x86:Interix*:3*) - echo i386-pc-interix3 + x86:Interix*:[34]*) + echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' + exit 0 ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks exit 0 ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? - echo i386-pc-interix + echo i586-pc-interix exit 0 ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin @@ -795,6 +807,9 @@ EOF arm*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit 0 ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; @@ -818,8 +833,26 @@ EOF #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` - rm -f $dummy.c && rmdir $tmpdir - test x"${CPU}" != x && echo "${CPU}-pc-linux-gnu" && exit 0 + test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu @@ -836,7 +869,7 @@ EOF EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; - esac + esac objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} @@ -855,6 +888,9 @@ EOF s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit 0 ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; @@ -875,7 +911,7 @@ EOF s/.*supported targets: *// s/ .*// p'` - case "$ld_supported_targets" in + case "$ld_supported_targets" in elf32-i386) TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" ;; @@ -912,9 +948,11 @@ EOF LIBC=gnuaout #endif #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` - rm -f $dummy.c && rmdir $tmpdir test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 ;; @@ -925,13 +963,30 @@ EOF echo i386-sequent-sysv4 exit 0 ;; i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. + # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit 0 ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit 0 ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit 0 ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit 0 ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then @@ -966,15 +1021,12 @@ EOF echo ${UNAME_MACHINE}-pc-sysv32 fi exit 0 ;; - i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit 0 ;; pc:*:*:*) # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i386. + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. echo i386-pc-msdosdjgpp - exit 0 ;; + exit 0 ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit 0 ;; @@ -992,9 +1044,15 @@ EOF # "miniframe" echo m68010-convergent-sysv exit 0 ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit 0 ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit 0 ;; M68*:*:R3V[567]*:*) test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; - 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0) + 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` @@ -1003,17 +1061,14 @@ EOF /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && echo i486-ncr-sysv4 && exit 0 ;; + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit 0 ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit 0 ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit 0 ;; @@ -1041,9 +1096,9 @@ EOF fi exit 0 ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - echo i586-unisys-sysv4 - exit 0 ;; + # says + echo i586-unisys-sysv4 + exit 0 ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm @@ -1065,11 +1120,11 @@ EOF exit 0 ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} + echo mips-nec-sysv${UNAME_RELEASE} else - echo mips-unknown-sysv${UNAME_RELEASE} + echo mips-unknown-sysv${UNAME_RELEASE} fi - exit 0 ;; + exit 0 ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit 0 ;; @@ -1085,6 +1140,9 @@ EOF SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit 0 ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit 0 ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit 0 ;; @@ -1092,7 +1150,11 @@ EOF echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit 0 ;; *:Darwin:*:*) - echo `uname -p`-apple-darwin${UNAME_RELEASE} + case `uname -p` in + *86) UNAME_PROCESSOR=i686 ;; + powerpc) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit 0 ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` @@ -1105,7 +1167,7 @@ EOF *:QNX:*:4*) echo i386-pc-qnx exit 0 ;; - NSR-[GKLNPTVW]:NONSTOP_KERNEL:*:*) + NSR-[DGKLNPTVWY]:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit 0 ;; *:NonStop-UX:*:*) @@ -1128,11 +1190,6 @@ EOF fi echo ${UNAME_MACHINE}-unknown-plan9 exit 0 ;; - i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility - # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit 0 ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit 0 ;; @@ -1151,11 +1208,8 @@ EOF *:ITS:*:*) echo pdp10-unknown-its exit 0 ;; - i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop - exit 0 ;; - i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} exit 0 ;; esac @@ -1179,11 +1233,11 @@ main () #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 - "4" + "4" #else "" #endif - ); exit (0); + ); exit (0); #endif #endif @@ -1277,8 +1331,7 @@ main () } EOF -$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0 -rm -f $dummy.c $dummy && rmdir $tmpdir +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0 # Apollos put the system type in the environment. diff --git a/openssh/config.sub b/openssh/config.sub index 75a74f7..1f31816 100755 --- a/openssh/config.sub +++ b/openssh/config.sub @@ -1,9 +1,9 @@ #! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002 Free Software Foundation, Inc. +# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. -timestamp='2002-07-03' +timestamp='2003-08-18' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software @@ -118,7 +118,7 @@ esac # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in - nto-qnx* | linux-gnu* | freebsd*-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*) + nto-qnx* | linux-gnu* | linux-dietlibc | kfreebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; @@ -162,10 +162,10 @@ case $os in os=-chorusos basic_machine=$1 ;; - -chorusrdb) - os=-chorusrdb + -chorusrdb) + os=-chorusrdb basic_machine=$1 - ;; + ;; -hiux*) os=-hiuxwe2 ;; @@ -228,36 +228,42 @@ case $basic_machine in | a29k \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ - | ip2k \ + | ip2k | iq2000 \ | m32r | m68000 | m68k | m88k | mcore \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ + | mips64vr | mips64vrel \ | mips64orion | mips64orionel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ + | msp430 \ | ns16k | ns32k \ | openrisc | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ - | sh | sh[1234] | sh3e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ | strongarm \ - | tahoe | thumb | tic80 | tron \ + | tahoe | thumb | tic4x | tic80 | tron \ | v850 | v850e \ | we32k \ | x86 | xscale | xstormy16 | xtensa \ @@ -292,7 +298,7 @@ case $basic_machine in | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* \ | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c54x-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ | clipper-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ @@ -300,32 +306,39 @@ case $basic_machine in | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ - | ip2k-* \ + | ip2k-* | iq2000-* \ | m32r-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | mcore-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ | mips64orion-* | mips64orionel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipstx39 | mipstx39el \ - | none-* | np1-* | ns16k-* | ns32k-* | nv1-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | msp430-* \ + | none-* | np1-* | nv1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* \ - | sh-* | sh[1234]-* | sh3e-* | sh[34]eb-* | shbe-* \ + | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ - | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ @@ -363,6 +376,9 @@ case $basic_machine in basic_machine=a29k-none os=-bsd ;; + amd64) + basic_machine=x86_64-pc + ;; amdahl) basic_machine=580-amdahl os=-sysv @@ -712,11 +728,12 @@ case $basic_machine in np1) basic_machine=np1-gould ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; nv1) basic_machine=nv1-cray + os=-unicosmp + ;; + nsr-tandem) + basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki @@ -754,21 +771,27 @@ case $basic_machine in pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; - pentiumpro | p6 | 6x86 | athlon) + pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; - pentiumii | pentium2) + pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; + pentium4) + basic_machine=i786-pc + ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; - pentiumii-* | pentium2-*) + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; pn) basic_machine=pn-gould ;; @@ -821,6 +844,16 @@ case $basic_machine in basic_machine=a29k-amd os=-udi ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; sequent) basic_machine=i386-sequent ;; @@ -828,6 +861,9 @@ case $basic_machine in basic_machine=sh-hitachi os=-hms ;; + sh64) + basic_machine=sh64-unknown + ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks @@ -890,18 +926,10 @@ case $basic_machine in basic_machine=sv1-cray os=-unicos ;; - sx*-nec) - basic_machine=sx6-nec - os=-sysv - ;; symmetry) basic_machine=i386-sequent os=-dynix ;; - t3d) - basic_machine=alpha-cray - os=-unicos - ;; t3e) basic_machine=alphaev5-cray os=-unicos @@ -914,6 +942,14 @@ case $basic_machine in basic_machine=tic54x-unknown os=-coff ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; tx39) basic_machine=mipstx39-unknown ;; @@ -948,8 +984,8 @@ case $basic_machine in os=-vms ;; vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; + basic_machine=f301-fujitsu + ;; vxworks960) basic_machine=i960-wrs os=-vxworks @@ -970,10 +1006,6 @@ case $basic_machine in basic_machine=hppa1.1-winbond os=-proelf ;; - windows32) - basic_machine=i386-pc - os=-windows32-msvcrt - ;; xps | xps100) basic_machine=xps100-honeywell ;; @@ -1020,7 +1052,7 @@ case $basic_machine in we32k) basic_machine=we32k-att ;; - sh3 | sh4 | sh3eb | sh4eb | sh[1234]le | sh3ele) + sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sh64) @@ -1044,10 +1076,6 @@ case $basic_machine in pmac | pmac-mpw) basic_machine=powerpc-apple ;; - c4x*) - basic_machine=c4x-none - os=-coff - ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; @@ -1074,8 +1102,8 @@ esac if [ x"$os" != x"" ] then case $os in - # First match some system type aliases - # that might get confused with valid system types. + # First match some system type aliases + # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` @@ -1103,18 +1131,19 @@ case $os in | -aos* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -kfreebsd* | -freebsd* | -riscix* \ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ - | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* | -powermax*) + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) @@ -1126,8 +1155,10 @@ case $os in ;; esac ;; + -nto-qnx*) + ;; -nto*) - os=-nto-qnx + os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ @@ -1136,6 +1167,9 @@ case $os in -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; @@ -1221,6 +1255,12 @@ case $os in -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; -none) ;; *) @@ -1252,6 +1292,9 @@ case $basic_machine in arm*-semi) os=-aout ;; + c4x-* | tic4x-*) + os=-coff + ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 diff --git a/openssh/configure.ac b/openssh/configure.ac index e6f4df8..b1b33fd 100644 --- a/openssh/configure.ac +++ b/openssh/configure.ac @@ -28,6 +28,8 @@ AC_PROG_CPP AC_PROG_RANLIB AC_PROG_INSTALL AC_PATH_PROG(AR, ar) +AC_PATH_PROG(CAT, cat) +AC_PATH_PROG(KILL, kill) AC_PATH_PROGS(PERL, perl5 perl) AC_PATH_PROG(SED, sed) AC_SUBST(PERL) @@ -37,6 +39,14 @@ AC_PATH_PROG(TEST_MINUS_S_SH, bash) AC_PATH_PROG(TEST_MINUS_S_SH, ksh) AC_PATH_PROG(TEST_MINUS_S_SH, sh) AC_PATH_PROG(SH, sh) +AC_SUBST(TEST_SHELL,sh) + +dnl for buildpkg.sh +AC_PATH_PROG(PATH_GROUPADD_PROG, groupadd, groupadd, + [/usr/sbin${PATH_SEPARATOR}/etc]) +AC_PATH_PROG(PATH_USERADD_PROG, useradd, useradd, + [/usr/sbin${PATH_SEPARATOR}/etc]) +AC_CHECK_PROG(MAKE_PACKAGE_SUPPORTED, pkgmk, yes, no) # System features AC_SYS_LARGEFILE @@ -244,6 +254,7 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) AC_DEFINE(PAM_TTY_KLUDGE) AC_DEFINE(LOCKED_PASSWD_PREFIX, "!") AC_DEFINE(SPT_TYPE,SPT_REUSEARGV) + AC_DEFINE(LINK_OPNOTSUPP_ERRNO, EPERM) inet6_default_4in6=yes case `uname -r` in 1.*|2.0.*) @@ -287,6 +298,7 @@ mips-sony-bsd|mips-sony-newsos4) AC_DEFINE(LOGIN_NEEDS_UTMPX) AC_DEFINE(LOGIN_NEEDS_TERM) AC_DEFINE(PAM_TTY_KLUDGE) + AC_DEFINE(SSHPAM_CHAUTHTOK_NEEDS_RUID) AC_DEFINE(LOCKED_PASSWD_STRING, "*LK*") # Pushing STREAMS modules will cause sshd to acquire a controlling tty. AC_DEFINE(SSHD_ACQUIRES_CTTY) @@ -366,6 +378,7 @@ mips-sony-bsd|mips-sony-newsos4) AC_CHECK_FUNCS(getluid setluid) MANTYPE=man do_sco3_extra_lib_check=yes + TEST_SHELL=ksh ;; *-*-sco3.2v5*) if test -z "$GCC"; then @@ -381,8 +394,10 @@ mips-sony-bsd|mips-sony-newsos4) AC_DEFINE(BROKEN_SETREUID) AC_DEFINE(BROKEN_SETREGID) AC_DEFINE(WITH_ABBREV_NO_TTY) + AC_DEFINE(BROKEN_UPDWTMPX) AC_CHECK_FUNCS(getluid setluid) MANTYPE=man + TEST_SHELL=ksh ;; *-*-unicosmk*) AC_DEFINE(NO_SSH_LASTLOG) @@ -503,16 +518,16 @@ int main(){exit(0);} ) # Checks for header files. -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 \ +AC_CHECK_HEADERS(bstring.h crypt.h dirent.h endian.h features.h \ + floatingpoint.h getopt.h glob.h ia.h lastlog.h limits.h login.h \ + login_cap.h maillock.h ndir.h netdb.h netgroup.h \ netinet/in_systm.h pam/pam_appl.h paths.h pty.h readpassphrase.h \ rpc/types.h security/pam_appl.h shadow.h stddef.h stdint.h \ - strings.h sys/strtio.h sys/audit.h sys/bitypes.h sys/bsdtty.h \ - sys/cdefs.h sys/mman.h sys/prctl.h sys/pstat.h sys/ptms.h \ - sys/select.h sys/stat.h sys/stream.h sys/stropts.h \ - sys/sysmacros.h sys/time.h sys/timers.h sys/un.h time.h tmpdir.h \ - ttyent.h usersec.h util.h utime.h utmp.h utmpx.h vis.h) + strings.h sys/dir.h sys/strtio.h sys/audit.h sys/bitypes.h \ + sys/bsdtty.h sys/cdefs.h sys/mman.h sys/ndir.h sys/prctl.h \ + sys/pstat.h sys/ptms.h sys/select.h sys/stat.h sys/stream.h \ + sys/stropts.h sys/sysmacros.h sys/time.h sys/timers.h sys/un.h \ + time.h tmpdir.h ttyent.h usersec.h util.h utime.h utmp.h utmpx.h vis.h) # Checks for libraries. AC_CHECK_FUNC(yp_match, , AC_CHECK_LIB(nsl, yp_match)) @@ -717,6 +732,14 @@ int main(void){struct dirent d;exit(sizeof(d.d_name)<=sizeof(char));} ] ) +AC_MSG_CHECKING([for /proc/pid/fd directory]) +if test -d "/proc/$$/fd" ; then + AC_DEFINE(HAVE_PROC_PID) + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi + # Check whether user wants S/Key support SKEY_MSG="no" AC_ARG_WITH(skey, @@ -818,9 +841,9 @@ 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 \ - bcopy bindresvport_sa clock fchmod fchown freeaddrinfo futimes \ - getaddrinfo getcwd getgrouplist getnameinfo getopt \ + arc4random __b64_ntop b64_ntop __b64_pton b64_pton bcopy \ + bindresvport_sa clock closefrom dirfd fchmod fchown freeaddrinfo \ + futimes getaddrinfo getcwd getgrouplist getnameinfo getopt \ getpeereid _getpty getrlimit getttyent glob inet_aton \ inet_ntoa inet_ntop innetgr login_getcapbool md5_crypt memmove \ mkdtemp mmap ngetaddrinfo nsleep ogetaddrinfo openlog_r openpty \ @@ -860,6 +883,8 @@ AC_CHECK_DECL(tcsendbreak, [#include ] ) +AC_CHECK_DECLS(h_errno, , ,[#include ]) + AC_CHECK_FUNCS(setresuid, [ dnl Some platorms have setresuid that isn't implemented, test for this AC_MSG_CHECKING(if setresuid seems to work) @@ -924,6 +949,20 @@ int main(void){char b[5];snprintf(b,5,"123456789");exit(b[4]!='\0');} ) fi +# Check for missing getpeereid (or equiv) support +NO_PEERCHECK="" +if test "x$ac_cv_func_getpeereid" != "xyes" ; then + AC_MSG_CHECKING([whether system supports SO_PEERCRED getsockopt]) + AC_TRY_COMPILE( + [#include + #include ], + [int i = SO_PEERCRED;], + [AC_MSG_RESULT(yes)], + [AC_MSG_RESULT(no) + NO_PEERCHECK=1] + ) +fi + dnl see whether mkstemp() requires XXXXXX if test "x$ac_cv_func_mkdtemp" = "xyes" ; then AC_MSG_CHECKING([for (overly) strict mkstemp]) @@ -2154,6 +2193,25 @@ AC_SEARCH_LIBS(getrrsetbyname, resolv, # Needed by our getrrsetbyname() AC_SEARCH_LIBS(res_query, resolv) AC_SEARCH_LIBS(dn_expand, resolv) + AC_MSG_CHECKING(if res_query will link) + AC_TRY_LINK_FUNC(res_query, AC_MSG_RESULT(yes), + [AC_MSG_RESULT(no) + saved_LIBS="$LIBS" + LIBS="$LIBS -lresolv" + AC_MSG_CHECKING(for res_query in -lresolv) + AC_LINK_IFELSE([ +#include +int main() +{ + res_query (0, 0, 0, 0, 0); + return 0; +} + ], + [LIBS="$LIBS -lresolv" + AC_MSG_RESULT(yes)], + [LIBS="$saved_LIBS" + AC_MSG_RESULT(no)]) + ]) AC_CHECK_FUNCS(_getshort _getlong) AC_CHECK_MEMBER(HEADER.ad, [AC_DEFINE(HAVE_HEADER_AD)],, @@ -2207,7 +2265,10 @@ AC_ARG_WITH(kerberos5, [ char *tmp = heimdal_version; ], [ AC_MSG_RESULT(yes) AC_DEFINE(HEIMDAL) - K5LIBS="-lkrb5 -ldes -lcom_err -lasn1 -lroken" + K5LIBS="-lkrb5 -ldes" + K5LIBS="$K5LIBS -lcom_err -lasn1" + AC_CHECK_LIB(roken, net_write, + [K5LIBS="$K5LIBS -lroken"]) ], [ AC_MSG_RESULT(no) K5LIBS="-lkrb5 -lk5crypto -lcom_err" @@ -2870,7 +2931,7 @@ if test "$ac_cv_lib_pam_pam_set_item" = yes ; then fi AC_EXEEXT -AC_CONFIG_FILES([Makefile openbsd-compat/Makefile scard/Makefile ssh_prng_cmds]) +AC_CONFIG_FILES([Makefile buildpkg.sh opensshd.init openbsd-compat/Makefile scard/Makefile ssh_prng_cmds]) AC_OUTPUT # Print summary of options @@ -2935,6 +2996,10 @@ echo " Libraries: ${LIBWRAP} ${LIBPAM} ${LIBS}" echo "" +if test "x$MAKE_PACKAGE_SUPPORTED" = "xyes" ; then + echo "SVR4 style packages are supported with \"make package\"\n" +fi + if test "x$PAM_MSG" = "xyes" ; then echo "PAM is enabled. You may need to install a PAM control file " echo "for sshd, otherwise password authentication may fail. " @@ -2951,3 +3016,13 @@ if test ! -z "$RAND_HELPER_CMDHASH" ; then echo "" fi +if test ! -z "$NO_PEERCHECK" ; then + echo "WARNING: the operating system that you are using does not " + echo "appear to support either the getpeereid() API nor the " + echo "SO_PEERCRED getsockopt() option. These facilities are used to " + echo "enforce security checks to prevent unauthorised connections to " + echo "ssh-agent. Their absence increases the risk that a malicious " + echo "user can connect to your agent. " + echo "" +fi + diff --git a/openssh/contrib/README b/openssh/contrib/README index 9de3d96..c002238 100644 --- a/openssh/contrib/README +++ b/openssh/contrib/README @@ -19,7 +19,7 @@ X11 SSH Askpass: Jim Knoble has written an excellent X11 passphrase requester. This is highly recommended: -http://www.ntrnet.net/~jmknoble/software/x11-ssh-askpass/index.html +http://www.jmknoble.net/software/x11-ssh-askpass/ In this directory @@ -44,17 +44,27 @@ sshd.pam.freebsd: A PAM config file which works with FreeBSD's PAM port. Contributed by Dominik Brettnacher -mdoc2man.pl: +findssl.sh: -Converts mdoc formated manpages into normal manpages. This can be used -on Solaris machines to provide manpages that are not preformated. -Contributed by Mark D. Roth +Search for all instances of OpenSSL headers and libraries and print their +versions. This is intended to help diagnose OpenSSH's "OpenSSL headers do not +match your library" errors. -redhat: +aix: + Files to build an AIX native (installp or SMIT installable) package. -RPM spec file and scripts for building Redhat packages +caldera: + RPM spec file and scripts for building Caldera OpenLinuix packages -suse: +cygwin: + Support files for Cygwin + +hpux: + Support files for HP-UX -RPM spec file and scripts for building SuSE packages +redhat: + RPM spec file and scripts for building Redhat packages + +suse: + RPM spec file and scripts for building SuSE packages diff --git a/openssh/contrib/caldera/openssh.spec b/openssh/contrib/caldera/openssh.spec index 71396ff..8b3f803 100644 --- a/openssh/contrib/caldera/openssh.spec +++ b/openssh/contrib/caldera/openssh.spec @@ -17,11 +17,11 @@ #old cvs stuff. please update before use. may be deprecated. %define use_stable 1 %if %{use_stable} - %define version 3.8.1p1 + %define version 3.9p1 %define cvs %{nil} %define release 1 %else - %define version 3.8.1p1 + %define version 3.9p1 %define cvs cvs20011009 %define release 0r1 %endif @@ -60,7 +60,7 @@ Source0: see-above:/.../openssh-%{version}.tar.gz %if %{use_stable} Source1: see-above:/.../openssh-%{version}.tar.gz.sig %endif -Source2: http://www.ntrnet.net/~jmknoble/software/%{xsa}/%{askpass}.tar.gz +Source2: http://www.jmknoble.net/software/%{xsa}/%{askpass}.tar.gz Source3: http://www.openssh.com/faq.html %Package server @@ -80,7 +80,7 @@ Summary(pt_BR) : Servidor do protocolo Secure Shell OpenSSH (sshd). %Package askpass Group : System/Network Requires : openssh = %{version} -URL : http://www.ntrnet.net/~jmknoble/software/x11-ssh-askpass/ +URL : http://www.jmknoble.net/software/x11-ssh-askpass/ Obsoletes : ssh-extras Summary : OpenSSH X11 pass-phrase dialog. diff --git a/openssh/contrib/cygwin/README b/openssh/contrib/cygwin/README index fc0a2f6..5a9b1ce 100644 --- a/openssh/contrib/cygwin/README +++ b/openssh/contrib/cygwin/README @@ -212,8 +212,8 @@ in the Cygwin binary distribution, install like this: cd /tmp/cygwin-ssh find * \! -type d | tar cvjfT my-openssh.tar.bz2 - -You must have installed the zlib and openssl-devel packages to be able to -build OpenSSH! +You must have installed the zlib, the openssl-devel and the minires-devel +packages to be able to build OpenSSH! Please send requests, error reports etc. to cygwin@cygwin.com. diff --git a/openssh/contrib/redhat/openssh.spec b/openssh/contrib/redhat/openssh.spec index b747009..f8a91f2 100644 --- a/openssh/contrib/redhat/openssh.spec +++ b/openssh/contrib/redhat/openssh.spec @@ -1,4 +1,4 @@ -%define ver 3.8.1p1 +%define ver 3.9p1 %define rel 1 # OpenSSH privilege separation requires a user & group ID @@ -74,7 +74,7 @@ Release: %{rel} %endif URL: http://www.openssh.com/portable.html Source0: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz -Source1: http://www.pobox.com/~jmknoble/software/x11-ssh-askpass/x11-ssh-askpass-%{aversion}.tar.gz +Source1: http://www.jmknoble.net/software/x11-ssh-askpass/x11-ssh-askpass-%{aversion}.tar.gz License: BSD Group: Applications/Internet BuildRoot: %{_tmppath}/%{name}-%{version}-buildroot diff --git a/openssh/contrib/redhat/sshd.pam b/openssh/contrib/redhat/sshd.pam index 24f3b46..e486077 100644 --- a/openssh/contrib/redhat/sshd.pam +++ b/openssh/contrib/redhat/sshd.pam @@ -4,5 +4,3 @@ auth required pam_nologin.so account required pam_stack.so service=system-auth password required pam_stack.so service=system-auth session required pam_stack.so service=system-auth -session required pam_limits.so -session optional pam_console.so diff --git a/openssh/contrib/solaris/README b/openssh/contrib/solaris/README index eb4c590..fefdd4b 100644 --- a/openssh/contrib/solaris/README +++ b/openssh/contrib/solaris/README @@ -12,8 +12,14 @@ Directions: 1. make -F Makefile.in distprep (Only if you are getting from the CVS tree) 2. ./configure --with-pam [..any other options you want..] -3. look at the top of contrib/solaris/buildpkg.sh for the configurable options. -4. ./contrib/solaris/buildpkg.sh +3. look at the top of buildpkg.sh for the configurable options and put + any changes you want in openssh-config.local. Additional customizations + can be done to the build process by creating one or more of the following + scripts that will be sourced by buildpkg.sh. + pkg_post_make_install_fixes.sh pkg-post-prototype-edit.sh + pkg-preinstall.local pkg-postinstall.local pkg-preremove.local + pkg-postremove.local pkg-request.local +4. Run "make package" If all goes well you should have a solaris package ready to be installed. diff --git a/openssh/contrib/suse/openssh.spec b/openssh/contrib/suse/openssh.spec index 2b43d03..3f4a018 100644 --- a/openssh/contrib/suse/openssh.spec +++ b/openssh/contrib/suse/openssh.spec @@ -1,6 +1,6 @@ Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation Name: openssh -Version: 3.8.1p1 +Version: 3.9p1 URL: http://www.openssh.com/ Release: 1 Source0: openssh-%{version}.tar.gz diff --git a/openssh/defines.h b/openssh/defines.h index 889b918..b21235f 100644 --- a/openssh/defines.h +++ b/openssh/defines.h @@ -424,6 +424,10 @@ struct winsize { # define __attribute__(x) #endif /* !defined(__GNUC__) || (__GNUC__ < 2) */ +#ifndef __dead +# define __dead __attribute__((noreturn)) +#endif + /* *-*-nto-qnx doesn't define this macro in the system headers */ #ifdef MISSING_HOWMANY # define howmany(x,y) (((x)+((y)-1))/(y)) @@ -462,6 +466,9 @@ struct winsize { (struct cmsghdr *)NULL) #endif /* CMSG_FIRSTHDR */ +#ifndef offsetof +# define offsetof(type, member) ((size_t) &((type *)0)->member) +#endif /* Function replacement / compatibility hacks */ diff --git a/openssh/dh.c b/openssh/dh.c index afd1e05..044d869 100644 --- a/openssh/dh.c +++ b/openssh/dh.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: dh.c,v 1.29 2004/02/27 22:49:27 dtucker Exp $"); +RCSID("$OpenBSD: dh.c,v 1.31 2004/08/04 10:37:52 djm Exp $"); #include "xmalloc.h" @@ -115,8 +115,9 @@ choose_dh(int min, int wantbits, int max) if ((f = fopen(_PATH_DH_MODULI, "r")) == NULL && (f = fopen(_PATH_DH_PRIMES, "r")) == NULL) { - logit("WARNING: %s does not exist, using old modulus", _PATH_DH_MODULI); - return (dh_new_group1()); + logit("WARNING: %s does not exist, using fixed modulus", + _PATH_DH_MODULI); + return (dh_new_group14()); } linenum = 0; @@ -144,7 +145,7 @@ choose_dh(int min, int wantbits, int max) if (bestcount == 0) { fclose(f); logit("WARNING: no suitable primes in %s", _PATH_DH_PRIMES); - return (NULL); + return (dh_new_group14()); } linenum = 0; @@ -169,7 +170,7 @@ choose_dh(int min, int wantbits, int max) return (dh_new_group(dhg.g, dhg.p)); } -/* diffie-hellman-group1-sha1 */ +/* diffie-hellman-groupN-sha1 */ int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub) @@ -272,6 +273,25 @@ dh_new_group1(void) return (dh_new_group_asc(gen, group1)); } +DH * +dh_new_group14(void) +{ + static char *gen = "2", *group14 = + "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" + "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD" + "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245" + "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" + "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D" + "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F" + "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D" + "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B" + "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9" + "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510" + "15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF"; + + return (dh_new_group_asc(gen, group14)); +} + /* * Estimates the group order for a Diffie-Hellman group that has an * attack complexity approximately the same as O(2**bits). Estimate diff --git a/openssh/dh.h b/openssh/dh.h index a0c97b2..723dd08 100644 --- a/openssh/dh.h +++ b/openssh/dh.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dh.h,v 1.7 2001/06/26 17:27:23 markus Exp $ */ +/* $OpenBSD: dh.h,v 1.8 2004/06/13 12:53:24 djm Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. @@ -36,6 +36,7 @@ DH *choose_dh(int, int, int); DH *dh_new_group_asc(const char *, const char *); DH *dh_new_group(BIGNUM *, BIGNUM *); DH *dh_new_group1(void); +DH *dh_new_group14(void); void dh_gen_key(DH *, int); int dh_pub_is_valid(DH *, BIGNUM *); diff --git a/openssh/dns.c b/openssh/dns.c index ad634f1..140ab60 100644 --- a/openssh/dns.c +++ b/openssh/dns.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dns.c,v 1.9 2003/11/21 11:57:03 djm Exp $ */ +/* $OpenBSD: dns.c,v 1.10 2004/06/21 17:36:31 avsm Exp $ */ /* * Copyright (c) 2003 Wesley Griffin. All rights reserved. @@ -43,7 +43,7 @@ #include "uuencode.h" extern char *__progname; -RCSID("$OpenBSD: dns.c,v 1.9 2003/11/21 11:57:03 djm Exp $"); +RCSID("$OpenBSD: dns.c,v 1.10 2004/06/21 17:36:31 avsm Exp $"); #ifndef LWRES static const char *errset_text[] = { @@ -56,9 +56,9 @@ static const char *errset_text[] = { }; static const char * -dns_result_totext(unsigned int error) +dns_result_totext(unsigned int res) { - switch (error) { + switch (res) { case ERRSET_SUCCESS: return errset_text[ERRSET_SUCCESS]; case ERRSET_NOMEMORY: diff --git a/openssh/envpass.sh b/openssh/envpass.sh new file mode 100644 index 0000000..67044d4 --- /dev/null +++ b/openssh/envpass.sh @@ -0,0 +1,44 @@ +# $OpenBSD: envpass.sh,v 1.1 2004/04/27 09:47:30 djm Exp $ +# Placed in the Public Domain. + +tid="environment passing" + +# NB accepted env vars are in test-exec.sh (_XXX_TEST_* and _XXX_TEST) + +trace "pass env, don't accept" +verbose "test $tid: pass env, don't accept" +_TEST_ENV=blah ${SSH} -oSendEnv="*" -F $OBJ/ssh_proxy otherhost \ + '[ -z "$_TEST_ENV" ]' +r=$? +if [ $r -ne 0 ]; then + fail "environment found" +fi + +trace "don't pass env, accept" +verbose "test $tid: don't pass env, accept" +${SSH} -F $OBJ/ssh_proxy otherhost \ + '[ -z "$_XXX_TEST_A" -a -z "$_XXX_TEST_B" ]' +r=$? +if [ $r -ne 0 ]; then + fail "environment found" +fi + +trace "pass single env, accept single env" +verbose "test $tid: pass single env, accept single env" +_XXX_TEST=blah ${SSH} -oSendEnv="_XXX_TEST" -F $OBJ/ssh_proxy otherhost \ + '[ "x$_XXX_TEST" = "xblah" ]' +r=$? +if [ $r -ne 0 ]; then + fail "environment not found" +fi + +trace "pass multiple env, accept multiple env" +verbose "test $tid: pass multiple env, accept multiple env" +_XXX_TEST_A=1 _XXX_TEST_B=2 ${SSH} -oSendEnv="_XXX_TEST_*" \ + -F $OBJ/ssh_proxy otherhost \ + '[ "x$_XXX_TEST_A" = "x1" -a "x$_XXX_TEST_B" = "x2" ]' +r=$? +if [ $r -ne 0 ]; then + fail "environment not found" +fi + diff --git a/openssh/gss-serv-krb5.c b/openssh/gss-serv-krb5.c index 4e3598e..91d87f7 100644 --- a/openssh/gss-serv-krb5.c +++ b/openssh/gss-serv-krb5.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gss-serv-krb5.c,v 1.2 2003/11/21 11:57:03 djm Exp $ */ +/* $OpenBSD: gss-serv-krb5.c,v 1.3 2004/07/21 10:36:23 djm Exp $ */ /* * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -53,7 +53,7 @@ static krb5_context krb_context = NULL; /* Initialise the krb5 library, for the stuff that GSSAPI won't do */ static int -ssh_gssapi_krb5_init() +ssh_gssapi_krb5_init(void) { krb5_error_code problem; @@ -134,11 +134,15 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) { int tmpfd; char ccname[40]; + mode_t old_umask; snprintf(ccname, sizeof(ccname), "FILE:/tmp/krb5cc_%d_XXXXXX", geteuid()); - if ((tmpfd = mkstemp(ccname + strlen("FILE:"))) == -1) { + old_umask = umask(0177); + tmpfd = mkstemp(ccname + strlen("FILE:")); + umask(old_umask); + if (tmpfd == -1) { logit("mkstemp(): %.100s", strerror(errno)); problem = errno; return; diff --git a/openssh/includes.h b/openssh/includes.h index ca943c7..3a6b4c3 100644 --- a/openssh/includes.h +++ b/openssh/includes.h @@ -1,4 +1,4 @@ -/* $OpenBSD: includes.h,v 1.17 2002/01/26 16:44:22 stevesk Exp $ */ +/* $OpenBSD: includes.h,v 1.18 2004/06/13 15:03:02 djm Exp $ */ /* * Author: Tatu Ylonen @@ -33,6 +33,7 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } #include #include #include +#include #ifdef HAVE_LIMITS_H # include /* For PATH_MAX */ @@ -180,6 +181,16 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } # include #endif +/* + * On HP-UX 11.11, shadow.h and prot.h provide conflicting declarations + * of getspnam when _INCLUDE__STDC__ is defined, so we unset it here. + */ +#ifdef __hpux +# ifdef _INCLUDE__STDC__ +# undef _INCLUDE__STDC__ +# endif +#endif + #include /* For OPENSSL_VERSION_NUMBER */ #include "defines.h" diff --git a/openssh/kex.c b/openssh/kex.c index 5a952c9..a668346 100644 --- a/openssh/kex.c +++ b/openssh/kex.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: kex.c,v 1.56 2003/11/21 11:57:03 djm Exp $"); +RCSID("$OpenBSD: kex.c,v 1.60 2004/06/21 17:36:31 avsm Exp $"); #include @@ -148,7 +148,7 @@ kex_finish(Kex *kex) void kex_send_kexinit(Kex *kex) { - u_int32_t rand = 0; + u_int32_t rnd = 0; u_char *cookie; int i; @@ -168,9 +168,9 @@ kex_send_kexinit(Kex *kex) cookie = buffer_ptr(&kex->my); for (i = 0; i < KEX_COOKIE_LEN; i++) { if (i % 4 == 0) - rand = arc4random(); - cookie[i] = rand; - rand >>= 8; + rnd = arc4random(); + cookie[i] = rnd; + rnd >>= 8; } packet_start(SSH2_MSG_KEXINIT); packet_put_raw(buffer_ptr(&kex->my), buffer_len(&kex->my)); @@ -293,6 +293,8 @@ choose_kex(Kex *k, char *client, char *server) fatal("no kex alg"); if (strcmp(k->name, KEX_DH1) == 0) { k->kex_type = KEX_DH_GRP1_SHA1; + } else if (strcmp(k->name, KEX_DH14) == 0) { + k->kex_type = KEX_DH_GRP14_SHA1; } else if (strcmp(k->name, KEX_DHGEX) == 0) { k->kex_type = KEX_DH_GEX_SHA1; } else @@ -479,6 +481,39 @@ kex_get_newkeys(int mode) return ret; } +void +derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus, + u_int8_t cookie[8], u_int8_t id[16]) +{ + const EVP_MD *evp_md = EVP_md5(); + EVP_MD_CTX md; + u_int8_t nbuf[2048], obuf[EVP_MAX_MD_SIZE]; + int len; + + EVP_DigestInit(&md, evp_md); + + len = BN_num_bytes(host_modulus); + if (len < (512 / 8) || len > sizeof(nbuf)) + fatal("%s: bad host modulus (len %d)", __func__, len); + BN_bn2bin(host_modulus, nbuf); + EVP_DigestUpdate(&md, nbuf, len); + + len = BN_num_bytes(server_modulus); + if (len < (512 / 8) || len > sizeof(nbuf)) + fatal("%s: bad server modulus (len %d)", __func__, len); + BN_bn2bin(server_modulus, nbuf); + EVP_DigestUpdate(&md, nbuf, len); + + EVP_DigestUpdate(&md, cookie, 8); + + EVP_DigestFinal(&md, obuf, NULL); + memcpy(id, obuf, 16); + + memset(nbuf, 0, sizeof(nbuf)); + memset(obuf, 0, sizeof(obuf)); + memset(&md, 0, sizeof(md)); +} + #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) void dump_digest(char *msg, u_char *digest, int len) diff --git a/openssh/kex.h b/openssh/kex.h index 52d442e..d9e9d65 100644 --- a/openssh/kex.h +++ b/openssh/kex.h @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.h,v 1.33 2003/02/16 17:09:57 markus Exp $ */ +/* $OpenBSD: kex.h,v 1.35 2004/06/13 12:53:24 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -32,6 +32,7 @@ #include "key.h" #define KEX_DH1 "diffie-hellman-group1-sha1" +#define KEX_DH14 "diffie-hellman-group14-sha1" #define KEX_DHGEX "diffie-hellman-group-exchange-sha1" enum kex_init_proposals { @@ -56,6 +57,7 @@ enum kex_modes { enum kex_exchange { KEX_DH_GRP1_SHA1, + KEX_DH_GRP14_SHA1, KEX_DH_GEX_SHA1, KEX_MAX }; @@ -137,6 +139,9 @@ u_char * kexgex_hash(char *, char *, char *, int, char *, int, u_char *, int, int, int, int, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *); +void +derive_ssh1_session_id(BIGNUM *, BIGNUM *, u_int8_t[8], u_int8_t[16]); + #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) void dump_digest(char *, u_char *, int); #endif diff --git a/openssh/kexdhc.c b/openssh/kexdhc.c index fe6dc53..f48bd46 100644 --- a/openssh/kexdhc.c +++ b/openssh/kexdhc.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: kexdhc.c,v 1.1 2003/02/16 17:09:57 markus Exp $"); +RCSID("$OpenBSD: kexdhc.c,v 1.2 2004/06/13 12:53:24 djm Exp $"); #include "xmalloc.h" #include "key.h" @@ -44,7 +44,16 @@ kexdh_client(Kex *kex) u_int klen, kout, slen, sbloblen; /* generate and send 'e', client DH public key */ - dh = dh_new_group1(); + switch (kex->kex_type) { + case KEX_DH_GRP1_SHA1: + dh = dh_new_group1(); + break; + case KEX_DH_GRP14_SHA1: + dh = dh_new_group14(); + break; + default: + fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); + } dh_gen_key(dh, kex->we_need * 8); packet_start(SSH2_MSG_KEXDH_INIT); packet_put_bignum2(dh->pub_key); diff --git a/openssh/kexdhs.c b/openssh/kexdhs.c index f04bce8..225e655 100644 --- a/openssh/kexdhs.c +++ b/openssh/kexdhs.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: kexdhs.c,v 1.1 2003/02/16 17:09:57 markus Exp $"); +RCSID("$OpenBSD: kexdhs.c,v 1.2 2004/06/13 12:53:24 djm Exp $"); #include "xmalloc.h" #include "key.h" @@ -45,7 +45,16 @@ kexdh_server(Kex *kex) u_int slen; /* generate server DH public key */ - dh = dh_new_group1(); + switch (kex->kex_type) { + case KEX_DH_GRP1_SHA1: + dh = dh_new_group1(); + break; + case KEX_DH_GRP14_SHA1: + dh = dh_new_group14(); + break; + default: + fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); + } dh_gen_key(dh, kex->we_need * 8); debug("expecting SSH2_MSG_KEXDH_INIT"); diff --git a/openssh/key.c b/openssh/key.c index 323e6ff..21b0869 100644 --- a/openssh/key.c +++ b/openssh/key.c @@ -32,7 +32,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$OpenBSD: key.c,v 1.55 2003/11/10 16:23:41 jakob Exp $"); +RCSID("$OpenBSD: key.c,v 1.56 2004/07/28 09:40:29 markus Exp $"); #include @@ -782,7 +782,7 @@ key_sign( return ssh_rsa_sign(key, sigp, lenp, data, datalen); break; default: - error("key_sign: illegal key type %d", key->type); + error("key_sign: invalid key type %d", key->type); return -1; break; } @@ -809,7 +809,7 @@ key_verify( return ssh_rsa_verify(key, signature, signaturelen, data, datalen); break; default: - error("key_verify: illegal key type %d", key->type); + error("key_verify: invalid key type %d", key->type); return -1; break; } diff --git a/openssh/log.c b/openssh/log.c index 0c4d512..5d8625d 100644 --- a/openssh/log.c +++ b/openssh/log.c @@ -51,6 +51,9 @@ static char *argv0; extern char *__progname; +#define LOG_SYSLOG_VIS (VIS_CSTYLE|VIS_NL|VIS_TAB|VIS_OCTAL) +#define LOG_STDERR_VIS (VIS_SAFE|VIS_OCTAL) + /* textual representation of log-facilities/levels */ static struct { @@ -316,7 +319,8 @@ do_log(LogLevel level, const char *fmt, va_list args) } else { vsnprintf(msgbuf, sizeof(msgbuf), fmt, args); } - strnvis(fmtbuf, msgbuf, sizeof(fmtbuf), VIS_SAFE|VIS_OCTAL); + strnvis(fmtbuf, msgbuf, sizeof(fmtbuf), + log_on_stderr ? LOG_STDERR_VIS : LOG_SYSLOG_VIS); if (log_on_stderr) { snprintf(msgbuf, sizeof msgbuf, "%s\r\n", fmtbuf); write(STDERR_FILENO, msgbuf, strlen(msgbuf)); diff --git a/openssh/log.h b/openssh/log.h index e026319..2b3c309 100644 --- a/openssh/log.h +++ b/openssh/log.h @@ -1,4 +1,4 @@ -/* $OpenBSD: log.h,v 1.10 2003/09/23 20:17:11 markus Exp $ */ +/* $OpenBSD: log.h,v 1.11 2004/06/21 22:02:58 djm Exp $ */ /* * Author: Tatu Ylonen @@ -53,7 +53,7 @@ void log_init(char *, LogLevel, SyslogFacility, int); SyslogFacility log_facility_number(char *); LogLevel log_level_number(char *); -void fatal(const char *, ...) __attribute__((format(printf, 1, 2))); +void fatal(const char *, ...) __dead __attribute__((format(printf, 1, 2))); void error(const char *, ...) __attribute__((format(printf, 1, 2))); void logit(const char *, ...) __attribute__((format(printf, 1, 2))); void verbose(const char *, ...) __attribute__((format(printf, 1, 2))); @@ -62,5 +62,5 @@ void debug2(const char *, ...) __attribute__((format(printf, 1, 2))); void debug3(const char *, ...) __attribute__((format(printf, 1, 2))); void do_log(LogLevel, const char *, va_list); -void cleanup_exit(int); +void cleanup_exit(int) __dead; #endif diff --git a/openssh/loginrec.c b/openssh/loginrec.c index 897921c..34c97f9 100644 --- a/openssh/loginrec.c +++ b/openssh/loginrec.c @@ -434,6 +434,11 @@ login_write (struct logininfo *li) #endif #ifdef USE_WTMPX wtmpx_write_entry(li); +#endif +#ifdef CUSTOM_SYS_AUTH_RECORD_LOGIN + if (li->type == LTYPE_LOGIN && + !sys_auth_record_login(li->username,li->hostname,li->line)) + logit("Writing login record failed for %s", li->username); #endif return 0; } @@ -813,8 +818,8 @@ utmp_write_direct(struct logininfo *li, struct utmp *ut) endttyent(); if((struct ttyent *)0 == ty) { - logit("utmp_write_entry: tty not found"); - return(1); + logit("%s: tty not found", __func__); + return (0); } #else /* FIXME */ @@ -823,7 +828,18 @@ utmp_write_direct(struct logininfo *li, struct utmp *ut) #endif /* HAVE_GETTTYENT */ if (tty > 0 && (fd = open(UTMP_FILE, O_RDWR|O_CREAT, 0644)) >= 0) { - (void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET); + off_t pos, ret; + + pos = (off_t)tty * sizeof(struct utmp); + if ((ret = lseek(fd, pos, SEEK_SET)) == -1) { + logit("%s: llseek: %s", strerror(errno)); + return (0); + } + if (ret != pos) { + logit("%s: Couldn't seek to tty %s slot in %s", tty, + UTMP_FILE); + return (0); + } /* * Prevent luser from zero'ing out ut_host. * If the new ut_line is empty but the old one is not @@ -836,9 +852,17 @@ utmp_write_direct(struct logininfo *li, struct utmp *ut) (void)memcpy(ut->ut_host, old_ut.ut_host, sizeof(ut->ut_host)); } - (void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET); + if ((ret = lseek(fd, pos, SEEK_SET)) == -1) { + logit("%s: llseek: %s", __func__, strerror(errno)); + return (0); + } + if (ret != pos) { + logit("%s: Couldn't seek to tty %s slot in %s", + __func__, tty, UTMP_FILE); + return (0); + } if (atomicio(vwrite, fd, ut, sizeof(*ut)) != sizeof(*ut)) - logit("utmp_write_direct: error writing %s: %s", + logit("%s: error writing %s: %s", __func__, UTMP_FILE, strerror(errno)); (void)close(fd); diff --git a/openssh/logintest.c b/openssh/logintest.c index 1922987..1528761 100644 --- a/openssh/logintest.c +++ b/openssh/logintest.c @@ -45,11 +45,7 @@ RCSID("$Id$"); -#ifdef HAVE___PROGNAME extern char *__progname; -#else -char *__progname; -#endif #define PAUSE_BEFORE_LOGOUT 3 diff --git a/openssh/mdoc2man.awk b/openssh/mdoc2man.awk index 9135af0..4e72cdc 100644 --- a/openssh/mdoc2man.awk +++ b/openssh/mdoc2man.awk @@ -32,6 +32,7 @@ BEGIN { extopt=0 literal=0 prenl=0 + breakw=0 line="" } @@ -298,6 +299,13 @@ function add(str) { w=nwords } else if(match(words[w],"^El$")) { optlist=oldoptlist + } else if(match(words[w],"^Bk$")) { + if(match(words[w+1],"-words")) { + w++ + breakw=1 + } + } else if(match(words[w],"^Ek$")) { + breakw=0 } else if(match(words[w],"^It$")&&optlist) { if(optlist==1) add(".IP \\(bu") @@ -306,7 +314,7 @@ function add(str) { else if(optlist==3) { add(".TP") prenl++ - if(match(words[w+1],"^Pa|Ev$")) { + if(match(words[w+1],"^Pa$|^Ev$")) { add(".B") w++ } diff --git a/openssh/misc.c b/openssh/misc.c index 1f32035..8cb411c 100644 --- a/openssh/misc.c +++ b/openssh/misc.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: misc.c,v 1.23 2003/10/28 09:08:06 markus Exp $"); +RCSID("$OpenBSD: misc.c,v 1.25 2004/08/11 21:43:05 avsm Exp $"); #include "misc.h" #include "log.h" @@ -46,7 +46,7 @@ chop(char *s) } /* set/unset filedescriptor to non-blocking */ -void +int set_nonblock(int fd) { int val; @@ -54,20 +54,23 @@ set_nonblock(int fd) val = fcntl(fd, F_GETFL, 0); if (val < 0) { error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno)); - return; + return (-1); } if (val & O_NONBLOCK) { - debug2("fd %d is O_NONBLOCK", fd); - return; + debug3("fd %d is O_NONBLOCK", fd); + return (0); } 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", - fd, strerror(errno)); + if (fcntl(fd, F_SETFL, val) == -1) { + debug("fcntl(%d, F_SETFL, O_NONBLOCK): %s", fd, + strerror(errno)); + return (-1); + } + return (0); } -void +int unset_nonblock(int fd) { int val; @@ -75,17 +78,20 @@ unset_nonblock(int fd) val = fcntl(fd, F_GETFL, 0); if (val < 0) { error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno)); - return; + return (-1); } if (!(val & O_NONBLOCK)) { - debug2("fd %d is not O_NONBLOCK", fd); - return; + debug3("fd %d is not O_NONBLOCK", fd); + return (0); } debug("fd %d clearing O_NONBLOCK", fd); val &= ~O_NONBLOCK; - if (fcntl(fd, F_SETFL, val) == -1) - debug("fcntl(%d, F_SETFL, O_NONBLOCK): %s", + if (fcntl(fd, F_SETFL, val) == -1) { + debug("fcntl(%d, F_SETFL, ~O_NONBLOCK): %s", fd, strerror(errno)); + return (-1); + } + return (0); } /* disable nagle on socket */ @@ -308,7 +314,7 @@ addargs(arglist *args, char *fmt, ...) { va_list ap; char buf[1024]; - int nalloc; + u_int nalloc; va_start(ap, fmt); vsnprintf(buf, sizeof(buf), fmt, ap); diff --git a/openssh/misc.h b/openssh/misc.h index 6d2869b..ec47a61 100644 --- a/openssh/misc.h +++ b/openssh/misc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.h,v 1.12 2002/03/19 10:49:35 markus Exp $ */ +/* $OpenBSD: misc.h,v 1.17 2004/08/11 21:43:05 avsm Exp $ */ /* * Author: Tatu Ylonen @@ -12,10 +12,12 @@ * called by a name other than "ssh" or "Secure Shell". */ +/* misc.c */ + char *chop(char *); char *strdelim(char **); -void set_nonblock(int); -void unset_nonblock(int); +int set_nonblock(int); +int unset_nonblock(int); void set_nodelay(int); int a2port(const char *); char *cleanhostname(char *); @@ -27,7 +29,20 @@ struct passwd *pwcopy(struct passwd *); typedef struct arglist arglist; struct arglist { char **list; - int num; - int nalloc; + u_int num; + u_int nalloc; }; void addargs(arglist *, char *, ...) __attribute__((format(printf, 2, 3))); + +/* tildexpand.c */ + +char *tilde_expand_filename(const char *, uid_t); + +/* readpass.c */ + +#define RP_ECHO 0x0001 +#define RP_ALLOW_STDIN 0x0002 +#define RP_ALLOW_EOF 0x0004 +#define RP_USE_ASKPASS 0x0008 + +char *read_passphrase(const char *, int); diff --git a/openssh/moduli.c b/openssh/moduli.c index a09073a..581b035 100644 --- a/openssh/moduli.c +++ b/openssh/moduli.c @@ -1,4 +1,4 @@ -/* $OpenBSD: moduli.c,v 1.5 2003/12/22 09:16:57 djm Exp $ */ +/* $OpenBSD: moduli.c,v 1.9 2004/07/11 17:48:47 deraadt Exp $ */ /* * Copyright 1994 Phil Karn * Copyright 1996-1998, 2003 William Allen Simpson @@ -38,7 +38,6 @@ */ #include "includes.h" -#include "moduli.h" #include "xmalloc.h" #include "log.h" @@ -49,55 +48,68 @@ */ /* need line long enough for largest moduli plus headers */ -#define QLINESIZE (100+8192) +#define QLINESIZE (100+8192) /* Type: decimal. * Specifies the internal structure of the prime modulus. */ -#define QTYPE_UNKNOWN (0) -#define QTYPE_UNSTRUCTURED (1) -#define QTYPE_SAFE (2) -#define QTYPE_SCHNOOR (3) -#define QTYPE_SOPHIE_GERMAINE (4) -#define QTYPE_STRONG (5) +#define QTYPE_UNKNOWN (0) +#define QTYPE_UNSTRUCTURED (1) +#define QTYPE_SAFE (2) +#define QTYPE_SCHNOOR (3) +#define QTYPE_SOPHIE_GERMAIN (4) +#define QTYPE_STRONG (5) /* Tests: decimal (bit field). * Specifies the methods used in checking for primality. * Usually, more than one test is used. */ -#define QTEST_UNTESTED (0x00) -#define QTEST_COMPOSITE (0x01) -#define QTEST_SIEVE (0x02) -#define QTEST_MILLER_RABIN (0x04) -#define QTEST_JACOBI (0x08) -#define QTEST_ELLIPTIC (0x10) +#define QTEST_UNTESTED (0x00) +#define QTEST_COMPOSITE (0x01) +#define QTEST_SIEVE (0x02) +#define QTEST_MILLER_RABIN (0x04) +#define QTEST_JACOBI (0x08) +#define QTEST_ELLIPTIC (0x10) /* * Size: decimal. * Specifies the number of the most significant bit (0 to M). * WARNING: internally, usually 1 to N. */ -#define QSIZE_MINIMUM (511) +#define QSIZE_MINIMUM (511) /* * Prime sieving defines */ /* Constant: assuming 8 bit bytes and 32 bit words */ -#define SHIFT_BIT (3) -#define SHIFT_BYTE (2) -#define SHIFT_WORD (SHIFT_BIT+SHIFT_BYTE) -#define SHIFT_MEGABYTE (20) -#define SHIFT_MEGAWORD (SHIFT_MEGABYTE-SHIFT_BYTE) +#define SHIFT_BIT (3) +#define SHIFT_BYTE (2) +#define SHIFT_WORD (SHIFT_BIT+SHIFT_BYTE) +#define SHIFT_MEGABYTE (20) +#define SHIFT_MEGAWORD (SHIFT_MEGABYTE-SHIFT_BYTE) + +/* + * Using virtual memory can cause thrashing. This should be the largest + * number that is supported without a large amount of disk activity -- + * that would increase the run time from hours to days or weeks! + */ +#define LARGE_MINIMUM (8UL) /* megabytes */ + +/* + * Do not increase this number beyond the unsigned integer bit size. + * Due to a multiple of 4, it must be LESS than 128 (yielding 2**30 bits). + */ +#define LARGE_MAXIMUM (127UL) /* megabytes */ /* * Constant: when used with 32-bit integers, the largest sieve prime * has to be less than 2**32. */ -#define SMALL_MAXIMUM (0xffffffffUL) +#define SMALL_MAXIMUM (0xffffffffUL) /* Constant: can sieve all primes less than 2**32, as 65537**2 > 2**32-1. */ -#define TINY_NUMBER (1UL<<16) +#define TINY_NUMBER (1UL<<16) /* Ensure enough bit space for testing 2*q. */ #define TEST_MAXIMUM (1UL<<16) @@ -114,6 +126,9 @@ * Prime testing defines */ +/* Minimum number of primality tests to perform */ +#define TRIAL_MINIMUM (4) + /* * Sieving data (XXX - move to struct) */ @@ -129,6 +144,8 @@ static u_int32_t *LargeSieve, largewords, largetries, largenumbers; static u_int32_t largebits, largememory; /* megabytes */ static BIGNUM *largebase; +int gen_candidates(FILE *, int, int, BIGNUM *); +int prime_test(FILE *, FILE *, u_int32_t, u_int32_t); /* * print moduli out in consistent form, @@ -219,7 +236,7 @@ sieve_large(u_int32_t s) } /* - * list candidates for Sophie-Germaine primes (where q = (p-1)/2) + * list candidates for Sophie-Germain primes (where q = (p-1)/2) * to standard output. * The list is checked against small known primes (less than 2**30). */ @@ -235,6 +252,13 @@ gen_candidates(FILE *out, int memory, int power, BIGNUM *start) largememory = memory; + if (memory != 0 && + (memory < LARGE_MINIMUM || memory > LARGE_MAXIMUM)) { + error("Invalid memory amount (min %ld, max %ld)", + LARGE_MINIMUM, LARGE_MAXIMUM); + return (-1); + } + /* * Set power to the length in bits of the prime to be generated. * This is changed to 1 less than the desired safe prime moduli p. @@ -403,7 +427,7 @@ gen_candidates(FILE *out, int memory, int power, BIGNUM *start) debug2("test q = largebase+%u", 2 * j); BN_set_word(q, 2 * j); BN_add(q, q, largebase); - if (qfileout(out, QTYPE_SOPHIE_GERMAINE, QTEST_SIEVE, + if (qfileout(out, QTYPE_SOPHIE_GERMAIN, QTEST_SIEVE, largetries, (power - 1) /* MSB */, (0), q) == -1) { ret = -1; break; @@ -430,8 +454,7 @@ gen_candidates(FILE *out, int memory, int power, BIGNUM *start) * The result is a list of so-call "safe" primes */ int -prime_test(FILE *in, FILE *out, u_int32_t trials, - u_int32_t generator_wanted) +prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted) { BIGNUM *q, *p, *a; BN_CTX *ctx; @@ -441,6 +464,11 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, time_t time_start, time_stop; int res; + if (trials < TRIAL_MINIMUM) { + error("Minimum primality trials is %d", TRIAL_MINIMUM); + return (-1); + } + time(&time_start); p = BN_new(); @@ -490,8 +518,8 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, /* modulus (hex) */ switch (in_type) { - case QTYPE_SOPHIE_GERMAINE: - debug2("%10u: (%u) Sophie-Germaine", count_in, in_type); + case QTYPE_SOPHIE_GERMAIN: + debug2("%10u: (%u) Sophie-Germain", count_in, in_type); a = q; BN_hex2bn(&a, cp); /* p = 2*q + 1 */ diff --git a/openssh/monitor.c b/openssh/monitor.c index 9c30c1c..b746340 100644 --- a/openssh/monitor.c +++ b/openssh/monitor.c @@ -25,7 +25,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: monitor.c,v 1.55 2004/02/05 05:37:17 dtucker Exp $"); +RCSID("$OpenBSD: monitor.c,v 1.61 2004/07/17 05:31:41 dtucker Exp $"); #include @@ -63,7 +63,6 @@ RCSID("$OpenBSD: monitor.c,v 1.55 2004/02/05 05:37:17 dtucker Exp $"); #include "bufaux.h" #include "compat.h" #include "ssh2.h" -#include "mpaux.h" #ifdef GSSAPI #include "ssh-gss.h" @@ -80,6 +79,7 @@ extern u_char session_id[]; extern Buffer input, output; extern Buffer auth_debug; extern int auth_debug_init; +extern Buffer loginmsg; /* State exported from the child */ @@ -351,9 +351,9 @@ monitor_set_child_handler(pid_t pid) } static void -monitor_child_handler(int signal) +monitor_child_handler(int sig) { - kill(monitor_child_pid, signal); + kill(monitor_child_pid, sig); } void @@ -468,7 +468,7 @@ monitor_reset_key_state(void) } int -mm_answer_moduli(int socket, Buffer *m) +mm_answer_moduli(int sock, Buffer *m) { DH *dh; int min, want, max; @@ -498,12 +498,12 @@ mm_answer_moduli(int socket, Buffer *m) DH_free(dh); } - mm_request_send(socket, MONITOR_ANS_MODULI, m); + mm_request_send(sock, MONITOR_ANS_MODULI, m); return (0); } int -mm_answer_sign(int socket, Buffer *m) +mm_answer_sign(int sock, Buffer *m) { Key *key; u_char *p; @@ -539,7 +539,7 @@ mm_answer_sign(int socket, Buffer *m) xfree(p); xfree(signature); - mm_request_send(socket, MONITOR_ANS_SIGN, m); + mm_request_send(sock, MONITOR_ANS_SIGN, m); /* Turn on permissions for getpwnam */ monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1); @@ -550,9 +550,9 @@ mm_answer_sign(int socket, Buffer *m) /* Retrieves the password entry and also checks if the user is permitted */ int -mm_answer_pwnamallow(int socket, Buffer *m) +mm_answer_pwnamallow(int sock, Buffer *m) { - char *login; + char *username; struct passwd *pwent; int allowed = 0; @@ -561,13 +561,13 @@ mm_answer_pwnamallow(int socket, Buffer *m) if (authctxt->attempt++ != 0) fatal("%s: multiple attempts for getpwnam", __func__); - login = buffer_get_string(m, NULL); + username = buffer_get_string(m, NULL); - pwent = getpwnamallow(login); + pwent = getpwnamallow(username); - authctxt->user = xstrdup(login); - setproctitle("%s [priv]", pwent ? login : "unknown"); - xfree(login); + authctxt->user = xstrdup(username); + setproctitle("%s [priv]", pwent ? username : "unknown"); + xfree(username); buffer_clear(m); @@ -594,7 +594,7 @@ mm_answer_pwnamallow(int socket, Buffer *m) out: debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed); - mm_request_send(socket, MONITOR_ANS_PWNAM, m); + mm_request_send(sock, MONITOR_ANS_PWNAM, m); /* For SSHv1 allow authentication now */ if (!compat20) @@ -613,14 +613,14 @@ mm_answer_pwnamallow(int socket, Buffer *m) return (0); } -int mm_answer_auth2_read_banner(int socket, Buffer *m) +int mm_answer_auth2_read_banner(int sock, Buffer *m) { char *banner; buffer_clear(m); banner = auth2_read_banner(); buffer_put_cstring(m, banner != NULL ? banner : ""); - mm_request_send(socket, MONITOR_ANS_AUTH2_READ_BANNER, m); + mm_request_send(sock, MONITOR_ANS_AUTH2_READ_BANNER, m); if (banner != NULL) xfree(banner); @@ -629,7 +629,7 @@ int mm_answer_auth2_read_banner(int socket, Buffer *m) } int -mm_answer_authserv(int socket, Buffer *m) +mm_answer_authserv(int sock, Buffer *m) { monitor_permit_authentications(1); @@ -647,7 +647,7 @@ mm_answer_authserv(int socket, Buffer *m) } int -mm_answer_authpassword(int socket, Buffer *m) +mm_answer_authpassword(int sock, Buffer *m) { static int call_count; char *passwd; @@ -665,7 +665,7 @@ mm_answer_authpassword(int socket, Buffer *m) buffer_put_int(m, authenticated); debug3("%s: sending result %d", __func__, authenticated); - mm_request_send(socket, MONITOR_ANS_AUTHPASSWORD, m); + mm_request_send(sock, MONITOR_ANS_AUTHPASSWORD, m); call_count++; if (plen == 0 && call_count == 1) @@ -679,7 +679,7 @@ mm_answer_authpassword(int socket, Buffer *m) #ifdef BSD_AUTH int -mm_answer_bsdauthquery(int socket, Buffer *m) +mm_answer_bsdauthquery(int sock, Buffer *m) { char *name, *infotxt; u_int numprompts; @@ -696,7 +696,7 @@ mm_answer_bsdauthquery(int socket, Buffer *m) buffer_put_cstring(m, prompts[0]); debug3("%s: sending challenge success: %u", __func__, success); - mm_request_send(socket, MONITOR_ANS_BSDAUTHQUERY, m); + mm_request_send(sock, MONITOR_ANS_BSDAUTHQUERY, m); if (success) { xfree(name); @@ -709,7 +709,7 @@ mm_answer_bsdauthquery(int socket, Buffer *m) } int -mm_answer_bsdauthrespond(int socket, Buffer *m) +mm_answer_bsdauthrespond(int sock, Buffer *m) { char *response; int authok; @@ -728,7 +728,7 @@ mm_answer_bsdauthrespond(int socket, Buffer *m) buffer_put_int(m, authok); debug3("%s: sending authenticated: %d", __func__, authok); - mm_request_send(socket, MONITOR_ANS_BSDAUTHRESPOND, m); + mm_request_send(sock, MONITOR_ANS_BSDAUTHRESPOND, m); auth_method = "bsdauth"; @@ -738,7 +738,7 @@ mm_answer_bsdauthrespond(int socket, Buffer *m) #ifdef SKEY int -mm_answer_skeyquery(int socket, Buffer *m) +mm_answer_skeyquery(int sock, Buffer *m) { struct skey skey; char challenge[1024]; @@ -753,13 +753,13 @@ mm_answer_skeyquery(int socket, Buffer *m) buffer_put_cstring(m, challenge); debug3("%s: sending challenge success: %u", __func__, success); - mm_request_send(socket, MONITOR_ANS_SKEYQUERY, m); + mm_request_send(sock, MONITOR_ANS_SKEYQUERY, m); return (0); } int -mm_answer_skeyrespond(int socket, Buffer *m) +mm_answer_skeyrespond(int sock, Buffer *m) { char *response; int authok; @@ -777,7 +777,7 @@ mm_answer_skeyrespond(int socket, Buffer *m) buffer_put_int(m, authok); debug3("%s: sending authenticated: %d", __func__, authok); - mm_request_send(socket, MONITOR_ANS_SKEYRESPOND, m); + mm_request_send(sock, MONITOR_ANS_SKEYRESPOND, m); auth_method = "skey"; @@ -787,7 +787,7 @@ mm_answer_skeyrespond(int socket, Buffer *m) #ifdef USE_PAM int -mm_answer_pam_start(int socket, Buffer *m) +mm_answer_pam_start(int sock, Buffer *m) { if (!options.use_pam) fatal("UsePAM not set, but ended up in %s anyway", __func__); @@ -800,7 +800,7 @@ mm_answer_pam_start(int socket, Buffer *m) } int -mm_answer_pam_account(int socket, Buffer *m) +mm_answer_pam_account(int sock, Buffer *m) { u_int ret; @@ -811,7 +811,7 @@ mm_answer_pam_account(int socket, Buffer *m) buffer_put_int(m, ret); - mm_request_send(socket, MONITOR_ANS_PAM_ACCOUNT, m); + mm_request_send(sock, MONITOR_ANS_PAM_ACCOUNT, m); return (ret); } @@ -820,7 +820,7 @@ static void *sshpam_ctxt, *sshpam_authok; extern KbdintDevice sshpam_device; int -mm_answer_pam_init_ctx(int socket, Buffer *m) +mm_answer_pam_init_ctx(int sock, Buffer *m) { debug3("%s", __func__); @@ -834,12 +834,12 @@ mm_answer_pam_init_ctx(int socket, Buffer *m) } else { buffer_put_int(m, 0); } - mm_request_send(socket, MONITOR_ANS_PAM_INIT_CTX, m); + mm_request_send(sock, MONITOR_ANS_PAM_INIT_CTX, m); return (0); } int -mm_answer_pam_query(int socket, Buffer *m) +mm_answer_pam_query(int sock, Buffer *m) { char *name, *info, **prompts; u_int num, *echo_on; @@ -868,12 +868,12 @@ mm_answer_pam_query(int socket, Buffer *m) xfree(prompts); if (echo_on != NULL) xfree(echo_on); - mm_request_send(socket, MONITOR_ANS_PAM_QUERY, m); + mm_request_send(sock, MONITOR_ANS_PAM_QUERY, m); return (0); } int -mm_answer_pam_respond(int socket, Buffer *m) +mm_answer_pam_respond(int sock, Buffer *m) { char **resp; u_int num; @@ -895,7 +895,7 @@ mm_answer_pam_respond(int socket, Buffer *m) } buffer_clear(m); buffer_put_int(m, ret); - mm_request_send(socket, MONITOR_ANS_PAM_RESPOND, m); + mm_request_send(sock, MONITOR_ANS_PAM_RESPOND, m); auth_method = "keyboard-interactive/pam"; if (ret == 0) sshpam_authok = sshpam_ctxt; @@ -903,13 +903,13 @@ mm_answer_pam_respond(int socket, Buffer *m) } int -mm_answer_pam_free_ctx(int socket, Buffer *m) +mm_answer_pam_free_ctx(int sock, Buffer *m) { debug3("%s", __func__); (sshpam_device.free_ctx)(sshpam_ctxt); buffer_clear(m); - mm_request_send(socket, MONITOR_ANS_PAM_FREE_CTX, m); + mm_request_send(sock, MONITOR_ANS_PAM_FREE_CTX, m); return (sshpam_authok == sshpam_ctxt); } #endif @@ -926,7 +926,7 @@ mm_append_debug(Buffer *m) } int -mm_answer_keyallowed(int socket, Buffer *m) +mm_answer_keyallowed(int sock, Buffer *m) { Key *key; char *cuser, *chost; @@ -996,7 +996,7 @@ mm_answer_keyallowed(int socket, Buffer *m) mm_append_debug(m); - mm_request_send(socket, MONITOR_ANS_KEYALLOWED, m); + mm_request_send(sock, MONITOR_ANS_KEYALLOWED, m); if (type == MM_RSAHOSTKEY) monitor_permit(mon_dispatch, MONITOR_REQ_RSACHALLENGE, allowed); @@ -1117,7 +1117,7 @@ monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser, } int -mm_answer_keyverify(int socket, Buffer *m) +mm_answer_keyverify(int sock, Buffer *m) { Key *key; u_char *signature, *data, *blob; @@ -1167,7 +1167,7 @@ mm_answer_keyverify(int socket, Buffer *m) buffer_clear(m); buffer_put_int(m, verified); - mm_request_send(socket, MONITOR_ANS_KEYVERIFY, m); + mm_request_send(sock, MONITOR_ANS_KEYVERIFY, m); return (verified); } @@ -1209,7 +1209,7 @@ mm_session_close(Session *s) } int -mm_answer_pty(int socket, Buffer *m) +mm_answer_pty(int sock, Buffer *m) { extern struct monitor *pmonitor; Session *s; @@ -1231,10 +1231,6 @@ mm_answer_pty(int socket, Buffer *m) buffer_put_int(m, 1); buffer_put_cstring(m, s->tty); - mm_request_send(socket, MONITOR_ANS_PTY, m); - - mm_send_fd(socket, s->ptyfd); - mm_send_fd(socket, s->ttyfd); /* We need to trick ttyslot */ if (dup2(s->ttyfd, 0) == -1) @@ -1245,6 +1241,15 @@ mm_answer_pty(int socket, Buffer *m) /* Now we can close the file descriptor again */ close(0); + /* send messages generated by record_login */ + buffer_put_string(m, buffer_ptr(&loginmsg), buffer_len(&loginmsg)); + buffer_clear(&loginmsg); + + mm_request_send(sock, MONITOR_ANS_PTY, m); + + mm_send_fd(sock, s->ptyfd); + mm_send_fd(sock, s->ttyfd); + /* make sure nothing uses fd 0 */ if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) < 0) fatal("%s: open(/dev/null): %s", __func__, strerror(errno)); @@ -1265,12 +1270,12 @@ mm_answer_pty(int socket, Buffer *m) if (s != NULL) mm_session_close(s); buffer_put_int(m, 0); - mm_request_send(socket, MONITOR_ANS_PTY, m); + mm_request_send(sock, MONITOR_ANS_PTY, m); return (0); } int -mm_answer_pty_cleanup(int socket, Buffer *m) +mm_answer_pty_cleanup(int sock, Buffer *m) { Session *s; char *tty; @@ -1286,7 +1291,7 @@ mm_answer_pty_cleanup(int socket, Buffer *m) } int -mm_answer_sesskey(int socket, Buffer *m) +mm_answer_sesskey(int sock, Buffer *m) { BIGNUM *p; int rsafail; @@ -1307,7 +1312,7 @@ mm_answer_sesskey(int socket, Buffer *m) BN_clear_free(p); - mm_request_send(socket, MONITOR_ANS_SESSKEY, m); + mm_request_send(sock, MONITOR_ANS_SESSKEY, m); /* Turn on permissions for sessid passing */ monitor_permit(mon_dispatch, MONITOR_REQ_SESSID, 1); @@ -1316,7 +1321,7 @@ mm_answer_sesskey(int socket, Buffer *m) } int -mm_answer_sessid(int socket, Buffer *m) +mm_answer_sessid(int sock, Buffer *m) { int i; @@ -1334,7 +1339,7 @@ mm_answer_sessid(int socket, Buffer *m) } int -mm_answer_rsa_keyallowed(int socket, Buffer *m) +mm_answer_rsa_keyallowed(int sock, Buffer *m) { BIGNUM *client_n; Key *key = NULL; @@ -1374,7 +1379,7 @@ mm_answer_rsa_keyallowed(int socket, Buffer *m) mm_append_debug(m); - mm_request_send(socket, MONITOR_ANS_RSAKEYALLOWED, m); + mm_request_send(sock, MONITOR_ANS_RSAKEYALLOWED, m); monitor_permit(mon_dispatch, MONITOR_REQ_RSACHALLENGE, allowed); monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 0); @@ -1382,7 +1387,7 @@ mm_answer_rsa_keyallowed(int socket, Buffer *m) } int -mm_answer_rsa_challenge(int socket, Buffer *m) +mm_answer_rsa_challenge(int sock, Buffer *m) { Key *key = NULL; u_char *blob; @@ -1408,7 +1413,7 @@ mm_answer_rsa_challenge(int socket, Buffer *m) buffer_put_bignum2(m, ssh1_challenge); debug3("%s sending reply", __func__); - mm_request_send(socket, MONITOR_ANS_RSACHALLENGE, m); + mm_request_send(sock, MONITOR_ANS_RSACHALLENGE, m); monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 1); @@ -1418,7 +1423,7 @@ mm_answer_rsa_challenge(int socket, Buffer *m) } int -mm_answer_rsa_response(int socket, Buffer *m) +mm_answer_rsa_response(int sock, Buffer *m) { Key *key = NULL; u_char *blob, *response; @@ -1457,13 +1462,13 @@ mm_answer_rsa_response(int socket, Buffer *m) buffer_clear(m); buffer_put_int(m, success); - mm_request_send(socket, MONITOR_ANS_RSARESPONSE, m); + mm_request_send(sock, MONITOR_ANS_RSARESPONSE, m); return (success); } int -mm_answer_term(int socket, Buffer *req) +mm_answer_term(int sock, Buffer *req) { extern struct monitor *pmonitor; int res, status; @@ -1480,7 +1485,7 @@ mm_answer_term(int socket, Buffer *req) res = WIFEXITED(status) ? WEXITSTATUS(status) : 1; /* Terminate process */ - exit (res); + exit(res); } void @@ -1547,6 +1552,7 @@ mm_get_kex(Buffer *m) fatal("mm_get_get: internal error: bad session id"); kex->we_need = buffer_get_int(m); kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; + kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server; kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; kex->server = 1; kex->hostkey_type = buffer_get_int(m); @@ -1740,23 +1746,23 @@ monitor_reinit(struct monitor *mon) #ifdef GSSAPI int -mm_answer_gss_setup_ctx(int socket, Buffer *m) +mm_answer_gss_setup_ctx(int sock, Buffer *m) { - gss_OID_desc oid; + gss_OID_desc goid; OM_uint32 major; u_int len; - oid.elements = buffer_get_string(m, &len); - oid.length = len; + goid.elements = buffer_get_string(m, &len); + goid.length = len; - major = ssh_gssapi_server_ctx(&gsscontext, &oid); + major = ssh_gssapi_server_ctx(&gsscontext, &goid); - xfree(oid.elements); + xfree(goid.elements); buffer_clear(m); buffer_put_int(m, major); - mm_request_send(socket,MONITOR_ANS_GSSSETUP, m); + mm_request_send(sock,MONITOR_ANS_GSSSETUP, m); /* Now we have a context, enable the step */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 1); @@ -1765,7 +1771,7 @@ mm_answer_gss_setup_ctx(int socket, Buffer *m) } int -mm_answer_gss_accept_ctx(int socket, Buffer *m) +mm_answer_gss_accept_ctx(int sock, Buffer *m) { gss_buffer_desc in; gss_buffer_desc out = GSS_C_EMPTY_BUFFER; @@ -1782,7 +1788,7 @@ mm_answer_gss_accept_ctx(int socket, Buffer *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); + mm_request_send(sock, MONITOR_ANS_GSSSTEP, m); gss_release_buffer(&minor, &out); @@ -1795,7 +1801,7 @@ mm_answer_gss_accept_ctx(int socket, Buffer *m) } int -mm_answer_gss_checkmic(int socket, Buffer *m) +mm_answer_gss_checkmic(int sock, Buffer *m) { gss_buffer_desc gssbuf, mic; OM_uint32 ret; @@ -1814,7 +1820,7 @@ mm_answer_gss_checkmic(int socket, Buffer *m) buffer_clear(m); buffer_put_int(m, ret); - mm_request_send(socket, MONITOR_ANS_GSSCHECKMIC, m); + mm_request_send(sock, MONITOR_ANS_GSSCHECKMIC, m); if (!GSS_ERROR(ret)) monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); @@ -1823,7 +1829,7 @@ mm_answer_gss_checkmic(int socket, Buffer *m) } int -mm_answer_gss_userok(int socket, Buffer *m) +mm_answer_gss_userok(int sock, Buffer *m) { int authenticated; @@ -1833,7 +1839,7 @@ mm_answer_gss_userok(int socket, Buffer *m) buffer_put_int(m, authenticated); debug3("%s: sending result %d", __func__, authenticated); - mm_request_send(socket, MONITOR_ANS_GSSUSEROK, m); + mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); auth_method="gssapi-with-mic"; diff --git a/openssh/monitor_fdpass.c b/openssh/monitor_fdpass.c index 22b7882..dd1a139 100644 --- a/openssh/monitor_fdpass.c +++ b/openssh/monitor_fdpass.c @@ -24,7 +24,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: monitor_fdpass.c,v 1.4 2002/06/26 14:50:04 deraadt Exp $"); +RCSID("$OpenBSD: monitor_fdpass.c,v 1.6 2004/08/13 02:51:48 djm Exp $"); #include @@ -32,7 +32,7 @@ RCSID("$OpenBSD: monitor_fdpass.c,v 1.4 2002/06/26 14:50:04 deraadt Exp $"); #include "monitor_fdpass.h" void -mm_send_fd(int socket, int fd) +mm_send_fd(int sock, int fd) { #if defined(HAVE_SENDMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR)) struct msghdr msg; @@ -63,7 +63,7 @@ mm_send_fd(int socket, int fd) msg.msg_iov = &vec; msg.msg_iovlen = 1; - if ((n = sendmsg(socket, &msg, 0)) == -1) + if ((n = sendmsg(sock, &msg, 0)) == -1) fatal("%s: sendmsg(%d): %s", __func__, fd, strerror(errno)); if (n != 1) @@ -76,7 +76,7 @@ mm_send_fd(int socket, int fd) } int -mm_receive_fd(int socket) +mm_receive_fd(int sock) { #if defined(HAVE_RECVMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR)) struct msghdr msg; @@ -102,7 +102,7 @@ mm_receive_fd(int socket) msg.msg_controllen = sizeof(tmp); #endif - if ((n = recvmsg(socket, &msg, 0)) == -1) + if ((n = recvmsg(sock, &msg, 0)) == -1) fatal("%s: recvmsg: %s", __func__, strerror(errno)); if (n != 1) fatal("%s: recvmsg: expected received 1 got %ld", @@ -113,6 +113,8 @@ mm_receive_fd(int socket) fatal("%s: no fd", __func__); #else cmsg = CMSG_FIRSTHDR(&msg); + if (cmsg == NULL) + fatal("%s: no message header", __func__); #ifndef BROKEN_CMSG_TYPE if (cmsg->cmsg_type != SCM_RIGHTS) fatal("%s: expected type %d got %d", __func__, diff --git a/openssh/monitor_mm.c b/openssh/monitor_mm.c index e57c87c..ff523a5 100644 --- a/openssh/monitor_mm.c +++ b/openssh/monitor_mm.c @@ -24,7 +24,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: monitor_mm.c,v 1.8 2002/08/02 14:43:15 millert Exp $"); +RCSID("$OpenBSD: monitor_mm.c,v 1.9 2004/05/11 19:01:43 deraadt Exp $"); #ifdef HAVE_SYS_MMAN_H #include diff --git a/openssh/monitor_wrap.c b/openssh/monitor_wrap.c index ee2dc20..0d7a0e3 100644 --- a/openssh/monitor_wrap.c +++ b/openssh/monitor_wrap.c @@ -25,7 +25,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: monitor_wrap.c,v 1.35 2003/11/17 11:06:07 markus Exp $"); +RCSID("$OpenBSD: monitor_wrap.c,v 1.39 2004/07/17 05:31:41 dtucker Exp $"); #include #include @@ -70,6 +70,7 @@ extern z_stream incoming_stream; extern z_stream outgoing_stream; extern struct monitor *pmonitor; extern Buffer input, output; +extern Buffer loginmsg; extern ServerOptions options; int @@ -83,7 +84,7 @@ mm_is_monitor(void) } void -mm_request_send(int socket, enum monitor_reqtype type, Buffer *m) +mm_request_send(int sock, enum monitor_reqtype type, Buffer *m) { u_int mlen = buffer_len(m); u_char buf[5]; @@ -92,14 +93,14 @@ 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(vwrite, socket, buf, sizeof(buf)) != sizeof(buf)) + if (atomicio(vwrite, sock, buf, sizeof(buf)) != sizeof(buf)) fatal("%s: write", __func__); - if (atomicio(vwrite, socket, buffer_ptr(m), mlen) != mlen) + if (atomicio(vwrite, sock, buffer_ptr(m), mlen) != mlen) fatal("%s: write", __func__); } void -mm_request_receive(int socket, Buffer *m) +mm_request_receive(int sock, Buffer *m) { u_char buf[4]; u_int msg_len; @@ -107,7 +108,7 @@ mm_request_receive(int socket, Buffer *m) debug3("%s entering", __func__); - res = atomicio(read, socket, buf, sizeof(buf)); + res = atomicio(read, sock, buf, sizeof(buf)); if (res != sizeof(buf)) { if (res == 0) cleanup_exit(255); @@ -118,19 +119,19 @@ mm_request_receive(int socket, Buffer *m) fatal("%s: read: bad msg_len %d", __func__, msg_len); buffer_clear(m); buffer_append_space(m, msg_len); - res = atomicio(read, socket, buffer_ptr(m), msg_len); + res = atomicio(read, sock, buffer_ptr(m), msg_len); if (res != msg_len) fatal("%s: read: %ld != msg_len", __func__, (long)res); } void -mm_request_receive_expect(int socket, enum monitor_reqtype type, Buffer *m) +mm_request_receive_expect(int sock, enum monitor_reqtype type, Buffer *m) { u_char rtype; debug3("%s entering: type %d", __func__, type); - mm_request_receive(socket, m); + mm_request_receive(sock, m); rtype = buffer_get_char(m); if (rtype != type) fatal("%s: read: rtype %d != type %d", __func__, @@ -194,7 +195,7 @@ mm_key_sign(Key *key, u_char **sigp, u_int *lenp, u_char *data, u_int datalen) } struct passwd * -mm_getpwnamallow(const char *login) +mm_getpwnamallow(const char *username) { Buffer m; struct passwd *pw; @@ -203,7 +204,7 @@ mm_getpwnamallow(const char *login) debug3("%s entering", __func__); buffer_init(&m); - buffer_put_cstring(&m, login); + buffer_put_cstring(&m, username); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PWNAM, &m); @@ -544,7 +545,7 @@ mm_send_kex(Buffer *m, Kex *kex) } void -mm_send_keystate(struct monitor *pmonitor) +mm_send_keystate(struct monitor *monitor) { Buffer m; u_char *blob, *p; @@ -580,7 +581,7 @@ mm_send_keystate(struct monitor *pmonitor) goto skip; } else { /* Kex for rekeying */ - mm_send_kex(&m, *pmonitor->m_pkex); + mm_send_kex(&m, *monitor->m_pkex); } debug3("%s: Sending new keys: %p %p", @@ -632,7 +633,7 @@ mm_send_keystate(struct monitor *pmonitor) buffer_put_string(&m, buffer_ptr(&input), buffer_len(&input)); buffer_put_string(&m, buffer_ptr(&output), buffer_len(&output)); - mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYEXPORT, &m); + mm_request_send(monitor->m_recvfd, MONITOR_REQ_KEYEXPORT, &m); debug3("%s: Finished sending state", __func__); buffer_free(&m); @@ -642,7 +643,7 @@ int mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen) { Buffer m; - char *p; + char *p, *msg; int success = 0; buffer_init(&m); @@ -658,11 +659,15 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen) return (0); } p = buffer_get_string(&m, NULL); + msg = buffer_get_string(&m, NULL); buffer_free(&m); strlcpy(namebuf, p, namebuflen); /* Possible truncation */ xfree(p); + buffer_append(&loginmsg, msg, strlen(msg)); + xfree(msg); + *ptyfd = mm_receive_fd(pmonitor->m_recvfd); *ttyfd = mm_receive_fd(pmonitor->m_recvfd); @@ -914,6 +919,7 @@ mm_bsdauth_respond(void *ctx, u_int numresponses, char **responses) return ((authok == 0) ? -1 : 0); } +#ifdef SKEY int mm_skey_query(void *ctx, char **name, char **infotxt, u_int *numprompts, char ***prompts, u_int **echo_on) @@ -977,6 +983,7 @@ mm_skey_respond(void *ctx, u_int numresponses, char **responses) return ((authok == 0) ? -1 : 0); } +#endif /* SKEY */ void mm_ssh1_session_id(u_char session_id[16]) @@ -1093,7 +1100,7 @@ mm_auth_rsa_verify_response(Key *key, BIGNUM *p, u_char response[16]) #ifdef GSSAPI OM_uint32 -mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) +mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID goid) { Buffer m; OM_uint32 major; @@ -1102,7 +1109,7 @@ mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) *ctx = NULL; buffer_init(&m); - buffer_put_string(&m, oid->elements, oid->length); + buffer_put_string(&m, goid->elements, goid->length); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSETUP, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSETUP, &m); diff --git a/openssh/monitor_wrap.h b/openssh/monitor_wrap.h index 2170b13..e5cf571 100644 --- a/openssh/monitor_wrap.h +++ b/openssh/monitor_wrap.h @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_wrap.h,v 1.13 2003/11/17 11:06:07 markus Exp $ */ +/* $OpenBSD: monitor_wrap.h,v 1.14 2004/06/21 17:36:31 avsm Exp $ */ /* * Copyright 2002 Niels Provos @@ -58,9 +58,9 @@ 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); +OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); +OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, + gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *); int mm_ssh_gssapi_userok(char *user); OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); #endif diff --git a/openssh/myproposal.h b/openssh/myproposal.h index 8b431d9..228ed68 100644 --- a/openssh/myproposal.h +++ b/openssh/myproposal.h @@ -1,4 +1,4 @@ -/* $OpenBSD: myproposal.h,v 1.15 2003/05/17 04:27:52 markus Exp $ */ +/* $OpenBSD: myproposal.h,v 1.16 2004/06/13 12:53:24 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -23,7 +23,9 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#define KEX_DEFAULT_KEX "diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1" +#define KEX_DEFAULT_KEX "diffie-hellman-group-exchange-sha1," \ + "diffie-hellman-group14-sha1," \ + "diffie-hellman-group1-sha1" #define KEX_DEFAULT_PK_ALG "ssh-rsa,ssh-dss" #define KEX_DEFAULT_ENCRYPT \ "aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour," \ diff --git a/openssh/nchan.c b/openssh/nchan.c index 3138cdd..aee3f37 100644 --- a/openssh/nchan.c +++ b/openssh/nchan.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: nchan.c,v 1.49 2003/08/29 10:04:36 markus Exp $"); +RCSID("$OpenBSD: nchan.c,v 1.51 2004/07/11 17:48:47 deraadt Exp $"); #include "ssh1.h" #include "ssh2.h" @@ -42,15 +42,15 @@ RCSID("$OpenBSD: nchan.c,v 1.49 2003/08/29 10:04:36 markus Exp $"); * tear down of channels: * * 1.3: strict request-ack-protocol: - * CLOSE -> - * <- CLOSE_CONFIRM + * CLOSE -> + * <- CLOSE_CONFIRM * * 1.5: uses variations of: - * IEOF -> - * <- OCLOSE - * <- IEOF - * OCLOSE -> - * i.e. both sides have to close the channel + * IEOF -> + * <- OCLOSE + * <- IEOF + * OCLOSE -> + * i.e. both sides have to close the channel * * 2.0: the EOF messages are optional * @@ -395,7 +395,7 @@ chan_mark_dead(Channel *c) } int -chan_is_dead(Channel *c, int send) +chan_is_dead(Channel *c, int do_send) { if (c->type == SSH_CHANNEL_ZOMBIE) { debug2("channel %d: zombie", c->self); @@ -416,7 +416,7 @@ chan_is_dead(Channel *c, int send) return 0; } if (!(c->flags & CHAN_CLOSE_SENT)) { - if (send) { + if (do_send) { chan_send_close2(c); } else { /* channel would be dead if we sent a close */ diff --git a/openssh/openbsd-compat/Makefile.in b/openssh/openbsd-compat/Makefile.in index 8b06199..5a5255d 100644 --- a/openssh/openbsd-compat/Makefile.in +++ b/openssh/openbsd-compat/Makefile.in @@ -18,7 +18,7 @@ LDFLAGS=-L. @LDFLAGS@ OPENBSD=base64.o basename.o bindresvport.o daemon.o dirname.o getcwd.o getgrouplist.o getopt.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sigact.o strlcat.o strlcpy.o strmode.o strsep.o strtoul.o vis.o -COMPAT=bsd-arc4random.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-snprintf.o bsd-waitpid.o fake-rfc2553.o xmmap.o xcrypt.o +COMPAT=bsd-arc4random.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-snprintf.o bsd-waitpid.o fake-rfc2553.o xmmap.o xcrypt.o PORTS=port-irix.o port-aix.o diff --git a/openssh/openbsd-compat/bsd-arc4random.c b/openssh/openbsd-compat/bsd-arc4random.c index 5cbb233..625bf73 100644 --- a/openssh/openbsd-compat/bsd-arc4random.c +++ b/openssh/openbsd-compat/bsd-arc4random.c @@ -56,13 +56,21 @@ unsigned int arc4random(void) void arc4random_stir(void) { unsigned char rand_buf[SEED_SIZE]; + int i; memset(&rc4, 0, sizeof(rc4)); if (RAND_bytes(rand_buf, sizeof(rand_buf)) <= 0) fatal("Couldn't obtain random bytes (error %ld)", ERR_get_error()); RC4_set_key(&rc4, sizeof(rand_buf), rand_buf); - RC4(&rc4, sizeof(rand_buf), rand_buf, rand_buf); + + /* + * Discard early keystream, as per recommendations in: + * http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps + */ + for(i = 0; i <= 256; i += sizeof(rand_buf)) + RC4(&rc4, sizeof(rand_buf), rand_buf, rand_buf); + memset(rand_buf, 0, sizeof(rand_buf)); rc4_ready = REKEY_BYTES; diff --git a/openssh/openbsd-compat/bsd-closefrom.c b/openssh/openbsd-compat/bsd-closefrom.c new file mode 100644 index 0000000..61a9fa3 --- /dev/null +++ b/openssh/openbsd-compat/bsd-closefrom.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2004 Todd C. Miller + * + * 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. + * + * 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" + +#ifndef HAVE_CLOSEFROM + +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_DIRENT_H +# include +# define NAMLEN(dirent) strlen((dirent)->d_name) +#else +# define dirent direct +# define NAMLEN(dirent) (dirent)->d_namlen +# ifdef HAVE_SYS_NDIR_H +# include +# endif +# ifdef HAVE_SYS_DIR_H +# include +# endif +# ifdef HAVE_NDIR_H +# include +# endif +#endif + +#ifndef OPEN_MAX +# define OPEN_MAX 256 +#endif + +RCSID("$Id: bsd-closefrom.c,v 1.1 2004/08/15 08:41:00 djm Exp $"); + +#ifndef lint +static const char sudorcsid[] = "$Sudo: closefrom.c,v 1.6 2004/06/01 20:51:56 millert Exp $"; +#endif /* lint */ + +/* + * Close all file descriptors greater than or equal to lowfd. + */ +void +closefrom(int lowfd) +{ + long fd, maxfd; +#if defined(HAVE_DIRFD) && defined(HAVE_PROC_PID) + char fdpath[PATH_MAX], *endp; + struct dirent *dent; + DIR *dirp; + int len; + + /* Check for a /proc/$$/fd directory. */ + len = snprintf(fdpath, sizeof(fdpath), "/proc/%ld/fd", (long)getpid()); + if (len != -1 && len <= sizeof(fdpath) && (dirp = opendir(fdpath))) { + while ((dent = readdir(dirp)) != NULL) { + fd = strtol(dent->d_name, &endp, 10); + if (dent->d_name != endp && *endp == '\0' && + fd >= 0 && fd < INT_MAX && fd >= lowfd && fd != dirfd(dirp)) + (void) close((int) fd); + } + (void) closedir(dirp); + } else +#endif + { + /* + * Fall back on sysconf() or getdtablesize(). We avoid checking + * resource limits since it is possible to open a file descriptor + * and then drop the rlimit such that it is below the open fd. + */ +#ifdef HAVE_SYSCONF + maxfd = sysconf(_SC_OPEN_MAX); +#else + maxfd = getdtablesize(); +#endif /* HAVE_SYSCONF */ + if (maxfd < 0) + maxfd = OPEN_MAX; + + for (fd = lowfd; fd < maxfd; fd++) + (void) close((int) fd); + } +} + +#endif /* HAVE_CLOSEFROM */ + diff --git a/openssh/openbsd-compat/bsd-misc.c b/openssh/openbsd-compat/bsd-misc.c index bc18b09..070a133 100644 --- a/openssh/openbsd-compat/bsd-misc.c +++ b/openssh/openbsd-compat/bsd-misc.c @@ -1,3 +1,4 @@ + /* * Copyright (c) 1999-2004 Damien Miller * @@ -19,6 +20,10 @@ RCSID("$Id$"); +#ifndef HAVE___PROGNAME +char *__progname; +#endif + /* * NB. duplicate __progname in case it is an alias for argv[0] * Otherwise it may get clobbered by setproctitle() diff --git a/openssh/openbsd-compat/getrrsetbyname.c b/openssh/openbsd-compat/getrrsetbyname.c index 66d1814..660427c 100644 --- a/openssh/openbsd-compat/getrrsetbyname.c +++ b/openssh/openbsd-compat/getrrsetbyname.c @@ -53,6 +53,10 @@ #define ANSWER_BUFFER_SIZE 1024*64 +#if defined(HAVE_DECL_H_ERRNO) && !HAVE_DECL_H_ERRNO +extern int h_errno; +#endif + struct dns_query { char *name; u_int16_t type; diff --git a/openssh/openbsd-compat/openbsd-compat.h b/openssh/openbsd-compat/openbsd-compat.h index 8f8b3fb..76366ff 100644 --- a/openssh/openbsd-compat/openbsd-compat.h +++ b/openssh/openbsd-compat/openbsd-compat.h @@ -48,6 +48,10 @@ char *basename(const char *path); int bindresvport_sa(int sd, struct sockaddr *sa); #endif +#ifndef HAVE_CLOSEFROM +void closefrom(int); +#endif + #ifndef HAVE_GETCWD char *getcwd(char *pt, size_t size); #endif diff --git a/openssh/openbsd-compat/port-aix.c b/openssh/openbsd-compat/port-aix.c index 2895f0d..78f4fae 100644 --- a/openssh/openbsd-compat/port-aix.c +++ b/openssh/openbsd-compat/port-aix.c @@ -101,7 +101,7 @@ aix_remove_embedded_newlines(char *p) int sys_auth_passwd(Authctxt *ctxt, const char *password) { - char *authmsg = NULL, *host, *msg, *name = ctxt->pw->pw_name; + char *authmsg = NULL, *msg, *name = ctxt->pw->pw_name; int authsuccess = 0, expired, reenter, result; do { @@ -115,30 +115,21 @@ sys_auth_passwd(Authctxt *ctxt, const char *password) if (result == 0) { authsuccess = 1; - host = (char *)get_canonical_hostname(options.use_dns); - /* * Record successful login. We don't have a pty yet, so just * label the line as "ssh" */ aix_setauthdb(name); - if (loginsuccess((char *)name, (char *)host, "ssh", &msg) == 0) { - if (msg != NULL) { - debug("%s: msg %s", __func__, msg); - buffer_append(&loginmsg, msg, strlen(msg)); - xfree(msg); - } - } /* * Check if the user's password is expired. */ - expired = passwdexpired(name, &msg); - if (msg && *msg) { - buffer_append(&loginmsg, msg, strlen(msg)); - aix_remove_embedded_newlines(msg); - } - debug3("AIX/passwdexpired returned %d msg %.100s", expired, msg); + expired = passwdexpired(name, &msg); + if (msg && *msg) { + buffer_append(&loginmsg, msg, strlen(msg)); + aix_remove_embedded_newlines(msg); + } + debug3("AIX/passwdexpired returned %d msg %.100s", expired, msg); switch (expired) { case 0: /* password not expired */ @@ -163,7 +154,70 @@ sys_auth_passwd(Authctxt *ctxt, const char *password) return authsuccess; } - + +/* + * Check if specified account is permitted to log in. + * Returns 1 if login is allowed, 0 if not allowed. + */ +int +sys_auth_allowed_user(struct passwd *pw) +{ + char *msg = NULL; + int result, permitted = 0; + struct stat st; + + /* + * Don't perform checks for root account (PermitRootLogin controls + * logins via * ssh) or if running as non-root user (since + * loginrestrictions will always fail due to insufficient privilege). + */ + if (pw->pw_uid == 0 || geteuid() != 0) { + debug3("%s: not checking", __func__); + return 1; + } + + result = loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &msg); + if (result == 0) + permitted = 1; + /* + * If restricted because /etc/nologin exists, the login will be denied + * in session.c after the nologin message is sent, so allow for now + * and do not append the returned message. + */ + if (result == -1 && errno == EPERM && stat(_PATH_NOLOGIN, &st) == 0) + permitted = 1; + else if (msg != NULL) + buffer_append(&loginmsg, msg, strlen(msg)); + if (msg == NULL) + msg = xstrdup("(none)"); + aix_remove_embedded_newlines(msg); + debug3("AIX/loginrestrictions returned %d msg %.100s", result, msg); + + if (!permitted) + logit("Login restricted for %s: %.100s", pw->pw_name, msg); + xfree(msg); + return permitted; +} + +int +sys_auth_record_login(const char *user, const char *host, const char *ttynm) +{ + char *msg; + int success = 0; + + aix_setauthdb(user); + if (loginsuccess((char *)user, host, ttynm, &msg) == 0) { + success = 1; + if (msg != NULL) { + debug("AIX/loginsuccess: msg %s", __func__, msg); + buffer_append(&loginmsg, msg, strlen(msg)); + xfree(msg); + } + } + aix_restoreauthdb(); + return (success); +} + # ifdef CUSTOM_FAILED_LOGIN /* * record_failed_login: generic "login failed" interface function diff --git a/openssh/openbsd-compat/port-aix.h b/openssh/openbsd-compat/port-aix.h index f6bed98..891fa8a 100644 --- a/openssh/openbsd-compat/port-aix.h +++ b/openssh/openbsd-compat/port-aix.h @@ -63,6 +63,10 @@ void aix_usrinfo(struct passwd *); #ifdef WITH_AIXAUTHENTICATE # define CUSTOM_SYS_AUTH_PASSWD 1 +# define CUSTOM_SYS_AUTH_ALLOWED_USER 1 +int sys_auth_allowed_user(struct passwd *); +# define CUSTOM_SYS_AUTH_RECORD_LOGIN 1 +int sys_auth_record_login(const char *, const char *, const char *); # define CUSTOM_FAILED_LOGIN 1 void record_failed_login(const char *, const char *); #endif diff --git a/openssh/openbsd-compat/sys-queue.h b/openssh/openbsd-compat/sys-queue.h index 8ff19e4..c49a946 100644 --- a/openssh/openbsd-compat/sys-queue.h +++ b/openssh/openbsd-compat/sys-queue.h @@ -1,6 +1,6 @@ /* OPENBSD ORIGINAL: sys/sys/queue.h */ -/* $OpenBSD: queue.h,v 1.23 2003/06/02 23:28:21 millert Exp $ */ +/* $OpenBSD: queue.h,v 1.25 2004/04/08 16:08:21 henning Exp $ */ /* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */ /* @@ -38,12 +38,13 @@ #define _FAKE_QUEUE_H_ /* - * Ignore all since older platforms have broken/incomplete - * that are too hard to work around. + * Require for OS/X and other platforms that have old/broken/incomplete + * . */ #undef SLIST_HEAD #undef SLIST_HEAD_INITIALIZER #undef SLIST_ENTRY +#undef SLIST_FOREACH_PREVPTR #undef SLIST_FIRST #undef SLIST_END #undef SLIST_EMPTY @@ -54,6 +55,7 @@ #undef SLIST_INSERT_HEAD #undef SLIST_REMOVE_HEAD #undef SLIST_REMOVE +#undef SLIST_REMOVE_NEXT #undef LIST_HEAD #undef LIST_HEAD_INITIALIZER #undef LIST_ENTRY @@ -194,6 +196,11 @@ struct { \ (var) != SLIST_END(head); \ (var) = SLIST_NEXT(var, field)) +#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \ + for ((varp) = &SLIST_FIRST((head)); \ + ((var) = *(varp)) != SLIST_END(head); \ + (varp) = &SLIST_NEXT((var), field)) + /* * Singly-linked List functions. */ @@ -211,6 +218,10 @@ struct { \ (head)->slh_first = (elm); \ } while (0) +#define SLIST_REMOVE_NEXT(head, elm, field) do { \ + (elm)->field.sle_next = (elm)->field.sle_next->field.sle_next; \ +} while (0) + #define SLIST_REMOVE_HEAD(head, field) do { \ (head)->slh_first = (head)->slh_first->field.sle_next; \ } while (0) @@ -400,7 +411,7 @@ struct { \ (var) != TAILQ_END(head); \ (var) = TAILQ_NEXT(var, field)) -#define TAILQ_FOREACH_REVERSE(var, head, field, headname) \ +#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ for((var) = TAILQ_LAST(head, headname); \ (var) != TAILQ_END(head); \ (var) = TAILQ_PREV(var, headname, field)) diff --git a/openssh/openbsd-compat/xmmap.c b/openssh/openbsd-compat/xmmap.c index 0e22ec6..d136a34 100644 --- a/openssh/openbsd-compat/xmmap.c +++ b/openssh/openbsd-compat/xmmap.c @@ -40,25 +40,28 @@ void *xmmap(size_t size) #ifdef HAVE_MMAP # ifdef MAP_ANON address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_ANON|MAP_SHARED, - -1, 0); + -1, (off_t)0); # else address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_SHARED, - open("/dev/zero", O_RDWR), 0); + open("/dev/zero", O_RDWR), (off_t)0); # endif #define MM_SWAP_TEMPLATE "/var/run/sshd.mm.XXXXXXXX" if (address == MAP_FAILED) { char tmpname[sizeof(MM_SWAP_TEMPLATE)] = MM_SWAP_TEMPLATE; int tmpfd; + mode_t old_umask; + old_umask = umask(0177); tmpfd = mkstemp(tmpname); + umask(old_umask); if (tmpfd == -1) fatal("mkstemp(\"%s\"): %s", MM_SWAP_TEMPLATE, strerror(errno)); unlink(tmpname); ftruncate(tmpfd, size); address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_SHARED, - tmpfd, 0); + tmpfd, (off_t)0); close(tmpfd); } diff --git a/openssh/opensshd.init.in b/openssh/opensshd.init.in new file mode 100755 index 0000000..ffa7cda --- /dev/null +++ b/openssh/opensshd.init.in @@ -0,0 +1,82 @@ +#!/sbin/sh +# Donated code that was put under PD license. +# +# Stripped PRNGd out of it for the time being. + +umask 022 + +CAT=@CAT@ +KILL=@KILL@ + +prefix=@prefix@ +sysconfdir=@sysconfdir@ +piddir=@piddir@ + +SSHD=$prefix/sbin/sshd +PIDFILE=$piddir/sshd.pid +SSH_KEYGEN=$prefix/bin/ssh-keygen +HOST_KEY_RSA1=$sysconfdir/ssh_host_key +HOST_KEY_DSA=$sysconfdir/ssh_host_dsa_key +HOST_KEY_RSA=$sysconfdir/ssh_host_rsa_key + + +checkkeys() { + if [ ! -f $HOST_KEY_RSA1 ]; then + ${SSH_KEYGEN} -t rsa1 -f ${HOST_KEY_RSA1} -N "" + fi + if [ ! -f $HOST_KEY_DSA ]; then + ${SSH_KEYGEN} -t dsa -f ${HOST_KEY_DSA} -N "" + fi + if [ ! -f $HOST_KEY_RSA ]; then + ${SSH_KEYGEN} -t rsa -f ${HOST_KEY_RSA} -N "" + fi +} + +stop_service() { + if [ -r $PIDFILE -a ! -z ${PIDFILE} ]; then + PID=`${CAT} ${PIDFILE}` + fi + if [ ${PID:=0} -gt 1 -a ! "X$PID" = "X " ]; then + ${KILL} ${PID} + else + echo "Unable to read PID file" + fi +} + +start_service() { + # XXX We really should check if the service is already going, but + # XXX we will opt out at this time. - Bal + + # Check to see if we have keys that need to be made + checkkeys + + # Start SSHD + echo "starting $SSHD... \c" ; $SSHD + + sshd_rc=$? + if [ $sshd_rc -ne 0 ]; then + echo "$0: Error ${sshd_rc} starting ${SSHD}... bailing." + exit $sshd_rc + fi + echo done. +} + +case $1 in + +'start') + start_service + ;; + +'stop') + stop_service + ;; + +'restart') + stop_service + start_service + ;; + +*) + echo "$0: usage: $0 {start|stop|restart}" + ;; +esac diff --git a/openssh/packet.c b/openssh/packet.c index daae9ff..82a5694 100644 --- a/openssh/packet.c +++ b/openssh/packet.c @@ -37,7 +37,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: packet.c,v 1.112 2003/09/23 20:17:11 markus Exp $"); +RCSID("$OpenBSD: packet.c,v 1.115 2004/06/21 17:36:31 avsm Exp $"); #include "openbsd-compat/sys-queue.h" @@ -154,8 +154,10 @@ packet_set_connection(int fd_in, int fd_out) fatal("packet_set_connection: cannot load cipher 'none'"); connection_in = fd_in; connection_out = fd_out; - cipher_init(&send_context, none, "", 0, NULL, 0, CIPHER_ENCRYPT); - cipher_init(&receive_context, none, "", 0, NULL, 0, CIPHER_DECRYPT); + cipher_init(&send_context, none, (const u_char *)"", + 0, NULL, 0, CIPHER_ENCRYPT); + cipher_init(&receive_context, none, (const u_char *)"", + 0, NULL, 0, CIPHER_DECRYPT); newkeys[MODE_IN] = newkeys[MODE_OUT] = NULL; if (!initialized) { initialized = 1; @@ -317,13 +319,10 @@ void packet_set_nonblocking(void) { /* Set the socket into non-blocking mode. */ - if (fcntl(connection_in, F_SETFL, O_NONBLOCK) < 0) - error("fcntl O_NONBLOCK: %.100s", strerror(errno)); + set_nonblock(connection_in); - if (connection_out != connection_in) { - if (fcntl(connection_out, F_SETFL, O_NONBLOCK) < 0) - error("fcntl O_NONBLOCK: %.100s", strerror(errno)); - } + if (connection_out != connection_in) + set_nonblock(connection_out); } /* Returns the socket used for reading. */ @@ -508,7 +507,7 @@ packet_send1(void) u_char buf[8], *cp; int i, padding, len; u_int checksum; - u_int32_t rand = 0; + u_int32_t rnd = 0; /* * If using packet compression, compress the payload of the outgoing @@ -534,9 +533,9 @@ packet_send1(void) cp = buffer_ptr(&outgoing_packet); for (i = 0; i < padding; i++) { if (i % 4 == 0) - rand = arc4random(); - cp[7 - i] = rand & 0xff; - rand >>= 8; + rnd = arc4random(); + cp[7 - i] = rnd & 0xff; + rnd >>= 8; } } buffer_consume(&outgoing_packet, 8 - padding); @@ -581,18 +580,18 @@ set_newkeys(int mode) Comp *comp; CipherContext *cc; u_int64_t *max_blocks; - int encrypt; + int crypt_type; debug2("set_newkeys: mode %d", mode); if (mode == MODE_OUT) { cc = &send_context; - encrypt = CIPHER_ENCRYPT; + crypt_type = CIPHER_ENCRYPT; p_send.packets = p_send.blocks = 0; max_blocks = &max_blocks_out; } else { cc = &receive_context; - encrypt = CIPHER_DECRYPT; + crypt_type = CIPHER_DECRYPT; p_read.packets = p_read.blocks = 0; max_blocks = &max_blocks_in; } @@ -621,7 +620,7 @@ set_newkeys(int mode) mac->enabled = 1; DBG(debug("cipher_init_context: %d", mode)); cipher_init(cc, enc->cipher, enc->key, enc->key_len, - enc->iv, enc->block_size, encrypt); + enc->iv, enc->block_size, crypt_type); /* Deleting the keys does not gain extra security */ /* memset(enc->iv, 0, enc->block_size); memset(enc->key, 0, enc->key_len); */ @@ -655,7 +654,7 @@ packet_send2_wrapped(void) u_char padlen, pad; u_int packet_length = 0; u_int i, len; - u_int32_t rand = 0; + u_int32_t rnd = 0; Enc *enc = NULL; Mac *mac = NULL; Comp *comp = NULL; @@ -714,9 +713,9 @@ packet_send2_wrapped(void) /* random padding */ for (i = 0; i < padlen; i++) { if (i % 4 == 0) - rand = arc4random(); - cp[i] = rand & 0xff; - rand >>= 8; + rnd = arc4random(); + cp[i] = rnd & 0xff; + rnd >>= 8; } } else { /* clear padding */ @@ -1449,7 +1448,7 @@ packet_is_interactive(void) return interactive_mode; } -u_int +int packet_set_maxsize(u_int s) { static int called = 0; @@ -1490,20 +1489,20 @@ packet_add_padding(u_char pad) void packet_send_ignore(int nbytes) { - u_int32_t rand = 0; + u_int32_t rnd = 0; int i; packet_start(compat20 ? SSH2_MSG_IGNORE : SSH_MSG_IGNORE); packet_put_int(nbytes); for (i = 0; i < nbytes; i++) { if (i % 4 == 0) - rand = arc4random(); - packet_put_char(rand & 0xff); - rand >>= 8; + rnd = arc4random(); + packet_put_char(rnd & 0xff); + rnd >>= 8; } } -#define MAX_PACKETS (1<<31) +#define MAX_PACKETS (1U<<31) int packet_need_rekeying(void) { diff --git a/openssh/packet.h b/openssh/packet.h index 7732faf..37f82f2 100644 --- a/openssh/packet.h +++ b/openssh/packet.h @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.h,v 1.40 2003/06/24 08:23:46 markus Exp $ */ +/* $OpenBSD: packet.h,v 1.41 2004/05/11 19:01:43 deraadt Exp $ */ /* * Author: Tatu Ylonen @@ -82,7 +82,7 @@ void tty_make_modes(int, struct termios *); void tty_parse_modes(int, int *); extern u_int max_packet_size; -u_int packet_set_maxsize(u_int); +int packet_set_maxsize(u_int); #define packet_get_maxsize() max_packet_size /* don't allow remaining bytes after the end of the message */ diff --git a/openssh/pathnames.h b/openssh/pathnames.h index 53208cf..cf42625 100644 --- a/openssh/pathnames.h +++ b/openssh/pathnames.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pathnames.h,v 1.14 2004/01/30 09:48:57 markus Exp $ */ +/* $OpenBSD: pathnames.h,v 1.15 2004/07/11 17:48:47 deraadt Exp $ */ /* * Author: Tatu Ylonen @@ -122,7 +122,7 @@ /* Location of ssh-keysign for hostbased authentication */ #ifndef _PATH_SSH_KEY_SIGN -#define _PATH_SSH_KEY_SIGN "/usr/libexec/ssh-keysign" +#define _PATH_SSH_KEY_SIGN "/usr/libexec/ssh-keysign" #endif /* xauth for X11 forwarding */ diff --git a/openssh/progressmeter.c b/openssh/progressmeter.c index f426685..93f5a3e 100644 --- a/openssh/progressmeter.c +++ b/openssh/progressmeter.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: progressmeter.c,v 1.19 2004/02/05 15:33:33 markus Exp $"); +RCSID("$OpenBSD: progressmeter.c,v 1.22 2004/07/11 17:48:47 deraadt Exp $"); #include "progressmeter.h" #include "atomicio.h" @@ -48,15 +48,15 @@ void refresh_progress_meter(void); /* signal handler for updating the progress meter */ static void update_progress_meter(int); -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 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 */ +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 */ /* units for format_size */ static const char unit[] = " KMGT"; @@ -167,7 +167,7 @@ refresh_progress_meter(void) /* bandwidth usage */ format_rate(buf + strlen(buf), win_size - strlen(buf), - bytes_per_second); + (off_t)bytes_per_second); strlcat(buf, "/s ", win_size); /* ETA */ @@ -224,7 +224,7 @@ update_progress_meter(int ignore) } void -start_progress_meter(char *f, off_t filesize, off_t *stat) +start_progress_meter(char *f, off_t filesize, off_t *ctr) { struct winsize winsize; @@ -232,7 +232,7 @@ start_progress_meter(char *f, off_t filesize, off_t *stat) file = f; end_pos = filesize; cur_pos = 0; - counter = stat; + counter = ctr; stalled = 0; bytes_per_second = 0; diff --git a/openssh/readconf.c b/openssh/readconf.c index ce0d1f7..a4fe1fe 100644 --- a/openssh/readconf.c +++ b/openssh/readconf.c @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: readconf.c,v 1.128 2004/03/05 10:53:58 markus Exp $"); +RCSID("$OpenBSD: readconf.c,v 1.134 2004/07/11 17:48:47 deraadt Exp $"); #include "ssh.h" #include "xmalloc.h" @@ -106,6 +106,7 @@ typedef enum { oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, oAddressFamily, oGssAuthentication, oGssDelegateCreds, oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, + oSendEnv, oControlPath, oControlMaster, oDeprecated, oUnsupported } OpCodes; @@ -193,6 +194,9 @@ static struct { { "addressfamily", oAddressFamily }, { "serveraliveinterval", oServerAliveInterval }, { "serveralivecountmax", oServerAliveCountMax }, + { "sendenv", oSendEnv }, + { "controlpath", oControlPath }, + { "controlmaster", oControlMaster }, { NULL, oBadOption } }; @@ -749,6 +753,27 @@ parse_int: intptr = &options->server_alive_count_max; goto parse_int; + case oSendEnv: + while ((arg = strdelim(&s)) != NULL && *arg != '\0') { + if (strchr(arg, '=') != NULL) + fatal("%s line %d: Invalid environment name.", + filename, linenum); + if (options->num_send_env >= MAX_SEND_ENV) + fatal("%s line %d: too many send env.", + filename, linenum); + options->send_env[options->num_send_env++] = + xstrdup(arg); + } + break; + + case oControlPath: + charptr = &options->control_path; + goto parse_string; + + case oControlMaster: + intptr = &options->control_master; + goto parse_yesnoask; + case oDeprecated: debug("%s line %d: Deprecated option \"%s\"", filename, linenum, keyword); @@ -779,7 +804,8 @@ parse_int: */ int -read_config_file(const char *filename, const char *host, Options *options) +read_config_file(const char *filename, const char *host, Options *options, + int checkperm) { FILE *f; char line[1024]; @@ -787,10 +813,19 @@ read_config_file(const char *filename, const char *host, Options *options) int bad_options = 0; /* Open the file. */ - f = fopen(filename, "r"); - if (!f) + if ((f = fopen(filename, "r")) == NULL) return 0; + if (checkperm) { + struct stat sb; + + if (fstat(fileno(f), &sb) == -1) + fatal("fstat %s: %s", filename, strerror(errno)); + if (((sb.st_uid != 0 && sb.st_uid != getuid()) || + (sb.st_mode & 022) != 0)) + fatal("Bad owner or permissions on %s", filename); + } + debug("Reading configuration data %.200s", filename); /* @@ -879,6 +914,9 @@ initialize_options(Options * options) options->verify_host_key_dns = -1; options->server_alive_interval = -1; options->server_alive_count_max = -1; + options->num_send_env = 0; + options->control_path = NULL; + options->control_master = -1; } /* @@ -999,6 +1037,8 @@ fill_default_options(Options * options) options->server_alive_interval = 0; if (options->server_alive_count_max == -1) options->server_alive_count_max = 3; + if (options->control_master == -1) + options->control_master = 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 */ diff --git a/openssh/readconf.h b/openssh/readconf.h index 93d833c..ded4225 100644 --- a/openssh/readconf.h +++ b/openssh/readconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.h,v 1.60 2004/03/05 10:53:58 markus Exp $ */ +/* $OpenBSD: readconf.h,v 1.64 2004/07/11 17:48:47 deraadt Exp $ */ /* * Author: Tatu Ylonen @@ -27,6 +27,8 @@ typedef struct { } Forward; /* Data structure for representing option data. */ +#define MAX_SEND_ENV 256 + typedef struct { int forward_agent; /* Forward authentication agent. */ int forward_x11; /* Forward X11 display. */ @@ -101,14 +103,20 @@ typedef struct { int rekey_limit; int no_host_authentication_for_localhost; int identities_only; - int server_alive_interval; + int server_alive_interval; int server_alive_count_max; + + int num_send_env; + char *send_env[MAX_SEND_ENV]; + + char *control_path; + int control_master; } Options; void initialize_options(Options *); void fill_default_options(Options *); -int read_config_file(const char *, const char *, Options *); +int read_config_file(const char *, const char *, Options *, int); int process_config_line(Options *, const char *, char *, const char *, int, int *); diff --git a/openssh/readpass.c b/openssh/readpass.c index 95ec5d8..eb4f6fd 100644 --- a/openssh/readpass.c +++ b/openssh/readpass.c @@ -23,10 +23,10 @@ */ #include "includes.h" -RCSID("$OpenBSD: readpass.c,v 1.28 2003/01/23 13:50:27 markus Exp $"); +RCSID("$OpenBSD: readpass.c,v 1.30 2004/06/17 15:10:14 djm Exp $"); #include "xmalloc.h" -#include "readpass.h" +#include "misc.h" #include "pathnames.h" #include "log.h" #include "ssh.h" @@ -103,7 +103,9 @@ read_passphrase(const char *prompt, int flags) int rppflags, use_askpass = 0, ttyfd; rppflags = (flags & RP_ECHO) ? RPP_ECHO_ON : RPP_ECHO_OFF; - if (flags & RP_ALLOW_STDIN) { + if (flags & RP_USE_ASKPASS) + use_askpass = 1; + else if (flags & RP_ALLOW_STDIN) { if (!isatty(STDIN_FILENO)) use_askpass = 1; } else { @@ -115,6 +117,9 @@ read_passphrase(const char *prompt, int flags) use_askpass = 1; } + if ((flags & RP_USE_ASKPASS) && getenv("DISPLAY") == NULL) + return (flags & RP_ALLOW_EOF) ? NULL : xstrdup(""); + if (use_askpass && getenv("DISPLAY")) { if (getenv(SSH_ASKPASS_ENV)) askpass = getenv(SSH_ASKPASS_ENV); diff --git a/openssh/regress/Makefile b/openssh/regress/Makefile index cf65b36..9e98e58 100644 --- a/openssh/regress/Makefile +++ b/openssh/regress/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.27 2004/02/17 08:23:20 dtucker Exp $ +# $OpenBSD: Makefile,v 1.31 2004/06/24 19:32:00 djm Exp $ REGRESS_TARGETS= t1 t2 t3 t4 t5 t6 t7 t-exec tests: $(REGRESS_TARGETS) @@ -13,6 +13,7 @@ LTESTS= connect \ proto-version \ proto-mismatch \ exit-status \ + envpass \ transfer \ banner \ rekey \ @@ -28,13 +29,16 @@ LTESTS= connect \ agent-ptrace \ keyscan \ keygen-change \ + scp \ sftp \ sftp-cmds \ sftp-badcmds \ sftp-batch \ reconfigure \ dynamic-forward \ - forwarding + forwarding \ + multiplex \ + reexec USER!= id -un CLEANFILES= t2.out t6.out1 t6.out2 t7.out t7.out.pub copy.1 copy.2 \ @@ -42,7 +46,9 @@ CLEANFILES= t2.out t6.out1 t6.out2 t7.out t7.out.pub copy.1 copy.2 \ ssh_config ssh_proxy sshd_config sshd_proxy \ rsa.pub rsa rsa1.pub rsa1 host.rsa host.rsa1 \ rsa-agent rsa-agent.pub rsa1-agent rsa1-agent.pub \ - ls.copy banner.in banner.out empty.in remote_pid + ls.copy banner.in banner.out empty.in \ + scp-ssh-wrapper.exe \ + remote_pid #LTESTS += ssh-com ssh-com-client ssh-com-keygen ssh-com-sftp diff --git a/openssh/regress/README.regress b/openssh/regress/README.regress index 86311e7..6934fa7 100644 --- a/openssh/regress/README.regress +++ b/openssh/regress/README.regress @@ -27,15 +27,26 @@ TEST_SSH_QUIET: set to "yes" to suppress non-fatal output. TEST_SSH_x: path to "ssh" command under test, where x=SSH,SSHD,SSHAGENT,SSHADD SSHKEYGEN,SSHKEYSCAN,SFTP,SFTPSERVER OBJ: used by test scripts to access build dir. +TEST_SHELL: shell used for running the test scripts. +TEST_SSH_PORT: TCP port to be used for the listening tests. +TEST_SSH_SSH_CONFOTPS: Configuration directives to be added to ssh_config + before running each test. +TEST_SSH_SSHD_CONFOTPS: Configuration directives to be added to sshd_config + before running each test. Individual tests. -You can invoke test-exec.sh directly if you set up the path to find the -binaries under test and the test scripts themselves, for example: +You can run an individual test from the top-level Makefile, eg: +$ make tests LTESTS=agent-timeout + +If you need to manipulate the environment more you can invoke test-exec.sh +directly if you set up the path to find the binaries under test and the +test scripts themselves, for example: $ cd regress -$ PATH=`pwd`/..:$PATH:. sh test-exec.sh `pwd` agent-timeout.sh +$ PATH=`pwd`/..:$PATH:. TEST_SHELL=/bin/sh sh test-exec.sh `pwd` \ + agent-timeout.sh ok agent timeout test @@ -82,16 +93,12 @@ Failed tests can be difficult to diagnose. Suggestions: Known Issues. -- If you build with tcpwrappers and try to run the regression tests, - your hosts.allow must permit connections from localhost and from - "unknown". This is because some tests are performed via the loopback - interface, while others are done with "sshd -i" as a ProxyCommand. In - the latter case, when sshd calls getpeername() on the socket it will - fail (because it's not a tcp socket) and will be identified as - "unknown", which is then checked against tcpwrappers. - - If your build requires ssh-rand-helper regress tests will fail unless ssh-rand-helper is in pre-installed (the path to ssh-rand-helper is hard coded). +- Recent GNU coreutils deprecate "head -[n]": this will cause the yes-head + test to fail. The old behaviour can be restored by setting (and + exporting) _POSIX2_VERSION=199209 before running the tests. + $Id$ diff --git a/openssh/regress/dynamic-forward.sh b/openssh/regress/dynamic-forward.sh index 3a6e5c1..392fc19 100644 --- a/openssh/regress/dynamic-forward.sh +++ b/openssh/regress/dynamic-forward.sh @@ -3,8 +3,8 @@ tid="dynamic forwarding" -PORT=4242 -FWDPORT=4243 +FWDPORT=`expr $PORT + 1` + DATA=/bin/ls${EXEEXT} if have_prog nc && nc -h 2>&1 | grep "proxy address" >/dev/null; then diff --git a/openssh/regress/envpass.sh b/openssh/regress/envpass.sh new file mode 100644 index 0000000..5a7e178 --- /dev/null +++ b/openssh/regress/envpass.sh @@ -0,0 +1,51 @@ +# $OpenBSD: envpass.sh,v 1.3 2004/06/22 22:42:02 dtucker Exp $ +# Placed in the Public Domain. + +tid="environment passing" + +# NB accepted env vars are in test-exec.sh (_XXX_TEST_* and _XXX_TEST) + +trace "pass env, don't accept" +verbose "test $tid: pass env, don't accept" +_TEST_ENV=blah ${SSH} -oSendEnv="*" -F $OBJ/ssh_proxy otherhost \ + sh << 'EOF' + test -z "$_TEST_ENV" +EOF +r=$? +if [ $r -ne 0 ]; then + fail "environment found" +fi + +trace "don't pass env, accept" +verbose "test $tid: don't pass env, accept" +${SSH} -F $OBJ/ssh_proxy otherhost \ + sh << 'EOF' + test -z "$_XXX_TEST_A" && test -z "$_XXX_TEST_B" +EOF +r=$? +if [ $r -ne 0 ]; then + fail "environment found" +fi + +trace "pass single env, accept single env" +verbose "test $tid: pass single env, accept single env" +_XXX_TEST=blah ${SSH} -oSendEnv="_XXX_TEST" -F $OBJ/ssh_proxy otherhost \ + sh << 'EOF' + test X"$_XXX_TEST" = X"blah" +EOF +r=$? +if [ $r -ne 0 ]; then + fail "environment not found" +fi + +trace "pass multiple env, accept multiple env" +verbose "test $tid: pass multiple env, accept multiple env" +_XXX_TEST_A=1 _XXX_TEST_B=2 ${SSH} -oSendEnv="_XXX_TEST_*" \ + -F $OBJ/ssh_proxy otherhost \ + sh << 'EOF' + test X"$_XXX_TEST_A" = X"1" -a X"$_XXX_TEST_B" = X"2" +EOF +r=$? +if [ $r -ne 0 ]; then + fail "environment not found" +fi diff --git a/openssh/regress/login-timeout.sh b/openssh/regress/login-timeout.sh index dfc6e6b..ce6edad 100644 --- a/openssh/regress/login-timeout.sh +++ b/openssh/regress/login-timeout.sh @@ -1,4 +1,4 @@ -# $OpenBSD: login-timeout.sh,v 1.1 2004/02/17 08:23:20 dtucker Exp $ +# $OpenBSD: login-timeout.sh,v 1.3 2004/03/08 10:17:12 dtucker Exp $ # Placed in the Public Domain. tid="connect after login grace timeout" @@ -15,7 +15,7 @@ if [ $? -ne 0 ]; then fail "ssh connect after login grace timeout failed with privsep" fi -kill `cat $PIDFILE` +$SUDO kill `cat $PIDFILE` trace "test login grace without privsep" echo "UsePrivilegeSeparation no" >> $OBJ/sshd_config diff --git a/openssh/regress/multiplex.sh b/openssh/regress/multiplex.sh new file mode 100644 index 0000000..dbf2025 --- /dev/null +++ b/openssh/regress/multiplex.sh @@ -0,0 +1,74 @@ +# $OpenBSD: multiplex.sh,v 1.8 2004/06/22 03:12:13 markus Exp $ +# Placed in the Public Domain. + +CTL=$OBJ/ctl-sock + +tid="connection multiplexing" + +DATA=/bin/ls${EXEEXT} +COPY=$OBJ/ls.copy + +start_sshd + +trace "start master, fork to background" +${SSH} -2 -MS$CTL -F $OBJ/ssh_config -oSendEnv="_XXX_TEST" -f somehost sleep 120 + +verbose "test $tid: envpass" +trace "env passing over multiplexed connection" +_XXX_TEST=blah ${SSH} -oSendEnv="_XXX_TEST" -S$CTL otherhost sh << 'EOF' + test X"$_XXX_TEST" = X"blah" +EOF +if [ $? -ne 0 ]; then + fail "environment not found" +fi + +verbose "test $tid: transfer" +rm -f ${COPY} +trace "ssh transfer over multiplexed connection and check result" +${SSH} -S$CTL otherhost cat ${DATA} > ${COPY} +test -f ${COPY} || fail "ssh -Sctl: failed copy ${DATA}" +cmp ${DATA} ${COPY} || fail "ssh -Sctl: corrupted copy of ${DATA}" + +rm -f ${COPY} +trace "ssh transfer over multiplexed connection and check result" +${SSH} -S $CTL otherhost cat ${DATA} > ${COPY} +test -f ${COPY} || fail "ssh -S ctl: failed copy ${DATA}" +cmp ${DATA} ${COPY} || fail "ssh -S ctl: corrupted copy of ${DATA}" + +rm -f ${COPY} +trace "sftp transfer over multiplexed connection and check result" +echo "get ${DATA} ${COPY}" | \ + ${SFTP} -S ${SSH} -oControlPath=$CTL otherhost >/dev/null 2>&1 +test -f ${COPY} || fail "sftp: failed copy ${DATA}" +cmp ${DATA} ${COPY} || fail "sftp: corrupted copy of ${DATA}" + +rm -f ${COPY} +trace "scp transfer over multiplexed connection and check result" +${SCP} -S ${SSH} -oControlPath=$CTL otherhost:${DATA} ${COPY} >/dev/null 2>&1 +test -f ${COPY} || fail "scp: failed copy ${DATA}" +cmp ${DATA} ${COPY} || fail "scp: corrupted copy of ${DATA}" + +rm -f ${COPY} + +for s in 0 1 4 5 44; do + trace "exit status $s over multiplexed connection" + verbose "test $tid: status $s" + ${SSH} -S $CTL otherhost exit $s + r=$? + if [ $r -ne $s ]; then + fail "exit code mismatch for protocol $p: $r != $s" + fi + + # same with early close of stdout/err + trace "exit status $s with early close over multiplexed connection" + ${SSH} -S $CTL -n otherhost \ + exec sh -c \'"sleep 2; exec > /dev/null 2>&1; sleep 3; exit $s"\' + r=$? + if [ $r -ne $s ]; then + fail "exit code (with sleep) mismatch for protocol $p: $r != $s" + fi +done + +# kill master, remove control socket. ssh -MS will exit when sleep exits +$SUDO kill `cat $PIDFILE` +rm -f $CTL diff --git a/openssh/regress/reexec.sh b/openssh/regress/reexec.sh new file mode 100644 index 0000000..39fffef --- /dev/null +++ b/openssh/regress/reexec.sh @@ -0,0 +1,87 @@ +# $OpenBSD: reexec.sh,v 1.3 2004/06/25 01:32:44 djm Exp $ +# Placed in the Public Domain. + +tid="reexec tests" + +DATA=/bin/ls +COPY=${OBJ}/copy +SSHD_ORIG=$SSHD +SSHD_COPY=$OBJ/sshd.copy + +# Start a sshd and then delete it +start_sshd_copy_zap () +{ + cp $SSHD_ORIG $SSHD_COPY + SSHD=$SSHD_COPY + start_sshd + rm -f $SSHD_COPY + SSHD=$SSHD_ORIG +} + +verbose "test config passing" +cp $OBJ/sshd_config $OBJ/sshd_config.orig + +start_sshd + +echo "InvalidXXX=no" >> $OBJ/sshd_config + +rm -f ${COPY} +for p in 1 2; do + verbose "$tid: proto $p" + ${SSH} -nqo "Protocol=$p" -F $OBJ/ssh_config somehost \ + cat ${DATA} > ${COPY} + if [ $? -ne 0 ]; then + fail "ssh cat $DATA failed" + fi + cmp ${DATA} ${COPY} || fail "corrupted copy" + rm -f ${COPY} +done + +$SUDO kill `cat $PIDFILE` +rm -f $PIDFILE + +cp $OBJ/sshd_config.orig $OBJ/sshd_config + +verbose "test reexec fallback" + +start_sshd_copy_zap + +rm -f ${COPY} +for p in 1 2; do + verbose "$tid: proto $p" + ${SSH} -nqo "Protocol=$p" -F $OBJ/ssh_config somehost \ + cat ${DATA} > ${COPY} + if [ $? -ne 0 ]; then + fail "ssh cat $DATA failed" + fi + cmp ${DATA} ${COPY} || fail "corrupted copy" + rm -f ${COPY} +done + +$SUDO kill `cat $PIDFILE` +rm -f $PIDFILE + +verbose "test reexec fallback without privsep" + +cp $OBJ/sshd_config.orig $OBJ/sshd_config +echo "UsePrivilegeSeparation=no" >> $OBJ/sshd_config + +start_sshd_copy_zap + +rm -f ${COPY} +for p in 1 2; do + verbose "$tid: proto $p" + ${SSH} -nqo "Protocol=$p" -F $OBJ/ssh_config somehost \ + cat ${DATA} > ${COPY} + if [ $? -ne 0 ]; then + fail "ssh cat $DATA failed" + fi + cmp ${DATA} ${COPY} || fail "corrupted copy" + rm -f ${COPY} +done + +$SUDO kill `cat $PIDFILE` +rm -f $PIDFILE + +cp $OBJ/sshd_config.orig $OBJ/sshd_config + diff --git a/openssh/regress/scp-ssh-wrapper.sh b/openssh/regress/scp-ssh-wrapper.sh new file mode 100644 index 0000000..8e43147 --- /dev/null +++ b/openssh/regress/scp-ssh-wrapper.sh @@ -0,0 +1,54 @@ +#!/bin/sh +# $OpenBSD: scp-ssh-wrapper.sh,v 1.1 2004/06/13 13:51:02 dtucker Exp $ +# Placed in the Public Domain. + +printname () { + NAME=$1 + save_IFS=$IFS + IFS=/ + set -- `echo "$NAME"` + IFS="$save_IFS" + while [ $# -ge 1 ] ; do + if [ "x$1" != "x" ]; then + echo "D0755 0 $1" + fi + shift; + done +} + +# discard first 5 args +shift; shift; shift; shift; shift + +BAD="../../../../../../../../../../../../../${DIR}/dotpathdir" + +case "$SCPTESTMODE" in +badserver_0) + echo "D0755 0 /${DIR}/rootpathdir" + echo "C755 2 rootpathfile" + echo "X" + ;; +badserver_1) + echo "D0755 0 $BAD" + echo "C755 2 file" + echo "X" + ;; +badserver_2) + echo "D0755 0 $BAD" + echo "C755 2 file" + echo "X" + ;; +badserver_3) + printname $BAD + echo "C755 2 file" + echo "X" + ;; +badserver_4) + printname $BAD + echo "D0755 0 .." + echo "C755 2 file" + echo "X" + ;; +*) + exec $1 + ;; +esac diff --git a/openssh/regress/scp.sh b/openssh/regress/scp.sh new file mode 100644 index 0000000..703cc08 --- /dev/null +++ b/openssh/regress/scp.sh @@ -0,0 +1,82 @@ +# $OpenBSD: scp.sh,v 1.2 2004/06/16 13:15:09 dtucker Exp $ +# Placed in the Public Domain. + +tid="scp" + +#set -x + +# Figure out if diff understands "-N" +if diff -N ${SRC}/scp.sh ${SRC}/scp.sh 2>/dev/null; then + DIFFOPT="-rN" +else + DIFFOPT="-r" +fi + +DATA=/bin/ls +COPY=${OBJ}/copy +COPY2=${OBJ}/copy2 +DIR=${COPY}.dd +DIR2=${COPY}.dd2 + +SRC=`dirname ${SCRIPT}` +cp ${SRC}/scp-ssh-wrapper.sh ${OBJ}/scp-ssh-wrapper.exe +chmod 755 ${OBJ}/scp-ssh-wrapper.exe +scpopts="-q -S ${OBJ}/scp-ssh-wrapper.exe" + +scpclean() { + rm -rf ${COPY} ${COPY2} ${DIR} ${DIR2} + mkdir ${DIR} ${DIR2} +} + +verbose "$tid: simple copy local file to remote file" +scpclean +$SCP $scpopts ${DATA} somehost:${COPY} || fail "copy failed" +cmp ${DATA} ${COPY} || fail "corrupted copy" + +verbose "$tid: simple copy remote file to local file" +scpclean +$SCP $scpopts somehost:${DATA} ${COPY} || fail "copy failed" +cmp ${DATA} ${COPY} || fail "corrupted copy" + +verbose "$tid: simple copy local file to remote dir" +scpclean +cp ${DATA} ${COPY} +$SCP $scpopts ${COPY} somehost:${DIR} || fail "copy failed" +cmp ${COPY} ${DIR}/copy || fail "corrupted copy" + +verbose "$tid: simple copy remote file to local dir" +scpclean +cp ${DATA} ${COPY} +$SCP $scpopts somehost:${COPY} ${DIR} || fail "copy failed" +cmp ${COPY} ${DIR}/copy || fail "corrupted copy" + +verbose "$tid: recursive local dir to remote dir" +scpclean +rm -rf ${DIR2} +cp ${DATA} ${DIR}/copy +$SCP $scpopts -r ${DIR} somehost:${DIR2} || fail "copy failed" +diff ${DIFFOPT} ${DIR} ${DIR2} || fail "corrupted copy" + +verbose "$tid: recursive remote dir to local dir" +scpclean +rm -rf ${DIR2} +cp ${DATA} ${DIR}/copy +$SCP $scpopts -r somehost:${DIR} ${DIR2} || fail "copy failed" +diff ${DIFFOPT} ${DIR} ${DIR2} || fail "corrupted copy" + +for i in 0 1 2 3 4; do + verbose "$tid: disallow bad server #$i" + SCPTESTMODE=badserver_$i + export DIR SCPTESTMODE + scpclean + $SCP $scpopts somehost:${DATA} ${DIR} >/dev/null 2>/dev/null + [ -d {$DIR}/rootpathdir ] && fail "allows dir relative to root dir" + [ -d ${DIR}/dotpathdir ] && fail "allows dir creation in non-recursive mode" + + scpclean + $SCP -r $scpopts somehost:${DATA} ${DIR2} >/dev/null 2>/dev/null + [ -d ${DIR}/dotpathdir ] && fail "allows dir creation outside of subdir" +done + +scpclean +rm -f ${OBJ}/scp-ssh-wrapper.exe diff --git a/openssh/regress/test-exec.sh b/openssh/regress/test-exec.sh index 986d992..70250ac 100644 --- a/openssh/regress/test-exec.sh +++ b/openssh/regress/test-exec.sh @@ -1,9 +1,14 @@ -# $OpenBSD: test-exec.sh,v 1.15 2004/02/24 16:56:30 markus Exp $ +# $OpenBSD: test-exec.sh,v 1.23 2004/06/25 01:25:12 djm Exp $ # Placed in the Public Domain. -PORT=4242 #SUDO=sudo +if [ ! -z "$TEST_SSH_PORT" ]; then + PORT="$TEST_SSH_PORT" +else + PORT=4242 +fi + if [ -x /usr/ucb/whoami ]; then USER=`/usr/ucb/whoami` elif whoami >/dev/null 2>&1; then @@ -47,6 +52,7 @@ SSHKEYGEN=ssh-keygen SSHKEYSCAN=ssh-keyscan SFTP=sftp SFTPSERVER=/usr/libexec/openssh/sftp-server +SCP=scp if [ "x$TEST_SSH_SSH" != "x" ]; then SSH="${TEST_SSH_SSH}" @@ -72,10 +78,16 @@ fi if [ "x$TEST_SSH_SFTPSERVER" != "x" ]; then SFTPSERVER="${TEST_SSH_SFTPSERVER}" fi +if [ "x$TEST_SSH_SCP" != "x" ]; then + SCP="${TEST_SSH_SCP}" +fi + +# Path to sshd must be absolute for rexec +SSHD=`which sshd` # these should be used in tests -export SSH SSHD SSHAGENT SSHADD SSHKEYGEN SSHKEYSCAN SFTP SFTPSERVER -#echo $SSH $SSHD $SSHAGENT $SSHADD $SSHKEYGEN $SSHKEYSCAN $SFTP $SFTPSERVER +export SSH SSHD SSHAGENT SSHADD SSHKEYGEN SSHKEYSCAN SFTP SFTPSERVER SCP +#echo $SSH $SSHD $SSHAGENT $SSHADD $SSHKEYGEN $SSHKEYSCAN $SFTP $SFTPSERVER $SCP # helper echon() @@ -156,15 +168,23 @@ trap fatal 3 2 # create server config cat << EOF > $OBJ/sshd_config + StrictModes no Port $PORT ListenAddress 127.0.0.1 #ListenAddress ::1 PidFile $PIDFILE AuthorizedKeysFile $OBJ/authorized_keys_%u LogLevel QUIET - StrictModes no + AcceptEnv _XXX_TEST_* + AcceptEnv _XXX_TEST + Subsystem sftp $SFTPSERVER EOF +if [ ! -z "$TEST_SSH_SSHD_CONFOPTS" ]; then + trace "adding sshd_config option $TEST_SSH_SSHD_CONFOPTS" + echo "$TEST_SSH_SSHD_CONFOPTS" >> $OBJ/sshd_config +fi + # server config for proxy connects cp $OBJ/sshd_config $OBJ/sshd_proxy @@ -190,6 +210,11 @@ Host * StrictHostKeyChecking yes EOF +if [ ! -z "$TEST_SSH_SSH_CONFOPTS" ]; then + trace "adding ssh_config option $TEST_SSH_SSHD_CONFOPTS" + echo "$TEST_SSH_SSH_CONFOPTS" >> $OBJ/ssh_config +fi + rm -f $OBJ/known_hosts $OBJ/authorized_keys_$USER trace "generate keys" diff --git a/openssh/regress/try-ciphers.sh b/openssh/regress/try-ciphers.sh index 15827e2..c6e1b91 100644 --- a/openssh/regress/try-ciphers.sh +++ b/openssh/regress/try-ciphers.sh @@ -29,8 +29,10 @@ for c in $ciphers; do fi done -if ! ${SSH} -oCiphers=acss@openssh.org 2>&1 | grep "Bad SSH2 cipher" >/dev/null +if ${SSH} -oCiphers=acss@openssh.org 2>&1 | grep "Bad SSH2 cipher" >/dev/null then + : +else echo "Ciphers acss@openssh.org" >> $OBJ/sshd_proxy c=acss@openssh.org diff --git a/openssh/rijndael.c b/openssh/rijndael.c index 1cd24de..7432ea2 100644 --- a/openssh/rijndael.c +++ b/openssh/rijndael.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rijndael.c,v 1.15 2003/11/21 11:57:03 djm Exp $ */ +/* $OpenBSD: rijndael.c,v 1.16 2004/06/23 00:39:38 mouring Exp $ */ /** * rijndael-alg-fst.c @@ -1218,10 +1218,10 @@ static void rijndaelDecrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 ct[16 } void -rijndael_set_key(rijndael_ctx *ctx, u_char *key, int bits, int encrypt) +rijndael_set_key(rijndael_ctx *ctx, u_char *key, int bits, int do_encrypt) { ctx->Nr = rijndaelKeySetupEnc(ctx->ek, key, bits); - if (encrypt) { + if (do_encrypt) { ctx->decrypt = 0; memset(ctx->dk, 0, sizeof(ctx->dk)); } else { diff --git a/openssh/scard-opensc.c b/openssh/scard-opensc.c index a9b7ebc..dd2c28d 100644 --- a/openssh/scard-opensc.c +++ b/openssh/scard-opensc.c @@ -35,7 +35,7 @@ #include "key.h" #include "log.h" #include "xmalloc.h" -#include "readpass.h" +#include "misc.h" #include "scard.h" #if OPENSSL_VERSION_NUMBER < 0x00907000L && defined(CRYPTO_LOCK_ENGINE) diff --git a/openssh/scard.c b/openssh/scard.c index 906287b..b3d2505 100644 --- a/openssh/scard.c +++ b/openssh/scard.c @@ -24,7 +24,7 @@ #include "includes.h" #if defined(SMARTCARD) && defined(USE_SECTOK) -RCSID("$OpenBSD: scard.c,v 1.28 2003/06/12 19:12:02 markus Exp $"); +RCSID("$OpenBSD: scard.c,v 1.29 2004/05/08 00:21:31 djm Exp $"); #include #include @@ -32,7 +32,7 @@ RCSID("$OpenBSD: scard.c,v 1.28 2003/06/12 19:12:02 markus Exp $"); #include "key.h" #include "log.h" #include "xmalloc.h" -#include "readpass.h" +#include "misc.h" #include "scard.h" #if OPENSSL_VERSION_NUMBER < 0x00907000L diff --git a/openssh/scp.1 b/openssh/scp.1 index 5a32211..f346b2a 100644 --- a/openssh/scp.1 +++ b/openssh/scp.1 @@ -9,7 +9,7 @@ .\" .\" Created: Sun May 7 00:14:37 1995 ylo .\" -.\" $OpenBSD: scp.1,v 1.33 2004/03/05 10:53:58 markus Exp $ +.\" $OpenBSD: scp.1,v 1.36 2004/06/13 15:03:02 djm Exp $ .\" .Dd September 25, 1999 .Dt SCP 1 @@ -127,7 +127,9 @@ For full details of the options listed below, and their possible values, see .It Compression .It CompressionLevel .It ConnectionAttempts -.It ConnectionTimeout +.It ConnectTimeout +.It ControlMaster +.It ControlPath .It GlobalKnownHostsFile .It GSSAPIAuthentication .It GSSAPIDelegateCredentials @@ -150,6 +152,7 @@ For full details of the options listed below, and their possible values, see .It PubkeyAuthentication .It RhostsRSAAuthentication .It RSAAuthentication +.It SendEnv .It ServerAliveInterval .It ServerAliveCountMax .It SmartcardDevice diff --git a/openssh/scp.c b/openssh/scp.c index 1daa2cc..ef9eaa1 100644 --- a/openssh/scp.c +++ b/openssh/scp.c @@ -71,7 +71,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: scp.c,v 1.113 2003/11/23 23:21:21 djm Exp $"); +RCSID("$OpenBSD: scp.c,v 1.117 2004/08/11 21:44:32 avsm Exp $"); #include "xmalloc.h" #include "atomicio.h" @@ -80,11 +80,7 @@ RCSID("$OpenBSD: scp.c,v 1.113 2003/11/23 23:21:21 djm Exp $"); #include "misc.h" #include "progressmeter.h" -#ifdef HAVE___PROGNAME extern char *__progname; -#else -char *__progname; -#endif void bwlimit(int); @@ -663,7 +659,7 @@ bwlimit(int amount) { static struct timeval bwstart, bwend; static int lamt, thresh = 16384; - u_int64_t wait; + u_int64_t waitlen; struct timespec ts, rm; if (!timerisset(&bwstart)) { @@ -681,10 +677,10 @@ bwlimit(int amount) return; lamt *= 8; - wait = (double)1000000L * lamt / limit_rate; + waitlen = (double)1000000L * lamt / limit_rate; - bwstart.tv_sec = wait / 1000000L; - bwstart.tv_usec = wait % 1000000L; + bwstart.tv_sec = waitlen / 1000000L; + bwstart.tv_usec = waitlen % 1000000L; if (timercmp(&bwstart, &bwend, >)) { timersub(&bwstart, &bwend, &bwend); @@ -759,6 +755,8 @@ sink(int argc, char **argv) *cp++ = ch; } while (cp < &buf[sizeof(buf) - 1] && ch != '\n'); *cp = 0; + if (verbose_mode) + fprintf(stderr, "Sink: %s", buf); if (buf[0] == '\01' || buf[0] == '\02') { if (iamremote == 0) @@ -822,6 +820,10 @@ sink(int argc, char **argv) size = size * 10 + (*cp++ - '0'); if (*cp++ != ' ') SCREWUP("size not delimited"); + if ((strchr(cp, '/') != NULL) || (strcmp(cp, "..") == 0)) { + run_err("error: unexpected filename: %s", cp); + exit(1); + } if (targisdir) { static char *namebuf; static int cursize; @@ -843,6 +845,8 @@ sink(int argc, char **argv) exists = stat(np, &stb) == 0; if (buf[0] == 'D') { int mod_flag = pflag; + if (!iamrecursive) + SCREWUP("received directory without -r"); if (exists) { if (!S_ISDIR(stb.st_mode)) { errno = ENOTDIR; @@ -894,11 +898,8 @@ bad: run_err("%s: %s", np, strerror(errno)); amt = size - i; count += amt; do { - j = read(remin, cp, amt); - if (j == -1 && (errno == EINTR || - errno == EAGAIN)) { - continue; - } else if (j <= 0) { + j = atomicio(read, remin, cp, amt); + if (j <= 0) { run_err("%s", j ? strerror(errno) : "dropped connection"); exit(1); @@ -938,21 +939,25 @@ bad: run_err("%s: %s", np, strerror(errno)); if (pflag) { if (exists || omode != mode) #ifdef HAVE_FCHMOD - if (fchmod(ofd, omode)) + if (fchmod(ofd, omode)) { #else /* HAVE_FCHMOD */ - if (chmod(np, omode)) + if (chmod(np, omode)) { #endif /* HAVE_FCHMOD */ run_err("%s: set mode: %s", np, strerror(errno)); + wrerr = DISPLAYED; + } } else { if (!exists && omode != mode) #ifdef HAVE_FCHMOD - if (fchmod(ofd, omode & ~mask)) + if (fchmod(ofd, omode & ~mask)) { #else /* HAVE_FCHMOD */ - if (chmod(np, omode & ~mask)) + if (chmod(np, omode & ~mask)) { #endif /* HAVE_FCHMOD */ run_err("%s: set mode: %s", np, strerror(errno)); + wrerr = DISPLAYED; + } } if (close(ofd) == -1) { wrerr = YES; diff --git a/openssh/servconf.c b/openssh/servconf.c index a72246b..fae3c65 100644 --- a/openssh/servconf.c +++ b/openssh/servconf.c @@ -10,7 +10,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: servconf.c,v 1.130 2003/12/23 16:12:10 jakob Exp $"); +RCSID("$OpenBSD: servconf.c,v 1.137 2004/08/13 11:09:24 dtucker Exp $"); #include "ssh.h" #include "log.h" @@ -18,7 +18,6 @@ RCSID("$OpenBSD: servconf.c,v 1.130 2003/12/23 16:12:10 jakob Exp $"); #include "xmalloc.h" #include "compat.h" #include "pathnames.h" -#include "tildexpand.h" #include "misc.h" #include "cipher.h" #include "kex.h" @@ -95,12 +94,14 @@ initialize_server_options(ServerOptions *options) options->max_startups_begin = -1; options->max_startups_rate = -1; options->max_startups = -1; + options->max_authtries = -1; options->banner = NULL; options->use_dns = -1; options->client_alive_interval = -1; options->client_alive_count_max = -1; options->authorized_keys_file = NULL; options->authorized_keys_file2 = NULL; + options->num_accept_env = 0; /* Needs to be accessable in many places */ use_privsep = -1; @@ -212,6 +213,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->max_authtries == -1) + options->max_authtries = DEFAULT_AUTH_FAIL_MAX; if (options->use_dns == -1) options->use_dns = 1; if (options->client_alive_interval == -1) @@ -262,11 +265,12 @@ typedef enum { sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, - sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups, + sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, + sMaxStartups, sMaxAuthTries, sBanner, sUseDNS, sHostbasedAuthentication, sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, - sGssAuthentication, sGssCleanupCreds, + sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sUsePrivilegeSeparation, sDeprecated, sUnsupported } ServerOpCodes; @@ -357,6 +361,7 @@ static struct { { "gatewayports", sGatewayPorts }, { "subsystem", sSubsystem }, { "maxstartups", sMaxStartups }, + { "maxauthtries", sMaxAuthTries }, { "banner", sBanner }, { "usedns", sUseDNS }, { "verifyreversemapping", sDeprecated }, @@ -366,6 +371,7 @@ static struct { { "authorizedkeysfile", sAuthorizedKeysFile }, { "authorizedkeysfile2", sAuthorizedKeysFile2 }, { "useprivilegeseparation", sUsePrivilegeSeparation}, + { "acceptenv", sAcceptEnv }, { NULL, sBadOption } }; @@ -868,6 +874,10 @@ parse_flag: options->max_startups = options->max_startups_begin; break; + case sMaxAuthTries: + intptr = &options->max_authtries; + goto parse_int; + case sBanner: charptr = &options->banner; goto parse_filename; @@ -892,6 +902,19 @@ parse_flag: intptr = &options->client_alive_count_max; goto parse_int; + case sAcceptEnv: + while ((arg = strdelim(&cp)) && *arg != '\0') { + if (strchr(arg, '=') != NULL) + fatal("%s line %d: Invalid environment name.", + filename, linenum); + if (options->num_accept_env >= MAX_ACCEPT_ENV) + fatal("%s line %d: too many allow env.", + filename, linenum); + options->accept_env[options->num_accept_env++] = + xstrdup(arg); + } + break; + case sDeprecated: logit("%s line %d: Deprecated option %s", filename, linenum, arg); @@ -919,26 +942,50 @@ parse_flag: /* Reads the server configuration file. */ void -read_server_config(ServerOptions *options, const char *filename) +load_server_config(const char *filename, Buffer *conf) { - int linenum, bad_options = 0; - char line[1024]; + char line[1024], *cp; FILE *f; - debug2("read_server_config: filename %s", filename); - f = fopen(filename, "r"); - if (!f) { + debug2("%s: filename %s", __func__, filename); + if ((f = fopen(filename, "r")) == NULL) { perror(filename); exit(1); } - linenum = 0; + buffer_clear(conf); while (fgets(line, sizeof(line), f)) { - /* Update line number counter. */ - linenum++; - if (process_server_config_line(options, line, filename, linenum) != 0) - bad_options++; + /* + * Trim out comments and strip whitespace + * NB - preserve newlines, they are needed to reproduce + * line numbers later for error messages + */ + if ((cp = strchr(line, '#')) != NULL) + memcpy(cp, "\n", 2); + cp = line + strspn(line, " \t\r"); + + buffer_append(conf, cp, strlen(cp)); } + buffer_append(conf, "\0", 1); fclose(f); + debug2("%s: done config len = %d", __func__, buffer_len(conf)); +} + +void +parse_server_config(ServerOptions *options, const char *filename, Buffer *conf) +{ + int linenum, bad_options = 0; + char *cp, *obuf, *cbuf; + + debug2("%s: config %s len %d", __func__, filename, buffer_len(conf)); + + obuf = cbuf = xstrdup(buffer_ptr(conf)); + linenum = 1; + while((cp = strsep(&cbuf, "\n")) != NULL) { + if (process_server_config_line(options, cp, filename, + linenum++) != 0) + bad_options++; + } + xfree(obuf); if (bad_options > 0) fatal("%s: terminating, %d bad configuration options", filename, bad_options); diff --git a/openssh/servconf.h b/openssh/servconf.h index 57c7e5f..ebd0568 100644 --- a/openssh/servconf.h +++ b/openssh/servconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.h,v 1.67 2003/12/23 16:12:10 jakob Exp $ */ +/* $OpenBSD: servconf.h,v 1.70 2004/06/24 19:30:54 djm Exp $ */ /* * Author: Tatu Ylonen @@ -16,6 +16,8 @@ #ifndef SERVCONF_H #define SERVCONF_H +#include "buffer.h" + #define MAX_PORTS 256 /* Max # ports. */ #define MAX_ALLOW_USERS 256 /* Max # users on allow list. */ @@ -24,6 +26,7 @@ #define MAX_DENY_GROUPS 256 /* Max # groups on deny list. */ #define MAX_SUBSYSTEMS 256 /* Max # subsystems. */ #define MAX_HOSTKEYS 256 /* Max # hostkeys. */ +#define MAX_ACCEPT_ENV 256 /* Max # of env vars. */ /* permit_root_login */ #define PERMIT_NOT_SET -1 @@ -32,6 +35,7 @@ #define PERMIT_NO_PASSWD 2 #define PERMIT_YES 3 +#define DEFAULT_AUTH_FAIL_MAX 6 /* Default for MaxAuthTries */ typedef struct { u_int num_ports; @@ -107,9 +111,13 @@ typedef struct { char *subsystem_name[MAX_SUBSYSTEMS]; char *subsystem_command[MAX_SUBSYSTEMS]; + u_int num_accept_env; + char *accept_env[MAX_ACCEPT_ENV]; + int max_startups_begin; int max_startups_rate; int max_startups; + int max_authtries; char *banner; /* SSH-2 banner message */ int use_dns; int client_alive_interval; /* @@ -128,9 +136,9 @@ typedef struct { } ServerOptions; void initialize_server_options(ServerOptions *); -void read_server_config(ServerOptions *, const char *); void fill_default_server_options(ServerOptions *); int process_server_config_line(ServerOptions *, char *, const char *, int); - +void load_server_config(const char *, Buffer *); +void parse_server_config(ServerOptions *, const char *, Buffer *); #endif /* SERVCONF_H */ diff --git a/openssh/serverloop.c b/openssh/serverloop.c index a777a04..eee1e79 100644 --- a/openssh/serverloop.c +++ b/openssh/serverloop.c @@ -35,7 +35,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: serverloop.c,v 1.115 2004/01/19 21:25:15 markus Exp $"); +RCSID("$OpenBSD: serverloop.c,v 1.117 2004/08/11 21:43:05 avsm Exp $"); #include "xmalloc.h" #include "packet.h" @@ -240,7 +240,7 @@ client_alive_check(void) */ static void wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp, - int *nallocp, u_int max_time_milliseconds) + u_int *nallocp, u_int max_time_milliseconds) { struct timeval tv, *tvp; int ret; @@ -486,7 +486,8 @@ void server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) { fd_set *readset = NULL, *writeset = NULL; - int max_fd = 0, nalloc = 0; + int max_fd = 0; + u_int nalloc = 0; int wait_status; /* Status returned by wait(). */ pid_t wait_pid; /* pid returned by wait(). */ int waiting_termination = 0; /* Have displayed waiting close message. */ @@ -991,6 +992,17 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt) listen_address, listen_port, options.gateway_ports); } xfree(listen_address); + } else if (strcmp(rtype, "cancel-tcpip-forward") == 0) { + char *cancel_address; + u_short cancel_port; + + cancel_address = packet_get_string(NULL); + cancel_port = (u_short)packet_get_int(); + debug("%s: cancel-tcpip-forward addr %s port %d", __func__, + cancel_address, cancel_port); + + success = channel_cancel_rport_listener(cancel_address, + cancel_port); } if (want_reply) { packet_start(success ? diff --git a/openssh/session.c b/openssh/session.c index 55db2ff..ee4008a 100644 --- a/openssh/session.c +++ b/openssh/session.c @@ -33,7 +33,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: session.c,v 1.172 2004/01/30 09:48:57 markus Exp $"); +RCSID("$OpenBSD: session.c,v 1.180 2004/07/28 09:40:29 markus Exp $"); #include "ssh.h" #include "ssh1.h" @@ -42,7 +42,7 @@ RCSID("$OpenBSD: session.c,v 1.172 2004/01/30 09:48:57 markus Exp $"); #include "sshpty.h" #include "packet.h" #include "buffer.h" -#include "mpaux.h" +#include "match.h" #include "uidswap.h" #include "compat.h" #include "channels.h" @@ -196,12 +196,11 @@ auth_input_request_forwarding(struct passwd * pw) static void display_loginmsg(void) { - if (buffer_len(&loginmsg) > 0) { - buffer_append(&loginmsg, "\0", 1); - printf("%s\n", (char *)buffer_ptr(&loginmsg)); - buffer_clear(&loginmsg); - } - fflush(stdout); + if (buffer_len(&loginmsg) > 0) { + buffer_append(&loginmsg, "\0", 1); + printf("%s", (char *)buffer_ptr(&loginmsg)); + buffer_clear(&loginmsg); + } } void @@ -265,7 +264,7 @@ do_authenticated1(Authctxt *authctxt) compression_level = packet_get_int(); packet_check_eom(); if (compression_level < 1 || compression_level > 9) { - packet_send_debug("Received illegal compression level %d.", + packet_send_debug("Received invalid compression level %d.", compression_level); break; } @@ -481,7 +480,11 @@ do_exec_no_pty(Session *s, const char *command) close(perr[1]); if (compat20) { - session_set_fds(s, pin[1], pout[0], s->is_subsystem ? -1 : perr[0]); + if (s->is_subsystem) { + close(perr[0]); + perr[0] = -1; + } + session_set_fds(s, pin[1], pout[0], perr[0]); } else { /* Enter the interactive session. */ server_loop(pid, pin[1], pout[0], perr[0]); @@ -672,14 +675,19 @@ do_exec(Session *s, const char *command) do_exec_no_pty(s, command); original_command = NULL; -} + /* + * Clear loginmsg: it's the child's responsibility to display + * it to the user, otherwise multiple sessions may accumulate + * multiple copies of the login messages. + */ + buffer_clear(&loginmsg); +} /* administrative, login(1)-like work */ void do_login(Session *s, const char *command) { - char *time_string; socklen_t fromlen; struct sockaddr_storage from; struct passwd * pw = s->pw; @@ -724,19 +732,6 @@ do_login(Session *s, const char *command) display_loginmsg(); -#ifndef NO_SSH_LASTLOG - if (options.print_lastlog && s->last_login_time != 0) { - time_string = ctime(&s->last_login_time); - if (strchr(time_string, '\n')) - *strchr(time_string, '\n') = 0; - if (strcmp(s->hostname, "") == 0) - printf("Last login: %s\r\n", time_string); - else - printf("Last login: %s from %s\r\n", time_string, - s->hostname); - } -#endif /* NO_SSH_LASTLOG */ - do_motd(); } @@ -996,6 +991,10 @@ do_setup_env(Session *s, const char *shell) if (!options.use_login) { /* Set basic environment. */ + for (i = 0; i < s->num_env; i++) + child_set_env(&env, &envsize, s->env[i].name, + s->env[i].val); + child_set_env(&env, &envsize, "USER", pw->pw_name); child_set_env(&env, &envsize, "LOGNAME", pw->pw_name); #ifdef _AIX @@ -1310,9 +1309,10 @@ do_setusercontext(struct passwd *pw) static void do_pwchange(Session *s) { + fflush(NULL); fprintf(stderr, "WARNING: Your password has expired.\n"); if (s->ttyfd != -1) { - fprintf(stderr, + fprintf(stderr, "You must change your password now and login again!\n"); execl(_PATH_PASSWD_PROG, "passwd", (char *)NULL); perror("passwd"); @@ -1423,6 +1423,13 @@ do_child(Session *s, const char *command) #else /* HAVE_OSF_SIA */ do_nologin(pw); do_setusercontext(pw); + /* + * PAM session modules in do_setusercontext may have + * generated messages, so if this in an interactive + * login then display them too. + */ + if (command == NULL) + display_loginmsg(); #endif /* HAVE_OSF_SIA */ } @@ -1688,12 +1695,6 @@ session_pty_req(Session *s) packet_disconnect("Protocol error: you already have a pty."); return 0; } - /* Get the time and hostname when the user last logged in. */ - if (options.print_lastlog) { - s->hostname[0] = '\0'; - s->last_login_time = get_last_login_time(s->pw->pw_uid, - s->pw->pw_name, s->hostname, sizeof(s->hostname)); - } s->term = packet_get_string(&len); @@ -1820,9 +1821,8 @@ session_exec_req(Session *s) static int session_break_req(Session *s) { - u_int break_length; - break_length = packet_get_int(); /* ignored */ + packet_get_int(); /* ignored */ packet_check_eom(); if (s->ttyfd == -1 || @@ -1831,6 +1831,41 @@ session_break_req(Session *s) return 1; } +static int +session_env_req(Session *s) +{ + char *name, *val; + u_int name_len, val_len, i; + + name = packet_get_string(&name_len); + val = packet_get_string(&val_len); + packet_check_eom(); + + /* Don't set too many environment variables */ + if (s->num_env > 128) { + debug2("Ignoring env request %s: too many env vars", name); + goto fail; + } + + for (i = 0; i < options.num_accept_env; i++) { + if (match_pattern(name, options.accept_env[i])) { + debug2("Setting env %d: %s=%s", s->num_env, name, val); + s->env = xrealloc(s->env, sizeof(*s->env) * + (s->num_env + 1)); + s->env[s->num_env].name = name; + s->env[s->num_env].val = val; + s->num_env++; + return (1); + } + } + debug2("Ignoring env request %s: disallowed name", name); + + fail: + xfree(name); + xfree(val); + return (0); +} + static int session_auth_agent_req(Session *s) { @@ -1878,13 +1913,16 @@ 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); + } else if (strcmp(rtype, "env") == 0) { + success = session_env_req(s); } } if (strcmp(rtype, "window-change") == 0) { success = session_window_change_req(s); + } else if (strcmp(rtype, "break") == 0) { + success = session_break_req(s); } + return success; } @@ -2017,6 +2055,8 @@ session_exit_message(Session *s, int status) void session_close(Session *s) { + int i; + debug("session_close: session %d pid %ld", s->self, (long)s->pid); if (s->ttyfd != -1) session_pty_cleanup(s); @@ -2031,6 +2071,12 @@ session_close(Session *s) if (s->auth_proto) xfree(s->auth_proto); s->used = 0; + for (i = 0; i < s->num_env; i++) { + xfree(s->env[i].name); + xfree(s->env[i].val); + } + if (s->env != NULL) + xfree(s->env); session_proctitle(s); } diff --git a/openssh/session.h b/openssh/session.h index 405b8fe..48be507 100644 --- a/openssh/session.h +++ b/openssh/session.h @@ -1,4 +1,4 @@ -/* $OpenBSD: session.h,v 1.21 2003/09/23 20:17:11 markus Exp $ */ +/* $OpenBSD: session.h,v 1.23 2004/07/17 05:31:41 dtucker Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -39,9 +39,6 @@ struct Session { int ptyfd, ttyfd, ptymaster; u_int row, col, xpixel, ypixel; char tty[TTYSZ]; - /* last login */ - char hostname[MAXHOSTNAMELEN]; - time_t last_login_time; /* X11 */ u_int display_number; char *display; @@ -53,6 +50,11 @@ struct Session { /* proto 2 */ int chanid; int is_subsystem; + int num_env; + struct { + char *name; + char *val; + } *env; }; void do_authenticated(Authctxt *); diff --git a/openssh/sftp-client.c b/openssh/sftp-client.c index 781d982..0ffacbc 100644 --- a/openssh/sftp-client.c +++ b/openssh/sftp-client.c @@ -20,7 +20,7 @@ /* XXX: copy between two remote sites */ #include "includes.h" -RCSID("$OpenBSD: sftp-client.c,v 1.47 2004/03/03 09:30:42 djm Exp $"); +RCSID("$OpenBSD: sftp-client.c,v 1.51 2004/07/11 17:48:47 deraadt Exp $"); #include "openbsd-compat/sys-queue.h" @@ -36,6 +36,7 @@ RCSID("$OpenBSD: sftp-client.c,v 1.47 2004/03/03 09:30:42 djm Exp $"); #include "sftp-common.h" #include "sftp-client.h" +extern volatile sig_atomic_t interrupted; extern int showprogress; /* Minimum amount of data to read at at time */ @@ -330,7 +331,7 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag, (*dir)[0] = NULL; } - for (;;) { + for (; !interrupted;) { int count; id = expected_id = conn->msg_id++; @@ -407,6 +408,13 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag, do_close(conn, handle, handle_len); xfree(handle); + /* Don't return partial matches on interrupt */ + if (interrupted && dir != NULL && *dir != NULL) { + free_sftp_dirents(*dir); + *dir = xmalloc(sizeof(**dir)); + **dir = NULL; + } + return(0); } @@ -643,7 +651,7 @@ do_symlink(struct sftp_conn *conn, char *oldpath, char *newpath) buffer_init(&msg); - /* Send rename request */ + /* Send symlink request */ id = conn->msg_id++; buffer_put_char(&msg, SSH2_FXP_SYMLINK); buffer_put_int(&msg, id); @@ -812,6 +820,16 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path, char *data; u_int len; + /* + * Simulate EOF on interrupt: stop sending new requests and + * allow outstanding requests to drain gracefully + */ + if (interrupted) { + if (num_req == 0) /* If we haven't started yet... */ + break; + max_req = 0; + } + /* Send some more requests */ while (num_req < max_req) { debug3("Request range %llu -> %llu (%d/%d)", @@ -899,8 +917,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path, (unsigned long long)offset, num_req); max_req = 1; - } - else if (max_req < conn->num_requests + 1) { + } else if (max_req <= conn->num_requests) { ++max_req; } } @@ -975,7 +992,7 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, TAILQ_ENTRY(outstanding_ack) tq; }; TAILQ_HEAD(ackhead, outstanding_ack) acks; - struct outstanding_ack *ack; + struct outstanding_ack *ack = NULL; TAILQ_INIT(&acks); @@ -1036,10 +1053,14 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, int len; /* - * Can't use atomicio here because it returns 0 on EOF, thus losing - * the last block of the file + * Can't use atomicio here because it returns 0 on EOF, + * thus losing the last block of the file. + * Simulate an EOF on interrupt, allowing ACKs from the + * server to drain. */ - do + if (interrupted) + len = 0; + else do len = read(local_fd, data, conn->transfer_buflen); while ((len == -1) && (errno == EINTR || errno == EAGAIN)); diff --git a/openssh/sftp-server.c b/openssh/sftp-server.c index 1d13e97..e822800 100644 --- a/openssh/sftp-server.c +++ b/openssh/sftp-server.c @@ -14,7 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "includes.h" -RCSID("$OpenBSD: sftp-server.c,v 1.45 2004/02/19 21:15:04 markus Exp $"); +RCSID("$OpenBSD: sftp-server.c,v 1.47 2004/06/25 05:38:48 dtucker Exp $"); #include "buffer.h" #include "bufaux.h" @@ -31,11 +31,7 @@ RCSID("$OpenBSD: sftp-server.c,v 1.45 2004/02/19 21:15:04 markus Exp $"); #define get_string(lenp) buffer_get_string(&iqueue, lenp); #define TRACE debug -#ifdef HAVE___PROGNAME extern char *__progname; -#else -char *__progname; -#endif /* input and output queue */ Buffer iqueue; @@ -260,7 +256,7 @@ send_msg(Buffer *m) } static void -send_status(u_int32_t id, u_int32_t error) +send_status(u_int32_t id, u_int32_t status) { Buffer msg; const char *status_messages[] = { @@ -276,14 +272,14 @@ send_status(u_int32_t id, u_int32_t error) "Unknown error" /* Others */ }; - TRACE("sent status id %u error %u", id, error); + TRACE("sent status id %u error %u", id, status); buffer_init(&msg); buffer_put_char(&msg, SSH2_FXP_STATUS); buffer_put_int(&msg, id); - buffer_put_int(&msg, error); + buffer_put_int(&msg, status); if (version >= 3) { buffer_put_cstring(&msg, - status_messages[MIN(error,SSH2_FX_MAX)]); + status_messages[MIN(status,SSH2_FX_MAX)]); buffer_put_cstring(&msg, ""); } send_msg(&msg); @@ -839,9 +835,29 @@ process_rename(void) status = errno_to_portable(errno); else if (S_ISREG(sb.st_mode)) { /* Race-free rename of regular files */ - if (link(oldpath, newpath) == -1) - status = errno_to_portable(errno); - else if (unlink(oldpath) == -1) { + if (link(oldpath, newpath) == -1) { + if (errno == EOPNOTSUPP +#ifdef LINK_OPNOTSUPP_ERRNO + || errno == LINK_OPNOTSUPP_ERRNO +#endif + ) { + struct stat st; + + /* + * fs doesn't support links, so fall back to + * stat+rename. This is racy. + */ + if (stat(newpath, &st) == -1) { + if (rename(oldpath, newpath) == -1) + status = + errno_to_portable(errno); + else + status = SSH2_FX_OK; + } + } else { + status = errno_to_portable(errno); + } + } else if (unlink(oldpath) == -1) { status = errno_to_portable(errno); /* clean spare link */ unlink(newpath); @@ -863,20 +879,20 @@ process_readlink(void) { u_int32_t id; int len; - char link[MAXPATHLEN]; + char buf[MAXPATHLEN]; char *path; id = get_int(); path = get_string(NULL); TRACE("readlink id %u path %s", id, path); - if ((len = readlink(path, link, sizeof(link) - 1)) == -1) + if ((len = readlink(path, buf, sizeof(buf) - 1)) == -1) send_status(id, errno_to_portable(errno)); else { Stat s; - link[len] = '\0'; + buf[len] = '\0'; attrib_clear(&s.attrib); - s.name = s.long_name = link; + s.name = s.long_name = buf; send_names(id, 1, &s); } xfree(path); diff --git a/openssh/sftp.1 b/openssh/sftp.1 index b2cab0c..3b035b1 100644 --- a/openssh/sftp.1 +++ b/openssh/sftp.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp.1,v 1.52 2004/03/05 10:53:58 markus Exp $ +.\" $OpenBSD: sftp.1,v 1.57 2004/06/21 22:41:31 djm Exp $ .\" .\" Copyright (c) 2001 Damien Miller. All rights reserved. .\" @@ -153,7 +153,9 @@ For full details of the options listed below, and their possible values, see .It Compression .It CompressionLevel .It ConnectionAttempts -.It ConnectionTimeout +.It ConnectTimeout +.It ControlMaster +.It ControlPath .It GlobalKnownHostsFile .It GSSAPIAuthentication .It GSSAPIDelegateCredentials @@ -176,6 +178,7 @@ For full details of the options listed below, and their possible values, see .It PubkeyAuthentication .It RhostsRSAAuthentication .It RSAAuthentication +.It SendEnv .It ServerAliveInterval .It ServerAliveCountMax .It SmartcardDevice @@ -300,6 +303,24 @@ If the .Fl l flag is specified, then display additional details including permissions and ownership information. +The +.Fl n +flag will produce a long listing with user and group information presented +numerically. +.Pp +By default, +.Ic ls +listings are sorted in lexicographical order. +This may be changed by specifying the +.Fl S +(sort by file size), +.Fl t +(sort by last modification time), or +.Fl f +(don't sort at all) flags. +Additionally, the sort order may be reversed using the +.Fl r +flag. .It Ic lumask Ar umask Set local umask to .Ar umask . diff --git a/openssh/sftp.c b/openssh/sftp.c index a47ccf5..f01c919 100644 --- a/openssh/sftp.c +++ b/openssh/sftp.c @@ -16,7 +16,7 @@ #include "includes.h" -RCSID("$OpenBSD: sftp.c,v 1.45 2004/03/03 09:31:20 djm Exp $"); +RCSID("$OpenBSD: sftp.c,v 1.56 2004/07/11 17:48:47 deraadt Exp $"); #include "buffer.h" #include "xmalloc.h" @@ -46,21 +46,32 @@ static pid_t sshpid = -1; /* This is set to 0 if the progressmeter is not desired. */ int showprogress = 1; +/* SIGINT received during command processing */ +volatile sig_atomic_t interrupted = 0; + +/* I wish qsort() took a separate ctx for the comparison function...*/ +int sort_flag; + int remote_glob(struct sftp_conn *, const char *, int, int (*)(const char *, int), glob_t *); /* proto for sftp-glob.c */ -#ifdef HAVE___PROGNAME extern char *__progname; -#else -char *__progname; -#endif /* Separators for interactive commands */ #define WHITESPACE " \t\r\n" -/* Define what type of ls view (0 - multi-column) */ -#define LONG_VIEW 1 /* Full view ala ls -l */ -#define SHORT_VIEW 2 /* Single row view ala ls -1 */ +/* ls flags */ +#define LS_LONG_VIEW 0x01 /* Full view ala ls -l */ +#define LS_SHORT_VIEW 0x02 /* Single row view ala ls -1 */ +#define LS_NUMERIC_VIEW 0x04 /* Long view with numeric uid/gid */ +#define LS_NAME_SORT 0x08 /* Sort by name (default) */ +#define LS_TIME_SORT 0x10 /* Sort by mtime */ +#define LS_SIZE_SORT 0x20 /* Sort by file size */ +#define LS_REVERSE_SORT 0x40 /* Reverse sort order */ +#define LS_SHOW_ALL 0x80 /* Don't skip filenames starting with '.' */ + +#define VIEW_FLAGS (LS_LONG_VIEW|LS_SHORT_VIEW|LS_NUMERIC_VIEW) +#define SORT_FLAGS (LS_NAME_SORT|LS_TIME_SORT|LS_SIZE_SORT) /* Commands for interactive mode */ #define I_CHDIR 1 @@ -130,6 +141,24 @@ static const struct CMD cmds[] = { int interactive_loop(int fd_in, int fd_out, char *file1, char *file2); +static void +killchild(int signo) +{ + if (sshpid > 1) + kill(sshpid, SIGTERM); + + _exit(1); +} + +static void +cmd_interrupt(int signo) +{ + const char msg[] = "\rInterrupt \n"; + + write(STDERR_FILENO, msg, sizeof(msg) - 1); + interrupted = 1; +} + static void help(void) { @@ -254,13 +283,13 @@ path_append(char *p1, char *p2) static char * make_absolute(char *p, char *pwd) { - char *abs; + char *abs_str; /* Derelativise */ if (p && p[0] != '/') { - abs = path_append(pwd, p); + abs_str = path_append(pwd, p); xfree(p); - return(abs); + return(abs_str); } else return(p); } @@ -313,15 +342,41 @@ parse_ls_flags(const char **cpp, int *lflag) { const char *cp = *cpp; + /* Defaults */ + *lflag = LS_NAME_SORT; + /* Check for flags */ if (cp++[0] == '-') { for(; strchr(WHITESPACE, *cp) == NULL; cp++) { switch (*cp) { case 'l': - *lflag = LONG_VIEW; + *lflag &= ~VIEW_FLAGS; + *lflag |= LS_LONG_VIEW; break; case '1': - *lflag = SHORT_VIEW; + *lflag &= ~VIEW_FLAGS; + *lflag |= LS_SHORT_VIEW; + break; + case 'n': + *lflag &= ~VIEW_FLAGS; + *lflag |= LS_NUMERIC_VIEW|LS_LONG_VIEW; + break; + case 'S': + *lflag &= ~SORT_FLAGS; + *lflag |= LS_SIZE_SORT; + break; + case 't': + *lflag &= ~SORT_FLAGS; + *lflag |= LS_TIME_SORT; + break; + case 'r': + *lflag |= LS_REVERSE_SORT; + break; + case 'f': + *lflag &= ~SORT_FLAGS; + break; + case 'a': + *lflag |= LS_SHOW_ALL; break; default: error("Invalid flag -%c", *cp); @@ -369,7 +424,7 @@ get_pathname(const char **cpp, char **path) i++; if (cp[i] != '\'' && cp[i] != '\"' && cp[i] != '\\') { - error("Bad escaped character '\%c'", + error("Bad escaped character '\\%c'", cp[i]); goto fail; } @@ -465,7 +520,7 @@ process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag) goto out; } - for (i = 0; g.gl_pathv[i]; i++) { + for (i = 0; g.gl_pathv[i] && !interrupted; i++) { if (infer_path(g.gl_pathv[i], &tmp)) { err = -1; goto out; @@ -534,7 +589,7 @@ process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag) goto out; } - for (i = 0; g.gl_pathv[i]; i++) { + for (i = 0; g.gl_pathv[i] && !interrupted; i++) { if (!is_reg(g.gl_pathv[i])) { error("skipping non-regular file %s", g.gl_pathv[i]); @@ -582,8 +637,17 @@ sdirent_comp(const void *aa, const void *bb) { SFTP_DIRENT *a = *(SFTP_DIRENT **)aa; SFTP_DIRENT *b = *(SFTP_DIRENT **)bb; + int rmul = sort_flag & LS_REVERSE_SORT ? -1 : 1; + +#define NCMP(a,b) (a == b ? 0 : (a < b ? 1 : -1)) + if (sort_flag & LS_NAME_SORT) + return (rmul * strcmp(a->filename, b->filename)); + else if (sort_flag & LS_TIME_SORT) + return (rmul * NCMP(a->a.mtime, b->a.mtime)); + else if (sort_flag & LS_SIZE_SORT) + return (rmul * NCMP(a->a.size, b->a.size)); - return (strcmp(a->filename, b->filename)); + fatal("Unknown ls sort type"); } /* sftp ls.1 replacement for directories */ @@ -596,14 +660,16 @@ do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag) if ((n = do_readdir(conn, path, &d)) != 0) return (n); - if (!(lflag & SHORT_VIEW)) { + if (!(lflag & LS_SHORT_VIEW)) { int m = 0, width = 80; struct winsize ws; char *tmp; /* Count entries for sort and find longest filename */ - for (n = 0; d[n] != NULL; n++) - m = MAX(m, strlen(d[n]->filename)); + for (n = 0; d[n] != NULL; n++) { + if (d[n]->filename[0] != '.' || (lflag & LS_SHOW_ALL)) + m = MAX(m, strlen(d[n]->filename)); + } /* Add any subpath that also needs to be counted */ tmp = path_strip(path, strip_path); @@ -619,24 +685,33 @@ do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag) colspace = MIN(colspace, width); } - qsort(d, n, sizeof(*d), sdirent_comp); + if (lflag & SORT_FLAGS) { + sort_flag = lflag & (SORT_FLAGS|LS_REVERSE_SORT); + qsort(d, n, sizeof(*d), sdirent_comp); + } - for (n = 0; d[n] != NULL; n++) { + for (n = 0; d[n] != NULL && !interrupted; n++) { char *tmp, *fname; + if (d[n]->filename[0] == '.' && !(lflag & LS_SHOW_ALL)) + continue; + tmp = path_append(path, d[n]->filename); fname = path_strip(tmp, strip_path); xfree(tmp); - if (lflag & LONG_VIEW) { - char *lname; - struct stat sb; + if (lflag & LS_LONG_VIEW) { + if (lflag & LS_NUMERIC_VIEW) { + char *lname; + struct stat sb; - memset(&sb, 0, sizeof(sb)); - attrib_to_stat(&d[n]->a, &sb); - lname = ls_file(fname, &sb, 1); - printf("%s\n", lname); - xfree(lname); + memset(&sb, 0, sizeof(sb)); + attrib_to_stat(&d[n]->a, &sb); + lname = ls_file(fname, &sb, 1); + printf("%s\n", lname); + xfree(lname); + } else + printf("%s\n", d[n]->longname); } else { printf("%-*s", colspace, fname); if (c >= columns) { @@ -649,7 +724,7 @@ do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag) xfree(fname); } - if (!(lflag & LONG_VIEW) && (c != 1)) + if (!(lflag & LS_LONG_VIEW) && (c != 1)) printf("\n"); free_sftp_dirents(d); @@ -673,6 +748,9 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, return (-1); } + if (interrupted) + goto out; + /* * If the glob returns a single match, which is the same as the * input glob, and it is a directory, then just list its contents @@ -690,7 +768,7 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, } } - if (!(lflag & SHORT_VIEW)) { + if (!(lflag & LS_SHORT_VIEW)) { int m = 0, width = 80; struct winsize ws; @@ -706,12 +784,12 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, colspace = width / columns; } - for (i = 0; g.gl_pathv[i]; i++) { + for (i = 0; g.gl_pathv[i] && !interrupted; i++) { char *fname; fname = path_strip(g.gl_pathv[i], strip_path); - if (lflag & LONG_VIEW) { + if (lflag & LS_LONG_VIEW) { char *lname; struct stat sb; @@ -740,9 +818,10 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, xfree(fname); } - if (!(lflag & LONG_VIEW) && (c != 1)) + if (!(lflag & LS_LONG_VIEW) && (c != 1)) printf("\n"); + out: if (g.gl_pathc) globfree(&g); @@ -952,7 +1031,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, case I_RM: path1 = make_absolute(path1, *pwd); remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g); - for (i = 0; g.gl_pathv[i]; i++) { + for (i = 0; g.gl_pathv[i] && !interrupted; i++) { printf("Removing %s\n", g.gl_pathv[i]); err = do_rm(conn, g.gl_pathv[i]); if (err != 0 && err_abort) @@ -1041,7 +1120,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS; a.perm = n_arg; remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g); - for (i = 0; g.gl_pathv[i]; i++) { + for (i = 0; g.gl_pathv[i] && !interrupted; i++) { printf("Changing mode on %s\n", g.gl_pathv[i]); err = do_setstat(conn, g.gl_pathv[i], &a); if (err != 0 && err_abort) @@ -1052,7 +1131,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, case I_CHGRP: path1 = make_absolute(path1, *pwd); remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g); - for (i = 0; g.gl_pathv[i]; i++) { + for (i = 0; g.gl_pathv[i] && !interrupted; i++) { if (!(aa = do_stat(conn, g.gl_pathv[i], 0))) { if (err != 0 && err_abort) break; @@ -1180,6 +1259,8 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2) for (;;) { char *cp; + signal(SIGINT, SIG_IGN); + printf("sftp> "); /* XXX: use libedit */ @@ -1195,6 +1276,10 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2) if (cp) *cp = '\0'; + /* Handle user interrupts gracefully during commands */ + interrupted = 0; + signal(SIGINT, cmd_interrupt); + err = parse_dispatch_command(conn, cmd, &pwd, batchmode); if (err != 0) break; @@ -1205,15 +1290,6 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2) return (err >= 0 ? 0 : -1); } -static void -killchild(int signo) -{ - if (sshpid > 1) - kill(sshpid, signo); - - _exit(1); -} - static void connect_to_server(char *path, char **args, int *in, int *out) { @@ -1243,15 +1319,23 @@ connect_to_server(char *path, char **args, int *in, int *out) if ((dup2(c_in, STDIN_FILENO) == -1) || (dup2(c_out, STDOUT_FILENO) == -1)) { fprintf(stderr, "dup2: %s\n", strerror(errno)); - exit(1); + _exit(1); } close(*in); close(*out); close(c_in); close(c_out); - execv(path, args); + + /* + * The underlying ssh is in the same process group, so we must + * ignore SIGINT if we want to gracefully abort commands, + * otherwise the signal will make it to the ssh process and + * kill it too + */ + signal(SIGINT, SIG_IGN); + execvp(path, args); fprintf(stderr, "exec: %s: %s\n", path, strerror(errno)); - exit(1); + _exit(1); } signal(SIGTERM, killchild); @@ -1280,7 +1364,7 @@ int main(int argc, char **argv) { int in, out, ch, err; - char *host, *userhost, *cp, *file2; + char *host, *userhost, *cp, *file2 = NULL; int debug_level = 0, sshver = 2; char *file1 = NULL, *sftp_server = NULL; char *ssh_program = _PATH_SSH_PROGRAM, *sftp_direct = NULL; @@ -1331,7 +1415,7 @@ main(int argc, char **argv) fatal("Batch file already specified."); /* Allow "-" as stdin */ - if (strcmp(optarg, "-") != 0 && + if (strcmp(optarg, "-") != 0 && (infile = fopen(optarg, "r")) == NULL) fatal("%s (%s).", strerror(errno), optarg); showprogress = 0; diff --git a/openssh/ssh-add.c b/openssh/ssh-add.c index e7699c9..06a5246 100644 --- a/openssh/ssh-add.c +++ b/openssh/ssh-add.c @@ -35,7 +35,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh-add.c,v 1.69 2003/11/21 11:57:03 djm Exp $"); +RCSID("$OpenBSD: ssh-add.c,v 1.70 2004/05/08 00:21:31 djm Exp $"); #include @@ -47,15 +47,8 @@ RCSID("$OpenBSD: ssh-add.c,v 1.69 2003/11/21 11:57:03 djm Exp $"); #include "authfd.h" #include "authfile.h" #include "pathnames.h" -#include "readpass.h" #include "misc.h" -#ifdef HAVE___PROGNAME -extern char *__progname; -#else -char *__progname; -#endif - /* argv0 */ extern char *__progname; diff --git a/openssh/ssh-agent.1 b/openssh/ssh-agent.1 index aab15cc..226804e 100644 --- a/openssh/ssh-agent.1 +++ b/openssh/ssh-agent.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-agent.1,v 1.39 2003/06/10 09:12:11 jmc Exp $ +.\" $OpenBSD: ssh-agent.1,v 1.41 2004/07/11 17:48:47 deraadt Exp $ .\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -134,13 +134,25 @@ remote logins, and the user can thus use the privileges given by the identities anywhere in the network in a secure way. .Pp There are two main ways to get an agent set up: -Either the agent starts a new subcommand into which some environment -variables are exported, or the agent prints the needed shell commands -(either +The first is that the agent starts a new subcommand into which some environment +variables are exported, eg +.Cm ssh-agent xterm & . +The second is that the agent prints the needed shell commands (either .Xr sh 1 or .Xr csh 1 -syntax can be generated) which can be evalled in the calling shell. +syntax can be generated) which can be evalled in the calling shell, eg +.Cm eval `ssh-agent -s` +for Bourne-type shells such as +.Xr sh 1 +or +.Xr ksh 1 +and +.Cm eval `ssh-agent -c` +for +.Xr csh 1 +and derivatives. +.Pp Later .Xr ssh 1 looks at these variables and uses them to establish a connection to the agent. diff --git a/openssh/ssh-agent.c b/openssh/ssh-agent.c index f5fce6b..bc4d8d3 100644 --- a/openssh/ssh-agent.c +++ b/openssh/ssh-agent.c @@ -35,7 +35,7 @@ #include "includes.h" #include "openbsd-compat/sys-queue.h" -RCSID("$OpenBSD: ssh-agent.c,v 1.117 2003/12/02 17:01:15 markus Exp $"); +RCSID("$OpenBSD: ssh-agent.c,v 1.120 2004/08/11 21:43:05 avsm Exp $"); #include #include @@ -50,7 +50,6 @@ RCSID("$OpenBSD: ssh-agent.c,v 1.117 2003/12/02 17:01:15 markus Exp $"); #include "authfd.h" #include "compat.h" #include "log.h" -#include "readpass.h" #include "misc.h" #ifdef SMARTCARD @@ -107,11 +106,7 @@ char socket_dir[1024]; int locked = 0; char *lock_passwd = NULL; -#ifdef HAVE___PROGNAME extern char *__progname; -#else -char *__progname; -#endif /* Default lifetime (0 == forever) */ static int lifetime = 0; @@ -790,8 +785,7 @@ new_socket(sock_type type, int fd) { u_int i, old_alloc, new_alloc; - if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) - error("fcntl O_NONBLOCK: %s", strerror(errno)); + set_nonblock(fd); if (fd > max_fd) max_fd = fd; @@ -822,7 +816,7 @@ new_socket(sock_type type, int fd) } static int -prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, int *nallocp) +prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, u_int *nallocp) { u_int i, sz; int n = 0; @@ -1008,7 +1002,8 @@ int main(int ac, char **av) { int c_flag = 0, d_flag = 0, k_flag = 0, s_flag = 0; - int sock, fd, ch, nalloc; + int sock, fd, ch; + u_int nalloc; char *shell, *format, *pidstr, *agentsocket = NULL; fd_set *readsetp = NULL, *writesetp = NULL; struct sockaddr_un sunaddr; diff --git a/openssh/ssh-gss.h b/openssh/ssh-gss.h index 4f032aa..52fb49a 100644 --- a/openssh/ssh-gss.h +++ b/openssh/ssh-gss.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-gss.h,v 1.4 2003/11/17 11:06:07 markus Exp $ */ +/* $OpenBSD: ssh-gss.h,v 1.5 2004/06/21 17:36:31 avsm Exp $ */ /* * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. * @@ -100,31 +100,31 @@ typedef struct { extern ssh_gssapi_mech *supported_mechs[]; -int ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len); -void ssh_gssapi_set_oid_data(Gssctxt *ctx, void *data, size_t len); -void ssh_gssapi_set_oid(Gssctxt *ctx, gss_OID oid); -void ssh_gssapi_supported_oids(gss_OID_set *oidset); -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); -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_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); +int ssh_gssapi_check_oid(Gssctxt *, void *, size_t); +void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t); +void ssh_gssapi_set_oid(Gssctxt *, gss_OID); +void ssh_gssapi_supported_oids(gss_OID_set *); +ssh_gssapi_mech *ssh_gssapi_get_ctype(Gssctxt *); + +OM_uint32 ssh_gssapi_import_name(Gssctxt *, const char *); +OM_uint32 ssh_gssapi_acquire_cred(Gssctxt *); +OM_uint32 ssh_gssapi_init_ctx(Gssctxt *, int, + gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *); +OM_uint32 ssh_gssapi_accept_ctx(Gssctxt *, + gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *); +OM_uint32 ssh_gssapi_getclient(Gssctxt *, ssh_gssapi_client *); +void ssh_gssapi_error(Gssctxt *); +char *ssh_gssapi_last_error(Gssctxt *, OM_uint32 *, OM_uint32 *); +void ssh_gssapi_build_ctx(Gssctxt **); +void ssh_gssapi_delete_ctx(Gssctxt **); OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); -OM_uint32 ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid); +OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID); void ssh_gssapi_buildmic(Buffer *, const char *, const char *, const char *); /* In the server */ int ssh_gssapi_userok(char *name); OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); -void ssh_gssapi_do_child(char ***envp, u_int *envsizep); +void ssh_gssapi_do_child(char ***, u_int *); void ssh_gssapi_cleanup_creds(void); void ssh_gssapi_storecreds(void); diff --git a/openssh/ssh-keygen.1 b/openssh/ssh-keygen.1 index 6dd6154..c0f24dc 100644 --- a/openssh/ssh-keygen.1 +++ b/openssh/ssh-keygen.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keygen.1,v 1.61 2003/12/22 09:16:58 djm Exp $ +.\" $OpenBSD: ssh-keygen.1,v 1.63 2004/08/13 00:01:43 jmc Exp $ .\" .\" -*- nroff -*- .\" @@ -192,7 +192,9 @@ to stdout. This option allows exporting keys for use by several commercial SSH implementations. .It Fl g -Use generic DNS resource record format. +Use generic DNS format when printing fingerprint resource records using the +.Fl r +command. .It Fl f Ar filename Specifies the filename of the key file. .It Fl i @@ -276,8 +278,9 @@ Multiple options increase the verbosity. The maximum is 3. .It Fl r Ar hostname -Print DNS resource record with the specified -.Ar hostname . +Print the SSHFP fingerprint resource record named +.Ar hostname +for the specified public key file. .El .Sh MODULI GENERATION .Nm diff --git a/openssh/ssh-keygen.c b/openssh/ssh-keygen.c index 1156a01..d39e7d8 100644 --- a/openssh/ssh-keygen.c +++ b/openssh/ssh-keygen.c @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh-keygen.c,v 1.113 2003/12/22 09:16:58 djm Exp $"); +RCSID("$OpenBSD: ssh-keygen.c,v 1.117 2004/07/11 17:48:47 deraadt Exp $"); #include #include @@ -26,8 +26,7 @@ RCSID("$OpenBSD: ssh-keygen.c,v 1.113 2003/12/22 09:16:58 djm Exp $"); #include "bufaux.h" #include "pathnames.h" #include "log.h" -#include "readpass.h" -#include "moduli.h" +#include "misc.h" #ifdef SMARTCARD #include "scard.h" @@ -77,14 +76,14 @@ int print_generic = 0; char *key_type_name = NULL; /* argv0 */ -#ifdef HAVE___PROGNAME extern char *__progname; -#else -char *__progname; -#endif char hostname[MAXHOSTNAMELEN]; +/* moduli.c */ +int gen_candidates(FILE *, int, int, BIGNUM *); +int prime_test(FILE *, FILE *, u_int32_t, u_int32_t); + static void ask_filename(struct passwd *pw, const char *prompt) { @@ -189,8 +188,8 @@ do_convert_to_ssh2(struct passwd *pw) static void buffer_get_bignum_bits(Buffer *b, BIGNUM *value) { - u_int bits = buffer_get_int(b); - u_int bytes = (bits + 7) / 8; + u_int bignum_bits = buffer_get_int(b); + u_int bytes = (bignum_bits + 7) / 8; if (buffer_len(b) < bytes) fatal("buffer_get_bignum_bits: input buffer too small: " @@ -627,7 +626,7 @@ do_change_passphrase(struct passwd *pw) * Print the SSHFP RR. */ static void -do_print_resource_record(struct passwd *pw, char *hostname) +do_print_resource_record(struct passwd *pw, char *hname) { Key *public; char *comment = NULL; @@ -641,7 +640,7 @@ do_print_resource_record(struct passwd *pw, char *hostname) } public = key_load_public(identity_file, &comment); if (public != NULL) { - export_dns_rr(hostname, public, stdout, print_generic); + export_dns_rr(hname, public, stdout, print_generic); key_free(public); xfree(comment); exit(0); @@ -896,7 +895,7 @@ main(int ac, char **av) if (log_level == SYSLOG_LEVEL_INFO) log_level = SYSLOG_LEVEL_DEBUG1; else { - if (log_level >= SYSLOG_LEVEL_DEBUG1 && + if (log_level >= SYSLOG_LEVEL_DEBUG1 && log_level < SYSLOG_LEVEL_DEBUG3) log_level++; } @@ -911,18 +910,9 @@ main(int ac, char **av) break; case 'a': trials = atoi(optarg); - if (trials < TRIAL_MINIMUM) { - fatal("Minimum primality trials is %d", - TRIAL_MINIMUM); - } break; case 'M': memory = atoi(optarg); - if (memory != 0 && - (memory < LARGE_MINIMUM || memory > LARGE_MAXIMUM)) { - fatal("Invalid memory amount (min %ld, max %ld)", - LARGE_MINIMUM, LARGE_MAXIMUM); - } break; case 'G': do_gen_candidates = 1; diff --git a/openssh/ssh-keyscan.1 b/openssh/ssh-keyscan.1 index 572751f..9efcf52 100644 --- a/openssh/ssh-keyscan.1 +++ b/openssh/ssh-keyscan.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keyscan.1,v 1.17 2003/06/10 09:12:11 jmc Exp $ +.\" $OpenBSD: ssh-keyscan.1,v 1.18 2004/07/12 23:34:25 brad Exp $ .\" .\" Copyright 1995, 1996 by David Mazieres . .\" @@ -97,7 +97,7 @@ to use IPv6 addresses only. If a ssh_known_hosts file is constructed using .Nm without verifying the keys, users will be vulnerable to -.I man in the middle +.Em man in the middle attacks. On the other hand, if the security model allows such a risk, .Nm diff --git a/openssh/ssh-keyscan.c b/openssh/ssh-keyscan.c index 266b23c..3cb52ac 100644 --- a/openssh/ssh-keyscan.c +++ b/openssh/ssh-keyscan.c @@ -7,7 +7,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh-keyscan.c,v 1.47 2004/03/08 09:38:05 djm Exp $"); +RCSID("$OpenBSD: ssh-keyscan.c,v 1.50 2004/08/11 21:44:32 avsm Exp $"); #include "openbsd-compat/sys-queue.h" @@ -49,11 +49,7 @@ int timeout = 5; int maxfd; #define MAXCON (maxfd - 10) -#ifdef HAVE___PROGNAME extern char *__progname; -#else -char *__progname; -#endif fd_set *read_wait; size_t read_wait_size; int ncon; @@ -349,6 +345,7 @@ keygrab_ssh2(con *c) "ssh-dss": "ssh-rsa"; c->c_kex = kex_setup(myproposal); c->c_kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; + c->c_kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; c->c_kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; c->c_kex->verify_host_key = hostjump; @@ -396,8 +393,8 @@ tcpconnect(char *host) error("socket: %s", strerror(errno)); continue; } - if (fcntl(s, F_SETFL, O_NONBLOCK) < 0) - fatal("F_SETFL: %s", strerror(errno)); + if (set_nonblock(s) == -1) + fatal("%s: set_nonblock(%d)", __func__, s); if (connect(s, ai->ai_addr, ai->ai_addrlen) < 0 && errno != EINPROGRESS) error("connect (`%s'): %s", host, strerror(errno)); @@ -497,7 +494,7 @@ congreet(int s) bufsiz = sizeof(buf); cp = buf; - while (bufsiz-- && (n = read(s, cp, 1)) == 1 && *cp != '\n') { + while (bufsiz-- && (n = atomicio(read, s, cp, 1)) == 1 && *cp != '\n') { if (*cp == '\r') *cp = '\n'; cp++; @@ -563,7 +560,7 @@ conread(int s) congreet(s); return; } - n = read(s, c->c_data + c->c_off, c->c_len - c->c_off); + n = atomicio(read, s, c->c_data + c->c_off, c->c_len - c->c_off); if (n < 0) { error("read (%s): %s", c->c_name, strerror(errno)); confree(s); diff --git a/openssh/ssh-keysign.c b/openssh/ssh-keysign.c index 9e9ebe2..5176557 100644 --- a/openssh/ssh-keysign.c +++ b/openssh/ssh-keysign.c @@ -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.15 2004/01/19 21:25:15 markus Exp $"); +RCSID("$OpenBSD: ssh-keysign.c,v 1.16 2004/04/18 23:10:26 djm Exp $"); #include #include @@ -41,15 +41,12 @@ RCSID("$OpenBSD: ssh-keysign.c,v 1.15 2004/01/19 21:25:15 markus Exp $"); #include "canohost.h" #include "pathnames.h" #include "readconf.h" +#include "uidswap.h" /* XXX readconf.c needs these */ uid_t original_real_uid; -#ifdef HAVE___PROGNAME extern char *__progname; -#else -char *__progname; -#endif static int valid_request(struct passwd *pw, char *host, Key **ret, u_char *data, @@ -154,8 +151,11 @@ main(int argc, char **argv) key_fd[0] = open(_PATH_HOST_RSA_KEY_FILE, O_RDONLY); key_fd[1] = open(_PATH_HOST_DSA_KEY_FILE, O_RDONLY); - seteuid(getuid()); - setuid(getuid()); + if ((pw = getpwuid(getuid())) == NULL) + fatal("getpwuid failed"); + pw = pwcopy(pw); + + permanently_set_uid(pw); init_rng(); seed_rng(); @@ -168,7 +168,7 @@ main(int argc, char **argv) /* verify that ssh-keysign is enabled by the admin */ original_real_uid = getuid(); /* XXX readconf.c needs this */ initialize_options(&options); - (void)read_config_file(_PATH_HOST_CONFIG_FILE, "", &options); + (void)read_config_file(_PATH_HOST_CONFIG_FILE, "", &options, 0); fill_default_options(&options); if (options.enable_ssh_keysign != 1) fatal("ssh-keysign not enabled in %s", @@ -177,10 +177,6 @@ main(int argc, char **argv) if (key_fd[0] == -1 && key_fd[1] == -1) fatal("could not open any host key"); - if ((pw = getpwuid(getuid())) == NULL) - fatal("getpwuid failed"); - pw = pwcopy(pw); - SSLeay_add_all_algorithms(); for (i = 0; i < 256; i++) rnd[i] = arc4random(); diff --git a/openssh/ssh-rand-helper.c b/openssh/ssh-rand-helper.c index 9c9c495..2d8707e 100644 --- a/openssh/ssh-rand-helper.c +++ b/openssh/ssh-rand-helper.c @@ -63,15 +63,7 @@ RCSID("$Id$"); # define SSH_PRNG_COMMAND_FILE SSHDIR "/ssh_prng_cmds" #endif -#ifdef HAVE___PROGNAME extern char *__progname; -#else -char *__progname; -#endif - -#ifndef offsetof -# define offsetof(type, member) ((size_t) &((type *)0)->member) -#endif #define WHITESPACE " \t\n" diff --git a/openssh/ssh.1 b/openssh/ssh.1 index 31eb66c..0ff77ea 100644 --- a/openssh/ssh.1 +++ b/openssh/ssh.1 @@ -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.182 2004/03/05 10:53:58 markus Exp $ +.\" $OpenBSD: ssh.1,v 1.194 2004/08/12 21:41:13 jakob Exp $ .Dd September 25, 1999 .Dt SSH 1 .Os @@ -43,14 +43,14 @@ .Nd OpenSSH SSH client (remote login program) .Sh SYNOPSIS .Nm ssh -.Op Fl 1246AaCfgkNnqsTtVvXxY +.Op Fl 1246AaCfgkMNnqsTtVvXxY .Op Fl b Ar bind_address .Op Fl c Ar cipher_spec +.Bk -words .Op Fl D Ar port .Op Fl e Ar escape_char .Op Fl F Ar configfile .Op Fl i Ar identity_file -.Bk -words .Oo Fl L Xo .Sm off .Ar port : @@ -74,6 +74,7 @@ .Sm on .Xc .Oc +.Op Fl S Ar ctl .Oo Ar user Ns @ Oc Ns Ar hostname .Op Ar command .Sh DESCRIPTION @@ -241,8 +242,8 @@ Additionally, supports hostbased or challenge response authentication. .Pp Protocol 2 provides additional mechanisms for confidentiality -(the traffic is encrypted using 3DES, Blowfish, CAST128 or Arcfour) -and integrity (hmac-md5, hmac-sha1). +(the traffic is encrypted using AES, 3DES, Blowfish, CAST128 or Arcfour) +and integrity (hmac-md5, hmac-sha1, hmac-ripemd160). Note that protocol 1 lacks a strong mechanism for ensuring the integrity of the connection. .Ss Login session and remote execution @@ -302,11 +303,18 @@ Display a list of escape characters. 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 +Open command line. +Currently this allows the addition of port forwardings using the .Fl L and .Fl R -options). +options (see below). +It also allows the cancellation of existing remote port-forwardings +using +.Fl KR Ar hostport . +Basic help is available, using the +.Fl h +option. .It Cm ~R Request rekeying of the connection (only useful for SSH protocol version 2 and if the peer supports it). @@ -392,6 +400,15 @@ The option can be used to prevent logins to machines whose host key is not known or has changed. .Pp +.Nm +can be configured to verify host identification using fingerprint resource +records (SSHFP) published in DNS. +The +.Cm VerifyHostKeyDNS +option can be used to control how DNS lookups are performed. +SSHFP resource records can be generated using +.Xr ssh-keygen 1 . +.Pp The options are as follows: .Bl -tag -width Ds .It Fl 1 @@ -442,13 +459,18 @@ The default value can be set on a host-by-host basis in the configuration files; see the .Cm Compression option. -.It Fl c Ar blowfish | 3des | des -Selects the cipher to use for encrypting the session. -.Ar 3des -is used by default. -It is believed to be secure. +.It Fl c Ar cipher_spec +Selects the cipher specification for encrypting the session. +.Pp +Protocol version 1 allows specification of a single cipher. +The suported values are +.Dq 3des , +.Dq blowfish +and +.Dq des . .Ar 3des (triple-des) is an encrypt-decrypt-encrypt triple with three different keys. +It is believed to be secure. .Ar blowfish is a fast block cipher; it appears very secure and is much faster than .Ar 3des . @@ -460,12 +482,30 @@ that do not support the .Ar 3des cipher. Its use is strongly discouraged due to cryptographic weaknesses. -.It Fl c Ar cipher_spec -Additionally, for protocol version 2 a comma-separated list of ciphers can -be specified in order of preference. -See -.Cm Ciphers -for more information. +The default is +.Dq 3des . +.Pp +For protocol version 2 +.Ar cipher_spec +is a comma-separated list of ciphers +listed in order of preference. +The supported ciphers are +.Dq 3des-cbc , +.Dq aes128-cbc , +.Dq aes192-cbc , +.Dq aes256-cbc , +.Dq aes128-ctr , +.Dq aes192-ctr , +.Dq aes256-ctr , +.Dq arcfour , +.Dq blowfish-cbc , +and +.Dq cast128-cbc . +The default is +.Bd -literal + ``aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour, + aes192-cbc,aes256-cbc'' +.Ed .It Fl D Ar port Specifies a local .Dq dynamic @@ -568,6 +608,17 @@ IPv6 addresses can be specified with an alternative syntax: .It Fl l Ar login_name Specifies the user to log in as on the remote machine. This also may be specified on a per-host basis in the configuration file. +.It Fl M +Places the +.Nm +client into +.Dq master +mode for connection sharing. +Refer to the description of +.Cm ControlMaster +in +.Xr ssh_config 5 +for details. .It Fl m Ar mac_spec Additionally, for protocol version 2 a comma-separated list of MAC (message authentication code) algorithms can @@ -618,7 +669,9 @@ For full details of the options listed below, and their possible values, see .It Compression .It CompressionLevel .It ConnectionAttempts -.It ConnectionTimeout +.It ConnectTimeout +.It ControlMaster +.It ControlPath .It DynamicForward .It EscapeChar .It ForwardAgent @@ -649,6 +702,7 @@ For full details of the options listed below, and their possible values, see .It RemoteForward .It RhostsRSAAuthentication .It RSAAuthentication +.It SendEnv .It ServerAliveInterval .It ServerAliveCountMax .It SmartcardDevice @@ -693,6 +747,15 @@ IPv6 addresses can be specified with an alternative syntax: .Ar hostport . .Xc .Sm on +.It Fl S Ar ctl +Specifies the location of a control socket for connection sharing. +Refer to the description of +.Cm ControlPath +and +.Cm ControlMaster +in +.Xr ssh_config 5 +for details. .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 @@ -885,6 +948,8 @@ the convenience of the user. This is the per-user configuration file. The file format and configuration options are described in .Xr ssh_config 5 . +Because of the potential for abuse, this file must have strict permissions: +read/write for the user, and not accessible by others. .It Pa $HOME/.ssh/authorized_keys Lists the public keys (RSA/DSA) that can be used for logging in as this user. The format of this file is described in the diff --git a/openssh/ssh.c b/openssh/ssh.c index e655e68..1419f98 100644 --- a/openssh/ssh.c +++ b/openssh/ssh.c @@ -40,7 +40,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh.c,v 1.209 2004/03/11 10:21:17 markus Exp $"); +RCSID("$OpenBSD: ssh.c,v 1.224 2004/07/28 09:40:29 markus Exp $"); #include #include @@ -53,31 +53,31 @@ RCSID("$OpenBSD: ssh.c,v 1.209 2004/03/11 10:21:17 markus Exp $"); #include "xmalloc.h" #include "packet.h" #include "buffer.h" +#include "bufaux.h" #include "channels.h" #include "key.h" #include "authfd.h" #include "authfile.h" #include "pathnames.h" +#include "dispatch.h" #include "clientloop.h" #include "log.h" #include "readconf.h" #include "sshconnect.h" -#include "tildexpand.h" -#include "dispatch.h" #include "misc.h" #include "kex.h" #include "mac.h" -#include "sshtty.h" +#include "sshpty.h" +#include "match.h" +#include "msg.h" +#include "monitor_fdpass.h" +#include "uidswap.h" #ifdef SMARTCARD #include "scard.h" #endif -#ifdef HAVE___PROGNAME extern char *__progname; -#else -char *__progname; -#endif /* Flag indicating whether debug mode is on. This can be set on the command line. */ int debug_flag = 0; @@ -141,16 +141,23 @@ static int client_global_request_id = 0; /* pid of proxycommand child process */ pid_t proxy_command_pid = 0; +/* fd to control socket */ +int control_fd = -1; + +/* Only used in control client mode */ +volatile sig_atomic_t control_client_terminate = 0; +u_int control_server_pid = 0; + /* Prints a help message to the user. This function never returns. */ static void usage(void) { fprintf(stderr, -"usage: ssh [-1246AaCfghkNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n" +"usage: ssh [-1246AaCfghkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n" " [-D port] [-e escape_char] [-F configfile] [-i identity_file]\n" " [-L port:host:hostport] [-l login_name] [-m mac_spec] [-o option]\n" -" [-p port] [-R port:host:hostport] [user@]hostname [command]\n" +" [-p port] [-R port:host:hostport] [-S ctl] [user@]hostname [command]\n" ); exit(1); } @@ -158,6 +165,7 @@ usage(void) static int ssh_session(void); static int ssh_session2(void); static void load_public_identity_files(void); +static void control_client(const char *path); /* * Main program for the ssh client. @@ -228,7 +236,7 @@ main(int ac, char **av) again: while ((opt = getopt(ac, av, - "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:NPR:TVXY")) != -1) { + "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:MNPR:S:TVXY")) != -1) { switch (opt) { case '1': options.protocol = SSH_PROTO_1; @@ -337,7 +345,7 @@ again: if (ciphers_valid(optarg)) { /* SSH2 only */ options.ciphers = xstrdup(optarg); - options.cipher = SSH_CIPHER_ILLEGAL; + options.cipher = SSH_CIPHER_INVALID; } else { /* SSH1 only */ options.cipher = cipher_number(optarg); @@ -364,6 +372,10 @@ again: exit(1); } break; + case 'M': + options.control_master = + (options.control_master >= 1) ? 2 : 1; + break; case 'p': options.port = a2port(optarg); if (options.port == 0) { @@ -432,6 +444,11 @@ again: case 's': subsystem_flag = 1; break; + case 'S': + if (options.control_path != NULL) + free(options.control_path); + options.control_path = xstrdup(optarg); + break; case 'b': options.bind_address = optarg; break; @@ -526,16 +543,17 @@ again: * file if the user specifies a config file on the command line. */ if (config != NULL) { - if (!read_config_file(config, host, &options)) + if (!read_config_file(config, host, &options, 0)) fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); } else { snprintf(buf, sizeof buf, "%.100s/%.100s", pw->pw_dir, _PATH_SSH_USER_CONFFILE); - (void)read_config_file(buf, host, &options); + (void)read_config_file(buf, host, &options, 1); /* Read systemwide configuration file after use config. */ - (void)read_config_file(_PATH_HOST_CONFIG_FILE, host, &options); + (void)read_config_file(_PATH_HOST_CONFIG_FILE, host, + &options, 0); } /* Fill configuration defaults. */ @@ -565,6 +583,13 @@ again: strcmp(options.proxy_command, "none") == 0) options.proxy_command = NULL; + if (options.control_path != NULL) { + options.control_path = tilde_expand_filename( + options.control_path, original_real_uid); + } + if (options.control_path != NULL && options.control_master == 0) + control_client(options.control_path); /* This doesn't return */ + /* Open a connection to the remote host. */ if (ssh_connect(host, &hostaddr, options.port, options.address_family, options.connection_attempts, @@ -620,8 +645,10 @@ again: * user's home directory if it happens to be on a NFS volume where * root is mapped to nobody. */ - seteuid(original_real_uid); - setuid(original_real_uid); + if (original_effective_uid == 0) { + PRIV_START; + permanently_set_uid(pw); + } /* * Now that we are back to our own permissions, create ~/.ssh @@ -677,6 +704,9 @@ again: exit_status = compat20 ? ssh_session2() : ssh_session(); packet_close(); + if (options.control_path != NULL && control_fd != -1) + unlink(options.control_path); + /* * Send SIGHUP to proxy command if used. We don't wait() in * case it hangs and instead rely on init to reap the child @@ -776,17 +806,17 @@ x11_get_proto(char **_proto, char **_data) * for the local connection. */ if (!got_data) { - u_int32_t rand = 0; + u_int32_t rnd = 0; logit("Warning: No xauth data; " "using fake authentication data for X11 forwarding."); strlcpy(proto, SSH_X11_PROTO, sizeof proto); for (i = 0; i < 16; i++) { if (i % 4 == 0) - rand = arc4random(); + rnd = arc4random(); snprintf(data + 2 * i, sizeof data - 2 * i, "%02x", - rand & 0xff); - rand >>= 8; + rnd & 0xff); + rnd >>= 8; } } } @@ -973,7 +1003,7 @@ ssh_session(void) } static void -client_subsystem_reply(int type, u_int32_t seq, void *ctxt) +ssh_subsystem_reply(int type, u_int32_t seq, void *ctxt) { int id, len; @@ -1005,40 +1035,53 @@ client_global_request_reply_fwd(int type, u_int32_t seq, void *ctxt) options.remote_forwards[i].port); } -/* request pty/x11/agent/tcpfwd/shell for channel */ static void -ssh_session2_setup(int id, void *arg) +ssh_control_listener(void) { - int len; - int interactive = 0; - struct termios tio; + struct sockaddr_un addr; + mode_t old_umask; + int addr_len; - debug2("ssh_session2_setup: id %d", id); + if (options.control_path == NULL || options.control_master <= 0) + return; - if (tty_flag) { - struct winsize ws; - char *cp; - cp = getenv("TERM"); - if (!cp) - cp = ""; - /* Store window size in the packet. */ - if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) - memset(&ws, 0, sizeof(ws)); + memset(&addr, '\0', sizeof(addr)); + addr.sun_family = AF_UNIX; + addr_len = offsetof(struct sockaddr_un, sun_path) + + strlen(options.control_path) + 1; - channel_request_start(id, "pty-req", 0); - packet_put_cstring(cp); - packet_put_int(ws.ws_col); - packet_put_int(ws.ws_row); - packet_put_int(ws.ws_xpixel); - packet_put_int(ws.ws_ypixel); - tio = get_saved_tio(); - tty_make_modes(/*ignored*/ 0, &tio); - packet_send(); - interactive = 1; - /* XXX wait for reply */ + if (strlcpy(addr.sun_path, options.control_path, + sizeof(addr.sun_path)) >= sizeof(addr.sun_path)) + fatal("ControlPath too long"); + + if ((control_fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) + fatal("%s socket(): %s\n", __func__, strerror(errno)); + + old_umask = umask(0177); + if (bind(control_fd, (struct sockaddr*)&addr, addr_len) == -1) { + control_fd = -1; + if (errno == EINVAL) + fatal("ControlSocket %s already exists", + options.control_path); + else + fatal("%s bind(): %s\n", __func__, strerror(errno)); } - if (options.forward_x11 && - getenv("DISPLAY") != NULL) { + umask(old_umask); + + if (listen(control_fd, 64) == -1) + fatal("%s listen(): %s\n", __func__, strerror(errno)); + + set_nonblock(control_fd); +} + +/* request pty/x11/agent/tcpfwd/shell for channel */ +static void +ssh_session2_setup(int id, void *arg) +{ + extern char **environ; + + int interactive = tty_flag; + if (options.forward_x11 && getenv("DISPLAY") != NULL) { char *proto, *data; /* Get reasonable local authentication information. */ x11_get_proto(&proto, &data); @@ -1056,27 +1099,8 @@ ssh_session2_setup(int id, void *arg) packet_send(); } - len = buffer_len(&command); - if (len > 0) { - if (len > 900) - len = 900; - if (subsystem_flag) { - debug("Sending subsystem: %.*s", len, (u_char *)buffer_ptr(&command)); - channel_request_start(id, "subsystem", /*want reply*/ 1); - /* register callback for reply */ - /* XXX we assume that client_loop has already been called */ - dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &client_subsystem_reply); - dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &client_subsystem_reply); - } else { - debug("Sending command: %.*s", len, (u_char *)buffer_ptr(&command)); - channel_request_start(id, "exec", 0); - } - packet_put_string(buffer_ptr(&command), buffer_len(&command)); - packet_send(); - } else { - channel_request_start(id, "shell", 0); - packet_send(); - } + client_session2_setup(id, tty_flag, subsystem_flag, getenv("TERM"), + NULL, fileno(stdin), &command, environ, &ssh_subsystem_reply); packet_set_interactive(interactive); } @@ -1122,7 +1146,7 @@ ssh_session2_open(void) channel_send_open(c->self); if (!no_shell_flag) - channel_register_confirm(c->self, ssh_session2_setup); + channel_register_confirm(c->self, ssh_session2_setup, NULL); return c->self; } @@ -1134,6 +1158,7 @@ ssh_session2(void) /* XXX should be pre-session */ ssh_init_forwarding(); + ssh_control_listener(); if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN)) id = ssh_session2_open(); @@ -1187,3 +1212,149 @@ load_public_identity_files(void) options.identity_keys[i] = public; } } + +static void +control_client_sighandler(int signo) +{ + control_client_terminate = signo; +} + +static void +control_client_sigrelay(int signo) +{ + if (control_server_pid > 1) + kill(control_server_pid, signo); +} + +static int +env_permitted(char *env) +{ + int i; + char name[1024], *cp; + + strlcpy(name, env, sizeof(name)); + if ((cp = strchr(name, '=')) == NULL) + return (0); + + *cp = '\0'; + + for (i = 0; i < options.num_send_env; i++) + if (match_pattern(name, options.send_env[i])) + return (1); + + return (0); +} + +static void +control_client(const char *path) +{ + struct sockaddr_un addr; + int i, r, sock, exitval, num_env, addr_len; + Buffer m; + char *cp; + extern char **environ; + + memset(&addr, '\0', sizeof(addr)); + addr.sun_family = AF_UNIX; + addr_len = offsetof(struct sockaddr_un, sun_path) + + strlen(path) + 1; + + if (strlcpy(addr.sun_path, path, + sizeof(addr.sun_path)) >= sizeof(addr.sun_path)) + fatal("ControlPath too long"); + + if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) + fatal("%s socket(): %s", __func__, strerror(errno)); + + if (connect(sock, (struct sockaddr*)&addr, addr_len) == -1) + fatal("Couldn't connect to %s: %s", path, strerror(errno)); + + if ((cp = getenv("TERM")) == NULL) + cp = ""; + + buffer_init(&m); + + /* Get PID of controlee */ + if (ssh_msg_recv(sock, &m) == -1) + fatal("%s: msg_recv", __func__); + if (buffer_get_char(&m) != 0) + fatal("%s: wrong version", __func__); + /* Connection allowed? */ + if (buffer_get_int(&m) != 1) + fatal("Connection to master denied"); + control_server_pid = buffer_get_int(&m); + + buffer_clear(&m); + buffer_put_int(&m, tty_flag); + buffer_put_int(&m, subsystem_flag); + buffer_put_cstring(&m, cp); + + buffer_append(&command, "\0", 1); + buffer_put_cstring(&m, buffer_ptr(&command)); + + if (options.num_send_env == 0 || environ == NULL) { + buffer_put_int(&m, 0); + } else { + /* Pass environment */ + num_env = 0; + for (i = 0; environ[i] != NULL; i++) + if (env_permitted(environ[i])) + num_env++; /* Count */ + + buffer_put_int(&m, num_env); + + for (i = 0; environ[i] != NULL && num_env >= 0; i++) + if (env_permitted(environ[i])) { + num_env--; + buffer_put_cstring(&m, environ[i]); + } + } + + if (ssh_msg_send(sock, /* version */0, &m) == -1) + fatal("%s: msg_send", __func__); + + mm_send_fd(sock, STDIN_FILENO); + mm_send_fd(sock, STDOUT_FILENO); + mm_send_fd(sock, STDERR_FILENO); + + /* Wait for reply, so master has a chance to gather ttymodes */ + buffer_clear(&m); + if (ssh_msg_recv(sock, &m) == -1) + fatal("%s: msg_recv", __func__); + if (buffer_get_char(&m) != 0) + fatal("%s: master returned error", __func__); + buffer_free(&m); + + signal(SIGINT, control_client_sighandler); + signal(SIGTERM, control_client_sighandler); + signal(SIGWINCH, control_client_sigrelay); + + if (tty_flag) + enter_raw_mode(); + + /* Stick around until the controlee closes the client_fd */ + exitval = 0; + for (;!control_client_terminate;) { + r = read(sock, &exitval, sizeof(exitval)); + if (r == 0) { + debug2("Received EOF from master"); + break; + } + if (r > 0) + debug2("Received exit status from master %d", exitval); + if (r == -1 && errno != EINTR) + fatal("%s: read %s", __func__, strerror(errno)); + } + + if (control_client_terminate) + debug2("Exiting on signal %d", control_client_terminate); + + close(sock); + + leave_raw_mode(); + + if (tty_flag && options.log_level != SYSLOG_LEVEL_QUIET) + fprintf(stderr, "Connection to master closed.\r\n"); + + exit(exitval); +} diff --git a/openssh/ssh1.h b/openssh/ssh1.h index 98d1dc9..cc7fbc8 100644 --- a/openssh/ssh1.h +++ b/openssh/ssh1.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh1.h,v 1.3 2001/05/30 12:55:13 markus Exp $ */ +/* $OpenBSD: ssh1.h,v 1.4 2004/07/11 17:48:47 deraadt Exp $ */ /* * Author: Tatu Ylonen @@ -29,8 +29,8 @@ #define SSH_SMSG_AUTH_RSA_CHALLENGE 7 /* int (BIGNUM) */ #define SSH_CMSG_AUTH_RSA_RESPONSE 8 /* int (BIGNUM) */ #define SSH_CMSG_AUTH_PASSWORD 9 /* pass (string) */ -#define SSH_CMSG_REQUEST_PTY 10 /* TERM, tty modes */ -#define SSH_CMSG_WINDOW_SIZE 11 /* row,col,xpix,ypix */ +#define SSH_CMSG_REQUEST_PTY 10 /* TERM, tty modes */ +#define SSH_CMSG_WINDOW_SIZE 11 /* row,col,xpix,ypix */ #define SSH_CMSG_EXEC_SHELL 12 /* */ #define SSH_CMSG_EXEC_CMD 13 /* cmd (string) */ #define SSH_SMSG_SUCCESS 14 /* */ @@ -45,7 +45,7 @@ #define SSH_MSG_CHANNEL_DATA 23 /* ch,data (int,str) */ #define SSH_MSG_CHANNEL_CLOSE 24 /* channel (int) */ #define SSH_MSG_CHANNEL_CLOSE_CONFIRMATION 25 /* channel (int) */ -/* SSH_CMSG_X11_REQUEST_FORWARDING 26 OBSOLETE */ +/* SSH_CMSG_X11_REQUEST_FORWARDING 26 OBSOLETE */ #define SSH_SMSG_X11_OPEN 27 /* channel (int) */ #define SSH_CMSG_PORT_FORWARD_REQUEST 28 /* p,host,hp (i,s,i) */ #define SSH_MSG_PORT_OPEN 29 /* ch,h,p (i,s,i) */ diff --git a/openssh/ssh_config.5 b/openssh/ssh_config.5 index 05581ec..0e1a031 100644 --- a/openssh/ssh_config.5 +++ b/openssh/ssh_config.5 @@ -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.29 2004/03/05 10:53:58 markus Exp $ +.\" $OpenBSD: ssh_config.5,v 1.38 2004/06/26 09:11:14 jmc Exp $ .Dd September 25, 1999 .Dt SSH_CONFIG 5 .Os @@ -185,6 +185,18 @@ The default is Specifies the ciphers allowed for protocol version 2 in order of preference. Multiple ciphers must be comma-separated. +The supported ciphers are +.Dq 3des-cbc , +.Dq aes128-cbc , +.Dq aes192-cbc , +.Dq aes256-cbc , +.Dq aes128-ctr , +.Dq aes192-ctr , +.Dq aes256-ctr , +.Dq arcfour , +.Dq blowfish-cbc , +and +.Dq cast128-cbc . The default is .Bd -literal ``aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour, @@ -232,6 +244,37 @@ 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 ControlMaster +Enables the sharing of multiple sessions over a single network connection. +When set to +.Dq yes +.Nm ssh +will listen for connections on a control socket specified using the +.Cm ControlPath +argument. +Additional sessions can connect to this socket using the same +.Cm ControlPath +with +.Cm ControlMaster +set to +.Dq no +(the default). +These sessions will reuse the master instance's network connection rather +than initiating new ones. +Setting this to +.Dq ask +will cause +.Nm ssh +to listen for control connections, but require confirmation using the +.Ev SSH_ASKPASS +program before they are accepted (see +.Xr ssh-add 1 +for details). +.It Cm ControlPath +Specify the path to the control socket used for connection sharing. +See +.Cm ControlMaster +above. .It Cm DynamicForward Specifies that a TCP/IP port on the local machine be forwarded over the secure channel, and the application @@ -313,7 +356,7 @@ if the .Cm ForwardX11Trusted option is also enabled. .It Cm ForwardX11Trusted -If the this option is set to +If this option is set to .Dq yes then remote X11 clients will have full access to the original X11 display. If this option is set to @@ -410,7 +453,7 @@ identities will be tried in sequence. Specifies that .Nm ssh should only use the authentication identity files configured in the -.Nm +.Nm files, even if the .Nm ssh-agent @@ -570,6 +613,27 @@ running. The default is .Dq yes . Note that this option applies to protocol version 1 only. +.It Cm SendEnv +Specifies what variables from the local +.Xr environ 7 +should be sent to the server. +Note that environment passing is only supported for protocol 2, the +server must also support it, and the server must be configured to +accept these environment variables. +Refer to +.Cm AcceptEnv +in +.Xr sshd_config 5 +for how to configure the server. +Variables are specified by name, which may contain the wildcard characters +.Ql \&* +and +.Ql \&? . +Multiple environment variables may be separated by whitespace or spread +across multiple +.Cm SendEnv +directives. +The default is not to send any environment variables. .It Cm ServerAliveInterval Sets a timeout interval in seconds after which if no data has been received from the server, @@ -729,9 +793,8 @@ The format of this file is described above. This file is used by the .Nm ssh client. -This file does not usually contain any sensitive information, -but the recommended permissions are read/write for the user, and not -accessible by others. +Because of the potential for abuse, this file must have strict permissions: +read/write for the user, and not accessible by others. .It Pa /etc/ssh/ssh_config Systemwide configuration file. This file provides defaults for those diff --git a/openssh/sshconnect.c b/openssh/sshconnect.c index dfeddd3..11008e5 100644 --- a/openssh/sshconnect.c +++ b/openssh/sshconnect.c @@ -13,7 +13,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect.c,v 1.156 2004/01/25 03:49:09 djm Exp $"); +RCSID("$OpenBSD: sshconnect.c,v 1.158 2004/06/21 17:36:31 avsm Exp $"); #include @@ -31,7 +31,6 @@ RCSID("$OpenBSD: sshconnect.c,v 1.156 2004/01/25 03:49:09 djm Exp $"); #include "readconf.h" #include "atomicio.h" #include "misc.h" -#include "readpass.h" #include "dns.h" @@ -768,19 +767,19 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, break; case HOST_CHANGED: if (options.check_host_ip && host_ip_differ) { - char *msg; + char *key_msg; if (ip_status == HOST_NEW) - msg = "is unknown"; + key_msg = "is unknown"; else if (ip_status == HOST_OK) - msg = "is unchanged"; + key_msg = "is unchanged"; else - msg = "has a different value"; + key_msg = "has a different value"; error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); error("@ WARNING: POSSIBLE DNS SPOOFING DETECTED! @"); error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); error("The %s host key for %s has changed,", type, host); error("and the key for the according IP address %s", ip); - error("%s. This could either mean that", msg); + error("%s. This could either mean that", key_msg); error("DNS SPOOFING is happening or the IP address for the host"); error("and its host key have changed at the same time."); if (ip_status != HOST_NEW) diff --git a/openssh/sshconnect1.c b/openssh/sshconnect1.c index 2f89964..6e2e31c 100644 --- a/openssh/sshconnect1.c +++ b/openssh/sshconnect1.c @@ -13,7 +13,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect1.c,v 1.56 2003/08/28 12:54:34 markus Exp $"); +RCSID("$OpenBSD: sshconnect1.c,v 1.60 2004/07/28 09:40:29 markus Exp $"); #include #include @@ -24,7 +24,7 @@ RCSID("$OpenBSD: sshconnect1.c,v 1.56 2003/08/28 12:54:34 markus Exp $"); #include "rsa.h" #include "buffer.h" #include "packet.h" -#include "mpaux.h" +#include "kex.h" #include "uidswap.h" #include "log.h" #include "readconf.h" @@ -32,7 +32,7 @@ RCSID("$OpenBSD: sshconnect1.c,v 1.56 2003/08/28 12:54:34 markus Exp $"); #include "authfd.h" #include "sshconnect.h" #include "authfile.h" -#include "readpass.h" +#include "misc.h" #include "cipher.h" #include "canohost.h" #include "auth.h" @@ -476,7 +476,7 @@ ssh_kex(char *host, struct sockaddr *hostaddr) u_char cookie[8]; u_int supported_ciphers; u_int server_flags, client_flags; - u_int32_t rand = 0; + u_int32_t rnd = 0; debug("Waiting for server public key."); @@ -528,7 +528,7 @@ ssh_kex(char *host, struct sockaddr *hostaddr) client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN; - compute_session_id(session_id, cookie, host_key->rsa->n, server_key->rsa->n); + derive_ssh1_session_id(host_key->rsa->n, server_key->rsa->n, cookie, session_id); /* Generate a session key. */ arc4random_stir(); @@ -540,9 +540,9 @@ ssh_kex(char *host, struct sockaddr *hostaddr) */ for (i = 0; i < 32; i++) { if (i % 4 == 0) - rand = arc4random(); - session_key[i] = rand & 0xff; - rand >>= 8; + rnd = arc4random(); + session_key[i] = rnd & 0xff; + rnd >>= 8; } /* @@ -598,7 +598,7 @@ ssh_kex(char *host, struct sockaddr *hostaddr) if (options.cipher == SSH_CIPHER_NOT_SET) { if (cipher_mask_ssh1(1) & supported_ciphers & (1 << ssh_cipher_default)) options.cipher = ssh_cipher_default; - } else if (options.cipher == SSH_CIPHER_ILLEGAL || + } else if (options.cipher == SSH_CIPHER_INVALID || !(cipher_mask_ssh1(1) & (1 << options.cipher))) { logit("No valid SSH1 cipher, using %.100s instead.", cipher_name(ssh_cipher_default)); diff --git a/openssh/sshconnect2.c b/openssh/sshconnect2.c index c261dfd..68d56d0 100644 --- a/openssh/sshconnect2.c +++ b/openssh/sshconnect2.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect2.c,v 1.135 2004/03/05 10:53:58 markus Exp $"); +RCSID("$OpenBSD: sshconnect2.c,v 1.138 2004/06/13 12:53:24 djm Exp $"); #include "openbsd-compat/sys-queue.h" @@ -43,7 +43,7 @@ RCSID("$OpenBSD: sshconnect2.c,v 1.135 2004/03/05 10:53:58 markus Exp $"); #include "authfd.h" #include "log.h" #include "readconf.h" -#include "readpass.h" +#include "misc.h" #include "match.h" #include "dispatch.h" #include "canohost.h" @@ -120,6 +120,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) /* start key exchange */ kex = kex_setup(myproposal); kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; + kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; kex->client_version_string=client_version_string; kex->server_version_string=server_version_string; @@ -458,7 +459,7 @@ input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt) * moved to the end of the queue. this also avoids confusion by * duplicate keys */ - TAILQ_FOREACH_REVERSE(id, &authctxt->keys, next, idlist) { + TAILQ_FOREACH_REVERSE(id, &authctxt->keys, idlist, next) { if (key_equal(key, id->key)) { sent = sign_and_send_pubkey(authctxt, id); break; diff --git a/openssh/sshd.8 b/openssh/sshd.8 index 34413e2..233b000 100644 --- a/openssh/sshd.8 +++ b/openssh/sshd.8 @@ -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.200 2003/10/08 08:27:36 jmc Exp $ +.\" $OpenBSD: sshd.8,v 1.201 2004/05/02 11:54:31 dtucker Exp $ .Dd September 25, 1999 .Dt SSHD 8 .Os @@ -196,7 +196,7 @@ configuration file. .Nm rereads its configuration file when it receives a hangup signal, .Dv SIGHUP , -by executing itself with the name it was started as, i.e., +by executing itself with the name and options it was started with, e.g., .Pa /usr/sbin/sshd . .Pp The options are as follows: diff --git a/openssh/sshd.c b/openssh/sshd.c index 6342842..60f63ef 100644 --- a/openssh/sshd.c +++ b/openssh/sshd.c @@ -42,7 +42,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshd.c,v 1.290 2004/03/11 10:21:17 markus Exp $"); +RCSID("$OpenBSD: sshd.c,v 1.301 2004/08/11 11:50:09 dtucker Exp $"); #include #include @@ -60,12 +60,12 @@ RCSID("$OpenBSD: sshd.c,v 1.290 2004/03/11 10:21:17 markus Exp $"); #include "rsa.h" #include "sshpty.h" #include "packet.h" -#include "mpaux.h" #include "log.h" #include "servconf.h" #include "uidswap.h" #include "compat.h" #include "buffer.h" +#include "bufaux.h" #include "cipher.h" #include "kex.h" #include "key.h" @@ -77,6 +77,7 @@ RCSID("$OpenBSD: sshd.c,v 1.290 2004/03/11 10:21:17 markus Exp $"); #include "canohost.h" #include "auth.h" #include "misc.h" +#include "msg.h" #include "dispatch.h" #include "channels.h" #include "session.h" @@ -96,11 +97,13 @@ int deny_severity = LOG_WARNING; #define O_NOCTTY 0 #endif -#ifdef HAVE___PROGNAME +/* Re-exec fds */ +#define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1) +#define REEXEC_STARTUP_PIPE_FD (STDERR_FILENO + 2) +#define REEXEC_CONFIG_PASS_FD (STDERR_FILENO + 3) +#define REEXEC_MIN_FREE_FD (STDERR_FILENO + 4) + extern char *__progname; -#else -char *__progname; -#endif /* Server configuration options. */ ServerOptions options; @@ -138,6 +141,12 @@ int log_stderr = 0; char **saved_argv; int saved_argc; +/* re-exec */ +int rexeced_flag = 0; +int rexec_flag = 1; +int rexec_argc = 0; +char **rexec_argv; + /* * The sockets that the server is listening; this is used in the SIGHUP * signal handler. @@ -201,12 +210,12 @@ int startup_pipe; /* in child */ int use_privsep; struct monitor *pmonitor = NULL; -/* message to be displayed after login */ -Buffer loginmsg; - /* global authentication context */ Authctxt *the_authctxt = NULL; +/* 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); @@ -650,6 +659,7 @@ privsep_postauth(Authctxt *authctxt) else if (pmonitor->m_pid != 0) { debug2("User child is on pid %ld", (long)pmonitor->m_pid); close(pmonitor->m_recvfd); + buffer_clear(&loginmsg); monitor_child_postauth(pmonitor); /* NEVERREACHED */ @@ -772,6 +782,87 @@ usage(void) exit(1); } +static void +send_rexec_state(int fd, Buffer *conf) +{ + Buffer m; + + debug3("%s: entering fd = %d config len %d", __func__, fd, + buffer_len(conf)); + + /* + * Protocol from reexec master to child: + * string configuration + * u_int ephemeral_key_follows + * bignum e (only if ephemeral_key_follows == 1) + * bignum n " + * bignum d " + * bignum iqmp " + * bignum p " + * bignum q " + */ + buffer_init(&m); + buffer_put_cstring(&m, buffer_ptr(conf)); + + if (sensitive_data.server_key != NULL && + sensitive_data.server_key->type == KEY_RSA1) { + buffer_put_int(&m, 1); + buffer_put_bignum(&m, sensitive_data.server_key->rsa->e); + buffer_put_bignum(&m, sensitive_data.server_key->rsa->n); + buffer_put_bignum(&m, sensitive_data.server_key->rsa->d); + buffer_put_bignum(&m, sensitive_data.server_key->rsa->iqmp); + buffer_put_bignum(&m, sensitive_data.server_key->rsa->p); + buffer_put_bignum(&m, sensitive_data.server_key->rsa->q); + } else + buffer_put_int(&m, 0); + + if (ssh_msg_send(fd, 0, &m) == -1) + fatal("%s: ssh_msg_send failed", __func__); + + buffer_free(&m); + + debug3("%s: done", __func__); +} + +static void +recv_rexec_state(int fd, Buffer *conf) +{ + Buffer m; + char *cp; + u_int len; + + debug3("%s: entering fd = %d", __func__, fd); + + buffer_init(&m); + + if (ssh_msg_recv(fd, &m) == -1) + fatal("%s: ssh_msg_recv failed", __func__); + if (buffer_get_char(&m) != 0) + fatal("%s: rexec version mismatch", __func__); + + cp = buffer_get_string(&m, &len); + if (conf != NULL) + buffer_append(conf, cp, len + 1); + xfree(cp); + + if (buffer_get_int(&m)) { + if (sensitive_data.server_key != NULL) + key_free(sensitive_data.server_key); + sensitive_data.server_key = key_new_private(KEY_RSA1); + buffer_get_bignum(&m, sensitive_data.server_key->rsa->e); + buffer_get_bignum(&m, sensitive_data.server_key->rsa->n); + buffer_get_bignum(&m, sensitive_data.server_key->rsa->d); + buffer_get_bignum(&m, sensitive_data.server_key->rsa->iqmp); + buffer_get_bignum(&m, sensitive_data.server_key->rsa->p); + buffer_get_bignum(&m, sensitive_data.server_key->rsa->q); + rsa_generate_additional_parameters( + sensitive_data.server_key->rsa); + } + buffer_free(&m); + + debug3("%s: done", __func__); +} + /* * Main program for the daemon. */ @@ -780,7 +871,8 @@ main(int ac, char **av) { extern char *optarg; extern int optind; - int opt, sock_in = 0, sock_out = 0, newsock, j, i, fdsetsz, on = 1; + int opt, j, i, fdsetsz, on = 1; + int sock_in = -1, sock_out = -1, newsock = -1; pid_t pid; socklen_t fromlen; fd_set *fdset; @@ -792,11 +884,12 @@ main(int ac, char **av) char ntop[NI_MAXHOST], strport[NI_MAXSERV]; char *line; int listen_sock, maxfd; - int startup_p[2]; + int startup_p[2], config_s[2]; int startups = 0; Key *key; Authctxt *authctxt; int ret, key_used = 0; + Buffer cfg; #ifdef HAVE_SECUREWARE (void)set_auth_parameters(ac, av); @@ -806,6 +899,7 @@ main(int ac, char **av) /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ saved_argc = ac; + rexec_argc = ac; saved_argv = xmalloc(sizeof(*saved_argv) * (ac + 1)); for (i = 0; i < ac; i++) saved_argv[i] = xstrdup(av[i]); @@ -824,7 +918,7 @@ main(int ac, char **av) initialize_server_options(&options); /* Parse command-line arguments. */ - while ((opt = getopt(ac, av, "f:p:b:k:h:g:u:o:dDeiqtQ46")) != -1) { + while ((opt = getopt(ac, av, "f:p:b:k:h:g:u:o:dDeiqrtQR46")) != -1) { switch (opt) { case '4': IPv4or6 = AF_INET; @@ -851,6 +945,13 @@ main(int ac, char **av) case 'i': inetd_flag = 1; break; + case 'r': + rexec_flag = 0; + break; + case 'R': + rexeced_flag = 1; + inetd_flag = 1; + break; case 'Q': /* ignored */ break; @@ -914,6 +1015,15 @@ main(int ac, char **av) break; } } + if (rexeced_flag || inetd_flag) + rexec_flag = 0; + if (rexec_flag && (av[0] == NULL || *av[0] != '/')) + fatal("sshd re-exec requires execution with an absolute path"); + if (rexeced_flag) + closefrom(REEXEC_MIN_FREE_FD); + else + closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); + SSLeay_add_all_algorithms(); channel_set_af(IPv4or6); @@ -936,7 +1046,7 @@ main(int ac, char **av) unsetenv("KRB5CCNAME"); #endif /* _AIX */ #ifdef _UNICOS - /* Cray can define user privs drop all prives now! + /* Cray can define user privs drop all privs now! * Not needed on PRIV_SU systems! */ drop_cray_privs(); @@ -944,8 +1054,23 @@ main(int ac, char **av) seed_rng(); - /* Read server configuration options from the configuration file. */ - read_server_config(&options, config_file_name); + sensitive_data.server_key = NULL; + sensitive_data.ssh1_host_key = NULL; + sensitive_data.have_ssh1_key = 0; + sensitive_data.have_ssh2_key = 0; + + /* Fetch our configuration */ + buffer_init(&cfg); + if (rexeced_flag) + recv_rexec_state(REEXEC_CONFIG_PASS_FD, &cfg); + else + load_server_config(config_file_name, &cfg); + + parse_server_config(&options, + rexeced_flag ? "rexec" : config_file_name, &cfg); + + if (!rexec_flag) + buffer_free(&cfg); /* Fill in default values for those options not explicitly set. */ fill_default_server_options(&options); @@ -963,10 +1088,6 @@ main(int ac, char **av) sizeof(Key *)); for (i = 0; i < options.num_host_key_files; i++) sensitive_data.host_keys[i] = NULL; - sensitive_data.server_key = NULL; - sensitive_data.ssh1_host_key = NULL; - sensitive_data.have_ssh1_key = 0; - sensitive_data.have_ssh2_key = 0; for (i = 0; i < options.num_host_key_files; i++) { key = key_load_private(options.host_key_files[i], "", NULL); @@ -1065,6 +1186,16 @@ main(int ac, char **av) if (setgroups(0, NULL) < 0) debug("setgroups() failed: %.200s", strerror(errno)); + if (rexec_flag) { + rexec_argv = xmalloc(sizeof(char *) * (rexec_argc + 2)); + for (i = 0; i < rexec_argc; i++) { + debug("rexec_argv[%d]='%s'", i, saved_argv[i]); + rexec_argv[i] = saved_argv[i]; + } + rexec_argv[rexec_argc] = "-R"; + rexec_argv[rexec_argc + 1] = NULL; + } + /* Initialize the log (it is reinitialized below in case we forked). */ if (debug_flag && !inetd_flag) log_stderr = 1; @@ -1106,19 +1237,34 @@ main(int ac, char **av) /* Start listening for a socket, unless started from inetd. */ if (inetd_flag) { - int s1; - s1 = dup(0); /* Make sure descriptors 0, 1, and 2 are in use. */ - dup(s1); - sock_in = dup(0); - sock_out = dup(1); + int fd; + startup_pipe = -1; + if (rexeced_flag) { + close(REEXEC_CONFIG_PASS_FD); + sock_in = sock_out = dup(STDIN_FILENO); + if (!debug_flag) { + startup_pipe = dup(REEXEC_STARTUP_PIPE_FD); + close(REEXEC_STARTUP_PIPE_FD); + } + } else { + sock_in = dup(STDIN_FILENO); + sock_out = dup(STDOUT_FILENO); + } /* * We intentionally do not close the descriptors 0, 1, and 2 - * as our code for setting the descriptors won\'t work if + * as our code for setting the descriptors won't work if * ttyfd happens to be one of those. */ + if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { + dup2(fd, STDIN_FILENO); + dup2(fd, STDOUT_FILENO); + if (fd > STDOUT_FILENO) + close(fd); + } debug("inetd sockets after dupping: %d, %d", sock_in, sock_out); - if (options.protocol & SSH_PROTO_1) + if ((options.protocol & SSH_PROTO_1) && + sensitive_data.server_key == NULL) generate_ephemeral_server_key(); } else { for (ai = options.listen_addrs; ai; ai = ai->ai_next) { @@ -1141,8 +1287,7 @@ main(int ac, char **av) verbose("socket: %.100s", strerror(errno)); continue; } - if (fcntl(listen_sock, F_SETFL, O_NONBLOCK) < 0) { - error("listen_sock O_NONBLOCK: %s", strerror(errno)); + if (set_nonblock(listen_sock) == -1) { close(listen_sock); continue; } @@ -1285,8 +1430,7 @@ main(int ac, char **av) error("accept: %.100s", strerror(errno)); continue; } - if (fcntl(newsock, F_SETFL, 0) < 0) { - error("newsock del O_NONBLOCK: %s", strerror(errno)); + if (unset_nonblock(newsock) == -1) { close(newsock); continue; } @@ -1300,6 +1444,16 @@ main(int ac, char **av) continue; } + if (rexec_flag && socketpair(AF_UNIX, + SOCK_STREAM, 0, config_s) == -1) { + error("reexec socketpair: %s", + strerror(errno)); + close(newsock); + close(startup_p[0]); + close(startup_p[1]); + continue; + } + for (j = 0; j < options.max_startups; j++) if (startup_pipes[j] == -1) { startup_pipes[j] = startup_p[0]; @@ -1323,8 +1477,15 @@ main(int ac, char **av) close_listen_socks(); sock_in = newsock; sock_out = newsock; + close(startup_p[0]); + close(startup_p[1]); startup_pipe = -1; pid = getpid(); + if (rexec_flag) { + send_rexec_state(config_s[0], + &cfg); + close(config_s[0]); + } break; } else { /* @@ -1346,6 +1507,7 @@ main(int ac, char **av) sock_in = newsock; sock_out = newsock; log_init(__progname, options.log_level, options.log_facility, log_stderr); + close(config_s[0]); break; } } @@ -1358,6 +1520,12 @@ main(int ac, char **av) close(startup_p[1]); + if (rexec_flag) { + send_rexec_state(config_s[0], &cfg); + close(config_s[0]); + close(config_s[1]); + } + /* Mark that the key has been used (it was "given" to the child). */ if ((options.protocol & SSH_PROTO_1) && key_used == 0) { @@ -1396,6 +1564,46 @@ main(int ac, char **av) error("setsid: %.100s", strerror(errno)); #endif + if (rexec_flag) { + int fd; + + debug("rexec start in %d out %d newsock %d pipe %d sock %d", + sock_in, sock_out, newsock, startup_pipe, config_s[0]); + dup2(newsock, STDIN_FILENO); + dup2(STDIN_FILENO, STDOUT_FILENO); + if (startup_pipe == -1) + close(REEXEC_STARTUP_PIPE_FD); + else + dup2(startup_pipe, REEXEC_STARTUP_PIPE_FD); + + dup2(config_s[1], REEXEC_CONFIG_PASS_FD); + close(config_s[1]); + if (startup_pipe != -1) + close(startup_pipe); + + execv(rexec_argv[0], rexec_argv); + + /* Reexec has failed, fall back and continue */ + error("rexec of %s failed: %s", rexec_argv[0], strerror(errno)); + recv_rexec_state(REEXEC_CONFIG_PASS_FD, NULL); + log_init(__progname, options.log_level, + options.log_facility, log_stderr); + + /* Clean up fds */ + startup_pipe = REEXEC_STARTUP_PIPE_FD; + close(config_s[1]); + close(REEXEC_CONFIG_PASS_FD); + newsock = sock_out = sock_in = dup(STDIN_FILENO); + if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { + dup2(fd, STDIN_FILENO); + dup2(fd, STDOUT_FILENO); + if (fd > STDERR_FILENO) + close(fd); + } + debug("rexec cleanup in %d out %d newsock %d pipe %d sock %d", + sock_in, sock_out, newsock, startup_pipe, config_s[0]); + } + /* * Disable the key regeneration alarm. We will not regenerate the * key since we are no longer in a position to give it to anyone. We @@ -1426,7 +1634,7 @@ main(int ac, char **av) #ifdef LIBWRAP /* Check whether logins are denied from this host. */ - { + if (packet_connection_is_on_socket()) { struct request_info req; request_init(&req, RQ_DAEMON, __progname, RQ_FILE, sock_in, 0); @@ -1474,6 +1682,9 @@ main(int ac, char **av) if (privsep_preauth(authctxt) == 1) goto authenticated; + /* prepare buffer to collect messages to display to user after login */ + buffer_init(&loginmsg); + /* perform the key exchange */ /* authenticate user and start session */ if (compat20) { @@ -1689,9 +1900,10 @@ do_ssh1_kex(void) BN_bn2bin(session_key_int, session_key + sizeof(session_key) - len); - compute_session_id(session_id, cookie, + derive_ssh1_session_id( sensitive_data.ssh1_host_key->rsa->n, - sensitive_data.server_key->rsa->n); + sensitive_data.server_key->rsa->n, + cookie, session_id); /* * Xor the first 16 bytes of the session key with the * session id. @@ -1774,6 +1986,7 @@ do_ssh2_kex(void) /* start key exchange */ kex = kex_setup(myproposal); kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; + kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server; kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; kex->server = 1; kex->client_version_string=client_version_string; diff --git a/openssh/sshd_config b/openssh/sshd_config index b45c8c5..65e6f1c 100644 --- a/openssh/sshd_config +++ b/openssh/sshd_config @@ -1,4 +1,4 @@ -# $OpenBSD: sshd_config,v 1.68 2003/12/29 16:39:50 millert Exp $ +# $OpenBSD: sshd_config,v 1.69 2004/05/23 23:59:53 dtucker Exp $ # This is the sshd server system-wide configuration file. See # sshd_config(5) for more information. @@ -35,6 +35,7 @@ #LoginGraceTime 2m #PermitRootLogin yes #StrictModes yes +#MaxAuthTries 6 #RSAAuthentication yes #PubkeyAuthentication yes @@ -67,9 +68,14 @@ #GSSAPIAuthentication no #GSSAPICleanupCredentials 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' and 'PermitEmptyPasswords' +# Set this to 'yes' to enable PAM authentication, account processing, +# and session processing. If this is enabled, PAM authentication will +# be allowed through the ChallengeResponseAuthentication mechanism. +# Depending on your PAM configuration, this may bypass the setting of +# PasswordAuthentication, PermitEmptyPasswords, and +# "PermitRootLogin without-password". If you just want the PAM account and +# session checks to run without PAM authentication, then enable this but set +# ChallengeResponseAuthentication=no #UsePAM no #AllowTcpForwarding yes diff --git a/openssh/sshd_config.5 b/openssh/sshd_config.5 index e15a225..09532fb 100644 --- a/openssh/sshd_config.5 +++ b/openssh/sshd_config.5 @@ -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.29 2004/03/08 10:18:57 dtucker Exp $ +.\" $OpenBSD: sshd_config.5,v 1.35 2004/06/26 09:14:40 jmc Exp $ .Dd September 25, 1999 .Dt SSHD_CONFIG 5 .Os @@ -61,6 +61,28 @@ 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 AcceptEnv +Specifies what environment variables sent by the client will be copied into +the session's +.Xr environ 7 . +See +.Cm SendEnv +in +.Xr ssh_config 5 +for how to configure the client. +Note that environment passing is only supported for protocol 2. +Variables are specified by name, which may contain the wildcard characters +.Ql \&* +and +.Ql \&? . +Multiple environment variables may be separated by whitespace or spread +across multiple +.Cm AcceptEnv +directives. +Be warned that some environment variables could be used to bypass restricted +user environments. +For this reason, care should be taken in the use of this directive. +The default is not to accept any environment variables. .It Cm AllowGroups This keyword can be followed by a list of group name patterns, separated by spaces. @@ -73,7 +95,6 @@ can be used as wildcards in the patterns. Only group names are valid; a numerical group ID is not recognized. By default, login is allowed for all groups. -.Pp .It Cm AllowTcpForwarding Specifies whether TCP forwarding is permitted. The default is @@ -81,7 +102,6 @@ The default is Note that disabling TCP forwarding does not improve security unless users are also denied shell access, as they can always install their own forwarders. -.Pp .It Cm AllowUsers This keyword can be followed by a list of user name patterns, separated by spaces. @@ -97,7 +117,6 @@ By default, login is allowed for all users. If the pattern takes the form USER@HOST then USER and HOST are separately checked, restricting logins to particular users from particular hosts. -.Pp .It Cm AuthorizedKeysFile Specifies the file that contains the public keys that can be used for user authentication. @@ -120,7 +139,6 @@ The contents of the specified file are sent to the remote user before authentication is allowed. This option is only available for protocol version 2. By default, no banner is displayed. -.Pp .It Cm ChallengeResponseAuthentication Specifies whether challenge response authentication is allowed. All authentication styles from @@ -131,8 +149,19 @@ The default is .It Cm Ciphers Specifies the ciphers allowed for protocol version 2. Multiple ciphers must be comma-separated. +The supported ciphers are +.Dq 3des-cbc , +.Dq aes128-cbc , +.Dq aes192-cbc , +.Dq aes256-cbc , +.Dq aes128-ctr , +.Dq aes192-ctr , +.Dq aes256-ctr , +.Dq arcfour , +.Dq blowfish-cbc , +and +.Dq cast128-cbc . The default is -.Pp .Bd -literal ``aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour, aes192-cbc,aes256-cbc,aes128-ctr,aes192-ctr,aes256-ctr'' @@ -193,7 +222,6 @@ can be used as wildcards in the patterns. Only group names are valid; a numerical group ID is not recognized. By default, login is allowed for all groups. -.Pp .It Cm DenyUsers This keyword can be followed by a list of user name patterns, separated by spaces. @@ -386,6 +414,12 @@ for data integrity protection. Multiple algorithms must be comma-separated. The default is .Dq hmac-md5,hmac-sha1,hmac-ripemd160,hmac-sha1-96,hmac-md5-96 . +.It Cm MaxAuthTries +Specifies the maximum number of authentication attempts permitted per +connection. +Once the number of failures reaches half this value, +additional failures are logged. +The default is 6. .It Cm MaxStartups Specifies the maximum number of concurrent unauthenticated connections to the .Nm sshd @@ -608,12 +642,25 @@ 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. The default is +Enables the Pluggable Authentication Module interface. +If set to +.Dq yes +this will enable PAM authentication using +.Cm ChallengeResponseAuthentication +and PAM account and session module processing for all authentication types. +.Pp +Because PAM challenge-response authentication usually serves an equivalent +role to password authentication, you should disable either +.Cm PasswordAuthentication +or +.Cm ChallengeResponseAuthentication. +.Pp +If +.Cm UsePAM +is enabled, you will not be able to run +.Xr sshd 8 +as a non-root user. +The default is .Dq no . .It Cm UsePrivilegeSeparation Specifies whether diff --git a/openssh/sshlogin.c b/openssh/sshlogin.c index e1cc4cc..15eb916 100644 --- a/openssh/sshlogin.c +++ b/openssh/sshlogin.c @@ -39,9 +39,15 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshlogin.c,v 1.7 2003/06/12 07:57:38 markus Exp $"); +RCSID("$OpenBSD: sshlogin.c,v 1.13 2004/08/12 09:18:24 djm Exp $"); #include "loginrec.h" +#include "log.h" +#include "buffer.h" +#include "servconf.h" + +extern Buffer loginmsg; +extern ServerOptions options; /* * Returns the time when the user last logged in. Returns 0 if the @@ -59,17 +65,52 @@ get_last_login_time(uid_t uid, const char *logname, return li.tv_sec; } +/* + * Generate and store last login message. This must be done before + * login_login() is called and lastlog is updated. + */ +static void +store_lastlog_message(const char *user, uid_t uid) +{ + char *time_string, hostname[MAXHOSTNAMELEN] = "", buf[512]; + time_t last_login_time; + +#ifndef NO_SSH_LASTLOG + if (!options.print_lastlog) + return; + + last_login_time = get_last_login_time(uid, user, hostname, + sizeof(hostname)); + + if (last_login_time != 0) { + time_string = ctime(&last_login_time); + if (strchr(time_string, '\n')) + *strchr(time_string, '\n') = '\0'; + if (strcmp(hostname, "") == 0) + snprintf(buf, sizeof(buf), "Last login: %s\r\n", + time_string); + else + snprintf(buf, sizeof(buf), "Last login: %s from %s\r\n", + time_string, hostname); + buffer_append(&loginmsg, buf, strlen(buf)); + } +#endif /* NO_SSH_LASTLOG */ +} + /* * Records that the user has logged in. I wish these parts of operating * systems were more standardized. */ void -record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid, +record_login(pid_t pid, const char *tty, const char *user, uid_t uid, const char *host, struct sockaddr * addr, socklen_t addrlen) { struct logininfo *li; - li = login_alloc_entry(pid, user, host, ttyname); + /* save previous login details before writing new */ + store_lastlog_message(user, uid); + + li = login_alloc_entry(pid, user, host, tty); login_set_addr(li, addr, addrlen); login_login(li); login_free_entry(li); @@ -91,11 +132,11 @@ record_utmp_only(pid_t pid, const char *ttyname, const char *user, /* Records that the user has logged out. */ void -record_logout(pid_t pid, const char *ttyname, const char *user) +record_logout(pid_t pid, const char *tty, const char *user) { struct logininfo *li; - li = login_alloc_entry(pid, user, NULL, ttyname); + li = login_alloc_entry(pid, user, NULL, tty); login_logout(li); login_free_entry(li); } diff --git a/openssh/sshpty.c b/openssh/sshpty.c index 0fe3891..efd1dfe 100644 --- a/openssh/sshpty.c +++ b/openssh/sshpty.c @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshpty.c,v 1.11 2004/01/11 21:55:06 deraadt Exp $"); +RCSID("$OpenBSD: sshpty.c,v 1.12 2004/06/21 17:36:31 avsm Exp $"); #ifdef HAVE_UTIL_H # include @@ -60,18 +60,18 @@ pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen) /* Releases the tty. Its ownership is returned to root, and permissions to 0666. */ void -pty_release(const char *ttyname) +pty_release(const char *tty) { - if (chown(ttyname, (uid_t) 0, (gid_t) 0) < 0) - error("chown %.100s 0 0 failed: %.100s", ttyname, strerror(errno)); - if (chmod(ttyname, (mode_t) 0666) < 0) - error("chmod %.100s 0666 failed: %.100s", ttyname, strerror(errno)); + if (chown(tty, (uid_t) 0, (gid_t) 0) < 0) + error("chown %.100s 0 0 failed: %.100s", tty, strerror(errno)); + if (chmod(tty, (mode_t) 0666) < 0) + error("chmod %.100s 0666 failed: %.100s", tty, strerror(errno)); } /* Makes the tty the process's controlling tty and sets it to sane modes. */ void -pty_make_controlling_tty(int *ttyfd, const char *ttyname) +pty_make_controlling_tty(int *ttyfd, const char *tty) { int fd; #ifdef USE_VHANGUP @@ -82,7 +82,7 @@ pty_make_controlling_tty(int *ttyfd, const char *ttyname) if (setsid() < 0) error("setsid: %.100s", strerror(errno)); - fd = open(ttyname, O_RDWR|O_NOCTTY); + fd = open(tty, O_RDWR|O_NOCTTY); if (fd != -1) { signal(SIGHUP, SIG_IGN); ioctl(fd, TCVHUP, (char *)NULL); @@ -97,7 +97,7 @@ pty_make_controlling_tty(int *ttyfd, const char *ttyname) ioctl(*ttyfd, TCSETCTTY, NULL); fd = open("/dev/tty", O_RDWR); if (fd < 0) - error("%.100s: %.100s", ttyname, strerror(errno)); + error("%.100s: %.100s", tty, strerror(errno)); close(*ttyfd); *ttyfd = fd; #else /* _UNICOS */ @@ -137,9 +137,9 @@ pty_make_controlling_tty(int *ttyfd, const char *ttyname) vhangup(); signal(SIGHUP, old); #endif /* USE_VHANGUP */ - fd = open(ttyname, O_RDWR); + fd = open(tty, O_RDWR); if (fd < 0) { - error("%.100s: %.100s", ttyname, strerror(errno)); + error("%.100s: %.100s", tty, strerror(errno)); } else { #ifdef USE_VHANGUP close(*ttyfd); @@ -174,7 +174,7 @@ pty_change_window_size(int ptyfd, int row, int col, } void -pty_setowner(struct passwd *pw, const char *ttyname) +pty_setowner(struct passwd *pw, const char *tty) { struct group *grp; gid_t gid; @@ -196,33 +196,33 @@ pty_setowner(struct passwd *pw, const char *ttyname) * Warn but continue if filesystem is read-only and the uids match/ * tty is owned by root. */ - if (stat(ttyname, &st)) - fatal("stat(%.100s) failed: %.100s", ttyname, + if (stat(tty, &st)) + fatal("stat(%.100s) failed: %.100s", tty, strerror(errno)); if (st.st_uid != pw->pw_uid || st.st_gid != gid) { - if (chown(ttyname, pw->pw_uid, gid) < 0) { + if (chown(tty, pw->pw_uid, gid) < 0) { if (errno == EROFS && (st.st_uid == pw->pw_uid || st.st_uid == 0)) debug("chown(%.100s, %u, %u) failed: %.100s", - ttyname, (u_int)pw->pw_uid, (u_int)gid, + tty, (u_int)pw->pw_uid, (u_int)gid, strerror(errno)); else fatal("chown(%.100s, %u, %u) failed: %.100s", - ttyname, (u_int)pw->pw_uid, (u_int)gid, + tty, (u_int)pw->pw_uid, (u_int)gid, strerror(errno)); } } if ((st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) != mode) { - if (chmod(ttyname, mode) < 0) { + if (chmod(tty, mode) < 0) { if (errno == EROFS && (st.st_mode & (S_IRGRP | S_IROTH)) == 0) debug("chmod(%.100s, 0%o) failed: %.100s", - ttyname, (u_int)mode, strerror(errno)); + tty, (u_int)mode, strerror(errno)); else fatal("chmod(%.100s, 0%o) failed: %.100s", - ttyname, (u_int)mode, strerror(errno)); + tty, (u_int)mode, strerror(errno)); } } } diff --git a/openssh/sshpty.h b/openssh/sshpty.h index df65e28..c0678de 100644 --- a/openssh/sshpty.h +++ b/openssh/sshpty.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sshpty.h,v 1.4 2002/03/04 17:27:39 stevesk Exp $ */ +/* $OpenBSD: sshpty.h,v 1.5 2004/05/08 00:01:37 deraadt Exp $ */ /* * Author: Tatu Ylonen @@ -17,6 +17,10 @@ #ifndef SSHPTY_H #define SSHPTY_H +struct termios get_saved_tio(void); +void leave_raw_mode(void); +void enter_raw_mode(void); + int pty_allocate(int *, int *, char *, int); void pty_release(const char *); void pty_make_controlling_tty(int *, const char *); diff --git a/openssh/sshtty.c b/openssh/sshtty.c index 4fb2d3d..0b17c3e 100644 --- a/openssh/sshtty.c +++ b/openssh/sshtty.c @@ -35,9 +35,9 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshtty.c,v 1.5 2003/09/19 17:43:35 markus Exp $"); +RCSID("$OpenBSD: sshtty.c,v 1.6 2004/05/08 00:01:37 deraadt Exp $"); -#include "sshtty.h" +#include "sshpty.h" #include "log.h" static struct termios _saved_tio; diff --git a/openssh/tildexpand.c b/openssh/tildexpand.c index cbe9811..cedb653 100644 --- a/openssh/tildexpand.c +++ b/openssh/tildexpand.c @@ -11,11 +11,11 @@ */ #include "includes.h" -RCSID("$OpenBSD: tildexpand.c,v 1.13 2002/06/23 03:25:50 deraadt Exp $"); +RCSID("$OpenBSD: tildexpand.c,v 1.15 2004/05/21 08:43:03 markus Exp $"); #include "xmalloc.h" #include "log.h" -#include "tildexpand.h" +#include "misc.h" /* * Expands tildes in the file name. Returns data allocated by xmalloc. diff --git a/openssh/ttymodes.h b/openssh/ttymodes.h index 7de4b83..481282c 100644 --- a/openssh/ttymodes.h +++ b/openssh/ttymodes.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ttymodes.h,v 1.12 2002/03/04 17:27:39 stevesk Exp $ */ +/* $OpenBSD: ttymodes.h,v 1.13 2004/07/11 17:48:47 deraadt Exp $ */ /* * Author: Tatu Ylonen @@ -113,17 +113,17 @@ TTYCHAR(VDISCARD, 18) /* name, field, op */ TTYMODE(IGNPAR, c_iflag, 30) TTYMODE(PARMRK, c_iflag, 31) -TTYMODE(INPCK, c_iflag, 32) +TTYMODE(INPCK, c_iflag, 32) TTYMODE(ISTRIP, c_iflag, 33) -TTYMODE(INLCR, c_iflag, 34) -TTYMODE(IGNCR, c_iflag, 35) -TTYMODE(ICRNL, c_iflag, 36) +TTYMODE(INLCR, c_iflag, 34) +TTYMODE(IGNCR, c_iflag, 35) +TTYMODE(ICRNL, c_iflag, 36) #if defined(IUCLC) -TTYMODE(IUCLC, c_iflag, 37) +TTYMODE(IUCLC, c_iflag, 37) #endif -TTYMODE(IXON, c_iflag, 38) -TTYMODE(IXANY, c_iflag, 39) -TTYMODE(IXOFF, c_iflag, 40) +TTYMODE(IXON, c_iflag, 38) +TTYMODE(IXANY, c_iflag, 39) +TTYMODE(IXOFF, c_iflag, 40) #ifdef IMAXBEL TTYMODE(IMAXBEL,c_iflag, 41) #endif /* IMAXBEL */ diff --git a/openssh/version.h b/openssh/version.h index e5ba5dd..aae2c3b 100644 --- a/openssh/version.h +++ b/openssh/version.h @@ -1,3 +1,3 @@ -/* $OpenBSD: version.h,v 1.41 2004/03/20 10:40:59 markus Exp $ */ +/* $OpenBSD: version.h,v 1.42 2004/08/16 08:17:01 markus Exp $ */ -#define SSH_VERSION "OpenSSH_3.8.1p1" +#define SSH_VERSION "OpenSSH_3.9p1" -- 2.45.1