зеркало из https://github.com/mozilla/gecko-dev.git
659 строки
18 KiB
C
659 строки
18 KiB
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.
|
|
*/
|
|
|
|
#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"
|
|
#include "p12plcy.h"
|
|
#include "nlslayer.h"
|
|
#include "softoken.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>
|
|
#include <unistd.h>
|
|
|
|
#ifndef SIG_ERR
|
|
#define SIG_ERR -1
|
|
#endif /*SIG_ERR*/
|
|
|
|
#endif /*XP_UNIX*/
|
|
|
|
#define POLICY_TYPE_INDEX 0
|
|
|
|
SSMCollection * connections = NULL;
|
|
SSMHashTable * tokenList = NULL;
|
|
PRMonitor * tokenLock = NULL;
|
|
SSMHashTable * ctrlConnections = NULL;
|
|
|
|
SSMPolicyType policyType = ssmDomestic;
|
|
|
|
/*
|
|
* The following is a quick write of enabling various ciphers. This code is
|
|
* essentially moved from the server core code. Eventually we will need to
|
|
* place this data and functionality in a more modular way.
|
|
*/
|
|
#define SSM_POLICY_END 0 /* end of table */
|
|
#define SSM_POLICY_SSL 1 /* SSL ciphersuites: not really used */
|
|
#define SSM_POLICY_PK12 2 /* PKCS #12 ciphersuites */
|
|
#define SSM_POLICY_SMIME 3 /* S/MIME ciphersuites */
|
|
|
|
typedef struct {
|
|
PRInt32 policy;
|
|
PRInt32 key;
|
|
PRInt32 value;
|
|
} SSMPolicyEntry;
|
|
|
|
static SSMPolicyEntry ssmPK12PolicyTable[] =
|
|
{
|
|
{SSM_POLICY_PK12, PKCS12_RC4_40, (PRInt32)PR_TRUE},
|
|
{SSM_POLICY_PK12, PKCS12_RC4_128, (PRInt32)PR_TRUE},
|
|
{SSM_POLICY_PK12, PKCS12_RC2_CBC_40, (PRInt32)PR_TRUE},
|
|
{SSM_POLICY_PK12, PKCS12_RC2_CBC_128, (PRInt32)PR_TRUE},
|
|
{SSM_POLICY_PK12, PKCS12_DES_56, (PRInt32)PR_TRUE},
|
|
{SSM_POLICY_PK12, PKCS12_DES_EDE3_168, (PRInt32)PR_TRUE},
|
|
{SSM_POLICY_END, 0, 0}
|
|
};
|
|
|
|
static SSMPolicyEntry ssmSMIMEPolicyTable[] =
|
|
{
|
|
{SSM_POLICY_SMIME, SMIME_RC2_CBC_40, (PRInt32)PR_TRUE},
|
|
{SSM_POLICY_SMIME, SMIME_RC2_CBC_64, (PRInt32)PR_TRUE},
|
|
{SSM_POLICY_SMIME, SMIME_RC2_CBC_128, (PRInt32)PR_TRUE},
|
|
{SSM_POLICY_SMIME, SMIME_DES_CBC_56, (PRInt32)PR_TRUE},
|
|
{SSM_POLICY_SMIME, SMIME_DES_EDE3_168, (PRInt32)PR_TRUE},
|
|
{SSM_POLICY_SMIME, SMIME_RC5PAD_64_16_40, (PRInt32)PR_TRUE},
|
|
{SSM_POLICY_SMIME, SMIME_RC5PAD_64_16_64, (PRInt32)PR_TRUE},
|
|
{SSM_POLICY_SMIME, SMIME_RC5PAD_64_16_128, (PRInt32)PR_TRUE},
|
|
{SSM_POLICY_END, 0, 0}
|
|
};
|
|
|
|
static SSMStatus SSM_InstallPK12Policy(void)
|
|
{
|
|
const SSMPolicyEntry* entry = ssmPK12PolicyTable;
|
|
int i;
|
|
|
|
for (i = 0; entry[i].policy != SSM_POLICY_END; i++) {
|
|
if (SEC_PKCS12EnableCipher(entry[i].key, entry[i].value) !=
|
|
SECSuccess) {
|
|
return SSM_FAILURE;
|
|
}
|
|
}
|
|
return SSM_SUCCESS;
|
|
}
|
|
|
|
static SSMStatus SSM_InstallSMIMEPolicy(void)
|
|
{
|
|
const SSMPolicyEntry* entry = ssmSMIMEPolicyTable;
|
|
int i;
|
|
|
|
for (i = 0; entry[i].policy != SSM_POLICY_END; i++) {
|
|
if (SECMIME_SetPolicy(entry[i].key, entry[i].value) != SECSuccess) {
|
|
return SSM_FAILURE;
|
|
}
|
|
}
|
|
return SSM_SUCCESS;
|
|
}
|
|
|
|
/* XXX sjlee: we don't need to do a similar thing for SSL as we can call an
|
|
* NSS function to do it
|
|
*/
|
|
|
|
#if 0
|
|
/*
|
|
* 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)
|
|
{
|
|
policyType = ssmDomestic;
|
|
return SECSuccess;
|
|
}
|
|
#endif
|
|
|
|
void SSM_SetPolicy(void)
|
|
{
|
|
#if 0
|
|
SVRPLCY_InstallSSLPolicy();
|
|
SVRPLCY_InstallPK12Policy();
|
|
SVRPLCY_InstallSMIMEPolicy();
|
|
SVRPLCY_InstallUtilityPolicy();
|
|
#else
|
|
/* Always domestic policy now */
|
|
NSS_SetDomesticPolicy();
|
|
SSM_InstallPK12Policy();
|
|
SSM_InstallSMIMEPolicy();
|
|
#endif
|
|
}
|
|
|
|
SSMPolicyType
|
|
SSM_GetPolicy(void)
|
|
{
|
|
return policyType;
|
|
}
|
|
|
|
static void
|
|
enable_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);
|
|
}
|
|
|
|
#define SHORT_PK11_STRING 33
|
|
#define LONG_PK11_STRING 65
|
|
|
|
static char*
|
|
ssm_ConverToLength(char *origString, PRUint32 newLen)
|
|
{
|
|
char *newString;
|
|
PRUint32 origLen;
|
|
PRUint32 copyLen;
|
|
|
|
newString = SSM_NEW_ARRAY(char,newLen+1);
|
|
if (newString == NULL) {
|
|
return origString;
|
|
}
|
|
origLen = PL_strlen(origString);
|
|
copyLen = (origLen > newLen) ? newLen : origLen;
|
|
memcpy(newString, origString, copyLen);
|
|
memset(newString+copyLen, ' ' ,newLen - copyLen);
|
|
newString[newLen]='\0';
|
|
PR_Free(origString);
|
|
return newString;
|
|
}
|
|
|
|
SECStatus
|
|
ssm_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;
|
|
}
|
|
if (PL_strlen(manufacturerID) != SHORT_PK11_STRING) {
|
|
manufacturerID = ssm_ConverToLength(manufacturerID, SHORT_PK11_STRING);
|
|
}
|
|
rv = SSM_FindUTF8StringInBundles(cx, "libraryDescription",
|
|
&libraryDescription);
|
|
if (rv != SSM_SUCCESS) {
|
|
goto loser;
|
|
}
|
|
if (PL_strlen(libraryDescription) != SHORT_PK11_STRING) {
|
|
libraryDescription = ssm_ConverToLength(libraryDescription,
|
|
SHORT_PK11_STRING);
|
|
}
|
|
rv = SSM_FindUTF8StringInBundles(cx, "tokenDescription",
|
|
&tokenDescription);
|
|
if (rv != SSM_SUCCESS) {
|
|
goto loser;
|
|
}
|
|
if (PL_strlen(tokenDescription) != SHORT_PK11_STRING) {
|
|
tokenDescription = ssm_ConverToLength(tokenDescription,
|
|
SHORT_PK11_STRING);
|
|
}
|
|
rv = SSM_FindUTF8StringInBundles(cx, "privateTokenDescription",
|
|
&privateTokenDescription);
|
|
if (rv != SSM_SUCCESS) {
|
|
goto loser;
|
|
}
|
|
if (PL_strlen(privateTokenDescription) != SHORT_PK11_STRING) {
|
|
privateTokenDescription = ssm_ConverToLength(privateTokenDescription,
|
|
SHORT_PK11_STRING);
|
|
}
|
|
rv = SSM_FindUTF8StringInBundles(cx, "slotDescription", &slotDescription);
|
|
if (rv != SSM_SUCCESS) {
|
|
goto loser;
|
|
}
|
|
if (PL_strlen(slotDescription) != LONG_PK11_STRING) {
|
|
slotDescription = ssm_ConverToLength(slotDescription,
|
|
LONG_PK11_STRING);
|
|
}
|
|
rv = SSM_FindUTF8StringInBundles(cx, "privateSlotDescription",
|
|
&privateSlotDescription);
|
|
if (rv != SSM_SUCCESS) {
|
|
goto loser;
|
|
}
|
|
if (PL_strlen(privateSlotDescription) != LONG_PK11_STRING) {
|
|
privateSlotDescription = ssm_ConverToLength(privateSlotDescription,
|
|
LONG_PK11_STRING);
|
|
}
|
|
rv = SSM_FindUTF8StringInBundles(cx, "fipsSlotDescription",
|
|
&fipsSlotDescription);
|
|
if (rv != SSM_SUCCESS) {
|
|
goto loser;
|
|
}
|
|
if (PL_strlen(fipsSlotDescription) != LONG_PK11_STRING) {
|
|
fipsSlotDescription = ssm_ConverToLength(fipsSlotDescription,
|
|
LONG_PK11_STRING);
|
|
}
|
|
rv = SSM_FindUTF8StringInBundles(cx, "fipsPrivateSlotDescription",
|
|
&fipsPrivateSlotDescription);
|
|
if (rv != SSM_SUCCESS) {
|
|
goto loser;
|
|
}
|
|
if (PL_strlen(fipsPrivateSlotDescription) != LONG_PK11_STRING) {
|
|
fipsPrivateSlotDescription =
|
|
ssm_ConverToLength(fipsPrivateSlotDescription, LONG_PK11_STRING);
|
|
}
|
|
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 void
|
|
psm_signal_handler_default(int sig)
|
|
{
|
|
#ifdef DEBUG
|
|
printf ("Trapping the signal %d\n", sig);
|
|
#endif
|
|
SSM_ReleaseLockFile();
|
|
kill(getpid(),SIGKILL);
|
|
}
|
|
|
|
static void
|
|
psm_signal_handler_ignore(int sig)
|
|
{
|
|
#ifdef DEBUG
|
|
printf ("Ignoring the signal %d\n", sig);
|
|
#endif
|
|
signal(sig,psm_signal_handler_ignore);
|
|
}
|
|
|
|
static SSMStatus
|
|
psm_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)
|
|
#elif defined(XP_MAC)
|
|
/*
|
|
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.
|
|
*/
|
|
|
|
static void* glue_component = NULL;
|
|
|
|
void RunMacPSM(void *arg)
|
|
#else
|
|
int main(int argc, char ** argv)
|
|
#endif
|
|
{
|
|
#if (defined(XP_PC) && !defined(DEBUG)) || (defined(XP_MAC))
|
|
/* substitute argc and argv for NSPR */
|
|
int argc = 0;
|
|
char *argv[] = {"", NULL};
|
|
#endif
|
|
PRIntn result = 0;
|
|
|
|
#ifdef XP_MAC
|
|
glue_component = arg;
|
|
#endif
|
|
|
|
#ifdef DEBUG
|
|
PR_STDIO_INIT();
|
|
#endif
|
|
|
|
#ifdef DEBUG
|
|
/* Initialize logging. */
|
|
SSM_InitLogging();
|
|
#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 NLS layer */
|
|
if (nlsInit() != PR_TRUE) {
|
|
SSM_DEBUG("Failed to initialize the NLS layer\n");
|
|
exit(1);
|
|
}
|
|
|
|
/* 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);
|
|
}
|
|
|
|
/* initialize random number generator */
|
|
SSM_DEBUG("Initializing random number generator.\n");
|
|
RNG_RNGInit();
|
|
RNG_SystemInfoForRNG();
|
|
|
|
/*
|
|
* 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_MAC
|
|
void *
|
|
psm_malloc(unsigned long numbytes)
|
|
{
|
|
return NewPtrClear(numbytes);
|
|
}
|
|
|
|
void
|
|
psm_free(void *ptr)
|
|
{
|
|
DisposePtr((char *) ptr);
|
|
}
|
|
#endif
|
|
|
|
|
|
PRIntn mainLoop(PRIntn argc, char ** argv)
|
|
{
|
|
PRFileDesc *socket, *respsocket;
|
|
PRNetAddr clientaddr;
|
|
SSMControlConnection *curconnect;
|
|
SSMResourceID ctrlID;
|
|
SSMStatus status = PR_FAILURE;
|
|
PRBool alive = PR_TRUE;
|
|
|
|
/* Register ourselves so that logs, etc can identify us */
|
|
SSM_RegisterThread("main", NULL);
|
|
|
|
/* Open NLS stuff */
|
|
SSM_DEBUG("Initializing NLS.\n");
|
|
#ifdef XP_MAC
|
|
SSM_InitNLS(":ui:");
|
|
#else
|
|
SSM_InitNLS("ui");
|
|
#endif
|
|
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;
|
|
}
|
|
|
|
#ifdef XP_MAC
|
|
if (PR_CEnterMonitor(glue_component) != NULL) {
|
|
PR_CNotify(glue_component);
|
|
PR_CExitMonitor(glue_component);
|
|
}
|
|
#endif
|
|
|
|
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(CARTMAN_SPINTIME);
|
|
#ifdef DEBUG
|
|
printf("master: Still ready for client connection on port %d\n", CARTMAN_PORT); fflush(stdout);
|
|
#endif
|
|
respsocket = PR_Accept(socket, &clientaddr,
|
|
PR_SecondsToInterval(2));
|
|
} */
|
|
if (!respsocket) {
|
|
/* accept failed: abort */
|
|
status = PR_GetError();
|
|
SSM_DEBUG("Error %d accepting control connection. Exiting.\n",
|
|
status);
|
|
goto loser;
|
|
}
|
|
|
|
if (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 {
|
|
/* connection did not come from localhost: shut down the
|
|
* connection and continue to loop
|
|
*/
|
|
SSM_DEBUG("Connection attempt from a non-local host!\n");
|
|
status = PR_Shutdown(respsocket, PR_SHUTDOWN_BOTH);
|
|
respsocket = NULL;
|
|
}
|
|
} /* 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;
|
|
}
|