summaryrefslogtreecommitdiffstats
path: root/modules-available/usblockoff/api.inc.php
blob: 52a98b67a0bcb5e3b8f97fe10698c8e7f1233cd9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
<?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));
}