<?php
HandleParameters();
function HandleParameters()
{
$getAction = Request::get('action', 0, 'string');
if ($getAction == "newdevice") {
$id = Request::get('id', '', 'string');
$serial = Request::get('serial', '', 'sting');
$name = Request::get('name', '', 'string');
$ip = Request::get('ip', 0, 'string');
$client = Database::queryFirst("SELECT m.machineuuid AS 'muid', m.currentuser AS 'user' FROM machine AS m WHERE m.clientip=:ip", array('ip' => $ip));
// TODO: product and vendor id necessary? It's already in the hwname part.
list($vid, $pid) = explode(':', $id);
$hwProps = array(
'vendorid' => $vid,
'productid' => $pid,
'name' => $name,
'with-interface' => Request::get('with-interface', '', 'string')
);
// TODO: WITH INTERFACE in the HW table?! Should be equal for every device but not guaranteed (ODROID).
$deviceProps = array(
'hash' => Request::get('hash', '', 'string'),
'parent-hash' => Request::get('parent-hash', '', 'string'),
'via-port' => Request::get('via-port', '', 'string'),
'interface-policy' => Request::get('interface-policy', '', 'string'),
'machineuuid' => $client['muid'],
'user' => $client['user'],
'lastseen' => time()
);
newDevice($id, $serial, $hwProps, $deviceProps);
} elseif ($getAction === "deletedevice") {
$id = Request::get('id', '', 'string');
$serial = Request::get('serial', '', 'string');
deleteDevice($id, $serial);
} elseif ($getAction === "getrule") {
$configid = Request::get('configid', '0', 'int');
getRule($configid);
} elseif ($getAction === "getidlist") {
echo getIDList();
}
}
/**
* Adds a new USB-Device to the db.
*
* @param string $id USB-Device id.
* @param string $serial USB-Device serial number.
* @param string $name USB-Device name.
*/
function newDevice($id, $serial, $hwProps, $deviceProps)
{
// Add or Update the usb device in the statistic_hw table.
$hwid = (int)Database::insertIgnore('statistic_hw', 'hwid', array(
'hwtype' => DeviceType::USB,
'hwname' => $id));
// TODO: Is it okay to use the id (vendor:product) as hwname to identify a usb device?
// Add all the global prop values to the statistics_hw_prop table.
// productid, vendorid, name, interfaces
// TODO:
addHwProps('statistic_hw_prop', $hwid, $hwProps);
// Only when the device has a serial number add the specific hw props.
// TODO: !!! Are there data transfer devices without a serial number? !!!
if (!empty($serial)) {
// Add the hwid -> serial in the usblockoff_hw table if not already existent.
$dbquery2 = Database::queryFirst("Select * FROM `usblockoff_hw` WHERE hwid=:hwid AND serial=:serial", array(
'hwid' => $hwid,
'serial' => $serial
));
if (empty($dbquery2)) {
Database::exec("INSERT INTO `usblockoff_hw` (hwid, serial) VALUES (:hwid, :serial)", array(
'hwid' => $hwid,
'serial' => $serial
));
}
// Add all the prop values to the usblockoff_hw_prop table.
// PROP: serial, machineuuid, time, user, ruleInformation, Port, hash, interface-policy
addUSBHwProps('usblockoff_hw_prop', $hwid, $serial, $deviceProps);
echo "Successfully added";
} else {
echo "No specific props were added. Device has no serial number";
}
}
function getRule($configid) {
// Get the config from the db.
$config = Database::queryFirst("SELECT * FROM `usb_configs` WHERE configid=:configid", array(
"configid" => $configid
));
$idList = array();
$rules = array();
// For each $id get the rule information and build the rule.
foreach (json_decode($config['rulesconfig']) as $id) {
$idList[] = $id;
// TODO: Make more efficient with one query instead of one per id.
$dbquery = Database::simpleQuery("SELECT * FROM `usb_rule_prop` WHERE ruleid=:id", array(
"id" => $id
));
$rule = "";
while ($attribute = $dbquery->fetch(PDO::FETCH_ASSOC)) {
if ($attribute['prop'] == "target") {
$rule = $attribute['value'] . $rule;
} else {
if ($attribute['prop'] == "serial" || $attribute['prop'] == "name" || $attribute['prop'] == "hash" ||
$attribute['prop'] == "parent-hash" || $attribute['prop'] == "via-port") {
$rule = $rule . " " . $attribute['prop'] . " \"" . $attribute['value'] . "\"";
} else {
$rule = $rule . " " . $attribute['prop'] . " " . $attribute['value'];
}
}
}
$rules[] = $rule;
}
// Return the completed rules.conf.
echo implode("\n", $rules);
}
function addHwProps($table, $hwid, $propArray) {
foreach ($propArray as $prop => $value) {
if (empty($value)) {
continue;
}
Database::exec("INSERT INTO " . $table . " (hwid, prop, value) VALUES (:hwid, :prop, :value) ON DUPLICATE KEY UPDATE value=:value", array(
'hwid' => $hwid,
'prop' => $prop,
'value' => $value
));
}
}
function addUSBHwProps($table, $hwid, $serial, $propArray) {
foreach ($propArray as $prop => $value) {
if (empty($value)) {
continue;
}
Database::exec("INSERT INTO " . $table . " (hwid, serial, prop, value) VALUES (:hwid, :serial, :prop, :value) ON DUPLICATE KEY UPDATE value=:value", array(
'hwid' => $hwid,
'serial' => $serial,
'prop' => $prop,
'value' => $value
));
}
}
/**
* Deletes a device from the db given a serial number.
*
* @param string $serial USB-Device serial number.
*/
function deleteDevice($id, $serial)
{
$hw = Database::queryFirst("SELECT * FROM `statistic_hw` WHERE hwname=:id", array('id' => $id));
if($hw['hwtype'] === DeviceType::USB) {
Database::exec("DELETE FROM `usblockoff_hw` WHERE hwid=:hwid AND serial=:serial", array(
'hwid' => $hw['hwid'],
'serial' => $serial));
echo "Successfully deleted.";
} else {
echo "Type is not a USB device";
}
}
/**
* Return a sorted list with all vendor / id information as JSON
*/
function getIDList() {
$usblist = array();
// TODO: Online version takes a bit longer to load but is more accurate. (2018 instead of 2015)
//$lines = file('http://www.linux-usb.org/usb.ids');
$lines = file('/var/lib/usbutils/usb.ids');
$currentVendor = '';
$br = false;
foreach ($lines as $line) {
if ($line === "\n" && $br) {
// If its the first part (vid - name / pid - name) skip comments else break because the part we needed is finished.
break;
} else if ($line[0] === '#' || $line === "\n") {
continue;
} else if (!ctype_space($line[0])) {
$br = true;
// It's a vendor id.
$l = explode(' ', preg_replace('~[\r\n\t]+~', '', $line));
$vendor = array();
$vendor['name'] = $l[1];
$vendor['products'] = array();
$currentVendor = $l[0];
$usblist[$l[0]] = $vendor;
} else if (!ctype_space($line[1])) {
// It's a product id.
$l = explode(' ', preg_replace('~[\r\n\t]+~', '', $line));
$usblist[$currentVendor]['products'][$l[0]] = $l[1];
} else {
// It's a interface
continue;
}
}
$sortVendorName = [];
$sortVendorId = [];
foreach ($usblist as $key => $value) {
$sortVendorName[] = (string)$value['name'];
$sortVendorId[] = (string)$key;
$sortProductName = [];
$sortProductId = [];
$tmp = $value['products'];
$keys2 = array_keys($tmp);
foreach ($tmp as $k => $v) {
$sortProductName[] = $v;
$sortProductId[] = $k;
}
array_multisort($sortProductName, SORT_ASC, $sortProductId, SORT_ASC, $tmp, $keys2);
$usblist[$key]['products'] = array_combine($keys2, $tmp);
}
$keys = array_keys($usblist);
array_multisort($sortVendorName, SORT_ASC, $sortVendorId, SORT_ASC, $usblist, $keys);
return json_encode(array_combine($keys, $usblist));
}