#ifndef _H_AGENTQUERY
#define _H_AGENTQUERY
#include <security_cdsa_utilities/AuthorizationData.h>
#include <security_utilities/ccaudit.h> // some queries do their own authentication
#include <Security/AuthorizationPlugin.h>
#include "kcdatabase.h"
#include "authhost.h"
#include "server.h"
#include "session.h"
#include <xpc/xpc.h>
using Authorization::AuthItemSet;
using Authorization::AuthValueVector;
using Security::OSXCode;
#define kMaximumAuthorizationTries (10000)
class SecurityAgentXPCConnection
{
public:
SecurityAgentXPCConnection(Session &session = Server::session());
virtual ~SecurityAgentXPCConnection();
virtual void activate(bool ignoreUid);
virtual void disconnect() { };
virtual void terminate();
protected:
RefPointer<AuthHostInstance> mHostInstance;
Session &mSession;
xpc_connection_t mXPCConnection;
const RefPointer<Connection> mConnection;
audit_token_t *mAuditToken;
uid_t mNobodyUID;
bool inDarkWake();
};
class SecurityAgentXPCQuery : public SecurityAgentXPCConnection
{
public:
static void killAllXPCClients();
typedef SecurityAgent::Reason Reason;
SecurityAgentXPCQuery(Session &session = Server::session());
void inferHints(Process &thisProcess);
void addHint(const char *name, const void *value = NULL, UInt32 valueLen = 0, UInt32 flags = 0);
virtual ~SecurityAgentXPCQuery();
virtual void disconnect();
virtual void terminate();
void create(const char *pluginId, const char *mechanismId);
void invoke();
void setTerminateOnSleep(bool terminateOnSleep) {mTerminateOnSleep = terminateOnSleep;}
bool getTerminateOnSleep() {return mTerminateOnSleep;}
void setInput(const AuthItemSet& inHints, const AuthItemSet& inContext) { mInHints = inHints; mInContext = inContext; }
void checkResult();
void readChoice();
bool allow;
bool remember;
protected:
AuthItemSet mClientHints;
AuthItemSet mImmutableHints;
AuthItemSet mInHints;
AuthItemSet mInContext;
AuthItemSet mOutHints;
AuthItemSet mOutContext;
bool mAgentConnected;
uint64_t mLastResult;
bool mTerminateOnSleep;
};
class QueryKeychainUse : public SecurityAgentXPCQuery {
public:
QueryKeychainUse(bool needPass, const Database *db);
Reason queryUser (const char* database, const char *description, AclAuthorization action);
private:
const KeychainDatabase *mPassphraseCheck; };
class QueryOld : public SecurityAgentXPCQuery {
static const int maxTries = kMaximumAuthorizationTries;
public:
QueryOld(Database &db) : database(db) {setTerminateOnSleep(true);}
Database &database;
Reason operator () ();
protected:
Reason query();
virtual Reason accept(CssmManagedData &) = 0;
};
class QueryUnlock : public QueryOld {
public:
QueryUnlock(KeychainDatabase &db) : QueryOld(db) { }
Reason retrievePassword(CssmOwnedData &passphrase);
protected:
Reason accept(CssmManagedData &passphrase);
};
class QueryKeybagPassphrase : public SecurityAgentXPCQuery {
public:
QueryKeybagPassphrase(Session &session, int32_t retries = kMaximumAuthorizationTries);
Reason query();
Reason accept(CssmManagedData &passphrase);
protected:
Session &mSession;
service_context_t mContext;
int32_t mRetries;
};
class QueryKeybagNewPassphrase : public QueryKeybagPassphrase {
public:
QueryKeybagNewPassphrase(Session &session);
Reason query(CssmOwnedData &oldPassphrase, CssmOwnedData &passphrase);
};
class QueryPIN : public QueryOld {
public:
QueryPIN(Database &db);
const CssmData &pin() const { return mPin; }
protected:
Reason accept(CssmManagedData &pin);
private:
CssmAutoData mPin; };
class QueryNewPassphrase : public SecurityAgentXPCQuery {
static const int maxTries = kMaximumAuthorizationTries;
public:
QueryNewPassphrase(Database &db, Reason reason) :
database(db), initialReason(reason),
mPassphrase(Allocator::standard(Allocator::sensitive)),
mOldPassphrase(Allocator::standard(Allocator::sensitive)),
mPassphraseValid(false) { }
Database &database;
Reason operator () (CssmOwnedData &oldPassphrase, CssmOwnedData &passphrase);
protected:
Reason query();
virtual Reason accept(CssmManagedData &passphrase, CssmData *oldPassphrase);
private:
Reason initialReason;
CssmAutoData mPassphrase;
CssmAutoData mOldPassphrase;
bool mPassphraseValid;
};
class QueryGenericPassphrase : public SecurityAgentXPCQuery {
public:
QueryGenericPassphrase() { }
Reason operator () (const CssmData *prompt, bool verify,
string &passphrase);
protected:
Reason query(const CssmData *prompt, bool verify, string &passphrase);
};
class QueryDBBlobSecret : public SecurityAgentXPCQuery {
static const int maxTries = kMaximumAuthorizationTries;
public:
QueryDBBlobSecret() { }
Reason operator () (DbHandle *dbHandleArray, uint8 dbHandleArrayCount, DbHandle *dbHandleAuthenticated);
protected:
Reason query(DbHandle *dbHandleArray, uint8 dbHandleArrayCount, DbHandle *dbHandleAuthenticated);
Reason accept(CssmManagedData &passphrase, DbHandle *dbHandlesToAuthenticate, uint8 dbHandleCount, DbHandle *dbHandleAuthenticated);
};
class QueryKeychainAuth : public SecurityAgentXPCQuery {
static const int maxTries = kMaximumAuthorizationTries;
public:
QueryKeychainAuth() { }
Reason operator () (const char *database, const char *description, AclAuthorization action, const char *prompt);
Reason accept(string &username, string &passphrase);
};
#endif //_H_AGENTQUERY