1 /* vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80: */
2 /*
3  * Copyright 2016 Red Hat, Inc.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #pragma once
19 
20 #include <jose/jose.h>
21 #include <getopt.h>
22 
23 #define __JCMD_AUTO(t) t ## _t __attribute__((cleanup(t ## _cleanup)))
24 #define jcmd_opt_key_auto_t __JCMD_AUTO(jcmd_opt_key)
25 #define jcmd_opt_io_auto_t  __JCMD_AUTO(jcmd_opt_io)
26 #define jcmd_opt_auto_t     __JCMD_AUTO(jcmd_opt)
27 #define FILE_AUTO      FILE __attribute__((cleanup(jcmd_file_cleanup)))
28 
29 #define JCMD_REGISTER(summary, function, ...)               \
30     static void __attribute__((constructor))                \
31     jcmd_ ## function ## _register(void)                    \
32     {                                                       \
33         static const char *names[] = { __VA_ARGS__, NULL }; \
34         static jcmd_t cmd = {                               \
35             .names = names,                                 \
36             .func = function,                               \
37             .desc = summary                                 \
38         };                                                  \
39         jcmd_push(&cmd);                                    \
40     }
41 
42 typedef struct jcmd_cfg jcmd_cfg_t;
43 typedef bool jcmd_set_t(const jcmd_cfg_t *cfg, void *vopt, const char *arg);
44 
45 typedef struct {
46     const char *arg;
47     const char *doc;
48 } jcmd_doc_t;
49 
50 struct jcmd_cfg {
51     const jcmd_doc_t *doc;
52     struct option opt;
53     const char *def;
54     jcmd_set_t *set;
55     off_t off;
56 };
57 
58 typedef struct {
59     const char *name;
60     const char *mult;
61 } jcmd_field_t;
62 
63 typedef struct {
64     const jcmd_field_t *fields;
65     FILE *detached;
66     bool  compact;
67     FILE *detach;
68     FILE *output;
69     FILE *input;
70     json_t *obj;
71 } jcmd_opt_io_t;
72 
73 typedef struct jcmd jcmd_t;
74 struct jcmd {
75     const jcmd_t *next;
76     const char *const *names;
77     int (*func)(int argc, char *argv[]);
78     const char *desc;
79 };
80 
81 static const jcmd_doc_t jcmd_doc_key[] = {
82     { .arg = "FILE", .doc="Read JWK(Set) from FILE" },
83     { .arg = "-",    .doc="Read JWK(Set) from standard input" },
84     {}
85 };
86 
87 void
88 jcmd_push(jcmd_t *cmd);
89 
90 bool
91 jcmd_opt_parse(int argc, char *argv[], const jcmd_cfg_t *cfgs, void *arg,
92                const char *prefix);
93 
94 jcmd_set_t jcmd_opt_io_set_input; /* Takes jcmd_opt_io_t* */
95 jcmd_set_t jcmd_opt_set_ifile;    /* Takes FILE** */
96 jcmd_set_t jcmd_opt_set_ofile;    /* Takes FILE** */
97 jcmd_set_t jcmd_opt_set_jsons;    /* Takes json_t** */
98 jcmd_set_t jcmd_opt_set_json;     /* Takes json_t** */
99 jcmd_set_t jcmd_opt_set_jwkt;     /* Takes json_t** */
100 jcmd_set_t jcmd_opt_set_jwks;     /* Takes json_t** */
101 jcmd_set_t jcmd_opt_set_flag;     /* Takes bool* */
102 
103 void
104 jcmd_opt_io_cleanup(jcmd_opt_io_t *io);
105 
106 void
107 jcmd_opt_key_cleanup(jcmd_opt_io_t *io);
108 
109 json_t *
110 jcmd_compact_field(FILE *file);
111 
112 void
113 jcmd_file_cleanup(FILE **file);
114