18127340 migrate the sftp dtrace provider feature from SunSSH to OpenSSH
authorHuie-Ying Lee <huieying.lee@oracle.com>
Tue, 29 Apr 2014 16:12:37 -0700
changeset 1862 753bed6dd354
parent 1861 8cb815f8d2d9
child 1863 5eace3760c01
18127340 migrate the sftp dtrace provider feature from SunSSH to OpenSSH 18528305 /var/empty should be delivered readonly
components/openssh/Makefile
components/openssh/dtrace_sftp/sftp_provider.d
components/openssh/dtrace_sftp/sftp_provider_impl.h
components/openssh/openssh.p5m
components/openssh/patches/013-dtrace_sftp.patch
--- a/components/openssh/Makefile	Tue Apr 29 09:05:09 2014 -0700
+++ b/components/openssh/Makefile	Tue Apr 29 16:12:37 2014 -0700
@@ -45,7 +45,7 @@
 # Enable ASLR for this component
 ASLR_MODE = $(ASLR_ENABLE)
 
-CONFIGURE_OPTIONS += CFLAGS="$(CFLAGS) -DSET_USE_PAM -DDEPRECATE_SUNSSH_OPT -DLASTLOG_FIX -DKRB5_BUILD_FIX -DAUE_openssh=6172"
+CONFIGURE_OPTIONS += CFLAGS="$(CFLAGS) -DSET_USE_PAM -DDEPRECATE_SUNSSH_OPT -DLASTLOG_FIX -DKRB5_BUILD_FIX -DAUE_openssh=6172 -DDTRACE_SFTP"
 
 # We need to disable lazyloading of dynamic dependent libraries. During the
 # pre-authentication phase, sshd will chroot to /var/empty which doesn't
@@ -68,6 +68,12 @@
 CONFIGURE_OPTIONS += --sbindir=/usr/lib/ssh
 CONFIGURE_OPTIONS += --sysconfdir=/etc/ssh
 
+# Copy the sftp dtrace provider file and the header file to source directory
+COMPONENT_PRE_BUILD_ACTION = \
+    ( echo "Copying dtrace sftp files..."; \
+      $(LN) -fs $(COMPONENT_DIR)/dtrace_sftp/*.[dh] $(SOURCE_DIR); \
+    )
+
 # common targets
 build:		$(BUILD_32)
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssh/dtrace_sftp/sftp_provider.d	Tue Apr 29 16:12:37 2014 -0700
@@ -0,0 +1,61 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/*
+ * We seem currently unable to depend properly on existing D libraries (like
+ * sftp.d). But the definitions for conninfo_t and sftpinfo_t are stored there
+ * (and have to be, since that's where the real translators live). So we're
+ * forced to define something here to satisfy dtrace(1M), but none of the
+ * definitions or translators here are actually used.
+ */
+typedef struct sftpinfo {
+	int dummy;
+} sftpinfo_t;
+
+typedef struct sftpproto {
+	int dummy;
+} sftpproto_t;
+
+typedef struct conninfo {
+	int dummy;
+} conninfo_t;
+
+translator conninfo_t <sftpproto_t *dp> {
+};
+
+translator sftpinfo_t <sftpproto_t *dp> {
+};
+
+provider sftp {
+	probe transfer__start(sftpproto_t *p) :
+	    (conninfo_t *p, sftpinfo_t *p);
+	probe transfer__done(sftpproto_t *p) :
+	    (conninfo_t *p, sftpinfo_t *p);
+};
+
+#pragma D attributes Evolving/Evolving/ISA provider sftp provider
+#pragma D attributes Private/Private/Unknown provider sftp module
+#pragma D attributes Private/Private/Unknown provider sftp function
+#pragma D attributes Private/Private/ISA provider sftp name
+#pragma D attributes Evolving/Evolving/ISA provider sftp args
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssh/dtrace_sftp/sftp_provider_impl.h	Tue Apr 29 16:12:37 2014 -0700
@@ -0,0 +1,73 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef	_SFTP_PROVIDER_IMPL_H
+#define	_SFTP_PROVIDER_IMPL_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * This structure must match the definition of same in sftp.d.
+ */
+typedef struct sftpproto {
+	int64_t sftp_nbytes;		/* bytes writtten or read */
+	const char *sftp_user;		/* user name */
+	const char *sftp_operation;	/* SFTP Operation */
+	const char *sftp_raddr;		/* remote address */
+	const char *sftp_pathname;	/* path with file name */
+	int32_t sftp_fd;		/* fd for transfer, if any */
+} sftpproto_t;
+
+#define	SFTP_TRANSFER_PROTO(proto, op, fd, path, len) \
+	bzero((proto), sizeof (struct sftpproto)); \
+	(proto)->sftp_user = (pw->pw_name ? pw->pw_name : "UNKNOWN"); \
+	(proto)->sftp_operation = (op ? op : "UNKNOWN"); \
+	(proto)->sftp_raddr = (client_addr); \
+	(proto)->sftp_fd = (fd); \
+	(proto)->sftp_pathname = (path ? path : "UNKNOWN"); \
+	(proto)->sftp_nbytes = (len); \
+
+#define	SFTP_TRANSFER_START_OP(op, fd, path, len) \
+	if (SFTP_TRANSFER_START_ENABLED()) { \
+		sftpproto_t proto; \
+		SFTP_TRANSFER_PROTO(&proto, op, fd, path, len); \
+		SFTP_TRANSFER_START(&proto); \
+	} \
+
+#define	SFTP_TRANSFER_DONE_OP(op, fd, path, len) \
+	if (SFTP_TRANSFER_DONE_ENABLED()) { \
+		sftpproto_t proto; \
+		SFTP_TRANSFER_PROTO(&proto, op, fd, path, len); \
+		SFTP_TRANSFER_DONE(&proto); \
+	} \
+
+#include <sftp_provider.h>
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _SFTP_PROVIDER_IMPL_H */
--- a/components/openssh/openssh.p5m	Tue Apr 29 09:05:09 2014 -0700
+++ b/components/openssh/openssh.p5m	Tue Apr 29 16:12:37 2014 -0700
@@ -124,7 +124,7 @@
     mediator=ssh mediator-implementation=openssh
 file usr/share/man/man5/sshd_config.5 \
     path=usr/share/man/man4/sshd_config.openssh.4
-dir  path=var/empty owner=root group=sys mode=0755
+dir  path=var/empty owner=root group=sys mode=0755 sysattr=readonly
 group groupname=sshd gid=22
 user username=sshd ftpuser=false gcos-field="sshd privsep" group=sshd \
     home-dir=/var/empty login-shell=/bin/false uid=22
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssh/patches/013-dtrace_sftp.patch	Tue Apr 29 16:12:37 2014 -0700
@@ -0,0 +1,148 @@
+#
+# This patch is to provide a SFTP DTrace provider which offers an administrator
+# some observability of SFTP data transfer. This was developed in-house. 
+# Because this is Solaris-specific and not suitable for upstream, we will not
+# contribute the changes to the upstream community.
+#
+--- orig/Makefile.in	Wed Apr 16 17:10:03 2014
++++ new/Makefile.in	Wed Apr 23 11:00:05 2014
[email protected]@ -76,7 +76,8 @@
+ 	jpake.o schnorr.o ssh-pkcs11.o krl.o smult_curve25519_ref.o \
+ 	kexc25519.o kexc25519c.o poly1305.o chacha.o cipher-chachapoly.o \
+ 	ssh-ed25519.o digest.o \
+-	sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o
++	sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o \
++	sftp_provider.o
+ 
+ SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
+ 	sshconnect.o sshconnect1.o sshconnect2.o mux.o \
[email protected]@ -96,7 +97,7 @@
+ 	sftp-server.o sftp-common.o \
+ 	roaming_common.o roaming_serv.o \
+ 	sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \
+-	sandbox-seccomp-filter.o sandbox-capsicum.o
++	sandbox-seccomp-filter.o sandbox-capsicum.o sftp_provider.o
+ 
+ MANPAGES	= moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out sshd_config.5.out ssh_config.5.out
+ MANPAGES_IN	= moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 sshd_config.5 ssh_config.5
[email protected]@ -173,8 +174,8 @@
+ ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o
+ 	$(LD) -o [email protected] ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
+ 
+-sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o sftp-server-main.o
+-	$(LD) -o [email protected] sftp-server.o sftp-common.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
++sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o sftp-server-main.o sftp_provider.o
++	$(LD) -o [email protected] sftp-server.o sftp-common.o sftp-server-main.o sftp_provider.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
+ 
+ sftp$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-client.o sftp-common.o sftp-glob.o progressmeter.o
+ 	$(LD) -o [email protected] progressmeter.o sftp.o sftp-client.o sftp-common.o sftp-glob.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(LIBEDIT)
[email protected]@ -211,9 +212,18 @@
+ 	    -Dumac_update=umac128_update -Dumac_final=umac128_final \
+ 	    -Dumac_delete=umac128_delete
+ 
++# dtrace sftp
++sftp_provider.h: $(srcdir)/sftp_provider.d
++	/usr/sbin/dtrace -xnolibs -h -s $(srcdir)/sftp_provider.d \
++	    -o $(srcdir)/sftp_provider.h
++
++sftp_provider.o: sftp_provider.d sftp_provider.h sftp-server.o
++	/usr/sbin/dtrace -G -32 -xnolibs -s $(srcdir)/sftp_provider.d \
++            sftp-server.o -o sftp_provider.o
++
+ clean:	regressclean
+ 	rm -f *.o *.a $(TARGETS) logintest config.cache config.log
+-	rm -f *.out core survey
++	rm -f *.out core survey sftp_provider.h
+ 	(cd openbsd-compat && $(MAKE) clean)
+ 
+ distclean:	regressclean
+--- orig/sftp-server.c	Wed Apr 16 18:44:37 2014
++++ new/sftp-server.c	Thu Apr 17 11:53:54 2014
[email protected]@ -51,6 +51,9 @@
+ 
+ #include "sftp.h"
+ #include "sftp-common.h"
++#ifdef DTRACE_SFTP
++#include "sftp_provider_impl.h"
++#endif
+ 
+ /* helper */
+ #define get_int64()			buffer_get_int64(&iqueue);
[email protected]@ -721,13 +724,24 @@
+ 	u_int32_t len;
+ 	int handle, fd, ret, status = SSH2_FX_FAILURE;
+ 	u_int64_t off;
++#ifdef DTRACE_SFTP
++	char *fpath;
++#endif
+ 
+ 	handle = get_handle();
+ 	off = get_int64();
+ 	len = get_int();
++#ifdef DTRACE_SFTP
++	fpath = handle_to_name(handle);
++#endif
+ 
++#ifdef DTRACE_SFTP
+ 	debug("request %u: read \"%s\" (handle %d) off %llu len %d",
++	    id, fpath, handle, (unsigned long long)off, len);
++#else
++	debug("request %u: read \"%s\" (handle %d) off %llu len %d",
+ 	    id, handle_to_name(handle), handle, (unsigned long long)off, len);
++#endif
+ 	if (len > sizeof buf) {
+ 		len = sizeof buf;
+ 		debug2("read change len %d", len);
[email protected]@ -738,7 +752,13 @@
+ 			error("process_read: seek failed");
+ 			status = errno_to_portable(errno);
+ 		} else {
++#ifdef DTRACE_SFTP
++		        SFTP_TRANSFER_START_OP("read", fd, fpath, len);
++#endif
+ 			ret = read(fd, buf, len);
++#ifdef DTRACE_SFTP
++                        SFTP_TRANSFER_DONE_OP("read", fd, fpath, ret);
++#endif
+ 			if (ret < 0) {
+ 				status = errno_to_portable(errno);
+ 			} else if (ret == 0) {
[email protected]@ -761,13 +781,22 @@
+ 	u_int len;
+ 	int handle, fd, ret, status;
+ 	char *data;
++#ifdef DTRACE_SFTP
++	char *fpath;
++#endif
+ 
+ 	handle = get_handle();
+ 	off = get_int64();
+ 	data = get_string(&len);
+-
++#ifdef DTRACE_SFTP
++	fpath = handle_to_name(handle);
+ 	debug("request %u: write \"%s\" (handle %d) off %llu len %d",
++	    id, fpath, handle, (unsigned long long)off, len);
++#else
++	debug("request %u: write \"%s\" (handle %d) off %llu len %d",
+ 	    id, handle_to_name(handle), handle, (unsigned long long)off, len);
++#endif
++
+ 	fd = handle_to_fd(handle);
+ 	
+ 	if (fd < 0)
[email protected]@ -779,7 +808,14 @@
+ 			error("process_write: seek failed");
+ 		} else {
+ /* XXX ATOMICIO ? */
++#ifdef DTRACE_SFTP
++		        SFTP_TRANSFER_START_OP("write", fd, fpath, len);
++#endif
+ 			ret = write(fd, data, len);
++#ifdef DTRACE_SFTP
++			SFTP_TRANSFER_DONE_OP("write", fd, fpath, ret);
++#endif
++
+ 			if (ret < 0) {
+ 				error("process_write: write failed");
+ 				status = errno_to_portable(errno);