Skip to content

Commit a30285e

Browse files
author
virco
committed
add encrypted folder support
1 parent 5d99741 commit a30285e

File tree

1 file changed

+69
-14
lines changed

1 file changed

+69
-14
lines changed

ppathstatus.c

Lines changed: 69 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
#include "plist.h"
3030
#include "plibs.h"
3131
#include "pfs.h"
32+
#include "pfolder.h"
33+
#include "pcloudcrypto.h"
3234
#include <string.h>
3335
#include <ctype.h>
3436

@@ -40,7 +42,8 @@
4042

4143
#define FOLDER_TASKS_HASH_SIZE 1024
4244

43-
#define ENTRY_FLAG_FOLDER 1
45+
#define ENTRY_FLAG_FOLDER 1
46+
#define ENTRY_FLAG_ENCRYPTED 2
4447

4548
typedef struct {
4649
uint32_t hash[4];
@@ -423,8 +426,29 @@ static void comp_hash(const char *s, size_t len, uint32_t *out, uint64_t seed1,
423426
out[3]=d;
424427
}
425428

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+
426450
static psync_path_status_t psync_path_status_drive(const char *path, size_t path_len) {
427-
char buff[1032];
451+
char buff[2048];
428452
uint32_t hash[4], h;
429453
psync_fstask_folder_t *folder;
430454
path_cache_entry_t *ce;
@@ -433,6 +457,8 @@ static psync_path_status_t psync_path_status_drive(const char *path, size_t path
433457
psync_folderid_t folderid;
434458
uint64_t flags;
435459
size_t off, poff;
460+
const char *name;
461+
size_t namelen;
436462
int wrlocked, found;
437463
while (is_slash(*path)) {
438464
path++;
@@ -445,7 +471,7 @@ static psync_path_status_t psync_path_status_drive(const char *path, size_t path
445471
restart:
446472
poff=0;
447473
folderid=0;
448-
flags=0;
474+
flags=ENTRY_FLAG_FOLDER;
449475
for (off=0; off<path_len; off++)
450476
if (is_slash(path[off])) {
451477
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
455481
if (folder) {
456482
if (unlikely(off-poff>=sizeof(buff)))
457483
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+
}
460491
if (psync_fstask_find_mkdir(folder, buff, 0))
461492
return rdunlock_return_in_prog();
462493
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
479510
}
480511
if (found)
481512
continue;
482-
//TODO: handle encrypted folders by encoding name to buff
483513
res=psync_sql_query_nolock("SELECT id, permissions, flags, userid FROM folder WHERE parentfolderid=? AND name=?");
484514
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+
}
486524
row=psync_sql_fetch_rowint(res);
487525
if (!row) {
488526
psync_sql_free_result(res);
@@ -499,6 +537,8 @@ static psync_path_status_t psync_path_status_drive(const char *path, size_t path
499537
}
500538
folderid=row[0];
501539
flags=ENTRY_FLAG_FOLDER;
540+
if (row[2]&PSYNC_FOLDER_FLAG_ENCRYPTED)
541+
flags|=ENTRY_FLAG_ENCRYPTED;
502542
psync_sql_free_result(res);
503543
ce=psync_list_remove_head_element(&path_cache_lru, path_cache_entry_t, list_lru);
504544
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
513553
if (poff==path_len)
514554
return psync_path_status_drive_folder_locked(folderid);
515555
folder=psync_fstask_get_folder_tasks_rdlocked(folderid);
556+
name=path+poff;
557+
namelen=path_len-poff;
516558
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))
518566
return rdunlock_return_in_prog();
519-
if (psync_fstask_find_creat(folder, path+poff, 0))
567+
if (psync_fstask_find_creat(folder, name, 0))
520568
return rdunlock_return_in_prog();
521569
}
570+
// we do the hash with the unencrypted name
522571
comp_hash(path+poff, path_len-poff, hash, folderid, drv_hash_seed);
523572
h=(hash[0]+hash[2])%PATH_HASH_SIZE;
524573
found=0;
@@ -535,28 +584,34 @@ static psync_path_status_t psync_path_status_drive(const char *path, size_t path
535584
}
536585
if (found) {
537586
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))
539588
return rdunlock_return(PSYNC_PATH_STATUS_NOT_FOUND);
540589
else
541590
return psync_path_status_drive_folder_locked(folderid);
542591
} else {
543-
if (folder && psync_fstask_find_unlink(folder, path+poff, 0))
592+
if (folder && psync_fstask_find_unlink(folder, name, 0))
544593
return rdunlock_return(PSYNC_PATH_STATUS_NOT_FOUND);
545594
else
546595
return rdunlock_return(PSYNC_PATH_STATUS_IN_SYNC);
547596
}
548597
}
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+
}
549604
res=psync_sql_query_nolock("SELECT id, permissions, flags, userid FROM folder WHERE parentfolderid=? AND name=?");
550605
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);
552607
row=psync_sql_fetch_rowint(res);
553608
if (!row || (folder && psync_fstask_find_rmdir(folder, path+poff, 0))) {
554609
psync_sql_free_result(res);
555610
if (folder && psync_fstask_find_unlink(folder, path+poff, 0))
556611
return rdunlock_return(PSYNC_PATH_STATUS_NOT_FOUND);
557612
res=psync_sql_query_nolock("SELECT id FROM file WHERE parentfolderid=? AND name=?");
558613
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);
560615
row=psync_sql_fetch_rowint(res);
561616
if (!row) {
562617
psync_sql_free_result(res);
@@ -572,7 +627,7 @@ static psync_path_status_t psync_path_status_drive(const char *path, size_t path
572627
goto restart;
573628
}
574629
folderid=row[0];
575-
flags=0;
630+
flags&=~ENTRY_FLAG_FOLDER;
576631
psync_sql_free_result(res);
577632
ce=psync_list_remove_head_element(&path_cache_lru, path_cache_entry_t, list_lru);
578633
psync_list_add_tail(&path_cache_lru, &ce->list_lru);

0 commit comments

Comments
 (0)