. */ /* login is stored as : @@url;login Password is salted (3 random characters) and encrypted All is encrypted with AES256 and key : PKDBF2(hmac_sha256, master key, url, 1000) */ $MAX_ENTRY_LEN = 512; $USERS_PATH = "./users/"; function open_crypto($mkey) { if (!isset($_SESSION['td'])) { $td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, ''); if ($td == false) die("Unable to open mcrypt"); $ret = mcrypt_generic_init($td, hex2bin($mkey), '0000000000000000'); if ($ret < 0) { echo "
Unable to set key $ret
"; return null; } $_SESSION['td'] = $td; } else $td = $_SESSION['td']; return $td; } function decrypt($mkey, $val, $salted) { $td = open_crypto($mkey); if ($td == null) return; $val = mdecrypt_generic($td, hex2bin($val)); // Remove 0 added by encrypt $val = str_replace("\0", '', $val); // Remove salt if ($salted) $val = substr($val, 0, strlen($val)-3); return $val; } function encrypt($mkey, $val, $salted) { global $MAX_ENTRY_LEN; $td = open_crypto($mkey); if ($td == null) return; if ($salted) { $val .= dechex(rand(256,4095)); //between 0x100 and 0xfff } $val = mcrypt_generic($td, $val); if (strlen($val) > $MAX_ENTRY_LEN) { echo "
Value to encrypt is too long
"; return null; } return bin2hex($val); } // From http://php.net/manual/en/function.copy.php function recurse_copy($src,$dst) { $dir = opendir($src); if ($dir == FALSE) return FALSE; if (!@mkdir($dst)) return FALSE; while(false !== ( $file = readdir($dir)) ) { if (( $file != '.' ) && ( $file != '..' )) { if ( is_dir($src . '/' . $file) ) { return recurse_copy($src . '/' . $file,$dst . '/' . $file); } else { copy($src . '/' . $file,$dst . '/' . $file); } } } closedir($dir); return TRUE; } function create_user($user) { global $USERS_PATH; if (strpos($user, "..") || strpos($user, "/") || $user[0] == "." || $user[0] == "_") { echo "
Invalid user
"; } else { $user = $USERS_PATH . $user; if (file_exists($user)) { echo "
User already exists
"; } else { if (!recurse_copy("./ref", $user)) { echo "
Cannot create user $user
"; } else { return true; } } } return false; } function load_database($user) { global $USERS_PATH; try { $db = new SQLite3($USERS_PATH . "$user/gpass.bdd", SQLITE3_OPEN_READWRITE); } catch(Exception $e) { echo "
Unable to load database for user $user !
"; return null; } // New access need to reset crypto unset($_SESSION['td']); return $db; } function add_entry($user, $login, $password) { $db = load_database($user); if ($db == null) { echo "Unknown user"; return false; } $count = $db->querySingle("SELECT COUNT(*) FROM gpass WHERE login='" . $login . "'"); if ($count != 0) { echo "Entry already exists"; return false; } $result = $db->query("INSERT INTO gpass ('login', 'password') VALUES ('" . $login . "', '" . $password . "')"); $db->close(); echo "OK"; return true; } function delete_entry($user, $login) { $db = load_database($user); if ($db == null) { echo "Unknown user"; return false; } $db->query("DELETE FROM gpass WHERE login='" . $login . "'"); $db->close(); echo "OK"; return true; } function update_entry($user, $mkey, $old_login, $url, $login, $password) { if (delete_entry($user, $old_login)) return add_entry($user, $mkey, $url, $login, $password); return false; } function list_entries($user) { $db = load_database($user); if ($db == null) return; $result = $db->query("SELECT * FROM gpass"); echo "entries\n"; while (($row = $result->fetchArray())) { echo $row['login'] . ";" . $row['password'] . "\n"; } } ?>