There are no available options for this view.

Parent Directory Parent Directory | Revision <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Log">Log</a> Revision <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Log">Log</a>

Revision 1.77 - (show annotations) (download) (as text)
Sat Nov 20 06:42:54 2004 UTC (7 years, 6 months ago) by dossy
Branch: MAIN
CVS Tags: v3_0beta26, v3_0beta27, HEAD
Changes since 1.76: +37 -72 lines
File MIME type: text/x-chdr
Fix memory leak in <a href="/cvs/aolserver/nsopenssl/sslcontext.c#A_IssueTmpRSAKey">IssueTmpRSAKey</a>, introducing new <a href="/cvs/aolserver/nsopenssl/sslcontext.c#A_NsMakeTmpRSAKey">NsMakeTmpRSAKey</a> and
pre-generating 512-bit and 1024-bit temporary RSA keys at nsopenssl
module initialization time.  Closes SF Bug #1069595.
1 /*
2 * The contents of this file are subject to the AOLserver Public License
3 * Version 1.1 (the "License"); you may not use this file except in
4 * compliance with the License. You may obtain a copy of the License at
5 * http://aolserver.com.
6 *
7 * Software distributed under the License is distributed on an "AS IS"
8 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
9 * the License for the specific language governing rights and limitations
10 * under the License.
11 *
12 * Alternatively, the contents of this file may be used under the terms
13 * of the GNU General Public License (the "GPL"), in which case the
14 * provisions of GPL are applicable instead of those above. If you wish
15 * to allow use of your version of this file only under the terms of the
16 * GPL and not to allow others to use your version of this file under the
17 * License, indicate your decision by deleting the provisions above and
18 * replace them with the notice and other provisions required by the GPL.
19 * If you do not delete the provisions above, a recipient may use your
20 * version of this file under either the License or the GPL.
21 *
22 * Copyright (C) 2000-2003 Scott S. Goodwin
23 *
24 * Module originally written by Stefan Arentz. Early contributions made by
25 * Freddie Mendoze and Rob Mayoff.
26 *
27 * Portions created by AOL are Copyright (C) 1999 America Online, Inc.
28 * All Rights Reserved.
29 */
30
31 /*
32 * nsopenssl.c --
33 *
34 * Implements SSLv2, SSLv3 and TLSv1 module using OpenSSL.
35 */
36
37 static const char *RCSID = "@(#) $Header: /cvsroot-fuse/aolserver/nsopenssl/nsopenssl.c,v 1.77 2004/11/20 06:42:54 dossy Exp $, compiled: " __DATE__ " " __TIME__;
38
39 #include "nsopenssl.h"
40
41 extern Tcl_HashTable NsOpenSSLServers;
42 extern void NsOpenSSLDriversLoad(char *server);
43 extern int <a href="/cvs/aolserver/nsopenssl/sslcontext.c#A_NsMakeTmpRSAKey">NsMakeTmpRSAKey</a>(int keylen);
44
45 static Ns_Mutex *locks;
46 static Ns_DriverProc <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_OpenSSLProc">OpenSSLProc</a>;
47
48 static int <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_InitOpenSSL">InitOpenSSL</a>(void);
49 static void <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_InitServerState">InitServerState</a>(char *server);
50 static int <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_SeedPRNG">SeedPRNG</a>(void);
51 static void <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_ThreadLockCallback">ThreadLockCallback</a>(int mode, int n, const char *file, int line);
52 static unsigned long <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_ThreadIdCallback">ThreadIdCallback</a>(void);
53 static struct CRYPTO_dynlock_value *<a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_ThreadDynlockCreateCallback">ThreadDynlockCreateCallback</a>(char *file, int line);
54 static void <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_ThreadDynlockLockCallback">ThreadDynlockLockCallback</a>(int mode, struct CRYPTO_dynlock_value *dynlock, const char *file, int line);
55 static void <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_ThreadDynlockDestroyCallback">ThreadDynlockDestroyCallback</a>(struct CRYPTO_dynlock_value *dynlock, const char *file, int line);
56 static void <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_ServerShutdown">ServerShutdown</a>(void *arg);
57 static void <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_LoadSSLContexts">LoadSSLContexts</a>(char *server);
58 static NsOpenSSLContext *<a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_LoadSSLContext">LoadSSLContext</a>(char *server, char *name);
59 static int <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_InitSSLDriver">InitSSLDriver</a>(char *server, NsOpenSSLDriver *ssldriver);
60 static void <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_LoadSSLDrivers">LoadSSLDrivers</a>(char *server);
61
62 int Ns_ModuleVersion = 1;
63
64
65 /*
66 *----------------------------------------------------------------------
67 *
68 * Ns_ModuleInit --
69 *
70 * nsopenssl module initialization.
71 *
72 * Results:
73 * NS_OK or NS_ERROR
74 *
75 * Side effects:
76 *
77 *----------------------------------------------------------------------
78 */
79
80 int
81 Ns_ModuleInit(char *server, char *module)
82 {
83 static int initialized = NS_FALSE;
84 int i;
85
86 /*
87 * Initialize one-time global stuff.
88 */
89
90 if (initialized == NS_FALSE) {
91 if (!STREQ(module, MODULE)) {
92 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Fatal, "Module '%s' should be named '%s'", module, MODULE);
93 }
94 if (<a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_InitOpenSSL">InitOpenSSL</a>() == NS_ERROR) {
95 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Error, "%s: OpenSSL failed to initialize", MODULE);
96 return NS_ERROR;
97 }
98 Tcl_InitHashTable(&NsOpenSSLServers, TCL_STRING_KEYS);
99
100 /*
101 * Pre-generate temporary RSA keys for 512 and 1024 bit keys.
102 */
103
104 <a href="/cvs/aolserver/nsopenssl/sslcontext.c#A_NsMakeTmpRSAKey">NsMakeTmpRSAKey</a>(512);
105 <a href="/cvs/aolserver/nsopenssl/sslcontext.c#A_NsMakeTmpRSAKey">NsMakeTmpRSAKey</a>(1024);
106
107 initialized = NS_TRUE;
108 }
109
110 /*
111 * Initialize this virtual server's state information
112 */
113
114 <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_InitServerState">InitServerState</a>(server);
115
116 /*
117 * Load this virtual server's SSL contexts from the configuration file.
118 */
119
120 <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_LoadSSLContexts">LoadSSLContexts</a>(server);
121
122 /*
123 * Load and start the driver(s) for this virtual server. A driver manages
124 * one SSL port; for a virtual server to use more than one port, you must
125 * define a driver for each port. A driver must be associated with a named
126 * SSL context.
127 */
128
129 <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_LoadSSLDrivers">LoadSSLDrivers</a>(server);
130
131 /*
132 * Create the nsopenssl Tcl commands for this virtual server's interps.
133 */
134
135 <a href="/cvs/aolserver/nsopenssl/tclcmds.c#A_NsOpenSSLTclInit">NsOpenSSLTclInit</a>(server);
136
137 /*
138 * Register a cleanup function to run at server shutdown time.
139 */
140
141 <a href="/cvs/aolserver/aolserver/nsd/callbacks.c#A_Ns_RegisterAtShutdown">Ns_RegisterAtShutdown</a>(<a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_ServerShutdown">ServerShutdown</a>, (void *) server);
142
143 return NS_OK;
144 }
145
146 /*
147 *----------------------------------------------------------------------
148 *
149 * <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_NsOpenSSLDebug">NsOpenSSLDebug</a> --
150 *
151 * Write message to log file. When not in debug mode, no logging is done,
152 * function just returns.
153 *
154 *----------------------------------------------------------------------
155 */
156
157 #if 0
158 extern void
159 <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_NsOpenSSLDebug">NsOpenSSLDebug</a>(char *fmt, ...)
160 {
161 va_list ap;
162 Ns_LogSeverity severity = "Debug";
163 char buf[1000];
164
165 //va_start(ap, fmt);
166 sprintf(&buf, fmt, ap);
167 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(severity, &buf);
168 //va_end(ap);
169
170 }
171 #endif
172
173
174
175 /*
176 *----------------------------------------------------------------------
177 *
178 * <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_InitServerState">InitServerState</a> --
179 *
180 * Initialize a virtual server's state storage. This holds pointers to SSL
181 * contexts stored by name, as well as default client and server SSL
182 * contexts to use in cases where the programmer didn't explicitly name one
183 * to use.
184 *
185 * Results:
186 *
187 * Side effects:
188 *
189 *----------------------------------------------------------------------
190 */
191
192 static void
193 <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_InitServerState">InitServerState</a>(char *server)
194 {
195 Server *thisServer = NULL;
196 Tcl_HashEntry *hPtr = NULL;
197 int new = 0;
198 Ns_DString ds;
199 char *lockName = NULL;
200
201 <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringInit">Ns_DStringInit</a>(&ds);
202 thisServer = ns_malloc(sizeof(Server));
203 if (thisServer == NULL) {
204 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Fatal, "%s (%s): memory allocation failed");
205 }
206 thisServer->server = server;
207 thisServer->defaultservercontext = NULL;
208 thisServer->defaultclientcontext = NULL;
209 thisServer->nextSessionCacheId = 1;
210 Ns_MutexInit(&thisServer->lock);
211 <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringPrintf">Ns_DStringPrintf</a>(&ds, "server:%s", server);
212 lockName = <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringExport">Ns_DStringExport</a>(&ds);
213 Ns_MutexSetName2(&thisServer->lock, MODULE_SHORT, lockName);
214 <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringTrunc">Ns_DStringTrunc</a>(&ds, 0);
215 ns_free(lockName);
216 lockName = NULL;
217 hPtr = Tcl_CreateHashEntry(&NsOpenSSLServers, server, &new);
218 Tcl_SetHashValue(hPtr, thisServer);
219 Tcl_InitHashTable(&thisServer->sslcontexts, TCL_STRING_KEYS);
220 Tcl_InitHashTable(&thisServer->ssldrivers, TCL_STRING_KEYS);
221
222 return;
223 }
224
225
226 /*
227 *----------------------------------------------------------------------
228 *
229 * <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_LoadSSLContexts">LoadSSLContexts</a> --
230 *
231 * Load the SSL context for a virtual server.
232 *
233 * Results:
234 * NS_OK or NS_ERROR
235 *
236 * Side effects:
237 * Registers driver with AOLserver core.
238 *
239 *----------------------------------------------------------------------
240 */
241
242 static void
243 <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_LoadSSLContexts">LoadSSLContexts</a>(char *server)
244 {
245 Server *thisServer = <a href="/cvs/aolserver/nsopenssl/sslcontext.c#A_NsOpenSSLServerGet">NsOpenSSLServerGet</a>(server);
246 NsOpenSSLContext *sslcontext = NULL;
247 Ns_Set *sslcontexts = NULL;
248 Ns_Set *defaults = NULL;
249 char *path = NULL;
250 char *name = NULL;
251 char *value = NULL;
252 int i = 0;
253
254 path = <a href="/cvs/aolserver/aolserver/nsd/config.c#A_Ns_ConfigGetPath">Ns_ConfigGetPath</a>(server, MODULE, "sslcontexts", NULL);
255 sslcontexts = <a href="/cvs/aolserver/aolserver/nsd/config.c#A_Ns_ConfigGetSection">Ns_ConfigGetSection</a>(path);
256
257 /*
258 * If no SSL contexts are defined for this virtual server, we won't start
259 * any drivers for it, and we won't be able to use SSL at all. I'll soon be
260 * adding the capability to build SSL contexts with the Tcl API dynamically
261 * so it will make sense to do this at some point in the future if you want
262 * to manage SSL conns but not through the AOLserver comm API.
263 */
264
265 if (sslcontexts == NULL) {
266 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Notice, "%s (%s): no SSL contexts defined for this server",
267 server, MODULE);
268 return;
269 }
270 for (i = 0; i < Ns_SetSize(sslcontexts); ++i) {
271 name = Ns_SetKey(sslcontexts, i);
272 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Notice, "%s (%s): loading SSL context '%s'", MODULE, server, name);
273 sslcontext = <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_LoadSSLContext">LoadSSLContext</a>(server, name);
274 <a href="/cvs/aolserver/nsopenssl/sslcontext.c#A_NsOpenSSLContextAdd">NsOpenSSLContextAdd</a>(server, sslcontext);
275 if (<a href="/cvs/aolserver/nsopenssl/sslcontext.c#A_NsOpenSSLContextInit">NsOpenSSLContextInit</a>(server, sslcontext) == NS_ERROR) {
276 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Error, "%s (%s): SSL context '%s' left uninitialized",
277 MODULE, server, name);
278 }
279 }
280
281 /*
282 * Set default server SSL client and server contexts. These are used in
283 * cases where the C or Tcl programmer does not specify what named SSL
284 * context to use.
285 */
286
287 path = <a href="/cvs/aolserver/aolserver/nsd/config.c#A_Ns_ConfigGetPath">Ns_ConfigGetPath</a>(server, MODULE, "defaults", NULL);
288 defaults = <a href="/cvs/aolserver/aolserver/nsd/config.c#A_Ns_ConfigGetSection">Ns_ConfigGetSection</a>(path);
289 if (defaults == NULL) {
290 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Notice, "%s (%s): no default SSL contexts defined for this server",
291 MODULE, server);
292 return;
293 }
294 for (i = 0; i < Ns_SetSize(defaults); ++i) {
295 name = Ns_SetKey(defaults, i);
296 value = <a href="/cvs/aolserver/aolserver/nsd/config.c#A_Ns_ConfigGetValue">Ns_ConfigGetValue</a>(path, name);
297 sslcontext = <a href="/cvs/aolserver/nsopenssl/sslcontext.c#A_Ns_OpenSSLServerSSLContextGet">Ns_OpenSSLServerSSLContextGet</a>(server, value);
298 if (sslcontext != NULL) {
299 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Notice, "%s (%s): default SSL context for %s is %s", MODULE, server, name, value);
300 if (STRIEQ(name, "server")) {
301 thisServer->defaultservercontext = value;
302 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Notice, "default server SSL context: %s", thisServer->defaultservercontext);
303 } else if (STRIEQ(name, "client")) {
304 thisServer->defaultclientcontext = value;
305 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Notice, "default client SSL context: %s", thisServer->defaultclientcontext);
306 } else {
307 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Error, "%s (%s): bad parameter '%s' for default contexts",
308 MODULE, server, name);
309 }
310 } else {
311 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Error, "%s (%s): SSL context '%s' doesn't exist; can't use it as a default",
312 MODULE, server, value);
313 }
314 }
315 }
316
317
318 /*
319 *----------------------------------------------------------------------
320 *
321 * <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_LoadSSLContext">LoadSSLContext</a> --
322 *
323 * Load values for a given SSL context from the configuration file.
324 *
325 * Results:
326 * Pointer to SSL Context or NULL
327 *
328 * Side effects:
329 * Memory may be allocated
330 *
331 *----------------------------------------------------------------------
332 */
333
334 static NsOpenSSLContext *
335 <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_LoadSSLContext">LoadSSLContext</a>(char *server, char *name)
336 {
337 NsOpenSSLContext *sslcontext = NULL;
338 char *role = NULL;
339 char *path = NULL;
340 char *moduleDir = NULL;
341 char *certFile = NULL;
342 char *keyFile = NULL;
343 char *caFile = NULL;
344 char *caDir = NULL;
345 char *protocols = NULL;
346 char *cipherSuite = NULL;
347 int sessionCache = DEFAULT_SESSION_CACHE;
348 int sessionCacheSize = DEFAULT_SESSION_CACHE_SIZE;
349 int sessionCacheTimeout = DEFAULT_SESSION_CACHE_TIMEOUT;
350 int peerVerify = DEFAULT_PEER_VERIFY;
351 int peerVerifyDepth = DEFAULT_PEER_VERIFY_DEPTH;
352 int trace = DEFAULT_TRACE;
353
354 path = <a href="/cvs/aolserver/aolserver/nsd/config.c#A_Ns_ConfigGetPath">Ns_ConfigGetPath</a>(server, MODULE, "sslcontext", name, NULL);
355 if (path == NULL) {
356 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Error, "%s (%s): failed to find SSL context '%s' in configuration file",
357 MODULE, server, name);
358 return NULL;
359 }
360 sslcontext = <a href="/cvs/aolserver/nsopenssl/sslcontext.c#A_NsOpenSSLContextCreate">NsOpenSSLContextCreate</a>(server, name);
361
362 /*
363 * Must be "client" or "server"
364 */
365
366 role = <a href="/cvs/aolserver/aolserver/nsd/config.c#A_Ns_ConfigGetValue">Ns_ConfigGetValue</a>(path, "role");
367 if (role != NULL) {
368 <a href="/cvs/aolserver/nsopenssl/sslcontext.c#A_NsOpenSSLContextRoleSet">NsOpenSSLContextRoleSet</a>(server, sslcontext, role);
369 }
370
371 /*
372 * A default module directory is automatically set when the SSL context was
373 * created, but you can override in the config file.
374 */
375
376 moduleDir = <a href="/cvs/aolserver/aolserver/nsd/config.c#A_Ns_ConfigGetValue">Ns_ConfigGetValue</a>(path, "moduledir");
377 if (moduleDir != NULL) {
378 <a href="/cvs/aolserver/nsopenssl/sslcontext.c#A_NsOpenSSLContextModuleDirSet">NsOpenSSLContextModuleDirSet</a>(server, sslcontext, moduleDir);
379 }
380
381 /*
382 * SSL clients don't require certificates, but SSL servers do. If certfile
383 * or keyfile are NULL, are not found, or are not accessible, we'll fail
384 * later when we try to instantiate the SSL context.
385 */
386
387 certFile = <a href="/cvs/aolserver/aolserver/nsd/config.c#A_Ns_ConfigGetValue">Ns_ConfigGetValue</a>(path, "certfile");
388 if (certFile != NULL) {
389 <a href="/cvs/aolserver/nsopenssl/sslcontext.c#A_NsOpenSSLContextCertFileSet">NsOpenSSLContextCertFileSet</a>(server, sslcontext, certFile);
390 }
391 keyFile = <a href="/cvs/aolserver/aolserver/nsd/config.c#A_Ns_ConfigGetValue">Ns_ConfigGetValue</a>(path, "keyfile");
392 if (keyFile != NULL) {
393 <a href="/cvs/aolserver/nsopenssl/sslcontext.c#A_NsOpenSSLContextKeyFileSet">NsOpenSSLContextKeyFileSet</a>(server, sslcontext, keyFile);
394 }
395
396 /*
397 * The default protocols and ciphersuites are good for general use.
398 */
399
400 protocols = <a href="/cvs/aolserver/aolserver/nsd/config.c#A_Ns_ConfigGetValue">Ns_ConfigGetValue</a>(path, "protocols");
401 if (protocols != NULL) {
402 <a href="/cvs/aolserver/nsopenssl/sslcontext.c#A_NsOpenSSLContextProtocolsSet">NsOpenSSLContextProtocolsSet</a>(server, sslcontext, protocols);
403 }
404 cipherSuite = <a href="/cvs/aolserver/aolserver/nsd/config.c#A_Ns_ConfigGetValue">Ns_ConfigGetValue</a>(path, "ciphersuite");
405 if (cipherSuite != NULL) {
406 <a href="/cvs/aolserver/nsopenssl/sslcontext.c#A_NsOpenSSLContextCipherSuiteSet">NsOpenSSLContextCipherSuiteSet</a>(server, sslcontext, cipherSuite);
407 }
408
409 /*
410 * The CA file/dir isn't necessary unless you actually do cert
411 * verification. The CA file is simply a bunch of PEM-format CA
412 * certificates concatenated together.
413 */
414
415 caFile = <a href="/cvs/aolserver/aolserver/nsd/config.c#A_Ns_ConfigGetValue">Ns_ConfigGetValue</a>(path, "cafile");
416 if (caFile != NULL) {
417 <a href="/cvs/aolserver/nsopenssl/sslcontext.c#A_NsOpenSSLContextCAFileSet">NsOpenSSLContextCAFileSet</a>(server, sslcontext, caFile);
418 }
419 caDir = <a href="/cvs/aolserver/aolserver/nsd/config.c#A_Ns_ConfigGetValue">Ns_ConfigGetValue</a>(path, "cadir");
420 if (caDir != NULL) {
421 <a href="/cvs/aolserver/nsopenssl/sslcontext.c#A_NsOpenSSLContextCADirSet">NsOpenSSLContextCADirSet</a>(server, sslcontext, caDir);
422 }
423
424 /*
425 * Peer verification will cause the server to request a client certificate.
426 * If you aren't sure whether to turn it on or not, leave it off!
427 */
428
429 if (<a href="/cvs/aolserver/aolserver/nsd/config.c#A_Ns_ConfigGetBool">Ns_ConfigGetBool</a>(path, "peerverify", &peerVerify) == NS_TRUE) {
430 <a href="/cvs/aolserver/nsopenssl/sslcontext.c#A_NsOpenSSLContextPeerVerifySet">NsOpenSSLContextPeerVerifySet</a>(server, sslcontext, peerVerify);
431 }
432
433 /*
434 * A certificate may be at the bottom of a chain. Verify depth determines
435 * how many levels down from the root cert you're willing to trust..
436 */
437
438 if (<a href="/cvs/aolserver/aolserver/nsd/config.c#A_Ns_ConfigGetInt">Ns_ConfigGetInt</a>(path, "peerverifydepth", &peerVerifyDepth) == NS_TRUE) {
439 <a href="/cvs/aolserver/nsopenssl/sslcontext.c#A_NsOpenSSLContextPeerVerifyDepthSet">NsOpenSSLContextPeerVerifyDepthSet</a>(server, sslcontext, peerVerifyDepth);
440 }
441
442 /*
443 * Session caching defaults to on, and should always be on if you
444 * have web browsers connecting. Some versions of MSIE and Netscape will
445 * fail if you don't have session caching on.
446 */
447
448 <a href="/cvs/aolserver/aolserver/nsd/config.c#A_Ns_ConfigGetBool">Ns_ConfigGetBool</a>(path, "sessioncache", &sessionCache);
449 if (sessionCache == NS_TRUE) {
450 <a href="/cvs/aolserver/nsopenssl/sslcontext.c#A_NsOpenSSLContextSessionCacheSet">NsOpenSSLContextSessionCacheSet</a>(server, sslcontext, sessionCache);
451 }
452 if (<a href="/cvs/aolserver/aolserver/nsd/config.c#A_Ns_ConfigGetInt">Ns_ConfigGetInt</a>(path, "sessioncachesize", &sessionCacheSize) == NS_TRUE) {
453 <a href="/cvs/aolserver/nsopenssl/sslcontext.c#A_NsOpenSSLContextSessionCacheSizeSet">NsOpenSSLContextSessionCacheSizeSet</a>(server, sslcontext, sessionCacheSize);
454 }
455 if (<a href="/cvs/aolserver/aolserver/nsd/config.c#A_Ns_ConfigGetInt">Ns_ConfigGetInt</a>(path, "sessioncachetimeout", &sessionCacheTimeout) == NS_TRUE) {
456 <a href="/cvs/aolserver/nsopenssl/sslcontext.c#A_NsOpenSSLContextSessionCacheTimeoutSet">NsOpenSSLContextSessionCacheTimeoutSet</a>(server, sslcontext, sessionCacheTimeout);
457 }
458
459 /*
460 * Trace SSL handshake.
461 */
462
463 <a href="/cvs/aolserver/aolserver/nsd/config.c#A_Ns_ConfigGetBool">Ns_ConfigGetBool</a>(path, "trace", &trace);
464 if (trace == NS_TRUE) {
465 <a href="/cvs/aolserver/nsopenssl/sslcontext.c#A_NsOpenSSLContextTraceSet">NsOpenSSLContextTraceSet</a>(server, sslcontext, 1);
466 } else {
467 <a href="/cvs/aolserver/nsopenssl/sslcontext.c#A_NsOpenSSLContextTraceSet">NsOpenSSLContextTraceSet</a>(server, sslcontext, 0);
468 }
469
470 return sslcontext;
471 }
472
473
474 /*
475 *----------------------------------------------------------------------
476 *
477 * <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_ServerShutdown">ServerShutdown</a> --
478 *
479 * Cleanup function to run at server shutdown.
480 *
481 * Results:
482 * None.
483 *
484 * Side effects:
485 * None.
486 *
487 *----------------------------------------------------------------------
488 */
489
490 static void
491 <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_ServerShutdown">ServerShutdown</a>(void *arg)
492 {
493 char *server = (char *) arg;
494
495 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Notice, "Shutdown called for server %s", server);
496
497 /*
498 * for each vserver.driver
499 * for each vserver.driver.conn
500 * close, free
501 * endfor
502 * free vserver.driver
503 * endfor
504 * free vserver
505 */
506
507 return;
508 }
509
510
511 /*
512 *----------------------------------------------------------------------
513 *
514 * <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_InitOpenSSL">InitOpenSSL</a> --
515 *
516 * Initialize the OpenSSL library.
517 *
518 * Results:
519 * NS_OK
520 *
521 * Side effects:
522 * Sets OpenSSL threading callbacks, seeds the pseudo random number
523 * generator, initializes SSL session caching id generation.
524 *
525 *----------------------------------------------------------------------
526 */
527
528 static int
529 <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_InitOpenSSL">InitOpenSSL</a>(void)
530 {
531 int i = 0;
532 int seedcnt = 0;
533 size_t num_locks = 0;
534 char *lockName = NULL;
535 Ns_DString ds;
536
537 <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringInit">Ns_DStringInit</a>(&ds);
538
539 /*
540 * Initialize OpenSSL callbacks
541 */
542
543 if (CRYPTO_set_mem_functions(ns_malloc, ns_realloc, ns_free) == 0)
544 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Warning, "%s: OpenSSL memory callbacks failed in <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_InitOpenSSL">InitOpenSSL</a>",
545 MODULE);
546 num_locks = CRYPTO_num_locks();
547 locks = ns_calloc(num_locks, sizeof(*locks));
548 for (i = 0; i < num_locks; i++) {
549 <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringPrintf">Ns_DStringPrintf</a>(&ds, "crypto:%d", i);
550 lockName = <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringExport">Ns_DStringExport</a>(&ds);
551 Ns_MutexSetName2(locks + i, MODULE_SHORT, lockName);
552 <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringTrunc">Ns_DStringTrunc</a>(&ds, 0);
553 ns_free(lockName);
554 lockName = NULL;
555 }
556 <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringFree">Ns_DStringFree</a>(&ds);
557 CRYPTO_set_locking_callback(<a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_ThreadLockCallback">ThreadLockCallback</a>);
558 CRYPTO_set_id_callback(<a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_ThreadIdCallback">ThreadIdCallback</a>);
559
560 /*
561 * Initialize the OpenSSL library itself
562 */
563
564 SSL_load_error_strings();
565 OpenSSL_add_ssl_algorithms();
566 SSL_library_init();
567 X509V3_add_standard_extensions();
568
569 /*
570 * Seed the OpenSSL Pseudo-Random Number Generator.
571 */
572
573 while (! RAND_status() && seedcnt < 3) {
574 seedcnt++;
575 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Notice, "%s: Seeding OpenSSL's PRNG", MODULE);
576 <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_SeedPRNG">SeedPRNG</a>();
577 }
578 if (! RAND_status()) {
579 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Warning, "%s: PRNG fails to have enough entropy after %d tries",
580 MODULE, seedcnt);
581 }
582
583 return NS_OK;
584 }
585
586
587 /*
588 *----------------------------------------------------------------------
589 *
590 * <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_SeedPRNG">SeedPRNG</a> --
591 *
592 * Seed OpenSSL's PRNG. OpenSSL will seed the PRNG transparently if
593 * /dev/urandom is available.
594 *
595 * Results:
596 * NS_TRUE or NS_FALSE.
597 *
598 * Side effects:
599 * An NS_FALSE will result in the connection failing. This function
600 * might be called at any time by the temporary key generating
601 * function if the PRNG is not sufficiently entropinous (yes, I
602 * made that word up).
603 *
604 *
605 *----------------------------------------------------------------------
606 */
607
608 static int
609 <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_SeedPRNG">SeedPRNG</a>(void)
610 {
611 double *buf_ptr = NULL;
612 double *bufoffset_ptr = NULL;
613 char *path = NULL;
614 char *randomFile = NULL;
615 size_t size = 0;
616 int i = 0;
617 int seedBytes = 0;
618 int readBytes = 0;
619 int maxBytes = 0;
620
621 if (RAND_status()) {
622 return NS_TRUE;
623 }
624 path = <a href="/cvs/aolserver/aolserver/nsd/config.c#A_Ns_ConfigGetPath">Ns_ConfigGetPath</a>(NULL, MODULE, NULL);
625 if (<a href="/cvs/aolserver/aolserver/nsd/config.c#A_Ns_ConfigGetInt">Ns_ConfigGetInt</a>(path, "seedbytes", &seedBytes) == NS_FALSE) {
626 seedBytes = DEFAULT_SEEDBYTES;
627 }
628 if (<a href="/cvs/aolserver/aolserver/nsd/config.c#A_Ns_ConfigGetInt">Ns_ConfigGetInt</a>(path, "maxbytes", &maxBytes) == NS_FALSE) {
629 maxBytes = DEFAULT_MAXBYTES;
630 }
631
632 /*
633 * Try to use the file specified by the user. If PRNG fails to seed here,
634 * you might try increasing the seedBytes parameter in nsd.tcl.
635 */
636
637 randomFile = <a href="/cvs/aolserver/aolserver/nsd/config.c#A_Ns_ConfigGetValue">Ns_ConfigGetValue</a>(path, "randomfile");
638 if (randomFile != NULL && access(randomFile, F_OK) == 0) {
639 if ((readBytes = RAND_load_file(randomFile, maxBytes))) {
640 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Notice, "%s: Obtained %d random bytes from %s",
641 MODULE, readBytes, randomFile);
642 } else {
643 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Warning, "%s: Unable to retrieve any random data from %s",
644 MODULE, randomFile);
645 }
646 } else {
647 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Warning, "%s: No randomFile set and/or found", MODULE);
648 }
649 if (RAND_status()) {
650 return NS_TRUE;
651 }
652
653 /*
654 * Use <a href="/cvs/aolserver/aolserver/nsd/random.c#A_Ns_DRand">Ns_DRand</a>(), passing it seedBytes as the second argument to RAND_add.
655 */
656
657 size = sizeof(double) * seedBytes;
658 buf_ptr = Ns_Malloc(size);
659 bufoffset_ptr = buf_ptr;
660 for (i = 0; i < seedBytes; i++) {
661 *bufoffset_ptr = <a href="/cvs/aolserver/aolserver/nsd/random.c#A_Ns_DRand">Ns_DRand</a>();
662 bufoffset_ptr++;
663 }
664 RAND_add(buf_ptr, seedBytes, (double) seedBytes);
665 ns_free(buf_ptr);
666 if (!RAND_status()) {
667 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Warning, "%s: failed to seed PRNG", MODULE);
668 return NS_FALSE;
669 }
670
671 return NS_TRUE;
672 }
673
674
675 /*
676 *----------------------------------------------------------------------
677 *
678 * <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_ThreadLockCallback">ThreadLockCallback</a> --
679 *
680 * Lock or unlock a mutex for OpenSSL.
681 *
682 * Results:
683 * None.
684 *
685 * Side effects:
686 * None.
687 *
688 *----------------------------------------------------------------------
689 */
690
691 static void
692 <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_ThreadLockCallback">ThreadLockCallback</a>(int mode, int n, const char *file, int line)
693 {
694 if (mode & CRYPTO_LOCK) {
695 Ns_MutexLock(locks + n);
696 } else {
697 Ns_MutexUnlock(locks + n);
698 }
699 }
700
701
702 /*
703 *----------------------------------------------------------------------
704 *
705 * <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_ThreadIdCallback">ThreadIdCallback</a> --
706 *
707 * Return this thread's id for OpenSSL.
708 *
709 * Results:
710 * None.
711 *
712 * Side effects:
713 * None.
714 *
715 *----------------------------------------------------------------------
716 */
717
718 static unsigned long
719 <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_ThreadIdCallback">ThreadIdCallback</a>(void)
720 {
721 return (unsigned long) Ns_ThreadId();
722 }
723
724
725 /*
726 *----------------------------------------------------------------------
727 *
728 * <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_ThreadDynlockCreateCallback">ThreadDynlockCreateCallback</a> --
729 *
730 * Create a dynamically-allocated mutex for OpenSSL.
731 *
732 * Results:
733 * None.
734 *
735 * Side effects:
736 * None.
737 *
738 *----------------------------------------------------------------------
739 */
740
741 static struct CRYPTO_dynlock_value *
742 <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_ThreadDynlockCreateCallback">ThreadDynlockCreateCallback</a>(char *file, int line)
743 {
744 Ns_Mutex *lock = NULL;
745 Ns_DString ds;
746
747 <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringInit">Ns_DStringInit</a>(&ds);
748 lock = ns_calloc(1, sizeof(*lock));
749 <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringVarAppend">Ns_DStringVarAppend</a>(&ds, "openssl: ", file, ": ");
750 <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringPrintf">Ns_DStringPrintf</a>(&ds, "%d", line);
751 Ns_MutexSetName2(lock, MODULE, <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringValue">Ns_DStringValue</a>(&ds));
752
753 return (struct CRYPTO_dynlock_value *) lock;
754 }
755
756
757 /*
758 *----------------------------------------------------------------------
759 *
760 * <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_ThreadDynlockLockCallback">ThreadDynlockLockCallback</a> --
761 *
762 * Lock or unlock a dynamically-allocated mutex for OpenSSL.
763 *
764 * Results:
765 * None.
766 *
767 * Side effects:
768 * None.
769 *
770 *----------------------------------------------------------------------
771 */
772
773 static void
774 <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_ThreadDynlockLockCallback">ThreadDynlockLockCallback</a>(int mode, struct CRYPTO_dynlock_value *dynlock,
775 const char *file, int line)
776 {
777 if (mode & CRYPTO_LOCK) {
778 Ns_MutexLock((Ns_Mutex *) dynlock);
779 } else {
780 Ns_MutexUnlock((Ns_Mutex *) dynlock);
781 }
782 }
783
784
785 /*
786 *----------------------------------------------------------------------
787 *
788 * <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_ThreadDynlockDestroyCallback">ThreadDynlockDestroyCallback</a> --
789 *
790 * Destroy a dynamically-allocated mutex for OpenSSL.
791 *
792 * Results:
793 * None.
794 *
795 * Side effects:
796 * None.
797 *
798 *----------------------------------------------------------------------
799 */
800
801 static void
802 <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_ThreadDynlockDestroyCallback">ThreadDynlockDestroyCallback</a>(struct CRYPTO_dynlock_value *dynlock,
803 const char *file, int line)
804 {
805 Ns_MutexDestroy((Ns_Mutex *) dynlock);
806 }
807
808
809 /*
810 *----------------------------------------------------------------------
811 *
812 * <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_LoadSSLDrivers">LoadSSLDrivers</a> --
813 *
814 * Load the SSL drivers for a virtual server.
815 *
816 * Results:
817 * NS_OK or NS_ERROR
818 *
819 * Side effects:
820 * Registers driver with AOLserver core.
821 *
822 *----------------------------------------------------------------------
823 */
824
825 static void
826 <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_LoadSSLDrivers">LoadSSLDrivers</a>(char *server)
827 {
828 NsOpenSSLContext *sslcontext = NULL;
829 NsOpenSSLDriver *ssldriver = NULL;
830 Ns_Set *ssldrivers = NULL;
831 char *path = NULL;
832 char *name = NULL;
833 char *sslcontextname = NULL;
834 int i = 0;
835
836 path = <a href="/cvs/aolserver/aolserver/nsd/config.c#A_Ns_ConfigGetPath">Ns_ConfigGetPath</a>(server, MODULE, "ssldrivers", NULL);
837 ssldrivers = <a href="/cvs/aolserver/aolserver/nsd/config.c#A_Ns_ConfigGetSection">Ns_ConfigGetSection</a>(path);
838 if (ssldrivers == NULL) {
839 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Notice, "%s (%s): no SSL drivers defined for this server",
840 MODULE, server);
841 return;
842 }
843 for (i = 0; i < Ns_SetSize(ssldrivers); ++i) {
844 name = Ns_SetKey(ssldrivers, i);
845 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Notice, "%s (%s): loading '%s' SSL driver", MODULE, server, name);
846 path = <a href="/cvs/aolserver/aolserver/nsd/config.c#A_Ns_ConfigGetPath">Ns_ConfigGetPath</a>(server, MODULE, "ssldriver", name, NULL);
847 if (path == NULL) {
848 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Error, "%s (%s): SSL driver '%s' not defined in configuration file",
849 MODULE, server, name);
850 continue;
851 }
852 sslcontextname = <a href="/cvs/aolserver/aolserver/nsd/config.c#A_Ns_ConfigGetValue">Ns_ConfigGetValue</a>(path, "sslcontext");
853 if (sslcontextname == NULL) {
854 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Error, "%s (%s): 'sslcontext' parameter not defined for driver '%s'",
855 MODULE, server, name);
856 continue;
857 }
858 sslcontext = <a href="/cvs/aolserver/nsopenssl/sslcontext.c#A_Ns_OpenSSLServerSSLContextGet">Ns_OpenSSLServerSSLContextGet</a>(server, sslcontextname);
859 if (sslcontext == NULL) {
860 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Error, "%s (%s): SSL context '%s' needed by driver '%s' not found",
861 MODULE, server, sslcontextname, name);
862 continue;
863 }
864
865 /*
866 * Create the driver.
867 */
868
869 ssldriver = ns_calloc(1, sizeof(NsOpenSSLDriver));
870 ssldriver->server = server;
871 ssldriver->sslcontext = sslcontext;
872 ssldriver->name = name;
873 ssldriver->path = path;
874 ssldriver->refcnt = 0;
875 if (!<a href="/cvs/aolserver/aolserver/nsd/config.c#A_Ns_ConfigGetInt">Ns_ConfigGetInt</a>(path, "port", &ssldriver->port)) {
876 ssldriver->port = 443;
877 }
878
879 /*
880 * Crank up the driver
881 */
882
883 if (<a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_InitSSLDriver">InitSSLDriver</a>(server, ssldriver) != NS_OK) {
884
885 }
886 }
887 }
888
889
890 /*
891 *----------------------------------------------------------------------
892 *
893 * <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_InitSSLDriver">InitSSLDriver</a> --
894 *
895 * Initialize an SSL driver.
896 *
897 * Results:
898 * NS_OK or NS_ERROR
899 *
900 * Side effects:
901 * Registers driver with AOLserver core.
902 *
903 *----------------------------------------------------------------------
904 */
905
906 static int
907 <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_InitSSLDriver">InitSSLDriver</a>(char *server, NsOpenSSLDriver *ssldriver)
908 {
909 Ns_DriverInitData init;
910 Server *thisServer = NULL;
911 Tcl_HashEntry *hPtr = NULL;
912 int new = 0;
913
914 /*
915 * Register the driver with AOLserver.
916 */
917
918 init.version = NS_DRIVER_VERSION_1;
919 init.name = MODULE;
920 init.proc = <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_OpenSSLProc">OpenSSLProc</a>;
921 init.opts = NS_DRIVER_SSL;
922 init.arg = ssldriver;
923 init.path = ssldriver->path;
924
925 if (<a href="/cvs/aolserver/aolserver/nsd/driver.c#A_Ns_DriverInit">Ns_DriverInit</a>(server, MODULE, &init) != NS_ERROR) {
926 return NS_ERROR;
927 }
928
929 /*
930 * Add the driver to the virtual server's state info.
931 */
932
933 thisServer = <a href="/cvs/aolserver/nsopenssl/sslcontext.c#A_NsOpenSSLServerGet">NsOpenSSLServerGet</a>(server);
934 Ns_MutexLock(&thisServer->lock);
935 hPtr = Tcl_CreateHashEntry(&thisServer->ssldrivers, ssldriver->name, &new);
936 if (new) {
937 Tcl_SetHashValue(hPtr, ssldriver);
938 } else {
939 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Error, "%s (%s): duplicate SSL driver name: %s",
940 MODULE, server, ssldriver->name);
941 return NS_ERROR;
942 }
943 Ns_MutexUnlock(&thisServer->lock);
944
945 return NS_OK;
946 }
947
948
949 /*
950 *----------------------------------------------------------------------
951 *
952 * <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_DestroySSLDriver">DestroySSLDriver</a> --
953 *
954 * Destroy an SSL driver.
955 *
956 * Results:
957 * None.
958 *
959 * Side effects:
960 * None.
961 *
962 *----------------------------------------------------------------------
963 */
964
965 #if 0
966 static void
967 <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_DestroySSLDriver">DestroySSLDriver</a>(NsOpenSSLDriver *ssldriver)
968 {
969 NsOpenSSLConn *sslconn;
970
971 if (ssldriver == NULL) {
972 return;
973 }
974
975 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Notice, "%s (%s): shutting down driver '%s'", MODULE,
976 ssldriver->server, ssldriver->name);
977
978 /*
979 * Destroy connections that are still tied to this driver. We need to lock
980 * the driver struct, set a flag that denotes it as no longer usable so new
981 * conns that come in before we've free'd it will be refused.
982 */
983
984 /* XXX lock */
985 if (ssldriver->refcnt > 0) {
986 while ((sslconn = ssldriver->firstFreeConn) != NULL) {
987 ssldriver->firstFreeConn = sslconn->next;
988 /* XXX doesn't this need to have it's contents free'd? */
989 ns_free(sslconn);
990 }
991 }
992
993 Ns_MutexDestroy(&ssldriver->lock);
994
995 /* XXX should an SSL context be deallocated when it's refcnt reaches 0 ??? */
996 if (ssldriver->sslcontext != NULL)
997 ssldriver->sslcontext->refcnt--;
998
999 ns_free(ssldriver);
1000
1001 /*
1002 * Remove driver from server state linked list.
1003 */
1004
1005 return;
1006 }
1007 #endif
1008
1009
1010 /*
1011 *----------------------------------------------------------------------
1012 *
1013 * <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_OpenSSLProc">OpenSSLProc</a> --
1014 *
1015 * SSL driver callback proc. This driver performs the necessary
1016 * handshake and encryption of SSL.
1017 *
1018 * Results:
1019 * For close, always 0. For keep, 0 if connection could be
1020 * properly flushed, -1 otherwise. For send and recv, # of bytes
1021 * processed or -1 on error.
1022 *
1023 * Side effects:
1024 * None.
1025 *
1026 *----------------------------------------------------------------------
1027 */
1028
1029 static int
1030 <a href="/cvs/aolserver/nsopenssl/nsopenssl.c#A_OpenSSLProc">OpenSSLProc</a>(Ns_DriverCmd cmd, Ns_Sock *sock, struct iovec *bufs, int nbufs)
1031 {
1032 NsOpenSSLDriver *driver = (NsOpenSSLDriver *) sock->driver->arg;
1033 NsOpenSSLConn *conn = (NsOpenSSLConn *) sock->arg;
1034 int n = -1, total, op;
1035
1036 switch (cmd) {
1037 case DriverRecv:
1038 case DriverSend:
1039 if (conn == NULL) {
1040 /*
1041 * If first connection, wrap SSL around the socket.
1042 */
1043
1044 conn = NsOpenSSLConnCreate(sock->sock, driver->sslcontext);
1045 conn->refcnt++;
1046 conn->peerport = driver->port;
1047 conn->recvwait = sock->driver->recvwait;
1048 conn->sendwait = sock->driver->sendwait;
1049 sock->arg = (void *) conn;
1050 }
1051
1052 /*
1053 * Process each buffer one at a time.
1054 */
1055
1056 op = (cmd == DriverSend) ? NSOPENSSL_SEND : NSOPENSSL_RECV;
1057 total = 0;
1058 do {
1059 n = NsOpenSSLConnOp(conn->ssl, bufs->iov_base,
1060 (int) bufs->iov_len, op);
1061 if (n > 0) {
1062 total += n;
1063 }
1064 ++bufs;
1065 } while (n > 0 && --nbufs > 0);
1066 if (n > 0) {
1067 n = total;
1068 }
1069 break;
1070
1071 case DriverKeep:
1072 if (conn != NULL && NsOpenSSLConnFlush(conn) == NS_OK) {
1073 n = 0;
1074 } else {
1075 n = -1;
1076 }
1077 break;
1078
1079 case DriverClose:
1080 if (conn != NULL) {
1081 (void) NsOpenSSLConnFlush(conn);
1082 NsOpenSSLConnDestroy(conn);
1083 sock->arg = NULL;
1084 }
1085 n = 0;
1086 break;
1087
1088 default:
1089 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Error, "%s (%s): Unsupported driver command '%d'",
1090 MODULE, driver->server, cmd);
1091 n = -1;
1092 break;
1093 }
1094 return n;
1095 }
1096