ctrlconn.c

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

C
2,170
字号
    PR_DestroyMonitor(conn->m_passwdLock);    PR_DestroyMonitor(conn->m_encrPasswdLock);    SSM_HashDestroy(conn->m_passwdTable);    SSM_HashDestroy(conn->m_encrPasswdTable);    PREF_ClosePrefs(conn->m_prefs);        /* log out all pk11 slots for now */    if (conn->m_pkcs11Init) {        PK11_LogoutAll();    }    if (conn->m_secAdvisorList)      SECITEM_ZfreeItem(conn->m_secAdvisorList, PR_TRUE);    /* Destroy superclass fields. */    SSMConnection_Destroy(SSMRESOURCE(conn), PR_FALSE);    SSM_HashRemove(ctrlConnections,                    (SSMHashKey)(conn->super.super.m_id), &value);                                    /* If this is the last control connection, quit. */    --ssm_ctrl_count;    SSM_DEBUG("Control count is now %ld.\n", ssm_ctrl_count);    if ((ssm_ctrl_count <= 0)#ifdef DEBUG        && (PR_GetEnv("NSM_SUPPRESS_EXIT") == NULL)#endif        )    {        SSM_DEBUG("Last control connection gone, quitting.\n");#ifdef XP_UNIX	SSM_ReleaseLockFile();#endif#ifdef XP_MAC		SetQuitFlag(PR_TRUE); // tell primordial thread to quit#else        exit(0);#endif    }    /* Free the connection object if asked. */    if (doFree)        PR_DELETE(conn);    return PR_SUCCESS;}SSMStatus SSMControlConnection_GetAttrIDs(SSMResource* res,										 SSMAttributeID** ids, PRIntn* count){    SSMStatus rv;	if (res == NULL || ids == NULL || count == NULL) {		goto loser;	}    rv = SSMConnection_GetAttrIDs(res, ids, count);    if (rv != PR_SUCCESS) {        goto loser;	}    *ids = (SSMAttributeID *) PR_REALLOC(*ids, (*count + 2)*sizeof(SSMAttributeID));    if (!*ids) {		goto loser;	}    (*ids)[*count++] = SSM_FID_DEFAULT_EMAIL_SIGNER_CERT;    (*ids)[*count++] = SSM_FID_DEFAULT_EMAIL_RECIPIENT_CERT;    goto done;loser:    if (rv == PR_SUCCESS) {		rv = PR_FAILURE;	}done:    return rv;}static void ssmcontrolconnection_getattr_thread(void* inArg){    GetAttrArg *arg = (GetAttrArg*)inArg;    SSMResource *res = arg->res;    SSMAttributeID attrID = arg->attrID;    SSMResourceAttrType attrType = arg->attrType;    SSMControlConnection* conn = (SSMControlConnection*)res;    SSMStatus rv = PR_SUCCESS;    CERTCertificate *cert = NULL;    SSMResourceCert *certRes;    SSMResourceID certID = 0;    char *certNickname = NULL;    PRBool locked = PR_FALSE;    SSMAttributeValue realValue, *value;    SECItem msg;    value = &realValue;    /* see what it is */#ifdef DEBUG    SSM_RegisterThread("ctrlconn getattr",NULL);#endif        switch(attrID) {    case SSM_FID_DEFAULT_EMAIL_SIGNER_CERT:        SSM_LockResource(SSMRESOURCE(conn));        locked = PR_TRUE;        rv = PREF_GetStringPref(conn->m_prefs, "security.default_mail_cert",                                 &certNickname);        if (rv != PR_SUCCESS) {            goto loser;        }        if (certNickname) {            cert = CERT_FindUserCertByUsage(conn->m_certdb,                                            certNickname,                                            certUsageEmailSigner,                                            PR_FALSE,                                            conn);            if (cert) {                SSM_CreateResource(SSM_RESTYPE_CERTIFICATE, cert, conn,                                   &certID, (SSMResource**)&certRes);                rv = SSM_ClientGetResourceReference(&certRes->super, &certID);                SSM_FreeResource(&certRes->super);                if (rv != SSM_SUCCESS)                    goto loser;            }        }        if (cert == NULL)            goto loser;        value->u.rid = certID;        value->type = SSM_RID_ATTRIBUTE;        SSM_UnlockResource(SSMRESOURCE(conn));        locked = PR_FALSE;        break;    case SSM_FID_DEFAULT_EMAIL_RECIPIENT_CERT:        SSM_LockResource(SSMRESOURCE(conn));        locked = PR_TRUE;        rv = PREF_GetStringPref(conn->m_prefs, "security.default_mail_cert",                                 &certNickname);        if (rv != PR_SUCCESS) {            goto loser;        }        if (certNickname) {            cert = CERT_FindUserCertByUsage(conn->m_certdb,                                            certNickname,                                            certUsageEmailRecipient,                                            PR_FALSE,                                            conn);            if (cert) {                SSM_CreateResource(SSM_RESTYPE_CERTIFICATE, cert, conn,                                   &certID, (SSMResource**)&certRes);                rv = SSM_ClientGetResourceReference(&certRes->super, &certID);                SSM_FreeResource(&certRes->super);                if (rv != SSM_SUCCESS)                    goto loser;            }        }        value->u.rid = certID;        value->type = SSM_RID_ATTRIBUTE;        SSM_UnlockResource(SSMRESOURCE(conn));        locked = PR_FALSE;		break;    default:        rv = SSMConnection_GetAttr(res, attrID, attrType, value);        if (rv != PR_SUCCESS) {			goto loser;		}    }    if (value->type != attrType) {        goto loser;    }    goto done;loser:    value->type = SSM_NO_ATTRIBUTE;    if (rv == PR_SUCCESS) {		rv = PR_FAILURE;	}done:    if (locked) {        SSM_UnlockResource(SSMRESOURCE(conn));    }    rv = ssmcontrolconnection_encodegetattr_reply(&msg, rv, value,                                                  attrType);    if (rv != SSM_SUCCESS) {        rv = ssmcontrolconnection_encode_err_reply(&msg, rv);        PR_ASSERT(rv == SSM_SUCCESS);    }    ssmcontrolconnection_send_message_to_client(conn, &msg);    PR_FREEIF(msg.data);    SSM_FreeResource(res);}SSMStatus SSMControlConnection_GetAttr(SSMResource *res, SSMAttributeID attrID,                                       SSMResourceAttrType attrType,                                       SSMAttributeValue *value){    GetAttrArg *arg = NULL;    if (res == NULL || value == NULL) {        goto loser;    }    arg = SSM_NEW(GetAttrArg);    if (arg == NULL) {        goto loser;    }    arg->res = res;    arg->attrID = attrID;    arg->attrType = attrType;    if (SSM_CreateAndRegisterThread(PR_USER_THREAD, ssmcontrolconnection_getattr_thread,                         (void *)arg, PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,                        PR_UNJOINABLE_THREAD, 0) == NULL) {        goto loser;    }    return SSM_ERR_DEFER_RESPONSE; loser:    if (arg != NULL) {        PR_Free(arg);    }    return SSM_FAILURE;}voidSSMControlConnection_Invariant(SSMControlConnection *conn){    if (conn)    {        SSMConnection_Invariant(SSMCONNECTION(conn));        SSM_LockResource(SSMRESOURCE(conn));        PR_ASSERT(SSM_IsAKindOf(SSMRESOURCE(conn), SSM_RESTYPE_CONTROL_CONNECTION));        PR_ASSERT(conn->m_controlOutQ != NULL);        SSM_UnlockResource(SSMRESOURCE(conn));    }}void SSMControlConnection_RecycleItem(SECItem* msg){    PR_ASSERT(msg != NULL);    if (msg->data != NULL) {        cmt_free(msg->data);        msg->data = NULL;    }    return;}/* * Read msgs from the control connection queue and send them back to client */void SSM_WriteCtrlThread(void * arg){    PRIntn sent, len, type;    SSMControlConnection * ctrl    = NULL;    SSMStatus rv= PR_FAILURE;    char * data;#ifdef TIMEBOMB    if (SSMTimeBombExpired)      return;#endif     ctrl = (SSMControlConnection *)arg;    SSM_RegisterNewThread("ctrl write", (SSMResource*) arg);    SSM_DEBUG("initializing.\n");    if (!ctrl)    {        rv = (SSMStatus) PR_INVALID_ARGUMENT_ERROR;        goto loser;    }    if (!ctrl->m_socket)         {        rv = (SSMStatus) PR_INVALID_ARGUMENT_ERROR;        goto loser;    }    ctrl->m_writeThread = PR_GetCurrentThread();    /* wait for SSM_DATA_PROVIDER_OPEN message */    rv = SSM_RecvQMessage(ctrl->m_controlOutQ,                           SSM_PRIORITY_ANY,                          &type, &len, &data,                           PR_TRUE);    if (rv != PR_SUCCESS || type != SSM_DATA_PROVIDER_OPEN)        goto loser;    SSM_DEBUG("got queue open message.\n");      /* look for data in the incoming queue and send it to the client */    while ((SSMRESOURCE(ctrl)->m_status == PR_SUCCESS) && (rv == PR_SUCCESS))    {        rv = SSM_RecvQMessage(ctrl->m_controlOutQ,                               SSM_PRIORITY_ANY,                              &type, &len, &data,                               PR_TRUE);        if (rv != PR_SUCCESS)        {            SSM_DEBUG("Couldn't read or block on outgoing queue (%d).\n",		      rv);            goto loser;	    }        switch (type)         {          case SSM_DATA_PROVIDER_SHUTDOWN:              SSM_DEBUG("got queue close message.\n");              goto loser;          default:              {                  CMTMessageHeader header;                  /* got a regular control message. send it to the client */                  SSM_DEBUG("got message for client (type=%lx,len=%ld).\n",                             type, len);                  header.type = PR_htonl(type);                  header.len = PR_htonl(len);                  /* Send the message header */                  sent = SSM_WriteThisMany(ctrl->m_socket, &header, sizeof(CMTMessageHeader));                  if (sent != sizeof(CMTMessageHeader)) {                      rv = (SSMStatus) PR_GetError();                      SSM_DEBUG("cannot send message type: %d.\n", rv);                      goto loser;                  }                  /* Send the message body */                  sent = SSM_WriteThisMany(ctrl->m_socket, data, len);                  if (sent != len)                   {                      rv = (SSMStatus) PR_GetError();                      SSM_DEBUG("cannot send message data: %d.\n", rv);                    goto loser;                  }                  PR_Free(data);              }              break;        }  /* end of switch */    } /* end of while alive loop */   loser:     if (ctrl)    {        SSM_DEBUG("Shutting down, rv = %d.\n", rv);        SSM_ShutdownResource(SSMRESOURCE(ctrl), rv);        SSM_FreeResource(SSMRESOURCE(ctrl));    }    return;}/*  * Check if given cert (arg) already exists in our cert resource db. */void SSMControlConnection_CertLookUp(SSMControlConnection * connection,                                      void * arg, SSMResource ** res){    PR_ASSERT(res);    SSM_HashFind(connection->m_certIdDB, (SSMHashKey) arg, (void **)res);    if (*res != NULL)        SSM_GetResourceReference(*res);}/* NSS_Init does not open the cert and key db's read/write.  Cartman needs * them to be opened read/write in order to do key gen's and import  * certificate chains. * * For now, we pretty much re-create the code of NSS_Init in this file.  If * NSS_Init is ever modified so that we can open the db's read/write, then * we just call the new function from the function SSM_InitNSS. */static char *ssm_certdb_name_cb(void *arg, int dbVersion){    const char *configdir = (const char*)arg;    const char *dbver;    switch (dbVersion) {    case 7:      dbver = "7";      break;    case 6:      dbver = "6";      break;    case 5:      dbver = "5";      break;    case 4:    default:      dbver = "";      break;    }#ifdef XP_MAC	/* on Mac, :: means parent directory. does non-Mac get // with Seamonkey? */    if(configdir[PL_strlen(configdir) - 1] == ':') {    	return PR_smprintf("%sCertificates%s", configdir, dbver);    } else {    	return PR_smprintf("%s:Certificates%s", configdir, dbver);    }#else    return PR_smprintf("%s/cert%s.db", configdir, dbver);#endif}static char *ssm_keydb_name_cb(void *arg, int dbVersion){    const char *configdir = (const char*)arg;    const char *dbver;    switch (dbVersion) {    case 3:      dbver = "3";      break;    case 2:    default:      dbver = "";      break;    }#ifdef XP_MAC    if (configdir[PL_strlen(configdir) - 1] == ':') {    	return PR_smprintf("%sKey Database%s", configdir, dbver);    } else {    	return PR_smprintf("%s:Key Database%s", configdir, dbver);    }#else    return PR_smprintf("%s/key%s.db", configdir, dbver);#endif}SECStatusssm_OpenCertDB(const char * configdir,SSMControlConnection *ctrl){    CERTCertDBHandle *certdb;    SECStatus         status = SECFailure;#ifdef ALLOW_STANDALONE    PRBool readonly = standalone;#else

⌨️ 快捷键说明

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