diff options
Diffstat (limited to 'controller/password.php')
-rw-r--r-- | controller/password.php | 346 |
1 files changed, 191 insertions, 155 deletions
diff --git a/controller/password.php b/controller/password.php index fa4f2c1..5e556e9 100644 --- a/controller/password.php +++ b/controller/password.php | |||
@@ -1,27 +1,31 @@ | |||
1 | <?php | 1 | <?php |
2 | // controller/password.php | 2 | // controller/password.php |
3 | // | ||
4 | // fichier data/password.txt et test captcha | ||
3 | 5 | ||
4 | // exécutée dans installation.php à l'ouverture de chaque page | 6 | // exécutée dans installation.php à l'ouverture de chaque page |
5 | function existPassword() | 7 | function existPassword() |
6 | { | 8 | { |
7 | // création du fichier | ||
8 | if(!file_exists('data/password.txt')) | ||
9 | { | ||
10 | touch('data/password.txt'); | ||
11 | chmod('data/password.txt', 0600); | ||
12 | } | ||
13 | |||
14 | // lecture | 9 | // lecture |
15 | $hashedPassword = file_get_contents('data/password.txt'); | 10 | $file_name = 'data/password.txt'; |
11 | $hashedPassword = file_get_contents($file_name); | ||
16 | if($hashedPassword === false) | 12 | if($hashedPassword === false) |
17 | { | 13 | { |
18 | echo('Erreur: ouverture du fichier password.txt impossible.'); | 14 | echo('Erreur: ouverture du fichier ' . $file_name . ' impossible.'); |
19 | exit(); | 15 | exit(); |
20 | } | 16 | } |
21 | 17 | ||
18 | $file_name = 'data/tmp/solution.txt'; | ||
22 | if(empty($hashedPassword)) | 19 | if(empty($hashedPassword)) |
23 | { | 20 | { |
21 | unset($_GET); | ||
24 | createPassword(); | 22 | createPassword(); |
23 | exit(); | ||
24 | } | ||
25 | // nettoyage | ||
26 | elseif(isset($_GET['page']) && $_GET['page'] != 'connexion' && file_exists($file_name)) | ||
27 | { | ||
28 | unlink($file_name); | ||
25 | } | 29 | } |
26 | } | 30 | } |
27 | 31 | ||
@@ -90,210 +94,247 @@ function controlCaptchaInput(): int | |||
90 | 94 | ||
91 | function createPassword() | 95 | function createPassword() |
92 | { | 96 | { |
93 | // paranoïa? | 97 | // I - traitement |
94 | if(isset($_SESSION['admin'])) | 98 | // cas anormal: session déjà existante |
99 | global $cookie; // nom du cookie dans cookies.php | ||
100 | if(isset($_COOKIE[$cookie])) | ||
95 | { | 101 | { |
96 | unset($_SESSION['admin']); | 102 | deleteCookie($cookie); // cookie supprimé au rechargement |
97 | header("Location: index.php"); | 103 | header("Location: index.php"); |
98 | exit(); | 104 | exit(); |
99 | } | 105 | } |
100 | 106 | ||
101 | $captcha = createCaptcha(); | ||
102 | |||
103 | $title = 'Bienvenue Melaine Favennec'; | ||
104 | $subHeading = 'Veuillez choisir le mot de passe que vous utiliserez pour gérer le site.'; | ||
105 | require('view/password.php'); | ||
106 | |||
107 | // contrôle de la saisie | 107 | // contrôle de la saisie |
108 | if(isset($_POST['motdepasse']) && !empty($_POST['motdepasse']) && isset($_POST['captcha']) && (int) $_POST['captcha'] == $_SESSION['captcha']) | 108 | $file_name = 'data/tmp/solution.txt'; |
109 | $error = ''; | ||
110 | if(file_exists($file_name)) | ||
109 | { | 111 | { |
110 | // caractères non désirés supprimés | 112 | $captcha_solution = file_get_contents($file_name); |
111 | // impossible d'entrer un espace ou une tabulation et de valider par erreur | 113 | unlink($file_name); |
112 | require('controller/Security.php'); | ||
113 | $password = Security::secureString($_POST['motdepasse']); | ||
114 | $password = removeSpacesTabsCRLF($_POST['motdepasse']); | ||
115 | 114 | ||
116 | // enregistrement | 115 | if(empty($_POST)) // page rechargée |
117 | if(isset($password) && $password == $_POST['motdepasse']) | 116 | {} |
117 | elseif(!isset($_POST['captcha']) || controlCaptchaInput() == 0) | ||
118 | { | ||
119 | $error = 'error_non_valid_captcha'; | ||
120 | } | ||
121 | elseif($_POST['captcha'] != $captcha_solution) | ||
118 | { | 122 | { |
119 | hashNewPassword($_POST['motdepasse']); | 123 | $error = 'bad_solution_captcha'; |
120 | unset($_SESSION['captcha']); // nettoyage | 124 | } |
121 | header('Location: index.php'); | 125 | elseif(!isset($_POST['motdepasse']) || empty($_POST['motdepasse'])) |
126 | { | ||
127 | $error = 'bad_password'; | ||
122 | } | 128 | } |
123 | // mot de passe non valable | ||
124 | else | 129 | else |
125 | { | 130 | { |
126 | sleep(1); | 131 | // -> caractères HTML dangereux supprimés |
127 | echo($header); | 132 | // -> empêche validation par erreur d'une chaine "vide" |
128 | echo($errorPassword); | 133 | require('controller/Security.php'); |
129 | echo($formulaireNouveauMDP); | 134 | $password = Security::secureString($_POST['motdepasse']); |
130 | echo($errorBadCharacters); | 135 | $password = removeSpacesTabsCRLF($_POST['motdepasse']); |
136 | |||
137 | // enregistrement et redirection | ||
138 | if(isset($password) && $password == $_POST['motdepasse']) | ||
139 | { | ||
140 | hashNewPassword($_POST['motdepasse']); | ||
141 | header('Location: index.php'); | ||
142 | exit(); | ||
143 | } | ||
144 | else | ||
145 | { | ||
146 | $error = 'bad_password'; | ||
147 | } | ||
131 | } | 148 | } |
132 | } | 149 | } |
133 | // saisie non valide | 150 | else // première fois |
134 | elseif(isset($_POST['captcha']) && controlCaptchaInput() == 0) | 151 | {} |
135 | { | 152 | |
136 | sleep(1); | 153 | // inséré dans $captchaHtml puis dans $formulaireNouveauMDP |
137 | echo($header); | 154 | $captcha = createCaptcha(); |
138 | echo($errorNonValidCaptcha); | 155 | // enregistrement de la réponse du captcha pour vérification |
139 | echo($formulaireNouveauMDP); | 156 | saveSolutionCaptcha($captcha[2]); |
140 | echo($errorBadCharacters); | 157 | |
141 | } | 158 | |
142 | // mauvais captcha | 159 | // II - affichage |
143 | elseif(isset($_POST['captcha']) && (int) $_POST['captcha'] != $_SESSION['captcha']) | 160 | $title = 'Bienvenue Melaine Favennec'; |
161 | $subHeading = 'Veuillez choisir le mot de passe que vous utiliserez pour gérer le site.'; | ||
162 | |||
163 | // même vue que la fonction changerMotDePasse() | ||
164 | require('view/password.php'); | ||
165 | |||
166 | echo($header); | ||
167 | if($error != '') | ||
144 | { | 168 | { |
145 | sleep(1); | 169 | sleep(1); |
146 | echo($header); | 170 | echo($error_messages[$error]); |
147 | echo($errorCaptcha); | ||
148 | echo($formulaireNouveauMDP); | ||
149 | echo($errorBadCharacters); | ||
150 | } | ||
151 | // 1ère fois | ||
152 | else | ||
153 | { | ||
154 | echo($header); | ||
155 | echo($formulaireNouveauMDP); | ||
156 | echo($errorBadCharacters); | ||
157 | //echo($warning); // message pas top | ||
158 | } | 171 | } |
172 | echo($formulaireNouveauMDP); | ||
173 | echo($error_messages['forbidden_characters']); | ||
159 | echo($footer); | 174 | echo($footer); |
160 | |||
161 | // fois suivante (dispense de nettoyer la variable) | ||
162 | $_SESSION['captcha'] = $captcha[2]; | ||
163 | exit(); | ||
164 | } | 175 | } |
165 | 176 | ||
166 | 177 | ||
167 | function connect() | 178 | function connect() |
168 | { | 179 | { |
180 | // I - traitement | ||
169 | // déjà en mode admin | 181 | // déjà en mode admin |
170 | if($_SESSION['admin'] == 1) | 182 | global $cookie; // nom du cookie dans cookies.php |
183 | if(isset($_COOKIE[$cookie])) | ||
171 | { | 184 | { |
172 | header('Location: index.php?page=' . $_GET['from']); | 185 | header('Location: index.php?page=' . $_GET['from']); |
173 | exit(); | 186 | exit(); |
174 | } | 187 | } |
175 | 188 | ||
176 | // Ajouter une sécurité par cpatcha avec un "input" supplémentaire | 189 | // contrôle de la saisie |
190 | $file_name = 'data/tmp/solution.txt'; | ||
191 | $error = ''; | ||
192 | if(file_exists($file_name)) | ||
193 | { | ||
194 | $captcha_solution = file_get_contents($file_name); | ||
195 | unlink($file_name); | ||
196 | |||
197 | if(empty($_POST)) // page rechargée | ||
198 | {} | ||
199 | elseif(!isset($_POST['captcha']) || controlCaptchaInput() == 0) | ||
200 | { | ||
201 | $error = 'error_non_valid_captcha'; | ||
202 | } | ||
203 | elseif($_POST['captcha'] != $captcha_solution) | ||
204 | { | ||
205 | $error = 'bad_solution_captcha'; | ||
206 | } | ||
207 | elseif(!isset($_POST['motdepasse']) || empty($_POST['motdepasse'])) | ||
208 | { | ||
209 | $error = 'bad_password'; | ||
210 | } | ||
211 | else | ||
212 | { | ||
213 | // enregistrement et redirection | ||
214 | if(testPassword($_POST["motdepasse"])) | ||
215 | { | ||
216 | session_name($cookie); | ||
217 | session_start(); | ||
218 | header('Location: index.php?page=' . $_GET['from']); | ||
219 | exit(); | ||
220 | } | ||
221 | else | ||
222 | { | ||
223 | $error = 'bad_password'; | ||
224 | } | ||
225 | } | ||
226 | } | ||
227 | else // première fois | ||
228 | {} | ||
229 | |||
230 | // inséré dans $captchaHtml puis dans $formulaireNouveauMDP | ||
177 | $captcha = createCaptcha(); | 231 | $captcha = createCaptcha(); |
178 | // Et créer une variable de session pour la réponse au CAPTCHA | 232 | // enregistrement de la réponse du captcha pour vérification |
233 | saveSolutionCaptcha($captcha[2]); | ||
234 | |||
179 | 235 | ||
236 | // II - affichage | ||
180 | $title = "Connexion"; | 237 | $title = "Connexion"; |
181 | $subHeading = "Veuillez saisir votre mot de passe pour pouvoir apporter des modifications au site."; | 238 | $subHeading = "Veuillez saisir votre mot de passe pour pouvoir apporter des modifications au site."; |
182 | 239 | // même vue que la fonction changerMotDePasse() | |
183 | // cette page utilise la même vue que la fonction changerMotDePasse() dans controller/admin.php | ||
184 | require('view/password.php'); | 240 | require('view/password.php'); |
185 | 241 | ||
186 | echo($header); | 242 | echo($header); |
187 | 243 | //echo($warning_messages['message_disconnect']); | |
188 | // bon codes (mot de passe et captcha) | 244 | if($error != '') |
189 | if(isset ($_POST["motdepasse"]) && testPassword($_POST["motdepasse"]) && isset($_POST['captcha']) && (int) $_POST['captcha'] == $_SESSION['captcha']) | ||
190 | { | ||
191 | $_SESSION['admin'] = 1; | ||
192 | unset($_SESSION['captcha']); // nettoyage | ||
193 | header('Location: index.php?page=' . $_GET['from']); | ||
194 | exit(); | ||
195 | } | ||
196 | // saisie non valide | ||
197 | elseif(isset($_POST['captcha']) && controlCaptchaInput() == 0) | ||
198 | { | ||
199 | echo($errorNonValidCaptcha); | ||
200 | sleep(1); | ||
201 | echo($formulaireConnexion); | ||
202 | } | ||
203 | // mauvais captcha | ||
204 | elseif(isset($_POST['captcha']) && (int) $_POST['captcha'] != $_SESSION['captcha']) | ||
205 | { | 245 | { |
206 | echo($errorCaptcha); | ||
207 | sleep(1); | 246 | sleep(1); |
208 | echo($formulaireConnexion); | 247 | echo($error_messages[$error]); |
209 | } | 248 | } |
249 | echo($formulaireConnexion); | ||
250 | echo($warning_messages['message_cookie']); | ||
251 | echo($warning_messages['private_browsing']); | ||
252 | echo($footer); | ||
253 | } | ||
210 | 254 | ||
211 | // mauvais codes | ||
212 | elseif(isset ($_POST["motdepasse"]) && !testPassword($_POST["motdepasse"])) | ||
213 | { | ||
214 | // défense aux attaques par force brute | ||
215 | // pas parfait, ne marche pas si l'attaquant multiplie les connexions au site | ||
216 | echo($errorPassword); | ||
217 | sleep(1); | ||
218 | echo($formulaireConnexion); | ||
219 | } | ||
220 | 255 | ||
221 | // première arrivée sur la page | 256 | function saveSolutionCaptcha(string $solution) |
222 | else | 257 | { |
223 | { | 258 | $file_name = 'data/tmp/solution.txt'; |
224 | echo($formulaireConnexion); | 259 | if(!file_exists($file_name)) |
225 | } | 260 | { |
226 | 261 | touch($file_name); | |
227 | // fois suivante (dispense de nettoyer la variable) | 262 | chmod($file_name, 0600); |
228 | $_SESSION['captcha'] = $captcha[2]; | 263 | } |
229 | 264 | file_put_contents($file_name, $solution); | |
230 | echo($messageDeconnect); | ||
231 | echo($footer); | ||
232 | } | 265 | } |
233 | 266 | ||
267 | |||
234 | function changePassword() | 268 | function changePassword() |
235 | { | 269 | { |
270 | // I - traitement | ||
236 | // vérification supplémentaire | 271 | // vérification supplémentaire |
237 | if($_SESSION['admin'] !== 1) | 272 | global $cookie; // nom du cookie dans cookies.php |
273 | if(!isset($_SESSION)) | ||
238 | { | 274 | { |
239 | $_SESSION['admin'] = 0; | 275 | deleteCookie($cookie); |
240 | header('Location: index.php?page=' . $_GET['from']); | 276 | header('Location: index.php?page=' . $_GET['from']); |
241 | exit(); | 277 | exit(); |
242 | } | 278 | } |
243 | 279 | ||
244 | $title = "Nouveau mot de passe"; | 280 | // contrôle de la saisie |
245 | $subHeading = "Veuillez saisir votre actuel mot de passe suivi du nouveau."; | 281 | $error = ''; |
246 | 282 | $success = false; | |
247 | require('view/password.php'); | 283 | if(empty($_POST)) // première fois ou page rechargée |
248 | echo($header); | 284 | {} |
249 | 285 | elseif(!isset($_POST['nouveauMotdepasse']) || empty($_POST['nouveauMotdepasse'])|| !isset($_POST['ancienMotdepasse']) || empty($_POST['ancienMotdepasse'])) | |
250 | // conformité du nouveau mot de passe | 286 | { |
251 | if(isset($_POST['nouveauMotdepasse']) && !empty($_POST['nouveauMotdepasse'])) | 287 | $error = 'bad_password'; |
288 | } | ||
289 | else | ||
252 | { | 290 | { |
253 | require('controller/Security.php'); | 291 | require('controller/Security.php'); |
254 | $newPassword = Security::secureString($_POST['nouveauMotdepasse']); | 292 | $newPassword = Security::secureString($_POST['nouveauMotdepasse']); |
255 | $newPassword = removeSpacesTabsCRLF($_POST['nouveauMotdepasse']); | 293 | $newPassword = removeSpacesTabsCRLF($_POST['nouveauMotdepasse']); |
256 | } | ||
257 | 294 | ||
258 | // bon mot de passe | 295 | if(isset($newPassword) && $newPassword !== $_POST['nouveauMotdepasse']) // erreur de conformité |
259 | if(isset($newPassword) && $newPassword === $_POST['nouveauMotdepasse'] | 296 | { |
260 | && isset ($_POST["ancienMotdepasse"]) && testPassword($_POST["ancienMotdepasse"])) | 297 | $error = 'forbidden_characters'; |
261 | { | 298 | } |
262 | // enregistrement et confirmation | 299 | else |
263 | hashNewPassword($_POST["nouveauMotdepasse"]); | 300 | { |
264 | echo($message); | 301 | if(testPassword($_POST["ancienMotdepasse"])) |
302 | { | ||
303 | // enregistrement et confirmation | ||
304 | hashNewPassword($_POST["nouveauMotdepasse"]); | ||
305 | $success = true; | ||
306 | } | ||
307 | else | ||
308 | { | ||
309 | $error = 'bad_password'; | ||
310 | } | ||
311 | } | ||
265 | } | 312 | } |
266 | // mauvais mot de passe | 313 | |
267 | elseif(isset ($_POST["ancienMotdepasse"]) && !testPassword($_POST["ancienMotdepasse"])) | 314 | |
315 | // II - affichage | ||
316 | $title = "Nouveau mot de passe"; | ||
317 | $subHeading = "Veuillez saisir votre actuel mot de passe suivi du nouveau."; | ||
318 | |||
319 | require('view/password.php'); | ||
320 | |||
321 | echo($header); | ||
322 | if($error != '') | ||
268 | { | 323 | { |
269 | // défense aux attaques par force brute | ||
270 | // pas parfait, ne marche pas si l'attaquant multiplie les connexions au site | ||
271 | echo($errorPassword); | ||
272 | sleep(1); | 324 | sleep(1); |
273 | echo($formulaireModifMDP); | 325 | echo($error_messages[$error]); |
274 | } | 326 | } |
275 | // erreur de conformité | 327 | elseif($success) |
276 | elseif(isset($newPassword) && $newPassword !== $_POST['nouveauMotdepasse']) | ||
277 | { | 328 | { |
278 | echo($errorBadCharacters); | 329 | echo($alertJSNewPassword); |
279 | echo($formulaireModifMDP); | ||
280 | } | 330 | } |
281 | // première arrivée sur la page | 331 | echo($formulaireModifMDP); |
282 | else | ||
283 | { | ||
284 | echo($formulaireModifMDP); | ||
285 | } | ||
286 | |||
287 | //echo($warning); | ||
288 | echo($footer); | 332 | echo($footer); |
289 | } | 333 | } |
290 | 334 | ||
291 | 335 | ||
292 | // hachage | ||
293 | function hashNewPassword(string $newPassword) | 336 | function hashNewPassword(string $newPassword) |
294 | { | 337 | { |
295 | // "réparation" des espaces accidentels | ||
296 | $newPassword= trim($newPassword); | ||
297 | // hachage | 338 | // hachage |
298 | $newHashedPassword = password_hash($newPassword, PASSWORD_DEFAULT); | 339 | $newHashedPassword = password_hash($newPassword, PASSWORD_DEFAULT); |
299 | 340 | ||
@@ -306,14 +347,9 @@ function hashNewPassword(string $newPassword) | |||
306 | 347 | ||
307 | function testPassword(string $password): bool | 348 | function testPassword(string $password): bool |
308 | { | 349 | { |
309 | // lecture | 350 | $hashedPassword = file_get_contents('data/password.txt'); |
310 | $oldHashedPassword = file_get_contents('data/password.txt'); | ||
311 | |||
312 | // "réparation" des espaces accidentels | ||
313 | $password= trim($password); | ||
314 | $oldHashedPassword = trim($oldHashedPassword); | ||
315 | 351 | ||
316 | if(password_verify($password, $oldHashedPassword)) | 352 | if(password_verify($password, $hashedPassword)) |
317 | { | 353 | { |
318 | return true; | 354 | return true; |
319 | } | 355 | } |