Compare commits

..

11 Commits

34 changed files with 460 additions and 172 deletions

2
.gitignore vendored
View File

@ -3,3 +3,5 @@ design
db
config.php
scanner/pamela.log
mac_log.csv
mac_log.csv.complete

4
README
View File

@ -1,3 +1,7 @@
HeatSync Labs / Cohoots Phoenix branch
https://github.com/zyphlar/pamela
-------
Hackerspace Brussels/Whitespace Ghent
presents
_ _ _

31
admin.php Executable file
View File

@ -0,0 +1,31 @@
<?php
if ($_POST) {
$text = preg_replace("/\s{2}/i","\n",$_POST['text']);
file_put_contents("mac_log.csv",$text);
header ("Location: ".$_SERVER['PHP_SELF']."?saved=true");
exit;
}
$text = htmlspecialchars(file_get_contents("mac_log.csv"));
if($_GET['saved'] == "true") {
$message = "Saved successfully.";
}
?><html>
<head>
<style type="text/css">
textarea { height: 600px; width: 400px; }
</style>
</head>
<body>
<span class="message">
<?php echo $message; ?>
</span>
<form method="POST">
<textarea name="text"><?php echo $text; ?></textarea>
<input type="submit" value="Save">
</form>
</body>
</html>

77
associate.php Executable file
View File

@ -0,0 +1,77 @@
<?php
$message = "";
if(isset($_POST['submit'])) {
$mac = csv_filter($_POST['macaddress']);
$name = csv_filter($_POST['name']);
if($mac != "" && $name != null) {
if(is_mac($mac)) {
file_put_contents("mac_log.csv","$mac,$name\n",FILE_APPEND);
$message = "Registered, thanks! It might take a few minutes for your name to show up.";
}
else {
$message = "The MAC address doesn't look right. MAC addresses look like this: 00:1a:2b:3c:4d:5e";
}
}
else {
$message = "Please enter a MAC address and name.";
}
}
function csv_filter($value) {
return preg_replace('/[^a-z0-9: {}]/i','',$value);
}
function is_mac($mac) {
if(preg_match('/^([0-9a-f]{2}([:-]|$)){6}$/i',$mac) > 0){
return true;}
else { return false; }
}
$arp_found = false;
function arp_lookup($ip) {
global $arp_found;
$arp = shell_exec("/usr/sbin/arp -a | grep $ip");
preg_match('/at ([0-9a-f]{2}[: ]){6}/i',$arp,$matches);
if(sizeof($matches) > 0) {
$mac = split(" ",$matches[0]);
$arp_found = true;
return $mac[1];
}
else {
$arp_found = false;
return "";
}
}
include('header-inc.php');
?>
<span class="message">
<?php echo $message; ?>
</span>
<div id="content">
<h2>Register Your Device</h2>
<div class="caption">
<form method="post" action="<?php echo htmlentities($_SERVER['PHP_SELF']); ?>">
<h3>Your computer or mobile device's MAC address can be found under your network info!</h3>
<table>
<tr><td><label for="name">Your Name:</label></td><td><input type="text" id="name" name="name" /></td></tr>
<tr><td><label for="macaddress">MAC Address:</label></td><td><input type="text" id="macaddress" name="macaddress" value="<?php echo arp_lookup($_SERVER['REMOTE_ADDR']); ?>" />
<span id="autodetect"><?php if($arp_found) { echo "(Autodetected your MAC from IP address ".$_SERVER['REMOTE_ADDR'].")"; } ?></span>
</td></tr>
</table>
<input type="submit" id="submit" name="submit" value="Register" />
</form>
</div>
</div>
</div>
</body>
</html>

39
header-inc.php Executable file
View File

@ -0,0 +1,39 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<?php if(isset($auto_reload)) { ?>
<script type="text/javascript">
function reload() {
window.location.reload()
}
function pageLoad() {
setInterval ( "reload()", 30000 );
}
</script>
<?php } ?>
<style type="text/css">
#autodetect { display: block; color: #666; }
.macaddr { color: #666; }
</style>
<link href="style.css" rel="stylesheet" type="text/css" />
<link href="http://fonts.googleapis.com/css?family=Lato:300,400,700,300italic,400italic,700italic" rel="stylesheet" type="text/css" />
</head>
<body <?php if(isset($auto_reload)){ ?>onLoad="pageLoad()"<?php } ?>>
<div id="header">
<div id="header_middle">
<img src="/static/images/logo.png" />
<div id="header_buttons">
<h2>Local Network</h2>
<p>See if there are people at the space!<br/>
If the feed is broken, please contact <a href="#">someone</a>.</p>
<p>Nobody here? Check the <a href="#">Website</a>.</p>
</div>
</div>
<div id="header_menu">
<a href="/">See Who's Here</a>
<a href="/associate.php">Register your device!</a>
</div>
</div>
<div id="content">

View File

@ -1,45 +1,38 @@
<?php
/*
Copyright 2010 Pieter Iserbyt
<?php
$auto_reload = true;
include('header-inc.php');
This file is part of Pamela.
Pamela is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
$result = http_parse_message(http_get("http://localhost/pamela/data.php"));
$result = preg_replace("/[\r|\n]/","",$result->body); // get rid of linebreaks
Pamela is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
$decode = json_decode($result);
$decode = preg_replace("/^([0-9a-f]{2}([:]|$)){6}$/i",'{$0}',$decode);
sort($decode,SORT_STRING | SORT_FLAG_CASE);
You should have received a copy of the GNU General Public License
along with Pamela. If not, see <http://www.gnu.org/licenses/>.
*/
$array = preg_grep("/^(?!\.)/",$decode);
require_once("config.php");
?><html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Pamela</title>
<script src="js/jquery-1.3.2.js" type="text/javascript"></script>
<script src="js/pamela-conf.php" type="text/javascript"></script>
<script src="js/pamela-buttons.js" type="text/javascript"></script>
<script src="js/pamela-nodes.js" type="text/javascript"></script>
<script src="js/pamela-matrices.js" type="text/javascript"></script>
<script src="js/pamela.js" type="text/javascript"></script>
<style type="text/css">
* {
margin:0;
padding:0;
}
body {
background-color: <?php echo PAM_BGCOLOR; ?>;
}
</style>
</head>
<body>
<canvas id="pamela"></canvas>
</body>
echo "<h2>Who's here right now?</h2>";
echo "<ul>";
foreach($array as $entry) {
if(substr($entry,0,1) == "{") {
if($_GET['showmacs'] == "1") {
echo "<li class='macaddr'>".$entry."</li>";
}
}
else{
echo "<li>".$entry."</li>";
}
}
if($_GET['showmacs'] == "1") {
echo "<li>&nbsp;<br/><a href=\"?showmacs=0\">Hide people who haven't registered yet</a>";
}
else {
echo "<li>&nbsp;<br/><a href=\"?showmacs=1\">Show people who haven't registered yet</a>";
}
echo "</ul>";
?>
</div>
</body>
</html>

27
pamela/config.example.php Normal file
View File

@ -0,0 +1,27 @@
<?php
// Filename and path of the sqlite db file. The file does not have to exist.
// The directory does need to exist though, and the directory must be writable.
define("SQLITE_DB", "/yourdir/pamela/db/pamela.sql");
// The background color for pamela
define("PAM_BGCOLOR", "#fff");
// The image shown in the center of the pamela interface
#define("PAM_IMAGE", "img/ccc.png");
#define("PAM_IMAGE", "img/norbert.png");
#define("PAM_IMAGE", "img/norbert-8bit.png");
define("PAM_IMAGE", "img/0x20.png");
// Set to FALSE to prevent the scanner button to be shown
define("PAM_BUT_SHOW", "TRUE");
// The text color for the text shown when hovering over the download button
define("PAM_BUT_COLOR", "#777");
// Number of seconds a data item remains valid. If it's older it will be removed.
define("DATA_TTL", "300");
// Url of the scanner script to download when the user clicks the download button.
define("PAM_SCANNER_LINK", "scanner/pamela-scanner.sh");

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

Before

Width:  |  Height:  |  Size: 88 KiB

After

Width:  |  Height:  |  Size: 88 KiB

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 549 B

After

Width:  |  Height:  |  Size: 549 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 673 B

After

Width:  |  Height:  |  Size: 673 B

View File

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

45
pamela/index.php Executable file
View File

@ -0,0 +1,45 @@
<?php
/*
Copyright 2010 Pieter Iserbyt
This file is part of Pamela.
Pamela is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Pamela is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Pamela. If not, see <http://www.gnu.org/licenses/>.
*/
require_once("config.php");
?><html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Pamela</title>
<script src="js/jquery-1.3.2.js" type="text/javascript"></script>
<script src="js/pamela-conf.php" type="text/javascript"></script>
<script src="js/pamela-buttons.js" type="text/javascript"></script>
<script src="js/pamela-nodes.js" type="text/javascript"></script>
<script src="js/pamela-matrices.js" type="text/javascript"></script>
<script src="js/pamela.js" type="text/javascript"></script>
<style type="text/css">
* {
margin:0;
padding:0;
}
body {
background-color: <?php echo PAM_BGCOLOR; ?>;
}
</style>
</head>
<body>
<canvas id="pamela"></canvas>
</body>
</html>

203
pamela/scanner/pamela-scanner.sh Executable file
View File

@ -0,0 +1,203 @@
#!/bin/bash
<<LICENSE
Copyright 2009 Pieter Iserbyt
This file is part of Pamela.
Pamela is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Pamela is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Pamela. If not, see <http://www.gnu.org/licenses/>.
LICENSE
PAM_DIR="$(cd $(dirname $0) && pwd)"
PAM_CRON="/etc/cron.d/pamela"
PAM_SCRIPT="${PAM_DIR}/$(basename $0)"
REGISTER=''
SIMULATE=''
IF='p2p1'
OUT='http://yourserver.com/upload.php'
USER=''
PASSWORD=''
TRANSLATE='/var/www/html/mac_log.csv'
POST=''
TIMEOUT=200
function usage {
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).
Defaults to [${OUT}].
-r Register the script in cron every 2 minutes
-q Unregister the script from cron
-u Http-auth user. Defaults to [${USER}].
-p Http-auth password. Defaults to [${PASSWORD}].
-s Simulate, don't commit the post.
-t URL Translate mac addresses using the data provided from the
specified URL. CSV format expected (mac,name\\n).
-h Shows help
This pamela scanner is an arp-scanner that uploads mac addresses in your local
lan on a webserver where you get a visual representation of those mac addresses
present. Multiple people on multiple lans can run this or any other scanner
together against the same web server, where all results will be agregated."
}
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}\" -t \"${TRANSLATE}\" | logger -t pamela" > "${PAM_CRON}"
echo "Depending on your version of crond, you might have to restart the cron daemon for the changes to take effect"
}
function unregister {
check_if_root
echo "Unregistering pamela in cron: ${PAM_CRON}"
rm "${PAM_CRON}"
echo "Depending on your version of crond, you might have to restart the cron daemon for the changes to take effect"
}
function parse_params {
TEMP=$(getopt -o 'hrqsi:o:u:p:t:-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;;
-u) USER="$2"; shift;;
-p) PASSWORD="$2"; shift;;
-r) REGISTER='r';;
-s) SIMULATE='s';;
-q) unregister; exit 0;;
-t) TRANSLATE="$2"; shift;;
-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
}
function scan {
echo $(date)" scanning..."
DATA=""
NUM_DATA=0
for M in $(arp-scan -R -i 10 --interface "${IF}" --localnet | awk '{ print $2 }' | grep :.*: | sort | uniq)
do
[ -n "${DATA}" ] && DATA="${DATA},${M}" || DATA="${M}";
let "NUM_DATA=NUM_DATA+1"
done
POST="${DATA}"
}
function translate {
if [ -z "${TRANSLATE}" ]
then
return 0
fi
# clean old translations
rm $TRANSLATE.complete
# Then we fall back to names obtained via zeroconf (aka avahi, aka bonjour)
#avahi-browse -a -t|grep :.*:.*:.*:|sed -e 's/.*IPv. \(.*\) \[\(.*\)].*/\2,\1[\2]/g' > $TRANSLATE.bon
# Finally we fall back to the name from arp-scan (maker of the network chipset)
# Yes I know we already ran arp-scan once...I'm too lazy to do it right
# And yes I'm using regex instead of learning how awk works.
#arp-scan -I eth0 -R --localnet|sed -e 's/\(.*\)\t\(.*\)\t\(.*\)/\2,\3[\2]/g'|grep :.*:.*:> $TRANSLATE.arp
# Combine names from 3 sources to one
# Note that the code below uses the last name to appear in the file
# So order them accordingly
#cat $TRANSLATE.bon $TRANSLATE.arp
cat $TRANSLATE >> $TRANSLATE.complete
POST=$(echo ${POST} | awk -v names="${TRANSLATE}.complete" 'BEGIN {
RS="\n"
FS=","
while ((getline nl < names) > 0) {
split(nl, n);
nms[n[1]] = n[2]
}
close(names)
RS=","
first=1
while ((getline i)> 0) {
sub(/\n$/,"",i)
# if (i in nms){ print "input:", i, "translates to", nms[i] }
if (!first)
printf(",")
printf (i in nms?nms[i]:i)
first=0
}
}')
}
function upload {
if [ -z "${SIMULATE}" ]
then
RESULT=$(wget "${OUT}" --timeout="${TIMEOUT}" --no-check-certificate -O - --quiet --post-data "data=${POST}" --user "${USER}" --password "${PASSWORD}")
else
echo Not executing: [wget "${OUT}" --timeout="${TIMEOUT}" --no-check-certificate -O - --quiet --post-data "data=${POST}" --user "${USER}" --password "${PASSWORD}"]
RESULT=
fi
if [ -n "${RESULT}" ]
then
echo Error uploading results:
echo "${RESULT}"
fi
echo $(date)" Uploaded ${NUM_DATA} mac addresses..."
}
parse_params $@
check_if_root
check_if_arpscan_installed
scan
translate
upload

View File

@ -1,133 +0,0 @@
#!/bin/bash
<<LICENSE
Copyright 2009 Pieter Iserbyt
This file is part of Pamela.
Pamela is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Pamela is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Pamela. If not, see <http://www.gnu.org/licenses/>.
LICENSE
PAM_DIR="$(cd $(dirname $0) && pwd)"
PAM_CRON="/etc/cron.d/pamela"
PAM_SCRIPT="$PAM_DIR/$(basename $0)"
REGISTER=
IF='eth0'
OUT='http://yourserver.com/pamela/upload.php'
USER=''
PASSWORD=''
function usage {
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).
Defaults to [$OUT].
-r Register the script in cron every 2 minutes
-q Unregister the script from cron
-u Http-auth user. Defaults to [$USER].
-p Http-auth password. Defaults to [$PASSWORD].
-h Shows help
This pamela scanner is an arp-scanner that uploads mac addresses in your local
lan on a webserver where you get a visual representation of those mac addresses
present. Multiple people on multiple lans can run this or any other scanner
together against the same web server, where all results will be agregated."
}
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 * * * * [ -x \"$PAM_SCRIPT\" ] && \"$PAM_SCRIPT\" -i \"$IF\" -o \"$OUT\" -u \"$USER\" -p \"$PASSWORD\" | logger -t pamela" > "$PAM_CRON"
echo "Depending on your version of crond, you might have to restart the cron daemon for the changes to take effect"
}
function unregister {
check_if_root
echo "Unregistering pamela in cron: $PAM_CRON"
rm "$PAM_CRON"
echo "Depending on your version of crond, you might have to restart the cron daemon for the changes to take effect"
}
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
}
function scan_and_upload {
echo $(date)" scanning..."
DATA=""
NUM_DATA=0
for M in $(arp-scan -R -i 10 --interface "$IF" --localnet | awk '{ print $2 }' | grep :.*: | sort | uniq)
do
[ -n "$DATA" ] && DATA="$DATA,$M" || DATA="$M";
let "NUM_DATA=NUM_DATA+1"
done
POST="data=$DATA"
RESULT=$(wget "$OUT" -O - --quiet --post-data "$POST" --user "$USER" --password "$PASSWORD")
if [ -n "$RESULT" ]
then
echo Error uploading results:
echo "$RESULT"
fi
echo $(date)" Uploaded $NUM_DATA mac addresses..."
}
parse_params $@
check_if_root
check_if_arpscan_installed
scan_and_upload

0
static/images/logo.png Normal file
View File

0
style.css Normal file
View File