Skip to content

Commit b05dd8d

Browse files
committed
Add CLI authenticator
1 parent c9bc7c1 commit b05dd8d

File tree

3 files changed

+114
-48
lines changed

3 files changed

+114
-48
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
*.swp
2+
.vs

demo_auth.php

+46-48
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,51 @@
11
<?php
22

3-
function login($username, $password) {
4-
$dbconn = pg_connect("host=localhost port=5432 dbname=tournesol_staging user=tournesol password=Tetu8raiwieGh3I");
5-
$auth_table = 'auth_user';
6-
7-
$result = pg_query($dbconn, "select * from $auth_table where username='$username'");
8-
9-
if(!$result) {
10-
return false;
11-
}
12-
13-
$n_rows = pg_num_rows($result);
14-
15-
if($n_rows != 1) {
16-
return false;
17-
}
18-
19-
echo "$n_rows rows\n";
20-
21-
$rs = pg_fetch_assoc($result);
22-
23-
var_dump($rs);
24-
25-
$password_hashed_db = $rs['password'];
26-
27-
var_dump($password_hashed_db);
28-
29-
list($algo_db, $iterations_db, $salt_db, $hash_db) = explode('$', $password_hashed_db);
30-
list($algo_db_1, $algo_db_2) = explode('_', $algo_db);
31-
32-
if($algo_db_1 != 'pbkdf2') {
33-
echo "Unknown algorithm $algo_db_1";
34-
return false;
3+
require 'postgres_django_auth.php';
4+
5+
// command-line interface
6+
if ('cli' === PHP_SAPI) {
7+
$options_default = [
8+
"host" => "localhost",
9+
"port" => 5432,
10+
"dbname" => "tournesol",
11+
"db_username" => "tournesol",
12+
"auth_table" => "auth_user",
13+
"password" => "",
14+
"db_password" => "",
15+
"username" => "",
16+
];
17+
$options = getopt('', ["username:", "password:", "db_password:",
18+
"host::", "port::", "dbname::",
19+
"db_username::", "auth_table::"]);
20+
$options = $options + $options_default;
21+
22+
if(!$options['username'] || !$options['password'] || !$options['db_password']) {
23+
$fn = $_SERVER['SCRIPT_FILENAME'];
24+
echo "Usage: php $fn --username=LOGIN_USERNAME --password=LOGIN_PASSWORD ";
25+
echo "--db_password=DB_PASSWORD\n";
26+
echo " [--host=DB_HOST] [--port=DB_PORT] [--dbname=DB_NAME] ";
27+
echo " [--db_username=DB_USERNAME] [--auth_table=AUTH_TABLE]";
28+
echo "\n";
29+
exit(1);
30+
}
31+
32+
// logging in
33+
try {
34+
$result = call_user_func_array("login_django_postgres", $options);
35+
} catch (Exception $e) {
36+
$result = false;
37+
$error = $e->getMessage();
38+
}
39+
40+
41+
if($result) {
42+
echo "Login successful\n";
43+
exit(0);
44+
}
45+
else {
46+
echo "Login failed: $error\n";
47+
exit(1);
48+
}
3549
}
3650

37-
var_dump($algo_db, $iterations_db, $salt_db);
38-
39-
$supplied_hash_password = base64_encode(hash_pbkdf2($algo_db_2, $password, $salt_db, $iterations_db, 32, true));
40-
41-
echo "$supplied_hash_password\n";
42-
43-
44-
return $supplied_hash_password == $hash_db;
45-
46-
47-
}
48-
49-
$result = login('harry_potter', 'Iefaegh0Yohdah6k');
50-
var_dump($result);
51-
echo "res=$result\n";
52-
5351
?>

postgres_django_auth.php

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
3+
function login_django_postgres($username, $password, $host='localhost', $port=5432,
4+
$dbname='tournesol_staging', $db_username='tournesol',
5+
$db_password='', $auth_table = 'auth_user') {
6+
/*
7+
Log in to a Django database stored in Postgres, assuming pbkdf2-sha256 encryption
8+
9+
Args:
10+
$username: username of the user trying to log in
11+
$password: password of the user trying to log in in plain text
12+
$host: Postgres database host
13+
$port: Postgres database port
14+
$dbname: Postgres database name
15+
$db_username: Postgres user name
16+
$db_password: Postgres user password
17+
$auth_table: Postgres Django authentication table
18+
19+
Returns:
20+
true if the login was successful, false on authentication failure
21+
throws exceptions in case if connection failed/database does not exist/user does not exist
22+
*/
23+
24+
// connecto to the database
25+
$dbconn = pg_connect("host=$host port=$port dbname=$dbname user=$db_username password=$db_password");
26+
27+
// no connection -> no login
28+
if(!$dbconn) {
29+
throw new Exception("Database connection failed");
30+
}
31+
32+
// query the user table
33+
$username_escaped = pg_escape_string($username);
34+
$result = pg_query($dbconn, "select * from $auth_table where username='$username_escaped'");
35+
36+
// no data -> not logged in
37+
if(!$result) {
38+
throw new Exception("Username not found");
39+
}
40+
41+
// number of rows with the username
42+
$n_rows = pg_num_rows($result);
43+
if($n_rows != 1) {
44+
throw new Exception("User not found");
45+
}
46+
47+
// obtaining the password for the single row
48+
$rs = pg_fetch_assoc($result);
49+
$password_hashed_db = $rs['password'];
50+
51+
// destructuring password parameters
52+
list($algo_db, $iterations_db, $salt_db, $hash_db) = explode('$', $password_hashed_db);
53+
list($algo_db_1, $algo_db_2) = explode('_', $algo_db);
54+
55+
// only pbkdf2 is implemented
56+
if($algo_db_1 != 'pbkdf2') {
57+
throw new Exception("Encryption mechanism not supported");
58+
}
59+
60+
// hashing the given password
61+
$supplied_hash_password = base64_encode(hash_pbkdf2($algo_db_2, $password, $salt_db, $iterations_db, 32, true));
62+
63+
// logged in === hashed($password) == $stored_hash
64+
return $supplied_hash_password == $hash_db;
65+
}
66+
67+
?>

0 commit comments

Comments
 (0)