From 8cbd403fde20dda880a7ff3262bf2c36f6582eac Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 19:13:25 +1100 Subject: - (dtucker) [Makefile.in added roaming_client.c roaming_serv.c] Import new files for roaming and add to Makefile. --- roaming_client.c | 276 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 276 insertions(+) create mode 100644 roaming_client.c (limited to 'roaming_client.c') diff --git a/roaming_client.c b/roaming_client.c new file mode 100644 index 000000000..b77dbd59b --- /dev/null +++ b/roaming_client.c @@ -0,0 +1,276 @@ +/* $OpenBSD: roaming_client.c,v 1.1 2009/10/24 11:22:37 andreas Exp $ */ +/* + * 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 +#include + +#include "xmalloc.h" +#include "buffer.h" +#include "channels.h" +#include "cipher.h" +#include "dispatch.h" +#include "clientloop.h" +#include "log.h" +#include "match.h" +#include "misc.h" +#include "packet.h" +#include "ssh.h" +#include "key.h" +#include "kex.h" +#include "readconf.h" +#include "roaming.h" +#include "ssh2.h" +#include "sshconnect.h" + +/* import */ +extern Options options; +extern char *host; +extern struct sockaddr_storage hostaddr; +extern int session_resumed; + +static u_int32_t roaming_id; +static u_int64_t cookie; +static u_int64_t lastseenchall; +static u_int64_t key1, key2, oldkey1, oldkey2; + +void +roaming_reply(int type, u_int32_t seq, void *ctxt) +{ + if (type == SSH2_MSG_REQUEST_FAILURE) { + logit("Server denied roaming"); + return; + } + verbose("Roaming enabled"); + roaming_id = packet_get_int(); + cookie = packet_get_int64(); + key1 = oldkey1 = packet_get_int64(); + key2 = oldkey2 = packet_get_int64(); + set_out_buffer_size(packet_get_int() + get_snd_buf_size()); + roaming_enabled = 1; +} + +void +request_roaming(void) +{ + packet_start(SSH2_MSG_GLOBAL_REQUEST); + packet_put_cstring(ROAMING_REQUEST); + packet_put_char(1); + packet_put_int(get_recv_buf_size()); + packet_send(); + client_register_global_confirm(roaming_reply, NULL); +} + +static void +roaming_auth_required(void) +{ + u_char digest[SHA_DIGEST_LENGTH]; + EVP_MD_CTX md; + Buffer b; + const EVP_MD *evp_md = EVP_sha1(); + u_int64_t chall, oldchall; + + chall = packet_get_int64(); + oldchall = packet_get_int64(); + if (oldchall != lastseenchall) { + key1 = oldkey1; + key2 = oldkey2; + } + lastseenchall = chall; + + buffer_init(&b); + buffer_put_int64(&b, cookie); + buffer_put_int64(&b, chall); + EVP_DigestInit(&md, evp_md); + EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); + EVP_DigestFinal(&md, digest, NULL); + buffer_free(&b); + + packet_start(SSH2_MSG_KEX_ROAMING_AUTH); + packet_put_int64(key1 ^ get_recv_bytes()); + packet_put_raw(digest, sizeof(digest)); + packet_send(); + + oldkey1 = key1; + oldkey2 = key2; + calculate_new_key(&key1, cookie, chall); + calculate_new_key(&key2, cookie, chall); + + debug("Received %" PRIu64 " bytes", get_recv_bytes()); + debug("Sent roaming_auth packet"); +} + +int +resume_kex(void) +{ + /* + * This should not happen - if the client sends the kex method + * resume@appgate.com then the kex is done in roaming_resume(). + */ + return 1; +} + +static int +roaming_resume(void) +{ + u_int64_t recv_bytes; + char *str = NULL, *kexlist = NULL, *c; + int i, type; + int timeout_ms = options.connection_timeout * 1000; + u_int len; + u_int32_t rnd = 0; + + resume_in_progress = 1; + + /* Exchange banners */ + ssh_exchange_identification(timeout_ms); + packet_set_nonblocking(); + + /* Send a kexinit message with resume@appgate.com as only kex algo */ + packet_start(SSH2_MSG_KEXINIT); + for (i = 0; i < KEX_COOKIE_LEN; i++) { + if (i % 4 == 0) + rnd = arc4random(); + packet_put_char(rnd & 0xff); + rnd >>= 8; + } + packet_put_cstring(KEX_RESUME); + for (i = 1; i < PROPOSAL_MAX; i++) { + /* kex algorithm added so start with i=1 and not 0 */ + packet_put_cstring(""); /* Not used when we resume */ + } + packet_put_char(1); /* first kex_packet follows */ + packet_put_int(0); /* reserved */ + packet_send(); + + /* Assume that resume@appgate.com will be accepted */ + packet_start(SSH2_MSG_KEX_ROAMING_RESUME); + packet_put_int(roaming_id); + packet_send(); + + /* Read the server's kexinit and check for resume@appgate.com */ + if ((type = packet_read()) != SSH2_MSG_KEXINIT) { + debug("expected kexinit on resume, got %d", type); + goto fail; + } + for (i = 0; i < KEX_COOKIE_LEN; i++) + (void)packet_get_char(); + kexlist = packet_get_string(&len); + if (!kexlist + || (str = match_list(KEX_RESUME, kexlist, NULL)) == NULL) { + debug("server doesn't allow resume"); + goto fail; + } + xfree(str); + for (i = 1; i < PROPOSAL_MAX; i++) { + /* kex algorithm taken care of so start with i=1 and not 0 */ + xfree(packet_get_string(&len)); + } + i = packet_get_char(); /* first_kex_packet_follows */ + if (i && (c = strchr(kexlist, ','))) + *c = 0; + if (i && strcmp(kexlist, KEX_RESUME)) { + debug("server's kex guess (%s) was wrong, skipping", kexlist); + (void)packet_read(); /* Wrong guess - discard packet */ + } + + /* + * Read the ROAMING_AUTH_REQUIRED challenge from the server and + * send ROAMING_AUTH + */ + if ((type = packet_read()) != SSH2_MSG_KEX_ROAMING_AUTH_REQUIRED) { + debug("expected roaming_auth_required, got %d", type); + goto fail; + } + roaming_auth_required(); + + /* Read ROAMING_AUTH_OK from the server */ + if ((type = packet_read()) != SSH2_MSG_KEX_ROAMING_AUTH_OK) { + debug("expected roaming_auth_ok, got %d", type); + goto fail; + } + recv_bytes = packet_get_int64() ^ oldkey2; + debug("Peer received %" PRIu64 " bytes", recv_bytes); + resend_bytes(packet_get_connection_out(), &recv_bytes); + + resume_in_progress = 0; + + session_resumed = 1; /* Tell clientloop */ + + return 0; + +fail: + if (kexlist) + xfree(kexlist); + if (packet_get_connection_in() == packet_get_connection_out()) + close(packet_get_connection_in()); + else { + close(packet_get_connection_in()); + close(packet_get_connection_out()); + } + return 1; +} + +int +wait_for_roaming_reconnect(void) +{ + static int reenter_guard = 0; + int timeout_ms = options.connection_timeout * 1000; + int c; + + if (reenter_guard != 0) + fatal("Server refused resume, roaming timeout may be exceeded"); + reenter_guard = 1; + + fprintf(stderr, "[connection suspended, press return to resume]"); + fflush(stderr); + packet_backup_state(); + /* TODO Perhaps we should read from tty here */ + while ((c = fgetc(stdin)) != EOF) { + if (c == 'Z' - 64) { + kill(getpid(), SIGTSTP); + continue; + } + if (c != '\n' && c != '\r') + continue; + + if (ssh_connect(host, &hostaddr, options.port, + options.address_family, 1, &timeout_ms, + options.tcp_keep_alive, options.use_privileged_port, + options.proxy_command) == 0 && roaming_resume() == 0) { + packet_restore_state(); + reenter_guard = 0; + fprintf(stderr, "[connection resumed]\n"); + fflush(stderr); + return 0; + } + + fprintf(stderr, "[reconnect failed, press return to retry]"); + fflush(stderr); + } + fprintf(stderr, "[exiting]\n"); + fflush(stderr); + exit(0); +} -- cgit v1.2.3 From cb5a1b6f7028dc3e3bf9f5875aee4a071eefe359 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 20:09:01 +1100 Subject: - (dtucker] [misc.c] Shrink the area covered by USE_ROUTINGDOMAIN more to eliminate an unused variable warning. --- ChangeLog | 2 ++ misc.c | 6 ++---- roaming_client.c | 2 ++ 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'roaming_client.c') diff --git a/ChangeLog b/ChangeLog index 8266723e8..adb52db3a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -165,6 +165,8 @@ too. - (dtucker) [misc.c] Move the routingdomain ifdef to allow the socket to be created. + - (dtucker] [misc.c] Shrink the area covered by USE_ROUTINGDOMAIN more + to eliminate an unused variable warning. 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/misc.c b/misc.c index 08a80226d..f62f8efc6 100644 --- a/misc.c +++ b/misc.c @@ -163,12 +163,12 @@ socket_rdomain(int domain, int type, int protocol, int rdomain) if (rdomain == -1) return (sock); -#ifdef USE_ROUTINGDOMAIN switch (domain) { case AF_INET6: ipproto = IPPROTO_IPV6; /* FALLTHROUGH */ case AF_INET: +#ifdef USE_ROUTINGDOMAIN debug2("socket %d af %d setting rdomain %d", sock, domain, rdomain); if (setsockopt(sock, ipproto, SO_RDOMAIN, &rdomain, @@ -178,6 +178,7 @@ socket_rdomain(int domain, int type, int protocol, int rdomain) close(sock); return (-1); } +#endif break; default: debug("socket %d af %d does not support rdomain %d", @@ -187,9 +188,6 @@ socket_rdomain(int domain, int type, int protocol, int rdomain) } return (sock); -#else - return (-1); -#endif } /* Characters considered whitespace in strsep calls. */ diff --git a/roaming_client.c b/roaming_client.c index b77dbd59b..cfa57f613 100644 --- a/roaming_client.c +++ b/roaming_client.c @@ -15,6 +15,8 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "includes.h" + #include #include #include -- cgit v1.2.3 From 11b5c07941f206d955184ff1e4c1ff6fba37d157 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 9 Jan 2010 16:40:48 +1100 Subject: - (dtucker) [roaming_client.c] Wrap inttypes.h in an ifdef. --- ChangeLog | 1 + roaming_client.c | 2 ++ 2 files changed, 3 insertions(+) (limited to 'roaming_client.c') diff --git a/ChangeLog b/ChangeLog index 65bbdd6bc..9e8b41017 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,7 @@ - (dtucker) Wrap use of IPPROTO_IPV6 in an ifdef for platforms that don't have it. - (dtucker) [defines.h] define PRIu64 for platforms that don't have it. + - (dtucker) [roaming_client.c] Wrap inttypes.h in an ifdef. 20091208 - (dtucker) OpenBSD CVS Sync diff --git a/roaming_client.c b/roaming_client.c index cfa57f613..c80db5826 100644 --- a/roaming_client.c +++ b/roaming_client.c @@ -21,7 +21,9 @@ #include #include +#ifdef HAVE_INTTYPES_H #include +#endif #include #include #include -- cgit v1.2.3 From 4b28251df4f1b653e7b3e015138c3da53a05bd58 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 9 Jan 2010 22:27:06 +1100 Subject: - dtucker@cvs.openbsd.org 2010/01/09 05:17:00 [roaming_client.c] Remove a PRIu64 format string that snuck in with roaming. ok djm@ --- ChangeLog | 3 +++ roaming_client.c | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'roaming_client.c') diff --git a/ChangeLog b/ChangeLog index b3ae6bdb4..9eda2f396 100644 --- a/ChangeLog +++ b/ChangeLog @@ -20,6 +20,9 @@ [mux.c sshpty.h clientloop.c sshtty.c] quell tc[gs]etattr warnings when forcing a tty (ssh -tt), since we usually don't actually have a tty to read/set; bz#1686 ok dtucker@ + - dtucker@cvs.openbsd.org 2010/01/09 05:17:00 + [roaming_client.c] + Remove a PRIu64 format string that snuck in with roaming. ok djm@ 20091208 - (dtucker) OpenBSD CVS Sync diff --git a/roaming_client.c b/roaming_client.c index c80db5826..cc387a544 100644 --- a/roaming_client.c +++ b/roaming_client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: roaming_client.c,v 1.1 2009/10/24 11:22:37 andreas Exp $ */ +/* $OpenBSD: roaming_client.c,v 1.2 2010/01/09 05:17:00 dtucker Exp $ */ /* * Copyright (c) 2004-2009 AppGate Network Security AB * @@ -122,7 +122,7 @@ roaming_auth_required(void) calculate_new_key(&key1, cookie, chall); calculate_new_key(&key2, cookie, chall); - debug("Received %" PRIu64 " bytes", get_recv_bytes()); + debug("Received %llu bytes", (long long unsigned)get_recv_bytes()); debug("Sent roaming_auth packet"); } @@ -216,7 +216,7 @@ roaming_resume(void) goto fail; } recv_bytes = packet_get_int64() ^ oldkey2; - debug("Peer received %" PRIu64 " bytes", recv_bytes); + debug("Peer received %llu bytes", (long long unsigned)recv_bytes); resend_bytes(packet_get_connection_out(), &recv_bytes); resume_in_progress = 0; -- cgit v1.2.3 From f37756759fef9ad9a65080424f50cbcfdbc6e512 Mon Sep 17 00:00:00 2001 From: Tim Rice Date: Sat, 16 Jan 2010 16:48:39 -0800 Subject: - (tim) [roaming_client.c] Use of is not really portable so we use "openbsd-compat/sys-queue.h" --- ChangeLog | 2 ++ roaming_client.c | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'roaming_client.c') diff --git a/ChangeLog b/ChangeLog index 00d78c698..145955680 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,8 @@ - (tim) [regress/portnum.sh] Shell portability fix. - (tim) [configure.ac] Define BROKEN_GETADDRINFO on SVR5 systems. The native getaddrinfo() is too old and limited for addr_pton() in addrmatch.c. + - (tim) [roaming_client.c] Use of is not really portable so + we use "openbsd-compat/sys-queue.h" 20100115 - (dtucker) OpenBSD CVS Sync diff --git a/roaming_client.c b/roaming_client.c index cc387a544..c0dd9ea9c 100644 --- a/roaming_client.c +++ b/roaming_client.c @@ -17,7 +17,7 @@ #include "includes.h" -#include +#include "openbsd-compat/sys-queue.h" #include #include @@ -122,7 +122,7 @@ roaming_auth_required(void) calculate_new_key(&key1, cookie, chall); calculate_new_key(&key2, cookie, chall); - debug("Received %llu bytes", (long long unsigned)get_recv_bytes()); + debug("Received %llu bytes", (unsigned long long)get_recv_bytes()); debug("Sent roaming_auth packet"); } @@ -216,7 +216,7 @@ roaming_resume(void) goto fail; } recv_bytes = packet_get_int64() ^ oldkey2; - debug("Peer received %llu bytes", (long long unsigned)recv_bytes); + debug("Peer received %llu bytes", (unsigned long long)recv_bytes); resend_bytes(packet_get_connection_out(), &recv_bytes); resume_in_progress = 0; -- cgit v1.2.3 From f589fd1ea8c352e6bf819733ecd505119a694c51 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Tue, 26 Jan 2010 12:53:06 +1100 Subject: - dtucker@cvs.openbsd.org 2010/01/18 01:50:27 [roaming_client.c] s/long long unsigned/unsigned long long/, from tim via portable (Id sync only, change already in portable) --- ChangeLog | 4 ++++ roaming_client.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'roaming_client.c') diff --git a/ChangeLog b/ChangeLog index 569a2d0a4..4334f6768 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,10 @@ [ssh-agent.1] Correct and clarify ssh-add's password asking behavior. Improved text dtucker and ok jmc + - dtucker@cvs.openbsd.org 2010/01/18 01:50:27 + [roaming_client.c] + s/long long unsigned/unsigned long long/, from tim via portable + (Id sync only, change already in portable) 20100122 - (tim) [configure.ac] Due to constraints in Windows Sockets in terms of diff --git a/roaming_client.c b/roaming_client.c index c0dd9ea9c..cea8e7360 100644 --- a/roaming_client.c +++ b/roaming_client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: roaming_client.c,v 1.2 2010/01/09 05:17:00 dtucker Exp $ */ +/* $OpenBSD: roaming_client.c,v 1.3 2010/01/18 01:50:27 dtucker Exp $ */ /* * Copyright (c) 2004-2009 AppGate Network Security AB * -- cgit v1.2.3