4 * $ ./ssh2_echo 127.0.0.1 user password
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.
11 #include "libssh2_config.h"
14 #ifdef HAVE_WINSOCK2_H
15 # include <winsock2.h>
17 #ifdef HAVE_SYS_SOCKET_H
18 # include <sys/socket.h>
20 #ifdef HAVE_NETINET_IN_H
21 # include <netinet/in.h>
23 #ifdef HAVE_SYS_SELECT_H
24 # include <sys/select.h>
29 #ifdef HAVE_ARPA_INET_H
30 # include <arpa/inet.h>
32 #ifdef HAVE_SYS_TIME_H
35 #include <sys/types.h>
44 static int waitsocket(int socket_fd
, LIBSSH2_SESSION
*session
)
46 struct timeval timeout
;
49 fd_set
*writefd
= NULL
;
50 fd_set
*readfd
= NULL
;
58 FD_SET(socket_fd
, &fd
);
60 /* now make sure we wait in the correct direction */
61 dir
= libssh2_session_block_directions(session
);
63 if(dir
& LIBSSH2_SESSION_BLOCK_INBOUND
)
66 if(dir
& LIBSSH2_SESSION_BLOCK_OUTBOUND
)
69 rc
= select(socket_fd
+ 1, readfd
, writefd
, NULL
, &timeout
);
76 int main(int argc
, char *argv
[])
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
;
84 struct sockaddr_in sin
;
85 const char *fingerprint
;
86 LIBSSH2_SESSION
*session
;
87 LIBSSH2_CHANNEL
*channel
;
90 char *exitsignal
=(char *)"none";
92 LIBSSH2_KNOWNHOSTS
*nh
;
99 err
= WSAStartup(MAKEWORD(2,0), &wsadata
);
101 fprintf(stderr
, "WSAStartup failed with error: %d\n", err
);
107 /* must be ip address only */
117 rc
= libssh2_init (0);
119 fprintf (stderr
, "libssh2 initialization failed (%d)\n", rc
);
123 hostaddr
= inet_addr(hostname
);
125 /* Ultra basic "connect to port 22 on localhost"
126 * Your code is responsible for creating the socket establishing the
129 sock
= socket(AF_INET
, SOCK_STREAM
, 0);
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");
140 /* Create a session instance */
141 session
= libssh2_session_init();
145 /* tell libssh2 we want it all done non-blocking */
146 libssh2_session_set_blocking(session
, 0);
148 /* ... start it up. This will trade welcome banners, exchange keys,
149 * and setup crypto, compression, and MAC layers
151 while ((rc
= libssh2_session_handshake(session
, sock
)) ==
152 LIBSSH2_ERROR_EAGAIN
);
154 fprintf(stderr
, "Failure establishing SSH session: %d\n", rc
);
158 nh
= libssh2_knownhost_init(session
);
160 /* eeek, do cleanup here */
164 /* read all hosts from here */
165 libssh2_knownhost_readfile(nh
, "known_hosts",
166 LIBSSH2_KNOWNHOST_FILE_OPENSSH
);
168 /* store all known hosts to here */
169 libssh2_knownhost_writefile(nh
, "dumpfile",
170 LIBSSH2_KNOWNHOST_FILE_OPENSSH
);
172 fingerprint
= libssh2_session_hostkey(session
, &len
, &type
);
174 struct libssh2_knownhost
*host
;
175 int check
= libssh2_knownhost_checkp(nh
, hostname
, 22,
177 LIBSSH2_KNOWNHOST_TYPE_PLAIN
|
178 LIBSSH2_KNOWNHOST_KEYENC_RAW
,
181 fprintf(stderr
, "Host check: %d, key: %s\n", check
,
182 (check
<= LIBSSH2_KNOWNHOST_CHECK_MISMATCH
)?
186 * At this point, we could verify that 'check' tells us the key is
191 /* eeek, do cleanup here */
194 libssh2_knownhost_free(nh
);
196 if ( strlen(password
) != 0 ) {
197 /* We could authenticate via password */
198 while ((rc
= libssh2_userauth_password(session
, username
, password
)) ==
199 LIBSSH2_ERROR_EAGAIN
);
201 fprintf(stderr
, "Authentication by password failed.\n");
206 libssh2_trace(session
, LIBSSH2_TRACE_SOCKET
);
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
);
214 if( channel
== NULL
) {
215 fprintf(stderr
,"Error\n");
218 while( (rc
= libssh2_channel_exec(channel
, commandline
)) ==
219 LIBSSH2_ERROR_EAGAIN
)
220 waitsocket(sock
, session
);
223 fprintf(stderr
, "exec error\n");
227 LIBSSH2_POLLFD
*fds
= NULL
;
229 int bufsize
= BUFSIZE
;
230 char buffer
[BUFSIZE
];
231 int totsize
= 1500000;
239 for (i
= 0; i
< BUFSIZE
; i
++)
242 if ((fds
= malloc (sizeof (LIBSSH2_POLLFD
))) == NULL
) {
243 fprintf(stderr
, "malloc failed\n");
247 fds
[0].type
= LIBSSH2_POLLFD_CHANNEL
;
248 fds
[0].fd
.channel
= channel
;
249 fds
[0].events
= LIBSSH2_POLLFD_POLLIN
| LIBSSH2_POLLFD_POLLOUT
;
252 int rc
= (libssh2_poll(fds
, 1, 10));
258 if (fds
[0].revents
& LIBSSH2_POLLFD_POLLIN
) {
259 int n
= libssh2_channel_read(channel
, buffer
, sizeof(buffer
));
262 if (n
== LIBSSH2_ERROR_EAGAIN
) {
264 fprintf(stderr
, "will read again\n");
267 fprintf(stderr
, "read failed\n");
272 fprintf(stderr
, "read %d bytes (%d in total)\n",
277 if (fds
[0].revents
& LIBSSH2_POLLFD_POLLOUT
) {
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
);
286 if (n
== LIBSSH2_ERROR_EAGAIN
) {
288 fprintf(stderr
, "will write again\n");
291 fprintf(stderr
, "write failed\n");
296 fprintf(stderr
, "wrote %d bytes (%d in total)",
298 if (left
>= bufsize
&& n
!= bufsize
) {
300 fprintf(stderr
, " PARTIAL");
302 fprintf(stderr
, "\n");
305 /* all data written, send EOF */
306 rc
= libssh2_channel_send_eof(channel
);
308 if (rc
== LIBSSH2_ERROR_EAGAIN
) {
309 fprintf(stderr
, "will send eof again\n");
312 fprintf(stderr
, "send eof failed\n");
316 fprintf(stderr
, "sent eof\n");
317 /* we're done writing, stop listening for OUT events */
318 fds
[0].events
&= ~LIBSSH2_POLLFD_POLLOUT
;
323 if (fds
[0].revents
& LIBSSH2_POLLFD_CHANNEL_CLOSED
) {
324 if (!act
) /* don't leave loop until we have read all data */
330 while( (rc
= libssh2_channel_close(channel
)) == LIBSSH2_ERROR_EAGAIN
)
331 waitsocket(sock
, session
);
334 exitcode
= libssh2_channel_get_exit_status( channel
);
335 libssh2_channel_get_exit_signal(channel
, &exitsignal
,
336 NULL
, NULL
, NULL
, NULL
, NULL
);
340 fprintf(stderr
, "\nGot signal: %s\n", exitsignal
);
342 libssh2_channel_free(channel
);
345 fprintf(stderr
, "\nrereads: %d rewrites: %d totwritten %d\n",
346 rereads
, rewrites
, totwritten
);
348 if (totwritten
!= totread
) {
349 fprintf(stderr
, "\n*** FAIL bytes written: %d bytes "
350 "read: %d ***\n", totwritten
, totread
);
355 libssh2_session_disconnect(session
,
356 "Normal Shutdown, Thank you for playing");
357 libssh2_session_free(session
);
364 fprintf(stderr
, "all done\n");