From b08f87e9e5970343c72098bf02d8f3d0dbe2c7e3 Mon Sep 17 00:00:00 2001 From: sandb Date: Mon, 22 Feb 2010 01:38:28 +0100 Subject: [PATCH] sqlite instead of file system to store macs --- .htaccess | 6 ++ config.php | 7 ++- index.xhtml => index.html | 0 lib/db.php | 11 ++++ lib/macs.php | 26 +++++++++ lib/util.php | 6 +- macs.php | 71 ++--------------------- scanner/pamela-scanner.sh | 119 +++++++++++++++++++++----------------- upload.php | 32 ++-------- 9 files changed, 130 insertions(+), 148 deletions(-) create mode 100644 .htaccess rename index.xhtml => index.html (100%) create mode 100644 lib/db.php create mode 100644 lib/macs.php diff --git a/.htaccess b/.htaccess new file mode 100644 index 0000000..77a26fa --- /dev/null +++ b/.htaccess @@ -0,0 +1,6 @@ +Addtype application/octet-stream .ttf .otf +AddType application/vnd.ms-fontobject .eot + +RewriteRule (.*).php $1 +RewriteRule (.*).hmtl $1 + diff --git a/config.php b/config.php index 9e24e6d..1adcf89 100644 --- a/config.php +++ b/config.php @@ -1,6 +1,11 @@ strftime('%s','now') - ".MACFILE_TTL); + if (!$q) return $results; + while(sqlite_has_more($q)) { + $row = sqlite_fetch_array($q, SQLITE_ASSOC); + $results[] = $row['mac']; + } + return $results; +} + +function macs_add($mac) { + $db = get_db(); + $mac = sqlite_escape_string($mac); + $q = sqlite_exec($db, "insert into macs values (\"$mac\", strftime('%s','now'))"); + if (!$q) return $results; +} + +function macs_purge() { + $db = get_db(); + return sqlite_exec($db, "delete from macs where committime <= strftime('%s','now') - ".MACFILE_TTL); +} diff --git a/lib/util.php b/lib/util.php index e40da10..d320359 100644 --- a/lib/util.php +++ b/lib/util.php @@ -95,4 +95,8 @@ function script($source) { + +function echoln($str) { + echo("$str\n"); +} + diff --git a/macs.php b/macs.php index 5586166..91f50a5 100644 --- a/macs.php +++ b/macs.php @@ -24,11 +24,8 @@ header("Cache-Control: no-cache"); header("Pragma: no-cache"); require_once("config.php"); -require_once("lib/util.php"); require_once("lib/trans.php"); - -// [ "00:01:e8:04:99:be", "00:05:4e:40:1e:97", "00:0c:f1:16:10:ba", "00:0c:f1:1d:dc:70", "00:0e:35:96:c7:ff", "00:11:85:6a:1f:ec", ] - +require_once("lib/macs.php"); function translator($mac) { global $mac_translation_table; @@ -37,65 +34,7 @@ function translator($mac) { return $mac; } - -class Macs { - - private $macs; - - function __construct() { - $this->macs = array(); - } - - private function readFile($filename) { - $mcs = file_get_contents($filename); - $this->macs = array_merge($this->macs, explode(',', $mcs)); - } - - private function readFiles($directory) { - $macFiles = scandir($directory); - foreach ($macFiles as $macFile) { - if (preg_match("/.+\.macs$/", $macFile) != 1) - continue; - - $filename = "$directory/$macFile"; - - // data is too old, remove - if (filemtime($filename) + MACFILE_TTL < time()) { - unlink($filename); - continue; - } - - $this->readFile($filename); - } - } - - private function cleanUp() { - $this->macs = array_unique($this->macs); - } - - private function translate() { - $this->macs = array_map("translator", $this->macs); - } - - private function createJson() { - if (count($this->macs) < 1) { - echo '[]'; - return; - } - - echo '["'; - echo implode('", "', $this->macs); - echo '"]'; - } - - public function run() { - $this->readFiles(OUTPUT_SERVER_DIRECTORY); - $this->cleanUp(); - $this->translate(); - $this->createJson(); - } - -} - -$macs = new Macs(); -$macs->run(); +$macs = macs_get(); +$macs = array_map("translator", $macs); +echo '["'.implode('", "', $macs).'"]'; +macs_purge(); diff --git a/scanner/pamela-scanner.sh b/scanner/pamela-scanner.sh index 7b4e7d5..d26e674 100755 --- a/scanner/pamela-scanner.sh +++ b/scanner/pamela-scanner.sh @@ -34,8 +34,7 @@ USER='' PASSWORD='' function usage { - -echo "Usage: pamela-scanner [OPTIONS] + echo "Usage: pamela-scanner [OPTIONS] -i INTERFACE Interface to arp-scan. Defaults to [$IF]. -o URL The url of the pamela upload script (including /upload.php). @@ -51,71 +50,85 @@ webserver where you get a visual representation of the mac addresses present. Multiple people on multiple lans can run pamela together against the same server, where all results are agregated. In short, pamela gives you an overview of how big the shared network is." +} -exit 1 +function check_if_root { + if [ "$(id -ru)" != "0" ] + then + echo "Must be root to run pamela-scanner" + exit 1 + fi +} +function check_if_arpscan_installed { + if [ -z "$(which arp-scan)" ] + then + echo "ENOARPSCAN: Could not find arp-scan, please install it" + fi } function register { + check_if_root + check_if_arpscan_installed echo "Registering pamela in cron: $PAM_CRON" echo "*/2 * * * * root [ -x \"$PAM_SCRIPT\" ] && \"$PAM_SCRIPT\" -i \"$IF\" -o \"$OUT\" -u \"$USER\" -p \"$PASSWORD\" >> \"$PAM_LOG\"" > "$PAM_CRON" - exit 0 } function unregister { + check_if_root echo "Unregistering pamela in cron: $PAM_CRON" rm "$PAM_CRON" - exit 0 } -TEMP=$(getopt -o 'hrqi:o:s:u:p:-n' "pamela arp scanner" -- "$@") -if [ $? != 0 ] ; then echo "Could not parse parameters..." >&2 ; exit 1 ; fi -eval set "$TEMP" -while true -do - shift; - [ -z "$1" ] && break; - case "$1" in - -i) IF="$2"; shift;; - -o) OUT="$2"; shift;; - -s) SLEEP="$2"; shift;; - -u) USER="$2"; shift;; - -p) PASSWORD="$2"; shift;; - -r) REGISTER='r';; - -q) unregister; break;; - -h|'-?') usage; break;; - *) echo "Unknown param: [$1]"; usage; exit 1; - esac -done +function parse_params { + TEMP=$(getopt -o 'hrqi:o:s:u:p:-n' "pamela arp scanner" -- "$@") + if [ $? != 0 ] ; then echo "Could not parse parameters..." >&2 ; exit 1 ; fi + eval set "$TEMP" + while true + do + shift; + [ -z "$1" ] && break; + case "$1" in + -i) IF="$2"; shift;; + -o) OUT="$2"; shift;; + -s) SLEEP="$2"; shift;; + -u) USER="$2"; shift;; + -p) PASSWORD="$2"; shift;; + -r) REGISTER='r';; + -q) unregister; exit 0;; + -h|'-?') usage; exit 1;; + *) echo "Unknown param: [$1]"; usage; exit 1;; + esac + done + # Register only after parsing all args + if [ -n "$REGISTER" ]; then + register + exit 0 + fi +} -#register only after parsing all args -[ -n "$REGISTER" ] && register +function scan_and_upload { + echo $(date)" scanning..." + NETMASK="$(ip -4 addr show "$IF" | egrep -o "brd [0-9\.]+" | egrep -o "[0-9\.]+")" + MACS="" + NUM_MACS=0 + for M in $(arp-scan -R -i 10 --interface "$IF" --localnet | awk '{ print $2 }' | grep :.*: | sort | uniq) + do + [ -n "$MACS" ] && MACS="$MACS,$M" || MACS="$M"; + let "NUM_MACS=NUM_MACS+1" + done + POST="sn=$NETMASK&macs=$MACS" + RESULT=$(wget "$OUT" -O - --quiet --post-data "$POST" --user "$USER" --password "$PASSWORD" || echo "wget error: $?") + if [ -n "$RESULT" ] + then + echo Error uploading results: + echo "$RESULT" + fi + echo $(date)" Uploaded $NUM_MACS mac addresses..." +} -if [ "$(id -ru)" != "0" ] -then - echo "Must be root to run pamela-scanner" - exit 1 -fi +parse_params $@ +check_if_root +check_if_arpscan_installed +scan_and_upload -if [ -z "$(which arp-scan)" ] -then - echo "ENOARPSCAN: Could not find arp-scan, please install it" -fi - -echo $(date)" scanning..." -NETMASK="$(ip -4 addr show "$IF" | egrep -o "brd [0-9\.]+" | egrep -o "[0-9\.]+")" -MACS="" -NUM_MACS=0 -for M in $(arp-scan -R -i 10 --interface "$IF" --localnet | awk '{ print $2 }' | grep :.*: | sort | uniq) -do - [ -n "$MACS" ] && MACS="$MACS,$M" || MACS="$M"; - let "NUM_MACS=NUM_MACS+1" -done -POST="sn=$NETMASK&macs=$MACS" -RESULT=$(wget "$OUT" -O - --quiet --post-data "$POST" --user "$USER" --password "$PASSWORD" || echo "wget error: $?") -if [ -n "$RESULT" ] -then - echo Error uploading results: - echo "$RESULT" -fi -echo $(date)" Uploaded $NUM_MACS mac addresses..." diff --git a/upload.php b/upload.php index 2502a0e..29dcaa7 100644 --- a/upload.php +++ b/upload.php @@ -19,48 +19,23 @@ */ header("Content-type: text/plain"); -require_once("config.php"); require_once("lib/util.php"); - -function echoln($str) { - echo("$str\n"); -} +require_once("lib/macs.php"); class Upload { - private $subnet; private $macs; function __construct() { - $this->subnet = getPost("sn"); $this->macs = getPost("macs"); } private function parseAndValidate() { - if ($this->subnet == NULL) { - echoln("Missing or bad sn param"); - return false; - } if ($this->macs == NULL) { echoln("Missing macs param"); return false; } - if (preg_match("/^(\d{1,3}\.){3}\d{1,3}$/", $this->subnet) != 1) { - echoln("subnet ($this->subnet) is not valid"); - return false; - } - - $snParts = explode('.', $this->subnet); - foreach($snParts as $part) { - $i = intvaldef($part, -1); - if (($i >= 0) && ($i <= 255)) - continue; - - echoln("subnet ($this->subnet) contains invalid parts ($part)"); - return false; - } - $mcs = explode(',', $this->macs); foreach($mcs as $mac) { if (preg_match("/^(([\dABCDEF]){2}:){5}([\dABCDEF]){2}$/i", $mac) == 1) @@ -72,7 +47,10 @@ class Upload { } private function writeMacs() { - file_put_contents(OUTPUT_SERVER_DIRECTORY."/$this->subnet.macs", $this->macs); + $mcs = explode(',', $this->macs); + foreach($mcs as $mac) { + macs_add($mac); + } } public function run() {