Skip to content

Instantly share code, notes, and snippets.

@jpriebe
Created June 28, 2016 01:03
Show Gist options
  • Save jpriebe/e000b63c1a25a04b09d235ab2cfe346e to your computer and use it in GitHub Desktop.
Save jpriebe/e000b63c1a25a04b09d235ab2cfe346e to your computer and use it in GitHub Desktop.
<?php
/**
* Authenticates to a ubiquiti EdgeOS router and enable/disable firewall rules
*
*/
class ubiquiti
{
private $_host = '';
private $_login_url = '';
private $_json_url = '';
private $_username = '';
private $_password = '';
private $_cookie_jar = '';
private $_http_headers = array ();
private $_x_csrf_token = '';
private $_last_response = '';
private $_last_response_obj = '';
private $_verbose = false;
public function get_last_response ()
{
return $this->_last_response;
}
public function get_last_response_obj ()
{
return $this->_last_response_obj;
}
public function __construct ($host, $username, $password)
{
$this->_host = $host;
$this->_login_url = 'https://' . $host . '/';
$this->_json_url = 'https://' . $host . '/api/edge/batch.json';
$this->_username = $username;
$this->_password = $password;
}
private function set_standard_curl_opts ($ch)
{
if ($this->_verbose)
{
curl_setopt ($ch, CURLOPT_VERBOSE, true);
curl_setopt ($ch, CURLOPT_STDERR, fopen('php://stderr', 'w'));
curl_setopt ($ch, CURLINFO_HEADER_OUT, true);
}
// this is mandatory, because we need to extract the X-CSRF-TOKEN from the cookie header
curl_setopt ($ch, CURLOPT_HEADER, true);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt ($ch, CURLOPT_COOKIESESSION, true);
curl_setopt ($ch, CURLOPT_COOKIEJAR, $this->_cookie_jar);
curl_setopt ($ch, CURLOPT_COOKIEFILE, $this->_cookie_jar);
$this->_http_headers[] = "Host: " . $this->_host;
$this->_http_headers[] = "Origin: https://" . $this->_host;
$this->_http_headers[] = "Referer: https://" . $this->_host . "/";
$this->_http_headers[] = "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36";
if ($this->_x_csrf_token)
{
$this->_http_headers[] = "X-CSRF-TOKEN: " . $this->_x_csrf_token;
}
curl_setopt ($ch, CURLOPT_HTTPHEADER, $this->_http_headers);
}
public function login ()
{
$post = array (
'username' => $this->_username,
'password' => $this->_password,
);
$this->_cookie_jar = tempnam('/tmp', 'ubiquiti_cj_');
$ch = curl_init ($this->_login_url);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt ($ch, CURLOPT_POST, 0);
$this->set_standard_curl_opts ($ch);
$response = curl_exec($ch);
if ($this->_verbose)
{
print "-------------------------------------------------------------------------------\n";
print "request headers:\n";
print "-------------------------------------------------------------------------------\n";
$info = curl_getinfo($ch);
print_r ($info['request_header']);
print "-------------------------------------------------------------------------------\n";
print "get form response:\n";
print "-------------------------------------------------------------------------------\n";
print substr ($response, 0, 1000);
}
// now go for the actual login POST
curl_setopt ($ch, CURLOPT_URL, $this->_login_url);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt ($ch, CURLOPT_POST, 1);
curl_setopt ($ch, CURLOPT_POSTFIELDS, $post);
curl_setopt ($ch, CURLOPT_POSTFIELDS, http_build_query ($post));
$this->_http_headers = array ('Content-Type: application/x-www-form-urlencoded');
$this->set_standard_curl_opts ($ch);
$response = curl_exec($ch);
if (preg_match ('#X-CSRF-TOKEN=\s*(\S+)#', $response, $matches))
{
$this->_x_csrf_token = $matches[1];
if ($this->_verbose)
{
print "X-CSRF-TOKEN: " . $this->_x_csrf_token . "\n";
}
}
if ($this->_verbose)
{
print "-------------------------------------------------------------------------------\n";
print "request headers:\n";
print "-------------------------------------------------------------------------------\n";
$info = curl_getinfo($ch);
print_r ($info['request_header']);
print "-------------------------------------------------------------------------------\n";
print "login response:\n";
print "-------------------------------------------------------------------------------\n";
print substr ($response, 0, 1000);
}
return $ch;
}
public function enable_fw_rule ($ruleset, $rule, $enable)
{
$ch = $this->login ();
if ($enable)
{
$body = <<<__TEXT__
{"DELETE":{"firewall":{"name":{"$ruleset":{"rule":{"$rule":{"disable":null}}},"__FORCE_ASSOC":true}}},"GET":{"firewall":{"name":{"$ruleset":{"rule":{"$rule":{}}},"__FORCE_ASSOC":true}}}}
__TEXT__;
}
else
{
$body = <<<__TEXT__
{"SET":{"firewall":{"name":{"$ruleset":{"rule":{"$rule":{"disable":null}}},"__FORCE_ASSOC":true}}},"GET":{"firewall":{"name":{"$ruleset":{"rule":{"$rule":{}}},"__FORCE_ASSOC":true}}}}
__TEXT__;
}
curl_setopt ($ch, CURLOPT_URL, $this->_json_url);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_POST, 1);
curl_setopt ($ch, CURLOPT_POSTFIELDS, $body);
$this->_http_headers = array ('Content-Type: application/json');
$this->set_standard_curl_opts ($ch);
$response = curl_exec($ch);
$this->_last_response = $response;
if ($this->_verbose)
{
print "-------------------------------------------------------------------------------\n";
print "request headers:\n";
print "-------------------------------------------------------------------------------\n";
$info = curl_getinfo($ch);
print_r ($info['request_header']);
print "-------------------------------------------------------------------------------\n";
print "body:\n";
print "-------------------------------------------------------------------------------\n";
print "$body\n";
print "-------------------------------------------------------------------------------\n";
print "enable_fw_rule response:\n";
print "-------------------------------------------------------------------------------\n";
print substr ($response, 0, 1000);
}
preg_match ('#(\{.+\})#', $response, $matches);
$json_string = $matches[1];
$o = json_decode ($json_string, true);
$this->_last_response_obj = $o;
if (!isset ($o['success']))
{
return false;
}
return $o['success'];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment