1 From df6b82f10e53d43cfbc4cb3f52aa7e1751998fa1 Mon Sep 17 00:00:00 2001
2 From: oracle <solaris@oracle.com>
3 Date: Mon, 3 Aug 2015 14:35:43 -0700
4 Subject: [PATCH 09/36] DTrace support for SFTP
5
6 ---
7 Makefile.in | 25 +++++++++++++++---
8 sftp-server.c | 25 ++++++++++++++++--
9 sftp64.d | 56 ++++++++++++++++++++++++++++++++++++++++
10 sftp_provider.d | 61 +++++++++++++++++++++++++++++++++++++++++++
11 sftp_provider_impl.h | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++
12 5 files changed, 234 insertions(+), 6 deletions(-)
13 create mode 100644 sftp64.d
14 create mode 100644 sftp_provider.d
15 create mode 100644 sftp_provider_impl.h
16
17 diff --git a/Makefile.in b/Makefile.in
18 index 9f953e1..121a261 100644
19 --- a/Makefile.in
20 +++ b/Makefile.in
21 @@ -26,6 +26,7 @@ ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass
22 SFTP_SERVER=$(libexecdir)/sftp-server
23 SSH_KEYSIGN=$(libexecdir)/ssh-keysign
24 SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper
25 +ROOTDLIBDIR64=$(DESTDIR)/usr/lib/dtrace/64
26 PRIVSEP_PATH=@PRIVSEP_PATH@
27 SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@
28 STRIP_OPT=@STRIP_OPT@
29 @@ -85,6 +86,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \
30 atomicio.o key.o dispatch.o mac.o uidswap.o uuencode.o misc.o \
31 monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \
32 msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \
33 + sftp_provider.o \
34 ssh-pkcs11.o smult_curve25519_ref.o \
35 poly1305.o chacha.o cipher-chachapoly.o \
36 ssh-ed25519.o digest-openssl.o digest-libc.o hmac.o \
37 @@ -111,7 +113,8 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
38 sftp-server.o sftp-common.o \
39 roaming_common.o roaming_serv.o \
40 sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \
41 - sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-solaris.o
42 + sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-solaris.o \
43 + sftp_provider.o
44
45 MANPAGES = moduli.4.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.1m.out sftp-server.1m.out sftp.1.out ssh-keysign.1m.out ssh-pkcs11-helper.1m.out sshd_config.4.out ssh_config.4.out
46 MANPAGES_IN = moduli.4 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.1m sftp-server.1m sftp.1 ssh-keysign.1m ssh-pkcs11-helper.1m sshd_config.4 ssh_config.4
47 @@ -188,8 +191,8 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11
48 ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o
49 $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
50
51 -sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o sftp-server-main.o
52 - $(LD) -o $@ sftp-server.o sftp-common.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
53 +sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o sftp-server-main.o sftp_provider.o
54 + $(LD) -o $@ sftp-server.o sftp-common.o sftp-server-main.o sftp_provider.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
55
56 sftp$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-client.o sftp-common.o sftp-glob.o progressmeter.o
57 $(LD) -o $@ progressmeter.o sftp.o sftp-client.o sftp-common.o sftp-glob.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(LIBEDIT)
58 @@ -226,9 +229,22 @@ umac128.o: umac.c
59 -Dumac_update=umac128_update -Dumac_final=umac128_final \
60 -Dumac_delete=umac128_delete
61
62 +# dtrace sftp
63 +sftp_provider.h: $(srcdir)/sftp_provider.d
64 + /usr/sbin/dtrace -xnolibs -h -s $(srcdir)/sftp_provider.d \
65 + -o $(srcdir)/sftp_provider.h
66 +
67 +sftp_provider.o: sftp_provider.d sftp_provider.h sftp-server.o
68 + /usr/sbin/dtrace -G -64 -xnolibs -s $(srcdir)/sftp_provider.d \
69 + sftp-server.o -o sftp_provider.o
70 +
71 +# special case for sftp-server.o, it includes sftp_provider.h
72 +sftp-server.o: sftp_provider.h sftp-server.c
73 + $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ -c $(srcdir)/sftp-server.c
74 +
75 clean: regressclean
76 rm -f *.o *.a $(TARGETS) logintest config.cache config.log
77 - rm -f *.out core survey
78 + rm -f *.out core survey sftp_provider.h
79 rm -f regress/unittests/test_helper/*.a
80 rm -f regress/unittests/test_helper/*.o
81 rm -f regress/unittests/sshbuf/*.o
82 @@ -341,6 +357,7 @@ install-files:
83 ln -s ./ssh$(EXEEXT) $(DESTDIR)$(bindir)/slogin
84 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
85 ln -s ./ssh.1 $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
86 + mkdir -p $(ROOTDLIBDIR64) && cp $(srcdir)/sftp64.d $(ROOTDLIBDIR64)/sftp64.d
87
88 install-sysconf:
89 if [ ! -d $(DESTDIR)$(sysconfdir) ]; then \
90 diff --git a/sftp-server.c b/sftp-server.c
91 index 3877c03..772a7c3 100644
92 --- a/sftp-server.c
93 +++ b/sftp-server.c
94 @@ -54,6 +54,9 @@
95
96 #include "sftp.h"
97 #include "sftp-common.h"
98 +#ifdef DTRACE_SFTP
99 +#include "sftp_provider_impl.h"
100 +#endif
101
102 /* Our verbosity */
103 static LogLevel log_level = SYSLOG_LEVEL_ERROR;
104 @@ -740,14 +743,17 @@ process_read(u_int32_t id)
105 u_int32_t len;
106 int r, handle, fd, ret, status = SSH2_FX_FAILURE;
107 u_int64_t off;
108 + char *fpath;
109
110 if ((r = get_handle(iqueue, &handle)) != 0 ||
111 (r = sshbuf_get_u64(iqueue, &off)) != 0 ||
112 (r = sshbuf_get_u32(iqueue, &len)) != 0)
113 fatal("%s: buffer error: %s", __func__, ssh_err(r));
114
115 + fpath = handle_to_name(handle);
116 +
117 debug("request %u: read \"%s\" (handle %d) off %llu len %d",
118 - id, handle_to_name(handle), handle, (unsigned long long)off, len);
119 + id, fpath, handle, (unsigned long long)off, len);
120 if (len > sizeof buf) {
121 len = sizeof buf;
122 debug2("read change len %d", len);
123 @@ -758,7 +764,13 @@ process_read(u_int32_t id)
124 error("process_read: seek failed");
125 status = errno_to_portable(errno);
126 } else {
127 +#ifdef DTRACE_SFTP
128 + SFTP_TRANSFER_START_OP("read", fd, fpath, len);
129 +#endif
130 ret = read(fd, buf, len);
131 +#ifdef DTRACE_SFTP
132 + SFTP_TRANSFER_DONE_OP("read", fd, fpath, ret);
133 +#endif
134 if (ret < 0) {
135 status = errno_to_portable(errno);
136 } else if (ret == 0) {
137 @@ -781,14 +793,16 @@ process_write(u_int32_t id)
138 size_t len;
139 int r, handle, fd, ret, status;
140 u_char *data;
141 + char *fpath;
142
143 if ((r = get_handle(iqueue, &handle)) != 0 ||
144 (r = sshbuf_get_u64(iqueue, &off)) != 0 ||
145 (r = sshbuf_get_string(iqueue, &data, &len)) != 0)
146 fatal("%s: buffer error: %s", __func__, ssh_err(r));
147
148 + fpath = handle_to_name(handle);
149 debug("request %u: write \"%s\" (handle %d) off %llu len %zu",
150 - id, handle_to_name(handle), handle, (unsigned long long)off, len);
151 + id, fpath, handle, (unsigned long long)off, len);
152 fd = handle_to_fd(handle);
153
154 if (fd < 0)
155 @@ -800,7 +814,14 @@ process_write(u_int32_t id)
156 error("process_write: seek failed");
157 } else {
158 /* XXX ATOMICIO ? */
159 +#ifdef DTRACE_SFTP
160 + SFTP_TRANSFER_START_OP("write", fd, fpath, len);
161 +#endif
162 ret = write(fd, data, len);
163 +#ifdef DTRACE_SFTP
164 + SFTP_TRANSFER_DONE_OP("write", fd, fpath, ret);
165 +#endif
166 +
167 if (ret < 0) {
168 error("process_write: write failed");
169 status = errno_to_portable(errno);
170 diff --git a/sftp64.d b/sftp64.d
171 new file mode 100644
172 index 0000000..8305d0a
173 --- /dev/null
174 +++ b/sftp64.d
175 @@ -0,0 +1,56 @@
176 +/*
177 + * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
178 + */
179 +
180 +#pragma D depends_on library net.d
181 +#pragma D depends_on library io.d
182 +#pragma D depends_on module lofs
183 +
184 +typedef struct sftpinfo {
185 + string sfi_user; /* user name */
186 + string sfi_operation; /* SFTP Operation */
187 + ssize_t sfi_nbytes; /* bytes transferred, if any */
188 + string sfi_pathname; /* pathname of transfer */
189 + string sfi_fsresource; /* Dataset(ZFS) or resource name */
190 +} sftpinfo_t;
191 +
192 +/*
193 + * This structure must match the definition of same in sftp_provider_impl.h.
194 + */
195 +typedef struct sftpproto {
196 + int64_t sftp_nbytes; /* bytes written or read */
197 + uint64_t sftp_user; /* user name */
198 + uint64_t sftp_operation; /* SFTP operation */
199 + uint64_t sftp_raddr; /* remote address */
200 + uint64_t sftp_pathname; /* path with file name */
201 + int32_t sftp_fd; /* fd for transfer, if any */
202 +} sftpproto_t;
203 +
204 +#pragma D binding "1.6.1" translator
205 +translator conninfo_t <sftpproto_t *s> {
206 + ci_protocol = "tcp";
207 + ci_remote = copyinstr((uintptr_t)
208 + *(uint64_t *)copyin((uintptr_t)&s->sftp_raddr, sizeof (uint64_t)));
209 + ci_local = "<unknown>";
210 +};
211 +
212 +#pragma D binding "1.6.1" translator
213 +translator sftpinfo_t <sftpproto_t *s> {
214 + sfi_user = copyinstr((uintptr_t)
215 + *(uint64_t *)copyin((uintptr_t)&s->sftp_user, sizeof (uint64_t)));
216 + sfi_operation = copyinstr((uintptr_t)
217 + *(uint64_t *)copyin((uintptr_t)&s->sftp_operation,
218 + sizeof (uint64_t)));
219 + sfi_nbytes =
220 + *(uint64_t *)copyin((uintptr_t)&s->sftp_nbytes, sizeof (uint64_t));
221 + sfi_fsresource = stringof(fds[*(int32_t *)copyin((uintptr_t)&s->sftp_fd,
222 + sizeof (int32_t))].fi_fs) == "lofs" ? stringof(((struct loinfo *)
223 + curthread->t_procp->p_user.u_finfo.fi_list[*(int32_t *)copyin(
224 + (uintptr_t)&s->sftp_fd, sizeof (int32_t))].uf_file->f_vnode->
225 + v_vfsp->vfs_data)->li_realvfs->vfs_resource->rs_string) :
226 + stringof(curthread->t_procp->p_user.u_finfo.fi_list[
227 + *(int32_t *)copyin((uintptr_t)&s->sftp_fd, sizeof (int32_t))].
228 + uf_file->f_vnode->v_vfsp->vfs_resource->rs_string);
229 + sfi_pathname = copyinstr((uintptr_t)*(uint64_t *)copyin(
230 + (uintptr_t)&s->sftp_pathname, sizeof (uint64_t)));
231 +};
232 diff --git a/sftp_provider.d b/sftp_provider.d
233 new file mode 100644
234 index 0000000..99e9920
235 --- /dev/null
236 +++ b/sftp_provider.d
237 @@ -0,0 +1,61 @@
238 +/*
239 + * CDDL HEADER START
240 + *
241 + * The contents of this file are subject to the terms of the
242 + * Common Development and Distribution License (the "License").
243 + * You may not use this file except in compliance with the License.
244 + *
245 + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
246 + * or http://www.opensolaris.org/os/licensing.
247 + * See the License for the specific language governing permissions
248 + * and limitations under the License.
249 + *
250 + * When distributing Covered Code, include this CDDL HEADER in each
251 + * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
252 + * If applicable, add the following below this CDDL HEADER, with the
253 + * fields enclosed by brackets "[]" replaced with your own identifying
254 + * information: Portions Copyright [yyyy] [name of copyright owner]
255 + *
256 + * CDDL HEADER END
257 + */
258 +/*
259 + * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
260 + */
261 +
262 +/*
263 + * We seem currently unable to depend properly on existing D libraries (like
264 + * sftp.d). But the definitions for conninfo_t and sftpinfo_t are stored there
265 + * (and have to be, since that's where the real translators live). So we're
266 + * forced to define something here to satisfy dtrace(1M), but none of the
267 + * definitions or translators here are actually used.
268 + */
269 +typedef struct sftpinfo {
270 + int dummy;
271 +} sftpinfo_t;
272 +
273 +typedef struct sftpproto {
274 + int dummy;
275 +} sftpproto_t;
276 +
277 +typedef struct conninfo {
278 + int dummy;
279 +} conninfo_t;
280 +
281 +translator conninfo_t <sftpproto_t *dp> {
282 +};
283 +
284 +translator sftpinfo_t <sftpproto_t *dp> {
285 +};
286 +
287 +provider sftp {
288 + probe transfer__start(sftpproto_t *p) :
289 + (conninfo_t *p, sftpinfo_t *p);
290 + probe transfer__done(sftpproto_t *p) :
291 + (conninfo_t *p, sftpinfo_t *p);
292 +};
293 +
294 +#pragma D attributes Evolving/Evolving/ISA provider sftp provider
295 +#pragma D attributes Private/Private/Unknown provider sftp module
296 +#pragma D attributes Private/Private/Unknown provider sftp function
297 +#pragma D attributes Private/Private/ISA provider sftp name
298 +#pragma D attributes Evolving/Evolving/ISA provider sftp args
299 diff --git a/sftp_provider_impl.h b/sftp_provider_impl.h
300 new file mode 100644
301 index 0000000..4b18e6e
302 --- /dev/null
303 +++ b/sftp_provider_impl.h
304 @@ -0,0 +1,73 @@
305 +/*
306 + * CDDL HEADER START
307 + *
308 + * The contents of this file are subject to the terms of the
309 + * Common Development and Distribution License (the "License").
310 + * You may not use this file except in compliance with the License.
311 + *
312 + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
313 + * or http://www.opensolaris.org/os/licensing.
314 + * See the License for the specific language governing permissions
315 + * and limitations under the License.
316 + *
317 + * When distributing Covered Code, include this CDDL HEADER in each
318 + * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
319 + * If applicable, add the following below this CDDL HEADER, with the
320 + * fields enclosed by brackets "[]" replaced with your own identifying
321 + * information: Portions Copyright [yyyy] [name of copyright owner]
322 + *
323 + * CDDL HEADER END
324 + */
325 +/*
326 + * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
327 + */
328 +
329 +#ifndef _SFTP_PROVIDER_IMPL_H
330 +#define _SFTP_PROVIDER_IMPL_H
331 +
332 +#ifdef __cplusplus
333 +extern "C" {
334 +#endif
335 +
336 +/*
337 + * This structure must match the definition of same in sftp.d.
338 + */
339 +typedef struct sftpproto {
340 + int64_t sftp_nbytes; /* bytes writtten or read */
341 + const char *sftp_user; /* user name */
342 + const char *sftp_operation; /* SFTP Operation */
343 + const char *sftp_raddr; /* remote address */
344 + const char *sftp_pathname; /* path with file name */
345 + int32_t sftp_fd; /* fd for transfer, if any */
346 +} sftpproto_t;
347 +
348 +#define SFTP_TRANSFER_PROTO(proto, op, fd, path, len) \
349 + bzero((proto), sizeof (struct sftpproto)); \
350 + (proto)->sftp_user = (pw->pw_name ? pw->pw_name : "UNKNOWN"); \
351 + (proto)->sftp_operation = (op ? op : "UNKNOWN"); \
352 + (proto)->sftp_raddr = (client_addr); \
353 + (proto)->sftp_fd = (fd); \
354 + (proto)->sftp_pathname = (path ? path : "UNKNOWN"); \
355 + (proto)->sftp_nbytes = (len); \
356 +
357 +#define SFTP_TRANSFER_START_OP(op, fd, path, len) \
358 + if (SFTP_TRANSFER_START_ENABLED()) { \
359 + sftpproto_t proto; \
360 + SFTP_TRANSFER_PROTO(&proto, op, fd, path, len); \
361 + SFTP_TRANSFER_START(&proto); \
362 + } \
363 +
364 +#define SFTP_TRANSFER_DONE_OP(op, fd, path, len) \
365 + if (SFTP_TRANSFER_DONE_ENABLED()) { \
366 + sftpproto_t proto; \
367 + SFTP_TRANSFER_PROTO(&proto, op, fd, path, len); \
368 + SFTP_TRANSFER_DONE(&proto); \
369 + } \
370 +
371 +#include "sftp_provider.h"
372 +
373 +#ifdef __cplusplus
374 +}
375 +#endif
376 +
377 +#endif /* _SFTP_PROVIDER_IMPL_H */
378 --
379 2.5.4 (Apple Git-61)
380