10
#include "libssh2_setup.h"
17
#ifdef HAVE_SYS_IOCTL_H
20
#ifdef HAVE_NETINET_IN_H
21
#include <netinet/in.h>
23
#ifdef HAVE_SYS_SOCKET_H
24
#include <sys/socket.h>
29
#ifdef HAVE_ARPA_INET_H
41
#define _PATH_UNIX_X "/tmp/.X11-unix/X%d"
48
LIBSSH2_CHANNEL *chan;
49
libssh2_socket_t sock;
50
struct chan_X11_list *next;
53
static struct chan_X11_list * gp_x11_chan = NULL;
54
static struct termios _saved_tio;
59
static void remove_node(struct chan_X11_list *elem)
61
struct chan_X11_list *current_node = NULL;
63
current_node = gp_x11_chan;
65
if(gp_x11_chan == elem) {
66
gp_x11_chan = gp_x11_chan->next;
71
while(current_node->next) {
72
if(current_node->next == elem) {
73
current_node->next = current_node->next->next;
74
current_node = current_node->next;
82
static void session_shutdown(LIBSSH2_SESSION *session)
84
libssh2_session_disconnect(session, "Normal Shutdown");
85
libssh2_session_free(session);
88
static int _raw_mode(void)
93
rc = tcgetattr(fileno(stdin), &tio);
97
tio.c_iflag &= ~(tcflag_t)(IGNBRK|BRKINT|PARMRK|ISTRIP|
98
INLCR|IGNCR|ICRNL|IXON);
99
tio.c_oflag &= ~(tcflag_t)OPOST;
100
tio.c_lflag &= ~(tcflag_t)(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
101
tio.c_cflag &= ~(tcflag_t)(CSIZE|PARENB);
103
rc = tcsetattr(fileno(stdin), TCSADRAIN, &tio);
108
static int _normal_mode(void)
111
rc = tcsetattr(fileno(stdin), TCSADRAIN, &_saved_tio);
120
static void x11_callback(LIBSSH2_SESSION *session, LIBSSH2_CHANNEL *channel,
121
char *shost, int sport, void **abstract)
128
libssh2_socket_t sock = LIBSSH2_INVALID_SOCKET;
129
struct sockaddr_un addr;
130
struct chan_X11_list *new;
131
struct chan_X11_list *chan_iter;
140
display = getenv("DISPLAY");
142
if(strncmp(display, "unix:", 5) == 0 ||
145
ptr = strrchr(display, ':');
146
temp_buff = (char *)calloc(strlen(ptr + 1) + 1, sizeof(char));
148
fprintf(stderr, "failed to calloc().\n");
151
memcpy(temp_buff, ptr + 1, strlen(ptr + 1));
152
display_port = atoi(temp_buff);
155
sock = socket(AF_UNIX, SOCK_STREAM, 0);
156
if(sock == LIBSSH2_INVALID_SOCKET)
158
memset(&addr, 0, sizeof(addr));
159
addr.sun_family = AF_UNIX;
160
snprintf(addr.sun_path, sizeof(addr.sun_path),
161
_PATH_UNIX_X, display_port);
162
rc = connect(sock, (struct sockaddr *) &addr, sizeof(addr));
168
gp_x11_chan = (struct chan_X11_list *)
169
calloc(1, sizeof(struct chan_X11_list));
170
gp_x11_chan->sock = sock;
171
gp_x11_chan->chan = channel;
172
gp_x11_chan->next = NULL;
175
chan_iter = gp_x11_chan;
176
while(chan_iter->next)
177
chan_iter = chan_iter->next;
179
new = (struct chan_X11_list *)
180
malloc(sizeof(struct chan_X11_list));
184
chan_iter->next = new;
188
shutdown(sock, SHUT_RDWR);
189
LIBSSH2_SOCKET_CLOSE(sock);
200
static int x11_send_receive(LIBSSH2_CHANNEL *channel, libssh2_socket_t sock)
203
unsigned int bufsize = 8192;
205
unsigned int nfds = 1;
206
LIBSSH2_POLLFD *fds = NULL;
208
struct timeval timeval_out;
209
timeval_out.tv_sec = 0;
210
timeval_out.tv_usec = 0;
214
#pragma GCC diagnostic push
215
#pragma GCC diagnostic ignored "-Wsign-conversion"
219
#pragma GCC diagnostic pop
222
buf = calloc(bufsize, sizeof(char));
226
fds = malloc(sizeof(LIBSSH2_POLLFD));
232
fds[0].type = LIBSSH2_POLLFD_CHANNEL;
233
fds[0].fd.channel = channel;
234
fds[0].events = LIBSSH2_POLLFD_POLLIN;
235
fds[0].revents = LIBSSH2_POLLFD_POLLIN;
237
rc = libssh2_poll(fds, nfds, 0);
240
nread = libssh2_channel_read(channel, buf, bufsize);
242
write(sock, buf, (size_t)nread);
245
rc = select((int)(sock + 1), &set, NULL, NULL, &timeval_out);
249
memset(buf, 0, bufsize);
252
nread = read(sock, buf, bufsize);
254
libssh2_channel_write(channel, buf, (size_t)nread);
264
if(libssh2_channel_eof(channel) == 1) {
273
int main(int argc, char *argv[])
275
uint32_t hostaddr = 0;
277
libssh2_socket_t sock = LIBSSH2_INVALID_SOCKET;
278
struct sockaddr_in sin;
279
LIBSSH2_SESSION *session = NULL;
280
LIBSSH2_CHANNEL *channel;
281
char *username = NULL;
282
char *password = NULL;
283
size_t bufsiz = 8193;
285
int set_debug_on = 0;
286
unsigned int nfds = 1;
287
LIBSSH2_POLLFD *fds = NULL;
290
struct chan_X11_list *current_node = NULL;
293
struct winsize w_size;
294
struct winsize w_size_bck;
298
struct timeval timeval_out;
299
timeval_out.tv_sec = 0;
300
timeval_out.tv_usec = 10;
303
hostaddr = inet_addr(argv[1]);
308
fprintf(stderr, "Usage: %s destination username password",
315
fprintf(stderr, "DEBUG is ON: %d\n", set_debug_on);
318
rc = libssh2_init(0);
320
fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
324
sock = socket(AF_INET, SOCK_STREAM, 0);
325
if(sock == LIBSSH2_INVALID_SOCKET) {
326
fprintf(stderr, "failed to open socket.\n");
330
sin.sin_family = AF_INET;
331
sin.sin_port = htons(22);
332
sin.sin_addr.s_addr = hostaddr;
334
if(connect(sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in))) {
335
fprintf(stderr, "Failed to established connection.\n");
339
session = libssh2_session_init();
340
rc = libssh2_session_handshake(session, sock);
342
fprintf(stderr, "Failed Start the SSH session\n");
346
if(set_debug_on == 1)
347
libssh2_trace(session, LIBSSH2_TRACE_CONN);
350
libssh2_session_callback_set2(session, LIBSSH2_CALLBACK_X11,
351
(libssh2_cb_generic *)x11_callback);
354
rc = libssh2_userauth_password(session, username, password);
356
fprintf(stderr, "Failed to authenticate\n");
357
session_shutdown(session);
358
shutdown(sock, SHUT_RDWR);
359
LIBSSH2_SOCKET_CLOSE(sock);
364
channel = libssh2_channel_open_session(session);
366
fprintf(stderr, "Failed to open a new channel\n");
367
session_shutdown(session);
368
shutdown(sock, SHUT_RDWR);
369
LIBSSH2_SOCKET_CLOSE(sock);
374
rc = libssh2_channel_request_pty(channel, "xterm");
376
fprintf(stderr, "Failed to request a pty\n");
377
session_shutdown(session);
378
shutdown(sock, SHUT_RDWR);
379
LIBSSH2_SOCKET_CLOSE(sock);
384
rc = libssh2_channel_x11_req(channel, 0);
386
fprintf(stderr, "Failed to request X11 forwarding\n");
387
session_shutdown(session);
388
shutdown(sock, SHUT_RDWR);
389
LIBSSH2_SOCKET_CLOSE(sock);
394
rc = libssh2_channel_shell(channel);
396
fprintf(stderr, "Failed to open a shell\n");
397
session_shutdown(session);
398
shutdown(sock, SHUT_RDWR);
399
LIBSSH2_SOCKET_CLOSE(sock);
405
fprintf(stderr, "Failed to entered in raw mode\n");
406
session_shutdown(session);
407
shutdown(sock, SHUT_RDWR);
408
LIBSSH2_SOCKET_CLOSE(sock);
412
memset(&w_size, 0, sizeof(struct winsize));
413
memset(&w_size_bck, 0, sizeof(struct winsize));
419
#pragma GCC diagnostic push
420
#pragma GCC diagnostic ignored "-Wsign-conversion"
422
FD_SET(fileno(stdin), &set);
424
#pragma GCC diagnostic pop
428
ioctl(fileno(stdin), TIOCGWINSZ, &w_size);
429
if((w_size.ws_row != w_size_bck.ws_row) ||
430
(w_size.ws_col != w_size_bck.ws_col)) {
433
libssh2_channel_request_pty_size(channel,
438
buf = calloc(bufsiz, sizeof(char));
442
fds = malloc(sizeof(LIBSSH2_POLLFD));
448
fds[0].type = LIBSSH2_POLLFD_CHANNEL;
449
fds[0].fd.channel = channel;
450
fds[0].events = LIBSSH2_POLLFD_POLLIN;
451
fds[0].revents = LIBSSH2_POLLFD_POLLIN;
453
rc = libssh2_poll(fds, nfds, 0);
455
libssh2_channel_read(channel, buf, sizeof(buf));
456
fprintf(stdout, "%s", buf);
462
current_node = gp_x11_chan;
467
while(current_node) {
468
struct chan_X11_list *next_node;
469
rc = x11_send_receive(current_node->chan, current_node->sock);
470
next_node = current_node->next;
472
shutdown(current_node->sock, SHUT_RDWR);
473
LIBSSH2_SOCKET_CLOSE(current_node->sock);
474
remove_node(current_node);
477
current_node = next_node;
480
rc = select((int)(fileno(stdin) + 1), &set, NULL, NULL, &timeval_out);
485
nread = read(fileno(stdin), buf, 1);
487
libssh2_channel_write(channel, buf, sizeof(buf));
493
if(libssh2_channel_eof(channel) == 1) {
499
libssh2_channel_free(channel);
513
fprintf(stderr, "Sorry, this platform is not supported.");