import initial
parent
7bf46c52bd
commit
105db05142
@ -0,0 +1,353 @@
|
||||
<?php
|
||||
|
||||
/***************************************************************************\
|
||||
* SPIP, Système de publication pour l'internet *
|
||||
* *
|
||||
* Copyright © avec tendresse depuis 2001 *
|
||||
* Arnaud Martin, Antoine Pitrou, Philippe Rivière, Emmanuel Saint-James *
|
||||
* *
|
||||
* Ce programme est un logiciel libre distribué sous licence GNU/GPL. *
|
||||
* Pour plus de détails voir le fichier COPYING.txt ou l'aide en ligne. *
|
||||
\***************************************************************************/
|
||||
|
||||
/**
|
||||
* Gestion de l'authentification par SPIP
|
||||
*
|
||||
* @package SPIP\Core\Authentification\SPIP
|
||||
**/
|
||||
|
||||
if (!defined('_ECRIRE_INC_VERSION')) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Authentifie et si ok retourne le tableau de la ligne SQL de l'utilisateur
|
||||
* Si risque de secu repere a l'installation retourne False
|
||||
*
|
||||
* @param string $login
|
||||
* @param string $pass
|
||||
* @param string $serveur
|
||||
* @param bool $phpauth
|
||||
* @return array|bool
|
||||
*/
|
||||
function auth_spip_dist($login, $pass, $serveur = '', $phpauth = false) {
|
||||
|
||||
// retrouver le login
|
||||
$login = auth_spip_retrouver_login($login);
|
||||
// login inconnu, n'allons pas plus loin
|
||||
if (!$login) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$md5pass = "";
|
||||
$shapass = $shanext = "";
|
||||
|
||||
if ($pass) {
|
||||
$row = sql_fetsel("alea_actuel, alea_futur", "spip_auteurs", "login=" . sql_quote($login, $serveur, 'text'), '', '',
|
||||
'', '', $serveur);
|
||||
|
||||
if ($row) {
|
||||
include_spip('auth/sha256.inc');
|
||||
$shapass = spip_sha256($row['alea_actuel'] . $pass);
|
||||
$shanext = spip_sha256($row['alea_futur'] . $pass);
|
||||
$md5pass = md5($row['alea_actuel'] . $pass);
|
||||
}
|
||||
}
|
||||
|
||||
// login inexistant ou mot de passe vide
|
||||
if (!$shapass and !$md5pass) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$row = sql_fetsel("*", "spip_auteurs",
|
||||
"login=" . sql_quote($login, $serveur, 'text') . " AND statut<>'5poubelle'", '', '', '', '', $serveur);
|
||||
|
||||
include_spip("chiffrer_fonctions");
|
||||
if ( $row["pass"] != $md5pass AND
|
||||
dechiffrer($row["pass"]) != $md5pass AND
|
||||
$row["pass"] != $shapass AND
|
||||
dechiffrer($row["pass"]) != $shapass ){
|
||||
unset($row);
|
||||
}
|
||||
|
||||
|
||||
// login/mot de passe incorrect
|
||||
if (!$row) {
|
||||
return array();
|
||||
}
|
||||
|
||||
// fait tourner le codage du pass dans la base
|
||||
// sauf si phpauth : cela reviendrait a changer l'alea a chaque hit, et aucune action verifiable par securiser_action()
|
||||
if ($shanext and !$phpauth) {
|
||||
|
||||
include_spip('inc/acces'); // pour creer_uniqid
|
||||
@sql_update('spip_auteurs', array(
|
||||
'alea_actuel' => 'alea_futur',
|
||||
'pass' => sql_quote(chiffrer($shanext), $serveur, 'text'),
|
||||
'alea_futur' => sql_quote(creer_uniqid(), $serveur, 'text')
|
||||
), "id_auteur=" . $row['id_auteur'] . ' AND pass IN (' . sql_quote($shapass, $serveur,
|
||||
'text') . ', ' . sql_quote($md5pass, $serveur, 'text') . ')', '', $serveur);
|
||||
// En profiter pour verifier la securite de tmp/
|
||||
// Si elle ne fonctionne pas a l'installation, prevenir
|
||||
if (!verifier_htaccess(_DIR_TMP) and defined('_ECRIRE_INSTALL')) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Informer du droit de modifier ou non son login
|
||||
*
|
||||
* @param string $serveur
|
||||
* @return bool
|
||||
* toujours true pour un auteur cree dans SPIP
|
||||
*/
|
||||
function auth_spip_autoriser_modifier_login($serveur = '') {
|
||||
if (strlen($serveur)) {
|
||||
return false;
|
||||
} // les fonctions d'ecriture sur base distante sont encore incompletes
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verification de la validite d'un login pour le mode d'auth concerne
|
||||
*
|
||||
* @param string $new_login
|
||||
* @param int $id_auteur
|
||||
* si auteur existant deja
|
||||
* @param string $serveur
|
||||
* @return string
|
||||
* message d'erreur si login non valide, chaine vide sinon
|
||||
*/
|
||||
function auth_spip_verifier_login($new_login, $id_auteur = 0, $serveur = '') {
|
||||
// login et mot de passe
|
||||
if (strlen($new_login)) {
|
||||
if (strlen($new_login) < _LOGIN_TROP_COURT) {
|
||||
return _T('info_login_trop_court_car_pluriel', array('nb' => _LOGIN_TROP_COURT));
|
||||
} else {
|
||||
$n = sql_countsel('spip_auteurs',
|
||||
"login=" . sql_quote($new_login) . " AND id_auteur!=" . intval($id_auteur) . " AND statut!='5poubelle'", '', '',
|
||||
$serveur);
|
||||
if ($n) {
|
||||
return _T('info_login_existant');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifier le login d'un auteur SPIP
|
||||
*
|
||||
* @param string $new_login
|
||||
* @param int $id_auteur
|
||||
* @param string $serveur
|
||||
* @return bool
|
||||
*/
|
||||
function auth_spip_modifier_login($new_login, $id_auteur, $serveur = '') {
|
||||
if (is_null($new_login) or auth_spip_verifier_login($new_login, $id_auteur, $serveur) != '') {
|
||||
return false;
|
||||
}
|
||||
if (!$id_auteur = intval($id_auteur)
|
||||
or !$auteur = sql_fetsel('login', 'spip_auteurs', 'id_auteur=' . intval($id_auteur), '', '', '', '', $serveur)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
if ($new_login == $auteur['login']) {
|
||||
return true;
|
||||
} // on a rien fait mais c'est bon !
|
||||
|
||||
include_spip('action/editer_auteur');
|
||||
|
||||
// vider le login des auteurs a la poubelle qui avaient ce meme login
|
||||
if (strlen($new_login)) {
|
||||
$anciens = sql_allfetsel('id_auteur', 'spip_auteurs',
|
||||
'login=' . sql_quote($new_login, $serveur, 'text') . " AND statut='5poubelle'", '', '', '', '', $serveur);
|
||||
while ($row = array_pop($anciens)) {
|
||||
auteur_modifier($row['id_auteur'], array('login' => ''), true); // manque la gestion de $serveur
|
||||
}
|
||||
}
|
||||
|
||||
auteur_modifier($id_auteur, array('login' => $new_login), true); // manque la gestion de $serveur
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrouver le login de quelqu'un qui cherche a se loger
|
||||
* Reconnaitre aussi ceux qui donnent leur nom ou email au lieu du login
|
||||
*
|
||||
* @param string $login
|
||||
* @param string $serveur
|
||||
* @return string
|
||||
*/
|
||||
function auth_spip_retrouver_login($login, $serveur = '') {
|
||||
if (!strlen($login)) {
|
||||
return null;
|
||||
} // pas la peine de requeter
|
||||
$l = sql_quote($login, $serveur, 'text');
|
||||
if ($r = sql_getfetsel('login', 'spip_auteurs',
|
||||
"statut<>'5poubelle'" .
|
||||
" AND (length(pass)>0)" .
|
||||
" AND (login=$l)", '', '', '', '', $serveur)
|
||||
) {
|
||||
return $r;
|
||||
}
|
||||
// Si pas d'auteur avec ce login
|
||||
// regarder s'il a saisi son nom ou son mail.
|
||||
// Ne pas fusionner avec la requete precedente
|
||||
// car un nom peut etre homonyme d'un autre login
|
||||
else {
|
||||
return sql_getfetsel('login', 'spip_auteurs',
|
||||
"statut<>'5poubelle'" .
|
||||
" AND (length(pass)>0)" .
|
||||
" AND (login<>'' AND (nom=$l OR email=$l))", '', '', '', '', $serveur);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Informer du droit de modifier ou non le pass
|
||||
*
|
||||
* @param string $serveur
|
||||
* @return bool
|
||||
* toujours true pour un auteur cree dans SPIP
|
||||
*/
|
||||
function auth_spip_autoriser_modifier_pass($serveur = '') {
|
||||
if (strlen($serveur)) {
|
||||
return false;
|
||||
} // les fonctions d'ecriture sur base distante sont encore incompletes
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verification de la validite d'un mot de passe pour le mode d'auth concerne
|
||||
* c'est ici que se font eventuellement les verifications de longueur mini/maxi
|
||||
* ou de force
|
||||
*
|
||||
* @param string $login
|
||||
* Le login de l'auteur : permet de verifier que pass et login sont differents
|
||||
* meme a la creation lorsque l'auteur n'existe pas encore
|
||||
* @param string $new_pass
|
||||
* Nouveau mot de passe
|
||||
* @param int $id_auteur
|
||||
* si auteur existant deja
|
||||
* @param string $serveur
|
||||
* @return string
|
||||
* message d'erreur si login non valide, chaine vide sinon
|
||||
*/
|
||||
function auth_spip_verifier_pass($login, $new_pass, $id_auteur = 0, $serveur = '') {
|
||||
// login et mot de passe
|
||||
if (strlen($new_pass) < _PASS_LONGUEUR_MINI) {
|
||||
return _T('info_passe_trop_court_car_pluriel', array('nb' => _PASS_LONGUEUR_MINI));
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifier le mot de passe de l'auteur sur le serveur concerne
|
||||
* en s'occupant du hash et companie
|
||||
*
|
||||
* @param string $login
|
||||
* @param string $new_pass
|
||||
* @param int $id_auteur
|
||||
* @param string $serveur
|
||||
* @return bool
|
||||
*/
|
||||
function auth_spip_modifier_pass($login, $new_pass, $id_auteur, $serveur = '') {
|
||||
if (is_null($new_pass) or auth_spip_verifier_pass($login, $new_pass, $id_auteur, $serveur) != '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$id_auteur = intval($id_auteur)
|
||||
or !sql_fetsel('login', 'spip_auteurs', 'id_auteur=' . intval($id_auteur), '', '', '', '', $serveur)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$c = array();
|
||||
include_spip('inc/acces');
|
||||
include_spip('auth/sha256.inc');
|
||||
include_spip("chiffrer_fonctions");
|
||||
$htpass = generer_htpass($new_pass);
|
||||
$alea_actuel = creer_uniqid();
|
||||
$alea_futur = creer_uniqid();
|
||||
$pass = chiffrer(spip_sha256($alea_actuel . $new_pass));
|
||||
$c['pass'] = $pass;
|
||||
$c['htpass'] = $htpass;
|
||||
$c['alea_actuel'] = $alea_actuel;
|
||||
$c['alea_futur'] = $alea_futur;
|
||||
$c['low_sec'] = '';
|
||||
|
||||
include_spip('action/editer_auteur');
|
||||
auteur_modifier($id_auteur, $c, true); // manque la gestion de $serveur
|
||||
|
||||
return true; // on a bien modifie le pass
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchroniser les fichiers htpasswd
|
||||
*
|
||||
* @param int $id_auteur
|
||||
* @param array $champs
|
||||
* @param array $options
|
||||
* all=>true permet de demander la regeneration complete des acces apres operation en base (import, upgrade)
|
||||
* @param string $serveur
|
||||
* @return void
|
||||
*/
|
||||
function auth_spip_synchroniser_distant($id_auteur, $champs, $options = array(), $serveur = '') {
|
||||
// ne rien faire pour une base distante : on ne sait pas regenerer les htaccess
|
||||
if (strlen($serveur)) {
|
||||
return;
|
||||
}
|
||||
// si un login, pass ou statut a ete modifie
|
||||
// regenerer les fichier htpass
|
||||
if (isset($champs['login'])
|
||||
or isset($champs['pass'])
|
||||
or isset($champs['statut'])
|
||||
or (isset($options['all']) and $options['all'])
|
||||
) {
|
||||
|
||||
$htaccess = _DIR_RESTREINT . _ACCESS_FILE_NAME;
|
||||
$htpasswd = _DIR_TMP . _AUTH_USER_FILE;
|
||||
|
||||
// Cette variable de configuration peut etre posee par un plugin
|
||||
// par exemple acces_restreint ;
|
||||
// si .htaccess existe, outrepasser spip_meta
|
||||
if ((!isset($GLOBALS['meta']['creer_htpasswd']) or ($GLOBALS['meta']['creer_htpasswd'] != 'oui'))
|
||||
and !@file_exists($htaccess)
|
||||
) {
|
||||
spip_unlink($htpasswd);
|
||||
spip_unlink($htpasswd . "-admin");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
# remarque : ici on laisse passer les "nouveau" de maniere a leur permettre
|
||||
# de devenir redacteur le cas echeant (auth http)... a nettoyer
|
||||
// attention, il faut au prealable se connecter a la base (necessaire car utilise par install)
|
||||
|
||||
$p1 = ''; // login:htpass pour tous
|
||||
$p2 = ''; // login:htpass pour les admins
|
||||
$s = sql_select("login, htpass, statut", "spip_auteurs",
|
||||
sql_in("statut", array('1comite', '0minirezo', 'nouveau')));
|
||||
while ($t = sql_fetch($s)) {
|
||||
if (strlen($t['login']) and strlen($t['htpass'])) {
|
||||
$p1 .= $t['login'] . ':' . $t['htpass'] . "\n";
|
||||
if ($t['statut'] == '0minirezo') {
|
||||
$p2 .= $t['login'] . ':' . $t['htpass'] . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
sql_free($s);
|
||||
if ($p1) {
|
||||
ecrire_fichier($htpasswd, $p1);
|
||||
ecrire_fichier($htpasswd . '-admin', $p2);
|
||||
spip_log("Ecriture de $htpasswd et $htpasswd-admin");
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
/**
|
||||
* Fichier gérant l'installation et désinstallation du plugin Chiffrer
|
||||
*
|
||||
* @plugin Chiffrer
|
||||
* @copyright 2021
|
||||
* @author g0uZ
|
||||
* @licence GNU/GPL
|
||||
* @package SPIP\Chiffrer\Installation
|
||||
*/
|
||||
|
||||
if (!defined('_ECRIRE_INC_VERSION')) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Installation de la clé de chiffrement
|
||||
*/
|
||||
function chiffrement_installation(){
|
||||
include_spip("chiffrer_fonctions");
|
||||
|
||||
initialiser_cle();
|
||||
|
||||
// pour * pass : chiffrer
|
||||
$res = sql_allfetsel(array('id_auteur','pass'), 'spip_auteurs', "length(pass)<=64 AND statut='0minirezo'");
|
||||
foreach ($res as $r){
|
||||
$pass_chiffre = chiffrer($r["pass"]);
|
||||
sql_update('spip_auteurs', array('pass' => sql_quote($pass_chiffre)), "id_auteur=" . $r['id_auteur']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Suppression de la clé de chiffrement
|
||||
*/
|
||||
function chiffrement_desinstallation(){
|
||||
include_spip("chiffrer_fonctions");
|
||||
|
||||
// pour * pass : dechiffrer
|
||||
$res = sql_allfetsel(array('id_auteur','pass'), 'spip_auteurs', "length(pass)>64 AND statut='0minirezo'");
|
||||
foreach ($res as $r){
|
||||
$pass_dechiffre = dechiffrer($r["pass"]);
|
||||
sql_update('spip_auteurs', array('pass' => sql_quote($pass_dechiffre)), "id_auteur=" . $r['id_auteur']);
|
||||
}
|
||||
supprimer_cle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fonction d'installation et de mise à jour du plugin Chiffrer.
|
||||
*
|
||||
* @param string $nom_meta_base_version
|
||||
* Nom de la meta informant de la version du schéma de données du plugin installé dans SPIP
|
||||
* @param string $version_cible
|
||||
* Version du schéma de données dans ce plugin (déclaré dans paquet.xml)
|
||||
* @return void
|
||||
**/
|
||||
function chiffrer_upgrade($nom_meta_base_version, $version_cible) {
|
||||
$maj = array();
|
||||
|
||||
// $maj['create'] = array(
|
||||
// array('chiffrement_installation'),
|
||||
// );
|
||||
//
|
||||
chiffrement_installation();
|
||||
|
||||
include_spip('base/upgrade');
|
||||
maj_plugin($nom_meta_base_version, $version_cible, $maj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fonction de désinstallation du plugin Chiffrer.
|
||||
*
|
||||
* @param string $nom_meta_base_version
|
||||
* Nom de la meta informant de la version du schéma de données du plugin installé dans SPIP
|
||||
* @return void
|
||||
**/
|
||||
function chiffrer_vider_tables($nom_meta_base_version) {
|
||||
chiffrement_desinstallation();
|
||||
effacer_meta($nom_meta_base_version);
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/**
|
||||
* Fonctions utiles au plugin Chiffrer
|
||||
*
|
||||
* @plugin Chiffrer
|
||||
* @copyright 2021
|
||||
* @author g0uZ
|
||||
* @licence GNU/GPL
|
||||
* @package SPIP\Chiffrer\Fonctions
|
||||
*/
|
||||
|
||||
if (!defined('_ECRIRE_INC_VERSION')) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function initialiser_cle(){
|
||||
if ( $fichier_cles = find_in_path("chiffrer_options.php") ){
|
||||
$GLOBALS['cle_secrete'] = openssl_random_pseudo_bytes(16);
|
||||
ecrire_fichier($fichier_cles, "<?php\n\n\$GLOBALS['cle_secrete'] = base64_decode('".base64_encode($GLOBALS['cle_secrete'])."');\n");
|
||||
}
|
||||
}
|
||||
|
||||
function supprimer_cle(){
|
||||
if ( $fichier_cles = find_in_path("chiffrer_options.php") ){
|
||||
ecrire_fichier($fichier_cles, '');
|
||||
}
|
||||
}
|
||||
|
||||
function chiffrer($clair){
|
||||
$cipher="AES-128-CBC";
|
||||
$ivlen = openssl_cipher_iv_length($cipher);
|
||||
$iv = openssl_random_pseudo_bytes($ivlen);
|
||||
$chiffre_raw = openssl_encrypt($clair, $cipher, $GLOBALS['cle_secrete'], $options=OPENSSL_RAW_DATA, $iv);
|
||||
$hmac = hash_hmac('sha256', $chiffre_raw, $GLOBALS['cle_secrete'], $as_binary=true);
|
||||
$chiffre = base64_encode( $iv.$hmac.$chiffre_raw );
|
||||
spip_log("chiffrer($clair)=$chiffre", _LOG_DEBUG);
|
||||
return $chiffre;
|
||||
}
|
||||
|
||||
function dechiffrer($chiffre){
|
||||
$cipher="AES-128-CBC";
|
||||
$c = base64_decode($chiffre);
|
||||
$ivlen = openssl_cipher_iv_length($cipher);
|
||||
$iv = substr($c, 0, $ivlen);
|
||||
$hmac = substr($c, $ivlen, $sha2len=32);
|
||||
$chiffre_raw = substr($c, $ivlen+$sha2len);
|
||||
$clair = openssl_decrypt($chiffre_raw, $cipher, $GLOBALS['cle_secrete'], $options=OPENSSL_RAW_DATA, $iv);
|
||||
spip_log("dechiffrer($chiffre)=$clair", _LOG_DEBUG);
|
||||
$calcmac = hash_hmac('sha256', $chiffre_raw, $GLOBALS['cle_secrete'], $as_binary=true);
|
||||
if ( hash_equals($hmac, $calcmac) ){ // timing attack safe comparison
|
||||
return $clair;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
$GLOBALS['cle_secrete'] = base64_decode('0Gm2Jlxf84zs+TBOlWUHPA==');
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
// This is a SPIP language file -- Ceci est un fichier langue de SPIP
|
||||
|
||||
if (!defined('_ECRIRE_INC_VERSION')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$GLOBALS[$GLOBALS['idx_lang']] = array(
|
||||
|
||||
// C
|
||||
'chiffrer_titre' => 'Chiffrer',
|
||||
);
|
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
// This is a SPIP language file -- Ceci est un fichier langue de SPIP
|
||||
|
||||
if (!defined('_ECRIRE_INC_VERSION')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$GLOBALS[$GLOBALS['idx_lang']] = array(
|
||||
|
||||
// C
|
||||
'chiffrer_description' => 'Ajoute un mécanisme de chiffrement/déchiffrement à Spip.',
|
||||
'chiffrer_nom' => 'Chiffrer',
|
||||
'chiffrer_slogan' => 'Protéger vos données en les chiffrant !',
|
||||
);
|
@ -0,0 +1,25 @@
|
||||
<paquet
|
||||
prefix="chiffrer"
|
||||
categorie="outil"
|
||||
version="1.0.0"
|
||||
etat="dev"
|
||||
compatibilite="[4.0.0;4.0.*]"
|
||||
logo="prive/themes/spip/images/chiffrer-xx.svg"
|
||||
documentation=""
|
||||
schema="1.0.0"
|
||||
>
|
||||
<!--
|
||||
Paquet généré le 2021-09-08 16:32:03
|
||||
-->
|
||||
|
||||
<nom>Chiffrer</nom>
|
||||
<!-- Protéger vos données en les chiffrant ! -->
|
||||
|
||||
<auteur lien='https://www.root-me.org/'>g0uZ</auteur>
|
||||
<credit lien="https://commons.wikimedia.org/wiki/File:Breezeicons-actions-32-document-encrypted.svg">Logo : commons.wikimedia.org</credit>
|
||||
|
||||
<licence>GNU/GPL</licence>
|
||||
|
||||
|
||||
|
||||
</paquet>
|
Loading…
Reference in New Issue