Repository: thrift Updated Branches: refs/heads/master b28160b9c -> 377719c2d
THRIFT-3272 (THRIFT-4066) fix perl SSL authentication support; fixed error in erlang test client using wrong key file and added CA Client: Perl This closes #1189 Project: http://git-wip-us.apache.org/repos/asf/thrift/repo Commit: http://git-wip-us.apache.org/repos/asf/thrift/commit/377719c2 Tree: http://git-wip-us.apache.org/repos/asf/thrift/tree/377719c2 Diff: http://git-wip-us.apache.org/repos/asf/thrift/diff/377719c2 Branch: refs/heads/master Commit: 377719c2d85f6f92df7a40e34a84129406f6deb4 Parents: b28160b Author: James E. King, III <[email protected]> Authored: Wed Feb 15 14:33:20 2017 -0500 Committer: James E. King, III <[email protected]> Committed: Wed Feb 15 14:33:20 2017 -0500 ---------------------------------------------------------------------- lib/perl/lib/Thrift/SSLServerSocket.pm | 26 +++++---- lib/perl/lib/Thrift/SSLSocket.pm | 52 ++++++++++++++---- lib/perl/lib/Thrift/Socket.pm | 81 ++++++++++++++++------------- test/erl/src/test_client.erl | 5 +- test/erl/src/test_thrift_server.erl | 2 +- test/known_failures_Linux.json | 27 ++-------- test/perl/TestClient.pl | 20 +++---- test/perl/TestServer.pl | 14 ++--- test/tests.json | 5 +- 9 files changed, 132 insertions(+), 100 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/thrift/blob/377719c2/lib/perl/lib/Thrift/SSLServerSocket.pm ---------------------------------------------------------------------- diff --git a/lib/perl/lib/Thrift/SSLServerSocket.pm b/lib/perl/lib/Thrift/SSLServerSocket.pm index 4daaf08..e885ede 100644 --- a/lib/perl/lib/Thrift/SSLServerSocket.pm +++ b/lib/perl/lib/Thrift/SSLServerSocket.pm @@ -48,21 +48,27 @@ sub new sub __client { - return new Thrift::SSLSocket(); + return new Thrift::SSLSocket(); } sub __listen { my $self = shift; - return IO::Socket::SSL->new(LocalAddr => $self->{host}, - LocalPort => $self->{port}, - Proto => 'tcp', - Listen => $self->{queue}, - ReuseAddr => 1, - SSL_cert_file => $self->{cert}, - SSL_key_file => $self->{key}, - SSL_ca_file => $self->{ca}); -} + my $opts = {Listen => $self->{queue}, + LocalAddr => $self->{host}, + LocalPort => $self->{port}, + Proto => 'tcp', + ReuseAddr => 1}; + + $opts->{SSL_ca_file} = $self->{ca} if defined $self->{ca}; + $opts->{SSL_cert_file} = $self->{cert} if defined $self->{cert}; + $opts->{SSL_cipher_list} = $self->{ciphers} if defined $self->{ciphers}; + $opts->{SSL_key_file} = $self->{key} if defined $self->{key}; + $opts->{SSL_use_cert} = (defined $self->{cert}) ? 1 : 0; + $opts->{SSL_verify_mode} = (defined $self->{ca}) ? IO::Socket::SSL::SSL_VERIFY_PEER : IO::Socket::SSL::SSL_VERIFY_NONE; + $opts->{SSL_version} = (defined $self->{version}) ? $self->{version} : 'SSLv23:!SSLv2:!SSLv3'; + return IO::Socket::SSL->new(%$opts); +} 1; http://git-wip-us.apache.org/repos/asf/thrift/blob/377719c2/lib/perl/lib/Thrift/SSLSocket.pm ---------------------------------------------------------------------- diff --git a/lib/perl/lib/Thrift/SSLSocket.pm b/lib/perl/lib/Thrift/SSLSocket.pm index 0d2edf8..046692e 100644 --- a/lib/perl/lib/Thrift/SSLSocket.pm +++ b/lib/perl/lib/Thrift/SSLSocket.pm @@ -29,10 +29,32 @@ use IO::Select; package Thrift::SSLSocket; -# TODO: Does not provide cipher selection or authentication hooks yet. - use base qw( Thrift::Socket ); +# +# Construction and usage +# +# my $opts = {} +# my $socket = new Thrift::SSLSocket(\%opts); +# +# options: +# +# Any option from Socket.pm is valid, and then: +# +# ca => certificate authority file (PEM file) to authenticate the +# server against; if not specified then the server is not +# authenticated +# cert => certificate to use as the client; if not specified then +# the client does not present one but still connects using +# secure protocol +# ciphers => allowed cipher list +# (see http://www.openssl.org/docs/apps/ciphers.html#CIPHER_STRINGS) +# key => certificate key for "cert" option +# version => acceptable SSL/TLS versions - if not specified then the +# default is to use SSLv23 handshake but only negotiate +# at TLSv1.0 or later +# + sub new { my $classname = shift; @@ -44,10 +66,20 @@ sub new sub __open { my $self = shift; - return IO::Socket::SSL->new(PeerAddr => $self->{host}, - PeerPort => $self->{port}, - Proto => 'tcp', - Timeout => $self->{sendTimeout} / 1000); + my $opts = {PeerAddr => $self->{host}, + PeerPort => $self->{port}, + Proto => 'tcp', + Timeout => $self->{sendTimeout} / 1000}; + + $opts->{SSL_ca_file} = $self->{ca} if defined $self->{ca}; + $opts->{SSL_cert_file} = $self->{cert} if defined $self->{cert}; + $opts->{SSL_cipher_list} = $self->{ciphers} if defined $self->{ciphers}; + $opts->{SSL_key_file} = $self->{key} if defined $self->{key}; + $opts->{SSL_use_cert} = (defined $self->{cert}) ? 1 : 0; + $opts->{SSL_verify_mode} = (defined $self->{ca}) ? IO::Socket::SSL::SSL_VERIFY_PEER : IO::Socket::SSL::SSL_VERIFY_NONE; + $opts->{SSL_version} = (defined $self->{version}) ? $self->{version} : 'SSLv23:!SSLv2:!SSLv3'; + + return IO::Socket::SSL->new(%$opts); } sub __close @@ -61,10 +93,10 @@ sub __close sub __recv { - my $self = shift; - my $sock = shift; - my $len = shift; - my $buf = undef; + my $self = shift; + my $sock = shift; + my $len = shift; + my $buf = undef; if ($sock) { sysread($sock, $buf, $len); } http://git-wip-us.apache.org/repos/asf/thrift/blob/377719c2/lib/perl/lib/Thrift/Socket.pm ---------------------------------------------------------------------- diff --git a/lib/perl/lib/Thrift/Socket.pm b/lib/perl/lib/Thrift/Socket.pm index eaf8b9e..c8e333b 100644 --- a/lib/perl/lib/Thrift/Socket.pm +++ b/lib/perl/lib/Thrift/Socket.pm @@ -31,23 +31,48 @@ package Thrift::Socket; use base qw( Thrift::Transport ); +# +# Construction and usage +# +# my $opts = {} +# my $socket = new Thrift::Socket(\%opts); +# +# options: +# +# host => host to connect to +# port => port to connect to +# sendTimeout => timeout used for send and for connect +# recvTimeout => timeout used for recv +# + sub new { - my $classname = shift; - my $host = shift || "localhost"; - my $port = shift || 9090; - my $debugHandler = shift; + my $classname = shift; + my $opts = shift; + # default settings: my $self = { - host => $host, - port => $port, - debugHandler => $debugHandler, - debug => 0, - sendTimeout => 10000, + host => 'localhost', + port => 9090, recvTimeout => 10000, - handle => undef, + sendTimeout => 10000, + + handle => undef }; + if (defined $opts and ref $opts eq ref {}) { + + # argument is a hash of options so override the defaults + $self->{$_} = $opts->{$_} for keys %$opts; + + } else { + + # older style constructor takes 3 arguments, none of which are required + $self->{host} = $opts || 'localhost'; + $self->{port} = shift || 9090; + + } + return bless($self,$classname); } @@ -70,19 +95,6 @@ sub setRecvTimeout # -#Sets debugging output on or off -# -# @param bool $debug -# -sub setDebug -{ - my $self = shift; - my $debug = shift; - - $self->{debug} = $debug; -} - -# # Tests whether this is open # # @return bool true if the socket is open @@ -107,11 +119,6 @@ sub open my $sock = $self->__open() || do { my $error = ref($self).': Could not connect to '.$self->{host}.':'.$self->{port}.' ('.$!.')'; - - if ($self->{debug}) { - $self->{debugHandler}->($error); - } - die new Thrift::TException($error); }; @@ -125,7 +132,7 @@ sub close { my $self = shift; if( defined $self->{handle} ) { - $self->__close(); + $self->__close(); } } @@ -216,7 +223,7 @@ sub write my $sent = $self->__send($sockets[0], $buf); if (!defined $sent || $sent == 0 ) { - + die new Thrift::TException(ref($self).': Could not write '.length($buf).' bytes '. $self->{host}.':'.$self->{host}); @@ -259,7 +266,7 @@ sub __open # sub __close { - my $self = shift; + my $self = shift; CORE::close(($self->{handle}->handles())[0]); } @@ -272,12 +279,12 @@ sub __close # sub __recv { - my $self = shift; - my $sock = shift; - my $len = shift; - my $buf = undef; - $sock->recv($buf, $len); - return $buf; + my $self = shift; + my $sock = shift; + my $len = shift; + my $buf = undef; + $sock->recv($buf, $len); + return $buf; } # http://git-wip-us.apache.org/repos/asf/thrift/blob/377719c2/test/erl/src/test_client.erl ---------------------------------------------------------------------- diff --git a/test/erl/src/test_client.erl b/test/erl/src/test_client.erl index 50ffc64..c916cee 100644 --- a/test/erl/src/test_client.erl +++ b/test/erl/src/test_client.erl @@ -51,8 +51,9 @@ parse_args([Head | Rest], Opts) -> ssl:start(), SslOptions = {ssloptions, [ - {certfile, "../keys/client.crt"} - ,{keyfile, "../keys/server.key"} + {cacertfile, "../keys/CA.pem"}, + {certfile, "../keys/client.pem"}, + {keyfile, "../keys/client.key"} ]}, Opts#options{client_opts = [{ssltransport, true} | [SslOptions | Opts#options.client_opts]]}; "--protocol=" ++ Proto -> http://git-wip-us.apache.org/repos/asf/thrift/blob/377719c2/test/erl/src/test_thrift_server.erl ---------------------------------------------------------------------- diff --git a/test/erl/src/test_thrift_server.erl b/test/erl/src/test_thrift_server.erl index f3ed2f7..dad8dec 100644 --- a/test/erl/src/test_thrift_server.erl +++ b/test/erl/src/test_thrift_server.erl @@ -51,7 +51,7 @@ parse_args([Head | Rest], Opts) -> ssl:start(), SslOptions = {ssloptions, [ - {certfile, "../keys/server.crt"} + {certfile, "../keys/server.pem"} ,{keyfile, "../keys/server.key"} ]}, Opts#options{server_opts = [{ssltransport, true} | [SslOptions | Opts#options.server_opts]]}; http://git-wip-us.apache.org/repos/asf/thrift/blob/377719c2/test/known_failures_Linux.json ---------------------------------------------------------------------- diff --git a/test/known_failures_Linux.json b/test/known_failures_Linux.json index 4ca2050..d60997d 100644 --- a/test/known_failures_Linux.json +++ b/test/known_failures_Linux.json @@ -34,8 +34,6 @@ "cpp-java_compact_http-ip-ssl", "cpp-java_json_http-ip", "cpp-java_json_http-ip-ssl", - "cpp-perl_binary_buffered-ip-ssl", - "cpp-perl_binary_framed-ip-ssl", "csharp-c_glib_binary_buffered-ip-ssl", "csharp-c_glib_binary_framed-ip-ssl", "csharp-c_glib_compact_buffered-ip-ssl", @@ -140,8 +138,6 @@ "d-nodejs_json_buffered-ip-ssl", "d-nodejs_json_framed-ip", "d-nodejs_json_framed-ip-ssl", - "d-perl_binary_buffered-ip-ssl", - "d-perl_binary_framed-ip-ssl", "d-py3_binary-accel_buffered-ip", "d-py3_binary-accel_buffered-ip-ssl", "d-py3_binary-accel_framed-ip", @@ -184,8 +180,6 @@ "d-py_json_framed-ip-ssl", "erl-nodejs_binary_buffered-ip", "erl-nodejs_compact_buffered-ip", - "erl-perl_binary_buffered-ip-ssl", - "erl-perl_binary_framed-ip-ssl", "erl-rb_binary-accel_buffered-ip", "erl-rb_binary-accel_framed-ip", "erl-rb_binary_buffered-ip", @@ -216,8 +210,6 @@ "go-java_json_http-ip", "go-java_json_http-ip-ssl", "go-nodejs_json_framed-ip", - "go-perl_binary_buffered-ip-ssl", - "go-perl_binary_framed-ip-ssl", "hs-csharp_binary_framed-ip", "hs-csharp_compact_framed-ip", "hs-csharp_json_framed-ip", @@ -229,21 +221,8 @@ "java-d_compact_buffered-ip", "java-d_compact_buffered-ip-ssl", "java-d_compact_framed-ip", - "java-perl_binary_buffered-ip-ssl", - "java-perl_binary_fastframed-framed-ip-ssl", - "java-perl_binary_framed-ip-ssl", - "nodejs-perl_binary_buffered-ip-ssl", - "nodejs-perl_binary_framed-ip-ssl", + "perl-erl_binary_buffered-ip-ssl", + "perl-erl_binary_framed-ip-ssl", "perl-perl_binary_buffered-ip-ssl", - "perl-perl_binary_framed-ip-ssl", - "perl-php_binary_framed-ip", - "py-cpp_compact_buffered-ip", - "py-perl_accel-binary_buffered-ip-ssl", - "py-perl_accel-binary_framed-ip-ssl", - "py-perl_binary_buffered-ip-ssl", - "py-perl_binary_framed-ip-ssl", - "py3-perl_accel-binary_buffered-ip-ssl", - "py3-perl_accel-binary_framed-ip-ssl", - "py3-perl_binary_buffered-ip-ssl", - "py3-perl_binary_framed-ip-ssl" + "perl-perl_binary_framed-ip-ssl" ] http://git-wip-us.apache.org/repos/asf/thrift/blob/377719c2/test/perl/TestClient.pl ---------------------------------------------------------------------- diff --git a/test/perl/TestClient.pl b/test/perl/TestClient.pl index 7ec32bf..483c964 100755 --- a/test/perl/TestClient.pl +++ b/test/perl/TestClient.pl @@ -47,15 +47,19 @@ sub usage { Usage: $0 [OPTIONS] Options: (default) + --ca CA to validate server with. --cert Certificate to use. Required if using --ssl. + --ciphers Acceptable cipher list. --domain-socket <file> Use a unix domain socket. --help Show usage. + --key Certificate key. + Required if using --ssl. --port <portnum> 9090 Port to use. --protocol {binary} binary Protocol to use. --ssl If present, use SSL. --transport {buffered|framed} buffered Transport to use. - + EOF } @@ -66,7 +70,10 @@ my %opts = ( ); GetOptions(\%opts, qw ( + ca=s cert=s + ciphers=s + key=s domain-socket=s help host=s @@ -81,18 +88,13 @@ if ($opts{help}) { exit 0; } -if ($opts{ssl} and not defined $opts{cert}) { - usage(); - exit 1; -} - my $socket = undef; if ($opts{"domain-socket"}) { $socket = new Thrift::UnixSocket($opts{"domain-socket"}); } elsif ($opts{ssl}) { - $socket = new Thrift::SSLSocket($opts{host}, $opts{port}); + $socket = new Thrift::SSLSocket(\%opts); } else { - $socket = new Thrift::Socket($opts{host}, $opts{port}); + $socket = new Thrift::Socket($opts{host}, $opts{port}); } my $transport; @@ -117,7 +119,7 @@ my $testClient = new ThriftTest::ThriftTestClient($protocol); eval { $transport->open(); -}; +}; if($@){ die(Dumper($@)); } http://git-wip-us.apache.org/repos/asf/thrift/blob/377719c2/test/perl/TestServer.pl ---------------------------------------------------------------------- diff --git a/test/perl/TestServer.pl b/test/perl/TestServer.pl index 4e0cc79..e2835f4 100644 --- a/test/perl/TestServer.pl +++ b/test/perl/TestServer.pl @@ -50,7 +50,8 @@ Usage: $0 [OPTIONS] Options: (default) --ca Certificate authority file (optional). --cert Certificate file. - Required if using --ssl. + Required if using --ssl. + --ciphers Acceptable cipher list. --domain-socket <file> Use a unix domain socket. --help Show usage. --key Private key file for certificate. @@ -60,7 +61,7 @@ Options: (default) --protocol {binary} binary Protocol to use. --ssl If present, use SSL/TLS. --transport {buffered|framed} buffered Transport to use. - + EOF } @@ -73,6 +74,7 @@ my %opts = ( GetOptions(\%opts, qw ( ca=s cert=s + ciphers=s domain-socket=s help host=s @@ -133,7 +135,7 @@ my $server = new Thrift::SimpleServer($processor, $serversocket, $transport, $pr print "Starting \"simple\" server ($opts{transport}/$opts{protocol}) listen on: $listening_on\n"; $server->serve(); -### +### ### Test server implementation ### @@ -148,7 +150,7 @@ sub new { } sub testVoid() { - print("testVoid()\n"); + print("testVoid()\n"); } sub testString() { @@ -320,7 +322,7 @@ sub testTypedef() { sub testMapMap() { my $self = shift; my $hello = shift; - + printf("testMapMap(%d)\n", $hello); my $result = { 4 => { 1 => 1, 2 => 2, 3 => 3, 4 => 4 }, -4 => { -1 => -1, -2 => -2, -3 => -3, -4 => -4 } }; return $result; @@ -352,7 +354,7 @@ sub testMulti() { my $arg3 = shift; my $arg4 = shift; my $arg5 = shift; - + print("testMulti()\n"); return new ThriftTest::Xtruct({string_thing => "Hello2", byte_thing => $arg0, i32_thing => $arg1, i64_thing => $arg2}); } http://git-wip-us.apache.org/repos/asf/thrift/blob/377719c2/test/tests.json ---------------------------------------------------------------------- diff --git a/test/tests.json b/test/tests.json index 5de36f5..e228928 100644 --- a/test/tests.json +++ b/test/tests.json @@ -414,7 +414,9 @@ "-Igen-perl/", "-I../../lib/perl/lib/", "TestClient.pl", - "--cert=../keys/client.pem" + "--ca=../keys/CA.pem", + "--cert=../keys/client.pem", + "--key=../keys/client.key" ] }, "server": { @@ -423,6 +425,7 @@ "-Igen-perl/", "-I../../lib/perl/lib/", "TestServer.pl", + "--ca=../keys/CA.pem", "--cert=../keys/server.pem", "--key=../keys/server.key" ]
