diff -ur Net-SSH-Perl-1.33.orig/lib/Net/SSH/Perl/ChannelMgr.pm Net-SSH-Perl-1.33/lib/Net/SSH/Perl/ChannelMgr.pm
--- Net-SSH-Perl-1.33.orig/lib/Net/SSH/Perl/ChannelMgr.pm 2003-12-03 15:35:21.000000000 +0000
+++ Net-SSH-Perl-1.33/lib/Net/SSH/Perl/ChannelMgr.pm 2008-12-09 16:25:45.000000000 +0000
@@ -31,6 +31,7 @@
SSH2_MSG_CHANNEL_OPEN_FAILURE() => \&input_open_failure,
SSH2_MSG_CHANNEL_REQUEST() => \&input_channel_request,
SSH2_MSG_CHANNEL_WINDOW_ADJUST() => \&input_window_adjust,
+ SSH2_MSG_KEXINIT() => \&input_kexinit,
};
}
@@ -196,6 +197,15 @@
}
}
+sub input_kexinit {
+ my $cmgr = shift;
+ my($packet) = @_;
+
+ my $kex = Net::SSH::Perl::Kex->new($cmgr->{ssh});
+ $kex->exchange($packet);
+ $cmgr->{ssh}->debug("Re-key complete.");
+}
+
sub register_handler {
my $cmgr = shift;
my($type, $code) = @_;
diff -ur Net-SSH-Perl-1.33.orig/lib/Net/SSH/Perl/Kex/DH1.pm Net-SSH-Perl-1.33/lib/Net/SSH/Perl/Kex/DH1.pm
--- Net-SSH-Perl-1.33.orig/lib/Net/SSH/Perl/Kex/DH1.pm 2008-10-02 19:51:15.000000000 +0100
+++ Net-SSH-Perl-1.33/lib/Net/SSH/Perl/Kex/DH1.pm 2008-12-09 16:24:49.000000000 +0000
@@ -71,10 +71,9 @@
croak "Key verification failed for server host key"
unless $s_host_key->verify($signature, $hash);
- $kex->derive_keys($hash, $shared_secret);
- $ssh->{kex} = $kex;
-
$ssh->session_id($hash);
+
+ $kex->derive_keys($hash, $shared_secret, $ssh->session_id);
}
sub kex_hash {
diff -ur Net-SSH-Perl-1.33.orig/lib/Net/SSH/Perl/Kex.pm Net-SSH-Perl-1.33/lib/Net/SSH/Perl/Kex.pm
--- Net-SSH-Perl-1.33.orig/lib/Net/SSH/Perl/Kex.pm 2008-10-21 13:48:50.000000000 +0100
+++ Net-SSH-Perl-1.33/lib/Net/SSH/Perl/Kex.pm 2008-12-09 16:32:30.000000000 +0000
@@ -56,7 +56,7 @@
sub exchange {
my $kex = shift;
my $ssh = $kex->{ssh};
- my $packet;
+ my $packet = shift;
my @proposal = @PROPOSAL;
if (!$ssh->config->get('ciphers')) {
@@ -69,7 +69,7 @@
# valid SSH1 ciphers to the SSH2 equivalent names
if($ssh->protocol eq PROTOCOL_SSH2) {
my %ssh2_cipher = reverse %Net::SSH::Perl::Cipher::CIPHERS_SSH2;
- $cs = join ',', map $ssh2_cipher{$_} || $_, split /,/, $cs;
+ $cs = join ',', map $ssh2_cipher{$_} || $_, split(/,/, $cs);
}
$proposal[ PROPOSAL_CIPH_ALGS_CTOS ] =
$proposal[ PROPOSAL_CIPH_ALGS_STOC ] = $cs;
@@ -88,7 +88,7 @@
}
$kex->{client_kexinit} = $kex->kexinit(\@proposal);
- my($sprop) = $kex->exchange_kexinit;
+ my($sprop) = $kex->exchange_kexinit($packet);
$kex->choose_conf(\@proposal, $sprop);
$ssh->debug("Algorithms, c->s: " .
@@ -102,16 +102,14 @@
$ssh->debug("Waiting for NEWKEYS message.");
$packet = Net::SSH::Perl::Packet->read_expect($ssh, SSH2_MSG_NEWKEYS);
- $ssh->debug("Enabling incoming encryption/MAC/compression.");
- for my $att (qw( mac ciph comp )) {
- $kex->{$att}[0]->enable if $kex->{$att}[0];
- }
-
- $ssh->debug("Send NEWKEYS, enable outgoing encryption/MAC/compression.");
+ $ssh->debug("Send NEWKEYS.");
$packet = $ssh->packet_start(SSH2_MSG_NEWKEYS);
$packet->send;
+ $ssh->debug("Enabling encryption/MAC/compression.");
+ $ssh->{kex} = $kex;
for my $att (qw( mac ciph comp )) {
+ $kex->{$att}[0]->enable if $kex->{$att}[0];
$kex->{$att}[1]->enable if $kex->{$att}[1];
}
}
@@ -132,14 +130,21 @@
sub exchange_kexinit {
my $kex = shift;
my $ssh = $kex->{ssh};
+ my $received_packet = shift;
my $packet;
$packet = $ssh->packet_start(SSH2_MSG_KEXINIT);
$packet->put_chars($kex->client_kexinit->bytes);
$packet->send;
- $ssh->debug("Sent key-exchange init (KEXINIT), wait response.");
- $packet = Net::SSH::Perl::Packet->read_expect($ssh, SSH2_MSG_KEXINIT);
+ if ( defined $received_packet ) {
+ $ssh->debug("Received key-exchange init (KEXINIT), sent response.");
+ $packet = $received_packet;
+ }
+ else {
+ $ssh->debug("Sent key-exchange init (KEXINIT), wait response.");
+ $packet = Net::SSH::Perl::Packet->read_expect($ssh, SSH2_MSG_KEXINIT);
+ }
$kex->{server_kexinit} = $packet->data;
$packet->get_char for 1..16;
@@ -152,11 +157,11 @@
sub derive_keys {
my $kex = shift;
- my($hash, $shared_secret) = @_;
+ my($hash, $shared_secret, $session_id) = @_;
my @keys;
for my $i (0..5) {
- push @keys,
- derive_key(ord('A')+$i, $kex->{we_need}, $hash, $shared_secret);
+ push @keys, derive_key(ord('A')+$i, $kex->{we_need}, $hash,
+ $shared_secret, $session_id);
}
my $is_ssh2 = $kex->{ssh}->protocol == PROTOCOL_SSH2;
for my $mode (0, 1) {
@@ -169,10 +174,10 @@
}
sub derive_key {
- my($id, $need, $hash, $shared_secret) = @_;
+ my($id, $need, $hash, $shared_secret, $session_id) = @_;
my $b = Net::SSH::Perl::Buffer->new( MP => 'SSH2' );
$b->put_mp_int($shared_secret);
- my $digest = sha1($b->bytes, $hash, chr($id), $hash);
+ my $digest = sha1($b->bytes, $hash, chr($id), $session_id);
for (my $have = 20; $need > $have; $have += 20) {
$digest .= sha1($b->bytes, $hash, $digest);
}
diff -ur Net-SSH-Perl-1.33.orig/lib/Net/SSH/Perl.pm Net-SSH-Perl-1.33/lib/Net/SSH/Perl.pm
--- Net-SSH-Perl-1.33.orig/lib/Net/SSH/Perl.pm 2008-10-21 12:03:14.000000000 +0100
+++ Net-SSH-Perl-1.33/lib/Net/SSH/Perl.pm 2008-12-09 16:30:21.000000000 +0000
@@ -337,7 +337,7 @@
sub session_id {
my $ssh = shift;
- $ssh->{session}{id} = shift if @_;
+ $ssh->{session}{id} = shift if @_ and not defined $ssh->{session}{id};
$ssh->{session}{id};
}