📄 main.c
字号:
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- *//* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Netscape security libraries. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1994-2000 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. *//* * PSM main thread: * * init PSM * while (alive) * accept connection * spawn a thread to handle connection * * There are two threads per connection, one reads the data, another writes * the reply. */#include "serv.h"#include "secport.h"#include "dataconn.h"#include "ctrlconn.h"#include "minihttp.h"#include "ciferfam.h"#include "secmime.h"#include "messages.h"#include "textgen.h"#include "oldfunc.h"#include "nss.h"void SSM_InitLogging(void);#ifdef TIMEBOMB#include "timebomb.h"#endif#ifdef WIN32#include <wtypes.h>#include <winreg.h>#include <winerror.h>#endif#ifdef XP_UNIX#include <signal.h>#ifndef SIG_ERR#define SIG_ERR -1#endif /*SIG_ERR*/#endif /*XP_UNIX*/#define POLICY_TYPE_INDEX 0SSMCollection * connections = NULL;SSMHashTable * tokenList = NULL;PRMonitor * tokenLock = NULL;SSMHashTable * ctrlConnections = NULL;#ifdef XP_MACSSMPolicyType policyType = ssmDomestic;#elseSSMPolicyType policyType = ssmUnknownPolicy;#endif/* * This function is required by svrplcy to set the * utility policy. This will tell us what kind of * policy we are running. */SECStatus Utility_SetPolicy(long which, int policy){ if (which == POLICY_TYPE_INDEX) { switch (policy) { case SVRPLCYDomestic: policyType = ssmDomestic; break; case SVRPLCYExport: policyType = ssmExport; break; case SVRPLCYFrance: policyType = ssmFrance; break; default: /* This is an unknown policy type. */ PR_ASSERT(0); break; } } return SECSuccess;}void SSM_SetPolicy(void){#ifndef XP_MAC SVRPLCY_InstallSSLPolicy(); SVRPLCY_InstallPK12Policy(); SVRPLCY_InstallSMIMEPolicy(); SVRPLCY_InstallUtilityPolicy();#else /* Assume domestic policy for now */ NSS_SetDomesticPolicy();#endif}SSMPolicyTypeSSM_GetPolicy(void){ return policyType;}static voidenable_SMIME_cipher_prefs(void){ SSMPolicyType policy; policy = SSM_GetPolicy(); switch (policy) { case ssmDomestic: SECMIME_EnableCipher(SMIME_DES_EDE3_168, 1); SECMIME_EnableCipher(SMIME_RC2_CBC_128, 1); SECMIME_EnableCipher(SMIME_RC2_CBC_64, 1); SECMIME_EnableCipher(SMIME_DES_CBC_56, 1);#if 0 SECMIME_EnableCipher(SMIME_RC5PAD_64_16_128, 1); SECMIME_EnableCipher(SMIME_RC5PAD_64_16_64, 1); SECMIME_EnableCipher(SMIME_FORTEZZA, 1);#endif case ssmExport: SECMIME_EnableCipher(SMIME_RC2_CBC_40, 1);#if 0 SECMIME_EnableCipher(SMIME_RC5PAD_64_16_40, 1);#endif case ssmFrance: default: break; } /* now tell secmime that we've sent it the last preference */ SECMIME_EnableCipher(CIPHER_FAMILYID_MASK, 0);}SECStatusssm_InitializePKCS11Strings(void){ char *manufacturerID = NULL; char *libraryDescription = NULL; char *tokenDescription = NULL; char *privateTokenDescription = NULL; char *slotDescription = NULL; char *privateSlotDescription = NULL; char *fipsSlotDescription = NULL; char *fipsPrivateSlotDescription = NULL; SSMTextGenContext *cx; SSMStatus rv; rv = SSMTextGen_NewTopLevelContext(NULL, &cx); if (rv != SSM_SUCCESS) { goto loser; } rv = SSM_FindUTF8StringInBundles(cx, "manufacturerID", &manufacturerID); if (rv != SSM_SUCCESS) { goto loser; } rv = SSM_FindUTF8StringInBundles(cx, "libraryDescription", &libraryDescription); if (rv != SSM_SUCCESS) { goto loser; } rv = SSM_FindUTF8StringInBundles(cx, "tokenDescription", &tokenDescription); if (rv != SSM_SUCCESS) { goto loser; } rv = SSM_FindUTF8StringInBundles(cx, "privateTokenDescription", &privateTokenDescription); if (rv != SSM_SUCCESS) { goto loser; } rv = SSM_FindUTF8StringInBundles(cx, "slotDescription", &slotDescription); if (rv != SSM_SUCCESS) { goto loser; } rv = SSM_FindUTF8StringInBundles(cx, "privateSlotDescription", &privateSlotDescription); if (rv != SSM_SUCCESS) { goto loser; } rv = SSM_FindUTF8StringInBundles(cx, "fipsSlotDescription", &fipsSlotDescription); if (rv != SSM_SUCCESS) { goto loser; } rv = SSM_FindUTF8StringInBundles(cx, "fipsPrivateSlotDescription", &fipsPrivateSlotDescription); if (rv != SSM_SUCCESS) { goto loser; } if (cx != NULL) { SSMTextGen_DestroyContext(cx); } PK11_ConfigurePKCS11(manufacturerID, libraryDescription, tokenDescription, privateTokenDescription, slotDescription, privateSlotDescription, fipsSlotDescription, fipsPrivateSlotDescription, 0, 0); return SECSuccess; loser: PR_FREEIF(manufacturerID); PR_FREEIF(libraryDescription); PR_FREEIF(tokenDescription); PR_FREEIF(privateTokenDescription); PR_FREEIF(slotDescription); PR_FREEIF(privateSlotDescription); if (cx != NULL) { SSMTextGen_DestroyContext(cx); } return SECFailure;}#ifdef XP_UNIX#define CATCH_SIGNAL_DEFAULT(SIGNAL) \ if (((int)signal(SIGNAL, psm_signal_handler_default)) == ((int)SIG_ERR)) \ goto loser;#define CATCH_SIGNAL_IGNORE(SIGNAL) \ if (((int)signal(SIGNAL, psm_signal_handler_ignore)) == ((int)SIG_ERR)) \ goto loser;static voidpsm_signal_handler_default(int sig){#ifdef DEBUG printf ("Trapping the signal %d\n", sig);#endif SSM_ReleaseLockFile(); kill(getpid(),SIGKILL);}static voidpsm_signal_handler_ignore(int sig){#ifdef DEBUG printf ("Ignoring the signal %d\n", sig);#endif signal(sig,psm_signal_handler_ignore);}static SSMStatuspsm_catch_signals(void){ CATCH_SIGNAL_IGNORE(SIGHUP); CATCH_SIGNAL_DEFAULT(SIGINT); CATCH_SIGNAL_DEFAULT(SIGQUIT); CATCH_SIGNAL_DEFAULT(SIGILL); CATCH_SIGNAL_DEFAULT(SIGTRAP); CATCH_SIGNAL_DEFAULT(SIGABRT); CATCH_SIGNAL_DEFAULT(SIGIOT);#ifdef SIGEMT CATCH_SIGNAL_DEFAULT(SIGEMT);#endif CATCH_SIGNAL_DEFAULT(SIGFPE); CATCH_SIGNAL_DEFAULT(SIGBUS); CATCH_SIGNAL_DEFAULT(SIGSEGV);#ifdef SIGSYS CATCH_SIGNAL_DEFAULT(SIGSYS);#endif CATCH_SIGNAL_IGNORE(SIGPIPE); CATCH_SIGNAL_DEFAULT(SIGTERM);#ifndef LINUX CATCH_SIGNAL_DEFAULT(SIGUSR1);#endif CATCH_SIGNAL_DEFAULT(SIGUSR2);#ifdef SIGXCPU CATCH_SIGNAL_DEFAULT(SIGXCPU);#endif#ifdef SIGDANGER CATCH_SIGNAL_DEFAULT(SIGDANGER);#endif return SSM_SUCCESS; loser: return SSM_FAILURE;}#endif#if defined(XP_PC) && !defined(DEBUG)int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpszLine, int nShow)#else#ifdef macintosh/* We run RunMacPSM in a separate thread off the main thread. This is because we can't do any blocking I/O routines on the main thread, because Mac NSPR doesn't own the original thread used to run the app.*/void RunMacPSM(void *arg)#elseint main(int argc, char ** argv)#endif#endif{#ifdef macintosh#pragma unused(arg)#endif#if (defined(XP_PC) && !defined(DEBUG)) || (defined(macintosh)) /* substitute argc and argv for NSPR */ int argc = 0; char *argv[] = {"", NULL};#endif PRIntn result = 0;#ifdef DEBUG PR_STDIO_INIT();#endif#ifdef TIMEBOMB SSM_CheckTimebomb();#endif#ifdef XP_UNIX if (psm_catch_signals() != SSM_SUCCESS) { SSM_DEBUG("Couldn't set signal handlers. Quitting\n"); exit(1); }#endif SSM_SetPolicy(); enable_SMIME_cipher_prefs(); if (SSM_GetPolicy() == ssmDomestic) { SSM_EnableHighGradeKeyGen(); } /* Initialize global list of control connections. */ connections = SSM_NewCollection(); if (connections == NULL) { SSM_DEBUG("Can't initialize! (%ld)\n", (long) result); exit(1); } /* Initialize global list of tokens */ result = SSM_HashCreate(&tokenList); if (result != PR_SUCCESS || !tokenList) { SSM_DEBUG("Can't initialize - tokenList \n"); exit(result); } tokenLock = PR_NewMonitor(); if (!tokenLock) { SSM_DEBUG("Can't initialize - tokenLock\n"); exit(1); } /* Initialize hash table of control connections */ result = SSM_HashCreate(&ctrlConnections); if (result != PR_SUCCESS || !ctrlConnections) { SSM_DEBUG("Can't initialize global table for control connections \n"); exit(result); } /* Initialize resource table */ SSM_ResourceInit(); if (SSM_InitPolicyHandler() != PR_SUCCESS) { SSM_DEBUG("Couldn't initialize the Policy Handler.\n"); exit (1); } /* * All the ciphers except SSL_RSA_WITH_NULL_MD5 are on by default. * Enable encryption, enable NULL cipher. */#ifdef XP_MAC result = mainLoop(argc, argv);#else result = PR_Initialize(mainLoop, argc, argv, 0);#endif#ifdef DEBUG printf("main: Finishing (%ld)\n", (long) result);#endif#ifdef XP_UNIX SSM_ReleaseLockFile();#endif#ifndef XP_MAC return result;#endif}#ifdef XP_MACvoid *psm_malloc(unsigned long numbytes){ return NewPtrClear(numbytes);}voidpsm_free(void *ptr){ DisposePtr((char *) ptr);}#endifPRIntn mainLoop(PRIntn argc, char ** argv){ PRFileDesc *socket, *respsocket; PRNetAddr clientaddr; SSMControlConnection *curconnect; SSMResourceID ctrlID; SSMStatus status = PR_FAILURE; PRBool alive = PR_TRUE;#ifdef DEBUG /* Initialize logging. */ SSM_InitLogging();#endif /* Register ourselves so that logs, etc can identify us */ SSM_RegisterThread("main", NULL); /* Open NLS stuff */ SSM_DEBUG("Initializing NLS.\n"); SSM_InitNLS("ui"); ssm_InitializePKCS11Strings(); /* Initialize the protocol */#ifdef XP_MAC CMT_Init(malloc, free);#else CMT_Init(PR_Malloc, PR_Free);#endif /* Open the HTTP listener */ SSM_DEBUG("Opening HTTP thread.\n"); status = SSM_InitHTTP(); if (status != SSM_SUCCESS) { SSM_DEBUG("Couldn't open web port. Exiting.\n"); goto loser; } /* open a port for control connections, with well-known port# */ socket = SSM_OpenControlPort(); if (!socket) { SSM_DEBUG("Couldn't open control port. Exiting.\n"); goto loser; } while (alive) { /* wait until there is incoming request */ respsocket = PR_Accept(socket, &clientaddr, PR_INTERVAL_NO_TIMEOUT); /* while (respsocket == NULL) { if (PR_GetError() != PR_WOULD_BLOCK_ERROR) goto loser; PR_Sleep(PSM_SPINTIME);#ifdef DEBUG printf("master: Still ready for client connection on port %d\n", PSM_PORT); fflush(stdout);#endif respsocket = PR_Accept(socket, &clientaddr, PR_SecondsToInterval(2)); } */ if (respsocket && SSM_SocketPeerCheck(respsocket, PR_TRUE)) { SSM_DEBUG("creating control connection.\n"); status = SSM_CreateResource(SSM_RESTYPE_CONTROL_CONNECTION, respsocket, NULL, &ctrlID, (SSMResource **) &curconnect); if (status != PR_SUCCESS) break; PR_ASSERT(RESOURCE_CLASS(curconnect) == SSM_RESTYPE_CONTROL_CONNECTION); } else { status = PR_GetError(); SSM_DEBUG("Error %d accepting control connection. Exiting.\n", status); goto loser; } } /* end while(true) */ loser: /* Shut down the HTTP thread. */ if (httpListenThread != NULL){ PR_Interrupt(httpListenThread); } exit(1); /* ### mwelch - should we return meaningful error code? */ return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -