PageRenderTime 52ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/spip/ecrire/auth/spip.php

https://github.com/eyeswebcrea/espace-couture-sittler.fr
PHP | 339 lines | 184 code | 45 blank | 110 comment | 36 complexity | 14c55408deb2c13ea558742eb4f245d6 MD5 | raw file
Possible License(s): LGPL-2.1, GPL-3.0
  1. <?php
  2. /***************************************************************************\
  3. * SPIP, Systeme de publication pour l'internet *
  4. * *
  5. * Copyright (c) 2001-2011 *
  6. * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
  7. * *
  8. * Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
  9. * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
  10. \***************************************************************************/
  11. if (!defined('_ECRIRE_INC_VERSION')) return;
  12. // Authentifie et si ok retourne le tableau de la ligne SQL de l'utilisateur
  13. // Si risque de secu repere a l'installation retourne False
  14. function auth_spip_dist ($login, $pass, $serveur='') {
  15. // retrouver le login
  16. $login = auth_spip_retrouver_login($login);
  17. // login inconnu, n'allons pas plus loin
  18. if (!$login) return array();
  19. $md5pass = $md5next = "";
  20. $shapass = $shanext = "";
  21. if (preg_match(",^\{([0-9a-f]{64});([0-9a-f]{64})\}$,i",$pass,$regs)){
  22. $shapass = $regs[1];
  23. $shanext = $regs[2];
  24. $pass="";
  25. }
  26. // compat avec une base mixte md5/sha256 : le js a envoye les 2 hash
  27. elseif (preg_match(",^\{([0-9a-f]{64});([0-9a-f]{64});([0-9a-f]{32});([0-9a-f]{32})\}$,i",$pass,$regs)){
  28. $shapass = $regs[1];
  29. $shanext = $regs[2];
  30. $md5pass = $regs[3];
  31. $md5next = $regs[4];
  32. $pass="";
  33. }
  34. // si envoi non crypte, crypter maintenant
  35. elseif ($pass) {
  36. $row = sql_fetsel("alea_actuel, alea_futur", "spip_auteurs", "login=" . sql_quote($login),'','','','',$serveur);
  37. if ($row) {
  38. include_spip('auth/sha256.inc');
  39. $shapass = _nano_sha256($row['alea_actuel'] . $pass);
  40. $shanext = _nano_sha256($row['alea_futur'] . $pass);
  41. $md5pass = md5($row['alea_actuel'] . $pass);
  42. }
  43. }
  44. // login inexistant ou mot de passe vide
  45. if (!$shapass AND !$md5pass) return array();
  46. $row = sql_fetsel("*", "spip_auteurs", "login=" . sql_quote($login) . " AND pass=" . sql_quote($shapass) . " AND statut<>'5poubelle'",'','','','',$serveur);
  47. // compat avec les anciennes bases en md5
  48. if (!$row AND $md5pass)
  49. $row = sql_fetsel("*", "spip_auteurs", "login=" . sql_quote($login) . " AND pass=" . sql_quote($md5pass) . " AND statut<>'5poubelle'",'','','','',$serveur);
  50. // login/mot de passe incorrect
  51. if (!$row) return array();
  52. // fait tourner le codage du pass dans la base
  53. if ($shanext) {
  54. include_spip('inc/acces'); // pour creer_uniqid
  55. @sql_update('spip_auteurs', array('alea_actuel' => 'alea_futur', 'pass' => sql_quote($shanext), 'alea_futur' => sql_quote(creer_uniqid())), "id_auteur=" . $row['id_auteur'].' AND pass IN ('.sql_quote($shapass).', '.sql_quote($md5pass).')','',$serveur);
  56. // En profiter pour verifier la securite de tmp/
  57. // Si elle ne fonctionne pas a l'installation, prevenir
  58. if (!verifier_htaccess(_DIR_TMP) AND defined('_ECRIRE_INSTALL'))
  59. return false;
  60. }
  61. return $row;
  62. }
  63. function auth_spip_formulaire_login($flux){
  64. // faut il encore envoyer md5 ?
  65. // on regarde si il reste des pass md5 en base pour des auteurs en statut pas poubelle
  66. // les hash md5 ont une longueur 32, les sha 64
  67. $compat_md5 = sql_countsel("spip_auteurs", "length(pass)=32 AND statut<>'poubelle'");
  68. // javascript qui gere la securite du login en evitant de faire circuler le pass en clair
  69. $flux['data'].=
  70. ($compat_md5?'<script type="text/javascript" src="'._DIR_JAVASCRIPT.'md5.js"></script>':'')
  71. . '<script type="text/javascript" src="'._DIR_JAVASCRIPT.'sha256.js"></script>'
  72. .'<script type="text/javascript" src="'._DIR_JAVASCRIPT.'login.js"></script>'
  73. .'<script type="text/javascript">/*<![CDATA[*/'
  74. ."var alea_actuel='".$flux['args']['contexte']['_alea_actuel']."';"
  75. ."var alea_futur='".$flux['args']['contexte']['_alea_futur']."';"
  76. ."var login='".$flux['args']['contexte']['var_login']."';"
  77. ."var page_auteur = '".generer_url_public('informer_auteur')."';"
  78. ."var informe_auteur_en_cours = false;"
  79. ."var attente_informe = 0;"
  80. ."var compat_md5 = ".($compat_md5?"true;":"false;")
  81. ."jQuery(function(){
  82. jQuery('#password')
  83. .after(\"<em id='pass_securise'><img src='"._DIR_IMG_PACK."securise.gif' width='16' height='16' alt='" . attribut_html(_T('login_securise')) . "' title='" . attribut_html(_T('login_securise')) . "' \/><\/em>\");
  84. affiche_login_secure();
  85. jQuery('#var_login').change(actualise_auteur);
  86. jQuery('form#formulaire_login').submit(login_submit);
  87. });"
  88. ."/*]]>*/</script>";
  89. return $flux;
  90. }
  91. /**
  92. * Informer du droit de modifier ou non son login
  93. * @return bool
  94. * toujours true pour un auteur cree dans SPIP
  95. */
  96. function auth_spip_autoriser_modifier_login($serveur=''){
  97. if (strlen($serveur))
  98. return false; // les fonctions d'ecriture sur base distante sont encore incompletes
  99. return true;
  100. }
  101. /**
  102. * Verification de la validite d'un login pour le mode d'auth concerne
  103. *
  104. * @param string $new_login
  105. * @param int $id_auteur
  106. * si auteur existant deja
  107. * @return string
  108. * message d'erreur si login non valide, chaine vide sinon
  109. */
  110. function auth_spip_verifier_login($new_login, $id_auteur=0, $serveur=''){
  111. // login et mot de passe
  112. if (strlen($new_login)){
  113. if (strlen($new_login) < _LOGIN_TROP_COURT)
  114. return 'info_login_trop_court';
  115. else {
  116. $n = sql_countsel('spip_auteurs', "login=" . sql_quote($new_login) . " AND id_auteur!=".intval($id_auteur)." AND statut!='5poubelle'",'','',$serveur);
  117. if ($n)
  118. return _T('info_login_existant');
  119. }
  120. }
  121. return '';
  122. }
  123. /**
  124. * Modifier le login d'un auteur SPIP
  125. *
  126. * @param string $new_login
  127. * @param int $id_auteur
  128. * @return bool
  129. */
  130. function auth_spip_modifier_login($new_login, $id_auteur, $serveur=''){
  131. if (is_null($new_login) OR auth_spip_verifier_login($new_login,$id_auteur,$serveur)!='')
  132. return false;
  133. if (!$id_auteur = intval($id_auteur)
  134. OR !$auteur = sql_fetsel('login','spip_auteurs','id_auteur='.intval($id_auteur),'','','','',$serveur))
  135. return false;
  136. if ($new_login == $auteur['login'])
  137. return true; // on a rien fait mais c'est bon !
  138. include_spip('inc/modifier');
  139. // vider le login des auteurs a la poubelle qui avaient ce meme login
  140. if (strlen($new_login)){
  141. $anciens = sql_select('id_auteur','spip_auteurs','login='.sql_quote($new_login)." AND statut='5poubelle'",'','','','',$serveur);
  142. while ($row = sql_fetch($anciens)){
  143. revision_auteur($row['id_auteur'], array('login'=>'')); // manque la gestion de $serveur
  144. }
  145. }
  146. include_spip('inc/modifier');
  147. revision_auteur($id_auteur, array('login'=>$new_login)); // manque la gestion de $serveur
  148. return true;
  149. }
  150. /**
  151. * Retrouver le login de quelqu'un qui cherche a se loger
  152. * Reconnaitre aussi ceux qui donnent leur nom ou email au lieu du login
  153. *
  154. * @param string $login
  155. * @return string
  156. */
  157. function auth_spip_retrouver_login($login, $serveur=''){
  158. if (!strlen($login)) return null; // pas la peine de requeter
  159. $l = sql_quote($login);
  160. if ($r = sql_getfetsel('login', 'spip_auteurs',
  161. "statut<>'5poubelle'" .
  162. " AND (length(pass)>0)" .
  163. " AND (login=$l)",'','','','',$serveur))
  164. return $r;
  165. // Si pas d'auteur avec ce login
  166. // regarder s'il a saisi son nom ou son mail.
  167. // Ne pas fusionner avec la requete precedente
  168. // car un nom peut etre homonyme d'un autre login
  169. else return sql_getfetsel('login', 'spip_auteurs',
  170. "statut<>'5poubelle'" .
  171. " AND (length(pass)>0)" .
  172. " AND (login<>'' AND (nom=$l OR email=$l))",'','','','',$serveur);
  173. }
  174. /**
  175. * informer sur un login
  176. * Ce dernier transmet le tableau ci-dessous a la fonction JS informer_auteur
  177. * Il est invoque par la fonction JS actualise_auteur via la globale JS
  178. * page_auteur=#URL_PAGE{informer_auteur} dans le squelette login
  179. * N'y aurait-il pas plus simple ?
  180. *
  181. * @param array $infos
  182. * @param array $row
  183. * @param string $serveur
  184. * @return array
  185. */
  186. function auth_spip_informer_login($infos, $row, $serveur=''){
  187. // pour la methode SPIP on a besoin des alea en plus pour encoder le pass avec
  188. $infos['alea_actuel'] = $row['alea_actuel'];
  189. $infos['alea_futur'] = $row['alea_futur'];
  190. return $infos;
  191. }
  192. /**
  193. * Informer du droit de modifier ou non le pass
  194. * @return bool
  195. * toujours true pour un auteur cree dans SPIP
  196. */
  197. function auth_spip_autoriser_modifier_pass($serveur=''){
  198. if (strlen($serveur))
  199. return false; // les fonctions d'ecriture sur base distante sont encore incompletes
  200. return true;
  201. }
  202. /**
  203. * Verification de la validite d'un mot de passe pour le mode d'auth concerne
  204. * c'est ici que se font eventuellement les verifications de longueur mini/maxi
  205. * ou de force
  206. *
  207. * @param string $new_pass
  208. * @param string $login
  209. * le login de l'auteur : permet de verifier que pass et login sont differents
  210. * meme a la creation lorsque l'auteur n'existe pas encore
  211. * @param int $id_auteur
  212. * si auteur existant deja
  213. * @return string
  214. * message d'erreur si login non valide, chaine vide sinon
  215. */
  216. function auth_spip_verifier_pass($login, $new_pass, $id_auteur=0, $serveur=''){
  217. // login et mot de passe
  218. if (strlen($new_pass) < 6)
  219. return _T('info_passe_trop_court');
  220. return '';
  221. }
  222. function auth_spip_modifier_pass($login, $new_pass, $id_auteur, $serveur=''){
  223. if (is_null($new_pass) OR auth_spip_verifier_pass($login, $new_pass,$id_auteur,$serveur)!='')
  224. return false;
  225. if (!$id_auteur = intval($id_auteur)
  226. OR !$auteur = sql_fetsel('login','spip_auteurs','id_auteur='.intval($id_auteur),'','','','',$serveur))
  227. return false;
  228. $c = array();
  229. include_spip('inc/acces');
  230. include_spip('auth/sha256.inc');
  231. $htpass = generer_htpass($new_pass);
  232. $alea_actuel = creer_uniqid();
  233. $alea_futur = creer_uniqid();
  234. $pass = _nano_sha256($alea_actuel.$new_pass);
  235. $c['pass'] = $pass;
  236. $c['htpass'] = $htpass;
  237. $c['alea_actuel'] = $alea_actuel;
  238. $c['alea_futur'] = $alea_futur;
  239. $c['low_sec'] = '';
  240. include_spip('inc/modifier');
  241. revision_auteur($id_auteur, $c); // manque la gestion de $serveur
  242. }
  243. /**
  244. * Synchroniser les fichiers htpasswd
  245. *
  246. * @param int $id_auteur
  247. * @param array $champs
  248. * @param array $options
  249. * all=>true permet de demander la regeneration complete des acces apres operation en base (import, upgrade)
  250. * @return void
  251. */
  252. function auth_spip_synchroniser_distant($id_auteur, $champs, $options = array(), $serveur=''){
  253. // ne rien faire pour une base distante : on ne sait pas regenerer les htaccess
  254. if (strlen($serveur))
  255. return;
  256. // si un login, pass ou statut a ete modifie
  257. // regenerer les fichier htpass
  258. if (isset($champs['login'])
  259. OR isset($champs['pass'])
  260. OR isset($champs['statut'])
  261. OR (isset($options['all']) AND $options['all'])
  262. ) {
  263. $htaccess = _DIR_RESTREINT . _ACCESS_FILE_NAME;
  264. $htpasswd = _DIR_TMP . _AUTH_USER_FILE;
  265. // Cette variable de configuration peut etre posee par un plugin
  266. // par exemple acces_restreint ;
  267. // si .htaccess existe, outrepasser spip_meta
  268. if (($GLOBALS['meta']['creer_htpasswd'] != 'oui')
  269. AND !@file_exists($htaccess)) {
  270. spip_unlink($htpasswd);
  271. spip_unlink($htpasswd."-admin");
  272. return;
  273. }
  274. # remarque : ici on laisse passer les "nouveau" de maniere a leur permettre
  275. # de devenir redacteur le cas echeant (auth http)... a nettoyer
  276. // attention, il faut au prealable se connecter a la base (necessaire car utilise par install)
  277. $p1 = ''; // login:htpass pour tous
  278. $p2 = ''; // login:htpass pour les admins
  279. $s = sql_select("login, htpass, statut", "spip_auteurs", sql_in("statut", array('1comite','0minirezo','nouveau')));
  280. while ($t = sql_fetch($s)) {
  281. if (strlen($t['login']) AND strlen($t['htpass'])) {
  282. $p1 .= $t['login'].':'.$t['htpass']."\n";
  283. if ($t['statut'] == '0minirezo')
  284. $p2 .= $t['login'].':'.$t['htpass']."\n";
  285. }
  286. }
  287. if ($p1) {
  288. ecrire_fichier($htpasswd, $p1);
  289. ecrire_fichier($htpasswd.'-admin', $p2);
  290. spip_log("Ecriture de $htpasswd et $htpasswd-admin");
  291. }
  292. }
  293. }
  294. ?>