source: creddy/creddy.c @ b04404d

abac0-leakabac0-meicompt_changesgec13mei-idmei-rt0-nmei_rt0mei_rt2mei_rt2_fix_1meiyap-rt1meiyap1rt2tvf-new-xml
Last change on this file since b04404d was b04404d, checked in by Mike Ryan <mikeryan@…>, 13 years ago

correct a regression: issuer option was used to mean two different
things. display issuer mode has been renamed.

see #17

  • Property mode set to 100644
File size: 8.7 KB
Line 
1#include <assert.h>
2#include <getopt.h>
3#include <stdio.h>
4#include <stdlib.h>
5#include <string.h>
6
7#include "creddy_common.h"
8
9#define OPT_CN              1
10#define OPT_VALIDITY        2
11#define OPT_CERT            3
12#define OPT_ISSUER          4
13#define OPT_KEY             5
14#define OPT_ROLE            6
15#define OPT_SUBJECT_CERT    7
16#define OPT_SUBJECT_ROLE    8
17#define OPT_OUT             9 // the world oughta be opt-in only :(
18#define OPT_ATTRCERT        10
19#define OPT_SUBJECT_ID      11
20
21subject_t *subjects = NULL;
22int num_subjects = 0;
23int subjects_size = 0;
24
25char **roles = NULL;
26int num_roles = 0;
27int roles_size = 0;
28
29void subject(char *subject, int cert) {
30    if (num_subjects == subjects_size) {
31        subjects_size *= 2;
32        subjects = xrealloc(subjects, sizeof(subject_t) * subjects_size);
33    }
34
35    int i = num_subjects++;
36    subjects[i].id = NULL;
37    subjects[i].cert = NULL;
38    subjects[i].role = NULL;
39
40    if (cert)
41        subjects[i].cert = subject;
42    else
43        subjects[i].id = subject;
44}
45
46void role(char *role) {
47    if (num_roles == roles_size) {
48        roles_size *= 2;
49        roles = xrealloc(roles, sizeof(char *) * roles_size);
50    }
51
52    int i = num_roles++;
53    roles[i] = role;
54}
55
56int main(int argc, char **argv) {
57    int ret;
58    options_t options = { 0, };
59
60    subjects = xmalloc(sizeof(subject_t) * 2);
61    subjects_size = 2;
62
63    roles = xmalloc(sizeof(char *) * 2);
64    roles_size = 2;
65
66    struct option getopts[] = {
67        { "help",       0, &options.help, 1 },
68        { "generate",   0, &options.mode, MODE_GENERATE },
69        { "verify",     0, &options.mode, MODE_VERIFY },
70        { "keyid",      0, &options.mode, MODE_KEYID },
71        { "attribute",  0, &options.mode, MODE_ATTRIBUTE },
72        { "roles",      0, &options.mode, MODE_ROLES },
73        { "version",    0, &options.mode, MODE_VERSION },
74        { "show_issuer", 0, &options.mode, MODE_ISSUER },
75
76        { "cert",       1, 0, OPT_CERT },
77
78        // generate options
79        { "cn",         1, 0, OPT_CN },
80        { "validity",   1, 0, OPT_VALIDITY },
81
82        // attribute options
83        { "issuer",     1, 0, OPT_ISSUER },
84        { "key",        1, 0, OPT_KEY },
85        { "role",       1, 0, OPT_ROLE },
86        { "subject-cert", 1, 0, OPT_SUBJECT_CERT },
87        { "subject-id", 1, 0, OPT_SUBJECT_ID },
88        { "subject-role", 1, 0, OPT_SUBJECT_ROLE },
89        { "out",          1, 0, OPT_OUT },
90
91        // verify option
92        { "attrcert",   1, 0, OPT_ATTRCERT },
93
94        { NULL },
95    };
96
97    for ( ; ; ) {
98        int c = getopt_long(argc, argv, "", getopts, NULL);
99        if (c < 0)
100            break;
101
102        switch (c) {
103            // set the option from the value in the getopts struct
104            case 0:
105                continue;
106
107            case OPT_CERT:
108                options.cert = xstrdup(optarg);
109                break;
110
111            // generate options
112            case OPT_CN:
113                options.cn = xstrdup(optarg);
114                break;
115            case OPT_VALIDITY: // also an attribute option
116                options.validity = atoi(optarg);
117                break;
118
119            // attribute options
120            case OPT_ISSUER:
121                options.issuer = xstrdup(optarg);
122                break;
123            case OPT_KEY:
124                options.key = xstrdup(optarg);
125                break;
126            case OPT_ROLE:
127                options.role = xstrdup(optarg);
128                break;
129            case OPT_SUBJECT_CERT:
130                subject(xstrdup(optarg), 1);
131                break;
132            case OPT_SUBJECT_ID:
133                subject(xstrdup(optarg), 0);
134                break;
135            case OPT_SUBJECT_ROLE:
136                role(xstrdup(optarg));
137                break;
138            case OPT_OUT:
139                options.out = xstrdup(optarg);
140                break;
141
142            // verify options
143            case OPT_ATTRCERT:
144                options.attrcert = xstrdup(optarg);
145                break;
146
147            case '?':
148                break;
149
150            default:
151                printf("wat\n");
152                return 45;
153        }
154    }
155
156    if (options.help || optind < argc) {
157        if (optind > 0 && optind < argc)
158            printf("I don't understand %s\n", argv[optind]);
159        usage(&options);
160    }
161
162    if (options.mode == MODE_ATTRIBUTE) {
163        int i;
164
165        // have to do error checking on subjects here
166        if (
167                (num_subjects == 0) ||
168                (num_subjects != num_roles && num_subjects != 1 && num_roles != 0)
169           ) {
170            printf(
171                "You have %d subject%s and %d role%s, which is invalid\n",
172                num_subjects, num_subjects == 1 ? "" : "s",
173                num_roles, num_roles == 1 ? "" : "s"
174            );
175            usage(&options);
176        }
177
178        for (i = 0; i < num_roles; ++i)
179            subjects[i].role = roles[i];
180        free(roles);
181
182        options.subjects = subjects;
183        options.num_subjects = num_subjects;
184    }
185
186    // launch the sub command
187    switch (options.mode) {
188        case MODE_GENERATE:
189            if (options.validity == 0) options.validity = 1080;
190            generate_main(&options);
191            break;
192
193        case MODE_KEYID:
194            keyid_main(&options);
195            break;
196
197        case MODE_ATTRIBUTE:
198            if (options.validity == 0) options.validity = 365;
199            attribute_main(&options);
200            break;
201
202        case MODE_ROLES:
203            roles_main(&options);
204            break;
205
206        case MODE_VERIFY:
207            verify_main(&options);
208            break;
209
210        case MODE_ISSUER:
211            issuer_main(&options);
212            break;
213
214        case MODE_VERSION:
215            printf("ABAC/creddy " ABAC_VERSION "\n");
216            break;
217
218        default:
219            usage(&options);
220    }
221
222    return 0;
223}
224
225void usage(options_t *opts) {
226    if (opts->mode == MODE_GENERATE)
227        printf(
228            "Usage: creddy --generate --cn <name> [ --validity <days> ]\n"
229            "    cert will be in ${name}_ID.der, private key in ${name}_private.pem\n"
230            "    default validity: 1080 days\n"
231        );
232
233    else if (opts->mode == MODE_VERIFY)
234        printf(
235            "Usage: identity --verify --cert <cert> [ --attrcert <cert> ]\n"
236            "    if attrcert is provided, verify that it was issued by cert\n"
237        );
238
239    else if (opts->mode == MODE_KEYID)
240        printf(
241            "Usage: identity --keyid --cert <cert>\n"
242        );
243
244    else if (opts->mode == MODE_ATTRIBUTE)
245        printf(
246            "Usage: identity --attribute \\\n"
247            "                --issuer <cert> --key <key> --role <role> \\\n"
248            "                [ --subject-cert <cert> | --subject-id <sha1> \\\n"
249            "                    [ --subject-role <role> ]  ... ] \\\n"
250            "                [ --validity <days> ] --out <file>\n"
251            "    default validity: 365 days\n"
252            "    provide exactly one of --subject-cert / --subject-id\n"
253            "    give multiple --subject-{cert,id} / --subject-role pairs for intersection\n"
254        );
255
256    else if (opts->mode == MODE_ROLES)
257        printf(
258            "Usage: identity --roles --cert <cert>\n"
259        );
260
261    else if (opts->mode == MODE_ISSUER)
262        printf(
263            "Usage: creddy --show_issuer --cert <cert>\n"
264            "   cert may be X.509 identity or attribute cert\n"
265        );
266
267    else
268        printf(
269            "Usage: creddy [ --<mode> ] [ --help ]\n"
270            "    --generate:  generate X.509 identity cert and private key\n"
271            "    --verify:    check validity of X.509 ID or attribute cert\n"
272            "    --keyid:     get fingerprint from X.509 ID cert\n"
273            "    --attribute: generate an X.509 attribute cert\n"
274            "    --roles:     list roles from an X.509 attribute cert\n"
275            "    --show_issuer: list issuer from an X.509 identity or attribute cert\n"
276            "    --version:   display ABAC version\n"
277        );
278
279
280    exit(1);
281}
282
283void *xmalloc(size_t len) {
284    void *ret = malloc(len);
285    if (ret == NULL)
286        err(1, "couldn't malloc %d bytes\n", len);
287    return ret;
288}
289
290void *xrealloc(void *ptr, size_t size) {
291    void *ret = realloc(ptr, size);
292    if (ret == NULL)
293        err(1, "couldn't realloc %d bytes\n", size);
294    return ret;
295}
296
297char *xstrdup(char *string) {
298    char *dup = strdup(string);
299    if (dup == NULL)
300        err(1, "Can't dup %s", string);
301    return dup;
302}
303
304certificate_t *attr_cert_from_file(char *filename) {
305    libabac_init();
306    certificate_t *cert = lib->creds->create(lib->creds,
307        CRED_CERTIFICATE, CERT_X509_AC,
308        BUILD_FROM_FILE, filename,
309        BUILD_END
310    );
311    if (cert == NULL)
312        errx(1, "Couldn't load attribute cert %s", filename);
313
314    return cert;
315}
Note: See TracBrowser for help on using the repository browser.