find_certificates() returns a vector of const pointers.
[fides] / src / fides.cc
1 /* fides.cc - Light-weight, decentralised trust and authorisation management
2    Copyright (C) 2008-2009  Guus Sliepen <guus@tinc-vpn.org>
3   
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2 of the License, or
7    (at your option) any later version.
8    
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13    
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include <getopt.h>
19 #include <sysexits.h>
20 #include <iostream>
21 #include <fstream>
22
23 #include "fides.h"
24
25 using namespace std;
26
27 static void help(ostream &out, const string &argv0) {
28         out << "Usage: " << argv0 << "<command> [arguments]\n"
29         "\n"
30         "Available commands are:\n"
31         "\n"
32         "  init      Initialise fides, generate a public/private keypair.\n"
33         "  version   Show version and copyright information.\n"
34         "  help      Show this help message.\n"
35         "\n"
36         "  trust <keyid>\n"
37         "            Trust allow/deny packets signed by the specified key.\n"
38         "  distrust <keyid>\n"
39         "            Distrust allow/deny packets signed by the specified key.\n"
40         "  dctrust <keyid>\n"
41         "            Don't care about allow/deny packets signed by the specified key.\n"
42         "  is_trusted <keyid>\n"
43         "            Returns 0 if key is trusted, 1 otherwise\n"
44         "  is_distrusted <keyid>\n"
45         "            Returns 0 if key is distrusted, 1 otherwise\n"
46         "\n"
47         "  sign <stuff ...>\n"
48         "            Sign stuff.\n"
49         "  allow <stuff ...>\n"
50         "            Allow stuff.\n"
51         "  deny <stuff ...> \n"
52         "            Deny stuff.\n"
53         "  dontcare <stuff ...> \n"
54         "            Don't care about stuff.\n"
55         "  is_allowed <stuff ...>\n"
56         "            Returns 0 if stuff is allowed, 1 otherwise\n"
57         "  is_denied <stuff ...>\n"
58         "            Returns 0 if stuff is denied, 1 otherwise\n"
59         "\n"
60         "  import [filename]\n"
61         "            Import keys and certificates from file, or stdin if unspecified.\n"
62         "  export [filename]\n"
63         "            Export keys and certificates to file, or stdout if unspecified.\n"
64         "  test <stuff ...>\n"
65         "            Tell whether stuff is allowed or not by counting relevant certificates\n"
66         "  find <regexp>\n"
67         "            Find all certificates matching regexp\n"
68         "  fsck      Verify the signature on all information collected.\n";
69 }
70
71 static void version(ostream &out = cout) {
72         out << "fides version 0.1\n"
73         "Copyright (c) 2008-2009 Guus Sliepen <guus@tinc-vpn.org>\n"
74         "\n"
75         "This program is free software; you can redistribute it and/or modify\n"
76         "it under the terms of the GNU General Public License as published by\n"
77         "the Free Software Foundation; either version 2 of the License, or\n"
78         "(at your option) any later version.\n";
79 }
80
81 static int init() {
82         fides fides;
83         if(fides.is_firstrun()) {
84                 cout << "New keys generated in " << fides.get_homedir() << '\n';
85         } else {
86                 cout << "Fides already initialised\n";
87         }
88         return 0;
89 }
90
91 static int is_trusted(int argc, char *const argv[]) {
92         if(argc < 1)
93                 return EX_USAGE;
94
95         fides fides;
96         fides::publickey *key = fides.find_key(fides::hexdecode(argv[0]));
97         if(!key) {
98                 cerr << "Unknown key!\n";
99                 return 1;
100         }
101         return fides.is_trusted(key) ? 0 : 1;
102 }
103
104 static int is_distrusted(int argc, char *const argv[]) {
105         if(argc < 1)
106                 return EX_USAGE;
107
108         fides fides;
109         fides::publickey *key = fides.find_key(fides::hexdecode(argv[0]));
110         if(!key) {
111                 cerr << "Unknown key!\n";
112                 return 1;
113         }
114         return fides.is_distrusted(key) ? 0 : 1;
115 }
116
117 static int trust(int argc, char *const argv[]) {
118         if(argc < 1)
119                 return EX_USAGE;
120
121         fides fides;
122         fides::publickey *key = fides.find_key(fides::hexdecode(argv[0]));
123         if(key)
124                 fides.trust(key);
125         else {
126                 cerr << "Unknown key!\n";
127                 return -1;
128         }
129         return 0;
130 }
131
132 static int dctrust(int argc, char *const argv[]) {
133         if(argc < 1)
134                 return EX_USAGE;
135
136         fides fides;
137         fides::publickey *key = fides.find_key(fides::hexdecode(argv[0]));
138         if(key)
139                 fides.dctrust(key);
140         else {
141                 cerr << "Unknown key!\n";
142                 return -1;
143         }
144         return 0;
145 }
146
147 static int distrust(int argc, char *const argv[]) {
148         if(argc < 1)
149                 return EX_USAGE;
150
151         fides fides;
152         fides::publickey *key = fides.find_key(fides::hexdecode(argv[0]));
153         if(key)
154                 fides.distrust(key);
155         else {
156                 cerr << "Unknown key!\n";
157                 return -1;
158         }
159         return 0;
160 }
161
162 static int sign(int argc, char *const argv[]) {
163         if(argc < 1)
164                 return EX_USAGE;
165
166         fides fides;
167         fides.sign(argv[0]);
168         return 0;
169 }
170
171 static int allow(int argc, char *const argv[]) {
172         if(argc < 1)
173                 return EX_USAGE;
174
175         fides fides;
176         fides.allow(argv[0]);
177         return 0;
178 }
179
180 static int dontcare(int argc, char *const argv[]) {
181         if(argc < 1)
182                 return EX_USAGE;
183
184         fides fides;
185         fides.dontcare(argv[0]);
186         return 0;
187 }
188
189 static int deny(int argc, char *const argv[]) {
190         if(argc < 1)
191                 return EX_USAGE;
192
193         fides fides;
194         fides.deny(argv[0]);
195         return 0;
196 }
197
198 static int import(int argc, char *const argv[]) {
199         fides fides;
200         
201         if(argc) {
202                 ifstream in(argv[0]);
203                 fides.import_all(in);
204         } else
205                 fides.import_all(cin);
206         return 0;
207 }
208
209 static int exprt(int argc, char *const argv[]) {
210         fides fides;
211
212         if(argc) {
213                 ofstream out(argv[0]);
214                 fides.export_all(out);
215         } else
216                 fides.export_all(cout);
217         return 0;
218 }
219
220 static int find(int argc, char *const argv[]) {
221         if(argc < 1)
222                 return EX_USAGE;
223
224         // Find certificates matching statement
225         fides fides;
226         const vector<const fides::certificate *> &certs = fides.find_certificates(argv[0]);
227         for(size_t i = 0; i < certs.size(); ++i)
228                 cout << i << ' ' << certs[i]->to_string() << '\n';
229         return 0;
230 }
231
232 static int is_allowed(int argc, char *const argv[]) {
233         if(argc < 1)
234                 return EX_USAGE;
235
236         fides fides;
237         return fides.is_allowed(argv[0]) ? 0 : 1;
238 }
239
240 static int is_denied(int argc, char *const argv[]) {
241         if(argc < 1)
242                 return EX_USAGE;
243
244         fides fides;
245         return fides.is_denied(argv[0]) ? 0 : 1;
246 }
247
248 static int test(int argc, char *const argv[]) {
249         if(argc < 1)
250                 return EX_USAGE;
251
252         fides fides;
253         int self, trusted, all;
254         fides.auth_stats(argv[0], self, trusted, all);
255         cout << "Self: " << self << ", trusted: " << trusted << ", all: " << all << '\n';
256         return 0;
257 }
258
259 static int fsck() {
260         fides fides;
261         if(fides.fsck()) {
262                 cout << "Everything OK\n";
263                 return 0;
264         } else {
265                 cout << "Integrity failure!\n";
266                 return 1;
267         }
268 }
269
270 int main(int argc, char *const argv[]) {
271         int r;
272         int option_index;
273
274         static struct option const long_options[] = {
275                 {"homedir", required_argument, NULL, 2},
276                 {"help", no_argument, NULL, 'h'},
277                 {"version", no_argument, NULL, 3},
278                 {NULL, 0, NULL, 0}
279         };
280
281         while((r = getopt_long(argc, argv, "h", long_options, &option_index)) != EOF) {
282                 switch (r) {
283                         case 0:                         /* long option */
284                                 break;
285                         case 1:                         /* non-option */
286                                 break;
287                         case 2:
288                                 //homedir = strdup(optarg);
289                                 break;
290                         case 3:
291                                 version();
292                                 return 0;
293                         case 'h':
294                                 help(cout, argv[0]);
295                                 return 0;
296                 }
297         }
298
299         if(argc < 2) {
300                 help(cerr, argv[0]);
301                 return EX_USAGE;
302         }
303
304         if(!strcmp(argv[1], "help")) {
305                 help(cout, argv[0]);
306                 return 0;
307         }
308
309         if(!strcmp(argv[1], "version")) {
310                 version();
311                 return 0;
312         }
313
314         if(!strcmp(argv[1], "init"))
315                 return init();
316
317         if(!strcmp(argv[1], "trust"))
318                 return trust(argc - 2, argv + 2);
319
320         if(!strcmp(argv[1], "dctrust"))
321                 return dctrust(argc - 2, argv + 2);
322
323         if(!strcmp(argv[1], "distrust"))
324                 return distrust(argc - 2, argv + 2);
325
326         if(!strcmp(argv[1], "is_trusted"))
327                 return is_trusted(argc - 2, argv + 2);
328
329         if(!strcmp(argv[1], "is_distrusted"))
330                 return is_distrusted(argc - 2, argv + 2);
331
332         if(!strcmp(argv[1], "is_allowed"))
333                 return is_allowed(argc - 2, argv + 2);
334
335         if(!strcmp(argv[1], "is_denied"))
336                 return is_denied(argc - 2, argv + 2);
337
338         if(!strcmp(argv[1], "allow"))
339                 return allow(argc - 2, argv + 2);
340
341         if(!strcmp(argv[1], "dontcare"))
342                 return dontcare(argc - 2, argv + 2);
343
344         if(!strcmp(argv[1], "deny"))
345                 return deny(argc - 2, argv + 2);
346
347         if(!strcmp(argv[1], "sign"))
348                 return sign(argc - 2, argv + 2);
349
350         if(!strcmp(argv[1], "import"))
351                 return import(argc - 2, argv + 2);
352
353         if(!strcmp(argv[1], "export"))
354                 return exprt(argc - 2, argv + 2);
355
356         if(!strcmp(argv[1], "test"))
357                 return test(argc - 2, argv + 2);
358
359         if(!strcmp(argv[1], "find"))
360                 return find(argc - 2, argv + 2);
361
362         if(!strcmp(argv[1], "fsck"))
363                 return fsck();
364
365         cerr << "Unknown command: " << argv[1] << '\n';
366         return EX_USAGE;
367 }