29
29
#include "plist.h"
30
30
#include "plibs.h"
31
31
#include "pfs.h"
32
+ #include "pfolder.h"
33
+ #include "pcloudcrypto.h"
32
34
#include <string.h>
33
35
#include <ctype.h>
34
36
40
42
41
43
#define FOLDER_TASKS_HASH_SIZE 1024
42
44
43
- #define ENTRY_FLAG_FOLDER 1
45
+ #define ENTRY_FLAG_FOLDER 1
46
+ #define ENTRY_FLAG_ENCRYPTED 2
44
47
45
48
typedef struct {
46
49
uint32_t hash [4 ];
@@ -423,8 +426,29 @@ static void comp_hash(const char *s, size_t len, uint32_t *out, uint64_t seed1,
423
426
out [3 ]= d ;
424
427
}
425
428
429
+ static int move_encname_to_buff (psync_folderid_t folderid , char * buff , size_t buff_size , const char * name , size_t namelen ) {
430
+ psync_crypto_aes256_text_encoder_t enc ;
431
+ char * encname ;
432
+ size_t len ;
433
+ if (unlikely (namelen >=buff_size ))
434
+ return -1 ;
435
+ memcpy (buff , name , namelen );
436
+ buff [namelen ]= 0 ;
437
+ enc = psync_cloud_crypto_get_folder_encoder (folderid );
438
+ if (unlikely (psync_crypto_is_error (enc )))
439
+ return -1 ;
440
+ encname = psync_cloud_crypto_encode_filename (enc , buff );
441
+ psync_cloud_crypto_release_folder_encoder (folderid , enc );
442
+ len = strlen (encname );
443
+ if (unlikely (len >=sizeof (buff )))
444
+ return -1 ;
445
+ memcpy (buff , encname , len + 1 );
446
+ psync_free (encname );
447
+ return 0 ;
448
+ }
449
+
426
450
static psync_path_status_t psync_path_status_drive (const char * path , size_t path_len ) {
427
- char buff [1032 ];
451
+ char buff [2048 ];
428
452
uint32_t hash [4 ], h ;
429
453
psync_fstask_folder_t * folder ;
430
454
path_cache_entry_t * ce ;
@@ -433,6 +457,8 @@ static psync_path_status_t psync_path_status_drive(const char *path, size_t path
433
457
psync_folderid_t folderid ;
434
458
uint64_t flags ;
435
459
size_t off , poff ;
460
+ const char * name ;
461
+ size_t namelen ;
436
462
int wrlocked , found ;
437
463
while (is_slash (* path )) {
438
464
path ++ ;
@@ -445,7 +471,7 @@ static psync_path_status_t psync_path_status_drive(const char *path, size_t path
445
471
restart :
446
472
poff = 0 ;
447
473
folderid = 0 ;
448
- flags = 0 ;
474
+ flags = ENTRY_FLAG_FOLDER ;
449
475
for (off = 0 ; off < path_len ; off ++ )
450
476
if (is_slash (path [off ])) {
451
477
if (off && is_slash (path [off - 1 ])) {
@@ -455,8 +481,13 @@ static psync_path_status_t psync_path_status_drive(const char *path, size_t path
455
481
if (folder ) {
456
482
if (unlikely (off - poff >=sizeof (buff )))
457
483
return rdunlock_return (PSYNC_PATH_STATUS_IN_SYNC );
458
- memcpy (buff , path + poff , off - poff );
459
- buff [off - poff ]= 0 ;
484
+ if (likely ((flags & ENTRY_FLAG_ENCRYPTED )== 0 )) {
485
+ memcpy (buff , path + poff , off - poff );
486
+ buff [off - poff ]= 0 ;
487
+ } else {
488
+ if (unlikely (move_encname_to_buff (folderid , buff , sizeof (buff ), path + poff , off - poff )))
489
+ return rdunlock_return (PSYNC_PATH_STATUS_IN_SYNC );
490
+ }
460
491
if (psync_fstask_find_mkdir (folder , buff , 0 ))
461
492
return rdunlock_return_in_prog ();
462
493
if (psync_fstask_find_rmdir (folder , buff , 0 ))
@@ -479,10 +510,17 @@ static psync_path_status_t psync_path_status_drive(const char *path, size_t path
479
510
}
480
511
if (found )
481
512
continue ;
482
- //TODO: handle encrypted folders by encoding name to buff
483
513
res = psync_sql_query_nolock ("SELECT id, permissions, flags, userid FROM folder WHERE parentfolderid=? AND name=?" );
484
514
psync_sql_bind_uint (res , 1 , folderid );
485
- psync_sql_bind_lstring (res , 2 , path + poff , off - poff );
515
+ if (likely ((flags & ENTRY_FLAG_ENCRYPTED )== 0 )) {
516
+ psync_sql_bind_lstring (res , 2 , path + poff , off - poff );
517
+ } else {
518
+ psync_sql_free_result (res );
519
+ if (unlikely (move_encname_to_buff (folderid , buff , sizeof (buff ), path + poff , off - poff )))
520
+ return rdunlock_return (PSYNC_PATH_STATUS_IN_SYNC );
521
+ psync_sql_bind_string (res , 2 , buff );
522
+
523
+ }
486
524
row = psync_sql_fetch_rowint (res );
487
525
if (!row ) {
488
526
psync_sql_free_result (res );
@@ -499,6 +537,8 @@ static psync_path_status_t psync_path_status_drive(const char *path, size_t path
499
537
}
500
538
folderid = row [0 ];
501
539
flags = ENTRY_FLAG_FOLDER ;
540
+ if (row [2 ]& PSYNC_FOLDER_FLAG_ENCRYPTED )
541
+ flags |=ENTRY_FLAG_ENCRYPTED ;
502
542
psync_sql_free_result (res );
503
543
ce = psync_list_remove_head_element (& path_cache_lru , path_cache_entry_t , list_lru );
504
544
psync_list_add_tail (& path_cache_lru , & ce -> list_lru );
@@ -513,12 +553,21 @@ static psync_path_status_t psync_path_status_drive(const char *path, size_t path
513
553
if (poff == path_len )
514
554
return psync_path_status_drive_folder_locked (folderid );
515
555
folder = psync_fstask_get_folder_tasks_rdlocked (folderid );
556
+ name = path + poff ;
557
+ namelen = path_len - poff ;
516
558
if (folder ) {
517
- if (psync_fstask_find_mkdir (folder , path + poff , 0 ))
559
+ if (unlikely (flags & ENTRY_FLAG_ENCRYPTED )) {
560
+ if (unlikely (move_encname_to_buff (folderid , buff , sizeof (buff ), path + poff , path_len - poff )))
561
+ return rdunlock_return (PSYNC_PATH_STATUS_IN_SYNC );
562
+ name = buff ;
563
+ namelen = strlen (buff );
564
+ }
565
+ if (psync_fstask_find_mkdir (folder , name , 0 ))
518
566
return rdunlock_return_in_prog ();
519
- if (psync_fstask_find_creat (folder , path + poff , 0 ))
567
+ if (psync_fstask_find_creat (folder , name , 0 ))
520
568
return rdunlock_return_in_prog ();
521
569
}
570
+ // we do the hash with the unencrypted name
522
571
comp_hash (path + poff , path_len - poff , hash , folderid , drv_hash_seed );
523
572
h = (hash [0 ]+ hash [2 ])%PATH_HASH_SIZE ;
524
573
found = 0 ;
@@ -535,28 +584,34 @@ static psync_path_status_t psync_path_status_drive(const char *path, size_t path
535
584
}
536
585
if (found ) {
537
586
if (flags & ENTRY_FLAG_FOLDER ) {
538
- if (folder && psync_fstask_find_rmdir (folder , path + poff , 0 ))
587
+ if (folder && psync_fstask_find_rmdir (folder , name , 0 ))
539
588
return rdunlock_return (PSYNC_PATH_STATUS_NOT_FOUND );
540
589
else
541
590
return psync_path_status_drive_folder_locked (folderid );
542
591
} else {
543
- if (folder && psync_fstask_find_unlink (folder , path + poff , 0 ))
592
+ if (folder && psync_fstask_find_unlink (folder , name , 0 ))
544
593
return rdunlock_return (PSYNC_PATH_STATUS_NOT_FOUND );
545
594
else
546
595
return rdunlock_return (PSYNC_PATH_STATUS_IN_SYNC );
547
596
}
548
597
}
598
+ if (unlikely (!folder && (flags & ENTRY_FLAG_ENCRYPTED ))) {
599
+ if (unlikely (move_encname_to_buff (folderid , buff , sizeof (buff ), path + poff , path_len - poff )))
600
+ return rdunlock_return (PSYNC_PATH_STATUS_IN_SYNC );
601
+ name = buff ;
602
+ namelen = strlen (buff );
603
+ }
549
604
res = psync_sql_query_nolock ("SELECT id, permissions, flags, userid FROM folder WHERE parentfolderid=? AND name=?" );
550
605
psync_sql_bind_uint (res , 1 , folderid );
551
- psync_sql_bind_lstring (res , 2 , path + poff , path_len - poff );
606
+ psync_sql_bind_lstring (res , 2 , name , namelen );
552
607
row = psync_sql_fetch_rowint (res );
553
608
if (!row || (folder && psync_fstask_find_rmdir (folder , path + poff , 0 ))) {
554
609
psync_sql_free_result (res );
555
610
if (folder && psync_fstask_find_unlink (folder , path + poff , 0 ))
556
611
return rdunlock_return (PSYNC_PATH_STATUS_NOT_FOUND );
557
612
res = psync_sql_query_nolock ("SELECT id FROM file WHERE parentfolderid=? AND name=?" );
558
613
psync_sql_bind_uint (res , 1 , folderid );
559
- psync_sql_bind_lstring (res , 2 , path + poff , path_len - poff );
614
+ psync_sql_bind_lstring (res , 2 , name , namelen );
560
615
row = psync_sql_fetch_rowint (res );
561
616
if (!row ) {
562
617
psync_sql_free_result (res );
@@ -572,7 +627,7 @@ static psync_path_status_t psync_path_status_drive(const char *path, size_t path
572
627
goto restart ;
573
628
}
574
629
folderid = row [0 ];
575
- flags = 0 ;
630
+ flags &=~ ENTRY_FLAG_FOLDER ;
576
631
psync_sql_free_result (res );
577
632
ce = psync_list_remove_head_element (& path_cache_lru , path_cache_entry_t , list_lru );
578
633
psync_list_add_tail (& path_cache_lru , & ce -> list_lru );
0 commit comments