User:Haravikk Mistral/RegionVerification
From OpenSimulator
Contents |
Overview
Problem
When receiving an HTTP request from a scripted object within an Open Simulator region, there is currently no means of verifying whether the request came from a legitimate source. For Second Life this is possible with a reverse DNS lookup on the IP address, if it has a valid simXXXX.<grid>.lindenlab.com address you can confirm that the request came from a legitimate source, but such a technique is not possible with Open Simulator based grids.
Proposed Solution
This proposal is to provide a call-back mechanism with which a web-service, knowing the source grid, region name and simulator IP address, can query the source grid to verify whether the IP address and region name are valid, i.e- asking the grid to confirm that it has a simulator with a given IP address, hosting the given region name.
Detailed Design
The Callback Service
Essentially what this feature boils down to is a callback service, implemented in much the same way as the GridInfo protocol. The proposed protocol would take the form:
http://example.org:9000/verify_region?name=Some%20Region&ip=123.123.123.123
To which the server would respond simply 'OK' if there exists a region named "Some Region", hosted by a simulator with IP address 123.123.123.123, or else 'NO' if there exists no region by that name assigned to that IP. Thus a web service knows either that the combo exists (OK), doesn't exist (NO) or that the grid cannot or will not verify it (any other response).
Example
The following example assumes the presence of the X-OpenSim-Location as proposed here:
<?php function fetch(array $array, $key, $default = null) { return (isset($array[$key])) ? $array[$key] : $default; } // TODO: Verify basic headers first (since they require no callbacks) if (isset($_SERVER['HTTP_X_OPENSIM_LOCATION'])) { $uri = parse_url($_SERVER['HTTP_X_OPENSIM_LOCATION']); if ((fetch($uri, 'scheme') == 'x-grid-info') || !$host = fetch($uri, 'host')) { die('Invalid URI'); } $grid_address = $host . (($port = fetch($uri, 'port')) ? ":$port" : ''); if (!preg_match(';^/region/([0-9]*[^0-9/]+[^/]*)((?:/([0-9]+)(?:/([0-9]+)(?:/([0-9]+))?)?)?;i', fetch($uri, 'path'), $match)) { die('Invalid URI'); } $region_name = urldecode($match[1]); $coords = []; if (strlen($match[2]) && strlen($match[3])) { // 2-D coords $coords = [(int)$match[2], (int)$match[3]]; if (strlen($match[4])) { $coords[] = (int)$match[4]; } } // TODO: Look up $grid_address and $_SERVER['REMOTE_ADDR'] in database, if they have been confirmed recently then don't do it again // Host is unconfirmed, try to confirm it now $curl = curl_init("http://$grid_address/verify_region?region=" . urlencode($region_name) . '&ip=' . $_SERVER['REMOTE_ADDR']); curl_setopts_array($curl = [CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION => true]); $response = curl_exec($curl); if ((curl_errno($curl) != 0) || (curl_getinfo($curl, CURLINFO_HTTP_CODE) != 200)) { die('Error occurred verifying region'); } curl_close($curl); switch($response) { case 'OK': // The grid confirmed the region and IP combo, we should cache it in our database to avoid repeated lookups break; case 'NO': die('Invalid region/IP'); break; default: // TODO: Use some kind of fallback or "untrusted" behaviour instead die('Unable to verify region/IP'); break; } }
Alternatives Considered
An alternative protocol for the verification would be to have the grid return some information about a region in an XML format. For example, a request for "Some Region" could return details such as its map location and IP, with the web-service extracting the IP itself to confirm. However, this raises the question of how much data should be revealed, and whether the ability to scrape by region name is desirable or not.
The proposed system above, while limited in the information it returns, requires the web-service to posses a valid region name and IP address, and can do nothing more than confirm that they are valid; if the IP address is incorrect then no data is returned (or some error, anything other than OK is considered to mean the combo was invalid or the operation is unsupported).
A DDOS attack against the grid servie is a very real possibility. A solution needs to include ratelimiting