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> 18*76df966eSMichael Lotz #include <Roster.h> 190dfaf59dSMichael Lotz #include <String.h> 200dfaf59dSMichael Lotz 218d9bc9e0SMichael Lotz #include <new> 228d9bc9e0SMichael Lotz 238d9bc9e0SMichael Lotz #include <stdio.h> 248d9bc9e0SMichael Lotz 258d9bc9e0SMichael Lotz 268d9bc9e0SMichael Lotz using namespace BPrivate; 278d9bc9e0SMichael Lotz 288d9bc9e0SMichael Lotz 29f16fef70SMichael Lotz static const char* kKeyringKeysIdentifier = "Keyrings"; 30f16fef70SMichael Lotz 3197b3abf1SMichael Lotz static const uint32 kFlagGetKey = 0x0001; 3297b3abf1SMichael Lotz static const uint32 kFlagEnumerateKeys = 0x0002; 3397b3abf1SMichael Lotz static const uint32 kFlagAddKey = 0x0004; 3497b3abf1SMichael Lotz static const uint32 kFlagRemoveKey = 0x0008; 3597b3abf1SMichael Lotz static const uint32 kFlagAddKeyring = 0x0010; 3697b3abf1SMichael Lotz static const uint32 kFlagRemoveKeyring = 0x0020; 3797b3abf1SMichael Lotz static const uint32 kFlagEnumerateKeyrings = 0x0040; 3897b3abf1SMichael Lotz static const uint32 kFlagSetMasterKey = 0x0080; 3997b3abf1SMichael Lotz static const uint32 kFlagRemoveMasterKey = 0x0100; 4097b3abf1SMichael Lotz static const uint32 kFlagAddKeyringsToMaster = 0x0200; 4197b3abf1SMichael Lotz static const uint32 kFlagRemoveKeyringsFromMaster = 0x0400; 4297b3abf1SMichael Lotz static const uint32 kFlagEnumerateMasterKeyrings = 0x0800; 4397b3abf1SMichael Lotz static const uint32 kFlagQueryAccessibility = 0x1000; 4497b3abf1SMichael Lotz static const uint32 kFlagRevokeAccess = 0x2000; 4597b3abf1SMichael Lotz static const uint32 kFlagEnumerateApplications = 0x4000; 4697b3abf1SMichael Lotz static const uint32 kFlagRemoveApplications = 0x8000; 4797b3abf1SMichael Lotz 4897b3abf1SMichael Lotz static const uint32 kDefaultAppFlags = kFlagGetKey | kFlagEnumerateKeys 4997b3abf1SMichael Lotz | kFlagAddKey | kFlagRemoveKey | kFlagAddKeyring | kFlagRemoveKeyring 5097b3abf1SMichael Lotz | kFlagEnumerateKeyrings | kFlagSetMasterKey | kFlagRemoveMasterKey 5197b3abf1SMichael Lotz | kFlagAddKeyringsToMaster | kFlagRemoveKeyringsFromMaster 5297b3abf1SMichael Lotz | kFlagEnumerateMasterKeyrings | kFlagQueryAccessibility 5397b3abf1SMichael Lotz | kFlagQueryAccessibility | kFlagRevokeAccess | kFlagEnumerateApplications 5497b3abf1SMichael Lotz | kFlagRemoveApplications; 5597b3abf1SMichael Lotz 56f16fef70SMichael Lotz 578d9bc9e0SMichael Lotz KeyStoreServer::KeyStoreServer() 588d9bc9e0SMichael Lotz : 5995eee1a3SMichael Lotz BApplication(kKeyStoreServerSignature), 6095eee1a3SMichael Lotz fDefaultKeyring(NULL), 6195eee1a3SMichael Lotz fKeyrings(20, true) 628d9bc9e0SMichael Lotz { 630dfaf59dSMichael Lotz BPath path; 640dfaf59dSMichael Lotz if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) 650dfaf59dSMichael Lotz return; 660dfaf59dSMichael Lotz 670dfaf59dSMichael Lotz BDirectory settingsDir(path.Path()); 680dfaf59dSMichael Lotz path.Append("system"); 690dfaf59dSMichael Lotz if (!settingsDir.Contains(path.Path())) 700dfaf59dSMichael Lotz settingsDir.CreateDirectory(path.Path(), NULL); 710dfaf59dSMichael Lotz 720dfaf59dSMichael Lotz settingsDir.SetTo(path.Path()); 730dfaf59dSMichael Lotz path.Append("keystore"); 740dfaf59dSMichael Lotz if (!settingsDir.Contains(path.Path())) 750dfaf59dSMichael Lotz settingsDir.CreateDirectory(path.Path(), NULL); 760dfaf59dSMichael Lotz 770dfaf59dSMichael Lotz settingsDir.SetTo(path.Path()); 780dfaf59dSMichael Lotz path.Append("keystore_database"); 790dfaf59dSMichael Lotz 800dfaf59dSMichael Lotz fKeyStoreFile.SetTo(path.Path(), B_READ_WRITE 810dfaf59dSMichael Lotz | (settingsDir.Contains(path.Path()) ? 0 : B_CREATE_FILE)); 820dfaf59dSMichael Lotz 830dfaf59dSMichael Lotz _ReadKeyStoreDatabase(); 8495eee1a3SMichael Lotz 8595eee1a3SMichael Lotz if (fDefaultKeyring == NULL) 861b3bb46aSMichael Lotz fDefaultKeyring = new(std::nothrow) Keyring(""); 878d9bc9e0SMichael Lotz } 888d9bc9e0SMichael Lotz 898d9bc9e0SMichael Lotz 908d9bc9e0SMichael Lotz KeyStoreServer::~KeyStoreServer() 918d9bc9e0SMichael Lotz { 928d9bc9e0SMichael Lotz } 938d9bc9e0SMichael Lotz 948d9bc9e0SMichael Lotz 958d9bc9e0SMichael Lotz void 968d9bc9e0SMichael Lotz KeyStoreServer::MessageReceived(BMessage* message) 978d9bc9e0SMichael Lotz { 980dfaf59dSMichael Lotz BMessage reply; 9995eee1a3SMichael Lotz status_t result = B_UNSUPPORTED; 10095eee1a3SMichael Lotz 10195eee1a3SMichael Lotz // Resolve the keyring for the relevant messages. 10295eee1a3SMichael Lotz Keyring* keyring = NULL; 10395eee1a3SMichael Lotz switch (message->what) { 10495eee1a3SMichael Lotz case KEY_STORE_GET_KEY: 10595eee1a3SMichael Lotz case KEY_STORE_GET_NEXT_KEY: 10695eee1a3SMichael Lotz case KEY_STORE_ADD_KEY: 10795eee1a3SMichael Lotz case KEY_STORE_REMOVE_KEY: 10895eee1a3SMichael Lotz case KEY_STORE_IS_KEYRING_ACCESSIBLE: 10995eee1a3SMichael Lotz case KEY_STORE_REVOKE_ACCESS: 110f16fef70SMichael Lotz case KEY_STORE_ADD_KEYRING_TO_MASTER: 111f16fef70SMichael Lotz case KEY_STORE_REMOVE_KEYRING_FROM_MASTER: 11295eee1a3SMichael Lotz { 11395eee1a3SMichael Lotz BString keyringName; 11495eee1a3SMichael Lotz if (message->FindString("keyring", &keyringName) != B_OK) 11595eee1a3SMichael Lotz keyringName = ""; 11695eee1a3SMichael Lotz 11795eee1a3SMichael Lotz keyring = _FindKeyring(keyringName); 11895eee1a3SMichael Lotz if (keyring == NULL) { 11995eee1a3SMichael Lotz result = B_BAD_VALUE; 12095eee1a3SMichael Lotz message->what = 0; 12195eee1a3SMichael Lotz // So that we don't do anything in the second switch. 12295eee1a3SMichael Lotz break; 12395eee1a3SMichael Lotz } 12495eee1a3SMichael Lotz 125ac9b28f0SMichael Lotz switch (message->what) { 126ac9b28f0SMichael Lotz case KEY_STORE_GET_KEY: 127ac9b28f0SMichael Lotz case KEY_STORE_GET_NEXT_KEY: 128ac9b28f0SMichael Lotz case KEY_STORE_ADD_KEY: 129ac9b28f0SMichael Lotz case KEY_STORE_REMOVE_KEY: 130f16fef70SMichael Lotz case KEY_STORE_ADD_KEYRING_TO_MASTER: 131ac9b28f0SMichael Lotz { 132ac9b28f0SMichael Lotz // These need keyring access to do anything. 133ac9b28f0SMichael Lotz while (!keyring->IsAccessible()) { 134ac9b28f0SMichael Lotz status_t accessResult = _AccessKeyring(*keyring); 135ac9b28f0SMichael Lotz if (accessResult != B_OK) { 136ac9b28f0SMichael Lotz result = accessResult; 137ac9b28f0SMichael Lotz message->what = 0; 138ac9b28f0SMichael Lotz break; 139ac9b28f0SMichael Lotz } 140ac9b28f0SMichael Lotz } 141ac9b28f0SMichael Lotz } 142ac9b28f0SMichael Lotz } 143ac9b28f0SMichael Lotz 14495eee1a3SMichael Lotz break; 14595eee1a3SMichael Lotz } 14695eee1a3SMichael Lotz } 1470dfaf59dSMichael Lotz 1488d9bc9e0SMichael Lotz switch (message->what) { 1498d9bc9e0SMichael Lotz case KEY_STORE_GET_KEY: 1508d9bc9e0SMichael Lotz { 15195eee1a3SMichael Lotz BString identifier; 15295eee1a3SMichael Lotz if (message->FindString("identifier", &identifier) != B_OK) { 15395eee1a3SMichael Lotz result = B_BAD_VALUE; 15495eee1a3SMichael Lotz break; 15595eee1a3SMichael Lotz } 15695eee1a3SMichael Lotz 15795eee1a3SMichael Lotz bool secondaryIdentifierOptional; 15895eee1a3SMichael Lotz if (message->FindBool("secondaryIdentifierOptional", 15995eee1a3SMichael Lotz &secondaryIdentifierOptional) != B_OK) { 16095eee1a3SMichael Lotz secondaryIdentifierOptional = false; 16195eee1a3SMichael Lotz } 16295eee1a3SMichael Lotz 16395eee1a3SMichael Lotz BString secondaryIdentifier; 16495eee1a3SMichael Lotz if (message->FindString("secondaryIdentifier", 16595eee1a3SMichael Lotz &secondaryIdentifier) != B_OK) { 16695eee1a3SMichael Lotz secondaryIdentifier = ""; 16795eee1a3SMichael Lotz secondaryIdentifierOptional = true; 16895eee1a3SMichael Lotz } 16995eee1a3SMichael Lotz 17095eee1a3SMichael Lotz BMessage keyMessage; 17195eee1a3SMichael Lotz result = keyring->FindKey(identifier, secondaryIdentifier, 17295eee1a3SMichael Lotz secondaryIdentifierOptional, &keyMessage); 17395eee1a3SMichael Lotz if (result == B_OK) 17495eee1a3SMichael Lotz reply.AddMessage("key", &keyMessage); 175f16fef70SMichael Lotz 1768d9bc9e0SMichael Lotz break; 1778d9bc9e0SMichael Lotz } 1788d9bc9e0SMichael Lotz 1798d9bc9e0SMichael Lotz case KEY_STORE_GET_NEXT_KEY: 1808d9bc9e0SMichael Lotz { 1810dfaf59dSMichael Lotz BKeyType type; 1820dfaf59dSMichael Lotz BKeyPurpose purpose; 1830dfaf59dSMichael Lotz uint32 cookie; 1840dfaf59dSMichael Lotz if (message->FindUInt32("type", (uint32*)&type) != B_OK 1850dfaf59dSMichael Lotz || message->FindUInt32("purpose", (uint32*)&purpose) != B_OK 1860dfaf59dSMichael Lotz || message->FindUInt32("cookie", &cookie) != B_OK) { 1870dfaf59dSMichael Lotz result = B_BAD_VALUE; 1880dfaf59dSMichael Lotz break; 1890dfaf59dSMichael Lotz } 1900dfaf59dSMichael Lotz 1910dfaf59dSMichael Lotz BMessage keyMessage; 19295eee1a3SMichael Lotz result = keyring->FindKey(type, purpose, cookie, keyMessage); 1930dfaf59dSMichael Lotz if (result == B_OK) { 1940dfaf59dSMichael Lotz cookie++; 1950dfaf59dSMichael Lotz reply.AddUInt32("cookie", cookie); 1960dfaf59dSMichael Lotz reply.AddMessage("key", &keyMessage); 1970dfaf59dSMichael Lotz } 1980dfaf59dSMichael Lotz 1990dfaf59dSMichael Lotz break; 2000dfaf59dSMichael Lotz } 2010dfaf59dSMichael Lotz 2020dfaf59dSMichael Lotz case KEY_STORE_ADD_KEY: 2030dfaf59dSMichael Lotz { 2040dfaf59dSMichael Lotz BMessage keyMessage; 2050dfaf59dSMichael Lotz BString identifier; 2060dfaf59dSMichael Lotz if (message->FindMessage("key", &keyMessage) != B_OK 2070dfaf59dSMichael Lotz || keyMessage.FindString("identifier", &identifier) != B_OK) { 2080dfaf59dSMichael Lotz result = B_BAD_VALUE; 2090dfaf59dSMichael Lotz break; 2100dfaf59dSMichael Lotz } 2110dfaf59dSMichael Lotz 2120dfaf59dSMichael Lotz BString secondaryIdentifier; 2130dfaf59dSMichael Lotz if (keyMessage.FindString("secondaryIdentifier", 2140dfaf59dSMichael Lotz &secondaryIdentifier) != B_OK) { 2150dfaf59dSMichael Lotz secondaryIdentifier = ""; 2160dfaf59dSMichael Lotz } 2170dfaf59dSMichael Lotz 21895eee1a3SMichael Lotz result = keyring->AddKey(identifier, secondaryIdentifier, keyMessage); 21995eee1a3SMichael Lotz if (result == B_OK) 22095eee1a3SMichael Lotz _WriteKeyStoreDatabase(); 22195eee1a3SMichael Lotz 22295eee1a3SMichael Lotz break; 22395eee1a3SMichael Lotz } 22495eee1a3SMichael Lotz 22595eee1a3SMichael Lotz case KEY_STORE_REMOVE_KEY: 22695eee1a3SMichael Lotz { 22795eee1a3SMichael Lotz BMessage keyMessage; 22895eee1a3SMichael Lotz BString identifier; 22995eee1a3SMichael Lotz if (message->FindMessage("key", &keyMessage) != B_OK 23095eee1a3SMichael Lotz || keyMessage.FindString("identifier", &identifier) != B_OK) { 23195eee1a3SMichael Lotz result = B_BAD_VALUE; 23295eee1a3SMichael Lotz break; 23395eee1a3SMichael Lotz } 23495eee1a3SMichael Lotz 23595eee1a3SMichael Lotz result = keyring->RemoveKey(identifier, keyMessage); 23695eee1a3SMichael Lotz if (result == B_OK) 23795eee1a3SMichael Lotz _WriteKeyStoreDatabase(); 23895eee1a3SMichael Lotz 23995eee1a3SMichael Lotz break; 24095eee1a3SMichael Lotz } 24195eee1a3SMichael Lotz 24295eee1a3SMichael Lotz case KEY_STORE_ADD_KEYRING: 24395eee1a3SMichael Lotz { 24495eee1a3SMichael Lotz BMessage keyMessage; 24595eee1a3SMichael Lotz BString keyring; 24695eee1a3SMichael Lotz if (message->FindString("keyring", &keyring) != B_OK 24795eee1a3SMichael Lotz || message->FindMessage("key", &keyMessage) != B_OK) { 24895eee1a3SMichael Lotz result = B_BAD_VALUE; 24995eee1a3SMichael Lotz break; 25095eee1a3SMichael Lotz } 25195eee1a3SMichael Lotz 25295eee1a3SMichael Lotz result = _AddKeyring(keyring, keyMessage); 25395eee1a3SMichael Lotz if (result == B_OK) 25495eee1a3SMichael Lotz _WriteKeyStoreDatabase(); 25595eee1a3SMichael Lotz 25695eee1a3SMichael Lotz break; 25795eee1a3SMichael Lotz } 25895eee1a3SMichael Lotz 25995eee1a3SMichael Lotz case KEY_STORE_REMOVE_KEYRING: 26095eee1a3SMichael Lotz { 26195eee1a3SMichael Lotz BString keyringName; 26295eee1a3SMichael Lotz if (message->FindString("keyring", &keyringName) != B_OK) 26395eee1a3SMichael Lotz keyringName = ""; 26495eee1a3SMichael Lotz 26595eee1a3SMichael Lotz result = _RemoveKeyring(keyringName); 26695eee1a3SMichael Lotz if (result == B_OK) 26795eee1a3SMichael Lotz _WriteKeyStoreDatabase(); 26895eee1a3SMichael Lotz 26995eee1a3SMichael Lotz break; 27095eee1a3SMichael Lotz } 27195eee1a3SMichael Lotz 27295eee1a3SMichael Lotz case KEY_STORE_GET_NEXT_KEYRING: 27395eee1a3SMichael Lotz { 27495eee1a3SMichael Lotz uint32 cookie; 27595eee1a3SMichael Lotz if (message->FindUInt32("cookie", &cookie) != B_OK) { 27695eee1a3SMichael Lotz result = B_BAD_VALUE; 27795eee1a3SMichael Lotz break; 27895eee1a3SMichael Lotz } 27995eee1a3SMichael Lotz 28095eee1a3SMichael Lotz if (cookie == 0) 28195eee1a3SMichael Lotz keyring = fDefaultKeyring; 28295eee1a3SMichael Lotz else 28395eee1a3SMichael Lotz keyring = fKeyrings.ItemAt(cookie - 1); 28495eee1a3SMichael Lotz 28595eee1a3SMichael Lotz if (keyring == NULL) { 28695eee1a3SMichael Lotz result = B_ENTRY_NOT_FOUND; 28795eee1a3SMichael Lotz break; 28895eee1a3SMichael Lotz } 28995eee1a3SMichael Lotz 29095eee1a3SMichael Lotz cookie++; 29195eee1a3SMichael Lotz reply.AddUInt32("cookie", cookie); 29295eee1a3SMichael Lotz reply.AddString("keyring", keyring->Name()); 29395eee1a3SMichael Lotz result = B_OK; 29495eee1a3SMichael Lotz break; 29595eee1a3SMichael Lotz } 29695eee1a3SMichael Lotz 29795eee1a3SMichael Lotz case KEY_STORE_IS_KEYRING_ACCESSIBLE: 29895eee1a3SMichael Lotz { 29995eee1a3SMichael Lotz reply.AddBool("accessible", keyring->IsAccessible()); 30095eee1a3SMichael Lotz result = B_OK; 301f16fef70SMichael Lotz break; 30295eee1a3SMichael Lotz } 30395eee1a3SMichael Lotz 304ac9b28f0SMichael Lotz case KEY_STORE_REVOKE_ACCESS: 305ac9b28f0SMichael Lotz { 306ac9b28f0SMichael Lotz keyring->RevokeAccess(); 307ac9b28f0SMichael Lotz result = B_OK; 308f16fef70SMichael Lotz break; 309f16fef70SMichael Lotz } 310f16fef70SMichael Lotz 311f16fef70SMichael Lotz case KEY_STORE_ADD_KEYRING_TO_MASTER: 312f16fef70SMichael Lotz case KEY_STORE_REMOVE_KEYRING_FROM_MASTER: 313f16fef70SMichael Lotz { 314f16fef70SMichael Lotz // We also need access to the default keyring. 315f16fef70SMichael Lotz while (!fDefaultKeyring->IsAccessible()) { 316f16fef70SMichael Lotz status_t accessResult = _AccessKeyring(*fDefaultKeyring); 317f16fef70SMichael Lotz if (accessResult != B_OK) { 318f16fef70SMichael Lotz result = accessResult; 319f16fef70SMichael Lotz message->what = 0; 320f16fef70SMichael Lotz break; 321f16fef70SMichael Lotz } 322f16fef70SMichael Lotz } 323f16fef70SMichael Lotz 324f16fef70SMichael Lotz if (message->what == 0) 325f16fef70SMichael Lotz break; 326f16fef70SMichael Lotz 327f16fef70SMichael Lotz BString secondaryIdentifier = keyring->Name(); 328f16fef70SMichael Lotz BMessage keyMessage = keyring->KeyMessage(); 329f16fef70SMichael Lotz keyMessage.RemoveName("identifier"); 330f16fef70SMichael Lotz keyMessage.AddString("identifier", kKeyringKeysIdentifier); 331f16fef70SMichael Lotz keyMessage.RemoveName("secondaryIdentifier"); 332f16fef70SMichael Lotz keyMessage.AddString("secondaryIdentifier", secondaryIdentifier); 333f16fef70SMichael Lotz 334f16fef70SMichael Lotz switch (message->what) { 335f16fef70SMichael Lotz case KEY_STORE_ADD_KEYRING_TO_MASTER: 336f16fef70SMichael Lotz result = fDefaultKeyring->AddKey(kKeyringKeysIdentifier, 337f16fef70SMichael Lotz secondaryIdentifier, keyMessage); 338f16fef70SMichael Lotz break; 339f16fef70SMichael Lotz 340f16fef70SMichael Lotz case KEY_STORE_REMOVE_KEYRING_FROM_MASTER: 341f16fef70SMichael Lotz result = fDefaultKeyring->RemoveKey(kKeyringKeysIdentifier, 342f16fef70SMichael Lotz keyMessage); 343f16fef70SMichael Lotz break; 344f16fef70SMichael Lotz } 345f16fef70SMichael Lotz 346f16fef70SMichael Lotz if (result == B_OK) 347f16fef70SMichael Lotz _WriteKeyStoreDatabase(); 348f16fef70SMichael Lotz 349f16fef70SMichael Lotz break; 350ac9b28f0SMichael Lotz } 351ac9b28f0SMichael Lotz 35295eee1a3SMichael Lotz case 0: 35395eee1a3SMichael Lotz { 35495eee1a3SMichael Lotz // Just the error case from above. 3558d9bc9e0SMichael Lotz break; 3568d9bc9e0SMichael Lotz } 3578d9bc9e0SMichael Lotz 3588d9bc9e0SMichael Lotz default: 3598d9bc9e0SMichael Lotz { 3608d9bc9e0SMichael Lotz printf("unknown message received: %" B_PRIu32 " \"%.4s\"\n", 3618d9bc9e0SMichael Lotz message->what, (const char*)&message->what); 3628d9bc9e0SMichael Lotz break; 3638d9bc9e0SMichael Lotz } 3648d9bc9e0SMichael Lotz } 3658d9bc9e0SMichael Lotz 3660dfaf59dSMichael Lotz if (message->IsSourceWaiting()) { 3670dfaf59dSMichael Lotz if (result == B_OK) 3680dfaf59dSMichael Lotz reply.what = KEY_STORE_SUCCESS; 3690dfaf59dSMichael Lotz else { 3700dfaf59dSMichael Lotz reply.what = KEY_STORE_RESULT; 3710dfaf59dSMichael Lotz reply.AddInt32("result", result); 3720dfaf59dSMichael Lotz } 3730dfaf59dSMichael Lotz 3740dfaf59dSMichael Lotz message->SendReply(&reply); 3750dfaf59dSMichael Lotz } 3768d9bc9e0SMichael Lotz } 3778d9bc9e0SMichael Lotz 3788d9bc9e0SMichael Lotz 3798d9bc9e0SMichael Lotz status_t 3800dfaf59dSMichael Lotz KeyStoreServer::_ReadKeyStoreDatabase() 3818d9bc9e0SMichael Lotz { 38295eee1a3SMichael Lotz BMessage keyrings; 38395eee1a3SMichael Lotz status_t result = keyrings.Unflatten(&fKeyStoreFile); 3840dfaf59dSMichael Lotz if (result != B_OK) { 3850dfaf59dSMichael Lotz printf("failed to read keystore database\n"); 3860dfaf59dSMichael Lotz _WriteKeyStoreDatabase(); 3870dfaf59dSMichael Lotz return result; 3880dfaf59dSMichael Lotz } 3890dfaf59dSMichael Lotz 39095eee1a3SMichael Lotz int32 index = 0; 39195eee1a3SMichael Lotz char* keyringName = NULL; 3921b3bb46aSMichael Lotz while (keyrings.GetInfo(B_RAW_TYPE, index++, &keyringName, NULL) == B_OK) { 3931b3bb46aSMichael Lotz Keyring* keyring = new(std::nothrow) Keyring(keyringName); 3941b3bb46aSMichael Lotz if (keyring == NULL) { 3951b3bb46aSMichael Lotz printf("no memory for allocating keyring \"%s\"\n", keyringName); 39695eee1a3SMichael Lotz continue; 39795eee1a3SMichael Lotz } 39895eee1a3SMichael Lotz 3991b3bb46aSMichael Lotz status_t result = keyring->ReadFromMessage(keyrings); 4001b3bb46aSMichael Lotz if (result != B_OK) { 4011b3bb46aSMichael Lotz printf("failed to read keyring \"%s\" from data\n", keyringName); 4021b3bb46aSMichael Lotz delete keyring; 40395eee1a3SMichael Lotz continue; 40495eee1a3SMichael Lotz } 40595eee1a3SMichael Lotz 40695eee1a3SMichael Lotz if (strlen(keyringName) == 0) 40795eee1a3SMichael Lotz fDefaultKeyring = keyring; 40895eee1a3SMichael Lotz else 40995eee1a3SMichael Lotz fKeyrings.BinaryInsert(keyring, &Keyring::Compare); 41095eee1a3SMichael Lotz } 41195eee1a3SMichael Lotz 4120dfaf59dSMichael Lotz return B_OK; 4130dfaf59dSMichael Lotz } 4140dfaf59dSMichael Lotz 4150dfaf59dSMichael Lotz 4160dfaf59dSMichael Lotz status_t 4170dfaf59dSMichael Lotz KeyStoreServer::_WriteKeyStoreDatabase() 4180dfaf59dSMichael Lotz { 41995eee1a3SMichael Lotz BMessage keyrings; 42095eee1a3SMichael Lotz if (fDefaultKeyring != NULL) 4211b3bb46aSMichael Lotz fDefaultKeyring->WriteToMessage(keyrings); 4220dfaf59dSMichael Lotz 42395eee1a3SMichael Lotz for (int32 i = 0; i < fKeyrings.CountItems(); i++) { 42495eee1a3SMichael Lotz Keyring* keyring = fKeyrings.ItemAt(i); 42595eee1a3SMichael Lotz if (keyring == NULL) 4260dfaf59dSMichael Lotz continue; 42795eee1a3SMichael Lotz 4281b3bb46aSMichael Lotz status_t result = keyring->WriteToMessage(keyrings); 4291b3bb46aSMichael Lotz if (result != B_OK) 4301b3bb46aSMichael Lotz return result; 4310dfaf59dSMichael Lotz } 4320dfaf59dSMichael Lotz 433aef629f2SMichael Lotz fKeyStoreFile.SetSize(0); 434aef629f2SMichael Lotz fKeyStoreFile.Seek(0, SEEK_SET); 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 481*76df966eSMichael Lotz status_t 482*76df966eSMichael Lotz KeyStoreServer::_ResolveCallingApp(const BMessage& message, 483*76df966eSMichael Lotz app_info& callingAppInfo) const 484*76df966eSMichael Lotz { 485*76df966eSMichael Lotz team_id callingTeam = message.ReturnAddress().Team(); 486*76df966eSMichael Lotz status_t result = be_roster->GetRunningAppInfo(callingTeam, 487*76df966eSMichael Lotz &callingAppInfo); 488*76df966eSMichael Lotz if (result != B_OK) 489*76df966eSMichael Lotz return result; 490*76df966eSMichael Lotz 491*76df966eSMichael Lotz // Do some sanity checks. 492*76df966eSMichael Lotz if (callingAppInfo.team != callingTeam) 493*76df966eSMichael Lotz return B_ERROR; 494*76df966eSMichael Lotz 495*76df966eSMichael Lotz return B_OK; 496*76df966eSMichael Lotz } 497*76df966eSMichael Lotz 498*76df966eSMichael Lotz 49995eee1a3SMichael Lotz Keyring* 50095eee1a3SMichael Lotz KeyStoreServer::_FindKeyring(const BString& name) 50195eee1a3SMichael Lotz { 50295eee1a3SMichael Lotz if (name.IsEmpty()) 50395eee1a3SMichael Lotz return fDefaultKeyring; 5040dfaf59dSMichael Lotz 50595eee1a3SMichael Lotz return fKeyrings.BinarySearchByKey(name, &Keyring::Compare); 5060dfaf59dSMichael Lotz } 5070dfaf59dSMichael Lotz 5080dfaf59dSMichael Lotz 5090dfaf59dSMichael Lotz status_t 51095eee1a3SMichael Lotz KeyStoreServer::_AddKeyring(const BString& name, const BMessage& keyMessage) 5110dfaf59dSMichael Lotz { 51295eee1a3SMichael Lotz if (_FindKeyring(name) != NULL) 5130dfaf59dSMichael Lotz return B_NAME_IN_USE; 5140dfaf59dSMichael Lotz 5151b3bb46aSMichael Lotz Keyring* keyring = new(std::nothrow) Keyring(name, &keyMessage); 51695eee1a3SMichael Lotz if (keyring == NULL) 51795eee1a3SMichael Lotz return B_NO_MEMORY; 51895eee1a3SMichael Lotz 51995eee1a3SMichael Lotz if (!fKeyrings.BinaryInsert(keyring, &Keyring::Compare)) { 52095eee1a3SMichael Lotz delete keyring; 52195eee1a3SMichael Lotz return B_ERROR; 52295eee1a3SMichael Lotz } 52395eee1a3SMichael Lotz 52495eee1a3SMichael Lotz return B_OK; 52595eee1a3SMichael Lotz } 52695eee1a3SMichael Lotz 52795eee1a3SMichael Lotz 52895eee1a3SMichael Lotz status_t 52995eee1a3SMichael Lotz KeyStoreServer::_RemoveKeyring(const BString& name) 53095eee1a3SMichael Lotz { 53195eee1a3SMichael Lotz Keyring* keyring = _FindKeyring(name); 53295eee1a3SMichael Lotz if (keyring == NULL) 53395eee1a3SMichael Lotz return B_ENTRY_NOT_FOUND; 53495eee1a3SMichael Lotz 53595eee1a3SMichael Lotz if (keyring == fDefaultKeyring) { 53695eee1a3SMichael Lotz // The default keyring can't be removed. 53795eee1a3SMichael Lotz return B_NOT_ALLOWED; 53895eee1a3SMichael Lotz } 53995eee1a3SMichael Lotz 54095eee1a3SMichael Lotz return fKeyrings.RemoveItem(keyring) ? B_OK : B_ERROR; 5418d9bc9e0SMichael Lotz } 5428d9bc9e0SMichael Lotz 5438d9bc9e0SMichael Lotz 544ac9b28f0SMichael Lotz status_t 545ac9b28f0SMichael Lotz KeyStoreServer::_AccessKeyring(Keyring& keyring) 546ac9b28f0SMichael Lotz { 547ac9b28f0SMichael Lotz // If we are accessing a keyring that has been added to master access we 548ac9b28f0SMichael Lotz // get the key from the default keyring and unlock with that. 549ac9b28f0SMichael Lotz BMessage keyMessage; 550ac9b28f0SMichael Lotz if (&keyring != fDefaultKeyring && fDefaultKeyring->IsAccessible()) { 551f16fef70SMichael Lotz if (fDefaultKeyring->FindKey(kKeyringKeysIdentifier, keyring.Name(), 552f16fef70SMichael Lotz false, &keyMessage) == B_OK) { 553ac9b28f0SMichael Lotz // We found a key for this keyring, try to access with it. 554ac9b28f0SMichael Lotz if (keyring.Access(keyMessage) == B_OK) 555ac9b28f0SMichael Lotz return B_OK; 556ac9b28f0SMichael Lotz } 557ac9b28f0SMichael Lotz } 558ac9b28f0SMichael Lotz 559ac9b28f0SMichael Lotz // No key, we need to request one from the user. 56090013c82SMichael Lotz status_t result = _RequestKey(keyring.Name(), keyMessage); 561ac9b28f0SMichael Lotz if (result != B_OK) 562ac9b28f0SMichael Lotz return result; 563ac9b28f0SMichael Lotz 564ac9b28f0SMichael Lotz return keyring.Access(keyMessage); 565ac9b28f0SMichael Lotz } 566ac9b28f0SMichael Lotz 567ac9b28f0SMichael Lotz 568ac9b28f0SMichael Lotz status_t 56990013c82SMichael Lotz KeyStoreServer::_RequestKey(const BString& keyringName, BMessage& keyMessage) 570ac9b28f0SMichael Lotz { 571ac9b28f0SMichael Lotz KeyRequestWindow* requestWindow = new(std::nothrow) KeyRequestWindow(); 572ac9b28f0SMichael Lotz if (requestWindow == NULL) 573ac9b28f0SMichael Lotz return B_NO_MEMORY; 574ac9b28f0SMichael Lotz 57590013c82SMichael Lotz return requestWindow->RequestKey(keyringName, keyMessage); 576ac9b28f0SMichael Lotz } 577ac9b28f0SMichael Lotz 578ac9b28f0SMichael Lotz 5798d9bc9e0SMichael Lotz int 5808d9bc9e0SMichael Lotz main(int argc, char* argv[]) 5818d9bc9e0SMichael Lotz { 5828d9bc9e0SMichael Lotz KeyStoreServer* app = new(std::nothrow) KeyStoreServer(); 5838d9bc9e0SMichael Lotz if (app == NULL) 5848d9bc9e0SMichael Lotz return 1; 5858d9bc9e0SMichael Lotz 5868d9bc9e0SMichael Lotz app->Run(); 5878d9bc9e0SMichael Lotz delete app; 5888d9bc9e0SMichael Lotz return 0; 5898d9bc9e0SMichael Lotz } 590