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.
 
 
 
 

301 lines
8.0 KiB

  1. /*
  2. * Sample showing how to do SFTP transfers.
  3. *
  4. * The sample code has default values for host name, user name, password
  5. * and path to copy, but you can specify them on the command line like:
  6. *
  7. * "sftp 192.168.0.1 user password /tmp/secrets -p|-i|-k"
  8. */
  9. #include "libssh2_config.h"
  10. #include <libssh2.h>
  11. #include <libssh2_sftp.h>
  12. #ifdef HAVE_WINSOCK2_H
  13. # include <winsock2.h>
  14. #endif
  15. #ifdef HAVE_SYS_SOCKET_H
  16. # include <sys/socket.h>
  17. #endif
  18. #ifdef HAVE_NETINET_IN_H
  19. # include <netinet/in.h>
  20. #endif
  21. # ifdef HAVE_UNISTD_H
  22. #include <unistd.h>
  23. #endif
  24. #ifdef HAVE_ARPA_INET_H
  25. # include <arpa/inet.h>
  26. #endif
  27. #ifdef HAVE_SYS_TIME_H
  28. # include <sys/time.h>
  29. #endif
  30. #include <sys/types.h>
  31. #include <fcntl.h>
  32. #include <errno.h>
  33. #include <stdio.h>
  34. #include <ctype.h>
  35. const char *keyfile1 = "~/.ssh/id_rsa.pub";
  36. const char *keyfile2 = "~/.ssh/id_rsa";
  37. const char *username = "username";
  38. const char *password = "password";
  39. const char *sftppath = "/tmp/TEST";
  40. static void kbd_callback(const char *name, int name_len,
  41. const char *instruction, int instruction_len,
  42. int num_prompts,
  43. const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
  44. LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
  45. void **abstract)
  46. {
  47. int i;
  48. size_t n;
  49. char buf[1024];
  50. (void)abstract;
  51. fprintf(stderr, "Performing keyboard-interactive authentication.\n");
  52. fprintf(stderr, "Authentication name: '");
  53. fwrite(name, 1, name_len, stderr);
  54. fprintf(stderr, "'\n");
  55. fprintf(stderr, "Authentication instruction: '");
  56. fwrite(instruction, 1, instruction_len, stderr);
  57. fprintf(stderr, "'\n");
  58. fprintf(stderr, "Number of prompts: %d\n\n", num_prompts);
  59. for(i = 0; i < num_prompts; i++) {
  60. fprintf(stderr, "Prompt %d from server: '", i);
  61. fwrite(prompts[i].text, 1, prompts[i].length, stderr);
  62. fprintf(stderr, "'\n");
  63. fprintf(stderr, "Please type response: ");
  64. fgets(buf, sizeof(buf), stdin);
  65. n = strlen(buf);
  66. while(n > 0 && strchr("\r\n", buf[n - 1]))
  67. n--;
  68. buf[n] = 0;
  69. responses[i].text = strdup(buf);
  70. responses[i].length = n;
  71. fprintf(stderr, "Response %d from user is '", i);
  72. fwrite(responses[i].text, 1, responses[i].length, stderr);
  73. fprintf(stderr, "'\n\n");
  74. }
  75. fprintf(stderr,
  76. "Done. Sending keyboard-interactive responses to server now.\n");
  77. }
  78. int main(int argc, char *argv[])
  79. {
  80. unsigned long hostaddr;
  81. int sock, i, auth_pw = 0;
  82. struct sockaddr_in sin;
  83. const char *fingerprint;
  84. char *userauthlist;
  85. LIBSSH2_SESSION *session;
  86. int rc;
  87. LIBSSH2_SFTP *sftp_session;
  88. LIBSSH2_SFTP_HANDLE *sftp_handle;
  89. #ifdef WIN32
  90. WSADATA wsadata;
  91. int err;
  92. err = WSAStartup(MAKEWORD(2, 0), &wsadata);
  93. if(err != 0) {
  94. fprintf(stderr, "WSAStartup failed with error: %d\n", err);
  95. return 1;
  96. }
  97. #endif
  98. if(argc > 1) {
  99. hostaddr = inet_addr(argv[1]);
  100. }
  101. else {
  102. hostaddr = htonl(0x7F000001);
  103. }
  104. if(argc > 2) {
  105. username = argv[2];
  106. }
  107. if(argc > 3) {
  108. password = argv[3];
  109. }
  110. if(argc > 4) {
  111. sftppath = argv[4];
  112. }
  113. rc = libssh2_init(0);
  114. if(rc != 0) {
  115. fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
  116. return 1;
  117. }
  118. /*
  119. * The application code is responsible for creating the socket
  120. * and establishing the connection
  121. */
  122. sock = socket(AF_INET, SOCK_STREAM, 0);
  123. sin.sin_family = AF_INET;
  124. sin.sin_port = htons(22);
  125. sin.sin_addr.s_addr = hostaddr;
  126. if(connect(sock, (struct sockaddr*)(&sin),
  127. sizeof(struct sockaddr_in)) != 0) {
  128. fprintf(stderr, "failed to connect!\n");
  129. return -1;
  130. }
  131. /* Create a session instance
  132. */
  133. session = libssh2_session_init();
  134. if(!session)
  135. return -1;
  136. /* Since we have set non-blocking, tell libssh2 we are blocking */
  137. libssh2_session_set_blocking(session, 1);
  138. /* ... start it up. This will trade welcome banners, exchange keys,
  139. * and setup crypto, compression, and MAC layers
  140. */
  141. rc = libssh2_session_handshake(session, sock);
  142. if(rc) {
  143. fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
  144. return -1;
  145. }
  146. /* At this point we havn't yet authenticated. The first thing to do
  147. * is check the hostkey's fingerprint against our known hosts Your app
  148. * may have it hard coded, may go to a file, may present it to the
  149. * user, that's your call
  150. */
  151. fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
  152. fprintf(stderr, "Fingerprint: ");
  153. for(i = 0; i < 20; i++) {
  154. fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
  155. }
  156. fprintf(stderr, "\n");
  157. /* check what authentication methods are available */
  158. userauthlist = libssh2_userauth_list(session, username, strlen(username));
  159. fprintf(stderr, "Authentication methods: %s\n", userauthlist);
  160. if(strstr(userauthlist, "password") != NULL) {
  161. auth_pw |= 1;
  162. }
  163. if(strstr(userauthlist, "keyboard-interactive") != NULL) {
  164. auth_pw |= 2;
  165. }
  166. if(strstr(userauthlist, "publickey") != NULL) {
  167. auth_pw |= 4;
  168. }
  169. /* if we got an 4. argument we set this option if supported */
  170. if(argc > 5) {
  171. if((auth_pw & 1) && !strcasecmp(argv[5], "-p")) {
  172. auth_pw = 1;
  173. }
  174. if((auth_pw & 2) && !strcasecmp(argv[5], "-i")) {
  175. auth_pw = 2;
  176. }
  177. if((auth_pw & 4) && !strcasecmp(argv[5], "-k")) {
  178. auth_pw = 4;
  179. }
  180. }
  181. if(auth_pw & 1) {
  182. /* We could authenticate via password */
  183. if(libssh2_userauth_password(session, username, password)) {
  184. fprintf(stderr, "Authentication by password failed.\n");
  185. goto shutdown;
  186. }
  187. }
  188. else if(auth_pw & 2) {
  189. /* Or via keyboard-interactive */
  190. if(libssh2_userauth_keyboard_interactive(session, username,
  191. &kbd_callback) ) {
  192. fprintf(stderr,
  193. "\tAuthentication by keyboard-interactive failed!\n");
  194. goto shutdown;
  195. }
  196. else {
  197. fprintf(stderr,
  198. "\tAuthentication by keyboard-interactive succeeded.\n");
  199. }
  200. }
  201. else if(auth_pw & 4) {
  202. /* Or by public key */
  203. if(libssh2_userauth_publickey_fromfile(session, username, keyfile1,
  204. keyfile2, password)) {
  205. fprintf(stderr, "\tAuthentication by public key failed!\n");
  206. goto shutdown;
  207. }
  208. else {
  209. fprintf(stderr, "\tAuthentication by public key succeeded.\n");
  210. }
  211. }
  212. else {
  213. fprintf(stderr, "No supported authentication methods found!\n");
  214. goto shutdown;
  215. }
  216. fprintf(stderr, "libssh2_sftp_init()!\n");
  217. sftp_session = libssh2_sftp_init(session);
  218. if(!sftp_session) {
  219. fprintf(stderr, "Unable to init SFTP session\n");
  220. goto shutdown;
  221. }
  222. fprintf(stderr, "libssh2_sftp_open()!\n");
  223. /* Request a file via SFTP */
  224. sftp_handle =
  225. libssh2_sftp_open(sftp_session, sftppath, LIBSSH2_FXF_READ, 0);
  226. if(!sftp_handle) {
  227. fprintf(stderr, "Unable to open file with SFTP: %ld\n",
  228. libssh2_sftp_last_error(sftp_session));
  229. goto shutdown;
  230. }
  231. fprintf(stderr, "libssh2_sftp_open() is done, now receive data!\n");
  232. do {
  233. char mem[1024];
  234. /* loop until we fail */
  235. fprintf(stderr, "libssh2_sftp_read()!\n");
  236. rc = libssh2_sftp_read(sftp_handle, mem, sizeof(mem));
  237. if(rc > 0) {
  238. write(1, mem, rc);
  239. }
  240. else {
  241. break;
  242. }
  243. } while(1);
  244. libssh2_sftp_close(sftp_handle);
  245. libssh2_sftp_shutdown(sftp_session);
  246. shutdown:
  247. libssh2_session_disconnect(session, "Normal Shutdown");
  248. libssh2_session_free(session);
  249. #ifdef WIN32
  250. closesocket(sock);
  251. #else
  252. close(sock);
  253. #endif
  254. fprintf(stderr, "all done\n");
  255. libssh2_exit();
  256. return 0;
  257. }