xref: /haiku/src/servers/keystore/KeyStoreServer.cpp (revision 707717e8bec291f31bef0e5ccaa92de5badc6f54)
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