Commit 2d1bf4c85b5dba50677cc6c4f8b855822577bb15

Authored by Perry Werneck
1 parent 3b32273a

Refactoring network and TLS/SSL engine to a modular way.

@@ -128,12 +128,16 @@ @@ -128,12 +128,16 @@
128 <Unit filename="src/core/linux/curl.c"> 128 <Unit filename="src/core/linux/curl.c">
129 <Option compilerVar="CC" /> 129 <Option compilerVar="CC" />
130 </Unit> 130 </Unit>
  131 + <Unit filename="src/core/linux/download.c">
  132 + <Option compilerVar="CC" />
  133 + </Unit>
131 <Unit filename="src/core/linux/event_dispatcher.c"> 134 <Unit filename="src/core/linux/event_dispatcher.c">
132 <Option compilerVar="CC" /> 135 <Option compilerVar="CC" />
133 </Unit> 136 </Unit>
134 <Unit filename="src/core/linux/log.c"> 137 <Unit filename="src/core/linux/log.c">
135 <Option compilerVar="CC" /> 138 <Option compilerVar="CC" />
136 </Unit> 139 </Unit>
  140 + <Unit filename="src/core/linux/private.h" />
137 <Unit filename="src/core/linux/util.c"> 141 <Unit filename="src/core/linux/util.c">
138 <Option compilerVar="CC" /> 142 <Option compilerVar="CC" />
139 </Unit> 143 </Unit>
@@ -320,11 +324,11 @@ @@ -320,11 +324,11 @@
320 <Unit filename="src/network_modules/openssl/main.c"> 324 <Unit filename="src/network_modules/openssl/main.c">
321 <Option compilerVar="CC" /> 325 <Option compilerVar="CC" />
322 </Unit> 326 </Unit>
323 - <Unit filename="src/network_modules/openssl/private.h" />  
324 - <Unit filename="src/network_modules/openssl/start.c"> 327 + <Unit filename="src/network_modules/openssl/messages.c">
325 <Option compilerVar="CC" /> 328 <Option compilerVar="CC" />
326 </Unit> 329 </Unit>
327 - <Unit filename="src/network_modules/openssl/states.c"> 330 + <Unit filename="src/network_modules/openssl/private.h" />
  331 + <Unit filename="src/network_modules/openssl/start.c">
328 <Option compilerVar="CC" /> 332 <Option compilerVar="CC" />
329 </Unit> 333 </Unit>
330 <Unit filename="src/network_modules/select.c"> 334 <Unit filename="src/network_modules/select.c">
src/core/connect.c
@@ -138,31 +138,72 @@ @@ -138,31 +138,72 @@
138 138
139 int lib3270_start_tls(H3270 *hSession) 139 int lib3270_start_tls(H3270 *hSession)
140 { 140 {
141 - int rc = 0;  
142 -  
143 - LIB3270_NETWORK_STATE state;  
144 - memset(&state,0,sizeof(state)); 141 + hSession->ssl.message = NULL; // Reset message.
  142 + set_ssl_state(hSession,LIB3270_SSL_NEGOTIATING);
145 143
146 non_blocking(hSession,False); 144 non_blocking(hSession,False);
147 145
148 - rc = lib3270_run_task( 146 + int rc = lib3270_run_task(
149 hSession, 147 hSession,
150 (int(*)(H3270 *h, void *)) hSession->network.module->start_tls, 148 (int(*)(H3270 *h, void *)) hSession->network.module->start_tls,
151 - &state 149 + NULL
152 ); 150 );
153 151
154 non_blocking(hSession,True); 152 non_blocking(hSession,True);
155 153
156 - if(hSession->ssl.host && rc) { 154 + if(rc == ENOTSUP) {
157 155
158 - // SSL is required and TLS/SSL has failed, abort.  
159 - lib3270_popup(hSession,(const LIB3270_POPUP *) state.popup,0);  
160 - lib3270_disconnect(hSession);  
161 - return rc; 156 + // No support for TLS/SSL in the active network module, the connection is insecure
  157 + set_ssl_state(hSession,LIB3270_SSL_UNSECURE);
  158 + return 0;
  159 +
  160 + }
  161 +
  162 + // The network module SHOULD set the status message.
  163 + if(!hSession->ssl.message) {
  164 +
  165 + static const LIB3270_POPUP message = {
  166 + .type = LIB3270_NOTIFY_CRITICAL,
  167 + .summary = N_( "Can't determine the TLS/SSL estate"),
  168 + .body = N_("The network module didn't set the TLS/SSL state message, this is not supposed to happen and can be a coding error")
  169 + };
  170 +
  171 + set_ssl_state(hSession,LIB3270_SSL_UNSECURE);
  172 + lib3270_popup_translated(hSession,&message,0);
  173 + return EINVAL;
  174 +
  175 + }
162 176
  177 + if(rc) {
  178 +
  179 + // Negotiation has failed. Will disconnect
  180 + set_ssl_state(hSession,LIB3270_SSL_UNSECURE);
  181 +
  182 + if(hSession->ssl.message) {
  183 + lib3270_popup_translated(hSession,(const LIB3270_POPUP *) hSession->ssl.message,0);
  184 + }
  185 +
  186 + return rc;
163 } 187 }
164 188
165 - // Not required or success 189 + // Negotiation complete is the connection secure?
  190 + if(hSession->ssl.message->type == LIB3270_NOTIFY_INFO) {
  191 +
  192 + // Yes! The message was only informational.
  193 + set_ssl_state(hSession,LIB3270_SSL_SECURE);
  194 +
  195 + } else {
  196 +
  197 + // No! The negotiation completed with a warning or error.
  198 + set_ssl_state(hSession,LIB3270_SSL_NEGOTIATED);
  199 +
  200 + // Ask user what I can do!
  201 + if(lib3270_popup_translated(hSession,(const LIB3270_POPUP *) hSession->ssl.message,1) == ECANCELED) {
  202 + lib3270_disconnect(hSession);
  203 + return ECANCELED;
  204 + }
  205 +
  206 + }
166 207
167 return 0; 208 return 0;
168 } 209 }
src/core/linux/curl.c
@@ -163,23 +163,22 @@ static int internal_curl_trace_callback(CURL GNUC_UNUSED(*handle), curl_infotype @@ -163,23 +163,22 @@ static int internal_curl_trace_callback(CURL GNUC_UNUSED(*handle), curl_infotype
163 return 0; 163 return 0;
164 } 164 }
165 165
166 -char * lib3270_get_from_url(H3270 *hSession, const char *url, size_t *length, const char **error_message) 166 +char * lib3270_url_get_using_curl(H3270 *hSession, const char *url, const char **error)
167 { 167 {
168 lib3270_write_event_trace(hSession,"Getting data from %s",url); 168 lib3270_write_event_trace(hSession,"Getting data from %s",url);
169 169
170 // Use CURL to download the CRL 170 // Use CURL to download the CRL
171 - lib3270_autoptr(CURLDATA) crl_data = lib3270_malloc(sizeof(CURLDATA)); 171 + lib3270_autoptr(CURLDATA) curl_data = lib3270_malloc(sizeof(CURLDATA));
172 lib3270_autoptr(CURL) hCurl = curl_easy_init(); 172 lib3270_autoptr(CURL) hCurl = curl_easy_init();
173 173
174 - memset(crl_data,0,sizeof(CURLDATA));  
175 - crl_data->hSession = hSession;  
176 - crl_data->data.length = CRL_DATA_LENGTH;  
177 - crl_data->data.contents = lib3270_malloc(crl_data->data.length); 174 + memset(curl_data,0,sizeof(CURLDATA));
  175 + curl_data->hSession = hSession;
  176 + curl_data->data.length = CRL_DATA_LENGTH;
  177 + curl_data->data.contents = lib3270_malloc(curl_data->data.length);
178 178
179 if(!hCurl) 179 if(!hCurl)
180 { 180 {
181 - *error_message= _( "Can't initialize curl operation" );  
182 - errno = EINVAL; 181 + *error = _( "Can't initialize curl operation" );
183 return NULL; 182 return NULL;
184 } 183 }
185 184
@@ -188,10 +187,10 @@ char * lib3270_get_from_url(H3270 *hSession, const char *url, size_t *length, co @@ -188,10 +187,10 @@ char * lib3270_get_from_url(H3270 *hSession, const char *url, size_t *length, co
188 curl_easy_setopt(hCurl, CURLOPT_URL, url); 187 curl_easy_setopt(hCurl, CURLOPT_URL, url);
189 curl_easy_setopt(hCurl, CURLOPT_FOLLOWLOCATION, 1L); 188 curl_easy_setopt(hCurl, CURLOPT_FOLLOWLOCATION, 1L);
190 189
191 - curl_easy_setopt(hCurl, CURLOPT_ERRORBUFFER, crl_data->errbuf); 190 + curl_easy_setopt(hCurl, CURLOPT_ERRORBUFFER, curl_data->errbuf);
192 191
193 curl_easy_setopt(hCurl, CURLOPT_WRITEFUNCTION, internal_curl_write_callback); 192 curl_easy_setopt(hCurl, CURLOPT_WRITEFUNCTION, internal_curl_write_callback);
194 - curl_easy_setopt(hCurl, CURLOPT_WRITEDATA, (void *) crl_data); 193 + curl_easy_setopt(hCurl, CURLOPT_WRITEDATA, (void *) curl_data);
195 194
196 curl_easy_setopt(hCurl, CURLOPT_USERNAME, ""); 195 curl_easy_setopt(hCurl, CURLOPT_USERNAME, "");
197 196
@@ -199,30 +198,27 @@ char * lib3270_get_from_url(H3270 *hSession, const char *url, size_t *length, co @@ -199,30 +198,27 @@ char * lib3270_get_from_url(H3270 *hSession, const char *url, size_t *length, co
199 { 198 {
200 curl_easy_setopt(hCurl, CURLOPT_VERBOSE, 1L); 199 curl_easy_setopt(hCurl, CURLOPT_VERBOSE, 1L);
201 curl_easy_setopt(hCurl, CURLOPT_DEBUGFUNCTION, internal_curl_trace_callback); 200 curl_easy_setopt(hCurl, CURLOPT_DEBUGFUNCTION, internal_curl_trace_callback);
202 - curl_easy_setopt(hCurl, CURLOPT_DEBUGDATA, (void *) crl_data); 201 + curl_easy_setopt(hCurl, CURLOPT_DEBUGDATA, (void *) curl_data);
203 } 202 }
204 203
205 res = curl_easy_perform(hCurl); 204 res = curl_easy_perform(hCurl);
206 205
207 if(res != CURLE_OK) 206 if(res != CURLE_OK)
208 { 207 {
209 - if(crl_data->errbuf[0])  
210 - lib3270_write_log(hSession,"curl","%s: %s",url, crl_data->errbuf); 208 + if(curl_data->errbuf[0])
  209 + lib3270_write_log(hSession,"curl","%s: %s",url, curl_data->errbuf);
211 210
212 - *error_message = curl_easy_strerror(res); 211 + *error = curl_easy_strerror(res);
213 212
214 - lib3270_write_log(hSession,"curl","%s: %s",url, *error_message); 213 + lib3270_write_log(hSession,"curl","%s: %s",url, *error);
215 errno = EINVAL; 214 errno = EINVAL;
216 return NULL; 215 return NULL;
217 216
218 } 217 }
219 218
220 - if(length)  
221 - *length = (size_t) crl_data->length;  
222 -  
223 - char * httpText = lib3270_malloc(crl_data->length+1);  
224 - memset(httpText,0,crl_data->length+1);  
225 - memcpy(httpText,crl_data->data.contents,crl_data->length); 219 + char * httpText = lib3270_malloc(curl_data->length+1);
  220 + memset(httpText,0,curl_data->length+1);
  221 + memcpy(httpText,curl_data->data.contents,curl_data->length);
226 222
227 return httpText; 223 return httpText;
228 224
src/core/linux/download.c 0 → 100644
@@ -0,0 +1,63 @@ @@ -0,0 +1,63 @@
  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 "private.h"
  31 +#include <utilc.h>
  32 +
  33 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  34 +
  35 + char * lib3270_url_get(H3270 *hSession, const char *u, const char **error) {
  36 +
  37 + lib3270_autoptr(char) url = lib3270_unescape(u);
  38 +
  39 + if(strncasecmp(url,"file://",7) == 0) {
  40 +
  41 + // Load local file contents.
  42 + char *rc = lib3270_file_get_contents(hSession,url+7);
  43 + if(!rc)
  44 + *error = strerror(errno);
  45 + return rc;
  46 + }
  47 +
  48 +#if defined(HAVE_LIBCURL)
  49 +
  50 + return lib3270_url_get_using_curl(hSession,url,error);
  51 +
  52 +#else
  53 +
  54 + // Can't get contents
  55 + *error = _("No handler for URL scheme.");
  56 + errno = EINVAL;
  57 + return NULL;
  58 +
  59 +
  60 +#endif // HAVE_LIBCURL
  61 +
  62 +
  63 + }
src/core/linux/private.h 0 → 100644
@@ -0,0 +1,44 @@ @@ -0,0 +1,44 @@
  1 +/*
  2 + * "Software G3270, 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 ', 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 private.h 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 de Mendonça)
  27 + *
  28 + */
  29 +
  30 +#ifndef PRIVATE_H_INCLUDED
  31 +
  32 + #define PRIVATE_H_INCLUDED
  33 +
  34 + #include <config.h>
  35 + #include <internals.h>
  36 +
  37 + #include <lib3270.h>
  38 + #include <lib3270/log.h>
  39 +
  40 + #if defined(HAVE_LIBCURL)
  41 + LIB3270_INTERNAL char * lib3270_url_get_using_curl(H3270 *hSession, const char *u, const char **error);
  42 + #endif // HAVE_LIBCURL
  43 +
  44 +#endif // !PRIVATE_H_INCLUDED
src/core/popup.c
@@ -45,6 +45,29 @@ LIB3270_EXPORT int lib3270_popup(H3270 *hSession, const LIB3270_POPUP *popup, un @@ -45,6 +45,29 @@ LIB3270_EXPORT int lib3270_popup(H3270 *hSession, const LIB3270_POPUP *popup, un
45 return hSession->cbk.popup(hSession,popup,wait); 45 return hSession->cbk.popup(hSession,popup,wait);
46 } 46 }
47 47
  48 +LIB3270_EXPORT int lib3270_popup_translated(H3270 *hSession, const LIB3270_POPUP *popup, unsigned char wait) {
  49 +
  50 + LIB3270_POPUP translated = *popup;
  51 +
  52 + if(popup->title) {
  53 + translated.title = dgettext(GETTEXT_PACKAGE,popup->title);
  54 + }
  55 +
  56 + if(popup->label) {
  57 + translated.label = dgettext(GETTEXT_PACKAGE,popup->label);
  58 + }
  59 +
  60 + if(popup->summary) {
  61 + translated.summary = dgettext(GETTEXT_PACKAGE,popup->summary);
  62 + }
  63 +
  64 + if(popup->body) {
  65 + translated.body = dgettext(GETTEXT_PACKAGE,popup->body);
  66 + }
  67 +
  68 + return hSession->cbk.popup(hSession,&translated,wait);
  69 +}
  70 +
48 /// @brief Pop up an error dialog. 71 /// @brief Pop up an error dialog.
49 void popup_an_error(H3270 *hSession, const char *fmt, ...) 72 void popup_an_error(H3270 *hSession, const char *fmt, ...)
50 { 73 {
src/core/util.c
@@ -39,6 +39,8 @@ @@ -39,6 +39,8 @@
39 #include "popupsc.h" 39 #include "popupsc.h"
40 #include <lib3270/selection.h> 40 #include <lib3270/selection.h>
41 #include <lib3270/log.h> 41 #include <lib3270/log.h>
  42 +#include <sys/stat.h>
  43 +#include <fcntl.h>
42 44
43 #if defined(HAVE_LIBSSL) 45 #if defined(HAVE_LIBSSL)
44 #include <openssl/opensslv.h> 46 #include <openssl/opensslv.h>
@@ -50,9 +52,7 @@ @@ -50,9 +52,7 @@
50 52
51 #define my_isspace(c) isspace((unsigned char)c) 53 #define my_isspace(c) isspace((unsigned char)c)
52 54
53 -/**  
54 - * @brief Cheesy internal version of sprintf that allocates its own memory.  
55 - */ 55 +/// @brief Cheesy internal version of sprintf that allocates its own memory.
56 char * lib3270_vsprintf(const char *fmt, va_list args) 56 char * lib3270_vsprintf(const char *fmt, va_list args)
57 { 57 {
58 char *r = NULL; 58 char *r = NULL;
@@ -119,34 +119,6 @@ char * xs_buffer(const char *fmt, ...) @@ -119,34 +119,6 @@ char * xs_buffer(const char *fmt, ...)
119 return r; 119 return r;
120 } 120 }
121 121
122 -// Common uses of xs_buffer.  
123 -  
124 -/*  
125 -void xs_warning(const char *fmt, ...)  
126 -{  
127 - va_list args;  
128 - char *r;  
129 -  
130 - va_start(args, fmt);  
131 - r = lib3270_vsprintf(fmt, args);  
132 - va_end(args);  
133 - lib3270_popup_dialog(lib3270_get_default_session_handle(),LIB3270_NOTIFY_WARNING,_("Warning"),r,NULL);  
134 - lib3270_free(r);  
135 -}  
136 -  
137 -void xs_error(const char *fmt, ...)  
138 -{  
139 - va_list args;  
140 - char *r;  
141 -  
142 - va_start(args, fmt);  
143 - r = lib3270_vsprintf(fmt, args);  
144 - va_end(args);  
145 - lib3270_popup_dialog(lib3270_get_default_session_handle(),LIB3270_NOTIFY_ERROR,_("Error"),r,NULL);  
146 - lib3270_free(r);  
147 -}  
148 -*/  
149 -  
150 /** 122 /**
151 * @brief Expands a character in the manner of "cat -v". 123 * @brief Expands a character in the manner of "cat -v".
152 */ 124 */
@@ -176,124 +148,6 @@ ctl_see(int c) @@ -176,124 +148,6 @@ ctl_see(int c)
176 return buf; 148 return buf;
177 } 149 }
178 150
179 -/*  
180 -/// @brief Whitespace stripper.  
181 -char *  
182 -strip_whitespace(const char *s)  
183 -{  
184 - char *t = NewString(s);  
185 -  
186 - while (*t && my_isspace(*t))  
187 - t++;  
188 - if (*t) {  
189 - char *u = t + strlen(t) - 1;  
190 -  
191 - while (my_isspace(*u)) {  
192 - *u-- = '\0';  
193 - }  
194 - }  
195 - return t;  
196 -}  
197 -*/  
198 -  
199 -/*  
200 -///  
201 -/// @brief Hierarchy (a>b>c) splitter.  
202 -///  
203 -Boolean  
204 -split_hier(char *label, char **base, char ***parents)  
205 -{  
206 - int n_parents = 0;  
207 - char *gt;  
208 - char *lp;  
209 -  
210 - label = NewString(label);  
211 - for (lp = label; (gt = strchr(lp, '>')) != CN; lp = gt + 1) {  
212 - if (gt == lp)  
213 - return False;  
214 - n_parents++;  
215 - }  
216 - if (!*lp)  
217 - return False;  
218 -  
219 - if (n_parents) {  
220 - *parents = (char **)Calloc(n_parents + 1, sizeof(char *));  
221 - for (n_parents = 0, lp = label;  
222 - (gt = strchr(lp, '>')) != CN;  
223 - lp = gt + 1) {  
224 - (*parents)[n_parents++] = lp;  
225 - *gt = '\0';  
226 - }  
227 - *base = lp;  
228 - } else {  
229 - (*parents) = NULL;  
230 - (*base) = label;  
231 - }  
232 - return True;  
233 -}  
234 -*/  
235 -  
236 -/*  
237 -/// @brief Incremental, reallocing version of snprintf.  
238 -#define RPF_BLKSIZE 4096  
239 -#define SP_TMP_LEN 16384  
240 -  
241 -/// @brief Initialize an RPF structure.  
242 -void  
243 -rpf_init(rpf_t *r)  
244 -{  
245 - r->buf = NULL;  
246 - r->alloc_len = 0;  
247 - r->cur_len = 0;  
248 -}  
249 -  
250 -/// @brief Reset an initialized RPF structure (re-use with length 0).  
251 -void  
252 -rpf_reset(rpf_t *r)  
253 -{  
254 - r->cur_len = 0;  
255 -}  
256 -  
257 -/// @brief Append a string to a dynamically-allocated buffer.  
258 -void  
259 -rpf(rpf_t *r, char *fmt, ...)  
260 -{  
261 - va_list a;  
262 - Boolean need_realloc = False;  
263 - int ns;  
264 - char tbuf[SP_TMP_LEN];  
265 -  
266 - // Figure out how much space would be needed.  
267 - va_start(a, fmt);  
268 - ns = vsprintf(tbuf, fmt, a); // XXX: dangerous, but so is vsnprintf  
269 - va_end(a);  
270 - if (ns >= SP_TMP_LEN)  
271 - Error(NULL,"rpf overrun");  
272 -  
273 - // Make sure we have that.  
274 - while (r->alloc_len - r->cur_len < ns + 1) {  
275 - r->alloc_len += RPF_BLKSIZE;  
276 - need_realloc = True;  
277 - }  
278 - if (need_realloc) {  
279 - r->buf = Realloc(r->buf, r->alloc_len);  
280 - }  
281 -  
282 - // Scribble onto the end of that.  
283 - (void) strcpy(r->buf + r->cur_len, tbuf);  
284 - r->cur_len += ns;  
285 -}  
286 -  
287 -/// @brief Free resources associated with an RPF.  
288 -void rpf_free(rpf_t *r)  
289 -{  
290 - lib3270_free(r->buf);  
291 - r->buf = NULL;  
292 - r->alloc_len = 0;  
293 - r->cur_len = 0;  
294 -}  
295 -*/  
296 -  
297 LIB3270_EXPORT void * lib3270_free(void *p) 151 LIB3270_EXPORT void * lib3270_free(void *p)
298 { 152 {
299 if(p) 153 if(p)
@@ -520,36 +374,6 @@ LIB3270_EXPORT LIB3270_POINTER lib3270_get_pointer(H3270 *hSession, int baddr) @@ -520,36 +374,6 @@ LIB3270_EXPORT LIB3270_POINTER lib3270_get_pointer(H3270 *hSession, int baddr)
520 374
521 } 375 }
522 376
523 -/*  
524 -LIB3270_EXPORT int lib3270_getpeername(H3270 *hSession, struct sockaddr *addr, socklen_t *addrlen)  
525 -{  
526 - CHECK_SESSION_HANDLE(hSession);  
527 -  
528 - memset(addr,0,*addrlen);  
529 -  
530 - if(hSession->connection.sock < 0) {  
531 - errno = ENOTCONN;  
532 - return -1;  
533 - }  
534 -  
535 - return getpeername(hSession->connection.sock, addr, addrlen);  
536 -  
537 -}  
538 -  
539 -LIB3270_EXPORT int lib3270_getsockname(H3270 *hSession, struct sockaddr *addr, socklen_t *addrlen)  
540 -{  
541 - CHECK_SESSION_HANDLE(hSession);  
542 -  
543 - memset(addr,0,*addrlen);  
544 -  
545 - if(hSession->connection.sock < 0) {  
546 - errno = ENOTCONN;  
547 - return -1;  
548 - }  
549 -  
550 - return getsockname(hSession->connection.sock, addr, addrlen);  
551 -}  
552 -*/  
553 static int xdigit_value(const char scanner) 377 static int xdigit_value(const char scanner)
554 { 378 {
555 379
@@ -660,3 +484,46 @@ int lib3270_compare_alnum(const char *s1, const char *s2) @@ -660,3 +484,46 @@ int lib3270_compare_alnum(const char *s1, const char *s2)
660 LIB3270_EXPORT const char * lib3270_get_translation_domain() { 484 LIB3270_EXPORT const char * lib3270_get_translation_domain() {
661 return GETTEXT_PACKAGE; 485 return GETTEXT_PACKAGE;
662 } 486 }
  487 +
  488 +LIB3270_INTERNAL char * lib3270_file_get_contents(H3270 GNUC_UNUSED(*hSession), const char *filename) {
  489 +
  490 + int fd = open(filename,O_RDONLY);
  491 + if(fd < 0)
  492 + return NULL;
  493 +
  494 + // Get file size.
  495 + struct stat st;
  496 +
  497 + if(fstat(fd,&st) < 0) {
  498 + int err = errno;
  499 + close(fd);
  500 + errno = err;
  501 + return NULL;
  502 + }
  503 +
  504 + char * text = lib3270_malloc(st.st_size+1);
  505 + memset(text,0,st.st_size+1);
  506 +
  507 + char *ptr = text;
  508 + while(st.st_size) {
  509 +
  510 + ssize_t bytes = read(fd,ptr,st.st_size);
  511 + if(bytes < 0) {
  512 + int err = errno;
  513 + close(fd);
  514 + lib3270_free(text);
  515 + errno = err;
  516 + return NULL;
  517 + }
  518 +
  519 + if(!bytes)
  520 + break;
  521 +
  522 + ptr += bytes;
  523 + st.st_size -= bytes;
  524 +
  525 + }
  526 +
  527 + close(fd);
  528 + return text;
  529 +}
src/include/internals.h
@@ -683,9 +683,10 @@ struct _h3270 @@ -683,9 +683,10 @@ struct _h3270
683 683
684 struct 684 struct
685 { 685 {
686 - int host : 1; ///< @brief Non zero if host requires SSL.  
687 - int error; ///< @brief OpenSSL error.  
688 - LIB3270_SSL_STATE state; 686 + int host : 1; ///< @brief Non zero if host requires SSL.
  687 + LIB3270_SSL_STATE state;
  688 + int error;
  689 + const LIB3270_SSL_MESSAGE * message; ///< @brief Pointer to SSL messages for current state.
689 } ssl; 690 } ssl;
690 691
691 /// @brief Event Listeners. 692 /// @brief Event Listeners.
@@ -835,14 +836,24 @@ LIB3270_INTERNAL void set_ssl_state(H3270 *session, LIB3270_SSL_STATE state); @@ -835,14 +836,24 @@ LIB3270_INTERNAL void set_ssl_state(H3270 *session, LIB3270_SSL_STATE state);
835 836
836 /// @brief Query data from URL. 837 /// @brief Query data from URL.
837 /// 838 ///
838 - /// @param hSession Handle of the TN3270 Session.  
839 - /// @param url The url to get.  
840 - /// @param length Pointer to the response lenght (can be NULL).  
841 - /// @param error_message Pointer to the error message. 839 + /// @param hSession Handle of the TN3270 Session.
  840 + /// @param url The url to get.
  841 + /// @param length Pointer to the response lenght (can be NULL).
  842 + /// @param error Pointer to the detailed error message.
842 /// 843 ///
843 /// @return The data from URL (release it with lib3270_free) or NULL on error. 844 /// @return The data from URL (release it with lib3270_free) or NULL on error.
844 /// 845 ///
845 - LIB3270_INTERNAL char * lib3270_get_from_url(H3270 *hSession, const char *url, size_t *length, const char **error_message); 846 + LIB3270_INTERNAL char * lib3270_url_get(H3270 *hSession, const char *url, const char **error);
  847 +
  848 + /// @brief Load text file.
  849 + ///
  850 + /// @param hSession Handle of the TN3270 Session.
  851 + /// @param filename The file name.
  852 + ///
  853 + /// @return The file contents (release it with lib3270_free or NULL on error (sets errno).
  854 + ///
  855 + LIB3270_INTERNAL char * lib3270_file_get_contents(H3270 *hSession, const char *filename);
  856 +
846 857
847 /// @brief Fire CState change. 858 /// @brief Fire CState change.
848 LIB3270_INTERNAL int lib3270_set_cstate(H3270 *hSession, LIB3270_CSTATE cstate); 859 LIB3270_INTERNAL int lib3270_set_cstate(H3270 *hSession, LIB3270_CSTATE cstate);
@@ -859,6 +870,18 @@ LIB3270_INTERNAL void set_ssl_state(H3270 *session, LIB3270_SSL_STATE state); @@ -859,6 +870,18 @@ LIB3270_INTERNAL void set_ssl_state(H3270 *session, LIB3270_SSL_STATE state);
859 /// 870 ///
860 LIB3270_INTERNAL int lib3270_start_tls(H3270 *hSession); 871 LIB3270_INTERNAL int lib3270_start_tls(H3270 *hSession);
861 872
  873 + /**
  874 + * @brief Emit translated popup message.
  875 + *
  876 + * @param hSession TN3270 Session handle.
  877 + * @param popup Popup descriptor.
  878 + * @param wait If non zero waits for user response.
  879 + *
  880 + * @return User action.
  881 + *
  882 + * @retval 0 User has confirmed, continue action.
  883 + * @retval ECANCELED Operation was canceled.
  884 + * @retval ENOTSUP No popup handler available.
  885 + */
  886 + LIB3270_EXPORT int lib3270_popup_translated(H3270 *hSession, const LIB3270_POPUP *popup, unsigned char wait);
862 887
863 - /// @brief Load file using URL.  
864 - LIB3270_INTERNAL char * lib3270_url_get(H3270 *hSession, const char *url, LIB3270_POPUP **popup);  
src/include/lib3270/session.h
@@ -39,10 +39,6 @@ @@ -39,10 +39,6 @@
39 #include <sys/socket.h> 39 #include <sys/socket.h>
40 #endif // _WIN32 40 #endif // _WIN32
41 41
42 -#ifdef HAVE_LIBSSL  
43 - #include <openssl/ssl.h>  
44 -#endif // HAVE_LIBSSL  
45 -  
46 #include <lib3270/popup.h> 42 #include <lib3270/popup.h>
47 #include <lib3270/toggle.h> 43 #include <lib3270/toggle.h>
48 44
src/include/networking.h
@@ -37,6 +37,11 @@ @@ -37,6 +37,11 @@
37 typedef struct _lib3270_network_popup LIB3270_NETWORK_POPUP; 37 typedef struct _lib3270_network_popup LIB3270_NETWORK_POPUP;
38 typedef struct _lib3270_net_context LIB3270_NET_CONTEXT; 38 typedef struct _lib3270_net_context LIB3270_NET_CONTEXT;
39 39
  40 + typedef struct lib3270_ssl_message {
  41 + LIB3270_POPUP_HEAD ///< @brief Standard popup fields.
  42 + const char * icon; ///< @brief Icon name from https://specifications.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html
  43 + } LIB3270_SSL_MESSAGE;
  44 +
40 typedef struct lib3270_network_state { 45 typedef struct lib3270_network_state {
41 46
42 int syserror; ///< @brief System error (errno) 47 int syserror; ///< @brief System error (errno)
@@ -46,7 +51,7 @@ @@ -46,7 +51,7 @@
46 51
47 const char * error_message; /// @brief System error message. 52 const char * error_message; /// @brief System error message.
48 53
49 - const LIB3270_NETWORK_POPUP *popup; /// @brief Detailed info for popup. 54 + const LIB3270_POPUP *popup; /// @brief Detailed info for popup.
50 55
51 } LIB3270_NETWORK_STATE; 56 } LIB3270_NETWORK_STATE;
52 57
@@ -63,7 +68,7 @@ @@ -63,7 +68,7 @@
63 /// @param hSession TN3270 session. 68 /// @param hSession TN3270 session.
64 /// @param state Pointer to state message. 69 /// @param state Pointer to state message.
65 /// 70 ///
66 - int (*init)(H3270 *hSession, LIB3270_NETWORK_STATE *state); 71 + int (*init)(H3270 *hSession);
67 72
68 /// @brief Deinitialize network module. 73 /// @brief Deinitialize network module.
69 /// 74 ///
@@ -87,7 +92,16 @@ @@ -87,7 +92,16 @@
87 /// 92 ///
88 int (*disconnect)(H3270 *hSession); 93 int (*disconnect)(H3270 *hSession);
89 94
90 - int (*start_tls)(H3270 *hSession, LIB3270_NETWORK_STATE *msg); 95 + /// @brief Start TLS/SSL.
  96 + ///
  97 + /// @param hSession TN3270 session.
  98 + ///
  99 + /// @return 0 if ok, error code if not.
  100 + ///
  101 + /// @retval 0 TLS/SSL was negotiated.
  102 + /// @retval ENOTSUP No TLS/SSL support in the network module.
  103 + ///
  104 + int (*start_tls)(H3270 *hSession);
91 105
92 /// @brief Send on network context. 106 /// @brief Send on network context.
93 /// 107 ///
@@ -158,7 +172,7 @@ @@ -158,7 +172,7 @@
158 */ 172 */
159 LIB3270_INTERNAL void lib3270_set_default_network_module(H3270 *hSession); 173 LIB3270_INTERNAL void lib3270_set_default_network_module(H3270 *hSession);
160 174
161 - LIB3270_INTERNAL int lib3270_activate_ssl_network_module(H3270 *hSession, int sock, LIB3270_NETWORK_STATE *state); 175 + LIB3270_INTERNAL int lib3270_activate_ssl_network_module(H3270 *hSession, int sock);
162 176
163 #endif // LIB3270_NETWORKING_H_INCLUDED 177 #endif // LIB3270_NETWORKING_H_INCLUDED
164 178
src/network_modules/default/main.c
@@ -248,34 +248,29 @@ static int unsecure_network_connect(H3270 *hSession, LIB3270_NETWORK_STATE *stat @@ -248,34 +248,29 @@ static int unsecure_network_connect(H3270 *hSession, LIB3270_NETWORK_STATE *stat
248 return 0; 248 return 0;
249 } 249 }
250 250
251 -static int unsecure_network_start_tls(H3270 *hSession, LIB3270_NETWORK_STATE *msg) { 251 +static int unsecure_network_start_tls(H3270 *hSession) {
252 252
253 if(hSession->ssl.host) { 253 if(hSession->ssl.host) {
254 254
255 // TLS/SSL is required, replace network module with the OpenSSL one. 255 // TLS/SSL is required, replace network module with the OpenSSL one.
256 - int rc = lib3270_activate_ssl_network_module(hSession, hSession->network.context->sock, msg); 256 + int rc = lib3270_activate_ssl_network_module(hSession, hSession->network.context->sock);
257 257
258 if(!rc) 258 if(!rc)
259 - rc = hSession->network.module->start_tls(hSession,msg); 259 + rc = hSession->network.module->start_tls(hSession);
260 260
261 return rc; 261 return rc;
262 -/*  
263 - // TODO: Replace network module with the openssl version, initialize and execute start_tls on it.  
264 -  
265 - static const LIB3270_POPUP popup = {  
266 - .type = LIB3270_NOTIFY_ERROR,  
267 - .summary = N_("Can't activate SSL/TLS"),  
268 - .body = N_("The protocol library was build without SSL/TLS support")  
269 - };  
270 262
271 - msg->popup = &popup; 263 + }
272 264
273 - return ENOTSUP;  
274 -*/ 265 + static LIB3270_SSL_MESSAGE message = {
  266 + .icon = "dialog-error",
  267 + .summary = N_( "The session is not secure" ),
  268 + .body = N_( "No TLS/SSL support on this session" )
  269 + };
275 270
276 - } 271 + hSession->ssl.message = &message;
277 272
278 - return 0; 273 + return ENOTSUP;
279 } 274 }
280 275
281 void lib3270_set_default_network_module(H3270 *hSession) { 276 void lib3270_set_default_network_module(H3270 *hSession) {
src/network_modules/openssl/context.c
@@ -144,7 +144,7 @@ static void info_callback(INFO_CONST SSL *s, int where, int ret) @@ -144,7 +144,7 @@ static void info_callback(INFO_CONST SSL *s, int where, int ret)
144 } 144 }
145 } 145 }
146 146
147 -SSL_CTX * lib3270_openssl_get_context(H3270 *hSession, LIB3270_NETWORK_STATE *state) { 147 +SSL_CTX * lib3270_openssl_get_context(H3270 *hSession) {
148 148
149 static SSL_CTX * context = NULL; 149 static SSL_CTX * context = NULL;
150 150
@@ -159,13 +159,13 @@ SSL_CTX * lib3270_openssl_get_context(H3270 *hSession, LIB3270_NETWORK_STATE *st @@ -159,13 +159,13 @@ SSL_CTX * lib3270_openssl_get_context(H3270 *hSession, LIB3270_NETWORK_STATE *st
159 context = SSL_CTX_new(SSLv23_method()); 159 context = SSL_CTX_new(SSLv23_method());
160 if(context == NULL) 160 if(context == NULL)
161 { 161 {
162 - static const LIB3270_NETWORK_POPUP popup = { 162 + static const LIB3270_SSL_MESSAGE message = {
163 .type = LIB3270_NOTIFY_SECURE, 163 .type = LIB3270_NOTIFY_SECURE,
164 .icon = "dialog-error", 164 .icon = "dialog-error",
165 .summary = N_( "Can't initialize the TLS/SSL context." ), 165 .summary = N_( "Can't initialize the TLS/SSL context." ),
166 }; 166 };
167 167
168 - hSession->network.context->state.popup = state->popup = &popup; 168 + hSession->ssl.message = &message;
169 hSession->network.context->state.error = ERR_get_error(); 169 hSession->network.context->state.error = ERR_get_error();
170 return NULL; 170 return NULL;
171 } 171 }
src/network_modules/openssl/crl.c
@@ -62,7 +62,7 @@ LIB3270_STRING_ARRAY * lib3270_openssl_get_crls_from_peer(H3270 *hSession, X509 @@ -62,7 +62,7 @@ LIB3270_STRING_ARRAY * lib3270_openssl_get_crls_from_peer(H3270 *hSession, X509
62 62
63 GENERAL_NAMES *gens = dp->distpoint->name.fullname; 63 GENERAL_NAMES *gens = dp->distpoint->name.fullname;
64 64
65 - size_t i; 65 + int i;
66 for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { 66 for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
67 int gtype; 67 int gtype;
68 GENERAL_NAME *gen = sk_GENERAL_NAME_value(gens, i); 68 GENERAL_NAME *gen = sk_GENERAL_NAME_value(gens, i);
src/network_modules/openssl/main.c
@@ -35,13 +35,6 @@ @@ -35,13 +35,6 @@
35 #include "private.h" 35 #include "private.h"
36 36
37 37
38 -static void crl_free(LIB3270_NET_CONTEXT *context) {  
39 - if(context->crl.cert) {  
40 - X509_CRL_free(context->crl.cert);  
41 - context->crl.cert = NULL;  
42 - }  
43 -}  
44 -  
45 static void openssl_network_finalize(H3270 *hSession) { 38 static void openssl_network_finalize(H3270 *hSession) {
46 39
47 debug("%s",__FUNCTION__); 40 debug("%s",__FUNCTION__);
@@ -51,7 +44,7 @@ static void openssl_network_finalize(H3270 *hSession) { @@ -51,7 +44,7 @@ static void openssl_network_finalize(H3270 *hSession) {
51 // Cleanupp 44 // Cleanupp
52 LIB3270_NET_CONTEXT *context = hSession->network.context; 45 LIB3270_NET_CONTEXT *context = hSession->network.context;
53 46
54 - crl_free(context); 47 + lib3270_openssl_crl_free(context);
55 48
56 // Release network context. 49 // Release network context.
57 lib3270_free(hSession->network.context); 50 lib3270_free(hSession->network.context);
@@ -115,11 +108,11 @@ static int openssl_network_setsockopt(H3270 *hSession, int level, int optname, c @@ -115,11 +108,11 @@ static int openssl_network_setsockopt(H3270 *hSession, int level, int optname, c
115 static int openssl_network_getsockopt(H3270 *hSession, int level, int optname, void *optval, socklen_t *optlen) { 108 static int openssl_network_getsockopt(H3270 *hSession, int level, int optname, void *optval, socklen_t *optlen) {
116 } 109 }
117 110
118 -static int openssl_network_init(H3270 *hSession, LIB3270_NETWORK_STATE *state) { 111 +static int openssl_network_init(H3270 *hSession) {
119 112
120 set_ssl_state(hSession,LIB3270_SSL_UNDEFINED); 113 set_ssl_state(hSession,LIB3270_SSL_UNDEFINED);
121 114
122 - SSL_CTX * ctx_context = (SSL_CTX *) lib3270_openssl_get_context(state,state); 115 + SSL_CTX * ctx_context = (SSL_CTX *) lib3270_openssl_get_context(hSession);
123 if(!ctx_context) 116 if(!ctx_context)
124 return -1; 117 return -1;
125 118
@@ -214,14 +207,22 @@ void lib3270_set_openssl_network_module(H3270 *hSession) { @@ -214,14 +207,22 @@ void lib3270_set_openssl_network_module(H3270 *hSession) {
214 hSession->network.module = &module; 207 hSession->network.module = &module;
215 } 208 }
216 209
217 -int lib3270_activate_ssl_network_module(H3270 *hSession, int sock, LIB3270_NETWORK_STATE *state) { 210 +int lib3270_activate_ssl_network_module(H3270 *hSession, int sock) {
218 211
219 lib3270_set_openssl_network_module(hSession); 212 lib3270_set_openssl_network_module(hSession);
220 213
221 - int rc = openssl_network_init(hSession, state); 214 + int rc = openssl_network_init(hSession);
222 215
223 hSession->network.context->sock = sock; 216 hSession->network.context->sock = sock;
224 217
225 return rc; 218 return rc;
226 219
227 } 220 }
  221 +
  222 +void lib3270_openssl_crl_free(LIB3270_NET_CONTEXT *context) {
  223 + if(context->crl.cert) {
  224 + X509_CRL_free(context->crl.cert);
  225 + context->crl.cert = NULL;
  226 + }
  227 +}
  228 +
src/network_modules/openssl/messages.c 0 → 100644
@@ -0,0 +1,376 @@ @@ -0,0 +1,376 @@
  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 +/// @brief OpenSSL states.
  31 +
  32 +#include "private.h"
  33 +
  34 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  35 +
  36 +const LIB3270_SSL_MESSAGE * lib3270_openssl_message_from_id(long id) {
  37 +
  38 + static const struct {
  39 +
  40 + long id;
  41 + LIB3270_SSL_MESSAGE message;
  42 +
  43 + } messages[] = {
  44 +
  45 + // http://www.openssl.org/docs/apps/verify.html
  46 + {
  47 + .id = X509_V_OK,
  48 + .message = {
  49 + .type = LIB3270_NOTIFY_INFO,
  50 + .icon = "security-high",
  51 + .summary = N_( "Secure connection was successful." ),
  52 + .body = N_( "The connection is secure and the host identity was confirmed." )
  53 + }
  54 + },
  55 +
  56 + {
  57 + .id = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT,
  58 + .message = {
  59 + .type = LIB3270_NOTIFY_ERROR,
  60 + .icon = "dialog-error",
  61 + .summary = N_( "Unable to get issuer certificate" ),
  62 + .body = N_( "The issuer certificate of a looked up certificate could not be found. This normally means the list of trusted certificates is not complete." )
  63 + }
  64 + },
  65 +
  66 + {
  67 + .id = X509_V_ERR_UNABLE_TO_GET_CRL,
  68 + .message = {
  69 + .type = LIB3270_NOTIFY_ERROR,
  70 + .icon = "dialog-error",
  71 + .summary = N_( "Unable to get certificate CRL." ),
  72 + .body = N_( "The Certificate revocation list (CRL) of a certificate could not be found." )
  73 + }
  74 + },
  75 +
  76 + {
  77 + .id = X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE,
  78 + .message = {
  79 + .type = LIB3270_NOTIFY_ERROR,
  80 + .icon = "dialog-error",
  81 + .summary = N_( "Unable to decrypt certificate's signature" ),
  82 + .body = N_( "The certificate signature could not be decrypted. This means that the actual signature value could not be determined rather than it not matching the expected value, this is only meaningful for RSA keys." )
  83 + }
  84 + },
  85 +
  86 + {
  87 + .id = X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE,
  88 + .message = {
  89 + .type = LIB3270_NOTIFY_ERROR,
  90 + .icon = "dialog-error",
  91 + .summary = N_( "Unable to decrypt CRL's signature" ),
  92 + .body = N_( "The CRL signature could not be decrypted: this means that the actual signature value could not be determined rather than it not matching the expected value. Unused." )
  93 + }
  94 + },
  95 +
  96 + {
  97 + .id = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY,
  98 + .message = {
  99 + .type = LIB3270_NOTIFY_ERROR,
  100 + .icon = "dialog-error",
  101 + .summary = N_( "Unable to decode issuer public key" ),
  102 + .body = N_( "The public key in the certificate SubjectPublicKeyInfo could not be read." )
  103 + }
  104 + },
  105 +
  106 + {
  107 + .id = X509_V_ERR_CERT_SIGNATURE_FAILURE,
  108 + .message = {
  109 + .type = LIB3270_NOTIFY_ERROR,
  110 + .icon = "dialog-error",
  111 + .summary = N_( "Certificate signature failure" ),
  112 + .body = N_( "The signature of the certificate is invalid." )
  113 + }
  114 + },
  115 +
  116 + {
  117 + .id = X509_V_ERR_CRL_SIGNATURE_FAILURE,
  118 + .message = {
  119 + .type = LIB3270_NOTIFY_ERROR,
  120 + .icon = "dialog-error",
  121 + .summary = N_( "CRL signature failure" ),
  122 + .body = N_( "The signature of the certificate is invalid." )
  123 + }
  124 + },
  125 +
  126 + {
  127 + .id = X509_V_ERR_CERT_NOT_YET_VALID,
  128 + .message = {
  129 + .type = LIB3270_NOTIFY_WARNING,
  130 + .icon = "dialog-warning",
  131 + .summary = N_( "Certificate is not yet valid" ),
  132 + .body = N_( "The certificate is not yet valid: the notBefore date is after the current time." )
  133 + }
  134 + },
  135 +
  136 + {
  137 + .id = X509_V_ERR_CERT_HAS_EXPIRED,
  138 + .message = {
  139 + .type = LIB3270_NOTIFY_ERROR,
  140 + .icon = "dialog-error",
  141 + .summary = N_( "Certificate has expired" ),
  142 + .body = N_( "The certificate has expired: that is the notAfter date is before the current time." )
  143 + }
  144 + },
  145 +
  146 + {
  147 + .id = X509_V_ERR_CRL_NOT_YET_VALID,
  148 + .message = {
  149 + .type = LIB3270_NOTIFY_WARNING,
  150 + .icon = "dialog-error",
  151 + .summary = N_( "The CRL is not yet valid." ),
  152 + .body = N_( "The Certificate revocation list (CRL) is not yet valid." )
  153 + }
  154 + },
  155 +
  156 + {
  157 + .id = X509_V_ERR_CRL_HAS_EXPIRED,
  158 + .message = {
  159 + #ifdef SSL_ENABLE_CRL_EXPIRATION_CHECK
  160 + .type = LIB3270_NOTIFY_ERROR,
  161 + #else
  162 + .type = LIB3270_NOTIFY_WARNING,
  163 + #endif // SSL_ENABLE_CRL_EXPIRATION_CHECK
  164 + .icon = "security-medium",
  165 + .summary = N_( "The CRL has expired." ),
  166 + .body = N_( "The Certificate revocation list (CRL) has expired.")
  167 + }
  168 + },
  169 +
  170 + {
  171 + .id = X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD,
  172 + .message = {
  173 + .type = LIB3270_NOTIFY_ERROR,
  174 + .icon = "dialog-error",
  175 + .summary = N_( "Format error in certificate's notBefore field" ),
  176 + .body = N_( "The certificate notBefore field contains an invalid time." )
  177 + }
  178 + },
  179 +
  180 + {
  181 + .id = X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD,
  182 + .message = {
  183 + .type = LIB3270_NOTIFY_ERROR,
  184 + .icon = "dialog-error",
  185 + .summary = N_( "Format error in certificate's notAfter field" ),
  186 + .body = N_( "The certificate notAfter field contains an invalid time." )
  187 + }
  188 + },
  189 +
  190 + {
  191 + .id = X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD,
  192 + .message = {
  193 + .type = LIB3270_NOTIFY_ERROR,
  194 + .icon = "dialog-error",
  195 + .summary = N_( "Format error in CRL's lastUpdate field" ),
  196 + .body = N_( "The CRL lastUpdate field contains an invalid time." )
  197 + }
  198 + },
  199 +
  200 + {
  201 + .id = X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD,
  202 + .message = {
  203 + .type = LIB3270_NOTIFY_ERROR,
  204 + .icon = "dialog-error",
  205 + .summary = N_( "Format error in CRL's nextUpdate field" ),
  206 + .body = N_( "The CRL nextUpdate field contains an invalid time." )
  207 + }
  208 + },
  209 +
  210 + {
  211 + .id = X509_V_ERR_OUT_OF_MEM,
  212 + .message = {
  213 + .type = LIB3270_NOTIFY_ERROR,
  214 + .icon = "dialog-error",
  215 + .summary = N_( "Out of memory" ),
  216 + .body = N_( "An error occurred trying to allocate memory. This should never happen." )
  217 + }
  218 + },
  219 +
  220 + {
  221 + .id = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT,
  222 + .message = {
  223 + .type = LIB3270_NOTIFY_WARNING,
  224 + .icon = "security-medium",
  225 + .summary = N_( "Self signed certificate" ),
  226 + .body = N_( "The passed certificate is self signed and the same certificate cannot be found in the list of trusted certificates." )
  227 + }
  228 + },
  229 +
  230 + {
  231 + .id = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN,
  232 + .message = {
  233 + #ifdef SSL_ENABLE_SELF_SIGNED_CERT_CHECK
  234 + .type = LIB3270_NOTIFY_ERROR,
  235 + #else
  236 + .type = LIB3270_NOTIFY_WARNING,
  237 + #endif // SSL_ENABLE_SELF_SIGNED_CERT_CHECK
  238 + .icon = "security-medium",
  239 + .summary = N_( "Self signed certificate in certificate chain" ),
  240 + .body = N_( "The certificate chain could be built up using the untrusted certificates but the root could not be found locally." )
  241 + }
  242 + },
  243 +
  244 + {
  245 + .id = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY,
  246 + .message = {
  247 + .type = LIB3270_NOTIFY_WARNING,
  248 + .icon = "security-low",
  249 + .summary = N_( "Unable to get local issuer certificate" ),
  250 + .body = N_( "The issuer certificate could not be found: this occurs if the issuer certificate of an untrusted certificate cannot be found." )
  251 + }
  252 + },
  253 +
  254 + {
  255 + .id = X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE,
  256 + .message = {
  257 + .type = LIB3270_NOTIFY_ERROR,
  258 + .icon = "security-low",
  259 + .summary = N_( "Unable to verify the first certificate" ),
  260 + .body = N_( "No signatures could be verified because the chain contains only one certificate and it is not self signed." )
  261 + }
  262 + },
  263 +
  264 + {
  265 + .id = X509_V_ERR_CERT_REVOKED,
  266 + .message = {
  267 + .type = LIB3270_NOTIFY_ERROR,
  268 + .icon = "security-low",
  269 + .summary = N_( "Certificate revoked" ),
  270 + .body = N_( "The certificate has been revoked." )
  271 + }
  272 + },
  273 +
  274 + {
  275 + .id = X509_V_ERR_INVALID_CA,
  276 + .message = {
  277 + .type = LIB3270_NOTIFY_ERROR,
  278 + .icon = "security-low",
  279 + .summary = N_( "Invalid CA certificate" ),
  280 + .body = N_( "A CA certificate is invalid. Either it is not a CA or its extensions are not consistent with the supplied purpose." )
  281 + }
  282 + },
  283 +
  284 + {
  285 + .id = X509_V_ERR_PATH_LENGTH_EXCEEDED,
  286 + .message = {
  287 + .type = LIB3270_NOTIFY_ERROR,
  288 + .icon = "dialog-error",
  289 + .summary = N_( "Path length constraint exceeded" ),
  290 + .body = N_( "The basicConstraints pathlength parameter has been exceeded." ),
  291 + }
  292 + },
  293 +
  294 + {
  295 + .id = X509_V_ERR_INVALID_PURPOSE,
  296 + .message = {
  297 + .type = LIB3270_NOTIFY_ERROR,
  298 + .icon = "dialog-error",
  299 + .summary = N_( "Unsupported certificate purpose" ),
  300 + .body = N_( "The supplied certificate cannot be used for the specified purpose." )
  301 + }
  302 + },
  303 +
  304 + {
  305 + .id = X509_V_ERR_CERT_UNTRUSTED,
  306 + .message = {
  307 + .type = LIB3270_NOTIFY_WARNING,
  308 + .icon = "security-low",
  309 + .summary = N_( "Certificate not trusted" ),
  310 + .body = N_( "The root CA is not marked as trusted for the specified purpose." )
  311 + }
  312 + },
  313 +
  314 + {
  315 + .id = X509_V_ERR_CERT_REJECTED,
  316 + .message = {
  317 + .type = LIB3270_NOTIFY_ERROR,
  318 + .icon = "security-low",
  319 + .summary = N_( "Certificate rejected" ),
  320 + .body = N_( "The root CA is marked to reject the specified purpose." )
  321 + }
  322 + },
  323 +
  324 + {
  325 + .id = X509_V_ERR_SUBJECT_ISSUER_MISMATCH,
  326 + .message = {
  327 + .type = LIB3270_NOTIFY_ERROR,
  328 + .icon = "security-low",
  329 + .summary = N_( "Subject issuer mismatch" ),
  330 + .body = N_( "The current candidate issuer certificate was rejected because its subject name did not match the issuer name of the current certificate. Only displayed when the -issuer_checks option is set." )
  331 + }
  332 + },
  333 +
  334 + {
  335 + .id = X509_V_ERR_AKID_SKID_MISMATCH,
  336 + .message = {
  337 + .type = LIB3270_NOTIFY_ERROR,
  338 + .icon = "dialog-error",
  339 + .summary = N_( "Authority and subject key identifier mismatch" ),
  340 + .body = N_( "The current candidate issuer certificate was rejected because its subject key identifier was present and did not match the authority key identifier current certificate. Only displayed when the -issuer_checks option is set." )
  341 + }
  342 + },
  343 +
  344 + {
  345 + .id = X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH,
  346 + .message = {
  347 + .type = LIB3270_NOTIFY_ERROR,
  348 + .icon = "dialog-error",
  349 + .summary = N_( "Authority and issuer serial number mismatch" ),
  350 + .body = N_( "The current candidate issuer certificate was rejected because its issuer name and serial number was present and did not match the authority key identifier of the current certificate. Only displayed when the -issuer_checks option is set." )
  351 + }
  352 + },
  353 +
  354 + {
  355 + .id = X509_V_ERR_KEYUSAGE_NO_CERTSIGN,
  356 + .message = {
  357 + .type = LIB3270_NOTIFY_ERROR,
  358 + .icon = "dialog-error",
  359 + .summary = N_( "Key usage does not include certificate signing" ),
  360 + .body = N_( "The current candidate issuer certificate was rejected because its keyUsage extension does not permit certificate signing." )
  361 + }
  362 + }
  363 +
  364 + };
  365 +
  366 + size_t ix;
  367 +
  368 + for(ix = 0; ix < (sizeof(messages)/sizeof(messages[0])); ix++) {
  369 +
  370 + if(messages[ix].id == id)
  371 + return &messages[ix].message;
  372 +
  373 + }
  374 +
  375 + return NULL;
  376 +}
src/network_modules/openssl/private.h
@@ -74,7 +74,6 @@ @@ -74,7 +74,6 @@
74 } crl; 74 } crl;
75 75
76 struct { 76 struct {
77 - const LIB3270_NETWORK_POPUP * popup; ///< @brief The active popup for the session.  
78 unsigned long error; ///< @brief The last OpenSSL error code. 77 unsigned long error; ///< @brief The last OpenSSL error code.
79 const char * message; ///< @brief The last OpenSSL state message. 78 const char * message; ///< @brief The last OpenSSL state message.
80 const char * alert; ///< @brief The last OpenSSL alert message. 79 const char * alert; ///< @brief The last OpenSSL alert message.
@@ -97,12 +96,22 @@ @@ -97,12 +96,22 @@
97 *ptr = NULL; 96 *ptr = NULL;
98 } 97 }
99 98
100 - LIB3270_INTERNAL SSL_CTX * lib3270_openssl_get_context(H3270 *hSession, LIB3270_NETWORK_STATE *state); 99 + static inline void lib3270_autoptr_cleanup_BIO(BIO **ptr) {
  100 + if(*ptr)
  101 + BIO_free_all(*ptr);
  102 + *ptr = NULL;
  103 + }
  104 +
  105 + LIB3270_INTERNAL SSL_CTX * lib3270_openssl_get_context(H3270 *hSession);
101 LIB3270_INTERNAL int lib3270_openssl_get_ex_index(H3270 *hSession); 106 LIB3270_INTERNAL int lib3270_openssl_get_ex_index(H3270 *hSession);
102 LIB3270_INTERNAL const LIB3270_NETWORK_POPUP * lib3270_openssl_get_popup_from_error_code(long id); 107 LIB3270_INTERNAL const LIB3270_NETWORK_POPUP * lib3270_openssl_get_popup_from_error_code(long id);
103 108
104 - LIB3270_INTERNAL int openssl_network_start_tls(H3270 *hSession, LIB3270_NETWORK_STATE *state); 109 + LIB3270_INTERNAL int openssl_network_start_tls(H3270 *hSession);
105 110
106 LIB3270_INTERNAL LIB3270_STRING_ARRAY * lib3270_openssl_get_crls_from_peer(H3270 *hSession, X509 *cert); 111 LIB3270_INTERNAL LIB3270_STRING_ARRAY * lib3270_openssl_get_crls_from_peer(H3270 *hSession, X509 *cert);
107 112
  113 + LIB3270_INTERNAL const LIB3270_SSL_MESSAGE * lib3270_openssl_message_from_id(long id);
  114 + LIB3270_INTERNAL void lib3270_openssl_crl_free(LIB3270_NET_CONTEXT *context);
  115 +
  116 +
108 #endif // !LIB3270_OPENSSL_MODULE_PRIVATE_H_INCLUDED 117 #endif // !LIB3270_OPENSSL_MODULE_PRIVATE_H_INCLUDED
src/network_modules/openssl/start.c
@@ -35,9 +35,62 @@ @@ -35,9 +35,62 @@
35 #include "private.h" 35 #include "private.h"
36 #include <lib3270/properties.h> 36 #include <lib3270/properties.h>
37 37
38 - int openssl_network_start_tls(H3270 *hSession, LIB3270_NETWORK_STATE *state) { 38 + static int import_crl(H3270 *hSession, SSL_CTX * ssl_ctx, LIB3270_NET_CONTEXT * context, const char *crl) {
39 39
40 - SSL_CTX * ctx_context = (SSL_CTX *) lib3270_openssl_get_context(hSession,state); 40 + X509_CRL * x509_crl = NULL;
  41 +
  42 + // Import CRL
  43 + {
  44 + lib3270_autoptr(BIO) bio = BIO_new_mem_buf(crl,-1);
  45 +
  46 + BIO * b64 = BIO_new(BIO_f_base64());
  47 + bio = BIO_push(b64, bio);
  48 +
  49 + BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
  50 +
  51 + if(!d2i_X509_CRL_bio(bio, &x509_crl)) {
  52 + trace_ssl(hSession,"Can't decode CRL data:\n%s\n",crl);
  53 + return -1;
  54 + }
  55 +
  56 + lib3270_openssl_crl_free(context);
  57 + context->crl.cert = x509_crl;
  58 +
  59 + }
  60 +
  61 + if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE)) {
  62 +
  63 + lib3270_autoptr(BIO) bio = BIO_new(BIO_s_mem());
  64 +
  65 + X509_CRL_print(bio,x509_crl);
  66 +
  67 + unsigned char *data = NULL;
  68 + int n = BIO_get_mem_data(bio, &data);
  69 +
  70 + lib3270_autoptr(char) text = (char *) lib3270_malloc(n+1);
  71 + memcpy(text,data,n);
  72 + text[n] ='\0';
  73 +
  74 + trace_ssl(hSession,"CRL Data:\n%s\n",text);
  75 +
  76 + }
  77 +
  78 + // Add CRL in the store.
  79 + X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx);
  80 +
  81 + if(X509_STORE_add_crl(store, x509_crl)) {
  82 + trace_ssl(hSession,"CRL was added to context cert store\n");
  83 + } else {
  84 + trace_ssl(hSession,"CRL was not added to context cert store\n");
  85 + }
  86 +
  87 + return 0;
  88 +
  89 + }
  90 +
  91 + int openssl_network_start_tls(H3270 *hSession) {
  92 +
  93 + SSL_CTX * ctx_context = (SSL_CTX *) lib3270_openssl_get_context(hSession);
41 if(!ctx_context) 94 if(!ctx_context)
42 return -1; 95 return -1;
43 96
@@ -45,16 +98,15 @@ @@ -45,16 +98,15 @@
45 98
46 debug("%s",__FUNCTION__); 99 debug("%s",__FUNCTION__);
47 100
48 - set_ssl_state(hSession,LIB3270_SSL_NEGOTIATING);  
49 context->con = SSL_new(ctx_context); 101 context->con = SSL_new(ctx_context);
50 if(context->con == NULL) 102 if(context->con == NULL)
51 { 103 {
52 - static const LIB3270_NETWORK_POPUP popup = { 104 + static const LIB3270_SSL_MESSAGE message = {
53 .type = LIB3270_NOTIFY_SECURE, 105 .type = LIB3270_NOTIFY_SECURE,
54 .summary = N_( "Cant create a new SSL structure for current connection." ) 106 .summary = N_( "Cant create a new SSL structure for current connection." )
55 }; 107 };
56 108
57 - state->popup = &popup; 109 + hSession->ssl.message = &message;
58 return -1; 110 return -1;
59 } 111 }
60 112
@@ -66,12 +118,12 @@ @@ -66,12 +118,12 @@
66 { 118 {
67 trace_ssl(hSession,"%s","SSL_set_fd failed!\n"); 119 trace_ssl(hSession,"%s","SSL_set_fd failed!\n");
68 120
69 - static const LIB3270_NETWORK_POPUP popup = { 121 + static const LIB3270_SSL_MESSAGE message = {
70 .summary = N_( "SSL negotiation failed" ), 122 .summary = N_( "SSL negotiation failed" ),
71 .body = N_( "Cant set the file descriptor for the input/output facility for the TLS/SSL (encrypted) side of ssl." ) 123 .body = N_( "Cant set the file descriptor for the input/output facility for the TLS/SSL (encrypted) side of ssl." )
72 }; 124 };
73 125
74 - state->popup = &popup; 126 + hSession->ssl.message = &message;
75 return -1; 127 return -1;
76 128
77 } 129 }
@@ -86,16 +138,17 @@ @@ -86,16 +138,17 @@
86 138
87 if(code == SSL_ERROR_SYSCALL && hSession->ssl.error) 139 if(code == SSL_ERROR_SYSCALL && hSession->ssl.error)
88 code = hSession->ssl.error; 140 code = hSession->ssl.error;
89 -  
90 - state->error_message = ERR_lib_error_string(code); 141 + else
  142 + hSession->ssl.error = code;
91 143
92 trace_ssl(hSession,"SSL_connect failed: %s\n",ERR_reason_error_string(code)); 144 trace_ssl(hSession,"SSL_connect failed: %s\n",ERR_reason_error_string(code));
93 145
94 - static const LIB3270_NETWORK_POPUP popup = { 146 + static const LIB3270_SSL_MESSAGE message = {
95 .summary = N_( "SSL Connect failed" ), 147 .summary = N_( "SSL Connect failed" ),
  148 + .body = N_("The client was unable to negotiate a secure connection with the host")
96 }; 149 };
97 150
98 - state->popup = &popup; 151 + hSession->ssl.message = &message;
99 return -1; 152 return -1;
100 153
101 } 154 }
@@ -131,23 +184,22 @@ @@ -131,23 +184,22 @@
131 // Do we really need to download a new CRL? 184 // Do we really need to download a new CRL?
132 if(lib3270_ssl_get_crl_download(hSession) && SSL_get_verify_result(context->con) == X509_V_ERR_UNABLE_TO_GET_CRL) { 185 if(lib3270_ssl_get_crl_download(hSession) && SSL_get_verify_result(context->con) == X509_V_ERR_UNABLE_TO_GET_CRL) {
133 186
134 - trace_ssl(hSession,"CRL Validation has failed, requesting download\n"); 187 + // CRL download is enabled and verification has failed; look for CRL file.
  188 + trace_ssl(hSession,"CRL Validation has failed, requesting CRL download\n");
135 189
136 lib3270_autoptr(char) crl_text = NULL; 190 lib3270_autoptr(char) crl_text = NULL;
137 if(context->crl.url) { 191 if(context->crl.url) {
138 192
139 // There's a pre-defined URL, use it. 193 // There's a pre-defined URL, use it.
140 - const LIB3270_POPUP * popup = NULL;  
141 - crl_text = lib3270_url_get(hSession, context->crl.url,&popup); 194 + const char *error_message = NULL;
  195 + crl_text = lib3270_url_get(hSession, context->crl.url,&error_message);
142 196
143 - if(popup) {  
144 - state->popup = popup;  
145 - trace_ssl(hSession,"Error downloading CRL from %s: %s\n",context->crl.url,popup->summary); 197 + if(error_message) {
  198 + trace_ssl(hSession,"Error downloading CRL from %s: %s\n",context->crl.url,error_message);
  199 + } else {
  200 + import_crl(hSession, ctx_context, context, crl_text);
146 } 201 }
147 202
148 -#ifndef DEBUG  
149 - #error TODO: Import crl_text;  
150 -#endif // DEBUG  
151 203
152 } else if(peer) { 204 } else if(peer) {
153 205
@@ -159,17 +211,15 @@ @@ -159,17 +211,15 @@
159 size_t ix; 211 size_t ix;
160 for(ix = 0; ix < uris->length; ix++) { 212 for(ix = 0; ix < uris->length; ix++) {
161 213
162 - LIB3270_POPUP * popup = NULL;  
163 - crl_text = lib3270_url_get(hSession, uris->str[ix], &popup); 214 + const char * error_message = NULL;
  215 + crl_text = lib3270_url_get(hSession, uris->str[ix], &error_message);
164 216
165 - if(popup) {  
166 - trace_ssl(hSession,"Error downloading CRL from %s: %s\n",uris[ix],popup->summary); 217 + if(error_message) {
  218 + trace_ssl(hSession,"Error downloading CRL from %s: %s\n",uris->str[ix],error_message);
  219 + } else if(!import_crl(hSession, ctx_context, context, crl_text)) {
  220 + break;
167 } 221 }
168 222
169 -#ifndef DEBUG  
170 - #error TODO: Import crl_text;  
171 -#endif // DEBUG  
172 -  
173 } 223 }
174 } 224 }
175 225
@@ -177,7 +227,74 @@ @@ -177,7 +227,74 @@
177 227
178 } 228 }
179 229
  230 + //
  231 + // Validate SSL state.
  232 + //
  233 + long verify_result = SSL_get_verify_result(context->con);
  234 +
  235 + const struct ssl_status_msg * msg = ssl_get_status_from_error_code(verify_result);
  236 + if(!msg) {
  237 +
  238 + trace_ssl(hSession,"Unexpected or invalid TLS/SSL verify result %d\n",verify_result);
  239 +
  240 + static const LIB3270_SSL_MESSAGE message = {
  241 + .type = LIB3270_NOTIFY_ERROR,
  242 + .icon = "dialog-error",
  243 + .summary = N_( "Invalid TLS/SSL verify result" ),
  244 + .body = N_( "The verification of the connection security status returned an unexpected value." )
  245 + };
  246 +
  247 + hSession->ssl.message = &message;
  248 + return EACCES;
  249 +
  250 + } else {
180 251
  252 + trace_ssl(hSession,"The TLS/SSL verify result was %d: %s\n",verify_result, msg);
  253 +
  254 + }
  255 +
  256 + // Get SSL Message
  257 + hSession->ssl.message = lib3270_openssl_message_from_id(verify_result);
  258 +
  259 + // Trace cypher
  260 + if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE))
  261 + {
  262 + char buffer[4096];
  263 + int alg_bits = 0;
  264 + const SSL_CIPHER * cipher = SSL_get_current_cipher(context->con);
  265 +
  266 + trace_ssl(hSession,"TLS/SSL cipher description: %s",SSL_CIPHER_description((SSL_CIPHER *) cipher, buffer, 4095));
  267 + SSL_CIPHER_get_bits(cipher, &alg_bits);
  268 + trace_ssl(hSession,"%s version %s with %d bits\n",
  269 + SSL_CIPHER_get_name(cipher),
  270 + SSL_CIPHER_get_version(cipher),
  271 + alg_bits);
  272 + }
  273 +
  274 + // Check results.
  275 + /*
  276 + switch(verify_result) {
  277 + case X509_V_OK:
  278 + trace_ssl(hSession,"TLS/SSL negotiated connection complete. Peer certificate %s presented.\n", peer ? "was" : "was not");
  279 + break;
  280 +
  281 +#ifdef SSL_ENABLE_SELF_SIGNED_CERT_CHECK
  282 + case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
  283 + trace_ssl(hSession,"TLS/SSL negotiated connection complete with self signed certificate in certificate chain\n");
  284 + set_ssl_state(hSession,LIB3270_SSL_NEGOTIATED);
  285 + return EACCES;
  286 +#endif
  287 +
  288 + default:
  289 + set_ssl_state(hSession,LIB3270_SSL_NEGOTIATED);
  290 + }
  291 + */
  292 +
  293 + if(hSession->ssl.message)
  294 + trace_ssl(hSession,"%s",hSession->ssl.message->summary);
  295 + else
  296 + trace_ssl(hSession,"TLS/SSL verify result was %ld\n", verify_result);
181 297
182 return 0; 298 return 0;
  299 +
183 } 300 }
src/network_modules/openssl/states.c
@@ -1,401 +0,0 @@ @@ -1,401 +0,0 @@
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 <lib3270/trace.h>  
34 -  
35 -#include <openssl/ssl.h>  
36 -#include <openssl/err.h>  
37 -  
38 -#include "private.h"  
39 -  
40 -/*--[ Implement ]------------------------------------------------------------------------------------*/  
41 -  
42 -static const LIB3270_NETWORK_POPUP popups[] =  
43 -{  
44 - // http://www.openssl.org/docs/apps/verify.html  
45 - {  
46 - .id = X509_V_OK,  
47 - .type = LIB3270_NOTIFY_SECURE,  
48 - .icon = "security-high",  
49 - .summary = N_( "Secure connection was successful." ),  
50 - .body = N_( "The connection is secure and the host identity was confirmed." )  
51 - },  
52 -  
53 - {  
54 - .id = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT,  
55 - .type = LIB3270_NOTIFY_ERROR,  
56 - .icon = "dialog-error",  
57 - .summary = N_( "Unable to get issuer certificate" ),  
58 - .body = N_( "The issuer certificate of a looked up certificate could not be found. This normally means the list of trusted certificates is not complete." )  
59 - },  
60 -  
61 - {  
62 - .id = X509_V_ERR_UNABLE_TO_GET_CRL,  
63 - .name = "X509_V_ERR_UNABLE_TO_GET_CRL",  
64 - .type = LIB3270_NOTIFY_ERROR,  
65 - .icon = "dialog-error",  
66 - .summary = N_( "Unable to get certificate CRL." ),  
67 - .body = N_( "The Certificate revocation list (CRL) of a certificate could not be found." )  
68 - },  
69 -  
70 - {  
71 - .id = X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE,  
72 - .type = LIB3270_NOTIFY_ERROR,  
73 - .icon = "dialog-error",  
74 - .summary = N_( "Unable to decrypt certificate's signature" ),  
75 - .body = N_( "The certificate signature could not be decrypted. This means that the actual signature value could not be determined rather than it not matching the expected value, this is only meaningful for RSA keys." )  
76 - },  
77 -  
78 - {  
79 - .id = X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE,  
80 - .type = LIB3270_NOTIFY_ERROR,  
81 - .icon = "dialog-error",  
82 - .summary = N_( "Unable to decrypt CRL's signature" ),  
83 - .body = N_( "The CRL signature could not be decrypted: this means that the actual signature value could not be determined rather than it not matching the expected value. Unused." )  
84 - },  
85 -  
86 - {  
87 - .id = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY,  
88 - .type = LIB3270_NOTIFY_ERROR,  
89 - .icon = "dialog-error",  
90 - .summary = N_( "Unable to decode issuer public key" ),  
91 - .body = N_( "The public key in the certificate SubjectPublicKeyInfo could not be read." )  
92 - },  
93 -  
94 - {  
95 - .id = X509_V_ERR_CERT_SIGNATURE_FAILURE,  
96 - .type = LIB3270_NOTIFY_ERROR,  
97 - .icon = "dialog-error",  
98 - .summary = N_( "Certificate signature failure" ),  
99 - .body = N_( "The signature of the certificate is invalid." )  
100 - },  
101 -  
102 - {  
103 - .id = X509_V_ERR_CRL_SIGNATURE_FAILURE,  
104 - .type = LIB3270_NOTIFY_ERROR,  
105 - .icon = "dialog-error",  
106 - .summary = N_( "CRL signature failure" ),  
107 - .body = N_( "The signature of the certificate is invalid." )  
108 - },  
109 -  
110 - {  
111 - .id = X509_V_ERR_CERT_NOT_YET_VALID,  
112 - .type = LIB3270_NOTIFY_WARNING,  
113 - .icon = "dialog-warning",  
114 - .summary = N_( "Certificate is not yet valid" ),  
115 - .body = N_( "The certificate is not yet valid: the notBefore date is after the current time." )  
116 - },  
117 -  
118 - {  
119 - .id = X509_V_ERR_CERT_HAS_EXPIRED,  
120 - .type = LIB3270_NOTIFY_ERROR,  
121 - .icon = "dialog-error",  
122 - .summary = N_( "Certificate has expired" ),  
123 - .body = N_( "The certificate has expired: that is the notAfter date is before the current time." )  
124 - },  
125 -  
126 - {  
127 - .id = X509_V_ERR_CRL_NOT_YET_VALID,  
128 - .type = LIB3270_NOTIFY_WARNING,  
129 - .icon = "dialog-error",  
130 - .summary = N_( "The CRL is not yet valid." ),  
131 - .body = N_( "The Certificate revocation list (CRL) is not yet valid." )  
132 - },  
133 -  
134 - {  
135 - .id = X509_V_ERR_CRL_HAS_EXPIRED,  
136 -#ifdef SSL_ENABLE_CRL_EXPIRATION_CHECK  
137 - .type = LIB3270_NOTIFY_ERROR,  
138 -#else  
139 - .type = LIB3270_NOTIFY_WARNING,  
140 -#endif // SSL_ENABLE_CRL_EXPIRATION_CHECK  
141 - .icon = "security-medium",  
142 - .summary = N_( "The CRL has expired." ),  
143 - .body = N_( "The Certificate revocation list (CRL) has expired.")  
144 - },  
145 -  
146 - {  
147 - .id = X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD,  
148 - .type = LIB3270_NOTIFY_ERROR,  
149 - .icon = "dialog-error",  
150 - .summary = N_( "Format error in certificate's notBefore field" ),  
151 - .body = N_( "The certificate notBefore field contains an invalid time." )  
152 - },  
153 -  
154 - {  
155 - .id = X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD,  
156 - .type = LIB3270_NOTIFY_ERROR,  
157 - .icon = "dialog-error",  
158 - .summary = N_( "Format error in certificate's notAfter field" ),  
159 - .body = N_( "The certificate notAfter field contains an invalid time." )  
160 - },  
161 -  
162 - {  
163 - .id = X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD,  
164 - .type = LIB3270_NOTIFY_ERROR,  
165 - .icon = "dialog-error",  
166 - .summary = N_( "Format error in CRL's lastUpdate field" ),  
167 - .body = N_( "The CRL lastUpdate field contains an invalid time." )  
168 - },  
169 -  
170 - {  
171 - .id = X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD,  
172 - .type = LIB3270_NOTIFY_ERROR,  
173 - .icon = "dialog-error",  
174 - .summary = N_( "Format error in CRL's nextUpdate field" ),  
175 - .body = N_( "The CRL nextUpdate field contains an invalid time." )  
176 - },  
177 -  
178 - {  
179 - .id = X509_V_ERR_OUT_OF_MEM,  
180 - .type = LIB3270_NOTIFY_ERROR,  
181 - .icon = "dialog-error",  
182 - .summary = N_( "Out of memory" ),  
183 - .body = N_( "An error occurred trying to allocate memory. This should never happen." )  
184 - },  
185 -  
186 - {  
187 - .id = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT,  
188 - .type = LIB3270_NOTIFY_WARNING,  
189 - .icon = "security-medium",  
190 - .summary = N_( "Self signed certificate" ),  
191 - .body = N_( "The passed certificate is self signed and the same certificate cannot be found in the list of trusted certificates." )  
192 - },  
193 -  
194 - {  
195 - .id = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN,  
196 -#ifdef SSL_ENABLE_SELF_SIGNED_CERT_CHECK  
197 - .type = LIB3270_NOTIFY_ERROR,  
198 -#else  
199 - .type = LIB3270_NOTIFY_WARNING,  
200 -#endif // SSL_ENABLE_SELF_SIGNED_CERT_CHECK  
201 - .icon = "security-medium",  
202 - .summary = N_( "Self signed certificate in certificate chain" ),  
203 - .body = N_( "The certificate chain could be built up using the untrusted certificates but the root could not be found locally." )  
204 - },  
205 -  
206 - {  
207 - .id = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY,  
208 - .type = LIB3270_NOTIFY_WARNING,  
209 - .icon = "security-low",  
210 - .summary = N_( "Unable to get local issuer certificate" ),  
211 - .body = N_( "The issuer certificate could not be found: this occurs if the issuer certificate of an untrusted certificate cannot be found." )  
212 - },  
213 -  
214 - {  
215 - .id = X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE,  
216 - .type = LIB3270_NOTIFY_ERROR,  
217 - .icon = "security-low",  
218 - .summary = N_( "Unable to verify the first certificate" ),  
219 - .body = N_( "No signatures could be verified because the chain contains only one certificate and it is not self signed." )  
220 - },  
221 -  
222 - {  
223 - .id = X509_V_ERR_CERT_REVOKED,  
224 - .type = LIB3270_NOTIFY_ERROR,  
225 - .icon = "security-low",  
226 - .summary = N_( "Certificate revoked" ),  
227 - .body = N_( "The certificate has been revoked." )  
228 - },  
229 -  
230 - {  
231 - .id = X509_V_ERR_INVALID_CA,  
232 - .type = LIB3270_NOTIFY_ERROR,  
233 - .icon = "security-low",  
234 - .summary = N_( "Invalid CA certificate" ),  
235 - .body = N_( "A CA certificate is invalid. Either it is not a CA or its extensions are not consistent with the supplied purpose." )  
236 - },  
237 -  
238 - {  
239 - .id = X509_V_ERR_PATH_LENGTH_EXCEEDED,  
240 - .type = LIB3270_NOTIFY_ERROR,  
241 - .icon = "dialog-error",  
242 - .summary = N_( "Path length constraint exceeded" ),  
243 - .body = N_( "The basicConstraints pathlength parameter has been exceeded." ),  
244 - },  
245 -  
246 - {  
247 - .id = X509_V_ERR_INVALID_PURPOSE,  
248 - .type = LIB3270_NOTIFY_ERROR,  
249 - .icon = "dialog-error",  
250 - .summary = N_( "Unsupported certificate purpose" ),  
251 - .body = N_( "The supplied certificate cannot be used for the specified purpose." )  
252 - },  
253 -  
254 - {  
255 - .id = X509_V_ERR_CERT_UNTRUSTED,  
256 - .type = LIB3270_NOTIFY_WARNING,  
257 - .icon = "security-low",  
258 - .summary = N_( "Certificate not trusted" ),  
259 - .body = N_( "The root CA is not marked as trusted for the specified purpose." )  
260 - },  
261 -  
262 - {  
263 - .id = X509_V_ERR_CERT_REJECTED,  
264 - .type = LIB3270_NOTIFY_ERROR,  
265 - .icon = "security-low",  
266 - .summary = N_( "Certificate rejected" ),  
267 - .body = N_( "The root CA is marked to reject the specified purpose." )  
268 - },  
269 -  
270 - {  
271 - .id = X509_V_ERR_SUBJECT_ISSUER_MISMATCH,  
272 - .type = LIB3270_NOTIFY_ERROR,  
273 - .icon = "security-low",  
274 - .summary = N_( "Subject issuer mismatch" ),  
275 - .body = N_( "The current candidate issuer certificate was rejected because its subject name did not match the issuer name of the current certificate. Only displayed when the -issuer_checks option is set." )  
276 - },  
277 -  
278 - {  
279 - .id = X509_V_ERR_AKID_SKID_MISMATCH,  
280 - .type = LIB3270_NOTIFY_ERROR,  
281 - .icon = "dialog-error",  
282 - .summary = N_( "Authority and subject key identifier mismatch" ),  
283 - .body = N_( "The current candidate issuer certificate was rejected because its subject key identifier was present and did not match the authority key identifier current certificate. Only displayed when the -issuer_checks option is set." )  
284 - },  
285 -  
286 - {  
287 - .id = X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH,  
288 - .type = LIB3270_NOTIFY_ERROR,  
289 - .icon = "dialog-error",  
290 - .summary = N_( "Authority and issuer serial number mismatch" ),  
291 - .body = N_( "The current candidate issuer certificate was rejected because its issuer name and serial number was present and did not match the authority key identifier of the current certificate. Only displayed when the -issuer_checks option is set." )  
292 - },  
293 -  
294 - {  
295 - .id = X509_V_ERR_KEYUSAGE_NO_CERTSIGN,  
296 - .type = LIB3270_NOTIFY_ERROR,  
297 - .icon = "dialog-error",  
298 - .summary = N_( "Key usage does not include certificate signing" ),  
299 - .body = N_( "The current candidate issuer certificate was rejected because its keyUsage extension does not permit certificate signing." )  
300 - }  
301 -  
302 - };  
303 -  
304 - const LIB3270_NETWORK_POPUP * lib3270_openssl_get_popup_from_error_code(long id)  
305 - {  
306 - size_t f;  
307 -  
308 - for(f=0;f < (sizeof(popups)/sizeof(popups[0]));f++)  
309 - {  
310 - if(popups[f].id == id)  
311 - return popups+f;  
312 - }  
313 - return NULL;  
314 - }  
315 -  
316 - /*  
317 - static const struct LIB3270_NETWORK_POPUP * get_ssl_status_msg(const H3270 *hSession)  
318 - {  
319 - return openssl_get_status_from_error_code(lib3270_get_SSL_verify_result(hSession));  
320 - }  
321 - */  
322 -  
323 - /*  
324 - const char * lib3270_get_ssl_state_message(const H3270 *hSession)  
325 - {  
326 - if(lib3270_get_ssl_state(hSession) != LIB3270_SSL_UNSECURE)  
327 - {  
328 - const struct ssl_status_msg *info = get_ssl_status_msg(hSession);  
329 - if(info)  
330 - return gettext(info->summary);  
331 - }  
332 -  
333 - return _( "The connection is insecure" );  
334 -  
335 - }  
336 -  
337 - const char * lib3270_get_ssl_state_icon_name(const H3270 *hSession)  
338 - {  
339 - if(lib3270_get_ssl_state(hSession) != LIB3270_SSL_UNSECURE)  
340 - {  
341 - const struct ssl_status_msg *info = get_ssl_status_msg(hSession);  
342 - if(info)  
343 - return info->iconName;  
344 - }  
345 -  
346 - return "dialog-error";  
347 -  
348 - }  
349 -  
350 -  
351 - const char * lib3270_get_ssl_state_description(const H3270 *hSession)  
352 - {  
353 - if(lib3270_get_ssl_state(hSession) != LIB3270_SSL_UNSECURE)  
354 - {  
355 - const struct ssl_status_msg *info = get_ssl_status_msg(hSession);  
356 - if(info)  
357 - return gettext(info->body);  
358 - }  
359 - else  
360 - {  
361 - return _( "The connection is insecure" );  
362 - }  
363 -  
364 - return _( "Unexpected or unknown security status");  
365 - }  
366 -  
367 - LIB3270_NOTIFY lib3270_get_ssl_state_icon(const H3270 *hSession)  
368 - {  
369 - if(lib3270_get_ssl_state(hSession) != LIB3270_SSL_UNSECURE)  
370 - {  
371 - const struct ssl_status_msg *info = get_ssl_status_msg(hSession);  
372 - if(info)  
373 - return info->type;  
374 - }  
375 -  
376 - return LIB3270_NOTIFY_ERROR;  
377 - }  
378 -  
379 -#else  
380 -  
381 - const char * lib3270_get_ssl_state_message(const H3270 *hSession)  
382 - {  
383 - return lib3270_get_hostname(hSession);  
384 - }  
385 -  
386 - const char * lib3270_get_ssl_state_description(const H3270 *hSession)  
387 - {  
388 - return _( "The connection is insecure" );  
389 - }  
390 -  
391 - LIB3270_NOTIFY lib3270_get_ssl_state_icon(const H3270 *hSession)  
392 - {  
393 - return LIB3270_NOTIFY_ERROR;  
394 - }  
395 -  
396 - const char * lib3270_get_ssl_state_icon_name(const H3270 *hSession)  
397 - {  
398 - return "dialog-error";  
399 - }  
400 -*/  
401 -  
src/ssl/properties.c
@@ -148,7 +148,7 @@ LIB3270_EXPORT char * lib3270_get_ssl_peer_certificate_text(const H3270 *hSessio @@ -148,7 +148,7 @@ LIB3270_EXPORT char * lib3270_get_ssl_peer_certificate_text(const H3270 *hSessio
148 148
149 FAIL_IF_ONLINE(hSession); 149 FAIL_IF_ONLINE(hSession);
150 150
151 -#if defined(HAVE_LIBSS) && defined(SSL_ENABLE_CRL_CHECK) 151 +#if defined(HAVE_LIBSSLx) && defined(SSL_ENABLE_CRL_CHECK)
152 152
153 if(hSession->ssl.crl.url) 153 if(hSession->ssl.crl.url)
154 { 154 {