Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/Remmina/Remmina.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xdata/desktop/remmina-file-wrapper.in6
-rw-r--r--src/remmina.124
-rw-r--r--src/remmina.c11
-rw-r--r--src/remmina_exec.c207
-rw-r--r--src/remmina_exec.h3
5 files changed, 235 insertions, 16 deletions
diff --git a/data/desktop/remmina-file-wrapper.in b/data/desktop/remmina-file-wrapper.in
index a2ec5933e..ccf6dbe56 100755
--- a/data/desktop/remmina-file-wrapper.in
+++ b/data/desktop/remmina-file-wrapper.in
@@ -34,13 +34,13 @@ export GLADE_HOME="$USRBIN/../share/remmina/ui/"
case "$@" in
*rdp:*)
- "$REMMINA" "${@#rdp:\/\/}"
+ "$REMMINA" "${@}"
;;
*spice:*)
- "$REMMINA" "${@#spice:\/\/}"
+ "$REMMINA" "${@}"
;;
*vnc:*)
- "$REMMINA" "${@#vnc:\/\/}"
+ "$REMMINA" "${@}"
;;
*remmina:*)
"$REMMINA" "${@#remmina:\/\/}"
diff --git a/src/remmina.1 b/src/remmina.1
index a9faec2d7..721333074 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
-Directly connect to desktop using options described by file, file type can be either .remmina or one supported by a file import capable plugin
+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
.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
@@ -72,6 +72,8 @@ Show the application's version
Modify connection profile, require also \-\-set\-option
.It --set-option \fIOPTION[=VALUE]\fR
Set one or more profile settings, to be used with \-\-update\-profile
+.It --encrypt-password\fR
+Encrypt a password
.It --display\fR=\fIDISPLAY\fR
X display to use
.El
@@ -84,6 +86,26 @@ To connect using an exisitng connection profile use:
.fi
.RE
.Lp
+To quick connect using a URI:
+.RS
+.nf
+remmina -c rdp://username:password@server
+remmina -c rdp://domain\\\\username@server
+remmina -c vnc://username@server
+remmina -c vnc://server?VncUsername=username
+remmina -c spice://server
+
+To quick connect using a URI along with an encrypted password:
+remmina -c rdp://username:encrypted-password@server
+remmina -c vnc://username:encrypted-password@server
+remmina -c vnc://server?VncUsername=username\\&VncPassword=encrypted-password
+
+To encrypt a password for use with a URI:
+remmina --encrypt-password
+
+.fi
+.RE
+.Lp
To update username and password and set a different resolution mode of a remmina connection profile use:
.RS
.nf
diff --git a/src/remmina.c b/src/remmina.c
index dbeae30a9..0d0dc7d96 100644
--- a/src/remmina.c
+++ b/src/remmina.c
@@ -83,9 +83,9 @@ 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 to desktop described in file (.remmina or type supported by plugin)"), 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 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 desktop described in file (.remmina or type supported by plugin)"), N_("FILE") },
+ { 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
{ "edit", 'e', 0, G_OPTION_ARG_FILENAME_ARRAY, NULL, N_("Edit desktop connection described in file (.remmina or type supported by plugin)"), N_("FILE") },
{ "help", '?', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, NULL, NULL, NULL },
@@ -116,6 +116,7 @@ static GOptionEntry remmina_options[] =
{ "update-profile", 0, 0, G_OPTION_ARG_FILENAME, NULL, N_("Modify connection profile (requires --set-option)"), NULL },
// TRANSLATORS: Shown in terminal. Do not use characters that may be not supported on a terminal
{ "set-option", 0, 0, G_OPTION_ARG_STRING_ARRAY, NULL, N_("Set one or more profile settings, to be used with --update-profile"), NULL },
+ { "encrypt-password", 0, 0, G_OPTION_ARG_NONE, NULL, N_("Encrypt a password"), NULL },
{ NULL }
};
@@ -226,6 +227,12 @@ static gint remmina_on_command_line(GApplication *app, GApplicationCommandLine *
executed = TRUE;
}
+ if (g_variant_dict_lookup_value(opts, "encrypt-password", NULL)) {
+ remmina_exec_command(REMMINA_COMMAND_ENCRYPT_PASSWORD, NULL);
+ executed = TRUE;
+ status = 1;
+ }
+
if (!executed)
remmina_exec_command(REMMINA_COMMAND_MAIN, NULL);
diff --git a/src/remmina_exec.c b/src/remmina_exec.c
index 17d76131f..bcdccb081 100644
--- a/src/remmina_exec.c
+++ b/src/remmina_exec.c
@@ -56,6 +56,7 @@
#include "remmina_icon.h"
#include "remmina/remmina_trace_calls.h"
#include "remmina_file_manager.h"
+#include "remmina_crypt.h"
#ifdef SNAP_BUILD
# define ISSNAP "- SNAP Build -"
@@ -214,16 +215,34 @@ static void remmina_exec_autostart_cb(RemminaFile *remminafile, gpointer user_da
}
}
+
void remmina_exec_command(RemminaCommandType command, const gchar* data)
{
TRACE_CALL(__func__);
- gchar* s1;
- gchar* s2;
- GtkWidget* widget;
- GtkWindow* mainwindow;
- GtkDialog* prefdialog;
- RemminaEntryPlugin* plugin;
-
+ gchar *s1;
+ gchar *s2;
+ gchar *p;
+ gchar **protocolserver;
+ gchar **userat;
+ gchar **userpass;
+ gchar **domainuser;
+ gchar **serverquery;
+ gchar **querystring;
+ gchar **querystringpart;
+ gchar **querystringpartkv;
+ gchar *protocol;
+ gchar *server;
+ gchar *user;
+ gchar *password;
+ gchar *value;
+ gchar *temp;
+ RemminaFile *remminafile;
+ GtkWidget *widget;
+ GtkWindow *mainwindow;
+ GtkDialog *prefdialog;
+ RemminaEntryPlugin *plugin;
+ int i;
+ int ch;
mainwindow = remmina_main_get_window();
switch (command) {
@@ -274,7 +293,154 @@ void remmina_exec_command(RemminaCommandType command, const gchar* data)
* we can implement multi profile connection:
* https://gitlab.com/Remmina/Remmina/issues/915
*/
- rcw_open_from_filename(data);
+ 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);
+ }
break;
case REMMINA_COMMAND_EDIT:
@@ -328,6 +494,30 @@ void remmina_exec_command(RemminaCommandType command, const gchar* data)
}
break;
+ case REMMINA_COMMAND_ENCRYPT_PASSWORD:
+ i = 0;
+ g_print("Enter the password you want to encrypt: ");
+ temp = (char *)g_malloc(255 * sizeof(char));
+ while ((ch = getchar()) != EOF && ch != '\n') {
+ if (i < 254) {
+ temp[i] = ch;
+ i++;
+ }
+ }
+ temp[i] = '\0';
+ s1 = remmina_crypt_encrypt(temp);
+ s2 = g_uri_escape_string(s1, NULL, TRUE);
+ g_print("\nEncrypted password: %s\n\n", s1);
+ g_print("Usage:\n");
+ g_print("rdp://username:%s@server\n", s1);
+ g_print("vnc://username:%s@server\n", s1);
+ g_print("vnc://server?VncUsername=user\\&VncPassword=%s\n", s2);
+ g_free(s1);
+ g_free(s2);
+ g_free(temp);
+ remmina_exec_exitremmina();
+ break;
+
case REMMINA_COMMAND_EXIT:
remmina_widget_pool_foreach(disable_rcw_delete_confirm_cb, NULL);
remmina_exec_exitremmina();
@@ -337,4 +527,3 @@ void remmina_exec_command(RemminaCommandType command, const gchar* data)
break;
}
}
-
diff --git a/src/remmina_exec.h b/src/remmina_exec.h
index adbb6ced2..5cb1afc2b 100644
--- a/src/remmina_exec.h
+++ b/src/remmina_exec.h
@@ -49,7 +49,8 @@ typedef enum {
REMMINA_COMMAND_FULL_VERSION = 8,
REMMINA_COMMAND_PLUGIN = 9,
REMMINA_COMMAND_EXIT = 10,
- REMMINA_COMMAND_AUTOSTART = 11
+ REMMINA_COMMAND_AUTOSTART = 11,
+ REMMINA_COMMAND_ENCRYPT_PASSWORD = 12
} RemminaCommandType;
typedef enum {