From 1508c8e7b11fd8d62de91d45cda240e48a14424d Mon Sep 17 00:00:00 2001 From: Espen Tveit Date: Wed, 22 Jul 2020 23:40:48 +0000 Subject: Make local variables reusable (not prefixed with type). Format code using uncrustify. Add indication that URI may be used in remmina --help. Add some examples to man page. --- data/desktop/org.remmina.Remmina.desktop.in | 2 +- data/desktop/remmina-file-wrapper.in | 3 + src/remmina.1 | 5 +- src/remmina.c | 2 +- src/remmina_exec.c | 288 +++++++++++++--------------- 5 files changed, 139 insertions(+), 161 deletions(-) diff --git a/data/desktop/org.remmina.Remmina.desktop.in b/data/desktop/org.remmina.Remmina.desktop.in index acf31aa70..1f59aaf74 100644 --- a/data/desktop/org.remmina.Remmina.desktop.in +++ b/data/desktop/org.remmina.Remmina.desktop.in @@ -75,7 +75,7 @@ Type=Application Categories=GTK;GNOME;X-GNOME-NetworkSettings;Network; Keywords=remote desktop;rdp;vnc;nx;ssh;spice;xdmcp; StartupWMClass=@REMMINA_APP_ID@ -MimeType=x-scheme-handler/rdp;x-scheme-handler/spice;x-scheme-handler/vnc;x-scheme-handler/remmina;application/x-remmina; +MimeType=x-scheme-handler/rdp;x-scheme-handler/spice;x-scheme-handler/vnc;x-scheme-handler/ssh;x-scheme-handler/remmina;application/x-remmina; Actions=Kiosk;Profile;Tray;Quit; [Desktop Action Profile] diff --git a/data/desktop/remmina-file-wrapper.in b/data/desktop/remmina-file-wrapper.in index ccf6dbe56..a2033a157 100755 --- a/data/desktop/remmina-file-wrapper.in +++ b/data/desktop/remmina-file-wrapper.in @@ -42,6 +42,9 @@ case "$@" in *vnc:*) "$REMMINA" "${@}" ;; + *ssh:*) + "$REMMINA" "${@}" + ;; *remmina:*) "$REMMINA" "${@#remmina:\/\/}" ;; diff --git a/src/remmina.1 b/src/remmina.1 index 721333074..41f452fd2 100644 --- a/src/remmina.1 +++ b/src/remmina.1 @@ -47,7 +47,7 @@ Show help options .It Fl a Show about dialog .It Fl c, -connect\fR=\fIFILE\fR -Connect directly either to a desktop using options described in a file, or a supported URI (RDP, VNC or SPICE). The filetype can be ".remmina" or one supported by a plugin capable of importing files +Connect directly either to a desktop using options described in a file, or a supported URI (RDP, VNC, SSH or SPICE). The filetype can be ".remmina" or one supported by a plugin capable of importing files .It Fl e, -edit\fR=\fIFILE\fR Open and edit desktop connection using options described by file, file type can be either .remmina or one supported by a file import capable plugin .It Fl k, -kiosk\fR @@ -89,10 +89,11 @@ To connect using an exisitng connection profile use: To quick connect using a URI: .RS .nf -remmina -c rdp://username:password@server +remmina -c rdp://username@server remmina -c rdp://domain\\\\username@server remmina -c vnc://username@server remmina -c vnc://server?VncUsername=username +remmina -c ssh://user@server remmina -c spice://server To quick connect using a URI along with an encrypted password: diff --git a/src/remmina.c b/src/remmina.c index 0d0dc7d96..25563ee35 100644 --- a/src/remmina.c +++ b/src/remmina.c @@ -83,7 +83,7 @@ static GOptionEntry remmina_options[] = // TRANSLATORS: Shown in terminal. Do not use characters that may be not supported on a terminal { "about", 'a', 0, G_OPTION_ARG_NONE, NULL, N_("Show \'About\'"), NULL }, // TRANSLATORS: Shown in terminal. Do not use characters that may be not supported on a terminal - { "connect", 'c', 0, G_OPTION_ARG_FILENAME_ARRAY, NULL, N_("Connect either to a desktop described in a file (.remmina or a filetype supported by a plugin) or a supported URI (RDP, VNC or SPICE)"), N_("FILE") }, + { "connect", 'c', 0, G_OPTION_ARG_FILENAME_ARRAY, NULL, N_("Connect either to a desktop described in a file (.remmina or a filetype supported by a plugin) or a supported URI (RDP, VNC, SSH or SPICE)"), N_("FILE") }, // TRANSLATORS: Shown in terminal. Do not use characters that may be not supported on a terminal { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_FILENAME_ARRAY, NULL, N_("Connect to a desktop described in a file (.remmina or a type supported by a plugin)"), N_("FILE") }, // TRANSLATORS: Shown in terminal. Do not use characters that may be not supported on a terminal diff --git a/src/remmina_exec.c b/src/remmina_exec.c index bcdccb081..946a1c221 100644 --- a/src/remmina_exec.c +++ b/src/remmina_exec.c @@ -216,27 +216,148 @@ static void remmina_exec_autostart_cb(RemminaFile *remminafile, gpointer user_da } -void remmina_exec_command(RemminaCommandType command, const gchar* data) +static void remmina_exec_connect(const gchar *data) { TRACE_CALL(__func__); - gchar *s1; - gchar *s2; - gchar *p; + + gchar *protocol; gchar **protocolserver; + gchar *server; + RemminaFile *remminafile; gchar **userat; gchar **userpass; + gchar *user; + gchar *password; gchar **domainuser; gchar **serverquery; gchar **querystring; gchar **querystringpart; gchar **querystringpartkv; - gchar *protocol; - gchar *server; - gchar *user; - gchar *password; gchar *value; gchar *temp; - RemminaFile *remminafile; + + protocol = NULL; + if (strncmp("rdp://", data, 6) == 0 || strncmp("RDP://", data, 6) == 0) + protocol = "RDP"; + else if (strncmp("vnc://", data, 6) == 0 || strncmp("VNC://", data, 6) == 0) + protocol = "VNC"; + else if (strncmp("ssh://", data, 6) == 0 || strncmp("SSH://", data, 6) == 0) + protocol = "SSH"; + else if (strncmp("spice://", data, 8) == 0 || strncmp("SPICE://", data, 8) == 0) + protocol = "SPICE"; + + if (protocol == NULL) { + rcw_open_from_filename(data); + return; + } + + protocolserver = g_strsplit(data, "://", 2); + server = g_strdup(protocolserver[1]); + + // Support loading .remmina files using handler + if ((temp = strrchr(server, '.')) != NULL && g_strcmp0(temp + 1, "remmina") == 0) { + g_strfreev(protocolserver); + temp = g_uri_unescape_string(server, NULL); + g_free(server); + server = temp; + rcw_open_from_filename(server); + return; + } + + remminafile = remmina_file_new(); + + // Check for username@server + if ((strcmp(protocol, "RDP") == 0 || strcmp(protocol, "VNC") == 0 || strcmp(protocol, "SSH") == 0) && strstr(server, "@") != NULL) { + userat = g_strsplit(server, "@", 2); + + // Check for username:password + if (strstr(userat[0], ":") != NULL) { + userpass = g_strsplit(userat[0], ":", 2); + user = g_uri_unescape_string(userpass[0], NULL); + password = g_uri_unescape_string(userpass[1], NULL); + + // Try to decrypt the password field if it contains = + temp = password != NULL && strrchr(password, '=') != NULL ? remmina_crypt_decrypt(password) : NULL; + if (temp != NULL) { + g_free(password); + password = temp; + } + remmina_file_set_string(remminafile, "password", password); + g_free(password); + g_strfreev(userpass); + } else { + user = g_uri_unescape_string(userat[0], NULL); + } + + // Check for domain\user for RDP connections + if (strcmp(protocol, "RDP") == 0 && strstr(user, "\\") != NULL) { + domainuser = g_strsplit(user, "\\", 2); + remmina_file_set_string(remminafile, "domain", domainuser[0]); + g_free(user); + user = g_strdup(domainuser[1]); + } + + remmina_file_set_string(remminafile, "username", user); + g_free(user); + g_free(server); + server = g_strdup(userat[1]); + g_strfreev(userat); + } + + if (strcmp(protocol, "VNC") == 0 && strstr(server, "?") != NULL) { + // https://tools.ietf.org/html/rfc7869 + // VncUsername, VncPassword and ColorLevel supported for vnc-params + + // Check for query string parameters + serverquery = g_strsplit(server, "?", 2); + querystring = g_strsplit(serverquery[1], "&", -1); + for (querystringpart = querystring; *querystringpart; querystringpart++) { + if (strstr(*querystringpart, "=") == NULL) + continue; + querystringpartkv = g_strsplit(*querystringpart, "=", 2); + value = g_uri_unescape_string(querystringpartkv[1], NULL); + if (strcmp(querystringpartkv[0], "VncPassword") == 0) { + // Try to decrypt password field if it contains = + temp = value != NULL && strrchr(value, '=') != NULL ? remmina_crypt_decrypt(value) : NULL; + if (temp != NULL) { + g_free(value); + value = temp; + } + remmina_file_set_string(remminafile, "password", value); + } else if (strcmp(querystringpartkv[0], "VncUsername") == 0) { + remmina_file_set_string(remminafile, "username", value); + } else if (strcmp(querystringpartkv[0], "ColorLevel") == 0) { + remmina_file_set_string(remminafile, "colordepth", value); + } + g_free(value); + g_strfreev(querystringpartkv); + } + g_strfreev(querystring); + g_free(server); + server = g_strdup(serverquery[0]); + g_strfreev(serverquery); + } + + // Unescape server + temp = g_uri_unescape_string(server, NULL); + g_free(server); + server = temp; + + remmina_file_set_string(remminafile, "server", server); + remmina_file_set_string(remminafile, "name", server); + remmina_file_set_string(remminafile, "sound", "off"); + remmina_file_set_string(remminafile, "protocol", protocol); + g_free(server); + g_strfreev(protocolserver); + rcw_open_from_file(remminafile); +} + +void remmina_exec_command(RemminaCommandType command, const gchar* data) +{ + TRACE_CALL(__func__); + gchar *s1; + gchar *s2; + gchar *temp; GtkWidget *widget; GtkWindow *mainwindow; GtkDialog *prefdialog; @@ -293,154 +414,7 @@ void remmina_exec_command(RemminaCommandType command, const gchar* data) * we can implement multi profile connection: * https://gitlab.com/Remmina/Remmina/issues/915 */ - protocol = NULL; - if (strncmp("rdp://", data, 6) == 0 || strncmp("RDP://", data, 6) == 0) - protocol = "RDP"; - else if (strncmp("vnc://", data, 6) == 0 || strncmp("VNC://", data, 6) == 0) - protocol = "VNC"; - else if (strncmp("spice://", data, 8) == 0 || strncmp("SPICE://", data, 8) == 0) - protocol = "SPICE"; - - if (protocol != NULL) { - protocolserver = g_strsplit(data, "://", 2); - server = g_strdup(protocolserver[1]); - - // Support loading .remmina files using handler - if ((p = strrchr(server, '.')) != NULL && g_strcmp0(p + 1, "remmina") == 0) { - g_strfreev(protocolserver); - temp = g_uri_unescape_string(server, NULL); - g_free(server); - server = temp; - rcw_open_from_filename(server); - break; - } - - remminafile = remmina_file_new(); - - if (strcmp(protocol, "RDP") == 0) { - // https://tools.ietf.org/html/rfc3986 - // "rdp://" [ userinfo "@" ] host [ ":" port ] - - // Check for username@server - if (strstr(server, "@") != NULL) { - userat = g_strsplit(server, "@", 2); - - // Check for username:password - if (strstr(userat[0], ":") != NULL) { - userpass = g_strsplit(userat[0], ":", 2); - user = g_uri_unescape_string(userpass[0], NULL); - password = g_uri_unescape_string(userpass[1], NULL); - - // Try to decrypt the password field if it contains = - temp = password != NULL && strrchr(password, '=') != NULL ? remmina_crypt_decrypt(password) : NULL; - if (temp != NULL) { - g_free(password); - password = temp; - } - remmina_file_set_string(remminafile, "password", password); - g_free(password); - g_strfreev(userpass); - } else { - user = g_uri_unescape_string(userat[0], NULL); - } - - // Check for domain\user - if (strstr(user, "\\") != NULL) { - domainuser = g_strsplit(user, "\\", 2); - remmina_file_set_string(remminafile, "domain", domainuser[0]); - g_free(user); - user = g_strdup(domainuser[1]); - } - - remmina_file_set_string(remminafile, "username", user); - g_free(user); - g_free(server); - server = g_strdup(userat[1]); - g_strfreev(userat); - } - } else if (strcmp(protocol, "VNC") == 0) { - // https://tools.ietf.org/html/rfc7869 - // VncUsername, VncPassword and ColorLevel supported for vnc-params - // "vnc://" [ userinfo "@" ] [ host [ ":" port ] ] [ "?" [ vnc-params ] ] - - // Check for username@server - if (strstr(server, "@") != NULL) { - userat = g_strsplit(server, "@", 2); - - // Check for username:password - if (strstr(userat[0], ":") != NULL) { - userpass = g_strsplit(userat[0], ":", 2); - user = g_uri_unescape_string(userpass[0], NULL); - remmina_file_set_string(remminafile, "username", user); - g_free(user); - password = g_uri_unescape_string(userpass[1], NULL); - - // Try to decrypt password field if it contains = - temp = password != NULL && strrchr(password, '=') != NULL ? remmina_crypt_decrypt(password) : NULL; - if (temp != NULL) { - g_free(password); - password = temp; - } - remmina_file_set_string(remminafile, "password", password); - g_free(password); - g_strfreev(userpass); - } else { - user = g_uri_unescape_string(userat[0], NULL); - remmina_file_set_string(remminafile, "username", user); - g_free(user); - } - g_free(server); - server = g_strdup(userat[1]); - g_strfreev(userat); - } - - // Check for query string parameters - if (strstr(server, "?") != NULL) { - serverquery = g_strsplit(server, "?", 2); - querystring = g_strsplit(serverquery[1], "&", -1); - for (querystringpart = querystring; *querystringpart; querystringpart++) { - if (strstr(*querystringpart, "=") != NULL) { - querystringpartkv = g_strsplit(*querystringpart, "=", 2); - value = g_uri_unescape_string(querystringpartkv[1], NULL); - if (strcmp(querystringpartkv[0], "VncPassword") == 0) { - // Try to decrypt password field if it contains = - temp = value != NULL && strrchr(value, '=') != NULL ? remmina_crypt_decrypt(value) : NULL; - if (temp != NULL) { - g_free(value); - value = temp; - } - remmina_file_set_string(remminafile, "password", value); - } else if (strcmp(querystringpartkv[0], "VncUsername") == 0) { - remmina_file_set_string(remminafile, "username", value); - } else if (strcmp(querystringpartkv[0], "ColorLevel") == 0) { - remmina_file_set_string(remminafile, "colordepth", value); - } - g_free(value); - g_strfreev(querystringpartkv); - } - } - g_strfreev(querystring); - g_free(server); - server = g_strdup(serverquery[0]); - g_strfreev(serverquery); - } - } - - // Unescape server - temp = g_uri_unescape_string(server, NULL); - g_free(server); - server = temp; - - remmina_file_set_string(remminafile, "server", server); - remmina_file_set_string(remminafile, "name", server); - remmina_file_set_string(remminafile, "sound", "off"); - remmina_file_set_string(remminafile, "protocol", protocol); - g_free(server); - g_strfreev(protocolserver); - rcw_open_from_file(remminafile); - } else { - rcw_open_from_filename(data); - } + remmina_exec_connect(data); break; case REMMINA_COMMAND_EDIT: -- cgit v1.2.3