Skip to content

Commit

Permalink
v0.0.4
Browse files Browse the repository at this point in the history
  • Loading branch information
geek-at committed Dec 10, 2023
1 parent 52c23d2 commit fa32f01
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 10 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Rolling

# v0.0.4
- Added "reload secret" API and UI
- Updated UI so IP can be cloned from the UI

# v0.0.3
- Fixed bug that all ips are flagged as private range
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,13 @@ sub IN NS dyndns.example.com. # the nameserver pointing to the machine runnin

# API

All API calls need the secret in form of a HTTP header called `SECRET`. The secret can be found in the web interface (unless you set the `NO_SECRET` config variable)
All API calls need the secret in form of a HTTP header called `SECRET` or via POST/GET parameter called `secret`. The secret can be found in the web interface (unless you set the `NO_SECRET` config variable)

| Endpoint | Explanation | API answer |
|----------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------|
| `/setip/yourhost.example.com` | Updates the IP of the hostname. If no POST vars are supplied, automatically detecting IP from request, if POST var `ipv4` or `ipv6` is provided, updates the host with these IPs | `OK updated [ip]` or the corresponding error message |
| `/clearips/yourhost.example.com` | Clears all IPs associated with this hostname | `OK` or the corresponding error message |
| `/renewsecret/yourhost.example.com` | Refreshes the secret and returns the new one | the secret or the corresponding error message |


## Examples
Expand Down
17 changes: 15 additions & 2 deletions web/inc/api.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,27 @@ function act()
$return = match ($this->url[1]) {
'setip' => $this->setIP(),
'clearips' => $this->clearIPs(),
'renewsecret' => $this->renewSecret(),
default => '404',
};
return $return;
}

private function renewSecret()
{
$secret = $_SERVER['HTTP_SECRET']?:$_REQUEST['secret'];
$hostname = preg_replace("/[^A-Za-z0-9-.]/", '', $this->url[2]);
$data = getHostData($hostname);
if(!$data['secret']) return 'Invalid hostname';
if($data['secret'] != $secret && NO_SECRET!==true) return 'Invalid secret';
$data['secret'] = bin2hex(random_bytes(32));
updateHostname($hostname,$data);
return $data['secret'];
}

private function clearIPs()
{
$secret = $_SERVER['HTTP_SECRET'];
$secret = $_SERVER['HTTP_SECRET']?:$_REQUEST['secret'];
$hostname = preg_replace("/[^A-Za-z0-9-.]/", '', $this->url[2]);
$data = getHostData($hostname);
if(!$data['secret']) return 'Invalid hostname';
Expand All @@ -33,7 +46,7 @@ private function clearIPs()

private function setIP()
{
$secret = $_SERVER['HTTP_SECRET'];
$secret = $_SERVER['HTTP_SECRET']?:$_REQUEST['secret'];
$hostname = preg_replace("/[^A-Za-z0-9-.]/", '', $this->url[2]);
$data = getHostData($hostname,(defined('ALLOW_DYNAMIC_CREATION') && ALLOW_DYNAMIC_CREATION===true));
if($data['dynamicallycreated']===true) //if this was just created, no need for the secret
Expand Down
2 changes: 1 addition & 1 deletion web/inc/core.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ function updateHostname($hostname,$config)
if($config['ipv6'])
$data.= "\naddress=/$hostname/".$config['ipv6'];

file_put_contents($file, $data);
//time to restart the service?
if($config['ipv4'] || $config['ipv6'])
restartDNSMASQ();
file_put_contents($file, $data);
error_log("[i] Updated hostfile for $hostname");
}

Expand Down
20 changes: 20 additions & 0 deletions web/inc/htmx.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,31 @@ function act()
array_shift($this->url);
$return = match ($this->url[0]) {
'host' => $this->renderHost(),
'updateip' => $this->updateIP(),
default => '404',
};
return $return;
}

private function updateIP(){
$hostname = $_REQUEST['hostname']?:$this->url[1];
$ip = getUserIP();
if(!$_SESSION[$hostname]) return error('Invalid session');
$hostdata = getHostData($hostname);
if(filter_var($ip, FILTER_VALIDATE_IP,FILTER_FLAG_IPV4)) //is the IP an IPv4?
$hostdata['ipv4'] = $ip;
else if(filter_var($ip, FILTER_VALIDATE_IP,FILTER_FLAG_IPV6)) //is the IP an IPv6?
$hostdata['ipv6'] = $ip;
$hostdata['lastupdated'] = date('Y-m-d H:i:s');
updateHostname($hostname,$hostdata);

return '
<label>IPv4: '.($hostdata['ipv4']?:'Not set').'</label>
<label>IPv6: '.($hostdata['ipv6']?:'Not set').'</label>
';

}

private function renderHost()
{
$hostname = $_REQUEST['hostname']?:$this->url[1];
Expand Down
17 changes: 11 additions & 6 deletions web/templates/host.html.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,19 @@

<label>(optional) Password to protect this host: <input name="password" value="<?= $hostdata['password'] ?>"></label>
<label>Note: <input type="text" name="note" value="<?= escape($hostdata['note']) ?>"></label>
<label>IPv4: <?= escape($hostdata['ipv4'])?:'Not set' ?></label>
<label>IPv6: <?= escape($hostdata['ipv6'])?:'Not set' ?></label>
<input type="submit" name="savedata" value="Save">
<div id="ips">
<label>IPv4: <?= escape($hostdata['ipv4'])?:'Not set' ?></label>
<label>IPv6: <?= escape($hostdata['ipv6'])?:'Not set' ?></label>
</div>
<button hx-get="/htmx/updateip/<?=$fulldomain?>" hx-target="#ips">Set to current IP (<?= getUserIP()?>)</button>
<label>Last updated: <?= escape($hostdata['lastupdated']?:'Never') ?></label>
<details>
<summary>Secret</summary>
<?=$hostdata['secret'];?>
<summary>Show secret</summary>
<div id="the-secret"><?=$hostdata['secret'];?></div>
<button hx-get="/api/renewsecret/<?=$fulldomain;?>?secret=<?=$hostdata['secret']?>" hx-target="#the-secret"><i class="fas fa-sync-alt"></i> Renew secret</button>
</details>
<label>Last updated: <?= escape($hostdata['lastupdated']?:'Never') ?></label>
<input type="submit" name="savedata" value="Save">

</form>

<h3>How to use</h3>
Expand Down

0 comments on commit fa32f01

Please sign in to comment.