352{
353 Socket::connect(_serv_addr, _addrlen);
354
356
357#if __DCL_USE_OPENSSL
360 __ssl = SSL_new(__ctx);
361 BIO* bio = BIO_new_socket(
__handle, BIO_NOCLOSE);
362
363 SSL_set_bio(__ssl, bio, bio);
364
365 if (SSL_connect(__ssl) < 0)
366 throw new IOException(
toString(),
new SSLException());
367
368#elif __DCL_USE_SCHANNEL
369 DWORD fContextReq = ISC_REQ_SEQUENCE_DETECT |
370 ISC_REQ_REPLAY_DETECT |
371 ISC_REQ_CONFIDENTIALITY |
372 ISC_RET_EXTENDED_ERROR |
373 ISC_REQ_ALLOCATE_MEMORY |
374 ISC_REQ_STREAM;
375
376 SecBufferDesc outBufferDesc;
377 SecBuffer outBuffers[1];
378
379 outBuffers[0].BufferType = SECBUFFER_TOKEN;
380 outBuffers[0].cbBuffer = 0;
381 outBuffers[0].pvBuffer =
NULL;
382 outBufferDesc.ulVersion = SECBUFFER_VERSION;
383 outBufferDesc.cBuffers = 1;
384 outBufferDesc.pBuffers = outBuffers;
385
386 CtxtHandle ctxt;
387 ULONG ctxtAttr;
388 TimeStamp tsExpiry;
389
390 SECURITY_STATUS ss = InitializeSecurityContextW(
391 &__cred,
394 fContextReq,
395 0,
396 0,
398 0,
399 &ctxt,
400 &outBufferDesc,
401 &ctxtAttr,
402 &tsExpiry
403 );
404
405 if (FAILED(ss))
406 throw new IOException(
toString(),
new SSLException(ss));
407
409
410 if (outBuffers[0].cbBuffer != 0 && outBuffers[0].pvBuffer !=
NULL) {
412 outBuffers[0].BufferType,
413 outBuffers[0].cbBuffer,
414 String::tryString((const char*) outBuffers[0].pvBuffer,
415 outBuffers[0].cbBuffer, 8).data()
416 );
418 (const char*) outBuffers[0].pvBuffer, outBuffers[0].cbBuffer, 0);
419 if (
n == SOCKET_ERROR ||
n == 0) {
420 FreeContextBuffer(outBuffers[0].pvBuffer);
421 DeleteSecurityContext(&ctxt);
422 throw new IOException(
toString(), WSAGetLastError());
423 }
424
426 FreeContextBuffer(outBuffers[0].pvBuffer);
427 outBuffers[0].pvBuffer =
NULL;
428 }
429
430
431
432 SecBufferDesc inBufferDesc;
433 SecBuffer inBuffers[2];
434
435 DWORD WSAError = 0;
436#define READ_BUFFER_SIZE 0x10000
437 char* readBuffer = (char*) malloc(READ_BUFFER_SIZE);
438 bool fDoRead = true;
439 unsigned int nRead = 0;
440
441 while (ss == SEC_I_CONTINUE_NEEDED ||
442 ss == SEC_E_INCOMPLETE_MESSAGE ||
443 ss == SEC_I_INCOMPLETE_CREDENTIALS) {
444 if (0 == nRead || ss == SEC_E_INCOMPLETE_MESSAGE) {
445 if (fDoRead) {
448 readBuffer + nRead,
449 READ_BUFFER_SIZE - nRead,
450 0
451 );
452 if (
n == SOCKET_ERROR) {
453 WSAError = WSAGetLastError();
454 ss = SEC_E_INTERNAL_ERROR;
455 break;
456 }
458 WSAError = WSAECONNRESET;
459 ss = SEC_E_INTERNAL_ERROR;
460 break;
461 }
463 String::tryString((
const char*) readBuffer + nRead,
n, 8).data());
464
466 }
467 else
468 fDoRead = true;
469 }
470
471 inBuffers[0].BufferType = SECBUFFER_TOKEN;
472 inBuffers[0].cbBuffer = nRead;
473 inBuffers[0].pvBuffer = readBuffer;
474
475 inBuffers[1].BufferType = SECBUFFER_EMPTY;
476 inBuffers[1].cbBuffer = 0;
477 inBuffers[1].pvBuffer =
NULL;
478
479 inBufferDesc.ulVersion = SECBUFFER_VERSION;
480 inBufferDesc.cBuffers = 2;
481 inBufferDesc.pBuffers = inBuffers;
482
483 outBuffers[0].BufferType = SECBUFFER_TOKEN;
484 outBuffers[0].cbBuffer = 0;
485 outBuffers[0].pvBuffer =
NULL;
486
487 outBufferDesc.ulVersion = SECBUFFER_VERSION;
488 outBufferDesc.cBuffers = 1;
489 outBufferDesc.pBuffers = outBuffers;
490
491 ss = InitializeSecurityContextW(
492 &__cred,
493 &ctxt,
495 fContextReq,
496 0,
497 SECURITY_NATIVE_DREP,
498 &inBufferDesc,
499 0,
501 &outBufferDesc,
502 &ctxtAttr,
503 &tsExpiry
504 );
505
506 if (ss == SEC_E_OK ||
507 ss == SEC_I_CONTINUE_NEEDED ||
508 FAILED(ss) && (ctxtAttr & ISC_RET_EXTENDED_ERROR)) {
509 if (outBuffers[0].cbBuffer != 0 && outBuffers[0].pvBuffer !=
NULL) {
512 (const char*) outBuffers[0].pvBuffer,
513 outBuffers[0].cbBuffer,
514 0
515 );
516 if (
n == SOCKET_ERROR ||
n == 0) {
517 WSAError = WSAGetLastError();
518 FreeContextBuffer(outBuffers[0].pvBuffer);
519 DeleteSecurityContext(&ctxt);
520 ss = SEC_E_INTERNAL_ERROR;
521 break;
522 }
523
525 FreeContextBuffer(outBuffers[0].pvBuffer);
526 outBuffers[0].pvBuffer =
NULL;
527 }
528 }
529
530 if (ss == SEC_E_INCOMPLETE_MESSAGE) {
531 __DCL_TRACE0(
__T(
"====================== SEC_E_INCOMPLETE_MESSAGE =====================\n"));
532 continue;
533 }
534
536 if (ss == SEC_E_OK) {
538
539 if (inBuffers[1].BufferType == SECBUFFER_EXTRA) {
541 }
542
543 break;
544 }
545
547
548 if(ss == SEC_I_INCOMPLETE_CREDENTIALS) {
550
551
552
553 break;
554
555 fDoRead = false;
556 ss = SEC_I_CONTINUE_NEEDED;
557 continue;
558 }
559
560 if (inBuffers[1].BufferType == SECBUFFER_EXTRA) {
562 memcpy(readBuffer,
563 readBuffer + (nRead - inBuffers[1].cbBuffer),
564 inBuffers[1].cbBuffer
565 );
566 nRead = inBuffers[1].cbBuffer;
567 }
568 else
569 nRead = 0;
570 }
571
572 free(readBuffer);
573
574 if (FAILED(ss)) {
575 DeleteSecurityContext(&ctxt);
576 }
577 else
578 __ctxt = ctxt;
579
580#endif
581}
#define __DCL_TRACE0(psz)
#define __DCL_TRACE3(fmt, arg1, arg2, arg3)
#define __DCL_TRACE2(fmt, arg1, arg2)
void CharsetConvertException *size_t n
virtual String toString() const
virtual size_t send(const void *_buf, size_t _n, int _flags=0) __DCL_THROWS1(IOException *)
virtual size_t recv(void *_buf, size_t _n, int _flags=0) __DCL_THROWS1(IOException *)