Commit 2d1bf4c85b5dba50677cc6c4f8b855822577bb15

Authored by Perry Werneck
1 parent 3b32273a

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

lib3270.cbp
... ... @@ -128,12 +128,16 @@
128 128 <Unit filename="src/core/linux/curl.c">
129 129 <Option compilerVar="CC" />
130 130 </Unit>
  131 + <Unit filename="src/core/linux/download.c">
  132 + <Option compilerVar="CC" />
  133 + </Unit>
131 134 <Unit filename="src/core/linux/event_dispatcher.c">
132 135 <Option compilerVar="CC" />
133 136 </Unit>
134 137 <Unit filename="src/core/linux/log.c">
135 138 <Option compilerVar="CC" />
136 139 </Unit>
  140 + <Unit filename="src/core/linux/private.h" />
137 141 <Unit filename="src/core/linux/util.c">
138 142 <Option compilerVar="CC" />
139 143 </Unit>
... ... @@ -320,11 +324,11 @@
320 324 <Unit filename="src/network_modules/openssl/main.c">
321 325 <Option compilerVar="CC" />
322 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 328 <Option compilerVar="CC" />
326 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 332 <Option compilerVar="CC" />
329 333 </Unit>
330 334 <Unit filename="src/network_modules/select.c">
... ...
src/core/connect.c
... ... @@ -138,31 +138,72 @@
138 138  
139 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 144 non_blocking(hSession,False);
147 145  
148   - rc = lib3270_run_task(
  146 + int rc = lib3270_run_task(
149 147 hSession,
150 148 (int(*)(H3270 *h, void *)) hSession->network.module->start_tls,
151   - &state
  149 + NULL
152 150 );
153 151  
154 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 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 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 168 lib3270_write_event_trace(hSession,"Getting data from %s",url);
169 169  
170 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 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 179 if(!hCurl)
180 180 {
181   - *error_message= _( "Can't initialize curl operation" );
182   - errno = EINVAL;
  181 + *error = _( "Can't initialize curl operation" );
183 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 187 curl_easy_setopt(hCurl, CURLOPT_URL, url);
189 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 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 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 198 {
200 199 curl_easy_setopt(hCurl, CURLOPT_VERBOSE, 1L);
201 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 204 res = curl_easy_perform(hCurl);
206 205  
207 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 214 errno = EINVAL;
216 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 223 return httpText;
228 224  
... ...
src/core/linux/download.c 0 → 100644
... ... @@ -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 @@
  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 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 71 /// @brief Pop up an error dialog.
49 72 void popup_an_error(H3270 *hSession, const char *fmt, ...)
50 73 {
... ...
src/core/util.c
... ... @@ -39,6 +39,8 @@
39 39 #include "popupsc.h"
40 40 #include <lib3270/selection.h>
41 41 #include <lib3270/log.h>
  42 +#include <sys/stat.h>
  43 +#include <fcntl.h>
42 44  
43 45 #if defined(HAVE_LIBSSL)
44 46 #include <openssl/opensslv.h>
... ... @@ -50,9 +52,7 @@
50 52  
51 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 56 char * lib3270_vsprintf(const char *fmt, va_list args)
57 57 {
58 58 char *r = NULL;
... ... @@ -119,34 +119,6 @@ char * xs_buffer(const char *fmt, ...)
119 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 123 * @brief Expands a character in the manner of "cat -v".
152 124 */
... ... @@ -176,124 +148,6 @@ ctl_see(int c)
176 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 151 LIB3270_EXPORT void * lib3270_free(void *p)
298 152 {
299 153 if(p)
... ... @@ -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 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 484 LIB3270_EXPORT const char * lib3270_get_translation_domain() {
661 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 683  
684 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 690 } ssl;
690 691  
691 692 /// @brief Event Listeners.
... ... @@ -835,14 +836,24 @@ LIB3270_INTERNAL void set_ssl_state(H3270 *session, LIB3270_SSL_STATE state);
835 836  
836 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 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 858 /// @brief Fire CState change.
848 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 870 ///
860 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 39 #include <sys/socket.h>
40 40 #endif // _WIN32
41 41  
42   -#ifdef HAVE_LIBSSL
43   - #include <openssl/ssl.h>
44   -#endif // HAVE_LIBSSL
45   -
46 42 #include <lib3270/popup.h>
47 43 #include <lib3270/toggle.h>
48 44  
... ...
src/include/networking.h
... ... @@ -37,6 +37,11 @@
37 37 typedef struct _lib3270_network_popup LIB3270_NETWORK_POPUP;
38 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 45 typedef struct lib3270_network_state {
41 46  
42 47 int syserror; ///< @brief System error (errno)
... ... @@ -46,7 +51,7 @@
46 51  
47 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 56 } LIB3270_NETWORK_STATE;
52 57  
... ... @@ -63,7 +68,7 @@
63 68 /// @param hSession TN3270 session.
64 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 73 /// @brief Deinitialize network module.
69 74 ///
... ... @@ -87,7 +92,16 @@
87 92 ///
88 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 106 /// @brief Send on network context.
93 107 ///
... ... @@ -158,7 +172,7 @@
158 172 */
159 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 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 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 253 if(hSession->ssl.host) {
254 254  
255 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 258 if(!rc)
259   - rc = hSession->network.module->start_tls(hSession,msg);
  259 + rc = hSession->network.module->start_tls(hSession);
260 260  
261 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 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 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 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 159 context = SSL_CTX_new(SSLv23_method());
160 160 if(context == NULL)
161 161 {
162   - static const LIB3270_NETWORK_POPUP popup = {
  162 + static const LIB3270_SSL_MESSAGE message = {
163 163 .type = LIB3270_NOTIFY_SECURE,
164 164 .icon = "dialog-error",
165 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 169 hSession->network.context->state.error = ERR_get_error();
170 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 62  
63 63 GENERAL_NAMES *gens = dp->distpoint->name.fullname;
64 64  
65   - size_t i;
  65 + int i;
66 66 for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
67 67 int gtype;
68 68 GENERAL_NAME *gen = sk_GENERAL_NAME_value(gens, i);
... ...
src/network_modules/openssl/main.c
... ... @@ -35,13 +35,6 @@
35 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 38 static void openssl_network_finalize(H3270 *hSession) {
46 39  
47 40 debug("%s",__FUNCTION__);
... ... @@ -51,7 +44,7 @@ static void openssl_network_finalize(H3270 *hSession) {
51 44 // Cleanupp
52 45 LIB3270_NET_CONTEXT *context = hSession->network.context;
53 46  
54   - crl_free(context);
  47 + lib3270_openssl_crl_free(context);
55 48  
56 49 // Release network context.
57 50 lib3270_free(hSession->network.context);
... ... @@ -115,11 +108,11 @@ static int openssl_network_setsockopt(H3270 *hSession, int level, int optname, c
115 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 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 116 if(!ctx_context)
124 117 return -1;
125 118  
... ... @@ -214,14 +207,22 @@ void lib3270_set_openssl_network_module(H3270 *hSession) {
214 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 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 216 hSession->network.context->sock = sock;
224 217  
225 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 @@
  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 74 } crl;
75 75  
76 76 struct {
77   - const LIB3270_NETWORK_POPUP * popup; ///< @brief The active popup for the session.
78 77 unsigned long error; ///< @brief The last OpenSSL error code.
79 78 const char * message; ///< @brief The last OpenSSL state message.
80 79 const char * alert; ///< @brief The last OpenSSL alert message.
... ... @@ -97,12 +96,22 @@
97 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 106 LIB3270_INTERNAL int lib3270_openssl_get_ex_index(H3270 *hSession);
102 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 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 117 #endif // !LIB3270_OPENSSL_MODULE_PRIVATE_H_INCLUDED
... ...
src/network_modules/openssl/start.c
... ... @@ -35,9 +35,62 @@
35 35 #include "private.h"
36 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 94 if(!ctx_context)
42 95 return -1;
43 96  
... ... @@ -45,16 +98,15 @@
45 98  
46 99 debug("%s",__FUNCTION__);
47 100  
48   - set_ssl_state(hSession,LIB3270_SSL_NEGOTIATING);
49 101 context->con = SSL_new(ctx_context);
50 102 if(context->con == NULL)
51 103 {
52   - static const LIB3270_NETWORK_POPUP popup = {
  104 + static const LIB3270_SSL_MESSAGE message = {
53 105 .type = LIB3270_NOTIFY_SECURE,
54 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 110 return -1;
59 111 }
60 112  
... ... @@ -66,12 +118,12 @@
66 118 {
67 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 122 .summary = N_( "SSL negotiation failed" ),
71 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 127 return -1;
76 128  
77 129 }
... ... @@ -86,16 +138,17 @@
86 138  
87 139 if(code == SSL_ERROR_SYSCALL && hSession->ssl.error)
88 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 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 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 152 return -1;
100 153  
101 154 }
... ... @@ -131,23 +184,22 @@
131 184 // Do we really need to download a new CRL?
132 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 190 lib3270_autoptr(char) crl_text = NULL;
137 191 if(context->crl.url) {
138 192  
139 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 204 } else if(peer) {
153 205  
... ... @@ -159,17 +211,15 @@
159 211 size_t ix;
160 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 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 298 return 0;
  299 +
183 300 }
... ...
src/network_modules/openssl/states.c
... ... @@ -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 148  
149 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 153 if(hSession->ssl.crl.url)
154 154 {
... ...