| 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);
|
| -}
|
|
|