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