2
0
Fork 0

Initial commit

This commit is contained in:
adrien 2018-05-17 22:17:35 +02:00
commit aea3056f0f
9 changed files with 927 additions and 0 deletions

16
Data/config Normal file
View File

@ -0,0 +1,16 @@
{
"host": "localhost",
"https": false,
"charset": "UTF-8",
"title": "Mon super site",
"keyword": "super,site,tue,ouf",
"rootmail": "toto@tata.com",
"status": {
"root": 0,
"webm": 1,
"user": 2,
"doe": -1
}
}

View File

@ -0,0 +1 @@
<?php

1
Include/config.inc.php Normal file
View File

@ -0,0 +1 @@
<?php

View File

@ -0,0 +1,259 @@
<?php
namespace item {
function is_readable(string $item, bool $is_file = false): bool
{
if (!\is_readable($item) || ($is_file && !is_file($item)) || (!$is_file && is_file($item)))
return (false);
return (true);
}
function is_writable(string $item): bool
{
return (\is_writable($item));
}
function exist(string $item): bool
{
if (!file_exists($item))
return (false);
return (true);
}
function get_content(string $item, bool $mod_check = false): string
{
if ($mod_check && !compare_perms($item, MASK)) {
remove($item);
exit();
}
return (file_get_contents($item));
}
function push_content(string $item, string $data, bool $add = false): bool
{
if ($add)
$flag = FILE_APPEND | LOCK_EX;
else
$flag = LOCK_EX;
return (file_put_contents($item, $data, $flag));
}
function compare_perms(string $item, int $expect): bool
{
if ($expect === (fileperms($item) & 0777))
return (true);
else
return (false);
}
function chmod(string $item, int $perm): bool
{
return (\chmod($item, $perm));
}
function mkdir(string $item, bool $recursiv = true): bool
{
if (!\item\exist($item))
return (\mkdir($item, MASK, $recursiv));
else
return true;
}
function rm(string $item): bool
{
return (unlink($item));
}
function rm_dir(string $item): bool
{
return (rmdir($item));
}
function rm_r() {}
function encode(array $item): string
{
return (\json\encode($item));
}
function decode(string $item): array
{
return (\json\decode($item));
}
function cp(string $item, string $dest): boolean
{
return (copy($item, $dest));
}
}
namespace buffer {
function push(string $file, array $datas): string
{
$source = DATA_DIR.$file;
$target = BUFF_DIR.$file;
if (
(\item\exist($source) && !\item\is_readable($source, true)) ||
(\item\exist($target) && \item\rm($target))
) {
exit(); // make clean exit
}
$datas = \item\get_content($source);
\item\push_content(BUFF_DIR.$file, $datas);
return ($datas);
}
function pull(string $file, array &$datas): void
{
if (\item\exist(BUFF_DIR.$file) && \item\is_readable(BUFF_DIR.$file, true))
$datas = \item\get_content(BUFF_DIR.$file);
else
$datas = push($file, $datas);
}
}
namespace json {
function decode(string $content): array
{
$content = json_decode($content, true);
if (json_last_error())
exit('Error: '.json_last_error());
return ($content);
}
function encode(array $content): string
{
$content = json_encode(
$content,
JSON_HEX_APOS | JSON_NUMERIC_CHECK | JSON_PRESERVE_ZERO_FRACTION
);
return ($content);
}
}
namespace conf {
/* *
* Configuration core, no direct requests
*
* @param int $action
* requested action 1/2
*
* @param array $args
*
* @return array
* */
function core(int $action, array $args = array()): array
{
static $datas = array();
if (empty($datas)) {
\buffer\pull('config', $datas);
$datas = \item\decode($datas);
}
if (1 === $action) {
return ($datas);
} else if (2 === $action) {
$datas = array_merge($datas, $args);
return ($args);
}
return (array());
}
/* *
* Initialise configuration
*
* @return void
* */
function init(): void
{
core(0);
}
/* *
* Get some configuraton datas
*
* @param string *
* name of required configuration
*
* @return array
* */
function get(): array
{
$datas = core(1);
if (0 >= func_num_args())
return $datas;
$buff = array();
$args = func_get_args();
foreach ($args as &$arg)
$buff[$arg] = $datas[$arg];
return ($buff);
}
/* *
* Set or change configuration
*
* @param array $args
* 'name_of_config' => 'new value'
*
* @return array
* */
function set(array $args): array
{
return (core(2, $args));
}
}
namespace render {
function page() {}
function menu(array $list): string
{
$buff = '';
foreach ($list as $name => $datas) {
if (!isset($datas['href']) || !isset($datas['content']))
continue;
$buff .= '<li id="'.$name.'"><a href="'.$datas['href'].'"';
if (isset($datas['title']))
$buff .= ' title="'.$datas['title'].'"';
if (isset($datas['id']))
$buff .= ' id="'.$datas['id'].'"';
if (isset($datas['class']))
$buff .= ' class="'.$datas['class'].'"';
if (isset($datas['target']))
$buff .= ' target="'.$datas['target'].'"';
$buff .= '>'.$datas['content'].'</a></li>'."\n";
}
return ('<ul>'."\n".$buff.'</ul>');
}
}

59
Include/main.inc.php Normal file
View File

@ -0,0 +1,59 @@
<?php
namespace main;
function init(): void
{
clearstatcache();
\item\mkdir(BUFF_DIR);
\conf\init();
if (gc_enabled()) {
gc_collect_cycles();
gc_disable();
}
}
function header(): void
{
$conf = \conf\get('https', 'host', 'charset', 'status');
// Check HTTPS
if ($conf['https'] &&
(empty($_SERVER["HTTP_HTTPS"]) ||
strtolower($_SERVER["HTTP_HTTPS"]) !== "on")
) {
header('HTTP/1.1 301 Moved Permanently');
header('Location: '.$conf['host'].substr($_SERVER['REQUEST_URI'], 1));
}
//header('Content-Type: text/html;charset='.$conf['charset']);
// Init session
if ($conf['https']) {
sessionStart(true);
} else {
sessionStart();
}
if (!isset($_SESSION['status']) || (empty($_SESSION['status']) && 0 !== $_SESSION['status']))
$_SESSION['status'] = $conf['status']['doe'];
// DEBUG REMOVE, JUST FOR TESTS
$_SESSION['status'] = $conf['status']['root'];
// include admin parts
if ($conf['status']['webm'] >= $_SESSION['status'])
require INC_DIR.'manage_func.inc.php';
if ($conf['status']['root'] === $_SESSION['status'])
require INC_DIR.'admin_func.inc.php';
}
function start(): void
{
//$conf = \conf\get('pageDef');
//page demandé
if (isset($_GET['manage']) && function_exists('\manage\main'))
echo \manage\main();
}

110
Include/manage_func.inc.php Normal file
View File

@ -0,0 +1,110 @@
<?php
namespace manage {
function main(): string
{
$html = '';
$jail = '\manage\pages\\';
$menu = \render\menu(menu());
$request = securityParser($_GET['manage']);
$function= $jail.$request;
if (function_exists($function))
$html .= $function();
else
echo 'etrange';
// Main
// logi
// * Connections
// * Ajout/sup/config
//root// configurer site
//root// * Nom/descrip/motskey/imgfond/logo
//root// * securite site
//root// * base serveur/url/langues...
//% gerer pages
// * Vue comme dans un filemanager
// * les pages ont un petit drapeau de langue, transparent si langue
// * indisponible
// gestion menu
// * ajouter menu
// ** gere entres du menu
//root// gerer users
//root// * ajouter user
//root// ** nom/mail/passwd/accreditation
//% gestion media
// * vue dossier
return ($menu.$html);
}
function menu(): array
{
$menu = array(
'main' => array('content'=>'accueil','id'=>'','class'=>'','title'=>'','href'=>'?manage=accueil'),
'pages' => array('content'=>'pages','id'=>'','class'=>'','title'=>'','href'=>'?manage=pages'),
'menus' => array('content'=>'menu','id'=>'','class'=>'','title'=>'','href'=>'?manage=menu'),
'medias' => array('content'=>'media','id'=>'','class'=>'','title'=>'','href'=>'?manage=media'),
'logs' => array('content'=>'logs','id'=>'','class'=>'','title'=>'','href'=>'?manage=logs'),
'users' => array('content'=>'users','id'=>'','class'=>'','title'=>'','href'=>'?manage=users'),
'config' => array('content'=>'config','id'=>'','class'=>'','title'=>'','href'=>'?manage=conf')
);
if (function_exists('\admin\menu'))
$menu += \admin\menu();
return ($menu);
}
function pages_hf(string $html): string
{
$header = '';
$footer = '';
return ($$html);
}
}
namespace manage\pages {
function pages(): string
{
$content = '';
return ($content);
}
function conf(): string
{
$conf = \conf\get();
$content = '<h1>Comics CMS configuration</h1>
<form action="" method="post">';
if ($conf['https'])
$conf['https'] = 'checked';
// SITE
$content .= '<fieldset><legend>Base</legend>
<label for="https">HTTPs: </label><input id="https" type="checkbox" name="https" value="true" '.$conf['https'].'><br />
<label for="url">HOST: </label><input id="url" type="text" name="url" placeholder="www.mywebsite.com" value="'.$conf['host'].'" required><br />
</fieldset>
';
// RS MOTOR
$content .= '<fieldset><legend>Informations</legend>
<label for="title">Title: </label><input id="title" type="text" name="title" placeholder="My web site name" value="'.$conf['title'].'" required><br />
<label for="rskey">KeyWord: </label><input id="rskey" type="text" name="rskey" placeholder="web,site,private" value="'.$conf['keyword'].'" required>
</fieldset>
';
// ROOT
$content .= '<fieldset><legend>Root</legend>
<label for="rmail">Root user mail: </label><input id="rmail" type="text" name="rmail" placeholder="root@mywebsite.com" value="'.$conf['rootmail'].'" required><br />
</fieldset>
';
$content .= '<input type="submit" value="Save this configuration"></form>';
return ($content);
}
}

13
Include/require.inc.php Normal file
View File

@ -0,0 +1,13 @@
<?php
# Libs
require LIB_DIR.'LittleSecureLib.php';
# Functions
require INC_DIR.'input_output.inc.php';
# Config
require INC_DIR.'config.inc.php';
# Main
require INC_DIR.'main.inc.php';

427
Library/LittleSecureLib.php Normal file
View File

@ -0,0 +1,427 @@
<?php
/* ----------
* ! NoCopyright, NoCopyleft for a free world !
* ! PasDeCopyright, PasDeCopyleft pour un monde libre !
* ----------
* Copyright (C) [2014] [Kara.Adrien] <adrien@iglou.eu>
* ----------
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* ----------
* http://www.apache.org/licenses/LICENSE-2.0
* ----------
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ----------
* Beta 0.7.5 - 21 September 2016
* ----------
* LittleSecureLib, est une petite librairie php de securisation general.
* Elle traite les failles d'includes, XSS, InjectSQL, VolDeSession et CSRF.
* Un support de HASH et chiffrement est aussi présent.
---------- */
/* ---------- Configuration ---------- */
// Debug mode
$debug = false; // true | false
// IE Edge, désactiver le mode de "compatibilité" pour Internet Explorer
$ieEdge = false;
// key pour ID Unique du lien de session
define('SESSION_SINGLE_KEY', 'M@ cléf un!qu€ Et pr|vè');
// key de chiffrement
//define('ENCRYPTION_KEY', 'ma clée aléatoire ...');
// Hash à utiliser
//define('BADHASH', 'sha1'); // Simple
//define('CRYPTHASH', 'haval256,3'); // Pour le chiffrement | strlen = 64 !
//define('BIGHASH', 'whirlpool'); // Complexe
// Le grain de sel du HASH
//define('SEED_A', 'faa');
//define('SEED_B', 'foo');
//Exemple de sel en sha1, conseil d'utiliser une info user inaliénable non privé !
//define('SALT', '78312c77fadb9f35dd5fd7b343a3925ac4cfdaf0');
/* ---------- Dépendances/Debug ---------- */
if ($debug) {
error_reporting(-1);
ini_set('display_errors', 'On');
if (!extension_loaded('openssl')) {
exit('DIE : The openssl lib is not loaded.');
}
if (!extension_loaded('mcrypt')) {
exit('DIE : The mcrypt +2.4.x lib is not loaded.');
}
if (!extension_loaded('iconv')) {
exit('DIE : The iconv lib is not loaded.');
}
if (!in_array(BADHASH, hash_algos())) {
exit('DIE : '.BADHASH.' is not available, check your libs.');
}
if (!in_array(CRYPTHASH, hash_algos())) {
exit('DIE : '.CRYPTHASH.' is not available, check your libs.');
}
if (!in_array(BIGHASH, hash_algos())) {
exit('DIE : '.BIGHASH.' is not available, check your libs.');
}
}
if ($ieEdge) {
header('x-ua-compatible: IE=Edge,chrome=1');
}
/* ---------- Filtres ---------- */
// Parseur de sécurisation
function securityParser($arg, $noUtf8 = false, $type = null)
{
if ((array) $arg === $arg) {
foreach ($arg as $key => &$value) {
charCleaner($arg[$key], $type);
if (!$noUtf8) {
utf8Encode($arg[$key]);
}
}
} else {
charCleaner($arg, $type);
if (!$noUtf8) {
utf8Encode($arg);
}
}
return ($arg);
}
/* -------- Encodage -------- */
// Verification de l'UTF8
function utf8Encode(&$arg)
{
$inCharset = mb_detect_encoding($arg, 'auto');
if (('UTF-8' !== $inCharset) && ('ASCII' !== $inCharset)) {
$mbAllow = mb_list_encodings();
if ('ISO-8859-1' === $inCharset) {
$arg = utf8_encode($arg);
} elseif (in_array($inCharset, $mbAllow)) {
error_log($arg.' ERROR_01');
$arg = mb_convert_encoding($arg, 'UTF-8', $inCharset);
} else {
$arg = iconv($inCharset, 'UTF-8//TRANSLIT', $arg);
}
}
}
/* -------- Clean -------- */
// Filtres de nettoyage - Utilisez $type True, pour un encodage plus soft
function charCleaner(&$arg, &$type)
{
$arg = trim($arg);
if ($type) {
$arg = htmlspecialchars($arg, ENT_QUOTES, 'UTF-8', true);
} else {
$arg = filter_var($arg, FILTER_SANITIZE_FULL_SPECIAL_CHARS);
}
}
// Netoyage db - Pour Oracle utilisez les 'Procédures stockée' !
function dbCleaner($arg, $type = null)
{
$arg = trim($arg);
switch ($type) {
case 'mysql':
$arg = htmlspecialchars($arg, ENT_QUOTES);
break;
case 'sqlite':
$arg = SQLite3::escapeString($arg);
break;
case 'pg':
$arg = pg_escape_string($arg);
break;
case 'xml':
$arg = strtr($arg, array('\\' => '\\\\', "'" => "\'", '"' => '\"', "{" => '\{', "}" => '\}', "<" => '\<', ">" => '\>'));
break;
case 'json':
$arg = strtr($arg, array('\\' => '\\\\', '"' => '\"'));
break;
default:
exit('DIE : LittleSecureLib --> dbCleaner | Bad type.');
break;
}
return ($arg);
}
// Filtre pour shell
function shellCleaner($arg, $char = false)
{
if ($char) {
$arg = escapeshellcmd($arg);
} else {
$arg = escapeshellarg($arg);
}
return ($arg);
}
/* -------- Global -------- */
// Filtre pour fichier
function fileExist($arg, $path)
{
$arg = securityParser($arg);
if ('/' !== strstr($path, '/')) {
$path = $path.'/';
}
if (strstr($arg, "..")) {
$arg = false;
} else {
if (is_link($path.$arg) or !file_exists($path.$arg)) {
$arg = false;
}
}
return ($arg);
}
// Verif email/télèphone/url/ipv4/ipv6
function multiCheck($arg, $type = null)
{
switch ($type) {
case 'email':
$arg = filter_var($arg, FILTER_SANITIZE_EMAIL);
if (!filter_var($arg, FILTER_VALIDATE_EMAIL)) {
$arg = false;
}
break;
case 'phone':
$arg = filter_var($arg, FILTER_SANITIZE_NUMBER_INT);
if (!preg_match("#^\+?[0-9\./, -]{6,20}$#", $arg)) {
$arg = false;
}
break;
case 'url':
$arg = filter_var($arg, FILTER_SANITIZE_URL);
if (!filter_var($arg, FILTER_VALIDATE_URL)) {
$arg = false;
}
break;
case 'ip':
if (!filter_var($arg, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 | FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE)) {
$arg = false;
}
break;
default:
exit('DIE : LittleSecureLib --> multiCheck | Bad type.');
break;
}
return ($arg);
}
/* ---------- Sessions ---------- */
/* *
* Start safe session
*
* Check session is not started
* Https cookie
* regen id and fingerprint
*
* @return void
* */
function sessionStart($secure = null, $onlyHttp = true, $target = '/')
{
if (sessionIsStart())
return;
session_set_cookie_params(0, $target, null, $secure, $onlyHttp);
session_start();
sessionRegenId();
sessionFingerprint();
}
/* *
* Check if session is started
*
* @return boolean
* */
function sessionIsStart()
{
if (PHP_SESSION_ACTIVE === session_status())
return true;
return false;
}
/* *
* Regenerate ID
*
* @return void
* */
function sessionRegenId()
{
if (!isset($_SESSION['idTime']) || empty($_SESSION['idTime']))
$_SESSION['idTime'] = time();
if (time() >= $_SESSION['idTime'] + 600) {
//New ID all 10mn
session_regenerate_id(true);
$_SESSION['idTime'] = time();
}
}
/* *
* Destroy session
*
* Check if session exist befor erase
*
* @return void
* */
function sessionDestroy()
{
sessionStart();
$_SESSION = array();
session_destroy();
session_write_close();
if (isset($_COOKIE['PHPSESSID'])) {
unset($_COOKIE['PHPSESSID']);
$params = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000, $params['path'], $params['domain'], $params['secure'], $params['httponly']);
}
}
/* *
* Make a fingerprint
*
* "Avoid" session hijacking
*
* @return void
* */
function sessionFingerprint()
{
$userInfo = SESSION_SINGLE_KEY;
if (isset($_SERVER['HTTP_ACCEPT_ENCODING']))
$userInfo .= $_SERVER['HTTP_ACCEPT_ENCODING'];
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE']))
$userInfo .= ','.$_SERVER['HTTP_ACCEPT_LANGUAGE'];
if (isset($_SERVER['HTTP_USER_AGENT']))
$userInfo .= ','.$_SERVER['HTTP_USER_AGENT'];
if (isset($_SERVER['REMOTE_ADDR']))
$userInfo .= ','.$_SERVER['REMOTE_ADDR'];
$userInfo = filter_var($userInfo, FILTER_SANITIZE_FULL_SPECIAL_CHARS);
if (isset($_SESSION['userInfo'])) {
if ($_SESSION['userInfo'] !== $userInfo) {
error_log('|- FINGERPRINT ERROR -> || VALID: '.$_SESSION['userInfo'].' || REJECTED: '.$userInfo);
sessionDestroy();
return false;
}
} else {
$_SESSION['userInfo'] = $userInfo;
}
return true;
}
/* ---------- CSRF ---------- */
// Token
function token($arg = null)
{
if ($arg) {
if ((isset($_SESSION['token'])) && ($_SESSION['token'] === $arg)) {
$arg = true;
} else {
$arg = false;
}
$_SESSION['token'] = '';
} else {
$arg = bin2hex(openssl_random_pseudo_bytes(32));
$_SESSION['token'] = $arg;
}
return ($arg);
}
// Variable aléatoire
function randVar($arg)
{
$rand = bin2hex(openssl_random_pseudo_bytes(8));
$_SESSION[$arg] = $rand;
return ($rand);
}
/* ---------- chiffrement et hash ---------- */
function leBoucher($arg, $type = null)
{
if ('BADHASH' === $type) {
$arg = hash(BADHASH, $arg, false);
} elseif ('CRYPTHASH' === $type) {
$arg = hash(CRYPTHASH, $arg, true);
} else {
//BIGHASH est utilisé par défault
$lenMax = strlen(SALT);
$lenMid = $lenMax / 2;
$arg = SEED_A.$arg.SEED_B;
$arg = hash(BIGHASH, $arg, false);
$arg = substr(SALT, 0, $lenMid).$arg.substr(SALT, $lenMid, $lenMax);
}
return ($arg);
}
function encrypt($arg, $action)
{
$key = leBoucher(ENCRYPTION_KEY, 'CRYPTHASH');
$ivSi = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CFB);
if ('cry' === $action) {
$iv = mcrypt_create_iv($ivSi, MCRYPT_RAND);
$arg = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $arg, MCRYPT_MODE_CFB, $iv);
$arg = $iv.$arg;
$arg = base64_encode($arg);
} elseif ('dec' === $action) {
$arg = base64_decode($arg);
$ivDe = substr($arg, 0, $ivSi);
$arg = substr($arg, $ivSi);
$arg = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $arg, MCRYPT_MODE_CFB, $ivDe);
} else {
exit('DIE : LittleSecureLib --> encrypt | Mauvaise action.');
}
return ($arg);
}

41
Public/index.php Normal file
View File

@ -0,0 +1,41 @@
<?php
/* ----------
* ! NoCopyright, NoCopyleft for a free world !
* ! PasDeCopyright, PasDeCopyleft pour un monde libre !
* ----------
* Copyright (C) [2016] [Kara.Adrien] <adrien@iglou.eu>
* ----------
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* ----------
* http://www.apache.org/licenses/LICENSE-2.0
* ----------
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ----------
* Alpha 0.0.1 - 7 Oct 2016
** ---------- */
// check php vers
// Define the absolute path
define('APP_ROOT', dirname(__DIR__).'/');
define('LIB_DIR', APP_ROOT.'Library/');
define('INC_DIR', APP_ROOT.'Include/');
define('DATA_DIR', APP_ROOT.'Data/');
define('BUFF_DIR', '/tmp/tmpfs_cms/');
define('MASK', '0700');
// Load every componants
require INC_DIR.'require.inc.php';
// CMS Use
main\init();
main\header();
main\start();