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