]> git.saurik.com Git - apple/security.git/blob - SecurityServer/MacYarrow/YarrowServer/YarrowServer_OSX.cpp
Security-28.tar.gz
[apple/security.git] / SecurityServer / MacYarrow / YarrowServer / YarrowServer_OSX.cpp
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19 /*
20 * YarrowServer - Yarrow RNG server object, OSX version
21 */
22 #include "YarrowServer_OSX.h"
23 #include <mach/mach_error.h>
24 #include <sys/errno.h>
25 #include <stdio.h> // debug
26 #include <yarrowMigTypes.h>
27 #include "MacYarrow_OSX.h"
28 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
29 #include <Security/cssmalloc.h>
30
31 #define YS_DEBUG 0
32 #if YS_DEBUG
33 #define ysprintf(x) printf x
34 #else
35 #define ysprintf(x)
36 #endif
37
38 using MachPlusPlus::MachServer;
39
40 /*
41 * A timer for this module. Just one, and it's always active subsequent to startup.
42 */
43 class YarrowTimer : public MachServer::Timer {
44 public:
45 YarrowTimer(MachPlusPlus::MachServer &server) :
46 MachServer::Timer(),
47 mServer(server) {}
48
49 void action();
50 void scheduleTimer(unsigned msFromNow);
51 private:
52 MachPlusPlus::MachServer &mServer; // to which we do setTimer()
53 };
54
55 /*
56 * Timeout event, the sole purpose of this class. Pass on to MacYarrow module.
57 */
58 void YarrowTimer::action()
59 {
60 unsigned nextTimeout = yarrowTimerEvent();
61 scheduleTimer(nextTimeout);
62 }
63
64 void YarrowTimer::scheduleTimer(unsigned msFromNow)
65 {
66 mServer.setTimer(this, Time::Interval(msFromNow / 1000.0));
67 }
68
69 /* global, one per process, therefore one per system */
70 static YarrowTimer *yarrowTimer;
71 static CssmAllocator *cssmAlloc; // for temp alloc in
72 // yarrow_server_getRandomBytes()
73
74 YarrowServer::YarrowServer(MachPlusPlus::MachServer &globalServer, const char *entropyFilePath) :
75 MachServer(YARROW_SERVER_NAME)
76 {
77 #ifdef TEMPORARY_SEMANTICS
78 MutexLocker ml (gYarrowMutex);
79 #endif
80 unsigned firstTimeout;
81 yarrowTimer = new YarrowTimer(globalServer);
82 cssmAlloc = &CssmAllocator::standard();
83 yarrowServerInit(entropyFilePath, &firstTimeout);
84 yarrowTimer->scheduleTimer(firstTimeout);
85 }
86
87
88 /*
89 * Clean up the server object
90 */
91 YarrowServer::~YarrowServer()
92 {
93 delete yarrowTimer; // FIXME - is this safe? Does MachServer do this?
94 }
95
96 /*
97 * Thread::run() specific to this class, needed because both MachServer
98 * and Thread have a run() method. Called from main().
99 */
100 void YarrowServer::runYarrow()
101 {
102 Thread::run();
103 }
104
105 /*
106 * Run the server. This will not return until the server is forced to exit.
107 */
108 void YarrowServer::action()
109 {
110 ysprintf(("YarrowServer: running MachServer\n"));
111 MachServer::run();
112 }
113
114
115 //
116 // The server run-loop function, called out from MachServer
117 //
118 boolean_t yarrow_server(mach_msg_header_t *, mach_msg_header_t *);
119
120 boolean_t YarrowServer::handle(mach_msg_header_t *in, mach_msg_header_t *out)
121 {
122 return yarrow_server(in, out);
123 }
124
125
126 //
127 // Handling dead-port notifications
128 // FIXME - how is this used?
129 //
130 void YarrowServer::notifyDeadName(MachPlusPlus::Port port)
131 {
132 // forcibly end the Connection
133 // FIXME....endConnection(port, true);
134 }
135
136 /*
137 * Functions called from server side of MIG interface.
138 * As far as I can tell, MIG doesn't generate
139 * prototypes for the server side...FIXME....
140 */
141
142 /* Bracket Macros */
143 #define UCSP_ARGS mach_port_t sport, mach_port_t rport, OSStatus *rcode
144
145 kern_return_t
146 yarrow_server_addEntropy(
147 UCSP_ARGS,
148 Data bytes,
149 mach_msg_type_number_t bytesCnt,
150 UInt32 entBits)
151 {
152 unsigned nextTimeout;
153 ysprintf(("yarrow server addEntropy(%02X %02X %02X %02X...) called\n",
154 ((UInt8 *)bytes)[0], ((UInt8 *)bytes)[1], ((UInt8 *)bytes)[2],
155 ((UInt8 *)bytes)[3]));
156 *rcode = yarrowAddEntropy(static_cast<UInt8 *>(bytes), bytesCnt, entBits,
157 &nextTimeout);
158 if(nextTimeout != 0) {
159 yarrowTimer->scheduleTimer(nextTimeout);
160 }
161 return KERN_SUCCESS;
162 }
163
164
165 kern_return_t
166 yarrow_server_getRandomBytes(
167 UCSP_ARGS,
168 UInt32 numBytes, // in
169 Data *bytes, // out
170 mach_msg_type_number_t *bytesCnt) // out
171 {
172 /*
173 * We have to allocate here; MIG does a virtual copy back to
174 * client. MachServer releases later.
175 */
176 void *tempPtr;
177 try {
178 tempPtr = cssmAlloc->malloc(numBytes);
179 }
180 catch(...) {
181 return unix_err(ENOMEM);
182 }
183 MachPlusPlus::MachServer::active().releaseWhenDone(*cssmAlloc, tempPtr);
184 *rcode = yarrowGetRandomBytes(reinterpret_cast<UInt8 *>(tempPtr), numBytes);
185 if(*rcode == noErr) {
186 *bytes = reinterpret_cast<Data>(tempPtr);
187 *bytesCnt = numBytes;
188 }
189 else {
190 *bytesCnt = 0;
191 }
192 ysprintf(("yarrow server getRandomBytes called; data %02X %02X %02X %02X...\n",
193 ((UInt8 *)*bytes)[0], ((UInt8 *)*bytes)[1], ((UInt8 *)*bytes)[2],
194 ((UInt8 *)*bytes)[3]));
195 return KERN_SUCCESS;
196 }