使用libssh链接远程ssh服务器并执行command

December 09, 2023
测试
测试
测试
测试
14 分钟阅读

看到段牛牛和大湿聊了一下批量ssh的东西,然后看到有个ssh的程序,

挺有意思,学习一下,然后实现了一下,记录下来了

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <libssh/libssh.h>
  6. int show_remote_processes(ssh_session session, unsigned char *command)
  7. {
  8.     ssh_channel channel;
  9. int rc;
  10.     char buffer[256];
  11.     unsigned int nbytes;
  12.     channel = ssh_channel_new(session);
  13. if (channel == NULL)
  14.         return SSH_ERROR;
  15.     rc = ssh_channel_open_session(channel);
  16. if (rc != SSH_OK)
  17. {
  18.         ssh_channel_free(channel);
  19.         return rc;
  20. }
  21.     rc = ssh_channel_request_exec(channel, command);
  22. if (rc != SSH_OK)
  23. {
  24.         ssh_channel_close(channel);
  25.         ssh_channel_free(channel);
  26.         return rc;
  27. }
  28.     nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
  29. while (nbytes > 0)
  30. {
  31. if (write(1, buffer, nbytes) != nbytes)
  32. {
  33.             ssh_channel_close(channel);
  34.             ssh_channel_free(channel);
  35.             return SSH_ERROR;
  36. }
  37.         nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
  38. }
  39. if (nbytes < 0)
  40. {
  41.         ssh_channel_close(channel);
  42.         ssh_channel_free(channel);
  43.         return SSH_ERROR;
  44. }
  45.     ssh_channel_send_eof(channel);
  46.     ssh_channel_close(channel);
  47.     ssh_channel_free(channel);
  48.     return SSH_OK;
  49. }
  50. int verify_knownhost(ssh_session session)
  51. {
  52. int state, hlen;
  53.     unsigned char *hash = NULL;
  54.     char *hexa;
  55.     char buf[10];
  56.     state = ssh_is_server_known(session);
  57.     hlen = ssh_get_pubkey_hash(session, &hash);
  58. if (hlen < 0)
  59.         return -1;
  60.     switch (state)
  61. {
  62. case SSH_SERVER_KNOWN_OK:
  63.             break; /* ok */
  64. case SSH_SERVER_KNOWN_CHANGED:
  65.             fprintf(stderr, "Host key for server changed: it is now:\n");
  66.             ssh_print_hexa("Public key hash", hash, hlen);
  67.             fprintf(stderr, "For security reasons, connection will be stopped\n");
  68.             free(hash);
  69.             return -1;
  70. case SSH_SERVER_FOUND_OTHER:
  71.             fprintf(stderr, "The host key for this server was not found but an other"
  72. "type of key exists.\n");
  73.             fprintf(stderr, "An attacker might change the default server key to"
  74. "confuse your client into thinking the key does not exist\n");
  75.             free(hash);
  76.             return -1;
  77. case SSH_SERVER_FILE_NOT_FOUND:
  78.             fprintf(stderr, "Could not find known host file.\n");
  79.             fprintf(stderr, "If you accept the host key here, the file will be"
  80. "automatically created.\n");
  81. /* fallback to SSH_SERVER_NOT_KNOWN behavior */
  82. case SSH_SERVER_NOT_KNOWN:
  83.             hexa = ssh_get_hexa(hash, hlen);
  84.             fprintf(stderr,"The server is unknown. Do you trust the host key?\n");
  85.             fprintf(stderr, "Public key hash: %s\n", hexa);
  86.             free(hexa);
  87. if (fgets(buf, sizeof(buf), stdin) == NULL)
  88. {
  89.                 free(hash);
  90.                 return -1;
  91. }
  92. if (strncasecmp(buf, "yes", 3) != 0)
  93. {
  94.                 free(hash);
  95.                 return -1;
  96. }
  97. if (ssh_write_knownhost(session) < 0)
  98. {
  99.                 fprintf(stderr, "Error %s\n", "error");
  100.                 free(hash);
  101.                 return -1;
  102. }
  103.             break;
  104. case SSH_SERVER_ERROR:
  105.             fprintf(stderr, "Error %s", ssh_get_error(session));
  106.             free(hash);
  107.             return -1;
  108. }
  109.     free(hash);
  110.     return 0;
  111. }
  112. static int ssh_connect_test(unsigned char *ipaddr, unsigned char *command)
  113. {
  114. int rc = 0;
  115.     char *password;
  116.     ssh_session my_ssh_session = ssh_new();
  117. if (!my_ssh_session) {
  118.         fprintf(stderr, "cannot alloc new ssh\r\n");
  119.         return -1;
  120. }
  121.     ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, ipaddr);
  122.     rc = ssh_connect(my_ssh_session);
  123. if (rc != SSH_OK)
  124. {
  125.         fprintf(stderr, "Error connecting to localhost: %s\n", ssh_get_error(my_ssh_session));
  126. exit(-1);
  127. }
  128. if (verify_knownhost(my_ssh_session) < 0)
  129. {
  130.         ssh_disconnect(my_ssh_session);
  131.         ssh_free(my_ssh_session);
  132. exit(-1);
  133. }
  134.     password = "passwordsamples";
  135.     rc = ssh_userauth_password(my_ssh_session, NULL, password);
  136. if (rc != SSH_AUTH_SUCCESS)
  137. {
  138.         fprintf(stderr, "Error authenticating with password: %s\n",    ssh_get_error(my_ssh_session));
  139.         ssh_disconnect(my_ssh_session);
  140.         ssh_free(my_ssh_session);
  141. exit(-1);
  142. }
  143.     show_remote_processes(my_ssh_session, command);
  144.     fprintf(stderr, "alloc success\r\n");
  145.     ssh_free(my_ssh_session);
  146.     return 0;
  147. }
  148. int main(int argc, char *argv[])
  149. {
  150. int ret = 0;
  151.     ret = ssh_connect_test(argv[1], argv[2]);
  152. if (ret < 0) {
  153.         fprintf(stderr, "connect error \r\n");
  154.         return -1;
  155. }
  156.     return 0;
  157. }

Makefile如下

  1. CFLAGS    += -Werror -I/usr/local/include -L/usr/local/lib
  2. CC        =gcc
  3. LIBS    = -lssh
  4. OBJS    += \
  5.          1.o
  6. TARGET    = target
  7. all:$(OBJS)
  8.     gcc $(CFLAGS) -o $(TARGET) $(OBJS) $(LIBS)
  9. clean:
  10.     rm -rf $(OBJS) $(TARGET)

然后直接make即可生成可执行文件target

然后执行效果如下

  1. [liuqi@btg example_libssh]$ ./target 192.168.0.118 date
  2. 2011年 06月 13日 星期一 14:07:04 CST
  3. alloc success
  4. [liuqi@btg example_libssh]$ ./target 192.168.0.118 who
  5. liuqi tty1 2011-06-13 10:28 (:0)
  6. liuqi pts/0 2011-06-13 10:29 (:0.0)
  7. liuqi pts/1 2011-06-13 10:29 (:0.0)
  8. liuqi pts/2 2011-06-13 13:54 (:0.0)
  9. liuqi pts/3 2011-06-13 14:02 (:0.0)
  10. alloc success
  11. [liuqi@btg example_libssh]$

继续阅读

更多来自我们博客的帖子

如何安装 BuddyPress
由 测试 December 17, 2023
经过差不多一年的开发,BuddyPress 这个基于 WordPress Mu 的 SNS 插件正式版终于发布了。BuddyPress...
阅读更多
Filter如何工作
由 测试 December 17, 2023
在 web.xml...
阅读更多
如何理解CGAffineTransform
由 测试 December 17, 2023
CGAffineTransform A structure for holding an affine transformation matrix. ...
阅读更多