From a45af5e1cca74598a10d6723937abf098310838e Mon Sep 17 00:00:00 2001 From: Victor Seva Date: Tue, 21 Mar 2017 10:48:48 +0100 Subject: [PATCH] TT#13257 use API to generate client cert and use it on next calls * code stolen from ngcp-panel/t/lib/Test/Collection.pm * remove apicert.pem afterwards Change-Id: Ib111ec0b6410f1e6157a7cf7c0fb67ccf101da2f --- .gitignore | 1 + debian/control | 1 + lib/Sipwise/API.pm | 65 +++++++++++++++++++++++++++++++++++++++++----- run_tests.sh | 2 ++ 4 files changed, 62 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index da6aef88..7ea677f1 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ sipp_scenario_responder*_reg.xml *.csv presence_*xml presence.sh +apicert.pem diff --git a/debian/control b/debian/control index 3397ce91..81d1d2af 100644 --- a/debian/control +++ b/debian/control @@ -13,6 +13,7 @@ Depends: curl, libfile-slurp-perl, libgraphviz-perl, + libio-compress-perl, libjson-perl, libtemplate-perl, libtext-csv-perl, diff --git a/lib/Sipwise/API.pm b/lib/Sipwise/API.pm index 82ff206a..567c0d59 100644 --- a/lib/Sipwise/API.pm +++ b/lib/Sipwise/API.pm @@ -30,6 +30,12 @@ use IO::Socket::SSL; use URI; use Data::Dumper; use File::Slurp; +use IO::Uncompress::Unzip; + +my $default_crt_path = '/usr/share/kamailio-config-tests/apicert.pem'; +if(exists $ENV{'BASE_DIR'}){ + $default_crt_path = $ENV{'BASE_DIR'}.'/apicert.pem'; +} my $opts_default = { host => '127.0.0.1', @@ -38,7 +44,8 @@ my $opts_default = { auth_pwd => 'administrator', verbose => 0, sslverify => 'no', - admin => 0 + admin => 0, + crt_path => $default_crt_path }; sub _get_id { @@ -127,8 +134,43 @@ sub do_query { return $res; } +sub _fetch_cert { + my ($self, $ua, $urlbase) = @_; + my $res = $ua->post( + $urlbase . '/api/admincerts/', + Content_Type => 'application/json', + Content => '{}' + ); + + unless($res->is_success) { + die "failed to fetch client certificate: " . $res->status_line . "\n"; + } + my $zip = $res->decoded_content; + my $z = IO::Uncompress::Unzip->new(\$zip, MultiStream => 0, Append => 1); + my $data; + while(!$z->eof() && (my $hdr = $z->getHeaderInfo())) { + unless($hdr->{Name} =~ /\.pem$/) { + # wrong file, just read stream, clear buffer and try next + while($z->read($data) > 0) {} + $data = undef; + $z->nextStream(); + next; + } + while($z->read($data) > 0) {} + last; + } + $z->close(); + unless($data) { + die "failed to find PEM file in client certificate zip file\n"; + } + open my $fh, ">:raw", $self->{opts}->{crt_path} or + die "failed to open " . $self->{opts}->{crt_path} . ": $!\n"; + print { $fh } $data; + close $fh; +} + sub create_ua { - my $self = shift; + my ($self, $urlbase) = @_; my $ua = LWP::UserAgent->new(); if($self->{opts}->{sslverify} eq 'no') { @@ -149,6 +191,13 @@ sub create_ua { $ua->add_handler("request_send", sub { shift->dump; return }); $ua->add_handler("response_done", sub { shift->dump; return }); } + unless (-f $self->{opts}->{crt_path}) { + $self->_fetch_cert($ua, $urlbase); + } + $ua->ssl_opts( + SSL_cert_file => $self->{opts}->{crt_path}, + SSL_key_file => $self->{opts}->{crt_path}, + ); return $ua; } @@ -156,7 +205,8 @@ sub _create { my ($self, $data, $urldata) = @_; my $urlbase = 'https://'.$self->{opts}->{host}.':'.$self->{opts}->{port}; - my $ua = $self->create_ua(); + my $ua = $self->create_ua($urlbase); + my $res = $self->do_request($ua, $urlbase.$urldata, $data); if($res->is_success) { if($self->{opts}->{verbose}) { @@ -173,7 +223,8 @@ sub _delete { my ($self, $urldata) = @_; my $urlbase = 'https://'.$self->{opts}->{host}.':'.$self->{opts}->{port}; - my $ua = $self->create_ua(); + my $ua = $self->create_ua($urlbase); + my $res = $self->do_query($ua, $urlbase.$urldata, undef, 'DELETE'); return $res->is_success; } @@ -181,7 +232,7 @@ sub _delete { sub _get_content { my ($self, $data, $urldata) = @_; my $urlbase = 'https://'.$self->{opts}->{host}.':'.$self->{opts}->{port}; - my $ua = $self->create_ua(); + my $ua = $self->create_ua($urlbase); my $res = $self->do_query($ua, $urlbase.$urldata, $data); if($res->is_success) { @@ -196,7 +247,7 @@ sub _get_content { sub _set_content { my ($self, $data, $urldata) = @_; my $urlbase = 'https://'.$self->{opts}->{host}.':'.$self->{opts}->{port}; - my $ua = $self->create_ua(); + my $ua = $self->create_ua($urlbase); my $res = $self->do_request($ua, $urlbase.$urldata, $data, 'PUT'); if($res->is_success) { @@ -699,7 +750,7 @@ sub upload_soundfile { "&set_id=$data->{set_id}&loopplay=$data->{loopplay}"; my $urlbase = 'https://'.$self->{opts}->{host}.':'.$self->{opts}->{port}; - my $ua = $self->create_ua(); + my $ua = $self->create_ua($urlbase); my $res = $self->_do_binary_request($ua, $urlbase.$urldata, $filepath, 'audio/x-wav'); if(! $res->is_success) { diff --git a/run_tests.sh b/run_tests.sh index 36e0fc56..ff35b7cd 100755 --- a/run_tests.sh +++ b/run_tests.sh @@ -51,6 +51,8 @@ function get_scenarios function cfg_debug_off { if [ -z "$SKIP" ]; then + echo "$(date) - Removed apicert.pem" + rm -f "${BASE_DIR}/apicert.pem" echo "$(date) - Setting config debug off" "${BIN_DIR}/config_debug.pl" -g "${GROUP}" off ${DOMAIN} if ! ngcpcfg apply "config debug off via kamailio-config-tests" ; then