Index: mozilla/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapdefaultclient.c |
=================================================================== |
--- mozilla/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapdefaultclient.c (revision 191424) |
+++ mozilla/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapdefaultclient.c (working copy) |
@@ -1,2493 +0,0 @@ |
-/* This Source Code Form is subject to the terms of the Mozilla Public |
- * License, v. 2.0. If a copy of the MPL was not distributed with this |
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
-/* |
- * pkix_pl_ldapdefaultclient.c |
- * |
- * LDAPDefaultClient Function Definitions |
- * |
- */ |
- |
-/* We can't decode the length of a message without at least this many bytes */ |
-#define MINIMUM_MSG_LENGTH 5 |
- |
-#include "pkix_pl_ldapdefaultclient.h" |
- |
-/* --Private-LdapDefaultClient-Message-Building-Functions---------------- */ |
- |
-/* |
- * FUNCTION: pkix_pl_LdapDefaultClient_MakeBind |
- * DESCRIPTION: |
- * |
- * This function creates and encodes a Bind message, using the arena pointed |
- * to by "arena", the version number contained in "versionData", the |
- * LDAPBindAPI pointed to by "bindAPI", and the messageID contained in |
- * "msgNum", and stores a pointer to the encoded string at "pBindMsg". |
- * |
- * See pkix_pl_ldaptemplates.c for the ASN.1 description of a Bind message. |
- * |
- * This code is not used if the DefaultClient was created with a NULL pointer |
- * supplied for the LDAPBindAPI structure. (Bind and Unbind do not seem to be |
- * expected for anonymous Search requests.) |
- * |
- * PARAMETERS: |
- * "arena" |
- * The address of the PRArenaPool used in encoding the message. Must be |
- * non-NULL. |
- * "versionData" |
- * The Int32 containing the version number to be encoded in the Bind |
- * message. |
- * "bindAPI" |
- * The address of the LDAPBindAPI to be encoded in the Bind message. Must |
- * be non-NULL. |
- * "msgNum" |
- * The Int32 containing the MessageID to be encoded in the Bind message. |
- * "pBindMsg" |
- * The address at which the encoded Bind message will be stored. Must be |
- * non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a LdapDefaultClient Error if the function fails in a |
- * non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-static PKIX_Error * |
-pkix_pl_LdapDefaultClient_MakeBind( |
- PRArenaPool *arena, |
- PKIX_Int32 versionData, |
- LDAPBindAPI *bindAPI, |
- PKIX_UInt32 msgNum, |
- SECItem **pBindMsg, |
- void *plContext) |
-{ |
- LDAPMessage msg; |
- char version = '\0'; |
- SECItem *encoded = NULL; |
- PKIX_UInt32 len = 0; |
- |
- PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_MakeBind"); |
- PKIX_NULLCHECK_TWO(arena, pBindMsg); |
- |
- PKIX_PL_NSSCALL(LDAPDEFAULTCLIENT, PORT_Memset, |
- (&msg, 0, sizeof (LDAPMessage))); |
- |
- version = (char)versionData; |
- |
- msg.messageID.type = siUnsignedInteger; |
- msg.messageID.data = (void*)&msgNum; |
- msg.messageID.len = sizeof (msgNum); |
- |
- msg.protocolOp.selector = LDAP_BIND_TYPE; |
- |
- msg.protocolOp.op.bindMsg.version.type = siUnsignedInteger; |
- msg.protocolOp.op.bindMsg.version.data = (void *)&version; |
- msg.protocolOp.op.bindMsg.version.len = sizeof (char); |
- |
- /* |
- * XXX At present we only know how to handle anonymous requests (no |
- * authentication), and we are guessing how to do simple authentication. |
- * This section will need to be revised and extended when other |
- * authentication is needed. |
- */ |
- if (bindAPI->selector == SIMPLE_AUTH) { |
- msg.protocolOp.op.bindMsg.bindName.type = siAsciiString; |
- msg.protocolOp.op.bindMsg.bindName.data = |
- (void *)bindAPI->chooser.simple.bindName; |
- len = PL_strlen(bindAPI->chooser.simple.bindName); |
- msg.protocolOp.op.bindMsg.bindName.len = len; |
- |
- msg.protocolOp.op.bindMsg.authentication.type = siAsciiString; |
- msg.protocolOp.op.bindMsg.authentication.data = |
- (void *)bindAPI->chooser.simple.authentication; |
- len = PL_strlen(bindAPI->chooser.simple.authentication); |
- msg.protocolOp.op.bindMsg.authentication.len = len; |
- } |
- |
- PKIX_PL_NSSCALLRV(LDAPDEFAULTCLIENT, encoded, SEC_ASN1EncodeItem, |
- (arena, NULL, (void *)&msg, PKIX_PL_LDAPMessageTemplate)); |
- if (!encoded) { |
- PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED); |
- } |
- |
- *pBindMsg = encoded; |
-cleanup: |
- |
- PKIX_RETURN(LDAPDEFAULTCLIENT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_LdapDefaultClient_MakeUnbind |
- * DESCRIPTION: |
- * |
- * This function creates and encodes a Unbind message, using the arena pointed |
- * to by "arena" and the messageID contained in "msgNum", and stores a pointer |
- * to the encoded string at "pUnbindMsg". |
- * |
- * See pkix_pl_ldaptemplates.c for the ASN.1 description of an Unbind message. |
- * |
- * This code is not used if the DefaultClient was created with a NULL pointer |
- * supplied for the LDAPBindAPI structure. (Bind and Unbind do not seem to be |
- * expected for anonymous Search requests.) |
- * |
- * PARAMETERS: |
- * "arena" |
- * The address of the PRArenaPool used in encoding the message. Must be |
- * non-NULL. |
- * "msgNum" |
- * The Int32 containing the MessageID to be encoded in the Unbind message. |
- * "pUnbindMsg" |
- * The address at which the encoded Unbind message will be stored. Must |
- * be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a LdapDefaultClient Error if the function fails in a |
- * non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-static PKIX_Error * |
-pkix_pl_LdapDefaultClient_MakeUnbind( |
- PRArenaPool *arena, |
- PKIX_UInt32 msgNum, |
- SECItem **pUnbindMsg, |
- void *plContext) |
-{ |
- LDAPMessage msg; |
- SECItem *encoded = NULL; |
- |
- PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_MakeUnbind"); |
- PKIX_NULLCHECK_TWO(arena, pUnbindMsg); |
- |
- PKIX_PL_NSSCALL(LDAPDEFAULTCLIENT, PORT_Memset, |
- (&msg, 0, sizeof (LDAPMessage))); |
- |
- msg.messageID.type = siUnsignedInteger; |
- msg.messageID.data = (void*)&msgNum; |
- msg.messageID.len = sizeof (msgNum); |
- |
- msg.protocolOp.selector = LDAP_UNBIND_TYPE; |
- |
- msg.protocolOp.op.unbindMsg.dummy.type = siBuffer; |
- msg.protocolOp.op.unbindMsg.dummy.data = NULL; |
- msg.protocolOp.op.unbindMsg.dummy.len = 0; |
- |
- PKIX_PL_NSSCALLRV(LDAPDEFAULTCLIENT, encoded, SEC_ASN1EncodeItem, |
- (arena, NULL, (void *)&msg, PKIX_PL_LDAPMessageTemplate)); |
- if (!encoded) { |
- PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED); |
- } |
- |
- *pUnbindMsg = encoded; |
-cleanup: |
- |
- PKIX_RETURN(LDAPDEFAULTCLIENT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_LdapDefaultClient_MakeAbandon |
- * DESCRIPTION: |
- * |
- * This function creates and encodes a Abandon message, using the arena pointed |
- * to by "arena" and the messageID contained in "msgNum", and stores a pointer |
- * to the encoded string at "pAbandonMsg". |
- * |
- * See pkix_pl_ldaptemplates.c for the ASN.1 description of an Abandon message. |
- * |
- * PARAMETERS: |
- * "arena" |
- * The address of the PRArenaPool used in encoding the message. Must be |
- * non-NULL. |
- * "msgNum" |
- * The Int32 containing the MessageID to be encoded in the Abandon message. |
- * "pAbandonMsg" |
- * The address at which the encoded Abandon message will be stored. Must |
- * be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a LdapDefaultClient Error if the function fails in a |
- * non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-static PKIX_Error * |
-pkix_pl_LdapDefaultClient_MakeAbandon( |
- PRArenaPool *arena, |
- PKIX_UInt32 msgNum, |
- SECItem **pAbandonMsg, |
- void *plContext) |
-{ |
- LDAPMessage msg; |
- SECItem *encoded = NULL; |
- |
- PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_MakeAbandon"); |
- PKIX_NULLCHECK_TWO(arena, pAbandonMsg); |
- |
- PKIX_PL_NSSCALL(LDAPDEFAULTCLIENT, PORT_Memset, |
- (&msg, 0, sizeof (LDAPMessage))); |
- |
- msg.messageID.type = siUnsignedInteger; |
- msg.messageID.data = (void*)&msgNum; |
- msg.messageID.len = sizeof (msgNum); |
- |
- msg.protocolOp.selector = LDAP_ABANDONREQUEST_TYPE; |
- |
- msg.protocolOp.op.abandonRequestMsg.messageID.type = siBuffer; |
- msg.protocolOp.op.abandonRequestMsg.messageID.data = (void*)&msgNum; |
- msg.protocolOp.op.abandonRequestMsg.messageID.len = sizeof (msgNum); |
- |
- PKIX_PL_NSSCALLRV(LDAPDEFAULTCLIENT, encoded, SEC_ASN1EncodeItem, |
- (arena, NULL, (void *)&msg, PKIX_PL_LDAPMessageTemplate)); |
- if (!encoded) { |
- PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED); |
- } |
- |
- *pAbandonMsg = encoded; |
-cleanup: |
- |
- PKIX_RETURN(LDAPDEFAULTCLIENT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_LdapDefaultClient_DecodeBindResponse |
- * DESCRIPTION: |
- * |
- * This function decodes the encoded data pointed to by "src", using the arena |
- * pointed to by "arena", storing the decoded LDAPMessage at "pBindResponse" |
- * and the decoding status at "pStatus". |
- * |
- * PARAMETERS: |
- * "arena" |
- * The address of the PRArenaPool to be used in decoding the message. Must |
- * be non-NULL. |
- * "src" |
- * The address of the SECItem containing the DER- (or BER-)encoded string. |
- * Must be non-NULL. |
- * "pBindResponse" |
- * The address at which the LDAPMessage is stored, if the decoding is |
- * successful (the returned status is SECSuccess). Must be non-NULL. |
- * "pStatus" |
- * The address at which the decoding status is stored. Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a LdapDefaultClient Error if the function fails in a |
- * non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-static PKIX_Error * |
-pkix_pl_LdapDefaultClient_DecodeBindResponse( |
- PRArenaPool *arena, |
- SECItem *src, |
- LDAPMessage *pBindResponse, |
- SECStatus *pStatus, |
- void *plContext) |
-{ |
- SECStatus rv = SECFailure; |
- LDAPMessage response; |
- |
- PKIX_ENTER |
- (LDAPDEFAULTCLIENT, |
- "pkix_pl_LdapDefaultClient_DecodeBindResponse"); |
- PKIX_NULLCHECK_FOUR(arena, src, pBindResponse, pStatus); |
- |
- PKIX_PL_NSSCALL |
- (LDAPDEFAULTCLIENT, |
- PORT_Memset, |
- (&response, 0, sizeof (LDAPMessage))); |
- |
- PKIX_PL_NSSCALLRV(LDAPDEFAULTCLIENT, rv, SEC_ASN1DecodeItem, |
- (arena, &response, PKIX_PL_LDAPMessageTemplate, src)); |
- |
- if (rv == SECSuccess) { |
- *pBindResponse = response; |
- } |
- |
- *pStatus = rv; |
- |
- PKIX_RETURN(LDAPDEFAULTCLIENT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_LdapDefaultClient_VerifyBindResponse |
- * DESCRIPTION: |
- * |
- * This function verifies that the contents of the message in the rcvbuf of |
- * the LdapDefaultClient object pointed to by "client", and whose length is |
- * provided by "buflen", is a response to a successful Bind. |
- * |
- * PARAMETERS: |
- * "client" |
- * The address of the LdapDefaultClient object. Must be non-NULL. |
- * "buflen" |
- * The value of the number of bytes in the receive buffer. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a LdapDefaultClient Error if the function fails in a |
- * non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-static PKIX_Error * |
-pkix_pl_LdapDefaultClient_VerifyBindResponse( |
- PKIX_PL_LdapDefaultClient *client, |
- PKIX_UInt32 bufLen, |
- void *plContext) |
-{ |
- SECItem decode = {siBuffer, NULL, 0}; |
- SECStatus rv = SECFailure; |
- LDAPMessage msg; |
- LDAPBindResponse *ldapBindResponse = NULL; |
- |
- PKIX_ENTER |
- (LDAPDEFAULTCLIENT, |
- "pkix_pl_LdapDefaultClient_VerifyBindResponse"); |
- PKIX_NULLCHECK_TWO(client, client->rcvBuf); |
- |
- decode.data = (void *)(client->rcvBuf); |
- decode.len = bufLen; |
- |
- PKIX_CHECK(pkix_pl_LdapDefaultClient_DecodeBindResponse |
- (client->arena, &decode, &msg, &rv, plContext), |
- PKIX_LDAPDEFAULTCLIENTDECODEBINDRESPONSEFAILED); |
- |
- if (rv == SECSuccess) { |
- ldapBindResponse = &msg.protocolOp.op.bindResponseMsg; |
- if (*(ldapBindResponse->resultCode.data) == SUCCESS) { |
- client->connectStatus = BOUND; |
- } else { |
- PKIX_ERROR(PKIX_BINDREJECTEDBYSERVER); |
- } |
- } else { |
- PKIX_ERROR(PKIX_CANTDECODEBINDRESPONSEFROMSERVER); |
- } |
- |
-cleanup: |
- |
- PKIX_RETURN(LDAPDEFAULTCLIENT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_LdapDefaultClient_RecvCheckComplete |
- * DESCRIPTION: |
- * |
- * This function determines whether the current response in the |
- * LdapDefaultClient pointed to by "client" is complete, in the sense that all |
- * bytes required to satisfy the message length field in the encoding have been |
- * received. If so, the pointer to input data is updated to reflect the number |
- * of bytes consumed, provided by "bytesProcessed". The state machine flag |
- * pointed to by "pKeepGoing" is updated to indicate whether processing can |
- * continue without further input. |
- * |
- * PARAMETERS: |
- * "client" |
- * The address of the LdapDefaultClient object. Must be non-NULL. |
- * "bytesProcessed" |
- * The UInt32 value of the number of bytes consumed from the current |
- * buffer. |
- * "pKeepGoing" |
- * The address at which the Boolean state machine flag is stored to |
- * indicate whether processing can continue without further input. |
- * Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a LdapDefaultClient Error if the function fails in a |
- * non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-static PKIX_Error * |
-pkix_pl_LdapDefaultClient_RecvCheckComplete( |
- PKIX_PL_LdapDefaultClient *client, |
- PKIX_UInt32 bytesProcessed, |
- PKIX_Boolean *pKeepGoing, |
- void *plContext) |
-{ |
- PKIX_Boolean complete = PKIX_FALSE; |
- SECStatus rv = SECFailure; |
- LDAPMessageType messageType = 0; |
- LDAPResultCode resultCode = 0; |
- |
- PKIX_ENTER |
- (LDAPDEFAULTCLIENT, |
- "pkix_pl_LdapDefaultClient_RecvCheckComplete"); |
- PKIX_NULLCHECK_TWO(client, pKeepGoing); |
- |
- PKIX_CHECK(pkix_pl_LdapResponse_IsComplete |
- (client->currentResponse, &complete, plContext), |
- PKIX_LDAPRESPONSEISCOMPLETEFAILED); |
- |
- if (complete) { |
- PKIX_CHECK(pkix_pl_LdapResponse_Decode |
- (client->arena, client->currentResponse, &rv, plContext), |
- PKIX_LDAPRESPONSEDECODEFAILED); |
- |
- if (rv != SECSuccess) { |
- PKIX_ERROR(PKIX_CANTDECODESEARCHRESPONSEFROMSERVER); |
- } |
- |
- PKIX_CHECK(pkix_pl_LdapResponse_GetMessageType |
- (client->currentResponse, &messageType, plContext), |
- PKIX_LDAPRESPONSEGETMESSAGETYPEFAILED); |
- |
- if (messageType == LDAP_SEARCHRESPONSEENTRY_TYPE) { |
- |
- if (client->entriesFound == NULL) { |
- PKIX_CHECK(PKIX_List_Create |
- (&(client->entriesFound), plContext), |
- PKIX_LISTCREATEFAILED); |
- } |
- |
- PKIX_CHECK(PKIX_List_AppendItem |
- (client->entriesFound, |
- (PKIX_PL_Object *)client->currentResponse, |
- plContext), |
- PKIX_LISTAPPENDITEMFAILED); |
- |
- PKIX_DECREF(client->currentResponse); |
- |
- /* current receive buffer empty? */ |
- if (client->currentBytesAvailable == 0) { |
- client->connectStatus = RECV; |
- *pKeepGoing = PKIX_TRUE; |
- } else { |
- client->connectStatus = RECV_INITIAL; |
- client->currentInPtr = &((char *) |
- (client->currentInPtr))[bytesProcessed]; |
- *pKeepGoing = PKIX_TRUE; |
- } |
- |
- } else if (messageType == LDAP_SEARCHRESPONSERESULT_TYPE) { |
- PKIX_CHECK(pkix_pl_LdapResponse_GetResultCode |
- (client->currentResponse, |
- &resultCode, |
- plContext), |
- PKIX_LDAPRESPONSEGETRESULTCODEFAILED); |
- |
- if ((client->entriesFound == NULL) && |
- ((resultCode == SUCCESS) || |
- (resultCode == NOSUCHOBJECT))) { |
- PKIX_CHECK(PKIX_List_Create |
- (&(client->entriesFound), plContext), |
- PKIX_LISTCREATEFAILED); |
- } else if (resultCode == SUCCESS) { |
- PKIX_CHECK(PKIX_List_SetImmutable |
- (client->entriesFound, plContext), |
- PKIX_LISTSETIMMUTABLEFAILED); |
- PKIX_CHECK(PKIX_PL_HashTable_Add |
- (client->cachePtr, |
- (PKIX_PL_Object *)client->currentRequest, |
- (PKIX_PL_Object *)client->entriesFound, |
- plContext), |
- PKIX_HASHTABLEADDFAILED); |
- } else { |
- PKIX_ERROR(PKIX_UNEXPECTEDRESULTCODEINRESPONSE); |
- } |
- |
- client->connectStatus = BOUND; |
- *pKeepGoing = PKIX_FALSE; |
- PKIX_DECREF(client->currentResponse); |
- |
- } else { |
- PKIX_ERROR(PKIX_SEARCHRESPONSEPACKETOFUNKNOWNTYPE); |
- } |
- } else { |
- client->connectStatus = RECV; |
- *pKeepGoing = PKIX_TRUE; |
- } |
- |
-cleanup: |
- PKIX_RETURN(LDAPDEFAULTCLIENT); |
-} |
- |
-/* --Private-LdapDefaultClient-Object-Functions------------------------- */ |
- |
-static PKIX_Error * |
-pkix_pl_LdapDefaultClient_InitiateRequest( |
- PKIX_PL_LdapClient *client, |
- LDAPRequestParams *requestParams, |
- void **pPollDesc, |
- PKIX_List **pResponse, |
- void *plContext); |
- |
-static PKIX_Error * |
-pkix_pl_LdapDefaultClient_ResumeRequest( |
- PKIX_PL_LdapClient *client, |
- void **pPollDesc, |
- PKIX_List **pResponse, |
- void *plContext); |
- |
-/* |
- * FUNCTION: pkix_pl_LdapDefaultClient_CreateHelper |
- * DESCRIPTION: |
- * |
- * This function creates a new LdapDefaultClient using the Socket pointed to |
- * by "socket", the PRIntervalTime pointed to by "timeout", and the |
- * LDAPBindAPI pointed to by "bindAPI", and stores the result at "pClient". |
- * |
- * A value of zero for "timeout" means the LDAPClient will use non-blocking |
- * I/O. |
- * |
- * PARAMETERS: |
- * "socket" |
- * Address of the Socket to be used for the client. Must be non-NULL. |
- * "bindAPI" |
- * The address of the LDAPBindAPI containing the Bind information to be |
- * encoded in the Bind message. |
- * "pClient" |
- * The address at which the created LdapDefaultClient is to be stored. |
- * Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a LdapDefaultClient Error if the function fails in |
- * a non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-PKIX_Error * |
-pkix_pl_LdapDefaultClient_CreateHelper( |
- PKIX_PL_Socket *socket, |
- LDAPBindAPI *bindAPI, |
- PKIX_PL_LdapDefaultClient **pClient, |
- void *plContext) |
-{ |
- PKIX_PL_HashTable *ht; |
- PKIX_PL_LdapDefaultClient *ldapDefaultClient = NULL; |
- PKIX_PL_Socket_Callback *callbackList; |
- PRFileDesc *fileDesc = NULL; |
- PRArenaPool *arena = NULL; |
- |
- PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_CreateHelper"); |
- PKIX_NULLCHECK_TWO(socket, pClient); |
- |
- PKIX_CHECK(PKIX_PL_Object_Alloc |
- (PKIX_LDAPDEFAULTCLIENT_TYPE, |
- sizeof (PKIX_PL_LdapDefaultClient), |
- (PKIX_PL_Object **)&ldapDefaultClient, |
- plContext), |
- PKIX_COULDNOTCREATELDAPDEFAULTCLIENTOBJECT); |
- |
- ldapDefaultClient->vtable.initiateFcn = |
- pkix_pl_LdapDefaultClient_InitiateRequest; |
- ldapDefaultClient->vtable.resumeFcn = |
- pkix_pl_LdapDefaultClient_ResumeRequest; |
- |
- PKIX_CHECK(pkix_pl_Socket_GetPRFileDesc |
- (socket, &fileDesc, plContext), |
- PKIX_SOCKETGETPRFILEDESCFAILED); |
- |
- ldapDefaultClient->pollDesc.fd = fileDesc; |
- ldapDefaultClient->pollDesc.in_flags = 0; |
- ldapDefaultClient->pollDesc.out_flags = 0; |
- |
- ldapDefaultClient->bindAPI = bindAPI; |
- |
- PKIX_CHECK(PKIX_PL_HashTable_Create |
- (LDAP_CACHEBUCKETS, 0, &ht, plContext), |
- PKIX_HASHTABLECREATEFAILED); |
- |
- ldapDefaultClient->cachePtr = ht; |
- |
- PKIX_CHECK(pkix_pl_Socket_GetCallbackList |
- (socket, &callbackList, plContext), |
- PKIX_SOCKETGETCALLBACKLISTFAILED); |
- |
- ldapDefaultClient->callbackList = callbackList; |
- |
- PKIX_INCREF(socket); |
- ldapDefaultClient->clientSocket = socket; |
- |
- ldapDefaultClient->messageID = 0; |
- |
- ldapDefaultClient->bindAPI = bindAPI; |
- |
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
- if (!arena) { |
- PKIX_ERROR_FATAL(PKIX_OUTOFMEMORY); |
- } |
- ldapDefaultClient->arena = arena; |
- |
- ldapDefaultClient->sendBuf = NULL; |
- ldapDefaultClient->bytesToWrite = 0; |
- |
- PKIX_CHECK(PKIX_PL_Malloc |
- (RCVBUFSIZE, &ldapDefaultClient->rcvBuf, plContext), |
- PKIX_MALLOCFAILED); |
- ldapDefaultClient->capacity = RCVBUFSIZE; |
- |
- ldapDefaultClient->bindMsg = NULL; |
- ldapDefaultClient->bindMsgLen = 0; |
- |
- ldapDefaultClient->entriesFound = NULL; |
- ldapDefaultClient->currentRequest = NULL; |
- ldapDefaultClient->currentResponse = NULL; |
- |
- *pClient = ldapDefaultClient; |
- |
-cleanup: |
- |
- if (PKIX_ERROR_RECEIVED) { |
- PKIX_DECREF(ldapDefaultClient); |
- } |
- |
- PKIX_RETURN(LDAPDEFAULTCLIENT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_LdapDefaultClient_Create |
- * DESCRIPTION: |
- * |
- * This function creates a new LdapDefaultClient using the PRNetAddr pointed to |
- * by "sockaddr", the PRIntervalTime pointed to by "timeout", and the |
- * LDAPBindAPI pointed to by "bindAPI", and stores the result at "pClient". |
- * |
- * A value of zero for "timeout" means the LDAPClient will use non-blocking |
- * I/O. |
- * |
- * PARAMETERS: |
- * "sockaddr" |
- * Address of the PRNetAddr to be used for the socket connection. Must be |
- * non-NULL. |
- * "timeout" |
- * The PRIntervalTime to be used in I/O requests for this client. |
- * "bindAPI" |
- * The address of the LDAPBindAPI containing the Bind information to be |
- * encoded in the Bind message. |
- * "pClient" |
- * The address at which the created LdapDefaultClient is to be stored. |
- * Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a LdapDefaultClient Error if the function fails in |
- * a non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-PKIX_Error * |
-PKIX_PL_LdapDefaultClient_Create( |
- PRNetAddr *sockaddr, |
- PRIntervalTime timeout, |
- LDAPBindAPI *bindAPI, |
- PKIX_PL_LdapDefaultClient **pClient, |
- void *plContext) |
-{ |
- PRErrorCode status = 0; |
- PKIX_PL_Socket *socket = NULL; |
- PKIX_PL_LdapDefaultClient *client = NULL; |
- |
- PKIX_ENTER(LDAPDEFAULTCLIENT, "PKIX_PL_LdapDefaultClient_Create"); |
- PKIX_NULLCHECK_TWO(sockaddr, pClient); |
- |
- PKIX_CHECK(pkix_pl_Socket_Create |
- (PKIX_FALSE, timeout, sockaddr, &status, &socket, plContext), |
- PKIX_SOCKETCREATEFAILED); |
- |
- PKIX_CHECK(pkix_pl_LdapDefaultClient_CreateHelper |
- (socket, bindAPI, &client, plContext), |
- PKIX_LDAPDEFAULTCLIENTCREATEHELPERFAILED); |
- |
- /* Did Socket_Create say the connection was made? */ |
- if (status == 0) { |
- if (client->bindAPI != NULL) { |
- client->connectStatus = CONNECTED; |
- } else { |
- client->connectStatus = BOUND; |
- } |
- } else { |
- client->connectStatus = CONNECT_PENDING; |
- } |
- |
- *pClient = client; |
- |
-cleanup: |
- if (PKIX_ERROR_RECEIVED) { |
- PKIX_DECREF(client); |
- } |
- |
- PKIX_DECREF(socket); |
- |
- PKIX_RETURN(LDAPDEFAULTCLIENT); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_LdapDefaultClient_CreateByName |
- * DESCRIPTION: |
- * |
- * This function creates a new LdapDefaultClient using the hostname pointed to |
- * by "hostname", the PRIntervalTime pointed to by "timeout", and the |
- * LDAPBindAPI pointed to by "bindAPI", and stores the result at "pClient". |
- * |
- * A value of zero for "timeout" means the LDAPClient will use non-blocking |
- * I/O. |
- * |
- * PARAMETERS: |
- * "hostname" |
- * Address of the hostname to be used for the socket connection. Must be |
- * non-NULL. |
- * "timeout" |
- * The PRIntervalTime to be used in I/O requests for this client. |
- * "bindAPI" |
- * The address of the LDAPBindAPI containing the Bind information to be |
- * encoded in the Bind message. |
- * "pClient" |
- * The address at which the created LdapDefaultClient is to be stored. |
- * Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a LdapDefaultClient Error if the function fails in |
- * a non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-PKIX_Error * |
-PKIX_PL_LdapDefaultClient_CreateByName( |
- char *hostname, |
- PRIntervalTime timeout, |
- LDAPBindAPI *bindAPI, |
- PKIX_PL_LdapDefaultClient **pClient, |
- void *plContext) |
-{ |
- PRErrorCode status = 0; |
- PKIX_PL_Socket *socket = NULL; |
- PKIX_PL_LdapDefaultClient *client = NULL; |
- |
- PKIX_ENTER(LDAPDEFAULTCLIENT, "PKIX_PL_LdapDefaultClient_CreateByName"); |
- PKIX_NULLCHECK_TWO(hostname, pClient); |
- |
- PKIX_CHECK(pkix_pl_Socket_CreateByName |
- (PKIX_FALSE, timeout, hostname, &status, &socket, plContext), |
- PKIX_SOCKETCREATEBYNAMEFAILED); |
- |
- PKIX_CHECK(pkix_pl_LdapDefaultClient_CreateHelper |
- (socket, bindAPI, &client, plContext), |
- PKIX_LDAPDEFAULTCLIENTCREATEHELPERFAILED); |
- |
- /* Did Socket_Create say the connection was made? */ |
- if (status == 0) { |
- if (client->bindAPI != NULL) { |
- client->connectStatus = CONNECTED; |
- } else { |
- client->connectStatus = BOUND; |
- } |
- } else { |
- client->connectStatus = CONNECT_PENDING; |
- } |
- |
- *pClient = client; |
- |
-cleanup: |
- if (PKIX_ERROR_RECEIVED) { |
- PKIX_DECREF(client); |
- } |
- |
- PKIX_DECREF(socket); |
- |
- PKIX_RETURN(LDAPDEFAULTCLIENT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_LdapDefaultClient_Destroy |
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) |
- */ |
-static PKIX_Error * |
-pkix_pl_LdapDefaultClient_Destroy( |
- PKIX_PL_Object *object, |
- void *plContext) |
-{ |
- PKIX_Int32 bytesWritten = 0; |
- PKIX_PL_LdapDefaultClient *client = NULL; |
- PKIX_PL_Socket_Callback *callbackList = NULL; |
- SECItem *encoded = NULL; |
- |
- PKIX_ENTER(LDAPDEFAULTCLIENT, |
- "pkix_pl_LdapDefaultClient_Destroy"); |
- PKIX_NULLCHECK_ONE(object); |
- |
- PKIX_CHECK(pkix_CheckType |
- (object, PKIX_LDAPDEFAULTCLIENT_TYPE, plContext), |
- PKIX_OBJECTNOTANLDAPDEFAULTCLIENT); |
- |
- client = (PKIX_PL_LdapDefaultClient *)object; |
- |
- switch (client->connectStatus) { |
- case CONNECT_PENDING: |
- break; |
- case CONNECTED: |
- case BIND_PENDING: |
- case BIND_RESPONSE: |
- case BIND_RESPONSE_PENDING: |
- case BOUND: |
- case SEND_PENDING: |
- case RECV: |
- case RECV_PENDING: |
- case RECV_INITIAL: |
- case RECV_NONINITIAL: |
- case ABANDON_PENDING: |
- if (client->bindAPI != NULL) { |
- PKIX_CHECK(pkix_pl_LdapDefaultClient_MakeUnbind |
- (client->arena, |
- ++(client->messageID), |
- &encoded, |
- plContext), |
- PKIX_LDAPDEFAULTCLIENTMAKEUNBINDFAILED); |
- |
- callbackList = |
- (PKIX_PL_Socket_Callback *)(client->callbackList); |
- PKIX_CHECK(callbackList->sendCallback |
- (client->clientSocket, |
- encoded->data, |
- encoded->len, |
- &bytesWritten, |
- plContext), |
- PKIX_SOCKETSENDFAILED); |
- } |
- break; |
- default: |
- PKIX_ERROR(PKIX_LDAPDEFAULTCLIENTINILLEGALSTATE); |
- } |
- |
- PKIX_DECREF(client->cachePtr); |
- PKIX_DECREF(client->clientSocket); |
- PKIX_DECREF(client->entriesFound); |
- PKIX_DECREF(client->currentRequest); |
- PKIX_DECREF(client->currentResponse); |
- |
- PKIX_CHECK(PKIX_PL_Free |
- (client->rcvBuf, plContext), PKIX_FREEFAILED); |
- |
- PKIX_PL_NSSCALL |
- (LDAPDEFAULTCLIENT, |
- PORT_FreeArena, |
- (client->arena, PR_FALSE)); |
- |
-cleanup: |
- |
- PKIX_RETURN(LDAPDEFAULTCLIENT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_LdapDefaultClient_Hashcode |
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h) |
- */ |
-static PKIX_Error * |
-pkix_pl_LdapDefaultClient_Hashcode( |
- PKIX_PL_Object *object, |
- PKIX_UInt32 *pHashcode, |
- void *plContext) |
-{ |
- PKIX_PL_LdapDefaultClient *ldapDefaultClient = NULL; |
- PKIX_UInt32 tempHash = 0; |
- |
- PKIX_ENTER |
- (LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_Hashcode"); |
- PKIX_NULLCHECK_TWO(object, pHashcode); |
- |
- PKIX_CHECK(pkix_CheckType |
- (object, PKIX_LDAPDEFAULTCLIENT_TYPE, plContext), |
- PKIX_OBJECTNOTANLDAPDEFAULTCLIENT); |
- |
- ldapDefaultClient = (PKIX_PL_LdapDefaultClient *)object; |
- |
- PKIX_CHECK(PKIX_PL_Object_Hashcode |
- ((PKIX_PL_Object *)ldapDefaultClient->clientSocket, |
- &tempHash, |
- plContext), |
- PKIX_SOCKETHASHCODEFAILED); |
- |
- if (ldapDefaultClient->bindAPI != NULL) { |
- tempHash = (tempHash << 7) + |
- ldapDefaultClient->bindAPI->selector; |
- } |
- |
- *pHashcode = tempHash; |
- |
-cleanup: |
- |
- PKIX_RETURN(LDAPDEFAULTCLIENT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_LdapDefaultClient_Equals |
- * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h) |
- */ |
-static PKIX_Error * |
-pkix_pl_LdapDefaultClient_Equals( |
- PKIX_PL_Object *firstObject, |
- PKIX_PL_Object *secondObject, |
- PKIX_Int32 *pResult, |
- void *plContext) |
-{ |
- PKIX_PL_LdapDefaultClient *firstClientContext = NULL; |
- PKIX_PL_LdapDefaultClient *secondClientContext = NULL; |
- PKIX_Int32 compare = 0; |
- |
- PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_Equals"); |
- PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult); |
- |
- *pResult = PKIX_FALSE; |
- |
- PKIX_CHECK(pkix_CheckTypes |
- (firstObject, |
- secondObject, |
- PKIX_LDAPDEFAULTCLIENT_TYPE, |
- plContext), |
- PKIX_OBJECTNOTANLDAPDEFAULTCLIENT); |
- |
- firstClientContext = (PKIX_PL_LdapDefaultClient *)firstObject; |
- secondClientContext = (PKIX_PL_LdapDefaultClient *)secondObject; |
- |
- if (firstClientContext == secondClientContext) { |
- *pResult = PKIX_TRUE; |
- goto cleanup; |
- } |
- |
- PKIX_CHECK(PKIX_PL_Object_Equals |
- ((PKIX_PL_Object *)firstClientContext->clientSocket, |
- (PKIX_PL_Object *)secondClientContext->clientSocket, |
- &compare, |
- plContext), |
- PKIX_SOCKETEQUALSFAILED); |
- |
- if (!compare) { |
- goto cleanup; |
- } |
- |
- if (PKIX_EXACTLY_ONE_NULL |
- (firstClientContext->bindAPI, secondClientContext->bindAPI)) { |
- goto cleanup; |
- } |
- |
- if (firstClientContext->bindAPI) { |
- if (firstClientContext->bindAPI->selector != |
- secondClientContext->bindAPI->selector) { |
- goto cleanup; |
- } |
- } |
- |
- *pResult = PKIX_TRUE; |
- |
-cleanup: |
- |
- PKIX_RETURN(LDAPDEFAULTCLIENT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_LdapDefaultClient_RegisterSelf |
- * |
- * DESCRIPTION: |
- * Registers PKIX_PL_LDAPDEFAULTCLIENT_TYPE and its related |
- * functions with systemClasses[] |
- * |
- * THREAD SAFETY: |
- * Not Thread Safe - for performance and complexity reasons |
- * |
- * Since this function is only called by PKIX_PL_Initialize, which should |
- * only be called once, it is acceptable that this function is not |
- * thread-safe. |
- */ |
-PKIX_Error * |
-pkix_pl_LdapDefaultClient_RegisterSelf(void *plContext) |
-{ |
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; |
- pkix_ClassTable_Entry entry; |
- |
- PKIX_ENTER |
- (LDAPDEFAULTCLIENT, |
- "pkix_pl_LdapDefaultClient_RegisterSelf"); |
- |
- entry.description = "LdapDefaultClient"; |
- entry.objCounter = 0; |
- entry.typeObjectSize = sizeof(PKIX_PL_LdapDefaultClient); |
- entry.destructor = pkix_pl_LdapDefaultClient_Destroy; |
- entry.equalsFunction = pkix_pl_LdapDefaultClient_Equals; |
- entry.hashcodeFunction = pkix_pl_LdapDefaultClient_Hashcode; |
- entry.toStringFunction = NULL; |
- entry.comparator = NULL; |
- entry.duplicateFunction = NULL; |
- |
- systemClasses[PKIX_LDAPDEFAULTCLIENT_TYPE] = entry; |
- |
- PKIX_RETURN(LDAPDEFAULTCLIENT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_LdapDefaultClient_GetPollDesc |
- * DESCRIPTION: |
- * |
- * This function retrieves the PRPollDesc from the LdapDefaultClient |
- * pointed to by "context" and stores the address at "pPollDesc". |
- * |
- * PARAMETERS: |
- * "context" |
- * The LdapDefaultClient whose PRPollDesc is desired. Must be non-NULL. |
- * "pPollDesc" |
- * Address where PRPollDesc will be stored. Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-PKIX_Error * |
-pkix_pl_LdapDefaultClient_GetPollDesc( |
- PKIX_PL_LdapDefaultClient *context, |
- PRPollDesc **pPollDesc, |
- void *plContext) |
-{ |
- PKIX_ENTER |
- (LDAPDEFAULTCLIENT, |
- "pkix_pl_LdapDefaultClient_GetPollDesc"); |
- PKIX_NULLCHECK_TWO(context, pPollDesc); |
- |
- *pPollDesc = &(context->pollDesc); |
- |
- PKIX_RETURN(LDAPDEFAULTCLIENT); |
-} |
- |
-/* --Private-Ldap-CertStore-I/O-Functions---------------------------- */ |
-/* |
- * FUNCTION: pkix_pl_LdapDefaultClient_ConnectContinue |
- * DESCRIPTION: |
- * |
- * This function determines whether a socket Connect initiated earlier for the |
- * CertStore embodied in the LdapDefaultClient "client" has completed, and |
- * stores in "pKeepGoing" a flag indicating whether processing can continue |
- * without further input. |
- * |
- * PARAMETERS: |
- * "client" |
- * The address of the LdapDefaultClient object. Must be non-NULL. |
- * "pKeepGoing" |
- * The address at which the Boolean state machine flag is stored to |
- * indicate whether processing can continue without further input. |
- * Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a LdapDefaultClient Error if the function fails in a |
- * non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-static PKIX_Error * |
-pkix_pl_LdapDefaultClient_ConnectContinue( |
- PKIX_PL_LdapDefaultClient *client, |
- PKIX_Boolean *pKeepGoing, |
- void *plContext) |
-{ |
- PKIX_PL_Socket_Callback *callbackList; |
- PRErrorCode status; |
- PKIX_Boolean keepGoing = PKIX_FALSE; |
- |
- PKIX_ENTER |
- (LDAPDEFAULTCLIENT, |
- "pkix_pl_LdapDefaultClient_ConnectContinue"); |
- PKIX_NULLCHECK_ONE(client); |
- |
- callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList); |
- |
- PKIX_CHECK(callbackList->connectcontinueCallback |
- (client->clientSocket, &status, plContext), |
- PKIX_SOCKETCONNECTCONTINUEFAILED); |
- |
- if (status == 0) { |
- if (client->bindAPI != NULL) { |
- client->connectStatus = CONNECTED; |
- } else { |
- client->connectStatus = BOUND; |
- } |
- keepGoing = PKIX_FALSE; |
- } else if (status != PR_IN_PROGRESS_ERROR) { |
- PKIX_ERROR(PKIX_UNEXPECTEDERRORINESTABLISHINGCONNECTION); |
- } |
- |
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache |
- ((PKIX_PL_Object *)client, plContext), |
- PKIX_OBJECTINVALIDATECACHEFAILED); |
- |
- *pKeepGoing = keepGoing; |
- |
-cleanup: |
- PKIX_RETURN(LDAPDEFAULTCLIENT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_LdapDefaultClient_Bind |
- * DESCRIPTION: |
- * |
- * This function creates and sends the LDAP-protocol Bind message for the |
- * CertStore embodied in the LdapDefaultClient "client", and stores in |
- * "pKeepGoing" a flag indicating whether processing can continue without |
- * further input. |
- * |
- * PARAMETERS: |
- * "client" |
- * The address of the LdapDefaultClient object. Must be non-NULL. |
- * "pKeepGoing" |
- * The address at which the Boolean state machine flag is stored to |
- * indicate whether processing can continue without further input. |
- * Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a LdapDefaultClient Error if the function fails in a |
- * non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-static PKIX_Error * |
-pkix_pl_LdapDefaultClient_Bind( |
- PKIX_PL_LdapDefaultClient *client, |
- PKIX_Boolean *pKeepGoing, |
- void *plContext) |
-{ |
- SECItem *encoded = NULL; |
- PKIX_Int32 bytesWritten = 0; |
- PKIX_PL_Socket_Callback *callbackList; |
- |
- PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_Bind"); |
- PKIX_NULLCHECK_ONE(client); |
- |
- /* if we have not yet constructed the BIND message, build it now */ |
- if (!(client->bindMsg)) { |
- PKIX_CHECK(pkix_pl_LdapDefaultClient_MakeBind |
- (client->arena, |
- 3, |
- client->bindAPI, |
- client->messageID, |
- &encoded, |
- plContext), |
- PKIX_LDAPDEFAULTCLIENTMAKEBINDFAILED); |
- client->bindMsg = encoded->data; |
- client->bindMsgLen = encoded->len; |
- } |
- |
- callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList); |
- |
- PKIX_CHECK(callbackList->sendCallback |
- (client->clientSocket, |
- client->bindMsg, |
- client->bindMsgLen, |
- &bytesWritten, |
- plContext), |
- PKIX_SOCKETSENDFAILED); |
- |
- client->lastIO = PR_Now(); |
- |
- if (bytesWritten < 0) { |
- client->connectStatus = BIND_PENDING; |
- *pKeepGoing = PKIX_FALSE; |
- } else { |
- client->connectStatus = BIND_RESPONSE; |
- *pKeepGoing = PKIX_TRUE; |
- } |
- |
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache |
- ((PKIX_PL_Object *)client, plContext), |
- PKIX_OBJECTINVALIDATECACHEFAILED); |
- |
-cleanup: |
- PKIX_RETURN(LDAPDEFAULTCLIENT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_LdapDefaultClient_BindContinue |
- * DESCRIPTION: |
- * |
- * This function determines whether the LDAP-protocol Bind message for the |
- * CertStore embodied in the LdapDefaultClient "client" has completed, and |
- * stores in "pKeepGoing" a flag indicating whether processing can continue |
- * without further input. |
- * |
- * PARAMETERS: |
- * "client" |
- * The address of the LdapDefaultClient object. Must be non-NULL. |
- * "pKeepGoing" |
- * The address at which the Boolean state machine flag is stored to |
- * indicate whether processing can continue without further input. |
- * Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a LdapDefaultClient Error if the function fails in a |
- * non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-PKIX_Error *pkix_pl_LdapDefaultClient_BindContinue( |
- PKIX_PL_LdapDefaultClient *client, |
- PKIX_Boolean *pKeepGoing, |
- void *plContext) |
-{ |
- PKIX_Int32 bytesWritten = 0; |
- PKIX_PL_Socket_Callback *callbackList = NULL; |
- |
- PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_BindContinue"); |
- PKIX_NULLCHECK_ONE(client); |
- |
- *pKeepGoing = PKIX_FALSE; |
- |
- callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList); |
- |
- PKIX_CHECK(callbackList->pollCallback |
- (client->clientSocket, &bytesWritten, NULL, plContext), |
- PKIX_SOCKETPOLLFAILED); |
- |
- /* |
- * If the send completed we can proceed to try for the |
- * response. If the send did not complete we will have |
- * continue to poll. |
- */ |
- if (bytesWritten >= 0) { |
- |
- client->connectStatus = BIND_RESPONSE; |
- |
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache |
- ((PKIX_PL_Object *)client, plContext), |
- PKIX_OBJECTINVALIDATECACHEFAILED); |
- |
- *pKeepGoing = PKIX_TRUE; |
- } |
- |
-cleanup: |
- PKIX_RETURN(LDAPDEFAULTCLIENT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_LdapDefaultClient_BindResponse |
- * DESCRIPTION: |
- * |
- * This function attempts to read the LDAP-protocol BindResponse message for |
- * the CertStore embodied in the LdapDefaultClient "client", and stores in |
- * "pKeepGoing" a flag indicating whether processing can continue without |
- * further input. |
- * |
- * If a BindResponse is received with a Result code of 0 (success), we |
- * continue with the connection. If a non-zero Result code is received, |
- * we throw an Error. Some more sophisticated handling of that condition |
- * might be in order in the future. |
- * |
- * PARAMETERS: |
- * "client" |
- * The address of the LdapDefaultClient object. Must be non-NULL. |
- * "pKeepGoing" |
- * The address at which the Boolean state machine flag is stored to |
- * indicate whether processing can continue without further input. |
- * Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a LdapDefaultClient Error if the function fails in a |
- * non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-static PKIX_Error * |
-pkix_pl_LdapDefaultClient_BindResponse( |
- PKIX_PL_LdapDefaultClient *client, |
- PKIX_Boolean *pKeepGoing, |
- void *plContext) |
-{ |
- PKIX_Int32 bytesRead = 0; |
- PKIX_PL_Socket_Callback *callbackList = NULL; |
- |
- PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_BindResponse"); |
- PKIX_NULLCHECK_TWO(client, client->rcvBuf); |
- |
- callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList); |
- |
- PKIX_CHECK(callbackList->recvCallback |
- (client->clientSocket, |
- client->rcvBuf, |
- client->capacity, |
- &bytesRead, |
- plContext), |
- PKIX_SOCKETRECVFAILED); |
- |
- client->lastIO = PR_Now(); |
- |
- if (bytesRead > 0) { |
- PKIX_CHECK(pkix_pl_LdapDefaultClient_VerifyBindResponse |
- (client, bytesRead, plContext), |
- PKIX_LDAPDEFAULTCLIENTVERIFYBINDRESPONSEFAILED); |
- /* |
- * XXX What should we do if failure? At present if |
- * VerifyBindResponse throws an Error, we do too. |
- */ |
- client->connectStatus = BOUND; |
- } else { |
- client->connectStatus = BIND_RESPONSE_PENDING; |
- } |
- |
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache |
- ((PKIX_PL_Object *)client, plContext), |
- PKIX_OBJECTINVALIDATECACHEFAILED); |
- |
- *pKeepGoing = PKIX_TRUE; |
- |
-cleanup: |
- PKIX_RETURN(LDAPDEFAULTCLIENT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_LdapDefaultClient_BindResponseContinue |
- * DESCRIPTION: |
- * |
- * This function determines whether the LDAP-protocol BindResponse message for |
- * the CertStore embodied in the LdapDefaultClient "client" has completed, and |
- * stores in "pKeepGoing" a flag indicating whether processing can continue |
- * without further input. |
- * |
- * PARAMETERS: |
- * "client" |
- * The address of the LdapDefaultClient object. Must be non-NULL. |
- * "pKeepGoing" |
- * The address at which the Boolean state machine flag is stored to |
- * indicate whether processing can continue without further input. |
- * Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a LdapDefaultClient Error if the function fails in a |
- * non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-static PKIX_Error * |
-pkix_pl_LdapDefaultClient_BindResponseContinue( |
- PKIX_PL_LdapDefaultClient *client, |
- PKIX_Boolean *pKeepGoing, |
- void *plContext) |
-{ |
- PKIX_Int32 bytesRead = 0; |
- PKIX_PL_Socket_Callback *callbackList = NULL; |
- |
- PKIX_ENTER |
- (LDAPDEFAULTCLIENT, |
- "pkix_pl_LdapDefaultClient_BindResponseContinue"); |
- PKIX_NULLCHECK_ONE(client); |
- |
- callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList); |
- |
- PKIX_CHECK(callbackList->pollCallback |
- (client->clientSocket, NULL, &bytesRead, plContext), |
- PKIX_SOCKETPOLLFAILED); |
- |
- if (bytesRead > 0) { |
- PKIX_CHECK(pkix_pl_LdapDefaultClient_VerifyBindResponse |
- (client, bytesRead, plContext), |
- PKIX_LDAPDEFAULTCLIENTVERIFYBINDRESPONSEFAILED); |
- client->connectStatus = BOUND; |
- |
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache |
- ((PKIX_PL_Object *)client, plContext), |
- PKIX_OBJECTINVALIDATECACHEFAILED); |
- |
- *pKeepGoing = PKIX_TRUE; |
- } else { |
- *pKeepGoing = PKIX_FALSE; |
- } |
- |
-cleanup: |
- PKIX_RETURN(LDAPDEFAULTCLIENT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_LdapDefaultClient_Send |
- * DESCRIPTION: |
- * |
- * This function creates and sends an LDAP-protocol message for the |
- * CertStore embodied in the LdapDefaultClient "client", and stores in |
- * "pKeepGoing" a flag indicating whether processing can continue without |
- * further input, and at "pBytesTransferred" the number of bytes sent. |
- * |
- * If "pBytesTransferred" is zero, it indicates that non-blocking I/O is in use |
- * and that transmission has not completed. |
- * |
- * PARAMETERS: |
- * "client" |
- * The address of the LdapDefaultClient object. Must be non-NULL. |
- * "pKeepGoing" |
- * The address at which the Boolean state machine flag is stored to |
- * indicate whether processing can continue without further input. |
- * Must be non-NULL. |
- * "pBytesTransferred" |
- * The address at which the number of bytes sent is stored. Must be |
- * non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a LdapDefaultClient Error if the function fails in a |
- * non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-static PKIX_Error * |
-pkix_pl_LdapDefaultClient_Send( |
- PKIX_PL_LdapDefaultClient *client, |
- PKIX_Boolean *pKeepGoing, |
- PKIX_UInt32 *pBytesTransferred, |
- void *plContext) |
-{ |
- PKIX_Int32 bytesWritten = 0; |
- PKIX_PL_Socket_Callback *callbackList = NULL; |
- |
- PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_Send"); |
- PKIX_NULLCHECK_THREE(client, pKeepGoing, pBytesTransferred); |
- |
- *pKeepGoing = PKIX_FALSE; |
- |
- /* Do we have anything waiting to go? */ |
- if (client->sendBuf) { |
- callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList); |
- |
- PKIX_CHECK(callbackList->sendCallback |
- (client->clientSocket, |
- client->sendBuf, |
- client->bytesToWrite, |
- &bytesWritten, |
- plContext), |
- PKIX_SOCKETSENDFAILED); |
- |
- client->lastIO = PR_Now(); |
- |
- /* |
- * If the send completed we can proceed to try for the |
- * response. If the send did not complete we will have |
- * to poll for completion later. |
- */ |
- if (bytesWritten >= 0) { |
- client->sendBuf = NULL; |
- client->connectStatus = RECV; |
- *pKeepGoing = PKIX_TRUE; |
- |
- } else { |
- *pKeepGoing = PKIX_FALSE; |
- client->connectStatus = SEND_PENDING; |
- } |
- |
- } |
- |
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache |
- ((PKIX_PL_Object *)client, plContext), |
- PKIX_OBJECTINVALIDATECACHEFAILED); |
- |
- *pBytesTransferred = bytesWritten; |
- |
-cleanup: |
- PKIX_RETURN(LDAPDEFAULTCLIENT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_LdapDefaultClient_SendContinue |
- * DESCRIPTION: |
- * |
- * This function determines whether the sending of the LDAP-protocol message |
- * for the CertStore embodied in the LdapDefaultClient "client" has completed, |
- * and stores in "pKeepGoing" a flag indicating whether processing can continue |
- * without further input, and at "pBytesTransferred" the number of bytes sent. |
- * |
- * If "pBytesTransferred" is zero, it indicates that non-blocking I/O is in use |
- * and that transmission has not completed. |
- * |
- * PARAMETERS: |
- * "client" |
- * The address of the LdapDefaultClient object. Must be non-NULL. |
- * "pKeepGoing" |
- * The address at which the Boolean state machine flag is stored to |
- * indicate whether processing can continue without further input. |
- * Must be non-NULL. |
- * "pBytesTransferred" |
- * The address at which the number of bytes sent is stored. Must be |
- * non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a LdapDefaultClient Error if the function fails in a |
- * non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-static PKIX_Error * |
-pkix_pl_LdapDefaultClient_SendContinue( |
- PKIX_PL_LdapDefaultClient *client, |
- PKIX_Boolean *pKeepGoing, |
- PKIX_UInt32 *pBytesTransferred, |
- void *plContext) |
-{ |
- PKIX_Int32 bytesWritten = 0; |
- PKIX_PL_Socket_Callback *callbackList = NULL; |
- |
- PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_SendContinue"); |
- PKIX_NULLCHECK_THREE(client, pKeepGoing, pBytesTransferred); |
- |
- *pKeepGoing = PKIX_FALSE; |
- |
- callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList); |
- |
- PKIX_CHECK(callbackList->pollCallback |
- (client->clientSocket, &bytesWritten, NULL, plContext), |
- PKIX_SOCKETPOLLFAILED); |
- |
- /* |
- * If the send completed we can proceed to try for the |
- * response. If the send did not complete we will have |
- * continue to poll. |
- */ |
- if (bytesWritten >= 0) { |
- client->sendBuf = NULL; |
- client->connectStatus = RECV; |
- |
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache |
- ((PKIX_PL_Object *)client, plContext), |
- PKIX_OBJECTINVALIDATECACHEFAILED); |
- |
- *pKeepGoing = PKIX_TRUE; |
- } |
- |
- *pBytesTransferred = bytesWritten; |
- |
-cleanup: |
- PKIX_RETURN(LDAPDEFAULTCLIENT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_LdapDefaultClient_Recv |
- * DESCRIPTION: |
- * |
- * This function receives an LDAP-protocol message for the CertStore embodied |
- * in the LdapDefaultClient "client", and stores in "pKeepGoing" a flag |
- * indicating whether processing can continue without further input. |
- * |
- * PARAMETERS: |
- * "client" |
- * The address of the LdapDefaultClient object. Must be non-NULL. |
- * "pKeepGoing" |
- * The address at which the Boolean state machine flag is stored to |
- * indicate whether processing can continue without further input. |
- * Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a LdapDefaultClient Error if the function fails in a |
- * non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-static PKIX_Error * |
-pkix_pl_LdapDefaultClient_Recv( |
- PKIX_PL_LdapDefaultClient *client, |
- PKIX_Boolean *pKeepGoing, |
- void *plContext) |
-{ |
- PKIX_Int32 bytesRead = 0; |
- PKIX_UInt32 bytesToRead = 0; |
- PKIX_PL_Socket_Callback *callbackList = NULL; |
- |
- PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_Recv"); |
- PKIX_NULLCHECK_THREE(client, pKeepGoing, client->rcvBuf); |
- |
- callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList); |
- |
- /* |
- * If we attempt to fill our buffer with every read, we increase |
- * the risk of an ugly situation: one or two bytes of a new message |
- * left over at the end of processing one message. With such a |
- * fragment, we can't decode a byte count and so won't know how much |
- * space to allocate for the next LdapResponse. We try to avoid that |
- * case by reading just enough to complete the current message, unless |
- * there will be at least MINIMUM_MSG_LENGTH bytes left over. |
- */ |
- if (client->currentResponse) { |
- PKIX_CHECK(pkix_pl_LdapResponse_GetCapacity |
- (client->currentResponse, &bytesToRead, plContext), |
- PKIX_LDAPRESPONSEGETCAPACITYFAILED); |
- if ((bytesToRead > client->capacity) || |
- ((bytesToRead + MINIMUM_MSG_LENGTH) < client->capacity)) { |
- bytesToRead = client->capacity; |
- } |
- } else { |
- bytesToRead = client->capacity; |
- } |
- |
- client->currentBytesAvailable = 0; |
- |
- PKIX_CHECK(callbackList->recvCallback |
- (client->clientSocket, |
- (void *)client->rcvBuf, |
- bytesToRead, |
- &bytesRead, |
- plContext), |
- PKIX_SOCKETRECVFAILED); |
- |
- client->currentInPtr = client->rcvBuf; |
- client->lastIO = PR_Now(); |
- |
- if (bytesRead > 0) { |
- client->currentBytesAvailable = bytesRead; |
- client->connectStatus = RECV_INITIAL; |
- *pKeepGoing = PKIX_TRUE; |
- } else { |
- client->connectStatus = RECV_PENDING; |
- *pKeepGoing = PKIX_FALSE; |
- } |
- |
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache |
- ((PKIX_PL_Object *)client, plContext), |
- PKIX_OBJECTINVALIDATECACHEFAILED); |
- |
-cleanup: |
- PKIX_RETURN(LDAPDEFAULTCLIENT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_LdapDefaultClient_RecvContinue |
- * DESCRIPTION: |
- * |
- * This function determines whether the receiving of the LDAP-protocol message |
- * for the CertStore embodied in the LdapDefaultClient "client" has completed, |
- * and stores in "pKeepGoing" a flag indicating whether processing can continue |
- * without further input. |
- * |
- * PARAMETERS: |
- * "client" |
- * The address of the LdapDefaultClient object. Must be non-NULL. |
- * "pKeepGoing" |
- * The address at which the Boolean state machine flag is stored to |
- * indicate whether processing can continue without further input. |
- * Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a LdapDefaultClient Error if the function fails in a |
- * non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-static PKIX_Error * |
-pkix_pl_LdapDefaultClient_RecvContinue( |
- PKIX_PL_LdapDefaultClient *client, |
- PKIX_Boolean *pKeepGoing, |
- void *plContext) |
-{ |
- PKIX_Int32 bytesRead = 0; |
- PKIX_PL_Socket_Callback *callbackList = NULL; |
- |
- PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_RecvContinue"); |
- PKIX_NULLCHECK_TWO(client, pKeepGoing); |
- |
- callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList); |
- |
- PKIX_CHECK(callbackList->pollCallback |
- (client->clientSocket, NULL, &bytesRead, plContext), |
- PKIX_SOCKETPOLLFAILED); |
- |
- if (bytesRead > 0) { |
- client->currentBytesAvailable += bytesRead; |
- client->connectStatus = RECV_INITIAL; |
- *pKeepGoing = PKIX_TRUE; |
- |
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache |
- ((PKIX_PL_Object *)client, plContext), |
- PKIX_OBJECTINVALIDATECACHEFAILED); |
- } else { |
- *pKeepGoing = PKIX_FALSE; |
- } |
- |
-cleanup: |
- PKIX_RETURN(LDAPDEFAULTCLIENT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_LdapDefaultClient_AbandonContinue |
- * DESCRIPTION: |
- * |
- * This function determines whether the abandon-message request of the |
- * LDAP-protocol message for the CertStore embodied in the LdapDefaultClient |
- * "client" has completed, and stores in "pKeepGoing" a flag indicating whether |
- * processing can continue without further input. |
- * |
- * PARAMETERS: |
- * "client" |
- * The address of the LdapDefaultClient object. Must be non-NULL. |
- * "pKeepGoing" |
- * The address at which the Boolean state machine flag is stored to |
- * indicate whether processing can continue without further input. |
- * Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a LdapDefaultClient Error if the function fails in a |
- * non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-static PKIX_Error * |
-pkix_pl_LdapDefaultClient_AbandonContinue( |
- PKIX_PL_LdapDefaultClient *client, |
- PKIX_Boolean *pKeepGoing, |
- void *plContext) |
-{ |
- PKIX_Int32 bytesWritten = 0; |
- PKIX_PL_Socket_Callback *callbackList = NULL; |
- |
- PKIX_ENTER |
- (LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_AbandonContinue"); |
- PKIX_NULLCHECK_TWO(client, pKeepGoing); |
- |
- callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList); |
- |
- PKIX_CHECK(callbackList->pollCallback |
- (client->clientSocket, &bytesWritten, NULL, plContext), |
- PKIX_SOCKETPOLLFAILED); |
- |
- if (bytesWritten > 0) { |
- client->connectStatus = BOUND; |
- *pKeepGoing = PKIX_TRUE; |
- |
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache |
- ((PKIX_PL_Object *)client, plContext), |
- PKIX_OBJECTINVALIDATECACHEFAILED); |
- } else { |
- *pKeepGoing = PKIX_FALSE; |
- } |
- |
-cleanup: |
- PKIX_RETURN(LDAPDEFAULTCLIENT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_LdapDefaultClient_RecvInitial |
- * DESCRIPTION: |
- * |
- * This function processes the contents of the first buffer of a received |
- * LDAP-protocol message for the CertStore embodied in the LdapDefaultClient |
- * "client", and stores in "pKeepGoing" a flag indicating whether processing can |
- * continue without further input. |
- * |
- * PARAMETERS: |
- * "client" |
- * The address of the LdapDefaultClient object. Must be non-NULL. |
- * "pKeepGoing" |
- * The address at which the Boolean state machine flag is stored to |
- * indicate whether processing can continue without further input. |
- * Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a LdapDefaultClient Error if the function fails in a |
- * non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-static PKIX_Error * |
-pkix_pl_LdapDefaultClient_RecvInitial( |
- PKIX_PL_LdapDefaultClient *client, |
- PKIX_Boolean *pKeepGoing, |
- void *plContext) |
-{ |
- unsigned char *msgBuf = NULL; |
- unsigned char *to = NULL; |
- unsigned char *from = NULL; |
- PKIX_UInt32 dataIndex = 0; |
- PKIX_UInt32 messageIdLen = 0; |
- PKIX_UInt32 messageLength = 0; |
- PKIX_UInt32 sizeofLength = 0; |
- PKIX_UInt32 bytesProcessed = 0; |
- unsigned char messageChar = 0; |
- LDAPMessageType messageType = 0; |
- PKIX_Int32 bytesRead = 0; |
- PKIX_PL_Socket_Callback *callbackList = NULL; |
- |
- PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_RecvInitial"); |
- PKIX_NULLCHECK_TWO(client, pKeepGoing); |
- |
- /* |
- * Is there an LDAPResponse in progress? I.e., have we |
- * already processed the tag and length at the beginning of |
- * the message? |
- */ |
- if (client->currentResponse) { |
- client->connectStatus = RECV_NONINITIAL; |
- *pKeepGoing = PKIX_TRUE; |
- goto cleanup; |
- } |
- msgBuf = client->currentInPtr; |
- |
- /* Do we have enough of the message to decode the message length? */ |
- if (client->currentBytesAvailable < MINIMUM_MSG_LENGTH) { |
- /* |
- * No! Move these few bytes to the beginning of rcvBuf |
- * and hang another read. |
- */ |
- |
- to = (unsigned char *)client->rcvBuf; |
- from = client->currentInPtr; |
- for (dataIndex = 0; |
- dataIndex < client->currentBytesAvailable; |
- dataIndex++) { |
- *to++ = *from++; |
- } |
- callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList); |
- PKIX_CHECK(callbackList->recvCallback |
- (client->clientSocket, |
- (void *)to, |
- client->capacity - client->currentBytesAvailable, |
- &bytesRead, |
- plContext), |
- PKIX_SOCKETRECVFAILED); |
- |
- client->currentInPtr = client->rcvBuf; |
- client->lastIO = PR_Now(); |
- |
- if (bytesRead <= 0) { |
- client->connectStatus = RECV_PENDING; |
- *pKeepGoing = PKIX_FALSE; |
- goto cleanup; |
- } else { |
- client->currentBytesAvailable += bytesRead; |
- } |
- } |
- |
- /* |
- * We have to determine whether the response is an entry, with |
- * application-specific tag LDAP_SEARCHRESPONSEENTRY_TYPE, or a |
- * resultCode, with application tag LDAP_SEARCHRESPONSERESULT_TYPE. |
- * First, we have to figure out where to look for the tag. |
- */ |
- |
- /* Is the message length short form (one octet) or long form? */ |
- if ((msgBuf[1] & 0x80) != 0) { |
- sizeofLength = msgBuf[1] & 0x7F; |
- for (dataIndex = 0; dataIndex < sizeofLength; dataIndex++) { |
- messageLength = |
- (messageLength << 8) + msgBuf[dataIndex + 2]; |
- } |
- } else { |
- messageLength = msgBuf[1]; |
- } |
- |
- /* How many bytes did the messageID require? */ |
- messageIdLen = msgBuf[dataIndex + 3]; |
- |
- messageChar = msgBuf[dataIndex + messageIdLen + 4]; |
- |
- /* Are we looking at an Entry message or a ResultCode message? */ |
- if ((SEC_ASN1_CONSTRUCTED | SEC_ASN1_APPLICATION | |
- LDAP_SEARCHRESPONSEENTRY_TYPE) == messageChar) { |
- |
- messageType = LDAP_SEARCHRESPONSEENTRY_TYPE; |
- |
- } else if ((SEC_ASN1_CONSTRUCTED | SEC_ASN1_APPLICATION | |
- LDAP_SEARCHRESPONSERESULT_TYPE) == messageChar) { |
- |
- messageType = LDAP_SEARCHRESPONSERESULT_TYPE; |
- |
- } else { |
- |
- PKIX_ERROR(PKIX_SEARCHRESPONSEPACKETOFUNKNOWNTYPE); |
- |
- } |
- |
- /* |
- * messageLength is the length from (tag, length, value). |
- * We have to allocate space for the tag and length bits too. |
- */ |
- PKIX_CHECK(pkix_pl_LdapResponse_Create |
- (messageType, |
- messageLength + dataIndex + 2, |
- client->currentBytesAvailable, |
- msgBuf, |
- &bytesProcessed, |
- &(client->currentResponse), |
- plContext), |
- PKIX_LDAPRESPONSECREATEFAILED); |
- |
- client->currentBytesAvailable -= bytesProcessed; |
- |
- PKIX_CHECK(pkix_pl_LdapDefaultClient_RecvCheckComplete |
- (client, bytesProcessed, pKeepGoing, plContext), |
- PKIX_LDAPDEFAULTCLIENTRECVCHECKCOMPLETEFAILED); |
- |
-cleanup: |
- |
- PKIX_RETURN(LDAPDEFAULTCLIENT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_LdapDefaultClient_RecvNonInitial |
- * DESCRIPTION: |
- * |
- * This function processes the contents of buffers, after the first, of a |
- * received LDAP-protocol message for the CertStore embodied in the |
- * LdapDefaultClient "client", and stores in "pKeepGoing" a flag indicating |
- * whether processing can continue without further input. |
- * |
- * PARAMETERS: |
- * "client" |
- * The address of the LdapDefaultClient object. Must be non-NULL. |
- * "pKeepGoing" |
- * The address at which the Boolean state machine flag is stored to |
- * indicate whether processing can continue without further input. |
- * Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a LdapDefaultClient Error if the function fails in a |
- * non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-static PKIX_Error * |
-pkix_pl_LdapDefaultClient_RecvNonInitial( |
- PKIX_PL_LdapDefaultClient *client, |
- PKIX_Boolean *pKeepGoing, |
- void *plContext) |
-{ |
- |
- PKIX_UInt32 bytesProcessed = 0; |
- |
- PKIX_ENTER |
- (LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_RecvNonInitial"); |
- PKIX_NULLCHECK_TWO(client, pKeepGoing); |
- |
- PKIX_CHECK(pkix_pl_LdapResponse_Append |
- (client->currentResponse, |
- client->currentBytesAvailable, |
- client->currentInPtr, |
- &bytesProcessed, |
- plContext), |
- PKIX_LDAPRESPONSEAPPENDFAILED); |
- |
- client->currentBytesAvailable -= bytesProcessed; |
- |
- PKIX_CHECK(pkix_pl_LdapDefaultClient_RecvCheckComplete |
- (client, bytesProcessed, pKeepGoing, plContext), |
- PKIX_LDAPDEFAULTCLIENTRECVCHECKCOMPLETEFAILED); |
- |
-cleanup: |
- |
- PKIX_RETURN(LDAPDEFAULTCLIENT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_LdapDefaultClient_Dispatch |
- * DESCRIPTION: |
- * |
- * This function is the state machine dispatcher for the CertStore embodied in |
- * the LdapDefaultClient pointed to by "client". Results are returned by |
- * changes to various fields in the context. |
- * |
- * PARAMETERS: |
- * "client" |
- * The address of the LdapDefaultClient object. Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a LdapDefaultClient Error if the function fails in a |
- * non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-static PKIX_Error * |
-pkix_pl_LdapDefaultClient_Dispatch( |
- PKIX_PL_LdapDefaultClient *client, |
- void *plContext) |
-{ |
- PKIX_UInt32 bytesTransferred = 0; |
- PKIX_Boolean keepGoing = PKIX_TRUE; |
- |
- PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_Dispatch"); |
- PKIX_NULLCHECK_ONE(client); |
- |
- while (keepGoing) { |
- switch (client->connectStatus) { |
- case CONNECT_PENDING: |
- PKIX_CHECK |
- (pkix_pl_LdapDefaultClient_ConnectContinue |
- (client, &keepGoing, plContext), |
- PKIX_LDAPDEFAULTCLIENTCONNECTCONTINUEFAILED); |
- break; |
- case CONNECTED: |
- PKIX_CHECK |
- (pkix_pl_LdapDefaultClient_Bind |
- (client, &keepGoing, plContext), |
- PKIX_LDAPDEFAULTCLIENTBINDFAILED); |
- break; |
- case BIND_PENDING: |
- PKIX_CHECK |
- (pkix_pl_LdapDefaultClient_BindContinue |
- (client, &keepGoing, plContext), |
- PKIX_LDAPDEFAULTCLIENTBINDCONTINUEFAILED); |
- break; |
- case BIND_RESPONSE: |
- PKIX_CHECK |
- (pkix_pl_LdapDefaultClient_BindResponse |
- (client, &keepGoing, plContext), |
- PKIX_LDAPDEFAULTCLIENTBINDRESPONSEFAILED); |
- break; |
- case BIND_RESPONSE_PENDING: |
- PKIX_CHECK |
- (pkix_pl_LdapDefaultClient_BindResponseContinue |
- (client, &keepGoing, plContext), |
- PKIX_LDAPDEFAULTCLIENTBINDRESPONSECONTINUEFAILED); |
- break; |
- case BOUND: |
- PKIX_CHECK |
- (pkix_pl_LdapDefaultClient_Send |
- (client, &keepGoing, &bytesTransferred, plContext), |
- PKIX_LDAPDEFAULTCLIENTSENDFAILED); |
- break; |
- case SEND_PENDING: |
- PKIX_CHECK |
- (pkix_pl_LdapDefaultClient_SendContinue |
- (client, &keepGoing, &bytesTransferred, plContext), |
- PKIX_LDAPDEFAULTCLIENTSENDCONTINUEFAILED); |
- break; |
- case RECV: |
- PKIX_CHECK |
- (pkix_pl_LdapDefaultClient_Recv |
- (client, &keepGoing, plContext), |
- PKIX_LDAPDEFAULTCLIENTRECVFAILED); |
- break; |
- case RECV_PENDING: |
- PKIX_CHECK |
- (pkix_pl_LdapDefaultClient_RecvContinue |
- (client, &keepGoing, plContext), |
- PKIX_LDAPDEFAULTCLIENTRECVCONTINUEFAILED); |
- break; |
- case RECV_INITIAL: |
- PKIX_CHECK |
- (pkix_pl_LdapDefaultClient_RecvInitial |
- (client, &keepGoing, plContext), |
- PKIX_LDAPDEFAULTCLIENTRECVINITIALFAILED); |
- break; |
- case RECV_NONINITIAL: |
- PKIX_CHECK |
- (pkix_pl_LdapDefaultClient_RecvNonInitial |
- (client, &keepGoing, plContext), |
- PKIX_LDAPDEFAULTCLIENTRECVNONINITIALFAILED); |
- break; |
- case ABANDON_PENDING: |
- PKIX_CHECK |
- (pkix_pl_LdapDefaultClient_AbandonContinue |
- (client, &keepGoing, plContext), |
- PKIX_LDAPDEFAULTCLIENTABANDONCONTINUEFAILED); |
- break; |
- default: |
- PKIX_ERROR(PKIX_LDAPCERTSTOREINILLEGALSTATE); |
- } |
- } |
- |
-cleanup: |
- |
- PKIX_RETURN(LDAPDEFAULTCLIENT); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_LdapDefaultClient_MakeAndFilter |
- * DESCRIPTION: |
- * |
- * This function allocates space from the arena pointed to by "arena" to |
- * construct a filter that will match components of the X500Name pointed to by |
- * XXX... |
- * |
- * PARAMETERS: |
- * "arena" |
- * The address of the PRArenaPool used in creating the filter. Must be |
- * non-NULL. |
- * "nameComponent" |
- * The address of a NULL-terminated list of LDAPNameComponents |
- * Must be non-NULL. |
- * "pFilter" |
- * The address at which the result is stored. |
- * "plContext" |
- * Platform-specific context pointer |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a CertStore Error if the function fails in a non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-static PKIX_Error * |
-pkix_pl_LdapDefaultClient_MakeAndFilter( |
- PRArenaPool *arena, |
- LDAPNameComponent **nameComponents, |
- LDAPFilter **pFilter, |
- void *plContext) |
-{ |
- LDAPFilter **setOfFilter; |
- LDAPFilter *andFilter = NULL; |
- LDAPFilter *currentFilter = NULL; |
- PKIX_UInt32 componentsPresent = 0; |
- void *v = NULL; |
- unsigned char *component = NULL; |
- LDAPNameComponent **componentP = NULL; |
- |
- PKIX_ENTER(CERTSTORE, "pkix_pl_LdapDefaultClient_MakeAndFilter"); |
- PKIX_NULLCHECK_THREE(arena, nameComponents, pFilter); |
- |
- /* count how many components we were provided */ |
- for (componentP = nameComponents, componentsPresent = 0; |
- *(componentP++) != NULL; |
- componentsPresent++) {} |
- |
- /* Space for (componentsPresent + 1) pointers to LDAPFilter */ |
- PKIX_PL_NSSCALLRV(CERTSTORE, v, PORT_ArenaZAlloc, |
- (arena, (componentsPresent + 1)*sizeof(LDAPFilter *))); |
- setOfFilter = (LDAPFilter **)v; |
- |
- /* Space for AndFilter and <componentsPresent> EqualFilters */ |
- PKIX_PL_NSSCALLRV(CERTSTORE, v, PORT_ArenaZNewArray, |
- (arena, LDAPFilter, componentsPresent + 1)); |
- setOfFilter[0] = (LDAPFilter *)v; |
- |
- /* Claim the first array element for the ANDFilter */ |
- andFilter = setOfFilter[0]; |
- |
- /* Set ANDFilter to point to the first EqualFilter pointer */ |
- andFilter->selector = LDAP_ANDFILTER_TYPE; |
- andFilter->filter.andFilter.filters = setOfFilter; |
- |
- currentFilter = andFilter + 1; |
- |
- for (componentP = nameComponents, componentsPresent = 0; |
- *(componentP) != NULL; componentP++) { |
- setOfFilter[componentsPresent++] = currentFilter; |
- currentFilter->selector = LDAP_EQUALFILTER_TYPE; |
- component = (*componentP)->attrType; |
- currentFilter->filter.equalFilter.attrType.data = component; |
- currentFilter->filter.equalFilter.attrType.len = |
- PL_strlen((const char *)component); |
- component = (*componentP)->attrValue; |
- currentFilter->filter.equalFilter.attrValue.data = component; |
- currentFilter->filter.equalFilter.attrValue.len = |
- PL_strlen((const char *)component); |
- currentFilter++; |
- } |
- |
- setOfFilter[componentsPresent] = NULL; |
- |
- *pFilter = andFilter; |
- |
- PKIX_RETURN(CERTSTORE); |
- |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_LdapDefaultClient_InitiateRequest |
- * DESCRIPTION: |
- * |
- * |
- * PARAMETERS: |
- * "client" |
- * The address of the LdapDefaultClient object. Must be non-NULL. |
- * "requestParams" |
- * The address of an LdapClientParams object. Must be non-NULL. |
- * "pPollDesc" |
- * The location where the address of the PRPollDesc is stored, if the |
- * client returns with I/O pending. |
- * "pResponse" |
- * The address where the List of LDAPResponses, or NULL for an |
- * unfinished request, is stored. Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a LdapDefaultClient Error if the function fails in a |
- * non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-static PKIX_Error * |
-pkix_pl_LdapDefaultClient_InitiateRequest( |
- PKIX_PL_LdapClient *genericClient, |
- LDAPRequestParams *requestParams, |
- void **pPollDesc, |
- PKIX_List **pResponse, |
- void *plContext) |
-{ |
- PKIX_List *searchResponseList = NULL; |
- SECItem *encoded = NULL; |
- LDAPFilter *filter = NULL; |
- PKIX_PL_LdapDefaultClient *client = 0; |
- |
- PKIX_ENTER |
- (LDAPDEFAULTCLIENT, |
- "pkix_pl_LdapDefaultClient_InitiateRequest"); |
- PKIX_NULLCHECK_FOUR(genericClient, requestParams, pPollDesc, pResponse); |
- |
- PKIX_CHECK(pkix_CheckType |
- ((PKIX_PL_Object *)genericClient, |
- PKIX_LDAPDEFAULTCLIENT_TYPE, |
- plContext), |
- PKIX_GENERICCLIENTNOTANLDAPDEFAULTCLIENT); |
- |
- client = (PKIX_PL_LdapDefaultClient *)genericClient; |
- |
- PKIX_CHECK(pkix_pl_LdapDefaultClient_MakeAndFilter |
- (client->arena, requestParams->nc, &filter, plContext), |
- PKIX_LDAPDEFAULTCLIENTMAKEANDFILTERFAILED); |
- |
- PKIX_CHECK(pkix_pl_LdapRequest_Create |
- (client->arena, |
- client->messageID++, |
- requestParams->baseObject, |
- requestParams->scope, |
- requestParams->derefAliases, |
- requestParams->sizeLimit, |
- requestParams->timeLimit, |
- PKIX_FALSE, /* attrs only */ |
- filter, |
- requestParams->attributes, |
- &client->currentRequest, |
- plContext), |
- PKIX_LDAPREQUESTCREATEFAILED); |
- |
- /* check hashtable for matching request */ |
- PKIX_CHECK(PKIX_PL_HashTable_Lookup |
- (client->cachePtr, |
- (PKIX_PL_Object *)(client->currentRequest), |
- (PKIX_PL_Object **)&searchResponseList, |
- plContext), |
- PKIX_HASHTABLELOOKUPFAILED); |
- |
- if (searchResponseList != NULL) { |
- *pPollDesc = NULL; |
- *pResponse = searchResponseList; |
- PKIX_DECREF(client->currentRequest); |
- goto cleanup; |
- } |
- |
- /* It wasn't cached. We'll have to actually send it. */ |
- |
- PKIX_CHECK(pkix_pl_LdapRequest_GetEncoded |
- (client->currentRequest, &encoded, plContext), |
- PKIX_LDAPREQUESTGETENCODEDFAILED); |
- |
- client->sendBuf = encoded->data; |
- client->bytesToWrite = encoded->len; |
- |
- PKIX_CHECK(pkix_pl_LdapDefaultClient_Dispatch(client, plContext), |
- PKIX_LDAPDEFAULTCLIENTDISPATCHFAILED); |
- |
- /* |
- * It's not enough that we may be done with a particular read. |
- * We're still processing the transaction until we've gotten the |
- * SearchResponseResult message and returned to the BOUND state. |
- * Otherwise we must still have a read pending, and must hold off |
- * on returning results. |
- */ |
- if ((client->connectStatus == BOUND) && |
- (client->entriesFound != NULL)) { |
- *pPollDesc = NULL; |
- *pResponse = client->entriesFound; |
- client->entriesFound = NULL; |
- PKIX_DECREF(client->currentRequest); |
- } else { |
- *pPollDesc = &client->pollDesc; |
- *pResponse = NULL; |
- } |
- |
-cleanup: |
- |
- PKIX_RETURN(LDAPDEFAULTCLIENT); |
- |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_LdapDefaultClient_ResumeRequest |
- * DESCRIPTION: |
- * |
- * |
- * PARAMETERS: |
- * "client" |
- * The address of the LdapDefaultClient object. Must be non-NULL. |
- * "pPollDesc" |
- * The location where the address of the PRPollDesc is stored, if the |
- * client returns with I/O pending. |
- * "pResponse" |
- * The address where the List of LDAPResponses, or NULL for an |
- * unfinished request, is stored. Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a LdapDefaultClient Error if the function fails in a |
- * non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-static PKIX_Error * |
-pkix_pl_LdapDefaultClient_ResumeRequest( |
- PKIX_PL_LdapClient *genericClient, |
- void **pPollDesc, |
- PKIX_List **pResponse, |
- void *plContext) |
-{ |
- PKIX_PL_LdapDefaultClient *client = 0; |
- |
- PKIX_ENTER |
- (LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_ResumeRequest"); |
- PKIX_NULLCHECK_THREE(genericClient, pPollDesc, pResponse); |
- |
- PKIX_CHECK(pkix_CheckType |
- ((PKIX_PL_Object *)genericClient, |
- PKIX_LDAPDEFAULTCLIENT_TYPE, |
- plContext), |
- PKIX_GENERICCLIENTNOTANLDAPDEFAULTCLIENT); |
- |
- client = (PKIX_PL_LdapDefaultClient *)genericClient; |
- |
- PKIX_CHECK(pkix_pl_LdapDefaultClient_Dispatch(client, plContext), |
- PKIX_LDAPDEFAULTCLIENTDISPATCHFAILED); |
- |
- /* |
- * It's not enough that we may be done with a particular read. |
- * We're still processing the transaction until we've gotten the |
- * SearchResponseResult message and returned to the BOUND state. |
- * Otherwise we must still have a read pending, and must hold off |
- * on returning results. |
- */ |
- if ((client->connectStatus == BOUND) && |
- (client->entriesFound != NULL)) { |
- *pPollDesc = NULL; |
- *pResponse = client->entriesFound; |
- client->entriesFound = NULL; |
- PKIX_DECREF(client->currentRequest); |
- } else { |
- *pPollDesc = &client->pollDesc; |
- *pResponse = NULL; |
- } |
- |
-cleanup: |
- |
- PKIX_RETURN(LDAPDEFAULTCLIENT); |
- |
-} |
- |
-/* --Public-LdapDefaultClient-Functions----------------------------------- */ |
- |
-/* |
- * FUNCTION: PKIX_PL_LdapDefaultClient_AbandonRequest |
- * DESCRIPTION: |
- * |
- * This function creates and sends an LDAP-protocol "Abandon" message to the |
- * server connected to the LdapDefaultClient pointed to by "client". |
- * |
- * PARAMETERS: |
- * "client" |
- * The LdapDefaultClient whose connection is to be abandoned. Must be |
- * non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-PKIX_Error * |
-PKIX_PL_LdapDefaultClient_AbandonRequest( |
- PKIX_PL_LdapDefaultClient *client, |
- void *plContext) |
-{ |
- PKIX_Int32 bytesWritten = 0; |
- PKIX_PL_Socket_Callback *callbackList = NULL; |
- SECItem *encoded = NULL; |
- |
- PKIX_ENTER(CERTSTORE, "PKIX_PL_LdapDefaultClient_AbandonRequest"); |
- PKIX_NULLCHECK_ONE(client); |
- |
- if (client->connectStatus == RECV_PENDING) { |
- PKIX_CHECK(pkix_pl_LdapDefaultClient_MakeAbandon |
- (client->arena, |
- (client->messageID) - 1, |
- &encoded, |
- plContext), |
- PKIX_LDAPDEFAULTCLIENTMAKEABANDONFAILED); |
- |
- callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList); |
- PKIX_CHECK(callbackList->sendCallback |
- (client->clientSocket, |
- encoded->data, |
- encoded->len, |
- &bytesWritten, |
- plContext), |
- PKIX_SOCKETSENDFAILED); |
- |
- if (bytesWritten < 0) { |
- client->connectStatus = ABANDON_PENDING; |
- } else { |
- client->connectStatus = BOUND; |
- } |
- } |
- |
- PKIX_DECREF(client->entriesFound); |
- PKIX_DECREF(client->currentRequest); |
- PKIX_DECREF(client->currentResponse); |
- |
-cleanup: |
- |
- PKIX_DECREF(client); |
- |
- PKIX_RETURN(CERTSTORE); |
-} |