1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* |
4
|
|
|
* @file main.functions.php |
5
|
|
|
* @author Nils Laumaillé |
6
|
|
|
* @version 2.1.27 |
7
|
|
|
* @copyright (c) 2009-2017 Nils Laumaillé |
8
|
|
|
* @licensing GNU AFFERO GPL 3.0 |
9
|
|
|
* @link |
10
|
|
|
*/ |
11
|
|
|
|
12
|
|
|
//define pbkdf2 iteration count |
13
|
|
|
define('ITCOUNT', '2072'); |
14
|
|
|
|
15
|
|
|
if (!isset($_SESSION['CPM']) || $_SESSION['CPM'] != 1) { |
16
|
|
|
die('Hacking attempt...'); |
17
|
|
|
} |
18
|
|
|
|
19
|
|
|
// Load config |
20
|
|
|
if (file_exists('../includes/config/tp.config.php')) { |
21
|
|
|
require_once '../includes/config/tp.config.php'; |
22
|
|
|
} elseif (file_exists('./includes/config/tp.config.php')) { |
23
|
|
|
require_once './includes/config/tp.config.php'; |
24
|
|
|
} elseif (file_exists('../../includes/config/tp.config.php')) { |
25
|
|
|
require_once '../../includes/config/tp.config.php'; |
26
|
|
|
} else { |
27
|
|
|
throw new Exception("Error file '/includes/config/tp.config.php' not exists", 1); |
28
|
|
|
} |
29
|
|
|
|
30
|
|
|
// load phpCrypt |
31
|
|
|
if (!isset($SETTINGS['cpassman_dir']) || empty($SETTINGS['cpassman_dir'])) { |
32
|
|
|
require_once '../includes/libraries/phpcrypt/phpCrypt.php'; |
33
|
|
|
require_once '../includes/config/settings.php'; |
34
|
|
|
} else { |
35
|
|
|
require_once $SETTINGS['cpassman_dir'].'/includes/libraries/phpcrypt/phpCrypt.php'; |
36
|
|
|
require_once $SETTINGS['cpassman_dir'].'/includes/config/settings.php'; |
37
|
|
|
} |
38
|
|
|
|
39
|
|
|
// Prepare PHPCrypt class calls |
40
|
|
|
use PHP_Crypt\PHP_Crypt as PHP_Crypt; |
41
|
|
|
|
42
|
|
|
// Prepare Encryption class calls |
43
|
|
|
use \Defuse\Crypto\Crypto; |
44
|
|
|
use \Defuse\Crypto\Exception as Ex; |
45
|
|
|
|
46
|
|
|
//Generate N# of random bits for use as salt |
47
|
|
|
/** |
48
|
|
|
* @param integer $size |
49
|
|
|
*/ |
50
|
|
|
function getBits($size) |
51
|
|
|
{ |
52
|
|
|
$str = ''; |
53
|
|
|
$var_x = $size + 10; |
54
|
|
|
for ($var_i = 0; $var_i < $var_x; $var_i++) { |
55
|
|
|
$str .= base_convert(mt_rand(1, 36), 10, 36); |
56
|
|
|
} |
57
|
|
|
return substr($str, 0, $size); |
58
|
|
|
} |
59
|
|
|
|
60
|
|
|
//generate pbkdf2 compliant hash |
61
|
|
View Code Duplication |
function strHashPbkdf2($var_p, $var_s, $var_c, $var_kl, $var_a = 'sha256', $var_st = 0) |
|
|
|
|
62
|
|
|
{ |
63
|
|
|
$var_kb = $var_st + $var_kl; // Key blocks to compute |
64
|
|
|
$var_dk = ''; // Derived key |
65
|
|
|
|
66
|
|
|
for ($block = 1; $block <= $var_kb; $block++) { // Create key |
67
|
|
|
$var_ib = $var_h = hash_hmac($var_a, $var_s.pack('N', $block), $var_p, true); // Initial hash for this block |
68
|
|
|
for ($var_i = 1; $var_i < $var_c; $var_i++) { // Perform block iterations |
69
|
|
|
$var_ib ^= ($var_h = hash_hmac($var_a, $var_h, $var_p, true)); // XOR each iterate |
70
|
|
|
} |
71
|
|
|
$var_dk .= $var_ib; // Append iterated block |
72
|
|
|
} |
73
|
|
|
return substr($var_dk, $var_st, $var_kl); // Return derived key of correct length |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
/** |
77
|
|
|
* stringUtf8Decode() |
78
|
|
|
* |
79
|
|
|
* utf8_decode |
80
|
|
|
*/ |
81
|
|
|
function stringUtf8Decode($string) |
82
|
|
|
{ |
83
|
|
|
return str_replace(" ", "+", utf8_decode($string)); |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
/** |
87
|
|
|
* encryptOld() |
88
|
|
|
* |
89
|
|
|
* crypt a string |
90
|
|
|
* @param string $text |
91
|
|
|
*/ |
92
|
|
|
function encryptOld($text, $personalSalt = "") |
93
|
|
|
{ |
94
|
|
|
if (empty($personalSalt) === false) { |
95
|
|
|
return trim( |
96
|
|
|
base64_encode( |
97
|
|
|
mcrypt_encrypt( |
98
|
|
|
MCRYPT_RIJNDAEL_256, |
99
|
|
|
$personalSalt, |
100
|
|
|
$text, |
101
|
|
|
MCRYPT_MODE_ECB, |
102
|
|
|
mcrypt_create_iv( |
103
|
|
|
mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), |
104
|
|
|
MCRYPT_RAND |
105
|
|
|
) |
106
|
|
|
) |
107
|
|
|
) |
108
|
|
|
); |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
// If $personalSalt is not empty |
112
|
|
|
return trim( |
113
|
|
|
base64_encode( |
114
|
|
|
mcrypt_encrypt( |
115
|
|
|
MCRYPT_RIJNDAEL_256, |
116
|
|
|
SALT, |
117
|
|
|
$text, |
118
|
|
|
MCRYPT_MODE_ECB, |
119
|
|
|
mcrypt_create_iv( |
120
|
|
|
mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), |
121
|
|
|
MCRYPT_RAND |
122
|
|
|
) |
123
|
|
|
) |
124
|
|
|
) |
125
|
|
|
); |
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
/** |
129
|
|
|
* decryptOld() |
130
|
|
|
* |
131
|
|
|
* decrypt a crypted string |
132
|
|
|
*/ |
133
|
|
|
function decryptOld($text, $personalSalt = "") |
134
|
|
|
{ |
135
|
|
|
if (!empty($personalSalt)) { |
136
|
|
|
return trim( |
137
|
|
|
mcrypt_decrypt( |
138
|
|
|
MCRYPT_RIJNDAEL_256, |
139
|
|
|
$personalSalt, |
140
|
|
|
base64_decode($text), |
141
|
|
|
MCRYPT_MODE_ECB, |
142
|
|
|
mcrypt_create_iv( |
143
|
|
|
mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), |
144
|
|
|
MCRYPT_RAND |
145
|
|
|
) |
146
|
|
|
) |
147
|
|
|
); |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
// No personal SK |
151
|
|
|
return trim( |
152
|
|
|
mcrypt_decrypt( |
153
|
|
|
MCRYPT_RIJNDAEL_256, |
154
|
|
|
SALT, |
155
|
|
|
base64_decode($text), |
156
|
|
|
MCRYPT_MODE_ECB, |
157
|
|
|
mcrypt_create_iv( |
158
|
|
|
mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), |
159
|
|
|
MCRYPT_RAND |
160
|
|
|
) |
161
|
|
|
) |
162
|
|
|
); |
163
|
|
|
} |
164
|
|
|
|
165
|
|
|
/** |
166
|
|
|
* encrypt() |
167
|
|
|
* |
168
|
|
|
* crypt a string |
169
|
|
|
* @param string $decrypted |
170
|
|
|
*/ |
171
|
|
|
function encrypt($decrypted, $personalSalt = "") |
172
|
|
|
{ |
173
|
|
|
global $SETTINGS; |
174
|
|
|
|
175
|
|
View Code Duplication |
if (!isset($SETTINGS['cpassman_dir']) || empty($SETTINGS['cpassman_dir'])) { |
176
|
|
|
require_once '../includes/libraries/Encryption/PBKDF2/PasswordHash.php'; |
177
|
|
|
} else { |
178
|
|
|
require_once $SETTINGS['cpassman_dir'].'/includes/libraries/Encryption/PBKDF2/PasswordHash.php'; |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
if (!empty($personalSalt)) { |
182
|
|
|
$staticSalt = $personalSalt; |
183
|
|
|
} else { |
184
|
|
|
$staticSalt = SALT; |
185
|
|
|
} |
186
|
|
|
|
187
|
|
|
//set our salt to a variable |
188
|
|
|
// Get 64 random bits for the salt for pbkdf2 |
189
|
|
|
$pbkdf2Salt = getBits(64); |
190
|
|
|
// generate a pbkdf2 key to use for the encryption. |
191
|
|
|
$key = substr(pbkdf2('sha256', $staticSalt, $pbkdf2Salt, ITCOUNT, 16 + 32, true), 32, 16); |
192
|
|
|
// Build $init_vect and $ivBase64. We use a block size of 256 bits (AES compliant) |
193
|
|
|
// and CTR mode. (Note: ECB mode is inadequate as IV is not used.) |
194
|
|
|
$init_vect = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, 'ctr'), MCRYPT_RAND); |
195
|
|
|
|
196
|
|
|
//base64 trim |
197
|
|
|
if (strlen($ivBase64 = rtrim(base64_encode($init_vect), '=')) != 43) { |
198
|
|
|
return false; |
199
|
|
|
} |
200
|
|
|
// Encrypt $decrypted |
201
|
|
|
$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $decrypted, 'ctr', $init_vect); |
202
|
|
|
// MAC the encrypted text |
203
|
|
|
$mac = hash_hmac('sha256', $encrypted, $staticSalt); |
204
|
|
|
// We're done! |
205
|
|
|
return base64_encode($ivBase64.$encrypted.$mac.$pbkdf2Salt); |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
/** |
209
|
|
|
* decrypt() |
210
|
|
|
* |
211
|
|
|
* decrypt a crypted string |
212
|
|
|
*/ |
213
|
|
|
function decrypt($encrypted, $personalSalt = "") |
214
|
|
|
{ |
215
|
|
|
global $SETTINGS; |
216
|
|
|
|
217
|
|
View Code Duplication |
if (!isset($SETTINGS['cpassman_dir']) || empty($SETTINGS['cpassman_dir'])) { |
218
|
|
|
require_once '../includes/libraries/Encryption/PBKDF2/PasswordHash.php'; |
219
|
|
|
} else { |
220
|
|
|
require_once $SETTINGS['cpassman_dir'].'/includes/libraries/Encryption/PBKDF2/PasswordHash.php'; |
221
|
|
|
} |
222
|
|
|
|
223
|
|
|
if (!empty($personalSalt)) { |
224
|
|
|
$staticSalt = $personalSalt; |
225
|
|
|
} else { |
226
|
|
|
$staticSalt = file_get_contents(SECUREPATH."/teampass-seckey.txt"); |
227
|
|
|
} |
228
|
|
|
//base64 decode the entire payload |
229
|
|
|
$encrypted = base64_decode($encrypted); |
230
|
|
|
// get the salt |
231
|
|
|
$pbkdf2Salt = substr($encrypted, -64); |
232
|
|
|
//remove the salt from the string |
233
|
|
|
$encrypted = substr($encrypted, 0, -64); |
234
|
|
|
$key = substr(pbkdf2('sha256', $staticSalt, $pbkdf2Salt, ITCOUNT, 16 + 32, true), 32, 16); |
235
|
|
|
// Retrieve $init_vect which is the first 22 characters plus ==, base64_decoded. |
236
|
|
|
$init_vect = base64_decode(substr($encrypted, 0, 43).'=='); |
237
|
|
|
// Remove $init_vect from $encrypted. |
238
|
|
|
$encrypted = substr($encrypted, 43); |
239
|
|
|
// Retrieve $mac which is the last 64 characters of $encrypted. |
240
|
|
|
$mac = substr($encrypted, -64); |
241
|
|
|
// Remove the last 64 chars from encrypted (remove MAC) |
242
|
|
|
$encrypted = substr($encrypted, 0, -64); |
243
|
|
|
//verify the sha256hmac from the encrypted data before even trying to decrypt it |
244
|
|
|
if (hash_hmac('sha256', $encrypted, $staticSalt) != $mac) { |
245
|
|
|
return false; |
246
|
|
|
} |
247
|
|
|
// Decrypt the data. |
248
|
|
|
$decrypted = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $encrypted, 'ctr', $init_vect), "\0\4"); |
249
|
|
|
// Yay! |
250
|
|
|
return $decrypted; |
251
|
|
|
} |
252
|
|
|
|
253
|
|
|
|
254
|
|
|
/** |
255
|
|
|
* genHash() |
256
|
|
|
* |
257
|
|
|
* Generate a hash for user login |
258
|
|
|
* @param string $password |
259
|
|
|
*/ |
260
|
|
View Code Duplication |
function bCrypt($password, $cost) |
|
|
|
|
261
|
|
|
{ |
262
|
|
|
$salt = sprintf('$2y$%02d$', $cost); |
263
|
|
|
if (function_exists('openssl_random_pseudo_bytes')) { |
264
|
|
|
$salt .= bin2hex(openssl_random_pseudo_bytes(11)); |
265
|
|
|
} else { |
266
|
|
|
$chars = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; |
267
|
|
|
for ($i = 0; $i < 22; $i++) { |
268
|
|
|
$salt .= $chars[mt_rand(0, 63)]; |
269
|
|
|
} |
270
|
|
|
} |
271
|
|
|
return crypt($password, $salt); |
272
|
|
|
} |
273
|
|
|
|
274
|
|
|
function cryption_before_defuse($message, $saltkey, $init_vect, $type = null, $scope = "public") |
275
|
|
|
{ |
276
|
|
|
if (DEFUSE_ENCRYPTION === true) { |
277
|
|
|
if ($scope === "perso") { |
278
|
|
|
return defuse_crypto( |
279
|
|
|
$message, |
280
|
|
|
$saltkey, |
281
|
|
|
$type |
282
|
|
|
); |
283
|
|
|
} else { |
284
|
|
|
return defuse_crypto( |
285
|
|
|
$message, |
286
|
|
|
file_get_contents(SECUREPATH."/teampass-seckey.txt"), |
287
|
|
|
$type |
288
|
|
|
); |
289
|
|
|
} |
290
|
|
|
} else { |
291
|
|
|
return cryption_phpCrypt($message, $saltkey, $init_vect, $type); |
292
|
|
|
} |
293
|
|
|
} |
294
|
|
|
|
295
|
|
|
/* |
296
|
|
|
* cryption() - Encrypt and decrypt string based upon phpCrypt library |
297
|
|
|
* |
298
|
|
|
* Using AES_128 and mode CBC |
299
|
|
|
* |
300
|
|
|
* $key and $init_vect have to be given in hex format |
301
|
|
|
*/ |
302
|
|
|
function cryption_phpCrypt($string, $key, $init_vect, $type) |
303
|
|
|
{ |
304
|
|
|
// manage key origin |
305
|
|
|
if (null != SALT && $key != SALT) { |
306
|
|
|
// check key (AES-128 requires a 16 bytes length key) |
307
|
|
|
if (strlen($key) < 16) { |
308
|
|
|
for ($inc = strlen($key) + 1; $inc <= 16; $inc++) { |
309
|
|
|
$key .= chr(0); |
310
|
|
|
} |
311
|
|
|
} elseif (strlen($key) > 16) { |
312
|
|
|
$key = substr($key, 16); |
313
|
|
|
} |
314
|
|
|
} |
315
|
|
|
|
316
|
|
|
// load crypt |
317
|
|
|
$crypt = new PHP_Crypt($key, PHP_Crypt::CIPHER_AES_128, PHP_Crypt::MODE_CBC); |
318
|
|
|
|
319
|
|
|
if ($type == "encrypt") { |
320
|
|
|
// generate IV and encrypt |
321
|
|
|
$init_vect = $crypt->createIV(); |
322
|
|
|
$encrypt = $crypt->encrypt($string); |
323
|
|
|
// return |
324
|
|
|
return array( |
325
|
|
|
"string" => bin2hex($encrypt), |
326
|
|
|
"iv" => bin2hex($init_vect), |
327
|
|
|
"error" => empty($encrypt) ? "ERR_ENCRYPTION_NOT_CORRECT" : "" |
328
|
|
|
); |
329
|
|
|
} elseif ($type == "decrypt") { |
330
|
|
|
// case if IV is empty |
331
|
|
|
if (empty($init_vect)) { |
332
|
|
|
return array( |
333
|
|
|
'string' => "", |
334
|
|
|
'error' => "ERR_ENCRYPTION_NOT_CORRECT" |
335
|
|
|
); |
336
|
|
|
} |
337
|
|
|
|
338
|
|
|
// convert |
339
|
|
|
try { |
340
|
|
|
$string = testHex2Bin(trim($string)); |
341
|
|
|
$init_vect = testHex2Bin($init_vect); |
342
|
|
|
} catch (Exception $e) { |
343
|
|
|
return array( |
344
|
|
|
'string' => "", |
345
|
|
|
'error' => "ERR_ENCRYPTION_NOT_CORRECT" |
346
|
|
|
); |
347
|
|
|
} |
348
|
|
|
|
349
|
|
|
// load IV |
350
|
|
|
$crypt->IV($init_vect); |
351
|
|
|
// decrypt |
352
|
|
|
$decrypt = $crypt->decrypt($string); |
353
|
|
|
// return |
354
|
|
|
return array( |
355
|
|
|
'string' => str_replace(chr(0), "", $decrypt), |
356
|
|
|
'error' => "" |
357
|
|
|
); |
358
|
|
|
} |
359
|
|
|
} |
360
|
|
|
|
361
|
|
|
function testHex2Bin($val) |
362
|
|
|
{ |
363
|
|
|
if (!@hex2bin($val)) { |
364
|
|
|
throw new Exception("ERROR"); |
365
|
|
|
} |
366
|
|
|
return hex2bin($val); |
367
|
|
|
} |
368
|
|
|
|
369
|
|
|
/** |
370
|
|
|
* @param string $ascii_key |
371
|
|
|
* @param string $type |
372
|
|
|
*/ |
373
|
|
|
function cryption($message, $ascii_key, $type) //defuse_crypto |
374
|
|
|
{ |
375
|
|
|
global $SETTINGS; |
376
|
|
|
|
377
|
|
|
// load PhpEncryption library |
378
|
|
View Code Duplication |
if (!isset($SETTINGS['cpassman_dir']) || empty($SETTINGS['cpassman_dir'])) { |
379
|
|
|
$path = '../includes/libraries/Encryption/Encryption/'; |
380
|
|
|
} else { |
381
|
|
|
$path = $SETTINGS['cpassman_dir'].'/includes/libraries/Encryption/Encryption/'; |
382
|
|
|
} |
383
|
|
|
|
384
|
|
|
require_once $path.'Crypto.php'; |
385
|
|
|
require_once $path.'Encoding.php'; |
386
|
|
|
require_once $path.'DerivedKeys.php'; |
387
|
|
|
require_once $path.'Key.php'; |
388
|
|
|
require_once $path.'KeyOrPassword.php'; |
389
|
|
|
require_once $path.'File.php'; |
390
|
|
|
require_once $path.'RuntimeTests.php'; |
391
|
|
|
require_once $path.'KeyProtectedByPassword.php'; |
392
|
|
|
require_once $path.'Core.php'; |
393
|
|
|
|
394
|
|
|
// init |
395
|
|
|
$err = ''; |
396
|
|
|
if (empty($ascii_key)) { |
397
|
|
|
$ascii_key = file_get_contents(SECUREPATH."/teampass-seckey.txt"); |
398
|
|
|
} |
399
|
|
|
|
400
|
|
|
// convert KEY |
401
|
|
|
$key = \Defuse\Crypto\Key::loadFromAsciiSafeString($ascii_key); |
402
|
|
|
|
403
|
|
|
try { |
404
|
|
|
if ($type === "encrypt") { |
405
|
|
|
$text = \Defuse\Crypto\Crypto::encrypt($message, $key); |
406
|
|
|
} elseif ($type === "decrypt") { |
407
|
|
|
$text = \Defuse\Crypto\Crypto::decrypt($message, $key); |
408
|
|
|
} |
409
|
|
|
} catch (Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException $ex) { |
410
|
|
|
$err = "an attack! either the wrong key was loaded, or the ciphertext has changed since it was created either corrupted in the database or intentionally modified by someone trying to carry out an attack."; |
411
|
|
|
} catch (Defuse\Crypto\Exception\BadFormatException $ex) { |
412
|
|
|
$err = $ex; |
413
|
|
|
} catch (Defuse\Crypto\Exception\EnvironmentIsBrokenException $ex) { |
414
|
|
|
$err = $ex; |
415
|
|
|
} catch (Defuse\Crypto\Exception\CryptoException $ex) { |
416
|
|
|
$err = $ex; |
417
|
|
|
} catch (Defuse\Crypto\Exception\IOException $ex) { |
418
|
|
|
$err = $ex; |
419
|
|
|
} |
420
|
|
|
|
421
|
|
|
return array( |
422
|
|
|
'string' => isset($text) ? $text : "", |
423
|
|
|
'error' => $err |
424
|
|
|
); |
425
|
|
|
} |
426
|
|
|
|
427
|
|
|
function defuse_generate_key() |
428
|
|
|
{ |
429
|
|
|
require_once '../includes/libraries/Encryption/Encryption/Crypto.php'; |
430
|
|
|
require_once '../includes/libraries/Encryption/Encryption/Encoding.php'; |
431
|
|
|
require_once '../includes/libraries/Encryption/Encryption/DerivedKeys.php'; |
432
|
|
|
require_once '../includes/libraries/Encryption/Encryption/Key.php'; |
433
|
|
|
require_once '../includes/libraries/Encryption/Encryption/KeyOrPassword.php'; |
434
|
|
|
require_once '../includes/libraries/Encryption/Encryption/File.php'; |
435
|
|
|
require_once '../includes/libraries/Encryption/Encryption/RuntimeTests.php'; |
436
|
|
|
require_once '../includes/libraries/Encryption/Encryption/KeyProtectedByPassword.php'; |
437
|
|
|
require_once '../includes/libraries/Encryption/Encryption/Core.php'; |
438
|
|
|
|
439
|
|
|
$key = \Defuse\Crypto\Key::createNewRandomKey(); |
440
|
|
|
$key = $key->saveToAsciiSafeString(); |
441
|
|
|
return $key; |
442
|
|
|
} |
443
|
|
|
|
444
|
|
|
function defuse_generate_personal_key($psk) |
445
|
|
|
{ |
446
|
|
|
require_once '../includes/libraries/Encryption/Encryption/Crypto.php'; |
447
|
|
|
require_once '../includes/libraries/Encryption/Encryption/Encoding.php'; |
448
|
|
|
require_once '../includes/libraries/Encryption/Encryption/DerivedKeys.php'; |
449
|
|
|
require_once '../includes/libraries/Encryption/Encryption/Key.php'; |
450
|
|
|
require_once '../includes/libraries/Encryption/Encryption/KeyOrPassword.php'; |
451
|
|
|
require_once '../includes/libraries/Encryption/Encryption/File.php'; |
452
|
|
|
require_once '../includes/libraries/Encryption/Encryption/RuntimeTests.php'; |
453
|
|
|
require_once '../includes/libraries/Encryption/Encryption/KeyProtectedByPassword.php'; |
454
|
|
|
require_once '../includes/libraries/Encryption/Encryption/Core.php'; |
455
|
|
|
|
456
|
|
|
$protected_key = \Defuse\Crypto\KeyProtectedByPassword::createRandomPasswordProtectedKey($psk); |
457
|
|
|
$protected_key_encoded = $protected_key->saveToAsciiSafeString(); |
458
|
|
|
|
459
|
|
|
return $protected_key_encoded; // save this in user table |
460
|
|
|
} |
461
|
|
|
|
462
|
|
|
/** |
463
|
|
|
* @param string $psk |
464
|
|
|
*/ |
465
|
|
|
function defuse_validate_personal_key($psk, $protected_key_encoded) |
466
|
|
|
{ |
467
|
|
|
require_once '../includes/libraries/Encryption/Encryption/Crypto.php'; |
468
|
|
|
require_once '../includes/libraries/Encryption/Encryption/Encoding.php'; |
469
|
|
|
require_once '../includes/libraries/Encryption/Encryption/DerivedKeys.php'; |
470
|
|
|
require_once '../includes/libraries/Encryption/Encryption/Key.php'; |
471
|
|
|
require_once '../includes/libraries/Encryption/Encryption/KeyOrPassword.php'; |
472
|
|
|
require_once '../includes/libraries/Encryption/Encryption/File.php'; |
473
|
|
|
require_once '../includes/libraries/Encryption/Encryption/RuntimeTests.php'; |
474
|
|
|
require_once '../includes/libraries/Encryption/Encryption/KeyProtectedByPassword.php'; |
475
|
|
|
require_once '../includes/libraries/Encryption/Encryption/Core.php'; |
476
|
|
|
|
477
|
|
|
try { |
478
|
|
|
$protected_key = \Defuse\Crypto\KeyProtectedByPassword::loadFromAsciiSafeString($protected_key_encoded); |
479
|
|
|
$user_key = $protected_key->unlockKey($psk); |
480
|
|
|
$user_key_encoded = $user_key->saveToAsciiSafeString(); |
481
|
|
|
} catch (Defuse\Crypto\Exception\EnvironmentIsBrokenException $ex) { |
482
|
|
|
return "Error - Major issue as the encryption is broken."; |
483
|
|
|
} catch (Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException $ex) { |
484
|
|
|
return "Error - The saltkey is not the correct one."; |
485
|
|
|
} |
486
|
|
|
|
487
|
|
|
return $user_key_encoded; // store it in session once user has entered his psk |
488
|
|
|
} |
489
|
|
|
|
490
|
|
|
/** |
491
|
|
|
* Decrypt a defuse string if encrypted |
492
|
|
|
* @param [type] $value Encrypted string |
|
|
|
|
493
|
|
|
* @return [type] Decrypted string |
|
|
|
|
494
|
|
|
*/ |
495
|
|
|
function defuse_return_decrypted($value) |
496
|
|
|
{ |
497
|
|
|
if (substr($value, 0, 3) === "def") { |
498
|
|
|
$value = cryption($value, "", "decrypt")['string']; |
499
|
|
|
} |
500
|
|
|
return $value; |
501
|
|
|
} |
502
|
|
|
|
503
|
|
|
/** |
504
|
|
|
* trimElement() |
505
|
|
|
* |
506
|
|
|
* trim a string depending on a specific string |
507
|
|
|
* @param string $element |
508
|
|
|
* @return string |
509
|
|
|
*/ |
510
|
|
|
function trimElement($chaine, $element) |
511
|
|
|
{ |
512
|
|
|
if (!empty($chaine)) { |
513
|
|
|
if (is_array($chaine) === true) { |
514
|
|
|
$chaine = implode(";", $chaine); |
515
|
|
|
} |
516
|
|
|
$chaine = trim($chaine); |
517
|
|
|
if (substr($chaine, 0, 1) == $element) { |
518
|
|
|
$chaine = substr($chaine, 1); |
519
|
|
|
} |
520
|
|
|
if (substr($chaine, strlen($chaine) - 1, 1) == $element) { |
521
|
|
|
$chaine = substr($chaine, 0, strlen($chaine) - 1); |
522
|
|
|
} |
523
|
|
|
} |
524
|
|
|
return $chaine; |
525
|
|
|
} |
526
|
|
|
|
527
|
|
|
/** |
528
|
|
|
* cleanString() |
529
|
|
|
* |
530
|
|
|
* permits to suppress all "special" characters from string |
531
|
|
|
*/ |
532
|
|
|
function cleanString($string, $special = false) |
533
|
|
|
{ |
534
|
|
|
// Create temporary table for special characters escape |
535
|
|
|
$tabSpecialChar = array(); |
536
|
|
|
for ($i = 0; $i <= 31; $i++) { |
537
|
|
|
$tabSpecialChar[] = chr($i); |
538
|
|
|
} |
539
|
|
|
array_push($tabSpecialChar, "<br />"); |
540
|
|
|
if ($special == "1") { |
541
|
|
|
$tabSpecialChar = array_merge($tabSpecialChar, array("</li>", "<ul>", "<ol>")); |
542
|
|
|
} |
543
|
|
|
|
544
|
|
|
return str_replace($tabSpecialChar, "\n", $string); |
545
|
|
|
} |
546
|
|
|
|
547
|
|
|
function db_error_handler($params) |
548
|
|
|
{ |
549
|
|
|
echo "Error: ".$params['error']."<br>\n"; |
550
|
|
|
echo "Query: ".$params['query']."<br>\n"; |
551
|
|
|
throw new Exception("Error - Query", 1); |
552
|
|
|
} |
553
|
|
|
|
554
|
|
|
/** |
555
|
|
|
* [identifyUserRights description] |
556
|
|
|
* @param string $groupesVisiblesUser [description] |
557
|
|
|
* @param string $groupesInterditsUser [description] |
558
|
|
|
* @param string $isAdmin [description] |
559
|
|
|
* @param string $idFonctions [description] |
560
|
|
|
* @return string [description] |
561
|
|
|
*/ |
562
|
|
|
function identifyUserRights($groupesVisiblesUser, $groupesInterditsUser, $isAdmin, $idFonctions) |
563
|
|
|
{ |
564
|
|
|
global $server, $user, $pass, $database, $port, $encoding; |
565
|
|
|
global $SETTINGS; |
566
|
|
|
|
567
|
|
|
//load ClassLoader |
568
|
|
|
require_once $SETTINGS['cpassman_dir'].'/sources/SplClassLoader.php'; |
569
|
|
|
|
570
|
|
|
//Connect to DB |
571
|
|
|
require_once $SETTINGS['cpassman_dir'].'/includes/libraries/Database/Meekrodb/db.class.php'; |
572
|
|
|
$pass = defuse_return_decrypted($pass); |
573
|
|
|
DB::$host = $server; |
574
|
|
|
DB::$user = $user; |
575
|
|
|
DB::$password = $pass; |
576
|
|
|
DB::$dbName = $database; |
577
|
|
|
DB::$port = $port; |
578
|
|
|
DB::$encoding = $encoding; |
579
|
|
|
DB::$error_handler = true; |
580
|
|
|
$link = mysqli_connect($server, $user, $pass, $database, $port); |
581
|
|
|
$link->set_charset($encoding); |
582
|
|
|
|
583
|
|
|
//Build tree |
584
|
|
|
$tree = new SplClassLoader('Tree\NestedTree', $SETTINGS['cpassman_dir'].'/includes/libraries'); |
585
|
|
|
$tree->register(); |
586
|
|
|
$tree = new Tree\NestedTree\NestedTree(prefix_table("nested_tree"), 'id', 'parent_id', 'title'); |
587
|
|
|
|
588
|
|
|
// Check if user is ADMINISTRATOR |
589
|
|
|
if ($isAdmin == 1) { |
590
|
|
|
$groupesVisibles = array(); |
591
|
|
|
$_SESSION['personal_folders'] = array(); |
592
|
|
|
$_SESSION['groupes_visibles'] = array(); |
593
|
|
|
$_SESSION['groupes_interdits'] = array(); |
594
|
|
|
$_SESSION['personal_visible_groups'] = array(); |
595
|
|
|
$_SESSION['read_only_folders'] = array(); |
596
|
|
|
$_SESSION['list_restricted_folders_for_items'] = array(); |
597
|
|
|
$_SESSION['list_folders_editable_by_role'] = array(); |
598
|
|
|
$_SESSION['list_folders_limited'] = array(); |
599
|
|
|
$_SESSION['no_access_folders'] = array(); |
600
|
|
|
$_SESSION['groupes_visibles_list'] = ""; |
601
|
|
|
$rows = DB::query("SELECT id FROM ".prefix_table("nested_tree")." WHERE personal_folder = %i", 0); |
602
|
|
|
foreach ($rows as $record) { |
603
|
|
|
array_push($groupesVisibles, $record['id']); |
604
|
|
|
} |
605
|
|
|
$_SESSION['groupes_visibles'] = $groupesVisibles; |
606
|
|
|
$_SESSION['all_non_personal_folders'] = $groupesVisibles; |
607
|
|
|
// Exclude all PF |
608
|
|
|
$_SESSION['forbiden_pfs'] = array(); |
609
|
|
|
$where = new WhereClause('and'); // create a WHERE statement of pieces joined by ANDs |
610
|
|
|
$where->add('personal_folder=%i', 1); |
611
|
|
|
if (isset($SETTINGS['enable_pf_feature']) && $SETTINGS['enable_pf_feature'] == 1) { |
612
|
|
|
$where->add('title=%s', $_SESSION['user_id']); |
613
|
|
|
$where->negateLast(); |
614
|
|
|
} |
615
|
|
|
// Get ID of personal folder |
616
|
|
|
$persfld = DB::queryfirstrow( |
617
|
|
|
"SELECT id FROM ".prefix_table("nested_tree")." WHERE title = %s", |
618
|
|
|
$_SESSION['user_id'] |
619
|
|
|
); |
620
|
|
|
if (!empty($persfld['id'])) { |
621
|
|
|
if (!in_array($persfld['id'], $_SESSION['groupes_visibles'])) { |
622
|
|
|
array_push($_SESSION['groupes_visibles'], $persfld['id']); |
623
|
|
|
array_push($_SESSION['personal_visible_groups'], $persfld['id']); |
624
|
|
|
// get all descendants |
625
|
|
|
$tree = new Tree\NestedTree\NestedTree(prefix_table("nested_tree"), 'id', 'parent_id', 'title'); |
626
|
|
|
$tree->rebuild(); |
627
|
|
|
$tst = $tree->getDescendants($persfld['id']); |
628
|
|
|
foreach ($tst as $t) { |
629
|
|
|
array_push($_SESSION['groupes_visibles'], $t->id); |
630
|
|
|
array_push($_SESSION['personal_visible_groups'], $t->id); |
631
|
|
|
} |
632
|
|
|
} |
633
|
|
|
} |
634
|
|
|
|
635
|
|
|
// get complete list of ROLES |
636
|
|
|
$tmp = explode(";", $idFonctions); |
637
|
|
|
$rows = DB::query( |
638
|
|
|
"SELECT * FROM ".prefix_table("roles_title")." |
639
|
|
|
ORDER BY title ASC" |
640
|
|
|
); |
641
|
|
|
foreach ($rows as $record) { |
642
|
|
|
if (!empty($record['id']) && !in_array($record['id'], $tmp)) { |
643
|
|
|
array_push($tmp, $record['id']); |
644
|
|
|
} |
645
|
|
|
} |
646
|
|
|
$_SESSION['fonction_id'] = implode(";", $tmp); |
647
|
|
|
|
648
|
|
|
$_SESSION['groupes_visibles_list'] = implode(',', $_SESSION['groupes_visibles']); |
649
|
|
|
$_SESSION['is_admin'] = $isAdmin; |
650
|
|
|
// Check if admin has created Folders and Roles |
651
|
|
|
DB::query("SELECT * FROM ".prefix_table("nested_tree").""); |
652
|
|
|
$_SESSION['nb_folders'] = DB::count(); |
653
|
|
|
DB::query("SELECT * FROM ".prefix_table("roles_title")); |
654
|
|
|
$_SESSION['nb_roles'] = DB::count(); |
655
|
|
|
} else { |
656
|
|
|
// init |
657
|
|
|
$_SESSION['groupes_visibles'] = array(); |
658
|
|
|
$_SESSION['personal_folders'] = array(); |
659
|
|
|
$_SESSION['groupes_interdits'] = array(); |
660
|
|
|
$_SESSION['personal_visible_groups'] = array(); |
661
|
|
|
$_SESSION['read_only_folders'] = array(); |
662
|
|
|
$_SESSION['fonction_id'] = $idFonctions; |
663
|
|
|
$groupesInterdits = array(); |
664
|
|
|
if (is_array($groupesInterditsUser) === false) { |
665
|
|
|
$groupesInterditsUser = explode(';', trimElement($groupesInterditsUser, ";")); |
666
|
|
|
} |
667
|
|
|
if (!empty($groupesInterditsUser) && count($groupesInterditsUser) > 0) { |
668
|
|
|
$groupesInterdits = $groupesInterditsUser; |
669
|
|
|
} |
670
|
|
|
$_SESSION['is_admin'] = $isAdmin; |
671
|
|
|
$fonctionsAssociees = explode(';', trimElement($idFonctions, ";")); |
672
|
|
|
|
673
|
|
|
$listAllowedFolders = $listFoldersLimited = $listFoldersEditableByRole = $listRestrictedFoldersForItems = $listReadOnlyFolders = array(); |
674
|
|
|
|
675
|
|
|
// rechercher tous les groupes visibles en fonction des roles de l'utilisateur |
676
|
|
|
foreach ($fonctionsAssociees as $roleId) { |
677
|
|
|
if (!empty($roleId)) { |
678
|
|
|
// Get allowed folders for each Role |
679
|
|
|
$rows = DB::query("SELECT folder_id FROM ".prefix_table("roles_values")." WHERE role_id=%i", $roleId); |
680
|
|
|
|
681
|
|
|
if (DB::count() > 0) { |
682
|
|
|
$tmp = DB::queryfirstrow("SELECT allow_pw_change FROM ".prefix_table("roles_title")." WHERE id = %i", $roleId); |
683
|
|
|
foreach ($rows as $record) { |
684
|
|
|
if (isset($record['folder_id']) && !in_array($record['folder_id'], $listAllowedFolders)) { |
685
|
|
|
array_push($listAllowedFolders, $record['folder_id']); |
686
|
|
|
} |
687
|
|
|
// Check if this group is allowed to modify any pw in allowed folders |
688
|
|
|
if ($tmp['allow_pw_change'] == 1 && !in_array($record['folder_id'], $listFoldersEditableByRole)) { |
689
|
|
|
array_push($listFoldersEditableByRole, $record['folder_id']); |
690
|
|
|
} |
691
|
|
|
} |
692
|
|
|
// Check for the users roles if some specific rights exist on items |
693
|
|
|
$rows = DB::query( |
694
|
|
|
"SELECT i.id_tree, r.item_id |
695
|
|
|
FROM ".prefix_table("items")." as i |
696
|
|
|
INNER JOIN ".prefix_table("restriction_to_roles")." as r ON (r.item_id=i.id) |
697
|
|
|
WHERE r.role_id=%i |
698
|
|
|
ORDER BY i.id_tree ASC", |
699
|
|
|
$roleId |
700
|
|
|
); |
701
|
|
|
$inc = 0; |
702
|
|
|
foreach ($rows as $record) { |
703
|
|
|
if (isset($record['id_tree'])) { |
704
|
|
|
$listFoldersLimited[$record['id_tree']][$inc] = $record['item_id']; |
705
|
|
|
$inc++; |
706
|
|
|
} |
707
|
|
|
} |
708
|
|
|
} |
709
|
|
|
} |
710
|
|
|
} |
711
|
|
|
|
712
|
|
|
// Does this user is allowed to see other items |
713
|
|
|
$inc = 0; |
714
|
|
|
$rows = DB::query( |
715
|
|
|
"SELECT id, id_tree FROM ".prefix_table("items")." |
716
|
|
|
WHERE restricted_to LIKE %ss AND inactif=%s", |
717
|
|
|
$_SESSION['user_id'].';', |
718
|
|
|
'0' |
719
|
|
|
); |
720
|
|
|
foreach ($rows as $record) { |
721
|
|
|
$listRestrictedFoldersForItems[$record['id_tree']][$inc] = $record['id']; |
722
|
|
|
$inc++; |
723
|
|
|
} |
724
|
|
|
// => Build final lists |
725
|
|
|
// Clean arrays |
726
|
|
|
$listAllowedFolders = array_unique($listAllowedFolders); |
727
|
|
|
$groupesVisiblesUser = explode(';', trimElement($groupesVisiblesUser, ";")); |
728
|
|
|
// Add user allowed folders |
729
|
|
|
$allowedFoldersTmp = array_unique( |
730
|
|
|
array_merge($listAllowedFolders, $groupesVisiblesUser) |
731
|
|
|
); |
732
|
|
|
// Exclude from allowed folders all the specific user forbidden folders |
733
|
|
|
$allowedFolders = array(); |
734
|
|
|
foreach ($allowedFoldersTmp as $ident) { |
735
|
|
|
if (!in_array($ident, $groupesInterditsUser) && !empty($ident)) { |
736
|
|
|
array_push($allowedFolders, $ident); |
737
|
|
|
} |
738
|
|
|
} |
739
|
|
|
|
740
|
|
|
// Clean array |
741
|
|
|
$listAllowedFolders = array_filter(array_unique($allowedFolders)); |
742
|
|
|
|
743
|
|
|
// Exclude all PF |
744
|
|
|
$_SESSION['forbiden_pfs'] = array(); |
745
|
|
|
|
746
|
|
|
$where = new WhereClause('and'); |
747
|
|
|
$where->add('personal_folder=%i', 1); |
748
|
|
|
if (isset($SETTINGS['enable_pf_feature']) && |
749
|
|
|
$SETTINGS['enable_pf_feature'] == 1 && |
750
|
|
|
isset($_SESSION['personal_folder']) && |
751
|
|
|
$_SESSION['personal_folder'] == 1 |
752
|
|
|
) { |
753
|
|
|
$where->add('title=%s', $_SESSION['user_id']); |
754
|
|
|
$where->negateLast(); |
755
|
|
|
} |
756
|
|
|
|
757
|
|
|
$persoFlds = DB::query( |
758
|
|
|
"SELECT id |
759
|
|
|
FROM ".prefix_table("nested_tree")." |
760
|
|
|
WHERE %l", |
761
|
|
|
$where |
762
|
|
|
); |
763
|
|
|
foreach ($persoFlds as $persoFldId) { |
764
|
|
|
array_push($_SESSION['forbiden_pfs'], $persoFldId['id']); |
765
|
|
|
} |
766
|
|
|
// Get IDs of personal folders |
767
|
|
|
if (isset($SETTINGS['enable_pf_feature']) && |
768
|
|
|
$SETTINGS['enable_pf_feature'] == 1 && |
769
|
|
|
isset($_SESSION['personal_folder']) && |
770
|
|
|
$_SESSION['personal_folder'] == 1 |
771
|
|
|
) { |
772
|
|
|
$persoFld = DB::queryfirstrow( |
773
|
|
|
"SELECT id |
774
|
|
|
FROM ".prefix_table("nested_tree")." |
775
|
|
|
WHERE title = %s", |
776
|
|
|
$_SESSION['user_id'] |
777
|
|
|
); |
778
|
|
|
if (empty($persoFld['id']) === false) { |
779
|
|
|
if (!in_array($persoFld['id'], $listAllowedFolders)) { |
780
|
|
|
array_push($_SESSION['personal_folders'], $persoFld['id']); |
781
|
|
|
// get all descendants |
782
|
|
|
$ids = $tree->getDescendants($persoFld['id'], true, false); |
783
|
|
|
foreach ($ids as $ident) { |
784
|
|
|
array_push($listAllowedFolders, $ident->id); |
785
|
|
|
array_push($_SESSION['personal_visible_groups'], $ident->id); |
786
|
|
|
array_push($_SESSION['personal_folders'], $ident->id); |
787
|
|
|
} |
788
|
|
|
} |
789
|
|
|
} |
790
|
|
|
// get list of readonly folders when pf is disabled. |
791
|
|
|
$_SESSION['personal_folders'] = array_unique($_SESSION['personal_folders']); |
792
|
|
|
// rule - if one folder is set as W or N in one of the Role, then User has access as W |
793
|
|
|
foreach ($listAllowedFolders as $folderId) { |
794
|
|
|
if (in_array($folderId, array_unique(array_merge($listReadOnlyFolders, $_SESSION['personal_folders']))) === false) { |
795
|
|
|
DB::query( |
796
|
|
|
"SELECT * |
797
|
|
|
FROM ".prefix_table("roles_values")." |
798
|
|
|
WHERE folder_id = %i AND role_id IN %li AND type IN %ls", |
799
|
|
|
$folderId, |
800
|
|
|
$fonctionsAssociees, |
801
|
|
|
array("W", "ND", "NE", "NDNE") |
802
|
|
|
); |
803
|
|
|
if (DB::count() === 0 && in_array($folderId, $groupesVisiblesUser) === false) { |
804
|
|
|
array_push($listReadOnlyFolders, $folderId); |
805
|
|
|
} |
806
|
|
|
} |
807
|
|
|
} |
808
|
|
|
} else { |
809
|
|
|
// get list of readonly folders when pf is disabled. |
810
|
|
|
// rule - if one folder is set as W in one of the Role, then User has access as W |
811
|
|
|
foreach ($listAllowedFolders as $folderId) { |
812
|
|
|
if (in_array($folderId, $listReadOnlyFolders) === false) { |
813
|
|
|
DB::query( |
814
|
|
|
"SELECT * |
815
|
|
|
FROM ".prefix_table("roles_values")." |
816
|
|
|
WHERE folder_id = %i AND role_id IN %li AND type IN %ls", |
817
|
|
|
$folderId, |
818
|
|
|
$fonctionsAssociees, |
819
|
|
|
array("W", "ND", "NE", "NDNE") |
820
|
|
|
); |
821
|
|
|
if (DB::count() == 0 && !in_array($folderId, $groupesVisiblesUser)) { |
822
|
|
|
array_push($listReadOnlyFolders, $folderId); |
823
|
|
|
} |
824
|
|
|
} |
825
|
|
|
} |
826
|
|
|
} |
827
|
|
|
|
828
|
|
|
// check if change proposals on User's items |
829
|
|
|
if (isset($SETTINGS['enable_suggestion']) === true && $SETTINGS['enable_suggestion'] == 1) { |
830
|
|
|
DB::query( |
831
|
|
|
"SELECT * |
832
|
|
|
FROM ".prefix_table("items_change")." AS c |
833
|
|
|
LEFT JOIN ".prefix_table("log_items")." AS i ON (c.item_id = i.id_item) |
834
|
|
|
WHERE i.action = %s AND i.id_user = %i", |
835
|
|
|
"at_creation", |
836
|
|
|
$_SESSION['user_id'] |
837
|
|
|
); |
838
|
|
|
$_SESSION['nb_item_change_proposals'] = DB::count(); |
839
|
|
|
} else { |
840
|
|
|
$_SESSION['nb_item_change_proposals'] = 0; |
841
|
|
|
} |
842
|
|
|
|
843
|
|
|
$_SESSION['all_non_personal_folders'] = $listAllowedFolders; |
844
|
|
|
$_SESSION['groupes_visibles'] = $listAllowedFolders; |
845
|
|
|
$_SESSION['groupes_visibles_list'] = implode(',', $listAllowedFolders); |
846
|
|
|
$_SESSION['personal_visible_groups_list'] = implode(',', $_SESSION['personal_visible_groups']); |
847
|
|
|
$_SESSION['read_only_folders'] = $listReadOnlyFolders; |
848
|
|
|
$_SESSION['no_access_folders'] = $groupesInterdits; |
849
|
|
|
|
850
|
|
|
$_SESSION['list_folders_limited'] = $listFoldersLimited; |
851
|
|
|
$_SESSION['list_folders_editable_by_role'] = $listFoldersEditableByRole; |
852
|
|
|
$_SESSION['list_restricted_folders_for_items'] = $listRestrictedFoldersForItems; |
853
|
|
|
// Folders and Roles numbers |
854
|
|
|
DB::queryfirstrow("SELECT id FROM ".prefix_table("nested_tree").""); |
855
|
|
|
$_SESSION['nb_folders'] = DB::count(); |
856
|
|
|
DB::queryfirstrow("SELECT id FROM ".prefix_table("roles_title")); |
857
|
|
|
$_SESSION['nb_roles'] = DB::count(); |
858
|
|
|
} |
859
|
|
|
|
860
|
|
|
// update user's timestamp |
861
|
|
|
DB::update( |
862
|
|
|
prefix_table('users'), |
863
|
|
|
array( |
864
|
|
|
'timestamp' => time() |
865
|
|
|
), |
866
|
|
|
"id=%i", |
867
|
|
|
$_SESSION['user_id'] |
868
|
|
|
); |
869
|
|
|
} |
870
|
|
|
|
871
|
|
|
/** |
872
|
|
|
* updateCacheTable() |
873
|
|
|
* |
874
|
|
|
* Update the CACHE table |
875
|
|
|
* @param string $action |
876
|
|
|
*/ |
877
|
|
|
function updateCacheTable($action, $ident = "") |
878
|
|
|
{ |
879
|
|
|
global $server, $user, $pass, $database, $port, $encoding; |
880
|
|
|
global $SETTINGS; |
881
|
|
|
|
882
|
|
|
require_once $SETTINGS['cpassman_dir'].'/sources/SplClassLoader.php'; |
883
|
|
|
|
884
|
|
|
//Connect to DB |
885
|
|
|
require_once $SETTINGS['cpassman_dir'].'/includes/libraries/Database/Meekrodb/db.class.php'; |
886
|
|
|
$pass = defuse_return_decrypted($pass); |
887
|
|
|
DB::$host = $server; |
888
|
|
|
DB::$user = $user; |
889
|
|
|
DB::$password = $pass; |
890
|
|
|
DB::$dbName = $database; |
891
|
|
|
DB::$port = $port; |
892
|
|
|
DB::$encoding = $encoding; |
893
|
|
|
DB::$error_handler = true; |
894
|
|
|
$link = mysqli_connect($server, $user, $pass, $database, $port); |
895
|
|
|
$link->set_charset($encoding); |
896
|
|
|
|
897
|
|
|
//Load Tree |
898
|
|
|
$tree = new SplClassLoader('Tree\NestedTree', '../includes/libraries'); |
899
|
|
|
$tree->register(); |
900
|
|
|
$tree = new Tree\NestedTree\NestedTree(prefix_table("nested_tree"), 'id', 'parent_id', 'title'); |
901
|
|
|
|
902
|
|
|
// Rebuild full cache table |
903
|
|
|
if ($action === "reload") { |
904
|
|
|
// truncate table |
905
|
|
|
DB::query("TRUNCATE TABLE ".prefix_table("cache")); |
906
|
|
|
|
907
|
|
|
// reload date |
908
|
|
|
$rows = DB::query( |
909
|
|
|
"SELECT * |
910
|
|
|
FROM ".prefix_table('items')." as i |
911
|
|
|
INNER JOIN ".prefix_table('log_items')." as l ON (l.id_item = i.id) |
912
|
|
|
AND l.action = %s |
913
|
|
|
AND i.inactif = %i", |
914
|
|
|
'at_creation', |
915
|
|
|
0 |
916
|
|
|
); |
917
|
|
|
foreach ($rows as $record) { |
918
|
|
|
// Get all TAGS |
919
|
|
|
$tags = ""; |
920
|
|
|
$itemTags = DB::query("SELECT tag FROM ".prefix_table('tags')." WHERE item_id=%i", $record['id']); |
921
|
|
View Code Duplication |
foreach ($itemTags as $itemTag) { |
922
|
|
|
if (!empty($itemTag['tag'])) { |
923
|
|
|
$tags .= $itemTag['tag']." "; |
924
|
|
|
} |
925
|
|
|
} |
926
|
|
|
// Get renewal period |
927
|
|
|
$resNT = DB::queryfirstrow("SELECT renewal_period FROM ".prefix_table('nested_tree')." WHERE id=%i", $record['id_tree']); |
928
|
|
|
|
929
|
|
|
// form id_tree to full foldername |
930
|
|
|
$folder = ""; |
931
|
|
|
$arbo = $tree->getPath($record['id_tree'], true); |
932
|
|
View Code Duplication |
foreach ($arbo as $elem) { |
933
|
|
|
if ($elem->title == $_SESSION['user_id'] && $elem->nlevel == 1) { |
934
|
|
|
$elem->title = $_SESSION['login']; |
935
|
|
|
} |
936
|
|
|
if (empty($folder)) { |
937
|
|
|
$folder = stripslashes($elem->title); |
938
|
|
|
} else { |
939
|
|
|
$folder .= " » ".stripslashes($elem->title); |
940
|
|
|
} |
941
|
|
|
} |
942
|
|
|
// store data |
943
|
|
|
DB::insert( |
944
|
|
|
prefix_table('cache'), |
945
|
|
|
array( |
946
|
|
|
'id' => $record['id'], |
947
|
|
|
'label' => $record['label'], |
948
|
|
|
'description' => isset($record['description']) ? $record['description'] : "", |
949
|
|
|
'url' => (isset($record['url']) && !empty($record['url'])) ? $record['url'] : "0", |
950
|
|
|
'tags' => $tags, |
951
|
|
|
'id_tree' => $record['id_tree'], |
952
|
|
|
'perso' => $record['perso'], |
953
|
|
|
'restricted_to' => (isset($record['restricted_to']) && !empty($record['restricted_to'])) ? $record['restricted_to'] : "0", |
954
|
|
|
'login' => isset($record['login']) ? $record['login'] : "", |
955
|
|
|
'folder' => $folder, |
956
|
|
|
'author' => $record['id_user'], |
957
|
|
|
'renewal_period' => isset($resNT['renewal_period']) ? $resNT['renewal_period'] : "0", |
958
|
|
|
'timestamp' => $record['date'] |
959
|
|
|
) |
960
|
|
|
); |
961
|
|
|
} |
962
|
|
|
// UPDATE an item |
963
|
|
|
} elseif ($action === "update_value") { |
964
|
|
|
// get new value from db |
965
|
|
|
$data = DB::queryfirstrow( |
966
|
|
|
"SELECT label, description, id_tree, perso, restricted_to, login, url |
967
|
|
|
FROM ".prefix_table('items')." |
968
|
|
|
WHERE id=%i", |
969
|
|
|
$ident |
970
|
|
|
); |
971
|
|
|
// Get all TAGS |
972
|
|
|
$tags = ""; |
973
|
|
|
$itemTags = DB::query("SELECT tag FROM ".prefix_table('tags')." WHERE item_id=%i", $ident); |
974
|
|
View Code Duplication |
foreach ($itemTags as $itemTag) { |
975
|
|
|
if (!empty($itemTag['tag'])) { |
976
|
|
|
$tags .= $itemTag['tag']." "; |
977
|
|
|
} |
978
|
|
|
} |
979
|
|
|
// form id_tree to full foldername |
980
|
|
|
$folder = ""; |
981
|
|
|
$arbo = $tree->getPath($data['id_tree'], true); |
982
|
|
View Code Duplication |
foreach ($arbo as $elem) { |
983
|
|
|
if ($elem->title == $_SESSION['user_id'] && $elem->nlevel == 1) { |
984
|
|
|
$elem->title = $_SESSION['login']; |
985
|
|
|
} |
986
|
|
|
if (empty($folder)) { |
987
|
|
|
$folder = stripslashes($elem->title); |
988
|
|
|
} else { |
989
|
|
|
$folder .= " » ".stripslashes($elem->title); |
990
|
|
|
} |
991
|
|
|
} |
992
|
|
|
// finaly update |
993
|
|
|
DB::update( |
994
|
|
|
prefix_table('cache'), |
995
|
|
|
array( |
996
|
|
|
'label' => $data['label'], |
997
|
|
|
'description' => $data['description'], |
998
|
|
|
'tags' => $tags, |
999
|
|
|
'url' => (isset($data['url']) && !empty($data['url'])) ? $data['url'] : "0", |
1000
|
|
|
'id_tree' => $data['id_tree'], |
1001
|
|
|
'perso' => $data['perso'], |
1002
|
|
|
'restricted_to' => (isset($data['restricted_to']) && !empty($data['restricted_to'])) ? $data['restricted_to'] : "0", |
1003
|
|
|
'login' => isset($data['login']) ? $data['login'] : "", |
1004
|
|
|
'folder' => $folder, |
1005
|
|
|
'author' => $_SESSION['user_id'], |
1006
|
|
|
), |
1007
|
|
|
"id = %i", |
1008
|
|
|
$ident |
1009
|
|
|
); |
1010
|
|
|
// ADD an item |
1011
|
|
|
} elseif ($action === "add_value") { |
1012
|
|
|
// get new value from db |
1013
|
|
|
$data = DB::queryFirstRow( |
1014
|
|
|
"SELECT i.label, i.description, i.id_tree as id_tree, i.perso, i.restricted_to, i.id, i.login, i.url, l.date |
1015
|
|
|
FROM ".prefix_table('items')." as i |
1016
|
|
|
INNER JOIN ".prefix_table('log_items')." as l ON (l.id_item = i.id) |
1017
|
|
|
WHERE i.id = %i |
1018
|
|
|
AND l.action = %s", |
1019
|
|
|
$ident, |
1020
|
|
|
'at_creation' |
1021
|
|
|
); |
1022
|
|
|
// Get all TAGS |
1023
|
|
|
$tags = ""; |
1024
|
|
|
$itemTags = DB::query("SELECT tag FROM ".prefix_table('tags')." WHERE item_id = %i", $ident); |
1025
|
|
View Code Duplication |
foreach ($itemTags as $itemTag) { |
1026
|
|
|
if (!empty($itemTag['tag'])) { |
1027
|
|
|
$tags .= $itemTag['tag']." "; |
1028
|
|
|
} |
1029
|
|
|
} |
1030
|
|
|
// form id_tree to full foldername |
1031
|
|
|
$folder = ""; |
1032
|
|
|
$arbo = $tree->getPath($data['id_tree'], true); |
1033
|
|
View Code Duplication |
foreach ($arbo as $elem) { |
1034
|
|
|
if ($elem->title == $_SESSION['user_id'] && $elem->nlevel == 1) { |
1035
|
|
|
$elem->title = $_SESSION['login']; |
1036
|
|
|
} |
1037
|
|
|
if (empty($folder)) { |
1038
|
|
|
$folder = stripslashes($elem->title); |
1039
|
|
|
} else { |
1040
|
|
|
$folder .= " » ".stripslashes($elem->title); |
1041
|
|
|
} |
1042
|
|
|
} |
1043
|
|
|
// finaly update |
1044
|
|
|
DB::insert( |
1045
|
|
|
prefix_table('cache'), |
1046
|
|
|
array( |
1047
|
|
|
'id' => $data['id'], |
1048
|
|
|
'label' => $data['label'], |
1049
|
|
|
'description' => $data['description'], |
1050
|
|
|
'tags' => (isset($tags) && !empty($tags)) ? $tags : "None", |
1051
|
|
|
'url' => (isset($data['url']) && !empty($data['url'])) ? $data['url'] : "0", |
1052
|
|
|
'id_tree' => $data['id_tree'], |
1053
|
|
|
'perso' => (isset($data['perso']) && !empty($data['perso']) && $data['perso'] !== "None") ? $data['perso'] : "0", |
1054
|
|
|
'restricted_to' => (isset($data['restricted_to']) && !empty($data['restricted_to'])) ? $data['restricted_to'] : "None", |
1055
|
|
|
'login' => isset($data['login']) ? $data['login'] : "", |
1056
|
|
|
'folder' => $folder, |
1057
|
|
|
'author' => $_SESSION['user_id'], |
1058
|
|
|
'timestamp' => $data['date'] |
1059
|
|
|
) |
1060
|
|
|
); |
1061
|
|
|
|
1062
|
|
|
// DELETE an item |
1063
|
|
|
} elseif ($action === "delete_value") { |
1064
|
|
|
DB::delete(prefix_table('cache'), "id = %i", $ident); |
1065
|
|
|
} |
1066
|
|
|
} |
1067
|
|
|
|
1068
|
|
|
/* |
1069
|
|
|
* |
1070
|
|
|
*/ |
1071
|
|
|
function getStatisticsData() |
1072
|
|
|
{ |
1073
|
|
|
global $SETTINGS; |
1074
|
|
|
|
1075
|
|
|
DB::query( |
1076
|
|
|
"SELECT id FROM ".prefix_table("nested_tree")." WHERE personal_folder = %i", |
1077
|
|
|
0 |
1078
|
|
|
); |
1079
|
|
|
$counter_folders = DB::count(); |
1080
|
|
|
|
1081
|
|
|
DB::query( |
1082
|
|
|
"SELECT id FROM ".prefix_table("nested_tree")." WHERE personal_folder = %i", |
1083
|
|
|
1 |
1084
|
|
|
); |
1085
|
|
|
$counter_folders_perso = DB::count(); |
1086
|
|
|
|
1087
|
|
|
DB::query( |
1088
|
|
|
"SELECT id FROM ".prefix_table("items")." WHERE perso = %i", |
1089
|
|
|
0 |
1090
|
|
|
); |
1091
|
|
|
$counter_items = DB::count(); |
1092
|
|
|
|
1093
|
|
|
DB::query( |
1094
|
|
|
"SELECT id FROM ".prefix_table("items")." WHERE perso = %i", |
1095
|
|
|
1 |
1096
|
|
|
); |
1097
|
|
|
$counter_items_perso = DB::count(); |
1098
|
|
|
|
1099
|
|
|
DB::query( |
1100
|
|
|
"SELECT id FROM ".prefix_table("users")."" |
1101
|
|
|
); |
1102
|
|
|
$counter_users = DB::count(); |
1103
|
|
|
|
1104
|
|
|
DB::query( |
1105
|
|
|
"SELECT id FROM ".prefix_table("users")." WHERE admin = %i", |
1106
|
|
|
1 |
1107
|
|
|
); |
1108
|
|
|
$admins = DB::count(); |
1109
|
|
|
|
1110
|
|
|
DB::query( |
1111
|
|
|
"SELECT id FROM ".prefix_table("users")." WHERE gestionnaire = %i", |
1112
|
|
|
1 |
1113
|
|
|
); |
1114
|
|
|
$managers = DB::count(); |
1115
|
|
|
|
1116
|
|
|
DB::query( |
1117
|
|
|
"SELECT id FROM ".prefix_table("users")." WHERE read_only = %i", |
1118
|
|
|
1 |
1119
|
|
|
); |
1120
|
|
|
$readOnly = DB::count(); |
1121
|
|
|
|
1122
|
|
|
// list the languages |
1123
|
|
|
$usedLang = []; |
1124
|
|
|
$tp_languages = DB::query( |
1125
|
|
|
"SELECT name FROM ".prefix_table("languages") |
1126
|
|
|
); |
1127
|
|
|
foreach ($tp_languages as $tp_language) { |
1128
|
|
|
DB::query( |
1129
|
|
|
"SELECT * FROM ".prefix_table("users")." WHERE user_language = %s", |
1130
|
|
|
$tp_language['name'] |
1131
|
|
|
); |
1132
|
|
|
$usedLang[$tp_language['name']] = round((DB::count() * 100 / $counter_users), 0); |
1133
|
|
|
} |
1134
|
|
|
|
1135
|
|
|
// get list of ips |
1136
|
|
|
$usedIp = []; |
1137
|
|
|
$tp_ips = DB::query( |
1138
|
|
|
"SELECT user_ip FROM ".prefix_table("users") |
1139
|
|
|
); |
1140
|
|
|
foreach ($tp_ips as $ip) { |
1141
|
|
|
if (array_key_exists($ip['user_ip'], $usedIp)) { |
1142
|
|
|
$usedIp[$ip['user_ip']] = $usedIp[$ip['user_ip']] + 1; |
1143
|
|
|
} elseif (!empty($ip['user_ip']) && $ip['user_ip'] !== "none") { |
1144
|
|
|
$usedIp[$ip['user_ip']] = 1; |
1145
|
|
|
} |
1146
|
|
|
} |
1147
|
|
|
|
1148
|
|
|
return array( |
1149
|
|
|
"error" => "", |
1150
|
|
|
"stat_phpversion" => phpversion(), |
1151
|
|
|
"stat_folders" => $counter_folders, |
1152
|
|
|
"stat_folders_shared" => intval($counter_folders) - intval($counter_folders_perso), |
1153
|
|
|
"stat_items" => $counter_items, |
1154
|
|
|
"stat_items_shared" => intval($counter_items) - intval($counter_items_perso), |
1155
|
|
|
"stat_users" => $counter_users, |
1156
|
|
|
"stat_admins" => $admins, |
1157
|
|
|
"stat_managers" => $managers, |
1158
|
|
|
"stat_ro" => $readOnly, |
1159
|
|
|
"stat_kb" => $SETTINGS['enable_kb'], |
1160
|
|
|
"stat_pf" => $SETTINGS['enable_pf_feature'], |
1161
|
|
|
"stat_fav" => $SETTINGS['enable_favourites'], |
1162
|
|
|
"stat_teampassversion" => $SETTINGS['cpassman_version'], |
1163
|
|
|
"stat_ldap" => $SETTINGS['ldap_mode'], |
1164
|
|
|
"stat_agses" => $SETTINGS['agses_authentication_enabled'], |
1165
|
|
|
"stat_duo" => $SETTINGS['duo'], |
1166
|
|
|
"stat_suggestion" => $SETTINGS['enable_suggestion'], |
1167
|
|
|
"stat_api" => $SETTINGS['api'], |
1168
|
|
|
"stat_customfields" => $SETTINGS['item_extra_fields'], |
1169
|
|
|
"stat_syslog" => $SETTINGS['syslog_enable'], |
1170
|
|
|
"stat_2fa" => $SETTINGS['google_authentication'], |
1171
|
|
|
"stat_stricthttps" => $SETTINGS['enable_sts'], |
1172
|
|
|
"stat_mysqlversion" => DB::serverVersion(), |
1173
|
|
|
"stat_languages" => $usedLang, |
1174
|
|
|
"stat_country" => $usedIp |
1175
|
|
|
); |
1176
|
|
|
} |
1177
|
|
|
|
1178
|
|
|
/** |
1179
|
|
|
* sendEmail() |
1180
|
|
|
* |
1181
|
|
|
* @return |
1182
|
|
|
*/ |
1183
|
|
|
function sendEmail($subject, $textMail, $email, $textMailAlt = "") |
1184
|
|
|
{ |
1185
|
|
|
global $LANG; |
1186
|
|
|
global $SETTINGS; |
1187
|
|
|
|
1188
|
|
|
// CAse where email not defined |
1189
|
|
|
if ($email === "none") { |
1190
|
|
|
return '"error":"" , "message":"'.$LANG['forgot_my_pw_email_sent'].'"'; |
1191
|
|
|
} |
1192
|
|
|
|
1193
|
|
|
include $SETTINGS['cpassman_dir'].'/includes/config/settings.php'; |
1194
|
|
|
//load library |
1195
|
|
|
$user_language = isset($_SESSION['user_language']) ? $_SESSION['user_language'] : "english"; |
1196
|
|
|
require_once $SETTINGS['cpassman_dir'].'/includes/language/'.$user_language.'.php'; |
1197
|
|
|
require_once $SETTINGS['cpassman_dir'].'/includes/libraries/Email/Phpmailer/PHPMailerAutoload.php'; |
1198
|
|
|
|
1199
|
|
|
// load PHPMailer |
1200
|
|
|
$mail = new PHPMailer(); |
1201
|
|
|
|
1202
|
|
|
// send to user |
1203
|
|
|
$mail->setLanguage("en", "../includes/libraries/Email/Phpmailer/language/"); |
1204
|
|
|
$mail->SMTPDebug = 0; //value 1 can be used to debug - 4 for debuging connections |
1205
|
|
|
$mail->Port = $SETTINGS['email_port']; //COULD BE USED |
1206
|
|
|
$mail->CharSet = "utf-8"; |
1207
|
|
|
if ($SETTINGS['email_security'] === "tls" || $SETTINGS['email_security'] === "ssl") { |
1208
|
|
|
$mail->SMTPSecure = $SETTINGS['email_security']; |
1209
|
|
|
$SMTPAutoTLS = true; |
1210
|
|
|
} else { |
1211
|
|
|
$SMTPAutoTLS = false; |
1212
|
|
|
$mail->SMTPSecure = ""; |
1213
|
|
|
} |
1214
|
|
|
$mail->SMTPAutoTLS = $SMTPAutoTLS; |
1215
|
|
|
$mail->isSmtp(); // send via SMTP |
1216
|
|
|
$mail->Host = $SETTINGS['email_smtp_server']; // SMTP servers |
1217
|
|
|
$mail->SMTPAuth = $SETTINGS['email_smtp_auth'] == '1' ? true : false; // turn on SMTP authentication |
1218
|
|
|
$mail->Username = $SETTINGS['email_auth_username']; // SMTP username |
1219
|
|
|
$mail->Password = $SETTINGS['email_auth_pwd']; // SMTP password |
1220
|
|
|
$mail->From = $SETTINGS['email_from']; |
1221
|
|
|
$mail->FromName = $SETTINGS['email_from_name']; |
1222
|
|
|
|
1223
|
|
|
// Prepare for each person |
1224
|
|
|
$dests = explode(",", $email); |
1225
|
|
|
foreach ($dests as $dest) { |
1226
|
|
|
$mail->addAddress($dest); |
1227
|
|
|
} |
1228
|
|
|
|
1229
|
|
|
$mail->WordWrap = 80; // set word wrap |
1230
|
|
|
$mail->isHtml(true); // send as HTML |
1231
|
|
|
$mail->Subject = $subject; |
1232
|
|
|
$mail->Body = $textMail; |
1233
|
|
|
$mail->AltBody = $textMailAlt; |
1234
|
|
|
// send email |
1235
|
|
|
if (!$mail->send()) { |
1236
|
|
|
return '"error":"error_mail_not_send" , "message":"'.str_replace(array("\n", "\t", "\r"), '', $mail->ErrorInfo).'"'; |
1237
|
|
|
} else { |
1238
|
|
|
return '"error":"" , "message":"'.$LANG['forgot_my_pw_email_sent'].'"'; |
1239
|
|
|
} |
1240
|
|
|
} |
1241
|
|
|
|
1242
|
|
|
/** |
1243
|
|
|
* generateKey() |
1244
|
|
|
* |
1245
|
|
|
* @return |
1246
|
|
|
*/ |
1247
|
|
|
function generateKey() |
1248
|
|
|
{ |
1249
|
|
|
return substr(md5(rand().rand()), 0, 15); |
1250
|
|
|
} |
1251
|
|
|
|
1252
|
|
|
/** |
1253
|
|
|
* dateToStamp() |
1254
|
|
|
* |
1255
|
|
|
* @return |
1256
|
|
|
*/ |
1257
|
|
|
function dateToStamp($date) |
1258
|
|
|
{ |
1259
|
|
|
global $SETTINGS; |
1260
|
|
|
|
1261
|
|
|
$date = date_parse_from_format($SETTINGS['date_format'], $date); |
1262
|
|
|
if ($date['warning_count'] == 0 && $date['error_count'] == 0) { |
1263
|
|
|
return mktime(23, 59, 59, $date['month'], $date['day'], $date['year']); |
1264
|
|
|
} else { |
1265
|
|
|
return false; |
1266
|
|
|
} |
1267
|
|
|
} |
1268
|
|
|
|
1269
|
|
|
function isDate($date) |
1270
|
|
|
{ |
1271
|
|
|
return (strtotime($date) !== false); |
1272
|
|
|
} |
1273
|
|
|
|
1274
|
|
|
/** |
1275
|
|
|
* isUTF8() |
1276
|
|
|
* |
1277
|
|
|
* @return integer is the string in UTF8 format. |
1278
|
|
|
*/ |
1279
|
|
|
|
1280
|
|
|
function isUTF8($string) |
1281
|
|
|
{ |
1282
|
|
|
if (is_array($string) === true) { |
1283
|
|
|
$string = $string['string']; |
1284
|
|
|
} |
1285
|
|
|
return preg_match( |
1286
|
|
|
'%^(?: |
1287
|
|
|
[\x09\x0A\x0D\x20-\x7E] # ASCII |
1288
|
|
|
| [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte |
1289
|
|
|
| \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs |
1290
|
|
|
| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte |
1291
|
|
|
| \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates |
1292
|
|
|
| \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 |
1293
|
|
|
| [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 |
1294
|
|
|
| \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 |
1295
|
|
|
)*$%xs', |
1296
|
|
|
$string |
1297
|
|
|
); |
1298
|
|
|
} |
1299
|
|
|
|
1300
|
|
|
/* |
1301
|
|
|
* FUNCTION |
1302
|
|
|
* permits to prepare data to be exchanged |
1303
|
|
|
*/ |
1304
|
|
|
/** |
1305
|
|
|
* @param string $type |
1306
|
|
|
*/ |
1307
|
|
|
function prepareExchangedData($data, $type) |
1308
|
|
|
{ |
1309
|
|
|
global $SETTINGS; |
1310
|
|
|
|
1311
|
|
|
//load ClassLoader |
1312
|
|
|
require_once $SETTINGS['cpassman_dir'].'/sources/SplClassLoader.php'; |
1313
|
|
|
//Load AES |
1314
|
|
|
$aes = new SplClassLoader('Encryption\Crypt', $SETTINGS['cpassman_dir'].'/includes/libraries'); |
1315
|
|
|
$aes->register(); |
1316
|
|
|
|
1317
|
|
|
if ($type == "encode") { |
1318
|
|
|
if (isset($SETTINGS['encryptClientServer']) |
1319
|
|
|
&& $SETTINGS['encryptClientServer'] === "0" |
1320
|
|
|
) { |
1321
|
|
|
return json_encode( |
1322
|
|
|
$data, |
1323
|
|
|
JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP |
1324
|
|
|
); |
1325
|
|
View Code Duplication |
} else { |
1326
|
|
|
return Encryption\Crypt\aesctr::encrypt( |
1327
|
|
|
json_encode( |
1328
|
|
|
$data, |
1329
|
|
|
JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP |
1330
|
|
|
), |
1331
|
|
|
$_SESSION['key'], |
1332
|
|
|
256 |
1333
|
|
|
); |
1334
|
|
|
} |
1335
|
|
|
} elseif ($type == "decode") { |
1336
|
|
|
if (isset($SETTINGS['encryptClientServer']) |
1337
|
|
|
&& $SETTINGS['encryptClientServer'] === "0" |
1338
|
|
|
) { |
1339
|
|
|
return json_decode( |
1340
|
|
|
$data, |
1341
|
|
|
true |
1342
|
|
|
); |
1343
|
|
|
} else { |
1344
|
|
|
return json_decode( |
1345
|
|
|
Encryption\Crypt\aesctr::decrypt( |
1346
|
|
|
$data, |
1347
|
|
|
$_SESSION['key'], |
1348
|
|
|
256 |
1349
|
|
|
), |
1350
|
|
|
true |
1351
|
|
|
); |
1352
|
|
|
} |
1353
|
|
|
} |
1354
|
|
|
} |
1355
|
|
|
|
1356
|
|
|
function make_thumb($src, $dest, $desired_width) |
1357
|
|
|
{ |
1358
|
|
|
/* read the source image */ |
1359
|
|
|
$source_image = imagecreatefrompng($src); |
1360
|
|
|
$width = imagesx($source_image); |
1361
|
|
|
$height = imagesy($source_image); |
1362
|
|
|
|
1363
|
|
|
/* find the "desired height" of this thumbnail, relative to the desired width */ |
1364
|
|
|
$desired_height = floor($height * ($desired_width / $width)); |
1365
|
|
|
|
1366
|
|
|
/* create a new, "virtual" image */ |
1367
|
|
|
$virtual_image = imagecreatetruecolor($desired_width, $desired_height); |
1368
|
|
|
|
1369
|
|
|
/* copy source image at a resized size */ |
1370
|
|
|
imagecopyresampled($virtual_image, $source_image, 0, 0, 0, 0, $desired_width, $desired_height, $width, $height); |
1371
|
|
|
|
1372
|
|
|
/* create the physical thumbnail image to its destination */ |
1373
|
|
|
imagejpeg($virtual_image, $dest); |
1374
|
|
|
} |
1375
|
|
|
|
1376
|
|
|
/* |
1377
|
|
|
** check table prefix in SQL query |
1378
|
|
|
*/ |
1379
|
|
|
/** |
1380
|
|
|
* @param string $table |
1381
|
|
|
*/ |
1382
|
|
|
function prefix_table($table) |
1383
|
|
|
{ |
1384
|
|
|
global $pre; |
1385
|
|
|
$safeTable = htmlspecialchars($pre.$table); |
1386
|
|
|
if (!empty($safeTable)) { |
1387
|
|
|
// sanitize string |
1388
|
|
|
return $safeTable; |
1389
|
|
|
} else { |
1390
|
|
|
// stop error no table |
1391
|
|
|
return "table_not_exists"; |
1392
|
|
|
} |
1393
|
|
|
} |
1394
|
|
|
|
1395
|
|
|
/* |
1396
|
|
|
* Creates a KEY using PasswordLib |
1397
|
|
|
*/ |
1398
|
|
|
function GenerateCryptKey($size = "", $secure = false, $numerals = false, $capitalize = false, $ambiguous = false, $symbols = false) |
1399
|
|
|
{ |
1400
|
|
|
global $SETTINGS; |
1401
|
|
|
require_once $SETTINGS['cpassman_dir'].'/sources/SplClassLoader.php'; |
1402
|
|
|
|
1403
|
|
|
// load library |
1404
|
|
|
$pwgen = new SplClassLoader('Encryption\PwGen', $SETTINGS['cpassman_dir'].'/includes/libraries'); |
1405
|
|
|
$pwgen->register(); |
1406
|
|
|
$pwgen = new Encryption\PwGen\pwgen(); |
1407
|
|
|
|
1408
|
|
|
// init |
1409
|
|
|
if (!empty($size)) { |
1410
|
|
|
$pwgen->setLength($size); |
1411
|
|
|
} |
1412
|
|
|
if (!empty($secure)) { |
1413
|
|
|
$pwgen->setSecure($secure); |
1414
|
|
|
} |
1415
|
|
|
if (!empty($numerals)) { |
1416
|
|
|
$pwgen->setNumerals($numerals); |
1417
|
|
|
} |
1418
|
|
|
if (!empty($capitalize)) { |
1419
|
|
|
$pwgen->setCapitalize($capitalize); |
1420
|
|
|
} |
1421
|
|
|
if (!empty($ambiguous)) { |
1422
|
|
|
$pwgen->setAmbiguous($ambiguous); |
1423
|
|
|
} |
1424
|
|
|
if (!empty($symbols)) { |
1425
|
|
|
$pwgen->setSymbols($symbols); |
1426
|
|
|
} |
1427
|
|
|
|
1428
|
|
|
// generate and send back |
1429
|
|
|
return $pwgen->generate(); |
1430
|
|
|
} |
1431
|
|
|
|
1432
|
|
|
/* |
1433
|
|
|
* Send sysLOG message |
1434
|
|
|
* @param string $message |
1435
|
|
|
* @param string $host |
1436
|
|
|
*/ |
1437
|
|
|
function send_syslog($message, $host, $port, $component = "teampass") |
1438
|
|
|
{ |
1439
|
|
|
$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); |
1440
|
|
|
$syslog_message = "<123>".date('M d H:i:s ').$component.": ".$message; |
1441
|
|
|
socket_sendto($sock, $syslog_message, strlen($syslog_message), 0, $host, $port); |
1442
|
|
|
socket_close($sock); |
1443
|
|
|
} |
1444
|
|
|
|
1445
|
|
|
|
1446
|
|
|
|
1447
|
|
|
/** |
1448
|
|
|
* logEvents() |
1449
|
|
|
* |
1450
|
|
|
* permits to log events into DB |
1451
|
|
|
* @param string $type |
1452
|
|
|
* @param string $label |
1453
|
|
|
* @param string $field_1 |
1454
|
|
|
*/ |
1455
|
|
|
function logEvents($type, $label, $who, $login = "", $field_1 = null) |
1456
|
|
|
{ |
1457
|
|
|
global $server, $user, $pass, $database, $port, $encoding; |
1458
|
|
|
global $SETTINGS; |
1459
|
|
|
|
1460
|
|
|
if (empty($who)) { |
1461
|
|
|
$who = get_client_ip_server(); |
1462
|
|
|
} |
1463
|
|
|
|
1464
|
|
|
// include librairies & connect to DB |
1465
|
|
|
require_once $SETTINGS['cpassman_dir'].'/includes/libraries/Database/Meekrodb/db.class.php'; |
1466
|
|
|
$pass = defuse_return_decrypted($pass); |
1467
|
|
|
DB::$host = $server; |
1468
|
|
|
DB::$user = $user; |
1469
|
|
|
DB::$password = $pass; |
1470
|
|
|
DB::$dbName = $database; |
1471
|
|
|
DB::$port = $port; |
1472
|
|
|
DB::$encoding = $encoding; |
1473
|
|
|
DB::$error_handler = true; |
1474
|
|
|
$link = mysqli_connect($server, $user, $pass, $database, $port); |
1475
|
|
|
$link->set_charset($encoding); |
1476
|
|
|
|
1477
|
|
|
DB::insert( |
1478
|
|
|
prefix_table("log_system"), |
1479
|
|
|
array( |
1480
|
|
|
'type' => $type, |
1481
|
|
|
'date' => time(), |
1482
|
|
|
'label' => $label, |
1483
|
|
|
'qui' => $who, |
1484
|
|
|
'field_1' => $field_1 === null ? "" : $field_1 |
1485
|
|
|
) |
1486
|
|
|
); |
1487
|
|
|
if (isset($SETTINGS['syslog_enable']) && $SETTINGS['syslog_enable'] == 1) { |
1488
|
|
|
if ($type == "user_mngt") { |
1489
|
|
|
send_syslog( |
1490
|
|
|
"The User ".$login." performed the action of ".$label." to the user ".$field_1." - ".$type, |
1491
|
|
|
$SETTINGS['syslog_host'], |
1492
|
|
|
$SETTINGS['syslog_port'], |
1493
|
|
|
"teampass" |
1494
|
|
|
); |
1495
|
|
|
} else { |
1496
|
|
|
send_syslog( |
1497
|
|
|
"The User ".$login." performed the action of ".$label." - ".$type, |
1498
|
|
|
$SETTINGS['syslog_host'], |
1499
|
|
|
$SETTINGS['syslog_port'], |
1500
|
|
|
"teampass" |
1501
|
|
|
); |
1502
|
|
|
} |
1503
|
|
|
} |
1504
|
|
|
} |
1505
|
|
|
|
1506
|
|
|
/** |
1507
|
|
|
* @param string $item |
1508
|
|
|
* @param string $action |
1509
|
|
|
*/ |
1510
|
|
|
function logItems($ident, $item, $id_user, $action, $login = "", $raison = null, $raison_iv = null, $encryption_type = "") |
1511
|
|
|
{ |
1512
|
|
|
global $server, $user, $pass, $database, $port, $encoding; |
1513
|
|
|
global $SETTINGS; |
1514
|
|
|
|
1515
|
|
|
// include librairies & connect to DB |
1516
|
|
|
require_once $SETTINGS['cpassman_dir'].'/includes/libraries/Database/Meekrodb/db.class.php'; |
1517
|
|
|
$pass = defuse_return_decrypted($pass); |
1518
|
|
|
DB::$host = $server; |
1519
|
|
|
DB::$user = $user; |
1520
|
|
|
DB::$password = $pass; |
1521
|
|
|
DB::$dbName = $database; |
1522
|
|
|
DB::$port = $port; |
1523
|
|
|
DB::$encoding = $encoding; |
1524
|
|
|
DB::$error_handler = true; |
1525
|
|
|
$link = mysqli_connect($server, $user, $pass, $database, $port); |
1526
|
|
|
$link->set_charset($encoding); |
1527
|
|
|
DB::insert( |
1528
|
|
|
prefix_table("log_items"), |
1529
|
|
|
array( |
1530
|
|
|
'id_item' => $ident, |
1531
|
|
|
'date' => time(), |
1532
|
|
|
'id_user' => $id_user, |
1533
|
|
|
'action' => $action, |
1534
|
|
|
'raison' => $raison, |
1535
|
|
|
'raison_iv' => $raison_iv, |
1536
|
|
|
'encryption_type' => $encryption_type |
1537
|
|
|
) |
1538
|
|
|
); |
1539
|
|
|
if (isset($SETTINGS['syslog_enable']) && $SETTINGS['syslog_enable'] == 1) { |
1540
|
|
|
send_syslog( |
1541
|
|
|
"The Item ".$item." was ".$action." by ".$login." ".$raison, |
1542
|
|
|
$SETTINGS['syslog_host'], |
1543
|
|
|
$SETTINGS['syslog_port'], |
1544
|
|
|
"teampass" |
1545
|
|
|
); |
1546
|
|
|
} |
1547
|
|
|
} |
1548
|
|
|
|
1549
|
|
|
/* |
1550
|
|
|
* Function to get the client ip address |
1551
|
|
|
*/ |
1552
|
|
|
function get_client_ip_server() |
1553
|
|
|
{ |
1554
|
|
|
if (getenv('HTTP_CLIENT_IP')) { |
1555
|
|
|
$ipaddress = getenv('HTTP_CLIENT_IP'); |
1556
|
|
|
} elseif (getenv('HTTP_X_FORWARDED_FOR')) { |
1557
|
|
|
$ipaddress = getenv('HTTP_X_FORWARDED_FOR'); |
1558
|
|
|
} elseif (getenv('HTTP_X_FORWARDED')) { |
1559
|
|
|
$ipaddress = getenv('HTTP_X_FORWARDED'); |
1560
|
|
|
} elseif (getenv('HTTP_FORWARDED_FOR')) { |
1561
|
|
|
$ipaddress = getenv('HTTP_FORWARDED_FOR'); |
1562
|
|
|
} elseif (getenv('HTTP_FORWARDED')) { |
1563
|
|
|
$ipaddress = getenv('HTTP_FORWARDED'); |
1564
|
|
|
} elseif (getenv('REMOTE_ADDR')) { |
1565
|
|
|
$ipaddress = getenv('REMOTE_ADDR'); |
1566
|
|
|
} else { |
1567
|
|
|
$ipaddress = 'UNKNOWN'; |
1568
|
|
|
} |
1569
|
|
|
|
1570
|
|
|
return $ipaddress; |
1571
|
|
|
} |
1572
|
|
|
|
1573
|
|
|
/** |
1574
|
|
|
* Escape all HTML, JavaScript, and CSS |
1575
|
|
|
* |
1576
|
|
|
* @param string $input The input string |
1577
|
|
|
* @param string $encoding Which character encoding are we using? |
1578
|
|
|
* @return string |
1579
|
|
|
*/ |
1580
|
|
|
function noHTML($input, $encoding = 'UTF-8') |
1581
|
|
|
{ |
1582
|
|
|
return htmlspecialchars($input, ENT_QUOTES | ENT_XHTML, $encoding, false); |
1583
|
|
|
} |
1584
|
|
|
|
1585
|
|
|
/** |
1586
|
|
|
* handleConfigFile() |
1587
|
|
|
* |
1588
|
|
|
* permits to handle the Teampass config file |
1589
|
|
|
* $action accepts "rebuild" and "update" |
1590
|
|
|
*/ |
1591
|
|
|
function handleConfigFile($action, $field = null, $value = null) |
1592
|
|
|
{ |
1593
|
|
|
global $server, $user, $pass, $database, $port, $encoding; |
1594
|
|
|
global $SETTINGS; |
1595
|
|
|
|
1596
|
|
|
$tp_config_file = "../includes/config/tp.config.php"; |
1597
|
|
|
|
1598
|
|
|
// Load AntiXSS |
1599
|
|
|
require_once $SETTINGS['cpassman_dir'].'/includes/libraries/protect/AntiXSS/AntiXSS.php'; |
1600
|
|
|
$antiXss = new protect\AntiXSS\AntiXSS(); |
|
|
|
|
1601
|
|
|
|
1602
|
|
|
// include librairies & connect to DB |
1603
|
|
|
require_once $SETTINGS['cpassman_dir'].'/includes/libraries/Database/Meekrodb/db.class.php'; |
1604
|
|
|
$pass = defuse_return_decrypted($pass); |
1605
|
|
|
DB::$host = $server; |
1606
|
|
|
DB::$user = $user; |
1607
|
|
|
DB::$password = $pass; |
1608
|
|
|
DB::$dbName = $database; |
1609
|
|
|
DB::$port = $port; |
1610
|
|
|
DB::$encoding = $encoding; |
1611
|
|
|
DB::$error_handler = true; |
1612
|
|
|
$link = mysqli_connect($server, $user, $pass, $database, $port); |
1613
|
|
|
$link->set_charset($encoding); |
1614
|
|
|
|
1615
|
|
|
if (!file_exists($tp_config_file) || $action == "rebuild") { |
1616
|
|
|
// perform a copy |
1617
|
|
|
if (file_exists($tp_config_file)) { |
1618
|
|
|
if (!copy($tp_config_file, $tp_config_file.'.'.date("Y_m_d_His", time()))) { |
1619
|
|
|
return "ERROR: Could not copy file '".$tp_config_file."'"; |
1620
|
|
|
} |
1621
|
|
|
} |
1622
|
|
|
|
1623
|
|
|
// regenerate |
1624
|
|
|
$data = array(); |
1625
|
|
|
$data[0] = "<?php\n"; |
1626
|
|
|
$data[1] = "global \$SETTINGS;\n"; |
1627
|
|
|
$data[2] = "\$SETTINGS = array (\n"; |
1628
|
|
|
$rows = DB::query( |
1629
|
|
|
"SELECT * FROM ".prefix_table("misc")." WHERE type=%s", |
1630
|
|
|
"admin" |
1631
|
|
|
); |
1632
|
|
|
foreach ($rows as $record) { |
1633
|
|
|
array_push($data, " '".$record['intitule']."' => '".$record['valeur']."',\n"); |
1634
|
|
|
} |
1635
|
|
|
array_push($data, ");\n"); |
1636
|
|
|
$data = array_unique($data); |
1637
|
|
|
} elseif ($action == "update" && empty($field) === false) { |
1638
|
|
|
$data = file($tp_config_file); |
1639
|
|
|
$inc = 0; |
1640
|
|
|
$bFound = false; |
1641
|
|
|
foreach ($data as $line) { |
1642
|
|
|
if (stristr($line, ");")) { |
1643
|
|
|
break; |
1644
|
|
|
} |
1645
|
|
|
|
1646
|
|
|
// |
1647
|
|
|
if (stristr($line, "'".$field."' => '")) { |
1648
|
|
|
$data[$inc] = " '".$field."' => '".filter_var($value, FILTER_SANITIZE_STRING)."',\n"; |
1649
|
|
|
$bFound = true; |
1650
|
|
|
break; |
1651
|
|
|
} |
1652
|
|
|
$inc++; |
1653
|
|
|
} |
1654
|
|
|
if ($bFound === false) { |
1655
|
|
|
$data[($inc)] = " '".$field."' => '".filter_var($value, FILTER_SANITIZE_STRING)."',\n);\n"; |
1656
|
|
|
} |
1657
|
|
|
} |
1658
|
|
|
|
1659
|
|
|
// update file |
1660
|
|
|
file_put_contents($tp_config_file, implode('', isset($data) ? $data : array())); |
1661
|
|
|
|
1662
|
|
|
return true; |
1663
|
|
|
} |
1664
|
|
|
|
1665
|
|
|
/* |
1666
|
|
|
** Permits to replace \ to permit correct display |
1667
|
|
|
*/ |
1668
|
|
|
/** |
1669
|
|
|
* @param string $input |
1670
|
|
|
*/ |
1671
|
|
|
function handleBackslash($input) |
1672
|
|
|
{ |
1673
|
|
|
return str_replace("&#92;", "\", $input); |
1674
|
|
|
} |
1675
|
|
|
|
1676
|
|
|
/* |
1677
|
|
|
** Permits to loas settings |
1678
|
|
|
*/ |
1679
|
|
|
function loadSettings() |
1680
|
|
|
{ |
1681
|
|
|
global $SETTINGS; |
1682
|
|
|
|
1683
|
|
|
/* LOAD CPASSMAN SETTINGS */ |
1684
|
|
|
if (!isset($SETTINGS['loaded']) || $SETTINGS['loaded'] != 1) { |
1685
|
|
|
$SETTINGS['duplicate_folder'] = 0; //by default, this is set to 0; |
1686
|
|
|
$SETTINGS['duplicate_item'] = 0; //by default, this is set to 0; |
1687
|
|
|
$SETTINGS['number_of_used_pw'] = 5; //by default, this value is set to 5; |
1688
|
|
|
$settings = array(); |
1689
|
|
|
|
1690
|
|
|
$rows = DB::query( |
1691
|
|
|
"SELECT * FROM ".prefix_table("misc")." WHERE type=%s_type OR type=%s_type2", |
1692
|
|
|
array( |
1693
|
|
|
'type' => "admin", |
1694
|
|
|
'type2' => "settings" |
1695
|
|
|
) |
1696
|
|
|
); |
1697
|
|
|
foreach ($rows as $record) { |
1698
|
|
|
if ($record['type'] == 'admin') { |
1699
|
|
|
$SETTINGS[$record['intitule']] = $record['valeur']; |
1700
|
|
|
} else { |
1701
|
|
|
$settings[$record['intitule']] = $record['valeur']; |
1702
|
|
|
} |
1703
|
|
|
} |
1704
|
|
|
$SETTINGS['loaded'] = 1; |
1705
|
|
|
$SETTINGS['default_session_expiration_time'] = 5; |
1706
|
|
|
} |
1707
|
|
|
} |
1708
|
|
|
|
1709
|
|
|
/* |
1710
|
|
|
** check if folder has custom fields. |
1711
|
|
|
** Ensure that target one also has same custom fields |
1712
|
|
|
*/ |
1713
|
|
|
function checkCFconsistency($source_id, $target_id) |
1714
|
|
|
{ |
1715
|
|
|
$source_cf = array(); |
1716
|
|
|
$rows = DB::QUERY( |
1717
|
|
|
"SELECT id_category |
1718
|
|
|
FROM ".prefix_table("categories_folders")." |
1719
|
|
|
WHERE id_folder = %i", |
1720
|
|
|
$source_id |
1721
|
|
|
); |
1722
|
|
|
foreach ($rows as $record) { |
1723
|
|
|
array_push($source_cf, $record['id_category']); |
1724
|
|
|
} |
1725
|
|
|
|
1726
|
|
|
$target_cf = array(); |
1727
|
|
|
$rows = DB::QUERY( |
1728
|
|
|
"SELECT id_category |
1729
|
|
|
FROM ".prefix_table("categories_folders")." |
1730
|
|
|
WHERE id_folder = %i", |
1731
|
|
|
$target_id |
1732
|
|
|
); |
1733
|
|
|
foreach ($rows as $record) { |
1734
|
|
|
array_push($target_cf, $record['id_category']); |
1735
|
|
|
} |
1736
|
|
|
|
1737
|
|
|
$cf_diff = array_diff($source_cf, $target_cf); |
1738
|
|
|
if (count($cf_diff) > 0) { |
1739
|
|
|
return false; |
1740
|
|
|
} |
1741
|
|
|
|
1742
|
|
|
return true; |
1743
|
|
|
} |
1744
|
|
|
|
1745
|
|
|
/* |
1746
|
|
|
* |
1747
|
|
|
*/ |
1748
|
|
|
function encrypt_or_decrypt_file($filename_to_rework, $filename_status) |
1749
|
|
|
{ |
1750
|
|
|
global $server, $user, $pass, $database, $port, $encoding; |
1751
|
|
|
global $SETTINGS; |
1752
|
|
|
|
1753
|
|
|
// Include librairies & connect to DB |
1754
|
|
|
require_once $SETTINGS['cpassman_dir'].'/includes/libraries/Database/Meekrodb/db.class.php'; |
1755
|
|
|
$pass = defuse_return_decrypted($pass); |
1756
|
|
|
DB::$host = $server; |
1757
|
|
|
DB::$user = $user; |
1758
|
|
|
DB::$password = $pass; |
1759
|
|
|
DB::$dbName = $database; |
1760
|
|
|
DB::$port = $port; |
1761
|
|
|
DB::$encoding = $encoding; |
1762
|
|
|
DB::$error_handler = true; |
1763
|
|
|
$link = mysqli_connect($server, $user, $pass, $database, $port); |
1764
|
|
|
$link->set_charset($encoding); |
1765
|
|
|
|
1766
|
|
|
// Get file info in DB |
1767
|
|
|
$fileInfo = DB::queryfirstrow( |
1768
|
|
|
"SELECT id FROM ".prefix_table("files")." WHERE file = %s", |
1769
|
|
|
filter_var($filename_to_rework, FILTER_SANITIZE_STRING) |
1770
|
|
|
); |
1771
|
|
|
if (empty($fileInfo['id']) === false) { |
1772
|
|
|
// Load PhpEncryption library |
1773
|
|
|
$path_to_encryption = '/includes/libraries/Encryption/Encryption/'; |
1774
|
|
|
require_once $SETTINGS['cpassman_dir'].$path_to_encryption.'Crypto.php'; |
1775
|
|
|
require_once $SETTINGS['cpassman_dir'].$path_to_encryption.'Encoding.php'; |
1776
|
|
|
require_once $SETTINGS['cpassman_dir'].$path_to_encryption.'DerivedKeys.php'; |
1777
|
|
|
require_once $SETTINGS['cpassman_dir'].$path_to_encryption.'Key.php'; |
1778
|
|
|
require_once $SETTINGS['cpassman_dir'].$path_to_encryption.'KeyOrPassword.php'; |
1779
|
|
|
require_once $SETTINGS['cpassman_dir'].$path_to_encryption.'File.php'; |
1780
|
|
|
require_once $SETTINGS['cpassman_dir'].$path_to_encryption.'RuntimeTests.php'; |
1781
|
|
|
require_once $SETTINGS['cpassman_dir'].$path_to_encryption.'KeyProtectedByPassword.php'; |
1782
|
|
|
require_once $SETTINGS['cpassman_dir'].$path_to_encryption.'Core.php'; |
1783
|
|
|
|
1784
|
|
|
// Get KEY |
1785
|
|
|
$ascii_key = file_get_contents(SECUREPATH."/teampass-seckey.txt"); |
1786
|
|
|
|
1787
|
|
|
if (isset($SETTINGS['enable_attachment_encryption']) |
1788
|
|
|
&& $SETTINGS['enable_attachment_encryption'] === "1" && |
1789
|
|
|
isset($filename_status) |
1790
|
|
|
&& ($filename_status === "clear" |
1791
|
|
|
|| $filename_status === "0") |
1792
|
|
|
) { |
1793
|
|
|
// File needs to be encrypted |
1794
|
|
View Code Duplication |
if (file_exists($SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework)) { |
1795
|
|
|
// Make a copy of file |
1796
|
|
|
if (!copy( |
1797
|
|
|
$SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework, |
1798
|
|
|
$SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework.".copy" |
1799
|
|
|
)) { |
1800
|
|
|
exit; |
1801
|
|
|
} else { |
1802
|
|
|
// Do a bck |
1803
|
|
|
copy( |
1804
|
|
|
$SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework, |
1805
|
|
|
$SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework.".bck" |
1806
|
|
|
); |
1807
|
|
|
} |
1808
|
|
|
|
1809
|
|
|
unlink($SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework); |
1810
|
|
|
|
1811
|
|
|
// Now encrypt the file with saltkey |
1812
|
|
|
$err = ''; |
1813
|
|
|
try { |
1814
|
|
|
\Defuse\Crypto\File::encryptFile( |
1815
|
|
|
$SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework.".copy", |
1816
|
|
|
$SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework, |
1817
|
|
|
\Defuse\Crypto\Key::loadFromAsciiSafeString($ascii_key) |
1818
|
|
|
); |
1819
|
|
|
} catch (Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException $ex) { |
1820
|
|
|
$err = "An attack! Either the wrong key was loaded, or the ciphertext has changed since it was created either corrupted in the database or intentionally modified by someone trying to carry out an attack."; |
1821
|
|
|
} catch (Defuse\Crypto\Exception\EnvironmentIsBrokenException $ex) { |
1822
|
|
|
$err = $ex; |
1823
|
|
|
} catch (Defuse\Crypto\Exception\IOException $ex) { |
1824
|
|
|
$err = $ex; |
1825
|
|
|
} |
1826
|
|
|
if (empty($err) === false) { |
1827
|
|
|
echo $err; |
1828
|
|
|
} |
1829
|
|
|
|
1830
|
|
|
unlink($SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework.".copy"); |
1831
|
|
|
|
1832
|
|
|
// update table |
1833
|
|
|
DB::update( |
1834
|
|
|
prefix_table('files'), |
1835
|
|
|
array( |
1836
|
|
|
'status' => 'encrypted' |
1837
|
|
|
), |
1838
|
|
|
"id = %i", |
1839
|
|
|
$fileInfo['id'] |
1840
|
|
|
); |
1841
|
|
|
} |
1842
|
|
|
} elseif (isset($SETTINGS['enable_attachment_encryption']) |
1843
|
|
|
&& $SETTINGS['enable_attachment_encryption'] === "0" |
1844
|
|
|
&& isset($filename_status) |
1845
|
|
|
&& $filename_status === "encrypted" |
1846
|
|
|
) { |
1847
|
|
|
// file needs to be decrypted |
1848
|
|
View Code Duplication |
if (file_exists($SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework)) { |
1849
|
|
|
// make a copy of file |
1850
|
|
|
if (!copy( |
1851
|
|
|
$SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework, |
1852
|
|
|
$SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework.".copy" |
1853
|
|
|
)) { |
1854
|
|
|
exit; |
1855
|
|
|
} else { |
1856
|
|
|
// do a bck |
1857
|
|
|
copy( |
1858
|
|
|
$SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework, |
1859
|
|
|
$SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework.".bck" |
1860
|
|
|
); |
1861
|
|
|
} |
1862
|
|
|
|
1863
|
|
|
unlink($SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework); |
1864
|
|
|
|
1865
|
|
|
// Now encrypt the file with saltkey |
1866
|
|
|
$err = ''; |
1867
|
|
|
try { |
1868
|
|
|
\Defuse\Crypto\File::decryptFile( |
1869
|
|
|
$SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework.".copy", |
1870
|
|
|
$SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework, |
1871
|
|
|
\Defuse\Crypto\Key::loadFromAsciiSafeString($ascii_key) |
1872
|
|
|
); |
1873
|
|
|
} catch (Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException $ex) { |
1874
|
|
|
$err = "An attack! Either the wrong key was loaded, or the ciphertext has changed since it was created either corrupted in the database or intentionally modified by someone trying to carry out an attack."; |
1875
|
|
|
} catch (Defuse\Crypto\Exception\EnvironmentIsBrokenException $ex) { |
1876
|
|
|
$err = $ex; |
1877
|
|
|
} catch (Defuse\Crypto\Exception\IOException $ex) { |
1878
|
|
|
$err = $ex; |
1879
|
|
|
} |
1880
|
|
|
if (empty($err) === false) { |
1881
|
|
|
echo $err; |
1882
|
|
|
} |
1883
|
|
|
|
1884
|
|
|
unlink($SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework.".copy"); |
1885
|
|
|
|
1886
|
|
|
// update table |
1887
|
|
|
DB::update( |
1888
|
|
|
prefix_table('files'), |
1889
|
|
|
array( |
1890
|
|
|
'status' => 'clear' |
1891
|
|
|
), |
1892
|
|
|
"id = %i", |
1893
|
|
|
$fileInfo['id'] |
1894
|
|
|
); |
1895
|
|
|
} |
1896
|
|
|
} |
1897
|
|
|
} |
1898
|
|
|
|
1899
|
|
|
// Exit |
1900
|
|
|
return false; |
1901
|
|
|
} |
1902
|
|
|
|
1903
|
|
|
/** |
1904
|
|
|
* Will encrypte/decrypt a fil eusing Defuse |
1905
|
|
|
* @param string $type can be either encrypt or decrypt |
1906
|
|
|
* @param string $source_file path to source file |
1907
|
|
|
* @param string $target_file path to target file |
1908
|
|
|
* @return string 'true' is success or error message |
1909
|
|
|
*/ |
1910
|
|
|
function prepareFileWithDefuse($type, $source_file, $target_file, $password = '') |
1911
|
|
|
{ |
1912
|
|
|
global $SETTINGS; |
1913
|
|
|
|
1914
|
|
|
// Load AntiXSS |
1915
|
|
|
require_once $SETTINGS['cpassman_dir'].'/includes/libraries/protect/AntiXSS/AntiXSS.php'; |
1916
|
|
|
$antiXss = new protect\AntiXSS\AntiXSS(); |
1917
|
|
|
|
1918
|
|
|
// Protect against bad inputs |
1919
|
|
|
if (is_array($source_file) ||is_array($target_file)) { |
1920
|
|
|
return 'error_cannot_be_array'; |
1921
|
|
|
} |
1922
|
|
|
|
1923
|
|
|
// Sanitize |
1924
|
|
|
$source_file = $antiXss->xss_clean($source_file); |
1925
|
|
|
$target_file = $antiXss->xss_clean($target_file); |
1926
|
|
|
|
1927
|
|
|
// load PhpEncryption library |
1928
|
|
|
$path_to_encryption = '/includes/libraries/Encryption/Encryption/'; |
1929
|
|
|
require_once $SETTINGS['cpassman_dir'].$path_to_encryption.'Crypto.php'; |
1930
|
|
|
require_once $SETTINGS['cpassman_dir'].$path_to_encryption.'Encoding.php'; |
1931
|
|
|
require_once $SETTINGS['cpassman_dir'].$path_to_encryption.'DerivedKeys.php'; |
1932
|
|
|
require_once $SETTINGS['cpassman_dir'].$path_to_encryption.'Key.php'; |
1933
|
|
|
require_once $SETTINGS['cpassman_dir'].$path_to_encryption.'KeyOrPassword.php'; |
1934
|
|
|
require_once $SETTINGS['cpassman_dir'].$path_to_encryption.'File.php'; |
1935
|
|
|
require_once $SETTINGS['cpassman_dir'].$path_to_encryption.'RuntimeTests.php'; |
1936
|
|
|
require_once $SETTINGS['cpassman_dir'].$path_to_encryption.'KeyProtectedByPassword.php'; |
1937
|
|
|
require_once $SETTINGS['cpassman_dir'].$path_to_encryption.'Core.php'; |
1938
|
|
|
|
1939
|
|
|
if (empty($password) === true) { |
1940
|
|
|
/* |
1941
|
|
|
File encryption/decryption is done with the SALTKEY |
1942
|
|
|
*/ |
1943
|
|
|
|
1944
|
|
|
// get KEY |
1945
|
|
|
$ascii_key = file_get_contents(SECUREPATH."/teampass-seckey.txt"); |
1946
|
|
|
|
1947
|
|
|
// Now perform action on the file |
1948
|
|
|
$err = ''; |
1949
|
|
View Code Duplication |
if ($type === 'decrypt') { |
1950
|
|
|
try { |
1951
|
|
|
\Defuse\Crypto\File::decryptFile( |
1952
|
|
|
$source_file, |
|
|
|
|
1953
|
|
|
$target_file, |
|
|
|
|
1954
|
|
|
\Defuse\Crypto\Key::loadFromAsciiSafeString($ascii_key) |
1955
|
|
|
); |
1956
|
|
|
} catch (Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException $ex) { |
1957
|
|
|
$err = "decryption_not_possible"; |
1958
|
|
|
} catch (Defuse\Crypto\Exception\EnvironmentIsBrokenException $ex) { |
1959
|
|
|
$err = $ex; |
1960
|
|
|
} catch (Defuse\Crypto\Exception\IOException $ex) { |
1961
|
|
|
$err = $ex; |
1962
|
|
|
} |
1963
|
|
|
} elseif ($type === 'encrypt') { |
1964
|
|
|
try { |
1965
|
|
|
\Defuse\Crypto\File::encryptFile( |
1966
|
|
|
$source_file, |
|
|
|
|
1967
|
|
|
$target_file, |
|
|
|
|
1968
|
|
|
\Defuse\Crypto\Key::loadFromAsciiSafeString($ascii_key) |
1969
|
|
|
); |
1970
|
|
|
} catch (Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException $ex) { |
1971
|
|
|
$err = "encryption_not_possible"; |
1972
|
|
|
} catch (Defuse\Crypto\Exception\EnvironmentIsBrokenException $ex) { |
1973
|
|
|
$err = $ex; |
1974
|
|
|
} catch (Defuse\Crypto\Exception\IOException $ex) { |
1975
|
|
|
$err = $ex; |
1976
|
|
|
} |
1977
|
|
|
} |
1978
|
|
|
} else { |
1979
|
|
|
/* |
1980
|
|
|
File encryption/decryption is done with special password and not the SALTKEY |
1981
|
|
|
*/ |
1982
|
|
|
|
1983
|
|
|
$err = ''; |
1984
|
|
View Code Duplication |
if ($type === 'decrypt') { |
1985
|
|
|
try { |
1986
|
|
|
\Defuse\Crypto\File::decryptFileWithPassword( |
1987
|
|
|
$source_file, |
|
|
|
|
1988
|
|
|
$target_file, |
|
|
|
|
1989
|
|
|
$password |
1990
|
|
|
); |
1991
|
|
|
} catch (Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException $ex) { |
1992
|
|
|
$err = "wrong_key"; |
1993
|
|
|
} catch (Defuse\Crypto\Exception\EnvironmentIsBrokenException $ex) { |
1994
|
|
|
$err = $ex; |
1995
|
|
|
} catch (Defuse\Crypto\Exception\IOException $ex) { |
1996
|
|
|
$err = $ex; |
1997
|
|
|
} |
1998
|
|
|
} elseif ($type === 'encrypt') { |
1999
|
|
|
try { |
2000
|
|
|
\Defuse\Crypto\File::encryptFileWithPassword( |
2001
|
|
|
$source_file, |
|
|
|
|
2002
|
|
|
$target_file, |
|
|
|
|
2003
|
|
|
$password |
2004
|
|
|
); |
2005
|
|
|
} catch (Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException $ex) { |
2006
|
|
|
$err = "wrong_key"; |
2007
|
|
|
} catch (Defuse\Crypto\Exception\EnvironmentIsBrokenException $ex) { |
2008
|
|
|
$err = $ex; |
2009
|
|
|
} catch (Defuse\Crypto\Exception\IOException $ex) { |
2010
|
|
|
$err = $ex; |
2011
|
|
|
} |
2012
|
|
|
} |
2013
|
|
|
} |
2014
|
|
|
|
2015
|
|
|
// return error |
2016
|
|
|
if (empty($err) === false) { |
2017
|
|
|
return $err; |
2018
|
|
|
} else { |
2019
|
|
|
return true; |
2020
|
|
|
} |
2021
|
|
|
} |
2022
|
|
|
|
2023
|
|
|
/* |
2024
|
|
|
* NOT TO BE USED |
2025
|
|
|
*/ |
2026
|
|
|
function debugTeampass($text) |
2027
|
|
|
{ |
2028
|
|
|
$debugFile = fopen('D:/wamp64/www/TeamPass/debug.txt', 'r+'); |
2029
|
|
|
fputs($debugFile, $text); |
2030
|
|
|
fclose($debugFile); |
2031
|
|
|
} |
2032
|
|
|
|
2033
|
|
|
|
2034
|
|
|
/** |
2035
|
|
|
* DELETE the file with expected command depending on server type |
2036
|
|
|
* @param string $file Path to file |
2037
|
|
|
* @return Nothing |
2038
|
|
|
*/ |
2039
|
|
|
function fileDelete($file) |
2040
|
|
|
{ |
2041
|
|
|
global $SETTINGS; |
2042
|
|
|
|
2043
|
|
|
// Load AntiXSS |
2044
|
|
|
require_once $SETTINGS['cpassman_dir'].'/includes/libraries/protect/AntiXSS/AntiXSS.php'; |
2045
|
|
|
$antiXss = new protect\AntiXSS\AntiXSS(); |
2046
|
|
|
|
2047
|
|
|
$file = $antiXss->xss_clean($file); |
2048
|
|
|
if (is_file($file)) { |
2049
|
|
|
unlink($file); |
2050
|
|
|
} |
2051
|
|
|
} |
2052
|
|
|
|
2053
|
|
|
/* |
2054
|
|
|
* Permits to extract the file extension |
2055
|
|
|
*/ |
2056
|
|
|
function getFileExtension($file) |
2057
|
|
|
{ |
2058
|
|
|
if (strpos($file, '.') === false) { |
2059
|
|
|
return $file; |
2060
|
|
|
} |
2061
|
|
|
|
2062
|
|
|
return substr($file, strrpos($file, '.') + 1); |
2063
|
|
|
} |
2064
|
|
|
|
2065
|
|
|
/** |
2066
|
|
|
* array_map |
2067
|
|
|
* @param [type] $func [description] |
|
|
|
|
2068
|
|
|
* @param [type] $arr [description] |
|
|
|
|
2069
|
|
|
* @return [type] [description] |
|
|
|
|
2070
|
|
|
*/ |
2071
|
|
|
function array_map_r($func, $arr) |
2072
|
|
|
{ |
2073
|
|
|
$newArr = array(); |
2074
|
|
|
|
2075
|
|
|
foreach ($arr as $key => $value) { |
2076
|
|
|
$newArr[ $key ] = (is_array($value) ? array_map_r($func, $value) : ( is_array($func) ? call_user_func_array($func, $value) : $func( $value ))); |
2077
|
|
|
} |
2078
|
|
|
|
2079
|
|
|
return $newArr; |
2080
|
|
|
} |
2081
|
|
|
|
2082
|
|
|
/** |
2083
|
|
|
* Permits to clean and sanitize text to be displayed |
2084
|
|
|
* @param string $text text to clean |
|
|
|
|
2085
|
|
|
* @param string $type what clean to perform |
2086
|
|
|
* @return string text cleaned up |
2087
|
|
|
*/ |
2088
|
|
|
function cleanText($string, $type = "") |
2089
|
|
|
{ |
2090
|
|
|
global $SETTINGS; |
2091
|
|
|
|
2092
|
|
|
// Load AntiXSS |
2093
|
|
|
require_once $SETTINGS['cpassman_dir'].'/includes/libraries/protect/AntiXSS/AntiXSS.php'; |
2094
|
|
|
$antiXss = new protect\AntiXSS\AntiXSS(); |
2095
|
|
|
|
2096
|
|
|
if ($type === "css") { |
2097
|
|
|
// Escape text and quotes in UTF8 format |
2098
|
|
|
return htmlentities($string, ENT_QUOTES | ENT_HTML5, 'UTF-8'); |
2099
|
|
|
} elseif ($type === "html" || empty($type)) { |
2100
|
|
|
// Html cleaner |
2101
|
|
|
return $antiXss->xss_clean($string); |
2102
|
|
|
} |
2103
|
|
|
} |
2104
|
|
|
|
2105
|
|
|
/** |
2106
|
|
|
* Performs chmod operation on subfolders |
2107
|
|
|
* @param string $dir Parent folder |
2108
|
|
|
* @param integer $dirPermissions New permission on folders |
2109
|
|
|
* @param integer $filePermissions New permission on files |
2110
|
|
|
* @return boolean Success/Failure |
2111
|
|
|
*/ |
2112
|
|
View Code Duplication |
function chmodRecursive($dir, $dirPermissions, $filePermissions) |
|
|
|
|
2113
|
|
|
{ |
2114
|
|
|
$pointer_dir = opendir($dir); |
|
|
|
|
2115
|
|
|
$res = true; |
2116
|
|
|
while ($file = readdir($pointer_dir)) { |
2117
|
|
|
if (($file == ".") || ($file == "..")) { |
2118
|
|
|
continue; |
2119
|
|
|
} |
2120
|
|
|
|
2121
|
|
|
$fullPath = $dir."/".$file; |
2122
|
|
|
|
2123
|
|
|
if (is_dir($fullPath)) { |
2124
|
|
|
if ($res = @chmod($fullPath, $dirPermissions)) { |
|
|
|
|
2125
|
|
|
$res = @chmodRecursive($fullPath, $dirPermissions, $filePermissions); |
2126
|
|
|
} |
2127
|
|
|
} else { |
2128
|
|
|
$res = chmod($fullPath, $filePermissions); |
|
|
|
|
2129
|
|
|
} |
2130
|
|
|
if (!$res) { |
2131
|
|
|
closedir($pointer_dir); |
2132
|
|
|
return false; |
2133
|
|
|
} |
2134
|
|
|
} |
2135
|
|
|
closedir($pointer_dir); |
2136
|
|
|
if (is_dir($dir) && $res) { |
2137
|
|
|
$res = @chmod($dir, $dirPermissions); |
|
|
|
|
2138
|
|
|
} |
2139
|
|
|
|
2140
|
|
|
return $res; |
2141
|
|
|
} |
2142
|
|
|
|
2143
|
|
|
/** |
2144
|
|
|
* Check if user can access to this item |
2145
|
|
|
* @param $item_id |
2146
|
|
|
*/ |
2147
|
|
|
function accessToItemIsGranted($item_id) |
2148
|
|
|
{ |
2149
|
|
|
global $SETTINGS; |
2150
|
|
|
|
2151
|
|
|
require_once $SETTINGS['cpassman_dir'].'/includes/libraries/protect/SuperGlobal/SuperGlobal.php'; |
2152
|
|
|
$superGlobal = new protect\SuperGlobal\SuperGlobal(); |
2153
|
|
|
|
2154
|
|
|
// Prepare superGlobal variables |
2155
|
|
|
$session_groupes_visibles = $superGlobal->get("groupes_visibles", "SESSION"); |
2156
|
|
|
$session_list_restricted_folders_for_items = $superGlobal->get("list_restricted_folders_for_items", "SESSION"); |
2157
|
|
|
|
2158
|
|
|
// Load item data |
2159
|
|
|
$data = DB::queryFirstRow( |
2160
|
|
|
"SELECT id_tree |
2161
|
|
|
FROM ".prefix_table("items")." |
2162
|
|
|
WHERE id = %i", |
2163
|
|
|
$item_id |
2164
|
|
|
); |
2165
|
|
|
|
2166
|
|
|
// Check if user can access this folder |
2167
|
|
|
if (in_array($data['id_tree'], $session_groupes_visibles) === false) { |
2168
|
|
|
// Now check if this folder is restricted to user |
2169
|
|
|
if (isset($session_list_restricted_folders_for_items[$data['id_tree']]) |
2170
|
|
|
&& !in_array($item_id, $session_list_restricted_folders_for_items[$data['id_tree']]) |
2171
|
|
|
) { |
2172
|
|
|
return "ERR_FOLDER_NOT_ALLOWED"; |
2173
|
|
|
} else { |
2174
|
|
|
return "ERR_FOLDER_NOT_ALLOWED"; |
2175
|
|
|
} |
2176
|
|
|
} |
2177
|
|
|
|
2178
|
|
|
return true; |
2179
|
|
|
} |
2180
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.