source: creddy/creddy.c @ b8a6c918

abac0-leak
Last change on this file since b8a6c918 was 1bf0f03, checked in by Mei <mei@…>, 11 years ago

1) save a copy before fixup of tests directory

  • Property mode set to 100644
File size: 11.3 KB
Line 
1
2/* creddy.c */
3
4#include <assert.h>
5#include <errno.h>
6#include <getopt.h>
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10#include <ctype.h>
11#include <err.h>
12
13#include "creddy_common.h"
14
15extern void libabac_init();
16
17#define OPT_CN              1
18#define OPT_VALIDITY        2
19#define OPT_CERT            3
20#define OPT_ISSUER          4
21#define OPT_KEY             5
22#define OPT_ROLE            6
23#define OPT_SUBJECT_CERT    7
24#define OPT_SUBJECT_ROLE    8
25#define OPT_OUT             9 // the world oughta be opt-in only :(
26#define OPT_ATTRCERT        10
27#define OPT_SUBJECT_ID      11
28#define OPT_SHOW            12
29#define OPT_ATTRRULE        13
30
31subject_t *subjects = NULL;
32int num_subjects = 0;
33int subjects_size = 0;
34
35char **roles = NULL;
36int num_roles = 0;
37int roles_size = 0;
38
39void subject(char *subject, int cert) {
40    if (num_subjects == subjects_size) {
41        subjects_size *= 2;
42        subjects = xrealloc(subjects, sizeof(subject_t) * subjects_size);
43    }
44
45    int i = num_subjects++;
46    subjects[i].id = NULL;
47    subjects[i].cert = NULL;
48    subjects[i].role = NULL;
49
50    if (cert)
51        subjects[i].cert = subject;
52    else
53        subjects[i].id = subject;
54}
55
56void role(char *role) {
57    if (num_roles == roles_size) {
58        roles_size *= 2;
59        roles = xrealloc(roles, sizeof(char *) * roles_size);
60    }
61
62    int i = num_roles++;
63    roles[i] = role;
64}
65
66int main(int argc, char **argv) {
67    options_t options = { 0, };
68    char *validity_str = NULL;
69
70    libabac_init();
71
72    subjects = xmalloc(sizeof(subject_t) * 2);
73    subjects_size = 2;
74
75    roles = xmalloc(sizeof(char *) * 2);
76    roles_size = 2;
77
78    struct option getopts[] = {
79        { "help",       0, &options.help, 1 },
80        { "generate",   0, &options.mode, MODE_GENERATE },
81        { "verify",     0, &options.mode, MODE_VERIFY },
82        { "keyid",      0, &options.mode, MODE_KEYID },
83        { "attribute",  0, &options.mode, MODE_ATTRIBUTE },
84        { "roles",      0, &options.mode, MODE_ROLES },
85        { "version",    0, &options.mode, MODE_VERSION },
86        { "display",    0, &options.mode, MODE_DISPLAY },
87
88        { "cert",       1, 0, OPT_CERT },
89
90        // generate options
91        { "cn",         1, 0, OPT_CN },
92        { "validity",   1, 0, OPT_VALIDITY },
93
94        // attribute options
95        { "issuer",     1, 0, OPT_ISSUER },
96        { "key",        1, 0, OPT_KEY },
97        { "role",       1, 0, OPT_ROLE },
98        { "subject-cert", 1, 0, OPT_SUBJECT_CERT },
99        { "subject-id", 1, 0, OPT_SUBJECT_ID },
100        { "subject-role", 1, 0, OPT_SUBJECT_ROLE },
101        { "out",          1, 0, OPT_OUT },
102
103        // attribute_rule option
104        { "attrrule",   1, 0, OPT_ATTRRULE },
105
106        // verify option
107        { "attrcert",   1, 0, OPT_ATTRCERT },
108
109        // display options
110        { "show",       1, 0, OPT_SHOW },
111
112        { NULL },
113    };
114
115    for ( ; ; ) {
116        int c = getopt_long(argc, argv, "", getopts, NULL);
117        if (c < 0)
118            break;
119
120        switch (c) {
121            // set the option from the value in the getopts struct
122            case 0:
123                continue;
124
125            case OPT_CERT:
126                options.cert = xstrdup(optarg);
127                break;
128
129            // generate options
130            case OPT_CN:
131                options.cn = xstrdup(optarg);
132                break;
133            case OPT_VALIDITY: // also an attribute option
134                validity_str = xstrdup(optarg);
135                break;
136
137            // attribute options
138            case OPT_ISSUER:
139                options.issuer = xstrdup(optarg);
140                break;
141            case OPT_KEY: // also an generate option
142                options.key = xstrdup(optarg);
143                break;
144            case OPT_ROLE:
145                options.role = xstrdup(optarg);
146                break;
147            case OPT_SUBJECT_CERT:
148                subject(xstrdup(optarg), 1);
149                break;
150            case OPT_SUBJECT_ID:
151                subject(xstrdup(optarg), 0);
152                break;
153            case OPT_SUBJECT_ROLE:
154                role(xstrdup(optarg));
155                break;
156            case OPT_OUT:
157                options.out = xstrdup(optarg);
158                break;
159
160            // attribute rule options
161            case OPT_ATTRRULE:
162                options.attrrule = xstrdup(optarg);
163                break;
164
165            // verify options
166            case OPT_ATTRCERT:
167                options.attrcert = xstrdup(optarg);
168                break;
169
170            // display options
171            case OPT_SHOW:
172                options.show = xstrdup(optarg);
173                break;
174
175            case '?':
176                break;
177
178            default:
179                printf("wat\n");
180                return 45;
181        }
182    }
183
184    if (options.help || optind < argc) {
185        if (optind > 0 && optind < argc)
186            printf("I don't understand %s\n", argv[optind]);
187        usage(&options);
188    }
189
190    // parse the validity
191    if (validity_str != NULL) {
192        char suffix = 'd'; // default suffix is days
193        int multiplier;
194
195        int len = strlen(validity_str);
196        assert(len > 0);
197
198        // get the suffix char if it's alphabetical
199        if (isalpha(validity_str[len - 1])) {
200            suffix = validity_str[len - 1];
201
202            // truncate
203            validity_str[len - 1] = '\0';
204            --len;
205
206            // make sure it's not only a suffix
207            if (len == 0) {
208                printf("Invalid validity\n");
209                usage(&options);
210            }
211        }
212
213        // convert the suffix to a multiplier
214        switch(suffix) {
215            case 's': multiplier =        1; break;
216            case 'm': multiplier =       60; break;
217            case 'h': multiplier =     3600; break;
218            case 'd': multiplier =    86400; break;
219            case 'y': multiplier = 31536000; break;
220            default:
221                printf("Invalid suffix, must be s m h d y\n");
222                usage(&options);
223        }
224
225        // ascii to int
226        char *end;
227        options.validity = strtol(validity_str, &end, 10);
228        if (errno != 0 || end - validity_str < len) {
229            printf("Invalid validity\n");
230            usage(&options);
231        }
232
233        if (options.validity <= 0) {
234            printf("Invalid validity: must be > 0\n");
235            usage(&options);
236        }
237
238        // multiply!
239        options.validity *= multiplier;
240
241        free(validity_str);
242    }
243
244    if (options.mode == MODE_ATTRIBUTE && options.attrrule == NULL) {
245        int i;
246
247        // have to do error checking on subjects here
248        if (
249                (num_subjects == 0) ||
250                (num_subjects != num_roles && num_subjects != 1 && num_roles != 0)
251           ) {
252            printf(
253                "You have %d subject%s and %d role%s, which is invalid\n",
254                num_subjects, num_subjects == 1 ? "" : "s",
255                num_roles, num_roles == 1 ? "" : "s"
256            );
257            usage(&options);
258        }
259
260        for (i = 0; i < num_roles; ++i)
261            subjects[i].role = roles[i];
262        free(roles);
263
264        options.subjects = subjects;
265        options.num_subjects = num_subjects;
266    }
267
268    // launch the sub command
269    switch (options.mode) {
270        case MODE_GENERATE:
271            if (options.validity == 0) options.validity = 1080 * 86400;
272            generate_main(&options);
273            break;
274
275        case MODE_KEYID:
276            keyid_main(&options);
277            break;
278
279        case MODE_ATTRIBUTE:
280            if (options.validity == 0) options.validity = 365 * 86400;
281            if(options.attrrule)
282                attribute_rule_main(&options);
283                else attribute_main(&options);
284            break;
285
286        case MODE_ROLES:
287            roles_main(&options);
288            break;
289
290        case MODE_VERIFY:
291            verify_main(&options);
292            break;
293
294        case MODE_DISPLAY:
295            display_main(&options);
296            break;
297
298        case MODE_VERSION:
299            printf("ABAC/creddy " ABAC_VERSION "\n");
300            break;
301
302        default:
303            usage(&options);
304    }
305
306    return 0;
307}
308
309void usage(options_t *opts) {
310    if (opts->mode == MODE_GENERATE)
311        printf(
312            "Usage: creddy --generate --cn <name> [ --validity <time> ] [ --out <dir> ]\n"
313            "    cert will be in ${name}_ID.der, private key in ${name}_private.pem\n"
314            "    files output to dir if specified\n"
315            "    default validity: 1080 days\n"
316            "\n"
317            "    time is specified with optional suffix: s m h d y\n"
318            "    defaults to days if unspecified\n"
319        );
320
321    else if (opts->mode == MODE_VERIFY)
322        printf(
323            "Usage: creddy --verify --cert <cert> [ --attrcert <cert> ]\n"
324            "    if attrcert is provided, verify that it was issued by cert\n"
325        );
326
327    else if (opts->mode == MODE_KEYID)
328        printf(
329            "Usage: creddy --keyid --cert <cert>\n"
330        );
331
332    else if (opts->mode == MODE_ATTRIBUTE)
333        printf(
334            "Usage: creddy --attribute \\\n"
335            "                --issuer <cert> --key <key> --role <role> \\\n"
336            "                [ --subject-cert <cert> | --subject-id <sha1> \\\n"
337            "                    [ --subject-role <role> ]  ... ] \\\n"
338            "                [ --validity <time> ] --out <file>\n"
339            "    default validity: 365 days\n"
340            "    provide exactly one of --subject-cert / --subject-id\n"
341            "    give multiple --subject-{cert,id} / --subject-role pairs for intersection\n"
342            "\n"
343            "    time is specified with optional suffix: s m h d y\n"
344            "    defaults to days if unspecified\n"
345        );
346
347    else if (opts->mode == MODE_ROLES)
348        printf(
349            "Usage: creddy --roles --cert <cert>\n"
350        );
351
352    else if (opts->mode == MODE_DISPLAY)
353        printf(
354            "Usage: creddy --display --show=[issuer,..,all] --cert <cert>\n"
355            "   values for --show are comma-separated:\n"
356            "       issuer      DN of issuer\n"
357            "       subject     DN of subject\n"
358            "       validity    validity period\n"
359            "       roles       attribute cert roles (fails silently on ID certs)\n"
360            "       all         all of the above\n"
361            "   cert may be X.509 identity or attribute cert\n"
362        );
363
364    else
365        printf(
366            "Usage: creddy [ --<mode> ] [ --help ]\n"
367            "    --generate:  generate X.509 identity cert and private key\n"
368            "    --verify:    check validity of X.509 ID or XML attribute cert\n"
369            "    --keyid:     get fingerprint from X.509 ID cert\n"
370            "    --attribute: generate an XML attribute cert\n"
371            "    --roles:     list roles from an XML attribute cert\n"
372            "    --display:   list metadata from an X.509 identity or an XML attribute cert\n"
373            "    --version:   display ABAC version\n"
374        );
375
376
377    exit(1);
378}
379
380void *xmalloc(size_t len) {
381    void *ret = malloc(len);
382    if (ret == NULL)
383        err(1, "couldn't malloc %zu bytes\n", len);
384    return ret;
385}
386
387void *xrealloc(void *ptr, size_t size) {
388    void *ret = realloc(ptr, size);
389    if (ret == NULL)
390        err(1, "couldn't realloc %zu bytes\n", size);
391    return ret;
392}
393
394char *xstrdup(char *string) {
395    char *dup = strdup(string);
396    if (dup == NULL)
397        err(1, "Can't dup %s", string);
398    return dup;
399}
400
Note: See TracBrowser for help on using the repository browser.