Commit f3c2e2799eec8539531dcfe7cfcd8277317f168f
1 parent
d9eeb3b7
Exists in
master
and in
3 other branches
Separando funções SSL do módulo telnet para facilitar a manutenção
Showing
7 changed files
with
464 additions
and
525 deletions
Show diff stats
connect.c
| @@ -82,7 +82,7 @@ static void net_connected(H3270 *hSession) | @@ -82,7 +82,7 @@ static void net_connected(H3270 *hSession) | ||
| 82 | _( "Network error" ), | 82 | _( "Network error" ), |
| 83 | _( "Unable to get connection state." ), | 83 | _( "Unable to get connection state." ), |
| 84 | #ifdef _WIN32 | 84 | #ifdef _WIN32 |
| 85 | - _( "Winsock Error %d"), WSAGetLastError() | 85 | + "%s", lib3270_win32_strerror(WSAGetLastError())); |
| 86 | #else | 86 | #else |
| 87 | _( "%s" ), strerror(errno) | 87 | _( "%s" ), strerror(errno) |
| 88 | #endif // _WIN32 | 88 | #endif // _WIN32 |
| @@ -167,16 +167,6 @@ static void net_connected(H3270 *hSession) | @@ -167,16 +167,6 @@ static void net_connected(H3270 *hSession) | ||
| 167 | } | 167 | } |
| 168 | #endif /*]*/ | 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 | LIB3270_EXPORT int lib3270_connect_host(H3270 *hSession, const char *hostname, const char *srvc) | 170 | LIB3270_EXPORT int lib3270_connect_host(H3270 *hSession, const char *hostname, const char *srvc) |
| 181 | { | 171 | { |
| 182 | int s; | 172 | int s; |
| @@ -303,8 +293,7 @@ static void net_connected(H3270 *hSession) | @@ -303,8 +293,7 @@ static void net_connected(H3270 *hSession) | ||
| 303 | LIB3270_NOTIFY_ERROR, | 293 | LIB3270_NOTIFY_ERROR, |
| 304 | _( "Connection error" ), | 294 | _( "Connection error" ), |
| 305 | _( "ioctlsocket(FIONBIO) failed." ), | 295 | _( "ioctlsocket(FIONBIO) failed." ), |
| 306 | - "%s", lib3270_win32_strerror(GetLastError())); | ||
| 307 | - | 296 | + "%s", lib3270_win32_strerror(WSAGetLastError())); |
| 308 | SOCK_CLOSE(hSession); | 297 | SOCK_CLOSE(hSession); |
| 309 | } | 298 | } |
| 310 | else if(connect(hSession->sock, rp->ai_addr, rp->ai_addrlen)) | 299 | else if(connect(hSession->sock, rp->ai_addr, rp->ai_addrlen)) |
| @@ -316,7 +305,7 @@ static void net_connected(H3270 *hSession) | @@ -316,7 +305,7 @@ static void net_connected(H3270 *hSession) | ||
| 316 | LIB3270_NOTIFY_ERROR, | 305 | LIB3270_NOTIFY_ERROR, |
| 317 | _( "Connection error" ), | 306 | _( "Connection error" ), |
| 318 | _( "Can't connect to host." ), | 307 | _( "Can't connect to host." ), |
| 319 | - "%s", lib3270_win32_strerror(GetLastError())); | 308 | + "%s", lib3270_win32_strerror(err)); |
| 320 | SOCK_CLOSE(hSession); | 309 | SOCK_CLOSE(hSession); |
| 321 | } | 310 | } |
| 322 | } | 311 | } |
| @@ -390,3 +379,56 @@ static void net_connected(H3270 *hSession) | @@ -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 | + |
globals.h
| @@ -137,18 +137,6 @@ enum iaction { | @@ -137,18 +137,6 @@ enum iaction { | ||
| 137 | IA_IDLE | 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 | // Version strings | 140 | // Version strings |
| 153 | LIB3270_INTERNAL const char * build; | 141 | LIB3270_INTERNAL const char * build; |
| 154 | LIB3270_INTERNAL const char * app_defaults_version; | 142 | LIB3270_INTERNAL const char * app_defaults_version; |
| @@ -157,99 +145,15 @@ LIB3270_INTERNAL const char * build_rpq_timestamp; | @@ -157,99 +145,15 @@ LIB3270_INTERNAL const char * build_rpq_timestamp; | ||
| 157 | LIB3270_INTERNAL const char * build_rpq_version; | 145 | LIB3270_INTERNAL const char * build_rpq_version; |
| 158 | LIB3270_INTERNAL const char * build_rpq_revision; | 146 | LIB3270_INTERNAL const char * build_rpq_revision; |
| 159 | 147 | ||
| 160 | -// LIB3270_INTERNAL int children; | ||
| 161 | - | ||
| 162 | #if defined(X3270_DBCS) /*[*/ | 148 | #if defined(X3270_DBCS) /*[*/ |
| 163 | LIB3270_INTERNAL Boolean dbcs; | 149 | LIB3270_INTERNAL Boolean dbcs; |
| 164 | #endif /*]*/ | 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 | #if defined(X3270_DBCS) /*[*/ | 153 | #if defined(X3270_DBCS) /*[*/ |
| 187 | LIB3270_INTERNAL char *full_efontname_dbcs; | 154 | LIB3270_INTERNAL char *full_efontname_dbcs; |
| 188 | #endif /*]*/ | 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 | /* keyboard modifer bitmap */ | 158 | /* keyboard modifer bitmap */ |
| 255 | #define ShiftKeyDown 0x01 | 159 | #define ShiftKeyDown 0x01 |
| @@ -263,19 +167,7 @@ struct toggle_name { | @@ -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 | /* input key type */ | 170 | /* input key type */ |
| 278 | -// enum keytype { KT_STD, KT_GE }; | ||
| 279 | 171 | ||
| 280 | /* Naming convention for private actions. */ | 172 | /* Naming convention for private actions. */ |
| 281 | #define PA_PFX "PA-" | 173 | #define PA_PFX "PA-" |
| @@ -341,8 +233,6 @@ LIB3270_INTERNAL void key_ACharacter(H3270 *hSession, unsigned char c, enum keyt | @@ -341,8 +233,6 @@ LIB3270_INTERNAL void key_ACharacter(H3270 *hSession, unsigned char c, enum keyt | ||
| 341 | LIB3270_INTERNAL void lib3270_initialize(void); | 233 | LIB3270_INTERNAL void lib3270_initialize(void); |
| 342 | LIB3270_INTERNAL int cursor_move(H3270 *session, int baddr); | 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 | LIB3270_INTERNAL void toggle_rectselect(H3270 *session, struct lib3270_toggle *t, LIB3270_TOGGLE_TYPE tt); | 236 | LIB3270_INTERNAL void toggle_rectselect(H3270 *session, struct lib3270_toggle *t, LIB3270_TOGGLE_TYPE tt); |
| 347 | LIB3270_INTERNAL void remove_input_calls(H3270 *session); | 237 | LIB3270_INTERNAL void remove_input_calls(H3270 *session); |
| 348 | 238 | ||
| @@ -358,3 +248,23 @@ LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession); | @@ -358,3 +248,23 @@ LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession); | ||
| 358 | #endif // DEBUG | 248 | #endif // DEBUG |
| 359 | 249 | ||
| 360 | LIB3270_EXPORT int lib3270_connect_host(H3270 *hSession, const char *hostname, const char *srvc); | 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 | + |
lib3270.cbp
| @@ -189,6 +189,7 @@ | @@ -189,6 +189,7 @@ | ||
| 189 | </Unit> | 189 | </Unit> |
| 190 | <Unit filename="sfc.h" /> | 190 | <Unit filename="sfc.h" /> |
| 191 | <Unit filename="shlobj_missing.h" /> | 191 | <Unit filename="shlobj_missing.h" /> |
| 192 | + <Unit filename="sources.mak" /> | ||
| 192 | <Unit filename="state.c"> | 193 | <Unit filename="state.c"> |
| 193 | <Option compilerVar="CC" /> | 194 | <Option compilerVar="CC" /> |
| 194 | </Unit> | 195 | </Unit> |
sources.mak
| @@ -28,7 +28,7 @@ | @@ -28,7 +28,7 @@ | ||
| 28 | TERMINAL_SOURCES = bounds.c ctlr.c util.c toggles.c screen.c selection.c kybd.c telnet.c \ | 28 | TERMINAL_SOURCES = bounds.c ctlr.c util.c toggles.c screen.c selection.c kybd.c telnet.c \ |
| 29 | host.c sf.c ansi.c resolver.c charset.c \ | 29 | host.c sf.c ansi.c resolver.c charset.c \ |
| 30 | version.c session.c state.c html.c trace_ds.c see.c \ | 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 | # tables.c utf8.c | 33 | # tables.c utf8.c |
| 34 | 34 |
| @@ -0,0 +1,356 @@ | @@ -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 | +} |
telnet.c
| @@ -46,10 +46,6 @@ | @@ -46,10 +46,6 @@ | ||
| 46 | #endif // !ANDROID | 46 | #endif // !ANDROID |
| 47 | 47 | ||
| 48 | #include <lib3270/config.h> | 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 | #include "globals.h" | 50 | #include "globals.h" |
| 55 | #include <errno.h> | 51 | #include <errno.h> |
| @@ -136,8 +132,9 @@ static void net_rawout(H3270 *session, unsigned const char *buf, size_t len); | @@ -136,8 +132,9 @@ static void net_rawout(H3270 *session, unsigned const char *buf, size_t len); | ||
| 136 | static void check_in3270(H3270 *session); | 132 | static void check_in3270(H3270 *session); |
| 137 | static void store3270in(H3270 *hSession, unsigned char c); | 133 | static void store3270in(H3270 *hSession, unsigned char c); |
| 138 | static void check_linemode(H3270 *hSession, Boolean init); | 134 | static void check_linemode(H3270 *hSession, Boolean init); |
| 139 | -static int non_blocking(H3270 *session, Boolean on); | ||
| 140 | static int net_connected(H3270 *session); | 135 | static int net_connected(H3270 *session); |
| 136 | +static void continue_tls(H3270 *hSession, unsigned char *sbbuf, int len); | ||
| 137 | + | ||
| 141 | #if defined(X3270_TN3270E) /*[*/ | 138 | #if defined(X3270_TN3270E) /*[*/ |
| 142 | static int tn3270e_negotiate(H3270 *hSession); | 139 | static int tn3270e_negotiate(H3270 *hSession); |
| 143 | #endif /*]*/ | 140 | #endif /*]*/ |
| @@ -239,22 +236,6 @@ static const char *trsp_flag[2] = { "POSITIVE-RESPONSE", "NEGATIVE-RESPONSE" }; | @@ -239,22 +236,6 @@ static const char *trsp_flag[2] = { "POSITIVE-RESPONSE", "NEGATIVE-RESPONSE" }; | ||
| 239 | #define XMIT_ROWS hSession->maxROWS | 236 | #define XMIT_ROWS hSession->maxROWS |
| 240 | #define XMIT_COLS hSession->maxCOLS | 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 | #if defined(_WIN32) /*[*/ | 240 | #if defined(_WIN32) /*[*/ |
| 260 | #define socket_errno() WSAGetLastError() | 241 | #define socket_errno() WSAGetLastError() |
| @@ -285,16 +266,6 @@ static const char *trsp_flag[2] = { "POSITIVE-RESPONSE", "NEGATIVE-RESPONSE" }; | @@ -285,16 +266,6 @@ static const char *trsp_flag[2] = { "POSITIVE-RESPONSE", "NEGATIVE-RESPONSE" }; | ||
| 285 | 266 | ||
| 286 | /*--[ Implement ]------------------------------------------------------------------------------------*/ | 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 | #if defined(_WIN32) /*[*/ | 269 | #if defined(_WIN32) /*[*/ |
| 299 | void sockstart(H3270 *session) | 270 | void sockstart(H3270 *session) |
| 300 | { | 271 | { |
| @@ -801,121 +772,6 @@ static void setup_lus(H3270 *hSession) | @@ -801,121 +772,6 @@ static void setup_lus(H3270 *hSession) | ||
| 801 | hSession->try_lu = *hSession->curr_lu; | 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 | static int net_connected(H3270 *hSession) | 775 | static int net_connected(H3270 *hSession) |
| 920 | { | 776 | { |
| 921 | if(hSession->proxy_type > 0) | 777 | if(hSession->proxy_type > 0) |
| @@ -1627,6 +1483,29 @@ static int telnet_fsm(H3270 *hSession, unsigned char c) | @@ -1627,6 +1483,29 @@ static int telnet_fsm(H3270 *hSession, unsigned char c) | ||
| 1627 | return 0; | 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 | #if defined(X3270_TN3270E) /*[*/ | 1509 | #if defined(X3270_TN3270E) /*[*/ |
| 1631 | /* Send a TN3270E terminal type request. */ | 1510 | /* Send a TN3270E terminal type request. */ |
| 1632 | static void tn3270e_request(H3270 *hSession) | 1511 | static void tn3270e_request(H3270 *hSession) |
| @@ -3127,237 +3006,6 @@ parse_ctlchar(char *s) | @@ -3127,237 +3006,6 @@ parse_ctlchar(char *s) | ||
| 3127 | } | 3006 | } |
| 3128 | #endif /*]*/ | 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 | /* Return the local address for the socket. */ | 3009 | /* Return the local address for the socket. */ |
| 3362 | int net_getsockname(const H3270 *session, void *buf, int *len) | 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,24 +3013,3 @@ int net_getsockname(const H3270 *session, void *buf, int *len) | ||
| 3365 | return -1; | 3013 | return -1; |
| 3366 | return getsockname(session->sock, buf, (socklen_t *)(void *)len); | 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 | -} |
testprogram.c
| @@ -22,7 +22,7 @@ static void * mainloop(void *dunno) | @@ -22,7 +22,7 @@ static void * mainloop(void *dunno) | ||
| 22 | int main(int numpar, char *param[]) | 22 | int main(int numpar, char *param[]) |
| 23 | { | 23 | { |
| 24 | H3270 * h; | 24 | H3270 * h; |
| 25 | - char line[4096]; | 25 | +// char line[4096]; |
| 26 | // pthread_t thread; | 26 | // pthread_t thread; |
| 27 | 27 | ||
| 28 | lib3270_initialize(); | 28 | lib3270_initialize(); |
| @@ -30,10 +30,13 @@ int main(int numpar, char *param[]) | @@ -30,10 +30,13 @@ int main(int numpar, char *param[]) | ||
| 30 | session = h = lib3270_session_new(""); | 30 | session = h = lib3270_session_new(""); |
| 31 | printf("3270 session %p created\n]",h); | 31 | printf("3270 session %p created\n]",h); |
| 32 | 32 | ||
| 33 | + lib3270_set_toggle(session,LIB3270_TOGGLE_DS_TRACE,1); | ||
| 34 | + | ||
| 33 | // pthread_create(&thread, NULL, mainloop, NULL); | 35 | // pthread_create(&thread, NULL, mainloop, NULL); |
| 34 | // pthread_detach(thread); | 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 | // lib3270_connect_host(h, "127.0.0.1", "9090"); | 40 | // lib3270_connect_host(h, "127.0.0.1", "9090"); |
| 38 | 41 | ||
| 39 | mainloop(0); | 42 | mainloop(0); |