mirror of
https://github.com/netbirdio/plugins.git
synced 2026-05-22 18:44:07 -07:00
(tinc) work in progress
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
PLUGIN_NAME= tinc
|
||||
PLUGIN_VERSION= 0.1
|
||||
PLUGIN_COMMENT= Tinc VPN
|
||||
PLUGIN_DEPENDS= tinc
|
||||
PLUGIN_MAINTAINER= ad@opnsense.org
|
||||
|
||||
.include "../../Mk/plugins.mk"
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2016 Deciso B.V.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
namespace OPNsense\Tinc\Api;
|
||||
|
||||
use \OPNsense\Base\ApiControllerBase;
|
||||
use \OPNsense\Core\Backend;
|
||||
|
||||
/**
|
||||
* Class ServiceController
|
||||
* @package OPNsense\Tinc
|
||||
*/
|
||||
class ServiceController extends ApiControllerBase
|
||||
{
|
||||
|
||||
/**
|
||||
* reconfigure captive portal
|
||||
*/
|
||||
public function reconfigureAction()
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
// close session for long running action
|
||||
$this->sessionClose();
|
||||
$backend = new Backend();
|
||||
$backend->configdRun('template reload OPNsense/Tinc');
|
||||
return array("status" => "ok");
|
||||
} else {
|
||||
return array("status" => "failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,250 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2016 Deciso B.V.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
namespace OPNsense\Tinc\Api;
|
||||
|
||||
use \OPNsense\Base\ApiMutableModelControllerBase;
|
||||
use \OPNsense\Base\UIModelGrid;
|
||||
use \OPNsense\Core\Backend;
|
||||
|
||||
/**
|
||||
* Class SettingsController Handles settings related API actions for Tinc VPN
|
||||
* @package OPNsense\Tinc
|
||||
*/
|
||||
class SettingsController extends ApiMutableModelControllerBase
|
||||
{
|
||||
static protected $internalModelName = 'tinc';
|
||||
static protected $internalModelClass = '\OPNsense\Tinc\Tinc';
|
||||
|
||||
/**
|
||||
* get network action
|
||||
* @param string $uuid item unique id
|
||||
* @return array
|
||||
*/
|
||||
public function getNetworkAction($uuid = null)
|
||||
{
|
||||
if ($uuid == null) {
|
||||
// generate new node, but don't save to disc
|
||||
$node = $this->getModel()->networks->network->Add();
|
||||
return array("network" => $node->getNodes());
|
||||
} else {
|
||||
$node = $this->getModel()->getNodeByReference('networks.network.'.$uuid);
|
||||
if ($node != null) {
|
||||
// return node
|
||||
return array("network" => $node->getNodes());
|
||||
}
|
||||
}
|
||||
return array() ;
|
||||
}
|
||||
|
||||
/**
|
||||
* set network action
|
||||
* @param string $uuid item unique id
|
||||
* @return array
|
||||
*/
|
||||
public function setNetworkAction($uuid = null)
|
||||
{
|
||||
if ($this->request->isPost() && $this->request->hasPost("network")) {
|
||||
if ($uuid != null) {
|
||||
$node = $this->getModel()->getNodeByReference('networks.network.'.$uuid);
|
||||
} else {
|
||||
$node = $this->getModel()->networks->network->Add();
|
||||
}
|
||||
$node->setNodes($this->request->getPost("network"));
|
||||
if (empty((string)$node->pubkey) || empty((string)$node->privkey)){
|
||||
// generate new keypair
|
||||
$backend = new Backend();
|
||||
$keys = json_decode(trim($backend->configdRun("tinc gen-key")), true);
|
||||
$node->pubkey = (string)$keys['pub'];
|
||||
$node->privkey = $keys['priv'];
|
||||
}
|
||||
return $this->validateAndSave($node, 'network');
|
||||
}
|
||||
return array("result"=>"failed");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* search user defined rules
|
||||
* @return array list of found user rules
|
||||
*/
|
||||
public function searchNetworkAction()
|
||||
{
|
||||
$this->sessionClose();
|
||||
$grid = new UIModelGrid($this->getModel()->networks->network);
|
||||
return $grid->fetchBindRequest(
|
||||
$this->request,
|
||||
array("enabled", "name"),
|
||||
"name"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* del network action
|
||||
* @param string $uuid item unique id
|
||||
* @return array
|
||||
*/
|
||||
public function delNetworkAction($uuid)
|
||||
{
|
||||
$result = array('result' => 'failed');
|
||||
if ($this->request->isPost()) {
|
||||
if ($this->getModel()->networks->network->del($uuid)) {
|
||||
$result = $this->validateAndSave();
|
||||
}
|
||||
}
|
||||
return $result ;
|
||||
}
|
||||
|
||||
/**
|
||||
* toggle network item action
|
||||
* @param string $uuid item unique id
|
||||
* @param boolean $enabled
|
||||
* @return array
|
||||
*/
|
||||
public function toggleNetworkAction($uuid, $enabled = null)
|
||||
{
|
||||
$result = array("result" => "failed");
|
||||
if ($this->request->isPost()) {
|
||||
if ($uuid != null) {
|
||||
$node = $this->getModel()->getNodeByReference('networks.network.' . $uuid);
|
||||
if ($node != null) {
|
||||
if ($enabled == "0" || $enabled == "1") {
|
||||
$node->enabled = (string)$enabled;
|
||||
} elseif ((string)$node->enabled == "1") {
|
||||
$node->enabled = "0";
|
||||
} else {
|
||||
$node->enabled = "1";
|
||||
}
|
||||
$result['result'] = $node->enabled;
|
||||
$this->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* get host action
|
||||
* @param string $uuid item unique id
|
||||
* @return array
|
||||
*/
|
||||
public function getHostAction($uuid = null)
|
||||
{
|
||||
if ($uuid == null) {
|
||||
// generate new node, but don't save to disc
|
||||
$node = $this->getModel()->hosts->host->Add();
|
||||
return array("host" => $node->getNodes());
|
||||
} else {
|
||||
$node = $this->getModel()->getNodeByReference('hosts.host.'.$uuid);
|
||||
if ($node != null) {
|
||||
// return node
|
||||
return array("host" => $node->getNodes());
|
||||
}
|
||||
}
|
||||
return array() ;
|
||||
}
|
||||
|
||||
/**
|
||||
* set host action
|
||||
* @param string $uuid item unique id
|
||||
* @return array
|
||||
*/
|
||||
public function setHostAction($uuid = null)
|
||||
{
|
||||
if ($this->request->isPost() && $this->request->hasPost("host")) {
|
||||
if ($uuid != null) {
|
||||
$node = $this->getModel()->getNodeByReference('hosts.host.'.$uuid);
|
||||
} else {
|
||||
$node = $this->getModel()->hosts->host->Add();
|
||||
}
|
||||
$node->setNodes($this->request->getPost("host"));
|
||||
return $this->validateAndSave($node, 'host');
|
||||
}
|
||||
return array("result"=>"failed");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* search user defined rules
|
||||
* @return array list of found user rules
|
||||
*/
|
||||
public function searchHostAction()
|
||||
{
|
||||
$this->sessionClose();
|
||||
$grid = new UIModelGrid($this->getModel()->hosts->host);
|
||||
return $grid->fetchBindRequest(
|
||||
$this->request,
|
||||
array("enabled", "hostname", 'network'),
|
||||
"name"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* del host action
|
||||
* @param string $uuid item unique id
|
||||
* @return array
|
||||
*/
|
||||
public function delHostAction($uuid)
|
||||
{
|
||||
$result = array('result' => 'failed');
|
||||
if ($this->request->isPost()) {
|
||||
if ($this->getModel()->hosts->host->del($uuid)) {
|
||||
$result = $this->validateAndSave();
|
||||
}
|
||||
}
|
||||
return $result ;
|
||||
}
|
||||
|
||||
/**
|
||||
* toggle host item action
|
||||
* @param string $uuid item unique id
|
||||
* @param boolean $enabled
|
||||
* @return array
|
||||
*/
|
||||
public function toggleHostAction($uuid, $enabled = null)
|
||||
{
|
||||
$result = array("result" => "failed");
|
||||
if ($this->request->isPost()) {
|
||||
if ($uuid != null) {
|
||||
$node = $this->getModel()->getNodeByReference('hosts.host.' . $uuid);
|
||||
if ($node != null) {
|
||||
if ($enabled == "0" || $enabled == "1") {
|
||||
$node->enabled = (string)$enabled;
|
||||
} elseif ((string)$node->enabled == "1") {
|
||||
$node->enabled = "0";
|
||||
} else {
|
||||
$node->enabled = "1";
|
||||
}
|
||||
$result['result'] = $node->enabled;
|
||||
$this->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2016 Deciso B.V.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OPNsense\Tinc;
|
||||
|
||||
/**
|
||||
* Class IndexController
|
||||
* @package OPNsense\Tinc
|
||||
*/
|
||||
class IndexController extends \OPNsense\Base\IndexController
|
||||
{
|
||||
public function indexAction()
|
||||
{
|
||||
$this->view->title = gettext('Tinc VPN');
|
||||
// link dialogs
|
||||
$this->view->formDialogNetwork = $this->getForm("dialogNetwork");
|
||||
$this->view->formDialogHost = $this->getForm("dialogHost");
|
||||
// choose template
|
||||
$this->view->pick('OPNsense/Tinc/index');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<form>
|
||||
<field>
|
||||
<id>host.enabled</id>
|
||||
<label>Enabled</label>
|
||||
<type>checkbox</type>
|
||||
<help>Enable this network</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>host.network</id>
|
||||
<label>Network</label>
|
||||
<type>dropdown</type>
|
||||
<help>The network for this host</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>host.hostname</id>
|
||||
<label>Hostname</label>
|
||||
<type>text</type>
|
||||
<help>The hostname for the selected machine in the network</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>host.extaddress</id>
|
||||
<label>Ext. Address</label>
|
||||
<type>text</type>
|
||||
<help>This machines external address to use</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>host.subnet</id>
|
||||
<label>Subnet</label>
|
||||
<type>text</type>
|
||||
<help>This machines part of the network</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>host.pubkey</id>
|
||||
<label>Public key</label>
|
||||
<type>textbox</type>
|
||||
<help>Public key for this host in the network</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>host.connectTo</id>
|
||||
<label>Connect To</label>
|
||||
<type>checkbox</type>
|
||||
<help>Connect to this host</help>
|
||||
</field>
|
||||
</form>
|
||||
@@ -0,0 +1,60 @@
|
||||
<form>
|
||||
<field>
|
||||
<id>network.enabled</id>
|
||||
<label>Enabled</label>
|
||||
<type>checkbox</type>
|
||||
<help>Enable this network</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>network.name</id>
|
||||
<label>Network Name</label>
|
||||
<type>text</type>
|
||||
<help>Name used for this network</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>network.network</id>
|
||||
<label>VPN network</label>
|
||||
<type>text</type>
|
||||
<help>Network for this VPN, where all hosts should fit in.</help>
|
||||
</field>
|
||||
<field>
|
||||
<label>This Host</label>
|
||||
<type>header</type>
|
||||
</field>
|
||||
<field>
|
||||
<id>network.hostname</id>
|
||||
<label>Hostname</label>
|
||||
<type>text</type>
|
||||
<help>The hostname for this machine in the network</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>network.extaddress</id>
|
||||
<label>Ext. Address</label>
|
||||
<type>text</type>
|
||||
<help>This machines external address to use</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>network.intaddress</id>
|
||||
<label>Int. Address</label>
|
||||
<type>text</type>
|
||||
<help>This machines internal address to use (within specified subnet)</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>network.subnet</id>
|
||||
<label>Subnet</label>
|
||||
<type>text</type>
|
||||
<help>This machines part of the network</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>network.privkey</id>
|
||||
<label>Private key</label>
|
||||
<type>textbox</type>
|
||||
<help>Private key for this host in the network (leave empty to generate)</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>network.pubkey</id>
|
||||
<label>Public key</label>
|
||||
<type>textbox</type>
|
||||
<help>Public key for this host in the network (leave empty to generate)</help>
|
||||
</field>
|
||||
</form>
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2016 Deciso B.V.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
namespace OPNsense\Tinc;
|
||||
|
||||
use OPNsense\Base\BaseModel;
|
||||
|
||||
/**
|
||||
* Class Tinc
|
||||
* @package OPNsense\Tinc
|
||||
*/
|
||||
class Tinc extends BaseModel
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
<model>
|
||||
<mount>//OPNsense/Tinc</mount>
|
||||
<version>1.0.0</version>
|
||||
<description>
|
||||
OPNsense Tinc VPN
|
||||
</description>
|
||||
<items>
|
||||
<networks>
|
||||
<network type="ArrayField">
|
||||
<id type="AutoNumberField">
|
||||
<ValidationMessage>ID should be a number.</ValidationMessage>
|
||||
<Required>Y</Required>
|
||||
</id>
|
||||
<name type="TextField">
|
||||
<Required>Y</Required>
|
||||
<mask>/^([0-9a-zA-Z]){1,50}$/u</mask>
|
||||
<ValidationMessage>The name should contain only alphanumeric characters.</ValidationMessage>
|
||||
</name>
|
||||
<hostname type="TextField">
|
||||
<Required>Y</Required>
|
||||
<mask>/^([0-9a-zA-Z\.]){1,1024}$/u</mask>
|
||||
<ValidationMessage>Please specify a valid hostname.</ValidationMessage>
|
||||
</hostname>
|
||||
<extaddress type="NetworkField">
|
||||
<Required>Y</Required>
|
||||
<WildcardEnabled>N</WildcardEnabled>
|
||||
<FieldSeparator>,</FieldSeparator>
|
||||
</extaddress>
|
||||
<intaddress type="NetworkField">
|
||||
<Required>Y</Required>
|
||||
<WildcardEnabled>N</WildcardEnabled>
|
||||
</intaddress>
|
||||
<subnet type="NetworkField">
|
||||
<Required>Y</Required>
|
||||
<WildcardEnabled>N</WildcardEnabled>
|
||||
<NetMaskRequired>Y</NetMaskRequired>
|
||||
<FieldSeparator>,</FieldSeparator>
|
||||
</subnet>
|
||||
<network type="NetworkField">
|
||||
<Required>Y</Required>
|
||||
<WildcardEnabled>N</WildcardEnabled>
|
||||
<NetMaskRequired>Y</NetMaskRequired>
|
||||
</network>
|
||||
<privkey type="TextField">
|
||||
<Required>Y</Required>
|
||||
</privkey>
|
||||
<pubkey type="TextField">
|
||||
<Required>Y</Required>
|
||||
</pubkey>
|
||||
<enabled type="BooleanField">
|
||||
<default>1</default>
|
||||
<Required>Y</Required>
|
||||
</enabled>
|
||||
</network>
|
||||
</networks>
|
||||
<hosts>
|
||||
<host type="ArrayField">
|
||||
<network type="ModelRelationField">
|
||||
<Model>
|
||||
<hosts>
|
||||
<source>OPNsense.Tinc.Tinc</source>
|
||||
<items>networks.network</items>
|
||||
<display>name</display>
|
||||
</hosts>
|
||||
</Model>
|
||||
<ValidationMessage>Related pipe or queue not found</ValidationMessage>
|
||||
<Required>Y</Required>
|
||||
</network>
|
||||
<hostname type="TextField">
|
||||
<Required>Y</Required>
|
||||
<mask>/^([0-9a-zA-Z\.]){1,1024}$/u</mask>
|
||||
<ValidationMessage>Please specify a valid hostname.</ValidationMessage>
|
||||
</hostname>
|
||||
<extaddress type="NetworkField">
|
||||
<Required>Y</Required>
|
||||
<WildcardEnabled>N</WildcardEnabled>
|
||||
<FieldSeparator>,</FieldSeparator>
|
||||
</extaddress>
|
||||
<subnet type="NetworkField">
|
||||
<Required>Y</Required>
|
||||
<WildcardEnabled>N</WildcardEnabled>
|
||||
<NetMaskRequired>Y</NetMaskRequired>
|
||||
<FieldSeparator>,</FieldSeparator>
|
||||
</subnet>
|
||||
<pubkey type="TextField">
|
||||
<Required>Y</Required>
|
||||
</pubkey>
|
||||
<connectTo type="BooleanField">
|
||||
<default>1</default>
|
||||
<Required>Y</Required>
|
||||
</connectTo>
|
||||
<enabled type="BooleanField">
|
||||
<default>1</default>
|
||||
<Required>Y</Required>
|
||||
</enabled>
|
||||
</host>
|
||||
</hosts>
|
||||
</items>
|
||||
</model>
|
||||
@@ -0,0 +1,155 @@
|
||||
{#
|
||||
|
||||
OPNsense® is Copyright © 2014 – 2016 by Deciso B.V.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#}
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
$( document ).ready(function() {
|
||||
/*************************************************************************************************************
|
||||
* link grid actions
|
||||
*************************************************************************************************************/
|
||||
|
||||
$("#grid-networks").UIBootgrid(
|
||||
{ search:'/api/tinc/settings/searchNetwork',
|
||||
get:'/api/tinc/settings/getNetwork/',
|
||||
set:'/api/tinc/settings/setNetwork/',
|
||||
add:'/api/tinc/settings/setNetwork/',
|
||||
del:'/api/tinc/settings/delNetwork/',
|
||||
toggle:'/api/tinc/settings/toggleNetwork/'
|
||||
}
|
||||
);
|
||||
|
||||
$("#grid-hosts").UIBootgrid(
|
||||
{ search:'/api/tinc/settings/searchHost',
|
||||
get:'/api/tinc/settings/getHost/',
|
||||
set:'/api/tinc/settings/setHost/',
|
||||
add:'/api/tinc/settings/setHost/',
|
||||
del:'/api/tinc/settings/delHost/',
|
||||
toggle:'/api/tinc/settings/toggleHost/'
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
/*************************************************************************************************************
|
||||
* Commands
|
||||
*************************************************************************************************************/
|
||||
|
||||
/**
|
||||
* Reconfigure
|
||||
*/
|
||||
$("#reconfigureAct").click(function(){
|
||||
$("#reconfigureAct_progress").addClass("fa fa-spinner fa-pulse");
|
||||
ajaxCall(url="/api/tinc/service/reconfigure", sendData={}, callback=function(data,status) {
|
||||
// when done, disable progress animation.
|
||||
$("#reconfigureAct_progress").removeClass("fa fa-spinner fa-pulse");
|
||||
|
||||
if (status != "success" || data['status'] != 'ok') {
|
||||
BootstrapDialog.show({
|
||||
type: BootstrapDialog.TYPE_WARNING,
|
||||
title: "{{ lang._('Error reconfiguring Tinc') }}",
|
||||
message: data['status'],
|
||||
draggable: true
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<ul class="nav nav-tabs" data-tabs="tabs" id="maintabs">
|
||||
<li class="active"><a data-toggle="tab" href="#networks">{{ lang._('Networks') }}</a></li>
|
||||
<li><a data-toggle="tab" href="#hosts">{{ lang._('Hosts') }}</a></li>
|
||||
</ul>
|
||||
<div class="tab-content content-box tab-content">
|
||||
<div id="networks" class="tab-pane fade in active">
|
||||
<!-- tab page "networks" -->
|
||||
<table id="grid-networks" class="table table-condensed table-hover table-striped table-responsive" data-editDialog="DialogNetwork">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-column-id="enabled" data-width="6em" data-type="string" data-formatter="rowtoggle">{{ lang._('Enabled') }}</th>
|
||||
<th data-column-id="id" data-type="number" data-visible="false">{{ lang._('ID') }}</th>
|
||||
<th data-column-id="name" data-type="string">{{ lang._('Name') }}</th>
|
||||
<th data-column-id="commands" data-width="7em" data-formatter="commands" data-sortable="false">{{ lang._('Commands') }}</th>
|
||||
<th data-column-id="uuid" data-type="string" data-identifier="true" data-visible="false">{{ lang._('ID') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>
|
||||
<button data-action="add" type="button" class="btn btn-xs btn-default"><span class="fa fa-plus"></span></button>
|
||||
<button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-trash-o"></span></button>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
<div id="hosts" class="tab-pane fade in">
|
||||
<div class="col-md-12">
|
||||
<!-- tab page "networks" -->
|
||||
<table id="grid-hosts" class="table table-condensed table-hover table-striped table-responsive" data-editDialog="DialogHost">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-column-id="enabled" data-width="6em" data-type="string" data-formatter="rowtoggle">{{ lang._('Enabled') }}</th>
|
||||
<th data-column-id="network" data-type="string">{{ lang._('Network') }}</th>
|
||||
<th data-column-id="hostname" data-type="string">{{ lang._('Hostname') }}</th>
|
||||
<th data-column-id="commands" data-width="7em" data-formatter="commands" data-sortable="false">{{ lang._('Commands') }}</th>
|
||||
<th data-column-id="uuid" data-type="string" data-identifier="true" data-visible="false">{{ lang._('ID') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>
|
||||
<button data-action="add" type="button" class="btn btn-xs btn-default"><span class="fa fa-plus"></span></button>
|
||||
<button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-trash-o"></span></button>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<hr/>
|
||||
<button class="btn btn-primary" id="reconfigureAct" type="button"><b>{{ lang._('Apply') }}</b><i id="reconfigureAct_progress" class=""></i></button>
|
||||
<br/><br/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{# include dialogs #}
|
||||
{{ partial("layout_partials/base_dialog",['fields':formDialogNetwork,'id':'DialogNetwork','label':'Edit Network'])}}
|
||||
{{ partial("layout_partials/base_dialog",['fields':formDialogHost,'id':'DialogHost','label':'Edit Host'])}}
|
||||
@@ -0,0 +1,55 @@
|
||||
#!/usr/local/bin/python2.7
|
||||
|
||||
"""
|
||||
Copyright (c) 2016 Deciso B.V. - Ad Schellevis
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
generate new keypair
|
||||
"""
|
||||
import os
|
||||
import tempfile
|
||||
import glob
|
||||
import ujson
|
||||
|
||||
# create temp directory
|
||||
temp_dir = tempfile.mkdtemp()
|
||||
# generate certs
|
||||
os.system('echo | /usr/local/sbin/tincd -K --config=%s 2>/dev/null' % (temp_dir))
|
||||
|
||||
# read and remove certs
|
||||
response=dict()
|
||||
for filename in glob.glob('%s/*'%temp_dir):
|
||||
data = open(filename,'r').read().strip()
|
||||
if filename.endswith('.priv'):
|
||||
response['priv'] = data
|
||||
elif filename.endswith('.pub'):
|
||||
response['pub'] = data
|
||||
os.remove(filename)
|
||||
|
||||
# cleanup
|
||||
os.rmdir(temp_dir)
|
||||
|
||||
# output generated keys
|
||||
print(ujson.dumps(response))
|
||||
@@ -0,0 +1,116 @@
|
||||
"""
|
||||
Copyright (c) 2016 Deciso B.V. - Ad Schellevis
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
"""
|
||||
|
||||
class NetwConfObject(object):
|
||||
def __init__(self):
|
||||
self._payload = dict()
|
||||
self._payload['hostname'] = None
|
||||
self._payload['network'] = None
|
||||
|
||||
def is_valid(self):
|
||||
for key in self._payload:
|
||||
if self._payload[key] is None:
|
||||
return False
|
||||
return True
|
||||
|
||||
def set(self, prop, value):
|
||||
if ('set_%s' % prop) in dir(self):
|
||||
getattr(self,'set_%s' % prop)(value)
|
||||
else:
|
||||
# default copy propery to _payload
|
||||
self._payload[prop] = value.text
|
||||
|
||||
def get_hostname(self):
|
||||
return self._payload['hostname']
|
||||
|
||||
def get_basepath(self):
|
||||
return '/usr/local/etc/tinc/%(network)s' % self._payload
|
||||
|
||||
class Network(NetwConfObject):
|
||||
def __init__(self):
|
||||
super(Network, self).__init__()
|
||||
self._payload['id'] = None
|
||||
self._payload['privkey'] = None
|
||||
self._hosts = list()
|
||||
|
||||
def set_id(self, value):
|
||||
self._payload['id'] = value.text
|
||||
|
||||
def set_hosts(self, hosts):
|
||||
for host in hosts:
|
||||
hostObj = Host()
|
||||
for host_prop in host:
|
||||
hostObj.set(host_prop.tag, host_prop)
|
||||
self._hosts.append(hostObj)
|
||||
|
||||
def config_text(self):
|
||||
result = list()
|
||||
result.append('AddressFamily=any')
|
||||
for host in self._hosts:
|
||||
if host.connect_to_this_host():
|
||||
result.append('ConnectTo = %s' % (host.get_hostname(),))
|
||||
result.append('Device=/dev/tinc%(id)s' % self._payload)
|
||||
result.append('Name=%(hostname)s' % self._payload)
|
||||
return '\n'.join(result)
|
||||
|
||||
def filename(self):
|
||||
return self.get_basepath() + '/tinc.conf'
|
||||
|
||||
def privkey(self):
|
||||
return {'filename': self.get_basepath() + '/rsa_key.priv', 'content': self._payload['privkey']}
|
||||
|
||||
def all(self):
|
||||
yield self
|
||||
for host in self._hosts:
|
||||
yield host
|
||||
|
||||
class Host(NetwConfObject):
|
||||
def __init__(self):
|
||||
super(Host, self).__init__()
|
||||
self._connectTo = "0"
|
||||
self._payload['address'] = None
|
||||
self._payload['subnet'] = None
|
||||
self._payload['pubkey'] = None
|
||||
|
||||
def connect_to_this_host(self):
|
||||
if self.is_valid() and self._connectTo == "1":
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def set_connectto(self, value):
|
||||
self._connectTo = value.text
|
||||
|
||||
def config_text(self):
|
||||
result = list()
|
||||
result.append('Address=%(address)s'%self._payload)
|
||||
result.append('Subnet=%(subnet)s'%self._payload)
|
||||
result.append(self._payload['pubkey'])
|
||||
return '\n'.join(result)
|
||||
|
||||
def filename(self):
|
||||
return '%s/hosts/%s' % (self.get_basepath(), self._payload['hostname'])
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
#!/usr/local/bin/python2.7
|
||||
|
||||
"""
|
||||
Copyright (c) 2016 Deciso B.V. - Ad Schellevis
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
reconfigure tincd, using the supplied configuration
|
||||
"""
|
||||
import os
|
||||
import tempfile
|
||||
import glob
|
||||
import xml.etree.ElementTree
|
||||
from lib import objects
|
||||
|
||||
def write_file(filename, content):
|
||||
dirname = '/'.join(filename.split('/')[0:-1])
|
||||
if not os.path.isdir(dirname):
|
||||
os.makedirs(dirname)
|
||||
open(filename, 'w').write(content)
|
||||
|
||||
def deploy(config_filename):
|
||||
# collect file info
|
||||
config_files=dict()
|
||||
if os.path.isfile(config_filename):
|
||||
for network in xml.etree.ElementTree.parse(config_filename).getroot():
|
||||
Network_obj = objects.Network()
|
||||
for network_prop in network:
|
||||
Network_obj.set(network_prop.tag, network_prop)
|
||||
# check if config is complete before collecting output files
|
||||
if Network_obj.is_valid():
|
||||
for conf_obj in Network_obj.all():
|
||||
if conf_obj.is_valid():
|
||||
config_files[conf_obj.filename()] = conf_obj.config_text()
|
||||
# private key
|
||||
tmp = Network_obj.privkey()
|
||||
config_files[tmp['filename']] = tmp['content']
|
||||
# remove previous configuration
|
||||
os.system('rm -rf /usr/local/etc/tinc')
|
||||
# write output
|
||||
for filename in config_files:
|
||||
write_file(filename, config_files[filename])
|
||||
|
||||
deploy('/usr/local/etc/tinc_deploy.xml')
|
||||
@@ -0,0 +1 @@
|
||||
tinc_deploy.xml:/usr/local/etc/tinc_deploy.xml
|
||||
@@ -0,0 +1,34 @@
|
||||
<networks>
|
||||
{% if helpers.exists('OPNsense.Tinc.networks.network') %}
|
||||
{% for network in helpers.toList('OPNsense.Tinc.networks.network', 'id') %}
|
||||
<network>
|
||||
<id>{{network.id}}</id>
|
||||
<hostname>{{network.hostname}}</hostname>
|
||||
<network>{{network.name}}</network>
|
||||
<privkey><![CDATA[{{network.privkey}}]]></privkey>
|
||||
<hosts>
|
||||
<host>
|
||||
<hostname>{{network.hostname}}</hostname>
|
||||
<network>{{network.name}}</network>
|
||||
<address>{{network.extaddress}}</address>
|
||||
<subnet>{{network.subnet}}</subnet>
|
||||
<pubkey><![CDATA[{{network.pubkey}}]]></pubkey>
|
||||
<connectto>0</connectto>
|
||||
</host>
|
||||
{% for host in helpers.toList('OPNsense.Tinc.hosts.host', 'hostname') %}
|
||||
{% if helpers.getUUID(host.network).id == network.id %}
|
||||
<host>
|
||||
<hostname>{{host.hostname}}</hostname>
|
||||
<network>{{network.name}}</network>
|
||||
<address>{{host.extaddress}}</address>
|
||||
<subnet>{{host.subnet}}</subnet>
|
||||
<pubkey><![CDATA[{{host.pubkey}}]]></pubkey>
|
||||
<connectto>{{host.connectTo}}</connectto>
|
||||
</host>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</hosts>
|
||||
</network>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</networks>
|
||||
Reference in New Issue
Block a user