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 69 worldChanged = 101 70}; 71 72typedef enum { 73 tool = 'TOOL', 74 bundle = 'BNDL', 75 unknown = 'UNKN' 76} RequestorType; 77 78#if defined(__cplusplus) 79 80using MachPlusPlus::Port; 81using MachPlusPlus::PortSet; 82using MachPlusPlus::Bootstrap; 83using MachPlusPlus::ReceivePort; 84using MachPlusPlus::Message; 85using Authorization::AuthItemSet; 86using Authorization::AuthValueVector; 87 88class Clients; 89 90class Client 91{ 92friend class Clients; 93 94enum MessageType { requestInterruptMessage, didDeactivateMessage, reportErrorMessage }; 95 96public: 97 Client(); 98 virtual ~Client(); 99 100 static AuthItemSet clientHints(SecurityAgent::RequestorType type, std::string &path, pid_t clientPid, uid_t clientUid); 101 102 static OSStatus startTransaction(Port serverPort); 103 static OSStatus endTransaction(Port serverPort); 104 105protected: 106 void establishServer(); 107 108public: 109 void activate(Port serverPort); 110 111 OSStatus contact(mach_port_t jobId, Bootstrap processBootstrap, mach_port_t userPrefs); 112 OSStatus create(const char *pluginId, const char *mechanismId, const SessionId inSessionId); 113 void setArguments(const Authorization::AuthValueVector& inArguments) { mArguments = inArguments; } 114 void setInput(const Authorization::AuthItemSet& inHints, const Authorization::AuthItemSet& inContext) { mInHints = inHints; mInContext = inContext; } 115 OSStatus invoke(); 116 OSStatus deactivate(); 117 OSStatus destroy(); 118 OSStatus terminate(); 119 void receive(); 120 121 void didCreate(const mach_port_t inStagePort); 122 void setResult(const AuthorizationResult inResult, const AuthorizationItemSet *inHints, const AuthorizationItemSet *inContext); 123 void requestInterrupt(); // setMessageType(requestInterrupt); 124 void didDeactivate(); // setMessageType(didDeactivate); 125 126 void setError(const OSStatus inMechanismError); // setMessageType(reportError); setError(mechanismError); 127 OSStatus getError(); 128 AuthorizationResult result() { return mResult; } 129 130 typedef enum _PluginState { 131 init, 132 created, 133 current, 134 deactivating, 135 active, 136 interrupting, 137 dead 138 } PluginState; 139 PluginState state() { return mState; } 140 141protected: 142 void setMessageType(const MessageType inMessageType); 143 // allow didCreate to set stagePort 144 void setStagePort(const mach_port_t inStagePort); 145 // allow server routines to use request port to find instance 146 147 // @@@ implement lessThan operator for set in terms of instance 148 149protected: 150 void setup(); 151 void teardown() throw(); 152 153 Port mServerPort; 154 Port mStagePort; 155 Port mClientPort; 156 157 MessageType mMessageType; 158 159 OSStatus mErrorState; 160 161 AuthorizationResult mResult; 162 AuthValueVector mArguments; 163 AuthItemSet mInHints; 164 AuthItemSet mInContext; 165 AuthItemSet mOutHints; 166 AuthItemSet mOutContext; 167 168 PluginState mState; 169 void setState(PluginState mState); 170 171public: 172 mach_port_t instance() const { return mClientPort; } 173// bool operator == (const Client &other) const { return this->instance() == other.instance(); } 174 bool operator < (const Client &other) const { return this->instance() < other.instance(); } 175 176 AuthItemSet &inHints() { return mInHints; } 177 AuthItemSet &inContext() { return mInContext; } 178 AuthItemSet &outHints() { return mOutHints; } 179 AuthItemSet &outContext() { return mOutContext; } 180 181public: 182 void check(mach_msg_return_t returnCode); 183 void checkResult(); 184}; 185 186class Clients 187{ 188friend class Client; 189 190protected: 191 set<Client*> mClients; 192 PortSet mClientPortSet; 193public: 194 Clients() {} 195 void create(); // create an agentclient 196 void insert(Client *agent) { StLock<Mutex> _(mLock); mClients.insert(agent); mClientPortSet += agent->instance(); } 197 void remove(Client *agent) { StLock<Mutex> _(mLock); mClientPortSet -= agent->instance(); mClients.erase(agent); } 198 Client &find(const mach_port_t instance) const; 199 bool receive(); 200 bool compare(const Client * client, mach_port_t instance); 201 202 mutable Mutex mLock; 203 static ThreadNexus<Clients> gClients; 204}; 205 206} // end namespace Authorization 207 208#endif /* __cplusplus__ */ 209 210#endif /* _H_AGENTCLIENT */ 211 212