cmtinit.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 491 行

C
491
字号
/* -*- 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. */#if defined(XP_UNIX) || defined(XP_BEOS) || defined(XP_OS2)#include <sys/time.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <sys/stat.h>#ifndef XP_BEOS#include <netinet/tcp.h>#endif#else#ifdef XP_MAC#include <Events.h> // for WaitNextEvent#else /* Windows */#include <windows.h>#include <winsock.h>#include <direct.h>#include <sys/stat.h>#endif#endif#include "messages.h"#include "cmtcmn.h"#include "cmtutils.h"#include <string.h>#if defined(XP_UNIX) || defined(XP_BEOS)#define DIRECTORY_SEPARATOR '/'#elif defined(WIN32) || defined(XP_OS2)#define DIRECTORY_SEPARATOR '\\'#elif defined XP_MAC#define DIRECTORY_SEPARATOR ':'#endif/* Local defines */#define CARTMAN_PORT	11111#define MAX_PATH_LEN    256/* write to the cmnav.log */#if 0#define LOG(x); do { FILE *f; f=fopen("cmnav.log","a+"); if (f) { \   fprintf(f, x); fclose(f); } } while(0);#define LOG_S(x); do { FILE *f; f=fopen("cmnav.log","a+"); if (f) { \   fprintf(f, "%s", x); fclose(f); } } while(0);#define ASSERT(x); if (!(x)) { LOG("ASSERT:"); LOG(#x); LOG("\n"); exit(-1); }#else#define LOG(x); ;#define LOG_S(x); ;#define ASSERT(x); ;#endifstatic char*getCurrWorkDir(char *buf, int maxLen){#if defined WIN32    return _getcwd(buf, maxLen);#elif defined(XP_UNIX) || defined(XP_BEOS)    return getcwd(buf, maxLen);#else    return NULL;#endif}static voidsetWorkingDir(char *path){#if defined WIN32    _chdir(path);#elif defined(XP_UNIX) || defined(XP_BEOS)    chdir(path);#else    return;#endif}static CMTStatuslaunch_psm(char *executable){#ifndef XP_MAC    char command[MAX_PATH_LEN];#endif#ifdef WIN32    STARTUPINFO sui;    PROCESS_INFORMATION pi;    UNALIGNED long *posfhnd;    int i;    char *posfile;    sprintf(command,"%s > psmlog", executable);    ZeroMemory( &sui, sizeof(sui) );    sui.cb = sizeof(sui);    sui.cbReserved2 = (WORD)(sizeof( int ) + (3 * (sizeof( char ) +                                                    sizeof( long ))));    sui.lpReserved2 = calloc( sui.cbReserved2, 1 );    *((UNALIGNED int *)(sui.lpReserved2)) = 3;    posfile = (char *)(sui.lpReserved2 + sizeof( int ));    posfhnd = (UNALIGNED long *)(sui.lpReserved2 + sizeof( int ) +                                  (3 * sizeof( char )));        for ( i = 0, posfile = (char *)(sui.lpReserved2 + sizeof( int )),              posfhnd = (UNALIGNED long *)(sui.lpReserved2 + sizeof( int ) + (3 * sizeof( char ))) ;          i < 3 ; i++, posfile++, posfhnd++ ) {                *posfile = 0;        *posfhnd = (long)INVALID_HANDLE_VALUE;    }    /* Now, fire up PSM */    if (!CreateProcess(NULL, command, NULL, NULL, TRUE, DETACHED_PROCESS,                        NULL, NULL, &sui, &pi)) {        goto loser;    }    return CMTSuccess; loser:    return CMTFailure;#elif defined(XP_UNIX) || defined(XP_BEOS)    sprintf(command,"./%s &", executable);    if (system(command) == -1) {        goto loser;    }    return CMTSuccess; loser:    return CMTFailure;#else    return CMTFailure;#endif}PCMT_CONTROL CMT_EstablishControlConnection(char            *inPath,                                             CMT_SocketFuncs *sockFuncs,                                            CMT_MUTEX       *mutex){    PCMT_CONTROL control;#ifndef XP_MAC    char *executable;    char *newWorkingDir;    char oldWorkingDir[MAX_PATH_LEN];    size_t stringLen;#endif        int i;    char *path = NULL;    /*	On the Mac, we do special magic in the Seamonkey PSM component, so    	if PSM isn't launched by the time we reach this point, we're not doing well. */#ifndef XP_MAC    struct stat stbuf;        /*     * Create our own copy of path.     * I'd like to do a straight strdup here, but that caused problems     * for https.     */    stringLen = strlen(inPath);    path = (char*) malloc(stringLen+1);    memcpy(path, inPath, stringLen);    path[stringLen] = '\0';    control = CMT_ControlConnect(mutex, sockFuncs);    if (control != NULL) {        return control;    }    /*     * We have to try to launch it now, so it better be a valid      * path.     */    if (stat(path, &stbuf) == -1) {        goto loser;    }    /*     * Now we have to parse the path and launch the psm server.     */    executable = strrchr(path, DIRECTORY_SEPARATOR);    if (executable != NULL) {        *executable = '\0';        executable ++;        newWorkingDir = path;    } else {        executable = path;        newWorkingDir = NULL;    }    if (getCurrWorkDir(oldWorkingDir, MAX_PATH_LEN) == NULL) {        goto loser;    }    setWorkingDir(newWorkingDir);    if (launch_psm(executable) != CMTSuccess) {        goto loser;    }    setWorkingDir(oldWorkingDir);#endif    /*     * Now try to connect to the psm server.  We will try to connect     * a maximum of 30 times and then give up.     */#ifdef WIN32    for (i=0; i<30; i++) {        Sleep(1000);        control = CMT_ControlConnect(mutex, sockFuncs);        if (control != NULL) {            break;        }    }#elif defined(XP_UNIX) || defined(XP_BEOS)    i = 0;    while (i<1000) {        i += sleep(10);	control = CMT_ControlConnect(mutex, sockFuncs);	if (control != NULL) {	  break;	}    }#elif defined(XP_MAC)	for (i=0; i<30; i++) 	{		EventRecord theEvent;		WaitNextEvent(0, &theEvent, 30, NULL);		control = CMT_ControlConnect(mutex, sockFuncs);		if (control != NULL) 			break;	}#else    /*     * Figure out how to sleep for a while first     */    for (i=0; i<30; i++) {      control = CMT_ControlConnect(mutex, sockFuncs);      if (control!= NULL) {	break;      }    }#endif    if (control == NULL) {        goto loser;    }    if (path) {        free (path);    }    return control; loser:    if (control != NULL) {        CMT_CloseControlConnection(control);    }    if (path) {        free(path);    }    return NULL;}PCMT_CONTROL CMT_ControlConnect(CMT_MUTEX *mutex, CMT_SocketFuncs *sockFuncs){    PCMT_CONTROL control = NULL;     CMTSocket sock=NULL;#ifdef XP_UNIX    int unixSock = 1;    char path[20];#else    int unixSock = 0;    char *path=NULL;#endif    if (sockFuncs == NULL) {        return NULL;    }#ifdef XP_UNIX    sprintf(path, "/tmp/.nsmc-%d", (int)geteuid());#endif        sock = sockFuncs->socket(unixSock);    if (sock == NULL) {        LOG("Could not create a socket to connect to Control Connection.\n");        goto loser;    }    /* Connect to the psm process */    if (sockFuncs->connect(sock, CARTMAN_PORT, path)) {	  LOG("Could not connect to Cartman\n");	  goto loser;    }#ifdef XP_UNIX    if (sockFuncs->verify(sock) != CMTSuccess) {        goto loser;    }#endif	LOG("Connected to Cartman\n");		/* fill in the CMTControl struct */	control = (PCMT_CONTROL)calloc(sizeof(CMT_CONTROL), 1);	if (control == NULL ) {		goto loser;	}	control->sock = sock;    if (mutex != NULL) {        control->mutex = (CMT_MUTEX*)calloc(sizeof(CMT_MUTEX),1);        if (control->mutex == NULL) {            goto loser;        }        *control->mutex = *mutex;    }    memcpy(&control->sockFuncs, sockFuncs, sizeof(CMT_SocketFuncs));    control->refCount = 1;	goto done;     loser:	if (control != NULL) {		free(control);    }    if (sock != NULL) {        sockFuncs->close(sock);    }	control = NULL;     done:	return control;}CMTStatus CMT_CloseControlConnection(PCMT_CONTROL control){	/* XXX Don't know what to do here yet */    if (control != NULL) {        CMInt32 refCount;        CMT_LOCK(control->mutex);        control->refCount--;        refCount = control->refCount;        CMT_UNLOCK(control->mutex);        if (refCount <= 0) {            if (control->mutex != NULL) {                free (control->mutex);            }            control->sockFuncs.close(control->sock);            free(control);        }    }    	return CMTSuccess;}CMTStatus CMT_Hello(PCMT_CONTROL control, CMUint32 version, char* profile,                     char* profileDir){	CMTItem message;    PCMT_EVENT eventHandler;    CMBool doesUI;    HelloRequest request;    HelloReply reply;	/* Check the passed parameters */	if (!control) {		return CMTFailure;	}	if (!profile) {		return CMTFailure;	}    if (!profileDir) {        return CMTFailure;    }    	/* Create the hello message */    eventHandler = CMT_GetEventHandler(control, SSM_UI_EVENT, 0);    doesUI = (eventHandler == NULL) ? CM_FALSE : CM_TRUE;    /* Setup the request struct */    request.version = version;    request.policy = 0; /* no more policy */    request.doesUI = doesUI;    request.profile = profile;    request.profileDir = profileDir;    message.type = SSM_REQUEST_MESSAGE | SSM_HELLO_MESSAGE;    if (CMT_EncodeMessage(HelloRequestTemplate, &message, &request) != CMTSuccess) {        goto loser;    }	/* Send the message and get the response */	if (CMT_SendMessage(control, &message) != CMTSuccess) {        goto loser;	}    if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_HELLO_MESSAGE)) {        goto loser;    }    /* Decode the message */    if (CMT_DecodeMessage(HelloReplyTemplate, &reply, &message) != CMTSuccess) {        goto loser;    }	/* Successful response */	if (reply.result == 0) {            /* Save the nonce value */            control->sessionID = reply.sessionID;            control->protocolVersion = reply.version;            control->port = reply.httpPort;            control->nonce = reply.nonce;            control->policy = reply.policy;            control->serverStringVersion = reply.stringVersion;            /* XXX Free the messages */            return CMTSuccess;	}loser:	/* XXX Free the messages */	return CMTFailure;}CMTStatus CMT_PassAllPrefs(PCMT_CONTROL control, int num,                           CMTSetPrefElement* list){    SetPrefListMessage request;    SingleNumMessage reply;    CMTItem message;    if ((control == NULL) || (list == NULL)) {        return CMTFailure;    }    /* pack the request */    request.length = num;    request.list = (SetPrefElement*)list;    if (CMT_EncodeMessage(SetPrefListMessageTemplate, &message, &request) !=        CMTSuccess) {        goto loser;    }    message.type = SSM_REQUEST_MESSAGE | SSM_PREF_ACTION;    /* send the message */    if (CMT_SendMessage(control, &message) != CMTSuccess) {        goto loser;    }    if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_PREF_ACTION)) {        goto loser;    }    if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message) !=        CMTSuccess) {        goto loser;    }    /* don't really need to check the return value */    return CMTSuccess;loser:    return CMTFailure;}char* CMT_GetServerStringVersion(PCMT_CONTROL control){    if (control == NULL) {        return NULL;    }    return control->serverStringVersion;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?