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