~ecryptfs/ecryptfs/trunk

2 by mhalcrow@us.ibm.com
Initial import of eCryptfs filesystem userspace utilities (mount helper, daemon component,
1
/**
2
 * Copyright (C) 2006 International Business Machines
3
 * Author(s): Michael A. Halcrow <mhalcrow@us.ibm.com>
4
 * 	      Trevor Highland <trevor.highland@gmail.com>
5
 *
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.
10
 *
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.
15
 *
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
19
 * 02111-1307, USA.
20
 */
21
22
#include <errno.h>
23
#include <string.h>
24
#include <stdlib.h>
301 by Dustin Kirkland
make most of the code compatible with -Werror
25
#include <stdio.h>
801 by Tyler Hicks
Fix sign comparison warnings and other issues surrounding the uint32_t type
26
#include <stdint.h>
27
#include <inttypes.h>
2 by mhalcrow@us.ibm.com
Initial import of eCryptfs filesystem userspace utilities (mount helper, daemon component,
28
#include "../include/ecryptfs.h"
29
#include "../include/decision_graph.h"
30
31
static struct param_node key_module_select_node = {
32
	.num_mnt_opt_names = 1,
33
	.mnt_opt_names = {"key"},
34
	.prompt = "Select key type to use for newly created files",
35
	.val_type = VAL_STR,
36
	.val = NULL,
37
	.display_opts = NULL,
38
	.default_val = NULL,
39
	.flags = DISPLAY_TRANSITION_NODE_VALS | ECRYPTFS_PARAM_FLAG_ECHO_INPUT,
40
	.num_transitions = 0,
41
	.tl = {{0}}
42
};
43
44
/**
45
 * sig_param_node_callback
46
 *
47
 * The eCryptfs utilities may modify the decision graph
48
 * in-flight. This is one example of that happening.
49
 *
50
 * By default, root_param_node will pull a "sig=" option out of the
51
 * already-supplied name/value pair list and skip the key module
52
 * selection stage altogether. If there is no "sig=" option provided
53
 * in the list (condition: node->val == NULL), then change the
54
 * next_token transition node pointer to point to the key module
55
 * selection node.
56
 */
57
static int
58
sig_param_node_callback(struct ecryptfs_ctx *ctx, struct param_node *node,
59
			struct val_node **head, void **foo)
60
{
61
	char *param;
62
	int rc = 0;
63
64
	if (!node->val) {
65
		node->tl[0].next_token = &key_module_select_node;
66
		goto out;
67
	}
68
	if (strcmp(node->val, "NULL") == 0) {
69
		node->tl[0].next_token = &key_module_select_node;
70
		goto out;
71
	}
72
	rc = asprintf(&param, "ecryptfs_sig=%s", node->val);
73
	if (rc == -1) {
74
		rc = -ENOMEM;
75
		syslog(LOG_ERR, "Out of memory\n");
76
		goto out;
77
	}
342 by Dustin Kirkland
fix mount parameter handling
78
	rc = stack_push(head, param);
2 by mhalcrow@us.ibm.com
Initial import of eCryptfs filesystem userspace utilities (mount helper, daemon component,
79
out:
80
	return rc;
81
}
82
29 by mhalcrow@us.ibm.com
Make cipher and key bytes selection use the decision graph subsystem
83
static struct param_node ecryptfs_cipher_param_node;
2 by mhalcrow@us.ibm.com
Initial import of eCryptfs filesystem userspace utilities (mount helper, daemon component,
84
85
static struct param_node root_param_node = {
86
	.num_mnt_opt_names = 1,
87
	.mnt_opt_names = {"sig"},
88
	.prompt = "Existing key signature",
89
	.val_type = VAL_STR,
90
	.val = NULL,
91
	.display_opts = NULL,
92
	.default_val = "NULL",
41 by mike@halcrow.us
Support for implicit transitions
93
	.flags = ECRYPTFS_PARAM_FLAG_NO_VALUE | ECRYPTFS_NO_AUTO_TRANSITION,
2 by mhalcrow@us.ibm.com
Initial import of eCryptfs filesystem userspace utilities (mount helper, daemon component,
94
	.num_transitions = 1,
95
	.tl = {{.val = "default",
96
		.pretty_val = "default",
29 by mhalcrow@us.ibm.com
Make cipher and key bytes selection use the decision graph subsystem
97
		.next_token = &ecryptfs_cipher_param_node,
2 by mhalcrow@us.ibm.com
Initial import of eCryptfs filesystem userspace utilities (mount helper, daemon component,
98
		.trans_func = sig_param_node_callback}}
99
};
100
384.1.7 by Michal Hlavinka
module_mgr.c: reenable default values
101
/* returns: 
102
 * 	on_null for str == NULL
103
 *	1 for str=="yes" or "y"
104
 *	0 for str=="no" or "n"
105
 *	-1 elsewhere */
106
static int is_yes(const char *str, int on_null)
376.1.6 by Michal Hlavinka
module_mgr.c: insist on yes/no answer
107
{
108
	if (str) {
109
		if (!strcmp(str,"y") || !strcmp(str,"yes"))
110
			return 1;
111
		if (!strcmp(str,"no") || !strcmp(str,"n"))
112
			return 0;
384.1.7 by Michal Hlavinka
module_mgr.c: reenable default values
113
	} else
114
		return on_null;
376.1.6 by Michal Hlavinka
module_mgr.c: insist on yes/no answer
115
116
	return -1;
117
}
118
119
120
/* returns: 0 for success
121
 *	    WRONG_VALUE if node->val is none of  'yes','y','no','n'
122
 *	    <0 for error
123
 */
124
static int stack_push_if_yes(struct param_node *node, struct val_node **head,
125
			     char *opt_name)
126
{
127
	int rc;
128
384.1.7 by Michal Hlavinka
module_mgr.c: reenable default values
129
	if (((rc=is_yes(node->val, 0)) == 1) || (node->flags & PARAMETER_SET)) {
376.1.6 by Michal Hlavinka
module_mgr.c: insist on yes/no answer
130
		rc = stack_push(head, opt_name);
131
	} else if (rc == -1)
132
		rc = WRONG_VALUE;
133
	free(node->val);
134
	node->val = NULL;
135
	return rc;
136
}
137
56 by mhalcrow@us.ibm.com
Add HMAC mount option to mount helper.
138
static int get_hmac(struct ecryptfs_ctx *ctx, struct param_node *node,
139
		    struct val_node **head, void **foo)
140
{
376.1.6 by Michal Hlavinka
module_mgr.c: insist on yes/no answer
141
	return stack_push_if_yes(node, head, "ecryptfs_hmac");
56 by mhalcrow@us.ibm.com
Add HMAC mount option to mount helper.
142
}
143
2 by mhalcrow@us.ibm.com
Initial import of eCryptfs filesystem userspace utilities (mount helper, daemon component,
144
static int get_passthrough(struct ecryptfs_ctx *ctx, struct param_node *node,
145
			   struct val_node **head, void **foo)
146
{
376.1.6 by Michal Hlavinka
module_mgr.c: insist on yes/no answer
147
	return stack_push_if_yes(node, head, "ecryptfs_passthrough");
2 by mhalcrow@us.ibm.com
Initial import of eCryptfs filesystem userspace utilities (mount helper, daemon component,
148
}
149
150
static int get_xattr(struct ecryptfs_ctx *ctx, struct param_node *node,
151
			   struct val_node **head, void **foo)
152
{
376.1.6 by Michal Hlavinka
module_mgr.c: insist on yes/no answer
153
	return stack_push_if_yes(node, head, "ecryptfs_xattr_metadata");
2 by mhalcrow@us.ibm.com
Initial import of eCryptfs filesystem userspace utilities (mount helper, daemon component,
154
}
155
156
static int get_encrypted_passthrough(struct ecryptfs_ctx *ctx,
157
				     struct param_node *node,
158
				     struct val_node **head, void **foo)
159
{
376.1.6 by Michal Hlavinka
module_mgr.c: insist on yes/no answer
160
	return stack_push_if_yes(node, head, "ecryptfs_encrypted_view");
2 by mhalcrow@us.ibm.com
Initial import of eCryptfs filesystem userspace utilities (mount helper, daemon component,
161
}
162
196 by Mike Halcrow
Filename encryption option passes sanity check.
163
static struct param_node end_param_node = {
164
	.num_mnt_opt_names = 1,
165
	.mnt_opt_names = {"end"},
166
	.prompt = "end",
167
	.val_type = VAL_STR,
168
	.val = NULL,
169
	.display_opts = NULL,
170
	.default_val = NULL,
171
	.flags = ECRYPTFS_PARAM_FLAG_NO_VALUE,
172
	.num_transitions = 0,
173
	.tl = {{.val = "default",
174
		.pretty_val = "default",
175
		.next_token = NULL,
176
		.trans_func = NULL}}
177
};
178
179
static struct param_node enable_filename_crypto_param_node;
180
181
static int filename_crypto_fnek_sig_callback(struct ecryptfs_ctx *ctx,
182
					     struct param_node *node,
183
					     struct val_node **head, void **foo)
184
{
185
	char *param;
186
	int rc = 0;
187
188
	if (!node->val) {
189
		node->flags = ECRYPTFS_PARAM_FLAG_ECHO_INPUT;
190
		enable_filename_crypto_param_node.tl[0].next_token =
191
			node->tl[0].next_token;
192
		node->tl[0].next_token = &enable_filename_crypto_param_node;
193
		goto out;
194
	}
195
	if (strcmp(node->val, "NULL") == 0) {
196
		node->flags = ECRYPTFS_PARAM_FLAG_ECHO_INPUT;
197
		enable_filename_crypto_param_node.tl[0].next_token =
198
			node->tl[0].next_token;
199
		node->tl[0].next_token = &enable_filename_crypto_param_node;
200
		goto out;
201
	}
202
	rc = asprintf(&param, "ecryptfs_fnek_sig=%s", node->val);
203
	if (rc == -1) {
204
		rc = -ENOMEM;
205
		syslog(LOG_ERR, "Out of memory\n");
206
		goto out;
207
	}
342 by Dustin Kirkland
fix mount parameter handling
208
	rc = stack_push(head, param);
196 by Mike Halcrow
Filename encryption option passes sanity check.
209
out:
210
	return rc;
211
}
212
213
static struct param_node filename_crypto_fnek_sig_param_node = {
214
	.num_mnt_opt_names = 1,
215
	.mnt_opt_names = {"ecryptfs_fnek_sig"},
451 by Dustin Kirkland
* src/libecryptfs/module_mgr.c: fix typo
216
	.prompt = "Filename Encryption Key (FNEK) Signature",
196 by Mike Halcrow
Filename encryption option passes sanity check.
217
	.val_type = VAL_STR,
218
	.val = NULL,
219
	.display_opts = NULL,
220
	.default_val = NULL,
221
	.suggested_val = NULL,
222
	.flags = ECRYPTFS_PARAM_FLAG_NO_VALUE | ECRYPTFS_NO_AUTO_TRANSITION,
223
	.num_transitions = 1,
224
	.tl = {{.val = "default",
225
		.pretty_val = "default",
226
		.next_token = &end_param_node,
227
		.trans_func = filename_crypto_fnek_sig_callback}}
228
};
229
230
static int get_enable_filename_crypto(struct ecryptfs_ctx *ctx,
231
					struct param_node *node,
232
					struct val_node **head, void **foo)
233
{
376.1.6 by Michal Hlavinka
module_mgr.c: insist on yes/no answer
234
	int yn, rc = 0;
196 by Mike Halcrow
Filename encryption option passes sanity check.
235
384.1.7 by Michal Hlavinka
module_mgr.c: reenable default values
236
	if (((yn=is_yes(node->val, 0)) > 0)
196 by Mike Halcrow
Filename encryption option passes sanity check.
237
	    || (node->flags & PARAMETER_SET)) {
238
		int i;
239
		struct val_node *val_node;
240
241
		for (i = 0;
242
		     i < filename_crypto_fnek_sig_param_node.num_transitions;
243
		     i++)
244
			filename_crypto_fnek_sig_param_node.tl[i].next_token =
245
				node->tl[0].next_token;
246
		node->tl[0].next_token = &filename_crypto_fnek_sig_param_node;
247
		val_node = (*head);
248
		while (val_node) {
249
			if (strncmp(val_node->val, "ecryptfs_sig=", 13) == 0) {
250
				rc  = asprintf(&filename_crypto_fnek_sig_param_node.suggested_val,
251
					       "%s",
252
					       &((char *)val_node->val)[13]);
253
				if (rc == -1) {
254
					rc = -ENOMEM;
255
					syslog(LOG_ERR,
256
					       "%s: No memory whilst "
257
					       "attempting to write [%s]\n",
258
					       __FUNCTION__,
259
					       &((char *)val_node->val)[13]);
260
					goto out_free;
261
				}
342 by Dustin Kirkland
fix mount parameter handling
262
				rc = 0;
196 by Mike Halcrow
Filename encryption option passes sanity check.
263
				break;
264
			}
265
			val_node = val_node->next;
266
		}
376.1.6 by Michal Hlavinka
module_mgr.c: insist on yes/no answer
267
	} else if (node->val) {
268
		if (yn < 0)
269
			rc = WRONG_VALUE;
803 by Tyler Hicks
Fix -Wempty-body warning
270
	} else {
376.1.6 by Michal Hlavinka
module_mgr.c: insist on yes/no answer
271
		/* default: no */;
803 by Tyler Hicks
Fix -Wempty-body warning
272
	}
196 by Mike Halcrow
Filename encryption option passes sanity check.
273
out_free:
376.1.6 by Michal Hlavinka
module_mgr.c: insist on yes/no answer
274
	if (node->val) {
196 by Mike Halcrow
Filename encryption option passes sanity check.
275
		free(node->val);
376.1.6 by Michal Hlavinka
module_mgr.c: insist on yes/no answer
276
		node->val = NULL;
277
	}
196 by Mike Halcrow
Filename encryption option passes sanity check.
278
	return rc;
279
}
280
281
static struct param_node enable_filename_crypto_param_node = {
282
	.num_mnt_opt_names = 1,
283
	.mnt_opt_names = {"ecryptfs_enable_filename_crypto"},
284
	.prompt = "Enable filename encryption (y/n)",
285
	.val_type = VAL_STR,
286
	.val = NULL,
287
	.display_opts = NULL,
288
	.default_val = NULL,
289
	.flags = ECRYPTFS_PARAM_FLAG_ECHO_INPUT,
290
	.num_transitions = 1,
291
	.tl = {{.val = "default",
292
		.pretty_val = "default",
293
		.next_token = &filename_crypto_fnek_sig_param_node,
294
		.trans_func = get_enable_filename_crypto}}
295
};
296
55 by mhalcrow@us.ibm.com
Fix the plaintext passthrough option processing nodes.
297
static struct param_node ecryptfs_version_support_node = {
298
	.num_mnt_opt_names = 1,
299
	.mnt_opt_names = {"end"},
300
	.prompt = "end",
301
	.val_type = VAL_STR,
302
	.val = NULL,
303
	.display_opts = NULL,
304
	.default_val = NULL,
305
	.flags = ECRYPTFS_PARAM_FLAG_NO_VALUE,
306
	.num_transitions = 1,
307
	.tl = {{.val = "default",
308
		.pretty_val = "default",
309
		.next_token = NULL,
310
		.trans_func = NULL}}
311
};
312
2 by mhalcrow@us.ibm.com
Initial import of eCryptfs filesystem userspace utilities (mount helper, daemon component,
313
static struct param_node encrypted_passthrough_param_node = {
314
	.num_mnt_opt_names = 1,
55 by mhalcrow@us.ibm.com
Fix the plaintext passthrough option processing nodes.
315
	.mnt_opt_names = {"ecryptfs_encrypted_view"},
196 by Mike Halcrow
Filename encryption option passes sanity check.
316
	.prompt = "Pass through encrypted versions of all files (y/N)",
2 by mhalcrow@us.ibm.com
Initial import of eCryptfs filesystem userspace utilities (mount helper, daemon component,
317
	.val_type = VAL_STR,
318
	.val = NULL,
319
	.display_opts = NULL,
320
	.default_val = "n",
321
	.flags = ECRYPTFS_PARAM_FLAG_ECHO_INPUT,
322
	.num_transitions = 1,
323
	.tl = {{.val = "default",
324
		.pretty_val = "default",
325
		.next_token = &end_param_node,
326
		.trans_func = get_encrypted_passthrough}}
327
};
328
329
static struct param_node xattr_param_node = {
330
	.num_mnt_opt_names = 1,
55 by mhalcrow@us.ibm.com
Fix the plaintext passthrough option processing nodes.
331
	.mnt_opt_names = {"ecryptfs_xattr"},
196 by Mike Halcrow
Filename encryption option passes sanity check.
332
	.prompt = "Write metadata to extended attribute region (y/N)",
2 by mhalcrow@us.ibm.com
Initial import of eCryptfs filesystem userspace utilities (mount helper, daemon component,
333
	.val_type = VAL_STR,
334
	.val = NULL,
335
	.display_opts = NULL,
336
	.default_val = "n",
337
	.flags = ECRYPTFS_PARAM_FLAG_ECHO_INPUT,
338
	.num_transitions = 1,
339
	.tl = {{.val = "default",
340
		.pretty_val = "default",
341
		.next_token = &end_param_node,
342
		.trans_func = get_xattr}}
343
};
344
345
static struct param_node passthrough_param_node = {
346
	.num_mnt_opt_names = 1,
55 by mhalcrow@us.ibm.com
Fix the plaintext passthrough option processing nodes.
347
	.mnt_opt_names = {"ecryptfs_passthrough"},
2 by mhalcrow@us.ibm.com
Initial import of eCryptfs filesystem userspace utilities (mount helper, daemon component,
348
	.prompt = "Enable plaintext passthrough (y/n)",
349
	.val_type = VAL_STR,
350
	.val = NULL,
351
	.display_opts = NULL,
352
	.default_val = NULL,
353
	.flags = ECRYPTFS_PARAM_FLAG_ECHO_INPUT,
354
	.num_transitions = 1,
355
	.tl = {{.val = "default",
356
		.pretty_val = "default",
357
		.next_token = &end_param_node,
358
		.trans_func = get_passthrough}}
359
};
360
56 by mhalcrow@us.ibm.com
Add HMAC mount option to mount helper.
361
static struct param_node hmac_param_node = {
362
	.num_mnt_opt_names = 1,
363
	.mnt_opt_names = {"ecryptfs_hmac"},
196 by Mike Halcrow
Filename encryption option passes sanity check.
364
	.prompt = "Enable HMAC integrity verification (y/N)",
56 by mhalcrow@us.ibm.com
Add HMAC mount option to mount helper.
365
	.val_type = VAL_STR,
366
	.val = NULL,
367
	.display_opts = NULL,
368
	.default_val = NULL,
369
	.flags = ECRYPTFS_PARAM_FLAG_ECHO_INPUT,
370
	.num_transitions = 1,
371
	.tl = {{.val = "default",
372
		.pretty_val = "default",
373
		.next_token = &end_param_node,
374
		.trans_func = get_hmac}}
375
};
376
29 by mhalcrow@us.ibm.com
Make cipher and key bytes selection use the decision graph subsystem
377
static struct param_node ecryptfs_key_bytes_param_node = {
378
	.num_mnt_opt_names = 1,
379
	.mnt_opt_names = {"ecryptfs_key_bytes"},
380
	.prompt = "Select key bytes",
381
	.val_type = VAL_STR,
382
	.val = NULL,
383
	.display_opts = NULL,
384
	.default_val = NULL,
385
	.flags = (DISPLAY_TRANSITION_NODE_VALS
386
		  | ECRYPTFS_PARAM_FORCE_DISPLAY_NODES
387
		  | ECRYPTFS_PARAM_FLAG_ECHO_INPUT),
388
	.num_transitions = 0,
389
	.tl = {{0}}
390
};
391
392
static struct supported_key_bytes {
393
	char *cipher_name;
394
	uint32_t key_bytes;
395
} supported_key_bytes[] = {
802 by Tyler Hicks
Remove the unused 'order' member of the supported_key_bytes struct
396
	{"aes", 16},
397
	{"aes", 32},
398
	{"aes", 24},
399
	{"anubis", 16},
400
	{"anubis", 32},
401
	{"des3_ede", 24},
402
	{"serpent", 16},
403
	{"serpent", 32},
404
	{"tnepres", 16},
405
	{"tnepres", 32},
406
	{"tea", 16},
407
	{"xeta", 16},
408
	{"xtea", 16},
409
	{"cast5", 16},
410
	{"cast6", 16},
411
	{"cast6", 32},
412
	{"twofish", 16},
413
	{"twofish", 32},
414
	{"blowfish", 16},
415
	{"blowfish", 32},
416
	{"blowfish", 56},
417
	{"khazad", 16},
418
	{"arc4", 16},
419
	{"arc4", 32},
420
	{NULL, 0}
29 by mhalcrow@us.ibm.com
Make cipher and key bytes selection use the decision graph subsystem
421
};
422
423
static int tf_ecryptfs_key_bytes(struct ecryptfs_ctx *ctx,
424
				 struct param_node *node,
425
				 struct val_node **head, void **foo)
426
{
427
	char *opt;
428
	int rc = 0;
429
430
	rc = asprintf(&opt, "ecryptfs_key_bytes=%s", node->val);
431
	free(node->val);
432
	node->val = NULL;
433
	if (rc == -1) {
434
		rc = -ENOMEM;
435
		goto out;
436
	}
342 by Dustin Kirkland
fix mount parameter handling
437
	rc = stack_push(head, opt);
29 by mhalcrow@us.ibm.com
Make cipher and key bytes selection use the decision graph subsystem
438
out:
439
	return rc;
440
}
441
384.1.11 by Michal Hlavinka
refuse mounting with too small rsa key (key_mod_openssl)
442
static int init_ecryptfs_key_bytes_param_node(char *cipher_name, 
801 by Tyler Hicks
Fix sign comparison warnings and other issues surrounding the uint32_t type
443
					      uint32_t min, uint32_t max)
29 by mhalcrow@us.ibm.com
Make cipher and key bytes selection use the decision graph subsystem
444
{
445
	int i;
446
	int rc = 0;
447
448
	i = 0;
449
	while (supported_key_bytes[i].cipher_name) {
384.1.11 by Michal Hlavinka
refuse mounting with too small rsa key (key_mod_openssl)
450
		if ((supported_key_bytes[i].key_bytes >= min) && 
451
		    (supported_key_bytes[i].key_bytes <= max) &&
452
		    (strcmp(cipher_name, supported_key_bytes[i].cipher_name)
453
		      == 0)) {
29 by mhalcrow@us.ibm.com
Make cipher and key bytes selection use the decision graph subsystem
454
			struct transition_node *tn;
455
			
456
			tn = &ecryptfs_key_bytes_param_node.tl[
457
				ecryptfs_key_bytes_param_node.num_transitions];
801 by Tyler Hicks
Fix sign comparison warnings and other issues surrounding the uint32_t type
458
			rc = asprintf(&tn->val, "%"PRIu32,
29 by mhalcrow@us.ibm.com
Make cipher and key bytes selection use the decision graph subsystem
459
				      supported_key_bytes[i].key_bytes);
460
			if (rc == -1) {
461
				rc = -ENOMEM;
462
				goto out;
463
			}
464
			rc = 0;
465
			if (!ecryptfs_key_bytes_param_node.suggested_val) {
466
				rc = asprintf(&ecryptfs_key_bytes_param_node.suggested_val,
801 by Tyler Hicks
Fix sign comparison warnings and other issues surrounding the uint32_t type
467
					      "%"PRIu32,
29 by mhalcrow@us.ibm.com
Make cipher and key bytes selection use the decision graph subsystem
468
					      supported_key_bytes[i].key_bytes);
469
				if (rc == -1) {
470
					rc = -ENOMEM;
471
					goto out;
472
				}
473
				rc = 0;
474
			}
55 by mhalcrow@us.ibm.com
Fix the plaintext passthrough option processing nodes.
475
			tn->next_token = &ecryptfs_version_support_node;
29 by mhalcrow@us.ibm.com
Make cipher and key bytes selection use the decision graph subsystem
476
			tn->trans_func = tf_ecryptfs_key_bytes;
477
			ecryptfs_key_bytes_param_node.num_transitions++;
478
		}
479
		i++;
480
	}
384.1.11 by Michal Hlavinka
refuse mounting with too small rsa key (key_mod_openssl)
481
	if (ecryptfs_key_bytes_param_node.num_transitions == 0) {
482
		syslog(LOG_ERR, "Error initializing key_bytes selection: "
483
		       "there is no posibility left for used params\n");
484
		return -EINVAL;
485
	}
29 by mhalcrow@us.ibm.com
Make cipher and key bytes selection use the decision graph subsystem
486
out:
487
	return rc;
488
}
489
801 by Tyler Hicks
Fix sign comparison warnings and other issues surrounding the uint32_t type
490
static int parse_key_bytes(uint32_t *bytes, const char *str)
491
{
492
	uintmax_t tmp;
493
	char *eptr;
494
495
	if (str[0] == '-')
496
		return -ERANGE;
497
498
	errno = 0;
499
	tmp = strtoumax(str, &eptr, 10);
500
	if (eptr == str)
501
		return -EINVAL;
815 by Tyler Hicks
r801 introduced the use of strtoumax(), which returns UINTMAX_MAX on
502
	else if (tmp == UINTMAX_MAX && errno == ERANGE)
801 by Tyler Hicks
Fix sign comparison warnings and other issues surrounding the uint32_t type
503
		return -ERANGE;
504
	else if (tmp > UINT32_MAX)
505
		return -ERANGE;
506
507
	*bytes = (uint32_t)tmp;
508
	return 0;
509
}
510
29 by mhalcrow@us.ibm.com
Make cipher and key bytes selection use the decision graph subsystem
511
static int tf_ecryptfs_cipher(struct ecryptfs_ctx *ctx, struct param_node *node,
512
			      struct val_node **head, void **foo)
513
{
514
	char *opt;
515
	int rc;
801 by Tyler Hicks
Fix sign comparison warnings and other issues surrounding the uint32_t type
516
	uint32_t min = 0, max = 999999;
384.1.11 by Michal Hlavinka
refuse mounting with too small rsa key (key_mod_openssl)
517
	struct val_node *tmp = *head, *tmpprev = NULL;
518
519
	while (tmp) {
520
		char *ptr;
521
		int popval = 0;
522
		if (tmp->val && (strstr(tmp->val,"max_key_bytes=") != NULL) && 
523
		    ((ptr=strchr(tmp->val,'=')) != NULL)) {
801 by Tyler Hicks
Fix sign comparison warnings and other issues surrounding the uint32_t type
524
			rc = parse_key_bytes(&max, ++ptr);
525
			if (rc)
526
				return rc;
384.1.11 by Michal Hlavinka
refuse mounting with too small rsa key (key_mod_openssl)
527
			popval = 1;
528
		}
529
		if (tmp->val && (strstr(tmp->val,"min_key_bytes=") != NULL) && 
530
		    ((ptr=strchr(tmp->val,'=')) != NULL)) {
801 by Tyler Hicks
Fix sign comparison warnings and other issues surrounding the uint32_t type
531
			rc = parse_key_bytes(&min, ++ptr);
532
			if (rc)
533
				return rc;
384.1.11 by Michal Hlavinka
refuse mounting with too small rsa key (key_mod_openssl)
534
			popval = 1;
535
		}
536
		if (popval) {
537
			if (tmp == *head)
538
				*head = (*head)->next;
539
			stack_pop(&tmp);
540
			if (tmpprev != NULL)
541
				tmpprev->next = tmp;
542
		}
543
		tmpprev = tmp;
544
		tmp = tmp->next;
545
	}
546
547
	rc = init_ecryptfs_key_bytes_param_node(node->val, min, max);
29 by mhalcrow@us.ibm.com
Make cipher and key bytes selection use the decision graph subsystem
548
	if (rc) {
549
		syslog(LOG_ERR, "%s: Error initializing key_bytes param node; "
550
		       "rc = [%d]\n", __FUNCTION__, rc);
551
		goto out;
552
	}
553
	rc = asprintf(&opt, "ecryptfs_cipher=%s", node->val);
554
	free(node->val);
555
	node->val = NULL;
556
	if (rc == -1) {
557
		rc = -ENOMEM;
558
		goto out;
559
	}
560
	rc = 0;
561
	if (ecryptfs_verbosity)
562
		syslog(LOG_INFO, "%s: Pushing onto stack; opt = [%s]\n",
563
		       __FUNCTION__, opt);
342 by Dustin Kirkland
fix mount parameter handling
564
	rc = stack_push(head, opt);
29 by mhalcrow@us.ibm.com
Make cipher and key bytes selection use the decision graph subsystem
565
out:
566
	return rc;
567
}
568
569
static struct param_node ecryptfs_cipher_param_node = {
570
	.num_mnt_opt_names = 1,
571
	.mnt_opt_names = {"ecryptfs_cipher"},
2 by mhalcrow@us.ibm.com
Initial import of eCryptfs filesystem userspace utilities (mount helper, daemon component,
572
	.prompt = "Select cipher",
573
	.val_type = VAL_STR,
574
	.val = NULL,
575
	.display_opts = NULL,
576
	.default_val = NULL,
29 by mhalcrow@us.ibm.com
Make cipher and key bytes selection use the decision graph subsystem
577
	.flags = (DISPLAY_TRANSITION_NODE_VALS | ECRYPTFS_DISPLAY_PRETTY_VALS
578
		  | ECRYPTFS_PARAM_FLAG_ECHO_INPUT),
579
	.num_transitions = 0,
580
	.tl = {{0}}
2 by mhalcrow@us.ibm.com
Initial import of eCryptfs filesystem userspace utilities (mount helper, daemon component,
581
};
582
684 by Tyler Hicks
* include/ecryptfs.h, libecryptfs/Makefile.am,
583
static struct cipher_descriptor {
584
	char *name;
585
	uint32_t blocksize;
586
	uint32_t min_keysize;
587
	uint32_t max_keysize;
588
} cipher_descriptors[] = {
589
	{"aes", 16, 16, 32},
688 by Tyler Hicks
* src/libecryptfs/module_mgr.c:
590
	{"blowfish", 8, 16, 56},
684 by Tyler Hicks
* include/ecryptfs.h, libecryptfs/Makefile.am,
591
	{"des3_ede", 8, 24, 24},
592
	{"twofish", 16, 16, 32},
593
	{"cast6", 16, 16, 32},
594
	{"cast5", 8, 5, 16},
595
	{NULL, 0, 0, 0}
596
};
597
598
static int init_ecryptfs_cipher_param_node()
29 by mhalcrow@us.ibm.com
Make cipher and key bytes selection use the decision graph subsystem
599
{
684 by Tyler Hicks
* include/ecryptfs.h, libecryptfs/Makefile.am,
600
	struct cipher_descriptor *cd = cipher_descriptors;
776.1.11 by Colin King
* src/libecryptfs/module_mgr.c
601
	int rc = 0;
29 by mhalcrow@us.ibm.com
Make cipher and key bytes selection use the decision graph subsystem
602
684 by Tyler Hicks
* include/ecryptfs.h, libecryptfs/Makefile.am,
603
	while (cd && cd->name) {
29 by mhalcrow@us.ibm.com
Make cipher and key bytes selection use the decision graph subsystem
604
		struct transition_node *tn;
605
606
		if (ecryptfs_cipher_param_node.num_transitions
607
		    >= MAX_NUM_TRANSITIONS) {
608
			syslog(LOG_WARNING, "%s: Exceeded maximum number of "
609
			       "transition nodes [%d] whilst constructing "
610
			       "cipher list\n", __FUNCTION__,
611
			       MAX_NUM_TRANSITIONS);
612
			goto out;
613
		}
614
		tn = &ecryptfs_cipher_param_node.tl[
615
			ecryptfs_cipher_param_node.num_transitions];
684 by Tyler Hicks
* include/ecryptfs.h, libecryptfs/Makefile.am,
616
		rc = asprintf(&tn->val, "%s", cd->name);
29 by mhalcrow@us.ibm.com
Make cipher and key bytes selection use the decision graph subsystem
617
		if (rc == -1) {
618
			rc = -ENOMEM;
619
			goto out;
620
		}
621
		rc = 0;
622
		if (!ecryptfs_cipher_param_node.suggested_val) {
623
			rc = asprintf(&ecryptfs_cipher_param_node.suggested_val,
684 by Tyler Hicks
* include/ecryptfs.h, libecryptfs/Makefile.am,
624
				      "%s", cd->name);
29 by mhalcrow@us.ibm.com
Make cipher and key bytes selection use the decision graph subsystem
625
			if (rc == -1) {
626
				rc = -ENOMEM;
627
				goto out;
628
			}
629
			rc = 0;
630
		}
684 by Tyler Hicks
* include/ecryptfs.h, libecryptfs/Makefile.am,
631
		rc = asprintf(&tn->pretty_val, "%s: blocksize = %d; "
632
			      "min keysize = %d; max keysize = %d", cd->name,
633
			      cd->blocksize, cd->min_keysize, cd->max_keysize);
29 by mhalcrow@us.ibm.com
Make cipher and key bytes selection use the decision graph subsystem
634
		if (rc == -1) {
635
			rc = -ENOMEM;
636
			goto out;
637
		}
638
		rc = 0;
639
		tn->next_token = &ecryptfs_key_bytes_param_node;
640
		tn->trans_func = tf_ecryptfs_cipher;
641
		ecryptfs_cipher_param_node.num_transitions++;
684 by Tyler Hicks
* include/ecryptfs.h, libecryptfs/Makefile.am,
642
		cd++;
29 by mhalcrow@us.ibm.com
Make cipher and key bytes selection use the decision graph subsystem
643
	}
644
out:
645
	return rc;
646
}
647
2 by mhalcrow@us.ibm.com
Initial import of eCryptfs filesystem userspace utilities (mount helper, daemon component,
648
static int
649
another_key_param_node_callback(struct ecryptfs_ctx *ctx,
650
				struct param_node *node,
651
				struct val_node **head, void **foo)
652
{
653
	struct ecryptfs_name_val_pair *nvp = ctx->nvp_head->next;
654
	int rc = 0;
655
656
	while (nvp) {
657
		int i;
658
659
		if (nvp->flags & ECRYPTFS_PROCESSED) {
660
			nvp = nvp->next;
661
			continue;
662
		}
663
		if (ecryptfs_verbosity)
664
			syslog(LOG_INFO, "Comparing nvp->name = [%s] to "
665
			       "key_module_select_node.mnt_opt_names[0] = "
666
			       "[%s]\n", nvp->name,
667
			       key_module_select_node.mnt_opt_names[0]);
668
		if (strcmp(nvp->name,
669
			   key_module_select_node.mnt_opt_names[0]) != 0) {
670
			nvp = nvp->next;
671
			continue;
672
		}
673
		for (i = 0; i < key_module_select_node.num_transitions; i++)
674
			if (strcmp(nvp->value,
675
				   key_module_select_node.tl[i].val) == 0) {
676
				node->tl[0].next_token =
677
					&key_module_select_node;
678
				if (ecryptfs_verbosity)
679
					syslog(LOG_INFO,
680
					       "Found another nvp match\n");
681
				goto out;
682
			}
683
		nvp = nvp->next;
684
	}
29 by mhalcrow@us.ibm.com
Make cipher and key bytes selection use the decision graph subsystem
685
	node->tl[0].next_token = &ecryptfs_cipher_param_node;
2 by mhalcrow@us.ibm.com
Initial import of eCryptfs filesystem userspace utilities (mount helper, daemon component,
686
out:
687
	return rc;
688
}
689
690
/**
691
 * Check for the existence of another transition node match in the
692
 * name/value pair list.
693
 */
694
static struct param_node another_key_param_node = {
695
	.num_mnt_opt_names = 1,
696
	.mnt_opt_names = {"another_key"},
697
	.prompt = "Internal check for another key",
698
	.val_type = VAL_STR,
699
	.val = NULL,
700
	.display_opts = NULL,
701
	.default_val = "NULL",
41 by mike@halcrow.us
Support for implicit transitions
702
	.flags = ECRYPTFS_PARAM_FLAG_NO_VALUE | ECRYPTFS_NO_AUTO_TRANSITION,
2 by mhalcrow@us.ibm.com
Initial import of eCryptfs filesystem userspace utilities (mount helper, daemon component,
703
	.num_transitions = 1,
704
	.tl = {{.val = "default",
705
		.pretty_val = "default",
29 by mhalcrow@us.ibm.com
Make cipher and key bytes selection use the decision graph subsystem
706
		.next_token = &ecryptfs_cipher_param_node,
2 by mhalcrow@us.ibm.com
Initial import of eCryptfs filesystem userspace utilities (mount helper, daemon component,
707
		.trans_func = another_key_param_node_callback}}
708
};
709
29 by mhalcrow@us.ibm.com
Make cipher and key bytes selection use the decision graph subsystem
710
static int
2 by mhalcrow@us.ibm.com
Initial import of eCryptfs filesystem userspace utilities (mount helper, daemon component,
711
fill_in_decision_graph_based_on_version_support(struct param_node *root,
712
						uint32_t version)
713
{
55 by mhalcrow@us.ibm.com
Fix the plaintext passthrough option processing nodes.
714
	struct param_node *last_param_node = &ecryptfs_version_support_node;
29 by mhalcrow@us.ibm.com
Make cipher and key bytes selection use the decision graph subsystem
715
	int rc;
2 by mhalcrow@us.ibm.com
Initial import of eCryptfs filesystem userspace utilities (mount helper, daemon component,
716
717
	ecryptfs_set_exit_param_on_graph(root, &another_key_param_node);
684 by Tyler Hicks
* include/ecryptfs.h, libecryptfs/Makefile.am,
718
	rc = init_ecryptfs_cipher_param_node();
29 by mhalcrow@us.ibm.com
Make cipher and key bytes selection use the decision graph subsystem
719
	if (rc) {
720
		syslog(LOG_ERR,
721
		       "%s: Error initializing cipher list; rc = [%d]\n",
722
		       __FUNCTION__, rc);
723
		goto out;
724
	}
2 by mhalcrow@us.ibm.com
Initial import of eCryptfs filesystem userspace utilities (mount helper, daemon component,
725
	if (ecryptfs_supports_plaintext_passthrough(version)) {
29 by mhalcrow@us.ibm.com
Make cipher and key bytes selection use the decision graph subsystem
726
		int i;
727
728
		for (i = 0; i < last_param_node->num_transitions; i++)
729
			last_param_node->tl[i].next_token =
730
				&passthrough_param_node;
99 by Mike Halcrow
Add default val for plaintext passthrough prompt
731
		rc = asprintf(&passthrough_param_node.suggested_val, "n");
732
		if (rc == -1) {
733
			rc = -ENOMEM;
734
			goto out;
735
		}
736
		rc = 0;
2 by mhalcrow@us.ibm.com
Initial import of eCryptfs filesystem userspace utilities (mount helper, daemon component,
737
		last_param_node = &passthrough_param_node;
738
	}
56 by mhalcrow@us.ibm.com
Add HMAC mount option to mount helper.
739
	if (ecryptfs_supports_hmac(version)) {
740
		int i;
741
742
		for (i = 0; i < last_param_node->num_transitions; i++)
743
			last_param_node->tl[i].next_token =
744
				&hmac_param_node;
745
		last_param_node = &hmac_param_node;
746
	}
2 by mhalcrow@us.ibm.com
Initial import of eCryptfs filesystem userspace utilities (mount helper, daemon component,
747
	if (ecryptfs_supports_xattr(version)) {
29 by mhalcrow@us.ibm.com
Make cipher and key bytes selection use the decision graph subsystem
748
		int i;
749
750
		for (i = 0; i < last_param_node->num_transitions; i++)
751
			last_param_node->tl[i].next_token = &xattr_param_node;
2 by mhalcrow@us.ibm.com
Initial import of eCryptfs filesystem userspace utilities (mount helper, daemon component,
752
		last_param_node = &xattr_param_node;
29 by mhalcrow@us.ibm.com
Make cipher and key bytes selection use the decision graph subsystem
753
		for (i = 0; i < last_param_node->num_transitions; i++)
754
			last_param_node->tl[i].next_token =
755
				&encrypted_passthrough_param_node;
2 by mhalcrow@us.ibm.com
Initial import of eCryptfs filesystem userspace utilities (mount helper, daemon component,
756
		last_param_node = &encrypted_passthrough_param_node;
757
	}
196 by Mike Halcrow
Filename encryption option passes sanity check.
758
	if (ecryptfs_supports_filename_encryption(version)) {
759
		int i;
760
761
		rc = asprintf(&enable_filename_crypto_param_node.suggested_val,
762
			      "n");
763
		if (rc == -1) {
764
			rc = -ENOMEM;
765
			goto out;
766
		}
767
		rc = 0;
768
		for (i = 0; i < last_param_node->num_transitions; i++)
769
			last_param_node->tl[i].next_token =
770
				&filename_crypto_fnek_sig_param_node;
771
		last_param_node = &filename_crypto_fnek_sig_param_node;
772
	}
29 by mhalcrow@us.ibm.com
Make cipher and key bytes selection use the decision graph subsystem
773
out:
774
	return rc;
2 by mhalcrow@us.ibm.com
Initial import of eCryptfs filesystem userspace utilities (mount helper, daemon component,
775
}
776
777
static struct param_node dummy_param_node = {
778
	.num_mnt_opt_names = 1,
779
	.mnt_opt_names = {"dummy"},
780
	.prompt = "dummy",
781
	.val_type = VAL_STR,
782
	.val = NULL,
783
	.display_opts = NULL,
784
	.default_val = NULL,
785
	.flags = ECRYPTFS_PARAM_FLAG_NO_VALUE,
786
	.num_transitions = 0,
787
	.tl = {{.val = "default",
788
		.pretty_val = "default",
789
		.next_token = NULL,
790
		.trans_func = NULL}}
791
};
792
793
/**
794
 * ecryptfs_process_decision_graph
795
 * @key_module_only: Only process the key module; set this if you are,
796
 *                   for instance, only inserting the key into the
797
 *                   user session keyring
798
 *
799
 * Called from: utils/mount.ecryptfs.c::main()
800
 *
801
 * Some values may be duplicated. For instance, if the user specifies
802
 * two keys of the same type, then we want to process both keys:
803
 *
804
 * key=passphrase:passwd=pass1,key=passphrase:passwd=pass1
805
 *
806
 * 
807
 */
808
int ecryptfs_process_decision_graph(struct ecryptfs_ctx *ctx,
809
				    struct val_node **mnt_params,
810
				    uint32_t version, char *opts_str,
811
				    int key_module_only)
812
{
813
	struct ecryptfs_name_val_pair nvp_head;
814
	struct ecryptfs_name_val_pair rc_file_nvp_head;
815
	struct ecryptfs_key_mod *key_mod;
816
	struct ecryptfs_name_val_pair allowed_duplicates;
817
	struct ecryptfs_name_val_pair *ad_cursor;
818
	int rc;
819
820
	ad_cursor = &allowed_duplicates;
821
	ad_cursor->next = NULL;
822
	/* Start with the key module type. Generate the options from
823
	 * the detected modules that are available */
824
	rc = ecryptfs_register_key_modules(ctx);
825
	if (rc) {
826
		syslog(LOG_ERR, "Error attempting to get key module list; "
827
		       "rc = [%d]\n", rc);
828
		goto out;
829
	}
830
	if ((ad_cursor->next = malloc(sizeof(allowed_duplicates))) == NULL) {
831
		rc = -ENOMEM;
832
		goto out;
833
	}
834
	ad_cursor = ad_cursor->next;
835
	ad_cursor->next = NULL;
707 by Tyler Hicks
* src/libecryptfs/module_mgr.c, src/pam_ecryptfs/pam_ecryptfs.c:
836
	if ((rc = asprintf(&ad_cursor->name, "%s",
2 by mhalcrow@us.ibm.com
Initial import of eCryptfs filesystem userspace utilities (mount helper, daemon component,
837
			   key_module_select_node.mnt_opt_names[0])) == -1) {
838
		rc = -ENOMEM;
839
		goto out_free_allowed_duplicates;
840
	}
35 by Mike Halcrow
Clean up the ecryptfs-manager lists
841
	key_module_select_node.num_transitions = 0;
2 by mhalcrow@us.ibm.com
Initial import of eCryptfs filesystem userspace utilities (mount helper, daemon component,
842
	key_mod = ctx->key_mod_list_head.next;
843
	while (key_mod) {
844
		struct transition_node *trans_node;
845
846
		if ((rc =
847
		     key_mod->ops->get_param_subgraph_trans_node(&trans_node,
848
								 version))) {
849
			syslog(LOG_INFO, "Key module [%s] does not have a "
850
			       "subgraph transition node; attempting to build "
851
			       "a linear subgraph from its parameter list\n",
852
			       key_mod->alias);
853
			if ((rc = ecryptfs_build_linear_subgraph(&trans_node,
854
								 key_mod))) {
855
				syslog(LOG_WARNING, "Error attempting to build "
856
				       "linear subgraph for key module [%s]; "
857
				       "excluding; rc = [%d]\n",
858
				       key_mod->alias, rc);
859
				key_mod = key_mod->next;
860
				continue;
861
			}
862
		}
863
		if (trans_node == NULL) {
864
			if ((rc = ecryptfs_build_linear_subgraph(&trans_node,
865
								 key_mod))) {
866
				syslog(LOG_WARNING, "Error attempting to build "
867
				       "linear subgraph for key module [%s]; "
868
				       "excluding; rc = [%d]\n",
869
				       key_mod->alias, rc);
870
				key_mod = key_mod->next;
871
				continue;
872
			}
873
		}
874
		if ((rc =
875
		     add_transition_node_to_param_node(&key_module_select_node,
876
						       trans_node))) {
877
			syslog(LOG_ERR, "Error attempting to add transition "
878
			       "node to param node; rc = [%d]\n", rc);
879
			goto out_free_allowed_duplicates;
880
		}
881
		/* Key module parameters may be duplicated, since
882
		 * the user may specify multiple keys. Make sure that
883
		 * the allowed_duplicates list has the parameters for
884
		 * this key module. */
885
		if ((rc = ecryptfs_insert_params_in_subgraph(ad_cursor,
886
							     trans_node))) {
887
			syslog(LOG_ERR, "Error attempting to insert allowed "
888
			       "duplicate parameters into subgraph for key "
889
			       "module; rc = [%d]\n", rc);
890
			goto out_free_allowed_duplicates;
891
		}
892
		key_mod = key_mod->next;
893
	}
29 by mhalcrow@us.ibm.com
Make cipher and key bytes selection use the decision graph subsystem
894
	if (key_module_only == ECRYPTFS_ASK_FOR_ALL_MOUNT_OPTIONS) {
895
		rc = fill_in_decision_graph_based_on_version_support(
896
			&key_module_select_node, version);
897
		if (rc) {
898
			syslog(LOG_ERR, "%s: Error attempting to fill in "
899
			       "decision graph; rc = [%d]\n", __FUNCTION__, rc);
900
			goto out;
901
		}
902
	} else
2 by mhalcrow@us.ibm.com
Initial import of eCryptfs filesystem userspace utilities (mount helper, daemon component,
903
		ecryptfs_set_exit_param_on_graph(&key_module_select_node,
904
						 &dummy_param_node);
905
	memset(&nvp_head, 0, sizeof(struct ecryptfs_name_val_pair));
906
	memset(&rc_file_nvp_head, 0, sizeof(struct ecryptfs_name_val_pair));
907
	ecryptfs_parse_rc_file(&rc_file_nvp_head);
908
	rc = ecryptfs_parse_options(opts_str, &nvp_head);
909
	ecryptfs_nvp_list_union(&rc_file_nvp_head, &nvp_head,
910
				&allowed_duplicates);
911
	if (ecryptfs_verbosity) {
912
		struct ecryptfs_name_val_pair *nvp_item = rc_file_nvp_head.next;
913
914
		while (nvp_item) {
915
			if (ecryptfs_verbosity)
916
				syslog(LOG_INFO, "name = [%s]; value = [%s]\n",
917
				       nvp_item->name, nvp_item->value);
918
			nvp_item = nvp_item->next;
919
		}
920
	}
921
	ctx->nvp_head = &rc_file_nvp_head;
315.1.1 by Michal Hlavinka
improve interactive mode of mount.ecryptfs
922
	rc = ecryptfs_eval_decision_graph(ctx, mnt_params, &root_param_node,
2 by mhalcrow@us.ibm.com
Initial import of eCryptfs filesystem userspace utilities (mount helper, daemon component,
923
				     &rc_file_nvp_head);
924
out_free_allowed_duplicates:
925
	ad_cursor = allowed_duplicates.next;
926
	while (ad_cursor) {
927
		struct ecryptfs_name_val_pair *next;
928
		
929
		next = ad_cursor->next;
930
		free(ad_cursor->name);
931
		free(ad_cursor);
932
		ad_cursor = next;
933
	}
934
out:
935
	return rc;
936
}
937
938
int ecryptfs_process_key_gen_decision_graph(struct ecryptfs_ctx *ctx,
939
					    uint32_t version)
940
{
941
	struct ecryptfs_name_val_pair nvp_head;
942
	struct ecryptfs_key_mod *key_mod;
943
	struct val_node *mnt_params;
944
	int rc;
945
946
	if ((mnt_params = malloc(sizeof(struct val_node))) == NULL) {
947
		rc = -ENOMEM;
948
		goto out;
949
	}
950
	memset(mnt_params, 0, sizeof(struct val_node));
951
	if ((rc = ecryptfs_register_key_modules(ctx))) {
952
		syslog(LOG_ERR, "Error attempting to get key module list; "
953
		       "rc = [%d]\n", rc);
954
		goto out;
955
	}
35 by Mike Halcrow
Clean up the ecryptfs-manager lists
956
	key_module_select_node.num_transitions = 0;
2 by mhalcrow@us.ibm.com
Initial import of eCryptfs filesystem userspace utilities (mount helper, daemon component,
957
	key_mod = ctx->key_mod_list_head.next;
958
	while (key_mod) {
959
		struct transition_node *trans_node;
960
961
		if ((rc =
962
		     key_mod->ops->get_gen_key_subgraph_trans_node(&trans_node,
963
								   version))) {
964
			syslog(LOG_INFO, "Key module [%s] does not have a "
965
			       "key generation subgraph transition node\n",
966
			       key_mod->alias);
967
			/* TODO: Implement key generation linear subgraph */
968
			key_mod = key_mod->next;
969
			continue;
970
		}
971
		if (trans_node == NULL) {
972
			syslog(LOG_INFO, "Key module [%s] does not have a "
973
			       "key generation subgraph transition node\n",
974
			       key_mod->alias);
975
			/* TODO: Implement key generation linear subgraph */
976
			key_mod = key_mod->next;
977
			continue;
978
		}
979
		if ((rc =
980
		     add_transition_node_to_param_node(&key_module_select_node,
981
						       trans_node))) {
982
			syslog(LOG_ERR, "Error attempting to add transition "
983
			       "node to param node; rc = [%d]\n", rc);
984
			goto out;
985
		}
986
		key_mod = key_mod->next;
987
	}
988
	ecryptfs_set_exit_param_on_graph(&key_module_select_node,
989
					 &dummy_param_node);
990
	memset(&nvp_head, 0, sizeof(struct ecryptfs_name_val_pair));
991
	ctx->nvp_head = &nvp_head;
992
	key_module_select_node.flags |= ECRYPTFS_PARAM_FORCE_DISPLAY_NODES;
993
	ecryptfs_eval_decision_graph(ctx, &mnt_params, &key_module_select_node,
994
				     &nvp_head);
995
out:
996
	free(mnt_params);
997
	return rc;
998
}