#ifndef _H_AGENTQUERY
#define _H_AGENTQUERY
#include <security_agent_client/agentclient.h>
#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 "AuthorizationEngine.h"
#include "authhost.h"
#include "server.h"
#include "session.h"
using Authorization::AuthItemSet;
using Authorization::AuthValueVector;
using Security::OSXCode;
class SecurityAgentConnection : public SecurityAgent::Client,
public SecurityAgentConnectionInterface
{
public:
SecurityAgentConnection(const AuthHostType type = securityAgent, Session &session = Server::session());
virtual ~SecurityAgentConnection();
virtual void activate();
virtual void reconnect();
virtual void disconnect() { };
virtual void terminate();
AuthHostType hostType() { return mAuthHostType; }
protected:
AuthHostType mAuthHostType;
RefPointer<AuthHostInstance> mHostInstance;
Port mPort;
const RefPointer<Connection> mConnection;
audit_token_t *mAuditToken;
};
class SecurityAgentTransaction : public SecurityAgentConnection
{
public:
SecurityAgentTransaction(const AuthHostType type = securityAgent, Session &session = Server::session(), bool startNow = true);
~SecurityAgentTransaction();
void start();
void end();
bool started() { return mStarted; }
private:
bool mStarted;
};
class SecurityAgentQuery : public SecurityAgentConnection
{
public:
typedef SecurityAgent::Reason Reason;
SecurityAgentQuery(const AuthHostType type = securityAgent, Session &session = Server::session());
void inferHints(Process &thisProcess);
void addHint(const char *name, const void *value = NULL, UInt32 valueLen = 0, UInt32 flags = 0);
virtual ~SecurityAgentQuery();
virtual void disconnect();
virtual void terminate();
void create(const char *pluginId, const char *mechanismId, const SessionId inSessionId);
void readChoice();
bool allow;
bool remember;
protected:
AuthItemSet mClientHints;
};
class QueryKeychainUse : public SecurityAgentQuery {
public:
QueryKeychainUse(bool needPass, const Database *db);
Reason queryUser (const char* database, const char *description, AclAuthorization action);
private:
const KeychainDatabase *mPassphraseCheck; };
class QueryCodeCheck : public SecurityAgentQuery {
public:
bool operator () (const char *aclPath);
};
class QueryOld : public SecurityAgentQuery {
static const int maxTries = kMaximumAuthorizationTries;
public:
QueryOld(Database &db) : database(db) { }
Database &database;
Reason operator () ();
protected:
Reason query();
virtual Reason accept(CssmManagedData &) = 0;
};
class QueryUnlock : public QueryOld {
public:
QueryUnlock(KeychainDatabase &db) : QueryOld(db) { }
protected:
Reason accept(CssmManagedData &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 SecurityAgentQuery {
static const int maxTries = kMaximumAuthorizationTries;
public:
QueryNewPassphrase(Database &db, Reason reason) :
database(db), initialReason(reason),
mPassphrase(Allocator::standard(Allocator::sensitive)),
mPassphraseValid(false) { }
Database &database;
Reason operator () (CssmOwnedData &passphrase);
protected:
Reason query();
virtual Reason accept(CssmManagedData &passphrase, CssmData *oldPassphrase);
private:
Reason initialReason;
CssmAutoData mPassphrase;
bool mPassphraseValid;
};
class QueryGenericPassphrase : public SecurityAgentQuery {
public:
QueryGenericPassphrase() { }
Reason operator () (const char *prompt, bool verify,
string &passphrase);
protected:
Reason query(const char *prompt, bool verify, string &passphrase);
};
class QueryDBBlobSecret : public SecurityAgentQuery {
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 QueryInvokeMechanism : public SecurityAgentQuery, public RefCount {
public:
QueryInvokeMechanism(const AuthHostType type, Session &session);
void initialize(const string &inPluginId, const string &inMechanismId, const AuthValueVector &arguments, const SessionId inSessionId = 0);
void run(const AuthValueVector &inArguments, AuthItemSet &inHints, AuthItemSet &inContext, AuthorizationResult *outResult);
bool operator () (const string &inPluginId, const string &inMechanismId, const Authorization::AuthValueVector &inArguments, AuthItemSet &inHints, AuthItemSet &inContext, AuthorizationResult *outResult);
void terminateAgent();
AuthValueVector mArguments;
};
class QueryKeychainAuth : public SecurityAgentQuery {
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