diff options
Diffstat (limited to '')
-rw-r--r-- | src/remmina_ssh.h | 284 |
1 files changed, 284 insertions, 0 deletions
diff --git a/src/remmina_ssh.h b/src/remmina_ssh.h new file mode 100644 index 0000000..baad192 --- /dev/null +++ b/src/remmina_ssh.h @@ -0,0 +1,284 @@ +/* + * Remmina - The GTK+ Remote Desktop Client + * Copyright (C) 2009-2011 Vic Lee + * Copyright (C) 2014-2015 Antenore Gatta, Fabio Castelli, Giovanni Panozzo + * Copyright (C) 2016-2023 Antenore Gatta, Giovanni Panozzo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations + * including the two. + * You must obey the GNU General Public License in all respects + * for all of the code used other than OpenSSL. * If you modify + * file(s) with this exception, you may extend this exception to your + * version of the file(s), but you are not obligated to do so. * If you + * do not wish to do so, delete this exception statement from your + * version. * If you delete this exception statement from all source + * files in the program, then also delete it here. + * + */ + +#pragma once + +#include "config.h" + +#ifdef HAVE_LIBSSH + +#define LIBSSH_STATIC 1 +#include <libssh/libssh.h> +#include <libssh/callbacks.h> +#include <libssh/sftp.h> +#include <pthread.h> +#include "remmina_file.h" +#include "rcw.h" + +G_BEGIN_DECLS + +/*-----------------------------------------------------------------------------* +* SSH Base * +*-----------------------------------------------------------------------------*/ + +#define REMMINA_SSH(a) ((RemminaSSH *)a) + +typedef struct _RemminaSSH { + ssh_session session; + ssh_callbacks callback; + gboolean authenticated; + + gchar * server; + gint port; + gchar * user; + gint auth; + gchar * password; + gchar * privkeyfile; + gchar * certfile; + + gchar * charset; + const gchar * kex_algorithms; + gchar * ciphers; + gchar * hostkeytypes; + gchar * proxycommand; + gint stricthostkeycheck; + const gchar * compression; + + gchar * error; + + pthread_mutex_t ssh_mutex; + + gchar * passphrase; + + gboolean is_tunnel; + gboolean is_multiauth; + gchar * tunnel_entrance_host; + gint tunnel_entrance_port; + +} RemminaSSH; + +gchar *remmina_ssh_identity_path(const gchar *id); + +/* Auto-detect commonly used private key identities */ +gchar *remmina_ssh_find_identity(void); + +/* Initialize the ssh object */ +gboolean remmina_ssh_init_from_file(RemminaSSH *ssh, RemminaFile *remminafile, gboolean is_tunnel); + +/* Initialize the SSH session */ +gboolean remmina_ssh_init_session(RemminaSSH *ssh); + +/* Authenticate SSH session */ + + +enum remmina_ssh_auth_result { + REMMINA_SSH_AUTH_NULL, + REMMINA_SSH_AUTH_SUCCESS, + REMMINA_SSH_AUTH_PARTIAL, + REMMINA_SSH_AUTH_AGAIN, + REMMINA_SSH_AUTH_AUTHFAILED_RETRY_AFTER_PROMPT, + REMMINA_SSH_AUTH_USERCANCEL, + REMMINA_SSH_AUTH_FATAL_ERROR, + REMMINA_SSH_AUTH_RECONNECT, + REMMINA_SSH_AUTH_AUTHFAILED_EMPTY_USERNAME +}; + +enum remmina_ssh_auth_result remmina_ssh_auth(RemminaSSH *ssh, const gchar *password, RemminaProtocolWidget *gp, RemminaFile *remminafile); + +enum remmina_ssh_auth_result remmina_ssh_auth_gui(RemminaSSH *ssh, RemminaProtocolWidget *gp, RemminaFile *remminafile); + +/* Error handling */ +#define remmina_ssh_has_error(ssh) (((RemminaSSH *)ssh)->error != NULL) +void remmina_ssh_set_error(RemminaSSH *ssh, const gchar *fmt); +void remmina_ssh_set_application_error(RemminaSSH *ssh, const gchar *fmt, ...); + +/* Converts a string to/from UTF-8, or simply duplicate it if no conversion */ +gchar *remmina_ssh_convert(RemminaSSH *ssh, const gchar *from); +gchar *remmina_ssh_unconvert(RemminaSSH *ssh, const gchar *from); + +void remmina_ssh_free(RemminaSSH *ssh); + +/*-----------------------------------------------------------------------------* +* SSH Tunnel * +*-----------------------------------------------------------------------------*/ +typedef struct _RemminaSSHTunnel RemminaSSHTunnel; +typedef struct _RemminaSSHTunnelBuffer RemminaSSHTunnelBuffer; + +typedef gboolean (*RemminaSSHTunnelCallback) (RemminaSSHTunnel *, gpointer); + +enum { + REMMINA_SSH_TUNNEL_OPEN, + REMMINA_SSH_TUNNEL_XPORT, + REMMINA_SSH_TUNNEL_REVERSE +}; + + +struct _RemminaSSHTunnel { + RemminaSSH ssh; + + gint tunnel_type; + + ssh_channel * channels; + gint * sockets; + RemminaSSHTunnelBuffer ** socketbuffers; + gint num_channels; + gint max_channels; + + pthread_t thread; + gboolean running; + + gchar * buffer; + gint buffer_len; + ssh_channel * channels_out; + + gint server_sock; + gchar * dest; + gint port; + gint localport; + + gint remotedisplay; + gboolean bindlocalhost; + gchar * localdisplay; + + RemminaSSHTunnelCallback init_func; + RemminaSSHTunnelCallback connect_func; + RemminaSSHTunnelCallback disconnect_func; + gpointer callback_data; + + RemminaSSHTunnelCallback destroy_func; + gpointer destroy_func_callback_data; + +}; + +/* Create a new SSH Tunnel session and connects to the SSH server */ +RemminaSSHTunnel *remmina_ssh_tunnel_new_from_file(RemminaFile *remminafile); + +/* Open the tunnel. A new thread will be started and listen on a local port. + * dest: The host:port of the remote destination + * local_port: The listening local port for the tunnel + */ +gboolean remmina_ssh_tunnel_open(RemminaSSHTunnel *tunnel, const gchar *host, gint port, gint local_port); + +/* Cancel accepting any incoming tunnel request. + * Typically called after the connection has already been establish. + */ +void remmina_ssh_tunnel_cancel_accept(RemminaSSHTunnel *tunnel); + +/* start X Port Forwarding */ +gboolean remmina_ssh_tunnel_xport(RemminaSSHTunnel *tunnel, gboolean bindlocalhost); + +/* start reverse tunnel. A new thread will be started and waiting for incoming connection. + * port: the port listening on the remote server side. + * local_port: the port listening on the local side. When connection on the server side comes + * in, it will connect to the local port and create the tunnel. The caller should + * start listening on the local port before calling it or in connect_func callback. + */ +gboolean remmina_ssh_tunnel_reverse(RemminaSSHTunnel *tunnel, gint port, gint local_port); + +/* Tells if the tunnel is terminated after start */ +gboolean remmina_ssh_tunnel_terminated(RemminaSSHTunnel *tunnel); + +/* Free the tunnel */ +void remmina_ssh_tunnel_free(RemminaSSHTunnel *tunnel); + +/*-----------------------------------------------------------------------------* +* SSH sFTP * +*-----------------------------------------------------------------------------*/ + +typedef struct _RemminaSFTP { + RemminaSSH ssh; + + sftp_session sftp_sess; +} RemminaSFTP; + +/* Create a new SFTP session object from RemminaFile */ +RemminaSFTP *remmina_sftp_new_from_file(RemminaFile *remminafile); + +/* Create a new SFTP session object from existing SSH session */ +RemminaSFTP *remmina_sftp_new_from_ssh(RemminaSSH *ssh); + +/* open the SFTP session, assuming the session already authenticated */ +gboolean remmina_sftp_open(RemminaSFTP *sftp); + +/* Free the SFTP session */ +void remmina_sftp_free(RemminaSFTP *sftp); + +/*-----------------------------------------------------------------------------* +* SSH Shell * +*-----------------------------------------------------------------------------*/ +typedef void (*RemminaSSHExitFunc) (gpointer data); + +typedef struct _RemminaSSHShell { + RemminaSSH ssh; + + gint master; + gint slave; + gchar * exec; + gchar * run_line; + pthread_t thread; + ssh_channel channel; + gboolean closed; + RemminaSSHExitFunc exit_callback; + gpointer user_data; + ssh_event event; +} RemminaSSHShell; + +/* Create a new SSH Shell session object from RemminaFile */ +RemminaSSHShell *remmina_ssh_shell_new_from_file(RemminaFile *remminafile); + +/* Create a new SSH Shell session object from existing SSH session */ +RemminaSSHShell *remmina_ssh_shell_new_from_ssh(RemminaSSH *ssh); + +/* open the SSH Shell, assuming the session already authenticated */ +gboolean remmina_ssh_shell_open(RemminaSSHShell *shell, RemminaSSHExitFunc exit_callback, gpointer data); + +/* Change the SSH Shell terminal size */ +void remmina_ssh_shell_set_size(RemminaSSHShell *shell, gint columns, gint rows); + +/* Free the SFTP session */ +void remmina_ssh_shell_free(RemminaSSHShell *shell); + +G_END_DECLS + +#else + +#define RemminaSSH void +#define RemminaSSHTunnel void +#define RemminaSFTP void +#define RemminaSSHShell void +typedef void (*RemminaSSHTunnelCallback)(void); + +#endif /* HAVE_LIBSSH */ |