Commit 2971e0a7ea2114e4f338af2b36fa6b7d71f1918b

Authored by Perry Werneck
1 parent 23df3f64

Splitting windows HTTP download method.

configure.ac
... ... @@ -80,7 +80,7 @@ case "$host" in
80 80 *-mingw32|*-pc-msys)
81 81 app_cv_osname="windows"
82 82 CFLAGS="$CFLAGS -pthread -D_WIN32_WINNT=0x0600"
83   - LIBS="$LIBS -lws2_32 -lwtsapi32 -lcomdlg32"
  83 + LIBS="$LIBS -lws2_32 -lwtsapi32 -lcomdlg32 -lwinhttp"
84 84 LDFLAGS="$LDFLAGS -pthread"
85 85 DLL_LDFLAGS="-shared -Wl,--output-def,\$(@D)/\$(LIBNAME).def"
86 86 DLLEXT=".dll"
... ...
lib3270.cbp
... ... @@ -218,6 +218,9 @@
218 218 <Unit filename="src/core/windows/event_dispatcher.c">
219 219 <Option compilerVar="CC" />
220 220 </Unit>
  221 + <Unit filename="src/core/windows/http.c">
  222 + <Option compilerVar="CC" />
  223 + </Unit>
221 224 <Unit filename="src/core/windows/log.c">
222 225 <Option compilerVar="CC" />
223 226 </Unit>
... ...
src/core/windows/http.c 0 → 100644
... ... @@ -0,0 +1,188 @@
  1 +/*
  2 + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
  3 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
  4 + * aplicativos mainframe. Registro no INPI sob o nome G3270.
  5 + *
  6 + * Copyright (C) <2008> <Banco do Brasil S.A.>
  7 + *
  8 + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
  9 + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
  10 + * Free Software Foundation.
  11 + *
  12 + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
  13 + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
  14 + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
  15 + * obter mais detalhes.
  16 + *
  17 + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
  18 + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
  19 + * St, Fifth Floor, Boston, MA 02110-1301 USA
  20 + *
  21 + * Este programa está nomeado como - e possui - linhas de código.
  22 + *
  23 + * Contatos:
  24 + *
  25 + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
  26 + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
  27 + *
  28 + * References:
  29 + *
  30 + * https://docs.microsoft.com/en-us/windows/win32/winhttp/winhttp-autoproxy-api
  31 + *
  32 + */
  33 +
  34 +/**
  35 + * @brief Implements CRL download using winhttp.
  36 + *
  37 + */
  38 +
  39 +#include <config.h>
  40 +#include <lib3270-internals.h>
  41 +#include <lib3270/log.h>
  42 +#include <lib3270/trace.h>
  43 +#include <winhttp.h>
  44 +#include <utilc.h>
  45 +
  46 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  47 +
  48 +static void lib3270_autoptr_cleanup_HINTERNET(HINTERNET **hInternet)
  49 +{
  50 + if(*hInternet)
  51 + WinHttpCloseHandle(*hInternet);
  52 + *hInternet = 0;
  53 +}
  54 +
  55 +char * lib3270_get_from_url(H3270 *hSession, const char *url, size_t *length, const char **error_message)
  56 +{
  57 + wchar_t wHostname[4096];
  58 + wchar_t wPath[4096];
  59 +
  60 + lib3270_trace_event(hSession,"Getting data from %s",url);
  61 +
  62 + {
  63 + // Strip URL
  64 + char * unescaped = lib3270_unescape(url);
  65 +
  66 + char *hostname = strstr(unescaped,"://");
  67 + if(!hostname)
  68 + hostname = unescaped;
  69 + else
  70 + hostname += 3;
  71 +
  72 + char *path = strchr(hostname,'/');
  73 + if(path)
  74 + *(path++) = 0;
  75 +
  76 + mbstowcs(wHostname, hostname, strlen(hostname)+1);
  77 + mbstowcs(wPath, path, strlen(path)+1);
  78 +
  79 + lib3270_free(unescaped);
  80 +
  81 + }
  82 +
  83 + // https://docs.microsoft.com/en-us/windows/desktop/api/winhttp/nf-winhttp-winhttpopenrequest
  84 +
  85 + // Open HTTP session
  86 + // https://docs.microsoft.com/en-us/windows/desktop/api/winhttp/nf-winhttp-winhttpopenrequest
  87 + static const char * userAgent = PACKAGE_NAME "/" PACKAGE_VERSION;
  88 + wchar_t wUserAgent[256];
  89 + mbstowcs(wUserAgent, userAgent, strlen(userAgent)+1);
  90 + lib3270_autoptr(HINTERNET) httpSession = WinHttpOpen(wUserAgent, WINHTTP_ACCESS_TYPE_NO_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0 );
  91 + if(!httpSession)
  92 + {
  93 + lib3270_autoptr(char) windows_error = lib3270_win32_translate_error_code(GetLastError());
  94 + lib3270_write_log(hSession,"http","%s: %s",url, windows_error);
  95 +
  96 + *error_message = _( "Can't open HTTP session" );
  97 + errno = EINVAL;
  98 + return NULL;
  99 + }
  100 +
  101 + // Connect to server
  102 + lib3270_autoptr(HINTERNET) hConnect = WinHttpConnect(httpSession, wHostname, INTERNET_DEFAULT_HTTP_PORT, 0);
  103 + if(!hConnect)
  104 + {
  105 + lib3270_autoptr(char) windows_error = lib3270_win32_translate_error_code(GetLastError());
  106 + lib3270_write_log(hSession,"http","%s: %s", url, windows_error);
  107 +
  108 + *error_message = _( "Can't connect to HTTP server." );
  109 +
  110 + return NULL;
  111 + }
  112 +
  113 + // Create request.
  114 + lib3270_autoptr(HINTERNET) hRequest = WinHttpOpenRequest(hConnect, L"GET", wPath, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_ESCAPE_PERCENT);
  115 + if(!hConnect)
  116 + {
  117 + lib3270_autoptr(char) windows_error = lib3270_win32_translate_error_code(GetLastError());
  118 + lib3270_write_log(hSession,"http","%s: %s", url, windows_error);
  119 +
  120 + *error_message = _( "Can't create HTTP request." );
  121 +
  122 + errno = EINVAL;
  123 + return NULL;
  124 + }
  125 +
  126 + WinHttpSetOption(hRequest, WINHTTP_OPTION_CLIENT_CERT_CONTEXT, WINHTTP_NO_CLIENT_CERT_CONTEXT, 0);
  127 +
  128 + // Send request.
  129 + if(!WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0))
  130 + {
  131 + lib3270_autoptr(char) windows_error = lib3270_win32_translate_error_code(GetLastError());
  132 + lib3270_write_log(hSession,"http","%s: %s", url, windows_error);
  133 +
  134 + *error_message = _( "Can't send HTTP request." );
  135 +
  136 + errno = EINVAL;
  137 + return NULL;
  138 + }
  139 +
  140 + // Get response
  141 + if(!WinHttpReceiveResponse(hRequest, NULL))
  142 + {
  143 + lib3270_autoptr(char) windows_error = lib3270_win32_translate_error_code(GetLastError());
  144 + lib3270_write_log(hSession,"http","%s: %s", url, windows_error);
  145 +
  146 + *error_message = _( "Error receiving HTTP response." );
  147 +
  148 + errno = EINVAL;
  149 + return NULL;
  150 +
  151 + }
  152 +
  153 + DWORD szResponse = 0;
  154 + if(!WinHttpQueryDataAvailable(hRequest, &szResponse))
  155 + {
  156 + lib3270_autoptr(char) windows_error = lib3270_win32_translate_error_code(GetLastError());
  157 + lib3270_write_log(hSession,"http","%s: %s", url, windows_error);
  158 +
  159 + *error_message = _( "Empty response from HTTP server." );
  160 +
  161 + errno = EINVAL;
  162 + return NULL;
  163 + }
  164 +
  165 + char * httpText = lib3270_malloc(szResponse+1);
  166 + memset(httpText,0,szResponse+1);
  167 +
  168 + debug("Data block: %p",httpText);
  169 + debug("Response before: %u", (unsigned int) szResponse);
  170 +
  171 + if(!WinHttpReadData(hRequest,httpText,szResponse,&szResponse)){
  172 + lib3270_autoptr(char) windows_error = lib3270_win32_translate_error_code(GetLastError());
  173 + lib3270_write_log(hSession,"http","%s: %s", url, windows_error);
  174 +
  175 + *error_message = _( "Can't read HTTP response size." );
  176 +
  177 + lib3270_free(httpText);
  178 +
  179 + errno = EINVAL;
  180 + return NULL;
  181 + }
  182 +
  183 + if(length)
  184 + *length = (size_t) szResponse;
  185 +
  186 + return httpText;
  187 +
  188 +}
... ...
src/include/lib3270-internals.h
... ... @@ -867,3 +867,13 @@ LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on);
867 867  
868 868 LIB3270_INTERNAL char * lib3270_get_user_name();
869 869  
  870 + /// @brief Query data from URL.
  871 + ///
  872 + /// @param hSession Handle of the TN3270 Session.
  873 + /// @param url The url to get.
  874 + /// @param length Pointer to the response lenght (can be NULL).
  875 + /// @param error_message Pointer to the error message.
  876 + ///
  877 + /// @return The data from URL (release it with lib3270_free) or NULL on error.
  878 + ///
  879 + LIB3270_INTERNAL char * lib3270_get_from_url(H3270 *hSession, const char *url, size_t *length, const char **error_message);
... ...
src/ssl/windows/http.c
... ... @@ -46,148 +46,23 @@
46 46  
47 47 /*--[ Implement ]------------------------------------------------------------------------------------*/
48 48  
49   -static void lib3270_autoptr_cleanup_HINTERNET(HINTERNET **hInternet)
50   -{
51   - if(*hInternet)
52   - WinHttpCloseHandle(*hInternet);
53   - *hInternet = 0;
54   -}
55   -
56 49 X509_CRL * get_crl_using_http(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *consturl)
57 50 {
58   - wchar_t wHostname[4096];
59   - wchar_t wPath[4096];
60   -
61   - {
62   - // Strip URL
63   - char * url = lib3270_unescape(consturl);
64   -
65   - char *hostname = strstr(url,"://");
66   - if(!hostname)
67   - hostname = url;
68   - else
69   - hostname += 3;
70   -
71   - char *path = strchr(hostname,'/');
72   - if(path)
73   - *(path++) = 0;
74   -
75   - mbstowcs(wHostname, hostname, strlen(hostname)+1);
76   - mbstowcs(wPath, path, strlen(path)+1);
77   -
78   - lib3270_free(url);
79   -
80   - }
81   -
82   - // https://docs.microsoft.com/en-us/windows/desktop/api/winhttp/nf-winhttp-winhttpopenrequest
83   -
84   - // Open HTTP session
85   - // https://docs.microsoft.com/en-us/windows/desktop/api/winhttp/nf-winhttp-winhttpopenrequest
86   - static const char * userAgent = PACKAGE_NAME "/" PACKAGE_VERSION;
87   - wchar_t wUserAgent[256];
88   - mbstowcs(wUserAgent, userAgent, strlen(userAgent)+1);
89   - lib3270_autoptr(HINTERNET) httpSession = WinHttpOpen(wUserAgent, WINHTTP_ACCESS_TYPE_NO_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0 );
90   - if(!httpSession)
91   - {
92   - lib3270_autoptr(char) windows_error = lib3270_win32_translate_error_code(GetLastError());
93   - lib3270_write_log(hSession,"ssl","%s: %s",consturl, windows_error);
94   -
95   - message->error = hSession->ssl.error = 0;
96   - message->title = _( "Security error" );
97   - message->text = _( "Can't open HTTP session" );
98   - debug("%s",message->text);
99   - errno = EINVAL;
100   - return NULL;
101   - }
102   -
103   - // Connect to server
104   - lib3270_autoptr(HINTERNET) hConnect = WinHttpConnect(httpSession, wHostname, INTERNET_DEFAULT_HTTP_PORT, 0);
105   - if(!hConnect)
106   - {
107   - lib3270_autoptr(char) windows_error = lib3270_win32_translate_error_code(GetLastError());
108   - lib3270_write_log(hSession,"ssl","%s: %s",consturl, windows_error);
109   -
110   - message->error = hSession->ssl.error = 0;
111   - message->title = _( "Security error" );
112   - message->text = _( "Can't connect to HTTP server." );
113   - debug("%s",message->text);
114   - errno = EINVAL;
115   - return NULL;
116   - }
117   -
118   - // Create request.
119   - lib3270_autoptr(HINTERNET) hRequest = WinHttpOpenRequest(hConnect, L"GET", wPath, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_ESCAPE_PERCENT);
120   - if(!hConnect)
121   - {
122   - message->error = hSession->ssl.error = 0;
123   - message->title = _( "Security error" );
124   - message->text = _( "Can't create HTTP request." );
125   - debug("%s",message->text);
126   - errno = EINVAL;
127   - return NULL;
128   - }
129   -
130   - WinHttpSetOption(hRequest, WINHTTP_OPTION_CLIENT_CERT_CONTEXT, WINHTTP_NO_CLIENT_CERT_CONTEXT, 0);
131   -
132   - // Send request.
133   - if(!WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0))
134   - {
135   - message->error = hSession->ssl.error = 0;
136   - message->title = _( "Security error" );
137   - message->text = _( "Can't send HTTP request." );
138   - debug("%s",message->text);
139   - errno = EINVAL;
140   - return NULL;
141   - }
142   -
143   - // Get response
144   - if(!WinHttpReceiveResponse(hRequest, NULL))
145   - {
146   - message->error = hSession->ssl.error = 0;
147   - message->title = _( "Security error" );
148   - message->text = _( "Can't receive HTTP response." );
149   - debug("%s",message->text);
150   - errno = EINVAL;
151   - return NULL;
152   - }
  51 + size_t szResponse = 0;
  52 + lib3270_autoptr(char) httpText = lib3270_get_from_url(hSession, consturl, &szResponse, &message->text);
153 53  
154   - DWORD szResponse = 0;
155   - if(!WinHttpQueryDataAvailable(hRequest, &szResponse))
  54 + if(!httpText)
156 55 {
157 56 message->error = hSession->ssl.error = 0;
158 57 message->title = _( "Security error" );
159   - message->text = _( "Empty response from HTTP server." );
160   - debug("%s",message->text);
161   - errno = EINVAL;
162   - return NULL;
163   - }
164   -
165   - lib3270_autoptr(char) httpText = lib3270_malloc(szResponse+1);
166   - memset(httpText,0,szResponse+1);
167   -
168   - debug("Data block: %p",httpText);
169   - debug("Response before: %u", (unsigned int) szResponse);
170   -
171   - if(!WinHttpReadData(hRequest,httpText,szResponse,&szResponse)){
172   - message->error = hSession->ssl.error = 0;
173   - message->title = _( "Security error" );
174   - message->text = _( "Can't read HTTP response." );
175   - debug("%s",message->text);
176   - errno = EINVAL;
177 58 return NULL;
178 59 }
179 60  
180   - debug("Response after: %u", (unsigned int) szResponse);
181   -
182   - //
183   - // Parse CRL
184   - //
185   - X509_CRL * x509_crl = NULL;
186   -
187 61 // Copy the pointer because d2i_X509_CRL changes the value!!!
188 62 const unsigned char *crl_data = (const unsigned char *) httpText;
189 63  
190   - if(!d2i_X509_CRL(&x509_crl,&crl_data, szResponse))
  64 + X509_CRL * x509_crl = NULL;
  65 + if(!d2i_X509_CRL(&x509_crl,&crl_data, (DWORD) szResponse))
191 66 {
192 67 message->error = hSession->ssl.error = ERR_get_error();
193 68 message->title = _( "Security error" );
... ... @@ -196,7 +71,6 @@ X509_CRL * get_crl_using_http(H3270 *hSession, SSL_ERROR_MESSAGE * message, cons
196 71 return NULL;
197 72 }
198 73  
199   - debug("**************URL:[%s]*********************",consturl);
200 74 return x509_crl;
201 75  
202 76 }
... ...