From 725d0de52af7fcbc159afebcd86fc8d6a8a75a3c Mon Sep 17 00:00:00 2001 From: Mcat12 Date: Tue, 1 Mar 2016 22:50:18 -0500 Subject: [PATCH 01/35] Fix Query Log data --- data.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/data.php b/data.php index 87614cbc..bafb62cc 100644 --- a/data.php +++ b/data.php @@ -128,9 +128,9 @@ $exploded = explode(" ", trim($query)); array_push($allQueries['data'], array( $time->format('Y-m-d\TH:i:s'), - substr($exploded[4], 6, -1), - $exploded[5], - $exploded[7], + substr($exploded[5], 6, -1), + $exploded[6], + $exploded[8], )); } From 4f20cc6627148d77f678455876f34eb9a49575b6 Mon Sep 17 00:00:00 2001 From: Mcat12 Date: Mon, 7 Mar 2016 20:58:00 -0500 Subject: [PATCH 02/35] Fix query log refresh --- queries.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/queries.php b/queries.php index 9a47c9af..b77cdc7f 100644 --- a/queries.php +++ b/queries.php @@ -63,7 +63,7 @@ } ); function refreshData() { - tableApi.ajax.url("api.php?getAllQuerie").load(); + tableApi.ajax.url("api.php?getAllQueries").load(); } From 951a28cb3689d84fe35c101d805d9f83810d0fc4 Mon Sep 17 00:00:00 2001 From: Mcat12 Date: Tue, 8 Mar 2016 12:30:35 -0500 Subject: [PATCH 03/35] Disable list editing --- header.html | 4 + list.php | 212 ---------------------------------------------- php/add.php | 17 ---- php/checkPass.php | 10 --- php/functions.php | 5 -- php/get.php | 15 ---- php/sub.php | 17 ---- 7 files changed, 4 insertions(+), 276 deletions(-) delete mode 100644 list.php delete mode 100644 php/add.php delete mode 100644 php/checkPass.php delete mode 100644 php/functions.php delete mode 100644 php/get.php delete mode 100644 php/sub.php diff --git a/header.html b/header.html index 9e904bea..49371f74 100644 --- a/header.html +++ b/header.html @@ -123,17 +123,21 @@ + +
  • diff --git a/list.php b/list.php deleted file mode 100644 index 8087f20f..00000000 --- a/list.php +++ /dev/null @@ -1,212 +0,0 @@ - - - - - - -
    - - - - - -
    - - - - - - - - - - -
      - - - - diff --git a/php/add.php b/php/add.php deleted file mode 100644 index c602119d..00000000 --- a/php/add.php +++ /dev/null @@ -1,17 +0,0 @@ -= 0; $i--) { - if($list[$i] == "") - unset($list[$i]); -} - -echo json_encode(array_values($list)); \ No newline at end of file diff --git a/php/sub.php b/php/sub.php deleted file mode 100644 index 9c5862e9..00000000 --- a/php/sub.php +++ /dev/null @@ -1,17 +0,0 @@ - Date: Tue, 8 Mar 2016 19:09:38 +0000 Subject: [PATCH 04/35] Vastly improve checking for domain in gravity.list (think 30+ seconds down to 1) --- data.php | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/data.php b/data.php index 3802707f..4fac0ad9 100644 --- a/data.php +++ b/data.php @@ -123,21 +123,26 @@ $dns_queries = getDnsQueries($log); $fileName = '/etc/pihole/gravity.list'; - $file = file_get_contents($fileName); - + //Turn gravity.list into an array + $lines = explode("\n", file_get_contents($fileName)); + + //Create a new array and set domain name as index instead of value, with value as 1 + foreach(array_values($lines) as $v){ + $new_lines[trim(strstr($v, ' '))] = 1; + } + foreach ($dns_queries as $query) { $time = date_create(substr($query, 0, 16)); $exploded = explode(" ", trim($query)); - - $searchString = " {$exploded[6]}\n"; - - if (strpos($file,$searchString)) { - $extra="Pi-holed"; - } - else { - $extra="OK"; - }; + //Is index of the domain name set? + if (isset($new_lines[$exploded[6]])){ + $extra = "Pi-holed"; + } + else + { + $extra = "OK"; + } array_push($allQueries['data'], array( $time->format('Y-m-d\TH:i:s'), substr($exploded[5], 6, -1), From b37ed3fa514e22adc9d4c66c0eaa59640514811f Mon Sep 17 00:00:00 2001 From: Mcat12 Date: Wed, 16 Mar 2016 20:35:37 -0400 Subject: [PATCH 05/35] Actually fixed query log this time Maybe --- data.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/data.php b/data.php index bafb62cc..8c3ee81a 100644 --- a/data.php +++ b/data.php @@ -124,13 +124,13 @@ foreach ($dns_queries as $query) { $time = date_create(substr($query, 0, 16)); - + $exploded = explode(" ", trim($query)); array_push($allQueries['data'], array( $time->format('Y-m-d\TH:i:s'), - substr($exploded[5], 6, -1), - $exploded[6], - $exploded[8], + substr($exploded[count($exploded)-4], 6, -1), + $exploded[count($exploded)-3], + $exploded[count($exploded)-1], )); } From 5394118fb6fa16df37a68169439c0b3a5b098683 Mon Sep 17 00:00:00 2001 From: Mcat12 Date: Thu, 17 Mar 2016 20:37:18 -0400 Subject: [PATCH 06/35] Fixed status indicator Was still using old indexing --- data.php | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/data.php b/data.php index d24befd7..4084ff01 100644 --- a/data.php +++ b/data.php @@ -121,29 +121,28 @@ $allQueries = array("data" => array()); $log = readInLog(); $dns_queries = getDnsQueries($log); - + $fileName = '/etc/pihole/gravity.list'; //Turn gravity.list into an array $lines = explode("\n", file_get_contents($fileName)); - + //Create a new array and set domain name as index instead of value, with value as 1 foreach(array_values($lines) as $v){ $new_lines[trim(strstr($v, ' '))] = 1; } - + foreach ($dns_queries as $query) { $time = date_create(substr($query, 0, 16)); - $exploded = explode(" ", trim($query)); - + //Is index of the domain name set? - if (isset($new_lines[$exploded[6]])){ + if (isset($new_lines[$exploded[count($exploded)-3]])){ $extra = "Pi-holed"; } else { $extra = "OK"; - } + } array_push($allQueries['data'], array( $time->format('Y-m-d\TH:i:s'), substr($exploded[count($exploded)-4], 6, -1), @@ -152,7 +151,6 @@ $extra, )); } - return $allQueries; } From e4727433793574574caf7bd913574111f3da2eb6 Mon Sep 17 00:00:00 2001 From: Mcat12 Date: Mon, 28 Mar 2016 22:49:23 -0400 Subject: [PATCH 07/35] fix template team link --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 80203764..047c8b05 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -8,4 +8,4 @@ Changes proposed in this pull request: - -@pihole/dashboard +@pi-hole/dashboard From ba10330960a91c7da6b29ef3201884d1a55d9b1b Mon Sep 17 00:00:00 2001 From: Promofaux Date: Thu, 31 Mar 2016 23:26:19 +0100 Subject: [PATCH 08/35] PHP no longer falls over when reading in a large number of domains from the blocklist --- data.php | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/data.php b/data.php index 4fac0ad9..66d81594 100644 --- a/data.php +++ b/data.php @@ -1,14 +1,12 @@ - 1 ? $domains : - file("/etc/pihole/gravity.list"); + //returns count of domains in blocklist. + $file="/etc/pihole/gravity.list"; + $linecount = 0; + $handle = fopen($file, "r"); + while(!feof($handle)){ + $line = fgets($handle); + $linecount++; + } + + fclose($handle); + + return $linecount; + } function readInLog() { global $log; From 096bc06d65783c6230d596987744a4e49dc7b2a9 Mon Sep 17 00:00:00 2001 From: Justin Theberge Date: Tue, 5 Apr 2016 08:59:03 -0400 Subject: [PATCH 09/35] Fix for high CPU usage caused by "PHP Warning" flooding the journal. PHP Warning: fgets() expects parameter 1 to be resource, boolean was given --- data.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/data.php b/data.php index c1c24440..0b8d2bbb 100644 --- a/data.php +++ b/data.php @@ -156,11 +156,12 @@ $file="/etc/pihole/gravity.list"; $linecount = 0; $handle = fopen($file, "r"); - while(!feof($handle)){ + if(gettype($handle) == "resource") { + while(!feof($handle)){ $line = fgets($handle); $linecount++; + } } - fclose($handle); return $linecount; From 63539fa16a31f790de4f7055340e0ee89f4f249f Mon Sep 17 00:00:00 2001 From: Justin Theberge Date: Wed, 6 Apr 2016 09:48:50 -0400 Subject: [PATCH 10/35] fix linecount --- data.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/data.php b/data.php index 0b8d2bbb..f0dc7dac 100644 --- a/data.php +++ b/data.php @@ -156,12 +156,9 @@ $file="/etc/pihole/gravity.list"; $linecount = 0; $handle = fopen($file, "r"); - if(gettype($handle) == "resource") { - while(!feof($handle)){ - $line = fgets($handle); - $linecount++; - } - } + while ($chunk = fread($handle, 1024000)) { + $linecount += substr_count($chunk, "\n"); + } fclose($handle); return $linecount; From b540ace9879ab47e91ce93ab4181b7f6e5f59ff5 Mon Sep 17 00:00:00 2001 From: Justin Theberge Date: Wed, 6 Apr 2016 10:19:07 -0400 Subject: [PATCH 11/35] relevant names --- data.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/data.php b/data.php index f0dc7dac..3c051dd0 100644 --- a/data.php +++ b/data.php @@ -153,15 +153,15 @@ /******** Private Members ********/ function readInBlockList() { //returns count of domains in blocklist. - $file="/etc/pihole/gravity.list"; - $linecount = 0; - $handle = fopen($file, "r"); - while ($chunk = fread($handle, 1024000)) { - $linecount += substr_count($chunk, "\n"); + $gravity="/etc/pihole/gravity.list"; + $swallowed = 0; + $NGC4889 = fopen($gravity, "r"); + while ($stars = fread($NGC4889, 1024000)) { + $swallowed += substr_count($stars, "\n"); } - fclose($handle); + fclose($NGC4889); - return $linecount; + return $swallowed; } function readInLog() { From e7829ab127139788eeda16e881c0ad25be9223c5 Mon Sep 17 00:00:00 2001 From: 7h3ju57 Date: Thu, 7 Apr 2016 10:59:35 -0400 Subject: [PATCH 12/35] actually get pihole status from dnsmasq --- header.html | 9 ++++++++- img/pi-offline.png | Bin 0 -> 13177 bytes img/pi-online.png | Bin 0 -> 14385 bytes 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 img/pi-offline.png create mode 100644 img/pi-online.png diff --git a/header.html b/header.html index 49371f74..09d4ed8d 100644 --- a/header.html +++ b/header.html @@ -104,7 +104,14 @@

      Status

      -
      Nominal + = "0") { + echo 'Status Nominal'; + } else { + echo 'Status Offline'; + } + ?>
      diff --git a/img/pi-offline.png b/img/pi-offline.png new file mode 100644 index 0000000000000000000000000000000000000000..3cc0b318d60ea38e71ddadd3432e3103a8e6c0e7 GIT binary patch literal 13177 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 literal 0 HcmV?d00001 diff --git a/img/pi-online.png b/img/pi-online.png new file mode 100644 index 0000000000000000000000000000000000000000..b54731f85e2dcec061aa4940972f9733a5cc9e1c GIT binary patch literal 14385 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 rc~eu Date: Thu, 7 Apr 2016 22:47:03 -0400 Subject: [PATCH 13/35] fix an oops --- header.html | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/header.html b/header.html index 09d4ed8d..ffe39d72 100644 --- a/header.html +++ b/header.html @@ -104,14 +104,14 @@ From 4ae7f83ed42b9b205b7017f9e8cdea3ae35c94f7 Mon Sep 17 00:00:00 2001 From: Justin Theberge Date: Fri, 8 Apr 2016 19:37:56 -0400 Subject: [PATCH 14/35] replace icon with font awesome circle change to "Nominal" to "Active" fixed some indentation --- header.html | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/header.html b/header.html index ffe39d72..189a7c81 100644 --- a/header.html +++ b/header.html @@ -105,12 +105,12 @@

      Status

      "0") { - echo 'Status Nominal'; - } else { - echo 'Status Offline'; - } + $pistatus = exec('pgrep dnsmasq | wc -l'); + if ($pistatus > "0") { + echo ' Active'; + } else { + echo ' Offline'; + } ?>
      From f0c8d759f61ebd699ca7ad4008f3dcc8c25e41bf Mon Sep 17 00:00:00 2001 From: Justin Theberge Date: Fri, 8 Apr 2016 19:52:10 -0400 Subject: [PATCH 15/35] removed unused icons --- img/pi-offline.png | Bin 13177 -> 0 bytes img/pi-online.png | Bin 14385 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 img/pi-offline.png delete mode 100644 img/pi-online.png diff --git a/img/pi-offline.png b/img/pi-offline.png deleted file mode 100644 index 3cc0b318d60ea38e71ddadd3432e3103a8e6c0e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13177 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 diff --git a/img/pi-online.png b/img/pi-online.png deleted file mode 100644 index b54731f85e2dcec061aa4940972f9733a5cc9e1c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14385 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 rc~eu Date: Fri, 15 Apr 2016 19:12:50 +0100 Subject: [PATCH 16/35] Rename function to make more sense. --- data.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data.php b/data.php index 3c051dd0..2e97306d 100644 --- a/data.php +++ b/data.php @@ -6,7 +6,7 @@ function getSummaryData() { global $ipv6; $log = readInLog(); - $domains_being_blocked = readInBlockList() / ($ipv6 ? 2 : 1); + $domains_being_blocked = gravityCount() / ($ipv6 ? 2 : 1); $dns_queries_today = count(getDnsQueries($log)); @@ -151,7 +151,7 @@ } /******** Private Members ********/ - function readInBlockList() { + function gravityCount() { //returns count of domains in blocklist. $gravity="/etc/pihole/gravity.list"; $swallowed = 0; From 1028d164dc71efc8d82d7b2ee99844194958c70a Mon Sep 17 00:00:00 2001 From: Promofaux Date: Fri, 15 Apr 2016 20:40:32 +0100 Subject: [PATCH 17/35] revamp the getAllQueries function. The filter now includes the 'forwarded' and '/etc/pihole/gravity.list' lines. Super Zoomy! --- data.php | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/data.php b/data.php index 2e97306d..9784f107 100644 --- a/data.php +++ b/data.php @@ -118,34 +118,34 @@ $log = readInLog(); $dns_queries = getDnsQueries($log); - $fileName = '/etc/pihole/gravity.list'; - //Turn gravity.list into an array - $lines = explode("\n", file_get_contents($fileName)); - - //Create a new array and set domain name as index instead of value, with value as 1 - foreach(array_values($lines) as $v){ - $new_lines[trim(strstr($v, ' '))] = 1; - } - foreach ($dns_queries as $query) { $time = date_create(substr($query, 0, 16)); $exploded = explode(" ", trim($query)); - - //Is index of the domain name set? - if (isset($new_lines[$exploded[count($exploded)-3]])){ - $extra = "Pi-holed"; + + if (substr($exploded[count($exploded)-4], 0, 5) == "query"){ + $type = substr($exploded[count($exploded)-4], 6, -1); + $domain = $exploded[count($exploded)-3]; + $client = $exploded[count($exploded)-1]; } - else - { - $extra = "OK"; + elseif (substr($exploded[count($exploded)-4], 0, 9) == "forwarded" ){ + $status="OK"; } - array_push($allQueries['data'], array( + elseif (substr($exploded[count($exploded)-4], 0, 5) == "/etc/" ){ + $status="Pi-holed"; + } + + if ( $status != ""){ + array_push($allQueries['data'], array( $time->format('Y-m-d\TH:i:s'), - substr($exploded[count($exploded)-4], 6, -1), - $exploded[count($exploded)-3], - $exploded[count($exploded)-1], - $extra, - )); + $type, + $domain, + $client, + $status, + )); + $status = ""; + } + + } return $allQueries; } @@ -247,7 +247,7 @@ } function findQueries($var) { - return strpos($var, ": query[") !== false; + return strpos($var, ": query[") || strpos($var, "gravity.list") || strpos($var, ": forwarded")!== false; } function findAds($var) { From 52281939ebd38849a36e4cf75e2cd7db0d4b5bac Mon Sep 17 00:00:00 2001 From: Promofaux Date: Fri, 15 Apr 2016 21:04:08 +0100 Subject: [PATCH 18/35] Create seperate filter for get all queries, as it was messing up the main page. --- data.php | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/data.php b/data.php index 9784f107..77001434 100644 --- a/data.php +++ b/data.php @@ -116,21 +116,22 @@ function getAllQueries() { $allQueries = array("data" => array()); $log = readInLog(); - $dns_queries = getDnsQueries($log); + $dns_queries = getDnsQueriesAll($log); foreach ($dns_queries as $query) { $time = date_create(substr($query, 0, 16)); $exploded = explode(" ", trim($query)); + $tmp = $exploded[count($exploded)-4]; - if (substr($exploded[count($exploded)-4], 0, 5) == "query"){ + if (substr($tmp, 0, 5) == "query"){ $type = substr($exploded[count($exploded)-4], 6, -1); $domain = $exploded[count($exploded)-3]; $client = $exploded[count($exploded)-1]; } - elseif (substr($exploded[count($exploded)-4], 0, 9) == "forwarded" ){ + elseif (substr($tmp, 0, 9) == "forwarded" ){ $status="OK"; } - elseif (substr($exploded[count($exploded)-4], 0, 5) == "/etc/" ){ + elseif (substr($tmp, strlen($tmp) - 12, 12) == "gravity.list" ){ $status="Pi-holed"; } @@ -172,6 +173,9 @@ function getDnsQueries($log) { return array_filter($log, "findQueries"); } + function getDnsQueriesAll($log) { + return array_filter($log, "findQueriesAll"); + } function getBlockedQueries($log) { return array_filter($log, "findAds"); } @@ -246,8 +250,12 @@ return array_reverse($recent); } + function findQueriesAll($var) { + return strpos($var, ": query[") || strpos($var, "gravity.list") || strpos($var, ": forwarded") !== false; + } + function findQueries($var) { - return strpos($var, ": query[") || strpos($var, "gravity.list") || strpos($var, ": forwarded")!== false; + return strpos($var, ": query[") !== false; } function findAds($var) { From 8bb172aae633f4bcc3b67d3a1e7396c46a1ec201 Mon Sep 17 00:00:00 2001 From: Promofaux Date: Fri, 15 Apr 2016 21:17:18 +0100 Subject: [PATCH 19/35] Simple turn off animations for now. Toggling to come later. --- index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.php b/index.php index 32b7ce36..cf159bf0 100644 --- a/index.php +++ b/index.php @@ -243,7 +243,7 @@ return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Windows()); } }; - var animate = !isMobile.any(); + var animate = false; var ctx = document.getElementById("queryOverTimeChart").getContext("2d"); timeLineChart = new Chart(ctx).Line(chartData, { From 77de621d254f68a7cf4a22a44bed82b065ab71a9 Mon Sep 17 00:00:00 2001 From: Promofaux Date: Fri, 15 Apr 2016 21:27:32 +0100 Subject: [PATCH 20/35] possible fix lighttpd for error where $status was undefined --- data.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data.php b/data.php index 77001434..d0b5d228 100644 --- a/data.php +++ b/data.php @@ -127,6 +127,7 @@ $type = substr($exploded[count($exploded)-4], 6, -1); $domain = $exploded[count($exploded)-3]; $client = $exploded[count($exploded)-1]; + $status = ""; } elseif (substr($tmp, 0, 9) == "forwarded" ){ $status="OK"; @@ -143,7 +144,6 @@ $client, $status, )); - $status = ""; } From ad2715e23f423af8b13ed641f319dec35975a8b4 Mon Sep 17 00:00:00 2001 From: Promofaux Date: Fri, 15 Apr 2016 23:40:40 +0100 Subject: [PATCH 21/35] Increase complexity of FindAds filter. Removes 'bad name' and host file reload lines from the log whilst parsing --- data.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/data.php b/data.php index d0b5d228..314d4b72 100644 --- a/data.php +++ b/data.php @@ -259,7 +259,11 @@ } function findAds($var) { - return strpos($var, "gravity.list") !== false; + $exploded = explode(" ", $var); + $tmp = $exploded[count($exploded)-4]; + $tmp2 = $exploded[count($exploded)-5]; + //filter out bad names and host file reloads: + return (substr($tmp, strlen($tmp) - 12, 12) == "gravity.list" && $tmp2 != "read") ; } function findForwards($var) { From 02f6517b55c59b76f928ed52c476109e2d4c2c4a Mon Sep 17 00:00:00 2001 From: Promofaux Date: Sat, 16 Apr 2016 00:55:19 +0100 Subject: [PATCH 22/35] Add ability to check for local hostnames --- data.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/data.php b/data.php index 314d4b72..58b8df0a 100644 --- a/data.php +++ b/data.php @@ -1,7 +1,8 @@ Date: Sat, 16 Apr 2016 00:56:30 +0100 Subject: [PATCH 23/35] Add hostname check to Top Clients graph and Query Log page --- data.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data.php b/data.php index 58b8df0a..cc1df896 100644 --- a/data.php +++ b/data.php @@ -103,7 +103,7 @@ $sources = array(); foreach($dns_queries as $query) { $exploded = explode(" ", $query); - $ip = trim($exploded[count($exploded)-1]); + $ip = hasHostName(trim($exploded[count($exploded)-1])); if (isset($sources[$ip])) { $sources[$ip]++; } @@ -142,7 +142,7 @@ $time->format('Y-m-d\TH:i:s'), $type, $domain, - $client, + hasHostName($client), $status, )); } From 4499e2f3b92e10cb63bfa497d989227673d087b6 Mon Sep 17 00:00:00 2001 From: Promofaux Date: Sat, 16 Apr 2016 01:07:33 +0100 Subject: [PATCH 24/35] Remove erroneous space after hostname --- data.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/data.php b/data.php index cc1df896..a11c9664 100644 --- a/data.php +++ b/data.php @@ -276,6 +276,8 @@ foreach ($hosts as $host){ $x = explode("\t", $host); if ( $var == $x[0] ){ + //For some reason there is an extra space... + $x[1] = substr($x[1],0,strlen($x[1]) -1); $var = $var . " ($x[1])"; } } From d3780def4e42d539e5af23048fd0f38977997216 Mon Sep 17 00:00:00 2001 From: Promofaux Date: Sat, 16 Apr 2016 01:56:03 +0100 Subject: [PATCH 25/35] Change TopClients to Doughnut chart instead of Radar chart, due to bug I cannot for the life of me work out (missing one client's value) --- index.php | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/index.php b/index.php index cf159bf0..7de860e7 100644 --- a/index.php +++ b/index.php @@ -267,21 +267,15 @@ legendTemplate : "
        -legend\"><% for (var i=0; i
      • \"><%if(segments[i].label){%><%=segments[i].label%><%}%>
      • <%}%>
      ", animation : animate } - ); - - var radarChartData = { - labels: [], - datasets: [ - { - label: "Top Clients", - fillColor: "rgba(220,220,220,0.5)", - strokeColor: "rgba(0, 166, 90,.8)", - data: [] - } - ] - }; + ); + ctx = document.getElementById("topClientsChart").getContext("2d"); - topClientsChart = new Chart(ctx).Radar(radarChartData, {animation : animate}); + topClientsChart = new Chart(ctx).Doughnut([], + { + legendTemplate : "
        -legend\"><% for (var i=0; i
      • \"><%if(segments[i].label){%><%=segments[i].label%><%}%>
      • <%}%>
      ", + animation : animate + } + ); }); // Functions to oupdate data in page @@ -329,9 +323,14 @@ function updateTopClientsChart() { $.getJSON("api.php?getQuerySources", function(data) { - console.log(data); + var colors = []; + $.each($.AdminLTE.options.colors, function(key, value) { colors.push(value); }); $.each(data, function(key, value) { - topClientsChart.addData([value], key); + topClientsChart.addData({ + value: value, + color: colors.shift(), + label: key + }); }); $('#top-clients .overlay').remove(); From fa8cec8fa7eace14cb2b31f8b7a077fb93a5dfcd Mon Sep 17 00:00:00 2001 From: Promofaux Date: Sat, 16 Apr 2016 02:50:15 +0100 Subject: [PATCH 26/35] add extra check to getAllQueries so that reads of gravity.list are not counted as pi-holed --- data.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data.php b/data.php index 314d4b72..17acdd5b 100644 --- a/data.php +++ b/data.php @@ -132,7 +132,7 @@ elseif (substr($tmp, 0, 9) == "forwarded" ){ $status="OK"; } - elseif (substr($tmp, strlen($tmp) - 12, 12) == "gravity.list" ){ + elseif (substr($tmp, strlen($tmp) - 12, 12) == "gravity.list" && $exploded[count($exploded)-5] != "read"){ $status="Pi-holed"; } From f45d42ca63c1b22bc6c001dbcb044451cde1ab56 Mon Sep 17 00:00:00 2001 From: Promofaux Date: Sat, 16 Apr 2016 14:21:34 +0100 Subject: [PATCH 27/35] Changes to data.php to allow showing Top 10 clients in table --- data.php | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/data.php b/data.php index 64e85da7..7de8812d 100644 --- a/data.php +++ b/data.php @@ -111,7 +111,11 @@ $sources[$ip] = 1; } } - return $sources; + arsort($sources); + array_slice($sources, 0, 10); + return Array( + 'top_sources' => $sources + ); } function getAllQueries() { @@ -283,19 +287,4 @@ } return $var; } - -/* - $data = array( - 'domains_being_blocked' => $domains_being_blocked, - 'dns_queries_today' => $dns_queries_today, - 'ads_blocked_today' => $ads_blocked_today, - 'ads_percentage_today' => $ads_percentage_today, - 'top_queries' => $topQueries, - 'top_ads' => $topAds, - 'domains_over_time' => $domains_over_time, - 'ads_over_time' => $ads_over_time, - 'recent_queries' => getRecent($dns_queries, 20), - ); - - */ -?> +?> \ No newline at end of file From ab93f9e4b6457be3e0cf94babf9717411c259248 Mon Sep 17 00:00:00 2001 From: Promofaux Date: Sat, 16 Apr 2016 14:23:59 +0100 Subject: [PATCH 28/35] Remove Radar chart for top clients. Add table similar to top ads and top domains --- index.php | 80 ++++++++++++++++++++++++++----------------------------- 1 file changed, 38 insertions(+), 42 deletions(-) diff --git a/index.php b/index.php index 7de860e7..0ee052b7 100644 --- a/index.php +++ b/index.php @@ -86,7 +86,7 @@
      -
      +

      Query Types

      @@ -102,23 +102,7 @@
      -
      -
      -
      -

      Top Clients

      -
      -
      -
      - -
      -
      -
      - -
      - -
      -
      -
      +

      Forward Destinations

      @@ -137,7 +121,7 @@
      -
      +

      Top Domains

      @@ -160,7 +144,7 @@
      -
      +

      Top Advertisers

      @@ -185,6 +169,29 @@
      +
      +
      +
      +

      Top Clients

      +
      + +
      + + + + + + +
      ClientRequestsFrequency
      +
      +
      + +
      + +
      + +
      +
      @@ -267,15 +274,7 @@ legendTemplate : "
        -legend\"><% for (var i=0; i
      • \"><%if(segments[i].label){%><%=segments[i].label%><%}%>
      • <%}%>
      ", animation : animate } - ); - - ctx = document.getElementById("topClientsChart").getContext("2d"); - topClientsChart = new Chart(ctx).Doughnut([], - { - legendTemplate : "
        -legend\"><% for (var i=0; i
      • \"><%if(segments[i].label){%><%=segments[i].label%><%}%>
      • <%}%>
      ", - animation : animate - } - ); + ); }); // Functions to oupdate data in page @@ -322,19 +321,15 @@ } function updateTopClientsChart() { - $.getJSON("api.php?getQuerySources", function(data) { - var colors = []; - $.each($.AdminLTE.options.colors, function(key, value) { colors.push(value); }); - $.each(data, function(key, value) { - topClientsChart.addData({ - value: value, - color: colors.shift(), - label: key - }); - }); - - $('#top-clients .overlay').remove(); - //$('#queries-over-time').append(timeLineChart.generateLegend()); + $.getJSON("api.php?summaryRaw&getQuerySources", function(data) { + var clienttable = $('#client-frequency').find('tbody:last'); + for (domain in data.top_sources) { + clienttable.append(' ' + domain + + ' ' + data.top_sources[domain] + '
      '); + } + + $('#client-frequency .overlay').remove(); }); } @@ -374,6 +369,7 @@ $.getJSON("api.php?summaryRaw&topItems", function(data) { var domaintable = $('#domain-frequency').find('tbody:last'); var adtable = $('#ad-frequency').find('tbody:last'); + for (domain in data.top_queries) { domaintable.append(' ' + domain + ' ' + data.top_queries[domain] + '
      Date: Mon, 18 Apr 2016 22:46:49 +0100 Subject: [PATCH 30/35] actually limit list of sources to 10. --- data.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data.php b/data.php index 1aca3a42..ebfeeed7 100644 --- a/data.php +++ b/data.php @@ -112,7 +112,7 @@ } } arsort($sources); - array_slice($sources, 0, 10); + $sources = array_slice($sources, 0, 10); return Array( 'top_sources' => $sources ); From 87ddd4cbc7e3f08575e11a51e79614e38fdc90d0 Mon Sep 17 00:00:00 2001 From: Rory M Date: Fri, 22 Apr 2016 12:34:41 +0100 Subject: [PATCH 31/35] Fix for XSS bug Pointed at the correct branch this time. --- api.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api.php b/api.php index ea74ca5f..b77d89a6 100644 --- a/api.php +++ b/api.php @@ -48,5 +48,5 @@ } - echo json_encode($data); + echo htmlspecialchars(json_encode($data)); ?> From 66e0c0f66e02ca01e338fcd0b20e4ce132cbf682 Mon Sep 17 00:00:00 2001 From: Rory M Date: Fri, 22 Apr 2016 13:12:10 +0100 Subject: [PATCH 32/35] Fixed incorrect ordering of sanitisers `json_encode` needs to call the result of `htmlspecialchars`, not visa versa! --- api.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api.php b/api.php index b77d89a6..e9bdf0f7 100644 --- a/api.php +++ b/api.php @@ -48,5 +48,5 @@ } - echo htmlspecialchars(json_encode($data)); + echo json_encode(htmlspecialchars($data)); ?> From b91b7cacb019f0a923ddcb9a012b81dac3abf1a4 Mon Sep 17 00:00:00 2001 From: Rory M Date: Fri, 22 Apr 2016 13:21:53 +0100 Subject: [PATCH 33/35] Final fix for XSS patch `htmlspecialchars` does not work on arrays. This is why testing is important :^) --- api.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api.php b/api.php index e9bdf0f7..f8a590cf 100644 --- a/api.php +++ b/api.php @@ -47,6 +47,6 @@ $data = array_merge($data, getAllQueries()); } - - echo json_encode(htmlspecialchars($data)); + foreach ($data as &$d) $d = htmlspecialchars($d); + echo json_encode($data); ?> From 26d54cfa9bdc15b8718fee586602a861307486de Mon Sep 17 00:00:00 2001 From: Rory M Date: Fri, 22 Apr 2016 14:27:21 +0100 Subject: [PATCH 34/35] Fix for XSS bug I actually tested this one! it works. My apologies for the previous, non-working commits-- I had to refresh my knowledge of PHP. --- api.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/api.php b/api.php index f8a590cf..85b282ea 100644 --- a/api.php +++ b/api.php @@ -47,6 +47,18 @@ $data = array_merge($data, getAllQueries()); } - foreach ($data as &$d) $d = htmlspecialchars($d); + function filterArray(&$a) { + $sanArray = array(); + foreach ($a as $k=>$v) { + if (is_array($v)) { + $sanArray[htmlspecialchars($k)] = filterArray($v); + } else { + $sanArray[htmlspecialchars($k)] = htmlspecialchars($v); + } + } + return $sanArray; + } + + $data = filterArray($data); echo json_encode($data); ?> From e79dc2bb0ed8e5551b46e39becebb6b90f34c4e5 Mon Sep 17 00:00:00 2001 From: Promofaux Date: Thu, 28 Apr 2016 20:22:27 +0100 Subject: [PATCH 35/35] Split $host at any whitespace, not just tab. addresses : https://github.com/pi-hole/pi-hole/issues/484 --- data.php | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/data.php b/data.php index ebfeeed7..1082a254 100644 --- a/data.php +++ b/data.php @@ -1,11 +1,11 @@ -format('Y-m-d\TH:i:s'), @@ -148,10 +148,10 @@ $domain, hasHostName($client), $status, - )); + )); } - - + + } return $allQueries; } @@ -164,11 +164,11 @@ $NGC4889 = fopen($gravity, "r"); while ($stars = fread($NGC4889, 1024000)) { $swallowed += substr_count($stars, "\n"); - } + } fclose($NGC4889); - + return $swallowed; - + } function readInLog() { global $log; @@ -226,7 +226,7 @@ function alignTimeArrays(&$times1, &$times2) { $max = max(array(max(array_keys($times1)), max(array_keys($times2)))); $min = min(array(min(array_keys($times1)), min(array_keys($times2)))); - + for ($i = $min; $i <= $max; $i++) { if (!isset($times2[$i])) { $times2[$i] = 0; @@ -258,7 +258,7 @@ function findQueriesAll($var) { return strpos($var, ": query[") || strpos($var, "gravity.list") || strpos($var, ": forwarded") !== false; } - + function findQueries($var) { return strpos($var, ": query[") !== false; } @@ -274,15 +274,15 @@ function findForwards($var) { return strpos($var, ": forwarded") !== false; } - + function hasHostName($var){ global $hosts; foreach ($hosts as $host){ - $x = explode("\t", $host); + $x = preg_split('/\s+/', $host); if ( $var == $x[0] ){ $var = $x[1] . "($var)"; } } return $var; } -?> \ No newline at end of file +?>

      Status

      - = "0") { - echo '
      Status Nominal'; - } else { - echo 'Status Offline'; - } - ?> + "0") { + echo 'Status Nominal'; + } else { + echo 'Status Offline'; + } + ?>