Commit 358c84c0e4f822573f7c26f024e003b2bee2c070

Authored by perry.werneck@gmail.com
1 parent 978afa4f

Corrigindo segfault/travamento quando a negociação SSL falha

Showing 3 changed files with 114 additions and 104 deletions   Show diff stats
XtGlue.c
... ... @@ -852,6 +852,7 @@ const char * KeysymToString(KeySym k)
852 852  
853 853 unsigned long AddTimeOut(unsigned long interval_ms, H3270 *session, void (*proc)(H3270 *session))
854 854 {
  855 + CHECK_SESSION_HANDLE(session);
855 856 if(callbacks->AddTimeOut)
856 857 return callbacks->AddTimeOut(interval_ms,session,proc);
857 858 return 0;
... ... @@ -865,6 +866,7 @@ void RemoveTimeOut(unsigned long timer)
865 866  
866 867 unsigned long AddInput(int source, H3270 *session, void (*fn)(H3270 *session))
867 868 {
  869 + CHECK_SESSION_HANDLE(session);
868 870 if(callbacks->AddInput)
869 871 return callbacks->AddInput(source,session,fn);
870 872 return 0;
... ... @@ -872,6 +874,7 @@ unsigned long AddInput(int source, H3270 *session, void (*fn)(H3270 *session))
872 874  
873 875 unsigned long AddExcept(int source, H3270 *session, void (*fn)(H3270 *session))
874 876 {
  877 + CHECK_SESSION_HANDLE(session);
875 878 if(callbacks->AddExcept)
876 879 return callbacks->AddExcept(source,session,fn);
877 880 return 0;
... ... @@ -880,6 +883,7 @@ unsigned long AddExcept(int source, H3270 *session, void (*fn)(H3270 *session))
880 883 #if !defined(_WIN32) /*[*/
881 884 unsigned long AddOutput(int source, H3270 *session, void (*fn)(H3270 *session))
882 885 {
  886 + CHECK_SESSION_HANDLE(session);
883 887 if(callbacks->AddOutput)
884 888 return callbacks->AddOutput(source,session,fn);
885 889 return 0;
... ...
telnet.c
... ... @@ -125,9 +125,9 @@ extern struct timeval ds_ts;
125 125 /* Statics */
126 126 // static int sock = -1; /* active socket */
127 127  
128   -#if defined(HAVE_LIBSSL) /*[*/
129   -static unsigned long last_ssl_error = 0;
130   -#endif
  128 +//#if defined(HAVE_LIBSSL) /*[*/
  129 +//static unsigned long last_ssl_error = 0;
  130 +//#endif
131 131  
132 132 //#if defined(_WIN32) /*[*/
133 133 //static HANDLE sock_handle = NULL;
... ... @@ -196,7 +196,7 @@ static void net_rawout(unsigned const char *buf, int len);
196 196 static void check_in3270(void);
197 197 static void store3270in(unsigned char c);
198 198 static void check_linemode(Boolean init);
199   -static int non_blocking(Boolean on);
  199 +// static int non_blocking(Boolean on);
200 200 static void net_connected(H3270 *session);
201 201 #if defined(X3270_TN3270E) /*[*/
202 202 static int tn3270e_negotiate(void);
... ... @@ -600,12 +600,14 @@ int net_connect(H3270 *session, const char *host, char *portname, Boolean ls, Bo
600 600 #endif
601 601  
602 602 /* set the socket to be non-delaying */
  603 +/*
603 604 #if defined(_WIN32)
604 605 if (non_blocking(False) < 0)
605 606 #else
606 607 if (non_blocking(True) < 0)
607 608 #endif
608 609 close_fail;
  610 +*/
609 611  
610 612 #if !defined(_WIN32)
611 613 /* don't share the socket with our children */
... ... @@ -614,7 +616,7 @@ int net_connect(H3270 *session, const char *host, char *portname, Boolean ls, Bo
614 616  
615 617 /* init ssl */
616 618 #if defined(HAVE_LIBSSL)
617   - last_ssl_error = 0;
  619 + session->last_ssl_error = 0;
618 620 if (session->ssl_host)
619 621 ssl_init();
620 622 #endif
... ... @@ -622,10 +624,23 @@ int net_connect(H3270 *session, const char *host, char *portname, Boolean ls, Bo
622 624 /* connect */
623 625 status_connecting(session,1);
624 626  
  627 + if(connect_sock(session, session->sock, &haddr.sa,ha_len) == 0)
  628 + {
  629 + trace_dsn("Connected.\n");
  630 + net_connected(session);
  631 + }
  632 + else
  633 + {
  634 + popup_a_sockerr(session, N_( "Can't connect to %s:%d" ),session->hostname, session->current_port);
  635 + close_fail;
  636 + }
  637 +
  638 +/*
625 639 switch(connect_sock(session, session->sock, &haddr.sa,ha_len))
626 640 {
627 641 case 0: // Connected
628 642 trace_dsn("Connected.\n");
  643 +
629 644 if(non_blocking(False) < 0)
630 645 close_fail;
631 646 net_connected(session);
... ... @@ -645,40 +660,19 @@ int net_connect(H3270 *session, const char *host, char *portname, Boolean ls, Bo
645 660 close_fail;
646 661  
647 662 }
648   -
649   -/*
650   - if (connect(session->sock, &haddr.sa, ha_len) == -1)
651   - {
652   - if (socket_errno() == SE_EWOULDBLOCK
653   -#if defined(SE_EINPROGRESS)
654   - || socket_errno() == SE_EINPROGRESS
655   -#endif
656   - ) {
657   - trace_dsn("Connection pending.\n");
658   - *pending = True;
659   -#if !defined(_WIN32)
660   - output_id = AddOutput(session->sock, session, output_possible);
661   -#endif
662   - } else {
663   - popup_a_sockerr(session, N_( "Can't connect to %s:%d" ),session->hostname, session->current_port);
664   - close_fail;
665   - }
666   - } else {
667   - if (non_blocking(False) < 0)
668   - close_fail;
669   - net_connected(session);
670   - }
671   - */
  663 +*/
672 664  
673 665 /* set up temporary termtype */
674   - if (appres.termname == CN && session->std_ds_host) {
  666 + if (appres.termname == CN && session->std_ds_host)
  667 + {
675 668 (void) sprintf(ttype_tmpval, "IBM-327%c-%d",
676 669 appres.m3279 ? '9' : '8', session->model_num);
677 670 session->termtype = ttype_tmpval;
678 671 }
679 672  
680 673 /* all done */
681   -#if defined(_WIN32) /*[*/
  674 +/*
  675 +#if defined(_WIN32)
682 676 if (session->sock_handle == NULL) {
683 677 char ename[256];
684 678  
... ... @@ -708,9 +702,12 @@ int net_connect(H3270 *session, const char *host, char *portname, Boolean ls, Bo
708 702 }
709 703  
710 704 return (int) session->sock_handle;
711   -#else /*][*/
  705 +#else
  706 + return session->sock;
  707 +#endif
  708 +*/
  709 +
712 710 return session->sock;
713   -#endif /*]*/
714 711 }
715 712 #undef close_fail
716 713  
... ... @@ -791,12 +788,18 @@ static void net_connected(H3270 *session)
791 788 {
792 789 trace_dsn("Can't set fd!\n");
793 790 }
  791 +
794 792 if (SSL_connect(ssl_con) != 1)
795 793 {
796   - /*
797   - * No need to trace the error, it was already
798   - * displayed.
799   - */
  794 + unsigned long e = ERR_get_error();
  795 + if(e != session->last_ssl_error)
  796 + {
  797 + popup_system_error(&h3270,_( "Connection failed error" ), _( "SSL negotiation failed" ), "%s", SSL_state_string_long(ssl_con));
  798 + session->last_ssl_error = e;
  799 + }
  800 +
  801 + trace_dsn("TLS/SSL tunneled connection failed with error %ld.",e);
  802 + trace("%s: SSL_connect failed with error %ld",__FUNCTION__,e);
800 803 host_disconnect(session,True);
801 804 return;
802 805 }
... ... @@ -859,15 +862,17 @@ static void net_connected(H3270 *session)
859 862 * appeared ready but recv() returned EWOULDBLOCK). Complete the
860 863 * connection-completion processing.
861 864 */
862   -static void
863   -connection_complete(void)
  865 +static void connection_complete(void)
864 866 {
865   -#if !defined(_WIN32) /*[*/
866   - if (non_blocking(False) < 0) {
  867 +/*
  868 +#if !defined(_WIN32)
  869 + if (non_blocking(False) < 0)
  870 + {
867 871 host_disconnect(&h3270,True);
868 872 return;
869 873 }
870   -#endif /*]*/
  874 +#endif
  875 +*/
871 876 host_connected(&h3270);
872 877 net_connected(&h3270);
873 878 }
... ... @@ -1008,7 +1013,8 @@ void net_input(H3270 *session)
1008 1013 return;
1009 1014 }
1010 1015 #if defined(HAVE_LIBSSL) /*[*/
1011   - if (ssl_con != NULL) {
  1016 + if (ssl_con != NULL)
  1017 + {
1012 1018 unsigned long e;
1013 1019 char err_buf[120];
1014 1020  
... ... @@ -1016,16 +1022,23 @@ void net_input(H3270 *session)
1016 1022 if (e != 0)
1017 1023 (void) ERR_error_string(e, err_buf);
1018 1024 else
1019   - strcpy(err_buf, "unknown error");
1020   - trace_dsn("RCVD SSL_read error %ld (%s)\n", e,
1021   - err_buf);
  1025 + strcpy(err_buf, _( "unknown error" ) );
  1026 +
  1027 + trace_dsn("RCVD SSL_read error %ld (%s)\n", e,err_buf);
  1028 +
  1029 + lib3270_popup_dialog( session,
  1030 + LIB3270_NOTIFY_CRITICAL,
  1031 + N_( "SSL Error" ),
  1032 + N_( "SSL Read error" ),
  1033 + "%s", err_buf);
1022 1034  
1023   - popup_an_error(NULL,"SSL_read:\n%s", err_buf);
1024 1035 host_disconnect(session,True);
1025 1036 return;
1026 1037 }
1027 1038 #endif /*]*/
1028   - if (HALF_CONNECTED && socket_errno() == SE_EAGAIN) {
  1039 +
  1040 + if (HALF_CONNECTED && socket_errno() == SE_EAGAIN)
  1041 + {
1029 1042 connection_complete();
1030 1043 return;
1031 1044 }
... ... @@ -1039,11 +1052,15 @@ void net_input(H3270 *session)
1039 1052 #endif
1040 1053 */
1041 1054 trace_dsn("RCVD socket error %d\n", errno);
1042   - if (HALF_CONNECTED) {
  1055 + if (HALF_CONNECTED)
  1056 + {
1043 1057 popup_a_sockerr(NULL, N_( "%s:%d" ),h3270.hostname, h3270.current_port);
1044   - } else if (socket_errno() != SE_ECONNRESET) {
  1058 + }
  1059 + else if (socket_errno() != SE_ECONNRESET)
  1060 + {
1045 1061 popup_a_sockerr(NULL, N_( "Socket read error" ) );
1046 1062 }
  1063 +
1047 1064 host_disconnect(session,True);
1048 1065 return;
1049 1066 } else if (nr == 0) {
... ... @@ -1057,11 +1074,13 @@ void net_input(H3270 *session)
1057 1074  
1058 1075 if (HALF_CONNECTED)
1059 1076 {
  1077 +/*
1060 1078 if (non_blocking(False) < 0)
1061 1079 {
1062 1080 host_disconnect(session,True);
1063 1081 return;
1064 1082 }
  1083 +*/
1065 1084 host_connected(session);
1066 1085 net_connected(session);
1067 1086 }
... ... @@ -1088,7 +1107,8 @@ void net_input(H3270 *session)
1088 1107 } else {
1089 1108 #endif
1090 1109 */
1091   - if (telnet_fsm(*cp)) {
  1110 + if (telnet_fsm(*cp))
  1111 + {
1092 1112 (void) ctlr_dbcs_postprocess();
1093 1113 host_disconnect(&h3270,True);
1094 1114 return;
... ... @@ -1950,19 +1970,11 @@ process_eor(void)
1950 1970 */
1951 1971 void net_exception(H3270 *session)
1952 1972 {
1953   -/*
1954   -#if defined(LOCAL_PROCESS)
1955   - if (local_process) {
1956   - trace_dsn("RCVD exception\n");
1957   - } else
1958   -#endif
1959   -*/
  1973 + trace_dsn("RCVD urgent data indication\n");
  1974 + if (!syncing)
1960 1975 {
1961   - trace_dsn("RCVD urgent data indication\n");
1962   - if (!syncing) {
1963   - syncing = 1;
1964   - x_except_off(session);
1965   - }
  1976 + syncing = 1;
  1977 + x_except_off(session);
1966 1978 }
1967 1979 }
1968 1980  
... ... @@ -3184,22 +3196,24 @@ net_snap_options(void)
3184 3196 /*
3185 3197 * Set blocking/non-blocking mode on the socket. On error, pops up an error
3186 3198 * message, but does not close the socket.
3187   - */
  3199 + */ /*
3188 3200 static int
3189 3201 non_blocking(Boolean on)
3190 3202 {
3191   -#if !defined(BLOCKING_CONNECT_ONLY) /*[*/
3192   -# if defined(FIONBIO) /*[*/
  3203 +#if !defined(BLOCKING_CONNECT_ONLY)
  3204 +# if defined(FIONBIO)
3193 3205 int i = on ? 1 : 0;
3194 3206  
3195   - if (SOCK_IOCTL(h3270.sock, FIONBIO, (int *) &i) < 0) {
  3207 + if (SOCK_IOCTL(h3270.sock, FIONBIO, (int *) &i) < 0)
  3208 + {
3196 3209 popup_a_sockerr(NULL, N_( "ioctl(%s)" ), "FIONBIO");
3197 3210 return -1;
3198 3211 }
3199   -# else /*][*/
  3212 +# else
3200 3213 int f;
3201 3214  
3202   - if ((f = fcntl(sock, F_GETFL, 0)) == -1) {
  3215 + if ((f = fcntl(sock, F_GETFL, 0)) == -1)
  3216 + {
3203 3217 popup_an_errno(NULL,errno, N_( "fcntl(%s)" ), "F_GETFL" );
3204 3218 return -1;
3205 3219 }
... ... @@ -3207,14 +3221,16 @@ non_blocking(Boolean on)
3207 3221 f |= O_NDELAY;
3208 3222 else
3209 3223 f &= ~O_NDELAY;
3210   - if (fcntl(sock, F_SETFL, f) < 0) {
  3224 + if (fcntl(sock, F_SETFL, f) < 0)
  3225 + {
3211 3226 popup_an_errno(NULL,errno, N_( "fcntl(%s)" ), "F_GETFL");
3212 3227 return -1;
3213 3228 }
3214   -# endif /*]*/
3215   -#endif /*]*/
  3229 +# endif
  3230 +#endif
3216 3231 return 0;
3217 3232 }
  3233 +*/
3218 3234  
3219 3235 #if defined(HAVE_LIBSSL) /*[*/
3220 3236  
... ... @@ -3281,8 +3297,6 @@ static void client_info_callback(INFO_CONST SSL *s, int where, int ret)
3281 3297 }
3282 3298 else if (ret < 0)
3283 3299 {
3284   - static int showing = 0;
3285   -
3286 3300 unsigned long e;
3287 3301 char err_buf[1024];
3288 3302  
... ... @@ -3292,9 +3306,9 @@ static void client_info_callback(INFO_CONST SSL *s, int where, int ret)
3292 3306  
3293 3307 if(e != 0)
3294 3308 {
3295   - if(e == last_ssl_error)
  3309 + if(e == h3270.last_ssl_error)
3296 3310 return;
3297   - last_ssl_error = e;
  3311 + h3270.last_ssl_error = e;
3298 3312 (void) ERR_error_string_n(e, err_buf, 1023);
3299 3313 }
3300 3314 #if defined(_WIN32)
... ... @@ -3315,24 +3329,14 @@ static void client_info_callback(INFO_CONST SSL *s, int where, int ret)
3315 3329  
3316 3330 trace_dsn("SSL Connect error in %s\nState: %s\nAlert: %s\n",err_buf,SSL_state_string_long(s),SSL_alert_type_string_long(ret));
3317 3331  
3318   - if(showing)
3319   - {
3320   - Log("SSL Connect error message %d discarded: \"%s\" state=%s alert=%s",showing++,err_buf,SSL_state_string_long(s),SSL_alert_type_string_long(ret));
3321   - }
3322   - else
3323   - {
3324   - showing++;
3325   - show_3270_popup_dialog( &h3270, // H3270 *session,
3326   - PW3270_DIALOG_CRITICAL, // PW3270_DIALOG type,
3327   - _( "SSL Connect error" ), // Title
3328   - err_buf, // Message
3329   - _( "<b>Connection state:</b> %s\n<b>Alert message:</b> %s" ),
3330   - SSL_state_string_long(s),
3331   - SSL_alert_type_string_long(ret));
3332   - showing = 0;
3333   - }
  3332 + show_3270_popup_dialog( &h3270, // H3270 *session,
  3333 + PW3270_DIALOG_CRITICAL, // PW3270_DIALOG type,
  3334 + _( "SSL Connect error" ), // Title
  3335 + err_buf, // Message
  3336 + _( "<b>Connection state:</b> %s\n<b>Alert message:</b> %s" ),
  3337 + SSL_state_string_long(s),
  3338 + SSL_alert_type_string_long(ret));
3334 3339  
3335   -// popup_system_error(_( "SSL Connect error" ), SSL_state_string_long(s), err_buf);
3336 3340  
3337 3341 }
3338 3342 }
... ... @@ -3372,21 +3376,21 @@ continue_tls(unsigned char *sbbuf, int len)
3372 3376 trace_dsn("Can't set fd!\n");
3373 3377 }
3374 3378  
3375   -#if defined(_WIN32) /*[*/
3376   - /* Make the socket blocking for SSL. */
3377   - (void) WSAEventSelect(h3270.sock, h3270.sock_handle, 0);
3378   - (void) non_blocking(False);
3379   -#endif /*]*/
  3379 +//#if defined(_WIN32)
  3380 +// /* Make the socket blocking for SSL. */
  3381 +// (void) WSAEventSelect(h3270.sock, h3270.sock_handle, 0);
  3382 +// (void) non_blocking(False);
  3383 +//#endif
3380 3384  
3381 3385 rv = SSL_connect(ssl_con);
3382 3386  
3383   -#if defined(_WIN32) /*[*/
3384   - /* Make the socket non-blocking again for event processing. */
3385   - (void) WSAEventSelect(h3270.sock, h3270.sock_handle, FD_READ | FD_CONNECT | FD_CLOSE);
3386   -#endif /*]*/
  3387 +//#if defined(_WIN32)
  3388 +// // Make the socket non-blocking again for event processing
  3389 +// (void) WSAEventSelect(h3270.sock, h3270.sock_handle, FD_READ | FD_CONNECT | FD_CLOSE);
  3390 +//#endif
3387 3391  
3388   - if (rv != 1) {
3389   - /* Error already displayed. */
  3392 + if (rv != 1)
  3393 + {
3390 3394 trace_dsn("continue_tls: SSL_connect failed\n");
3391 3395 net_disconnect();
3392 3396 return;
... ...
xio.c
... ... @@ -66,6 +66,8 @@ void x_add_input(H3270 *h,int net_sock)
66 66 */
67 67 void x_except_off(H3270 *h)
68 68 {
  69 + CHECK_SESSION_HANDLE(h);
  70 +
69 71 if(h->excepting)
70 72 {
71 73 RemoveInput(h->ns_exception_id);
... ...