30 #define SECURITY_WIN32 
   35 #define SCHANNEL_INITIAL_BUFFER_SIZE   4096 
   36 #define SCHANNEL_FREE_BUFFER_SIZE      1024 
   39 #ifndef SECBUFFER_ALERT 
   40 #define SECBUFFER_ALERT                17 
   64     SecPkgContext_StreamSizes 
sizes;
 
   80                                  unsigned long buffer_count)
 
   82     desc->ulVersion = SECBUFFER_VERSION;
 
   83     desc->pBuffers = buffers;
 
   84     desc->cBuffers = buffer_count;
 
   94         SecBufferDesc BuffDesc;
 
   96         SECURITY_STATUS sspi_ret;
 
   98         SecBufferDesc outbuf_desc;
 
  100         DWORD dwshut = SCHANNEL_SHUTDOWN;
 
  104         sspi_ret = ApplyControlToken(&
c->ctxt_handle, &BuffDesc);
 
  105         if (sspi_ret != SEC_E_OK)
 
  111         sspi_ret = InitializeSecurityContext(&
c->cred_handle, &
c->ctxt_handle, 
s->host,
 
  112                                              c->request_flags, 0, 0, 
NULL, 0, &
c->ctxt_handle,
 
  113                                              &outbuf_desc, &
c->context_flags, &
c->ctxt_timestamp);
 
  114         if (sspi_ret == SEC_E_OK || sspi_ret == SEC_I_CONTEXT_EXPIRED) {
 
  116             FreeContextBuffer(outbuf.pvBuffer);
 
  117             if (
ret < 0 || 
ret != outbuf.cbBuffer)
 
  132     DeleteSecurityContext(&
c->ctxt_handle);
 
  133     FreeCredentialsHandle(&
c->cred_handle);
 
  136     c->enc_buf_size = 
c->enc_buf_offset = 0;
 
  139     c->dec_buf_size = 
c->dec_buf_offset = 0;
 
  149     SECURITY_STATUS sspi_ret;
 
  150     SecBuffer outbuf[3] = { 0 };
 
  151     SecBufferDesc outbuf_desc;
 
  153     SecBufferDesc inbuf_desc;
 
  156     if (
c->enc_buf == 
NULL) {
 
  157         c->enc_buf_offset = 0;
 
  164     if (
c->dec_buf == 
NULL) {
 
  165         c->dec_buf_offset = 0;
 
  177                 c->enc_buf_size = 
c->enc_buf_offset = 0;
 
  184                              c->enc_buf_size - 
c->enc_buf_offset);
 
  189             c->enc_buf_offset += 
ret;
 
  197         if (inbuf[0].pvBuffer == 
NULL) {
 
  203         memcpy(inbuf[0].pvBuffer, 
c->enc_buf, 
c->enc_buf_offset);
 
  211         sspi_ret = InitializeSecurityContext(&
c->cred_handle, &
c->ctxt_handle, 
s->host, 
c->request_flags,
 
  212                                              0, 0, &inbuf_desc, 0, 
NULL, &outbuf_desc, &
c->context_flags,
 
  216         if (sspi_ret == SEC_E_INCOMPLETE_MESSAGE) {
 
  223         if (sspi_ret == SEC_I_INCOMPLETE_CREDENTIALS &&
 
  224             !(
c->request_flags & ISC_REQ_USE_SUPPLIED_CREDS)) {
 
  226             c->request_flags |= ISC_REQ_USE_SUPPLIED_CREDS;
 
  232         if (sspi_ret == SEC_I_CONTINUE_NEEDED || sspi_ret == SEC_E_OK) {
 
  233             for (
i = 0; 
i < 3; 
i++) {
 
  234                 if (outbuf[
i].BufferType == SECBUFFER_TOKEN && outbuf[
i].cbBuffer > 0) {
 
  236                     if (
ret < 0 || 
ret != outbuf[
i].cbBuffer) {
 
  243                 if (outbuf[
i].pvBuffer != 
NULL) {
 
  244                     FreeContextBuffer(outbuf[
i].pvBuffer);
 
  245                     outbuf[
i].pvBuffer = 
NULL;
 
  249             if (sspi_ret == SEC_E_WRONG_PRINCIPAL)
 
  257         if (inbuf[1].BufferType == SECBUFFER_EXTRA && inbuf[1].cbBuffer > 0) {
 
  258             if (
c->enc_buf_offset > inbuf[1].cbBuffer) {
 
  259                 memmove(
c->enc_buf, (
c->enc_buf + 
c->enc_buf_offset) - inbuf[1].cbBuffer,
 
  261                 c->enc_buf_offset = inbuf[1].cbBuffer;
 
  262                 if (sspi_ret == SEC_I_CONTINUE_NEEDED) {
 
  268             c->enc_buf_offset  = 0;
 
  271         if (sspi_ret == SEC_I_CONTINUE_NEEDED) {
 
  283     for (
i = 0; 
i < 3; 
i++) {
 
  284         if (outbuf[
i].pvBuffer != 
NULL) {
 
  285             FreeContextBuffer(outbuf[
i].pvBuffer);
 
  286             outbuf[
i].pvBuffer = 
NULL;
 
  298     SecBufferDesc outbuf_desc;
 
  299     SECURITY_STATUS sspi_ret;
 
  305     c->request_flags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT |
 
  306                        ISC_REQ_CONFIDENTIALITY | ISC_REQ_ALLOCATE_MEMORY |
 
  309     sspi_ret = InitializeSecurityContext(&
c->cred_handle, 
NULL, 
s->host, 
c->request_flags, 0, 0,
 
  310                                          NULL, 0, &
c->ctxt_handle, &outbuf_desc, &
c->context_flags,
 
  312     if (sspi_ret != SEC_I_CONTINUE_NEEDED) {
 
  319     FreeContextBuffer(outbuf.pvBuffer);
 
  320     if (
ret < 0 || 
ret != outbuf.cbBuffer) {
 
  329     DeleteSecurityContext(&
c->ctxt_handle);
 
  337     SECURITY_STATUS sspi_ret;
 
  338     SCHANNEL_CRED schannel_cred = { 0 };
 
  351     schannel_cred.dwVersion = SCHANNEL_CRED_VERSION;
 
  354         schannel_cred.dwFlags = SCH_CRED_AUTO_CRED_VALIDATION |
 
  355                                 SCH_CRED_REVOCATION_CHECK_CHAIN;
 
  357         schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION |
 
  358                                 SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
 
  359                                 SCH_CRED_IGNORE_REVOCATION_OFFLINE;
 
  362     sspi_ret = AcquireCredentialsHandle(
NULL, (TCHAR *)UNISP_NAME, SECPKG_CRED_OUTBOUND,
 
  365     if (sspi_ret != SEC_E_OK) {
 
  388     SECURITY_STATUS sspi_ret = SEC_E_OK;
 
  390     SecBufferDesc inbuf_desc;
 
  399     if (
c->dec_buf_offset > 0)
 
  402     if (
c->sspi_close_notify)
 
  405     if (!
c->connection_closed) {
 
  406         size = 
c->enc_buf_size - 
c->enc_buf_offset;
 
  407         if (size < SCHANNEL_FREE_BUFFER_SIZE || c->enc_buf_size < min_enc_buf_size) {
 
  409             if (
c->enc_buf_size < min_enc_buf_size)
 
  410                 c->enc_buf_size = min_enc_buf_size;
 
  413                 c->enc_buf_size = 
c->enc_buf_offset = 0;
 
  419                          c->enc_buf_size - 
c->enc_buf_offset);
 
  421             c->connection_closed = 1;
 
  423         } 
else if (
ret < 0) {
 
  428         c->enc_buf_offset += 
ret;
 
  431     while (
c->enc_buf_offset > 0 && sspi_ret == SEC_E_OK) {
 
  441         sspi_ret = DecryptMessage(&
c->ctxt_handle, &inbuf_desc, 0, 
NULL);
 
  442         if (sspi_ret == SEC_E_OK || sspi_ret == SEC_I_RENEGOTIATE ||
 
  443             sspi_ret == SEC_I_CONTEXT_EXPIRED) {
 
  445             if (inbuf[1].BufferType == SECBUFFER_DATA) {
 
  449                 if (
c->dec_buf_size - 
c->dec_buf_offset < 
size || 
c->dec_buf_size < 
len)  {
 
  450                     c->dec_buf_size = 
c->dec_buf_offset + 
size;
 
  451                     if (
c->dec_buf_size < 
len)
 
  452                         c->dec_buf_size = 
len;
 
  455                         c->dec_buf_size = 
c->dec_buf_offset = 0;
 
  461                 size = inbuf[1].cbBuffer;
 
  463                     memcpy(
c->dec_buf + 
c->dec_buf_offset, inbuf[1].pvBuffer, 
size);
 
  464                     c->dec_buf_offset += 
size;
 
  467             if (inbuf[3].BufferType == SECBUFFER_EXTRA && inbuf[3].cbBuffer > 0) {
 
  468                 if (
c->enc_buf_offset > inbuf[3].cbBuffer) {
 
  469                     memmove(
c->enc_buf, (
c->enc_buf + 
c->enc_buf_offset) - inbuf[3].cbBuffer,
 
  471                     c->enc_buf_offset = inbuf[3].cbBuffer;
 
  474                 c->enc_buf_offset = 0;
 
  476             if (sspi_ret == SEC_I_RENEGOTIATE) {
 
  477                 if (
c->enc_buf_offset) {
 
  490             } 
else if (sspi_ret == SEC_I_CONTEXT_EXPIRED) {
 
  491                 c->sspi_close_notify = 1;
 
  492                 if (!
c->connection_closed) {
 
  493                     c->connection_closed = 1;
 
  499         } 
else if (sspi_ret == SEC_E_INCOMPLETE_MESSAGE) {
 
  514         memcpy(buf, 
c->dec_buf, 
size);
 
  515         memmove(
c->dec_buf, 
c->dec_buf + 
size, 
c->dec_buf_offset - 
size);
 
  516         c->dec_buf_offset -= 
size;
 
  521     if (
ret == 0 && !
c->connection_closed)
 
  531     SECURITY_STATUS sspi_ret;
 
  532     int ret = 0, data_size;
 
  535     SecBufferDesc outbuf_desc;
 
  537     if (
c->sizes.cbMaximumMessage == 0) {
 
  538         sspi_ret = QueryContextAttributes(&
c->ctxt_handle, SECPKG_ATTR_STREAM_SIZES, &
c->sizes);
 
  539         if (sspi_ret != SEC_E_OK)
 
  546     data_size = 
c->sizes.cbHeader + 
len + 
c->sizes.cbTrailer;
 
  552                   data, 
c->sizes.cbHeader);
 
  561     memcpy(outbuf[1].pvBuffer, buf, 
len);
 
  563     sspi_ret = EncryptMessage(&
c->ctxt_handle, 0, &outbuf_desc, 0);
 
  564     if (sspi_ret == SEC_E_OK)  {
 
  565         len = outbuf[0].cbBuffer + outbuf[1].cbBuffer + outbuf[2].cbBuffer;
 
  574         if (sspi_ret == SEC_E_INSUFFICIENT_MEMORY)
 
  583     return ret < 0 ? 
ret : outbuf[1].cbBuffer;