📄 p7dconn.c
字号:
/* PKCS7 decoding is performed by a single service thread. This thread feeds data from the outgoing queue into the PKCS7 decoder. */void SSMP7DecodeConnection_ServiceThread(void * arg){ SSMStatus rv = PR_SUCCESS; SSMP7DecodeConnection* conn; SSMControlConnection* ctrl; SECItem* msg; PRIntn read; char buffer[LINESIZE+1] = {0}; SSM_RegisterNewThread("p7decode", (SSMResource *) arg); conn = (SSMP7DecodeConnection *)arg; SSM_DEBUG("initializing.\n"); if (!arg) { PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); goto loser; } SSMDATACONNECTION(conn)->m_dataServiceThread = PR_GetCurrentThread(); /* set up the client data socket and authenticate it with nonce */ rv = SSMDataConnection_SetupClientSocket(SSMDATACONNECTION(conn)); if (rv != PR_SUCCESS) { goto loser; } /* Start decoding */ SSM_DEBUG("Start updating decoder..\n"); while ((SSMRESOURCE(conn)->m_status == PR_SUCCESS) && (SSM_Count(SSMDATACONNECTION(conn)->m_shutdownQ) == 0) && (rv == PR_SUCCESS)) { read = LINESIZE; /* set the read size to the default line size */ rv = SSMDataConnection_ReadFromSocket(SSMDATACONNECTION(conn), (PRInt32*)&read, buffer); if (read > 0) { /* there is data, pass it along to PKCS7 */ SSM_DEBUG("Received %ld bytes of data for decoder.\n", read); PR_ASSERT(conn->m_context); if (SEC_PKCS7DecoderUpdate(conn->m_context, buffer, read) != SECSuccess) { conn->m_error = PR_GetError(); goto finish; } } else { /* either EOF or an error condition */ /* If we have a decoder in progress, stop it. */ SSM_LockResource(SSMRESOURCE(conn)); if (conn->m_context) { SSM_DEBUG("Stopping PKCS7 decoder, generating content info struct.\n"); SSMP7DecodeConnection_FinishDecoding(conn); } SSM_UnlockResource(SSMRESOURCE(conn)); break; } }finish: /* we have an EOF, shut down the client socket */ PR_ASSERT(SSMDATACONNECTION(conn)->m_clientSocket != NULL); if (SSMDATACONNECTION(conn)->m_clientSocket != NULL) { SSM_DEBUG("shutting down client socket.\n"); SSM_LockResource(SSMRESOURCE(conn)); PR_Shutdown(SSMDATACONNECTION(conn)->m_clientSocket, PR_SHUTDOWN_SEND); SSM_UnlockResource(SSMRESOURCE(conn)); } /* If we've been asked to return the result, return it. */ if (SSMDATACONNECTION(conn)->m_sendResult) { SSM_DEBUG("Responding to deferred content info request.\n"); msg = (SECItem*)PORT_ZAlloc(sizeof(SECItem)); PR_ASSERT(msg != NULL); /* need to have some preallocated failure to send */ if (conn->m_cinfo) { SSMAttributeValue value; GetAttribReply reply; value.type = SSM_RID_ATTRIBUTE; rv = SSM_ClientGetResourceReference(&conn->m_cinfo->super, &value.u.rid); if (rv != PR_SUCCESS) { goto loser; } msg->type = (SECItemType) (SSM_REPLY_OK_MESSAGE | SSM_RESOURCE_ACTION | SSM_GET_ATTRIBUTE | SSM_RID_ATTRIBUTE); reply.result = SSM_SUCCESS; reply.value = value; if (CMT_EncodeMessage(GetAttribReplyTemplate, (CMTItem*)msg, &reply) != CMTSuccess) { goto loser; } SSM_DEBUG("Generated a reply (t %lx/l %ld/d %lx)\n", msg->type, msg->len, msg->data); /* * We don't need the content info anymore since we sent it back * Is it OK to release our reference? */ SSM_FreeResource(&conn->m_cinfo->super); conn->m_cinfo = NULL; } else { SingleNumMessage reply; msg->type = (SECItemType) (SSM_REPLY_ERR_MESSAGE | SSM_RESOURCE_ACTION | SSM_GET_ATTRIBUTE | SSM_STRING_ATTRIBUTE); reply.value = SSM_ERR_ATTRIBUTE_MISSING; if (CMT_EncodeMessage(SingleNumMessageTemplate, (CMTItem*)msg, &reply) != CMTSuccess) { goto loser; } SSM_DEBUG("Generated error reply (t %lx/l %ld/d %lx)\n", msg->type, msg->len, msg->data); } /* Post this message to the parent's control queue for delivery back to the client. */ ctrl = (SSMControlConnection*)(SSMCONNECTION(conn)->m_parent); PR_ASSERT(SSM_IsAKindOf(&ctrl->super.super, SSM_RESTYPE_CONTROL_CONNECTION)); rv = SSM_SendQMessage(ctrl->m_controlOutQ, SSM_PRIORITY_NORMAL, msg->type, msg->len, (char*)msg->data, PR_TRUE); SSM_FreeMessage(msg); if (rv != PR_SUCCESS) goto loser; } loser: SSM_DEBUG("** Thread shutting down ** (%ld)\n", rv); if (conn != NULL) { SSM_ShutdownResource(SSMRESOURCE(conn), rv); SSM_FreeResource(SSMRESOURCE(conn)); }}SSMStatus SSMP7DecodeConnection_GetAttrIDs(SSMResource *res, SSMAttributeID **ids, PRIntn *count){ SSMStatus rv; rv = SSMDataConnection_GetAttrIDs(res, ids, count); if (rv != PR_SUCCESS) goto loser; *ids = (SSMAttributeID *) PR_REALLOC(*ids, (*count + 1) * sizeof(SSMAttributeID)); if (! *ids) goto loser; (*ids)[*count++] = SSM_FID_P7CONN_CONTENT_INFO; goto done; loser: if (rv == PR_SUCCESS) rv = PR_FAILURE; done: return rv;}SSMStatus SSMP7DecodeConnection_GetAttr(SSMResource *res, SSMAttributeID attrID, SSMResourceAttrType attrType, SSMAttributeValue *value){ SSMStatus rv = PR_SUCCESS; SSMP7DecodeConnection *dc = (SSMP7DecodeConnection *) res; SSMP7DecodeConnection_Invariant(dc); /* see what it is */ switch(attrID) { case SSM_FID_P7CONN_CONTENT_INFO: if (!dc->m_cinfo) { goto loser; } /* Allocate a resource ID */ value->type = SSM_RID_ATTRIBUTE; rv = SSM_ClientGetResourceReference(&dc->m_cinfo->super, &value->u.rid); if (rv != PR_SUCCESS) goto loser; /* Let's get rid of our reference to it and let the client inherit it. */ SSM_LockResource(res); SSM_FreeResource(&dc->m_cinfo->super); dc->m_cinfo = NULL; SSM_UnlockResource(res); break; case SSM_FID_RESOURCE_ERROR: value->type = SSM_NUMERIC_ATTRIBUTE; value->u.numeric = dc->m_error; break; default: rv = SSMDataConnection_GetAttr(res,attrID,attrType,value); if (rv != PR_SUCCESS) goto loser; } goto done; loser: value->type = SSM_NO_ATTRIBUTE; if (rv == PR_SUCCESS) rv = PR_FAILURE; done: return rv;}/* Callback functions for decoder. For now, use empty/default functions. */void SSMP7DecodeConnection_ContentCallback(void *arg, const char *buf, unsigned long len){ SSMStatus rv; SSMP7DecodeConnection *conn = (SSMP7DecodeConnection *)arg; PRIntn sent = 0; SSM_DEBUG("writing data to socket.\n"); PR_ASSERT(SSMDATACONNECTION(conn)->m_clientSocket != NULL); sent = PR_Send(SSMDATACONNECTION(conn)->m_clientSocket, (void*)buf, (PRIntn)len, 0, PR_INTERVAL_NO_TIMEOUT); if (sent != (PRIntn)len) { rv = PR_GetError(); SSM_DEBUG("error writing data: %d \n", rv); }}PK11SymKey * SSMP7DecodeConnection_GetDecryptKey(void *arg, SECAlgorithmID *algid){ return NULL;}PRBool SSMP7DecodeConnection_DecryptionAllowed(SECAlgorithmID *algid, PK11SymKey *bulkkey){ return SECMIME_DecryptionAllowed(algid, bulkkey);}SECItem * SSMP7DecodeConnection_GetPasswordKey(void *arg, SECKEYKeyDBHandle *handle){ return NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -