mirror of
https://github.com/opnsense/plugins.git
synced 2026-05-28 04:34:15 -04:00
dns: migrated plugins from core
(cherry picked from commit4c57c258f1) (cherry picked from commit594a1f829c) (cherry picked from commit5a9b5bbcb9)
This commit is contained in:
parent
e5086ddc5c
commit
fb6c960756
26 changed files with 4128 additions and 1 deletions
2
Makefile
2
Makefile
|
|
@ -3,7 +3,7 @@ PAGER?= less
|
|||
all:
|
||||
@cat ${.CURDIR}/README.md | ${PAGER}
|
||||
|
||||
CATEGORIES= devel net net-mgmt sysutils security www
|
||||
CATEGORIES= devel dns net net-mgmt sysutils security www
|
||||
|
||||
.for CATEGORY in ${CATEGORIES}
|
||||
_${CATEGORY}!= ls -1d ${CATEGORY}/*
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ A list of currently available plugins
|
|||
```
|
||||
devel/debug -- Debugging Tools
|
||||
devel/helloworld -- A sample framework application
|
||||
dns/dyndns -- Dynamic DNS Support
|
||||
dns/rfc2136 -- RFC-2136 Support
|
||||
net/ftp-proxy -- Control ftp-proxy processes
|
||||
net/haproxy -- Reliable, high performance TCP/HTTP load balancer
|
||||
net/igmp-proxy -- IGMP-Proxy Service
|
||||
|
|
|
|||
7
dns/dyndns/Makefile
Normal file
7
dns/dyndns/Makefile
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
PLUGIN_NAME= dyndns
|
||||
PLUGIN_VERSION= 1.0
|
||||
PLUGIN_COMMENT= Dynamic DNS Support
|
||||
PLUGIN_MAINTAINER= franco@opnsense.org
|
||||
PLUGIN_DEVEL= yes
|
||||
|
||||
.include "../../Mk/plugins.mk"
|
||||
1
dns/dyndns/pkg-descr
Normal file
1
dns/dyndns/pkg-descr
Normal file
|
|
@ -0,0 +1 @@
|
|||
Support for numerous Dynamic DNS services (DynDNS et al)
|
||||
200
dns/dyndns/src/etc/inc/plugins.inc.d/dyndns.inc
Normal file
200
dns/dyndns/src/etc/inc/plugins.inc.d/dyndns.inc
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
Copyright (C) 2014-2017 Franco Fichtner <franco@opnsense.org>
|
||||
Copyright (C) 2010 Ermal Luci
|
||||
Copyright (C) 2005-2006 Colin Smith <ethethlay@gmail.com>
|
||||
Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>
|
||||
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.
|
||||
*/
|
||||
|
||||
require_once('plugins.inc.d/dyndns/phpDynDNS.inc');
|
||||
require_once('plugins.inc.d/dyndns/r53.inc');
|
||||
|
||||
function dyndns_configure()
|
||||
{
|
||||
return array(
|
||||
'bootup' => array('dyndns_configure_do'),
|
||||
'local' => array('dyndns_configure_do'),
|
||||
'newwanip' => array('dyndns_configure_do:2'),
|
||||
);
|
||||
}
|
||||
|
||||
function dyndns_enabled()
|
||||
{
|
||||
global $config;
|
||||
|
||||
if (isset($config['dyndnses']['dyndns'])) {
|
||||
foreach ($config['dyndnses']['dyndns'] as $conf) {
|
||||
if (isset($conf['enable'])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function dyndns_services()
|
||||
{
|
||||
global $config;
|
||||
|
||||
$services = array();
|
||||
|
||||
if (dyndns_enabled()) {
|
||||
$services[] = array(
|
||||
'description' => gettext('Dynamic DNS'),
|
||||
'configd' => array(
|
||||
'restart' => array('dyndns reload'),
|
||||
),
|
||||
'nocheck' => true,
|
||||
'name' => 'dyndns',
|
||||
);
|
||||
}
|
||||
|
||||
return $services;
|
||||
}
|
||||
|
||||
function dyndns_cron()
|
||||
{
|
||||
$jobs = array();
|
||||
|
||||
if (dyndns_enabled()) {
|
||||
$jobs[]['autocron'] = array('/usr/local/etc/rc.dyndns', '11', '1');
|
||||
}
|
||||
|
||||
return $jobs;
|
||||
}
|
||||
|
||||
function dyndns_list()
|
||||
{
|
||||
/*
|
||||
* XXX something like this would be cool:
|
||||
*
|
||||
* https://github.com/openwrt/packages/blob/master/net/ddns-scripts/files/services
|
||||
*/
|
||||
|
||||
return array(
|
||||
'3322' => '3322',
|
||||
'citynetwork' => 'City Network',
|
||||
'cloudflare' => 'CloudFlare',
|
||||
'custom' => 'Custom',
|
||||
'custom-v6' => 'Custom (v6)',
|
||||
'dhs' => 'DHS',
|
||||
'dnsexit' => 'DNSexit',
|
||||
'dnsomatic' => 'DNS-O-Matic',
|
||||
'duckdns' => 'Duck DNS',
|
||||
'dyndns' => 'DynDNS (dynamic)',
|
||||
'dyndns-custom' => 'DynDNS (custom)',
|
||||
'dyndns-static' => 'DynDNS (static)',
|
||||
'dyns' => 'DyNS',
|
||||
'easydns' => 'easyDNS',
|
||||
'eurodns' => 'EuroDNS',
|
||||
'freedns' => 'freeDNS',
|
||||
'googledomains' => 'Google Domains',
|
||||
'gratisdns' => 'GratisDNS',
|
||||
'he-net' => 'HE.net',
|
||||
'he-net-tunnelbroker' => 'HE.net Tunnelbroker',
|
||||
'he-net-v6' => 'HE.net (v6)',
|
||||
'loopia' => 'Loopia',
|
||||
'namecheap' => 'Namecheap',
|
||||
'noip' => 'No-IP',
|
||||
'noip-free' => 'No-IP (free)',
|
||||
'ods' => 'ODS.org',
|
||||
'opendns' => 'OpenDNS',
|
||||
'oray' => 'Oray',
|
||||
'ovh-dynhost' => 'OVH DynHOST',
|
||||
'route53' => 'Route 53',
|
||||
'selfhost' => 'SelfHost',
|
||||
'strato' => 'STRATO',
|
||||
'zoneedit' => 'ZoneEdit',
|
||||
);
|
||||
}
|
||||
|
||||
function dyndns_cache_file($conf, $ipver = 4)
|
||||
{
|
||||
$ipver = $ipver == 6 ? '_v6' : '';
|
||||
|
||||
return "/var/cache/dyndns_{$conf['interface']}_{$conf['host']}_{$conf['id']}{$ipver}.cache";
|
||||
}
|
||||
|
||||
function dyndns_configure_client($conf)
|
||||
{
|
||||
if (!isset($conf['enable'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$dns = new updatedns($dnsService = $conf['type'],
|
||||
$dnsHost = $conf['host'],
|
||||
$dnsUser = $conf['username'],
|
||||
$dnsPass = $conf['password'],
|
||||
$dnsWilcard = $conf['wildcard'],
|
||||
$dnsMX = $conf['mx'],
|
||||
$dnsIf = "{$conf['interface']}",
|
||||
$dnsBackMX = NULL,
|
||||
$dnsServer = NULL,
|
||||
$dnsPort = NULL,
|
||||
$dnsUpdateURL = "{$conf['updateurl']}",
|
||||
$forceUpdate = $conf['force'],
|
||||
$dnsZoneID=$conf['zoneid'],
|
||||
$dnsTTL=$conf['ttl'],
|
||||
$dnsResultMatch = "{$conf['resultmatch']}",
|
||||
$dnsRequestIf = "{$conf['requestif']}",
|
||||
$dnsID = "{$conf['id']}",
|
||||
$dnsVerboseLog = $conf['verboselog'],
|
||||
$curlIpresolveV4 = $conf['curl_ipresolve_v4'],
|
||||
$curlSslVerifypeer = $conf['curl_ssl_verifypeer']
|
||||
);
|
||||
}
|
||||
|
||||
function dyndns_configure_do($verbose = false, $int = '')
|
||||
{
|
||||
global $config;
|
||||
|
||||
if (!dyndns_enabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$dyndnscfg = $config['dyndnses']['dyndns'];
|
||||
$gwgroups = return_gateway_groups_array();
|
||||
|
||||
if ($verbose) {
|
||||
echo 'Configuring dynamic DNS clients...';
|
||||
flush();
|
||||
}
|
||||
|
||||
foreach ($dyndnscfg as $dyndns) {
|
||||
if ((empty($int)) || ($int == $dyndns['interface']) || (is_array($gwgroups[$dyndns['interface']]))) {
|
||||
$dyndns['verboselog'] = isset($dyndns['verboselog']);
|
||||
$dyndns['curl_ipresolve_v4'] = isset($dyndns['curl_ipresolve_v4']);
|
||||
$dyndns['curl_ssl_verifypeer'] = isset($dyndns['curl_ssl_verifypeer']);
|
||||
dyndns_configure_client($dyndns);
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
if ($verbose) {
|
||||
echo "done.\n";
|
||||
}
|
||||
}
|
||||
1302
dns/dyndns/src/etc/inc/plugins.inc.d/dyndns/phpDynDNS.inc
Normal file
1302
dns/dyndns/src/etc/inc/plugins.inc.d/dyndns/phpDynDNS.inc
Normal file
File diff suppressed because it is too large
Load diff
754
dns/dyndns/src/etc/inc/plugins.inc.d/dyndns/r53.inc
Normal file
754
dns/dyndns/src/etc/inc/plugins.inc.d/dyndns/r53.inc
Normal file
|
|
@ -0,0 +1,754 @@
|
|||
<?php
|
||||
/**
|
||||
*
|
||||
* Copyright (c) 2011, Dan Myers.
|
||||
* Parts copyright (c) 2008, Donovan Schonknecht.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
|
||||
*
|
||||
* This is a modified BSD license (the third clause has been removed).
|
||||
* The BSD license may be found here:
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
*
|
||||
* Amazon Route 53 is a trademark of Amazon.com, Inc. or its affiliates.
|
||||
*
|
||||
* Route53 is based on Donovan Schonknecht's Amazon S3 PHP class, found here:
|
||||
* http://undesigned.org.za/2007/10/22/amazon-s3-php-class
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Amazon Route53 PHP class
|
||||
*
|
||||
* @link http://sourceforge.net/projects/php-r53/
|
||||
* version 0.9.0
|
||||
*
|
||||
*/
|
||||
class Route53
|
||||
{
|
||||
const API_VERSION = '2010-10-01';
|
||||
|
||||
protected $__accessKey; // AWS Access key
|
||||
protected $__secretKey; // AWS Secret key
|
||||
protected $__host;
|
||||
|
||||
public function getAccessKey() { return $this->__accessKey; }
|
||||
public function getSecretKey() { return $this->__secretKey; }
|
||||
public function getHost() { return $this->__host; }
|
||||
|
||||
protected $__verifyHost = 1;
|
||||
protected $__verifyPeer = 1;
|
||||
|
||||
// verifyHost and verifyPeer determine whether curl verifies ssl certificates.
|
||||
// It may be necessary to disable these checks on certain systems.
|
||||
// These only have an effect if SSL is enabled.
|
||||
public function verifyHost() { return $this->__verifyHost; }
|
||||
public function enableVerifyHost($enable = true) { $this->__verifyHost = $enable; }
|
||||
|
||||
public function verifyPeer() { return $this->__verifyPeer; }
|
||||
public function enableVerifyPeer($enable = true) { $this->__verifyPeer = $enable; }
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $accessKey Access key
|
||||
* @param string $secretKey Secret key
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($accessKey = null, $secretKey = null, $host = 'route53.amazonaws.com') {
|
||||
if ($accessKey !== null && $secretKey !== null) {
|
||||
$this->setAuth($accessKey, $secretKey);
|
||||
}
|
||||
$this->__host = $host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set AWS access key and secret key
|
||||
*
|
||||
* @param string $accessKey Access key
|
||||
* @param string $secretKey Secret key
|
||||
* @return void
|
||||
*/
|
||||
public function setAuth($accessKey, $secretKey) {
|
||||
$this->__accessKey = $accessKey;
|
||||
$this->__secretKey = $secretKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists the hosted zones on the account
|
||||
*
|
||||
* @param string marker A pagination marker returned by a previous truncated call
|
||||
* @param int maxItems The maximum number of items per page. The service uses min($maxItems, 100).
|
||||
* @return A list of hosted zones
|
||||
*/
|
||||
public function listHostedZones($marker = null, $maxItems = 100) {
|
||||
$rest = new Route53Request($this, 'hostedzone', 'GET');
|
||||
|
||||
if($marker !== null) {
|
||||
$rest->setParameter('marker', $marker);
|
||||
}
|
||||
if($maxItems !== 100) {
|
||||
$rest->setParameter('maxitems', $maxItems);
|
||||
}
|
||||
|
||||
$rest = $rest->getResponse();
|
||||
if($rest->error === false && $rest->code !== 200) {
|
||||
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
||||
}
|
||||
if($rest->error !== false) {
|
||||
$this->__triggerError('listHostedZones', $rest->error);
|
||||
return false;
|
||||
}
|
||||
|
||||
$response = array();
|
||||
if (!isset($rest->body))
|
||||
{
|
||||
return $response;
|
||||
}
|
||||
|
||||
$zones = array();
|
||||
foreach($rest->body->HostedZones->HostedZone as $z)
|
||||
{
|
||||
$zones[] = $this->parseHostedZone($z);
|
||||
}
|
||||
$response['HostedZone'] = $zones;
|
||||
|
||||
if(isset($rest->body->MaxItems)) {
|
||||
$response['MaxItems'] = (string)$rest->body->MaxItems;
|
||||
}
|
||||
|
||||
if(isset($rest->body->IsTruncated)) {
|
||||
$response['IsTruncated'] = (string)$rest->body->IsTruncated;
|
||||
if($response['IsTruncated'] == 'true') {
|
||||
$response['NextMarker'] = (string)$rest->body->NextMarker;
|
||||
}
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves information on a specified hosted zone
|
||||
*
|
||||
* @param string zoneId The id of the hosted zone, as returned by CreateHostedZoneResponse or ListHostedZoneResponse
|
||||
* In other words, if ListHostedZoneResponse shows the zone's Id as '/hostedzone/Z1PA6795UKMFR9',
|
||||
* then that full value should be passed here, including the '/hostedzone/' prefix.
|
||||
* @return A data structure containing information about the specified zone
|
||||
*/
|
||||
public function getHostedZone($zoneId) {
|
||||
// we'll strip off the leading forward slash, so we can use it as the action directly.
|
||||
$zoneId = trim($zoneId, '/');
|
||||
|
||||
$rest = new Route53Request($this, $zoneId, 'GET');
|
||||
|
||||
$rest = $rest->getResponse();
|
||||
if($rest->error === false && $rest->code !== 200) {
|
||||
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
||||
}
|
||||
if($rest->error !== false) {
|
||||
$this->__triggerError('getHostedZone', $rest->error);
|
||||
return false;
|
||||
}
|
||||
|
||||
$response = array();
|
||||
if (!isset($rest->body))
|
||||
{
|
||||
return $response;
|
||||
}
|
||||
|
||||
$response['HostedZone'] = $this->parseHostedZone($rest->body->HostedZone);
|
||||
$response['NameServers'] = $this->parseDelegationSet($rest->body->DelegationSet);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new hosted zone
|
||||
*
|
||||
* @param string name The name of the hosted zone (e.g. "example.com.")
|
||||
* @param string reference A user-specified unique reference for this request
|
||||
* @param string comment An optional user-specified comment to attach to the zone
|
||||
* @return A data structure containing information about the newly created zone
|
||||
*/
|
||||
public function createHostedZone($name, $reference, $comment = '') {
|
||||
// hosted zone names must end with a period, but people will forget this a lot...
|
||||
if(strrpos($name, '.') != (strlen($name) - 1)) {
|
||||
$name .= '.';
|
||||
}
|
||||
|
||||
$data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
|
||||
$data .= '<CreateHostedZoneRequest xmlns="https://route53.amazonaws.com/doc/'.Route53::API_VERSION."/\">\n";
|
||||
$data .= '<Name>'.$name."</Name>\n";
|
||||
$data .= '<CallerReference>'.$reference."</CallerReference>\n";
|
||||
if(strlen($comment) > 0) {
|
||||
$data .= "<HostedZoneConfig>\n";
|
||||
$data .= '<Comment>'.$comment."</Comment>\n";
|
||||
$data .= "</HostedZoneConfig>\n";
|
||||
}
|
||||
$data .= "</CreateHostedZoneRequest>\n";
|
||||
|
||||
$rest = new Route53Request($this, 'hostedzone', 'POST', $data);
|
||||
|
||||
$rest = $rest->getResponse();
|
||||
|
||||
if($rest->error === false && !in_array($rest->code, array(200, 201, 202, 204)) ) {
|
||||
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
||||
}
|
||||
if($rest->error !== false) {
|
||||
$this->__triggerError('createHostedZone', $rest->error);
|
||||
return false;
|
||||
}
|
||||
|
||||
$response = array();
|
||||
if (!isset($rest->body))
|
||||
{
|
||||
return $response;
|
||||
}
|
||||
|
||||
$response['HostedZone'] = $this->parseHostedZone($rest->body->HostedZone);
|
||||
$response['ChangeInfo'] = $this->parseChangeInfo($rest->body->ChangeInfo);
|
||||
$response['NameServers'] = $this->parseDelegationSet($rest->body->DelegationSet);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves information on a specified hosted zone
|
||||
*
|
||||
* @param string zoneId The id of the hosted zone, as returned by CreateHostedZoneResponse or ListHostedZoneResponse
|
||||
* In other words, if ListHostedZoneResponse shows the zone's Id as '/hostedzone/Z1PA6795UKMFR9',
|
||||
* then that full value should be passed here, including the '/hostedzone/' prefix.
|
||||
* @return The change request data corresponding to this delete
|
||||
*/
|
||||
public function deleteHostedZone($zoneId) {
|
||||
// we'll strip off the leading forward slash, so we can use it as the action directly.
|
||||
$zoneId = trim($zoneId, '/');
|
||||
|
||||
$rest = new Route53Request($this, $zoneId, 'DELETE');
|
||||
|
||||
$rest = $rest->getResponse();
|
||||
if($rest->error === false && $rest->code !== 200) {
|
||||
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
||||
}
|
||||
if($rest->error !== false) {
|
||||
$this->__triggerError('deleteHostedZone', $rest->error);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isset($rest->body))
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
return $this->parseChangeInfo($rest->body->ChangeInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a list of resource record sets for a given zone
|
||||
*
|
||||
* @param string zoneId The id of the hosted zone, as returned by CreateHostedZoneResponse or ListHostedZoneResponse
|
||||
* In other words, if ListHostedZoneResponse shows the zone's Id as '/hostedzone/Z1PA6795UKMFR9',
|
||||
* then that full value should be passed here, including the '/hostedzone/' prefix.
|
||||
* @param string type The type of resource record set to begin listing from. If this is specified, $name must also be specified.
|
||||
* Must be one of: A, AAAA, CNAME, MX, NS, PTR, SOA, SPF, SRV, TXT
|
||||
* @param string name The name at which to begin listing resource records (in the lexographic order of records).
|
||||
* @param int maxItems The maximum number of results to return. The service uses min($maxItems, 100).
|
||||
* @return The list of matching resource record sets
|
||||
*/
|
||||
public function listResourceRecordSets($zoneId, $type = '', $name = '', $maxItems = 100) {
|
||||
// we'll strip off the leading forward slash, so we can use it as the action directly.
|
||||
$zoneId = trim($zoneId, '/');
|
||||
|
||||
$rest = new Route53Request($this, $zoneId.'/rrset', 'GET');
|
||||
|
||||
if(strlen($type) > 0) {
|
||||
$rest->setParameter('type', $type);
|
||||
}
|
||||
if(strlen($name) > 0) {
|
||||
$rest->setParameter('name', $name);
|
||||
}
|
||||
if($maxItems != 100) {
|
||||
$rest->setParameter('maxitems', $maxItems);
|
||||
}
|
||||
|
||||
$rest = $rest->getResponse();
|
||||
if($rest->error === false && $rest->code !== 200) {
|
||||
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
||||
}
|
||||
if($rest->error !== false) {
|
||||
$this->__triggerError('listResourceRecordSets', $rest->error);
|
||||
return false;
|
||||
}
|
||||
|
||||
$response = array();
|
||||
if (!isset($rest->body))
|
||||
{
|
||||
return $response;
|
||||
}
|
||||
|
||||
$recordSets = array();
|
||||
foreach($rest->body->ResourceRecordSets->ResourceRecordSet as $set) {
|
||||
$recordSets[] = $this->parseResourceRecordSet($set);
|
||||
}
|
||||
|
||||
$response['ResourceRecordSets'] = $recordSets;
|
||||
|
||||
if(isset($rest->body->MaxItems)) {
|
||||
$response['MaxItems'] = (string)$rest->body->MaxItems;
|
||||
}
|
||||
|
||||
if(isset($rest->body->IsTruncated)) {
|
||||
$response['IsTruncated'] = (string)$rest->body->IsTruncated;
|
||||
if($response['IsTruncated'] == 'true') {
|
||||
$response['NextRecordName'] = (string)$rest->body->NextRecordName;
|
||||
$response['NextRecordType'] = (string)$rest->body->NextRecordType;
|
||||
}
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the specified resource record set changes (create or delete).
|
||||
*
|
||||
* @param string zoneId The id of the hosted zone, as returned by CreateHostedZoneResponse or ListHostedZoneResponse
|
||||
* In other words, if ListHostedZoneResponse shows the zone's Id as '/hostedzone/Z1PA6795UKMFR9',
|
||||
* then that full value should be passed here, including the '/hostedzone/' prefix.
|
||||
* @param array changes An array of change objects, as they are returned by the prepareChange utility method.
|
||||
* You may also pass a single change object.
|
||||
* @param string comment An optional comment to attach to the change request
|
||||
* @return The status of the change request
|
||||
*/
|
||||
public function changeResourceRecordSets($zoneId, $changes, $comment = '') {
|
||||
// we'll strip off the leading forward slash, so we can use it as the action directly.
|
||||
$zoneId = trim($zoneId, '/');
|
||||
|
||||
$data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
|
||||
$data .= '<ChangeResourceRecordSetsRequest xmlns="https://route53.amazonaws.com/doc/'.Route53::API_VERSION."/\">\n";
|
||||
$data .= "<ChangeBatch>\n";
|
||||
|
||||
if(strlen($comment) > 0) {
|
||||
$data .= '<Comment>'.$comment."</Comment>\n";
|
||||
}
|
||||
|
||||
if(!is_array($changes)) {
|
||||
$changes = array($changes);
|
||||
}
|
||||
|
||||
$data .= "<Changes>\n";
|
||||
foreach($changes as $change) {
|
||||
$data .= $change;
|
||||
}
|
||||
$data .= "</Changes>\n";
|
||||
|
||||
$data .= "</ChangeBatch>\n";
|
||||
$data .= "</ChangeResourceRecordSetsRequest>\n";
|
||||
|
||||
$rest = new Route53Request($this, $zoneId.'/rrset', 'POST', $data);
|
||||
|
||||
$rest = $rest->getResponse();
|
||||
if($rest->error === false && !in_array($rest->code, array(200, 201, 202, 204))) {
|
||||
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
||||
}
|
||||
if($rest->error !== false) {
|
||||
$this->__triggerError('changeResourceRecordSets', $rest->error);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isset($rest->body))
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
return $this->parseChangeInfo($rest->body->ChangeInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves information on a specified change request
|
||||
*
|
||||
* @param string changeId The id of the change, as returned by CreateHostedZoneResponse or ChangeResourceRecordSets
|
||||
* In other words, if CreateHostedZoneResponse showed the change's Id as '/change/C2682N5HXP0BZ4',
|
||||
* then that full value should be passed here, including the '/change/' prefix.
|
||||
* @return The status of the change request
|
||||
*/
|
||||
public function getChange($changeId) {
|
||||
// we'll strip off the leading forward slash, so we can use it as the action directly.
|
||||
$zoneId = trim($changeId, '/');
|
||||
|
||||
$rest = new Route53Request($this, $changeId, 'GET');
|
||||
|
||||
$rest = $rest->getResponse();
|
||||
if($rest->error === false && $rest->code !== 200) {
|
||||
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
||||
}
|
||||
if($rest->error !== false) {
|
||||
$this->__triggerError('getChange', $rest->error);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isset($rest->body))
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
return $this->parseChangeInfo($rest->body->ChangeInfo);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Utility function to parse a HostedZone tag structure
|
||||
*/
|
||||
private function parseHostedZone($tag) {
|
||||
$zone = array();
|
||||
$zone['Id'] = (string)$tag->Id;
|
||||
$zone['Name'] = (string)$tag->Name;
|
||||
$zone['CallerReference'] = (string)$tag->CallerReference;
|
||||
|
||||
// these might always be set, but check just in case, since
|
||||
// their values are option on CreateHostedZone requests
|
||||
if(isset($tag->Config) && isset($tag->Config->Comment)) {
|
||||
$zone['Config'] = array('Comment' => (string)$tag->Config->Comment);
|
||||
}
|
||||
|
||||
return $zone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function to parse a ChangeInfo tag structure
|
||||
*/
|
||||
private function parseChangeInfo($tag) {
|
||||
$info = array();
|
||||
$info['Id'] = (string)$tag->Id;
|
||||
$info['Status'] = (string)$tag->Status;
|
||||
$info['SubmittedAt'] = (string)$tag->SubmittedAt;
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function to parse a DelegationSet tag structure
|
||||
*/
|
||||
private function parseDelegationSet($tag) {
|
||||
$servers = array();
|
||||
foreach($tag->NameServers->NameServer as $ns) {
|
||||
$servers[] = (string)$ns;
|
||||
}
|
||||
return $servers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function to parse a ResourceRecordSet tag structure
|
||||
*/
|
||||
private function parseResourceRecordSet($tag) {
|
||||
$rrs = array();
|
||||
$rrs['Name'] = (string)$tag->Name;
|
||||
$rrs['Type'] = (string)$tag->Type;
|
||||
$rrs['TTL'] = (string)$tag->TTL;
|
||||
$rrs['ResourceRecords'] = array();
|
||||
foreach($tag->ResourceRecords->ResourceRecord as $rr) {
|
||||
$rrs['ResourceRecords'][] = (string)$rr->Value;
|
||||
}
|
||||
return $rrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function to prepare a Change object for ChangeResourceRecordSets requests.
|
||||
* All fields are required.
|
||||
*
|
||||
* @param string action The action to perform. One of: CREATE, DELETE
|
||||
* @param string name The name to perform the action on.
|
||||
* If it does not end with '.', then AWS treats the name as relative to the zone root.
|
||||
* @param string type The type of record being modified.
|
||||
* Must be one of: A, AAAA, CNAME, MX, NS, PTR, SOA, SPF, SRV, TXT
|
||||
* @param int ttl The time-to-live value for this record, in seconds.
|
||||
* @param array records An array of resource records to attach to this change.
|
||||
* Each member of this array can either be a string, or an array of strings.
|
||||
* Passing an array of strings will attach multiple values to a single resource record.
|
||||
* If a single string is passed as $records instead of an array,
|
||||
* it will be treated as a single-member array.
|
||||
* @return object An opaque object containing the change request.
|
||||
* Do not write code that depends on the contents of this object, as it may change at any time.
|
||||
*/
|
||||
public function prepareChange($action, $name, $type, $ttl, $records) {
|
||||
$change = "<Change>\n";
|
||||
$change .= '<Action>'.$action."</Action>\n";
|
||||
$change .= "<ResourceRecordSet>\n";
|
||||
$change .= '<Name>'.$name."</Name>\n";
|
||||
$change .= '<Type>'.$type."</Type>\n";
|
||||
$change .= '<TTL>'.$ttl."</TTL>\n";
|
||||
$change .= "<ResourceRecords>\n";
|
||||
|
||||
if(!is_array($records)) {
|
||||
$records = array($records);
|
||||
}
|
||||
|
||||
foreach($records as $record) {
|
||||
$change .= "<ResourceRecord>\n";
|
||||
if(is_array($record)) {
|
||||
foreach($record as $value) {
|
||||
$change .= '<Value>'.$value."</Value>\n";
|
||||
}
|
||||
}
|
||||
else {
|
||||
$change .= '<Value>'.$record."</Value>\n";
|
||||
}
|
||||
$change .= "</ResourceRecord>\n";
|
||||
}
|
||||
|
||||
$change .= "</ResourceRecords>\n";
|
||||
$change .= "</ResourceRecordSet>\n";
|
||||
$change .= "</Change>\n";
|
||||
|
||||
return $change;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger an error message
|
||||
*
|
||||
* @internal Used by member functions to output errors
|
||||
* @param array $error Array containing error information
|
||||
* @return string
|
||||
*/
|
||||
public function __triggerError($functionname, $error)
|
||||
{
|
||||
if($error == false) {
|
||||
log_error(sprintf("Route53::%s(): Encountered an error, but no description given", $functionname));
|
||||
}
|
||||
else if(isset($error['curl']) && $error['curl'])
|
||||
{
|
||||
log_error(sprintf("Route53::%s(): %s %s", $functionname, $error['code'], $error['message']));
|
||||
}
|
||||
else if(isset($error['Error']))
|
||||
{
|
||||
$e = $error['Error'];
|
||||
$message = sprintf("Route53::%s(): %s - %s: %s\nRequest Id: %s\n", $functionname, $e['Type'], $e['Code'], $e['Message'], $error['RequestId']);
|
||||
log_error($message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback handler for 503 retries.
|
||||
*
|
||||
* @internal Used by SimpleDBRequest to call the user-specified callback, if set
|
||||
* @param $attempt The number of failed attempts so far
|
||||
* @return The retry delay in microseconds, or 0 to stop retrying.
|
||||
*/
|
||||
public function __executeServiceTemporarilyUnavailableRetryDelay($attempt)
|
||||
{
|
||||
if(is_callable($this->__serviceUnavailableRetryDelayCallback)) {
|
||||
$callback = $this->__serviceUnavailableRetryDelayCallback;
|
||||
return $callback($attempt);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
final class Route53Request
|
||||
{
|
||||
private $r53, $action, $verb, $data, $parameters = array();
|
||||
public $response;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $r53 The Route53 object making this request
|
||||
* @param string $action SimpleDB action
|
||||
* @param string $verb HTTP verb
|
||||
* @param string $data For POST requests, the data being posted (optional)
|
||||
* @return mixed
|
||||
*/
|
||||
function __construct($r53, $action, $verb, $data = '') {
|
||||
$this->r53 = $r53;
|
||||
$this->action = $action;
|
||||
$this->verb = $verb;
|
||||
$this->data = $data;
|
||||
$this->response = new STDClass;
|
||||
$this->response->error = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set request parameter
|
||||
*
|
||||
* @param string $key Key
|
||||
* @param string $value Value
|
||||
* @param boolean $replace Whether to replace the key if it already exists (default true)
|
||||
* @return void
|
||||
*/
|
||||
public function setParameter($key, $value, $replace = true) {
|
||||
if(!$replace && isset($this->parameters[$key]))
|
||||
{
|
||||
$temp = (array)($this->parameters[$key]);
|
||||
$temp[] = $value;
|
||||
$this->parameters[$key] = $temp;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->parameters[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the response
|
||||
*
|
||||
* @return object | false
|
||||
*/
|
||||
public function getResponse() {
|
||||
|
||||
$params = array();
|
||||
foreach ($this->parameters as $var => $value)
|
||||
{
|
||||
if(is_array($value))
|
||||
{
|
||||
foreach($value as $v)
|
||||
{
|
||||
$params[] = $var.'='.$this->__customUrlEncode($v);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$params[] = $var.'='.$this->__customUrlEncode($value);
|
||||
}
|
||||
}
|
||||
|
||||
sort($params, SORT_STRING);
|
||||
|
||||
$query = implode('&', $params);
|
||||
|
||||
// must be in format 'Sun, 06 Nov 1994 08:49:37 GMT'
|
||||
$date = gmdate('D, d M Y H:i:s e');
|
||||
|
||||
$headers = array();
|
||||
$headers[] = 'Date: '.$date;
|
||||
$headers[] = 'Host: '.$this->r53->getHost();
|
||||
|
||||
$auth = 'AWS3-HTTPS AWSAccessKeyId='.$this->r53->getAccessKey();
|
||||
$auth .= ',Algorithm=HmacSHA256,Signature='.$this->__getSignature($date);
|
||||
$headers[] = 'X-Amzn-Authorization: '.$auth;
|
||||
|
||||
$url = 'https://'.$this->r53->getHost().'/'.Route53::API_VERSION.'/'.$this->action.'?'.$query;
|
||||
|
||||
// Basic setup
|
||||
$curl = curl_init();
|
||||
curl_setopt($curl, CURLOPT_USERAGENT, 'Route53/php');
|
||||
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, ($this->r53->verifyHost() ? 1 : 0));
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, ($this->r53->verifyPeer() ? 1 : 0));
|
||||
|
||||
curl_setopt($curl, CURLOPT_URL, $url);
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, false);
|
||||
curl_setopt($curl, CURLOPT_WRITEFUNCTION, array(&$this, '__responseWriteCallback'));
|
||||
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
|
||||
|
||||
// Request types
|
||||
switch ($this->verb) {
|
||||
case 'GET': break;
|
||||
case 'POST':
|
||||
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $this->verb);
|
||||
if(strlen($this->data) > 0) {
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $this->data);
|
||||
$headers[] = 'Content-Type: text/plain';
|
||||
$headers[] = 'Content-Length: '.strlen($this->data);
|
||||
}
|
||||
break;
|
||||
case 'DELETE':
|
||||
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($curl, CURLOPT_HEADER, false);
|
||||
|
||||
// Execute, grab errors
|
||||
if (curl_exec($curl)) {
|
||||
$this->response->code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
||||
} else {
|
||||
$this->response->error = array(
|
||||
'curl' => true,
|
||||
'code' => curl_errno($curl),
|
||||
'message' => curl_error($curl),
|
||||
'resource' => $this->resource
|
||||
);
|
||||
}
|
||||
|
||||
@curl_close($curl);
|
||||
|
||||
// Parse body into XML
|
||||
if ($this->response->error === false && isset($this->response->body)) {
|
||||
$this->response->body = simplexml_load_string($this->response->body);
|
||||
|
||||
// Grab Route53 errors
|
||||
if (!in_array($this->response->code, array(200, 201, 202, 204))
|
||||
&& isset($this->response->body->Error)) {
|
||||
$error = $this->response->body->Error;
|
||||
$output = array();
|
||||
$output['curl'] = false;
|
||||
$output['Error'] = array();
|
||||
$output['Error']['Type'] = (string)$error->Type;
|
||||
$output['Error']['Code'] = (string)$error->Code;
|
||||
$output['Error']['Message'] = (string)$error->Message;
|
||||
$output['RequestId'] = (string)$this->response->body->RequestId;
|
||||
|
||||
$this->response->error = $output;
|
||||
unset($this->response->body);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
/**
|
||||
* CURL write callback
|
||||
*
|
||||
* @param resource &$curl CURL resource
|
||||
* @param string &$data Data
|
||||
* @return integer
|
||||
*/
|
||||
private function __responseWriteCallback(&$curl, &$data) {
|
||||
$this->response->body .= $data;
|
||||
return strlen($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Contributed by afx114
|
||||
* URL encode the parameters as per http://docs.amazonwebservices.com/AWSECommerceService/latest/DG/index.html?Query_QueryAuth.html
|
||||
* PHP's rawurlencode() follows RFC 1738, not RFC 3986 as required by Amazon. The only difference is the tilde (~), so convert it back after rawurlencode
|
||||
* See: http://www.morganney.com/blog/API/AWS-Product-Advertising-API-Requires-a-Signed-Request.php
|
||||
*
|
||||
* @param string $var String to encode
|
||||
* @return string
|
||||
*/
|
||||
private function __customUrlEncode($var) {
|
||||
return str_replace('%7E', '~', rawurlencode($var));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the auth string using Hmac-SHA256
|
||||
*
|
||||
* @internal Used by SimpleDBRequest::getResponse()
|
||||
* @param string $string String to sign
|
||||
* @return string
|
||||
*/
|
||||
private function __getSignature($string) {
|
||||
return base64_encode(hash_hmac('sha256', $string, $this->r53->getSecretKey(), true));
|
||||
}
|
||||
}
|
||||
51
dns/dyndns/src/etc/rc.dyndns
Executable file
51
dns/dyndns/src/etc/rc.dyndns
Executable file
|
|
@ -0,0 +1,51 @@
|
|||
#!/usr/local/bin/php
|
||||
<?php
|
||||
|
||||
/*
|
||||
Copyright (C) 2004 Scott Ullrich
|
||||
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.
|
||||
*/
|
||||
|
||||
require_once("config.inc");
|
||||
require_once("interfaces.inc");
|
||||
require_once("util.inc");
|
||||
require_once("filter.inc");
|
||||
require_once("services.inc");
|
||||
require_once("plugins.inc.d/dyndns.inc");
|
||||
|
||||
if (isset($argv[1])) {
|
||||
$argument = trim($argv[1], " \n");
|
||||
} else {
|
||||
$argument = null;
|
||||
}
|
||||
|
||||
if (empty($argument)) {
|
||||
dyndns_configure_do(true);
|
||||
} else {
|
||||
$interface = lookup_gateway_interface_by_name($argument);
|
||||
if (empty($interface)) {
|
||||
$interface = $argument;
|
||||
}
|
||||
dyndns_configure_do(true, $interface);
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<acl>
|
||||
<page-services-dynamicdnsclients>
|
||||
<name>Services: Dynamic DNS clients</name>
|
||||
<patterns>
|
||||
<pattern>services_dyndns.php*</pattern>
|
||||
<pattern>services_dyndns_edit.php*</pattern>
|
||||
</patterns>
|
||||
</page-services-dynamicdnsclients>
|
||||
</acl>
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<menu>
|
||||
<Services>
|
||||
<DynamicDNS VisibleName="Dynamic DNS" url="/services_dyndns.php" cssClass="fa fa-tags fa-fw">
|
||||
<Edit url="/services_dyndns_edit.php*" visibility="hidden"/>
|
||||
</DynamicDNS>
|
||||
</Services>
|
||||
</menu>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
[reload]
|
||||
command:/usr/local/etc/rc.dyndns
|
||||
description:Dynamic DNS Update
|
||||
parameters:%s
|
||||
type:script
|
||||
message:updating dyndns %s
|
||||
202
dns/dyndns/src/www/services_dyndns.php
Normal file
202
dns/dyndns/src/www/services_dyndns.php
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
Copyright (C) 2014-2016 Deciso B.V.
|
||||
Copyright (C) 2008 Ermal Luçi
|
||||
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.
|
||||
*/
|
||||
|
||||
require_once("guiconfig.inc");
|
||||
require_once("interfaces.inc");
|
||||
require_once("services.inc");
|
||||
require_once("system.inc");
|
||||
require_once("plugins.inc.d/dyndns.inc");
|
||||
|
||||
if (empty($config['dyndnses']['dyndns']) || !isset($config['dyndnses']['dyndns'])) {
|
||||
$config['dyndnses']['dyndns'] = array();
|
||||
}
|
||||
$a_dyndns = &$config['dyndnses']['dyndns'];
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if (isset($_POST['act']) && $_POST['act'] == "del" && isset($_POST['id'])) {
|
||||
if (!empty($a_dyndns[$_POST['id']])) {
|
||||
$conf = $a_dyndns[$_POST['id']];
|
||||
@unlink(dyndns_cache_file($conf, 4));
|
||||
@unlink(dyndns_cache_file($conf, 6));
|
||||
unset($a_dyndns[$_POST['id']]);
|
||||
write_config();
|
||||
system_cron_configure();
|
||||
}
|
||||
exit;
|
||||
} elseif (isset($_POST['act']) && $_POST['act'] == "toggle" && isset($_POST['id'])) {
|
||||
if (!empty($a_dyndns[$_POST['id']])) {
|
||||
if (!empty($a_dyndns[$_POST['id']]['enable'])) {
|
||||
$a_dyndns[$_POST['id']]['enable'] = false;
|
||||
} else {
|
||||
$a_dyndns[$_POST['id']]['enable'] = true;
|
||||
}
|
||||
write_config();
|
||||
system_cron_configure();
|
||||
if ($a_dyndns[$_POST['id']]['enable']) {
|
||||
$a_dyndns[$_POST['id']]['force'] = true;
|
||||
dyndns_configure_client($a_dyndns[$_POST['id']]);
|
||||
}
|
||||
}
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
include("head.inc");
|
||||
|
||||
legacy_html_escape_form_data($a_dyndns);
|
||||
|
||||
$main_buttons = array(
|
||||
array('label' => gettext('Add'), 'href' => 'services_dyndns_edit.php'),
|
||||
);
|
||||
|
||||
?>
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
$( document ).ready(function() {
|
||||
// delete service action
|
||||
$(".act_delete_service").click(function(event){
|
||||
event.preventDefault();
|
||||
var id = $(this).data("id");
|
||||
BootstrapDialog.show({
|
||||
type:BootstrapDialog.TYPE_DANGER,
|
||||
title: "<?= gettext("Dynamic DNS");?>",
|
||||
message: "<?=gettext("Do you really want to delete this entry?");?>",
|
||||
buttons: [{
|
||||
label: "<?= gettext("No");?>",
|
||||
action: function(dialogRef) {
|
||||
dialogRef.close();
|
||||
}}, {
|
||||
label: "<?= gettext("Yes");?>",
|
||||
action: function(dialogRef) {
|
||||
$.post(window.location, {act: 'del', id:id}, function(data) {
|
||||
location.reload();
|
||||
});
|
||||
}
|
||||
}]
|
||||
});
|
||||
});
|
||||
// link toggle buttons
|
||||
$(".act_toggle").click(function(event){
|
||||
event.preventDefault();
|
||||
$.post(window.location, {act: 'toggle', id:$(this).data("id")}, function(data) {
|
||||
location.reload();
|
||||
});
|
||||
});
|
||||
// watch scroll position and set to last known on page load
|
||||
watchScrollPosition();
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php include("fbegin.inc"); ?>
|
||||
<section class="page-content-main">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<section class="col-xs-12">
|
||||
<div class="tab-content content-box col-xs-12">
|
||||
<form method="post" name="iform" id="iform">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?=gettext("Interface");?></th>
|
||||
<th><?=gettext("Service");?></th>
|
||||
<th><?=gettext("Hostname");?></th>
|
||||
<th><?=gettext("Cached IP");?></th>
|
||||
<th><?=gettext("Description");?></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
$i = 0;
|
||||
foreach ($a_dyndns as $dyndns): ?>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="#" class="act_toggle" data-id="<?=$i;?>" data-toggle="tooltip" title="<?=(!empty($dyndns['enable'])) ? gettext("disable") : gettext("enable");?>">
|
||||
<span class="glyphicon glyphicon-play <?=(!empty($dyndns['enable'])) ? "text-success" : "text-muted";?>"></span>
|
||||
</a>
|
||||
<?=!empty($config['interfaces'][$dyndns['interface']]['descr']) ? $config['interfaces'][$dyndns['interface']]['descr'] : strtoupper($dyndns['interface']);?>
|
||||
</td>
|
||||
<td><?=dyndns_list()[$dyndns['type']];?></td>
|
||||
<td><?=$dyndns['host'];?></td>
|
||||
<td>
|
||||
<?php
|
||||
$filename = dyndns_cache_file($dyndns, 4);
|
||||
$fdata = '';
|
||||
if (file_exists($filename) && !empty($dyndns['enable'])) {
|
||||
$ipaddr = get_dyndns_ip($dyndns['interface'], 4);
|
||||
$fdata = @file_get_contents($filename);
|
||||
}
|
||||
|
||||
$filename_v6 = dyndns_cache_file($dyndns, 6);
|
||||
$fdata6 = '';
|
||||
if (file_exists($filename_v6) && !empty($dyndns['enable'])) {
|
||||
$ipv6addr = get_dyndns_ip($dyndns['interface'], 6);
|
||||
$fdata6 = @file_get_contents($filename_v6);
|
||||
}
|
||||
|
||||
if (!empty($fdata)) {
|
||||
$cached_ip_s = explode('|', $fdata);
|
||||
$cached_ip = $cached_ip_s[0];
|
||||
echo sprintf(
|
||||
'<font color="%s">%s</font>',
|
||||
$ipaddr != $cached_ip ? 'red' : 'green',
|
||||
htmlspecialchars($cached_ip)
|
||||
);
|
||||
} elseif (!empty($fdata6)) {
|
||||
$cached_ipv6_s = explode('|', $fdata6);
|
||||
$cached_ipv6 = $cached_ipv6_s[0];
|
||||
echo sprintf(
|
||||
'<font color="%s">%s</font>',
|
||||
$ipv6addr != $cached_ipv6 ? 'red' : 'green',
|
||||
htmlspecialchars($cached_ipv6)
|
||||
);
|
||||
} else {
|
||||
echo sprintf('<span class="text-muted">%s</span>', gettext('N/A'));
|
||||
}?>
|
||||
</td>
|
||||
<td><?=$dyndns['descr'];?></td>
|
||||
<td>
|
||||
<a href="services_dyndns_edit.php?id=<?=$i;?>" class="btn btn-default btn-xs"><span class="glyphicon glyphicon-pencil"></span></a>
|
||||
<a href="#" data-id="<?=$i;?>" class="act_delete_service"><button type="button" class="btn btn-xs btn-default"><span class="fa fa-trash text-muted"></span></button></a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
$i++;
|
||||
endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<?php include("foot.inc"); ?>
|
||||
427
dns/dyndns/src/www/services_dyndns_edit.php
Normal file
427
dns/dyndns/src/www/services_dyndns_edit.php
Normal file
|
|
@ -0,0 +1,427 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
Copyright (C) 2014-2015 Deciso B.V.
|
||||
Copyright (C) 2008 Ermal Luçi
|
||||
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.
|
||||
*/
|
||||
|
||||
require_once("guiconfig.inc");
|
||||
require_once("services.inc") ;
|
||||
require_once("interfaces.inc");
|
||||
require_once("system.inc");
|
||||
require_once("plugins.inc.d/dyndns.inc");
|
||||
|
||||
/* returns true if $uname is a valid dynamic DNS username */
|
||||
function is_dyndns_username($uname)
|
||||
{
|
||||
if (!is_string($uname)) {
|
||||
return false;
|
||||
} elseif (preg_match("/[^a-z0-9\-.@_:]/i", $uname)) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($config['dyndnses']['dyndns'])) {
|
||||
$config['dyndnses']['dyndns'] = array();
|
||||
}
|
||||
$a_dyndns = &$config['dyndnses']['dyndns'];
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
if (isset($_GET['id']) && !empty($a_dyndns[$_GET['id']])) {
|
||||
$id = $_GET['id'];
|
||||
}
|
||||
$config_copy_fieldnames = array('username', 'password', 'host', 'mx', 'type', 'zoneid', 'ttl', 'updateurl',
|
||||
'resultmatch', 'requestif', 'descr', 'interface');
|
||||
foreach ($config_copy_fieldnames as $fieldname) {
|
||||
if (isset($id) && isset($a_dyndns[$id][$fieldname])) {
|
||||
$pconfig[$fieldname] = $a_dyndns[$id][$fieldname];
|
||||
} else {
|
||||
$pconfig[$fieldname] = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($id)) {
|
||||
$pconfig['enable'] = isset($a_dyndns[$id]['enable']);
|
||||
} else {
|
||||
$pconfig['enable'] = true;
|
||||
}
|
||||
$pconfig['wildcard'] = isset($id) && isset($a_dyndns[$id]['wildcard']);
|
||||
$pconfig['verboselog'] = isset($id) && isset($a_dyndns[$id]['verboselog']);
|
||||
$pconfig['curl_ipresolve_v4'] = isset($id) && isset($a_dyndns[$id]['curl_ipresolve_v4']);
|
||||
$pconfig['curl_ssl_verifypeer'] = isset($id) && isset($a_dyndns[$id]['curl_ssl_verifypeer']);
|
||||
} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if (isset($_POST['id']) && !empty($a_dyndns[$_POST['id']])) {
|
||||
$id = $_POST['id'];
|
||||
}
|
||||
$input_errors = array();
|
||||
$pconfig = $_POST;
|
||||
if(($pconfig['type'] == "freedns" || $pconfig['type'] == "namecheap") && $pconfig['username'] == "") {
|
||||
$pconfig['username'] = "none";
|
||||
}
|
||||
|
||||
/* input validation */
|
||||
$reqdfields = array();
|
||||
$reqdfieldsn = array();
|
||||
$reqdfields = array('type');
|
||||
$reqdfieldsn = array(gettext('Service type'));
|
||||
if ($pconfig['type'] != 'custom' && $pconfig['type'] != 'custom-v6') {
|
||||
$reqdfields[] = 'host';
|
||||
$reqdfieldsn[] = gettext('Hostname');
|
||||
$reqdfields[] = 'username';
|
||||
$reqdfieldsn[] = gettext('Username');
|
||||
if ($pconfig['type'] != 'duckdns') {
|
||||
$reqdfields[] = 'password';
|
||||
$reqdfieldsn[] = gettext('Password');
|
||||
}
|
||||
} else {
|
||||
$reqdfields[] = 'updateurl';
|
||||
$reqdfieldsn[] = gettext('Update URL');
|
||||
}
|
||||
|
||||
do_input_validation($pconfig, $reqdfields, $reqdfieldsn, $input_errors);
|
||||
|
||||
if (isset($pconfig['host']) && in_array('host', $reqdfields)) {
|
||||
/* Namecheap can have a @. in hostname */
|
||||
if ($pconfig['type'] == "namecheap" && substr($pconfig['host'], 0, 2) == '@.') {
|
||||
$host_to_check = substr($pconfig['host'], 2);
|
||||
} else {
|
||||
$host_to_check = $pconfig['host'];
|
||||
}
|
||||
|
||||
if (!is_domain($host_to_check)) {
|
||||
$input_errors[] = gettext("The Hostname contains invalid characters.");
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($pconfig['mx']) && !is_domain($pconfig['mx'])) {
|
||||
$input_errors[] = gettext("The MX contains invalid characters.");
|
||||
}
|
||||
if ((in_array("username", $reqdfields) && !empty($pconfig['username']) && !is_dyndns_username($pconfig['username'])) || ((in_array("username", $reqdfields)) && ($pconfig['username'] == ""))) {
|
||||
$input_errors[] = gettext("The username contains invalid characters.");
|
||||
}
|
||||
|
||||
|
||||
if (count($input_errors) == 0) {
|
||||
$dyndns = array();
|
||||
$dyndns['type'] = $pconfig['type'];
|
||||
$dyndns['username'] = $pconfig['username'];
|
||||
$dyndns['password'] = $pconfig['password'];
|
||||
$dyndns['host'] = $pconfig['host'];
|
||||
$dyndns['mx'] = $pconfig['mx'];
|
||||
$dyndns['wildcard'] = !empty($pconfig['wildcard']);
|
||||
$dyndns['verboselog'] = !empty($pconfig['verboselog']);
|
||||
$dyndns['curl_ipresolve_v4'] = !empty($pconfig['curl_ipresolve_v4']);
|
||||
$dyndns['curl_ssl_verifypeer'] = !empty($pconfig['curl_ssl_verifypeer']);
|
||||
$dyndns['enable'] = !empty($pconfig['enable']);
|
||||
$dyndns['interface'] = $pconfig['interface'];
|
||||
$dyndns['zoneid'] = $pconfig['zoneid'];
|
||||
$dyndns['ttl'] = $pconfig['ttl'];
|
||||
$dyndns['updateurl'] = $pconfig['updateurl'];
|
||||
// Trim hard-to-type but sometimes returned characters
|
||||
$dyndns['resultmatch'] = trim($pconfig['resultmatch'], "\t\n\r");
|
||||
($dyndns['type'] == "custom" || $dyndns['type'] == "custom-v6") ? $dyndns['requestif'] = $pconfig['requestif'] : $dyndns['requestif'] = $pconfig['interface'];
|
||||
$dyndns['descr'] = $pconfig['descr'];
|
||||
$dyndns['force'] = isset($pconfig['force']);
|
||||
if ($dyndns['username'] == "none") {
|
||||
$dyndns['username'] = "";
|
||||
}
|
||||
|
||||
if (isset($id)) {
|
||||
$a_dyndns[$id] = $dyndns;
|
||||
} else {
|
||||
$a_dyndns[] = $dyndns;
|
||||
$id = count($a_dyndns) - 1;
|
||||
}
|
||||
|
||||
$dyndns['id'] = $id;
|
||||
for($i = 0; $i < count($a_dyndns); $i++) {
|
||||
$a_dyndns[$i]['id'] = $i;
|
||||
}
|
||||
|
||||
write_config();
|
||||
system_cron_configure();
|
||||
|
||||
if ($dyndns['force']) {
|
||||
dyndns_configure_client($dyndns);
|
||||
}
|
||||
|
||||
header(url_safe('Location: /services_dyndns.php'));
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
legacy_html_escape_form_data($pconfig);
|
||||
|
||||
include("head.inc");
|
||||
|
||||
?>
|
||||
<body>
|
||||
<?php include("fbegin.inc"); ?>
|
||||
<script type="text/javascript">
|
||||
$( document ).ready(function() {
|
||||
$("#type").change(function(){
|
||||
$(".opt_field").hide();
|
||||
switch ($(this).val()) {
|
||||
case "custom":
|
||||
case "custom-v6":
|
||||
$(".type_custom").show();
|
||||
break;
|
||||
case "route53":
|
||||
$(".type_route53").show();
|
||||
break;
|
||||
default:
|
||||
$(".type_default").show();
|
||||
break;
|
||||
}
|
||||
$(window).resize(); // force zebra re-stripe (opnsense_standard_table_form)
|
||||
});
|
||||
$("#type").change();
|
||||
});
|
||||
</script>
|
||||
|
||||
<section class="page-content-main">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<?php if (isset($input_errors) && count($input_errors) > 0) print_input_errors($input_errors); ?>
|
||||
<section class="col-xs-12">
|
||||
<div class="content-box">
|
||||
<form method="post" name="iform" id="iform">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped opnsense_standard_table_form">
|
||||
<tr>
|
||||
<td width="22%"><strong><?= gettext("Dynamic DNS client") ?></strong></td>
|
||||
<td width="78%" align="right">
|
||||
<small><?= gettext("full help") ?> </small>
|
||||
<i class="fa fa-toggle-off text-danger" style="cursor: pointer;" id="show_all_help_page" type="button"></i>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i class="fa fa-info-circle text-muted"></i> <?= gettext("Enable") ?></td>
|
||||
<td>
|
||||
<input name="enable" type="checkbox" id="enable" value="<?= gettext("yes") ?>" <?= empty($pconfig['enable']) ? '' : 'checked="checked"' ?> />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i class="fa fa-info-circle text-muted"></i> <?= gettext("Service type") ?></td>
|
||||
<td>
|
||||
<select name="type" class="selectpicker" id="type">
|
||||
<?php
|
||||
foreach (dyndns_list() as $value => $type):?>
|
||||
<option value="<?= $value ?>" <?= $value == $pconfig['type'] ? 'selected="selected"' : '' ?>>
|
||||
<?= $type ?>
|
||||
</option>
|
||||
<?php
|
||||
endforeach;?>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i class="fa fa-info-circle text-muted"></i> <?= gettext("Interface to monitor") ?></td>
|
||||
<td>
|
||||
<select name="interface" class="selectpicker" id="interface">
|
||||
<?php
|
||||
$iflist = get_configured_interface_with_descr();
|
||||
$iflist = array_merge($iflist, return_gateway_groups_array());
|
||||
foreach ($iflist as $if => $ifdesc):?>
|
||||
<option value="<?= $if ?>" <?=$pconfig['interface'] == $if ? 'selected="selected"' : '';?>>
|
||||
<?= is_array($ifdesc) ? $if : htmlspecialchars($ifdesc) ?>
|
||||
</option>
|
||||
|
||||
<?php
|
||||
endforeach;?>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="opt_field type_custom">
|
||||
<td><a id="help_for_requestif" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?= gettext("Interface to send update from") ?></td>
|
||||
<td>
|
||||
<select name="requestif" class="selectpicker" id="requestif">
|
||||
<?php
|
||||
$iflist = get_configured_interface_with_descr();
|
||||
$iflist = array_merge($iflist, return_gateway_groups_array());
|
||||
foreach ($iflist as $if => $ifdesc):?>
|
||||
<option value="<?= $if ?>" <?= $pconfig['requestif'] == $if ? 'selected="selected"' : '' ?>>
|
||||
<?= is_array($ifdesc) ? $if : htmlspecialchars($ifdesc) ?>
|
||||
</option>
|
||||
|
||||
<?php
|
||||
endforeach;?>
|
||||
</select>
|
||||
<div class="hidden" for="help_for_requestif">
|
||||
<?= gettext("Note: This is almost always the same as the Interface to Monitor.");?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a id="help_for_host" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?= gettext("Hostname") ?></td>
|
||||
<td>
|
||||
<input name="host" type="text" id="host" value="<?= $pconfig['host'] ?>" />
|
||||
<div class="hidden" for="help_for_host">
|
||||
<?= gettext("Enter the complete host/domain name. example: myhost.dyndns.org") ?><br />
|
||||
<?= gettext("For he.net tunnelbroker, enter your tunnel ID") ?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="opt_field type_default type_route53">
|
||||
<td><a id="help_for_mx" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?= gettext("MX") ?></td>
|
||||
<td>
|
||||
<input name="mx" type="text" id="mx" value="<?= $pconfig['mx'] ?>" />
|
||||
<div class="hidden" for="help_for_mx">
|
||||
<?= gettext("Note: With a dynamic DNS service you can only use a hostname, not an IP address.") ?>
|
||||
<br />
|
||||
<?= gettext("Set this option only if you need a special MX record. Not all services support this.") ?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="opt_field type_default type_route53">
|
||||
<td><i class="fa fa-info-circle text-muted"></i> <?= gettext("Wildcards") ?></td>
|
||||
<td>
|
||||
<input name="wildcard" type="checkbox" id="wildcard" value="yes" <?= empty($pconfig['wildcard']) ? '' : 'checked="checked"' ?> />
|
||||
<strong><?= gettext("Enable Wildcard") ?></strong>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i class="fa fa-info-circle text-muted"></i> <?= gettext("Verbose logging") ?></td>
|
||||
<td>
|
||||
<input name="verboselog" type="checkbox" id="verboselog" value="yes" <?= empty($pconfig['verboselog']) ? '' : 'checked="checked"' ?> />
|
||||
<strong><?= gettext("Enable verbose logging") ?></strong>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="opt_field type_custom">
|
||||
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("CURL options"); ?></td>
|
||||
<td>
|
||||
<input name="curl_ipresolve_v4" type="checkbox" id="curl_ipresolve_v4" value="yes" <?= empty($pconfig['curl_ipresolve_v4']) ? '' : 'checked="checked"' ?> />
|
||||
<?= gettext("Force IPv4 resolving") ?><br />
|
||||
<input name="curl_ssl_verifypeer" type="checkbox" id="curl_ssl_verifypeer" value="yes" <?= empty($pconfig['curl_ssl_verifypeer']) ? '' : 'checked="checked"' ?> />
|
||||
<?= gettext("Verify SSL peer") ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a id="help_for_username" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?= gettext("Username") ?></td>
|
||||
<td>
|
||||
<input name="username" type="text" id="username" value="<?= $pconfig['username'] ?>" />
|
||||
<div class="hidden" for="help_for_username">
|
||||
<?= gettext("Username is required for all types except Namecheap, FreeDNS and Custom Entries.");?>
|
||||
<br /><?= gettext('Route 53: Enter your Access Key ID.') ?>
|
||||
<br /><?= gettext('Duck DNS: Enter your Token.') ?>
|
||||
<br /><?= gettext('For Custom Entries, Username and Password represent HTTP Authentication username and passwords.') ?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a id="help_for_password" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?= gettext("Password") ?></td>
|
||||
<td>
|
||||
<input name="password" type="password" id="password" value="<?= $pconfig['password'] ?>" />
|
||||
<div class="hidden" for="help_for_password">
|
||||
<?=gettext('FreeDNS (freedns.afraid.org): Enter your "Authentication Token" provided by FreeDNS.') ?>
|
||||
<br /><?= gettext('Route 53: Enter your Secret Access Key.') ?>
|
||||
<br /><?= gettext('Duck DNS: Leave blank.') ?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="opt_field type_route53">
|
||||
<td><a id="help_for_zoneid" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?= gettext("Zone ID") ?></td>
|
||||
<td>
|
||||
<input name="zoneid" type="text" id="zoneid" value="<?= $pconfig['zoneid'] ?>" />
|
||||
<div class="hidden" for="help_for_zoneid">
|
||||
<?= gettext("Enter Zone ID that you received when you created your domain in Route 53.") ?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="opt_field type_custom">
|
||||
<td><a id="help_for_updateurl" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Update URL") ?></td>
|
||||
<td>
|
||||
<input name="updateurl" type="text" id="updateurl" value="<?= $pconfig['updateurl'] ?>" />
|
||||
<div class="hidden" for="help_for_updateurl">
|
||||
<?= gettext("This is the only field required by for Custom Dynamic DNS, and is only used by Custom Entries.") ?>
|
||||
<br />
|
||||
<?= gettext("If you need the new IP to be included in the request, put %IP% in its place.") ?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="opt_field type_custom">
|
||||
<td><a id="help_for_resultmatch" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?= gettext("Result Match") ?></td>
|
||||
<td>
|
||||
<textarea name="resultmatch" class="formpre" id="resultmatch" cols="65" rows="7"><?= $pconfig['resultmatch'] ?></textarea>
|
||||
<div class="hidden" for="help_for_resultmatch">
|
||||
<?= gettext("This field is only used by Custom Dynamic DNS Entries.") ?>
|
||||
<br />
|
||||
<?= gettext("This field should be identical to what your dynamic DNS Provider will return if the update succeeds, leave it blank to disable checking of returned results.");?>
|
||||
<br />
|
||||
<?= gettext("If you need the new IP to be included in the request, put %IP% in its place.") ?>
|
||||
<br />
|
||||
<?= gettext('If you need to include multiple possible values, separate them with a |. If your provider includes a |, escape it with \|') ?>
|
||||
<br />
|
||||
<?= gettext('Tabs (\t), newlines (\n) and carriage returns (\r) at the beginning or end of the returned results are removed before comparison.') ?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="opt_field type_route53">
|
||||
<td><a id="help_for_ttl" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("TTL");?></td>
|
||||
<td>
|
||||
<input name="ttl" type="text" id="ttl" value="<?= $pconfig['ttl'] ?>" />
|
||||
<div class="hidden" for="help_for_ttl">
|
||||
<?= gettext("Choose TTL for your dns record.") ?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i class="fa fa-info-circle text-muted"></i> <?= gettext("Description") ?></td>
|
||||
<td>
|
||||
<input name="descr" type="text" id="descr" value="<?= $pconfig['descr'] ?>" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>
|
||||
<button name="submit" type="submit" class="btn btn-primary" value="save"><?= gettext('Save') ?></button>
|
||||
<?php
|
||||
if (isset($id)): ?>
|
||||
<button name="force" type="submit" class="btn btn-primary" value="force"><?= gettext('Save and Force Update') ?></button>
|
||||
<input name="id" type="hidden" value="<?= $id ?>" />
|
||||
<?php
|
||||
endif; ?>
|
||||
<a href="services_dyndns.php" class="btn btn-default"><?= gettext('Cancel') ?></a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<?= sprintf(gettext('You must configure a DNS server in %sSystem: ' .
|
||||
'General setup%s or allow the DNS server list to be overridden ' .
|
||||
'by DHCP/PPP on WAN for dynamic DNS updates to work.'),
|
||||
'<a href="system_general.php">', '</a>'); ?>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<?php include("foot.inc"); ?>
|
||||
4
dns/dyndns/src/www/widgets/include/dyn_dns_status.inc
Normal file
4
dns/dyndns/src/www/widgets/include/dyn_dns_status.inc
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
<?php
|
||||
|
||||
$dyn_dns_status_title = gettext('Dynamic DNS');
|
||||
$dyn_dns_status_title_link = 'services_dyndns.php';
|
||||
168
dns/dyndns/src/www/widgets/widgets/dyn_dns_status.widget.php
Normal file
168
dns/dyndns/src/www/widgets/widgets/dyn_dns_status.widget.php
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
Copyright (C) 2014-2016 Deciso B.V.
|
||||
Copyright (C) 2008 Ermal Luci
|
||||
Copyright (C) 2013 Stanley P. Miller \ stan-qaz
|
||||
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.
|
||||
*/
|
||||
|
||||
require_once("guiconfig.inc");
|
||||
require_once("widgets/include/dyn_dns_status.inc");
|
||||
require_once("services.inc");
|
||||
require_once("interfaces.inc");
|
||||
require_once("plugins.inc.d/dyndns.inc");
|
||||
|
||||
if (!isset($config['dyndnses']['dyndns'])) {
|
||||
$config['dyndnses']['dyndns'] = array();
|
||||
}
|
||||
|
||||
$a_dyndns = &$config['dyndnses']['dyndns'];
|
||||
|
||||
if (!empty($_REQUEST['getdyndnsstatus'])) {
|
||||
$first_entry = true;
|
||||
foreach ($a_dyndns as $dyndns) {
|
||||
if ($first_entry) {
|
||||
$first_entry = false;
|
||||
} else {
|
||||
// Put a vertical bar delimiter between the echoed HTML for each entry processed.
|
||||
echo '|';
|
||||
}
|
||||
|
||||
$filename = dyndns_cache_file($dyndns, 4);
|
||||
$fdata = '';
|
||||
if (!empty($dyndns['enable']) && file_exists($filename)) {
|
||||
$ipaddr = get_dyndns_ip($dyndns['interface'], 4);
|
||||
$fdata = @file_get_contents($filename);
|
||||
}
|
||||
|
||||
$filename_v6 = dyndns_cache_file($dyndns, 6);
|
||||
$fdata6 = '';
|
||||
if (!empty($dyndns['enable']) && file_exists($filename_v6)) {
|
||||
$ipv6addr = get_dyndns_ip($dyndns['interface'], 6);
|
||||
$fdata6 = @file_get_contents($filename_v6);
|
||||
}
|
||||
|
||||
if (!empty($fdata)) {
|
||||
$cached_ip_s = explode('|', $fdata);
|
||||
$cached_ip = $cached_ip_s[0];
|
||||
echo sprintf(
|
||||
'<font color="%s">%s</font>',
|
||||
$ipaddr != $cached_ip ? 'red' : 'green',
|
||||
htmlspecialchars($cached_ip)
|
||||
);
|
||||
} elseif (!empty($fdata6)) {
|
||||
$cached_ipv6_s = explode('|', $fdata6);
|
||||
$cached_ipv6 = $cached_ipv6_s[0];
|
||||
echo sprintf(
|
||||
'<font color="%s">%s</font>',
|
||||
$ipv6addr != $cached_ipv6 ? 'red' : 'green',
|
||||
htmlspecialchars($cached_ipv6)
|
||||
);
|
||||
} else {
|
||||
echo gettext('N/A');
|
||||
}
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<table class="table table-striped table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?=gettext("Interface");?></th>
|
||||
<th><?=gettext("Service");?></th>
|
||||
<th><?=gettext("Hostname");?></th>
|
||||
<th><?=gettext("Cached IP");?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
$iflist = get_configured_interface_with_descr();
|
||||
$types = dyndns_list();
|
||||
$groupslist = return_gateway_groups_array();
|
||||
foreach ($a_dyndns as $i => $dyndns) :?>
|
||||
<tr ondblclick="document.location='services_dyndns_edit.php?id=<?=$i;?>'">
|
||||
<td <?= isset($dyndns['enable']) ? '' : 'class="text-muted"' ?>>
|
||||
<?php
|
||||
foreach ($iflist as $if => $ifdesc) {
|
||||
if ($dyndns['interface'] == $if) {
|
||||
echo "{$ifdesc}";
|
||||
break;
|
||||
}
|
||||
}
|
||||
foreach ($groupslist as $if => $group) {
|
||||
if ($dyndns['interface'] == $if) {
|
||||
echo "{$if}";
|
||||
break;
|
||||
}
|
||||
}?>
|
||||
</td>
|
||||
<td <?= isset($dyndns['enable']) ? '' : 'class="text-muted"' ?>>
|
||||
<?php
|
||||
if (isset($types[$dyndns['type']])) {
|
||||
echo htmlspecialchars($types[$dyndns['type']]);
|
||||
} else {
|
||||
echo htmlspecialchars($dyndns['type']);
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
<td <?= isset($dyndns['enable']) ? '' : 'class="text-muted"' ?>>
|
||||
<?= htmlspecialchars($dyndns['host']) ?>
|
||||
</td>
|
||||
<td <?= isset($dyndns['enable']) ? '' : 'class="text-muted"' ?>>
|
||||
<div id='dyndnsstatus<?=$i;?>'>
|
||||
<?= gettext('Checking...') ?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
endforeach;?>
|
||||
</tbody>
|
||||
</table>
|
||||
<script type="text/javascript">
|
||||
function dyndns_getstatus()
|
||||
{
|
||||
scroll(0,0);
|
||||
var url = "/widgets/widgets/dyn_dns_status.widget.php";
|
||||
var pars = 'getdyndnsstatus=yes';
|
||||
jQuery.ajax(url, {type: 'get', data: pars, complete: dyndnscallback});
|
||||
// Refresh the status every 5 minutes
|
||||
setTimeout('dyndns_getstatus()', 5*60*1000);
|
||||
}
|
||||
function dyndnscallback(transport)
|
||||
{
|
||||
// The server returns a string of statuses separated by vertical bars
|
||||
var responseStrings = transport.responseText.split("|");
|
||||
for (var count=0; count<responseStrings.length; count++) {
|
||||
var divlabel = '#dyndnsstatus' + count;
|
||||
jQuery(divlabel).prop('innerHTML',responseStrings[count]);
|
||||
}
|
||||
}
|
||||
$( document ).ready(function() {
|
||||
// Do the first status check 2 seconds after the dashboard opens
|
||||
setTimeout('dyndns_getstatus()', 2000);
|
||||
});
|
||||
</script>
|
||||
8
dns/rfc2136/Makefile
Normal file
8
dns/rfc2136/Makefile
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
PLUGIN_NAME= rfc2136
|
||||
PLUGIN_VERSION= 1.0
|
||||
PLUGIN_COMMENT= RFC-2136 Support
|
||||
PLUGIN_MAINTAINER= franco@opnsense.org
|
||||
PLUGIN_DEPENDS= bind911
|
||||
PLUGIN_DEVEL= yes
|
||||
|
||||
.include "../../Mk/plugins.mk"
|
||||
1
dns/rfc2136/pkg-descr
Normal file
1
dns/rfc2136/pkg-descr
Normal file
|
|
@ -0,0 +1 @@
|
|||
Support for RFC-2136 based dynamic DNS updates using Bind
|
||||
248
dns/rfc2136/src/etc/inc/plugins.inc.d/rfc2136.inc
Normal file
248
dns/rfc2136/src/etc/inc/plugins.inc.d/rfc2136.inc
Normal file
|
|
@ -0,0 +1,248 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
Copyright (C) 2014-2017 Franco Fichtner <franco@opnsense.org>
|
||||
Copyright (C) 2010 Ermal Luci
|
||||
Copyright (C) 2005-2006 Colin Smith <ethethlay@gmail.com>
|
||||
Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>
|
||||
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.
|
||||
*/
|
||||
|
||||
function rfc2136_configure()
|
||||
{
|
||||
return array(
|
||||
'bootup' => array('rfc2136_configure_do'),
|
||||
'local' => array('rfc2136_configure_do'),
|
||||
'newwanip' => array('rfc2136_configure_do:2'),
|
||||
);
|
||||
}
|
||||
|
||||
function rfc2136_enabled()
|
||||
{
|
||||
global $config;
|
||||
|
||||
if (isset($config['dnsupdates']['dnsupdate'])) {
|
||||
foreach ($config['dnsupdates']['dnsupdate'] as $dnsupdate) {
|
||||
if (isset($dnsupdate['enable'])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function rfc2136_services()
|
||||
{
|
||||
global $config;
|
||||
|
||||
$services = array();
|
||||
|
||||
if (rfc2136_enabled()) {
|
||||
$services[] = array(
|
||||
'description' => gettext('RFC 2136'),
|
||||
'configd' => array(
|
||||
'restart' => array('rfc2136 reload'),
|
||||
),
|
||||
'nocheck' => true,
|
||||
'name' => 'rfc2136',
|
||||
);
|
||||
}
|
||||
|
||||
return $services;
|
||||
}
|
||||
|
||||
function rfc2136_cron()
|
||||
{
|
||||
$jobs = array();
|
||||
|
||||
if (rfc2136_enabled()) {
|
||||
$jobs[]['autocron'] = array('/usr/local/etc/rc.rfc2136', '16', '1');
|
||||
}
|
||||
|
||||
return $jobs;
|
||||
}
|
||||
|
||||
function rfc2136_cache_file($dnsupdate, $ipver = 4)
|
||||
{
|
||||
$ipver = $ipver == 6 ? '_v6' : '';
|
||||
|
||||
return "/var/cache/rfc2136_{$dnsupdate['interface']}_{$dnsupdate['host']}_{$dnsupdate['server']}{$ipver}.cache";
|
||||
}
|
||||
|
||||
function rfc2136_configure_do($verbose = false, $int = '', $updatehost = '', $forced = false)
|
||||
{
|
||||
global $config;
|
||||
|
||||
if (!rfc2136_enabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$notify_text = '';
|
||||
|
||||
if ($verbose) {
|
||||
echo 'Configuring RFC 2136 clients...';
|
||||
flush();
|
||||
}
|
||||
|
||||
foreach ($config['dnsupdates']['dnsupdate'] as $i => $dnsupdate) {
|
||||
if (!isset($dnsupdate['enable'])) {
|
||||
continue;
|
||||
} elseif (!empty($int) && $int != $dnsupdate['interface']) {
|
||||
continue;
|
||||
} elseif (!empty($updatehost) && ($updatehost != $dnsupdate['host'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$currentTime = time();
|
||||
|
||||
$keyname = $dnsupdate['keyname'];
|
||||
/* trailing dot */
|
||||
if (substr($keyname, -1) != ".") {
|
||||
$keyname .= ".";
|
||||
}
|
||||
|
||||
$hostname = $dnsupdate['host'];
|
||||
/* trailing dot */
|
||||
if (substr($hostname, -1) != ".") {
|
||||
$hostname .= ".";
|
||||
}
|
||||
|
||||
/* write private key file
|
||||
this is dumb - public and private keys are the same for HMAC-MD5,
|
||||
but nsupdate insists on having both */
|
||||
$fd = fopen("/var/etc/K{$i}{$keyname}+157+00000.private", "w");
|
||||
$privkey = <<<EOD
|
||||
Private-key-format: v1.2
|
||||
Algorithm: 157 (HMAC)
|
||||
Key: {$dnsupdate['keydata']}
|
||||
|
||||
EOD;
|
||||
fwrite($fd, $privkey);
|
||||
fclose($fd);
|
||||
|
||||
/* write public key file */
|
||||
if ($dnsupdate['keytype'] == "zone") {
|
||||
$flags = 257;
|
||||
$proto = 3;
|
||||
} elseif ($dnsupdate['keytype'] == "host") {
|
||||
$flags = 513;
|
||||
$proto = 3;
|
||||
} elseif ($dnsupdate['keytype'] == "user") {
|
||||
$flags = 0;
|
||||
$proto = 2;
|
||||
}
|
||||
|
||||
$fd = fopen("/var/etc/K{$i}{$keyname}+157+00000.key", "w");
|
||||
fwrite($fd, "{$keyname} IN KEY {$flags} {$proto} 157 {$dnsupdate['keydata']}\n");
|
||||
fclose($fd);
|
||||
|
||||
/* generate update instructions */
|
||||
$upinst = "";
|
||||
if (!empty($dnsupdate['server'])) {
|
||||
$upinst .= "server {$dnsupdate['server']}\n";
|
||||
}
|
||||
|
||||
$maxCacheAgeSecs = 25 * 24 * 60 * 60;
|
||||
$need_update = false;
|
||||
|
||||
if (empty($dnsupdate['recordtype']) || $dnsupdate['recordtype'] == 'A') {
|
||||
$cacheFile = rfc2136_cache_file($dnsupdate, 4);
|
||||
if (file_exists($cacheFile)) {
|
||||
list($cachedipv4, $cacheTimev4) = explode('|', file_get_contents($cacheFile));
|
||||
} else {
|
||||
list($cachedipv4, $cacheTimev4) = array('', '');
|
||||
}
|
||||
if (isset($dnsupdate['usepublicip'])) {
|
||||
$wanip = get_dyndns_ip($dnsupdate['interface'], 4);
|
||||
} else {
|
||||
$wanip = get_interface_ip($dnsupdate['interface']);
|
||||
}
|
||||
if (is_ipaddrv4($wanip)) {
|
||||
if (($wanip != $cachedipv4) || (($currentTime - $cacheTimev4) > $maxCacheAgeSecs) || $forced) {
|
||||
$upinst .= "update delete {$dnsupdate['host']}. A\n";
|
||||
$upinst .= "update add {$dnsupdate['host']}. {$dnsupdate['ttl']} A {$wanip}\n";
|
||||
$notify_text .= sprintf(gettext('Dynamic DNS updated IP Address (A) for %s on %s to %s'), $dnsupdate['host'], strtoupper($dnsupdate['interface']), $wanip) . "\n";
|
||||
@file_put_contents($cacheFile, "{$wanip}|{$currentTime}");
|
||||
log_error("Dynamic DNS: updating cache file {$cacheFile}: {$wanip}");
|
||||
$need_update = true;
|
||||
} else {
|
||||
log_error("Dynamic DNS: Not updating {$dnsupdate['host']} A record because the IP address has not changed.");
|
||||
}
|
||||
} else {
|
||||
@unlink($cacheFile);
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($dnsupdate['recordtype']) || $dnsupdate['recordtype'] == 'AAAA') {
|
||||
$cacheFile6 = rfc2136_cache_file($dnsupdate, 6);
|
||||
if (file_exists($cacheFile6)) {
|
||||
list($cachedipv6, $cacheTimev6) = explode('|', file_get_contents($cacheFile6));
|
||||
} else {
|
||||
list($cachedipv6, $cacheTimev6) = array('', '');
|
||||
}
|
||||
if (isset($dnsupdate['usepublicip'])) {
|
||||
$wanipv6 = get_dyndns_ip($dnsupdate['interface'], 6);
|
||||
} else {
|
||||
$wanipv6 = get_interface_ipv6($dnsupdate['interface']);
|
||||
}
|
||||
if (is_ipaddrv6($wanipv6)) {
|
||||
if (($wanipv6 != $cachedipv6) || (($currentTime - $cacheTimev6) > $maxCacheAgeSecs) || $forced) {
|
||||
$upinst .= "update delete {$dnsupdate['host']}. AAAA\n";
|
||||
$upinst .= "update add {$dnsupdate['host']}. {$dnsupdate['ttl']} AAAA {$wanipv6}\n";
|
||||
$notify_text .= sprintf(gettext('Dynamic DNS updated IPv6 Address (AAAA) for %s on %s to %s'), $dnsupdate['host'], strtoupper($dnsupdate['interface']), $wanipv6) . "\n";
|
||||
@file_put_contents($cacheFile6, "{$wanipv6}|{$currentTime}");
|
||||
log_error("Dynamic DNS: updating cache file {$cacheFile6}: {$wanipv6}");
|
||||
$need_update = true;
|
||||
} else {
|
||||
log_error("Dynamic DNS: Not updating {$dnsupdate['host']} AAAA record because the IPv6 address has not changed.");
|
||||
}
|
||||
} else {
|
||||
@unlink($cacheFile6);
|
||||
}
|
||||
}
|
||||
|
||||
$upinst .= "\n"; /* mind that trailing newline! */
|
||||
|
||||
if ($need_update) {
|
||||
@file_put_contents("/var/etc/nsupdatecmds{$i}", $upinst);
|
||||
unset($upinst);
|
||||
/* invoke nsupdate */
|
||||
$cmd = "/usr/local/bin/nsupdate -k /var/etc/K{$i}{$keyname}+157+00000.key";
|
||||
if (isset($dnsupdate['usetcp']))
|
||||
$cmd .= " -v";
|
||||
$cmd .= " /var/etc/nsupdatecmds{$i}";
|
||||
mwexec_bg($cmd);
|
||||
unset($cmd);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($notify_text)) {
|
||||
notify_all_remote($notify_text);
|
||||
}
|
||||
|
||||
if ($verbose) {
|
||||
echo "done.\n";
|
||||
}
|
||||
}
|
||||
51
dns/rfc2136/src/etc/rc.rfc2136
Executable file
51
dns/rfc2136/src/etc/rc.rfc2136
Executable file
|
|
@ -0,0 +1,51 @@
|
|||
#!/usr/local/bin/php
|
||||
<?php
|
||||
|
||||
/*
|
||||
Copyright (C) 2004 Scott Ullrich
|
||||
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.
|
||||
*/
|
||||
|
||||
require_once("config.inc");
|
||||
require_once("interfaces.inc");
|
||||
require_once("util.inc");
|
||||
require_once("filter.inc");
|
||||
require_once("services.inc");
|
||||
require_once("plugins.inc.d/rfc2136.inc");
|
||||
|
||||
if (isset($argv[1])) {
|
||||
$argument = trim($argv[1], " \n");
|
||||
} else {
|
||||
$argument = null;
|
||||
}
|
||||
|
||||
if (empty($argument)) {
|
||||
rfc2136_configure_do(true);
|
||||
} else {
|
||||
$interface = lookup_gateway_interface_by_name($argument);
|
||||
if (empty($interface)) {
|
||||
$interface = $argument;
|
||||
}
|
||||
rfc2136_configure_do(true, $interface);
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<acl>
|
||||
<page-services-rfc2136clients>
|
||||
<name>Services: RFC 2136 clients</name>
|
||||
<patterns>
|
||||
<pattern>services_rfc2136.php*</pattern>
|
||||
<pattern>services_rfc2136_edit.php*</pattern>
|
||||
</patterns>
|
||||
</page-services-rfc2136clients>
|
||||
</acl>
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<menu>
|
||||
<Services>
|
||||
<RFC2136 VisibleName="RFC 2136" url="/services_rfc2136.php" cssClass="fa fa-tags fa-fw">
|
||||
<Edit url="/services_rfc2136_edit.php*" visibility="hidden"/>
|
||||
</RFC2136>
|
||||
</Services>
|
||||
</menu>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
[reload]
|
||||
command:/usr/local/etc/rc.rfc2136
|
||||
description:RFC 2136 Update
|
||||
parameters:%s
|
||||
type:script
|
||||
message:updating rfc2136 %s
|
||||
212
dns/rfc2136/src/www/services_rfc2136.php
Normal file
212
dns/rfc2136/src/www/services_rfc2136.php
Normal file
|
|
@ -0,0 +1,212 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
Copyright (C) 2014-2015 Deciso B.V.
|
||||
Copyright (C) 2008 Ermal Luçi
|
||||
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.
|
||||
*/
|
||||
|
||||
require_once("guiconfig.inc");
|
||||
require_once("interfaces.inc");
|
||||
require_once("services.inc");
|
||||
require_once("system.inc");
|
||||
require_once("plugins.inc.d/rfc2136.inc");
|
||||
|
||||
if (!isset($config['dnsupdates']['dnsupdate'])) {
|
||||
$config['dnsupdates']['dnsupdate'] = array();
|
||||
}
|
||||
|
||||
$a_rfc2136 = &$config['dnsupdates']['dnsupdate'];
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if (isset($_POST['act']) && $_POST['act'] == "del" && isset($_POST['id'])) {
|
||||
if (!empty($a_rfc2136[$_POST['id']])) {
|
||||
@unlink(rfc2136_cache_file($a_rfc2136[$_POST['id']], 4));
|
||||
@unlink(rfc2136_cache_file($a_rfc2136[$_POST['id']], 6));
|
||||
unset($a_rfc2136[$_POST['id']]);
|
||||
write_config();
|
||||
system_cron_configure();
|
||||
}
|
||||
exit;
|
||||
} elseif (isset($_POST['act']) && $_POST['act'] == "toggle" && isset($_POST['id'])) {
|
||||
if (!empty($a_rfc2136[$_POST['id']])) {
|
||||
if (!empty($a_rfc2136[$_POST['id']]['enable'])) {
|
||||
$a_rfc2136[$_POST['id']]['enable'] = false;
|
||||
} else {
|
||||
$a_rfc2136[$_POST['id']]['enable'] = true;
|
||||
}
|
||||
write_config();
|
||||
system_cron_configure();
|
||||
if (!empty($a_rfc2136[$_POST['id']]['enable'])) {
|
||||
rfc2136_configure_do(false, '', $a_rfc2136[$_POST['id']]['host'], true);
|
||||
}
|
||||
}
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
include("head.inc");
|
||||
|
||||
legacy_html_escape_form_data($a_rfc2136);
|
||||
|
||||
$main_buttons = array(
|
||||
array('label' => gettext('Add'), 'href' => 'services_rfc2136_edit.php'),
|
||||
);
|
||||
|
||||
?>
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
$( document ).ready(function() {
|
||||
// delete service action
|
||||
$(".act_delete_service").click(function(event){
|
||||
event.preventDefault();
|
||||
var id = $(this).data("id");
|
||||
BootstrapDialog.show({
|
||||
type:BootstrapDialog.TYPE_DANGER,
|
||||
title: "<?= gettext("RFC 2136");?>",
|
||||
message: "<?=gettext("Do you really want to delete this client?");?>",
|
||||
buttons: [{
|
||||
label: "<?= gettext("No");?>",
|
||||
action: function(dialogRef) {
|
||||
dialogRef.close();
|
||||
}}, {
|
||||
label: "<?= gettext("Yes");?>",
|
||||
action: function(dialogRef) {
|
||||
$.post(window.location, {act: 'del', id:id}, function(data) {
|
||||
location.reload();
|
||||
});
|
||||
}
|
||||
}]
|
||||
});
|
||||
});
|
||||
// link toggle buttons
|
||||
$(".act_toggle").click(function(event){
|
||||
event.preventDefault();
|
||||
$.post(window.location, {act: 'toggle', id:$(this).data("id")}, function(data) {
|
||||
location.reload();
|
||||
});
|
||||
});
|
||||
// watch scroll position and set to last known on page load
|
||||
watchScrollPosition();
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php include("fbegin.inc"); ?>
|
||||
<section class="page-content-main">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<?php if (isset($input_errors) && count($input_errors) > 0) print_input_errors($input_errors); ?>
|
||||
<section class="col-xs-12">
|
||||
<div class="tab-content content-box col-xs-12">
|
||||
<form method="post" name="iform" id="iform">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?=gettext("If");?></th>
|
||||
<th><?=gettext("Server");?></th>
|
||||
<th><?=gettext("Hostname");?></th>
|
||||
<th><?=gettext("Cached IP");?></th>
|
||||
<th><?=gettext("Description");?></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
$i = 0;
|
||||
foreach ($a_rfc2136 as $rfc2136): ?>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="#" class="act_toggle" data-id="<?=$i;?>" data-toggle="tooltip" title="<?=(!empty($rfc2136['enable'])) ? gettext("disable") : gettext("enable");?>">
|
||||
<span class="glyphicon glyphicon-play <?=(!empty($rfc2136['enable'])) ? "text-success" : "text-muted";?>"></span>
|
||||
</a>
|
||||
<?=!empty($config['interfaces'][$rfc2136['interface']]['descr']) ? $config['interfaces'][$rfc2136['interface']]['descr'] : strtoupper($rfc2136['interface']);?>
|
||||
</td>
|
||||
<td><?=$rfc2136['server'];?></td>
|
||||
<td><?=$rfc2136['host'];?></td>
|
||||
<td>
|
||||
<?php
|
||||
$filename = rfc2136_cache_file($rfc2136, 4);
|
||||
if (file_exists($filename) && !empty($rfc2136['enable']) && (empty($rfc2136['recordtype']) || $rfc2136['recordtype'] == 'A')) {
|
||||
echo "IPv4: ";
|
||||
if (isset($rfc2136['usepublicip'])) {
|
||||
$ipaddr = get_dyndns_ip($rfc2136['interface'], 4);
|
||||
} else {
|
||||
$ipaddr = get_interface_ip($rfc2136['interface']);
|
||||
}
|
||||
$cached_ip_s = explode("|", file_get_contents($filename));
|
||||
$cached_ip = $cached_ip_s[0];
|
||||
if ($ipaddr <> $cached_ip) {
|
||||
echo "<font color='red'>";
|
||||
} else {
|
||||
echo "<font color='green'>";
|
||||
}
|
||||
echo htmlspecialchars($cached_ip);
|
||||
echo "</font>";
|
||||
} else {
|
||||
echo 'IPv4: ' . gettext('N/A');
|
||||
}
|
||||
echo "<br />";
|
||||
$filename6 = rfc2136_cache_file($rfc2136, 6);
|
||||
if (file_exists($filename6) && !empty($rfc2136['enable']) && (empty($rfc2136['recordtype']) || $rfc2136['recordtype'] == 'AAAA')) {
|
||||
echo "IPv6: ";
|
||||
if (isset($rfc2136['usepublicip'])) {
|
||||
$ipaddr = get_dyndns_ip($rfc2136['interface'], 6);
|
||||
} else {
|
||||
$ipaddr = get_interface_ipv6($rfc2136['interface']);
|
||||
}
|
||||
$cached_ip_s = explode("|", file_get_contents($filename6));
|
||||
$cached_ip = $cached_ip_s[0];
|
||||
if ($ipaddr <> $cached_ip) {
|
||||
echo "<font color='red'>";
|
||||
} else {
|
||||
echo "<font color='green'>";
|
||||
}
|
||||
echo htmlspecialchars($cached_ip);
|
||||
echo "</font>";
|
||||
} else {
|
||||
echo 'IPv6: ' . gettext('N/A');
|
||||
}?>
|
||||
</td>
|
||||
<td><?=$rfc2136['descr'];?></td>
|
||||
<td>
|
||||
<a href="services_rfc2136_edit.php?id=<?=$i;?>">
|
||||
<button type="button" class="btn btn-xs btn-default"><span class="fa fa-pencil"></span></button>
|
||||
</a>
|
||||
<a href="#" data-id="<?=$i;?>" class="act_delete_service"><button type="button" class="btn btn-xs btn-default"><span class="fa fa-trash text-muted"></span></button></a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
$i++;
|
||||
endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<?php include("foot.inc"); ?>
|
||||
273
dns/rfc2136/src/www/services_rfc2136_edit.php
Normal file
273
dns/rfc2136/src/www/services_rfc2136_edit.php
Normal file
|
|
@ -0,0 +1,273 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
Copyright (C) 2014-2016 Deciso B.V.
|
||||
Copyright (C) 2008 Ermal Luçi
|
||||
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.
|
||||
*/
|
||||
|
||||
require_once("guiconfig.inc");
|
||||
require_once("services.inc");
|
||||
require_once("system.inc");
|
||||
require_once("interfaces.inc");
|
||||
require_once("plugins.inc.d/rfc2136.inc");
|
||||
|
||||
if (!isset($config['dnsupdates']['dnsupdate'])) {
|
||||
$config['dnsupdates']['dnsupdate'] = array();
|
||||
}
|
||||
$a_rfc2136 = &$config['dnsupdates']['dnsupdate'];
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
if (isset($_GET['id']) && !empty($a_rfc2136[$_GET['id']])) {
|
||||
$id = $_GET['id'];
|
||||
}
|
||||
|
||||
if (isset($id)) {
|
||||
$pconfig['enable'] = isset($a_rfc2136[$id]['enable']);
|
||||
} else {
|
||||
$pconfig['enable'] = true;
|
||||
}
|
||||
|
||||
$pconfig['host'] = isset($id) && !empty($a_rfc2136[$id]['host']) ? $a_rfc2136[$id]['host'] : null;
|
||||
$pconfig['ttl'] = isset($id) &&!empty($a_rfc2136[$id]['ttl']) ? $a_rfc2136[$id]['ttl'] : 60;
|
||||
$pconfig['keydata'] = isset($id) &&!empty($a_rfc2136[$id]['keydata']) ? $a_rfc2136[$id]['keydata'] : null;
|
||||
$pconfig['keyname'] = isset($id) &&!empty($a_rfc2136[$id]['keyname']) ? $a_rfc2136[$id]['keyname'] : null;
|
||||
$pconfig['keytype'] = isset($id) &&!empty($a_rfc2136[$id]['keytype']) ? $a_rfc2136[$id]['keytype'] : "zone";
|
||||
$pconfig['server'] = isset($id) &&!empty($a_rfc2136[$id]['server']) ? $a_rfc2136[$id]['server'] : null;
|
||||
$pconfig['interface'] = isset($id) &&!empty($a_rfc2136[$id]['interface']) ? $a_rfc2136[$id]['interface'] : null;
|
||||
$pconfig['descr'] = isset($id) &&!empty($a_rfc2136[$id]['descr']) ? $a_rfc2136[$id]['descr'] : null;
|
||||
$pconfig['recordtype'] = isset($id) && !empty($a_rfc2136[$id]['recordtype']) ? $a_rfc2136[$id]['recordtype'] : null;
|
||||
|
||||
$pconfig['usetcp'] = isset($a_rfc2136[$id]['usetcp']);
|
||||
$pconfig['usepublicip'] = isset($a_rfc2136[$id]['usepublicip']);
|
||||
|
||||
} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if (isset($_POST['id']) && !empty($a_rfc2136[$_POST['id']])) {
|
||||
$id = $_POST['id'];
|
||||
}
|
||||
$input_errors = array();
|
||||
$pconfig = $_POST;
|
||||
/* input validation */
|
||||
$reqdfields = array();
|
||||
$reqdfieldsn = array();
|
||||
$reqdfields = array_merge($reqdfields, explode(" ", "host ttl keyname keydata"));
|
||||
$reqdfieldsn = array_merge($reqdfieldsn, array(gettext("Hostname"), gettext("TTL"), gettext("Key name"), gettext("Key")));
|
||||
|
||||
do_input_validation($pconfig, $reqdfields, $reqdfieldsn, $input_errors);
|
||||
|
||||
if (!empty($pconfig['host']) && !is_domain($pconfig['host'])) {
|
||||
$input_errors[] = gettext("The DNS update host name contains invalid characters.");
|
||||
}
|
||||
if (!empty($pconfig['ttl']) && !is_numericint($pconfig['ttl'])) {
|
||||
$input_errors[] = gettext("The DNS update TTL must be an integer.");
|
||||
}
|
||||
if (!empty($pconfig['keyname']) && !is_domain($pconfig['keyname'])) {
|
||||
$input_errors[] = gettext("The DNS update key name contains invalid characters.");
|
||||
}
|
||||
|
||||
if (count($input_errors) == 0) {
|
||||
$rfc2136 = array();
|
||||
$rfc2136['enable'] = !empty($pconfig['enable']);
|
||||
$rfc2136['host'] = $pconfig['host'];
|
||||
$rfc2136['ttl'] = $pconfig['ttl'];
|
||||
$rfc2136['keyname'] = $pconfig['keyname'];
|
||||
$rfc2136['keytype'] = $pconfig['keytype'];
|
||||
$rfc2136['keydata'] = $pconfig['keydata'];
|
||||
$rfc2136['server'] = $pconfig['server'];
|
||||
$rfc2136['usetcp'] = !empty($pconfig['usetcp']);
|
||||
$rfc2136['usepublicip'] = !empty($pconfig['usepublicip']);
|
||||
$rfc2136['interface'] = $pconfig['interface'];
|
||||
$rfc2136['descr'] = $pconfig['descr'];
|
||||
|
||||
if (!empty($pconfig['recordtype'])) {
|
||||
$rfc2136['recordtype'] = $pconfig['recordtype'];
|
||||
}
|
||||
|
||||
if (isset($id)) {
|
||||
$a_rfc2136[$id] = $rfc2136;
|
||||
} else {
|
||||
$a_rfc2136[] = $rfc2136;
|
||||
}
|
||||
|
||||
write_config('New/Edited RFC2136 dnsupdate entry was posted');
|
||||
system_cron_configure();
|
||||
|
||||
if (!empty($pconfig['force'])) {
|
||||
rfc2136_configure_do(false, '', $rfc2136['host'], true);
|
||||
}
|
||||
|
||||
header(url_safe('Location: /services_rfc2136.php'));
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
legacy_html_escape_form_data($pconfig);
|
||||
include("head.inc");
|
||||
|
||||
?>
|
||||
<body>
|
||||
<?php include("fbegin.inc"); ?>
|
||||
<section class="page-content-main">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<?php if (isset($input_errors) && count($input_errors) > 0) print_input_errors($input_errors); ?>
|
||||
<?php if (isset($savemsg)) print_info_box($savemsg); ?>
|
||||
<section class="col-xs-12">
|
||||
<div class="content-box">
|
||||
<form method="post" name="iform" id="iform">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped opnsense_standard_table_form">
|
||||
<tr>
|
||||
<td width="22%"><strong><?=gettext("RFC 2136 client");?></strong></td>
|
||||
<td width="78%" align="right">
|
||||
<small><?=gettext("full help"); ?> </small>
|
||||
<i class="fa fa-toggle-off text-danger" style="cursor: pointer;" id="show_all_help_page" type="button"></i>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Enable");?></td>
|
||||
<td>
|
||||
<input name="enable" type="checkbox" id="enable" value="yes" <?=!empty($pconfig['enable']) ? "checked=\"checked\"" : ""; ?> />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Interface to monitor");?></td>
|
||||
<td>
|
||||
<select name="interface" class="selectpicker" id="requestif">
|
||||
<?php
|
||||
foreach (get_configured_interface_with_descr() as $if => $ifdesc):?>
|
||||
<option value="<?=$if;?>" <?=$pconfig['interface'] == $if ? "selected=\"selected\"" : "";?>>
|
||||
<?=htmlspecialchars($ifdesc);?>
|
||||
</option>
|
||||
|
||||
<?php
|
||||
endforeach;?>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a id="help_for_host" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Hostname");?></td>
|
||||
<td>
|
||||
<input name="host" type="text" id="host" value="<?=$pconfig['host'];?>" />
|
||||
<div class="hidden" for="help_for_host">
|
||||
<?= gettext('Fully qualified hostname of the host to be updated.') ?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a id="help_for_recordtype" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Record Type");?></td>
|
||||
<td>
|
||||
<input name="recordtype" type="radio" value="" <?= empty($pconfig['recordtype']) ? 'checked="checked"' : '' ?> /> <?=gettext('All');?>
|
||||
<input name="recordtype" type="radio" value="A" <?= $pconfig['recordtype'] == 'A' ? 'checked="checked"' : '' ?> /> <?=gettext('A (IPv4)');?>
|
||||
<input name="recordtype" type="radio" value="AAAA" <?= $pconfig['recordtype'] == 'AAAA' ? 'checked="checked"' : '' ?> /> <?=gettext('AAAA (IPv6)');?>
|
||||
<div class="hidden" for="help_for_recordtype">
|
||||
<?=gettext("'All' will update all available record types.");?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("TTL"); ?> (<?=gettext("seconds");?>)</td>
|
||||
<td>
|
||||
<input name="ttl" type="text" id="ttl" value="<?=$pconfig['ttl'];?>" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a id="help_for_keyname" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Key name");?></td>
|
||||
<td>
|
||||
<input name="keyname" type="text" id="keyname" value="<?=$pconfig['keyname'];?>" />
|
||||
<div class="hidden" for="help_for_keyname">
|
||||
<?=gettext("This must match the setting on the DNS server.");?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Key type");?> </td>
|
||||
<td>
|
||||
<input name="keytype" type="radio" value="zone" <?= $pconfig['keytype'] == "zone" ? "checked=\"checked\"" :""; ?> /> <?=gettext("Zone");?>
|
||||
<input name="keytype" type="radio" value="host" <?= $pconfig['keytype'] == "host" ? "checked=\"checked\"" :""; ?> /> <?=gettext("Host");?>
|
||||
<input name="keytype" type="radio" value="user" <?= $pconfig['keytype'] == "user" ? "checked=\"checked\"" :""; ?> /> <?=gettext("User");?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a id="help_for_keydata" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Key");?></td>
|
||||
<td>
|
||||
<input name="keydata" type="text" id="keydata" size="70" value="<?=htmlspecialchars($pconfig['keydata']);?>" />
|
||||
<div class="hidden" for="help_for_keydata">
|
||||
<?=gettext("Paste an HMAC-MD5 key here.");?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Server");?></td>
|
||||
<td>
|
||||
<input name="server" type="text" class="formfld" id="server" size="30" value="<?=$pconfig['server'];?>" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Protocol");?></td>
|
||||
<td>
|
||||
<input name="usetcp" type="checkbox" id="usetcp" value="<?=gettext("yes");?>" <?=!empty($pconfig['usetcp']) ? "checked=\"checked\"" : ""; ?> />
|
||||
<strong><?=gettext("Use TCP instead of UDP");?></strong>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Use Public IP");?></td>
|
||||
<td>
|
||||
<input name="usepublicip" type="checkbox" id="usepublicip" value="<?=gettext("yes");?>" <?=!empty($pconfig['usepublicip']) ? "checked=\"checked\"" : ""; ?> />
|
||||
<strong><?=gettext("If the interface IP is private, attempt to fetch and use the public IP instead.");?></strong>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?=gettext("Description");?></td>
|
||||
<td>
|
||||
<input name="descr" type="text" id="descr" value="<?=$pconfig['descr'];?>" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>
|
||||
<button name="save" type="submit" class="btn btn-primary" value="save"><?= gettext('Save') ?></button>
|
||||
<?php if (isset($id)): ?>
|
||||
<button name="force" type="submit" class="btn btn-primary" value="force"><?= gettext('Save and Force Update') ?></button>
|
||||
<input name="id" type="hidden" value="<?=$id;?>" />
|
||||
<?php endif; ?>
|
||||
<a href="services_rfc2136.php" class="btn btn-default"><?= gettext('Cancel') ?></a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<?= sprintf(gettext("You must configure a DNS server in %sSystem: " .
|
||||
"General setup%s or allow the DNS server list to be overridden " .
|
||||
"by DHCP/PPP on WAN for dynamic DNS updates to work."),'<a href="system_general.php">', '</a>');?>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<?php include("foot.inc"); ?>
|
||||
4
dns/rfc2136/src/www/widgets/include/rfc2136.inc
Normal file
4
dns/rfc2136/src/www/widgets/include/rfc2136.inc
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
<?php
|
||||
|
||||
$rfc2136_title = gettext('RFC 2136');
|
||||
$rfc2136_title_link = 'services_rfc2136.php';
|
||||
168
dns/rfc2136/src/www/widgets/widgets/rfc2136.widget.php
Normal file
168
dns/rfc2136/src/www/widgets/widgets/rfc2136.widget.php
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
Copyright (C) 2017 Franco Fichtner <franco@opnsense.org>
|
||||
Copyright (C) 2014-2016 Deciso B.V.
|
||||
Copyright (C) 2008 Ermal Luci
|
||||
Copyright (C) 2013 Stanley P. Miller \ stan-qaz
|
||||
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.
|
||||
*/
|
||||
|
||||
require_once("guiconfig.inc");
|
||||
require_once("widgets/include/rfc2136.inc");
|
||||
require_once("services.inc");
|
||||
require_once("interfaces.inc");
|
||||
require_once("plugins.inc.d/rfc2136.inc");
|
||||
|
||||
if (!isset($config['dnsupdates']['dnsupdate'])) {
|
||||
$config['dnsupdates']['dnsupdate'] = array();
|
||||
}
|
||||
|
||||
$a_rfc2136 = &$config['dnsupdates']['dnsupdate'];
|
||||
|
||||
if (!empty($_REQUEST['getrfc2136status'])) {
|
||||
$first_entry = true;
|
||||
foreach ($a_rfc2136 as $rfc2136) {
|
||||
if ($first_entry) {
|
||||
$first_entry = false;
|
||||
} else {
|
||||
// Put a vertical bar delimiter between the echoed HTML for each entry processed.
|
||||
echo '|';
|
||||
}
|
||||
|
||||
$filename = rfc2136_cache_file($rfc2136, 4);
|
||||
$fdata = '';
|
||||
if (!empty($rfc2136['enable']) && (empty($rfc2136['recordtype']) || $rfc2136['recordtype'] == 'A') && file_exists($filename)) {
|
||||
$ipaddr = get_dyndns_ip($rfc2136['interface'], 4);
|
||||
$fdata = @file_get_contents($filename);
|
||||
}
|
||||
|
||||
$filename_v6 = rfc2136_cache_file($rfc2136, 6);
|
||||
$fdata6 = '';
|
||||
if (!empty($rfc2136['enable']) && (empty($rfc2136['recordtype']) || $rfc2136['recordtype'] == 'AAAA') && file_exists($filename_v6)) {
|
||||
$ipv6addr = get_dyndns_ip($rfc2136['interface'], 6);
|
||||
$fdata6 = @file_get_contents($filename_v6);
|
||||
}
|
||||
|
||||
if (!empty($fdata)) {
|
||||
$cached_ip_s = explode('|', $fdata);
|
||||
$cached_ip = $cached_ip_s[0];
|
||||
echo sprintf(
|
||||
'IPv4: <font color="%s">%s</font>',
|
||||
$ipaddr != $cached_ip ? 'red' : 'green',
|
||||
htmlspecialchars($cached_ip)
|
||||
);
|
||||
} else {
|
||||
echo 'IPv4: ' . gettext('N/A');
|
||||
}
|
||||
|
||||
echo '<br />';
|
||||
|
||||
if (!empty($fdata6)) {
|
||||
$cached_ipv6_s = explode('|', $fdata6);
|
||||
$cached_ipv6 = $cached_ipv6_s[0];
|
||||
echo sprintf(
|
||||
'IPv6: <font color="%s">%s</font>',
|
||||
$ipv6addr != $cached_ipv6 ? 'red' : 'green',
|
||||
htmlspecialchars($cached_ipv6)
|
||||
);
|
||||
} else {
|
||||
echo 'IPv6: ' . gettext('N/A');
|
||||
}
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<table class="table table-striped table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?=gettext("Interface");?></th>
|
||||
<th><?=gettext("Server");?></th>
|
||||
<th><?=gettext("Hostname");?></th>
|
||||
<th><?=gettext("Cached IP");?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
$iflist = get_configured_interface_with_descr();
|
||||
$groupslist = return_gateway_groups_array();
|
||||
foreach ($a_rfc2136 as $i => $rfc2136) :?>
|
||||
<tr ondblclick="document.location='services_rfc2136_edit.php?id=<?=$i;?>'">
|
||||
<td <?= isset($rfc2136['enable']) ? '' : 'class="text-muted"' ?>>
|
||||
<?php
|
||||
foreach ($iflist as $if => $ifdesc) {
|
||||
if ($rfc2136['interface'] == $if) {
|
||||
echo "{$ifdesc}";
|
||||
break;
|
||||
}
|
||||
}
|
||||
foreach ($groupslist as $if => $group) {
|
||||
if ($rfc2136['interface'] == $if) {
|
||||
echo "{$if}";
|
||||
break;
|
||||
}
|
||||
}?>
|
||||
</td>
|
||||
<td <?= isset($rfc2136['enable']) ? '' : 'class="text-muted"' ?>>
|
||||
<?= htmlspecialchars($rfc2136['server']) ?>
|
||||
</td>
|
||||
<td <?= isset($rfc2136['enable']) ? '' : 'class="text-muted"' ?>>
|
||||
<?= htmlspecialchars($rfc2136['host']) ?>
|
||||
</td>
|
||||
<td <?= isset($rfc2136['enable']) ? '' : 'class="text-muted"' ?>>
|
||||
<div id='rfc2136status<?=$i;?>'>
|
||||
<?= gettext('Checking...') ?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
endforeach;?>
|
||||
</tbody>
|
||||
</table>
|
||||
<script type="text/javascript">
|
||||
function rfc2136_getstatus()
|
||||
{
|
||||
scroll(0,0);
|
||||
var url = "/widgets/widgets/rfc2136.widget.php";
|
||||
var pars = 'getrfc2136status=yes';
|
||||
jQuery.ajax(url, {type: 'get', data: pars, complete: rfc2136callback});
|
||||
// Refresh the status every 5 minutes
|
||||
setTimeout('rfc2136_getstatus()', 5*60*1000);
|
||||
}
|
||||
function rfc2136callback(transport)
|
||||
{
|
||||
// The server returns a string of statuses separated by vertical bars
|
||||
var responseStrings = transport.responseText.split("|");
|
||||
for (var count=0; count<responseStrings.length; count++) {
|
||||
var divlabel = '#rfc2136status' + count;
|
||||
jQuery(divlabel).prop('innerHTML',responseStrings[count]);
|
||||
}
|
||||
}
|
||||
$( document ).ready(function() {
|
||||
// Do the first status check 2 seconds after the dashboard opens
|
||||
setTimeout('rfc2136_getstatus()', 2000);
|
||||
});
|
||||
</script>
|
||||
Loading…
Reference in a new issue