Commit 7a87d265f93cd60b056ae7cdc5e557fdc555ce5b
1 parent
0669cde0
Exists in
master
and in
3 other branches
Implementing network modules for non SSL/TLS sessions.
Showing
25 changed files
with
504 additions
and
226 deletions
Show diff stats
Makefile.in
... | ... | @@ -45,6 +45,8 @@ SOURCES= \ |
45 | 45 | $(wildcard src/selection/*.c) \ |
46 | 46 | $(wildcard src/ssl/*.c) \ |
47 | 47 | $(wildcard src/ssl/@OSNAME@/*.c) \ |
48 | + $(wildcard src/network_modules/*.c) \ | |
49 | + $(wildcard src/network_modules/@OSNAME@/*.c) \ | |
48 | 50 | $(BASEDIR)/.tmp/$(LIBNAME)/fallbacks.c |
49 | 51 | |
50 | 52 | TEST_SOURCES= \ | ... | ... |
lib3270.cbp
... | ... | @@ -307,6 +307,10 @@ |
307 | 307 | <Unit filename="src/mkfb/mkfb.c"> |
308 | 308 | <Option compilerVar="CC" /> |
309 | 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 | 314 | <Unit filename="src/network_modules/unsecure.c"> |
311 | 315 | <Option compilerVar="CC" /> |
312 | 316 | </Unit> | ... | ... |
src/core/connect.c
... | ... | @@ -62,7 +62,7 @@ |
62 | 62 | if(ssl_ctx_init(hSession, (SSL_ERROR_MESSAGE *) ssl_error)) |
63 | 63 | return -1; |
64 | 64 | |
65 | -#if defined(SSL_ENABLE_CRL_CHECK) | |
65 | +#if defined(HAVE_LIBSSL) && defined(SSL_ENABLE_CRL_CHECK) | |
66 | 66 | lib3270_crl_free_if_expired(hSession); |
67 | 67 | #endif // defined(SSL_ENABLE_CRL_CHECK) |
68 | 68 | |
... | ... | @@ -71,6 +71,7 @@ |
71 | 71 | |
72 | 72 | #endif // HAVE_LIBSSL |
73 | 73 | |
74 | +/* | |
74 | 75 | void connection_failed(H3270 *hSession, const char *message) |
75 | 76 | { |
76 | 77 | lib3270_disconnect(hSession); |
... | ... | @@ -94,6 +95,7 @@ |
94 | 95 | lib3270_activate_auto_reconnect(hSession,1000); |
95 | 96 | |
96 | 97 | } |
98 | +*/ | |
97 | 99 | |
98 | 100 | int lib3270_allow_reconnect(const H3270 *hSession) |
99 | 101 | { |
... | ... | @@ -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 | 176 | int rc = 0; |
180 | 177 | |
181 | - if(hSession->network.module->start_tls) | |
178 | + if(hSession->network.module->start_tls,required) | |
182 | 179 | { |
183 | 180 | LIB3270_NETWORK_STATE state; |
184 | 181 | memset(&state,0,sizeof(state)); | ... | ... |
src/core/host.c
... | ... | @@ -42,6 +42,7 @@ |
42 | 42 | #endif // HAVE_MALLOC_H |
43 | 43 | |
44 | 44 | #include <internals.h> |
45 | +#include <stdlib.h> | |
45 | 46 | #include "resources.h" |
46 | 47 | |
47 | 48 | #include "hostc.h" |
... | ... | @@ -279,7 +280,7 @@ static void update_url(H3270 *hSession) |
279 | 280 | lib3270_free(hSession->host.url); |
280 | 281 | hSession->host.url = url; |
281 | 282 | |
282 | -#ifdef SSL_ENABLE_CRL_CHECK | |
283 | +#if defined(HAVE_LIBSSL) && defined(SSL_ENABLE_CRL_CHECK) | |
283 | 284 | lib3270_crl_free(hSession); |
284 | 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 | 299 | } |
300 | 300 | |
301 | 301 | |
302 | -/* | |
303 | 302 | LIB3270_EXPORT void lib3270_remove_poll(H3270 *session, void *id) |
304 | 303 | { |
305 | - debug("%s(%d,%p)",__FUNCTION__,session->connection.sock,id); | |
306 | 304 | remove_poll(session, id); |
307 | 305 | } |
308 | -*/ | |
309 | 306 | |
310 | 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 | 517 | |
521 | 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 | 521 | return 0; |
525 | 522 | |
526 | 523 | lib3270_set_poll_state(hSession,hSession->xio.read, on); | ... | ... |
src/core/linux/connect.c
... | ... | @@ -42,8 +42,6 @@ |
42 | 42 | #include <unistd.h> |
43 | 43 | #include <fcntl.h> |
44 | 44 | |
45 | -// #define SOCK_CLOSE(s) close(s->connection.sock); s->connection.sock = -1; | |
46 | - | |
47 | 45 | #include <stdlib.h> |
48 | 46 | |
49 | 47 | #include "hostc.h" |
... | ... | @@ -58,8 +56,8 @@ |
58 | 56 | |
59 | 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 | 61 | int err; |
64 | 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 | 81 | } |
84 | 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 | 102 | return; |
89 | 103 | } |
90 | 104 | |
91 | 105 | hSession->xio.except = hSession->network.module->add_poll(hSession,LIB3270_IO_FLAG_EXCEPTION,net_exception,0); |
92 | 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 | 109 | return; |
96 | 110 | |
97 | 111 | lib3270_setup_session(hSession); |
98 | 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 | 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 | 172 | hSession->ever_3270 = False; |
172 | 173 | |
173 | 174 | #if defined(HAVE_LIBSSL) |
... | ... | @@ -182,7 +183,7 @@ static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG |
182 | 183 | |
183 | 184 | // set options for inline out-of-band data and keepalives |
184 | 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 | 188 | int rc = errno; |
188 | 189 | lib3270_popup_dialog( hSession, |
... | ... | @@ -191,12 +192,12 @@ static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG |
191 | 192 | _( "setsockopt(SO_OOBINLINE) has failed" ), |
192 | 193 | "%s", |
193 | 194 | strerror(rc)); |
194 | - SOCK_CLOSE(hSession); | |
195 | + hSession->network.module->disconnect(hSession); | |
195 | 196 | return rc; |
196 | 197 | } |
197 | 198 | |
198 | 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 | 202 | int rc = errno; |
202 | 203 | |
... | ... | @@ -209,7 +210,8 @@ static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG |
209 | 210 | buffer, |
210 | 211 | "%s", |
211 | 212 | strerror(rc)); |
212 | - SOCK_CLOSE(hSession); | |
213 | + | |
214 | + hSession->network.module->disconnect(hSession); | |
213 | 215 | return rc; |
214 | 216 | } |
215 | 217 | else |
... | ... | @@ -254,7 +256,7 @@ static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG |
254 | 256 | case LIB3270_CONNECTED_INITIAL_E: |
255 | 257 | case LIB3270_CONNECTED_NVT: |
256 | 258 | case LIB3270_CONNECTED_SSCP: |
257 | - case LIB3270_RESOLVING: | |
259 | + case LIB3270_CONNECTING: | |
258 | 260 | break; |
259 | 261 | |
260 | 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 | 135 | // Alocate new struct |
136 | 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 | 147 | strcpy((char *)(popup+1),body); |
141 | 148 | popup->body = (char *)(popup+1); |
... | ... | @@ -154,7 +161,8 @@ static int def_popup(H3270 *hSession, const LIB3270_POPUP *popup, unsigned char |
154 | 161 | |
155 | 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 | 168 | return ENOTSUP; | ... | ... |
src/core/properties/boolean.c
src/core/properties/string.c
src/core/rpq.c
... | ... | @@ -686,7 +686,7 @@ static int get_rpq_address(H3270 *hSession, unsigned char *buf, const int maxlen |
686 | 686 | struct sockaddr_in6 sa6; |
687 | 687 | #endif // HAVE_GETADDRINFO |
688 | 688 | } u; |
689 | - int addrlen = sizeof(u); | |
689 | + socklen_t addrlen = sizeof(u); | |
690 | 690 | void *src = NULL; |
691 | 691 | int len = 0; |
692 | 692 | ... | ... |
src/core/screen.c
... | ... | @@ -550,19 +550,21 @@ void status_oerr(H3270 *session, int error_type) |
550 | 550 | */ |
551 | 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 | 555 | mcursor_set(hSession,LIB3270_POINTER_LOCKED); |
556 | + | |
557 | + lib3270_st_changed(hSession, LIB3270_STATE_RESOLVING, True); | |
557 | 558 | status_changed(hSession, LIB3270_MESSAGE_RESOLVING); |
558 | 559 | } |
559 | 560 | |
560 | 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 | 565 | mcursor_set(hSession,LIB3270_POINTER_LOCKED); |
566 | + | |
567 | + lib3270_st_changed(hSession, LIB3270_STATE_CONNECTING, True); | |
566 | 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 | 84 | lib3270_crl_free(h); |
85 | 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 | 94 | // Release state change callbacks |
88 | 95 | for(f=0;f<LIB3270_STATE_USER;f++) |
89 | 96 | lib3270_linked_list_free(&h->listeners.state[f]); |
90 | 97 | |
91 | - | |
92 | 98 | // Release toggle change listeners. |
93 | 99 | for(f=0;f<LIB3270_TOGGLE_COUNT;f++) |
94 | 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 | 322 | int f; |
317 | 323 | |
318 | 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 | 331 | lib3270_set_host_charset(hSession,charset); |
322 | 332 | lib3270_reset_callbacks(hSession); |
... | ... | @@ -438,22 +448,11 @@ H3270 * lib3270_session_new(const char *model) |
438 | 448 | trace("%s - configured=%s",__FUNCTION__,default_session ? "Yes" : "No"); |
439 | 449 | |
440 | 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 | 453 | if(!default_session) |
453 | 454 | default_session = hSession; |
454 | 455 | |
455 | - lib3270_session_init(hSession, model, "bracket" ); | |
456 | - | |
457 | 456 | if(screen_init(hSession)) |
458 | 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 | 38 | |
39 | 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 | 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 | 49 | LIB3270_EXPORT int lib3270_is_disconnected(const H3270 *h) | ... | ... |
src/core/telnet.c
... | ... | @@ -261,7 +261,6 @@ static const char *trsp_flag[2] = { "POSITIVE-RESPONSE", "NEGATIVE-RESPONSE" }; |
261 | 261 | #define SE_EAGAIN WSAEINPROGRESS |
262 | 262 | #define SE_EPIPE WSAECONNABORTED |
263 | 263 | #define SE_EINPROGRESS WSAEINPROGRESS |
264 | - #define SOCK_CLOSE(s) closesocket(s) | |
265 | 264 | #define SOCK_IOCTL(s, f, v) ioctlsocket(s, f, (void *)v) |
266 | 265 | #else /*][*/ |
267 | 266 | #define socket_errno() errno |
... | ... | @@ -275,7 +274,6 @@ static const char *trsp_flag[2] = { "POSITIVE-RESPONSE", "NEGATIVE-RESPONSE" }; |
275 | 274 | #define SE_EINPROGRESS EINPROGRESS |
276 | 275 | #endif /*]*/ |
277 | 276 | |
278 | - #define SOCK_CLOSE(s) close(s) | |
279 | 277 | #define SOCK_IOCTL ioctl |
280 | 278 | #endif /*]*/ |
281 | 279 | |
... | ... | @@ -539,8 +537,6 @@ LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession) |
539 | 537 | */ |
540 | 538 | void net_disconnect(H3270 *hSession) |
541 | 539 | { |
542 | - LIB3270_NETWORK_STATE state; | |
543 | - memset(&state,0,sizeof(state)); | |
544 | 540 | |
545 | 541 | // Disconnect from host |
546 | 542 | #if defined(HAVE_LIBSSL) |
... | ... | @@ -563,7 +559,7 @@ void net_disconnect(H3270 *hSession) |
563 | 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 | 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 | 637 | if (hSession->ssl.con != NULL) |
642 | 638 | nr = SSL_read(hSession->ssl.con, (char *) buffer, BUFSZ); |
643 | 639 | else |
644 | - nr = hSession->network.module->recv(hSession->network.context, buffer, BUFSZ); | |
640 | + nr = hSession->network.module->recv(hSession, buffer, BUFSZ); | |
645 | 641 | #else |
646 | - nr = hSession->network.module->recv(hSession->network.context, buffer, BUFSZ); | |
642 | + nr = hSession->network.module->recv(hSession, buffer, BUFSZ); | |
647 | 643 | #endif // HAVE_LIBSSL |
648 | 644 | |
649 | 645 | if (nr < 0) |
... | ... | @@ -1602,13 +1598,10 @@ static int process_eor(H3270 *hSession) |
1602 | 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 | 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 | 1606 | trace_dsn(session,"RCVD urgent data indication\n"); |
1614 | 1607 | if (!session->syncing) |
... | ... | @@ -1655,9 +1648,10 @@ LIB3270_INTERNAL int lib3270_sock_send(H3270 *hSession, unsigned const char *buf |
1655 | 1648 | if(rc > 0) |
1656 | 1649 | return rc; |
1657 | 1650 | |
1658 | - // Recv error, notify | |
1651 | + // Send error, notify | |
1659 | 1652 | |
1660 | 1653 | #if defined(HAVE_LIBSSL) |
1654 | + #error TODO - The send method should emit popup messages. | |
1661 | 1655 | if(hSession->ssl.con != NULL) |
1662 | 1656 | { |
1663 | 1657 | unsigned long e; |
... | ... | @@ -1671,25 +1665,7 @@ LIB3270_INTERNAL int lib3270_sock_send(H3270 *hSession, unsigned const char *buf |
1671 | 1665 | } |
1672 | 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 | 1670 | return -1; |
1695 | 1671 | } |
... | ... | @@ -2029,7 +2005,7 @@ const char * lib3270_connection_state_get_name(const LIB3270_CSTATE cstate) |
2029 | 2005 | static const char *state_names[] = |
2030 | 2006 | { |
2031 | 2007 | "unconnected", |
2032 | - "resolving", | |
2008 | + "connecting", | |
2033 | 2009 | "pending", |
2034 | 2010 | "connected initial", |
2035 | 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 | 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
src/core/windows/connect.c
src/include/internals.h
... | ... | @@ -883,10 +883,16 @@ LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on); |
883 | 883 | /// @brief Fire CState change. |
884 | 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 | 252 | typedef enum lib3270_cstate |
253 | 253 | { |
254 | 254 | LIB3270_NOT_CONNECTED, ///< @brief no socket, disconnected |
255 | - LIB3270_RESOLVING, ///< @brief resolving hostname | |
255 | + LIB3270_CONNECTING, ///< @brief connecting to host | |
256 | 256 | LIB3270_PENDING, ///< @brief connection pending |
257 | 257 | LIB3270_CONNECTED_INITIAL, ///< @brief connected, no mode yet |
258 | 258 | LIB3270_CONNECTED_ANSI, ///< @brief connected in NVT ANSI mode | ... | ... |
src/include/networking.h
... | ... | @@ -41,34 +41,23 @@ |
41 | 41 | DWORD winerror; ///< @brief Win32 error got from GetLastError() |
42 | 42 | #endif // _WIN32 |
43 | 43 | |
44 | + const char * error_message; /// @brief System error message. | |
45 | + | |
44 | 46 | const LIB3270_POPUP *popup; /// @brief Detailed info for popup. |
45 | 47 | |
46 | 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 | 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 | 54 | /// @brief Deinitialize network module. |
66 | 55 | /// |
67 | 56 | /// @param context Network context. |
68 | 57 | /// @param hSession TN3270 session. |
69 | 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 | 62 | /// @brief Connect to host. |
74 | 63 | /// |
... | ... | @@ -77,7 +66,7 @@ |
77 | 66 | /// @param seconds Seconds for timeout. |
78 | 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 | 71 | /// @brief Disconnect from host. |
83 | 72 | /// |
... | ... | @@ -85,9 +74,9 @@ |
85 | 74 | /// @param hSession TN3270 session. |
86 | 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 | 81 | /// @brief Send on network context. |
93 | 82 | /// |
... | ... | @@ -126,16 +115,26 @@ |
126 | 115 | int (*getsockname)(const H3270 *hSession, struct sockaddr *addr, socklen_t *addrlen); |
127 | 116 | |
128 | 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 | 120 | /// @brief Get socket options. |
132 | 121 | int (*getsockopt)(H3270 *hSession, int level, int optname, void *optval, socklen_t *optlen); |
133 | 122 | |
134 | 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 | 139 | #endif // LIB3270_NETWORKING_H_INCLUDED |
141 | 140 | ... | ... |
... | ... | @@ -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 | +} | ... | ... |
... | ... | @@ -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 | 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 | 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 | 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 | 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 | 71 | if(hSession->network.context->sock < 0) { |
76 | 72 | return -(errno = ENOTCONN); |
... | ... | @@ -78,19 +74,68 @@ ssize_t unsecure_network_send(H3270 *hSession, const void *buffer, size_t length |
78 | 74 | |
79 | 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 | 132 | if(hSession->network.context->sock < 0) { |
90 | 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 | 140 | if(bytes < 0) { |
96 | 141 | return -errno; |
... | ... | @@ -99,17 +144,17 @@ ssize_t unsecure_network_recv(H3270 *hSession, void *buf, size_t len) { |
99 | 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 | 148 | if(hSession->network.context->sock < 0) |
104 | 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 | 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 | 159 | if(hSession->network.context->sock < 0) |
115 | 160 | return 0; |
... | ... | @@ -165,29 +210,93 @@ int unsecure_non_blocking(H3270 *hSession, const unsigned char on) { |
165 | 210 | |
166 | 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 | 223 | errno = ENOTCONN; |
178 | 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 | 234 | errno = ENOTCONN; |
189 | 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 | 45 | #include <lib3270/trace.h> |
46 | 46 | #include <lib3270/log.h> |
47 | 47 | |
48 | - #ifdef HAVE_LDAP | |
48 | + #if defined(HAVE_LIBSSL) && defined(HAVE_LDAP) | |
49 | 49 | |
50 | 50 | /// @brief Use libldap to get CRL. |
51 | 51 | LIB3270_INTERNAL X509_CRL * get_crl_using_ldap(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *consturl); |
52 | 52 | |
53 | 53 | #endif // HAVE_LDAP |
54 | 54 | |
55 | - #ifdef HAVE_LIBCURL | |
55 | + #if defined (HAVE_LIBSSL) && defined(HAVE_LIBCURL) | |
56 | 56 | |
57 | 57 | /// @brief Use libcurl to get CRL. |
58 | 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 | 51 | |
52 | 52 | } |
53 | 53 | |
54 | -#ifdef SSL_ENABLE_CRL_CHECK | |
54 | +#if defined(HAVE_LIBSSL) && defined(SSL_ENABLE_CRL_CHECK) | |
55 | 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 | 120 | #pragma GCC diagnostic ignored "-Wunused-parameter" |
121 | 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 | 124 | if(hSession->ssl.crl.url) |
125 | 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 | 144 | |
145 | 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 | 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 | 197 | #pragma GCC diagnostic ignored "-Wunused-parameter" |
198 | 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 | 201 | if(hSession->ssl.crl.prefer) |
202 | 202 | return hSession->ssl.crl.prefer; |
203 | 203 | #endif |
... | ... | @@ -213,7 +213,7 @@ LIB3270_EXPORT char * lib3270_get_ssl_peer_certificate_text(const H3270 *hSessio |
213 | 213 | |
214 | 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 | 218 | if(hSession->ssl.crl.prefer) |
219 | 219 | { | ... | ... |