From d0137ef83eaef1fbdd9745cfb3c75ea68aa0fa12 Mon Sep 17 00:00:00 2001 From: dtucker Date: Sun, 21 Jun 2009 08:53:53 +0000 Subject: [PATCH] - andreas@cvs.openbsd.org 2009/05/28 16:50:16 [sshd.c packet.c serverloop.c monitor_wrap.c clientloop.c sshconnect.c monitor.c Added roaming.h roaming_common.c roaming_dummy.c] Keep track of number of bytes read and written. Needed for upcoming changes. Most code from Martin Forssen, maf at appgate dot com. ok markus@ Also, applied appropriate changes to Makefile.in --- ChangeLog | 3 +- Makefile.in | 14 ++++--- clientloop.c | 9 +++-- monitor.c | 14 ++++++- monitor_wrap.c | 9 ++++- packet.c | 30 +++++++------- roaming.h | 31 +++++++++++++++ roaming_common.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++ roaming_dummy.c | 55 ++++++++++++++++++++++++++ serverloop.c | 8 +++- sshconnect.c | 8 ++-- sshd.c | 7 ++-- 12 files changed, 253 insertions(+), 35 deletions(-) create mode 100644 roaming.h create mode 100644 roaming_common.c create mode 100644 roaming_dummy.c diff --git a/ChangeLog b/ChangeLog index 2f73a6bc..8ed7db99 100644 --- a/ChangeLog +++ b/ChangeLog @@ -83,10 +83,11 @@ ok markus@ - andreas@cvs.openbsd.org 2009/05/28 16:50:16 [sshd.c packet.c serverloop.c monitor_wrap.c clientloop.c sshconnect.c - monitor.c] + monitor.c Added roaming.h roaming_common.c roaming_dummy.c] Keep track of number of bytes read and written. Needed for upcoming changes. Most code from Martin Forssen, maf at appgate dot com. ok markus@ + Also, applied appropriate changes to Makefile.in 20090616 - (dtucker) [configure.ac defines.h] Bug #1607: handle the case where fsid_t diff --git a/Makefile.in b/Makefile.in index ff2ed20c..4398c87f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -74,7 +74,8 @@ LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \ entropy.o scard-opensc.o gss-genr.o umac.o jpake.o schnorr.o SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ - sshconnect.o sshconnect1.o sshconnect2.o mux.o + sshconnect.o sshconnect1.o sshconnect2.o mux.o \ + roaming_common.o SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ sshpty.o sshlogin.o servconf.o serverloop.o \ @@ -86,7 +87,8 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ auth-krb5.o \ auth2-gss.o gss-serv.o gss-serv-krb5.o \ loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ - audit.o audit-bsm.o platform.o sftp-server.o sftp-common.o + audit.o audit-bsm.o platform.o sftp-server.o sftp-common.o \ + roaming_common.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-rand-helper.8.out ssh-keysign.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-rand-helper.8 ssh-keysign.8 sshd_config.5 ssh_config.5 @@ -151,11 +153,11 @@ ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o - $(LD) -o $@ ssh-keysign.o readconf.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) +ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o roaming_dummy.o + $(LD) -o $@ ssh-keysign.o readconf.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o - $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) +ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o + $(LD) -o $@ 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 $@ sftp-server.o sftp-common.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) diff --git a/clientloop.c b/clientloop.c index d5a06556..43f001bc 100644 --- a/clientloop.c +++ b/clientloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.c,v 1.211 2009/05/27 06:33:39 andreas Exp $ */ +/* $OpenBSD: clientloop.c,v 1.212 2009/05/28 16:50:16 andreas Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -109,6 +109,7 @@ #include "misc.h" #include "match.h" #include "msg.h" +#include "roaming.h" /* import options */ extern Options options; @@ -634,7 +635,7 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr) static void client_process_net_input(fd_set *readset) { - int len; + int len, cont = 0; char buf[8192]; /* @@ -643,8 +644,8 @@ client_process_net_input(fd_set *readset) */ if (FD_ISSET(connection_in, readset)) { /* Read as much as possible. */ - len = read(connection_in, buf, sizeof(buf)); - if (len == 0) { + len = roaming_read(connection_in, buf, sizeof(buf), &cont); + if (len == 0 && cont == 0) { /* * Received EOF. The remote host has closed the * connection. diff --git a/monitor.c b/monitor.c index 61242e6d..36a9e1dc 100644 --- a/monitor.c +++ b/monitor.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor.c,v 1.102 2009/05/25 06:48:01 andreas Exp $ */ +/* $OpenBSD: monitor.c,v 1.103 2009/05/28 16:50:16 andreas Exp $ */ /* * Copyright 2002 Niels Provos * Copyright 2002 Markus Friedl @@ -125,6 +125,8 @@ struct { u_int ilen; u_char *output; u_int olen; + u_int64_t sent_bytes; + u_int64_t recv_bytes; } child_state; /* Functions on the monitor that answer unprivileged requests */ @@ -1679,6 +1681,10 @@ monitor_apply_keystate(struct monitor *pmonitor) child_state.olen); memset(child_state.output, 0, child_state.olen); xfree(child_state.output); + + /* Roaming */ + if (compat20) + roam_set_bytes(child_state.sent_bytes, child_state.recv_bytes); } static Kex * @@ -1794,6 +1800,12 @@ mm_get_keystate(struct monitor *pmonitor) child_state.input = buffer_get_string(&m, &child_state.ilen); child_state.output = buffer_get_string(&m, &child_state.olen); + /* Roaming */ + if (compat20) { + child_state.sent_bytes = buffer_get_int64(&m); + child_state.recv_bytes = buffer_get_int64(&m); + } + buffer_free(&m); } diff --git a/monitor_wrap.c b/monitor_wrap.c index d71d4a8c..b696d782 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_wrap.c,v 1.66 2009/05/25 06:48:01 andreas Exp $ */ +/* $OpenBSD: monitor_wrap.c,v 1.67 2009/05/28 16:50:16 andreas Exp $ */ /* * Copyright 2002 Niels Provos * Copyright 2002 Markus Friedl @@ -77,6 +77,7 @@ #include "channels.h" #include "session.h" #include "servconf.h" +#include "roaming.h" /* Imports */ extern int compat20; @@ -660,6 +661,12 @@ mm_send_keystate(struct monitor *monitor) buffer_put_string(&m, buffer_ptr(input), buffer_len(input)); buffer_put_string(&m, buffer_ptr(output), buffer_len(output)); + /* Roaming */ + if (compat20) { + buffer_put_int64(&m, get_sent_bytes()); + buffer_put_int64(&m, get_recv_bytes()); + } + mm_request_send(monitor->m_recvfd, MONITOR_REQ_KEYEXPORT, &m); debug3("%s: Finished sending state", __func__); diff --git a/packet.c b/packet.c index cecab82e..f3f8389a 100644 --- a/packet.c +++ b/packet.c @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.c,v 1.162 2009/05/27 06:36:07 andreas Exp $ */ +/* $OpenBSD: packet.c,v 1.163 2009/05/28 16:50:16 andreas Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -77,6 +77,7 @@ #include "canohost.h" #include "misc.h" #include "ssh.h" +#include "roaming.h" #ifdef PACKET_DEBUG #define DBG(x) x @@ -1012,7 +1013,7 @@ packet_send(void) int packet_read_seqnr(u_int32_t *seqnr_p) { - int type, len, ret, ms_remain; + int type, len, ret, ms_remain, cont; fd_set *setp; char buf[8192]; struct timeval timeout, start, *timeoutp = NULL; @@ -1061,8 +1062,7 @@ packet_read_seqnr(u_int32_t *seqnr_p) if ((ret = select(active_state->connection_in + 1, setp, NULL, NULL, timeoutp)) >= 0) break; - if (errno != EAGAIN && errno != EINTR && - errno != EWOULDBLOCK) + if (errno != EAGAIN && errno != EINTR) break; if (active_state->packet_timeout_ms == -1) continue; @@ -1078,7 +1078,11 @@ packet_read_seqnr(u_int32_t *seqnr_p) cleanup_exit(255); } /* Read data from the socket. */ - len = read(active_state->connection_in, buf, sizeof(buf)); + do { + cont = 0; + len = roaming_read(active_state->connection_in, buf, + sizeof(buf), &cont); + } while (len == 0 && cont); if (len == 0) { logit("Connection closed by %.200s", get_remote_ipaddr()); cleanup_exit(255); @@ -1624,23 +1628,23 @@ void packet_write_poll(void) { int len = buffer_len(&active_state->output); + int cont; if (len > 0) { - len = write(active_state->connection_out, - buffer_ptr(&active_state->output), len); + cont = 0; + len = roaming_write(active_state->connection_out, + buffer_ptr(&active_state->output), len, &cont); if (len == -1) { - if (errno == EINTR || errno == EAGAIN || - errno == EWOULDBLOCK) + if (errno == EINTR || errno == EAGAIN) return; fatal("Write failed: %.100s", strerror(errno)); } - if (len == 0) + if (len == 0 && !cont) fatal("Write connection closed"); buffer_consume(&active_state->output, len); } } - /* * Calls packet_write_poll repeatedly until all pending output data has been * written. @@ -1673,8 +1677,7 @@ packet_write_wait(void) if ((ret = select(active_state->connection_out + 1, NULL, setp, NULL, timeoutp)) >= 0) break; - if (errno != EAGAIN && errno != EINTR && - errno != EWOULDBLOCK) + if (errno != EAGAIN && errno != EINTR) break; if (active_state->packet_timeout_ms == -1) continue; @@ -1713,7 +1716,6 @@ packet_not_very_much_data_to_write(void) return buffer_len(&active_state->output) < 128 * 1024; } - static void packet_set_tos(int interactive) { diff --git a/roaming.h b/roaming.h new file mode 100644 index 00000000..88193453 --- /dev/null +++ b/roaming.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2004-2009 AppGate Network Security AB + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef ROAMING_H +#define ROAMING_H + +extern int resume_in_progress; + +void add_recv_bytes(u_int64_t); +ssize_t roaming_write(int, const void *, size_t, int *); +ssize_t roaming_read(int, void *, size_t, int *); +ssize_t roaming_atomicio(ssize_t (*)(int, void *, size_t), int, void *, size_t); +u_int64_t get_recv_bytes(void); +u_int64_t get_sent_bytes(void); +void roam_set_bytes(u_int64_t, u_int64_t); +int resume_kex(void); + +#endif /* ROAMING */ diff --git a/roaming_common.c b/roaming_common.c new file mode 100644 index 00000000..5a871b23 --- /dev/null +++ b/roaming_common.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2004-2009 AppGate Network Security AB + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include "atomicio.h" +#include "log.h" +#include "packet.h" +#include "xmalloc.h" +#include "cipher.h" +#include "buffer.h" +#include "roaming.h" + +static u_int64_t write_bytes = 0; +static u_int64_t read_bytes = 0; + +int resume_in_progress = 0; + +u_int64_t +get_recv_bytes(void) +{ + return read_bytes; +} + +void +add_recv_bytes(u_int64_t num) +{ + read_bytes += num; +} + +u_int64_t +get_sent_bytes(void) +{ + return write_bytes; +} + +void +roam_set_bytes(u_int64_t sent, u_int64_t recv) +{ + read_bytes = recv; + write_bytes = sent; +} + +ssize_t +roaming_write(int fd, const void *buf, size_t count, int *cont) +{ + ssize_t ret; + + ret = write(fd, buf, count); + if (ret > 0 && !resume_in_progress) { + write_bytes += ret; + } + debug("Wrote %d bytes for a total of %lld", ret, write_bytes); + return ret; +} + +ssize_t +roaming_read(int fd, void *buf, size_t count, int *cont) +{ + ssize_t ret = read(fd, buf, count); + if (ret > 0) { + if (!resume_in_progress) { + read_bytes += ret; + } + } + return ret; +} + +ssize_t +roaming_atomicio(ssize_t(*f)(), int fd, void *buf, size_t count) +{ + ssize_t ret = atomicio(f, fd, buf, count); + + if ((f == write || f == vwrite) && ret > 0 && !resume_in_progress) { + write_bytes += ret; + } else if (f == read && ret > 0 && !resume_in_progress) { + read_bytes += ret; + } + return ret; +} diff --git a/roaming_dummy.c b/roaming_dummy.c new file mode 100644 index 00000000..cd1d2025 --- /dev/null +++ b/roaming_dummy.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2004-2009 AppGate Network Security AB + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file is included in the client programs which should not + * support roaming. + */ + +#include +#include + +int resume_in_progress = 0; + +u_int64_t get_recv_bytes() +{ + return 0; +} + +ssize_t +roaming_write(int fd, const void *buf, size_t count, int *cont) +{ + return write(fd, buf, count); +} + +ssize_t +roaming_read(int fd, void *buf, size_t count, int *cont) +{ + if (cont) + *cont = 0; + return read(fd, buf, count); +} + +void +add_recv_bytes(u_int64_t num) +{ +} + +int +resume_kex() +{ + return 1; +} diff --git a/serverloop.c b/serverloop.c index 53cb67d7..d8cb54bc 100644 --- a/serverloop.c +++ b/serverloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: serverloop.c,v 1.158 2009/05/25 06:48:01 andreas Exp $ */ +/* $OpenBSD: serverloop.c,v 1.159 2009/05/28 16:50:16 andreas Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -78,6 +78,7 @@ #include "auth-options.h" #include "serverloop.h" #include "misc.h" +#include "roaming.h" extern ServerOptions options; @@ -391,8 +392,11 @@ process_input(fd_set *readset) /* Read and buffer any input data from the client. */ if (FD_ISSET(connection_in, readset)) { - len = read(connection_in, buf, sizeof(buf)); + int cont = 0; + len = roaming_read(connection_in, buf, sizeof(buf), &cont); if (len == 0) { + if (cont) + return; verbose("Connection closed by %.100s", get_remote_ipaddr()); connection_closed = 1; diff --git a/sshconnect.c b/sshconnect.c index dee3ba54..3e57e859 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.c,v 1.213 2009/05/27 06:38:16 andreas Exp $ */ +/* $OpenBSD: sshconnect.c,v 1.214 2009/05/28 16:50:16 andreas Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -56,6 +56,7 @@ #include "atomicio.h" #include "misc.h" #include "dns.h" +#include "roaming.h" #include "version.h" char *client_version_string = NULL; @@ -452,7 +453,7 @@ ssh_exchange_identification(int timeout_ms) } } - len = atomicio(read, connection_in, &buf[i], 1); + len = roaming_atomicio(read, connection_in, &buf[i], 1); if (len != 1 && errno == EPIPE) fatal("ssh_exchange_identification: " @@ -537,7 +538,8 @@ ssh_exchange_identification(int timeout_ms) compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1, compat20 ? PROTOCOL_MINOR_2 : minor1, SSH_VERSION, compat20 ? "\r\n" : "\n"); - if (atomicio(vwrite, connection_out, buf, strlen(buf)) != strlen(buf)) + if (roaming_atomicio(vwrite, connection_out, buf, strlen(buf)) + != strlen(buf)) fatal("write: %.100s", strerror(errno)); client_version_string = xstrdup(buf); chop(client_version_string); diff --git a/sshd.c b/sshd.c index 3b5cd3cf..91831e20 100644 --- a/sshd.c +++ b/sshd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshd.c,v 1.366 2009/01/22 10:02:34 djm Exp $ */ +/* $OpenBSD: sshd.c,v 1.367 2009/05/28 16:50:16 andreas Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -117,6 +117,7 @@ #include "ssh-gss.h" #endif #include "monitor_wrap.h" +#include "roaming.h" #include "version.h" #ifdef LIBWRAP @@ -419,7 +420,7 @@ sshd_exchange_identification(int sock_in, int sock_out) server_version_string = xstrdup(buf); /* Send our protocol version identification. */ - if (atomicio(vwrite, sock_out, server_version_string, + if (roaming_atomicio(vwrite, sock_out, server_version_string, strlen(server_version_string)) != strlen(server_version_string)) { logit("Could not write ident string to %s", get_remote_ipaddr()); @@ -429,7 +430,7 @@ sshd_exchange_identification(int sock_in, int sock_out) /* Read other sides version identification. */ memset(buf, 0, sizeof(buf)); for (i = 0; i < sizeof(buf) - 1; i++) { - if (atomicio(read, sock_in, &buf[i], 1) != 1) { + if (roaming_atomicio(read, sock_in, &buf[i], 1) != 1) { logit("Did not receive identification string from %s", get_remote_ipaddr()); cleanup_exit(255); -- 2.45.1