agentquery.h
1 /* 2 * Copyright (c) 2000-2005,2007-2010,2012-2013 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24 25 // 26 // passphrases - canonical code to obtain passphrases 27 // 28 #ifndef _H_AGENTQUERY 29 #define _H_AGENTQUERY 30 31 #include <security_cdsa_utilities/AuthorizationData.h> 32 #include <security_utilities/ccaudit.h> // some queries do their own authentication 33 #include <Security/AuthorizationPlugin.h> 34 #include "kcdatabase.h" 35 #include "authhost.h" 36 #include "server.h" 37 #include "session.h" 38 #include <xpc/xpc.h> 39 40 using Authorization::AuthItemSet; 41 using Authorization::AuthValueVector; 42 using Security::OSXCode; 43 44 #define kMaximumAuthorizationTries (10000) 45 46 // 47 // base for classes talking to com.apple.security.agent and com.apple.security.authhost 48 // 49 class SecurityAgentXPCConnection 50 { 51 public: 52 SecurityAgentXPCConnection(Session &session = Server::session()); 53 virtual ~SecurityAgentXPCConnection(); 54 virtual void activate(bool ignoreUid); 55 virtual void disconnect() { }; 56 virtual void terminate(); 57 58 protected: 59 RefPointer<AuthHostInstance> mHostInstance; 60 Session &mSession; 61 xpc_connection_t mXPCConnection; 62 const RefPointer<Connection> mConnection; 63 audit_token_t *mAuditToken; 64 uid_t mNobodyUID; 65 66 bool inDarkWake(); 67 68 }; 69 70 71 // 72 // The main com.apple.security.agent interaction base class 73 // 74 class SecurityAgentXPCQuery : public SecurityAgentXPCConnection 75 { 76 public: 77 static void killAllXPCClients(); 78 79 typedef SecurityAgent::Reason Reason; 80 81 SecurityAgentXPCQuery(Session &session = Server::session()); 82 83 84 void inferHints(Process &thisProcess); 85 void addHint(const char *name, const void *value = NULL, UInt32 valueLen = 0, UInt32 flags = 0); 86 87 virtual ~SecurityAgentXPCQuery(); 88 89 virtual void disconnect(); 90 virtual void terminate(); 91 void create(const char *pluginId, const char *mechanismId); 92 void invoke(); 93 void setTerminateOnSleep(bool terminateOnSleep) {mTerminateOnSleep = terminateOnSleep;} 94 bool getTerminateOnSleep() {return mTerminateOnSleep;} 95 void setInput(const AuthItemSet& inHints, const AuthItemSet& inContext) { mInHints = inHints; mInContext = inContext; } 96 void checkResult(); 97 98 void readChoice(); 99 100 bool allow; 101 bool remember; 102 103 protected: 104 AuthItemSet mClientHints; 105 AuthItemSet mImmutableHints; 106 AuthItemSet mInHints; 107 AuthItemSet mInContext; 108 AuthItemSet mOutHints; 109 AuthItemSet mOutContext; 110 bool mAgentConnected; 111 uint64_t mLastResult; 112 bool mTerminateOnSleep; 113 }; 114 115 // 116 // Specialized for "rogue app" alert queries 117 // 118 class QueryKeychainUse : public SecurityAgentXPCQuery { 119 public: 120 QueryKeychainUse(bool needPass, const Database *db); 121 Reason queryUser (const char* database, const char *description, AclAuthorization action); 122 123 private: 124 const KeychainDatabase *mPassphraseCheck; // NULL to not check passphrase 125 }; 126 127 128 // 129 // A query for an existing passphrase 130 // 131 class QueryOld : public SecurityAgentXPCQuery { 132 static const int maxTries = kMaximumAuthorizationTries; 133 public: 134 QueryOld(Database &db) : database(db) {setTerminateOnSleep(true);} 135 136 Database &database; 137 138 Reason operator () (); 139 140 protected: 141 Reason query(); 142 virtual Reason accept(CssmManagedData &) = 0; 143 }; 144 145 146 class QueryUnlock : public QueryOld { 147 public: 148 QueryUnlock(KeychainDatabase &db) : QueryOld(db) { } 149 Reason retrievePassword(CssmOwnedData &passphrase); 150 151 protected: 152 Reason accept(CssmManagedData &passphrase); 153 }; 154 155 156 class QueryKeybagPassphrase : public SecurityAgentXPCQuery { 157 public: 158 QueryKeybagPassphrase(Session &session, int32_t retries = kMaximumAuthorizationTries); 159 160 Reason query(); 161 Reason accept(CssmManagedData &passphrase); 162 protected: 163 Session &mSession; 164 service_context_t mContext; 165 int32_t mRetries; 166 }; 167 168 class QueryKeybagNewPassphrase : public QueryKeybagPassphrase { 169 public: 170 QueryKeybagNewPassphrase(Session &session); 171 172 Reason query(CssmOwnedData &oldPassphrase, CssmOwnedData &passphrase); 173 }; 174 175 // 176 // Repurpose QueryUnlock for PIN prompting 177 // Not very clean - but this stuff is an outdated hack as it is... 178 // 179 class QueryPIN : public QueryOld { 180 public: 181 QueryPIN(Database &db); 182 183 const CssmData &pin() const { return mPin; } 184 185 protected: 186 Reason accept(CssmManagedData &pin); 187 188 private: 189 CssmAutoData mPin; // PIN obtained 190 }; 191 192 193 // 194 // A query for a new passphrase 195 // 196 class QueryNewPassphrase : public SecurityAgentXPCQuery { 197 static const int maxTries = kMaximumAuthorizationTries; 198 public: 199 QueryNewPassphrase(Database &db, Reason reason) : 200 database(db), initialReason(reason), 201 mPassphrase(Allocator::standard(Allocator::sensitive)), 202 mOldPassphrase(Allocator::standard(Allocator::sensitive)), 203 mPassphraseValid(false) { } 204 205 Database &database; 206 207 Reason operator () (CssmOwnedData &oldPassphrase, CssmOwnedData &passphrase); 208 209 protected: 210 Reason query(); 211 virtual Reason accept(CssmManagedData &passphrase, CssmData *oldPassphrase); 212 213 private: 214 Reason initialReason; 215 CssmAutoData mPassphrase; 216 CssmAutoData mOldPassphrase; 217 bool mPassphraseValid; 218 }; 219 220 221 // 222 // Generic passphrase query (not associated with a database) 223 // 224 class QueryGenericPassphrase : public SecurityAgentXPCQuery { 225 public: 226 QueryGenericPassphrase() { } 227 Reason operator () (const CssmData *prompt, bool verify, 228 string &passphrase); 229 230 protected: 231 Reason query(const CssmData *prompt, bool verify, string &passphrase); 232 }; 233 234 235 // 236 // Generic secret query (not associated with a database) 237 // 238 class QueryDBBlobSecret : public SecurityAgentXPCQuery { 239 static const int maxTries = kMaximumAuthorizationTries; 240 public: 241 QueryDBBlobSecret() { } 242 Reason operator () (DbHandle *dbHandleArray, uint8 dbHandleArrayCount, DbHandle *dbHandleAuthenticated); 243 244 protected: 245 Reason query(DbHandle *dbHandleArray, uint8 dbHandleArrayCount, DbHandle *dbHandleAuthenticated); 246 Reason accept(CssmManagedData &passphrase, DbHandle *dbHandlesToAuthenticate, uint8 dbHandleCount, DbHandle *dbHandleAuthenticated); 247 }; 248 249 // hybrid of confirm-access and generic authentication queries, for 250 // securityd's use; keep the Frankenstein references to yourself 251 // (the alternative is to ask the user to unlock the system keychain, 252 // and you don't want that, do you?) 253 class QueryKeychainAuth : public SecurityAgentXPCQuery { 254 static const int maxTries = kMaximumAuthorizationTries; 255 public: 256 QueryKeychainAuth() { } 257 // "prompt" can be NULL 258 Reason performQuery(const KeychainDatabase&, const char *description, AclAuthorization action, const char *prompt); 259 Reason accept(string &username, string &passphrase); 260 }; 261 262 #endif //_H_AGENTQUERY