Skip to content

Commit 7ae4a55

Browse files
committed
Updating the permissions: using default_permissions and using a mask for files and directories. Adding a dir_cache config
1 parent bd4b139 commit 7ae4a55

File tree

6 files changed

+54
-23
lines changed

6 files changed

+54
-23
lines changed

example/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ DAZ_SECKEY=$(shell pwd)/example.seckey
77
export C4GH_PASSPHRASE=hello
88

99
DAZ_OPTS+=ro,seckey=$(DAZ_SECKEY),passphrase_from_env=C4GH_PASSPHRASE
10-
DAZ_OPTS+=allow_other
10+
DAZ_OPTS+=allow_other,default_permissions
11+
DAZ_OPTS+=file_cache,dir_cache
1112

1213
all: up
1314

src/fs.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ crypt4gh_sqlite_getattr(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *f
5757

5858
if( ino == FUSE_ROOT_ID ){ /* It's the root directory itself */
5959
s.st_ino = ino;
60-
s.st_mode = S_IFDIR | 0500;
60+
s.st_mode = S_IFDIR | config.dperm;
6161
s.st_nlink = 1;
6262
s.st_size = 0;
6363
time_t now = time(NULL);
@@ -105,9 +105,9 @@ crypt4gh_sqlite_getattr(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *f
105105
s.st_size = (uint64_t)sqlite3_column_int(stmt, 3);
106106

107107
if(sqlite3_column_int(stmt, 4)) // is_dir
108-
s.st_mode = S_IFDIR | 0500;
108+
s.st_mode = S_IFDIR | config.dperm;
109109
else
110-
s.st_mode = S_IFREG | 0400;
110+
s.st_mode = S_IFREG | config.fperm;
111111

112112
time_t now = time(NULL);
113113
struct timespec mt = { .tv_sec = mtime, .tv_nsec = 0L },
@@ -191,9 +191,9 @@ __attribute__((nonnull(3)))
191191
e.attr.st_size = (uint64_t)sqlite3_column_int64(stmt, 4);
192192

193193
if(sqlite3_column_int(stmt, 5)) // is_dir
194-
e.attr.st_mode = S_IFDIR | 0500;
194+
e.attr.st_mode = S_IFDIR | config.dperm;
195195
else
196-
e.attr.st_mode = S_IFREG | 0400;
196+
e.attr.st_mode = S_IFREG | config.fperm;
197197
break;
198198
}
199199

@@ -238,7 +238,8 @@ crypt4gh_sqlite_opendir(fuse_req_t req, fuse_ino_t ino,
238238
}
239239

240240
fi->fh = (uint64_t)stmt;
241-
fi->cache_readdir = 1;
241+
if (config.dir_cache)
242+
fi->cache_readdir = 1;
242243
D3("stmt: %s", sqlite3_sql(stmt)); /* sqlite3_finalize will free it */
243244
fuse_reply_open(req, fi);
244245
}
@@ -312,7 +313,7 @@ crypt4gh_sqlite_readdir_plus(fuse_req_t req, fuse_ino_t ino, size_t size,
312313
e.attr.st_atim = at;
313314
e.attr.st_nlink = 1;
314315
e.attr.st_size = 0;
315-
e.attr.st_mode = S_IFDIR | 0500;
316+
e.attr.st_mode = S_IFDIR | config.dperm;
316317

317318
if(offset < 1){
318319
e.ino = 2;
@@ -364,9 +365,9 @@ crypt4gh_sqlite_readdir_plus(fuse_req_t req, fuse_ino_t ino, size_t size,
364365
e.attr.st_size = (uint64_t)sqlite3_column_int64(stmt, 5);
365366

366367
if(sqlite3_column_int(stmt, 6)) // is_dir
367-
e.attr.st_mode = S_IFDIR | 0500;
368+
e.attr.st_mode = S_IFDIR | config.dperm;
368369
else
369-
e.attr.st_mode = S_IFREG | 0400;
370+
e.attr.st_mode = S_IFREG | config.fperm;
370371

371372
/* add the entry to the buffer and check size */
372373
char* pe = (char*)sqlite3_column_text(stmt, 1);

src/includes.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,11 @@ struct fs_config {
116116
time_t mounted_at;
117117
int direct_io;
118118

119+
unsigned int fmask;
120+
unsigned int dmask;
121+
unsigned int dperm;
122+
unsigned int fperm;
123+
119124
int debug; /* replace/overwrite the fuse debug */
120125
int verbose;
121126
int foreground;

src/keys/kdf.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ crypt4gh_sqlite_kdf_derive_key(char* alg,
4949
/* See https://www.rfc-editor.org/rfc/rfc7914.txt
5050
and https://doc.libsodium.org/advanced/scrypt#notes */
5151
if (!strncmp(alg, "scrypt", 6)){
52-
D1("Deriving a shared key using scrypt");
52+
D3("Deriving a shared key using scrypt");
5353
return crypto_pwhash_scryptsalsa208sha256_ll((const uint8_t*)passphrase, passphrase_len,
5454
salt, salt_len,
5555
1<<14, 8, 1,
@@ -59,7 +59,7 @@ crypt4gh_sqlite_kdf_derive_key(char* alg,
5959
/* See keys/bcrypt
6060
and https://github.com/pyca/bcrypt/tree/master/src/_csrc */
6161
if (!strncmp(alg, "bcrypt", 6)){
62-
D1("Deriving a shared key using scrypt");
62+
D3("Deriving a shared key using scrypt");
6363
return bcrypt_pbkdf(passphrase, passphrase_len,
6464
salt, salt_len,
6565
key, key_len,
@@ -68,6 +68,7 @@ crypt4gh_sqlite_kdf_derive_key(char* alg,
6868

6969
/* See https://www.openssl.org/docs/man1.1.0/man3/PKCS5_PBKDF2_HMAC.html */
7070
if (!strncmp(alg, "pbkdf2_hmac_sha256", 18)){
71+
D3("Deriving a shared key using HMAC-SHA256");
7172
const EVP_MD *digest = EVP_sha256();
7273
if(digest == NULL) return 3;
7374
int rc = PKCS5_PBKDF2_HMAC(passphrase, passphrase_len,

src/keys/key.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ crypt4gh_sqlite_public_key_from_blob(const char* line,
3737
int rc = 1;
3838
char* end = (char*)line + len - 1; /* point at the end */
3939
D3("Length: %lu", len);
40-
D3("Last char: %c", *end);
40+
//D3("Last char: %c", *end);
4141

4242
while(isspace(*line)){ line++; len--; }; /* skip leading white-space (or newline) */
4343
while(isspace(*end)){ end--; len--; }; /* Discount trailing white-space or newline */
@@ -174,7 +174,7 @@ crypt4gh_sqlite_private_key_from_blob(char* line, size_t len,
174174
/* we _can_ change "line" */
175175
*(end+1) = '\0';
176176

177-
D2("base64 string: %s", line);
177+
D3("base64 string: %s", line);
178178

179179
/* Decoded string will be NULL-terminated too */
180180
tmp = (u_char*)malloc((len+1) * sizeof(char));

src/main.c

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818

1919
#define FS_NAME "crypt4gh-sqlite.fs"
2020

21+
#define DEFAULT_FILE_MASK 0337
22+
#define DEFAULT_DIR_MASK 0227
23+
2124
/* global variable */
2225
struct fs_config config;
2326

@@ -35,7 +38,9 @@ static void usage(struct fuse_args *args)
3538
" --debug=N debug level <N>\n"
3639
" -o direct_io enable direct i/o\n"
3740
" -o file_cache instructs the kernel to cache output data\n"
38-
" -o file_cache instructs the kernel to cache output data\n"
41+
" -o dir_cache instructs the kernel to cache directory listings\n"
42+
" -o file_mask=N file permissions' mask [default: %o]\n"
43+
" -o dir_mask=N directory permissions' mask [default: %o]\n"
3944
" -o entry_timeout=S seconds for which lookup names are cached [default: one day]\n"
4045
" -o attr_timeout=S seconds for which directories/files attributes are cached [default: one day]\n"
4146
" -o dotdot Shows '.' and '..' directories [default: ignored]\n"
@@ -46,7 +51,7 @@ static void usage(struct fuse_args *args)
4651
" -o seckey=<path> Absolute path to the Crypt4GH secret key\n"
4752
" -o passphrase_from_env=<ENVVAR>\n"
4853
" read passphrase from environment variable <ENVVAR>\n"
49-
, args->argv[0]);
54+
, args->argv[0], DEFAULT_FILE_MASK, DEFAULT_DIR_MASK);
5055
}
5156

5257

@@ -68,13 +73,17 @@ static struct fuse_opt fs_opts[] = {
6873

6974
CRYPT4GH_SQLITE_OPT("direct_io", direct_io, 1),
7075
CRYPT4GH_SQLITE_OPT("file_cache", file_cache, 1),
76+
CRYPT4GH_SQLITE_OPT("dir_cache", dir_cache, 1),
7177

7278
CRYPT4GH_SQLITE_OPT("dotdot", show_dotdot, 1),
7379

7480
/* Mount group id */
7581
CRYPT4GH_SQLITE_OPT("user_id=%u", uid, 0), // chill... it's not root
7682
CRYPT4GH_SQLITE_OPT("group_id=%u", gid, 0),
7783

84+
CRYPT4GH_SQLITE_OPT("file_mask=%u", fmask, DEFAULT_FILE_MASK),
85+
CRYPT4GH_SQLITE_OPT("dir_mask=%u", dmask, DEFAULT_DIR_MASK),
86+
7887
/* in case Crypt4GH is enabled */
7988
CRYPT4GH_SQLITE_OPT("seckey=%s" , seckeypath , 0),
8089
CRYPT4GH_SQLITE_OPT("passphrase_from_env=%s", passphrase_from_env, 0),
@@ -202,6 +211,8 @@ c4gh_init(void)
202211
{
203212
int res = 0;
204213

214+
D1("Initializing the file system");
215+
205216
if(!config.seckeypath || *config.seckeypath != '/'){
206217
E("Missing secret key path, or non-absolute path");
207218
res ++;
@@ -210,7 +221,7 @@ c4gh_init(void)
210221

211222
/* Get the passphrase to unlock the Crypt4GH secret key */
212223
if (config.passphrase_from_env) {
213-
D1("Getting the passphrase from envvar %s", config.passphrase_from_env);
224+
D2("Getting the passphrase from envvar %s", config.passphrase_from_env);
214225
config.passphrase = getenv(config.passphrase_from_env);
215226
} else {
216227
char prompt[PATH_MAX + sizeof("Enter the passphrase for the Crypt4GH key '': ")];
@@ -235,7 +246,7 @@ c4gh_init(void)
235246
}
236247

237248
/* Load the private key */
238-
D2("Loading secret key from %s", config.seckeypath);
249+
D3("Loading secret key from %s", config.seckeypath);
239250

240251
if( crypt4gh_sqlite_private_key_from_file(config.seckeypath, config.passphrase,
241252
config.seckey, config.pubkey) ){
@@ -292,6 +303,9 @@ int main(int argc, char *argv[])
292303
config.uid = getuid(); /* current user */
293304
config.gid = getgid(); /* current group */
294305

306+
config.fmask = DEFAULT_FILE_MASK;
307+
config.dmask = DEFAULT_DIR_MASK;
308+
295309
/* General options */
296310
if (fuse_opt_parse(&args, &config, fs_opts, fs_opt_proc) == -1)
297311
exit(1);
@@ -332,6 +346,10 @@ int main(int argc, char *argv[])
332346
exit(1);
333347
}
334348

349+
/* File and Dir permissions */
350+
config.dperm = 0777 & ~config.dmask;
351+
config.fperm = 0666 & ~config.dmask;
352+
335353
fuse_opt_insert_arg(&args, 1, "-ofsname=" FS_NAME);
336354

337355
if(config.debug)
@@ -392,17 +410,22 @@ int main(int argc, char *argv[])
392410
goto bailout_unmount;
393411
}
394412

395-
D2("Mode: %s-threaded", (config.singlethread)?"single":"multi");
396413
D2("PID: %d", getpid());
397-
398-
if (config.singlethread)
414+
D2("File cache: %s | Dir cache: %s | File perm: o%o | Dir perm: o%o",
415+
(config.file_cache)?"yes":"no",
416+
(config.dir_cache)?"yes":"no",
417+
config.fperm,
418+
config.dperm);
419+
420+
if (config.singlethread){
421+
D2("Mode: single-threaded");
399422
res = fuse_session_loop(se);
400-
else {
423+
} else {
401424
struct fuse_loop_config cf = {
402425
.clone_fd = config.clone_fd,
403426
.max_idle_threads = config.max_idle_threads,
404427
};
405-
D2("Max idle threads: %d", cf.max_idle_threads);
428+
D2("Mode: multi-threaded (max idle threads: %d)", cf.max_idle_threads);
406429
res = fuse_session_loop_mt(se, &cf);
407430
}
408431

0 commit comments

Comments
 (0)