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
RevLine 
[461541a]1
2/* creddy.c */
3
[abd7c25]4#include <assert.h>
[00d21a1]5#include <errno.h>
[abd7c25]6#include <getopt.h>
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
[461541a]10#include <ctype.h>
11#include <err.h>
[abd7c25]12
[04f5da1]13#include "creddy_common.h"
[abd7c25]14
15#define OPT_CN              1
16#define OPT_VALIDITY        2
[fd0febd]17#define OPT_CERT            3
[085f159]18#define OPT_ISSUER          4
19#define OPT_KEY             5
20#define OPT_ROLE            6
[ee5afdd]21#define OPT_SUBJECT_CERT    7
[085f159]22#define OPT_SUBJECT_ROLE    8
23#define OPT_OUT             9 // the world oughta be opt-in only :(
[784a398]24#define OPT_ATTRCERT        10
[ee5afdd]25#define OPT_SUBJECT_ID      11
[0aaa651]26#define OPT_SHOW            12
[461541a]27#define OPT_ATTRRULE        13
[abd7c25]28
[980a7b6]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
[abd7c25]64int main(int argc, char **argv) {
65    options_t options = { 0, };
[00d21a1]66    char *validity_str = NULL;
[abd7c25]67
[461541a]68    libabac_init();
69
[980a7b6]70    subjects = xmalloc(sizeof(subject_t) * 2);
71    subjects_size = 2;
72
73    roles = xmalloc(sizeof(char *) * 2);
74    roles_size = 2;
75
[abd7c25]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 },
[19be896]83        { "version",    0, &options.mode, MODE_VERSION },
[0aaa651]84        { "display",    0, &options.mode, MODE_DISPLAY },
[abd7c25]85
[fd0febd]86        { "cert",       1, 0, OPT_CERT },
87
[abd7c25]88        // generate options
89        { "cn",         1, 0, OPT_CN },
90        { "validity",   1, 0, OPT_VALIDITY },
91
[085f159]92        // attribute options
93        { "issuer",     1, 0, OPT_ISSUER },
94        { "key",        1, 0, OPT_KEY },
95        { "role",       1, 0, OPT_ROLE },
[ee5afdd]96        { "subject-cert", 1, 0, OPT_SUBJECT_CERT },
97        { "subject-id", 1, 0, OPT_SUBJECT_ID },
[ec06cb6]98        { "subject-role", 1, 0, OPT_SUBJECT_ROLE },
[085f159]99        { "out",          1, 0, OPT_OUT },
100
[461541a]101        // attribute_rule option
102        { "attrrule",   1, 0, OPT_ATTRRULE },
103
[784a398]104        // verify option
105        { "attrcert",   1, 0, OPT_ATTRCERT },
106
[0aaa651]107        // display options
108        { "show",       1, 0, OPT_SHOW },
109
[abd7c25]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
[fd0febd]123            case OPT_CERT:
124                options.cert = xstrdup(optarg);
125                break;
126
[abd7c25]127            // generate options
128            case OPT_CN:
129                options.cn = xstrdup(optarg);
130                break;
[085f159]131            case OPT_VALIDITY: // also an attribute option
[00d21a1]132                validity_str = xstrdup(optarg);
[abd7c25]133                break;
134
[085f159]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;
[ee5afdd]145            case OPT_SUBJECT_CERT:
[980a7b6]146                subject(xstrdup(optarg), 1);
[ee5afdd]147                break;
148            case OPT_SUBJECT_ID:
[980a7b6]149                subject(xstrdup(optarg), 0);
[085f159]150                break;
151            case OPT_SUBJECT_ROLE:
[980a7b6]152                role(xstrdup(optarg));
[085f159]153                break;
154            case OPT_OUT:
155                options.out = xstrdup(optarg);
156                break;
157
[461541a]158            // attribute rule options
159            case OPT_ATTRRULE:
160                options.attrrule = xstrdup(optarg);
161                break;
162
[784a398]163            // verify options
164            case OPT_ATTRCERT:
165                options.attrcert = xstrdup(optarg);
166                break;
167
[0aaa651]168            // display options
169            case OPT_SHOW:
170                options.show = xstrdup(optarg);
171                break;
172
[abd7c25]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
[00d21a1]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
[461541a]242    if (options.mode == MODE_ATTRIBUTE && options.attrrule == NULL) {
[980a7b6]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
[9410b51]266    // launch the sub command
[abd7c25]267    switch (options.mode) {
268        case MODE_GENERATE:
[00d21a1]269            if (options.validity == 0) options.validity = 1080 * 86400;
[abd7c25]270            generate_main(&options);
271            break;
272
[fd0febd]273        case MODE_KEYID:
274            keyid_main(&options);
275            break;
276
[085f159]277        case MODE_ATTRIBUTE:
[00d21a1]278            if (options.validity == 0) options.validity = 365 * 86400;
[461541a]279            if(options.attrrule)
280                attribute_rule_main(&options);
281                else attribute_main(&options);
[085f159]282            break;
283
[9410b51]284        case MODE_ROLES:
285            roles_main(&options);
286            break;
287
[784a398]288        case MODE_VERIFY:
289            verify_main(&options);
290            break;
291
[0aaa651]292        case MODE_DISPLAY:
293            display_main(&options);
[adc86c3]294            break;
295
[19be896]296        case MODE_VERSION:
297            printf("ABAC/creddy " ABAC_VERSION "\n");
298            break;
299
[abd7c25]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(
[00d21a1]310            "Usage: creddy --generate --cn <name> [ --validity <time> ] [ --out <dir> ]\n"
[f1e892e]311            "    cert will be in ${name}_ID.der, private key in ${name}_private.pem\n"
[8231b92]312            "    files output to dir if specified\n"
[abd7c25]313            "    default validity: 1080 days\n"
[00d21a1]314            "\n"
315            "    time is specified with optional suffix: s m h d y\n"
316            "    defaults to days if unspecified\n"
[abd7c25]317        );
318
319    else if (opts->mode == MODE_VERIFY)
320        printf(
[91659cb]321            "Usage: creddy --verify --cert <cert> [ --attrcert <cert> ]\n"
[abd7c25]322            "    if attrcert is provided, verify that it was issued by cert\n"
323        );
324
325    else if (opts->mode == MODE_KEYID)
326        printf(
[91659cb]327            "Usage: creddy --keyid --cert <cert>\n"
[abd7c25]328        );
329
330    else if (opts->mode == MODE_ATTRIBUTE)
331        printf(
[91659cb]332            "Usage: creddy --attribute \\\n"
[abd7c25]333            "                --issuer <cert> --key <key> --role <role> \\\n"
[980a7b6]334            "                [ --subject-cert <cert> | --subject-id <sha1> \\\n"
335            "                    [ --subject-role <role> ]  ... ] \\\n"
[00d21a1]336            "                [ --validity <time> ] --out <file>\n"
[abd7c25]337            "    default validity: 365 days\n"
[ee5afdd]338            "    provide exactly one of --subject-cert / --subject-id\n"
[980a7b6]339            "    give multiple --subject-{cert,id} / --subject-role pairs for intersection\n"
[00d21a1]340            "\n"
341            "    time is specified with optional suffix: s m h d y\n"
342            "    defaults to days if unspecified\n"
[abd7c25]343        );
344
345    else if (opts->mode == MODE_ROLES)
346        printf(
[91659cb]347            "Usage: creddy --roles --cert <cert>\n"
[abd7c25]348        );
349
[0aaa651]350    else if (opts->mode == MODE_DISPLAY)
[adc86c3]351        printf(
[405bba3]352            "Usage: creddy --display --show=[issuer,..,all] --cert <cert>\n"
[0aaa651]353            "   values for --show are comma-separated:\n"
354            "       issuer      DN of issuer\n"
[b19d1f0]355            "       subject     DN of subject\n"
[405bba3]356            "       validity    validity period\n"
[08e7235]357            "       roles       attribute cert roles (fails silently on ID certs)\n"
[0aaa651]358            "       all         all of the above\n"
[adc86c3]359            "   cert may be X.509 identity or attribute cert\n"
360        );
361
[abd7c25]362    else
363        printf(
[66462c5]364            "Usage: creddy [ --<mode> ] [ --help ]\n"
[abd7c25]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"
[0aaa651]370            "    --display:   list metadata from an X.509 identity or attribute cert\n"
[19be896]371            "    --version:   display ABAC version\n"
[abd7c25]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
[980a7b6]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
[abd7c25]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.