Skip to content

Commit 65a19ee

Browse files
committed
Initial commit
0 parents  commit 65a19ee

17 files changed

+373
-0
lines changed

.gitignore

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# app specific #
2+
################
3+
4+
datastore/dd_*
5+
6+
# Compiled source #
7+
###################
8+
*.com
9+
*.class
10+
*.dll
11+
*.exe
12+
*.o
13+
*.so
14+
15+
# Packages #
16+
############
17+
# it's better to unpack these files and commit the raw source
18+
# git has its own built in compression methods
19+
*.7z
20+
*.dmg
21+
*.gz
22+
*.iso
23+
*.jar
24+
*.rar
25+
*.tar
26+
*.zip
27+
28+
# Logs and databases #
29+
######################
30+
*.log
31+
*.sql
32+
*.sqlite
33+
34+
# OS generated files #
35+
######################
36+
.DS_Store
37+
.DS_Store?
38+
._*
39+
.Spotlight-V100
40+
.Trashes
41+
ehthumbs.db
42+
Thumbs.db

.htaccess

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
RewriteEngine On
2+
RewriteBase /dev/dns/
3+
4+
RewriteCond %{REQUEST_FILENAME} !-d
5+
RewriteCond %{REQUEST_FILENAME} !-f
6+
7+
RewriteRule ^ping/([^/]*)/([^/]*)$ dns.php?token=$1&hostname=$2 [QSA,L]
8+
RewriteRule ^([^/]*)$ index.php?hostname=$1&type=$2 [QSA,L]

datastore/.htaccess

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
deny from all

datastore/sample.dd_config.json

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"api_key": "your linode api key",
3+
"token": "some random string of characters",
4+
"hosts": {
5+
"your computer's hostname": {"domain_id": "your linode domain id", "resource_id": "your linode resource id"}
6+
}
7+
}

datastore/sample.dd_data.json

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{"hosts":
2+
{}
3+
}

dns.php

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?php
2+
3+
require("loader.php");
4+
5+
$receptor = new DynamicDNS_Receptor();
6+
$receptor->refresh();

index.php

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?php
2+
3+
require("loader.php");
4+
5+
$viewer = new DynamicDNS_Viewer();
6+
$viewer->render();

library/DataStore.php

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
class DynamicDNS_DataStore {
4+
5+
public $config;
6+
public $data;
7+
8+
public function __construct() {
9+
try {
10+
$this->load();
11+
} catch (Exception $e) {
12+
Helper::feedback(array('code' => 500, 'could not handle config/data files'));
13+
}
14+
}
15+
16+
public function load() {
17+
$this->config = json_decode(file_get_contents(DD_CONFIG));
18+
$this->data = json_decode(file_get_contents(DD_DATA));
19+
}
20+
21+
public function save() {
22+
file_put_contents(DD_DATA, json_encode($this->data));
23+
}
24+
25+
}

library/Helper.php

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
class Helper {
4+
public static function feedback($obj = array()) {
5+
$obj = array_merge(array(
6+
"status" => "normal",
7+
"code" => 200,
8+
"time" => time()
9+
), $obj);
10+
11+
http_response_code($obj['code']);
12+
echo json_encode($obj);
13+
}
14+
}

library/Receptor.php

+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
<?php
2+
3+
class DynamicDNS_Receptor {
4+
5+
private $datastore;
6+
7+
public function __construct() {
8+
$this->datastore = new DynamicDNS_DataStore();
9+
}
10+
11+
private function is_request_valid() {
12+
$hostname = isset($_GET['hostname']) && !empty($_GET['hostname']);
13+
$token = isset($_GET['token']) && !empty($_GET['token']);
14+
return $hostname && $token;
15+
}
16+
17+
private function verify_hostname() {
18+
$hostname = $_GET['hostname'];
19+
$config = isset( $this->datastore->config->hosts->{$hostname} );
20+
if ( $config ) {
21+
if ( isset($this->datastore->data->hosts->{$hostname}) == false ) {
22+
$obj = new stdClass();
23+
$obj->{'last_update'} = 0;
24+
$obj->{'updates'} = 0;
25+
$obj->{'ip'} = '';
26+
$this->datastore->data->hosts->{$hostname} = $obj;
27+
}
28+
return true;
29+
}
30+
return false;
31+
}
32+
33+
private function verify_token() {
34+
$token = $_GET['token'];
35+
if ( $token == $this->datastore->config->token ) {
36+
return true;
37+
}
38+
return false;
39+
}
40+
41+
private function verify_change($hostname) {
42+
$client_ip = $_SERVER['REMOTE_ADDR'];
43+
// has not changed
44+
if ( $this->datastore->data->hosts->{$hostname}->{'ip'} == $client_ip ) {
45+
return false;
46+
}
47+
48+
// has changed
49+
return true;
50+
}
51+
52+
53+
public function refresh() {
54+
55+
if ( !$this->is_request_valid() ) {
56+
Helper::feedback(array("code" => 400, "status" => "invalid request"));
57+
return false;
58+
}
59+
if ( !$this->verify_token() ) {
60+
Helper::feedback(array("code" => 401, "status" => "invalid token"));
61+
return false;
62+
}
63+
if ( !$this->verify_hostname() ) {
64+
Helper::feedback(array("code" => 401, "status" => "invalid hostname"));
65+
return false;
66+
}
67+
68+
$hostname = $_GET['hostname'];
69+
70+
$config = $this->datastore->config->hosts->{$hostname};
71+
$data = $this->datastore->data->hosts->{$hostname};
72+
73+
if ( $this->verify_change($hostname) == false ) {
74+
Helper::feedback(array("code" => 202, "status" => "host not changed"));
75+
return false;
76+
}
77+
78+
$result = $this->update($hostname);
79+
if ( $result ) {
80+
Helper::feedback(array("code" => 201, "status" => "dynamic dns successful"));
81+
} else {
82+
Helper::feedback(array("code" => 500, "status" => "dynamic dns failed"));
83+
}
84+
85+
}
86+
87+
private function update($hostname) {
88+
89+
$ip = $_SERVER['REMOTE_ADDR'];
90+
91+
$url = sprintf("%sapi_key=%s&api_action=domain.resource.update&DomainID=%s&ResourceID=%s&Target=%s", LINODE_API, $this->datastore->config->api_key, $this->datastore->config->hosts->{$hostname}->{'domain_id'}, $this->datastore->config->hosts->{$hostname}->{'resource_id'}, $ip);
92+
93+
$response = file_get_contents($url);
94+
$response_json = json_decode($response);
95+
96+
if ( count($response_json->{'ERRORARRAY'}) == 0 ) {
97+
$this->datastore->data->hosts->{$hostname}->{'ip'} = $ip;
98+
$this->datastore->data->hosts->{$hostname}->{'updates'} = $this->datastore->data->hosts->{$hostname}->{'updates'} + 1;
99+
$this->datastore->data->hosts->{$hostname}->{'last_update'} = time();
100+
$this->datastore->save();
101+
return true;
102+
}
103+
104+
return false;
105+
106+
}
107+
108+
109+
}

library/Viewer.php

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
class DynamicDNS_Viewer {
4+
5+
private $datastore;
6+
7+
public function __construct() {
8+
$this->datastore = new DynamicDNS_DataStore();
9+
}
10+
11+
private function is_request_valid() {
12+
if ( isset($_GET['hostname']) == false ) {
13+
return false;
14+
}
15+
16+
$hostname = $_GET['hostname'];
17+
18+
$config = isset( $this->datastore->config->hosts->{$hostname} );
19+
$data = isset( $this->datastore->data->hosts->{$hostname} );
20+
21+
if ( $config && $data ) {
22+
return true;
23+
}
24+
return false;
25+
}
26+
27+
public function render() {
28+
29+
if ( !$this->is_request_valid() ) {
30+
include(DD_VIEWS . 'invalid-hostname-view.php');
31+
return false;
32+
}
33+
34+
$type = "html";
35+
if ( isset($_GET['type']) && !empty($_GET['type']) ) {
36+
$type = $_GET['type'];
37+
}
38+
39+
$hostname = $_GET['hostname'];
40+
$ip = $this->datastore->data->hosts->{$hostname}->{'ip'};
41+
42+
switch ($type) {
43+
case 'plain':
44+
include(DD_VIEWS . 'plain-view.php');
45+
break;
46+
47+
case 'json':
48+
include(DD_VIEWS . 'json-view.php');
49+
break;
50+
51+
default:
52+
include(DD_VIEWS . 'html-view.php');
53+
break;
54+
}
55+
56+
}
57+
58+
}

loader.php

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
define('DD_CONFIG', 'datastore/dd_config.json');
4+
define('DD_DATA', 'datastore/dd_data.json');
5+
6+
define('DD_VIEWS', 'views/');
7+
define('DD_LIBRARY', 'library/');
8+
9+
define('LINODE_API', 'https://api.linode.com/api/?');
10+
11+
require_once(DD_LIBRARY . 'Helper.php');
12+
require_once(DD_LIBRARY . 'DataStore.php');
13+
require_once(DD_LIBRARY . 'Receptor.php');
14+
require_once(DD_LIBRARY . 'Viewer.php');

view.php

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?php
2+
3+
require("loader.php");
4+
5+
$viewer = new DynamicDNS_Viewer();
6+
$viewer->render();

views/html-view.php

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php if (!defined('DD_VIEWS')) {exit(-1);} ?>
2+
<!doctype html>
3+
<html>
4+
<head>
5+
6+
<title><?php echo $hostname; ?></title>
7+
8+
9+
<style type="text/css">
10+
body {
11+
background-color: #ddd;
12+
color: #222;
13+
font-size: 1em;
14+
font-family: Helvetica, Arial, sans-serif;
15+
}
16+
.container h1 {
17+
font-size: 4em;
18+
text-align: center;
19+
}
20+
a, a:link {
21+
color: #222;
22+
text-decoration: none;
23+
}
24+
a:hover {
25+
color: #000;
26+
text-decoration: underline;
27+
}
28+
</style>
29+
30+
</head>
31+
<body>
32+
33+
<div class="container">
34+
<h1><a href="http://<?php echo $ip; ?>/"><?php echo $ip; ?></a></h1>
35+
</div>
36+
37+
</body>
38+
</html>

views/invalid-hostname-view.php

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php if (!defined('DD_VIEWS')) {exit(-1);} ?>
2+
<!doctype html>
3+
<html>
4+
<head>
5+
6+
<title>invalid hostname</title>
7+
8+
9+
<style type="text/css">
10+
body {
11+
background-color: #ddd;
12+
color: #222;
13+
font-size: 1em;
14+
font-family: Helvetica, Arial, sans-serif;
15+
}
16+
.container h2 {
17+
font-size: 4em;
18+
text-align: center;
19+
}
20+
</style>
21+
22+
</head>
23+
<body>
24+
25+
<div class="container">
26+
<h2>invalid hostname</h2>
27+
</div>
28+
29+
</body>
30+
</html>

0 commit comments

Comments
 (0)