-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathauth.php
More file actions
158 lines (134 loc) Β· 5.24 KB
/
Copy pathauth.php
File metadata and controls
158 lines (134 loc) Β· 5.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
<?php
/**
* Authentification PHP pour ShareBox
* - require_auth() : redirige vers login si pas connectΓ©
* - Brute-force protection : 5 tentatives max par IP / 15 min
*/
require_once __DIR__ . '/db.php';
require_once __DIR__ . '/functions.php';
function require_auth(): void {
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
// ββ Trusted header auth (Apache Digest, reverse proxy, etc.) ββββββββ
if (defined('TRUSTED_AUTH_HEADER') && TRUSTED_AUTH_HEADER !== '') {
$remoteUser = $_SERVER[TRUSTED_AUTH_HEADER] ?? '';
if ($remoteUser !== '') {
// Sanitize username
$remoteUser = preg_replace('/[^a-z0-9_-]/i', '', $remoteUser);
// If session already set for this user, nothing to do
if (($_SESSION['sharebox_user'] ?? '') === $remoteUser) {
return;
}
// Auto-provision user in DB if not exists
$db = get_db();
$stmt = $db->prepare("SELECT * FROM users WHERE username = ?");
$stmt->execute([$remoteUser]);
$user = $stmt->fetch();
$isAdmin = defined('ADMIN_USER') && $remoteUser === ADMIN_USER;
if (!$user) {
// Auto-create user β admin if ADMIN_USER matches, else regular user
$role = $isAdmin ? 'admin' : 'user';
$db->prepare("INSERT INTO users (username, password_hash, role, private) VALUES (?, ?, ?, 0)")
->execute([$remoteUser, password_hash(bin2hex(random_bytes(16)), PASSWORD_BCRYPT), $role]);
$stmt = $db->prepare("SELECT * FROM users WHERE username = ?");
$stmt->execute([$remoteUser]);
$user = $stmt->fetch();
}
// Create session
session_regenerate_id(true);
$_SESSION['sharebox_user'] = $user['username'];
$_SESSION['sharebox_role'] = $user['role'];
$_SESSION['sharebox_private'] = (int)($user['private'] ?? 0);
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
log_activity('login_trusted', $user['username'], $_SERVER['REMOTE_ADDR'] ?? null,
'header=' . TRUSTED_AUTH_HEADER);
return;
}
}
// ββ Standard session check ββββββββββββββββββββββββββββββββββββββββββ
if (empty($_SESSION['sharebox_user'])) {
header('Location: /share/login.php');
exit;
}
}
function is_logged_in(): bool {
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
// Trusted header: auto-provision session if not set
if (defined('TRUSTED_AUTH_HEADER') && TRUSTED_AUTH_HEADER !== '') {
$remoteUser = $_SERVER[TRUSTED_AUTH_HEADER] ?? '';
if ($remoteUser !== '' && empty($_SESSION['sharebox_user'])) {
require_auth(); // This will create the session
return true;
}
}
return !empty($_SESSION['sharebox_user']);
}
function get_current_user_name(): ?string {
return $_SESSION['sharebox_user'] ?? null;
}
function is_admin(): bool {
return is_logged_in() && (($_SESSION['sharebox_role'] ?? '') === 'admin');
}
/**
* Brute-force rate limiting (file-based, simple)
*/
function check_rate_limit(string $ip): bool {
$file = sys_get_temp_dir() . '/sharebox_login_' . md5($ip);
if (!file_exists($file)) return true;
$fh = fopen($file, 'r');
if (!$fh) return true;
flock($fh, LOCK_SH);
$raw = stream_get_contents($fh);
flock($fh, LOCK_UN);
fclose($fh);
$data = json_decode($raw, true);
if (!$data) return true;
// Reset after 15 minutes
if (time() - $data['first'] > 900) {
unlink($file);
return true;
}
return $data['count'] < 5;
}
function record_failed_attempt(string $ip): void {
$file = sys_get_temp_dir() . '/sharebox_login_' . md5($ip);
$data = ['count' => 1, 'first' => time()];
$fh = fopen($file, 'c+');
if (!$fh) return;
flock($fh, LOCK_EX);
$raw = stream_get_contents($fh);
$existing = json_decode($raw, true);
if ($existing) {
$data = $existing;
$data['count']++;
}
ftruncate($fh, 0);
rewind($fh);
fwrite($fh, json_encode($data));
flock($fh, LOCK_UN);
fclose($fh);
}
function clear_rate_limit(string $ip): void {
$file = sys_get_temp_dir() . '/sharebox_login_' . md5($ip);
if (file_exists($file)) unlink($file);
}
/**
* Ensure at least one admin user exists (first-run bootstrap).
* Uses SHAREBOX_ADMIN_USER / SHAREBOX_ADMIN_PASS env vars, or defaults to admin + random password.
*/
function ensure_admin_exists(): void {
$db = get_db();
$count = (int)$db->query("SELECT COUNT(*) FROM users")->fetchColumn();
if ($count === 0) {
$user = getenv('SHAREBOX_ADMIN_USER') ?: 'admin';
$pass = getenv('SHAREBOX_ADMIN_PASS') ?: bin2hex(random_bytes(8));
$db->prepare("INSERT INTO users (username, password_hash, role) VALUES (?, ?, 'admin')")
->execute([$user, password_hash($pass, PASSWORD_BCRYPT)]);
if (!getenv('SHAREBOX_ADMIN_PASS')) {
error_log("ShareBox: admin user '$user' created with password: $pass");
}
}
}