Commit 5bfd24c748f1329aad6b341b7abe291900212258
1 parent
ca1b7ce9
Exists in
master
and in
5 other branches
Separando funções SSL do módulo telnet para facilitar a manutenção
Showing
8 changed files
with
467 additions
and
527 deletions
Show diff stats
pw3270.cbp
| ... | ... | @@ -107,7 +107,6 @@ |
| 107 | 107 | <Unit filename="src/lib3270/charset.c"> |
| 108 | 108 | <Option compilerVar="CC" /> |
| 109 | 109 | </Unit> |
| 110 | - <Unit filename="src/lib3270/charset.h" /> | |
| 111 | 110 | <Unit filename="src/lib3270/connect.c"> |
| 112 | 111 | <Option compilerVar="CC" /> |
| 113 | 112 | </Unit> |
| ... | ... | @@ -201,6 +200,9 @@ |
| 201 | 200 | <Unit filename="src/lib3270/sf.h" /> |
| 202 | 201 | <Unit filename="src/lib3270/shlobj_missing.h" /> |
| 203 | 202 | <Unit filename="src/lib3270/sources.mak" /> |
| 203 | + <Unit filename="src/lib3270/ssl.c"> | |
| 204 | + <Option compilerVar="CC" /> | |
| 205 | + </Unit> | |
| 204 | 206 | <Unit filename="src/lib3270/state.c"> |
| 205 | 207 | <Option compilerVar="CC" /> |
| 206 | 208 | </Unit> |
| ... | ... | @@ -208,7 +210,6 @@ |
| 208 | 210 | <Unit filename="src/lib3270/tables.c"> |
| 209 | 211 | <Option compilerVar="CC" /> |
| 210 | 212 | </Unit> |
| 211 | - <Unit filename="src/lib3270/tablesc.h" /> | |
| 212 | 213 | <Unit filename="src/lib3270/telnet.c"> |
| 213 | 214 | <Option compilerVar="CC" /> |
| 214 | 215 | </Unit> | ... | ... |
src/lib3270/connect.c
| ... | ... | @@ -82,7 +82,7 @@ static void net_connected(H3270 *hSession) |
| 82 | 82 | _( "Network error" ), |
| 83 | 83 | _( "Unable to get connection state." ), |
| 84 | 84 | #ifdef _WIN32 |
| 85 | - _( "Winsock Error %d"), WSAGetLastError() | |
| 85 | + "%s", lib3270_win32_strerror(WSAGetLastError())); | |
| 86 | 86 | #else |
| 87 | 87 | _( "%s" ), strerror(errno) |
| 88 | 88 | #endif // _WIN32 |
| ... | ... | @@ -167,16 +167,6 @@ static void net_connected(H3270 *hSession) |
| 167 | 167 | } |
| 168 | 168 | #endif /*]*/ |
| 169 | 169 | |
| 170 | - static void set_ssl_state(H3270 *hSession, LIB3270_SSL_STATE state) | |
| 171 | - { | |
| 172 | - if(state == hSession->secure) | |
| 173 | - return; | |
| 174 | - | |
| 175 | - trace_dsn(hSession,"SSL state changes to %d\n",(int) state); | |
| 176 | - | |
| 177 | - hSession->update_ssl(hSession,hSession->secure = state); | |
| 178 | - } | |
| 179 | - | |
| 180 | 170 | LIB3270_EXPORT int lib3270_connect_host(H3270 *hSession, const char *hostname, const char *srvc) |
| 181 | 171 | { |
| 182 | 172 | int s; |
| ... | ... | @@ -303,8 +293,7 @@ static void net_connected(H3270 *hSession) |
| 303 | 293 | LIB3270_NOTIFY_ERROR, |
| 304 | 294 | _( "Connection error" ), |
| 305 | 295 | _( "ioctlsocket(FIONBIO) failed." ), |
| 306 | - "%s", lib3270_win32_strerror(GetLastError())); | |
| 307 | - | |
| 296 | + "%s", lib3270_win32_strerror(WSAGetLastError())); | |
| 308 | 297 | SOCK_CLOSE(hSession); |
| 309 | 298 | } |
| 310 | 299 | else if(connect(hSession->sock, rp->ai_addr, rp->ai_addrlen)) |
| ... | ... | @@ -316,7 +305,7 @@ static void net_connected(H3270 *hSession) |
| 316 | 305 | LIB3270_NOTIFY_ERROR, |
| 317 | 306 | _( "Connection error" ), |
| 318 | 307 | _( "Can't connect to host." ), |
| 319 | - "%s", lib3270_win32_strerror(GetLastError())); | |
| 308 | + "%s", lib3270_win32_strerror(err)); | |
| 320 | 309 | SOCK_CLOSE(hSession); |
| 321 | 310 | } |
| 322 | 311 | } |
| ... | ... | @@ -390,3 +379,56 @@ static void net_connected(H3270 *hSession) |
| 390 | 379 | |
| 391 | 380 | } |
| 392 | 381 | |
| 382 | +int non_blocking(H3270 *hSession, Boolean on) | |
| 383 | +{ | |
| 384 | +#ifdef WIN32 | |
| 385 | + WSASetLastError(0); | |
| 386 | + u_long iMode= on ? 1 : 0; | |
| 387 | + | |
| 388 | + if(ioctlsocket(hSession->sock,FIONBIO,&iMode)) | |
| 389 | + { | |
| 390 | + lib3270_popup_dialog( hSession, | |
| 391 | + LIB3270_NOTIFY_ERROR, | |
| 392 | + _( "Connection error" ), | |
| 393 | + _( "ioctlsocket(FIONBIO) failed." ), | |
| 394 | + "%s", lib3270_win32_strerror(GetLastError())); | |
| 395 | + } | |
| 396 | +#else | |
| 397 | + | |
| 398 | + int f; | |
| 399 | + | |
| 400 | + if ((f = fcntl(hSession->sock, F_GETFL, 0)) == -1) | |
| 401 | + { | |
| 402 | + lib3270_popup_dialog( hSession, | |
| 403 | + LIB3270_NOTIFY_ERROR, | |
| 404 | + _( "Socket error" ), | |
| 405 | + _( "fcntl() error when getting socket state." ), | |
| 406 | + _( "%s" ), strerror(errno) | |
| 407 | + ); | |
| 408 | + | |
| 409 | + return -1; | |
| 410 | + } | |
| 411 | + | |
| 412 | + if (on) | |
| 413 | + f |= O_NDELAY; | |
| 414 | + else | |
| 415 | + f &= ~O_NDELAY; | |
| 416 | + | |
| 417 | + if (fcntl(hSession->sock, F_SETFL, f) < 0) | |
| 418 | + { | |
| 419 | + lib3270_popup_dialog( hSession, | |
| 420 | + LIB3270_NOTIFY_ERROR, | |
| 421 | + _( "Socket error" ), | |
| 422 | + on ? _( "Can't set socket to blocking mode." ) : _( "Can't set socket to non blocking mode" ), | |
| 423 | + _( "%s" ), strerror(errno) | |
| 424 | + ); | |
| 425 | + return -1; | |
| 426 | + } | |
| 427 | + | |
| 428 | +#endif | |
| 429 | + | |
| 430 | + trace("Socket %d is %s",hSession->sock, on ? "non-blocking" : "blocking"); | |
| 431 | + | |
| 432 | + return 0; | |
| 433 | +} | |
| 434 | + | ... | ... |
src/lib3270/globals.h
| ... | ... | @@ -137,18 +137,6 @@ enum iaction { |
| 137 | 137 | IA_IDLE |
| 138 | 138 | }; |
| 139 | 139 | |
| 140 | -// LIB3270_INTERNAL int COLS; | |
| 141 | -// LIB3270_INTERNAL int ROWS; | |
| 142 | - | |
| 143 | -// LIB3270_INTERNAL H3270 h3270; | |
| 144 | - | |
| 145 | -/* | |
| 146 | -#if defined(X3270_DISPLAY) | |
| 147 | - LIB3270_INTERNAL Atom a_3270, a_registry, a_encoding; | |
| 148 | - LIB3270_INTERNAL XtAppContext appcontext; | |
| 149 | -#endif | |
| 150 | -*/ | |
| 151 | - | |
| 152 | 140 | // Version strings |
| 153 | 141 | LIB3270_INTERNAL const char * build; |
| 154 | 142 | LIB3270_INTERNAL const char * app_defaults_version; |
| ... | ... | @@ -157,99 +145,15 @@ LIB3270_INTERNAL const char * build_rpq_timestamp; |
| 157 | 145 | LIB3270_INTERNAL const char * build_rpq_version; |
| 158 | 146 | LIB3270_INTERNAL const char * build_rpq_revision; |
| 159 | 147 | |
| 160 | -// LIB3270_INTERNAL int children; | |
| 161 | - | |
| 162 | 148 | #if defined(X3270_DBCS) /*[*/ |
| 163 | 149 | LIB3270_INTERNAL Boolean dbcs; |
| 164 | 150 | #endif /*]*/ |
| 165 | 151 | |
| 166 | -// #if defined(X3270_FT) /*[*/ | |
| 167 | -// LIB3270_INTERNAL int dft_buffersize; | |
| 168 | -// #endif /*]*/ | |
| 169 | - | |
| 170 | -// LIB3270_INTERNAL char *efontname; | |
| 171 | -// LIB3270_INTERNAL Boolean ever_3270; | |
| 172 | -// LIB3270_INTERNAL Boolean exiting; | |
| 173 | - | |
| 174 | -/* | |
| 175 | -#if defined(X3270_DISPLAY) | |
| 176 | - LIB3270_INTERNAL Boolean *extended_3270font; | |
| 177 | - LIB3270_INTERNAL Font *fid; | |
| 178 | - LIB3270_INTERNAL Boolean *font_8bit; | |
| 179 | -#endif | |
| 180 | -*/ | |
| 181 | - | |
| 182 | -// LIB3270_INTERNAL Boolean flipped; | |
| 183 | -// LIB3270_INTERNAL char *full_current_host; | |
| 184 | -// LIB3270_INTERNAL char *full_efontname; | |
| 185 | 152 | |
| 186 | 153 | #if defined(X3270_DBCS) /*[*/ |
| 187 | 154 | LIB3270_INTERNAL char *full_efontname_dbcs; |
| 188 | 155 | #endif /*]*/ |
| 189 | 156 | |
| 190 | -//LIB3270_INTERNAL char *funky_font; | |
| 191 | -//LIB3270_INTERNAL char *hostname; | |
| 192 | - | |
| 193 | -#if defined(X3270_DBCS) /*[*/ | |
| 194 | -// LIB3270_INTERNAL char *local_encoding; | |
| 195 | - | |
| 196 | - #if defined(X3270_DISPLAY) /*[*/ | |
| 197 | -// LIB3270_INTERNAL char *locale_name; | |
| 198 | - #endif /*]*/ | |
| 199 | - | |
| 200 | -#endif /*]*/ | |
| 201 | - | |
| 202 | -/* | |
| 203 | -#if defined(LOCAL_PROCESS) | |
| 204 | - LIB3270_INTERNAL Boolean local_process; | |
| 205 | -#endif | |
| 206 | -*/ | |
| 207 | - | |
| 208 | -// LIB3270_INTERNAL int maxCOLS; | |
| 209 | -// LIB3270_INTERNAL int maxROWS; | |
| 210 | -// LIB3270_INTERNAL char *model_name; | |
| 211 | -// LIB3270_INTERNAL int model_num; | |
| 212 | -// LIB3270_INTERNAL Boolean no_login_host; | |
| 213 | -// LIB3270_INTERNAL Boolean non_tn3270e_host; | |
| 214 | -// LIB3270_INTERNAL int ov_cols, ov_rows; | |
| 215 | -// LIB3270_INTERNAL Boolean passthru_host; | |
| 216 | -// extern const char *programname; | |
| 217 | -// LIB3270_INTERNAL char *qualified_host; | |
| 218 | -// LIB3270_INTERNAL char *reconnect_host; | |
| 219 | -// LIB3270_INTERNAL int screen_depth; | |
| 220 | -// LIB3270_INTERNAL Boolean scroll_initted; | |
| 221 | - | |
| 222 | -//#if defined(HAVE_LIBSSL) /*[*/ | |
| 223 | -// LIB3270_INTERNAL Boolean secure_connection; | |
| 224 | -//#endif /*]*/ | |
| 225 | - | |
| 226 | -// LIB3270_INTERNAL Boolean shifted; | |
| 227 | -// LIB3270_INTERNAL Boolean ssl_host; | |
| 228 | -// LIB3270_INTERNAL Boolean *standard_font; | |
| 229 | -// LIB3270_INTERNAL Boolean std_ds_host; | |
| 230 | -// LIB3270_INTERNAL char *termtype; | |
| 231 | -// LIB3270_INTERNAL Widget toplevel; | |
| 232 | -// LIB3270_INTERNAL Boolean visible_control; | |
| 233 | -// LIB3270_INTERNAL int *xtra_width; | |
| 234 | - | |
| 235 | -/* | |
| 236 | -#if defined(X3270_DISPLAY) | |
| 237 | - LIB3270_INTERNAL Atom a_delete_me; | |
| 238 | - LIB3270_INTERNAL Atom a_save_yourself; | |
| 239 | - LIB3270_INTERNAL Atom a_state; | |
| 240 | - LIB3270_INTERNAL Display *display; | |
| 241 | - LIB3270_INTERNAL Pixmap gray; | |
| 242 | - LIB3270_INTERNAL Pixel keypadbg_pixel; | |
| 243 | - LIB3270_INTERNAL XrmDatabase rdb; | |
| 244 | - LIB3270_INTERNAL Window root_window; | |
| 245 | - LIB3270_INTERNAL char *user_title; | |
| 246 | - LIB3270_INTERNAL unsigned char xk_selector; | |
| 247 | -#endif | |
| 248 | -*/ | |
| 249 | - | |
| 250 | -/* Connection state */ | |
| 251 | -// LIB3270_INTERNAL enum ft_state ft_state; | |
| 252 | - | |
| 253 | 157 | |
| 254 | 158 | /* keyboard modifer bitmap */ |
| 255 | 159 | #define ShiftKeyDown 0x01 |
| ... | ... | @@ -263,19 +167,7 @@ struct toggle_name { |
| 263 | 167 | }; |
| 264 | 168 | |
| 265 | 169 | |
| 266 | -/* translation lists */ /* | |
| 267 | -struct trans_list { | |
| 268 | - char *name; | |
| 269 | - char *pathname; | |
| 270 | - Boolean is_temp; | |
| 271 | - Boolean from_server; | |
| 272 | - struct trans_list *next; | |
| 273 | -}; | |
| 274 | -LIB3270_INTERNAL struct trans_list *trans_list; | |
| 275 | -*/ | |
| 276 | - | |
| 277 | 170 | /* input key type */ |
| 278 | -// enum keytype { KT_STD, KT_GE }; | |
| 279 | 171 | |
| 280 | 172 | /* Naming convention for private actions. */ |
| 281 | 173 | #define PA_PFX "PA-" |
| ... | ... | @@ -341,8 +233,6 @@ LIB3270_INTERNAL void key_ACharacter(H3270 *hSession, unsigned char c, enum keyt |
| 341 | 233 | LIB3270_INTERNAL void lib3270_initialize(void); |
| 342 | 234 | LIB3270_INTERNAL int cursor_move(H3270 *session, int baddr); |
| 343 | 235 | |
| 344 | -// LIB3270_INTERNAL void add_input_calls(H3270 *, void (*)(H3270 *), void (*)(H3270 *)); | |
| 345 | - | |
| 346 | 236 | LIB3270_INTERNAL void toggle_rectselect(H3270 *session, struct lib3270_toggle *t, LIB3270_TOGGLE_TYPE tt); |
| 347 | 237 | LIB3270_INTERNAL void remove_input_calls(H3270 *session); |
| 348 | 238 | |
| ... | ... | @@ -358,3 +248,23 @@ LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession); |
| 358 | 248 | #endif // DEBUG |
| 359 | 249 | |
| 360 | 250 | LIB3270_EXPORT int lib3270_connect_host(H3270 *hSession, const char *hostname, const char *srvc); |
| 251 | + | |
| 252 | +LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on); | |
| 253 | + | |
| 254 | +#if defined(HAVE_LIBSSL) /*[*/ | |
| 255 | + | |
| 256 | + LIB3270_INTERNAL void ssl_init(H3270 *session); | |
| 257 | + LIB3270_INTERNAL int ssl_negotiate(H3270 *hSession); | |
| 258 | + LIB3270_INTERNAL void set_ssl_state(H3270 *session, LIB3270_SSL_STATE state); | |
| 259 | + | |
| 260 | + | |
| 261 | + #if OPENSSL_VERSION_NUMBER >= 0x00907000L /*[*/ | |
| 262 | + #define INFO_CONST const | |
| 263 | + #else /*][*/ | |
| 264 | + #define INFO_CONST | |
| 265 | + #endif /*]*/ | |
| 266 | + | |
| 267 | + LIB3270_INTERNAL void ssl_info_callback(INFO_CONST SSL *s, int where, int ret); | |
| 268 | + | |
| 269 | +#endif /*]*/ | |
| 270 | + | ... | ... |
src/lib3270/lib3270.cbp
src/lib3270/sources.mak
| ... | ... | @@ -28,7 +28,7 @@ |
| 28 | 28 | TERMINAL_SOURCES = bounds.c ctlr.c util.c toggles.c screen.c selection.c kybd.c telnet.c \ |
| 29 | 29 | host.c sf.c ansi.c resolver.c charset.c \ |
| 30 | 30 | version.c session.c state.c html.c trace_ds.c see.c \ |
| 31 | - paste.c | |
| 31 | + paste.c ssl.c | |
| 32 | 32 | |
| 33 | 33 | # tables.c utf8.c |
| 34 | 34 | ... | ... |
| ... | ... | @@ -0,0 +1,356 @@ |
| 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 GNU, 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 ssl.c 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 Mendonça) | |
| 27 | + * licinio@bb.com.br (Licínio Luis Branco) | |
| 28 | + * kraucer@bb.com.br (Kraucer Fernandes Mazuco) | |
| 29 | + * | |
| 30 | + */ | |
| 31 | + | |
| 32 | + | |
| 33 | +#include <lib3270/config.h> | |
| 34 | +#if defined(HAVE_LIBSSL) | |
| 35 | + #include <openssl/ssl.h> | |
| 36 | + #include <openssl/err.h> | |
| 37 | +#endif | |
| 38 | + | |
| 39 | +#include "globals.h" | |
| 40 | +#include <errno.h> | |
| 41 | +#include <lib3270/internals.h> | |
| 42 | +#include <lib3270/trace.h> | |
| 43 | +#include "trace_dsc.h" | |
| 44 | + | |
| 45 | +static int ssl_3270_ex_index = -1; /**< Index of h3270 handle in SSL session */ | |
| 46 | + | |
| 47 | +/*--[ Implement ]------------------------------------------------------------------------------------*/ | |
| 48 | + | |
| 49 | +#if defined(HAVE_LIBSSL) | |
| 50 | +int ssl_negotiate(H3270 *hSession) | |
| 51 | +{ | |
| 52 | + int rv; | |
| 53 | + | |
| 54 | + trace("%s",__FUNCTION__); | |
| 55 | + | |
| 56 | + set_ssl_state(hSession,LIB3270_SSL_NEGOTIATING); | |
| 57 | + non_blocking(hSession,False); | |
| 58 | + | |
| 59 | + /* Initialize the SSL library. */ | |
| 60 | + ssl_init(hSession); | |
| 61 | + if(hSession->ssl_con == NULL) | |
| 62 | + { | |
| 63 | + /* Failed. */ | |
| 64 | + popup_an_error(hSession,_( "SSL init failed!")); | |
| 65 | + lib3270_disconnect(hSession); | |
| 66 | + return -1; | |
| 67 | + } | |
| 68 | + | |
| 69 | + /* Set up the TLS/SSL connection. */ | |
| 70 | + if(SSL_set_fd(hSession->ssl_con, hSession->sock) != 1) | |
| 71 | + { | |
| 72 | + trace_dsn(hSession,"SSL_set_fd failed!\n"); | |
| 73 | + #warning Show a better popup here | |
| 74 | + // popup_an_error(hSession,_( "SSL_set_fd failed!")); | |
| 75 | + lib32070_disconnect(hSession); | |
| 76 | + return -1; | |
| 77 | + } | |
| 78 | + | |
| 79 | + trace("%s: Running SSL_connect",__FUNCTION__); | |
| 80 | + rv = SSL_connect(hSession->ssl_con); | |
| 81 | + trace("%s: SSL_connect exits with rc=%d",__FUNCTION__,rv); | |
| 82 | + | |
| 83 | + if (rv != 1) | |
| 84 | + { | |
| 85 | + int ssl_error = SSL_get_error(hSession->ssl_con,rv); | |
| 86 | + | |
| 87 | + if(ssl_error == SSL_ERROR_SYSCALL) | |
| 88 | + { | |
| 89 | + if(!hSession->ssl_error) | |
| 90 | + { | |
| 91 | + trace_dsn(hSession,"SSL_connect failed (ssl_error=%lu)\n",hSession->ssl_error); | |
| 92 | + popup_an_error(hSession,_( "SSL connect failed!")); | |
| 93 | + } | |
| 94 | + else | |
| 95 | + { | |
| 96 | + trace_dsn(hSession,"SSL_connect failed: %s %s\n", | |
| 97 | + ERR_lib_error_string(hSession->ssl_error), | |
| 98 | + ERR_reason_error_string(hSession->ssl_error)); | |
| 99 | + popup_an_error(hSession,"%s",_( ERR_reason_error_string(hSession->ssl_error) )); | |
| 100 | + } | |
| 101 | + | |
| 102 | + } | |
| 103 | + else | |
| 104 | + { | |
| 105 | + trace_dsn(hSession,"SSL_connect failed (ssl_error=%d errno=%d)\n",ssl_error,errno); | |
| 106 | + popup_an_error(hSession,_( "SSL connect failed!")); | |
| 107 | + } | |
| 108 | + | |
| 109 | + lib3270_disconnect(hSession); | |
| 110 | + return -1; | |
| 111 | + } | |
| 112 | + | |
| 113 | + /* Success. */ | |
| 114 | + if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_DS_TRACE)) | |
| 115 | + { | |
| 116 | + char buffer[4096]; | |
| 117 | + int alg_bits = 0; | |
| 118 | + const SSL_CIPHER * cipher = SSL_get_current_cipher(hSession->ssl_con); | |
| 119 | + X509 * peer = SSL_get_peer_certificate(hSession->ssl_con); | |
| 120 | + | |
| 121 | + trace_dsn(hSession,"TLS/SSL negotiated connection complete. Connection is now secure.\n"); | |
| 122 | + | |
| 123 | + trace_dsn(hSession,"TLS/SSL cipher description: %s",SSL_CIPHER_description((SSL_CIPHER *) cipher, buffer, 4095)); | |
| 124 | + SSL_CIPHER_get_bits(cipher, &alg_bits); | |
| 125 | + trace_dsn(hSession,"%s version %s with %d bits verify=%ld\n", | |
| 126 | + SSL_CIPHER_get_name(cipher), | |
| 127 | + SSL_CIPHER_get_version(cipher), | |
| 128 | + alg_bits, | |
| 129 | + SSL_get_verify_result(hSession->ssl_con)); | |
| 130 | + | |
| 131 | + if(peer) | |
| 132 | + { | |
| 133 | + BIO * out = BIO_new(BIO_s_mem()); | |
| 134 | + unsigned char * data; | |
| 135 | + unsigned char * text; | |
| 136 | + int n; | |
| 137 | + | |
| 138 | + X509_print(out,peer); | |
| 139 | + | |
| 140 | + n = BIO_get_mem_data(out, &data); | |
| 141 | + text = (unsigned char *) malloc (n+1); | |
| 142 | + text[n] ='\0'; | |
| 143 | + memcpy(text,data,n); | |
| 144 | + | |
| 145 | + trace_dsn(hSession,"TLS/SSL peer certificate:\n%s\n",text); | |
| 146 | + | |
| 147 | + free(text); | |
| 148 | + BIO_free(out); | |
| 149 | + X509_free(peer); | |
| 150 | + | |
| 151 | + } | |
| 152 | + } | |
| 153 | + | |
| 154 | + if(!SSL_get_verify_result(hSession->ssl_con)) | |
| 155 | + set_ssl_state(hSession,LIB3270_SSL_SECURE); | |
| 156 | + | |
| 157 | + /* Tell the world that we are (still) connected, now in secure mode. */ | |
| 158 | + lib3270_set_connected(hSession); | |
| 159 | + return 0; | |
| 160 | +} | |
| 161 | +#endif // HAVE_LIBSSL | |
| 162 | + | |
| 163 | +#if defined(HAVE_LIBSSL) /*[*/ | |
| 164 | + | |
| 165 | +/* Initialize the OpenSSL library. */ | |
| 166 | +void ssl_init(H3270 *session) | |
| 167 | +{ | |
| 168 | + static SSL_CTX *ssl_ctx = NULL; | |
| 169 | + | |
| 170 | + session->ssl_error = 0; | |
| 171 | + set_ssl_state(session,LIB3270_SSL_UNDEFINED); | |
| 172 | + | |
| 173 | + if(ssl_ctx == NULL) | |
| 174 | + { | |
| 175 | + lib3270_write_log(session,"SSL","%s","Initializing SSL context"); | |
| 176 | + SSL_load_error_strings(); | |
| 177 | + SSL_library_init(); | |
| 178 | + ssl_ctx = SSL_CTX_new(SSLv23_method()); | |
| 179 | + if(ssl_ctx == NULL) | |
| 180 | + { | |
| 181 | + popup_an_error(session,"SSL_CTX_new failed"); | |
| 182 | + session->ssl_host = False; | |
| 183 | + return; | |
| 184 | + } | |
| 185 | + SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL); | |
| 186 | + SSL_CTX_set_info_callback(ssl_ctx, ssl_info_callback); | |
| 187 | + SSL_CTX_set_default_verify_paths(ssl_ctx); | |
| 188 | + | |
| 189 | +#if defined(_WIN32) | |
| 190 | + { | |
| 191 | + HKEY hKey = 0; | |
| 192 | + | |
| 193 | + if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Software\\" PACKAGE_NAME,0,KEY_QUERY_VALUE,&hKey) == ERROR_SUCCESS) | |
| 194 | + { | |
| 195 | + char data[4096]; | |
| 196 | + unsigned long datalen = sizeof(data); // data field length(in), data returned length(out) | |
| 197 | + unsigned long datatype; // #defined in winnt.h (predefined types 0-11) | |
| 198 | + | |
| 199 | + if(RegQueryValueExA(hKey,"datadir",NULL,&datatype,(LPBYTE) data,&datalen) == ERROR_SUCCESS) | |
| 200 | + { | |
| 201 | + strncat(data,"\\certs",4095); | |
| 202 | + | |
| 203 | + trace("Loading certs from \"%s\"",data); | |
| 204 | + SSL_CTX_load_verify_locations(ssl_ctx,NULL,data); | |
| 205 | + } | |
| 206 | + RegCloseKey(hKey); | |
| 207 | + } | |
| 208 | + | |
| 209 | + | |
| 210 | + } | |
| 211 | + | |
| 212 | +#endif // _WIN32 | |
| 213 | + | |
| 214 | + ssl_3270_ex_index = SSL_get_ex_new_index(0,NULL,NULL,NULL,NULL); | |
| 215 | + | |
| 216 | + | |
| 217 | + } | |
| 218 | + | |
| 219 | + if(session->ssl_con) | |
| 220 | + SSL_free(session->ssl_con); | |
| 221 | + | |
| 222 | + session->ssl_con = SSL_new(ssl_ctx); | |
| 223 | + if(session->ssl_con == NULL) | |
| 224 | + { | |
| 225 | + popup_an_error(session,"SSL_new failed"); | |
| 226 | + session->ssl_host = False; | |
| 227 | + return; | |
| 228 | + } | |
| 229 | + | |
| 230 | + SSL_set_ex_data(session->ssl_con,ssl_3270_ex_index,(char *) session); | |
| 231 | + | |
| 232 | +// SSL_set_verify(session->ssl_con, SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); | |
| 233 | + SSL_set_verify(session->ssl_con, 0, NULL); | |
| 234 | + | |
| 235 | +} | |
| 236 | + | |
| 237 | +/* Callback for tracing protocol negotiation. */ | |
| 238 | +void ssl_info_callback(INFO_CONST SSL *s, int where, int ret) | |
| 239 | +{ | |
| 240 | +// H3270 *hSession = lib3270_get_default_session_handle(); // TODO: Find a better way! | |
| 241 | + H3270 *hSession = (H3270 *) SSL_get_ex_data(s,ssl_3270_ex_index); | |
| 242 | + | |
| 243 | +#ifdef DEBUG | |
| 244 | + trace("%s: hsession=%p, session=%p",__FUNCTION__,hSession,lib3270_get_default_session_handle()); | |
| 245 | + if(hSession != lib3270_get_default_session_handle()) | |
| 246 | + exit(-1); | |
| 247 | +#endif // DEBUG | |
| 248 | + | |
| 249 | + switch(where) | |
| 250 | + { | |
| 251 | + case SSL_CB_CONNECT_LOOP: | |
| 252 | + trace_dsn(hSession,"SSL_connect: %s %s\n",SSL_state_string(s), SSL_state_string_long(s)); | |
| 253 | + break; | |
| 254 | + | |
| 255 | + case SSL_CB_CONNECT_EXIT: | |
| 256 | + | |
| 257 | + trace_dsn(hSession,"%s: SSL_CB_CONNECT_EXIT\n",__FUNCTION__); | |
| 258 | + | |
| 259 | + if (ret == 0) | |
| 260 | + { | |
| 261 | + trace_dsn(hSession,"SSL_connect: failed in %s\n",SSL_state_string_long(s)); | |
| 262 | + } | |
| 263 | + else if (ret < 0) | |
| 264 | + { | |
| 265 | + unsigned long e = ERR_get_error(); | |
| 266 | + char err_buf[1024]; | |
| 267 | + | |
| 268 | + if(e != 0) | |
| 269 | + { | |
| 270 | + hSession->ssl_error = e; | |
| 271 | + (void) ERR_error_string_n(e, err_buf, 1023); | |
| 272 | + } | |
| 273 | +#if defined(_WIN32) | |
| 274 | + else if (GetLastError() != 0) | |
| 275 | + { | |
| 276 | + strncpy(err_buf,lib3270_win32_strerror(GetLastError()),1023); | |
| 277 | + } | |
| 278 | +#else | |
| 279 | + else if (errno != 0) | |
| 280 | + { | |
| 281 | + strncpy(err_buf, strerror(errno),1023); | |
| 282 | + } | |
| 283 | +#endif | |
| 284 | + else | |
| 285 | + { | |
| 286 | + err_buf[0] = '\0'; | |
| 287 | + } | |
| 288 | + | |
| 289 | + trace_dsn(hSession,"SSL Connect error %d\nMessage: %s\nState: %s\nAlert: %s\n", | |
| 290 | + ret, | |
| 291 | + err_buf, | |
| 292 | + SSL_state_string_long(s), | |
| 293 | + SSL_alert_type_string_long(ret) | |
| 294 | + ); | |
| 295 | + | |
| 296 | + } | |
| 297 | + | |
| 298 | + | |
| 299 | + default: | |
| 300 | + trace_dsn(hSession,"SSL Current state is \"%s\"\n",SSL_state_string_long(s)); | |
| 301 | + } | |
| 302 | + | |
| 303 | +// trace("%s: state=%04x where=%04x ret=%d",__FUNCTION__,SSL_state(s),where,ret); | |
| 304 | + | |
| 305 | +#ifdef DEBUG | |
| 306 | + if(where & SSL_CB_EXIT) | |
| 307 | + { | |
| 308 | + trace("%s: SSL_CB_EXIT ret=%d\n",__FUNCTION__,ret); | |
| 309 | + } | |
| 310 | +#endif | |
| 311 | + | |
| 312 | + if(where & SSL_CB_ALERT) | |
| 313 | + trace_dsn(hSession,"SSL ALERT: %s\n",SSL_alert_type_string_long(ret)); | |
| 314 | + | |
| 315 | + if(where & SSL_CB_HANDSHAKE_DONE) | |
| 316 | + { | |
| 317 | + trace_dsn(hSession,"%s: SSL_CB_HANDSHAKE_DONE state=%04x\n",__FUNCTION__,SSL_state(s)); | |
| 318 | + if(SSL_state(s) == 0x03) | |
| 319 | + set_ssl_state(hSession,LIB3270_SSL_NEGOTIATED); | |
| 320 | + else | |
| 321 | + set_ssl_state(hSession,LIB3270_SSL_UNSECURE); | |
| 322 | + } | |
| 323 | +} | |
| 324 | + | |
| 325 | +#endif /*]*/ | |
| 326 | + | |
| 327 | +LIB3270_EXPORT LIB3270_SSL_STATE lib3270_get_secure(H3270 *session) | |
| 328 | +{ | |
| 329 | + CHECK_SESSION_HANDLE(session); | |
| 330 | + return session->secure; | |
| 331 | +} | |
| 332 | + | |
| 333 | +LIB3270_EXPORT int lib3270_is_secure(H3270 *hSession) | |
| 334 | +{ | |
| 335 | + return lib3270_get_secure(hSession) == LIB3270_SSL_SECURE; | |
| 336 | +} | |
| 337 | + | |
| 338 | +LIB3270_EXPORT long lib3270_get_SSL_verify_result(H3270 *hSession) | |
| 339 | +{ | |
| 340 | + CHECK_SESSION_HANDLE(hSession); | |
| 341 | +#if defined(HAVE_LIBSSL) | |
| 342 | + if(hSession->ssl_con) | |
| 343 | + return SSL_get_verify_result(hSession->ssl_con); | |
| 344 | +#endif // HAVE_LIBSSL | |
| 345 | + return -1; | |
| 346 | +} | |
| 347 | + | |
| 348 | +void set_ssl_state(H3270 *session, LIB3270_SSL_STATE state) | |
| 349 | +{ | |
| 350 | + if(state == session->secure) | |
| 351 | + return; | |
| 352 | + | |
| 353 | + trace_dsn(session,"SSL state changes to %d\n",(int) state); | |
| 354 | + | |
| 355 | + session->update_ssl(session,session->secure = state); | |
| 356 | +} | ... | ... |
src/lib3270/telnet.c
| ... | ... | @@ -46,10 +46,6 @@ |
| 46 | 46 | #endif // !ANDROID |
| 47 | 47 | |
| 48 | 48 | #include <lib3270/config.h> |
| 49 | -#if defined(HAVE_LIBSSL) | |
| 50 | - #include <openssl/ssl.h> | |
| 51 | - #include <openssl/err.h> | |
| 52 | -#endif | |
| 53 | 49 | |
| 54 | 50 | #include "globals.h" |
| 55 | 51 | #include <errno.h> |
| ... | ... | @@ -136,8 +132,9 @@ static void net_rawout(H3270 *session, unsigned const char *buf, size_t len); |
| 136 | 132 | static void check_in3270(H3270 *session); |
| 137 | 133 | static void store3270in(H3270 *hSession, unsigned char c); |
| 138 | 134 | static void check_linemode(H3270 *hSession, Boolean init); |
| 139 | -static int non_blocking(H3270 *session, Boolean on); | |
| 140 | 135 | static int net_connected(H3270 *session); |
| 136 | +static void continue_tls(H3270 *hSession, unsigned char *sbbuf, int len); | |
| 137 | + | |
| 141 | 138 | #if defined(X3270_TN3270E) /*[*/ |
| 142 | 139 | static int tn3270e_negotiate(H3270 *hSession); |
| 143 | 140 | #endif /*]*/ |
| ... | ... | @@ -239,22 +236,6 @@ static const char *trsp_flag[2] = { "POSITIVE-RESPONSE", "NEGATIVE-RESPONSE" }; |
| 239 | 236 | #define XMIT_ROWS hSession->maxROWS |
| 240 | 237 | #define XMIT_COLS hSession->maxCOLS |
| 241 | 238 | |
| 242 | -#if defined(HAVE_LIBSSL) /*[*/ | |
| 243 | - | |
| 244 | - static void ssl_init(H3270 *session); | |
| 245 | - | |
| 246 | - #if OPENSSL_VERSION_NUMBER >= 0x00907000L /*[*/ | |
| 247 | - #define INFO_CONST const | |
| 248 | - #else /*][*/ | |
| 249 | - #define INFO_CONST | |
| 250 | - #endif /*]*/ | |
| 251 | - | |
| 252 | - static void ssl_info_callback(INFO_CONST SSL *s, int where, int ret); | |
| 253 | - static void continue_tls(H3270 *hSession, unsigned char *sbbuf, int len); | |
| 254 | - | |
| 255 | - static int ssl_3270_ex_index = -1; /**< Index of h3270 handle in SSL session */ | |
| 256 | - | |
| 257 | -#endif /*]*/ | |
| 258 | 239 | |
| 259 | 240 | #if defined(_WIN32) /*[*/ |
| 260 | 241 | #define socket_errno() WSAGetLastError() |
| ... | ... | @@ -285,16 +266,6 @@ static const char *trsp_flag[2] = { "POSITIVE-RESPONSE", "NEGATIVE-RESPONSE" }; |
| 285 | 266 | |
| 286 | 267 | /*--[ Implement ]------------------------------------------------------------------------------------*/ |
| 287 | 268 | |
| 288 | -static void set_ssl_state(H3270 *session, LIB3270_SSL_STATE state) | |
| 289 | -{ | |
| 290 | - if(state == session->secure) | |
| 291 | - return; | |
| 292 | - | |
| 293 | - trace_dsn(session,"SSL state changes to %d\n",(int) state); | |
| 294 | - | |
| 295 | - session->update_ssl(session,session->secure = state); | |
| 296 | -} | |
| 297 | - | |
| 298 | 269 | #if defined(_WIN32) /*[*/ |
| 299 | 270 | void sockstart(H3270 *session) |
| 300 | 271 | { |
| ... | ... | @@ -801,121 +772,6 @@ static void setup_lus(H3270 *hSession) |
| 801 | 772 | hSession->try_lu = *hSession->curr_lu; |
| 802 | 773 | } |
| 803 | 774 | |
| 804 | -#if defined(HAVE_LIBSSL) | |
| 805 | -static int ssl_negotiate(H3270 *hSession) | |
| 806 | -{ | |
| 807 | - int rv; | |
| 808 | - | |
| 809 | - trace("%s",__FUNCTION__); | |
| 810 | - | |
| 811 | - set_ssl_state(hSession,LIB3270_SSL_NEGOTIATING); | |
| 812 | - non_blocking(hSession,False); | |
| 813 | - | |
| 814 | - /* Initialize the SSL library. */ | |
| 815 | - ssl_init(hSession); | |
| 816 | - if(hSession->ssl_con == NULL) | |
| 817 | - { | |
| 818 | - /* Failed. */ | |
| 819 | - popup_an_error(hSession,_( "SSL init failed!")); | |
| 820 | - net_disconnect(hSession); | |
| 821 | - return -1; | |
| 822 | - } | |
| 823 | - | |
| 824 | - /* Set up the TLS/SSL connection. */ | |
| 825 | - if(SSL_set_fd(hSession->ssl_con, hSession->sock) != 1) | |
| 826 | - { | |
| 827 | - trace_dsn(hSession,"SSL_set_fd failed!\n"); | |
| 828 | - popup_an_error(hSession,_( "SSL_set_fd failed!")); | |
| 829 | - net_disconnect(hSession); | |
| 830 | - return -1; | |
| 831 | - } | |
| 832 | - | |
| 833 | - trace("%s: Running SSL_connect",__FUNCTION__); | |
| 834 | - rv = SSL_connect(hSession->ssl_con); | |
| 835 | - trace("%s: SSL_connect exits with rc=%d",__FUNCTION__,rv); | |
| 836 | - | |
| 837 | - if (rv != 1) | |
| 838 | - { | |
| 839 | - int ssl_error = SSL_get_error(hSession->ssl_con,rv); | |
| 840 | - | |
| 841 | - if(ssl_error == SSL_ERROR_SYSCALL) | |
| 842 | - { | |
| 843 | - if(!hSession->ssl_error) | |
| 844 | - { | |
| 845 | - trace_dsn(hSession,"SSL_connect failed (ssl_error=%lu)\n",hSession->ssl_error); | |
| 846 | - popup_an_error(hSession,_( "SSL connect failed!")); | |
| 847 | - } | |
| 848 | - else | |
| 849 | - { | |
| 850 | - trace_dsn(hSession,"SSL_connect failed: %s %s\n", | |
| 851 | - ERR_lib_error_string(hSession->ssl_error), | |
| 852 | - ERR_reason_error_string(hSession->ssl_error)); | |
| 853 | - popup_an_error(hSession,"%s",_( ERR_reason_error_string(hSession->ssl_error) )); | |
| 854 | - } | |
| 855 | - | |
| 856 | - } | |
| 857 | - else | |
| 858 | - { | |
| 859 | - trace_dsn(hSession,"SSL_connect failed (ssl_error=%d errno=%d)\n",ssl_error,errno); | |
| 860 | - popup_an_error(hSession,_( "SSL connect failed!")); | |
| 861 | - } | |
| 862 | - | |
| 863 | - net_disconnect(hSession); | |
| 864 | - return -1; | |
| 865 | - } | |
| 866 | - | |
| 867 | - non_blocking(hSession,True); | |
| 868 | - | |
| 869 | - /* Success. */ | |
| 870 | - if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_DS_TRACE)) | |
| 871 | - { | |
| 872 | - char buffer[4096]; | |
| 873 | - int alg_bits = 0; | |
| 874 | - const SSL_CIPHER * cipher = SSL_get_current_cipher(hSession->ssl_con); | |
| 875 | - X509 * peer = SSL_get_peer_certificate(hSession->ssl_con); | |
| 876 | - | |
| 877 | - trace_dsn(hSession,"TLS/SSL negotiated connection complete. Connection is now secure.\n"); | |
| 878 | - | |
| 879 | - trace_dsn(hSession,"TLS/SSL cipher description: %s",SSL_CIPHER_description((SSL_CIPHER *) cipher, buffer, 4095)); | |
| 880 | - SSL_CIPHER_get_bits(cipher, &alg_bits); | |
| 881 | - trace_dsn(hSession,"%s version %s with %d bits verify=%ld\n", | |
| 882 | - SSL_CIPHER_get_name(cipher), | |
| 883 | - SSL_CIPHER_get_version(cipher), | |
| 884 | - alg_bits, | |
| 885 | - SSL_get_verify_result(hSession->ssl_con)); | |
| 886 | - | |
| 887 | - if(peer) | |
| 888 | - { | |
| 889 | - BIO * out = BIO_new(BIO_s_mem()); | |
| 890 | - unsigned char * data; | |
| 891 | - unsigned char * text; | |
| 892 | - int n; | |
| 893 | - | |
| 894 | - X509_print(out,peer); | |
| 895 | - | |
| 896 | - n = BIO_get_mem_data(out, &data); | |
| 897 | - text = (unsigned char *) malloc (n+1); | |
| 898 | - text[n] ='\0'; | |
| 899 | - memcpy(text,data,n); | |
| 900 | - | |
| 901 | - trace_dsn(hSession,"TLS/SSL peer certificate:\n%s\n",text); | |
| 902 | - | |
| 903 | - free(text); | |
| 904 | - BIO_free(out); | |
| 905 | - X509_free(peer); | |
| 906 | - | |
| 907 | - } | |
| 908 | - } | |
| 909 | - | |
| 910 | - if(!SSL_get_verify_result(hSession->ssl_con)) | |
| 911 | - set_ssl_state(hSession,LIB3270_SSL_SECURE); | |
| 912 | - | |
| 913 | - /* Tell the world that we are (still) connected, now in secure mode. */ | |
| 914 | - lib3270_set_connected(hSession); | |
| 915 | - return 0; | |
| 916 | -} | |
| 917 | -#endif // HAVE_LIBSSL | |
| 918 | - | |
| 919 | 775 | static int net_connected(H3270 *hSession) |
| 920 | 776 | { |
| 921 | 777 | if(hSession->proxy_type > 0) |
| ... | ... | @@ -1627,6 +1483,29 @@ static int telnet_fsm(H3270 *hSession, unsigned char c) |
| 1627 | 1483 | return 0; |
| 1628 | 1484 | } |
| 1629 | 1485 | |
| 1486 | +/** | |
| 1487 | + * Process a STARTTLS subnegotiation. | |
| 1488 | + */ | |
| 1489 | +static void continue_tls(H3270 *hSession, unsigned char *sbbuf, int len) | |
| 1490 | +{ | |
| 1491 | + /* Whatever happens, we're not expecting another SB STARTTLS. */ | |
| 1492 | + hSession->need_tls_follows = 0; | |
| 1493 | + | |
| 1494 | + /* Make sure the option is FOLLOWS. */ | |
| 1495 | + if (len < 2 || sbbuf[1] != TLS_FOLLOWS) | |
| 1496 | + { | |
| 1497 | + /* Trace the junk. */ | |
| 1498 | + trace_dsn(hSession,"%s ? %s\n", opt(TELOPT_STARTTLS), cmd(SE)); | |
| 1499 | + popup_an_error(hSession,_( "TLS negotiation failure")); | |
| 1500 | + net_disconnect(hSession); | |
| 1501 | + return; | |
| 1502 | + } | |
| 1503 | + | |
| 1504 | + /* Trace what we got. */ | |
| 1505 | + trace_dsn(hSession,"%s FOLLOWS %s\n", opt(TELOPT_STARTTLS), cmd(SE)); | |
| 1506 | + ssl_negotiate(hSession); | |
| 1507 | +} | |
| 1508 | + | |
| 1630 | 1509 | #if defined(X3270_TN3270E) /*[*/ |
| 1631 | 1510 | /* Send a TN3270E terminal type request. */ |
| 1632 | 1511 | static void tn3270e_request(H3270 *hSession) |
| ... | ... | @@ -3127,237 +3006,6 @@ parse_ctlchar(char *s) |
| 3127 | 3006 | } |
| 3128 | 3007 | #endif /*]*/ |
| 3129 | 3008 | |
| 3130 | -/* | |
| 3131 | - * Set blocking/non-blocking mode on the socket. On error, pops up an error | |
| 3132 | - * message, but does not close the socket. | |
| 3133 | - */ | |
| 3134 | -static int non_blocking(H3270 *session, Boolean on) | |
| 3135 | -{ | |
| 3136 | -# if defined(FIONBIO) | |
| 3137 | - | |
| 3138 | - int i = on ? 1 : 0; | |
| 3139 | - | |
| 3140 | - if (SOCK_IOCTL(session->sock, FIONBIO, (int *) &i) < 0) | |
| 3141 | - { | |
| 3142 | - popup_a_sockerr(session,N_( "Error in ioctl(%s) when setting no blocking mode" ), "FIONBIO"); | |
| 3143 | - return -1; | |
| 3144 | - } | |
| 3145 | - | |
| 3146 | -#else | |
| 3147 | - | |
| 3148 | - int f; | |
| 3149 | - | |
| 3150 | - if ((f = fcntl(session->sock, F_GETFL, 0)) == -1) | |
| 3151 | - { | |
| 3152 | - popup_an_errno(session,errno, _( "Error in fcntl(%s) when setting non blocking mode" ), "F_GETFL" ); | |
| 3153 | - return -1; | |
| 3154 | - } | |
| 3155 | - | |
| 3156 | - if (on) | |
| 3157 | - f |= O_NDELAY; | |
| 3158 | - else | |
| 3159 | - f &= ~O_NDELAY; | |
| 3160 | - | |
| 3161 | - if (fcntl(session->sock, F_SETFL, f) < 0) | |
| 3162 | - { | |
| 3163 | - popup_an_errno(session,errno, _( "Error in fcntl(%s) when setting non blocking mode" ), "F_SETFL"); | |
| 3164 | - return -1; | |
| 3165 | - } | |
| 3166 | - | |
| 3167 | -#endif // FIONBIO | |
| 3168 | - | |
| 3169 | - trace("Socket %d is %s",session->sock, on ? "non-blocking" : "blocking"); | |
| 3170 | - | |
| 3171 | - return 0; | |
| 3172 | -} | |
| 3173 | - | |
| 3174 | -#if defined(HAVE_LIBSSL) /*[*/ | |
| 3175 | - | |
| 3176 | -/* Initialize the OpenSSL library. */ | |
| 3177 | -static void ssl_init(H3270 *session) | |
| 3178 | -{ | |
| 3179 | - static SSL_CTX *ssl_ctx = NULL; | |
| 3180 | - | |
| 3181 | - session->ssl_error = 0; | |
| 3182 | - set_ssl_state(session,LIB3270_SSL_UNDEFINED); | |
| 3183 | - | |
| 3184 | - if(ssl_ctx == NULL) | |
| 3185 | - { | |
| 3186 | - lib3270_write_log(session,"SSL","%s","Initializing SSL context"); | |
| 3187 | - SSL_load_error_strings(); | |
| 3188 | - SSL_library_init(); | |
| 3189 | - ssl_ctx = SSL_CTX_new(SSLv23_method()); | |
| 3190 | - if(ssl_ctx == NULL) | |
| 3191 | - { | |
| 3192 | - popup_an_error(session,"SSL_CTX_new failed"); | |
| 3193 | - session->ssl_host = False; | |
| 3194 | - return; | |
| 3195 | - } | |
| 3196 | - SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL); | |
| 3197 | - SSL_CTX_set_info_callback(ssl_ctx, ssl_info_callback); | |
| 3198 | - SSL_CTX_set_default_verify_paths(ssl_ctx); | |
| 3199 | - | |
| 3200 | -#if defined(_WIN32) | |
| 3201 | - { | |
| 3202 | - HKEY hKey = 0; | |
| 3203 | - | |
| 3204 | - if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Software\\" PACKAGE_NAME,0,KEY_QUERY_VALUE,&hKey) == ERROR_SUCCESS) | |
| 3205 | - { | |
| 3206 | - char data[4096]; | |
| 3207 | - unsigned long datalen = sizeof(data); // data field length(in), data returned length(out) | |
| 3208 | - unsigned long datatype; // #defined in winnt.h (predefined types 0-11) | |
| 3209 | - | |
| 3210 | - if(RegQueryValueExA(hKey,"datadir",NULL,&datatype,(LPBYTE) data,&datalen) == ERROR_SUCCESS) | |
| 3211 | - { | |
| 3212 | - strncat(data,"\\certs",4095); | |
| 3213 | - | |
| 3214 | - trace("Loading certs from \"%s\"",data); | |
| 3215 | - SSL_CTX_load_verify_locations(ssl_ctx,NULL,data); | |
| 3216 | - } | |
| 3217 | - RegCloseKey(hKey); | |
| 3218 | - } | |
| 3219 | - | |
| 3220 | - | |
| 3221 | - } | |
| 3222 | - | |
| 3223 | -#endif // _WIN32 | |
| 3224 | - | |
| 3225 | - ssl_3270_ex_index = SSL_get_ex_new_index(0,NULL,NULL,NULL,NULL); | |
| 3226 | - | |
| 3227 | - | |
| 3228 | - } | |
| 3229 | - | |
| 3230 | - if(session->ssl_con) | |
| 3231 | - SSL_free(session->ssl_con); | |
| 3232 | - | |
| 3233 | - session->ssl_con = SSL_new(ssl_ctx); | |
| 3234 | - if(session->ssl_con == NULL) | |
| 3235 | - { | |
| 3236 | - popup_an_error(session,"SSL_new failed"); | |
| 3237 | - session->ssl_host = False; | |
| 3238 | - return; | |
| 3239 | - } | |
| 3240 | - | |
| 3241 | - SSL_set_ex_data(session->ssl_con,ssl_3270_ex_index,(char *) session); | |
| 3242 | - | |
| 3243 | -// SSL_set_verify(session->ssl_con, SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); | |
| 3244 | - SSL_set_verify(session->ssl_con, 0, NULL); | |
| 3245 | - | |
| 3246 | -} | |
| 3247 | - | |
| 3248 | -/* Callback for tracing protocol negotiation. */ | |
| 3249 | -static void ssl_info_callback(INFO_CONST SSL *s, int where, int ret) | |
| 3250 | -{ | |
| 3251 | -// H3270 *hSession = lib3270_get_default_session_handle(); // TODO: Find a better way! | |
| 3252 | - H3270 *hSession = (H3270 *) SSL_get_ex_data(s,ssl_3270_ex_index); | |
| 3253 | - | |
| 3254 | -#ifdef DEBUG | |
| 3255 | - trace("%s: hsession=%p, session=%p",__FUNCTION__,hSession,lib3270_get_default_session_handle()); | |
| 3256 | - if(hSession != lib3270_get_default_session_handle()) | |
| 3257 | - exit(-1); | |
| 3258 | -#endif // DEBUG | |
| 3259 | - | |
| 3260 | - switch(where) | |
| 3261 | - { | |
| 3262 | - case SSL_CB_CONNECT_LOOP: | |
| 3263 | - trace_dsn(hSession,"SSL_connect: %s %s\n",SSL_state_string(s), SSL_state_string_long(s)); | |
| 3264 | - break; | |
| 3265 | - | |
| 3266 | - case SSL_CB_CONNECT_EXIT: | |
| 3267 | - | |
| 3268 | - trace_dsn(hSession,"%s: SSL_CB_CONNECT_EXIT\n",__FUNCTION__); | |
| 3269 | - | |
| 3270 | - if (ret == 0) | |
| 3271 | - { | |
| 3272 | - trace_dsn(hSession,"SSL_connect: failed in %s\n",SSL_state_string_long(s)); | |
| 3273 | - } | |
| 3274 | - else if (ret < 0) | |
| 3275 | - { | |
| 3276 | - unsigned long e = ERR_get_error(); | |
| 3277 | - char err_buf[1024]; | |
| 3278 | - | |
| 3279 | - if(e != 0) | |
| 3280 | - { | |
| 3281 | - hSession->ssl_error = e; | |
| 3282 | - (void) ERR_error_string_n(e, err_buf, 1023); | |
| 3283 | - } | |
| 3284 | -#if defined(_WIN32) | |
| 3285 | - else if (GetLastError() != 0) | |
| 3286 | - { | |
| 3287 | - strncpy(err_buf,lib3270_win32_strerror(GetLastError()),1023); | |
| 3288 | - } | |
| 3289 | -#else | |
| 3290 | - else if (errno != 0) | |
| 3291 | - { | |
| 3292 | - strncpy(err_buf, strerror(errno),1023); | |
| 3293 | - } | |
| 3294 | -#endif | |
| 3295 | - else | |
| 3296 | - { | |
| 3297 | - err_buf[0] = '\0'; | |
| 3298 | - } | |
| 3299 | - | |
| 3300 | - trace_dsn(hSession,"SSL Connect error %d\nMessage: %s\nState: %s\nAlert: %s\n", | |
| 3301 | - ret, | |
| 3302 | - err_buf, | |
| 3303 | - SSL_state_string_long(s), | |
| 3304 | - SSL_alert_type_string_long(ret) | |
| 3305 | - ); | |
| 3306 | - | |
| 3307 | - } | |
| 3308 | - | |
| 3309 | - | |
| 3310 | - default: | |
| 3311 | - trace_dsn(hSession,"SSL Current state is \"%s\"\n",SSL_state_string_long(s)); | |
| 3312 | - } | |
| 3313 | - | |
| 3314 | -// trace("%s: state=%04x where=%04x ret=%d",__FUNCTION__,SSL_state(s),where,ret); | |
| 3315 | - | |
| 3316 | -#ifdef DEBUG | |
| 3317 | - if(where & SSL_CB_EXIT) | |
| 3318 | - { | |
| 3319 | - trace("%s: SSL_CB_EXIT ret=%d\n",__FUNCTION__,ret); | |
| 3320 | - } | |
| 3321 | -#endif | |
| 3322 | - | |
| 3323 | - if(where & SSL_CB_ALERT) | |
| 3324 | - trace_dsn(hSession,"SSL ALERT: %s\n",SSL_alert_type_string_long(ret)); | |
| 3325 | - | |
| 3326 | - if(where & SSL_CB_HANDSHAKE_DONE) | |
| 3327 | - { | |
| 3328 | - trace_dsn(hSession,"%s: SSL_CB_HANDSHAKE_DONE state=%04x\n",__FUNCTION__,SSL_state(s)); | |
| 3329 | - if(SSL_state(s) == 0x03) | |
| 3330 | - set_ssl_state(hSession,LIB3270_SSL_NEGOTIATED); | |
| 3331 | - else | |
| 3332 | - set_ssl_state(hSession,LIB3270_SSL_UNSECURE); | |
| 3333 | - } | |
| 3334 | -} | |
| 3335 | - | |
| 3336 | -/** | |
| 3337 | - * Process a STARTTLS subnegotiation. | |
| 3338 | - */ | |
| 3339 | -static void continue_tls(H3270 *hSession, unsigned char *sbbuf, int len) | |
| 3340 | -{ | |
| 3341 | - /* Whatever happens, we're not expecting another SB STARTTLS. */ | |
| 3342 | - hSession->need_tls_follows = 0; | |
| 3343 | - | |
| 3344 | - /* Make sure the option is FOLLOWS. */ | |
| 3345 | - if (len < 2 || sbbuf[1] != TLS_FOLLOWS) | |
| 3346 | - { | |
| 3347 | - /* Trace the junk. */ | |
| 3348 | - trace_dsn(hSession,"%s ? %s\n", opt(TELOPT_STARTTLS), cmd(SE)); | |
| 3349 | - popup_an_error(hSession,_( "TLS negotiation failure")); | |
| 3350 | - net_disconnect(hSession); | |
| 3351 | - return; | |
| 3352 | - } | |
| 3353 | - | |
| 3354 | - /* Trace what we got. */ | |
| 3355 | - trace_dsn(hSession,"%s FOLLOWS %s\n", opt(TELOPT_STARTTLS), cmd(SE)); | |
| 3356 | - ssl_negotiate(hSession); | |
| 3357 | -} | |
| 3358 | - | |
| 3359 | -#endif /*]*/ | |
| 3360 | - | |
| 3361 | 3009 | /* Return the local address for the socket. */ |
| 3362 | 3010 | int net_getsockname(const H3270 *session, void *buf, int *len) |
| 3363 | 3011 | { |
| ... | ... | @@ -3365,24 +3013,3 @@ int net_getsockname(const H3270 *session, void *buf, int *len) |
| 3365 | 3013 | return -1; |
| 3366 | 3014 | return getsockname(session->sock, buf, (socklen_t *)(void *)len); |
| 3367 | 3015 | } |
| 3368 | - | |
| 3369 | -LIB3270_EXPORT LIB3270_SSL_STATE lib3270_get_secure(H3270 *session) | |
| 3370 | -{ | |
| 3371 | - CHECK_SESSION_HANDLE(session); | |
| 3372 | - return session->secure; | |
| 3373 | -} | |
| 3374 | - | |
| 3375 | -LIB3270_EXPORT int lib3270_is_secure(H3270 *hSession) | |
| 3376 | -{ | |
| 3377 | - return lib3270_get_secure(hSession) == LIB3270_SSL_SECURE; | |
| 3378 | -} | |
| 3379 | - | |
| 3380 | -LIB3270_EXPORT long lib3270_get_SSL_verify_result(H3270 *hSession) | |
| 3381 | -{ | |
| 3382 | - CHECK_SESSION_HANDLE(hSession); | |
| 3383 | -#if defined(HAVE_LIBSSL) | |
| 3384 | - if(hSession->ssl_con) | |
| 3385 | - return SSL_get_verify_result(hSession->ssl_con); | |
| 3386 | -#endif // HAVE_LIBSSL | |
| 3387 | - return -1; | |
| 3388 | -} | ... | ... |
src/lib3270/testprogram.c
| ... | ... | @@ -22,7 +22,7 @@ static void * mainloop(void *dunno) |
| 22 | 22 | int main(int numpar, char *param[]) |
| 23 | 23 | { |
| 24 | 24 | H3270 * h; |
| 25 | - char line[4096]; | |
| 25 | +// char line[4096]; | |
| 26 | 26 | // pthread_t thread; |
| 27 | 27 | |
| 28 | 28 | lib3270_initialize(); |
| ... | ... | @@ -30,10 +30,13 @@ int main(int numpar, char *param[]) |
| 30 | 30 | session = h = lib3270_session_new(""); |
| 31 | 31 | printf("3270 session %p created\n]",h); |
| 32 | 32 | |
| 33 | + lib3270_set_toggle(session,LIB3270_TOGGLE_DS_TRACE,1); | |
| 34 | + | |
| 33 | 35 | // pthread_create(&thread, NULL, mainloop, NULL); |
| 34 | 36 | // pthread_detach(thread); |
| 35 | 37 | |
| 36 | - lib3270_connect_host(h, "fandezhi.efglobe.com", "telnet"); | |
| 38 | + lib3270_connect_host(h, "$HOST3270", "8023"); | |
| 39 | +// lib3270_connect_host(h, "fandezhi.efglobe.com", "telnet"); | |
| 37 | 40 | // lib3270_connect_host(h, "127.0.0.1", "9090"); |
| 38 | 41 | |
| 39 | 42 | mainloop(0); | ... | ... |