2
* Copyright (C) 2006 International Business Machines Corp.
3
* Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
4
* Trevor Highland <trevor.highland@gmail.com>
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
23
#include <sys/types.h>
25
#endif /* S_SPLINT_S */
32
#endif /* S_SPLINT_S */
36
#include "../include/ecryptfs.h"
38
#define MAX_TOK_LEN 128
39
#define MAX_FILE_SIZE 0xa000
41
int print_nvp_list(struct ecryptfs_name_val_pair *dst)
43
syslog(LOG_ERR, "Printing nvp list\n");
45
syslog(LOG_ERR, "name=%s\n", dst->name);
46
syslog(LOG_ERR, "val=%s\n", dst->value);
53
* For each name in dst that is also in src, set the value in dst to
54
* that which is in src.
56
* For each name in src that is not in dst, append a copy of the node
59
int ecryptfs_nvp_list_union(struct ecryptfs_name_val_pair *dst,
60
struct ecryptfs_name_val_pair *src)
63
struct ecryptfs_name_val_pair *dst_cursor;
64
struct ecryptfs_name_val_pair *src_cursor;
66
src_cursor = src->next;
69
struct ecryptfs_name_val_pair *prev_dst_cursor;
71
if (!src_cursor->name)
74
prev_dst_cursor = dst;
75
dst_cursor = dst->next;
77
if (!dst_cursor->name)
79
if (strcmp(src_cursor->name, dst_cursor->name) == 0) {
81
free(dst_cursor->value);
82
rc = asprintf(&dst_cursor->value, "%s",
90
prev_dst_cursor = dst_cursor;
91
dst_cursor = dst_cursor->next;
94
prev_dst_cursor->next = dst_cursor =
95
malloc(sizeof(struct ecryptfs_name_val_pair));
100
dst_cursor->next = NULL;
101
dst_cursor->flags = src_cursor->flags;
102
rc = asprintf(&dst_cursor->name, "%s",
108
rc = asprintf(&dst_cursor->value, "%s",
116
src_cursor = src_cursor->next;
123
ecryptfs_parse_rc_file_fullpath(struct ecryptfs_name_val_pair *nvp_list_head,
129
fd = open(fullpath, O_RDONLY);
134
rc = parse_options_file(fd, nvp_list_head);
140
int ecryptfs_parse_rc_file(struct ecryptfs_name_val_pair *nvp_list_head)
145
char *rcfile_fullpath;
151
rc = asprintf(&rcfile_fullpath, "%s/.ecryptfsrc", home);
156
rc = ecryptfs_parse_rc_file_fullpath(nvp_list_head, rcfile_fullpath);
157
free(rcfile_fullpath);
162
int process_comma_tok(struct ecryptfs_name_val_pair **current, char *tok,
163
/*@null@*/ char *prefix)
165
int tok_len = (int)strlen(tok);
166
char new_prefix[MAX_TOK_LEN];
167
char sub_token[MAX_TOK_LEN];
173
if(tok && tok[0] == '\0') {
176
if (tok_len < 0 || tok_len > MAX_TOK_LEN) {
180
if (tok[0] == '=' || tok[0] == ':') {
185
if (tok_len > 4 && !memcmp(tok, "key=", 4))
186
for (i = 4; i < tok_len; i++) {
188
goto process_colon_list;
190
goto process_nv_pair;
192
new_prefix[j] = '\0';
195
while (i < tok_len) {
198
if ((rc = process_comma_tok(current, sub_token, NULL)))
202
sub_token[j++] = tok[i];
206
rc = process_comma_tok(current, sub_token, new_prefix);
209
st_len = snprintf(sub_token, MAX_TOK_LEN, "%s%s",
210
(prefix ? prefix : ""), tok);
212
for (i = 0; i < st_len; i++)
213
if (sub_token[i] == '=') {
214
if (!(name = malloc(i + 1))) {
218
memcpy(name, sub_token, i);
223
if (!(name = malloc(i+1))) {
227
memcpy(name, sub_token, i);
231
if (!(value = malloc(i - j + 1))) {
235
memcpy(value, &sub_token[j+1], (i - j));
236
value[(i - j)] = '\0';
239
if (!((*current)->next =
240
malloc(sizeof(struct ecryptfs_name_val_pair)))) {
244
if (strlen(name) == 0) {
248
*current = (*current)->next;
249
(*current)->name = name;
250
(*current)->value = value;
251
(*current)->next = NULL;
258
* name=val,key=PKI:name1=val1:name2=val2,name=val...
260
int generate_nv_list(struct ecryptfs_name_val_pair *head, char *buf)
262
struct ecryptfs_name_val_pair *current = head;
263
char tok_str[MAX_TOK_LEN];
264
int buf_len = strlen(buf);
268
for (i = 0; i < buf_len; i++) {
269
if (buf[i] == ',' || buf[i] == '\n') {
271
if ((rc = process_comma_tok(¤t, tok_str, NULL)))
275
tok_str[j++] = buf[i];
276
if (j == MAX_TOK_LEN)
280
if ((rc = process_comma_tok(¤t, tok_str, NULL)))
286
int ecryptfs_parse_options(char *opts, struct ecryptfs_name_val_pair *head)
288
return generate_nv_list(head, opts);
291
int parse_options_file(int fd, struct ecryptfs_name_val_pair *head)
297
struct stat filestat;
299
rc = fstat(fd, &filestat);
302
pagesize = getpagesize();
303
file_size = filestat.st_size;
304
if (file_size > MAX_FILE_SIZE) {
305
syslog(LOG_ERR, "File size too large\n");
309
if (file_size % pagesize) {
310
file_size -= file_size % pagesize;
311
file_size += pagesize;
313
data = mmap((caddr_t)0, file_size, PROT_READ, MAP_PRIVATE, fd, 0);
314
if (data == MAP_FAILED) {
318
rc = generate_nv_list(head, data);
319
munmap(data, file_size);