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

📄 ctrlconn.c

📁 安全开发库。含客户端建立ssl连接、签名、证书验证、证书发布和撤销等。编译用到nss
💻 C
📖 第 1 页 / 共 5 页
字号:
            SSM_SendQMessage(conn->m_controlOutQ,                                   SSM_PRIORITY_SHUTDOWN,                                  SSM_DATA_PROVIDER_SHUTDOWN,                                  0, NULL, PR_TRUE);        if (conn->m_writeThread) PR_Interrupt(conn->m_writeThread);        if (conn->m_frontEndThread) PR_Interrupt(conn->m_frontEndThread);    }    /* If the front end thread is down, close the client socket */    if ((!conn->m_frontEndThread) && (conn->m_socket))    {        /* Got a socket but nothing to work on it with. Close the socket. */#ifndef XP_UNIX	/* Don't close socket with linger on UNIX since the	 * control socket on UNIX is a UNIX domain socket.	 */        SSM_DEBUG("Closing control socket with linger.\n");        trv = SSM_CloseSocketWithLinger(conn->m_socket);#else	SSM_DEBUG("Closing control socket.\n");	trv = PR_Close(conn->m_socket);#endif        PR_ASSERT(trv == PR_SUCCESS);        conn->m_socket = NULL; /* don't try closing more than once */        SSM_DEBUG("Closed control socket (rv == %d).\n",rv);    }	if (SSMRESOURCE(conn)->m_threadCount == 0)	{		/* All service threads are down. Shut down NSS. */		ssm_ShutdownNSS(conn);	}    SSM_UnlockResource(arg);    return rv;}SSMStatus SSMControlConnection_Destroy(SSMResource *res,                                       PRBool doFree){    SSMControlConnection *conn = (SSMControlConnection *) res;    void *value;    /* Drain and destroy the queue. */    if (conn->m_controlOutQ)        ssm_DrainAndDestroyQueue(&(conn->m_controlOutQ));    /* Free our fields. */    PR_FREEIF(conn->m_nonce);    PR_FREEIF(conn->m_profileName);    PR_FREEIF(conn->m_dirRoot);    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);    /* Destory the obscuring object */    if (conn->m_obscureObj) {        SSMObscure_Destroy(conn->m_obscureObj);    }    /* 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		/*  Can't just exit on the Mac, because otherwise the NSPR threads			will keep spinning forever. We have to send the app a			Quit command so that all the threads will shut down in an orderly			way. */		gTheApp->SendAEQuit();#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 (PR_CreateThread(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;                  int orv;                  /* 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);                  /* Obscure the message header */                  orv = SSMObscure_Send(ctrl->m_obscureObj, &header, sizeof(CMTMessageHeader));                  if (orv != 0) {                      goto loser;                  }                  /* 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;                  }                  /* Obscure the message body */                  orv = SSMObscure_Send(ctrl->m_obscureObj, data, len);                  if (orv != 0) {                      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.  PSM 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.

⌨️ 快捷键说明

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