Commit 7a87d265f93cd60b056ae7cdc5e557fdc555ce5b

Authored by Perry Werneck
1 parent 0669cde0

Implementing network modules for non SSL/TLS sessions.

@@ -45,6 +45,8 @@ SOURCES= \ @@ -45,6 +45,8 @@ SOURCES= \
45 $(wildcard src/selection/*.c) \ 45 $(wildcard src/selection/*.c) \
46 $(wildcard src/ssl/*.c) \ 46 $(wildcard src/ssl/*.c) \
47 $(wildcard src/ssl/@OSNAME@/*.c) \ 47 $(wildcard src/ssl/@OSNAME@/*.c) \
  48 + $(wildcard src/network_modules/*.c) \
  49 + $(wildcard src/network_modules/@OSNAME@/*.c) \
48 $(BASEDIR)/.tmp/$(LIBNAME)/fallbacks.c 50 $(BASEDIR)/.tmp/$(LIBNAME)/fallbacks.c
49 51
50 TEST_SOURCES= \ 52 TEST_SOURCES= \
@@ -307,6 +307,10 @@ @@ -307,6 +307,10 @@
307 <Unit filename="src/mkfb/mkfb.c"> 307 <Unit filename="src/mkfb/mkfb.c">
308 <Option compilerVar="CC" /> 308 <Option compilerVar="CC" />
309 </Unit> 309 </Unit>
  310 + <Unit filename="src/network_modules/linux/connect.c">
  311 + <Option compilerVar="CC" />
  312 + </Unit>
  313 + <Unit filename="src/network_modules/private.h" />
310 <Unit filename="src/network_modules/unsecure.c"> 314 <Unit filename="src/network_modules/unsecure.c">
311 <Option compilerVar="CC" /> 315 <Option compilerVar="CC" />
312 </Unit> 316 </Unit>
src/core/connect.c
@@ -62,7 +62,7 @@ @@ -62,7 +62,7 @@
62 if(ssl_ctx_init(hSession, (SSL_ERROR_MESSAGE *) ssl_error)) 62 if(ssl_ctx_init(hSession, (SSL_ERROR_MESSAGE *) ssl_error))
63 return -1; 63 return -1;
64 64
65 -#if defined(SSL_ENABLE_CRL_CHECK) 65 +#if defined(HAVE_LIBSSL) && defined(SSL_ENABLE_CRL_CHECK)
66 lib3270_crl_free_if_expired(hSession); 66 lib3270_crl_free_if_expired(hSession);
67 #endif // defined(SSL_ENABLE_CRL_CHECK) 67 #endif // defined(SSL_ENABLE_CRL_CHECK)
68 68
@@ -71,6 +71,7 @@ @@ -71,6 +71,7 @@
71 71
72 #endif // HAVE_LIBSSL 72 #endif // HAVE_LIBSSL
73 73
  74 +/*
74 void connection_failed(H3270 *hSession, const char *message) 75 void connection_failed(H3270 *hSession, const char *message)
75 { 76 {
76 lib3270_disconnect(hSession); 77 lib3270_disconnect(hSession);
@@ -94,6 +95,7 @@ @@ -94,6 +95,7 @@
94 lib3270_activate_auto_reconnect(hSession,1000); 95 lib3270_activate_auto_reconnect(hSession,1000);
95 96
96 } 97 }
  98 +*/
97 99
98 int lib3270_allow_reconnect(const H3270 *hSession) 100 int lib3270_allow_reconnect(const H3270 *hSession)
99 { 101 {
@@ -169,16 +171,11 @@ @@ -169,16 +171,11 @@
169 171
170 } 172 }
171 173
172 - static int bg_start_tls(H3270 *hSession, void *message)  
173 - {  
174 -  
175 - }  
176 -  
177 - int lib3270_start_tls(H3270 *hSession) 174 + int lib3270_start_tls(H3270 *hSession, Bool required)
178 { 175 {
179 int rc = 0; 176 int rc = 0;
180 177
181 - if(hSession->network.module->start_tls) 178 + if(hSession->network.module->start_tls,required)
182 { 179 {
183 LIB3270_NETWORK_STATE state; 180 LIB3270_NETWORK_STATE state;
184 memset(&state,0,sizeof(state)); 181 memset(&state,0,sizeof(state));
src/core/host.c
@@ -42,6 +42,7 @@ @@ -42,6 +42,7 @@
42 #endif // HAVE_MALLOC_H 42 #endif // HAVE_MALLOC_H
43 43
44 #include <internals.h> 44 #include <internals.h>
  45 +#include <stdlib.h>
45 #include "resources.h" 46 #include "resources.h"
46 47
47 #include "hostc.h" 48 #include "hostc.h"
@@ -279,7 +280,7 @@ static void update_url(H3270 *hSession) @@ -279,7 +280,7 @@ static void update_url(H3270 *hSession)
279 lib3270_free(hSession->host.url); 280 lib3270_free(hSession->host.url);
280 hSession->host.url = url; 281 hSession->host.url = url;
281 282
282 -#ifdef SSL_ENABLE_CRL_CHECK 283 +#if defined(HAVE_LIBSSL) && defined(SSL_ENABLE_CRL_CHECK)
283 lib3270_crl_free(hSession); 284 lib3270_crl_free(hSession);
284 #endif // SSL_ENABLE_CRL_CHECK 285 #endif // SSL_ENABLE_CRL_CHECK
285 286
src/core/iocalls.c
@@ -299,13 +299,10 @@ static void internal_remove_poll(H3270 *session, void *id) @@ -299,13 +299,10 @@ static void internal_remove_poll(H3270 *session, void *id)
299 } 299 }
300 300
301 301
302 -/*  
303 LIB3270_EXPORT void lib3270_remove_poll(H3270 *session, void *id) 302 LIB3270_EXPORT void lib3270_remove_poll(H3270 *session, void *id)
304 { 303 {
305 - debug("%s(%d,%p)",__FUNCTION__,session->connection.sock,id);  
306 remove_poll(session, id); 304 remove_poll(session, id);
307 } 305 }
308 -*/  
309 306
310 LIB3270_EXPORT void lib3270_set_poll_state(H3270 *session, void *id, int enabled) 307 LIB3270_EXPORT void lib3270_set_poll_state(H3270 *session, void *id, int enabled)
311 { 308 {
@@ -520,7 +517,7 @@ LIB3270_EXPORT int lib3270_run_task(H3270 *hSession, int(*callback)(H3270 *h, vo @@ -520,7 +517,7 @@ LIB3270_EXPORT int lib3270_run_task(H3270 *hSession, int(*callback)(H3270 *h, vo
520 517
521 int non_blocking(H3270 *hSession, Boolean on) 518 int non_blocking(H3270 *hSession, Boolean on)
522 { 519 {
523 - if(hSession->network.module->non_blocking,on) 520 + if(hSession->network.module->non_blocking(hSession,on))
524 return 0; 521 return 0;
525 522
526 lib3270_set_poll_state(hSession,hSession->xio.read, on); 523 lib3270_set_poll_state(hSession,hSession->xio.read, on);
src/core/linux/connect.c
@@ -42,8 +42,6 @@ @@ -42,8 +42,6 @@
42 #include <unistd.h> 42 #include <unistd.h>
43 #include <fcntl.h> 43 #include <fcntl.h>
44 44
45 -// #define SOCK_CLOSE(s) close(s->connection.sock); s->connection.sock = -1;  
46 -  
47 #include <stdlib.h> 45 #include <stdlib.h>
48 46
49 #include "hostc.h" 47 #include "hostc.h"
@@ -58,8 +56,8 @@ @@ -58,8 +56,8 @@
58 56
59 /*---[ Implement ]-------------------------------------------------------------------------------*/ 57 /*---[ Implement ]-------------------------------------------------------------------------------*/
60 58
61 -static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG GNUC_UNUSED(flag), void GNUC_UNUSED(*dunno))  
62 -{ 59 + static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG GNUC_UNUSED(flag), void GNUC_UNUSED(*dunno))
  60 + {
63 int err; 61 int err;
64 socklen_t len = sizeof(err); 62 socklen_t len = sizeof(err);
65 63
@@ -83,91 +81,94 @@ static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG @@ -83,91 +81,94 @@ static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG
83 } 81 }
84 else if(err) 82 else if(err)
85 { 83 {
86 - lib3270_autoptr(char) body = lib3270_strdup_printf(_("%s (rc=%d)"),strerror(err),err);  
87 - connection_failed(hSession,body); 84 + lib3270_autoptr(LIB3270_POPUP) popup =
  85 + lib3270_popup_clone_printf(
  86 + NULL,
  87 + _( "Can't connect to %s:%s"),
  88 + hSession->host.current,
  89 + hSession->host.srvc
  90 + );
  91 +
  92 + lib3270_autoptr(char) syserror =
  93 + lib3270_strdup_printf(
  94 + _("The system error was \"%s\" (rc=%d)"),
  95 + strerror(err),
  96 + err
  97 + );
  98 +
  99 + if(hSession->cbk.popup(hSession,popup,!hSession->auto_reconnect_inprogress) == 0)
  100 + lib3270_activate_auto_reconnect(hSession,1000);
  101 +
88 return; 102 return;
89 } 103 }
90 104
91 hSession->xio.except = hSession->network.module->add_poll(hSession,LIB3270_IO_FLAG_EXCEPTION,net_exception,0); 105 hSession->xio.except = hSession->network.module->add_poll(hSession,LIB3270_IO_FLAG_EXCEPTION,net_exception,0);
92 hSession->xio.read = hSession->network.module->add_poll(hSession,LIB3270_IO_FLAG_READ,net_input,0); 106 hSession->xio.read = hSession->network.module->add_poll(hSession,LIB3270_IO_FLAG_READ,net_input,0);
93 107
94 - if(lib3270_start_tls(hSession)) 108 + if(lib3270_start_tls(hSession,0))
95 return; 109 return;
96 110
97 lib3270_setup_session(hSession); 111 lib3270_setup_session(hSession);
98 lib3270_set_connected_initial(hSession); 112 lib3270_set_connected_initial(hSession);
99 113
100 -}  
101 -  
102 - struct resolver  
103 - {  
104 - const char * message;  
105 - }; 114 + }
106 115
107 - static int background_connect(H3270 *hSession, void *host) 116 + int net_reconnect(H3270 *hSession, int seconds)
108 { 117 {
  118 + LIB3270_NETWORK_STATE state;
  119 + memset(&state,0,sizeof(state));
109 120
110 - struct addrinfo hints;  
111 - struct addrinfo * result = NULL;  
112 - struct addrinfo * rp = NULL;  
113 -  
114 - memset(&hints,0,sizeof(hints));  
115 - hints.ai_family = AF_UNSPEC; // Allow IPv4 or IPv6  
116 - hints.ai_socktype = SOCK_STREAM; // Stream socket  
117 - hints.ai_flags = AI_PASSIVE; // For wildcard IP address  
118 - hints.ai_protocol = 0; // Any protocol  
119 -  
120 - status_resolving(hSession);  
121 -  
122 - int rc = getaddrinfo(hSession->host.current, hSession->host.srvc, &hints, &result);  
123 - if(rc != 0) 121 + // Initialize and connect to host
  122 + if(lib3270_run_task(hSession, (int(*)(H3270 *, void *)) hSession->network.module->connect, &state))
124 { 123 {
125 - ((struct resolver *) host)->message = gai_strerror(rc);  
126 - return -1;  
127 - }  
128 -  
129 - status_connecting(hSession);  
130 -  
131 - for(rp = result; hSession->connection.sock < 0 && rp != NULL; rp = rp->ai_next)  
132 - {  
133 - hSession->connection.sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);  
134 - if(hSession->connection.sock < 0) 124 + lib3270_autoptr(LIB3270_POPUP) popup =
  125 + lib3270_popup_clone_printf(
  126 + NULL,
  127 + _( "Can't connect to %s:%s"),
  128 + hSession->host.current,
  129 + hSession->host.srvc
  130 + );
  131 +
  132 + if(!popup->summary)
135 { 133 {
136 - ((struct resolver *) host)->message = strerror(errno);  
137 - continue; 134 + popup->summary = popup->body;
  135 + popup->body = NULL;
138 } 136 }
139 137
140 - // Connected!  
141 - if(connect(hSession->connection.sock, rp->ai_addr, rp->ai_addrlen)) 138 + lib3270_autoptr(char) syserror = NULL;
  139 + if(state.syserror)
142 { 140 {
143 - SOCK_CLOSE(hSession);  
144 - ((struct resolver *) host)->message = strerror(errno);  
145 - continue; 141 + syserror = lib3270_strdup_printf(
  142 + _("The system error was \"%s\" (rc=%d)"),
  143 + strerror(state.syserror),
  144 + state.syserror
  145 + );
146 } 146 }
  147 +#ifdef _WIN32
  148 + else if(state.winerror)
  149 + {
  150 + #error TODO
  151 + }
  152 +#endif // _WIN32
147 153
148 - }  
149 -  
150 - freeaddrinfo(result);  
151 -  
152 - return 0;  
153 -  
154 - } 154 + if(!popup->body)
  155 + {
  156 + if(state.error_message)
  157 + popup->body = state.error_message;
  158 + else
  159 + popup->body = syserror;
  160 + }
155 161
156 - int net_reconnect(H3270 *hSession, int seconds)  
157 - {  
158 - struct resolver host;  
159 - memset(&host,0,sizeof(host)); 162 + if(hSession->cbk.popup(hSession,popup,!hSession->auto_reconnect_inprogress) == 0)
  163 + lib3270_activate_auto_reconnect(hSession,1000);
160 164
161 - // Connect to host  
162 - if(lib3270_run_task(hSession, background_connect, &host) || hSession->connection.sock < 0)  
163 - {  
164 - connection_failed(hSession,host.message);  
165 return errno = ENOTCONN; 165 return errno = ENOTCONN;
166 } 166 }
167 167
168 - /* don't share the socket with our children */  
169 - (void) fcntl(hSession->connection.sock, F_SETFD, 1);  
170 168
  169 + //
  170 + // Connected
  171 + //
171 hSession->ever_3270 = False; 172 hSession->ever_3270 = False;
172 173
173 #if defined(HAVE_LIBSSL) 174 #if defined(HAVE_LIBSSL)
@@ -182,7 +183,7 @@ static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG @@ -182,7 +183,7 @@ static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG
182 183
183 // set options for inline out-of-band data and keepalives 184 // set options for inline out-of-band data and keepalives
184 int optval = 1; 185 int optval = 1;
185 - if (setsockopt(hSession->connection.sock, SOL_SOCKET, SO_OOBINLINE, (char *)&optval,sizeof(optval)) < 0) 186 + if(hSession->network.module->setsockopt(hSession, SOL_SOCKET, SO_OOBINLINE, &optval, sizeof(optval)) < 0)
186 { 187 {
187 int rc = errno; 188 int rc = errno;
188 lib3270_popup_dialog( hSession, 189 lib3270_popup_dialog( hSession,
@@ -191,12 +192,12 @@ static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG @@ -191,12 +192,12 @@ static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG
191 _( "setsockopt(SO_OOBINLINE) has failed" ), 192 _( "setsockopt(SO_OOBINLINE) has failed" ),
192 "%s", 193 "%s",
193 strerror(rc)); 194 strerror(rc));
194 - SOCK_CLOSE(hSession); 195 + hSession->network.module->disconnect(hSession);
195 return rc; 196 return rc;
196 } 197 }
197 198
198 optval = lib3270_get_toggle(hSession,LIB3270_TOGGLE_KEEP_ALIVE) ? 1 : 0; 199 optval = lib3270_get_toggle(hSession,LIB3270_TOGGLE_KEEP_ALIVE) ? 1 : 0;
199 - if (setsockopt(hSession->connection.sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&optval, sizeof(optval)) < 0) 200 + if (hSession->network.module->setsockopt(hSession, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval)) < 0)
200 { 201 {
201 int rc = errno; 202 int rc = errno;
202 203
@@ -209,7 +210,8 @@ static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG @@ -209,7 +210,8 @@ static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG
209 buffer, 210 buffer,
210 "%s", 211 "%s",
211 strerror(rc)); 212 strerror(rc));
212 - SOCK_CLOSE(hSession); 213 +
  214 + hSession->network.module->disconnect(hSession);
213 return rc; 215 return rc;
214 } 216 }
215 else 217 else
@@ -254,7 +256,7 @@ static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG @@ -254,7 +256,7 @@ static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG
254 case LIB3270_CONNECTED_INITIAL_E: 256 case LIB3270_CONNECTED_INITIAL_E:
255 case LIB3270_CONNECTED_NVT: 257 case LIB3270_CONNECTED_NVT:
256 case LIB3270_CONNECTED_SSCP: 258 case LIB3270_CONNECTED_SSCP:
257 - case LIB3270_RESOLVING: 259 + case LIB3270_CONNECTING:
258 break; 260 break;
259 261
260 case LIB3270_NOT_CONNECTED: 262 case LIB3270_NOT_CONNECTED:
src/core/popup.c
@@ -135,7 +135,14 @@ LIB3270_POPUP * lib3270_popup_clone_printf(const LIB3270_POPUP *origin, const ch @@ -135,7 +135,14 @@ LIB3270_POPUP * lib3270_popup_clone_printf(const LIB3270_POPUP *origin, const ch
135 // Alocate new struct 135 // Alocate new struct
136 LIB3270_POPUP * popup = lib3270_malloc(sizeof(LIB3270_POPUP)+strlen(body)+1); 136 LIB3270_POPUP * popup = lib3270_malloc(sizeof(LIB3270_POPUP)+strlen(body)+1);
137 137
138 - *popup = *origin; 138 + if(origin)
  139 + {
  140 + *popup = *origin;
  141 + }
  142 + else
  143 + {
  144 + memset(popup,0,sizeof(LIB3270_POPUP));
  145 + }
139 146
140 strcpy((char *)(popup+1),body); 147 strcpy((char *)(popup+1),body);
141 popup->body = (char *)(popup+1); 148 popup->body = (char *)(popup+1);
@@ -154,7 +161,8 @@ static int def_popup(H3270 *hSession, const LIB3270_POPUP *popup, unsigned char @@ -154,7 +161,8 @@ static int def_popup(H3270 *hSession, const LIB3270_POPUP *popup, unsigned char
154 161
155 for(ix = 0; ix < (sizeof(text)/sizeof(text[0])); ix++) 162 for(ix = 0; ix < (sizeof(text)/sizeof(text[0])); ix++)
156 { 163 {
157 - lib3270_write_log(hSession,"popup","%s",text[ix]); 164 + if(text[ix])
  165 + lib3270_write_log(hSession,"popup","%s",text[ix]);
158 } 166 }
159 167
160 return ENOTSUP; 168 return ENOTSUP;
src/core/properties/boolean.c
@@ -47,7 +47,7 @@ @@ -47,7 +47,7 @@
47 47
48 void lib3270_disable_crl_download(H3270 *hSession) 48 void lib3270_disable_crl_download(H3270 *hSession)
49 { 49 {
50 -#ifdef SSL_ENABLE_CRL_CHECK 50 +#if defined(HAVE_LIBSSL) && defined(SSL_ENABLE_CRL_CHECK)
51 hSession->ssl.crl.download = 0; 51 hSession->ssl.crl.download = 0;
52 #endif // SSL_ENABLE_CRL_CHECK 52 #endif // SSL_ENABLE_CRL_CHECK
53 } 53 }
src/core/properties/string.c
@@ -28,6 +28,7 @@ @@ -28,6 +28,7 @@
28 */ 28 */
29 29
30 #include <config.h> 30 #include <config.h>
  31 + #include <stdlib.h>
31 #include <internals.h> 32 #include <internals.h>
32 #include <string.h> 33 #include <string.h>
33 #include <lib3270.h> 34 #include <lib3270.h>
src/core/rpq.c
@@ -686,7 +686,7 @@ static int get_rpq_address(H3270 *hSession, unsigned char *buf, const int maxlen @@ -686,7 +686,7 @@ static int get_rpq_address(H3270 *hSession, unsigned char *buf, const int maxlen
686 struct sockaddr_in6 sa6; 686 struct sockaddr_in6 sa6;
687 #endif // HAVE_GETADDRINFO 687 #endif // HAVE_GETADDRINFO
688 } u; 688 } u;
689 - int addrlen = sizeof(u); 689 + socklen_t addrlen = sizeof(u);
690 void *src = NULL; 690 void *src = NULL;
691 int len = 0; 691 int len = 0;
692 692
src/core/screen.c
@@ -550,19 +550,21 @@ void status_oerr(H3270 *session, int error_type) @@ -550,19 +550,21 @@ void status_oerr(H3270 *session, int error_type)
550 */ 550 */
551 void status_resolving(H3270 *hSession) 551 void status_resolving(H3270 *hSession)
552 { 552 {
553 - lib3270_set_cstate(hSession,LIB3270_RESOLVING);  
554 - lib3270_st_changed(hSession, LIB3270_STATE_RESOLVING, True); 553 + debug("%s",__FUNCTION__);
555 554
556 mcursor_set(hSession,LIB3270_POINTER_LOCKED); 555 mcursor_set(hSession,LIB3270_POINTER_LOCKED);
  556 +
  557 + lib3270_st_changed(hSession, LIB3270_STATE_RESOLVING, True);
557 status_changed(hSession, LIB3270_MESSAGE_RESOLVING); 558 status_changed(hSession, LIB3270_MESSAGE_RESOLVING);
558 } 559 }
559 560
560 void status_connecting(H3270 *hSession) 561 void status_connecting(H3270 *hSession)
561 { 562 {
562 - lib3270_set_cstate(hSession,LIB3270_RESOLVING);  
563 - lib3270_st_changed(hSession, LIB3270_STATE_CONNECTING, True); 563 + debug("%s",__FUNCTION__);
564 564
565 mcursor_set(hSession,LIB3270_POINTER_LOCKED); 565 mcursor_set(hSession,LIB3270_POINTER_LOCKED);
  566 +
  567 + lib3270_st_changed(hSession, LIB3270_STATE_CONNECTING, True);
566 status_changed(hSession, LIB3270_MESSAGE_CONNECTING); 568 status_changed(hSession, LIB3270_MESSAGE_CONNECTING);
567 } 569 }
568 570
src/core/session.c
@@ -84,11 +84,17 @@ void lib3270_session_free(H3270 *h) @@ -84,11 +84,17 @@ void lib3270_session_free(H3270 *h)
84 lib3270_crl_free(h); 84 lib3270_crl_free(h);
85 #endif // SSL_ENABLE_CRL_CHECK 85 #endif // SSL_ENABLE_CRL_CHECK
86 86
  87 + // Release network module
  88 + if(h->network.module)
  89 + {
  90 + h->network.module->finalize(h);
  91 + h->network.module = NULL;
  92 + }
  93 +
87 // Release state change callbacks 94 // Release state change callbacks
88 for(f=0;f<LIB3270_STATE_USER;f++) 95 for(f=0;f<LIB3270_STATE_USER;f++)
89 lib3270_linked_list_free(&h->listeners.state[f]); 96 lib3270_linked_list_free(&h->listeners.state[f]);
90 97
91 -  
92 // Release toggle change listeners. 98 // Release toggle change listeners.
93 for(f=0;f<LIB3270_TOGGLE_COUNT;f++) 99 for(f=0;f<LIB3270_TOGGLE_COUNT;f++)
94 lib3270_linked_list_free(&h->listeners.toggle[f]); 100 lib3270_linked_list_free(&h->listeners.toggle[f]);
@@ -316,7 +322,11 @@ static void lib3270_session_init(H3270 *hSession, const char *model, const char @@ -316,7 +322,11 @@ static void lib3270_session_init(H3270 *hSession, const char *model, const char
316 int f; 322 int f;
317 323
318 memset(hSession,0,sizeof(H3270)); 324 memset(hSession,0,sizeof(H3270));
319 -// hSession->sz = sizeof(H3270); 325 + lib3270_set_default_network_module(hSession);
  326 +
  327 +#if defined(SSL_ENABLE_CRL_CHECK) && defined(HAVE_LIBSSL)
  328 + hSession->ssl.crl.download = 1;
  329 +#endif // SSL_ENABLE_CRL_CHECK
320 330
321 lib3270_set_host_charset(hSession,charset); 331 lib3270_set_host_charset(hSession,charset);
322 lib3270_reset_callbacks(hSession); 332 lib3270_reset_callbacks(hSession);
@@ -438,22 +448,11 @@ H3270 * lib3270_session_new(const char *model) @@ -438,22 +448,11 @@ H3270 * lib3270_session_new(const char *model)
438 trace("%s - configured=%s",__FUNCTION__,default_session ? "Yes" : "No"); 448 trace("%s - configured=%s",__FUNCTION__,default_session ? "Yes" : "No");
439 449
440 hSession = lib3270_malloc(sizeof(H3270)); 450 hSession = lib3270_malloc(sizeof(H3270));
441 - hSession->id = 0;  
442 -  
443 -#ifdef HAVE_LIBSSL  
444 - hSession->ssl.protocol.min_version = 0;  
445 - hSession->ssl.protocol.max_version = 0;  
446 -#endif // HAVE_LIBSSL  
447 -  
448 -#if defined(SSL_ENABLE_CRL_CHECK) && defined(HAVE_LIBSSL)  
449 - hSession->ssl.crl.download = 1;  
450 -#endif // SSL_ENABLE_CRL_CHECK 451 + lib3270_session_init(hSession, model, "bracket" );
451 452
452 if(!default_session) 453 if(!default_session)
453 default_session = hSession; 454 default_session = hSession;
454 455
455 - lib3270_session_init(hSession, model, "bracket" );  
456 -  
457 if(screen_init(hSession)) 456 if(screen_init(hSession))
458 return NULL; 457 return NULL;
459 458
src/core/state.c
@@ -38,12 +38,12 @@ LIB3270_EXPORT LIB3270_CSTATE lib3270_get_connection_state(const H3270 *h) @@ -38,12 +38,12 @@ LIB3270_EXPORT LIB3270_CSTATE lib3270_get_connection_state(const H3270 *h)
38 38
39 LIB3270_EXPORT int lib3270_pconnected(const H3270 *h) 39 LIB3270_EXPORT int lib3270_pconnected(const H3270 *h)
40 { 40 {
41 - return (((int) h->connection.state) >= (int)LIB3270_RESOLVING); 41 + return (((int) h->connection.state) >= (int)LIB3270_CONNECTING);
42 } 42 }
43 43
44 LIB3270_EXPORT int lib3270_half_connected(const H3270 *h) 44 LIB3270_EXPORT int lib3270_half_connected(const H3270 *h)
45 { 45 {
46 - return (h->connection.state == LIB3270_RESOLVING || h->connection.state == LIB3270_PENDING); 46 + return (h->connection.state == LIB3270_CONNECTING || h->connection.state == LIB3270_PENDING);
47 } 47 }
48 48
49 LIB3270_EXPORT int lib3270_is_disconnected(const H3270 *h) 49 LIB3270_EXPORT int lib3270_is_disconnected(const H3270 *h)
src/core/telnet.c
@@ -261,7 +261,6 @@ static const char *trsp_flag[2] = { &quot;POSITIVE-RESPONSE&quot;, &quot;NEGATIVE-RESPONSE&quot; }; @@ -261,7 +261,6 @@ static const char *trsp_flag[2] = { &quot;POSITIVE-RESPONSE&quot;, &quot;NEGATIVE-RESPONSE&quot; };
261 #define SE_EAGAIN WSAEINPROGRESS 261 #define SE_EAGAIN WSAEINPROGRESS
262 #define SE_EPIPE WSAECONNABORTED 262 #define SE_EPIPE WSAECONNABORTED
263 #define SE_EINPROGRESS WSAEINPROGRESS 263 #define SE_EINPROGRESS WSAEINPROGRESS
264 - #define SOCK_CLOSE(s) closesocket(s)  
265 #define SOCK_IOCTL(s, f, v) ioctlsocket(s, f, (void *)v) 264 #define SOCK_IOCTL(s, f, v) ioctlsocket(s, f, (void *)v)
266 #else /*][*/ 265 #else /*][*/
267 #define socket_errno() errno 266 #define socket_errno() errno
@@ -275,7 +274,6 @@ static const char *trsp_flag[2] = { &quot;POSITIVE-RESPONSE&quot;, &quot;NEGATIVE-RESPONSE&quot; }; @@ -275,7 +274,6 @@ static const char *trsp_flag[2] = { &quot;POSITIVE-RESPONSE&quot;, &quot;NEGATIVE-RESPONSE&quot; };
275 #define SE_EINPROGRESS EINPROGRESS 274 #define SE_EINPROGRESS EINPROGRESS
276 #endif /*]*/ 275 #endif /*]*/
277 276
278 - #define SOCK_CLOSE(s) close(s)  
279 #define SOCK_IOCTL ioctl 277 #define SOCK_IOCTL ioctl
280 #endif /*]*/ 278 #endif /*]*/
281 279
@@ -539,8 +537,6 @@ LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession) @@ -539,8 +537,6 @@ LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession)
539 */ 537 */
540 void net_disconnect(H3270 *hSession) 538 void net_disconnect(H3270 *hSession)
541 { 539 {
542 - LIB3270_NETWORK_STATE state;  
543 - memset(&state,0,sizeof(state));  
544 540
545 // Disconnect from host 541 // Disconnect from host
546 #if defined(HAVE_LIBSSL) 542 #if defined(HAVE_LIBSSL)
@@ -563,7 +559,7 @@ void net_disconnect(H3270 *hSession) @@ -563,7 +559,7 @@ void net_disconnect(H3270 *hSession)
563 hSession->xio.write = 0; 559 hSession->xio.write = 0;
564 } 560 }
565 561
566 - hSession->network.module->disconnect(hSession,&state); 562 + hSession->network.module->disconnect(hSession);
567 563
568 trace_dsn(hSession,"SENT disconnect\n"); 564 trace_dsn(hSession,"SENT disconnect\n");
569 565
@@ -641,9 +637,9 @@ void net_input(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG GNUC_UNUSED @@ -641,9 +637,9 @@ void net_input(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG GNUC_UNUSED
641 if (hSession->ssl.con != NULL) 637 if (hSession->ssl.con != NULL)
642 nr = SSL_read(hSession->ssl.con, (char *) buffer, BUFSZ); 638 nr = SSL_read(hSession->ssl.con, (char *) buffer, BUFSZ);
643 else 639 else
644 - nr = hSession->network.module->recv(hSession->network.context, buffer, BUFSZ); 640 + nr = hSession->network.module->recv(hSession, buffer, BUFSZ);
645 #else 641 #else
646 - nr = hSession->network.module->recv(hSession->network.context, buffer, BUFSZ); 642 + nr = hSession->network.module->recv(hSession, buffer, BUFSZ);
647 #endif // HAVE_LIBSSL 643 #endif // HAVE_LIBSSL
648 644
649 if (nr < 0) 645 if (nr < 0)
@@ -1602,13 +1598,10 @@ static int process_eor(H3270 *hSession) @@ -1602,13 +1598,10 @@ static int process_eor(H3270 *hSession)
1602 return 0; 1598 return 0;
1603 } 1599 }
1604 1600
1605 -  
1606 -/**  
1607 - * @brief Called when there is an exceptional condition on the socket.  
1608 - */ 1601 +/// @brief Called when there is an exceptional condition on the socket.
1609 void net_exception(H3270 *session, int GNUC_UNUSED(fd), LIB3270_IO_FLAG GNUC_UNUSED(flag), void GNUC_UNUSED(*dunno)) 1602 void net_exception(H3270 *session, int GNUC_UNUSED(fd), LIB3270_IO_FLAG GNUC_UNUSED(flag), void GNUC_UNUSED(*dunno))
1610 { 1603 {
1611 - CHECK_SESSION_HANDLE(session); 1604 + debug("%s",__FUNCTION__);
1612 1605
1613 trace_dsn(session,"RCVD urgent data indication\n"); 1606 trace_dsn(session,"RCVD urgent data indication\n");
1614 if (!session->syncing) 1607 if (!session->syncing)
@@ -1655,9 +1648,10 @@ LIB3270_INTERNAL int lib3270_sock_send(H3270 *hSession, unsigned const char *buf @@ -1655,9 +1648,10 @@ LIB3270_INTERNAL int lib3270_sock_send(H3270 *hSession, unsigned const char *buf
1655 if(rc > 0) 1648 if(rc > 0)
1656 return rc; 1649 return rc;
1657 1650
1658 - // Recv error, notify 1651 + // Send error, notify
1659 1652
1660 #if defined(HAVE_LIBSSL) 1653 #if defined(HAVE_LIBSSL)
  1654 + #error TODO - The send method should emit popup messages.
1661 if(hSession->ssl.con != NULL) 1655 if(hSession->ssl.con != NULL)
1662 { 1656 {
1663 unsigned long e; 1657 unsigned long e;
@@ -1671,25 +1665,7 @@ LIB3270_INTERNAL int lib3270_sock_send(H3270 *hSession, unsigned const char *buf @@ -1671,25 +1665,7 @@ LIB3270_INTERNAL int lib3270_sock_send(H3270 *hSession, unsigned const char *buf
1671 } 1665 }
1672 #endif // HAVE_LIBSSL 1666 #endif // HAVE_LIBSSL
1673 1667
1674 - trace_dsn(hSession,"RCVD socket error %d\n", socket_errno());  
1675 -  
1676 - switch(socket_errno())  
1677 - {  
1678 - case SE_EPIPE:  
1679 - popup_an_error(hSession, "%s", _( "Broken pipe" ));  
1680 - break;  
1681 -  
1682 - case SE_ECONNRESET:  
1683 - popup_an_error(hSession, "%s", _( "Connection reset by peer" ));  
1684 - break;  
1685 -  
1686 - case SE_EINTR:  
1687 - return 0;  
1688 -  
1689 - default:  
1690 - popup_a_sockerr(NULL, "%s", _( "Socket write error" ) );  
1691 -  
1692 - } 1668 + trace_dsn(hSession,"RCVD socket error %d\n", -rc);
1693 1669
1694 return -1; 1670 return -1;
1695 } 1671 }
@@ -2029,7 +2005,7 @@ const char * lib3270_connection_state_get_name(const LIB3270_CSTATE cstate) @@ -2029,7 +2005,7 @@ const char * lib3270_connection_state_get_name(const LIB3270_CSTATE cstate)
2029 static const char *state_names[] = 2005 static const char *state_names[] =
2030 { 2006 {
2031 "unconnected", 2007 "unconnected",
2032 - "resolving", 2008 + "connecting",
2033 "pending", 2009 "pending",
2034 "connected initial", 2010 "connected initial",
2035 "TN3270 NVT", 2011 "TN3270 NVT",
src/core/toggles/init.c
@@ -77,19 +77,22 @@ static void toggle_nop(H3270 GNUC_UNUSED(*session), const struct lib3270_toggle @@ -77,19 +77,22 @@ static void toggle_nop(H3270 GNUC_UNUSED(*session), const struct lib3270_toggle
77 { 77 {
78 } 78 }
79 79
80 -static void toggle_keepalive(H3270 *session, const struct lib3270_toggle GNUC_UNUSED(*t), LIB3270_TOGGLE_TYPE GNUC_UNUSED(tt)) 80 +static void toggle_keepalive(H3270 *hSession, const struct lib3270_toggle GNUC_UNUSED(*t), LIB3270_TOGGLE_TYPE GNUC_UNUSED(tt))
81 { 81 {
82 - // Update keep-alive option  
83 - int optval = t->value ? 1 : 0;  
84 -  
85 - if(session->network.module->setsockopt(session, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval)) < 0)  
86 - {  
87 - if(errno != ENOTCONN)  
88 - popup_a_sockerr(session, _( "Can't %s network keep-alive" ), optval ? _( "enable" ) : _( "disable" ));  
89 - }  
90 - else 82 + if(hSession->network.context)
91 { 83 {
92 - trace_dsn(session,"Network keep-alive is %s\n",optval ? "enabled" : "disabled" ); 84 + // Has network context, update keep-alive option
  85 + int optval = t->value ? 1 : 0;
  86 +
  87 + if(hSession->network.module->setsockopt(hSession, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval)) < 0)
  88 + {
  89 + if(errno != ENOTCONN)
  90 + popup_a_sockerr(hSession, _( "Can't %s network keep-alive" ), optval ? _( "enable" ) : _( "disable" ));
  91 + }
  92 + else
  93 + {
  94 + trace_dsn(hSession,"Network keep-alive is %s\n",optval ? "enabled" : "disabled" );
  95 + }
93 } 96 }
94 97
95 } 98 }
src/core/util.c
@@ -44,6 +44,10 @@ @@ -44,6 +44,10 @@
44 #include <openssl/opensslv.h> 44 #include <openssl/opensslv.h>
45 #endif // HAVE_LIBSSL 45 #endif // HAVE_LIBSSL
46 46
  47 +#if defined(HAVE_MALLOC_H)
  48 + #include <malloc.h>
  49 +#endif // defined
  50 +
47 #define my_isspace(c) isspace((unsigned char)c) 51 #define my_isspace(c) isspace((unsigned char)c)
48 52
49 /** 53 /**
src/core/windows/connect.c
@@ -47,8 +47,6 @@ @@ -47,8 +47,6 @@
47 #include <iconv.h> 47 #include <iconv.h>
48 #endif // HAVE_ICONV 48 #endif // HAVE_ICONV
49 49
50 -#define SOCK_CLOSE(s) closesocket(s->connection.sock); s->connection.sock = -1;  
51 -  
52 #include "hostc.h" 50 #include "hostc.h"
53 #include "trace_dsc.h" 51 #include "trace_dsc.h"
54 #include "telnetc.h" 52 #include "telnetc.h"
src/include/internals.h
@@ -883,10 +883,16 @@ LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on); @@ -883,10 +883,16 @@ LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on);
883 /// @brief Fire CState change. 883 /// @brief Fire CState change.
884 LIB3270_INTERNAL int lib3270_set_cstate(H3270 *hSession, LIB3270_CSTATE cstate); 884 LIB3270_INTERNAL int lib3270_set_cstate(H3270 *hSession, LIB3270_CSTATE cstate);
885 885
886 - inline LIB3270_NET_CONTEXT * lib3270_get_net_context(H3270 *hSession) {  
887 - return hSession->network.context;  
888 - }  
889 -  
890 - LIB3270_INTERNAL int lib3270_start_tls(H3270 *hSession); 886 + ///
  887 + /// @brief Start TLS/SSL
  888 + ///
  889 + /// @param hSession Session handle.
  890 + /// @param required Non zero if the SSL/TLS is not optional.
  891 + ///
  892 + /// @return 0 if ok, non zero if failed.
  893 + ///
  894 + /// @retval ENOTSUP TLS/SSL is not supported by library.
  895 + ///
  896 + LIB3270_INTERNAL int lib3270_start_tls(H3270 *hSession, Bool required);
891 897
892 898
src/include/lib3270.h
@@ -252,7 +252,7 @@ @@ -252,7 +252,7 @@
252 typedef enum lib3270_cstate 252 typedef enum lib3270_cstate
253 { 253 {
254 LIB3270_NOT_CONNECTED, ///< @brief no socket, disconnected 254 LIB3270_NOT_CONNECTED, ///< @brief no socket, disconnected
255 - LIB3270_RESOLVING, ///< @brief resolving hostname 255 + LIB3270_CONNECTING, ///< @brief connecting to host
256 LIB3270_PENDING, ///< @brief connection pending 256 LIB3270_PENDING, ///< @brief connection pending
257 LIB3270_CONNECTED_INITIAL, ///< @brief connected, no mode yet 257 LIB3270_CONNECTED_INITIAL, ///< @brief connected, no mode yet
258 LIB3270_CONNECTED_ANSI, ///< @brief connected in NVT ANSI mode 258 LIB3270_CONNECTED_ANSI, ///< @brief connected in NVT ANSI mode
src/include/networking.h
@@ -41,34 +41,23 @@ @@ -41,34 +41,23 @@
41 DWORD winerror; ///< @brief Win32 error got from GetLastError() 41 DWORD winerror; ///< @brief Win32 error got from GetLastError()
42 #endif // _WIN32 42 #endif // _WIN32
43 43
  44 + const char * error_message; /// @brief System error message.
  45 +
44 const LIB3270_POPUP *popup; /// @brief Detailed info for popup. 46 const LIB3270_POPUP *popup; /// @brief Detailed info for popup.
45 47
46 } LIB3270_NETWORK_STATE; 48 } LIB3270_NETWORK_STATE;
47 49
48 - typedef struct _lib3270_new_context LIB3270_NET_CONTEXT; 50 + typedef struct _lib3270_net_context LIB3270_NET_CONTEXT;
49 51
50 typedef struct lib3270_net_module { 52 typedef struct lib3270_net_module {
51 53
52 - const char * name; ///< @brief The network module name.  
53 -  
54 - /// @brief Initialize network module  
55 - ///  
56 - /// @param hSession TN3270 session.  
57 - /// @param state Pointer to state message.  
58 - ///  
59 - /// @return Allocated network context.  
60 - ///  
61 - /// @retval NULL Initialization failed.  
62 - ///  
63 - LIB3270_NET_CONTEXT * (*init)(H3270 *hSession, LIB3270_NETWORK_STATE *state);  
64 -  
65 /// @brief Deinitialize network module. 54 /// @brief Deinitialize network module.
66 /// 55 ///
67 /// @param context Network context. 56 /// @param context Network context.
68 /// @param hSession TN3270 session. 57 /// @param hSession TN3270 session.
69 /// @param state Pointer to state message. 58 /// @param state Pointer to state message.
70 /// 59 ///
71 - void (*deinit)(H3270 *hSession, LIB3270_NETWORK_STATE *state); 60 + void (*finalize)(H3270 *hSession);
72 61
73 /// @brief Connect to host. 62 /// @brief Connect to host.
74 /// 63 ///
@@ -77,7 +66,7 @@ @@ -77,7 +66,7 @@
77 /// @param seconds Seconds for timeout. 66 /// @param seconds Seconds for timeout.
78 /// @param state Pointer to state message. 67 /// @param state Pointer to state message.
79 /// 68 ///
80 - int (*connect)(H3270 *hSession, int seconds, LIB3270_NETWORK_STATE *state); 69 + int (*connect)(H3270 *hSession, LIB3270_NETWORK_STATE *state);
81 70
82 /// @brief Disconnect from host. 71 /// @brief Disconnect from host.
83 /// 72 ///
@@ -85,9 +74,9 @@ @@ -85,9 +74,9 @@
85 /// @param hSession TN3270 session. 74 /// @param hSession TN3270 session.
86 /// @param state Pointer to state message. 75 /// @param state Pointer to state message.
87 /// 76 ///
88 - int (*disconnect)(H3270 *hSession, LIB3270_NETWORK_STATE *state); 77 + int (*disconnect)(H3270 *hSession);
89 78
90 - int (*start_tls)(H3270 *hSession, LIB3270_NETWORK_STATE *msg); 79 + int (*start_tls)(H3270 *hSession, LIB3270_NETWORK_STATE *msg, unsigned char required);
91 80
92 /// @brief Send on network context. 81 /// @brief Send on network context.
93 /// 82 ///
@@ -126,16 +115,26 @@ @@ -126,16 +115,26 @@
126 int (*getsockname)(const H3270 *hSession, struct sockaddr *addr, socklen_t *addrlen); 115 int (*getsockname)(const H3270 *hSession, struct sockaddr *addr, socklen_t *addrlen);
127 116
128 /// @brief Set socket options. 117 /// @brief Set socket options.
129 - int (*setsockopt)(H3270 *hSession, int level, int optname, void *optval, size_t optlen); 118 + int (*setsockopt)(H3270 *hSession, int level, int optname, const void *optval, size_t optlen);
130 119
131 /// @brief Get socket options. 120 /// @brief Get socket options.
132 int (*getsockopt)(H3270 *hSession, int level, int optname, void *optval, socklen_t *optlen); 121 int (*getsockopt)(H3270 *hSession, int level, int optname, void *optval, socklen_t *optlen);
133 122
134 } LIB3270_NET_MODULE; 123 } LIB3270_NET_MODULE;
135 124
136 - LIB3270_NET_CONTEXT * lib3270_get_net_context(H3270 *hSession);  
137 - LIB3270_NET_CONTEXT * lib3270_get_default_net_context(void);  
138 - 125 + /**
  126 + * @brief Activate the default (and insecure) network module.
  127 + *
  128 + */
  129 + LIB3270_INTERNAL void lib3270_set_default_network_module(H3270 *hSession);
  130 +
  131 + /**
  132 + * @brief Connect to host, returns a connected socket.
  133 + *
  134 + * @return The Socket number or -1 in case of failure.
  135 + *
  136 + */
  137 + LIB3270_INTERNAL int lib3270_network_connect(H3270 *hSession, LIB3270_NETWORK_STATE *state);
139 138
140 #endif // LIB3270_NETWORKING_H_INCLUDED 139 #endif // LIB3270_NETWORKING_H_INCLUDED
141 140
src/network_modules/linux/connect.c 0 → 100644
@@ -0,0 +1,118 @@ @@ -0,0 +1,118 @@
  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 ', 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 networking.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 + /**
  31 + * @brief Default networking methods.
  32 + *
  33 + */
  34 +
  35 + #include <config.h>
  36 + #include <internals.h>
  37 + #include <networking.h>
  38 + #include <screen.h>
  39 + #include <unistd.h>
  40 + #include <fcntl.h>
  41 +
  42 + #include <sys/types.h>
  43 + #include <sys/socket.h>
  44 + #include <netdb.h>
  45 +
  46 +int lib3270_network_connect(H3270 *hSession, LIB3270_NETWORK_STATE *state) {
  47 +
  48 + //
  49 + // Resolve hostname
  50 + //
  51 + struct addrinfo hints;
  52 + struct addrinfo * result = NULL;
  53 + memset(&hints,0,sizeof(hints));
  54 + hints.ai_family = AF_UNSPEC; // Allow IPv4 or IPv6
  55 + hints.ai_socktype = SOCK_STREAM; // Stream socket
  56 + hints.ai_flags = AI_PASSIVE; // For wildcard IP address
  57 + hints.ai_protocol = 0; // Any protocol
  58 +
  59 + status_resolving(hSession);
  60 +
  61 + int rc = getaddrinfo(hSession->host.current, hSession->host.srvc, &hints, &result);
  62 + if(rc)
  63 + {
  64 + state->error_message = gai_strerror(rc);
  65 + return -1;
  66 + }
  67 +
  68 + //
  69 + // Try connecting to hosts.
  70 + //
  71 + int sock = -1;
  72 + struct addrinfo * rp = NULL;
  73 +
  74 + status_connecting(hSession);
  75 +
  76 + for(rp = result; sock < 0 && rp != NULL; rp = rp->ai_next)
  77 + {
  78 + // Got socket from host definition.
  79 + sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
  80 + if(sock < 0)
  81 + {
  82 + // Can't get socket.
  83 + state->syserror = errno;
  84 + continue;
  85 + }
  86 +
  87 + // Try connect.
  88 + if(connect(sock, rp->ai_addr, rp->ai_addrlen))
  89 + {
  90 + // Can't connect to host
  91 + state->syserror = errno;
  92 + close(sock);
  93 + sock = -1;
  94 + continue;
  95 + }
  96 +
  97 + }
  98 +
  99 + freeaddrinfo(result);
  100 +
  101 + if(sock < 0)
  102 + {
  103 + static const LIB3270_POPUP popup = {
  104 + .name = "CantConnect",
  105 + .type = LIB3270_NOTIFY_ERROR,
  106 + .summary = N_("Can't connect to host"),
  107 + .label = N_("Try again")
  108 + };
  109 +
  110 + state->popup = &popup;
  111 + return sock;
  112 + }
  113 +
  114 + // don't share the socket with our children
  115 + (void) fcntl(sock, F_SETFD, 1);
  116 +
  117 + return sock;
  118 +}
src/network_modules/private.h 0 → 100644
@@ -0,0 +1,52 @@ @@ -0,0 +1,52 @@
  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 LIB3270_NETWORK_MODULES_PRIVATE_H_INCLUDED
  31 +
  32 + #define LIB3270_NETWORK_MODULES_PRIVATE_H_INCLUDED
  33 +
  34 + #include <config.h>
  35 +
  36 + #ifdef _WIN32
  37 + #include <winsock.h>
  38 + #include <windows.h>
  39 + #else
  40 + #include <unistd.h>
  41 + #include <fcntl.h>
  42 + #endif // _WIN32
  43 +
  44 + #include <internals.h>
  45 + #include <networking.h>
  46 +
  47 + #include <lib3270.h>
  48 + #include <lib3270/log.h>
  49 +
  50 + LIB3270_INTERNAL ssize_t unsecure_network_send(H3270 *hSession, const void *buffer, size_t length);
  51 +
  52 +#endif // !LIB3270_NETWORK_MODULES_PRIVATE_H_INCLUDED
src/network_modules/unsecure.c
@@ -32,45 +32,41 @@ @@ -32,45 +32,41 @@
32 * 32 *
33 */ 33 */
34 34
35 - #include <config.h>  
36 - #ifdef _WIN32  
37 - #include <winsock.h>  
38 - #include <windows.h>  
39 - #endif // _WIN32 35 + #include "private.h"
40 36
41 - #include <internals.h>  
42 - #include <networking.h> 37 + #include <sys/types.h>
  38 + #include <sys/socket.h>
  39 + #include <netdb.h>
43 40
44 - struct _lib3270_new_context { 41 + struct _lib3270_net_context {
45 int sock; 42 int sock;
46 }; 43 };
47 44
48 - LIB3270_NET_CONTEXT * unsecure_network_init(H3270 *hSession, LIB3270_NETWORK_STATE *state) { 45 + static void unsecure_network_finalize(H3270 *hSession) {
49 46
50 - LIB3270_NET_CONTEXT * context = lib3270_malloc(sizeof(LIB3270_NET_CONTEXT));  
51 -  
52 - context->sock = -1; 47 + debug("%s",__FUNCTION__);
53 48
54 - return context;  
55 - } 49 + if(hSession->network.context) {
  50 + lib3270_free(hSession->network.context);
  51 + hSession->network.context = NULL;
  52 + }
56 53
57 - void unsecure_network_deinit(H3270 *hSession, LIB3270_NETWORK_STATE *state) {  
58 - unsecure_network_disconnect(hSession->network.context,hSession,state);  
59 - lib3270_free(context);  
60 } 54 }
61 55
62 -int unsecure_network_disconnect(H3270 *hSession, LIB3270_NETWORK_STATE *state) { 56 + static int unsecure_network_disconnect(H3270 *hSession) {
63 57
64 debug("%s",__FUNCTION__); 58 debug("%s",__FUNCTION__);
65 - if(context->sock >= 0) {  
66 - shutdown(hSession.network.context->sock, 2); 59 +
  60 + if(hSession->network.context->sock >= 0) {
  61 + shutdown(hSession->network.context->sock, 2);
67 close(hSession->network.context->sock); 62 close(hSession->network.context->sock);
68 - hSession.network.context->sock = -1; 63 + hSession->network.context->sock = -1;
69 } 64 }
70 65
71 -} 66 + return 0;
  67 + }
72 68
73 -ssize_t unsecure_network_send(H3270 *hSession, const void *buffer, size_t length) { 69 + ssize_t unsecure_network_send(H3270 *hSession, const void *buffer, size_t length) {
74 70
75 if(hSession->network.context->sock < 0) { 71 if(hSession->network.context->sock < 0) {
76 return -(errno = ENOTCONN); 72 return -(errno = ENOTCONN);
@@ -78,19 +74,68 @@ ssize_t unsecure_network_send(H3270 *hSession, const void *buffer, size_t length @@ -78,19 +74,68 @@ ssize_t unsecure_network_send(H3270 *hSession, const void *buffer, size_t length
78 74
79 ssize_t bytes = send(hSession->network.context->sock,buffer,length,0); 75 ssize_t bytes = send(hSession->network.context->sock,buffer,length,0);
80 76
81 - if(bytes < 0)  
82 - return -errno; 77 + debug("%s bytes=%d",__FUNCTION__,(int) bytes);
83 78
84 - return 0;  
85 -} 79 + if(bytes >= 0)
  80 + return bytes;
  81 +
  82 + int rc = errno;
86 83
87 -ssize_t unsecure_network_recv(H3270 *hSession, void *buf, size_t len) { 84 + debug("%s: %s",__FUNCTION__,strerror(rc));
  85 +
  86 + switch(rc)
  87 + {
  88 + case EPIPE:
  89 + lib3270_popup_dialog(
  90 + hSession,
  91 + LIB3270_NOTIFY_ERROR,
  92 + NULL,
  93 + _("Broken pipe"),
  94 + _("The system error code was %d"),
  95 + rc
  96 + );
  97 + break;
  98 +
  99 + case ECONNRESET:
  100 + lib3270_popup_dialog(
  101 + hSession,
  102 + LIB3270_NOTIFY_ERROR,
  103 + NULL,
  104 + _("Connection reset by peer"),
  105 + _("The system error code was %d"),
  106 + rc
  107 + );
  108 + break;
  109 +
  110 + case EINTR:
  111 + return 0;
  112 +
  113 + default:
  114 + lib3270_popup_dialog(
  115 + hSession,
  116 + LIB3270_NOTIFY_ERROR,
  117 + NULL,
  118 + _("Unexpected error writing to network socket"),
  119 + _("The system error code was %d (%s)"),
  120 + rc, strerror(rc)
  121 + );
  122 +
  123 + }
  124 +
  125 + return -rc;
  126 + }
  127 +
  128 + static ssize_t unsecure_network_recv(H3270 *hSession, void *buf, size_t len) {
  129 +
  130 + debug("%s",__FUNCTION__);
88 131
89 if(hSession->network.context->sock < 0) { 132 if(hSession->network.context->sock < 0) {
90 return -(errno = ENOTCONN); 133 return -(errno = ENOTCONN);
91 } 134 }
92 135
93 - ssize_t bytes = recv(hSession->network.context->sock, (char *) buffer, len, 0); 136 + ssize_t bytes = recv(hSession->network.context->sock, (char *) buf, len, 0);
  137 +
  138 + debug("%s bytes=%d",__FUNCTION__,(int) bytes);
94 139
95 if(bytes < 0) { 140 if(bytes < 0) {
96 return -errno; 141 return -errno;
@@ -99,17 +144,17 @@ ssize_t unsecure_network_recv(H3270 *hSession, void *buf, size_t len) { @@ -99,17 +144,17 @@ ssize_t unsecure_network_recv(H3270 *hSession, void *buf, size_t len) {
99 return bytes; 144 return bytes;
100 } 145 }
101 146
102 -int unsecure_getsockname(const H3270 *hSession, struct sockaddr *addr, socklen_t *addrlen) { 147 +static int unsecure_network_getsockname(const H3270 *hSession, struct sockaddr *addr, socklen_t *addrlen) {
103 if(hSession->network.context->sock < 0) 148 if(hSession->network.context->sock < 0)
104 return -(errno = ENOTCONN); 149 return -(errno = ENOTCONN);
105 - return getsockname(hSession->network.context->sock, buf, addrlen); 150 + return getsockname(hSession->network.context->sock, addr, addrlen);
106 } 151 }
107 152
108 -void * unsecure_add_poll(H3270 *hSession, LIB3270_IO_FLAG flag, void(*call)(H3270 *, int, LIB3270_IO_FLAG, void *), void *userdata) { 153 +static void * unsecure_network_add_poll(H3270 *hSession, LIB3270_IO_FLAG flag, void(*call)(H3270 *, int, LIB3270_IO_FLAG, void *), void *userdata) {
109 return lib3270_add_poll_fd(hSession,hSession->network.context->sock,flag,call,userdata); 154 return lib3270_add_poll_fd(hSession,hSession->network.context->sock,flag,call,userdata);
110 } 155 }
111 156
112 -int unsecure_non_blocking(H3270 *hSession, const unsigned char on) { 157 +static int unsecure_network_non_blocking(H3270 *hSession, const unsigned char on) {
113 158
114 if(hSession->network.context->sock < 0) 159 if(hSession->network.context->sock < 0)
115 return 0; 160 return 0;
@@ -165,29 +210,93 @@ int unsecure_non_blocking(H3270 *hSession, const unsigned char on) { @@ -165,29 +210,93 @@ int unsecure_non_blocking(H3270 *hSession, const unsigned char on) {
165 210
166 debug("Socket %d is now %s",hSession->network.context->sock,(on ? "Non Blocking" : "Blocking")); 211 debug("Socket %d is now %s",hSession->network.context->sock,(on ? "Non Blocking" : "Blocking"));
167 212
  213 + return 0;
168 } 214 }
169 215
170 -int unsecure_is_connected(H3270 *hSession) {  
171 - return hSession->network.context.sock > 0; 216 +static int unsecure_network_is_connected(H3270 *hSession) {
  217 + return hSession->network.context->sock > 0;
172 } 218 }
173 219
174 -int unsecure_setsockopt(H3270 *hSession, int level, int optname, const void *optval, size_t optlen) { 220 +static int unsecure_network_setsockopt(H3270 *hSession, int level, int optname, const void *optval, size_t optlen) {
175 221
176 - if(hSession->network.context.sock < 0) { 222 + if(hSession->network.context->sock < 0) {
177 errno = ENOTCONN; 223 errno = ENOTCONN;
178 return -1; 224 return -1;
179 } 225 }
180 226
181 - return setsockopt(hSession->network.context.sock, level, optname, optval, optlen); 227 + return setsockopt(hSession->network.context->sock, level, optname, optval, optlen);
182 228
183 } 229 }
184 230
185 -int unsecure_getsockopt(H3270 *hSession, int level, int optname, void *optval, socklen_t *optlen) { 231 +static int unsecure_network_getsockopt(H3270 *hSession, int level, int optname, void *optval, socklen_t *optlen) {
186 232
187 - if(hSession->network.context.sock < 0) { 233 + if(hSession->network.context->sock < 0) {
188 errno = ENOTCONN; 234 errno = ENOTCONN;
189 return -1; 235 return -1;
190 } 236 }
191 237
192 - return getsockopt(hSession->network.context.sock, level, optname, optval, optlen) 238 + return getsockopt(hSession->network.context->sock, level, optname, optval, optlen);
  239 +}
  240 +
  241 +static int unsecure_network_connect(H3270 *hSession, LIB3270_NETWORK_STATE *state) {
  242 +
  243 + hSession->network.context->sock = lib3270_network_connect(hSession, state);
  244 + if(hSession->network.context->sock < 0)
  245 + return hSession->network.context->sock;
  246 +
  247 + return 0;
193 } 248 }
  249 +
  250 +static int unsecure_network_start_tls(H3270 GNUC_UNUSED(*hSession), LIB3270_NETWORK_STATE *msg, unsigned char required) {
  251 +
  252 + if(required) {
  253 +
  254 + // TODO: Replace network module with the openssl version, initialize and execute start_tls on it.
  255 +
  256 + static const LIB3270_POPUP popup = {
  257 + .type = LIB3270_NOTIFY_ERROR,
  258 + .summary = N_("Can't activate SSL/TLS"),
  259 + .body = N_("The protocol library was build without SSL/TLS support")
  260 + };
  261 +
  262 + msg->popup = &popup;
  263 +
  264 + return ENOTSUP;
  265 +
  266 + }
  267 +
  268 + return 0;
  269 +}
  270 +
  271 +void lib3270_set_default_network_module(H3270 *hSession) {
  272 +
  273 + static const LIB3270_NET_MODULE module = {
  274 + .finalize = unsecure_network_finalize,
  275 + .connect = unsecure_network_connect,
  276 + .disconnect = unsecure_network_disconnect,
  277 + .start_tls = unsecure_network_start_tls,
  278 + .send = unsecure_network_send,
  279 + .recv = unsecure_network_recv,
  280 + .add_poll = unsecure_network_add_poll,
  281 + .non_blocking = unsecure_network_non_blocking,
  282 + .is_connected = unsecure_network_is_connected,
  283 + .getsockname = unsecure_network_getsockname,
  284 + .setsockopt = unsecure_network_setsockopt,
  285 + .getsockopt = unsecure_network_getsockopt
  286 + };
  287 +
  288 + debug("%s",__FUNCTION__);
  289 +
  290 + if(hSession->network.context) {
  291 + // Has context, finalize it.
  292 + hSession->network.module->finalize(hSession);
  293 + }
  294 +
  295 + hSession->network.context = lib3270_malloc(sizeof(LIB3270_NET_CONTEXT));
  296 + memset(hSession->network.context,0,sizeof(LIB3270_NET_CONTEXT));
  297 + hSession->network.context->sock = -1;
  298 +
  299 + hSession->network.module = &module;
  300 +
  301 +}
  302 +
src/ssl/linux/private.h
@@ -45,14 +45,14 @@ @@ -45,14 +45,14 @@
45 #include <lib3270/trace.h> 45 #include <lib3270/trace.h>
46 #include <lib3270/log.h> 46 #include <lib3270/log.h>
47 47
48 - #ifdef HAVE_LDAP 48 + #if defined(HAVE_LIBSSL) && defined(HAVE_LDAP)
49 49
50 /// @brief Use libldap to get CRL. 50 /// @brief Use libldap to get CRL.
51 LIB3270_INTERNAL X509_CRL * get_crl_using_ldap(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *consturl); 51 LIB3270_INTERNAL X509_CRL * get_crl_using_ldap(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *consturl);
52 52
53 #endif // HAVE_LDAP 53 #endif // HAVE_LDAP
54 54
55 - #ifdef HAVE_LIBCURL 55 + #if defined (HAVE_LIBSSL) && defined(HAVE_LIBCURL)
56 56
57 /// @brief Use libcurl to get CRL. 57 /// @brief Use libcurl to get CRL.
58 LIB3270_INTERNAL X509_CRL * get_crl_using_url(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *consturl); 58 LIB3270_INTERNAL X509_CRL * get_crl_using_url(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *consturl);
src/ssl/properties.c
@@ -51,7 +51,7 @@ LIB3270_EXPORT int lib3270_get_secure_host(const H3270 *hSession) @@ -51,7 +51,7 @@ LIB3270_EXPORT int lib3270_get_secure_host(const H3270 *hSession)
51 51
52 } 52 }
53 53
54 -#ifdef SSL_ENABLE_CRL_CHECK 54 +#if defined(HAVE_LIBSSL) && defined(SSL_ENABLE_CRL_CHECK)
55 LIB3270_EXPORT char * lib3270_get_ssl_crl_text(const H3270 *hSession) 55 LIB3270_EXPORT char * lib3270_get_ssl_crl_text(const H3270 *hSession)
56 { 56 {
57 57
@@ -120,7 +120,7 @@ LIB3270_EXPORT char * lib3270_get_ssl_peer_certificate_text(const H3270 *hSessio @@ -120,7 +120,7 @@ LIB3270_EXPORT char * lib3270_get_ssl_peer_certificate_text(const H3270 *hSessio
120 #pragma GCC diagnostic ignored "-Wunused-parameter" 120 #pragma GCC diagnostic ignored "-Wunused-parameter"
121 const char * lib3270_crl_get_url(const H3270 *hSession) 121 const char * lib3270_crl_get_url(const H3270 *hSession)
122 { 122 {
123 -#ifdef SSL_ENABLE_CRL_CHECK 123 +#if defined(HAVE_LIBSSL) && defined(SSL_ENABLE_CRL_CHECK)
124 if(hSession->ssl.crl.url) 124 if(hSession->ssl.crl.url)
125 return hSession->ssl.crl.url; 125 return hSession->ssl.crl.url;
126 126
@@ -144,7 +144,7 @@ LIB3270_EXPORT char * lib3270_get_ssl_peer_certificate_text(const H3270 *hSessio @@ -144,7 +144,7 @@ LIB3270_EXPORT char * lib3270_get_ssl_peer_certificate_text(const H3270 *hSessio
144 144
145 FAIL_IF_ONLINE(hSession); 145 FAIL_IF_ONLINE(hSession);
146 146
147 -#ifdef SSL_ENABLE_CRL_CHECK 147 +#if defined(HAVE_LIBSS) && defined(SSL_ENABLE_CRL_CHECK)
148 148
149 if(hSession->ssl.crl.url) 149 if(hSession->ssl.crl.url)
150 { 150 {
@@ -197,7 +197,7 @@ LIB3270_EXPORT char * lib3270_get_ssl_peer_certificate_text(const H3270 *hSessio @@ -197,7 +197,7 @@ LIB3270_EXPORT char * lib3270_get_ssl_peer_certificate_text(const H3270 *hSessio
197 #pragma GCC diagnostic ignored "-Wunused-parameter" 197 #pragma GCC diagnostic ignored "-Wunused-parameter"
198 const char * lib3270_crl_get_preferred_protocol(const H3270 *hSession) 198 const char * lib3270_crl_get_preferred_protocol(const H3270 *hSession)
199 { 199 {
200 -#ifdef SSL_ENABLE_CRL_CHECK 200 +#if defined(HAVE_LIBSSL) && defined(SSL_ENABLE_CRL_CHECK)
201 if(hSession->ssl.crl.prefer) 201 if(hSession->ssl.crl.prefer)
202 return hSession->ssl.crl.prefer; 202 return hSession->ssl.crl.prefer;
203 #endif 203 #endif
@@ -213,7 +213,7 @@ LIB3270_EXPORT char * lib3270_get_ssl_peer_certificate_text(const H3270 *hSessio @@ -213,7 +213,7 @@ LIB3270_EXPORT char * lib3270_get_ssl_peer_certificate_text(const H3270 *hSessio
213 213
214 FAIL_IF_ONLINE(hSession); 214 FAIL_IF_ONLINE(hSession);
215 215
216 -#ifdef SSL_ENABLE_CRL_CHECK 216 +#if defined(HAVE_LIBSSL) && defined(HAVE_SSL_ENABLE_CRL_CHECK)
217 217
218 if(hSession->ssl.crl.prefer) 218 if(hSession->ssl.crl.prefer)
219 { 219 {