~ecryptfs/ecryptfs/trunk

« back to all changes in this revision

Viewing changes to src/libecryptfs/key_management.c

  • Committer: mhalcrow@us.ibm.com
  • Date: 2007-11-06 22:56:01 UTC
  • Revision ID: git-v1:f8357de9d554b274497b5cce9db4347254b7e7eb
Initial import of eCryptfs filesystem userspace utilities (mount helper, daemon component,
etc.)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * Copyright (C) 2006 International Business Machines
 
3
 * Author(s): Michael C. Thompson <mcthomps@us.ibm.com>
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or
 
6
 * modify it under the terms of the GNU General Public License as
 
7
 * published by the Free Software Foundation; either version 2 of the
 
8
 * License, or (at your option) any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful, but
 
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
 * General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program; if not, write to the Free Software
 
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 
18
 * 02111-1307, USA.
 
19
 */
 
20
 
 
21
#include <errno.h>
 
22
#include <gcrypt.h>
 
23
#include <keyutils.h>
 
24
#ifndef S_SPLINT_S
 
25
#include <stdio.h>
 
26
#endif
 
27
#include <stdlib.h>
 
28
#include <string.h>
 
29
#include <syslog.h>
 
30
#include <fcntl.h>
 
31
#include <unistd.h>
 
32
#include <arpa/inet.h>
 
33
#include <sys/mman.h>
 
34
#include <sys/types.h>
 
35
#include <sys/stat.h>
 
36
#include "config.h"
 
37
#include "../include/ecryptfs.h"
 
38
 
 
39
#ifndef ENOKEY
 
40
#warning ENOKEY is not defined in your errno.h; setting it to 126
 
41
#define ENOKEY 126
 
42
#endif
 
43
 
 
44
/**
 
45
 * This is the common functionality used to put a password generated key into
 
46
 * the keyring, shared by both non-interactive and interactive signature
 
47
 * generation code.
 
48
 *
 
49
 * Returns 0 on add, 1 on pre-existed, negative on failure.
 
50
 */
 
51
int ecryptfs_add_passphrase_key_to_keyring(char *auth_tok_sig, char *passphrase,
 
52
                                           char *salt)
 
53
{
 
54
        int rc;
 
55
        char session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES];
 
56
        struct ecryptfs_auth_tok *auth_tok = NULL;
 
57
 
 
58
        if ((rc = generate_passphrase_sig(auth_tok_sig, passphrase, salt,
 
59
                                          session_key_encryption_key))) {
 
60
                syslog(LOG_ERR, "Error generating passphrase signature; "
 
61
                       "rc = [%d]\n", rc);
 
62
                rc = (rc < 0) ? rc : rc * -1;
 
63
                goto out;
 
64
        }
 
65
        rc = (int)keyctl_search(KEY_SPEC_USER_KEYRING, "user", auth_tok_sig, 0);
 
66
        if (rc != -1) { /* we already have this key in keyring; we're done */
 
67
                rc = 1;
 
68
                syslog(LOG_WARNING, "Passphrase key already in keyring\n", rc);
 
69
                goto out;
 
70
        } else if ((rc == -1) && (errno != ENOKEY)) {
 
71
                int errnum = errno;
 
72
 
 
73
                syslog(LOG_ERR, "keyctl_search failed: %s errno=[%d]\n",
 
74
                       strerror(errnum), errnum);
 
75
                rc = (errnum < 0) ? errnum : errnum * -1;
 
76
                goto out;
 
77
        }
 
78
        auth_tok = malloc(sizeof(struct ecryptfs_auth_tok));
 
79
        if (!auth_tok) {
 
80
                syslog(LOG_ERR, "Unable to allocate memory for auth_tok\n");
 
81
                rc = -ENOMEM;
 
82
                goto out;
 
83
        }
 
84
        if ((rc = generate_payload(auth_tok, auth_tok_sig, salt,
 
85
                                   session_key_encryption_key))) {
 
86
                syslog(LOG_ERR, "Error generating payload for auth tok key; "
 
87
                       "rc = [%d]\n", rc);
 
88
                rc = (rc < 0) ? rc : rc * -1;
 
89
                goto out_wipe;
 
90
        }
 
91
        rc = add_key("user", auth_tok_sig, (void *)auth_tok,
 
92
                     sizeof(struct ecryptfs_auth_tok), KEY_SPEC_USER_KEYRING);
 
93
        if (rc == -1) {
 
94
                int errnum = errno;
 
95
 
 
96
                syslog(LOG_ERR, "Error adding key with sig [%s]; rc = [%d] "
 
97
                       "\%s\"\n", auth_tok_sig, rc, strerror(errnum));
 
98
                rc = (errnum < 0) ? errnum : errnum * -1;
 
99
                goto out_wipe;
 
100
        }
 
101
        rc = 0;
 
102
out_wipe:
 
103
        memset(auth_tok, 0, sizeof(auth_tok));
 
104
out:
 
105
        free(auth_tok);
 
106
        return rc;
 
107
}
 
108
 
 
109
int ecryptfs_wrap_passphrase(char *filename, char *wrapping_passphrase,
 
110
                             char *wrapping_salt, char *decrypted_passphrase)
 
111
{
 
112
        char wrapping_auth_tok_sig[ECRYPTFS_SIG_SIZE_HEX + 1];
 
113
        char wrapping_key[ECRYPTFS_MAX_KEY_BYTES];
 
114
        char padded_decrypted_passphrase[ECRYPTFS_MAX_PASSPHRASE_BYTES + 1];
 
115
        char encrypted_passphrase[ECRYPTFS_MAX_PASSPHRASE_BYTES + 1];
 
116
        int encrypted_passphrase_pos = 0;
 
117
        int decrypted_passphrase_pos = 0;
 
118
        gcry_cipher_hd_t gcry_handle;
 
119
        gcry_error_t gcry_err;
 
120
        int encrypted_passphrase_bytes;
 
121
        int decrypted_passphrase_bytes;
 
122
        int fd;
 
123
        ssize_t size;
 
124
        int rc;
 
125
 
 
126
        decrypted_passphrase_bytes = strlen(decrypted_passphrase);
 
127
        if (decrypted_passphrase_bytes > ECRYPTFS_MAX_PASSPHRASE_BYTES) {
 
128
                syslog(LOG_ERR, "Decrypted passphrase is [%d] bytes long; "
 
129
                       "[%d] is the max\n", decrypted_passphrase_bytes,
 
130
                       ECRYPTFS_MAX_PASSPHRASE_BYTES);
 
131
                rc = -EIO;
 
132
                goto out;
 
133
        }
 
134
        if ((rc = generate_passphrase_sig(wrapping_auth_tok_sig,
 
135
                                          wrapping_passphrase, wrapping_salt,
 
136
                                          wrapping_key))) {
 
137
                syslog(LOG_ERR, "Error generating passphrase signature; "
 
138
                       "rc = [%d]\n", rc);
 
139
                rc = (rc < 0) ? rc : rc * -1;
 
140
                goto out;
 
141
        }
 
142
        memset(padded_decrypted_passphrase, 0,
 
143
               (ECRYPTFS_MAX_PASSPHRASE_BYTES + 1));
 
144
        memcpy(padded_decrypted_passphrase, decrypted_passphrase,
 
145
               decrypted_passphrase_bytes);
 
146
        if ((decrypted_passphrase_bytes % ECRYPTFS_AES_BLOCK_SIZE) != 0)
 
147
                decrypted_passphrase_bytes += (ECRYPTFS_AES_BLOCK_SIZE
 
148
                                               - (decrypted_passphrase_bytes
 
149
                                                  % ECRYPTFS_AES_BLOCK_SIZE));
 
150
        encrypted_passphrase_bytes = decrypted_passphrase_bytes;
 
151
        if ((gcry_err = gcry_cipher_open(&gcry_handle, GCRY_CIPHER_AES,
 
152
                                         GCRY_CIPHER_MODE_ECB, 0))) {
 
153
                syslog(LOG_ERR, "Error attempting to initialize AES cipher; "
 
154
                       "gcry_error_t = [%d]\n", gcry_err);
 
155
                rc = -EIO;
 
156
                goto out;
 
157
        }
 
158
        if ((gcry_err = gcry_cipher_setkey(gcry_handle, wrapping_key,
 
159
                                           ECRYPTFS_AES_KEY_BYTES))) {
 
160
                syslog(LOG_ERR, "Error attempting to set AES key; "
 
161
                       "gcry_error_t = [%d]\n", gcry_err);
 
162
                rc = -EIO;
 
163
                gcry_cipher_close(gcry_handle);
 
164
                goto out;
 
165
        }
 
166
        while (decrypted_passphrase_bytes > 0) {
 
167
                if ((gcry_err = gcry_cipher_encrypt(
 
168
                             gcry_handle,
 
169
                             &encrypted_passphrase[encrypted_passphrase_pos],
 
170
                             ECRYPTFS_AES_BLOCK_SIZE,
 
171
                             &decrypted_passphrase[decrypted_passphrase_pos],
 
172
                             ECRYPTFS_AES_BLOCK_SIZE))) {
 
173
                        syslog(LOG_ERR, "Error attempting to encrypt block; "
 
174
                               "gcry_error = [%d]\n", gcry_err);
 
175
                        rc = -EIO;
 
176
                        gcry_cipher_close(gcry_handle);
 
177
                        goto out;
 
178
                }
 
179
                encrypted_passphrase_pos += ECRYPTFS_AES_BLOCK_SIZE;
 
180
                decrypted_passphrase_pos += ECRYPTFS_AES_BLOCK_SIZE;
 
181
                decrypted_passphrase_bytes -= ECRYPTFS_AES_BLOCK_SIZE;
 
182
        }
 
183
        gcry_cipher_close(gcry_handle);
 
184
        unlink(filename);
 
185
        if ((fd = open(filename, (O_WRONLY | O_CREAT | O_EXCL),
 
186
                       (S_IRUSR | S_IWUSR))) == -1) {
 
187
                syslog(LOG_ERR, "Error attempting to open [%s] for writing\n",
 
188
                       filename);
 
189
                rc = -EIO;
 
190
                goto out;
 
191
        }
 
192
        if ((size = write(fd, wrapping_auth_tok_sig,
 
193
                          ECRYPTFS_SIG_SIZE_HEX)) <= 0) {
 
194
                syslog(LOG_ERR, "Error attempting to write encrypted "
 
195
                       "passphrase ([%d] bytes) to file [%s]; size = [%d]\n",
 
196
                       encrypted_passphrase_bytes, filename, size);
 
197
                rc = -EIO;
 
198
                close(fd);
 
199
                goto out;
 
200
        }
 
201
        if ((size = write(fd, encrypted_passphrase,
 
202
                          encrypted_passphrase_bytes)) <= 0) {
 
203
                syslog(LOG_ERR, "Error attempting to write encrypted "
 
204
                       "passphrase ([%d] bytes) to file [%s]; size = [%d]\n",
 
205
                       encrypted_passphrase_bytes, filename, size);
 
206
                rc = -EIO;
 
207
                close(fd);
 
208
                goto out;
 
209
        }
 
210
        close(fd);
 
211
        rc = 0;
 
212
out:
 
213
        return rc;
 
214
}
 
215
 
 
216
/**
 
217
 * decryptfs_passphrase must be able to hold
 
218
 * ECRYPTFS_MAX_PASSPHRASE_BYTES + 1 bytes
 
219
 */
 
220
int ecryptfs_unwrap_passphrase(char *decrypted_passphrase, char *filename,
 
221
                               char *wrapping_passphrase, char *wrapping_salt)
 
222
{
 
223
        char wrapping_auth_tok_sig[ECRYPTFS_SIG_SIZE_HEX + 1];
 
224
        char wrapping_auth_tok_sig_from_file[ECRYPTFS_SIG_SIZE_HEX + 1];
 
225
        char wrapping_key[ECRYPTFS_MAX_KEY_BYTES];
 
226
        char encrypted_passphrase[ECRYPTFS_MAX_PASSPHRASE_BYTES + 1];
 
227
        int encrypted_passphrase_pos = 0;
 
228
        int decrypted_passphrase_pos = 0;
 
229
        gcry_cipher_hd_t gcry_handle;
 
230
        gcry_error_t gcry_err;
 
231
        int encrypted_passphrase_bytes;
 
232
        int fd;
 
233
        ssize_t size;
 
234
        int rc;
 
235
 
 
236
        if ((rc = generate_passphrase_sig(wrapping_auth_tok_sig,
 
237
                                          wrapping_passphrase, wrapping_salt,
 
238
                                          wrapping_key))) {
 
239
                syslog(LOG_ERR, "Error generating passphrase signature; "
 
240
                       "rc = [%d]\n", rc);
 
241
                rc = (rc < 0) ? rc : rc * -1;
 
242
                goto out;
 
243
        }
 
244
        if ((fd = open(filename, O_RDONLY)) == -1) {
 
245
                syslog(LOG_ERR, "Error attempting to open [%s] for reading\n",
 
246
                       filename);
 
247
                rc = -EIO;
 
248
                goto out;
 
249
        }
 
250
        if ((size = read(fd, wrapping_auth_tok_sig_from_file,
 
251
                         ECRYPTFS_SIG_SIZE_HEX)) <= 0) {
 
252
                syslog(LOG_ERR, "Error attempting to read encrypted "
 
253
                       "passphrase from file [%s]; size = [%d]\n",
 
254
                       filename, size);
 
255
                rc = -EIO;
 
256
                close(fd);
 
257
                goto out;
 
258
        }
 
259
        if ((size = read(fd, encrypted_passphrase,
 
260
                         ECRYPTFS_MAX_PASSPHRASE_BYTES)) <= 0) {
 
261
                syslog(LOG_ERR, "Error attempting to read encrypted "
 
262
                       "passphrase from file [%s]; size = [%d]\n",
 
263
                       filename, size);
 
264
                rc = -EIO;
 
265
                close(fd);
 
266
                goto out;
 
267
        }
 
268
        close(fd);
 
269
        if (memcmp(wrapping_auth_tok_sig_from_file, wrapping_auth_tok_sig,
 
270
                   ECRYPTFS_SIG_SIZE_HEX) != 0) {
 
271
                syslog(LOG_ERR, "Incorrect wrapping key for file [%s]\n",
 
272
                       filename);
 
273
                rc = -EIO;
 
274
                goto out;
 
275
        }
 
276
        encrypted_passphrase_bytes = size;
 
277
        if ((gcry_err = gcry_cipher_open(&gcry_handle, GCRY_CIPHER_AES,
 
278
                                         GCRY_CIPHER_MODE_ECB, 0))) {
 
279
                syslog(LOG_ERR, "Error attempting to initialize AES cipher; "
 
280
                       "gcry_error_t = [%d]\n", gcry_err);
 
281
                rc = -EIO;
 
282
                goto out;
 
283
        }
 
284
        if ((gcry_err = gcry_cipher_setkey(gcry_handle, wrapping_key,
 
285
                                           ECRYPTFS_AES_KEY_BYTES))) {
 
286
                syslog(LOG_ERR, "Error attempting to set AES key; "
 
287
                       "gcry_error_t = [%d]\n", gcry_err);
 
288
                rc = -EIO;
 
289
                gcry_cipher_close(gcry_handle);
 
290
                goto out;
 
291
        }
 
292
        memset(decrypted_passphrase, 0, ECRYPTFS_MAX_PASSPHRASE_BYTES + 1);
 
293
        while (encrypted_passphrase_bytes > 0) {
 
294
                if ((gcry_err = gcry_cipher_decrypt(
 
295
                             gcry_handle,
 
296
                             &decrypted_passphrase[encrypted_passphrase_pos],
 
297
                             ECRYPTFS_AES_BLOCK_SIZE,
 
298
                             &encrypted_passphrase[decrypted_passphrase_pos],
 
299
                             ECRYPTFS_AES_BLOCK_SIZE))) {
 
300
                        syslog(LOG_ERR, "Error attempting to decrypt block; "
 
301
                               "gcry_error = [%d]\n", gcry_err);
 
302
                        rc = -EIO;
 
303
                        gcry_cipher_close(gcry_handle);
 
304
                        goto out;
 
305
                }
 
306
                encrypted_passphrase_pos += ECRYPTFS_AES_BLOCK_SIZE;
 
307
                decrypted_passphrase_pos += ECRYPTFS_AES_BLOCK_SIZE;
 
308
                encrypted_passphrase_bytes -= ECRYPTFS_AES_BLOCK_SIZE;
 
309
        }
 
310
out:
 
311
        return rc;
 
312
}
 
313
 
 
314
/**
 
315
 * ecryptfs_insert_wrapped_passphrase_into_keyring()
 
316
 *
 
317
 * Inserts two auth_tok objects into the user session keyring: a
 
318
 * wrapping passphrase auth_tok and the unwrapped passphrase auth_tok.
 
319
 *
 
320
 * Returns the signature of the wrapped passphrase that is inserted
 
321
 * into the user session keyring.
 
322
 */
 
323
int ecryptfs_insert_wrapped_passphrase_into_keyring(
 
324
        char *auth_tok_sig, char *filename, char *wrapping_passphrase,
 
325
        char *salt)
 
326
{
 
327
        char decrypted_passphrase[ECRYPTFS_MAX_PASSPHRASE_BYTES + 1] ;
 
328
        int rc;
 
329
 
 
330
        if ((rc = ecryptfs_unwrap_passphrase(decrypted_passphrase, filename,
 
331
                                             wrapping_passphrase, salt))) {
 
332
                syslog(LOG_ERR, "Error attempting to unwrap passphrase from "
 
333
                       "file [%s]; rc = [%d]\n", filename, rc);
 
334
                rc = -EIO;
 
335
                goto out;
 
336
        }
 
337
        if ((rc = ecryptfs_add_passphrase_key_to_keyring(auth_tok_sig,
 
338
                                                         decrypted_passphrase,
 
339
                                                         salt))) {
 
340
                syslog(LOG_ERR, "Error attempting to add passphrase key to "
 
341
                       "user session keyring; rc = [%d]\n", rc);
 
342
                goto out;
 
343
        }
 
344
out:
 
345
        return rc;
 
346
}
 
347
 
 
348
/**
 
349
 * ecryptfs_add_key_module_key_to_keyring
 
350
 * @auth_tok_sig: (ECRYPTFS_SIG_SIZE_HEX + 1) bytes of allocated
 
351
 *                memory into which this function will write the
 
352
 *                expanded-hex key signature for the given key
 
353
 *                module
 
354
 * @key_mod: Key module handle
 
355
 *
 
356
 * Inserts a key module key blob into the keyring, using the
 
357
 * auth_tok_sig as the key signature.
 
358
 *
 
359
 * Returns =0 on successful addition, =1 if the key is already in the
 
360
 * keyring, and <0 on failure.
 
361
 */
 
362
int
 
363
ecryptfs_add_key_module_key_to_keyring(char *auth_tok_sig,
 
364
                                       struct ecryptfs_key_mod *key_mod)
 
365
{
 
366
        size_t blob_size;
 
367
        struct ecryptfs_auth_tok *auth_tok;
 
368
        int rc;
 
369
 
 
370
        if (key_mod->blob == NULL) {
 
371
                if ((rc = (key_mod->ops->get_blob)(NULL, &blob_size,
 
372
                                                   key_mod->param_vals,
 
373
                                                   key_mod->num_param_vals))) {
 
374
                        syslog(LOG_ERR, "Error attempting to get blob from "
 
375
                               "key module; rc = [%d]\n", rc);
 
376
                        goto out;
 
377
                }
 
378
        } else {
 
379
                blob_size = key_mod->blob_size;
 
380
        }
 
381
        if ((auth_tok = malloc(sizeof(struct ecryptfs_auth_tok) + blob_size))
 
382
            == NULL) {
 
383
                rc = -ENOMEM;
 
384
                goto out;
 
385
        }
 
386
        if ((rc = ecryptfs_generate_key_payload(auth_tok, key_mod, auth_tok_sig,
 
387
                                                blob_size))) {
 
388
                syslog(LOG_ERR, "Error initializing key from module; "
 
389
                       "rc = [%d]\n", rc);
 
390
                goto out;
 
391
        }
 
392
        rc = (int)keyctl_search(KEY_SPEC_USER_KEYRING, "user", auth_tok_sig, 0);
 
393
        if (rc != -1) { /* we already have this key in keyring; we're done */
 
394
                rc = 1;
 
395
                goto out;
 
396
        }
 
397
        rc = add_key("user", auth_tok_sig, (void *)auth_tok,
 
398
                     (sizeof(struct ecryptfs_auth_tok) + blob_size),
 
399
                     KEY_SPEC_USER_KEYRING);
 
400
        if (rc < 0)
 
401
                syslog(LOG_ERR, "Error adding key with sig [%s]; rc ="
 
402
                       " [%d]\n", auth_tok_sig, rc);
 
403
        else rc = 0;
 
404
out:
 
405
        memset(auth_tok, 0, (sizeof(struct ecryptfs_auth_tok) + blob_size));
 
406
        free(auth_tok);
 
407
        return rc;
 
408
}
 
409
 
 
410
int ecryptfs_read_salt_hex_from_rc(char *salt_hex)
 
411
{
 
412
        struct ecryptfs_name_val_pair nvp_list_head;
 
413
        struct ecryptfs_name_val_pair *nvp;
 
414
        int rc;
 
415
 
 
416
        memset(&nvp_list_head, 0, sizeof(struct ecryptfs_name_val_pair));
 
417
        rc = ecryptfs_parse_rc_file(&nvp_list_head);
 
418
        if (rc) {
 
419
                syslog(LOG_WARNING, "Error attempting to parse .ecryptfsrc "
 
420
                       "file; rc = [%d]", rc);
 
421
                goto out;
 
422
        }
 
423
        nvp = &nvp_list_head;
 
424
        while (nvp) {
 
425
                if (strcmp(nvp->name, "salt") == 0) {
 
426
                        int valsize;
 
427
 
 
428
                        if (!nvp->value)
 
429
                                goto next_iteration;
 
430
                        valsize = strlen(nvp->value);
 
431
                        if (valsize != ECRYPTFS_SALT_SIZE_HEX);
 
432
                                goto next_iteration;
 
433
                        memcpy(salt_hex, nvp->value, ECRYPTFS_SALT_SIZE_HEX);
 
434
                        goto out_free;
 
435
                }
 
436
next_iteration:
 
437
                nvp = nvp->next;
 
438
        }
 
439
        rc = -EINVAL;
 
440
out_free:
 
441
        free_name_val_pairs(nvp_list_head.next);
 
442
out:
 
443
        return rc;
 
444
}
 
445
 
 
446
int ecryptfs_check_sig(char *auth_tok_sig, char *sig_cache_filename,
 
447
                       int *flags)
 
448
{
 
449
        int fd;
 
450
        char tmp[ECRYPTFS_SIG_SIZE_HEX + 1];
 
451
        ssize_t size;
 
452
        int rc = 0;
 
453
 
 
454
        (*flags) &= ~ECRYPTFS_SIG_FLAG_NOENT;
 
455
        fd = open(sig_cache_filename, O_RDONLY);
 
456
        if (fd == -1) {
 
457
                (*flags) |= ECRYPTFS_SIG_FLAG_NOENT;
 
458
                goto out;
 
459
        }
 
460
        while ((size = read(fd, tmp, (ECRYPTFS_SIG_SIZE_HEX + 1)))
 
461
               == (ECRYPTFS_SIG_SIZE_HEX + 1)) {
 
462
                if (memcmp(auth_tok_sig, tmp, ECRYPTFS_SIG_SIZE_HEX)
 
463
                    == 0) {
 
464
                        close(fd);
 
465
                        goto out;
 
466
                }
 
467
        }
 
468
        close(fd);
 
469
        (*flags) |= ECRYPTFS_SIG_FLAG_NOENT;
 
470
out:
 
471
        return rc;
 
472
}
 
473
 
 
474
int ecryptfs_append_sig(char *auth_tok_sig, char *sig_cache_filename)
 
475
{
 
476
        int fd;
 
477
        ssize_t size;
 
478
        char tmp[ECRYPTFS_SIG_SIZE_HEX + 1];
 
479
        int rc = 0;
 
480
 
 
481
        fd = open(sig_cache_filename, (O_WRONLY | O_CREAT),
 
482
                  (S_IRUSR | S_IWUSR));
 
483
        if (fd == -1) {
 
484
                syslog(LOG_ERR, "Open resulted in [%d]; [%s]\n", errno,
 
485
                       strerror(errno));
 
486
                rc = -EIO;
 
487
                goto out;
 
488
        }
 
489
        lseek(fd, 0, SEEK_END);
 
490
        memcpy(tmp, auth_tok_sig, ECRYPTFS_SIG_SIZE_HEX);
 
491
        tmp[ECRYPTFS_SIG_SIZE_HEX] = '\n';
 
492
        if ((size = write(fd, tmp, (ECRYPTFS_SIG_SIZE_HEX + 1))) !=
 
493
            (ECRYPTFS_SIG_SIZE_HEX + 1)) {
 
494
                syslog(LOG_ERR, "Write of sig resulted in [%d]; errno = [%d]; "
 
495
                       "[%s]\n", size, errno, strerror(errno));
 
496
                rc = -EIO;
 
497
                close(fd);
 
498
                goto out;
 
499
        }
 
500
        close(fd);
 
501
out:
 
502
        return rc;
 
503
}
 
504
 
 
505
int ecryptfs_validate_keyring(void)
 
506
{
 
507
        long rc_long;
 
508
        int rc = 0;
 
509
 
 
510
        if ((rc_long = keyctl(KEYCTL_LINK, KEY_SPEC_USER_KEYRING,
 
511
                              KEY_SPEC_SESSION_KEYRING))) {
 
512
                syslog(LOG_ERR, "Error attempting to link the user session "
 
513
                       "keyring into the session keyring\n");
 
514
                rc = -EIO;
 
515
                goto out;
 
516
        }
 
517
out:
 
518
        return rc;
 
519
}