/* * agentclient.h * SecurityAgent * * Copyright (c) 2002,2008 Apple Inc.. All rights reserved. * */ #ifndef _H_AGENTCLIENT #define _H_AGENTCLIENT #include #include #include #include #include #if defined(__cplusplus) #include #include #include namespace SecurityAgent { #endif /* __cplusplus__ */ // Manimum number of failed authentications before // SecurityAgent dialog is killed. #define kMaximumAuthorizationTries 10000 // Number of failed authentications before a password // hint is displayed. #define kAuthorizationTriesBeforeHint 3 #define maxPassphraseLength 1024 // // Unified reason codes transmitted to SecurityAgent (and internationalized there) // enum Reason { noReason = 0, // no reason (not used, used as a NULL) unknownReason, // something else (catch-all internal error) // reasons for asking for a new passphrase newDatabase = 11, // need passphrase for a new database changePassphrase, // changing passphrase for existing database // reasons for retrying an unlock query invalidPassphrase = 21, // passphrase was wrong // reasons for retrying a new passphrase query passphraseIsNull = 31, // empty passphrase passphraseTooSimple, // passphrase is not complex enough passphraseRepeated, // passphrase was used before (must use new one) passphraseUnacceptable, // passphrase unacceptable for some other reason oldPassphraseWrong, // the old passphrase given is wrong // reasons for retrying an authorization query userNotInGroup = 41, // authenticated user not in needed group unacceptableUser, // authenticated user unacceptable for some other reason // reasons for canceling a staged query tooManyTries = 61, // too many failed attempts to get it right noLongerNeeded, // the queried item is no longer needed keychainAddFailed, // the requested itemed couldn't be added to the keychain generalErrorCancel, // something went wrong so we have to give up now worldChanged = 101 }; typedef enum { tool = 'TOOL', bundle = 'BNDL', unknown = 'UNKN' } RequestorType; #if defined(__cplusplus) using MachPlusPlus::Port; using MachPlusPlus::PortSet; using MachPlusPlus::Bootstrap; using MachPlusPlus::ReceivePort; using MachPlusPlus::Message; using Authorization::AuthItemSet; using Authorization::AuthValueVector; class Clients; class Client { friend class Clients; enum MessageType { requestInterruptMessage, didDeactivateMessage, reportErrorMessage }; public: Client(); virtual ~Client(); static AuthItemSet clientHints(SecurityAgent::RequestorType type, std::string &path, pid_t clientPid, uid_t clientUid); static OSStatus startTransaction(Port serverPort); static OSStatus endTransaction(Port serverPort); protected: void establishServer(); public: void activate(Port serverPort); OSStatus create(const char *pluginId, const char *mechanismId, const SessionId inSessionId); void setArguments(const Authorization::AuthValueVector& inArguments) { mArguments = inArguments; } void setInput(const Authorization::AuthItemSet& inHints, const Authorization::AuthItemSet& inContext) { mInHints = inHints; mInContext = inContext; } OSStatus invoke(); OSStatus deactivate(); OSStatus destroy(); OSStatus terminate(); void receive(); void didCreate(const mach_port_t inStagePort); void setResult(const AuthorizationResult inResult, const AuthorizationItemSet *inHints, const AuthorizationItemSet *inContext); void requestInterrupt(); // setMessageType(requestInterrupt); void didDeactivate(); // setMessageType(didDeactivate); void setError(const OSStatus inMechanismError); // setMessageType(reportError); setError(mechanismError); OSStatus getError(); AuthorizationResult result() { return mResult; } typedef enum _PluginState { init, created, current, deactivating, active, interrupting, dead } PluginState; PluginState state() { return mState; } protected: void setMessageType(const MessageType inMessageType); // allow didCreate to set stagePort void setStagePort(const mach_port_t inStagePort); // allow server routines to use request port to find instance // @@@ implement lessThan operator for set in terms of instance protected: void setup(); void teardown() throw(); Port mServerPort; Port mStagePort; Port mClientPort; MessageType mMessageType; OSStatus mErrorState; AuthorizationResult mResult; AuthValueVector mArguments; AuthItemSet mInHints; AuthItemSet mInContext; AuthItemSet mOutHints; AuthItemSet mOutContext; PluginState mState; void setState(PluginState mState); public: mach_port_t instance() const { return mClientPort; } // bool operator == (const Client &other) const { return this->instance() == other.instance(); } bool operator < (const Client &other) const { return this->instance() < other.instance(); } AuthItemSet &inHints() { return mInHints; } AuthItemSet &inContext() { return mInContext; } AuthItemSet &outHints() { return mOutHints; } AuthItemSet &outContext() { return mOutContext; } public: void check(mach_msg_return_t returnCode); void checkResult(); }; class Clients { friend class Client; protected: set mClients; PortSet mClientPortSet; public: Clients() {} void create(); // create an agentclient void insert(Client *agent) { StLock _(mLock); mClients.insert(agent); mClientPortSet += agent->instance(); } void remove(Client *agent) { StLock _(mLock); mClientPortSet -= agent->instance(); mClients.erase(agent); } Client &find(const mach_port_t instance) const; bool receive(); bool compare(const Client * client, mach_port_t instance); mutable Mutex mLock; static ThreadNexus gClients; }; } // end namespace Authorization #endif /* __cplusplus__ */ #endif /* _H_AGENTCLIENT */