summaryrefslogtreecommitdiffstats
path: root/modules-available/remoteaccess/api.inc.php
blob: 2e1e4bf96690319cc8da38a4967069d2790a71c5 (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
<?php

$ip = $_SERVER['REMOTE_ADDR'];
if (substr($ip, 0, 7) === '::ffff:') $ip = substr($ip, 7);

$password = Request::post('password', false, 'string');
if ($password !== false) {
	$c = Database::queryFirst("SELECT machineuuid FROM machine WHERE clientip = :ip", ['ip' => $ip]);
	if ($c !== false) {
		Database::exec("INSERT INTO remoteaccess_machine (machineuuid, password)
				VALUES (:uuid, :passwd)
				ON DUPLICATE KEY UPDATE password = VALUES(password)", ['uuid' => $c['machineuuid'], 'passwd' => $password]);
	}
	exit;
}

$range = IpUtil::parseCidr(Property::get(RemoteAccess::PROP_ALLOWED_VNC_NET));
if ($range === false) {
	die('No allowed IP defined');
}
$iplong = ip2long($ip);
if (PHP_INT_SIZE === 4) {
	$iplong = sprintf('%u', $iplong);
}
if ($iplong < $range['start'] || $iplong > $range['end']) {
	die('Access denied');
}

Header('Content-Type: application/json');

$remoteLocations = RemoteAccess::getEnabledLocations();

if (empty($remoteLocations)) {
	$rows = [];
} else {
// TODO fail-counter for WOL, so we can ignore machines that apparently can't be woken up
// -> Reset counter in our ~poweron hook, but only if the time roughly matches a WOL attempt (within ~5 minutes)
	$rows = Database::queryAll("SELECT m.clientip, m.locationid, m.state, ram.password, ram.woltime FROM machine m
	LEFT JOIN remoteaccess_machine ram ON (ram.machineuuid = m.machineuuid AND (ram.password IS NOT NULL OR m.state <> 'IDLE'))
	LEFT JOIN runmode r ON (r.machineuuid = m.machineuuid)
	WHERE m.locationid IN (:locs)
		AND r.machineuuid IS NULL",
		['locs' => $remoteLocations]);

	$wolCut = time() - 90;
	foreach ($rows as &$row) {
		if (($row['state'] === 'OFFLINE' || $row['state'] === 'STANDBY') && $row['woltime'] > $wolCut) {
			$row['wol_in_progress'] = true;
		}
		settype($row['locationid'], 'int');
		unset($row['woltime']);
	}
}

$groups = Database::queryAll("SELECT g.groupid AS id, g.groupname AS name,
       GROUP_CONCAT(l.locationid) AS locationids, g.passwd AS password
	FROM remoteaccess_group g INNER JOIN remoteaccess_x_location l USING (groupid)
	WHERE g.active = 1
	GROUP BY g.groupid");
foreach ($groups as &$group) {
	$group['locationids'] = explode(',', $group['locationids']);
	if (empty($group['password'])) {
		unset($group['password']);
	}
	settype($group['id'], 'int');
	foreach ($group['locationids'] as &$lid) {
		settype($lid, 'int');
	}
}

$fakeid = 100000;
echo json_encode(['clients' => $rows, 'locations' => $groups]);

// WTF, this makes the server return a 500 -.-
//fastcgi_finish_request();

RemoteAccess::ensureMachinesRunning();