1/* 2 * Copyright (c) 2004 Apple Computer, 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// server - master server loop for tokend 25// 26#include "server.h" 27#include "tdclient.h" 28#include <securityd_client/ssclient.h> 29#include <security_cdsa_client/mdsclient.h> 30 31using namespace MachPlusPlus; 32 33 34// 35// The MIG-generated server dispatch function 36// 37extern boolean_t tokend_server(mach_msg_header_t *in, mach_msg_header_t *out); 38 39 40namespace Security { 41namespace Tokend { 42 43 44// 45// The server singleton 46// 47Server *server = NULL; 48 49 50// 51// Drive the server 52// 53int Server::operator () (int argc, const char *argv[], SecTokendCallbackFlags flags) 54{ 55 // process command-line arguments as sent by securityd 56 if (argc != 4) { 57 secdebug("tokenlib", "invalid argument count (%d)", argc); 58 Syslog::notice("token daemon invoked with invalid arguments"); 59 return 2; 60 } 61 62 // argv[1] == version of wire protocol 63 const char *versionString = argv[1]; 64 if (atol(versionString) != TDPROTOVERSION) { 65 // This would be a mismatch between securityd and the SecurityTokend.framework 66 // It's NOT a "binary compatibility" mismatch; that got checked for by our caller. 67 secdebug("tokenlib", "incoming protocol %s expected %d - aborting", 68 versionString, TDPROTOVERSION); 69 return 2; 70 } 71 72 // argv[2] == reader name 73 mReaderName = argv[2]; 74 secdebug("tokenlib", "reader '%s' wire protocol %s", mReaderName, versionString); 75 76 // argv[3] == hex coding of reader state, with name() undefined 77 CssmData::wrap(mStartupReaderState).fromHex(argv[3]); 78 mStartupReaderState.name(readerName()); // fix name pointer (shipped separately) 79 80#if !defined(NDEBUG) 81 // stop right here; do not run the server. We're being run from the command line 82 if (flags & kSecTokendCallbacksTestNoServer) 83 return 0; 84#endif 85 86 // handshake with securityd 87 secdebug("tokenlib", "checking in with securityd"); 88 SecurityServer::ClientSession client(Allocator::standard(), Allocator::standard()); 89 client.childCheckIn(primaryServicePort(), TaskPort()); 90 91 // start dispatch; from here on securityd is driving us 92 secdebug("tokenlib", "starting server loop"); 93 run(); 94 95 // we don't usually return from run(), but just in case 96 termination(0, 0); 97} 98 99 100// 101// Handle the terminate message 102// 103void Server::termination(uint32 reason, uint32 options) 104{ 105 secdebug("tokenlib", "terminate(%d,0x%x) received", reason, options); 106 if (terminate) 107 terminate(reason, options); // ignore return code 108 exit(0); 109} 110 111 112// 113// MIG handler hook 114// 115boolean_t Server::handle(mach_msg_header_t *in, mach_msg_header_t *out) 116{ 117 return tokend_server(in, out); 118} 119 120 121} // namespace Tokend 122} // namespace Security 123