Commit 5f352dbad225e9e417112c354176607d8a49a672
1 parent
99a99f76
Exists in
master
and in
3 other branches
Adding callback to let the application (or user) to decide if the
connection will continue on SSL error.
Showing
7 changed files
with
132 additions
and
119 deletions
Show diff stats
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) | ... | ... |