18d9bc9e0SMichael Lotz /* 28d9bc9e0SMichael Lotz * Copyright 2012, Michael Lotz, mmlr@mlotz.ch. All Rights Reserved. 38d9bc9e0SMichael Lotz * Distributed under the terms of the MIT License. 48d9bc9e0SMichael Lotz */ 58d9bc9e0SMichael Lotz 68d9bc9e0SMichael Lotz 78d9bc9e0SMichael Lotz #include "KeyStoreServer.h" 8ac9b28f0SMichael Lotz 9ac9b28f0SMichael Lotz #include "KeyRequestWindow.h" 1095eee1a3SMichael Lotz #include "Keyring.h" 118d9bc9e0SMichael Lotz 128d9bc9e0SMichael Lotz #include <KeyStoreDefs.h> 138d9bc9e0SMichael Lotz 140dfaf59dSMichael Lotz #include <Directory.h> 150dfaf59dSMichael Lotz #include <Entry.h> 160dfaf59dSMichael Lotz #include <FindDirectory.h> 170dfaf59dSMichael Lotz #include <Path.h> 180dfaf59dSMichael Lotz #include <String.h> 190dfaf59dSMichael Lotz 208d9bc9e0SMichael Lotz #include <new> 218d9bc9e0SMichael Lotz 228d9bc9e0SMichael Lotz #include <stdio.h> 238d9bc9e0SMichael Lotz 248d9bc9e0SMichael Lotz 258d9bc9e0SMichael Lotz using namespace BPrivate; 268d9bc9e0SMichael Lotz 278d9bc9e0SMichael Lotz 28f16fef70SMichael Lotz static const char* kKeyringKeysIdentifier = "Keyrings"; 29f16fef70SMichael Lotz 3097b3abf1SMichael Lotz static const uint32 kFlagGetKey = 0x0001; 3197b3abf1SMichael Lotz static const uint32 kFlagEnumerateKeys = 0x0002; 3297b3abf1SMichael Lotz static const uint32 kFlagAddKey = 0x0004; 3397b3abf1SMichael Lotz static const uint32 kFlagRemoveKey = 0x0008; 3497b3abf1SMichael Lotz static const uint32 kFlagAddKeyring = 0x0010; 3597b3abf1SMichael Lotz static const uint32 kFlagRemoveKeyring = 0x0020; 3697b3abf1SMichael Lotz static const uint32 kFlagEnumerateKeyrings = 0x0040; 3797b3abf1SMichael Lotz static const uint32 kFlagSetMasterKey = 0x0080; 3897b3abf1SMichael Lotz static const uint32 kFlagRemoveMasterKey = 0x0100; 3997b3abf1SMichael Lotz static const uint32 kFlagAddKeyringsToMaster = 0x0200; 4097b3abf1SMichael Lotz static const uint32 kFlagRemoveKeyringsFromMaster = 0x0400; 4197b3abf1SMichael Lotz static const uint32 kFlagEnumerateMasterKeyrings = 0x0800; 4297b3abf1SMichael Lotz static const uint32 kFlagQueryAccessibility = 0x1000; 4397b3abf1SMichael Lotz static const uint32 kFlagRevokeAccess = 0x2000; 4497b3abf1SMichael Lotz static const uint32 kFlagEnumerateApplications = 0x4000; 4597b3abf1SMichael Lotz static const uint32 kFlagRemoveApplications = 0x8000; 4697b3abf1SMichael Lotz 4797b3abf1SMichael Lotz static const uint32 kDefaultAppFlags = kFlagGetKey | kFlagEnumerateKeys 4897b3abf1SMichael Lotz | kFlagAddKey | kFlagRemoveKey | kFlagAddKeyring | kFlagRemoveKeyring 4997b3abf1SMichael Lotz | kFlagEnumerateKeyrings | kFlagSetMasterKey | kFlagRemoveMasterKey 5097b3abf1SMichael Lotz | kFlagAddKeyringsToMaster | kFlagRemoveKeyringsFromMaster 5197b3abf1SMichael Lotz | kFlagEnumerateMasterKeyrings | kFlagQueryAccessibility 5297b3abf1SMichael Lotz | kFlagQueryAccessibility | kFlagRevokeAccess | kFlagEnumerateApplications 5397b3abf1SMichael Lotz | kFlagRemoveApplications; 5497b3abf1SMichael Lotz 55f16fef70SMichael Lotz 568d9bc9e0SMichael Lotz KeyStoreServer::KeyStoreServer() 578d9bc9e0SMichael Lotz : 5895eee1a3SMichael Lotz BApplication(kKeyStoreServerSignature), 5995eee1a3SMichael Lotz fDefaultKeyring(NULL), 6095eee1a3SMichael Lotz fKeyrings(20, true) 618d9bc9e0SMichael Lotz { 620dfaf59dSMichael Lotz BPath path; 630dfaf59dSMichael Lotz if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) 640dfaf59dSMichael Lotz return; 650dfaf59dSMichael Lotz 660dfaf59dSMichael Lotz BDirectory settingsDir(path.Path()); 670dfaf59dSMichael Lotz path.Append("system"); 680dfaf59dSMichael Lotz if (!settingsDir.Contains(path.Path())) 690dfaf59dSMichael Lotz settingsDir.CreateDirectory(path.Path(), NULL); 700dfaf59dSMichael Lotz 710dfaf59dSMichael Lotz settingsDir.SetTo(path.Path()); 720dfaf59dSMichael Lotz path.Append("keystore"); 730dfaf59dSMichael Lotz if (!settingsDir.Contains(path.Path())) 740dfaf59dSMichael Lotz settingsDir.CreateDirectory(path.Path(), NULL); 750dfaf59dSMichael Lotz 760dfaf59dSMichael Lotz settingsDir.SetTo(path.Path()); 770dfaf59dSMichael Lotz path.Append("keystore_database"); 780dfaf59dSMichael Lotz 790dfaf59dSMichael Lotz fKeyStoreFile.SetTo(path.Path(), B_READ_WRITE 800dfaf59dSMichael Lotz | (settingsDir.Contains(path.Path()) ? 0 : B_CREATE_FILE)); 810dfaf59dSMichael Lotz 820dfaf59dSMichael Lotz _ReadKeyStoreDatabase(); 8395eee1a3SMichael Lotz 8495eee1a3SMichael Lotz if (fDefaultKeyring == NULL) 85*1b3bb46aSMichael Lotz fDefaultKeyring = new(std::nothrow) Keyring(""); 868d9bc9e0SMichael Lotz } 878d9bc9e0SMichael Lotz 888d9bc9e0SMichael Lotz 898d9bc9e0SMichael Lotz KeyStoreServer::~KeyStoreServer() 908d9bc9e0SMichael Lotz { 918d9bc9e0SMichael Lotz } 928d9bc9e0SMichael Lotz 938d9bc9e0SMichael Lotz 948d9bc9e0SMichael Lotz void 958d9bc9e0SMichael Lotz KeyStoreServer::MessageReceived(BMessage* message) 968d9bc9e0SMichael Lotz { 970dfaf59dSMichael Lotz BMessage reply; 9895eee1a3SMichael Lotz status_t result = B_UNSUPPORTED; 9995eee1a3SMichael Lotz 10095eee1a3SMichael Lotz // Resolve the keyring for the relevant messages. 10195eee1a3SMichael Lotz Keyring* keyring = NULL; 10295eee1a3SMichael Lotz switch (message->what) { 10395eee1a3SMichael Lotz case KEY_STORE_GET_KEY: 10495eee1a3SMichael Lotz case KEY_STORE_GET_NEXT_KEY: 10595eee1a3SMichael Lotz case KEY_STORE_ADD_KEY: 10695eee1a3SMichael Lotz case KEY_STORE_REMOVE_KEY: 10795eee1a3SMichael Lotz case KEY_STORE_IS_KEYRING_ACCESSIBLE: 10895eee1a3SMichael Lotz case KEY_STORE_REVOKE_ACCESS: 109f16fef70SMichael Lotz case KEY_STORE_ADD_KEYRING_TO_MASTER: 110f16fef70SMichael Lotz case KEY_STORE_REMOVE_KEYRING_FROM_MASTER: 11195eee1a3SMichael Lotz { 11295eee1a3SMichael Lotz BString keyringName; 11395eee1a3SMichael Lotz if (message->FindString("keyring", &keyringName) != B_OK) 11495eee1a3SMichael Lotz keyringName = ""; 11595eee1a3SMichael Lotz 11695eee1a3SMichael Lotz keyring = _FindKeyring(keyringName); 11795eee1a3SMichael Lotz if (keyring == NULL) { 11895eee1a3SMichael Lotz result = B_BAD_VALUE; 11995eee1a3SMichael Lotz message->what = 0; 12095eee1a3SMichael Lotz // So that we don't do anything in the second switch. 12195eee1a3SMichael Lotz break; 12295eee1a3SMichael Lotz } 12395eee1a3SMichael Lotz 124ac9b28f0SMichael Lotz switch (message->what) { 125ac9b28f0SMichael Lotz case KEY_STORE_GET_KEY: 126ac9b28f0SMichael Lotz case KEY_STORE_GET_NEXT_KEY: 127ac9b28f0SMichael Lotz case KEY_STORE_ADD_KEY: 128ac9b28f0SMichael Lotz case KEY_STORE_REMOVE_KEY: 129f16fef70SMichael Lotz case KEY_STORE_ADD_KEYRING_TO_MASTER: 130ac9b28f0SMichael Lotz { 131ac9b28f0SMichael Lotz // These need keyring access to do anything. 132ac9b28f0SMichael Lotz while (!keyring->IsAccessible()) { 133ac9b28f0SMichael Lotz status_t accessResult = _AccessKeyring(*keyring); 134ac9b28f0SMichael Lotz if (accessResult != B_OK) { 135ac9b28f0SMichael Lotz result = accessResult; 136ac9b28f0SMichael Lotz message->what = 0; 137ac9b28f0SMichael Lotz break; 138ac9b28f0SMichael Lotz } 139ac9b28f0SMichael Lotz } 140ac9b28f0SMichael Lotz } 141ac9b28f0SMichael Lotz } 142ac9b28f0SMichael Lotz 14395eee1a3SMichael Lotz break; 14495eee1a3SMichael Lotz } 14595eee1a3SMichael Lotz } 1460dfaf59dSMichael Lotz 1478d9bc9e0SMichael Lotz switch (message->what) { 1488d9bc9e0SMichael Lotz case KEY_STORE_GET_KEY: 1498d9bc9e0SMichael Lotz { 15095eee1a3SMichael Lotz BString identifier; 15195eee1a3SMichael Lotz if (message->FindString("identifier", &identifier) != B_OK) { 15295eee1a3SMichael Lotz result = B_BAD_VALUE; 15395eee1a3SMichael Lotz break; 15495eee1a3SMichael Lotz } 15595eee1a3SMichael Lotz 15695eee1a3SMichael Lotz bool secondaryIdentifierOptional; 15795eee1a3SMichael Lotz if (message->FindBool("secondaryIdentifierOptional", 15895eee1a3SMichael Lotz &secondaryIdentifierOptional) != B_OK) { 15995eee1a3SMichael Lotz secondaryIdentifierOptional = false; 16095eee1a3SMichael Lotz } 16195eee1a3SMichael Lotz 16295eee1a3SMichael Lotz BString secondaryIdentifier; 16395eee1a3SMichael Lotz if (message->FindString("secondaryIdentifier", 16495eee1a3SMichael Lotz &secondaryIdentifier) != B_OK) { 16595eee1a3SMichael Lotz secondaryIdentifier = ""; 16695eee1a3SMichael Lotz secondaryIdentifierOptional = true; 16795eee1a3SMichael Lotz } 16895eee1a3SMichael Lotz 16995eee1a3SMichael Lotz BMessage keyMessage; 17095eee1a3SMichael Lotz result = keyring->FindKey(identifier, secondaryIdentifier, 17195eee1a3SMichael Lotz secondaryIdentifierOptional, &keyMessage); 17295eee1a3SMichael Lotz if (result == B_OK) 17395eee1a3SMichael Lotz reply.AddMessage("key", &keyMessage); 174f16fef70SMichael Lotz 1758d9bc9e0SMichael Lotz break; 1768d9bc9e0SMichael Lotz } 1778d9bc9e0SMichael Lotz 1788d9bc9e0SMichael Lotz case KEY_STORE_GET_NEXT_KEY: 1798d9bc9e0SMichael Lotz { 1800dfaf59dSMichael Lotz BKeyType type; 1810dfaf59dSMichael Lotz BKeyPurpose purpose; 1820dfaf59dSMichael Lotz uint32 cookie; 1830dfaf59dSMichael Lotz if (message->FindUInt32("type", (uint32*)&type) != B_OK 1840dfaf59dSMichael Lotz || message->FindUInt32("purpose", (uint32*)&purpose) != B_OK 1850dfaf59dSMichael Lotz || message->FindUInt32("cookie", &cookie) != B_OK) { 1860dfaf59dSMichael Lotz result = B_BAD_VALUE; 1870dfaf59dSMichael Lotz break; 1880dfaf59dSMichael Lotz } 1890dfaf59dSMichael Lotz 1900dfaf59dSMichael Lotz BMessage keyMessage; 19195eee1a3SMichael Lotz result = keyring->FindKey(type, purpose, cookie, keyMessage); 1920dfaf59dSMichael Lotz if (result == B_OK) { 1930dfaf59dSMichael Lotz cookie++; 1940dfaf59dSMichael Lotz reply.AddUInt32("cookie", cookie); 1950dfaf59dSMichael Lotz reply.AddMessage("key", &keyMessage); 1960dfaf59dSMichael Lotz } 1970dfaf59dSMichael Lotz 1980dfaf59dSMichael Lotz break; 1990dfaf59dSMichael Lotz } 2000dfaf59dSMichael Lotz 2010dfaf59dSMichael Lotz case KEY_STORE_ADD_KEY: 2020dfaf59dSMichael Lotz { 2030dfaf59dSMichael Lotz BMessage keyMessage; 2040dfaf59dSMichael Lotz BString identifier; 2050dfaf59dSMichael Lotz if (message->FindMessage("key", &keyMessage) != B_OK 2060dfaf59dSMichael Lotz || keyMessage.FindString("identifier", &identifier) != B_OK) { 2070dfaf59dSMichael Lotz result = B_BAD_VALUE; 2080dfaf59dSMichael Lotz break; 2090dfaf59dSMichael Lotz } 2100dfaf59dSMichael Lotz 2110dfaf59dSMichael Lotz BString secondaryIdentifier; 2120dfaf59dSMichael Lotz if (keyMessage.FindString("secondaryIdentifier", 2130dfaf59dSMichael Lotz &secondaryIdentifier) != B_OK) { 2140dfaf59dSMichael Lotz secondaryIdentifier = ""; 2150dfaf59dSMichael Lotz } 2160dfaf59dSMichael Lotz 21795eee1a3SMichael Lotz result = keyring->AddKey(identifier, secondaryIdentifier, keyMessage); 21895eee1a3SMichael Lotz if (result == B_OK) 21995eee1a3SMichael Lotz _WriteKeyStoreDatabase(); 22095eee1a3SMichael Lotz 22195eee1a3SMichael Lotz break; 22295eee1a3SMichael Lotz } 22395eee1a3SMichael Lotz 22495eee1a3SMichael Lotz case KEY_STORE_REMOVE_KEY: 22595eee1a3SMichael Lotz { 22695eee1a3SMichael Lotz BMessage keyMessage; 22795eee1a3SMichael Lotz BString identifier; 22895eee1a3SMichael Lotz if (message->FindMessage("key", &keyMessage) != B_OK 22995eee1a3SMichael Lotz || keyMessage.FindString("identifier", &identifier) != B_OK) { 23095eee1a3SMichael Lotz result = B_BAD_VALUE; 23195eee1a3SMichael Lotz break; 23295eee1a3SMichael Lotz } 23395eee1a3SMichael Lotz 23495eee1a3SMichael Lotz result = keyring->RemoveKey(identifier, keyMessage); 23595eee1a3SMichael Lotz if (result == B_OK) 23695eee1a3SMichael Lotz _WriteKeyStoreDatabase(); 23795eee1a3SMichael Lotz 23895eee1a3SMichael Lotz break; 23995eee1a3SMichael Lotz } 24095eee1a3SMichael Lotz 24195eee1a3SMichael Lotz case KEY_STORE_ADD_KEYRING: 24295eee1a3SMichael Lotz { 24395eee1a3SMichael Lotz BMessage keyMessage; 24495eee1a3SMichael Lotz BString keyring; 24595eee1a3SMichael Lotz if (message->FindString("keyring", &keyring) != B_OK 24695eee1a3SMichael Lotz || message->FindMessage("key", &keyMessage) != B_OK) { 24795eee1a3SMichael Lotz result = B_BAD_VALUE; 24895eee1a3SMichael Lotz break; 24995eee1a3SMichael Lotz } 25095eee1a3SMichael Lotz 25195eee1a3SMichael Lotz result = _AddKeyring(keyring, keyMessage); 25295eee1a3SMichael Lotz if (result == B_OK) 25395eee1a3SMichael Lotz _WriteKeyStoreDatabase(); 25495eee1a3SMichael Lotz 25595eee1a3SMichael Lotz break; 25695eee1a3SMichael Lotz } 25795eee1a3SMichael Lotz 25895eee1a3SMichael Lotz case KEY_STORE_REMOVE_KEYRING: 25995eee1a3SMichael Lotz { 26095eee1a3SMichael Lotz BString keyringName; 26195eee1a3SMichael Lotz if (message->FindString("keyring", &keyringName) != B_OK) 26295eee1a3SMichael Lotz keyringName = ""; 26395eee1a3SMichael Lotz 26495eee1a3SMichael Lotz result = _RemoveKeyring(keyringName); 26595eee1a3SMichael Lotz if (result == B_OK) 26695eee1a3SMichael Lotz _WriteKeyStoreDatabase(); 26795eee1a3SMichael Lotz 26895eee1a3SMichael Lotz break; 26995eee1a3SMichael Lotz } 27095eee1a3SMichael Lotz 27195eee1a3SMichael Lotz case KEY_STORE_GET_NEXT_KEYRING: 27295eee1a3SMichael Lotz { 27395eee1a3SMichael Lotz uint32 cookie; 27495eee1a3SMichael Lotz if (message->FindUInt32("cookie", &cookie) != B_OK) { 27595eee1a3SMichael Lotz result = B_BAD_VALUE; 27695eee1a3SMichael Lotz break; 27795eee1a3SMichael Lotz } 27895eee1a3SMichael Lotz 27995eee1a3SMichael Lotz if (cookie == 0) 28095eee1a3SMichael Lotz keyring = fDefaultKeyring; 28195eee1a3SMichael Lotz else 28295eee1a3SMichael Lotz keyring = fKeyrings.ItemAt(cookie - 1); 28395eee1a3SMichael Lotz 28495eee1a3SMichael Lotz if (keyring == NULL) { 28595eee1a3SMichael Lotz result = B_ENTRY_NOT_FOUND; 28695eee1a3SMichael Lotz break; 28795eee1a3SMichael Lotz } 28895eee1a3SMichael Lotz 28995eee1a3SMichael Lotz cookie++; 29095eee1a3SMichael Lotz reply.AddUInt32("cookie", cookie); 29195eee1a3SMichael Lotz reply.AddString("keyring", keyring->Name()); 29295eee1a3SMichael Lotz result = B_OK; 29395eee1a3SMichael Lotz break; 29495eee1a3SMichael Lotz } 29595eee1a3SMichael Lotz 29695eee1a3SMichael Lotz case KEY_STORE_IS_KEYRING_ACCESSIBLE: 29795eee1a3SMichael Lotz { 29895eee1a3SMichael Lotz reply.AddBool("accessible", keyring->IsAccessible()); 29995eee1a3SMichael Lotz result = B_OK; 300f16fef70SMichael Lotz break; 30195eee1a3SMichael Lotz } 30295eee1a3SMichael Lotz 303ac9b28f0SMichael Lotz case KEY_STORE_REVOKE_ACCESS: 304ac9b28f0SMichael Lotz { 305ac9b28f0SMichael Lotz keyring->RevokeAccess(); 306ac9b28f0SMichael Lotz result = B_OK; 307f16fef70SMichael Lotz break; 308f16fef70SMichael Lotz } 309f16fef70SMichael Lotz 310f16fef70SMichael Lotz case KEY_STORE_ADD_KEYRING_TO_MASTER: 311f16fef70SMichael Lotz case KEY_STORE_REMOVE_KEYRING_FROM_MASTER: 312f16fef70SMichael Lotz { 313f16fef70SMichael Lotz // We also need access to the default keyring. 314f16fef70SMichael Lotz while (!fDefaultKeyring->IsAccessible()) { 315f16fef70SMichael Lotz status_t accessResult = _AccessKeyring(*fDefaultKeyring); 316f16fef70SMichael Lotz if (accessResult != B_OK) { 317f16fef70SMichael Lotz result = accessResult; 318f16fef70SMichael Lotz message->what = 0; 319f16fef70SMichael Lotz break; 320f16fef70SMichael Lotz } 321f16fef70SMichael Lotz } 322f16fef70SMichael Lotz 323f16fef70SMichael Lotz if (message->what == 0) 324f16fef70SMichael Lotz break; 325f16fef70SMichael Lotz 326f16fef70SMichael Lotz BString secondaryIdentifier = keyring->Name(); 327f16fef70SMichael Lotz BMessage keyMessage = keyring->KeyMessage(); 328f16fef70SMichael Lotz keyMessage.RemoveName("identifier"); 329f16fef70SMichael Lotz keyMessage.AddString("identifier", kKeyringKeysIdentifier); 330f16fef70SMichael Lotz keyMessage.RemoveName("secondaryIdentifier"); 331f16fef70SMichael Lotz keyMessage.AddString("secondaryIdentifier", secondaryIdentifier); 332f16fef70SMichael Lotz 333f16fef70SMichael Lotz switch (message->what) { 334f16fef70SMichael Lotz case KEY_STORE_ADD_KEYRING_TO_MASTER: 335f16fef70SMichael Lotz result = fDefaultKeyring->AddKey(kKeyringKeysIdentifier, 336f16fef70SMichael Lotz secondaryIdentifier, keyMessage); 337f16fef70SMichael Lotz break; 338f16fef70SMichael Lotz 339f16fef70SMichael Lotz case KEY_STORE_REMOVE_KEYRING_FROM_MASTER: 340f16fef70SMichael Lotz result = fDefaultKeyring->RemoveKey(kKeyringKeysIdentifier, 341f16fef70SMichael Lotz keyMessage); 342f16fef70SMichael Lotz break; 343f16fef70SMichael Lotz } 344f16fef70SMichael Lotz 345f16fef70SMichael Lotz if (result == B_OK) 346f16fef70SMichael Lotz _WriteKeyStoreDatabase(); 347f16fef70SMichael Lotz 348f16fef70SMichael Lotz break; 349ac9b28f0SMichael Lotz } 350ac9b28f0SMichael Lotz 35195eee1a3SMichael Lotz case 0: 35295eee1a3SMichael Lotz { 35395eee1a3SMichael Lotz // Just the error case from above. 3548d9bc9e0SMichael Lotz break; 3558d9bc9e0SMichael Lotz } 3568d9bc9e0SMichael Lotz 3578d9bc9e0SMichael Lotz default: 3588d9bc9e0SMichael Lotz { 3598d9bc9e0SMichael Lotz printf("unknown message received: %" B_PRIu32 " \"%.4s\"\n", 3608d9bc9e0SMichael Lotz message->what, (const char*)&message->what); 3618d9bc9e0SMichael Lotz break; 3628d9bc9e0SMichael Lotz } 3638d9bc9e0SMichael Lotz } 3648d9bc9e0SMichael Lotz 3650dfaf59dSMichael Lotz if (message->IsSourceWaiting()) { 3660dfaf59dSMichael Lotz if (result == B_OK) 3670dfaf59dSMichael Lotz reply.what = KEY_STORE_SUCCESS; 3680dfaf59dSMichael Lotz else { 3690dfaf59dSMichael Lotz reply.what = KEY_STORE_RESULT; 3700dfaf59dSMichael Lotz reply.AddInt32("result", result); 3710dfaf59dSMichael Lotz } 3720dfaf59dSMichael Lotz 3730dfaf59dSMichael Lotz message->SendReply(&reply); 3740dfaf59dSMichael Lotz } 3758d9bc9e0SMichael Lotz } 3768d9bc9e0SMichael Lotz 3778d9bc9e0SMichael Lotz 3788d9bc9e0SMichael Lotz status_t 3790dfaf59dSMichael Lotz KeyStoreServer::_ReadKeyStoreDatabase() 3808d9bc9e0SMichael Lotz { 38195eee1a3SMichael Lotz BMessage keyrings; 38295eee1a3SMichael Lotz status_t result = keyrings.Unflatten(&fKeyStoreFile); 3830dfaf59dSMichael Lotz if (result != B_OK) { 3840dfaf59dSMichael Lotz printf("failed to read keystore database\n"); 3850dfaf59dSMichael Lotz _WriteKeyStoreDatabase(); 3860dfaf59dSMichael Lotz return result; 3870dfaf59dSMichael Lotz } 3880dfaf59dSMichael Lotz 38995eee1a3SMichael Lotz int32 index = 0; 39095eee1a3SMichael Lotz char* keyringName = NULL; 391*1b3bb46aSMichael Lotz while (keyrings.GetInfo(B_RAW_TYPE, index++, &keyringName, NULL) == B_OK) { 392*1b3bb46aSMichael Lotz Keyring* keyring = new(std::nothrow) Keyring(keyringName); 393*1b3bb46aSMichael Lotz if (keyring == NULL) { 394*1b3bb46aSMichael Lotz printf("no memory for allocating keyring \"%s\"\n", keyringName); 39595eee1a3SMichael Lotz continue; 39695eee1a3SMichael Lotz } 39795eee1a3SMichael Lotz 398*1b3bb46aSMichael Lotz status_t result = keyring->ReadFromMessage(keyrings); 399*1b3bb46aSMichael Lotz if (result != B_OK) { 400*1b3bb46aSMichael Lotz printf("failed to read keyring \"%s\" from data\n", keyringName); 401*1b3bb46aSMichael Lotz delete keyring; 40295eee1a3SMichael Lotz continue; 40395eee1a3SMichael Lotz } 40495eee1a3SMichael Lotz 40595eee1a3SMichael Lotz if (strlen(keyringName) == 0) 40695eee1a3SMichael Lotz fDefaultKeyring = keyring; 40795eee1a3SMichael Lotz else 40895eee1a3SMichael Lotz fKeyrings.BinaryInsert(keyring, &Keyring::Compare); 40995eee1a3SMichael Lotz } 41095eee1a3SMichael Lotz 4110dfaf59dSMichael Lotz return B_OK; 4120dfaf59dSMichael Lotz } 4130dfaf59dSMichael Lotz 4140dfaf59dSMichael Lotz 4150dfaf59dSMichael Lotz status_t 4160dfaf59dSMichael Lotz KeyStoreServer::_WriteKeyStoreDatabase() 4170dfaf59dSMichael Lotz { 4180dfaf59dSMichael Lotz fKeyStoreFile.SetSize(0); 4190dfaf59dSMichael Lotz fKeyStoreFile.Seek(0, SEEK_SET); 4200dfaf59dSMichael Lotz 42195eee1a3SMichael Lotz BMessage keyrings; 42295eee1a3SMichael Lotz if (fDefaultKeyring != NULL) 423*1b3bb46aSMichael Lotz fDefaultKeyring->WriteToMessage(keyrings); 4240dfaf59dSMichael Lotz 42595eee1a3SMichael Lotz for (int32 i = 0; i < fKeyrings.CountItems(); i++) { 42695eee1a3SMichael Lotz Keyring* keyring = fKeyrings.ItemAt(i); 42795eee1a3SMichael Lotz if (keyring == NULL) 4280dfaf59dSMichael Lotz continue; 42995eee1a3SMichael Lotz 430*1b3bb46aSMichael Lotz status_t result = keyring->WriteToMessage(keyrings); 431*1b3bb46aSMichael Lotz if (result != B_OK) 432*1b3bb46aSMichael Lotz return result; 4330dfaf59dSMichael Lotz } 4340dfaf59dSMichael Lotz 43595eee1a3SMichael Lotz return keyrings.Flatten(&fKeyStoreFile); 4360dfaf59dSMichael Lotz } 4370dfaf59dSMichael Lotz 4380dfaf59dSMichael Lotz 43997b3abf1SMichael Lotz uint32 44097b3abf1SMichael Lotz KeyStoreServer::_AccessFlagsFor(uint32 command) const 44197b3abf1SMichael Lotz { 44297b3abf1SMichael Lotz switch (command) { 44397b3abf1SMichael Lotz case KEY_STORE_GET_KEY: 44497b3abf1SMichael Lotz return kFlagGetKey; 44597b3abf1SMichael Lotz case KEY_STORE_GET_NEXT_KEY: 44697b3abf1SMichael Lotz return kFlagEnumerateKeys; 44797b3abf1SMichael Lotz case KEY_STORE_ADD_KEY: 44897b3abf1SMichael Lotz return kFlagAddKey; 44997b3abf1SMichael Lotz case KEY_STORE_REMOVE_KEY: 45097b3abf1SMichael Lotz return kFlagRemoveKey; 45197b3abf1SMichael Lotz case KEY_STORE_ADD_KEYRING: 45297b3abf1SMichael Lotz return kFlagAddKeyring; 45397b3abf1SMichael Lotz case KEY_STORE_REMOVE_KEYRING: 45497b3abf1SMichael Lotz return kFlagRemoveKeyring; 45597b3abf1SMichael Lotz case KEY_STORE_GET_NEXT_KEYRING: 45697b3abf1SMichael Lotz return kFlagEnumerateKeyrings; 45797b3abf1SMichael Lotz case KEY_STORE_SET_MASTER_KEY: 45897b3abf1SMichael Lotz return kFlagSetMasterKey; 45997b3abf1SMichael Lotz case KEY_STORE_REMOVE_MASTER_KEY: 46097b3abf1SMichael Lotz return kFlagRemoveMasterKey; 46197b3abf1SMichael Lotz case KEY_STORE_ADD_KEYRING_TO_MASTER: 46297b3abf1SMichael Lotz return kFlagAddKeyringsToMaster; 46397b3abf1SMichael Lotz case KEY_STORE_REMOVE_KEYRING_FROM_MASTER: 46497b3abf1SMichael Lotz return kFlagRemoveKeyringsFromMaster; 46597b3abf1SMichael Lotz case KEY_STORE_GET_NEXT_MASTER_KEYRING: 46697b3abf1SMichael Lotz return kFlagEnumerateMasterKeyrings; 46797b3abf1SMichael Lotz case KEY_STORE_IS_KEYRING_ACCESSIBLE: 46897b3abf1SMichael Lotz return kFlagQueryAccessibility; 46997b3abf1SMichael Lotz case KEY_STORE_REVOKE_ACCESS: 47097b3abf1SMichael Lotz return kFlagRevokeAccess; 47197b3abf1SMichael Lotz case KEY_STORE_GET_NEXT_APPLICATION: 47297b3abf1SMichael Lotz return kFlagEnumerateApplications; 47397b3abf1SMichael Lotz case KEY_STORE_REMOVE_APPLICATION: 47497b3abf1SMichael Lotz return kFlagRemoveApplications; 47597b3abf1SMichael Lotz } 47697b3abf1SMichael Lotz 47797b3abf1SMichael Lotz return 0; 47897b3abf1SMichael Lotz } 47997b3abf1SMichael Lotz 48097b3abf1SMichael Lotz 48195eee1a3SMichael Lotz Keyring* 48295eee1a3SMichael Lotz KeyStoreServer::_FindKeyring(const BString& name) 48395eee1a3SMichael Lotz { 48495eee1a3SMichael Lotz if (name.IsEmpty()) 48595eee1a3SMichael Lotz return fDefaultKeyring; 4860dfaf59dSMichael Lotz 48795eee1a3SMichael Lotz return fKeyrings.BinarySearchByKey(name, &Keyring::Compare); 4880dfaf59dSMichael Lotz } 4890dfaf59dSMichael Lotz 4900dfaf59dSMichael Lotz 4910dfaf59dSMichael Lotz status_t 49295eee1a3SMichael Lotz KeyStoreServer::_AddKeyring(const BString& name, const BMessage& keyMessage) 4930dfaf59dSMichael Lotz { 49495eee1a3SMichael Lotz if (_FindKeyring(name) != NULL) 4950dfaf59dSMichael Lotz return B_NAME_IN_USE; 4960dfaf59dSMichael Lotz 497*1b3bb46aSMichael Lotz Keyring* keyring = new(std::nothrow) Keyring(name, &keyMessage); 49895eee1a3SMichael Lotz if (keyring == NULL) 49995eee1a3SMichael Lotz return B_NO_MEMORY; 50095eee1a3SMichael Lotz 50195eee1a3SMichael Lotz if (!fKeyrings.BinaryInsert(keyring, &Keyring::Compare)) { 50295eee1a3SMichael Lotz delete keyring; 50395eee1a3SMichael Lotz return B_ERROR; 50495eee1a3SMichael Lotz } 50595eee1a3SMichael Lotz 50695eee1a3SMichael Lotz return B_OK; 50795eee1a3SMichael Lotz } 50895eee1a3SMichael Lotz 50995eee1a3SMichael Lotz 51095eee1a3SMichael Lotz status_t 51195eee1a3SMichael Lotz KeyStoreServer::_RemoveKeyring(const BString& name) 51295eee1a3SMichael Lotz { 51395eee1a3SMichael Lotz Keyring* keyring = _FindKeyring(name); 51495eee1a3SMichael Lotz if (keyring == NULL) 51595eee1a3SMichael Lotz return B_ENTRY_NOT_FOUND; 51695eee1a3SMichael Lotz 51795eee1a3SMichael Lotz if (keyring == fDefaultKeyring) { 51895eee1a3SMichael Lotz // The default keyring can't be removed. 51995eee1a3SMichael Lotz return B_NOT_ALLOWED; 52095eee1a3SMichael Lotz } 52195eee1a3SMichael Lotz 52295eee1a3SMichael Lotz return fKeyrings.RemoveItem(keyring) ? B_OK : B_ERROR; 5238d9bc9e0SMichael Lotz } 5248d9bc9e0SMichael Lotz 5258d9bc9e0SMichael Lotz 526ac9b28f0SMichael Lotz status_t 527ac9b28f0SMichael Lotz KeyStoreServer::_AccessKeyring(Keyring& keyring) 528ac9b28f0SMichael Lotz { 529ac9b28f0SMichael Lotz // If we are accessing a keyring that has been added to master access we 530ac9b28f0SMichael Lotz // get the key from the default keyring and unlock with that. 531ac9b28f0SMichael Lotz BMessage keyMessage; 532ac9b28f0SMichael Lotz if (&keyring != fDefaultKeyring && fDefaultKeyring->IsAccessible()) { 533f16fef70SMichael Lotz if (fDefaultKeyring->FindKey(kKeyringKeysIdentifier, keyring.Name(), 534f16fef70SMichael Lotz false, &keyMessage) == B_OK) { 535ac9b28f0SMichael Lotz // We found a key for this keyring, try to access with it. 536ac9b28f0SMichael Lotz if (keyring.Access(keyMessage) == B_OK) 537ac9b28f0SMichael Lotz return B_OK; 538ac9b28f0SMichael Lotz } 539ac9b28f0SMichael Lotz } 540ac9b28f0SMichael Lotz 541ac9b28f0SMichael Lotz // No key, we need to request one from the user. 54290013c82SMichael Lotz status_t result = _RequestKey(keyring.Name(), keyMessage); 543ac9b28f0SMichael Lotz if (result != B_OK) 544ac9b28f0SMichael Lotz return result; 545ac9b28f0SMichael Lotz 546ac9b28f0SMichael Lotz return keyring.Access(keyMessage); 547ac9b28f0SMichael Lotz } 548ac9b28f0SMichael Lotz 549ac9b28f0SMichael Lotz 550ac9b28f0SMichael Lotz status_t 55190013c82SMichael Lotz KeyStoreServer::_RequestKey(const BString& keyringName, BMessage& keyMessage) 552ac9b28f0SMichael Lotz { 553ac9b28f0SMichael Lotz KeyRequestWindow* requestWindow = new(std::nothrow) KeyRequestWindow(); 554ac9b28f0SMichael Lotz if (requestWindow == NULL) 555ac9b28f0SMichael Lotz return B_NO_MEMORY; 556ac9b28f0SMichael Lotz 55790013c82SMichael Lotz return requestWindow->RequestKey(keyringName, keyMessage); 558ac9b28f0SMichael Lotz } 559ac9b28f0SMichael Lotz 560ac9b28f0SMichael Lotz 5618d9bc9e0SMichael Lotz int 5628d9bc9e0SMichael Lotz main(int argc, char* argv[]) 5638d9bc9e0SMichael Lotz { 5648d9bc9e0SMichael Lotz KeyStoreServer* app = new(std::nothrow) KeyStoreServer(); 5658d9bc9e0SMichael Lotz if (app == NULL) 5668d9bc9e0SMichael Lotz return 1; 5678d9bc9e0SMichael Lotz 5688d9bc9e0SMichael Lotz app->Run(); 5698d9bc9e0SMichael Lotz delete app; 5708d9bc9e0SMichael Lotz return 0; 5718d9bc9e0SMichael Lotz } 572