summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog2
-rw-r--r--Makefile.in6
-rw-r--r--roaming_client.c276
-rw-r--r--roaming_serv.c29
4 files changed, 310 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 05b99b160..dbe3c0c92 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -154,6 +154,8 @@
154 [sftp-server.c] 154 [sftp-server.c]
155 bz#1566 don't unnecessarily dup() in and out fds for sftp-server; 155 bz#1566 don't unnecessarily dup() in and out fds for sftp-server;
156 ok markus@ 156 ok markus@
157 - (dtucker) [Makefile.in added roaming_client.c roaming_serv.c] Import new
158 files for roaming and add to Makefile.
157 159
15820091226 16020091226
159 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 161 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1
diff --git a/Makefile.in b/Makefile.in
index da66311d0..a16782dff 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,4 +1,4 @@
1# $Id: Makefile.in,v 1.301 2009/10/02 01:50:55 djm Exp $ 1# $Id: Makefile.in,v 1.302 2010/01/08 08:13:25 dtucker Exp $
2 2
3# uncomment if you run a non bourne compatable shell. Ie. csh 3# uncomment if you run a non bourne compatable shell. Ie. csh
4#SHELL = @SH@ 4#SHELL = @SH@
@@ -75,7 +75,7 @@ LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \
75 75
76SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ 76SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
77 sshconnect.o sshconnect1.o sshconnect2.o mux.o \ 77 sshconnect.o sshconnect1.o sshconnect2.o mux.o \
78 roaming_common.o 78 roaming_common.o roaming_client.c
79 79
80SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ 80SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
81 sshpty.o sshlogin.o servconf.o serverloop.o \ 81 sshpty.o sshlogin.o servconf.o serverloop.o \
@@ -88,7 +88,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
88 auth2-gss.o gss-serv.o gss-serv-krb5.o \ 88 auth2-gss.o gss-serv.o gss-serv-krb5.o \
89 loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ 89 loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \
90 audit.o audit-bsm.o platform.o sftp-server.o sftp-common.o \ 90 audit.o audit-bsm.o platform.o sftp-server.o sftp-common.o \
91 roaming_common.o 91 roaming_common.o roaming_serv.c
92 92
93MANPAGES = 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 93MANPAGES = 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
94MANPAGES_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 94MANPAGES_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
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 @@
1/* $OpenBSD: roaming_client.c,v 1.1 2009/10/24 11:22:37 andreas Exp $ */
2/*
3 * Copyright (c) 2004-2009 AppGate Network Security AB
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <sys/queue.h>
19#include <sys/types.h>
20#include <sys/socket.h>
21
22#include <inttypes.h>
23#include <signal.h>
24#include <string.h>
25#include <unistd.h>
26
27#include <openssl/crypto.h>
28#include <openssl/sha.h>
29
30#include "xmalloc.h"
31#include "buffer.h"
32#include "channels.h"
33#include "cipher.h"
34#include "dispatch.h"
35#include "clientloop.h"
36#include "log.h"
37#include "match.h"
38#include "misc.h"
39#include "packet.h"
40#include "ssh.h"
41#include "key.h"
42#include "kex.h"
43#include "readconf.h"
44#include "roaming.h"
45#include "ssh2.h"
46#include "sshconnect.h"
47
48/* import */
49extern Options options;
50extern char *host;
51extern struct sockaddr_storage hostaddr;
52extern int session_resumed;
53
54static u_int32_t roaming_id;
55static u_int64_t cookie;
56static u_int64_t lastseenchall;
57static u_int64_t key1, key2, oldkey1, oldkey2;
58
59void
60roaming_reply(int type, u_int32_t seq, void *ctxt)
61{
62 if (type == SSH2_MSG_REQUEST_FAILURE) {
63 logit("Server denied roaming");
64 return;
65 }
66 verbose("Roaming enabled");
67 roaming_id = packet_get_int();
68 cookie = packet_get_int64();
69 key1 = oldkey1 = packet_get_int64();
70 key2 = oldkey2 = packet_get_int64();
71 set_out_buffer_size(packet_get_int() + get_snd_buf_size());
72 roaming_enabled = 1;
73}
74
75void
76request_roaming(void)
77{
78 packet_start(SSH2_MSG_GLOBAL_REQUEST);
79 packet_put_cstring(ROAMING_REQUEST);
80 packet_put_char(1);
81 packet_put_int(get_recv_buf_size());
82 packet_send();
83 client_register_global_confirm(roaming_reply, NULL);
84}
85
86static void
87roaming_auth_required(void)
88{
89 u_char digest[SHA_DIGEST_LENGTH];
90 EVP_MD_CTX md;
91 Buffer b;
92 const EVP_MD *evp_md = EVP_sha1();
93 u_int64_t chall, oldchall;
94
95 chall = packet_get_int64();
96 oldchall = packet_get_int64();
97 if (oldchall != lastseenchall) {
98 key1 = oldkey1;
99 key2 = oldkey2;
100 }
101 lastseenchall = chall;
102
103 buffer_init(&b);
104 buffer_put_int64(&b, cookie);
105 buffer_put_int64(&b, chall);
106 EVP_DigestInit(&md, evp_md);
107 EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
108 EVP_DigestFinal(&md, digest, NULL);
109 buffer_free(&b);
110
111 packet_start(SSH2_MSG_KEX_ROAMING_AUTH);
112 packet_put_int64(key1 ^ get_recv_bytes());
113 packet_put_raw(digest, sizeof(digest));
114 packet_send();
115
116 oldkey1 = key1;
117 oldkey2 = key2;
118 calculate_new_key(&key1, cookie, chall);
119 calculate_new_key(&key2, cookie, chall);
120
121 debug("Received %" PRIu64 " bytes", get_recv_bytes());
122 debug("Sent roaming_auth packet");
123}
124
125int
126resume_kex(void)
127{
128 /*
129 * This should not happen - if the client sends the kex method
130 * resume@appgate.com then the kex is done in roaming_resume().
131 */
132 return 1;
133}
134
135static int
136roaming_resume(void)
137{
138 u_int64_t recv_bytes;
139 char *str = NULL, *kexlist = NULL, *c;
140 int i, type;
141 int timeout_ms = options.connection_timeout * 1000;
142 u_int len;
143 u_int32_t rnd = 0;
144
145 resume_in_progress = 1;
146
147 /* Exchange banners */
148 ssh_exchange_identification(timeout_ms);
149 packet_set_nonblocking();
150
151 /* Send a kexinit message with resume@appgate.com as only kex algo */
152 packet_start(SSH2_MSG_KEXINIT);
153 for (i = 0; i < KEX_COOKIE_LEN; i++) {
154 if (i % 4 == 0)
155 rnd = arc4random();
156 packet_put_char(rnd & 0xff);
157 rnd >>= 8;
158 }
159 packet_put_cstring(KEX_RESUME);
160 for (i = 1; i < PROPOSAL_MAX; i++) {
161 /* kex algorithm added so start with i=1 and not 0 */
162 packet_put_cstring(""); /* Not used when we resume */
163 }
164 packet_put_char(1); /* first kex_packet follows */
165 packet_put_int(0); /* reserved */
166 packet_send();
167
168 /* Assume that resume@appgate.com will be accepted */
169 packet_start(SSH2_MSG_KEX_ROAMING_RESUME);
170 packet_put_int(roaming_id);
171 packet_send();
172
173 /* Read the server's kexinit and check for resume@appgate.com */
174 if ((type = packet_read()) != SSH2_MSG_KEXINIT) {
175 debug("expected kexinit on resume, got %d", type);
176 goto fail;
177 }
178 for (i = 0; i < KEX_COOKIE_LEN; i++)
179 (void)packet_get_char();
180 kexlist = packet_get_string(&len);
181 if (!kexlist
182 || (str = match_list(KEX_RESUME, kexlist, NULL)) == NULL) {
183 debug("server doesn't allow resume");
184 goto fail;
185 }
186 xfree(str);
187 for (i = 1; i < PROPOSAL_MAX; i++) {
188 /* kex algorithm taken care of so start with i=1 and not 0 */
189 xfree(packet_get_string(&len));
190 }
191 i = packet_get_char(); /* first_kex_packet_follows */
192 if (i && (c = strchr(kexlist, ',')))
193 *c = 0;
194 if (i && strcmp(kexlist, KEX_RESUME)) {
195 debug("server's kex guess (%s) was wrong, skipping", kexlist);
196 (void)packet_read(); /* Wrong guess - discard packet */
197 }
198
199 /*
200 * Read the ROAMING_AUTH_REQUIRED challenge from the server and
201 * send ROAMING_AUTH
202 */
203 if ((type = packet_read()) != SSH2_MSG_KEX_ROAMING_AUTH_REQUIRED) {
204 debug("expected roaming_auth_required, got %d", type);
205 goto fail;
206 }
207 roaming_auth_required();
208
209 /* Read ROAMING_AUTH_OK from the server */
210 if ((type = packet_read()) != SSH2_MSG_KEX_ROAMING_AUTH_OK) {
211 debug("expected roaming_auth_ok, got %d", type);
212 goto fail;
213 }
214 recv_bytes = packet_get_int64() ^ oldkey2;
215 debug("Peer received %" PRIu64 " bytes", recv_bytes);
216 resend_bytes(packet_get_connection_out(), &recv_bytes);
217
218 resume_in_progress = 0;
219
220 session_resumed = 1; /* Tell clientloop */
221
222 return 0;
223
224fail:
225 if (kexlist)
226 xfree(kexlist);
227 if (packet_get_connection_in() == packet_get_connection_out())
228 close(packet_get_connection_in());
229 else {
230 close(packet_get_connection_in());
231 close(packet_get_connection_out());
232 }
233 return 1;
234}
235
236int
237wait_for_roaming_reconnect(void)
238{
239 static int reenter_guard = 0;
240 int timeout_ms = options.connection_timeout * 1000;
241 int c;
242
243 if (reenter_guard != 0)
244 fatal("Server refused resume, roaming timeout may be exceeded");
245 reenter_guard = 1;
246
247 fprintf(stderr, "[connection suspended, press return to resume]");
248 fflush(stderr);
249 packet_backup_state();
250 /* TODO Perhaps we should read from tty here */
251 while ((c = fgetc(stdin)) != EOF) {
252 if (c == 'Z' - 64) {
253 kill(getpid(), SIGTSTP);
254 continue;
255 }
256 if (c != '\n' && c != '\r')
257 continue;
258
259 if (ssh_connect(host, &hostaddr, options.port,
260 options.address_family, 1, &timeout_ms,
261 options.tcp_keep_alive, options.use_privileged_port,
262 options.proxy_command) == 0 && roaming_resume() == 0) {
263 packet_restore_state();
264 reenter_guard = 0;
265 fprintf(stderr, "[connection resumed]\n");
266 fflush(stderr);
267 return 0;
268 }
269
270 fprintf(stderr, "[reconnect failed, press return to retry]");
271 fflush(stderr);
272 }
273 fprintf(stderr, "[exiting]\n");
274 fflush(stderr);
275 exit(0);
276}
diff --git a/roaming_serv.c b/roaming_serv.c
new file mode 100644
index 000000000..65e9fe631
--- /dev/null
+++ b/roaming_serv.c
@@ -0,0 +1,29 @@
1/* $OpenBSD: roaming_serv.c,v 1.1 2009/10/24 11:18:23 andreas Exp $ */
2/*
3 * Copyright (c) 2004-2009 AppGate Network Security AB
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <sys/types.h>
19
20#include "roaming.h"
21
22/*
23 * Wait for the roaming client to reconnect. Returns 0 if a connect ocurred.
24 */
25int
26wait_for_roaming_reconnect(void)
27{
28 return 1;
29}