summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/remmina_file_editor.c28
-rw-r--r--src/remmina_protocol_widget.c38
-rw-r--r--src/remmina_utils.c61
-rw-r--r--src/remmina_utils.h1
4 files changed, 117 insertions, 11 deletions
diff --git a/src/remmina_file_editor.c b/src/remmina_file_editor.c
index feca2bc..12eba54 100644
--- a/src/remmina_file_editor.c
+++ b/src/remmina_file_editor.c
@@ -129,6 +129,7 @@ struct _RemminaFileEditorPriv {
GtkWidget * ssh_tunnel_server_default_radio;
GtkWidget * ssh_tunnel_server_custom_radio;
GtkWidget * ssh_tunnel_server_entry;
+ GtkWidget * ssh_tunnel_command_entry;
GtkWidget * ssh_tunnel_auth_agent_radio;
GtkWidget * ssh_tunnel_auth_password_radio;
GtkWidget * ssh_tunnel_auth_password;
@@ -418,6 +419,8 @@ static void remmina_file_editor_ssh_tunnel_enabled_check_on_toggled(GtkToggleBut
gtk_widget_set_sensitive(GTK_WIDGET(gfe->priv->ssh_tunnel_username_entry), enabled);
gtk_widget_set_sensitive(GTK_WIDGET(gfe->priv->ssh_tunnel_auth_password), enabled);
gtk_widget_set_sensitive(GTK_WIDGET(gfe->priv->ssh_tunnel_auth_combo), enabled);
+ gtk_widget_set_sensitive(GTK_WIDGET(gfe->priv->ssh_tunnel_command_entry), enabled);
+
//}
g_free(p);
}
@@ -447,6 +450,12 @@ static void remmina_file_editor_ssh_tunnel_enabled_check_on_toggled(GtkToggleBut
gtk_entry_set_text(GTK_ENTRY(gfe->priv->ssh_tunnel_passphrase), cp ? cp : "");
}
}
+ if (gfe->priv->ssh_tunnel_command_entry) {
+ if (enabled && gtk_entry_get_text(GTK_ENTRY(gfe->priv->ssh_tunnel_command_entry))[0] == '\0') {
+ cp = remmina_file_get_string(priv->remmina_file, "ssh_tunnel_command");
+ gtk_entry_set_text(GTK_ENTRY(gfe->priv->ssh_tunnel_command_entry), cp ? cp : "");
+ }
+ }
}
#endif
@@ -1384,6 +1393,19 @@ static void remmina_file_editor_create_ssh_tunnel_tab(RemminaFileEditor *gfe, Re
cs ? cs : "");
}
+
+ remmina_public_create_group(GTK_GRID(grid), _("SSH Command"), row, 2, 1);
+ row += 2;
+ priv->ssh_tunnel_command_entry =
+ remmina_file_editor_create_text(gfe, grid, row, 0,
+ _("Startup command"), NULL, "ssh_tunnel_command");
+ cs = remmina_file_get_string(priv->remmina_file, "ssh_tunnel_command");
+ gtk_entry_set_text(GTK_ENTRY(priv->ssh_tunnel_command_entry),
+ cs ? cs : "");
+ row++;
+
+
+
remmina_file_editor_ssh_tunnel_enabled_check_on_toggled(NULL, gfe, ssh_setting);
gtk_widget_show_all(grid);
g_free(p);
@@ -1455,6 +1477,7 @@ static void remmina_file_editor_protocol_combo_on_changed(GtkComboBox *combo, Re
priv->ssh_tunnel_server_custom_radio = NULL;
priv->ssh_tunnel_server_entry = NULL;
priv->ssh_tunnel_username_entry = NULL;
+ priv->ssh_tunnel_command_entry = NULL;
priv->ssh_tunnel_auth_combo = NULL;
priv->ssh_tunnel_auth_password = NULL;
priv->ssh_tunnel_privatekey_chooser = NULL;
@@ -1542,6 +1565,11 @@ static void remmina_file_editor_save_ssh_tunnel_tab(RemminaFileEditor *gfe)
"ssh_tunnel_password",
(ssh_tunnel_enabled && (ssh_tunnel_auth == SSH_AUTH_PASSWORD)) ? gtk_entry_get_text(GTK_ENTRY(priv->ssh_tunnel_auth_password)) : NULL);
+ char* command = gtk_entry_get_text(GTK_ENTRY(priv->ssh_tunnel_command_entry));
+ remmina_file_set_string(
+ priv->remmina_file,
+ "ssh_tunnel_command", command);
+
remmina_file_set_string(
priv->remmina_file,
"ssh_tunnel_passphrase",
diff --git a/src/remmina_protocol_widget.c b/src/remmina_protocol_widget.c
index 7becda0..c8362a9 100644
--- a/src/remmina_protocol_widget.c
+++ b/src/remmina_protocol_widget.c
@@ -1168,6 +1168,44 @@ gchar *remmina_protocol_widget_start_direct_tunnel(RemminaProtocolWidget *gp, gi
g_ptr_array_add(gp->priv->ssh_tunnels, tunnel);
+
+ //try startup command
+ ssh_channel channel;
+ int rc;
+ const gchar* tunnel_command = remmina_file_get_string(gp->priv->remmina_file, "ssh_tunnel_command");
+ if (tunnel_command != NULL){
+ channel = ssh_channel_new(REMMINA_SSH(tunnel)->session);
+ if (channel == NULL) return g_strdup_printf("127.0.0.1:%i", remmina_pref.sshtunnel_port);
+
+ rc = ssh_channel_open_session(channel);
+ if (rc != SSH_OK)
+ {
+ ssh_channel_free(channel);
+ return g_strdup_printf("127.0.0.1:%i", remmina_pref.sshtunnel_port);
+ }
+ rc = ssh_channel_request_exec(channel, tunnel_command);
+ if (rc != SSH_OK)
+ {
+ ssh_channel_close(channel);
+ ssh_channel_free(channel);
+ return g_strdup_printf("127.0.0.1:%i", remmina_pref.sshtunnel_port);
+ }
+ struct timeval timeout = {10, 0};
+ ssh_channel channels[2];
+ channels[0] = channel;
+ channels[1] = NULL;
+ rc = ssh_channel_select(channels, NULL, NULL, &timeout);
+ if (rc == SSH_OK){
+ char buffer[256];
+ ssh_channel_read(channel, buffer, sizeof(buffer), 0);
+ }
+
+ REMMINA_DEBUG("Ran startup command");
+ ssh_channel_close(channel);
+ ssh_channel_free(channel);
+ }
+
+
return g_strdup_printf("127.0.0.1:%i", remmina_pref.sshtunnel_port);
#else
diff --git a/src/remmina_utils.c b/src/remmina_utils.c
index 14c0283..0abe855 100644
--- a/src/remmina_utils.c
+++ b/src/remmina_utils.c
@@ -46,8 +46,14 @@
#include <glib/gstdio.h>
#include <gio/gio.h>
#include <openssl/evp.h>
+
+#if OPENSSL_VERSION_MAJOR >= 3
#include <openssl/decoder.h>
#include <openssl/core_names.h>
+#else
+#include <openssl/pem.h>
+#endif
+
#include <openssl/rsa.h>
#include <openssl/err.h>
#include "remmina_sodium.h"
@@ -709,9 +715,16 @@ gchar *remmina_gen_random_uuid()
*/
EVP_PKEY *remmina_get_pubkey(const char *keytype, const char *public_key_selection) {
BIO *pkbio;
- OSSL_DECODER_CTX *dctx;
-
EVP_PKEY *pubkey = NULL;
+
+ pkbio = BIO_new_mem_buf(public_key_selection, -1);
+
+ if (pkbio == NULL) {
+ return NULL;
+ }
+
+#if OPENSSL_VERSION_MAJOR >= 3
+ OSSL_DECODER_CTX *dctx;
const char *format = "PEM";
const char *structure = NULL;
dctx = OSSL_DECODER_CTX_new_for_pkey(&pubkey, format, structure,
@@ -722,15 +735,18 @@ EVP_PKEY *remmina_get_pubkey(const char *keytype, const char *public_key_selecti
if (dctx == NULL) {
return NULL;
}
- pkbio = BIO_new_mem_buf(public_key_selection, -1);
if (OSSL_DECODER_from_bio(dctx, pkbio) == 0) {
BIO_free(pkbio);
OSSL_DECODER_CTX_free(dctx);
return NULL;
}
- BIO_free(pkbio);
+
OSSL_DECODER_CTX_free(dctx);
+#else
+ PEM_read_bio_PUBKEY(pkbio, &pubkey, NULL, NULL);
+#endif
+ BIO_free(pkbio);
return pubkey;
}
@@ -750,10 +766,8 @@ gchar *remmina_rsa_encrypt_string(EVP_PKEY *pubkey, const char *instr)
int remaining;
size_t blksz, maxblksz;
unsigned char *outptr;
-
unsigned char *ebuf = NULL;
gsize ebufLen;
- EVP_PKEY_CTX *ctx = NULL;
int pkeyLen = EVP_PKEY_size(pubkey);
int inLen = strlen(instr);
remaining = inLen;
@@ -766,6 +780,8 @@ gchar *remmina_rsa_encrypt_string(EVP_PKEY *pubkey, const char *instr)
}
outptr = ebuf;
+#if OPENSSL_VERSION_MAJOR >= 3
+ EVP_PKEY_CTX *ctx = NULL;
ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pubkey, NULL);
if (ctx == NULL) {
g_free(ebuf);
@@ -783,12 +799,19 @@ gchar *remmina_rsa_encrypt_string(EVP_PKEY *pubkey, const char *instr)
g_free(ebuf);
return NULL;
}
+#else
+ RSA* rsa = EVP_PKEY_get1_RSA(pubkey);
+ if (rsa == NULL) {
+ return NULL;
+ }
+#endif
/* encrypt input string block by block */
while (remaining > 0) {
blksz = remaining > maxblksz ? maxblksz : remaining;
size_t out_blksz;
+#if OPENSSL_VERSION_MAJOR >= 3
int calc_size_return_val = EVP_PKEY_encrypt(ctx, NULL, &out_blksz, (const unsigned char *)instr, blksz);
if (calc_size_return_val == -2) {
EVP_PKEY_CTX_free(ctx);
@@ -806,6 +829,13 @@ gchar *remmina_rsa_encrypt_string(EVP_PKEY *pubkey, const char *instr)
g_free(ebuf);
return NULL;
}
+#else
+ out_blksz = RSA_public_encrypt(blksz, (const unsigned char *)instr, outptr, rsa, RSA_PKCS1_OAEP_PADDING);
+ if (out_blksz == -1) {
+ g_free(ebuf);
+ return NULL;
+ }
+#endif
instr += blksz;
remaining -= blksz;
@@ -814,7 +844,9 @@ gchar *remmina_rsa_encrypt_string(EVP_PKEY *pubkey, const char *instr)
enc = g_base64_encode(ebuf, ebufLen);
g_free(ebuf);
+#if OPENSSL_VERSION_MAJOR >= 3
EVP_PKEY_CTX_free(ctx);
+#endif
return enc;
}
@@ -876,7 +908,7 @@ gboolean remmina_execute_plugin_signature_verification(GFile* plugin_file, size_
/* Create context for verification */
- ctx = EVP_MD_CTX_create();
+ ctx = EVP_MD_CTX_new();
if(ctx == NULL) {
return FALSE;
}
@@ -888,6 +920,7 @@ gboolean remmina_execute_plugin_signature_verification(GFile* plugin_file, size_
return FALSE;
}
+#if OPENSSL_VERSION_MAJOR >= 3
/* Set up context with the corresponding message digest. 1 is the only code for success */
int return_val = EVP_DigestInit_ex(ctx, message_digest, NULL);
@@ -897,8 +930,10 @@ gboolean remmina_execute_plugin_signature_verification(GFile* plugin_file, size_
}
/* Add the public key and initialize the context for verification*/
-
return_val = EVP_DigestVerifyInit(ctx, NULL, message_digest, NULL, public_key);
+#else
+ int return_val = EVP_VerifyInit(ctx, message_digest);
+#endif
if(return_val != 1) {
EVP_MD_CTX_free(ctx);
@@ -911,8 +946,11 @@ gboolean remmina_execute_plugin_signature_verification(GFile* plugin_file, size_
read = g_input_stream_read(G_INPUT_STREAM(in_stream), buffer, 1024, NULL, NULL);
while (read > 0){
total_read += read;
+#if OPENSSL_VERSION_MAJOR >= 3
return_val = EVP_DigestVerifyUpdate(ctx, buffer, read);
-
+#else
+ return_val = EVP_VerifyUpdate(ctx, buffer, read);
+#endif
if(return_val != 1) {
EVP_MD_CTX_free(ctx);
return FALSE;
@@ -925,8 +963,11 @@ gboolean remmina_execute_plugin_signature_verification(GFile* plugin_file, size_
ERR_clear_error();
/* Execute the signature verification. */
+#if OPENSSL_VERSION_MAJOR >= 3
return_val = EVP_DigestVerifyFinal(ctx, sig, sig_len);
-
+#else
+ return_val = EVP_VerifyFinal(ctx, sig, sig_len, public_key);
+#endif
if(return_val != 1) {
EVP_MD_CTX_free(ctx);
return FALSE;
diff --git a/src/remmina_utils.h b/src/remmina_utils.h
index 8c3af3f..ec5f044 100644
--- a/src/remmina_utils.h
+++ b/src/remmina_utils.h
@@ -44,7 +44,6 @@
#include <gio/gio.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
-#include <openssl/decoder.h>
#define MAX_COMPRESSED_FILE_SIZE 100000 //100kb file size max
#define NAME_OF_DIGEST "SHA256"