1/* 2 * agentclient.h 3 * SecurityAgent 4 * 5 * Copyright (c) 2002,2008 Apple Inc.. All rights reserved. 6 * 7 */ 8 9#ifndef _H_AGENTCLIENT 10#define _H_AGENTCLIENT 11 12#include <Security/Authorization.h> 13#include <Security/AuthorizationPlugin.h> 14#include <Security/AuthorizationTags.h> 15#include <Security/AuthorizationTagsPriv.h> 16 17#include <security_agent_client/sa_types.h> 18 19#if defined(__cplusplus) 20 21#include <string> 22#include <security_utilities/mach++.h> 23#include <security_cdsa_utilities/AuthorizationData.h> 24 25namespace SecurityAgent { 26#endif /* __cplusplus__ */ 27 28// Manimum number of failed authentications before 29// SecurityAgent dialog is killed. 30#define kMaximumAuthorizationTries 10000 31 32// Number of failed authentications before a password 33// hint is displayed. 34#define kAuthorizationTriesBeforeHint 3 35 36#define maxPassphraseLength 1024 37 38// 39// Unified reason codes transmitted to SecurityAgent (and internationalized there) 40// 41enum Reason { 42 noReason = 0, // no reason (not used, used as a NULL) 43 unknownReason, // something else (catch-all internal error) 44 45 // reasons for asking for a new passphrase 46 newDatabase = 11, // need passphrase for a new database 47 changePassphrase, // changing passphrase for existing database 48 49 // reasons for retrying an unlock query 50 invalidPassphrase = 21, // passphrase was wrong 51 52 // reasons for retrying a new passphrase query 53 passphraseIsNull = 31, // empty passphrase 54 passphraseTooSimple, // passphrase is not complex enough 55 passphraseRepeated, // passphrase was used before (must use new one) 56 passphraseUnacceptable, // passphrase unacceptable for some other reason 57 oldPassphraseWrong, // the old passphrase given is wrong 58 59 // reasons for retrying an authorization query 60 userNotInGroup = 41, // authenticated user not in needed group 61 unacceptableUser, // authenticated user unacceptable for some other reason 62 63 // reasons for canceling a staged query 64 tooManyTries = 61, // too many failed attempts to get it right 65 noLongerNeeded, // the queried item is no longer needed 66 keychainAddFailed, // the requested itemed couldn't be added to the keychain 67 generalErrorCancel, // something went wrong so we have to give up now 68 resettingPassword, // The user has indicated that they wish to reset their password 69 70 worldChanged = 101 71}; 72 73typedef enum { 74 tool = 'TOOL', 75 bundle = 'BNDL', 76 unknown = 'UNKN' 77} RequestorType; 78 79#if defined(__cplusplus) 80 81using MachPlusPlus::Port; 82using MachPlusPlus::PortSet; 83using MachPlusPlus::Bootstrap; 84using MachPlusPlus::ReceivePort; 85using MachPlusPlus::Message; 86using Authorization::AuthItemSet; 87using Authorization::AuthValueVector; 88 89class Clients; 90 91class Client 92{ 93friend class Clients; 94 95enum MessageType { requestInterruptMessage, didDeactivateMessage, reportErrorMessage }; 96 97public: 98 Client(); 99 virtual ~Client(); 100 101 static AuthItemSet clientHints(SecurityAgent::RequestorType type, std::string &path, pid_t clientPid, uid_t clientUid); 102 103 static OSStatus startTransaction(Port serverPort); 104 static OSStatus endTransaction(Port serverPort); 105 106protected: 107 void establishServer(); 108 109public: 110 void activate(Port serverPort); 111 112 OSStatus contact(mach_port_t jobId, Bootstrap processBootstrap, mach_port_t userPrefs); 113 OSStatus create(const char *pluginId, const char *mechanismId, const SessionId inSessionId); 114 void setArguments(const Authorization::AuthValueVector& inArguments) { mArguments = inArguments; } 115 void setInput(const Authorization::AuthItemSet& inHints, const Authorization::AuthItemSet& inContext) { mInHints = inHints; mInContext = inContext; } 116 OSStatus invoke(); 117 OSStatus deactivate(); 118 OSStatus destroy(); 119 OSStatus terminate(); 120 void receive(); 121 122 void didCreate(const mach_port_t inStagePort); 123 void setResult(const AuthorizationResult inResult, const AuthorizationItemSet *inHints, const AuthorizationItemSet *inContext); 124 void requestInterrupt(); // setMessageType(requestInterrupt); 125 void didDeactivate(); // setMessageType(didDeactivate); 126 127 void setError(const OSStatus inMechanismError); // setMessageType(reportError); setError(mechanismError); 128 OSStatus getError(); 129 AuthorizationResult result() { return mResult; } 130 131 typedef enum _PluginState { 132 init, 133 created, 134 current, 135 deactivating, 136 active, 137 interrupting, 138 dead 139 } PluginState; 140 PluginState state() { return mState; } 141 142protected: 143 void setMessageType(const MessageType inMessageType); 144 // allow didCreate to set stagePort 145 void setStagePort(const mach_port_t inStagePort); 146 // allow server routines to use request port to find instance 147 148 // @@@ implement lessThan operator for set in terms of instance 149 150protected: 151 void setup(); 152 void teardown() throw(); 153 154 Port mServerPort; 155 Port mStagePort; 156 Port mClientPort; 157 158 MessageType mMessageType; 159 160 OSStatus mErrorState; 161 162 AuthorizationResult mResult; 163 AuthValueVector mArguments; 164 AuthItemSet mInHints; 165 AuthItemSet mInContext; 166 AuthItemSet mOutHints; 167 AuthItemSet mOutContext; 168 169 PluginState mState; 170 void setState(PluginState mState); 171 172 bool mTerminateOnSleep; 173 174public: 175 mach_port_t instance() const { return mClientPort; } 176// bool operator == (const Client &other) const { return this->instance() == other.instance(); } 177 bool operator < (const Client &other) const { return this->instance() < other.instance(); } 178 179 AuthItemSet &inHints() { return mInHints; } 180 AuthItemSet &inContext() { return mInContext; } 181 AuthItemSet &outHints() { return mOutHints; } 182 AuthItemSet &outContext() { return mOutContext; } 183 184 void setTerminateOnSleep(bool terminateOnSleep) {mTerminateOnSleep = terminateOnSleep;} 185 bool getTerminateOnSleep() {return mTerminateOnSleep;} 186 187public: 188 void check(mach_msg_return_t returnCode); 189 void checkResult(); 190}; 191 192class Clients 193{ 194friend class Client; 195 196protected: 197 set<Client*> mClients; 198 PortSet mClientPortSet; 199public: 200 Clients() {} 201 void create(); // create an agentclient 202 void insert(Client *agent) { StLock<Mutex> _(mLock); mClients.insert(agent); mClientPortSet += agent->instance(); } 203 void remove(Client *agent) { StLock<Mutex> _(mLock); mClientPortSet -= agent->instance(); mClients.erase(agent); } 204 Client &find(const mach_port_t instance) const; 205 bool receive(); 206 bool compare(const Client * client, mach_port_t instance); 207 208 mutable Mutex mLock; 209 static ThreadNexus<Clients> gClients; 210 static ModuleNexus<RecursiveMutex> gAllClientsMutex; 211 static ModuleNexus<set<Client*> > allClients; 212 static void killAllClients(); 213}; 214 215} // end namespace Authorization 216 217#endif /* __cplusplus__ */ 218 219#endif /* _H_AGENTCLIENT */ 220 221