]> andersk Git - openssh.git/commitdiff
NB: big update - may break stuff. Please test!
authordjm <djm>
Sun, 4 Feb 2001 12:20:18 +0000 (12:20 +0000)
committerdjm <djm>
Sun, 4 Feb 2001 12:20:18 +0000 (12:20 +0000)
 - (djm) OpenBSD CVS sync:
   - markus@cvs.openbsd.org  2001/02/03 03:08:38
     [auth-options.c auth-rh-rsa.c auth-rhosts.c auth.c canohost.c]
     [canohost.h servconf.c servconf.h session.c sshconnect1.c sshd.8]
     [sshd_config]
     make ReverseMappingCheck optional in sshd_config; ok djm@,dugsong@
   - markus@cvs.openbsd.org  2001/02/03 03:19:51
     [ssh.1 sshd.8 sshd_config]
     Skey is now called ChallengeResponse
   - markus@cvs.openbsd.org  2001/02/03 03:43:09
     [sshd.8]
     use no-pty option in .ssh/authorized_keys* if you need a 8-bit clean
     channel. note from Erik.Anggard@cygate.se (pr/1659)
   - stevesk@cvs.openbsd.org 2001/02/03 10:03:06
     [ssh.1]
     typos; ok markus@
   - djm@cvs.openbsd.org     2001/02/04 04:11:56
     [scp.1 sftp-server.c ssh.1 sshd.8 sftp-client.c sftp-client.h]
     [sftp-common.c sftp-common.h sftp-int.c sftp-int.h sftp.1 sftp.c]
     Basic interactive sftp client; ok theo@
 - (djm) Update RPM specs for new sftp binary
 - (djm) Update several bits for new optional reverse lookup stuff. I
   think I got them all.

34 files changed:
ChangeLog
Makefile.in
TODO
auth-options.c
auth-pam.c
auth-rh-rsa.c
auth-rhosts.c
auth.c
auth1.c
auth2.c
canohost.c
canohost.h
channels.c
contrib/caldera/openssh.spec
contrib/redhat/openssh.spec
contrib/suse/openssh.spec
scp.1
servconf.c
servconf.h
session.c
sftp-client.c [new file with mode: 0644]
sftp-client.h [new file with mode: 0644]
sftp-common.c [new file with mode: 0644]
sftp-common.h [new file with mode: 0644]
sftp-int.c [new file with mode: 0644]
sftp-int.h [new file with mode: 0644]
sftp-server.c
sftp.1 [new file with mode: 0644]
sftp.c [new file with mode: 0644]
ssh.1
ssh_config
sshconnect1.c
sshd.8
sshd_config

index 766c8803f930b286b1c0f2840035056f0c23cbad..5afaf69a8574af67d2c4a4dab93b2b47bcadb090 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,9 +2,32 @@
  - (bal) I think this is the last of the bsd-*.h that don't belong.
  - (bal) Minor Makefile fix
  - (bal) openbsd-compat/Makefile minor fix.  Ensure dependancies are done
-   right. 
+   right.
  - (bal) Changed order of LIB="" in -with-skey due to library resolving.
  - (bal) next-posix.h changed to bsd-nextstep.h
+ - (djm) OpenBSD CVS sync:
+   - markus@cvs.openbsd.org  2001/02/03 03:08:38
+     [auth-options.c auth-rh-rsa.c auth-rhosts.c auth.c canohost.c]
+     [canohost.h servconf.c servconf.h session.c sshconnect1.c sshd.8]
+     [sshd_config]
+     make ReverseMappingCheck optional in sshd_config; ok djm@,dugsong@
+   - markus@cvs.openbsd.org  2001/02/03 03:19:51
+     [ssh.1 sshd.8 sshd_config]
+     Skey is now called ChallengeResponse
+   - markus@cvs.openbsd.org  2001/02/03 03:43:09
+     [sshd.8]
+     use no-pty option in .ssh/authorized_keys* if you need a 8-bit clean
+     channel. note from Erik.Anggard@cygate.se (pr/1659)
+   - stevesk@cvs.openbsd.org 2001/02/03 10:03:06
+     [ssh.1]
+     typos; ok markus@
+   - djm@cvs.openbsd.org     2001/02/04 04:11:56
+     [scp.1 sftp-server.c ssh.1 sshd.8 sftp-client.c sftp-client.h]
+     [sftp-common.c sftp-common.h sftp-int.c sftp-int.h sftp.1 sftp.c]
+     Basic interactive sftp client; ok theo@
+ - (djm) Update RPM specs for new sftp binary
+ - (djm) Update several bits for new optional reverse lookup stuff. I 
+   think I got them all.
 
 20010103
  - (bal) Cygwin clean up by Corinna Vinschen <vinschen@redhat.com>
@@ -14,7 +37,7 @@
    platforms so builds fail.  (NeXT being a well known one)
 
 20010102
- - (bal) Makefile fix where sourcedir != builddir by Corinna Vinschen 
+ - (bal) Makefile fix where sourcedir != builddir by Corinna Vinschen
    <vinschen@redhat.com>
  - (bal) Makefile fix to use $(MAKE) instead of 'make'  for platforms
    that use 'gmake'.   Patch by Tim Rice <tim@multitalents.net>
@@ -75,7 +98,7 @@
      ``StrictHostKeyChecking ask'' documentation and small cleanup.
      ok markus@
    - stevesk@cvs.openbsd.org 2001/01/28 20:43:25
-     [sshd.8] 
+     [sshd.8]
      spelling.  ok markus@
    - stevesk@cvs.openbsd.org 2001/01/28 20:53:21
      [xmalloc.c]
   - (bal) Minor auth2.c resync.  Whitespace and moving of an #include.
 
 20010126
- - (bal) SSH_PROGRAM vs _PATH_SSH_PROGRAM fix pointed out by Roumen 
+ - (bal) SSH_PROGRAM vs _PATH_SSH_PROGRAM fix pointed out by Roumen
    Petrov <roumen.petrov@skalasoft.com>
  - (bal) OpenBSD Sync
    - deraadt@cvs.openbsd.org 2001/01/25 8:06:33
  - (djm) Sync bsd-* support files:
    - deraadt@cvs.openbsd.org 2000/01/26 03:43:20
      [rresvport.c bindresvport.c]
-     new bindresvport() semantics that itojun, shin, jean-luc and i have 
+     new bindresvport() semantics that itojun, shin, jean-luc and i have
      agreed on, which will be happy for the future. bindresvport_sa() for
      sockaddr *, too.  docs later..
    - deraadt@cvs.openbsd.org 2000/01/24 02:24:21
      [bindresvport.c]
-     in bindresvport(), if sin is non-NULL, example sin->sin_family for 
+     in bindresvport(), if sin is non-NULL, example sin->sin_family for
      the actual family being processed
  - (djm) Mention PRNGd in documentation, it is nicer than EGD
  - (djm) Automatically search for "well-known" EGD/PRNGd sockets in autoconf
  - (bal) OpenBSD Resync
    - markus@cvs.openbsd.org 2001/01/23 10:45:10
      [ssh.h]
-     nuke comment            
+     nuke comment
  - (bal) no 64bit support patch from Tim Rice <tim@multitalents.net>
  - (bal) #ifdef around S_IFSOCK if platform does not support it.
    patch by Tim Rice <tim@multitalents.net>
 20010123
  - (bal) regexp.h typo in configure.in.  Should have been regex.h
  - (bal) SSH_USER_DIR to _PATH_SSH_USER_DIR patch by stevesk@
- - (bal) SSH_ASKPASS_DEFAULT to _PATH_SSH_ASKPASS_DEFAULT 
+ - (bal) SSH_ASKPASS_DEFAULT to _PATH_SSH_ASKPASS_DEFAULT
  - (bal) OpenBSD Resync
    - markus@cvs.openbsd.org 2001/01/22 8:15:00
      [auth-krb4.c sshconnect1.c]
      fix typo; from stevesk@
    - markus@cvs.openbsd.org 2001/01/19 16:50:58
      [ssh-dss.c]
-     clear and free digest, make consistent with other code (use dlen); from 
+     clear and free digest, make consistent with other code (use dlen); from
      stevesk@
    - markus@cvs.openbsd.org 2001/01/20 15:55:20 GMT 2001 by markus
      [auth-options.c auth-options.h auth-rsa.c auth2.c]
      pass the filename to auth_parse_options()
-   - markus@cvs.openbsd.org 2001/01/20 17:59:40 GMT 2001 
+   - markus@cvs.openbsd.org 2001/01/20 17:59:40 GMT 2001
      [readconf.c]
      fix SIGSEGV from -o ""; problem noted by jehsom@togetherweb.com
    - stevesk@cvs.openbsd.org 2001/01/20 18:20:29
      dh_new_group() does not return NULL.  ok markus@
    - markus@cvs.openbsd.org 2001/01/20 21:33:42
      [ssh-add.c]
-     do not loop forever if askpass does not exist; from 
+     do not loop forever if askpass does not exist; from
      andrew@pimlott.ne.mediaone.net
    - djm@cvs.openbsd.org 2001/01/20 23:00:56
      [servconf.c]
       match.c misc.c misc.h nchan.c packet.c pty.c radix.h readconf.c
       readpass.c readpass.h rsa.c scp.c servconf.c serverloop.c serverloop.h
       session.c sftp-server.c ssh-add.c ssh-agent.c ssh-dss.c ssh-keygen.c
-      ssh-keyscan.c ssh-rsa.c ssh.c ssh.h sshconnect.c sshconnect.h 
+      ssh-keyscan.c ssh-rsa.c ssh.c ssh.h sshconnect.c sshconnect.h
       sshconnect1.c sshconnect2.c sshd.c tildexpand.c tildexpand.h
       ttysmodes.c uidswap.c xmalloc.c]
-     split ssh.h and try to cleanup the #include mess. remove unnecessary 
+     split ssh.h and try to cleanup the #include mess. remove unnecessary
      #includes.  rename util.[ch] -> misc.[ch]
  - (bal) renamed 'PIDDIR' to '_PATH_SSH_PIDDIR' to match OpenBSD tree
- - (bal) Moved #ifdef KRB4 in auth-krb4.c above the #include to resolve 
+ - (bal) Moved #ifdef KRB4 in auth-krb4.c above the #include to resolve
    conflict when compiling for non-kerb install
  - (bal) removed the #ifdef SKEY in auth1.c to match Markus' changes
    on 1/19.
    - markus@cvs.openbsd.org 2001/01/18 16:20:21
      [log-client.c log-server.c log.c readconf.c servconf.c ssh.1 ssh.h
       sshd.8 sshd.c]
-     log() is at pri=LOG_INFO, since LOG_NOTICE goes to /dev/console on many 
+     log() is at pri=LOG_INFO, since LOG_NOTICE goes to /dev/console on many
      systems
    - markus@cvs.openbsd.org 2001/01/18 16:59:59
      [auth-passwd.c auth.c auth.h auth1.c auth2.c serverloop.c session.c
    to fix NULL pointer deref and fake authloop breakage in PAM code.
  - (bal) Updated contrib/cygwin/ by Corinna Vinschen <vinschen@redhat.com>
  - (bal) Minor cygwin patch to auth1.c.  Suggested by djm.
+
 20010118
  - (bal) Super Sized OpenBSD Resync
    - markus@cvs.openbsd.org 2001/01/11 22:14:20 GMT 2001 by markus
      [ssh-add.c]
      typo, from stevesk@sweden.hp.com
    - markus@cvs.openbsd.org 2001/01/13 18:32:50
-     [packet.c session.c ssh.c sshconnect.c sshd.c] 
+     [packet.c session.c ssh.c sshconnect.c sshd.c]
      split out keepalive from packet_interactive (from dale@accentre.com)
      set IPTOS_LOWDELAY TCP_NODELAY IPTOS_THROUGHPUT for ssh2, too.
    - markus@cvs.openbsd.org 2001/01/13 18:36:45
    - markus@cvs.openbsd.org 2001/01/13 18:43:31
      [session.c]
      Wall
-   - markus@cvs.openbsd.org 2001/01/13 19:14:08 
+   - markus@cvs.openbsd.org 2001/01/13 19:14:08
      [clientloop.h clientloop.c ssh.c]
      move callback to headerfile
    - markus@cvs.openbsd.org 2001/01/15 21:40:10
      readable long listing for sftp-server, ok deraadt@
    - markus@cvs.openbsd.org 2001/01/16 19:20:06
      [key.c ssh-rsa.c]
-     make "ssh-rsa" key format for ssh2 confirm to the ietf-drafts; from 
-     galb@vandyke.com.  note that you have to delete older ssh2-rsa keys, 
-     since they are in the wrong format, too. they must be removed from 
+     make "ssh-rsa" key format for ssh2 confirm to the ietf-drafts; from
+     galb@vandyke.com.  note that you have to delete older ssh2-rsa keys,
+     since they are in the wrong format, too. they must be removed from
      .ssh/authorized_keys2 and .ssh/known_hosts2, etc.
-     (cd; grep -v ssh-rsa .ssh/authorized_keys2 > TMP && mv TMP 
-     .ssh/authorized_keys2) additionally, we now check that 
+     (cd; grep -v ssh-rsa .ssh/authorized_keys2 > TMP && mv TMP
+     .ssh/authorized_keys2) additionally, we now check that
      BN_num_bits(rsa->n) >= 768.
    - markus@cvs.openbsd.org 2001/01/16 20:54:27
      [sftp-server.c]
  - (bal) Added bsd-strmode.[ch] since some non-OpenBSD platforms may
    be missing such feature.
 
+
 20010117
  - (djm) Only write random seed file at exit
  - (djm) Make PAM support optional, enable with --with-pam
- - (djm) Try to use libcrypt on Linux, but link it after OpenSSL (which 
+ - (djm) Try to use libcrypt on Linux, but link it after OpenSSL (which
    provides a crypt() of its own)
  - (djm) Avoid a warning in bsd-bindresvport.c
  - (djm) Try to avoid adding -I/usr/include to CPPFLAGS during SSL tests. This
-   can cause weird segfaults errors on Solaris 
+   can cause weird segfaults errors on Solaris
  - (djm) Avoid warning in PAM code by making read_passphrase arguments const
  - (djm) Add --with-pam to RPM spec files
 
      [auth.c sshd.8]
      support supplementary group in {Allow,Deny}Groups
      from stevesk@pobox.com
-       
+
 20010112
  - (bal) OpenBSD Sync
    - markus@cvs.openbsd.org 2001/01/10 22:56:22
             use #defines from the draft
             move #definations to sftp.h
      more info:
-     http://www.ietf.org/internet-drafts/draft-ietf-secsh-filexfer-00.txt 
+     http://www.ietf.org/internet-drafts/draft-ietf-secsh-filexfer-00.txt
    - markus@cvs.openbsd.org 2001/01/10 19:43:20
      [sshd.c]
      XXX - generate_empheral_server_key() is not safe against races,
-     because it calls log()     
+     because it calls log()
    - markus@cvs.openbsd.org 2001/01/09 21:19:50
      [packet.c]
      allow TCP_NDELAY for ipv6; from netbsd via itojun@
      [sshconnect2.c]
      handle SSH2_MSG_USERAUTH_BANNER; fixes bug when connecting to a server
      that prints a banner (e.g. /etc/issue.net)
+
 20010105
  - (bal) contrib/caldera/ provided by Tim Rice <tim@multitalents.net>
  - (bal) bsd-getcwd.c and bsd-setenv.c changed from bcopy() to memmove()
      log remote ip on disconnect; PR 1600 from jcs@rt.fm
    - markus@cvs.openbsd.org 2001/01/02 20:50:56
      [sshconnect.c]
-     strict_host_key_checking for host_status != HOST_CHANGED && 
+     strict_host_key_checking for host_status != HOST_CHANGED &&
      ip_status == HOST_CHANGED
- - (bal) authfile.c: Synced CVS ID tag 
+ - (bal) authfile.c: Synced CVS ID tag
  - (bal) UnixWare 2.0 fixes by Tim Rice <tim@multitalents.net>
  - (bal) Disable sftp-server if no 64bit int support exists.  Based on
    patch by Tim Rice <tim@multitalents.net>
  - (bal) if no MAXHOSTNAMELEN is defined.  Default to 64 character defination.
    Suggested by Christian Kurz <shorty@debian.org>
  - (bal) Add in '.c.o' section to Makefile.in to address make programs that
-    don't honor CPPFLAGS by default.  Suggested by Lutz Jaenicke 
+    don't honor CPPFLAGS by default.  Suggested by Lutz Jaenicke
     <Lutz.Jaenicke@aet.TU-Cottbus.DE>
 
 20001229
- - (bal) Fixed spelling of 'authorized_keys' in ssh-copy-id.1 by Christian 
+ - (bal) Fixed spelling of 'authorized_keys' in ssh-copy-id.1 by Christian
    Kurz <shorty@debian.org>
  - (bal) OpenBSD CVS Update
    - markus@cvs.openbsd.org 2000/12/28 14:25:51
    bad reference to 'NeXT including it else were' on the #ifdef version.
 
 20001227
- - (bal) Typo in configure.in: entut?ent should be endut?ent.  Suggested by 
+ - (bal) Typo in configure.in: entut?ent should be endut?ent.  Suggested by
    Takumi Yamane <yamtak@b-session.com>
  - (bal) Checks for getrlimit(), sysconf(), and setdtablesize().  Patch
    by Corinna Vinschen <vinschen@redhat.com>
  - (djm) Fix catman-do target for non-bash
- - (bal) Typo in configure.in: entut?ent should be endut?ent.  Suggested by 
+ - (bal) Typo in configure.in: entut?ent should be endut?ent.  Suggested by
    Takumi Yamane <yamtak@b-session.com>
  - (bal) Checks for getrlimit(), sysconf(), and setdtablesize().  Patch
    by Corinna Vinschen <vinschen@redhat.com>
  - (djm) Fix catman-do target for non-bash
- - (bal) Fixed NeXT's lack of CPPFLAGS honoring.  
- - (bal) ssh-keyscan.c: NeXT (and older BSDs) don't support getrlimit() w/ 
+ - (bal) Fixed NeXT's lack of CPPFLAGS honoring.
+ - (bal) ssh-keyscan.c: NeXT (and older BSDs) don't support getrlimit() w/
    'RLIMIT_NOFILE'
- - (djm) Remove *.Ylonen files. They are no longer in the OpenBSD tree, 
-   the info in COPYING.Ylonen has been moved to the start of each 
+ - (djm) Remove *.Ylonen files. They are no longer in the OpenBSD tree,
+   the info in COPYING.Ylonen has been moved to the start of each
    SSH1-derived file and README.Ylonen is well out of date.
 
 20001223
    - markus@cvs.openbsd.org 2000/12/17 02:33:40
      [uidswap.c]
      typo; from wsanchez@apple.com
-       
+
 20001220
- - (djm) Workaround PAM inconsistencies between Solaris derived PAM code 
+ - (djm) Workaround PAM inconsistencies between Solaris derived PAM code
    and Linux-PAM. Based on report and fix from Andrew Morgan
    <morgan@transmeta.com>
 
  - (stevesk) OpenBSD CVS update:
    - markus@cvs.openbsd.org 2000/12/12 15:30:02
      [ssh-keyscan.c ssh.c sshd.c]
-     consistently use __progname; from stevesk@pobox.com       
+     consistently use __progname; from stevesk@pobox.com
 
 20001211
  - (bal) Applied patch to include ssh-keyscan into Redhat's package, and
 
 20001210
  - (bal) OpenBSD CVS updates
-   - markus@cvs.openbsd.org 2000/12/09 13:41:51 
+   - markus@cvs.openbsd.org 2000/12/09 13:41:51
      [cipher.c cipher.h rijndael.c rijndael.h rijndael_boxes.h]
      undo rijndael changes
-   - markus@cvs.openbsd.org 2000/12/09 13:48:31 
+   - markus@cvs.openbsd.org 2000/12/09 13:48:31
      [rijndael.c]
      fix byte order bug w/o introducing new implementation
-   - markus@cvs.openbsd.org 2000/12/09 14:08:27 
+   - markus@cvs.openbsd.org 2000/12/09 14:08:27
      [sftp-server.c]
      "" -> "." for realpath; from vinschen@redhat.com
-   - markus@cvs.openbsd.org 2000/12/09 14:06:54 
+   - markus@cvs.openbsd.org 2000/12/09 14:06:54
      [ssh-agent.c]
      extern int optind; from stevesk@sweden.hp.com
    - provos@cvs.openbsd.org 2000/12/09 23:51:11
 
 20001209
  - (bal) OpenBSD CVS updates:
-   - djm@cvs.openbsd.org 2000/12/07 4:24:59 
+   - djm@cvs.openbsd.org 2000/12/07 4:24:59
      [ssh.1]
      Typo fix from Wilfredo Sanchez <wsanchez@apple.com>; ok theo
 
 20001207
  - (bal) OpenBSD CVS updates:
-   - markus@cvs.openbsd.org 2000/12/06 22:58:14 
+   - markus@cvs.openbsd.org 2000/12/06 22:58:14
      [compat.c compat.h packet.c]
      disable debug messages for ssh.com/f-secure 2.0.1x, 2.1.0
    - markus@cvs.openbsd.org 2000/12/06 23:10:39
      [rijndael.c]
      unexpand(1)
-   - markus@cvs.openbsd.org 2000/12/06 23:05:43 
+   - markus@cvs.openbsd.org 2000/12/06 23:05:43
      [cipher.c cipher.h rijndael.c rijndael.h rijndael_boxes.h]
      new rijndael implementation. fixes endian bugs
 
 
 20001204
  - (bal) More C functions defined in NeXT that are unaccessable without
-   defining -POSIX. 
- - (bal) OpenBSD CVS updates: 
-   - markus@cvs.openbsd.org 2000/12/03 11:29:04 
+   defining -POSIX.
+ - (bal) OpenBSD CVS updates:
+   - markus@cvs.openbsd.org 2000/12/03 11:29:04
      [compat.c]
      remove fallback to SSH_BUG_HMAC now that the drafts are updated
    - markus@cvs.openbsd.org 2000/12/03 11:27:55
      [compat.c]
-     correctly match "2.1.0.pl2 SSH" etc; from 
+     correctly match "2.1.0.pl2 SSH" etc; from
      pekkas@netcore.fi/bugzilla.redhat
    - markus@cvs.openbsd.org 2000/12/03 11:15:03
      [auth2.c compat.c compat.h sshconnect2.c]
  - (bal) OpenBSD CVS updates:
   - markus@cvs.openbsd.org 2000/11/30 22:54:31
     [channels.c]
-    debug->warn if tried to do -R style fwd w/o client requesting this; 
+    debug->warn if tried to do -R style fwd w/o client requesting this;
     ok neils@
   - markus@cvs.openbsd.org 2000/11/29 20:39:17
     [cipher.c]
   - markus@cvs.openbsd.org 2000/11/30 18:33:05
     [ssh-agent.c]
     agents must not dump core, ok niels@
-  - markus@cvs.openbsd.org 2000/11/30 07:04:02 
+  - markus@cvs.openbsd.org 2000/11/30 07:04:02
     [ssh.1]
     T is for both protocols
   - markus@cvs.openbsd.org 2000/12/01 00:00:51
     check -T before isatty()
   - provos@cvs.openbsd.org 2000/11/29 13:51:27
     [sshconnect.c]
-    show IP address and hostname when new key is encountered. okay markus@ 
+    show IP address and hostname when new key is encountered. okay markus@
   - markus@cvs.openbsd.org 2000/11/30 22:53:35
     [sshconnect.c]
     disable agent/x11/port fwding if hostkey has changed; ok niels@
 
 20001202
  - (bal) Backed out of part of Alain St-Denis' loginrec.c patch.
- - (bal) Irix need some sort of mansubdir, patch by Michael Stone 
+ - (bal) Irix need some sort of mansubdir, patch by Michael Stone
    <mstone@cs.loyola.edu>
 
 20001129
  - (djm) Back out all the serverloop.c hacks. sshd will now hang again
    if there are background children with open fds.
  - (djm) bsd-rresvport.c bzero -> memset
- - (djm) Don't fail in defines.h on absence of 64 bit types (we will 
+ - (djm) Don't fail in defines.h on absence of 64 bit types (we will
    still fail during compilation of sftp-server).
  - (djm) Fail if ar is not found during configure
  - (djm) OpenBSD CVS updates:
  - (bal) Merge OpenBSD changes:
    - markus@cvs.openbsd.org  2000/11/15 22:31:36
      [auth-options.c]
-     case insensitive key options; from stevesk@sweeden.hp.com    
+     case insensitive key options; from stevesk@sweeden.hp.com
    - markus@cvs.openbsd.org  2000/11/16 17:55:43
      [dh.c]
      do not use perror() in sshd, after child is forked()
      do not reorder keys if a key is removed
    - markus@cvs.openbsd.org  2000/11/15 19:58:08
      [ssh.c]
-     just ignore non existing user keys   
+     just ignore non existing user keys
    - millert@cvs.openbsd.org  200/11/15 20:24:43
      [ssh-keygen.c]
      Add missing \n at end of error message.
 20001117
  - (bal) Changed from 'primes' to 'primes.out' for consistancy sake.  It
    has no affect the output.  Patch by Corinna Vinschen <vinschen@redhat.com>
- - (stevesk) Reworked progname support. 
+ - (stevesk) Reworked progname support.
  - (bal) Misplaced #include "includes.h" in bsd-setproctitle.c.  Patch by
    Shinichi Maruyama <marya@st.jip.co.jp>
 
    <roth@feep.net>
 
 20001113
- - (djm) Add pointer to http://www.imasy.or.jp/~gotoh/connect.c to 
+ - (djm) Add pointer to http://www.imasy.or.jp/~gotoh/connect.c to
    contrib/README
  - (djm) Merge OpenBSD changes:
    - markus@cvs.openbsd.org  2000/11/06 16:04:56
      [readconf.c readconf.h rsa.c rsa.h servconf.c servconf.h ssh-add.c]
      [ssh-agent.c ssh-keygen.1 ssh-keygen.c ssh.1 ssh.c ssh_config]
      [sshconnect1.c sshconnect2.c sshd.8 sshd.c sshd_config ssh-dss.c]
-     [ssh-dss.h ssh-rsa.c ssh-rsa.h dsa.c dsa.h]                   
+     [ssh-dss.h ssh-rsa.c ssh-rsa.h dsa.c dsa.h]
      add support for RSA to SSH2.  please test.
      there are now 3 types of keys: RSA1 is used by ssh-1 only,
      RSA and DSA are used by SSH2.
  - (djm) Added /etc/primes for kex DH group neg, fixup Makefile.in and
    packaging files
  - (djm) Fix new Makefile.in warnings
- - (djm) Fix vsprintf("%h") in bsd-snprintf.c, short int va_args are 
-   promoted to type int. Report and fix from Dan Astoorian 
+ - (djm) Fix vsprintf("%h") in bsd-snprintf.c, short int va_args are
+   promoted to type int. Report and fix from Dan Astoorian
    <djast@cs.toronto.edu>
- - (djm) Hardwire sysconfdir in RPM spec files as some RPM versions get 
+ - (djm) Hardwire sysconfdir in RPM spec files as some RPM versions get
    it wrong. Report from Bennett Todd <bet@rahul.net>
 
 20001110
  - (bal) Changed from --with-skey to --with-skey=PATH in configure.in
  - (bal) Added in check to verify S/Key library is being detected in
    configure.in
- - (bal) next-posix.h - added another prototype wrapped in POSIX ifdef/endif. 
+ - (bal) next-posix.h - added another prototype wrapped in POSIX ifdef/endif.
    Patch by Mark Miller <markm@swoon.net>
  - (bal) Added 'util.h' header to loginrec.c only if HAVE_UTIL_H is defined
-   to remove warnings under MacOS X.  Patch by Mark Miller <markm@swoon.net> 
+   to remove warnings under MacOS X.  Patch by Mark Miller <markm@swoon.net>
  - (bal) Fixed LDFLAG mispelling in configure.in for --with-afs
 
 20001107
 20001106
  - (djm) Use Jim's new 1.0.3 askpass in Redhat RPMs
  - (djm) Manually fix up missed diff hunks (mainly RCS idents)
- - (djm) Remove UPGRADING document in favour of a link to the better 
+ - (djm) Remove UPGRADING document in favour of a link to the better
    maintained FAQ on www.openssh.com
  - (djm) Fix multiple dependancy on gnome-libs from Pekka Savola
    <pekkas@netcore.fi>
  - (bal) next-posix.h - spelling and forgot a prototype
 
 20001028
- - (djm) fix select hack in serverloop.c from Philippe WILLEM 
+ - (djm) fix select hack in serverloop.c from Philippe WILLEM
    <Philippe.WILLEM@urssaf.fr>
  - (djm) Fix mangled AIXAUTHENTICATE code
- - (djm) authctxt->pw may be NULL. Fix from Markus Friedl 
+ - (djm) authctxt->pw may be NULL. Fix from Markus Friedl
    <markus.friedl@informatik.uni-erlangen.de>
  - (djm) Sync with OpenBSD:
    - markus@cvs.openbsd.org  2000/10/16 15:46:32
    - markus@cvs.openbsd.org  2000/10/27 01:32:19
      [channels.c channels.h clientloop.c serverloop.c session.c]
      [ssh.c util.c]
-     enable non-blocking IO on channels, and tty's (except for the 
+     enable non-blocking IO on channels, and tty's (except for the
      client ttys).
 
 20001027
    supplied passphrase. Problem report from Lutz Jaenicke
    <Lutz.Jaenicke@aet.TU-Cottbus.DE>
  - (bal) Changed from GNU rx to PCRE on suggestion from djm.
- - (bal) Integrated Sony NEWS-OS patches from NAKAJI Hirouyuki 
+ - (bal) Integrated Sony NEWS-OS patches from NAKAJI Hirouyuki
    <nakaji@tutrp.tut.ac.jp>
 
 20001016
      AllowTcpForwarding; from naddy@
    - markus@cvs.openbsd.org  2000/10/14 06:16:56
      [auth2.c compat.c compat.h sshconnect2.c version.h]
-     OpenSSH_2.3; note that is is not complete, but the version number 
+     OpenSSH_2.3; note that is is not complete, but the version number
      needs to be changed for interoperability reasons
    - markus@cvs.openbsd.org  2000/10/14 06:19:45
      [auth-rsa.c]
    - markus@cvs.openbsd.org  2000/10/15 08:18:31
      [rijndael.c]
      typo
- - (djm) Copy manpages back over from OpenBSD - too tedious to wade 
+ - (djm) Copy manpages back over from OpenBSD - too tedious to wade
    through diffs
- - (djm) Added condrestart to Redhat init script. Patch from Pekka Savola 
+ - (djm) Added condrestart to Redhat init script. Patch from Pekka Savola
    <pekkas@netcore.fi>
  - (djm) Update version in Redhat spec file
- - (djm) Merge some of Nalin Dahyabhai <nalin@redhat.com> changes from the 
+ - (djm) Merge some of Nalin Dahyabhai <nalin@redhat.com> changes from the
    Redhat 7.0 spec file
  - (djm) Make inability to read/write PRNG seedfile non-fatal
 
  - (bal) Add support for realpath and getcwd for platforms with broken
    or missing realpath implementations for sftp-server.
  - (bal) Corrected mistake in INSTALL in regards to GNU rx library
- - (bal) Add support for GNU rx library for those lacking regexp support 
+ - (bal) Add support for GNU rx library for those lacking regexp support
  - (djm) Don't accept PAM_PROMPT_ECHO_ON messages during initial auth
  - (djm) Revert SSH2 serverloop hack, will find a better way.
  - (djm) Add workaround for Linux 2.4's gratuitious errno change. Patch
 
 20000930
  - (djm) Irix ssh_prng_cmds path fix from Pekka Savola <pekkas@netcore.fi>
- - (djm) Support in bsd-snprintf.c for long long conversions from 
+ - (djm) Support in bsd-snprintf.c for long long conversions from
    Ben Lindstrom <mouring@pconline.com>
  - (djm) Cleanup NeXT support from Ben Lindstrom <mouring@pconline.com>
  - (djm) Ignore SIGPIPEs from serverloop to child. Fixes crashes with
-   very short lived X connections. Bug report from Tobias Oetiker 
+   very short lived X connections. Bug report from Tobias Oetiker
    <oetiker@ee.ethz.ch>. Fix from Markus Friedl <markus@cvs.openbsd.org>
  - (djm) Add recent InitScripts as a RPM dependancy for openssh-server
    patch from Pekka Savola <pekkas@netcore.fi>
    - markus@cvs.openbsd.org  2000/09/28 12:03:18
      [channels.c]
      debug -> debug2 cleanup
- - (djm) Irix strips "/dev/tty" from [uw]tmp entries (other systems only 
+ - (djm) Irix strips "/dev/tty" from [uw]tmp entries (other systems only
    strip "/dev/"). Fix loginrec.c based on patch from Alain St-Denis
    <Alain.St-Denis@ec.gc.ca>
- - (djm) Fix 9 character passphrase failure with gnome-ssh-askpass. 
-   Problem was caused by interrupted read in ssh-add. Report from Donald 
+ - (djm) Fix 9 character passphrase failure with gnome-ssh-askpass.
+   Problem was caused by interrupted read in ssh-add. Report from Donald
    J. Barry <don@astro.cornell.edu>
 
 20000929
  - (djm) Fix SSH2 not terminating until all background tasks done problem.
- - (djm) Another off-by-one fix from Pavel Kankovsky 
-   <peak@argo.troja.mff.cuni.cz> 
+ - (djm) Another off-by-one fix from Pavel Kankovsky
+   <peak@argo.troja.mff.cuni.cz>
  - (djm) Clean up. Strip some unnecessary differences with OpenBSD's code,
    tidy necessary differences. Use Markus' new debugN() in entropy.c
- - (djm) Merged big SCO portability patch from Tim Rice 
+ - (djm) Merged big SCO portability patch from Tim Rice
    <tim@multitalents.net>
 
 20000926
  - (djm) Update X11-askpass to 1.0.2 in RPM spec file
  - (djm) Define _REENTRANT to pickup strtok_r() on HP/UX
- - (djm) Security: fix off-by-one buffer overrun in fake-getnameinfo.c. 
-   Report and fix from Pavel Kankovsky <peak@argo.troja.mff.cuni.cz> 
+ - (djm) Security: fix off-by-one buffer overrun in fake-getnameinfo.c.
+   Report and fix from Pavel Kankovsky <peak@argo.troja.mff.cuni.cz>
 
 20000924
  - (djm) Merged cleanup patch from Mark Miller <markm@swoon.net>
    <markm@swoon.net>
 
 20000923
- - (djm) Fix address logging in utmp from Kevin Steves 
+ - (djm) Fix address logging in utmp from Kevin Steves
    <stevesk@sweden.hp.com>
  - (djm) Redhat spec and manpage fixes from Pekka Savola <pekkas@netcore.fi>
  - (djm) Seperate tests for int64_t and u_int64_t types
- - (djm) Tweak password expiry checking at suggestion of Kevin Steves 
+ - (djm) Tweak password expiry checking at suggestion of Kevin Steves
    <stevesk@sweden.hp.com>
  - (djm) NeXT patch from Ben Lindstrom <mouring@pconline.com>
- - (djm) Use printf %lld instead of %qd in sftp-server.c. Fix from 
+ - (djm) Use printf %lld instead of %qd in sftp-server.c. Fix from
    Michael Stone <mstone@cs.loyola.edu>
  - (djm) OpenBSD CVS sync:
    - markus@cvs.openbsd.org  2000/09/17 09:38:59
    <asminer@cs.iastate.edu>
 
 20000916
- - (djm) Fix SSL search order from Lutz Jaenicke 
+ - (djm) Fix SSL search order from Lutz Jaenicke
    <Lutz.Jaenicke@aet.TU-Cottbus.DE>
  - (djm) New SuSE spec from Corinna Vinschen <corinna@vinschen.de>
  - (djm) Update CygWin support from Corinna Vinschen <vinschen@cygnus.com>
  - (djm) Use a real struct sockaddr inside the fake struct sockaddr_storage.
    Patch from Larry Jones <larry.jones@sdrc.com>
- - (djm) Add Steve VanDevender's <stevev@darkwing.uoregon.edu> PAM 
+ - (djm) Add Steve VanDevender's <stevev@darkwing.uoregon.edu> PAM
    password change patch.
  - (djm) Bring licenses on my stuff in line with OpenBSD's
  - (djm) Cleanup auth-passwd.c and unify HP/UX authentication. Patch from
  - (djm) Update Redhat SPEC file accordingly
  - (djm) Add Kevin Steves <stevesk@sweden.hp.com> HP/UX contrib files
  - (djm) Add Charles Levert <charles@comm.polymtl.ca> getpgrp patch
- - (djm) Fix password auth on HP/UX 10.20. Patch from Dirk De Wachter 
+ - (djm) Fix password auth on HP/UX 10.20. Patch from Dirk De Wachter
    <Dirk.DeWachter@rug.ac.be>
- - (djm) Fixprogs and entropy list fixes from Larry Jones 
+ - (djm) Fixprogs and entropy list fixes from Larry Jones
    <larry.jones@sdrc.com>
  - (djm) Fix for SuSE spec file from Takashi YOSHIDA
    <tyoshida@gemini.rc.kyushu-u.ac.jp>
      prototype
    - deraadt@cvs.openbsd.org 2000/09/07 14:27:56
      [ALL]
-     cleanup copyright notices on all files.  I have attempted to be 
-     accurate with the details.  everything is now under Tatu's licence 
-     (which I copied from his readme), and/or the core-sdi bsd-ish thing 
-     for deattack, or various openbsd developers under a 2-term bsd 
+     cleanup copyright notices on all files.  I have attempted to be
+     accurate with the details.  everything is now under Tatu's licence
+     (which I copied from his readme), and/or the core-sdi bsd-ish thing
+     for deattack, or various openbsd developers under a 2-term bsd
      licence.  We're not changing any rules, just being accurate.
    - markus@cvs.openbsd.org  2000/09/07 14:40:30
      [channels.c channels.h clientloop.c serverloop.c ssh.c]
  - (djm) Added 'distprep' make target to simplify packaging
  - (djm) Added patch from Chris Adams <cmadams@hiwaay.net> to add OSF SIA
    support. Enable using "USE_SIA=1 ./configure [options]"
-  
+
 20000627
  - (djm) Fixes to login code - not setting li->uid, cleanups
  - (djm) Formatting
   - Don't try to retrieve lastlog from wtmp/wtmpx if DISABLE_LASTLOG is
      def'd
   - Set AIX to use preformatted manpages
-  
+
 20000610
  - (djm) Minor doc tweaks
  - (djm) Fix for configure on bash2 from Jim Knoble <jmknoble@jmknoble.cx>
     teach protocol v2 to count login failures properly and also enable an
     explanation of why the password prompt comes up again like v1; this is NOT
     crypto
-  - markus@cvs.openbsd.org 
+  - markus@cvs.openbsd.org
     [readconf.c readconf.h servconf.c servconf.h session.c ssh.1 ssh.c sshd.8]
     xauth_location support; pr 1234
     [readconf.c sshconnect2.c]
  - (andre) New login code
     - Remove bsd-login.[ch] and all the OpenBSD-derived code in login.c
     - Add loginrec.[ch], logintest.c and autoconf code
-  
+
 20000531
  - Cleanup of auth.c, login.c and fake-*
  - Cleanup of auth-pam.c, save and print "account expired" error messages
      no adjust after close
    - [sshd.c compat.c ]
      interop w/ latest ssh.com windows client.
+
 20000406
  - OpenBSD CVS update:
    - [channels.c]
    - [readpass.c]
      instead of blocking SIGINT, catch it ourselves, so that we can clean
      the tty modes up and kill ourselves -- instead of our process group
-     leader (scp, cvs, ...) going away and leaving us in noecho mode. 
+     leader (scp, cvs, ...) going away and leaving us in noecho mode.
      people with cbreak shells never even noticed..
    - [ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh.1 sshd.8]
      ie. -> i.e.,
 20000118
  - Fixed --with-pid-dir option
  - Makefile fix from Gary E. Miller <gem@rellim.com>
- - Compile fix for HPUX and Solaris from Andre Lucas   
+ - Compile fix for HPUX and Solaris from Andre Lucas
    <andre.lucas@dial.pipex.com>
 
 20000117
 
 20000103
  - Add explicit make rules for files proccessed by fixpaths.
- - Fix "make install" in RPM spec files. Report from Tenkou N. Hattori 
+ - Fix "make install" in RPM spec files. Report from Tenkou N. Hattori
    <tnh@kondara.org>
  - Removed "nullok" directive from default PAM configuration files.
    Added information on enabling EmptyPasswords on openssh+PAM in
    - Use LDFLAGS correctly
    - Fix SIGIO error in scp
    - Simplify status line printing in scp
- - Added better test for inline functions compiler support from 
+ - Added better test for inline functions compiler support from
    Darren_Hall@progressive.com
 
 19991214
      print usage() everytime we get bad options
    - [ssh-keygen.c] overflow, djm@mindrot.org
    - [sshd.c] fix sigchld race; cjc5@po.cwru.edu
-    
+
 19991120
  - Merged more Solaris support from Marc G. Fournier
    <marc.fournier@acadiau.ca>
index c3cd580ea8401d75ece4c571912f02afcfc5dfc6..8ea71915a0e561b5af67fd9be69ab801318ad09f 100644 (file)
@@ -33,9 +33,9 @@ SSH_MODE= @SSHMODE@
 
 INSTALL_SSH_PRNG_CMDS=@INSTALL_SSH_PRNG_CMDS@
 
-@NO_SFTP@SFTP-SERVER=sftp-server$(EXEEXT)
+@NO_SFTP@SFTP_PROGS=sftp-server$(EXEEXT) sftp$(EXEEXT)
 
-TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-agent$(EXEEXT) scp$(EXEEXT) $(SFTP-SERVER)
+TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-agent$(EXEEXT) scp$(EXEEXT) $(SFTP_PROGS)
 
 LIBSSH_OBJS=atomicio.o authfd.o authfile.o bufaux.o buffer.o canohost.o channels.o cipher.o cli.o compat.o compress.o crc32.o deattack.o dispatch.o hmac.o hostfile.o key.o kex.o log.o match.o misc.o mpaux.o nchan.o packet.o radix.o rijndael.o entropy.o readpass.o rsa.o ssh-dss.o ssh-rsa.o tildexpand.o ttymodes.o uidswap.o uuencode.o xmalloc.o 
 
@@ -43,8 +43,8 @@ SSHOBJS= ssh.o sshconnect.o sshconnect1.o sshconnect2.o log-client.o readconf.o
 
 SSHDOBJS= sshd.o auth.o auth1.o auth2.o auth-chall.o auth2-chall.o auth-rhosts.o auth-options.o auth-krb4.o auth-pam.o auth2-pam.o auth-passwd.o auth-rsa.o auth-rh-rsa.o dh.o pty.o log-server.o login.o loginrec.o servconf.o serverloop.o md5crypt.o session.o groupaccess.o
 
-TROFFMAN       = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8
-CATMAN         = scp.0 ssh-add.0 ssh-agent.0 ssh-keygen.0 ssh-keyscan.0 ssh.0 sshd.0 sftp-server.0
+TROFFMAN       = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1
+CATMAN         = scp.0 ssh-add.0 ssh-agent.0 ssh-keygen.0 ssh-keyscan.0 ssh.0 sshd.0 sftp-server.0 sftp.1
 MANPAGES       = @MANTYPE@
 
 CONFIGFILES=sshd_config ssh_config primes
@@ -105,8 +105,12 @@ ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o log-client.o
 ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a log-client.o ssh-keyscan.o
        $(LD) -o $@ ssh-keyscan.o log-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) 
 
-sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp-server.o log-server.o
-       $(LD) -o $@ sftp-server.o log-server.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) 
+sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp-server.o sftp-common.o log-server.o
+       $(LD) -o $@ sftp-server.o sftp-common.o log-server.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) 
+
+# XXX: need to -lssh twice here!
+sftp$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-client.o sftp-int.o sftp-common.o log-client.o
+       $(LD) -o $@ sftp.o sftp-client.o sftp-common.o sftp-int.o log-client.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
 
 # test driver for the loginrec code - not built by default
 logintest: logintest.o $(LIBCOMPAT) libssh.a log-client.o loginrec.o
@@ -156,6 +160,7 @@ install-files:
        $(INSTALL) -m 0755 -s ssh-keygen $(DESTDIR)$(bindir)/ssh-keygen
        $(INSTALL) -m 0775 -s ssh-keyscan $(DESTDIR)$(bindir)/ssh-keyscan
        $(INSTALL) -m 0755 -s sshd $(DESTDIR)$(sbindir)/sshd
+       @NO_SFTP@$$(INSTALL) -m 0755 -s sftp $(DESTDIR)$(bindir)/sftp
        @NO_SFTP@$(INSTALL) -m 0755 -s sftp-server $(DESTDIR)$(libexecdir)/sftp-server
        $(INSTALL) -m 644 ssh.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1
        $(INSTALL) -m 644 scp.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1
@@ -164,6 +169,7 @@ install-files:
        $(INSTALL) -m 644 ssh-keygen.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keygen.1
        $(INSTALL) -m 644 ssh-keyscan.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keyscan.1
        $(INSTALL) -m 644 sshd.[08].out $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8
+       @NO_SFTP@$$(INSTALL) -m 644 sftp.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/sftp.1
        @NO_SFTP@$(INSTALL) -m 644 sftp-server.[08].out $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
        -rm -f $(DESTDIR)$(bindir)/slogin
        ln -s ssh$(EXEEXT) $(DESTDIR)$(bindir)/slogin
@@ -241,6 +247,7 @@ uninstall:
        -rm -f $(DESTDIR)$(bindir)/ssh-agent$(EXEEXT)
        -rm -f $(DESTDIR)$(bindir)/ssh-keygen$(EXEEXT)
        -rm -f $(DESTDIR)$(bindir)/ssh-keyscan$(EXEEXT)
+       -rm -f $(DESTDIR)$(bindir)/sftp$(EXEEXT)
        -rm -f $(DESTDIR)$(sbindir)/sshd$(EXEEXT)
        -rm -r $(DESTDIR)$(libexecdir)/sftp-server$(EXEEXT)
        -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1
@@ -248,6 +255,7 @@ uninstall:
        -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1
        -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-agent.1
        -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keygen.1
+       -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/sftp.1
        -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keyscan.1
        -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8
        -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
diff --git a/TODO b/TODO
index 62c51e150d20527fb895b792bbca29843e0ff489..1165a0d94b97171a60c2a83b7a561eda7b804d20 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,4 +1,6 @@
 Programming:
+- Grep for 'XXX' comments and fix
+
 - Replacement for setproctitle() - HP/UX support only currently
 
 - Improve PAM support (a pam_lastlog module will cause sshd to exit)
index 5457d9b149c7c1c6b0cf72c8f1910410d717c9c4..04d2f085f62c58e6ad375bdac488db5e0fa7f43b 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth-options.c,v 1.11 2001/01/21 19:05:41 markus Exp $");
+RCSID("$OpenBSD: auth-options.c,v 1.12 2001/02/03 10:08:36 markus Exp $");
 
 #include "packet.h"
 #include "xmalloc.h"
@@ -18,6 +18,7 @@ RCSID("$OpenBSD: auth-options.c,v 1.11 2001/01/21 19:05:41 markus Exp $");
 #include "log.h"
 #include "canohost.h"
 #include "auth-options.h"
+#include "servconf.h"
 
 /* Flags set authorized_keys flags */
 int no_port_forwarding_flag = 0;
@@ -31,6 +32,8 @@ char *forced_command = NULL;
 /* "environment=" options. */
 struct envstring *custom_environment = NULL;
 
+extern ServerOptions options;
+
 void
 auth_clear_options(void)
 {
@@ -55,61 +58,61 @@ auth_clear_options(void)
  * side effect: sets key option flags
  */
 int
-auth_parse_options(struct passwd *pw, char *options, char *file, u_long linenum)
+auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
 {
        const char *cp;
-       if (!options)
+       if (!opts)
                return 1;
 
        /* reset options */
        auth_clear_options();
 
-       while (*options && *options != ' ' && *options != '\t') {
+       while (*opts && *opts != ' ' && *opts != '\t') {
                cp = "no-port-forwarding";
-               if (strncasecmp(options, cp, strlen(cp)) == 0) {
+               if (strncasecmp(opts, cp, strlen(cp)) == 0) {
                        packet_send_debug("Port forwarding disabled.");
                        no_port_forwarding_flag = 1;
-                       options += strlen(cp);
+                       opts += strlen(cp);
                        goto next_option;
                }
                cp = "no-agent-forwarding";
-               if (strncasecmp(options, cp, strlen(cp)) == 0) {
+               if (strncasecmp(opts, cp, strlen(cp)) == 0) {
                        packet_send_debug("Agent forwarding disabled.");
                        no_agent_forwarding_flag = 1;
-                       options += strlen(cp);
+                       opts += strlen(cp);
                        goto next_option;
                }
                cp = "no-X11-forwarding";
-               if (strncasecmp(options, cp, strlen(cp)) == 0) {
+               if (strncasecmp(opts, cp, strlen(cp)) == 0) {
                        packet_send_debug("X11 forwarding disabled.");
                        no_x11_forwarding_flag = 1;
-                       options += strlen(cp);
+                       opts += strlen(cp);
                        goto next_option;
                }
                cp = "no-pty";
-               if (strncasecmp(options, cp, strlen(cp)) == 0) {
+               if (strncasecmp(opts, cp, strlen(cp)) == 0) {
                        packet_send_debug("Pty allocation disabled.");
                        no_pty_flag = 1;
-                       options += strlen(cp);
+                       opts += strlen(cp);
                        goto next_option;
                }
                cp = "command=\"";
-               if (strncasecmp(options, cp, strlen(cp)) == 0) {
+               if (strncasecmp(opts, cp, strlen(cp)) == 0) {
                        int i;
-                       options += strlen(cp);
-                       forced_command = xmalloc(strlen(options) + 1);
+                       opts += strlen(cp);
+                       forced_command = xmalloc(strlen(opts) + 1);
                        i = 0;
-                       while (*options) {
-                               if (*options == '"')
+                       while (*opts) {
+                               if (*opts == '"')
                                        break;
-                               if (*options == '\\' && options[1] == '"') {
-                                       options += 2;
+                               if (*opts == '\\' && opts[1] == '"') {
+                                       opts += 2;
                                        forced_command[i++] = '"';
                                        continue;
                                }
-                               forced_command[i++] = *options++;
+                               forced_command[i++] = *opts++;
                        }
-                       if (!*options) {
+                       if (!*opts) {
                                debug("%.100s, line %lu: missing end quote",
                                    file, linenum);
                                packet_send_debug("%.100s, line %lu: missing end quote",
@@ -118,28 +121,28 @@ auth_parse_options(struct passwd *pw, char *options, char *file, u_long linenum)
                        }
                        forced_command[i] = 0;
                        packet_send_debug("Forced command: %.900s", forced_command);
-                       options++;
+                       opts++;
                        goto next_option;
                }
                cp = "environment=\"";
-               if (strncasecmp(options, cp, strlen(cp)) == 0) {
+               if (strncasecmp(opts, cp, strlen(cp)) == 0) {
                        int i;
                        char *s;
                        struct envstring *new_envstring;
-                       options += strlen(cp);
-                       s = xmalloc(strlen(options) + 1);
+                       opts += strlen(cp);
+                       s = xmalloc(strlen(opts) + 1);
                        i = 0;
-                       while (*options) {
-                               if (*options == '"')
+                       while (*opts) {
+                               if (*opts == '"')
                                        break;
-                               if (*options == '\\' && options[1] == '"') {
-                                       options += 2;
+                               if (*opts == '\\' && opts[1] == '"') {
+                                       opts += 2;
                                        s[i++] = '"';
                                        continue;
                                }
-                               s[i++] = *options++;
+                               s[i++] = *opts++;
                        }
-                       if (!*options) {
+                       if (!*opts) {
                                debug("%.100s, line %lu: missing end quote",
                                    file, linenum);
                                packet_send_debug("%.100s, line %lu: missing end quote",
@@ -149,7 +152,7 @@ auth_parse_options(struct passwd *pw, char *options, char *file, u_long linenum)
                        s[i] = 0;
                        packet_send_debug("Adding to environment: %.900s", s);
                        debug("Adding to environment: %.900s", s);
-                       options++;
+                       opts++;
                        new_envstring = xmalloc(sizeof(struct envstring));
                        new_envstring->s = s;
                        new_envstring->next = custom_environment;
@@ -157,23 +160,26 @@ auth_parse_options(struct passwd *pw, char *options, char *file, u_long linenum)
                        goto next_option;
                }
                cp = "from=\"";
-               if (strncasecmp(options, cp, strlen(cp)) == 0) {
+               if (strncasecmp(opts, cp, strlen(cp)) == 0) {
                        int mname, mip;
-                       char *patterns = xmalloc(strlen(options) + 1);
+                       const char *remote_ip = get_remote_ipaddr();
+                       const char *remote_host = get_canonical_hostname(
+                           options.reverse_mapping_check);
+                       char *patterns = xmalloc(strlen(opts) + 1);
                        int i;
-                       options += strlen(cp);
+                       opts += strlen(cp);
                        i = 0;
-                       while (*options) {
-                               if (*options == '"')
+                       while (*opts) {
+                               if (*opts == '"')
                                        break;
-                               if (*options == '\\' && options[1] == '"') {
-                                       options += 2;
+                               if (*opts == '\\' && opts[1] == '"') {
+                                       opts += 2;
                                        patterns[i++] = '"';
                                        continue;
                                }
-                               patterns[i++] = *options++;
+                               patterns[i++] = *opts++;
                        }
-                       if (!*options) {
+                       if (!*opts) {
                                debug("%.100s, line %lu: missing end quote",
                                    file, linenum);
                                packet_send_debug("%.100s, line %lu: missing end quote",
@@ -181,24 +187,26 @@ auth_parse_options(struct passwd *pw, char *options, char *file, u_long linenum)
                                continue;
                        }
                        patterns[i] = 0;
-                       options++;
+                       opts++;
                        /*
                         * Deny access if we get a negative
                         * match for the hostname or the ip
                         * or if we get not match at all
                         */
-                       mname = match_hostname(get_canonical_hostname(),
-                           patterns, strlen(patterns));
-                       mip = match_hostname(get_remote_ipaddr(),
-                           patterns, strlen(patterns));
+                       mname = match_hostname(remote_host, patterns,
+                           strlen(patterns));
+                       mip = match_hostname(remote_ip, patterns,
+                           strlen(patterns));
                        xfree(patterns);
                        if (mname == -1 || mip == -1 ||
                            (mname != 1 && mip != 1)) {
-                               log("Authentication tried for %.100s with correct key but not from a permitted host (host=%.200s, ip=%.200s).",
-                                   pw->pw_name, get_canonical_hostname(),
-                                   get_remote_ipaddr());
-                               packet_send_debug("Your host '%.200s' is not permitted to use this key for login.",
-                               get_canonical_hostname());
+                               log("Authentication tried for %.100s with "
+                                   "correct key but not from a permitted "
+                                   "host (host=%.200s, ip=%.200s).",
+                                   pw->pw_name, remote_host, remote_ip);
+                               packet_send_debug("Your host '%.200s' is not "
+                                   "permitted to use this key for login.",
+                                   remote_host);
                                /* deny access */
                                return 0;
                        }
@@ -210,13 +218,13 @@ next_option:
                 * Skip the comma, and move to the next option
                 * (or break out if there are no more).
                 */
-               if (!*options)
+               if (!*opts)
                        fatal("Bugs in auth-options.c option processing.");
-               if (*options == ' ' || *options == '\t')
+               if (*opts == ' ' || *opts == '\t')
                        break;          /* End of options. */
-               if (*options != ',')
+               if (*opts != ',')
                        goto bad_option;
-               options++;
+               opts++;
                /* Process the next option. */
        }
        /* grant access */
@@ -224,9 +232,9 @@ next_option:
 
 bad_option:
        log("Bad options in %.100s file, line %lu: %.50s",
-           file, linenum, options);
+           file, linenum, opts);
        packet_send_debug("Bad options in %.100s file, line %lu: %.50s",
-           file, linenum, options);
+           file, linenum, opts);
        /* deny access */
        return 0;
 }
index fcf3b69093a9c9f6f8d17834cac7731b18dd8b36..3980861fe2b8cdb16f7330378d02b3d358d6fdc7 100644 (file)
@@ -211,10 +211,12 @@ int auth_pam_password(struct passwd *pw, const char *password)
 int do_pam_account(char *username, char *remote_user)
 {
        int pam_retval;
+       extern ServerOptions options;
        
-       debug("PAM setting rhost to \"%.200s\"", get_canonical_hostname());
+       debug("PAM setting rhost to \"%.200s\"", 
+           get_canonical_hostname(options.reverse_mapping_check));
        pam_retval = pam_set_item(pamh, PAM_RHOST, 
-               get_canonical_hostname());
+               get_canonical_hostname(options.reverse_mapping_check));
        if (pam_retval != PAM_SUCCESS) {
                fatal("PAM set rhost failed[%d]: %.200s", 
                        pam_retval, PAM_STRERROR(pamh, pam_retval));
index 87d51549d2097bb2676bff5000553298d4832b7d..0edbdb5f3772ee84a22acb7ab59fdb0ca921ae34 100644 (file)
@@ -13,7 +13,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth-rh-rsa.c,v 1.21 2001/01/21 19:05:42 markus Exp $");
+RCSID("$OpenBSD: auth-rh-rsa.c,v 1.22 2001/02/03 10:08:36 markus Exp $");
 
 #include "packet.h"
 #include "xmalloc.h"
@@ -49,7 +49,8 @@ auth_rhosts_rsa(struct passwd *pw, const char *client_user, RSA *client_host_key
        if (!auth_rhosts(pw, client_user))
                return 0;
 
-       canonical_hostname = get_canonical_hostname();
+       canonical_hostname = get_canonical_hostname(
+           options.reverse_mapping_check);
 
        debug("Rhosts RSA authentication: canonical host %.900s", canonical_hostname);
 
index 4f9ea886d47a5bf0365c4168a182cad4348df025..d8d10ffc9dd5441c5e23db41bf1cfde03cdb4d19 100644 (file)
@@ -14,7 +14,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth-rhosts.c,v 1.19 2001/01/21 19:05:42 markus Exp $");
+RCSID("$OpenBSD: auth-rhosts.c,v 1.20 2001/02/03 10:08:36 markus Exp $");
 
 #include "packet.h"
 #include "xmalloc.h"
@@ -183,7 +183,7 @@ auth_rhosts(struct passwd *pw, const char *client_user)
            stat(_PATH_SSH_HOSTS_EQUIV, &st) < 0)
                return 0;
 
-       hostname = get_canonical_hostname();
+       hostname = get_canonical_hostname(options.reverse_mapping_check);
        ipaddr = get_remote_ipaddr();
 
        /* If not logging in as superuser, try /etc/hosts.equiv and shosts.equiv. */
diff --git a/auth.c b/auth.c
index 187216d277a854548fd3a4fe392ccfe9bb654130..4e3cf675ee0116302dedceb4575c36cbf20c1a59 100644 (file)
--- a/auth.c
+++ b/auth.c
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth.c,v 1.14 2001/01/21 19:05:43 markus Exp $");
+RCSID("$OpenBSD: auth.c,v 1.15 2001/02/03 10:08:37 markus Exp $");
 
 #ifdef HAVE_LOGIN_H
 #include <login.h>
@@ -228,7 +228,7 @@ auth_root_allowed(void)
                log("Root login accepted for forced command.");
                return 1;
        } else {
-               log("ROOT LOGIN REFUSED FROM %.200s", get_canonical_hostname());
+               log("ROOT LOGIN REFUSED FROM %.200s", get_remote_ipaddr());
                return 0;
        }
 }
diff --git a/auth1.c b/auth1.c
index 6e9808e5ec75221dfb6361f5982fbcbf3e7282e3..1986b2d8dd4c4c9042f2ab7d25351004099fc50d 100644 (file)
--- a/auth1.c
+++ b/auth1.c
@@ -266,8 +266,8 @@ do_authloop(Authctxt *authctxt)
 #elif defined(HAVE_OSF_SIA)
                        /* Do SIA auth with password */
                        if (sia_validate_user(NULL, saved_argc, saved_argv, 
-                               get_canonical_hostname(), pw->pw_name, NULL, 0
-                               NULL, password) == SIASUCCESS) {
+                           get_canonical_hostname(options.reverse_mapping_check)
+                           pw->pw_name, NULL, 0, NULL, password) == SIASUCCESS) {
                                authenticated = 1;
                        }
 #else /* !USE_PAM && !HAVE_OSF_SIA */
@@ -347,7 +347,9 @@ do_authloop(Authctxt *authctxt)
 
                if (authctxt->failures++ > AUTH_FAIL_MAX) {
 #ifdef WITH_AIXAUTHENTICATE 
-                       loginfailed(user,get_canonical_hostname(),"ssh");
+                       loginfailed(user, 
+                           get_canonical_hostname(options.reverse_mapping_check), 
+                           "ssh");
 #endif /* WITH_AIXAUTHENTICATE */
                        packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
                }
@@ -433,7 +435,9 @@ do_authentication()
 
 #ifdef WITH_AIXAUTHENTICATE
        /* We don't have a pty yet, so just label the line as "ssh" */
-       if (loginsuccess(authctxt->user,get_canonical_hostname(),"ssh",&aixloginmsg) < 0)
+       if (loginsuccess(authctxt->user, 
+           get_canonical_hostname(options.reverse_mapping_check),
+           "ssh", &aixloginmsg) < 0)
                aixloginmsg = NULL;
 #endif /* WITH_AIXAUTHENTICATE */
 
diff --git a/auth2.c b/auth2.c
index cff34c602a87435b92244db3e6a4479e0c4ca643..5f8b4234012c190837bd6b3950dd36842e803deb 100644 (file)
--- a/auth2.c
+++ b/auth2.c
@@ -310,7 +310,8 @@ userauth_reply(Authctxt *authctxt, int authenticated)
 #ifdef WITH_AIXAUTHENTICATE
                /* We don't have a pty yet, so just label the line as "ssh" */
                if (loginsuccess(authctxt->user?authctxt->user:"NOUSER", 
-                       get_canonical_hostname(), "ssh", &aixloginmsg) < 0)
+                   get_canonical_hostname(options.reverse_mapping_check), 
+                   "ssh", &aixloginmsg) < 0)
                        aixloginmsg = NULL;
 #endif /* WITH_AIXAUTHENTICATE */
                /* turn off userauth */
@@ -354,8 +355,9 @@ userauth_none(Authctxt *authctxt)
        return auth_pam_password(authctxt->pw, "");
 #elif defined(HAVE_OSF_SIA)
        return (sia_validate_user(NULL, saved_argc, saved_argv, 
-               get_canonical_hostname(), authctxt->user?authctxt->user:"NOUSER", 
-                       NULL, 0, NULL, "") == SIASUCCESS);
+           get_canonical_hostname(options.reverse_mapping_check), 
+           authctxt->user?authctxt->user:"NOUSER", NULL, 0, 
+           NULL, "") == SIASUCCESS);
 #else /* !HAVE_OSF_SIA && !USE_PAM */
        return auth_password(authctxt->pw, "");
 #endif /* USE_PAM */
@@ -381,8 +383,9 @@ userauth_passwd(Authctxt *authctxt)
            auth_pam_password(authctxt->pw, password) == 1)
 #elif defined(HAVE_OSF_SIA)
            sia_validate_user(NULL, saved_argc, saved_argv, 
-                       get_canonical_hostname(), authctxt->user?authctxt->user:"NOUSER", 
-                       NULL, 0, NULL, password) == SIASUCCESS)
+           get_canonical_hostname(options.reverse_mapping_check), 
+           authctxt->user?authctxt->user:"NOUSER", NULL, 0, NULL, 
+           password) == SIASUCCESS)
 #else /* !USE_PAM && !HAVE_OSF_SIA */
            auth_password(authctxt->pw, password) == 1)
 #endif /* USE_PAM */
index f3a65932877b04432ac1e532a85ba34caf596bcc..8253e9b6e714f48c3646c769c8fb097aa851f1b9 100644 (file)
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: canohost.c,v 1.19 2001/01/29 19:42:33 markus Exp $");
+RCSID("$OpenBSD: canohost.c,v 1.20 2001/02/03 10:08:37 markus Exp $");
 
 #include "packet.h"
 #include "xmalloc.h"
 #include "log.h"
 
+void   check_ip_options(int socket, char *ipaddr);
+
 /*
  * Return the canonical name of the host at the other end of the socket. The
  * caller should free the returned string with xfree.
  */
 
 char *
-get_remote_hostname(int socket)
+get_remote_hostname(int socket, int reverse_mapping_check)
 {
        struct sockaddr_storage from;
        int i;
        socklen_t fromlen;
        struct addrinfo hints, *ai, *aitop;
-       char name[MAXHOSTNAMELEN];
-       char ntop[NI_MAXHOST], ntop2[NI_MAXHOST];
+       char name[NI_MAXHOST], ntop[NI_MAXHOST], ntop2[NI_MAXHOST];
 
        /* Get IP address of client. */
        fromlen = sizeof(from);
        memset(&from, 0, sizeof(from));
-       if (getpeername(socket, (struct sockaddr *) & from, &fromlen) < 0) {
+       if (getpeername(socket, (struct sockaddr *) &from, &fromlen) < 0) {
                debug("getpeername failed: %.100s", strerror(errno));
                fatal_cleanup();
        }
-
 #ifdef IPV4_IN_IPV6
        if (from.ss_family == AF_INET6) {
                struct sockaddr_in6 *from6 = (struct sockaddr_in6 *)&from;
@@ -63,6 +63,8 @@ get_remote_hostname(int socket)
                }
        }
 #endif
+       if (from.ss_family == AF_INET)
+               check_ip_options(socket, ntop);
 
        if (getnameinfo((struct sockaddr *)&from, fromlen, ntop, sizeof(ntop),
             NULL, 0, NI_NUMERICHOST) != 0)
@@ -70,99 +72,99 @@ get_remote_hostname(int socket)
 
        /* Map the IP address to a host name. */
        if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name),
-            NULL, 0, NI_NAMEREQD) == 0) {
-               /* Got host name. */
-               name[sizeof(name) - 1] = '\0';
-               /*
-                * Convert it to all lowercase (which is expected by the rest
-                * of this software).
-                */
-               for (i = 0; name[i]; i++)
-                       if (isupper(name[i]))
-                               name[i] = tolower(name[i]);
-
-               /*
-                * Map it back to an IP address and check that the given
-                * address actually is an address of this host.  This is
-                * necessary because anyone with access to a name server can
-                * define arbitrary names for an IP address. Mapping from
-                * name to IP address can be trusted better (but can still be
-                * fooled if the intruder has access to the name server of
-                * the domain).
-                */
-               memset(&hints, 0, sizeof(hints));
-               hints.ai_family = from.ss_family;
-               hints.ai_socktype = SOCK_STREAM;
-               if (getaddrinfo(name, NULL, &hints, &aitop) != 0) {
-                       log("reverse mapping checking getaddrinfo for %.700s failed - POSSIBLE BREAKIN ATTEMPT!", name);
-                       strlcpy(name, ntop, sizeof name);
-                       goto check_ip_options;
-               }
-               /* Look for the address from the list of addresses. */
-               for (ai = aitop; ai; ai = ai->ai_next) {
-                       if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2,
-                           sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 &&
-                           (strcmp(ntop, ntop2) == 0))
-                                       break;
-               }
-               freeaddrinfo(aitop);
-               /* If we reached the end of the list, the address was not there. */
-               if (!ai) {
-                       /* Address not found for the host name. */
-                       log("Address %.100s maps to %.600s, but this does not map back to the address - POSSIBLE BREAKIN ATTEMPT!",
-                           ntop, name);
-                       strlcpy(name, ntop, sizeof name);
-                       goto check_ip_options;
-               }
-               /* Address was found for the host name.  We accept the host name. */
-       } else {
-               /* Host name not found.  Use ascii representation of the address. */
-               strlcpy(name, ntop, sizeof name);
-               log("Could not reverse map address %.100s.", name);
+            NULL, 0, NI_NAMEREQD) != 0) {
+               /* Host name not found.  Use ip address. */
+               log("Could not reverse map address %.100s.", ntop);
+               return xstrdup(ntop);
        }
 
-check_ip_options:
+       /* Got host name. */
+       name[sizeof(name) - 1] = '\0';
+       /*
+        * Convert it to all lowercase (which is expected by the rest
+        * of this software).
+        */
+       for (i = 0; name[i]; i++)
+               if (isupper(name[i]))
+                       name[i] = tolower(name[i]);
 
+       if (!reverse_mapping_check)
+               return xstrdup(name);
        /*
-        * If IP options are supported, make sure there are none (log and
-        * disconnect them if any are found).  Basically we are worried about
-        * source routing; it can be used to pretend you are somebody
-        * (ip-address) you are not. That itself may be "almost acceptable"
-        * under certain circumstances, but rhosts autentication is useless
-        * if source routing is accepted. Notice also that if we just dropped
-        * source routing here, the other side could use IP spoofing to do
-        * rest of the interaction and could still bypass security.  So we
-        * exit here if we detect any IP options.
+        * Map it back to an IP address and check that the given
+        * address actually is an address of this host.  This is
+        * necessary because anyone with access to a name server can
+        * define arbitrary names for an IP address. Mapping from
+        * name to IP address can be trusted better (but can still be
+        * fooled if the intruder has access to the name server of
+        * the domain).
         */
-       /* IP options -- IPv4 only */
-       if (from.ss_family == AF_INET) {
-               u_char options[200], *ucp;
-               char text[1024], *cp;
-               socklen_t option_size;
-               int ipproto;
-               struct protoent *ip;
-
-               if ((ip = getprotobyname("ip")) != NULL)
-                       ipproto = ip->p_proto;
-               else
-                       ipproto = IPPROTO_IP;
-               option_size = sizeof(options);
-               if (getsockopt(socket, ipproto, IP_OPTIONS, (char *) options,
-                   &option_size) >= 0 && option_size != 0) {
-                       cp = text;
-                       /* Note: "text" buffer must be at least 3x as big as options. */
-                       for (ucp = options; option_size > 0; ucp++, option_size--, cp += 3)
-                               sprintf(cp, " %2.2x", *ucp);
-                       log("Connection from %.100s with IP options:%.800s",
-                           ntop, text);
-                       packet_disconnect("Connection from %.100s with IP options:%.800s",
-                                         ntop, text);
-               }
+       memset(&hints, 0, sizeof(hints));
+       hints.ai_family = from.ss_family;
+       hints.ai_socktype = SOCK_STREAM;
+       if (getaddrinfo(name, NULL, &hints, &aitop) != 0) {
+               log("reverse mapping checking getaddrinfo for %.700s "
+                   "failed - POSSIBLE BREAKIN ATTEMPT!", name);
+               return xstrdup(ntop);
+       }
+       /* Look for the address from the list of addresses. */
+       for (ai = aitop; ai; ai = ai->ai_next) {
+               if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2,
+                   sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 &&
+                   (strcmp(ntop, ntop2) == 0))
+                               break;
+       }
+       freeaddrinfo(aitop);
+       /* If we reached the end of the list, the address was not there. */
+       if (!ai) {
+               /* Address not found for the host name. */
+               log("Address %.100s maps to %.600s, but this does not "
+                   "map back to the address - POSSIBLE BREAKIN ATTEMPT!",
+                   ntop, name);
+               return xstrdup(ntop);
        }
-
        return xstrdup(name);
 }
 
+/*
+ * If IP options are supported, make sure there are none (log and
+ * disconnect them if any are found).  Basically we are worried about
+ * source routing; it can be used to pretend you are somebody
+ * (ip-address) you are not. That itself may be "almost acceptable"
+ * under certain circumstances, but rhosts autentication is useless
+ * if source routing is accepted. Notice also that if we just dropped
+ * source routing here, the other side could use IP spoofing to do
+ * rest of the interaction and could still bypass security.  So we
+ * exit here if we detect any IP options.
+ */
+/* IPv4 only */
+void
+check_ip_options(int socket, char *ipaddr)
+{
+       u_char options[200], *ucp;
+       char text[1024], *cp;
+       socklen_t option_size;
+       int ipproto;
+       struct protoent *ip;
+
+       if ((ip = getprotobyname("ip")) != NULL)
+               ipproto = ip->p_proto;
+       else
+               ipproto = IPPROTO_IP;
+       option_size = sizeof(options);
+       if (getsockopt(socket, ipproto, IP_OPTIONS, (void *)options,
+           &option_size) >= 0 && option_size != 0) {
+               cp = text;
+               /* Note: "text" buffer must be at least 3x as big as options. */
+               for (ucp = options; option_size > 0; ucp++, option_size--, cp += 3)
+                       sprintf(cp, " %2.2x", *ucp);
+               log("Connection from %.100s with IP options:%.800s",
+                   ipaddr, text);
+               packet_disconnect("Connection from %.100s with IP options:%.800s",
+                   ipaddr, text);
+       }
+}
+
 /*
  * Return the canonical name of the host in the other side of the current
  * connection.  The host name is cached, so it is efficient to call this
@@ -170,20 +172,27 @@ check_ip_options:
  */
 
 const char *
-get_canonical_hostname()
+get_canonical_hostname(int reverse_mapping_check)
 {
        static char *canonical_host_name = NULL;
+       static int reverse_mapping_checked = 0;
 
-       /* Check if we have previously retrieved this same name. */
-       if (canonical_host_name != NULL)
-               return canonical_host_name;
+       /* Check if we have previously retrieved name with same option. */
+       if (canonical_host_name != NULL) {
+               if (reverse_mapping_checked != reverse_mapping_check)
+                       xfree(canonical_host_name);
+               else
+                       return canonical_host_name;
+       }
 
        /* Get the real hostname if socket; otherwise return UNKNOWN. */
        if (packet_connection_is_on_socket())
-               canonical_host_name = get_remote_hostname(packet_get_connection_in());
+               canonical_host_name = get_remote_hostname(
+                   packet_get_connection_in(), reverse_mapping_check);
        else
                canonical_host_name = xstrdup("UNKNOWN");
 
+       reverse_mapping_checked = reverse_mapping_check;
        return canonical_host_name;
 }
 
index 982ec594965d669e8ea407a111690bff6ee03818..da60b3af9f00cba61175b94fbe63ba98c9fcf88a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: canohost.h,v 1.3 2001/01/29 19:42:35 markus Exp $     */
+/*     $OpenBSD: canohost.h,v 1.4 2001/02/03 10:08:37 markus Exp $     */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * incompatible with the protocol description in the RFC file, it must be
  * called by a name other than "ssh" or "Secure Shell".
  */
-/*
- * Returns the name of the machine at the other end of the socket.  The
- * returned string should be freed by the caller.
- */
-char   *get_remote_hostname(int socket);
 
 /*
  * Return the canonical name of the host in the other side of the current
  * connection (as returned by packet_get_connection).  The host name is
  * cached, so it is efficient to call this several times.
  */
-const char *get_canonical_hostname(void);
+const char *get_canonical_hostname(int reverse_mapping_check);
 
 /*
  * Returns the IP-address of the remote host as a string.  The returned
- * string must not be freed.
+ * string is cached and must not be freed.
  */
 const char *get_remote_ipaddr(void);
 
index 82a2db05e151d3af84ffd587bdb3b72cc1ec298a..d343ac89e5a4205dd599ed0d3e8ed358cb1521de 100644 (file)
@@ -40,7 +40,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: channels.c,v 1.85 2001/01/29 19:42:35 markus Exp $");
+RCSID("$OpenBSD: channels.c,v 1.88 2001/02/01 21:58:08 markus Exp $");
 
 #include <openssl/rsa.h>
 #include <openssl/dsa.h>
@@ -600,7 +600,7 @@ channel_post_port_listener(Channel *c, fd_set * readset, fd_set * writeset)
        struct sockaddr addr;
        int newsock, newch;
        socklen_t addrlen;
-       char buf[1024], *remote_hostname, *rtype;
+       char buf[1024], *remote_ipaddr, *rtype;
        int remote_port;
 
        rtype = (c->type == SSH_CHANNEL_RPORT_LISTENER) ?
@@ -616,13 +616,13 @@ channel_post_port_listener(Channel *c, fd_set * readset, fd_set * writeset)
                        error("accept: %.100s", strerror(errno));
                        return;
                }
-               remote_hostname = get_remote_hostname(newsock);
+               remote_ipaddr = get_peer_ipaddr(newsock);
                remote_port = get_peer_port(newsock);
                snprintf(buf, sizeof buf,
                    "listen port %d for %.100s port %d, "
                    "connect from %.200s port %d",
                    c->listening_port, c->path, c->host_port,
-                   remote_hostname, remote_port);
+                   remote_ipaddr, remote_port);
 
                newch = channel_new(rtype,
                    SSH_CHANNEL_OPENING, newsock, newsock, -1,
@@ -644,7 +644,7 @@ channel_post_port_listener(Channel *c, fd_set * readset, fd_set * writeset)
                                packet_put_int(c->host_port);
                        }
                        /* originator host and port */
-                       packet_put_cstring(remote_hostname);
+                       packet_put_cstring(remote_ipaddr);
                        packet_put_int(remote_port);
                        packet_send();
                } else {
@@ -657,7 +657,7 @@ channel_post_port_listener(Channel *c, fd_set * readset, fd_set * writeset)
                        }
                        packet_send();
                }
-               xfree(remote_hostname);
+               xfree(remote_ipaddr);
        }
 }
 
index 557770d76cec71cbe45167c6d8ef1f926ec24a66..6bba4d36a6c2df595cdc401332da01d1108407e1 100644 (file)
@@ -253,9 +253,13 @@ fi
 %attr(4755,root,root) %{_bindir}/ssh
 %attr(0755,root,root) %{_bindir}/ssh-agent
 %attr(0755,root,root) %{_bindir}/ssh-add
+%attr(0755,root,root) %{_bindir}/ssh-keyscan
+%attr(0755,root,root) %{_bindir}/sftp
 %attr(0644,root,root) %{_mandir}/man1/ssh.1*
 %attr(0644,root,root) %{_mandir}/man1/ssh-agent.1*
 %attr(0644,root,root) %{_mandir}/man1/ssh-add.1*
+%attr(0644,root,root) %{_mandir}/man1/ssh-keyscan.1*
+%attr(0644,root,root) %{_mandir}/man1/sftp.1*
 %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ssh_config
 %attr(-,root,root) %{_bindir}/slogin
 %attr(-,root,root) %{_mandir}/man1/slogin.1*
index 482306f8b932d8ae0da1bfddda2201a82d64f48b..c6574a279f43a071603057ae12b84553d6ef128b 100644 (file)
@@ -223,9 +223,13 @@ fi
 %attr(4755,root,root) %{_bindir}/ssh
 %attr(0755,root,root) %{_bindir}/ssh-agent
 %attr(0755,root,root) %{_bindir}/ssh-add
+%attr(0755,root,root) %{_bindir}/ssh-keyscan
+%attr(0755,root,root) %{_bindir}/sftp
 %attr(0644,root,root) %{_mandir}/man1/ssh.1*
 %attr(0644,root,root) %{_mandir}/man1/ssh-agent.1*
 %attr(0644,root,root) %{_mandir}/man1/ssh-add.1*
+%attr(0644,root,root) %{_mandir}/man1/ssh-keyscan.1*
+%attr(0644,root,root) %{_mandir}/man1/sftp.1*
 %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ssh_config
 %attr(-,root,root) %{_bindir}/slogin
 %attr(-,root,root) %{_mandir}/man1/slogin.1*
index b4cc2d92fdf486e08fc5a2999dd1a8e9148085df..01ff204e0892fbc57ceecfd2ff9577fbddf0d684 100644 (file)
@@ -180,6 +180,8 @@ fi
 %attr(-,root,root) /usr/bin/slogin
 %attr(0755,root,root) /usr/bin/ssh-agent
 %attr(0755,root,root) /usr/bin/ssh-add
+%attr(0755,root,root) /usr/bin/ssh-keyscan
+%attr(0755,root,root) /usr/bin/sftp
 %attr(0755,root,root) /usr/sbin/sshd
 %attr(-,root,root) /usr/sbin/rcsshd
 %attr(0755,root,root) %dir /usr/lib/ssh
diff --git a/scp.1 b/scp.1
index 0a2ca1a3445b2f238622c41800e9656dc4ecb87e..10e67aa33d1cfb576886017065948d61d3ddb402 100644 (file)
--- a/scp.1
+++ b/scp.1
@@ -9,7 +9,7 @@
 .\"
 .\" Created: Sun May  7 00:14:37 1995 ylo
 .\"
-.\" $OpenBSD: scp.1,v 1.13 2000/10/16 09:38:44 djm Exp $
+.\" $OpenBSD: scp.1,v 1.14 2001/02/04 11:11:53 djm Exp $
 .\"
 .Dd September 25, 1999
 .Dt SCP 1
@@ -129,6 +129,7 @@ program in BSD source code from the Regents of the University of
 California.
 .Sh SEE ALSO
 .Xr rcp 1 ,
+.Xr sftp 1 ,
 .Xr ssh 1 ,
 .Xr ssh-add 1 ,
 .Xr ssh-agent 1 ,
index 9f292b6a5495f54640f2f86c0dbe27c89aded394..5fa41e028e9dca4bbf3c98c1b99dd2bb7fc74406 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: servconf.c,v 1.63 2001/01/22 23:06:39 markus Exp $");
+RCSID("$OpenBSD: servconf.c,v 1.64 2001/02/03 10:08:37 markus Exp $");
 
 #ifdef KRB4
 #include <krb.h>
@@ -92,6 +92,7 @@ initialize_server_options(ServerOptions *options)
        options->max_startups_rate = -1;
        options->max_startups = -1;
        options->banner = NULL;
+       options->reverse_mapping_check = -1;
 }
 
 void
@@ -186,6 +187,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->reverse_mapping_check == -1)
+               options->reverse_mapping_check = 0;
 }
 
 /* Keyword tokens. */
@@ -208,7 +211,7 @@ typedef enum {
        sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
        sIgnoreUserKnownHosts, sCiphers, sProtocol, sPidFile,
        sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
-       sBanner
+       sBanner, sReverseMappingCheck
 } ServerOpCodes;
 
 /* Textual representation of the tokens. */
@@ -268,6 +271,7 @@ static struct {
        { "subsystem", sSubsystem },
        { "maxstartups", sMaxStartups },
        { "banner", sBanner },
+       { "reversemappingcheck", sReverseMappingCheck },
        { NULL, 0 }
 };
 
@@ -577,6 +581,10 @@ parse_flag:
                        intptr = &options->gateway_ports;
                        goto parse_flag;
 
+               case sReverseMappingCheck:
+                       intptr = &options->reverse_mapping_check;
+                       goto parse_flag;
+
                case sLogFacility:
                        intptr = (int *) &options->log_facility;
                        arg = strdelim(&cp);
index e31636701fb0ffab0f4dcf8e0c814574ad6b8d31..e7abb94d8ea97ee93306577b10cee6fd60c1c204 100644 (file)
@@ -11,7 +11,7 @@
  * called by a name other than "ssh" or "Secure Shell".
  */
 
-/* RCSID("$OpenBSD: servconf.h,v 1.35 2001/01/22 23:06:40 markus Exp $"); */
+/* RCSID("$OpenBSD: servconf.h,v 1.36 2001/02/03 10:08:37 markus Exp $"); */
 
 #ifndef SERVCONF_H
 #define SERVCONF_H
@@ -102,6 +102,7 @@ typedef struct {
        int     max_startups_rate;
        int     max_startups;
        char   *banner;                 /* SSH-2 banner message */
+       int     reverse_mapping_check;  /* cross-check ip and dns */
 
 }       ServerOptions;
 /*
index b6ab8873197e10da66115794f47e26bface65570..51b661afbf5f69ae7ab6aea8bd9a65e5a449dd31 100644 (file)
--- a/session.c
+++ b/session.c
@@ -33,7 +33,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: session.c,v 1.51 2001/01/21 19:05:56 markus Exp $");
+RCSID("$OpenBSD: session.c,v 1.52 2001/02/03 10:08:37 markus Exp $");
 
 #include "ssh.h"
 #include "ssh1.h"
@@ -683,7 +683,7 @@ get_remote_name_or_ip(void)
 {
        static const char *remote = "";
        if (utmp_len > 0)
-               remote = get_canonical_hostname();
+               remote = get_canonical_hostname(options.reverse_mapping_check);
        if (utmp_len == 0 || strlen(remote) > utmp_len)
                remote = get_remote_ipaddr();
        return remote;
@@ -1061,7 +1061,7 @@ do_child(const char *command, struct passwd * pw, const char *term,
 #ifdef HAVE_OSF_SIA
                extern char **saved_argv;
                extern int saved_argc;
-               char *host = get_canonical_hostname ();
+               char *host = get_canonical_hostname(options.reverse_mapping_check);
 
                if (sia_become_user(NULL, saved_argc, saved_argv, host,
                    pw->pw_name, ttyname, 0, NULL, NULL, SIA_BEU_SETLUID) !=
diff --git a/sftp-client.c b/sftp-client.c
new file mode 100644 (file)
index 0000000..458d736
--- /dev/null
@@ -0,0 +1,792 @@
+/*
+ * Copyright (c) 2001 Damien Miller.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* XXX: memleaks */
+/* XXX: signed vs unsigned */
+/* XXX: redesign to allow concurrent overlapped operations */
+/* XXX: we use fatal too much, error may be more appropriate in places */
+/* XXX: copy between two remote sites */
+
+#include "includes.h"
+RCSID("$OpenBSD: sftp-client.c,v 1.1 2001/02/04 11:11:54 djm Exp $");
+
+#include "ssh.h"
+#include "buffer.h"
+#include "bufaux.h"
+#include "getput.h"
+#include "xmalloc.h"
+#include "log.h"
+#include "atomicio.h"
+#include "pathnames.h"
+
+#include "sftp.h"
+#include "sftp-common.h"
+#include "sftp-client.h"
+
+/* How much data to read/write at at time during copies */
+/* XXX: what should this be? */
+#define COPY_SIZE      8192
+
+void
+send_msg(int fd, Buffer *m)
+{
+       int mlen = buffer_len(m);
+       int len;
+       Buffer oqueue;
+
+       buffer_init(&oqueue);
+       buffer_put_int(&oqueue, mlen);
+       buffer_append(&oqueue, buffer_ptr(m), mlen);
+       buffer_consume(m, mlen);
+
+       len = atomicio(write, fd, buffer_ptr(&oqueue), buffer_len(&oqueue));
+       if (len <= 0)
+               fatal("Couldn't send packet: %s", strerror(errno));
+
+       buffer_free(&oqueue);
+}
+
+void
+get_msg(int fd, Buffer *m)
+{
+       u_int len, msg_len;
+       unsigned char buf[4096];
+
+       len = atomicio(read, fd, buf, 4);
+       if (len != 4)
+               fatal("Couldn't read packet: %s", strerror(errno));
+
+       msg_len = GET_32BIT(buf);
+       if (msg_len > 256 * 1024)
+               fatal("Received message too long %d", msg_len);
+
+       while (msg_len) {
+               len = atomicio(read, fd, buf, MIN(msg_len, sizeof(buf)));
+               if (len <= 0)
+                       fatal("Couldn't read packet: %s", strerror(errno));
+
+               msg_len -= len;
+               buffer_append(m, buf, len);
+       }
+}
+
+void
+send_string_request(int fd, u_int id, u_int code, char *s,
+    u_int len)
+{
+       Buffer msg;
+
+       buffer_init(&msg);
+       buffer_put_char(&msg, code);
+       buffer_put_int(&msg, id);
+       buffer_put_string(&msg, s, len);
+       send_msg(fd, &msg);
+       debug3("Sent message fd %d T:%d I:%d", fd, code, id);
+       buffer_free(&msg);
+}
+
+void
+send_string_attrs_request(int fd, u_int id, u_int code, char *s,
+    u_int len, Attrib *a)
+{
+       Buffer msg;
+
+       buffer_init(&msg);
+       buffer_put_char(&msg, code);
+       buffer_put_int(&msg, id);
+       buffer_put_string(&msg, s, len);
+       encode_attrib(&msg, a);
+       send_msg(fd, &msg);
+       debug3("Sent message fd %d T:%d I:%d", fd, code, id);
+       buffer_free(&msg);
+}
+
+u_int
+get_status(int fd, int expected_id)
+{
+       Buffer msg;
+       u_int type, id, status;
+
+       buffer_init(&msg);
+       get_msg(fd, &msg);
+       type = buffer_get_char(&msg);
+       id = buffer_get_int(&msg);
+
+       if (id != expected_id)
+               fatal("ID mismatch (%d != %d)", id, expected_id);
+       if (type != SSH2_FXP_STATUS)
+               fatal("Expected SSH2_FXP_STATUS(%d) packet, got %d",
+                   SSH2_FXP_STATUS, type);
+
+       status = buffer_get_int(&msg);
+       buffer_free(&msg);
+
+       debug3("SSH2_FXP_STATUS %d", status);
+
+       return(status);
+}
+
+char *
+get_handle(int fd, u_int expected_id, u_int *len)
+{
+       Buffer msg;
+       u_int type, id;
+       char *handle;
+
+       buffer_init(&msg);
+       get_msg(fd, &msg);
+       type = buffer_get_char(&msg);
+       id = buffer_get_int(&msg);
+
+       if (id != expected_id)
+               fatal("ID mismatch (%d != %d)", id, expected_id);
+       if (type == SSH2_FXP_STATUS) {
+               int status = buffer_get_int(&msg);
+
+               error("Couldn't get handle: %s", fx2txt(status));
+               return(NULL);
+       } else if (type != SSH2_FXP_HANDLE)
+               fatal("Expected SSH2_FXP_HANDLE(%d) packet, got %d",
+                   SSH2_FXP_HANDLE, type);
+
+       handle = buffer_get_string(&msg, len);
+       buffer_free(&msg);
+
+       return(handle);
+}
+
+Attrib *
+get_decode_stat(int fd, u_int expected_id)
+{
+       Buffer msg;
+       u_int type, id;
+       Attrib *a;
+
+       buffer_init(&msg);
+       get_msg(fd, &msg);
+
+       type = buffer_get_char(&msg);
+       id = buffer_get_int(&msg);
+
+       debug3("Received stat reply T:%d I:%d", type, id);
+       if (id != expected_id)
+               fatal("ID mismatch (%d != %d)", id, expected_id);
+       if (type == SSH2_FXP_STATUS) {
+               int status = buffer_get_int(&msg);
+
+               error("Couldn't stat remote file: %s", fx2txt(status));
+               return(NULL);
+       } else if (type != SSH2_FXP_ATTRS) {
+               fatal("Expected SSH2_FXP_ATTRS(%d) packet, got %d",
+                   SSH2_FXP_ATTRS, type);
+       }
+       a = decode_attrib(&msg);
+       buffer_free(&msg);
+
+       return(a);
+}
+
+int
+do_init(int fd_in, int fd_out)
+{
+       int type, version;
+       Buffer msg;
+
+       buffer_init(&msg);
+       buffer_put_char(&msg, SSH2_FXP_INIT);
+       buffer_put_int(&msg, SSH2_FILEXFER_VERSION);
+       send_msg(fd_out, &msg);
+
+       buffer_clear(&msg);
+
+       get_msg(fd_in, &msg);
+
+       /* Expecting a VERSION reply */
+       if ((type = buffer_get_char(&msg)) != SSH2_FXP_VERSION) {
+               error("Invalid packet back from SSH2_FXP_INIT (type %d)",
+                   type);
+               buffer_free(&msg);
+               return(-1);
+       }
+       version = buffer_get_int(&msg);
+
+       debug2("Remote version: %d", version);
+
+       /* Check for extensions */
+       while (buffer_len(&msg) > 0) {
+               char *name = buffer_get_string(&msg, NULL);
+               char *value = buffer_get_string(&msg, NULL);
+
+               debug2("Init extension: \"%s\"", name);
+               xfree(name);
+               xfree(value);
+       }
+
+       buffer_free(&msg);
+       return(0);
+}
+
+int
+do_close(int fd_in, int fd_out, char *handle, u_int handle_len)
+{
+       u_int id, status;
+       Buffer msg;
+
+       buffer_init(&msg);
+
+       id = arc4random();
+       buffer_put_char(&msg, SSH2_FXP_CLOSE);
+       buffer_put_int(&msg, id);
+       buffer_put_string(&msg, handle, handle_len);
+       send_msg(fd_out, &msg);
+       debug3("Sent message SSH2_FXP_CLOSE I:%d", id);
+
+       status = get_status(fd_in, id);
+       if (status != SSH2_FX_OK)
+               error("Couldn't close file: %s", fx2txt(status));
+
+       buffer_free(&msg);
+
+       return(status);
+}
+
+int
+do_ls(int fd_in, int fd_out, char *path)
+{
+       Buffer msg;
+       u_int type, id, handle_len, i, expected_id;
+       char *handle;
+
+       id = arc4random();
+
+       buffer_init(&msg);
+       buffer_put_char(&msg, SSH2_FXP_OPENDIR);
+       buffer_put_int(&msg, id);
+       buffer_put_cstring(&msg, path);
+       send_msg(fd_out, &msg);
+
+       buffer_clear(&msg);
+
+       handle = get_handle(fd_in, id, &handle_len);
+       if (handle == NULL)
+               return(-1);
+
+       for(;;) {
+               int count;
+
+               expected_id = ++id;
+
+               debug3("Sending SSH2_FXP_READDIR I:%d", id);
+
+               buffer_clear(&msg);
+               buffer_put_char(&msg, SSH2_FXP_READDIR);
+               buffer_put_int(&msg, id);
+               buffer_put_string(&msg, handle, handle_len);
+               send_msg(fd_out, &msg);
+
+               buffer_clear(&msg);
+
+               get_msg(fd_in, &msg);
+
+               type = buffer_get_char(&msg);
+               id = buffer_get_int(&msg);
+
+               debug3("Received reply T:%d I:%d", type, id);
+
+               if (id != expected_id)
+                       fatal("ID mismatch (%d != %d)", id, expected_id);
+
+               if (type == SSH2_FXP_STATUS) {
+                       int status = buffer_get_int(&msg);
+
+                       debug3("Received SSH2_FXP_STATUS %d", status);
+
+                       if (status == SSH2_FX_EOF) {
+                               break;
+                       } else {
+                               error("Couldn't read directory: %s",
+                                   fx2txt(status));
+                               do_close(fd_in, fd_out, handle, handle_len);
+                               return(NULL);
+                       }
+               } else if (type != SSH2_FXP_NAME)
+                       fatal("Expected SSH2_FXP_NAME(%d) packet, got %d",
+                           SSH2_FXP_NAME, type);
+
+               count = buffer_get_int(&msg);
+               debug3("Received %i SSH2_FXP_NAME responses", count);
+               for(i = 0; i < count; i++) {
+                       char *filename, *longname;
+                       Attrib *a;
+
+                       filename = buffer_get_string(&msg, NULL);
+                       longname = buffer_get_string(&msg, NULL);
+                       a = decode_attrib(&msg);
+
+                       printf("%s\n", longname);
+
+                       xfree(filename);
+                       xfree(longname);
+               }
+       }
+
+       buffer_free(&msg);
+       do_close(fd_in, fd_out, handle, handle_len);
+       xfree(handle);
+
+       return(0);
+}
+
+int
+do_rm(int fd_in, int fd_out, char *path)
+{
+       u_int status, id;
+
+       debug2("Sending SSH2_FXP_REMOVE \"%s\"", path);
+
+       id = arc4random();
+       send_string_request(fd_out, id, SSH2_FXP_REMOVE, path, strlen(path));
+       status = get_status(fd_in, id);
+       if (status != SSH2_FX_OK)
+               error("Couldn't delete file: %s", fx2txt(status));
+       return(status);
+}
+
+int
+do_mkdir(int fd_in, int fd_out, char *path, Attrib *a)
+{
+       u_int status, id;
+
+       id = arc4random();
+       send_string_attrs_request(fd_out, id, SSH2_FXP_MKDIR, path,
+           strlen(path), a);
+
+       status = get_status(fd_in, id);
+       if (status != SSH2_FX_OK)
+               error("Couldn't create directory: %s", fx2txt(status));
+
+       return(status);
+}
+
+int
+do_rmdir(int fd_in, int fd_out, char *path)
+{
+       u_int status, id;
+
+       id = arc4random();
+       send_string_request(fd_out, id, SSH2_FXP_RMDIR, path, strlen(path));
+
+       status = get_status(fd_in, id);
+       if (status != SSH2_FX_OK)
+               error("Couldn't remove directory: %s", fx2txt(status));
+
+       return(status);
+}
+
+Attrib *
+do_stat(int fd_in, int fd_out, char *path)
+{
+       u_int id;
+
+       id = arc4random();
+       send_string_request(fd_out, id, SSH2_FXP_STAT, path, strlen(path));
+       return(get_decode_stat(fd_in, id));
+}
+
+Attrib *
+do_lstat(int fd_in, int fd_out, char *path)
+{
+       u_int id;
+
+       id = arc4random();
+       send_string_request(fd_out, id, SSH2_FXP_LSTAT, path, strlen(path));
+       return(get_decode_stat(fd_in, id));
+}
+
+Attrib *
+do_fstat(int fd_in, int fd_out, char *handle,
+    u_int handle_len)
+{
+       u_int id;
+
+       id = arc4random();
+       send_string_request(fd_out, id, SSH2_FXP_FSTAT, handle, handle_len);
+       return(get_decode_stat(fd_in, id));
+}
+
+int
+do_setstat(int fd_in, int fd_out, char *path, Attrib *a)
+{
+       u_int status, id;
+
+       id = arc4random();
+       send_string_attrs_request(fd_out, id, SSH2_FXP_SETSTAT, path,
+           strlen(path), a);
+
+       status = get_status(fd_in, id);
+       if (status != SSH2_FX_OK)
+               error("Couldn't setstat on \"%s\": %s", path,
+                   fx2txt(status));
+
+       return(status);
+}
+
+int
+do_fsetstat(int fd_in, int fd_out, char *handle, u_int handle_len,
+    Attrib *a)
+{
+       u_int status, id;
+
+       id = arc4random();
+       send_string_attrs_request(fd_out, id, SSH2_FXP_FSETSTAT, handle,
+           handle_len, a);
+
+       status = get_status(fd_in, id);
+       if (status != SSH2_FX_OK)
+               error("Couldn't fsetstat: %s", fx2txt(status));
+
+       return(status);
+}
+
+char *
+do_realpath(int fd_in, int fd_out, char *path)
+{
+       Buffer msg;
+       u_int type, expected_id, count, id;
+       char *filename, *longname;
+       Attrib *a;
+
+       expected_id = id = arc4random();
+       send_string_request(fd_out, id, SSH2_FXP_REALPATH, path,
+           strlen(path));
+
+       buffer_init(&msg);
+
+       get_msg(fd_in, &msg);
+       type = buffer_get_char(&msg);
+       id = buffer_get_int(&msg);
+
+       if (id != expected_id)
+               fatal("ID mismatch (%d != %d)", id, expected_id);
+
+       if (type == SSH2_FXP_STATUS) {
+               u_int status = buffer_get_int(&msg);
+
+               error("Couldn't canonicalise: %s", fx2txt(status));
+               return(NULL);
+       } else if (type != SSH2_FXP_NAME)
+               fatal("Expected SSH2_FXP_NAME(%d) packet, got %d",
+                   SSH2_FXP_NAME, type);
+
+       count = buffer_get_int(&msg);
+       if (count != 1)
+               fatal("Got multiple names (%d) from SSH_FXP_REALPATH", count);
+
+       filename = buffer_get_string(&msg, NULL);
+       longname = buffer_get_string(&msg, NULL);
+       a = decode_attrib(&msg);
+
+       debug3("SSH_FXP_REALPATH %s -> %s", path, filename);
+
+       xfree(longname);
+
+       buffer_free(&msg);
+
+       return(filename);
+}
+
+int
+do_rename(int fd_in, int fd_out, char *oldpath, char *newpath)
+{
+       Buffer msg;
+       u_int status, id;
+
+       buffer_init(&msg);
+
+       /* Send rename request */
+       id = arc4random();
+       buffer_put_char(&msg, SSH2_FXP_RENAME);
+       buffer_put_int(&msg, id);
+       buffer_put_cstring(&msg, oldpath);
+       buffer_put_cstring(&msg, newpath);
+       send_msg(fd_out, &msg);
+       debug3("Sent message SSH2_FXP_RENAME \"%s\" -> \"%s\"", oldpath,
+           newpath);
+       buffer_free(&msg);
+
+       status = get_status(fd_in, id);
+       if (status != SSH2_FX_OK)
+               error("Couldn't rename file \"%s\" to \"%s\": %s", oldpath, newpath,
+                   fx2txt(status));
+
+       return(status);
+}
+
+int
+do_download(int fd_in, int fd_out, char *remote_path, char *local_path,
+    int pflag)
+{
+       int local_fd;
+       u_int expected_id, handle_len, mode, type, id;
+       u_int64_t offset;
+       char *handle;
+       Buffer msg;
+       Attrib junk, *a;
+
+       a = do_stat(fd_in, fd_out, remote_path);
+       if (a == NULL)
+               return(-1);
+
+       /* XXX: should we preserve set[ug]id? */
+       if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)
+               mode = S_IWRITE | (a->perm & 0777);
+       else
+               mode = 0666;
+
+       local_fd = open(local_path, O_WRONLY | O_CREAT | O_TRUNC, mode);
+       if (local_fd == -1) {
+               error("Couldn't open local file \"%s\" for writing: %s",
+                   local_path, strerror(errno));
+               return(errno);
+       }
+
+       /* Override umask and utimes if asked */
+       if (pflag && fchmod(local_fd, mode) == -1)
+               error("Couldn't set mode on \"%s\": %s", local_path,
+                   strerror(errno));
+       if (pflag && (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME)) {
+               struct timeval tv;
+
+               tv.tv_sec = a->atime;
+               tv.tv_usec = a->mtime;
+               if (utimes(local_path, &tv) == -1)
+                       error("Can't set times on \"%s\": %s", local_path,
+                           strerror(errno));
+       }
+
+       buffer_init(&msg);
+
+       /* Send open request */
+       id = arc4random();
+       buffer_put_char(&msg, SSH2_FXP_OPEN);
+       buffer_put_int(&msg, id);
+       buffer_put_cstring(&msg, remote_path);
+       buffer_put_int(&msg, SSH2_FXF_READ);
+       attrib_clear(&junk); /* Send empty attributes */
+       encode_attrib(&msg, &junk);
+       send_msg(fd_out, &msg);
+       debug3("Sent message SSH2_FXP_OPEN I:%d P:%s", id, remote_path);
+
+       handle = get_handle(fd_in, id, &handle_len);
+       if (handle == NULL) {
+               buffer_free(&msg);
+               close(local_fd);
+               return(-1);
+       }
+
+       /* Read from remote and write to local */
+       offset = 0;
+       for(;;) {
+               u_int len;
+               char *data;
+
+               expected_id = ++id;
+
+               buffer_clear(&msg);
+               buffer_put_char(&msg, SSH2_FXP_READ);
+               buffer_put_int(&msg, id);
+               buffer_put_string(&msg, handle, handle_len);
+               buffer_put_int64(&msg, offset);
+               buffer_put_int(&msg, COPY_SIZE);
+               send_msg(fd_out, &msg);
+               debug3("Sent message SSH2_FXP_READ I:%d O:%llu S:%u",
+                   id, offset, COPY_SIZE);
+
+               buffer_clear(&msg);
+
+               get_msg(fd_in, &msg);
+               type = buffer_get_char(&msg);
+               id = buffer_get_int(&msg);
+               debug3("Received reply T:%d I:%d", type, id);
+               if (id != expected_id)
+                       fatal("ID mismatch (%d != %d)", id, expected_id);
+               if (type == SSH2_FXP_STATUS) {
+                       int status = buffer_get_int(&msg);
+
+                       if (status == SSH2_FX_EOF)
+                               break;
+                       else {
+                               error("Couldn't read from remote "
+                                   "file \"%s\" : %s", remote_path,
+                                    fx2txt(status));
+                               do_close(fd_in, fd_out, handle, handle_len);
+                               xfree(handle);
+                               close(local_fd);
+                               buffer_free(&msg);
+                               return(status);
+                       }
+               } else if (type != SSH2_FXP_DATA) {
+                       fatal("Expected SSH2_FXP_DATA(%d) packet, got %d",
+                           SSH2_FXP_DATA, type);
+               }
+
+               data = buffer_get_string(&msg, &len);
+               if (len > COPY_SIZE)
+                       fatal("Received more data than asked for %d > %d",
+                           len, COPY_SIZE);
+
+               debug3("In read loop, got %d offset %lld", len, offset);
+               if (atomicio(write, local_fd, data, len) != len) {
+                       error("Couldn't write to \"%s\": %s", local_path,
+                           strerror(errno));
+                       do_close(fd_in, fd_out, handle, handle_len);
+                       xfree(handle);
+                       close(local_fd);
+                       xfree(data);
+                       buffer_free(&msg);
+                       return(-1);
+               }
+
+               offset += len;
+               xfree(data);
+       }
+       xfree(handle);
+       buffer_free(&msg);
+       close(local_fd);
+
+       return(do_close(fd_in, fd_out, handle, handle_len));
+}
+
+int
+do_upload(int fd_in, int fd_out, char *local_path, char *remote_path,
+    int pflag)
+{
+       int local_fd;
+       u_int handle_len, id;
+       u_int64_t offset;
+       char *handle;
+       Buffer msg;
+       struct stat sb;
+       Attrib a;
+
+       if ((local_fd = open(local_path, O_RDONLY, 0)) == -1) {
+               error("Couldn't open local file \"%s\" for reading: %s",
+                   local_path, strerror(errno));
+               return(-1);
+       }
+       if (fstat(local_fd, &sb) == -1) {
+               error("Couldn't fstat local file \"%s\": %s",
+                   local_path, strerror(errno));
+               close(local_fd);
+               return(-1);
+       }
+       stat_to_attrib(&sb, &a);
+
+       a.flags &= ~SSH2_FILEXFER_ATTR_SIZE;
+       a.flags &= ~SSH2_FILEXFER_ATTR_UIDGID;
+       a.perm &= 0777;
+       if (!pflag)
+               a.flags &= ~SSH2_FILEXFER_ATTR_ACMODTIME;
+
+       buffer_init(&msg);
+
+       /* Send open request */
+       id = arc4random();
+       buffer_put_char(&msg, SSH2_FXP_OPEN);
+       buffer_put_int(&msg, id);
+       buffer_put_cstring(&msg, remote_path);
+       buffer_put_int(&msg, SSH2_FXF_WRITE|SSH2_FXF_CREAT|SSH2_FXF_TRUNC);
+       encode_attrib(&msg, &a);
+       send_msg(fd_out, &msg);
+       debug3("Sent message SSH2_FXP_OPEN I:%d P:%s", id, remote_path);
+
+       buffer_clear(&msg);
+
+       handle = get_handle(fd_in, id, &handle_len);
+       if (handle == NULL) {
+               close(local_fd);
+               buffer_free(&msg);
+               return(-1);
+       }
+
+       /* Override umask and utimes if asked */
+       if (pflag)
+               do_fsetstat(fd_in, fd_out, handle, handle_len, &a);
+
+       /* Read from local and write to remote */
+       offset = 0;
+       for(;;) {
+               int len;
+               char data[COPY_SIZE];
+               u_int status;
+
+               /*
+                * Can't use atomicio here because it returns 0 on EOF, thus losing
+                * the last block of the file
+                */
+               do
+                       len = read(local_fd, data, COPY_SIZE);
+               while ((len == -1) && (errno == EINTR || errno == EAGAIN));
+
+               if (len == -1)
+                       fatal("Couldn't read from \"%s\": %s", local_path,
+                           strerror(errno));
+               if (len == 0)
+                       break;
+
+               buffer_clear(&msg);
+               buffer_put_char(&msg, SSH2_FXP_WRITE);
+               buffer_put_int(&msg, ++id);
+               buffer_put_string(&msg, handle, handle_len);
+               buffer_put_int64(&msg, offset);
+               buffer_put_string(&msg, data, len);
+               send_msg(fd_out, &msg);
+               debug3("Sent message SSH2_FXP_WRITE I:%d O:%llu S:%u",
+                   id, offset, len);
+
+               status = get_status(fd_in, id);
+               if (status != SSH2_FX_OK) {
+                       error("Couldn't write to remote file \"%s\": %s",
+                           remote_path, fx2txt(status));
+                       do_close(fd_in, fd_out, handle, handle_len);
+                       xfree(handle);
+                       close(local_fd);
+                       return(-1);
+               }
+               debug3("In write loop, got %d offset %lld", len, offset);
+
+               offset += len;
+       }
+       xfree(handle);
+       buffer_free(&msg);
+
+       if (close(local_fd) == -1) {
+               error("Couldn't close local file \"%s\": %s", local_path,
+                   strerror(errno));
+               do_close(fd_in, fd_out, handle, handle_len);
+               return(-1);
+       }
+
+       return(do_close(fd_in, fd_out, handle, handle_len));
+}
diff --git a/sftp-client.h b/sftp-client.h
new file mode 100644 (file)
index 0000000..838b46b
--- /dev/null
@@ -0,0 +1,84 @@
+/* $OpenBSD: sftp-client.h,v 1.1 2001/02/04 11:11:54 djm Exp $ */
+
+/*
+ * Copyright (c) 2001 Damien Miller.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Client side of SSH2 filexfer protocol */
+
+/* Initialiase a SSH filexfer connection */
+int do_init(int fd_in, int fd_out);
+
+/* Close file referred to by 'handle' */
+int do_close(int fd_in, int fd_out, char *handle, u_int handle_len);
+
+/* List contents of directory 'path' to stdout */
+int do_ls(int fd_in, int fd_out, char *path);
+
+/* Delete file 'path' */
+int do_rm(int fd_in, int fd_out, char *path);
+
+/* Create directory 'path' */
+int do_mkdir(int fd_in, int fd_out, char *path, Attrib *a);
+
+/* Remove directory 'path' */
+int do_rmdir(int fd_in, int fd_out, char *path);
+
+/* Get file attributes of 'path' (follows symlinks) */
+Attrib *do_stat(int fd_in, int fd_out, char *path);
+
+/* Get file attributes of 'path' (does not follow symlinks) */
+Attrib *do_lstat(int fd_in, int fd_out, char *path);
+
+/* Get file attributes of open file 'handle' */
+Attrib *do_fstat(int fd_in, int fd_out, char *handle,
+    u_int handle_len);
+
+/* Set file attributes of 'path' */
+int do_setstat(int fd_in, int fd_out, char *path, Attrib *a);
+
+/* Set file attributes of open file 'handle' */
+int do_fsetstat(int fd_in, int fd_out, char *handle,
+    u_int handle_len, Attrib *a);
+
+/* Canonicalise 'path' - caller must free result */
+char *do_realpath(int fd_in, int fd_out, char *path);
+
+/* Rename 'oldpath' to 'newpath' */
+int do_rename(int fd_in, int fd_out, char *oldpath, char *newpath);
+
+/* XXX: add callbacks to do_download/do_upload so we can do progress meter */
+
+/*
+ * Download 'remote_path' to 'local_path'. Preserve permissions and times
+ * if 'pflag' is set
+ */
+int do_download(int fd_in, int fd_out, char *remote_path, char *local_path,
+    int pflag);
+
+/*
+ * Upload 'local_path' to 'remote_path'. Preserve permissions and times
+ * if 'pflag' is set
+ */
+int do_upload(int fd_in, int fd_out, char *local_path, char *remote_path,
+    int pflag);
diff --git a/sftp-common.c b/sftp-common.c
new file mode 100644 (file)
index 0000000..aed9b33
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2001 Markus Friedl.  All rights reserved.
+ * Copyright (c) 2001 Damien Miller.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "includes.h"
+RCSID("$OpenBSD: sftp-common.c,v 1.1 2001/02/04 11:11:54 djm Exp $");
+
+#include "buffer.h"
+#include "bufaux.h"
+#include "getput.h"
+#include "log.h"
+#include "xmalloc.h"
+
+#include "sftp.h"
+#include "sftp-common.h"
+
+void
+attrib_clear(Attrib *a)
+{
+       a->flags = 0;
+       a->size = 0;
+       a->uid = 0;
+       a->gid = 0;
+       a->perm = 0;
+       a->atime = 0;
+       a->mtime = 0;
+}
+
+void
+stat_to_attrib(struct stat *st, Attrib *a)
+{
+       attrib_clear(a);
+       a->flags = 0;
+       a->flags |= SSH2_FILEXFER_ATTR_SIZE;
+       a->size = st->st_size;
+       a->flags |= SSH2_FILEXFER_ATTR_UIDGID;
+       a->uid = st->st_uid;
+       a->gid = st->st_gid;
+       a->flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
+       a->perm = st->st_mode;
+       a->flags |= SSH2_FILEXFER_ATTR_ACMODTIME;
+       a->atime = st->st_atime;
+       a->mtime = st->st_mtime;
+}
+
+Attrib *
+decode_attrib(Buffer *b)
+{
+       static Attrib a;
+       attrib_clear(&a);
+       a.flags = buffer_get_int(b);
+       if (a.flags & SSH2_FILEXFER_ATTR_SIZE)
+               a.size = buffer_get_int64(b);
+       if (a.flags & SSH2_FILEXFER_ATTR_UIDGID) {
+               a.uid = buffer_get_int(b);
+               a.gid = buffer_get_int(b);
+       }
+       if (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS)
+               a.perm = buffer_get_int(b);
+       if (a.flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
+               a.atime = buffer_get_int(b);
+               a.mtime = buffer_get_int(b);
+       }
+       /* vendor-specific extensions */
+       if (a.flags & SSH2_FILEXFER_ATTR_EXTENDED) {
+               char *type, *data;
+               int i, count;
+               count = buffer_get_int(b);
+               for (i = 0; i < count; i++) {
+                       type = buffer_get_string(b, NULL);
+                       data = buffer_get_string(b, NULL);
+                       debug3("Got file attribute \"%s\"", type);
+                       xfree(type);
+                       xfree(data);
+               }
+       }
+       return &a;
+}
+
+void
+encode_attrib(Buffer *b, Attrib *a)
+{
+       buffer_put_int(b, a->flags);
+       if (a->flags & SSH2_FILEXFER_ATTR_SIZE)
+               buffer_put_int64(b, a->size);
+       if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) {
+               buffer_put_int(b, a->uid);
+               buffer_put_int(b, a->gid);
+       }
+       if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)
+               buffer_put_int(b, a->perm);
+       if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
+               buffer_put_int(b, a->atime);
+               buffer_put_int(b, a->mtime);
+       }
+}
+
+const char *
+fx2txt(int status)
+{
+       switch (status) {
+       case SSH2_FX_OK:
+               return("No Error");
+       case SSH2_FX_EOF:
+               return("End of File");
+       case SSH2_FX_NO_SUCH_FILE:
+               return("No Such File");
+       case SSH2_FX_PERMISSION_DENIED:
+               return("Permission Denied");
+       case SSH2_FX_FAILURE:
+               return("Failure");
+       case SSH2_FX_BAD_MESSAGE:
+               return("Bad message");
+       case SSH2_FX_NO_CONNECTION:
+               return("No connection");
+       case SSH2_FX_CONNECTION_LOST:
+               return("Connection lost");
+       case SSH2_FX_OP_UNSUPPORTED:
+               return("Operation unsupported");
+       default:
+               return("Unknown status");
+       };
+       /* NOTREACHED */
+}
+
diff --git a/sftp-common.h b/sftp-common.h
new file mode 100644 (file)
index 0000000..6dc1a32
--- /dev/null
@@ -0,0 +1,55 @@
+/*     $OpenBSD: sftp-common.h,v 1.1 2001/02/04 11:11:54 djm Exp $     */
+
+/*
+ * Copyright (c) 2001 Markus Friedl.  All rights reserved.
+ * Copyright (c) 2001 Damien Miller.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+typedef struct Attrib Attrib;
+
+/* File attributes */
+struct Attrib {
+       u_int32_t       flags;
+       u_int64_t       size;
+       u_int32_t       uid;
+       u_int32_t       gid;
+       u_int32_t       perm;
+       u_int32_t       atime;
+       u_int32_t       mtime;
+};
+
+/* Clear contents of attributes structure */
+void attrib_clear(Attrib *a);
+
+/* Convert from struct stat to filexfer attribs */
+void stat_to_attrib(struct stat *st, Attrib *a);
+
+/* Decode attributes in buffer */
+Attrib *decode_attrib(Buffer *b);
+
+/* Encode attributes to buffer */
+void encode_attrib(Buffer *b, Attrib *a);
+
+/* Convert from SSH2_FX_ status to text error message */
+const char *fx2txt(int status);
+
diff --git a/sftp-int.c b/sftp-int.c
new file mode 100644 (file)
index 0000000..f050c09
--- /dev/null
@@ -0,0 +1,583 @@
+/*
+ * Copyright (c) 2001 Damien Miller.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* XXX: finish implementation of all commands */
+/* XXX: do fnmatch() instead of using raw pathname */
+/* XXX: recursive operations */
+
+#include "includes.h"
+RCSID("$OpenBSD: sftp-int.c,v 1.1 2001/02/04 11:11:54 djm Exp $");
+
+#include "buffer.h"
+#include "xmalloc.h"
+#include "log.h"
+#include "pathnames.h"
+
+#include "sftp.h"
+#include "sftp-common.h"
+#include "sftp-client.h"
+#include "sftp-int.h"
+
+/* Seperators for interactive commands */
+#define WHITESPACE " \t\r\n"
+
+/* Commands for interactive mode */
+#define I_CHDIR                1
+#define I_CHGRP                2
+#define I_CHMOD                3
+#define I_CHOWN                4
+#define I_GET          5
+#define I_HELP         6
+#define I_LCHDIR       7
+#define I_LLS          8
+#define I_LMKDIR       9
+#define I_LPWD         10
+#define I_LS           11
+#define I_LUMASK       12
+#define I_MKDIR                13
+#define I_PUT          14
+#define I_PWD          15
+#define I_QUIT         16
+#define I_RENAME       17
+#define I_RM           18
+#define I_RMDIR                19
+#define I_SHELL                20
+
+struct CMD {
+       const int n;
+       const char *c;
+};
+
+const struct CMD cmds[] = {
+       { I_CHDIR,      "CD" },
+       { I_CHDIR,      "CHDIR" },
+       { I_CHDIR,      "LCD" },
+       { I_CHGRP,      "CHGRP" },
+       { I_CHMOD,      "CHMOD" },
+       { I_CHOWN,      "CHOWN" },
+       { I_HELP,       "HELP" },
+       { I_GET,        "GET" },
+       { I_LCHDIR,     "LCHDIR" },
+       { I_LLS,        "LLS" },
+       { I_LMKDIR,     "LMKDIR" },
+       { I_LPWD,       "LPWD" },
+       { I_LS,         "LS" },
+       { I_LUMASK,     "LUMASK" },
+       { I_MKDIR,      "MKDIR" },
+       { I_PUT,        "PUT" },
+       { I_PWD,        "PWD" },
+       { I_QUIT,       "EXIT" },
+       { I_QUIT,       "QUIT" },
+       { I_RENAME,     "RENAME" },
+       { I_RMDIR,      "RMDIR" },
+       { I_RM,         "RM" },
+       { I_SHELL,      "!" },
+       { -1,           NULL}
+};
+
+void
+help(void)
+{
+       printf("Available commands:\n");
+       printf("CD path                       Change remote directory to 'path'\n");
+       printf("LCD path                      Change local directory to 'path'\n");
+       printf("CHGRP grp path                Change group of file 'path' to 'grp'\n");
+       printf("CHMOD mode path               Change permissions of file 'path' to 'mode'\n");
+       printf("CHOWN own path                Change owner of file 'path' to 'own'\n");
+       printf("HELP                          Display this help text\n");
+       printf("GET remote-path [local-path]  Download file\n");
+       printf("LLS [ls options] [path]       Display local directory listing\n");
+       printf("LMKDIR path                   Create local directory\n");
+       printf("LPWD                          Print local working directory\n");
+       printf("LS [path]                     Display remote directory listing\n");
+       printf("LUMASK umask                  Set local umask to 'umask'\n");
+       printf("MKDIR path                    Create remote directory\n");
+       printf("PUT local-path [remote-path]  Upload file\n");
+       printf("PWD                           Display remote working directory\n");
+       printf("EXIT                          Quit sftp\n");
+       printf("QUIT                          Quit sftp\n");
+       printf("RENAME oldpath newpath        Rename remote file\n");
+       printf("RMDIR path                    Remove remote directory\n");
+       printf("RM path                       Delete remote file\n");
+       printf("!command                      Execute 'command' in local shell\n");
+       printf("!                             Escape to local shell\n");
+}
+
+void
+local_do_shell(const char *args)
+{
+       int ret, status;
+       char *shell;
+       pid_t pid;
+       
+       if (!*args)
+               args = NULL;
+       
+       if ((shell = getenv("SHELL")) == NULL)
+               shell = _PATH_BSHELL;
+
+       if ((pid = fork()) == -1)
+               fatal("Couldn't fork: %s", strerror(errno));
+
+       if (pid == 0) {
+               /* XXX: child has pipe fds to ssh subproc open - issue? */
+               if (args) {
+                       debug3("Executing %s -c \"%s\"", shell, args);
+                       ret = execl(shell, shell, "-c", args, NULL);
+               } else {
+                       debug3("Executing %s", shell);
+                       ret = execl(shell, shell, NULL);
+               }
+               fprintf(stderr, "Couldn't execute \"%s\": %s\n", shell, 
+                   strerror(errno));
+               _exit(1);
+       }
+       if (waitpid(pid, &status, 0) == -1)
+               fatal("Couldn't wait for child: %s", strerror(errno));
+       if (!WIFEXITED(status))
+               error("Shell exited abormally");
+       else if (WEXITSTATUS(status))
+               error("Shell exited with status %d", WEXITSTATUS(status));
+}
+
+void 
+local_do_ls(const char *args)
+{
+       if (!args || !*args)
+               local_do_shell("ls");
+       else {
+               char *buf = xmalloc(8 + strlen(args) + 1);
+
+               /* XXX: quoting - rip quoting code from ftp? */
+               sprintf(buf, "/bin/ls %s", args);
+               local_do_shell(buf);
+       }
+}
+
+char *
+make_absolute(char *p, char *pwd)
+{
+       char buf[2048];
+
+       /* Derelativise */
+       if (p && p[0] != '/') {
+               snprintf(buf, sizeof(buf), "%s/%s", pwd, p);
+               xfree(p);
+               p = xstrdup(buf);
+       }
+
+       return(p);
+}
+
+int
+parse_getput_flags(const char **cpp, int *pflag)
+{
+       const char *cp = *cpp;
+
+       /* Check for flags */
+       if (cp[0] == '-' && cp[1] && strchr(WHITESPACE, cp[2])) {
+               switch (*cp) {
+               case 'P':
+                       *pflag = 1;
+                       break;
+               default:
+                       error("Invalid flag -%c", *cp);
+                       return(-1);
+               }
+               cp += 2;
+               *cpp = cp + strspn(cp, WHITESPACE);
+       }
+
+       return(0);
+}
+
+int
+get_pathname(const char **cpp, char **path)
+{
+       const char *quot, *cp = *cpp;
+       int i;
+
+       cp += strspn(cp, WHITESPACE);
+       if (!*cp) {
+               *cpp = cp;
+               *path = NULL;
+               return(0);
+       }
+
+       /* Check for quoted filenames */
+       if (*cp == '\"' || *cp == '\'') {
+               quot = cp++;
+               for(i = 0; cp[i] && cp[i] != *quot; i++)
+                       ;
+               if (!cp[i]) {
+                       error("Unterminated quote");
+                       *path = NULL;
+                       return(-1);
+               }
+               if (i == 0) {
+                       error("Empty quotes");
+                       *path = NULL;
+                       return(-1);
+               }
+               *path = xmalloc(i + 1);
+               memcpy(*path, cp, i);
+               (*path)[i] = '\0';
+               cp += i + 1;
+               *cpp = cp + strspn(cp, WHITESPACE);
+               return(0);
+       }
+
+       /* Read to end of filename */
+       for(i = 0; cp[i] && cp[i] != ' '; i++)
+               ;
+
+       *path = xmalloc(i + 1);
+       memcpy(*path, cp, i);
+       (*path)[i] = '\0';
+       cp += i;
+       *cpp = cp + strspn(cp, WHITESPACE);
+
+       return(0);
+}
+
+int
+infer_path(const char *p, char **ifp)
+{
+       char *cp;
+
+       debug("XXX: P = \"%s\"", p);
+
+       cp = strrchr(p, '/');
+
+       if (cp == NULL) {
+               *ifp = xstrdup(p);
+               return(0);
+       }
+
+       if (!cp[1]) {
+               error("Invalid path");
+               return(-1);
+       }
+
+       *ifp = xstrdup(cp + 1);
+       return(0);
+}
+
+int
+parse_args(const char **cpp, int *pflag, unsigned long *n_arg,
+    char **path1, char **path2)
+{
+       const char *cmd, *cp = *cpp;
+       int i, cmdnum;
+
+       /* Skip leading whitespace */
+       cp = cp + strspn(cp, WHITESPACE);
+
+       /* Ignore blank lines */
+       if (!*cp)
+               return(-1);
+
+       /* Figure out which command we have */
+       for(i = 0; cmds[i].c; i++) {
+               int cmdlen = strlen(cmds[i].c);
+
+               /* Check for command followed by whitespace */
+               if (!strncasecmp(cp, cmds[i].c, cmdlen) &&
+                   strchr(WHITESPACE, cp[cmdlen])) {
+                       cp += cmdlen;
+                       cp = cp + strspn(cp, WHITESPACE);
+                       break;
+               }
+       }
+       cmdnum = cmds[i].n;
+       cmd = cmds[i].c;
+
+       /* Special case */
+       if (*cp == '!') {
+               cp++;
+               cmdnum = I_SHELL;
+       } else if (cmdnum == -1) {
+               error("Invalid command.");
+               return(-1);
+       }
+
+       /* Get arguments and parse flags */
+       *pflag = *n_arg = 0;
+       *path1 = *path2 = NULL;
+       switch (cmdnum) {
+       case I_GET:
+       case I_PUT:
+               if (parse_getput_flags(&cp, pflag))
+                       return(-1);
+               /* Get first pathname (mandatory) */
+               if (get_pathname(&cp, path1))
+                       return(-1);
+               if (*path1 == NULL) {
+                       error("You must specify at least one path after a "
+                           "%s command.", cmd);
+                       return(-1);
+               }
+               /* Try to get second pathname (optional) */
+               if (get_pathname(&cp, path2))
+                       return(-1);
+               /* Otherwise try to guess it from first path */
+               if (*path2 == NULL && infer_path(*path1, path2))
+                       return(-1);
+               break;
+       case I_RENAME:
+               /* Get first pathname (mandatory) */
+               if (get_pathname(&cp, path1))
+                       return(-1);
+               if (get_pathname(&cp, path2))
+                       return(-1);
+               if (!*path1 || !*path2) {
+                       error("You must specify two paths after a %s "
+                           "command.", cmd);
+                       return(-1);
+               }
+               break;
+       case I_RM:
+       case I_MKDIR:
+       case I_RMDIR:
+       case I_CHDIR:
+       case I_LCHDIR:
+       case I_LMKDIR:
+               /* Get pathname (mandatory) */
+               if (get_pathname(&cp, path1))
+                       return(-1);
+               if (*path1 == NULL) {
+                       error("You must specify a path after a %s command.", 
+                           cmd);
+                       return(-1);
+               }
+               break;
+       case I_LS:
+               /* Path is optional */
+               if (get_pathname(&cp, path1))
+                       return(-1);
+               break;
+       case I_LLS:
+       case I_SHELL:
+               /* Uses the rest of the line */
+               break;
+       case I_LUMASK:
+       case I_CHMOD:
+       case I_CHOWN:
+       case I_CHGRP:
+               /* Get numeric arg (mandatory) */
+               if (*cp < '0' && *cp > '9') {
+                       error("You must supply a numeric argument "
+                           "to the %s command.", cmd);
+                       return(-1);
+               }
+               *n_arg = strtoul(cp, (char**)&cp, 0);
+               if (!*cp || !strchr(WHITESPACE, *cp)) {
+                       error("You must supply a numeric argument "
+                           "to the %s command.", cmd);
+                       return(-1);
+               }
+               cp += strspn(cp, WHITESPACE);
+
+               /* Get pathname (mandatory) */
+               if (get_pathname(&cp, path1))
+                       return(-1);
+               if (*path1 == NULL) {
+                       error("You must specify a path after a %s command.", 
+                           cmd);
+                       return(-1);
+               }
+               break;
+       case I_QUIT:
+       case I_PWD:
+       case I_LPWD:
+       case I_HELP:
+               break;
+       default:
+               fatal("Command not implemented");
+       }
+
+       *cpp = cp;
+
+       return(cmdnum);
+}
+
+int
+parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
+{
+       char *path1, *path2;
+       int pflag, cmdnum;
+       unsigned long n_arg;
+       Attrib a, *aa;
+       char path_buf[PATH_MAX];
+
+       path1 = path2 = NULL;
+       cmdnum = parse_args(&cmd, &pflag, &n_arg, &path1, &path2);
+
+       /* Perform command */
+       switch (cmdnum) {
+       case -1:
+               break;
+       case I_GET:
+               path1 = make_absolute(path1, *pwd);
+               do_download(in, out, path1, path2, pflag);
+               break;
+       case I_PUT:
+               path2 = make_absolute(path2, *pwd);
+               do_upload(in, out, path1, path2, pflag);
+               break;
+       case I_RENAME:
+               path1 = make_absolute(path1, *pwd);
+               path2 = make_absolute(path2, *pwd);
+               do_rename(in, out, path1, path2);
+               break;
+       case I_RM:
+               path1 = make_absolute(path1, *pwd);
+               do_rm(in, out, path1);
+               break;
+       case I_MKDIR:
+               path1 = make_absolute(path1, *pwd);
+               attrib_clear(&a);
+               a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
+               a.perm = 0777;
+               do_mkdir(in, out, path1, &a);
+               break;
+       case I_RMDIR:
+               path1 = make_absolute(path1, *pwd);
+               do_rmdir(in, out, path1);
+               break;
+       case I_CHDIR:
+               path1 = make_absolute(path1, *pwd);
+               xfree(*pwd);
+               *pwd = do_realpath(in, out, path1);
+               break;
+       case I_LS:
+               path1 = make_absolute(path1, *pwd);
+               do_ls(in, out, path1?path1:*pwd);
+               break;
+       case I_LCHDIR:
+               if (chdir(path1) == -1)
+                       error("Couldn't change local directory to "
+                           "\"%s\": %s", path1, strerror(errno));
+               break;
+       case I_LMKDIR:
+               if (mkdir(path1, 0777) == -1)
+                       error("Couldn't create local directory to "
+                           "\"%s\": %s", path1, strerror(errno));
+               break;
+       case I_LLS:
+               local_do_ls(cmd);
+               break;
+       case I_SHELL:
+               local_do_shell(cmd);
+               break;
+       case I_LUMASK:
+               umask(n_arg);
+               break;
+       case I_CHMOD:
+               path1 = make_absolute(path1, *pwd);
+               attrib_clear(&a);
+               a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
+               a.perm = n_arg;
+               do_setstat(in, out, path1, &a);
+       case I_CHOWN:
+               path1 = make_absolute(path1, *pwd);
+               aa = do_stat(in, out, path1);
+               if (!aa->flags & SSH2_FILEXFER_ATTR_UIDGID) {
+                       error("Can't get current ownership of "
+                           "remote file \"%s\"", path1);
+                       break;
+               }
+               aa->uid = n_arg;
+               do_setstat(in, out, path1, aa);
+               break;
+       case I_CHGRP:
+               path1 = make_absolute(path1, *pwd);
+               aa = do_stat(in, out, path1);
+               if (!aa->flags & SSH2_FILEXFER_ATTR_UIDGID) {
+                       error("Can't get current ownership of "
+                           "remote file \"%s\"", path1);
+                       break;
+               }
+               aa->gid = n_arg;
+               do_setstat(in, out, path1, aa);
+               break;
+       case I_PWD:
+               printf("Remote working directory: %s\n", *pwd);
+               break;
+       case I_LPWD:
+               if (!getcwd(path_buf, sizeof(path_buf)))
+                       error("Couldn't get local cwd: %s\n",
+                           strerror(errno));
+               else
+                       printf("Local working directory: %s\n",
+                           path_buf);
+               break;
+       case I_QUIT:
+               return(-1);
+       case I_HELP:
+               help();
+               break;
+       default:
+               fatal("%d is not implemented", cmdnum);
+       }
+
+       if (path1)
+               xfree(path1);
+       if (path2)
+               xfree(path2);
+
+       return(0);
+}
+
+void
+interactive_loop(int fd_in, int fd_out)
+{
+       char *pwd;
+       char cmd[2048];
+
+       pwd = do_realpath(fd_in, fd_out, ".");
+       if (pwd == NULL)
+               fatal("Need cwd");
+
+       setlinebuf(stdout);
+       setlinebuf(stdin);
+
+       for(;;) {
+               char *cp;
+
+               printf("sftp> ");
+
+               /* XXX: use libedit */
+               if (fgets(cmd, sizeof(cmd), stdin) == NULL) {
+                       printf("\n");
+                       break;
+               }
+               cp = strrchr(cmd, '\n');
+               if (cp)
+                       *cp = '\0';
+               if (parse_dispatch_command(fd_in, fd_out, cmd, &pwd))
+                       break;
+       }
+       xfree(pwd);
+}
diff --git a/sftp-int.h b/sftp-int.h
new file mode 100644 (file)
index 0000000..234d800
--- /dev/null
@@ -0,0 +1,27 @@
+/* $OpenBSD: sftp-int.h,v 1.1 2001/02/04 11:11:54 djm Exp $ */
+
+/*
+ * Copyright (c) 2001 Damien Miller.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+void interactive_loop(int fd_in, int fd_out);
index a3e11ce5b7b852f228f2a5276e9de0795d04bfb0..0e0040094e58f75e7fbc7ba3fa41cf7b3101f829 100644 (file)
@@ -22,7 +22,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include "includes.h"
-RCSID("$OpenBSD: sftp-server.c,v 1.14 2001/01/21 19:05:56 markus Exp $");
+RCSID("$OpenBSD: sftp-server.c,v 1.15 2001/02/04 11:11:54 djm Exp $");
 
 #include "buffer.h"
 #include "bufaux.h"
@@ -31,6 +31,7 @@ RCSID("$OpenBSD: sftp-server.c,v 1.14 2001/01/21 19:05:56 markus Exp $");
 #include "xmalloc.h"
 
 #include "sftp.h"
+#include "sftp-common.h"
 
 /* helper */
 #define get_int64()                    buffer_get_int64(&iqueue);
@@ -50,22 +51,9 @@ Buffer oqueue;
 
 /* portable attibutes, etc. */
 
-typedef struct Attrib Attrib;
 typedef struct Stat Stat;
 
-struct Attrib
-{
-       u_int32_t       flags;
-       u_int64_t       size;
-       u_int32_t       uid;
-       u_int32_t       gid;
-       u_int32_t       perm;
-       u_int32_t       atime;
-       u_int32_t       mtime;
-};
-
-struct Stat
-{
+struct Stat {
        char *name;
        char *long_name;
        Attrib attrib;
@@ -122,90 +110,6 @@ flags_from_portable(int pflags)
        return flags;
 }
 
-void
-attrib_clear(Attrib *a)
-{
-       a->flags = 0;
-       a->size = 0;
-       a->uid = 0;
-       a->gid = 0;
-       a->perm = 0;
-       a->atime = 0;
-       a->mtime = 0;
-}
-
-Attrib *
-decode_attrib(Buffer *b)
-{
-       static Attrib a;
-       attrib_clear(&a);
-       a.flags = buffer_get_int(b);
-       if (a.flags & SSH2_FILEXFER_ATTR_SIZE) {
-               a.size = buffer_get_int64(b);
-       }
-       if (a.flags & SSH2_FILEXFER_ATTR_UIDGID) {
-               a.uid = buffer_get_int(b);
-               a.gid = buffer_get_int(b);
-       }
-       if (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
-               a.perm = buffer_get_int(b);
-       }
-       if (a.flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
-               a.atime = buffer_get_int(b);
-               a.mtime = buffer_get_int(b);
-       }
-       /* vendor-specific extensions */
-       if (a.flags & SSH2_FILEXFER_ATTR_EXTENDED) {
-               char *type, *data;
-               int i, count;
-               count = buffer_get_int(b);
-               for (i = 0; i < count; i++) {
-                       type = buffer_get_string(b, NULL);
-                       data = buffer_get_string(b, NULL);
-                       xfree(type);
-                       xfree(data);
-               }
-       }
-       return &a;
-}
-
-void
-encode_attrib(Buffer *b, Attrib *a)
-{
-       buffer_put_int(b, a->flags);
-       if (a->flags & SSH2_FILEXFER_ATTR_SIZE) {
-               buffer_put_int64(b, a->size);
-       }
-       if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) {
-               buffer_put_int(b, a->uid);
-               buffer_put_int(b, a->gid);
-       }
-       if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
-               buffer_put_int(b, a->perm);
-       }
-       if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
-               buffer_put_int(b, a->atime);
-               buffer_put_int(b, a->mtime);
-       }
-}
-
-void
-stat_to_attrib(struct stat *st, Attrib *a)
-{
-       attrib_clear(a);
-       a->flags = 0;
-       a->flags |= SSH2_FILEXFER_ATTR_SIZE;
-       a->size = st->st_size;
-       a->flags |= SSH2_FILEXFER_ATTR_UIDGID;
-       a->uid = st->st_uid;
-       a->gid = st->st_gid;
-       a->flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
-       a->perm = st->st_mode;
-       a->flags |= SSH2_FILEXFER_ATTR_ACMODTIME;
-       a->atime = st->st_atime;
-       a->mtime = st->st_mtime;
-}
-
 Attrib *
 get_attrib(void)
 {
diff --git a/sftp.1 b/sftp.1
new file mode 100644 (file)
index 0000000..59206b6
--- /dev/null
+++ b/sftp.1
@@ -0,0 +1,156 @@
+.\" $OpenBSD: sftp.1,v 1.1 2001/02/04 11:11:54 djm Exp $
+.\"
+.\" Copyright (c) 2001 Damien Miller. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd Febuary 4, 2001
+.Dt SFTP 1
+.Os
+.Sh NAME
+.Nm sftp
+.Nd Secure file tranfer program
+.Sh SYNOPSIS
+.Nm sftp
+.Op Fl v Li | Fl C
+.Op Fl o Ar ssh_option
+.Op Ar hostname | user@hostname
+.Sh DESCRIPTION
+.Nm
+is an interactive file transfer program, similar to
+.Xr ftp 1 ,
+which performs all operations over an encrypted
+.Xr ssh 1
+transport.
+It may also use many features of ssh, such as public key authentication and
+compression.
+.Nm
+connects and logs into the specified
+.Ar hostname
+then enters an interactive command mode.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl C
+Enables compression (via ssh's 
+.Fl C
+flag)
+.It Fl v
+Raise logging level. This option is also passed to ssh.
+.It Fl o Ar ssh_option
+Specify an option to be directly passed to
+.Xr ssh 1 .
+.El
+.Sh INTERACTIVE COMMANDS
+Once in interactive mode
+.Nm ,
+understands a set of commands similar to those of 
+.Xr ftp 1 .
+Commands are case insensitive.
+.Bl -tag -width Ds
+.It Ic CD Ar path
+Change remote directory to 
+.Ar path
+.It Ic LCD Ar path
+Change local directory to 
+.Ar path
+.It Ic CHGRP Ar grp Ar path
+Change group of file 
+.Ar path to 
+.Ar grp .
+.Ar grp
+must be numeric.
+.It Ic CHMOD Ar mode Ar path
+Change permissions of file 
+.Ar path to 
+.Ar mode
+.It Ic CHOWN Ar own Ar path
+Change owner of file 
+.Ar path to 
+.Ar own .
+.Ar own
+must be a numeric UID.
+.It Ic HELP
+Display help text
+.It Ic GET Ar remote-file Op Ar local-file
+Retrieve the
+.Ar remote-file
+and store it on the local machine.
+If the local
+file name is not specified, it is given the same name it has on the 
+remote machine.
+.It Ic LLS Op Ar ls-options Op Ar path
+Display local directory listing of either 
+.Ar path
+or current directory if
+.Ar path
+was not specified.
+.It Ic LMKDIR Ar path
+Create local directory specified by
+.Ar path
+.It Ic LPWD
+Print local working directory
+.It Ic LS Op Ar path
+Display remote directory listing of either
+.Ar path
+or current directory, is
+.Ar path not specified.
+.It Ic LUMASK Ar umask
+Set local umask to 
+.Ar umask
+.It Ic MKDIR Ar path
+Create remote directory specified by
+.Ar path
+.It Ic PUT local-file Op Ar remote-file
+Upload
+.Ar local-file
+and store it on the remote machine. If the local file name is not specified, 
+it is given the same name it has on the local machine.
+.It Ic PWD
+Display remote working directory
+.It Ic EXIT
+Quit sftp
+.It Ic QUIT
+Quit sftp
+.It Ic RENAME Ar oldpath Ar newpath
+Rename remote file from
+.Ar oldpath
+to
+.Ar newpath
+.It Ic RMDIR Ar path
+Remove remote directory specified by
+.Ar path
+.It Ic RM Ar path
+Delete remote file specified by
+.Ar path
+.It Ic ! Ar command
+Execute 
+.Ar command
+in local shell
+.It Ic !
+Escape to local shell
+.Sh AUTHORS
+Damien Miller <djm@mindrot.org>
+.Sh SEE ALSO
+.Xr ssh 1 ,
+.Xr ssh-add 1 ,
+.Xr ssh-keygen 1 ,
+.Xr sshd 8
diff --git a/sftp.c b/sftp.c
new file mode 100644 (file)
index 0000000..0dca12d
--- /dev/null
+++ b/sftp.c
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2001 Damien Miller.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "includes.h"
+
+RCSID("$OpenBSD: sftp.c,v 1.1 2001/02/04 11:11:54 djm Exp $");
+
+/* XXX: commandline mode */
+/* XXX: copy between two remote hosts (commandline) */
+/* XXX: short-form remote directory listings (like 'ls -C') */
+
+#include "buffer.h"
+#include "xmalloc.h"
+#include "log.h"
+#include "pathnames.h"
+
+#include "sftp.h"
+#include "sftp-common.h"
+#include "sftp-client.h"
+#include "sftp-int.h"
+
+void
+connect_to_server(char **args, int *in, int *out, pid_t *sshpid)
+{
+       int c_in, c_out;
+#ifdef USE_PIPES
+       int pin[2], pout[2];
+       if ((pipe(pin) == -1) || (pipe(pout) == -1))
+               fatal("pipe: %s", strerror(errno));
+       *in = pin[0];
+       *out = pout[1];
+       c_in = pout[0];
+       c_out = pin[1];
+#else /* USE_PIPES */
+       int inout[2];
+       if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) == -1)
+               fatal("socketpair: %s", strerror(errno));
+       *in = *out = inout[0];
+       c_in = c_out = inout[1];
+#endif /* USE_PIPES */
+
+       if ((*sshpid = fork()) == -1)
+               fatal("fork: %s", strerror(errno));
+       else if (*sshpid == 0) {
+               if ((dup2(c_in, STDIN_FILENO) == -1) ||
+                   (dup2(c_out, STDOUT_FILENO) == -1)) {
+                       fprintf(stderr, "dup2: %s\n", strerror(errno));
+                       exit(1);
+               }
+               close(*in);
+               close(*out);
+               close(c_in);
+               close(c_out);
+               execv(_PATH_SSH_PROGRAM, args);
+               fprintf(stderr, "exec: %s", strerror(errno));
+               exit(1);
+       }
+
+       close(c_in);
+       close(c_out);
+}
+
+char **
+make_ssh_args(char *add_arg)
+{
+       static char **args = NULL;
+       static int nargs = 0;
+       char debug_buf[4096];
+       int i;
+
+       /* Init args array */
+       if (args == NULL) {
+               nargs = 4;
+               i = 0;
+               args = xmalloc(sizeof(*args) * nargs);
+               args[i++] = "ssh";
+               args[i++] = "-oProtocol=2";
+               args[i++] = "-s";
+               args[i++] = NULL;
+       }
+
+       /* If asked to add args, then do so and return */
+       if (add_arg) {
+               i = nargs++ - 1;
+               args = xrealloc(args, sizeof(*args) * nargs);
+               args[i++] = add_arg;
+               args[i++] = NULL;
+               return(NULL);
+       }
+
+       /* Otherwise finish up and return the arg array */
+       make_ssh_args("sftp");
+
+       /* XXX: overflow - doesn't grow debug_buf */
+       debug_buf[0] = '\0';
+       for(i = 0; args[i]; i++) {
+               if (i)
+                       strlcat(debug_buf, " ", sizeof(debug_buf));
+
+               strlcat(debug_buf, args[i], sizeof(debug_buf));
+       }
+       debug("SSH args \"%s\"", debug_buf);
+
+       return(args);
+}
+
+void 
+usage(void)
+{
+       fprintf(stderr, "usage: sftp [-vC] [-osshopt=value] [user@]host\n");
+       exit(1);
+}
+
+int 
+main(int argc, char **argv)
+{
+       int in, out, i, debug_level, compress_flag;
+       pid_t sshpid;
+       char *cp;
+       LogLevel ll;
+
+       debug_level = compress_flag = 0;
+       for(i = 1; i < argc && argv[i][0] == '-'; i++) {
+               if (!strcmp(argv[i], "-v"))
+                       debug_level = MIN(3, debug_level + 1);
+               else if (!strcmp(argv[i], "-C"))
+                       compress_flag = 1;
+               else if (!strncmp(argv[i], "-o", 2)) {
+                       make_ssh_args(argv[i]);
+               } else {
+                       fprintf(stderr, "Unknown option \"%s\"\n", argv[i]);
+                       usage();
+               }
+       }
+
+       if (i == argc || argc > (i + 1))
+               usage();
+
+       if ((cp = strchr(argv[i], '@')) == NULL)
+               cp = argv[i];
+       else {
+               *cp = '\0';
+               if (!argv[i][0]) {
+                       fprintf(stderr, "Missing username\n");
+                       usage();
+               }
+               make_ssh_args("-l");
+               make_ssh_args(argv[i]);
+               cp++;
+       }
+
+       if (!*cp) {
+               fprintf(stderr, "Missing hostname\n");
+               usage();
+       }
+
+       /* Set up logging and debug '-d' arguments to ssh */
+       ll = SYSLOG_LEVEL_INFO;
+       switch (debug_level) {
+       case 1:
+               ll = SYSLOG_LEVEL_DEBUG1;
+               make_ssh_args("-v");
+               break;
+       case 2:
+               ll = SYSLOG_LEVEL_DEBUG2;
+               make_ssh_args("-v");
+               make_ssh_args("-v");
+               break;
+       case 3:
+               ll = SYSLOG_LEVEL_DEBUG3;
+               make_ssh_args("-v");
+               make_ssh_args("-v");
+               make_ssh_args("-v");
+               break;
+       }
+
+       if (compress_flag)
+               make_ssh_args("-C");
+
+       log_init(argv[0], ll, SYSLOG_FACILITY_USER, 1);
+
+       make_ssh_args(cp);
+
+       fprintf(stderr, "Connecting to %s...\n", cp);
+
+       connect_to_server(make_ssh_args(NULL), &in, &out, &sshpid);
+
+       do_init(in, out);
+
+       interactive_loop(in, out);
+
+       close(in);
+       close(out);
+
+       if (kill(sshpid, SIGHUP) == -1)
+               fatal("Couldn't terminate ssh process: %s", strerror(errno));
+
+       /* XXX: wait? */
+
+       exit(0);
+}
diff --git a/ssh.1 b/ssh.1
index 6f10436a2c5a4d0441d67082c22994d843807fc0..99fb8c7cd5c33543e56544024f8643ba87a2c452 100644 (file)
--- a/ssh.1
+++ b/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.80 2001/01/29 12:36:10 djm Exp $
+.\" $OpenBSD: ssh.1,v 1.83 2001/02/04 11:11:55 djm Exp $
 .Dd September 25, 1999
 .Dt SSH 1
 .Os
@@ -753,8 +753,8 @@ Specifies a file to use instead of
 .It Cm HostKeyAlias
 Specifies an alias that should be used instead of the
 real host name when looking up or saving the host key
-the kown_hosts files.
-This option is useful for tunneling ssh connection
+in the known_hosts files.
+This option is useful for tunneling ssh connections
 or if you have multiple servers running on a single host.
 .It Cm HostName
 Specifies the real host name to log into.
@@ -914,8 +914,9 @@ RSA authentication will only be
 attempted if the identity file exists, or an authentication agent is
 running.
 Note that this option applies to protocol version 1 only.
-.It Cm SkeyAuthentication
-Specifies whether to use
+.It Cm ChallengeResponseAuthentication
+Specifies whether to use challenge response authentication.
+Currently there is only support for
 .Xr skey 1
 authentication.
 The argument to this keyword must be
@@ -1270,6 +1271,7 @@ protocol versions 1.5 and 2.0.
 .Xr rlogin 1 ,
 .Xr rsh 1 ,
 .Xr scp 1 ,
+.Xr sftp 1 ,
 .Xr ssh-add 1 ,
 .Xr ssh-agent 1 ,
 .Xr ssh-keygen 1 ,
index e7dabbf53d1ff758f115b47249ac1ab8161a88ec..cfaf2313f849dabfcaf772aa57184acba8a751b9 100644 (file)
@@ -1,8 +1,8 @@
-#      $OpenBSD: ssh_config,v 1.7 2001/01/29 01:58:18 niklas Exp $
+#      $OpenBSD: ssh_config,v 1.8 2001/02/02 12:57:51 deraadt Exp $
 
-# This is ssh client systemwide configuration file.  This file provides 
-# defaults for users, and the values can be changed in per-user configuration
-# files or on the command line.
+# This is ssh client systemwide configuration file.  See ssh(1) for more
+# information.  This file provides defaults for users, and the values can
+# be changed in per-user configuration files or on the command line.
 
 # Configuration data is parsed as follows:
 #  1. command line options
index e732806f3ffcd439b16eb3a055ca304c4b4def88..80b769b47deeb471705dc986c9bf177dfa67ce69 100644 (file)
@@ -13,7 +13,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshconnect1.c,v 1.21 2001/01/29 19:47:31 markus Exp $");
+RCSID("$OpenBSD: sshconnect1.c,v 1.22 2001/02/03 10:08:37 markus Exp $");
 
 #include <openssl/bn.h>
 #include <openssl/evp.h>
@@ -399,11 +399,11 @@ try_kerberos_authentication()
        if (stat(tkt_string(), &st) < 0)
                return 0;
 
-       strncpy(inst, (char *) krb_get_phost(get_canonical_hostname()), INST_SZ);
+       strncpy(inst, (char *) krb_get_phost(get_canonical_hostname(1)), INST_SZ);
 
-       realm = (char *) krb_realmofhost(get_canonical_hostname());
+       realm = (char *) krb_realmofhost(get_canonical_hostname(1));
        if (!realm) {
-               debug("Kerberos V4: no realm for %s", get_canonical_hostname());
+               debug("Kerberos V4: no realm for %s", get_canonical_hostname(1));
                return 0;
        }
        /* This can really be anything. */
diff --git a/sshd.8 b/sshd.8
index 1aad0fc88680ced1c6d29c4dccd5ee6fc16c125e..c71ecb2a89495a99c621db9419df3fb4b8e662e1 100644 (file)
--- a/sshd.8
+++ b/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.86 2001/01/28 20:43:25 stevesk Exp $
+.\" $OpenBSD: sshd.8,v 1.90 2001/02/04 11:11:55 djm Exp $
 .Dd September 25, 1999
 .Dt SSHD 8
 .Os
@@ -593,6 +593,14 @@ The default is
 .It Cm RandomSeed
 Obsolete.
 Random number generation uses other techniques.
+.It Cm ReverseMappingCheck
+Specifies whether
+.Nm
+should try to verify the remote host name and check that
+the resolved host name for the remote IP address maps back to the
+very same IP address.
+The default is
+.Dq no .
 .It Cm RhostsAuthentication
 Specifies whether authentication using rhosts or /etc/hosts.equiv
 files is sufficient.
@@ -616,15 +624,15 @@ Note that this option applies to protocol version 1 only.
 .It Cm ServerKeyBits
 Defines the number of bits in the server key.
 The minimum value is 512, and the default is 768.
-.It Cm SkeyAuthentication
+.It Cm ChallengeResponseAuthentication
 Specifies whether
-.Xr skey 1
+challenge reponse
 authentication is allowed.
+Currently there is only support for
+.Xr skey 1
+authentication.
 The default is
 .Dq yes .
-Note that s/key authentication is enabled only if
-.Cm PasswordAuthentication
-is allowed, too.
 .It Cm StrictModes
 Specifies whether
 .Nm
@@ -797,6 +805,9 @@ authentication.
 The command supplied by the user (if any) is ignored.
 The command is run on a pty if the connection requests a pty;
 otherwise it is run without a tty.
+Note that if you want a 8-bit clean channel,
+you must not request a pty or should specify
+.Cm no-pty .
 A quote may be included in the command by quoting it with a backslash.
 This option might be useful
 to restrict certain RSA keys to perform just a specific operation.
@@ -1076,6 +1087,7 @@ Markus Friedl contributed the support for SSH
 protocol versions 1.5 and 2.0.
 .Sh SEE ALSO
 .Xr scp 1 ,
+.Xr sftp 1 ,
 .Xr sftp-server 8 ,
 .Xr ssh 1 ,
 .Xr ssh-add 1 ,
index 25c0ec3f71b2e9a333e9e02c39ee5e92297d6a92..9ba1789a45dba1a64fb6800261218a3737143b66 100644 (file)
@@ -1,6 +1,7 @@
-#      $OpenBSD: sshd_config,v 1.27 2001/01/29 01:58:19 niklas Exp $
+#      $OpenBSD: sshd_config,v 1.30 2001/02/03 10:19:51 markus Exp $
 
-# This is ssh server systemwide configuration file.
+# This is the sshd server system-wide configuration file.  See sshd(8)
+# for more information.
 
 Port 22
 #Protocol 2,1
@@ -39,9 +40,9 @@ RSAAuthentication yes
 # To disable tunneled clear text passwords, change to no here!
 PasswordAuthentication yes
 PermitEmptyPasswords no
+
 # Uncomment to disable s/key passwords 
-#SkeyAuthentication no
-#KbdInteractiveAuthentication yes
+#ChallengeResposeAuthentication no
 
 # To change Kerberos options
 #KerberosAuthentication no
@@ -59,3 +60,4 @@ PermitEmptyPasswords no
 #Subsystem     sftp    /usr/libexec/sftp-server
 #MaxStartups 10:30:60
 #Banner /etc/issue.net
+#ReverseMappingCheck yes
This page took 4.50647 seconds and 5 git commands to generate.