xref: /haiku/src/bin/keystore/keystore.cpp (revision 71452e98334eaac603bf542d159e24788a46bebb)
1 /*
2  * Copyright 2012, Haiku Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Michael Lotz, mmlr@mlotz.ch
7  */
8 
9 
10 #include <Application.h>
11 #include <KeyStore.h>
12 
13 #include <stdio.h>
14 
15 
16 int
17 add_password(const char* keyring, const char* identifier,
18 	const char* secondaryIdentifier, const char* passwordString)
19 {
20 	BKeyStore keyStore;
21 	BPasswordKey password(passwordString, B_KEY_PURPOSE_GENERIC, identifier,
22 		secondaryIdentifier);
23 
24 	status_t result = keyStore.AddKey(keyring, password);
25 	if (result != B_OK) {
26 		printf("failed to add password: %s\n", strerror(result));
27 		return 2;
28 	}
29 
30 	return 0;
31 }
32 
33 
34 int
35 remove_password(const char* keyring, const char* identifier,
36 	const char* secondaryIdentifier)
37 {
38 	BKeyStore keyStore;
39 	BPasswordKey password;
40 
41 	status_t result = keyStore.GetKey(keyring, B_KEY_TYPE_PASSWORD, identifier,
42 		secondaryIdentifier, false, password);
43 	if (result != B_OK) {
44 		printf("failed to get password \"%s\": %s\n", identifier,
45 			strerror(result));
46 		return 2;
47 	}
48 
49 	result = keyStore.RemoveKey(keyring, password);
50 	if (result != B_OK) {
51 		printf("failed to remove password: %s\n", strerror(result));
52 		return 3;
53 	}
54 
55 	return 0;
56 }
57 
58 
59 int
60 add_keyring(const char* keyring)
61 {
62 	BKeyStore keyStore;
63 
64 	status_t result = keyStore.AddKeyring(keyring);
65 	if (result != B_OK) {
66 		printf("failed to add keyring: %s\n", strerror(result));
67 		return 2;
68 	}
69 
70 	return 0;
71 }
72 
73 
74 int
75 remove_keyring(const char* keyring)
76 {
77 	BKeyStore keyStore;
78 
79 	status_t result = keyStore.RemoveKeyring(keyring);
80 	if (result != B_OK) {
81 		printf("failed to remove keyring: %s\n", strerror(result));
82 		return 2;
83 	}
84 
85 	return 0;
86 }
87 
88 
89 int
90 list_passwords(const char* keyring)
91 {
92 	BKeyStore keyStore;
93 	uint32 cookie = 0;
94 
95 	while (true) {
96 		BPasswordKey password;
97 		status_t result = keyStore.GetNextKey(keyring, B_KEY_TYPE_PASSWORD,
98 			B_KEY_PURPOSE_ANY, cookie, password);
99 		if (result == B_ENTRY_NOT_FOUND)
100 			break;
101 
102 		if (result != B_OK) {
103 			printf("failed to get next key with: %s\n", strerror(result));
104 			return 2;
105 		}
106 
107 		password.PrintToStream();
108 	}
109 
110 	return 0;
111 }
112 
113 
114 int
115 list_keyrings()
116 {
117 	BKeyStore keyStore;
118 	uint32 cookie = 0;
119 
120 	while (true) {
121 		BString keyring;
122 		status_t result = keyStore.GetNextKeyring(cookie, keyring);
123 		if (result == B_ENTRY_NOT_FOUND)
124 			break;
125 
126 		if (result != B_OK) {
127 			printf("failed to get next key with: %s\n", strerror(result));
128 			return 2;
129 		}
130 
131 		printf("keyring: \"%s\"\n", keyring.String());
132 	}
133 
134 	return 0;
135 }
136 
137 
138 int
139 show_status(const char* keyring)
140 {
141 	BKeyStore keyStore;
142 	printf("keyring \"%s\" is %slocked\n", keyring,
143 		keyStore.IsKeyringUnlocked(keyring) ? "un" : "");
144 	return 0;
145 }
146 
147 
148 int
149 lock_keyring(const char* keyring)
150 {
151 	BKeyStore keyStore;
152 	status_t result = keyStore.LockKeyring(keyring);
153 	if (result != B_OK) {
154 		printf("failed to lock keyring \"%s\": %s\n", keyring,
155 			strerror(result));
156 		return 2;
157 	}
158 
159 	return 0;
160 }
161 
162 
163 int
164 add_keyring_to_master(const char* keyring)
165 {
166 	BKeyStore keyStore;
167 	status_t result= keyStore.AddKeyringToMaster(keyring);
168 	if (result != B_OK) {
169 		printf("failed to add keyring \"%s\" to master: %s\n", keyring,
170 			strerror(result));
171 		return 2;
172 	}
173 
174 	return 0;
175 }
176 
177 
178 int
179 remove_keyring_from_master(const char* keyring)
180 {
181 	BKeyStore keyStore;
182 	status_t result= keyStore.RemoveKeyringFromMaster(keyring);
183 	if (result != B_OK) {
184 		printf("failed to remove keyring \"%s\" from master: %s\n", keyring,
185 			strerror(result));
186 		return 2;
187 	}
188 
189 	return 0;
190 }
191 
192 
193 int
194 list_applications(const char* keyring)
195 {
196 	BKeyStore keyStore;
197 	uint32 cookie = 0;
198 
199 	while (true) {
200 		BString signature;
201 		status_t result = keyStore.GetNextApplication(keyring,
202 			cookie, signature);
203 		if (result == B_ENTRY_NOT_FOUND)
204 			break;
205 
206 		if (result != B_OK) {
207 			printf("failed to get next application: %s\n", strerror(result));
208 			return 2;
209 		}
210 
211 		printf("application: \"%s\"\n", signature.String());
212 	}
213 
214 	return 0;
215 }
216 
217 
218 int
219 remove_application(const char* keyring, const char* signature)
220 {
221 	BKeyStore keyStore;
222 
223 	status_t result = keyStore.RemoveApplication(keyring, signature);
224 	if (result != B_OK) {
225 		printf("failed to remove application: %s\n", strerror(result));
226 		return 3;
227 	}
228 
229 	return 0;
230 }
231 
232 
233 int
234 set_unlock_key(const char* keyring, const char* passwordString)
235 {
236 	BKeyStore keyStore;
237 	BPasswordKey password(passwordString, B_KEY_PURPOSE_KEYRING, NULL);
238 
239 	status_t result = keyStore.SetUnlockKey(keyring, password);
240 	if (result != B_OK) {
241 		printf("failed to set unlock key: %s\n", strerror(result));
242 		return 3;
243 	}
244 
245 	return 0;
246 }
247 
248 
249 int
250 remove_unlock_key(const char* keyring)
251 {
252 	BKeyStore keyStore;
253 
254 	status_t result = keyStore.RemoveUnlockKey(keyring);
255 	if (result != B_OK) {
256 		printf("failed to remove unlock key: %s\n", strerror(result));
257 		return 3;
258 	}
259 
260 	return 0;
261 }
262 
263 
264 int
265 print_usage(const char* name)
266 {
267 	printf("usage:\n");
268 	printf("\t%s list passwords [<fromKeyring>]\n", name);
269 	printf("\t\tLists all passwords of the specified keyring or from the"
270 		" master keyring if none is supplied.\n");
271 	printf("\t%s list keyrings\n", name);
272 	printf("\t\tLists all keyrings.\n");
273 	printf("\t%s list applications [<fromKeyring>]\n", name);
274 	printf("\t\tLists the applications that have been granted permanent access"
275 		" to a keyring once it is unlocked.\n\n");
276 
277 	printf("\t%s add password <identifier> [<secondaryIdentifier>] <password>"
278 		"\n", name);
279 	printf("\t\tAdds the specified password to the master keyring.\n");
280 	printf("\t%s add password to <keyring> <identifier> [<secondaryIdentifier>]"
281 		" <password>\n", name);
282 	printf("\t\tAdds the specified password to the specified keyring.\n\n");
283 
284 	printf("\t%s remove password <identifier> [<secondaryIdentifier>]\n", name);
285 	printf("\t\tRemoves the specified password from the master keyring.\n");
286 	printf("\t%s remove password from <keyring> <identifier>"
287 		" [<secondaryIdentifier>]\n", name);
288 	printf("\t\tRemoves the specified password from the specified keyring.\n\n");
289 
290 	printf("\t%s add keyring <name>\n", name);
291 	printf("\t\tAdds a new keyring with the specified name.\n");
292 	printf("\t%s remove keyring <name>\n", name);
293 	printf("\t\tRemoves the specified keyring.\n\n");
294 
295 	printf("\t%s status [<keyring>]\n", name);
296 	printf("\t\tShows the lock state of the specified keyring, or the"
297 		" master keyring if none is supplied.\n\n");
298 
299 	printf("\t%s lock [<keyring>]\n", name);
300 	printf("\t\tLock the specified keyring, or the master keyring if none is"
301 		" supplied.\n\n");
302 
303 	printf("\t%s master add <keyring>\n", name);
304 	printf("\t\tAdd the access key for the specified keyring to the master"
305 		" keyring.\n");
306 
307 	printf("\t%s master remove <keyring>\n", name);
308 	printf("\t\tRemove the access key for the specified keyring from the"
309 		" master keyring.\n\n");
310 
311 	printf("\t%s remove application <signature>\n", name);
312 	printf("\t\tRemove permanent access for the application with the given"
313 		" signature from the master keyring.\n");
314 	printf("\t%s remove application from <keyring> <signature>\n", name);
315 	printf("\t\tRemove permanent access for the application with the given"
316 		" signature from the specified keyring.\n\n");
317 
318 	printf("\t%s key set <keyring> <password>\n", name);
319 	printf("\t\tSet the unlock key of the specified keyring to the given"
320 		" password.\n");
321 	printf("\t%s key remove <keyring>\n", name);
322 	printf("\t\tRemove the unlock key of the specified keyring.\n");
323 	return 1;
324 }
325 
326 
327 int
328 main(int argc, char* argv[])
329 {
330 	BApplication app("application/x-vnd.Haiku-keystore-cli");
331 
332 	if (argc < 2)
333 		return print_usage(argv[0]);
334 
335 	if (strcmp(argv[1], "list") == 0) {
336 		if (argc < 3)
337 			return print_usage(argv[0]);
338 
339 		if (strcmp(argv[2], "passwords") == 0)
340 			return list_passwords(argc > 3 ? argv[3] : NULL);
341 		if (strcmp(argv[2], "keyrings") == 0)
342 			return list_keyrings();
343 		if (strcmp(argv[2], "applications") == 0)
344 			return list_applications(argc > 3 ? argv[3] : NULL);
345 	} else if (strcmp(argv[1], "add") == 0) {
346 		if (argc < 3)
347 			return print_usage(argv[0]);
348 
349 		if (strcmp(argv[2], "password") == 0) {
350 			if (argc < 5)
351 				return print_usage(argv[0]);
352 
353 			const char* keyring = NULL;
354 			const char* identifier = NULL;
355 			const char* secondaryIdentifier = NULL;
356 			const char* password = NULL;
357 			if (argc >= 7 && argc <= 8 && strcmp(argv[3], "to") == 0) {
358 				keyring = argv[4];
359 				identifier = argv[5];
360 				if (argc == 7)
361 					password = argv[6];
362 				else {
363 					secondaryIdentifier = argv[6];
364 					password = argv[7];
365 				}
366 			} else if (argc <= 6) {
367 				identifier = argv[3];
368 				if (argc == 5)
369 					password = argv[4];
370 				else {
371 					secondaryIdentifier = argv[4];
372 					password = argv[5];
373 				}
374 			}
375 
376 			if (password != NULL) {
377 				return add_password(keyring, identifier, secondaryIdentifier,
378 					password);
379 			}
380 		} else if (strcmp(argv[2], "keyring") == 0) {
381 			if (argc < 4)
382 				return print_usage(argv[0]);
383 
384 			return add_keyring(argv[3]);
385 		}
386 	} else if (strcmp(argv[1], "remove") == 0) {
387 		if (argc < 3)
388 			return print_usage(argv[0]);
389 
390 		if (strcmp(argv[2], "password") == 0) {
391 			if (argc < 4)
392 				return print_usage(argv[0]);
393 
394 			const char* keyring = NULL;
395 			const char* identifier = NULL;
396 			const char* secondaryIdentifier = NULL;
397 			if (argc >= 6 && argc <= 7 && strcmp(argv[3], "from") == 0) {
398 				keyring = argv[4];
399 				identifier = argv[5];
400 				if (argc == 7)
401 					secondaryIdentifier = argv[6];
402 			} else if (argc <= 5) {
403 				identifier = argv[3];
404 				if (argc == 5)
405 					secondaryIdentifier = argv[4];
406 			}
407 
408 			if (identifier != NULL) {
409 				return remove_password(keyring, identifier,
410 					secondaryIdentifier);
411 			}
412 		} else if (strcmp(argv[2], "keyring") == 0) {
413 			if (argc == 4)
414 				return remove_keyring(argv[3]);
415 		} else if (strcmp(argv[2], "application") == 0) {
416 			const char* keyring = NULL;
417 			const char* signature = NULL;
418 			if (argc == 6 && strcmp(argv[3], "from") == 0) {
419 				keyring = argv[4];
420 				signature = argv[5];
421 			} else if (argc == 4)
422 				signature = argv[3];
423 
424 			if (signature != NULL)
425 				return remove_application(keyring, signature);
426 		}
427 	} else if (strcmp(argv[1], "status") == 0) {
428 		if (argc != 2 && argc != 3)
429 			return print_usage(argv[0]);
430 
431 		return show_status(argc == 3 ? argv[2] : "");
432 	} else if (strcmp(argv[1], "lock") == 0) {
433 		if (argc != 2 && argc != 3)
434 			return print_usage(argv[0]);
435 
436 		return lock_keyring(argc == 3 ? argv[2] : "");
437 	} else if (strcmp(argv[1], "master") == 0) {
438 		if (argc != 4)
439 			return print_usage(argv[0]);
440 
441 		if (strcmp(argv[2], "add") == 0)
442 			return add_keyring_to_master(argv[3]);
443 		if (strcmp(argv[2], "remove") == 0)
444 			return remove_keyring_from_master(argv[3]);
445 	} else if (strcmp(argv[1], "key") == 0) {
446 		if (argc < 4)
447 			return print_usage(argv[0]);
448 
449 		if (strcmp(argv[2], "set") == 0) {
450 			if (argc == 5)
451 				return set_unlock_key(argv[3], argv[4]);
452 		} else if (strcmp(argv[2], "remove") == 0) {
453 			if (argc == 4)
454 				return remove_unlock_key(argv[3]);
455 		}
456 	}
457 
458 	return print_usage(argv[0]);
459 }
460