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;
141 if (
c->tls_shared.tcp)
150 SECURITY_STATUS sspi_ret;
151 SecBuffer outbuf[3] = { 0 };
152 SecBufferDesc outbuf_desc;
154 SecBufferDesc inbuf_desc;
157 if (
c->enc_buf ==
NULL) {
158 c->enc_buf_offset = 0;
165 if (
c->dec_buf ==
NULL) {
166 c->dec_buf_offset = 0;
178 c->enc_buf_size =
c->enc_buf_offset = 0;
185 c->enc_buf_size -
c->enc_buf_offset);
190 c->enc_buf_offset +=
ret;
198 if (inbuf[0].pvBuffer ==
NULL) {
204 memcpy(inbuf[0].pvBuffer,
c->enc_buf,
c->enc_buf_offset);
212 sspi_ret = InitializeSecurityContext(&
c->cred_handle, &
c->ctxt_handle,
s->host,
c->request_flags,
213 0, 0, &inbuf_desc, 0,
NULL, &outbuf_desc, &
c->context_flags,
217 if (sspi_ret == SEC_E_INCOMPLETE_MESSAGE) {
224 if (sspi_ret == SEC_I_INCOMPLETE_CREDENTIALS &&
225 !(
c->request_flags & ISC_REQ_USE_SUPPLIED_CREDS)) {
227 c->request_flags |= ISC_REQ_USE_SUPPLIED_CREDS;
233 if (sspi_ret == SEC_I_CONTINUE_NEEDED || sspi_ret == SEC_E_OK) {
234 for (
i = 0;
i < 3;
i++) {
235 if (outbuf[
i].BufferType == SECBUFFER_TOKEN && outbuf[
i].cbBuffer > 0) {
237 if (
ret < 0 ||
ret != outbuf[
i].cbBuffer) {
244 if (outbuf[
i].pvBuffer !=
NULL) {
245 FreeContextBuffer(outbuf[
i].pvBuffer);
246 outbuf[
i].pvBuffer =
NULL;
250 if (sspi_ret == SEC_E_WRONG_PRINCIPAL)
258 if (inbuf[1].BufferType == SECBUFFER_EXTRA && inbuf[1].cbBuffer > 0) {
259 if (
c->enc_buf_offset > inbuf[1].cbBuffer) {
260 memmove(
c->enc_buf, (
c->enc_buf +
c->enc_buf_offset) - inbuf[1].cbBuffer,
262 c->enc_buf_offset = inbuf[1].cbBuffer;
263 if (sspi_ret == SEC_I_CONTINUE_NEEDED) {
269 c->enc_buf_offset = 0;
272 if (sspi_ret == SEC_I_CONTINUE_NEEDED) {
284 for (
i = 0;
i < 3;
i++) {
285 if (outbuf[
i].pvBuffer !=
NULL) {
286 FreeContextBuffer(outbuf[
i].pvBuffer);
287 outbuf[
i].pvBuffer =
NULL;
299 SecBufferDesc outbuf_desc;
300 SECURITY_STATUS sspi_ret;
306 c->request_flags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT |
307 ISC_REQ_CONFIDENTIALITY | ISC_REQ_ALLOCATE_MEMORY |
310 sspi_ret = InitializeSecurityContext(&
c->cred_handle,
NULL,
s->host,
c->request_flags, 0, 0,
311 NULL, 0, &
c->ctxt_handle, &outbuf_desc, &
c->context_flags,
313 if (sspi_ret != SEC_I_CONTINUE_NEEDED) {
320 FreeContextBuffer(outbuf.pvBuffer);
321 if (
ret < 0 ||
ret != outbuf.cbBuffer) {
330 DeleteSecurityContext(&
c->ctxt_handle);
338 SECURITY_STATUS sspi_ret;
339 SCHANNEL_CRED schannel_cred = { 0 };
352 schannel_cred.dwVersion = SCHANNEL_CRED_VERSION;
355 schannel_cred.dwFlags = SCH_CRED_AUTO_CRED_VALIDATION |
356 SCH_CRED_REVOCATION_CHECK_CHAIN;
358 schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION |
359 SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
360 SCH_CRED_IGNORE_REVOCATION_OFFLINE;
363 sspi_ret = AcquireCredentialsHandle(
NULL, (
TCHAR *)UNISP_NAME, SECPKG_CRED_OUTBOUND,
366 if (sspi_ret != SEC_E_OK) {
389 SECURITY_STATUS sspi_ret = SEC_E_OK;
391 SecBufferDesc inbuf_desc;
400 if (
c->dec_buf_offset > 0)
403 if (
c->sspi_close_notify)
406 if (!
c->connection_closed) {
407 size =
c->enc_buf_size -
c->enc_buf_offset;
408 if (size < SCHANNEL_FREE_BUFFER_SIZE || c->enc_buf_size < min_enc_buf_size) {
410 if (
c->enc_buf_size < min_enc_buf_size)
411 c->enc_buf_size = min_enc_buf_size;
414 c->enc_buf_size =
c->enc_buf_offset = 0;
420 c->enc_buf_size -
c->enc_buf_offset);
422 c->connection_closed = 1;
424 }
else if (
ret < 0) {
429 c->enc_buf_offset +=
ret;
432 while (
c->enc_buf_offset > 0 && sspi_ret == SEC_E_OK) {
442 sspi_ret = DecryptMessage(&
c->ctxt_handle, &inbuf_desc, 0,
NULL);
443 if (sspi_ret == SEC_E_OK || sspi_ret == SEC_I_RENEGOTIATE ||
444 sspi_ret == SEC_I_CONTEXT_EXPIRED) {
446 if (inbuf[1].BufferType == SECBUFFER_DATA) {
450 if (
c->dec_buf_size -
c->dec_buf_offset <
size ||
c->dec_buf_size <
len) {
451 c->dec_buf_size =
c->dec_buf_offset +
size;
452 if (
c->dec_buf_size <
len)
453 c->dec_buf_size =
len;
456 c->dec_buf_size =
c->dec_buf_offset = 0;
462 size = inbuf[1].cbBuffer;
464 memcpy(
c->dec_buf +
c->dec_buf_offset, inbuf[1].pvBuffer,
size);
465 c->dec_buf_offset +=
size;
468 if (inbuf[3].BufferType == SECBUFFER_EXTRA && inbuf[3].cbBuffer > 0) {
469 if (
c->enc_buf_offset > inbuf[3].cbBuffer) {
470 memmove(
c->enc_buf, (
c->enc_buf +
c->enc_buf_offset) - inbuf[3].cbBuffer,
472 c->enc_buf_offset = inbuf[3].cbBuffer;
475 c->enc_buf_offset = 0;
477 if (sspi_ret == SEC_I_RENEGOTIATE) {
478 if (
c->enc_buf_offset) {
491 }
else if (sspi_ret == SEC_I_CONTEXT_EXPIRED) {
492 c->sspi_close_notify = 1;
493 if (!
c->connection_closed) {
494 c->connection_closed = 1;
500 }
else if (sspi_ret == SEC_E_INCOMPLETE_MESSAGE) {
516 memmove(
c->dec_buf,
c->dec_buf +
size,
c->dec_buf_offset -
size);
517 c->dec_buf_offset -=
size;
522 if (
ret == 0 && !
c->connection_closed)
532 SECURITY_STATUS sspi_ret;
533 int ret = 0, data_size;
536 SecBufferDesc outbuf_desc;
538 if (
c->sizes.cbMaximumMessage == 0) {
539 sspi_ret = QueryContextAttributes(&
c->ctxt_handle, SECPKG_ATTR_STREAM_SIZES, &
c->sizes);
540 if (sspi_ret != SEC_E_OK)
547 data_size =
c->sizes.cbHeader +
len +
c->sizes.cbTrailer;
553 data,
c->sizes.cbHeader);
562 memcpy(outbuf[1].pvBuffer,
buf,
len);
564 sspi_ret = EncryptMessage(&
c->ctxt_handle, 0, &outbuf_desc, 0);
565 if (sspi_ret == SEC_E_OK) {
566 len = outbuf[0].cbBuffer + outbuf[1].cbBuffer + outbuf[2].cbBuffer;
575 if (sspi_ret == SEC_E_INSUFFICIENT_MEMORY)
584 return ret < 0 ?
ret : outbuf[1].cbBuffer;