Subject: | Net-FTPSSL-0.09 ccc() does not perform bidirection SSL shutdown |
Date: | Tue, 7 Jul 2009 10:29:02 -0700 (PDT) |
To: | bug-Net-FTPSSL [...] rt.cpan.org |
From: | TJ Saunders <tj [...] castaglia.org> |
The ccc() method of Net::FTPSSL currently tells IO::Socket::SSL to skip
the call to SSL_shutdown() (this is the recommended usage according to the
IO::Socket::SSL docs). However, this makes Net::FTPSSL not handle the CCC
command properly.
Here's the example Perl code demonstrating the issue, and the expected
behavior:
my $user = 'proftpd';
my $passwd = 'test';
my $home_dir = '/tmp';
my $client_opts = {
Encryption => 'E',
Port => $port,
Croak => 1,
};
if ($ENV{TEST_VERBOSE}) {
$client_opts->{Debug} = 1;
}
my $client = Net::FTPSSL->new('127.0.0.1', %$client_opts);
unless ($client) {
die("Can't connect to FTPS server: " . IO::Socket::SSL::errstr());
}
unless ($client->login($user, $passwd)) {
die("Can't login: " . $client->last_message());
}
$client->ccc();
my $cwd = $client->pwd();
$client->quit();
$self->assert($home_dir eq $cwd);
When executing this against proftpd-1.3.2 compiled with mod_tls, the
resulting Net:FTPSSL debug shows:
SKT <<< 220 ProFTPD 1.3.2 Server (ProFTPD) [127.0.0.1]
SKT >>> AUTH TLS
SKT <<< 234 AUTH TLS successful
Show quoted text
>>> USER proftpd
<<< 331 Password required for proftpd
Show quoted text >>> PASS *******
<<< 230 User proftpd logged in
Show quoted text >>> PBSZ 0
<<< 200 PBSZ 0 successful
Show quoted text >>> PROT P
<<< 200 Protection set to Private
Show quoted text >>> CCC
<<< 200 Clearing control channel protection
Show quoted text >>> PWD
<<< +).mleěvt
<<< WD :zaŀ^ntx=J0
After issuing the CCC command, the client should still be able to issue
FTP commands such as PWD. But the above shows that Net::FTPSSL is not
parsing/handling the responses from proftpd, after the CCC, properly.
In the mod_tls log, with OpenSSL diagnostics enabled, for the above, I
see:
Jul 07 09:34:48 mod_tls/2.3[28335]: received CCC, clearing control channel protection
Jul 07 09:34:48 mod_tls/2.3[28335]: [msg] sent TLSv1 warning 'close_notify' Alert message (2 bytes)
Jul 07 09:34:48 mod_tls/2.3[28335]: [info] writing: SSL/TLS alert warning: close notify
Jul 07 09:34:48 mod_tls/2.3[28335]: [msg] sent message of unknown version (22340) (2 bytes)
Jul 07 09:34:48 mod_tls/2.3[28335]: [info] writing: SSL/TLS alert fatal: protocol version
Jul 07 09:34:48 mod_tls/2.3[28335]: SSL_shutdown error [1]:
(1) error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number
This shows mod_tls (via the OpenSSL SSL_shutdown() call) sending the
close_notify alert to the client. Notice, though, that the client does
not send a close_notify alert in response.
However, if the following code in FTPSSL.pm is changed from:
# Stop SSL, but leave the socket open!
unless ( $self->stop_SSL ( SSL_no_shutdown => 1 ) ) {
to be:
# Stop SSL, but leave the socket open!
unless ( $self->stop_SSL ( SSL_no_shutdown => 0 ) ) {
and the test tried again, the Net::FTPSSL debug log shows:
SKT <<< 220 ProFTPD 1.3.2 Server (ProFTPD) [127.0.0.1]
SKT >>> AUTH TLS
SKT <<< 234 AUTH TLS successful
Show quoted text >>> USER proftpd
<<< 331 Password required for proftpd
Show quoted text >>> PASS *******
<<< 230 User proftpd logged in
Show quoted text >>> PBSZ 0
<<< 200 PBSZ 0 successful
Show quoted text >>> PROT P
<<< 200 Protection set to Private
Show quoted text >>> CCC
<<< 200 Clearing control channel protection
Show quoted text >>> PWD
<<< 257 "/tmp" is the current directory
Show quoted text >>> QUIT
<<< 221 Goodbye.
Net::FTPSSL was able to parse/handle the PWD response this time. And in
the mod_tls logs, again with OpenSSL diagnostics enabled, I the following
for the above modified Net::FTPSSL code:
Jul 07 10:17:32 mod_tls/2.3[29361]: received CCC, clearing control channel protection
Jul 07 10:17:32 mod_tls/2.3[29361]: [msg] sent TLSv1 warning 'close_notify' Alert message (2 bytes)
Jul 07 10:17:32 mod_tls/2.3[29361]: [info] writing: SSL/TLS alert warning: close notify
Jul 07 10:17:32 mod_tls/2.3[29361]: [msg] received TLSv1 warning 'close_notify' Alert message (2 bytes)
Jul 07 10:17:32 mod_tls/2.3[29361]: [info] reading: SSL/TLS alert warning: close notify
This time, a full bidirectional shutdown of the SSL session occurred; the
'close_notify' alerts were sent and received by both peers. Section 12.3
of RFC 4217 shows that a bidirectional shutdown of the SSL session on the
control channel is the expected behavior.
Keep up the good work with the Net::FTPSSL module; I'm enjoying using it
for my proftpd/mod_tls development!
Cheers,
TJ
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Absence is to love what wind is to fire: it extinguishes the small, it
enkindles the great.
-Comte de Bussy-Rabutin
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~