⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ctrlconn.c

📁 安全开发库。含客户端建立ssl连接、签名、证书验证、证书发布和撤销等。编译用到nss
💻 C
📖 第 1 页 / 共 5 页
字号:
/* -*- 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 "ctrlconn.h"#include "dataconn.h"#include "sslconn.h"#include "p7cinfo.h"#include "p7econn.h"#include "p7dconn.h"#include "secmime.h"#include "hashconn.h"#include "certres.h"#include "cert.h"#include "certdb.h"#include "servimpl.h"#include "newproto.h"#include "messages.h"#include "serv.h"#include "ssmerrs.h"#include "minihttp.h"#include "secmod.h"#include "kgenctxt.h"#include "advisor.h"#include "processmsg.h"#include "signtextres.h"#include "p12res.h"#include "p12plcy.h"#include "secmime.h"#include "ciferfam.h"#include "profile.h"#include "prefs.h"#include "ocsp.h"#ifdef XP_MAC#include "CCompleteApp.h"#endif/* * The structure passed to get an attribute for the control connection, * which may require a password prompt. */typedef struct GetAttrArgStr {    SSMResource *res;    SSMAttributeID attrID;    SSMResourceAttrType attrType;} GetAttrArg;static SSMStatusssmcontrolconnection_encodegetattr_reply(SECItem *msg, SSMStatus rv,                                          SSMAttributeValue *value,                                         SSMResourceAttrType attrType);/* The ONLY reason why we can use these macros for both control and   data connections is that they inherit from the same superclass. */#define SSMCONNECTION(c) (&(c)->super)#define SSMRESOURCE(c) (&(c)->super.super)/* Special resource id values */#define SSM_BASE_RID  0x00000003#define SSM_MAX_RID   0x0FFFFFFFstatic long ssm_ctrl_count = 0;static SSMResourceID ssm_next_ctrlrid = SSM_MAX_RID;static char * gUserDir = NULL;int RecvInitObscureData(PRFileDesc *fd, SSMObscureObject * obj, void * buf, int bufSize );int SendInitObscureData(PRFileDesc *fd, SSMObscureObject * obj);static PRMonitor *policySetLock = NULL;static PRBool policySet = PR_FALSE;SSMStatus SSM_InitPolicyHandler(void){    policySetLock = PR_NewMonitor();    if (policySetLock == NULL) {        return PR_FAILURE;    }    return PR_SUCCESS;}#ifdef TIMEBOMB#include "timebomb.h"PRBool SSMTimeBombExpired = PR_FALSE;#endifSSMStatus SSMControlConnection_Create(void *arg,                                      SSMControlConnection * connection,                                      SSMResource **res){    SSMStatus rv = PR_SUCCESS;    SSMControlConnection *conn;    *res = NULL; /* in case we fail */        conn = (SSMControlConnection *) PR_CALLOC(sizeof(SSMControlConnection));    if (!conn) goto loser;        SSMRESOURCE(conn)->m_connection = conn;    rv = SSMControlConnection_Init(conn, SSM_RESTYPE_CONTROL_CONNECTION,                                    (PRFileDesc *) arg);    if (rv != PR_SUCCESS)         goto loser;       SSMControlConnection_Invariant(conn);    ssm_ctrl_count++;    SSM_DEBUG("Control count is now %ld.\n", ssm_ctrl_count);    *res = SSMRESOURCE(conn);    rv = SSM_HashInsert(ctrlConnections, (SSMHashKey)(*res)->m_id,                         (void *)*res);    if (rv != PR_SUCCESS)         goto loser;    return PR_SUCCESS; loser:    if (rv == PR_SUCCESS) rv = PR_FAILURE;    if (conn)     {        SSM_ShutdownResource(SSMRESOURCE(conn), rv); /* force destroy */        SSM_FreeResource(SSMRESOURCE(conn));    }           return rv;}SSMStatus SSMControlConnection_GenerateNonce(SSMControlConnection *conn){    char *n = PR_smprintf("nonce%d%d%d", rand(), rand(), rand());    conn->m_nonce = n;    return (n ? PR_SUCCESS : PR_FAILURE);}intRecvInitObscureData(PRFileDesc *fd, SSMObscureObject * obj, void * buf, int bufSize ){    SSMObscureBool done = 0;    int rv = -1;    do {	    int cc;        cc = PR_Recv(fd, buf, bufSize, 0, PR_INTERVAL_NO_TIMEOUT);        if (cc <= 0)            return -1;        rv = SSMObscure_RecvInit(obj, buf, cc, &done);    } while (!done);    return rv;}/* returns -1 on error, 0 on success. */intSendInitObscureData(PRFileDesc *fd, SSMObscureObject * obj){    unsigned char * initBuf = NULL;    int             rv      = -1;    do {        int bufLen;        int len;        int cc;        bufLen = SSMObscure_SendInit(obj, NULL);        if (bufLen <= 0)	        break;        initBuf = (unsigned char *) malloc(bufLen);        if (!initBuf)	        break;        len = SSMObscure_SendInit(obj, initBuf);        if (len != bufLen)            break;        cc = PR_Send(fd, initBuf, len, 0, PR_INTERVAL_NO_TIMEOUT);        /* Note, this code assumes a blocking socket,         ** and hence doesn't deal with short writes.        */        if (cc < len) 	        break;    	rv = 0;    } while (0);    if (initBuf) {    	free(initBuf);    	initBuf = NULL;    }    return rv;}SSMObscureObject* InitServerObscureObject(PRFileDesc *fd){    SSMObscureObject *sobj = NULL;    unsigned char buf[512];    int rv = -1;    sobj = SSMObscure_Create(1);    if (!sobj) {        goto loser;    }    rv = RecvInitObscureData(fd, sobj, buf, sizeof(buf));    if (rv < 0) {        goto loser;    }    rv = SendInitObscureData(fd, sobj);    if (rv < 0) {        goto loser;    }    return sobj;loser:    if (sobj) {        SSMObscure_Destroy(sobj);    }    return NULL;}SSMStatus SSMControlConnection_Init(SSMControlConnection *conn,                                    SSMResourceType type,                                   PRFileDesc *socket){    SSMStatus rv = PR_SUCCESS;    PRBool locked = PR_FALSE;    PRNetAddr dataAddr;    rv = SSM_HashCreate(&conn->m_resourceDB);    if (rv != PR_SUCCESS || !conn->m_resourceDB)         goto loser;    /* We need to see if there are any other control connections already     * established.  If there are, then we need to use the next RID      * as ours so the correct control connection is found for UI events.     * Before all control connections would get the RID of 3, and that would     * cause problems.     */    conn->m_lastRID = ssm_next_ctrlrid;    conn->m_secAdvisorList = NULL;    rv = SSM_HashCreate(&conn->m_resourceIdDB);    if (rv != PR_SUCCESS || conn->m_resourceIdDB == NULL)        goto loser;    rv = SSMConnection_Init(NULL, &conn->super, type);    if (rv != PR_SUCCESS) goto loser;    ssm_next_ctrlrid = conn->super.super.m_id;    SSM_LockResource(SSMRESOURCE(conn));    locked = PR_TRUE;    /* Current version. Allow this to drop when the Hello request comes in. */    conn->m_version = SSM_PROTOCOL_VERSION;    /* Generate a nonce. */    rv = SSMControlConnection_GenerateNonce(conn);    if (rv != PR_SUCCESS) goto loser;    SSM_DEBUG("Generated nonce of `%s'.\n",conn->m_nonce);    conn->m_controlOutQ = SSM_NewCollection();    if (!conn->m_controlOutQ)         goto loser;    conn->m_socket = socket;    /* Set up the protocol obscuring object */    if (!(conn->m_obscureObj = InitServerObscureObject(conn->m_socket))) {        goto loser;    }    /* Create the data socket */    conn->m_dataSocket = SSM_OpenPort();    if (!conn->m_dataSocket) {        goto loser;    }    /* Get the data port */    rv = PR_GetSockName(conn->m_dataSocket, &dataAddr);    if (rv != PR_SUCCESS) {        goto loser;    }    conn->m_dataPort = PR_ntohs(dataAddr.inet.port);    SSMCONNECTION(conn)->m_auth_func = SSMControlConnection_Authenticate;        /* Creat password handling stuff:temporary and long-term password tables */    rv = SSM_HashCreate(&conn->m_passwdTable);    if (rv != PR_SUCCESS || !conn->m_passwdTable)         goto loser;    conn->m_passwdLock = PR_NewMonitor();    if (!conn->m_passwdLock)         goto loser;    conn->m_waiting = 0;    rv = SSM_HashCreate(&conn->m_encrPasswdTable);    if (rv != PR_SUCCESS || !conn->m_encrPasswdTable)        goto loser;    conn->m_encrPasswdLock = PR_NewMonitor();    if (!conn->m_encrPasswdLock)        goto loser;    /* database for cert look-up by cert ID */    rv = SSM_HashCreate(&conn->m_certIdDB);    if (rv != PR_SUCCESS || !conn->m_certIdDB)        goto loser;    conn->m_prefs = PREF_NewPrefs();    if (conn->m_prefs == NULL) {        goto loser;    }    conn->m_doesUI = PR_FALSE;    /* Spin threads after we set the shutdown function. */    SSM_DEBUG("spawning read msg thread for %lx.\n", (long) conn);#ifdef ALLOW_STANDALONE    if (!standalone)    {#endif        /* Get reference for front end thread */        SSM_GetResourceReference(SSMRESOURCE(conn));        conn->m_frontEndThread = SSM_CreateThread(SSMRESOURCE(conn),                                                  SSM_FrontEndThread);        if (conn->m_frontEndThread == NULL)             goto loser;#ifdef ALLOW_STANDALONE    }#endif    SSM_UnlockResource(SSMRESOURCE(conn));    return PR_SUCCESS; loser:    if (rv == PR_SUCCESS) rv = PR_FAILURE;    if (locked)        SSM_UnlockResource(SSMRESOURCE(conn));    if (socket)    {        PR_Close(socket); /* close this */        conn->m_socket = NULL;    }    if (conn->m_passwdLock)         PR_DestroyMonitor(conn->m_passwdLock);    if (conn->m_passwdTable)         SSM_HashDestroy(conn->m_passwdTable);    if (conn->m_encrPasswdLock)         PR_DestroyMonitor(conn->m_encrPasswdLock);    if (conn->m_encrPasswdTable)         SSM_HashDestroy(conn->m_encrPasswdTable);    if (conn->m_certIdDB)         SSM_HashDestroy(conn->m_certIdDB);    if (conn->m_prefs)        PREF_ClosePrefs(conn->m_prefs);    if (conn->m_resourceDB)         SSM_HashDestroy(conn->m_resourceDB);    if (conn->m_resourceIdDB)        SSM_HashDestroy(conn->m_resourceIdDB);    if (conn->m_obscureObj) {        SSMObscure_Destroy(conn->m_obscureObj);    }     return rv;}SSMStatus SSMControlConnection_Shutdown(SSMResource *arg, SSMStatus status){    SSMStatus rv, trv; /* rv propagates superclass shutdown */    PRThread *closer = PR_GetCurrentThread();    SSMControlConnection *conn = (SSMControlConnection *) arg;    SSMControlConnection_Invariant(conn); #ifdef TIMEBOMB    if (SSMTimeBombExpired)      return;#endif    SSM_LockResource(arg);        /* if the thread calling this routine is a service thread,       clear its place in the connection object. this is a       prelude to the wakeup call just below. */    arg->m_threadCount--; /* decrement if service thread */    if (closer == conn->m_writeThread)        conn->m_writeThread = NULL;    if (closer == conn->m_frontEndThread)        conn->m_frontEndThread = NULL;    else        arg->m_threadCount++; /* not a service thread, restore thread count */    /* shut down our base class. */    rv = SSMConnection_Shutdown(arg, status);    /* wake up threads if this is the first time throwing an error */    if ((arg->m_status != PR_SUCCESS) &&        (rv != SSM_ERR_ALREADY_SHUT_DOWN))    {		SSM_DEBUG("First time aborting control connection.\n");		SSM_DEBUG("Posting shutdown msgs to queues.\n");        /* close queues that our threads may be listening on */        if (conn->m_controlOutQ)

⌨️ 快捷键说明

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