From 4a3430078e9399bd4e85e424a1fcef06faa22918 Mon Sep 17 00:00:00 2001 From: Jannik Schönartz Date: Tue, 20 Mar 2018 19:43:50 +0100 Subject: [usb-lock-off] Added the edit rule function. Saveing is not finished. --- modules-available/usblockoff/api.inc.php | 66 +++++++- modules-available/usblockoff/page.inc.php | 175 ++++++++++++++++++++- .../usblockoff/templates/server-prop-dropdown.html | 10 +- .../usblockoff/templates/usb-edit-rule.html | 82 ++++++++++ 4 files changed, 322 insertions(+), 11 deletions(-) create mode 100644 modules-available/usblockoff/templates/usb-edit-rule.html (limited to 'modules-available') diff --git a/modules-available/usblockoff/api.inc.php b/modules-available/usblockoff/api.inc.php index 67f805f5..52a98b67 100644 --- a/modules-available/usblockoff/api.inc.php +++ b/modules-available/usblockoff/api.inc.php @@ -31,13 +31,15 @@ function HandleParameters() 'lastseen' => time() ); newDevice($id, $serial, $hwProps, $deviceProps); - } elseif ($getAction == "deletedevice") { + } elseif ($getAction === "deletedevice") { $id = Request::get('id', '', 'string'); $serial = Request::get('serial', '', 'string'); deleteDevice($id, $serial); - } elseif ($getAction == "getrule") { + } elseif ($getAction === "getrule") { $configid = Request::get('configid', '0', 'int'); getRule($configid); + } elseif ($getAction === "getidlist") { + echo getIDList(); } } @@ -166,3 +168,63 @@ function deleteDevice($id, $serial) 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)); +} diff --git a/modules-available/usblockoff/page.inc.php b/modules-available/usblockoff/page.inc.php index 8c32a699..d5334838 100644 --- a/modules-available/usblockoff/page.inc.php +++ b/modules-available/usblockoff/page.inc.php @@ -24,6 +24,8 @@ class Page_usblockoff extends Page $this->deleteConfig(); } elseif ($this->action === 'deleteRule') { $this->deleteRule(); + } elseif ($this->action === 'editRule') { + $this->editRule(); } } @@ -60,10 +62,18 @@ class Page_usblockoff extends Page Message::addError('invalid-rule-id'); return; } + $configid = Request::get("configid", ""); + $this->showEditRule($configid, $ruleid); + } + } - // TODO: Use another html page where stuff can be configured. - // WiP + private function editRule() { + $attributes = Request::post('attributes', '', 'string'); + $attributes = json_decode($attributes); + + foreach ($attributes as $a) { + // TODO: get attributes with $a['prop'] and $a['value'] and save or UPDATE it in the db. } } @@ -128,10 +138,11 @@ class Page_usblockoff extends Page $settings = array(); $setting = array(); $setting['title'] = "Action"; - $setting['select_list'] = array(array( - 'option' => 'allow', - 'active' => true, - ), + $setting['select_list'] = array( + array( + 'option' => 'allow', + 'active' => true, + ), array( 'option' => 'block', 'active' => false, @@ -154,7 +165,8 @@ class Page_usblockoff extends Page 'with-interface' => false); foreach ($ruleValues as $key => $value) { $settings[] = array( - 'settingHtml' => Render::parse('server-prop-bool', array('title' => Dictionary::translateFile('rule', $key), + 'settingHtml' => Render::parse('server-prop-bool', array( + 'title' => Dictionary::translateFile('rule', $key), 'helptext' => array('helptext' => Dictionary::translateFile('rule', $key . "_helptext")), 'property' => $key, 'currentvalue' => $value)), @@ -167,6 +179,155 @@ class Page_usblockoff extends Page )); } + private function showEditRule($configid, $ruleid) { + $attributes = array(); + + $query = Database::simpleQuery("SELECT * FROM `usb_rule_prop` WHERE ruleid=:ruleid", array( + 'ruleid' => $ruleid + )); + $idList = json_decode($this->getIDList(), true); + $pidList = array(); + + while ($attribute = $query->fetch(PDO::FETCH_ASSOC)) { + $attributesHtml = ''; + $attr = array( + 'title' => $attribute['prop'], // TODO: Dictionary::translateFile(' ... + 'property' => $attribute['prop'], + 'currentvalue' => $attribute['value'], + 'helptext' => "TODO", // TODO Dict bla bla.. + ); + + if ($attribute['prop'] === 'target') { + $attr['select_list'] = array( + array( + 'option' => 'allow', + 'active' => ($attribute['value'] === 'allow' ? true : false), + 'value' => 'allow', + ), + array( + 'option' => 'block', + 'active' => ($attribute['value'] === 'block' ? true : false), + 'value' => 'block', + ), + array( + 'option' => 'reject', + 'active' => ($attribute['value'] === 'reject' ? true : false), + 'value' => 'reject', + )); + + $attributesHtml = Render::parse('server-prop-dropdown', (array)$attr); + } else if ($attribute['prop'] === 'id') { + + $id = explode(':', $attribute['value']); + $vid = $id[0]; + $pid = $id[1]; + + // Vendor ID + $attr['title'] = "VID"; + $attr['select_list'] = array(); + $attr['toTextButton'] = true; + $attr['property'] = 'vid'; + + $attr['select_list'][] = array( + 'option' => $idList[$vid]['name'], + 'active' => true, + 'value' => $vid, + ); + + $attributesHtml = Render::parse('server-prop-dropdown', (array)$attr); + $attributes[] = array( + 'attributesHtml' => $attributesHtml + ); + + // Product ID + $attr['title'] = "PID"; + $attr['select_list'] = array(); + $attr['property'] = 'pid'; + + $attr['select_list'][] = array( + 'option' => $idList[$vid]['products'][$pid], + 'active' => true, + 'value' => $pid, + ); + + $attributesHtml = Render::parse('server-prop-dropdown', (array)$attr); + } else { + $attr['inputtype'] = 'text'; + $attributesHtml = Render::parse('server-prop-generic', (array)$attr); + } + $attributes[] = array( + 'attributesHtml' => $attributesHtml + ); + } + + Render::addTemplate('usb-edit-rule', array( + 'configid' => $configid, + 'attributes' => $attributes, + 'pidList' => array_values($pidList), + 'usbJson' => json_encode($idList), + )); + } + + /** + * 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), JSON_HEX_APOS); + } + private function addGenericRule($target = 'allow') { $settings = array(); $configid = Request::get("configid", ""); diff --git a/modules-available/usblockoff/templates/server-prop-dropdown.html b/modules-available/usblockoff/templates/server-prop-dropdown.html index 337c40aa..73a55467 100644 --- a/modules-available/usblockoff/templates/server-prop-dropdown.html +++ b/modules-available/usblockoff/templates/server-prop-dropdown.html @@ -1,12 +1,18 @@
-
+
+ {{#toTextButton}} + + {{/toTextButton}} +
{{#helptext}} diff --git a/modules-available/usblockoff/templates/usb-edit-rule.html b/modules-available/usblockoff/templates/usb-edit-rule.html new file mode 100644 index 00000000..ec14d5ab --- /dev/null +++ b/modules-available/usblockoff/templates/usb-edit-rule.html @@ -0,0 +1,82 @@ +
+ + + + + +
+
{{lang_editRules}}
+
+
+ + {{#attributes}} + {{{attributesHtml}}} + {{/attributes}} + +
+
+
+ +
+ Cancel + + +
+ +
+ + -- cgit v1.2.3-55-g7522