2
* Remmina - The GTK+ Remote Desktop Client
3
* Copyright (C) 2009-2010 Vic Lee
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place, Suite 330,
18
* Boston, MA 02111-1307, USA.
25
/* Define this before stdlib.h to have posix_openpt */
26
#define _XOPEN_SOURCE 600
29
#include <glib/gi18n.h>
34
#include <sys/types.h>
39
#ifdef HAVE_ARPA_INET_H
40
#include <arpa/inet.h>
42
#ifdef HAVE_NETINET_IN_H
43
#include <netinet/in.h>
45
#ifdef HAVE_SYS_SOCKET_H
46
#include <sys/socket.h>
57
#include "remminapublic.h"
58
#include "remminalog.h"
59
#include "remminassh.h"
61
/*************************** SSH Base *********************************/
63
#define LOCK_SSH(ssh) pthread_mutex_lock (&REMMINA_SSH (ssh)->ssh_mutex);
64
#define UNLOCK_SSH(ssh) pthread_mutex_unlock (&REMMINA_SSH (ssh)->ssh_mutex);
66
static const gchar *common_identities[] = {
74
remmina_ssh_identity_path (const gchar *id)
76
if (id == NULL) return NULL;
77
if (id[0] == '/') return g_strdup (id);
78
return g_strdup_printf ("%s/%s", g_get_home_dir (), id);
82
remmina_ssh_find_identity (void)
87
for (i = 0; common_identities[i]; i++)
89
path = remmina_ssh_identity_path (common_identities[i]);
90
if (g_file_test (path, G_FILE_TEST_IS_REGULAR | G_FILE_TEST_EXISTS))
100
remmina_ssh_set_error (RemminaSSH *ssh, const gchar *fmt)
104
err = ssh_get_error (ssh->session);
105
ssh->error = g_strdup_printf (fmt, err);
109
remmina_ssh_set_application_error (RemminaSSH *ssh, const gchar *fmt, ...)
113
va_start (args, fmt);
114
ssh->error = g_strdup_vprintf (fmt, args);
119
remmina_ssh_auth_password (RemminaSSH *ssh)
123
if (ssh->authenticated) return 1;
124
if (ssh->password == NULL) return -1;
126
ret = ssh_userauth_password (ssh->session, NULL, ssh->password);
127
if (ret != SSH_AUTH_SUCCESS)
129
remmina_ssh_set_error (ssh, _("SSH password authentication failed: %s"));
133
ssh->authenticated = TRUE;
138
remmina_ssh_auth_pubkey (RemminaSSH *ssh)
142
ssh_private_key privkey;
145
if (ssh->authenticated) return 1;
147
if (ssh->pubkeyfile == NULL || ssh->privkeyfile == NULL)
149
ssh->error = g_strdup_printf (_("SSH public key authentication failed: %s"),
150
_("SSH Key file not yet set."));
154
pubkey = publickey_from_file (ssh->session, ssh->pubkeyfile, &keytype);
157
remmina_ssh_set_error (ssh, _("SSH public key authentication failed: %s"));
161
privkey = privatekey_from_file (ssh->session, ssh->privkeyfile, keytype, _
162
(ssh->password ? ssh->password : ""));
165
string_free (pubkey);
166
if (ssh->password == NULL || ssh->password[0] == '\0') return -1;
168
remmina_ssh_set_error (ssh, _("SSH public key authentication failed: %s"));
172
ret = ssh_userauth_pubkey (ssh->session, NULL, pubkey, privkey);
173
string_free (pubkey);
174
privatekey_free (privkey);
176
if (ret != SSH_AUTH_SUCCESS)
178
remmina_ssh_set_error (ssh, _("SSH public key authentication failed: %s"));
182
ssh->authenticated = TRUE;
187
remmina_ssh_auth_auto_pubkey (RemminaSSH* ssh)
190
ret = ssh_userauth_autopubkey (ssh->session, "");
192
if (ret != SSH_AUTH_SUCCESS)
194
remmina_ssh_set_error (ssh, _("SSH automatic public key authentication failed: %s"));
198
ssh->authenticated = TRUE;
203
remmina_ssh_auth (RemminaSSH *ssh, const gchar *password)
207
g_free (ssh->password);
208
ssh->password = g_strdup (password);
214
case SSH_AUTH_PASSWORD:
215
return remmina_ssh_auth_password (ssh);
217
case SSH_AUTH_PUBLICKEY:
218
return remmina_ssh_auth_pubkey (ssh);
220
case SSH_AUTH_AUTO_PUBLICKEY:
221
return remmina_ssh_auth_auto_pubkey (ssh);
229
remmina_ssh_auth_gui (RemminaSSH *ssh, RemminaInitDialog *dialog, gboolean threaded)
235
/* Try empty password or existing password first */
236
ret = remmina_ssh_auth (ssh, NULL);
237
if (ret > 0) return 1;
239
/* Requested for a non-empty password */
242
if (!dialog) return -1;
246
case SSH_AUTH_PASSWORD:
247
tips = _("Authenticating %s's password to SSH server %s...");
248
keyname = _("SSH password");
250
case SSH_AUTH_PUBLICKEY:
251
tips = _("Authenticating %s's identity to SSH server %s...");
252
keyname = _("SSH private key passphrase");
258
if (ssh->auth != SSH_AUTH_AUTO_PUBLICKEY)
260
if (threaded) gdk_threads_enter();
261
remmina_init_dialog_set_status (dialog, tips, ssh->user, ssh->server);
263
ret = remmina_init_dialog_authpwd (dialog, keyname, FALSE);
264
if (threaded) {gdk_flush();gdk_threads_leave();}
266
if (ret != GTK_RESPONSE_OK) return -1;
268
ret = remmina_ssh_auth (ssh, dialog->password);
280
remmina_ssh_log_callback (ssh_session session, int priority, const char *message, void *userdata)
282
remmina_log_printf ("[SSH] %s\n", message);
286
remmina_ssh_init_session (RemminaSSH *ssh)
290
ssh->callback = g_new0 (struct ssh_callbacks_struct, 1);
291
ssh->callback->userdata = ssh;
293
/* Init & startup the SSH session */
294
ssh->session = ssh_new ();
295
ssh_options_set (ssh->session, SSH_OPTIONS_HOST, ssh->server);
296
ssh_options_set (ssh->session, SSH_OPTIONS_PORT, &ssh->port);
297
ssh_options_set (ssh->session, SSH_OPTIONS_USER, ssh->user);
298
if (remmina_log_running ())
300
verbosity = SSH_LOG_RARE;
301
ssh_options_set (ssh->session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
302
ssh->callback->log_function = remmina_ssh_log_callback;
304
ssh_callbacks_init (ssh->callback);
305
ssh_set_callbacks(ssh->session, ssh->callback);
307
if (ssh_connect (ssh->session))
309
remmina_ssh_set_error (ssh, _("Failed to startup SSH session: %s"));
313
/* Try the "none" authentication */
314
if (ssh_userauth_none (ssh->session, NULL) == SSH_AUTH_SUCCESS)
316
ssh->authenticated = TRUE;
322
remmina_ssh_init_from_file (RemminaSSH *ssh, RemminaFile *remminafile)
324
const gchar *ssh_server;
325
const gchar *ssh_username;
326
const gchar *ssh_privatekey;
331
ssh->callback = NULL;
332
ssh->authenticated = FALSE;
334
pthread_mutex_init (&ssh->ssh_mutex, NULL);
336
/* Parse the address and port */
337
ssh_server = remmina_file_get_string (remminafile, "ssh_server");
338
ssh_username = remmina_file_get_string (remminafile, "ssh_username");
339
ssh_privatekey = remmina_file_get_string (remminafile, "ssh_privatekey");
340
server = remmina_file_get_string (remminafile, "server");
343
remmina_public_get_server_port (ssh_server, 22, &ssh->server, &ssh->port);
344
if (ssh->server[0] == '\0')
346
g_free (ssh->server);
347
remmina_public_get_server_port (server, 0, &ssh->server, NULL);
350
else if (server == NULL)
356
remmina_public_get_server_port (server, 0, &ssh->server, NULL);
360
ssh->user = g_strdup (ssh_username ? ssh_username : g_get_user_name ());
361
ssh->password = NULL;
362
ssh->auth = remmina_file_get_int (remminafile, "ssh_auth", 0);
363
ssh->charset = g_strdup (remmina_file_get_string (remminafile, "ssh_charset"));
365
/* Public/Private keys */
366
s = (ssh_privatekey ? g_strdup (ssh_privatekey) : remmina_ssh_find_identity ());
369
ssh->privkeyfile = remmina_ssh_identity_path (s);
370
ssh->pubkeyfile = g_strdup_printf ("%s.pub", ssh->privkeyfile);
375
ssh->privkeyfile = NULL;
376
ssh->pubkeyfile = NULL;
383
remmina_ssh_init_from_ssh (RemminaSSH *ssh, const RemminaSSH *ssh_src)
386
ssh->authenticated = FALSE;
388
pthread_mutex_init (&ssh->ssh_mutex, NULL);
390
ssh->server = g_strdup (ssh_src->server);
391
ssh->port = ssh_src->port;
392
ssh->user = g_strdup (ssh_src->user);
393
ssh->auth = ssh_src->auth;
394
ssh->password = g_strdup (ssh_src->password);
395
ssh->pubkeyfile = g_strdup (ssh_src->pubkeyfile);
396
ssh->privkeyfile = g_strdup (ssh_src->privkeyfile);
397
ssh->charset = g_strdup (ssh_src->charset);
403
remmina_ssh_convert (RemminaSSH *ssh, const gchar *from)
407
if (ssh->charset && from)
409
to = g_convert (from, -1, "UTF-8", ssh->charset, NULL, NULL, NULL);
411
if (!to) to = g_strdup (from);
416
remmina_ssh_unconvert (RemminaSSH *ssh, const gchar *from)
420
if (ssh->charset && from)
422
to = g_convert (from, -1, ssh->charset, "UTF-8", NULL, NULL, NULL);
424
if (!to) to = g_strdup (from);
429
remmina_ssh_free (RemminaSSH *ssh)
433
ssh_free (ssh->session);
436
g_free (ssh->callback);
437
g_free (ssh->server);
439
g_free (ssh->password);
440
g_free (ssh->pubkeyfile);
441
g_free (ssh->privkeyfile);
442
g_free (ssh->charset);
444
pthread_mutex_destroy (&ssh->ssh_mutex);
448
/*************************** SSH Tunnel *********************************/
449
struct _RemminaSSHTunnelBuffer
456
static RemminaSSHTunnelBuffer*
457
remmina_ssh_tunnel_buffer_new (ssize_t len)
459
RemminaSSHTunnelBuffer *buffer;
461
buffer = g_new (RemminaSSHTunnelBuffer, 1);
462
buffer->data = (gchar*) g_malloc (len);
463
buffer->ptr = buffer->data;
469
remmina_ssh_tunnel_buffer_free (RemminaSSHTunnelBuffer *buffer)
473
g_free (buffer->data);
479
remmina_ssh_tunnel_new_from_file (RemminaFile *remminafile)
481
RemminaSSHTunnel *tunnel;
483
tunnel = g_new (RemminaSSHTunnel, 1);
485
remmina_ssh_init_from_file (REMMINA_SSH (tunnel), remminafile);
487
tunnel->tunnel_type = -1;
488
tunnel->channels = NULL;
489
tunnel->sockets = NULL;
490
tunnel->socketbuffers = NULL;
491
tunnel->num_channels = 0;
492
tunnel->max_channels = 0;
493
tunnel->x11_channel = NULL;
495
tunnel->running = FALSE;
496
tunnel->server_sock = -1;
499
tunnel->buffer = NULL;
500
tunnel->buffer_len = 0;
501
tunnel->channels_out = NULL;
502
tunnel->remotedisplay = 0;
503
tunnel->localdisplay = NULL;
504
tunnel->init_func = NULL;
505
tunnel->connect_func = NULL;
506
tunnel->disconnect_func = NULL;
507
tunnel->callback_data = NULL;
513
remmina_ssh_tunnel_close_all_channels (RemminaSSHTunnel *tunnel)
517
for (i = 0; i < tunnel->num_channels; i++)
519
close (tunnel->sockets[i]);
520
remmina_ssh_tunnel_buffer_free (tunnel->socketbuffers[i]);
521
channel_close (tunnel->channels[i]);
522
channel_free (tunnel->channels[i]);
525
g_free (tunnel->channels);
526
tunnel->channels = NULL;
527
g_free (tunnel->sockets);
528
tunnel->sockets = NULL;
529
g_free (tunnel->socketbuffers);
530
tunnel->socketbuffers = NULL;
532
tunnel->num_channels = 0;
533
tunnel->max_channels = 0;
535
if (tunnel->x11_channel)
537
channel_close (tunnel->x11_channel);
538
channel_free (tunnel->x11_channel);
539
tunnel->x11_channel = NULL;
544
remmina_ssh_tunnel_remove_channel (RemminaSSHTunnel *tunnel, gint n)
546
channel_close (tunnel->channels[n]);
547
channel_free (tunnel->channels[n]);
548
close (tunnel->sockets[n]);
549
remmina_ssh_tunnel_buffer_free (tunnel->socketbuffers[n]);
550
tunnel->num_channels--;
551
tunnel->channels[n] = tunnel->channels[tunnel->num_channels];
552
tunnel->channels[tunnel->num_channels] = NULL;
553
tunnel->sockets[n] = tunnel->sockets[tunnel->num_channels];
554
tunnel->socketbuffers[n] = tunnel->socketbuffers[tunnel->num_channels];
557
/* Register the new channel/socket pair */
559
remmina_ssh_tunnel_add_channel (RemminaSSHTunnel *tunnel, ssh_channel channel, gint sock)
564
i = tunnel->num_channels++;
565
if (tunnel->num_channels > tunnel->max_channels)
567
/* Allocate an extra NULL pointer in channels for ssh_select */
568
tunnel->channels = (ssh_channel*) g_realloc (tunnel->channels,
569
sizeof (ssh_channel) * (tunnel->num_channels + 1));
570
tunnel->sockets = (gint*) g_realloc (tunnel->sockets,
571
sizeof (gint) * tunnel->num_channels);
572
tunnel->socketbuffers = (RemminaSSHTunnelBuffer**) g_realloc (tunnel->socketbuffers,
573
sizeof (RemminaSSHTunnelBuffer*) * tunnel->num_channels);
574
tunnel->max_channels = tunnel->num_channels;
576
tunnel->channels_out = (ssh_channel*) g_realloc (tunnel->channels_out,
577
sizeof (ssh_channel) * (tunnel->num_channels + 1));
579
tunnel->channels[i] = channel;
580
tunnel->channels[i + 1] = NULL;
581
tunnel->sockets[i] = sock;
582
tunnel->socketbuffers[i] = NULL;
584
flags = fcntl (sock, F_GETFL, 0);
585
fcntl (sock, F_SETFL, flags | O_NONBLOCK);
589
remmina_ssh_tunnel_main_thread_proc (gpointer data)
591
RemminaSSHTunnel *tunnel = (RemminaSSHTunnel*) data;
593
ssize_t len = 0, lenw = 0;
595
struct timeval timeout;
598
ssh_channel channel = NULL;
599
gboolean first = TRUE;
600
gboolean disconnected;
605
struct sockaddr_in sin;
607
g_get_current_time (&t1);
610
switch (tunnel->tunnel_type)
612
case REMMINA_SSH_TUNNEL_OPEN:
613
/* Accept a local connection */
614
sock = accept (tunnel->server_sock, NULL, NULL);
617
REMMINA_SSH (tunnel)->error = g_strdup ("Failed to accept local socket");
622
if ((channel = channel_new (tunnel->ssh.session)) == NULL)
625
remmina_ssh_set_error (REMMINA_SSH (tunnel), "Failed to createt channel : %s");
629
/* Request the SSH server to connect to the destination */
630
if (channel_open_forward (channel, tunnel->dest, tunnel->port, "127.0.0.1", 0) != SSH_OK)
633
channel_close (channel);
634
channel_free (channel);
635
remmina_ssh_set_error (REMMINA_SSH (tunnel), _("Failed to connect to the SSH tunnel destination: %s"));
639
remmina_ssh_tunnel_add_channel (tunnel, channel, sock);
642
case REMMINA_SSH_TUNNEL_X11:
643
if ((tunnel->x11_channel = channel_new (tunnel->ssh.session)) == NULL)
645
remmina_ssh_set_error (REMMINA_SSH (tunnel), "Failed to create channel : %s");
649
if (!remmina_public_get_xauth_cookie (tunnel->localdisplay, &ptr))
651
remmina_ssh_set_application_error (REMMINA_SSH (tunnel), "%s", ptr);
656
if (channel_open_session (tunnel->x11_channel) ||
657
channel_request_x11 (tunnel->x11_channel, TRUE, NULL, ptr,
658
gdk_screen_get_number (gdk_screen_get_default ())))
661
remmina_ssh_set_error (REMMINA_SSH (tunnel), "Failed to open channel : %s");
666
if (channel_request_exec (tunnel->x11_channel, tunnel->dest))
668
ptr = g_strdup_printf (_("Failed to execute %s on SSH server : %%s"), tunnel->dest);
669
remmina_ssh_set_error (REMMINA_SSH (tunnel), ptr);
675
if (tunnel->init_func &&
676
! (*tunnel->init_func) (tunnel, tunnel->callback_data))
678
if (tunnel->disconnect_func)
680
(*tunnel->disconnect_func) (tunnel, tunnel->callback_data);
688
case REMMINA_SSH_TUNNEL_XPORT:
689
/* Detect the next available port starting from 6010 on the server */
690
for (i = 10; i <= MAX_X_DISPLAY_NUMBER; i++)
692
if (channel_forward_listen (REMMINA_SSH (tunnel)->session,
693
(tunnel->bindlocalhost ? "localhost" : NULL), 6000 + i, NULL))
699
tunnel->remotedisplay = i;
703
if (tunnel->remotedisplay < 1)
705
remmina_ssh_set_error (REMMINA_SSH (tunnel), _("Failed to request port forwarding : %s"));
706
if (tunnel->disconnect_func)
708
(*tunnel->disconnect_func) (tunnel, tunnel->callback_data);
714
if (tunnel->init_func &&
715
! (*tunnel->init_func) (tunnel, tunnel->callback_data))
717
if (tunnel->disconnect_func)
719
(*tunnel->disconnect_func) (tunnel, tunnel->callback_data);
727
case REMMINA_SSH_TUNNEL_REVERSE:
728
if (channel_forward_listen (REMMINA_SSH (tunnel)->session, NULL, tunnel->port, NULL))
730
remmina_ssh_set_error (REMMINA_SSH (tunnel), _("Failed to request port forwarding : %s"));
731
if (tunnel->disconnect_func)
733
(*tunnel->disconnect_func) (tunnel, tunnel->callback_data);
739
if (tunnel->init_func &&
740
! (*tunnel->init_func) (tunnel, tunnel->callback_data))
742
if (tunnel->disconnect_func)
744
(*tunnel->disconnect_func) (tunnel, tunnel->callback_data);
753
tunnel->buffer_len = 10240;
754
tunnel->buffer = g_malloc (tunnel->buffer_len);
756
/* Start the tunnel data transmittion */
757
while (tunnel->running)
759
if (tunnel->tunnel_type == REMMINA_SSH_TUNNEL_XPORT ||
760
tunnel->tunnel_type == REMMINA_SSH_TUNNEL_X11 ||
761
tunnel->tunnel_type == REMMINA_SSH_TUNNEL_REVERSE)
766
/* Wait for a period of time for the first incoming connection */
767
if (tunnel->tunnel_type == REMMINA_SSH_TUNNEL_X11)
769
channel = channel_accept_x11 (tunnel->x11_channel, 15000);
773
channel = channel_forward_accept (REMMINA_SSH (tunnel)->session, 15000);
777
remmina_ssh_set_application_error (REMMINA_SSH (tunnel), _("No response from the server."));
778
if (tunnel->disconnect_func)
780
(*tunnel->disconnect_func) (tunnel, tunnel->callback_data);
785
if (tunnel->connect_func)
787
(*tunnel->connect_func) (tunnel, tunnel->callback_data);
789
if (tunnel->tunnel_type == REMMINA_SSH_TUNNEL_REVERSE)
791
/* For reverse tunnel, we only need one connection. */
792
channel_forward_cancel (REMMINA_SSH (tunnel)->session, NULL, tunnel->port);
795
else if (tunnel->tunnel_type != REMMINA_SSH_TUNNEL_REVERSE)
797
/* Poll once per some period of time if no incoming connections.
798
* Don't try to poll continuously as it will significantly slow down the loop */
799
g_get_current_time (&t1);
800
diff = (t1.tv_sec - t2.tv_sec) * 10 + (t1.tv_usec - t2.tv_usec) / 100000;
803
if (tunnel->tunnel_type == REMMINA_SSH_TUNNEL_X11)
805
channel = channel_accept_x11 (tunnel->x11_channel, 0);
809
channel = channel_forward_accept (REMMINA_SSH (tunnel)->session, 0);
820
if (tunnel->tunnel_type == REMMINA_SSH_TUNNEL_REVERSE)
822
sin.sin_family = AF_INET;
823
sin.sin_port = htons (tunnel->localport);
824
sin.sin_addr.s_addr = inet_addr ("127.0.0.1");
825
sock = socket (AF_INET, SOCK_STREAM, 0);
826
if (connect (sock, (struct sockaddr *) &sin, sizeof (sin)) < 0)
828
remmina_ssh_set_application_error (REMMINA_SSH (tunnel),
829
"Cannot connect to local port %i.", tunnel->localport);
836
sock = remmina_public_open_xdisplay (tunnel->localdisplay);
840
remmina_ssh_tunnel_add_channel (tunnel, channel, sock);
844
/* Failed to create unix socket. Will this happen? */
845
channel_close (channel);
846
channel_free (channel);
852
if (tunnel->num_channels <= 0)
854
/* No more connections. We should quit */
859
timeout.tv_usec = 200000;
863
for (i = 0; i < tunnel->num_channels; i++)
865
if (tunnel->sockets[i] > maxfd)
867
maxfd = tunnel->sockets[i];
869
FD_SET (tunnel->sockets[i], &set);
872
ret = ssh_select (tunnel->channels, tunnel->channels_out, maxfd + 1, &set, &timeout);
873
if (!tunnel->running) break;
874
if (ret == SSH_EINTR) continue;
875
if (ret == -1) break;
878
while (tunnel->running && i < tunnel->num_channels)
880
disconnected = FALSE;
881
if (FD_ISSET (tunnel->sockets[i], &set))
883
while (!disconnected &&
884
(len = read (tunnel->sockets[i], tunnel->buffer, tunnel->buffer_len)) > 0)
886
for (ptr = tunnel->buffer, lenw = 0; len > 0; len -= lenw, ptr += lenw)
888
lenw = channel_write (tunnel->channels[i], (char*) ptr, len);
896
if (len == 0) disconnected = TRUE;
900
remmina_ssh_tunnel_remove_channel (tunnel, i);
905
if (!tunnel->running) break;
908
while (tunnel->running && i < tunnel->num_channels)
910
disconnected = FALSE;
912
if (!tunnel->socketbuffers[i])
914
len = channel_poll (tunnel->channels[i], 0);
915
if (len == SSH_ERROR || len == SSH_EOF)
921
tunnel->socketbuffers[i] = remmina_ssh_tunnel_buffer_new (len);
922
len = channel_read_nonblocking (tunnel->channels[i], tunnel->socketbuffers[i]->data, len, 0);
929
tunnel->socketbuffers[i]->len = len;
934
if (!disconnected && tunnel->socketbuffers[i])
936
for (lenw = 0; tunnel->socketbuffers[i]->len > 0;
937
tunnel->socketbuffers[i]->len -= lenw, tunnel->socketbuffers[i]->ptr += lenw)
939
lenw = write (tunnel->sockets[i], tunnel->socketbuffers[i]->ptr, tunnel->socketbuffers[i]->len);
940
if (lenw == -1 && errno == EAGAIN && tunnel->running)
942
/* Sometimes we cannot write to a socket (always EAGAIN), probably because it's internal
943
* buffer is full. We need read the pending bytes from the socket first. so here we simply
944
* break, leave the buffer there, and continue with other data */
953
if (tunnel->socketbuffers[i]->len <= 0)
955
remmina_ssh_tunnel_buffer_free (tunnel->socketbuffers[i]);
956
tunnel->socketbuffers[i] = NULL;
962
remmina_ssh_tunnel_remove_channel (tunnel, i);
969
remmina_ssh_tunnel_close_all_channels (tunnel);
975
remmina_ssh_tunnel_main_thread (gpointer data)
977
RemminaSSHTunnel *tunnel = (RemminaSSHTunnel*) data;
979
pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL);
983
remmina_ssh_tunnel_main_thread_proc (data);
984
if (tunnel->server_sock < 0 || tunnel->thread == 0 || !tunnel->running) break;
991
remmina_ssh_tunnel_cancel_accept (RemminaSSHTunnel *tunnel)
993
if (tunnel->server_sock >= 0)
995
close (tunnel->server_sock);
996
tunnel->server_sock = -1;
1001
remmina_ssh_tunnel_open (RemminaSSHTunnel* tunnel, const gchar *host, gint port, gint local_port)
1005
struct sockaddr_in sin;
1007
tunnel->tunnel_type = REMMINA_SSH_TUNNEL_OPEN;
1008
tunnel->dest = g_strdup (host);
1009
tunnel->port = port;
1010
if (tunnel->port == 0)
1012
REMMINA_SSH (tunnel)->error = g_strdup ("Destination port has not been assigned");
1016
/* Create the server socket that listens on the local port */
1017
sock = socket (AF_INET, SOCK_STREAM, 0);
1020
REMMINA_SSH (tunnel)->error = g_strdup ("Failed to create socket.");
1023
setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof (sockopt));
1025
sin.sin_family = AF_INET;
1026
sin.sin_port = htons (local_port);
1027
sin.sin_addr.s_addr = inet_addr ("127.0.0.1");
1029
if (bind (sock, (struct sockaddr *) &sin, sizeof(sin)))
1031
REMMINA_SSH (tunnel)->error = g_strdup ("Failed to bind on local port.");
1036
if (listen (sock, 1))
1038
REMMINA_SSH (tunnel)->error = g_strdup ("Failed to listen on local port.");
1043
tunnel->server_sock = sock;
1044
tunnel->running = TRUE;
1046
if (pthread_create (&tunnel->thread, NULL, remmina_ssh_tunnel_main_thread, tunnel))
1048
remmina_ssh_set_application_error (REMMINA_SSH (tunnel), "Failed to initialize pthread.");
1056
remmina_ssh_tunnel_x11 (RemminaSSHTunnel *tunnel, const gchar *cmd)
1058
tunnel->tunnel_type = REMMINA_SSH_TUNNEL_X11;
1059
tunnel->dest = g_strdup (cmd);
1060
tunnel->running = TRUE;
1062
if (pthread_create (&tunnel->thread, NULL, remmina_ssh_tunnel_main_thread, tunnel))
1064
remmina_ssh_set_application_error (REMMINA_SSH (tunnel), "Failed to initialize pthread.");
1072
remmina_ssh_tunnel_xport (RemminaSSHTunnel *tunnel, gboolean bindlocalhost)
1074
tunnel->tunnel_type = REMMINA_SSH_TUNNEL_XPORT;
1075
tunnel->bindlocalhost = bindlocalhost;
1076
tunnel->running = TRUE;
1078
if (pthread_create (&tunnel->thread, NULL, remmina_ssh_tunnel_main_thread, tunnel))
1080
remmina_ssh_set_application_error (REMMINA_SSH (tunnel), "Failed to initialize pthread.");
1088
remmina_ssh_tunnel_reverse (RemminaSSHTunnel *tunnel, gint port, gint local_port)
1090
tunnel->tunnel_type = REMMINA_SSH_TUNNEL_REVERSE;
1091
tunnel->port = port;
1092
tunnel->localport = local_port;
1093
tunnel->running = TRUE;
1095
if (pthread_create (&tunnel->thread, NULL, remmina_ssh_tunnel_main_thread, tunnel))
1097
remmina_ssh_set_application_error (REMMINA_SSH (tunnel), "Failed to initialize pthread.");
1105
remmina_ssh_tunnel_terminated (RemminaSSHTunnel* tunnel)
1107
return (tunnel->thread == 0);
1111
remmina_ssh_tunnel_free (RemminaSSHTunnel* tunnel)
1115
thread = tunnel->thread;
1118
tunnel->running = FALSE;
1119
pthread_cancel (thread);
1120
pthread_join (thread, NULL);
1124
if (tunnel->tunnel_type == REMMINA_SSH_TUNNEL_XPORT && tunnel->remotedisplay > 0)
1126
channel_forward_cancel (REMMINA_SSH (tunnel)->session,
1127
NULL, 6000 + tunnel->remotedisplay);
1129
if (tunnel->server_sock >= 0)
1131
close (tunnel->server_sock);
1132
tunnel->server_sock = -1;
1134
remmina_ssh_tunnel_close_all_channels (tunnel);
1136
g_free (tunnel->buffer);
1137
g_free (tunnel->channels_out);
1138
g_free (tunnel->dest);
1139
g_free (tunnel->localdisplay);
1141
remmina_ssh_free (REMMINA_SSH (tunnel));
1144
/*************************** SFTP *********************************/
1147
remmina_sftp_new_from_file (RemminaFile *remminafile)
1151
sftp = g_new (RemminaSFTP, 1);
1153
remmina_ssh_init_from_file (REMMINA_SSH (sftp), remminafile);
1155
sftp->sftp_sess = NULL;
1161
remmina_sftp_new_from_ssh (RemminaSSH *ssh)
1165
sftp = g_new (RemminaSFTP, 1);
1167
remmina_ssh_init_from_ssh (REMMINA_SSH (sftp), ssh);
1169
sftp->sftp_sess = NULL;
1175
remmina_sftp_open (RemminaSFTP *sftp)
1177
sftp->sftp_sess = sftp_new (sftp->ssh.session);
1178
if (!sftp->sftp_sess)
1180
remmina_ssh_set_error (REMMINA_SSH (sftp), _("Failed to create sftp session: %s"));
1183
if (sftp_init (sftp->sftp_sess))
1185
remmina_ssh_set_error (REMMINA_SSH (sftp), _("Failed to initialize sftp session: %s"));
1192
remmina_sftp_free (RemminaSFTP *sftp)
1194
if (sftp->sftp_sess)
1196
sftp_free (sftp->sftp_sess);
1197
sftp->sftp_sess = NULL;
1199
remmina_ssh_free (REMMINA_SSH (sftp));
1202
/*************************** SSH Shell *********************************/
1205
remmina_ssh_shell_new_from_file (RemminaFile *remminafile)
1207
RemminaSSHShell *shell;
1209
shell = g_new0 (RemminaSSHShell, 1);
1211
remmina_ssh_init_from_file (REMMINA_SSH (shell), remminafile);
1215
shell->exec = g_strdup (remmina_file_get_string (remminafile, "exec"));
1221
remmina_ssh_shell_new_from_ssh (RemminaSSH *ssh)
1223
RemminaSSHShell *shell;
1225
shell = g_new0 (RemminaSSHShell, 1);
1227
remmina_ssh_init_from_ssh (REMMINA_SSH (shell), ssh);
1236
remmina_ssh_shell_thread (gpointer data)
1238
RemminaSSHShell *shell = (RemminaSSHShell*) data;
1240
struct timeval timeout;
1241
ssh_channel channel = NULL;
1242
ssh_channel ch[2], chout[2];
1250
if ((channel = channel_new (REMMINA_SSH (shell)->session)) == NULL ||
1251
channel_open_session (channel))
1254
remmina_ssh_set_error (REMMINA_SSH (shell), "Failed to open channel : %s");
1255
if (channel) channel_free (channel);
1260
channel_request_pty (channel);
1261
if (shell->exec && shell->exec[0])
1263
ret = channel_request_exec (channel, shell->exec);
1267
ret = channel_request_shell (channel);
1272
remmina_ssh_set_error (REMMINA_SSH (shell), "Failed to request shell : %s");
1273
channel_close (channel);
1274
channel_free (channel);
1279
shell->channel = channel;
1284
buf = g_malloc (buf_len + 1);
1289
while (!shell->closed)
1292
timeout.tv_usec = 0;
1295
FD_SET (shell->master, &fds);
1297
ret = ssh_select (ch, chout, shell->master + 1, &fds, &timeout);
1298
if (ret == SSH_EINTR) continue;
1299
if (ret == -1) break;
1301
if (FD_ISSET (shell->master, &fds))
1303
len = read (shell->master, buf, buf_len);
1304
if (len <= 0) break;
1306
channel_write (channel, buf, len);
1309
for (i = 0; i < 2; i++)
1312
len = channel_poll (channel, i);
1314
if (len == SSH_ERROR || len == SSH_EOF)
1316
shell->closed = TRUE;
1319
if (len <= 0) continue;
1323
buf = (gchar*) g_realloc (buf, buf_len + 1);
1326
len = channel_read_nonblocking (channel, buf, len, i);
1330
shell->closed = TRUE;
1335
ret = write (shell->master, buf, len);
1336
if (ret <= 0) break;
1343
shell->channel = NULL;
1344
channel_close (channel);
1345
channel_free (channel);
1351
if (shell->exit_callback) shell->exit_callback (shell->user_data);
1356
remmina_ssh_shell_open (RemminaSSHShell *shell, RemminaSSHExitFunc exit_callback, gpointer data)
1359
struct termios stermios;
1361
shell->master = posix_openpt (O_RDWR | O_NOCTTY);
1362
if (shell->master == -1 ||
1363
grantpt (shell->master) == -1 ||
1364
unlockpt (shell->master) == -1 ||
1365
(slavedevice = ptsname (shell->master)) == NULL ||
1366
(shell->slave = open (slavedevice, O_RDWR | O_NOCTTY)) < 0)
1368
REMMINA_SSH (shell)->error = g_strdup ("Failed to create pty device.");
1372
/* These settings works fine with OpenSSH... */
1373
tcgetattr (shell->slave, &stermios);
1374
stermios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL | ICANON);
1375
stermios.c_iflag &= ~(ICRNL);
1376
tcsetattr (shell->slave, TCSANOW, &stermios);
1378
shell->exit_callback = exit_callback;
1379
shell->user_data = data;
1381
/* Once the process started, we should always TRUE and assume the pthread will be created always */
1382
pthread_create (&shell->thread, NULL, remmina_ssh_shell_thread, shell);
1388
remmina_ssh_shell_set_size (RemminaSSHShell *shell, gint columns, gint rows)
1393
channel_change_pty_size (shell->channel, columns, rows);
1399
remmina_ssh_shell_free (RemminaSSHShell *shell)
1401
pthread_t thread = shell->thread;
1403
shell->exit_callback = NULL;
1406
shell->closed = TRUE;
1407
pthread_join (thread, NULL);
1409
close (shell->master);
1412
g_free (shell->exec);
1415
/* It's not necessary to close shell->slave since the other end (vte) will close it */;
1416
remmina_ssh_free (REMMINA_SSH (shell));
1419
#endif /* HAVE_LIBSSH */