- Add client certificate info for IExportProvider type in ExportController
- return object in ExportFactory->getProvider()
- Add getFilename(), getFileType(), getContent() to interface IExportProvider and basic implementation for PlainOpenVPN
- Frontend (export.volt), use returned api info to generate download
This commit is contained in:
Ad Schellevis 2018-10-30 18:13:50 +01:00
parent 1d9b7ef480
commit fbb1dd39b8
5 changed files with 110 additions and 12 deletions

View File

@ -29,6 +29,7 @@
namespace OPNsense\OpenVPN\Api;
use \OPNsense\Base\ApiControllerBase;
use \OPNsense\Base\UserException;
use \OPNsense\Core\Config;
use \OPNsense\Core\Backend;
use \OPNsense\OpenVPN\Export;
@ -317,9 +318,10 @@ class ExportController extends ApiControllerBase
if ($server !== null) {
// fetch server config data
$config = array();
foreach (array('disable', 'local_port', 'protocol', 'crypto', 'digest', 'tunnel_networkv6', 'reneg-sec',
'local_network', 'local_networkv6', 'tunnel_network', 'compression', 'passtos', 'shared_key',
'mode', 'dev_mode', 'tls', 'client_mgmt_port') as $field) {
foreach (array('disable', 'description', 'local_port', 'protocol', 'crypto', 'digest',
'tunnel_networkv6', 'reneg-sec', 'local_network', 'local_networkv6',
'tunnel_network', 'compression', 'passtos', 'shared_key', 'mode',
'dev_mode', 'tls', 'client_mgmt_port') as $field) {
if (!empty($server->$field)) {
$config[$field] = (string)$server->$field;
} else {
@ -329,6 +331,7 @@ class ExportController extends ApiControllerBase
// fetch associated certificate data, add to config
$config['server_ca_chain'] = array();
$config['server_cn'] = null;
$config['server_cert_is_srv'] = null;
if (!empty($server->certref)) {
if (isset(Config::getInstance()->object()->cert)) {
foreach (Config::getInstance()->object()->cert as $cert) {
@ -355,6 +358,24 @@ class ExportController extends ApiControllerBase
}
}
}
if ($certref !== null) {
if (isset(Config::getInstance()->object()->cert)) {
foreach (Config::getInstance()->object()->cert as $cert) {
if (isset($cert->refid) && (string)$certref == $cert->refid) {
// certificate CN
$str_crt = base64_decode((string)$cert->crt);
$inf_crt = openssl_x509_parse($str_crt);
$config['client_cn'] = $inf_crt['subject']['CN'];
$config['client_crt'] = (string)$cert->crt;
$config['client_prv'] = (string)$cert->prv;
}
}
}
if (empty($config['client_cn'])) {
throw new UserException("Client certificate not found", gettext("OpenVPN export"));
}
}
// overlay (saved) user settings
if ($this->request->hasPost('openvpn_export')) {
$response = $this->storePresetsAction($vpnid);
@ -364,12 +385,16 @@ class ExportController extends ApiControllerBase
$config[$key] = (string)$value;
}
}
// request config generation
$factory = new ExportFactory();
$provider = $factory->getProvider($config['template']);
if ($provider !== null) {
$provider->setConfig($config);
// TODO: execute provider and fetch content
if ($response['result'] == 'ok') {
// request config generation
$factory = new ExportFactory();
$provider = $factory->getProvider($config['template']);
if ($provider !== null) {
$provider->setConfig($config);
$response['filename'] = $provider->getFilename();
$response['filetype'] = $provider->getFileType();
$response['content'] = base64_encode($provider->getContent());
}
}
}
}

View File

@ -73,7 +73,7 @@ class ExportFactory
{
$providers = $this->listProviders();
if (!empty($providers[$className])) {
return $providers[$className];
return $providers[$className]['handle'];
} else {
return null;
}

View File

@ -44,4 +44,19 @@ interface IExportProvider
* @return array list of supported options, so the user interface can hide the non supported ones
*/
public function supportedOptions();
/**
* @return string filename
*/
public function getFilename();
/**
* @return string file type
*/
public function getFileType();
/**
* @return string|binary content data
*/
public function getContent();
}

View File

@ -38,4 +38,53 @@ class PlainOpenVPN extends BaseExporter implements IExportProvider
{
return array("testxx1", "testxx3");
}
/**
* @return string filename
*/
public function getFilename()
{
$result = array();
if (!empty($this->config['description'])) {
$result[] = $this->config['description'];
} else {
$result[] = "openvpn";
}
if (!empty($this->config['client_cn'])) {
$result[] = $this->config['client_cn'];
}
return implode("_", $result) . ".ovpn";
}
/**
* @return string file type
*/
public function getFileType()
{
return "text/plain";
}
/**
* @return array
*/
protected function openvpnConfParts()
{
$conf = array();
if (isset($this->config['dev_mode'])) {
$conf[] = "dev {$this->config['dev_mode']}";
}
$conf[] = "persist-tun";
$conf[] = "persist-key";
return $conf;
}
/**
* @return string content
*/
public function getContent()
{
return implode("\n", $this->openvpnConfParts());
}
}

View File

@ -106,8 +106,17 @@ POSSIBILITY OF SUCH DAMAGE.
var caref = $(this).data('certref');
var vpnid = $("#openvpn_export\\.servers").find('option:selected').val();
saveFormToEndpoint("/api/openvpn/export/download/"+vpnid+"/"+caref+"/",'frm_ExportSettings', function(data){
// TODO: error handling + download to client when successful
console.log(data);
if (data.filename !== undefined) {
var link = $('<a></a>')
.attr('href','data:'+data.filetype+';charset=utf8,' + encodeURIComponent(atob(data.content)))
.attr('download', data.filename)
.appendTo('body');
link.ready(function() {
link.get(0).click();
link.empty();
});
}
});
});
}