diff --git a/web/application/controllers/base.php b/web/application/controllers/base.php index a8b287b..96c7a9b 100644 --- a/web/application/controllers/base.php +++ b/web/application/controllers/base.php @@ -24,20 +24,8 @@ abstract class base extends \system\engine\HF_Controller { } protected function setupUser() { - if (isset($_COOKIE["session"])) { - $validSession = Sessions::getByField("sessionid", $_COOKIE["session"]); - if ($validSession) { - try { - $this->session = $validSession[0]; - $this->sessionData = json_decode($this->session->data); - if ($this->sessionData == null) { - return; - } - $this->user = \application\models\Users::getByField("id", $this->sessionData->userId)[0]; - } catch (\Exception $e) { - } - } else { - } + if ($this->sessionData) { + $this->user = \application\models\Users::getByField("id", $this->sessionData->userId)[0]; } } @@ -63,12 +51,25 @@ abstract class base extends \system\engine\HF_Controller { return false; } - protected function login() { - if (!$this->user) { - header("Location: /login"); - - } else { - $bool = true; + protected function setupSession() { + if (isset($_COOKIE["session"])) { + $validSession = Sessions::getByField("sessionid", $_COOKIE["session"]); + if ($validSession) { + try { + $this->session = $validSession[0]; + $this->sessionData = json_decode($this->session->data); + } catch (\Exception $e) { } + } else { + $bytes = openssl_random_pseudo_bytes(10, $bool); + $sessionId = bin2hex($bytes); + $this->session = new Sessions(); + $this->session->ip = $_SERVER["REMOTE_ADDR"]; + $this->session->userAgent = $_SERVER["HTTP_USER_AGENT"]; + $this->session->sessionid = $sessionId; + $this->session->save(); + setcookie("session", $sessionId, 2147483647, "/"); + } + } else { $bytes = openssl_random_pseudo_bytes(10, $bool); $sessionId = bin2hex($bytes); $this->session = new Sessions(); @@ -76,7 +77,13 @@ abstract class base extends \system\engine\HF_Controller { $this->session->userAgent = $_SERVER["HTTP_USER_AGENT"]; $this->session->sessionid = $sessionId; $this->session->save(); - setcookie("session", $sessionId, 2147483647); + setcookie("session", $sessionId, 2147483647, "/"); + } + } + + protected function login() { + if (!$this->user) { + header("Location: /login"); } } @@ -101,8 +108,9 @@ abstract class base extends \system\engine\HF_Controller { \vendor\DB\DB::$c = $this->pdo; } + $this->setupSession(); $this->setupUser(); - if ($this->loginRequired) { + if ($this->loginRequired && !$this->user) { $this->login(); } } diff --git a/web/application/controllers/history.php b/web/application/controllers/history.php index 1895267..ac115ce 100644 --- a/web/application/controllers/history.php +++ b/web/application/controllers/history.php @@ -1,16 +1,18 @@ view_private == 1 && !$this->user) { - header("Location: /login"); + $this->login(); return false; } if ($job->view_private == 1 && $this->user && $this->user->id != $job->user_id) { - header("Location: /"); + $this->login(); return false; } return true; @@ -18,25 +20,33 @@ class history extends base public function view($id) { $idArr = explode("-", $id); - if (count($idArr) == 2) { - /** @var \application\models\Histories $historyArr */ - $historyArr = \application\models\Histories::getByField("jobs_id", $idArr[1]); - /** @var \application\models\Jobs[] $jobObject */ - $jobObject = \application\models\Jobs::getByField("id", $idArr[1]); - if ($this->checkAccess($jobObject[0])) { - echo $this->loadRender("history.html", ["jobid" => $idArr[1], "histories" => $historyArr]); - } - } + try { + if (count($idArr) == 2) { + /** @var \application\models\Histories $historyArr */ + //$historyArr = \application\models\Histories::getByField("jobs_id", $idArr[1]); + $historyArr = DB::fetchObject("SELECT * FROM histories WHERE jobs_id = ? ORDER BY run_date DESC", '\application\models\Histories', [$idArr[1]]); + /** @var \application\models\Jobs[] $jobObject */ + $jobObject = \application\models\Jobs::getByField("id", $idArr[1]); + if ($this->checkAccess($jobObject[0])) { + echo $this->loadRender("history.html", ["job" => $jobObject[0], "histories" => $historyArr]); + } + } + } catch (\Exception $e) { + header("Location: /"); + } } public function log($jobId, $logId) { - $jobObject = \application\models\Jobs::getByField("id", $jobId); - if ($this->checkAccess($jobObject[0])) { - /** @var \application\models\Histories[] $historyArr */ - $historyArr = \application\models\Histories::getByField("id", $logId); - echo $historyArr[0]->output; - } - - + try { + $jobObject = \application\models\Jobs::getByField("id", $jobId); + if ($this->checkAccess($jobObject[0])) { + /** @var \application\models\Histories[] $historyArr */ + $historyArr = \application\models\Histories::getByField("id", $logId); + header("Content-Type: text/plain"); + echo $historyArr[0]->output; + } + } catch (\Exception $e) { + header("Location: /"); + } } } \ No newline at end of file diff --git a/web/application/controllers/job.php b/web/application/controllers/job.php index d70d50a..2387302 100644 --- a/web/application/controllers/job.php +++ b/web/application/controllers/job.php @@ -3,7 +3,9 @@ class job extends base { public function add() { if (!isset($_POST["jobName"])) { - echo $this->loadRender("add.html"); + $sharedkey = bin2hex(openssl_random_pseudo_bytes(16, $bool)); + $hash = bin2hex(openssl_random_pseudo_bytes(32, $bool)); + echo $this->loadRender("add.html", ["hash" => $hash, "sharedkey" => $sharedkey]); } else { $data = $_POST; $data["user_id"] = $this->user->id; @@ -38,4 +40,19 @@ class job extends base { } } + public function force($id) { + $job = \application\models\Jobs::getByField("id", $id); + if ($job && $job[0]->user_id == $this->user->id) { //secuirty check + if ($job[0]->force_run == 1) { + $job[0]->force_run = 0; + } else { + $job[0]->force_run = 1; + } + $job[0]->save(); + header("Location: /"); + } else { + header("Location: /"); + } + } + } \ No newline at end of file diff --git a/web/application/controllers/service.php b/web/application/controllers/service.php new file mode 100644 index 0000000..a25fea7 --- /dev/null +++ b/web/application/controllers/service.php @@ -0,0 +1,95 @@ + {"nonce": "randomString", "message": "cipherText", "signature": "abcdef"} + * Signature will be a sha256 of the message pre-encrypt with nonce appended to the end + * ie + * {JSON} + "|" nonce + "|" + sharedhash + * Note: sharedhash should NOT be the sharedkey that is used to encrypt the message + * + * + * Unencrypted cipherText will look like + * {"output": "stdout of run", "run_date": "2015-01-01", "time_taken": 10, "result": 0} + * Just like in most modern programs - a result of anything but 0 indicates an error + * + * @param $jobId + */ + public function upload($jobId) { + if ($jobId && is_int($jobId)) { + /** @var \application\models\Jobs $job */ + $job = \application\models\Jobs::getByField("id", $jobId)[0]; + //decrypt message + $data = json_decode($_POST["data"]); + $rawMessage = aes_decrypt($job->sharedkey,$data["message"]); + + // if decryption was successful - + // check signature + if (hash("sha256", $rawMessage . $data["nonce"] . $job->hash) == $data["signature"]) { + // the message is verified + $messageJson = json_decode($rawMessage); + $history = \application\models\Histories::create($messageJson); + $history->jobs_id = $job->id; + } + } + } + + public function run() { + if (in_array($_SERVER["REMOTE_ADDR"], $this->config["ACCEPTED_IPS"])) { // not very secure - but worst case they fire off the run early + if (!file_exists("/tmp/kritbot")) { + touch("/tmp/kritbot"); + /** @var \application\models\Jobs[] $jobs */ + $jobs = DB::fetchObject("SELECT * FROM jobs", "\\application\\models\\Jobs"); + foreach($jobs as $job) { + if ($job->runType == 1) { + $cron = Cron\CronExpression::factory($job->cron); + if ($cron->isDue() || $job->force_run == 1) { + $output = []; + $returnVar = 0; + + $start = microtime(true); + // grumble grumble something something windows + if (stripos(php_uname("s"), "Win") !== false) { + file_put_contents("/tmp/kritscript.bat", $job->runScript); + exec("c:\\windows\\system32\\cmd.exe /c c:/tmp/kritscript.bat", $output, $returnVar); + } else { + file_put_contents("/tmp/kritscript", $job->runScript); + exec("/tmp/kritscript", $output, $returnVar); + chmod("/tmp/kritscript", 0777); + } + $end = microtime(true); + $delta = $end - $start; + $scriptOutput = implode("\n", $output); + if ($returnVar != 0) { + if (stripos(php_uname("s"), "Win") !== false) { + file_put_contents("/tmp/kritscript.bat", $job->failScript); + exec("c:\\windows\\system32\\cmd.exe /c c:/tmp/kirtscript.bat"); + } else { + file_put_contents("/tmp/kritscript", $job->failScript); + exec("/tmp/kritscript", $output, $returnVar); + chmod("/tmp/kritscript", 0777); + } + } + $historyObj = new \application\models\Histories(); + $historyObj->output = $scriptOutput; + $historyObj->result = $returnVar; + $historyObj->time_taken = $delta; + $historyObj->jobs_id = $job->id; + $now = date("Y-m-d H:i:s"); + $historyObj->run_date = $now; + $historyObj->save(); + $job->force_run = 0; + $job->last_run = $now; + $job->last_result = $returnVar; + $job->save(); + } + } + } + unlink("/tmp/kritbot"); + } + } + } +} \ No newline at end of file diff --git a/web/application/migrations/2.php b/web/application/migrations/2.php index 51d4d67..4a63ec6 100644 --- a/web/application/migrations/2.php +++ b/web/application/migrations/2.php @@ -12,10 +12,13 @@ DB::query("CREATE TABLE jobs ( failScript TEXT, last_run DATETIME, last_result INTEGER, - api_key VARCHAR(255), + hash VARCHAR(255), + sharedkey VARCHAR(32), view_private INTEGER, - user_id INTEGER + user_id INTEGER, + comments TEXT, + force_run INTEGER );"); -DB::query("INSERT INTO jobs VALUES (null, 'test', 1, 'TESTING', '*/5 * * *', 'TESTING', '2015-01-01', 0, '', 0, 1)"); -DB::query("INSERT INTO jobs VALUES (null, 'test2', 1, 'TESTING', '*/5 * * *', 'TESTING', '2015-01-01', 0, '', 1, 1)"); \ No newline at end of file +DB::query("INSERT INTO jobs VALUES (null, 'test', 1, 'TESTING', '*/5 * * * *', 'TESTING', '2015-01-01', 0, '123', '123', 0, 1, 'TEST COMMENT', 0)"); +DB::query("INSERT INTO jobs VALUES (null, 'test2', 1, 'TESTING', '*/5 * * * *', 'TESTING', '2015-01-01', 0, '321', '321', 1, 1, 'TEST COMMENT2', 0)"); \ No newline at end of file diff --git a/web/application/migrations/3.php b/web/application/migrations/3.php index 6338d3f..832d0c8 100644 --- a/web/application/migrations/3.php +++ b/web/application/migrations/3.php @@ -8,7 +8,7 @@ DB::query("CREATE TABLE histories ( output TEXT, jobs_id INTEGER, run_date DATETIME, - time_taken INTEGER, + time_taken DECIMAL(10,5), result INTEGER );"); diff --git a/web/application/models/Jobs.php b/web/application/models/Jobs.php index 3ded424..47b5894 100644 --- a/web/application/models/Jobs.php +++ b/web/application/models/Jobs.php @@ -11,8 +11,11 @@ class Jobs extends \system\engine\HF_Model { public $last_run; public $last_result; public $user_id; - public $api_key; + public $hash; + public $sharedkey; public $view_private; + public $force_run; + public $comments; public $h2o_safe = true; diff --git a/web/application/views/add.html b/web/application/views/add.html index 3473649..05d91af 100644 --- a/web/application/views/add.html +++ b/web/application/views/add.html @@ -21,14 +21,14 @@