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.
 
 
 
 

293 lines
7.4 KiB

  1. /*
  2. * Sample showing how to use libssh2 to request agent forwarding
  3. * on the remote host. The command executed will run with agent forwarded
  4. * so you should be able to do things like clone out protected git
  5. * repos and such.
  6. *
  7. * The example uses agent authentication to ensure an agent to forward
  8. * is running.
  9. *
  10. * Run it like this:
  11. *
  12. * $ ./ssh2_agent_forwarding 127.0.0.1 user "uptime"
  13. *
  14. */
  15. #include "libssh2_config.h"
  16. #include <libssh2.h>
  17. #ifdef HAVE_WINSOCK2_H
  18. # include <winsock2.h>
  19. #endif
  20. #ifdef HAVE_SYS_SOCKET_H
  21. # include <sys/socket.h>
  22. #endif
  23. #ifdef HAVE_NETINET_IN_H
  24. # include <netinet/in.h>
  25. #endif
  26. #ifdef HAVE_SYS_SELECT_H
  27. # include <sys/select.h>
  28. #endif
  29. # ifdef HAVE_UNISTD_H
  30. #include <unistd.h>
  31. #endif
  32. #ifdef HAVE_ARPA_INET_H
  33. # include <arpa/inet.h>
  34. #endif
  35. #ifdef HAVE_SYS_TIME_H
  36. # include <sys/time.h>
  37. #endif
  38. #include <sys/types.h>
  39. #include <stdlib.h>
  40. #include <fcntl.h>
  41. #include <errno.h>
  42. #include <stdio.h>
  43. #include <ctype.h>
  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. timeout.tv_sec = 10;
  53. timeout.tv_usec = 0;
  54. FD_ZERO(&fd);
  55. FD_SET(socket_fd, &fd);
  56. /* now make sure we wait in the correct direction */
  57. dir = libssh2_session_block_directions(session);
  58. if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
  59. readfd = &fd;
  60. if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
  61. writefd = &fd;
  62. rc = select(socket_fd + 1, readfd, writefd, NULL, &timeout);
  63. return rc;
  64. }
  65. int main(int argc, char *argv[])
  66. {
  67. const char *hostname = "127.0.0.1";
  68. const char *commandline = "uptime";
  69. const char *username = NULL;
  70. unsigned long hostaddr;
  71. int sock;
  72. struct sockaddr_in sin;
  73. LIBSSH2_SESSION *session;
  74. LIBSSH2_CHANNEL *channel;
  75. LIBSSH2_AGENT *agent = NULL;
  76. struct libssh2_agent_publickey *identity, *prev_identity = NULL;
  77. int rc;
  78. int exitcode;
  79. char *exitsignal = (char *)"none";
  80. int bytecount = 0;
  81. #ifdef WIN32
  82. WSADATA wsadata;
  83. WSAStartup(MAKEWORD(2, 0), &wsadata);
  84. #endif
  85. if(argc < 2) {
  86. fprintf(stderr, "At least IP and username arguments are required.\n");
  87. return 1;
  88. }
  89. /* must be ip address only */
  90. hostname = argv[1];
  91. username = argv[2];
  92. if(argc > 3) {
  93. commandline = argv[3];
  94. }
  95. rc = libssh2_init(0);
  96. if(rc != 0) {
  97. fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
  98. return 1;
  99. }
  100. hostaddr = inet_addr(hostname);
  101. /* Ultra basic "connect to port 22 on localhost"
  102. * Your code is responsible for creating the socket establishing the
  103. * connection
  104. */
  105. sock = socket(AF_INET, SOCK_STREAM, 0);
  106. sin.sin_family = AF_INET;
  107. sin.sin_port = htons(22);
  108. sin.sin_addr.s_addr = hostaddr;
  109. if(connect(sock, (struct sockaddr*)(&sin),
  110. sizeof(struct sockaddr_in)) != 0) {
  111. fprintf(stderr, "failed to connect!\n");
  112. return -1;
  113. }
  114. /* Create a session instance */
  115. session = libssh2_session_init();
  116. if(!session)
  117. return -1;
  118. if(libssh2_session_handshake(session, sock) != 0) {
  119. fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
  120. return -1;
  121. }
  122. /* Connect to the ssh-agent */
  123. agent = libssh2_agent_init(session);
  124. if(!agent) {
  125. fprintf(stderr, "Failure initializing ssh-agent support\n");
  126. rc = 1;
  127. goto shutdown;
  128. }
  129. if(libssh2_agent_connect(agent)) {
  130. fprintf(stderr, "Failure connecting to ssh-agent\n");
  131. rc = 1;
  132. goto shutdown;
  133. }
  134. if(libssh2_agent_list_identities(agent)) {
  135. fprintf(stderr, "Failure requesting identities to ssh-agent\n");
  136. rc = 1;
  137. goto shutdown;
  138. }
  139. while(1) {
  140. rc = libssh2_agent_get_identity(agent, &identity, prev_identity);
  141. if(rc == 1)
  142. break;
  143. if(rc < 0) {
  144. fprintf(stderr,
  145. "Failure obtaining identity from ssh-agent support\n");
  146. rc = 1;
  147. goto shutdown;
  148. }
  149. if(libssh2_agent_userauth(agent, username, identity)) {
  150. fprintf(stderr, "\tAuthentication with username %s and "
  151. "public key %s failed!\n",
  152. username, identity->comment);
  153. }
  154. else {
  155. fprintf(stderr, "\tAuthentication with username %s and "
  156. "public key %s succeeded!\n",
  157. username, identity->comment);
  158. break;
  159. }
  160. prev_identity = identity;
  161. }
  162. if(rc) {
  163. fprintf(stderr, "Couldn't continue authentication\n");
  164. goto shutdown;
  165. }
  166. #if 0
  167. libssh2_trace(session, ~0);
  168. #endif
  169. /* Set session to non-blocking */
  170. libssh2_session_set_blocking(session, 0);
  171. /* Exec non-blocking on the remove host */
  172. while((channel = libssh2_channel_open_session(session)) == NULL &&
  173. libssh2_session_last_error(session, NULL, NULL, 0) ==
  174. LIBSSH2_ERROR_EAGAIN) {
  175. waitsocket(sock, session);
  176. }
  177. if(channel == NULL) {
  178. fprintf(stderr, "Error\n");
  179. exit(1);
  180. }
  181. while((rc = libssh2_channel_request_auth_agent(channel)) ==
  182. LIBSSH2_ERROR_EAGAIN) {
  183. waitsocket(sock, session);
  184. }
  185. if(rc != 0) {
  186. fprintf(stderr, "Error, couldn't request auth agent, error code %d.\n",
  187. rc);
  188. exit(1);
  189. }
  190. else {
  191. fprintf(stdout, "\tAgent forwarding request succeeded!\n");
  192. }
  193. while((rc = libssh2_channel_exec(channel, commandline)) ==
  194. LIBSSH2_ERROR_EAGAIN) {
  195. waitsocket(sock, session);
  196. }
  197. if(rc != 0) {
  198. fprintf(stderr, "Error\n");
  199. exit(1);
  200. }
  201. for(;;) {
  202. /* loop until we block */
  203. int rc;
  204. do {
  205. char buffer[0x4000];
  206. rc = libssh2_channel_read(channel, buffer, sizeof(buffer) );
  207. if(rc > 0) {
  208. int i;
  209. bytecount += rc;
  210. fprintf(stderr, "We read:\n");
  211. for(i = 0; i < rc; ++i)
  212. fputc(buffer[i], stderr);
  213. fprintf(stderr, "\n");
  214. }
  215. else {
  216. if(rc != LIBSSH2_ERROR_EAGAIN)
  217. /* no need to output this for the EAGAIN case */
  218. fprintf(stderr, "libssh2_channel_read returned %d\n", rc);
  219. }
  220. }
  221. while(rc > 0);
  222. /* this is due to blocking that would occur otherwise so we loop on
  223. this condition */
  224. if(rc == LIBSSH2_ERROR_EAGAIN) {
  225. waitsocket(sock, session);
  226. }
  227. else
  228. break;
  229. }
  230. exitcode = 127;
  231. while((rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN) {
  232. waitsocket(sock, session);
  233. }
  234. if(rc == 0) {
  235. exitcode = libssh2_channel_get_exit_status(channel);
  236. libssh2_channel_get_exit_signal(channel, &exitsignal,
  237. NULL, NULL, NULL, NULL, NULL);
  238. }
  239. if(exitsignal) {
  240. printf("\nGot signal: %s\n", exitsignal);
  241. }
  242. else {
  243. printf("\nEXIT: %d bytecount: %d\n", exitcode, bytecount);
  244. }
  245. libssh2_channel_free(channel);
  246. channel = NULL;
  247. shutdown:
  248. libssh2_session_disconnect(session,
  249. "Normal Shutdown, Thank you for playing");
  250. libssh2_session_free(session);
  251. #ifdef WIN32
  252. closesocket(sock);
  253. #else
  254. close(sock);
  255. #endif
  256. fprintf(stderr, "all done\n");
  257. libssh2_exit();
  258. return 0;
  259. }