diff options
author | Giovanni Panozzo <giovanni@panozzo.it> | 2018-09-21 17:20:49 +0300 |
---|---|---|
committer | Giovanni Panozzo <giovanni@panozzo.it> | 2018-12-04 23:27:06 +0300 |
commit | 363b68017ae4ddafaa77c11ec2c2c846358895a2 (patch) | |
tree | 60662e59c708cf3a7edff51d61af7d4368038ffa /src/remmina_protocol_widget.c | |
parent | a131a9c48d7d276b7d3f98508c3770e12ee34bf8 (diff) |
rcw_preopen complete
Diffstat (limited to 'src/remmina_protocol_widget.c')
-rw-r--r-- | src/remmina_protocol_widget.c | 473 |
1 files changed, 332 insertions, 141 deletions
diff --git a/src/remmina_protocol_widget.c b/src/remmina_protocol_widget.c index c694c13fc..a4e5f5b3d 100644 --- a/src/remmina_protocol_widget.c +++ b/src/remmina_protocol_widget.c @@ -77,6 +77,9 @@ struct _RemminaProtocolWidgetPriv { gint profile_remote_width; gint profile_remote_height; + RemminaMessagePanel *connect_message_panel; + RemminaMessagePanel *auth_message_panel; + /* Data saved from the last message_panel when the user confirm */ gchar *username; gchar *password; @@ -92,6 +95,13 @@ struct _RemminaProtocolWidgetPriv { }; +enum panel_type { + RPWDT_AUTHUSERPWD, + RPWDT_AUTHPWD, + RPWDT_QUESTIONYESNO, + RPWDT_AUTHX509 +}; + G_DEFINE_TYPE(RemminaProtocolWidget, remmina_protocol_widget, GTK_TYPE_EVENT_BOX) enum { @@ -134,7 +144,6 @@ static void remmina_protocol_widget_class_init(RemminaProtocolWidgetClass *klass static void remmina_protocol_widget_destroy(RemminaProtocolWidget* gp, gpointer data) { TRACE_CALL(__func__); - remmina_connection_object_hide_message_panel(gp->cnnobj); g_free(gp->priv->username); gp->priv->username = NULL; @@ -170,7 +179,7 @@ static void remmina_protocol_widget_destroy(RemminaProtocolWidget* gp, gpointer gp->priv = NULL; } -static void remmina_protocol_widget_connect(RemminaProtocolWidget* gp, gpointer data) +static void remmina_protocol_widget_on_connected(RemminaProtocolWidget* gp, gpointer data) { TRACE_CALL(__func__); #ifdef HAVE_LIBSSH @@ -178,13 +187,13 @@ static void remmina_protocol_widget_connect(RemminaProtocolWidget* gp, gpointer remmina_ssh_tunnel_cancel_accept(gp->priv->ssh_tunnel); } #endif - remmina_connection_object_hide_message_panel(gp->cnnobj); + remmina_connection_object_destroy_message_panel(gp->cnnobj, gp->priv->connect_message_panel); + gp->priv->connect_message_panel = NULL; } -static void remmina_protocol_widget_disconnect(RemminaProtocolWidget* gp, gpointer data) +static void remmina_protocol_widget_on_disconnected(RemminaProtocolWidget* gp, gpointer data) { TRACE_CALL(__func__); - remmina_connection_object_hide_message_panel(gp->cnnobj); } void remmina_protocol_widget_grab_focus(RemminaProtocolWidget* gp) @@ -209,8 +218,8 @@ static void remmina_protocol_widget_init(RemminaProtocolWidget* gp) gp->priv = priv; g_signal_connect(G_OBJECT(gp), "destroy", G_CALLBACK(remmina_protocol_widget_destroy), NULL); - g_signal_connect(G_OBJECT(gp), "connect", G_CALLBACK(remmina_protocol_widget_connect), NULL); - g_signal_connect(G_OBJECT(gp), "disconnect", G_CALLBACK(remmina_protocol_widget_disconnect), NULL); + g_signal_connect(G_OBJECT(gp), "connect", G_CALLBACK(remmina_protocol_widget_on_connected), NULL); + g_signal_connect(G_OBJECT(gp), "disconnect", G_CALLBACK(remmina_protocol_widget_on_disconnected), NULL); } void remmina_protocol_widget_open_connection_real(gpointer data) @@ -267,6 +276,12 @@ void remmina_protocol_widget_open_connection_real(gpointer data) } } +static void cancel_open_connection_cb(void *cbdata, int btn) +{ + RemminaProtocolWidget *gp = (RemminaProtocolWidget*)cbdata; + remmina_protocol_widget_close_connection(gp); +} + void remmina_protocol_widget_open_connection(RemminaProtocolWidget* gp, RemminaFile* remminafile) { TRACE_CALL(__func__); @@ -280,17 +295,19 @@ void remmina_protocol_widget_open_connection(RemminaProtocolWidget* gp, RemminaF /* Exec precommand before everything else */ mp = remmina_message_panel_new(); - remmina_message_panel_setup_progress(mp, _("Executing external commands...")); + remmina_message_panel_setup_progress(mp, _("Executing external commands..."), NULL, NULL); remmina_connection_object_show_message_panel(gp->cnnobj, mp); remmina_ext_exec_new(remminafile, "precommand"); + remmina_connection_object_destroy_message_panel(gp->cnnobj, mp); name = remmina_file_get_string(remminafile, "name"); s = g_strdup_printf(_("Connecting to '%s'..."), (name ? name : "*")); mp = remmina_message_panel_new(); - remmina_message_panel_setup_progress(mp, s); + remmina_message_panel_setup_progress(mp, s, cancel_open_connection_cb, gp); g_free(s); + gp->priv->connect_message_panel = mp; remmina_connection_object_show_message_panel(gp->cnnobj, mp); remmina_protocol_widget_open_connection_real(gp); @@ -480,12 +497,6 @@ const RemminaProtocolFeature* remmina_protocol_widget_get_features(RemminaProtoc return gp->priv->features; } -const gchar* remmina_protocol_widget_get_domain(RemminaProtocolWidget* gp) -{ - TRACE_CALL(__func__); - return gp->priv->plugin->domain; -} - gboolean remmina_protocol_widget_query_feature_by_type(RemminaProtocolWidget* gp, RemminaProtocolFeatureType type) { TRACE_CALL(__func__); @@ -582,7 +593,52 @@ void remmina_protocol_widget_set_hostkey_func(RemminaProtocolWidget* gp, Remmina gp->priv->hostkey_func = func; } +RemminaMessagePanel* remmina_protocol_widget_mpprogress(RemminaConnectionObject* cnnobj, const gchar *msg, RemminaMessagePanelCallback response_callback, gpointer response_callback_data) +{ + RemminaMessagePanel *mp; + + if ( !remmina_masterthread_exec_is_main_thread() ) { + /* Allow the execution of this function from a non main thread */ + RemminaMTExecData *d; + d = (RemminaMTExecData*)g_malloc( sizeof(RemminaMTExecData) ); + d->func = FUNC_PROTOCOLWIDGET_MPPROGRESS; + d->p.protocolwidget_mpprogress.cnnobj = cnnobj; + d->p.protocolwidget_mpprogress.message = msg; + d->p.protocolwidget_mpprogress.response_callback = response_callback; + d->p.protocolwidget_mpprogress.response_callback_data = response_callback_data; + remmina_masterthread_exec_and_wait(d); + mp = d->p.protocolwidget_mpprogress.ret_mp; + g_free(d); + return mp; + } + + mp = remmina_message_panel_new(); + remmina_message_panel_setup_progress(mp, msg, response_callback, response_callback_data); + remmina_connection_object_show_message_panel(cnnobj, mp); + return mp; +} + +void remmina_protocol_widget_mpdestroy(RemminaConnectionObject *cnnobj, RemminaMessagePanel *mp) +{ + if ( !remmina_masterthread_exec_is_main_thread() ) { + /* Allow the execution of this function from a non main thread */ + RemminaMTExecData *d; + d = (RemminaMTExecData*)g_malloc( sizeof(RemminaMTExecData) ); + d->func = FUNC_PROTOCOLWIDGET_MPDESTROY; + d->p.protocolwidget_mpdestroy.cnnobj = cnnobj; + d->p.protocolwidget_mpdestroy.mp = mp; + remmina_masterthread_exec_and_wait(d); + g_free(d); + return; + } + remmina_connection_object_destroy_message_panel(cnnobj, mp); +} + #ifdef HAVE_LIBSSH +static void cancel_init_tunnel_cb(void *cbdata, int btn) +{ + printf("REMMINA: cancelling an opening tunnel is not implemented\n"); +} static gboolean remmina_protocol_widget_init_tunnel(RemminaProtocolWidget* gp) { TRACE_CALL(__func__); @@ -596,11 +652,9 @@ static gboolean remmina_protocol_widget_init_tunnel(RemminaProtocolWidget* gp) tunnel = remmina_ssh_tunnel_new_from_file(gp->priv->remmina_file); msg = g_strdup_printf(_("Connecting to SSH server %s..."), REMMINA_SSH(tunnel)->server); - mp = remmina_message_panel_new(); - remmina_message_panel_setup_progress(mp, msg); - g_free(msg); - remmina_connection_object_show_message_panel(gp->cnnobj, mp); + mp = remmina_protocol_widget_mpprogress(gp->cnnobj, msg, cancel_init_tunnel_cb, NULL); + g_free(msg); if (!remmina_ssh_init_session(REMMINA_SSH(tunnel))) { remmina_protocol_widget_set_error(gp, REMMINA_SSH(tunnel)->error); @@ -608,7 +662,7 @@ static gboolean remmina_protocol_widget_init_tunnel(RemminaProtocolWidget* gp) return FALSE; } - ret = remmina_ssh_auth_gui(REMMINA_SSH(tunnel), gp->cnnobj, gp->priv->remmina_file); + ret = remmina_ssh_auth_gui(REMMINA_SSH(tunnel), gp, gp->priv->remmina_file); if (ret <= 0) { if (ret == 0) { remmina_protocol_widget_set_error(gp, REMMINA_SSH(tunnel)->error); @@ -617,6 +671,8 @@ static gboolean remmina_protocol_widget_init_tunnel(RemminaProtocolWidget* gp) return FALSE; } + remmina_protocol_widget_mpdestroy(gp->cnnobj, mp); + gp->priv->ssh_tunnel = tunnel; } @@ -624,6 +680,15 @@ static gboolean remmina_protocol_widget_init_tunnel(RemminaProtocolWidget* gp) } #endif + +#ifdef HAVE_LIBSSH +static void cancel_start_direct_tunnel_cb(void *cbdata, int btn) +{ + printf("REMMINA: cancelling start_direct_tunnel is not implemented\n"); +} +#endif + + /** * Start an SSH tunnel if possible and return the host:port string. * @@ -635,7 +700,6 @@ gchar* remmina_protocol_widget_start_direct_tunnel(RemminaProtocolWidget* gp, gi gchar *host, *dest; gint port; gchar *msg; - RemminaMessagePanel *mp; server = remmina_file_get_string(gp->priv->remmina_file, "server"); @@ -651,6 +715,8 @@ gchar* remmina_protocol_widget_start_direct_tunnel(RemminaProtocolWidget* gp, gi } #ifdef HAVE_LIBSSH + RemminaMessagePanel *mp; + if (!remmina_file_get_int(gp->priv->remmina_file, "ssh_enabled", FALSE)) { dest = g_strdup_printf("[%s]:%i", host, port); g_free(host); @@ -669,10 +735,8 @@ gchar* remmina_protocol_widget_start_direct_tunnel(RemminaProtocolWidget* gp, gi } msg = g_strdup_printf(_("Connecting to %s through SSH tunnel..."), server); - mp = remmina_message_panel_new(); - remmina_message_panel_setup_progress(mp, msg); + mp = remmina_protocol_widget_mpprogress(gp->cnnobj, msg, cancel_start_direct_tunnel_cb, NULL); g_free(msg); - remmina_connection_object_show_message_panel(gp->cnnobj, mp); if (remmina_file_get_int(gp->priv->remmina_file, "ssh_loopback", FALSE)) { g_free(host); @@ -684,8 +748,10 @@ gchar* remmina_protocol_widget_start_direct_tunnel(RemminaProtocolWidget* gp, gi remmina_protocol_widget_set_error(gp, REMMINA_SSH(gp->priv->ssh_tunnel)->error); return NULL; } - g_free(host); + + remmina_protocol_widget_mpdestroy(gp->cnnobj, mp); + return g_strdup_printf("127.0.0.1:%i", remmina_pref.sshtunnel_port); #else @@ -697,6 +763,14 @@ gchar* remmina_protocol_widget_start_direct_tunnel(RemminaProtocolWidget* gp, gi #endif } +#ifdef HAVE_LIBSSH +static void cancel_start_reverse_tunnel_cb(void *cbdata, int btn) +{ + printf("REMMINA: cancelling start_reverse_tunnel is not implemented\n"); +} +#endif + + gboolean remmina_protocol_widget_start_reverse_tunnel(RemminaProtocolWidget* gp, gint local_port) { TRACE_CALL(__func__); @@ -713,15 +787,14 @@ gboolean remmina_protocol_widget_start_reverse_tunnel(RemminaProtocolWidget* gp, } msg = g_strdup_printf(_("Waiting for an incoming SSH tunnel at port %i..."), remmina_file_get_int(gp->priv->remmina_file, "listenport", 0)); - mp = remmina_message_panel_new(); - remmina_message_panel_setup_progress(mp, msg); + mp = remmina_protocol_widget_mpprogress(gp->cnnobj, msg, cancel_start_reverse_tunnel_cb, NULL); g_free(msg); - remmina_connection_object_show_message_panel(gp->cnnobj, mp); if (!remmina_ssh_tunnel_reverse(gp->priv->ssh_tunnel, remmina_file_get_int(gp->priv->remmina_file, "listenport", 0), local_port)) { remmina_protocol_widget_set_error(gp, REMMINA_SSH(gp->priv->ssh_tunnel)->error); return FALSE; } + remmina_protocol_widget_mpdestroy(gp->cnnobj, mp); #endif return TRUE; @@ -821,7 +894,12 @@ static gboolean remmina_protocol_widget_tunnel_disconnect_callback(RemminaSSHTun return TRUE; } #endif - +#ifdef HAVE_LIBSSH +static void cancel_connect_xport_cb(void *cbdata, int btn) +{ + printf("REMMINA: cancelling a xport connect is not implemented\n"); +} +#endif gboolean remmina_protocol_widget_start_xport_tunnel(RemminaProtocolWidget* gp, RemminaXPortTunnelInitFunc init_func) { TRACE_CALL(__func__); @@ -834,10 +912,8 @@ gboolean remmina_protocol_widget_start_xport_tunnel(RemminaProtocolWidget* gp, R if (!remmina_protocol_widget_init_tunnel(gp)) return FALSE; msg = g_strdup_printf(_("Connecting to %s through SSH tunnel..."), remmina_file_get_string(gp->priv->remmina_file, "server")); - mp = remmina_message_panel_new(); - remmina_message_panel_setup_progress(mp, msg); + mp = remmina_protocol_widget_mpprogress(gp->cnnobj, msg, cancel_connect_xport_cb, NULL); g_free(msg); - remmina_connection_object_show_message_panel(gp->cnnobj, mp); gp->priv->init_func = init_func; gp->priv->ssh_tunnel->init_func = remmina_protocol_widget_tunnel_init_callback; @@ -855,6 +931,8 @@ gboolean remmina_protocol_widget_start_xport_tunnel(RemminaProtocolWidget* gp, R return FALSE; } + remmina_protocol_widget_mpdestroy(gp->cnnobj, mp); + return TRUE; #else @@ -979,54 +1057,142 @@ RemminaFile* remmina_protocol_widget_get_file(RemminaProtocolWidget* gp) return gp->priv->remmina_file; } -gint remmina_protocol_widget_init_authpwd(RemminaProtocolWidget* gp, RemminaAuthpwdType authpwd_type, gboolean allow_password_saving) -{ - TRACE_CALL(__func__); - RemminaFile* remminafile = gp->priv->remmina_file; - gchar* s; - gint ret; - RemminaMessagePanel* mp; +struct remmina_protocol_widget_dialog_mt_data_t { + /* Input data */ + RemminaProtocolWidget *gp; + char *str1; + char *str2; + enum panel_type dtype; unsigned pflags; + /* Running status */ + pthread_mutex_t pt_mutex; + pthread_cond_t pt_cond; + /* Output/retval */ + int rcbutton; +}; - switch (authpwd_type) { - case REMMINA_AUTHPWD_TYPE_PROTOCOL: - s = g_strdup_printf(_("%s password"), remmina_file_get_string(remminafile, "protocol")); - break; - case REMMINA_AUTHPWD_TYPE_SSH_PWD: - s = g_strdup(_("SSH password")); - break; - case REMMINA_AUTHPWD_TYPE_SSH_PRIVKEY: - s = g_strdup(_("SSH private key passphrase")); - break; - default: - s = g_strdup(_("Password")); - break; +static void authuserpwd_mt_cb(void *user_data, int button) +{ + struct remmina_protocol_widget_dialog_mt_data_t *d = (struct remmina_protocol_widget_dialog_mt_data_t *)user_data; + d->rcbutton = button; + if (button == GTK_RESPONSE_OK) { + if (d->dtype == RPWDT_AUTHUSERPWD || d->dtype == RPWDT_AUTHPWD) { + d->gp->priv->password = remmina_message_panel_field_get_string(d->gp->priv->auth_message_panel, REMMINA_MESSAGE_PANEL_PASSWORD); + d->gp->priv->username = remmina_message_panel_field_get_string(d->gp->priv->auth_message_panel, REMMINA_MESSAGE_PANEL_USERNAME); + d->gp->priv->domain = remmina_message_panel_field_get_string(d->gp->priv->auth_message_panel, REMMINA_MESSAGE_PANEL_DOMAIN); + d->gp->priv->save_password = remmina_message_panel_field_get_switch_state(d->gp->priv->auth_message_panel, REMMINA_MESSAGE_PANEL_FLAG_SAVEPASSRORD); + } else if (d->dtype == RPWDT_AUTHX509) { + d->gp->priv->cacert = remmina_message_panel_field_get_filename(d->gp->priv->auth_message_panel, REMMINA_MESSAGE_PANEL_CACERTFILE); + d->gp->priv->cacrl = remmina_message_panel_field_get_filename(d->gp->priv->auth_message_panel, REMMINA_MESSAGE_PANEL_CACRLFILE); + d->gp->priv->clientcert = remmina_message_panel_field_get_filename(d->gp->priv->auth_message_panel, REMMINA_MESSAGE_PANEL_CLIENTCERTFILE); + d->gp->priv->clientkey = remmina_message_panel_field_get_filename(d->gp->priv->auth_message_panel, REMMINA_MESSAGE_PANEL_CLIENTKEYFILE); + } } + /* Hide and destroy message panel, we can do it now because we are on the main thread */ + remmina_connection_object_destroy_message_panel(d->gp->cnnobj, d->gp->priv->auth_message_panel); + + /* Awake the locked subthread */ + pthread_mutex_lock(&d->pt_mutex); + + pthread_cond_signal(&d->pt_cond); + pthread_mutex_unlock(&d->pt_mutex); +} + +static gboolean remmina_protocol_widget_dialog_mt_setup(gpointer user_data) +{ + struct remmina_protocol_widget_dialog_mt_data_t *d = (struct remmina_protocol_widget_dialog_mt_data_t *)user_data; + + RemminaFile* remminafile = d->gp->priv->remmina_file; + RemminaMessagePanel *mp; + const gchar *s; mp = remmina_message_panel_new(); - /* ToDo: init mp with username, password, and checkbox */ - pflags = 0; - if (!remminafile->prevent_saving && allow_password_saving) - pflags |= REMMINA_MESSAGE_PANEL_FLAG_SAVEPASSRORD; - remmina_message_panel_setup_auth(mp, s, pflags); - g_free(s); - remmina_connection_object_show_message_panel(gp->cnnobj, mp); - ret = remmina_message_panel_wait_user_answer(mp); - /* ToDo: take parameters from mp and save in gp->priv->password */ + if (d->dtype == RPWDT_AUTHUSERPWD) { + remmina_message_panel_setup_auth(mp, authuserpwd_mt_cb, d, _("Enter authentication credentials"), d->str1, d->pflags); + if ((s = remmina_file_get_string(remminafile, "username")) != NULL) + remmina_message_panel_field_set_string(mp, REMMINA_MESSAGE_PANEL_USERNAME, s); + if ((d->pflags & REMMINA_MESSAGE_PANEL_FLAG_DOMAIN) && (s = remmina_file_get_string(remminafile, "domain")) != NULL) + remmina_message_panel_field_set_string(mp, REMMINA_MESSAGE_PANEL_DOMAIN, s); + if ((s = remmina_file_get_string(remminafile, "password")) != NULL) + remmina_message_panel_field_set_string(mp, REMMINA_MESSAGE_PANEL_PASSWORD, s); + if (d->pflags & REMMINA_MESSAGE_PANEL_FLAG_SAVEPASSRORD) { + remmina_message_panel_field_set_switch(mp, REMMINA_MESSAGE_PANEL_FLAG_SAVEPASSRORD, FALSE); + } + } else if (d->dtype == RPWDT_AUTHPWD) { + remmina_message_panel_setup_auth(mp, authuserpwd_mt_cb, d, _("Enter authentication credentials"), d->str1, d->pflags); + if ((s = remmina_file_get_string(remminafile, "username")) != NULL) + remmina_message_panel_field_set_string(mp, REMMINA_MESSAGE_PANEL_USERNAME, s); + if ((s = remmina_file_get_string(remminafile, "password")) != NULL) + remmina_message_panel_field_set_string(mp, REMMINA_MESSAGE_PANEL_PASSWORD, s); + if (d->pflags & REMMINA_MESSAGE_PANEL_FLAG_SAVEPASSRORD) { + remmina_message_panel_field_set_switch(mp, REMMINA_MESSAGE_PANEL_FLAG_SAVEPASSRORD, FALSE); + } + } else if (d->dtype == RPWDT_QUESTIONYESNO) { + remmina_message_panel_setup_question(mp, d->str1, authuserpwd_mt_cb, d); + } else if (d->dtype == RPWDT_AUTHX509) { + remmina_message_panel_setup_auth_x509(mp, authuserpwd_mt_cb, d); + if ((s = remmina_file_get_string(remminafile, "cacert")) != NULL) + remmina_message_panel_field_set_filename(mp, REMMINA_MESSAGE_PANEL_CACERTFILE, s); + if ((s = remmina_file_get_string(remminafile, "cacrl")) != NULL) + remmina_message_panel_field_set_filename(mp, REMMINA_MESSAGE_PANEL_CACRLFILE, s); + if ((s = remmina_file_get_string(remminafile, "clientcert")) != NULL) + remmina_message_panel_field_set_filename(mp, REMMINA_MESSAGE_PANEL_CLIENTCERTFILE, s); + if ((s = remmina_file_get_string(remminafile, "clientkey")) != NULL) + remmina_message_panel_field_set_filename(mp, REMMINA_MESSAGE_PANEL_CLIENTKEYFILE, s); + } + + d->gp->priv->auth_message_panel = mp; + remmina_connection_object_show_message_panel(d->gp->cnnobj, mp); - g_clear_object(&mp); + return FALSE; +} - return ret; +static int remmina_protocol_widget_dialog(enum panel_type dtype, RemminaProtocolWidget* gp, unsigned pflags, const char *str1, const char *str2) +{ + + struct remmina_protocol_widget_dialog_mt_data_t *d = (struct remmina_protocol_widget_dialog_mt_data_t*)g_malloc( sizeof(struct remmina_protocol_widget_dialog_mt_data_t) ); + int rcbutton; + + if (remmina_masterthread_exec_is_main_thread()) { + printf("REMMINA warning. %s should not be called from the master thread.\n", __func__); + } + + d->gp = gp; + d->pflags = pflags; + d->dtype = dtype; + d->str1 = g_strdup(str1); + d->str2 = g_strdup(str2); + + // pthread_cleanup_push(ptcleanup, (void*)d); + pthread_cond_init(&d->pt_cond, NULL); + pthread_mutex_init(&d->pt_mutex, NULL); + g_idle_add(remmina_protocol_widget_dialog_mt_setup, d); + pthread_mutex_lock(&d->pt_mutex); + pthread_cond_wait(&d->pt_cond, &d->pt_mutex); + // pthread_cleanup_pop(0); + pthread_mutex_destroy(&d->pt_mutex); + pthread_cond_destroy(&d->pt_cond); + + rcbutton = d->rcbutton; + g_free(d->str1); + g_free(d->str2); + g_free(d); + + return rcbutton; + +} + +gint remmina_protocol_widget_panel_question_yesno(RemminaProtocolWidget* gp, const char *msg) +{ + return remmina_protocol_widget_dialog(RPWDT_QUESTIONYESNO, gp, 0, msg, NULL); } -gint remmina_protocol_widget_init_authuserpwd(RemminaProtocolWidget* gp, gboolean want_domain, gboolean allow_password_saving) +gint remmina_protocol_widget_panel_authuserpwd(RemminaProtocolWidget* gp, gboolean want_domain, gboolean allow_password_saving, const char *tips) { TRACE_CALL(__func__); - RemminaFile* remminafile = gp->priv->remmina_file; unsigned pflags; - RemminaMessagePanel* mp; - gint ret; + RemminaFile* remminafile = gp->priv->remmina_file; pflags = REMMINA_MESSAGE_PANEL_FLAG_USERNAME; if (remmina_file_get_filename(remminafile) != NULL && @@ -1035,106 +1201,120 @@ gint remmina_protocol_widget_init_authuserpwd(RemminaProtocolWidget* gp, gboolea if (want_domain) pflags |= REMMINA_MESSAGE_PANEL_FLAG_DOMAIN; - mp = remmina_message_panel_new(); - /* ToDo: init mp with username, password, domain (if want_domain) and checkbox */ - remmina_message_panel_setup_auth(mp, _("Enter authentication credentials"), pflags); - remmina_connection_object_show_message_panel(gp->cnnobj, mp); - ret = remmina_message_panel_wait_user_answer(mp); + return remmina_protocol_widget_dialog(RPWDT_AUTHUSERPWD, gp, pflags, _("Password"), tips); +} - /* ToDo: take parameters from mp and save in gp->priv->username/password/domain */ +gint remmina_protocol_widget_panel_authpwd(RemminaProtocolWidget* gp, RemminaAuthpwdType authpwd_type, gboolean allow_password_saving) +{ + TRACE_CALL(__func__); + unsigned pflags; + RemminaFile* remminafile = gp->priv->remmina_file; + char *password_prompt; + int rc; - g_clear_object(&mp); - return ret; + pflags = 0; + if (remmina_file_get_filename(remminafile) != NULL && + !remminafile->prevent_saving && allow_password_saving) + pflags |= REMMINA_MESSAGE_PANEL_FLAG_SAVEPASSRORD; + + switch (authpwd_type) { + case REMMINA_AUTHPWD_TYPE_PROTOCOL: + password_prompt = g_strdup_printf(_("%s password"), remmina_file_get_string(remminafile, "protocol")); + break; + case REMMINA_AUTHPWD_TYPE_SSH_PWD: + password_prompt = g_strdup(_("SSH password")); + break; + case REMMINA_AUTHPWD_TYPE_SSH_PRIVKEY: + password_prompt = g_strdup(_("SSH private key passphrase")); + break; + default: + password_prompt = g_strdup(_("Password")); + break; + } -/* Original code: + rc = remmina_protocol_widget_dialog(RPWDT_AUTHPWD, gp, pflags, password_prompt, NULL); + g_free(password_prompt); + return rc; - return remmina_init_dialog_authuserpwd( - REMMINA_INIT_DIALOG(gp->priv->init_dialog), - want_domain, - remmina_file_get_string(remminafile, "username"), - want_domain ? remmina_file_get_string(remminafile, "domain") : NULL, - (remmina_file_get_filename(remminafile) != NULL && - !remminafile->prevent_saving && allow_password_saving)); - * - */ } -gint remmina_protocol_widget_init_certificate(RemminaProtocolWidget* gp, const gchar* subject, const gchar* issuer, const gchar* fingerprint) +gint remmina_protocol_widget_panel_authx509(RemminaProtocolWidget* gp) { TRACE_CALL(__func__); - RemminaMessagePanel* mp; - gint ret; - mp = remmina_message_panel_new(); - remmina_message_panel_setup_cert(mp, subject, issuer, fingerprint, NULL); - remmina_connection_object_show_message_panel(gp->cnnobj, mp); - ret = remmina_message_panel_wait_user_answer(mp); + return remmina_protocol_widget_dialog(RPWDT_AUTHX509, gp, 0, NULL, NULL); +} + + +gint remmina_protocol_widget_panel_new_certificate(RemminaProtocolWidget* gp, const gchar* subject, const gchar* issuer, const gchar* fingerprint) +{ + TRACE_CALL(__func__); + gchar *s; + int rc; + + // For markup see https://developer.gnome.org/pygtk/stable/pango-markup-language.html + s = g_strdup_printf( + "<big>%s</big>\n\n%s %s\n%s %s\n%s %s\n\n<big>%s</big>", + _("Certificate Details:"), + _("Subject:"), subject, + _("Issuer:"), issuer, + _("Fingerprint:"), fingerprint, + _("Accept Certificate?")); + rc = remmina_protocol_widget_dialog(RPWDT_QUESTIONYESNO, gp, 0, s, NULL); + g_free(s); + + /* For compatibility with plugin API: the plugin expects GTK_RESPONSE_OK when user confirms new cert */ + return rc == GTK_RESPONSE_YES ? GTK_RESPONSE_OK : rc; - g_clear_object(&mp); - return ret; } -gint remmina_protocol_widget_changed_certificate(RemminaProtocolWidget *gp, const gchar* subject, const gchar* issuer, const gchar* new_fingerprint, const gchar* old_fingerprint) +gint remmina_protocol_widget_panel_changed_certificate(RemminaProtocolWidget *gp, const gchar* subject, const gchar* issuer, const gchar* new_fingerprint, const gchar* old_fingerprint) { TRACE_CALL(__func__); - RemminaMessagePanel* mp; - gint ret; + gchar *s; + int rc; - mp = remmina_message_panel_new(); - remmina_message_panel_setup_cert(mp, subject, issuer, new_fingerprint, old_fingerprint); - remmina_connection_object_show_message_panel(gp->cnnobj, mp); - ret = remmina_message_panel_wait_user_answer(mp); + // For markup see https://developer.gnome.org/pygtk/stable/pango-markup-language.html + s = g_strdup_printf( + "<big>%s</big>\n\n%s %s\n%s %s\n%s %s\n%s %s\n\n<big>%s</big>", + _("Certificate Changed! Details:"), + _("Subject:"), subject, + _("Issuer:"), issuer, + _("Old Fingerprint:"), old_fingerprint, + _("New Fingerprint:"), new_fingerprint, + _("Accept Changed Certificate?")); + rc = remmina_protocol_widget_dialog(RPWDT_QUESTIONYESNO, gp, 0, s, NULL); + g_free(s); - g_clear_object(&mp); - return ret; + /* For compatibility with plugin API: the plugin expects GTK_RESPONSE_OK when user confirms new cert */ + return rc == GTK_RESPONSE_YES ? GTK_RESPONSE_OK : rc; } -gchar* remmina_protocol_widget_init_get_username(RemminaProtocolWidget* gp) +gchar* remmina_protocol_widget_get_username(RemminaProtocolWidget* gp) { TRACE_CALL(__func__); return g_strdup(gp->priv->username); } -gchar* remmina_protocol_widget_init_get_password(RemminaProtocolWidget* gp) +gchar* remmina_protocol_widget_get_password(RemminaProtocolWidget* gp) { TRACE_CALL(__func__); return g_strdup(gp->priv->password); } -gchar* remmina_protocol_widget_init_get_domain(RemminaProtocolWidget* gp) +gchar* remmina_protocol_widget_get_domain(RemminaProtocolWidget* gp) { TRACE_CALL(__func__); return g_strdup(gp->priv->domain); } -gboolean remmina_protocol_widget_init_get_savepassword(RemminaProtocolWidget *gp) +gboolean remmina_protocol_widget_get_savepassword(RemminaProtocolWidget *gp) { TRACE_CALL(__func__); return gp->priv->save_password; } -gint remmina_protocol_widget_init_authx509(RemminaProtocolWidget* gp) -{ - TRACE_CALL(__func__); - RemminaFile* remminafile = gp->priv->remmina_file; - RemminaMessagePanel *mp; - gint ret; - - mp = remmina_message_panel_new(); - remmina_message_panel_setup_auth_x509(mp, - remmina_file_get_string(remminafile, "cacert"), remmina_file_get_string(remminafile, "cacrl"), - remmina_file_get_string(remminafile, "clientcert"), remmina_file_get_string(remminafile, "clientkey")); - - remmina_connection_object_show_message_panel(gp->cnnobj, mp); - ret = remmina_message_panel_wait_user_answer(mp); - - /* ToDo: save cacert, cacrl, clientcert, clientkey into apposite gp->priv-> strings */ - - g_clear_object(&mp); - return ret; -} - -gchar* remmina_protocol_widget_init_get_cacert(RemminaProtocolWidget* gp) +gchar* remmina_protocol_widget_get_cacert(RemminaProtocolWidget* gp) { TRACE_CALL(__func__); gchar* s; @@ -1143,7 +1323,7 @@ gchar* remmina_protocol_widget_init_get_cacert(RemminaProtocolWidget* gp) return (s && s[0] ? g_strdup(s) : NULL); } -gchar* remmina_protocol_widget_init_get_cacrl(RemminaProtocolWidget* gp) +gchar* remmina_protocol_widget_get_cacrl(RemminaProtocolWidget* gp) { TRACE_CALL(__func__); gchar* s; @@ -1152,7 +1332,7 @@ gchar* remmina_protocol_widget_init_get_cacrl(RemminaProtocolWidget* gp) return (s && s[0] ? g_strdup(s) : NULL); } -gchar* remmina_protocol_widget_init_get_clientcert(RemminaProtocolWidget* gp) +gchar* remmina_protocol_widget_get_clientcert(RemminaProtocolWidget* gp) { TRACE_CALL(__func__); gchar* s; @@ -1161,7 +1341,7 @@ gchar* remmina_protocol_widget_init_get_clientcert(RemminaProtocolWidget* gp) return (s && s[0] ? g_strdup(s) : NULL); } -gchar* remmina_protocol_widget_init_get_clientkey(RemminaProtocolWidget* gp) +gchar* remmina_protocol_widget_get_clientkey(RemminaProtocolWidget* gp) { TRACE_CALL(__func__); gchar* s; @@ -1170,7 +1350,7 @@ gchar* remmina_protocol_widget_init_get_clientkey(RemminaProtocolWidget* gp) return (s && s[0] ? g_strdup(s) : NULL); } -void remmina_protocol_widget_init_save_cred(RemminaProtocolWidget* gp) +void remmina_protocol_widget_save_cred(RemminaProtocolWidget* gp) { TRACE_CALL(__func__); @@ -1225,7 +1405,7 @@ void remmina_protocol_widget_init_save_cred(RemminaProtocolWidget* gp) } -void remmina_protocol_widget_init_show_listen(RemminaProtocolWidget* gp, gint port) +void remmina_protocol_widget_panel_show_listen(RemminaProtocolWidget* gp, gint port) { TRACE_CALL(__func__); RemminaMessagePanel *mp; @@ -1235,33 +1415,44 @@ void remmina_protocol_widget_init_show_listen(RemminaProtocolWidget* gp, gint po s = g_strdup_printf( _("Listening on port %i for an incoming %s connection..."), port, remmina_file_get_string(gp->priv->remmina_file, "protocol")); - remmina_message_panel_setup_progress(mp, s); + remmina_message_panel_setup_progress(mp, s, NULL, NULL); g_free(s); remmina_connection_object_show_message_panel(gp->cnnobj, mp); } -void remmina_protocol_widget_init_show_retry(RemminaProtocolWidget* gp) +void remmina_protocol_widget_panel_show_retry(RemminaProtocolWidget* gp) { TRACE_CALL(__func__); RemminaMessagePanel *mp; + if ( !remmina_masterthread_exec_is_main_thread() ) { + /* Allow the execution of this function from a non main thread */ + RemminaMTExecData *d; + d = (RemminaMTExecData*)g_malloc( sizeof(RemminaMTExecData) ); + d->func = FUNC_PROTOCOLWIDGET_MPSHOWRETRY; + d->p.protocolwidget_mpshowretry.gp = gp; + remmina_masterthread_exec_and_wait(d); + g_free(d); + return; + } + mp = remmina_message_panel_new(); - remmina_message_panel_setup_progress(mp, _("Authentication failed. Trying to reconnect...")); + remmina_message_panel_setup_progress(mp, _("Authentication failed. Trying to reconnect..."), NULL, NULL); remmina_connection_object_show_message_panel(gp->cnnobj, mp); } -void remmina_protocol_widget_init_show(RemminaProtocolWidget* gp) +void remmina_protocol_widget_panel_show(RemminaProtocolWidget* gp) { TRACE_CALL(__func__); - printf("REMMINA: error, function %s is not implemented\n", __func__); + printf("REMMINA: error, function %s is not implemented. Is left here only for plugin API compatibility.\n", __func__); } -void remmina_protocol_widget_init_hide(RemminaProtocolWidget* gp) +void remmina_protocol_widget_panel_hide(RemminaProtocolWidget* gp) { TRACE_CALL(__func__); - remmina_connection_object_hide_message_panel(gp->cnnobj); + printf("REMMINA: error, function %s is not implemented. Is left here only for plugin API compatibility.\n", __func__); } static void remmina_protocol_widget_chat_on_destroy(RemminaProtocolWidget* gp) |