THRIFT-4881 Allow TLS1.1 and TLS1.2 even when not configured as systemwide default
Client: Delphi
Patch: Jens Geyer
diff --git a/lib/delphi/src/Thrift.WinHTTP.pas b/lib/delphi/src/Thrift.WinHTTP.pas
index 6ad8400..4b98f69 100644
--- a/lib/delphi/src/Thrift.WinHTTP.pas
+++ b/lib/delphi/src/Thrift.WinHTTP.pas
@@ -84,6 +84,16 @@
                              const dwFlags : DWORD
                              ) : HINTERNET;  stdcall;
 
+function WinHttpQueryOption( const hInternet : HINTERNET;
+                             const dwOption : DWORD;
+                             const pBuffer : Pointer;
+                             var dwBufferLength : DWORD) : BOOL;  stdcall;
+
+function WinHttpSetOption( const hInternet : HINTERNET;
+                           const dwOption : DWORD;
+                           const pBuffer : Pointer;
+                           const dwBufferLength : DWORD) : BOOL;  stdcall;
+
 function WinHttpSetTimeouts( const hRequestOrSession : HINTERNET;
                              const aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout : Int32
                              ) : BOOL;  stdcall;
@@ -193,6 +203,157 @@
   INTERNET_SCHEME_HTTP  = INTERNET_SCHEME(1);
   INTERNET_SCHEME_HTTPS = INTERNET_SCHEME(2);
 
+  WINHTTP_NO_CLIENT_CERT_CONTEXT = nil;
+
+  // options manifests for WinHttp{Query|Set}Option
+  WINHTTP_OPTION_CALLBACK = 1;
+  WINHTTP_OPTION_RESOLVE_TIMEOUT = 2;
+  WINHTTP_OPTION_CONNECT_TIMEOUT = 3;
+  WINHTTP_OPTION_CONNECT_RETRIES = 4;
+  WINHTTP_OPTION_SEND_TIMEOUT = 5;
+  WINHTTP_OPTION_RECEIVE_TIMEOUT = 6;
+  WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT = 7;
+  WINHTTP_OPTION_HANDLE_TYPE = 9;
+  WINHTTP_OPTION_READ_BUFFER_SIZE = 12;
+  WINHTTP_OPTION_WRITE_BUFFER_SIZE = 13;
+  WINHTTP_OPTION_PARENT_HANDLE = 21;
+  WINHTTP_OPTION_EXTENDED_ERROR = 24;
+  WINHTTP_OPTION_SECURITY_FLAGS = 31;
+  WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT = 32;
+  WINHTTP_OPTION_URL = 34;
+  WINHTTP_OPTION_SECURITY_KEY_BITNESS = 36;
+  WINHTTP_OPTION_PROXY = 38;
+  WINHTTP_OPTION_USER_AGENT = 41;
+  WINHTTP_OPTION_CONTEXT_VALUE = 45;
+  WINHTTP_OPTION_CLIENT_CERT_CONTEXT = 47;
+  WINHTTP_OPTION_REQUEST_PRIORITY = 58;
+  WINHTTP_OPTION_HTTP_VERSION = 59;
+  WINHTTP_OPTION_DISABLE_FEATURE = 63;
+  WINHTTP_OPTION_CODEPAGE = 68;
+  WINHTTP_OPTION_MAX_CONNS_PER_SERVER = 73;
+  WINHTTP_OPTION_MAX_CONNS_PER_1_0_SERVER = 74;
+  WINHTTP_OPTION_AUTOLOGON_POLICY = 77;
+  WINHTTP_OPTION_SERVER_CERT_CONTEXT = 78;
+  WINHTTP_OPTION_ENABLE_FEATURE = 79;
+  WINHTTP_OPTION_WORKER_THREAD_COUNT = 80;
+  WINHTTP_OPTION_PASSPORT_COBRANDING_TEXT = 81;
+  WINHTTP_OPTION_PASSPORT_COBRANDING_URL = 82;
+  WINHTTP_OPTION_CONFIGURE_PASSPORT_AUTH = 83;
+  WINHTTP_OPTION_SECURE_PROTOCOLS = 84;
+  WINHTTP_OPTION_ENABLETRACING = 85;
+  WINHTTP_OPTION_PASSPORT_SIGN_OUT = 86;
+  WINHTTP_OPTION_PASSPORT_RETURN_URL = 87;
+  WINHTTP_OPTION_REDIRECT_POLICY = 88;
+  WINHTTP_OPTION_MAX_HTTP_AUTOMATIC_REDIRECTS = 89;
+  WINHTTP_OPTION_MAX_HTTP_STATUS_CONTINUE = 90;
+  WINHTTP_OPTION_MAX_RESPONSE_HEADER_SIZE = 91;
+  WINHTTP_OPTION_MAX_RESPONSE_DRAIN_SIZE = 92;
+  WINHTTP_OPTION_CONNECTION_INFO = 93;
+  WINHTTP_OPTION_CLIENT_CERT_ISSUER_LIST = 94;
+  WINHTTP_OPTION_SPN = 96;
+  WINHTTP_OPTION_GLOBAL_PROXY_CREDS = 97;
+  WINHTTP_OPTION_GLOBAL_SERVER_CREDS = 98;
+  WINHTTP_OPTION_UNLOAD_NOTIFY_EVENT = 99;
+  WINHTTP_OPTION_REJECT_USERPWD_IN_URL = 100;
+  WINHTTP_OPTION_USE_GLOBAL_SERVER_CREDENTIALS = 101;
+  WINHTTP_OPTION_RECEIVE_PROXY_CONNECT_RESPONSE = 103;
+  WINHTTP_OPTION_IS_PROXY_CONNECT_RESPONSE = 104;
+  WINHTTP_OPTION_SERVER_SPN_USED = 106;
+  WINHTTP_OPTION_PROXY_SPN_USED = 107;
+  WINHTTP_OPTION_SERVER_CBT = 108;
+  //
+  WINHTTP_FIRST_OPTION = WINHTTP_OPTION_CALLBACK;
+  WINHTTP_LAST_OPTION = WINHTTP_OPTION_SERVER_CBT;
+
+  WINHTTP_OPTION_USERNAME = $1000;
+  WINHTTP_OPTION_PASSWORD = $1001;
+  WINHTTP_OPTION_PROXY_USERNAME = $1002;
+  WINHTTP_OPTION_PROXY_PASSWORD = $1003;
+
+  // manifest value for WINHTTP_OPTION_MAX_CONNS_PER_SERVER and WINHTTP_OPTION_MAX_CONNS_PER_1_0_SERVER
+  WINHTTP_CONNS_PER_SERVER_UNLIMITED    = $FFFFFFFF;
+
+  // values for WINHTTP_OPTION_AUTOLOGON_POLICY
+  WINHTTP_AUTOLOGON_SECURITY_LEVEL_MEDIUM  = 0;
+  WINHTTP_AUTOLOGON_SECURITY_LEVEL_LOW     = 1;
+  WINHTTP_AUTOLOGON_SECURITY_LEVEL_HIGH    = 2;
+
+  WINHTTP_AUTOLOGON_SECURITY_LEVEL_DEFAULT = WINHTTP_AUTOLOGON_SECURITY_LEVEL_MEDIUM;
+
+  // values for WINHTTP_OPTION_REDIRECT_POLICY
+  WINHTTP_OPTION_REDIRECT_POLICY_NEVER                  = 0;
+  WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP = 1;
+  WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS                 = 2;
+
+  WINHTTP_OPTION_REDIRECT_POLICY_LAST      = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
+  WINHTTP_OPTION_REDIRECT_POLICY_DEFAULT   = WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP;
+
+  WINHTTP_DISABLE_PASSPORT_AUTH      = $00000000;
+  WINHTTP_ENABLE_PASSPORT_AUTH       = $10000000;
+  WINHTTP_DISABLE_PASSPORT_KEYRING   = $20000000;
+  WINHTTP_ENABLE_PASSPORT_KEYRING    = $40000000;
+
+  // values for WINHTTP_OPTION_DISABLE_FEATURE
+  WINHTTP_DISABLE_COOKIES            = $00000001;
+  WINHTTP_DISABLE_REDIRECTS          = $00000002;
+  WINHTTP_DISABLE_AUTHENTICATION     = $00000004;
+  WINHTTP_DISABLE_KEEP_ALIVE         = $00000008;
+
+  // values for WINHTTP_OPTION_ENABLE_FEATURE
+  WINHTTP_ENABLE_SSL_REVOCATION            = $00000001;
+  WINHTTP_ENABLE_SSL_REVERT_IMPERSONATION  = $00000002;
+
+  // values for WINHTTP_OPTION_SPN
+  WINHTTP_DISABLE_SPN_SERVER_PORT    = $00000000;
+  WINHTTP_ENABLE_SPN_SERVER_PORT     = $00000001;
+  WINHTTP_OPTION_SPN_MASK            = WINHTTP_ENABLE_SPN_SERVER_PORT;
+
+  // winhttp handle types
+  WINHTTP_HANDLE_TYPE_SESSION  = 1;
+  WINHTTP_HANDLE_TYPE_CONNECT  = 2;
+  WINHTTP_HANDLE_TYPE_REQUEST  = 3;
+
+  // values for auth schemes
+  WINHTTP_AUTH_SCHEME_BASIC      = $00000001;
+  WINHTTP_AUTH_SCHEME_NTLM       = $00000002;
+  WINHTTP_AUTH_SCHEME_PASSPORT   = $00000004;
+  WINHTTP_AUTH_SCHEME_DIGEST     = $00000008;
+  WINHTTP_AUTH_SCHEME_NEGOTIATE  = $00000010;
+
+  // WinHttp supported Authentication Targets
+  WINHTTP_AUTH_TARGET_SERVER     = $00000000;
+  WINHTTP_AUTH_TARGET_PROXY      = $00000001;
+
+  // values for WINHTTP_OPTION_SECURITY_FLAGS
+
+  // query only
+  SECURITY_FLAG_SECURE           = $00000001; // can query only
+  SECURITY_FLAG_STRENGTH_WEAK    = $10000000;
+  SECURITY_FLAG_STRENGTH_MEDIUM  = $40000000;
+  SECURITY_FLAG_STRENGTH_STRONG  = $20000000;
+
+  // Secure connection error status flags
+  WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED         = $00000001;
+  WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT            = $00000002;
+  WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED            = $00000004;
+  WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA              = $00000008;
+  WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID         = $00000010;
+  WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID       = $00000020;
+  WINHTTP_CALLBACK_STATUS_FLAG_CERT_WRONG_USAGE        = $00000040;
+  WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR  = $80000000;
+
+  WINHTTP_FLAG_SECURE_PROTOCOL_SSL2   = $00000008;
+  WINHTTP_FLAG_SECURE_PROTOCOL_SSL3   = $00000020;
+  WINHTTP_FLAG_SECURE_PROTOCOL_TLS1   = $00000080;
+  WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1 = $00000200;
+  WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2 = $00000800;
+
+  // Note: SECURE_PROTOCOL_ALL does not include TLS1.1 and higher!
+  WINHTTP_FLAG_SECURE_PROTOCOL_ALL    = WINHTTP_FLAG_SECURE_PROTOCOL_SSL2
+                                     or WINHTTP_FLAG_SECURE_PROTOCOL_SSL3
+                                     or WINHTTP_FLAG_SECURE_PROTOCOL_TLS1;
+
+
 const
   WINHTTP_ERROR_BASE                      = 12000;
   ERROR_WINHTTP_OUT_OF_HANDLES            = WINHTTP_ERROR_BASE + 1;
@@ -254,6 +415,7 @@
                          or WINHTTP_FLAG_ESCAPE_DISABLE;
 
 
+
 type
   IWinHTTPRequest = interface
     ['{35C6D9D4-FDCE-42C6-B84C-9294E6FB904C}']
@@ -274,10 +436,11 @@
   end;
 
   IWinHTTPSession = interface
-    ['{B6F8BD98-0605-4A9E-B671-4CB191D74A5E}']
+    ['{261ADCB7-5465-4407-8840-468C17F009F0}']
     function  Handle : HINTERNET;
     function  Connect( const aHostName : UnicodeString; const aPort : INTERNET_PORT = INTERNET_DEFAULT_PORT) : IWinHTTPConnection;
     function  SetTimeouts( const aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout : Int32) : Boolean;
+    function  EnableSecureProtocols( const aFlagSet : DWORD) : Boolean;
   end;
 
   IWinHTTPUrl = interface
@@ -339,7 +502,7 @@
     // IWinHTTPSession
     function  Connect( const aHostName : UnicodeString; const aPort : INTERNET_PORT = INTERNET_DEFAULT_PORT) : IWinHTTPConnection;
     function  SetTimeouts( const aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout : Int32) : Boolean;
-
+    function  EnableSecureProtocols( const aFlagSet : DWORD) : Boolean;
   public
     constructor Create( const aAgent : UnicodeString;
                         const aAccessType : DWORD          = WINHTTP_ACCESS_TYPE_DEFAULT_PROXY;
@@ -444,6 +607,8 @@
 function WinHttpOpenRequest; stdcall; external WINHTTP_DLL;
 function WinHttpSendRequest; stdcall; external WINHTTP_DLL;
 function WinHttpSetTimeouts; stdcall; external WINHTTP_DLL;
+function WinHttpQueryOption; stdcall; external WINHTTP_DLL;
+function WinHttpSetOption; stdcall; external WINHTTP_DLL;
 function WinHttpAddRequestHeaders; stdcall; external WINHTTP_DLL;
 function WinHttpWriteData; stdcall; external WINHTTP_DLL;
 function WinHttpReceiveResponse; stdcall; external WINHTTP_DLL;
@@ -521,6 +686,14 @@
 end;
 
 
+function TWinHTTPSessionImpl.EnableSecureProtocols( const aFlagSet : DWORD) : Boolean;
+var dwSize : DWORD;
+begin
+  dwSize := SizeOf(aFlagSet);
+  result := WinHttpSetOption( Handle, WINHTTP_OPTION_SECURE_PROTOCOLS, @aFlagset, dwSize);
+end;
+
+
 { TWinHTTPConnectionImpl }
 
 constructor TWinHTTPConnectionImpl.Create( const aSession : IWinHTTPSession; const aHostName : UnicodeString; const aPort : INTERNET_PORT);