|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* @author Nils Laumaillé <[email protected]> |
|
4
|
|
|
* |
|
5
|
|
|
* @version 2.1.27 |
|
6
|
|
|
* |
|
7
|
|
|
* @copyright 2009-2018 Nils Laumaillé |
|
8
|
|
|
* @license GNU GPL-3.0 |
|
9
|
|
|
* |
|
10
|
|
|
* @see |
|
11
|
|
|
*/ |
|
12
|
|
|
if (!isset($_SESSION['CPM']) || $_SESSION['CPM'] != 1) { |
|
13
|
|
|
die('Hacking attempt...'); |
|
14
|
|
|
} |
|
15
|
|
|
|
|
16
|
|
|
// Load config if $SETTINGS not defined |
|
17
|
|
|
if (!isset($SETTINGS['cpassman_dir']) || empty($SETTINGS['cpassman_dir'])) { |
|
18
|
|
|
if (file_exists('../includes/config/tp.config.php')) { |
|
19
|
|
|
include_once '../includes/config/tp.config.php'; |
|
20
|
|
|
} elseif (file_exists('./includes/config/tp.config.php')) { |
|
21
|
|
|
include_once './includes/config/tp.config.php'; |
|
22
|
|
|
} elseif (file_exists('../../includes/config/tp.config.php')) { |
|
23
|
|
|
include_once '../../includes/config/tp.config.php'; |
|
24
|
|
|
} else { |
|
25
|
|
|
throw new Exception("Error file '/includes/config/tp.config.php' not exists", 1); |
|
26
|
|
|
} |
|
27
|
|
|
} |
|
28
|
|
|
|
|
29
|
|
|
// load phpCrypt |
|
30
|
|
|
if (!isset($SETTINGS['cpassman_dir']) || empty($SETTINGS['cpassman_dir'])) { |
|
31
|
|
|
include_once '../includes/libraries/phpcrypt/phpCrypt.php'; |
|
32
|
|
|
include_once '../includes/config/settings.php'; |
|
33
|
|
|
} else { |
|
34
|
|
|
include_once $SETTINGS['cpassman_dir'].'/includes/libraries/phpcrypt/phpCrypt.php'; |
|
35
|
|
|
include_once $SETTINGS['cpassman_dir'].'/includes/config/settings.php'; |
|
36
|
|
|
} |
|
37
|
|
|
|
|
38
|
|
|
header('Content-type: text/html; charset=utf-8'); |
|
39
|
|
|
header('Cache-Control: no-cache, must-revalidate'); |
|
40
|
|
|
|
|
41
|
|
|
// Prepare PHPCrypt class calls |
|
42
|
|
|
use PHP_Crypt\PHP_Crypt as PHP_Crypt; |
|
43
|
|
|
|
|
44
|
|
|
/** |
|
45
|
|
|
* Convert language code to string. |
|
46
|
|
|
* |
|
47
|
|
|
* @param string $string String to get |
|
48
|
|
|
* |
|
49
|
|
|
* @return string |
|
50
|
|
|
*/ |
|
51
|
|
|
function langHdl($string) |
|
52
|
|
|
{ |
|
53
|
|
|
// Clean the string to convert |
|
54
|
|
|
$string = trim($string); |
|
55
|
|
|
|
|
56
|
|
|
if (empty($string) === true || isset($_SESSION['teampass']['lang'][$string]) === false) { |
|
57
|
|
|
// Manage error |
|
58
|
|
|
return 'ERROR in language strings!'; |
|
59
|
|
|
} else { |
|
60
|
|
|
return str_replace( |
|
61
|
|
|
array('"', "'"), |
|
62
|
|
|
array('"', '''), |
|
63
|
|
|
$_SESSION['teampass']['lang'][$string] |
|
64
|
|
|
); |
|
65
|
|
|
} |
|
66
|
|
|
} |
|
67
|
|
|
|
|
68
|
|
|
//Generate N# of random bits for use as salt |
|
69
|
|
|
/** |
|
70
|
|
|
* Undocumented function. |
|
71
|
|
|
* |
|
72
|
|
|
* @param int $size Length |
|
73
|
|
|
* |
|
74
|
|
|
* @return array |
|
75
|
|
|
*/ |
|
76
|
|
|
function getBits($size) |
|
77
|
|
|
{ |
|
78
|
|
|
$str = ''; |
|
79
|
|
|
$var_x = $size + 10; |
|
80
|
|
|
for ($var_i = 0; $var_i < $var_x; ++$var_i) { |
|
81
|
|
|
$str .= base_convert(mt_rand(1, 36), 10, 36); |
|
82
|
|
|
} |
|
83
|
|
|
|
|
84
|
|
|
return substr($str, 0, $size); |
|
|
|
|
|
|
85
|
|
|
} |
|
86
|
|
|
|
|
87
|
|
|
//generate pbkdf2 compliant hash |
|
88
|
|
|
function strHashPbkdf2($var_p, $var_s, $var_c, $var_kl, $var_a = 'sha256', $var_st = 0) |
|
89
|
|
|
{ |
|
90
|
|
|
$var_kb = $var_st + $var_kl; // Key blocks to compute |
|
91
|
|
|
$var_dk = ''; // Derived key |
|
92
|
|
|
|
|
93
|
|
|
for ($block = 1; $block <= $var_kb; ++$block) { // Create key |
|
94
|
|
|
$var_ib = $var_h = hash_hmac($var_a, $var_s.pack('N', $block), $var_p, true); // Initial hash for this block |
|
95
|
|
|
for ($var_i = 1; $var_i < $var_c; ++$var_i) { // Perform block iterations |
|
96
|
|
|
$var_ib ^= ($var_h = hash_hmac($var_a, $var_h, $var_p, true)); // XOR each iterate |
|
97
|
|
|
} |
|
98
|
|
|
$var_dk .= $var_ib; // Append iterated block |
|
99
|
|
|
} |
|
100
|
|
|
|
|
101
|
|
|
return substr($var_dk, $var_st, $var_kl); // Return derived key of correct length |
|
102
|
|
|
} |
|
103
|
|
|
|
|
104
|
|
|
/** |
|
105
|
|
|
* stringUtf8Decode(). |
|
106
|
|
|
* |
|
107
|
|
|
* utf8_decode |
|
108
|
|
|
*/ |
|
109
|
|
|
function stringUtf8Decode($string) |
|
110
|
|
|
{ |
|
111
|
|
|
return str_replace(' ', '+', utf8_decode($string)); |
|
112
|
|
|
} |
|
113
|
|
|
|
|
114
|
|
|
/** |
|
115
|
|
|
* encryptOld(). |
|
116
|
|
|
* |
|
117
|
|
|
* crypt a string |
|
118
|
|
|
* |
|
119
|
|
|
* @param string $text |
|
120
|
|
|
*/ |
|
121
|
|
|
function encryptOld($text, $personalSalt = '') |
|
122
|
|
|
{ |
|
123
|
|
|
if (empty($personalSalt) === false) { |
|
124
|
|
|
return trim( |
|
125
|
|
|
base64_encode( |
|
126
|
|
|
mcrypt_encrypt( |
|
|
|
|
|
|
127
|
|
|
MCRYPT_RIJNDAEL_256, |
|
128
|
|
|
$personalSalt, |
|
129
|
|
|
$text, |
|
130
|
|
|
MCRYPT_MODE_ECB, |
|
131
|
|
|
mcrypt_create_iv( |
|
|
|
|
|
|
132
|
|
|
mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), |
|
|
|
|
|
|
133
|
|
|
MCRYPT_RAND |
|
134
|
|
|
) |
|
135
|
|
|
) |
|
136
|
|
|
) |
|
137
|
|
|
); |
|
138
|
|
|
} |
|
139
|
|
|
|
|
140
|
|
|
// If $personalSalt is not empty |
|
141
|
|
|
return trim( |
|
142
|
|
|
base64_encode( |
|
143
|
|
|
mcrypt_encrypt( |
|
|
|
|
|
|
144
|
|
|
MCRYPT_RIJNDAEL_256, |
|
145
|
|
|
SALT, |
|
146
|
|
|
$text, |
|
147
|
|
|
MCRYPT_MODE_ECB, |
|
148
|
|
|
mcrypt_create_iv( |
|
|
|
|
|
|
149
|
|
|
mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), |
|
|
|
|
|
|
150
|
|
|
MCRYPT_RAND |
|
151
|
|
|
) |
|
152
|
|
|
) |
|
153
|
|
|
) |
|
154
|
|
|
); |
|
155
|
|
|
} |
|
156
|
|
|
|
|
157
|
|
|
/** |
|
158
|
|
|
* decryptOld(). |
|
159
|
|
|
* |
|
160
|
|
|
* decrypt a crypted string |
|
161
|
|
|
*/ |
|
162
|
|
|
function decryptOld($text, $personalSalt = '') |
|
163
|
|
|
{ |
|
164
|
|
|
if (!empty($personalSalt)) { |
|
165
|
|
|
return trim( |
|
166
|
|
|
mcrypt_decrypt( |
|
|
|
|
|
|
167
|
|
|
MCRYPT_RIJNDAEL_256, |
|
168
|
|
|
$personalSalt, |
|
169
|
|
|
base64_decode($text), |
|
170
|
|
|
MCRYPT_MODE_ECB, |
|
171
|
|
|
mcrypt_create_iv( |
|
|
|
|
|
|
172
|
|
|
mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), |
|
|
|
|
|
|
173
|
|
|
MCRYPT_RAND |
|
174
|
|
|
) |
|
175
|
|
|
) |
|
176
|
|
|
); |
|
177
|
|
|
} |
|
178
|
|
|
|
|
179
|
|
|
// No personal SK |
|
180
|
|
|
return trim( |
|
181
|
|
|
mcrypt_decrypt( |
|
|
|
|
|
|
182
|
|
|
MCRYPT_RIJNDAEL_256, |
|
183
|
|
|
SALT, |
|
184
|
|
|
base64_decode($text), |
|
185
|
|
|
MCRYPT_MODE_ECB, |
|
186
|
|
|
mcrypt_create_iv( |
|
|
|
|
|
|
187
|
|
|
mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), |
|
|
|
|
|
|
188
|
|
|
MCRYPT_RAND |
|
189
|
|
|
) |
|
190
|
|
|
) |
|
191
|
|
|
); |
|
192
|
|
|
} |
|
193
|
|
|
|
|
194
|
|
|
/** |
|
195
|
|
|
* encrypt(). |
|
196
|
|
|
* |
|
197
|
|
|
* crypt a string |
|
198
|
|
|
* |
|
199
|
|
|
* @param string $decrypted |
|
200
|
|
|
*/ |
|
201
|
|
|
function encrypt($decrypted, $personalSalt = '') |
|
202
|
|
|
{ |
|
203
|
|
|
global $SETTINGS; |
|
204
|
|
|
|
|
205
|
|
|
if (!isset($SETTINGS['cpassman_dir']) || empty($SETTINGS['cpassman_dir'])) { |
|
206
|
|
|
require_once '../includes/libraries/Encryption/PBKDF2/PasswordHash.php'; |
|
207
|
|
|
} else { |
|
208
|
|
|
require_once $SETTINGS['cpassman_dir'].'/includes/libraries/Encryption/PBKDF2/PasswordHash.php'; |
|
209
|
|
|
} |
|
210
|
|
|
|
|
211
|
|
|
if (!empty($personalSalt)) { |
|
212
|
|
|
$staticSalt = $personalSalt; |
|
213
|
|
|
} else { |
|
214
|
|
|
$staticSalt = SALT; |
|
215
|
|
|
} |
|
216
|
|
|
|
|
217
|
|
|
//set our salt to a variable |
|
218
|
|
|
// Get 64 random bits for the salt for pbkdf2 |
|
219
|
|
|
$pbkdf2Salt = getBits(64); |
|
220
|
|
|
// generate a pbkdf2 key to use for the encryption. |
|
221
|
|
|
$key = substr(pbkdf2('sha256', $staticSalt, $pbkdf2Salt, ITCOUNT, 16 + 32, true), 32, 16); |
|
222
|
|
|
// Build $init_vect and $ivBase64. We use a block size of 256 bits (AES compliant) |
|
223
|
|
|
// and CTR mode. (Note: ECB mode is inadequate as IV is not used.) |
|
224
|
|
|
$init_vect = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, 'ctr'), MCRYPT_RAND); |
|
|
|
|
|
|
225
|
|
|
|
|
226
|
|
|
//base64 trim |
|
227
|
|
|
if (strlen($ivBase64 = rtrim(base64_encode($init_vect), '=')) != 43) { |
|
228
|
|
|
return false; |
|
229
|
|
|
} |
|
230
|
|
|
// Encrypt $decrypted |
|
231
|
|
|
$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $decrypted, 'ctr', $init_vect); |
|
|
|
|
|
|
232
|
|
|
// MAC the encrypted text |
|
233
|
|
|
$mac = hash_hmac('sha256', $encrypted, $staticSalt); |
|
234
|
|
|
// We're done! |
|
235
|
|
|
return base64_encode($ivBase64.$encrypted.$mac.$pbkdf2Salt); |
|
|
|
|
|
|
236
|
|
|
} |
|
237
|
|
|
|
|
238
|
|
|
/** |
|
239
|
|
|
* decrypt(). |
|
240
|
|
|
* |
|
241
|
|
|
* decrypt a crypted string |
|
242
|
|
|
*/ |
|
243
|
|
|
function decrypt($encrypted, $personalSalt = '') |
|
244
|
|
|
{ |
|
245
|
|
|
global $SETTINGS; |
|
246
|
|
|
|
|
247
|
|
|
if (!isset($SETTINGS['cpassman_dir']) || empty($SETTINGS['cpassman_dir'])) { |
|
248
|
|
|
include_once '../includes/libraries/Encryption/PBKDF2/PasswordHash.php'; |
|
249
|
|
|
} else { |
|
250
|
|
|
include_once $SETTINGS['cpassman_dir'].'/includes/libraries/Encryption/PBKDF2/PasswordHash.php'; |
|
251
|
|
|
} |
|
252
|
|
|
|
|
253
|
|
|
if (!empty($personalSalt)) { |
|
254
|
|
|
$staticSalt = $personalSalt; |
|
255
|
|
|
} else { |
|
256
|
|
|
$staticSalt = file_get_contents(SECUREPATH.'/teampass-seckey.txt'); |
|
257
|
|
|
} |
|
258
|
|
|
//base64 decode the entire payload |
|
259
|
|
|
$encrypted = base64_decode($encrypted); |
|
260
|
|
|
// get the salt |
|
261
|
|
|
$pbkdf2Salt = substr($encrypted, -64); |
|
262
|
|
|
//remove the salt from the string |
|
263
|
|
|
$encrypted = substr($encrypted, 0, -64); |
|
264
|
|
|
$key = substr(pbkdf2('sha256', $staticSalt, $pbkdf2Salt, ITCOUNT, 16 + 32, true), 32, 16); |
|
265
|
|
|
// Retrieve $init_vect which is the first 22 characters plus ==, base64_decoded. |
|
266
|
|
|
$init_vect = base64_decode(substr($encrypted, 0, 43).'=='); |
|
267
|
|
|
// Remove $init_vect from $encrypted. |
|
268
|
|
|
$encrypted = substr($encrypted, 43); |
|
269
|
|
|
// Retrieve $mac which is the last 64 characters of $encrypted. |
|
270
|
|
|
$mac = substr($encrypted, -64); |
|
271
|
|
|
// Remove the last 64 chars from encrypted (remove MAC) |
|
272
|
|
|
$encrypted = substr($encrypted, 0, -64); |
|
273
|
|
|
//verify the sha256hmac from the encrypted data before even trying to decrypt it |
|
274
|
|
|
if (hash_hmac('sha256', $encrypted, $staticSalt) != $mac) { |
|
275
|
|
|
return false; |
|
276
|
|
|
} |
|
277
|
|
|
// Decrypt the data. |
|
278
|
|
|
$decrypted = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $encrypted, 'ctr', $init_vect), "\0\4"); |
|
|
|
|
|
|
279
|
|
|
// Yay! |
|
280
|
|
|
return $decrypted; |
|
281
|
|
|
} |
|
282
|
|
|
|
|
283
|
|
|
/** |
|
284
|
|
|
* genHash(). |
|
285
|
|
|
* |
|
286
|
|
|
* Generate a hash for user login |
|
287
|
|
|
* |
|
288
|
|
|
* @param string $password |
|
289
|
|
|
*/ |
|
290
|
|
|
function bCrypt($password, $cost) |
|
291
|
|
|
{ |
|
292
|
|
|
$salt = sprintf('$2y$%02d$', $cost); |
|
293
|
|
|
if (function_exists('openssl_random_pseudo_bytes')) { |
|
294
|
|
|
$salt .= bin2hex(openssl_random_pseudo_bytes(11)); |
|
295
|
|
|
} else { |
|
296
|
|
|
$chars = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; |
|
297
|
|
|
for ($i = 0; $i < 22; ++$i) { |
|
298
|
|
|
$salt .= $chars[mt_rand(0, 63)]; |
|
299
|
|
|
} |
|
300
|
|
|
} |
|
301
|
|
|
|
|
302
|
|
|
return crypt($password, $salt); |
|
303
|
|
|
} |
|
304
|
|
|
|
|
305
|
|
|
/* |
|
306
|
|
|
* cryption() - Encrypt and decrypt string based upon phpCrypt library |
|
307
|
|
|
* |
|
308
|
|
|
* Using AES_128 and mode CBC |
|
309
|
|
|
* |
|
310
|
|
|
* $key and $init_vect have to be given in hex format |
|
311
|
|
|
*/ |
|
312
|
|
|
function cryption_phpCrypt($string, $key, $init_vect, $type) |
|
313
|
|
|
{ |
|
314
|
|
|
// manage key origin |
|
315
|
|
|
if (null != SALT && $key != SALT) { |
|
316
|
|
|
// check key (AES-128 requires a 16 bytes length key) |
|
317
|
|
|
if (strlen($key) < 16) { |
|
318
|
|
|
for ($inc = strlen($key) + 1; $inc <= 16; ++$inc) { |
|
319
|
|
|
$key .= chr(0); |
|
320
|
|
|
} |
|
321
|
|
|
} elseif (strlen($key) > 16) { |
|
322
|
|
|
$key = substr($key, 16); |
|
323
|
|
|
} |
|
324
|
|
|
} |
|
325
|
|
|
|
|
326
|
|
|
// load crypt |
|
327
|
|
|
$crypt = new PHP_Crypt($key, PHP_Crypt::CIPHER_AES_128, PHP_Crypt::MODE_CBC); |
|
328
|
|
|
|
|
329
|
|
|
if ($type === 'encrypt') { |
|
330
|
|
|
// generate IV and encrypt |
|
331
|
|
|
$init_vect = $crypt->createIV(); |
|
332
|
|
|
$encrypt = $crypt->encrypt($string); |
|
333
|
|
|
// return |
|
334
|
|
|
return array( |
|
335
|
|
|
'string' => bin2hex($encrypt), |
|
336
|
|
|
'iv' => bin2hex($init_vect), |
|
337
|
|
|
'error' => empty($encrypt) ? 'ERR_ENCRYPTION_NOT_CORRECT' : '', |
|
338
|
|
|
); |
|
339
|
|
|
} elseif ($type === 'decrypt') { |
|
340
|
|
|
// case if IV is empty |
|
341
|
|
|
if (empty($init_vect)) { |
|
342
|
|
|
return array( |
|
343
|
|
|
'string' => '', |
|
344
|
|
|
'error' => 'ERR_ENCRYPTION_NOT_CORRECT', |
|
345
|
|
|
); |
|
346
|
|
|
} |
|
347
|
|
|
|
|
348
|
|
|
// convert |
|
349
|
|
|
try { |
|
350
|
|
|
$string = testHex2Bin(trim($string)); |
|
351
|
|
|
$init_vect = testHex2Bin($init_vect); |
|
352
|
|
|
} catch (Exception $e) { |
|
353
|
|
|
return array( |
|
354
|
|
|
'string' => '', |
|
355
|
|
|
'error' => 'ERR_ENCRYPTION_NOT_CORRECT', |
|
356
|
|
|
); |
|
357
|
|
|
} |
|
358
|
|
|
|
|
359
|
|
|
// load IV |
|
360
|
|
|
$crypt->IV($init_vect); |
|
361
|
|
|
// decrypt |
|
362
|
|
|
$decrypt = $crypt->decrypt($string); |
|
363
|
|
|
// return |
|
364
|
|
|
return array( |
|
365
|
|
|
'string' => str_replace(chr(0), '', $decrypt), |
|
366
|
|
|
'error' => '', |
|
367
|
|
|
); |
|
368
|
|
|
} |
|
369
|
|
|
} |
|
370
|
|
|
|
|
371
|
|
|
function testHex2Bin($val) |
|
372
|
|
|
{ |
|
373
|
|
|
if (!@hex2bin($val)) { |
|
374
|
|
|
throw new Exception('ERROR'); |
|
375
|
|
|
} |
|
376
|
|
|
|
|
377
|
|
|
return hex2bin($val); |
|
378
|
|
|
} |
|
379
|
|
|
|
|
380
|
|
|
/** |
|
381
|
|
|
* Defuse cryption function. |
|
382
|
|
|
* |
|
383
|
|
|
* @param string $message what to de/crypt |
|
384
|
|
|
* @param string $ascii_key key to use |
|
385
|
|
|
* @param string $type operation to perform |
|
386
|
|
|
* @param array $SETTINGS Teampass settings |
|
387
|
|
|
* |
|
388
|
|
|
* @return array |
|
389
|
|
|
*/ |
|
390
|
|
|
function cryption($message, $ascii_key, $type, $SETTINGS) |
|
391
|
|
|
{ |
|
392
|
|
|
// load PhpEncryption library |
|
393
|
|
|
if (isset($SETTINGS['cpassman_dir']) === false || empty($SETTINGS['cpassman_dir']) === true) { |
|
394
|
|
|
$path = '../includes/libraries/Encryption/Encryption/'; |
|
395
|
|
|
} else { |
|
396
|
|
|
$path = $SETTINGS['cpassman_dir'].'/includes/libraries/Encryption/Encryption/'; |
|
397
|
|
|
} |
|
398
|
|
|
|
|
399
|
|
|
include_once $path.'Crypto.php'; |
|
400
|
|
|
include_once $path.'Encoding.php'; |
|
401
|
|
|
include_once $path.'DerivedKeys.php'; |
|
402
|
|
|
include_once $path.'Key.php'; |
|
403
|
|
|
include_once $path.'KeyOrPassword.php'; |
|
404
|
|
|
include_once $path.'File.php'; |
|
405
|
|
|
include_once $path.'RuntimeTests.php'; |
|
406
|
|
|
include_once $path.'KeyProtectedByPassword.php'; |
|
407
|
|
|
include_once $path.'Core.php'; |
|
408
|
|
|
|
|
409
|
|
|
// init |
|
410
|
|
|
$err = ''; |
|
411
|
|
|
if (empty($ascii_key) === true) { |
|
412
|
|
|
$ascii_key = file_get_contents(SECUREPATH.'/teampass-seckey.txt'); |
|
413
|
|
|
} |
|
414
|
|
|
|
|
415
|
|
|
// convert KEY |
|
416
|
|
|
$key = \Defuse\Crypto\Key::loadFromAsciiSafeString($ascii_key); |
|
417
|
|
|
|
|
418
|
|
|
try { |
|
419
|
|
|
if ($type === 'encrypt') { |
|
420
|
|
|
$text = \Defuse\Crypto\Crypto::encrypt($message, $key); |
|
421
|
|
|
} elseif ($type === 'decrypt') { |
|
422
|
|
|
$text = \Defuse\Crypto\Crypto::decrypt($message, $key); |
|
423
|
|
|
} |
|
424
|
|
|
} catch (Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException $ex) { |
|
425
|
|
|
$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.'; |
|
426
|
|
|
} catch (Defuse\Crypto\Exception\BadFormatException $ex) { |
|
427
|
|
|
$err = $ex; |
|
428
|
|
|
} catch (Defuse\Crypto\Exception\EnvironmentIsBrokenException $ex) { |
|
429
|
|
|
$err = $ex; |
|
430
|
|
|
} catch (Defuse\Crypto\Exception\CryptoException $ex) { |
|
431
|
|
|
$err = $ex; |
|
432
|
|
|
} catch (Defuse\Crypto\Exception\IOException $ex) { |
|
433
|
|
|
$err = $ex; |
|
434
|
|
|
} |
|
435
|
|
|
|
|
436
|
|
|
return array( |
|
437
|
|
|
'string' => isset($text) ? $text : '', |
|
438
|
|
|
'error' => $err, |
|
439
|
|
|
); |
|
440
|
|
|
} |
|
441
|
|
|
|
|
442
|
|
|
/** |
|
443
|
|
|
* Generating a defuse key. |
|
444
|
|
|
* |
|
445
|
|
|
* @return string |
|
446
|
|
|
*/ |
|
447
|
|
|
function defuse_generate_key() |
|
448
|
|
|
{ |
|
449
|
|
|
include_once '../includes/libraries/Encryption/Encryption/Crypto.php'; |
|
450
|
|
|
include_once '../includes/libraries/Encryption/Encryption/Encoding.php'; |
|
451
|
|
|
include_once '../includes/libraries/Encryption/Encryption/DerivedKeys.php'; |
|
452
|
|
|
include_once '../includes/libraries/Encryption/Encryption/Key.php'; |
|
453
|
|
|
include_once '../includes/libraries/Encryption/Encryption/KeyOrPassword.php'; |
|
454
|
|
|
include_once '../includes/libraries/Encryption/Encryption/File.php'; |
|
455
|
|
|
include_once '../includes/libraries/Encryption/Encryption/RuntimeTests.php'; |
|
456
|
|
|
include_once '../includes/libraries/Encryption/Encryption/KeyProtectedByPassword.php'; |
|
457
|
|
|
include_once '../includes/libraries/Encryption/Encryption/Core.php'; |
|
458
|
|
|
|
|
459
|
|
|
$key = \Defuse\Crypto\Key::createNewRandomKey(); |
|
460
|
|
|
$key = $key->saveToAsciiSafeString(); |
|
461
|
|
|
|
|
462
|
|
|
return $key; |
|
463
|
|
|
} |
|
464
|
|
|
|
|
465
|
|
|
/** |
|
466
|
|
|
* Generate a Defuse personal key. |
|
467
|
|
|
* |
|
468
|
|
|
* @param string $psk psk used |
|
469
|
|
|
* |
|
470
|
|
|
* @return string |
|
471
|
|
|
*/ |
|
472
|
|
|
function defuse_generate_personal_key($psk) |
|
473
|
|
|
{ |
|
474
|
|
|
require_once '../includes/libraries/Encryption/Encryption/Crypto.php'; |
|
475
|
|
|
require_once '../includes/libraries/Encryption/Encryption/Encoding.php'; |
|
476
|
|
|
require_once '../includes/libraries/Encryption/Encryption/DerivedKeys.php'; |
|
477
|
|
|
require_once '../includes/libraries/Encryption/Encryption/Key.php'; |
|
478
|
|
|
require_once '../includes/libraries/Encryption/Encryption/KeyOrPassword.php'; |
|
479
|
|
|
require_once '../includes/libraries/Encryption/Encryption/File.php'; |
|
480
|
|
|
require_once '../includes/libraries/Encryption/Encryption/RuntimeTests.php'; |
|
481
|
|
|
require_once '../includes/libraries/Encryption/Encryption/KeyProtectedByPassword.php'; |
|
482
|
|
|
require_once '../includes/libraries/Encryption/Encryption/Core.php'; |
|
483
|
|
|
|
|
484
|
|
|
$protected_key = \Defuse\Crypto\KeyProtectedByPassword::createRandomPasswordProtectedKey($psk); |
|
485
|
|
|
$protected_key_encoded = $protected_key->saveToAsciiSafeString(); |
|
486
|
|
|
|
|
487
|
|
|
return $protected_key_encoded; // save this in user table |
|
488
|
|
|
} |
|
489
|
|
|
|
|
490
|
|
|
/** |
|
491
|
|
|
* Validate persoanl key with defuse. |
|
492
|
|
|
* |
|
493
|
|
|
* @param string $psk the user's psk |
|
494
|
|
|
* @param string $protected_key_encoded special key |
|
495
|
|
|
* |
|
496
|
|
|
* @return string |
|
497
|
|
|
*/ |
|
498
|
|
|
function defuse_validate_personal_key($psk, $protected_key_encoded) |
|
499
|
|
|
{ |
|
500
|
|
|
require_once '../includes/libraries/Encryption/Encryption/Crypto.php'; |
|
501
|
|
|
require_once '../includes/libraries/Encryption/Encryption/Encoding.php'; |
|
502
|
|
|
require_once '../includes/libraries/Encryption/Encryption/DerivedKeys.php'; |
|
503
|
|
|
require_once '../includes/libraries/Encryption/Encryption/Key.php'; |
|
504
|
|
|
require_once '../includes/libraries/Encryption/Encryption/KeyOrPassword.php'; |
|
505
|
|
|
require_once '../includes/libraries/Encryption/Encryption/File.php'; |
|
506
|
|
|
require_once '../includes/libraries/Encryption/Encryption/RuntimeTests.php'; |
|
507
|
|
|
require_once '../includes/libraries/Encryption/Encryption/KeyProtectedByPassword.php'; |
|
508
|
|
|
require_once '../includes/libraries/Encryption/Encryption/Core.php'; |
|
509
|
|
|
|
|
510
|
|
|
try { |
|
511
|
|
|
$protected_key = \Defuse\Crypto\KeyProtectedByPassword::loadFromAsciiSafeString($protected_key_encoded); |
|
512
|
|
|
$user_key = $protected_key->unlockKey($psk); |
|
513
|
|
|
$user_key_encoded = $user_key->saveToAsciiSafeString(); |
|
514
|
|
|
} catch (Defuse\Crypto\Exception\EnvironmentIsBrokenException $ex) { |
|
515
|
|
|
return 'Error - Major issue as the encryption is broken.'; |
|
516
|
|
|
} catch (Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException $ex) { |
|
517
|
|
|
return 'Error - The saltkey is not the correct one.'; |
|
518
|
|
|
} |
|
519
|
|
|
|
|
520
|
|
|
return $user_key_encoded; // store it in session once user has entered his psk |
|
521
|
|
|
} |
|
522
|
|
|
|
|
523
|
|
|
/** |
|
524
|
|
|
* Decrypt a defuse string if encrypted. |
|
525
|
|
|
* |
|
526
|
|
|
* @param string $value Encrypted string |
|
527
|
|
|
* |
|
528
|
|
|
* @return string Decrypted string |
|
529
|
|
|
*/ |
|
530
|
|
|
function defuseReturnDecrypted($value, $SETTINGS) |
|
531
|
|
|
{ |
|
532
|
|
|
if (substr($value, 0, 3) === 'def') { |
|
533
|
|
|
$value = cryption($value, '', 'decrypt', $SETTINGS)['string']; |
|
534
|
|
|
} |
|
535
|
|
|
|
|
536
|
|
|
return $value; |
|
537
|
|
|
} |
|
538
|
|
|
|
|
539
|
|
|
/** |
|
540
|
|
|
* trimElement(). |
|
541
|
|
|
* |
|
542
|
|
|
* trim a string depending on a specific string |
|
543
|
|
|
* |
|
544
|
|
|
* @param string $chaine what to trim |
|
545
|
|
|
* @param string $element trim on what |
|
546
|
|
|
* |
|
547
|
|
|
* @return string |
|
548
|
|
|
*/ |
|
549
|
|
|
function trimElement($chaine, $element) |
|
550
|
|
|
{ |
|
551
|
|
|
if (!empty($chaine)) { |
|
552
|
|
|
if (is_array($chaine) === true) { |
|
|
|
|
|
|
553
|
|
|
$chaine = implode(';', $chaine); |
|
554
|
|
|
} |
|
555
|
|
|
$chaine = trim($chaine); |
|
556
|
|
|
if (substr($chaine, 0, 1) === $element) { |
|
557
|
|
|
$chaine = substr($chaine, 1); |
|
558
|
|
|
} |
|
559
|
|
|
if (substr($chaine, strlen($chaine) - 1, 1) === $element) { |
|
560
|
|
|
$chaine = substr($chaine, 0, strlen($chaine) - 1); |
|
561
|
|
|
} |
|
562
|
|
|
} |
|
563
|
|
|
|
|
564
|
|
|
return $chaine; |
|
565
|
|
|
} |
|
566
|
|
|
|
|
567
|
|
|
/** |
|
568
|
|
|
* Permits to suppress all "special" characters from string. |
|
569
|
|
|
* |
|
570
|
|
|
* @param string $string what to clean |
|
571
|
|
|
* @param bool $special use of special chars? |
|
572
|
|
|
* |
|
573
|
|
|
* @return string |
|
574
|
|
|
*/ |
|
575
|
|
|
function cleanString($string, $special = false) |
|
576
|
|
|
{ |
|
577
|
|
|
// Create temporary table for special characters escape |
|
578
|
|
|
$tabSpecialChar = array(); |
|
579
|
|
|
for ($i = 0; $i <= 31; ++$i) { |
|
580
|
|
|
$tabSpecialChar[] = chr($i); |
|
581
|
|
|
} |
|
582
|
|
|
array_push($tabSpecialChar, '<br />'); |
|
583
|
|
|
if ((int) $special === 1) { |
|
584
|
|
|
$tabSpecialChar = array_merge($tabSpecialChar, array('</li>', '<ul>', '<ol>')); |
|
585
|
|
|
} |
|
586
|
|
|
|
|
587
|
|
|
return str_replace($tabSpecialChar, "\n", $string); |
|
588
|
|
|
} |
|
589
|
|
|
|
|
590
|
|
|
/** |
|
591
|
|
|
* Erro manager for DB. |
|
592
|
|
|
* |
|
593
|
|
|
* @param array $params output from query |
|
594
|
|
|
*/ |
|
595
|
|
|
function db_error_handler($params) |
|
596
|
|
|
{ |
|
597
|
|
|
echo 'Error: '.$params['error']."<br>\n"; |
|
598
|
|
|
echo 'Query: '.$params['query']."<br>\n"; |
|
599
|
|
|
throw new Exception('Error - Query', 1); |
|
600
|
|
|
} |
|
601
|
|
|
|
|
602
|
|
|
/** |
|
603
|
|
|
* [identifyUserRights description]. |
|
604
|
|
|
* |
|
605
|
|
|
* @param string $groupesVisiblesUser [description] |
|
606
|
|
|
* @param string $groupesInterditsUser [description] |
|
607
|
|
|
* @param string $isAdmin [description] |
|
608
|
|
|
* @param string $idFonctions [description] |
|
609
|
|
|
* |
|
610
|
|
|
* @return string [description] |
|
611
|
|
|
*/ |
|
612
|
|
|
function identifyUserRights( |
|
613
|
|
|
$groupesVisiblesUser, |
|
614
|
|
|
$groupesInterditsUser, |
|
615
|
|
|
$isAdmin, |
|
616
|
|
|
$idFonctions, |
|
617
|
|
|
$SETTINGS |
|
618
|
|
|
) { |
|
619
|
|
|
//load ClassLoader |
|
620
|
|
|
include_once $SETTINGS['cpassman_dir'].'/sources/SplClassLoader.php'; |
|
621
|
|
|
|
|
622
|
|
|
//Connect to DB |
|
623
|
|
|
include_once $SETTINGS['cpassman_dir'].'/includes/libraries/Database/Meekrodb/db.class.php'; |
|
624
|
|
|
$link = mysqli_connect(DB_HOST, DB_USER, defuseReturnDecrypted(DB_PASSWD, $SETTINGS), DB_NAME, DB_PORT); |
|
625
|
|
|
$link->set_charset(DB_ENCODING); |
|
626
|
|
|
|
|
627
|
|
|
//Build tree |
|
628
|
|
|
$tree = new SplClassLoader('Tree\NestedTree', $SETTINGS['cpassman_dir'].'/includes/libraries'); |
|
629
|
|
|
$tree->register(); |
|
630
|
|
|
$tree = new Tree\NestedTree\NestedTree(prefixTable('nested_tree'), 'id', 'parent_id', 'title'); |
|
631
|
|
|
|
|
632
|
|
|
// Check if user is ADMINISTRATOR |
|
633
|
|
|
if ($isAdmin === '1') { |
|
634
|
|
|
identAdmin( |
|
635
|
|
|
$idFonctions, |
|
636
|
|
|
$SETTINGS, |
|
637
|
|
|
$tree |
|
|
|
|
|
|
638
|
|
|
); |
|
639
|
|
|
} else { |
|
640
|
|
|
identUser( |
|
641
|
|
|
$groupesVisiblesUser, |
|
642
|
|
|
$groupesInterditsUser, |
|
643
|
|
|
$idFonctions, |
|
644
|
|
|
$SETTINGS, |
|
645
|
|
|
$tree |
|
|
|
|
|
|
646
|
|
|
); |
|
647
|
|
|
} |
|
648
|
|
|
|
|
649
|
|
|
// update user's timestamp |
|
650
|
|
|
DB::update( |
|
651
|
|
|
prefixTable('users'), |
|
652
|
|
|
array( |
|
653
|
|
|
'timestamp' => time(), |
|
654
|
|
|
), |
|
655
|
|
|
'id=%i', |
|
656
|
|
|
$_SESSION['user_id'] |
|
657
|
|
|
); |
|
658
|
|
|
} |
|
659
|
|
|
|
|
660
|
|
|
/** |
|
661
|
|
|
* Identify administrator. |
|
662
|
|
|
* |
|
663
|
|
|
* @param string $idFonctions Roles of user |
|
664
|
|
|
* @param array $SETTINGS Teampass settings |
|
665
|
|
|
* @param array $tree Tree of folders |
|
666
|
|
|
*/ |
|
667
|
|
|
function identAdmin($idFonctions, $SETTINGS, $tree) |
|
668
|
|
|
{ |
|
669
|
|
|
$groupesVisibles = array(); |
|
670
|
|
|
$_SESSION['personal_folders'] = array(); |
|
671
|
|
|
$_SESSION['groupes_visibles'] = array(); |
|
672
|
|
|
$_SESSION['groupes_interdits'] = array(); |
|
673
|
|
|
$_SESSION['personal_visible_groups'] = array(); |
|
674
|
|
|
$_SESSION['read_only_folders'] = array(); |
|
675
|
|
|
$_SESSION['list_restricted_folders_for_items'] = array(); |
|
676
|
|
|
$_SESSION['list_folders_editable_by_role'] = array(); |
|
677
|
|
|
$_SESSION['list_folders_limited'] = array(); |
|
678
|
|
|
$_SESSION['no_access_folders'] = array(); |
|
679
|
|
|
$_SESSION['groupes_visibles_list'] = ''; |
|
680
|
|
|
|
|
681
|
|
|
// Get list of Folders |
|
682
|
|
|
$rows = DB::query('SELECT id FROM '.prefixTable('nested_tree').' WHERE personal_folder = %i', 0); |
|
683
|
|
|
foreach ($rows as $record) { |
|
684
|
|
|
array_push($groupesVisibles, $record['id']); |
|
685
|
|
|
} |
|
686
|
|
|
$_SESSION['groupes_visibles'] = $groupesVisibles; |
|
687
|
|
|
$_SESSION['all_non_personal_folders'] = $groupesVisibles; |
|
688
|
|
|
// Exclude all PF |
|
689
|
|
|
$_SESSION['forbiden_pfs'] = array(); |
|
690
|
|
|
$where = new WhereClause('and'); // create a WHERE statement of pieces joined by ANDs |
|
691
|
|
|
$where->add('personal_folder=%i', 1); |
|
692
|
|
|
if (isset($SETTINGS['enable_pf_feature']) === true |
|
693
|
|
|
&& (int) $SETTINGS['enable_pf_feature'] === 1 |
|
694
|
|
|
) { |
|
695
|
|
|
$where->add('title=%s', $_SESSION['user_id']); |
|
696
|
|
|
$where->negateLast(); |
|
697
|
|
|
} |
|
698
|
|
|
// Get ID of personal folder |
|
699
|
|
|
$persfld = DB::queryfirstrow( |
|
700
|
|
|
'SELECT id FROM '.prefixTable('nested_tree').' WHERE title = %s', |
|
701
|
|
|
$_SESSION['user_id'] |
|
702
|
|
|
); |
|
703
|
|
|
if (empty($persfld['id']) === false) { |
|
704
|
|
|
if (in_array($persfld['id'], $_SESSION['groupes_visibles']) === false) { |
|
705
|
|
|
array_push($_SESSION['groupes_visibles'], $persfld['id']); |
|
706
|
|
|
array_push($_SESSION['personal_visible_groups'], $persfld['id']); |
|
707
|
|
|
// get all descendants |
|
708
|
|
|
$tree = new Tree\NestedTree\NestedTree(prefixTable('nested_tree'), 'id', 'parent_id', 'title'); |
|
709
|
|
|
$tree->rebuild(); |
|
710
|
|
|
$tst = $tree->getDescendants($persfld['id']); |
|
711
|
|
|
foreach ($tst as $t) { |
|
712
|
|
|
array_push($_SESSION['groupes_visibles'], $t->id); |
|
713
|
|
|
array_push($_SESSION['personal_visible_groups'], $t->id); |
|
714
|
|
|
} |
|
715
|
|
|
} |
|
716
|
|
|
} |
|
717
|
|
|
|
|
718
|
|
|
// get complete list of ROLES |
|
719
|
|
|
$tmp = explode(';', $idFonctions); |
|
720
|
|
|
$rows = DB::query( |
|
721
|
|
|
'SELECT * FROM '.prefixTable('roles_title').' |
|
722
|
|
|
ORDER BY title ASC' |
|
723
|
|
|
); |
|
724
|
|
|
foreach ($rows as $record) { |
|
725
|
|
|
if (!empty($record['id']) && !in_array($record['id'], $tmp)) { |
|
726
|
|
|
array_push($tmp, $record['id']); |
|
727
|
|
|
} |
|
728
|
|
|
} |
|
729
|
|
|
$_SESSION['fonction_id'] = implode(';', $tmp); |
|
730
|
|
|
|
|
731
|
|
|
$_SESSION['groupes_visibles_list'] = implode(',', $_SESSION['groupes_visibles']); |
|
732
|
|
|
$_SESSION['is_admin'] = 1; |
|
733
|
|
|
// Check if admin has created Folders and Roles |
|
734
|
|
|
DB::query('SELECT * FROM '.prefixTable('nested_tree').''); |
|
735
|
|
|
$_SESSION['nb_folders'] = DB::count(); |
|
736
|
|
|
DB::query('SELECT * FROM '.prefixTable('roles_title')); |
|
737
|
|
|
$_SESSION['nb_roles'] = DB::count(); |
|
738
|
|
|
} |
|
739
|
|
|
|
|
740
|
|
|
/** |
|
741
|
|
|
* Undocumented function. |
|
742
|
|
|
* |
|
743
|
|
|
* @param string $groupesVisiblesUser Allowed folders |
|
744
|
|
|
* @param string $groupesInterditsUser Not allowed folders |
|
745
|
|
|
* @param string $idFonctions Roles of user |
|
746
|
|
|
* @param array $SETTINGS Teampass settings |
|
747
|
|
|
* @param array $tree Tree of folders |
|
748
|
|
|
*/ |
|
749
|
|
|
function identUser( |
|
750
|
|
|
$groupesVisiblesUser, |
|
751
|
|
|
$groupesInterditsUser, |
|
752
|
|
|
$idFonctions, |
|
753
|
|
|
$SETTINGS, |
|
754
|
|
|
$tree |
|
755
|
|
|
) { |
|
756
|
|
|
// init |
|
757
|
|
|
$_SESSION['groupes_visibles'] = array(); |
|
758
|
|
|
$_SESSION['personal_folders'] = array(); |
|
759
|
|
|
$_SESSION['groupes_interdits'] = array(); |
|
760
|
|
|
$_SESSION['personal_visible_groups'] = array(); |
|
761
|
|
|
$_SESSION['read_only_folders'] = array(); |
|
762
|
|
|
$_SESSION['fonction_id'] = $idFonctions; |
|
763
|
|
|
|
|
764
|
|
|
$groupesInterdits = array(); |
|
765
|
|
|
if (is_array($groupesInterditsUser) === false) { |
|
|
|
|
|
|
766
|
|
|
$groupesInterditsUser = explode(';', trimElement(/* @scrutinizer ignore-type */ $groupesInterditsUser, ';')); |
|
767
|
|
|
} |
|
768
|
|
|
if (empty($groupesInterditsUser) === false && count($groupesInterditsUser) > 0) { |
|
769
|
|
|
$groupesInterdits = $groupesInterditsUser; |
|
770
|
|
|
} |
|
771
|
|
|
$_SESSION['is_admin'] = '0'; |
|
772
|
|
|
$fonctionsAssociees = explode(';', trimElement($idFonctions, ';')); |
|
773
|
|
|
|
|
774
|
|
|
$listAllowedFolders = $listFoldersLimited = $listFoldersEditableByRole = $listRestrictedFoldersForItems = $listReadOnlyFolders = array(); |
|
775
|
|
|
|
|
776
|
|
|
// rechercher tous les groupes visibles en fonction des roles de l'utilisateur |
|
777
|
|
|
foreach ($fonctionsAssociees as $roleId) { |
|
778
|
|
|
if (empty($roleId) === false) { |
|
779
|
|
|
// Get allowed folders for each Role |
|
780
|
|
|
$rows = DB::query( |
|
781
|
|
|
'SELECT folder_id FROM '.prefixTable('roles_values').' WHERE role_id=%i', |
|
782
|
|
|
$roleId |
|
783
|
|
|
); |
|
784
|
|
|
|
|
785
|
|
|
if (DB::count() > 0) { |
|
786
|
|
|
$tmp = DB::queryfirstrow( |
|
787
|
|
|
'SELECT allow_pw_change FROM '.prefixTable('roles_title').' WHERE id = %i', |
|
788
|
|
|
$roleId |
|
789
|
|
|
); |
|
790
|
|
|
foreach ($rows as $record) { |
|
791
|
|
|
if (isset($record['folder_id']) && in_array($record['folder_id'], $listAllowedFolders) === false) { |
|
792
|
|
|
array_push($listAllowedFolders, $record['folder_id']); |
|
793
|
|
|
} |
|
794
|
|
|
// Check if this group is allowed to modify any pw in allowed folders |
|
795
|
|
|
if ((int) $tmp['allow_pw_change'] === 1 |
|
796
|
|
|
&& in_array($record['folder_id'], $listFoldersEditableByRole) === false |
|
797
|
|
|
) { |
|
798
|
|
|
array_push($listFoldersEditableByRole, $record['folder_id']); |
|
799
|
|
|
} |
|
800
|
|
|
} |
|
801
|
|
|
// Check for the users roles if some specific rights exist on items |
|
802
|
|
|
$rows = DB::query( |
|
803
|
|
|
'SELECT i.id_tree, r.item_id |
|
804
|
|
|
FROM '.prefixTable('items').' as i |
|
805
|
|
|
INNER JOIN '.prefixTable('restriction_to_roles').' as r ON (r.item_id=i.id) |
|
806
|
|
|
WHERE r.role_id=%i |
|
807
|
|
|
ORDER BY i.id_tree ASC', |
|
808
|
|
|
$roleId |
|
809
|
|
|
); |
|
810
|
|
|
$inc = 0; |
|
811
|
|
|
foreach ($rows as $record) { |
|
812
|
|
|
if (isset($record['id_tree'])) { |
|
813
|
|
|
$listFoldersLimited[$record['id_tree']][$inc] = $record['item_id']; |
|
814
|
|
|
++$inc; |
|
815
|
|
|
} |
|
816
|
|
|
} |
|
817
|
|
|
} |
|
818
|
|
|
} |
|
819
|
|
|
} |
|
820
|
|
|
|
|
821
|
|
|
// Clean arrays |
|
822
|
|
|
$listAllowedFolders = array_unique($listAllowedFolders); |
|
823
|
|
|
$groupesVisiblesUser = explode(';', trimElement($groupesVisiblesUser, ';')); |
|
824
|
|
|
|
|
825
|
|
|
// Does this user is allowed to see other items |
|
826
|
|
|
$inc = 0; |
|
827
|
|
|
$rows = DB::query( |
|
828
|
|
|
'SELECT id, id_tree FROM '.prefixTable('items').' |
|
829
|
|
|
WHERE restricted_to LIKE %ss AND inactif=%s', |
|
830
|
|
|
$_SESSION['user_id'].';', |
|
831
|
|
|
'0' |
|
832
|
|
|
); |
|
833
|
|
|
foreach ($rows as $record) { |
|
834
|
|
|
// Exclude restriction on item if folder is fully accessible |
|
835
|
|
|
if (in_array($record['id_tree'], $listAllowedFolders) === false) { |
|
836
|
|
|
$listRestrictedFoldersForItems[$record['id_tree']][$inc] = $record['id']; |
|
837
|
|
|
++$inc; |
|
838
|
|
|
} |
|
839
|
|
|
} |
|
840
|
|
|
|
|
841
|
|
|
// => Build final lists |
|
842
|
|
|
// Add user allowed folders |
|
843
|
|
|
$allowedFoldersTmp = array_unique( |
|
844
|
|
|
array_merge($listAllowedFolders, $groupesVisiblesUser) |
|
845
|
|
|
); |
|
846
|
|
|
// Exclude from allowed folders all the specific user forbidden folders |
|
847
|
|
|
$allowedFolders = array(); |
|
848
|
|
|
foreach ($allowedFoldersTmp as $ident) { |
|
849
|
|
|
if (!in_array($ident, $groupesInterditsUser) && !empty($ident)) { |
|
850
|
|
|
array_push($allowedFolders, $ident); |
|
851
|
|
|
} |
|
852
|
|
|
} |
|
853
|
|
|
|
|
854
|
|
|
// Clean array |
|
855
|
|
|
$listAllowedFolders = array_filter(array_unique($allowedFolders)); |
|
856
|
|
|
|
|
857
|
|
|
// Exclude all PF |
|
858
|
|
|
$_SESSION['forbiden_pfs'] = array(); |
|
859
|
|
|
|
|
860
|
|
|
$where = new WhereClause('and'); |
|
861
|
|
|
$where->add('personal_folder=%i', 1); |
|
862
|
|
|
if (isset($SETTINGS['enable_pf_feature']) === true && $SETTINGS['enable_pf_feature'] === '1' |
|
863
|
|
|
&& isset($_SESSION['personal_folder']) === true && $_SESSION['personal_folder'] === '1' |
|
864
|
|
|
) { |
|
865
|
|
|
$where->add('title=%s', $_SESSION['user_id']); |
|
866
|
|
|
$where->negateLast(); |
|
867
|
|
|
} |
|
868
|
|
|
|
|
869
|
|
|
$persoFlds = DB::query( |
|
870
|
|
|
'SELECT id |
|
871
|
|
|
FROM '.prefixTable('nested_tree').' |
|
872
|
|
|
WHERE %l', |
|
873
|
|
|
$where |
|
874
|
|
|
); |
|
875
|
|
|
foreach ($persoFlds as $persoFldId) { |
|
876
|
|
|
array_push($_SESSION['forbiden_pfs'], $persoFldId['id']); |
|
877
|
|
|
} |
|
878
|
|
|
// Get IDs of personal folders |
|
879
|
|
|
if (isset($SETTINGS['enable_pf_feature']) === true && $SETTINGS['enable_pf_feature'] === '1' |
|
880
|
|
|
&& isset($_SESSION['personal_folder']) === true && $_SESSION['personal_folder'] === '1' |
|
881
|
|
|
) { |
|
882
|
|
|
$persoFld = DB::queryfirstrow( |
|
883
|
|
|
'SELECT id |
|
884
|
|
|
FROM '.prefixTable('nested_tree').' |
|
885
|
|
|
WHERE title = %s AND personal_folder = %i', |
|
886
|
|
|
$_SESSION['user_id'], |
|
887
|
|
|
1 |
|
888
|
|
|
); |
|
889
|
|
|
if (empty($persoFld['id']) === false) { |
|
890
|
|
|
if (in_array($persoFld['id'], $listAllowedFolders) === false) { |
|
891
|
|
|
array_push($_SESSION['personal_folders'], $persoFld['id']); |
|
892
|
|
|
array_push($listAllowedFolders, $persoFld['id']); |
|
893
|
|
|
array_push($_SESSION['personal_visible_groups'], $persoFld['id']); |
|
894
|
|
|
// get all descendants |
|
895
|
|
|
$ids = $tree->getChildren($persoFld['id'], false, false); |
|
896
|
|
|
foreach ($ids as $ident) { |
|
897
|
|
|
if ($ident->personal_folder === 1) { |
|
898
|
|
|
array_push($listAllowedFolders, $ident->id); |
|
899
|
|
|
array_push($_SESSION['personal_visible_groups'], $ident->id); |
|
900
|
|
|
array_push($_SESSION['personal_folders'], $ident->id); |
|
901
|
|
|
} |
|
902
|
|
|
} |
|
903
|
|
|
} |
|
904
|
|
|
} |
|
905
|
|
|
// get list of readonly folders when pf is disabled. |
|
906
|
|
|
$_SESSION['personal_folders'] = array_unique($_SESSION['personal_folders']); |
|
907
|
|
|
// rule - if one folder is set as W or N in one of the Role, then User has access as W |
|
908
|
|
|
foreach ($listAllowedFolders as $folderId) { |
|
909
|
|
|
if (in_array($folderId, array_unique(array_merge($listReadOnlyFolders, $_SESSION['personal_folders']))) === false) { |
|
910
|
|
|
DB::query( |
|
911
|
|
|
'SELECT * |
|
912
|
|
|
FROM '.prefixTable('roles_values').' |
|
913
|
|
|
WHERE folder_id = %i AND role_id IN %li AND type IN %ls', |
|
914
|
|
|
$folderId, |
|
915
|
|
|
$fonctionsAssociees, |
|
916
|
|
|
array('W', 'ND', 'NE', 'NDNE') |
|
917
|
|
|
); |
|
918
|
|
|
if (DB::count() === 0 && in_array($folderId, $groupesVisiblesUser) === false) { |
|
919
|
|
|
array_push($listReadOnlyFolders, $folderId); |
|
920
|
|
|
} |
|
921
|
|
|
} |
|
922
|
|
|
} |
|
923
|
|
|
} else { |
|
924
|
|
|
// get list of readonly folders when pf is disabled. |
|
925
|
|
|
// rule - if one folder is set as W in one of the Role, then User has access as W |
|
926
|
|
|
foreach ($listAllowedFolders as $folderId) { |
|
927
|
|
|
if (in_array($folderId, $listReadOnlyFolders) === false) { |
|
928
|
|
|
DB::query( |
|
929
|
|
|
'SELECT * |
|
930
|
|
|
FROM '.prefixTable('roles_values').' |
|
931
|
|
|
WHERE folder_id = %i AND role_id IN %li AND type IN %ls', |
|
932
|
|
|
$folderId, |
|
933
|
|
|
$fonctionsAssociees, |
|
934
|
|
|
array('W', 'ND', 'NE', 'NDNE') |
|
935
|
|
|
); |
|
936
|
|
|
if (DB::count() === 0 && in_array($folderId, $groupesVisiblesUser) === false) { |
|
937
|
|
|
array_push($listReadOnlyFolders, $folderId); |
|
938
|
|
|
} |
|
939
|
|
|
} |
|
940
|
|
|
} |
|
941
|
|
|
} |
|
942
|
|
|
|
|
943
|
|
|
// check if change proposals on User's items |
|
944
|
|
|
if (isset($SETTINGS['enable_suggestion']) === true && $SETTINGS['enable_suggestion'] === '1') { |
|
945
|
|
|
DB::query( |
|
946
|
|
|
'SELECT * |
|
947
|
|
|
FROM '.prefixTable('items_change').' AS c |
|
948
|
|
|
LEFT JOIN '.prefixTable('log_items').' AS i ON (c.item_id = i.id_item) |
|
949
|
|
|
WHERE i.action = %s AND i.id_user = %i', |
|
950
|
|
|
'at_creation', |
|
951
|
|
|
$_SESSION['user_id'] |
|
952
|
|
|
); |
|
953
|
|
|
$_SESSION['nb_item_change_proposals'] = DB::count(); |
|
954
|
|
|
} else { |
|
955
|
|
|
$_SESSION['nb_item_change_proposals'] = 0; |
|
956
|
|
|
} |
|
957
|
|
|
|
|
958
|
|
|
$_SESSION['all_non_personal_folders'] = $listAllowedFolders; |
|
959
|
|
|
$_SESSION['groupes_visibles'] = $listAllowedFolders; |
|
960
|
|
|
$_SESSION['groupes_visibles_list'] = implode(',', $listAllowedFolders); |
|
961
|
|
|
$_SESSION['personal_visible_groups_list'] = implode(',', $_SESSION['personal_visible_groups']); |
|
962
|
|
|
$_SESSION['read_only_folders'] = $listReadOnlyFolders; |
|
963
|
|
|
$_SESSION['no_access_folders'] = $groupesInterdits; |
|
964
|
|
|
|
|
965
|
|
|
$_SESSION['list_folders_limited'] = $listFoldersLimited; |
|
966
|
|
|
$_SESSION['list_folders_editable_by_role'] = $listFoldersEditableByRole; |
|
967
|
|
|
$_SESSION['list_restricted_folders_for_items'] = $listRestrictedFoldersForItems; |
|
968
|
|
|
// Folders and Roles numbers |
|
969
|
|
|
DB::queryfirstrow('SELECT id FROM '.prefixTable('nested_tree').''); |
|
970
|
|
|
$_SESSION['nb_folders'] = DB::count(); |
|
971
|
|
|
DB::queryfirstrow('SELECT id FROM '.prefixTable('roles_title')); |
|
972
|
|
|
$_SESSION['nb_roles'] = DB::count(); |
|
973
|
|
|
} |
|
974
|
|
|
|
|
975
|
|
|
/** |
|
976
|
|
|
* Update the CACHE table. |
|
977
|
|
|
* |
|
978
|
|
|
* @param string $action What to do |
|
979
|
|
|
* @param array $SETTINGS Teampass settings |
|
980
|
|
|
* @param string $ident Ident format |
|
981
|
|
|
*/ |
|
982
|
|
|
function updateCacheTable($action, $SETTINGS, $ident = null) |
|
983
|
|
|
{ |
|
984
|
|
|
if ($action === 'reload') { |
|
985
|
|
|
// Rebuild full cache table |
|
986
|
|
|
cacheTableRefresh($SETTINGS); |
|
987
|
|
|
} elseif ($action === 'update_value' && is_null($ident) === false) { |
|
988
|
|
|
// UPDATE an item |
|
989
|
|
|
cacheTableUpdate($SETTINGS, $ident); |
|
990
|
|
|
} elseif ($action === 'add_value' && is_null($ident) === false) { |
|
991
|
|
|
// ADD an item |
|
992
|
|
|
cacheTableAdd($SETTINGS, $ident); |
|
993
|
|
|
} elseif ($action === 'delete_value' && is_null($ident) === false) { |
|
994
|
|
|
// DELETE an item |
|
995
|
|
|
DB::delete(prefixTable('cache'), 'id = %i', $ident); |
|
996
|
|
|
} |
|
997
|
|
|
} |
|
998
|
|
|
|
|
999
|
|
|
/** |
|
1000
|
|
|
* Cache table - refresh. |
|
1001
|
|
|
* |
|
1002
|
|
|
* @param array $SETTINGS Teampass settings |
|
1003
|
|
|
*/ |
|
1004
|
|
|
function cacheTableRefresh($SETTINGS) |
|
1005
|
|
|
{ |
|
1006
|
|
|
include_once $SETTINGS['cpassman_dir'].'/sources/SplClassLoader.php'; |
|
1007
|
|
|
|
|
1008
|
|
|
//Connect to DB |
|
1009
|
|
|
include_once $SETTINGS['cpassman_dir'].'/includes/libraries/Database/Meekrodb/db.class.php'; |
|
1010
|
|
|
DB::$host = DB_HOST; |
|
1011
|
|
|
DB::$user = DB_USER; |
|
1012
|
|
|
DB::$password = defuseReturnDecrypted(DB_PASSWD, $SETTINGS); |
|
1013
|
|
|
DB::$dbName = DB_NAME; |
|
1014
|
|
|
DB::$port = DB_PORT; |
|
1015
|
|
|
DB::$encoding = DB_ENCODING; |
|
1016
|
|
|
|
|
1017
|
|
|
$link = mysqli_connect(DB_HOST, DB_USER, defuseReturnDecrypted(DB_PASSWD, $SETTINGS), DB_NAME, DB_PORT); |
|
1018
|
|
|
$link->set_charset(DB_ENCODING); |
|
1019
|
|
|
|
|
1020
|
|
|
//Load Tree |
|
1021
|
|
|
$tree = new SplClassLoader('Tree\NestedTree', '../includes/libraries'); |
|
1022
|
|
|
$tree->register(); |
|
1023
|
|
|
$tree = new Tree\NestedTree\NestedTree(prefixTable('nested_tree'), 'id', 'parent_id', 'title'); |
|
1024
|
|
|
|
|
1025
|
|
|
// truncate table |
|
1026
|
|
|
DB::query('TRUNCATE TABLE '.prefixTable('cache')); |
|
1027
|
|
|
|
|
1028
|
|
|
// reload date |
|
1029
|
|
|
$rows = DB::query( |
|
1030
|
|
|
'SELECT * |
|
1031
|
|
|
FROM '.prefixTable('items').' as i |
|
1032
|
|
|
INNER JOIN '.prefixTable('log_items').' as l ON (l.id_item = i.id) |
|
1033
|
|
|
AND l.action = %s |
|
1034
|
|
|
AND i.inactif = %i', |
|
1035
|
|
|
'at_creation', |
|
1036
|
|
|
0 |
|
1037
|
|
|
); |
|
1038
|
|
|
foreach ($rows as $record) { |
|
1039
|
|
|
if (empty($record['id_tree']) === false) { |
|
1040
|
|
|
// Get all TAGS |
|
1041
|
|
|
$tags = ''; |
|
1042
|
|
|
$itemTags = DB::query('SELECT tag FROM '.prefixTable('tags').' WHERE item_id=%i', $record['id']); |
|
1043
|
|
|
foreach ($itemTags as $itemTag) { |
|
1044
|
|
|
if (!empty($itemTag['tag'])) { |
|
1045
|
|
|
$tags .= $itemTag['tag'].' '; |
|
1046
|
|
|
} |
|
1047
|
|
|
} |
|
1048
|
|
|
// Get renewal period |
|
1049
|
|
|
$resNT = DB::queryfirstrow('SELECT renewal_period FROM '.prefixTable('nested_tree').' WHERE id=%i', $record['id_tree']); |
|
1050
|
|
|
|
|
1051
|
|
|
// form id_tree to full foldername |
|
1052
|
|
|
$folder = ''; |
|
1053
|
|
|
$arbo = $tree->getPath($record['id_tree'], true); |
|
1054
|
|
|
foreach ($arbo as $elem) { |
|
1055
|
|
|
if ((int) $elem->title === $_SESSION['user_id'] |
|
1056
|
|
|
&& (int) $elem->nlevel === 1 |
|
1057
|
|
|
) { |
|
1058
|
|
|
$elem->title = $_SESSION['login']; |
|
1059
|
|
|
} |
|
1060
|
|
|
if (empty($folder)) { |
|
1061
|
|
|
$folder = stripslashes($elem->title); |
|
1062
|
|
|
} else { |
|
1063
|
|
|
$folder .= ' » '.stripslashes($elem->title); |
|
1064
|
|
|
} |
|
1065
|
|
|
} |
|
1066
|
|
|
// store data |
|
1067
|
|
|
DB::insert( |
|
1068
|
|
|
prefixTable('cache'), |
|
1069
|
|
|
array( |
|
1070
|
|
|
'id' => $record['id'], |
|
1071
|
|
|
'label' => $record['label'], |
|
1072
|
|
|
'description' => isset($record['description']) ? $record['description'] : '', |
|
1073
|
|
|
'url' => (isset($record['url']) && !empty($record['url'])) ? $record['url'] : '0', |
|
1074
|
|
|
'tags' => $tags, |
|
1075
|
|
|
'id_tree' => $record['id_tree'], |
|
1076
|
|
|
'perso' => $record['perso'], |
|
1077
|
|
|
'restricted_to' => (isset($record['restricted_to']) && !empty($record['restricted_to'])) ? $record['restricted_to'] : '0', |
|
1078
|
|
|
'login' => isset($record['login']) ? $record['login'] : '', |
|
1079
|
|
|
'folder' => $folder, |
|
1080
|
|
|
'author' => $record['id_user'], |
|
1081
|
|
|
'renewal_period' => isset($resNT['renewal_period']) ? $resNT['renewal_period'] : '0', |
|
1082
|
|
|
'timestamp' => $record['date'], |
|
1083
|
|
|
) |
|
1084
|
|
|
); |
|
1085
|
|
|
} |
|
1086
|
|
|
} |
|
1087
|
|
|
} |
|
1088
|
|
|
|
|
1089
|
|
|
/** |
|
1090
|
|
|
* Cache table - update existing value. |
|
1091
|
|
|
* |
|
1092
|
|
|
* @param array $SETTINGS Teampass settings |
|
1093
|
|
|
* @param string $ident Ident format |
|
1094
|
|
|
*/ |
|
1095
|
|
|
function cacheTableUpdate($SETTINGS, $ident = null) |
|
1096
|
|
|
{ |
|
1097
|
|
|
include_once $SETTINGS['cpassman_dir'].'/sources/SplClassLoader.php'; |
|
1098
|
|
|
|
|
1099
|
|
|
//Connect to DB |
|
1100
|
|
|
include_once $SETTINGS['cpassman_dir'].'/includes/libraries/Database/Meekrodb/db.class.php'; |
|
1101
|
|
|
DB::$host = DB_HOST; |
|
1102
|
|
|
DB::$user = DB_USER; |
|
1103
|
|
|
DB::$password = defuseReturnDecrypted(DB_PASSWD, $SETTINGS); |
|
1104
|
|
|
DB::$dbName = DB_NAME; |
|
1105
|
|
|
DB::$port = DB_PORT; |
|
1106
|
|
|
DB::$encoding = DB_ENCODING; |
|
1107
|
|
|
|
|
1108
|
|
|
$link = mysqli_connect(DB_HOST, DB_USER, defuseReturnDecrypted(DB_PASSWD, $SETTINGS), DB_NAME, DB_PORT); |
|
1109
|
|
|
$link->set_charset(DB_ENCODING); |
|
1110
|
|
|
|
|
1111
|
|
|
//Load Tree |
|
1112
|
|
|
$tree = new SplClassLoader('Tree\NestedTree', '../includes/libraries'); |
|
1113
|
|
|
$tree->register(); |
|
1114
|
|
|
$tree = new Tree\NestedTree\NestedTree(prefixTable('nested_tree'), 'id', 'parent_id', 'title'); |
|
1115
|
|
|
|
|
1116
|
|
|
// get new value from db |
|
1117
|
|
|
$data = DB::queryfirstrow( |
|
1118
|
|
|
'SELECT label, description, id_tree, perso, restricted_to, login, url |
|
1119
|
|
|
FROM '.prefixTable('items').' |
|
1120
|
|
|
WHERE id=%i', |
|
1121
|
|
|
$ident |
|
1122
|
|
|
); |
|
1123
|
|
|
// Get all TAGS |
|
1124
|
|
|
$tags = ''; |
|
1125
|
|
|
$itemTags = DB::query('SELECT tag FROM '.prefixTable('tags').' WHERE item_id=%i', $ident); |
|
1126
|
|
|
foreach ($itemTags as $itemTag) { |
|
1127
|
|
|
if (!empty($itemTag['tag'])) { |
|
1128
|
|
|
$tags .= $itemTag['tag'].' '; |
|
1129
|
|
|
} |
|
1130
|
|
|
} |
|
1131
|
|
|
// form id_tree to full foldername |
|
1132
|
|
|
$folder = ''; |
|
1133
|
|
|
$arbo = $tree->getPath($data['id_tree'], true); |
|
1134
|
|
|
foreach ($arbo as $elem) { |
|
1135
|
|
|
if ((int) $elem->title === $_SESSION['user_id'] && (int) $elem->nlevel === 1) { |
|
1136
|
|
|
$elem->title = $_SESSION['login']; |
|
1137
|
|
|
} |
|
1138
|
|
|
if (empty($folder)) { |
|
1139
|
|
|
$folder = stripslashes($elem->title); |
|
1140
|
|
|
} else { |
|
1141
|
|
|
$folder .= ' » '.stripslashes($elem->title); |
|
1142
|
|
|
} |
|
1143
|
|
|
} |
|
1144
|
|
|
// finaly update |
|
1145
|
|
|
DB::update( |
|
1146
|
|
|
prefixTable('cache'), |
|
1147
|
|
|
array( |
|
1148
|
|
|
'label' => $data['label'], |
|
1149
|
|
|
'description' => $data['description'], |
|
1150
|
|
|
'tags' => $tags, |
|
1151
|
|
|
'url' => (isset($data['url']) && !empty($data['url'])) ? $data['url'] : '0', |
|
1152
|
|
|
'id_tree' => $data['id_tree'], |
|
1153
|
|
|
'perso' => $data['perso'], |
|
1154
|
|
|
'restricted_to' => (isset($data['restricted_to']) && !empty($data['restricted_to'])) ? $data['restricted_to'] : '0', |
|
1155
|
|
|
'login' => isset($data['login']) ? $data['login'] : '', |
|
1156
|
|
|
'folder' => $folder, |
|
1157
|
|
|
'author' => $_SESSION['user_id'], |
|
1158
|
|
|
), |
|
1159
|
|
|
'id = %i', |
|
1160
|
|
|
$ident |
|
1161
|
|
|
); |
|
1162
|
|
|
} |
|
1163
|
|
|
|
|
1164
|
|
|
/** |
|
1165
|
|
|
* Cache table - add new value. |
|
1166
|
|
|
* |
|
1167
|
|
|
* @param array $SETTINGS Teampass settings |
|
1168
|
|
|
* @param string $ident Ident format |
|
1169
|
|
|
*/ |
|
1170
|
|
|
function cacheTableAdd($SETTINGS, $ident = null) |
|
1171
|
|
|
{ |
|
1172
|
|
|
include_once $SETTINGS['cpassman_dir'].'/sources/SplClassLoader.php'; |
|
1173
|
|
|
|
|
1174
|
|
|
//Connect to DB |
|
1175
|
|
|
include_once $SETTINGS['cpassman_dir'].'/includes/libraries/Database/Meekrodb/db.class.php'; |
|
1176
|
|
|
DB::$host = DB_HOST; |
|
1177
|
|
|
DB::$user = DB_USER; |
|
1178
|
|
|
DB::$password = defuseReturnDecrypted(DB_PASSWD, $SETTINGS); |
|
1179
|
|
|
DB::$dbName = DB_NAME; |
|
1180
|
|
|
DB::$port = DB_PORT; |
|
1181
|
|
|
DB::$encoding = DB_ENCODING; |
|
1182
|
|
|
|
|
1183
|
|
|
$link = mysqli_connect(DB_HOST, DB_USER, defuseReturnDecrypted(DB_PASSWD, $SETTINGS), DB_NAME, DB_PORT); |
|
1184
|
|
|
$link->set_charset(DB_ENCODING); |
|
1185
|
|
|
|
|
1186
|
|
|
//Load Tree |
|
1187
|
|
|
$tree = new SplClassLoader('Tree\NestedTree', '../includes/libraries'); |
|
1188
|
|
|
$tree->register(); |
|
1189
|
|
|
$tree = new Tree\NestedTree\NestedTree(prefixTable('nested_tree'), 'id', 'parent_id', 'title'); |
|
1190
|
|
|
|
|
1191
|
|
|
// get new value from db |
|
1192
|
|
|
$data = DB::queryFirstRow( |
|
1193
|
|
|
'SELECT i.label, i.description, i.id_tree as id_tree, i.perso, i.restricted_to, i.id, i.login, i.url, l.date |
|
1194
|
|
|
FROM '.prefixTable('items').' as i |
|
1195
|
|
|
INNER JOIN '.prefixTable('log_items').' as l ON (l.id_item = i.id) |
|
1196
|
|
|
WHERE i.id = %i |
|
1197
|
|
|
AND l.action = %s', |
|
1198
|
|
|
$ident, |
|
1199
|
|
|
'at_creation' |
|
1200
|
|
|
); |
|
1201
|
|
|
// Get all TAGS |
|
1202
|
|
|
$tags = ''; |
|
1203
|
|
|
$itemTags = DB::query('SELECT tag FROM '.prefixTable('tags').' WHERE item_id = %i', $ident); |
|
1204
|
|
|
foreach ($itemTags as $itemTag) { |
|
1205
|
|
|
if (!empty($itemTag['tag'])) { |
|
1206
|
|
|
$tags .= $itemTag['tag'].' '; |
|
1207
|
|
|
} |
|
1208
|
|
|
} |
|
1209
|
|
|
// form id_tree to full foldername |
|
1210
|
|
|
$folder = ''; |
|
1211
|
|
|
$arbo = $tree->getPath($data['id_tree'], true); |
|
1212
|
|
|
foreach ($arbo as $elem) { |
|
1213
|
|
|
if ((int) $elem->title === $_SESSION['user_id'] && (int) $elem->nlevel === 1) { |
|
1214
|
|
|
$elem->title = $_SESSION['login']; |
|
1215
|
|
|
} |
|
1216
|
|
|
if (empty($folder)) { |
|
1217
|
|
|
$folder = stripslashes($elem->title); |
|
1218
|
|
|
} else { |
|
1219
|
|
|
$folder .= ' » '.stripslashes($elem->title); |
|
1220
|
|
|
} |
|
1221
|
|
|
} |
|
1222
|
|
|
// finaly update |
|
1223
|
|
|
DB::insert( |
|
1224
|
|
|
prefixTable('cache'), |
|
1225
|
|
|
array( |
|
1226
|
|
|
'id' => $data['id'], |
|
1227
|
|
|
'label' => $data['label'], |
|
1228
|
|
|
'description' => $data['description'], |
|
1229
|
|
|
'tags' => (isset($tags) && !empty($tags)) ? $tags : 'None', |
|
1230
|
|
|
'url' => (isset($data['url']) && !empty($data['url'])) ? $data['url'] : '0', |
|
1231
|
|
|
'id_tree' => $data['id_tree'], |
|
1232
|
|
|
'perso' => (isset($data['perso']) && !empty($data['perso']) && $data['perso'] !== 'None') ? $data['perso'] : '0', |
|
1233
|
|
|
'restricted_to' => (isset($data['restricted_to']) && !empty($data['restricted_to'])) ? $data['restricted_to'] : '0', |
|
1234
|
|
|
'login' => isset($data['login']) ? $data['login'] : '', |
|
1235
|
|
|
'folder' => $folder, |
|
1236
|
|
|
'author' => $_SESSION['user_id'], |
|
1237
|
|
|
'timestamp' => $data['date'], |
|
1238
|
|
|
) |
|
1239
|
|
|
); |
|
1240
|
|
|
} |
|
1241
|
|
|
|
|
1242
|
|
|
/** |
|
1243
|
|
|
* Do statistics. |
|
1244
|
|
|
* |
|
1245
|
|
|
* @return array |
|
1246
|
|
|
*/ |
|
1247
|
|
|
function getStatisticsData() |
|
1248
|
|
|
{ |
|
1249
|
|
|
DB::query( |
|
1250
|
|
|
'SELECT id FROM '.prefixTable('nested_tree').' WHERE personal_folder = %i', |
|
1251
|
|
|
0 |
|
1252
|
|
|
); |
|
1253
|
|
|
$counter_folders = DB::count(); |
|
1254
|
|
|
|
|
1255
|
|
|
DB::query( |
|
1256
|
|
|
'SELECT id FROM '.prefixTable('nested_tree').' WHERE personal_folder = %i', |
|
1257
|
|
|
1 |
|
1258
|
|
|
); |
|
1259
|
|
|
$counter_folders_perso = DB::count(); |
|
1260
|
|
|
|
|
1261
|
|
|
DB::query( |
|
1262
|
|
|
'SELECT id FROM '.prefixTable('items').' WHERE perso = %i', |
|
1263
|
|
|
0 |
|
1264
|
|
|
); |
|
1265
|
|
|
$counter_items = DB::count(); |
|
1266
|
|
|
|
|
1267
|
|
|
DB::query( |
|
1268
|
|
|
'SELECT id FROM '.prefixTable('items').' WHERE perso = %i', |
|
1269
|
|
|
1 |
|
1270
|
|
|
); |
|
1271
|
|
|
$counter_items_perso = DB::count(); |
|
1272
|
|
|
|
|
1273
|
|
|
DB::query( |
|
1274
|
|
|
'SELECT id FROM '.prefixTable('users').'' |
|
1275
|
|
|
); |
|
1276
|
|
|
$counter_users = DB::count(); |
|
1277
|
|
|
|
|
1278
|
|
|
DB::query( |
|
1279
|
|
|
'SELECT id FROM '.prefixTable('users').' WHERE admin = %i', |
|
1280
|
|
|
1 |
|
1281
|
|
|
); |
|
1282
|
|
|
$admins = DB::count(); |
|
1283
|
|
|
|
|
1284
|
|
|
DB::query( |
|
1285
|
|
|
'SELECT id FROM '.prefixTable('users').' WHERE gestionnaire = %i', |
|
1286
|
|
|
1 |
|
1287
|
|
|
); |
|
1288
|
|
|
$managers = DB::count(); |
|
1289
|
|
|
|
|
1290
|
|
|
DB::query( |
|
1291
|
|
|
'SELECT id FROM '.prefixTable('users').' WHERE read_only = %i', |
|
1292
|
|
|
1 |
|
1293
|
|
|
); |
|
1294
|
|
|
$readOnly = DB::count(); |
|
1295
|
|
|
|
|
1296
|
|
|
// list the languages |
|
1297
|
|
|
$usedLang = []; |
|
1298
|
|
|
$tp_languages = DB::query( |
|
1299
|
|
|
'SELECT name FROM '.prefixTable('languages') |
|
1300
|
|
|
); |
|
1301
|
|
|
foreach ($tp_languages as $tp_language) { |
|
1302
|
|
|
DB::query( |
|
1303
|
|
|
'SELECT * FROM '.prefixTable('users').' WHERE user_language = %s', |
|
1304
|
|
|
$tp_language['name'] |
|
1305
|
|
|
); |
|
1306
|
|
|
$usedLang[$tp_language['name']] = round((DB::count() * 100 / $counter_users), 0); |
|
1307
|
|
|
} |
|
1308
|
|
|
|
|
1309
|
|
|
// get list of ips |
|
1310
|
|
|
$usedIp = []; |
|
1311
|
|
|
$tp_ips = DB::query( |
|
1312
|
|
|
'SELECT user_ip FROM '.prefixTable('users') |
|
1313
|
|
|
); |
|
1314
|
|
|
foreach ($tp_ips as $ip) { |
|
1315
|
|
|
if (array_key_exists($ip['user_ip'], $usedIp)) { |
|
1316
|
|
|
$usedIp[$ip['user_ip']] = $usedIp[$ip['user_ip']] + 1; |
|
1317
|
|
|
} elseif (!empty($ip['user_ip']) && $ip['user_ip'] !== 'none') { |
|
1318
|
|
|
$usedIp[$ip['user_ip']] = 1; |
|
1319
|
|
|
} |
|
1320
|
|
|
} |
|
1321
|
|
|
|
|
1322
|
|
|
return array( |
|
1323
|
|
|
'error' => '', |
|
1324
|
|
|
'stat_phpversion' => phpversion(), |
|
1325
|
|
|
'stat_folders' => $counter_folders, |
|
1326
|
|
|
'stat_folders_shared' => intval($counter_folders) - intval($counter_folders_perso), |
|
1327
|
|
|
'stat_items' => $counter_items, |
|
1328
|
|
|
'stat_items_shared' => intval($counter_items) - intval($counter_items_perso), |
|
1329
|
|
|
'stat_users' => $counter_users, |
|
1330
|
|
|
'stat_admins' => $admins, |
|
1331
|
|
|
'stat_managers' => $managers, |
|
1332
|
|
|
'stat_ro' => $readOnly, |
|
1333
|
|
|
'stat_kb' => $SETTINGS['enable_kb'], |
|
|
|
|
|
|
1334
|
|
|
'stat_pf' => $SETTINGS['enable_pf_feature'], |
|
1335
|
|
|
'stat_fav' => $SETTINGS['enable_favourites'], |
|
1336
|
|
|
'stat_teampassversion' => $SETTINGS['cpassman_version'], |
|
1337
|
|
|
'stat_ldap' => $SETTINGS['ldap_mode'], |
|
1338
|
|
|
'stat_agses' => $SETTINGS['agses_authentication_enabled'], |
|
1339
|
|
|
'stat_duo' => $SETTINGS['duo'], |
|
1340
|
|
|
'stat_suggestion' => $SETTINGS['enable_suggestion'], |
|
1341
|
|
|
'stat_api' => $SETTINGS['api'], |
|
1342
|
|
|
'stat_customfields' => $SETTINGS['item_extra_fields'], |
|
1343
|
|
|
'stat_syslog' => $SETTINGS['syslog_enable'], |
|
1344
|
|
|
'stat_2fa' => $SETTINGS['google_authentication'], |
|
1345
|
|
|
'stat_stricthttps' => $SETTINGS['enable_sts'], |
|
1346
|
|
|
'stat_mysqlversion' => DB::serverVersion(), |
|
1347
|
|
|
'stat_languages' => $usedLang, |
|
1348
|
|
|
'stat_country' => $usedIp, |
|
1349
|
|
|
); |
|
1350
|
|
|
} |
|
1351
|
|
|
|
|
1352
|
|
|
/** |
|
1353
|
|
|
* Permits to send an email. |
|
1354
|
|
|
* |
|
1355
|
|
|
* @param string $subject email subject |
|
1356
|
|
|
* @param string $textMail email message |
|
1357
|
|
|
* @param string $email email |
|
1358
|
|
|
* @param array $SETTINGS settings |
|
1359
|
|
|
* @param string $textMailAlt email message alt |
|
1360
|
|
|
* @param bool $silent no errors |
|
1361
|
|
|
* |
|
1362
|
|
|
* @return string some json info |
|
1363
|
|
|
*/ |
|
1364
|
|
|
function sendEmail( |
|
1365
|
|
|
$subject, |
|
1366
|
|
|
$textMail, |
|
1367
|
|
|
$email, |
|
1368
|
|
|
$SETTINGS, |
|
1369
|
|
|
$textMailAlt = null, |
|
1370
|
|
|
$silent = true |
|
1371
|
|
|
) { |
|
1372
|
|
|
// CAse where email not defined |
|
1373
|
|
|
if ($email === 'none') { |
|
1374
|
|
|
return '"error":"" , "message":"'.langHdl('forgot_my_pw_email_sent').'"'; |
|
1375
|
|
|
} |
|
1376
|
|
|
|
|
1377
|
|
|
// Load settings |
|
1378
|
|
|
include_once $SETTINGS['cpassman_dir'].'/includes/config/settings.php'; |
|
1379
|
|
|
|
|
1380
|
|
|
// Load superglobal |
|
1381
|
|
|
include_once $SETTINGS['cpassman_dir'].'/includes/libraries/protect/SuperGlobal/SuperGlobal.php'; |
|
1382
|
|
|
$superGlobal = new protect\SuperGlobal\SuperGlobal(); |
|
1383
|
|
|
|
|
1384
|
|
|
// Get user language |
|
1385
|
|
|
$session_user_language = $superGlobal->get('user_language', 'SESSION'); |
|
1386
|
|
|
$user_language = isset($session_user_language) ? $session_user_language : 'english'; |
|
1387
|
|
|
include_once $SETTINGS['cpassman_dir'].'/includes/language/'.$user_language.'.php'; |
|
1388
|
|
|
|
|
1389
|
|
|
// Load library |
|
1390
|
|
|
include_once $SETTINGS['cpassman_dir'].'/sources/SplClassLoader.php'; |
|
1391
|
|
|
|
|
1392
|
|
|
// load PHPMailer |
|
1393
|
|
|
$mail = new SplClassLoader('Email\PHPMailer', '../includes/libraries'); |
|
1394
|
|
|
$mail->register(); |
|
1395
|
|
|
$mail = new Email\PHPMailer\PHPMailer(true); |
|
1396
|
|
|
try { |
|
1397
|
|
|
// send to user |
|
1398
|
|
|
$mail->setLanguage('en', $SETTINGS['cpassman_dir'].'/includes/libraries/Email/PHPMailer/language/'); |
|
1399
|
|
|
$mail->SMTPDebug = 0; //value 1 can be used to debug - 4 for debuging connections |
|
1400
|
|
|
$mail->Port = $SETTINGS['email_port']; //COULD BE USED |
|
1401
|
|
|
$mail->CharSet = 'utf-8'; |
|
1402
|
|
|
$mail->SMTPSecure = ($SETTINGS['email_security'] === 'tls' |
|
1403
|
|
|
|| $SETTINGS['email_security'] === 'ssl') ? $SETTINGS['email_security'] : ''; |
|
1404
|
|
|
$mail->SMTPAutoTLS = ($SETTINGS['email_security'] === 'tls' |
|
1405
|
|
|
|| $SETTINGS['email_security'] === 'ssl') ? true : false; |
|
1406
|
|
|
$mail->SMTPOptions = array( |
|
1407
|
|
|
'ssl' => array( |
|
1408
|
|
|
'verify_peer' => false, |
|
1409
|
|
|
'verify_peer_name' => false, |
|
1410
|
|
|
'allow_self_signed' => true, |
|
1411
|
|
|
), |
|
1412
|
|
|
); |
|
1413
|
|
|
$mail->isSmtp(); // send via SMTP |
|
1414
|
|
|
$mail->Host = $SETTINGS['email_smtp_server']; // SMTP servers |
|
1415
|
|
|
$mail->SMTPAuth = (int) $SETTINGS['email_smtp_auth'] === 1 ? true : false; // turn on SMTP authentication |
|
1416
|
|
|
$mail->Username = $SETTINGS['email_auth_username']; // SMTP username |
|
1417
|
|
|
$mail->Password = $SETTINGS['email_auth_pwd']; // SMTP password |
|
1418
|
|
|
$mail->From = $SETTINGS['email_from']; |
|
1419
|
|
|
$mail->FromName = $SETTINGS['email_from_name']; |
|
1420
|
|
|
|
|
1421
|
|
|
// Prepare for each person |
|
1422
|
|
|
foreach (array_filter(explode(',', $email)) as $dest) { |
|
1423
|
|
|
$mail->addAddress($dest); |
|
1424
|
|
|
} |
|
1425
|
|
|
|
|
1426
|
|
|
// Prepare HTML |
|
1427
|
|
|
$text_html = emailBody($textMail); |
|
1428
|
|
|
|
|
1429
|
|
|
$mail->WordWrap = 80; // set word wrap |
|
1430
|
|
|
$mail->isHtml(true); // send as HTML |
|
1431
|
|
|
$mail->Subject = $subject; |
|
1432
|
|
|
$mail->Body = $text_html; |
|
1433
|
|
|
$mail->AltBody = (is_null($textMailAlt) === false) ? $textMailAlt : ''; |
|
1434
|
|
|
|
|
1435
|
|
|
// send email |
|
1436
|
|
|
if ($mail->send()) { |
|
1437
|
|
|
if ($silent === false) { |
|
1438
|
|
|
return json_encode( |
|
1439
|
|
|
array( |
|
1440
|
|
|
'error' => false, |
|
1441
|
|
|
'message' => langHdl('forgot_my_pw_email_sent'), |
|
1442
|
|
|
) |
|
1443
|
|
|
); |
|
1444
|
|
|
} |
|
1445
|
|
|
} elseif ($silent === false) { |
|
1446
|
|
|
return json_encode( |
|
1447
|
|
|
array( |
|
1448
|
|
|
'error' => true, |
|
1449
|
|
|
'message' => str_replace(array("\n", "\t", "\r"), '', $mail->ErrorInfo), |
|
1450
|
|
|
) |
|
1451
|
|
|
); |
|
1452
|
|
|
} |
|
1453
|
|
|
} catch (Exception $e) { |
|
1454
|
|
|
if ($silent === false) { |
|
1455
|
|
|
return json_encode( |
|
1456
|
|
|
array( |
|
1457
|
|
|
'error' => true, |
|
1458
|
|
|
'message' => str_replace(array("\n", "\t", "\r"), '', $mail->ErrorInfo), |
|
1459
|
|
|
) |
|
1460
|
|
|
); |
|
1461
|
|
|
} |
|
1462
|
|
|
} |
|
1463
|
|
|
} |
|
1464
|
|
|
|
|
1465
|
|
|
/** |
|
1466
|
|
|
* Returns the email body. |
|
1467
|
|
|
* |
|
1468
|
|
|
* @param string $textMail Text for the email |
|
1469
|
|
|
* |
|
1470
|
|
|
* @return string |
|
1471
|
|
|
*/ |
|
1472
|
|
|
function emailBody($textMail) |
|
1473
|
|
|
{ |
|
1474
|
|
|
return '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.= |
|
1475
|
|
|
w3.org/TR/html4/loose.dtd"><html> |
|
1476
|
|
|
<head><title>Email Template</title> |
|
1477
|
|
|
<style type="text/css"> |
|
1478
|
|
|
body { background-color: #f0f0f0; padding: 10px 0; margin:0 0 10px =0; } |
|
1479
|
|
|
</style></head> |
|
1480
|
|
|
<body style="-ms-text-size-adjust: none; size-adjust: none; margin: 0; padding: 10px 0; background-color: #f0f0f0;" bgcolor="#f0f0f0" leftmargin="0" topmargin="0" marginwidth="0" marginheight="0"> |
|
1481
|
|
|
<table border="0" width="100%" height="100%" cellpadding="0" cellspacing="0" bgcolor="#f0f0f0" style="border-spacing: 0;"> |
|
1482
|
|
|
<tr><td style="border-collapse: collapse;"><br> |
|
1483
|
|
|
<table border="0" width="100%" cellpadding="0" cellspacing="0" bgcolor="#17357c" style="border-spacing: 0; margin-bottom: 25px;"> |
|
1484
|
|
|
<tr><td style="border-collapse: collapse; padding: 11px 20px;"> |
|
1485
|
|
|
<div style="max-width:150px; max-height:34px; color:#f0f0f0; font-weight:bold;">Teampass</div> |
|
1486
|
|
|
</td></tr></table></td> |
|
1487
|
|
|
</tr> |
|
1488
|
|
|
<tr><td align="center" valign="top" bgcolor="#f0f0f0" style="border-collapse: collapse; background-color: #f0f0f0;"> |
|
1489
|
|
|
<table width="600" cellpadding="0" cellspacing="0" border="0" class="container" bgcolor="#ffffff" style="border-spacing: 0; border-bottom: 1px solid #e0e0e0; box-shadow: 0 0 3px #ddd; color: #434343; font-family: Helvetica, Verdana, sans-serif;"> |
|
1490
|
|
|
<tr><td class="container-padding" bgcolor="#ffffff" style="border-collapse: collapse; border-left: 1px solid #e0e0e0; background-color: #ffffff; padding-left: 30px; padding-right: 30px;"> |
|
1491
|
|
|
<br><div style="float:right;">'. |
|
1492
|
|
|
$textMail. |
|
1493
|
|
|
'<br><br></td></tr></table> |
|
1494
|
|
|
</td></tr></table> |
|
1495
|
|
|
<br></body></html>'; |
|
1496
|
|
|
} |
|
1497
|
|
|
|
|
1498
|
|
|
/** |
|
1499
|
|
|
* Generate a Key. |
|
1500
|
|
|
* |
|
1501
|
|
|
* @return string |
|
1502
|
|
|
*/ |
|
1503
|
|
|
function generateKey() |
|
1504
|
|
|
{ |
|
1505
|
|
|
return substr(md5(rand().rand()), 0, 15); |
|
1506
|
|
|
} |
|
1507
|
|
|
|
|
1508
|
|
|
/** |
|
1509
|
|
|
* Convert date to timestamp. |
|
1510
|
|
|
* |
|
1511
|
|
|
* @param string $date The date |
|
1512
|
|
|
* @param array $SETTINGS Teampass settings |
|
1513
|
|
|
* |
|
1514
|
|
|
* @return string |
|
1515
|
|
|
*/ |
|
1516
|
|
|
function dateToStamp($date, $SETTINGS) |
|
1517
|
|
|
{ |
|
1518
|
|
|
$date = date_parse_from_format($SETTINGS['date_format'], $date); |
|
1519
|
|
|
if ((int) $date['warning_count'] === 0 && (int) $date['error_count'] === 0) { |
|
1520
|
|
|
return mktime(23, 59, 59, $date['month'], $date['day'], $date['year']); |
|
1521
|
|
|
} else { |
|
1522
|
|
|
return ''; |
|
1523
|
|
|
} |
|
1524
|
|
|
} |
|
1525
|
|
|
|
|
1526
|
|
|
/** |
|
1527
|
|
|
* Is this a date. |
|
1528
|
|
|
* |
|
1529
|
|
|
* @param string $date Date |
|
1530
|
|
|
* |
|
1531
|
|
|
* @return bool |
|
1532
|
|
|
*/ |
|
1533
|
|
|
function isDate($date) |
|
1534
|
|
|
{ |
|
1535
|
|
|
return strtotime($date) !== false; |
|
1536
|
|
|
} |
|
1537
|
|
|
|
|
1538
|
|
|
/** |
|
1539
|
|
|
* isUTF8(). |
|
1540
|
|
|
* |
|
1541
|
|
|
* @return int is the string in UTF8 format |
|
1542
|
|
|
*/ |
|
1543
|
|
|
function isUTF8($string) |
|
1544
|
|
|
{ |
|
1545
|
|
|
if (is_array($string) === true) { |
|
1546
|
|
|
$string = $string['string']; |
|
1547
|
|
|
} |
|
1548
|
|
|
|
|
1549
|
|
|
return preg_match( |
|
1550
|
|
|
'%^(?: |
|
1551
|
|
|
[\x09\x0A\x0D\x20-\x7E] # ASCII |
|
1552
|
|
|
| [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte |
|
1553
|
|
|
| \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs |
|
1554
|
|
|
| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte |
|
1555
|
|
|
| \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates |
|
1556
|
|
|
| \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 |
|
1557
|
|
|
| [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 |
|
1558
|
|
|
| \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 |
|
1559
|
|
|
)*$%xs', |
|
1560
|
|
|
$string |
|
1561
|
|
|
); |
|
1562
|
|
|
} |
|
1563
|
|
|
|
|
1564
|
|
|
/** |
|
1565
|
|
|
* Prepare an array to UTF8 format before JSON_encode. |
|
1566
|
|
|
* |
|
1567
|
|
|
* @param array $array Array of values |
|
1568
|
|
|
* |
|
1569
|
|
|
* @return array |
|
1570
|
|
|
*/ |
|
1571
|
|
|
function utf8Converter($array) |
|
1572
|
|
|
{ |
|
1573
|
|
|
array_walk_recursive( |
|
1574
|
|
|
$array, |
|
1575
|
|
|
function (&$item, $key) { |
|
1576
|
|
|
if (mb_detect_encoding($item, 'utf-8', true) === false) { |
|
1577
|
|
|
$item = utf8_encode($item); |
|
1578
|
|
|
} |
|
1579
|
|
|
} |
|
1580
|
|
|
); |
|
1581
|
|
|
|
|
1582
|
|
|
return $array; |
|
1583
|
|
|
} |
|
1584
|
|
|
|
|
1585
|
|
|
/** |
|
1586
|
|
|
* Permits to prepare data to be exchanged. |
|
1587
|
|
|
* |
|
1588
|
|
|
* @param array|string $data Text |
|
1589
|
|
|
* @param string $type Parameter |
|
1590
|
|
|
* @param string $key Optional key |
|
1591
|
|
|
* |
|
1592
|
|
|
* @return string |
|
1593
|
|
|
*/ |
|
1594
|
|
|
function prepareExchangedData($data, $type, $key = null) |
|
1595
|
|
|
{ |
|
1596
|
|
|
if (isset($SETTINGS['cpassman_dir']) === false || empty($SETTINGS['cpassman_dir'])) { |
|
|
|
|
|
|
1597
|
|
|
if (file_exists('../includes/config/tp.config.php')) { |
|
1598
|
|
|
include '../includes/config/tp.config.php'; |
|
1599
|
|
|
} elseif (file_exists('./includes/config/tp.config.php')) { |
|
1600
|
|
|
include './includes/config/tp.config.php'; |
|
1601
|
|
|
} elseif (file_exists('../../includes/config/tp.config.php')) { |
|
1602
|
|
|
include '../../includes/config/tp.config.php'; |
|
1603
|
|
|
} else { |
|
1604
|
|
|
throw new Exception("Error file '/includes/config/tp.config.php' not exists", 1); |
|
1605
|
|
|
} |
|
1606
|
|
|
} |
|
1607
|
|
|
|
|
1608
|
|
|
//load ClassLoader |
|
1609
|
|
|
include_once $SETTINGS['cpassman_dir'].'/sources/SplClassLoader.php'; |
|
1610
|
|
|
//Load AES |
|
1611
|
|
|
$aes = new SplClassLoader('Encryption\Crypt', $SETTINGS['cpassman_dir'].'/includes/libraries'); |
|
|
|
|
|
|
1612
|
|
|
$aes->register(); |
|
1613
|
|
|
|
|
1614
|
|
|
if ($key !== null) { |
|
1615
|
|
|
$_SESSION['key'] = $key; |
|
1616
|
|
|
} |
|
1617
|
|
|
|
|
1618
|
|
|
if ($type === 'encode' && is_array($data) === true) { |
|
1619
|
|
|
// Ensure UTF8 format |
|
1620
|
|
|
$data = utf8Converter($data); |
|
1621
|
|
|
// Now encode |
|
1622
|
|
|
if (isset($SETTINGS['encryptClientServer']) |
|
1623
|
|
|
&& $SETTINGS['encryptClientServer'] === '0' |
|
1624
|
|
|
) { |
|
1625
|
|
|
return json_encode( |
|
1626
|
|
|
$data, |
|
1627
|
|
|
JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP |
|
1628
|
|
|
); |
|
1629
|
|
|
} else { |
|
1630
|
|
|
return Encryption\Crypt\aesctr::encrypt( |
|
1631
|
|
|
json_encode( |
|
1632
|
|
|
$data, |
|
1633
|
|
|
JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP |
|
1634
|
|
|
), |
|
1635
|
|
|
$_SESSION['key'], |
|
1636
|
|
|
256 |
|
1637
|
|
|
); |
|
1638
|
|
|
} |
|
1639
|
|
|
} elseif ($type === 'decode' && is_array($data) === false) { |
|
1640
|
|
|
if (isset($SETTINGS['encryptClientServer']) |
|
1641
|
|
|
&& $SETTINGS['encryptClientServer'] === '0' |
|
1642
|
|
|
) { |
|
1643
|
|
|
return json_decode( |
|
1644
|
|
|
$data, |
|
|
|
|
|
|
1645
|
|
|
true |
|
1646
|
|
|
); |
|
1647
|
|
|
} else { |
|
1648
|
|
|
return json_decode( |
|
1649
|
|
|
Encryption\Crypt\aesctr::decrypt( |
|
1650
|
|
|
$data, |
|
|
|
|
|
|
1651
|
|
|
$_SESSION['key'], |
|
1652
|
|
|
256 |
|
1653
|
|
|
), |
|
1654
|
|
|
true |
|
1655
|
|
|
); |
|
1656
|
|
|
} |
|
1657
|
|
|
} |
|
1658
|
|
|
} |
|
1659
|
|
|
|
|
1660
|
|
|
/** |
|
1661
|
|
|
* Create a thumbnail. |
|
1662
|
|
|
* |
|
1663
|
|
|
* @param string $src Source |
|
1664
|
|
|
* @param string $dest Destination |
|
1665
|
|
|
* @param float $desired_width Size of width |
|
1666
|
|
|
*/ |
|
1667
|
|
|
function makeThumbnail($src, $dest, $desired_width) |
|
1668
|
|
|
{ |
|
1669
|
|
|
/* read the source image */ |
|
1670
|
|
|
$source_image = imagecreatefrompng($src); |
|
1671
|
|
|
$width = imagesx($source_image); |
|
1672
|
|
|
$height = imagesy($source_image); |
|
1673
|
|
|
|
|
1674
|
|
|
/* find the "desired height" of this thumbnail, relative to the desired width */ |
|
1675
|
|
|
$desired_height = floor($height * ($desired_width / $width)); |
|
1676
|
|
|
|
|
1677
|
|
|
/* create a new, "virtual" image */ |
|
1678
|
|
|
$virtual_image = imagecreatetruecolor($desired_width, $desired_height); |
|
|
|
|
|
|
1679
|
|
|
|
|
1680
|
|
|
/* copy source image at a resized size */ |
|
1681
|
|
|
imagecopyresampled($virtual_image, $source_image, 0, 0, 0, 0, $desired_width, $desired_height, $width, $height); |
|
|
|
|
|
|
1682
|
|
|
|
|
1683
|
|
|
/* create the physical thumbnail image to its destination */ |
|
1684
|
|
|
imagejpeg($virtual_image, $dest); |
|
1685
|
|
|
} |
|
1686
|
|
|
|
|
1687
|
|
|
/** |
|
1688
|
|
|
* Check table prefix in SQL query. |
|
1689
|
|
|
* |
|
1690
|
|
|
* @param string $table Table name |
|
1691
|
|
|
* |
|
1692
|
|
|
* @return string |
|
1693
|
|
|
*/ |
|
1694
|
|
|
function prefixTable($table) |
|
1695
|
|
|
{ |
|
1696
|
|
|
$safeTable = htmlspecialchars(DB_PREFIX.$table); |
|
1697
|
|
|
if (!empty($safeTable)) { |
|
1698
|
|
|
// sanitize string |
|
1699
|
|
|
return $safeTable; |
|
1700
|
|
|
} else { |
|
1701
|
|
|
// stop error no table |
|
1702
|
|
|
return 'table_not_exists'; |
|
1703
|
|
|
} |
|
1704
|
|
|
} |
|
1705
|
|
|
|
|
1706
|
|
|
/* |
|
1707
|
|
|
* Creates a KEY using PasswordLib |
|
1708
|
|
|
*/ |
|
1709
|
|
|
function GenerateCryptKey($size = null, $secure = false, $numerals = false, $capitalize = false, $symbols = false) |
|
1710
|
|
|
{ |
|
1711
|
|
|
global $SETTINGS; |
|
1712
|
|
|
include_once $SETTINGS['cpassman_dir'].'/sources/SplClassLoader.php'; |
|
1713
|
|
|
|
|
1714
|
|
|
if ($secure === true) { |
|
1715
|
|
|
$numerals = true; |
|
1716
|
|
|
$capitalize = true; |
|
1717
|
|
|
$symbols = true; |
|
1718
|
|
|
} |
|
1719
|
|
|
|
|
1720
|
|
|
// Load libraries |
|
1721
|
|
|
$generator = new SplClassLoader('PasswordGenerator\Generator', '../includes/libraries'); |
|
1722
|
|
|
$generator->register(); |
|
1723
|
|
|
$generator = new PasswordGenerator\Generator\ComputerPasswordGenerator(); |
|
1724
|
|
|
|
|
1725
|
|
|
// Can we use PHP7 random_int function? |
|
1726
|
|
|
/*if (version_compare(phpversion(), '7.0', '>=')) { |
|
1727
|
|
|
include_once $SETTINGS['cpassman_dir'].'/includes/libraries/PasswordGenerator/RandomGenerator/Php7RandomGenerator.php'; |
|
1728
|
|
|
$generator->setRandomGenerator(new PasswordGenerator\RandomGenerator\Php7RandomGenerator()); |
|
1729
|
|
|
}*/ |
|
1730
|
|
|
|
|
1731
|
|
|
// init |
|
1732
|
|
|
if (empty($size) === false && is_null($size) === false) { |
|
1733
|
|
|
$generator->setLength(intval($size)); |
|
1734
|
|
|
} |
|
1735
|
|
|
if (empty($numerals) === false) { |
|
1736
|
|
|
$generator->setNumbers($numerals); |
|
1737
|
|
|
} |
|
1738
|
|
|
if (empty($capitalize) === false) { |
|
1739
|
|
|
$generator->setUppercase($capitalize); |
|
1740
|
|
|
} |
|
1741
|
|
|
if (empty($symbols) === false) { |
|
1742
|
|
|
$generator->setSymbols($symbols); |
|
1743
|
|
|
} |
|
1744
|
|
|
|
|
1745
|
|
|
// generate and send back |
|
1746
|
|
|
return $generator->generatePassword(); |
|
1747
|
|
|
} |
|
1748
|
|
|
|
|
1749
|
|
|
/* |
|
1750
|
|
|
* Send sysLOG message |
|
1751
|
|
|
* @param string $message |
|
1752
|
|
|
* @param string $host |
|
1753
|
|
|
*/ |
|
1754
|
|
|
function send_syslog($message, $host, $port, $component = 'teampass') |
|
1755
|
|
|
{ |
|
1756
|
|
|
$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); |
|
1757
|
|
|
$syslog_message = '<123>'.date('M d H:i:s ').$component.': '.$message; |
|
1758
|
|
|
socket_sendto($sock, $syslog_message, strlen($syslog_message), 0, $host, $port); |
|
1759
|
|
|
socket_close($sock); |
|
1760
|
|
|
} |
|
1761
|
|
|
|
|
1762
|
|
|
/** |
|
1763
|
|
|
* logEvents(). |
|
1764
|
|
|
* |
|
1765
|
|
|
* permits to log events into DB |
|
1766
|
|
|
* |
|
1767
|
|
|
* @param string $type |
|
1768
|
|
|
* @param string $label |
|
1769
|
|
|
* @param string $field_1 |
|
1770
|
|
|
*/ |
|
1771
|
|
|
function logEvents($type, $label, $who, $login = null, $field_1 = null) |
|
1772
|
|
|
{ |
|
1773
|
|
|
global $server, $user, $pass, $database, $port, $encoding; |
|
1774
|
|
|
global $SETTINGS; |
|
1775
|
|
|
|
|
1776
|
|
|
if (empty($who)) { |
|
1777
|
|
|
$who = getClientIpServer(); |
|
1778
|
|
|
} |
|
1779
|
|
|
|
|
1780
|
|
|
// include librairies & connect to DB |
|
1781
|
|
|
require_once $SETTINGS['cpassman_dir'].'/includes/libraries/Database/Meekrodb/db.class.php'; |
|
1782
|
|
|
DB::$host = DB_HOST; |
|
1783
|
|
|
DB::$user = DB_USER; |
|
1784
|
|
|
DB::$password = defuseReturnDecrypted(DB_PASSWD, $SETTINGS); |
|
1785
|
|
|
DB::$dbName = DB_NAME; |
|
1786
|
|
|
DB::$port = DB_PORT; |
|
1787
|
|
|
DB::$encoding = DB_ENCODING; |
|
1788
|
|
|
//DB::$errorHandler = true; |
|
1789
|
|
|
|
|
1790
|
|
|
$link = mysqli_connect(DB_HOST, DB_USER, defuseReturnDecrypted(DB_PASSWD, $SETTINGS), DB_NAME, DB_PORT); |
|
1791
|
|
|
$link->set_charset(DB_ENCODING); |
|
1792
|
|
|
|
|
1793
|
|
|
DB::insert( |
|
1794
|
|
|
prefixTable('log_system'), |
|
1795
|
|
|
array( |
|
1796
|
|
|
'type' => $type, |
|
1797
|
|
|
'date' => time(), |
|
1798
|
|
|
'label' => $label, |
|
1799
|
|
|
'qui' => $who, |
|
1800
|
|
|
'field_1' => $field_1 === null ? '' : $field_1, |
|
1801
|
|
|
) |
|
1802
|
|
|
); |
|
1803
|
|
|
|
|
1804
|
|
|
// If SYSLOG |
|
1805
|
|
|
if (isset($SETTINGS['syslog_enable']) === true && (int) $SETTINGS['syslog_enable'] === 1) { |
|
1806
|
|
|
if ($type === 'user_mngt') { |
|
1807
|
|
|
send_syslog( |
|
1808
|
|
|
'action='.str_replace('at_', '', $label).' attribute=user user='.$who.' userid="'.$login.'" change="'.$field_1.'" ', |
|
1809
|
|
|
$SETTINGS['syslog_host'], |
|
1810
|
|
|
$SETTINGS['syslog_port'], |
|
1811
|
|
|
'teampass' |
|
1812
|
|
|
); |
|
1813
|
|
|
} else { |
|
1814
|
|
|
send_syslog( |
|
1815
|
|
|
'action='.$type.' attribute='.$label.' user='.$who.' userid="'.$login.'" ', |
|
1816
|
|
|
$SETTINGS['syslog_host'], |
|
1817
|
|
|
$SETTINGS['syslog_port'], |
|
1818
|
|
|
'teampass' |
|
1819
|
|
|
); |
|
1820
|
|
|
} |
|
1821
|
|
|
} |
|
1822
|
|
|
} |
|
1823
|
|
|
|
|
1824
|
|
|
/** |
|
1825
|
|
|
* Log events. |
|
1826
|
|
|
* |
|
1827
|
|
|
* @param array $SETTINGS Teampass settings |
|
1828
|
|
|
* @param int $item_id Item id |
|
1829
|
|
|
* @param string $item_label Item label |
|
1830
|
|
|
* @param int $id_user User id |
|
1831
|
|
|
* @param string $action Code for reason |
|
1832
|
|
|
* @param string $login User login |
|
1833
|
|
|
* @param string $raison Code for reason |
|
1834
|
|
|
* @param string $encryption_type Encryption on |
|
1835
|
|
|
*/ |
|
1836
|
|
|
function logItems( |
|
1837
|
|
|
$SETTINGS, |
|
1838
|
|
|
$item_id, |
|
1839
|
|
|
$item_label, |
|
1840
|
|
|
$id_user, |
|
1841
|
|
|
$action, |
|
1842
|
|
|
$login = null, |
|
1843
|
|
|
$raison = null, |
|
1844
|
|
|
$encryption_type = null |
|
1845
|
|
|
) { |
|
1846
|
|
|
$dataItem = ''; |
|
1847
|
|
|
|
|
1848
|
|
|
// include librairies & connect to DB |
|
1849
|
|
|
include_once $SETTINGS['cpassman_dir'].'/includes/libraries/Database/Meekrodb/db.class.php'; |
|
1850
|
|
|
DB::$host = DB_HOST; |
|
1851
|
|
|
DB::$user = DB_USER; |
|
1852
|
|
|
DB::$password = defuseReturnDecrypted(DB_PASSWD, $SETTINGS); |
|
1853
|
|
|
DB::$dbName = DB_NAME; |
|
1854
|
|
|
DB::$port = DB_PORT; |
|
1855
|
|
|
DB::$encoding = DB_ENCODING; |
|
1856
|
|
|
$link = mysqli_connect(DB_HOST, DB_USER, defuseReturnDecrypted(DB_PASSWD, $SETTINGS), DB_NAME, DB_PORT); |
|
1857
|
|
|
$link->set_charset(DB_ENCODING); |
|
1858
|
|
|
|
|
1859
|
|
|
// Insert log in DB |
|
1860
|
|
|
DB::insert( |
|
1861
|
|
|
prefixTable('log_items'), |
|
1862
|
|
|
array( |
|
1863
|
|
|
'id_item' => $item_id, |
|
1864
|
|
|
'date' => time(), |
|
1865
|
|
|
'id_user' => $id_user, |
|
1866
|
|
|
'action' => $action, |
|
1867
|
|
|
'raison' => $raison, |
|
1868
|
|
|
'raison_iv' => '', |
|
1869
|
|
|
'encryption_type' => is_null($encryption_type) === true ? TP_ENCRYPTION_NAME : $encryption_type, |
|
1870
|
|
|
) |
|
1871
|
|
|
); |
|
1872
|
|
|
// Timestamp the last change |
|
1873
|
|
|
if ($action === 'at_creation' || $action === 'at_modifiation' || $action === 'at_delete' || $action === 'at_import') { |
|
1874
|
|
|
DB::update( |
|
1875
|
|
|
prefixTable('misc'), |
|
1876
|
|
|
array( |
|
1877
|
|
|
'valeur' => time(), |
|
1878
|
|
|
), |
|
1879
|
|
|
'type = %s AND intitule = %s', |
|
1880
|
|
|
'timestamp', |
|
1881
|
|
|
'last_item_change' |
|
1882
|
|
|
); |
|
1883
|
|
|
} |
|
1884
|
|
|
|
|
1885
|
|
|
// SYSLOG |
|
1886
|
|
|
if (isset($SETTINGS['syslog_enable']) === true && $SETTINGS['syslog_enable'] === '1') { |
|
1887
|
|
|
// Extract reason |
|
1888
|
|
|
$attribute = explode(' : ', $raison); |
|
1889
|
|
|
|
|
1890
|
|
|
// Get item info if not known |
|
1891
|
|
|
if (empty($item_label) === true) { |
|
1892
|
|
|
$dataItem = DB::queryfirstrow( |
|
1893
|
|
|
'SELECT id, id_tree, label |
|
1894
|
|
|
FROM '.prefixTable('items').' |
|
1895
|
|
|
WHERE id = %i', |
|
1896
|
|
|
$item_id |
|
1897
|
|
|
); |
|
1898
|
|
|
|
|
1899
|
|
|
$item_label = $dataItem['label']; |
|
1900
|
|
|
} |
|
1901
|
|
|
|
|
1902
|
|
|
send_syslog( |
|
1903
|
|
|
'action='.str_replace('at_', '', $action).' attribute='.str_replace('at_', '', $attribute[0]).' itemno='.$item_id.' user='.addslashes($login).' itemname="'.addslashes($item_label).'"', |
|
1904
|
|
|
$SETTINGS['syslog_host'], |
|
1905
|
|
|
$SETTINGS['syslog_port'], |
|
1906
|
|
|
'teampass' |
|
1907
|
|
|
); |
|
1908
|
|
|
} |
|
1909
|
|
|
|
|
1910
|
|
|
// send notification if enabled |
|
1911
|
|
|
if (isset($SETTINGS['enable_email_notification_on_item_shown']) === true |
|
1912
|
|
|
&& $SETTINGS['enable_email_notification_on_item_shown'] === '1' |
|
1913
|
|
|
&& $action === 'at_shown' |
|
1914
|
|
|
) { |
|
1915
|
|
|
// Get info about item |
|
1916
|
|
|
if (empty($dataItem) === true || empty($item_label) === true) { |
|
1917
|
|
|
$dataItem = DB::queryfirstrow( |
|
1918
|
|
|
'SELECT id, id_tree, label |
|
1919
|
|
|
FROM '.prefixTable('items').' |
|
1920
|
|
|
WHERE id = %i', |
|
1921
|
|
|
$item_id |
|
1922
|
|
|
); |
|
1923
|
|
|
$item_label = $dataItem['label']; |
|
1924
|
|
|
} |
|
1925
|
|
|
|
|
1926
|
|
|
// send back infos |
|
1927
|
|
|
DB::insert( |
|
1928
|
|
|
prefixTable('emails'), |
|
1929
|
|
|
array( |
|
1930
|
|
|
'timestamp' => time(), |
|
1931
|
|
|
'subject' => langHdl('email_on_open_notification_subject'), |
|
1932
|
|
|
'body' => str_replace( |
|
1933
|
|
|
array('#tp_user#', '#tp_item#', '#tp_link#'), |
|
1934
|
|
|
array( |
|
1935
|
|
|
addslashes($_SESSION['login']), |
|
1936
|
|
|
addslashes($item_label), |
|
1937
|
|
|
$SETTINGS['cpassman_url'].'/index.php?page=items&group='.$dataItem['id_tree'].'&id='.$dataItem['id'], |
|
1938
|
|
|
), |
|
1939
|
|
|
langHdl('email_on_open_notification_mail') |
|
1940
|
|
|
), |
|
1941
|
|
|
'receivers' => $_SESSION['listNotificationEmails'], |
|
1942
|
|
|
'status' => '', |
|
1943
|
|
|
) |
|
1944
|
|
|
); |
|
1945
|
|
|
} |
|
1946
|
|
|
} |
|
1947
|
|
|
|
|
1948
|
|
|
/** |
|
1949
|
|
|
* Get the client ip address. |
|
1950
|
|
|
* |
|
1951
|
|
|
* @return string IP address |
|
1952
|
|
|
*/ |
|
1953
|
|
|
function getClientIpServer() |
|
1954
|
|
|
{ |
|
1955
|
|
|
if (getenv('HTTP_CLIENT_IP')) { |
|
1956
|
|
|
$ipaddress = getenv('HTTP_CLIENT_IP'); |
|
1957
|
|
|
} elseif (getenv('HTTP_X_FORWARDED_FOR')) { |
|
1958
|
|
|
$ipaddress = getenv('HTTP_X_FORWARDED_FOR'); |
|
1959
|
|
|
} elseif (getenv('HTTP_X_FORWARDED')) { |
|
1960
|
|
|
$ipaddress = getenv('HTTP_X_FORWARDED'); |
|
1961
|
|
|
} elseif (getenv('HTTP_FORWARDED_FOR')) { |
|
1962
|
|
|
$ipaddress = getenv('HTTP_FORWARDED_FOR'); |
|
1963
|
|
|
} elseif (getenv('HTTP_FORWARDED')) { |
|
1964
|
|
|
$ipaddress = getenv('HTTP_FORWARDED'); |
|
1965
|
|
|
} elseif (getenv('REMOTE_ADDR')) { |
|
1966
|
|
|
$ipaddress = getenv('REMOTE_ADDR'); |
|
1967
|
|
|
} else { |
|
1968
|
|
|
$ipaddress = 'UNKNOWN'; |
|
1969
|
|
|
} |
|
1970
|
|
|
|
|
1971
|
|
|
return $ipaddress; |
|
1972
|
|
|
} |
|
1973
|
|
|
|
|
1974
|
|
|
/** |
|
1975
|
|
|
* Escape all HTML, JavaScript, and CSS. |
|
1976
|
|
|
* |
|
1977
|
|
|
* @param string $input The input string |
|
1978
|
|
|
* @param string $encoding Which character encoding are we using? |
|
1979
|
|
|
* |
|
1980
|
|
|
* @return string |
|
1981
|
|
|
*/ |
|
1982
|
|
|
function noHTML($input, $encoding = 'UTF-8') |
|
1983
|
|
|
{ |
|
1984
|
|
|
return htmlspecialchars($input, ENT_QUOTES | ENT_XHTML, $encoding, false); |
|
1985
|
|
|
} |
|
1986
|
|
|
|
|
1987
|
|
|
/** |
|
1988
|
|
|
* handleConfigFile(). |
|
1989
|
|
|
* |
|
1990
|
|
|
* permits to handle the Teampass config file |
|
1991
|
|
|
* $action accepts "rebuild" and "update" |
|
1992
|
|
|
*/ |
|
1993
|
|
|
function handleConfigFile($action, $field = null, $value = null) |
|
1994
|
|
|
{ |
|
1995
|
|
|
global $server, $user, $pass, $database, $port, $encoding; |
|
1996
|
|
|
global $SETTINGS; |
|
1997
|
|
|
|
|
1998
|
|
|
$tp_config_file = '../includes/config/tp.config.php'; |
|
1999
|
|
|
|
|
2000
|
|
|
// include librairies & connect to DB |
|
2001
|
|
|
include_once $SETTINGS['cpassman_dir'].'/includes/libraries/Database/Meekrodb/db.class.php'; |
|
2002
|
|
|
DB::$host = DB_HOST; |
|
2003
|
|
|
DB::$user = DB_USER; |
|
2004
|
|
|
DB::$password = defuseReturnDecrypted(DB_PASSWD, $SETTINGS); |
|
2005
|
|
|
DB::$dbName = DB_NAME; |
|
2006
|
|
|
DB::$port = DB_PORT; |
|
2007
|
|
|
DB::$encoding = DB_ENCODING; |
|
2008
|
|
|
//DB::$errorHandler = true; |
|
2009
|
|
|
|
|
2010
|
|
|
$link = mysqli_connect(DB_HOST, DB_USER, defuseReturnDecrypted(DB_PASSWD, $SETTINGS), DB_NAME, DB_PORT); |
|
2011
|
|
|
$link->set_charset(DB_ENCODING); |
|
2012
|
|
|
|
|
2013
|
|
|
if (file_exists($tp_config_file) === false || $action === 'rebuild') { |
|
2014
|
|
|
// perform a copy |
|
2015
|
|
|
if (file_exists($tp_config_file)) { |
|
2016
|
|
|
if (!copy($tp_config_file, $tp_config_file.'.'.date('Y_m_d_His', time()))) { |
|
2017
|
|
|
return "ERROR: Could not copy file '".$tp_config_file."'"; |
|
2018
|
|
|
} |
|
2019
|
|
|
} |
|
2020
|
|
|
|
|
2021
|
|
|
// regenerate |
|
2022
|
|
|
$data = array(); |
|
2023
|
|
|
$data[0] = "<?php\n"; |
|
2024
|
|
|
$data[1] = "global \$SETTINGS;\n"; |
|
2025
|
|
|
$data[2] = "\$SETTINGS = array (\n"; |
|
2026
|
|
|
$rows = DB::query( |
|
2027
|
|
|
'SELECT * FROM '.prefixTable('misc').' WHERE type=%s', |
|
2028
|
|
|
'admin' |
|
2029
|
|
|
); |
|
2030
|
|
|
foreach ($rows as $record) { |
|
2031
|
|
|
array_push($data, " '".$record['intitule']."' => '".$record['valeur']."',\n"); |
|
2032
|
|
|
} |
|
2033
|
|
|
array_push($data, ");\n"); |
|
2034
|
|
|
$data = array_unique($data); |
|
2035
|
|
|
} elseif ($action === 'update' && empty($field) === false) { |
|
2036
|
|
|
$data = file($tp_config_file); |
|
2037
|
|
|
$inc = 0; |
|
2038
|
|
|
$bFound = false; |
|
2039
|
|
|
foreach ($data as $line) { |
|
2040
|
|
|
if (stristr($line, ');')) { |
|
2041
|
|
|
break; |
|
2042
|
|
|
} |
|
2043
|
|
|
|
|
2044
|
|
|
if (stristr($line, "'".$field."' => '")) { |
|
2045
|
|
|
$data[$inc] = " '".$field."' => '".filter_var($value, FILTER_SANITIZE_STRING)."',\n"; |
|
2046
|
|
|
$bFound = true; |
|
2047
|
|
|
break; |
|
2048
|
|
|
} |
|
2049
|
|
|
++$inc; |
|
2050
|
|
|
} |
|
2051
|
|
|
if ($bFound === false) { |
|
2052
|
|
|
$data[($inc)] = " '".$field."' => '".filter_var($value, FILTER_SANITIZE_STRING)."',\n);\n"; |
|
2053
|
|
|
} |
|
2054
|
|
|
} |
|
2055
|
|
|
|
|
2056
|
|
|
// update file |
|
2057
|
|
|
file_put_contents($tp_config_file, implode('', isset($data) ? $data : array())); |
|
2058
|
|
|
|
|
2059
|
|
|
return true; |
|
2060
|
|
|
} |
|
2061
|
|
|
|
|
2062
|
|
|
/* |
|
2063
|
|
|
** Permits to replace \ to permit correct display |
|
2064
|
|
|
*/ |
|
2065
|
|
|
/** |
|
2066
|
|
|
* @param string $input |
|
2067
|
|
|
*/ |
|
2068
|
|
|
function handleBackslash($input) |
|
2069
|
|
|
{ |
|
2070
|
|
|
return str_replace('&#92;', '\', $input); |
|
2071
|
|
|
} |
|
2072
|
|
|
|
|
2073
|
|
|
/* |
|
2074
|
|
|
** Permits to loas settings |
|
2075
|
|
|
*/ |
|
2076
|
|
|
function loadSettings() |
|
2077
|
|
|
{ |
|
2078
|
|
|
global $SETTINGS; |
|
2079
|
|
|
|
|
2080
|
|
|
/* LOAD CPASSMAN SETTINGS */ |
|
2081
|
|
|
if (!isset($SETTINGS['loaded']) || $SETTINGS['loaded'] != 1) { |
|
2082
|
|
|
$SETTINGS['duplicate_folder'] = 0; //by default, this is set to 0; |
|
2083
|
|
|
$SETTINGS['duplicate_item'] = 0; //by default, this is set to 0; |
|
2084
|
|
|
$SETTINGS['number_of_used_pw'] = 5; //by default, this value is set to 5; |
|
2085
|
|
|
$settings = array(); |
|
2086
|
|
|
|
|
2087
|
|
|
$rows = DB::query( |
|
2088
|
|
|
'SELECT * FROM '.prefixTable('misc').' WHERE type=%s_type OR type=%s_type2', |
|
2089
|
|
|
array( |
|
2090
|
|
|
'type' => 'admin', |
|
2091
|
|
|
'type2' => 'settings', |
|
2092
|
|
|
) |
|
2093
|
|
|
); |
|
2094
|
|
|
foreach ($rows as $record) { |
|
2095
|
|
|
if ($record['type'] === 'admin') { |
|
2096
|
|
|
$SETTINGS[$record['intitule']] = $record['valeur']; |
|
2097
|
|
|
} else { |
|
2098
|
|
|
$settings[$record['intitule']] = $record['valeur']; |
|
2099
|
|
|
} |
|
2100
|
|
|
} |
|
2101
|
|
|
$SETTINGS['loaded'] = 1; |
|
2102
|
|
|
$SETTINGS['default_session_expiration_time'] = 5; |
|
2103
|
|
|
} |
|
2104
|
|
|
} |
|
2105
|
|
|
|
|
2106
|
|
|
/* |
|
2107
|
|
|
** check if folder has custom fields. |
|
2108
|
|
|
** Ensure that target one also has same custom fields |
|
2109
|
|
|
*/ |
|
2110
|
|
|
function checkCFconsistency($source_id, $target_id) |
|
2111
|
|
|
{ |
|
2112
|
|
|
$source_cf = array(); |
|
2113
|
|
|
$rows = DB::QUERY( |
|
2114
|
|
|
'SELECT id_category |
|
2115
|
|
|
FROM '.prefixTable('categories_folders').' |
|
2116
|
|
|
WHERE id_folder = %i', |
|
2117
|
|
|
$source_id |
|
2118
|
|
|
); |
|
2119
|
|
|
foreach ($rows as $record) { |
|
2120
|
|
|
array_push($source_cf, $record['id_category']); |
|
2121
|
|
|
} |
|
2122
|
|
|
|
|
2123
|
|
|
$target_cf = array(); |
|
2124
|
|
|
$rows = DB::QUERY( |
|
2125
|
|
|
'SELECT id_category |
|
2126
|
|
|
FROM '.prefixTable('categories_folders').' |
|
2127
|
|
|
WHERE id_folder = %i', |
|
2128
|
|
|
$target_id |
|
2129
|
|
|
); |
|
2130
|
|
|
foreach ($rows as $record) { |
|
2131
|
|
|
array_push($target_cf, $record['id_category']); |
|
2132
|
|
|
} |
|
2133
|
|
|
|
|
2134
|
|
|
$cf_diff = array_diff($source_cf, $target_cf); |
|
2135
|
|
|
if (count($cf_diff) > 0) { |
|
2136
|
|
|
return false; |
|
2137
|
|
|
} |
|
2138
|
|
|
|
|
2139
|
|
|
return true; |
|
2140
|
|
|
} |
|
2141
|
|
|
|
|
2142
|
|
|
/** |
|
2143
|
|
|
* Shall we crypt/decrypt. |
|
2144
|
|
|
* |
|
2145
|
|
|
* @param string $filename_to_rework File name |
|
2146
|
|
|
* @param string $filename_status Its status |
|
2147
|
|
|
* @param array $SETTINGS Settings |
|
2148
|
|
|
*/ |
|
2149
|
|
|
function encryptOrDecryptFile( |
|
2150
|
|
|
$filename_to_rework, |
|
2151
|
|
|
$filename_status, |
|
2152
|
|
|
$SETTINGS |
|
2153
|
|
|
) { |
|
2154
|
|
|
// Include librairies & connect to DB |
|
2155
|
|
|
include_once $SETTINGS['cpassman_dir'].'/includes/libraries/Database/Meekrodb/db.class.php'; |
|
2156
|
|
|
DB::$host = DB_HOST; |
|
2157
|
|
|
DB::$user = DB_USER; |
|
2158
|
|
|
DB::$password = defuseReturnDecrypted(DB_PASSWD, $SETTINGS); |
|
2159
|
|
|
DB::$dbName = DB_NAME; |
|
2160
|
|
|
DB::$port = DB_PORT; |
|
2161
|
|
|
DB::$encoding = DB_ENCODING; |
|
2162
|
|
|
$link = mysqli_connect(DB_HOST, DB_USER, defuseReturnDecrypted(DB_PASSWD, $SETTINGS), DB_NAME, DB_PORT); |
|
2163
|
|
|
$link->set_charset(DB_ENCODING); |
|
2164
|
|
|
|
|
2165
|
|
|
// Get file info in DB |
|
2166
|
|
|
$fileInfo = DB::queryfirstrow( |
|
2167
|
|
|
'SELECT id FROM '.prefixTable('files').' WHERE file = %s', |
|
2168
|
|
|
filter_var($filename_to_rework, FILTER_SANITIZE_STRING) |
|
2169
|
|
|
); |
|
2170
|
|
|
if (empty($fileInfo['id']) === false) { |
|
2171
|
|
|
// Load PhpEncryption library |
|
2172
|
|
|
$path_to_encryption = '/includes/libraries/Encryption/Encryption/'; |
|
2173
|
|
|
include_once $SETTINGS['cpassman_dir'].$path_to_encryption.'Crypto.php'; |
|
2174
|
|
|
include_once $SETTINGS['cpassman_dir'].$path_to_encryption.'Encoding.php'; |
|
2175
|
|
|
include_once $SETTINGS['cpassman_dir'].$path_to_encryption.'DerivedKeys.php'; |
|
2176
|
|
|
include_once $SETTINGS['cpassman_dir'].$path_to_encryption.'Key.php'; |
|
2177
|
|
|
include_once $SETTINGS['cpassman_dir'].$path_to_encryption.'KeyOrPassword.php'; |
|
2178
|
|
|
include_once $SETTINGS['cpassman_dir'].$path_to_encryption.'File.php'; |
|
2179
|
|
|
include_once $SETTINGS['cpassman_dir'].$path_to_encryption.'RuntimeTests.php'; |
|
2180
|
|
|
include_once $SETTINGS['cpassman_dir'].$path_to_encryption.'KeyProtectedByPassword.php'; |
|
2181
|
|
|
include_once $SETTINGS['cpassman_dir'].$path_to_encryption.'Core.php'; |
|
2182
|
|
|
|
|
2183
|
|
|
// Get KEY |
|
2184
|
|
|
$ascii_key = file_get_contents(SECUREPATH.'/teampass-seckey.txt'); |
|
2185
|
|
|
|
|
2186
|
|
|
if (isset($SETTINGS['enable_attachment_encryption']) |
|
2187
|
|
|
&& $SETTINGS['enable_attachment_encryption'] === '1' |
|
2188
|
|
|
&& isset($filename_status) === true |
|
2189
|
|
|
&& ($filename_status === 'clear' || $filename_status === '0') |
|
2190
|
|
|
) { |
|
2191
|
|
|
// File needs to be encrypted |
|
2192
|
|
|
if (file_exists($SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework) === true) { |
|
2193
|
|
|
// Make a copy of file |
|
2194
|
|
|
if (copy( |
|
2195
|
|
|
$SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework, |
|
2196
|
|
|
$SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework.'.copy' |
|
2197
|
|
|
) |
|
2198
|
|
|
=== false |
|
2199
|
|
|
) { |
|
2200
|
|
|
return; |
|
2201
|
|
|
} else { |
|
2202
|
|
|
// Do a bck |
|
2203
|
|
|
copy( |
|
2204
|
|
|
$SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework, |
|
2205
|
|
|
$SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework.'.bck' |
|
2206
|
|
|
); |
|
2207
|
|
|
} |
|
2208
|
|
|
|
|
2209
|
|
|
unlink($SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework); |
|
2210
|
|
|
|
|
2211
|
|
|
// Now encrypt the file with saltkey |
|
2212
|
|
|
$err = ''; |
|
2213
|
|
|
try { |
|
2214
|
|
|
\Defuse\Crypto\File::encryptFile( |
|
2215
|
|
|
$SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework.'.copy', |
|
2216
|
|
|
$SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework, |
|
2217
|
|
|
\Defuse\Crypto\Key::loadFromAsciiSafeString($ascii_key) |
|
2218
|
|
|
); |
|
2219
|
|
|
} catch (Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException $ex) { |
|
2220
|
|
|
$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.'; |
|
2221
|
|
|
} catch (Defuse\Crypto\Exception\EnvironmentIsBrokenException $ex) { |
|
2222
|
|
|
$err = $ex; |
|
2223
|
|
|
} catch (Defuse\Crypto\Exception\IOException $ex) { |
|
2224
|
|
|
$err = $ex; |
|
2225
|
|
|
} |
|
2226
|
|
|
if (empty($err) === false) { |
|
2227
|
|
|
echo $err; |
|
2228
|
|
|
} |
|
2229
|
|
|
|
|
2230
|
|
|
unlink($SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework.'.copy'); |
|
2231
|
|
|
|
|
2232
|
|
|
// update table |
|
2233
|
|
|
DB::update( |
|
2234
|
|
|
prefixTable('files'), |
|
2235
|
|
|
array( |
|
2236
|
|
|
'status' => 'encrypted', |
|
2237
|
|
|
), |
|
2238
|
|
|
'id = %i', |
|
2239
|
|
|
$fileInfo['id'] |
|
2240
|
|
|
); |
|
2241
|
|
|
} |
|
2242
|
|
|
} elseif (isset($SETTINGS['enable_attachment_encryption']) |
|
2243
|
|
|
&& $SETTINGS['enable_attachment_encryption'] === '0' |
|
2244
|
|
|
&& isset($filename_status) |
|
2245
|
|
|
&& $filename_status === 'encrypted' |
|
2246
|
|
|
) { |
|
2247
|
|
|
// file needs to be decrypted |
|
2248
|
|
|
if (file_exists($SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework)) { |
|
2249
|
|
|
// make a copy of file |
|
2250
|
|
|
if (!copy( |
|
2251
|
|
|
$SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework, |
|
2252
|
|
|
$SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework.'.copy' |
|
2253
|
|
|
)) { |
|
2254
|
|
|
return; |
|
2255
|
|
|
} else { |
|
2256
|
|
|
// do a bck |
|
2257
|
|
|
copy( |
|
2258
|
|
|
$SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework, |
|
2259
|
|
|
$SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework.'.bck' |
|
2260
|
|
|
); |
|
2261
|
|
|
} |
|
2262
|
|
|
|
|
2263
|
|
|
unlink($SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework); |
|
2264
|
|
|
|
|
2265
|
|
|
// Now encrypt the file with saltkey |
|
2266
|
|
|
$err = ''; |
|
2267
|
|
|
try { |
|
2268
|
|
|
\Defuse\Crypto\File::decryptFile( |
|
2269
|
|
|
$SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework.'.copy', |
|
2270
|
|
|
$SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework, |
|
2271
|
|
|
\Defuse\Crypto\Key::loadFromAsciiSafeString($ascii_key) |
|
2272
|
|
|
); |
|
2273
|
|
|
} catch (Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException $ex) { |
|
2274
|
|
|
$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.'; |
|
2275
|
|
|
} catch (Defuse\Crypto\Exception\EnvironmentIsBrokenException $ex) { |
|
2276
|
|
|
$err = $ex; |
|
2277
|
|
|
} catch (Defuse\Crypto\Exception\IOException $ex) { |
|
2278
|
|
|
$err = $ex; |
|
2279
|
|
|
} |
|
2280
|
|
|
if (empty($err) === false) { |
|
2281
|
|
|
echo $err; |
|
2282
|
|
|
} |
|
2283
|
|
|
|
|
2284
|
|
|
unlink($SETTINGS['path_to_upload_folder'].'/'.$filename_to_rework.'.copy'); |
|
2285
|
|
|
|
|
2286
|
|
|
// update table |
|
2287
|
|
|
DB::update( |
|
2288
|
|
|
prefixTable('files'), |
|
2289
|
|
|
array( |
|
2290
|
|
|
'status' => 'clear', |
|
2291
|
|
|
), |
|
2292
|
|
|
'id = %i', |
|
2293
|
|
|
$fileInfo['id'] |
|
2294
|
|
|
); |
|
2295
|
|
|
} |
|
2296
|
|
|
} |
|
2297
|
|
|
} |
|
2298
|
|
|
|
|
2299
|
|
|
// Exit |
|
2300
|
|
|
return false; |
|
2301
|
|
|
} |
|
2302
|
|
|
|
|
2303
|
|
|
/** |
|
2304
|
|
|
* Will encrypte/decrypt a fil eusing Defuse. |
|
2305
|
|
|
* |
|
2306
|
|
|
* @param string $type can be either encrypt or decrypt |
|
2307
|
|
|
* @param string $source_file path to source file |
|
2308
|
|
|
* @param string $target_file path to target file |
|
2309
|
|
|
* @param array $SETTINGS Settings |
|
2310
|
|
|
* @param string $password A password |
|
2311
|
|
|
* |
|
2312
|
|
|
* @return string|bool |
|
2313
|
|
|
*/ |
|
2314
|
|
|
function prepareFileWithDefuse( |
|
2315
|
|
|
$type, |
|
2316
|
|
|
$source_file, |
|
2317
|
|
|
$target_file, |
|
2318
|
|
|
$SETTINGS, |
|
2319
|
|
|
$password = null |
|
2320
|
|
|
) { |
|
2321
|
|
|
// Load AntiXSS |
|
2322
|
|
|
include_once $SETTINGS['cpassman_dir'].'/includes/libraries/protect/AntiXSS/AntiXSS.php'; |
|
2323
|
|
|
$antiXss = new protect\AntiXSS\AntiXSS(); |
|
2324
|
|
|
|
|
2325
|
|
|
// Protect against bad inputs |
|
2326
|
|
|
if (is_array($source_file) === true || is_array($target_file) === true) { |
|
|
|
|
|
|
2327
|
|
|
return 'error_cannot_be_array'; |
|
2328
|
|
|
} |
|
2329
|
|
|
|
|
2330
|
|
|
// Sanitize |
|
2331
|
|
|
$source_file = $antiXss->xss_clean($source_file); |
|
2332
|
|
|
$target_file = $antiXss->xss_clean($target_file); |
|
2333
|
|
|
|
|
2334
|
|
|
// load PhpEncryption library |
|
2335
|
|
|
$path_to_encryption = '/includes/libraries/Encryption/Encryption/'; |
|
2336
|
|
|
include_once $SETTINGS['cpassman_dir'].$path_to_encryption.'Crypto.php'; |
|
2337
|
|
|
include_once $SETTINGS['cpassman_dir'].$path_to_encryption.'Encoding.php'; |
|
2338
|
|
|
include_once $SETTINGS['cpassman_dir'].$path_to_encryption.'DerivedKeys.php'; |
|
2339
|
|
|
include_once $SETTINGS['cpassman_dir'].$path_to_encryption.'Key.php'; |
|
2340
|
|
|
include_once $SETTINGS['cpassman_dir'].$path_to_encryption.'KeyOrPassword.php'; |
|
2341
|
|
|
include_once $SETTINGS['cpassman_dir'].$path_to_encryption.'File.php'; |
|
2342
|
|
|
include_once $SETTINGS['cpassman_dir'].$path_to_encryption.'RuntimeTests.php'; |
|
2343
|
|
|
include_once $SETTINGS['cpassman_dir'].$path_to_encryption.'KeyProtectedByPassword.php'; |
|
2344
|
|
|
include_once $SETTINGS['cpassman_dir'].$path_to_encryption.'Core.php'; |
|
2345
|
|
|
|
|
2346
|
|
|
if (empty($password) === true || is_null($password) === true) { |
|
2347
|
|
|
/* |
|
2348
|
|
|
File encryption/decryption is done with the SALTKEY |
|
2349
|
|
|
*/ |
|
2350
|
|
|
|
|
2351
|
|
|
// get KEY |
|
2352
|
|
|
$ascii_key = file_get_contents(SECUREPATH.'/teampass-seckey.txt'); |
|
2353
|
|
|
|
|
2354
|
|
|
// Now perform action on the file |
|
2355
|
|
|
$err = ''; |
|
2356
|
|
|
if ($type === 'decrypt') { |
|
2357
|
|
|
try { |
|
2358
|
|
|
\Defuse\Crypto\File::decryptFile( |
|
2359
|
|
|
$source_file, |
|
2360
|
|
|
$target_file, |
|
2361
|
|
|
\Defuse\Crypto\Key::loadFromAsciiSafeString($ascii_key) |
|
2362
|
|
|
); |
|
2363
|
|
|
} catch (Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException $ex) { |
|
2364
|
|
|
$err = 'decryption_not_possible'; |
|
2365
|
|
|
} catch (Defuse\Crypto\Exception\EnvironmentIsBrokenException $ex) { |
|
2366
|
|
|
$err = $ex; |
|
2367
|
|
|
} catch (Defuse\Crypto\Exception\IOException $ex) { |
|
2368
|
|
|
$err = $ex; |
|
2369
|
|
|
} |
|
2370
|
|
|
} elseif ($type === 'encrypt') { |
|
2371
|
|
|
try { |
|
2372
|
|
|
\Defuse\Crypto\File::encryptFile( |
|
2373
|
|
|
$source_file, |
|
2374
|
|
|
$target_file, |
|
2375
|
|
|
\Defuse\Crypto\Key::loadFromAsciiSafeString($ascii_key) |
|
2376
|
|
|
); |
|
2377
|
|
|
} catch (Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException $ex) { |
|
2378
|
|
|
$err = 'encryption_not_possible'; |
|
2379
|
|
|
} catch (Defuse\Crypto\Exception\EnvironmentIsBrokenException $ex) { |
|
2380
|
|
|
$err = $ex; |
|
2381
|
|
|
} catch (Defuse\Crypto\Exception\IOException $ex) { |
|
2382
|
|
|
$err = $ex; |
|
2383
|
|
|
} |
|
2384
|
|
|
} |
|
2385
|
|
|
} else { |
|
2386
|
|
|
/* |
|
2387
|
|
|
File encryption/decryption is done with special password and not the SALTKEY |
|
2388
|
|
|
*/ |
|
2389
|
|
|
|
|
2390
|
|
|
$err = ''; |
|
2391
|
|
|
if ($type === 'decrypt') { |
|
2392
|
|
|
try { |
|
2393
|
|
|
\Defuse\Crypto\File::decryptFileWithPassword( |
|
2394
|
|
|
$source_file, |
|
2395
|
|
|
$target_file, |
|
2396
|
|
|
$password |
|
2397
|
|
|
); |
|
2398
|
|
|
} catch (Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException $ex) { |
|
2399
|
|
|
$err = 'wrong_key'; |
|
2400
|
|
|
} catch (Defuse\Crypto\Exception\EnvironmentIsBrokenException $ex) { |
|
2401
|
|
|
$err = $ex; |
|
2402
|
|
|
} catch (Defuse\Crypto\Exception\IOException $ex) { |
|
2403
|
|
|
$err = $ex; |
|
2404
|
|
|
} |
|
2405
|
|
|
} elseif ($type === 'encrypt') { |
|
2406
|
|
|
try { |
|
2407
|
|
|
\Defuse\Crypto\File::encryptFileWithPassword( |
|
2408
|
|
|
$source_file, |
|
2409
|
|
|
$target_file, |
|
2410
|
|
|
$password |
|
2411
|
|
|
); |
|
2412
|
|
|
} catch (Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException $ex) { |
|
2413
|
|
|
$err = 'wrong_key'; |
|
2414
|
|
|
} catch (Defuse\Crypto\Exception\EnvironmentIsBrokenException $ex) { |
|
2415
|
|
|
$err = $ex; |
|
2416
|
|
|
} catch (Defuse\Crypto\Exception\IOException $ex) { |
|
2417
|
|
|
$err = $ex; |
|
2418
|
|
|
} |
|
2419
|
|
|
} |
|
2420
|
|
|
} |
|
2421
|
|
|
|
|
2422
|
|
|
// return error |
|
2423
|
|
|
if (empty($err) === false) { |
|
2424
|
|
|
return $err; |
|
2425
|
|
|
} else { |
|
2426
|
|
|
return true; |
|
2427
|
|
|
} |
|
2428
|
|
|
} |
|
2429
|
|
|
|
|
2430
|
|
|
/* |
|
2431
|
|
|
* NOT TO BE USED |
|
2432
|
|
|
*/ |
|
2433
|
|
|
/** |
|
2434
|
|
|
* Undocumented function. |
|
2435
|
|
|
* |
|
2436
|
|
|
* @param string $text Text to debug |
|
2437
|
|
|
*/ |
|
2438
|
|
|
function debugTeampass($text) |
|
2439
|
|
|
{ |
|
2440
|
|
|
$debugFile = fopen('D:/wamp64/www/TeamPass/debug.txt', 'r+'); |
|
2441
|
|
|
fputs($debugFile, $text); |
|
|
|
|
|
|
2442
|
|
|
fclose($debugFile); |
|
|
|
|
|
|
2443
|
|
|
} |
|
2444
|
|
|
|
|
2445
|
|
|
/** |
|
2446
|
|
|
* DELETE the file with expected command depending on server type. |
|
2447
|
|
|
* |
|
2448
|
|
|
* @param string $file Path to file |
|
2449
|
|
|
* @param array $SETTINGS Teampass settings |
|
2450
|
|
|
*/ |
|
2451
|
|
|
function fileDelete($file, $SETTINGS) |
|
2452
|
|
|
{ |
|
2453
|
|
|
// Load AntiXSS |
|
2454
|
|
|
include_once $SETTINGS['cpassman_dir'].'/includes/libraries/protect/AntiXSS/AntiXSS.php'; |
|
2455
|
|
|
$antiXss = new protect\AntiXSS\AntiXSS(); |
|
2456
|
|
|
|
|
2457
|
|
|
$file = $antiXss->xss_clean($file); |
|
2458
|
|
|
if (is_file($file)) { |
|
2459
|
|
|
unlink($file); |
|
2460
|
|
|
} |
|
2461
|
|
|
} |
|
2462
|
|
|
|
|
2463
|
|
|
/** |
|
2464
|
|
|
* Permits to extract the file extension. |
|
2465
|
|
|
* |
|
2466
|
|
|
* @param string $file File name |
|
2467
|
|
|
* |
|
2468
|
|
|
* @return string |
|
2469
|
|
|
*/ |
|
2470
|
|
|
function getFileExtension($file) |
|
2471
|
|
|
{ |
|
2472
|
|
|
if (strpos($file, '.') === false) { |
|
2473
|
|
|
return $file; |
|
2474
|
|
|
} |
|
2475
|
|
|
|
|
2476
|
|
|
return substr($file, strrpos($file, '.') + 1); |
|
2477
|
|
|
} |
|
2478
|
|
|
|
|
2479
|
|
|
/** |
|
2480
|
|
|
* Performs chmod operation on subfolders. |
|
2481
|
|
|
* |
|
2482
|
|
|
* @param string $dir Parent folder |
|
2483
|
|
|
* @param int $dirPermissions New permission on folders |
|
2484
|
|
|
* @param int $filePermissions New permission on files |
|
2485
|
|
|
* |
|
2486
|
|
|
* @return bool |
|
2487
|
|
|
*/ |
|
2488
|
|
|
function chmodRecursive($dir, $dirPermissions, $filePermissions) |
|
2489
|
|
|
{ |
|
2490
|
|
|
$pointer_dir = opendir($dir); |
|
2491
|
|
|
$res = true; |
|
2492
|
|
|
while (false !== ($file = readdir($pointer_dir))) { |
|
|
|
|
|
|
2493
|
|
|
if (($file === '.') || ($file === '..')) { |
|
2494
|
|
|
continue; |
|
2495
|
|
|
} |
|
2496
|
|
|
|
|
2497
|
|
|
$fullPath = $dir.'/'.$file; |
|
2498
|
|
|
|
|
2499
|
|
|
if (is_dir($fullPath)) { |
|
2500
|
|
|
if ($res = @chmod($fullPath, $dirPermissions)) { |
|
2501
|
|
|
$res = @chmodRecursive($fullPath, $dirPermissions, $filePermissions); |
|
2502
|
|
|
} |
|
2503
|
|
|
} else { |
|
2504
|
|
|
$res = chmod($fullPath, $filePermissions); |
|
2505
|
|
|
} |
|
2506
|
|
|
if (!$res) { |
|
2507
|
|
|
closedir($pointer_dir); |
|
|
|
|
|
|
2508
|
|
|
|
|
2509
|
|
|
return false; |
|
2510
|
|
|
} |
|
2511
|
|
|
} |
|
2512
|
|
|
closedir($pointer_dir); |
|
2513
|
|
|
if (is_dir($dir) && $res) { |
|
2514
|
|
|
$res = @chmod($dir, $dirPermissions); |
|
2515
|
|
|
} |
|
2516
|
|
|
|
|
2517
|
|
|
return $res; |
|
2518
|
|
|
} |
|
2519
|
|
|
|
|
2520
|
|
|
/** |
|
2521
|
|
|
* Check if user can access to this item. |
|
2522
|
|
|
* |
|
2523
|
|
|
* @param int $item_id ID of item |
|
2524
|
|
|
*/ |
|
2525
|
|
|
function accessToItemIsGranted($item_id) |
|
2526
|
|
|
{ |
|
2527
|
|
|
global $SETTINGS; |
|
2528
|
|
|
|
|
2529
|
|
|
include_once $SETTINGS['cpassman_dir'].'/includes/libraries/protect/SuperGlobal/SuperGlobal.php'; |
|
2530
|
|
|
$superGlobal = new protect\SuperGlobal\SuperGlobal(); |
|
2531
|
|
|
|
|
2532
|
|
|
// Prepare superGlobal variables |
|
2533
|
|
|
$session_groupes_visibles = $superGlobal->get('groupes_visibles', 'SESSION'); |
|
2534
|
|
|
$session_list_restricted_folders_for_items = $superGlobal->get('list_restricted_folders_for_items', 'SESSION'); |
|
2535
|
|
|
|
|
2536
|
|
|
// Load item data |
|
2537
|
|
|
$data = DB::queryFirstRow( |
|
2538
|
|
|
'SELECT id_tree |
|
2539
|
|
|
FROM '.prefixTable('items').' |
|
2540
|
|
|
WHERE id = %i', |
|
2541
|
|
|
$item_id |
|
2542
|
|
|
); |
|
2543
|
|
|
|
|
2544
|
|
|
// Check if user can access this folder |
|
2545
|
|
|
if (in_array($data['id_tree'], $session_groupes_visibles) === false) { |
|
2546
|
|
|
// Now check if this folder is restricted to user |
|
2547
|
|
|
if (isset($session_list_restricted_folders_for_items[$data['id_tree']]) |
|
2548
|
|
|
&& !in_array($item_id, $session_list_restricted_folders_for_items[$data['id_tree']]) |
|
2549
|
|
|
) { |
|
2550
|
|
|
return 'ERR_FOLDER_NOT_ALLOWED'; |
|
2551
|
|
|
} else { |
|
2552
|
|
|
return 'ERR_FOLDER_NOT_ALLOWED'; |
|
2553
|
|
|
} |
|
2554
|
|
|
} |
|
2555
|
|
|
|
|
2556
|
|
|
return true; |
|
2557
|
|
|
} |
|
2558
|
|
|
|
|
2559
|
|
|
/** |
|
2560
|
|
|
* Creates a unique key. |
|
2561
|
|
|
* |
|
2562
|
|
|
* @param float $lenght Key lenght |
|
2563
|
|
|
* |
|
2564
|
|
|
* @return string |
|
2565
|
|
|
*/ |
|
2566
|
|
|
function uniqidReal($lenght = 13) |
|
2567
|
|
|
{ |
|
2568
|
|
|
// uniqid gives 13 chars, but you could adjust it to your needs. |
|
2569
|
|
|
if (function_exists('random_bytes')) { |
|
2570
|
|
|
$bytes = random_bytes(ceil($lenght / 2)); |
|
|
|
|
|
|
2571
|
|
|
} elseif (function_exists('openssl_random_pseudo_bytes')) { |
|
2572
|
|
|
$bytes = openssl_random_pseudo_bytes(ceil($lenght / 2)); |
|
|
|
|
|
|
2573
|
|
|
} else { |
|
2574
|
|
|
throw new Exception('no cryptographically secure random function available'); |
|
2575
|
|
|
} |
|
2576
|
|
|
|
|
2577
|
|
|
return substr(bin2hex($bytes), 0, $lenght); |
|
|
|
|
|
|
2578
|
|
|
} |
|
2579
|
|
|
|
|
2580
|
|
|
/** |
|
2581
|
|
|
* Obfuscate an email. |
|
2582
|
|
|
* |
|
2583
|
|
|
* @param string $email Email address |
|
2584
|
|
|
* |
|
2585
|
|
|
* @return string |
|
2586
|
|
|
*/ |
|
2587
|
|
|
function obfuscateEmail($email) |
|
2588
|
|
|
{ |
|
2589
|
|
|
$prop = 2; |
|
2590
|
|
|
$start = ''; |
|
2591
|
|
|
$end = ''; |
|
2592
|
|
|
$domain = substr(strrchr($email, '@'), 1); |
|
2593
|
|
|
$mailname = str_replace($domain, '', $email); |
|
2594
|
|
|
$name_l = strlen($mailname); |
|
2595
|
|
|
$domain_l = strlen($domain); |
|
2596
|
|
|
for ($i = 0; $i <= $name_l / $prop - 1; ++$i) { |
|
2597
|
|
|
$start .= 'x'; |
|
2598
|
|
|
} |
|
2599
|
|
|
|
|
2600
|
|
|
for ($i = 0; $i <= $domain_l / $prop - 1; ++$i) { |
|
2601
|
|
|
$end .= 'x'; |
|
2602
|
|
|
} |
|
2603
|
|
|
|
|
2604
|
|
|
return substr_replace($mailname, $start, 2, $name_l / $prop) |
|
2605
|
|
|
.substr_replace($domain, $end, 2, $domain_l / $prop); |
|
2606
|
|
|
} |
|
2607
|
|
|
|
|
2608
|
|
|
/** |
|
2609
|
|
|
* Permits to get LDAP information about a user. |
|
2610
|
|
|
* |
|
2611
|
|
|
* @param string $username User name |
|
2612
|
|
|
* @param string $password User password |
|
2613
|
|
|
* @param array $SETTINGS Settings |
|
2614
|
|
|
* |
|
2615
|
|
|
* @return string |
|
2616
|
|
|
*/ |
|
2617
|
|
|
function connectLDAP($username, $password, $SETTINGS) |
|
2618
|
|
|
{ |
|
2619
|
|
|
$ldapInfo = ''; |
|
2620
|
|
|
|
|
2621
|
|
|
// Prepare LDAP connection if set up |
|
2622
|
|
|
|
|
2623
|
|
|
if ($SETTINGS['ldap_type'] === 'posix-search') { |
|
2624
|
|
|
$ldapInfo = ldapPosixSearch( |
|
2625
|
|
|
$username, |
|
2626
|
|
|
$password, |
|
2627
|
|
|
$SETTINGS |
|
2628
|
|
|
); |
|
2629
|
|
|
} else { |
|
2630
|
|
|
$ldapInfo = ldapPosixAndWindows( |
|
2631
|
|
|
$username, |
|
2632
|
|
|
$password, |
|
2633
|
|
|
$SETTINGS |
|
2634
|
|
|
); |
|
2635
|
|
|
} |
|
2636
|
|
|
|
|
2637
|
|
|
return json_encode($ldapInfo); |
|
2638
|
|
|
} |
|
2639
|
|
|
|
|
2640
|
|
|
/** |
|
2641
|
|
|
* Undocumented function. |
|
2642
|
|
|
* |
|
2643
|
|
|
* @param string $username Username |
|
2644
|
|
|
* @param string $password Password |
|
2645
|
|
|
* @param array $SETTINGS Settings |
|
2646
|
|
|
* |
|
2647
|
|
|
* @return array |
|
2648
|
|
|
*/ |
|
2649
|
|
|
function ldapPosixSearch($username, $password, $SETTINGS) |
|
2650
|
|
|
{ |
|
2651
|
|
|
$ldapURIs = ''; |
|
2652
|
|
|
$user_email = ''; |
|
2653
|
|
|
$user_found = false; |
|
2654
|
|
|
$user_lastname = ''; |
|
2655
|
|
|
$user_name = ''; |
|
2656
|
|
|
$ldapConnection = false; |
|
2657
|
|
|
|
|
2658
|
|
|
foreach (explode(',', $SETTINGS['ldap_domain_controler']) as $domainControler) { |
|
2659
|
|
|
if ($SETTINGS['ldap_ssl'] == 1) { |
|
2660
|
|
|
$ldapURIs .= 'ldaps://'.$domainControler.':'.$SETTINGS['ldap_port'].' '; |
|
2661
|
|
|
} else { |
|
2662
|
|
|
$ldapURIs .= 'ldap://'.$domainControler.':'.$SETTINGS['ldap_port'].' '; |
|
2663
|
|
|
} |
|
2664
|
|
|
} |
|
2665
|
|
|
$ldapconn = ldap_connect($ldapURIs); |
|
2666
|
|
|
|
|
2667
|
|
|
if ($SETTINGS['ldap_tls']) { |
|
2668
|
|
|
ldap_start_tls($ldapconn); |
|
2669
|
|
|
} |
|
2670
|
|
|
ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3); |
|
2671
|
|
|
ldap_set_option($ldapconn, LDAP_OPT_REFERRALS, 0); |
|
2672
|
|
|
|
|
2673
|
|
|
// Is LDAP connection ready? |
|
2674
|
|
|
if ($ldapconn !== false) { |
|
2675
|
|
|
// Should we bind the connection? |
|
2676
|
|
|
if (empty($SETTINGS['ldap_bind_dn']) === false |
|
2677
|
|
|
&& empty($SETTINGS['ldap_bind_passwd']) === false |
|
2678
|
|
|
) { |
|
2679
|
|
|
$ldapbind = ldap_bind($ldapconn, $SETTINGS['ldap_bind_dn'], $SETTINGS['ldap_bind_passwd']); |
|
2680
|
|
|
} else { |
|
2681
|
|
|
$ldapbind = false; |
|
2682
|
|
|
} |
|
2683
|
|
|
if ((empty($SETTINGS['ldap_bind_dn']) === true && empty($SETTINGS['ldap_bind_passwd']) === true) |
|
2684
|
|
|
|| $ldapbind === true |
|
2685
|
|
|
) { |
|
2686
|
|
|
$filter = '(&('.$SETTINGS['ldap_user_attribute'].'='.$username.')(objectClass='.$SETTINGS['ldap_object_class'].'))'; |
|
2687
|
|
|
$result = ldap_search( |
|
2688
|
|
|
$ldapconn, |
|
2689
|
|
|
$SETTINGS['ldap_search_base'], |
|
2690
|
|
|
$filter, |
|
2691
|
|
|
array('dn', 'mail', 'givenname', 'sn', 'samaccountname') |
|
2692
|
|
|
); |
|
2693
|
|
|
|
|
2694
|
|
|
// Check if user was found in AD |
|
2695
|
|
|
if (ldap_count_entries($ldapconn, $result) > 0) { |
|
2696
|
|
|
// Get user's info and especially the DN |
|
2697
|
|
|
$result = ldap_get_entries($ldapconn, $result); |
|
2698
|
|
|
$user_dn = $result[0]['dn']; |
|
2699
|
|
|
$user_email = $result[0]['mail'][0]; |
|
2700
|
|
|
$user_lastname = $result[0]['sn'][0]; |
|
2701
|
|
|
$user_name = isset($result[0]['givenname'][0]) === true ? $result[0]['givenname'][0] : ''; |
|
2702
|
|
|
$user_found = true; |
|
2703
|
|
|
|
|
2704
|
|
|
// Should we restrain the search in specified user groups |
|
2705
|
|
|
$GroupRestrictionEnabled = false; |
|
2706
|
|
|
if (isset($SETTINGS['ldap_usergroup']) === true |
|
2707
|
|
|
&& empty($SETTINGS['ldap_usergroup']) === false |
|
2708
|
|
|
) { |
|
2709
|
|
|
// New way to check User's group membership |
|
2710
|
|
|
$filter_group = 'memberUid='.$username; |
|
2711
|
|
|
$result_group = ldap_search( |
|
2712
|
|
|
$ldapconn, |
|
2713
|
|
|
$SETTINGS['ldap_search_base'], |
|
2714
|
|
|
$filter_group, |
|
2715
|
|
|
array('dn', 'samaccountname') |
|
2716
|
|
|
); |
|
2717
|
|
|
|
|
2718
|
|
|
if ($result_group) { |
|
|
|
|
|
|
2719
|
|
|
$entries = ldap_get_entries($ldapconn, $result_group); |
|
2720
|
|
|
|
|
2721
|
|
|
if ($entries['count'] > 0) { |
|
2722
|
|
|
// Now check if group fits |
|
2723
|
|
|
for ($i = 0; $i < $entries['count']; ++$i) { |
|
2724
|
|
|
$parsr = ldap_explode_dn($entries[$i]['dn'], 0); |
|
2725
|
|
|
if (str_replace(array('CN=', 'cn='), '', $parsr[0]) === $SETTINGS['ldap_usergroup']) { |
|
2726
|
|
|
$GroupRestrictionEnabled = true; |
|
2727
|
|
|
break; |
|
2728
|
|
|
} |
|
2729
|
|
|
} |
|
2730
|
|
|
} |
|
2731
|
|
|
} |
|
2732
|
|
|
} |
|
2733
|
|
|
|
|
2734
|
|
|
// Is user in the LDAP? |
|
2735
|
|
|
if ($GroupRestrictionEnabled === true |
|
2736
|
|
|
|| ($GroupRestrictionEnabled === false |
|
2737
|
|
|
&& (isset($SETTINGS['ldap_usergroup']) === false |
|
2738
|
|
|
|| (isset($SETTINGS['ldap_usergroup']) === true |
|
2739
|
|
|
&& empty($SETTINGS['ldap_usergroup']) === true))) |
|
2740
|
|
|
) { |
|
2741
|
|
|
// Try to auth inside LDAP |
|
2742
|
|
|
$ldapbind = ldap_bind($ldapconn, $user_dn, $password); |
|
2743
|
|
|
if ($ldapbind === true) { |
|
2744
|
|
|
$ldapConnection = true; |
|
2745
|
|
|
} else { |
|
2746
|
|
|
$ldapConnection = false; |
|
2747
|
|
|
} |
|
2748
|
|
|
} |
|
2749
|
|
|
} else { |
|
2750
|
|
|
$ldapConnection = false; |
|
2751
|
|
|
} |
|
2752
|
|
|
} else { |
|
2753
|
|
|
$ldapConnection = false; |
|
2754
|
|
|
} |
|
2755
|
|
|
} else { |
|
2756
|
|
|
$ldapConnection = false; |
|
2757
|
|
|
} |
|
2758
|
|
|
|
|
2759
|
|
|
return array( |
|
2760
|
|
|
'lastname' => $user_lastname, |
|
2761
|
|
|
'name' => $user_name, |
|
2762
|
|
|
'email' => $user_email, |
|
2763
|
|
|
'auth_success' => $ldapConnection, |
|
2764
|
|
|
'user_found' => $user_found, |
|
2765
|
|
|
); |
|
2766
|
|
|
} |
|
2767
|
|
|
|
|
2768
|
|
|
/** |
|
2769
|
|
|
* Undocumented function. |
|
2770
|
|
|
* |
|
2771
|
|
|
* @param string $username Username |
|
2772
|
|
|
* @param string $password Password |
|
2773
|
|
|
* @param array $SETTINGS Settings |
|
2774
|
|
|
* |
|
2775
|
|
|
* @return array |
|
2776
|
|
|
*/ |
|
2777
|
|
|
function ldapPosixAndWindows($username, $password, $SETTINGS) |
|
2778
|
|
|
{ |
|
2779
|
|
|
$user_email = ''; |
|
2780
|
|
|
$user_found = false; |
|
2781
|
|
|
$user_lastname = ''; |
|
2782
|
|
|
$user_name = ''; |
|
2783
|
|
|
$ldapConnection = false; |
|
2784
|
|
|
$ldap_suffix = ''; |
|
2785
|
|
|
|
|
2786
|
|
|
//Multiple Domain Names |
|
2787
|
|
|
if (strpos(html_entity_decode($username), '\\') === true) { |
|
2788
|
|
|
$ldap_suffix = '@'.substr(html_entity_decode($username), 0, strpos(html_entity_decode($username), '\\')); |
|
|
|
|
|
|
2789
|
|
|
$username = substr(html_entity_decode($username), strpos(html_entity_decode($username), '\\') + 1); |
|
2790
|
|
|
} |
|
2791
|
|
|
//load ClassLoader |
|
2792
|
|
|
include_once $SETTINGS['cpassman_dir'].'/sources/SplClassLoader.php'; |
|
2793
|
|
|
|
|
2794
|
|
|
$adldap = new SplClassLoader('adLDAP', '../includes/libraries/LDAP'); |
|
2795
|
|
|
$adldap->register(); |
|
2796
|
|
|
|
|
2797
|
|
|
// Posix style LDAP handles user searches a bit differently |
|
2798
|
|
|
if ($SETTINGS['ldap_type'] === 'posix') { |
|
2799
|
|
|
$ldap_suffix = ','.$SETTINGS['ldap_suffix'].','.$SETTINGS['ldap_domain_dn']; |
|
2800
|
|
|
} else { |
|
2801
|
|
|
// case where $SETTINGS['ldap_type'] equals 'windows' |
|
2802
|
|
|
//Multiple Domain Names |
|
2803
|
|
|
$ldap_suffix = $SETTINGS['ldap_suffix']; |
|
2804
|
|
|
} |
|
2805
|
|
|
|
|
2806
|
|
|
// Ensure no double commas exist in ldap_suffix |
|
2807
|
|
|
$ldap_suffix = str_replace(',,', ',', $ldap_suffix); |
|
2808
|
|
|
|
|
2809
|
|
|
// Create LDAP connection |
|
2810
|
|
|
$adldap = new adLDAP\adLDAP( |
|
2811
|
|
|
array( |
|
2812
|
|
|
'base_dn' => $SETTINGS['ldap_domain_dn'], |
|
2813
|
|
|
'account_suffix' => $ldap_suffix, |
|
2814
|
|
|
'domain_controllers' => explode(',', $SETTINGS['ldap_domain_controler']), |
|
2815
|
|
|
'ad_port' => $SETTINGS['ldap_port'], |
|
2816
|
|
|
'use_ssl' => $SETTINGS['ldap_ssl'], |
|
2817
|
|
|
'use_tls' => $SETTINGS['ldap_tls'], |
|
2818
|
|
|
) |
|
2819
|
|
|
); |
|
2820
|
|
|
|
|
2821
|
|
|
// OpenLDAP expects an attribute=value pair |
|
2822
|
|
|
if ($SETTINGS['ldap_type'] === 'posix') { |
|
2823
|
|
|
$auth_username = $SETTINGS['ldap_user_attribute'].'='.$username; |
|
2824
|
|
|
} else { |
|
2825
|
|
|
$auth_username = $username; |
|
2826
|
|
|
} |
|
2827
|
|
|
|
|
2828
|
|
|
// Authenticate the user |
|
2829
|
|
|
if ($adldap->authenticate($auth_username, html_entity_decode($password))) { |
|
2830
|
|
|
// Get user info |
|
2831
|
|
|
$result = $adldap->user()->info($auth_username, array('mail', 'givenname', 'sn')); |
|
2832
|
|
|
$user_email = $result[0]['mail'][0]; |
|
2833
|
|
|
$user_lastname = $result[0]['sn'][0]; |
|
2834
|
|
|
$user_name = $result[0]['givenname'][0]; |
|
2835
|
|
|
$user_found = true; |
|
2836
|
|
|
|
|
2837
|
|
|
// Is user in allowed group |
|
2838
|
|
|
if (isset($SETTINGS['ldap_allowed_usergroup']) === true |
|
2839
|
|
|
&& empty($SETTINGS['ldap_allowed_usergroup']) === false |
|
2840
|
|
|
) { |
|
2841
|
|
|
if ($adldap->user()->inGroup($auth_username, $SETTINGS['ldap_allowed_usergroup']) === true) { |
|
2842
|
|
|
$ldapConnection = true; |
|
2843
|
|
|
} else { |
|
2844
|
|
|
$ldapConnection = false; |
|
2845
|
|
|
} |
|
2846
|
|
|
} else { |
|
2847
|
|
|
$ldapConnection = true; |
|
2848
|
|
|
} |
|
2849
|
|
|
} else { |
|
2850
|
|
|
$ldapConnection = false; |
|
2851
|
|
|
} |
|
2852
|
|
|
|
|
2853
|
|
|
return array( |
|
2854
|
|
|
'lastname' => $user_lastname, |
|
2855
|
|
|
'name' => $user_name, |
|
2856
|
|
|
'email' => $user_email, |
|
2857
|
|
|
'auth_success' => $ldapConnection, |
|
2858
|
|
|
'user_found' => $user_found, |
|
2859
|
|
|
); |
|
2860
|
|
|
} |
|
2861
|
|
|
|
|
2862
|
|
|
//-------------------------------- |
|
2863
|
|
|
|
|
2864
|
|
|
/** |
|
2865
|
|
|
* Perform a Query. |
|
2866
|
|
|
* |
|
2867
|
|
|
* @param array $SETTINGS Teamapss settings |
|
2868
|
|
|
* @param string $fields Fields to use |
|
2869
|
|
|
* @param string $table Table to use |
|
2870
|
|
|
* |
|
2871
|
|
|
* @return array |
|
2872
|
|
|
*/ |
|
2873
|
|
|
function performDBQuery($SETTINGS, $fields, $table) |
|
2874
|
|
|
{ |
|
2875
|
|
|
// include librairies & connect to DB |
|
2876
|
|
|
include_once $SETTINGS['cpassman_dir'].'/includes/config/settings.php'; |
|
2877
|
|
|
include_once $SETTINGS['cpassman_dir'].'/includes/libraries/Database/Meekrodb/db.class.php'; |
|
2878
|
|
|
$link = mysqli_connect(DB_HOST, DB_USER, defuseReturnDecrypted(DB_PASSWD, $SETTINGS), DB_NAME, DB_PORT); |
|
2879
|
|
|
$link->set_charset(DB_ENCODING); |
|
2880
|
|
|
|
|
2881
|
|
|
// Insert log in DB |
|
2882
|
|
|
return DB::query( |
|
2883
|
|
|
'SELECT '.$fields.' |
|
2884
|
|
|
FROM '.prefixTable($table) |
|
2885
|
|
|
); |
|
2886
|
|
|
} |
|
2887
|
|
|
|
|
2888
|
|
|
/** |
|
2889
|
|
|
* Undocumented function. |
|
2890
|
|
|
* |
|
2891
|
|
|
* @param int $bytes Size of file |
|
2892
|
|
|
* |
|
2893
|
|
|
* @return string |
|
2894
|
|
|
*/ |
|
2895
|
|
|
function formatSizeUnits($bytes) |
|
2896
|
|
|
{ |
|
2897
|
|
|
if ($bytes >= 1073741824) { |
|
2898
|
|
|
$bytes = number_format($bytes / 1073741824, 2).' GB'; |
|
2899
|
|
|
} elseif ($bytes >= 1048576) { |
|
2900
|
|
|
$bytes = number_format($bytes / 1048576, 2).' MB'; |
|
2901
|
|
|
} elseif ($bytes >= 1024) { |
|
2902
|
|
|
$bytes = number_format($bytes / 1024, 2).' KB'; |
|
2903
|
|
|
} elseif ($bytes > 1) { |
|
2904
|
|
|
$bytes = $bytes.' bytes'; |
|
2905
|
|
|
} elseif ($bytes == 1) { |
|
2906
|
|
|
$bytes = $bytes.' byte'; |
|
2907
|
|
|
} else { |
|
2908
|
|
|
$bytes = '0 bytes'; |
|
2909
|
|
|
} |
|
2910
|
|
|
|
|
2911
|
|
|
return $bytes; |
|
2912
|
|
|
} |
|
2913
|
|
|
|
|
2914
|
|
|
/** |
|
2915
|
|
|
* Generate user pair of keys. |
|
2916
|
|
|
* |
|
2917
|
|
|
* @param string $userPwd User password |
|
2918
|
|
|
* |
|
2919
|
|
|
* @return array |
|
2920
|
|
|
*/ |
|
2921
|
|
|
function generateUserKeys($userPwd) |
|
2922
|
|
|
{ |
|
2923
|
|
|
// include library |
|
2924
|
|
|
include_once '../includes/libraries/Encryption/phpseclib/Math/BigInteger.php'; |
|
2925
|
|
|
include_once '../includes/libraries/Encryption/phpseclib/Crypt/RSA.php'; |
|
2926
|
|
|
include_once '../includes/libraries/Encryption/phpseclib/Crypt/AES.php'; |
|
2927
|
|
|
|
|
2928
|
|
|
// Load classes |
|
2929
|
|
|
$rsa = new Crypt_RSA(); |
|
2930
|
|
|
$cipher = new Crypt_AES(); |
|
2931
|
|
|
|
|
2932
|
|
|
// Create the private and public key |
|
2933
|
|
|
$res = $rsa->createKey(4096); |
|
2934
|
|
|
|
|
2935
|
|
|
// Encrypt the privatekey |
|
2936
|
|
|
$cipher->setPassword($userPwd); |
|
2937
|
|
|
$privatekey = $cipher->encrypt($res['privatekey']); |
|
2938
|
|
|
|
|
2939
|
|
|
return array( |
|
2940
|
|
|
'private_key' => base64_encode($privatekey), |
|
2941
|
|
|
'public_key' => base64_encode($res['publickey']), |
|
2942
|
|
|
'private_key_clear' => base64_encode($res['privatekey']), |
|
2943
|
|
|
); |
|
2944
|
|
|
} |
|
2945
|
|
|
|
|
2946
|
|
|
/** |
|
2947
|
|
|
* Permits to decrypt the user's privatekey. |
|
2948
|
|
|
* |
|
2949
|
|
|
* @param string $userPwd User password |
|
2950
|
|
|
* @param string $userPrivateKey User private key |
|
2951
|
|
|
* |
|
2952
|
|
|
* @return string |
|
2953
|
|
|
*/ |
|
2954
|
|
|
function decryptPrivateKey($userPwd, $userPrivateKey) |
|
2955
|
|
|
{ |
|
2956
|
|
|
if (empty($userPwd) === false) { |
|
2957
|
|
|
include_once '../includes/libraries/Encryption/phpseclib/Crypt/AES.php'; |
|
2958
|
|
|
|
|
2959
|
|
|
// Load classes |
|
2960
|
|
|
$cipher = new Crypt_AES(); |
|
2961
|
|
|
|
|
2962
|
|
|
// Encrypt the privatekey |
|
2963
|
|
|
$cipher->setPassword($userPwd); |
|
2964
|
|
|
|
|
2965
|
|
|
return base64_encode($cipher->decrypt(base64_decode($userPrivateKey))); |
|
2966
|
|
|
} |
|
2967
|
|
|
} |
|
2968
|
|
|
|
|
2969
|
|
|
/** |
|
2970
|
|
|
* Permits to encrypt the user's privatekey. |
|
2971
|
|
|
* |
|
2972
|
|
|
* @param string $userPwd User password |
|
2973
|
|
|
* @param string $userPrivateKey User private key |
|
2974
|
|
|
* |
|
2975
|
|
|
* @return string |
|
2976
|
|
|
*/ |
|
2977
|
|
|
function encryptPrivateKey($userPwd, $userPrivateKey) |
|
2978
|
|
|
{ |
|
2979
|
|
|
if (empty($userPwd) === false) { |
|
2980
|
|
|
include_once '../includes/libraries/Encryption/phpseclib/Crypt/AES.php'; |
|
2981
|
|
|
|
|
2982
|
|
|
// Load classes |
|
2983
|
|
|
$cipher = new Crypt_AES(); |
|
2984
|
|
|
|
|
2985
|
|
|
// Encrypt the privatekey |
|
2986
|
|
|
$cipher->setPassword($userPwd); |
|
2987
|
|
|
|
|
2988
|
|
|
return base64_encode($cipher->encrypt(base64_decode($userPrivateKey))); |
|
2989
|
|
|
} |
|
2990
|
|
|
} |
|
2991
|
|
|
|
|
2992
|
|
|
/** |
|
2993
|
|
|
* Performs an AES encryption of the. |
|
2994
|
|
|
* |
|
2995
|
|
|
* @param string $userPwd User password |
|
2996
|
|
|
* @param string $userPrivateKey User private key |
|
2997
|
|
|
* |
|
2998
|
|
|
* @return string |
|
2999
|
|
|
*/ |
|
3000
|
|
|
/*function encryptData($userPwd, $userPrivateKey) |
|
3001
|
|
|
{ |
|
3002
|
|
|
if (empty($userPwd) === false) { |
|
3003
|
|
|
include_once '../includes/libraries/Encryption/phpseclib/Crypt/AES.php'; |
|
3004
|
|
|
|
|
3005
|
|
|
// Load classes |
|
3006
|
|
|
$cipher = new Crypt_AES(); |
|
3007
|
|
|
|
|
3008
|
|
|
// Encrypt the privatekey |
|
3009
|
|
|
$cipher->setPassword($userPwd); |
|
3010
|
|
|
|
|
3011
|
|
|
return $cipher->decrypt(base64_decode($userPrivateKey)); |
|
3012
|
|
|
} |
|
3013
|
|
|
} |
|
3014
|
|
|
*/ |
|
3015
|
|
|
|
|
3016
|
|
|
/** |
|
3017
|
|
|
* Generate a key. |
|
3018
|
|
|
* |
|
3019
|
|
|
* @param int $length Length of the key to generate |
|
3020
|
|
|
* |
|
3021
|
|
|
* @return string |
|
3022
|
|
|
*/ |
|
3023
|
|
|
/* |
|
3024
|
|
|
function randomStr($length) |
|
3025
|
|
|
{ |
|
3026
|
|
|
$keyspace = str_shuffle('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'); |
|
3027
|
|
|
$pieces = []; |
|
3028
|
|
|
$max = mb_strlen($keyspace, '8bit') - 1; |
|
3029
|
|
|
for ($i = 0; $i < $length; ++$i) { |
|
3030
|
|
|
$pieces[] = $keyspace[random_int(0, $max)]; |
|
3031
|
|
|
} |
|
3032
|
|
|
|
|
3033
|
|
|
return implode('', $pieces); |
|
3034
|
|
|
} |
|
3035
|
|
|
*/ |
|
3036
|
|
|
|
|
3037
|
|
|
/** |
|
3038
|
|
|
* Encrypts a string using AES. |
|
3039
|
|
|
* |
|
3040
|
|
|
* @param string $data String to encrypt |
|
3041
|
|
|
* |
|
3042
|
|
|
* @return array |
|
3043
|
|
|
*/ |
|
3044
|
|
|
function doDataEncryption($data) |
|
3045
|
|
|
{ |
|
3046
|
|
|
// Includes |
|
3047
|
|
|
include_once '../includes/libraries/Encryption/phpseclib/Crypt/AES.php'; |
|
3048
|
|
|
|
|
3049
|
|
|
// Load classes |
|
3050
|
|
|
$cipher = new Crypt_AES(CRYPT_AES_MODE_CBC); |
|
3051
|
|
|
|
|
3052
|
|
|
// Generate an object key |
|
3053
|
|
|
$objectKey = uniqidReal(32); |
|
3054
|
|
|
|
|
3055
|
|
|
// Set it as password |
|
3056
|
|
|
$cipher->setPassword($objectKey); |
|
3057
|
|
|
|
|
3058
|
|
|
return array( |
|
3059
|
|
|
'encrypted' => base64_encode($cipher->encrypt($data)), |
|
3060
|
|
|
'objectKey' => base64_encode($objectKey), |
|
3061
|
|
|
); |
|
3062
|
|
|
} |
|
3063
|
|
|
|
|
3064
|
|
|
/** |
|
3065
|
|
|
* Decrypts a string using AES. |
|
3066
|
|
|
* |
|
3067
|
|
|
* @param string $data Encrypted data |
|
3068
|
|
|
* @param string $key Key to uncrypt |
|
3069
|
|
|
* |
|
3070
|
|
|
* @return string |
|
3071
|
|
|
*/ |
|
3072
|
|
|
function doDataDecryption($data, $key) |
|
3073
|
|
|
{ |
|
3074
|
|
|
// Includes |
|
3075
|
|
|
include_once '../includes/libraries/Encryption/phpseclib/Crypt/AES.php'; |
|
3076
|
|
|
|
|
3077
|
|
|
// Load classes |
|
3078
|
|
|
$cipher = new Crypt_AES(); |
|
3079
|
|
|
|
|
3080
|
|
|
// Set the object key |
|
3081
|
|
|
$cipher->setPassword(base64_decode($key)); |
|
3082
|
|
|
|
|
3083
|
|
|
return base64_encode($cipher->decrypt(base64_decode($data))); |
|
3084
|
|
|
} |
|
3085
|
|
|
|
|
3086
|
|
|
/** |
|
3087
|
|
|
* Encrypts using RSA a string using a public key. |
|
3088
|
|
|
* |
|
3089
|
|
|
* @param string $key Key to be encrypted |
|
3090
|
|
|
* @param string $publicKey User public key |
|
3091
|
|
|
* |
|
3092
|
|
|
* @return string |
|
3093
|
|
|
*/ |
|
3094
|
|
|
function encryptUserObjectKey($key, $publicKey) |
|
3095
|
|
|
{ |
|
3096
|
|
|
// Includes |
|
3097
|
|
|
include_once '../includes/libraries/Encryption/phpseclib/Math/BigInteger.php'; |
|
3098
|
|
|
include_once '../includes/libraries/Encryption/phpseclib/Crypt/RSA.php'; |
|
3099
|
|
|
|
|
3100
|
|
|
// Load classes |
|
3101
|
|
|
$rsa = new Crypt_RSA(); |
|
3102
|
|
|
$rsa->loadKey(base64_decode($publicKey)); |
|
3103
|
|
|
|
|
3104
|
|
|
// Encrypt |
|
3105
|
|
|
return base64_encode($rsa->encrypt(base64_decode($key))); |
|
3106
|
|
|
} |
|
3107
|
|
|
|
|
3108
|
|
|
/** |
|
3109
|
|
|
* Decrypts using RSA an encrypted string using a private key. |
|
3110
|
|
|
* |
|
3111
|
|
|
* @param string $key Encrypted key |
|
3112
|
|
|
* @param string $privateKey User private key |
|
3113
|
|
|
* |
|
3114
|
|
|
* @return string |
|
3115
|
|
|
*/ |
|
3116
|
|
|
function decryptUserObjectKey($key, $privateKey) |
|
3117
|
|
|
{ |
|
3118
|
|
|
// Includes |
|
3119
|
|
|
include_once '../includes/libraries/Encryption/phpseclib/Math/BigInteger.php'; |
|
3120
|
|
|
include_once '../includes/libraries/Encryption/phpseclib/Crypt/RSA.php'; |
|
3121
|
|
|
|
|
3122
|
|
|
// Load classes |
|
3123
|
|
|
$rsa = new Crypt_RSA(); |
|
3124
|
|
|
$rsa->loadKey(base64_decode($privateKey)); |
|
3125
|
|
|
|
|
3126
|
|
|
// Decrypt |
|
3127
|
|
|
return base64_encode($rsa->decrypt(base64_decode($key))); |
|
3128
|
|
|
} |
|
3129
|
|
|
|
|
3130
|
|
|
/** |
|
3131
|
|
|
* Encrypts a file. |
|
3132
|
|
|
* |
|
3133
|
|
|
* @param string $fileInName File name |
|
3134
|
|
|
* @param string $fileInPath Path to file |
|
3135
|
|
|
* |
|
3136
|
|
|
* @return array |
|
3137
|
|
|
*/ |
|
3138
|
|
|
function encryptFile($fileInName, $fileInPath) |
|
3139
|
|
|
{ |
|
3140
|
|
|
define('FILE_BUFFER_SIZE', 128 * 1024); |
|
3141
|
|
|
|
|
3142
|
|
|
// Includes |
|
3143
|
|
|
include_once '../includes/config/include.php'; |
|
3144
|
|
|
include_once '../includes/libraries/Encryption/phpseclib/Math/BigInteger.php'; |
|
3145
|
|
|
include_once '../includes/libraries/Encryption/phpseclib/Crypt/RSA.php'; |
|
3146
|
|
|
include_once '../includes/libraries/Encryption/phpseclib/Crypt/AES.php'; |
|
3147
|
|
|
|
|
3148
|
|
|
// Load classes |
|
3149
|
|
|
$cipher = new Crypt_AES(); |
|
3150
|
|
|
|
|
3151
|
|
|
// Generate an object key |
|
3152
|
|
|
$objectKey = uniqidReal(32); |
|
3153
|
|
|
|
|
3154
|
|
|
// Set it as password |
|
3155
|
|
|
$cipher->setPassword($objectKey); |
|
3156
|
|
|
|
|
3157
|
|
|
// Prevent against out of memory |
|
3158
|
|
|
$cipher->enableContinuousBuffer(); |
|
3159
|
|
|
$cipher->disablePadding(); |
|
3160
|
|
|
|
|
3161
|
|
|
// Encrypt the file content |
|
3162
|
|
|
$plaintext = file_get_contents($fileInPath.'/'.$fileInName); |
|
3163
|
|
|
$ciphertext = $cipher->encrypt($plaintext); |
|
3164
|
|
|
|
|
3165
|
|
|
// Save new file |
|
3166
|
|
|
$hash = md5($plaintext); |
|
3167
|
|
|
$fileOut = $fileInPath.'/'.TP_FILE_PREFIX.$hash; |
|
3168
|
|
|
file_put_contents($fileOut, $ciphertext); |
|
3169
|
|
|
unlink($fileInPath.'/'.$fileInName); |
|
3170
|
|
|
|
|
3171
|
|
|
return array( |
|
3172
|
|
|
'fileHash' => base64_encode($hash), |
|
3173
|
|
|
'objectKey' => base64_encode($objectKey), |
|
3174
|
|
|
); |
|
3175
|
|
|
} |
|
3176
|
|
|
|
|
3177
|
|
|
function decryptFile($fileName, $filePath, $key) |
|
3178
|
|
|
{ |
|
3179
|
|
|
define('FILE_BUFFER_SIZE', 128 * 1024); |
|
3180
|
|
|
|
|
3181
|
|
|
// Includes |
|
3182
|
|
|
include_once '../includes/config/include.php'; |
|
3183
|
|
|
include_once '../includes/libraries/Encryption/phpseclib/Math/BigInteger.php'; |
|
3184
|
|
|
include_once '../includes/libraries/Encryption/phpseclib/Crypt/RSA.php'; |
|
3185
|
|
|
include_once '../includes/libraries/Encryption/phpseclib/Crypt/AES.php'; |
|
3186
|
|
|
|
|
3187
|
|
|
// Get file name |
|
3188
|
|
|
$fileName = base64_decode($fileName); |
|
3189
|
|
|
|
|
3190
|
|
|
// Load classes |
|
3191
|
|
|
$cipher = new Crypt_AES(); |
|
3192
|
|
|
|
|
3193
|
|
|
// Set the object key |
|
3194
|
|
|
$cipher->setPassword(base64_decode($key)); |
|
3195
|
|
|
|
|
3196
|
|
|
// Prevent against out of memory |
|
3197
|
|
|
$cipher->enableContinuousBuffer(); |
|
3198
|
|
|
$cipher->disablePadding(); |
|
3199
|
|
|
|
|
3200
|
|
|
// Get file content |
|
3201
|
|
|
$ciphertext = file_get_contents($filePath.'/'.TP_FILE_PREFIX.$fileName); |
|
3202
|
|
|
|
|
3203
|
|
|
// Decrypt file content and return |
|
3204
|
|
|
return base64_encode($cipher->decrypt($ciphertext)); |
|
3205
|
|
|
} |
|
3206
|
|
|
|
|
3207
|
|
|
/** |
|
3208
|
|
|
* Undocumented function. |
|
3209
|
|
|
* |
|
3210
|
|
|
* @param int $length Length of password |
|
3211
|
|
|
* |
|
3212
|
|
|
* @return string |
|
3213
|
|
|
*/ |
|
3214
|
|
|
function generateQuickPassword($length = 16) |
|
3215
|
|
|
{ |
|
3216
|
|
|
// Generate new user password |
|
3217
|
|
|
$small_letters = range('a', 'z'); |
|
3218
|
|
|
$big_letters = range('A', 'Z'); |
|
3219
|
|
|
$digits = range(0, 9); |
|
3220
|
|
|
$symbols = array('#', '_', '-', '@', '$', '+', '&'); |
|
3221
|
|
|
|
|
3222
|
|
|
$res = array_merge($small_letters, $big_letters, $digits, $symbols); |
|
3223
|
|
|
$c = count($res); |
|
3224
|
|
|
// first variant |
|
3225
|
|
|
|
|
3226
|
|
|
$random_string = ''; |
|
3227
|
|
|
for ($i = 0; $i < $length; ++$i) { |
|
3228
|
|
|
$random_string .= $res[random_int(0, $c - 1)]; |
|
3229
|
|
|
} |
|
3230
|
|
|
|
|
3231
|
|
|
return $random_string; |
|
3232
|
|
|
} |
|
3233
|
|
|
|
|
3234
|
|
|
/** |
|
3235
|
|
|
* Permit to store the sharekey of an object for users. |
|
3236
|
|
|
* |
|
3237
|
|
|
* @param string $object_name Type for table selection |
|
3238
|
|
|
* @param int $post_folder_is_personal Personal |
|
3239
|
|
|
* @param int $post_folder_id Folder |
|
3240
|
|
|
* @param int $post_object_id Object |
|
3241
|
|
|
* @param array $objectKey Object key |
|
3242
|
|
|
* @param array $SETTINGS Teampass settings |
|
3243
|
|
|
*/ |
|
3244
|
|
|
function storeUsersShareKey( |
|
3245
|
|
|
$object_name, |
|
3246
|
|
|
$post_folder_is_personal, |
|
3247
|
|
|
$post_folder_id, |
|
3248
|
|
|
$post_object_id, |
|
3249
|
|
|
$objectKey, |
|
3250
|
|
|
$SETTINGS |
|
3251
|
|
|
) { |
|
3252
|
|
|
// include librairies & connect to DB |
|
3253
|
|
|
include_once $SETTINGS['cpassman_dir'].'/includes/config/settings.php'; |
|
3254
|
|
|
include_once $SETTINGS['cpassman_dir'].'/includes/libraries/Database/Meekrodb/db.class.php'; |
|
3255
|
|
|
$link = mysqli_connect(DB_HOST, DB_USER, defuseReturnDecrypted(DB_PASSWD, $SETTINGS), DB_NAME, DB_PORT); |
|
3256
|
|
|
$link->set_charset(DB_ENCODING); |
|
3257
|
|
|
|
|
3258
|
|
|
// Delete existing entries for this object |
|
3259
|
|
|
DB::delete( |
|
3260
|
|
|
$object_name, |
|
3261
|
|
|
'object_id = %i', |
|
3262
|
|
|
$post_object_id |
|
3263
|
|
|
); |
|
3264
|
|
|
|
|
3265
|
|
|
if ((int) $post_folder_is_personal === 1 |
|
3266
|
|
|
&& in_array($post_folder_id, $_SESSION['personal_folders']) === true |
|
3267
|
|
|
) { |
|
3268
|
|
|
// If this is a personal object |
|
3269
|
|
|
// Only create the sharekey for user |
|
3270
|
|
|
DB::insert( |
|
3271
|
|
|
$object_name, |
|
3272
|
|
|
array( |
|
3273
|
|
|
'object_id' => $post_object_id, |
|
3274
|
|
|
'user_id' => $_SESSION['user_id'], |
|
3275
|
|
|
'share_key' => encryptUserObjectKey($objectKey, $_SESSION['user']['public_key']), |
|
|
|
|
|
|
3276
|
|
|
) |
|
3277
|
|
|
); |
|
3278
|
|
|
} else { |
|
3279
|
|
|
// This is a public object |
|
3280
|
|
|
// Create sharekey for each user |
|
3281
|
|
|
$users = DB::query( |
|
3282
|
|
|
'SELECT id, public_key |
|
3283
|
|
|
FROM '.prefixTable('users').' |
|
3284
|
|
|
WHERE id NOT IN ("'.OTV_USER_ID.'","'.SSH_USER_ID.'","'.API_USER_ID.'") |
|
3285
|
|
|
AND public_key != ""' |
|
3286
|
|
|
); |
|
3287
|
|
|
foreach ($users as $user) { |
|
3288
|
|
|
// Insert in DB the new object key for this item by user |
|
3289
|
|
|
DB::insert( |
|
3290
|
|
|
$object_name, |
|
3291
|
|
|
array( |
|
3292
|
|
|
'object_id' => $post_object_id, |
|
3293
|
|
|
'user_id' => $user['id'], |
|
3294
|
|
|
'share_key' => encryptUserObjectKey( |
|
3295
|
|
|
$objectKey, |
|
3296
|
|
|
$user['public_key'] |
|
3297
|
|
|
), |
|
3298
|
|
|
) |
|
3299
|
|
|
); |
|
3300
|
|
|
} |
|
3301
|
|
|
} |
|
3302
|
|
|
} |
|
3303
|
|
|
|
|
3304
|
|
|
/** |
|
3305
|
|
|
* Is this string base64 encoded? |
|
3306
|
|
|
* |
|
3307
|
|
|
* @param string $str Encoded string? |
|
3308
|
|
|
* |
|
3309
|
|
|
* @return bool |
|
3310
|
|
|
*/ |
|
3311
|
|
|
function isBase64($str) |
|
3312
|
|
|
{ |
|
3313
|
|
|
$str = (string) trim($str); |
|
3314
|
|
|
|
|
3315
|
|
|
if (!isset($str[0])) { |
|
3316
|
|
|
return false; |
|
3317
|
|
|
} |
|
3318
|
|
|
|
|
3319
|
|
|
$base64String = (string) base64_decode($str, true); |
|
3320
|
|
|
if ($base64String && base64_encode($base64String) === $str) { |
|
3321
|
|
|
return true; |
|
3322
|
|
|
} |
|
3323
|
|
|
|
|
3324
|
|
|
return false; |
|
3325
|
|
|
} |
|
3326
|
|
|
|