diff --git a/.pullapprove.yml b/.pullapprove.yml index 8bd8f0a2b..8bd890cba 100644 --- a/.pullapprove.yml +++ b/.pullapprove.yml @@ -33,6 +33,6 @@ groups: conditions: branches: - master - required: -1 + required: 4 teams: - admin diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 64e702f86..bfb67b776 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,3 +7,4 @@ This is a basic checklist for now, We will update it in the future. * Submit Pull Requests to the development branch only. * Before Submitting your Pull Request, merge `devel` with your new branch and fix any conflicts. (Make sure you don't break anything in development!) * Be patient. We will review all submitted pull requests, but our focus is on stability.. please don't be offended if we reject your PR, or it appears we're doing nothing with it! We'll get around to it.. +* Please use the Pi-hole brand: **Pi-hole** (Take a special look at the capitalized 'P' and a low 'h' with a hyphen) diff --git a/README.md b/README.md index 12769874c..e3f3b257a 100644 --- a/README.md +++ b/README.md @@ -22,8 +22,10 @@ A read-only API can be accessed at `/admin/api.php`. With either no parameters o } ``` -There are many more parameters, such as `summaryRaw`, `overTimeData10mins`, ` topClients` or `getQuerySources`, `getQueryTypes`, `getForwardDestinations`, and `getAllQueries`. -Together with a token it is also possible to enable and disable (also with a set timeout) blocking via the API. +There are many more parameters, such as `summaryRaw`, `overTimeData10mins`, `topItems`, ` topClients` or `getQuerySources`, `getQueryTypes`, `getForwardDestinations`, and finally `getAllQueries`. +Together with a token it is also possible to enable and disable (also with a set timeout) blocking via the API + +The API returns more information (in a slighly different format if `FTL` is running) - it supports a fall-back to the "old" PHP API if `FTL` is not running. Test the type and/or version of the API by using the parameter `type` and `version`.

diff --git a/api.php b/api.php index e8703cc74..d6d68c344 100644 --- a/api.php +++ b/api.php @@ -1,151 +1,101 @@ "enabled")); - unlink("../custom_disable_timer"); - } - elseif (isset($_GET['disable']) && $auth) { - if(isset($_GET["auth"])) - { - if($_GET["auth"] !== $pwhash) - die("Not authorized!"); - } - else - { - // Skip token validation if explicit auth string is given - check_csrf($_GET['token']); - } - $disable = intval($_GET['disable']); - // intval returns the integer value on success, or 0 on failure - if($disable > 0) - { - $timestamp = time(); - exec("sudo pihole disable ".$disable."s"); - file_put_contents("../custom_disable_timer",($timestamp+$disable)*1000); - } - else - { - exec('sudo pihole disable'); - unlink("../custom_disable_timer"); - } - $data = array_merge($data, array("status" => "disabled")); - } - - if (isset($_GET['getGravityDomains'])) { - $data = array_merge($data, getGravity()); - } - - if (isset($_GET['tailLog']) && $auth) { - $data = array_merge($data, tailPiholeLog($_GET['tailLog'])); - } - - function filterArray(&$inArray) { - $outArray = array(); - foreach ($inArray as $key=>$value) { - if (is_array($value)) { - $outArray[htmlspecialchars($key)] = filterArray($value); - } else { - $outArray[htmlspecialchars($key)] = !is_numeric($value) ? htmlspecialchars($value) : $value; - } - } - return $outArray; - } - - $data = filterArray($data); - - if(isset($_GET["jsonForceObject"])) - { - echo json_encode($data, JSON_FORCE_OBJECT); - } - else - { - echo json_encode($data); - } +* Please see LICENSE file for your rights under this license */ + +$api = true; +header('Content-type: application/json'); +require("scripts/pi-hole/php/FTL.php"); +require("scripts/pi-hole/php/password.php"); +require("scripts/pi-hole/php/auth.php"); +check_cors(); + + +$data = array(); + +// Common API functions +if (isset($_GET['status']) && $auth) +{ + $pistatus = exec('sudo pihole status web'); + if ($pistatus == "1") + { + $data = array_merge($data, array("status" => "enabled")); + } + else + { + $data = array_merge($data, array("status" => "disabled")); + } +} +elseif (isset($_GET['enable']) && $auth) +{ + if(isset($_GET["auth"])) + { + if($_GET["auth"] !== $pwhash) + die("Not authorized!"); + } + else + { + // Skip token validation if explicit auth string is given + check_csrf($_GET['token']); + } + exec('sudo pihole enable'); + $data = array_merge($data, array("status" => "enabled")); + unlink("../custom_disable_timer"); +} +elseif (isset($_GET['disable']) && $auth) +{ + if(isset($_GET["auth"])) + { + if($_GET["auth"] !== $pwhash) + die("Not authorized!"); + } + else + { + // Skip token validation if explicit auth string is given + check_csrf($_GET['token']); + } + $disable = intval($_GET['disable']); + // intval returns the integer value on success, or 0 on failure + if($disable > 0) + { + $timestamp = time(); + exec("sudo pihole disable ".$disable."s"); + file_put_contents("../custom_disable_timer",($timestamp+$disable)*1000); + } + else + { + exec('sudo pihole disable'); + unlink("../custom_disable_timer"); + } + $data = array_merge($data, array("status" => "disabled")); +} + +// Other API functions +if(!testFTL() && !isset($_GET["PHP"])) +{ + $data = array_merge($data, array("FTLnotrunning" => true)); +} +else +{ + if(!isset($_GET["PHP"])) + { + require("api_FTL.php"); + } + else + { + require("api_PHP.php"); + } +} + +if(isset($_GET["jsonForceObject"])) +{ + echo json_encode($data, JSON_FORCE_OBJECT); +} +else +{ + echo json_encode($data); +} ?> diff --git a/api_FTL.php b/api_FTL.php new file mode 100644 index 000000000..0e0a26375 --- /dev/null +++ b/api_FTL.php @@ -0,0 +1,287 @@ + $domains_over_time, + 'ads_over_time' => $ads_over_time); + $data = array_merge($data, $result); +} + +if (isset($_GET['topItems']) && $auth) +{ + if(is_numeric($_GET['topItems'])) + { + sendRequestFTL("top-domains (".$_GET['topItems'].")"); + } + else + { + sendRequestFTL("top-domains"); + } + + $return = getResponseFTL(); + $top_queries = array(); + foreach($return as $line) + { + $tmp = explode(" ",$line); + $top_queries[$tmp[2]] = intval($tmp[1]); + } + + if(is_numeric($_GET['topItems'])) + { + sendRequestFTL("top-ads (".$_GET['topItems'].")"); + } + else + { + sendRequestFTL("top-ads"); + } + + $return = getResponseFTL(); + $top_ads = array(); + foreach($return as $line) + { + $tmp = explode(" ",$line); + $top_ads[$tmp[2]] = intval($tmp[1]); + } + + $result = array('top_queries' => $top_queries, + 'top_ads' => $top_ads); + + $data = array_merge($data, $result); +} + +if ((isset($_GET['topClients']) || isset($_GET['getQuerySources'])) && $auth) +{ + + if(isset($_GET['topClients'])) + { + $number = $_GET['topClients']; + } + elseif(isset($_GET['getQuerySources'])) + { + $number = $_GET['getQuerySources']; + } + + if(is_numeric($number)) + { + sendRequestFTL("top-clients (".$number.")"); + } + else + { + sendRequestFTL("top-clients"); + } + + $return = getResponseFTL(); + $top_clients = array(); + foreach($return as $line) + { + $tmp = explode(" ",$line); + if(count($tmp) == 4) + { + $top_clients[$tmp[3]."|".$tmp[2]] = intval($tmp[1]); + } + else + { + $top_clients[$tmp[2]] = intval($tmp[1]); + } + } + + $result = array('top_sources' => $top_clients); + $data = array_merge($data, $result); +} + +if (isset($_GET['getForwardDestinations']) && $auth) +{ + sendRequestFTL("forward-dest"); + $return = getResponseFTL(); + $forward_dest = array(); + foreach($return as $line) + { + $tmp = explode(" ",$line); + if(count($tmp) == 4) + { + $forward_dest[$tmp[3]."|".$tmp[2]] = intval($tmp[1]); + } + else + { + $forward_dest[$tmp[2]] = intval($tmp[1]); + } + } + + $result = array('forward_destinations' => $forward_dest); + $data = array_merge($data, $result); +} + +if (isset($_GET['getQueryTypes']) && $auth) +{ + sendRequestFTL("querytypes"); + $return = getResponseFTL(); + $querytypes = array(); + foreach($return as $ret) + { + $tmp = explode(": ",$ret); + $querytypes[$tmp[0]] = intval($tmp[1]); + } + + $result = array('querytypes' => $querytypes); + $data = array_merge($data, $result); +} + +if (isset($_GET['getAllQueries']) && $auth) +{ + if(isset($_GET['from']) && isset($_GET['until'])) + { + // Get limited time interval + sendRequestFTL("getallqueries-time ".$_GET['from']." ".$_GET['until']); + } + else if(isset($_GET['domain'])) + { + // Get specific domain only + sendRequestFTL("getallqueries-domain ".$_GET['domain']); + } + else if(isset($_GET['client'])) + { + // Get specific client only + sendRequestFTL("getallqueries-client ".$_GET['client']); + } + else + { + // Get all queries + sendRequestFTL("getallqueries"); + } + $return = getResponseFTL(); + $allQueries = array(); + foreach($return as $line) + { + $tmp = explode(" ",$line); + array_push($allQueries,$tmp); + } + + $result = array('data' => $allQueries); + $data = array_merge($data, $result); +} + +if(isset($_GET["recentBlocked"])) +{ + sendRequestFTL("recentBlocked"); + die(getResponseFTL()[0]); + unset($data); +} + +if (isset($_GET['overTimeDataForwards']) && $auth) +{ + sendRequestFTL("ForwardedoverTime"); + $return = getResponseFTL(); + + foreach($return as $line) + { + $tmp = explode(" ",$line); + for ($i=0; $i < count($tmp)-1; $i++) { + $over_time[intval($tmp[0])][$i] = intval($tmp[$i+1]); + } + } + $result = array('over_time' => $over_time); + $data = array_merge($data, $result); +} + +if (isset($_GET['getForwardDestinationNames']) && $auth) +{ + sendRequestFTL("forward-names"); + $return = getResponseFTL(); + $forward_dest = array(); + foreach($return as $line) + { + $tmp = explode(" ",$line); + if(count($tmp) == 4) + { + $forward_dest[$tmp[3]."|".$tmp[2]] = intval($tmp[1]); + } + else + { + $forward_dest[$tmp[2]] = intval($tmp[1]); + } + } + + $result = array('forward_destinations' => $forward_dest); + $data = array_merge($data, $result); +} + +if (isset($_GET['overTimeDataQueryTypes']) && $auth) +{ + sendRequestFTL("QueryTypesoverTime"); + $return = getResponseFTL(); + + foreach($return as $line) + { + $tmp = explode(" ",$line); + for ($i=0; $i < count($tmp)-1; $i++) { + $over_time[intval($tmp[0])][$i] = intval($tmp[$i+1]); + } + } + $result = array('over_time' => $over_time); + $data = array_merge($data, $result); +} + +disconnectFTL(); +?> diff --git a/api_PHP.php b/api_PHP.php new file mode 100644 index 000000000..dc7a1d2b9 --- /dev/null +++ b/api_PHP.php @@ -0,0 +1,93 @@ +$value) { + if (is_array($value)) { + $outArray[htmlspecialchars($key)] = filterArray($value); + } else { + $outArray[htmlspecialchars($key)] = !is_numeric($value) ? htmlspecialchars($value) : $value; + } + } + return $outArray; + } + + $data = filterArray($data); +?> diff --git a/debug.php b/debug.php index 84416cff0..20ffa7c87 100644 --- a/debug.php +++ b/debug.php @@ -1,4 +1,10 @@ - diff --git a/gravity.php b/gravity.php index 15f6e605c..5e7367255 100644 --- a/gravity.php +++ b/gravity.php @@ -1,10 +1,10 @@ - - diff --git a/help.php b/help.php index 66818b104..102c6e721 100644 --- a/help.php +++ b/help.php @@ -1,10 +1,10 @@ - - 0) @@ -48,20 +48,13 @@ +

The Top Domains and Top Advertisers lists may be hidden depending on the privacy Settings on the settings page

Note that the login session does not expire on the dashboard, as the summary is updated every 10 seconds which refreshes the session.

@@ -70,7 +63,7 @@

Query Log

-

Shows the recent queries by parsing Pi-hole's log. It is possible to search through the whole list by using the "Search" input field. If the status is reported as "OK", then the DNS request has been permitted. Otherwise ("Pi-holed") it has been blocked. By clicking on the buttons under "Action" the corresponding domains can quickly be added to the white-/blacklist. The status of the action will be reported on this page.

+

Shows the recent queries by parsing Pi-hole's log. It is possible to search through the whole list by using the "Search" input field. If the status is reported as "OK", then the DNS request has been permitted. Otherwise ("Pi-holed") it has been blocked. By clicking on the buttons under "Action" the corresponding domains can quickly be added to the white-/blacklist. The status of the action will be reported on this page. By default, only the recent 10 minutes are shown to enhance the loading speed of the query log page. All domains can be requested by clicking on the corresponding link in the header of the page. Note that the result heavily depends on your privacy settings (see Settings page).

@@ -84,7 +77,7 @@

Disable / Enable

- Disables/enables Pi-Hole blocking completely. You may have to wait a few minutes for the changes to reach all of your devices. The change will be reflected by a changed status (top left) + Disables/enables Pi-hole blocking completely. You may have to wait a few minutes for the changes to reach all of your devices. The change will be reflected by a changed status (top left)
@@ -108,18 +101,22 @@

Settings

- Change settings for the Pi-Hole + Change settings for the Pi-hole

Networking

- Displays information about the interfaces of the Pi-Hole. No changes possible. -

Pi-Hole DHCP Server

- Using this setting you can enable/disable the DHCP server of the Pi-Hole. Note that you should disable any other DHCP server on your network to avoid IP addresses being used more than once. You have to give the range of IPs that DHCP will serve and the IP of the local router (gateway). If the DHCP server is active, the current leases are shown on the settings page. IPv4 DHCP will always be activated, IPv6 (stateless + statefull) can be enabled. + Displays information about the interfaces of the Pi-hole. No changes possible. +

Pi-hole DHCP Server

+ Using this setting you can enable/disable the DHCP server of the Pi-hole. Note that you should disable any other DHCP server on your network to avoid IP addresses being used more than once. You have to give the range of IPs that DHCP will serve and the IP of the local router (gateway). If the DHCP server is active, the current leases are shown on the settings page. IPv4 DHCP will always be activated, IPv6 (stateless + statefull) can be enabled.

Upstream DNS Servers

Customize used upstream DNS servers + advanced settings for DNS servers. Note that any number of DNS servers may be enabled at a time.

Query Logging

Enabled/disable query logging on your Pi-hole + provide option to flush the log

API

- Change settings which apply to the API as well as the web UI
- Note that Top Clients have to be given as IP addresses + Change settings which apply to the API as well as the web UI +
    +
  • Show permitted domain entries: Toogle permitted queries in Query Log + Top Domains on Main Page
  • +
  • Show blockes domain entries: Toogle blocked queries in Query Log + Top Ads on Main Page
  • +
  • Privacy mode: Replace IPs in query log with "hidden"
  • +

Web User Interface

Other settings which affect the webUI but not the API of Pi-hole

System Administration

@@ -129,7 +126,7 @@

Authentication system (currently enableddisabled)

-

Using the command

sudo pihole -a -p pa22w0rd
where pa22w0rd is the password to be set in this example, one can enable the authentication system of this web interface. Thereafter, a login is required for most pages (the dashboard will show a limited amount of statistics). Note that the authentication system may be disabled again, by setting an empty password using the command shown above. The Help center will show more details concerning the authentication system only if it is enabled

+

Using the command

sudo pihole -a -p
and entering a password to be set, one can enable the authentication system of this web interface. Thereafter, a login is required for most pages (the dashboard will show a limited amount of statistics). Note that the authentication system may be disabled again, by setting an empty password using the command shown above. The Help center will show more details concerning the authentication system only if it is enabled

diff --git a/index.php b/index.php index 659a868a1..470c5180a 100644 --- a/index.php +++ b/index.php @@ -1,10 +1,10 @@ - - @@ -68,7 +68,7 @@
-

Queries over time

+

Queries over Time

@@ -89,14 +89,14 @@ // a password if($auth){ ?>
-
+