-
-
Notifications
You must be signed in to change notification settings - Fork 499
/
Copy pathsshtunnel.c
153 lines (119 loc) · 3.99 KB
/
sshtunnel.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/**
* @example sshtunnel.c
* An example of an RFB client tunneled through SSH by using https://github.com/bk138/libsshtunnel
*/
#include <rfb/rfbclient.h>
#include <libsshtunnel.h>
#include <signal.h>
/* The one global bool that's global so we can set it via
a signal handler... */
int maintain_connection = 1;
void intHandler(int dummy) {
maintain_connection = 0;
}
void ssh_signal_error(void *client,
ssh_tunnel_error_t error_code,
const char *error_message) {
fprintf(stderr, "libsshtunnel error: %s", error_message);
}
int ssh_fingerprint_check(void* client,
const char *fingerprint,
int fingerprint_len,
const char *host) {
fprintf(stderr, "ssh_fingerprint_check: host %s has ", host);
for(int i = 0; i < fingerprint_len; i++)
printf("%02X ", (unsigned char)fingerprint[i]);
printf("\n");
return 0;
}
int main(int argc, char *argv[])
{
rfbClient *client = rfbGetClient(8,3,4);
/*
Get args and create SSH tunnel
*/
int rc = ssh_tunnel_init();
if(rc) {
fprintf(stderr, "Tunnel initialization failed (%d)\n", rc);
return EXIT_FAILURE;
}
ssh_tunnel_t *data;
if (argc == 6) {
/* SSH tunnel w/ password */
data = ssh_tunnel_open_with_password(argv[1], argv[2], argv[3], argv[4], atoi(argv[5]), client, ssh_fingerprint_check, ssh_signal_error);
} else if (argc == 7) {
/* SSH tunnel w/ privkey */
FILE *privkey_file;
char *privkey_buffer;
long privkey_buffer_len;
// Open the file in binary mode for reading
privkey_file = fopen(argv[3], "rb");
if (privkey_file == NULL) {
perror("Error opening privkey");
return EXIT_FAILURE;
}
// Determine the size of the file
fseek(privkey_file, 0, SEEK_END);
privkey_buffer_len = ftell(privkey_file);
fseek(privkey_file, 0, SEEK_SET);
if (privkey_buffer_len == -1) {
perror("Error getting file size of privkey");
fclose(privkey_file);
return EXIT_FAILURE;
}
// Allocate memory for the buffer
privkey_buffer = (char *)malloc(privkey_buffer_len);
if (privkey_buffer == NULL) {
perror("Error allocating memory for privkey");
fclose(privkey_file);
return EXIT_FAILURE;
}
// Read the content of the file into the buffer
fread(privkey_buffer, 1, privkey_buffer_len, privkey_file);
if (ferror(privkey_file) != 0) {
perror("Error reading privkey");
fclose(privkey_file);
free(privkey_buffer);
return EXIT_FAILURE;
}
// Close the file
fclose(privkey_file);
data = ssh_tunnel_open_with_privkey(argv[1], argv[2], privkey_buffer, privkey_buffer_len, argv[4], argv[5], atoi(argv[6]), client, ssh_fingerprint_check, ssh_signal_error);
free(privkey_buffer);
} else {
fprintf(stderr,
"Usage (w/ password): %s <ssh-server-host> <ssh-server-username> <ssh-server-password> <rfb-host> <rfb-port>\n"
"Usage (w/ privkey): %s <ssh-server-host> <ssh-server-username> <privkey_filename> <privkey_password> <rfb-host> <rfb-port>\n",
argv[0], argv[0]);
return(EXIT_FAILURE);
}
/*
The actual VNC connection setup.
*/
client->serverHost = strdup("127.0.0.1");
if(data) // might be NULL if ssh setup failed
client->serverPort = ssh_tunnel_get_port(data);
rfbClientSetClientData(client, (void*)42, data);
if (!data || !rfbInitClient(client,NULL,NULL))
return EXIT_FAILURE;
printf("Successfully connected to %s:%d - hit Ctrl-C to disconnect\n", client->serverHost, client->serverPort);
signal(SIGINT, intHandler);
while (maintain_connection) {
int n = WaitForMessage(client,50);
if(n < 0)
break;
if(n)
if(!HandleRFBServerMessage(client))
break;
}
/* Disconnect client inside tunnel */
if(client && client->sock != RFB_INVALID_SOCKET)
rfbCloseSocket(client->sock);
/* Close the tunnel and clean up */
ssh_tunnel_close(rfbClientGetClientData(client, (void*)42));
/* free client */
rfbClientCleanup(client);
/* Teardown ssh tunnel machinery */
ssh_tunnel_exit();
return EXIT_SUCCESS;
}