1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
14 * The Original Code is the PKIX-C library.
16 * The Initial Developer of the Original Code is
17 * Sun Microsystems, Inc.
18 * Portions created by the Initial Developer are
19 * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
22 * Sun Microsystems, Inc.
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 * pkix_pl_ldapdefaultclient.c
40 * LDAPDefaultClient Function Definitions
44 /* We can't decode the length of a message without at least this many bytes */
45 #define MINIMUM_MSG_LENGTH 5
47 #include "pkix_pl_ldapdefaultclient.h"
49 /* --Private-LdapDefaultClient-Message-Building-Functions---------------- */
52 * FUNCTION: pkix_pl_LdapDefaultClient_MakeBind
55 * This function creates and encodes a Bind message, using the arena pointed
56 * to by "arena", the version number contained in "versionData", the
57 * LDAPBindAPI pointed to by "bindAPI", and the messageID contained in
58 * "msgNum", and stores a pointer to the encoded string at "pBindMsg".
60 * See pkix_pl_ldaptemplates.c for the ASN.1 description of a Bind message.
62 * This code is not used if the DefaultClient was created with a NULL pointer
63 * supplied for the LDAPBindAPI structure. (Bind and Unbind do not seem to be
64 * expected for anonymous Search requests.)
68 * The address of the PRArenaPool used in encoding the message. Must be
71 * The Int32 containing the version number to be encoded in the Bind
74 * The address of the LDAPBindAPI to be encoded in the Bind message. Must
77 * The Int32 containing the MessageID to be encoded in the Bind message.
79 * The address at which the encoded Bind message will be stored. Must be
82 * Platform-specific context pointer.
84 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
86 * Returns NULL if the function succeeds.
87 * Returns a LdapDefaultClient Error if the function fails in a
89 * Returns a Fatal Error if the function fails in an unrecoverable way.
92 pkix_pl_LdapDefaultClient_MakeBind(
94 PKIX_Int32 versionData
,
102 SECItem
*encoded
= NULL
;
105 PKIX_ENTER(LDAPDEFAULTCLIENT
, "pkix_pl_LdapDefaultClient_MakeBind");
106 PKIX_NULLCHECK_TWO(arena
, pBindMsg
);
108 PKIX_PL_NSSCALL(LDAPDEFAULTCLIENT
, PORT_Memset
,
109 (&msg
, 0, sizeof (LDAPMessage
)));
111 version
= (char)versionData
;
113 msg
.messageID
.type
= siUnsignedInteger
;
114 msg
.messageID
.data
= (void*)&msgNum
;
115 msg
.messageID
.len
= sizeof (msgNum
);
117 msg
.protocolOp
.selector
= LDAP_BIND_TYPE
;
119 msg
.protocolOp
.op
.bindMsg
.version
.type
= siUnsignedInteger
;
120 msg
.protocolOp
.op
.bindMsg
.version
.data
= (void *)&version
;
121 msg
.protocolOp
.op
.bindMsg
.version
.len
= sizeof (char);
124 * XXX At present we only know how to handle anonymous requests (no
125 * authentication), and we are guessing how to do simple authentication.
126 * This section will need to be revised and extended when other
127 * authentication is needed.
129 if (bindAPI
->selector
== SIMPLE_AUTH
) {
130 msg
.protocolOp
.op
.bindMsg
.bindName
.type
= siAsciiString
;
131 msg
.protocolOp
.op
.bindMsg
.bindName
.data
=
132 (void *)bindAPI
->chooser
.simple
.bindName
;
133 len
= PL_strlen(bindAPI
->chooser
.simple
.bindName
);
134 msg
.protocolOp
.op
.bindMsg
.bindName
.len
= len
;
136 msg
.protocolOp
.op
.bindMsg
.authentication
.type
= siAsciiString
;
137 msg
.protocolOp
.op
.bindMsg
.authentication
.data
=
138 (void *)bindAPI
->chooser
.simple
.authentication
;
139 len
= PL_strlen(bindAPI
->chooser
.simple
.authentication
);
140 msg
.protocolOp
.op
.bindMsg
.authentication
.len
= len
;
143 PKIX_PL_NSSCALLRV(LDAPDEFAULTCLIENT
, encoded
, SEC_ASN1EncodeItem
,
144 (arena
, NULL
, (void *)&msg
, PKIX_PL_LDAPMessageTemplate
));
146 PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED
);
152 PKIX_RETURN(LDAPDEFAULTCLIENT
);
156 * FUNCTION: pkix_pl_LdapDefaultClient_MakeUnbind
159 * This function creates and encodes a Unbind message, using the arena pointed
160 * to by "arena" and the messageID contained in "msgNum", and stores a pointer
161 * to the encoded string at "pUnbindMsg".
163 * See pkix_pl_ldaptemplates.c for the ASN.1 description of an Unbind message.
165 * This code is not used if the DefaultClient was created with a NULL pointer
166 * supplied for the LDAPBindAPI structure. (Bind and Unbind do not seem to be
167 * expected for anonymous Search requests.)
171 * The address of the PRArenaPool used in encoding the message. Must be
174 * The Int32 containing the MessageID to be encoded in the Unbind message.
176 * The address at which the encoded Unbind message will be stored. Must
179 * Platform-specific context pointer.
181 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
183 * Returns NULL if the function succeeds.
184 * Returns a LdapDefaultClient Error if the function fails in a
186 * Returns a Fatal Error if the function fails in an unrecoverable way.
189 pkix_pl_LdapDefaultClient_MakeUnbind(
192 SECItem
**pUnbindMsg
,
196 SECItem
*encoded
= NULL
;
198 PKIX_ENTER(LDAPDEFAULTCLIENT
, "pkix_pl_LdapDefaultClient_MakeUnbind");
199 PKIX_NULLCHECK_TWO(arena
, pUnbindMsg
);
201 PKIX_PL_NSSCALL(LDAPDEFAULTCLIENT
, PORT_Memset
,
202 (&msg
, 0, sizeof (LDAPMessage
)));
204 msg
.messageID
.type
= siUnsignedInteger
;
205 msg
.messageID
.data
= (void*)&msgNum
;
206 msg
.messageID
.len
= sizeof (msgNum
);
208 msg
.protocolOp
.selector
= LDAP_UNBIND_TYPE
;
210 msg
.protocolOp
.op
.unbindMsg
.dummy
.type
= siBuffer
;
211 msg
.protocolOp
.op
.unbindMsg
.dummy
.data
= NULL
;
212 msg
.protocolOp
.op
.unbindMsg
.dummy
.len
= 0;
214 PKIX_PL_NSSCALLRV(LDAPDEFAULTCLIENT
, encoded
, SEC_ASN1EncodeItem
,
215 (arena
, NULL
, (void *)&msg
, PKIX_PL_LDAPMessageTemplate
));
217 PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED
);
220 *pUnbindMsg
= encoded
;
223 PKIX_RETURN(LDAPDEFAULTCLIENT
);
227 * FUNCTION: pkix_pl_LdapDefaultClient_MakeAbandon
230 * This function creates and encodes a Abandon message, using the arena pointed
231 * to by "arena" and the messageID contained in "msgNum", and stores a pointer
232 * to the encoded string at "pAbandonMsg".
234 * See pkix_pl_ldaptemplates.c for the ASN.1 description of an Abandon message.
238 * The address of the PRArenaPool used in encoding the message. Must be
241 * The Int32 containing the MessageID to be encoded in the Abandon message.
243 * The address at which the encoded Abandon message will be stored. Must
246 * Platform-specific context pointer.
248 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
250 * Returns NULL if the function succeeds.
251 * Returns a LdapDefaultClient Error if the function fails in a
253 * Returns a Fatal Error if the function fails in an unrecoverable way.
256 pkix_pl_LdapDefaultClient_MakeAbandon(
259 SECItem
**pAbandonMsg
,
263 SECItem
*encoded
= NULL
;
265 PKIX_ENTER(LDAPDEFAULTCLIENT
, "pkix_pl_LdapDefaultClient_MakeAbandon");
266 PKIX_NULLCHECK_TWO(arena
, pAbandonMsg
);
268 PKIX_PL_NSSCALL(LDAPDEFAULTCLIENT
, PORT_Memset
,
269 (&msg
, 0, sizeof (LDAPMessage
)));
271 msg
.messageID
.type
= siUnsignedInteger
;
272 msg
.messageID
.data
= (void*)&msgNum
;
273 msg
.messageID
.len
= sizeof (msgNum
);
275 msg
.protocolOp
.selector
= LDAP_ABANDONREQUEST_TYPE
;
277 msg
.protocolOp
.op
.abandonRequestMsg
.messageID
.type
= siBuffer
;
278 msg
.protocolOp
.op
.abandonRequestMsg
.messageID
.data
= (void*)&msgNum
;
279 msg
.protocolOp
.op
.abandonRequestMsg
.messageID
.len
= sizeof (msgNum
);
281 PKIX_PL_NSSCALLRV(LDAPDEFAULTCLIENT
, encoded
, SEC_ASN1EncodeItem
,
282 (arena
, NULL
, (void *)&msg
, PKIX_PL_LDAPMessageTemplate
));
284 PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED
);
287 *pAbandonMsg
= encoded
;
290 PKIX_RETURN(LDAPDEFAULTCLIENT
);
294 * FUNCTION: pkix_pl_LdapDefaultClient_DecodeBindResponse
297 * This function decodes the encoded data pointed to by "src", using the arena
298 * pointed to by "arena", storing the decoded LDAPMessage at "pBindResponse"
299 * and the decoding status at "pStatus".
303 * The address of the PRArenaPool to be used in decoding the message. Must
306 * The address of the SECItem containing the DER- (or BER-)encoded string.
309 * The address at which the LDAPMessage is stored, if the decoding is
310 * successful (the returned status is SECSuccess). Must be non-NULL.
312 * The address at which the decoding status is stored. Must be non-NULL.
314 * Platform-specific context pointer.
316 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
318 * Returns NULL if the function succeeds.
319 * Returns a LdapDefaultClient Error if the function fails in a
321 * Returns a Fatal Error if the function fails in an unrecoverable way.
324 pkix_pl_LdapDefaultClient_DecodeBindResponse(
327 LDAPMessage
*pBindResponse
,
331 SECStatus rv
= SECFailure
;
332 LDAPMessage response
;
336 "pkix_pl_LdapDefaultClient_DecodeBindResponse");
337 PKIX_NULLCHECK_FOUR(arena
, src
, pBindResponse
, pStatus
);
342 (&response
, 0, sizeof (LDAPMessage
)));
344 PKIX_PL_NSSCALLRV(LDAPDEFAULTCLIENT
, rv
, SEC_ASN1DecodeItem
,
345 (arena
, &response
, PKIX_PL_LDAPMessageTemplate
, src
));
347 if (rv
== SECSuccess
) {
348 *pBindResponse
= response
;
353 PKIX_RETURN(LDAPDEFAULTCLIENT
);
357 * FUNCTION: pkix_pl_LdapDefaultClient_VerifyBindResponse
360 * This function verifies that the contents of the message in the rcvbuf of
361 * the LdapDefaultClient object pointed to by "client", and whose length is
362 * provided by "buflen", is a response to a successful Bind.
366 * The address of the LdapDefaultClient object. Must be non-NULL.
368 * The value of the number of bytes in the receive buffer.
370 * Platform-specific context pointer.
372 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
374 * Returns NULL if the function succeeds.
375 * Returns a LdapDefaultClient Error if the function fails in a
377 * Returns a Fatal Error if the function fails in an unrecoverable way.
380 pkix_pl_LdapDefaultClient_VerifyBindResponse(
381 PKIX_PL_LdapDefaultClient
*client
,
385 SECItem decode
= {siBuffer
, NULL
, 0};
386 SECStatus rv
= SECFailure
;
388 LDAPBindResponse
*ldapBindResponse
= NULL
;
392 "pkix_pl_LdapDefaultClient_VerifyBindResponse");
393 PKIX_NULLCHECK_TWO(client
, client
->rcvBuf
);
395 decode
.data
= (void *)(client
->rcvBuf
);
398 PKIX_CHECK(pkix_pl_LdapDefaultClient_DecodeBindResponse
399 (client
->arena
, &decode
, &msg
, &rv
, plContext
),
400 PKIX_LDAPDEFAULTCLIENTDECODEBINDRESPONSEFAILED
);
402 if (rv
== SECSuccess
) {
403 ldapBindResponse
= &msg
.protocolOp
.op
.bindResponseMsg
;
404 if (*(ldapBindResponse
->resultCode
.data
) == SUCCESS
) {
405 client
->connectStatus
= BOUND
;
407 PKIX_ERROR(PKIX_BINDREJECTEDBYSERVER
);
410 PKIX_ERROR(PKIX_CANTDECODEBINDRESPONSEFROMSERVER
);
415 PKIX_RETURN(LDAPDEFAULTCLIENT
);
419 * FUNCTION: pkix_pl_LdapDefaultClient_RecvCheckComplete
422 * This function determines whether the current response in the
423 * LdapDefaultClient pointed to by "client" is complete, in the sense that all
424 * bytes required to satisfy the message length field in the encoding have been
425 * received. If so, the pointer to input data is updated to reflect the number
426 * of bytes consumed, provided by "bytesProcessed". The state machine flag
427 * pointed to by "pKeepGoing" is updated to indicate whether processing can
428 * continue without further input.
432 * The address of the LdapDefaultClient object. Must be non-NULL.
434 * The UInt32 value of the number of bytes consumed from the current
437 * The address at which the Boolean state machine flag is stored to
438 * indicate whether processing can continue without further input.
441 * Platform-specific context pointer.
443 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
445 * Returns NULL if the function succeeds.
446 * Returns a LdapDefaultClient Error if the function fails in a
448 * Returns a Fatal Error if the function fails in an unrecoverable way.
451 pkix_pl_LdapDefaultClient_RecvCheckComplete(
452 PKIX_PL_LdapDefaultClient
*client
,
453 PKIX_UInt32 bytesProcessed
,
454 PKIX_Boolean
*pKeepGoing
,
457 PKIX_Boolean complete
= PKIX_FALSE
;
458 SECStatus rv
= SECFailure
;
459 LDAPMessageType messageType
= 0;
460 LDAPResultCode resultCode
= 0;
464 "pkix_pl_LdapDefaultClient_RecvCheckComplete");
465 PKIX_NULLCHECK_TWO(client
, pKeepGoing
);
467 PKIX_CHECK(pkix_pl_LdapResponse_IsComplete
468 (client
->currentResponse
, &complete
, plContext
),
469 PKIX_LDAPRESPONSEISCOMPLETEFAILED
);
472 PKIX_CHECK(pkix_pl_LdapResponse_Decode
473 (client
->arena
, client
->currentResponse
, &rv
, plContext
),
474 PKIX_LDAPRESPONSEDECODEFAILED
);
476 if (rv
!= SECSuccess
) {
477 PKIX_ERROR(PKIX_CANTDECODESEARCHRESPONSEFROMSERVER
);
480 PKIX_CHECK(pkix_pl_LdapResponse_GetMessageType
481 (client
->currentResponse
, &messageType
, plContext
),
482 PKIX_LDAPRESPONSEGETMESSAGETYPEFAILED
);
484 if (messageType
== LDAP_SEARCHRESPONSEENTRY_TYPE
) {
486 if (client
->entriesFound
== NULL
) {
487 PKIX_CHECK(PKIX_List_Create
488 (&(client
->entriesFound
), plContext
),
489 PKIX_LISTCREATEFAILED
);
492 PKIX_CHECK(PKIX_List_AppendItem
493 (client
->entriesFound
,
494 (PKIX_PL_Object
*)client
->currentResponse
,
496 PKIX_LISTAPPENDITEMFAILED
);
498 PKIX_DECREF(client
->currentResponse
);
500 /* current receive buffer empty? */
501 if (client
->currentBytesAvailable
== 0) {
502 client
->connectStatus
= RECV
;
503 *pKeepGoing
= PKIX_TRUE
;
505 client
->connectStatus
= RECV_INITIAL
;
506 client
->currentInPtr
= &((char *)
507 (client
->currentInPtr
))[bytesProcessed
];
508 *pKeepGoing
= PKIX_TRUE
;
511 } else if (messageType
== LDAP_SEARCHRESPONSERESULT_TYPE
) {
512 PKIX_CHECK(pkix_pl_LdapResponse_GetResultCode
513 (client
->currentResponse
,
516 PKIX_LDAPRESPONSEGETRESULTCODEFAILED
);
518 if ((client
->entriesFound
== NULL
) &&
519 ((resultCode
== SUCCESS
) ||
520 (resultCode
== NOSUCHOBJECT
))) {
521 PKIX_CHECK(PKIX_List_Create
522 (&(client
->entriesFound
), plContext
),
523 PKIX_LISTCREATEFAILED
);
524 } else if (resultCode
== SUCCESS
) {
525 PKIX_CHECK(PKIX_List_SetImmutable
526 (client
->entriesFound
, plContext
),
527 PKIX_LISTSETIMMUTABLEFAILED
);
528 PKIX_CHECK(PKIX_PL_HashTable_Add
530 (PKIX_PL_Object
*)client
->currentRequest
,
531 (PKIX_PL_Object
*)client
->entriesFound
,
533 PKIX_HASHTABLEADDFAILED
);
535 PKIX_ERROR(PKIX_UNEXPECTEDRESULTCODEINRESPONSE
);
538 client
->connectStatus
= BOUND
;
539 *pKeepGoing
= PKIX_FALSE
;
540 PKIX_DECREF(client
->currentResponse
);
543 PKIX_ERROR(PKIX_SEARCHRESPONSEPACKETOFUNKNOWNTYPE
);
546 client
->connectStatus
= RECV
;
547 *pKeepGoing
= PKIX_TRUE
;
551 PKIX_RETURN(LDAPDEFAULTCLIENT
);
554 /* --Private-LdapDefaultClient-Object-Functions------------------------- */
557 pkix_pl_LdapDefaultClient_InitiateRequest(
558 PKIX_PL_LdapClient
*client
,
559 LDAPRequestParams
*requestParams
,
561 PKIX_List
**pResponse
,
565 pkix_pl_LdapDefaultClient_ResumeRequest(
566 PKIX_PL_LdapClient
*client
,
568 PKIX_List
**pResponse
,
572 * FUNCTION: pkix_pl_LdapDefaultClient_CreateHelper
575 * This function creates a new LdapDefaultClient using the Socket pointed to
576 * by "socket", the PRIntervalTime pointed to by "timeout", and the
577 * LDAPBindAPI pointed to by "bindAPI", and stores the result at "pClient".
579 * A value of zero for "timeout" means the LDAPClient will use non-blocking
584 * Address of the Socket to be used for the client. Must be non-NULL.
586 * The address of the LDAPBindAPI containing the Bind information to be
587 * encoded in the Bind message.
589 * The address at which the created LdapDefaultClient is to be stored.
592 * Platform-specific context pointer.
594 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
596 * Returns NULL if the function succeeds.
597 * Returns a LdapDefaultClient Error if the function fails in
599 * Returns a Fatal Error if the function fails in an unrecoverable way.
602 pkix_pl_LdapDefaultClient_CreateHelper(
603 PKIX_PL_Socket
*socket
,
604 LDAPBindAPI
*bindAPI
,
605 PKIX_PL_LdapDefaultClient
**pClient
,
608 PKIX_PL_HashTable
*ht
;
609 PKIX_PL_LdapDefaultClient
*ldapDefaultClient
= NULL
;
610 PKIX_PL_Socket_Callback
*callbackList
;
611 PRFileDesc
*fileDesc
= NULL
;
612 PRArenaPool
*arena
= NULL
;
614 PKIX_ENTER(LDAPDEFAULTCLIENT
, "pkix_pl_LdapDefaultClient_CreateHelper");
615 PKIX_NULLCHECK_TWO(socket
, pClient
);
617 PKIX_CHECK(PKIX_PL_Object_Alloc
618 (PKIX_LDAPDEFAULTCLIENT_TYPE
,
619 sizeof (PKIX_PL_LdapDefaultClient
),
620 (PKIX_PL_Object
**)&ldapDefaultClient
,
622 PKIX_COULDNOTCREATELDAPDEFAULTCLIENTOBJECT
);
624 ldapDefaultClient
->vtable
.initiateFcn
=
625 pkix_pl_LdapDefaultClient_InitiateRequest
;
626 ldapDefaultClient
->vtable
.resumeFcn
=
627 pkix_pl_LdapDefaultClient_ResumeRequest
;
629 PKIX_CHECK(pkix_pl_Socket_GetPRFileDesc
630 (socket
, &fileDesc
, plContext
),
631 PKIX_SOCKETGETPRFILEDESCFAILED
);
633 ldapDefaultClient
->pollDesc
.fd
= fileDesc
;
634 ldapDefaultClient
->pollDesc
.in_flags
= 0;
635 ldapDefaultClient
->pollDesc
.out_flags
= 0;
637 ldapDefaultClient
->bindAPI
= bindAPI
;
639 PKIX_CHECK(PKIX_PL_HashTable_Create
640 (LDAP_CACHEBUCKETS
, 0, &ht
, plContext
),
641 PKIX_HASHTABLECREATEFAILED
);
643 ldapDefaultClient
->cachePtr
= ht
;
645 PKIX_CHECK(pkix_pl_Socket_GetCallbackList
646 (socket
, &callbackList
, plContext
),
647 PKIX_SOCKETGETCALLBACKLISTFAILED
);
649 ldapDefaultClient
->callbackList
= callbackList
;
652 ldapDefaultClient
->clientSocket
= socket
;
654 ldapDefaultClient
->messageID
= 0;
656 ldapDefaultClient
->bindAPI
= bindAPI
;
658 arena
= PORT_NewArena(DER_DEFAULT_CHUNKSIZE
);
660 PKIX_ERROR_FATAL(PKIX_OUTOFMEMORY
);
662 ldapDefaultClient
->arena
= arena
;
664 ldapDefaultClient
->sendBuf
= NULL
;
665 ldapDefaultClient
->bytesToWrite
= 0;
667 PKIX_CHECK(PKIX_PL_Malloc
668 (RCVBUFSIZE
, &ldapDefaultClient
->rcvBuf
, plContext
),
670 ldapDefaultClient
->capacity
= RCVBUFSIZE
;
672 ldapDefaultClient
->bindMsg
= NULL
;
673 ldapDefaultClient
->bindMsgLen
= 0;
675 ldapDefaultClient
->entriesFound
= NULL
;
676 ldapDefaultClient
->currentRequest
= NULL
;
677 ldapDefaultClient
->currentResponse
= NULL
;
679 *pClient
= ldapDefaultClient
;
683 if (PKIX_ERROR_RECEIVED
) {
684 PKIX_DECREF(ldapDefaultClient
);
687 PKIX_RETURN(LDAPDEFAULTCLIENT
);
691 * FUNCTION: PKIX_PL_LdapDefaultClient_Create
694 * This function creates a new LdapDefaultClient using the PRNetAddr pointed to
695 * by "sockaddr", the PRIntervalTime pointed to by "timeout", and the
696 * LDAPBindAPI pointed to by "bindAPI", and stores the result at "pClient".
698 * A value of zero for "timeout" means the LDAPClient will use non-blocking
703 * Address of the PRNetAddr to be used for the socket connection. Must be
706 * The PRIntervalTime to be used in I/O requests for this client.
708 * The address of the LDAPBindAPI containing the Bind information to be
709 * encoded in the Bind message.
711 * The address at which the created LdapDefaultClient is to be stored.
714 * Platform-specific context pointer.
716 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
718 * Returns NULL if the function succeeds.
719 * Returns a LdapDefaultClient Error if the function fails in
721 * Returns a Fatal Error if the function fails in an unrecoverable way.
724 PKIX_PL_LdapDefaultClient_Create(
726 PRIntervalTime timeout
,
727 LDAPBindAPI
*bindAPI
,
728 PKIX_PL_LdapDefaultClient
**pClient
,
731 PRErrorCode status
= 0;
732 PKIX_PL_Socket
*socket
= NULL
;
733 PKIX_PL_LdapDefaultClient
*client
= NULL
;
735 PKIX_ENTER(LDAPDEFAULTCLIENT
, "PKIX_PL_LdapDefaultClient_Create");
736 PKIX_NULLCHECK_TWO(sockaddr
, pClient
);
738 PKIX_CHECK(pkix_pl_Socket_Create
739 (PKIX_FALSE
, timeout
, sockaddr
, &status
, &socket
, plContext
),
740 PKIX_SOCKETCREATEFAILED
);
742 PKIX_CHECK(pkix_pl_LdapDefaultClient_CreateHelper
743 (socket
, bindAPI
, &client
, plContext
),
744 PKIX_LDAPDEFAULTCLIENTCREATEHELPERFAILED
);
746 /* Did Socket_Create say the connection was made? */
748 if (client
->bindAPI
!= NULL
) {
749 client
->connectStatus
= CONNECTED
;
751 client
->connectStatus
= BOUND
;
754 client
->connectStatus
= CONNECT_PENDING
;
760 if (PKIX_ERROR_RECEIVED
) {
766 PKIX_RETURN(LDAPDEFAULTCLIENT
);
770 * FUNCTION: PKIX_PL_LdapDefaultClient_CreateByName
773 * This function creates a new LdapDefaultClient using the hostname pointed to
774 * by "hostname", the PRIntervalTime pointed to by "timeout", and the
775 * LDAPBindAPI pointed to by "bindAPI", and stores the result at "pClient".
777 * A value of zero for "timeout" means the LDAPClient will use non-blocking
782 * Address of the hostname to be used for the socket connection. Must be
785 * The PRIntervalTime to be used in I/O requests for this client.
787 * The address of the LDAPBindAPI containing the Bind information to be
788 * encoded in the Bind message.
790 * The address at which the created LdapDefaultClient is to be stored.
793 * Platform-specific context pointer.
795 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
797 * Returns NULL if the function succeeds.
798 * Returns a LdapDefaultClient Error if the function fails in
800 * Returns a Fatal Error if the function fails in an unrecoverable way.
803 PKIX_PL_LdapDefaultClient_CreateByName(
805 PRIntervalTime timeout
,
806 LDAPBindAPI
*bindAPI
,
807 PKIX_PL_LdapDefaultClient
**pClient
,
810 PRErrorCode status
= 0;
811 PKIX_PL_Socket
*socket
= NULL
;
812 PKIX_PL_LdapDefaultClient
*client
= NULL
;
814 PKIX_ENTER(LDAPDEFAULTCLIENT
, "PKIX_PL_LdapDefaultClient_CreateByName");
815 PKIX_NULLCHECK_TWO(hostname
, pClient
);
817 PKIX_CHECK(pkix_pl_Socket_CreateByName
818 (PKIX_FALSE
, timeout
, hostname
, &status
, &socket
, plContext
),
819 PKIX_SOCKETCREATEBYNAMEFAILED
);
821 PKIX_CHECK(pkix_pl_LdapDefaultClient_CreateHelper
822 (socket
, bindAPI
, &client
, plContext
),
823 PKIX_LDAPDEFAULTCLIENTCREATEHELPERFAILED
);
825 /* Did Socket_Create say the connection was made? */
827 if (client
->bindAPI
!= NULL
) {
828 client
->connectStatus
= CONNECTED
;
830 client
->connectStatus
= BOUND
;
833 client
->connectStatus
= CONNECT_PENDING
;
839 if (PKIX_ERROR_RECEIVED
) {
845 PKIX_RETURN(LDAPDEFAULTCLIENT
);
849 * FUNCTION: pkix_pl_LdapDefaultClient_Destroy
850 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
853 pkix_pl_LdapDefaultClient_Destroy(
854 PKIX_PL_Object
*object
,
857 PKIX_Int32 bytesWritten
= 0;
858 PKIX_PL_LdapDefaultClient
*client
= NULL
;
859 PKIX_PL_Socket_Callback
*callbackList
= NULL
;
860 SECItem
*encoded
= NULL
;
862 PKIX_ENTER(LDAPDEFAULTCLIENT
,
863 "pkix_pl_LdapDefaultClient_Destroy");
864 PKIX_NULLCHECK_ONE(object
);
866 PKIX_CHECK(pkix_CheckType
867 (object
, PKIX_LDAPDEFAULTCLIENT_TYPE
, plContext
),
868 PKIX_OBJECTNOTANLDAPDEFAULTCLIENT
);
870 client
= (PKIX_PL_LdapDefaultClient
*)object
;
872 switch (client
->connectStatus
) {
873 case CONNECT_PENDING
:
878 case BIND_RESPONSE_PENDING
:
884 case RECV_NONINITIAL
:
885 case ABANDON_PENDING
:
886 if (client
->bindAPI
!= NULL
) {
887 PKIX_CHECK(pkix_pl_LdapDefaultClient_MakeUnbind
889 ++(client
->messageID
),
892 PKIX_LDAPDEFAULTCLIENTMAKEUNBINDFAILED
);
895 (PKIX_PL_Socket_Callback
*)(client
->callbackList
);
896 PKIX_CHECK(callbackList
->sendCallback
897 (client
->clientSocket
,
902 PKIX_SOCKETSENDFAILED
);
906 PKIX_ERROR(PKIX_LDAPDEFAULTCLIENTINILLEGALSTATE
);
909 PKIX_DECREF(client
->cachePtr
);
910 PKIX_DECREF(client
->clientSocket
);
911 PKIX_DECREF(client
->entriesFound
);
912 PKIX_DECREF(client
->currentRequest
);
913 PKIX_DECREF(client
->currentResponse
);
915 PKIX_CHECK(PKIX_PL_Free
916 (client
->rcvBuf
, plContext
), PKIX_FREEFAILED
);
921 (client
->arena
, PR_FALSE
));
925 PKIX_RETURN(LDAPDEFAULTCLIENT
);
929 * FUNCTION: pkix_pl_LdapDefaultClient_Hashcode
930 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
933 pkix_pl_LdapDefaultClient_Hashcode(
934 PKIX_PL_Object
*object
,
935 PKIX_UInt32
*pHashcode
,
938 PKIX_PL_LdapDefaultClient
*ldapDefaultClient
= NULL
;
939 PKIX_UInt32 tempHash
= 0;
942 (LDAPDEFAULTCLIENT
, "pkix_pl_LdapDefaultClient_Hashcode");
943 PKIX_NULLCHECK_TWO(object
, pHashcode
);
945 PKIX_CHECK(pkix_CheckType
946 (object
, PKIX_LDAPDEFAULTCLIENT_TYPE
, plContext
),
947 PKIX_OBJECTNOTANLDAPDEFAULTCLIENT
);
949 ldapDefaultClient
= (PKIX_PL_LdapDefaultClient
*)object
;
951 PKIX_CHECK(PKIX_PL_Object_Hashcode
952 ((PKIX_PL_Object
*)ldapDefaultClient
->clientSocket
,
955 PKIX_SOCKETHASHCODEFAILED
);
957 if (ldapDefaultClient
->bindAPI
!= NULL
) {
958 tempHash
= (tempHash
<< 7) +
959 ldapDefaultClient
->bindAPI
->selector
;
962 *pHashcode
= tempHash
;
966 PKIX_RETURN(LDAPDEFAULTCLIENT
);
970 * FUNCTION: pkix_pl_LdapDefaultClient_Equals
971 * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h)
974 pkix_pl_LdapDefaultClient_Equals(
975 PKIX_PL_Object
*firstObject
,
976 PKIX_PL_Object
*secondObject
,
980 PKIX_PL_LdapDefaultClient
*firstClientContext
= NULL
;
981 PKIX_PL_LdapDefaultClient
*secondClientContext
= NULL
;
982 PKIX_Int32 compare
= 0;
984 PKIX_ENTER(LDAPDEFAULTCLIENT
, "pkix_pl_LdapDefaultClient_Equals");
985 PKIX_NULLCHECK_THREE(firstObject
, secondObject
, pResult
);
987 *pResult
= PKIX_FALSE
;
989 PKIX_CHECK(pkix_CheckTypes
992 PKIX_LDAPDEFAULTCLIENT_TYPE
,
994 PKIX_OBJECTNOTANLDAPDEFAULTCLIENT
);
996 firstClientContext
= (PKIX_PL_LdapDefaultClient
*)firstObject
;
997 secondClientContext
= (PKIX_PL_LdapDefaultClient
*)secondObject
;
999 if (firstClientContext
== secondClientContext
) {
1000 *pResult
= PKIX_TRUE
;
1004 PKIX_CHECK(PKIX_PL_Object_Equals
1005 ((PKIX_PL_Object
*)firstClientContext
->clientSocket
,
1006 (PKIX_PL_Object
*)secondClientContext
->clientSocket
,
1009 PKIX_SOCKETEQUALSFAILED
);
1015 if (PKIX_EXACTLY_ONE_NULL
1016 (firstClientContext
->bindAPI
, secondClientContext
->bindAPI
)) {
1020 if (firstClientContext
->bindAPI
) {
1021 if (firstClientContext
->bindAPI
->selector
!=
1022 secondClientContext
->bindAPI
->selector
) {
1027 *pResult
= PKIX_TRUE
;
1031 PKIX_RETURN(LDAPDEFAULTCLIENT
);
1035 * FUNCTION: pkix_pl_LdapDefaultClient_RegisterSelf
1038 * Registers PKIX_PL_LDAPDEFAULTCLIENT_TYPE and its related
1039 * functions with systemClasses[]
1042 * Not Thread Safe - for performance and complexity reasons
1044 * Since this function is only called by PKIX_PL_Initialize, which should
1045 * only be called once, it is acceptable that this function is not
1049 pkix_pl_LdapDefaultClient_RegisterSelf(void *plContext
)
1051 extern pkix_ClassTable_Entry systemClasses
[PKIX_NUMTYPES
];
1052 pkix_ClassTable_Entry entry
;
1056 "pkix_pl_LdapDefaultClient_RegisterSelf");
1058 entry
.description
= "LdapDefaultClient";
1059 entry
.objCounter
= 0;
1060 entry
.typeObjectSize
= sizeof(PKIX_PL_LdapDefaultClient
);
1061 entry
.destructor
= pkix_pl_LdapDefaultClient_Destroy
;
1062 entry
.equalsFunction
= pkix_pl_LdapDefaultClient_Equals
;
1063 entry
.hashcodeFunction
= pkix_pl_LdapDefaultClient_Hashcode
;
1064 entry
.toStringFunction
= NULL
;
1065 entry
.comparator
= NULL
;
1066 entry
.duplicateFunction
= NULL
;
1068 systemClasses
[PKIX_LDAPDEFAULTCLIENT_TYPE
] = entry
;
1070 PKIX_RETURN(LDAPDEFAULTCLIENT
);
1074 * FUNCTION: pkix_pl_LdapDefaultClient_GetPollDesc
1077 * This function retrieves the PRPollDesc from the LdapDefaultClient
1078 * pointed to by "context" and stores the address at "pPollDesc".
1082 * The LdapDefaultClient whose PRPollDesc is desired. Must be non-NULL.
1084 * Address where PRPollDesc will be stored. Must be non-NULL.
1086 * Platform-specific context pointer.
1088 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1090 * Returns NULL if the function succeeds.
1091 * Returns a Fatal Error if the function fails in an unrecoverable way.
1094 pkix_pl_LdapDefaultClient_GetPollDesc(
1095 PKIX_PL_LdapDefaultClient
*context
,
1096 PRPollDesc
**pPollDesc
,
1101 "pkix_pl_LdapDefaultClient_GetPollDesc");
1102 PKIX_NULLCHECK_TWO(context
, pPollDesc
);
1104 *pPollDesc
= &(context
->pollDesc
);
1106 PKIX_RETURN(LDAPDEFAULTCLIENT
);
1109 /* --Private-Ldap-CertStore-I/O-Functions---------------------------- */
1111 * FUNCTION: pkix_pl_LdapDefaultClient_ConnectContinue
1114 * This function determines whether a socket Connect initiated earlier for the
1115 * CertStore embodied in the LdapDefaultClient "client" has completed, and
1116 * stores in "pKeepGoing" a flag indicating whether processing can continue
1117 * without further input.
1121 * The address of the LdapDefaultClient object. Must be non-NULL.
1123 * The address at which the Boolean state machine flag is stored to
1124 * indicate whether processing can continue without further input.
1127 * Platform-specific context pointer.
1129 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1131 * Returns NULL if the function succeeds.
1132 * Returns a LdapDefaultClient Error if the function fails in a
1134 * Returns a Fatal Error if the function fails in an unrecoverable way.
1137 pkix_pl_LdapDefaultClient_ConnectContinue(
1138 PKIX_PL_LdapDefaultClient
*client
,
1139 PKIX_Boolean
*pKeepGoing
,
1142 PKIX_PL_Socket_Callback
*callbackList
;
1144 PKIX_Boolean keepGoing
= PKIX_FALSE
;
1148 "pkix_pl_LdapDefaultClient_ConnectContinue");
1149 PKIX_NULLCHECK_ONE(client
);
1151 callbackList
= (PKIX_PL_Socket_Callback
*)(client
->callbackList
);
1153 PKIX_CHECK(callbackList
->connectcontinueCallback
1154 (client
->clientSocket
, &status
, plContext
),
1155 PKIX_SOCKETCONNECTCONTINUEFAILED
);
1158 if (client
->bindAPI
!= NULL
) {
1159 client
->connectStatus
= CONNECTED
;
1161 client
->connectStatus
= BOUND
;
1163 keepGoing
= PKIX_FALSE
;
1164 } else if (status
!= PR_IN_PROGRESS_ERROR
) {
1165 PKIX_ERROR(PKIX_UNEXPECTEDERRORINESTABLISHINGCONNECTION
);
1168 PKIX_CHECK(PKIX_PL_Object_InvalidateCache
1169 ((PKIX_PL_Object
*)client
, plContext
),
1170 PKIX_OBJECTINVALIDATECACHEFAILED
);
1172 *pKeepGoing
= keepGoing
;
1175 PKIX_RETURN(LDAPDEFAULTCLIENT
);
1179 * FUNCTION: pkix_pl_LdapDefaultClient_Bind
1182 * This function creates and sends the LDAP-protocol Bind message for the
1183 * CertStore embodied in the LdapDefaultClient "client", and stores in
1184 * "pKeepGoing" a flag indicating whether processing can continue without
1189 * The address of the LdapDefaultClient object. Must be non-NULL.
1191 * The address at which the Boolean state machine flag is stored to
1192 * indicate whether processing can continue without further input.
1195 * Platform-specific context pointer.
1197 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1199 * Returns NULL if the function succeeds.
1200 * Returns a LdapDefaultClient Error if the function fails in a
1202 * Returns a Fatal Error if the function fails in an unrecoverable way.
1205 pkix_pl_LdapDefaultClient_Bind(
1206 PKIX_PL_LdapDefaultClient
*client
,
1207 PKIX_Boolean
*pKeepGoing
,
1210 SECItem
*encoded
= NULL
;
1211 PKIX_Int32 bytesWritten
= 0;
1212 PKIX_PL_Socket_Callback
*callbackList
;
1214 PKIX_ENTER(LDAPDEFAULTCLIENT
, "pkix_pl_LdapDefaultClient_Bind");
1215 PKIX_NULLCHECK_ONE(client
);
1217 /* if we have not yet constructed the BIND message, build it now */
1218 if (!(client
->bindMsg
)) {
1219 PKIX_CHECK(pkix_pl_LdapDefaultClient_MakeBind
1226 PKIX_LDAPDEFAULTCLIENTMAKEBINDFAILED
);
1227 client
->bindMsg
= encoded
->data
;
1228 client
->bindMsgLen
= encoded
->len
;
1231 callbackList
= (PKIX_PL_Socket_Callback
*)(client
->callbackList
);
1233 PKIX_CHECK(callbackList
->sendCallback
1234 (client
->clientSocket
,
1239 PKIX_SOCKETSENDFAILED
);
1241 client
->lastIO
= PR_Now();
1243 if (bytesWritten
< 0) {
1244 client
->connectStatus
= BIND_PENDING
;
1245 *pKeepGoing
= PKIX_FALSE
;
1247 client
->connectStatus
= BIND_RESPONSE
;
1248 *pKeepGoing
= PKIX_TRUE
;
1251 PKIX_CHECK(PKIX_PL_Object_InvalidateCache
1252 ((PKIX_PL_Object
*)client
, plContext
),
1253 PKIX_OBJECTINVALIDATECACHEFAILED
);
1256 PKIX_RETURN(LDAPDEFAULTCLIENT
);
1260 * FUNCTION: pkix_pl_LdapDefaultClient_BindContinue
1263 * This function determines whether the LDAP-protocol Bind message for the
1264 * CertStore embodied in the LdapDefaultClient "client" has completed, and
1265 * stores in "pKeepGoing" a flag indicating whether processing can continue
1266 * without further input.
1270 * The address of the LdapDefaultClient object. Must be non-NULL.
1272 * The address at which the Boolean state machine flag is stored to
1273 * indicate whether processing can continue without further input.
1276 * Platform-specific context pointer.
1278 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1280 * Returns NULL if the function succeeds.
1281 * Returns a LdapDefaultClient Error if the function fails in a
1283 * Returns a Fatal Error if the function fails in an unrecoverable way.
1285 PKIX_Error
*pkix_pl_LdapDefaultClient_BindContinue(
1286 PKIX_PL_LdapDefaultClient
*client
,
1287 PKIX_Boolean
*pKeepGoing
,
1290 PKIX_Int32 bytesWritten
= 0;
1291 PKIX_PL_Socket_Callback
*callbackList
= NULL
;
1293 PKIX_ENTER(LDAPDEFAULTCLIENT
, "pkix_pl_LdapDefaultClient_BindContinue");
1294 PKIX_NULLCHECK_ONE(client
);
1296 *pKeepGoing
= PKIX_FALSE
;
1298 callbackList
= (PKIX_PL_Socket_Callback
*)(client
->callbackList
);
1300 PKIX_CHECK(callbackList
->pollCallback
1301 (client
->clientSocket
, &bytesWritten
, NULL
, plContext
),
1302 PKIX_SOCKETPOLLFAILED
);
1305 * If the send completed we can proceed to try for the
1306 * response. If the send did not complete we will have
1309 if (bytesWritten
>= 0) {
1311 client
->connectStatus
= BIND_RESPONSE
;
1313 PKIX_CHECK(PKIX_PL_Object_InvalidateCache
1314 ((PKIX_PL_Object
*)client
, plContext
),
1315 PKIX_OBJECTINVALIDATECACHEFAILED
);
1317 *pKeepGoing
= PKIX_TRUE
;
1321 PKIX_RETURN(LDAPDEFAULTCLIENT
);
1325 * FUNCTION: pkix_pl_LdapDefaultClient_BindResponse
1328 * This function attempts to read the LDAP-protocol BindResponse message for
1329 * the CertStore embodied in the LdapDefaultClient "client", and stores in
1330 * "pKeepGoing" a flag indicating whether processing can continue without
1333 * If a BindResponse is received with a Result code of 0 (success), we
1334 * continue with the connection. If a non-zero Result code is received,
1335 * we throw an Error. Some more sophisticated handling of that condition
1336 * might be in order in the future.
1340 * The address of the LdapDefaultClient object. Must be non-NULL.
1342 * The address at which the Boolean state machine flag is stored to
1343 * indicate whether processing can continue without further input.
1346 * Platform-specific context pointer.
1348 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1350 * Returns NULL if the function succeeds.
1351 * Returns a LdapDefaultClient Error if the function fails in a
1353 * Returns a Fatal Error if the function fails in an unrecoverable way.
1356 pkix_pl_LdapDefaultClient_BindResponse(
1357 PKIX_PL_LdapDefaultClient
*client
,
1358 PKIX_Boolean
*pKeepGoing
,
1361 PKIX_Int32 bytesRead
= 0;
1362 PKIX_PL_Socket_Callback
*callbackList
= NULL
;
1364 PKIX_ENTER(LDAPDEFAULTCLIENT
, "pkix_pl_LdapDefaultClient_BindResponse");
1365 PKIX_NULLCHECK_TWO(client
, client
->rcvBuf
);
1367 callbackList
= (PKIX_PL_Socket_Callback
*)(client
->callbackList
);
1369 PKIX_CHECK(callbackList
->recvCallback
1370 (client
->clientSocket
,
1375 PKIX_SOCKETRECVFAILED
);
1377 client
->lastIO
= PR_Now();
1379 if (bytesRead
> 0) {
1380 PKIX_CHECK(pkix_pl_LdapDefaultClient_VerifyBindResponse
1381 (client
, bytesRead
, plContext
),
1382 PKIX_LDAPDEFAULTCLIENTVERIFYBINDRESPONSEFAILED
);
1384 * XXX What should we do if failure? At present if
1385 * VerifyBindResponse throws an Error, we do too.
1387 client
->connectStatus
= BOUND
;
1389 client
->connectStatus
= BIND_RESPONSE_PENDING
;
1392 PKIX_CHECK(PKIX_PL_Object_InvalidateCache
1393 ((PKIX_PL_Object
*)client
, plContext
),
1394 PKIX_OBJECTINVALIDATECACHEFAILED
);
1396 *pKeepGoing
= PKIX_TRUE
;
1399 PKIX_RETURN(LDAPDEFAULTCLIENT
);
1403 * FUNCTION: pkix_pl_LdapDefaultClient_BindResponseContinue
1406 * This function determines whether the LDAP-protocol BindResponse message for
1407 * the CertStore embodied in the LdapDefaultClient "client" has completed, and
1408 * stores in "pKeepGoing" a flag indicating whether processing can continue
1409 * without further input.
1413 * The address of the LdapDefaultClient object. Must be non-NULL.
1415 * The address at which the Boolean state machine flag is stored to
1416 * indicate whether processing can continue without further input.
1419 * Platform-specific context pointer.
1421 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1423 * Returns NULL if the function succeeds.
1424 * Returns a LdapDefaultClient Error if the function fails in a
1426 * Returns a Fatal Error if the function fails in an unrecoverable way.
1429 pkix_pl_LdapDefaultClient_BindResponseContinue(
1430 PKIX_PL_LdapDefaultClient
*client
,
1431 PKIX_Boolean
*pKeepGoing
,
1434 PKIX_Int32 bytesRead
= 0;
1435 PKIX_PL_Socket_Callback
*callbackList
= NULL
;
1439 "pkix_pl_LdapDefaultClient_BindResponseContinue");
1440 PKIX_NULLCHECK_ONE(client
);
1442 callbackList
= (PKIX_PL_Socket_Callback
*)(client
->callbackList
);
1444 PKIX_CHECK(callbackList
->pollCallback
1445 (client
->clientSocket
, NULL
, &bytesRead
, plContext
),
1446 PKIX_SOCKETPOLLFAILED
);
1448 if (bytesRead
> 0) {
1449 PKIX_CHECK(pkix_pl_LdapDefaultClient_VerifyBindResponse
1450 (client
, bytesRead
, plContext
),
1451 PKIX_LDAPDEFAULTCLIENTVERIFYBINDRESPONSEFAILED
);
1452 client
->connectStatus
= BOUND
;
1454 PKIX_CHECK(PKIX_PL_Object_InvalidateCache
1455 ((PKIX_PL_Object
*)client
, plContext
),
1456 PKIX_OBJECTINVALIDATECACHEFAILED
);
1458 *pKeepGoing
= PKIX_TRUE
;
1460 *pKeepGoing
= PKIX_FALSE
;
1464 PKIX_RETURN(LDAPDEFAULTCLIENT
);
1468 * FUNCTION: pkix_pl_LdapDefaultClient_Send
1471 * This function creates and sends an LDAP-protocol message for the
1472 * CertStore embodied in the LdapDefaultClient "client", and stores in
1473 * "pKeepGoing" a flag indicating whether processing can continue without
1474 * further input, and at "pBytesTransferred" the number of bytes sent.
1476 * If "pBytesTransferred" is zero, it indicates that non-blocking I/O is in use
1477 * and that transmission has not completed.
1481 * The address of the LdapDefaultClient object. Must be non-NULL.
1483 * The address at which the Boolean state machine flag is stored to
1484 * indicate whether processing can continue without further input.
1486 * "pBytesTransferred"
1487 * The address at which the number of bytes sent is stored. Must be
1490 * Platform-specific context pointer.
1492 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1494 * Returns NULL if the function succeeds.
1495 * Returns a LdapDefaultClient Error if the function fails in a
1497 * Returns a Fatal Error if the function fails in an unrecoverable way.
1500 pkix_pl_LdapDefaultClient_Send(
1501 PKIX_PL_LdapDefaultClient
*client
,
1502 PKIX_Boolean
*pKeepGoing
,
1503 PKIX_UInt32
*pBytesTransferred
,
1506 PKIX_Int32 bytesWritten
= 0;
1507 PKIX_PL_Socket_Callback
*callbackList
= NULL
;
1509 PKIX_ENTER(LDAPDEFAULTCLIENT
, "pkix_pl_LdapDefaultClient_Send");
1510 PKIX_NULLCHECK_THREE(client
, pKeepGoing
, pBytesTransferred
);
1512 *pKeepGoing
= PKIX_FALSE
;
1514 /* Do we have anything waiting to go? */
1515 if (client
->sendBuf
) {
1516 callbackList
= (PKIX_PL_Socket_Callback
*)(client
->callbackList
);
1518 PKIX_CHECK(callbackList
->sendCallback
1519 (client
->clientSocket
,
1521 client
->bytesToWrite
,
1524 PKIX_SOCKETSENDFAILED
);
1526 client
->lastIO
= PR_Now();
1529 * If the send completed we can proceed to try for the
1530 * response. If the send did not complete we will have
1531 * to poll for completion later.
1533 if (bytesWritten
>= 0) {
1534 client
->sendBuf
= NULL
;
1535 client
->connectStatus
= RECV
;
1536 *pKeepGoing
= PKIX_TRUE
;
1539 *pKeepGoing
= PKIX_FALSE
;
1540 client
->connectStatus
= SEND_PENDING
;
1545 PKIX_CHECK(PKIX_PL_Object_InvalidateCache
1546 ((PKIX_PL_Object
*)client
, plContext
),
1547 PKIX_OBJECTINVALIDATECACHEFAILED
);
1549 *pBytesTransferred
= bytesWritten
;
1552 PKIX_RETURN(LDAPDEFAULTCLIENT
);
1556 * FUNCTION: pkix_pl_LdapDefaultClient_SendContinue
1559 * This function determines whether the sending of the LDAP-protocol message
1560 * for the CertStore embodied in the LdapDefaultClient "client" has completed,
1561 * and stores in "pKeepGoing" a flag indicating whether processing can continue
1562 * without further input, and at "pBytesTransferred" the number of bytes sent.
1564 * If "pBytesTransferred" is zero, it indicates that non-blocking I/O is in use
1565 * and that transmission has not completed.
1569 * The address of the LdapDefaultClient object. Must be non-NULL.
1571 * The address at which the Boolean state machine flag is stored to
1572 * indicate whether processing can continue without further input.
1574 * "pBytesTransferred"
1575 * The address at which the number of bytes sent is stored. Must be
1578 * Platform-specific context pointer.
1580 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1582 * Returns NULL if the function succeeds.
1583 * Returns a LdapDefaultClient Error if the function fails in a
1585 * Returns a Fatal Error if the function fails in an unrecoverable way.
1588 pkix_pl_LdapDefaultClient_SendContinue(
1589 PKIX_PL_LdapDefaultClient
*client
,
1590 PKIX_Boolean
*pKeepGoing
,
1591 PKIX_UInt32
*pBytesTransferred
,
1594 PKIX_Int32 bytesWritten
= 0;
1595 PKIX_PL_Socket_Callback
*callbackList
= NULL
;
1597 PKIX_ENTER(LDAPDEFAULTCLIENT
, "pkix_pl_LdapDefaultClient_SendContinue");
1598 PKIX_NULLCHECK_THREE(client
, pKeepGoing
, pBytesTransferred
);
1600 *pKeepGoing
= PKIX_FALSE
;
1602 callbackList
= (PKIX_PL_Socket_Callback
*)(client
->callbackList
);
1604 PKIX_CHECK(callbackList
->pollCallback
1605 (client
->clientSocket
, &bytesWritten
, NULL
, plContext
),
1606 PKIX_SOCKETPOLLFAILED
);
1609 * If the send completed we can proceed to try for the
1610 * response. If the send did not complete we will have
1613 if (bytesWritten
>= 0) {
1614 client
->sendBuf
= NULL
;
1615 client
->connectStatus
= RECV
;
1617 PKIX_CHECK(PKIX_PL_Object_InvalidateCache
1618 ((PKIX_PL_Object
*)client
, plContext
),
1619 PKIX_OBJECTINVALIDATECACHEFAILED
);
1621 *pKeepGoing
= PKIX_TRUE
;
1624 *pBytesTransferred
= bytesWritten
;
1627 PKIX_RETURN(LDAPDEFAULTCLIENT
);
1631 * FUNCTION: pkix_pl_LdapDefaultClient_Recv
1634 * This function receives an LDAP-protocol message for the CertStore embodied
1635 * in the LdapDefaultClient "client", and stores in "pKeepGoing" a flag
1636 * indicating whether processing can continue without further input.
1640 * The address of the LdapDefaultClient object. Must be non-NULL.
1642 * The address at which the Boolean state machine flag is stored to
1643 * indicate whether processing can continue without further input.
1646 * Platform-specific context pointer.
1648 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1650 * Returns NULL if the function succeeds.
1651 * Returns a LdapDefaultClient Error if the function fails in a
1653 * Returns a Fatal Error if the function fails in an unrecoverable way.
1656 pkix_pl_LdapDefaultClient_Recv(
1657 PKIX_PL_LdapDefaultClient
*client
,
1658 PKIX_Boolean
*pKeepGoing
,
1661 PKIX_Int32 bytesRead
= 0;
1662 PKIX_UInt32 bytesToRead
= 0;
1663 PKIX_PL_Socket_Callback
*callbackList
= NULL
;
1665 PKIX_ENTER(LDAPDEFAULTCLIENT
, "pkix_pl_LdapDefaultClient_Recv");
1666 PKIX_NULLCHECK_THREE(client
, pKeepGoing
, client
->rcvBuf
);
1668 callbackList
= (PKIX_PL_Socket_Callback
*)(client
->callbackList
);
1671 * If we attempt to fill our buffer with every read, we increase
1672 * the risk of an ugly situation: one or two bytes of a new message
1673 * left over at the end of processing one message. With such a
1674 * fragment, we can't decode a byte count and so won't know how much
1675 * space to allocate for the next LdapResponse. We try to avoid that
1676 * case by reading just enough to complete the current message, unless
1677 * there will be at least MINIMUM_MSG_LENGTH bytes left over.
1679 if (client
->currentResponse
) {
1680 PKIX_CHECK(pkix_pl_LdapResponse_GetCapacity
1681 (client
->currentResponse
, &bytesToRead
, plContext
),
1682 PKIX_LDAPRESPONSEGETCAPACITYFAILED
);
1683 if ((bytesToRead
> client
->capacity
) ||
1684 ((bytesToRead
+ MINIMUM_MSG_LENGTH
) < client
->capacity
)) {
1685 bytesToRead
= client
->capacity
;
1688 bytesToRead
= client
->capacity
;
1691 client
->currentBytesAvailable
= 0;
1693 PKIX_CHECK(callbackList
->recvCallback
1694 (client
->clientSocket
,
1695 (void *)client
->rcvBuf
,
1699 PKIX_SOCKETRECVFAILED
);
1701 client
->currentInPtr
= client
->rcvBuf
;
1702 client
->lastIO
= PR_Now();
1704 if (bytesRead
> 0) {
1705 client
->currentBytesAvailable
= bytesRead
;
1706 client
->connectStatus
= RECV_INITIAL
;
1707 *pKeepGoing
= PKIX_TRUE
;
1709 client
->connectStatus
= RECV_PENDING
;
1710 *pKeepGoing
= PKIX_FALSE
;
1713 PKIX_CHECK(PKIX_PL_Object_InvalidateCache
1714 ((PKIX_PL_Object
*)client
, plContext
),
1715 PKIX_OBJECTINVALIDATECACHEFAILED
);
1718 PKIX_RETURN(LDAPDEFAULTCLIENT
);
1722 * FUNCTION: pkix_pl_LdapDefaultClient_RecvContinue
1725 * This function determines whether the receiving of the LDAP-protocol message
1726 * for the CertStore embodied in the LdapDefaultClient "client" has completed,
1727 * and stores in "pKeepGoing" a flag indicating whether processing can continue
1728 * without further input.
1732 * The address of the LdapDefaultClient object. Must be non-NULL.
1734 * The address at which the Boolean state machine flag is stored to
1735 * indicate whether processing can continue without further input.
1738 * Platform-specific context pointer.
1740 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1742 * Returns NULL if the function succeeds.
1743 * Returns a LdapDefaultClient Error if the function fails in a
1745 * Returns a Fatal Error if the function fails in an unrecoverable way.
1748 pkix_pl_LdapDefaultClient_RecvContinue(
1749 PKIX_PL_LdapDefaultClient
*client
,
1750 PKIX_Boolean
*pKeepGoing
,
1753 PKIX_Int32 bytesRead
= 0;
1754 PKIX_PL_Socket_Callback
*callbackList
= NULL
;
1756 PKIX_ENTER(LDAPDEFAULTCLIENT
, "pkix_pl_LdapDefaultClient_RecvContinue");
1757 PKIX_NULLCHECK_TWO(client
, pKeepGoing
);
1759 callbackList
= (PKIX_PL_Socket_Callback
*)(client
->callbackList
);
1761 PKIX_CHECK(callbackList
->pollCallback
1762 (client
->clientSocket
, NULL
, &bytesRead
, plContext
),
1763 PKIX_SOCKETPOLLFAILED
);
1765 if (bytesRead
> 0) {
1766 client
->currentBytesAvailable
+= bytesRead
;
1767 client
->connectStatus
= RECV_INITIAL
;
1768 *pKeepGoing
= PKIX_TRUE
;
1770 PKIX_CHECK(PKIX_PL_Object_InvalidateCache
1771 ((PKIX_PL_Object
*)client
, plContext
),
1772 PKIX_OBJECTINVALIDATECACHEFAILED
);
1774 *pKeepGoing
= PKIX_FALSE
;
1778 PKIX_RETURN(LDAPDEFAULTCLIENT
);
1782 * FUNCTION: pkix_pl_LdapDefaultClient_AbandonContinue
1785 * This function determines whether the abandon-message request of the
1786 * LDAP-protocol message for the CertStore embodied in the LdapDefaultClient
1787 * "client" has completed, and stores in "pKeepGoing" a flag indicating whether
1788 * processing can continue without further input.
1792 * The address of the LdapDefaultClient object. Must be non-NULL.
1794 * The address at which the Boolean state machine flag is stored to
1795 * indicate whether processing can continue without further input.
1798 * Platform-specific context pointer.
1800 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1802 * Returns NULL if the function succeeds.
1803 * Returns a LdapDefaultClient Error if the function fails in a
1805 * Returns a Fatal Error if the function fails in an unrecoverable way.
1808 pkix_pl_LdapDefaultClient_AbandonContinue(
1809 PKIX_PL_LdapDefaultClient
*client
,
1810 PKIX_Boolean
*pKeepGoing
,
1813 PKIX_Int32 bytesWritten
= 0;
1814 PKIX_PL_Socket_Callback
*callbackList
= NULL
;
1817 (LDAPDEFAULTCLIENT
, "pkix_pl_LdapDefaultClient_AbandonContinue");
1818 PKIX_NULLCHECK_TWO(client
, pKeepGoing
);
1820 callbackList
= (PKIX_PL_Socket_Callback
*)(client
->callbackList
);
1822 PKIX_CHECK(callbackList
->pollCallback
1823 (client
->clientSocket
, &bytesWritten
, NULL
, plContext
),
1824 PKIX_SOCKETPOLLFAILED
);
1826 if (bytesWritten
> 0) {
1827 client
->connectStatus
= BOUND
;
1828 *pKeepGoing
= PKIX_TRUE
;
1830 PKIX_CHECK(PKIX_PL_Object_InvalidateCache
1831 ((PKIX_PL_Object
*)client
, plContext
),
1832 PKIX_OBJECTINVALIDATECACHEFAILED
);
1834 *pKeepGoing
= PKIX_FALSE
;
1838 PKIX_RETURN(LDAPDEFAULTCLIENT
);
1842 * FUNCTION: pkix_pl_LdapDefaultClient_RecvInitial
1845 * This function processes the contents of the first buffer of a received
1846 * LDAP-protocol message for the CertStore embodied in the LdapDefaultClient
1847 * "client", and stores in "pKeepGoing" a flag indicating whether processing can
1848 * continue without further input.
1852 * The address of the LdapDefaultClient object. Must be non-NULL.
1854 * The address at which the Boolean state machine flag is stored to
1855 * indicate whether processing can continue without further input.
1858 * Platform-specific context pointer.
1860 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1862 * Returns NULL if the function succeeds.
1863 * Returns a LdapDefaultClient Error if the function fails in a
1865 * Returns a Fatal Error if the function fails in an unrecoverable way.
1868 pkix_pl_LdapDefaultClient_RecvInitial(
1869 PKIX_PL_LdapDefaultClient
*client
,
1870 PKIX_Boolean
*pKeepGoing
,
1873 unsigned char *msgBuf
= NULL
;
1874 unsigned char *to
= NULL
;
1875 unsigned char *from
= NULL
;
1876 PKIX_UInt32 dataIndex
= 0;
1877 PKIX_UInt32 messageIdLen
= 0;
1878 PKIX_UInt32 messageLength
= 0;
1879 PKIX_UInt32 sizeofLength
= 0;
1880 PKIX_UInt32 bytesProcessed
= 0;
1881 unsigned char messageChar
= 0;
1882 LDAPMessageType messageType
= 0;
1883 PKIX_Int32 bytesRead
= 0;
1884 PKIX_PL_Socket_Callback
*callbackList
= NULL
;
1886 PKIX_ENTER(LDAPDEFAULTCLIENT
, "pkix_pl_LdapDefaultClient_RecvInitial");
1887 PKIX_NULLCHECK_TWO(client
, pKeepGoing
);
1890 * Is there an LDAPResponse in progress? I.e., have we
1891 * already processed the tag and length at the beginning of
1894 if (client
->currentResponse
) {
1895 client
->connectStatus
= RECV_NONINITIAL
;
1896 *pKeepGoing
= PKIX_TRUE
;
1899 msgBuf
= client
->currentInPtr
;
1901 /* Do we have enough of the message to decode the message length? */
1902 if (client
->currentBytesAvailable
< MINIMUM_MSG_LENGTH
) {
1904 * No! Move these few bytes to the beginning of rcvBuf
1905 * and hang another read.
1908 to
= (unsigned char *)client
->rcvBuf
;
1909 from
= client
->currentInPtr
;
1911 dataIndex
< client
->currentBytesAvailable
;
1915 callbackList
= (PKIX_PL_Socket_Callback
*)(client
->callbackList
);
1916 PKIX_CHECK(callbackList
->recvCallback
1917 (client
->clientSocket
,
1919 client
->capacity
- client
->currentBytesAvailable
,
1922 PKIX_SOCKETRECVFAILED
);
1924 client
->currentInPtr
= client
->rcvBuf
;
1925 client
->lastIO
= PR_Now();
1927 if (bytesRead
<= 0) {
1928 client
->connectStatus
= RECV_PENDING
;
1929 *pKeepGoing
= PKIX_FALSE
;
1932 client
->currentBytesAvailable
+= bytesRead
;
1937 * We have to determine whether the response is an entry, with
1938 * application-specific tag LDAP_SEARCHRESPONSEENTRY_TYPE, or a
1939 * resultCode, with application tag LDAP_SEARCHRESPONSERESULT_TYPE.
1940 * First, we have to figure out where to look for the tag.
1943 /* Is the message length short form (one octet) or long form? */
1944 if ((msgBuf
[1] & 0x80) != 0) {
1945 sizeofLength
= msgBuf
[1] & 0x7F;
1946 for (dataIndex
= 0; dataIndex
< sizeofLength
; dataIndex
++) {
1948 (messageLength
<< 8) + msgBuf
[dataIndex
+ 2];
1951 messageLength
= msgBuf
[1];
1954 /* How many bytes did the messageID require? */
1955 messageIdLen
= msgBuf
[dataIndex
+ 3];
1957 messageChar
= msgBuf
[dataIndex
+ messageIdLen
+ 4];
1959 /* Are we looking at an Entry message or a ResultCode message? */
1960 if ((SEC_ASN1_CONSTRUCTED
| SEC_ASN1_APPLICATION
|
1961 LDAP_SEARCHRESPONSEENTRY_TYPE
) == messageChar
) {
1963 messageType
= LDAP_SEARCHRESPONSEENTRY_TYPE
;
1965 } else if ((SEC_ASN1_CONSTRUCTED
| SEC_ASN1_APPLICATION
|
1966 LDAP_SEARCHRESPONSERESULT_TYPE
) == messageChar
) {
1968 messageType
= LDAP_SEARCHRESPONSERESULT_TYPE
;
1972 PKIX_ERROR(PKIX_SEARCHRESPONSEPACKETOFUNKNOWNTYPE
);
1977 * messageLength is the length from (tag, length, value).
1978 * We have to allocate space for the tag and length bits too.
1980 PKIX_CHECK(pkix_pl_LdapResponse_Create
1982 messageLength
+ dataIndex
+ 2,
1983 client
->currentBytesAvailable
,
1986 &(client
->currentResponse
),
1988 PKIX_LDAPRESPONSECREATEFAILED
);
1990 client
->currentBytesAvailable
-= bytesProcessed
;
1992 PKIX_CHECK(pkix_pl_LdapDefaultClient_RecvCheckComplete
1993 (client
, bytesProcessed
, pKeepGoing
, plContext
),
1994 PKIX_LDAPDEFAULTCLIENTRECVCHECKCOMPLETEFAILED
);
1998 PKIX_RETURN(LDAPDEFAULTCLIENT
);
2002 * FUNCTION: pkix_pl_LdapDefaultClient_RecvNonInitial
2005 * This function processes the contents of buffers, after the first, of a
2006 * received LDAP-protocol message for the CertStore embodied in the
2007 * LdapDefaultClient "client", and stores in "pKeepGoing" a flag indicating
2008 * whether processing can continue without further input.
2012 * The address of the LdapDefaultClient object. Must be non-NULL.
2014 * The address at which the Boolean state machine flag is stored to
2015 * indicate whether processing can continue without further input.
2018 * Platform-specific context pointer.
2020 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
2022 * Returns NULL if the function succeeds.
2023 * Returns a LdapDefaultClient Error if the function fails in a
2025 * Returns a Fatal Error if the function fails in an unrecoverable way.
2028 pkix_pl_LdapDefaultClient_RecvNonInitial(
2029 PKIX_PL_LdapDefaultClient
*client
,
2030 PKIX_Boolean
*pKeepGoing
,
2034 PKIX_UInt32 bytesProcessed
= 0;
2037 (LDAPDEFAULTCLIENT
, "pkix_pl_LdapDefaultClient_RecvNonInitial");
2038 PKIX_NULLCHECK_TWO(client
, pKeepGoing
);
2040 PKIX_CHECK(pkix_pl_LdapResponse_Append
2041 (client
->currentResponse
,
2042 client
->currentBytesAvailable
,
2043 client
->currentInPtr
,
2046 PKIX_LDAPRESPONSEAPPENDFAILED
);
2048 client
->currentBytesAvailable
-= bytesProcessed
;
2050 PKIX_CHECK(pkix_pl_LdapDefaultClient_RecvCheckComplete
2051 (client
, bytesProcessed
, pKeepGoing
, plContext
),
2052 PKIX_LDAPDEFAULTCLIENTRECVCHECKCOMPLETEFAILED
);
2056 PKIX_RETURN(LDAPDEFAULTCLIENT
);
2060 * FUNCTION: pkix_pl_LdapDefaultClient_Dispatch
2063 * This function is the state machine dispatcher for the CertStore embodied in
2064 * the LdapDefaultClient pointed to by "client". Results are returned by
2065 * changes to various fields in the context.
2069 * The address of the LdapDefaultClient object. Must be non-NULL.
2071 * Platform-specific context pointer.
2073 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
2075 * Returns NULL if the function succeeds.
2076 * Returns a LdapDefaultClient Error if the function fails in a
2078 * Returns a Fatal Error if the function fails in an unrecoverable way.
2081 pkix_pl_LdapDefaultClient_Dispatch(
2082 PKIX_PL_LdapDefaultClient
*client
,
2085 PKIX_UInt32 bytesTransferred
= 0;
2086 PKIX_Boolean keepGoing
= PKIX_TRUE
;
2088 PKIX_ENTER(LDAPDEFAULTCLIENT
, "pkix_pl_LdapDefaultClient_Dispatch");
2089 PKIX_NULLCHECK_ONE(client
);
2092 switch (client
->connectStatus
) {
2093 case CONNECT_PENDING
:
2095 (pkix_pl_LdapDefaultClient_ConnectContinue
2096 (client
, &keepGoing
, plContext
),
2097 PKIX_LDAPDEFAULTCLIENTCONNECTCONTINUEFAILED
);
2101 (pkix_pl_LdapDefaultClient_Bind
2102 (client
, &keepGoing
, plContext
),
2103 PKIX_LDAPDEFAULTCLIENTBINDFAILED
);
2107 (pkix_pl_LdapDefaultClient_BindContinue
2108 (client
, &keepGoing
, plContext
),
2109 PKIX_LDAPDEFAULTCLIENTBINDCONTINUEFAILED
);
2113 (pkix_pl_LdapDefaultClient_BindResponse
2114 (client
, &keepGoing
, plContext
),
2115 PKIX_LDAPDEFAULTCLIENTBINDRESPONSEFAILED
);
2117 case BIND_RESPONSE_PENDING
:
2119 (pkix_pl_LdapDefaultClient_BindResponseContinue
2120 (client
, &keepGoing
, plContext
),
2121 PKIX_LDAPDEFAULTCLIENTBINDRESPONSECONTINUEFAILED
);
2125 (pkix_pl_LdapDefaultClient_Send
2126 (client
, &keepGoing
, &bytesTransferred
, plContext
),
2127 PKIX_LDAPDEFAULTCLIENTSENDFAILED
);
2131 (pkix_pl_LdapDefaultClient_SendContinue
2132 (client
, &keepGoing
, &bytesTransferred
, plContext
),
2133 PKIX_LDAPDEFAULTCLIENTSENDCONTINUEFAILED
);
2137 (pkix_pl_LdapDefaultClient_Recv
2138 (client
, &keepGoing
, plContext
),
2139 PKIX_LDAPDEFAULTCLIENTRECVFAILED
);
2143 (pkix_pl_LdapDefaultClient_RecvContinue
2144 (client
, &keepGoing
, plContext
),
2145 PKIX_LDAPDEFAULTCLIENTRECVCONTINUEFAILED
);
2149 (pkix_pl_LdapDefaultClient_RecvInitial
2150 (client
, &keepGoing
, plContext
),
2151 PKIX_LDAPDEFAULTCLIENTRECVINITIALFAILED
);
2153 case RECV_NONINITIAL
:
2155 (pkix_pl_LdapDefaultClient_RecvNonInitial
2156 (client
, &keepGoing
, plContext
),
2157 PKIX_LDAPDEFAULTCLIENTRECVNONINITIALFAILED
);
2159 case ABANDON_PENDING
:
2161 (pkix_pl_LdapDefaultClient_AbandonContinue
2162 (client
, &keepGoing
, plContext
),
2163 PKIX_LDAPDEFAULTCLIENTABANDONCONTINUEFAILED
);
2166 PKIX_ERROR(PKIX_LDAPCERTSTOREINILLEGALSTATE
);
2172 PKIX_RETURN(LDAPDEFAULTCLIENT
);
2176 * FUNCTION: pkix_pl_LdapDefaultClient_MakeAndFilter
2179 * This function allocates space from the arena pointed to by "arena" to
2180 * construct a filter that will match components of the X500Name pointed to by
2185 * The address of the PRArenaPool used in creating the filter. Must be
2188 * The address of a NULL-terminated list of LDAPNameComponents
2191 * The address at which the result is stored.
2193 * Platform-specific context pointer
2195 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
2197 * Returns NULL if the function succeeds.
2198 * Returns a CertStore Error if the function fails in a non-fatal way.
2199 * Returns a Fatal Error if the function fails in an unrecoverable way.
2202 pkix_pl_LdapDefaultClient_MakeAndFilter(
2204 LDAPNameComponent
**nameComponents
,
2205 LDAPFilter
**pFilter
,
2208 LDAPFilter
**setOfFilter
;
2209 LDAPFilter
*andFilter
= NULL
;
2210 LDAPFilter
*currentFilter
= NULL
;
2211 PKIX_UInt32 componentsPresent
= 0;
2213 unsigned char *component
= NULL
;
2214 LDAPNameComponent
**componentP
= NULL
;
2216 PKIX_ENTER(CERTSTORE
, "pkix_pl_LdapDefaultClient_MakeAndFilter");
2217 PKIX_NULLCHECK_THREE(arena
, nameComponents
, pFilter
);
2219 /* count how many components we were provided */
2220 for (componentP
= nameComponents
, componentsPresent
= 0;
2221 *(componentP
++) != NULL
;
2222 componentsPresent
++) {}
2224 /* Space for (componentsPresent + 1) pointers to LDAPFilter */
2225 PKIX_PL_NSSCALLRV(CERTSTORE
, v
, PORT_ArenaZAlloc
,
2226 (arena
, (componentsPresent
+ 1)*sizeof(LDAPFilter
*)));
2227 setOfFilter
= (LDAPFilter
**)v
;
2229 /* Space for AndFilter and <componentsPresent> EqualFilters */
2230 PKIX_PL_NSSCALLRV(CERTSTORE
, v
, PORT_ArenaZNewArray
,
2231 (arena
, LDAPFilter
, componentsPresent
+ 1));
2232 setOfFilter
[0] = (LDAPFilter
*)v
;
2234 /* Claim the first array element for the ANDFilter */
2235 andFilter
= setOfFilter
[0];
2237 /* Set ANDFilter to point to the first EqualFilter pointer */
2238 andFilter
->selector
= LDAP_ANDFILTER_TYPE
;
2239 andFilter
->filter
.andFilter
.filters
= setOfFilter
;
2241 currentFilter
= andFilter
+ 1;
2243 for (componentP
= nameComponents
, componentsPresent
= 0;
2244 *(componentP
) != NULL
; componentP
++) {
2245 setOfFilter
[componentsPresent
++] = currentFilter
;
2246 currentFilter
->selector
= LDAP_EQUALFILTER_TYPE
;
2247 component
= (*componentP
)->attrType
;
2248 currentFilter
->filter
.equalFilter
.attrType
.data
= component
;
2249 currentFilter
->filter
.equalFilter
.attrType
.len
=
2250 PL_strlen((const char *)component
);
2251 component
= (*componentP
)->attrValue
;
2252 currentFilter
->filter
.equalFilter
.attrValue
.data
= component
;
2253 currentFilter
->filter
.equalFilter
.attrValue
.len
=
2254 PL_strlen((const char *)component
);
2258 setOfFilter
[componentsPresent
] = NULL
;
2260 *pFilter
= andFilter
;
2262 PKIX_RETURN(CERTSTORE
);
2267 * FUNCTION: pkix_pl_LdapDefaultClient_InitiateRequest
2273 * The address of the LdapDefaultClient object. Must be non-NULL.
2275 * The address of an LdapClientParams object. Must be non-NULL.
2277 * The location where the address of the PRPollDesc is stored, if the
2278 * client returns with I/O pending.
2280 * The address where the List of LDAPResponses, or NULL for an
2281 * unfinished request, is stored. Must be non-NULL.
2283 * Platform-specific context pointer.
2285 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
2287 * Returns NULL if the function succeeds.
2288 * Returns a LdapDefaultClient Error if the function fails in a
2290 * Returns a Fatal Error if the function fails in an unrecoverable way.
2293 pkix_pl_LdapDefaultClient_InitiateRequest(
2294 PKIX_PL_LdapClient
*genericClient
,
2295 LDAPRequestParams
*requestParams
,
2297 PKIX_List
**pResponse
,
2300 PKIX_List
*searchResponseList
= NULL
;
2301 SECItem
*encoded
= NULL
;
2302 LDAPFilter
*filter
= NULL
;
2303 PKIX_PL_LdapDefaultClient
*client
= 0;
2307 "pkix_pl_LdapDefaultClient_InitiateRequest");
2308 PKIX_NULLCHECK_FOUR(genericClient
, requestParams
, pPollDesc
, pResponse
);
2310 PKIX_CHECK(pkix_CheckType
2311 ((PKIX_PL_Object
*)genericClient
,
2312 PKIX_LDAPDEFAULTCLIENT_TYPE
,
2314 PKIX_GENERICCLIENTNOTANLDAPDEFAULTCLIENT
);
2316 client
= (PKIX_PL_LdapDefaultClient
*)genericClient
;
2318 PKIX_CHECK(pkix_pl_LdapDefaultClient_MakeAndFilter
2319 (client
->arena
, requestParams
->nc
, &filter
, plContext
),
2320 PKIX_LDAPDEFAULTCLIENTMAKEANDFILTERFAILED
);
2322 PKIX_CHECK(pkix_pl_LdapRequest_Create
2324 client
->messageID
++,
2325 requestParams
->baseObject
,
2326 requestParams
->scope
,
2327 requestParams
->derefAliases
,
2328 requestParams
->sizeLimit
,
2329 requestParams
->timeLimit
,
2330 PKIX_FALSE
, /* attrs only */
2332 requestParams
->attributes
,
2333 &client
->currentRequest
,
2335 PKIX_LDAPREQUESTCREATEFAILED
);
2337 /* check hashtable for matching request */
2338 PKIX_CHECK(PKIX_PL_HashTable_Lookup
2340 (PKIX_PL_Object
*)(client
->currentRequest
),
2341 (PKIX_PL_Object
**)&searchResponseList
,
2343 PKIX_HASHTABLELOOKUPFAILED
);
2345 if (searchResponseList
!= NULL
) {
2347 *pResponse
= searchResponseList
;
2348 PKIX_DECREF(client
->currentRequest
);
2352 /* It wasn't cached. We'll have to actually send it. */
2354 PKIX_CHECK(pkix_pl_LdapRequest_GetEncoded
2355 (client
->currentRequest
, &encoded
, plContext
),
2356 PKIX_LDAPREQUESTGETENCODEDFAILED
);
2358 client
->sendBuf
= encoded
->data
;
2359 client
->bytesToWrite
= encoded
->len
;
2361 PKIX_CHECK(pkix_pl_LdapDefaultClient_Dispatch(client
, plContext
),
2362 PKIX_LDAPDEFAULTCLIENTDISPATCHFAILED
);
2365 * It's not enough that we may be done with a particular read.
2366 * We're still processing the transaction until we've gotten the
2367 * SearchResponseResult message and returned to the BOUND state.
2368 * Otherwise we must still have a read pending, and must hold off
2369 * on returning results.
2371 if ((client
->connectStatus
== BOUND
) &&
2372 (client
->entriesFound
!= NULL
)) {
2374 *pResponse
= client
->entriesFound
;
2375 client
->entriesFound
= NULL
;
2376 PKIX_DECREF(client
->currentRequest
);
2378 *pPollDesc
= &client
->pollDesc
;
2384 PKIX_RETURN(LDAPDEFAULTCLIENT
);
2389 * FUNCTION: pkix_pl_LdapDefaultClient_ResumeRequest
2395 * The address of the LdapDefaultClient object. Must be non-NULL.
2397 * The location where the address of the PRPollDesc is stored, if the
2398 * client returns with I/O pending.
2400 * The address where the List of LDAPResponses, or NULL for an
2401 * unfinished request, is stored. Must be non-NULL.
2403 * Platform-specific context pointer.
2405 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
2407 * Returns NULL if the function succeeds.
2408 * Returns a LdapDefaultClient Error if the function fails in a
2410 * Returns a Fatal Error if the function fails in an unrecoverable way.
2413 pkix_pl_LdapDefaultClient_ResumeRequest(
2414 PKIX_PL_LdapClient
*genericClient
,
2416 PKIX_List
**pResponse
,
2419 PKIX_PL_LdapDefaultClient
*client
= 0;
2422 (LDAPDEFAULTCLIENT
, "pkix_pl_LdapDefaultClient_ResumeRequest");
2423 PKIX_NULLCHECK_THREE(genericClient
, pPollDesc
, pResponse
);
2425 PKIX_CHECK(pkix_CheckType
2426 ((PKIX_PL_Object
*)genericClient
,
2427 PKIX_LDAPDEFAULTCLIENT_TYPE
,
2429 PKIX_GENERICCLIENTNOTANLDAPDEFAULTCLIENT
);
2431 client
= (PKIX_PL_LdapDefaultClient
*)genericClient
;
2433 PKIX_CHECK(pkix_pl_LdapDefaultClient_Dispatch(client
, plContext
),
2434 PKIX_LDAPDEFAULTCLIENTDISPATCHFAILED
);
2437 * It's not enough that we may be done with a particular read.
2438 * We're still processing the transaction until we've gotten the
2439 * SearchResponseResult message and returned to the BOUND state.
2440 * Otherwise we must still have a read pending, and must hold off
2441 * on returning results.
2443 if ((client
->connectStatus
== BOUND
) &&
2444 (client
->entriesFound
!= NULL
)) {
2446 *pResponse
= client
->entriesFound
;
2447 client
->entriesFound
= NULL
;
2448 PKIX_DECREF(client
->currentRequest
);
2450 *pPollDesc
= &client
->pollDesc
;
2456 PKIX_RETURN(LDAPDEFAULTCLIENT
);
2460 /* --Public-LdapDefaultClient-Functions----------------------------------- */
2463 * FUNCTION: PKIX_PL_LdapDefaultClient_AbandonRequest
2466 * This function creates and sends an LDAP-protocol "Abandon" message to the
2467 * server connected to the LdapDefaultClient pointed to by "client".
2471 * The LdapDefaultClient whose connection is to be abandoned. Must be
2474 * Platform-specific context pointer.
2476 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
2478 * Returns NULL if the function succeeds.
2479 * Returns a Fatal Error if the function fails in an unrecoverable way.
2482 PKIX_PL_LdapDefaultClient_AbandonRequest(
2483 PKIX_PL_LdapDefaultClient
*client
,
2486 PKIX_Int32 bytesWritten
= 0;
2487 PKIX_PL_Socket_Callback
*callbackList
= NULL
;
2488 SECItem
*encoded
= NULL
;
2490 PKIX_ENTER(CERTSTORE
, "PKIX_PL_LdapDefaultClient_AbandonRequest");
2491 PKIX_NULLCHECK_ONE(client
);
2493 if (client
->connectStatus
== RECV_PENDING
) {
2494 PKIX_CHECK(pkix_pl_LdapDefaultClient_MakeAbandon
2496 (client
->messageID
) - 1,
2499 PKIX_LDAPDEFAULTCLIENTMAKEABANDONFAILED
);
2501 callbackList
= (PKIX_PL_Socket_Callback
*)(client
->callbackList
);
2502 PKIX_CHECK(callbackList
->sendCallback
2503 (client
->clientSocket
,
2508 PKIX_SOCKETSENDFAILED
);
2510 if (bytesWritten
< 0) {
2511 client
->connectStatus
= ABANDON_PENDING
;
2513 client
->connectStatus
= BOUND
;
2517 PKIX_DECREF(client
->entriesFound
);
2518 PKIX_DECREF(client
->currentRequest
);
2519 PKIX_DECREF(client
->currentResponse
);
2523 PKIX_DECREF(client
);
2525 PKIX_RETURN(CERTSTORE
);