1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
/** |
6
|
|
|
* Teampass - a collaborative passwords manager. |
7
|
|
|
* --- |
8
|
|
|
* This file is part of the TeamPass project. |
9
|
|
|
* |
10
|
|
|
* TeamPass is free software: you can redistribute it and/or modify it |
11
|
|
|
* under the terms of the GNU General Public License as published by |
12
|
|
|
* the Free Software Foundation, version 3 of the License. |
13
|
|
|
* |
14
|
|
|
* TeamPass is distributed in the hope that it will be useful, |
15
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
16
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17
|
|
|
* GNU General Public License for more details. |
18
|
|
|
* |
19
|
|
|
* You should have received a copy of the GNU General Public License |
20
|
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>. |
21
|
|
|
* |
22
|
|
|
* Certain components of this file may be under different licenses. For |
23
|
|
|
* details, see the `licenses` directory or individual file headers. |
24
|
|
|
* --- |
25
|
|
|
* @file admin.queries.php |
26
|
|
|
* @author Nils Laumaillé ([email protected]) |
27
|
|
|
* @copyright 2009-2025 Teampass.net |
28
|
|
|
* @license GPL-3.0 |
29
|
|
|
* @see https://www.teampass.net |
30
|
|
|
*/ |
31
|
|
|
|
32
|
|
|
use TeampassClasses\SessionManager\SessionManager; |
33
|
|
|
use Symfony\Component\HttpFoundation\Request as SymfonyRequest; |
34
|
|
|
use TeampassClasses\Language\Language; |
35
|
|
|
use TeampassClasses\PerformChecks\PerformChecks; |
36
|
|
|
use TeampassClasses\ConfigManager\ConfigManager; |
37
|
|
|
use TeampassClasses\NestedTree\NestedTree; |
38
|
|
|
use Duo\DuoUniversal\Client; |
39
|
|
|
use Duo\DuoUniversal\DuoException; |
40
|
|
|
use TeampassClasses\EmailService\EmailSettings; |
41
|
|
|
use TeampassClasses\EmailService\EmailService; |
42
|
|
|
|
43
|
|
|
// Load functions |
44
|
|
|
require_once 'main.functions.php'; |
45
|
|
|
$session = SessionManager::getSession(); |
46
|
|
|
$request = SymfonyRequest::createFromGlobals(); |
47
|
|
|
loadClasses('DB'); |
48
|
|
|
$lang = new Language($session->get('user-language') ?? 'english'); |
49
|
|
|
|
50
|
|
|
// Load config |
51
|
|
|
$configManager = new ConfigManager(); |
52
|
|
|
$SETTINGS = $configManager->getAllSettings(); |
53
|
|
|
|
54
|
|
|
// Do checks |
55
|
|
|
// Instantiate the class with posted data |
56
|
|
|
$checkUserAccess = new PerformChecks( |
57
|
|
|
dataSanitizer( |
58
|
|
|
[ |
59
|
|
|
'type' => htmlspecialchars($request->request->get('type', ''), ENT_QUOTES, 'UTF-8'), |
60
|
|
|
], |
61
|
|
|
[ |
62
|
|
|
'type' => 'trim|escape', |
63
|
|
|
], |
64
|
|
|
), |
65
|
|
|
[ |
66
|
|
|
'user_id' => returnIfSet($session->get('user-id'), null), |
67
|
|
|
'user_key' => returnIfSet($session->get('key'), null), |
68
|
|
|
] |
69
|
|
|
); |
70
|
|
|
// Handle the case |
71
|
|
|
echo $checkUserAccess->caseHandler(); |
72
|
|
|
if ($checkUserAccess->checkSession() === false || $checkUserAccess->userAccessPage('admin') === false) { |
73
|
|
|
// Not allowed page |
74
|
|
|
$session->set('system-error_code', ERR_NOT_ALLOWED); |
75
|
|
|
include $SETTINGS['cpassman_dir'] . '/error.php'; |
76
|
|
|
exit; |
77
|
|
|
} |
78
|
|
|
|
79
|
|
|
// Define Timezone |
80
|
|
|
date_default_timezone_set($SETTINGS['timezone'] ?? 'UTC'); |
81
|
|
|
|
82
|
|
|
// Set header properties |
83
|
|
|
header('Content-type: text/html; charset=utf-8'); |
84
|
|
|
header('Cache-Control: no-cache, no-store, must-revalidate'); |
85
|
|
|
|
86
|
|
|
// --------------------------------- // |
87
|
|
|
|
88
|
|
|
|
89
|
|
|
// Load tree |
90
|
|
|
$tree = new NestedTree(prefixTable('nested_tree'), 'id', 'parent_id', 'title'); |
91
|
|
|
|
92
|
|
|
// Prepare POST variables |
93
|
|
|
$post_type = filter_input(INPUT_POST, 'type', FILTER_SANITIZE_FULL_SPECIAL_CHARS); |
94
|
|
|
$post_data = filter_input(INPUT_POST, 'data', FILTER_SANITIZE_FULL_SPECIAL_CHARS, FILTER_FLAG_NO_ENCODE_QUOTES); |
95
|
|
|
$post_key = filter_input(INPUT_POST, 'key', FILTER_SANITIZE_FULL_SPECIAL_CHARS); |
96
|
|
|
$post_id = filter_input(INPUT_POST, 'id', FILTER_SANITIZE_NUMBER_INT); |
97
|
|
|
$post_status = filter_input(INPUT_POST, 'status', FILTER_SANITIZE_NUMBER_INT); |
98
|
|
|
$post_label = filter_input(INPUT_POST, 'label', FILTER_SANITIZE_FULL_SPECIAL_CHARS); |
99
|
|
|
$post_action = filter_input(INPUT_POST, 'action', FILTER_SANITIZE_FULL_SPECIAL_CHARS); |
100
|
|
|
$post_cpt = filter_input(INPUT_POST, 'cpt', FILTER_SANITIZE_NUMBER_INT); |
101
|
|
|
$post_object = filter_input(INPUT_POST, 'object', FILTER_SANITIZE_FULL_SPECIAL_CHARS); |
102
|
|
|
$post_start = filter_input(INPUT_POST, 'start', FILTER_SANITIZE_NUMBER_INT); |
103
|
|
|
$post_length = filter_input(INPUT_POST, 'length', FILTER_SANITIZE_NUMBER_INT); |
104
|
|
|
$post_option = filter_input(INPUT_POST, 'option', FILTER_SANITIZE_FULL_SPECIAL_CHARS); |
105
|
|
|
$post_nbItems = filter_input(INPUT_POST, 'nbItems', FILTER_SANITIZE_NUMBER_INT); |
106
|
|
|
$post_counter = filter_input(INPUT_POST, 'counter', FILTER_SANITIZE_NUMBER_INT); |
107
|
|
|
$post_list = filter_input(INPUT_POST, 'list', FILTER_SANITIZE_FULL_SPECIAL_CHARS); |
108
|
|
|
|
109
|
|
|
switch ($post_type) { |
110
|
|
|
//########################################################## |
111
|
|
|
//CASE for creating a DB backup |
112
|
|
|
case 'admin_action_db_backup': |
113
|
|
|
// Check KEY |
114
|
|
|
if ($post_key !== $session->get('key')) { |
115
|
|
|
echo prepareExchangedData( |
116
|
|
|
array( |
117
|
|
|
'error' => true, |
118
|
|
|
'message' => $lang->get('key_is_not_correct'), |
119
|
|
|
), |
120
|
|
|
'encode' |
121
|
|
|
); |
122
|
|
|
break; |
123
|
|
|
} |
124
|
|
|
// Is admin? |
125
|
|
|
if ($session->get('user-admin') === 1) { |
126
|
|
|
echo prepareExchangedData( |
127
|
|
|
array( |
128
|
|
|
'error' => true, |
129
|
|
|
'message' => $lang->get('error_not_allowed_to'), |
130
|
|
|
), |
131
|
|
|
'encode' |
132
|
|
|
); |
133
|
|
|
break; |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
require_once $SETTINGS['cpassman_dir'] . '/sources/main.functions.php'; |
137
|
|
|
$return = ''; |
138
|
|
|
|
139
|
|
|
//Get all tables |
140
|
|
|
$tables = array(); |
141
|
|
|
$result = DB::query('SHOW TABLES'); |
142
|
|
|
foreach ($result as $row) { |
143
|
|
|
$tables[] = $row['Tables_in_' . DB_NAME]; |
144
|
|
|
} |
145
|
|
|
|
146
|
|
|
//cycle through |
147
|
|
|
foreach ($tables as $table) { |
148
|
|
|
if (defined('DB_PREFIX') || substr_count($table, DB_PREFIX) > 0) { |
149
|
|
|
$table = (is_string($table) ? $table : strval($table)); |
150
|
|
|
// Do query |
151
|
|
|
$result = DB::query('SELECT * FROM ' . $table); |
152
|
|
|
DB::query( |
153
|
|
|
'SELECT * |
154
|
|
|
FROM INFORMATION_SCHEMA.COLUMNS |
155
|
|
|
WHERE table_schema = %s |
156
|
|
|
AND table_name = %s', |
157
|
|
|
DB_NAME, |
158
|
|
|
$table |
159
|
|
|
); |
160
|
|
|
$numFields = DB::count(); |
161
|
|
|
|
162
|
|
|
// prepare a drop table |
163
|
|
|
$return .= 'DROP TABLE ' . $table . ';'; |
164
|
|
|
$row2 = DB::queryFirstRow('SHOW CREATE TABLE ' . $table); |
165
|
|
|
$return .= "\n\n" . strval($row2['Create Table']) . ";\n\n"; |
166
|
|
|
|
167
|
|
|
//prepare all fields and datas |
168
|
|
|
for ($i = 0; $i < $numFields; ++$i) { |
169
|
|
|
if (is_object($result)) { |
170
|
|
|
while ($row = $result->fetch_row()) { |
171
|
|
|
$return .= 'INSERT INTO ' . $table . ' VALUES('; |
172
|
|
|
for ($j = 0; $j < $numFields; ++$j) { |
173
|
|
|
$row[$j] = addslashes($row[$j]); |
174
|
|
|
$row[$j] = preg_replace("/\n/", '\\n', $row[$j]); |
175
|
|
|
if (isset($row[$j])) { |
176
|
|
|
$return .= '"' . $row[$j] . '"'; |
177
|
|
|
} else { |
178
|
|
|
$return .= 'NULL'; |
179
|
|
|
} |
180
|
|
|
if ($j < ($numFields - 1)) { |
181
|
|
|
$return .= ','; |
182
|
|
|
} |
183
|
|
|
} |
184
|
|
|
$return .= ");\n"; |
185
|
|
|
} |
186
|
|
|
} |
187
|
|
|
} |
188
|
|
|
$return .= "\n\n\n"; |
189
|
|
|
} |
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
if (!empty($return)) { |
193
|
|
|
// get a token |
194
|
|
|
$token = GenerateCryptKey(20, false, true, true, false, true); |
195
|
|
|
|
196
|
|
|
//save file |
197
|
|
|
$filename = time() . '-' . $token . '.sql'; |
198
|
|
|
$handle = fopen($SETTINGS['path_to_files_folder'] . '/' . $filename, 'w+'); |
199
|
|
|
if ($handle !== false) { |
200
|
|
|
//write file |
201
|
|
|
fwrite($handle, $return); |
202
|
|
|
fclose($handle); |
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
// Encrypt the file |
206
|
|
|
if (empty($post_option) === false) { |
207
|
|
|
// Encrypt the file |
208
|
|
|
prepareFileWithDefuse( |
209
|
|
|
'encrypt', |
210
|
|
|
$SETTINGS['path_to_files_folder'] . '/' . $filename, |
211
|
|
|
$SETTINGS['path_to_files_folder'] . '/defuse_temp_' . $filename, |
212
|
|
|
$post_option |
213
|
|
|
); |
214
|
|
|
|
215
|
|
|
// Do clean |
216
|
|
|
unlink($SETTINGS['path_to_files_folder'] . '/' . $filename); |
217
|
|
|
rename( |
218
|
|
|
$SETTINGS['path_to_files_folder'] . '/defuse_temp_' . $filename, |
219
|
|
|
$SETTINGS['path_to_files_folder'] . '/' . $filename |
220
|
|
|
); |
221
|
|
|
} |
222
|
|
|
|
223
|
|
|
//generate 2d key |
224
|
|
|
$session->set('user-key_tmp', GenerateCryptKey(20, false, true, true, false, true)); |
225
|
|
|
|
226
|
|
|
//update LOG |
227
|
|
|
logEvents($SETTINGS, 'admin_action', 'dataBase backup', (string) $session->get('user-id'), $session->get('user-login')); |
228
|
|
|
|
229
|
|
|
echo '[{"result":"db_backup" , "href":"sources/downloadFile.php?name=' . urlencode($filename) . '&sub=files&file=' . $filename . '&type=sql&key=' . $session->get('key') . '&key_tmp=' . $session->get('user-key_tmp') . '&pathIsFiles=1"}]'; |
230
|
|
|
} |
231
|
|
|
break; |
232
|
|
|
|
233
|
|
|
//########################################################## |
234
|
|
|
//CASE for restoring a DB backup |
235
|
|
|
case 'admin_action_db_restore': |
236
|
|
|
// Check KEY |
237
|
|
|
if ($post_key !== $session->get('key')) { |
238
|
|
|
echo prepareExchangedData( |
239
|
|
|
array( |
240
|
|
|
'error' => true, |
241
|
|
|
'message' => $lang->get('key_is_not_correct'), |
242
|
|
|
), |
243
|
|
|
'encode' |
244
|
|
|
); |
245
|
|
|
break; |
246
|
|
|
} |
247
|
|
|
// Is admin? |
248
|
|
|
if ($session->get('user-admin') === 1) { |
249
|
|
|
echo prepareExchangedData( |
250
|
|
|
array( |
251
|
|
|
'error' => true, |
252
|
|
|
'message' => $lang->get('error_not_allowed_to'), |
253
|
|
|
), |
254
|
|
|
'encode' |
255
|
|
|
); |
256
|
|
|
break; |
257
|
|
|
} |
258
|
|
|
include_once $SETTINGS['cpassman_dir'] . '/sources/main.functions.php'; |
259
|
|
|
|
260
|
|
|
$dataPost = explode('&', $post_option); |
261
|
|
|
$file = htmlspecialchars($dataPost[0]); |
262
|
|
|
$key = htmlspecialchars($dataPost[1]); |
263
|
|
|
|
264
|
|
|
// Get filename from database |
265
|
|
|
$data = DB::queryFirstRow( |
266
|
|
|
'SELECT valeur |
267
|
|
|
FROM ' . prefixTable('misc') . ' |
268
|
|
|
WHERE increment_id = %i', |
269
|
|
|
$file |
270
|
|
|
); |
271
|
|
|
|
272
|
|
|
$file = is_string($data['valeur']) ? $data['valeur'] : ''; |
273
|
|
|
|
274
|
|
|
// Delete operation id |
275
|
|
|
DB::delete( |
276
|
|
|
prefixTable('misc'), |
277
|
|
|
'increment_id = %i', |
278
|
|
|
$file |
279
|
|
|
); |
280
|
|
|
|
281
|
|
|
// Undecrypt the file |
282
|
|
|
if (empty($key) === false) { |
283
|
|
|
// Decrypt the file |
284
|
|
|
$ret = prepareFileWithDefuse( |
285
|
|
|
'decrypt', |
286
|
|
|
$SETTINGS['path_to_files_folder'] . '/' . $file, |
287
|
|
|
$SETTINGS['path_to_files_folder'] . '/defuse_temp_' . $file, |
288
|
|
|
$key |
289
|
|
|
); |
290
|
|
|
|
291
|
|
|
if (empty($ret) === false) { |
292
|
|
|
// deepcode ignore ServerLeak: $ret can only be an error string, so no important data here to be sent to client |
293
|
|
|
echo '[{"result":"db_restore" , "message":"An error occurred ('.(string) $ret.')"}]'; |
294
|
|
|
break; |
295
|
|
|
} |
296
|
|
|
|
297
|
|
|
// Do clean |
298
|
|
|
fileDelete($SETTINGS['path_to_files_folder'] . '/' . $file, $SETTINGS); |
299
|
|
|
$file = $SETTINGS['path_to_files_folder'] . '/defuse_temp_' . $file; |
300
|
|
|
} else { |
301
|
|
|
$file = $SETTINGS['path_to_files_folder'] . '/' . $file; |
302
|
|
|
} |
303
|
|
|
|
304
|
|
|
//read sql file |
305
|
|
|
$handle = fopen($file, 'r'); |
306
|
|
|
$query = ''; |
307
|
|
|
while (!feof($handle)) { |
308
|
|
|
$query .= fgets($handle, 4096); |
309
|
|
|
if (substr(rtrim($query), -1) === ';') { |
310
|
|
|
//launch query |
311
|
|
|
DB::query($query); |
312
|
|
|
$query = ''; |
313
|
|
|
} |
314
|
|
|
} |
315
|
|
|
fclose($handle); |
316
|
|
|
|
317
|
|
|
//delete file |
318
|
|
|
unlink($SETTINGS['path_to_files_folder'] . '/' . $file); |
319
|
|
|
|
320
|
|
|
//Show done |
321
|
|
|
echo '[{"result":"db_restore" , "message":""}]'; |
322
|
|
|
break; |
323
|
|
|
|
324
|
|
|
//########################################################## |
325
|
|
|
//CASE for optimizing the DB |
326
|
|
|
case 'admin_action_db_optimize': |
327
|
|
|
// Check KEY |
328
|
|
|
if ($post_key !== $session->get('key')) { |
329
|
|
|
echo prepareExchangedData( |
330
|
|
|
array( |
331
|
|
|
'error' => true, |
332
|
|
|
'message' => $lang->get('key_is_not_correct'), |
333
|
|
|
), |
334
|
|
|
'encode' |
335
|
|
|
); |
336
|
|
|
break; |
337
|
|
|
} |
338
|
|
|
// Is admin? |
339
|
|
|
if ($session->get('user-admin') === 1) { |
340
|
|
|
echo prepareExchangedData( |
341
|
|
|
array( |
342
|
|
|
'error' => true, |
343
|
|
|
'message' => $lang->get('error_not_allowed_to'), |
344
|
|
|
), |
345
|
|
|
'encode' |
346
|
|
|
); |
347
|
|
|
break; |
348
|
|
|
} |
349
|
|
|
|
350
|
|
|
//Get all tables |
351
|
|
|
$alltables = DB::query('SHOW TABLES'); |
352
|
|
|
foreach ($alltables as $table) { |
353
|
|
|
foreach ($table as $i => $tablename) { |
354
|
|
|
$tablename = (is_string($tablename) ? $tablename : strval($tablename)); |
355
|
|
|
if (substr_count($tablename, DB_PREFIX) > 0) { |
356
|
|
|
// launch optimization quieries |
357
|
|
|
DB::query('ANALYZE TABLE `' . $tablename . '`'); |
358
|
|
|
DB::query('OPTIMIZE TABLE `' . $tablename . '`'); |
359
|
|
|
} |
360
|
|
|
} |
361
|
|
|
} |
362
|
|
|
|
363
|
|
|
//Clean up LOG_ITEMS table |
364
|
|
|
$rows = DB::query( |
365
|
|
|
'SELECT id |
366
|
|
|
FROM ' . prefixTable('items') . ' |
367
|
|
|
ORDER BY id ASC' |
368
|
|
|
); |
369
|
|
|
foreach ($rows as $item) { |
370
|
|
|
DB::query( |
371
|
|
|
'SELECT * FROM ' . prefixTable('log_items') . ' WHERE id_item = %i AND action = %s', |
372
|
|
|
$item['id'], |
373
|
|
|
'at_creation' |
374
|
|
|
); |
375
|
|
|
$counter = DB::count(); |
376
|
|
|
if ($counter === 0) { |
377
|
|
|
//Create new at_creation entry |
378
|
|
|
$rowTmp = DB::queryFirstRow( |
379
|
|
|
'SELECT date, id_user FROM ' . prefixTable('log_items') . ' WHERE id_item=%i ORDER BY date ASC', |
380
|
|
|
$item['id'] |
381
|
|
|
); |
382
|
|
|
DB::insert( |
383
|
|
|
prefixTable('log_items'), |
384
|
|
|
array( |
385
|
|
|
'id_item' => $item['id'], |
386
|
|
|
'date' => $rowTmp['date'] - 1, |
387
|
|
|
'id_user' => empty($rowTmp['id_user']) === true ? 1 : $rowTmp['id_user'], |
388
|
|
|
'action' => 'at_creation', |
389
|
|
|
'raison' => '', |
390
|
|
|
) |
391
|
|
|
); |
392
|
|
|
} |
393
|
|
|
} |
394
|
|
|
|
395
|
|
|
// Log |
396
|
|
|
logEvents( |
397
|
|
|
$SETTINGS, |
398
|
|
|
'system', |
399
|
|
|
'admin_action_db_optimize', |
400
|
|
|
(string) $session->get('user-id'), |
401
|
|
|
$session->get('user-login'), |
402
|
|
|
'success' |
403
|
|
|
); |
404
|
|
|
|
405
|
|
|
//Show done |
406
|
|
|
echo prepareExchangedData( |
407
|
|
|
array( |
408
|
|
|
'error' => false, |
409
|
|
|
'message' => $lang->get('last_execution') . ' ' . |
410
|
|
|
date($SETTINGS['date_format'] . ' ' . $SETTINGS['time_format'], (int) time()) . |
411
|
|
|
'<i class="fas fa-check text-success ml-2"></i>', |
412
|
|
|
), |
413
|
|
|
'encode' |
414
|
|
|
); |
415
|
|
|
break; |
416
|
|
|
|
417
|
|
|
|
418
|
|
|
|
419
|
|
|
/* |
420
|
|
|
* Reload the Cache table |
421
|
|
|
*/ |
422
|
|
|
case 'admin_action_reload_cache_table': |
423
|
|
|
// Check KEY |
424
|
|
|
if ($post_key !== $session->get('key')) { |
425
|
|
|
echo prepareExchangedData( |
426
|
|
|
array( |
427
|
|
|
'error' => true, |
428
|
|
|
'message' => $lang->get('key_is_not_correct'), |
429
|
|
|
), |
430
|
|
|
'encode' |
431
|
|
|
); |
432
|
|
|
break; |
433
|
|
|
} |
434
|
|
|
// Is admin? |
435
|
|
|
if ($session->get('user-admin') === 1) { |
436
|
|
|
echo prepareExchangedData( |
437
|
|
|
array( |
438
|
|
|
'error' => true, |
439
|
|
|
'message' => $lang->get('error_not_allowed_to'), |
440
|
|
|
), |
441
|
|
|
'encode' |
442
|
|
|
); |
443
|
|
|
break; |
444
|
|
|
} |
445
|
|
|
|
446
|
|
|
require_once $SETTINGS['cpassman_dir'] . '/sources/main.functions.php'; |
447
|
|
|
updateCacheTable('reload', NULL); |
448
|
|
|
|
449
|
|
|
// Log |
450
|
|
|
logEvents( |
451
|
|
|
$SETTINGS, |
452
|
|
|
'system', |
453
|
|
|
'admin_action_reload_cache_table', |
454
|
|
|
(string) $session->get('user-id'), |
455
|
|
|
$session->get('user-login'), |
456
|
|
|
'success' |
457
|
|
|
); |
458
|
|
|
|
459
|
|
|
echo prepareExchangedData( |
460
|
|
|
[ |
461
|
|
|
'error' => false, |
462
|
|
|
'message' => $lang->get('last_execution') . ' ' . |
463
|
|
|
date($SETTINGS['date_format'] . ' ' . $SETTINGS['time_format'], (int) time()) . |
464
|
|
|
'<i class="fas fa-check text-success mr-2"></i>', |
465
|
|
|
], |
466
|
|
|
'encode' |
467
|
|
|
); |
468
|
|
|
break; |
469
|
|
|
|
470
|
|
|
|
471
|
|
|
/* |
472
|
|
|
* Change SALT Key START |
473
|
|
|
*/ |
474
|
|
|
case 'admin_action_change_salt_key___start': |
475
|
|
|
// Check KEY |
476
|
|
|
if ($post_key !== $session->get('key')) { |
477
|
|
|
echo prepareExchangedData( |
478
|
|
|
array( |
479
|
|
|
'error' => true, |
480
|
|
|
'message' => $lang->get('key_is_not_correct'), |
481
|
|
|
), |
482
|
|
|
'encode' |
483
|
|
|
); |
484
|
|
|
break; |
485
|
|
|
} |
486
|
|
|
// Is admin? |
487
|
|
|
if ($session->get('user-admin') === 1) { |
488
|
|
|
echo prepareExchangedData( |
489
|
|
|
array( |
490
|
|
|
'error' => true, |
491
|
|
|
'message' => $lang->get('error_not_allowed_to'), |
492
|
|
|
), |
493
|
|
|
'encode' |
494
|
|
|
); |
495
|
|
|
break; |
496
|
|
|
} |
497
|
|
|
|
498
|
|
|
$error = ''; |
499
|
|
|
require_once 'main.functions.php'; |
500
|
|
|
|
501
|
|
|
// store old sk |
502
|
|
|
$session->set('user-reencrypt_old_salt', file_get_contents(SECUREPATH.'/'.SECUREFILE)); |
503
|
|
|
|
504
|
|
|
// generate new saltkey |
505
|
|
|
$old_sk_filename = SECUREPATH.'/'.SECUREFILE . date('Y_m_d', mktime(0, 0, 0, (int) date('m'), (int) date('d'), (int) date('y'))) . '.' . time(); |
506
|
|
|
copy( |
507
|
|
|
SECUREPATH.'/'.SECUREFILE, |
508
|
|
|
$old_sk_filename |
509
|
|
|
); |
510
|
|
|
$new_key = defuse_generate_key(); |
511
|
|
|
file_put_contents( |
512
|
|
|
SECUREPATH.'/'.SECUREFILE, |
513
|
|
|
$new_key |
514
|
|
|
); |
515
|
|
|
|
516
|
|
|
// store new sk |
517
|
|
|
$session->set('user-reencrypt_new_salt', file_get_contents(SECUREPATH.'/'.SECUREFILE)); |
518
|
|
|
|
519
|
|
|
//put tool in maintenance. |
520
|
|
|
DB::update( |
521
|
|
|
prefixTable('misc'), |
522
|
|
|
array( |
523
|
|
|
'valeur' => '1', |
524
|
|
|
'updated_at' => time(), |
525
|
|
|
), |
526
|
|
|
'intitule = %s AND type= %s', |
527
|
|
|
'maintenance_mode', |
528
|
|
|
'admin' |
529
|
|
|
); |
530
|
|
|
//log |
531
|
|
|
logEvents($SETTINGS, 'system', 'change_salt_key', (string) $session->get('user-id'), $session->get('user-login')); |
532
|
|
|
|
533
|
|
|
// get number of items to change |
534
|
|
|
DB::query('SELECT id FROM ' . prefixTable('items') . ' WHERE perso = %i', 0); |
535
|
|
|
$nb_of_items = DB::count(); |
536
|
|
|
|
537
|
|
|
// create backup table |
538
|
|
|
DB::query('DROP TABLE IF EXISTS ' . prefixTable('sk_reencrypt_backup')); |
539
|
|
|
DB::query( |
540
|
|
|
'CREATE TABLE `' . prefixTable('sk_reencrypt_backup') . '` ( |
541
|
|
|
`id` int(12) NOT null AUTO_INCREMENT, |
542
|
|
|
`current_table` varchar(100) NOT NULL, |
543
|
|
|
`current_field` varchar(500) NOT NULL, |
544
|
|
|
`value_id` varchar(500) NOT NULL, |
545
|
|
|
`value` text NOT NULL, |
546
|
|
|
`value2` varchar(500) NOT NULL, |
547
|
|
|
`current_sql` text NOT NULL, |
548
|
|
|
`result` text NOT NULL, |
549
|
|
|
PRIMARY KEY (`id`) |
550
|
|
|
) CHARSET=utf8;' |
551
|
|
|
); |
552
|
|
|
|
553
|
|
|
// store old SK in backup table |
554
|
|
|
DB::insert( |
555
|
|
|
prefixTable('sk_reencrypt_backup'), |
556
|
|
|
array( |
557
|
|
|
'current_table' => 'old_sk', |
558
|
|
|
'current_field' => 'old_sk', |
559
|
|
|
'value_id' => 'old_sk', |
560
|
|
|
'value' => $session->get('user-reencrypt_old_salt'), |
561
|
|
|
'current_sql' => 'old_sk', |
562
|
|
|
'value2' => $old_sk_filename, |
563
|
|
|
'result' => 'none', |
564
|
|
|
) |
565
|
|
|
); |
566
|
|
|
|
567
|
|
|
// delete previous backup files |
568
|
|
|
$files = glob($SETTINGS['path_to_upload_folder'] . '/*'); // get all file names |
569
|
|
|
foreach ($files as $file) { // iterate files |
570
|
|
|
if (is_file($file)) { |
571
|
|
|
$file_parts = pathinfo($file); |
572
|
|
|
if (strpos($file_parts['filename'], '.bck-change-sk') !== false) { |
573
|
|
|
unlink($file); // delete file |
574
|
|
|
} |
575
|
|
|
} |
576
|
|
|
} |
577
|
|
|
|
578
|
|
|
// Send back |
579
|
|
|
echo prepareExchangedData( |
580
|
|
|
array( |
581
|
|
|
'error' => false, |
582
|
|
|
'message' => '', |
583
|
|
|
'nextAction' => 'encrypt_items', |
584
|
|
|
'nbOfItems' => $nb_of_items, |
585
|
|
|
), |
586
|
|
|
'encode' |
587
|
|
|
); |
588
|
|
|
break; |
589
|
|
|
|
590
|
|
|
/* |
591
|
|
|
* Change SALT Key - ENCRYPT |
592
|
|
|
*/ |
593
|
|
|
case 'admin_action_change_salt_key___encrypt': |
594
|
|
|
// Check KEY |
595
|
|
|
if ($post_key !== $session->get('key')) { |
596
|
|
|
echo prepareExchangedData( |
597
|
|
|
array( |
598
|
|
|
'error' => true, |
599
|
|
|
'message' => $lang->get('key_is_not_correct'), |
600
|
|
|
'nextAction' => '', |
601
|
|
|
'nbOfItems' => '', |
602
|
|
|
), |
603
|
|
|
'encode' |
604
|
|
|
); |
605
|
|
|
break; |
606
|
|
|
} |
607
|
|
|
// Is admin? |
608
|
|
|
if ($session->get('user-admin') === 1) { |
609
|
|
|
echo prepareExchangedData( |
610
|
|
|
array( |
611
|
|
|
'error' => true, |
612
|
|
|
'message' => $lang->get('error_not_allowed_to'), |
613
|
|
|
), |
614
|
|
|
'encode' |
615
|
|
|
); |
616
|
|
|
break; |
617
|
|
|
} |
618
|
|
|
|
619
|
|
|
$error = ''; |
620
|
|
|
require_once 'main.functions.php'; |
621
|
|
|
|
622
|
|
|
// prepare SK |
623
|
|
|
if (empty($session->get('user-reencrypt_new_salt')) === true || empty($session->get('user-reencrypt_old_salt')) === true) { |
624
|
|
|
// SK is not correct |
625
|
|
|
echo prepareExchangedData( |
626
|
|
|
array( |
627
|
|
|
'error' => true, |
628
|
|
|
'message' => 'saltkeys are empty???', |
629
|
|
|
'nbOfItems' => '', |
630
|
|
|
'nextAction' => '', |
631
|
|
|
), |
632
|
|
|
'encode' |
633
|
|
|
); |
634
|
|
|
break; |
635
|
|
|
} |
636
|
|
|
|
637
|
|
|
// Do init |
638
|
|
|
$nb_of_items = 0; |
639
|
|
|
$error = $nextStart = ''; |
640
|
|
|
|
641
|
|
|
|
642
|
|
|
// what objects to treat |
643
|
|
|
if (empty($post_object) === true) { |
644
|
|
|
// no more object to treat |
645
|
|
|
$nextAction = 'finishing'; |
646
|
|
|
} else { |
647
|
|
|
// manage list of objects |
648
|
|
|
$objects = explode(',', $post_object); |
649
|
|
|
|
650
|
|
|
// Allowed values for $_POST['object'] : "items,logs,files,categories" |
651
|
|
|
if (in_array($objects[0], array('items', 'logs', 'files', 'categories')) === false) { |
652
|
|
|
echo prepareExchangedData( |
653
|
|
|
array( |
654
|
|
|
'error' => true, |
655
|
|
|
'message' => 'Input `' . $objects[0] . '` is not allowed', |
656
|
|
|
'nbOfItems' => '', |
657
|
|
|
'nextAction' => '', |
658
|
|
|
), |
659
|
|
|
'encode' |
660
|
|
|
); |
661
|
|
|
break; |
662
|
|
|
} |
663
|
|
|
|
664
|
|
|
if ($objects[0] === 'items') { |
665
|
|
|
//change all encrypted data in Items (passwords) |
666
|
|
|
$rows = DB::query( |
667
|
|
|
'SELECT id, pw, pw_iv |
668
|
|
|
FROM ' . prefixTable('items') . ' |
669
|
|
|
WHERE perso = %s |
670
|
|
|
LIMIT ' . $post_start . ', ' . $post_length, |
671
|
|
|
'0' |
672
|
|
|
); |
673
|
|
|
foreach ($rows as $record) { |
674
|
|
|
// backup data |
675
|
|
|
DB::insert( |
676
|
|
|
prefixTable('sk_reencrypt_backup'), |
677
|
|
|
array( |
678
|
|
|
'current_table' => 'items', |
679
|
|
|
'current_field' => 'pw', |
680
|
|
|
'value_id' => $record['id'], |
681
|
|
|
'value' => $record['pw'], |
682
|
|
|
'current_sql' => 'UPDATE ' . prefixTable('items') . " SET pw = '" . $record['pw'] . "' WHERE id = '" . $record['id'] . "';", |
683
|
|
|
'value2' => 'none', |
684
|
|
|
'result' => 'none', |
685
|
|
|
) |
686
|
|
|
); |
687
|
|
|
$newID = DB::insertId(); |
688
|
|
|
|
689
|
|
|
$pw = cryption( |
690
|
|
|
$record['pw'], |
691
|
|
|
$session->get('user-reencrypt_old_salt'), |
692
|
|
|
'decrypt', |
693
|
|
|
$SETTINGS |
694
|
|
|
); |
695
|
|
|
//encrypt with new SALT |
696
|
|
|
$encrypt = cryption( |
697
|
|
|
$pw['string'], |
698
|
|
|
$session->get('user-reencrypt_new_salt'), |
699
|
|
|
'encrypt', |
700
|
|
|
$SETTINGS |
701
|
|
|
); |
702
|
|
|
|
703
|
|
|
//save in DB |
704
|
|
|
DB::update( |
705
|
|
|
prefixTable('items'), |
706
|
|
|
array( |
707
|
|
|
'pw' => $encrypt['string'], |
708
|
|
|
'pw_iv' => '', |
709
|
|
|
), |
710
|
|
|
'id = %i', |
711
|
|
|
$record['id'] |
712
|
|
|
); |
713
|
|
|
|
714
|
|
|
// update backup table |
715
|
|
|
DB::update( |
716
|
|
|
prefixTable('sk_reencrypt_backup'), |
717
|
|
|
array( |
718
|
|
|
'result' => 'ok', |
719
|
|
|
), |
720
|
|
|
'id=%i', |
721
|
|
|
$newID |
722
|
|
|
); |
723
|
|
|
} |
724
|
|
|
// --- |
725
|
|
|
// CASE OF LOGS |
726
|
|
|
// --- |
727
|
|
|
} elseif ($objects[0] === 'logs') { |
728
|
|
|
//change all encrypted data in Logs (passwords) |
729
|
|
|
$rows = DB::query( |
730
|
|
|
'SELECT raison, increment_id |
731
|
|
|
FROM ' . prefixTable('log_items') . " |
732
|
|
|
WHERE action = %s AND raison LIKE 'at_pw :%' |
733
|
|
|
LIMIT " . $post_start . ', ' . $post_length, |
734
|
|
|
'at_modification' |
735
|
|
|
); |
736
|
|
|
foreach ($rows as $record) { |
737
|
|
|
// backup data |
738
|
|
|
DB::insert( |
739
|
|
|
prefixTable('sk_reencrypt_backup'), |
740
|
|
|
array( |
741
|
|
|
'current_table' => 'log_items', |
742
|
|
|
'current_field' => 'raison', |
743
|
|
|
'value_id' => $record['increment_id'], |
744
|
|
|
'value' => $record['raison'], |
745
|
|
|
'current_sql' => 'UPDATE ' . prefixTable('log_items') . " SET raison = '" . $record['raison'] . "' WHERE increment_id = '" . $record['increment_id'] . "';", |
746
|
|
|
'value2' => 'none', |
747
|
|
|
'result' => 'none', |
748
|
|
|
) |
749
|
|
|
); |
750
|
|
|
$newID = DB::insertId(); |
751
|
|
|
|
752
|
|
|
// extract the pwd |
753
|
|
|
$tmp = explode('at_pw :', $record['raison']); |
754
|
|
|
if (!empty($tmp[1])) { |
755
|
|
|
$pw = cryption( |
756
|
|
|
$tmp[1], |
757
|
|
|
$session->get('user-reencrypt_old_salt'), |
758
|
|
|
'decrypt', |
759
|
|
|
$SETTINGS |
760
|
|
|
); |
761
|
|
|
//encrypt with new SALT |
762
|
|
|
$encrypt = cryption( |
763
|
|
|
$pw['string'], |
764
|
|
|
$session->get('user-reencrypt_new_salt'), |
765
|
|
|
'encrypt', |
766
|
|
|
$SETTINGS |
767
|
|
|
); |
768
|
|
|
|
769
|
|
|
// save in DB |
770
|
|
|
DB::update( |
771
|
|
|
prefixTable('log_items'), |
772
|
|
|
array( |
773
|
|
|
'raison' => 'at_pw :' . $encrypt['string'], |
774
|
|
|
'encryption_type' => 'defuse', |
775
|
|
|
), |
776
|
|
|
'increment_id = %i', |
777
|
|
|
$record['increment_id'] |
778
|
|
|
); |
779
|
|
|
|
780
|
|
|
// update backup table |
781
|
|
|
DB::update( |
782
|
|
|
prefixTable('sk_reencrypt_backup'), |
783
|
|
|
array( |
784
|
|
|
'result' => 'ok', |
785
|
|
|
), |
786
|
|
|
'id=%i', |
787
|
|
|
$newID |
788
|
|
|
); |
789
|
|
|
} |
790
|
|
|
} |
791
|
|
|
// --- |
792
|
|
|
// CASE OF CATEGORIES |
793
|
|
|
// --- |
794
|
|
|
} elseif ($objects[0] === 'categories') { |
795
|
|
|
//change all encrypted data in CATEGORIES (passwords) |
796
|
|
|
$rows = DB::query( |
797
|
|
|
'SELECT id, data |
798
|
|
|
FROM ' . prefixTable('categories_items') . ' |
799
|
|
|
LIMIT ' . $post_start . ', ' . $post_length |
800
|
|
|
); |
801
|
|
|
foreach ($rows as $record) { |
802
|
|
|
// backup data |
803
|
|
|
DB::insert( |
804
|
|
|
prefixTable('sk_reencrypt_backup'), |
805
|
|
|
array( |
806
|
|
|
'current_table' => 'categories_items', |
807
|
|
|
'current_field' => 'data', |
808
|
|
|
'value_id' => $record['id'], |
809
|
|
|
'value' => $record['data'], |
810
|
|
|
'current_sql' => 'UPDATE ' . prefixTable('categories_items') . " SET data = '" . $record['data'] . "' WHERE id = '" . $record['id'] . "';", |
811
|
|
|
'value2' => 'none', |
812
|
|
|
'result' => 'none', |
813
|
|
|
) |
814
|
|
|
); |
815
|
|
|
$newID = DB::insertId(); |
816
|
|
|
|
817
|
|
|
$pw = cryption( |
818
|
|
|
$record['data'], |
819
|
|
|
$session->get('user-reencrypt_old_salt'), |
820
|
|
|
'decrypt', |
821
|
|
|
$SETTINGS |
822
|
|
|
); |
823
|
|
|
//encrypt with new SALT |
824
|
|
|
$encrypt = cryption( |
825
|
|
|
$pw['string'], |
826
|
|
|
$session->get('user-reencrypt_new_salt'), |
827
|
|
|
'encrypt', |
828
|
|
|
$SETTINGS |
829
|
|
|
); |
830
|
|
|
// save in DB |
831
|
|
|
DB::update( |
832
|
|
|
prefixTable('categories_items'), |
833
|
|
|
array( |
834
|
|
|
'data' => $encrypt['string'], |
835
|
|
|
'encryption_type' => 'defuse', |
836
|
|
|
), |
837
|
|
|
'id = %i', |
838
|
|
|
$record['id'] |
839
|
|
|
); |
840
|
|
|
|
841
|
|
|
// update backup table |
842
|
|
|
DB::update( |
843
|
|
|
prefixTable('sk_reencrypt_backup'), |
844
|
|
|
array( |
845
|
|
|
'result' => 'ok', |
846
|
|
|
), |
847
|
|
|
'id=%i', |
848
|
|
|
$newID |
849
|
|
|
); |
850
|
|
|
} |
851
|
|
|
// --- |
852
|
|
|
// CASE OF FILES |
853
|
|
|
// --- |
854
|
|
|
} elseif ($objects[0] === 'files') { |
855
|
|
|
// Change all encrypted data in FILES (passwords) |
856
|
|
|
$rows = DB::query( |
857
|
|
|
'SELECT id, file, status |
858
|
|
|
FROM ' . prefixTable('files') . " |
859
|
|
|
WHERE status = 'encrypted' |
860
|
|
|
LIMIT " . $post_start . ', ' . $post_length |
861
|
|
|
); |
862
|
|
|
foreach ($rows as $record) { |
863
|
|
|
// backup data |
864
|
|
|
DB::insert( |
865
|
|
|
prefixTable('sk_reencrypt_backup'), |
866
|
|
|
array( |
867
|
|
|
'current_table' => 'files', |
868
|
|
|
'current_field' => 'file', |
869
|
|
|
'value_id' => $record['id'], |
870
|
|
|
'value' => $record['file'], |
871
|
|
|
'current_sql' => 'no_query', |
872
|
|
|
'value2' => 'none', |
873
|
|
|
'result' => 'none', |
874
|
|
|
) |
875
|
|
|
); |
876
|
|
|
$newID = DB::insertId(); |
877
|
|
|
|
878
|
|
|
if (file_exists($SETTINGS['path_to_upload_folder'] . '/' . $record['file'])) { |
879
|
|
|
// make a copy of file |
880
|
|
|
if (!copy( |
881
|
|
|
$SETTINGS['path_to_upload_folder'] . '/' . $record['file'], |
882
|
|
|
$SETTINGS['path_to_upload_folder'] . '/' . $record['file'] . '.copy' |
883
|
|
|
)) { |
884
|
|
|
$error = 'Copy not possible'; |
885
|
|
|
exit; |
886
|
|
|
} else { |
887
|
|
|
// prepare a bck of file (that will not be deleted) |
888
|
|
|
$backup_filename = $record['file'] . '.bck-change-sk.' . time(); |
889
|
|
|
copy( |
890
|
|
|
$SETTINGS['path_to_upload_folder'] . '/' . $record['file'], |
891
|
|
|
$SETTINGS['path_to_upload_folder'] . '/' . $backup_filename |
892
|
|
|
); |
893
|
|
|
} |
894
|
|
|
|
895
|
|
|
// Treat the file |
896
|
|
|
// STEP1 - Do decryption |
897
|
|
|
prepareFileWithDefuse( |
898
|
|
|
'decrypt', |
899
|
|
|
$SETTINGS['path_to_upload_folder'] . '/' . $record['file'], |
900
|
|
|
$SETTINGS['path_to_upload_folder'] . '/' . $record['file'] . '_encrypted' |
901
|
|
|
); |
902
|
|
|
|
903
|
|
|
// Do cleanup of files |
904
|
|
|
unlink($SETTINGS['path_to_upload_folder'] . '/' . $record['file']); |
905
|
|
|
|
906
|
|
|
// STEP2 - Do encryption |
907
|
|
|
prepareFileWithDefuse( |
908
|
|
|
'encryp', |
909
|
|
|
$SETTINGS['path_to_upload_folder'] . '/' . $record['file'] . '_encrypted', |
910
|
|
|
$SETTINGS['path_to_upload_folder'] . '/' . $record['file'] |
911
|
|
|
); |
912
|
|
|
|
913
|
|
|
// Do cleanup of files |
914
|
|
|
unlink($SETTINGS['path_to_upload_folder'] . '/' . $record['file'] . '_encrypted'); |
915
|
|
|
|
916
|
|
|
// Update backup table |
917
|
|
|
DB::update( |
918
|
|
|
prefixTable('sk_reencrypt_backup'), |
919
|
|
|
array( |
920
|
|
|
'value2' => $backup_filename, |
921
|
|
|
'result' => 'ok', |
922
|
|
|
), |
923
|
|
|
'id=%i', |
924
|
|
|
$newID |
925
|
|
|
); |
926
|
|
|
} |
927
|
|
|
} |
928
|
|
|
} |
929
|
|
|
|
930
|
|
|
$nextStart = intval($post_start) + intval($post_length); |
931
|
|
|
|
932
|
|
|
// check if last item to change has been treated |
933
|
|
|
if ($nextStart >= intval($post_nbItems)) { |
934
|
|
|
array_shift($objects); |
935
|
|
|
$nextAction = implode(',', $objects); // remove first object of the list |
936
|
|
|
|
937
|
|
|
// do some things for new object |
938
|
|
|
if (isset($objects[0])) { |
939
|
|
|
if ($objects[0] === 'logs') { |
940
|
|
|
DB::query('SELECT increment_id FROM ' . prefixTable('log_items') . " WHERE action = %s AND raison LIKE 'at_pw :%'", 'at_modification'); |
941
|
|
|
} elseif ($objects[0] === 'files') { |
942
|
|
|
DB::query('SELECT id FROM ' . prefixTable('files')); |
943
|
|
|
} elseif ($objects[0] === 'categories') { |
944
|
|
|
DB::query('SELECT id FROM ' . prefixTable('categories_items')); |
945
|
|
|
} elseif ($objects[0] === 'custfields') { |
946
|
|
|
DB::query('SELECT raison FROM ' . prefixTable('log_items') . " WHERE action = %s AND raison LIKE 'at_pw :%'", 'at_modification'); |
947
|
|
|
} |
948
|
|
|
$nb_of_items = DB::count(); |
949
|
|
|
} else { |
950
|
|
|
// now finishing |
951
|
|
|
$nextAction = 'finishing'; |
952
|
|
|
} |
953
|
|
|
} else { |
954
|
|
|
$nextAction = $post_object; |
955
|
|
|
$nb_of_items = 0; |
956
|
|
|
} |
957
|
|
|
} |
958
|
|
|
|
959
|
|
|
// Send back |
960
|
|
|
echo prepareExchangedData( |
961
|
|
|
array( |
962
|
|
|
'error' => false, |
963
|
|
|
'message' => '', |
964
|
|
|
'nextAction' => $nextAction, |
965
|
|
|
'nextStart' => (int) $nextStart, |
966
|
|
|
'nbOfItems' => $nb_of_items, |
967
|
|
|
'oldsk' => $session->get('user-reencrypt_old_salt'), |
968
|
|
|
'newsk' => $session->get('user-reencrypt_new_salt'), |
969
|
|
|
), |
970
|
|
|
'encode' |
971
|
|
|
); |
972
|
|
|
break; |
973
|
|
|
|
974
|
|
|
/* |
975
|
|
|
* Change SALT Key - END |
976
|
|
|
*/ |
977
|
|
|
case 'admin_action_change_salt_key___end': |
978
|
|
|
// Check KEY |
979
|
|
|
if ($post_key !== $session->get('key')) { |
980
|
|
|
echo prepareExchangedData( |
981
|
|
|
array( |
982
|
|
|
'error' => true, |
983
|
|
|
'message' => $lang->get('key_is_not_correct'), |
984
|
|
|
), |
985
|
|
|
'encode' |
986
|
|
|
); |
987
|
|
|
break; |
988
|
|
|
} |
989
|
|
|
// Is admin? |
990
|
|
|
if ($session->get('user-admin') === 1) { |
991
|
|
|
echo prepareExchangedData( |
992
|
|
|
array( |
993
|
|
|
'error' => true, |
994
|
|
|
'message' => $lang->get('error_not_allowed_to'), |
995
|
|
|
), |
996
|
|
|
'encode' |
997
|
|
|
); |
998
|
|
|
break; |
999
|
|
|
} |
1000
|
|
|
$error = ''; |
1001
|
|
|
|
1002
|
|
|
// quit maintenance mode. |
1003
|
|
|
DB::update( |
1004
|
|
|
prefixTable('misc'), |
1005
|
|
|
array( |
1006
|
|
|
'valeur' => '0', |
1007
|
|
|
'updated_at' => time(), |
1008
|
|
|
), |
1009
|
|
|
'intitule = %s AND type= %s', |
1010
|
|
|
'maintenance_mode', |
1011
|
|
|
'admin' |
1012
|
|
|
); |
1013
|
|
|
|
1014
|
|
|
// Send back |
1015
|
|
|
echo prepareExchangedData( |
1016
|
|
|
array( |
1017
|
|
|
'error' => false, |
1018
|
|
|
'message' => '', |
1019
|
|
|
'nextAction' => 'done', |
1020
|
|
|
), |
1021
|
|
|
'encode' |
1022
|
|
|
); |
1023
|
|
|
break; |
1024
|
|
|
|
1025
|
|
|
/* |
1026
|
|
|
* Change SALT Key - Restore BACKUP data |
1027
|
|
|
*/ |
1028
|
|
|
case 'admin_action_change_salt_key___restore_backup': |
1029
|
|
|
// Check KEY |
1030
|
|
|
if ($post_key !== $session->get('key')) { |
1031
|
|
|
echo prepareExchangedData( |
1032
|
|
|
array( |
1033
|
|
|
'error' => true, |
1034
|
|
|
'message' => $lang->get('key_is_not_correct'), |
1035
|
|
|
), |
1036
|
|
|
'encode' |
1037
|
|
|
); |
1038
|
|
|
break; |
1039
|
|
|
} |
1040
|
|
|
// Is admin? |
1041
|
|
|
if ($session->get('user-admin') === 1) { |
1042
|
|
|
echo prepareExchangedData( |
1043
|
|
|
array( |
1044
|
|
|
'error' => true, |
1045
|
|
|
'message' => $lang->get('error_not_allowed_to'), |
1046
|
|
|
), |
1047
|
|
|
'encode' |
1048
|
|
|
); |
1049
|
|
|
break; |
1050
|
|
|
} |
1051
|
|
|
|
1052
|
|
|
// delete files |
1053
|
|
|
$previous_saltkey_filename = ''; |
1054
|
|
|
$rows = DB::query( |
1055
|
|
|
'SELECT current_table, value, value2, current_sql |
1056
|
|
|
FROM ' . prefixTable('sk_reencrypt_backup') |
1057
|
|
|
); |
1058
|
|
|
foreach ($rows as $record) { |
1059
|
|
|
if ($record['current_table'] === 'items' || $record['current_table'] === 'logs' || $record['current_table'] === 'categories') { |
1060
|
|
|
// excute query |
1061
|
|
|
DB::query( |
1062
|
|
|
str_replace("\'", "'", $record['current_sql']) |
1063
|
|
|
); |
1064
|
|
|
} elseif ($record['current_table'] === 'files') { |
1065
|
|
|
// restore backup file |
1066
|
|
|
if (file_exists($SETTINGS['path_to_upload_folder'] . '/' . $record['value'])) { |
1067
|
|
|
unlink($SETTINGS['path_to_upload_folder'] . '/' . $record['value']); |
1068
|
|
|
if (file_exists($SETTINGS['path_to_upload_folder'] . '/' . $record['value2'])) { |
1069
|
|
|
rename( |
1070
|
|
|
$SETTINGS['path_to_upload_folder'] . '/' . $record['value2'], |
1071
|
|
|
$SETTINGS['path_to_upload_folder'] . '/' . $record['value'] |
1072
|
|
|
); |
1073
|
|
|
} |
1074
|
|
|
} |
1075
|
|
|
} elseif ($record['current_table'] === 'old_sk') { |
1076
|
|
|
$previous_saltkey_filename = $record['value2']; |
1077
|
|
|
} |
1078
|
|
|
} |
1079
|
|
|
|
1080
|
|
|
// restore saltkey file |
1081
|
|
|
if (file_exists($previous_saltkey_filename)) { |
1082
|
|
|
unlink(SECUREPATH.'/'.SECUREFILE); |
1083
|
|
|
rename( |
1084
|
|
|
$previous_saltkey_filename, |
1085
|
|
|
SECUREPATH.'/'.SECUREFILE |
1086
|
|
|
); |
1087
|
|
|
} |
1088
|
|
|
|
1089
|
|
|
// drop table |
1090
|
|
|
DB::query('DROP TABLE IF EXISTS ' . prefixTable('sk_reencrypt_backup')); |
1091
|
|
|
|
1092
|
|
|
// Send back |
1093
|
|
|
echo prepareExchangedData( |
1094
|
|
|
array( |
1095
|
|
|
'error' => false, |
1096
|
|
|
'message' => '', |
1097
|
|
|
), |
1098
|
|
|
'encode' |
1099
|
|
|
); |
1100
|
|
|
|
1101
|
|
|
break; |
1102
|
|
|
|
1103
|
|
|
/* |
1104
|
|
|
* Change SALT Key - Delete BACKUP data |
1105
|
|
|
*/ |
1106
|
|
|
case 'admin_action_change_salt_key___delete_backup': |
1107
|
|
|
// Check KEY |
1108
|
|
|
if ($post_key !== $session->get('key')) { |
1109
|
|
|
echo prepareExchangedData( |
1110
|
|
|
array( |
1111
|
|
|
'error' => true, |
1112
|
|
|
'message' => $lang->get('key_is_not_correct'), |
1113
|
|
|
), |
1114
|
|
|
'encode' |
1115
|
|
|
); |
1116
|
|
|
break; |
1117
|
|
|
} |
1118
|
|
|
// Is admin? |
1119
|
|
|
if ($session->get('user-admin') === 1) { |
1120
|
|
|
echo prepareExchangedData( |
1121
|
|
|
array( |
1122
|
|
|
'error' => true, |
1123
|
|
|
'message' => $lang->get('error_not_allowed_to'), |
1124
|
|
|
), |
1125
|
|
|
'encode' |
1126
|
|
|
); |
1127
|
|
|
break; |
1128
|
|
|
} |
1129
|
|
|
|
1130
|
|
|
// delete files |
1131
|
|
|
$rows = DB::query( |
1132
|
|
|
'SELECT value, value2 |
1133
|
|
|
FROM ' . prefixTable('sk_reencrypt_backup') . " |
1134
|
|
|
WHERE current_table = 'files'" |
1135
|
|
|
); |
1136
|
|
|
foreach ($rows as $record) { |
1137
|
|
|
if (file_exists($SETTINGS['path_to_upload_folder'] . '/' . $record['value2'])) { |
1138
|
|
|
unlink($SETTINGS['path_to_upload_folder'] . '/' . $record['value2']); |
1139
|
|
|
} |
1140
|
|
|
} |
1141
|
|
|
|
1142
|
|
|
// drop table |
1143
|
|
|
DB::query('DROP TABLE IF EXISTS ' . prefixTable('sk_reencrypt_backup')); |
1144
|
|
|
|
1145
|
|
|
echo '[{"status":"done"}]'; |
1146
|
|
|
break; |
1147
|
|
|
|
1148
|
|
|
/* |
1149
|
|
|
* Test the email configuraiton |
1150
|
|
|
*/ |
1151
|
|
|
case 'admin_email_test_configuration': |
1152
|
|
|
// Check KEY |
1153
|
|
|
if ($post_key !== $session->get('key')) { |
1154
|
|
|
echo prepareExchangedData( |
1155
|
|
|
array( |
1156
|
|
|
'error' => true, |
1157
|
|
|
'message' => $lang->get('key_is_not_correct'), |
1158
|
|
|
), |
1159
|
|
|
'encode' |
1160
|
|
|
); |
1161
|
|
|
break; |
1162
|
|
|
} |
1163
|
|
|
|
1164
|
|
|
// User has an email set? |
1165
|
|
|
if (empty($session->get('user-email')) === true) { |
1166
|
|
|
echo prepareExchangedData( |
1167
|
|
|
array( |
1168
|
|
|
'error' => true, |
1169
|
|
|
'message' => $lang->get('no_email_set'), |
1170
|
|
|
), |
1171
|
|
|
'encode' |
1172
|
|
|
); |
1173
|
|
|
} else { |
1174
|
|
|
require_once $SETTINGS['cpassman_dir'] . '/sources/main.functions.php'; |
1175
|
|
|
|
1176
|
|
|
//send email |
1177
|
|
|
$emailSettings = new EmailSettings($SETTINGS); |
1178
|
|
|
$emailService = new EmailService(); |
1179
|
|
|
$emailService->sendMail( |
1180
|
|
|
$lang->get('admin_email_test_subject'), |
1181
|
|
|
$lang->get('admin_email_test_body'), |
1182
|
|
|
$session->get('user-email'), |
1183
|
|
|
$emailSettings |
1184
|
|
|
); |
1185
|
|
|
|
1186
|
|
|
echo prepareExchangedData( |
1187
|
|
|
array( |
1188
|
|
|
'error' => false, |
1189
|
|
|
'message' => '', |
1190
|
|
|
), |
1191
|
|
|
'encode' |
1192
|
|
|
); |
1193
|
|
|
} |
1194
|
|
|
break; |
1195
|
|
|
|
1196
|
|
|
/* |
1197
|
|
|
* Send emails in backlog |
1198
|
|
|
*/ |
1199
|
|
|
case 'admin_email_send_backlog': |
1200
|
|
|
// Check KEY |
1201
|
|
|
if ($post_key !== $session->get('key')) { |
1202
|
|
|
echo prepareExchangedData( |
1203
|
|
|
array( |
1204
|
|
|
'error' => true, |
1205
|
|
|
'message' => $lang->get('key_is_not_correct'), |
1206
|
|
|
), |
1207
|
|
|
'encode' |
1208
|
|
|
); |
1209
|
|
|
break; |
1210
|
|
|
} |
1211
|
|
|
|
1212
|
|
|
include_once $SETTINGS['cpassman_dir'] . '/sources/main.functions.php'; |
1213
|
|
|
$emailSettings = new EmailSettings($SETTINGS); |
1214
|
|
|
$emailService = new EmailService(); |
1215
|
|
|
|
1216
|
|
|
$rows = DB::query( |
1217
|
|
|
'SELECT * |
1218
|
|
|
FROM ' . prefixTable('emails') . ' |
1219
|
|
|
WHERE status = %s OR status = %s', |
1220
|
|
|
'not_sent', |
1221
|
|
|
'' |
1222
|
|
|
); |
1223
|
|
|
$counter = DB::count(); |
1224
|
|
|
$error = false; |
1225
|
|
|
$message = ''; |
1226
|
|
|
|
1227
|
|
|
if ($counter > 0) { |
1228
|
|
|
// Only treat first email |
1229
|
|
|
foreach ($rows as $record) { |
1230
|
|
|
//send email |
1231
|
|
|
$email = $emailService->sendMail( |
1232
|
|
|
$record['subject'], |
1233
|
|
|
$record['body'], |
1234
|
|
|
$record['receivers'], |
1235
|
|
|
$emailSettings |
1236
|
|
|
); |
1237
|
|
|
$ret = json_decode( |
1238
|
|
|
$email, |
1239
|
|
|
true |
1240
|
|
|
); |
1241
|
|
|
|
1242
|
|
|
if (empty($ret['error']) === false) { |
1243
|
|
|
//update item_id in files table |
1244
|
|
|
DB::update( |
1245
|
|
|
prefixTable('emails'), |
1246
|
|
|
array( |
1247
|
|
|
'status' => 'not_sent', |
1248
|
|
|
), |
1249
|
|
|
'timestamp = %s', |
1250
|
|
|
$record['timestamp'] |
1251
|
|
|
); |
1252
|
|
|
|
1253
|
|
|
$error = true; |
1254
|
|
|
$message = $ret['message']; |
1255
|
|
|
} else { |
1256
|
|
|
//delete from DB |
1257
|
|
|
DB::delete( |
1258
|
|
|
prefixTable('emails'), |
1259
|
|
|
'timestamp = %s', |
1260
|
|
|
$record['timestamp'] |
1261
|
|
|
); |
1262
|
|
|
|
1263
|
|
|
//update LOG |
1264
|
|
|
logEvents( |
1265
|
|
|
$SETTINGS, |
1266
|
|
|
'admin_action', |
1267
|
|
|
'Emails backlog', |
1268
|
|
|
(string) $session->get('user-id'), |
1269
|
|
|
$session->get('user-login') |
1270
|
|
|
); |
1271
|
|
|
} |
1272
|
|
|
|
1273
|
|
|
// Exit loop |
1274
|
|
|
break; |
1275
|
|
|
} |
1276
|
|
|
} |
1277
|
|
|
|
1278
|
|
|
echo prepareExchangedData( |
1279
|
|
|
array( |
1280
|
|
|
'error' => $error, |
1281
|
|
|
'message' => $message, |
1282
|
|
|
'counter' => $counter, |
1283
|
|
|
), |
1284
|
|
|
'encode' |
1285
|
|
|
); |
1286
|
|
|
break; |
1287
|
|
|
|
1288
|
|
|
/* |
1289
|
|
|
* Send emails in backlog |
1290
|
|
|
*/ |
1291
|
|
|
case 'admin_email_send_backlog_old': |
1292
|
|
|
// Check KEY |
1293
|
|
|
if ($post_key !== $session->get('key')) { |
1294
|
|
|
echo prepareExchangedData( |
1295
|
|
|
array( |
1296
|
|
|
'error' => true, |
1297
|
|
|
'message' => $lang->get('key_is_not_correct'), |
1298
|
|
|
), |
1299
|
|
|
'encode' |
1300
|
|
|
); |
1301
|
|
|
break; |
1302
|
|
|
} |
1303
|
|
|
|
1304
|
|
|
include_once $SETTINGS['cpassman_dir'] . '/sources/main.functions.php'; |
1305
|
|
|
|
1306
|
|
|
// Instatiate email settings and service |
1307
|
|
|
$emailSettings = new EmailSettings($SETTINGS); |
1308
|
|
|
$emailService = new EmailService(); |
1309
|
|
|
|
1310
|
|
|
$rows = DB::query('SELECT * FROM ' . prefixTable('emails') . ' WHERE status = %s OR status = %s', 'not_sent', ''); |
1311
|
|
|
foreach ($rows as $record) { |
1312
|
|
|
//send email |
1313
|
|
|
$email = $emailService->sendMail( |
1314
|
|
|
$record['subject'], |
1315
|
|
|
$record['body'], |
1316
|
|
|
$record['receivers'], |
1317
|
|
|
$emailSettings |
1318
|
|
|
); |
1319
|
|
|
$ret = json_decode( |
1320
|
|
|
$email, |
1321
|
|
|
true |
1322
|
|
|
); |
1323
|
|
|
|
1324
|
|
|
if (empty($ret['error']) === false) { |
1325
|
|
|
//update item_id in files table |
1326
|
|
|
DB::update( |
1327
|
|
|
prefixTable('emails'), |
1328
|
|
|
array( |
1329
|
|
|
'status' => 'not_sent', |
1330
|
|
|
), |
1331
|
|
|
'timestamp = %s', |
1332
|
|
|
$record['timestamp'] |
1333
|
|
|
); |
1334
|
|
|
} else { |
1335
|
|
|
//delete from DB |
1336
|
|
|
DB::delete(prefixTable('emails'), 'timestamp = %s', $record['timestamp']); |
1337
|
|
|
} |
1338
|
|
|
} |
1339
|
|
|
|
1340
|
|
|
//update LOG |
1341
|
|
|
logEvents($SETTINGS, 'admin_action', 'Emails backlog', (string) $session->get('user-id'), $session->get('user-login')); |
1342
|
|
|
|
1343
|
|
|
echo prepareExchangedData( |
1344
|
|
|
array( |
1345
|
|
|
'error' => false, |
1346
|
|
|
'message' => '', |
1347
|
|
|
), |
1348
|
|
|
'encode' |
1349
|
|
|
); |
1350
|
|
|
break; |
1351
|
|
|
|
1352
|
|
|
/* |
1353
|
|
|
* Attachments encryption |
1354
|
|
|
*/ |
1355
|
|
|
case 'admin_action_attachments_cryption': |
1356
|
|
|
// Check KEY |
1357
|
|
|
if ($post_key !== $session->get('key')) { |
1358
|
|
|
echo prepareExchangedData( |
1359
|
|
|
array( |
1360
|
|
|
'error' => true, |
1361
|
|
|
'message' => $lang->get('key_is_not_correct'), |
1362
|
|
|
), |
1363
|
|
|
'encode' |
1364
|
|
|
); |
1365
|
|
|
break; |
1366
|
|
|
} |
1367
|
|
|
// Is admin? |
1368
|
|
|
if ($session->get('user-admin') === 1) { |
1369
|
|
|
echo prepareExchangedData( |
1370
|
|
|
array( |
1371
|
|
|
'error' => true, |
1372
|
|
|
'message' => $lang->get('error_not_allowed_to'), |
1373
|
|
|
), |
1374
|
|
|
'encode' |
1375
|
|
|
); |
1376
|
|
|
break; |
1377
|
|
|
} |
1378
|
|
|
|
1379
|
|
|
require_once $SETTINGS['cpassman_dir'] . '/sources/main.functions.php'; |
1380
|
|
|
|
1381
|
|
|
// init |
1382
|
|
|
$filesList = array(); |
1383
|
|
|
|
1384
|
|
|
// get through files |
1385
|
|
|
if (null !== $post_option && empty($post_option) === false) { |
1386
|
|
|
// Loop on files |
1387
|
|
|
$rows = DB::query( |
1388
|
|
|
'SELECT id, file, status |
1389
|
|
|
FROM ' . prefixTable('files') |
1390
|
|
|
); |
1391
|
|
|
foreach ($rows as $record) { |
1392
|
|
|
if (is_file($SETTINGS['path_to_upload_folder'] . '/' . $record['file'])) { |
1393
|
|
|
$addFile = false; |
1394
|
|
|
if (($post_option === 'attachments-decrypt' && $record['status'] === 'encrypted') |
1395
|
|
|
|| ($post_option === 'attachments-encrypt' && $record['status'] === 'clear') |
1396
|
|
|
) { |
1397
|
|
|
$addFile = true; |
1398
|
|
|
} |
1399
|
|
|
|
1400
|
|
|
if ($addFile === true) { |
1401
|
|
|
array_push($filesList, $record['id']); |
1402
|
|
|
} |
1403
|
|
|
} |
1404
|
|
|
} |
1405
|
|
|
} else { |
1406
|
|
|
echo prepareExchangedData( |
1407
|
|
|
array( |
1408
|
|
|
'error' => true, |
1409
|
|
|
'message' => $lang->get('error_not_allowed_to'), |
1410
|
|
|
), |
1411
|
|
|
'encode' |
1412
|
|
|
); |
1413
|
|
|
} |
1414
|
|
|
|
1415
|
|
|
echo prepareExchangedData( |
1416
|
|
|
array( |
1417
|
|
|
'error' => false, |
1418
|
|
|
'message' => '', |
1419
|
|
|
'list' => $filesList, |
1420
|
|
|
'counter' => 0, |
1421
|
|
|
), |
1422
|
|
|
'encode' |
1423
|
|
|
); |
1424
|
|
|
break; |
1425
|
|
|
|
1426
|
|
|
/* |
1427
|
|
|
* Attachments encryption - Treatment in several loops |
1428
|
|
|
*/ |
1429
|
|
|
case 'admin_action_attachments_cryption_continu': |
1430
|
|
|
// Check KEY |
1431
|
|
|
if ($post_key !== $session->get('key')) { |
1432
|
|
|
echo prepareExchangedData( |
1433
|
|
|
array( |
1434
|
|
|
'error' => true, |
1435
|
|
|
'message' => $lang->get('key_is_not_correct'), |
1436
|
|
|
), |
1437
|
|
|
'encode' |
1438
|
|
|
); |
1439
|
|
|
break; |
1440
|
|
|
} |
1441
|
|
|
// Is admin? |
1442
|
|
|
if ($session->get('user-admin') === 1) { |
1443
|
|
|
echo prepareExchangedData( |
1444
|
|
|
array( |
1445
|
|
|
'error' => true, |
1446
|
|
|
'message' => $lang->get('error_not_allowed_to'), |
1447
|
|
|
), |
1448
|
|
|
'encode' |
1449
|
|
|
); |
1450
|
|
|
break; |
1451
|
|
|
} |
1452
|
|
|
|
1453
|
|
|
// Prepare variables |
1454
|
|
|
$post_list = filter_var_array($post_list, FILTER_SANITIZE_FULL_SPECIAL_CHARS); |
1455
|
|
|
$post_counter = filter_var($post_counter, FILTER_SANITIZE_NUMBER_INT); |
1456
|
|
|
|
1457
|
|
|
include $SETTINGS['cpassman_dir'] . '/includes/config/settings.php'; |
1458
|
|
|
include_once $SETTINGS['cpassman_dir'] . '/sources/main.functions.php'; |
1459
|
|
|
|
1460
|
|
|
$cpt = 0; |
1461
|
|
|
$continu = true; |
1462
|
|
|
$newFilesList = array(); |
1463
|
|
|
$message = ''; |
1464
|
|
|
|
1465
|
|
|
// treat 10 files |
1466
|
|
|
foreach ($post_list as $file) { |
1467
|
|
|
if ($cpt < 5) { |
1468
|
|
|
// Get file name |
1469
|
|
|
$file_info = DB::queryFirstRow( |
1470
|
|
|
'SELECT file |
1471
|
|
|
FROM ' . prefixTable('files') . ' |
1472
|
|
|
WHERE id = %i', |
1473
|
|
|
$file |
1474
|
|
|
); |
1475
|
|
|
|
1476
|
|
|
// skip file is Coherancey not respected |
1477
|
|
|
if (is_file($SETTINGS['path_to_upload_folder'] . '/' . $file_info['file'])) { |
1478
|
|
|
// Case where we want to decrypt |
1479
|
|
|
if ($post_option === 'decrypt') { |
1480
|
|
|
prepareFileWithDefuse( |
1481
|
|
|
'decrypt', |
1482
|
|
|
$SETTINGS['path_to_upload_folder'] . '/' . $file_info['file'], |
1483
|
|
|
$SETTINGS['path_to_upload_folder'] . '/defuse_temp_' . $file_info['file'], |
1484
|
|
|
); |
1485
|
|
|
// Case where we want to encrypt |
1486
|
|
|
} elseif ($post_option === 'encrypt') { |
1487
|
|
|
prepareFileWithDefuse( |
1488
|
|
|
'encrypt', |
1489
|
|
|
$SETTINGS['path_to_upload_folder'] . '/' . $file_info['file'], |
1490
|
|
|
$SETTINGS['path_to_upload_folder'] . '/defuse_temp_' . $file_info['file'], |
1491
|
|
|
); |
1492
|
|
|
} |
1493
|
|
|
// Do file cleanup |
1494
|
|
|
fileDelete($SETTINGS['path_to_upload_folder'] . '/' . $file_info['file'], $SETTINGS); |
1495
|
|
|
rename( |
1496
|
|
|
$SETTINGS['path_to_upload_folder'] . '/defuse_temp_' . $file_info['file'], |
1497
|
|
|
$SETTINGS['path_to_upload_folder'] . '/' . $file_info['file'] |
1498
|
|
|
); |
1499
|
|
|
|
1500
|
|
|
// store in DB |
1501
|
|
|
DB::update( |
1502
|
|
|
prefixTable('files'), |
1503
|
|
|
array( |
1504
|
|
|
'status' => $post_option === 'attachments-decrypt' ? 'clear' : 'encrypted', |
1505
|
|
|
), |
1506
|
|
|
'id = %i', |
1507
|
|
|
$file |
1508
|
|
|
); |
1509
|
|
|
|
1510
|
|
|
++$cpt; |
1511
|
|
|
} |
1512
|
|
|
} else { |
1513
|
|
|
// build list |
1514
|
|
|
array_push($newFilesList, $file); |
1515
|
|
|
} |
1516
|
|
|
} |
1517
|
|
|
|
1518
|
|
|
// Should we stop |
1519
|
|
|
if (count($newFilesList) === 0) { |
1520
|
|
|
$continu = false; |
1521
|
|
|
|
1522
|
|
|
//update LOG |
1523
|
|
|
logEvents( |
1524
|
|
|
$SETTINGS, |
1525
|
|
|
'admin_action', |
1526
|
|
|
'attachments_encryption_changed', |
1527
|
|
|
(string) $session->get('user-id'), |
1528
|
|
|
$session->get('user-login'), |
1529
|
|
|
$post_option === 'attachments-decrypt' ? 'clear' : 'encrypted' |
1530
|
|
|
); |
1531
|
|
|
|
1532
|
|
|
$message = $lang->get('last_execution') . ' ' . |
1533
|
|
|
date($SETTINGS['date_format'] . ' ' . $SETTINGS['time_format'], (int) time()) . |
1534
|
|
|
'<i class="fas fa-check text-success ml-2 mr-3"></i>'; |
1535
|
|
|
} |
1536
|
|
|
|
1537
|
|
|
echo prepareExchangedData( |
1538
|
|
|
array( |
1539
|
|
|
'error' => false, |
1540
|
|
|
'message' => $message, |
1541
|
|
|
'list' => $newFilesList, |
1542
|
|
|
'counter' => $post_cpt + $cpt, |
1543
|
|
|
'continu' => $continu, |
1544
|
|
|
), |
1545
|
|
|
'encode' |
1546
|
|
|
); |
1547
|
|
|
break; |
1548
|
|
|
|
1549
|
|
|
/* |
1550
|
|
|
* API save key |
1551
|
|
|
*/ |
1552
|
|
|
case 'admin_action_api_save_key': |
1553
|
|
|
// Check KEY |
1554
|
|
|
if ($post_key !== $session->get('key')) { |
1555
|
|
|
echo prepareExchangedData( |
1556
|
|
|
array( |
1557
|
|
|
'error' => true, |
1558
|
|
|
'message' => $lang->get('key_is_not_correct'), |
1559
|
|
|
), |
1560
|
|
|
'encode' |
1561
|
|
|
); |
1562
|
|
|
break; |
1563
|
|
|
} |
1564
|
|
|
// Is admin? |
1565
|
|
|
if ($session->get('user-admin') === 1) { |
1566
|
|
|
echo prepareExchangedData( |
1567
|
|
|
array( |
1568
|
|
|
'error' => true, |
1569
|
|
|
'message' => $lang->get('error_not_allowed_to'), |
1570
|
|
|
), |
1571
|
|
|
'encode' |
1572
|
|
|
); |
1573
|
|
|
break; |
1574
|
|
|
} |
1575
|
|
|
|
1576
|
|
|
// decrypt and retrieve data in JSON format |
1577
|
|
|
$dataReceived = prepareExchangedData( |
1578
|
|
|
$post_data, |
1579
|
|
|
'decode' |
1580
|
|
|
); |
1581
|
|
|
|
1582
|
|
|
$post_label = isset($dataReceived['label']) === true ? filter_var($dataReceived['label'], FILTER_SANITIZE_FULL_SPECIAL_CHARS) : ''; |
1583
|
|
|
$post_action = filter_var($dataReceived['action'], FILTER_SANITIZE_FULL_SPECIAL_CHARS); |
1584
|
|
|
$timestamp = time(); |
1585
|
|
|
|
1586
|
|
|
// add new key |
1587
|
|
|
if (null !== $post_action && $post_action === 'add') { |
1588
|
|
|
// Generate KEY |
1589
|
|
|
require_once 'main.functions.php'; |
1590
|
|
|
$key = GenerateCryptKey(39, false, true, true, false, true); |
1591
|
|
|
|
1592
|
|
|
// Generate objectKey |
1593
|
|
|
//$object = doDataEncryption($key, SECUREFILE.':'.$timestamp); |
1594
|
|
|
|
1595
|
|
|
// Save in DB |
1596
|
|
|
DB::insert( |
1597
|
|
|
prefixTable('api'), |
1598
|
|
|
array( |
1599
|
|
|
'increment_id' => null, |
1600
|
|
|
'type' => 'key', |
1601
|
|
|
'label' => $post_label, |
1602
|
|
|
'value' => $key, //$object['encrypted'], |
1603
|
|
|
'timestamp' => $timestamp, |
1604
|
|
|
//'user_id' => -1, |
1605
|
|
|
) |
1606
|
|
|
); |
1607
|
|
|
|
1608
|
|
|
$post_id = DB::insertId(); |
1609
|
|
|
// Update existing key |
1610
|
|
|
} elseif (null !== $post_action && $post_action === 'update') { |
1611
|
|
|
$post_id = filter_var($dataReceived['id'], FILTER_SANITIZE_NUMBER_INT); |
1612
|
|
|
|
1613
|
|
|
DB::update( |
1614
|
|
|
prefixTable('api'), |
1615
|
|
|
array( |
1616
|
|
|
'label' => $post_label, |
1617
|
|
|
'timestamp' => $timestamp, |
1618
|
|
|
), |
1619
|
|
|
'increment_id=%i', |
1620
|
|
|
$post_id |
1621
|
|
|
); |
1622
|
|
|
// Delete existing key |
1623
|
|
|
} elseif (null !== $post_action && $post_action === 'delete') { |
1624
|
|
|
$post_id = filter_var($dataReceived['id'], FILTER_SANITIZE_NUMBER_INT); |
1625
|
|
|
|
1626
|
|
|
DB::query( |
1627
|
|
|
'DELETE FROM ' . prefixTable('api') . ' WHERE increment_id = %i', |
1628
|
|
|
$post_id |
1629
|
|
|
); |
1630
|
|
|
} |
1631
|
|
|
|
1632
|
|
|
// send data |
1633
|
|
|
echo prepareExchangedData( |
1634
|
|
|
array( |
1635
|
|
|
'error' => false, |
1636
|
|
|
'message' => '', |
1637
|
|
|
'keyId' => $post_id, |
1638
|
|
|
'key' => isset($key) === true ? $key : '', |
1639
|
|
|
), |
1640
|
|
|
'encode' |
1641
|
|
|
); |
1642
|
|
|
break; |
1643
|
|
|
|
1644
|
|
|
/* |
1645
|
|
|
* API save key |
1646
|
|
|
*/ |
1647
|
|
|
case 'admin_action_api_save_ip': |
1648
|
|
|
// Check KEY |
1649
|
|
|
if ($post_key !== $session->get('key')) { |
1650
|
|
|
echo prepareExchangedData( |
1651
|
|
|
array( |
1652
|
|
|
'error' => true, |
1653
|
|
|
'message' => $lang->get('key_is_not_correct'), |
1654
|
|
|
), |
1655
|
|
|
'encode' |
1656
|
|
|
); |
1657
|
|
|
break; |
1658
|
|
|
} |
1659
|
|
|
// Is admin? |
1660
|
|
|
if ($session->get('user-admin') === 1) { |
1661
|
|
|
echo prepareExchangedData( |
1662
|
|
|
array( |
1663
|
|
|
'error' => true, |
1664
|
|
|
'message' => $lang->get('error_not_allowed_to'), |
1665
|
|
|
), |
1666
|
|
|
'encode' |
1667
|
|
|
); |
1668
|
|
|
break; |
1669
|
|
|
} |
1670
|
|
|
|
1671
|
|
|
// decrypt and retrieve data in JSON format |
1672
|
|
|
$dataReceived = prepareExchangedData( |
1673
|
|
|
$post_data, |
1674
|
|
|
'decode' |
1675
|
|
|
); |
1676
|
|
|
|
1677
|
|
|
$post_action = filter_var($dataReceived['action'], FILTER_SANITIZE_FULL_SPECIAL_CHARS); |
1678
|
|
|
|
1679
|
|
|
// add new key |
1680
|
|
|
if (null !== $post_action && $post_action === 'add') { |
1681
|
|
|
$post_label = filter_var($dataReceived['label'], FILTER_SANITIZE_FULL_SPECIAL_CHARS); |
1682
|
|
|
$post_ip = filter_var($dataReceived['ip'], FILTER_SANITIZE_FULL_SPECIAL_CHARS); |
1683
|
|
|
|
1684
|
|
|
// Store in DB |
1685
|
|
|
DB::insert( |
1686
|
|
|
prefixTable('api'), |
1687
|
|
|
array( |
1688
|
|
|
'increment_id' => null, |
1689
|
|
|
'type' => 'ip', |
1690
|
|
|
'label' => $post_label, |
1691
|
|
|
'value' => $post_ip, |
1692
|
|
|
'timestamp' => time(), |
1693
|
|
|
) |
1694
|
|
|
); |
1695
|
|
|
|
1696
|
|
|
$post_id = DB::insertId(); |
1697
|
|
|
// Update existing key |
1698
|
|
|
} elseif (null !== $post_action && $post_action === 'update') { |
1699
|
|
|
$post_id = filter_var($dataReceived['id'], FILTER_SANITIZE_FULL_SPECIAL_CHARS); |
1700
|
|
|
$post_field = filter_var($dataReceived['field'], FILTER_SANITIZE_FULL_SPECIAL_CHARS); |
1701
|
|
|
$post_value = filter_var($dataReceived['value'], FILTER_SANITIZE_FULL_SPECIAL_CHARS); |
1702
|
|
|
if ($post_field === 'value') { |
1703
|
|
|
$arr = array( |
1704
|
|
|
'value' => $post_value, |
1705
|
|
|
'timestamp' => time(), |
1706
|
|
|
); |
1707
|
|
|
} else { |
1708
|
|
|
$arr = array( |
1709
|
|
|
'label' => $post_value, |
1710
|
|
|
'timestamp' => time(), |
1711
|
|
|
); |
1712
|
|
|
} |
1713
|
|
|
DB::update( |
1714
|
|
|
prefixTable('api'), |
1715
|
|
|
$arr, |
1716
|
|
|
'increment_id=%i', |
1717
|
|
|
$post_id |
1718
|
|
|
); |
1719
|
|
|
// Delete existing key |
1720
|
|
|
} elseif (null !== $post_action && $post_action === 'delete') { |
1721
|
|
|
$post_id = filter_var($dataReceived['id'], FILTER_SANITIZE_FULL_SPECIAL_CHARS); |
1722
|
|
|
DB::query('DELETE FROM ' . prefixTable('api') . ' WHERE increment_id=%i', $post_id); |
1723
|
|
|
} |
1724
|
|
|
|
1725
|
|
|
echo prepareExchangedData( |
1726
|
|
|
array( |
1727
|
|
|
'error' => false, |
1728
|
|
|
'message' => '', |
1729
|
|
|
'ipId' => $post_id, |
1730
|
|
|
), |
1731
|
|
|
'encode' |
1732
|
|
|
); |
1733
|
|
|
break; |
1734
|
|
|
|
1735
|
|
|
case 'save_api_status': |
1736
|
|
|
// Do query |
1737
|
|
|
DB::query('SELECT * FROM ' . prefixTable('misc') . ' WHERE type = %s AND intitule = %s', 'admin', 'api'); |
1738
|
|
|
$counter = DB::count(); |
1739
|
|
|
if ($counter === 0) { |
1740
|
|
|
DB::insert( |
1741
|
|
|
prefixTable('misc'), |
1742
|
|
|
array( |
1743
|
|
|
'type' => 'admin', |
1744
|
|
|
'intitule' => 'api', |
1745
|
|
|
'valeur' => $post_status, |
1746
|
|
|
'created_at' => time(), |
1747
|
|
|
) |
1748
|
|
|
); |
1749
|
|
|
} else { |
1750
|
|
|
DB::update( |
1751
|
|
|
prefixTable('misc'), |
1752
|
|
|
array( |
1753
|
|
|
'valeur' => $post_status, |
1754
|
|
|
'updated_at' => time(), |
1755
|
|
|
), |
1756
|
|
|
'type = %s AND intitule = %s', |
1757
|
|
|
'admin', |
1758
|
|
|
'api' |
1759
|
|
|
); |
1760
|
|
|
} |
1761
|
|
|
$SETTINGS['api'] = $post_status; |
1762
|
|
|
break; |
1763
|
|
|
|
1764
|
|
|
case 'run_duo_config_check': |
1765
|
|
|
//Libraries call |
1766
|
|
|
require_once $SETTINGS['cpassman_dir'] . '/sources/main.functions.php'; |
1767
|
|
|
// Check KEY |
1768
|
|
|
if ($post_key !== $session->get('key')) { |
1769
|
|
|
echo prepareExchangedData( |
1770
|
|
|
array( |
1771
|
|
|
'error' => true, |
1772
|
|
|
'message' => $lang->get('key_is_not_correct'), |
1773
|
|
|
), |
1774
|
|
|
'encode' |
1775
|
|
|
); |
1776
|
|
|
break; |
1777
|
|
|
} |
1778
|
|
|
|
1779
|
|
|
// decrypt and retreive data in JSON format |
1780
|
|
|
$dataReceived = prepareExchangedData( |
1781
|
|
|
$post_data, |
1782
|
|
|
'decode' |
1783
|
|
|
); |
1784
|
|
|
|
1785
|
|
|
// Check if we have what we need first |
1786
|
|
|
if (empty($dataReceived['duo_ikey']) || empty($dataReceived['duo_skey']) || empty($dataReceived['duo_host'])) { |
1787
|
|
|
echo prepareExchangedData( |
1788
|
|
|
array( |
1789
|
|
|
'error' => true, |
1790
|
|
|
'message' => $lang->get('data_are_missing'), |
1791
|
|
|
), |
1792
|
|
|
'encode' |
1793
|
|
|
); |
1794
|
|
|
break; |
1795
|
|
|
} |
1796
|
|
|
|
1797
|
|
|
// Run Duo Config Check |
1798
|
|
|
try { |
1799
|
|
|
$duo_client = new Client( |
1800
|
|
|
$dataReceived['duo_ikey'], |
1801
|
|
|
$dataReceived['duo_skey'], |
1802
|
|
|
$dataReceived['duo_host'], |
1803
|
|
|
$SETTINGS['cpassman_url'].'/'.DUO_CALLBACK |
1804
|
|
|
); |
1805
|
|
|
} catch (DuoException $e) { |
1806
|
|
|
if (defined('LOG_TO_SERVER') && LOG_TO_SERVER === true) { |
1807
|
|
|
error_log('TEAMPASS Error - duo config - '.$e->getMessage()); |
1808
|
|
|
} |
1809
|
|
|
// deepcode ignore ServerLeak: Data is encrypted before being sent |
1810
|
|
|
echo prepareExchangedData( |
1811
|
|
|
array( |
1812
|
|
|
'error' => true, |
1813
|
|
|
'message' => $lang->get('duo_config_error'), |
1814
|
|
|
), |
1815
|
|
|
'encode' |
1816
|
|
|
); |
1817
|
|
|
break; |
1818
|
|
|
} |
1819
|
|
|
|
1820
|
|
|
// Run healthcheck against Duo with the config |
1821
|
|
|
try { |
1822
|
|
|
$duo_client->healthCheck(); |
1823
|
|
|
} catch (DuoException $e) { |
1824
|
|
|
if (defined('LOG_TO_SERVER') && LOG_TO_SERVER === true) { |
1825
|
|
|
error_log('TEAMPASS Error - duo config - '.$e->getMessage()); |
1826
|
|
|
} |
1827
|
|
|
// deepcode ignore ServerLeak: Data is encrypted before being sent |
1828
|
|
|
echo prepareExchangedData( |
1829
|
|
|
array( |
1830
|
|
|
'error' => true, |
1831
|
|
|
'message' => $lang->get('duo_error_check_config'), |
1832
|
|
|
), |
1833
|
|
|
'encode' |
1834
|
|
|
); |
1835
|
|
|
break; |
1836
|
|
|
} |
1837
|
|
|
|
1838
|
|
|
// send data |
1839
|
|
|
echo prepareExchangedData( |
1840
|
|
|
array( |
1841
|
|
|
'error' => false, |
1842
|
|
|
'message' => '', |
1843
|
|
|
), |
1844
|
|
|
'encode' |
1845
|
|
|
); |
1846
|
|
|
break; |
1847
|
|
|
|
1848
|
|
|
case 'save_google_options': |
1849
|
|
|
// Check KEY and rights |
1850
|
|
|
if ($post_key !== $session->get('key')) { |
1851
|
|
|
echo prepareExchangedData( |
1852
|
|
|
array( |
1853
|
|
|
'error' => true, |
1854
|
|
|
'message' => $lang->get('key_is_not_correct'), |
1855
|
|
|
), |
1856
|
|
|
'encode' |
1857
|
|
|
); |
1858
|
|
|
break; |
1859
|
|
|
} |
1860
|
|
|
// decrypt and retreive data in JSON format |
1861
|
|
|
$dataReceived = prepareExchangedData( |
1862
|
|
|
$post_data, |
1863
|
|
|
'decode' |
1864
|
|
|
); |
1865
|
|
|
|
1866
|
|
|
// Google Authentication |
1867
|
|
|
if (htmlspecialchars_decode($dataReceived['google_authentication']) === 'false') { |
1868
|
|
|
$tmp = 0; |
1869
|
|
|
} else { |
1870
|
|
|
$tmp = 1; |
1871
|
|
|
} |
1872
|
|
|
DB::query('SELECT * FROM ' . prefixTable('misc') . ' WHERE type = %s AND intitule = %s', 'admin', 'google_authentication'); |
1873
|
|
|
$counter = DB::count(); |
1874
|
|
|
if ($counter === 0) { |
1875
|
|
|
DB::insert( |
1876
|
|
|
prefixTable('misc'), |
1877
|
|
|
array( |
1878
|
|
|
'type' => 'admin', |
1879
|
|
|
'intitule' => 'google_authentication', |
1880
|
|
|
'valeur' => $tmp, |
1881
|
|
|
'created_at' => time(), |
1882
|
|
|
) |
1883
|
|
|
); |
1884
|
|
|
} else { |
1885
|
|
|
DB::update( |
1886
|
|
|
prefixTable('misc'), |
1887
|
|
|
array( |
1888
|
|
|
'valeur' => $tmp, |
1889
|
|
|
'updated_at' => time(), |
1890
|
|
|
), |
1891
|
|
|
'type = %s AND intitule = %s', |
1892
|
|
|
'admin', |
1893
|
|
|
'google_authentication' |
1894
|
|
|
); |
1895
|
|
|
} |
1896
|
|
|
$SETTINGS['google_authentication'] = htmlspecialchars_decode($dataReceived['google_authentication']); |
1897
|
|
|
|
1898
|
|
|
// ga_website_name |
1899
|
|
|
if (is_null($dataReceived['ga_website_name']) === false) { |
1900
|
|
|
DB::query('SELECT * FROM ' . prefixTable('misc') . ' WHERE type = %s AND intitule = %s', 'admin', 'ga_website_name'); |
1901
|
|
|
$counter = DB::count(); |
1902
|
|
|
if ($counter === 0) { |
1903
|
|
|
DB::insert( |
1904
|
|
|
prefixTable('misc'), |
1905
|
|
|
array( |
1906
|
|
|
'type' => 'admin', |
1907
|
|
|
'intitule' => 'ga_website_name', |
1908
|
|
|
'valeur' => htmlspecialchars_decode($dataReceived['ga_website_name']), |
1909
|
|
|
'created_at' => time(), |
1910
|
|
|
) |
1911
|
|
|
); |
1912
|
|
|
} else { |
1913
|
|
|
DB::update( |
1914
|
|
|
prefixTable('misc'), |
1915
|
|
|
array( |
1916
|
|
|
'valeur' => htmlspecialchars_decode($dataReceived['ga_website_name']), |
1917
|
|
|
'updated_at' => time(), |
1918
|
|
|
), |
1919
|
|
|
'type = %s AND intitule = %s', |
1920
|
|
|
'admin', |
1921
|
|
|
'ga_website_name' |
1922
|
|
|
); |
1923
|
|
|
} |
1924
|
|
|
$SETTINGS['ga_website_name'] = htmlspecialchars_decode($dataReceived['ga_website_name']); |
1925
|
|
|
} else { |
1926
|
|
|
$SETTINGS['ga_website_name'] = ''; |
1927
|
|
|
} |
1928
|
|
|
|
1929
|
|
|
// send data |
1930
|
|
|
echo '[{"result" : "' . addslashes($lang['done']) . '" , "error" : ""}]'; |
1931
|
|
|
break; |
1932
|
|
|
|
1933
|
|
|
case 'save_agses_options': |
1934
|
|
|
// Check KEY and rights |
1935
|
|
|
if ($post_key !== $session->get('key')) { |
1936
|
|
|
echo prepareExchangedData( |
1937
|
|
|
array( |
1938
|
|
|
'error' => true, |
1939
|
|
|
'message' => $lang->get('key_is_not_correct'), |
1940
|
|
|
), |
1941
|
|
|
'encode' |
1942
|
|
|
); |
1943
|
|
|
break; |
1944
|
|
|
} |
1945
|
|
|
// decrypt and retreive data in JSON format |
1946
|
|
|
$dataReceived = prepareExchangedData( |
1947
|
|
|
$post_data, |
1948
|
|
|
'decode' |
1949
|
|
|
); |
1950
|
|
|
|
1951
|
|
|
// agses_hosted_url |
1952
|
|
|
if (!is_null($dataReceived['agses_hosted_url'])) { |
1953
|
|
|
DB::query('SELECT * FROM ' . prefixTable('misc') . ' WHERE type = %s AND intitule = %s', 'admin', 'agses_hosted_url'); |
1954
|
|
|
$counter = DB::count(); |
1955
|
|
|
if ($counter === 0) { |
1956
|
|
|
DB::insert( |
1957
|
|
|
prefixTable('misc'), |
1958
|
|
|
array( |
1959
|
|
|
'type' => 'admin', |
1960
|
|
|
'intitule' => 'agses_hosted_url', |
1961
|
|
|
'valeur' => htmlspecialchars_decode($dataReceived['agses_hosted_url']), |
1962
|
|
|
'created_at' => time(), |
1963
|
|
|
) |
1964
|
|
|
); |
1965
|
|
|
} else { |
1966
|
|
|
DB::update( |
1967
|
|
|
prefixTable('misc'), |
1968
|
|
|
array( |
1969
|
|
|
'valeur' => htmlspecialchars_decode($dataReceived['agses_hosted_url']), |
1970
|
|
|
'updated_at' => time(), |
1971
|
|
|
), |
1972
|
|
|
'type = %s AND intitule = %s', |
1973
|
|
|
'admin', |
1974
|
|
|
'agses_hosted_url' |
1975
|
|
|
); |
1976
|
|
|
} |
1977
|
|
|
$SETTINGS['agses_hosted_url'] = htmlspecialchars_decode($dataReceived['agses_hosted_url']); |
1978
|
|
|
} else { |
1979
|
|
|
$SETTINGS['agses_hosted_url'] = ''; |
1980
|
|
|
} |
1981
|
|
|
|
1982
|
|
|
// agses_hosted_id |
1983
|
|
|
if (!is_null($dataReceived['agses_hosted_id'])) { |
1984
|
|
|
DB::query('SELECT * FROM ' . prefixTable('misc') . ' WHERE type = %s AND intitule = %s', 'admin', 'agses_hosted_id'); |
1985
|
|
|
$counter = DB::count(); |
1986
|
|
|
if ($counter === 0) { |
1987
|
|
|
DB::insert( |
1988
|
|
|
prefixTable('misc'), |
1989
|
|
|
array( |
1990
|
|
|
'type' => 'admin', |
1991
|
|
|
'intitule' => 'agses_hosted_id', |
1992
|
|
|
'valeur' => htmlspecialchars_decode($dataReceived['agses_hosted_id']), |
1993
|
|
|
'created_at' => time(), |
1994
|
|
|
) |
1995
|
|
|
); |
1996
|
|
|
} else { |
1997
|
|
|
DB::update( |
1998
|
|
|
prefixTable('misc'), |
1999
|
|
|
array( |
2000
|
|
|
'valeur' => htmlspecialchars_decode($dataReceived['agses_hosted_id']), |
2001
|
|
|
'updated_at' => time(), |
2002
|
|
|
), |
2003
|
|
|
'type = %s AND intitule = %s', |
2004
|
|
|
'admin', |
2005
|
|
|
'agses_hosted_id' |
2006
|
|
|
); |
2007
|
|
|
} |
2008
|
|
|
$SETTINGS['agses_hosted_id'] = htmlspecialchars_decode($dataReceived['agses_hosted_id']); |
2009
|
|
|
} else { |
2010
|
|
|
$SETTINGS['agses_hosted_id'] = ''; |
2011
|
|
|
} |
2012
|
|
|
|
2013
|
|
|
// agses_hosted_apikey |
2014
|
|
|
if (!is_null($dataReceived['agses_hosted_apikey'])) { |
2015
|
|
|
DB::query('SELECT * FROM ' . prefixTable('misc') . ' WHERE type = %s AND intitule = %s', 'admin', 'agses_hosted_apikey'); |
2016
|
|
|
$counter = DB::count(); |
2017
|
|
|
if ($counter === 0) { |
2018
|
|
|
DB::insert( |
2019
|
|
|
prefixTable('misc'), |
2020
|
|
|
array( |
2021
|
|
|
'type' => 'admin', |
2022
|
|
|
'intitule' => 'agses_hosted_apikey', |
2023
|
|
|
'valeur' => htmlspecialchars_decode($dataReceived['agses_hosted_apikey']), |
2024
|
|
|
'created_at' => time(), |
2025
|
|
|
) |
2026
|
|
|
); |
2027
|
|
|
} else { |
2028
|
|
|
DB::update( |
2029
|
|
|
prefixTable('misc'), |
2030
|
|
|
array( |
2031
|
|
|
'valeur' => htmlspecialchars_decode($dataReceived['agses_hosted_apikey']), |
2032
|
|
|
'updated_at' => time(), |
2033
|
|
|
), |
2034
|
|
|
'type = %s AND intitule = %s', |
2035
|
|
|
'admin', |
2036
|
|
|
'agses_hosted_apikey' |
2037
|
|
|
); |
2038
|
|
|
} |
2039
|
|
|
$SETTINGS['agses_hosted_apikey'] = htmlspecialchars_decode($dataReceived['agses_hosted_apikey']); |
2040
|
|
|
} else { |
2041
|
|
|
$SETTINGS['agses_hosted_apikey'] = ''; |
2042
|
|
|
} |
2043
|
|
|
|
2044
|
|
|
// send data |
2045
|
|
|
echo '[{"result" : "' . addslashes($lang['done']) . '" , "error" : ""}]'; |
2046
|
|
|
break; |
2047
|
|
|
|
2048
|
|
|
case 'save_option_change': |
2049
|
|
|
// Check KEY and rights |
2050
|
|
|
if ($post_key !== $session->get('key')) { |
2051
|
|
|
echo prepareExchangedData( |
2052
|
|
|
array( |
2053
|
|
|
'error' => true, |
2054
|
|
|
'message' => $lang->get('key_is_not_correct'), |
2055
|
|
|
), |
2056
|
|
|
'encode' |
2057
|
|
|
); |
2058
|
|
|
break; |
2059
|
|
|
} |
2060
|
|
|
// decrypt and retreive data in JSON format |
2061
|
|
|
$dataReceived = prepareExchangedData( |
2062
|
|
|
$post_data, |
2063
|
|
|
'decode' |
2064
|
|
|
); |
2065
|
|
|
|
2066
|
|
|
// prepare data |
2067
|
|
|
$post_value = filter_var($dataReceived['value'], FILTER_SANITIZE_FULL_SPECIAL_CHARS); |
2068
|
|
|
$post_field = filter_var($dataReceived['field'], FILTER_SANITIZE_FULL_SPECIAL_CHARS); |
2069
|
|
|
$post_translate = isset($dataReceived['translate']) === true ? filter_var($dataReceived['translate'], FILTER_SANITIZE_FULL_SPECIAL_CHARS) : ''; |
2070
|
|
|
|
2071
|
|
|
require_once 'main.functions.php'; |
2072
|
|
|
|
2073
|
|
|
// In case of key, then encrypt it |
2074
|
|
|
if ($post_field === 'bck_script_passkey') { |
2075
|
|
|
$post_value = cryption( |
2076
|
|
|
$post_value, |
2077
|
|
|
'', |
2078
|
|
|
'encrypt', |
2079
|
|
|
$SETTINGS |
2080
|
|
|
)['string']; |
2081
|
|
|
} |
2082
|
|
|
|
2083
|
|
|
// Check if setting is already in DB. If NO then insert, if YES then update. |
2084
|
|
|
$data = DB::query( |
2085
|
|
|
'SELECT * FROM ' . prefixTable('misc') . ' |
2086
|
|
|
WHERE type = %s AND intitule = %s', |
2087
|
|
|
'admin', |
2088
|
|
|
$post_field |
2089
|
|
|
); |
2090
|
|
|
$counter = DB::count(); |
2091
|
|
|
if ($counter === 0) { |
2092
|
|
|
DB::insert( |
2093
|
|
|
prefixTable('misc'), |
2094
|
|
|
array( |
2095
|
|
|
'valeur' => $post_value, |
2096
|
|
|
'type' => 'admin', |
2097
|
|
|
'intitule' => $post_field, |
2098
|
|
|
'created_at' => time(), |
2099
|
|
|
) |
2100
|
|
|
); |
2101
|
|
|
// in case of stats enabled, add the actual time |
2102
|
|
|
if ($post_field === 'send_stats') { |
2103
|
|
|
DB::insert( |
2104
|
|
|
prefixTable('misc'), |
2105
|
|
|
array( |
2106
|
|
|
'valeur' => time(), |
2107
|
|
|
'type' => 'admin', |
2108
|
|
|
'intitule' => $post_field . '_time', |
2109
|
|
|
'updated_at' => time(), |
2110
|
|
|
) |
2111
|
|
|
); |
2112
|
|
|
} |
2113
|
|
|
} else { |
2114
|
|
|
// Update DB settings |
2115
|
|
|
DB::update( |
2116
|
|
|
prefixTable('misc'), |
2117
|
|
|
array( |
2118
|
|
|
'valeur' => $post_value, |
2119
|
|
|
'updated_at' => time(), |
2120
|
|
|
), |
2121
|
|
|
'type = %s AND intitule = %s', |
2122
|
|
|
'admin', |
2123
|
|
|
$post_field |
2124
|
|
|
); |
2125
|
|
|
|
2126
|
|
|
// in case of stats enabled, update the actual time |
2127
|
|
|
if ($post_field === 'send_stats') { |
2128
|
|
|
// Check if previous time exists, if not them insert this value in DB |
2129
|
|
|
DB::query( |
2130
|
|
|
'SELECT * FROM ' . prefixTable('misc') . ' |
2131
|
|
|
WHERE type = %s AND intitule = %s', |
2132
|
|
|
'admin', |
2133
|
|
|
$post_field . '_time' |
2134
|
|
|
); |
2135
|
|
|
$counter = DB::count(); |
2136
|
|
|
if ($counter === 0) { |
2137
|
|
|
DB::insert( |
2138
|
|
|
prefixTable('misc'), |
2139
|
|
|
array( |
2140
|
|
|
'valeur' => 0, |
2141
|
|
|
'type' => 'admin', |
2142
|
|
|
'intitule' => $post_field . '_time', |
2143
|
|
|
'created_at' => time(), |
2144
|
|
|
) |
2145
|
|
|
); |
2146
|
|
|
} else { |
2147
|
|
|
DB::update( |
2148
|
|
|
prefixTable('misc'), |
2149
|
|
|
array( |
2150
|
|
|
'valeur' => 0, |
2151
|
|
|
'updated_at' => time(), |
2152
|
|
|
), |
2153
|
|
|
'type = %s AND intitule = %s', |
2154
|
|
|
'admin', |
2155
|
|
|
$post_field |
2156
|
|
|
); |
2157
|
|
|
} |
2158
|
|
|
} |
2159
|
|
|
} |
2160
|
|
|
|
2161
|
|
|
// special Cases |
2162
|
|
|
if ($post_field === 'cpassman_url') { |
2163
|
|
|
// update also jsUrl for CSFP protection |
2164
|
|
|
$jsUrl = $post_value . '/includes/libraries/csrfp/js/csrfprotector.js'; |
2165
|
|
|
$csrfp_file = '../includes/libraries/csrfp/libs/csrfp.config.php'; |
2166
|
|
|
$data = file_get_contents($csrfp_file); |
2167
|
|
|
$posJsUrl = strpos($data, '"jsUrl" => "'); |
2168
|
|
|
$posEndLine = strpos($data, '",', $posJsUrl); |
2169
|
|
|
$line = substr($data, $posJsUrl, ($posEndLine - $posJsUrl + 2)); |
2170
|
|
|
$newdata = str_replace($line, '"jsUrl" => "' . filter_var($jsUrl, FILTER_SANITIZE_FULL_SPECIAL_CHARS) . '",', $data); |
2171
|
|
|
file_put_contents($csrfp_file, $newdata); |
2172
|
|
|
} elseif ($post_field === 'restricted_to_input' && (int) $post_value === 0) { |
2173
|
|
|
DB::update( |
2174
|
|
|
prefixTable('misc'), |
2175
|
|
|
array( |
2176
|
|
|
'valeur' => 0, |
2177
|
|
|
'updated_at' => time(), |
2178
|
|
|
), |
2179
|
|
|
'type = %s AND intitule = %s', |
2180
|
|
|
'admin', |
2181
|
|
|
'restricted_to_roles' |
2182
|
|
|
); |
2183
|
|
|
} |
2184
|
|
|
|
2185
|
|
|
// Avoid break tp.config.php file with ' in parameter. |
2186
|
|
|
$dataReceived['value'] = addslashes((string) $dataReceived['value']); |
2187
|
|
|
|
2188
|
|
|
// store in SESSION |
2189
|
|
|
$SETTINGS[$post_field] = $post_value; |
2190
|
|
|
|
2191
|
|
|
// Encrypt data to return |
2192
|
|
|
echo prepareExchangedData( |
2193
|
|
|
array( |
2194
|
|
|
'error' => false, |
2195
|
|
|
'misc' => $counter . ' ; ' . $SETTINGS[$post_field], |
2196
|
|
|
'message' => empty($post_translate) === false ? $lang->get($post_translate) : '', |
2197
|
|
|
), |
2198
|
|
|
'encode' |
2199
|
|
|
); |
2200
|
|
|
break; |
2201
|
|
|
|
2202
|
|
|
case 'get_values_for_statistics': |
2203
|
|
|
// Check KEY and rights |
2204
|
|
|
if ($post_key !== $session->get('key')) { |
2205
|
|
|
echo prepareExchangedData( |
2206
|
|
|
array( |
2207
|
|
|
'error' => true, |
2208
|
|
|
'message' => $lang->get('key_is_not_correct'), |
2209
|
|
|
), |
2210
|
|
|
'encode' |
2211
|
|
|
); |
2212
|
|
|
break; |
2213
|
|
|
} |
2214
|
|
|
|
2215
|
|
|
// Encrypt data to return |
2216
|
|
|
echo prepareExchangedData( |
2217
|
|
|
getStatisticsData($SETTINGS), |
2218
|
|
|
'encode' |
2219
|
|
|
); |
2220
|
|
|
|
2221
|
|
|
break; |
2222
|
|
|
|
2223
|
|
|
case 'save_sending_statistics': |
2224
|
|
|
// Check KEY and rights |
2225
|
|
|
if ($post_key !== $session->get('key')) { |
2226
|
|
|
echo prepareExchangedData( |
2227
|
|
|
array( |
2228
|
|
|
'error' => true, |
2229
|
|
|
'message' => $lang->get('key_is_not_correct'), |
2230
|
|
|
), |
2231
|
|
|
'encode' |
2232
|
|
|
); |
2233
|
|
|
break; |
2234
|
|
|
} |
2235
|
|
|
|
2236
|
|
|
// send statistics |
2237
|
|
|
if (null !== $post_status) { |
2238
|
|
|
DB::query('SELECT * FROM ' . prefixTable('misc') . ' WHERE type = %s AND intitule = %s', 'admin', 'send_stats'); |
2239
|
|
|
$counter = DB::count(); |
2240
|
|
|
if ($counter === 0) { |
2241
|
|
|
DB::insert( |
2242
|
|
|
prefixTable('misc'), |
2243
|
|
|
array( |
2244
|
|
|
'type' => 'admin', |
2245
|
|
|
'intitule' => 'send_stats', |
2246
|
|
|
'valeur' => $post_status, |
2247
|
|
|
'created_at' => time(), |
2248
|
|
|
) |
2249
|
|
|
); |
2250
|
|
|
} else { |
2251
|
|
|
DB::update( |
2252
|
|
|
prefixTable('misc'), |
2253
|
|
|
array( |
2254
|
|
|
'valeur' => $post_status, |
2255
|
|
|
'updated_at' => time(), |
2256
|
|
|
), |
2257
|
|
|
'type = %s AND intitule = %s', |
2258
|
|
|
'admin', |
2259
|
|
|
'send_stats' |
2260
|
|
|
); |
2261
|
|
|
} |
2262
|
|
|
$SETTINGS['send_stats'] = $post_status; |
2263
|
|
|
} else { |
2264
|
|
|
$SETTINGS['send_stats'] = '0'; |
2265
|
|
|
} |
2266
|
|
|
|
2267
|
|
|
// send statistics items |
2268
|
|
|
if (null !== $post_list) { |
2269
|
|
|
DB::query('SELECT * FROM ' . prefixTable('misc') . ' WHERE type = %s AND intitule = %s', 'admin', 'send_statistics_items'); |
2270
|
|
|
$counter = DB::count(); |
2271
|
|
|
if ($counter === 0) { |
2272
|
|
|
DB::insert( |
2273
|
|
|
prefixTable('misc'), |
2274
|
|
|
array( |
2275
|
|
|
'type' => 'admin', |
2276
|
|
|
'intitule' => 'send_statistics_items', |
2277
|
|
|
'valeur' => $post_list, |
2278
|
|
|
'created_at' => time(), |
2279
|
|
|
) |
2280
|
|
|
); |
2281
|
|
|
} else { |
2282
|
|
|
DB::update( |
2283
|
|
|
prefixTable('misc'), |
2284
|
|
|
array( |
2285
|
|
|
'valeur' => $post_list, |
2286
|
|
|
'updated_at' => time(), |
2287
|
|
|
), |
2288
|
|
|
'type = %s AND intitule = %s', |
2289
|
|
|
'admin', |
2290
|
|
|
'send_statistics_items' |
2291
|
|
|
); |
2292
|
|
|
} |
2293
|
|
|
$SETTINGS['send_statistics_items'] = $post_list; |
2294
|
|
|
} else { |
2295
|
|
|
$SETTINGS['send_statistics_items'] = ''; |
2296
|
|
|
} |
2297
|
|
|
|
2298
|
|
|
// send data |
2299
|
|
|
echo '[{"error" : false}]'; |
2300
|
|
|
break; |
2301
|
|
|
|
2302
|
|
|
case 'is_backup_table_existing': |
2303
|
|
|
// Check KEY and rights |
2304
|
|
|
if ($post_key !== $session->get('key')) { |
2305
|
|
|
echo prepareExchangedData( |
2306
|
|
|
array( |
2307
|
|
|
'error' => true, |
2308
|
|
|
'message' => $lang->get('key_is_not_correct'), |
2309
|
|
|
), |
2310
|
|
|
'encode' |
2311
|
|
|
); |
2312
|
|
|
break; |
2313
|
|
|
} |
2314
|
|
|
|
2315
|
|
|
if (DB::query("SHOW TABLES LIKE '" . prefixTable('sk_reencrypt_backup') . "'")) { |
2316
|
|
|
if (DB::count() === 1) { |
2317
|
|
|
echo 1; |
2318
|
|
|
} else { |
2319
|
|
|
echo 0; |
2320
|
|
|
} |
2321
|
|
|
} else { |
2322
|
|
|
echo 0; |
2323
|
|
|
} |
2324
|
|
|
|
2325
|
|
|
break; |
2326
|
|
|
|
2327
|
|
|
case 'get_list_of_roles': |
2328
|
|
|
// Check KEY and rights |
2329
|
|
|
if ($post_key !== $session->get('key')) { |
2330
|
|
|
echo prepareExchangedData( |
2331
|
|
|
array( |
2332
|
|
|
'error' => true, |
2333
|
|
|
'message' => $lang->get('key_is_not_correct'), |
2334
|
|
|
), |
2335
|
|
|
'encode' |
2336
|
|
|
); |
2337
|
|
|
break; |
2338
|
|
|
} |
2339
|
|
|
|
2340
|
|
|
// decrypt and retreive data in JSON format |
2341
|
|
|
$dataReceived = prepareExchangedData( |
2342
|
|
|
$post_data, |
2343
|
|
|
'decode' |
2344
|
|
|
); |
2345
|
|
|
|
2346
|
|
|
// prepare data |
2347
|
|
|
$sourcePage = filter_var($dataReceived['source_page'], FILTER_SANITIZE_FULL_SPECIAL_CHARS); |
2348
|
|
|
if ($sourcePage === 'ldap') { |
2349
|
|
|
$selected_administrated_by = isset($SETTINGS['ldap_new_user_is_administrated_by']) && $SETTINGS['ldap_new_user_is_administrated_by'] === '0' ? 1 : 0; |
2350
|
|
|
$selected_new_user_role = isset($SETTINGS['ldap_new_user_role']) && $SETTINGS['ldap_new_user_role'] === '0' ? 1 : 0; |
2351
|
|
|
} elseif ($sourcePage === 'oauth') { |
2352
|
|
|
$selected_administrated_by = isset($SETTINGS['oauth_new_user_is_administrated_by']) && $SETTINGS['oauth_new_user_is_administrated_by'] === '0' ? 1 : 0; |
2353
|
|
|
$selected_new_user_role = isset($SETTINGS['oauth_selfregistered_user_belongs_to_role']) && $SETTINGS['oauth_selfregistered_user_belongs_to_role'] === '0' ? 1 : ''; |
2354
|
|
|
} else { |
2355
|
|
|
echo prepareExchangedData( |
2356
|
|
|
[], |
2357
|
|
|
'encode' |
2358
|
|
|
); |
2359
|
|
|
|
2360
|
|
|
break; |
2361
|
|
|
} |
2362
|
|
|
|
2363
|
|
|
$json = array(); |
2364
|
|
|
array_push( |
2365
|
|
|
$json, |
2366
|
|
|
array( |
2367
|
|
|
'id' => '0', |
2368
|
|
|
'title' => $lang->get('god'), |
2369
|
|
|
'selected_administrated_by' => $selected_administrated_by, |
2370
|
|
|
'selected_role' => $selected_new_user_role, |
2371
|
|
|
) |
2372
|
|
|
); |
2373
|
|
|
|
2374
|
|
|
$rows = DB::query( |
2375
|
|
|
'SELECT id, title |
2376
|
|
|
FROM ' . prefixTable('roles_title') . ' |
2377
|
|
|
ORDER BY title ASC' |
2378
|
|
|
); |
2379
|
|
|
foreach ($rows as $record) { |
2380
|
|
|
if ($sourcePage === 'ldap') { |
2381
|
|
|
$selected_administrated_by = isset($SETTINGS['ldap_new_user_is_administrated_by']) && $SETTINGS['ldap_new_user_is_administrated_by'] === $record['id'] ? 1 : 0; |
2382
|
|
|
$selected_new_user_role = isset($SETTINGS['ldap_new_user_role']) && $SETTINGS['ldap_new_user_role'] === $record['id'] ? 1 : 0; |
2383
|
|
|
} elseif ($sourcePage === 'oauth') { |
2384
|
|
|
$selected_administrated_by = isset($SETTINGS['oauth_new_user_is_administrated_by']) && $SETTINGS['oauth_new_user_is_administrated_by'] === $record['id'] ? 1 : 0; |
2385
|
|
|
$selected_new_user_role = isset($SETTINGS['oauth_selfregistered_user_belongs_to_role']) && $SETTINGS['oauth_selfregistered_user_belongs_to_role'] === $record['id'] ? 1 : 0; |
2386
|
|
|
} |
2387
|
|
|
array_push( |
2388
|
|
|
$json, |
2389
|
|
|
array( |
2390
|
|
|
'id' => $record['id'], |
2391
|
|
|
'title' => addslashes($record['title']), |
2392
|
|
|
'selected_administrated_by' => $selected_administrated_by, |
2393
|
|
|
'selected_role' => $selected_new_user_role, |
2394
|
|
|
) |
2395
|
|
|
); |
2396
|
|
|
} |
2397
|
|
|
|
2398
|
|
|
echo prepareExchangedData( |
2399
|
|
|
$json, |
2400
|
|
|
'encode' |
2401
|
|
|
); |
2402
|
|
|
|
2403
|
|
|
break; |
2404
|
|
|
|
2405
|
|
|
case 'save_user_change': |
2406
|
|
|
// Check KEY and rights |
2407
|
|
|
if ($post_key !== $session->get('key')) { |
2408
|
|
|
echo prepareExchangedData( |
2409
|
|
|
array( |
2410
|
|
|
'error' => true, |
2411
|
|
|
'message' => $lang->get('key_is_not_correct'), |
2412
|
|
|
), |
2413
|
|
|
'encode' |
2414
|
|
|
); |
2415
|
|
|
break; |
2416
|
|
|
} |
2417
|
|
|
|
2418
|
|
|
// decrypt and retrieve data in JSON format |
2419
|
|
|
$dataReceived = prepareExchangedData( |
2420
|
|
|
$post_data, |
2421
|
|
|
'decode' |
2422
|
|
|
); |
2423
|
|
|
|
2424
|
|
|
$post_increment_id = isset($dataReceived['increment_id']) === true ? filter_var($dataReceived['increment_id'], FILTER_SANITIZE_NUMBER_INT) : ''; |
2425
|
|
|
$post_field = filter_var($dataReceived['field'], FILTER_SANITIZE_FULL_SPECIAL_CHARS); |
2426
|
|
|
$post_value = filter_var($dataReceived['value'], FILTER_SANITIZE_FULL_SPECIAL_CHARS); |
2427
|
|
|
|
2428
|
|
|
if (is_numeric($post_increment_id) === false) { |
2429
|
|
|
echo prepareExchangedData( |
2430
|
|
|
array( |
2431
|
|
|
'error' => true, |
2432
|
|
|
'message' => $lang->get('no_user'), |
2433
|
|
|
), |
2434
|
|
|
'encode' |
2435
|
|
|
); |
2436
|
|
|
break; |
2437
|
|
|
} |
2438
|
|
|
|
2439
|
|
|
//update. |
2440
|
|
|
DB::debugMode(false); |
2441
|
|
|
DB::update( |
2442
|
|
|
prefixTable('api'), |
2443
|
|
|
array( |
2444
|
|
|
$post_field => $post_value, |
2445
|
|
|
), |
2446
|
|
|
'increment_id = %i', |
2447
|
|
|
(int) $post_increment_id |
2448
|
|
|
); |
2449
|
|
|
DB::debugMode(false); |
2450
|
|
|
//log |
2451
|
|
|
logEvents($SETTINGS, 'system', 'api_user_readonly', (string) $session->get('user-id'), $session->get('user-login')); |
2452
|
|
|
|
2453
|
|
|
echo prepareExchangedData( |
2454
|
|
|
array( |
2455
|
|
|
'error' => false, |
2456
|
|
|
'message' => '', |
2457
|
|
|
), |
2458
|
|
|
'encode' |
2459
|
|
|
); |
2460
|
|
|
|
2461
|
|
|
break; |
2462
|
|
|
|
2463
|
|
|
case "tablesIntegrityCheck": |
2464
|
|
|
// Check KEY and rights |
2465
|
|
|
if ($post_key !== $session->get('key')) { |
2466
|
|
|
echo prepareExchangedData( |
2467
|
|
|
array( |
2468
|
|
|
'error' => true, |
2469
|
|
|
'message' => $lang->get('key_is_not_correct'), |
2470
|
|
|
), |
2471
|
|
|
'encode' |
2472
|
|
|
); |
2473
|
|
|
break; |
2474
|
|
|
} |
2475
|
|
|
|
2476
|
|
|
$ret = tablesIntegrityCheck(); |
2477
|
|
|
|
2478
|
|
|
echo prepareExchangedData( |
2479
|
|
|
array( |
2480
|
|
|
'error' => $ret['error'], |
2481
|
|
|
'message' => $ret['message'], |
2482
|
|
|
'tables' => json_encode($ret['array'], JSON_FORCE_OBJECT), |
2483
|
|
|
), |
2484
|
|
|
'encode' |
2485
|
|
|
); |
2486
|
|
|
|
2487
|
|
|
break; |
2488
|
|
|
|
2489
|
|
|
case "filesIntegrityCheck": |
2490
|
|
|
// Check KEY and rights |
2491
|
|
|
if ($post_key !== $session->get('key')) { |
2492
|
|
|
echo prepareExchangedData( |
2493
|
|
|
array( |
2494
|
|
|
'error' => true, |
2495
|
|
|
'message' => $lang->get('key_is_not_correct'), |
2496
|
|
|
), |
2497
|
|
|
'encode' |
2498
|
|
|
); |
2499
|
|
|
break; |
2500
|
|
|
} |
2501
|
|
|
|
2502
|
|
|
$ret = filesIntegrityCheck($SETTINGS['cpassman_dir']); |
2503
|
|
|
|
2504
|
|
|
$ignoredFiles = DB::queryFirstField( |
2505
|
|
|
'SELECT valeur |
2506
|
|
|
FROM ' . prefixTable('misc') . ' |
2507
|
|
|
WHERE type = %s AND intitule = %s', |
2508
|
|
|
'admin', |
2509
|
|
|
'ignored_unknown_files' |
2510
|
|
|
); |
2511
|
|
|
$ignoredFilesKeys = !is_null($ignoredFiles) && !empty($ignoredFiles) ? json_decode($ignoredFiles) : []; |
2512
|
|
|
|
2513
|
|
|
echo prepareExchangedData( |
2514
|
|
|
array( |
2515
|
|
|
'error' => $ret['error'], |
2516
|
|
|
'message' => $ret['message'], |
2517
|
|
|
'files' => json_encode($ret['array'], JSON_FORCE_OBJECT), |
2518
|
|
|
'ignoredNumber' => count($ignoredFilesKeys), |
2519
|
|
|
), |
2520
|
|
|
'encode' |
2521
|
|
|
); |
2522
|
|
|
|
2523
|
|
|
break; |
2524
|
|
|
|
2525
|
|
|
case "ignoreFile": |
2526
|
|
|
// Check KEY and rights |
2527
|
|
|
if ($post_key !== $session->get('key')) { |
2528
|
|
|
echo prepareExchangedData( |
2529
|
|
|
array( |
2530
|
|
|
'error' => true, |
2531
|
|
|
'message' => $lang->get('key_is_not_correct'), |
2532
|
|
|
), |
2533
|
|
|
'encode' |
2534
|
|
|
); |
2535
|
|
|
break; |
2536
|
|
|
} |
2537
|
|
|
|
2538
|
|
|
// decrypt and retrieve data in JSON format |
2539
|
|
|
$dataReceived = prepareExchangedData( |
2540
|
|
|
$post_data, |
2541
|
|
|
'decode' |
2542
|
|
|
); |
2543
|
|
|
|
2544
|
|
|
$post_id = isset($dataReceived['id']) === true ? filter_var($dataReceived['id'], FILTER_SANITIZE_NUMBER_INT) : ''; |
2545
|
|
|
|
2546
|
|
|
// Get ignored unknown files |
2547
|
|
|
$existingData = DB::queryFirstRow( |
2548
|
|
|
'SELECT valeur |
2549
|
|
|
FROM ' . prefixTable('misc') . ' |
2550
|
|
|
WHERE type = %s AND intitule = %s', |
2551
|
|
|
'admin', |
2552
|
|
|
'ignored_unknown_files' |
2553
|
|
|
); |
2554
|
|
|
|
2555
|
|
|
// Get the json list ignored unknown files |
2556
|
|
|
$unknownFilesArray = []; |
2557
|
|
|
if (!empty($existingData) && !empty($existingData['valeur'])) { |
2558
|
|
|
$unknownFilesArray = json_decode($existingData['valeur'], true) ?: []; |
2559
|
|
|
} |
2560
|
|
|
|
2561
|
|
|
// Add the new file to the list |
2562
|
|
|
$unknownFilesArray[] = $post_id; |
2563
|
|
|
|
2564
|
|
|
// Save the new list |
2565
|
|
|
DB::insertUpdate( |
2566
|
|
|
prefixTable('misc'), |
2567
|
|
|
[ |
2568
|
|
|
'type' => 'admin', |
2569
|
|
|
'intitule' => 'ignored_unknown_files', |
2570
|
|
|
'valeur' => json_encode($unknownFilesArray), |
2571
|
|
|
'created_at' => time(), |
2572
|
|
|
], |
2573
|
|
|
[ |
2574
|
|
|
'valeur' => json_encode($unknownFilesArray), |
2575
|
|
|
'updated_at' => time(), |
2576
|
|
|
] |
2577
|
|
|
); |
2578
|
|
|
|
2579
|
|
|
|
2580
|
|
|
echo prepareExchangedData( |
2581
|
|
|
array( |
2582
|
|
|
'error' => false, |
2583
|
|
|
'message' => '', |
2584
|
|
|
), |
2585
|
|
|
'encode' |
2586
|
|
|
); |
2587
|
|
|
|
2588
|
|
|
break; |
2589
|
|
|
|
2590
|
|
|
case "deleteFilesIntegrityCheck": |
2591
|
|
|
// Check KEY and rights |
2592
|
|
|
if ($post_key !== $session->get('key')) { |
2593
|
|
|
echo prepareExchangedData( |
2594
|
|
|
array( |
2595
|
|
|
'error' => true, |
2596
|
|
|
'message' => $lang->get('key_is_not_correct'), |
2597
|
|
|
), |
2598
|
|
|
'encode' |
2599
|
|
|
); |
2600
|
|
|
break; |
2601
|
|
|
} |
2602
|
|
|
|
2603
|
|
|
// Get the list of files to delete |
2604
|
|
|
$filesToDelete = DB::queryFirstField( |
2605
|
|
|
'SELECT valeur |
2606
|
|
|
FROM ' . prefixTable('misc') . ' |
2607
|
|
|
WHERE type = %s AND intitule = %s', |
2608
|
|
|
'admin', |
2609
|
|
|
'unknown_files' |
2610
|
|
|
); |
2611
|
|
|
|
2612
|
|
|
if (is_null($filesToDelete)) { |
2613
|
|
|
echo prepareExchangedData( |
2614
|
|
|
array( |
2615
|
|
|
'deletionResults' => null, |
2616
|
|
|
), |
2617
|
|
|
'encode' |
2618
|
|
|
); |
2619
|
|
|
break; |
2620
|
|
|
} |
2621
|
|
|
$referenceFiles = (array) json_decode($filesToDelete); |
2622
|
|
|
|
2623
|
|
|
// Launch |
2624
|
|
|
$ret = deleteFiles($referenceFiles, true); |
2625
|
|
|
|
2626
|
|
|
echo prepareExchangedData( |
2627
|
|
|
array( |
2628
|
|
|
'deletionResults' => $ret, |
2629
|
|
|
), |
2630
|
|
|
'encode' |
2631
|
|
|
); |
2632
|
|
|
|
2633
|
|
|
break; |
2634
|
|
|
|
2635
|
|
|
} |
2636
|
|
|
|
2637
|
|
|
/** |
2638
|
|
|
* Delete multiple files with cross-platform compatibility |
2639
|
|
|
* |
2640
|
|
|
* This function deletes a list of files while ensuring compatibility |
2641
|
|
|
* across different operating systems (Windows, Linux, etc.) |
2642
|
|
|
* |
2643
|
|
|
* @param array $files Array of file paths to delete |
2644
|
|
|
* @param bool $ignoreErrors If true, continues execution even if a file cannot be deleted |
2645
|
|
|
* @return array Results of deletion operations (success/failure for each file) |
2646
|
|
|
*/ |
2647
|
|
|
function deleteFiles(array $files, bool $ignoreErrors = false): array |
2648
|
|
|
{ |
2649
|
|
|
$session = SessionManager::getSession(); |
2650
|
|
|
$lang = new Language($session->get('user-language') ?? 'english'); |
2651
|
|
|
|
2652
|
|
|
$results = []; |
2653
|
|
|
$fullPath = __DIR__ . '/../'; |
2654
|
|
|
|
2655
|
|
|
foreach ($files as $file) { |
2656
|
|
|
// Normalize path separators for cross-platform compatibility |
2657
|
|
|
$normalizedPath = str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $fullPath.$file); |
2658
|
|
|
|
2659
|
|
|
// Check if file exists |
2660
|
|
|
if (!file_exists($normalizedPath)) { |
2661
|
|
|
$results[$normalizedPath] = [ |
2662
|
|
|
'success' => false, |
2663
|
|
|
'error' => $lang->get('file_not_exists') |
2664
|
|
|
]; |
2665
|
|
|
|
2666
|
|
|
if (!$ignoreErrors) { |
2667
|
|
|
return $results; |
2668
|
|
|
} |
2669
|
|
|
|
2670
|
|
|
continue; |
2671
|
|
|
} |
2672
|
|
|
|
2673
|
|
|
// Check if path is actually a file (not a directory) |
2674
|
|
|
if (!is_file($normalizedPath)) { |
2675
|
|
|
$results[$normalizedPath] = [ |
2676
|
|
|
'success' => false, |
2677
|
|
|
'error' => $lang->get('path_not_a_file') |
2678
|
|
|
]; |
2679
|
|
|
|
2680
|
|
|
if (!$ignoreErrors) { |
2681
|
|
|
return $results; |
2682
|
|
|
} |
2683
|
|
|
|
2684
|
|
|
continue; |
2685
|
|
|
} |
2686
|
|
|
|
2687
|
|
|
// Check if file is writable (can be deleted) |
2688
|
|
|
if (!is_writable($normalizedPath)) { |
2689
|
|
|
$results[$normalizedPath] = [ |
2690
|
|
|
'success' => false, |
2691
|
|
|
'error' => $lang->get('file_not_writable') |
2692
|
|
|
]; |
2693
|
|
|
|
2694
|
|
|
if (!$ignoreErrors) { |
2695
|
|
|
return $results; |
2696
|
|
|
} |
2697
|
|
|
|
2698
|
|
|
continue; |
2699
|
|
|
} |
2700
|
|
|
|
2701
|
|
|
// Try to delete the file |
2702
|
|
|
$deleteResult = '';//@unlink($normalizedPath); |
2703
|
|
|
|
2704
|
|
|
if ($deleteResult) { |
2705
|
|
|
$results[$normalizedPath] = [ |
2706
|
|
|
'success' => true, |
2707
|
|
|
'error' => '', |
2708
|
|
|
]; |
2709
|
|
|
} else { |
2710
|
|
|
$results[$normalizedPath] = [ |
2711
|
|
|
'success' => false, |
2712
|
|
|
'error' => $lang->get('failed_to_delete') |
2713
|
|
|
]; |
2714
|
|
|
|
2715
|
|
|
if (!$ignoreErrors) { |
2716
|
|
|
return $results; |
2717
|
|
|
} |
2718
|
|
|
} |
2719
|
|
|
} |
2720
|
|
|
|
2721
|
|
|
return $results; |
2722
|
|
|
} |
2723
|
|
|
|
2724
|
|
|
/** |
2725
|
|
|
* Check the integrity of the files |
2726
|
|
|
* |
2727
|
|
|
* @param string $baseDir |
2728
|
|
|
* @return array |
2729
|
|
|
*/ |
2730
|
|
|
function filesIntegrityCheck($baseDir): array |
2731
|
|
|
{ |
2732
|
|
|
$referenceFile = __DIR__ . '/../files_reference.txt'; |
2733
|
|
|
|
2734
|
|
|
$unknownFiles = findUnknownFiles($baseDir, $referenceFile); |
2735
|
|
|
|
2736
|
|
|
if (empty($unknownFiles)) { |
2737
|
|
|
return [ |
2738
|
|
|
'error' => false, |
2739
|
|
|
'array' => [], |
2740
|
|
|
'message' => '' |
2741
|
|
|
]; |
2742
|
|
|
} |
2743
|
|
|
|
2744
|
|
|
// Check if the files are in the integrity file |
2745
|
|
|
return [ |
2746
|
|
|
'error' => true, |
2747
|
|
|
'array' => $unknownFiles, |
2748
|
|
|
'message' => '' |
2749
|
|
|
]; |
2750
|
|
|
} |
2751
|
|
|
|
2752
|
|
|
/* |
2753
|
|
|
* Get all files in a directory |
2754
|
|
|
* |
2755
|
|
|
* @param string $dir |
2756
|
|
|
* @return array |
2757
|
|
|
*/ |
2758
|
|
|
function getAllFiles($dir): array |
2759
|
|
|
{ |
2760
|
|
|
$files = []; |
2761
|
|
|
$excludeDirs = ['upload', 'files', 'install', '_tools', 'random_compat', 'avatars']; // Répertoires à exclure |
2762
|
|
|
$excludeFilePrefixes = ['csrfp.config.php', 'settings.php', 'version-commit.php', 'phpstan.neon']; // Fichiers à exclure par préfixe |
2763
|
|
|
|
2764
|
|
|
$iterator = new RecursiveIteratorIterator( |
2765
|
|
|
new RecursiveCallbackFilterIterator( |
2766
|
|
|
new RecursiveDirectoryIterator( |
2767
|
|
|
$dir, |
2768
|
|
|
FilesystemIterator::SKIP_DOTS |
2769
|
|
|
), |
2770
|
|
|
function ($current, $key, $iterator) { |
|
|
|
|
2771
|
|
|
// Ignore hidden files and folders |
2772
|
|
|
if ($current->getFilename()[0] === '.') { |
2773
|
|
|
return false; |
2774
|
|
|
} |
2775
|
|
|
return true; |
2776
|
|
|
} |
2777
|
|
|
), |
2778
|
|
|
RecursiveIteratorIterator::SELF_FIRST |
2779
|
|
|
); |
2780
|
|
|
|
2781
|
|
|
foreach ($iterator as $file) { |
2782
|
|
|
try { |
2783
|
|
|
if ($file->isFile()) { |
2784
|
|
|
$relativePath = str_replace($dir . DIRECTORY_SEPARATOR, '', $file->getPathname()); |
2785
|
|
|
$relativePath = str_replace('\\', '/', $relativePath); // Normalisation Windows/Linux |
2786
|
|
|
|
2787
|
|
|
// Split relatif path into parts |
2788
|
|
|
$pathParts = explode('/', $relativePath); |
2789
|
|
|
|
2790
|
|
|
// Check if any part of the path is in the excludeDirs array |
2791
|
|
|
foreach ($pathParts as $part) { |
2792
|
|
|
if (in_array($part, $excludeDirs, true)) { |
2793
|
|
|
continue 2; // Skip the file |
2794
|
|
|
} |
2795
|
|
|
} |
2796
|
|
|
|
2797
|
|
|
// Check if the file name starts with any of the prefixes in excludeFilePrefixes |
2798
|
|
|
$filename = basename($relativePath); |
2799
|
|
|
foreach ($excludeFilePrefixes as $prefix) { |
2800
|
|
|
if (strpos($filename, $prefix) === 0) { |
2801
|
|
|
continue 2; // Skip the file |
2802
|
|
|
} |
2803
|
|
|
} |
2804
|
|
|
|
2805
|
|
|
// If OK then add to the list |
2806
|
|
|
$files[] = $relativePath; |
2807
|
|
|
} |
2808
|
|
|
} catch (UnexpectedValueException $e) { |
2809
|
|
|
continue; // Ignore the file if an error occurs |
2810
|
|
|
} |
2811
|
|
|
} |
2812
|
|
|
|
2813
|
|
|
return $files; |
2814
|
|
|
} |
2815
|
|
|
|
2816
|
|
|
/** |
2817
|
|
|
* Find unknown files |
2818
|
|
|
* |
2819
|
|
|
* @param string $baseDir |
2820
|
|
|
* @param string $referenceFile |
2821
|
|
|
* @return array |
2822
|
|
|
*/ |
2823
|
|
|
function findUnknownFiles($baseDir, $referenceFile): array |
2824
|
|
|
{ |
2825
|
|
|
$currentFiles = getAllFiles($baseDir); |
2826
|
|
|
$referenceFiles = file($referenceFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); |
2827
|
|
|
|
2828
|
|
|
// Remove empty lines and comments from the reference file |
2829
|
|
|
$unknownFiles = array_diff($currentFiles, $referenceFiles); |
2830
|
|
|
|
2831
|
|
|
// Save list to DB |
2832
|
|
|
DB::insertUpdate( |
2833
|
|
|
prefixTable('misc'), |
2834
|
|
|
array( |
2835
|
|
|
'type' => 'admin', |
2836
|
|
|
'intitule' => 'unknown_files', |
2837
|
|
|
'valeur' => json_encode($unknownFiles), |
2838
|
|
|
'created_at' => time(), |
2839
|
|
|
), |
2840
|
|
|
[ |
2841
|
|
|
'valeur' => json_encode($unknownFiles), |
2842
|
|
|
'updated_at' => time(), |
2843
|
|
|
] |
2844
|
|
|
); |
2845
|
|
|
|
2846
|
|
|
// NOw remove ignored files from the list returned to user |
2847
|
|
|
// Get ignored files |
2848
|
|
|
$ignoredFiles = DB::queryFirstField( |
2849
|
|
|
'SELECT valeur |
2850
|
|
|
FROM ' . prefixTable('misc') . ' |
2851
|
|
|
WHERE type = %s AND intitule = %s', |
2852
|
|
|
'admin', |
2853
|
|
|
'ignored_unknown_files' |
2854
|
|
|
); |
2855
|
|
|
$ignoredFilesKeys = !is_null($ignoredFiles) && !empty($ignoredFiles) ? array_flip(json_decode($ignoredFiles)) : []; |
2856
|
|
|
$unknownFiles = array_diff_key($unknownFiles, $ignoredFilesKeys); |
2857
|
|
|
|
2858
|
|
|
return $unknownFiles; |
2859
|
|
|
} |
2860
|
|
|
|
2861
|
|
|
/** |
2862
|
|
|
* Check the integrity of the tables |
2863
|
|
|
* |
2864
|
|
|
* @return array |
2865
|
|
|
*/ |
2866
|
|
|
function tablesIntegrityCheck(): array |
2867
|
|
|
{ |
2868
|
|
|
// Get integrity tables file |
2869
|
|
|
$integrityTablesFile = TEAMPASS_ROOT_PATH . '/includes/tables_integrity.json'; |
2870
|
|
|
if (file_exists($integrityTablesFile) === false) { |
2871
|
|
|
return [ |
2872
|
|
|
'error' => true, |
2873
|
|
|
'message' => "Integrity file has not been found." |
2874
|
|
|
]; |
2875
|
|
|
} |
2876
|
|
|
// Convert json to array |
2877
|
|
|
$integrityTables = json_decode(file_get_contents($integrityTablesFile), true); |
2878
|
|
|
if (json_last_error() !== JSON_ERROR_NONE) { |
2879
|
|
|
return [ |
2880
|
|
|
'error' => true, |
2881
|
|
|
'message' => "Integrity file is corrupted" |
2882
|
|
|
]; |
2883
|
|
|
} |
2884
|
|
|
// Get all tables |
2885
|
|
|
$tables = []; |
2886
|
|
|
foreach (DB::queryFirstColumn("SHOW TABLES") as $table) { |
2887
|
|
|
$tables[] = str_replace(DB_PREFIX, "", $table);; |
2888
|
|
|
} |
2889
|
|
|
// Prepare the integrity check |
2890
|
|
|
$tablesInError = []; |
2891
|
|
|
// Check if the tables are in the integrity file |
2892
|
|
|
foreach ($tables as $table) { |
2893
|
|
|
$tableFound = false; |
2894
|
|
|
$tableHash = ""; |
2895
|
|
|
foreach ($integrityTables as $integrityTable) { |
2896
|
|
|
if ($integrityTable["table_name"] === $table) { |
2897
|
|
|
$tableFound = true; |
2898
|
|
|
$tableHash = $integrityTable["structure_hash"]; |
2899
|
|
|
break; // Sortir de la boucle si la table est trouvée |
2900
|
|
|
} |
2901
|
|
|
} |
2902
|
|
|
|
2903
|
|
|
if ($tableFound === true) { |
2904
|
|
|
$createTable = DB::queryFirstRow("SHOW CREATE TABLE ".DB_PREFIX."$table"); |
2905
|
|
|
$currentHash = hash('sha256', $createTable['Create Table']); |
2906
|
|
|
if ($currentHash !== $tableHash) { |
2907
|
|
|
$tablesInError[] = DB_PREFIX.$table; |
2908
|
|
|
} |
2909
|
|
|
} |
2910
|
|
|
} |
2911
|
|
|
return [ |
2912
|
|
|
'error' => false, |
2913
|
|
|
'array' => $tablesInError, |
2914
|
|
|
'message' => "" |
2915
|
|
|
]; |
2916
|
|
|
} |
2917
|
|
|
|