From ea62e9679dd003c50ef04cb2ce9a361aad343f3e Mon Sep 17 00:00:00 2001
From: Jannik Schönartz
Date: Tue, 13 Mar 2018 11:23:22 +0100
Subject: [usb-lock-off] Big rework. Moved from client side (modal) stuff to
server side (new page) system. Removed the rules.conf textfield and added an
UI prototype for the rules creation.
---
modules-available/usblockoff/api.inc.php | 39 +++
modules-available/usblockoff/config.json | 2 +-
modules-available/usblockoff/install.inc.php | 36 +--
modules-available/usblockoff/lang/de/messages.json | 3 +-
modules-available/usblockoff/lang/en/messages.json | 3 +-
modules-available/usblockoff/page.inc.php | 293 ++++++++++++++-------
.../usblockoff/templates/usb-add-generic-rule.html | 61 +++--
.../templates/usb-configuration-table.html | 75 ++++++
.../usblockoff/templates/usb-device-list.html | 183 ++++++-------
.../usblockoff/templates/usb-edit-config.html | 11 +-
.../usblockoff/templates/usb-rules-config.html | 154 +++++------
11 files changed, 541 insertions(+), 319 deletions(-)
(limited to 'modules-available')
diff --git a/modules-available/usblockoff/api.inc.php b/modules-available/usblockoff/api.inc.php
index 6a5e4a7d..67f805f5 100644
--- a/modules-available/usblockoff/api.inc.php
+++ b/modules-available/usblockoff/api.inc.php
@@ -35,6 +35,9 @@ function HandleParameters()
$id = Request::get('id', '', 'string');
$serial = Request::get('serial', '', 'string');
deleteDevice($id, $serial);
+ } elseif ($getAction == "getrule") {
+ $configid = Request::get('configid', '0', 'int');
+ getRule($configid);
}
}
@@ -83,6 +86,42 @@ function newDevice($id, $serial, $hwProps, $deviceProps)
}
}
+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)) {
diff --git a/modules-available/usblockoff/config.json b/modules-available/usblockoff/config.json
index 12049689..7655f131 100644
--- a/modules-available/usblockoff/config.json
+++ b/modules-available/usblockoff/config.json
@@ -1,4 +1,4 @@
{
"category":"main.beta",
- "dependencies": ["bootstrap_switch", "bootstrap_dialog", "statistics", "permissionmanager"]
+ "dependencies": ["bootstrap_switch", "js_jqueryui", "bootstrap_dialog", "statistics", "permissionmanager"]
}
diff --git a/modules-available/usblockoff/install.inc.php b/modules-available/usblockoff/install.inc.php
index 967771d1..cf260c61 100644
--- a/modules-available/usblockoff/install.inc.php
+++ b/modules-available/usblockoff/install.inc.php
@@ -1,47 +1,49 @@
action === 'updateConfig') {
$this->updateConfig();
+ } elseif ($this->action === 'addDevices') {
+ $this->addDevices();
} elseif ($this->action === 'deleteConfig') {
$this->deleteConfig();
+ } elseif ($this->action === 'deleteRule') {
+ $this->deleteRule();
}
}
@@ -50,7 +50,140 @@ class Page_usblockoff extends Page
'rulesConfigHtml' => $rulesConfigHtml,
'daemonConfigHtml' => $daemonConfigHtml
));
+ } else if ($show === "add-devices") {
+ $this->deviceList();
+ } else if ($show === "add-generic-rule") {
+ $this->addGenericRule();
+ }
+ }
+
+ private function addDevices()
+ {
+ $configid = Request::any('configid', 0, 'int');
+
+ $rules = json_decode(Request::post('rules', '', 'string'), true);
+ foreach ($rules as $rule) {
+ $rid = (int)$rule['id'];
+ if($rid == 0) {
+ // New entry so insert only with new id.
+ $rid = Database::queryFirst("SELECT MAX(ruleid) AS ID FROM `usb_rule_prop`");
+ $rid = $rid['ID'];
+ if ($rid == null) $rid = 1;
+ else $rid += 1;
+ } else {
+ // Old entry so delete all old ones and insert new ones.
+ Database::exec("DELETE FROM `usb_rule_prop` WHERE ruleid=:ruleid", array('ruleid' => $rid));
+ }
+
+ Database::exec("INSERT INTO `usb_rule_prop` (ruleid, prop, value) VALUES (:ruleid, :prop, :val)", array(
+ 'ruleid' => $rid,
+ 'prop' => 'target',
+ 'val' => $rule['target']
+ ));
+
+ foreach ($rule['attributes'] as $attribute) {
+ // TODO: Better in one query?
+ Database::exec("INSERT INTO `usb_rule_prop` (ruleid, prop, value) VALUES (:ruleid, :prop, :val)", array(
+ 'ruleid' => $rid,
+ 'prop' => $attribute['prop'],
+ 'val' => $attribute['value']
+ ));
+ }
+
+ // TODO: Add id at the end of the config entry.
+ $config = Database::queryFirst("SELECT rulesconfig FROM `usb_configs` WHERE configid=:configid", array(
+ 'configid' => $configid
+ ));
+ $rulesconfig = json_decode($config['rulesconfig'], true);
+ $rulesconfig[] = $rid;
+ Database::exec("UPDATE `usb_configs` SET rulesconfig = :rulesconfig WHERE configid=:configid", array(
+ 'configid' => $configid,
+ 'rulesconfig' => json_encode($rulesconfig)
+ ));
+ //$result['rules'][] = $rid;
+ }
+
+ Util::redirect('?do=usblockoff&show=edit-config&configid=' . $configid);
+ }
+
+ private function deviceList()
+ {
+ $configid = Request::get("configid", 0, 'int');
+ $usbdevices = $this->getUsbDeviceList();
+
+ // TODO: Translate Operator Action etc..
+
+ $settings = array();
+ $setting = array();
+ $setting['title'] = "Action";
+ $setting['select_list'] = array(array(
+ 'option' => 'allow',
+ 'active' => true,
+ ),
+ array(
+ 'option' => 'block',
+ 'active' => false,
+ ),
+ array(
+ 'option' => 'reject',
+ 'active' => false,
+ ));
+ $setting['helptext'] = array('helptext' => Dictionary::translateFile('rule', 'abr_helptext'));
+ $setting['property'] = 'action';
+ $setting['settingHtml'] = Render::parse('server-prop-dropdown', (array)$setting);
+ $settings[] = $setting;
+
+ $ruleValues = array('id' => true,
+ 'serial' => true,
+ 'name' => true,
+ //'hash' => false,
+ //'parent-hash' => false,
+ 'via-port' => false,
+ 'with-interface' => false);
+ foreach ($ruleValues as $key => $value) {
+ $settings[] = array(
+ 'settingHtml' => Render::parse('server-prop-bool', array('title' => Dictionary::translateFile('rule', $key),
+ 'helptext' => array('helptext' => Dictionary::translateFile('rule', $key . "_helptext")),
+ 'property' => $key,
+ 'currentvalue' => $value)),
+ );
}
+ Render::addTemplate('usb-device-list', array(
+ 'list' => array_values($usbdevices),
+ 'settings' => array_values($settings),
+ 'configid' => $configid
+ ));
+ }
+
+ private function addGenericRule($target = 'allow') {
+ $settings = array();
+ $configid = Request::get("configid", "");
+
+ // TODO: Translate Operator Action etc..
+
+ $setting = array();
+ $setting['title'] = "Action";
+ $setting['select_list'] = array(array(
+ 'option' => 'allow',
+ 'active' => ($target == 'allow' ? true : false),
+ ),
+ array(
+ 'option' => 'block',
+ 'active' => ($target == 'block' ? true : false),
+ ),
+ array(
+ 'option' => 'reject',
+ 'active' => ($target == 'reject' ? true : false),
+ ));
+ $setting['helptext'] = array('helptext' => Dictionary::translateFile('rule', 'abr_helptext'));
+ $setting['property'] = 'action';
+ $setting['settingHtml'] = Render::parse('server-prop-dropdown', (array)$setting);
+ $settings[] = $setting;
+
+ Render::addTemplate('usb-add-generic-rule', array(
+ 'settings' => array_values($settings),
+ 'configid' => $configid
+ ));
}
protected function loadConfigChooser()
@@ -68,7 +201,6 @@ class Page_usblockoff extends Page
protected function deleteConfig()
{
$configID = Request::any('id', 0, 'int');
-
if ($configID != 0) {
Database::exec("DELETE FROM `usb_configs` WHERE configid=:configid", array('configid' => $configID));
}
@@ -77,6 +209,19 @@ class Page_usblockoff extends Page
Util::redirect('?do=usblockoff');
}
+ protected function deleteRule()
+ {
+ $configid = Request::any('configid', 0, 'int');
+ $ruleid = Request::any('id', 0, 'int');
+ if ($ruleid != 0) {
+ Database::exec("DELETE FROM `usb_rule_prop` WHERE ruleid=:ruleid", array('ruleid' => $ruleid));
+ }
+
+ Message::addSuccess('rule-deleted');
+ Util::redirect('?do=usblockoff&show=edit-config&configid=' . $configid);
+ }
+
+
protected function updateConfig()
{
$result['saveAsNewConfig'] = Request::post('saveAsNewConfig', false, 'bool');
@@ -93,7 +238,7 @@ class Page_usblockoff extends Page
$result['IPCAccessControlFiles'] = Request::post('IPCAccessControlFiles', '', 'string');
$result['DeviceRulesWithPort'] = Request::post('DeviceRulesWithPort', '', 'string');
$result['AuditFilePath'] = Request::post('AuditFilePath', '', 'string');
- $result['rules'] = Request::post('rules', '', 'string');
+ $result['rules'] = json_decode(Request::post('rules', '', 'string'), true);
$id = Request::post('id', 0, 'int');
$configname = Request::post('configName', '', 'string');
@@ -126,32 +271,66 @@ class Page_usblockoff extends Page
if ($id == '0' || $result['saveAsNewConfig']) {
$dbquery = Database::exec("INSERT INTO `usb_configs` (configname, rulesconfig, daemonconfig) VALUES (:configname, :rulesconfig, :daemonconfig)",
array('configname' => $configname,
- 'rulesconfig' => $result['rules'],
+ 'rulesconfig' => json_encode($result['rules']),
'daemonconfig' => implode($newDaemonConf)));
} else {
$dbquery = Database::exec("UPDATE `usb_configs` SET configname=:configname, rulesconfig=:rulesconfig, daemonconfig=:daemonconfig WHERE configid=:configid",
array('configid' => $id,
'configname' => $configname,
- 'rulesconfig' => $result['rules'],
+ 'rulesconfig' => json_encode($result['rules']),
'daemonconfig' => implode($newDaemonConf)));
}
Message::addSuccess('config-saved');
}
- private function loadRulesConfig($id) {
+ private function loadRulesConfig($configid) {
$rulesConf = null;
- if ($id == 0) {
+ if ($configid == 0) {
$currentdir = getcwd();
-
+ // TODO: No need for that with the new rule db structure.
$rulesConf = file_get_contents($currentdir . '/modules/usblockoff/inc/default-configs/rules.conf');
} else {
- $dbquery = Database::queryFirst("SELECT * FROM `usb_configs` WHERE configid=:id", array('id' => $id));
- $rulesConf = $dbquery['rulesconfig'];
+ $dbquery = Database::queryFirst("SELECT * FROM `usb_configs` WHERE configid=:id", array('id' => $configid));
+ $ruleIds = json_decode($dbquery['rulesconfig'], true);
}
+
+ $rulesArray = [];
+ foreach ($ruleIds as $id) {
+ // TODO: Query rule and prepare array for the html file.
+ $dbq = Database::simpleQuery("SELECT * FROM `usb_rule_prop` WHERE ruleid=:id", array('id' => $id));
+ $rule = [];
+ $rule['id'] = $id;
+ $rule['hasoverload'] = false;
+ $rule['num_overload'] = 0;
+ $rule['attributes'] = array();
+ $rule['attributes_overload'] = "";
+ while ($entry = $dbq->fetch(PDO::FETCH_ASSOC)) {
+ if ($entry['prop'] == "target") {
+ $rule['target'] = $entry['value'];
+ } else {
+ $attributes = [];
+ $attributes['prop'] = $entry['prop'];
+ $attributes['value'] = $entry['value'];
+
+ if(sizeof($rule['attributes']) >= 3) {
+ $rule['hasoverload'] = true;
+ $rule['num_overload'] += 1;
+ $rule['attributes_overload'] .= $attributes['prop'] . ': ' . $attributes['value'] . "
";
+ } else {
+ $rule['attributes'][] = $attributes;
+ }
+ }
+ }
+
+ if (!empty($rule['target'])) {
+ $rulesArray[] = $rule;
+ }
+ }
return Render::parse('usb-rules-config', array(
- 'rules' => $rulesConf,
+ 'rules' => (array)$rulesArray,
+ 'configid' => $configid
));
}
@@ -168,7 +347,6 @@ class Page_usblockoff extends Page
$dbquery = Database::queryFirst("SELECT * FROM `usb_configs` WHERE configid=:id", array('id' => $id));
$daemonConf = explode("\r\n", $dbquery['daemonconfig']);
}
-
$element = array();
$hlptxt = '';
@@ -205,90 +383,11 @@ class Page_usblockoff extends Page
die('Unauthorized');
}
$action = Request::any('action');
- if ($action === 'deviceList') {
- $this->ajaxDeviceList();
- } elseif ($action === 'genericRuleBuilder') {
- $this->ajaxGenericRuleBuilder();
- }
- }
-
-
-
- private function ajaxGenericRuleBuilder() {
- $settings = array();
-
- // TODO: Translate Operator Action etc..
- $setting = array();
- $setting['title'] = "Action";
- $setting['select_list'] = array(array(
- 'option' => 'allow',
- 'active' => true,
- ),
- array(
- 'option' => 'block',
- 'active' => false,
- ),
- array(
- 'option' => 'reject',
- 'active' => false,
- ));
- $setting['helptext'] = array('helptext' => Dictionary::translateFile('rule', 'abr_helptext'));
- $setting['property'] = 'action';
- $setting['settingHtml'] = Render::parse('server-prop-dropdown', (array)$setting);
- $settings[] = $setting;
-
- echo Render::parse('usb-add-generic-rule', array(
- 'settings' => array_values($settings),
- ));
- }
-
- private function ajaxDeviceList()
- {
- $usbdevices = $this->getUsbDeviceList();
-
- // TODO: Translate Operator Action etc..
-
- $settings = array();
- $setting = array();
- $setting['title'] = "Action";
- $setting['select_list'] = array(array(
- 'option' => 'allow',
- 'active' => true,
- ),
- array(
- 'option' => 'block',
- 'active' => false,
- ),
- array(
- 'option' => 'reject',
- 'active' => false,
- ));
- $setting['helptext'] = array('helptext' => Dictionary::translateFile('rule', 'abr_helptext'));
- $setting['property'] = 'action';
- $setting['settingHtml'] = Render::parse('server-prop-dropdown', (array)$setting);
- $settings[] = $setting;
-
- $ruleValues = array('id' => true,
- 'serial' => true,
- 'name' => true,
- 'hash' => false,
- 'parent-hash' => false,
- 'via-port' => false,
- 'with-interface' => false,
- 'interface-policy' => false);
- foreach ($ruleValues as $key => $value) {
- $settings[] = array(
- 'settingHtml' => Render::parse('server-prop-bool', array('title' => Dictionary::translateFile('rule', $key),
- 'helptext' => array('helptext' => Dictionary::translateFile('rule', $key . "_helptext")),
- 'property' => $key,
- 'currentvalue' => $value)),
- );
+ // TODO: Removed if not needed anymore.
+ if ($action === '') {
+ //$this->ajaxDeviceList();
}
- echo Render::parse('usb-device-list', array(
- 'list' => array_values($usbdevices),
- 'settings' => array_values($settings)
- ));
}
private function getUsbDeviceList() {
diff --git a/modules-available/usblockoff/templates/usb-add-generic-rule.html b/modules-available/usblockoff/templates/usb-add-generic-rule.html
index 07729db4..77b5f13e 100644
--- a/modules-available/usblockoff/templates/usb-add-generic-rule.html
+++ b/modules-available/usblockoff/templates/usb-add-generic-rule.html
@@ -18,8 +18,10 @@
Todo: Implement this.
+Or not.
+¯\_(ツ)_/¯
+ +