]> sourceware.org Git - systemtap.git/blame - stap-server-connect.c
Version bumps for 0.9.6 release
[systemtap.git] / stap-server-connect.c
CommitLineData
1cecb3c5
DB
1/*
2 SSL server program listens on a port, accepts client connection, reads
3 the data into a temporary file, calls the systemtap server script and
4 then transmits the resulting fileback to the client.
5
64aa100f 6 Copyright (C) 2008, 2009 Red Hat Inc.
1cecb3c5
DB
7
8 This file is part of systemtap, and is free software. You can
9 redistribute it and/or modify it under the terms of the GNU General Public
10 License as published by the Free Software Foundation; either version 2 of the
11 License, or (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21*/
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <errno.h>
27
28#include <ssl.h>
29#include <nspr.h>
30#include <plgetopt.h>
31#include <nss.h>
32#include <pk11func.h>
33
34#define READ_BUFFER_SIZE (60 * 1024)
35
36/* Global variables */
37static char *password = NULL;
38static CERTCertificate *cert = NULL;
39static SECKEYPrivateKey *privKey = NULL;
40static char *dbdir = NULL;
41static char requestFileName[] = "/tmp/stap.server.client.zip.XXXXXX";
42static char responseDirName[] = "/tmp/stap.server.XXXXXX";
89dd03e3 43static char responseZipName[] = "/tmp/stap.server.XXXXXX.zip.XXXXXX";
1cecb3c5
DB
44
45static void
46Usage(const char *progName)
47{
48 fprintf(stderr,
49 "Usage: %s -p port -d dbdir -n rsa_nickname -w passwordFile\n",
50 progName);
51 exit(1);
52}
53
54static void
55errWarn(char *function)
56{
57 PRErrorCode errorNumber = PR_GetError();
58
59 printf("Error in function %s: %d\n\n", function, errorNumber);
60}
61
62static void
63exitErr(char *function)
64{
65 errWarn(function);
66 /* Exit gracefully. */
67 /* ignoring return value of NSS_Shutdown as code exits with 1*/
68 (void) NSS_Shutdown();
69 PR_Cleanup();
70 exit(1);
71}
72
73/* Function: readDataFromSocket()
74 *
75 * Purpose: Read data from the socket into a temporary file.
76 *
77 */
78static SECStatus
79readDataFromSocket(PRFileDesc *sslSocket)
80{
81 PRFileDesc *local_file_fd;
82 PRFileInfo info;
83 PRInt32 numBytesRead;
84 PRInt32 numBytesWritten;
85 PRInt32 totalBytes;
86 char buffer[READ_BUFFER_SIZE];
87
88 /* Open the output file. */
89 local_file_fd = PR_Open(requestFileName, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
90 PR_IRUSR | PR_IWUSR | PR_IRGRP | PR_IWGRP | PR_IROTH);
91 if (local_file_fd == NULL)
92 {
93 fprintf (stderr, "could not open output file %s\n", requestFileName);
94 return SECFailure;
95 }
96
97 /* Read the number fo bytes to be received. */
98 numBytesRead = PR_Read(sslSocket, & info.size, sizeof (info.size));
99 if (numBytesRead == 0) /* EOF */
100 {
101 fprintf (stderr, "Error reading size of request file\n");
102 return SECFailure;
103 }
104 if (numBytesRead < 0)
105 {
106 errWarn("PR_Read");
107 return SECFailure;
108 }
109
110 /* Read until EOF or until the expected number of bytes has been read. */
111 for (totalBytes = 0; totalBytes < info.size; totalBytes += numBytesRead)
112 {
113 numBytesRead = PR_Read(sslSocket, buffer, READ_BUFFER_SIZE);
114 if (numBytesRead == 0)
115 break; /* EOF */
116 if (numBytesRead < 0)
117 {
118 errWarn("PR_Read");
119 break;
120 }
121
122 /* Write to stdout */
123 numBytesWritten = PR_Write(local_file_fd, buffer, numBytesRead);
124 if (numBytesWritten < 0)
125 fprintf (stderr, "could not write to output file %s\n", requestFileName);
126 if (numBytesWritten != numBytesRead)
127 fprintf (stderr, "could not write to output file %s\n", requestFileName);
128#if DEBUG
129 fprintf(stderr, "***** Connection read %d bytes.\n", numBytesRead);
130#if 0
131 buffer[numBytesRead] = '\0';
132 fprintf(stderr, "************\n%s\n************\n", buffer);
133#endif
134#endif
135 }
136
137 if (totalBytes != info.size)
138 {
139 fprintf (stderr, "Expected %d bytes, got %d\n", info.size, totalBytes);
140 return SECFailure;
141 }
142
143 PR_Close(local_file_fd);
144
145 return SECSuccess;
146}
147
148/* Function: setupSSLSocket()
149 *
150 * Purpose: Configure a socket for SSL.
151 *
152 *
153 */
154static PRFileDesc *
155setupSSLSocket(PRFileDesc *tcpSocket)
156{
157 PRFileDesc *sslSocket;
158 SSLKEAType certKEA;
159#if 0
160 int certErr = 0;
161#endif
162 SECStatus secStatus;
163
164 /* Inport the socket into SSL. */
165 sslSocket = SSL_ImportFD(NULL, tcpSocket);
166 if (sslSocket == NULL)
167 {
168 errWarn("SSL_ImportFD");
169 goto loser;
170 }
171
172 /* Set the appropriate flags. */
173 secStatus = SSL_OptionSet(sslSocket, SSL_SECURITY, PR_TRUE);
174 if (secStatus != SECSuccess)
175 {
176 errWarn("SSL_OptionSet SSL_SECURITY");
177 goto loser;
178 }
179
180 secStatus = SSL_OptionSet(sslSocket, SSL_HANDSHAKE_AS_SERVER, PR_TRUE);
181 if (secStatus != SECSuccess)
182 {
183 errWarn("SSL_OptionSet:SSL_HANDSHAKE_AS_SERVER");
184 goto loser;
185 }
186
187 secStatus = SSL_OptionSet(sslSocket, SSL_REQUEST_CERTIFICATE, PR_FALSE);
188 if (secStatus != SECSuccess)
189 {
190 errWarn("SSL_OptionSet:SSL_REQUEST_CERTIFICATE");
191 goto loser;
192 }
193
194 secStatus = SSL_OptionSet(sslSocket, SSL_REQUIRE_CERTIFICATE, PR_FALSE);
195 if (secStatus != SECSuccess)
196 {
197 errWarn("SSL_OptionSet:SSL_REQUIRE_CERTIFICATE");
198 goto loser;
199 }
200
201 /* Set the appropriate callback routines. */
202#if 0 /* use the default */
203 secStatus = SSL_AuthCertificateHook(sslSocket, myAuthCertificate,
204 CERT_GetDefaultCertDB());
205 if (secStatus != SECSuccess)
206 {
207 errWarn("SSL_AuthCertificateHook");
208 goto loser;
209 }
210#endif
211#if 0 /* Use the default */
212 secStatus = SSL_BadCertHook(sslSocket,
213 (SSLBadCertHandler)myBadCertHandler, &certErr);
214 if (secStatus != SECSuccess)
215 {
216 errWarn("SSL_BadCertHook");
217 goto loser;
218 }
219#endif
220#if 0 /* no handshake callback */
221 secStatus = SSL_HandshakeCallback(sslSocket,
222 myHandshakeCallback,
223 NULL);
224 if (secStatus != SECSuccess)
225 {
226 errWarn("SSL_HandshakeCallback");
227 goto loser;
228 }
229#endif
230 secStatus = SSL_SetPKCS11PinArg(sslSocket, password);
231 if (secStatus != SECSuccess)
232 {
233 errWarn("SSL_HandshakeCallback");
234 goto loser;
235 }
236
237 certKEA = NSS_FindCertKEAType(cert);
238
239 secStatus = SSL_ConfigSecureServer(sslSocket, cert, privKey, certKEA);
240 if (secStatus != SECSuccess)
241 {
242 errWarn("SSL_ConfigSecureServer");
243 goto loser;
244 }
245
246 return sslSocket;
247
248loser:
249 PR_Close(tcpSocket);
250 return NULL;
251}
252
253#if 0 /* No client authentication and not authenticating after each transaction. */
254/* Function: authenticateSocket()
255 *
256 * Purpose: Perform client authentication on the socket.
257 *
258 */
259static SECStatus
260authenticateSocket(PRFileDesc *sslSocket, PRBool requireCert)
261{
262 CERTCertificate *cert;
263 SECStatus secStatus;
264
265 /* Returns NULL if client authentication is not enabled or if the
266 * client had no certificate. */
267 cert = SSL_PeerCertificate(sslSocket);
268 if (cert)
269 {
270 /* Client had a certificate, so authentication is through. */
271 CERT_DestroyCertificate(cert);
272 return SECSuccess;
273 }
274
275 /* Request client to authenticate itself. */
276 secStatus = SSL_OptionSet(sslSocket, SSL_REQUEST_CERTIFICATE, PR_TRUE);
277 if (secStatus != SECSuccess)
278 {
279 errWarn("SSL_OptionSet:SSL_REQUEST_CERTIFICATE");
280 return SECFailure;
281 }
282
283 /* If desired, require client to authenticate itself. Note
284 * SSL_REQUEST_CERTIFICATE must also be on, as above. */
285 secStatus = SSL_OptionSet(sslSocket, SSL_REQUIRE_CERTIFICATE, requireCert);
286 if (secStatus != SECSuccess)
287 {
288 errWarn("SSL_OptionSet:SSL_REQUIRE_CERTIFICATE");
289 return SECFailure;
290 }
291
292 /* Having changed socket configuration parameters, redo handshake. */
293 secStatus = SSL_ReHandshake(sslSocket, PR_TRUE);
294 if (secStatus != SECSuccess)
295 {
296 errWarn("SSL_ReHandshake");
297 return SECFailure;
298 }
299
300 /* Force the handshake to complete before moving on. */
301 secStatus = SSL_ForceHandshake(sslSocket);
302 if (secStatus != SECSuccess)
303 {
304 errWarn("SSL_ForceHandshake");
305 return SECFailure;
306 }
307
308 return SECSuccess;
309}
310#endif /* No client authentication and not authenticating after each transaction. */
311
312/* Function: writeDataToSocket
313 *
314 * Purpose: Write the server's response back to the socket.
315 *
316 */
317static SECStatus
318writeDataToSocket(PRFileDesc *sslSocket)
319{
320 int numBytes;
321 PRFileDesc *local_file_fd;
322 PRFileInfo info;
323 PRStatus prStatus;
324
325 /* Try to open the local file named.
326 * If successful, then write it to the client.
327 */
89dd03e3 328 prStatus = PR_GetFileInfo(responseZipName, &info);
1cecb3c5
DB
329 if (prStatus != PR_SUCCESS || info.type != PR_FILE_FILE || info.size < 0)
330 {
89dd03e3 331 fprintf (stderr, "Input file %s not found\n", responseZipName);
1cecb3c5
DB
332 return SECFailure;
333 }
334
89dd03e3 335 local_file_fd = PR_Open(responseZipName, PR_RDONLY, 0);
1cecb3c5
DB
336 if (local_file_fd == NULL)
337 {
89dd03e3 338 fprintf (stderr, "Could not open input file %s\n", responseZipName);
1cecb3c5
DB
339 return SECFailure;
340 }
341
342 /* Transmit the local file across the socket.
343 */
344 numBytes = PR_TransmitFile(sslSocket, local_file_fd,
345 NULL, 0,
346 PR_TRANSMITFILE_KEEP_OPEN,
347 PR_INTERVAL_NO_TIMEOUT);
348
349 /* Error in transmission. */
350 if (numBytes < 0)
351 {
352 errWarn("PR_TransmitFile");
353 return SECFailure;
354 }
355#if DEBUG
356 /* Transmitted bytes successfully. */
357 fprintf(stderr, "PR_TransmitFile wrote %d bytes from %s\n",
89dd03e3 358 numBytes, responseZipName);
1cecb3c5
DB
359#endif
360
361 PR_Close(local_file_fd);
362
363 return SECSuccess;
364}
365
366/* Function: int handle_connection()
367 *
368 * Purpose: Handle a connection to a socket.
369 *
370 */
371static SECStatus
372handle_connection(PRFileDesc *tcpSocket)
373{
374 PRFileDesc * sslSocket = NULL;
375 SECStatus secStatus = SECFailure;
376 PRStatus prStatus;
377 PRSocketOptionData socketOption;
378 PRFileInfo info;
379 char *cmdline;
380 int rc;
381 char *rc1;
382
383 /* Make sure the socket is blocking. */
384 socketOption.option = PR_SockOpt_Nonblocking;
385 socketOption.value.non_blocking = PR_FALSE;
386 PR_SetSocketOption(tcpSocket, &socketOption);
387
388 sslSocket = setupSSLSocket(tcpSocket);
389 if (sslSocket == NULL)
390 {
391 errWarn("setupSSLSocket");
392 goto cleanup;
393 }
394
395 secStatus = SSL_ResetHandshake(sslSocket, /* asServer */ PR_TRUE);
396 if (secStatus != SECSuccess)
397 {
398 errWarn("SSL_ResetHandshake");
399 goto cleanup;
400 }
401
64aa100f
DB
402 /* Force the handshake to complete before moving on. */
403 secStatus = SSL_ForceHandshake(sslSocket);
404 if (secStatus != SECSuccess)
405 {
406 errWarn("SSL_ForceHandshake");
407 goto cleanup;
408 }
409
1cecb3c5
DB
410 /* Create a temporary files and directories. */
411 memcpy (requestFileName + sizeof (requestFileName) - 1 - 6, "XXXXXX", 6);
412 rc = mkstemp(requestFileName);
413 if (rc == -1)
414 {
415 fprintf (stderr, "Could not create temporary file %s\n", requestFileName);
416 perror ("");
417 secStatus = SECFailure;
418 goto cleanup;
419 }
420
421 memcpy (responseDirName + sizeof (responseDirName) - 1 - 6, "XXXXXX", 6);
422 rc1 = mkdtemp(responseDirName);
423 if (! rc1)
424 {
425 fprintf (stderr, "Could not create temporary directory %s\n", responseDirName);
426 perror ("");
427 secStatus = SECFailure;
428 goto cleanup;
429 }
430
89dd03e3
DB
431 memcpy (responseZipName, responseDirName, sizeof (responseDirName) - 1);
432 memcpy (responseZipName + sizeof (responseZipName) - 1 - 6, "XXXXXX", 6);
433 rc = mkstemp(responseZipName);
1cecb3c5
DB
434 if (rc == -1)
435 {
89dd03e3 436 fprintf (stderr, "Could not create temporary file %s\n", responseZipName);
1cecb3c5
DB
437 perror ("");
438 secStatus = SECFailure;
64aa100f
DB
439
440 /* Remove this so that the other temp files will get removed in cleanup. */
441 prStatus = PR_RmDir (responseDirName);
442 if (prStatus != PR_SUCCESS)
443 errWarn ("PR_RmDir");
1cecb3c5
DB
444 goto cleanup;
445 }
446
447 /* Read data from the socket.
448 * If the user is requesting/requiring authentication, authenticate
449 * the socket. */
450#if DEBUG
451 fprintf(stdout, "\nReading data from socket...\n\n");
452#endif
453 secStatus = readDataFromSocket(sslSocket);
454 if (secStatus != SECSuccess)
455 goto cleanup;
456
457#if 0 /* Don't authenticate after each transaction */
458 if (REQUEST_CERT_ALL)
459 {
460 fprintf(stdout, "\nAuthentication requested.\n\n");
461 secStatus = authenticateSocket(sslSocket);
462 if (secStatus != SECSuccess)
463 goto cleanup;
464 }
465#endif
466
467 /* Call the stap-server script. */
468 cmdline = PORT_Alloc(sizeof ("stap-server") +
469 sizeof (requestFileName) +
470 sizeof (responseDirName) +
89dd03e3 471 sizeof (responseZipName) +
1cecb3c5
DB
472 strlen (dbdir) + 1);
473 if (! cmdline) {
474 errWarn ("PORT_Alloc");
475 secStatus = SECFailure;
476 goto cleanup;
477 }
478
479 sprintf (cmdline, "stap-server %s %s %s %s",
89dd03e3 480 requestFileName, responseDirName, responseZipName, dbdir);
1cecb3c5
DB
481 rc = system (cmdline);
482
483 PR_Free (cmdline);
484
485#if DEBUG
486 fprintf(stdout, "\nWriting data to socket...\n\n");
487#endif
488 secStatus = writeDataToSocket(sslSocket);
489
490cleanup:
1cecb3c5
DB
491 /* Close down the socket. */
492 prStatus = PR_Close(tcpSocket);
493 if (prStatus != PR_SUCCESS)
494 errWarn("PR_Close");
495
496 /* Attempt to remove temporary files, unless the temporary directory was
497 not deleted by the server script. */
498 prStatus = PR_GetFileInfo(responseDirName, &info);
499 if (prStatus != PR_SUCCESS)
500 {
501 prStatus = PR_Delete (requestFileName);
502 if (prStatus != PR_SUCCESS)
503 errWarn ("PR_Delete");
89dd03e3 504 prStatus = PR_Delete (responseZipName);
1cecb3c5
DB
505 if (prStatus != PR_SUCCESS)
506 errWarn ("PR_Delete");
507 }
508
509 return secStatus;
510}
511
512/* Function: int accept_connection()
513 *
514 * Purpose: Accept a connection to the socket.
515 *
516 */
517static SECStatus
518accept_connection(PRFileDesc *listenSocket)
519{
520 PRNetAddr addr;
521 PRStatus prStatus;
522 PRFileDesc *tcpSocket;
64aa100f 523#if 0
1cecb3c5 524 SECStatus result;
64aa100f 525#endif
1cecb3c5
DB
526
527 while (PR_TRUE)
528 {
529#if DEBUG
530 fprintf(stderr, "\n\n\nAbout to call accept.\n");
531#endif
532
533 /* Accept a connection to the socket. */
534 tcpSocket = PR_Accept(listenSocket, &addr, PR_INTERVAL_NO_TIMEOUT);
535 if (tcpSocket == NULL)
536 {
537 errWarn("PR_Accept");
538 break;
539 }
540
541 /* Accepted the connection, now handle it. */
64aa100f
DB
542 /*result =*/ handle_connection (tcpSocket);
543#if 0 /* Not necessary */
1cecb3c5
DB
544 if (result != SECSuccess)
545 {
546 prStatus = PR_Close(tcpSocket);
547 if (prStatus != PR_SUCCESS)
548 exitErr("PR_Close");
549 break;
550 }
64aa100f 551#endif
1cecb3c5
DB
552 }
553
554#if DEBUG
555 fprintf(stderr, "Closing listen socket.\n");
556#endif
557 prStatus = PR_Close(listenSocket);
558 if (prStatus != PR_SUCCESS)
559 exitErr("PR_Close");
560
561 return SECSuccess;
562}
563
564/* Function: void server_main()
565 *
566 * Purpose: This is the server's main function. It configures a socket
567 * and listens to it.
568 *
569 */
570static void
571server_main(unsigned short port, SECKEYPrivateKey *privKey, CERTCertificate *cert)
572{
573 SECStatus secStatus;
574 PRStatus prStatus;
575 PRFileDesc * listenSocket;
576 PRNetAddr addr;
577 PRSocketOptionData socketOption;
578
579 /* Create a new socket. */
580 listenSocket = PR_NewTCPSocket();
581 if (listenSocket == NULL)
582 exitErr("PR_NewTCPSocket");
583
584 /* Set socket to be blocking -
585 * on some platforms the default is nonblocking.
586 */
587 socketOption.option = PR_SockOpt_Nonblocking;
588 socketOption.value.non_blocking = PR_FALSE;
589
590 prStatus = PR_SetSocketOption(listenSocket, &socketOption);
591 if (prStatus != PR_SUCCESS)
592 exitErr("PR_SetSocketOption");
593
594#if 0
595 /* This cipher is not on by default. The Acceptance test
596 * would like it to be. Turn this cipher on.
597 */
598 secStatus = SSL_CipherPrefSetDefault(SSL_RSA_WITH_NULL_MD5, PR_TRUE);
599 if (secStatus != SECSuccess)
600 exitErr("SSL_CipherPrefSetDefault:SSL_RSA_WITH_NULL_MD5");
601#endif
602
603 /* Configure the network connection. */
604 addr.inet.family = PR_AF_INET;
605 addr.inet.ip = PR_INADDR_ANY;
606 addr.inet.port = PR_htons(port);
607
608 /* Bind the address to the listener socket. */
609 prStatus = PR_Bind(listenSocket, &addr);
610 if (prStatus != PR_SUCCESS)
611 exitErr("PR_Bind");
612
613 /* Listen for connection on the socket. The second argument is
614 * the maximum size of the queue for pending connections.
615 */
616 prStatus = PR_Listen(listenSocket, 5);
617 if (prStatus != PR_SUCCESS)
618 exitErr("PR_Listen");
619
620 /* Handle connections to the socket. */
621 secStatus = accept_connection (listenSocket);
622 if (secStatus != SECSuccess)
623 PR_Close(listenSocket);
624}
625
626/* Function: char * myPasswd()
627 *
628 * Purpose: This function is our custom password handler that is called by
629 * SSL when retreiving private certs and keys from the database. Returns a
630 * pointer to a string that with a password for the database. Password pointer
631 * should point to dynamically allocated memory that will be freed later.
632 */
633static char *
634myPasswd(PK11SlotInfo *info, PRBool retry, void *arg)
635{
636 char * passwd = NULL;
637
638 if (! retry && arg)
639 passwd = PORT_Strdup((char *)arg);
640
641 return passwd;
642}
643
644/* Obtain the certificate and key database password from the given file. */
645static char *
646getPassword(char *fileName)
647{
648 PRFileDesc *local_file_fd;
649 PRFileInfo fileInfo;
650 PRInt32 numBytesRead;
651 PRStatus prStatus;
652 char *password;
653 PRInt32 i;
654
655 prStatus = PR_GetFileInfo(fileName, &fileInfo);
656 if (prStatus != PR_SUCCESS || fileInfo.type != PR_FILE_FILE || fileInfo.size < 0)
657 {
658 fprintf (stderr, "Password file %s not found\n", fileName);
659 return NULL;
660 }
661
662 local_file_fd = PR_Open(fileName, PR_RDONLY, 0);
663 if (local_file_fd == NULL)
664 {
665 fprintf (stderr, "Could not open password file %s\n", fileName);
666 return NULL;
667 }
668
669 password = PORT_Alloc(fileInfo.size + 1);
670 if (! password) {
671 errWarn ("PORT_Alloc");
672 return NULL;
673 }
674
675 numBytesRead = PR_Read(local_file_fd, password, fileInfo.size);
676 if (numBytesRead <= 0)
677 {
678 fprintf (stderr, "Error reading password file\n");
679 exitErr ("PR_Read");
680 }
681
682 PR_Close(local_file_fd);
683
684 /* Keep only the first line of data. */
685 for (i = 0; i < numBytesRead; ++i)
686 {
687 if (password[i] == '\n' || password[i] == '\r' ||
688 password[i] == '\0')
689 break;
690 }
691 password[i] = '\0';
692
693 return password;
694}
695
696/* Function: int main()
697 *
698 * Purpose: Parses command arguments and configures SSL server.
699 *
700 */
701int
702main(int argc, char **argv)
703{
704 char * progName = NULL;
705 char * nickName = NULL;
706 char * passwordFile = NULL;
707 unsigned short port = 0;
708 SECStatus secStatus;
709 PLOptState * optstate;
710 PLOptStatus status;
711
712 progName = PL_strdup(argv[0]);
713
714 optstate = PL_CreateOptState(argc, argv, "d:p:n:w:");
715 while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK)
716 {
717 switch(optstate->option)
718 {
719 case 'd': dbdir = PL_strdup(optstate->value); break;
720 case 'n': nickName = PL_strdup(optstate->value); break;
721 case 'p': port = PORT_Atoi(optstate->value); break;
722 case 'w': passwordFile = PL_strdup(optstate->value); break;
723 default:
724 case '?': Usage(progName);
725 }
726 }
727
728 if (nickName == NULL || port == 0 || dbdir == NULL || passwordFile == NULL)
729 Usage(progName);
730
731 password = getPassword (passwordFile);
732
733 /* Call the NSPR initialization routines. */
734 PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
735
736 /* Set the cert database password callback. */
737 PK11_SetPasswordFunc(myPasswd);
738
739 /* Initialize NSS. */
740 secStatus = NSS_Init(dbdir);
741 if (secStatus != SECSuccess)
742 exitErr("NSS_Init");
743
744 /* Set the policy for this server (REQUIRED - no default). */
745 secStatus = NSS_SetDomesticPolicy();
746 if (secStatus != SECSuccess)
747 exitErr("NSS_SetDomesticPolicy");
748
749 /* Get own certificate and private key. */
750 cert = PK11_FindCertFromNickname(nickName, password);
751 if (cert == NULL)
752 exitErr("PK11_FindCertFromNickname");
753
754 privKey = PK11_FindKeyByAnyCert(cert, password);
755 if (privKey == NULL)
756 exitErr("PK11_FindKeyByAnyCert");
757
758 /* Configure the server's cache for a multi-process application
759 * using default timeout values (24 hrs) and directory location (/tmp).
760 */
761 SSL_ConfigMPServerSIDCache(256, 0, 0, NULL);
762
763 /* Launch server. */
764 server_main(port, privKey, cert);
765
766 /* Shutdown NSS and exit NSPR gracefully. */
767 NSS_Shutdown();
768 PR_Cleanup();
769
770 return 0;
771}
0c5f5812
JS
772
773/* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
This page took 0.095408 seconds and 5 git commands to generate.