geom_gate userland utility improvements
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

320 lines
8.5 KiB

  1. /*
  2. * Sample showing how to use libssh2 to execute a command remotely.
  3. *
  4. * The sample code has fixed values for host name, user name, password
  5. * and command to run.
  6. *
  7. * Run it like this:
  8. *
  9. * $ ./ssh2_exec 127.0.0.1 user password "uptime"
  10. *
  11. */
  12. #include "libssh2_config.h"
  13. #include <libssh2.h>
  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. static int waitsocket(int socket_fd, LIBSSH2_SESSION *session)
  44. {
  45. struct timeval timeout;
  46. int rc;
  47. fd_set fd;
  48. fd_set *writefd = NULL;
  49. fd_set *readfd = NULL;
  50. int dir;
  51. timeout.tv_sec = 10;
  52. timeout.tv_usec = 0;
  53. FD_ZERO(&fd);
  54. FD_SET(socket_fd, &fd);
  55. /* now make sure we wait in the correct direction */
  56. dir = libssh2_session_block_directions(session);
  57. if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
  58. readfd = &fd;
  59. if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
  60. writefd = &fd;
  61. rc = select(socket_fd + 1, readfd, writefd, NULL, &timeout);
  62. return rc;
  63. }
  64. int main(int argc, char *argv[])
  65. {
  66. const char *hostname = "127.0.0.1";
  67. const char *commandline = "uptime";
  68. const char *username = "user";
  69. const char *password = "password";
  70. unsigned long hostaddr;
  71. int sock;
  72. struct sockaddr_in sin;
  73. const char *fingerprint;
  74. LIBSSH2_SESSION *session;
  75. LIBSSH2_CHANNEL *channel;
  76. int rc;
  77. int exitcode;
  78. char *exitsignal = (char *)"none";
  79. int bytecount = 0;
  80. size_t len;
  81. LIBSSH2_KNOWNHOSTS *nh;
  82. int type;
  83. #ifdef WIN32
  84. WSADATA wsadata;
  85. int err;
  86. err = WSAStartup(MAKEWORD(2, 0), &wsadata);
  87. if(err != 0) {
  88. fprintf(stderr, "WSAStartup failed with error: %d\n", err);
  89. return 1;
  90. }
  91. #endif
  92. if(argc > 1)
  93. /* must be ip address only */
  94. hostname = argv[1];
  95. if(argc > 2) {
  96. username = argv[2];
  97. }
  98. if(argc > 3) {
  99. password = argv[3];
  100. }
  101. if(argc > 4) {
  102. commandline = argv[4];
  103. }
  104. rc = libssh2_init(0);
  105. if(rc != 0) {
  106. fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
  107. return 1;
  108. }
  109. hostaddr = inet_addr(hostname);
  110. /* Ultra basic "connect to port 22 on localhost"
  111. * Your code is responsible for creating the socket establishing the
  112. * connection
  113. */
  114. sock = socket(AF_INET, SOCK_STREAM, 0);
  115. sin.sin_family = AF_INET;
  116. sin.sin_port = htons(22);
  117. sin.sin_addr.s_addr = hostaddr;
  118. if(connect(sock, (struct sockaddr*)(&sin),
  119. sizeof(struct sockaddr_in)) != 0) {
  120. fprintf(stderr, "failed to connect!\n");
  121. return -1;
  122. }
  123. /* Create a session instance */
  124. session = libssh2_session_init();
  125. if(!session)
  126. return -1;
  127. /* tell libssh2 we want it all done non-blocking */
  128. libssh2_session_set_blocking(session, 0);
  129. /* ... start it up. This will trade welcome banners, exchange keys,
  130. * and setup crypto, compression, and MAC layers
  131. */
  132. while((rc = libssh2_session_handshake(session, sock)) ==
  133. LIBSSH2_ERROR_EAGAIN);
  134. if(rc) {
  135. fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
  136. return -1;
  137. }
  138. nh = libssh2_knownhost_init(session);
  139. if(!nh) {
  140. /* eeek, do cleanup here */
  141. return 2;
  142. }
  143. /* read all hosts from here */
  144. libssh2_knownhost_readfile(nh, "known_hosts",
  145. LIBSSH2_KNOWNHOST_FILE_OPENSSH);
  146. /* store all known hosts to here */
  147. libssh2_knownhost_writefile(nh, "dumpfile",
  148. LIBSSH2_KNOWNHOST_FILE_OPENSSH);
  149. fingerprint = libssh2_session_hostkey(session, &len, &type);
  150. if(fingerprint) {
  151. struct libssh2_knownhost *host;
  152. #if LIBSSH2_VERSION_NUM >= 0x010206
  153. /* introduced in 1.2.6 */
  154. int check = libssh2_knownhost_checkp(nh, hostname, 22,
  155. fingerprint, len,
  156. LIBSSH2_KNOWNHOST_TYPE_PLAIN|
  157. LIBSSH2_KNOWNHOST_KEYENC_RAW,
  158. &host);
  159. #else
  160. /* 1.2.5 or older */
  161. int check = libssh2_knownhost_check(nh, hostname,
  162. fingerprint, len,
  163. LIBSSH2_KNOWNHOST_TYPE_PLAIN|
  164. LIBSSH2_KNOWNHOST_KEYENC_RAW,
  165. &host);
  166. #endif
  167. fprintf(stderr, "Host check: %d, key: %s\n", check,
  168. (check <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
  169. host->key:"<none>");
  170. /*****
  171. * At this point, we could verify that 'check' tells us the key is
  172. * fine or bail out.
  173. *****/
  174. }
  175. else {
  176. /* eeek, do cleanup here */
  177. return 3;
  178. }
  179. libssh2_knownhost_free(nh);
  180. if(strlen(password) != 0) {
  181. /* We could authenticate via password */
  182. while((rc = libssh2_userauth_password(session, username, password)) ==
  183. LIBSSH2_ERROR_EAGAIN);
  184. if(rc) {
  185. fprintf(stderr, "Authentication by password failed.\n");
  186. goto shutdown;
  187. }
  188. }
  189. else {
  190. /* Or by public key */
  191. while((rc = libssh2_userauth_publickey_fromfile(session, username,
  192. "/home/user/"
  193. ".ssh/id_rsa.pub",
  194. "/home/user/"
  195. ".ssh/id_rsa",
  196. password)) ==
  197. LIBSSH2_ERROR_EAGAIN);
  198. if(rc) {
  199. fprintf(stderr, "\tAuthentication by public key failed\n");
  200. goto shutdown;
  201. }
  202. }
  203. #if 0
  204. libssh2_trace(session, ~0);
  205. #endif
  206. /* Exec non-blocking on the remove host */
  207. while((channel = libssh2_channel_open_session(session)) == NULL &&
  208. libssh2_session_last_error(session, NULL, NULL, 0) ==
  209. LIBSSH2_ERROR_EAGAIN) {
  210. waitsocket(sock, session);
  211. }
  212. if(channel == NULL) {
  213. fprintf(stderr, "Error\n");
  214. exit(1);
  215. }
  216. while((rc = libssh2_channel_exec(channel, commandline)) ==
  217. LIBSSH2_ERROR_EAGAIN) {
  218. waitsocket(sock, session);
  219. }
  220. if(rc != 0) {
  221. fprintf(stderr, "Error\n");
  222. exit(1);
  223. }
  224. for(;;) {
  225. /* loop until we block */
  226. int rc;
  227. do {
  228. char buffer[0x4000];
  229. rc = libssh2_channel_read(channel, buffer, sizeof(buffer) );
  230. if(rc > 0) {
  231. int i;
  232. bytecount += rc;
  233. fprintf(stderr, "We read:\n");
  234. for(i = 0; i < rc; ++i)
  235. fputc(buffer[i], stderr);
  236. fprintf(stderr, "\n");
  237. }
  238. else {
  239. if(rc != LIBSSH2_ERROR_EAGAIN)
  240. /* no need to output this for the EAGAIN case */
  241. fprintf(stderr, "libssh2_channel_read returned %d\n", rc);
  242. }
  243. }
  244. while(rc > 0);
  245. /* this is due to blocking that would occur otherwise so we loop on
  246. this condition */
  247. if(rc == LIBSSH2_ERROR_EAGAIN) {
  248. waitsocket(sock, session);
  249. }
  250. else
  251. break;
  252. }
  253. exitcode = 127;
  254. while((rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN)
  255. waitsocket(sock, session);
  256. if(rc == 0) {
  257. exitcode = libssh2_channel_get_exit_status(channel);
  258. libssh2_channel_get_exit_signal(channel, &exitsignal,
  259. NULL, NULL, NULL, NULL, NULL);
  260. }
  261. if(exitsignal)
  262. fprintf(stderr, "\nGot signal: %s\n", exitsignal);
  263. else
  264. fprintf(stderr, "\nEXIT: %d bytecount: %d\n", exitcode, bytecount);
  265. libssh2_channel_free(channel);
  266. channel = NULL;
  267. shutdown:
  268. libssh2_session_disconnect(session,
  269. "Normal Shutdown, Thank you for playing");
  270. libssh2_session_free(session);
  271. #ifdef WIN32
  272. closesocket(sock);
  273. #else
  274. close(sock);
  275. #endif
  276. fprintf(stderr, "all done\n");
  277. libssh2_exit();
  278. return 0;
  279. }