Skip to content

Commit 66a1656

Browse files
Converting unbound queries to object oriented design
1 parent 67cd474 commit 66a1656

3 files changed

Lines changed: 231 additions & 9 deletions

File tree

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
<?php
2+
require_once("api/framework/APIBaseModel.inc");
3+
require_once("api/framework/APIResponse.inc");
4+
5+
class APIServicesUnboundModifyHosts extends APIBaseModel {
6+
# Create our method constructor
7+
public function __construct() {
8+
parent::__construct();
9+
$this->methods = ["POST"];
10+
$this->privileges = ["page-all", "page-services-dnsresolver-edithost"];
11+
$this->change_note = "Modified DNS Resolver host override via API";
12+
}
13+
14+
public function action() {
15+
// Sort and write our new configuration
16+
//usort($this->validated_data["hosts_conf"], "strcmp");
17+
$this->config["unbound"]["hosts"] = $this->validated_data["hosts_conf"];
18+
$this->write_config();
19+
mark_subsystem_dirty("unbound");
20+
# If user requests immediately application
21+
if ($this->validated_data["apply"] === true) {
22+
APITools\unbound_reload_config();
23+
}
24+
return APIResponse\get(0, $this->validated_data["update_list"]);
25+
}
26+
27+
public function validate_payload() {
28+
if (isset($this->initial_data['host'])) {
29+
$this->validated_data["hostname"] = trim($this->initial_data['host']);
30+
$h_mode = true;
31+
}
32+
if (isset($this->initial_data['new_host'])) {
33+
$new_hostname = trim($this->initial_data['new_host']);
34+
}
35+
if (isset($this->initial_data['domain'])) {
36+
$this->validated_data["domain"] = trim($this->initial_data['domain']);
37+
} elseif ($h_mode) {
38+
$this->errors[] = APIResponse\get(2005);
39+
}
40+
if (isset($this->initial_data['new_domain'])) {
41+
$this->validated_data["new_domain"] = trim($this->initial_data['new_domain']);
42+
}
43+
if (isset($this->initial_data['ip']) and !$h_mode) {
44+
$this->validated_data["ip"] = trim($this->initial_data['ip']);
45+
$i_mode = true;
46+
}
47+
if (isset($this->initial_data['new_ip'])) {
48+
$this->validated_data["new_ip"] = trim($this->initial_data['new_ip']);
49+
} elseif ($i_mode) {
50+
$this->errors[] = APIResponse\get(2012);
51+
}
52+
if (isset($this->initial_data['descr'])) {
53+
$this->validated_data["descr"] = $this->initial_data['descr'];
54+
}
55+
if (isset($this->initial_data['aliases'])) {
56+
$this->validated_data["aliases"] = $this->initial_data['aliases'];
57+
}
58+
if ($this->initial_data['apply'] === true) {
59+
$this->validated_data["apply"] = $this->initial_data['apply'];
60+
}
61+
// Validate our input against our exist configuration
62+
if (APITools\unbound_host_override_exists($this->validated_data["hostname"], $this->validated_data["domain"]) or $i_mode) {
63+
$this->validated_data["hosts_conf"] = $this->config["unbound"]["hosts"]; // Current Unbound host overrides
64+
$h_count = 0; // Assign a loop counter
65+
$this->validated_data["update_list"] = array(); // Assign array to track which values were updated
66+
// Check modification mode
67+
if ($i_mode) {
68+
if (is_ipaddrv4($this->validated_data["new_ip"]) or is_ipaddrv6($this->validated_data["new_ip"])) {
69+
foreach ($this->validated_data["hosts_conf"] as $he) {
70+
// If our IP matches, update our IP
71+
if ($this->validated_data["ip"] === $he["ip"]) {
72+
$this->validated_data["hosts_conf"][$h_count]["ip"] = $this->validated_data["new_ip"];
73+
$this->validated_data["update_list"][] = $this->validated_data["hosts_conf"][$h_count];
74+
}
75+
// Increase our counter
76+
$h_count++;
77+
}
78+
} else {
79+
$this->errors[] = APIResponse\get(2011);
80+
}
81+
} elseif ($h_mode) {
82+
foreach ($this->validated_data["hosts_conf"] as $he) {
83+
$he_updated = false;
84+
// Check if both our hostname and domain names were changed
85+
if (isset($new_hostname) and isset($this->validated_data["new_domain"])) {
86+
if ($this->validated_data["hostname"] === $he["host"] and $this->validated_data["domain"] === $he["domain"]) {
87+
if (!APITools\unbound_host_override_exists($new_hostname, $this->validated_data["new_domain"])) {
88+
$this->validated_data["hosts_conf"][$h_count]["host"] = $new_hostname;
89+
$this->validated_data["hosts_conf"][$h_count]["domain"] = $this->validated_data["new_domain"];
90+
$he_updated = true;
91+
} else {
92+
$this->errors[] = APIResponse\get(2010);
93+
}
94+
}
95+
} elseif (isset($new_hostname)) {
96+
if ($this->validated_data["hostname"] === $he["host"] and $this->validated_data["domain"] === $he["domain"]) {
97+
if (!APITools\unbound_host_override_exists($new_hostname, $he["domain"])) {
98+
$this->validated_data["hosts_conf"][$h_count]["host"] = $new_hostname;
99+
$he_updated = true;
100+
} else {
101+
$this->errors[] = APIResponse\get(2010);
102+
}
103+
}
104+
} elseif (isset($this->validated_data["new_domain"])) {
105+
if ($this->validated_data["hostname"] === $he["host"] and $this->validated_data["domain"] === $he["domain"]) {
106+
if (!APITools\unbound_host_override_exists($he["host"], $this->validated_data["new_domain"])) {
107+
$this->validated_data["hosts_conf"][$h_count]["domain"] = $this->validated_data["new_domain"];
108+
$he_updated = true;
109+
} else {
110+
$this->errors[] = APIResponse\get(2010);
111+
}
112+
}
113+
}
114+
if (isset($this->validated_data["new_ip"])) {
115+
if (is_ipaddrv4($this->validated_data["new_ip"]) or is_ipaddrv6($this->validated_data["new_ip"])) {
116+
if ($this->validated_data["hostname"] === $he["host"] and $this->validated_data["domain"] === $he["domain"]) {
117+
$this->validated_data["hosts_conf"][$h_count]["ip"] = $this->validated_data["new_ip"];
118+
$he_updated = true;
119+
}
120+
} else {
121+
$this->errors[] = APIResponse\get(2011);
122+
}
123+
}
124+
if (isset($this->validated_data["descr"])) {
125+
if ($this->validated_data["hostname"] === $he["host"] and $this->validated_data["domain"] === $he["domain"]) {
126+
$this->validated_data["hosts_conf"][$h_count]["descr"] = $this->validated_data["descr"];
127+
$he_updated = true;
128+
}
129+
}
130+
if (isset($this->validated_data["aliases"])) {
131+
// Check if we have more than one
132+
if (count($this->validated_data["update_list"]) <= 1) {
133+
$alias_fin = $this->unbound_parse_aliases($this->validated_data["aliases"]); // Parse our aliases
134+
if ($alias_fin !== "") {
135+
$this->validated_data["hosts_conf"][$h_count]["aliases"] = $alias_fin;
136+
$he_updated = true;
137+
}
138+
}
139+
}
140+
// Check if our entry was updated, if so add it to our update list
141+
if ($he_updated) {
142+
$this->validated_data["update_list"][] = $this->validated_data["hosts_conf"][$h_count];
143+
}
144+
// Increase our counter
145+
$h_count++;
146+
}
147+
}
148+
} else {
149+
$this->errors[] = APIResponse\get(2013);
150+
}
151+
}
152+
153+
// Check user's DNS Resolver (Unbound) host override alias input for errors
154+
public function unbound_parse_aliases($aliases) {
155+
$aliases_fin = ""; // Default our alias value to blank string
156+
if (is_array($aliases)) {
157+
$a_count = 0;
158+
$aliases_fin = array();
159+
foreach ($aliases as $alias_ent) {
160+
// Check that each alias has a valid hostname
161+
if (array_key_exists("host", $alias_ent) and is_string($alias_ent["host"])) {
162+
$aliases_fin[$a_count] = array("host" => trim($alias_ent["host"]));
163+
} else {
164+
$this->errors[] = APIResponse\get(2007);
165+
}
166+
// Check that each alias has a valid domain name
167+
if (array_key_exists("domain", $alias_ent) and is_string($alias_ent["domain"])) {
168+
$aliases_fin[$a_count]["domain"] = trim($alias_ent["domain"]);
169+
} else {
170+
$this->errors[] = APIResponse\get(2008);
171+
}
172+
// Check for alias description under descr key
173+
if (array_key_exists("descr", $alias_ent) and is_string($alias_ent["descr"])) {
174+
if (is_string($alias_ent["descr"])) {
175+
$aliases_fin[$a_count]["description"] = $alias_ent["descr"];
176+
}
177+
}
178+
// Check for alias description under description key
179+
if (array_key_exists("description", $alias_ent) and is_string($alias_ent["description"])) {
180+
if (is_string($alias_ent["description"])) {
181+
$aliases_fin[$a_count]["description"] = $alias_ent["description"];
182+
}
183+
}
184+
// Increase our counter
185+
$a_count++;
186+
}
187+
// Check if our aliases already exist
188+
foreach ($aliases_fin as $af) {
189+
print_r($af);
190+
if (APITools\unbound_host_override_exists($af["host"], $af["domain"]) === true) {
191+
$this->errors[] = APIResponse\get(2009);
192+
}
193+
}
194+
// Nest our aliases under the item key
195+
$aliases_fin = array("item" => $aliases_fin);
196+
}
197+
// Return our parsed aliases
198+
return $aliases_fin;
199+
}
200+
}

pfSense-pkg-API/files/etc/inc/api/framework/APITools.inc

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -672,4 +672,32 @@ function unbound_reload_config() {
672672
clear_subsystem_dirty("unbound");
673673
return true;
674674
}
675-
}
675+
}
676+
677+
// Check if a DNS Resolver (Unbound) host override already exists
678+
function unbound_host_override_exists($hostname, $domain) {
679+
// Local variables
680+
global $err_lib, $config;
681+
$curr_hosts = array();
682+
$host_exists = false;
683+
// Check if host override already exists
684+
if (array_key_exists("hosts", $config["unbound"])) {
685+
$curr_hosts = $config["unbound"]["hosts"];
686+
}
687+
foreach ($curr_hosts as $host_ent) {
688+
if ($host_ent["host"] === $hostname and $host_ent["domain"] === $domain) {
689+
$host_exists = true;
690+
break;
691+
}
692+
if (is_array($host_ent["aliases"])) {
693+
foreach ($host_ent["aliases"]["item"] as $alias_ent) {
694+
if ($alias_ent["host"] === $hostname and $alias_ent["domain"] === $domain) {
695+
$host_exists = true;
696+
break;
697+
}
698+
}
699+
}
700+
}
701+
return $host_exists;
702+
}
703+
Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
11
<?php
22
# Copyright 2020 - Jared Hendrickson
3-
# IMPORTS
4-
require_once("apicalls.inc");
5-
6-
# RUN API CALL
7-
$resp = api_services_unbound_modify_hosts();
8-
http_response_code($resp["code"]);
9-
echo json_encode($resp) . PHP_EOL;
10-
exit();
3+
require_once("api/api_models/APIServicesUnboundModifyHosts.inc");
4+
(new APIServicesUnboundModifyHosts())->listen();

0 commit comments

Comments
 (0)