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 28*f16fef70SMichael Lotz static const char* kKeyringKeysIdentifier = "Keyrings"; 29*f16fef70SMichael Lotz 30*f16fef70SMichael Lotz 318d9bc9e0SMichael Lotz KeyStoreServer::KeyStoreServer() 328d9bc9e0SMichael Lotz : 3395eee1a3SMichael Lotz BApplication(kKeyStoreServerSignature), 3495eee1a3SMichael Lotz fDefaultKeyring(NULL), 3595eee1a3SMichael Lotz fKeyrings(20, true) 368d9bc9e0SMichael Lotz { 370dfaf59dSMichael Lotz BPath path; 380dfaf59dSMichael Lotz if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) 390dfaf59dSMichael Lotz return; 400dfaf59dSMichael Lotz 410dfaf59dSMichael Lotz BDirectory settingsDir(path.Path()); 420dfaf59dSMichael Lotz path.Append("system"); 430dfaf59dSMichael Lotz if (!settingsDir.Contains(path.Path())) 440dfaf59dSMichael Lotz settingsDir.CreateDirectory(path.Path(), NULL); 450dfaf59dSMichael Lotz 460dfaf59dSMichael Lotz settingsDir.SetTo(path.Path()); 470dfaf59dSMichael Lotz path.Append("keystore"); 480dfaf59dSMichael Lotz if (!settingsDir.Contains(path.Path())) 490dfaf59dSMichael Lotz settingsDir.CreateDirectory(path.Path(), NULL); 500dfaf59dSMichael Lotz 510dfaf59dSMichael Lotz settingsDir.SetTo(path.Path()); 520dfaf59dSMichael Lotz path.Append("keystore_database"); 530dfaf59dSMichael Lotz 540dfaf59dSMichael Lotz fKeyStoreFile.SetTo(path.Path(), B_READ_WRITE 550dfaf59dSMichael Lotz | (settingsDir.Contains(path.Path()) ? 0 : B_CREATE_FILE)); 560dfaf59dSMichael Lotz 570dfaf59dSMichael Lotz _ReadKeyStoreDatabase(); 5895eee1a3SMichael Lotz 5995eee1a3SMichael Lotz if (fDefaultKeyring == NULL) 6095eee1a3SMichael Lotz fDefaultKeyring = new(std::nothrow) Keyring("", BMessage()); 618d9bc9e0SMichael Lotz } 628d9bc9e0SMichael Lotz 638d9bc9e0SMichael Lotz 648d9bc9e0SMichael Lotz KeyStoreServer::~KeyStoreServer() 658d9bc9e0SMichael Lotz { 668d9bc9e0SMichael Lotz } 678d9bc9e0SMichael Lotz 688d9bc9e0SMichael Lotz 698d9bc9e0SMichael Lotz void 708d9bc9e0SMichael Lotz KeyStoreServer::MessageReceived(BMessage* message) 718d9bc9e0SMichael Lotz { 720dfaf59dSMichael Lotz BMessage reply; 7395eee1a3SMichael Lotz status_t result = B_UNSUPPORTED; 7495eee1a3SMichael Lotz 7595eee1a3SMichael Lotz // Resolve the keyring for the relevant messages. 7695eee1a3SMichael Lotz Keyring* keyring = NULL; 7795eee1a3SMichael Lotz switch (message->what) { 7895eee1a3SMichael Lotz case KEY_STORE_GET_KEY: 7995eee1a3SMichael Lotz case KEY_STORE_GET_NEXT_KEY: 8095eee1a3SMichael Lotz case KEY_STORE_ADD_KEY: 8195eee1a3SMichael Lotz case KEY_STORE_REMOVE_KEY: 8295eee1a3SMichael Lotz case KEY_STORE_IS_KEYRING_ACCESSIBLE: 8395eee1a3SMichael Lotz case KEY_STORE_REVOKE_ACCESS: 84*f16fef70SMichael Lotz case KEY_STORE_ADD_KEYRING_TO_MASTER: 85*f16fef70SMichael Lotz case KEY_STORE_REMOVE_KEYRING_FROM_MASTER: 8695eee1a3SMichael Lotz { 8795eee1a3SMichael Lotz BString keyringName; 8895eee1a3SMichael Lotz if (message->FindString("keyring", &keyringName) != B_OK) 8995eee1a3SMichael Lotz keyringName = ""; 9095eee1a3SMichael Lotz 9195eee1a3SMichael Lotz keyring = _FindKeyring(keyringName); 9295eee1a3SMichael Lotz if (keyring == NULL) { 9395eee1a3SMichael Lotz result = B_BAD_VALUE; 9495eee1a3SMichael Lotz message->what = 0; 9595eee1a3SMichael Lotz // So that we don't do anything in the second switch. 9695eee1a3SMichael Lotz break; 9795eee1a3SMichael Lotz } 9895eee1a3SMichael Lotz 99ac9b28f0SMichael Lotz switch (message->what) { 100ac9b28f0SMichael Lotz case KEY_STORE_GET_KEY: 101ac9b28f0SMichael Lotz case KEY_STORE_GET_NEXT_KEY: 102ac9b28f0SMichael Lotz case KEY_STORE_ADD_KEY: 103ac9b28f0SMichael Lotz case KEY_STORE_REMOVE_KEY: 104*f16fef70SMichael Lotz case KEY_STORE_ADD_KEYRING_TO_MASTER: 105ac9b28f0SMichael Lotz { 106ac9b28f0SMichael Lotz // These need keyring access to do anything. 107ac9b28f0SMichael Lotz while (!keyring->IsAccessible()) { 108ac9b28f0SMichael Lotz status_t accessResult = _AccessKeyring(*keyring); 109ac9b28f0SMichael Lotz if (accessResult != B_OK) { 110ac9b28f0SMichael Lotz result = accessResult; 111ac9b28f0SMichael Lotz message->what = 0; 112ac9b28f0SMichael Lotz break; 113ac9b28f0SMichael Lotz } 114ac9b28f0SMichael Lotz } 115ac9b28f0SMichael Lotz } 116ac9b28f0SMichael Lotz } 117ac9b28f0SMichael Lotz 11895eee1a3SMichael Lotz break; 11995eee1a3SMichael Lotz } 12095eee1a3SMichael Lotz } 1210dfaf59dSMichael Lotz 1228d9bc9e0SMichael Lotz switch (message->what) { 1238d9bc9e0SMichael Lotz case KEY_STORE_GET_KEY: 1248d9bc9e0SMichael Lotz { 12595eee1a3SMichael Lotz BString identifier; 12695eee1a3SMichael Lotz if (message->FindString("identifier", &identifier) != B_OK) { 12795eee1a3SMichael Lotz result = B_BAD_VALUE; 12895eee1a3SMichael Lotz break; 12995eee1a3SMichael Lotz } 13095eee1a3SMichael Lotz 13195eee1a3SMichael Lotz bool secondaryIdentifierOptional; 13295eee1a3SMichael Lotz if (message->FindBool("secondaryIdentifierOptional", 13395eee1a3SMichael Lotz &secondaryIdentifierOptional) != B_OK) { 13495eee1a3SMichael Lotz secondaryIdentifierOptional = false; 13595eee1a3SMichael Lotz } 13695eee1a3SMichael Lotz 13795eee1a3SMichael Lotz BString secondaryIdentifier; 13895eee1a3SMichael Lotz if (message->FindString("secondaryIdentifier", 13995eee1a3SMichael Lotz &secondaryIdentifier) != B_OK) { 14095eee1a3SMichael Lotz secondaryIdentifier = ""; 14195eee1a3SMichael Lotz secondaryIdentifierOptional = true; 14295eee1a3SMichael Lotz } 14395eee1a3SMichael Lotz 14495eee1a3SMichael Lotz BMessage keyMessage; 14595eee1a3SMichael Lotz result = keyring->FindKey(identifier, secondaryIdentifier, 14695eee1a3SMichael Lotz secondaryIdentifierOptional, &keyMessage); 14795eee1a3SMichael Lotz if (result == B_OK) 14895eee1a3SMichael Lotz reply.AddMessage("key", &keyMessage); 149*f16fef70SMichael Lotz 1508d9bc9e0SMichael Lotz break; 1518d9bc9e0SMichael Lotz } 1528d9bc9e0SMichael Lotz 1538d9bc9e0SMichael Lotz case KEY_STORE_GET_NEXT_KEY: 1548d9bc9e0SMichael Lotz { 1550dfaf59dSMichael Lotz BKeyType type; 1560dfaf59dSMichael Lotz BKeyPurpose purpose; 1570dfaf59dSMichael Lotz uint32 cookie; 1580dfaf59dSMichael Lotz if (message->FindUInt32("type", (uint32*)&type) != B_OK 1590dfaf59dSMichael Lotz || message->FindUInt32("purpose", (uint32*)&purpose) != B_OK 1600dfaf59dSMichael Lotz || message->FindUInt32("cookie", &cookie) != B_OK) { 1610dfaf59dSMichael Lotz result = B_BAD_VALUE; 1620dfaf59dSMichael Lotz break; 1630dfaf59dSMichael Lotz } 1640dfaf59dSMichael Lotz 1650dfaf59dSMichael Lotz BMessage keyMessage; 16695eee1a3SMichael Lotz result = keyring->FindKey(type, purpose, cookie, keyMessage); 1670dfaf59dSMichael Lotz if (result == B_OK) { 1680dfaf59dSMichael Lotz cookie++; 1690dfaf59dSMichael Lotz reply.AddUInt32("cookie", cookie); 1700dfaf59dSMichael Lotz reply.AddMessage("key", &keyMessage); 1710dfaf59dSMichael Lotz } 1720dfaf59dSMichael Lotz 1730dfaf59dSMichael Lotz break; 1740dfaf59dSMichael Lotz } 1750dfaf59dSMichael Lotz 1760dfaf59dSMichael Lotz case KEY_STORE_ADD_KEY: 1770dfaf59dSMichael Lotz { 1780dfaf59dSMichael Lotz BMessage keyMessage; 1790dfaf59dSMichael Lotz BString identifier; 1800dfaf59dSMichael Lotz if (message->FindMessage("key", &keyMessage) != B_OK 1810dfaf59dSMichael Lotz || keyMessage.FindString("identifier", &identifier) != B_OK) { 1820dfaf59dSMichael Lotz result = B_BAD_VALUE; 1830dfaf59dSMichael Lotz break; 1840dfaf59dSMichael Lotz } 1850dfaf59dSMichael Lotz 1860dfaf59dSMichael Lotz BString secondaryIdentifier; 1870dfaf59dSMichael Lotz if (keyMessage.FindString("secondaryIdentifier", 1880dfaf59dSMichael Lotz &secondaryIdentifier) != B_OK) { 1890dfaf59dSMichael Lotz secondaryIdentifier = ""; 1900dfaf59dSMichael Lotz } 1910dfaf59dSMichael Lotz 19295eee1a3SMichael Lotz result = keyring->AddKey(identifier, secondaryIdentifier, keyMessage); 19395eee1a3SMichael Lotz if (result == B_OK) 19495eee1a3SMichael Lotz _WriteKeyStoreDatabase(); 19595eee1a3SMichael Lotz 19695eee1a3SMichael Lotz break; 19795eee1a3SMichael Lotz } 19895eee1a3SMichael Lotz 19995eee1a3SMichael Lotz case KEY_STORE_REMOVE_KEY: 20095eee1a3SMichael Lotz { 20195eee1a3SMichael Lotz BMessage keyMessage; 20295eee1a3SMichael Lotz BString identifier; 20395eee1a3SMichael Lotz if (message->FindMessage("key", &keyMessage) != B_OK 20495eee1a3SMichael Lotz || keyMessage.FindString("identifier", &identifier) != B_OK) { 20595eee1a3SMichael Lotz result = B_BAD_VALUE; 20695eee1a3SMichael Lotz break; 20795eee1a3SMichael Lotz } 20895eee1a3SMichael Lotz 20995eee1a3SMichael Lotz result = keyring->RemoveKey(identifier, keyMessage); 21095eee1a3SMichael Lotz if (result == B_OK) 21195eee1a3SMichael Lotz _WriteKeyStoreDatabase(); 21295eee1a3SMichael Lotz 21395eee1a3SMichael Lotz break; 21495eee1a3SMichael Lotz } 21595eee1a3SMichael Lotz 21695eee1a3SMichael Lotz case KEY_STORE_ADD_KEYRING: 21795eee1a3SMichael Lotz { 21895eee1a3SMichael Lotz BMessage keyMessage; 21995eee1a3SMichael Lotz BString keyring; 22095eee1a3SMichael Lotz if (message->FindString("keyring", &keyring) != B_OK 22195eee1a3SMichael Lotz || message->FindMessage("key", &keyMessage) != B_OK) { 22295eee1a3SMichael Lotz result = B_BAD_VALUE; 22395eee1a3SMichael Lotz break; 22495eee1a3SMichael Lotz } 22595eee1a3SMichael Lotz 22695eee1a3SMichael Lotz result = _AddKeyring(keyring, keyMessage); 22795eee1a3SMichael Lotz if (result == B_OK) 22895eee1a3SMichael Lotz _WriteKeyStoreDatabase(); 22995eee1a3SMichael Lotz 23095eee1a3SMichael Lotz break; 23195eee1a3SMichael Lotz } 23295eee1a3SMichael Lotz 23395eee1a3SMichael Lotz case KEY_STORE_REMOVE_KEYRING: 23495eee1a3SMichael Lotz { 23595eee1a3SMichael Lotz BString keyringName; 23695eee1a3SMichael Lotz if (message->FindString("keyring", &keyringName) != B_OK) 23795eee1a3SMichael Lotz keyringName = ""; 23895eee1a3SMichael Lotz 23995eee1a3SMichael Lotz result = _RemoveKeyring(keyringName); 24095eee1a3SMichael Lotz if (result == B_OK) 24195eee1a3SMichael Lotz _WriteKeyStoreDatabase(); 24295eee1a3SMichael Lotz 24395eee1a3SMichael Lotz break; 24495eee1a3SMichael Lotz } 24595eee1a3SMichael Lotz 24695eee1a3SMichael Lotz case KEY_STORE_GET_NEXT_KEYRING: 24795eee1a3SMichael Lotz { 24895eee1a3SMichael Lotz uint32 cookie; 24995eee1a3SMichael Lotz if (message->FindUInt32("cookie", &cookie) != B_OK) { 25095eee1a3SMichael Lotz result = B_BAD_VALUE; 25195eee1a3SMichael Lotz break; 25295eee1a3SMichael Lotz } 25395eee1a3SMichael Lotz 25495eee1a3SMichael Lotz if (cookie == 0) 25595eee1a3SMichael Lotz keyring = fDefaultKeyring; 25695eee1a3SMichael Lotz else 25795eee1a3SMichael Lotz keyring = fKeyrings.ItemAt(cookie - 1); 25895eee1a3SMichael Lotz 25995eee1a3SMichael Lotz if (keyring == NULL) { 26095eee1a3SMichael Lotz result = B_ENTRY_NOT_FOUND; 26195eee1a3SMichael Lotz break; 26295eee1a3SMichael Lotz } 26395eee1a3SMichael Lotz 26495eee1a3SMichael Lotz cookie++; 26595eee1a3SMichael Lotz reply.AddUInt32("cookie", cookie); 26695eee1a3SMichael Lotz reply.AddString("keyring", keyring->Name()); 26795eee1a3SMichael Lotz result = B_OK; 26895eee1a3SMichael Lotz break; 26995eee1a3SMichael Lotz } 27095eee1a3SMichael Lotz 27195eee1a3SMichael Lotz case KEY_STORE_IS_KEYRING_ACCESSIBLE: 27295eee1a3SMichael Lotz { 27395eee1a3SMichael Lotz reply.AddBool("accessible", keyring->IsAccessible()); 27495eee1a3SMichael Lotz result = B_OK; 275*f16fef70SMichael Lotz break; 27695eee1a3SMichael Lotz } 27795eee1a3SMichael Lotz 278ac9b28f0SMichael Lotz case KEY_STORE_REVOKE_ACCESS: 279ac9b28f0SMichael Lotz { 280ac9b28f0SMichael Lotz keyring->RevokeAccess(); 281ac9b28f0SMichael Lotz result = B_OK; 282*f16fef70SMichael Lotz break; 283*f16fef70SMichael Lotz } 284*f16fef70SMichael Lotz 285*f16fef70SMichael Lotz case KEY_STORE_ADD_KEYRING_TO_MASTER: 286*f16fef70SMichael Lotz case KEY_STORE_REMOVE_KEYRING_FROM_MASTER: 287*f16fef70SMichael Lotz { 288*f16fef70SMichael Lotz // We also need access to the default keyring. 289*f16fef70SMichael Lotz while (!fDefaultKeyring->IsAccessible()) { 290*f16fef70SMichael Lotz status_t accessResult = _AccessKeyring(*fDefaultKeyring); 291*f16fef70SMichael Lotz if (accessResult != B_OK) { 292*f16fef70SMichael Lotz result = accessResult; 293*f16fef70SMichael Lotz message->what = 0; 294*f16fef70SMichael Lotz break; 295*f16fef70SMichael Lotz } 296*f16fef70SMichael Lotz } 297*f16fef70SMichael Lotz 298*f16fef70SMichael Lotz if (message->what == 0) 299*f16fef70SMichael Lotz break; 300*f16fef70SMichael Lotz 301*f16fef70SMichael Lotz BString secondaryIdentifier = keyring->Name(); 302*f16fef70SMichael Lotz BMessage keyMessage = keyring->KeyMessage(); 303*f16fef70SMichael Lotz keyMessage.RemoveName("identifier"); 304*f16fef70SMichael Lotz keyMessage.AddString("identifier", kKeyringKeysIdentifier); 305*f16fef70SMichael Lotz keyMessage.RemoveName("secondaryIdentifier"); 306*f16fef70SMichael Lotz keyMessage.AddString("secondaryIdentifier", secondaryIdentifier); 307*f16fef70SMichael Lotz 308*f16fef70SMichael Lotz switch (message->what) { 309*f16fef70SMichael Lotz case KEY_STORE_ADD_KEYRING_TO_MASTER: 310*f16fef70SMichael Lotz result = fDefaultKeyring->AddKey(kKeyringKeysIdentifier, 311*f16fef70SMichael Lotz secondaryIdentifier, keyMessage); 312*f16fef70SMichael Lotz break; 313*f16fef70SMichael Lotz 314*f16fef70SMichael Lotz case KEY_STORE_REMOVE_KEYRING_FROM_MASTER: 315*f16fef70SMichael Lotz result = fDefaultKeyring->RemoveKey(kKeyringKeysIdentifier, 316*f16fef70SMichael Lotz keyMessage); 317*f16fef70SMichael Lotz break; 318*f16fef70SMichael Lotz } 319*f16fef70SMichael Lotz 320*f16fef70SMichael Lotz if (result == B_OK) 321*f16fef70SMichael Lotz _WriteKeyStoreDatabase(); 322*f16fef70SMichael Lotz 323*f16fef70SMichael Lotz break; 324ac9b28f0SMichael Lotz } 325ac9b28f0SMichael Lotz 32695eee1a3SMichael Lotz case 0: 32795eee1a3SMichael Lotz { 32895eee1a3SMichael Lotz // Just the error case from above. 3298d9bc9e0SMichael Lotz break; 3308d9bc9e0SMichael Lotz } 3318d9bc9e0SMichael Lotz 3328d9bc9e0SMichael Lotz default: 3338d9bc9e0SMichael Lotz { 3348d9bc9e0SMichael Lotz printf("unknown message received: %" B_PRIu32 " \"%.4s\"\n", 3358d9bc9e0SMichael Lotz message->what, (const char*)&message->what); 3368d9bc9e0SMichael Lotz break; 3378d9bc9e0SMichael Lotz } 3388d9bc9e0SMichael Lotz } 3398d9bc9e0SMichael Lotz 3400dfaf59dSMichael Lotz if (message->IsSourceWaiting()) { 3410dfaf59dSMichael Lotz if (result == B_OK) 3420dfaf59dSMichael Lotz reply.what = KEY_STORE_SUCCESS; 3430dfaf59dSMichael Lotz else { 3440dfaf59dSMichael Lotz reply.what = KEY_STORE_RESULT; 3450dfaf59dSMichael Lotz reply.AddInt32("result", result); 3460dfaf59dSMichael Lotz } 3470dfaf59dSMichael Lotz 3480dfaf59dSMichael Lotz message->SendReply(&reply); 3490dfaf59dSMichael Lotz } 3508d9bc9e0SMichael Lotz } 3518d9bc9e0SMichael Lotz 3528d9bc9e0SMichael Lotz 3538d9bc9e0SMichael Lotz status_t 3540dfaf59dSMichael Lotz KeyStoreServer::_ReadKeyStoreDatabase() 3558d9bc9e0SMichael Lotz { 35695eee1a3SMichael Lotz BMessage keyrings; 35795eee1a3SMichael Lotz status_t result = keyrings.Unflatten(&fKeyStoreFile); 3580dfaf59dSMichael Lotz if (result != B_OK) { 3590dfaf59dSMichael Lotz printf("failed to read keystore database\n"); 3600dfaf59dSMichael Lotz _WriteKeyStoreDatabase(); 3610dfaf59dSMichael Lotz return result; 3620dfaf59dSMichael Lotz } 3630dfaf59dSMichael Lotz 36495eee1a3SMichael Lotz int32 index = 0; 36595eee1a3SMichael Lotz char* keyringName = NULL; 36695eee1a3SMichael Lotz while (keyrings.GetInfo(B_MESSAGE_TYPE, index++, &keyringName, 36795eee1a3SMichael Lotz NULL) == B_OK) { 36895eee1a3SMichael Lotz 36995eee1a3SMichael Lotz BMessage keyringData; 37095eee1a3SMichael Lotz if (keyrings.FindMessage(keyringName, &keyringData) != B_OK) { 37195eee1a3SMichael Lotz printf("failed to retrieve keyring data for keyring \"%s\"\n", 37295eee1a3SMichael Lotz keyringName); 37395eee1a3SMichael Lotz continue; 37495eee1a3SMichael Lotz } 37595eee1a3SMichael Lotz 37695eee1a3SMichael Lotz Keyring* keyring = new(std::nothrow) Keyring(keyringName, keyringData); 37795eee1a3SMichael Lotz if (keyring == NULL) { 37895eee1a3SMichael Lotz printf("no memory for allocating keyring \"%s\"\n", keyringName); 37995eee1a3SMichael Lotz continue; 38095eee1a3SMichael Lotz } 38195eee1a3SMichael Lotz 38295eee1a3SMichael Lotz if (strlen(keyringName) == 0) 38395eee1a3SMichael Lotz fDefaultKeyring = keyring; 38495eee1a3SMichael Lotz else 38595eee1a3SMichael Lotz fKeyrings.BinaryInsert(keyring, &Keyring::Compare); 38695eee1a3SMichael Lotz } 38795eee1a3SMichael Lotz 3880dfaf59dSMichael Lotz return B_OK; 3890dfaf59dSMichael Lotz } 3900dfaf59dSMichael Lotz 3910dfaf59dSMichael Lotz 3920dfaf59dSMichael Lotz status_t 3930dfaf59dSMichael Lotz KeyStoreServer::_WriteKeyStoreDatabase() 3940dfaf59dSMichael Lotz { 3950dfaf59dSMichael Lotz fKeyStoreFile.SetSize(0); 3960dfaf59dSMichael Lotz fKeyStoreFile.Seek(0, SEEK_SET); 3970dfaf59dSMichael Lotz 39895eee1a3SMichael Lotz BMessage keyrings; 39995eee1a3SMichael Lotz if (fDefaultKeyring != NULL) 40095eee1a3SMichael Lotz keyrings.AddMessage("", &fDefaultKeyring->Data()); 4010dfaf59dSMichael Lotz 40295eee1a3SMichael Lotz for (int32 i = 0; i < fKeyrings.CountItems(); i++) { 40395eee1a3SMichael Lotz Keyring* keyring = fKeyrings.ItemAt(i); 40495eee1a3SMichael Lotz if (keyring == NULL) 4050dfaf59dSMichael Lotz continue; 40695eee1a3SMichael Lotz 40795eee1a3SMichael Lotz keyrings.AddMessage(keyring->Name(), &keyring->Data()); 4080dfaf59dSMichael Lotz } 4090dfaf59dSMichael Lotz 41095eee1a3SMichael Lotz return keyrings.Flatten(&fKeyStoreFile); 4110dfaf59dSMichael Lotz } 4120dfaf59dSMichael Lotz 4130dfaf59dSMichael Lotz 41495eee1a3SMichael Lotz Keyring* 41595eee1a3SMichael Lotz KeyStoreServer::_FindKeyring(const BString& name) 41695eee1a3SMichael Lotz { 41795eee1a3SMichael Lotz if (name.IsEmpty()) 41895eee1a3SMichael Lotz return fDefaultKeyring; 4190dfaf59dSMichael Lotz 42095eee1a3SMichael Lotz return fKeyrings.BinarySearchByKey(name, &Keyring::Compare); 4210dfaf59dSMichael Lotz } 4220dfaf59dSMichael Lotz 4230dfaf59dSMichael Lotz 4240dfaf59dSMichael Lotz status_t 42595eee1a3SMichael Lotz KeyStoreServer::_AddKeyring(const BString& name, const BMessage& keyMessage) 4260dfaf59dSMichael Lotz { 42795eee1a3SMichael Lotz if (_FindKeyring(name) != NULL) 4280dfaf59dSMichael Lotz return B_NAME_IN_USE; 4290dfaf59dSMichael Lotz 4301dd765c9SMichael Lotz Keyring* keyring = new(std::nothrow) Keyring(name, BMessage(), &keyMessage); 43195eee1a3SMichael Lotz if (keyring == NULL) 43295eee1a3SMichael Lotz return B_NO_MEMORY; 43395eee1a3SMichael Lotz 43495eee1a3SMichael Lotz if (!fKeyrings.BinaryInsert(keyring, &Keyring::Compare)) { 43595eee1a3SMichael Lotz delete keyring; 43695eee1a3SMichael Lotz return B_ERROR; 43795eee1a3SMichael Lotz } 43895eee1a3SMichael Lotz 43995eee1a3SMichael Lotz return B_OK; 44095eee1a3SMichael Lotz } 44195eee1a3SMichael Lotz 44295eee1a3SMichael Lotz 44395eee1a3SMichael Lotz status_t 44495eee1a3SMichael Lotz KeyStoreServer::_RemoveKeyring(const BString& name) 44595eee1a3SMichael Lotz { 44695eee1a3SMichael Lotz Keyring* keyring = _FindKeyring(name); 44795eee1a3SMichael Lotz if (keyring == NULL) 44895eee1a3SMichael Lotz return B_ENTRY_NOT_FOUND; 44995eee1a3SMichael Lotz 45095eee1a3SMichael Lotz if (keyring == fDefaultKeyring) { 45195eee1a3SMichael Lotz // The default keyring can't be removed. 45295eee1a3SMichael Lotz return B_NOT_ALLOWED; 45395eee1a3SMichael Lotz } 45495eee1a3SMichael Lotz 45595eee1a3SMichael Lotz return fKeyrings.RemoveItem(keyring) ? B_OK : B_ERROR; 4568d9bc9e0SMichael Lotz } 4578d9bc9e0SMichael Lotz 4588d9bc9e0SMichael Lotz 459ac9b28f0SMichael Lotz status_t 460ac9b28f0SMichael Lotz KeyStoreServer::_AccessKeyring(Keyring& keyring) 461ac9b28f0SMichael Lotz { 462ac9b28f0SMichael Lotz // If we are accessing a keyring that has been added to master access we 463ac9b28f0SMichael Lotz // get the key from the default keyring and unlock with that. 464ac9b28f0SMichael Lotz BMessage keyMessage; 465ac9b28f0SMichael Lotz if (&keyring != fDefaultKeyring && fDefaultKeyring->IsAccessible()) { 466*f16fef70SMichael Lotz if (fDefaultKeyring->FindKey(kKeyringKeysIdentifier, keyring.Name(), 467*f16fef70SMichael Lotz false, &keyMessage) == B_OK) { 468ac9b28f0SMichael Lotz // We found a key for this keyring, try to access with it. 469ac9b28f0SMichael Lotz if (keyring.Access(keyMessage) == B_OK) 470ac9b28f0SMichael Lotz return B_OK; 471ac9b28f0SMichael Lotz } 472ac9b28f0SMichael Lotz } 473ac9b28f0SMichael Lotz 474ac9b28f0SMichael Lotz // No key, we need to request one from the user. 475ac9b28f0SMichael Lotz keyMessage.AddString("keyring", keyring.Name()); 476ac9b28f0SMichael Lotz status_t result = _RequestKey(keyMessage); 477ac9b28f0SMichael Lotz if (result != B_OK) 478ac9b28f0SMichael Lotz return result; 479ac9b28f0SMichael Lotz 480ac9b28f0SMichael Lotz return keyring.Access(keyMessage); 481ac9b28f0SMichael Lotz } 482ac9b28f0SMichael Lotz 483ac9b28f0SMichael Lotz 484ac9b28f0SMichael Lotz status_t 485ac9b28f0SMichael Lotz KeyStoreServer::_RequestKey(BMessage& keyMessage) 486ac9b28f0SMichael Lotz { 487ac9b28f0SMichael Lotz KeyRequestWindow* requestWindow = new(std::nothrow) KeyRequestWindow(); 488ac9b28f0SMichael Lotz if (requestWindow == NULL) 489ac9b28f0SMichael Lotz return B_NO_MEMORY; 490ac9b28f0SMichael Lotz 491ac9b28f0SMichael Lotz return requestWindow->RequestKey(keyMessage); 492ac9b28f0SMichael Lotz } 493ac9b28f0SMichael Lotz 494ac9b28f0SMichael Lotz 4958d9bc9e0SMichael Lotz int 4968d9bc9e0SMichael Lotz main(int argc, char* argv[]) 4978d9bc9e0SMichael Lotz { 4988d9bc9e0SMichael Lotz KeyStoreServer* app = new(std::nothrow) KeyStoreServer(); 4998d9bc9e0SMichael Lotz if (app == NULL) 5008d9bc9e0SMichael Lotz return 1; 5018d9bc9e0SMichael Lotz 5028d9bc9e0SMichael Lotz app->Run(); 5038d9bc9e0SMichael Lotz delete app; 5048d9bc9e0SMichael Lotz return 0; 5058d9bc9e0SMichael Lotz } 506