kritbit

kritbit Commit Details


Date:2015-11-20 22:33:31 (9 years 1 month ago)
Author:Natalie Adams
Branch:master
Commit:17c98a46444b856f5d282c5b47042b776c30e4d7
Parents: 0a78b3f29a2f0d8087f4d59dbc8f94afa040298e
Message:adding AES Updating DB library adding a lot of functionality

Changes:

File differences

web/application/controllers/base.php
2424
2525
2626
27
28
29
30
31
32
33
34
35
36
37
38
39
40
27
28
4129
4230
4331
......
6351
6452
6553
66
67
68
69
70
71
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
7273
7374
7475
......
7677
7778
7879
79
80
81
82
83
84
85
86
8087
8188
8289
......
101108
102109
103110
111
104112
105
113
106114
107115
108116
}
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];
}
}
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();
$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");
}
}
\vendor\DB\DB::$c = $this->pdo;
}
$this->setupSession();
$this->setupUser();
if ($this->loginRequired) {
if ($this->loginRequired && !$this->user) {
$this->login();
}
}
web/application/controllers/history.php
11
22
3
4
35
46
57
68
79
810
9
11
1012
1113
1214
13
15
1416
1517
1618
......
1820
1921
2022
21
22
23
24
25
26
27
28
29
23
24
25
26
27
28
29
30
31
32
33
34
35
36
3037
3138
3239
33
34
35
36
37
38
39
40
40
41
42
43
44
45
46
47
48
49
50
4151
4252
<?php
use \vendor\DB\DB;
class history extends base
{
public $loginRequired = false;
protected function checkAccess($job) {
if ($job->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;
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: /");
}
}
}
web/application/controllers/job.php
33
44
55
6
6
7
8
79
810
911
......
3840
3941
4042
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
4158
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;
}
}
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: /");
}
}
}
web/application/controllers/service.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
<?php
use \vendor\DB\DB;
class service extends base {
/**
* This service will expect a JSON POST data of:
* ["data"] => {"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");
}
}
}
}
web/application/migrations/2.php
1212
1313
1414
15
15
16
1617
17
18
19
20
1821
1922
20
21
23
24
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)");
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)");
web/application/migrations/3.php
88
99
1010
11
11
1212
1313
1414
output TEXT,
jobs_id INTEGER,
run_date DATETIME,
time_taken INTEGER,
time_taken DECIMAL(10,5),
result INTEGER
);");
web/application/models/Jobs.php
1111
1212
1313
14
14
15
1516
17
18
1619
1720
1821
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;
web/application/views/add.html
2121
2222
2323
24
24
2525
2626
2727
2828
2929
3030
31
31
3232
3333
3434
......
6161
6262
6363
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
6485
6586
6687
<label class="col-sm-2 control-label" for="dropdownMenu1">Run Type:</label>
<div id="dropdown1" class="col-sm-10 dropdown">
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
<span id="selectedType">Ran by Kritbit</span>
<span id="selectedType">{% if job.runType %}{{job.getRunType}}{% else %}Ran by Kritbit{% endif %}</span>
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
<li data-type="1"><a href="#">Ran by Kritbit</a></li>
<li data-type="2"><a href="#">External Source</a></li>
</ul>
<input type="hidden" id="runType" name="runType" value="{{job.runType}}">
<input type="hidden" id="runType" name="runType" value="{% if job.runType %}{{job.runType}}{% else %}1{% endif %}">
</div>
</div>
<br>
</div>
<div class="form-group col-sm-10">
<label class="col-sm-2 control-label" for="comment">Job comment:</label>
<div class="col-sm-10">
<textarea class="form-control" rows="6" name="comments" id="comment">{{job.comments}}</textarea>
</div>
</div>
<div class="form-group col-sm-10">
<label class="col-sm-2 control-label" for="hash">Hash:</label>
<div class="col-sm-10">
<input type="text" value="{% if job.hash %}{{job.hash}}{% else %}{{hash}}{% endif %}" class="form-control" name="hash" id="hash" readonly>
</div>
</div>
<div class="form-group col-sm-10">
<label class="col-sm-2 control-label" for="sharedKey">Shared key:</label>
<div class="col-sm-10">
<input type="text" value="{% if job.hash %}{{job.sharedkey}}{% else %}{{sharedkey}}{% endif %}" class="form-control" name="sharedkey" id="sharedKey" readonly>
</div>
</div>
<div class="form-group col-sm-10">
<label class="col-sm-2 control-label" for="private">Require login to view history:</label>
<div class="checkbox">
<label>
web/application/views/history.html
33
44
55
6
6
77
88
9
10
11
12
13
14
915
1016
1117
......
2329
2430
2531
26
32
2733
2834
2935
{% block content %}
<div class="page-header">
<h1>Job list</h1>
<h1>History list</h1>
</div>
<div class="row">
<div class="col-md-4 col-md-offset-5">{{job.comments|nl2br|safe}}</div>
</div>
<hr>
<table align="center" style="width: 60%;" class="table table-hover">
<thead>
<tr>
{% endif %}
{% for history in histories %}
<tr>
<td><a class="btn btn-default" href="/history/log/{{jobid}}/{{history.id}}/" role="button">View</a></td>
<td><a class="btn btn-default" href="/history/log/{{job.id}}/{{history.id}}/" role="button">View</a></td>
<td>{{history.run_date}}</td>
<td>{{history.time_taken}}</td>
<td>{{history.result}}</td>
web/application/views/main.html
1717
1818
1919
20
2021
2122
2223
......
3031
3132
3233
34
35
36
37
38
3339
3440
3541
<th>Last Result</th>
<th>History</th>
<th>Delete</th>
<th>Force Run</th>
</tr>
</thead>
<tbody>
<td>{{job.last_result}}</td>
<td><a class="btn btn-default" href="/history/view/{{job.jobName}}-{{job.id}}" role="button">History</a></td>
<td><a class="btn btn-danger" href="/job/delete/{{job.id}}" role="button">Delete</a></td>
{% if job.force_run == 1 %}
<td><a class="btn btn-warning" href="/job/force/{{job.id}}" role="button">Enabled</a></td>
{% else %}
<td><a class="btn btn-success" href="/job/force/{{job.id}}" role="button">Disabled</a></td>
{% endif %}
</tr>
{% endfor %}
</tbody>
web/application/views/menu.html
99
1010
1111
12
12
1313
1414
1515
......
2727
2828
2929
30
3031
32
3133
3234
3335
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">Kritbot</a>
<a class="navbar-brand" href="/">Kritbit</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<button type="submit" class="btn btn-default">Submit</button>
</form>
<ul class="nav navbar-nav navbar-right">
{% if user %}
<li><a href="/login/logout">Logout - {{user.email}}</a></li>
{% endif %}
<!-- <li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
web/system/vendor/DB.php
9393
9494
9595
96
9697
9798
98
99
99
100100
101101
102102
*/
static function fetchObject($query, $className, $params = NULL)
{
/** @var \PDOStatement $statement */
if( ! $statement = DB::query($query, $params)) return null;
$statement->setFetchMode(\PDO::FETCH_INTO, new $className);
return $statement->fetchAll();
return $statement->fetchAll(\PDO::FETCH_CLASS, $className);
}
/**
web/system/vendor/aes.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php
// Source: http://stackoverflow.com/a/8232171/195722
function aes_encrypt($key, $text) {
$realKey = "";
if (count($key) < 32) { //if it's less than 32 bits - pad it
$realKey = str_pad($key, 32 - count($key) + 1);
} else if (count($key) > 32) {
throw new \Exception("Key is too long");
} else {
$realKey = $key;
}
return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $realKey, $text, MCRYPT_MODE_ECB));
}
function aes_decrypt($key, $cipherText) {
$realKey = "";
if (count($key) < 32) { //if it's less than 32 bits - pad it
$realKey = str_pad($key, 32 - count($key) + 1);
} else if (count($key) > 32) {
throw new \Exception("Key is too long");
} else {
$realKey = $key;
}
return mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $realKey, base64_decode($cipherText), MCRYPT_MODE_ECB);
}

Archive Download the corresponding diff file

Branches

Number of commits:
Page rendered in 0.10249s using 14 queries.