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) {
115 ret =
ffurl_write(
s->tcp, outbuf.pvBuffer, outbuf.cbBuffer);
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;
183 ret =
ffurl_read(
c->tls_shared.tcp,
c->enc_buf +
c->enc_buf_offset,
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) {
235 ret =
ffurl_write(
c->tls_shared.tcp, outbuf[
i].pvBuffer, outbuf[
i].cbBuffer);
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) {
318 ret =
ffurl_write(
s->tcp, outbuf.pvBuffer, outbuf.cbBuffer);
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;
567 if (ret < 0 || ret !=
len) {
574 if (sspi_ret == SEC_E_INSUFFICIENT_MEMORY)
583 return ret < 0 ? ret : outbuf[1].cbBuffer;
int ffurl_read(URLContext *h, unsigned char *buf, int size)
Read up to size bytes from the resource accessed by h, and store the read bytes in buf.
int ffurl_get_short_seek(URLContext *h)
Return the current short seek threshold value for this URL.
int ffurl_closep(URLContext **hh)
Close the resource accessed by the URLContext h, and free the memory used by it.
int ffurl_write(URLContext *h, const unsigned char *buf, int size)
Write size bytes from buf to the resource accessed by h.
int ffurl_get_file_handle(URLContext *h)
Return the file descriptor associated with this URL.
#define flags(name, subs,...)
static int read_data(void *opaque, uint8_t *buf, int buf_size)
static av_cold void cleanup(FlashSV2Context *s)
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
#define AVERROR_EOF
End of file.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
#define AV_LOG_VERBOSE
Detailed information.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
const char * av_default_item_name(void *ptr)
Return the context name.
int av_reallocp(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory through a pointer to a pointer.
#define LIBAVUTIL_VERSION_INT
common internal API header
miscellaneous OS support macros and functions.
Describe the class of an AVClass context structure.
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
SecPkgContext_StreamSizes sizes
int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AVDictionary **options)
#define TLS_COMMON_OPTIONS(pstruct, options_field)
static int tls_close(URLContext *h)
static const AVClass tls_class
static void init_sec_buffer_desc(SecBufferDesc *desc, SecBuffer *buffers, unsigned long buffer_count)
const URLProtocol ff_tls_protocol
static const AVOption options[]
static int tls_read(URLContext *h, uint8_t *buf, int len)
static int tls_shutdown_client(URLContext *h)
static int tls_write(URLContext *h, const uint8_t *buf, int len)
static int tls_client_handshake(URLContext *h)
static int tls_client_handshake_loop(URLContext *h, int initial)
static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
static void init_sec_buffer(SecBuffer *buffer, unsigned long type, void *data, unsigned long size)
#define SCHANNEL_INITIAL_BUFFER_SIZE
static int tls_get_short_seek(URLContext *h)
static int tls_get_file_handle(URLContext *h)
#define SCHANNEL_FREE_BUFFER_SIZE
unbuffered private I/O API
#define URL_PROTOCOL_FLAG_NETWORK