Intial Commit, maybe with errors ! Not tested on a web-server !
This commit is contained in:
commit
ec1d41e8d4
|
@ -0,0 +1,3 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<brute-force-attack>
|
||||
</brute-force-attack>
|
|
@ -0,0 +1,384 @@
|
|||
<?php
|
||||
/*
|
||||
Copyright (c) 2008 Sebastián Grignoli
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of copyright holders nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @author "Sebastián Grignoli" <grignoli@gmail.com>
|
||||
* @package Encoding
|
||||
* @version 2.0
|
||||
* @link https://github.com/neitanod/forceutf8
|
||||
* @example https://github.com/neitanod/forceutf8
|
||||
* @license Revised BSD
|
||||
*/
|
||||
|
||||
|
||||
class Encoding {
|
||||
|
||||
const ICONV_TRANSLIT = "TRANSLIT";
|
||||
const ICONV_IGNORE = "IGNORE";
|
||||
const WITHOUT_ICONV = "";
|
||||
|
||||
protected static $win1252ToUtf8 = array(
|
||||
128 => "\xe2\x82\xac",
|
||||
|
||||
130 => "\xe2\x80\x9a",
|
||||
131 => "\xc6\x92",
|
||||
132 => "\xe2\x80\x9e",
|
||||
133 => "\xe2\x80\xa6",
|
||||
134 => "\xe2\x80\xa0",
|
||||
135 => "\xe2\x80\xa1",
|
||||
136 => "\xcb\x86",
|
||||
137 => "\xe2\x80\xb0",
|
||||
138 => "\xc5\xa0",
|
||||
139 => "\xe2\x80\xb9",
|
||||
140 => "\xc5\x92",
|
||||
|
||||
142 => "\xc5\xbd",
|
||||
|
||||
|
||||
145 => "\xe2\x80\x98",
|
||||
146 => "\xe2\x80\x99",
|
||||
147 => "\xe2\x80\x9c",
|
||||
148 => "\xe2\x80\x9d",
|
||||
149 => "\xe2\x80\xa2",
|
||||
150 => "\xe2\x80\x93",
|
||||
151 => "\xe2\x80\x94",
|
||||
152 => "\xcb\x9c",
|
||||
153 => "\xe2\x84\xa2",
|
||||
154 => "\xc5\xa1",
|
||||
155 => "\xe2\x80\xba",
|
||||
156 => "\xc5\x93",
|
||||
|
||||
158 => "\xc5\xbe",
|
||||
159 => "\xc5\xb8"
|
||||
);
|
||||
|
||||
protected static $brokenUtf8ToUtf8 = array(
|
||||
"\xc2\x80" => "\xe2\x82\xac",
|
||||
|
||||
"\xc2\x82" => "\xe2\x80\x9a",
|
||||
"\xc2\x83" => "\xc6\x92",
|
||||
"\xc2\x84" => "\xe2\x80\x9e",
|
||||
"\xc2\x85" => "\xe2\x80\xa6",
|
||||
"\xc2\x86" => "\xe2\x80\xa0",
|
||||
"\xc2\x87" => "\xe2\x80\xa1",
|
||||
"\xc2\x88" => "\xcb\x86",
|
||||
"\xc2\x89" => "\xe2\x80\xb0",
|
||||
"\xc2\x8a" => "\xc5\xa0",
|
||||
"\xc2\x8b" => "\xe2\x80\xb9",
|
||||
"\xc2\x8c" => "\xc5\x92",
|
||||
|
||||
"\xc2\x8e" => "\xc5\xbd",
|
||||
|
||||
|
||||
"\xc2\x91" => "\xe2\x80\x98",
|
||||
"\xc2\x92" => "\xe2\x80\x99",
|
||||
"\xc2\x93" => "\xe2\x80\x9c",
|
||||
"\xc2\x94" => "\xe2\x80\x9d",
|
||||
"\xc2\x95" => "\xe2\x80\xa2",
|
||||
"\xc2\x96" => "\xe2\x80\x93",
|
||||
"\xc2\x97" => "\xe2\x80\x94",
|
||||
"\xc2\x98" => "\xcb\x9c",
|
||||
"\xc2\x99" => "\xe2\x84\xa2",
|
||||
"\xc2\x9a" => "\xc5\xa1",
|
||||
"\xc2\x9b" => "\xe2\x80\xba",
|
||||
"\xc2\x9c" => "\xc5\x93",
|
||||
|
||||
"\xc2\x9e" => "\xc5\xbe",
|
||||
"\xc2\x9f" => "\xc5\xb8"
|
||||
);
|
||||
|
||||
protected static $utf8ToWin1252 = array(
|
||||
"\xe2\x82\xac" => "\x80",
|
||||
|
||||
"\xe2\x80\x9a" => "\x82",
|
||||
"\xc6\x92" => "\x83",
|
||||
"\xe2\x80\x9e" => "\x84",
|
||||
"\xe2\x80\xa6" => "\x85",
|
||||
"\xe2\x80\xa0" => "\x86",
|
||||
"\xe2\x80\xa1" => "\x87",
|
||||
"\xcb\x86" => "\x88",
|
||||
"\xe2\x80\xb0" => "\x89",
|
||||
"\xc5\xa0" => "\x8a",
|
||||
"\xe2\x80\xb9" => "\x8b",
|
||||
"\xc5\x92" => "\x8c",
|
||||
|
||||
"\xc5\xbd" => "\x8e",
|
||||
|
||||
|
||||
"\xe2\x80\x98" => "\x91",
|
||||
"\xe2\x80\x99" => "\x92",
|
||||
"\xe2\x80\x9c" => "\x93",
|
||||
"\xe2\x80\x9d" => "\x94",
|
||||
"\xe2\x80\xa2" => "\x95",
|
||||
"\xe2\x80\x93" => "\x96",
|
||||
"\xe2\x80\x94" => "\x97",
|
||||
"\xcb\x9c" => "\x98",
|
||||
"\xe2\x84\xa2" => "\x99",
|
||||
"\xc5\xa1" => "\x9a",
|
||||
"\xe2\x80\xba" => "\x9b",
|
||||
"\xc5\x93" => "\x9c",
|
||||
|
||||
"\xc5\xbe" => "\x9e",
|
||||
"\xc5\xb8" => "\x9f"
|
||||
);
|
||||
|
||||
static function toUTF8($text){
|
||||
/**
|
||||
* Function \ForceUTF8\Encoding::toUTF8
|
||||
*
|
||||
* This function leaves UTF8 characters alone, while converting almost all non-UTF8 to UTF8.
|
||||
*
|
||||
* It assumes that the encoding of the original string is either Windows-1252 or ISO 8859-1.
|
||||
*
|
||||
* It may fail to convert characters to UTF-8 if they fall into one of these scenarios:
|
||||
*
|
||||
* 1) when any of these characters: ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß
|
||||
* are followed by any of these: ("group B")
|
||||
* ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶•¸¹º»¼½¾¿
|
||||
* For example: %ABREPRESENT%C9%BB. «REPRESENTÉ»
|
||||
* The "«" (%AB) character will be converted, but the "É" followed by "»" (%C9%BB)
|
||||
* is also a valid unicode character, and will be left unchanged.
|
||||
*
|
||||
* 2) when any of these: àáâãäåæçèéêëìíîï are followed by TWO chars from group B,
|
||||
* 3) when any of these: ðñòó are followed by THREE chars from group B.
|
||||
*
|
||||
* @name toUTF8
|
||||
* @param string $text Any string.
|
||||
* @return string The same string, UTF8 encoded
|
||||
*
|
||||
*/
|
||||
|
||||
if(is_array($text))
|
||||
{
|
||||
foreach($text as $k => $v)
|
||||
{
|
||||
$text[$k] = self::toUTF8($v);
|
||||
}
|
||||
return $text;
|
||||
}
|
||||
|
||||
if(!is_string($text)) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
$max = self::strlen($text);
|
||||
|
||||
$buf = "";
|
||||
for($i = 0; $i < $max; $i++){
|
||||
$c1 = $text{$i};
|
||||
if($c1>="\xc0"){ //Should be converted to UTF8, if it's not UTF8 already
|
||||
$c2 = $i+1 >= $max? "\x00" : $text{$i+1};
|
||||
$c3 = $i+2 >= $max? "\x00" : $text{$i+2};
|
||||
$c4 = $i+3 >= $max? "\x00" : $text{$i+3};
|
||||
if($c1 >= "\xc0" & $c1 <= "\xdf"){ //looks like 2 bytes UTF8
|
||||
if($c2 >= "\x80" && $c2 <= "\xbf"){ //yeah, almost sure it's UTF8 already
|
||||
$buf .= $c1 . $c2;
|
||||
$i++;
|
||||
} else { //not valid UTF8. Convert it.
|
||||
$cc1 = (chr(ord($c1) / 64) | "\xc0");
|
||||
$cc2 = ($c1 & "\x3f") | "\x80";
|
||||
$buf .= $cc1 . $cc2;
|
||||
}
|
||||
} elseif($c1 >= "\xe0" & $c1 <= "\xef"){ //looks like 3 bytes UTF8
|
||||
if($c2 >= "\x80" && $c2 <= "\xbf" && $c3 >= "\x80" && $c3 <= "\xbf"){ //yeah, almost sure it's UTF8 already
|
||||
$buf .= $c1 . $c2 . $c3;
|
||||
$i = $i + 2;
|
||||
} else { //not valid UTF8. Convert it.
|
||||
$cc1 = (chr(ord($c1) / 64) | "\xc0");
|
||||
$cc2 = ($c1 & "\x3f") | "\x80";
|
||||
$buf .= $cc1 . $cc2;
|
||||
}
|
||||
} elseif($c1 >= "\xf0" & $c1 <= "\xf7"){ //looks like 4 bytes UTF8
|
||||
if($c2 >= "\x80" && $c2 <= "\xbf" && $c3 >= "\x80" && $c3 <= "\xbf" && $c4 >= "\x80" && $c4 <= "\xbf"){ //yeah, almost sure it's UTF8 already
|
||||
$buf .= $c1 . $c2 . $c3 . $c4;
|
||||
$i = $i + 3;
|
||||
} else { //not valid UTF8. Convert it.
|
||||
$cc1 = (chr(ord($c1) / 64) | "\xc0");
|
||||
$cc2 = ($c1 & "\x3f") | "\x80";
|
||||
$buf .= $cc1 . $cc2;
|
||||
}
|
||||
} else { //doesn't look like UTF8, but should be converted
|
||||
$cc1 = (chr(ord($c1) / 64) | "\xc0");
|
||||
$cc2 = (($c1 & "\x3f") | "\x80");
|
||||
$buf .= $cc1 . $cc2;
|
||||
}
|
||||
} elseif(($c1 & "\xc0") == "\x80"){ // needs conversion
|
||||
if(isset(self::$win1252ToUtf8[ord($c1)])) { //found in Windows-1252 special cases
|
||||
$buf .= self::$win1252ToUtf8[ord($c1)];
|
||||
} else {
|
||||
$cc1 = (chr(ord($c1) / 64) | "\xc0");
|
||||
$cc2 = (($c1 & "\x3f") | "\x80");
|
||||
$buf .= $cc1 . $cc2;
|
||||
}
|
||||
} else { // it doesn't need conversion
|
||||
$buf .= $c1;
|
||||
}
|
||||
}
|
||||
return $buf;
|
||||
}
|
||||
|
||||
static function toWin1252($text, $option = self::WITHOUT_ICONV) {
|
||||
if(is_array($text)) {
|
||||
foreach($text as $k => $v) {
|
||||
$text[$k] = self::toWin1252($v, $option);
|
||||
}
|
||||
return $text;
|
||||
} elseif(is_string($text)) {
|
||||
return static::utf8_decode($text, $option);
|
||||
} else {
|
||||
return $text;
|
||||
}
|
||||
}
|
||||
|
||||
static function toISO8859($text, $option = self::WITHOUT_ICONV) {
|
||||
return self::toWin1252($text, $option);
|
||||
}
|
||||
|
||||
static function toLatin1($text, $option = self::WITHOUT_ICONV) {
|
||||
return self::toWin1252($text, $option);
|
||||
}
|
||||
|
||||
static function fixUTF8($text, $option = self::WITHOUT_ICONV){
|
||||
if(is_array($text)) {
|
||||
foreach($text as $k => $v) {
|
||||
$text[$k] = self::fixUTF8($v, $option);
|
||||
}
|
||||
return $text;
|
||||
}
|
||||
|
||||
if(!is_string($text)) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
$last = "";
|
||||
while($last <> $text){
|
||||
$last = $text;
|
||||
$text = self::toUTF8(static::utf8_decode($text, $option));
|
||||
}
|
||||
$text = self::toUTF8(static::utf8_decode($text, $option));
|
||||
return $text;
|
||||
}
|
||||
|
||||
static function UTF8FixWin1252Chars($text){
|
||||
// If you received an UTF-8 string that was converted from Windows-1252 as it was ISO8859-1
|
||||
// (ignoring Windows-1252 chars from 80 to 9F) use this function to fix it.
|
||||
// See: http://en.wikipedia.org/wiki/Windows-1252
|
||||
|
||||
return str_replace(array_keys(self::$brokenUtf8ToUtf8), array_values(self::$brokenUtf8ToUtf8), $text);
|
||||
}
|
||||
|
||||
static function removeBOM($str=""){
|
||||
if(substr($str, 0,3) == pack("CCC",0xef,0xbb,0xbf)) {
|
||||
$str=substr($str, 3);
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
|
||||
protected static function strlen($text){
|
||||
return (function_exists('mb_strlen') && ((int) ini_get('mbstring.func_overload')) & 2) ?
|
||||
mb_strlen($text,'8bit') : strlen($text);
|
||||
}
|
||||
|
||||
public static function normalizeEncoding($encodingLabel)
|
||||
{
|
||||
$encoding = strtoupper($encodingLabel);
|
||||
$encoding = preg_replace('/[^a-zA-Z0-9\s]/', '', $encoding);
|
||||
$equivalences = array(
|
||||
'ISO88591' => 'ISO-8859-1',
|
||||
'ISO8859' => 'ISO-8859-1',
|
||||
'ISO' => 'ISO-8859-1',
|
||||
'LATIN1' => 'ISO-8859-1',
|
||||
'LATIN' => 'ISO-8859-1',
|
||||
'UTF8' => 'UTF-8',
|
||||
'UTF' => 'UTF-8',
|
||||
'WIN1252' => 'ISO-8859-1',
|
||||
'WINDOWS1252' => 'ISO-8859-1'
|
||||
);
|
||||
|
||||
if(empty($equivalences[$encoding])){
|
||||
return 'UTF-8';
|
||||
}
|
||||
|
||||
return $equivalences[$encoding];
|
||||
}
|
||||
|
||||
public static function encode($encodingLabel, $text)
|
||||
{
|
||||
$encodingLabel = self::normalizeEncoding($encodingLabel);
|
||||
if($encodingLabel == 'ISO-8859-1') return self::toLatin1($text);
|
||||
return self::toUTF8($text);
|
||||
}
|
||||
|
||||
protected static function utf8_decode($text, $option = self::WITHOUT_ICONV)
|
||||
{
|
||||
if ($option == self::WITHOUT_ICONV || !function_exists('iconv')) {
|
||||
$o = utf8_decode(
|
||||
str_replace(array_keys(self::$utf8ToWin1252), array_values(self::$utf8ToWin1252), self::toUTF8($text))
|
||||
);
|
||||
} else {
|
||||
$o = iconv("UTF-8", "Windows-1252" . ($option == self::ICONV_TRANSLIT ? '//TRANSLIT' : ($option == self::ICONV_IGNORE ? '//IGNORE' : '')), $text);
|
||||
}
|
||||
return $o;
|
||||
}
|
||||
|
||||
/****/
|
||||
|
||||
public static function destructionH4x0RChaine($chaine){
|
||||
return preg_replace('#[\x00-\x1F\x7F-\x9F/\\\\]#', '', $chaine);
|
||||
}
|
||||
|
||||
public static function protectionDoubleQuote($chaine){
|
||||
$chaine = preg_replace('/"(\w+)"/', '« ${1} »', $chaine);
|
||||
$chaine = preg_replace('#"#', '_', $chaine);
|
||||
return $chaine;
|
||||
}
|
||||
public static function protectionSimpleQuote($chaine){
|
||||
$chaine = preg_replace("#'#", '_', $chaine);
|
||||
return $chaine;
|
||||
}
|
||||
|
||||
public static function myUrlEncode($string) {
|
||||
$replacements = array('%21', '%2A', '%27', '%28', '%29', '%3B', '%3A', '%40', '%26', '%3D'/*, '%2B'*/, '%24', '%2C', '%2F', '%3F', '%25', '%23', '%5B', '%5D');
|
||||
$entities = array('!', '*', "'", "(", ")", ";", ":", "@", "&", "="/*, "+"*/, "$", ",", "/", "?", "%", "#", "[", "]");
|
||||
$string = urlencode($string);
|
||||
$string = str_replace($entities, $replacements, $string);
|
||||
return $string;
|
||||
}
|
||||
|
||||
public static function myUrlDecode($string) {
|
||||
$entities = array('%21', '%2A', '%27', '%28', '%29', '%3B', '%3A', '%40', '%26', '%3D'/*, '%2B'*/, '%24', '%2C', '%2F', '%3F', '%25', '%23', '%5B', '%5D');
|
||||
$replacements = array('!', '*', "'", "(", ")", ";", ":", "@", "&", "="/*, "+"*/, "$", ",", "/", "?", "%", "#", "[", "]");
|
||||
$string = str_replace($entities, $replacements, $string);
|
||||
$string = urldecode($string);
|
||||
return $string;
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
forceutf8
|
||||
=========
|
||||
|
||||
PHP Class Encoding featuring popular \ForceUTF8\Encoding::toUTF8() function --formerly known as forceUTF8()-- that fixes mixed encoded strings.
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
If you apply the PHP function utf8_encode() to an already-UTF8 string it will return a garbled UTF8 string.
|
||||
|
||||
This class addresses this issue and provides a handy static function called \ForceUTF8\Encoding::toUTF8().
|
||||
|
||||
You don't need to know what the encoding of your strings is. It can be Latin1 (ISO 8859-1), Windows-1252 or UTF8, or the string can have a mix of them. \ForceUTF8\Encoding::toUTF8() will convert everything to UTF8.
|
||||
|
||||
Sometimes you have to deal with services that are unreliable in terms of encoding, possibly mixing UTF8 and Latin1 in the same string.
|
||||
|
||||
Update:
|
||||
|
||||
I've included another function, \ForceUTF8\Encoding::fixUTF8(), which will fix the double (or multiple) encoded UTF8 string that looks garbled.
|
||||
|
||||
Usage:
|
||||
======
|
||||
|
||||
use \ForceUTF8\Encoding;
|
||||
|
||||
$utf8_string = Encoding::toUTF8($utf8_or_latin1_or_mixed_string);
|
||||
|
||||
$latin1_string = Encoding::toLatin1($utf8_or_latin1_or_mixed_string);
|
||||
|
||||
also:
|
||||
|
||||
$utf8_string = Encoding::fixUTF8($garbled_utf8_string);
|
||||
|
||||
Examples:
|
||||
|
||||
use \ForceUTF8\Encoding;
|
||||
|
||||
echo Encoding::fixUTF8("Fédération Camerounaise de Football\n");
|
||||
echo Encoding::fixUTF8("Fédération Camerounaise de Football\n");
|
||||
echo Encoding::fixUTF8("Fédération Camerounaise de Football\n");
|
||||
echo Encoding::fixUTF8("Fédération Camerounaise de Football\n");
|
||||
|
||||
will output:
|
||||
|
||||
Fédération Camerounaise de Football
|
||||
Fédération Camerounaise de Football
|
||||
Fédération Camerounaise de Football
|
||||
Fédération Camerounaise de Football
|
||||
|
||||
Options:
|
||||
========
|
||||
By default, `Encoding::fixUTF8` will use the `Encoding::WITHOUT_ICONV` flag, signalling that iconv should not be used to fix garbled UTF8 strings.
|
||||
|
||||
This class also provides options for iconv processing, such as `Encoding::ICONV_TRANSLIT` and `Encoding::ICONV_IGNORE` to enable these flags when the iconv class is utilized. The functionality of such flags are documented in the [PHP iconv documentation](http://php.net/manual/en/function.iconv.php).
|
||||
|
||||
Examples:
|
||||
|
||||
use \ForceUTF8\Encoding;
|
||||
|
||||
$str = "Fédération Camerounaise—de—Football\n"; // Uses U+2014 which is invalid ISO8859-1 but exists in Win1252
|
||||
echo Encoding::fixUTF8($str); // Will break U+2014
|
||||
echo Encoding::fixUTF8($str, Encoding::ICONV_IGNORE); // Will preserve U+2014
|
||||
echo Encoding::fixUTF8($str, Encoding::ICONV_TRANSLIT); // Will preserve U+2014
|
||||
|
||||
will output:
|
||||
|
||||
Fédération Camerounaise?de?Football
|
||||
Fédération Camerounaise—de—Football
|
||||
Fédération Camerounaise—de—Football
|
||||
|
||||
while:
|
||||
|
||||
use \ForceUTF8\Encoding;
|
||||
|
||||
$str = "čęėįšųūž"; // Uses several characters not present in ISO8859-1 / Win1252
|
||||
echo Encoding::fixUTF8($str); // Will break invalid characters
|
||||
echo Encoding::fixUTF8($str, Encoding::ICONV_IGNORE); // Will remove invalid characters, keep those present in Win1252
|
||||
echo Encoding::fixUTF8($str, Encoding::ICONV_TRANSLIT); // Will trasliterate invalid characters, keep those present in Win1252
|
||||
|
||||
will output:
|
||||
|
||||
????????
|
||||
šž
|
||||
ceeišuuž
|
||||
|
||||
|
||||
Install via composer:
|
||||
=====================
|
||||
Edit your composer.json file to include the following:
|
||||
|
||||
```json
|
||||
{
|
||||
"require": {
|
||||
"neitanod/forceutf8": "~2.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Tips:
|
||||
=====
|
||||
You can tip me with Bitcoin if you want. :)
|
||||
|
||||
<img src="resources/wallet.jpg" width="225" alt="1Awfu4TZpy99H7Pyzt1mooxU1aP2mJVdHP">
|
|
@ -0,0 +1,317 @@
|
|||
<?php
|
||||
/**
|
||||
* A Compatibility library with PHP 5.5's simplified password hashing API.
|
||||
*
|
||||
* @author Anthony Ferrara <ircmaxell@php.net>
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @copyright 2012 The Authors
|
||||
*/
|
||||
|
||||
namespace {
|
||||
|
||||
if (!defined('PASSWORD_BCRYPT')) {
|
||||
/**
|
||||
* PHPUnit Process isolation caches constants, but not function declarations.
|
||||
* So we need to check if the constants are defined separately from
|
||||
* the functions to enable supporting process isolation in userland
|
||||
* code.
|
||||
*/
|
||||
define('PASSWORD_BCRYPT', 1);
|
||||
define('PASSWORD_DEFAULT', PASSWORD_BCRYPT);
|
||||
define('PASSWORD_BCRYPT_DEFAULT_COST', 10);
|
||||
}
|
||||
|
||||
if (!function_exists('password_hash')) {
|
||||
|
||||
/**
|
||||
* Hash the password using the specified algorithm
|
||||
*
|
||||
* @param string $password The password to hash
|
||||
* @param int $algo The algorithm to use (Defined by PASSWORD_* constants)
|
||||
* @param array $options The options for the algorithm to use
|
||||
*
|
||||
* @return string|false The hashed password, or false on error.
|
||||
*/
|
||||
function password_hash($password, $algo, array $options = array()) {
|
||||
if (!function_exists('crypt')) {
|
||||
trigger_error("Crypt must be loaded for password_hash to function", E_USER_WARNING);
|
||||
return null;
|
||||
}
|
||||
if (is_null($password) || is_int($password)) {
|
||||
$password = (string) $password;
|
||||
}
|
||||
if (!is_string($password)) {
|
||||
trigger_error("password_hash(): Password must be a string", E_USER_WARNING);
|
||||
return null;
|
||||
}
|
||||
if (!is_int($algo)) {
|
||||
trigger_error("password_hash() expects parameter 2 to be long, " . gettype($algo) . " given", E_USER_WARNING);
|
||||
return null;
|
||||
}
|
||||
$resultLength = 0;
|
||||
switch ($algo) {
|
||||
case PASSWORD_BCRYPT:
|
||||
$cost = PASSWORD_BCRYPT_DEFAULT_COST;
|
||||
if (isset($options['cost'])) {
|
||||
$cost = (int) $options['cost'];
|
||||
if ($cost < 4 || $cost > 31) {
|
||||
trigger_error(sprintf("password_hash(): Invalid bcrypt cost parameter specified: %d", $cost), E_USER_WARNING);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// The length of salt to generate
|
||||
$raw_salt_len = 16;
|
||||
// The length required in the final serialization
|
||||
$required_salt_len = 22;
|
||||
$hash_format = sprintf("$2y$%02d$", $cost);
|
||||
// The expected length of the final crypt() output
|
||||
$resultLength = 60;
|
||||
break;
|
||||
default:
|
||||
trigger_error(sprintf("password_hash(): Unknown password hashing algorithm: %s", $algo), E_USER_WARNING);
|
||||
return null;
|
||||
}
|
||||
$salt_req_encoding = false;
|
||||
if (isset($options['salt'])) {
|
||||
switch (gettype($options['salt'])) {
|
||||
case 'NULL':
|
||||
case 'boolean':
|
||||
case 'integer':
|
||||
case 'double':
|
||||
case 'string':
|
||||
$salt = (string) $options['salt'];
|
||||
break;
|
||||
case 'object':
|
||||
if (method_exists($options['salt'], '__tostring')) {
|
||||
$salt = (string) $options['salt'];
|
||||
break;
|
||||
}
|
||||
case 'array':
|
||||
case 'resource':
|
||||
default:
|
||||
trigger_error('password_hash(): Non-string salt parameter supplied', E_USER_WARNING);
|
||||
return null;
|
||||
}
|
||||
if (PasswordCompat\binary\_strlen($salt) < $required_salt_len) {
|
||||
trigger_error(sprintf("password_hash(): Provided salt is too short: %d expecting %d", PasswordCompat\binary\_strlen($salt), $required_salt_len), E_USER_WARNING);
|
||||
return null;
|
||||
} elseif (0 == preg_match('#^[a-zA-Z0-9./]+$#D', $salt)) {
|
||||
$salt_req_encoding = true;
|
||||
}
|
||||
} else {
|
||||
$buffer = '';
|
||||
$buffer_valid = false;
|
||||
if (function_exists('mcrypt_create_iv') && !defined('PHALANGER')) {
|
||||
$buffer = mcrypt_create_iv($raw_salt_len, MCRYPT_DEV_URANDOM);
|
||||
if ($buffer) {
|
||||
$buffer_valid = true;
|
||||
}
|
||||
}
|
||||
if (!$buffer_valid && function_exists('openssl_random_pseudo_bytes')) {
|
||||
$strong = false;
|
||||
$buffer = openssl_random_pseudo_bytes($raw_salt_len, $strong);
|
||||
if ($buffer && $strong) {
|
||||
$buffer_valid = true;
|
||||
}
|
||||
}
|
||||
if (!$buffer_valid && @is_readable('/dev/urandom')) {
|
||||
$file = fopen('/dev/urandom', 'r');
|
||||
$read = 0;
|
||||
$local_buffer = '';
|
||||
while ($read < $raw_salt_len) {
|
||||
$local_buffer .= fread($file, $raw_salt_len - $read);
|
||||
$read = PasswordCompat\binary\_strlen($local_buffer);
|
||||
}
|
||||
fclose($file);
|
||||
if ($read >= $raw_salt_len) {
|
||||
$buffer_valid = true;
|
||||
}
|
||||
$buffer = str_pad($buffer, $raw_salt_len, "\0") ^ str_pad($local_buffer, $raw_salt_len, "\0");
|
||||
}
|
||||
if (!$buffer_valid || PasswordCompat\binary\_strlen($buffer) < $raw_salt_len) {
|
||||
$buffer_length = PasswordCompat\binary\_strlen($buffer);
|
||||
for ($i = 0; $i < $raw_salt_len; $i++) {
|
||||
if ($i < $buffer_length) {
|
||||
$buffer[$i] = $buffer[$i] ^ chr(mt_rand(0, 255));
|
||||
} else {
|
||||
$buffer .= chr(mt_rand(0, 255));
|
||||
}
|
||||
}
|
||||
}
|
||||
$salt = $buffer;
|
||||
$salt_req_encoding = true;
|
||||
}
|
||||
if ($salt_req_encoding) {
|
||||
// encode string with the Base64 variant used by crypt
|
||||
$base64_digits =
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
||||
$bcrypt64_digits =
|
||||
'./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
|
||||
$base64_string = base64_encode($salt);
|
||||
$salt = strtr(rtrim($base64_string, '='), $base64_digits, $bcrypt64_digits);
|
||||
}
|
||||
$salt = PasswordCompat\binary\_substr($salt, 0, $required_salt_len);
|
||||
|
||||
$hash = $hash_format . $salt;
|
||||
|
||||
$ret = crypt($password, $hash);
|
||||
|
||||
if (!is_string($ret) || PasswordCompat\binary\_strlen($ret) != $resultLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get information about the password hash. Returns an array of the information
|
||||
* that was used to generate the password hash.
|
||||
*
|
||||
* array(
|
||||
* 'algo' => 1,
|
||||
* 'algoName' => 'bcrypt',
|
||||
* 'options' => array(
|
||||
* 'cost' => PASSWORD_BCRYPT_DEFAULT_COST,
|
||||
* ),
|
||||
* )
|
||||
*
|
||||
* @param string $hash The password hash to extract info from
|
||||
*
|
||||
* @return array The array of information about the hash.
|
||||
*/
|
||||
function password_get_info($hash) {
|
||||
$return = array(
|
||||
'algo' => 0,
|
||||
'algoName' => 'unknown',
|
||||
'options' => array(),
|
||||
);
|
||||
if (PasswordCompat\binary\_substr($hash, 0, 4) == '$2y$' && PasswordCompat\binary\_strlen($hash) == 60) {
|
||||
$return['algo'] = PASSWORD_BCRYPT;
|
||||
$return['algoName'] = 'bcrypt';
|
||||
list($cost) = sscanf($hash, "$2y$%d$");
|
||||
$return['options']['cost'] = $cost;
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the password hash needs to be rehashed according to the options provided
|
||||
*
|
||||
* If the answer is true, after validating the password using password_verify, rehash it.
|
||||
*
|
||||
* @param string $hash The hash to test
|
||||
* @param int $algo The algorithm used for new password hashes
|
||||
* @param array $options The options array passed to password_hash
|
||||
*
|
||||
* @return boolean True if the password needs to be rehashed.
|
||||
*/
|
||||
function password_needs_rehash($hash, $algo, array $options = array()) {
|
||||
$info = password_get_info($hash);
|
||||
if ($info['algo'] !== (int) $algo) {
|
||||
return true;
|
||||
}
|
||||
switch ($algo) {
|
||||
case PASSWORD_BCRYPT:
|
||||
$cost = isset($options['cost']) ? (int) $options['cost'] : PASSWORD_BCRYPT_DEFAULT_COST;
|
||||
if ($cost !== $info['options']['cost']) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify a password against a hash using a timing attack resistant approach
|
||||
*
|
||||
* @param string $password The password to verify
|
||||
* @param string $hash The hash to verify against
|
||||
*
|
||||
* @return boolean If the password matches the hash
|
||||
*/
|
||||
function password_verify($password, $hash) {
|
||||
if (!function_exists('crypt')) {
|
||||
trigger_error("Crypt must be loaded for password_verify to function", E_USER_WARNING);
|
||||
return false;
|
||||
}
|
||||
$ret = crypt($password, $hash);
|
||||
if (!is_string($ret) || PasswordCompat\binary\_strlen($ret) != PasswordCompat\binary\_strlen($hash) || PasswordCompat\binary\_strlen($ret) <= 13) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$status = 0;
|
||||
for ($i = 0; $i < PasswordCompat\binary\_strlen($ret); $i++) {
|
||||
$status |= (ord($ret[$i]) ^ ord($hash[$i]));
|
||||
}
|
||||
|
||||
return $status === 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace PasswordCompat\binary {
|
||||
|
||||
if (!function_exists('PasswordCompat\\binary\\_strlen')) {
|
||||
|
||||
/**
|
||||
* Count the number of bytes in a string
|
||||
*
|
||||
* We cannot simply use strlen() for this, because it might be overwritten by the mbstring extension.
|
||||
* In this case, strlen() will count the number of *characters* based on the internal encoding. A
|
||||
* sequence of bytes might be regarded as a single multibyte character.
|
||||
*
|
||||
* @param string $binary_string The input string
|
||||
*
|
||||
* @internal
|
||||
* @return int The number of bytes
|
||||
*/
|
||||
function _strlen($binary_string) {
|
||||
if (function_exists('mb_strlen')) {
|
||||
return mb_strlen($binary_string, '8bit');
|
||||
}
|
||||
return strlen($binary_string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a substring based on byte limits
|
||||
*
|
||||
* @see _strlen()
|
||||
*
|
||||
* @param string $binary_string The input string
|
||||
* @param int $start
|
||||
* @param int $length
|
||||
*
|
||||
* @internal
|
||||
* @return string The substring
|
||||
*/
|
||||
function _substr($binary_string, $start, $length) {
|
||||
if (function_exists('mb_substr')) {
|
||||
return mb_substr($binary_string, $start, $length, '8bit');
|
||||
}
|
||||
return substr($binary_string, $start, $length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if current PHP version is compatible with the library
|
||||
*
|
||||
* @return boolean the check result
|
||||
*/
|
||||
function check() {
|
||||
static $pass = NULL;
|
||||
|
||||
if (is_null($pass)) {
|
||||
if (function_exists('crypt')) {
|
||||
$hash = '$2y$04$usesomesillystringfore7hnbRJHxXVLeakoG8K30oukPsA.ztMG';
|
||||
$test = crypt("password", $hash);
|
||||
$pass = $test == $hash;
|
||||
} else {
|
||||
$pass = false;
|
||||
}
|
||||
}
|
||||
return $pass;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
password_compat
|
||||
===============
|
||||
|
||||
[![Build Status](https://travis-ci.org/ircmaxell/password_compat.png?branch=master)](https://travis-ci.org/ircmaxell/password_compat) [![Code Climate](https://codeclimate.com/github/ircmaxell/password_compat/badges/gpa.svg)](https://codeclimate.com/github/ircmaxell/password_compat)
|
||||
|
||||
This library is intended to provide forward compatibility with the [password_*](http://php.net/password) functions that ship with PHP 5.5.
|
||||
|
||||
See [the RFC](https://wiki.php.net/rfc/password_hash) for more detailed information.
|
||||
|
||||
|
||||
Requirements
|
||||
============
|
||||
|
||||
This library requires `PHP >= 5.3.7` OR a version that has the `$2y` fix backported into it (such as RedHat provides). Note that Debian's 5.3.3 version is **NOT** supported.
|
||||
|
||||
The runtime checks have been removed due to this version issue. To see if password_compat is available for your system, run the included `version-test.php`. If it outputs "Pass", you can safely use the library. If not, you cannot.
|
||||
|
||||
If you attempt to use password-compat on an unsupported version, attempts to create or verify hashes will return `false`. You have been warned!
|
||||
|
||||
The reason for this is that PHP prior to 5.3.7 contains a [security issue with its BCRYPT implementation](http://php.net/security/crypt_blowfish.php). Therefore, it's highly recommended that you upgrade to a newer version of PHP prior to using this layer.
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
To install, simply `require` the `password.php` file under `lib`.
|
||||
|
||||
You can also install it via `Composer` by using the [Packagist archive](http://packagist.org/packages/ircmaxell/password-compat).
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
**Creating Password Hashes**
|
||||
|
||||
To create a password hash from a password, simply use the `password_hash` function.
|
||||
````PHP
|
||||
$hash = password_hash($password, PASSWORD_BCRYPT);
|
||||
````
|
||||
Note that the algorithm that we chose is `PASSWORD_BCRYPT`. That's the current strongest algorithm supported. This is the `BCRYPT` crypt algorithm. It produces a 60 character hash as the result.
|
||||
|
||||
`BCRYPT` also allows for you to define a `cost` parameter in the options array. This allows for you to change the CPU cost of the algorithm:
|
||||
````PHP
|
||||
$hash = password_hash($password, PASSWORD_BCRYPT, array("cost" => 10));
|
||||
````
|
||||
That's the same as the default. The cost can range from `4` to `31`. I would suggest that you use the highest cost that you can, while keeping response time reasonable (I target between 0.1 and 0.5 seconds for a hash, depending on use-case).
|
||||
|
||||
Another algorithm name is supported:
|
||||
````PHP
|
||||
PASSWORD_DEFAULT
|
||||
````
|
||||
This will use the strongest algorithm available to PHP at the current time. Presently, this is the same as specifying `PASSWORD_BCRYPT`. But in future versions of PHP, it may be updated to use a stronger algorithm if one is introduced. It can also be changed if a problem is identified with the BCRYPT algorithm. Note that if you use this option, you are **strongly** encouraged to store it in a `VARCHAR(255)` column to avoid truncation issues if a future algorithm increases the length of the generated hash.
|
||||
|
||||
It is very important that you should check the return value of `password_hash` prior to storing it, because `false` or `null` may be returned if it encountered an error.
|
||||
|
||||
**Verifying Password Hashes**
|
||||
|
||||
To verify a hash created by `password_hash`, simply call:
|
||||
````PHP
|
||||
if (password_verify($password, $hash)) {
|
||||
/* Valid */
|
||||
} else {
|
||||
/* Invalid */
|
||||
}
|
||||
````
|
||||
That's all there is to it.
|
||||
|
||||
**Rehashing Passwords**
|
||||
|
||||
From time to time you may update your hashing parameters (algorithm, cost, etc). So a function to determine if rehashing is necessary is available:
|
||||
````PHP
|
||||
if (password_verify($password, $hash)) {
|
||||
if (password_needs_rehash($hash, $algorithm, $options)) {
|
||||
$hash = password_hash($password, $algorithm, $options);
|
||||
/* Store new hash in db */
|
||||
}
|
||||
}
|
||||
````
|
||||
|
||||
Security Vulnerabilities
|
||||
========================
|
||||
|
||||
If you have found a security issue, please contact the author directly at [ircmaxell@php.net](mailto:ircmaxell@php.net).
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
<footer>
|
||||
<p>© Unachieved <a href="http://www.evolutis.fr/">Evolutis</a> & <a href="http://www.ip-formation.com/">IP-formation</a> 2011 - develloped by Emmanuel ROY on an Debian dev2 original totally reindexed by sadness</p>
|
||||
</footer>
|
||||
|
||||
|
||||
<!-- JavaScript at the bottom for fast page loading -->
|
||||
|
||||
|
||||
<script src="js/markdown.js"></script>
|
||||
<script>
|
||||
function Editor(input, preview) {
|
||||
this.update = function () {
|
||||
preview.innerHTML = markdown.toHTML(input.value);
|
||||
};
|
||||
input.editor = this;
|
||||
this.update();
|
||||
}
|
||||
var $ = function (id) { return document.getElementById(id); };
|
||||
new Editor($("text-input"), $("preview"));
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,72 @@
|
|||
<!DOCTYPE html>
|
||||
<!-- paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/ -->
|
||||
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]-->
|
||||
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8" lang="en"> <![endif]-->
|
||||
<!--[if IE 8]> <html class="no-js lt-ie9" lang="en"> <![endif]-->
|
||||
<!-- Consider adding a manifest.appcache: h5bp.com/d/Offline -->
|
||||
<!--[if gt IE 8]><!--> <html class="no-js" lang="fr"> <!--<![endif]-->
|
||||
<head>
|
||||
<META charset="utf-8">
|
||||
|
||||
<META NAME="Category" CONTENT=""/>
|
||||
<META NAME="Publisher" CONTENT="Emmanuel ROY"/>
|
||||
<META NAME="Copyright" CONTENT="© - 2015 - Acksop"/>
|
||||
<META NAME="Expires" CONTENT="Never Maybe!"/>
|
||||
<META NAME="Distribution" CONTENT="Global"/>
|
||||
<META NAME='Description' lang='<?php echo $lang; ?>' CONTENT="<?php echo $metaDesc ?>"/>
|
||||
<META NAME='Identifier-URL' CONTENT="new.emmanuelroy.name/<?php echo $page['name'] ?>"/>
|
||||
<?php
|
||||
/*Rich META from google
|
||||
<meta name="department" content="legal" />
|
||||
<meta name="audience" content="all" />
|
||||
<meta name="doc_status" content="draft" />
|
||||
//a utiliser avec un syteme de classement utilisateur
|
||||
<meta name="rating" content="5" />
|
||||
//link: http://en.wikipedia.org/wiki/Smart_tag_%28Microsoft%29
|
||||
<meta name="mssmarttagspreventparsing" content="..." />
|
||||
//link: https://support.google.com/customsearch/answer/2595557?hl=fr
|
||||
<meta name="verify-v1" content="..." />
|
||||
*/
|
||||
?>
|
||||
|
||||
<META NAME='Keywords' lang='fr' CONTENT="Art, Programming, Languages, Personnal Website, Curriculum Vitae Multimédia"/>
|
||||
<META NAME="Author" CONTENT="<?php if(isset($auteur)){ echo $auteur; }else {echo 'Emmanuel ROY And More'; } ?>"/>
|
||||
<META NAME="Reply-to" CONTENT="contact@emmanuelroy.name"/>
|
||||
<META NAME="Date-Creation-yyyymmdd" CONTENT="<?php echo $dateCreation ?>"/>
|
||||
<META NAME="Date-Revision-yyyymmdd" CONTENT="<?php echo $dateRevision ?>"/>
|
||||
<META NAME="Revisit-After" CONTENT="365,333333333333333333333333333... - 1 days"/>
|
||||
<META NAME="Robots" CONTENT="index, nofollow"/>
|
||||
<META NAME="GOOGLEBOT" CONTENT="NOARCHIVE"/>
|
||||
<META NAME="the-WAYBACK-MACHINE" CONTENT="ARCHIVE"/>
|
||||
|
||||
<!-- Use the .htaccess and remove these lines to avoid edge case issues.
|
||||
More info: h5bp.com/i/378 -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
|
||||
<title><?php echo $title ?></title>
|
||||
|
||||
<!-- Mobile viewport optimized: h5bp.com/viewport -->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<!-- Place favicon.ico and apple-touch-icon.png in the root directory: mathiasbynens.be/notes/touch-icons -->
|
||||
|
||||
<!--<link rel="stylesheet" href="/css/style.css" />-->
|
||||
|
||||
<!-- More ideas for your <head> here: h5bp.com/d/head-Tips -->
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- All JavaScript at the bottom, except this Modernizr build.
|
||||
Modernizr enables HTML5 elements & feature detects for optimal performance.
|
||||
Create your own custom Modernizr build: www.modernizr.com/download/ -->
|
||||
<!-- <script src="/js/libs/modernizr-2.5.3.min.js"></script>-->
|
||||
|
||||
</head>
|
||||
|
||||
|
||||
|
||||
<body>
|
||||
<!-- Prompt IE 6 users to install Chrome Frame. Remove this if you support IE 6.
|
||||
chromium.org/developers/how-tos/chrome-frame-getting-started -->
|
||||
<!--[if lt IE 7]><p class=chromeframe>Your browser is <em>ancient!</em> <a href="http://browsehappy.com/">Upgrade to a different browser</a> or <a href="http://www.google.com/chromeframe/?redirect=true">install Google Chrome Frame</a> to experience this site.</p><![endif]-->
|
|
@ -0,0 +1,21 @@
|
|||
<?php include LAYOUT_PATH . DIRECTORY_SEPARATOR .'header.php';?>
|
||||
|
||||
<!--
|
||||
<header>
|
||||
<h2>Ceci est le header de la page <?php echo $page['name'] ?></h2>
|
||||
</header>
|
||||
-->
|
||||
|
||||
<br /><br /><br />
|
||||
<?php echo $content ?>
|
||||
<br /><br /><br />
|
||||
|
||||
<!--
|
||||
<footer>
|
||||
<h2>Ceci est le footer de la page <?php echo $page['name'] ?></h2>
|
||||
</footer>
|
||||
-->
|
||||
|
||||
|
||||
<?php include LAYOUT_PATH . DIRECTORY_SEPARATOR .'footer.php';?>
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
$title = 'Envoi d\'un lien de veille et stokage en XML';
|
||||
$metaDesc = 'CV - Emmanuel ROY - chatbot pour tinternet';
|
||||
$dateCreation = '20191107';
|
||||
$dateRevision = '20191107';
|
||||
$encoding = 'utf-8';
|
||||
$layout = 'layout_codage';
|
|
@ -0,0 +1,29 @@
|
|||
<form method="post" action="/traitementEnvoiLienVeilleTinternet.php">
|
||||
|
||||
<textarea id="text-input" oninput="this.editor.update()"
|
||||
rows="6" cols="60">Type **Markdown** here.</textarea>
|
||||
<div id="preview"> </div>
|
||||
|
||||
<textarea class='span8' name=message id=message tabindex="1" cols="80" rows="5" required><?php if(isset($_GET['message'])){echo Encoding::myUrlDecode($_GET['message']);}?></textarea>
|
||||
|
||||
<div class="clearfix" style="padding: 14px 200px;">
|
||||
<input class="btn primary" name="password" type="password" id="password" tabindex="2" required />
|
||||
</div>
|
||||
<div class="clearfix" style="padding: 14px 200px;">
|
||||
<input class="btn primary" name="submit" type="submit" id="submit" tabindex="3" value="Envoyer" />
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<br /><br />
|
||||
|
||||
<div id='mattermostform_success'></div>
|
||||
<?php
|
||||
if(isset($_GET['envoiDuMessage'])){
|
||||
if($_GET['envoiDuMessage'] == 'oui'){
|
||||
echo "<p>La veille Mattermost as été correctement transmis.</p>";
|
||||
}else{
|
||||
echo "<p>La veille Mattermost n'as pas été transmis. Veuillez vérifiez les informations que vous avez saisies ...</p>";
|
||||
}
|
||||
}
|
||||
?>
|
||||
</div>
|
|
@ -0,0 +1,6 @@
|
|||
<?php
|
||||
define(HASH_ALGORITHM, PASSWORD_BCRYPT);
|
||||
define(HASH,password_hash('xxxx-0000', HASH_ALGORITHM));
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
<?php
|
||||
session_start();
|
||||
|
||||
/*RESTRICTION D'USAGE DU SITE PERSONNEL AU BLACK HAT HACKER */
|
||||
|
||||
//chargement en mémoire des anciennes attaques
|
||||
$attempts = simplexml_load_file( APPLICATION_PATH . DIRECTORY_SEPARATOR ."bruteforce-logger.xml" , "SimpleXMLElement" , LIBXML_NOCDATA );
|
||||
if($attempts->xpath("/brute-force-attack/attempt/from")) {
|
||||
foreach ($attempts->xpath("/brute-force-attack/attempt/from") as $attempt) {
|
||||
// Récupération des ip et test de corrélation actuelle
|
||||
if ($attempt['from'] == $_SERVER['REMOTE_ADDR']) {
|
||||
$page['action'] = 'default';
|
||||
$page['name'] = 'error-brute-force-attack';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**/
|
||||
/* ITERATION D'UNE POSSIBLE ATTAQUE BRUTE FORCE SUR UNE PAGE DE TRAITEMENT */
|
||||
|
||||
if ($page['action'] == 'traitementPOSTvar'){
|
||||
if(isset($_SESSION['brute-force-attempt'])) {
|
||||
$_SESSION['brute-force-attempt']++;
|
||||
}else{
|
||||
$_SESSION['brute-force-attempt']=1;
|
||||
}
|
||||
}
|
||||
|
||||
/**/
|
||||
/* TESTS PERMETTANT DE DEFINIR CERTAINS CAS COMME ETANT DANGEREUX*/
|
||||
|
||||
if ( !isset($_SESSION['current-ip'])
|
||||
|| !isset($_SESSION['current-time']) ){
|
||||
|
||||
//Ce test permet d'identifier ceux qui veulent faire un traitement sans provenir d'une page de formulaire
|
||||
|
||||
if($page['action'] == 'traitementPOSTvar'){
|
||||
$page['action'] = 'default';
|
||||
$page['name'] = 'error';
|
||||
}
|
||||
}else{
|
||||
|
||||
if( $_SESSION['last-ip'] !== $_SERVER['REMOTE_ADDR']
|
||||
|| $_SESSION['last-time'] > $_SERVER['REQUEST_TIME'] ){
|
||||
|
||||
//ce test permet de verifier que le demandeur est bien le meme que celui qui provient d'un formulaire
|
||||
|
||||
$page['action'] = 'default';
|
||||
$page['name'] = 'error';
|
||||
}
|
||||
|
||||
if( $page['action'] == 'traitementPOSTvar' && $_SESSION['brute-force-attempt'] > 5 ){
|
||||
|
||||
//ce test permet de logger une attaque brute force sur un formulaire
|
||||
|
||||
$dom = new DOMDocument;
|
||||
$dom->load(APPLICATION_PATH . DIRECTORY_SEPARATOR ."bruteforce-logger.xml");
|
||||
|
||||
$noeudBruteForce = $dom->getElementsByTagName("brute-force-attack")->item(0);
|
||||
|
||||
$attemptNode = $dom->createElement("attempt");
|
||||
|
||||
$dateNode = $dom->createElement("date");
|
||||
$textNode = $dom->createTextNode(htmlentities($_SERVER['REQUEST_TIME']));
|
||||
$dateNode->appendChild($textNode);
|
||||
$attemptNode->appendChild($dateNode);
|
||||
|
||||
$ipNode = $dom->createElement("from");
|
||||
$textNode = $dom->createTextNode(htmlentities($_SERVER['REMOTE_ADDR']));
|
||||
$ipNode->appendChild($textNode);
|
||||
$attemptNode->appendChild($ipNode);
|
||||
|
||||
$noeudBruteForce->appendChild($attemptNode);
|
||||
$dom->save(APPLICATION_PATH . DIRECTORY_SEPARATOR ."bruteforce-logger.xml");
|
||||
|
||||
|
||||
$page['action'] = 'default';
|
||||
$page['name'] = 'error-brute-force-attack';
|
||||
|
||||
}
|
||||
|
||||
//mise en tampon des données courante de combat
|
||||
$_SESSION['last-ip'] = $_SESSION['current-ip'];
|
||||
$_SESSION['last-time'] = $_SESSION['current-time'];
|
||||
}
|
||||
/**/
|
||||
|
||||
//actualisation des données courante du temps réel
|
||||
$_SESSION['current-ip'] = $_SERVER['REMOTE_ADDR'];
|
||||
$_SESSION['current-time'] = $_SERVER['REQUEST_TIME'];
|
||||
$_SESSION['current-server'] = $_SERVER['SERVER_ADDR'];
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
define('PUBLIC_PATH' , dirname(__FILE__) );
|
||||
define('APPLICATION_PATH' , dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . "app" );
|
||||
define('CLASS_PATH' , APPLICATION_PATH . DIRECTORY_SEPARATOR . "class" );
|
||||
define('PAGES_PATH' , APPLICATION_PATH . DIRECTORY_SEPARATOR . "page" );
|
||||
define('LAYOUT_PATH' , APPLICATION_PATH . DIRECTORY_SEPARATOR . "layout" );
|
||||
|
||||
require_once CLASS_PATH . DIRECTORY_SEPARATOR . 'password.class.php';
|
||||
require_once CLASS_PATH . DIRECTORY_SEPARATOR . 'encoding.class.php';
|
||||
require APPLICATION_PATH . DIRECTORY_SEPARATOR . 'session.php';
|
||||
|
||||
|
||||
//pour chaque page et mise en tampon
|
||||
ob_start();
|
||||
require_once PAGES_PATH . DIRECTORY_SEPARATOR . 'TINTERNET-chatbot.php' ;
|
||||
require_once PAGES_PATH . DIRECTORY_SEPARATOR . 'TINTERNET-chatbot.phtml' ;
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
require_once LAYOUT_PATH . DIRECTORY_SEPARATOR . $layout . '.phtml';
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,149 @@
|
|||
<?php
|
||||
|
||||
define('PUBLIC_PATH' , dirname(__FILE__));
|
||||
define('APPLICATION_PATH' , dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . "app" );
|
||||
define('CLASS_PATH' , APPLICATION_PATH . DIRECTORY_SEPARATOR . "class" );
|
||||
|
||||
require APPLICATION_PATH . DIRECTORY_SEPARATOR . "parameters.php";
|
||||
require APPLICATION_PATH . DIRECTORY_SEPARATOR . 'session.php';
|
||||
require_once CLASS_PATH . DIRECTORY_SEPARATOR . 'password.class.php';
|
||||
require_once CLASS_PATH . DIRECTORY_SEPARATOR . 'encoding.class.php';
|
||||
|
||||
error_reporting(-1);
|
||||
ini_set('display_errors', 1);
|
||||
|
||||
function passValide($password){
|
||||
|
||||
//password_hash('tototo', HASH_ALGORITHM)
|
||||
|
||||
if (password_verify($password, HASH)) {
|
||||
if (password_needs_rehash(HASH, HASH_ALGORITHM)) {
|
||||
$hash = password_hash($password, HASH_ALGORITHM);
|
||||
|
||||
$file = "";
|
||||
$lines = file(APPLICATION_PATH . DIRECTORY_SEPARATOR . "parameters.php");
|
||||
foreach ($lines as $line_num => $line) {
|
||||
if(preg_match("#define\(HASH,(.*)\)#",$line,$matches)){
|
||||
$newline = preg_replace("#define\(HASH,(.*)\)#","define(HASH,'$hash')",$line);
|
||||
}else{
|
||||
$newline = $line;
|
||||
}
|
||||
if ($newline != "") {
|
||||
$file .= $newline . "\n";
|
||||
}
|
||||
}
|
||||
/* Store new hash in parameters file */
|
||||
file_put_contents(APPLICATION_PATH . DIRECTORY_SEPARATOR . "parameters.php",$file);
|
||||
}
|
||||
}
|
||||
//try fallback passengers
|
||||
if (password_verify($password,HASH)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//https://code.tutsplus.com/tutorials/8-regular-expressions-you-should-know--net-6149
|
||||
|
||||
function extractLink($message){
|
||||
preg_match_all("#((?:https?:\/\/)?(?:[\da-z\.-]+)\.(?:[a-z\.]{2,6})(?:[\/\w \.-]*)*\/?)#",$message,$matches);
|
||||
return $matches;
|
||||
}
|
||||
|
||||
function extractText($message){
|
||||
$links = extractLink($message);
|
||||
array_shift($links);
|
||||
foreach ($links as $link) {
|
||||
if ($link != "") {
|
||||
$message = preg_replace("#$link[0]#"," ... ",$message);
|
||||
}
|
||||
}
|
||||
return $message;
|
||||
}
|
||||
|
||||
/**************************************************************************************************************/
|
||||
/******************* TEST COTÉ SERVEUR POUR L'ENVOI DU MESSAGE *********************************************/
|
||||
|
||||
$message = Encoding::fixUTF8(Encoding::protectionDoubleQuote(Encoding::protectionSimpleQuote($_POST['message'])));
|
||||
|
||||
if (passValide($_POST['password']) && $_POST['message'] != ""){
|
||||
|
||||
$hookMattermost = "http://{your-mattermost-site}/hooks/xxx-generatedkey-xxx";
|
||||
|
||||
$payload = <<<EOD
|
||||
payload={
|
||||
"channel": "bot-tests",
|
||||
"username": "acksop",
|
||||
"text": "$message"
|
||||
}
|
||||
EOD;
|
||||
|
||||
$json = <<<EOD
|
||||
{
|
||||
"channel": "bot-tests",
|
||||
"username": "acksop",
|
||||
"text": "$message"
|
||||
}
|
||||
EOD;
|
||||
|
||||
|
||||
$commandURL = "curl -i -X POST --data-urlencode '$payload' $hookMattermost";
|
||||
$commandJSON = "curl -i -X POST -H 'Content-Type: application/json' -d '$json' $hookMattermost";
|
||||
|
||||
echo "<pre>";
|
||||
print_r($commandJSON);
|
||||
echo "</pre><pre>";
|
||||
print_r($commandURL);
|
||||
|
||||
$dom = new DOMDocument;
|
||||
$dom->load(PUBLIC_PATH . DIRECTORY_SEPARATOR ."veilleTinternet.xml");
|
||||
|
||||
$noeudVeille = $dom->getElementsByTagName("veille")->item(0);
|
||||
|
||||
$messageNode = $dom->createElement("message");
|
||||
|
||||
$myOriginalTextNode = $dom->createElement("originel");
|
||||
$textNode = $dom->createTextNode(htmlentities($message));
|
||||
$myOriginalTextNode->appendChild($textNode);
|
||||
$messageNode->appendChild($myOriginalTextNode);
|
||||
|
||||
$myTextNode = $dom->createElement("text");
|
||||
$textNode = $dom->createTextNode(htmlentities(extractText($message)));
|
||||
$myTextNode->appendChild($textNode);
|
||||
$messageNode->appendChild($myTextNode);
|
||||
|
||||
$myLinksNode = $dom->createElement("links");
|
||||
$links = extractLink($message);
|
||||
array_shift($links);
|
||||
foreach($links as $link) {
|
||||
if($link != "") {
|
||||
$myLinkNode = $dom->createElement("link");
|
||||
$textNode = $dom->createTextNode(htmlentities($link[0]));
|
||||
$myLinkNode->appendChild($textNode);
|
||||
$myLinksNode->appendChild($myLinkNode);
|
||||
}
|
||||
}
|
||||
$messageNode->appendChild($myLinksNode);
|
||||
|
||||
//$dom->insertBefore( $messageNode, $noeudVeille );
|
||||
$noeudVeille->appendChild($messageNode);
|
||||
|
||||
$dom->save(PUBLIC_PATH . DIRECTORY_SEPARATOR ."veilleTinternet.xml");
|
||||
|
||||
shell_exec($commandJSON);
|
||||
shell_exec($commandURL);
|
||||
die();
|
||||
if(isset($_POST['ajax'])){
|
||||
echo "Votre Lien as été correctement transmis. Vous receverez une réponse dans les prochains jours.";
|
||||
}else{
|
||||
header("Location: /index.php?envoiDuMessage=oui");
|
||||
}
|
||||
|
||||
}else{
|
||||
if(isset($_POST['ajax'])){
|
||||
echo "Votre Lien n'as pas été transmis. Veuillez vérifiez les informations que vous avez saisies ...";
|
||||
}else{
|
||||
header("Location: /index.php?envoiDuMessage=non&message=".Encoding::myUrlEncode($message));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<veille>
|
||||
<message>
|
||||
<originel>test http://new.emmanuelroy.name</originel>
|
||||
<text>test</text>
|
||||
<links>
|
||||
<link>http://new.emmanuelroy.name</link>
|
||||
</links>
|
||||
</message>
|
||||
</veille>
|
Loading…
Reference in New Issue