source: creddy/creddy.c @ 461541a

abac0-leakabac0-meimei-idmei-rt0-nmei_rt0tvf-new-xml
Last change on this file since 461541a was 461541a, checked in by Mei <mei@…>, 11 years ago

1) updated original rt0 to remove libstrongswan dependency

a) identity credential being made/accessed with openssl api calls

(X509/EVP_PKEY pem)

b) attribute credential being made/access via xmlsec1 (custom XML

structure)

2) refactored libcreddy into libabac and now one ABAC namespace for

libabac

3) added attribute_rule suboption to creddy's attribute as another way

to insert access rule

4) added some regression tests into example directory
5) updated some docs.

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