Overview
Comment: | Amélioration de la vérification de hash pour l'import de DB |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | dev |
Files: | files | file ages | folders |
SHA1: |
42d8fe5ab57aa10bb13743194625c2d2 |
User & Date: | bohwaz on 2017-05-05 07:35:00 |
Other Links: | branch diff | manifest | tags |
Context
2017-05-08
| ||
00:13 | Merge avec trunk check-in: 0e42b2b443 user: bohwaz tags: dev | |
2017-05-05
| ||
07:35 | Amélioration de la vérification de hash pour l'import de DB check-in: 42d8fe5ab5 user: bohwaz tags: dev | |
2017-05-04
| ||
07:38 | Modernisation/corrections du code check-in: abedb2727c user: bohwaz tags: dev | |
Changes
Modified src/include/lib/Garradin/DB.php from [8264aea346] to [a155d87551].
1 2 3 4 5 6 7 8 9 10 11 12 13 | <?php namespace Garradin; class DB { static protected $_instance = null; /** * Instance SQLite3 * @var SQLite3 */ protected $db = null; | > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <?php namespace Garradin; class DB { /** * Application ID pour SQLite * @link https://www.sqlite.org/pragma.html#pragma_application_id */ const APPID = 0x5da2d811; static protected $_instance = null; /** * Instance SQLite3 * @var SQLite3 */ protected $db = null; |
︙ | ︙ |
Modified src/include/lib/Garradin/Install.php from [cbbaf6e1e8] to [323e87e4cd].
︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 | { static public function install($nom_asso, $adresse_asso, $email_asso, $nom_categorie, $nom_membre, $email_membre, $passe_membre, $site_asso = WWW_URL) { $db = DB::getInstance(true); // Création de la base de données $db->begin(); $db->exec(file_get_contents(DB_SCHEMA)); $db->commit(); // Configuration de base // c'est dans Config::set que sont vérifiées les données utilisateur (renvoie UserException) $config = Config::getInstance(); $config->set('nom_asso', $nom_asso); | > | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | { static public function install($nom_asso, $adresse_asso, $email_asso, $nom_categorie, $nom_membre, $email_membre, $passe_membre, $site_asso = WWW_URL) { $db = DB::getInstance(true); // Création de la base de données $db->begin(); $db->exec('PRAGMA application_id = ' . DB::APPID . ';'); $db->exec(file_get_contents(DB_SCHEMA)); $db->commit(); // Configuration de base // c'est dans Config::set que sont vérifiées les données utilisateur (renvoie UserException) $config = Config::getInstance(); $config->set('nom_asso', $nom_asso); |
︙ | ︙ |
Modified src/include/lib/Garradin/Sauvegarde.php from [c9ec5ef48e] to [b0e237675e].
︙ | ︙ | |||
147 148 149 150 151 152 153 154 155 156 157 158 159 160 | while (!feof($in)) { fwrite($out, fread($in, 8192)); } fclose($in); fclose($out); return true; } /** * Restaure une sauvegarde locale * @param string $file Le nom de fichier à utiliser comme point de restauration | > > > > | 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | while (!feof($in)) { fwrite($out, fread($in, 8192)); } fclose($in); // Ajout du hash pour vérification intégrité fwrite($out, sha1_file(DB_FILE)); fclose($out); return true; } /** * Restaure une sauvegarde locale * @param string $file Le nom de fichier à utiliser comme point de restauration |
︙ | ︙ | |||
173 174 175 176 177 178 179 | } return $this->restoreDB(DATA_ROOT . '/' . $file); } /** * Restaure une copie distante (fichier envoyé) | | > > > | > > > > > > > > > > > > > > | | 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 | } return $this->restoreDB(DATA_ROOT . '/' . $file); } /** * Restaure une copie distante (fichier envoyé) * @param array $file Tableau provenant de $_FILES * @param integer $user_id ID du membre actuellement connecté, utilisé pour * vérifier qu'il est toujours administrateur dans la sauvegarde * @param boolean $check_integrity Vérifier l'intégrité de la sauvegarde avant de restaurer * @return boolean true */ public function restoreFromUpload($file, $user_id, $check_integrity = true) { if (empty($file['size']) || empty($file['tmp_name']) || !empty($file['error'])) { throw new UserException('Le fichier n\'a pas été correctement envoyé. Essayer de le renvoyer à nouveau.'); } if ($check_integrity) { $integrity = $this->checkIntegrity($file['tmp_name']); if ($integrity === null) { throw new UserException('Le fichier fourni n\'est pas une base de donnée SQLite3.'); } elseif ($integrity === false) { return self::INTEGRITY_FAIL; } } $r = $this->restoreDB($file['tmp_name'], $user_id); if ($r) { unlink($file['tmp_name']); } return $r; } /** * Vérifie l'intégrité d'une sauvegarde Garradin * @param string $file Chemin absolu vers la base de donnée * @return boolean */ protected function checkIntegrity($file_path, $remove_hash = true) { $size = filesize($file_path); $fp = fopen($file_path, 'r+'); $header = fread($fp, 16); // Vérifie que le fichier est bien une base SQLite3 if ($header !== "SQLite format 3\000") { fclose($fp); |
︙ | ︙ | |||
223 224 225 226 227 228 229 | // Ne ressemble pas à un hash sha1 if (!preg_match('/[a-f0-9]{40}/', $hash)) { fclose($fp); return false; } | < < < < > > | | | < < < < < < < < < < < | < < < < < < < < < < < < < < | | > > > > > > > > > > > > > > < < | 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 | // Ne ressemble pas à un hash sha1 if (!preg_match('/[a-f0-9]{40}/', $hash)) { fclose($fp); return false; } $max = $size - 40; // Suppression du hash if ($remove_hash) { ftruncate($fp, $max); } fclose($fp); $file_hash = sha1_file($file_path); // Vérification du hash return ($file_hash === $hash); } /** * Restauration de base de données, la fonction qui le fait vraiment * @param string $file Chemin absolu vers la base de données à utiliser * @return mixed true si rien ne va plus, ou self::NEED_UPGRADE si la version de la DB * ne correspond pas à la version de Garradin (mise à jour nécessaire). */ protected function restoreDB($file, $user_id = false) { // Essayons déjà d'ouvrir la base de données à restaurer en lecture try { $db = new \SQLite3($file, SQLITE3_OPEN_READONLY); } catch (\Exception $e) { throw new UserException('Le fichier fourni n\'est pas une base de données valide. ' . 'Message d\'erreur de SQLite : ' . $e->getMessage()); } try { // Regardons ensuite si la base de données n'est pas corrompue $check = $db->firstColumn('PRAGMA integrity_check;'); } catch (\Exception $e) { // Ici SQLite peut rejeter un message type "file is encrypted or is not a db" throw new UserException('Le fichier fourni n\'est pas une base de données valide. ' . 'Message d\'erreur de SQLite : ' . $e->getMessage()); } if (strtolower(trim($check)) != 'ok') { throw new UserException('Le fichier fourni est corrompu. SQLite a trouvé ' . $check . ' erreurs.'); } // On ne peut pas faire de vérifications très poussées sur la structure de la base de données, // celle-ci pouvant changer d'une version à l'autre et on peut vouloir importer une base // un peu vieille, mais on vérifie quand même que ça ressemble un minimum à une base garradin $table = $db->firstColumn('SELECT 1 FROM sqlite_master WHERE type=\'table\' AND tbl_name=\'config\';'); if (!$table) { throw new UserException('Le fichier fourni ne semble pas contenir de données liées à Garradin.'); } // On récupère la version $version = $db->querySingle('SELECT valeur FROM config WHERE cle=\'version\';'); // Vérification de l'AppID pour les versions récentes if (version_compare($version, '0.8.0', '>=')) { $appid = $db->firstColumn('PRAGMA application_id;'); if ($appid !== DB::APPID) { throw new UserException('Ce fichier n\'est pas une sauvegarde Garradin (AppID ne correspond pas).'); } } if ($user_id) { // Empêchons l'admin de se tirer une balle dans le pied $is_still_admin = $db->querySingle('SELECT 1 FROM membres_categories WHERE id = (SELECT id_categorie FROM membres WHERE id = ' . (int) $user_id . ') AND droit_config >= ' . Membres::DROIT_ADMIN . ' AND droit_connexion >= ' . Membres::DROIT_ACCES); if (!$is_still_admin) { throw new UserException('Vous n\'êtes pas administrateur dans le fichier de sauvegarde fourni.'); } } $db->close(); $backup = str_replace('.sqlite', date('.Y-m-d-His') . '.avant_restauration.sqlite', DB_FILE); if (!rename(DB_FILE, $backup)) { |
︙ | ︙ |
Modified src/www/admin/upgrade.php from [80018cd596] to [db73c7b27f].
︙ | ︙ | |||
247 248 249 250 251 252 253 254 255 256 257 258 259 260 | if (version_compare($v, '0.8.0', '<')) { $db->exec('PRAGMA foreign_keys = OFF; BEGIN;'); // Mise à jour base de données $db->exec(file_get_contents(ROOT . '/include/data/0.8.0.sql')); $db->exec('END;'); } Utils::clearCaches(); $config->setVersion(garradin_version()); | > > > | 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 | if (version_compare($v, '0.8.0', '<')) { $db->exec('PRAGMA foreign_keys = OFF; BEGIN;'); // Mise à jour base de données $db->exec(file_get_contents(ROOT . '/include/data/0.8.0.sql')); // Inscriptin de l'appid $db->exec('PRAGMA application_id = ' . DB::APPID . ';'); $db->exec('END;'); } Utils::clearCaches(); $config->setVersion(garradin_version()); |
︙ | ︙ |