Commit 5f352dbad225e9e417112c354176607d8a49a672

Authored by Perry Werneck
1 parent 99a99f76

Adding callback to let the application (or user) to decide if the

connection will continue on SSL error.
lib3270.cbp
... ... @@ -194,7 +194,6 @@
194 194 <Unit filename="src/include/icmdc.h" />
195 195 <Unit filename="src/include/keypadc.h" />
196 196 <Unit filename="src/include/kybdc.h" />
197   - <Unit filename="src/include/lib3270++.h" />
198 197 <Unit filename="src/include/lib3270-internals.h" />
199 198 <Unit filename="src/include/lib3270.h" />
200 199 <Unit filename="src/include/lib3270/X11keysym.h" />
... ...
src/core/connect.c
... ... @@ -33,6 +33,7 @@
33 33 #include <errno.h>
34 34 #include <lib3270/log.h>
35 35 #include <lib3270/trace.h>
  36 +#include <trace_dsc.h>
36 37  
37 38 #if defined(HAVE_LIBSSL)
38 39 #include <openssl/err.h>
... ... @@ -54,10 +55,123 @@
54 55 }
55 56  
56 57 #ifdef SSL_ENABLE_CRL_CHECK
57   -static int background_ssl_crl_check(H3270 *hSession, void *ssl_error)
  58 +static int background_ssl_crl_get(H3270 *hSession, void *ssl_error)
58 59 {
59   - return lib3270_check_X509_crl(hSession, (SSL_ERROR_MESSAGE *) ssl_error);
  60 + if(ssl_ctx_init(hSession, (SSL_ERROR_MESSAGE *) ssl_error)) {
  61 + return -1;
  62 + }
  63 +
  64 + // Do I have X509 CRL?
  65 + if(hSession->ssl.crl.cert)
  66 + {
  67 + // Ok, have it. Is it valid?
  68 +
  69 + // https://stackoverflow.com/questions/23407376/testing-x509-certificate-expiry-date-with-c
  70 + // X509_CRL_get_nextUpdate is deprecated in openssl 1.1.0
  71 + #if OPENSSL_VERSION_NUMBER < 0x10100000L
  72 + const ASN1_TIME * next_update = X509_CRL_get_nextUpdate(hSession->ssl.crl.cert);
  73 + #else
  74 + const ASN1_TIME * next_update = X509_CRL_get0_nextUpdate(hSession->ssl.crl.cert);
  75 + #endif
  76 +
  77 + if(X509_cmp_current_time(next_update) == 1)
  78 + {
  79 + int day, sec;
  80 + if(ASN1_TIME_diff(&day, &sec, NULL, next_update))
  81 + {
  82 + trace_ssl(hSession,"CRL Certificate is valid for %d day(s) and %d second(s)\n",day,sec);
  83 + return 0;
  84 + }
  85 + else
  86 + {
  87 + trace_ssl(hSession,"Can't get CRL next update, releasing it\n");
  88 + }
  89 +
  90 + }
  91 + else
  92 + {
  93 + trace_ssl(hSession,"CRL Certificate is no longer valid\n");
  94 + }
  95 +
  96 + // Certificate is no longer valid, release it.
  97 + X509_CRL_free(hSession->ssl.crl.cert);
  98 + hSession->ssl.crl.cert = NULL;
  99 +
  100 + }
  101 +
  102 + //
  103 + // Get CRL
  104 + //
  105 + // https://stackoverflow.com/questions/10510850/how-to-verify-the-certificate-for-the-ongoing-ssl-session
  106 + //
  107 + trace_ssl(hSession,"Getting CRL from %s\n",lib3270_get_crl_url(hSession));
  108 +
  109 + hSession->ssl.crl.cert = lib3270_get_crl(hSession,(SSL_ERROR_MESSAGE *) ssl_error,lib3270_get_crl_url(hSession));
  110 + if(hSession->ssl.crl.cert)
  111 + {
  112 + // Got CRL, add it to ssl store
  113 + if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE))
  114 + {
  115 + lib3270_autoptr(char) text = lib3270_get_ssl_crl_text(hSession);
  116 +
  117 + if(text)
  118 + trace_ssl(hSession,"\n%s\n",text);
  119 +
  120 + }
  121 +
  122 + // Add CRL in the store.
  123 + X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx);
  124 + if(X509_STORE_add_crl(store, hSession->ssl.crl.cert))
  125 + {
  126 + trace_ssl(hSession,"CRL was added to cert store\n");
  127 + }
  128 + else
  129 + {
  130 + trace_ssl(hSession,"CRL was not added to cert store\n");
  131 + }
  132 +
  133 +
  134 + }
  135 +
  136 + return 0;
  137 +
60 138 }
  139 +
  140 +static int notify_crl_error(H3270 *hSession, int rc, const SSL_ERROR_MESSAGE *message)
  141 +{
  142 + lib3270_write_log(
  143 + hSession,
  144 + "SSL-CRL-GET",
  145 + "CRL GET error: %s (rc=%d ssl_error=%d)",
  146 + message->title,
  147 + rc,
  148 + message->error
  149 + );
  150 +
  151 + if(message->description)
  152 + {
  153 + lib3270_write_log(hSession,"SSL-CRL-GET","%s",message->description);
  154 +
  155 + if(hSession->cbk.popup_ssl_error(hSession,rc,message->title,message->text,message->description))
  156 + return rc;
  157 + }
  158 + else if(message->error)
  159 + {
  160 + lib3270_autoptr(char) formatted_error = lib3270_strdup_printf(_( "%s (SSL error %d)" ),ERR_reason_error_string(message->error),message->error);
  161 + lib3270_write_log(hSession,"SSL-CRL-GET","%s",formatted_error);
  162 +
  163 + if(hSession->cbk.popup_ssl_error(hSession,rc,message->title,message->text,formatted_error))
  164 + return rc;
  165 + }
  166 + else
  167 + {
  168 + if(hSession->cbk.popup_ssl_error(hSession,rc,message->title,message->text,""))
  169 + return rc;
  170 + }
  171 +
  172 + return 0;
  173 +}
  174 +
61 175 #endif // SSL_ENABLE_CRL_CHECK
62 176  
63 177 int lib3270_reconnect(H3270 *hSession, int seconds)
... ... @@ -93,44 +207,18 @@ static int background_ssl_crl_check(H3270 *hSession, void *ssl_error)
93 207 }
94 208  
95 209 #ifdef SSL_ENABLE_CRL_CHECK
  210 +
96 211 SSL_ERROR_MESSAGE ssl_error;
97 212 memset(&ssl_error,0,sizeof(ssl_error));
98 213  
99 214 set_ssl_state(hSession,LIB3270_SSL_NEGOTIATING);
100   - int rc = lib3270_run_task(hSession, background_ssl_crl_check, &ssl_error);
  215 + int rc = lib3270_run_task(hSession, background_ssl_crl_get, &ssl_error);
101 216  
102 217 debug("CRL check returns %d",rc);
103 218  
104   - if(rc)
105   - {
106   - lib3270_write_log(
107   - hSession,
108   - "SSL-CRL-CHECK",
109   - "CRL Check error: %s (rc=%d ssl_error=%d)",
110   - ssl_error.title,
111   - rc,
112   - ssl_error.error
113   - );
114   -
115   - if(ssl_error.description)
116   - {
117   - lib3270_write_log(hSession,"SSL-CRL-CHECK","%s",ssl_error.description);
118   - lib3270_popup_dialog(hSession, LIB3270_NOTIFY_ERROR, ssl_error.title, ssl_error.text, "%s", ssl_error.description);
119   - }
120   - else if(ssl_error.error)
121   - {
122   - lib3270_autoptr(char) formatted_error = lib3270_strdup_printf("%s (SSL error %d)",ERR_reason_error_string(ssl_error.error),ssl_error.error);
123   - lib3270_write_log(hSession,"SSL-CRL-CHECK","%s",formatted_error);
124   - lib3270_popup_dialog(hSession, LIB3270_NOTIFY_ERROR, ssl_error.title, ssl_error.text, "%s", formatted_error);
125   - }
126   - else
127   - {
128   - lib3270_popup_dialog(hSession, LIB3270_NOTIFY_ERROR, ssl_error.title, ssl_error.text, "%s","");
129   - }
130   -
131   - // return errno = rc;
  219 + if(rc && notify_crl_error(hSession, rc,&ssl_error))
  220 + return errno = rc;
132 221  
133   - }
134 222 #endif // SSL_ENABLE_CRL_CHECK
135 223  
136 224 #if defined(HAVE_LIBSSL)
... ...
src/core/session.c
... ... @@ -224,6 +224,12 @@ static void def_popup(H3270 *session, LIB3270_NOTIFY GNUC_UNUSED(type), const ch
224 224 #endif // ANDROID
225 225 }
226 226  
  227 +static int def_popup_ssl_error(H3270 *session, int GNUC_UNUSED(rc), const char *title, const char *summary, const char *body)
  228 +{
  229 + lib3270_popup_dialog(session, LIB3270_NOTIFY_ERROR, title, summary, "%s", body);
  230 + return -1;
  231 +}
  232 +
227 233 static void def_trace(H3270 GNUC_UNUSED(*session), void GNUC_UNUSED(*userdata), const char *fmt, va_list args)
228 234 {
229 235 vfprintf(stdout,fmt,args);
... ... @@ -287,6 +293,7 @@ void lib3270_reset_callbacks(H3270 *hSession)
287 293 hSession->cbk.cursor = set_cursor;
288 294 hSession->cbk.message = message;
289 295 hSession->cbk.popup = def_popup;
  296 + hSession->cbk.popup_ssl_error = def_popup_ssl_error;
290 297 hSession->cbk.update_ssl = update_ssl;
291 298 hSession->cbk.display = screen_disp;
292 299 hSession->cbk.set_width = nop_int;
... ...
src/include/lib3270-internals.h
... ... @@ -773,7 +773,6 @@ LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on);
773 773  
774 774 #ifdef SSL_ENABLE_CRL_CHECK
775 775 LIB3270_INTERNAL X509_CRL * lib3270_get_crl(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *url);
776   - LIB3270_INTERNAL int lib3270_check_X509_crl(H3270 *hSession, SSL_ERROR_MESSAGE * message);
777 776 #endif // SSL_ENABLE_CRL_CHECK
778 777  
779 778 /// @brief Clear element at adress.
... ...
src/include/lib3270/session.h
... ... @@ -78,6 +78,7 @@
78 78  
79 79 void (*message)(H3270 *session, LIB3270_NOTIFY id , const char *title, const char *message, const char *text);
80 80 void (*popup)(H3270 *session, LIB3270_NOTIFY id, const char *title, const char *msg, const char *fmt, va_list);
  81 + int (*popup_ssl_error)(H3270 *session, int rc, const char *title, const char *summary, const char *body);
81 82  
82 83 #ifdef HAVE_LIBSSL
83 84 void (*set_peer_certificate)(const X509 *cert);
... ...
src/ssl/ctx_init.c
... ... @@ -63,8 +63,6 @@
63 63  
64 64 /*--[ Implement ]------------------------------------------------------------------------------------*/
65 65  
66   -#ifdef SSL_ENABLE_CRL_CHECK
67   -
68 66 /*
69 67 #pragma GCC diagnostic push
70 68 #pragma GCC diagnostic ignored "-Wsequence-point"
... ... @@ -101,85 +99,6 @@ static time_t ASN1_GetTimeT(const ASN1_TIME* time)
101 99 #pragma GCC diagnostic pop
102 100 */
103 101  
104   -int lib3270_check_X509_crl(H3270 *hSession, SSL_ERROR_MESSAGE * message)
105   -{
106   - // Returns if don't have an SSL context.
107   - if(!ssl_ctx)
108   - {
109   - trace("No SSL context %s will return %d",__FUNCTION__,0);
110   - return 0;
111   - }
112   -
113   - // Do I have X509 CRL? Is it valid?
114   - if(hSession->ssl.crl.cert)
115   - {
116   -
117   - // https://stackoverflow.com/questions/23407376/testing-x509-certificate-expiry-date-with-c
118   - // X509_CRL_get_nextUpdate is deprecated in openssl 1.1.0
119   - #if OPENSSL_VERSION_NUMBER < 0x10100000L
120   - const ASN1_TIME * next_update = X509_CRL_get_nextUpdate(hSession->ssl.crl.cert);
121   - #else
122   - const ASN1_TIME * next_update = X509_CRL_get0_nextUpdate(hSession->ssl.crl.cert);
123   - #endif
124   -
125   - if(X509_cmp_current_time(next_update) == 1)
126   - {
127   - int day, sec;
128   - if(ASN1_TIME_diff(&day, &sec, NULL, next_update))
129   - {
130   - trace_ssl(hSession,"CRL Certificate is valid for %d day(s) and %d second(s)\n",day,sec);
131   - return 0;
132   - }
133   - else
134   - {
135   - trace_ssl(hSession,"Can't get CRL next update\n");
136   - }
137   -
138   - }
139   -
140   - // Certificate is no longer valid, release it.
141   - trace_ssl(hSession,"CRL Certificate is no longer valid\n");
142   -
143   - X509_CRL_free(hSession->ssl.crl.cert);
144   - hSession->ssl.crl.cert = NULL;
145   -
146   - }
147   -
148   - //
149   - // Set up CRL validation
150   - //
151   - // https://stackoverflow.com/questions/10510850/how-to-verify-the-certificate-for-the-ongoing-ssl-session
152   - //
153   - hSession->ssl.crl.cert = lib3270_get_crl(hSession,message,lib3270_get_crl_url(hSession));
154   - if(!hSession->ssl.crl.cert)
155   - {
156   - return -1;
157   - }
158   -
159   - if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE))
160   - {
161   - lib3270_autoptr(char) text = lib3270_get_ssl_crl_text(hSession);
162   -
163   - if(text)
164   - trace_ssl(hSession,"\n%s\n",text);
165   -
166   - }
167   -
168   - // Add CRL in the store.
169   - X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx);
170   - if(X509_STORE_add_crl(store, hSession->ssl.crl.cert))
171   - {
172   - trace_ssl(hSession,"CRL was added to cert store\n");
173   - return 0;
174   - }
175   -
176   - trace_ssl(hSession,"CRL was not added to cert store\n");
177   -
178   - return -1;
179   -}
180   -#endif // SSL_ENABLE_CRL_CHECK
181   -
182   -
183 102 /**
184 103 * @brief Initialize openssl library.
185 104 *
... ... @@ -251,11 +170,10 @@ int ssl_ctx_init(H3270 *hSession, SSL_ERROR_MESSAGE * message)
251 170 X509_VERIFY_PARAM_free(param);
252 171 trace_ssl(hSession,"CRL CHECK was enabled\n");
253 172  
254   - return lib3270_check_X509_crl(hSession,message);
255   -#else
256   - return 0;
257 173 #endif // SSL_ENABLE_CRL_CHECK
258 174  
  175 + return 0;
  176 +
259 177 }
260 178  
261 179 #endif // HAVE_LIBSSL
... ...
src/testprogram/testprogram.c
... ... @@ -5,6 +5,7 @@
5 5 #include <getopt.h>
6 6  
7 7 #include <lib3270.h>
  8 +#include <lib3270-internals.h>
8 9 #include <lib3270/actions.h>
9 10 #include <lib3270/trace.h>
10 11  
... ... @@ -12,7 +13,7 @@
12 13  
13 14 const char *trace_file = "test.trace";
14 15  
15   -static void write_trace(H3270 *session, void *userdata, const char *fmt, va_list args)
  16 +static void write_trace(H3270 GNUC_UNUSED(*session), void GNUC_UNUSED(*userdata), const char *fmt, va_list args)
16 17 {
17 18 FILE *out = fopen(trace_file,"a");
18 19 if(out)
... ...