diff --git a/configure.ac b/configure.ac
index 34b652b..7bbf964 100644
--- a/configure.ac
+++ b/configure.ac
@@ -332,18 +332,6 @@ if test "$app_cv_self_signed_certs" == "yes"; then
AC_DEFINE(SSL_ALLOW_SELF_SIGNED_CERT)
fi
-dnl AC_ARG_WITH([ssl-crl-check],
-dnl [AS_HELP_STRING([--with-ssl-crl-check], [enable validation of the certificate revogation list in TN3270S connections])],
-dnl [
-dnl app_cv_enable_crl_check="$withval"
-dnl ],[
-dnl app_cv_enable_crl_check="no"
-dnl ])
-dnl
-dnl if test "$app_cv_enable_crl_check" == "yes"; then
-dnl AC_DEFINE(SSL_ENABLE_CRL_CHECK)
-dnl fi
-
dnl ---------------------------------------------------------------------------
dnl Check for pic
dnl ---------------------------------------------------------------------------
diff --git a/lib3270.cbp b/lib3270.cbp
index 7f73799..6310438 100644
--- a/lib3270.cbp
+++ b/lib3270.cbp
@@ -212,6 +212,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/include/config.h.in b/src/include/config.h.in
index eb23510..2565d36 100644
--- a/src/include/config.h.in
+++ b/src/include/config.h.in
@@ -50,7 +50,6 @@
#undef HAVE_LDAP
#undef HAVE_LIBSSL
#undef SSL_ALLOW_SELF_SIGNED_CERT
- #undef SSL_ENABLE_CRL_CHECK
/* Windows Options */
#ifdef WIN32
diff --git a/src/include/lib3270/macros.h b/src/include/lib3270/macros.h
index 7af7523..2058096 100644
--- a/src/include/lib3270/macros.h
+++ b/src/include/lib3270/macros.h
@@ -30,7 +30,10 @@
*
*/
- #define LIB3270_MACRO( name ) LIB3270_EXPORT char * lib3270_macro_ ## name (H3270 *hSession, int argc, const char **argv)
+ #error Deprecated
- LIB3270_EXPORT char * lib3270_run_macro(H3270 *session, const char **argv);
+
+ // #define LIB3270_MACRO( name ) LIB3270_EXPORT char * lib3270_macro_ ## name (H3270 *hSession, int argc, const char **argv)
+
+// LIB3270_EXPORT char * lib3270_run_macro(H3270 *session, const char **argv);
diff --git a/src/lib3270/Makefile.in b/src/lib3270/Makefile.in
index 73721c5..5f47558 100644
--- a/src/lib3270/Makefile.in
+++ b/src/lib3270/Makefile.in
@@ -30,6 +30,7 @@ LIBNAME=lib@LIB3270_NAME@
SOURCES= \
$(wildcard *.c) \
+ $(wildcard ssl/*.c) \
$(wildcard @OSNAME@/*.c) \
$(wildcard @OSNAME@/*.rc) \
$(BASEDIR)/.tmp/$(LIBNAME)/fallbacks.c
diff --git a/src/lib3270/connect.c b/src/lib3270/connect.c
index e1a5ca1..15e7470 100644
--- a/src/lib3270/connect.c
+++ b/src/lib3270/connect.c
@@ -129,7 +129,7 @@ static void net_connected(H3270 *hSession, int fd, LIB3270_IO_FLAG flag, void *d
hSession->ns_read_id = lib3270_add_poll_fd(hSession,hSession->sock,LIB3270_IO_FLAG_READ,net_input,0);
#if defined(HAVE_LIBSSL)
- if(hSession->ssl_con && hSession->secure == LIB3270_SSL_UNDEFINED)
+ if(hSession->ssl.con && hSession->ssl.state == LIB3270_SSL_UNDEFINED)
{
if(ssl_negotiate(hSession))
return;
@@ -333,12 +333,12 @@ static void net_connected(H3270 *hSession, int fd, LIB3270_IO_FLAG flag, void *d
#endif
hSession->ever_3270 = False;
- hSession->ssl_host = 0;
+ hSession->ssl.host = 0;
if(hSession->options&LIB3270_OPTION_SSL)
{
#if defined(HAVE_LIBSSL)
- hSession->ssl_host = 1;
+ hSession->ssl.host = 1;
ssl_init(hSession);
#else
lib3270_popup_dialog( hSession,
diff --git a/src/lib3270/host.c b/src/lib3270/host.c
index 464897d..78fb0b7 100644
--- a/src/lib3270/host.c
+++ b/src/lib3270/host.c
@@ -144,7 +144,7 @@ void lib3270_set_disconnected(H3270 *hSession)
hSession->cstate = LIB3270_NOT_CONNECTED;
hSession->starting = 0;
- hSession->secure = LIB3270_SSL_UNDEFINED;
+ hSession->ssl.state = LIB3270_SSL_UNDEFINED;
set_status(hSession,OIA_FLAG_UNDERA,False);
@@ -155,7 +155,7 @@ void lib3270_set_disconnected(H3270 *hSession)
if(hSession->cbk.update_connect)
hSession->cbk.update_connect(hSession,0);
- hSession->cbk.update_ssl(hSession,hSession->secure);
+ hSession->cbk.update_ssl(hSession,hSession->ssl.state);
}
diff --git a/src/lib3270/kybd.c b/src/lib3270/kybd.c
index bd7e3e1..a7e47ed 100644
--- a/src/lib3270/kybd.c
+++ b/src/lib3270/kybd.c
@@ -399,7 +399,7 @@ void kybd_inhibit(H3270 *session, Boolean inhibit)
/*
* Called when a host connects or disconnects.
*/
-void kybd_connect(H3270 *session, int connected, void *dunno)
+void kybd_connect(H3270 *session, int connected, void *dunno unused)
{
if (session->kybdlock & KL_DEFERRED_UNLOCK)
RemoveTimeOut(session, session->unlock_id);
@@ -421,7 +421,7 @@ void kybd_connect(H3270 *session, int connected, void *dunno)
/*
* Called when we switch between 3270 and ANSI modes.
*/
-void kybd_in3270(H3270 *hSession, int in3270 unused, void *dunno)
+void kybd_in3270(H3270 *hSession, int in3270 unused, void *dunno unused)
{
if (hSession->kybdlock & KL_DEFERRED_UNLOCK)
RemoveTimeOut(hSession, hSession->unlock_id);
@@ -694,7 +694,7 @@ static Boolean ins_prep(H3270 *hSession, int faddr, int baddr, int count)
#define GE_WFLAG 0x100
#define PASTE_WFLAG 0x200
-static void key_Character_wrapper(H3270 *hSession, const char *param1, const char *param2)
+static void key_Character_wrapper(H3270 *hSession, const char *param1, const char *param2 unused)
{
int code;
Boolean with_ge = False;
diff --git a/src/lib3270/macros.c b/src/lib3270/macros.c
index f494e24..100e0b1 100644
--- a/src/lib3270/macros.c
+++ b/src/lib3270/macros.c
@@ -30,6 +30,7 @@
*
*/
+/*
#ifdef WIN32
#include
#include
@@ -46,17 +47,21 @@
#include "private.h"
#include "utilc.h"
#include "api.h"
+ */
/*--[ Structs & Defines ]----------------------------------------------------------------------------*/
+/*
struct macro_list
{
const char *name;
char *(*exec)(H3270 *session, int argc, const char **argv);
};
+*/
/*--[ Implement ]------------------------------------------------------------------------------------*/
+/*
static const char * get_state(H3270 *h)
{
#define DECLARE_XLAT_STATE(x) { x, #x }
@@ -106,33 +111,6 @@
buffer = lib3270_get_string_at_address(hSession,0,-1,'\n');
break;
-/*
- case 2: // Just size, get current cursor position
- start = 0;
- qtd = atoi(argv[1]);
- break;
-
- case 3: // Use start position
- start = atoi(argv[1]);
- qtd = atoi(argv[2]);
- break;
-
- case 4: // Get start position from row/col
- lib3270_get_screen_size(hSession,&rows,&cols);
-
- row = atoi(argv[1])-1;
- col = atoi(argv[2])-1;
-
- if(row < 0 || row > rows || col < 0 || col > cols)
- {
- errno = EINVAL;
- return NULL;
- }
-
- start = (row * cols) + col;
- qtd = atoi(argv[3]);
- break;
-*/
default:
errno = EINVAL;
}
@@ -317,9 +295,11 @@
return strdup(ret);
}
+*/
/*--[ Macro entry point ]----------------------------------------------------------------------------*/
+/*
LIB3270_EXPORT char * lib3270_run_macro(H3270 *session, const char **argv)
{
#define LIB3270_MACRO_ENTRY( name ) { #name, lib3270_macro_ ## name }
@@ -379,4 +359,4 @@
// Not found, return NULL
return NULL;
}
-
+*/
diff --git a/src/lib3270/private.h b/src/lib3270/private.h
index 5a120b6..c5a0127 100644
--- a/src/lib3270/private.h
+++ b/src/lib3270/private.h
@@ -38,6 +38,10 @@
#include
#include "api.h"
+#if defined(HAVE_LIBSSL)
+ #include
+#endif // HAVE_LIBSSL
+
#if defined(X3270_TN3270E) && !defined(X3270_ANSI) /*[*/
#define X3270_ANSI 1 /* RFC2355 requires NVT mode */
#endif /*]*/
@@ -341,8 +345,6 @@ struct _h3270
char * oversize;
- LIB3270_SSL_STATE secure;
-
struct lib3270_toggle
{
char value; /**< toggle value */
@@ -406,7 +408,6 @@ struct _h3270
char no_login_host;
char non_tn3270e_host;
char passthru_host;
- char ssl_host;
char ever_3270;
// ctlr.c
@@ -602,8 +603,13 @@ struct _h3270
void * ns_exception_id;
// SSL Data (Always defined to maintain the structure size)
- unsigned long ssl_error;
- SSL * ssl_con;
+ struct
+ {
+ char host;
+ LIB3270_SSL_STATE state;
+ unsigned long error;
+ SSL * con;
+ } ssl;
timeout_t * timeouts;
input_t * inputs;
@@ -649,6 +655,7 @@ LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on);
#if defined(HAVE_LIBSSL) /*[*/
+ LIB3270_INTERNAL int ssl_ctx_init(void);
LIB3270_INTERNAL int ssl_init(H3270 *session);
LIB3270_INTERNAL int ssl_negotiate(H3270 *hSession);
LIB3270_INTERNAL void set_ssl_state(H3270 *session, LIB3270_SSL_STATE state);
@@ -662,5 +669,17 @@ LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on);
LIB3270_INTERNAL void ssl_info_callback(INFO_CONST SSL *s, int where, int ret);
+ /**
+ * @brief Global SSL_CTX object as framework to establish TLS/SSL or DTLS enabled connections.
+ *
+ */
+ LIB3270_INTERNAL SSL_CTX * ssl_ctx;
+
+ /**
+ * @brief Index of h3270 handle in SSL session.
+ *
+ */
+ LIB3270_INTERNAL int ssl_3270_ex_index;
+
#endif /*]*/
diff --git a/src/lib3270/ssl.c b/src/lib3270/ssl.c
deleted file mode 100644
index c1b5032..0000000
--- a/src/lib3270/ssl.c
+++ /dev/null
@@ -1,514 +0,0 @@
-/*
- * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
- * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
- * aplicativos mainframe. Registro no INPI sob o nome G3270.
- *
- * Copyright (C) <2008>
- *
- * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
- * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
- * Free Software Foundation.
- *
- * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
- * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
- * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
- * obter mais detalhes.
- *
- * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
- * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
- * St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Este programa está nomeado como ssl.c e possui - linhas de código.
- *
- * Contatos:
- *
- * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
- * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
- * licinio@bb.com.br (Licínio Luis Branco)
- * kraucer@bb.com.br (Kraucer Fernandes Mazuco)
- *
- *
- * References:
- *
- * http://www.openssl.org/docs/ssl/
- *
- */
-
-
-#include
-#if defined(HAVE_LIBSSL)
- #include
- #include
- #include
-
- #ifndef SSL_ST_OK
- #define SSL_ST_OK 3
- #endif // !SSL_ST_OK
-
-#endif
-
-#include "private.h"
-#include
-#include
-#include
-#include
-#include "trace_dsc.h"
-
-#if defined(HAVE_LIBSSL)
-
-static int ssl_3270_ex_index = -1; /**< Index of h3270 handle in SSL session */
-#endif // HAVE_LIBSSL
-
-/*--[ Implement ]------------------------------------------------------------------------------------*/
-
-#if defined(HAVE_LIBSSL)
-int ssl_negotiate(H3270 *hSession)
-{
- int rv;
-
- trace("%s",__FUNCTION__);
-
- set_ssl_state(hSession,LIB3270_SSL_NEGOTIATING);
- non_blocking(hSession,False);
-
- /* Initialize the SSL library. */
- if(ssl_init(hSession))
- {
- /* Failed. */
- lib3270_disconnect(hSession);
- return -1;
- }
-
- /* Set up the TLS/SSL connection. */
- if(SSL_set_fd(hSession->ssl_con, hSession->sock) != 1)
- {
- trace_dsn(hSession,"%s","SSL_set_fd failed!\n");
-
- lib3270_popup_dialog(
- hSession,
- LIB3270_NOTIFY_ERROR,
- N_( "Security error" ),
- N_( "SSL negotiation failed" ),
- "%s",_( "Cant set the file descriptor for the input/output facility for the TLS/SSL (encrypted) side of ssl." )
- );
-
- lib3270_disconnect(hSession);
- return -1;
- }
-
- trace("%s: Running SSL_connect",__FUNCTION__);
- rv = SSL_connect(hSession->ssl_con);
- trace("%s: SSL_connect exits with rc=%d",__FUNCTION__,rv);
-
- if (rv != 1)
- {
- int ssl_error = SSL_get_error(hSession->ssl_con,rv);
- const char * msg = "";
-
- if(ssl_error == SSL_ERROR_SYSCALL && hSession->ssl_error)
- ssl_error = hSession->ssl_error;
-
- msg = ERR_lib_error_string(ssl_error);
-
- trace_dsn(hSession,"SSL_connect failed: %s %s\n",msg,ERR_reason_error_string(hSession->ssl_error));
-
- lib3270_popup_dialog(
- hSession,
- LIB3270_NOTIFY_ERROR,
- N_( "Security error" ),
- N_( "SSL Connect failed" ),
- "%s",msg ? msg : ""
- );
-
- lib3270_disconnect(hSession);
- return -1;
- }
-
- /* Success. */
- X509 * peer = NULL;
- rv = SSL_get_verify_result(hSession->ssl_con);
-
- switch(rv)
- {
- case X509_V_OK:
- peer = SSL_get_peer_certificate(hSession->ssl_con);
-/*
-#if defined(SSL_ENABLE_CRL_CHECK)
- trace_dsn(hSession,"TLS/SSL negotiated connection complete with CRL validation. Peer certificate %s presented.\n", peer ? "was" : "was not");
-#else
- trace_dsn(hSession,"TLS/SSL negotiated connection complete without CRL validation. Peer certificate %s presented.\n", peer ? "was" : "was not");
-#endif // SSL_ENABLE_CRL_CHECK
-*/
- break;
-
- case X509_V_ERR_UNABLE_TO_GET_CRL:
- trace_dsn(hSession,"%s","The CRL of a certificate could not be found.\n" );
- lib3270_disconnect(hSession);
- lib3270_popup_dialog( hSession,
- LIB3270_NOTIFY_ERROR,
- _( "SSL error" ),
- _( "Unable to get certificate CRL." ),
- _( "The Certificate revocation list (CRL) of a certificate could not be found." )
- );
- return -1;
-
- case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
- peer = SSL_get_peer_certificate(hSession->ssl_con);
- trace_dsn(hSession,"%s","TLS/SSL negotiated connection complete with self signed certificate in certificate chain\n" );
-
-#ifdef SSL_ALLOW_SELF_SIGNED_CERT
- break;
-#else
- lib3270_disconnect(hSession);
- lib3270_popup_dialog( hSession,
- LIB3270_NOTIFY_ERROR,
- _( "SSL error" ),
- _( "The SSL certificate for this host is not trusted." ),
- _( "The security certificate presented by this host was not issued by a trusted certificate authority." )
- );
-
- return -1;
-#endif // SSL_ALLOW_SELF_SIGNED_CERT
-
- default:
- trace_dsn(hSession,"Unexpected or invalid TLS/SSL verify result %d\n",rv);
- }
-
- if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_DS_TRACE))
- {
- char buffer[4096];
- int alg_bits = 0;
- const SSL_CIPHER * cipher = SSL_get_current_cipher(hSession->ssl_con);
-
- trace_dsn(hSession,"TLS/SSL cipher description: %s",SSL_CIPHER_description((SSL_CIPHER *) cipher, buffer, 4095));
- SSL_CIPHER_get_bits(cipher, &alg_bits);
- trace_dsn(hSession,"%s version %s with %d bits\n",
- SSL_CIPHER_get_name(cipher),
- SSL_CIPHER_get_version(cipher),
- alg_bits);
- }
-
-
- if(peer)
- {
- if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_DS_TRACE))
- {
- BIO * out = BIO_new(BIO_s_mem());
- unsigned char * data;
- unsigned char * text;
- int n;
-
- X509_print(out,peer);
-
- n = BIO_get_mem_data(out, &data);
- text = (unsigned char *) malloc (n+1);
- text[n] ='\0';
- memcpy(text,data,n);
-
- trace_dsn(hSession,"TLS/SSL peer certificate:\n%s\n",text);
-
- free(text);
- BIO_free(out);
-
- }
-
- hSession->cbk.set_peer_certificate(peer);
-
- set_ssl_state(hSession,LIB3270_SSL_SECURE);
- X509_free(peer);
- }
-
-
- /* Tell the world that we are (still) connected, now in secure mode. */
- lib3270_set_connected_initial(hSession);
- non_blocking(hSession,True);
-
- return 0;
-}
-#endif // HAVE_LIBSSL
-
-#if defined(HAVE_LIBSSL) /*[*/
-
-/**
- * Initializa openssl library.
- *
- * @param hSession lib3270 session handle.
- *
- * @return 0 if ok, non zero if fails.
- *
- */
-int ssl_init(H3270 *hSession)
-{
- static SSL_CTX *ssl_ctx = NULL;
-
- hSession->ssl_error = 0;
- set_ssl_state(hSession,LIB3270_SSL_UNDEFINED);
-
- if(ssl_ctx == NULL)
- {
- lib3270_write_log(hSession,"SSL","%s","Initializing SSL context");
-
- SSL_load_error_strings();
- SSL_library_init();
-
- ssl_ctx = SSL_CTX_new(SSLv23_method());
- if(ssl_ctx == NULL)
- {
- int ssl_error = ERR_get_error();
-
- lib3270_popup_dialog(
- hSession,
- LIB3270_NOTIFY_ERROR,
- N_( "Security error" ),
- N_( "SSL_CTX_new() has failed" ),
- "%s",ERR_reason_error_string(ssl_error)
- );
-
- set_ssl_state(hSession,LIB3270_SSL_UNDEFINED);
-
- hSession->ssl_host = False;
- return -1;
- }
- SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL);
- SSL_CTX_set_info_callback(ssl_ctx, ssl_info_callback);
- SSL_CTX_set_default_verify_paths(ssl_ctx);
-
-#if defined(_WIN32)
- {
- HKEY hKey = 0;
-
- if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Software\\" PACKAGE_NAME,0,KEY_QUERY_VALUE,&hKey) == ERROR_SUCCESS)
- {
- char data[4096];
- unsigned long datalen = sizeof(data); // data field length(in), data returned length(out)
- unsigned long datatype; // #defined in winnt.h (predefined types 0-11)
-
- if(RegQueryValueExA(hKey,"datadir",NULL,&datatype,(LPBYTE) data,&datalen) == ERROR_SUCCESS)
- {
- strncat(data,"\\certs",4095);
-
- trace("Loading certs from \"%s\"",data);
- if(!SSL_CTX_load_verify_locations(ssl_ctx,NULL,data))
- {
- char buffer[4096];
- int ssl_error = ERR_get_error();
-
- snprintf(buffer,4095,_("Cant set default locations for trusted CA certificates to\n%s"),data);
-
- lib3270_popup_dialog(
- hSession,
- LIB3270_NOTIFY_ERROR,
- N_( "Security error" ),
- buffer,
- N_( "%s" ),ERR_lib_error_string(ssl_error)
- );
- }
- }
- RegCloseKey(hKey);
- }
-
-
- }
-#else
- static const char * ssldir[] =
- {
-#ifdef DATAROOTDIR
- DATAROOTDIR "/" PACKAGE_NAME "/certs",
-#endif // DATAROOTDIR
-#ifdef SYSCONFDIR
- SYSCONFDIR "/ssl/certs",
- SYSCONFDIR "/certs",
-#endif
- "/etc/ssl/certs"
- };
-
- size_t f;
-
- for(f = 0;f < sizeof(ssldir) / sizeof(ssldir[0]);f++)
- {
- if(!access(ssldir[f],R_OK) && SSL_CTX_load_verify_locations(ssl_ctx,NULL,ssldir[f]))
- {
- trace_dsn(hSession,"Checking %s for trusted CA certificates.\n",ssldir[f]);
- break;
- }
- }
-
-#endif // _WIN32
-
-#if defined(SSL_ENABLE_CRL_CHECK)
- // Set up CRL validation
- // https://stackoverflow.com/questions/4389954/does-openssl-automatically-handle-crls-certificate-revocation-lists-now
- X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx);
-
- // Enable CRL checking
- X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_new();
- X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
- X509_STORE_set1_param(store, param);
- X509_VERIFY_PARAM_free(param);
-
- // X509_STORE_free(store);
-
- trace_dsn(hSession,"CRL CHECK is enabled.\n");
-
-#else
-
- trace_dsn(hSession,"CRL CHECK is disabled.\n");
-
-#endif // SSL_ENABLE_CRL_CHECK
-
- ssl_3270_ex_index = SSL_get_ex_new_index(0,NULL,NULL,NULL,NULL);
-
-
- }
-
- if(hSession->ssl_con)
- SSL_free(hSession->ssl_con);
-
- hSession->ssl_con = SSL_new(ssl_ctx);
- if(hSession->ssl_con == NULL)
- {
- int ssl_error = ERR_get_error();
-
- lib3270_popup_dialog(
- hSession,
- LIB3270_NOTIFY_ERROR,
- N_( "Security error" ),
- N_( "Cant create a new SSL structure for current connection." ),
- N_( "%s" ),ERR_lib_error_string(ssl_error)
- );
-
- hSession->ssl_host = False;
- return -1;
- }
-
- SSL_set_ex_data(hSession->ssl_con,ssl_3270_ex_index,(char *) hSession);
-
-// SSL_set_verify(session->ssl_con, SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
- SSL_set_verify(hSession->ssl_con, 0, NULL);
-
- return 0;
-}
-
-/* Callback for tracing protocol negotiation. */
-void ssl_info_callback(INFO_CONST SSL *s, int where, int ret)
-{
- H3270 *hSession = (H3270 *) SSL_get_ex_data(s,ssl_3270_ex_index);
-
-#ifdef DEBUG
- if(hSession != lib3270_get_default_session_handle())
- {
- trace("%s: hsession=%p, session=%p",__FUNCTION__,hSession,lib3270_get_default_session_handle());
- exit(-1);
- }
-#endif // DEBUG
-
- switch(where)
- {
- case SSL_CB_CONNECT_LOOP:
- trace_dsn(hSession,"SSL_connect: %s %s\n",SSL_state_string(s), SSL_state_string_long(s));
- break;
-
- case SSL_CB_CONNECT_EXIT:
-
- trace_dsn(hSession,"%s: SSL_CB_CONNECT_EXIT\n",__FUNCTION__);
-
- if (ret == 0)
- {
- trace_dsn(hSession,"SSL_connect: failed in %s\n",SSL_state_string_long(s));
- }
- else if (ret < 0)
- {
- unsigned long e = ERR_get_error();
- char err_buf[1024];
-
- if(e != 0)
- {
- hSession->ssl_error = e;
- (void) ERR_error_string_n(e, err_buf, 1023);
- }
-#if defined(_WIN32)
- else if (GetLastError() != 0)
- {
- strncpy(err_buf,lib3270_win32_strerror(GetLastError()),1023);
- }
-#else
- else if (errno != 0)
- {
- strncpy(err_buf, strerror(errno),1023);
- }
-#endif
- else
- {
- err_buf[0] = '\0';
- }
-
- trace_dsn(hSession,"SSL Connect error %d\nMessage: %s\nState: %s\nAlert: %s\n",
- ret,
- err_buf,
- SSL_state_string_long(s),
- SSL_alert_type_string_long(ret)
- );
-
- }
-
-
- default:
- trace_dsn(hSession,"SSL Current state is \"%s\"\n",SSL_state_string_long(s));
- }
-
-#ifdef DEBUG
- if(where & SSL_CB_EXIT)
- {
- trace("%s: SSL_CB_EXIT ret=%d\n",__FUNCTION__,ret);
- }
-#endif
-
- if(where & SSL_CB_ALERT)
- trace_dsn(hSession,"SSL ALERT: %s\n",SSL_alert_type_string_long(ret));
-
- if(where & SSL_CB_HANDSHAKE_DONE)
- {
- trace_dsn(hSession,"%s: SSL_CB_HANDSHAKE_DONE state=%04x\n",__FUNCTION__,SSL_get_state(s));
- if(SSL_get_state(s) == SSL_ST_OK)
- set_ssl_state(hSession,LIB3270_SSL_NEGOTIATED);
- else
- set_ssl_state(hSession,LIB3270_SSL_UNSECURE);
- }
-}
-
-#endif /*]*/
-
-LIB3270_EXPORT int lib3270_is_secure(H3270 *hSession)
-{
- return lib3270_get_secure(hSession) == LIB3270_SSL_SECURE;
-}
-
-LIB3270_EXPORT long lib3270_get_SSL_verify_result(H3270 *hSession)
-{
- CHECK_SESSION_HANDLE(hSession);
-#if defined(HAVE_LIBSSL)
- if(hSession->ssl_con)
- return SSL_get_verify_result(hSession->ssl_con);
-#endif // HAVE_LIBSSL
- return -1;
-}
-
-LIB3270_EXPORT LIB3270_SSL_STATE lib3270_get_secure(H3270 *session)
-{
- CHECK_SESSION_HANDLE(session);
-
- return session->secure;
-}
-
-void set_ssl_state(H3270 *session, LIB3270_SSL_STATE state)
-{
- CHECK_SESSION_HANDLE(session);
-
- if(state == session->secure)
- return;
-
- session->secure = state;
- trace_dsn(session,"SSL state changes to %d\n",(int) state);
-
- session->cbk.update_ssl(session,session->secure);
-}
diff --git a/src/lib3270/ssl/init.c b/src/lib3270/ssl/init.c
new file mode 100644
index 0000000..a03390f
--- /dev/null
+++ b/src/lib3270/ssl/init.c
@@ -0,0 +1,177 @@
+/*
+ * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
+ * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
+ * aplicativos mainframe. Registro no INPI sob o nome G3270.
+ *
+ * Copyright (C) <2008>
+ *
+ * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
+ * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
+ * Free Software Foundation.
+ *
+ * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
+ * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
+ * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
+ * obter mais detalhes.
+ *
+ * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
+ * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
+ * St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Este programa está nomeado como ssl.c e possui - linhas de código.
+ *
+ * Contatos:
+ *
+ * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
+ * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
+ * licinio@bb.com.br (Licínio Luis Branco)
+ * kraucer@bb.com.br (Kraucer Fernandes Mazuco)
+ *
+ *
+ * References:
+ *
+ * http://www.openssl.org/docs/ssl/
+ *
+ */
+
+/**
+ * @brief OpenSSL initialization.
+ *
+ */
+
+#include
+#if defined(HAVE_LIBSSL)
+
+#include
+#include
+#include
+
+#ifndef SSL_ST_OK
+ #define SSL_ST_OK 3
+#endif // !SSL_ST_OK
+
+#include "../private.h"
+#include
+#include
+#include
+#include
+#include "trace_dsc.h"
+
+/*--[ Implement ]------------------------------------------------------------------------------------*/
+
+/**
+ * @brief Initialize openssl library.
+ *
+ * @return 0 if ok, non zero if fails.
+ *
+ */
+int ssl_ctx_init(void)
+{
+ debug("%s ssl_ctx=%p",__FUNCTION__,ssl_ctx);
+
+ if(ssl_ctx != NULL)
+ return 0;
+
+ SSL_load_error_strings();
+ SSL_library_init();
+
+ ssl_ctx = SSL_CTX_new(SSLv23_method());
+ if(ssl_ctx == NULL)
+ return -1;
+
+ SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL);
+ SSL_CTX_set_info_callback(ssl_ctx, ssl_info_callback);
+ SSL_CTX_set_default_verify_paths(ssl_ctx);
+
+#if defined(_WIN32)
+ {
+ HKEY hKey = 0;
+
+ if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Software\\" PACKAGE_NAME,0,KEY_QUERY_VALUE,&hKey) == ERROR_SUCCESS)
+ {
+ char data[4096];
+ unsigned long datalen = sizeof(data); // data field length(in), data returned length(out)
+ unsigned long datatype; // #defined in winnt.h (predefined types 0-11)
+
+ if(RegQueryValueExA(hKey,"datadir",NULL,&datatype,(LPBYTE) data,&datalen) == ERROR_SUCCESS)
+ {
+ strncat(data,"\\certs",4095);
+
+ trace("Loading certs from \"%s\"",data);
+ if(!SSL_CTX_load_verify_locations(ssl_ctx,NULL,data))
+ {
+ char buffer[4096];
+ int ssl_error = ERR_get_error();
+
+ snprintf(buffer,4095,_("Cant set default locations for trusted CA certificates to\n%s"),data);
+
+ lib3270_popup_dialog(
+ hSession,
+ LIB3270_NOTIFY_ERROR,
+ N_( "Security error" ),
+ buffer,
+ N_( "%s" ),ERR_lib_error_string(ssl_error)
+ );
+ }
+ }
+ RegCloseKey(hKey);
+ }
+
+
+ }
+#else
+ static const char * ssldir[] =
+ {
+#ifdef DATAROOTDIR
+ DATAROOTDIR "/" PACKAGE_NAME "/certs",
+#endif // DATAROOTDIR
+#ifdef SYSCONFDIR
+ SYSCONFDIR "/ssl/certs",
+ SYSCONFDIR "/certs",
+#endif
+ "/etc/ssl/certs"
+ };
+
+ size_t f;
+
+ for(f = 0;f < sizeof(ssldir) / sizeof(ssldir[0]);f++)
+ {
+ SSL_CTX_load_verify_locations(ssl_ctx,NULL,ssldir[f]);
+ }
+
+#endif // _WIN32
+
+ //
+ // Initialize CUSTOM CRL CHECK
+ //
+
+
+/*
+#if defined(SSL_ENABLE_CRL_CHECK)
+ // Set up CRL validation
+ // https://stackoverflow.com/questions/4389954/does-openssl-automatically-handle-crls-certificate-revocation-lists-now
+ X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx);
+
+ // Enable CRL checking
+ X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_new();
+ X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
+ X509_STORE_set1_param(store, param);
+ X509_VERIFY_PARAM_free(param);
+
+ // X509_STORE_free(store);
+
+ trace_dsn(hSession,"CRL CHECK is enabled.\n");
+
+#else
+
+ trace_dsn(hSession,"CRL CHECK is disabled.\n");
+
+#endif // SSL_ENABLE_CRL_CHECK
+*/
+
+ ssl_3270_ex_index = SSL_get_ex_new_index(0,NULL,NULL,NULL,NULL);
+
+ return 0;
+}
+
+#endif // HAVE_LIBSSL
diff --git a/src/lib3270/ssl/negotiate.c b/src/lib3270/ssl/negotiate.c
new file mode 100644
index 0000000..e1a12e2
--- /dev/null
+++ b/src/lib3270/ssl/negotiate.c
@@ -0,0 +1,378 @@
+/*
+ * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
+ * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
+ * aplicativos mainframe. Registro no INPI sob o nome G3270.
+ *
+ * Copyright (C) <2008>
+ *
+ * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
+ * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
+ * Free Software Foundation.
+ *
+ * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
+ * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
+ * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
+ * obter mais detalhes.
+ *
+ * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
+ * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
+ * St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Este programa está nomeado como ssl.c e possui - linhas de código.
+ *
+ * Contatos:
+ *
+ * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
+ * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
+ * licinio@bb.com.br (Licínio Luis Branco)
+ * kraucer@bb.com.br (Kraucer Fernandes Mazuco)
+ *
+ *
+ * References:
+ *
+ * http://www.openssl.org/docs/ssl/
+ *
+ */
+
+
+#include
+#if defined(HAVE_LIBSSL)
+ #include
+ #include
+ #include
+
+ #ifndef SSL_ST_OK
+ #define SSL_ST_OK 3
+ #endif // !SSL_ST_OK
+
+#endif
+
+#include "../private.h"
+#include
+#include
+#include
+#include
+#include "trace_dsc.h"
+
+/*--[ Implement ]------------------------------------------------------------------------------------*/
+
+#if defined(HAVE_LIBSSL)
+
+ /**
+ * @brief Index of h3270 handle in SSL session.
+ *
+ */
+ int ssl_3270_ex_index = -1;
+
+/**
+ * @brief Global SSL_CTX object as framework to establish TLS/SSL or DTLS enabled connections.
+ *
+ */
+ SSL_CTX * ssl_ctx = NULL;
+
+/**
+ * @brief Initialize openssl session.
+ *
+ * @param hSession lib3270 session handle.
+ *
+ * @return 0 if ok, non zero if fails.
+ *
+ */
+int ssl_init(H3270 *hSession)
+{
+ set_ssl_state(hSession,LIB3270_SSL_UNDEFINED);
+ hSession->ssl.error = 0;
+ hSession->ssl.host = False;
+
+ if(ssl_ctx_init()) {
+
+ hSession->ssl.error = ERR_get_error();
+
+ lib3270_popup_dialog(
+ hSession,
+ LIB3270_NOTIFY_ERROR,
+ N_( "Security error" ),
+ N_( "SSL initialization has failed" ),
+ "%s",ERR_reason_error_string(hSession->ssl.error)
+ );
+
+ set_ssl_state(hSession,LIB3270_SSL_UNDEFINED);
+
+ hSession->ssl.host = False;
+ return -1;
+ }
+
+ if(hSession->ssl.con)
+ SSL_free(hSession->ssl.con);
+
+ hSession->ssl.con = SSL_new(ssl_ctx);
+ if(hSession->ssl.con == NULL)
+ {
+ hSession->ssl.error = ERR_get_error();
+
+ lib3270_popup_dialog(
+ hSession,
+ LIB3270_NOTIFY_ERROR,
+ N_( "Security error" ),
+ N_( "Cant create a new SSL structure for current connection." ),
+ N_( "%s" ),ERR_lib_error_string(hSession->ssl.error)
+ );
+
+ return -1;
+ }
+
+ SSL_set_ex_data(hSession->ssl.con,ssl_3270_ex_index,(char *) hSession);
+
+// SSL_set_verify(session->ssl_con, SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
+ SSL_set_verify(hSession->ssl.con, 0, NULL);
+
+ return 0;
+}
+
+int ssl_negotiate(H3270 *hSession)
+{
+ int rv;
+
+ trace("%s",__FUNCTION__);
+
+ set_ssl_state(hSession,LIB3270_SSL_NEGOTIATING);
+ non_blocking(hSession,False);
+
+ /* Initialize the SSL library. */
+ if(ssl_init(hSession))
+ {
+ /* Failed. */
+ lib3270_disconnect(hSession);
+ return -1;
+ }
+
+ /* Set up the TLS/SSL connection. */
+ if(SSL_set_fd(hSession->ssl.con, hSession->sock) != 1)
+ {
+ trace_dsn(hSession,"%s","SSL_set_fd failed!\n");
+
+ lib3270_popup_dialog(
+ hSession,
+ LIB3270_NOTIFY_ERROR,
+ N_( "Security error" ),
+ N_( "SSL negotiation failed" ),
+ "%s",_( "Cant set the file descriptor for the input/output facility for the TLS/SSL (encrypted) side of ssl." )
+ );
+
+ lib3270_disconnect(hSession);
+ return -1;
+ }
+
+ trace("%s: Running SSL_connect",__FUNCTION__);
+ rv = SSL_connect(hSession->ssl.con);
+ trace("%s: SSL_connect exits with rc=%d",__FUNCTION__,rv);
+
+ if (rv != 1)
+ {
+ int ssl_error = SSL_get_error(hSession->ssl.con,rv);
+ const char * msg = "";
+
+ if(ssl_error == SSL_ERROR_SYSCALL && hSession->ssl.error)
+ ssl_error = hSession->ssl.error;
+
+ msg = ERR_lib_error_string(ssl_error);
+
+ trace_dsn(hSession,"SSL_connect failed: %s %s\n",msg,ERR_reason_error_string(hSession->ssl.error));
+
+ lib3270_popup_dialog(
+ hSession,
+ LIB3270_NOTIFY_ERROR,
+ N_( "Security error" ),
+ N_( "SSL Connect failed" ),
+ "%s",msg ? msg : ""
+ );
+
+ lib3270_disconnect(hSession);
+ return -1;
+ }
+
+ /* Success. */
+ X509 * peer = NULL;
+ rv = SSL_get_verify_result(hSession->ssl.con);
+
+ switch(rv)
+ {
+ case X509_V_OK:
+ peer = SSL_get_peer_certificate(hSession->ssl.con);
+ trace_dsn(hSession,"TLS/SSL negotiated connection complete. Peer certificate %s presented.\n", peer ? "was" : "was not");
+ break;
+
+ case X509_V_ERR_UNABLE_TO_GET_CRL:
+ trace_dsn(hSession,"%s","The CRL of a certificate could not be found.\n" );
+ lib3270_disconnect(hSession);
+ lib3270_popup_dialog( hSession,
+ LIB3270_NOTIFY_ERROR,
+ _( "SSL error" ),
+ _( "Unable to get certificate CRL." ),
+ _( "The Certificate revocation list (CRL) of a certificate could not be found." )
+ );
+ return -1;
+
+ case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
+ peer = SSL_get_peer_certificate(hSession->ssl.con);
+ trace_dsn(hSession,"%s","TLS/SSL negotiated connection complete with self signed certificate in certificate chain\n" );
+
+#ifdef SSL_ALLOW_SELF_SIGNED_CERT
+ break;
+#else
+ lib3270_disconnect(hSession);
+ lib3270_popup_dialog( hSession,
+ LIB3270_NOTIFY_ERROR,
+ _( "SSL error" ),
+ _( "The SSL certificate for this host is not trusted." ),
+ _( "The security certificate presented by this host was not issued by a trusted certificate authority." )
+ );
+
+ return -1;
+#endif // SSL_ALLOW_SELF_SIGNED_CERT
+
+ default:
+ trace_dsn(hSession,"Unexpected or invalid TLS/SSL verify result %d\n",rv);
+ }
+
+ if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_DS_TRACE))
+ {
+ char buffer[4096];
+ int alg_bits = 0;
+ const SSL_CIPHER * cipher = SSL_get_current_cipher(hSession->ssl.con);
+
+ trace_dsn(hSession,"TLS/SSL cipher description: %s",SSL_CIPHER_description((SSL_CIPHER *) cipher, buffer, 4095));
+ SSL_CIPHER_get_bits(cipher, &alg_bits);
+ trace_dsn(hSession,"%s version %s with %d bits\n",
+ SSL_CIPHER_get_name(cipher),
+ SSL_CIPHER_get_version(cipher),
+ alg_bits);
+ }
+
+
+ if(peer)
+ {
+ if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_DS_TRACE))
+ {
+ BIO * out = BIO_new(BIO_s_mem());
+ unsigned char * data;
+ unsigned char * text;
+ int n;
+
+ X509_print(out,peer);
+
+ n = BIO_get_mem_data(out, &data);
+ text = (unsigned char *) malloc (n+1);
+ text[n] ='\0';
+ memcpy(text,data,n);
+
+ trace_dsn(hSession,"TLS/SSL peer certificate:\n%s\n",text);
+
+ free(text);
+ BIO_free(out);
+
+ }
+
+ hSession->cbk.set_peer_certificate(peer);
+
+ set_ssl_state(hSession,LIB3270_SSL_SECURE);
+ X509_free(peer);
+ }
+
+
+ /* Tell the world that we are (still) connected, now in secure mode. */
+ lib3270_set_connected_initial(hSession);
+ non_blocking(hSession,True);
+
+ return 0;
+}
+
+/* Callback for tracing protocol negotiation. */
+void ssl_info_callback(INFO_CONST SSL *s, int where, int ret)
+{
+ H3270 *hSession = (H3270 *) SSL_get_ex_data(s,ssl_3270_ex_index);
+
+#ifdef DEBUG
+ if(hSession != lib3270_get_default_session_handle())
+ {
+ trace("%s: hsession=%p, session=%p",__FUNCTION__,hSession,lib3270_get_default_session_handle());
+ exit(-1);
+ }
+#endif // DEBUG
+
+ switch(where)
+ {
+ case SSL_CB_CONNECT_LOOP:
+ trace_dsn(hSession,"SSL_connect: %s %s\n",SSL_state_string(s), SSL_state_string_long(s));
+ break;
+
+ case SSL_CB_CONNECT_EXIT:
+
+ trace_dsn(hSession,"%s: SSL_CB_CONNECT_EXIT\n",__FUNCTION__);
+
+ if (ret == 0)
+ {
+ trace_dsn(hSession,"SSL_connect: failed in %s\n",SSL_state_string_long(s));
+ }
+ else if (ret < 0)
+ {
+ unsigned long e = ERR_get_error();
+ char err_buf[1024];
+
+ if(e != 0)
+ {
+ hSession->ssl.error = e;
+ (void) ERR_error_string_n(e, err_buf, 1023);
+ }
+#if defined(_WIN32)
+ else if (GetLastError() != 0)
+ {
+ strncpy(err_buf,lib3270_win32_strerror(GetLastError()),1023);
+ }
+#else
+ else if (errno != 0)
+ {
+ strncpy(err_buf, strerror(errno),1023);
+ }
+#endif
+ else
+ {
+ err_buf[0] = '\0';
+ }
+
+ trace_dsn(hSession,"SSL Connect error %d\nMessage: %s\nState: %s\nAlert: %s\n",
+ ret,
+ err_buf,
+ SSL_state_string_long(s),
+ SSL_alert_type_string_long(ret)
+ );
+
+ }
+
+
+ default:
+ trace_dsn(hSession,"SSL Current state is \"%s\"\n",SSL_state_string_long(s));
+ }
+
+#ifdef DEBUG
+ if(where & SSL_CB_EXIT)
+ {
+ trace("%s: SSL_CB_EXIT ret=%d\n",__FUNCTION__,ret);
+ }
+#endif
+
+ if(where & SSL_CB_ALERT)
+ trace_dsn(hSession,"SSL ALERT: %s\n",SSL_alert_type_string_long(ret));
+
+ if(where & SSL_CB_HANDSHAKE_DONE)
+ {
+ trace_dsn(hSession,"%s: SSL_CB_HANDSHAKE_DONE state=%04x\n",__FUNCTION__,SSL_get_state(s));
+ if(SSL_get_state(s) == SSL_ST_OK)
+ set_ssl_state(hSession,LIB3270_SSL_NEGOTIATED);
+ else
+ set_ssl_state(hSession,LIB3270_SSL_UNSECURE);
+ }
+}
+
+#endif /*]*/
+
diff --git a/src/lib3270/ssl/state.c b/src/lib3270/ssl/state.c
new file mode 100644
index 0000000..e703244
--- /dev/null
+++ b/src/lib3270/ssl/state.c
@@ -0,0 +1,74 @@
+/*
+ * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
+ * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
+ * aplicativos mainframe. Registro no INPI sob o nome G3270.
+ *
+ * Copyright (C) <2008>
+ *
+ * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
+ * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
+ * Free Software Foundation.
+ *
+ * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
+ * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
+ * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
+ * obter mais detalhes.
+ *
+ * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
+ * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
+ * St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Este programa está nomeado como - e possui - linhas de código.
+ *
+ * Contatos:
+ *
+ * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
+ * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
+ *
+ */
+
+#include
+#include "../private.h"
+#include
+#include
+#include
+#include
+#include
+
+/*--[ Implement ]------------------------------------------------------------------------------------*/
+
+LIB3270_EXPORT int lib3270_is_secure(H3270 *hSession)
+{
+ return lib3270_get_secure(hSession) == LIB3270_SSL_SECURE;
+}
+
+LIB3270_EXPORT long lib3270_get_SSL_verify_result(H3270 *hSession)
+{
+ CHECK_SESSION_HANDLE(hSession);
+#if defined(HAVE_LIBSSL)
+ if(hSession->ssl.con)
+ return SSL_get_verify_result(hSession->ssl.con);
+#endif // HAVE_LIBSSL
+ return -1;
+}
+
+LIB3270_EXPORT LIB3270_SSL_STATE lib3270_get_secure(H3270 *hSession)
+{
+ CHECK_SESSION_HANDLE(hSession);
+ return hSession->ssl.state;
+}
+
+void set_ssl_state(H3270 *hSession, LIB3270_SSL_STATE state)
+{
+ CHECK_SESSION_HANDLE(hSession);
+
+ debug("%s: %d -> %d",__FUNCTION__,hSession->ssl.state,state);
+
+ if(state == hSession->ssl.state)
+ return;
+
+ hSession->ssl.state = state;
+ trace_dsn(hSession,"SSL state changes to %d\n",(int) state);
+
+ hSession->cbk.update_ssl(hSession,hSession->ssl.state);
+}
diff --git a/src/lib3270/telnet.c b/src/lib3270/telnet.c
index 79a20ea..5417b93 100644
--- a/src/lib3270/telnet.c
+++ b/src/lib3270/telnet.c
@@ -806,11 +806,11 @@ static int net_connected(H3270 *hSession)
}
*/
- trace_dsn(hSession,"Connected to %s%s.\n", hSession->host.current,hSession->ssl_host? " using SSL": "");
+ trace_dsn(hSession,"Connected to %s%s.\n", hSession->host.current,hSession->ssl.host? " using SSL": "");
#if defined(HAVE_LIBSSL)
/* Set up SSL. */
- if(hSession->ssl_con && hSession->secure == LIB3270_SSL_UNDEFINED)
+ if(hSession->ssl.con && hSession->ssl.state == LIB3270_SSL_UNDEFINED)
{
if(ssl_negotiate(hSession))
return -1;
@@ -899,11 +899,12 @@ LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession)
trace("%s",__FUNCTION__);
#if defined(HAVE_LIBSSL)
- if(hSession->ssl_con != NULL)
+ if(hSession->ssl.con != NULL)
{
- SSL_shutdown(hSession->ssl_con);
- SSL_free(hSession->ssl_con);
- hSession->ssl_con = NULL;
+ set_ssl_state(hSession,LIB3270_SSL_UNDEFINED);
+ SSL_shutdown(hSession->ssl.con);
+ SSL_free(hSession->ssl.con);
+ hSession->ssl.con = NULL;
}
#endif
@@ -1010,8 +1011,8 @@ void net_input(H3270 *hSession, int fd unused, LIB3270_IO_FLAG flag unused, void
#endif
#if defined(HAVE_LIBSSL)
- if (hSession->ssl_con != NULL)
- nr = SSL_read(hSession->ssl_con, (char *) buffer, BUFSZ);
+ if (hSession->ssl.con != NULL)
+ nr = SSL_read(hSession->ssl.con, (char *) buffer, BUFSZ);
else
nr = recv(hSession->sock, (char *) buffer, BUFSZ, 0);
#else
@@ -1024,7 +1025,7 @@ void net_input(H3270 *hSession, int fd unused, LIB3270_IO_FLAG flag unused, void
return;
#if defined(HAVE_LIBSSL) /*[*/
- if(hSession->ssl_con != NULL)
+ if(hSession->ssl.con != NULL)
{
unsigned long e;
char err_buf[120];
@@ -1991,8 +1992,8 @@ LIB3270_INTERNAL int lib3270_sock_send(H3270 *hSession, unsigned const char *buf
int rc;
#if defined(HAVE_LIBSSL)
- if(hSession->ssl_con != NULL)
- rc = SSL_write(hSession->ssl_con, (const char *) buf, len);
+ if(hSession->ssl.con != NULL)
+ rc = SSL_write(hSession->ssl.con, (const char *) buf, len);
else
rc = send(hSession->sock, (const char *) buf, len, 0);
#else
@@ -2005,7 +2006,7 @@ LIB3270_INTERNAL int lib3270_sock_send(H3270 *hSession, unsigned const char *buf
// Recv error, notify
#if defined(HAVE_LIBSSL)
- if(hSession->ssl_con != NULL)
+ if(hSession->ssl.con != NULL)
{
unsigned long e;
char err_buf[120];
--
libgit2 0.21.2