xref: /haiku/src/servers/keystore/KeyStoreServer.cpp (revision bec02d0c2f483a804eb0b833d099b85b3660cdb0)
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 
33*bec02d0cSMichael Lotz static const uint32 kKeyStoreFormatVersion = 1;
34*bec02d0cSMichael 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;
4297b3abf1SMichael Lotz static const uint32 kFlagSetMasterKey				= 0x0080;
4397b3abf1SMichael Lotz static const uint32 kFlagRemoveMasterKey			= 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
5497b3abf1SMichael Lotz 	| kFlagEnumerateKeyrings | kFlagSetMasterKey | kFlagRemoveMasterKey
5597b3abf1SMichael Lotz 	| kFlagAddKeyringsToMaster | kFlagRemoveKeyringsFromMaster
56c8ae843fSMichael Lotz 	| kFlagEnumerateMasterKeyrings | kFlagQueryLockState | kFlagLockKeyring
57c8ae843fSMichael Lotz 	| kFlagEnumerateApplications | kFlagRemoveApplications;
5897b3abf1SMichael Lotz 
59f16fef70SMichael Lotz 
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 
88*bec02d0cSMichael Lotz 	if (fMasterKeyring == NULL) {
89a5a5f4caSMichael Lotz 		fMasterKeyring = new(std::nothrow) Keyring(kMasterKeyringName);
90*bec02d0cSMichael Lotz 		fKeyrings.BinaryInsert(fMasterKeyring, &Keyring::Compare);
91*bec02d0cSMichael Lotz 	}
928d9bc9e0SMichael Lotz }
938d9bc9e0SMichael Lotz 
948d9bc9e0SMichael Lotz 
958d9bc9e0SMichael Lotz KeyStoreServer::~KeyStoreServer()
968d9bc9e0SMichael Lotz {
978d9bc9e0SMichael Lotz }
988d9bc9e0SMichael Lotz 
998d9bc9e0SMichael Lotz 
1008d9bc9e0SMichael Lotz void
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:
126f16fef70SMichael Lotz 		case KEY_STORE_ADD_KEYRING_TO_MASTER:
127f16fef70SMichael Lotz 		case KEY_STORE_REMOVE_KEYRING_FROM_MASTER:
128b31a707aSMichael Lotz 		case KEY_STORE_GET_NEXT_APPLICATION:
129b31a707aSMichael Lotz 		case KEY_STORE_REMOVE_APPLICATION:
13095eee1a3SMichael Lotz 		{
13195eee1a3SMichael Lotz 			BString keyringName;
13295eee1a3SMichael Lotz 			if (message->FindString("keyring", &keyringName) != B_OK)
13395eee1a3SMichael Lotz 				keyringName = "";
13495eee1a3SMichael Lotz 
13595eee1a3SMichael Lotz 			keyring = _FindKeyring(keyringName);
13695eee1a3SMichael Lotz 			if (keyring == NULL) {
13795eee1a3SMichael Lotz 				result = B_BAD_VALUE;
13895eee1a3SMichael Lotz 				message->what = 0;
13995eee1a3SMichael Lotz 					// So that we don't do anything in the second switch.
14095eee1a3SMichael Lotz 				break;
14195eee1a3SMichael Lotz 			}
14295eee1a3SMichael Lotz 
143ac9b28f0SMichael Lotz 			switch (message->what) {
144ac9b28f0SMichael Lotz 				case KEY_STORE_GET_KEY:
145ac9b28f0SMichael Lotz 				case KEY_STORE_GET_NEXT_KEY:
146ac9b28f0SMichael Lotz 				case KEY_STORE_ADD_KEY:
147ac9b28f0SMichael Lotz 				case KEY_STORE_REMOVE_KEY:
148f16fef70SMichael Lotz 				case KEY_STORE_ADD_KEYRING_TO_MASTER:
149b31a707aSMichael Lotz 				case KEY_STORE_GET_NEXT_APPLICATION:
150b31a707aSMichael Lotz 				case KEY_STORE_REMOVE_APPLICATION:
151ac9b28f0SMichael Lotz 				{
152ac9b28f0SMichael Lotz 					// These need keyring access to do anything.
153c8ae843fSMichael Lotz 					while (!keyring->IsUnlocked()) {
154c8ae843fSMichael Lotz 						status_t unlockResult = _UnlockKeyring(*keyring);
155c8ae843fSMichael Lotz 						if (unlockResult != B_OK) {
156c8ae843fSMichael Lotz 							result = unlockResult;
157ac9b28f0SMichael Lotz 							message->what = 0;
158ac9b28f0SMichael Lotz 							break;
159ac9b28f0SMichael Lotz 						}
160ac9b28f0SMichael Lotz 					}
161cfa81315SMichael Lotz 
162cfa81315SMichael Lotz 					status_t validateResult = _ValidateAppAccess(*keyring,
163cfa81315SMichael Lotz 						callingAppInfo, accessFlags);
164cfa81315SMichael Lotz 					if (validateResult != B_OK) {
165cfa81315SMichael Lotz 						result = validateResult;
166cfa81315SMichael Lotz 						message->what = 0;
167cfa81315SMichael Lotz 						break;
168cfa81315SMichael Lotz 					}
169cfa81315SMichael Lotz 
170cfa81315SMichael Lotz 					break;
171ac9b28f0SMichael Lotz 				}
172ac9b28f0SMichael Lotz 			}
173ac9b28f0SMichael Lotz 
17495eee1a3SMichael Lotz 			break;
17595eee1a3SMichael Lotz 		}
17695eee1a3SMichael Lotz 	}
1770dfaf59dSMichael Lotz 
1788d9bc9e0SMichael Lotz 	switch (message->what) {
1798d9bc9e0SMichael Lotz 		case KEY_STORE_GET_KEY:
1808d9bc9e0SMichael Lotz 		{
18195eee1a3SMichael Lotz 			BString identifier;
18295eee1a3SMichael Lotz 			if (message->FindString("identifier", &identifier) != B_OK) {
18395eee1a3SMichael Lotz 				result = B_BAD_VALUE;
18495eee1a3SMichael Lotz 				break;
18595eee1a3SMichael Lotz 			}
18695eee1a3SMichael Lotz 
18795eee1a3SMichael Lotz 			bool secondaryIdentifierOptional;
18895eee1a3SMichael Lotz 			if (message->FindBool("secondaryIdentifierOptional",
18995eee1a3SMichael Lotz 					&secondaryIdentifierOptional) != B_OK) {
19095eee1a3SMichael Lotz 				secondaryIdentifierOptional = false;
19195eee1a3SMichael Lotz 			}
19295eee1a3SMichael Lotz 
19395eee1a3SMichael Lotz 			BString secondaryIdentifier;
19495eee1a3SMichael Lotz 			if (message->FindString("secondaryIdentifier",
19595eee1a3SMichael Lotz 					&secondaryIdentifier) != B_OK) {
19695eee1a3SMichael Lotz 				secondaryIdentifier = "";
19795eee1a3SMichael Lotz 				secondaryIdentifierOptional = true;
19895eee1a3SMichael Lotz 			}
19995eee1a3SMichael Lotz 
20095eee1a3SMichael Lotz 			BMessage keyMessage;
20195eee1a3SMichael Lotz 			result = keyring->FindKey(identifier, secondaryIdentifier,
20295eee1a3SMichael Lotz 				secondaryIdentifierOptional, &keyMessage);
20395eee1a3SMichael Lotz 			if (result == B_OK)
20495eee1a3SMichael Lotz 				reply.AddMessage("key", &keyMessage);
205f16fef70SMichael Lotz 
2068d9bc9e0SMichael Lotz 			break;
2078d9bc9e0SMichael Lotz 		}
2088d9bc9e0SMichael Lotz 
2098d9bc9e0SMichael Lotz 		case KEY_STORE_GET_NEXT_KEY:
2108d9bc9e0SMichael Lotz 		{
2110dfaf59dSMichael Lotz 			BKeyType type;
2120dfaf59dSMichael Lotz 			BKeyPurpose purpose;
2130dfaf59dSMichael Lotz 			uint32 cookie;
2140dfaf59dSMichael Lotz 			if (message->FindUInt32("type", (uint32*)&type) != B_OK
2150dfaf59dSMichael Lotz 				|| message->FindUInt32("purpose", (uint32*)&purpose) != B_OK
2160dfaf59dSMichael Lotz 				|| message->FindUInt32("cookie", &cookie) != B_OK) {
2170dfaf59dSMichael Lotz 				result = B_BAD_VALUE;
2180dfaf59dSMichael Lotz 				break;
2190dfaf59dSMichael Lotz 			}
2200dfaf59dSMichael Lotz 
2210dfaf59dSMichael Lotz 			BMessage keyMessage;
22295eee1a3SMichael Lotz 			result = keyring->FindKey(type, purpose, cookie, keyMessage);
2230dfaf59dSMichael Lotz 			if (result == B_OK) {
2240dfaf59dSMichael Lotz 				cookie++;
2250dfaf59dSMichael Lotz 				reply.AddUInt32("cookie", cookie);
2260dfaf59dSMichael Lotz 				reply.AddMessage("key", &keyMessage);
2270dfaf59dSMichael Lotz 			}
2280dfaf59dSMichael Lotz 
2290dfaf59dSMichael Lotz 			break;
2300dfaf59dSMichael Lotz 		}
2310dfaf59dSMichael Lotz 
2320dfaf59dSMichael Lotz 		case KEY_STORE_ADD_KEY:
2330dfaf59dSMichael Lotz 		{
2340dfaf59dSMichael Lotz 			BMessage keyMessage;
2350dfaf59dSMichael Lotz 			BString identifier;
2360dfaf59dSMichael Lotz 			if (message->FindMessage("key", &keyMessage) != B_OK
2370dfaf59dSMichael Lotz 				|| keyMessage.FindString("identifier", &identifier) != B_OK) {
2380dfaf59dSMichael Lotz 				result = B_BAD_VALUE;
2390dfaf59dSMichael Lotz 				break;
2400dfaf59dSMichael Lotz 			}
2410dfaf59dSMichael Lotz 
2420dfaf59dSMichael Lotz 			BString secondaryIdentifier;
2430dfaf59dSMichael Lotz 			if (keyMessage.FindString("secondaryIdentifier",
2440dfaf59dSMichael Lotz 					&secondaryIdentifier) != B_OK) {
2450dfaf59dSMichael Lotz 				secondaryIdentifier = "";
2460dfaf59dSMichael Lotz 			}
2470dfaf59dSMichael Lotz 
24895eee1a3SMichael Lotz 			result = keyring->AddKey(identifier, secondaryIdentifier, keyMessage);
24995eee1a3SMichael Lotz 			if (result == B_OK)
25095eee1a3SMichael Lotz 				_WriteKeyStoreDatabase();
25195eee1a3SMichael Lotz 
25295eee1a3SMichael Lotz 			break;
25395eee1a3SMichael Lotz 		}
25495eee1a3SMichael Lotz 
25595eee1a3SMichael Lotz 		case KEY_STORE_REMOVE_KEY:
25695eee1a3SMichael Lotz 		{
25795eee1a3SMichael Lotz 			BMessage keyMessage;
25895eee1a3SMichael Lotz 			BString identifier;
25995eee1a3SMichael Lotz 			if (message->FindMessage("key", &keyMessage) != B_OK
26095eee1a3SMichael Lotz 				|| keyMessage.FindString("identifier", &identifier) != B_OK) {
26195eee1a3SMichael Lotz 				result = B_BAD_VALUE;
26295eee1a3SMichael Lotz 				break;
26395eee1a3SMichael Lotz 			}
26495eee1a3SMichael Lotz 
26595eee1a3SMichael Lotz 			result = keyring->RemoveKey(identifier, keyMessage);
26695eee1a3SMichael Lotz 			if (result == B_OK)
26795eee1a3SMichael Lotz 				_WriteKeyStoreDatabase();
26895eee1a3SMichael Lotz 
26995eee1a3SMichael Lotz 			break;
27095eee1a3SMichael Lotz 		}
27195eee1a3SMichael Lotz 
27295eee1a3SMichael Lotz 		case KEY_STORE_ADD_KEYRING:
27395eee1a3SMichael Lotz 		{
27495eee1a3SMichael Lotz 			BMessage keyMessage;
27595eee1a3SMichael Lotz 			BString keyring;
276d4d6d123SMichael Lotz 			if (message->FindString("keyring", &keyring) != B_OK) {
27795eee1a3SMichael Lotz 				result = B_BAD_VALUE;
27895eee1a3SMichael Lotz 				break;
27995eee1a3SMichael Lotz 			}
28095eee1a3SMichael Lotz 
281d4d6d123SMichael Lotz 			result = _AddKeyring(keyring);
28295eee1a3SMichael Lotz 			if (result == B_OK)
28395eee1a3SMichael Lotz 				_WriteKeyStoreDatabase();
28495eee1a3SMichael Lotz 
28595eee1a3SMichael Lotz 			break;
28695eee1a3SMichael Lotz 		}
28795eee1a3SMichael Lotz 
28895eee1a3SMichael Lotz 		case KEY_STORE_REMOVE_KEYRING:
28995eee1a3SMichael Lotz 		{
29095eee1a3SMichael Lotz 			BString keyringName;
29195eee1a3SMichael Lotz 			if (message->FindString("keyring", &keyringName) != B_OK)
29295eee1a3SMichael Lotz 				keyringName = "";
29395eee1a3SMichael Lotz 
29495eee1a3SMichael Lotz 			result = _RemoveKeyring(keyringName);
29595eee1a3SMichael Lotz 			if (result == B_OK)
29695eee1a3SMichael Lotz 				_WriteKeyStoreDatabase();
29795eee1a3SMichael Lotz 
29895eee1a3SMichael Lotz 			break;
29995eee1a3SMichael Lotz 		}
30095eee1a3SMichael Lotz 
30195eee1a3SMichael Lotz 		case KEY_STORE_GET_NEXT_KEYRING:
30295eee1a3SMichael Lotz 		{
30395eee1a3SMichael Lotz 			uint32 cookie;
30495eee1a3SMichael Lotz 			if (message->FindUInt32("cookie", &cookie) != B_OK) {
30595eee1a3SMichael Lotz 				result = B_BAD_VALUE;
30695eee1a3SMichael Lotz 				break;
30795eee1a3SMichael Lotz 			}
30895eee1a3SMichael Lotz 
309*bec02d0cSMichael Lotz 			keyring = fKeyrings.ItemAt(cookie);
31095eee1a3SMichael Lotz 			if (keyring == NULL) {
31195eee1a3SMichael Lotz 				result = B_ENTRY_NOT_FOUND;
31295eee1a3SMichael Lotz 				break;
31395eee1a3SMichael Lotz 			}
31495eee1a3SMichael Lotz 
31595eee1a3SMichael Lotz 			cookie++;
31695eee1a3SMichael Lotz 			reply.AddUInt32("cookie", cookie);
31795eee1a3SMichael Lotz 			reply.AddString("keyring", keyring->Name());
31895eee1a3SMichael Lotz 			result = B_OK;
31995eee1a3SMichael Lotz 			break;
32095eee1a3SMichael Lotz 		}
32195eee1a3SMichael Lotz 
322c8ae843fSMichael Lotz 		case KEY_STORE_IS_KEYRING_UNLOCKED:
32395eee1a3SMichael Lotz 		{
324c8ae843fSMichael Lotz 			reply.AddBool("unlocked", keyring->IsUnlocked());
32595eee1a3SMichael Lotz 			result = B_OK;
326f16fef70SMichael Lotz 			break;
32795eee1a3SMichael Lotz 		}
32895eee1a3SMichael Lotz 
329c8ae843fSMichael Lotz 		case KEY_STORE_LOCK_KEYRING:
330ac9b28f0SMichael Lotz 		{
331c8ae843fSMichael Lotz 			keyring->Lock();
332ac9b28f0SMichael Lotz 			result = B_OK;
333f16fef70SMichael Lotz 			break;
334f16fef70SMichael Lotz 		}
335f16fef70SMichael Lotz 
336f16fef70SMichael Lotz 		case KEY_STORE_ADD_KEYRING_TO_MASTER:
337f16fef70SMichael Lotz 		case KEY_STORE_REMOVE_KEYRING_FROM_MASTER:
338f16fef70SMichael Lotz 		{
339a5a5f4caSMichael Lotz 			// We also need access to the master keyring.
340a5a5f4caSMichael Lotz 			while (!fMasterKeyring->IsUnlocked()) {
341a5a5f4caSMichael Lotz 				status_t unlockResult = _UnlockKeyring(*fMasterKeyring);
342c8ae843fSMichael Lotz 				if (unlockResult != B_OK) {
343c8ae843fSMichael Lotz 					result = unlockResult;
344f16fef70SMichael Lotz 					message->what = 0;
345f16fef70SMichael Lotz 					break;
346f16fef70SMichael Lotz 				}
347f16fef70SMichael Lotz 			}
348f16fef70SMichael Lotz 
349f16fef70SMichael Lotz 			if (message->what == 0)
350f16fef70SMichael Lotz 				break;
351f16fef70SMichael Lotz 
352f16fef70SMichael Lotz 			BString secondaryIdentifier = keyring->Name();
353f16fef70SMichael Lotz 			BMessage keyMessage = keyring->KeyMessage();
354f16fef70SMichael Lotz 			keyMessage.RemoveName("identifier");
355f16fef70SMichael Lotz 			keyMessage.AddString("identifier", kKeyringKeysIdentifier);
356f16fef70SMichael Lotz 			keyMessage.RemoveName("secondaryIdentifier");
357f16fef70SMichael Lotz 			keyMessage.AddString("secondaryIdentifier", secondaryIdentifier);
358f16fef70SMichael Lotz 
359f16fef70SMichael Lotz 			switch (message->what) {
360f16fef70SMichael Lotz 				case KEY_STORE_ADD_KEYRING_TO_MASTER:
361a5a5f4caSMichael Lotz 					result = fMasterKeyring->AddKey(kKeyringKeysIdentifier,
362f16fef70SMichael Lotz 						secondaryIdentifier, keyMessage);
363f16fef70SMichael Lotz 					break;
364f16fef70SMichael Lotz 
365f16fef70SMichael Lotz 				case KEY_STORE_REMOVE_KEYRING_FROM_MASTER:
366a5a5f4caSMichael Lotz 					result = fMasterKeyring->RemoveKey(kKeyringKeysIdentifier,
367f16fef70SMichael Lotz 						keyMessage);
368f16fef70SMichael Lotz 					break;
369f16fef70SMichael Lotz 			}
370f16fef70SMichael Lotz 
371f16fef70SMichael Lotz 			if (result == B_OK)
372f16fef70SMichael Lotz 				_WriteKeyStoreDatabase();
373f16fef70SMichael Lotz 
374f16fef70SMichael Lotz 			break;
375ac9b28f0SMichael Lotz 		}
376ac9b28f0SMichael Lotz 
377b31a707aSMichael Lotz 		case KEY_STORE_GET_NEXT_APPLICATION:
378b31a707aSMichael Lotz 		{
379b31a707aSMichael Lotz 			uint32 cookie;
380b31a707aSMichael Lotz 			if (message->FindUInt32("cookie", &cookie) != B_OK) {
381b31a707aSMichael Lotz 				result = B_BAD_VALUE;
382b31a707aSMichael Lotz 				break;
383b31a707aSMichael Lotz 			}
384b31a707aSMichael Lotz 
385b31a707aSMichael Lotz 			BString signature;
386b31a707aSMichael Lotz 			BString path;
387b31a707aSMichael Lotz 			result = keyring->GetNextApplication(cookie, signature, path);
388b31a707aSMichael Lotz 			if (result != B_OK)
389b31a707aSMichael Lotz 				break;
390b31a707aSMichael Lotz 
391b31a707aSMichael Lotz 			reply.AddUInt32("cookie", cookie);
392b31a707aSMichael Lotz 			reply.AddString("signature", signature);
393b31a707aSMichael Lotz 			reply.AddString("path", path);
394b31a707aSMichael Lotz 			result = B_OK;
395b31a707aSMichael Lotz 			break;
396b31a707aSMichael Lotz 		}
397b31a707aSMichael Lotz 
398b31a707aSMichael Lotz 		case KEY_STORE_REMOVE_APPLICATION:
399b31a707aSMichael Lotz 		{
400b31a707aSMichael Lotz 			const char* signature = NULL;
401b31a707aSMichael Lotz 			const char* path = NULL;
402b31a707aSMichael Lotz 
403b31a707aSMichael Lotz 			if (message->FindString("signature", &signature) != B_OK) {
404b31a707aSMichael Lotz 				result = B_BAD_VALUE;
405b31a707aSMichael Lotz 				break;
406b31a707aSMichael Lotz 			}
407b31a707aSMichael Lotz 
408b31a707aSMichael Lotz 			if (message->FindString("path", &path) != B_OK)
409b31a707aSMichael Lotz 				path = NULL;
410b31a707aSMichael Lotz 
411b31a707aSMichael Lotz 			result = keyring->RemoveApplication(signature, path);
412b31a707aSMichael Lotz 			break;
413b31a707aSMichael Lotz 		}
414b31a707aSMichael Lotz 
41595eee1a3SMichael Lotz 		case 0:
41695eee1a3SMichael Lotz 		{
41795eee1a3SMichael Lotz 			// Just the error case from above.
4188d9bc9e0SMichael Lotz 			break;
4198d9bc9e0SMichael Lotz 		}
4208d9bc9e0SMichael Lotz 
4218d9bc9e0SMichael Lotz 		default:
4228d9bc9e0SMichael Lotz 		{
4238d9bc9e0SMichael Lotz 			printf("unknown message received: %" B_PRIu32 " \"%.4s\"\n",
4248d9bc9e0SMichael Lotz 				message->what, (const char*)&message->what);
4258d9bc9e0SMichael Lotz 			break;
4268d9bc9e0SMichael Lotz 		}
4278d9bc9e0SMichael Lotz 	}
4288d9bc9e0SMichael Lotz 
4290dfaf59dSMichael Lotz 	if (message->IsSourceWaiting()) {
4300dfaf59dSMichael Lotz 		if (result == B_OK)
4310dfaf59dSMichael Lotz 			reply.what = KEY_STORE_SUCCESS;
4320dfaf59dSMichael Lotz 		else {
4330dfaf59dSMichael Lotz 			reply.what = KEY_STORE_RESULT;
4340dfaf59dSMichael Lotz 			reply.AddInt32("result", result);
4350dfaf59dSMichael Lotz 		}
4360dfaf59dSMichael Lotz 
4370dfaf59dSMichael Lotz 		message->SendReply(&reply);
4380dfaf59dSMichael Lotz 	}
4398d9bc9e0SMichael Lotz }
4408d9bc9e0SMichael Lotz 
4418d9bc9e0SMichael Lotz 
4428d9bc9e0SMichael Lotz status_t
4430dfaf59dSMichael Lotz KeyStoreServer::_ReadKeyStoreDatabase()
4448d9bc9e0SMichael Lotz {
445*bec02d0cSMichael Lotz 	BMessage keystore;
446*bec02d0cSMichael Lotz 	status_t result = keystore.Unflatten(&fKeyStoreFile);
4470dfaf59dSMichael Lotz 	if (result != B_OK) {
4480dfaf59dSMichael Lotz 		printf("failed to read keystore database\n");
4490dfaf59dSMichael Lotz 		_WriteKeyStoreDatabase();
450*bec02d0cSMichael Lotz 			// Reinitializes the database.
4510dfaf59dSMichael Lotz 		return result;
4520dfaf59dSMichael Lotz 	}
4530dfaf59dSMichael Lotz 
45495eee1a3SMichael Lotz 	int32 index = 0;
455*bec02d0cSMichael Lotz 	BMessage keyringData;
456*bec02d0cSMichael Lotz 	while (keystore.FindMessage("keyrings", index++, &keyringData) == B_OK) {
457*bec02d0cSMichael Lotz 		Keyring* keyring = new(std::nothrow) Keyring();
4581b3bb46aSMichael Lotz 		if (keyring == NULL) {
459*bec02d0cSMichael Lotz 			printf("no memory for allocating keyring\n");
460*bec02d0cSMichael Lotz 			break;
46195eee1a3SMichael Lotz 		}
46295eee1a3SMichael Lotz 
463*bec02d0cSMichael Lotz 		status_t result = keyring->ReadFromMessage(keyringData);
4641b3bb46aSMichael Lotz 		if (result != B_OK) {
465*bec02d0cSMichael Lotz 			printf("failed to read keyring from data\n");
4661b3bb46aSMichael Lotz 			delete keyring;
46795eee1a3SMichael Lotz 			continue;
46895eee1a3SMichael Lotz 		}
46995eee1a3SMichael Lotz 
470*bec02d0cSMichael Lotz 		if (strcmp(keyring->Name(), kMasterKeyringName) == 0)
471a5a5f4caSMichael Lotz 			fMasterKeyring = keyring;
472*bec02d0cSMichael Lotz 
47395eee1a3SMichael Lotz 		fKeyrings.BinaryInsert(keyring, &Keyring::Compare);
47495eee1a3SMichael Lotz 	}
47595eee1a3SMichael Lotz 
4760dfaf59dSMichael Lotz 	return B_OK;
4770dfaf59dSMichael Lotz }
4780dfaf59dSMichael Lotz 
4790dfaf59dSMichael Lotz 
4800dfaf59dSMichael Lotz status_t
4810dfaf59dSMichael Lotz KeyStoreServer::_WriteKeyStoreDatabase()
4820dfaf59dSMichael Lotz {
483*bec02d0cSMichael Lotz 	BMessage keystore;
484*bec02d0cSMichael Lotz 	keystore.AddUInt32("format", kKeyStoreFormatVersion);
4850dfaf59dSMichael Lotz 
48695eee1a3SMichael Lotz 	for (int32 i = 0; i < fKeyrings.CountItems(); i++) {
48795eee1a3SMichael Lotz 		Keyring* keyring = fKeyrings.ItemAt(i);
48895eee1a3SMichael Lotz 		if (keyring == NULL)
4890dfaf59dSMichael Lotz 			continue;
49095eee1a3SMichael Lotz 
491*bec02d0cSMichael Lotz 		BMessage keyringData;
492*bec02d0cSMichael Lotz 		status_t result = keyring->WriteToMessage(keyringData);
4931b3bb46aSMichael Lotz 		if (result != B_OK)
4941b3bb46aSMichael Lotz 			return result;
495*bec02d0cSMichael Lotz 
496*bec02d0cSMichael Lotz 		keystore.AddMessage("keyrings", &keyringData);
4970dfaf59dSMichael Lotz 	}
4980dfaf59dSMichael Lotz 
499aef629f2SMichael Lotz 	fKeyStoreFile.SetSize(0);
500aef629f2SMichael Lotz 	fKeyStoreFile.Seek(0, SEEK_SET);
501*bec02d0cSMichael Lotz 	return keystore.Flatten(&fKeyStoreFile);
5020dfaf59dSMichael Lotz }
5030dfaf59dSMichael Lotz 
5040dfaf59dSMichael Lotz 
50597b3abf1SMichael Lotz uint32
50697b3abf1SMichael Lotz KeyStoreServer::_AccessFlagsFor(uint32 command) const
50797b3abf1SMichael Lotz {
50897b3abf1SMichael Lotz 	switch (command) {
50997b3abf1SMichael Lotz 		case KEY_STORE_GET_KEY:
51097b3abf1SMichael Lotz 			return kFlagGetKey;
51197b3abf1SMichael Lotz 		case KEY_STORE_GET_NEXT_KEY:
51297b3abf1SMichael Lotz 			return kFlagEnumerateKeys;
51397b3abf1SMichael Lotz 		case KEY_STORE_ADD_KEY:
51497b3abf1SMichael Lotz 			return kFlagAddKey;
51597b3abf1SMichael Lotz 		case KEY_STORE_REMOVE_KEY:
51697b3abf1SMichael Lotz 			return kFlagRemoveKey;
51797b3abf1SMichael Lotz 		case KEY_STORE_ADD_KEYRING:
51897b3abf1SMichael Lotz 			return kFlagAddKeyring;
51997b3abf1SMichael Lotz 		case KEY_STORE_REMOVE_KEYRING:
52097b3abf1SMichael Lotz 			return kFlagRemoveKeyring;
52197b3abf1SMichael Lotz 		case KEY_STORE_GET_NEXT_KEYRING:
52297b3abf1SMichael Lotz 			return kFlagEnumerateKeyrings;
52397b3abf1SMichael Lotz 		case KEY_STORE_SET_MASTER_KEY:
52497b3abf1SMichael Lotz 			return kFlagSetMasterKey;
52597b3abf1SMichael Lotz 		case KEY_STORE_REMOVE_MASTER_KEY:
52697b3abf1SMichael Lotz 			return kFlagRemoveMasterKey;
52797b3abf1SMichael Lotz 		case KEY_STORE_ADD_KEYRING_TO_MASTER:
52897b3abf1SMichael Lotz 			return kFlagAddKeyringsToMaster;
52997b3abf1SMichael Lotz 		case KEY_STORE_REMOVE_KEYRING_FROM_MASTER:
53097b3abf1SMichael Lotz 			return kFlagRemoveKeyringsFromMaster;
53197b3abf1SMichael Lotz 		case KEY_STORE_GET_NEXT_MASTER_KEYRING:
53297b3abf1SMichael Lotz 			return kFlagEnumerateMasterKeyrings;
533c8ae843fSMichael Lotz 		case KEY_STORE_IS_KEYRING_UNLOCKED:
534c8ae843fSMichael Lotz 			return kFlagQueryLockState;
535c8ae843fSMichael Lotz 		case KEY_STORE_LOCK_KEYRING:
536c8ae843fSMichael Lotz 			return kFlagLockKeyring;
53797b3abf1SMichael Lotz 		case KEY_STORE_GET_NEXT_APPLICATION:
53897b3abf1SMichael Lotz 			return kFlagEnumerateApplications;
53997b3abf1SMichael Lotz 		case KEY_STORE_REMOVE_APPLICATION:
54097b3abf1SMichael Lotz 			return kFlagRemoveApplications;
54197b3abf1SMichael Lotz 	}
54297b3abf1SMichael Lotz 
54397b3abf1SMichael Lotz 	return 0;
54497b3abf1SMichael Lotz }
54597b3abf1SMichael Lotz 
54697b3abf1SMichael Lotz 
547a2f27987SMichael Lotz const char*
548a2f27987SMichael Lotz KeyStoreServer::_AccessStringFor(uint32 accessFlag) const
549a2f27987SMichael Lotz {
550a2f27987SMichael Lotz 	switch (accessFlag) {
551a2f27987SMichael Lotz 		case kFlagGetKey:
552a2f27987SMichael Lotz 			return "Get keys from the keyring.";
553a2f27987SMichael Lotz 		case kFlagEnumerateKeys:
554a2f27987SMichael Lotz 			return "Enumerate and get keys from the keyring.";
555a2f27987SMichael Lotz 		case kFlagAddKey:
556a2f27987SMichael Lotz 			return "Add keys to the keyring.";
557a2f27987SMichael Lotz 		case kFlagRemoveKey:
558a2f27987SMichael Lotz 			return "Remove keys from the keyring.";
559a2f27987SMichael Lotz 		case kFlagAddKeyring:
560a2f27987SMichael Lotz 			return "Add new keyrings.";
561a2f27987SMichael Lotz 		case kFlagRemoveKeyring:
562a2f27987SMichael Lotz 			return "Remove keyrings.";
563a2f27987SMichael Lotz 		case kFlagEnumerateKeyrings:
564a2f27987SMichael Lotz 			return "Enumerate the available keyrings.";
565a2f27987SMichael Lotz 		case kFlagSetMasterKey:
566a2f27987SMichael Lotz 			return "Set the master key.";
567a2f27987SMichael Lotz 		case kFlagRemoveMasterKey:
568a2f27987SMichael Lotz 			return "Remove the master key.";
569a2f27987SMichael Lotz 		case kFlagAddKeyringsToMaster:
570a2f27987SMichael Lotz 			return "Add the keyring key to the master keyring.";
571a2f27987SMichael Lotz 		case kFlagRemoveKeyringsFromMaster:
572a2f27987SMichael Lotz 			return "Remove the keyring key from the master keyring.";
573a2f27987SMichael Lotz 		case kFlagEnumerateMasterKeyrings:
574a2f27987SMichael Lotz 			return "Enumerate keyrings added to the master keyring.";
575a2f27987SMichael Lotz 		case kFlagQueryLockState:
576a2f27987SMichael Lotz 			return "Query the lock state of the keyring.";
577a2f27987SMichael Lotz 		case kFlagLockKeyring:
578a2f27987SMichael Lotz 			return "Lock the keyring.";
579a2f27987SMichael Lotz 		case kFlagEnumerateApplications:
580a2f27987SMichael Lotz 			return "Enumerate the applications of the keyring.";
581a2f27987SMichael Lotz 		case kFlagRemoveApplications:
582a2f27987SMichael Lotz 			return "Remove applications from the keyring.";
583a2f27987SMichael Lotz 	}
584a2f27987SMichael Lotz 
585a2f27987SMichael Lotz 	return NULL;
586a2f27987SMichael Lotz }
587a2f27987SMichael Lotz 
588a2f27987SMichael Lotz 
58976df966eSMichael Lotz status_t
59076df966eSMichael Lotz KeyStoreServer::_ResolveCallingApp(const BMessage& message,
59176df966eSMichael Lotz 	app_info& callingAppInfo) const
59276df966eSMichael Lotz {
59376df966eSMichael Lotz 	team_id callingTeam = message.ReturnAddress().Team();
59476df966eSMichael Lotz 	status_t result = be_roster->GetRunningAppInfo(callingTeam,
59576df966eSMichael Lotz 		&callingAppInfo);
59676df966eSMichael Lotz 	if (result != B_OK)
59776df966eSMichael Lotz 		return result;
59876df966eSMichael Lotz 
59976df966eSMichael Lotz 	// Do some sanity checks.
60076df966eSMichael Lotz 	if (callingAppInfo.team != callingTeam)
60176df966eSMichael Lotz 		return B_ERROR;
60276df966eSMichael Lotz 
60376df966eSMichael Lotz 	return B_OK;
60476df966eSMichael Lotz }
60576df966eSMichael Lotz 
60676df966eSMichael Lotz 
607cfa81315SMichael Lotz status_t
608cfa81315SMichael Lotz KeyStoreServer::_ValidateAppAccess(Keyring& keyring, const app_info& appInfo,
609cfa81315SMichael Lotz 	uint32 accessFlags)
610cfa81315SMichael Lotz {
611cfa81315SMichael Lotz 	BMessage appMessage;
612cfa81315SMichael Lotz 	BPath path(&appInfo.ref);
613cfa81315SMichael Lotz 	status_t result = keyring.FindApplication(appInfo.signature,
614cfa81315SMichael Lotz 		path.Path(), appMessage);
615cfa81315SMichael Lotz 	if (result != B_OK && result != B_ENTRY_NOT_FOUND)
616cfa81315SMichael Lotz 		return result;
617cfa81315SMichael Lotz 
618cfa81315SMichael Lotz 	// TODO: Implement running image checksum mechanism.
619cfa81315SMichael Lotz 	BString checksum = "dummy";
620cfa81315SMichael Lotz 
621cfa81315SMichael Lotz 	bool appIsNew = false;
622cfa81315SMichael Lotz 	bool appWasUpdated = false;
623cfa81315SMichael Lotz 	uint32 appFlags = 0;
624cfa81315SMichael Lotz 	BString appSum = "";
625cfa81315SMichael Lotz 	if (result == B_OK) {
626cfa81315SMichael Lotz 		if (appMessage.FindUInt32("flags", &appFlags) != B_OK
627cfa81315SMichael Lotz 			|| appMessage.FindString("checksum", &appSum) != B_OK) {
628cfa81315SMichael Lotz 			appIsNew = true;
629cfa81315SMichael Lotz 			appFlags = 0;
630cfa81315SMichael Lotz 		} else if (appSum != checksum) {
631cfa81315SMichael Lotz 			appWasUpdated = true;
632cfa81315SMichael Lotz 			appFlags = 0;
633cfa81315SMichael Lotz 		}
634cfa81315SMichael Lotz 	} else
635cfa81315SMichael Lotz 		appIsNew = true;
636cfa81315SMichael Lotz 
637cfa81315SMichael Lotz 	if ((accessFlags & appFlags) == accessFlags)
638cfa81315SMichael Lotz 		return B_OK;
639cfa81315SMichael Lotz 
640a59169deSMichael Lotz 	const char* accessString = _AccessStringFor(accessFlags);
641cfa81315SMichael Lotz 	bool allowAlways = false;
642cfa81315SMichael Lotz 	result = _RequestAppAccess(keyring.Name(), appInfo.signature, path.Path(),
643a59169deSMichael Lotz 		accessString, appIsNew, appWasUpdated, accessFlags, allowAlways);
644cfa81315SMichael Lotz 	if (result != B_OK || !allowAlways)
645cfa81315SMichael Lotz 		return result;
646cfa81315SMichael Lotz 
647cfa81315SMichael Lotz 	appMessage.MakeEmpty();
648cfa81315SMichael Lotz 	appMessage.AddString("path", path.Path());
649ee834720SMichael Lotz 	appMessage.AddUInt32("flags", appFlags | accessFlags);
650cfa81315SMichael Lotz 	appMessage.AddString("checksum", checksum);
651cfa81315SMichael Lotz 
652cfa81315SMichael Lotz 	keyring.RemoveApplication(appInfo.signature, path.Path());
653cfa81315SMichael Lotz 	if (keyring.AddApplication(appInfo.signature, appMessage) == B_OK)
654cfa81315SMichael Lotz 		_WriteKeyStoreDatabase();
655cfa81315SMichael Lotz 
656cfa81315SMichael Lotz 	return B_OK;
657cfa81315SMichael Lotz }
658cfa81315SMichael Lotz 
659cfa81315SMichael Lotz 
660cfa81315SMichael Lotz status_t
661cfa81315SMichael Lotz KeyStoreServer::_RequestAppAccess(const BString& keyringName,
662a59169deSMichael Lotz 	const char* signature, const char* path, const char* accessString,
663a59169deSMichael Lotz 	bool appIsNew, bool appWasUpdated, uint32 accessFlags, bool& allowAlways)
664cfa81315SMichael Lotz {
665cfa81315SMichael Lotz 	AppAccessRequestWindow* requestWindow
666cfa81315SMichael Lotz 		= new(std::nothrow) AppAccessRequestWindow(keyringName, signature, path,
667a59169deSMichael Lotz 			accessString, appIsNew, appWasUpdated);
668cfa81315SMichael Lotz 	if (requestWindow == NULL)
669cfa81315SMichael Lotz 		return B_NO_MEMORY;
670cfa81315SMichael Lotz 
671cfa81315SMichael Lotz 	return requestWindow->RequestAppAccess(allowAlways);
672cfa81315SMichael Lotz }
673cfa81315SMichael Lotz 
674cfa81315SMichael Lotz 
67595eee1a3SMichael Lotz Keyring*
67695eee1a3SMichael Lotz KeyStoreServer::_FindKeyring(const BString& name)
67795eee1a3SMichael Lotz {
678a5a5f4caSMichael Lotz 	if (name.IsEmpty() || name == kMasterKeyringName)
679a5a5f4caSMichael Lotz 		return fMasterKeyring;
6800dfaf59dSMichael Lotz 
68195eee1a3SMichael Lotz 	return fKeyrings.BinarySearchByKey(name, &Keyring::Compare);
6820dfaf59dSMichael Lotz }
6830dfaf59dSMichael Lotz 
6840dfaf59dSMichael Lotz 
6850dfaf59dSMichael Lotz status_t
686d4d6d123SMichael Lotz KeyStoreServer::_AddKeyring(const BString& name)
6870dfaf59dSMichael Lotz {
68895eee1a3SMichael Lotz 	if (_FindKeyring(name) != NULL)
6890dfaf59dSMichael Lotz 		return B_NAME_IN_USE;
6900dfaf59dSMichael Lotz 
691d4d6d123SMichael Lotz 	Keyring* keyring = new(std::nothrow) Keyring(name);
69295eee1a3SMichael Lotz 	if (keyring == NULL)
69395eee1a3SMichael Lotz 		return B_NO_MEMORY;
69495eee1a3SMichael Lotz 
69595eee1a3SMichael Lotz 	if (!fKeyrings.BinaryInsert(keyring, &Keyring::Compare)) {
69695eee1a3SMichael Lotz 		delete keyring;
69795eee1a3SMichael Lotz 		return B_ERROR;
69895eee1a3SMichael Lotz 	}
69995eee1a3SMichael Lotz 
70095eee1a3SMichael Lotz 	return B_OK;
70195eee1a3SMichael Lotz }
70295eee1a3SMichael Lotz 
70395eee1a3SMichael Lotz 
70495eee1a3SMichael Lotz status_t
70595eee1a3SMichael Lotz KeyStoreServer::_RemoveKeyring(const BString& name)
70695eee1a3SMichael Lotz {
70795eee1a3SMichael Lotz 	Keyring* keyring = _FindKeyring(name);
70895eee1a3SMichael Lotz 	if (keyring == NULL)
70995eee1a3SMichael Lotz 		return B_ENTRY_NOT_FOUND;
71095eee1a3SMichael Lotz 
711a5a5f4caSMichael Lotz 	if (keyring == fMasterKeyring) {
712a5a5f4caSMichael Lotz 		// The master keyring can't be removed.
71395eee1a3SMichael Lotz 		return B_NOT_ALLOWED;
71495eee1a3SMichael Lotz 	}
71595eee1a3SMichael Lotz 
71695eee1a3SMichael Lotz 	return fKeyrings.RemoveItem(keyring) ? B_OK : B_ERROR;
7178d9bc9e0SMichael Lotz }
7188d9bc9e0SMichael Lotz 
7198d9bc9e0SMichael Lotz 
720ac9b28f0SMichael Lotz status_t
721c8ae843fSMichael Lotz KeyStoreServer::_UnlockKeyring(Keyring& keyring)
722ac9b28f0SMichael Lotz {
723ac9b28f0SMichael Lotz 	// If we are accessing a keyring that has been added to master access we
724a5a5f4caSMichael Lotz 	// get the key from the master keyring and unlock with that.
725ac9b28f0SMichael Lotz 	BMessage keyMessage;
726a5a5f4caSMichael Lotz 	if (&keyring != fMasterKeyring && fMasterKeyring->IsUnlocked()) {
727a5a5f4caSMichael Lotz 		if (fMasterKeyring->FindKey(kKeyringKeysIdentifier, keyring.Name(),
728f16fef70SMichael Lotz 				false, &keyMessage) == B_OK) {
729c8ae843fSMichael Lotz 			// We found a key for this keyring, try to unlock with it.
730c8ae843fSMichael Lotz 			if (keyring.Unlock(keyMessage) == B_OK)
731ac9b28f0SMichael Lotz 				return B_OK;
732ac9b28f0SMichael Lotz 		}
733ac9b28f0SMichael Lotz 	}
734ac9b28f0SMichael Lotz 
735ac9b28f0SMichael Lotz 	// No key, we need to request one from the user.
73690013c82SMichael Lotz 	status_t result = _RequestKey(keyring.Name(), keyMessage);
737ac9b28f0SMichael Lotz 	if (result != B_OK)
738ac9b28f0SMichael Lotz 		return result;
739ac9b28f0SMichael Lotz 
740c8ae843fSMichael Lotz 	return keyring.Unlock(keyMessage);
741ac9b28f0SMichael Lotz }
742ac9b28f0SMichael Lotz 
743ac9b28f0SMichael Lotz 
744ac9b28f0SMichael Lotz status_t
74590013c82SMichael Lotz KeyStoreServer::_RequestKey(const BString& keyringName, BMessage& keyMessage)
746ac9b28f0SMichael Lotz {
747ac9b28f0SMichael Lotz 	KeyRequestWindow* requestWindow = new(std::nothrow) KeyRequestWindow();
748ac9b28f0SMichael Lotz 	if (requestWindow == NULL)
749ac9b28f0SMichael Lotz 		return B_NO_MEMORY;
750ac9b28f0SMichael Lotz 
75190013c82SMichael Lotz 	return requestWindow->RequestKey(keyringName, keyMessage);
752ac9b28f0SMichael Lotz }
753ac9b28f0SMichael Lotz 
754ac9b28f0SMichael Lotz 
7558d9bc9e0SMichael Lotz int
7568d9bc9e0SMichael Lotz main(int argc, char* argv[])
7578d9bc9e0SMichael Lotz {
7588d9bc9e0SMichael Lotz 	KeyStoreServer* app = new(std::nothrow) KeyStoreServer();
7598d9bc9e0SMichael Lotz 	if (app == NULL)
7608d9bc9e0SMichael Lotz 		return 1;
7618d9bc9e0SMichael Lotz 
7628d9bc9e0SMichael Lotz 	app->Run();
7638d9bc9e0SMichael Lotz 	delete app;
7648d9bc9e0SMichael Lotz 	return 0;
7658d9bc9e0SMichael Lotz }
766