Commit 5edf578010d0a319a5362cc6743e228f7300d787

Authored by Perry Werneck
1 parent 265084d8

Still refactoring the CRL download methods.

lib3270.cbp
... ... @@ -301,6 +301,9 @@
301 301 <Unit filename="src/selection/selection.c">
302 302 <Option compilerVar="CC" />
303 303 </Unit>
  304 + <Unit filename="src/ssl/crl.c">
  305 + <Option compilerVar="CC" />
  306 + </Unit>
304 307 <Unit filename="src/ssl/linux/curl.c">
305 308 <Option compilerVar="CC" />
306 309 </Unit>
... ...
src/core/connect.c
... ... @@ -55,7 +55,6 @@
55 55  
56 56 }
57 57  
58   -#ifdef SSL_ENABLE_CRL_CHECK
59 58 static int background_ssl_crl_get(H3270 *hSession, void *ssl_error)
60 59 {
61 60 if(ssl_ctx_init(hSession, (SSL_ERROR_MESSAGE *) ssl_error)) {
... ... @@ -105,39 +104,11 @@ static int background_ssl_crl_get(H3270 *hSession, void *ssl_error)
105 104 //
106 105 // https://stackoverflow.com/questions/10510850/how-to-verify-the-certificate-for-the-ongoing-ssl-session
107 106 //
108   - trace_ssl(hSession,"Getting CRL from %s\n",lib3270_get_crl_url(hSession));
109   -
110   - hSession->ssl.crl.cert = lib3270_get_crl(hSession,(SSL_ERROR_MESSAGE *) ssl_error,lib3270_get_crl_url(hSession));
111   - if(hSession->ssl.crl.cert)
112   - {
113   - // Got CRL, add it to ssl store
114   - if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE))
115   - {
116   - lib3270_autoptr(char) text = lib3270_get_ssl_crl_text(hSession);
117   -
118   - if(text)
119   - trace_ssl(hSession,"\n%s\n",text);
120   -
121   - }
122   -
123   - // Add CRL in the store.
124   - X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx);
125   - if(X509_STORE_add_crl(store, hSession->ssl.crl.cert))
126   - {
127   - trace_ssl(hSession,"CRL was added to cert store\n");
128   - }
129   - else
130   - {
131   - trace_ssl(hSession,"CRL was not added to cert store\n");
132   - }
133   -
134   -
135   - }
136   -
137   - return 0;
  107 + return lib3270_get_crl_from_url(hSession, ssl_error, lib3270_get_crl_url(hSession));
138 108  
139 109 }
140 110  
  111 +#ifdef SSL_ENABLE_CRL_CHECK
141 112 static int notify_crl_error(H3270 *hSession, int rc, const SSL_ERROR_MESSAGE *message)
142 113 {
143 114 lib3270_write_log(
... ... @@ -181,7 +152,6 @@ static int notify_crl_error(H3270 *hSession, int rc, const SSL_ERROR_MESSAGE *me
181 152  
182 153 return 0;
183 154 }
184   -
185 155 #endif // SSL_ENABLE_CRL_CHECK
186 156  
187 157 int lib3270_reconnect(H3270 *hSession, int seconds)
... ...
src/core/properties/string.c
... ... @@ -136,6 +136,13 @@
136 136 },
137 137  
138 138 {
  139 + .name = "crlprefer", // Property name.
  140 + .description = N_( "Prefered protocol for CRL" ), // Property description.
  141 + .get = lib3270_get_crl_prefered_protocol, // Get value.
  142 + .set = lib3270_set_crl_prefered_protocol, // Set value.
  143 + },
  144 +
  145 + {
139 146 .name = "default_host", // Property name.
140 147 .description = N_( "Default host URL" ), // Property description.
141 148 .get = lib3270_get_default_host, // Get value.
... ...
src/core/session.c
... ... @@ -82,6 +82,12 @@ void lib3270_session_free(H3270 *h)
82 82 h->ssl.crl.url = NULL;
83 83 }
84 84  
  85 + if(h->ssl.crl.prefer)
  86 + {
  87 + free(h->ssl.crl.prefer);
  88 + h->ssl.crl.prefer = NULL;
  89 + }
  90 +
85 91 if(h->ssl.crl.cert)
86 92 {
87 93 X509_CRL_free(h->ssl.crl.cert);
... ...
src/include/lib3270-internals.h
... ... @@ -41,6 +41,8 @@
41 41  
42 42 #if defined(HAVE_LIBSSL)
43 43 #include <openssl/ssl.h>
  44 + #include <openssl/x509v3.h>
  45 +
44 46 #endif // HAVE_LIBSSL
45 47  
46 48 #if defined(X3270_TN3270E) && !defined(X3270_ANSI) /*[*/
... ... @@ -693,8 +695,9 @@ struct _h3270
693 695 #ifdef SSL_ENABLE_CRL_CHECK
694 696 struct
695 697 {
696   - char * url;
697   - X509_CRL * cert;
  698 + char * prefer; ///< @brief Prefered protocol for CRL.
  699 + char * url; ///< @brief URL for CRL download.
  700 + X509_CRL * cert; ///< @brief Loaded CRL (can be null).
698 701 } crl;
699 702 #endif // SSL_ENABLE_CRL_CHECK
700 703 SSL * con;
... ... @@ -848,6 +851,8 @@ LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on);
848 851  
849 852 #ifdef SSL_ENABLE_CRL_CHECK
850 853 LIB3270_INTERNAL X509_CRL * lib3270_get_crl(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *url);
  854 + LIB3270_INTERNAL int lib3270_get_crl_from_url(H3270 *hSession, void *ssl_error, const char *url);
  855 + LIB3270_INTERNAL int lib3270_get_crl_from_dist_points(H3270 *hSession, CRL_DIST_POINTS * dist_points, void *ssl_error);
851 856 #endif // SSL_ENABLE_CRL_CHECK
852 857  
853 858 #endif
... ... @@ -862,4 +867,3 @@ LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on);
862 867  
863 868 LIB3270_INTERNAL char * lib3270_get_user_name();
864 869  
865   -
... ...
src/include/lib3270.h
... ... @@ -490,9 +490,11 @@
490 490 *
491 491 */
492 492 LIB3270_EXPORT int lib3270_set_crl_url(H3270 *hSession, const char *crl);
493   -
494 493 LIB3270_EXPORT const char * lib3270_get_crl_url(const H3270 *hSession);
495 494  
  495 + LIB3270_EXPORT int lib3270_set_crl_prefered_protocol(H3270 *hSession, const char *protocol);
  496 + LIB3270_EXPORT const char * lib3270_get_crl_prefered_protocol(H3270 *hSession);
  497 +
496 498 /**
497 499 * @brief Get hostname for the connect/reconnect operations.
498 500 *
... ...
src/ssl/crl.c 0 → 100644
... ... @@ -0,0 +1,184 @@
  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 + */
  29 +
  30 +#include <config.h>
  31 +#include <lib3270.h>
  32 +#include <lib3270/log.h>
  33 +#include <trace_dsc.h>
  34 +#include <lib3270-internals.h>
  35 +#include <array.h>
  36 +
  37 +#ifdef HAVE_LIBSSL
  38 + #include <openssl/ssl.h>
  39 + #include <openssl/err.h>
  40 +#endif // HAVE_LIBSSL
  41 +
  42 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  43 +
  44 +#ifdef SSL_ENABLE_CRL_CHECK
  45 +int lib3270_get_crl_from_url(H3270 *hSession, void *ssl_error, const char *url)
  46 +{
  47 +
  48 + if(!(url && *url))
  49 + return -1;
  50 +
  51 + // Invalidate current certificate.
  52 + if(hSession->ssl.crl.cert)
  53 + {
  54 + trace_ssl(hSession,"%s\n","Discarding current CRL");
  55 + X509_CRL_free(hSession->ssl.crl.cert);
  56 + hSession->ssl.crl.cert = NULL;
  57 + }
  58 +
  59 + //
  60 + // Get the new CRL
  61 + //
  62 + // https://stackoverflow.com/questions/10510850/how-to-verify-the-certificate-for-the-ongoing-ssl-session
  63 + //
  64 + trace_ssl(hSession,"Getting new CRL from %s\n",url);
  65 +
  66 + hSession->ssl.crl.cert = lib3270_get_crl(hSession,(SSL_ERROR_MESSAGE *) ssl_error,url);
  67 +
  68 + if(hSession->ssl.crl.cert)
  69 + {
  70 + // Got CRL, add it to ssl store
  71 + if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE))
  72 + {
  73 + lib3270_autoptr(char) text = lib3270_get_ssl_crl_text(hSession);
  74 +
  75 + if(text)
  76 + trace_ssl(hSession,"\n%s\n",text);
  77 +
  78 + }
  79 +
  80 + // Add CRL in the store.
  81 + X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx);
  82 + if(X509_STORE_add_crl(store, hSession->ssl.crl.cert))
  83 + {
  84 + trace_ssl(hSession,"CRL was added to context cert store\n");
  85 + }
  86 + else
  87 + {
  88 + trace_ssl(hSession,"CRL was not added to context cert store\n");
  89 + }
  90 +
  91 + return 0;
  92 + }
  93 +
  94 + return -1;
  95 +
  96 +}
  97 +#endif // SSL_ENABLE_CRL_CHECK
  98 +
  99 +#if !defined(SSL_DEFAULT_CRL_URL) && defined(SSL_ENABLE_CRL_CHECK)
  100 +int lib3270_get_crl_from_dist_points(H3270 *hSession, CRL_DIST_POINTS * dist_points, void *ssl_error)
  101 +{
  102 + size_t ix;
  103 + int i, gtype;
  104 + lib3270_autoptr(LIB3270_STRING_ARRAY) uris = lib3270_string_array_new();
  105 +
  106 + // https://nougat.cablelabs.com/DLNA-RUI/openssl/commit/57912ed329f870b237f2fd9f2de8dec3477d1729
  107 +
  108 + for(ix = 0; ix < (size_t) sk_DIST_POINT_num(dist_points); ix++) {
  109 +
  110 + DIST_POINT *dp = sk_DIST_POINT_value(dist_points, ix);
  111 +
  112 + if(!dp->distpoint || dp->distpoint->type != 0)
  113 + continue;
  114 +
  115 + GENERAL_NAMES *gens = dp->distpoint->name.fullname;
  116 +
  117 + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++)
  118 + {
  119 + GENERAL_NAME *gen = sk_GENERAL_NAME_value(gens, i);
  120 + ASN1_STRING *uri = GENERAL_NAME_get0_value(gen, &gtype);
  121 + if(uri)
  122 + {
  123 + const unsigned char * data = ASN1_STRING_get0_data(uri);
  124 + if(data)
  125 + {
  126 + lib3270_string_array_append(uris,(char *) data);
  127 + }
  128 + }
  129 +
  130 + }
  131 +
  132 + }
  133 +
  134 +#ifdef DEBUG
  135 + {
  136 + for(ix = 0; ix < uris->length; ix++)
  137 + {
  138 + debug("%u: %s", (unsigned int) ix, uris->str[ix]);
  139 + }
  140 + }
  141 +#endif // DEBUG
  142 +
  143 + if(hSession->ssl.crl.url)
  144 + {
  145 + // Check if we already have the URL.
  146 + if(!strcmp(hSession->ssl.crl.url,uris->str[ix]))
  147 + {
  148 + trace_ssl(hSession,"Keeping CRL from %s\n",hSession->ssl.crl.url);
  149 + return 0;
  150 + }
  151 +
  152 + // The URL is invalid or not to this cert, remove it!
  153 + lib3270_free(hSession->ssl.crl.url);
  154 + hSession->ssl.crl.url = NULL;
  155 + }
  156 +
  157 + if(hSession->ssl.crl.prefer && *hSession->ssl.crl.prefer)
  158 + {
  159 + size_t length = strlen(hSession->ssl.crl.prefer);
  160 +
  161 + for(ix = 0; ix < uris->length; ix++)
  162 + {
  163 + if(!strncmp(uris->str[ix],hSession->ssl.crl.prefer,length))
  164 + {
  165 + trace_ssl(hSession,"Trying preferred URL %s\n",uris->str[ix]);
  166 + if(lib3270_get_crl_from_url(hSession, ssl_error, uris->str[ix]) == 0)
  167 + return 0;
  168 + }
  169 +
  170 + }
  171 +
  172 + }
  173 +
  174 + // Can't load, try all of them.
  175 + for(ix = 0; ix < uris->length; ix++)
  176 + {
  177 + trace_ssl(hSession,"Trying CRL from %s\n",uris->str[ix]);
  178 + if(lib3270_get_crl_from_url(hSession, ssl_error, uris->str[ix]) == 0)
  179 + return 0;
  180 + }
  181 +
  182 + return -1;
  183 +}
  184 +#endif // !SSL_DEFAULT_CRL_URL && SSL_ENABLE_CRL_CHECK
... ...
src/ssl/linux/getcrl.c
... ... @@ -59,8 +59,6 @@ LIB3270_INTERNAL X509_CRL * lib3270_get_crl(H3270 *hSession, SSL_ERROR_MESSAGE *
59 59 return NULL;
60 60 }
61 61  
62   - trace_ssl(hSession, "Getting CRL from \"%s\"\n",consturl);
63   -
64 62 if(strncasecmp(consturl,"file://",7) == 0)
65 63 {
66 64 lib3270_autoptr(FILE) hCRL = fopen(consturl+7,"r");
... ...
src/ssl/linux/ldap.c
... ... @@ -88,7 +88,7 @@ LIB3270_INTERNAL X509_CRL * get_crl_using_ldap(H3270 *hSession, SSL_ERROR_MESSAG
88 88 X509_CRL * x509_crl = NULL;
89 89  
90 90 int rc;
91   - lib3270_autoptr(char) url = strdup(consturl);
  91 + lib3270_autoptr(char) url = lib3270_unescape(consturl);
92 92 char * base = strchr(url+7,'/');
93 93 char * attrs[] = { NULL, NULL };
94 94  
... ...
src/ssl/negotiate.c
... ... @@ -134,67 +134,27 @@ static int background_ssl_init(H3270 *hSession, void *message)
134 134 }
135 135  
136 136 #if !defined(SSL_DEFAULT_CRL_URL) && defined(SSL_ENABLE_CRL_CHECK)
137   -
138   -static int getCRLFromDistPoints(H3270 *hSession, CRL_DIST_POINTS * dist_points, SSL_ERROR_MESSAGE *message)
  137 +int x509_store_ctx_error_callback(int ok, X509_STORE_CTX *ctx)
139 138 {
140   - int ix, i, gtype;
141   - lib3270_autoptr(LIB3270_STRING_ARRAY) uris = lib3270_string_array_new();
142   -
143   - // https://nougat.cablelabs.com/DLNA-RUI/openssl/commit/57912ed329f870b237f2fd9f2de8dec3477d1729
144   -
145   - for(ix = 0; ix < sk_DIST_POINT_num(dist_points); ix++) {
146   -
147   - DIST_POINT *dp = sk_DIST_POINT_value(dist_points, ix);
148   -
149   - if(!dp->distpoint || dp->distpoint->type != 0)
150   - continue;
151   -
152   - GENERAL_NAMES *gens = dp->distpoint->name.fullname;
  139 + debug("%s(%d)",__FUNCTION__,ok);
153 140  
154   - for (i = 0; i < sk_GENERAL_NAME_num(gens); i++)
155   - {
156   - GENERAL_NAME *gen = sk_GENERAL_NAME_value(gens, i);
157   - ASN1_STRING *uri = GENERAL_NAME_get0_value(gen, &gtype);
158   - if(uri)
159   - {
160   - const unsigned char * data = ASN1_STRING_get0_data(uri);
161   - if(data)
162   - {
163   - lib3270_string_array_append(uris,(char *) data);
164   - }
165   - }
166   -
167   - }
168   -
169   - }
170   -
171   -#ifdef DEBUG
172   - {
173   - for(ix = 0; ix < uris->length; ix++)
174   - {
175   - debug("%u: %s", (unsigned int) ix, uris->str[ix]);
176   - }
177   - }
178   -#endif // DEBUG
179   -
180   - /*
181   - if(hSession->ssl.crl.url)
182   - {
183   - // Check if we already have the URL.
184   -
185   -
186   - // The URL is invalid or not to this cert, remove it!
187   - lib3270_free(hSession->ssl.crl.url);
188   - hSession->ssl.crl.url = NULL;
189   - }
190   - */
191   -
192   -
193   - return 0;
  141 +/*
  142 + 55 {
  143 + 56 if (!ok) {
  144 + 57 Category::getInstance("OpenSSL").error(
  145 + 58 "path validation failure at depth(%d): %s",
  146 + 59 X509_STORE_CTX_get_error_depth(ctx),
  147 + 60 X509_verify_cert_error_string(X509_STORE_CTX_get_error(ctx))
  148 + 61 );
  149 + 62 }
  150 + 63 return ok;
  151 + 64 }
  152 +*/
  153 + return ok;
194 154 }
195   -
196 155 #endif // !SSL_DEFAULT_CRL_URL && SSL_ENABLE_CRL_CHECK
197 156  
  157 +
198 158 static int background_ssl_negotiation(H3270 *hSession, void *message)
199 159 {
200 160 int rv;
... ... @@ -225,7 +185,7 @@ static int background_ssl_negotiation(H3270 *hSession, void *message)
225 185  
226 186 if (rv != 1)
227 187 {
228   - const char * msg = "";
  188 + const char * msg = "";
229 189  
230 190 ((SSL_ERROR_MESSAGE *) message)->error = SSL_get_error(hSession->ssl.con,rv);
231 191 if(((SSL_ERROR_MESSAGE *) message)->error == SSL_ERROR_SYSCALL && hSession->ssl.error)
... ... @@ -292,16 +252,38 @@ static int background_ssl_negotiation(H3270 *hSession, void *message)
292 252 return EACCES;
293 253 }
294 254  
295   - if(getCRLFromDistPoints(hSession, dist_points, (SSL_ERROR_MESSAGE *) message))
  255 + if(lib3270_get_crl_from_dist_points(hSession, dist_points, (SSL_ERROR_MESSAGE *) message))
296 256 return EACCES;
297 257  
  258 + // Got CRL, verify it!
  259 + // Reference: https://stackoverflow.com/questions/10510850/how-to-verify-the-certificate-for-the-ongoing-ssl-session
  260 + X509_STORE_CTX *csc = X509_STORE_CTX_new();
  261 +
  262 + X509_STORE_CTX_set_verify_cb(csc,x509_store_ctx_error_callback);
  263 +
  264 + X509_STORE_CTX_init(csc, SSL_CTX_get_cert_store(ssl_ctx), peer, NULL);
  265 +
  266 + if(X509_verify_cert(csc) != 1)
  267 + rv = X509_STORE_CTX_get_error(csc);
  268 + else
  269 + rv = X509_V_OK;
  270 +
  271 + X509_STORE_CTX_free(csc);
  272 +
  273 +#else
  274 + // No CRL download, use the standard verification.
  275 + rv = SSL_get_verify_result(hSession->ssl.con);
  276 +
298 277 #endif // !SSL_DEFAULT_CRL_URL && SSL_ENABLE_CRL_CHECK
299 278  
300 279 }
  280 + else
  281 + {
  282 + rv = SSL_get_verify_result(hSession->ssl.con);
  283 + }
301 284  
302 285  
303 286 // Validate certificate.
304   - rv = SSL_get_verify_result(hSession->ssl.con);
305 287  
306 288 debug("SSL Verify result was %d", rv);
307 289 const struct ssl_status_msg * msg = ssl_get_status_from_error_code((long) rv);
... ...
src/ssl/properties.c
... ... @@ -174,3 +174,52 @@ LIB3270_EXPORT char * lib3270_get_ssl_peer_certificate_text(const H3270 *hSessio
174 174 }
175 175 #pragma GCC diagnostic pop
176 176  
  177 + #pragma GCC diagnostic push
  178 + #pragma GCC diagnostic ignored "-Wunused-parameter"
  179 + const char * lib3270_get_crl_prefered_protocol(H3270 *hSession)
  180 + {
  181 +#ifdef SSL_ENABLE_CRL_CHECK
  182 + if(hSession->ssl.crl.prefer)
  183 + return hSession->ssl.crl.prefer;
  184 +#endif
  185 + errno = ENODATA;
  186 + return "";
  187 + }
  188 + #pragma GCC diagnostic pop
  189 +
  190 + #pragma GCC diagnostic push
  191 + #pragma GCC diagnostic ignored "-Wunused-parameter"
  192 + int lib3270_set_crl_prefered_protocol(H3270 *hSession, const char *protocol)
  193 + {
  194 +
  195 + FAIL_IF_ONLINE(hSession);
  196 +
  197 +#ifdef SSL_ENABLE_CRL_CHECK
  198 +
  199 + if(hSession->ssl.crl.prefer)
  200 + {
  201 + free(hSession->ssl.crl.prefer);
  202 + hSession->ssl.crl.prefer = NULL;
  203 + }
  204 +
  205 + if(hSession->ssl.crl.prefer)
  206 + {
  207 + X509_CRL_free(hSession->ssl.crl.prefer);
  208 + hSession->ssl.crl.prefer = NULL;
  209 + }
  210 +
  211 + if(protocol)
  212 + {
  213 + hSession->ssl.crl.prefer = strdup(protocol);
  214 + }
  215 +
  216 + return 0;
  217 +
  218 +#else
  219 +
  220 + return errno = ENOTSUP;
  221 +
  222 +#endif // SSL_ENABLE_CRL_CHECK
  223 +
  224 + }
  225 + #pragma GCC diagnostic pop
... ...
src/ssl/windows/getcrl.c
... ... @@ -65,8 +65,6 @@ LIB3270_INTERNAL X509_CRL * lib3270_get_crl(H3270 *hSession, SSL_ERROR_MESSAGE *
65 65 return NULL;
66 66 }
67 67  
68   - trace_ssl(hSession, "Getting CRL from \"%s\"\n",consturl);
69   -
70 68 if(strncasecmp(consturl,"file://",7) == 0)
71 69 {
72 70 lib3270_autoptr(FILE) hCRL = fopen(consturl+7,"r");
... ...
src/testprogram/testprogram.c
... ... @@ -43,6 +43,7 @@ int main(int argc, char *argv[])
43 43  
44 44 printf("3270 session %p created\n]",h);
45 45  
  46 + lib3270_set_crl_prefered_protocol(h,"ldap");
46 47 lib3270_set_url(h,NULL);
47 48  
48 49 int long_index =0;
... ...