Commit b407b35c7352e5c95e66b0f1acb8b3c2a8419391

Authored by Perry Werneck
1 parent dfd84b63

Adding CRL download using winhttp api.

configure.ac
... ... @@ -447,16 +447,29 @@ AC_ARG_WITH([libname], [AS_HELP_STRING([--with-libname], [Setup library name])],
447 447 AC_DEFINE_UNQUOTED(LIB3270_NAME,$app_cv_libname)
448 448 AC_SUBST(LIB3270_NAME,$app_cv_libname)
449 449  
  450 +dnl ---------------------------------------------------------------------------
  451 +dnl OS Defs
  452 +dnl ---------------------------------------------------------------------------
  453 +
450 454 case "$host" in
451 455 *-mingw32|*-pc-msys)
  456 +
452 457 AC_SUBST(SONAME,lib$app_cv_libname.dll)
  458 +
  459 + if test "$app_cv_enable_crl_check" == "yes"; then
  460 + LIBS="$LIBS -lwinhttp"
  461 + fi
  462 +
453 463 ;;
454 464  
455 465 s390x-*)
  466 +
456 467 AC_SUBST(SONAME,lib$app_cv_libname.so)
  468 +
457 469 ;;
458 470  
459 471 *)
  472 +
460 473 AC_SUBST(SONAME,lib$app_cv_libname.so.$app_vrs_major.$app_vrs_minor)
461 474  
462 475 esac
... ...
lib3270.cbp
... ... @@ -337,6 +337,9 @@
337 337 <Unit filename="src/ssl/windows/getcrl.c">
338 338 <Option compilerVar="CC" />
339 339 </Unit>
  340 + <Unit filename="src/ssl/windows/http.c">
  341 + <Option compilerVar="CC" />
  342 + </Unit>
340 343 <Unit filename="src/ssl/windows/init.c">
341 344 <Option compilerVar="CC" />
342 345 </Unit>
... ...
src/ssl/windows/getcrl.c
... ... @@ -99,6 +99,10 @@ X509_CRL * lib3270_download_crl(H3270 *hSession, SSL_ERROR_MESSAGE * message, co
99 99  
100 100 }
101 101 #endif // HAVE_LDAP
  102 + else if(strncasecmp(consturl,"http://",7) == 0 && strlen(consturl) > 8)
  103 + {
  104 + return get_crl_using_http(hSession, message, consturl);
  105 + }
102 106 else
103 107 {
104 108 #ifdef HAVE_LIBCURL
... ...
src/ssl/windows/http.c 0 → 100644
... ... @@ -0,0 +1,192 @@
  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 "private.h"
  41 +
  42 +#if defined(HAVE_LIBSSL) && defined(SSL_ENABLE_CRL_CHECK)
  43 +
  44 +#include <winhttp.h>
  45 +#include <utilc.h>
  46 +
  47 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  48 +
  49 +static void lib3270_autoptr_cleanup_HINTERNET(HINTERNET **hInternet)
  50 +{
  51 + if(*hInternet)
  52 + WinHttpCloseHandle(*hInternet);
  53 + *hInternet = 0;
  54 +}
  55 +
  56 +X509_CRL * get_crl_using_http(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *consturl)
  57 +{
  58 + // Strip URL.
  59 + lib3270_autoptr(char) urldup = lib3270_unescape(consturl);
  60 +
  61 + char *hostname = strstr(urldup,"://");
  62 + if(!hostname)
  63 + hostname = urldup;
  64 + else
  65 + hostname += 3;
  66 +
  67 + char *path = strchr(hostname,'/');
  68 + if(path)
  69 + *(path++) = 0;
  70 +
  71 + // https://docs.microsoft.com/en-us/windows/desktop/api/winhttp/nf-winhttp-winhttpopenrequest
  72 +
  73 + // Open HTTP session
  74 + // https://docs.microsoft.com/en-us/windows/desktop/api/winhttp/nf-winhttp-winhttpopenrequest
  75 + static const char * userAgent = PACKAGE_NAME "/" PACKAGE_VERSION;
  76 + wchar_t wUserAgent[256];
  77 + mbstowcs(wUserAgent, userAgent, strlen(userAgent)+1);
  78 + lib3270_autoptr(HINTERNET) httpSession = WinHttpOpen(wUserAgent, WINHTTP_ACCESS_TYPE_NO_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0 );
  79 + if(!httpSession)
  80 + {
  81 + lib3270_autoptr(char) windows_error = lib3270_win32_translate_error_code(GetLastError());
  82 + lib3270_write_log(hSession,"ssl","%s: %s",consturl, windows_error);
  83 +
  84 + message->error = hSession->ssl.error = 0;
  85 + message->title = _( "Security error" );
  86 + message->text = _( "Can't open HTTP session" );
  87 + debug("%s",message->text);
  88 + errno = EINVAL;
  89 + return NULL;
  90 + }
  91 +
  92 + // Connect to server
  93 + debug("Hostname: \"%s\"",hostname);
  94 + wchar_t wHostname[4096];
  95 + mbstowcs(wHostname, hostname, strlen(hostname)+1);
  96 + lib3270_autoptr(HINTERNET) hConnect = WinHttpConnect(httpSession, wHostname, INTERNET_DEFAULT_HTTP_PORT, 0);
  97 + if(!hConnect)
  98 + {
  99 + lib3270_autoptr(char) windows_error = lib3270_win32_translate_error_code(GetLastError());
  100 + lib3270_write_log(hSession,"ssl","%s: %s",consturl, windows_error);
  101 +
  102 + message->error = hSession->ssl.error = 0;
  103 + message->title = _( "Security error" );
  104 + message->text = _( "Can't connect to HTTP server." );
  105 + debug("%s",message->text);
  106 + errno = EINVAL;
  107 + return NULL;
  108 + }
  109 +
  110 + // Create request.
  111 + debug("Path: \"%s\"",path);
  112 + wchar_t wPath[4096];
  113 + mbstowcs(wPath, path, strlen(path)+1);
  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 + message->error = hSession->ssl.error = 0;
  118 + message->title = _( "Security error" );
  119 + message->text = _( "Can't create HTTP request." );
  120 + debug("%s",message->text);
  121 + errno = EINVAL;
  122 + return NULL;
  123 + }
  124 +
  125 + WinHttpSetOption(hRequest, WINHTTP_OPTION_CLIENT_CERT_CONTEXT, WINHTTP_NO_CLIENT_CERT_CONTEXT, 0);
  126 +
  127 + // Send request.
  128 + if(!WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0))
  129 + {
  130 + message->error = hSession->ssl.error = 0;
  131 + message->title = _( "Security error" );
  132 + message->text = _( "Can't send HTTP request." );
  133 + debug("%s",message->text);
  134 + errno = EINVAL;
  135 + return NULL;
  136 + }
  137 +
  138 + // Get response
  139 + if(!WinHttpReceiveResponse(hRequest, NULL))
  140 + {
  141 + message->error = hSession->ssl.error = 0;
  142 + message->title = _( "Security error" );
  143 + message->text = _( "Can't receive HTTP response." );
  144 + debug("%s",message->text);
  145 + errno = EINVAL;
  146 + return NULL;
  147 + }
  148 +
  149 + DWORD szResponse = 0;
  150 + if(!WinHttpQueryDataAvailable(hRequest, &szResponse))
  151 + {
  152 + message->error = hSession->ssl.error = 0;
  153 + message->title = _( "Security error" );
  154 + message->text = _( "Empty response from HTTP server." );
  155 + debug("%s",message->text);
  156 + errno = EINVAL;
  157 + return NULL;
  158 + }
  159 +
  160 + lib3270_autoptr(char) httpText = lib3270_malloc(szResponse+1);
  161 + memset(httpText,0,szResponse+1);
  162 +
  163 + debug("Response length: %u", (unsigned int) szResponse);
  164 +
  165 + if(!WinHttpReadData(hRequest,httpText,szResponse,&szResponse)){
  166 + message->error = hSession->ssl.error = 0;
  167 + message->title = _( "Security error" );
  168 + message->text = _( "Can't read HTTP response." );
  169 + debug("%s",message->text);
  170 + errno = EINVAL;
  171 + return NULL;
  172 + }
  173 +
  174 + //
  175 + // Parse CRL
  176 + //
  177 + X509_CRL * x509_crl = NULL;
  178 +
  179 + if(!d2i_X509_CRL(&x509_crl, (const unsigned char **) &httpText, szResponse))
  180 + {
  181 + message->error = hSession->ssl.error = ERR_get_error();
  182 + message->title = _( "Security error" );
  183 + message->text = _( "Can't decode certificate revocation list" );
  184 + lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->text);
  185 + return NULL;
  186 + }
  187 +
  188 + return x509_crl;
  189 +
  190 +}
  191 +
  192 +#endif // defined(HAVE_LIBSSL) && defined(SSL_ENABLE_CRL_CHECK)
... ...
src/ssl/windows/private.h
... ... @@ -64,4 +64,8 @@
64 64  
65 65 #endif // HAVE_LDAP
66 66  
  67 + /// @brief Use winhttp to get CRL.
  68 + LIB3270_INTERNAL X509_CRL * get_crl_using_http(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *consturl);
  69 +
  70 +
67 71 #endif // !LIB3270_WIN32_SSL_PRIVATE_H_INCLUDED
... ...
src/testprogram/testprogram.c
... ... @@ -43,7 +43,10 @@ int main(int argc, char *argv[])
43 43  
44 44 printf("3270 session %p created\n]",h);
45 45  
  46 +#ifdef HAVE_LDAP
46 47 lib3270_set_crl_prefered_protocol(h,"ldap");
  48 +#endif // HAVE_LDAP
  49 +
47 50 lib3270_set_url(h,NULL);
48 51  
49 52 int long_index =0;
... ...