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
9cfa81315SMichael Lotz #include "AppAccessRequestWindow.h"
10ac9b28f0SMichael Lotz #include "KeyRequestWindow.h"
1195eee1a3SMichael Lotz #include "Keyring.h"
128d9bc9e0SMichael Lotz
138d9bc9e0SMichael Lotz #include <KeyStoreDefs.h>
148d9bc9e0SMichael Lotz
150dfaf59dSMichael Lotz #include <Directory.h>
160dfaf59dSMichael Lotz #include <Entry.h>
170dfaf59dSMichael Lotz #include <FindDirectory.h>
180dfaf59dSMichael Lotz #include <Path.h>
1976df966eSMichael Lotz #include <Roster.h>
200dfaf59dSMichael Lotz #include <String.h>
210dfaf59dSMichael Lotz
228d9bc9e0SMichael Lotz #include <new>
238d9bc9e0SMichael Lotz
248d9bc9e0SMichael Lotz #include <stdio.h>
258d9bc9e0SMichael Lotz
268d9bc9e0SMichael Lotz
278d9bc9e0SMichael Lotz using namespace BPrivate;
288d9bc9e0SMichael Lotz
298d9bc9e0SMichael Lotz
30a5a5f4caSMichael Lotz static const char* kMasterKeyringName = "Master";
31f16fef70SMichael Lotz static const char* kKeyringKeysIdentifier = "Keyrings";
32f16fef70SMichael Lotz
33bec02d0cSMichael Lotz static const uint32 kKeyStoreFormatVersion = 1;
34bec02d0cSMichael Lotz
3597b3abf1SMichael Lotz static const uint32 kFlagGetKey = 0x0001;
3697b3abf1SMichael Lotz static const uint32 kFlagEnumerateKeys = 0x0002;
3797b3abf1SMichael Lotz static const uint32 kFlagAddKey = 0x0004;
3897b3abf1SMichael Lotz static const uint32 kFlagRemoveKey = 0x0008;
3997b3abf1SMichael Lotz static const uint32 kFlagAddKeyring = 0x0010;
4097b3abf1SMichael Lotz static const uint32 kFlagRemoveKeyring = 0x0020;
4197b3abf1SMichael Lotz static const uint32 kFlagEnumerateKeyrings = 0x0040;
424a0460a9SMichael Lotz static const uint32 kFlagSetUnlockKey = 0x0080;
434a0460a9SMichael Lotz static const uint32 kFlagRemoveUnlockKey = 0x0100;
4497b3abf1SMichael Lotz static const uint32 kFlagAddKeyringsToMaster = 0x0200;
4597b3abf1SMichael Lotz static const uint32 kFlagRemoveKeyringsFromMaster = 0x0400;
4697b3abf1SMichael Lotz static const uint32 kFlagEnumerateMasterKeyrings = 0x0800;
47c8ae843fSMichael Lotz static const uint32 kFlagQueryLockState = 0x1000;
48c8ae843fSMichael Lotz static const uint32 kFlagLockKeyring = 0x2000;
4997b3abf1SMichael Lotz static const uint32 kFlagEnumerateApplications = 0x4000;
5097b3abf1SMichael Lotz static const uint32 kFlagRemoveApplications = 0x8000;
5197b3abf1SMichael Lotz
5297b3abf1SMichael Lotz static const uint32 kDefaultAppFlags = kFlagGetKey | kFlagEnumerateKeys
5397b3abf1SMichael Lotz | kFlagAddKey | kFlagRemoveKey | kFlagAddKeyring | kFlagRemoveKeyring
544a0460a9SMichael Lotz | kFlagEnumerateKeyrings | kFlagSetUnlockKey | kFlagRemoveUnlockKey
5597b3abf1SMichael Lotz | kFlagAddKeyringsToMaster | kFlagRemoveKeyringsFromMaster
56c8ae843fSMichael Lotz | kFlagEnumerateMasterKeyrings | kFlagQueryLockState | kFlagLockKeyring
57c8ae843fSMichael Lotz | kFlagEnumerateApplications | kFlagRemoveApplications;
5897b3abf1SMichael Lotz
59f16fef70SMichael Lotz
KeyStoreServer()608d9bc9e0SMichael Lotz KeyStoreServer::KeyStoreServer()
618d9bc9e0SMichael Lotz :
6295eee1a3SMichael Lotz BApplication(kKeyStoreServerSignature),
63a5a5f4caSMichael Lotz fMasterKeyring(NULL),
6495eee1a3SMichael Lotz fKeyrings(20, true)
658d9bc9e0SMichael Lotz {
660dfaf59dSMichael Lotz BPath path;
670dfaf59dSMichael Lotz if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK)
680dfaf59dSMichael Lotz return;
690dfaf59dSMichael Lotz
700dfaf59dSMichael Lotz BDirectory settingsDir(path.Path());
710dfaf59dSMichael Lotz path.Append("system");
720dfaf59dSMichael Lotz if (!settingsDir.Contains(path.Path()))
730dfaf59dSMichael Lotz settingsDir.CreateDirectory(path.Path(), NULL);
740dfaf59dSMichael Lotz
750dfaf59dSMichael Lotz settingsDir.SetTo(path.Path());
760dfaf59dSMichael Lotz path.Append("keystore");
770dfaf59dSMichael Lotz if (!settingsDir.Contains(path.Path()))
780dfaf59dSMichael Lotz settingsDir.CreateDirectory(path.Path(), NULL);
790dfaf59dSMichael Lotz
800dfaf59dSMichael Lotz settingsDir.SetTo(path.Path());
810dfaf59dSMichael Lotz path.Append("keystore_database");
820dfaf59dSMichael Lotz
830dfaf59dSMichael Lotz fKeyStoreFile.SetTo(path.Path(), B_READ_WRITE
840dfaf59dSMichael Lotz | (settingsDir.Contains(path.Path()) ? 0 : B_CREATE_FILE));
850dfaf59dSMichael Lotz
860dfaf59dSMichael Lotz _ReadKeyStoreDatabase();
8795eee1a3SMichael Lotz
88bec02d0cSMichael Lotz if (fMasterKeyring == NULL) {
89a5a5f4caSMichael Lotz fMasterKeyring = new(std::nothrow) Keyring(kMasterKeyringName);
90bec02d0cSMichael Lotz fKeyrings.BinaryInsert(fMasterKeyring, &Keyring::Compare);
91bec02d0cSMichael Lotz }
928d9bc9e0SMichael Lotz }
938d9bc9e0SMichael Lotz
948d9bc9e0SMichael Lotz
~KeyStoreServer()958d9bc9e0SMichael Lotz KeyStoreServer::~KeyStoreServer()
968d9bc9e0SMichael Lotz {
978d9bc9e0SMichael Lotz }
988d9bc9e0SMichael Lotz
998d9bc9e0SMichael Lotz
1008d9bc9e0SMichael Lotz void
MessageReceived(BMessage * message)1018d9bc9e0SMichael Lotz KeyStoreServer::MessageReceived(BMessage* message)
1028d9bc9e0SMichael Lotz {
1030dfaf59dSMichael Lotz BMessage reply;
10495eee1a3SMichael Lotz status_t result = B_UNSUPPORTED;
105cfa81315SMichael Lotz app_info callingAppInfo;
106cfa81315SMichael Lotz
107cfa81315SMichael Lotz uint32 accessFlags = _AccessFlagsFor(message->what);
108cfa81315SMichael Lotz if (accessFlags == 0)
109cfa81315SMichael Lotz message->what = 0;
110cfa81315SMichael Lotz
111cfa81315SMichael Lotz if (message->what != 0) {
112cfa81315SMichael Lotz result = _ResolveCallingApp(*message, callingAppInfo);
113cfa81315SMichael Lotz if (result != B_OK)
114cfa81315SMichael Lotz message->what = 0;
115cfa81315SMichael Lotz }
11695eee1a3SMichael Lotz
11795eee1a3SMichael Lotz // Resolve the keyring for the relevant messages.
11895eee1a3SMichael Lotz Keyring* keyring = NULL;
11995eee1a3SMichael Lotz switch (message->what) {
12095eee1a3SMichael Lotz case KEY_STORE_GET_KEY:
12195eee1a3SMichael Lotz case KEY_STORE_GET_NEXT_KEY:
12295eee1a3SMichael Lotz case KEY_STORE_ADD_KEY:
12395eee1a3SMichael Lotz case KEY_STORE_REMOVE_KEY:
124c8ae843fSMichael Lotz case KEY_STORE_IS_KEYRING_UNLOCKED:
125c8ae843fSMichael Lotz case KEY_STORE_LOCK_KEYRING:
1264a0460a9SMichael Lotz case KEY_STORE_SET_UNLOCK_KEY:
1274a0460a9SMichael Lotz case KEY_STORE_REMOVE_UNLOCK_KEY:
128f16fef70SMichael Lotz case KEY_STORE_ADD_KEYRING_TO_MASTER:
129f16fef70SMichael Lotz case KEY_STORE_REMOVE_KEYRING_FROM_MASTER:
130b31a707aSMichael Lotz case KEY_STORE_GET_NEXT_APPLICATION:
131b31a707aSMichael Lotz case KEY_STORE_REMOVE_APPLICATION:
13295eee1a3SMichael Lotz {
13395eee1a3SMichael Lotz BString keyringName;
13495eee1a3SMichael Lotz if (message->FindString("keyring", &keyringName) != B_OK)
13595eee1a3SMichael Lotz keyringName = "";
13695eee1a3SMichael Lotz
13795eee1a3SMichael Lotz keyring = _FindKeyring(keyringName);
13895eee1a3SMichael Lotz if (keyring == NULL) {
13995eee1a3SMichael Lotz result = B_BAD_VALUE;
14095eee1a3SMichael Lotz message->what = 0;
14195eee1a3SMichael Lotz // So that we don't do anything in the second switch.
14295eee1a3SMichael Lotz break;
14395eee1a3SMichael Lotz }
14495eee1a3SMichael Lotz
145ac9b28f0SMichael Lotz switch (message->what) {
146ac9b28f0SMichael Lotz case KEY_STORE_GET_KEY:
147ac9b28f0SMichael Lotz case KEY_STORE_GET_NEXT_KEY:
148ac9b28f0SMichael Lotz case KEY_STORE_ADD_KEY:
149ac9b28f0SMichael Lotz case KEY_STORE_REMOVE_KEY:
1504a0460a9SMichael Lotz case KEY_STORE_SET_UNLOCK_KEY:
1514a0460a9SMichael Lotz case KEY_STORE_REMOVE_UNLOCK_KEY:
152f16fef70SMichael Lotz case KEY_STORE_ADD_KEYRING_TO_MASTER:
153b31a707aSMichael Lotz case KEY_STORE_GET_NEXT_APPLICATION:
154b31a707aSMichael Lotz case KEY_STORE_REMOVE_APPLICATION:
155ac9b28f0SMichael Lotz {
156ac9b28f0SMichael Lotz // These need keyring access to do anything.
157c8ae843fSMichael Lotz while (!keyring->IsUnlocked()) {
158c8ae843fSMichael Lotz status_t unlockResult = _UnlockKeyring(*keyring);
159c8ae843fSMichael Lotz if (unlockResult != B_OK) {
160c8ae843fSMichael Lotz result = unlockResult;
161ac9b28f0SMichael Lotz message->what = 0;
162ac9b28f0SMichael Lotz break;
163ac9b28f0SMichael Lotz }
164ac9b28f0SMichael Lotz }
165cfa81315SMichael Lotz
166cfa81315SMichael Lotz status_t validateResult = _ValidateAppAccess(*keyring,
167cfa81315SMichael Lotz callingAppInfo, accessFlags);
168cfa81315SMichael Lotz if (validateResult != B_OK) {
169cfa81315SMichael Lotz result = validateResult;
170cfa81315SMichael Lotz message->what = 0;
171cfa81315SMichael Lotz break;
172cfa81315SMichael Lotz }
173cfa81315SMichael Lotz
174cfa81315SMichael Lotz break;
175ac9b28f0SMichael Lotz }
176ac9b28f0SMichael Lotz }
177ac9b28f0SMichael Lotz
17895eee1a3SMichael Lotz break;
17995eee1a3SMichael Lotz }
18095eee1a3SMichael Lotz }
1810dfaf59dSMichael Lotz
1828d9bc9e0SMichael Lotz switch (message->what) {
1838d9bc9e0SMichael Lotz case KEY_STORE_GET_KEY:
1848d9bc9e0SMichael Lotz {
18595eee1a3SMichael Lotz BString identifier;
18695eee1a3SMichael Lotz if (message->FindString("identifier", &identifier) != B_OK) {
18795eee1a3SMichael Lotz result = B_BAD_VALUE;
18895eee1a3SMichael Lotz break;
18995eee1a3SMichael Lotz }
19095eee1a3SMichael Lotz
19195eee1a3SMichael Lotz bool secondaryIdentifierOptional;
19295eee1a3SMichael Lotz if (message->FindBool("secondaryIdentifierOptional",
19395eee1a3SMichael Lotz &secondaryIdentifierOptional) != B_OK) {
19495eee1a3SMichael Lotz secondaryIdentifierOptional = false;
19595eee1a3SMichael Lotz }
19695eee1a3SMichael Lotz
19795eee1a3SMichael Lotz BString secondaryIdentifier;
19895eee1a3SMichael Lotz if (message->FindString("secondaryIdentifier",
19995eee1a3SMichael Lotz &secondaryIdentifier) != B_OK) {
20095eee1a3SMichael Lotz secondaryIdentifier = "";
20195eee1a3SMichael Lotz secondaryIdentifierOptional = true;
20295eee1a3SMichael Lotz }
20395eee1a3SMichael Lotz
20495eee1a3SMichael Lotz BMessage keyMessage;
20595eee1a3SMichael Lotz result = keyring->FindKey(identifier, secondaryIdentifier,
20695eee1a3SMichael Lotz secondaryIdentifierOptional, &keyMessage);
20795eee1a3SMichael Lotz if (result == B_OK)
20895eee1a3SMichael Lotz reply.AddMessage("key", &keyMessage);
209f16fef70SMichael Lotz
2108d9bc9e0SMichael Lotz break;
2118d9bc9e0SMichael Lotz }
2128d9bc9e0SMichael Lotz
2138d9bc9e0SMichael Lotz case KEY_STORE_GET_NEXT_KEY:
2148d9bc9e0SMichael Lotz {
2150dfaf59dSMichael Lotz BKeyType type;
2160dfaf59dSMichael Lotz BKeyPurpose purpose;
2170dfaf59dSMichael Lotz uint32 cookie;
2180dfaf59dSMichael Lotz if (message->FindUInt32("type", (uint32*)&type) != B_OK
2190dfaf59dSMichael Lotz || message->FindUInt32("purpose", (uint32*)&purpose) != B_OK
2200dfaf59dSMichael Lotz || message->FindUInt32("cookie", &cookie) != B_OK) {
2210dfaf59dSMichael Lotz result = B_BAD_VALUE;
2220dfaf59dSMichael Lotz break;
2230dfaf59dSMichael Lotz }
2240dfaf59dSMichael Lotz
2250dfaf59dSMichael Lotz BMessage keyMessage;
22695eee1a3SMichael Lotz result = keyring->FindKey(type, purpose, cookie, keyMessage);
2270dfaf59dSMichael Lotz if (result == B_OK) {
2280dfaf59dSMichael Lotz cookie++;
2290dfaf59dSMichael Lotz reply.AddUInt32("cookie", cookie);
2300dfaf59dSMichael Lotz reply.AddMessage("key", &keyMessage);
2310dfaf59dSMichael Lotz }
2320dfaf59dSMichael Lotz
2330dfaf59dSMichael Lotz break;
2340dfaf59dSMichael Lotz }
2350dfaf59dSMichael Lotz
2360dfaf59dSMichael Lotz case KEY_STORE_ADD_KEY:
2370dfaf59dSMichael Lotz {
2380dfaf59dSMichael Lotz BMessage keyMessage;
2390dfaf59dSMichael Lotz BString identifier;
2400dfaf59dSMichael Lotz if (message->FindMessage("key", &keyMessage) != B_OK
2410dfaf59dSMichael Lotz || keyMessage.FindString("identifier", &identifier) != B_OK) {
2420dfaf59dSMichael Lotz result = B_BAD_VALUE;
2430dfaf59dSMichael Lotz break;
2440dfaf59dSMichael Lotz }
2450dfaf59dSMichael Lotz
2460dfaf59dSMichael Lotz BString secondaryIdentifier;
2470dfaf59dSMichael Lotz if (keyMessage.FindString("secondaryIdentifier",
2480dfaf59dSMichael Lotz &secondaryIdentifier) != B_OK) {
2490dfaf59dSMichael Lotz secondaryIdentifier = "";
2500dfaf59dSMichael Lotz }
2510dfaf59dSMichael Lotz
25295eee1a3SMichael Lotz result = keyring->AddKey(identifier, secondaryIdentifier, 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_KEY:
26095eee1a3SMichael Lotz {
26195eee1a3SMichael Lotz BMessage keyMessage;
26295eee1a3SMichael Lotz BString identifier;
26395eee1a3SMichael Lotz if (message->FindMessage("key", &keyMessage) != B_OK
26495eee1a3SMichael Lotz || keyMessage.FindString("identifier", &identifier) != B_OK) {
26595eee1a3SMichael Lotz result = B_BAD_VALUE;
26695eee1a3SMichael Lotz break;
26795eee1a3SMichael Lotz }
26895eee1a3SMichael Lotz
26995eee1a3SMichael Lotz result = keyring->RemoveKey(identifier, keyMessage);
27095eee1a3SMichael Lotz if (result == B_OK)
27195eee1a3SMichael Lotz _WriteKeyStoreDatabase();
27295eee1a3SMichael Lotz
27395eee1a3SMichael Lotz break;
27495eee1a3SMichael Lotz }
27595eee1a3SMichael Lotz
27695eee1a3SMichael Lotz case KEY_STORE_ADD_KEYRING:
27795eee1a3SMichael Lotz {
27895eee1a3SMichael Lotz BMessage keyMessage;
27995eee1a3SMichael Lotz BString keyring;
280d4d6d123SMichael Lotz if (message->FindString("keyring", &keyring) != B_OK) {
28195eee1a3SMichael Lotz result = B_BAD_VALUE;
28295eee1a3SMichael Lotz break;
28395eee1a3SMichael Lotz }
28495eee1a3SMichael Lotz
285d4d6d123SMichael Lotz result = _AddKeyring(keyring);
28695eee1a3SMichael Lotz if (result == B_OK)
28795eee1a3SMichael Lotz _WriteKeyStoreDatabase();
28895eee1a3SMichael Lotz
28995eee1a3SMichael Lotz break;
29095eee1a3SMichael Lotz }
29195eee1a3SMichael Lotz
29295eee1a3SMichael Lotz case KEY_STORE_REMOVE_KEYRING:
29395eee1a3SMichael Lotz {
29495eee1a3SMichael Lotz BString keyringName;
29595eee1a3SMichael Lotz if (message->FindString("keyring", &keyringName) != B_OK)
29695eee1a3SMichael Lotz keyringName = "";
29795eee1a3SMichael Lotz
29895eee1a3SMichael Lotz result = _RemoveKeyring(keyringName);
29995eee1a3SMichael Lotz if (result == B_OK)
30095eee1a3SMichael Lotz _WriteKeyStoreDatabase();
30195eee1a3SMichael Lotz
30295eee1a3SMichael Lotz break;
30395eee1a3SMichael Lotz }
30495eee1a3SMichael Lotz
30595eee1a3SMichael Lotz case KEY_STORE_GET_NEXT_KEYRING:
30695eee1a3SMichael Lotz {
30795eee1a3SMichael Lotz uint32 cookie;
30895eee1a3SMichael Lotz if (message->FindUInt32("cookie", &cookie) != B_OK) {
30995eee1a3SMichael Lotz result = B_BAD_VALUE;
31095eee1a3SMichael Lotz break;
31195eee1a3SMichael Lotz }
31295eee1a3SMichael Lotz
313bec02d0cSMichael Lotz keyring = fKeyrings.ItemAt(cookie);
31495eee1a3SMichael Lotz if (keyring == NULL) {
31595eee1a3SMichael Lotz result = B_ENTRY_NOT_FOUND;
31695eee1a3SMichael Lotz break;
31795eee1a3SMichael Lotz }
31895eee1a3SMichael Lotz
31995eee1a3SMichael Lotz cookie++;
32095eee1a3SMichael Lotz reply.AddUInt32("cookie", cookie);
32195eee1a3SMichael Lotz reply.AddString("keyring", keyring->Name());
32295eee1a3SMichael Lotz result = B_OK;
32395eee1a3SMichael Lotz break;
32495eee1a3SMichael Lotz }
32595eee1a3SMichael Lotz
326c8ae843fSMichael Lotz case KEY_STORE_IS_KEYRING_UNLOCKED:
32795eee1a3SMichael Lotz {
328c8ae843fSMichael Lotz reply.AddBool("unlocked", keyring->IsUnlocked());
32995eee1a3SMichael Lotz result = B_OK;
330f16fef70SMichael Lotz break;
33195eee1a3SMichael Lotz }
33295eee1a3SMichael Lotz
333c8ae843fSMichael Lotz case KEY_STORE_LOCK_KEYRING:
334ac9b28f0SMichael Lotz {
335c8ae843fSMichael Lotz keyring->Lock();
336ac9b28f0SMichael Lotz result = B_OK;
337f16fef70SMichael Lotz break;
338f16fef70SMichael Lotz }
339f16fef70SMichael Lotz
3404a0460a9SMichael Lotz case KEY_STORE_SET_UNLOCK_KEY:
3414a0460a9SMichael Lotz {
3424a0460a9SMichael Lotz BMessage keyMessage;
3434a0460a9SMichael Lotz if (message->FindMessage("key", &keyMessage) != B_OK) {
3444a0460a9SMichael Lotz result = B_BAD_VALUE;
3454a0460a9SMichael Lotz break;
3464a0460a9SMichael Lotz }
3474a0460a9SMichael Lotz
3484a0460a9SMichael Lotz result = keyring->SetUnlockKey(keyMessage);
3494a0460a9SMichael Lotz if (result == B_OK)
3504a0460a9SMichael Lotz _WriteKeyStoreDatabase();
3514a0460a9SMichael Lotz
3524a0460a9SMichael Lotz // TODO: Update the key in the master if this keyring was added.
3534a0460a9SMichael Lotz break;
3544a0460a9SMichael Lotz }
3554a0460a9SMichael Lotz
3564a0460a9SMichael Lotz case KEY_STORE_REMOVE_UNLOCK_KEY:
3574a0460a9SMichael Lotz {
3584a0460a9SMichael Lotz result = keyring->RemoveUnlockKey();
3594a0460a9SMichael Lotz if (result == B_OK)
3604a0460a9SMichael Lotz _WriteKeyStoreDatabase();
3614a0460a9SMichael Lotz
3624a0460a9SMichael Lotz break;
3634a0460a9SMichael Lotz }
3644a0460a9SMichael Lotz
365f16fef70SMichael Lotz case KEY_STORE_ADD_KEYRING_TO_MASTER:
366f16fef70SMichael Lotz case KEY_STORE_REMOVE_KEYRING_FROM_MASTER:
367f16fef70SMichael Lotz {
368a5a5f4caSMichael Lotz // We also need access to the master keyring.
369a5a5f4caSMichael Lotz while (!fMasterKeyring->IsUnlocked()) {
370a5a5f4caSMichael Lotz status_t unlockResult = _UnlockKeyring(*fMasterKeyring);
371c8ae843fSMichael Lotz if (unlockResult != B_OK) {
372c8ae843fSMichael Lotz result = unlockResult;
373f16fef70SMichael Lotz message->what = 0;
374f16fef70SMichael Lotz break;
375f16fef70SMichael Lotz }
376f16fef70SMichael Lotz }
377f16fef70SMichael Lotz
378f16fef70SMichael Lotz if (message->what == 0)
379f16fef70SMichael Lotz break;
380f16fef70SMichael Lotz
381f16fef70SMichael Lotz BString secondaryIdentifier = keyring->Name();
382a82011ffSMichael Lotz BMessage keyMessage = keyring->UnlockKey();
383f16fef70SMichael Lotz keyMessage.RemoveName("identifier");
384f16fef70SMichael Lotz keyMessage.AddString("identifier", kKeyringKeysIdentifier);
385f16fef70SMichael Lotz keyMessage.RemoveName("secondaryIdentifier");
386f16fef70SMichael Lotz keyMessage.AddString("secondaryIdentifier", secondaryIdentifier);
387f16fef70SMichael Lotz
388f16fef70SMichael Lotz switch (message->what) {
389f16fef70SMichael Lotz case KEY_STORE_ADD_KEYRING_TO_MASTER:
390a5a5f4caSMichael Lotz result = fMasterKeyring->AddKey(kKeyringKeysIdentifier,
391f16fef70SMichael Lotz secondaryIdentifier, keyMessage);
392f16fef70SMichael Lotz break;
393f16fef70SMichael Lotz
394f16fef70SMichael Lotz case KEY_STORE_REMOVE_KEYRING_FROM_MASTER:
395a5a5f4caSMichael Lotz result = fMasterKeyring->RemoveKey(kKeyringKeysIdentifier,
396f16fef70SMichael Lotz keyMessage);
397f16fef70SMichael Lotz break;
398f16fef70SMichael Lotz }
399f16fef70SMichael Lotz
400f16fef70SMichael Lotz if (result == B_OK)
401f16fef70SMichael Lotz _WriteKeyStoreDatabase();
402f16fef70SMichael Lotz
403f16fef70SMichael Lotz break;
404ac9b28f0SMichael Lotz }
405ac9b28f0SMichael Lotz
406b31a707aSMichael Lotz case KEY_STORE_GET_NEXT_APPLICATION:
407b31a707aSMichael Lotz {
408b31a707aSMichael Lotz uint32 cookie;
409b31a707aSMichael Lotz if (message->FindUInt32("cookie", &cookie) != B_OK) {
410b31a707aSMichael Lotz result = B_BAD_VALUE;
411b31a707aSMichael Lotz break;
412b31a707aSMichael Lotz }
413b31a707aSMichael Lotz
414b31a707aSMichael Lotz BString signature;
415b31a707aSMichael Lotz BString path;
416b31a707aSMichael Lotz result = keyring->GetNextApplication(cookie, signature, path);
417b31a707aSMichael Lotz if (result != B_OK)
418b31a707aSMichael Lotz break;
419b31a707aSMichael Lotz
420b31a707aSMichael Lotz reply.AddUInt32("cookie", cookie);
421b31a707aSMichael Lotz reply.AddString("signature", signature);
422b31a707aSMichael Lotz reply.AddString("path", path);
423b31a707aSMichael Lotz result = B_OK;
424b31a707aSMichael Lotz break;
425b31a707aSMichael Lotz }
426b31a707aSMichael Lotz
427b31a707aSMichael Lotz case KEY_STORE_REMOVE_APPLICATION:
428b31a707aSMichael Lotz {
429b31a707aSMichael Lotz const char* signature = NULL;
430b31a707aSMichael Lotz const char* path = NULL;
431b31a707aSMichael Lotz
432b31a707aSMichael Lotz if (message->FindString("signature", &signature) != B_OK) {
433b31a707aSMichael Lotz result = B_BAD_VALUE;
434b31a707aSMichael Lotz break;
435b31a707aSMichael Lotz }
436b31a707aSMichael Lotz
437b31a707aSMichael Lotz if (message->FindString("path", &path) != B_OK)
438b31a707aSMichael Lotz path = NULL;
439b31a707aSMichael Lotz
440b31a707aSMichael Lotz result = keyring->RemoveApplication(signature, path);
441d3b8b801SMichael Lotz if (result == B_OK)
442d3b8b801SMichael Lotz _WriteKeyStoreDatabase();
443d3b8b801SMichael Lotz
444b31a707aSMichael Lotz break;
445b31a707aSMichael Lotz }
446b31a707aSMichael Lotz
44795eee1a3SMichael Lotz case 0:
44895eee1a3SMichael Lotz {
44995eee1a3SMichael Lotz // Just the error case from above.
4508d9bc9e0SMichael Lotz break;
4518d9bc9e0SMichael Lotz }
4528d9bc9e0SMichael Lotz
4538d9bc9e0SMichael Lotz default:
4548d9bc9e0SMichael Lotz {
4558d9bc9e0SMichael Lotz printf("unknown message received: %" B_PRIu32 " \"%.4s\"\n",
4568d9bc9e0SMichael Lotz message->what, (const char*)&message->what);
4578d9bc9e0SMichael Lotz break;
4588d9bc9e0SMichael Lotz }
4598d9bc9e0SMichael Lotz }
4608d9bc9e0SMichael Lotz
4610dfaf59dSMichael Lotz if (message->IsSourceWaiting()) {
4620dfaf59dSMichael Lotz if (result == B_OK)
4630dfaf59dSMichael Lotz reply.what = KEY_STORE_SUCCESS;
4640dfaf59dSMichael Lotz else {
4650dfaf59dSMichael Lotz reply.what = KEY_STORE_RESULT;
4660dfaf59dSMichael Lotz reply.AddInt32("result", result);
4670dfaf59dSMichael Lotz }
4680dfaf59dSMichael Lotz
4690dfaf59dSMichael Lotz message->SendReply(&reply);
4700dfaf59dSMichael Lotz }
4718d9bc9e0SMichael Lotz }
4728d9bc9e0SMichael Lotz
4738d9bc9e0SMichael Lotz
4748d9bc9e0SMichael Lotz status_t
_ReadKeyStoreDatabase()4750dfaf59dSMichael Lotz KeyStoreServer::_ReadKeyStoreDatabase()
4768d9bc9e0SMichael Lotz {
477bec02d0cSMichael Lotz BMessage keystore;
478bec02d0cSMichael Lotz status_t result = keystore.Unflatten(&fKeyStoreFile);
4790dfaf59dSMichael Lotz if (result != B_OK) {
4800dfaf59dSMichael Lotz printf("failed to read keystore database\n");
4810dfaf59dSMichael Lotz _WriteKeyStoreDatabase();
482bec02d0cSMichael Lotz // Reinitializes the database.
4830dfaf59dSMichael Lotz return result;
4840dfaf59dSMichael Lotz }
4850dfaf59dSMichael Lotz
48695eee1a3SMichael Lotz int32 index = 0;
487bec02d0cSMichael Lotz BMessage keyringData;
488bec02d0cSMichael Lotz while (keystore.FindMessage("keyrings", index++, &keyringData) == B_OK) {
489bec02d0cSMichael Lotz Keyring* keyring = new(std::nothrow) Keyring();
4901b3bb46aSMichael Lotz if (keyring == NULL) {
491bec02d0cSMichael Lotz printf("no memory for allocating keyring\n");
492bec02d0cSMichael Lotz break;
49395eee1a3SMichael Lotz }
49495eee1a3SMichael Lotz
495bec02d0cSMichael Lotz status_t result = keyring->ReadFromMessage(keyringData);
4961b3bb46aSMichael Lotz if (result != B_OK) {
497bec02d0cSMichael Lotz printf("failed to read keyring from data\n");
4981b3bb46aSMichael Lotz delete keyring;
49995eee1a3SMichael Lotz continue;
50095eee1a3SMichael Lotz }
50195eee1a3SMichael Lotz
502bec02d0cSMichael Lotz if (strcmp(keyring->Name(), kMasterKeyringName) == 0)
503a5a5f4caSMichael Lotz fMasterKeyring = keyring;
504bec02d0cSMichael Lotz
50595eee1a3SMichael Lotz fKeyrings.BinaryInsert(keyring, &Keyring::Compare);
50695eee1a3SMichael Lotz }
50795eee1a3SMichael Lotz
5080dfaf59dSMichael Lotz return B_OK;
5090dfaf59dSMichael Lotz }
5100dfaf59dSMichael Lotz
5110dfaf59dSMichael Lotz
5120dfaf59dSMichael Lotz status_t
_WriteKeyStoreDatabase()5130dfaf59dSMichael Lotz KeyStoreServer::_WriteKeyStoreDatabase()
5140dfaf59dSMichael Lotz {
515bec02d0cSMichael Lotz BMessage keystore;
516bec02d0cSMichael Lotz keystore.AddUInt32("format", kKeyStoreFormatVersion);
5170dfaf59dSMichael Lotz
51895eee1a3SMichael Lotz for (int32 i = 0; i < fKeyrings.CountItems(); i++) {
51995eee1a3SMichael Lotz Keyring* keyring = fKeyrings.ItemAt(i);
52095eee1a3SMichael Lotz if (keyring == NULL)
5210dfaf59dSMichael Lotz continue;
52295eee1a3SMichael Lotz
523bec02d0cSMichael Lotz BMessage keyringData;
524bec02d0cSMichael Lotz status_t result = keyring->WriteToMessage(keyringData);
5251b3bb46aSMichael Lotz if (result != B_OK)
5261b3bb46aSMichael Lotz return result;
527bec02d0cSMichael Lotz
528bec02d0cSMichael Lotz keystore.AddMessage("keyrings", &keyringData);
5290dfaf59dSMichael Lotz }
5300dfaf59dSMichael Lotz
531aef629f2SMichael Lotz fKeyStoreFile.SetSize(0);
532aef629f2SMichael Lotz fKeyStoreFile.Seek(0, SEEK_SET);
533bec02d0cSMichael Lotz return keystore.Flatten(&fKeyStoreFile);
5340dfaf59dSMichael Lotz }
5350dfaf59dSMichael Lotz
5360dfaf59dSMichael Lotz
53797b3abf1SMichael Lotz uint32
_AccessFlagsFor(uint32 command) const53897b3abf1SMichael Lotz KeyStoreServer::_AccessFlagsFor(uint32 command) const
53997b3abf1SMichael Lotz {
54097b3abf1SMichael Lotz switch (command) {
54197b3abf1SMichael Lotz case KEY_STORE_GET_KEY:
54297b3abf1SMichael Lotz return kFlagGetKey;
54397b3abf1SMichael Lotz case KEY_STORE_GET_NEXT_KEY:
54497b3abf1SMichael Lotz return kFlagEnumerateKeys;
54597b3abf1SMichael Lotz case KEY_STORE_ADD_KEY:
54697b3abf1SMichael Lotz return kFlagAddKey;
54797b3abf1SMichael Lotz case KEY_STORE_REMOVE_KEY:
54897b3abf1SMichael Lotz return kFlagRemoveKey;
54997b3abf1SMichael Lotz case KEY_STORE_ADD_KEYRING:
55097b3abf1SMichael Lotz return kFlagAddKeyring;
55197b3abf1SMichael Lotz case KEY_STORE_REMOVE_KEYRING:
55297b3abf1SMichael Lotz return kFlagRemoveKeyring;
55397b3abf1SMichael Lotz case KEY_STORE_GET_NEXT_KEYRING:
55497b3abf1SMichael Lotz return kFlagEnumerateKeyrings;
5554a0460a9SMichael Lotz case KEY_STORE_SET_UNLOCK_KEY:
5564a0460a9SMichael Lotz return kFlagSetUnlockKey;
5574a0460a9SMichael Lotz case KEY_STORE_REMOVE_UNLOCK_KEY:
5584a0460a9SMichael Lotz return kFlagRemoveUnlockKey;
55997b3abf1SMichael Lotz case KEY_STORE_ADD_KEYRING_TO_MASTER:
56097b3abf1SMichael Lotz return kFlagAddKeyringsToMaster;
56197b3abf1SMichael Lotz case KEY_STORE_REMOVE_KEYRING_FROM_MASTER:
56297b3abf1SMichael Lotz return kFlagRemoveKeyringsFromMaster;
56397b3abf1SMichael Lotz case KEY_STORE_GET_NEXT_MASTER_KEYRING:
56497b3abf1SMichael Lotz return kFlagEnumerateMasterKeyrings;
565c8ae843fSMichael Lotz case KEY_STORE_IS_KEYRING_UNLOCKED:
566c8ae843fSMichael Lotz return kFlagQueryLockState;
567c8ae843fSMichael Lotz case KEY_STORE_LOCK_KEYRING:
568c8ae843fSMichael Lotz return kFlagLockKeyring;
56997b3abf1SMichael Lotz case KEY_STORE_GET_NEXT_APPLICATION:
57097b3abf1SMichael Lotz return kFlagEnumerateApplications;
57197b3abf1SMichael Lotz case KEY_STORE_REMOVE_APPLICATION:
57297b3abf1SMichael Lotz return kFlagRemoveApplications;
57397b3abf1SMichael Lotz }
57497b3abf1SMichael Lotz
57597b3abf1SMichael Lotz return 0;
57697b3abf1SMichael Lotz }
57797b3abf1SMichael Lotz
57897b3abf1SMichael Lotz
579a2f27987SMichael Lotz const char*
_AccessStringFor(uint32 accessFlag) const580a2f27987SMichael Lotz KeyStoreServer::_AccessStringFor(uint32 accessFlag) const
581a2f27987SMichael Lotz {
582a2f27987SMichael Lotz switch (accessFlag) {
583a2f27987SMichael Lotz case kFlagGetKey:
584a2f27987SMichael Lotz return "Get keys from the keyring.";
585a2f27987SMichael Lotz case kFlagEnumerateKeys:
586a2f27987SMichael Lotz return "Enumerate and get keys from the keyring.";
587a2f27987SMichael Lotz case kFlagAddKey:
588a2f27987SMichael Lotz return "Add keys to the keyring.";
589a2f27987SMichael Lotz case kFlagRemoveKey:
590a2f27987SMichael Lotz return "Remove keys from the keyring.";
591a2f27987SMichael Lotz case kFlagAddKeyring:
592a2f27987SMichael Lotz return "Add new keyrings.";
593a2f27987SMichael Lotz case kFlagRemoveKeyring:
594a2f27987SMichael Lotz return "Remove keyrings.";
595a2f27987SMichael Lotz case kFlagEnumerateKeyrings:
596a2f27987SMichael Lotz return "Enumerate the available keyrings.";
5974a0460a9SMichael Lotz case kFlagSetUnlockKey:
5984a0460a9SMichael Lotz return "Set the unlock key of the keyring.";
5994a0460a9SMichael Lotz case kFlagRemoveUnlockKey:
6004a0460a9SMichael Lotz return "Remove the unlock key of the keyring.";
601a2f27987SMichael Lotz case kFlagAddKeyringsToMaster:
602a2f27987SMichael Lotz return "Add the keyring key to the master keyring.";
603a2f27987SMichael Lotz case kFlagRemoveKeyringsFromMaster:
604a2f27987SMichael Lotz return "Remove the keyring key from the master keyring.";
605a2f27987SMichael Lotz case kFlagEnumerateMasterKeyrings:
606a2f27987SMichael Lotz return "Enumerate keyrings added to the master keyring.";
607a2f27987SMichael Lotz case kFlagQueryLockState:
608a2f27987SMichael Lotz return "Query the lock state of the keyring.";
609a2f27987SMichael Lotz case kFlagLockKeyring:
610a2f27987SMichael Lotz return "Lock the keyring.";
611a2f27987SMichael Lotz case kFlagEnumerateApplications:
612a2f27987SMichael Lotz return "Enumerate the applications of the keyring.";
613a2f27987SMichael Lotz case kFlagRemoveApplications:
614a2f27987SMichael Lotz return "Remove applications from the keyring.";
615a2f27987SMichael Lotz }
616a2f27987SMichael Lotz
617a2f27987SMichael Lotz return NULL;
618a2f27987SMichael Lotz }
619a2f27987SMichael Lotz
620a2f27987SMichael Lotz
62176df966eSMichael Lotz status_t
_ResolveCallingApp(const BMessage & message,app_info & callingAppInfo) const62276df966eSMichael Lotz KeyStoreServer::_ResolveCallingApp(const BMessage& message,
62376df966eSMichael Lotz app_info& callingAppInfo) const
62476df966eSMichael Lotz {
62576df966eSMichael Lotz team_id callingTeam = message.ReturnAddress().Team();
62676df966eSMichael Lotz status_t result = be_roster->GetRunningAppInfo(callingTeam,
62776df966eSMichael Lotz &callingAppInfo);
62876df966eSMichael Lotz if (result != B_OK)
62976df966eSMichael Lotz return result;
63076df966eSMichael Lotz
63176df966eSMichael Lotz // Do some sanity checks.
63276df966eSMichael Lotz if (callingAppInfo.team != callingTeam)
63376df966eSMichael Lotz return B_ERROR;
63476df966eSMichael Lotz
63576df966eSMichael Lotz return B_OK;
63676df966eSMichael Lotz }
63776df966eSMichael Lotz
63876df966eSMichael Lotz
639cfa81315SMichael Lotz status_t
_ValidateAppAccess(Keyring & keyring,const app_info & appInfo,uint32 accessFlags)640cfa81315SMichael Lotz KeyStoreServer::_ValidateAppAccess(Keyring& keyring, const app_info& appInfo,
641cfa81315SMichael Lotz uint32 accessFlags)
642cfa81315SMichael Lotz {
643cfa81315SMichael Lotz BMessage appMessage;
644cfa81315SMichael Lotz BPath path(&appInfo.ref);
645cfa81315SMichael Lotz status_t result = keyring.FindApplication(appInfo.signature,
646cfa81315SMichael Lotz path.Path(), appMessage);
647cfa81315SMichael Lotz if (result != B_OK && result != B_ENTRY_NOT_FOUND)
648cfa81315SMichael Lotz return result;
649cfa81315SMichael Lotz
650cfa81315SMichael Lotz // TODO: Implement running image checksum mechanism.
651*707717e8SAxel Dörfler BString checksum = path.Path();
652cfa81315SMichael Lotz
653cfa81315SMichael Lotz bool appIsNew = false;
654cfa81315SMichael Lotz bool appWasUpdated = false;
655cfa81315SMichael Lotz uint32 appFlags = 0;
656cfa81315SMichael Lotz BString appSum = "";
657cfa81315SMichael Lotz if (result == B_OK) {
658cfa81315SMichael Lotz if (appMessage.FindUInt32("flags", &appFlags) != B_OK
659cfa81315SMichael Lotz || appMessage.FindString("checksum", &appSum) != B_OK) {
660cfa81315SMichael Lotz appIsNew = true;
661cfa81315SMichael Lotz appFlags = 0;
662cfa81315SMichael Lotz } else if (appSum != checksum) {
663cfa81315SMichael Lotz appWasUpdated = true;
664cfa81315SMichael Lotz appFlags = 0;
665cfa81315SMichael Lotz }
666cfa81315SMichael Lotz } else
667cfa81315SMichael Lotz appIsNew = true;
668cfa81315SMichael Lotz
669cfa81315SMichael Lotz if ((accessFlags & appFlags) == accessFlags)
670cfa81315SMichael Lotz return B_OK;
671cfa81315SMichael Lotz
672a59169deSMichael Lotz const char* accessString = _AccessStringFor(accessFlags);
673cfa81315SMichael Lotz bool allowAlways = false;
674cfa81315SMichael Lotz result = _RequestAppAccess(keyring.Name(), appInfo.signature, path.Path(),
675a59169deSMichael Lotz accessString, appIsNew, appWasUpdated, accessFlags, allowAlways);
676cfa81315SMichael Lotz if (result != B_OK || !allowAlways)
677cfa81315SMichael Lotz return result;
678cfa81315SMichael Lotz
679cfa81315SMichael Lotz appMessage.MakeEmpty();
680cfa81315SMichael Lotz appMessage.AddString("path", path.Path());
681ee834720SMichael Lotz appMessage.AddUInt32("flags", appFlags | accessFlags);
682cfa81315SMichael Lotz appMessage.AddString("checksum", checksum);
683cfa81315SMichael Lotz
684cfa81315SMichael Lotz keyring.RemoveApplication(appInfo.signature, path.Path());
685cfa81315SMichael Lotz if (keyring.AddApplication(appInfo.signature, appMessage) == B_OK)
686cfa81315SMichael Lotz _WriteKeyStoreDatabase();
687cfa81315SMichael Lotz
688cfa81315SMichael Lotz return B_OK;
689cfa81315SMichael Lotz }
690cfa81315SMichael Lotz
691cfa81315SMichael Lotz
692cfa81315SMichael Lotz status_t
_RequestAppAccess(const BString & keyringName,const char * signature,const char * path,const char * accessString,bool appIsNew,bool appWasUpdated,uint32 accessFlags,bool & allowAlways)693cfa81315SMichael Lotz KeyStoreServer::_RequestAppAccess(const BString& keyringName,
694a59169deSMichael Lotz const char* signature, const char* path, const char* accessString,
695a59169deSMichael Lotz bool appIsNew, bool appWasUpdated, uint32 accessFlags, bool& allowAlways)
696cfa81315SMichael Lotz {
697cfa81315SMichael Lotz AppAccessRequestWindow* requestWindow
698cfa81315SMichael Lotz = new(std::nothrow) AppAccessRequestWindow(keyringName, signature, path,
699a59169deSMichael Lotz accessString, appIsNew, appWasUpdated);
700cfa81315SMichael Lotz if (requestWindow == NULL)
701cfa81315SMichael Lotz return B_NO_MEMORY;
702cfa81315SMichael Lotz
703cfa81315SMichael Lotz return requestWindow->RequestAppAccess(allowAlways);
704cfa81315SMichael Lotz }
705cfa81315SMichael Lotz
706cfa81315SMichael Lotz
70795eee1a3SMichael Lotz Keyring*
_FindKeyring(const BString & name)70895eee1a3SMichael Lotz KeyStoreServer::_FindKeyring(const BString& name)
70995eee1a3SMichael Lotz {
710a5a5f4caSMichael Lotz if (name.IsEmpty() || name == kMasterKeyringName)
711a5a5f4caSMichael Lotz return fMasterKeyring;
7120dfaf59dSMichael Lotz
71395eee1a3SMichael Lotz return fKeyrings.BinarySearchByKey(name, &Keyring::Compare);
7140dfaf59dSMichael Lotz }
7150dfaf59dSMichael Lotz
7160dfaf59dSMichael Lotz
7170dfaf59dSMichael Lotz status_t
_AddKeyring(const BString & name)718d4d6d123SMichael Lotz KeyStoreServer::_AddKeyring(const BString& name)
7190dfaf59dSMichael Lotz {
72095eee1a3SMichael Lotz if (_FindKeyring(name) != NULL)
7210dfaf59dSMichael Lotz return B_NAME_IN_USE;
7220dfaf59dSMichael Lotz
723d4d6d123SMichael Lotz Keyring* keyring = new(std::nothrow) Keyring(name);
72495eee1a3SMichael Lotz if (keyring == NULL)
72595eee1a3SMichael Lotz return B_NO_MEMORY;
72695eee1a3SMichael Lotz
72795eee1a3SMichael Lotz if (!fKeyrings.BinaryInsert(keyring, &Keyring::Compare)) {
72895eee1a3SMichael Lotz delete keyring;
72995eee1a3SMichael Lotz return B_ERROR;
73095eee1a3SMichael Lotz }
73195eee1a3SMichael Lotz
73295eee1a3SMichael Lotz return B_OK;
73395eee1a3SMichael Lotz }
73495eee1a3SMichael Lotz
73595eee1a3SMichael Lotz
73695eee1a3SMichael Lotz status_t
_RemoveKeyring(const BString & name)73795eee1a3SMichael Lotz KeyStoreServer::_RemoveKeyring(const BString& name)
73895eee1a3SMichael Lotz {
73995eee1a3SMichael Lotz Keyring* keyring = _FindKeyring(name);
74095eee1a3SMichael Lotz if (keyring == NULL)
74195eee1a3SMichael Lotz return B_ENTRY_NOT_FOUND;
74295eee1a3SMichael Lotz
743a5a5f4caSMichael Lotz if (keyring == fMasterKeyring) {
744a5a5f4caSMichael Lotz // The master keyring can't be removed.
74595eee1a3SMichael Lotz return B_NOT_ALLOWED;
74695eee1a3SMichael Lotz }
74795eee1a3SMichael Lotz
74895eee1a3SMichael Lotz return fKeyrings.RemoveItem(keyring) ? B_OK : B_ERROR;
7498d9bc9e0SMichael Lotz }
7508d9bc9e0SMichael Lotz
7518d9bc9e0SMichael Lotz
752ac9b28f0SMichael Lotz status_t
_UnlockKeyring(Keyring & keyring)753c8ae843fSMichael Lotz KeyStoreServer::_UnlockKeyring(Keyring& keyring)
754ac9b28f0SMichael Lotz {
755a82011ffSMichael Lotz if (!keyring.HasUnlockKey())
756a82011ffSMichael Lotz return keyring.Unlock(NULL);
757a82011ffSMichael Lotz
758ac9b28f0SMichael Lotz // If we are accessing a keyring that has been added to master access we
759a5a5f4caSMichael Lotz // get the key from the master keyring and unlock with that.
760ac9b28f0SMichael Lotz BMessage keyMessage;
761a5a5f4caSMichael Lotz if (&keyring != fMasterKeyring && fMasterKeyring->IsUnlocked()) {
762a5a5f4caSMichael Lotz if (fMasterKeyring->FindKey(kKeyringKeysIdentifier, keyring.Name(),
763f16fef70SMichael Lotz false, &keyMessage) == B_OK) {
764c8ae843fSMichael Lotz // We found a key for this keyring, try to unlock with it.
765a82011ffSMichael Lotz if (keyring.Unlock(&keyMessage) == B_OK)
766ac9b28f0SMichael Lotz return B_OK;
767ac9b28f0SMichael Lotz }
768ac9b28f0SMichael Lotz }
769ac9b28f0SMichael Lotz
770ac9b28f0SMichael Lotz // No key, we need to request one from the user.
77190013c82SMichael Lotz status_t result = _RequestKey(keyring.Name(), keyMessage);
772ac9b28f0SMichael Lotz if (result != B_OK)
773ac9b28f0SMichael Lotz return result;
774ac9b28f0SMichael Lotz
775a82011ffSMichael Lotz return keyring.Unlock(&keyMessage);
776ac9b28f0SMichael Lotz }
777ac9b28f0SMichael Lotz
778ac9b28f0SMichael Lotz
779ac9b28f0SMichael Lotz status_t
_RequestKey(const BString & keyringName,BMessage & keyMessage)78090013c82SMichael Lotz KeyStoreServer::_RequestKey(const BString& keyringName, BMessage& keyMessage)
781ac9b28f0SMichael Lotz {
782ac9b28f0SMichael Lotz KeyRequestWindow* requestWindow = new(std::nothrow) KeyRequestWindow();
783ac9b28f0SMichael Lotz if (requestWindow == NULL)
784ac9b28f0SMichael Lotz return B_NO_MEMORY;
785ac9b28f0SMichael Lotz
78690013c82SMichael Lotz return requestWindow->RequestKey(keyringName, keyMessage);
787ac9b28f0SMichael Lotz }
788ac9b28f0SMichael Lotz
789ac9b28f0SMichael Lotz
7908d9bc9e0SMichael Lotz int
main(int argc,char * argv[])7918d9bc9e0SMichael Lotz main(int argc, char* argv[])
7928d9bc9e0SMichael Lotz {
7938d9bc9e0SMichael Lotz KeyStoreServer* app = new(std::nothrow) KeyStoreServer();
7948d9bc9e0SMichael Lotz if (app == NULL)
7958d9bc9e0SMichael Lotz return 1;
7968d9bc9e0SMichael Lotz
7978d9bc9e0SMichael Lotz app->Run();
7988d9bc9e0SMichael Lotz delete app;
7998d9bc9e0SMichael Lotz return 0;
8008d9bc9e0SMichael Lotz }
801