summaryrefslogtreecommitdiff
path: root/t/lib
diff options
context:
space:
mode:
authorTharanga Gamaethige <tgamaethige@netflix.com>2018-11-30 17:44:33 -0800
committerdormando <dormando@rydia.net>2019-04-15 21:36:18 -0700
commitee1cfe3bf9384d1a93545fc942e25bed6437d910 (patch)
tree2e880ddd3d263b85f2cf6de73b8eb15d14d02e37 /t/lib
parentd2dcfff7edd28baf3587ab103d6fbac322335a68 (diff)
downloadmemcached-ee1cfe3bf9384d1a93545fc942e25bed6437d910.tar.gz
Basic implementation of TLS for memcached.1.5.13
Most of the work done by Tharanga. Some commits squashed in by dormando. Also reviewed by dormando. Tested, working, but experimental implementation of TLS for memcached. Enable with ./configure --enable-tls Requires OpenSSL 1.1.0 or better. See `memcached -h` output for usage.
Diffstat (limited to 't/lib')
-rw-r--r--t/lib/MemcachedTest.pm86
1 files changed, 80 insertions, 6 deletions
diff --git a/t/lib/MemcachedTest.pm b/t/lib/MemcachedTest.pm
index 416daaf..72ebe08 100644
--- a/t/lib/MemcachedTest.pm
+++ b/t/lib/MemcachedTest.pm
@@ -15,7 +15,22 @@ my @unixsockets = ();
@EXPORT = qw(new_memcached sleep mem_get_is mem_gets mem_gets_is mem_stats
supports_sasl free_port supports_drop_priv supports_extstore
- wait_ext_flush);
+ wait_ext_flush, supports_tls, enabled_tls_testing);
+
+use constant MAX_READ_WRITE_SIZE => 16384;
+use constant SRV_CRT => "server_crt.pem";
+use constant SRV_KEY => "server_key.pem";
+use constant CLIENT_CRT => "client_crt.pem";
+use constant CLIENT_KEY => "client_key.pem";
+use constant CA_CRT => "cacert.pem";
+
+my $testdir = $builddir . "/t/";
+my $client_crt = $testdir. CLIENT_CRT;
+my $client_key = $testdir. CLIENT_KEY;
+my $server_crt = $testdir . SRV_CRT;
+my $server_key = $testdir . SRV_KEY;
+
+my $tls_checked = 0;
sub sleep {
my $n = shift;
@@ -149,10 +164,20 @@ sub free_port {
my $port;
while (!$sock) {
$port = int(rand(20000)) + 30000;
- $sock = IO::Socket::INET->new(LocalAddr => '127.0.0.1',
+ if (enabled_tls_testing()) {
+ $sock = eval qq{ IO::Socket::SSL->new(LocalAddr => '127.0.0.1',
+ LocalPort => $port,
+ Proto => '$type',
+ ReuseAddr => 1,
+ SSL_verify_mode => SSL_VERIFY_NONE);
+ };
+ die $@ if $@; # sanity check.
+ } else {
+ $sock = IO::Socket::INET->new(LocalAddr => '127.0.0.1',
LocalPort => $port,
Proto => $type,
ReuseAddr => 1);
+ }
}
return $port;
}
@@ -175,6 +200,23 @@ sub supports_extstore {
return 0;
}
+sub supports_tls {
+ my $output = `$builddir/memcached-debug -h`;
+ return 1 if $output =~ /enable-ssl/i;
+ return 0;
+}
+
+sub enabled_tls_testing {
+ if ($tls_checked) {
+ return 1;
+ } elsif (supports_tls() && $ENV{SSL_TEST}) {
+ eval "use IO::Socket::SSL";
+ croak("IO::Socket::SSL not installed or failed to load, cannot run SSL tests as requested") if $@;
+ $tls_checked = 1;
+ return 1;
+ }
+}
+
sub supports_drop_priv {
my $output = `$builddir/memcached-debug -h`;
return 1 if $output =~ /no_drop_privileges/i;
@@ -185,10 +227,21 @@ sub new_memcached {
my ($args, $passed_port) = @_;
my $port = $passed_port;
my $host = '127.0.0.1';
+ my $ssl_enabled = enabled_tls_testing();
if ($ENV{T_MEMD_USE_DAEMON}) {
my ($host, $port) = ($ENV{T_MEMD_USE_DAEMON} =~ m/^([^:]+):(\d+)$/);
- my $conn = IO::Socket::INET->new(PeerAddr => "$host:$port");
+ my $conn;
+ if ($ssl_enabled) {
+ $conn = eval qq{IO::Socket::SSL->new(PeerAddr => "$host:$port",
+ SSL_verify_mode => SSL_VERIFY_NONE,
+ SSL_cert_file => '$client_crt',
+ SSL_key_file => '$client_key');
+ };
+ die $@ if $@; # sanity check.
+ } else {
+ $conn = IO::Socket::INET->new(PeerAddr => "$host:$port");
+ }
if ($conn) {
return Memcached::Handle->new(conn => $conn,
host => $host,
@@ -203,13 +256,18 @@ sub new_memcached {
$args .= " -o relaxed_privileges";
my $udpport;
- if ($args =~ /-l (\S+)/) {
- $port = free_port();
+ if ($args =~ /-l (\S+)/ || ($ssl_enabled && ($args !~ /-s (\S+)/))) {
+ if (!$port) {
+ $port = free_port();
+ }
$udpport = free_port("udp");
$args .= " -p $port";
if (supports_udp()) {
$args .= " -U $udpport";
}
+ if ($ssl_enabled) {
+ $args .= " -Z -o ssl_chain_cert=$server_crt -o ssl_key=$server_key";
+ }
} elsif ($args !~ /-s (\S+)/) {
my $num = @unixsockets;
my $file = "/tmp/memcachetest.$$.$num";
@@ -246,7 +304,17 @@ sub new_memcached {
# sockets
for (1..20) {
- my $conn = IO::Socket::INET->new(PeerAddr => "127.0.0.1:$port");
+ my $conn;
+ if ($ssl_enabled) {
+ $conn = eval qq{ IO::Socket::SSL->new(PeerAddr => "127.0.0.1:$port",
+ SSL_verify_mode => SSL_VERIFY_NONE,
+ SSL_cert_file => '$client_crt',
+ SSL_key_file => '$client_key');
+ };
+ die $@ if $@; # sanity check.
+ } else {
+ $conn = IO::Socket::INET->new(PeerAddr => "127.0.0.1:$port");
+ }
if ($conn) {
return Memcached::Handle->new(pid => $childpid,
conn => $conn,
@@ -299,6 +367,12 @@ sub new_sock {
my $self = shift;
if ($self->{domainsocket}) {
return IO::Socket::UNIX->new(Peer => $self->{domainsocket});
+ } elsif (MemcachedTest::enabled_tls_testing()) {
+ return eval qq{ IO::Socket::SSL->new(PeerAddr => "$self->{host}:$self->{port}",
+ SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE,
+ SSL_cert_file => '$client_crt',
+ SSL_key_file => '$client_key');
+ };
} else {
return IO::Socket::INET->new(PeerAddr => "$self->{host}:$self->{port}");
}