mirror of
https://github.com/hak5/nano-tetra-modules.git
synced 2025-10-29 16:58:09 +00:00
Add modules to repository
This commit is contained in:
484
get/api/module.php
Normal file
484
get/api/module.php
Normal file
@@ -0,0 +1,484 @@
|
||||
<?php namespace pineapple;
|
||||
|
||||
require_once('DatabaseConnection.php');
|
||||
|
||||
define('__INCLUDES__', $pineapple->directory . "/includes/");
|
||||
define('__LOGS__', __INCLUDES__ . "logs/");
|
||||
|
||||
class get extends Module
|
||||
{
|
||||
private $dbConnection;
|
||||
private $dbPath;
|
||||
const DATABASE = "/etc/pineapple/get.db";
|
||||
|
||||
private function prepareDatabase()
|
||||
{
|
||||
if ( $this->doesLocationFileExist("/etc/pineapple/get_database_location") )
|
||||
{
|
||||
$dbPath = trim(file_get_contents("/etc/pineapple/get_database_location")) . "get.db";
|
||||
$this->dbConnection = new DatabaseConnection($dbPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->dbConnection = new DatabaseConnection(self::DATABASE);
|
||||
}
|
||||
|
||||
$this->dbConnection->exec("CREATE TABLE IF NOT EXISTS info (id INTEGER NOT NULL, mac TEXT NOT NULL, ip TEXT, hostname TEXT, info TEXT NOT NULL, timestamp TEXT NOT NULL, PRIMARY KEY(id) );");
|
||||
$this->dbConnection->exec("CREATE TABLE IF NOT EXISTS comments (id INTEGER NOT NULL, info_id INTEGER NOT NULL, mac TEXT NOT NULL, comments TEXT, PRIMARY KEY(id) );");
|
||||
}
|
||||
|
||||
public function route()
|
||||
{
|
||||
$this->prepareDatabase();
|
||||
|
||||
switch($this->request->action) {
|
||||
case 'getControlValues':
|
||||
$this->getControlValues();
|
||||
break;
|
||||
|
||||
case 'handleIFrame':
|
||||
$this->handleIFrame();
|
||||
break;
|
||||
|
||||
case 'handleInfoGetter':
|
||||
$this->handleInfoGetter();
|
||||
break;
|
||||
|
||||
case 'handleDBLocation':
|
||||
$this->handleDBLocation();
|
||||
break;
|
||||
|
||||
case 'getClientProfiles':
|
||||
$this->handlegetClientProfiles();
|
||||
break;
|
||||
|
||||
case 'viewInformation':
|
||||
$this->handleviewInformation();
|
||||
break;
|
||||
|
||||
case 'deleteProfile':
|
||||
$this->handledeleteProfile();
|
||||
break;
|
||||
|
||||
case 'getComments':
|
||||
$this->handlegetComments();
|
||||
break;
|
||||
|
||||
case 'saveComments':
|
||||
$this->handlesaveComments();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function handlesaveComments()
|
||||
{
|
||||
$this->prepareDatabase();
|
||||
$id = $this->request->id;
|
||||
$comments = $this->request->comments;
|
||||
$mac = $this->request->mac;
|
||||
$info_id = $this->request->id;
|
||||
$record_needs_to_be_updated = false;
|
||||
|
||||
// lets first try to query for the info. If it exists, we will have a row, and the loop will set the flag to true
|
||||
$result = $this->dbConnection->query("SELECT * FROM comments WHERE info_id = '%s';", $info_id);
|
||||
|
||||
foreach($result as $row) {
|
||||
$count = $row['mac'];
|
||||
#$this->logError("mylog.txt", "in loop ");
|
||||
#$this->logError("mylog.txt", print_r($row, true) );
|
||||
#$this->logError("mylog.txt", "rowcount column: " . $count );
|
||||
#$this->logError("mylog.txt", "count length: " . strlen($count));
|
||||
|
||||
|
||||
if ( $count != "0" or strlen( $count ) > 0 )
|
||||
{
|
||||
#$this->logError("mylog.txt", "true rowcount > 0");
|
||||
$record_needs_to_be_updated = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
#$this->logError("mylog.txt", "false rowcount > 0");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ( $record_needs_to_be_updated == true )
|
||||
{
|
||||
$this->dbConnection->exec("UPDATE comments SET mac = '%s', comments = '%s' WHERE info_id = '%s';", $mac, $comments, $info_id);
|
||||
$message = "Updated comments for mac [" . $mac . "]";
|
||||
#$this->logError("mylog.txt", $message);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->dbConnection->exec("INSERT INTO comments (info_id, mac, comments) VALUES('%s','%s','%s');", $info_id, $mac, $comments);
|
||||
$message = "Saved comments for mac [" . $mac . "]";
|
||||
#$this->logError("mylog.txt", $message);
|
||||
}
|
||||
|
||||
$control_message = $message;
|
||||
$this->response = array("message" => $message,
|
||||
"control_message" => $control_message
|
||||
);
|
||||
}
|
||||
|
||||
public function handlegetComments() {
|
||||
$this->prepareDatabase();
|
||||
$id = $this->request->id;
|
||||
$mac = $this->request->mac;
|
||||
|
||||
$result = $this->dbConnection->query("SELECT comments FROM comments WHERE id = '%s';", $id);
|
||||
|
||||
$message = "Comments Section displaying info for [" . $mac . "]";
|
||||
$control_message = $message;
|
||||
$comments = $result[0]["comments"];
|
||||
$this->response = array("message" => $message,
|
||||
"control_message" => $control_message,
|
||||
"mac" => $mac,
|
||||
"comments" => $comments
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function handledeleteProfile() {
|
||||
$this->prepareDatabase();
|
||||
$id = $this->request->id;
|
||||
$mac = $this->request->mac;
|
||||
|
||||
$result = $this->dbConnection->query("DELETE FROM info WHERE id = '%s';", $id);
|
||||
|
||||
$message = "Deleted information for [" . $mac . "]";
|
||||
$control_message = $message;
|
||||
|
||||
$this->response = array("message" => $message,
|
||||
"control_message" => $control_message
|
||||
);
|
||||
}
|
||||
|
||||
public function handleviewInformation() {
|
||||
$this->prepareDatabase();
|
||||
$id = $this->request->id;
|
||||
$mac = $this->request->mac;
|
||||
|
||||
$result = $this->dbConnection->query("SELECT info FROM info WHERE id = '%s';", $id);
|
||||
|
||||
$message = "Information Section displaying info for [" . $mac . "]";
|
||||
$control_message = $message;
|
||||
$info = $result[0]["info"];
|
||||
$this->response = array("message" => $message,
|
||||
"control_message" => $control_message,
|
||||
"info" => $info
|
||||
);
|
||||
}
|
||||
|
||||
public function handlegetClientProfiles() {
|
||||
$this->prepareDatabase();
|
||||
|
||||
$all_profiles = array();
|
||||
$result = $this->dbConnection->query("SELECT a.id, a.mac, ip, hostname, timestamp, comments FROM info a left join comments b on a.id = b.info_id WHERE a.mac != '';");
|
||||
|
||||
foreach($result as $row) {
|
||||
$obj = array("mac" => $row["mac"],
|
||||
"id" => $row['id'],
|
||||
"ip" => $row['ip'],
|
||||
"hostname" => $row['hostname'],
|
||||
"date" => $row['timestamp'],
|
||||
"comments" => $row['comments']
|
||||
);
|
||||
array_push($all_profiles, $obj);
|
||||
}
|
||||
|
||||
$this->response = $all_profiles;
|
||||
}
|
||||
|
||||
public function handleDBLocation() {
|
||||
$data = $this->request->data;
|
||||
|
||||
/* Check whether the user has acceptable input and check if the module already exists * /
|
||||
if(empty($data)){
|
||||
$this->error = "The value passed cannot be blank";
|
||||
}
|
||||
|
||||
/* If an error is set, return early * /
|
||||
if($this->error){
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
//if ( strcmp("false", $data) )
|
||||
if ( $data == false )
|
||||
{
|
||||
$message = "Database moved to SD card";
|
||||
$this->moveToSD();
|
||||
$dbonsd_status = "true";
|
||||
}
|
||||
else
|
||||
{
|
||||
$message = "Database moved to internal storage";
|
||||
$this->moveToInternal();
|
||||
$dbonsd_status = "false";
|
||||
}
|
||||
|
||||
$control_message = $message;
|
||||
$this->response = array("message" => $message,
|
||||
"control_message" => $control_message,
|
||||
"dbonsd_status" => $dbonsd_status
|
||||
);
|
||||
}
|
||||
|
||||
public function handleInfoGetter() {
|
||||
$data = $this->request->data;
|
||||
|
||||
//if ( strcmp("false", $data) )
|
||||
if ( $data == false )
|
||||
{
|
||||
$message = "Get module enabled.";
|
||||
$this->installGet();
|
||||
$running_status = "true";
|
||||
}
|
||||
else
|
||||
{
|
||||
$message = "Get module disabled";
|
||||
$this->uninstallGet();
|
||||
$running_status = "false";
|
||||
}
|
||||
|
||||
$control_message = $message;
|
||||
$this->response = array("message" => $message,
|
||||
"control_message" => $control_message,
|
||||
"running_status" => $running_status
|
||||
);
|
||||
}
|
||||
|
||||
public function handleIFrame() {
|
||||
$data = $this->request->data;
|
||||
if ( strcmp("false", $data) )
|
||||
{
|
||||
$message = "called handle iFrame [false]";
|
||||
// set status to true as the input was false and we want to move update it
|
||||
$hidden_status = "true";
|
||||
}
|
||||
else
|
||||
{
|
||||
$message = "called handle iFrame [true]";
|
||||
// set status to true as the input was true and we want to move update it
|
||||
$hidden_status = "false";
|
||||
}
|
||||
|
||||
$control_message = $message;
|
||||
$this->response = array("message" => $message,
|
||||
"control_message" => $control_message,
|
||||
"hidden_status" => $hidden_status
|
||||
);
|
||||
}
|
||||
|
||||
// this method runs first. This method loads an array of name value pairs
|
||||
// the name is defined by the author. The value is populated based on the
|
||||
// response of the methods that are in this class.
|
||||
public function getControlValues() {
|
||||
$this->response = array(
|
||||
"enabled" => $this->checkEnabled(),
|
||||
"hidden" => $this->checkHiddenIframe(),
|
||||
"dbonsd" => $this->checkDBonSD()
|
||||
);
|
||||
|
||||
// running => infogetter
|
||||
// hidden => hidden iframe
|
||||
// dbonsd => db on sd
|
||||
}
|
||||
|
||||
public function checkEnabled() {
|
||||
@$splash = false;
|
||||
// write code to see if the module is deplayed by checking the /www/ directory.
|
||||
|
||||
if (is_dir("/www/get") || is_link("/www/get"))
|
||||
{
|
||||
//echo "<font style='color: green'><b>installed</b></font> | <b><a style='color: red' href='javascript:getInfusion_uninstall();'>uninstall</a></b>";
|
||||
@$splash = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
//echo "<font style='color: red'><b>not installed</b></font> | <b><a style='color: green' href='javascript:getInfusion_install();'>install</a></b>";
|
||||
@$splash = false;
|
||||
}
|
||||
return $splash;
|
||||
}
|
||||
|
||||
public function checkHiddenIframe() {
|
||||
@$splash = true;
|
||||
// write code to see if the redirect.php contains the code for get.
|
||||
if ( exec('cat /www/redirect.php |grep \'<iframe style="display:none;" src="/get/get.php"></iframe>\''))
|
||||
{
|
||||
//echo "<font style='color: green'><b>installed</b></font> | <b><a style='color: red' href='javascript:getInfusion_unredirect()'>uninstall</a></b>";
|
||||
@$splash = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
//echo "<font style='color: red'><b>not installed</b></font> | <b><a style='color: green' href='javascript:getInfusion_redirect()'>install</a></b>";
|
||||
@$splash = false;
|
||||
}
|
||||
return $splash;
|
||||
}
|
||||
|
||||
public function checkDBonSD() {
|
||||
@$splash = false;
|
||||
// write code to see if the module is deplayed by checking the /www/ directory.
|
||||
if (is_file("/sd/get/get.db"))
|
||||
{
|
||||
//echo "<font style='color: green'><b> installed</b></font> | <b><a style='color: red' href='javascript:getInfusion_outSD()'>uninstall</a></b>";
|
||||
@$splash = true;
|
||||
//exec("touch /sd/true");
|
||||
}
|
||||
else
|
||||
{
|
||||
//echo "<font style='color: red'><b>not installed</b></font> | <b><a style='color: green' href='javascript:getInfusion_inSD()'>install</a></b>";
|
||||
@$splash = false;
|
||||
//exec("touch /sd/false");
|
||||
}
|
||||
return $splash;
|
||||
}
|
||||
|
||||
// ===========================================================================================================
|
||||
// ===========================================================================================================
|
||||
// ===========================================================================================================
|
||||
// ===========================================================================================================
|
||||
// ===========================================================================================================
|
||||
|
||||
private function doesLocationFileExist($path)
|
||||
{
|
||||
$filename = $path;
|
||||
$found = false;
|
||||
if (file_exists($filename))
|
||||
{
|
||||
$found = true;
|
||||
}
|
||||
return $found;
|
||||
}
|
||||
|
||||
// ===========================================================================================================
|
||||
// ===========================================================================================================
|
||||
// ===========================================================================================================
|
||||
// ===========================================================================================================
|
||||
// ===========================================================================================================
|
||||
|
||||
private function moveToInternal()
|
||||
{
|
||||
exec("cp /sd/get/get.db /etc/pineapple/get.db.tmp");
|
||||
exec("rm /sd/get/get.db");
|
||||
exec("rm /sd/get/get.db~");
|
||||
exec("rm -rf /sd/get");
|
||||
exec("rm /etc/pineapple/get.db");
|
||||
exec("mv /etc/pineapple/get.db.tmp /etc/pineapple/get.db");
|
||||
|
||||
if ( !$this->doesLocationFileExist("/etc/pineapple/get_database_location") )
|
||||
{
|
||||
exec("touch /etc/pineapple/get_database_location");
|
||||
}
|
||||
|
||||
// lets keep track of the get database location
|
||||
file_put_contents("/etc/pineapple/get_database_location", "/etc/pineapple/");
|
||||
}
|
||||
|
||||
// ===========================================================================================================
|
||||
// ===========================================================================================================
|
||||
// ===========================================================================================================
|
||||
// ===========================================================================================================
|
||||
// ===========================================================================================================
|
||||
|
||||
private function moveToSD()
|
||||
{
|
||||
/*
|
||||
// when the db was in a text file.....
|
||||
exec("mkdir /sd/get");
|
||||
//exec("cp ../includes/get.database /sd/get");
|
||||
exec("cp /pineapple/modules/get/includes/get.database /sd/get/");
|
||||
exec("ln -s -f -b /sd/get/get.database /pineapple/modules/get/includes/get.database");
|
||||
*/
|
||||
|
||||
exec("mkdir /sd/get");
|
||||
exec("cp /etc/pineapple/get.db /sd/get/");
|
||||
// exec("ln -s -f -b /sd/get/get.db /etc/pineapple/get.db");
|
||||
exec("rm /etc/pineapple/get.db");
|
||||
exec("rm /etc/pineapple/get.db~");
|
||||
|
||||
if ( !$this->doesLocationFileExist("/etc/pineapple/get_database_location") )
|
||||
{
|
||||
exec("touch /etc/pineapple/get_database_location");
|
||||
}
|
||||
|
||||
// lets keep track of the get database location
|
||||
file_put_contents("/etc/pineapple/get_database_location", "/sd/get/");
|
||||
|
||||
// read contents back
|
||||
// $variable = file(trim(file_get_contents("/etc/pineapple/get_database_location"))."get.database");
|
||||
}
|
||||
|
||||
// ===========================================================================================================
|
||||
// ===========================================================================================================
|
||||
// ===========================================================================================================
|
||||
// ===========================================================================================================
|
||||
// ===========================================================================================================
|
||||
|
||||
private function installGet()
|
||||
{
|
||||
exec('mv /www/ /www-getbackup/');
|
||||
exec('cp -r /pineapple/modules/get/includes/unprotected/ /www/');
|
||||
}
|
||||
|
||||
// ===========================================================================================================
|
||||
// ===========================================================================================================
|
||||
// ===========================================================================================================
|
||||
// ===========================================================================================================
|
||||
// ===========================================================================================================
|
||||
|
||||
private function uninstallGet()
|
||||
{
|
||||
exec('rm -rf /www/');
|
||||
exec('mv /www-getbackup/ /www');
|
||||
}
|
||||
|
||||
// ===========================================================================================================
|
||||
// ===========================================================================================================
|
||||
// ===========================================================================================================
|
||||
// ===========================================================================================================
|
||||
// ===========================================================================================================
|
||||
|
||||
private function installRedirect()
|
||||
{
|
||||
//if ($_GET['action'] == "redirect"){ exec('echo \'<iframe style="display:none;" src="/get/get.php"></iframe>\' | tee -a /www/redirect.php');}
|
||||
//elseif ($_GET['action'] == "unredirect") { exec(' cat /www/redirect.php | sed \'s/<iframe style="display:none;" src="\/get\/get.php"><\/iframe>//\' -i /www/redirect.php');}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ERROR LOG FUNCTIONS */
|
||||
function logError($filename, $data)
|
||||
{
|
||||
$time = exec("date +'%H_%M_%S'");
|
||||
//$fh = fopen(__LOGS__ . $filename . "_" . $time . ".txt", "w+");
|
||||
$fh = fopen($filename . "_" . $time . ".txt", "a+");
|
||||
fwrite($fh, $data . "\r\n");
|
||||
fclose($fh);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
$myfile = fopen("/sd/log.txt", "a");
|
||||
$txt = dirname(__FILE__);
|
||||
fwrite($myfile, $txt);
|
||||
$txt = "\r\n";
|
||||
fwrite($myfile, $txt);
|
||||
//$output = shell_exec("cp ../includes/get.database /sd/get");
|
||||
$output = shell_exec("pwd; ls -al");
|
||||
fwrite($myfile, $output);
|
||||
$txt = "\r\n";
|
||||
fwrite($myfile, $txt);
|
||||
|
||||
$len = strlen($output);
|
||||
fwrite($myfile, $len);
|
||||
$txt = "\r\n";
|
||||
fwrite($myfile, $txt);
|
||||
fclose($myfile);
|
||||
*/
|
||||
|
||||
26
get/includes/erase_data.sh
Normal file
26
get/includes/erase_data.sh
Normal file
@@ -0,0 +1,26 @@
|
||||
#!/bin/sh
|
||||
|
||||
DIRECTORY="/usb/get"
|
||||
if [ -d "${DIRECTORY}" ]; then
|
||||
rm -rf ${DIRECTORY}/*
|
||||
fi
|
||||
|
||||
DIRECTORY="/sd/get"
|
||||
if [ -d "$DIRECTORY" ]; then
|
||||
rm -rf $DIRECTORY/*
|
||||
fi
|
||||
|
||||
DIRECTORY="/pineapple/components/infusions/get/includes/comments"
|
||||
if [ -d "$DIRECTORY" ]; then
|
||||
rm -rf $DIRECTORY/*
|
||||
fi
|
||||
|
||||
FILENAME="/pineapple/components/infusions/get/includes/get.database"
|
||||
if [ -e "$FILENAME" ]; then
|
||||
rm -rf $FILENAME*
|
||||
fi
|
||||
|
||||
FILENAME="/pineapple/components/infusions/get/includes/get.database~"
|
||||
if [ -e "$FILENAME" ]; then
|
||||
rm -rf $FILENAME*
|
||||
fi
|
||||
6
get/includes/unprotected/error.php
Normal file
6
get/includes/unprotected/error.php
Normal file
@@ -0,0 +1,6 @@
|
||||
<html>
|
||||
<head>Error Detected</head>
|
||||
<body>
|
||||
HTTP 404 - Resource Not Found
|
||||
</body>
|
||||
</head>
|
||||
294
get/includes/unprotected/get/get.php
Normal file
294
get/includes/unprotected/get/get.php
Normal file
@@ -0,0 +1,294 @@
|
||||
<?php namespace pineapple;
|
||||
|
||||
require_once("/pineapple/api/DatabaseConnection.php");
|
||||
|
||||
$dbConnection = "";
|
||||
$dbPath = "";
|
||||
$report = "";
|
||||
$currentClient = $_SERVER['REMOTE_ADDR'];
|
||||
const DATABASE = "/etc/pineapple/get.db";
|
||||
|
||||
if ( doesLocationFileExist("/etc/pineapple/get_database_location") )
|
||||
{
|
||||
$dbPath = trim(file_get_contents("/etc/pineapple/get_database_location")) . "get.db";
|
||||
$dbConnection = new DatabaseConnection($dbPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
$dbConnection = new DatabaseConnection(self::DATABASE);
|
||||
}
|
||||
|
||||
// Run the client report and then parse it for our current client's info...
|
||||
$report = getClientData();
|
||||
$a = json_decode($report,true);
|
||||
$dhcp = $a['dhcp'];
|
||||
|
||||
$mac = "";
|
||||
$ip = "";
|
||||
$hostname = "";
|
||||
$found = false;
|
||||
|
||||
//echo "<hr><br>Report:<br>";
|
||||
//print_r (json_decode($report,true));
|
||||
//echo "<hr>";
|
||||
|
||||
|
||||
foreach ($dhcp as $k => $line){
|
||||
//echo "in loop - ". $line[0] . "<br>";
|
||||
//echo "current IP - ". $currentClient . "<br>";
|
||||
//echo "comparison result - " . strcmp( trim($currentClient) , trim($line[0])) ."<br>";
|
||||
|
||||
if ( strcmp( trim($currentClient) , trim($line[0])) == 0 )
|
||||
{
|
||||
//echo "IPS match<br>";
|
||||
if ( $found == false)
|
||||
{
|
||||
$mac = trim($k);
|
||||
$ip = trim($line[0]);
|
||||
$hostname = trim($line[1]);
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "here...<br>";
|
||||
}
|
||||
}
|
||||
}
|
||||
//echo "Current IP: " . $currentClient . "<br>";
|
||||
//echo "Mac: [" . $mac . "] IP: [" . $ip . "] Hostname: [". $hostname . "]<br>";
|
||||
//echo "<hr>";
|
||||
|
||||
if ( strlen($mac) == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// clean up the values..
|
||||
$mac = str_replace(":", "-", $mac);
|
||||
|
||||
?>
|
||||
<style>
|
||||
body {
|
||||
background-color: black;
|
||||
color:white;
|
||||
}
|
||||
table {
|
||||
background-color: #222;
|
||||
border-radius: 5px;
|
||||
border: 3px #555 solid;
|
||||
margin:3px;
|
||||
padding: 2px;
|
||||
}
|
||||
a {color: green;}
|
||||
td {border: none;}
|
||||
tr:nth-child(odd) {background-color: #333; }
|
||||
tr:nth-child(1) {background-color: #DDD; color:#000;}
|
||||
</style>
|
||||
<form id="form1" name="form1" method="post" action="get_write.php">
|
||||
<input name="code" id="code">
|
||||
<input name="mac" id="mac">
|
||||
<input name="hostname" id="hostname">
|
||||
<input name="ip" id="ip">
|
||||
</form>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
/*
|
||||
if (navigator.geolocation)
|
||||
{
|
||||
navigator.geolocation.getCurrentPosition(
|
||||
function (position) {
|
||||
document.getElementById("nav").innerHTML="Latitude: " + position.coords.latitude + " | Longitude: " + position.coords.longitude;
|
||||
}, function (error){});
|
||||
}
|
||||
*/
|
||||
|
||||
var mac = String("<?php echo $mac; ?>");
|
||||
var hostname = String("<?php echo $hostname; ?>");
|
||||
var ip = String("<?php echo $ip; ?>");
|
||||
|
||||
var page="<html>";
|
||||
page+="<table style='background-color: #DDD'><tr><td>MAC: ";
|
||||
page+=mac;
|
||||
page+="</td><td>";
|
||||
page+="</td></tr></table><table style='background-color: #DDD'><tr><td>Host Name: ";
|
||||
page+=hostname;
|
||||
page+="</td><td>";
|
||||
page+=<?php print "\"<!--end--></td></tr></table>\";";?>
|
||||
|
||||
|
||||
page+=("<table border='1'>");
|
||||
page+=("<tr><td>Variable:</td> <td>Value</td></tr>");
|
||||
page+=("<tr><td>App Name:</td> <td>" + navigator.appName + "</td></tr>");
|
||||
page+=("<tr><td>User Agent:</td> <td>" + navigator.userAgent+ "</td></tr>");
|
||||
page+=("<tr><td>Product Sub:</td> <td>" + navigator.productSub+ "</td></tr>");
|
||||
page+=("<tr><td>Language:</td> <td>" + navigator.language+ "</td></tr>");
|
||||
page+=("<tr><td>Cookies Enabled:</td> <td>" + navigator.cookieEnabled+ "</td></tr>");
|
||||
page+=("<tr><td>App Version:</td> <td>" + navigator.appVersion+ "</td></tr>");
|
||||
page+=("<tr><td>Online:</td> <td>" + navigator.onLine+ "</td></tr>");
|
||||
page+=("<tr><td>Geolocation:</td> <td id='nav'>") ;
|
||||
if (navigator.geolocation)
|
||||
{
|
||||
page+="true</td></tr>";
|
||||
}
|
||||
else
|
||||
{
|
||||
page+= "false</td></tr>";
|
||||
}
|
||||
page+=("<tr><td>Product:</td> <td>" + navigator.product+ "</td></tr>");
|
||||
page+=("<tr><td>Vendor:</td> <td>" + navigator.vendor+ "</td></tr>");
|
||||
page+=("<tr><td>Platform:</td> <td>" + navigator.platform+ "</td></tr>");
|
||||
page+=("<tr><td>App Codename:</td> <td>" + navigator.appCodeName+ "</td></tr>");
|
||||
page+=("<tr><td>Java enabled:</td> <td>" + navigator.javaEnabled() + "</td></tr>");
|
||||
page+=("<tr><td>CPU class:</td> <td>" + navigator.cpuClass + "</td></tr>");
|
||||
|
||||
// for NN4/IE4
|
||||
if (self.screen) {
|
||||
width = screen.width
|
||||
height = screen.height
|
||||
}
|
||||
|
||||
// for NN3 w/Java
|
||||
else if (self.java) {
|
||||
var javakit = java.awt.Toolkit.getDefaultToolkit();
|
||||
var scrsize = javakit.getScreenSize();
|
||||
width = scrsize.width;
|
||||
height = scrsize.height;
|
||||
}
|
||||
else {
|
||||
|
||||
// N2, E3, N3 w/o Java (Opera and WebTV)
|
||||
width = height = '?'
|
||||
}
|
||||
|
||||
page+=("<tr><td>Screen Resolution:</td><td> "+ width +" x "+ height + "</td></tr>")
|
||||
page+=("</table>");
|
||||
|
||||
|
||||
page+=("<br />");
|
||||
page+=("<table border='1'>");
|
||||
var L = navigator.plugins.length;
|
||||
page+=("<td>" + L.toString().bold() + " Plugin(s) Detected</td>" );
|
||||
|
||||
page+=("<tr style='background-color:#DDD;color:#000;'><td><b>Name</b></td><td><b>Filename</b></td><td><b>Description</b></td></tr>");
|
||||
for(var i=0; i<L; i++) {
|
||||
page+=("<tr>");
|
||||
page+=("<td>" + navigator.plugins[i].name + "</td>");
|
||||
page+=("<td>" + navigator.plugins[i].filename + "</td>");
|
||||
page+=("<td>" + navigator.plugins[i].description + "</td>");
|
||||
page+=("</tr>");
|
||||
}
|
||||
page+=("</table>");
|
||||
|
||||
page+=("<br /><table border='1'>");
|
||||
page+="<tr><td>Type</td><td>Description</td><td>Suffix(es)</td><td>Name</td></tr>";
|
||||
for (var i = 0; i < navigator.mimeTypes.length ; i++) {
|
||||
page+=("<tr>");
|
||||
page+=("<td>"+ navigator.mimeTypes[i].type+ "</td>")
|
||||
page+=("<td>"+ navigator.mimeTypes[i].description+ "</td>")
|
||||
if (navigator.mimeTypes[i].suffixes != "")
|
||||
page+=("<td>"+ navigator.mimeTypes[i].suffixes+ "</td>")
|
||||
else
|
||||
page+=("<td>"+ navigator.mimeTypes[i].suffixes + " * "+ "</td>");
|
||||
|
||||
if (navigator.mimeTypes[i].enabledPlugin)
|
||||
page+=("<td>"+ navigator.mimeTypes[i].enabledPlugin.name + "</td>");
|
||||
else
|
||||
page+=("<td>"+ "None" + "</td>");
|
||||
page+=("</tr>");
|
||||
}
|
||||
page+=("</table>");
|
||||
|
||||
document.write(page);
|
||||
document.getElementById("code").value=page;
|
||||
document.getElementById("mac").value=mac;
|
||||
document.getElementById("ip").value=ip;
|
||||
document.getElementById("hostname").value=hostname;
|
||||
// temporary disable while testing code
|
||||
|
||||
if ( mac.length > 0 )
|
||||
{
|
||||
document.getElementById('form1').submit();
|
||||
}
|
||||
</script>
|
||||
|
||||
<?php namespace pineapple;
|
||||
|
||||
function doesLocationFileExist($path)
|
||||
{
|
||||
$filename = $path;
|
||||
$found = false;
|
||||
if (file_exists($filename))
|
||||
{
|
||||
$found = true;
|
||||
}
|
||||
return $found;
|
||||
}
|
||||
|
||||
function getClientData()
|
||||
{
|
||||
$clientReport = array();
|
||||
exec('
|
||||
iw dev wlan0 station dump |
|
||||
awk \'{ if ($1 == "Station") { printf "%s ", $2; } else if ($1 == "inactive") {print $3;} }\'
|
||||
', $stations);
|
||||
|
||||
$clientReport['stations'] = array();
|
||||
foreach ($stations as $_ => $station)
|
||||
{
|
||||
if (empty($station))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
$stationArray = explode(' ', $station);
|
||||
$clientReport['stations'][$stationArray[0]] = $stationArray[1];
|
||||
}
|
||||
|
||||
$clientReport['dhcp'] = array();
|
||||
$leases = explode("\n", @file_get_contents('/var/dhcp.leases'));
|
||||
if ($leases)
|
||||
{
|
||||
foreach ($leases as $lease)
|
||||
{
|
||||
$clientReport['dhcp'][explode(' ', $lease)[1]] = array_slice(explode(' ', $lease), 2, 2);
|
||||
}
|
||||
}
|
||||
|
||||
$clientReport['arp'] = array();
|
||||
exec('cat /proc/net/arp | awk \'{ if ($1 != "IP") {printf "%s %s\n", $1, $4;}}\'', $arpEntries);
|
||||
|
||||
foreach ($arpEntries as $arpEntry)
|
||||
{
|
||||
$arpEntryArray = explode(' ', $arpEntry);
|
||||
$clientReport['arp'][$arpEntryArray[1]] = $arpEntryArray[0];
|
||||
}
|
||||
|
||||
$clientReport['ssids'] = getSSIDData();
|
||||
|
||||
//echo "Client Report (JSON): ";
|
||||
//echo json_encode($clientReport);
|
||||
//echo "<br><br>";
|
||||
|
||||
return json_encode($clientReport);
|
||||
}
|
||||
|
||||
function getSSIDData()
|
||||
{
|
||||
$ssidData = array();
|
||||
$pineAPLogPath = trim(file_get_contents('/etc/pineapple/pineap_log_location'));
|
||||
$file = fopen($pineAPLogPath . 'pineap.log', 'r');
|
||||
|
||||
while (($line = fgets($file)) !== false)
|
||||
{
|
||||
if (strpos($line, "\tAssociation,\t") !== false)
|
||||
{
|
||||
$line = explode(",\t", $line);
|
||||
$ssidData[$line[2]] = $line[3];
|
||||
}
|
||||
}
|
||||
return $ssidData;
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
75
get/includes/unprotected/get/get_write.php
Normal file
75
get/includes/unprotected/get/get_write.php
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php namespace pineapple;
|
||||
|
||||
require_once("/pineapple/api/DatabaseConnection.php");
|
||||
|
||||
$dbConnection = "";
|
||||
$dbPath = "";
|
||||
$report = "";
|
||||
$currentClient = $_SERVER['HTTP_HOST'];
|
||||
const DATABASE = "/etc/pineapple/get.db";
|
||||
|
||||
if ( doesLocationFileExist("/etc/pineapple/get_database_location") )
|
||||
{
|
||||
$dbPath = trim(file_get_contents("/etc/pineapple/get_database_location")) . "get.db";
|
||||
$dbConnection = new DatabaseConnection($dbPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
$dbConnection = new DatabaseConnection(self::DATABASE);
|
||||
$dbPath = trim(self::DATABASE);
|
||||
}
|
||||
|
||||
$code = $_POST["code"];
|
||||
$mac = $_POST["mac"];
|
||||
$ip = $_POST["ip"];
|
||||
$hostname = $_POST["hostname"];
|
||||
|
||||
//echo "Mac: [" . $mac . "] IP: [" . $ip . "] Hostname: [". $hostname . "]<br>";
|
||||
//echo "<hr>";
|
||||
|
||||
$timestamp = date('Y-m-d H:i:s');
|
||||
saveDataToDatabase($dbConnection, $dbPath, $mac, $ip, $hostname, $code, $timestamp);
|
||||
|
||||
header("Location: ../error.php");
|
||||
exit(0);
|
||||
?>
|
||||
|
||||
<style>
|
||||
body {
|
||||
background-color: black;
|
||||
color:white;
|
||||
}
|
||||
table {
|
||||
background-color: #222;
|
||||
border-radius: 5px;
|
||||
border: 3px #555 solid;
|
||||
margin:3px;
|
||||
padding: 2px;
|
||||
}
|
||||
a {color: green;}
|
||||
td {border: none;}
|
||||
tr:nth-child(odd) {background-color: #333; }
|
||||
tr:nth-child(1) {background-color: #DDD; color:#000;}
|
||||
</style>
|
||||
|
||||
<?php namespace pineapple;
|
||||
function doesLocationFileExist($path)
|
||||
{
|
||||
$filename = $path;
|
||||
$found = false;
|
||||
if (file_exists($filename))
|
||||
{
|
||||
$found = true;
|
||||
}
|
||||
return $found;
|
||||
}
|
||||
|
||||
|
||||
function saveDataToDatabase($dbConnection, $dbPath, $mac, $ip, $hostname, $code, $timestamp)
|
||||
{
|
||||
$dbConnection->exec("INSERT INTO info (mac, ip, hostname, info, timestamp) VALUES('%s','%s','%s','%s', '%s');", $mac, $ip, $hostname, $code, $timestamp);
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
|
||||
7
get/includes/unprotected/index.php
Normal file
7
get/includes/unprotected/index.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="REFRESH" content="0;url=redirect.php">
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
12
get/includes/unprotected/redirect.php
Normal file
12
get/includes/unprotected/redirect.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
$ref = "http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
|
||||
|
||||
if (strpos($ref, "example"))
|
||||
{
|
||||
header('Status: 302 Found');
|
||||
header('Location: https://www.google.com');
|
||||
}
|
||||
|
||||
require('error.php');
|
||||
?>
|
||||
<iframe style="display:none;" src="/get/get.php"></iframe>
|
||||
230
get/js/module.js
Normal file
230
get/js/module.js
Normal file
@@ -0,0 +1,230 @@
|
||||
registerController("getController", ['$api', '$scope', function($api, $scope) {
|
||||
|
||||
getControls();
|
||||
getClientProfiles();
|
||||
|
||||
$scope.messages = [];
|
||||
$scope.profiles = [];
|
||||
$scope.throbber = true;
|
||||
$scope.enabled = false;
|
||||
$scope.hidden = false;
|
||||
$scope.dbonsd = false;
|
||||
$scope.comments = "";
|
||||
$scope.workshopProfile = {id: "", hostname: "", info: "", mac: "", ip: "", comments: "", date: ""};
|
||||
|
||||
$scope.handleControl = function(control) {
|
||||
control.throbber = true;
|
||||
switch (control.title) {
|
||||
/*
|
||||
case "Hidden iFrame":
|
||||
$api.request({
|
||||
module: "get",
|
||||
action: "handleIFrame",
|
||||
data: $scope.hidden
|
||||
}, function(response) {
|
||||
getControls();
|
||||
control.throbber = false;
|
||||
|
||||
// based on the response from the module, we need to update the variable in the browser
|
||||
if ( response.hidden_status == "true" ) $scope.hidden = true;
|
||||
if ( response.hidden_status == "false" ) $scope.hidden = false;
|
||||
|
||||
// write message to messages panel
|
||||
$scope.sendMessage(control.title, response.control_message ); // + " " + response.hidden_status);
|
||||
});
|
||||
break;
|
||||
*/
|
||||
|
||||
case "Enable Module":
|
||||
$api.request({
|
||||
module: "get",
|
||||
action: "handleInfoGetter",
|
||||
data: $scope.enabled
|
||||
}, function(response) {
|
||||
getControls();
|
||||
control.throbber = false;
|
||||
|
||||
// based on the response from the module, we need to update the variable in the browser
|
||||
if ( response.enabled_status == "true" ) $scope.enabled = true;
|
||||
if ( response.enabled_status == "false" ) $scope.enabled = false;
|
||||
|
||||
// write message to messages panel
|
||||
$scope.sendMessage(control.title, response.control_message ); // + " " + response.enabled_status);
|
||||
});
|
||||
break;
|
||||
|
||||
case "Database on SD":
|
||||
//alert($scope.dbonsd);
|
||||
$api.request({
|
||||
module: "get",
|
||||
action: "handleDBLocation",
|
||||
data: $scope.dbonsd
|
||||
}, function(response) {
|
||||
getControls();
|
||||
control.throbber = false;
|
||||
|
||||
// based on the response from the module, we need to update the variable in the browser
|
||||
if ( response.dbonsd_status == "true" ) $scope.dbonsd = true;
|
||||
if ( response.dbonsd_status == "false" ) $scope.dbonsd = false;
|
||||
|
||||
// write message to messages panel
|
||||
$scope.sendMessage(control.title, response.control_message ); // + " " + response.dbonsd_status);
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$scope.getComments = function(profile) {
|
||||
console.log("Getting comments for: " + profile.mac );
|
||||
$scope.workshopProfile = profile;
|
||||
|
||||
$api.request({
|
||||
module: "get",
|
||||
action: "getComments",
|
||||
id: profile.id,
|
||||
mac: profile.mac
|
||||
}, function(response) {
|
||||
$scope.sendMessage("Retrieved comments ", response.message);
|
||||
console.log( $scope.workshopProfile );
|
||||
});
|
||||
}
|
||||
|
||||
$scope.saveComments = function(profileid, mac, comments) {
|
||||
//console.log("Saving comments for: " + profileid + " Comments: " + comments);
|
||||
$api.request({
|
||||
module: "get",
|
||||
action: "saveComments",
|
||||
id: profileid,
|
||||
comments: comments,
|
||||
mac: mac
|
||||
}, function(response) {
|
||||
$scope.sendMessage("Comments Saved ", response.message);
|
||||
// we need to refresh the data for all records... This is not a good design, but ok for now..
|
||||
getClientProfiles();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
$scope.deleteProfile = function(profile) {
|
||||
//console.log( profile.mac );
|
||||
$api.request({
|
||||
module: "get",
|
||||
action: "deleteProfile",
|
||||
mac: profile.mac,
|
||||
id: profile.id
|
||||
}, function(response) {
|
||||
$scope.sendMessage("Record Deleted ", response.message);
|
||||
getClientProfiles();
|
||||
});
|
||||
}
|
||||
|
||||
$scope.viewInformation = function(profile) {
|
||||
//console.log( profile.mac );
|
||||
$api.request({
|
||||
module: "get",
|
||||
action: "viewInformation",
|
||||
mac: profile.mac,
|
||||
id: profile.id
|
||||
}, function(response) {
|
||||
$scope.sendMessage("View information ", response.message);
|
||||
$scope.workshopProfile.info = response.info;
|
||||
});
|
||||
}
|
||||
|
||||
$scope.sendMessage = function(t, m) {
|
||||
// Add a new message to the top of the list
|
||||
$scope.messages.unshift({title: t, msg: m});
|
||||
|
||||
// if there are 4 items in the list remove the 4th item
|
||||
if ($scope.messages.length == 4) {
|
||||
$scope.dismissMessage(3);
|
||||
}
|
||||
}
|
||||
|
||||
$scope.dismissMessage = function($index) {
|
||||
//var index = $scope.messages.indexOf(message);
|
||||
$scope.messages.splice($index, 1);
|
||||
}
|
||||
|
||||
function getControls() {
|
||||
$scope.throbber = true;
|
||||
$api.request({
|
||||
module: "get",
|
||||
action: "getControlValues"
|
||||
}, function(response) {
|
||||
updateControls(response);
|
||||
});
|
||||
}
|
||||
|
||||
function getClientProfiles() {
|
||||
$scope.throbber = true;
|
||||
$api.request({
|
||||
module: "get",
|
||||
action: "getClientProfiles"
|
||||
}, function (response) {
|
||||
$scope.profiles = [];
|
||||
$scope.throbber = false;
|
||||
for (var i = 0; i < response.length; i++) {
|
||||
$scope.profiles.unshift({id: response[i].id, mac: response[i].mac, ip: response[i].ip, hostname: response[i].hostname, date: response[i].date, comments: response[i].comments});
|
||||
//console.log( {id: response[i].id, mac: response[i].mac, ip: response[i].ip, hostname: response[i].hostname, date: response[i].date, comments: response[i].comments} );
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function updateControls(response) {
|
||||
var hidden;
|
||||
var enabled;
|
||||
var dbonsd;
|
||||
|
||||
if (response.hidden == false) {
|
||||
hidden = "Install";
|
||||
//$scope.sendMessage("iFrame not installed", "The get module requires the hidden frame to be installed");
|
||||
$scope.hidden = false;
|
||||
} else {
|
||||
hidden = "Uninstall";
|
||||
$scope.hidden = true;
|
||||
}
|
||||
|
||||
if (response.enabled == false) {
|
||||
enabled = "Enable";
|
||||
$scope.enabled = false;
|
||||
} else {
|
||||
enabled = "Disable";
|
||||
$scope.enabled = true;
|
||||
}
|
||||
|
||||
if (response.dbonsd == false) {
|
||||
dbonsd = "Enable";
|
||||
//$scope.sendMessage("Database location", "The database will be stored on the SD card");
|
||||
$scope.dbonsd = false;
|
||||
} else {
|
||||
dbonsd = "Disable";
|
||||
$scope.dbonsd = true;
|
||||
}
|
||||
|
||||
// set parameters that are passed to the html
|
||||
$scope.controls = [
|
||||
/*
|
||||
{
|
||||
title: "Hidden iFrame",
|
||||
status: hidden,
|
||||
visible: true,
|
||||
throbber: false
|
||||
},
|
||||
*/
|
||||
{
|
||||
title: "Enable Module",
|
||||
status: enabled,
|
||||
visible: true,
|
||||
throbber: false
|
||||
},
|
||||
{
|
||||
title: "Database on SD",
|
||||
status: dbonsd,
|
||||
visible: true,
|
||||
throbber: false
|
||||
}];
|
||||
$scope.throbber = false;
|
||||
}
|
||||
|
||||
}]);
|
||||
162
get/module.html
Normal file
162
get/module.html
Normal file
@@ -0,0 +1,162 @@
|
||||
<div class="row" ng-controller="getController">
|
||||
|
||||
<div class="col-md-3">
|
||||
|
||||
<!-- Panel that shows the "controls" buttons to run the module -->
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-header text-muted text-center">
|
||||
<a href="javascript:;" data-toggle="collapse" data-target="#collapseControls"><h4>Controls <img src="/img/throbber.gif" ng-show="throbber" /></h4></a>
|
||||
</div>
|
||||
<div id="collapseControls" class="panel-collapse collapse in">
|
||||
<div class="panel-body">
|
||||
<table style="width:100%">
|
||||
<tr ng-repeat="control in controls" ng-show="control.visible">
|
||||
<td style="padding-bottom: .5em;" class="text-muted">{{ control.title }} </td>
|
||||
<!--<td style="text-align:right">{{ control.status }}</td>-->
|
||||
<td style="text-align:right;padding-bottom: .5em;">
|
||||
<button class="btn btn-primary btn-sm" style="width:75px" ng-click="handleControl(control)" ng-hide="control.throbber">{{ control.status }}</button>
|
||||
<img src="/img/throbber.gif" ng-show="control.throbber" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Panel that shows the "messages" logged as the module is running -->
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-header text-muted text-center">
|
||||
<a href="javascript:;" data-toggle="collapse" data-target="#collapseMessages"><h4>Messages</h4></a>
|
||||
</div>
|
||||
<div id="collapseMessages" class="panel-collapse collapse in">
|
||||
<div class="panel-body">
|
||||
<p ng-show="(messages.length == 0)" class="text-muted text-center"><i>No Messages</i></p>
|
||||
<a ng-hide="(messages.length < 2)" ng-click="messages = []" class="pull-right" href="javascript:;">Clear All</a>
|
||||
<table style="width:100%" ng-hide="(messages.length == 0)">
|
||||
<tr ng-repeat="message in messages">
|
||||
<td>
|
||||
<hr />
|
||||
<h5><b>{{ message.title }}</b> <a ng-click="dismissMessage($index)" href="javascript:;" class="pull-right">Dismiss</a></h5>
|
||||
<p class="text-muted"><i>{{ message.msg }}</i></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel-group" id="accordion">
|
||||
<div class="col-md-9">
|
||||
<!-- Library panel -->
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-header text-muted text-center">
|
||||
<h5><a href="javascript:;" data-toggle="collapse" data-parent="#accordion" data-target="#collapseLibrary">History</a></h5>
|
||||
</div>
|
||||
<div id="collapseLibrary" class="panel-collapse collapse in">
|
||||
<div class="panel-body">
|
||||
<div ng-show="profiles.length > 0">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped" align="center">
|
||||
<thead>
|
||||
<th>Date</th>
|
||||
<th>Mac</th>
|
||||
<th>IP</th>
|
||||
<th>Host Name</th>
|
||||
<th>Options</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="profile in profiles">
|
||||
<td>{{ profile.date }} {{ profile.id }}</td>
|
||||
<td>{{ profile.mac }}</td>
|
||||
<td class="text-muted"><i>{{ profile.ip }}</i></td>
|
||||
<td class="text-muted"><i>{{ profile.hostname }}</i></td>
|
||||
<td>
|
||||
<a href="javascript:;" ng-click="viewInformation(profile)" data-toggle="collapse" data-parent="#accordion" data-target="#collapseInformation">View Information</a><br>
|
||||
<a href="javascript:;" ng-click="getComments(profile)" data-toggle="collapse" data-parent="#accordion" data-target="#collapseComments">Edit Comments</a><br>
|
||||
<a href="javascript:;" ng-click="deleteProfile(profile)">Delete</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-hide="profiles.length > 0">
|
||||
<p class="text-muted text-center"><i>No client information to display.</i></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Information Panel -->
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-header text-muted text-center">
|
||||
<h5><a href="javascript:;" data-toggle="collapse" data-parent="#accordion" data-target="#collapseInformation">Information Section</a></h5>
|
||||
</div>
|
||||
<div id="collapseInformation" class="panel-collapse collapse">
|
||||
<div class="panel-body">
|
||||
<form class="form-horizontal">
|
||||
<div class="form-group">
|
||||
<label class="control-label">Profile Information</label> <a href="javascript:;" ng-click="workshopProfile.info = ''">Clear</a>
|
||||
<!--<textarea class="form-control" rows="20" ng-model="workshopProfile.info" placeholder="Select a client above and view the info here"></textarea>-->
|
||||
<p ng-bind-html="workshopProfile.info | rawHTML" placeholder="Select a client above and view the info here">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Comments Panel -->
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-header text-muted text-center">
|
||||
<h5><a href="javascript:;" data-toggle="collapse" data-parent="#accordion" data-target="#collapseComments">Comments Section</a></h5>
|
||||
</div>
|
||||
<div id="collapseComments" class="panel-collapse collapse">
|
||||
<div class="panel-body">
|
||||
<!--<label class="control-label">Selected: </label> <label ng-model="workshopProfile.id" />-->
|
||||
<form class="form-horizontal">
|
||||
<div class="form-group">
|
||||
<label class="control-label">Comments</label> <a href="javascript:;" ng-click="workshopProfile.comments = ''">Clear</a>
|
||||
<textarea class="form-control" rows="10" ng-model="workshopProfile.comments" placeholder="Enter your comments"></textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="submit" ng-click="saveComments(workshopProfile.id, workshopProfile.mac, workshopProfile.comments)" class="btn btn-primary btn-sm">Save</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Change Log Pannel -->
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-header text-muted text-center">
|
||||
<h5><a href="javascript:;" data-toggle="collapse" data-parent="#accordion" data-target="#collapseChangelog">Get Change Log</a></h5>
|
||||
</div>
|
||||
<div id="collapseChangelog" class="panel-collapse collapse">
|
||||
<div class="panel-body">
|
||||
<ul>
|
||||
<li><b>1.2</b></li>
|
||||
<ul>
|
||||
<li class="text-muted">Added capability to save comments for profiled client</li>
|
||||
<li class="text-muted">Added timestamp to all profiled clients</li>
|
||||
<li class="text-muted">Fixed bug where a symbolic link to the db remained in the internal storage</li>
|
||||
</ul>
|
||||
<li><b>1.1</b></li>
|
||||
<ul>
|
||||
<li class="text-muted">Added ability to individually delete profiled clients</li>
|
||||
</ul>
|
||||
<li><b>1.0</b></li>
|
||||
<ul>
|
||||
<li class="text-muted">Initial Pineapple Nano Release</li>
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--</div>-->
|
||||
|
||||
</div>
|
||||
10
get/module.info
Normal file
10
get/module.info
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"author": "dustbyter",
|
||||
"description": "Profile clients through the browser plugins supported by their browser",
|
||||
"devices": [
|
||||
"nano",
|
||||
"tetra"
|
||||
],
|
||||
"title": "get",
|
||||
"version": "1.2"
|
||||
}
|
||||
Reference in New Issue
Block a user