]> git.proxmox.com Git - rustc.git/blob - src/vendor/libssh2-sys/libssh2/example/ssh2_echo.c
New upstream version 1.19.0+dfsg1
[rustc.git] / src / vendor / libssh2-sys / libssh2 / example / ssh2_echo.c
1 /*
2 * Run it like this:
3 *
4 * $ ./ssh2_echo 127.0.0.1 user password
5 *
6 * The code sends a 'cat' command, and then writes a lot of data to it only to
7 * check that reading the returned data sums up to the same amount.
8 *
9 */
10
11 #include "libssh2_config.h"
12 #include <libssh2.h>
13
14 #ifdef HAVE_WINSOCK2_H
15 # include <winsock2.h>
16 #endif
17 #ifdef HAVE_SYS_SOCKET_H
18 # include <sys/socket.h>
19 #endif
20 #ifdef HAVE_NETINET_IN_H
21 # include <netinet/in.h>
22 #endif
23 #ifdef HAVE_SYS_SELECT_H
24 # include <sys/select.h>
25 #endif
26 # ifdef HAVE_UNISTD_H
27 #include <unistd.h>
28 #endif
29 #ifdef HAVE_ARPA_INET_H
30 # include <arpa/inet.h>
31 #endif
32 #ifdef HAVE_SYS_TIME_H
33 #include <sys/time.h>
34 #endif
35 #include <sys/types.h>
36 #ifdef HAVE_STDLIB_H
37 #include <stdlib.h>
38 #endif
39 #include <fcntl.h>
40 #include <errno.h>
41 #include <stdio.h>
42 #include <ctype.h>
43
44 static int waitsocket(int socket_fd, LIBSSH2_SESSION *session)
45 {
46 struct timeval timeout;
47 int rc;
48 fd_set fd;
49 fd_set *writefd = NULL;
50 fd_set *readfd = NULL;
51 int dir;
52
53 timeout.tv_sec = 10;
54 timeout.tv_usec = 0;
55
56 FD_ZERO(&fd);
57
58 FD_SET(socket_fd, &fd);
59
60 /* now make sure we wait in the correct direction */
61 dir = libssh2_session_block_directions(session);
62
63 if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
64 readfd = &fd;
65
66 if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
67 writefd = &fd;
68
69 rc = select(socket_fd + 1, readfd, writefd, NULL, &timeout);
70
71 return rc;
72 }
73
74 #define BUFSIZE 32000
75
76 int main(int argc, char *argv[])
77 {
78 const char *hostname = "127.0.0.1";
79 const char *commandline = "cat";
80 const char *username = "user";
81 const char *password = "password";
82 unsigned long hostaddr;
83 int sock;
84 struct sockaddr_in sin;
85 const char *fingerprint;
86 LIBSSH2_SESSION *session;
87 LIBSSH2_CHANNEL *channel;
88 int rc;
89 int exitcode = 0;
90 char *exitsignal=(char *)"none";
91 size_t len;
92 LIBSSH2_KNOWNHOSTS *nh;
93 int type;
94
95 #ifdef WIN32
96 WSADATA wsadata;
97 int err;
98
99 err = WSAStartup(MAKEWORD(2,0), &wsadata);
100 if (err != 0) {
101 fprintf(stderr, "WSAStartup failed with error: %d\n", err);
102 return 1;
103 }
104 #endif
105
106 if (argc > 1)
107 /* must be ip address only */
108 hostname = argv[1];
109
110 if (argc > 2) {
111 username = argv[2];
112 }
113 if (argc > 3) {
114 password = argv[3];
115 }
116
117 rc = libssh2_init (0);
118 if (rc != 0) {
119 fprintf (stderr, "libssh2 initialization failed (%d)\n", rc);
120 return 1;
121 }
122
123 hostaddr = inet_addr(hostname);
124
125 /* Ultra basic "connect to port 22 on localhost"
126 * Your code is responsible for creating the socket establishing the
127 * connection
128 */
129 sock = socket(AF_INET, SOCK_STREAM, 0);
130
131 sin.sin_family = AF_INET;
132 sin.sin_port = htons(22);
133 sin.sin_addr.s_addr = hostaddr;
134 if (connect(sock, (struct sockaddr*)(&sin),
135 sizeof(struct sockaddr_in)) != 0) {
136 fprintf(stderr, "failed to connect!\n");
137 return -1;
138 }
139
140 /* Create a session instance */
141 session = libssh2_session_init();
142 if (!session)
143 return -1;
144
145 /* tell libssh2 we want it all done non-blocking */
146 libssh2_session_set_blocking(session, 0);
147
148 /* ... start it up. This will trade welcome banners, exchange keys,
149 * and setup crypto, compression, and MAC layers
150 */
151 while ((rc = libssh2_session_handshake(session, sock)) ==
152 LIBSSH2_ERROR_EAGAIN);
153 if (rc) {
154 fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
155 return -1;
156 }
157
158 nh = libssh2_knownhost_init(session);
159 if(!nh) {
160 /* eeek, do cleanup here */
161 return 2;
162 }
163
164 /* read all hosts from here */
165 libssh2_knownhost_readfile(nh, "known_hosts",
166 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
167
168 /* store all known hosts to here */
169 libssh2_knownhost_writefile(nh, "dumpfile",
170 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
171
172 fingerprint = libssh2_session_hostkey(session, &len, &type);
173 if(fingerprint) {
174 struct libssh2_knownhost *host;
175 int check = libssh2_knownhost_checkp(nh, hostname, 22,
176 fingerprint, len,
177 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
178 LIBSSH2_KNOWNHOST_KEYENC_RAW,
179 &host);
180
181 fprintf(stderr, "Host check: %d, key: %s\n", check,
182 (check <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
183 host->key:"<none>");
184
185 /*****
186 * At this point, we could verify that 'check' tells us the key is
187 * fine or bail out.
188 *****/
189 }
190 else {
191 /* eeek, do cleanup here */
192 return 3;
193 }
194 libssh2_knownhost_free(nh);
195
196 if ( strlen(password) != 0 ) {
197 /* We could authenticate via password */
198 while ((rc = libssh2_userauth_password(session, username, password)) ==
199 LIBSSH2_ERROR_EAGAIN);
200 if (rc) {
201 fprintf(stderr, "Authentication by password failed.\n");
202 exit(1);
203 }
204 }
205
206 libssh2_trace(session, LIBSSH2_TRACE_SOCKET);
207
208 /* Exec non-blocking on the remove host */
209 while( (channel = libssh2_channel_open_session(session)) == NULL &&
210 libssh2_session_last_error(session,NULL,NULL,0) ==
211 LIBSSH2_ERROR_EAGAIN ) {
212 waitsocket(sock, session);
213 }
214 if( channel == NULL ) {
215 fprintf(stderr,"Error\n");
216 exit( 1 );
217 }
218 while( (rc = libssh2_channel_exec(channel, commandline)) ==
219 LIBSSH2_ERROR_EAGAIN )
220 waitsocket(sock, session);
221
222 if( rc != 0 ) {
223 fprintf(stderr, "exec error\n");
224 exit( 1 );
225 }
226 else {
227 LIBSSH2_POLLFD *fds = NULL;
228 int running = 1;
229 int bufsize = BUFSIZE;
230 char buffer[BUFSIZE];
231 int totsize = 1500000;
232 int totwritten = 0;
233 int totread = 0;
234 int partials = 0;
235 int rereads = 0;
236 int rewrites = 0;
237 int i;
238
239 for (i = 0; i < BUFSIZE; i++)
240 buffer[i] = 'A';
241
242 if ((fds = malloc (sizeof (LIBSSH2_POLLFD))) == NULL) {
243 fprintf(stderr, "malloc failed\n");
244 exit(1);
245 }
246
247 fds[0].type = LIBSSH2_POLLFD_CHANNEL;
248 fds[0].fd.channel = channel;
249 fds[0].events = LIBSSH2_POLLFD_POLLIN | LIBSSH2_POLLFD_POLLOUT;
250
251 do {
252 int rc = (libssh2_poll(fds, 1, 10));
253 int act = 0;
254
255 if (rc < 1)
256 continue;
257
258 if (fds[0].revents & LIBSSH2_POLLFD_POLLIN) {
259 int n = libssh2_channel_read(channel, buffer, sizeof(buffer));
260 act++;
261
262 if (n == LIBSSH2_ERROR_EAGAIN) {
263 rereads++;
264 fprintf(stderr, "will read again\n");
265 }
266 else if (n < 0) {
267 fprintf(stderr, "read failed\n");
268 exit(1);
269 }
270 else {
271 totread += n;
272 fprintf(stderr, "read %d bytes (%d in total)\n",
273 n, totread);
274 }
275 }
276
277 if (fds[0].revents & LIBSSH2_POLLFD_POLLOUT) {
278 act++;
279
280 if (totwritten < totsize) {
281 /* we have not written all data yet */
282 int left = totsize - totwritten;
283 int size = (left < bufsize) ? left : bufsize;
284 int n = libssh2_channel_write_ex(channel, 0, buffer, size);
285
286 if (n == LIBSSH2_ERROR_EAGAIN) {
287 rewrites++;
288 fprintf(stderr, "will write again\n");
289 }
290 else if (n < 0) {
291 fprintf(stderr, "write failed\n");
292 exit(1);
293 }
294 else {
295 totwritten += n;
296 fprintf(stderr, "wrote %d bytes (%d in total)",
297 n, totwritten);
298 if (left >= bufsize && n != bufsize) {
299 partials++;
300 fprintf(stderr, " PARTIAL");
301 }
302 fprintf(stderr, "\n");
303 }
304 } else {
305 /* all data written, send EOF */
306 rc = libssh2_channel_send_eof(channel);
307
308 if (rc == LIBSSH2_ERROR_EAGAIN) {
309 fprintf(stderr, "will send eof again\n");
310 }
311 else if (rc < 0) {
312 fprintf(stderr, "send eof failed\n");
313 exit(1);
314 }
315 else {
316 fprintf(stderr, "sent eof\n");
317 /* we're done writing, stop listening for OUT events */
318 fds[0].events &= ~LIBSSH2_POLLFD_POLLOUT;
319 }
320 }
321 }
322
323 if (fds[0].revents & LIBSSH2_POLLFD_CHANNEL_CLOSED) {
324 if (!act) /* don't leave loop until we have read all data */
325 running = 0;
326 }
327 } while(running);
328
329 exitcode = 127;
330 while( (rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN )
331 waitsocket(sock, session);
332
333 if( rc == 0 ) {
334 exitcode = libssh2_channel_get_exit_status( channel );
335 libssh2_channel_get_exit_signal(channel, &exitsignal,
336 NULL, NULL, NULL, NULL, NULL);
337 }
338
339 if (exitsignal)
340 fprintf(stderr, "\nGot signal: %s\n", exitsignal);
341
342 libssh2_channel_free(channel);
343 channel = NULL;
344
345 fprintf(stderr, "\nrereads: %d rewrites: %d totwritten %d\n",
346 rereads, rewrites, totwritten);
347
348 if (totwritten != totread) {
349 fprintf(stderr, "\n*** FAIL bytes written: %d bytes "
350 "read: %d ***\n", totwritten, totread);
351 exit(1);
352 }
353 }
354
355 libssh2_session_disconnect(session,
356 "Normal Shutdown, Thank you for playing");
357 libssh2_session_free(session);
358
359 #ifdef WIN32
360 closesocket(sock);
361 #else
362 close(sock);
363 #endif
364 fprintf(stderr, "all done\n");
365
366 libssh2_exit();
367
368 return exitcode;
369 }