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 | { | ... | ... |