Commit e5fc82f478434fcada6a2f9c0774f826fb4f9788

Authored by perry.werneck@gmail.com
1 parent a4aa3906

Melhorando tratamento do indicador de SSL

src/include/lib3270.h
... ... @@ -138,7 +138,7 @@
138 138 {
139 139 LIB3270_FLAG_BOXSOLID, /**< System available */
140 140 LIB3270_FLAG_UNDERA, /**< Control Unit STATUS */
141   - LIB3270_FLAG_SECURE, /**< Security status */
  141 +// LIB3270_FLAG_SECURE, /**< Security status */
142 142 LIB3270_FLAG_TYPEAHEAD,
143 143 LIB3270_FLAG_PRINTER,
144 144 LIB3270_FLAG_REVERSE,
... ... @@ -213,6 +213,20 @@
213 213  
214 214  
215 215 /**
  216 + * SSL state
  217 + *
  218 + */
  219 + typedef enum lib3270_ssl_state
  220 + {
  221 + LIB3270_SSL_UNSECURE, /**< No secure connection */
  222 + LIB3270_SSL_SECURE, /**< Connection secure */
  223 + LIB3270_SSL_NEGOTIATING, /**< Negotiating SSL */
  224 + LIB3270_SSL_UNDEFINED /**< Undefined */
  225 + } LIB3270_SSL_STATE;
  226 +
  227 + #define LIB3270_SSL_FAILED LIB3270_SSL_UNSECURE
  228 +
  229 + /**
216 230 * Notification message types.
217 231 *
218 232 */
... ... @@ -611,6 +625,9 @@
611 625 LIB3270_EXPORT int lib3270_in_tn3270e(H3270 *h);
612 626 LIB3270_EXPORT int lib3270_in_e(H3270 *h);
613 627  
  628 + LIB3270_EXPORT LIB3270_SSL_STATE lib3270_get_secure(H3270 *session);
  629 +
  630 +
614 631 /**
615 632 * Call non gui function.
616 633 *
... ...
src/include/lib3270/session.h
... ... @@ -71,7 +71,7 @@
71 71 unsigned short sz; /**< Struct size */
72 72  
73 73 // Connection info
74   - int secure_connection;
  74 +// int secure_connection;
75 75 int sock; /**< Network socket */
76 76 int net_sock;
77 77 LIB3270_CSTATE cstate; /**< Connection state */
... ... @@ -81,6 +81,8 @@
81 81 int selected : 1; /**< Has selected region? */
82 82 int rectsel : 1; /**< Selected region is a rectangle ? */
83 83  
  84 + LIB3270_SSL_STATE secure;
  85 +
84 86 struct lib3270_toggle toggle[LIB3270_TOGGLE_COUNT];
85 87  
86 88 // Network & Termtype
... ... @@ -177,6 +179,7 @@
177 179 void (*update_connect)(H3270 *session, unsigned char connected);
178 180 void (*update_model)(H3270 *session, const char *name, int model, int rows, int cols);
179 181 void (*update_selection)(H3270 *session, int start, int end);
  182 + void (*update_ssl)(H3270 *session, LIB3270_SSL_STATE state);
180 183  
181 184 void (*set_timer)(H3270 *session, unsigned char on);
182 185 void (*erase)(H3270 *session);
... ...
src/lib3270/api.h
... ... @@ -157,7 +157,7 @@
157 157  
158 158 #define OIA_FLAG_BOXSOLID LIB3270_FLAG_BOXSOLID
159 159 #define OIA_FLAG_UNDERA LIB3270_FLAG_UNDERA
160   - #define OIA_FLAG_SECURE LIB3270_FLAG_SECURE
  160 +// #define OIA_FLAG_SECURE LIB3270_FLAG_SECURE
161 161 #define OIA_FLAG_TYPEAHEAD LIB3270_FLAG_TYPEAHEAD
162 162 #define OIA_FLAG_PRINTER LIB3270_FLAG_PRINTER
163 163 #define OIA_FLAG_REVERSE LIB3270_FLAG_REVERSE
... ... @@ -356,7 +356,7 @@
356 356 LOCAL_EXTERN void Input_String(const unsigned char *str);
357 357 LOCAL_EXTERN void screen_size(int *rows, int *cols);
358 358  
359   - #define query_secure_connection(h) lib3270_get_ssl_state(h)
  359 +// #define query_secure_connection(h) lib3270_get_ssl_state(h)
360 360 #define lib3270_paste_string(str) lib3270_set_string(NULL,str)
361 361 #define get_3270_terminal_size(h,r,c) lib3270_get_screen_size(h,r,c)
362 362  
... ...
src/lib3270/init.c
... ... @@ -118,6 +118,10 @@ static void message(H3270 *session, LIB3270_NOTIFY id , const char *title, const
118 118 lib3270_write_log(session,"%s",text);
119 119 }
120 120  
  121 +static void update_ssl(H3270 *session, LIB3270_SSL_STATE state)
  122 +{
  123 +}
  124 +
121 125 static void lib3270_session_init(H3270 *hSession, const char *model)
122 126 {
123 127 int ovc, ovr;
... ... @@ -144,6 +148,7 @@ static void lib3270_session_init(H3270 *hSession, const char *model)
144 148 hSession->update_selection = update_selection;
145 149 hSession->cursor = set_cursor;
146 150 hSession->message = message;
  151 + hSession->update_ssl = update_ssl;
147 152  
148 153 hSession->sock = -1;
149 154 hSession->model_num = -1;
... ...
src/lib3270/screen.c
... ... @@ -546,15 +546,19 @@ static void status_connect(H3270 *session, int connected, void *dunno)
546 546 else
547 547 id = LIB3270_STATUS_CONNECTED;
548 548  
549   -#if defined(HAVE_LIBSSL) /*[*/
  549 +/*
  550 +#if defined(HAVE_LIBSSL)
550 551 set_status(session,OIA_FLAG_SECURE,session->secure_connection);
551   -#endif /*]*/
  552 +#endif
  553 +*/
552 554  
553 555 }
554 556 else
555 557 {
556 558 set_status(session,OIA_FLAG_BOXSOLID,False);
  559 +/*
557 560 set_status(session,OIA_FLAG_SECURE,False);
  561 +*/
558 562  
559 563 id = LIB3270_STATUS_DISCONNECTED;
560 564 }
... ...
src/lib3270/telnet.c
... ... @@ -351,8 +351,19 @@ static void output_possible(H3270 *session);
351 351 #endif /*]*/
352 352  
353 353  
  354 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  355 +
  356 +void set_ssl_state(H3270 *session, LIB3270_SSL_STATE state)
  357 +{
  358 + if(state == session->secure)
  359 + return;
  360 +
  361 + trace_dsn("SSL state changes to %d",(int) state);
  362 + trace("SSL state changes to %d",(int) state);
  363 +
  364 + session->update_ssl(session,session->secure = state);
  365 +}
354 366  
355   -
356 367 #if defined(_WIN32) /*[*/
357 368 void sockstart(H3270 *session)
358 369 {
... ... @@ -477,6 +488,8 @@ int net_connect(H3270 *session, const char *host, char *portname, Boolean ls, Bo
477 488  
478 489 #define close_fail { (void) SOCK_CLOSE(session->sock); session->sock = -1; return -1; }
479 490  
  491 + set_ssl_state(session,LIB3270_SSL_UNSECURE);
  492 +
480 493 #if defined(_WIN32)
481 494 sockstart(session);
482 495 #endif
... ... @@ -763,44 +776,49 @@ static void net_connected(H3270 *session)
763 776  
764 777 #if defined(HAVE_LIBSSL) /*[*/
765 778 /* Set up SSL. */
766   - if(session->ssl_host && !session->secure_connection)
  779 + if(session->ssl_con && session->secure == LIB3270_SSL_UNDEFINED)
767 780 {
768 781 int rc;
769 782  
  783 + set_ssl_state(session,LIB3270_SSL_NEGOTIATING);
  784 +
770 785 if (SSL_set_fd(session->ssl_con, session->sock) != 1)
771 786 {
772 787 trace_dsn("Can't set fd!\n");
773 788 popup_system_error(&h3270,_( "Connection failed" ), _( "Can't set SSL socket file descriptor" ), "%s", SSL_state_string_long(session->ssl_con));
  789 + set_ssl_state(session,LIB3270_SSL_UNSECURE);
774 790 }
  791 + else
  792 + {
  793 + non_blocking(False);
  794 + rc = SSL_connect(session->ssl_con);
775 795  
776   - non_blocking(False);
777   - rc = SSL_connect(session->ssl_con);
  796 + if(rc != 1)
  797 + {
  798 + unsigned long e = ERR_get_error();
  799 + const char * state = SSL_state_string_long(session->ssl_con);
778 800  
779   - if(rc != 1)
780   - {
781   - unsigned long e = ERR_get_error();
782   - const char * state = SSL_state_string_long(session->ssl_con);
  801 + trace_dsn("TLS/SSL tunneled connection failed with error %ld, rc=%d and state=%s",e,rc,state);
783 802  
784   - trace_dsn("TLS/SSL tunneled connection failed with error %ld, rc=%d and state=%s",e,rc,state);
  803 + host_disconnect(session,True);
785 804  
786   - host_disconnect(session,True);
  805 + if(e != session->last_ssl_error)
  806 + {
  807 + session->message( &h3270,
  808 + LIB3270_NOTIFY_ERROR,
  809 + _( "Connection failed" ),
  810 + _( "SSL negotiation failed" ),
  811 + state);
  812 + session->last_ssl_error = e;
  813 + }
  814 + return;
787 815  
788   - if(e != session->last_ssl_error)
789   - {
790   - session->message( &h3270,
791   - LIB3270_NOTIFY_ERROR,
792   - _( "Connection failed" ),
793   - _( "SSL negotiation failed" ),
794   - state);
795   - session->last_ssl_error = e;
796 816 }
797   - return;
798   -
  817 + non_blocking(True);
799 818 }
800   - non_blocking(True);
801 819  
802   - session->secure_connection = True;
803   - trace_dsn("TLS/SSL tunneled connection complete. Connection is now secure.\n");
  820 +// session->secure_connection = True;
  821 +// trace_dsn("TLS/SSL tunneled connection complete. Connection is now secure.\n");
804 822  
805 823 /* Tell everyone else again. */
806 824 host_connected(session);
... ... @@ -897,18 +915,22 @@ static void output_possible(H3270 *session)
897 915 */
898 916 void net_disconnect(void)
899 917 {
900   -#if defined(HAVE_LIBSSL) /*[*/
  918 +#if defined(HAVE_LIBSSL)
901 919 if (h3270.ssl_con != NULL)
902 920 {
903 921 SSL_shutdown(h3270.ssl_con);
904 922 SSL_free(h3270.ssl_con);
905 923 h3270.ssl_con = NULL;
906 924 }
907   - h3270.secure_connection = False;
908   -#endif /*]*/
  925 +#endif
  926 +
  927 + set_ssl_state(&h3270,LIB3270_SSL_UNSECURE);
  928 +
909 929 if (CONNECTED)
910 930 (void) shutdown(h3270.sock, 2);
  931 +
911 932 (void) SOCK_CLOSE(h3270.sock);
  933 +
912 934 h3270.sock = -1;
913 935 trace_dsn("SENT disconnect\n");
914 936  
... ... @@ -3233,6 +3255,8 @@ static void ssl_init(H3270 *session)
3233 3255 {
3234 3256 static SSL_CTX *ssl_ctx = NULL;
3235 3257  
  3258 + set_ssl_state(session,LIB3270_SSL_UNDEFINED);
  3259 +
3236 3260 if(ssl_ctx == NULL)
3237 3261 {
3238 3262 lib3270_write_log(session,"%s","Initializing SSL context");
... ... @@ -3293,6 +3317,9 @@ static void client_info_callback(INFO_CONST SSL *s, int where, int ret)
3293 3317 break;
3294 3318  
3295 3319 case SSL_CB_CONNECT_EXIT:
  3320 +
  3321 + trace("%s: SSL_CB_CONNECT_EXIT",__FUNCTION__);
  3322 +
3296 3323 if (ret == 0)
3297 3324 {
3298 3325 trace_dsn("SSL_connect: failed in %s\n",SSL_state_string_long(s));
... ... @@ -3349,6 +3376,15 @@ static void client_info_callback(INFO_CONST SSL *s, int where, int ret)
3349 3376  
3350 3377 if(where & SSL_CB_ALERT)
3351 3378 lib3270_write_log(NULL,"SSL","ALERT: %s",SSL_alert_type_string_long(ret));
  3379 +
  3380 + if(where & SSL_CB_HANDSHAKE_DONE)
  3381 + {
  3382 + trace("%s: SSL_CB_HANDSHAKE_DONE state=%04x",__FUNCTION__,SSL_state(s));
  3383 + if(SSL_state(s) == 0x03)
  3384 + set_ssl_state(&h3270,LIB3270_SSL_SECURE);
  3385 + else
  3386 + set_ssl_state(&h3270,LIB3270_SSL_UNSECURE);
  3387 + }
3352 3388 }
3353 3389  
3354 3390 /* Process a STARTTLS subnegotiation. */
... ... @@ -3406,10 +3442,10 @@ static void continue_tls(unsigned char *sbbuf, int len)
3406 3442 return;
3407 3443 }
3408 3444  
3409   - h3270.secure_connection = True;
  3445 +// h3270.secure_connection = True;
3410 3446  
3411 3447 /* Success. */
3412   - trace_dsn("TLS/SSL negotiated connection complete. Connection is now secure.\n");
  3448 +// trace_dsn("TLS/SSL negotiated connection complete. Connection is now secure.\n");
3413 3449  
3414 3450 /* Tell the world that we are (still) connected, now in secure mode. */
3415 3451 host_connected(&h3270);
... ... @@ -3455,6 +3491,13 @@ net_proxy_port(void)
3455 3491 return NULL;
3456 3492 }
3457 3493  
  3494 +LIB3270_EXPORT LIB3270_SSL_STATE lib3270_get_secure(H3270 *session)
  3495 +{
  3496 + CHECK_SESSION_HANDLE(session);
  3497 + return session->secure;
  3498 +}
  3499 +
  3500 +/*
3458 3501 LIB3270_EXPORT int lib3270_get_ssl_state(H3270 *h)
3459 3502 {
3460 3503 CHECK_SESSION_HANDLE(h);
... ... @@ -3465,6 +3508,7 @@ LIB3270_EXPORT int lib3270_get_ssl_state(H3270 *h)
3465 3508 return 0;
3466 3509 #endif
3467 3510 }
  3511 +*/
3468 3512  
3469 3513 /*
3470 3514 int Get3270Socket(void)
... ...
src/pw3270/v3270/oia.c
... ... @@ -306,18 +306,10 @@ void v3270_draw_ssl_status(cairo_t *cr, H3270 *host, struct v3270_metrics *metri
306 306 {
307 307 cairo_surface_t * icon;
308 308 double sz = rect->width < rect->height ? rect->width : rect->height;
309   - int idx = lib3270_get_ssl_state(host) ? 1 : 0;
310   -
311   - static const struct
312   - {
313   - unsigned short width;
314   - unsigned short height;
315   - unsigned char * bits;
316   - } bitmap[] =
317   - {
318   - { unlocked_width, unlocked_height, unlocked_bits },
319   - { locked_width, locked_height, locked_bits },
320   - };
  309 + int idx = 0; // lib3270_get_ssl_state(host) ? 1 : 0;
  310 + unsigned short width;
  311 + unsigned short height;
  312 + unsigned char * bits;
321 313  
322 314 #ifdef DEBUG
323 315 cairo_set_source_rgb(cr,0.1,0.1,0.1);
... ... @@ -330,15 +322,42 @@ void v3270_draw_ssl_status(cairo_t *cr, H3270 *host, struct v3270_metrics *metri
330 322 cairo_rectangle(cr, 0, 0, rect->width, rect->height);
331 323 cairo_fill(cr);
332 324  
333   - gdk_cairo_set_source_color(cr,color+V3270_COLOR_OIA_FOREGROUND);
  325 + switch(lib3270_get_secure(host))
  326 + {
  327 + case LIB3270_SSL_UNSECURE: /**< No secure connection */
  328 + gdk_cairo_set_source_color(cr,color+V3270_COLOR_OIA_FOREGROUND);
  329 + width = unlocked_width;
  330 + height = unlocked_height;
  331 + bits = (unsigned char *) unlocked_bits;
  332 + break;
  333 +
  334 + case LIB3270_SSL_SECURE: /**< Connection secure */
  335 + gdk_cairo_set_source_color(cr,color+V3270_COLOR_OIA_FOREGROUND);
  336 + width = locked_width;
  337 + height = locked_height;
  338 + bits = (unsigned char *) locked_bits;
  339 + break;
  340 +
  341 + case LIB3270_SSL_NEGOTIATING: /**< Negotiating SSL */
  342 + gdk_cairo_set_source_color(cr,color+V3270_COLOR_OIA_STATUS_WARNING);
  343 + width = locked_width;
  344 + height = locked_height;
  345 + bits = (unsigned char *) locked_bits;
  346 + break;
  347 +
  348 + default:
  349 + return;
  350 +
  351 + }
  352 +
334 353  
335   - icon = cairo_image_surface_create_for_data( (unsigned char *) bitmap[idx].bits,
  354 + icon = cairo_image_surface_create_for_data( bits,
336 355 CAIRO_FORMAT_A1,
337   - bitmap[idx].width,bitmap[idx].height,
  356 + width,height,
338 357 cairo_format_stride_for_width(CAIRO_FORMAT_A1,locked_width));
339 358  
340   - cairo_scale(cr, sz / ((double) bitmap[idx].width),
341   - sz / ((double) bitmap[idx].height));
  359 + cairo_scale(cr, sz / ((double) width),
  360 + sz / ((double) height));
342 361  
343 362 cairo_mask_surface(cr,icon,(rect->width-sz)/2,(rect->height-sz)/2);
344 363  
... ... @@ -985,6 +1004,22 @@ void v3270_stop_timer(GtkWidget *widget)
985 1004  
986 1005 }
987 1006  
  1007 +void v3270_update_ssl(H3270 *session, LIB3270_SSL_STATE state)
  1008 +{
  1009 + v3270 * terminal = GTK_V3270(session->widget);
  1010 + cairo_t * cr;
  1011 + GdkRectangle * r;
  1012 +
  1013 + if(!terminal->surface)
  1014 + return;
  1015 +
  1016 + cr = set_update_region(terminal,&r,V3270_OIA_SSL);
  1017 + v3270_draw_ssl_status(cr,terminal->host,&terminal->metrics,terminal->color,r);
  1018 + gtk_widget_queue_draw_area(GTK_WIDGET(terminal),r->x,r->y,r->width,r->height);
  1019 + cairo_destroy(cr);
  1020 +
  1021 +}
  1022 +
988 1023 void v3270_update_oia(H3270 *session, LIB3270_FLAG id, unsigned char on)
989 1024 {
990 1025 cairo_t *cr;
... ... @@ -1011,12 +1046,14 @@ void v3270_update_oia(H3270 *session, LIB3270_FLAG id, unsigned char on)
1011 1046 cairo_destroy(cr);
1012 1047 break;
1013 1048  
  1049 +/*
1014 1050 case LIB3270_FLAG_SECURE:
1015 1051 cr = set_update_region(terminal,&r,V3270_OIA_SSL);
1016 1052 v3270_draw_ssl_status(cr,terminal->host,&terminal->metrics,terminal->color,r);
1017 1053 gtk_widget_queue_draw_area(GTK_WIDGET(terminal),r->x,r->y,r->width,r->height);
1018 1054 cairo_destroy(cr);
1019 1055 break;
  1056 +*/
1020 1057  
1021 1058 case LIB3270_FLAG_TYPEAHEAD:
1022 1059 update_text_field(terminal,on,V3270_OIA_TYPEAHEAD,"T");
... ...
src/pw3270/v3270/private.h
... ... @@ -224,6 +224,7 @@ void v3270_update_luname(GtkWidget *widget,const gchar *name);
224 224 void v3270_update_message(v3270 *widget, LIB3270_MESSAGE id);
225 225 void v3270_update_cursor(H3270 *session, unsigned short row, unsigned short col, unsigned char c, unsigned short attr);
226 226 void v3270_update_oia(H3270 *session, LIB3270_FLAG id, unsigned char on);
  227 +void v3270_update_ssl(H3270 *session, LIB3270_SSL_STATE state);
227 228  
228 229 // Keyboard & Mouse
229 230 gboolean v3270_key_press_event(GtkWidget *widget, GdkEventKey *event);
... ...
src/pw3270/v3270/widget.c
... ... @@ -769,6 +769,7 @@ static void v3270_init(v3270 *widget)
769 769 widget->host->changed = changed;
770 770 widget->host->ctlr_done = ctlr_done;
771 771 widget->host->message = message;
  772 + widget->host->update_ssl = v3270_update_ssl;
772 773  
773 774 // Setup input method
774 775 widget->input_method = gtk_im_multicontext_new();
... ...