Skip Menu |

This queue is for tickets about the Net-SSH-Perl CPAN distribution.

Report information
The Basics
Id: 25044
Status: resolved
Priority: 0/
Queue: Net-SSH-Perl

People
Owner: greg [...] turnstep.com
Requestors: crashingdaily [...] gmail.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: Net::SFTP not rekeying
Date: Mon, 19 Feb 2007 21:50:06 -0500
To: bug-Net-SSH-Perl [...] rt.cpan.org
From: "Crashing Daily" <crashingdaily [...] gmail.com>
bug #12429 also applies to Net::SSH::Perl 1.30 (is there a newer version?) Net::SFTP transfers hang after 1GB data transferred. Server: OpenSSH_3.9p1, OpenSSL 0.9.7a Feb 19 2003 debug log: Feb 15 23:21:55 olive sshd[19497]: debug1: need rekeying Feb 15 23:21:55 olive sshd[19497]: debug1: SSH2_MSG_KEXINIT sent Client script using Net::SFTP 0.10, reports: sftp: In read loop, got 8192 offset 1069547520 sftp: Sent message SSH2_FXP_READ I:130563 O:1069555712 Warning: ignore packet type 20 channel 1: window 16358 sent adjust 16410 sftp: Received reply T:103 I:130563 sftp: In read loop, got 8192 offset 1069555712 sftp: Sent message SSH2_FXP_READ I:130564 O:1069563904 OpenSSH 3.9 automatically attempts rekeying with SSH2 clients after ~1GB of data transfer unless the client version is one that is known by the server to not support rekeying (see SSH_BUG_NOREKEY in OpenSSH compat.c). To confirm this issue, if the $VERSION of Net::SSH::Perl is changed to 'OpenSSH_2.5.2' (a recognized non-rekeying client) then the transfer completes without hanging.
From: peter.oliver [...] eon-is.co.uk
On Mon Feb 19 21:50:25 2007, crashingdaily@gmail.com wrote: Show quoted text
> Net::SFTP transfers hang after 1GB data transferred.
... Show quoted text
> OpenSSH 3.9 automatically attempts rekeying with SSH2 clients after > ~1GB of data transfer unless the client version is one that is known > by the server to not support rekeying (see SSH_BUG_NOREKEY in OpenSSH > compat.c).
Attached is a patch which adds support for re-keying to Net::SSH::Perl. This allows transfers to continue beyond 1 GB.
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}; }
On Tue Dec 09 11:54:23 2008, pdoliver wrote: Show quoted text
> Attached is a patch which adds support for re-keying to Net::SSH::Perl. > This allows transfers to continue beyond 1 GB.
According to the Changes file this patch was applied in v1.34. Steffen -- Steffen Schwigon <ss5@renormalist.net> Dresden Perl Mongers <http://dresden-pm.org/>