mirror of git://anongit.mindrot.org/openssh.git
- (dtucker) [Makefile.in added roaming_client.c roaming_serv.c] Import new
files for roaming and add to Makefile.
This commit is contained in:
parent
aaf51d2d5b
commit
8cbd403fde
|
@ -154,6 +154,8 @@
|
|||
[sftp-server.c]
|
||||
bz#1566 don't unnecessarily dup() in and out fds for sftp-server;
|
||||
ok markus@
|
||||
- (dtucker) [Makefile.in added roaming_client.c roaming_serv.c] Import new
|
||||
files for roaming and add to Makefile.
|
||||
|
||||
20091226
|
||||
- (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $Id: Makefile.in,v 1.301 2009/10/02 01:50:55 djm Exp $
|
||||
# $Id: Makefile.in,v 1.302 2010/01/08 08:13:25 dtucker Exp $
|
||||
|
||||
# uncomment if you run a non bourne compatable shell. Ie. csh
|
||||
#SHELL = @SH@
|
||||
|
@ -75,7 +75,7 @@ LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \
|
|||
|
||||
SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
|
||||
sshconnect.o sshconnect1.o sshconnect2.o mux.o \
|
||||
roaming_common.o
|
||||
roaming_common.o roaming_client.c
|
||||
|
||||
SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
|
||||
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 \
|
|||
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 \
|
||||
roaming_common.o
|
||||
roaming_common.o roaming_serv.c
|
||||
|
||||
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
|
||||
|
|
|
@ -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 <sys/queue.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#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);
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/* $OpenBSD: roaming_serv.c,v 1.1 2009/10/24 11:18:23 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 <sys/types.h>
|
||||
|
||||
#include "roaming.h"
|
||||
|
||||
/*
|
||||
* Wait for the roaming client to reconnect. Returns 0 if a connect ocurred.
|
||||
*/
|
||||
int
|
||||
wait_for_roaming_reconnect(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
Loading…
Reference in New Issue