comparison nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapdefaultclient.c @ 0:1e5118fa0cb1

This is NSS with a Cmake Buildsyste To compile a static NSS library for Windows we've used the Chromium-NSS fork and added a Cmake buildsystem to compile it statically for Windows. See README.chromium for chromium changes and README.trustbridge for our modifications.
author Andre Heinecke <andre.heinecke@intevation.de>
date Mon, 28 Jul 2014 10:47:06 +0200
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:1e5118fa0cb1
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 /*
5 * pkix_pl_ldapdefaultclient.c
6 *
7 * LDAPDefaultClient Function Definitions
8 *
9 */
10
11 /* We can't decode the length of a message without at least this many bytes */
12 #define MINIMUM_MSG_LENGTH 5
13
14 #include "pkix_pl_ldapdefaultclient.h"
15
16 /* --Private-LdapDefaultClient-Message-Building-Functions---------------- */
17
18 /*
19 * FUNCTION: pkix_pl_LdapDefaultClient_MakeBind
20 * DESCRIPTION:
21 *
22 * This function creates and encodes a Bind message, using the arena pointed
23 * to by "arena", the version number contained in "versionData", the
24 * LDAPBindAPI pointed to by "bindAPI", and the messageID contained in
25 * "msgNum", and stores a pointer to the encoded string at "pBindMsg".
26 *
27 * See pkix_pl_ldaptemplates.c for the ASN.1 description of a Bind message.
28 *
29 * This code is not used if the DefaultClient was created with a NULL pointer
30 * supplied for the LDAPBindAPI structure. (Bind and Unbind do not seem to be
31 * expected for anonymous Search requests.)
32 *
33 * PARAMETERS:
34 * "arena"
35 * The address of the PLArenaPool used in encoding the message. Must be
36 * non-NULL.
37 * "versionData"
38 * The Int32 containing the version number to be encoded in the Bind
39 * message.
40 * "bindAPI"
41 * The address of the LDAPBindAPI to be encoded in the Bind message. Must
42 * be non-NULL.
43 * "msgNum"
44 * The Int32 containing the MessageID to be encoded in the Bind message.
45 * "pBindMsg"
46 * The address at which the encoded Bind message will be stored. Must be
47 * non-NULL.
48 * "plContext"
49 * Platform-specific context pointer.
50 * THREAD SAFETY:
51 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
52 * RETURNS:
53 * Returns NULL if the function succeeds.
54 * Returns a LdapDefaultClient Error if the function fails in a
55 * non-fatal way.
56 * Returns a Fatal Error if the function fails in an unrecoverable way.
57 */
58 static PKIX_Error *
59 pkix_pl_LdapDefaultClient_MakeBind(
60 PLArenaPool *arena,
61 PKIX_Int32 versionData,
62 LDAPBindAPI *bindAPI,
63 PKIX_UInt32 msgNum,
64 SECItem **pBindMsg,
65 void *plContext)
66 {
67 LDAPMessage msg;
68 char version = '\0';
69 SECItem *encoded = NULL;
70 PKIX_UInt32 len = 0;
71
72 PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_MakeBind");
73 PKIX_NULLCHECK_TWO(arena, pBindMsg);
74
75 PKIX_PL_NSSCALL(LDAPDEFAULTCLIENT, PORT_Memset,
76 (&msg, 0, sizeof (LDAPMessage)));
77
78 version = (char)versionData;
79
80 msg.messageID.type = siUnsignedInteger;
81 msg.messageID.data = (void*)&msgNum;
82 msg.messageID.len = sizeof (msgNum);
83
84 msg.protocolOp.selector = LDAP_BIND_TYPE;
85
86 msg.protocolOp.op.bindMsg.version.type = siUnsignedInteger;
87 msg.protocolOp.op.bindMsg.version.data = (void *)&version;
88 msg.protocolOp.op.bindMsg.version.len = sizeof (char);
89
90 /*
91 * XXX At present we only know how to handle anonymous requests (no
92 * authentication), and we are guessing how to do simple authentication.
93 * This section will need to be revised and extended when other
94 * authentication is needed.
95 */
96 if (bindAPI->selector == SIMPLE_AUTH) {
97 msg.protocolOp.op.bindMsg.bindName.type = siAsciiString;
98 msg.protocolOp.op.bindMsg.bindName.data =
99 (void *)bindAPI->chooser.simple.bindName;
100 len = PL_strlen(bindAPI->chooser.simple.bindName);
101 msg.protocolOp.op.bindMsg.bindName.len = len;
102
103 msg.protocolOp.op.bindMsg.authentication.type = siAsciiString;
104 msg.protocolOp.op.bindMsg.authentication.data =
105 (void *)bindAPI->chooser.simple.authentication;
106 len = PL_strlen(bindAPI->chooser.simple.authentication);
107 msg.protocolOp.op.bindMsg.authentication.len = len;
108 }
109
110 PKIX_PL_NSSCALLRV(LDAPDEFAULTCLIENT, encoded, SEC_ASN1EncodeItem,
111 (arena, NULL, (void *)&msg, PKIX_PL_LDAPMessageTemplate));
112 if (!encoded) {
113 PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED);
114 }
115
116 *pBindMsg = encoded;
117 cleanup:
118
119 PKIX_RETURN(LDAPDEFAULTCLIENT);
120 }
121
122 /*
123 * FUNCTION: pkix_pl_LdapDefaultClient_MakeUnbind
124 * DESCRIPTION:
125 *
126 * This function creates and encodes a Unbind message, using the arena pointed
127 * to by "arena" and the messageID contained in "msgNum", and stores a pointer
128 * to the encoded string at "pUnbindMsg".
129 *
130 * See pkix_pl_ldaptemplates.c for the ASN.1 description of an Unbind message.
131 *
132 * This code is not used if the DefaultClient was created with a NULL pointer
133 * supplied for the LDAPBindAPI structure. (Bind and Unbind do not seem to be
134 * expected for anonymous Search requests.)
135 *
136 * PARAMETERS:
137 * "arena"
138 * The address of the PLArenaPool used in encoding the message. Must be
139 * non-NULL.
140 * "msgNum"
141 * The Int32 containing the MessageID to be encoded in the Unbind message.
142 * "pUnbindMsg"
143 * The address at which the encoded Unbind message will be stored. Must
144 * be non-NULL.
145 * "plContext"
146 * Platform-specific context pointer.
147 * THREAD SAFETY:
148 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
149 * RETURNS:
150 * Returns NULL if the function succeeds.
151 * Returns a LdapDefaultClient Error if the function fails in a
152 * non-fatal way.
153 * Returns a Fatal Error if the function fails in an unrecoverable way.
154 */
155 static PKIX_Error *
156 pkix_pl_LdapDefaultClient_MakeUnbind(
157 PLArenaPool *arena,
158 PKIX_UInt32 msgNum,
159 SECItem **pUnbindMsg,
160 void *plContext)
161 {
162 LDAPMessage msg;
163 SECItem *encoded = NULL;
164
165 PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_MakeUnbind");
166 PKIX_NULLCHECK_TWO(arena, pUnbindMsg);
167
168 PKIX_PL_NSSCALL(LDAPDEFAULTCLIENT, PORT_Memset,
169 (&msg, 0, sizeof (LDAPMessage)));
170
171 msg.messageID.type = siUnsignedInteger;
172 msg.messageID.data = (void*)&msgNum;
173 msg.messageID.len = sizeof (msgNum);
174
175 msg.protocolOp.selector = LDAP_UNBIND_TYPE;
176
177 msg.protocolOp.op.unbindMsg.dummy.type = siBuffer;
178 msg.protocolOp.op.unbindMsg.dummy.data = NULL;
179 msg.protocolOp.op.unbindMsg.dummy.len = 0;
180
181 PKIX_PL_NSSCALLRV(LDAPDEFAULTCLIENT, encoded, SEC_ASN1EncodeItem,
182 (arena, NULL, (void *)&msg, PKIX_PL_LDAPMessageTemplate));
183 if (!encoded) {
184 PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED);
185 }
186
187 *pUnbindMsg = encoded;
188 cleanup:
189
190 PKIX_RETURN(LDAPDEFAULTCLIENT);
191 }
192
193 /*
194 * FUNCTION: pkix_pl_LdapDefaultClient_MakeAbandon
195 * DESCRIPTION:
196 *
197 * This function creates and encodes a Abandon message, using the arena pointed
198 * to by "arena" and the messageID contained in "msgNum", and stores a pointer
199 * to the encoded string at "pAbandonMsg".
200 *
201 * See pkix_pl_ldaptemplates.c for the ASN.1 description of an Abandon message.
202 *
203 * PARAMETERS:
204 * "arena"
205 * The address of the PLArenaPool used in encoding the message. Must be
206 * non-NULL.
207 * "msgNum"
208 * The Int32 containing the MessageID to be encoded in the Abandon message.
209 * "pAbandonMsg"
210 * The address at which the encoded Abandon message will be stored. Must
211 * be non-NULL.
212 * "plContext"
213 * Platform-specific context pointer.
214 * THREAD SAFETY:
215 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
216 * RETURNS:
217 * Returns NULL if the function succeeds.
218 * Returns a LdapDefaultClient Error if the function fails in a
219 * non-fatal way.
220 * Returns a Fatal Error if the function fails in an unrecoverable way.
221 */
222 static PKIX_Error *
223 pkix_pl_LdapDefaultClient_MakeAbandon(
224 PLArenaPool *arena,
225 PKIX_UInt32 msgNum,
226 SECItem **pAbandonMsg,
227 void *plContext)
228 {
229 LDAPMessage msg;
230 SECItem *encoded = NULL;
231
232 PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_MakeAbandon");
233 PKIX_NULLCHECK_TWO(arena, pAbandonMsg);
234
235 PKIX_PL_NSSCALL(LDAPDEFAULTCLIENT, PORT_Memset,
236 (&msg, 0, sizeof (LDAPMessage)));
237
238 msg.messageID.type = siUnsignedInteger;
239 msg.messageID.data = (void*)&msgNum;
240 msg.messageID.len = sizeof (msgNum);
241
242 msg.protocolOp.selector = LDAP_ABANDONREQUEST_TYPE;
243
244 msg.protocolOp.op.abandonRequestMsg.messageID.type = siBuffer;
245 msg.protocolOp.op.abandonRequestMsg.messageID.data = (void*)&msgNum;
246 msg.protocolOp.op.abandonRequestMsg.messageID.len = sizeof (msgNum);
247
248 PKIX_PL_NSSCALLRV(LDAPDEFAULTCLIENT, encoded, SEC_ASN1EncodeItem,
249 (arena, NULL, (void *)&msg, PKIX_PL_LDAPMessageTemplate));
250 if (!encoded) {
251 PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED);
252 }
253
254 *pAbandonMsg = encoded;
255 cleanup:
256
257 PKIX_RETURN(LDAPDEFAULTCLIENT);
258 }
259
260 /*
261 * FUNCTION: pkix_pl_LdapDefaultClient_DecodeBindResponse
262 * DESCRIPTION:
263 *
264 * This function decodes the encoded data pointed to by "src", using the arena
265 * pointed to by "arena", storing the decoded LDAPMessage at "pBindResponse"
266 * and the decoding status at "pStatus".
267 *
268 * PARAMETERS:
269 * "arena"
270 * The address of the PLArenaPool to be used in decoding the message. Must
271 * be non-NULL.
272 * "src"
273 * The address of the SECItem containing the DER- (or BER-)encoded string.
274 * Must be non-NULL.
275 * "pBindResponse"
276 * The address at which the LDAPMessage is stored, if the decoding is
277 * successful (the returned status is SECSuccess). Must be non-NULL.
278 * "pStatus"
279 * The address at which the decoding status is stored. Must be non-NULL.
280 * "plContext"
281 * Platform-specific context pointer.
282 * THREAD SAFETY:
283 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
284 * RETURNS:
285 * Returns NULL if the function succeeds.
286 * Returns a LdapDefaultClient Error if the function fails in a
287 * non-fatal way.
288 * Returns a Fatal Error if the function fails in an unrecoverable way.
289 */
290 static PKIX_Error *
291 pkix_pl_LdapDefaultClient_DecodeBindResponse(
292 PLArenaPool *arena,
293 SECItem *src,
294 LDAPMessage *pBindResponse,
295 SECStatus *pStatus,
296 void *plContext)
297 {
298 SECStatus rv = SECFailure;
299 LDAPMessage response;
300
301 PKIX_ENTER
302 (LDAPDEFAULTCLIENT,
303 "pkix_pl_LdapDefaultClient_DecodeBindResponse");
304 PKIX_NULLCHECK_FOUR(arena, src, pBindResponse, pStatus);
305
306 PKIX_PL_NSSCALL
307 (LDAPDEFAULTCLIENT,
308 PORT_Memset,
309 (&response, 0, sizeof (LDAPMessage)));
310
311 PKIX_PL_NSSCALLRV(LDAPDEFAULTCLIENT, rv, SEC_ASN1DecodeItem,
312 (arena, &response, PKIX_PL_LDAPMessageTemplate, src));
313
314 if (rv == SECSuccess) {
315 *pBindResponse = response;
316 }
317
318 *pStatus = rv;
319
320 PKIX_RETURN(LDAPDEFAULTCLIENT);
321 }
322
323 /*
324 * FUNCTION: pkix_pl_LdapDefaultClient_VerifyBindResponse
325 * DESCRIPTION:
326 *
327 * This function verifies that the contents of the message in the rcvbuf of
328 * the LdapDefaultClient object pointed to by "client", and whose length is
329 * provided by "buflen", is a response to a successful Bind.
330 *
331 * PARAMETERS:
332 * "client"
333 * The address of the LdapDefaultClient object. Must be non-NULL.
334 * "buflen"
335 * The value of the number of bytes in the receive buffer.
336 * "plContext"
337 * Platform-specific context pointer.
338 * THREAD SAFETY:
339 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
340 * RETURNS:
341 * Returns NULL if the function succeeds.
342 * Returns a LdapDefaultClient Error if the function fails in a
343 * non-fatal way.
344 * Returns a Fatal Error if the function fails in an unrecoverable way.
345 */
346 static PKIX_Error *
347 pkix_pl_LdapDefaultClient_VerifyBindResponse(
348 PKIX_PL_LdapDefaultClient *client,
349 PKIX_UInt32 bufLen,
350 void *plContext)
351 {
352 SECItem decode = {siBuffer, NULL, 0};
353 SECStatus rv = SECFailure;
354 LDAPMessage msg;
355 LDAPBindResponse *ldapBindResponse = NULL;
356
357 PKIX_ENTER
358 (LDAPDEFAULTCLIENT,
359 "pkix_pl_LdapDefaultClient_VerifyBindResponse");
360 PKIX_NULLCHECK_TWO(client, client->rcvBuf);
361
362 decode.data = (void *)(client->rcvBuf);
363 decode.len = bufLen;
364
365 PKIX_CHECK(pkix_pl_LdapDefaultClient_DecodeBindResponse
366 (client->arena, &decode, &msg, &rv, plContext),
367 PKIX_LDAPDEFAULTCLIENTDECODEBINDRESPONSEFAILED);
368
369 if (rv == SECSuccess) {
370 ldapBindResponse = &msg.protocolOp.op.bindResponseMsg;
371 if (*(ldapBindResponse->resultCode.data) == SUCCESS) {
372 client->connectStatus = BOUND;
373 } else {
374 PKIX_ERROR(PKIX_BINDREJECTEDBYSERVER);
375 }
376 } else {
377 PKIX_ERROR(PKIX_CANTDECODEBINDRESPONSEFROMSERVER);
378 }
379
380 cleanup:
381
382 PKIX_RETURN(LDAPDEFAULTCLIENT);
383 }
384
385 /*
386 * FUNCTION: pkix_pl_LdapDefaultClient_RecvCheckComplete
387 * DESCRIPTION:
388 *
389 * This function determines whether the current response in the
390 * LdapDefaultClient pointed to by "client" is complete, in the sense that all
391 * bytes required to satisfy the message length field in the encoding have been
392 * received. If so, the pointer to input data is updated to reflect the number
393 * of bytes consumed, provided by "bytesProcessed". The state machine flag
394 * pointed to by "pKeepGoing" is updated to indicate whether processing can
395 * continue without further input.
396 *
397 * PARAMETERS:
398 * "client"
399 * The address of the LdapDefaultClient object. Must be non-NULL.
400 * "bytesProcessed"
401 * The UInt32 value of the number of bytes consumed from the current
402 * buffer.
403 * "pKeepGoing"
404 * The address at which the Boolean state machine flag is stored to
405 * indicate whether processing can continue without further input.
406 * Must be non-NULL.
407 * "plContext"
408 * Platform-specific context pointer.
409 * THREAD SAFETY:
410 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
411 * RETURNS:
412 * Returns NULL if the function succeeds.
413 * Returns a LdapDefaultClient Error if the function fails in a
414 * non-fatal way.
415 * Returns a Fatal Error if the function fails in an unrecoverable way.
416 */
417 static PKIX_Error *
418 pkix_pl_LdapDefaultClient_RecvCheckComplete(
419 PKIX_PL_LdapDefaultClient *client,
420 PKIX_UInt32 bytesProcessed,
421 PKIX_Boolean *pKeepGoing,
422 void *plContext)
423 {
424 PKIX_Boolean complete = PKIX_FALSE;
425 SECStatus rv = SECFailure;
426 LDAPMessageType messageType = 0;
427 LDAPResultCode resultCode = 0;
428
429 PKIX_ENTER
430 (LDAPDEFAULTCLIENT,
431 "pkix_pl_LdapDefaultClient_RecvCheckComplete");
432 PKIX_NULLCHECK_TWO(client, pKeepGoing);
433
434 PKIX_CHECK(pkix_pl_LdapResponse_IsComplete
435 (client->currentResponse, &complete, plContext),
436 PKIX_LDAPRESPONSEISCOMPLETEFAILED);
437
438 if (complete) {
439 PKIX_CHECK(pkix_pl_LdapResponse_Decode
440 (client->arena, client->currentResponse, &rv, plContext),
441 PKIX_LDAPRESPONSEDECODEFAILED);
442
443 if (rv != SECSuccess) {
444 PKIX_ERROR(PKIX_CANTDECODESEARCHRESPONSEFROMSERVER);
445 }
446
447 PKIX_CHECK(pkix_pl_LdapResponse_GetMessageType
448 (client->currentResponse, &messageType, plContext),
449 PKIX_LDAPRESPONSEGETMESSAGETYPEFAILED);
450
451 if (messageType == LDAP_SEARCHRESPONSEENTRY_TYPE) {
452
453 if (client->entriesFound == NULL) {
454 PKIX_CHECK(PKIX_List_Create
455 (&(client->entriesFound), plContext),
456 PKIX_LISTCREATEFAILED);
457 }
458
459 PKIX_CHECK(PKIX_List_AppendItem
460 (client->entriesFound,
461 (PKIX_PL_Object *)client->currentResponse,
462 plContext),
463 PKIX_LISTAPPENDITEMFAILED);
464
465 PKIX_DECREF(client->currentResponse);
466
467 /* current receive buffer empty? */
468 if (client->currentBytesAvailable == 0) {
469 client->connectStatus = RECV;
470 *pKeepGoing = PKIX_TRUE;
471 } else {
472 client->connectStatus = RECV_INITIAL;
473 client->currentInPtr = &((char *)
474 (client->currentInPtr))[bytesProcessed];
475 *pKeepGoing = PKIX_TRUE;
476 }
477
478 } else if (messageType == LDAP_SEARCHRESPONSERESULT_TYPE) {
479 PKIX_CHECK(pkix_pl_LdapResponse_GetResultCode
480 (client->currentResponse,
481 &resultCode,
482 plContext),
483 PKIX_LDAPRESPONSEGETRESULTCODEFAILED);
484
485 if ((client->entriesFound == NULL) &&
486 ((resultCode == SUCCESS) ||
487 (resultCode == NOSUCHOBJECT))) {
488 PKIX_CHECK(PKIX_List_Create
489 (&(client->entriesFound), plContext),
490 PKIX_LISTCREATEFAILED);
491 } else if (resultCode == SUCCESS) {
492 PKIX_CHECK(PKIX_List_SetImmutable
493 (client->entriesFound, plContext),
494 PKIX_LISTSETIMMUTABLEFAILED);
495 PKIX_CHECK(PKIX_PL_HashTable_Add
496 (client->cachePtr,
497 (PKIX_PL_Object *)client->currentRequest,
498 (PKIX_PL_Object *)client->entriesFound,
499 plContext),
500 PKIX_HASHTABLEADDFAILED);
501 } else {
502 PKIX_ERROR(PKIX_UNEXPECTEDRESULTCODEINRESPONSE);
503 }
504
505 client->connectStatus = BOUND;
506 *pKeepGoing = PKIX_FALSE;
507 PKIX_DECREF(client->currentResponse);
508
509 } else {
510 PKIX_ERROR(PKIX_SEARCHRESPONSEPACKETOFUNKNOWNTYPE);
511 }
512 } else {
513 client->connectStatus = RECV;
514 *pKeepGoing = PKIX_TRUE;
515 }
516
517 cleanup:
518 PKIX_RETURN(LDAPDEFAULTCLIENT);
519 }
520
521 /* --Private-LdapDefaultClient-Object-Functions------------------------- */
522
523 static PKIX_Error *
524 pkix_pl_LdapDefaultClient_InitiateRequest(
525 PKIX_PL_LdapClient *client,
526 LDAPRequestParams *requestParams,
527 void **pPollDesc,
528 PKIX_List **pResponse,
529 void *plContext);
530
531 static PKIX_Error *
532 pkix_pl_LdapDefaultClient_ResumeRequest(
533 PKIX_PL_LdapClient *client,
534 void **pPollDesc,
535 PKIX_List **pResponse,
536 void *plContext);
537
538 /*
539 * FUNCTION: pkix_pl_LdapDefaultClient_CreateHelper
540 * DESCRIPTION:
541 *
542 * This function creates a new LdapDefaultClient using the Socket pointed to
543 * by "socket", the PRIntervalTime pointed to by "timeout", and the
544 * LDAPBindAPI pointed to by "bindAPI", and stores the result at "pClient".
545 *
546 * A value of zero for "timeout" means the LDAPClient will use non-blocking
547 * I/O.
548 *
549 * PARAMETERS:
550 * "socket"
551 * Address of the Socket to be used for the client. Must be non-NULL.
552 * "bindAPI"
553 * The address of the LDAPBindAPI containing the Bind information to be
554 * encoded in the Bind message.
555 * "pClient"
556 * The address at which the created LdapDefaultClient is to be stored.
557 * Must be non-NULL.
558 * "plContext"
559 * Platform-specific context pointer.
560 * THREAD SAFETY:
561 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
562 * RETURNS:
563 * Returns NULL if the function succeeds.
564 * Returns a LdapDefaultClient Error if the function fails in
565 * a non-fatal way.
566 * Returns a Fatal Error if the function fails in an unrecoverable way.
567 */
568 PKIX_Error *
569 pkix_pl_LdapDefaultClient_CreateHelper(
570 PKIX_PL_Socket *socket,
571 LDAPBindAPI *bindAPI,
572 PKIX_PL_LdapDefaultClient **pClient,
573 void *plContext)
574 {
575 PKIX_PL_HashTable *ht;
576 PKIX_PL_LdapDefaultClient *ldapDefaultClient = NULL;
577 PKIX_PL_Socket_Callback *callbackList;
578 PRFileDesc *fileDesc = NULL;
579 PLArenaPool *arena = NULL;
580
581 PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_CreateHelper");
582 PKIX_NULLCHECK_TWO(socket, pClient);
583
584 PKIX_CHECK(PKIX_PL_Object_Alloc
585 (PKIX_LDAPDEFAULTCLIENT_TYPE,
586 sizeof (PKIX_PL_LdapDefaultClient),
587 (PKIX_PL_Object **)&ldapDefaultClient,
588 plContext),
589 PKIX_COULDNOTCREATELDAPDEFAULTCLIENTOBJECT);
590
591 ldapDefaultClient->vtable.initiateFcn =
592 pkix_pl_LdapDefaultClient_InitiateRequest;
593 ldapDefaultClient->vtable.resumeFcn =
594 pkix_pl_LdapDefaultClient_ResumeRequest;
595
596 PKIX_CHECK(pkix_pl_Socket_GetPRFileDesc
597 (socket, &fileDesc, plContext),
598 PKIX_SOCKETGETPRFILEDESCFAILED);
599
600 ldapDefaultClient->pollDesc.fd = fileDesc;
601 ldapDefaultClient->pollDesc.in_flags = 0;
602 ldapDefaultClient->pollDesc.out_flags = 0;
603
604 ldapDefaultClient->bindAPI = bindAPI;
605
606 PKIX_CHECK(PKIX_PL_HashTable_Create
607 (LDAP_CACHEBUCKETS, 0, &ht, plContext),
608 PKIX_HASHTABLECREATEFAILED);
609
610 ldapDefaultClient->cachePtr = ht;
611
612 PKIX_CHECK(pkix_pl_Socket_GetCallbackList
613 (socket, &callbackList, plContext),
614 PKIX_SOCKETGETCALLBACKLISTFAILED);
615
616 ldapDefaultClient->callbackList = callbackList;
617
618 PKIX_INCREF(socket);
619 ldapDefaultClient->clientSocket = socket;
620
621 ldapDefaultClient->messageID = 0;
622
623 ldapDefaultClient->bindAPI = bindAPI;
624
625 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
626 if (!arena) {
627 PKIX_ERROR_FATAL(PKIX_OUTOFMEMORY);
628 }
629 ldapDefaultClient->arena = arena;
630
631 ldapDefaultClient->sendBuf = NULL;
632 ldapDefaultClient->bytesToWrite = 0;
633
634 PKIX_CHECK(PKIX_PL_Malloc
635 (RCVBUFSIZE, &ldapDefaultClient->rcvBuf, plContext),
636 PKIX_MALLOCFAILED);
637 ldapDefaultClient->capacity = RCVBUFSIZE;
638
639 ldapDefaultClient->bindMsg = NULL;
640 ldapDefaultClient->bindMsgLen = 0;
641
642 ldapDefaultClient->entriesFound = NULL;
643 ldapDefaultClient->currentRequest = NULL;
644 ldapDefaultClient->currentResponse = NULL;
645
646 *pClient = ldapDefaultClient;
647
648 cleanup:
649
650 if (PKIX_ERROR_RECEIVED) {
651 PKIX_DECREF(ldapDefaultClient);
652 }
653
654 PKIX_RETURN(LDAPDEFAULTCLIENT);
655 }
656
657 /*
658 * FUNCTION: PKIX_PL_LdapDefaultClient_Create
659 * DESCRIPTION:
660 *
661 * This function creates a new LdapDefaultClient using the PRNetAddr pointed to
662 * by "sockaddr", the PRIntervalTime pointed to by "timeout", and the
663 * LDAPBindAPI pointed to by "bindAPI", and stores the result at "pClient".
664 *
665 * A value of zero for "timeout" means the LDAPClient will use non-blocking
666 * I/O.
667 *
668 * PARAMETERS:
669 * "sockaddr"
670 * Address of the PRNetAddr to be used for the socket connection. Must be
671 * non-NULL.
672 * "timeout"
673 * The PRIntervalTime to be used in I/O requests for this client.
674 * "bindAPI"
675 * The address of the LDAPBindAPI containing the Bind information to be
676 * encoded in the Bind message.
677 * "pClient"
678 * The address at which the created LdapDefaultClient is to be stored.
679 * Must be non-NULL.
680 * "plContext"
681 * Platform-specific context pointer.
682 * THREAD SAFETY:
683 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
684 * RETURNS:
685 * Returns NULL if the function succeeds.
686 * Returns a LdapDefaultClient Error if the function fails in
687 * a non-fatal way.
688 * Returns a Fatal Error if the function fails in an unrecoverable way.
689 */
690 PKIX_Error *
691 PKIX_PL_LdapDefaultClient_Create(
692 PRNetAddr *sockaddr,
693 PRIntervalTime timeout,
694 LDAPBindAPI *bindAPI,
695 PKIX_PL_LdapDefaultClient **pClient,
696 void *plContext)
697 {
698 PRErrorCode status = 0;
699 PKIX_PL_Socket *socket = NULL;
700 PKIX_PL_LdapDefaultClient *client = NULL;
701
702 PKIX_ENTER(LDAPDEFAULTCLIENT, "PKIX_PL_LdapDefaultClient_Create");
703 PKIX_NULLCHECK_TWO(sockaddr, pClient);
704
705 PKIX_CHECK(pkix_pl_Socket_Create
706 (PKIX_FALSE, timeout, sockaddr, &status, &socket, plContext),
707 PKIX_SOCKETCREATEFAILED);
708
709 PKIX_CHECK(pkix_pl_LdapDefaultClient_CreateHelper
710 (socket, bindAPI, &client, plContext),
711 PKIX_LDAPDEFAULTCLIENTCREATEHELPERFAILED);
712
713 /* Did Socket_Create say the connection was made? */
714 if (status == 0) {
715 if (client->bindAPI != NULL) {
716 client->connectStatus = CONNECTED;
717 } else {
718 client->connectStatus = BOUND;
719 }
720 } else {
721 client->connectStatus = CONNECT_PENDING;
722 }
723
724 *pClient = client;
725
726 cleanup:
727 if (PKIX_ERROR_RECEIVED) {
728 PKIX_DECREF(client);
729 }
730
731 PKIX_DECREF(socket);
732
733 PKIX_RETURN(LDAPDEFAULTCLIENT);
734 }
735
736 /*
737 * FUNCTION: PKIX_PL_LdapDefaultClient_CreateByName
738 * DESCRIPTION:
739 *
740 * This function creates a new LdapDefaultClient using the hostname pointed to
741 * by "hostname", the PRIntervalTime pointed to by "timeout", and the
742 * LDAPBindAPI pointed to by "bindAPI", and stores the result at "pClient".
743 *
744 * A value of zero for "timeout" means the LDAPClient will use non-blocking
745 * I/O.
746 *
747 * PARAMETERS:
748 * "hostname"
749 * Address of the hostname to be used for the socket connection. Must be
750 * non-NULL.
751 * "timeout"
752 * The PRIntervalTime to be used in I/O requests for this client.
753 * "bindAPI"
754 * The address of the LDAPBindAPI containing the Bind information to be
755 * encoded in the Bind message.
756 * "pClient"
757 * The address at which the created LdapDefaultClient is to be stored.
758 * Must be non-NULL.
759 * "plContext"
760 * Platform-specific context pointer.
761 * THREAD SAFETY:
762 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
763 * RETURNS:
764 * Returns NULL if the function succeeds.
765 * Returns a LdapDefaultClient Error if the function fails in
766 * a non-fatal way.
767 * Returns a Fatal Error if the function fails in an unrecoverable way.
768 */
769 PKIX_Error *
770 PKIX_PL_LdapDefaultClient_CreateByName(
771 char *hostname,
772 PRIntervalTime timeout,
773 LDAPBindAPI *bindAPI,
774 PKIX_PL_LdapDefaultClient **pClient,
775 void *plContext)
776 {
777 PRErrorCode status = 0;
778 PKIX_PL_Socket *socket = NULL;
779 PKIX_PL_LdapDefaultClient *client = NULL;
780
781 PKIX_ENTER(LDAPDEFAULTCLIENT, "PKIX_PL_LdapDefaultClient_CreateByName");
782 PKIX_NULLCHECK_TWO(hostname, pClient);
783
784 PKIX_CHECK(pkix_pl_Socket_CreateByName
785 (PKIX_FALSE, timeout, hostname, &status, &socket, plContext),
786 PKIX_SOCKETCREATEBYNAMEFAILED);
787
788 PKIX_CHECK(pkix_pl_LdapDefaultClient_CreateHelper
789 (socket, bindAPI, &client, plContext),
790 PKIX_LDAPDEFAULTCLIENTCREATEHELPERFAILED);
791
792 /* Did Socket_Create say the connection was made? */
793 if (status == 0) {
794 if (client->bindAPI != NULL) {
795 client->connectStatus = CONNECTED;
796 } else {
797 client->connectStatus = BOUND;
798 }
799 } else {
800 client->connectStatus = CONNECT_PENDING;
801 }
802
803 *pClient = client;
804
805 cleanup:
806 if (PKIX_ERROR_RECEIVED) {
807 PKIX_DECREF(client);
808 }
809
810 PKIX_DECREF(socket);
811
812 PKIX_RETURN(LDAPDEFAULTCLIENT);
813 }
814
815 /*
816 * FUNCTION: pkix_pl_LdapDefaultClient_Destroy
817 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
818 */
819 static PKIX_Error *
820 pkix_pl_LdapDefaultClient_Destroy(
821 PKIX_PL_Object *object,
822 void *plContext)
823 {
824 PKIX_Int32 bytesWritten = 0;
825 PKIX_PL_LdapDefaultClient *client = NULL;
826 PKIX_PL_Socket_Callback *callbackList = NULL;
827 SECItem *encoded = NULL;
828
829 PKIX_ENTER(LDAPDEFAULTCLIENT,
830 "pkix_pl_LdapDefaultClient_Destroy");
831 PKIX_NULLCHECK_ONE(object);
832
833 PKIX_CHECK(pkix_CheckType
834 (object, PKIX_LDAPDEFAULTCLIENT_TYPE, plContext),
835 PKIX_OBJECTNOTANLDAPDEFAULTCLIENT);
836
837 client = (PKIX_PL_LdapDefaultClient *)object;
838
839 switch (client->connectStatus) {
840 case CONNECT_PENDING:
841 break;
842 case CONNECTED:
843 case BIND_PENDING:
844 case BIND_RESPONSE:
845 case BIND_RESPONSE_PENDING:
846 case BOUND:
847 case SEND_PENDING:
848 case RECV:
849 case RECV_PENDING:
850 case RECV_INITIAL:
851 case RECV_NONINITIAL:
852 case ABANDON_PENDING:
853 if (client->bindAPI != NULL) {
854 PKIX_CHECK(pkix_pl_LdapDefaultClient_MakeUnbind
855 (client->arena,
856 ++(client->messageID),
857 &encoded,
858 plContext),
859 PKIX_LDAPDEFAULTCLIENTMAKEUNBINDFAILED);
860
861 callbackList =
862 (PKIX_PL_Socket_Callback *)(client->callbackList);
863 PKIX_CHECK(callbackList->sendCallback
864 (client->clientSocket,
865 encoded->data,
866 encoded->len,
867 &bytesWritten,
868 plContext),
869 PKIX_SOCKETSENDFAILED);
870 }
871 break;
872 default:
873 PKIX_ERROR(PKIX_LDAPDEFAULTCLIENTINILLEGALSTATE);
874 }
875
876 PKIX_DECREF(client->cachePtr);
877 PKIX_DECREF(client->clientSocket);
878 PKIX_DECREF(client->entriesFound);
879 PKIX_DECREF(client->currentRequest);
880 PKIX_DECREF(client->currentResponse);
881
882 PKIX_CHECK(PKIX_PL_Free
883 (client->rcvBuf, plContext), PKIX_FREEFAILED);
884
885 PKIX_PL_NSSCALL
886 (LDAPDEFAULTCLIENT,
887 PORT_FreeArena,
888 (client->arena, PR_FALSE));
889
890 cleanup:
891
892 PKIX_RETURN(LDAPDEFAULTCLIENT);
893 }
894
895 /*
896 * FUNCTION: pkix_pl_LdapDefaultClient_Hashcode
897 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
898 */
899 static PKIX_Error *
900 pkix_pl_LdapDefaultClient_Hashcode(
901 PKIX_PL_Object *object,
902 PKIX_UInt32 *pHashcode,
903 void *plContext)
904 {
905 PKIX_PL_LdapDefaultClient *ldapDefaultClient = NULL;
906 PKIX_UInt32 tempHash = 0;
907
908 PKIX_ENTER
909 (LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_Hashcode");
910 PKIX_NULLCHECK_TWO(object, pHashcode);
911
912 PKIX_CHECK(pkix_CheckType
913 (object, PKIX_LDAPDEFAULTCLIENT_TYPE, plContext),
914 PKIX_OBJECTNOTANLDAPDEFAULTCLIENT);
915
916 ldapDefaultClient = (PKIX_PL_LdapDefaultClient *)object;
917
918 PKIX_CHECK(PKIX_PL_Object_Hashcode
919 ((PKIX_PL_Object *)ldapDefaultClient->clientSocket,
920 &tempHash,
921 plContext),
922 PKIX_SOCKETHASHCODEFAILED);
923
924 if (ldapDefaultClient->bindAPI != NULL) {
925 tempHash = (tempHash << 7) +
926 ldapDefaultClient->bindAPI->selector;
927 }
928
929 *pHashcode = tempHash;
930
931 cleanup:
932
933 PKIX_RETURN(LDAPDEFAULTCLIENT);
934 }
935
936 /*
937 * FUNCTION: pkix_pl_LdapDefaultClient_Equals
938 * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h)
939 */
940 static PKIX_Error *
941 pkix_pl_LdapDefaultClient_Equals(
942 PKIX_PL_Object *firstObject,
943 PKIX_PL_Object *secondObject,
944 PKIX_Int32 *pResult,
945 void *plContext)
946 {
947 PKIX_PL_LdapDefaultClient *firstClientContext = NULL;
948 PKIX_PL_LdapDefaultClient *secondClientContext = NULL;
949 PKIX_Int32 compare = 0;
950
951 PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_Equals");
952 PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
953
954 *pResult = PKIX_FALSE;
955
956 PKIX_CHECK(pkix_CheckTypes
957 (firstObject,
958 secondObject,
959 PKIX_LDAPDEFAULTCLIENT_TYPE,
960 plContext),
961 PKIX_OBJECTNOTANLDAPDEFAULTCLIENT);
962
963 firstClientContext = (PKIX_PL_LdapDefaultClient *)firstObject;
964 secondClientContext = (PKIX_PL_LdapDefaultClient *)secondObject;
965
966 if (firstClientContext == secondClientContext) {
967 *pResult = PKIX_TRUE;
968 goto cleanup;
969 }
970
971 PKIX_CHECK(PKIX_PL_Object_Equals
972 ((PKIX_PL_Object *)firstClientContext->clientSocket,
973 (PKIX_PL_Object *)secondClientContext->clientSocket,
974 &compare,
975 plContext),
976 PKIX_SOCKETEQUALSFAILED);
977
978 if (!compare) {
979 goto cleanup;
980 }
981
982 if (PKIX_EXACTLY_ONE_NULL
983 (firstClientContext->bindAPI, secondClientContext->bindAPI)) {
984 goto cleanup;
985 }
986
987 if (firstClientContext->bindAPI) {
988 if (firstClientContext->bindAPI->selector !=
989 secondClientContext->bindAPI->selector) {
990 goto cleanup;
991 }
992 }
993
994 *pResult = PKIX_TRUE;
995
996 cleanup:
997
998 PKIX_RETURN(LDAPDEFAULTCLIENT);
999 }
1000
1001 /*
1002 * FUNCTION: pkix_pl_LdapDefaultClient_RegisterSelf
1003 *
1004 * DESCRIPTION:
1005 * Registers PKIX_PL_LDAPDEFAULTCLIENT_TYPE and its related
1006 * functions with systemClasses[]
1007 *
1008 * THREAD SAFETY:
1009 * Not Thread Safe - for performance and complexity reasons
1010 *
1011 * Since this function is only called by PKIX_PL_Initialize, which should
1012 * only be called once, it is acceptable that this function is not
1013 * thread-safe.
1014 */
1015 PKIX_Error *
1016 pkix_pl_LdapDefaultClient_RegisterSelf(void *plContext)
1017 {
1018 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
1019 pkix_ClassTable_Entry entry;
1020
1021 PKIX_ENTER
1022 (LDAPDEFAULTCLIENT,
1023 "pkix_pl_LdapDefaultClient_RegisterSelf");
1024
1025 entry.description = "LdapDefaultClient";
1026 entry.objCounter = 0;
1027 entry.typeObjectSize = sizeof(PKIX_PL_LdapDefaultClient);
1028 entry.destructor = pkix_pl_LdapDefaultClient_Destroy;
1029 entry.equalsFunction = pkix_pl_LdapDefaultClient_Equals;
1030 entry.hashcodeFunction = pkix_pl_LdapDefaultClient_Hashcode;
1031 entry.toStringFunction = NULL;
1032 entry.comparator = NULL;
1033 entry.duplicateFunction = NULL;
1034
1035 systemClasses[PKIX_LDAPDEFAULTCLIENT_TYPE] = entry;
1036
1037 PKIX_RETURN(LDAPDEFAULTCLIENT);
1038 }
1039
1040 /*
1041 * FUNCTION: pkix_pl_LdapDefaultClient_GetPollDesc
1042 * DESCRIPTION:
1043 *
1044 * This function retrieves the PRPollDesc from the LdapDefaultClient
1045 * pointed to by "context" and stores the address at "pPollDesc".
1046 *
1047 * PARAMETERS:
1048 * "context"
1049 * The LdapDefaultClient whose PRPollDesc is desired. Must be non-NULL.
1050 * "pPollDesc"
1051 * Address where PRPollDesc will be stored. Must be non-NULL.
1052 * "plContext"
1053 * Platform-specific context pointer.
1054 * THREAD SAFETY:
1055 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1056 * RETURNS:
1057 * Returns NULL if the function succeeds.
1058 * Returns a Fatal Error if the function fails in an unrecoverable way.
1059 */
1060 PKIX_Error *
1061 pkix_pl_LdapDefaultClient_GetPollDesc(
1062 PKIX_PL_LdapDefaultClient *context,
1063 PRPollDesc **pPollDesc,
1064 void *plContext)
1065 {
1066 PKIX_ENTER
1067 (LDAPDEFAULTCLIENT,
1068 "pkix_pl_LdapDefaultClient_GetPollDesc");
1069 PKIX_NULLCHECK_TWO(context, pPollDesc);
1070
1071 *pPollDesc = &(context->pollDesc);
1072
1073 PKIX_RETURN(LDAPDEFAULTCLIENT);
1074 }
1075
1076 /* --Private-Ldap-CertStore-I/O-Functions---------------------------- */
1077 /*
1078 * FUNCTION: pkix_pl_LdapDefaultClient_ConnectContinue
1079 * DESCRIPTION:
1080 *
1081 * This function determines whether a socket Connect initiated earlier for the
1082 * CertStore embodied in the LdapDefaultClient "client" has completed, and
1083 * stores in "pKeepGoing" a flag indicating whether processing can continue
1084 * without further input.
1085 *
1086 * PARAMETERS:
1087 * "client"
1088 * The address of the LdapDefaultClient object. Must be non-NULL.
1089 * "pKeepGoing"
1090 * The address at which the Boolean state machine flag is stored to
1091 * indicate whether processing can continue without further input.
1092 * Must be non-NULL.
1093 * "plContext"
1094 * Platform-specific context pointer.
1095 * THREAD SAFETY:
1096 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1097 * RETURNS:
1098 * Returns NULL if the function succeeds.
1099 * Returns a LdapDefaultClient Error if the function fails in a
1100 * non-fatal way.
1101 * Returns a Fatal Error if the function fails in an unrecoverable way.
1102 */
1103 static PKIX_Error *
1104 pkix_pl_LdapDefaultClient_ConnectContinue(
1105 PKIX_PL_LdapDefaultClient *client,
1106 PKIX_Boolean *pKeepGoing,
1107 void *plContext)
1108 {
1109 PKIX_PL_Socket_Callback *callbackList;
1110 PRErrorCode status;
1111 PKIX_Boolean keepGoing = PKIX_FALSE;
1112
1113 PKIX_ENTER
1114 (LDAPDEFAULTCLIENT,
1115 "pkix_pl_LdapDefaultClient_ConnectContinue");
1116 PKIX_NULLCHECK_ONE(client);
1117
1118 callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
1119
1120 PKIX_CHECK(callbackList->connectcontinueCallback
1121 (client->clientSocket, &status, plContext),
1122 PKIX_SOCKETCONNECTCONTINUEFAILED);
1123
1124 if (status == 0) {
1125 if (client->bindAPI != NULL) {
1126 client->connectStatus = CONNECTED;
1127 } else {
1128 client->connectStatus = BOUND;
1129 }
1130 keepGoing = PKIX_FALSE;
1131 } else if (status != PR_IN_PROGRESS_ERROR) {
1132 PKIX_ERROR(PKIX_UNEXPECTEDERRORINESTABLISHINGCONNECTION);
1133 }
1134
1135 PKIX_CHECK(PKIX_PL_Object_InvalidateCache
1136 ((PKIX_PL_Object *)client, plContext),
1137 PKIX_OBJECTINVALIDATECACHEFAILED);
1138
1139 *pKeepGoing = keepGoing;
1140
1141 cleanup:
1142 PKIX_RETURN(LDAPDEFAULTCLIENT);
1143 }
1144
1145 /*
1146 * FUNCTION: pkix_pl_LdapDefaultClient_Bind
1147 * DESCRIPTION:
1148 *
1149 * This function creates and sends the LDAP-protocol Bind message for the
1150 * CertStore embodied in the LdapDefaultClient "client", and stores in
1151 * "pKeepGoing" a flag indicating whether processing can continue without
1152 * further input.
1153 *
1154 * PARAMETERS:
1155 * "client"
1156 * The address of the LdapDefaultClient object. Must be non-NULL.
1157 * "pKeepGoing"
1158 * The address at which the Boolean state machine flag is stored to
1159 * indicate whether processing can continue without further input.
1160 * Must be non-NULL.
1161 * "plContext"
1162 * Platform-specific context pointer.
1163 * THREAD SAFETY:
1164 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1165 * RETURNS:
1166 * Returns NULL if the function succeeds.
1167 * Returns a LdapDefaultClient Error if the function fails in a
1168 * non-fatal way.
1169 * Returns a Fatal Error if the function fails in an unrecoverable way.
1170 */
1171 static PKIX_Error *
1172 pkix_pl_LdapDefaultClient_Bind(
1173 PKIX_PL_LdapDefaultClient *client,
1174 PKIX_Boolean *pKeepGoing,
1175 void *plContext)
1176 {
1177 SECItem *encoded = NULL;
1178 PKIX_Int32 bytesWritten = 0;
1179 PKIX_PL_Socket_Callback *callbackList;
1180
1181 PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_Bind");
1182 PKIX_NULLCHECK_ONE(client);
1183
1184 /* if we have not yet constructed the BIND message, build it now */
1185 if (!(client->bindMsg)) {
1186 PKIX_CHECK(pkix_pl_LdapDefaultClient_MakeBind
1187 (client->arena,
1188 3,
1189 client->bindAPI,
1190 client->messageID,
1191 &encoded,
1192 plContext),
1193 PKIX_LDAPDEFAULTCLIENTMAKEBINDFAILED);
1194 client->bindMsg = encoded->data;
1195 client->bindMsgLen = encoded->len;
1196 }
1197
1198 callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
1199
1200 PKIX_CHECK(callbackList->sendCallback
1201 (client->clientSocket,
1202 client->bindMsg,
1203 client->bindMsgLen,
1204 &bytesWritten,
1205 plContext),
1206 PKIX_SOCKETSENDFAILED);
1207
1208 client->lastIO = PR_Now();
1209
1210 if (bytesWritten < 0) {
1211 client->connectStatus = BIND_PENDING;
1212 *pKeepGoing = PKIX_FALSE;
1213 } else {
1214 client->connectStatus = BIND_RESPONSE;
1215 *pKeepGoing = PKIX_TRUE;
1216 }
1217
1218 PKIX_CHECK(PKIX_PL_Object_InvalidateCache
1219 ((PKIX_PL_Object *)client, plContext),
1220 PKIX_OBJECTINVALIDATECACHEFAILED);
1221
1222 cleanup:
1223 PKIX_RETURN(LDAPDEFAULTCLIENT);
1224 }
1225
1226 /*
1227 * FUNCTION: pkix_pl_LdapDefaultClient_BindContinue
1228 * DESCRIPTION:
1229 *
1230 * This function determines whether the LDAP-protocol Bind message for the
1231 * CertStore embodied in the LdapDefaultClient "client" has completed, and
1232 * stores in "pKeepGoing" a flag indicating whether processing can continue
1233 * without further input.
1234 *
1235 * PARAMETERS:
1236 * "client"
1237 * The address of the LdapDefaultClient object. Must be non-NULL.
1238 * "pKeepGoing"
1239 * The address at which the Boolean state machine flag is stored to
1240 * indicate whether processing can continue without further input.
1241 * Must be non-NULL.
1242 * "plContext"
1243 * Platform-specific context pointer.
1244 * THREAD SAFETY:
1245 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1246 * RETURNS:
1247 * Returns NULL if the function succeeds.
1248 * Returns a LdapDefaultClient Error if the function fails in a
1249 * non-fatal way.
1250 * Returns a Fatal Error if the function fails in an unrecoverable way.
1251 */
1252 PKIX_Error *pkix_pl_LdapDefaultClient_BindContinue(
1253 PKIX_PL_LdapDefaultClient *client,
1254 PKIX_Boolean *pKeepGoing,
1255 void *plContext)
1256 {
1257 PKIX_Int32 bytesWritten = 0;
1258 PKIX_PL_Socket_Callback *callbackList = NULL;
1259
1260 PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_BindContinue");
1261 PKIX_NULLCHECK_ONE(client);
1262
1263 *pKeepGoing = PKIX_FALSE;
1264
1265 callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
1266
1267 PKIX_CHECK(callbackList->pollCallback
1268 (client->clientSocket, &bytesWritten, NULL, plContext),
1269 PKIX_SOCKETPOLLFAILED);
1270
1271 /*
1272 * If the send completed we can proceed to try for the
1273 * response. If the send did not complete we will have
1274 * continue to poll.
1275 */
1276 if (bytesWritten >= 0) {
1277
1278 client->connectStatus = BIND_RESPONSE;
1279
1280 PKIX_CHECK(PKIX_PL_Object_InvalidateCache
1281 ((PKIX_PL_Object *)client, plContext),
1282 PKIX_OBJECTINVALIDATECACHEFAILED);
1283
1284 *pKeepGoing = PKIX_TRUE;
1285 }
1286
1287 cleanup:
1288 PKIX_RETURN(LDAPDEFAULTCLIENT);
1289 }
1290
1291 /*
1292 * FUNCTION: pkix_pl_LdapDefaultClient_BindResponse
1293 * DESCRIPTION:
1294 *
1295 * This function attempts to read the LDAP-protocol BindResponse message for
1296 * the CertStore embodied in the LdapDefaultClient "client", and stores in
1297 * "pKeepGoing" a flag indicating whether processing can continue without
1298 * further input.
1299 *
1300 * If a BindResponse is received with a Result code of 0 (success), we
1301 * continue with the connection. If a non-zero Result code is received,
1302 * we throw an Error. Some more sophisticated handling of that condition
1303 * might be in order in the future.
1304 *
1305 * PARAMETERS:
1306 * "client"
1307 * The address of the LdapDefaultClient object. Must be non-NULL.
1308 * "pKeepGoing"
1309 * The address at which the Boolean state machine flag is stored to
1310 * indicate whether processing can continue without further input.
1311 * Must be non-NULL.
1312 * "plContext"
1313 * Platform-specific context pointer.
1314 * THREAD SAFETY:
1315 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1316 * RETURNS:
1317 * Returns NULL if the function succeeds.
1318 * Returns a LdapDefaultClient Error if the function fails in a
1319 * non-fatal way.
1320 * Returns a Fatal Error if the function fails in an unrecoverable way.
1321 */
1322 static PKIX_Error *
1323 pkix_pl_LdapDefaultClient_BindResponse(
1324 PKIX_PL_LdapDefaultClient *client,
1325 PKIX_Boolean *pKeepGoing,
1326 void *plContext)
1327 {
1328 PKIX_Int32 bytesRead = 0;
1329 PKIX_PL_Socket_Callback *callbackList = NULL;
1330
1331 PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_BindResponse");
1332 PKIX_NULLCHECK_TWO(client, client->rcvBuf);
1333
1334 callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
1335
1336 PKIX_CHECK(callbackList->recvCallback
1337 (client->clientSocket,
1338 client->rcvBuf,
1339 client->capacity,
1340 &bytesRead,
1341 plContext),
1342 PKIX_SOCKETRECVFAILED);
1343
1344 client->lastIO = PR_Now();
1345
1346 if (bytesRead > 0) {
1347 PKIX_CHECK(pkix_pl_LdapDefaultClient_VerifyBindResponse
1348 (client, bytesRead, plContext),
1349 PKIX_LDAPDEFAULTCLIENTVERIFYBINDRESPONSEFAILED);
1350 /*
1351 * XXX What should we do if failure? At present if
1352 * VerifyBindResponse throws an Error, we do too.
1353 */
1354 client->connectStatus = BOUND;
1355 } else {
1356 client->connectStatus = BIND_RESPONSE_PENDING;
1357 }
1358
1359 PKIX_CHECK(PKIX_PL_Object_InvalidateCache
1360 ((PKIX_PL_Object *)client, plContext),
1361 PKIX_OBJECTINVALIDATECACHEFAILED);
1362
1363 *pKeepGoing = PKIX_TRUE;
1364
1365 cleanup:
1366 PKIX_RETURN(LDAPDEFAULTCLIENT);
1367 }
1368
1369 /*
1370 * FUNCTION: pkix_pl_LdapDefaultClient_BindResponseContinue
1371 * DESCRIPTION:
1372 *
1373 * This function determines whether the LDAP-protocol BindResponse message for
1374 * the CertStore embodied in the LdapDefaultClient "client" has completed, and
1375 * stores in "pKeepGoing" a flag indicating whether processing can continue
1376 * without further input.
1377 *
1378 * PARAMETERS:
1379 * "client"
1380 * The address of the LdapDefaultClient object. Must be non-NULL.
1381 * "pKeepGoing"
1382 * The address at which the Boolean state machine flag is stored to
1383 * indicate whether processing can continue without further input.
1384 * Must be non-NULL.
1385 * "plContext"
1386 * Platform-specific context pointer.
1387 * THREAD SAFETY:
1388 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1389 * RETURNS:
1390 * Returns NULL if the function succeeds.
1391 * Returns a LdapDefaultClient Error if the function fails in a
1392 * non-fatal way.
1393 * Returns a Fatal Error if the function fails in an unrecoverable way.
1394 */
1395 static PKIX_Error *
1396 pkix_pl_LdapDefaultClient_BindResponseContinue(
1397 PKIX_PL_LdapDefaultClient *client,
1398 PKIX_Boolean *pKeepGoing,
1399 void *plContext)
1400 {
1401 PKIX_Int32 bytesRead = 0;
1402 PKIX_PL_Socket_Callback *callbackList = NULL;
1403
1404 PKIX_ENTER
1405 (LDAPDEFAULTCLIENT,
1406 "pkix_pl_LdapDefaultClient_BindResponseContinue");
1407 PKIX_NULLCHECK_ONE(client);
1408
1409 callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
1410
1411 PKIX_CHECK(callbackList->pollCallback
1412 (client->clientSocket, NULL, &bytesRead, plContext),
1413 PKIX_SOCKETPOLLFAILED);
1414
1415 if (bytesRead > 0) {
1416 PKIX_CHECK(pkix_pl_LdapDefaultClient_VerifyBindResponse
1417 (client, bytesRead, plContext),
1418 PKIX_LDAPDEFAULTCLIENTVERIFYBINDRESPONSEFAILED);
1419 client->connectStatus = BOUND;
1420
1421 PKIX_CHECK(PKIX_PL_Object_InvalidateCache
1422 ((PKIX_PL_Object *)client, plContext),
1423 PKIX_OBJECTINVALIDATECACHEFAILED);
1424
1425 *pKeepGoing = PKIX_TRUE;
1426 } else {
1427 *pKeepGoing = PKIX_FALSE;
1428 }
1429
1430 cleanup:
1431 PKIX_RETURN(LDAPDEFAULTCLIENT);
1432 }
1433
1434 /*
1435 * FUNCTION: pkix_pl_LdapDefaultClient_Send
1436 * DESCRIPTION:
1437 *
1438 * This function creates and sends an LDAP-protocol message for the
1439 * CertStore embodied in the LdapDefaultClient "client", and stores in
1440 * "pKeepGoing" a flag indicating whether processing can continue without
1441 * further input, and at "pBytesTransferred" the number of bytes sent.
1442 *
1443 * If "pBytesTransferred" is zero, it indicates that non-blocking I/O is in use
1444 * and that transmission has not completed.
1445 *
1446 * PARAMETERS:
1447 * "client"
1448 * The address of the LdapDefaultClient object. Must be non-NULL.
1449 * "pKeepGoing"
1450 * The address at which the Boolean state machine flag is stored to
1451 * indicate whether processing can continue without further input.
1452 * Must be non-NULL.
1453 * "pBytesTransferred"
1454 * The address at which the number of bytes sent is stored. Must be
1455 * non-NULL.
1456 * "plContext"
1457 * Platform-specific context pointer.
1458 * THREAD SAFETY:
1459 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1460 * RETURNS:
1461 * Returns NULL if the function succeeds.
1462 * Returns a LdapDefaultClient Error if the function fails in a
1463 * non-fatal way.
1464 * Returns a Fatal Error if the function fails in an unrecoverable way.
1465 */
1466 static PKIX_Error *
1467 pkix_pl_LdapDefaultClient_Send(
1468 PKIX_PL_LdapDefaultClient *client,
1469 PKIX_Boolean *pKeepGoing,
1470 PKIX_UInt32 *pBytesTransferred,
1471 void *plContext)
1472 {
1473 PKIX_Int32 bytesWritten = 0;
1474 PKIX_PL_Socket_Callback *callbackList = NULL;
1475
1476 PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_Send");
1477 PKIX_NULLCHECK_THREE(client, pKeepGoing, pBytesTransferred);
1478
1479 *pKeepGoing = PKIX_FALSE;
1480
1481 /* Do we have anything waiting to go? */
1482 if (client->sendBuf) {
1483 callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
1484
1485 PKIX_CHECK(callbackList->sendCallback
1486 (client->clientSocket,
1487 client->sendBuf,
1488 client->bytesToWrite,
1489 &bytesWritten,
1490 plContext),
1491 PKIX_SOCKETSENDFAILED);
1492
1493 client->lastIO = PR_Now();
1494
1495 /*
1496 * If the send completed we can proceed to try for the
1497 * response. If the send did not complete we will have
1498 * to poll for completion later.
1499 */
1500 if (bytesWritten >= 0) {
1501 client->sendBuf = NULL;
1502 client->connectStatus = RECV;
1503 *pKeepGoing = PKIX_TRUE;
1504
1505 } else {
1506 *pKeepGoing = PKIX_FALSE;
1507 client->connectStatus = SEND_PENDING;
1508 }
1509
1510 }
1511
1512 PKIX_CHECK(PKIX_PL_Object_InvalidateCache
1513 ((PKIX_PL_Object *)client, plContext),
1514 PKIX_OBJECTINVALIDATECACHEFAILED);
1515
1516 *pBytesTransferred = bytesWritten;
1517
1518 cleanup:
1519 PKIX_RETURN(LDAPDEFAULTCLIENT);
1520 }
1521
1522 /*
1523 * FUNCTION: pkix_pl_LdapDefaultClient_SendContinue
1524 * DESCRIPTION:
1525 *
1526 * This function determines whether the sending of the LDAP-protocol message
1527 * for the CertStore embodied in the LdapDefaultClient "client" has completed,
1528 * and stores in "pKeepGoing" a flag indicating whether processing can continue
1529 * without further input, and at "pBytesTransferred" the number of bytes sent.
1530 *
1531 * If "pBytesTransferred" is zero, it indicates that non-blocking I/O is in use
1532 * and that transmission has not completed.
1533 *
1534 * PARAMETERS:
1535 * "client"
1536 * The address of the LdapDefaultClient object. Must be non-NULL.
1537 * "pKeepGoing"
1538 * The address at which the Boolean state machine flag is stored to
1539 * indicate whether processing can continue without further input.
1540 * Must be non-NULL.
1541 * "pBytesTransferred"
1542 * The address at which the number of bytes sent is stored. Must be
1543 * non-NULL.
1544 * "plContext"
1545 * Platform-specific context pointer.
1546 * THREAD SAFETY:
1547 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1548 * RETURNS:
1549 * Returns NULL if the function succeeds.
1550 * Returns a LdapDefaultClient Error if the function fails in a
1551 * non-fatal way.
1552 * Returns a Fatal Error if the function fails in an unrecoverable way.
1553 */
1554 static PKIX_Error *
1555 pkix_pl_LdapDefaultClient_SendContinue(
1556 PKIX_PL_LdapDefaultClient *client,
1557 PKIX_Boolean *pKeepGoing,
1558 PKIX_UInt32 *pBytesTransferred,
1559 void *plContext)
1560 {
1561 PKIX_Int32 bytesWritten = 0;
1562 PKIX_PL_Socket_Callback *callbackList = NULL;
1563
1564 PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_SendContinue");
1565 PKIX_NULLCHECK_THREE(client, pKeepGoing, pBytesTransferred);
1566
1567 *pKeepGoing = PKIX_FALSE;
1568
1569 callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
1570
1571 PKIX_CHECK(callbackList->pollCallback
1572 (client->clientSocket, &bytesWritten, NULL, plContext),
1573 PKIX_SOCKETPOLLFAILED);
1574
1575 /*
1576 * If the send completed we can proceed to try for the
1577 * response. If the send did not complete we will have
1578 * continue to poll.
1579 */
1580 if (bytesWritten >= 0) {
1581 client->sendBuf = NULL;
1582 client->connectStatus = RECV;
1583
1584 PKIX_CHECK(PKIX_PL_Object_InvalidateCache
1585 ((PKIX_PL_Object *)client, plContext),
1586 PKIX_OBJECTINVALIDATECACHEFAILED);
1587
1588 *pKeepGoing = PKIX_TRUE;
1589 }
1590
1591 *pBytesTransferred = bytesWritten;
1592
1593 cleanup:
1594 PKIX_RETURN(LDAPDEFAULTCLIENT);
1595 }
1596
1597 /*
1598 * FUNCTION: pkix_pl_LdapDefaultClient_Recv
1599 * DESCRIPTION:
1600 *
1601 * This function receives an LDAP-protocol message for the CertStore embodied
1602 * in the LdapDefaultClient "client", and stores in "pKeepGoing" a flag
1603 * indicating whether processing can continue without further input.
1604 *
1605 * PARAMETERS:
1606 * "client"
1607 * The address of the LdapDefaultClient object. Must be non-NULL.
1608 * "pKeepGoing"
1609 * The address at which the Boolean state machine flag is stored to
1610 * indicate whether processing can continue without further input.
1611 * Must be non-NULL.
1612 * "plContext"
1613 * Platform-specific context pointer.
1614 * THREAD SAFETY:
1615 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1616 * RETURNS:
1617 * Returns NULL if the function succeeds.
1618 * Returns a LdapDefaultClient Error if the function fails in a
1619 * non-fatal way.
1620 * Returns a Fatal Error if the function fails in an unrecoverable way.
1621 */
1622 static PKIX_Error *
1623 pkix_pl_LdapDefaultClient_Recv(
1624 PKIX_PL_LdapDefaultClient *client,
1625 PKIX_Boolean *pKeepGoing,
1626 void *plContext)
1627 {
1628 PKIX_Int32 bytesRead = 0;
1629 PKIX_UInt32 bytesToRead = 0;
1630 PKIX_PL_Socket_Callback *callbackList = NULL;
1631
1632 PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_Recv");
1633 PKIX_NULLCHECK_THREE(client, pKeepGoing, client->rcvBuf);
1634
1635 callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
1636
1637 /*
1638 * If we attempt to fill our buffer with every read, we increase
1639 * the risk of an ugly situation: one or two bytes of a new message
1640 * left over at the end of processing one message. With such a
1641 * fragment, we can't decode a byte count and so won't know how much
1642 * space to allocate for the next LdapResponse. We try to avoid that
1643 * case by reading just enough to complete the current message, unless
1644 * there will be at least MINIMUM_MSG_LENGTH bytes left over.
1645 */
1646 if (client->currentResponse) {
1647 PKIX_CHECK(pkix_pl_LdapResponse_GetCapacity
1648 (client->currentResponse, &bytesToRead, plContext),
1649 PKIX_LDAPRESPONSEGETCAPACITYFAILED);
1650 if ((bytesToRead > client->capacity) ||
1651 ((bytesToRead + MINIMUM_MSG_LENGTH) < client->capacity)) {
1652 bytesToRead = client->capacity;
1653 }
1654 } else {
1655 bytesToRead = client->capacity;
1656 }
1657
1658 client->currentBytesAvailable = 0;
1659
1660 PKIX_CHECK(callbackList->recvCallback
1661 (client->clientSocket,
1662 (void *)client->rcvBuf,
1663 bytesToRead,
1664 &bytesRead,
1665 plContext),
1666 PKIX_SOCKETRECVFAILED);
1667
1668 client->currentInPtr = client->rcvBuf;
1669 client->lastIO = PR_Now();
1670
1671 if (bytesRead > 0) {
1672 client->currentBytesAvailable = bytesRead;
1673 client->connectStatus = RECV_INITIAL;
1674 *pKeepGoing = PKIX_TRUE;
1675 } else {
1676 client->connectStatus = RECV_PENDING;
1677 *pKeepGoing = PKIX_FALSE;
1678 }
1679
1680 PKIX_CHECK(PKIX_PL_Object_InvalidateCache
1681 ((PKIX_PL_Object *)client, plContext),
1682 PKIX_OBJECTINVALIDATECACHEFAILED);
1683
1684 cleanup:
1685 PKIX_RETURN(LDAPDEFAULTCLIENT);
1686 }
1687
1688 /*
1689 * FUNCTION: pkix_pl_LdapDefaultClient_RecvContinue
1690 * DESCRIPTION:
1691 *
1692 * This function determines whether the receiving of the LDAP-protocol message
1693 * for the CertStore embodied in the LdapDefaultClient "client" has completed,
1694 * and stores in "pKeepGoing" a flag indicating whether processing can continue
1695 * without further input.
1696 *
1697 * PARAMETERS:
1698 * "client"
1699 * The address of the LdapDefaultClient object. Must be non-NULL.
1700 * "pKeepGoing"
1701 * The address at which the Boolean state machine flag is stored to
1702 * indicate whether processing can continue without further input.
1703 * Must be non-NULL.
1704 * "plContext"
1705 * Platform-specific context pointer.
1706 * THREAD SAFETY:
1707 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1708 * RETURNS:
1709 * Returns NULL if the function succeeds.
1710 * Returns a LdapDefaultClient Error if the function fails in a
1711 * non-fatal way.
1712 * Returns a Fatal Error if the function fails in an unrecoverable way.
1713 */
1714 static PKIX_Error *
1715 pkix_pl_LdapDefaultClient_RecvContinue(
1716 PKIX_PL_LdapDefaultClient *client,
1717 PKIX_Boolean *pKeepGoing,
1718 void *plContext)
1719 {
1720 PKIX_Int32 bytesRead = 0;
1721 PKIX_PL_Socket_Callback *callbackList = NULL;
1722
1723 PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_RecvContinue");
1724 PKIX_NULLCHECK_TWO(client, pKeepGoing);
1725
1726 callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
1727
1728 PKIX_CHECK(callbackList->pollCallback
1729 (client->clientSocket, NULL, &bytesRead, plContext),
1730 PKIX_SOCKETPOLLFAILED);
1731
1732 if (bytesRead > 0) {
1733 client->currentBytesAvailable += bytesRead;
1734 client->connectStatus = RECV_INITIAL;
1735 *pKeepGoing = PKIX_TRUE;
1736
1737 PKIX_CHECK(PKIX_PL_Object_InvalidateCache
1738 ((PKIX_PL_Object *)client, plContext),
1739 PKIX_OBJECTINVALIDATECACHEFAILED);
1740 } else {
1741 *pKeepGoing = PKIX_FALSE;
1742 }
1743
1744 cleanup:
1745 PKIX_RETURN(LDAPDEFAULTCLIENT);
1746 }
1747
1748 /*
1749 * FUNCTION: pkix_pl_LdapDefaultClient_AbandonContinue
1750 * DESCRIPTION:
1751 *
1752 * This function determines whether the abandon-message request of the
1753 * LDAP-protocol message for the CertStore embodied in the LdapDefaultClient
1754 * "client" has completed, and stores in "pKeepGoing" a flag indicating whether
1755 * processing can continue without further input.
1756 *
1757 * PARAMETERS:
1758 * "client"
1759 * The address of the LdapDefaultClient object. Must be non-NULL.
1760 * "pKeepGoing"
1761 * The address at which the Boolean state machine flag is stored to
1762 * indicate whether processing can continue without further input.
1763 * Must be non-NULL.
1764 * "plContext"
1765 * Platform-specific context pointer.
1766 * THREAD SAFETY:
1767 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1768 * RETURNS:
1769 * Returns NULL if the function succeeds.
1770 * Returns a LdapDefaultClient Error if the function fails in a
1771 * non-fatal way.
1772 * Returns a Fatal Error if the function fails in an unrecoverable way.
1773 */
1774 static PKIX_Error *
1775 pkix_pl_LdapDefaultClient_AbandonContinue(
1776 PKIX_PL_LdapDefaultClient *client,
1777 PKIX_Boolean *pKeepGoing,
1778 void *plContext)
1779 {
1780 PKIX_Int32 bytesWritten = 0;
1781 PKIX_PL_Socket_Callback *callbackList = NULL;
1782
1783 PKIX_ENTER
1784 (LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_AbandonContinue");
1785 PKIX_NULLCHECK_TWO(client, pKeepGoing);
1786
1787 callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
1788
1789 PKIX_CHECK(callbackList->pollCallback
1790 (client->clientSocket, &bytesWritten, NULL, plContext),
1791 PKIX_SOCKETPOLLFAILED);
1792
1793 if (bytesWritten > 0) {
1794 client->connectStatus = BOUND;
1795 *pKeepGoing = PKIX_TRUE;
1796
1797 PKIX_CHECK(PKIX_PL_Object_InvalidateCache
1798 ((PKIX_PL_Object *)client, plContext),
1799 PKIX_OBJECTINVALIDATECACHEFAILED);
1800 } else {
1801 *pKeepGoing = PKIX_FALSE;
1802 }
1803
1804 cleanup:
1805 PKIX_RETURN(LDAPDEFAULTCLIENT);
1806 }
1807
1808 /*
1809 * FUNCTION: pkix_pl_LdapDefaultClient_RecvInitial
1810 * DESCRIPTION:
1811 *
1812 * This function processes the contents of the first buffer of a received
1813 * LDAP-protocol message for the CertStore embodied in the LdapDefaultClient
1814 * "client", and stores in "pKeepGoing" a flag indicating whether processing can
1815 * continue without further input.
1816 *
1817 * PARAMETERS:
1818 * "client"
1819 * The address of the LdapDefaultClient object. Must be non-NULL.
1820 * "pKeepGoing"
1821 * The address at which the Boolean state machine flag is stored to
1822 * indicate whether processing can continue without further input.
1823 * Must be non-NULL.
1824 * "plContext"
1825 * Platform-specific context pointer.
1826 * THREAD SAFETY:
1827 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1828 * RETURNS:
1829 * Returns NULL if the function succeeds.
1830 * Returns a LdapDefaultClient Error if the function fails in a
1831 * non-fatal way.
1832 * Returns a Fatal Error if the function fails in an unrecoverable way.
1833 */
1834 static PKIX_Error *
1835 pkix_pl_LdapDefaultClient_RecvInitial(
1836 PKIX_PL_LdapDefaultClient *client,
1837 PKIX_Boolean *pKeepGoing,
1838 void *plContext)
1839 {
1840 unsigned char *msgBuf = NULL;
1841 unsigned char *to = NULL;
1842 unsigned char *from = NULL;
1843 PKIX_UInt32 dataIndex = 0;
1844 PKIX_UInt32 messageIdLen = 0;
1845 PKIX_UInt32 messageLength = 0;
1846 PKIX_UInt32 sizeofLength = 0;
1847 PKIX_UInt32 bytesProcessed = 0;
1848 unsigned char messageChar = 0;
1849 LDAPMessageType messageType = 0;
1850 PKIX_Int32 bytesRead = 0;
1851 PKIX_PL_Socket_Callback *callbackList = NULL;
1852
1853 PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_RecvInitial");
1854 PKIX_NULLCHECK_TWO(client, pKeepGoing);
1855
1856 /*
1857 * Is there an LDAPResponse in progress? I.e., have we
1858 * already processed the tag and length at the beginning of
1859 * the message?
1860 */
1861 if (client->currentResponse) {
1862 client->connectStatus = RECV_NONINITIAL;
1863 *pKeepGoing = PKIX_TRUE;
1864 goto cleanup;
1865 }
1866 msgBuf = client->currentInPtr;
1867
1868 /* Do we have enough of the message to decode the message length? */
1869 if (client->currentBytesAvailable < MINIMUM_MSG_LENGTH) {
1870 /*
1871 * No! Move these few bytes to the beginning of rcvBuf
1872 * and hang another read.
1873 */
1874
1875 to = (unsigned char *)client->rcvBuf;
1876 from = client->currentInPtr;
1877 for (dataIndex = 0;
1878 dataIndex < client->currentBytesAvailable;
1879 dataIndex++) {
1880 *to++ = *from++;
1881 }
1882 callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
1883 PKIX_CHECK(callbackList->recvCallback
1884 (client->clientSocket,
1885 (void *)to,
1886 client->capacity - client->currentBytesAvailable,
1887 &bytesRead,
1888 plContext),
1889 PKIX_SOCKETRECVFAILED);
1890
1891 client->currentInPtr = client->rcvBuf;
1892 client->lastIO = PR_Now();
1893
1894 if (bytesRead <= 0) {
1895 client->connectStatus = RECV_PENDING;
1896 *pKeepGoing = PKIX_FALSE;
1897 goto cleanup;
1898 } else {
1899 client->currentBytesAvailable += bytesRead;
1900 }
1901 }
1902
1903 /*
1904 * We have to determine whether the response is an entry, with
1905 * application-specific tag LDAP_SEARCHRESPONSEENTRY_TYPE, or a
1906 * resultCode, with application tag LDAP_SEARCHRESPONSERESULT_TYPE.
1907 * First, we have to figure out where to look for the tag.
1908 */
1909
1910 /* Is the message length short form (one octet) or long form? */
1911 if ((msgBuf[1] & 0x80) != 0) {
1912 sizeofLength = msgBuf[1] & 0x7F;
1913 for (dataIndex = 0; dataIndex < sizeofLength; dataIndex++) {
1914 messageLength =
1915 (messageLength << 8) + msgBuf[dataIndex + 2];
1916 }
1917 } else {
1918 messageLength = msgBuf[1];
1919 }
1920
1921 /* How many bytes did the messageID require? */
1922 messageIdLen = msgBuf[dataIndex + 3];
1923
1924 messageChar = msgBuf[dataIndex + messageIdLen + 4];
1925
1926 /* Are we looking at an Entry message or a ResultCode message? */
1927 if ((SEC_ASN1_CONSTRUCTED | SEC_ASN1_APPLICATION |
1928 LDAP_SEARCHRESPONSEENTRY_TYPE) == messageChar) {
1929
1930 messageType = LDAP_SEARCHRESPONSEENTRY_TYPE;
1931
1932 } else if ((SEC_ASN1_CONSTRUCTED | SEC_ASN1_APPLICATION |
1933 LDAP_SEARCHRESPONSERESULT_TYPE) == messageChar) {
1934
1935 messageType = LDAP_SEARCHRESPONSERESULT_TYPE;
1936
1937 } else {
1938
1939 PKIX_ERROR(PKIX_SEARCHRESPONSEPACKETOFUNKNOWNTYPE);
1940
1941 }
1942
1943 /*
1944 * messageLength is the length from (tag, length, value).
1945 * We have to allocate space for the tag and length bits too.
1946 */
1947 PKIX_CHECK(pkix_pl_LdapResponse_Create
1948 (messageType,
1949 messageLength + dataIndex + 2,
1950 client->currentBytesAvailable,
1951 msgBuf,
1952 &bytesProcessed,
1953 &(client->currentResponse),
1954 plContext),
1955 PKIX_LDAPRESPONSECREATEFAILED);
1956
1957 client->currentBytesAvailable -= bytesProcessed;
1958
1959 PKIX_CHECK(pkix_pl_LdapDefaultClient_RecvCheckComplete
1960 (client, bytesProcessed, pKeepGoing, plContext),
1961 PKIX_LDAPDEFAULTCLIENTRECVCHECKCOMPLETEFAILED);
1962
1963 cleanup:
1964
1965 PKIX_RETURN(LDAPDEFAULTCLIENT);
1966 }
1967
1968 /*
1969 * FUNCTION: pkix_pl_LdapDefaultClient_RecvNonInitial
1970 * DESCRIPTION:
1971 *
1972 * This function processes the contents of buffers, after the first, of a
1973 * received LDAP-protocol message for the CertStore embodied in the
1974 * LdapDefaultClient "client", and stores in "pKeepGoing" a flag indicating
1975 * whether processing can continue without further input.
1976 *
1977 * PARAMETERS:
1978 * "client"
1979 * The address of the LdapDefaultClient object. Must be non-NULL.
1980 * "pKeepGoing"
1981 * The address at which the Boolean state machine flag is stored to
1982 * indicate whether processing can continue without further input.
1983 * Must be non-NULL.
1984 * "plContext"
1985 * Platform-specific context pointer.
1986 * THREAD SAFETY:
1987 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1988 * RETURNS:
1989 * Returns NULL if the function succeeds.
1990 * Returns a LdapDefaultClient Error if the function fails in a
1991 * non-fatal way.
1992 * Returns a Fatal Error if the function fails in an unrecoverable way.
1993 */
1994 static PKIX_Error *
1995 pkix_pl_LdapDefaultClient_RecvNonInitial(
1996 PKIX_PL_LdapDefaultClient *client,
1997 PKIX_Boolean *pKeepGoing,
1998 void *plContext)
1999 {
2000
2001 PKIX_UInt32 bytesProcessed = 0;
2002
2003 PKIX_ENTER
2004 (LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_RecvNonInitial");
2005 PKIX_NULLCHECK_TWO(client, pKeepGoing);
2006
2007 PKIX_CHECK(pkix_pl_LdapResponse_Append
2008 (client->currentResponse,
2009 client->currentBytesAvailable,
2010 client->currentInPtr,
2011 &bytesProcessed,
2012 plContext),
2013 PKIX_LDAPRESPONSEAPPENDFAILED);
2014
2015 client->currentBytesAvailable -= bytesProcessed;
2016
2017 PKIX_CHECK(pkix_pl_LdapDefaultClient_RecvCheckComplete
2018 (client, bytesProcessed, pKeepGoing, plContext),
2019 PKIX_LDAPDEFAULTCLIENTRECVCHECKCOMPLETEFAILED);
2020
2021 cleanup:
2022
2023 PKIX_RETURN(LDAPDEFAULTCLIENT);
2024 }
2025
2026 /*
2027 * FUNCTION: pkix_pl_LdapDefaultClient_Dispatch
2028 * DESCRIPTION:
2029 *
2030 * This function is the state machine dispatcher for the CertStore embodied in
2031 * the LdapDefaultClient pointed to by "client". Results are returned by
2032 * changes to various fields in the context.
2033 *
2034 * PARAMETERS:
2035 * "client"
2036 * The address of the LdapDefaultClient object. Must be non-NULL.
2037 * "plContext"
2038 * Platform-specific context pointer.
2039 * THREAD SAFETY:
2040 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
2041 * RETURNS:
2042 * Returns NULL if the function succeeds.
2043 * Returns a LdapDefaultClient Error if the function fails in a
2044 * non-fatal way.
2045 * Returns a Fatal Error if the function fails in an unrecoverable way.
2046 */
2047 static PKIX_Error *
2048 pkix_pl_LdapDefaultClient_Dispatch(
2049 PKIX_PL_LdapDefaultClient *client,
2050 void *plContext)
2051 {
2052 PKIX_UInt32 bytesTransferred = 0;
2053 PKIX_Boolean keepGoing = PKIX_TRUE;
2054
2055 PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_Dispatch");
2056 PKIX_NULLCHECK_ONE(client);
2057
2058 while (keepGoing) {
2059 switch (client->connectStatus) {
2060 case CONNECT_PENDING:
2061 PKIX_CHECK
2062 (pkix_pl_LdapDefaultClient_ConnectContinue
2063 (client, &keepGoing, plContext),
2064 PKIX_LDAPDEFAULTCLIENTCONNECTCONTINUEFAILED);
2065 break;
2066 case CONNECTED:
2067 PKIX_CHECK
2068 (pkix_pl_LdapDefaultClient_Bind
2069 (client, &keepGoing, plContext),
2070 PKIX_LDAPDEFAULTCLIENTBINDFAILED);
2071 break;
2072 case BIND_PENDING:
2073 PKIX_CHECK
2074 (pkix_pl_LdapDefaultClient_BindContinue
2075 (client, &keepGoing, plContext),
2076 PKIX_LDAPDEFAULTCLIENTBINDCONTINUEFAILED);
2077 break;
2078 case BIND_RESPONSE:
2079 PKIX_CHECK
2080 (pkix_pl_LdapDefaultClient_BindResponse
2081 (client, &keepGoing, plContext),
2082 PKIX_LDAPDEFAULTCLIENTBINDRESPONSEFAILED);
2083 break;
2084 case BIND_RESPONSE_PENDING:
2085 PKIX_CHECK
2086 (pkix_pl_LdapDefaultClient_BindResponseContinue
2087 (client, &keepGoing, plContext),
2088 PKIX_LDAPDEFAULTCLIENTBINDRESPONSECONTINUEFAILED);
2089 break;
2090 case BOUND:
2091 PKIX_CHECK
2092 (pkix_pl_LdapDefaultClient_Send
2093 (client, &keepGoing, &bytesTransferred, plContext),
2094 PKIX_LDAPDEFAULTCLIENTSENDFAILED);
2095 break;
2096 case SEND_PENDING:
2097 PKIX_CHECK
2098 (pkix_pl_LdapDefaultClient_SendContinue
2099 (client, &keepGoing, &bytesTransferred, plContext),
2100 PKIX_LDAPDEFAULTCLIENTSENDCONTINUEFAILED);
2101 break;
2102 case RECV:
2103 PKIX_CHECK
2104 (pkix_pl_LdapDefaultClient_Recv
2105 (client, &keepGoing, plContext),
2106 PKIX_LDAPDEFAULTCLIENTRECVFAILED);
2107 break;
2108 case RECV_PENDING:
2109 PKIX_CHECK
2110 (pkix_pl_LdapDefaultClient_RecvContinue
2111 (client, &keepGoing, plContext),
2112 PKIX_LDAPDEFAULTCLIENTRECVCONTINUEFAILED);
2113 break;
2114 case RECV_INITIAL:
2115 PKIX_CHECK
2116 (pkix_pl_LdapDefaultClient_RecvInitial
2117 (client, &keepGoing, plContext),
2118 PKIX_LDAPDEFAULTCLIENTRECVINITIALFAILED);
2119 break;
2120 case RECV_NONINITIAL:
2121 PKIX_CHECK
2122 (pkix_pl_LdapDefaultClient_RecvNonInitial
2123 (client, &keepGoing, plContext),
2124 PKIX_LDAPDEFAULTCLIENTRECVNONINITIALFAILED);
2125 break;
2126 case ABANDON_PENDING:
2127 PKIX_CHECK
2128 (pkix_pl_LdapDefaultClient_AbandonContinue
2129 (client, &keepGoing, plContext),
2130 PKIX_LDAPDEFAULTCLIENTABANDONCONTINUEFAILED);
2131 break;
2132 default:
2133 PKIX_ERROR(PKIX_LDAPCERTSTOREINILLEGALSTATE);
2134 }
2135 }
2136
2137 cleanup:
2138
2139 PKIX_RETURN(LDAPDEFAULTCLIENT);
2140 }
2141
2142 /*
2143 * FUNCTION: pkix_pl_LdapDefaultClient_MakeAndFilter
2144 * DESCRIPTION:
2145 *
2146 * This function allocates space from the arena pointed to by "arena" to
2147 * construct a filter that will match components of the X500Name pointed to by
2148 * XXX...
2149 *
2150 * PARAMETERS:
2151 * "arena"
2152 * The address of the PLArenaPool used in creating the filter. Must be
2153 * non-NULL.
2154 * "nameComponent"
2155 * The address of a NULL-terminated list of LDAPNameComponents
2156 * Must be non-NULL.
2157 * "pFilter"
2158 * The address at which the result is stored.
2159 * "plContext"
2160 * Platform-specific context pointer
2161 * THREAD SAFETY:
2162 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
2163 * RETURNS:
2164 * Returns NULL if the function succeeds.
2165 * Returns a CertStore Error if the function fails in a non-fatal way.
2166 * Returns a Fatal Error if the function fails in an unrecoverable way.
2167 */
2168 static PKIX_Error *
2169 pkix_pl_LdapDefaultClient_MakeAndFilter(
2170 PLArenaPool *arena,
2171 LDAPNameComponent **nameComponents,
2172 LDAPFilter **pFilter,
2173 void *plContext)
2174 {
2175 LDAPFilter **setOfFilter;
2176 LDAPFilter *andFilter = NULL;
2177 LDAPFilter *currentFilter = NULL;
2178 PKIX_UInt32 componentsPresent = 0;
2179 void *v = NULL;
2180 unsigned char *component = NULL;
2181 LDAPNameComponent **componentP = NULL;
2182
2183 PKIX_ENTER(CERTSTORE, "pkix_pl_LdapDefaultClient_MakeAndFilter");
2184 PKIX_NULLCHECK_THREE(arena, nameComponents, pFilter);
2185
2186 /* count how many components we were provided */
2187 for (componentP = nameComponents, componentsPresent = 0;
2188 *(componentP++) != NULL;
2189 componentsPresent++) {}
2190
2191 /* Space for (componentsPresent + 1) pointers to LDAPFilter */
2192 PKIX_PL_NSSCALLRV(CERTSTORE, v, PORT_ArenaZAlloc,
2193 (arena, (componentsPresent + 1)*sizeof(LDAPFilter *)));
2194 setOfFilter = (LDAPFilter **)v;
2195
2196 /* Space for AndFilter and <componentsPresent> EqualFilters */
2197 PKIX_PL_NSSCALLRV(CERTSTORE, v, PORT_ArenaZNewArray,
2198 (arena, LDAPFilter, componentsPresent + 1));
2199 setOfFilter[0] = (LDAPFilter *)v;
2200
2201 /* Claim the first array element for the ANDFilter */
2202 andFilter = setOfFilter[0];
2203
2204 /* Set ANDFilter to point to the first EqualFilter pointer */
2205 andFilter->selector = LDAP_ANDFILTER_TYPE;
2206 andFilter->filter.andFilter.filters = setOfFilter;
2207
2208 currentFilter = andFilter + 1;
2209
2210 for (componentP = nameComponents, componentsPresent = 0;
2211 *(componentP) != NULL; componentP++) {
2212 setOfFilter[componentsPresent++] = currentFilter;
2213 currentFilter->selector = LDAP_EQUALFILTER_TYPE;
2214 component = (*componentP)->attrType;
2215 currentFilter->filter.equalFilter.attrType.data = component;
2216 currentFilter->filter.equalFilter.attrType.len =
2217 PL_strlen((const char *)component);
2218 component = (*componentP)->attrValue;
2219 currentFilter->filter.equalFilter.attrValue.data = component;
2220 currentFilter->filter.equalFilter.attrValue.len =
2221 PL_strlen((const char *)component);
2222 currentFilter++;
2223 }
2224
2225 setOfFilter[componentsPresent] = NULL;
2226
2227 *pFilter = andFilter;
2228
2229 PKIX_RETURN(CERTSTORE);
2230
2231 }
2232
2233 /*
2234 * FUNCTION: pkix_pl_LdapDefaultClient_InitiateRequest
2235 * DESCRIPTION:
2236 *
2237 *
2238 * PARAMETERS:
2239 * "client"
2240 * The address of the LdapDefaultClient object. Must be non-NULL.
2241 * "requestParams"
2242 * The address of an LdapClientParams object. Must be non-NULL.
2243 * "pPollDesc"
2244 * The location where the address of the PRPollDesc is stored, if the
2245 * client returns with I/O pending.
2246 * "pResponse"
2247 * The address where the List of LDAPResponses, or NULL for an
2248 * unfinished request, is stored. Must be non-NULL.
2249 * "plContext"
2250 * Platform-specific context pointer.
2251 * THREAD SAFETY:
2252 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
2253 * RETURNS:
2254 * Returns NULL if the function succeeds.
2255 * Returns a LdapDefaultClient Error if the function fails in a
2256 * non-fatal way.
2257 * Returns a Fatal Error if the function fails in an unrecoverable way.
2258 */
2259 static PKIX_Error *
2260 pkix_pl_LdapDefaultClient_InitiateRequest(
2261 PKIX_PL_LdapClient *genericClient,
2262 LDAPRequestParams *requestParams,
2263 void **pPollDesc,
2264 PKIX_List **pResponse,
2265 void *plContext)
2266 {
2267 PKIX_List *searchResponseList = NULL;
2268 SECItem *encoded = NULL;
2269 LDAPFilter *filter = NULL;
2270 PKIX_PL_LdapDefaultClient *client = 0;
2271
2272 PKIX_ENTER
2273 (LDAPDEFAULTCLIENT,
2274 "pkix_pl_LdapDefaultClient_InitiateRequest");
2275 PKIX_NULLCHECK_FOUR(genericClient, requestParams, pPollDesc, pResponse);
2276
2277 PKIX_CHECK(pkix_CheckType
2278 ((PKIX_PL_Object *)genericClient,
2279 PKIX_LDAPDEFAULTCLIENT_TYPE,
2280 plContext),
2281 PKIX_GENERICCLIENTNOTANLDAPDEFAULTCLIENT);
2282
2283 client = (PKIX_PL_LdapDefaultClient *)genericClient;
2284
2285 PKIX_CHECK(pkix_pl_LdapDefaultClient_MakeAndFilter
2286 (client->arena, requestParams->nc, &filter, plContext),
2287 PKIX_LDAPDEFAULTCLIENTMAKEANDFILTERFAILED);
2288
2289 PKIX_CHECK(pkix_pl_LdapRequest_Create
2290 (client->arena,
2291 client->messageID++,
2292 requestParams->baseObject,
2293 requestParams->scope,
2294 requestParams->derefAliases,
2295 requestParams->sizeLimit,
2296 requestParams->timeLimit,
2297 PKIX_FALSE, /* attrs only */
2298 filter,
2299 requestParams->attributes,
2300 &client->currentRequest,
2301 plContext),
2302 PKIX_LDAPREQUESTCREATEFAILED);
2303
2304 /* check hashtable for matching request */
2305 PKIX_CHECK(PKIX_PL_HashTable_Lookup
2306 (client->cachePtr,
2307 (PKIX_PL_Object *)(client->currentRequest),
2308 (PKIX_PL_Object **)&searchResponseList,
2309 plContext),
2310 PKIX_HASHTABLELOOKUPFAILED);
2311
2312 if (searchResponseList != NULL) {
2313 *pPollDesc = NULL;
2314 *pResponse = searchResponseList;
2315 PKIX_DECREF(client->currentRequest);
2316 goto cleanup;
2317 }
2318
2319 /* It wasn't cached. We'll have to actually send it. */
2320
2321 PKIX_CHECK(pkix_pl_LdapRequest_GetEncoded
2322 (client->currentRequest, &encoded, plContext),
2323 PKIX_LDAPREQUESTGETENCODEDFAILED);
2324
2325 client->sendBuf = encoded->data;
2326 client->bytesToWrite = encoded->len;
2327
2328 PKIX_CHECK(pkix_pl_LdapDefaultClient_Dispatch(client, plContext),
2329 PKIX_LDAPDEFAULTCLIENTDISPATCHFAILED);
2330
2331 /*
2332 * It's not enough that we may be done with a particular read.
2333 * We're still processing the transaction until we've gotten the
2334 * SearchResponseResult message and returned to the BOUND state.
2335 * Otherwise we must still have a read pending, and must hold off
2336 * on returning results.
2337 */
2338 if ((client->connectStatus == BOUND) &&
2339 (client->entriesFound != NULL)) {
2340 *pPollDesc = NULL;
2341 *pResponse = client->entriesFound;
2342 client->entriesFound = NULL;
2343 PKIX_DECREF(client->currentRequest);
2344 } else {
2345 *pPollDesc = &client->pollDesc;
2346 *pResponse = NULL;
2347 }
2348
2349 cleanup:
2350
2351 PKIX_RETURN(LDAPDEFAULTCLIENT);
2352
2353 }
2354
2355 /*
2356 * FUNCTION: pkix_pl_LdapDefaultClient_ResumeRequest
2357 * DESCRIPTION:
2358 *
2359 *
2360 * PARAMETERS:
2361 * "client"
2362 * The address of the LdapDefaultClient object. Must be non-NULL.
2363 * "pPollDesc"
2364 * The location where the address of the PRPollDesc is stored, if the
2365 * client returns with I/O pending.
2366 * "pResponse"
2367 * The address where the List of LDAPResponses, or NULL for an
2368 * unfinished request, is stored. Must be non-NULL.
2369 * "plContext"
2370 * Platform-specific context pointer.
2371 * THREAD SAFETY:
2372 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
2373 * RETURNS:
2374 * Returns NULL if the function succeeds.
2375 * Returns a LdapDefaultClient Error if the function fails in a
2376 * non-fatal way.
2377 * Returns a Fatal Error if the function fails in an unrecoverable way.
2378 */
2379 static PKIX_Error *
2380 pkix_pl_LdapDefaultClient_ResumeRequest(
2381 PKIX_PL_LdapClient *genericClient,
2382 void **pPollDesc,
2383 PKIX_List **pResponse,
2384 void *plContext)
2385 {
2386 PKIX_PL_LdapDefaultClient *client = 0;
2387
2388 PKIX_ENTER
2389 (LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_ResumeRequest");
2390 PKIX_NULLCHECK_THREE(genericClient, pPollDesc, pResponse);
2391
2392 PKIX_CHECK(pkix_CheckType
2393 ((PKIX_PL_Object *)genericClient,
2394 PKIX_LDAPDEFAULTCLIENT_TYPE,
2395 plContext),
2396 PKIX_GENERICCLIENTNOTANLDAPDEFAULTCLIENT);
2397
2398 client = (PKIX_PL_LdapDefaultClient *)genericClient;
2399
2400 PKIX_CHECK(pkix_pl_LdapDefaultClient_Dispatch(client, plContext),
2401 PKIX_LDAPDEFAULTCLIENTDISPATCHFAILED);
2402
2403 /*
2404 * It's not enough that we may be done with a particular read.
2405 * We're still processing the transaction until we've gotten the
2406 * SearchResponseResult message and returned to the BOUND state.
2407 * Otherwise we must still have a read pending, and must hold off
2408 * on returning results.
2409 */
2410 if ((client->connectStatus == BOUND) &&
2411 (client->entriesFound != NULL)) {
2412 *pPollDesc = NULL;
2413 *pResponse = client->entriesFound;
2414 client->entriesFound = NULL;
2415 PKIX_DECREF(client->currentRequest);
2416 } else {
2417 *pPollDesc = &client->pollDesc;
2418 *pResponse = NULL;
2419 }
2420
2421 cleanup:
2422
2423 PKIX_RETURN(LDAPDEFAULTCLIENT);
2424
2425 }
2426
2427 /* --Public-LdapDefaultClient-Functions----------------------------------- */
2428
2429 /*
2430 * FUNCTION: PKIX_PL_LdapDefaultClient_AbandonRequest
2431 * DESCRIPTION:
2432 *
2433 * This function creates and sends an LDAP-protocol "Abandon" message to the
2434 * server connected to the LdapDefaultClient pointed to by "client".
2435 *
2436 * PARAMETERS:
2437 * "client"
2438 * The LdapDefaultClient whose connection is to be abandoned. Must be
2439 * non-NULL.
2440 * "plContext"
2441 * Platform-specific context pointer.
2442 * THREAD SAFETY:
2443 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
2444 * RETURNS:
2445 * Returns NULL if the function succeeds.
2446 * Returns a Fatal Error if the function fails in an unrecoverable way.
2447 */
2448 PKIX_Error *
2449 PKIX_PL_LdapDefaultClient_AbandonRequest(
2450 PKIX_PL_LdapDefaultClient *client,
2451 void *plContext)
2452 {
2453 PKIX_Int32 bytesWritten = 0;
2454 PKIX_PL_Socket_Callback *callbackList = NULL;
2455 SECItem *encoded = NULL;
2456
2457 PKIX_ENTER(CERTSTORE, "PKIX_PL_LdapDefaultClient_AbandonRequest");
2458 PKIX_NULLCHECK_ONE(client);
2459
2460 if (client->connectStatus == RECV_PENDING) {
2461 PKIX_CHECK(pkix_pl_LdapDefaultClient_MakeAbandon
2462 (client->arena,
2463 (client->messageID) - 1,
2464 &encoded,
2465 plContext),
2466 PKIX_LDAPDEFAULTCLIENTMAKEABANDONFAILED);
2467
2468 callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
2469 PKIX_CHECK(callbackList->sendCallback
2470 (client->clientSocket,
2471 encoded->data,
2472 encoded->len,
2473 &bytesWritten,
2474 plContext),
2475 PKIX_SOCKETSENDFAILED);
2476
2477 if (bytesWritten < 0) {
2478 client->connectStatus = ABANDON_PENDING;
2479 } else {
2480 client->connectStatus = BOUND;
2481 }
2482 }
2483
2484 PKIX_DECREF(client->entriesFound);
2485 PKIX_DECREF(client->currentRequest);
2486 PKIX_DECREF(client->currentResponse);
2487
2488 cleanup:
2489
2490 PKIX_DECREF(client);
2491
2492 PKIX_RETURN(CERTSTORE);
2493 }
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)