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