summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog40
-rw-r--r--Makefile.in18
-rw-r--r--README.openssh217
-rw-r--r--authfd.c3
-rw-r--r--configure.in2
-rw-r--r--scp.115
-rw-r--r--scp.c4
-rw-r--r--session.c35
-rw-r--r--sftp-server.833
-rw-r--r--sftp-server.c1078
-rw-r--r--ssh-add.15
-rw-r--r--ssh-agent.c5
-rw-r--r--ssh.14
-rw-r--r--sshd.88
-rw-r--r--sshd_config3
15 files changed, 1222 insertions, 48 deletions
diff --git a/ChangeLog b/ChangeLog
index da17a9c12..9aa9423c8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,43 @@
120000905
2 - (djm) Import OpenBSD CVS changes
3 - markus@cvs.openbsd.org 2000/08/31 15:52:24
4 [Makefile sshd.8 sshd_config sftp-server.8 sftp-server.c]
5 implement a SFTP server. interops with sftp2, scp2 and the windows
6 client from ssh.com
7 - markus@cvs.openbsd.org 2000/08/31 15:56:03
8 [README.openssh2]
9 sync
10 - markus@cvs.openbsd.org 2000/08/31 16:05:42
11 [session.c]
12 Wall
13 - markus@cvs.openbsd.org 2000/08/31 16:09:34
14 [authfd.c ssh-agent.c]
15 add a flag to SSH2_AGENTC_SIGN_REQUEST for future extensions
16 - deraadt@cvs.openbsd.org 2000/09/01 09:25:13
17 [scp.1 scp.c]
18 cleanup and fix -S support; stevesk@sweden.hp.com
19 - markus@cvs.openbsd.org 2000/09/01 16:29:32
20 [sftp-server.c]
21 portability fixes
22 - markus@cvs.openbsd.org 2000/09/01 16:32:41
23 [sftp-server.c]
24 fix cast; mouring@pconline.com
25 - itojun@cvs.openbsd.org 2000/09/03 09:23:28
26 [ssh-add.1 ssh.1]
27 add missing .El against .Bl.
28 - markus@cvs.openbsd.org 2000/09/04 13:03:41
29 [session.c]
30 missing close; ok theo
31 - markus@cvs.openbsd.org 2000/09/04 13:07:21
32 [session.c]
33 fix get_last_login_time order; from andre@van-veen.de
34 - markus@cvs.openbsd.org 2000/09/04 13:10:09
35 [sftp-server.c]
36 more cast fixes; from mouring@pconline.com
37 - markus@cvs.openbsd.org 2000/09/04 13:06:04
38 [session.c]
39 set SSH_ORIGINAL_COMMAND; from Leakin@dfw.nostrum.com, bet@rahul.net
40 - (djm) Cleanup after import. Fix sftp-server compilation, Makefile
120000903 4120000903
2 - (djm) Fix Redhat init script 42 - (djm) Fix Redhat init script
3 43
diff --git a/Makefile.in b/Makefile.in
index 4ceef7043..7eb84ce63 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -15,8 +15,8 @@ DESTDIR=
15VPATH=@srcdir@ 15VPATH=@srcdir@
16 16
17SSH_PROGRAM=@bindir@/ssh 17SSH_PROGRAM=@bindir@/ssh
18ASKPASS_LOCATION=@libexecdir@/ssh 18LIBEXEC=@libexecdir@/ssh
19ASKPASS_PROGRAM=$(ASKPASS_LOCATION)/ssh-askpass 19ASKPASS_PROGRAM=$(LIBEXEC)/ssh-askpass
20 20
21CC=@CC@ 21CC=@CC@
22LD=@LD@ 22LD=@LD@
@@ -32,7 +32,7 @@ LDFLAGS=-L. @LDFLAGS@
32 32
33INSTALL_SSH_PRNG_CMDS=@INSTALL_SSH_PRNG_CMDS@ 33INSTALL_SSH_PRNG_CMDS=@INSTALL_SSH_PRNG_CMDS@
34 34
35TARGETS=ssh sshd ssh-add ssh-keygen ssh-agent scp $(EXTRA_TARGETS) 35TARGETS=ssh sshd ssh-add ssh-keygen ssh-agent scp sftp-server $(EXTRA_TARGETS)
36 36
37LIBSSH_OBJS=atomicio.o authfd.o authfile.o bufaux.o buffer.o canohost.o channels.o cipher.o compat.o compress.o crc32.o deattack.o dispatch.o dsa.o hmac.o hostfile.o key.o kex.o log.o match.o mpaux.o nchan.o packet.o radix.o entropy.o readpass.o rsa.o tildexpand.o ttymodes.o uidswap.o util.o uuencode.o xmalloc.o 37LIBSSH_OBJS=atomicio.o authfd.o authfile.o bufaux.o buffer.o canohost.o channels.o cipher.o compat.o compress.o crc32.o deattack.o dispatch.o dsa.o hmac.o hostfile.o key.o kex.o log.o match.o mpaux.o nchan.o packet.o radix.o entropy.o readpass.o rsa.o tildexpand.o ttymodes.o uidswap.o util.o uuencode.o xmalloc.o
38 38
@@ -42,13 +42,13 @@ SSHOBJS= ssh.o sshconnect.o sshconnect1.o sshconnect2.o log-client.o readconf.o
42 42
43SSHDOBJS= sshd.o auth.o auth1.o auth2.o auth-rhosts.o auth-options.o auth-krb4.o auth-pam.o auth-passwd.o auth-rsa.o auth-rh-rsa.o pty.o log-server.o login.o loginrec.o servconf.o serverloop.o md5crypt.o session.o 43SSHDOBJS= sshd.o auth.o auth1.o auth2.o auth-rhosts.o auth-options.o auth-krb4.o auth-pam.o auth-passwd.o auth-rsa.o auth-rh-rsa.o pty.o log-server.o login.o loginrec.o servconf.o serverloop.o md5crypt.o session.o
44 44
45TROFFMAN = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh.1 sshd.8 45TROFFMAN = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh.1 sshd.8 sftp-server.8
46CATMAN = scp.0 ssh-add.0 ssh-agent.0 ssh-keygen.0 ssh.0 sshd.0 46CATMAN = scp.0 ssh-add.0 ssh-agent.0 ssh-keygen.0 ssh.0 sshd.0 sftp-server.0
47MANPAGES = @MANTYPE@ 47MANPAGES = @MANTYPE@
48 48
49CONFIGFILES=sshd_config ssh_config 49CONFIGFILES=sshd_config ssh_config
50 50
51PATHSUBS = -D/etc/ssh_config=$(sysconfdir)/ssh_config -D/etc/known_hosts=$(sysconfdir)/ssh_known_hosts -D/etc/sshd_config=$(sysconfdir)/sshd_config -D/etc/shosts.equiv=$(sysconfdir)/shosts.equiv -D/etc/ssh_host_key=$(sysconfdir)/ssh_host_key -D/var/run/sshd.pid=$(piddir)/sshd.pid 51PATHSUBS = -D/etc/ssh_config=$(sysconfdir)/ssh_config -D/etc/known_hosts=$(sysconfdir)/ssh_known_hosts -D/etc/sshd_config=$(sysconfdir)/sshd_config -D/usr/libexec=$(LIBEXEC) -D/etc/shosts.equiv=$(sysconfdir)/shosts.equiv -D/etc/ssh_host_key=$(sysconfdir)/ssh_host_key -D/var/run/sshd.pid=$(piddir)/sshd.pid
52 52
53FIXPATHSCMD = $(PERL) $(srcdir)/fixpaths $(PATHSUBS) 53FIXPATHSCMD = $(PERL) $(srcdir)/fixpaths $(PATHSUBS)
54 54
@@ -86,6 +86,9 @@ ssh-agent: libopenbsd-compat.a libssh.a ssh-agent.o log-client.o
86ssh-keygen: libopenbsd-compat.a libssh.a ssh-keygen.o log-client.o 86ssh-keygen: libopenbsd-compat.a libssh.a ssh-keygen.o log-client.o
87 $(LD) -o $@ ssh-keygen.o log-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) 87 $(LD) -o $@ ssh-keygen.o log-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
88 88
89sftp-server: libopenbsd-compat.a libssh.a sftp-server.o log-server.o
90 $(LD) -o $@ sftp-server.o log-server.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
91
89# test driver for the loginrec code - not built by default 92# test driver for the loginrec code - not built by default
90logintest: logintest.o libopenbsd-compat.a libssh.a log-client.o loginrec.o 93logintest: logintest.o libopenbsd-compat.a libssh.a log-client.o loginrec.o
91 $(LD) -o $@ logintest.o $(LDFLAGS) loginrec.o -lopenbsd-compat -lssh log-client.o $(LIBS) 94 $(LD) -o $@ logintest.o $(LDFLAGS) loginrec.o -lopenbsd-compat -lssh log-client.o $(LIBS)
@@ -123,18 +126,21 @@ install-files:
123 ./mkinstalldirs $(DESTDIR)$(mandir) 126 ./mkinstalldirs $(DESTDIR)$(mandir)
124 ./mkinstalldirs $(DESTDIR)$(mandir)/$(mansubdir)1 127 ./mkinstalldirs $(DESTDIR)$(mandir)/$(mansubdir)1
125 ./mkinstalldirs $(DESTDIR)$(mandir)/$(mansubdir)8 128 ./mkinstalldirs $(DESTDIR)$(mandir)/$(mansubdir)8
129 ./mkinstalldirs $(DESTDIR)$(LIBEXEC)
126 $(INSTALL) -m 4755 -s ssh $(DESTDIR)$(bindir)/ssh 130 $(INSTALL) -m 4755 -s ssh $(DESTDIR)$(bindir)/ssh
127 $(INSTALL) -m 0755 -s scp $(DESTDIR)$(bindir)/scp 131 $(INSTALL) -m 0755 -s scp $(DESTDIR)$(bindir)/scp
128 $(INSTALL) -m 0755 -s ssh-add $(DESTDIR)$(bindir)/ssh-add 132 $(INSTALL) -m 0755 -s ssh-add $(DESTDIR)$(bindir)/ssh-add
129 $(INSTALL) -m 0755 -s ssh-agent $(DESTDIR)$(bindir)/ssh-agent 133 $(INSTALL) -m 0755 -s ssh-agent $(DESTDIR)$(bindir)/ssh-agent
130 $(INSTALL) -m 0755 -s ssh-keygen $(DESTDIR)$(bindir)/ssh-keygen 134 $(INSTALL) -m 0755 -s ssh-keygen $(DESTDIR)$(bindir)/ssh-keygen
131 $(INSTALL) -m 0755 -s sshd $(DESTDIR)$(sbindir)/sshd 135 $(INSTALL) -m 0755 -s sshd $(DESTDIR)$(sbindir)/sshd
136 $(INSTALL) -m 0755 -s sftp-server $(DESTDIR)$(LIBEXEC)/sftp-server
132 $(INSTALL) -m 644 ssh.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 137 $(INSTALL) -m 644 ssh.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1
133 $(INSTALL) -m 644 scp.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1 138 $(INSTALL) -m 644 scp.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1
134 $(INSTALL) -m 644 ssh-add.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1 139 $(INSTALL) -m 644 ssh-add.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1
135 $(INSTALL) -m 644 ssh-agent.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-agent.1 140 $(INSTALL) -m 644 ssh-agent.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-agent.1
136 $(INSTALL) -m 644 ssh-keygen.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keygen.1 141 $(INSTALL) -m 644 ssh-keygen.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keygen.1
137 $(INSTALL) -m 644 sshd.[08].out $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8 142 $(INSTALL) -m 644 sshd.[08].out $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8
143 $(INSTALL) -m 644 sftp-server.[08].out $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
138 -rm -f $(DESTDIR)$(bindir)/slogin 144 -rm -f $(DESTDIR)$(bindir)/slogin
139 ln -s ssh $(DESTDIR)$(bindir)/slogin 145 ln -s ssh $(DESTDIR)$(bindir)/slogin
140 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 146 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
diff --git a/README.openssh2 b/README.openssh2
index 12c90aa31..df737c695 100644
--- a/README.openssh2
+++ b/README.openssh2
@@ -1,4 +1,4 @@
1$Id: README.openssh2,v 1.8 2000/05/07 18:30:03 markus Exp $ 1$Id: README.openssh2,v 1.9 2000/08/31 21:56:03 markus Exp $
2 2
3howto: 3howto:
4 1) generate server key: 4 1) generate server key:
@@ -15,30 +15,27 @@ howto:
15 15
16works: 16works:
17 secsh-transport: works w/o rekey 17 secsh-transport: works w/o rekey
18 proposal exchange, i.e. different enc/mac/comp per direction
19 encryption: blowfish-cbc, 3des-cbc, arcfour, cast128-cbc
20 mac: hmac-md5, hmac-sha1, (hmac-ripemd160)
21 compression: zlib, none
22 secsh-userauth: passwd and pubkey with DSA 18 secsh-userauth: passwd and pubkey with DSA
23 secsh-connection: pty+shell or command, flow control works (window adjust) 19 secsh-connection: pty+shell or command, flow control works (window adjust)
24 tcp-forwarding: -L works, -R incomplete 20 tcp-forwarding: -L works, -R incomplete
25 x11-fwd 21 x11-fwd
26 dss/dsa: host key database in ~/.ssh/known_hosts2 22 dss/dsa: host key database in ~/.ssh/known_hosts2
23 ssh-agent: supports SSH1-RSA and ssh-dss keys
27 client interops w/ sshd2, lshd 24 client interops w/ sshd2, lshd
28 server interops w/ ssh2, lsh, ssh.com's Windows client, SecureCRT, F-Secure SSH Client 4.0, SecureFX (secure ftp) 25 server interops w/ ssh2, lsh, ssh.com's Windows client, SecureCRT, F-Secure SSH Client 4.0, SecureFX (secure ftp)
29 server supports multiple concurrent sessions (e.g. with SSH.com Windows client) 26 server supports multiple concurrent sessions (e.g. with SSH.com Windows client)
27 server supports SFTP (interops with ssh.com's windows, sftp2, scp2)
30todo: 28todo:
31 re-keying 29 RE-KEYING
32 secsh-connection features: 30 secsh-connection features:
33 tcp-forwarding, agent-fwd 31 complete tcp-forwarding, agent-fwd
34 auth other than passwd, and DSA-pubkey: 32 auth other than passwd, and DSA-pubkey:
35 keyboard-interactive, (PGP-pubkey?) 33 keyboard-interactive, (PGP-pubkey?), kerberos
36 config 34 config
37 server-auth w/ old host-keys 35 server-auth w/ old host-keys
38 cleanup 36 cleanup
39 advanced key storage? 37 advanced key storage?
40 keynote 38 keynote
41 sftp
42 39
43-markus 40-markus
44$Date: 2000/05/07 18:30:03 $ 41$Date: 2000/08/31 21:56:03 $
diff --git a/authfd.c b/authfd.c
index d9427d377..6c40afc65 100644
--- a/authfd.c
+++ b/authfd.c
@@ -17,7 +17,7 @@
17 */ 17 */
18 18
19#include "includes.h" 19#include "includes.h"
20RCSID("$OpenBSD: authfd.c,v 1.25 2000/08/19 21:34:42 markus Exp $"); 20RCSID("$OpenBSD: authfd.c,v 1.26 2000/08/31 22:09:34 markus Exp $");
21 21
22#include "ssh.h" 22#include "ssh.h"
23#include "rsa.h" 23#include "rsa.h"
@@ -359,6 +359,7 @@ ssh_agent_sign(AuthenticationConnection *auth,
359 buffer_put_char(&msg, SSH2_AGENTC_SIGN_REQUEST); 359 buffer_put_char(&msg, SSH2_AGENTC_SIGN_REQUEST);
360 buffer_put_string(&msg, blob, blen); 360 buffer_put_string(&msg, blob, blen);
361 buffer_put_string(&msg, data, datalen); 361 buffer_put_string(&msg, data, datalen);
362 buffer_put_int(&msg, 0); /* flags, unused */
362 xfree(blob); 363 xfree(blob);
363 364
364 if (ssh_request_reply(auth, &msg, &msg) == 0) { 365 if (ssh_request_reply(auth, &msg, &msg) == 0) {
diff --git a/configure.in b/configure.in
index 33b82895b..b1dd1d067 100644
--- a/configure.in
+++ b/configure.in
@@ -235,7 +235,7 @@ fi
235AC_CHECK_HEADERS(bstring.h endian.h floatingpoint.h lastlog.h limits.h login.h login_cap.h maillock.h netdb.h netgroup.h netinet/in_systm.h paths.h poll.h pty.h shadow.h security/pam_appl.h sys/bitypes.h sys/bsdtty.h sys/cdefs.h sys/poll.h sys/select.h sys/stat.h sys/stropts.h sys/sysmacros.h sys/time.h sys/ttcompat.h stddef.h time.h ttyent.h usersec.h util.h utmp.h utmpx.h) 235AC_CHECK_HEADERS(bstring.h endian.h floatingpoint.h lastlog.h limits.h login.h login_cap.h maillock.h netdb.h netgroup.h netinet/in_systm.h paths.h poll.h pty.h shadow.h security/pam_appl.h sys/bitypes.h sys/bsdtty.h sys/cdefs.h sys/poll.h sys/select.h sys/stat.h sys/stropts.h sys/sysmacros.h sys/time.h sys/ttcompat.h stddef.h time.h ttyent.h usersec.h util.h utmp.h utmpx.h)
236 236
237dnl Checks for library functions. 237dnl Checks for library functions.
238AC_CHECK_FUNCS(arc4random atexit b64_ntop bcopy bindresvport_af clock freeaddrinfo gai_strerror getaddrinfo getnameinfo getrusage getttyent inet_aton inet_ntoa innetgr login_getcapbool md5_crypt memmove mkdtemp on_exit openpty rresvport_af setenv seteuid setlogin setproctitle setreuid sigaction sigvec snprintf strerror strlcat strlcpy strsep vsnprintf vhangup _getpty __b64_ntop) 238AC_CHECK_FUNCS(arc4random atexit b64_ntop bcopy bindresvport_af clock freeaddrinfo futimes gai_strerror getaddrinfo getnameinfo getrusage getttyent inet_aton inet_ntoa innetgr login_getcapbool md5_crypt memmove mkdtemp on_exit openpty rresvport_af setenv seteuid setlogin setproctitle setreuid sigaction sigvec snprintf strerror strlcat strlcpy strsep vsnprintf vhangup _getpty __b64_ntop)
239dnl Checks for time functions 239dnl Checks for time functions
240AC_CHECK_FUNCS(gettimeofday time) 240AC_CHECK_FUNCS(gettimeofday time)
241dnl Checks for libutil functions 241dnl Checks for libutil functions
diff --git a/scp.1 b/scp.1
index b7b247624..51ef34c88 100644
--- a/scp.1
+++ b/scp.1
@@ -9,7 +9,7 @@
9.\" 9.\"
10.\" Created: Sun May 7 00:14:37 1995 ylo 10.\" Created: Sun May 7 00:14:37 1995 ylo
11.\" 11.\"
12.\" $Id: scp.1,v 1.9 2000/08/23 00:46:24 djm Exp $ 12.\" $Id: scp.1,v 1.10 2000/09/05 02:34:54 djm Exp $
13.\" 13.\"
14.Dd September 25, 1999 14.Dd September 25, 1999
15.Dt SCP 1 15.Dt SCP 1
@@ -20,6 +20,7 @@
20.Sh SYNOPSIS 20.Sh SYNOPSIS
21.Nm scp 21.Nm scp
22.Op Fl pqrvC46 22.Op Fl pqrvC46
23.Op Fl S Ar program
23.Op Fl P Ar port 24.Op Fl P Ar port
24.Op Fl c Ar cipher 25.Op Fl c Ar cipher
25.Op Fl i Ar identity_file 26.Op Fl i Ar identity_file
@@ -68,11 +69,6 @@ This option is directly passed to
68.It Fl p 69.It Fl p
69Preserves modification times, access times, and modes from the 70Preserves modification times, access times, and modes from the
70original file. 71original file.
71.It Fl S
72Name of program to use for the encrypted connection.
73The program must understand
74.Xr ssh 1
75options.
76.It Fl r 72.It Fl r
77Recursively copy entire directories. 73Recursively copy entire directories.
78.It Fl v 74.It Fl v
@@ -103,9 +99,10 @@ because
103.Fl p 99.Fl p
104is already reserved for preserving the times and modes of the file in 100is already reserved for preserving the times and modes of the file in
105.Xr rcp 1 . 101.Xr rcp 1 .
106.It Fl S 102.It Fl S Ar program
107Name of program to use for the encrypted connection. The program must 103Name of
108understand 104.Ar program
105to use for the encrypted connection. The program must understand
109.Xr ssh 1 106.Xr ssh 1
110options. 107options.
111.It Fl 4 108.It Fl 4
diff --git a/scp.c b/scp.c
index 3b356a9c0..33bd0a5ff 100644
--- a/scp.c
+++ b/scp.c
@@ -47,7 +47,7 @@
47 */ 47 */
48 48
49#include "includes.h" 49#include "includes.h"
50RCSID("$OpenBSD: scp.c,v 1.36 2000/08/24 21:46:59 deraadt Exp $"); 50RCSID("$OpenBSD: scp.c,v 1.37 2000/09/01 15:25:13 deraadt Exp $");
51 51
52#include "ssh.h" 52#include "ssh.h"
53#include "xmalloc.h" 53#include "xmalloc.h"
@@ -262,7 +262,7 @@ main(argc, argv)
262 extern int optind; 262 extern int optind;
263 263
264 fflag = tflag = 0; 264 fflag = tflag = 0;
265 while ((ch = getopt(argc, argv, "dfprtvBCc:i:P:q46S")) != EOF) 265 while ((ch = getopt(argc, argv, "dfprtvBCc:i:P:q46S:")) != EOF)
266 switch (ch) { 266 switch (ch) {
267 /* User-visible flags. */ 267 /* User-visible flags. */
268 case '4': 268 case '4':
diff --git a/session.c b/session.c
index 3678b8f09..d5faf4cf3 100644
--- a/session.c
+++ b/session.c
@@ -8,7 +8,7 @@
8 */ 8 */
9 9
10#include "includes.h" 10#include "includes.h"
11RCSID("$OpenBSD: session.c,v 1.31 2000/08/28 03:50:54 deraadt Exp $"); 11RCSID("$OpenBSD: session.c,v 1.35 2000/09/04 19:07:21 markus Exp $");
12 12
13#include "xmalloc.h" 13#include "xmalloc.h"
14#include "ssh.h" 14#include "ssh.h"
@@ -113,6 +113,9 @@ extern int startup_pipe;
113/* Local Xauthority file. */ 113/* Local Xauthority file. */
114static char *xauthfile; 114static char *xauthfile;
115 115
116/* original command from peer. */
117char *original_command = NULL;
118
116/* data */ 119/* data */
117#define MAX_SESSIONS 10 120#define MAX_SESSIONS 10
118Session sessions[MAX_SESSIONS]; 121Session sessions[MAX_SESSIONS];
@@ -177,7 +180,7 @@ void
177do_authenticated(struct passwd * pw) 180do_authenticated(struct passwd * pw)
178{ 181{
179 Session *s; 182 Session *s;
180 int type; 183 int type, fd;
181 int compression_level = 0, enable_compression_after_reply = 0; 184 int compression_level = 0, enable_compression_after_reply = 0;
182 int have_pty = 0; 185 int have_pty = 0;
183 char *command; 186 char *command;
@@ -332,7 +335,9 @@ do_authenticated(struct passwd * pw)
332 break; 335 break;
333 } 336 }
334 strlcat(xauthfile, "/cookies", MAXPATHLEN); 337 strlcat(xauthfile, "/cookies", MAXPATHLEN);
335 open(xauthfile, O_RDWR|O_CREAT|O_EXCL, 0600); 338 fd = open(xauthfile, O_RDWR|O_CREAT|O_EXCL, 0600);
339 if (fd >= 0)
340 close(fd);
336 restore_uid(); 341 restore_uid();
337 fatal_add_cleanup(xauthfile_cleanup_proc, NULL); 342 fatal_add_cleanup(xauthfile_cleanup_proc, NULL);
338 success = 1; 343 success = 1;
@@ -377,6 +382,7 @@ do_authenticated(struct passwd * pw)
377 packet_integrity_check(plen, 0, type); 382 packet_integrity_check(plen, 0, type);
378 } 383 }
379 if (forced_command != NULL) { 384 if (forced_command != NULL) {
385 original_command = command;
380 command = forced_command; 386 command = forced_command;
381 debug("Forced command '%.500s'", forced_command); 387 debug("Forced command '%.500s'", forced_command);
382 } 388 }
@@ -638,6 +644,7 @@ do_login(Session *s)
638 FILE *f; 644 FILE *f;
639 char *time_string; 645 char *time_string;
640 char buf[256]; 646 char buf[256];
647 char hostname[MAXHOSTNAMELEN];
641 socklen_t fromlen; 648 socklen_t fromlen;
642 struct sockaddr_storage from; 649 struct sockaddr_storage from;
643 struct stat st; 650 struct stat st;
@@ -659,6 +666,10 @@ do_login(Session *s)
659 } 666 }
660 } 667 }
661 668
669 /* Get the time and hostname when the user last logged in. */
670 last_login_time = get_last_login_time(pw->pw_uid, pw->pw_name,
671 hostname, sizeof(hostname));
672
662 /* Record that there was a login on that tty from the remote host. */ 673 /* Record that there was a login on that tty from the remote host. */
663 record_login(pid, s->tty, pw->pw_name, pw->pw_uid, 674 record_login(pid, s->tty, pw->pw_name, pw->pw_uid,
664 get_remote_name_or_ip(), (struct sockaddr *)&from); 675 get_remote_name_or_ip(), (struct sockaddr *)&from);
@@ -680,12 +691,6 @@ do_login(Session *s)
680 printf("%s\n", aixloginmsg); 691 printf("%s\n", aixloginmsg);
681#endif /* WITH_AIXAUTHENTICATE */ 692#endif /* WITH_AIXAUTHENTICATE */
682 693
683 /*
684 * Get the time when the user last logged in. 'buf' will be set
685 * to contain the hostname the last login was from.
686 */
687 last_login_time = get_last_login_time(pw->pw_uid, pw->pw_name,
688 buf, sizeof(buf));
689 if (last_login_time != 0) { 694 if (last_login_time != 0) {
690 time_string = ctime(&last_login_time); 695 time_string = ctime(&last_login_time);
691 if (strchr(time_string, '\n')) 696 if (strchr(time_string, '\n'))
@@ -911,7 +916,7 @@ do_child(const char *command, struct passwd * pw, const char *term,
911 const char *display, const char *auth_proto, 916 const char *display, const char *auth_proto,
912 const char *auth_data, const char *ttyname) 917 const char *auth_data, const char *ttyname)
913{ 918{
914 const char *shell, *hostname, *cp = NULL; 919 const char *shell, *hostname = NULL, *cp = NULL;
915 char buf[256]; 920 char buf[256];
916 char cmd[1024]; 921 char cmd[1024];
917 FILE *f = NULL; 922 FILE *f = NULL;
@@ -1089,6 +1094,9 @@ do_child(const char *command, struct passwd * pw, const char *term,
1089 child_set_env(&env, &envsize, "TERM", term); 1094 child_set_env(&env, &envsize, "TERM", term);
1090 if (display) 1095 if (display)
1091 child_set_env(&env, &envsize, "DISPLAY", display); 1096 child_set_env(&env, &envsize, "DISPLAY", display);
1097 if (original_command)
1098 child_set_env(&env, &envsize, "SSH_ORIGINAL_COMMAND",
1099 original_command);
1092 1100
1093#ifdef _AIX 1101#ifdef _AIX
1094 { 1102 {
@@ -1511,6 +1519,7 @@ session_subsystem_req(Session *s)
1511int 1519int
1512session_x11_req(Session *s) 1520session_x11_req(Session *s)
1513{ 1521{
1522 int fd;
1514 if (no_x11_forwarding_flag) { 1523 if (no_x11_forwarding_flag) {
1515 debug("X11 forwarding disabled in user configuration file."); 1524 debug("X11 forwarding disabled in user configuration file.");
1516 return 0; 1525 return 0;
@@ -1555,7 +1564,9 @@ session_x11_req(Session *s)
1555 return 0; 1564 return 0;
1556 } 1565 }
1557 strlcat(xauthfile, "/cookies", MAXPATHLEN); 1566 strlcat(xauthfile, "/cookies", MAXPATHLEN);
1558 open(xauthfile, O_RDWR|O_CREAT|O_EXCL, 0600); 1567 fd = open(xauthfile, O_RDWR|O_CREAT|O_EXCL, 0600);
1568 if (fd >= 0)
1569 close(fd);
1559 restore_uid(); 1570 restore_uid();
1560 fatal_add_cleanup(xauthfile_cleanup_proc, s); 1571 fatal_add_cleanup(xauthfile_cleanup_proc, s);
1561 return 1; 1572 return 1;
@@ -1582,7 +1593,7 @@ session_exec_req(Session *s)
1582 char *command = packet_get_string(&len); 1593 char *command = packet_get_string(&len);
1583 packet_done(); 1594 packet_done();
1584 if (forced_command) { 1595 if (forced_command) {
1585 xfree(command); 1596 original_command = command;
1586 command = forced_command; 1597 command = forced_command;
1587 debug("Forced command '%.500s'", forced_command); 1598 debug("Forced command '%.500s'", forced_command);
1588 } 1599 }
diff --git a/sftp-server.8 b/sftp-server.8
new file mode 100644
index 000000000..85720a082
--- /dev/null
+++ b/sftp-server.8
@@ -0,0 +1,33 @@
1.\" $OpenBSD: sftp-server.8,v 1.1 2000/08/31 21:52:23 markus Exp $
2.Dd August 30, 2000
3.Dt SFTP-SERVER 8
4.Os
5.Sh NAME
6.Nm sftp-server
7.Nd SFTP server subsystem
8.Sh SYNOPSIS
9.Nm sftp-server
10.Sh DESCRIPTION
11.Nm
12is a program that speaks the server side of SFTP protocol
13to stdout and expects client requests from stdin.
14.Nm
15is not intended to be called directly, but from
16.Xr sshd 8
17using the
18.Cm Subsystem
19option.
20See
21.Xr sshd 8
22for more information.
23.Sh HISTORY
24.Nm
25first appeared in
26.Ox 2.8 .
27.Sh AUTHOR
28Markus Friedl <markus@openbsd.org>
29.Sh SEE ALSO
30.Xr ssh 1 ,
31.Xr ssh-add 1 ,
32.Xr ssh-keygen 1 ,
33.Xr sshd 8 ,
diff --git a/sftp-server.c b/sftp-server.c
new file mode 100644
index 000000000..39cecac59
--- /dev/null
+++ b/sftp-server.c
@@ -0,0 +1,1078 @@
1/*
2 * Copyright (c) 2000 Markus Friedl. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. All advertising materials mentioning features or use of this software
13 * must display the following acknowledgement:
14 * This product includes software developed by Markus Friedl.
15 * 4. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29#include "includes.h"
30RCSID("$OpenBSD: sftp-server.c,v 1.4 2000/09/04 19:10:08 markus Exp $");
31
32#include "ssh.h"
33#include "buffer.h"
34#include "bufaux.h"
35#include "getput.h"
36#include "xmalloc.h"
37
38/* version */
39#define SSH_FILEXFER_VERSION 2
40
41/* client to server */
42#define SSH_FXP_INIT 1
43#define SSH_FXP_OPEN 3
44#define SSH_FXP_CLOSE 4
45#define SSH_FXP_READ 5
46#define SSH_FXP_WRITE 6
47#define SSH_FXP_LSTAT 7
48#define SSH_FXP_FSTAT 8
49#define SSH_FXP_SETSTAT 9
50#define SSH_FXP_FSETSTAT 10
51#define SSH_FXP_OPENDIR 11
52#define SSH_FXP_READDIR 12
53#define SSH_FXP_REMOVE 13
54#define SSH_FXP_MKDIR 14
55#define SSH_FXP_RMDIR 15
56#define SSH_FXP_REALPATH 16
57#define SSH_FXP_STAT 17
58#define SSH_FXP_RENAME 18
59
60/* server to client */
61#define SSH_FXP_VERSION 2
62#define SSH_FXP_STATUS 101
63#define SSH_FXP_HANDLE 102
64#define SSH_FXP_DATA 103
65#define SSH_FXP_NAME 104
66#define SSH_FXP_ATTRS 105
67
68/* portable open modes */
69#define SSH_FXF_READ 0x01
70#define SSH_FXF_WRITE 0x02
71#define SSH_FXF_APPEND 0x04
72#define SSH_FXF_CREAT 0x08
73#define SSH_FXF_TRUNC 0x10
74#define SSH_FXF_EXCL 0x20
75
76/* attributes */
77#define SSH_FXA_HAVE_SIZE 0x01
78#define SSH_FXA_HAVE_UGID 0x02
79#define SSH_FXA_HAVE_PERM 0x04
80#define SSH_FXA_HAVE_TIME 0x08
81
82/* status messages */
83#define SSH_FX_OK 0x00
84#define SSH_FX_EOF 0x01
85#define SSH_FX_NO_SUCH_FILE 0x02
86#define SSH_FX_PERMISSION_DENIED 0x03
87#define SSH_FX_FAILURE 0x04
88#define SSH_FX_BAD_MESSAGE 0x05
89#define SSH_FX_NO_CONNECTION 0x06
90#define SSH_FX_CONNECTION_LOST 0x07
91
92
93/* helper */
94#define get_int() buffer_get_int(&iqueue);
95#define get_string(lenp) buffer_get_string(&iqueue, lenp);
96#define TRACE log
97
98/* input and output queue */
99Buffer iqueue;
100Buffer oqueue;
101
102/* portable attibutes, etc. */
103
104typedef struct Attrib Attrib;
105typedef struct Stat Stat;
106
107struct Attrib
108{
109 u_int32_t flags;
110 u_int32_t size_high;
111 u_int32_t size_low;
112 u_int64_t size;
113 u_int32_t uid;
114 u_int32_t gid;
115 u_int32_t perm;
116 u_int32_t atime;
117 u_int32_t mtime;
118};
119
120struct Stat
121{
122 char *name;
123 char *long_name;
124 Attrib attrib;
125};
126
127int
128errno_to_portable(int unixerrno)
129{
130 int ret = 0;
131 switch (unixerrno) {
132 case 0:
133 ret = SSH_FX_OK;
134 break;
135 case ENOENT:
136 case ENOTDIR:
137 case EBADF:
138 case ELOOP:
139 ret = SSH_FX_NO_SUCH_FILE;
140 break;
141 case EPERM:
142 case EACCES:
143 case EFAULT:
144 ret = SSH_FX_PERMISSION_DENIED;
145 break;
146 case ENAMETOOLONG:
147 case EINVAL:
148 ret = SSH_FX_BAD_MESSAGE;
149 break;
150 default:
151 ret = SSH_FX_FAILURE;
152 break;
153 }
154 return ret;
155}
156
157int
158flags_from_portable(int pflags)
159{
160 int flags = 0;
161 if (pflags & SSH_FXF_READ &&
162 pflags & SSH_FXF_WRITE) {
163 flags = O_RDWR;
164 } else if (pflags & SSH_FXF_READ) {
165 flags = O_RDONLY;
166 } else if (pflags & SSH_FXF_WRITE) {
167 flags = O_WRONLY;
168 }
169 if (pflags & SSH_FXF_CREAT)
170 flags |= O_CREAT;
171 if (pflags & SSH_FXF_TRUNC)
172 flags |= O_TRUNC;
173 if (pflags & SSH_FXF_EXCL)
174 flags |= O_EXCL;
175 return flags;
176}
177
178void
179attrib_clear(Attrib *a)
180{
181 a->flags = 0;
182 a->size_low = 0;
183 a->size_high = 0;
184 a->size = 0;
185 a->uid = 0;
186 a->gid = 0;
187 a->perm = 0;
188 a->atime = 0;
189 a->mtime = 0;
190}
191
192Attrib *
193decode_attrib(Buffer *b)
194{
195 static Attrib a;
196 attrib_clear(&a);
197 a.flags = get_int();
198 if (a.flags & SSH_FXA_HAVE_SIZE) {
199 a.size_high = get_int();
200 a.size_low = get_int();
201 a.size = (((u_int64_t) a.size_high) << 32) + a.size_low;
202 }
203 if (a.flags & SSH_FXA_HAVE_UGID) {
204 a.uid = get_int();
205 a.gid = get_int();
206 }
207 if (a.flags & SSH_FXA_HAVE_PERM) {
208 a.perm = get_int();
209 }
210 if (a.flags & SSH_FXA_HAVE_TIME) {
211 a.atime = get_int();
212 a.mtime = get_int();
213 }
214 return &a;
215}
216
217void
218encode_attrib(Buffer *b, Attrib *a)
219{
220 buffer_put_int(b, a->flags);
221 if (a->flags & SSH_FXA_HAVE_SIZE) {
222 buffer_put_int(b, a->size_high);
223 buffer_put_int(b, a->size_low);
224 }
225 if (a->flags & SSH_FXA_HAVE_UGID) {
226 buffer_put_int(b, a->uid);
227 buffer_put_int(b, a->gid);
228 }
229 if (a->flags & SSH_FXA_HAVE_PERM) {
230 buffer_put_int(b, a->perm);
231 }
232 if (a->flags & SSH_FXA_HAVE_TIME) {
233 buffer_put_int(b, a->atime);
234 buffer_put_int(b, a->mtime);
235 }
236}
237
238Attrib *
239stat_to_attrib(struct stat *st)
240{
241 static Attrib a;
242 attrib_clear(&a);
243 a.flags = 0;
244 a.flags |= SSH_FXA_HAVE_SIZE;
245 a.size = st->st_size;
246 a.size_low = a.size;
247 a.size_high = (u_int32_t) (a.size >> 32);
248 a.flags |= SSH_FXA_HAVE_UGID;
249 a.uid = st->st_uid;
250 a.gid = st->st_gid;
251 a.flags |= SSH_FXA_HAVE_PERM;
252 a.perm = st->st_mode;
253 a.flags |= SSH_FXA_HAVE_TIME;
254 a.atime = st->st_atime;
255 a.mtime = st->st_mtime;
256 return &a;
257}
258
259Attrib *
260get_attrib(void)
261{
262 return decode_attrib(&iqueue);
263}
264
265/* handle handles */
266
267typedef struct Handle Handle;
268struct Handle {
269 int use;
270 DIR *dirp;
271 int fd;
272 char *name;
273};
274enum {
275 HANDLE_UNUSED,
276 HANDLE_DIR,
277 HANDLE_FILE
278};
279Handle handles[100];
280
281void
282handle_init(void)
283{
284 int i;
285 for(i = 0; i < sizeof(handles)/sizeof(Handle); i++)
286 handles[i].use = HANDLE_UNUSED;
287}
288
289int
290handle_new(int use, char *name, int fd, DIR *dirp)
291{
292 int i;
293 for(i = 0; i < sizeof(handles)/sizeof(Handle); i++) {
294 if (handles[i].use == HANDLE_UNUSED) {
295 handles[i].use = use;
296 handles[i].dirp = dirp;
297 handles[i].fd = fd;
298 handles[i].name = name;
299 return i;
300 }
301 }
302 return -1;
303}
304
305int
306handle_is_ok(int i, int type)
307{
308 return i >= 0 && i < sizeof(handles)/sizeof(Handle) && handles[i].use == type;
309}
310
311int
312handle_to_string(int handle, char **stringp, int *hlenp)
313{
314 char buf[1024];
315 if (stringp == NULL || hlenp == NULL)
316 return -1;
317 snprintf(buf, sizeof buf, "%d", handle);
318 *stringp = xstrdup(buf);
319 *hlenp = strlen(*stringp);
320 return 0;
321}
322
323int
324handle_from_string(char *handle, int hlen)
325{
326/* XXX OVERFLOW ? */
327 char *ep;
328 long lval = strtol(handle, &ep, 10);
329 int val = lval;
330 if (*ep != '\0')
331 return -1;
332 if (handle_is_ok(val, HANDLE_FILE) ||
333 handle_is_ok(val, HANDLE_DIR))
334 return val;
335 return -1;
336}
337
338char *
339handle_to_name(int handle)
340{
341 if (handle_is_ok(handle, HANDLE_DIR)||
342 handle_is_ok(handle, HANDLE_FILE))
343 return handles[handle].name;
344 return NULL;
345}
346
347DIR *
348handle_to_dir(int handle)
349{
350 if (handle_is_ok(handle, HANDLE_DIR))
351 return handles[handle].dirp;
352 return NULL;
353}
354
355int
356handle_to_fd(int handle)
357{
358 if (handle_is_ok(handle, HANDLE_FILE))
359 return handles[handle].fd;
360 return -1;
361}
362
363int
364handle_close(int handle)
365{
366 int ret = -1;
367 if (handle_is_ok(handle, HANDLE_FILE)) {
368 ret = close(handles[handle].fd);
369 handles[handle].use = HANDLE_UNUSED;
370 } else if (handle_is_ok(handle, HANDLE_DIR)) {
371 ret = closedir(handles[handle].dirp);
372 handles[handle].use = HANDLE_UNUSED;
373 } else {
374 errno = ENOENT;
375 }
376 return ret;
377}
378
379int
380get_handle(void)
381{
382 char *handle;
383 int hlen, val;
384 handle = get_string(&hlen);
385 val = handle_from_string(handle, hlen);
386 xfree(handle);
387 return val;
388}
389
390/* send replies */
391
392void
393send_msg(Buffer *m)
394{
395 int mlen = buffer_len(m);
396 buffer_put_int(&oqueue, mlen);
397 buffer_append(&oqueue, buffer_ptr(m), mlen);
398 buffer_consume(m, mlen);
399}
400
401void
402send_status(u_int32_t id, u_int32_t error)
403{
404 Buffer msg;
405 TRACE("sent status id %d error %d", id, error);
406 buffer_init(&msg);
407 buffer_put_char(&msg, SSH_FXP_STATUS);
408 buffer_put_int(&msg, id);
409 buffer_put_int(&msg, error);
410 send_msg(&msg);
411 buffer_free(&msg);
412}
413void
414send_data_or_handle(char type, u_int32_t id, char *data, int dlen)
415{
416 Buffer msg;
417 buffer_init(&msg);
418 buffer_put_char(&msg, type);
419 buffer_put_int(&msg, id);
420 buffer_put_string(&msg, data, dlen);
421 send_msg(&msg);
422 buffer_free(&msg);
423}
424
425void
426send_data(u_int32_t id, char *data, int dlen)
427{
428 TRACE("sent data id %d len %d", id, dlen);
429 send_data_or_handle(SSH_FXP_DATA, id, data, dlen);
430}
431
432void
433send_handle(u_int32_t id, int handle)
434{
435 char *string;
436 int hlen;
437 handle_to_string(handle, &string, &hlen);
438 TRACE("sent handle id %d handle %d", id, handle);
439 send_data_or_handle(SSH_FXP_HANDLE, id, string, hlen);
440 xfree(string);
441}
442
443void
444send_names(u_int32_t id, int count, Stat *stats)
445{
446 Buffer msg;
447 int i;
448 buffer_init(&msg);
449 buffer_put_char(&msg, SSH_FXP_NAME);
450 buffer_put_int(&msg, id);
451 buffer_put_int(&msg, count);
452 TRACE("sent names id %d count %d", id, count);
453 for (i = 0; i < count; i++) {
454 buffer_put_cstring(&msg, stats[i].name);
455 buffer_put_cstring(&msg, stats[i].long_name);
456 encode_attrib(&msg, &stats[i].attrib);
457 }
458 send_msg(&msg);
459 buffer_free(&msg);
460}
461
462void
463send_attrib(u_int32_t id, Attrib *a)
464{
465 Buffer msg;
466 TRACE("sent attrib id %d have 0x%x", id, a->flags);
467 buffer_init(&msg);
468 buffer_put_char(&msg, SSH_FXP_ATTRS);
469 buffer_put_int(&msg, id);
470 encode_attrib(&msg, a);
471 send_msg(&msg);
472 buffer_free(&msg);
473}
474
475/* parse incoming */
476
477void
478process_init(void)
479{
480 Buffer msg;
481 int version = buffer_get_int(&iqueue);
482
483 TRACE("client version %d", version);
484 buffer_init(&msg);
485 buffer_put_char(&msg, SSH_FXP_VERSION);
486 buffer_put_int(&msg, SSH_FILEXFER_VERSION);
487 send_msg(&msg);
488 buffer_free(&msg);
489}
490
491void
492process_open(void)
493{
494 u_int32_t id, pflags;
495 Attrib *a;
496 char *name;
497 int handle, fd, flags, mode, status = SSH_FX_FAILURE;
498
499 id = get_int();
500 name = get_string(NULL);
501 pflags = get_int();
502 a = get_attrib();
503 flags = flags_from_portable(pflags);
504 mode = (a->flags & SSH_FXA_HAVE_PERM) ? a->perm : 0666;
505 TRACE("open id %d name %s flags %d mode 0%o", id, name, pflags, mode);
506 fd = open(name, flags, mode);
507 if (fd < 0) {
508 status = errno_to_portable(errno);
509 } else {
510 handle = handle_new(HANDLE_FILE, xstrdup(name), fd, NULL);
511 if (handle < 0) {
512 close(fd);
513 } else {
514 send_handle(id, handle);
515 status = SSH_FX_OK;
516 }
517 }
518 if (status != SSH_FX_OK)
519 send_status(id, status);
520 xfree(name);
521}
522
523void
524process_close(void)
525{
526 u_int32_t id;
527 int handle, ret, status = SSH_FX_FAILURE;
528
529 id = get_int();
530 handle = get_handle();
531 TRACE("close id %d handle %d", id, handle);
532 ret = handle_close(handle);
533 status = (ret == -1) ? errno_to_portable(errno) : SSH_FX_OK;
534 send_status(id, status);
535}
536
537void
538process_read(void)
539{
540 char buf[64*1024];
541 u_int32_t id, off_high, off_low, len;
542 int handle, fd, ret, status = SSH_FX_FAILURE;
543 u_int64_t off;
544
545 id = get_int();
546 handle = get_handle();
547 off_high = get_int();
548 off_low = get_int();
549 len = get_int();
550
551 off = (((u_int64_t) off_high) << 32) + off_low;
552 TRACE("read id %d handle %d off %qd len %d", id, handle, off, len);
553 if (len > sizeof buf) {
554 len = sizeof buf;
555 log("read change len %d", len);
556 }
557 fd = handle_to_fd(handle);
558 if (fd >= 0) {
559 if (lseek(fd, off, SEEK_SET) < 0) {
560 error("process_read: seek failed");
561 status = errno_to_portable(errno);
562 } else {
563 ret = read(fd, buf, len);
564 if (ret < 0) {
565 status = errno_to_portable(errno);
566 } else if (ret == 0) {
567 status = SSH_FX_EOF;
568 } else {
569 send_data(id, buf, ret);
570 status = SSH_FX_OK;
571 }
572 }
573 }
574 if (status != SSH_FX_OK)
575 send_status(id, status);
576}
577
578void
579process_write(void)
580{
581 u_int32_t id, off_high, off_low;
582 u_int64_t off;
583 int len;
584 int handle, fd, ret, status = SSH_FX_FAILURE;
585 char *data;
586
587 id = get_int();
588 handle = get_handle();
589 off_high = get_int();
590 off_low = get_int();
591 data = get_string(&len);
592
593 off = (((u_int64_t) off_high) << 32) + off_low;
594 TRACE("write id %d handle %d off %qd len %d", id, handle, off, len);
595 fd = handle_to_fd(handle);
596 if (fd >= 0) {
597 if (lseek(fd, off, SEEK_SET) < 0) {
598 status = errno_to_portable(errno);
599 error("process_write: seek failed");
600 } else {
601/* XXX ATOMICIO ? */
602 ret = write(fd, data, len);
603 if (ret == -1) {
604 error("process_write: write failed");
605 status = errno_to_portable(errno);
606 } else if (ret == len) {
607 status = SSH_FX_OK;
608 } else {
609 log("nothing at all written");
610 }
611 }
612 }
613 send_status(id, status);
614 xfree(data);
615}
616
617void
618process_do_stat(int do_lstat)
619{
620 Attrib *a;
621 struct stat st;
622 u_int32_t id;
623 char *name;
624 int ret, status = SSH_FX_FAILURE;
625
626 id = get_int();
627 name = get_string(NULL);
628 TRACE("%sstat id %d name %s", do_lstat ? "l" : "", id, name);
629 ret = do_lstat ? lstat(name, &st) : stat(name, &st);
630 if (ret < 0) {
631 status = errno_to_portable(errno);
632 } else {
633 a = stat_to_attrib(&st);
634 send_attrib(id, a);
635 status = SSH_FX_OK;
636 }
637 if (status != SSH_FX_OK)
638 send_status(id, status);
639 xfree(name);
640}
641
642void
643process_stat(void)
644{
645 process_do_stat(0);
646}
647
648void
649process_lstat(void)
650{
651 process_do_stat(1);
652}
653
654void
655process_fstat(void)
656{
657 Attrib *a;
658 struct stat st;
659 u_int32_t id;
660 int fd, ret, handle, status = SSH_FX_FAILURE;
661
662 id = get_int();
663 handle = get_handle();
664 TRACE("fstat id %d handle %d", id, handle);
665 fd = handle_to_fd(handle);
666 if (fd >= 0) {
667 ret = fstat(fd, &st);
668 if (ret < 0) {
669 status = errno_to_portable(errno);
670 } else {
671 a = stat_to_attrib(&st);
672 send_attrib(id, a);
673 status = SSH_FX_OK;
674 }
675 }
676 if (status != SSH_FX_OK)
677 send_status(id, status);
678}
679
680struct timeval *
681attrib_to_tv(Attrib *a)
682{
683 static struct timeval tv[2];
684 tv[0].tv_sec = a->atime;
685 tv[0].tv_usec = 0;
686 tv[1].tv_sec = a->mtime;
687 tv[1].tv_usec = 0;
688 return tv;
689}
690
691void
692process_setstat(void)
693{
694 Attrib *a;
695 u_int32_t id;
696 char *name;
697 int ret;
698 int status = SSH_FX_OK;
699
700 id = get_int();
701 name = get_string(NULL);
702 a = get_attrib();
703 TRACE("setstat id %d name %s", id, name);
704 if (a->flags & SSH_FXA_HAVE_PERM) {
705 ret = chmod(name, a->perm & 0777);
706 if (ret == -1)
707 status = errno_to_portable(errno);
708 }
709 if (a->flags & SSH_FXA_HAVE_TIME) {
710 ret = utimes(name, attrib_to_tv(a));
711 if (ret == -1)
712 status = errno_to_portable(errno);
713 }
714 send_status(id, status);
715 xfree(name);
716}
717
718void
719process_fsetstat(void)
720{
721 Attrib *a;
722 u_int32_t id;
723 int handle, fd, ret;
724 int status = SSH_FX_OK;
725 char *name = NULL;
726
727 id = get_int();
728 handle = get_handle();
729 a = get_attrib();
730 TRACE("fsetstat id %d handle %d", id, handle);
731 fd = handle_to_fd(handle);
732 name = handle_to_name(handle);
733 if ((fd < 0) || (name == NULL)) {
734 status = SSH_FX_FAILURE;
735 } else {
736 if (a->flags & SSH_FXA_HAVE_PERM) {
737 ret = fchmod(fd, a->perm & 0777);
738 if (ret == -1)
739 status = errno_to_portable(errno);
740 }
741 if (a->flags & SSH_FXA_HAVE_TIME) {
742#ifdef HAVE_FUTIMES
743 ret = futimes(fd, attrib_to_tv(a));
744#else
745 ret = utimes(name, attrib_to_tv(a));
746#endif
747 if (ret == -1)
748 status = errno_to_portable(errno);
749 }
750 }
751 send_status(id, status);
752}
753
754void
755process_opendir(void)
756{
757 DIR *dirp = NULL;
758 char *path;
759 int handle, status = SSH_FX_FAILURE;
760 u_int32_t id;
761
762 id = get_int();
763 path = get_string(NULL);
764 TRACE("opendir id %d path %s", id, path);
765 dirp = opendir(path);
766 if (dirp == NULL) {
767 status = errno_to_portable(errno);
768 } else {
769 handle = handle_new(HANDLE_DIR, xstrdup(path), 0, dirp);
770 if (handle < 0) {
771 closedir(dirp);
772 } else {
773 send_handle(id, handle);
774 status = SSH_FX_OK;
775 }
776
777 }
778 if (status != SSH_FX_OK)
779 send_status(id, status);
780 xfree(path);
781}
782
783char *
784ls_file(char *name, struct stat *st)
785{
786 char buf[1024];
787 snprintf(buf, sizeof buf, "0%o %d %d %qd %d %s",
788 st->st_mode, st->st_uid, st->st_gid, (long long)st->st_size,(int) st->st_mtime,
789 name);
790 return xstrdup(buf);
791}
792
793void
794process_readdir(void)
795{
796 DIR *dirp;
797 struct dirent *dp;
798 char *path;
799 int handle;
800 u_int32_t id;
801
802 id = get_int();
803 handle = get_handle();
804 TRACE("readdir id %d handle %d", id, handle);
805 dirp = handle_to_dir(handle);
806 path = handle_to_name(handle);
807 if (dirp == NULL || path == NULL) {
808 send_status(id, SSH_FX_FAILURE);
809 } else {
810 Attrib *a;
811 struct stat st;
812 char pathname[1024];
813 Stat *stats;
814 int nstats = 10, count = 0, i;
815 stats = xmalloc(nstats * sizeof(Stat));
816 while ((dp = readdir(dirp)) != NULL) {
817 if (count >= nstats) {
818 nstats *= 2;
819 stats = xrealloc(stats, nstats * sizeof(Stat));
820 }
821/* XXX OVERFLOW ? */
822 snprintf(pathname, sizeof pathname,
823 "%s/%s", path, dp->d_name);
824 if (lstat(pathname, &st) < 0)
825 continue;
826 a = stat_to_attrib(&st);
827 stats[count].attrib = *a;
828 stats[count].name = xstrdup(dp->d_name);
829 stats[count].long_name = ls_file(dp->d_name, &st);
830 count++;
831 /* send up to 100 entries in one message */
832 if (count == 100)
833 break;
834 }
835 send_names(id, count, stats);
836 for(i = 0; i < count; i++) {
837 xfree(stats[i].name);
838 xfree(stats[i].long_name);
839 }
840 xfree(stats);
841 }
842}
843
844void
845process_remove(void)
846{
847 char *name;
848 u_int32_t id;
849 int status = SSH_FX_FAILURE;
850 int ret;
851
852 id = get_int();
853 name = get_string(NULL);
854 TRACE("remove id %d name %s", id, name);
855 ret = remove(name);
856 status = (ret == -1) ? errno_to_portable(errno) : SSH_FX_OK;
857 send_status(id, status);
858 xfree(name);
859}
860
861void
862process_mkdir(void)
863{
864 Attrib *a;
865 u_int32_t id;
866 char *name;
867 int ret, mode, status = SSH_FX_FAILURE;
868
869 id = get_int();
870 name = get_string(NULL);
871 a = get_attrib();
872 mode = (a->flags & SSH_FXA_HAVE_PERM) ? a->perm & 0777 : 0777;
873 TRACE("mkdir id %d name %s mode 0%o", id, name, mode);
874 ret = mkdir(name, mode);
875 status = (ret == -1) ? errno_to_portable(errno) : SSH_FX_OK;
876 send_status(id, status);
877 xfree(name);
878}
879
880void
881process_rmdir(void)
882{
883 u_int32_t id;
884 char *name;
885 int ret, status;
886
887 id = get_int();
888 name = get_string(NULL);
889 TRACE("rmdir id %d name %s", id, name);
890 ret = rmdir(name);
891 status = (ret == -1) ? errno_to_portable(errno) : SSH_FX_OK;
892 send_status(id, status);
893 xfree(name);
894}
895
896void
897process_realpath(void)
898{
899 char resolvedname[MAXPATHLEN];
900 u_int32_t id;
901 char *path;
902
903 id = get_int();
904 path = get_string(NULL);
905 TRACE("realpath id %d path %s", id, path);
906 if (realpath(path, resolvedname) == NULL) {
907 send_status(id, errno_to_portable(errno));
908 } else {
909 Stat s;
910 attrib_clear(&s.attrib);
911 s.name = s.long_name = resolvedname;
912 send_names(id, 1, &s);
913 }
914 xfree(path);
915}
916
917void
918process_rename(void)
919{
920 u_int32_t id;
921 char *oldpath, *newpath;
922 int ret, status;
923
924 id = get_int();
925 oldpath = get_string(NULL);
926 newpath = get_string(NULL);
927 TRACE("rename id %d old %s new %s", id, oldpath, newpath);
928 ret = rename(oldpath, newpath);
929 status = (ret == -1) ? errno_to_portable(errno) : SSH_FX_OK;
930 send_status(id, status);
931 xfree(oldpath);
932 xfree(newpath);
933}
934
935
936/* stolen from ssh-agent */
937
938void
939process(void)
940{
941 unsigned int msg_len;
942 unsigned int type;
943 unsigned char *cp;
944
945 if (buffer_len(&iqueue) < 5)
946 return; /* Incomplete message. */
947 cp = (unsigned char *) buffer_ptr(&iqueue);
948 msg_len = GET_32BIT(cp);
949 if (msg_len > 256 * 1024) {
950 error("bad message ");
951 exit(11);
952 }
953 if (buffer_len(&iqueue) < msg_len + 4)
954 return;
955 buffer_consume(&iqueue, 4);
956 type = buffer_get_char(&iqueue);
957 switch (type) {
958 case SSH_FXP_INIT:
959 process_init();
960 break;
961 case SSH_FXP_OPEN:
962 process_open();
963 break;
964 case SSH_FXP_CLOSE:
965 process_close();
966 break;
967 case SSH_FXP_READ:
968 process_read();
969 break;
970 case SSH_FXP_WRITE:
971 process_write();
972 break;
973 case SSH_FXP_LSTAT:
974 process_lstat();
975 break;
976 case SSH_FXP_FSTAT:
977 process_fstat();
978 break;
979 case SSH_FXP_SETSTAT:
980 process_setstat();
981 break;
982 case SSH_FXP_FSETSTAT:
983 process_fsetstat();
984 break;
985 case SSH_FXP_OPENDIR:
986 process_opendir();
987 break;
988 case SSH_FXP_READDIR:
989 process_readdir();
990 break;
991 case SSH_FXP_REMOVE:
992 process_remove();
993 break;
994 case SSH_FXP_MKDIR:
995 process_mkdir();
996 break;
997 case SSH_FXP_RMDIR:
998 process_rmdir();
999 break;
1000 case SSH_FXP_REALPATH:
1001 process_realpath();
1002 break;
1003 case SSH_FXP_STAT:
1004 process_stat();
1005 break;
1006 case SSH_FXP_RENAME:
1007 process_rename();
1008 break;
1009 default:
1010 error("Unknown message %d", type);
1011 break;
1012 }
1013}
1014
1015int
1016main(int ac, char **av)
1017{
1018 fd_set rset, wset;
1019 int in, out, max;
1020 size_t len, olen;
1021
1022 handle_init();
1023
1024 in = dup(STDIN_FILENO);
1025 out = dup(STDOUT_FILENO);
1026
1027 max = 0;
1028 if (in > max)
1029 max = in;
1030 if (out > max)
1031 max = out;
1032
1033 buffer_init(&iqueue);
1034 buffer_init(&oqueue);
1035
1036 for (;;) {
1037 FD_ZERO(&rset);
1038 FD_ZERO(&wset);
1039
1040 FD_SET(in, &rset);
1041 olen = buffer_len(&oqueue);
1042 if (olen > 0)
1043 FD_SET(out, &wset);
1044
1045 if (select(max+1, &rset, &wset, NULL, NULL) < 0) {
1046 if (errno == EINTR)
1047 continue;
1048 exit(2);
1049 }
1050
1051 /* copy stdin to iqueue */
1052 if (FD_ISSET(in, &rset)) {
1053 char buf[4*4096];
1054 len = read(in, buf, sizeof buf);
1055 if (len == 0) {
1056 debug("read eof");
1057 exit(0);
1058 } else if (len < 0) {
1059 error("read error");
1060 exit(1);
1061 } else {
1062 buffer_append(&iqueue, buf, len);
1063 }
1064 }
1065 /* send oqueue to stdout */
1066 if (FD_ISSET(out, &wset)) {
1067 len = write(out, buffer_ptr(&oqueue), olen);
1068 if (len < 0) {
1069 error("write error");
1070 exit(1);
1071 } else {
1072 buffer_consume(&oqueue, len);
1073 }
1074 }
1075 /* process requests from client */
1076 process();
1077 }
1078}
diff --git a/ssh-add.1 b/ssh-add.1
index 8e9d33bfe..0e6930aba 100644
--- a/ssh-add.1
+++ b/ssh-add.1
@@ -9,7 +9,7 @@
9.\" 9.\"
10.\" Created: Sat Apr 22 23:55:14 1995 ylo 10.\" Created: Sat Apr 22 23:55:14 1995 ylo
11.\" 11.\"
12.\" $Id: ssh-add.1,v 1.15 2000/08/29 00:33:51 djm Exp $ 12.\" $Id: ssh-add.1,v 1.16 2000/09/05 02:34:54 djm Exp $
13.\" 13.\"
14.Dd September 25, 1999 14.Dd September 25, 1999
15.Dt SSH-ADD 1 15.Dt SSH-ADD 1
@@ -65,7 +65,7 @@ This is the default file added by
65when no other files have been specified. 65when no other files have been specified.
66.It Pa $HOME/.ssh/id_dsa 66.It Pa $HOME/.ssh/id_dsa
67Contains the DSA authentication identity of the user. 67Contains the DSA authentication identity of the user.
68.Pp 68.El
69.Sh ENVIRONMENT 69.Sh ENVIRONMENT
70.Bl -tag -width Ds 70.Bl -tag -width Ds
71.It Ev "DISPLAY" and "SSH_ASKPASS" 71.It Ev "DISPLAY" and "SSH_ASKPASS"
@@ -91,6 +91,7 @@ or related script.
91may be necessary to redirect the input from 91may be necessary to redirect the input from
92.Pa /dev/null 92.Pa /dev/null
93to make this work.) 93to make this work.)
94.El
94.Sh AUTHOR 95.Sh AUTHOR
95Tatu Ylonen <ylo@cs.hut.fi> 96Tatu Ylonen <ylo@cs.hut.fi>
96.Pp 97.Pp
diff --git a/ssh-agent.c b/ssh-agent.c
index 56b81a78d..0bc4722b2 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-agent.c,v 1.33 2000/08/19 21:34:43 markus Exp $ */ 1/* $OpenBSD: ssh-agent.c,v 1.34 2000/08/31 22:09:34 markus Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -12,7 +12,7 @@
12 */ 12 */
13 13
14#include "includes.h" 14#include "includes.h"
15RCSID("$OpenBSD: ssh-agent.c,v 1.33 2000/08/19 21:34:43 markus Exp $"); 15RCSID("$OpenBSD: ssh-agent.c,v 1.34 2000/08/31 22:09:34 markus Exp $");
16 16
17#include "ssh.h" 17#include "ssh.h"
18#include "rsa.h" 18#include "rsa.h"
@@ -219,6 +219,7 @@ process_sign_request2(SocketEntry *e)
219 219
220 blob = buffer_get_string(&e->input, &blen); 220 blob = buffer_get_string(&e->input, &blen);
221 data = buffer_get_string(&e->input, &dlen); 221 data = buffer_get_string(&e->input, &dlen);
222 buffer_get_int(&e->input); /* flags, unused */
222 223
223 key = dsa_key_from_blob(blob, blen); 224 key = dsa_key_from_blob(blob, blen);
224 if (key != NULL) { 225 if (key != NULL) {
diff --git a/ssh.1 b/ssh.1
index 67dc3df77..ca208871e 100644
--- a/ssh.1
+++ b/ssh.1
@@ -9,7 +9,7 @@
9.\" 9.\"
10.\" Created: Sat Apr 22 21:55:14 1995 ylo 10.\" Created: Sat Apr 22 21:55:14 1995 ylo
11.\" 11.\"
12.\" $Id: ssh.1,v 1.30 2000/08/29 00:33:51 djm Exp $ 12.\" $Id: ssh.1,v 1.31 2000/09/05 02:34:54 djm Exp $
13.\" 13.\"
14.Dd September 25, 1999 14.Dd September 25, 1999
15.Dt SSH 1 15.Dt SSH 1
@@ -946,6 +946,7 @@ Specifies the location of the
946program. 946program.
947The default is 947The default is
948.Pa /usr/X11R6/bin/xauth . 948.Pa /usr/X11R6/bin/xauth .
949.El
949.Sh ENVIRONMENT 950.Sh ENVIRONMENT
950.Nm 951.Nm
951will normally set the following environment variables: 952will normally set the following environment variables:
@@ -1189,6 +1190,7 @@ above.
1189.It Pa libcrypto.so.X.1 1190.It Pa libcrypto.so.X.1
1190A version of this library which includes support for the RSA algorithm 1191A version of this library which includes support for the RSA algorithm
1191is required for proper operation. 1192is required for proper operation.
1193.El
1192.Sh AUTHOR 1194.Sh AUTHOR
1193OpenSSH 1195OpenSSH
1194is a derivative of the original (free) ssh 1.2.12 release by Tatu Ylonen, 1196is a derivative of the original (free) ssh 1.2.12 release by Tatu Ylonen,
diff --git a/sshd.8 b/sshd.8
index d710baad5..0402748d2 100644
--- a/sshd.8
+++ b/sshd.8
@@ -9,7 +9,7 @@
9.\" 9.\"
10.\" Created: Sat Apr 22 21:55:14 1995 ylo 10.\" Created: Sat Apr 22 21:55:14 1995 ylo
11.\" 11.\"
12.\" $Id: sshd.8,v 1.27 2000/08/29 00:33:51 djm Exp $ 12.\" $Id: sshd.8,v 1.28 2000/09/05 02:34:54 djm Exp $
13.\" 13.\"
14.Dd September 25, 1999 14.Dd September 25, 1999
15.Dt SSHD 8 15.Dt SSHD 8
@@ -589,6 +589,11 @@ The default is
589.It Cm Subsystem 589.It Cm Subsystem
590Configures an external subsystem (e.g. file transfer daemon). 590Configures an external subsystem (e.g. file transfer daemon).
591Arguments should be a subsystem name and a command to execute upon subsystem request. 591Arguments should be a subsystem name and a command to execute upon subsystem request.
592The command
593.Xr sftp-server 8
594implements the
595.Dq sftp
596file transfer subsystem.
592By default no subsystems are defined. 597By default no subsystems are defined.
593Note that this option applies to protocol version 2 only. 598Note that this option applies to protocol version 2 only.
594.It Cm SyslogFacility 599.It Cm SyslogFacility
@@ -1031,6 +1036,7 @@ Niels Provos, Theo de Raadt, and Dug Song.
1031The support for SSH protocol 2 was written by Markus Friedl. 1036The support for SSH protocol 2 was written by Markus Friedl.
1032.Sh SEE ALSO 1037.Sh SEE ALSO
1033.Xr scp 1 , 1038.Xr scp 1 ,
1039.Xr sftp-server 8 ,
1034.Xr ssh 1 , 1040.Xr ssh 1 ,
1035.Xr ssh-add 1 , 1041.Xr ssh-add 1 ,
1036.Xr ssh-agent 1 , 1042.Xr ssh-agent 1 ,
diff --git a/sshd_config b/sshd_config
index b89b19fc8..43d2e8ea6 100644
--- a/sshd_config
+++ b/sshd_config
@@ -50,5 +50,6 @@ PermitEmptyPasswords no
50CheckMail no 50CheckMail no
51#UseLogin no 51#UseLogin no
52 52
53#Subsystem sftp /usr/local/sbin/sftpd 53# Uncomment if you want to enable sftp
54#Subsystem sftp /usr/libexec/sftp-server
54#MaxStartups 10:30:60 55#MaxStartups 10:30:60