2
* Copyright (C) 2006 International Business Machines Corp.
3
* Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
4
* Tyler Hicks <tyhicks@ou.edu>
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License as
8
* published by the Free Software Foundation; either version 2 of the
9
* License, or (at your option) any later version.
11
* This program is distributed in the hope that it will be useful, but
12
* WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
* General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
32
#include <sys/mount.h>
36
#include <sys/types.h>
41
#include "../include/ecryptfs.h"
43
int ecryptfs_verbosity = 0;
45
void ecryptfs_get_versions(int *major, int *minor, int *file_version)
47
*major = ECRYPTFS_VERSION_MAJOR;
48
*minor = ECRYPTFS_VERSION_MINOR;
50
*file_version = ECRYPTFS_SUPPORTED_FILE_VERSION;
53
inline void to_hex(char *dst, char *src, int src_size)
57
for (x = 0; x < src_size; x++)
58
sprintf(&dst[x*2], "%.2x", (unsigned char)src[x] );
59
dst[src_size*2] = '\0';
62
void from_hex(char *dst, char *src, int dst_size)
67
for (x = 0; x < dst_size; x++) {
69
tmp[1] = src[x * 2 + 1];
70
dst[x] = (char)strtol(tmp, NULL, 16);
74
int do_hash(char *src, int src_size, char *dst, int algo)
81
err = gcry_md_open(&hd, algo, 0);
82
mdlen = gcry_md_get_algo_dlen(algo);
84
syslog(LOG_ERR, "Failed to open hash algo [%d]: "
88
gcry_md_write(hd, src, src_size);
89
hash = gcry_md_read(hd, algo);
90
memcpy(dst, hash, mdlen);
97
* TODO: We need to support more hash algs
99
* @passphrase A NULL-terminated char array
103
* @passphrase_sig An allocated char array into which the generated
104
* signature is written; PASSWORD_SIG_SIZE bytes should be allocated
108
generate_passphrase_sig(char *passphrase_sig, char *passphrase, char *salt,
109
char *session_key_encryption_key)
111
char salt_and_passphrase[ECRYPTFS_MAX_PASSPHRASE_BYTES
112
+ ECRYPTFS_SALT_SIZE];
114
int alg = GCRY_MD_SHA512;
115
int dig_len = SHA512_DIGEST_LENGTH;
116
char buf[SHA512_DIGEST_LENGTH];
117
int hash_iterations = ECRYPTFS_DEFAULT_NUM_HASH_ITERATIONS;
120
passphrase_size = strlen(passphrase);
121
if (passphrase_size > ECRYPTFS_MAX_PASSPHRASE_BYTES) {
122
passphrase_sig = NULL;
123
syslog(LOG_ERR, "Passphrase too large (%d bytes)\n",
127
memcpy(salt_and_passphrase, salt, ECRYPTFS_SALT_SIZE);
128
memcpy((salt_and_passphrase + ECRYPTFS_SALT_SIZE), passphrase,
130
if ((rc = do_hash(salt_and_passphrase,
131
(ECRYPTFS_SALT_SIZE + passphrase_size), buf, alg))) {
135
while (hash_iterations--) {
136
if ((rc = do_hash(buf, dig_len, buf, alg))) {
140
memcpy(session_key_encryption_key, buf, ECRYPTFS_MAX_KEY_BYTES);
141
if ((rc = do_hash(buf, dig_len, buf, alg))) {
144
to_hex(passphrase_sig, buf, ECRYPTFS_SIG_SIZE);
149
* @return Zero on success
152
generate_payload(struct ecryptfs_auth_tok *auth_tok, char *passphrase_sig,
153
char *salt, char *session_key_encryption_key)
158
memset(auth_tok, 0, sizeof(struct ecryptfs_auth_tok));
159
ecryptfs_get_versions(&major, &minor, NULL);
160
auth_tok->version = (((uint16_t)(major << 8) & 0xFF00)
161
| ((uint16_t)minor & 0x00FF));
162
auth_tok->token_type = ECRYPTFS_PASSWORD;
163
strncpy(auth_tok->token.password.signature, passphrase_sig,
164
ECRYPTFS_PASSWORD_SIG_SIZE);
165
memcpy(auth_tok->token.password.salt, salt, ECRYPTFS_SALT_SIZE);
166
memcpy(auth_tok->token.password.session_key_encryption_key,
167
session_key_encryption_key, ECRYPTFS_MAX_KEY_BYTES);
168
/* TODO: Make the hash parameterizable via policy */
169
auth_tok->token.password.session_key_encryption_key_bytes =
170
ECRYPTFS_MAX_KEY_BYTES;
171
auth_tok->token.password.flags |=
172
ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET;
173
/* The kernel code will encrypt the session key. */
174
auth_tok->session_key.encrypted_key[0] = 0;
175
auth_tok->session_key.encrypted_key_size = 0;
176
/* Default; subject to change by kernel eCryptfs */
177
auth_tok->token.password.hash_algo = PGP_DIGEST_ALGO_SHA512;
178
auth_tok->token.password.flags &= ~(ECRYPTFS_PERSISTENT_PASSWORD);
183
* @auth_tok: A previous call to get_blob() by the callee determined
184
* how much space to allocate at the end of the auth_tok
185
* memory for the blob; this memory is already allocated
186
* and ready to be written into
189
ecryptfs_generate_key_payload(struct ecryptfs_auth_tok *auth_tok,
190
struct ecryptfs_key_mod *key_mod,
191
char *sig, size_t blob_size)
194
unsigned char *key_data;
196
size_t blob_size_tmp;
199
memset(auth_tok, 0, sizeof(struct ecryptfs_auth_tok) + blob_size);
200
ecryptfs_get_versions(&major, &minor, NULL);
201
auth_tok->version = (((uint16_t)(major << 8) & 0xFF00)
202
| ((uint16_t)minor & 0x00FF));
203
auth_tok->token_type = ECRYPTFS_PRIVATE_KEY;
204
if (key_mod->blob == NULL) {
205
if ((rc = (key_mod->ops->get_blob)
206
(auth_tok->token.private_key.data, &blob_size_tmp,
207
key_mod->param_vals, key_mod->num_param_vals))) {
208
syslog(LOG_ERR, "Call into key module's get_blob "
209
"failed; rc = [%d]\n", rc);
213
blob_size_tmp = key_mod->blob_size;
214
memcpy(auth_tok->token.private_key.data, key_mod->blob,
217
if (blob_size != blob_size_tmp) {
219
syslog(LOG_ERR, "BUG: blob_size != blob_size_tmp; key module "
220
"is having a hard time getting the two to match between "
221
"get_blob() calls, and this has probably led to memory "
222
"corruption. Bombing out.\n");
226
if ((rc = (key_mod->ops->get_key_data)
227
(NULL, &key_data_len, auth_tok->token.private_key.data))) {
228
syslog(LOG_ERR, "Call into key module's get_key_data failed; "
232
if (key_data_len == 0) {
233
if ((rc = (key_mod->ops->get_key_sig)(
235
auth_tok->token.private_key.data))) {
236
syslog(LOG_ERR, "Call into key module's get_key_sig "
237
"failed; rc = [%d]\n", rc);
241
if ((key_data = malloc(key_data_len)) == NULL) {
245
if ((rc = (key_mod->ops->get_key_data)
246
(key_data, &key_data_len,
247
auth_tok->token.private_key.data))) {
248
syslog(LOG_ERR, "Call into key module's get_key_data "
249
"failed; rc = [%d]\n", rc);
252
if ((rc = ecryptfs_generate_sig_from_key_data(
253
sig, key_data, key_data_len))) {
254
syslog(LOG_ERR, "Error attempting to generate "
255
"signature from key data; rc = [%d]\n", rc);
258
if (sig[0] == '\0') {
259
if ((rc = (key_mod->ops->get_key_sig)(
261
auth_tok->token.private_key.data))) {
262
syslog(LOG_ERR, "Call into key module's "
263
"get_key_sig failed; rc = [%d]\n", rc);
268
strncpy(auth_tok->token.private_key.key_mod_alias, key_mod->alias,
269
ECRYPTFS_MAX_KEY_MOD_NAME_BYTES);
270
/* TODO: Get rid of this */
271
auth_tok->token.private_key.key_size = ECRYPTFS_MAX_KEY_MOD_NAME_BYTES;
272
auth_tok->token.private_key.data_len = blob_size;
273
memcpy(auth_tok->token.private_key.signature, sig,
274
ECRYPTFS_SIG_SIZE_HEX);
275
auth_tok->token.private_key.signature[ECRYPTFS_SIG_SIZE_HEX] = '\0';
280
int ecryptfs_mount(char *source, char *target, unsigned long flags, char *opts)
282
FILE *mtab_fd = NULL;
283
struct mntent mountent;
284
char cwd[MAX_PATH_SIZE];
286
char *fullpath_source = NULL;
287
char *fullpath_target = NULL;
291
mountent.mnt_opts = NULL;
294
syslog(LOG_ERR, "Invalid source directory\n");
299
syslog(LOG_ERR, "Invalid target directory\n");
302
if (strlen(opts) > 200) {
304
syslog(LOG_ERR, "Invalid mount options length\n");
307
if (mount(source, target, "ecryptfs", flags, opts)) {
309
syslog(LOG_ERR, "Failed to perform eCryptfs mount: "
310
"[%s]\n", strerror(errno));
313
mtab_fd = setmntent("/etc/mtab", "a");
316
syslog(LOG_ERR, "Failed to update the mount table\n");
319
cwdptr = getcwd(cwd, MAX_PATH_SIZE);
322
syslog(LOG_ERR, "Failed to get the current working directory; "
323
"errno = [%d]\n", errno);
326
if (source[0] != '/') {
327
rc = asprintf(&fullpath_source, "%s%s", cwd, source);
329
rc = asprintf(&fullpath_source, "%s", source);
332
fullpath_source = NULL;
333
syslog(LOG_ERR, "Out of memory\n");
336
if (target[0] != '/') {
337
rc = asprintf(&fullpath_target, "%s%s", cwd, target);
339
rc = asprintf(&fullpath_target, "%s", target);
342
fullpath_target = NULL;
343
syslog(LOG_ERR, "Out of memory\n");
347
i = strlen(fullpath_source);
348
if (i > 1 && fullpath_source[i - 1] == '/')
349
fullpath_source[i - 1] = '\0';
350
i = strlen(fullpath_target);
351
if (i > 1 && fullpath_target[i - 1] == '/')
352
fullpath_target[i - 1] = '\0';
353
mountent.mnt_fsname = fullpath_source;
354
mountent.mnt_dir = fullpath_target;
355
mountent.mnt_type = "ecryptfs";
356
/* we need the following byte count:
358
* 23 max for strings below
361
mountent.mnt_opts = malloc(224);
362
if (!mountent.mnt_opts) {
364
syslog(LOG_ERR, "Failed to allocate memory for mount "
368
memset(mountent.mnt_opts, 0, 224);
369
/* reporting the right mount opts */
370
if (flags & MS_RDONLY)
371
strcat(mountent.mnt_opts,"ro");
373
strcat(mountent.mnt_opts,"rw");
374
if (flags & MS_NOEXEC)
375
strcat(mountent.mnt_opts,",noexec");
376
if (flags & MS_NOSUID)
377
strcat(mountent.mnt_opts,",nosuid");
378
if (flags & MS_NODEV)
379
strcat(mountent.mnt_opts,",nodev");
381
strcat(mountent.mnt_opts, ",");
382
strcat(mountent.mnt_opts, opts);
384
mountent.mnt_freq = 0;
385
mountent.mnt_passno = 0;
386
if (addmntent(mtab_fd, &mountent)) {
388
syslog(LOG_ERR, "Failed to write to the mount "
394
free(fullpath_source);
395
free(fullpath_target);
396
free(mountent.mnt_opts);
402
static int zombie_semaphore_get(void)
405
struct semid_ds semid_ds;
410
sem_id = semget(ECRYPTFS_SEM_KEY, 1, (0666 | IPC_EXCL | IPC_CREAT));
416
rc = semop(sem_id, &sb, 1);
418
semctl(sem_id, 0, IPC_RMID);
419
syslog(LOG_ERR, "Error initializing semaphore\n");
423
} else if (errno == EEXIST) {
426
sem_id = semget(ECRYPTFS_SEM_KEY, 1, 0);
428
syslog(LOG_ERR, "Error getting existing semaphore");
432
#define RETRY_LIMIT 3
433
for (i = 0; i < RETRY_LIMIT; i++) {
434
semctl(sem_id, 0, IPC_STAT, &semid_ds);
435
if (semid_ds.sem_otime != 0) {
442
syslog(LOG_ERR, "Waited too long for initialized "
443
"semaphore; something's wrong\n");
448
syslog(LOG_ERR, "Error attempting to get semaphore\n");
457
static void zombie_semaphore_lock(int sem_id)
465
sb.sem_flg = IPC_NOWAIT;
466
for (i = 0; i < RETRY_LIMIT; i++) {
467
rc = semop(sem_id, &sb, 1);
468
if (rc == -1 && errno == EAGAIN) {
470
} else if (rc == -1) {
471
syslog(LOG_ERR, "Error locking semaphore; errno "
472
"string = [%m]\n", errno);
477
syslog(LOG_ERR, "Error locking semaphore; hit max retries\n");
482
static void zombie_semaphore_unlock(int sem_id)
490
rc = semop(sem_id, &sb, 1);
492
syslog(LOG_ERR, "Error unlocking semaphore\n");
499
static int get_zombie_shared_mem_locked(int *shm_id, int *sem_id)
503
(*sem_id) = zombie_semaphore_get();
504
if ((*sem_id) == -1) {
505
syslog(LOG_ERR, "Error attempting to get zombie semaphore\n");
509
zombie_semaphore_lock((*sem_id));
510
rc = shmget(ECRYPTFS_SHM_KEY, ECRYPTFS_SHM_SIZE, (0666 | IPC_CREAT
512
if (rc == -1 && errno == EEXIST)
513
rc = shmget(ECRYPTFS_SHM_KEY, ECRYPTFS_SHM_SIZE, 0);
518
shm_virt = shmat((*shm_id), NULL, 0);
519
if (shm_virt == (void *)-1) {
520
syslog(LOG_ERR, "Error attaching to newly allocated "
521
"shared memory; errno string = [%m]\n", errno);
523
zombie_semaphore_unlock((*sem_id));
526
memset(shm_virt, 0, ECRYPTFS_SHM_SIZE);
527
if ((rc = shmdt(shm_virt))) {
529
zombie_semaphore_unlock((*sem_id));
532
rc = shmget(ECRYPTFS_SHM_KEY, ECRYPTFS_SHM_SIZE, 0);
535
syslog(LOG_ERR, "Error attempting to get identifier for "
536
"shared memory with key [0x.8x]\n", ECRYPTFS_SHM_KEY);
538
zombie_semaphore_unlock((*sem_id));
547
static int list_pid_sid_pairs(int shm_id)
555
if (sizeof(pid_t) != sizeof(uint32_t)) {
556
syslog(LOG_ERR, "sizeof(pid_t) != sizeof(uint32_t); the code "
557
"needs some tweaking to work on this architecture\n");
561
shm_virt = shmat(shm_id, NULL, 0);
562
if (shm_virt == (void *)-1) {
567
memcpy(&sid_tmp, &shm_virt[i], sizeof(pid_t));
569
sid_tmp = ntohl(sid_tmp); /* uint32_t */
570
memcpy(&pid_tmp, &shm_virt[i], sizeof(pid_t));
572
pid_tmp = ntohl(pid_tmp); /* uint32_t */
573
while (!(sid_tmp == 0 && pid_tmp == 0)) {
574
if ((i + (2 * sizeof(pid_t))) > ECRYPTFS_SHM_SIZE)
576
memcpy(&sid_tmp, &shm_virt[i], sizeof(pid_t));
578
sid_tmp = ntohl(sid_tmp); /* uint32_t */
579
memcpy(&pid_tmp, &shm_virt[i], sizeof(pid_t));
581
pid_tmp = ntohl(pid_tmp); /* uint32_t */
583
if ((rc = shmdt(shm_virt)))
589
static int find_pid_for_this_sid(pid_t *pid, int shm_id)
600
if (sizeof(pid_t) != sizeof(uint32_t)) {
601
syslog(LOG_ERR, "sizeof(pid_t) != sizeof(uint32_t); the code "
602
"needs some tweaking to work on this architecture\n");
606
shm_virt = shmat(shm_id, NULL, 0);
607
if (shm_virt == (void *)-1) {
612
memcpy(&sid_tmp, &shm_virt[i], sizeof(pid_t));
614
sid_tmp = ntohl(sid_tmp); /* uint32_t */
615
memcpy(&pid_tmp, &shm_virt[i], sizeof(pid_t));
617
pid_tmp = ntohl(pid_tmp); /* uint32_t */
619
sid = getsid(this_pid);
620
while (!(sid_tmp == 0 && pid_tmp == 0)) {
621
if (sid_tmp == sid) {
625
if ((i + (2 * sizeof(pid_t))) > ECRYPTFS_SHM_SIZE)
627
memcpy(&sid_tmp, &shm_virt[i], sizeof(pid_t));
629
sid_tmp = ntohl(sid_tmp); /* uint32_t */
630
memcpy(&pid_tmp, &shm_virt[i], sizeof(pid_t));
632
pid_tmp = ntohl(pid_tmp); /* uint32_t */
635
if ((rc = shmdt(shm_virt))) {
643
static int remove_pid_for_this_sid(int shm_id)
655
if (sizeof(pid_t) != sizeof(uint32_t)) {
656
syslog(LOG_ERR, "sizeof(pid_t) != sizeof(uint32_t); the code "
657
"needs some tweaking to work on this architecture\n");
661
shm_virt = shmat(shm_id, NULL, 0);
662
if (shm_virt == (void *)-1) {
667
memcpy(&sid_tmp, &shm_virt[i], sizeof(pid_t));
669
sid_tmp = ntohl(sid_tmp); /* uint32_t */
670
memcpy(&pid_tmp, &shm_virt[i], sizeof(pid_t));
672
pid_tmp = ntohl(pid_tmp); /* uint32_t */
674
sid = getsid(this_pid);
675
while (!(sid_tmp == 0 && pid_tmp == 0)) {
676
if (sid_tmp == sid) {
680
if ((i + (2 * sizeof(pid_t))) > ECRYPTFS_SHM_SIZE)
682
memcpy(&sid_tmp, &shm_virt[i], sizeof(pid_t));
684
sid_tmp = ntohl(sid_tmp); /* uint32_t */
685
memcpy(&pid_tmp, &shm_virt[i], sizeof(pid_t));
687
pid_tmp = ntohl(pid_tmp); /* uint32_t */
691
int remainder = (ECRYPTFS_SHM_SIZE - i);
693
if (remainder != 0) {
694
if ((tmp = malloc(remainder)) == NULL) {
699
memcpy(tmp, &shm_virt[i], remainder);
700
i -= (2 * sizeof(pid_t));
701
memcpy(&shm_virt[i], tmp, remainder);
704
i -= (2 * sizeof(pid_t));
705
memset(&shm_virt[i], 0, (2 * sizeof(pid_t)));
709
if ((rc = shmdt(shm_virt)))
715
static int add_sid_pid_pair_to_shm(int shm_id)
725
if (sizeof(pid_t) != sizeof(uint32_t)) {
726
syslog(LOG_ERR, "sizeof(pid_t) != sizeof(uint32_t); the code "
727
"needs some tweaking to work on this architecture\n");
731
shm_virt = shmat(shm_id, NULL, 0);
732
if (shm_virt == (void *)-1) {
733
syslog(LOG_ERR, "Error attaching to shared memory; error "
734
"string = [%m]\n", errno);
735
shm_virt = shmat(shm_id, NULL, 0);
736
if (shm_virt == (void *)-1) {
737
syslog(LOG_ERR, "Error attaching to shared memory; error "
738
"string = [%m]\n", errno);
746
memcpy(&sid_tmp, &shm_virt[i], sizeof(pid_t));
748
sid_tmp = ntohl(sid_tmp); /* uint32_t */
749
memcpy(&pid_tmp, &shm_virt[i], sizeof(pid_t));
751
pid_tmp = ntohl(pid_tmp); /* uint32_t */
752
while (!(sid_tmp == 0 && pid_tmp == 0)) {
753
if ((i + (2 * sizeof(pid_t))) > ECRYPTFS_SHM_SIZE) {
755
"No space left in shared memory region\n");
760
memcpy(&sid_tmp, &shm_virt[i], sizeof(pid_t));
762
sid_tmp = ntohl(sid_tmp); /* uint32_t */
763
memcpy(&pid_tmp, &shm_virt[i], sizeof(pid_t));
765
pid_tmp = ntohl(pid_tmp); /* uint32_t */
771
i -= (2 * sizeof(pid_t));
772
memcpy(&shm_virt[i], &sid, sizeof(pid_t));
774
memcpy(&shm_virt[i], &pid, sizeof(pid_t));
776
if ((i + (2 * sizeof(pid_t))) <= ECRYPTFS_SHM_SIZE)
777
memset(&shm_virt[i], 0, (i + (2 * sizeof(pid_t))));
778
if ((rc = shmdt(shm_virt))) {
779
syslog(LOG_ERR, "Error detaching from shared memory\n");
786
int ecryptfs_set_zombie_session_placeholder(void)
792
if ((rc = get_zombie_shared_mem_locked(&shm_id, &sem_id))) {
794
"Error getting shared memory segment\n");
797
if ((rc = add_sid_pid_pair_to_shm(shm_id))) {
798
syslog(LOG_ERR, "Error adding sid/pid pair to shared memory "
799
"segment; rc = [%d]\n", rc);
800
zombie_semaphore_unlock(sem_id);
803
zombie_semaphore_unlock(sem_id);
804
sleep(ECRYPTFS_ZOMBIE_SLEEP_SECONDS);
805
if ((rc = get_zombie_shared_mem_locked(&shm_id, &sem_id))) {
807
"Error getting shared memory segment\n");
810
if ((rc = remove_pid_for_this_sid(shm_id))) {
811
syslog(LOG_ERR, "Error attempting to remove pid/sid "
812
"pair from shared memory segment; rc = [%d]\n",
814
zombie_semaphore_unlock(sem_id);
817
zombie_semaphore_unlock(sem_id);
823
int ecryptfs_kill_and_clear_zombie_session_placeholder(void)
830
if ((rc = get_zombie_shared_mem_locked(&shm_id, &sem_id))) {
831
syslog(LOG_ERR, "Error getting shared memory segment\n");
834
if ((rc = find_pid_for_this_sid(&pid, shm_id))) {
835
syslog(LOG_ERR, "Error finding pid for sid in shared memory "
836
"segment; rc = [%d]\n", rc);
837
zombie_semaphore_unlock(sem_id);
841
syslog(LOG_WARNING, "No valid pid found for this sid\n");
843
if ((rc = kill(pid, SIGKILL))) {
844
syslog(LOG_ERR, "Error attempting to kill process "
845
"[%d]; rc = [%d]; errno string = [%m]\n", pid,
848
if ((rc = remove_pid_for_this_sid(shm_id))) {
849
syslog(LOG_ERR, "Error attempting to remove pid/sid "
850
"pair from shared memory segment; rc = [%d]\n",
852
zombie_semaphore_unlock(sem_id);
856
zombie_semaphore_unlock(sem_id);
861
int ecryptfs_list_zombie_session_placeholders(void)
867
if ((rc = get_zombie_shared_mem_locked(&shm_id, &sem_id))) {
869
"Error getting shared memory segment\n");
872
if ((rc = list_pid_sid_pairs(shm_id))) {
873
syslog(LOG_ERR, "Error listing sid/pid pairs in shared memory "
874
"segment; rc = [%d]\n", rc);
875
zombie_semaphore_unlock(sem_id);
878
zombie_semaphore_unlock(sem_id);
883
static struct ecryptfs_ctx_ops ctx_ops;
885
struct ecryptfs_ctx_ops *cryptfs_get_ctx_opts (void)