Commit 2d1bf4c85b5dba50677cc6c4f8b855822577bb15
1 parent
3b32273a
Exists in
master
and in
3 other branches
Refactoring network and TLS/SSL engine to a modular way.
Showing
19 changed files
with
866 additions
and
698 deletions
Show diff stats
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 | ... | ... |
... | ... | @@ -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 | + } | ... | ... |
... | ... | @@ -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
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 | + | ... | ... |
... | ... | @@ -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 | { | ... | ... |