~ecryptfs/ecryptfs/trunk

« back to all changes in this revision

Viewing changes to src/utils/io.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): Trevor Highland <tshighla@us.ibm.com>
 
4
 *            Theresa Nelson <tmnelson@us.ibm.com>
 
5
 *            Tyler Hicks <tyhicks@ou.edu>
 
6
 *
 
7
 * I/O functions for mount helper
 
8
 *
 
9
 * This program is free software; you can redistribute it and/or
 
10
 * modify it under the terms of the GNU General Public License as
 
11
 * published by the Free Software Foundation; either version 2 of the
 
12
 * License, or (at your option) any later version.
 
13
 *
 
14
 * This program is distributed in the hope that it will be useful, but
 
15
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
17
 * General Public License for more details.
 
18
 *
 
19
 * You should have received a copy of the GNU General Public License
 
20
 * along with this program; if not, write to the Free Software
 
21
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 
22
 * 02111-1307, USA.
 
23
 */
 
24
 
 
25
#include <stdio.h>
 
26
#include <string.h>
 
27
#include <termios.h>
 
28
#include <stdlib.h>
 
29
#include <errno.h>
 
30
#include <sys/mman.h>
 
31
#include "config.h"
 
32
#include "ecryptfs.h"
 
33
#include "io.h"
 
34
 
 
35
static int disable_echo(struct termios *saved_settings)
 
36
{
 
37
        struct termios current_settings;
 
38
        int rc = 0;
 
39
 
 
40
        rc = tcgetattr(0, &current_settings);
 
41
        if (rc)
 
42
                return rc;
 
43
        *saved_settings = current_settings;
 
44
        current_settings.c_lflag &= ~ECHO;
 
45
        rc = tcsetattr(0, TCSANOW, &current_settings);
 
46
        return rc;
 
47
}
 
48
 
 
49
static int enable_echo(struct termios *saved_settings)
 
50
{
 
51
        return tcsetattr(0, TCSANOW, saved_settings);
 
52
}
 
53
 
 
54
int mygetchar(void)
 
55
{
 
56
        int c = getchar();
 
57
 
 
58
        if (c == '\r')
 
59
                c = '\n';
 
60
        return c;
 
61
}
 
62
 
 
63
int get_string_stdin(char **val, char *prompt, int echo)
 
64
{
 
65
#define DEFAULT_STRING_LENGTH 16
 
66
        int count = 0;
 
67
        struct termios saved_settings;
 
68
        int length = DEFAULT_STRING_LENGTH;
 
69
        char *temp;
 
70
        int rc = 0;
 
71
 
 
72
        printf("%s: ", prompt);
 
73
        temp = malloc(length);
 
74
        if (!temp) {
 
75
                rc = -ENOMEM;
 
76
                goto out;
 
77
        }
 
78
        *val = temp;
 
79
        if (!echo) {
 
80
                rc = disable_echo(&saved_settings);
 
81
                if (rc)
 
82
                        goto out;
 
83
        }
 
84
        do {
 
85
                if (count == length) {
 
86
                        temp = malloc(length * 2);
 
87
                        if (!temp) {
 
88
                                rc = -ENOMEM;
 
89
                                goto out;
 
90
                        }
 
91
                        memcpy(temp, *val, length);
 
92
                        memset(*val, 0, length);
 
93
                        length *= 2;
 
94
                        free(*val);
 
95
                        *val = temp;
 
96
                }
 
97
                (*val)[count] = mygetchar();
 
98
                count++;
 
99
        } while((*val)[count-1] != '\n');
 
100
        (*val)[count - 1] = '\0';
 
101
        if (!echo) {
 
102
                printf("\n");
 
103
                rc = enable_echo(&saved_settings);
 
104
        }
 
105
out:
 
106
        return rc;
 
107
}
 
108
 
 
109
int get_string(char *val, int len, int echo)
 
110
{
 
111
        int count = 0;
 
112
        struct termios saved_settings;
 
113
        int rc = 0;
 
114
 
 
115
        if (echo == ECRYPTFS_ECHO_OFF) {
 
116
                rc = disable_echo(&saved_settings);
 
117
                if (rc)
 
118
                        goto out;
 
119
        }
 
120
        do {
 
121
                val[count] = mygetchar();
 
122
                count++;
 
123
        } while(val[count-1] != '\n' && (count < len));
 
124
        if (count > len)
 
125
                val[len - 1] = '\0';
 
126
        else
 
127
                val[count - 1] = '\0';
 
128
        if (echo == ECRYPTFS_ECHO_OFF) {
 
129
                printf("\n");
 
130
                rc = enable_echo(&saved_settings);
 
131
        }
 
132
out:
 
133
        return rc;
 
134
}
 
135
 
 
136
static inline int munch_newline(void)
 
137
{
 
138
        if (mygetchar() == '\n')
 
139
                return 0;
 
140
        while (mygetchar() != '\n');
 
141
        return -1;
 
142
}
 
143
 
 
144
int manager_menu(void)
 
145
{
 
146
        char str[8];
 
147
        int selection;
 
148
 
 
149
        printf("\neCryptfs key management menu\n");
 
150
        printf("-------------------------------\n");
 
151
        printf("\t%d. Add passphrase key to keyring\n", MME_MOUNT_PASSPHRASE);
 
152
        printf("\t%d. Add public key to keyring\n", MME_MOUNT_PUBKEY);
 
153
        printf("\t%d. Generate new public/private keypair\n", MME_GEN_PUBKEY);
 
154
        printf("\t%d. Exit\n", MME_ABORT);
 
155
try_again:
 
156
        printf("\nMake selection: ");
 
157
        str[0] = mygetchar();
 
158
        if (munch_newline()) {
 
159
                printf("Invalid selection\n");
 
160
                goto try_again;
 
161
        }
 
162
        str[strlen(str)] = '\0';
 
163
        selection = atoi(str);
 
164
        switch (selection) {
 
165
        case MME_MOUNT_PASSPHRASE:
 
166
        case MME_MOUNT_PUBKEY:
 
167
        case MME_GEN_PUBKEY:
 
168
        case MME_ABORT:
 
169
                break;
 
170
        default:
 
171
                printf("Invalid selection\n");
 
172
                goto try_again;
 
173
        }
 
174
        return selection;
 
175
}
 
176
 
 
177
int read_passphrase_salt(char *pass, char *salt)
 
178
{
 
179
        char *confirmed_pass;
 
180
        int rc = 0;
 
181
 
 
182
        confirmed_pass = malloc(ECRYPTFS_MAX_PASSWORD_LENGTH);
 
183
        if (!confirmed_pass) {
 
184
                rc = -ENOMEM;
 
185
                ecryptfs_syslog(LOG_ERR, "Failed to allocate memory\n");
 
186
                goto out;
 
187
        }
 
188
        mlock(confirmed_pass, ECRYPTFS_MAX_PASSWORD_LENGTH);
 
189
        printf("\n\tMount-wide passphrase: ");
 
190
        rc = get_string(pass, ECRYPTFS_MAX_PASSWORD_LENGTH, ECRYPTFS_ECHO_OFF);
 
191
        if (rc)
 
192
                goto out;
 
193
        if (pass[0] == '\0') {
 
194
                printf("Invalid passphrase. Aborting mount.\n");
 
195
                rc = -EINVAL;
 
196
                goto out;
 
197
        }
 
198
        printf("\tConfirm passphrase: ");
 
199
        rc = get_string(confirmed_pass, ECRYPTFS_MAX_PASSWORD_LENGTH,
 
200
                        ECRYPTFS_ECHO_OFF);
 
201
        if (rc) {
 
202
                ecryptfs_syslog(LOG_ERR, "Failed to read passphrase\n");
 
203
                goto out;
 
204
        }
 
205
        if (strcmp(pass, confirmed_pass) != 0) {
 
206
                printf("Passphrase mismatch. Aborting mount\n");
 
207
                rc = -EINVAL;
 
208
                goto out;
 
209
        }
 
210
        printf("\tUsing the default salt value\n");
 
211
out:
 
212
        memset(confirmed_pass, 0, ECRYPTFS_MAX_PASSWORD_LENGTH);
 
213
        free(confirmed_pass);
 
214
        return rc;
 
215
}
 
216
 
 
217
int ecryptfs_select_key_mod(struct ecryptfs_key_mod **key_mod,
 
218
                            struct ecryptfs_ctx *ctx)
 
219
{
 
220
        int rc;
 
221
        int key_mod_type;
 
222
        int count;
 
223
        struct ecryptfs_key_mod *curr;
 
224
        char str[8];
 
225
        int default_key_mod = 1;
 
226
 
 
227
prompt_user:
 
228
        count = 1;
 
229
        curr = ctx->key_mod_list_head.next;
 
230
        if (!curr) {
 
231
                rc = 1;
 
232
                goto out;
 
233
        }
 
234
        if (!(curr->next))
 
235
                goto success;
 
236
        printf("\nThe following PKI modules are available:\n");
 
237
        while (curr) {
 
238
                printf("\t%i. %s\n", count, curr->alias);
 
239
                count++;
 
240
                curr = curr->next;
 
241
        }
 
242
        printf("\nSelect desired key module [%d]: ", default_key_mod);
 
243
        fgets(str, 4, stdin);
 
244
        printf("\n");
 
245
        str[strlen(str)] = '\0';
 
246
        if (str[0] == '\n')
 
247
                key_mod_type = default_key_mod;
 
248
        else
 
249
                key_mod_type = atoi(str);
 
250
        if (key_mod_type < 1 || key_mod_type >= count) {
 
251
                char *pch = strstr(str, "\n");
 
252
 
 
253
                printf("Invalid selection\n");
 
254
                if (!pch) {
 
255
                        int ch;
 
256
 
 
257
                        while ((ch = mygetchar()) != '\n');
 
258
                }
 
259
                goto prompt_user;
 
260
        }
 
261
        curr = ctx->key_mod_list_head.next;
 
262
        while(key_mod_type > 1) {
 
263
                curr = curr->next;
 
264
                key_mod_type--;
 
265
        }
 
266
success:
 
267
        (*key_mod) = curr;
 
268
        rc = 0;
 
269
out:
 
270
        return rc;
 
271
}