1/* 2 * Copyright (c) 2000-2009 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// connection - manage connections to clients 27// 28#ifndef _H_CONNECTION 29#define _H_CONNECTION 30 31#include "process.h" 32#include "session.h" 33#include "notifications.h" 34#include <bsm/libbsm.h> // audit_token_t 35#include <string> 36 37using MachPlusPlus::Port; 38using MachPlusPlus::TaskPort; 39 40class Session; 41 42// define the minimum interface Connection requires for classes wanting to 43// participate in SecurityAgent/authorizationhost IPCs (defined here rather 44// than agentquery.h to avoid circularity in headers) 45class SecurityAgentConnectionInterface 46{ 47public: 48 virtual void disconnect() = 0; 49}; 50 51// 52// A Connection object represents an established connection between a client 53// and securityd. There is a separate Connection object for each Mach reply port 54// that was (ever) used to talk to securityd. In practice, this maps to one reply 55// port (and thus one Connection) for each client thread that (ever) talks to securityd. 56// 57// If a client tricked us into using multiple reply ports from one thread, we'd treat 58// them as distinct client threads (which really doesn't much matter to us). The standard 59// client library (libsecurityd) won't let you do that. 60// 61class Connection : public PerConnection, public Listener::JitterBuffer { 62public: 63 Connection(Process &proc, Port rPort); 64 virtual ~Connection(); 65 void terminate(); // normal termination 66 void abort(bool keepReplyPort = false); // abnormal termination 67 68 Port clientPort() const { return mClientPort; } 69 70 // Code Signing guest management - tracks current guest id in client 71 SecGuestRef guestRef() const { return mGuestRef; } 72 void guestRef(SecGuestRef newGuest, SecCSFlags flags = 0); 73 74 audit_token_t *auditToken() const { return mAuditToken; } 75 76 // work framing - called as work threads pick up connection work 77 void beginWork(audit_token_t &auditToken); // I've got it 78 void checkWork(); // everything still okay? 79 void endWork(CSSM_RETURN &rcode); // Done with this 80 81 // notify that a SecurityAgent call may hang the active worker thread for a while 82 void useAgent(SecurityAgentConnectionInterface *client) 83 { StLock<Mutex> _(*this); agentWait = client; } 84 85 // set an overriding CSSM_RETURN to return instead of success 86 void overrideReturn(CSSM_RETURN rc) { mOverrideReturn = rc; } 87 88 Process &process() const { return parent<Process>(); } 89 Session &session() const { return process().session(); } 90 91private: 92 // peer state: established during connection startup; fixed thereafter 93 Port mClientPort; // client's Mach reply port 94 SecGuestRef mGuestRef; // last known Code Signing guest reference for this client thread 95 audit_token_t *mAuditToken; // in case auditing is required 96 CSSM_RETURN mOverrideReturn; // override successful return code (only) 97 98 // transient state (altered as we go) 99 enum State { 100 idle, // no thread services us 101 busy, // a thread is busy servicing us 102 dying // busy and scheduled to die as soon as possible 103 } state; 104 SecurityAgentConnectionInterface *agentWait; // SA connection we may be waiting on 105}; 106 107 108#endif //_H_CONNECTION 109