No more warnings

This commit is contained in:
Geoffrey Frogeye 2019-04-22 21:53:26 +02:00
parent 77b77a3c70
commit 62df3fddb5
2 changed files with 118 additions and 77 deletions

186
index.php
View file

@ -2,19 +2,35 @@
require __DIR__ . '/vendor/autoload.php'; require __DIR__ . '/vendor/autoload.php';
require_once('config.inc.php'); require_once 'config.inc.php';
if (!array_key_exists('REDIRECT_URL', $_SERVER) || rtrim($_SERVER['REDIRECT_URL'], '/') == '') { if (!array_key_exists('REDIRECT_URL', $_SERVER)
include('default.php'); || rtrim($_SERVER['REDIRECT_URL'], '/') == ''
) {
include 'default.php';
exit; exit;
} }
$route = explode('/', trim(substr(explode('?', $_SERVER['REDIRECT_URL'])[0], strrpos($_SERVER['SCRIPT_NAME'], '/')), '/')); $route = explode(
'/',
trim(
substr(
explode(
'?',
$_SERVER['REDIRECT_URL']
)[0],
strrpos($_SERVER['SCRIPT_NAME'], '/')
), '/'
)
);
$meth = $_SERVER['REQUEST_METHOD']; $meth = $_SERVER['REQUEST_METHOD'];
header('Content-Type: text/plain'); header('Content-Type: text/plain');
// $FQDN_REGEX = '[a-zA-Z0-9\p{L}][a-zA-Z0-9\p{L}-\.]{1,61}[a-zA-Z0-9\p{L}]\.[a-zA-Z0-9\p{L}][a-zA-Z\p{L}-]*[a-zA-Z0-9\p{L}]+'; // From http://stackoverflow.com/a/38477788/2766106
$FQDN_REGEX = '.+'; // From http://stackoverflow.com/a/38477788/2766106 // $FQDN_REGEX = '[a-zA-Z0-9\p{L}][a-zA-Z0-9\p{L}-\.]{1,61}[a-zA-Z0-9\p{L}]\.\
// [a-zA-Z0-9\p{L}][a-zA-Z\p{L}-]*[a-zA-Z0-9\p{L}]+';
// // From http://stackoverflow.com/a/38477788/2766106
$FQDN_REGEX = '.+'; // TODO
$IP4_REGEX = '/^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}/'; // From http://stackoverflow.com/a/5284410 $IP4_REGEX = '/^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}/'; // From http://stackoverflow.com/a/5284410
$SSH_KEY_REGEX = '/^(ssh-(rsa|ed25519|dss)|ecdsa-sha2-nistp256) [a-zA-Z0-9+=\/]+/'; $SSH_KEY_REGEX = '/^(ssh-(rsa|ed25519|dss)|ecdsa-sha2-nistp256) [a-zA-Z0-9+=\/]+/';
@ -25,7 +41,7 @@ $machineArgs = array(
'repeatable' => false, 'repeatable' => false,
'optional' => false 'optional' => false
), ),
'host' => array( # DEPRECATED 'host' => array( // DEPRECATED
'type' => 'string', 'type' => 'string',
'pattern' => '/^'.$FQDN_REGEX.'(:\d+)?$/', 'pattern' => '/^'.$FQDN_REGEX.'(:\d+)?$/',
'repeatable' => true, 'repeatable' => true,
@ -94,19 +110,18 @@ function computeDiff($from, $to)
$n1 = count($from); $n1 = count($from);
$n2 = count($to); $n2 = count($to);
for ($j = -1; $j < $n2; $j++) $dm[-1][$j] = 0; for ($j = -1; $j < $n2; $j++) {
for ($i = -1; $i < $n1; $i++) $dm[$i][-1] = 0; $dm[-1][$j] = 0;
for ($i = 0; $i < $n1; $i++) }
{ for ($i = -1; $i < $n1; $i++) {
for ($j = 0; $j < $n2; $j++) $dm[$i][-1] = 0;
{ }
if ($from[$i] == $to[$j]) for ($i = 0; $i < $n1; $i++) {
{ for ($j = 0; $j < $n2; $j++) {
if ($from[$i] == $to[$j]) {
$ad = $dm[$i - 1][$j - 1]; $ad = $dm[$i - 1][$j - 1];
$dm[$i][$j] = $ad + 1; $dm[$i][$j] = $ad + 1;
} } else {
else
{
$a1 = $dm[$i - 1][$j]; $a1 = $dm[$i - 1][$j];
$a2 = $dm[$i][$j - 1]; $a2 = $dm[$i][$j - 1];
$dm[$i][$j] = max($a1, $a2); $dm[$i][$j] = max($a1, $a2);
@ -116,22 +131,17 @@ function computeDiff($from, $to)
$i = $n1 - 1; $i = $n1 - 1;
$j = $n2 - 1; $j = $n2 - 1;
while (($i > -1) || ($j > -1)) while (($i > -1) || ($j > -1)) {
{ if ($j > -1) {
if ($j > -1) if ($dm[$i][$j - 1] == $dm[$i][$j]) {
{
if ($dm[$i][$j - 1] == $dm[$i][$j])
{
$diffValues[] = $to[$j]; $diffValues[] = $to[$j];
$diffMask[] = 1; $diffMask[] = 1;
$j--; $j--;
continue; continue;
} }
} }
if ($i > -1) if ($i > -1) {
{ if ($dm[$i - 1][$j] == $dm[$i][$j]) {
if ($dm[$i - 1][$j] == $dm[$i][$j])
{
$diffValues[] = $from[$i]; $diffValues[] = $from[$i];
$diffMask[] = -1; $diffMask[] = -1;
$i--; $i--;
@ -152,7 +162,8 @@ function computeDiff($from, $to)
return array('values' => $diffValues, 'mask' => $diffMask); return array('values' => $diffValues, 'mask' => $diffMask);
} }
function requireToken() { function requireToken()
{
global $TOTP; global $TOTP;
if (isset($_SERVER['HTTP_X_TOTP']) && $_SERVER['HTTP_X_TOTP']) { if (isset($_SERVER['HTTP_X_TOTP']) && $_SERVER['HTTP_X_TOTP']) {
if (!$TOTP->verify($_SERVER['HTTP_X_TOTP'], null, 1)) { if (!$TOTP->verify($_SERVER['HTTP_X_TOTP'], null, 1)) {
@ -166,7 +177,8 @@ function requireToken() {
} }
function requireSigned() { function requireSigned()
{
if ($_SERVER['SSL_CLIENT_VERIFY'] == 'NONE') { if ($_SERVER['SSL_CLIENT_VERIFY'] == 'NONE') {
http_response_code(401); http_response_code(401);
die("Authorization required\n"); die("Authorization required\n");
@ -176,7 +188,8 @@ function requireSigned() {
} }
} }
function logActivity($text) { function logActivity($text)
{
$ex = explode("\n", $text); $ex = explode("\n", $text);
$t = ''; $t = '';
foreach ($ex as $line) { foreach ($ex as $line) {
@ -188,11 +201,13 @@ function logActivity($text) {
file_put_contents('machines.log', $t, FILE_APPEND); file_put_contents('machines.log', $t, FILE_APPEND);
} }
function save($elname, $elements) { function save($elname, $elements)
{
file_put_contents($elname.'.ser.db', serialize($elements)); file_put_contents($elname.'.ser.db', serialize($elements));
} }
function load($elname) { function load($elname)
{
if (!file_exists($elname.'.ser.db')) { if (!file_exists($elname.'.ser.db')) {
save($elname, []); save($elname, []);
} }
@ -201,29 +216,24 @@ function load($elname) {
// Get keys that can be used to connect // Get keys that can be used to connect
// to the network // to the network
function getKeys($network) { function getKeys($network)
{
global $SSH_KEY_REGEX; global $SSH_KEY_REGEX;
global $DOMAIN; global $DOMAIN;
$machines = load('machine'); $machines = load('machine');
$networks = load('network'); $networks = load('network');
$t = ''; $t = '';
foreach ($machines as $machineName => $machine) { foreach ($machines as $machineName => $machine) {
if ( if ((isset($machine['network']) && isset($networks[$machine['network']]))
( && (($networks[$machine['network']]['secure'] == 'true')
isset($machine['network']) || ($network && isset($network['allowed'])
&& isset($networks[$machine['network']]) && in_array($machine['network'], $network['allowed'])))
) && (
(
$networks[$machine['network']]['secure'] == 'true'
) || (
$network
&& isset($network['allowed'])
&& in_array($machine['network'], $network['allowed'])
)
)
) { ) {
if (isset($machine['userkey']) && preg_match($SSH_KEY_REGEX, $machine['userkey'], $matches)) { if (isset($machine['userkey'])
$t .= $matches[0].' '.$machineName.'@'.($machine['network'] ? $machine['network'].'.' : '').$DOMAIN."\n"; && preg_match($SSH_KEY_REGEX, $machine['userkey'], $matches)
) {
$t .= $matches[0].' '.$machineName.'@'.($machine['network']
? $machine['network'].'.' : '').$DOMAIN."\n";
} }
} }
} }
@ -232,7 +242,8 @@ function getKeys($network) {
// Display an element in a simple, easily-editable, // Display an element in a simple, easily-editable,
// easily-diffable, plain text format // easily-diffable, plain text format
function displayElement($element, $elementArgs) { function displayElement($element, $elementArgs)
{
$t = ''; $t = '';
ksort($element); ksort($element);
foreach ($element as $arg => $value) { foreach ($element as $arg => $value) {
@ -259,7 +270,8 @@ function displayElement($element, $elementArgs) {
// Verifiy if one argument is valid // Verifiy if one argument is valid
// return false if valid, string with // return false if valid, string with
// description if not // description if not
function argAssertOne($argData, $data) { function argAssertOne($argData, $data)
{
// Type casting // Type casting
switch ($argData['type']) { switch ($argData['type']) {
case 'boolean': case 'boolean':
@ -296,9 +308,10 @@ function argAssertOne($argData, $data) {
return false; return false;
} }
function argAssert($arg, $data, $args) { function argAssert($arg, $data, $args)
{
$argData = $args[$arg]; $argData = $args[$arg];
# TODO oneof // TODO oneof
if (!$data) { if (!$data) {
if ($argData['optional']) { if ($argData['optional']) {
@ -330,8 +343,10 @@ function argAssert($arg, $data, $args) {
// Hooks // Hooks
// //
function updateGitKeys($api, $keys) { function updateGitKeys($api, $keys)
function apiRequest($api, $route, $meth = 'GET', $data = null) { {
function apiRequest($api, $route, $meth = 'GET', $data = null)
{
$ch = curl_init(); $ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $api['api'].'/'.$route); curl_setopt($ch, CURLOPT_URL, $api['api'].'/'.$route);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $meth); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $meth);
@ -342,10 +357,12 @@ function updateGitKeys($api, $keys) {
} else { } else {
$dataStr = ''; $dataStr = '';
} }
curl_setopt($ch, CURLOPT_HTTPHEADER, array( $authHeader = isset($api['authHeader']) ?
(isset($api['authHeader']) ? $api['authHeader'] : 'Authorization: token').' '.$api['token'], $api['authHeader'] : 'Authorization: token';
'Content-Type: application/json', curl_setopt(
)); $ch, CURLOPT_HTTPHEADER, array($authHeader.' '.$api['token'],
'Content-Type: application/json')
);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$raw = curl_exec($ch); $raw = curl_exec($ch);
curl_close($ch); curl_close($ch);
@ -376,10 +393,12 @@ function updateGitKeys($api, $keys) {
} }
} }
if (!$found) { if (!$found) {
apiRequest($api, 'user/keys', 'POST', array( apiRequest(
$api, 'user/keys', 'POST', array(
"title" => ltrim(preg_replace($SSH_KEY_REGEX, '', $key)), "title" => ltrim(preg_replace($SSH_KEY_REGEX, '', $key)),
"key" => $key "key" => $key
)); )
);
} }
} }
@ -409,7 +428,7 @@ case 'network':
echo $key."\n"; echo $key."\n";
} }
// GET /element/{name} // GET /element/{name}
} elseif (count($route) == 2 && $meth == 'GET') { } elseif (count($route) == 2 && $meth == 'GET') {
if ($elname != 'machine') { if ($elname != 'machine') {
requireSigned(); requireSigned();
@ -423,7 +442,7 @@ case 'network':
die("Unknown $elname\n"); die("Unknown $elname\n");
} }
// POST /element // POST /element
} elseif (count($route) == 1 && $meth == 'POST') { } elseif (count($route) == 1 && $meth == 'POST') {
if (isset($_SERVER['HTTP_X_TOTP']) && $elname == 'machine') { if (isset($_SERVER['HTTP_X_TOTP']) && $elname == 'machine') {
$restrained = true; $restrained = true;
@ -466,10 +485,12 @@ case 'network':
$elements[$name] = $element; $elements[$name] = $element;
save($elname, $elements); save($elname, $elements);
http_response_code(201); http_response_code(201);
logActivity("Created $elname \"$name\"\n".displayElement($element, $elementArgs)); logActivity(
"Created $elname \"$name\"\n".displayElement($element, $elementArgs)
);
} }
// POST /element/{name} // POST /element/{name}
} elseif (count($route) == 2 && $meth == 'POST') { } elseif (count($route) == 2 && $meth == 'POST') {
requireSigned(); requireSigned();
foreach ($_POST as $arg => $value) { foreach ($_POST as $arg => $value) {
@ -493,13 +514,17 @@ case 'network':
$element[$arg] = $_POST[$arg]; $element[$arg] = $_POST[$arg];
} }
} }
$oldEls = explode("\n", displayElement($elements[$route[1]], $elementArgs)); $oldEls = explode(
"\n", displayElement($elements[$route[1]], $elementArgs)
);
$elements[$route[1]] = $element; $elements[$route[1]] = $element;
save($elname, $elements); save($elname, $elements);
http_response_code(204); http_response_code(204);
$newEls = explode("\n", displayElement($elements[$route[1]], $elementArgs)); $newEls = explode(
"\n", displayElement($elements[$route[1]], $elementArgs)
);
$diff = computeDiff($oldEls, $newEls); $diff = computeDiff($oldEls, $newEls);
$t = ''; $t = '';
foreach ($diff['values'] as $i => $line) { foreach ($diff['values'] as $i => $line) {
@ -519,7 +544,7 @@ case 'network':
die("Unknown $elname\n"); die("Unknown $elname\n");
} }
// DELETE /element/{name} // DELETE /element/{name}
} elseif (count($route) == 2 && $meth == 'DELETE') { } elseif (count($route) == 2 && $meth == 'DELETE') {
requireSigned(); requireSigned();
$elements = load($elname); $elements = load($elname);
@ -558,14 +583,16 @@ case 'akey':
// GET /akey/{network}?signature // GET /akey/{network}?signature
if (isset($_GET['signature'])) { if (isset($_GET['signature'])) {
echo file_get_contents('akey/'.$networkName.'.authorized_keys.sha256'); echo file_get_contents(
'akey/'.$networkName.'.authorized_keys.sha256'
);
// GET /akey/{network}?unsigned // GET /akey/{network}?unsigned
} elseif (isset($_GET['unsigned'])) { } elseif (isset($_GET['unsigned'])) {
requireSigned(); requireSigned();
echo getKeys($networkName ? $network : null); echo getKeys($networkName ? $network : null);
// GET /akey/{network} // GET /akey/{network}
} else { } else {
echo file_get_contents('akey/'.$networkName.'.authorized_keys'); echo file_get_contents('akey/'.$networkName.'.authorized_keys');
} }
@ -574,7 +601,7 @@ case 'akey':
die("Unknown network\n"); die("Unknown network\n");
} }
// PUT /akey/{network} // PUT /akey/{network}
} elseif ((count($route) == 1 || count($route) == 2) && $meth == 'PUT') { } elseif ((count($route) == 1 || count($route) == 2) && $meth == 'PUT') {
requireSigned(); requireSigned();
if (count($route) == 2) { if (count($route) == 2) {
@ -589,7 +616,10 @@ case 'akey':
} }
$sign = file_get_contents('php://input'); $sign = file_get_contents('php://input');
file_put_contents('akey/'.$networkName.'.authorized_keys', getKeys($networkName ? $network : null)); file_put_contents(
'akey/'.$networkName.'.authorized_keys',
getKeys($networkName ? $network : null)
);
file_put_contents('akey/'.$networkName.'.authorized_keys.sha256', $sign); file_put_contents('akey/'.$networkName.'.authorized_keys.sha256', $sign);
if (array_key_exists($networkName, $GIT_APIS)) { if (array_key_exists($networkName, $GIT_APIS)) {
@ -618,7 +648,9 @@ case 'config':
$networks = load('network'); $networks = load('network');
if (isset($machines[$machineName])) { if (isset($machines[$machineName])) {
$machine = $machines[$machineName]; $machine = $machines[$machineName];
if (!isset($machine['network']) || !isset($networks[$machine['network']])) { if (!isset($machine['network'])
|| !isset($networks[$machine['network']])
) {
break; break;
} }
$network = $network[$machine['network']]; $network = $network[$machine['network']];
@ -644,7 +676,7 @@ case 'config':
// Activity log // Activity log
case 'log': case 'log':
if (count($route) == 1 && $meth == 'GET') { if (count($route) == 1 && $meth == 'GET') {
requireSigned(); requireSigned();
if (!isset($_GET['from']) || !$from = intval($_GET['from'])) { if (!isset($_GET['from']) || !$from = intval($_GET['from'])) {
$from = 0; $from = 0;
@ -665,13 +697,13 @@ case 'log':
break; break;
case 'totp': case 'totp':
global $TOTP; global $TOTP;
if (count($route) == 1 && $meth == 'GET') { if (count($route) == 1 && $meth == 'GET') {
requireSigned(); requireSigned();
echo $TOTP->getProvisioningUri(); echo $TOTP->getProvisioningUri();
} }
break; break;
case 'cert': case 'cert':
if (count($route) == 1 && $meth == 'GET') { if (count($route) == 1 && $meth == 'GET') {
echo file_get_contents('machines.crt'); echo file_get_contents('machines.crt');
} }
break; break;

9
ruleset.xml Normal file
View file

@ -0,0 +1,9 @@
<?xml version="1.0"?>
<ruleset name="Custom">
<description>Machines coding standard</description>
<rule ref="PEAR">
<exclude name="PEAR.Commenting.FileComment.Missing"/>
<exclude name="PEAR.Commenting.FunctionComment.Missing"/>
<exclude name="PEAR.Commenting.FunctionComment.WrongStyle"/>
</rule>
</ruleset>