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 @@
{{lang_modeOptions}} +
@@ -64,6 +66,7 @@
+
@@ -140,16 +143,26 @@ - \ No newline at end of file diff --git a/modules-available/usblockoff/templates/usb-configuration-table.html b/modules-available/usblockoff/templates/usb-configuration-table.html index eb3a8839..3ceebce5 100644 --- a/modules-available/usblockoff/templates/usb-configuration-table.html +++ b/modules-available/usblockoff/templates/usb-configuration-table.html @@ -6,6 +6,7 @@ + + + + + + +
+
+
+
{{lang_configurationTable}}
+
+
+ +
+
+ + + + + + + + + + + {{#config_list}} + + + + + + + {{/config_list}} + +
{{lang_serverName}}{{lang_ruleInfoTODO}}{{lang_edit}}{{lang_delete}}
{{config_name}}TODO: Show Rule information here + + + + + + + +
+ +
+
+ +
+
+
+
+
+
+
{{lang_configurationTable}}
+
+
+ +

Work in progress ...

+

Todo: Implement this.

+

Or not.

+

¯\_(ツ)_/¯

+ +
+
+
+