From 71620f6b8e70948df4b49a48a3d79596e9ff01b8 Mon Sep 17 00:00:00 2001 From: Andreas Granig Date: Fri, 12 Dec 2014 23:41:40 +0100 Subject: [PATCH] MT#10587 Encrypt Yealink configs. --- debian/control | 2 ++ lib/NGCP/Panel/Controller/API/PbxDevices.pm | 6 ++++ lib/NGCP/Panel/Controller/Customer.pm | 6 ++++ lib/NGCP/Panel/Controller/Device.pm | 40 +++++++++++++++++---- 4 files changed, 47 insertions(+), 7 deletions(-) diff --git a/debian/control b/debian/control index 5622419a9f..4bfe19ea12 100644 --- a/debian/control +++ b/debian/control @@ -13,6 +13,7 @@ Build-Depends: debhelper (>= 8), libcatalyst-perl (>= 5.90040), libcatalyst-view-tt-perl, libconvert-ascii85-perl, + libcrypt-rijndael-perl, libdata-hal-perl, libdata-printer-perl, libdata-validate-ip-perl, @@ -80,6 +81,7 @@ Depends: gettext, libcatalyst-view-tt-perl, libconfig-general-perl, libconvert-ascii85-perl, + libcrypt-rijndael-perl, libdata-hal-perl, libdata-printer-perl, libdata-record-perl, diff --git a/lib/NGCP/Panel/Controller/API/PbxDevices.pm b/lib/NGCP/Panel/Controller/API/PbxDevices.pm index a6f121caa8..708e6add77 100644 --- a/lib/NGCP/Panel/Controller/API/PbxDevices.pm +++ b/lib/NGCP/Panel/Controller/API/PbxDevices.pm @@ -250,6 +250,12 @@ sub POST :Allow { identifier => $resource->{identifier}, station_name => $resource->{station_name}, }); + if($dev_model->bootstrap_method eq "redirect_yealink") { + my @chars = ("A".."Z", "a".."z", "0".."9"); + my $device_key = ""; + $device_key .= $chars[rand @chars] for 0 .. 15; + $device->update({ encryption_key => $device_key }); + } my $err = NGCP::Panel::Utils::DeviceBootstrap::dispatch($c, 'register', $device); die $err if($err); for my $line ( @{$resource->{lines}} ) { diff --git a/lib/NGCP/Panel/Controller/Customer.pm b/lib/NGCP/Panel/Controller/Customer.pm index 7944dab8a2..22d9e25539 100644 --- a/lib/NGCP/Panel/Controller/Customer.pm +++ b/lib/NGCP/Panel/Controller/Customer.pm @@ -1138,6 +1138,12 @@ sub pbx_device_create :Chained('base') :PathPart('pbx/device/create') :Args(0) { identifier => $identifier, station_name => $station_name, }); + if($fdev->profile->config->device->bootstrap_method eq "redirect_yealink") { + my @chars = ("A".."Z", "a".."z", "0".."9"); + my $device_key = ""; + $device_key .= $chars[rand @chars] for 0 .. 15; + $fdev->update({ encryption_key => $device_key }); + } $err = NGCP::Panel::Utils::DeviceBootstrap::dispatch( $c, 'register', $fdev); diff --git a/lib/NGCP/Panel/Controller/Device.pm b/lib/NGCP/Panel/Controller/Device.pm index 9dec73b270..5f129179b6 100644 --- a/lib/NGCP/Panel/Controller/Device.pm +++ b/lib/NGCP/Panel/Controller/Device.pm @@ -2,6 +2,7 @@ package NGCP::Panel::Controller::Device; use Sipwise::Base; use Template; +use Crypt::Rijndael; use NGCP::Panel::Form::Device::Model; use NGCP::Panel::Form::Device::ModelAdmin; use NGCP::Panel::Form::Device::Firmware; @@ -1069,13 +1070,8 @@ sub dev_field_config :Chained('/') :PathPart('device/autoprov/config') :Args() { return; } - my $schema = $c->config->{deviceprovisioning}->{secure} ? 'https' : 'http'; - my $host = $c->config->{deviceprovisioning}->{host} // $c->req->uri->host; - my $port = $c->config->{deviceprovisioning}->{port} // 1444; - $id =~ s/\.cfg$//; if($c->req->user_agent =~ /PolycomVVX/) { - $id =~ s/\.cfg$//; $c->response->content_type('text/xml'); $c->response->body( ''. @@ -1093,6 +1089,12 @@ sub dev_field_config :Chained('/') :PathPart('device/autoprov/config') :Args() { $id = lc $id; $id =~ s/\-phone\.cfg$//; # polycoms send a -phone.cfg suffix + my $yealink_key; + if($id =~ s/_secure\.enc$//) { + # mark to serve master-encrypted device key instead of config + $yealink_key = $c->config->{autoprovisioning}->{yealink_key}; + } + my $dev = $c->model('DB')->resultset('autoprov_field_devices')->find({ identifier => $id }); @@ -1107,8 +1109,23 @@ sub dev_field_config :Chained('/') :PathPart('device/autoprov/config') :Args() { return; } + if($yealink_key && defined $dev->encryption_key) { + my $cipher = Crypt::Rijndael->new( + $yealink_key, Crypt::Rijndael::MODE_ECB() + ); + $c->response->content_type('text/plain'); + $c->response->body($cipher->encrypt($dev->encryption_key)); + $c->response->status(200); + return; + } + my $model = $dev->profile->config->device; + # TODO: only if not set in model config! + my $schema = $c->config->{deviceprovisioning}->{secure} ? 'https' : 'http'; + my $host = $c->config->{deviceprovisioning}->{host} // $c->req->uri->host; + my $port = $c->config->{deviceprovisioning}->{port} // 1444; + my $vars = { config => { url => "$schema://$host:$port/device/autoprov/config/$id", @@ -1203,8 +1220,17 @@ sub dev_field_config :Chained('/') :PathPart('device/autoprov/config') :Args() { $c->log->debug("providing config to $id"); $c->log->debug($processed_data); - $c->response->content_type($dev->profile->config->content_type); - $c->response->body($processed_data); + if(defined $dev->encryption_key) { + # yealink uses weak ECB mode, but well... + my $cipher = Crypt::Rijndael->new( + $dev->encryption_key, Crypt::Rijndael::MODE_ECB() + ); + $c->response->content_type("application/octet-stream"); + $c->response->body($cipher->encrypt($processed_data)); + } else { + $c->response->content_type($dev->profile->config->content_type); + $c->response->body($processed_data); + } } sub dev_static_jitsi_config :Chained('/') :PathPart('device/autoprov/static/jitsi') :Args(0) {