免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 10944 | 回复: 10
打印 上一主题 下一主题

libssh2示例修改版 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-01-13 12:59 |只看该作者 |倒序浏览
主要把代码做了分离。稍作修改可以做交互式的执行命令。



libssh2_exec.h


  1. #ifndef __LIBSSH2_EXEC_H
  2. #define __LIBSSH2_EXEC_H

  3. #include "libssh2_config.h"
  4. #include <libssh2.h>


  5. #ifdef HAVE_NETINET_IN_H
  6. # include <netinet/in.h>
  7. #endif
  8. #ifdef HAVE_SYS_SOCKET_H
  9. # include <sys/socket.h>
  10. #endif
  11. # ifdef HAVE_UNISTD_H
  12. #include <unistd.h>
  13. #endif
  14. #ifdef HAVE_ARPA_INET_H
  15. # include <arpa/inet.h>
  16. #endif

  17. #include <sys/time.h>
  18. #include <sys/types.h>
  19. #include <stdlib.h>
  20. #include <fcntl.h>
  21. #include <errno.h>
  22. #include <stdio.h>
  23. #include <ctype.h>


  24. static int waitsocket(int *socket_fd, LIBSSH2_SESSION *session);
  25. void close_channel(LIBSSH2_CHANNEL *channel);
  26. void shutdown_socket(int *sock, LIBSSH2_SESSION *session);
  27. int connect_sock(int *sock, LIBSSH2_SESSION **session,LIBSSH2_CHANNEL **channel);
  28. int create_channel(int *sock, LIBSSH2_SESSION **session,LIBSSH2_CHANNEL **channel);
  29. int cmd_request(int *sock, LIBSSH2_SESSION *session,LIBSSH2_CHANNEL *channel,char *cmdline);

  30. #endif

复制代码

[ 本帖最后由 diyself 于 2010-1-13 13:07 编辑 ]

评分

参与人数 1可用积分 +10 收起 理由
prolj + 10 非常感谢,最大权限就10个小手,还望以 ...

查看全部评分

论坛徽章:
0
2 [报告]
发表于 2010-01-13 13:00 |只看该作者
libssh2_exec.c

  1. #include "libssh2_exec.h"
  2. //#include "libssh2_config.h"
  3. //#include <libssh2.h>


  4. static int waitsocket(int *socket_fd, LIBSSH2_SESSION *session)
  5. {
  6.     struct timeval timeout;
  7.     int rc;
  8.     fd_set fd;
  9.     fd_set *writefd = NULL;
  10.     fd_set *readfd = NULL;
  11.     int dir;

  12.     timeout.tv_sec = 10;
  13.     timeout.tv_usec = 0;

  14.     FD_ZERO(&fd);

  15.     FD_SET(*socket_fd, &fd);

  16.     /* now make sure we wait in the correct direction */
  17.     dir = libssh2_session_block_directions(session);

  18.     if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
  19.         readfd = &fd;

  20.     if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
  21.         writefd = &fd;

  22.     rc = select(*socket_fd + 1, readfd, writefd, NULL, &timeout);

  23.     return rc;
  24. }
  25. void close_channel(LIBSSH2_CHANNEL *channel)
  26. {
  27.     libssh2_channel_free(channel);
  28.     channel = NULL;
  29. }

  30. void shutdown_socket(int *sock, LIBSSH2_SESSION *session)
  31. {
  32.     libssh2_session_disconnect(session,"Normal Shutdown, Thank you for playing");
  33.     libssh2_session_free(session);


  34.     close(*sock);
  35. }

  36. /***********************************************
  37. 函数名称:connect_sock

  38. 函数功能:建立ssh 连接

  39. 传入参数:

  40. 返回数据:

  41. ***********************************************/
  42. int connect_sock(int *sock, LIBSSH2_SESSION **session,LIBSSH2_CHANNEL **channel)
  43. {
  44.     const char *hostname = "127.0.0.1";
  45.     const char *username    = "root";
  46.     const char *password    = "root";
  47.     unsigned long hostaddr;


  48.     struct sockaddr_in sin;
  49.     const char *fingerprint;

  50.     int rc;
  51.     int exitcode;
  52.     int bytecount = 0;
  53.     size_t len;
  54.     LIBSSH2_KNOWNHOSTS *nh;
  55.     int type;
  56.     hostaddr = inet_addr(hostname);

  57.     /* Ultra basic "connect to port 22 on localhost"
  58.      * Your code is responsible for creating the socket establishing the
  59.      * connection
  60.      */
  61.     *sock = socket(AF_INET, SOCK_STREAM, 0); //建立ssh socket

  62.     sin.sin_family = AF_INET;
  63.     sin.sin_port = htons(22);
  64.     sin.sin_addr.s_addr = hostaddr;
  65.     if (connect(*sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in)) != 0) {
  66.         fprintf(stderr, "failed to connect!\n");
  67.         return -1;
  68.     }


  69.     /* Create a *session instance */
  70.     *session = libssh2_session_init();
  71.     if (!*session)
  72.         return -1;

  73.     /* tell libssh2 we want it all done non-blocking */
  74.     libssh2_session_set_blocking(*session, 0);        //建立ssh 会话

  75.     /* ... start it up. This will trade welcome banners, exchange keys,
  76.      * and setup crypto, compression, and MAC layers
  77.      */
  78.     while ((rc = libssh2_session_startup(*session, *sock)) == LIBSSH2_ERROR_EAGAIN);
  79.     if (rc) {
  80.         fprintf(stderr, "Failure establishing SSH *session: %d\n", rc);
  81.         return -1;
  82.     }

  83.     nh = libssh2_knownhost_init(*session);
  84.     if(!nh) {
  85.         /* eeek, do cleanup here */
  86.         return 2;
  87.     }

  88.     /* read all hosts from here */
  89.     libssh2_knownhost_readfile(nh, "known_hosts",
  90.                                LIBSSH2_KNOWNHOST_FILE_OPENSSH);

  91.     /* store all known hosts to here */
  92.     libssh2_knownhost_writefile(nh, "dumpfile", LIBSSH2_KNOWNHOST_FILE_OPENSSH);

  93.     fingerprint = libssh2_session_hostkey(*session, &len, &type);
  94.     if(fingerprint) {
  95.         struct libssh2_knownhost *host;
  96.         int check = libssh2_knownhost_check(nh, (char *)hostname,
  97.                                             (char *)fingerprint, len,
  98.                                             LIBSSH2_KNOWNHOST_TYPE_PLAIN|
  99.                                             LIBSSH2_KNOWNHOST_KEYENC_RAW,
  100.                                             &host);

  101.        // fprintf(stderr, "Host check: %d, key: %s\n", check,
  102.         //        (check <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
  103.           //      host->key:"<none>");

  104.         /*****
  105.          * At this point, we could verify that 'check' tells us the key is
  106.          * fine or bail out.
  107.          *****/
  108.     }
  109.     else {
  110.         /* eeek, do cleanup here */
  111.         return 3;
  112.     }
  113.     libssh2_knownhost_free(nh);

  114.     if ( strlen(password) != 0 ) {
  115.         /* We could authenticate via password *///进行密码验证
  116.         while ((rc = libssh2_userauth_password(*session, username, password)) ==
  117.                LIBSSH2_ERROR_EAGAIN);
  118.         if (rc) {
  119.             fprintf(stderr, "Authentication by password failed.\n");
  120.             shutdown_socket(sock, *session);
  121.                         return 1;
  122.         }

  123.     }
  124.     else {
  125.         /* Or by public key */
  126.         while ((rc = libssh2_userauth_publickey_fromfile(*session, username,
  127.                                                          "/home/user/"
  128.                                                          ".ssh/id_rsa.pub",
  129.                                                          "/home/user/"
  130.                                                          ".ssh/id_rsa",
  131.                                                          password)) ==
  132.                LIBSSH2_ERROR_EAGAIN);
  133.         if (rc) {
  134.             fprintf(stderr, "\tAuthentication by public key failed\n");
  135.             shutdown_socket(sock, *session);
  136.         }
  137.     }


  138.     /* Exec non-blocking on the remove host */


  139.         return 0;
  140. }

  141. /***********************************************
  142. 函数名称:create_channel

  143. 函数功能:创建ssh通道

  144. 传入参数:

  145. 返回数据:

  146. ***********************************************/
  147. int create_channel(int *sock, LIBSSH2_SESSION **session,LIBSSH2_CHANNEL **channel)
  148. {

  149.          while( (*channel = libssh2_channel_open_session(*session)) == NULL &&
  150.            libssh2_session_last_error(*session,NULL,NULL,0) ==
  151.            LIBSSH2_ERROR_EAGAIN )
  152.     {
  153.         waitsocket(sock, *session);
  154.     }
  155.     if( *channel == NULL )
  156.     {
  157.         fprintf(stderr,"Error\n");
  158.         exit( 1 );
  159.     }
  160.         return 0;
  161. }

  162. /***********************************************
  163. 函数名称:cmd_request

  164. 函数功能:执行请求的命令

  165. 传入参数:

  166. 返回数据:

  167. ***********************************************/
  168. int cmd_request(int *sock, LIBSSH2_SESSION *session,LIBSSH2_CHANNEL *channel,char *cmdline)
  169. {       

  170.     int rc=0,exitcode=0,bytecount=0;
  171.     while( (rc = libssh2_channel_exec(channel, cmdline)) == LIBSSH2_ERROR_EAGAIN )//执行请求的命令
  172.     {
  173.         waitsocket(sock, session);
  174.     }
  175.     if( rc != 0 )
  176.     {
  177.         fprintf(stderr,"Error\n");
  178.         exit( 1 );
  179.     }
  180.     char buffer[2048];
  181.     for( ;; )
  182.     {
  183.         // loop until we block
  184.         int rc=0,exitcode=0;
  185.         do
  186.         {
  187.        
  188.                         memset(&buffer,0,sizeof(buffer));
  189.             rc = libssh2_channel_read( channel, buffer, sizeof(buffer)-1 );//分批接收命令执行结果
  190.             buffer[rc] = '\0';

  191.              printf("\n%s\n",buffer);


  192.         }
  193.         while( rc > 0 );

  194.         // this is due to blocking that would occur otherwise so we loop on
  195.           // this condition
  196.         if( rc == LIBSSH2_ERROR_EAGAIN )
  197.         {
  198.             waitsocket(sock, session);
  199.         }
  200.         else
  201.             break;
  202.     }
  203.     exitcode = 127;
  204.     while( (rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN )
  205.         waitsocket(sock, session);
  206.        
  207.     if( rc == 0 )
  208.     {
  209.         exitcode = libssh2_channel_get_exit_status( channel );
  210.     }
  211.     if(exitcode == 127)
  212.     {

  213.     }


  214.        


  215.     return 0;
  216. }

复制代码

[ 本帖最后由 diyself 于 2010-1-13 13:12 编辑 ]

论坛徽章:
0
3 [报告]
发表于 2010-01-13 13:01 |只看该作者
server.c

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <errno.h>
  4. #include <string.h>
  5. #include <sys/types.h>
  6. #include <netinet/in.h>
  7. #include <sys/socket.h>
  8. #include <sys/wait.h>
  9. #include <semaphore.h>
  10. #include <pthread.h>
  11. #include "libssh2_exec.h"


  12. int main()
  13. {
  14.     int sock,rc;
  15.     LIBSSH2_SESSION *session = NULL;
  16.     LIBSSH2_CHANNEL *channel = NULL;

  17.    
  18.         char buff[1024];
  19.         if(connect_sock(&sock, &session,&channel)!=0)
  20.         {       
  21.                 printf("连接sshd失败'的信息。\n");

  22.                 return 1;
  23.         }

  24.        
  25.                                        
  26.        create_channel(&sock, &session,&channel);
  27.         strcpy(buff,"ls -l");                                             //执行ls -l
  28.        cmd_request(&sock, session,channel,buff);
  29.         strcpy(buff,"ps aux");                                      //执行ps aux
  30.        create_channel(&sock, &session,&channel);
  31.        cmd_request(&sock, session,channel,buff);

  32.     /*也可用下面的代替上面6行
  33.         strcpy(buff,"ls -l;ps aux");                                      //执行ls -l;ps aux
  34.        create_channel(&sock, &session,&channel);
  35.        cmd_request(&sock, session,channel,buff);

  36. */
  37.         close_channel(channel);
  38.         shutdown_socket(&sock, session);
  39.         return 0;
  40. }


复制代码

[ 本帖最后由 diyself 于 2010-1-13 13:20 编辑 ]

论坛徽章:
0
4 [报告]
发表于 2010-01-13 13:02 |只看该作者

来自源代码的文件

libssh2_config.h

  1. /* src/libssh2_config.h.  Generated from libssh2_config.h.in by configure.  */
  2. /* src/libssh2_config.h.in.  Generated from configure.in by autoheader.  */

  3. /* Define if building universal (internal helper macro) */
  4. /* #undef AC_APPLE_UNIVERSAL_BUILD */

  5. /* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
  6.    systems. This function is required for `alloca.c' support on those systems.
  7.    */
  8. /* #undef CRAY_STACKSEG_END */

  9. /* Define to 1 if using `alloca.c'. */
  10. /* #undef C_ALLOCA */

  11. /* Define to 1 if you have `alloca', as a function or macro. */
  12. #define HAVE_ALLOCA 1

  13. /* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
  14.    */
  15. #define HAVE_ALLOCA_H 1

  16. /* Define to 1 if you have the <arpa/inet.h> header file. */
  17. #define HAVE_ARPA_INET_H 1

  18. /* disabled non-blocking sockets */
  19. /* #undef HAVE_DISABLED_NONBLOCKING */

  20. /* Define to 1 if you have the <dlfcn.h> header file. */
  21. #define HAVE_DLFCN_H 1

  22. /* Define to 1 if you have the <errno.h> header file. */
  23. #define HAVE_ERRNO_H 1

  24. /* Define to 1 if you have the <fcntl.h> header file. */
  25. #define HAVE_FCNTL_H 1

  26. /* use FIONBIO for non-blocking sockets */
  27. /* #undef HAVE_FIONBIO */

  28. /* Define to 1 if you have the `gettimeofday' function. */
  29. #define HAVE_GETTIMEOFDAY 1

  30. /* Define to 1 if you have the <inttypes.h> header file. */
  31. #define HAVE_INTTYPES_H 1

  32. /* use ioctlsocket() for non-blocking sockets */
  33. /* #undef HAVE_IOCTLSOCKET */

  34. /* use Ioctlsocket() for non-blocking sockets */
  35. /* #undef HAVE_IOCTLSOCKET_CASE */

  36. /* Define if you have the gcrypt library. */
  37. /* #undef HAVE_LIBGCRYPT */

  38. /* Define if you have the ssl library. */
  39. #define HAVE_LIBSSL 1

  40. /* Define if you have the z library. */
  41. #define HAVE_LIBZ 1

  42. /* Define to 1 if the compiler supports the 'long long' data type. */
  43. #define HAVE_LONGLONG 1

  44. /* Define to 1 if you have the <memory.h> header file. */
  45. #define HAVE_MEMORY_H 1

  46. /* Define to 1 if you have the <netinet/in.h> header file. */
  47. #define HAVE_NETINET_IN_H 1

  48. /* use O_NONBLOCK for non-blocking sockets */
  49. #define HAVE_O_NONBLOCK 1

  50. /* Define to 1 if you have the `poll' function. */
  51. #define HAVE_POLL 1

  52. /* Define to 1 if you have the select function. */
  53. #define HAVE_SELECT 1

  54. /* use SO_NONBLOCK for non-blocking sockets */
  55. /* #undef HAVE_SO_NONBLOCK */

  56. /* Define to 1 if you have the <stdint.h> header file. */
  57. #define HAVE_STDINT_H 1

  58. /* Define to 1 if you have the <stdio.h> header file. */
  59. #define HAVE_STDIO_H 1

  60. /* Define to 1 if you have the <stdlib.h> header file. */
  61. #define HAVE_STDLIB_H 1

  62. /* Define to 1 if you have the <strings.h> header file. */
  63. #define HAVE_STRINGS_H 1

  64. /* Define to 1 if you have the <string.h> header file. */
  65. #define HAVE_STRING_H 1

  66. /* Define to 1 if you have the `strtoll' function. */
  67. #define HAVE_STRTOLL 1

  68. /* Define to 1 if you have the <sys/ioctl.h> header file. */
  69. #define HAVE_SYS_IOCTL_H 1

  70. /* Define to 1 if you have the <sys/select.h> header file. */
  71. #define HAVE_SYS_SELECT_H 1

  72. /* Define to 1 if you have the <sys/socket.h> header file. */
  73. #define HAVE_SYS_SOCKET_H 1

  74. /* Define to 1 if you have the <sys/stat.h> header file. */
  75. #define HAVE_SYS_STAT_H 1

  76. /* Define to 1 if you have the <sys/time.h> header file. */
  77. #define HAVE_SYS_TIME_H 1

  78. /* Define to 1 if you have the <sys/types.h> header file. */
  79. #define HAVE_SYS_TYPES_H 1

  80. /* Define to 1 if you have the <sys/uio.h> header file. */
  81. #define HAVE_SYS_UIO_H 1

  82. /* Define to 1 if you have the <unistd.h> header file. */
  83. #define HAVE_UNISTD_H 1

  84. /* Define to 1 if you have the <windows.h> header file. */
  85. /* #undef HAVE_WINDOWS_H */

  86. /* Define to 1 if you have the <winsock2.h> header file. */
  87. /* #undef HAVE_WINSOCK2_H */

  88. /* Define to 1 if you have the <ws2tcpip.h> header file. */
  89. /* #undef HAVE_WS2TCPIP_H */

  90. /* Enable "none" cipher -- NOT RECOMMENDED */
  91. /* #undef LIBSSH2_CRYPT_NONE */

  92. /* Enable newer diffie-hellman-group-exchange-sha1 syntax */
  93. #define LIBSSH2_DH_GEX_NEW 1

  94. /* Compile in zlib support */
  95. #define LIBSSH2_HAVE_ZLIB 1

  96. /* Use libgcrypt */
  97. /* #undef LIBSSH2_LIBGCRYPT */

  98. /* Enable "none" MAC -- NOT RECOMMENDED */
  99. /* #undef LIBSSH2_MAC_NONE */

  100. /* Define to the sub-directory in which libtool stores uninstalled libraries.
  101.    */
  102. #define LT_OBJDIR ".libs/"

  103. /* Define to 1 if _REENTRANT preprocessor symbol must be defined. */
  104. /* #undef NEED_REENTRANT */

  105. /* Name of package */
  106. #define PACKAGE "libssh2"

  107. /* Define to the address where bug reports for this package should be sent. */
  108. #define PACKAGE_BUGREPORT "libssh2-[email]devel@lists.sourceforge.net[/email]"

  109. /* Define to the full name of this package. */
  110. #define PACKAGE_NAME "libssh2"

  111. /* Define to the full name and version of this package. */
  112. #define PACKAGE_STRING "libssh2 -"

  113. /* Define to the one symbol short name of this package. */
  114. #define PACKAGE_TARNAME "libssh2"

  115. /* Define to the version of this package. */
  116. #define PACKAGE_VERSION "-"

  117. /* If using the C implementation of alloca, define if you know the
  118.    direction of stack growth for your system; otherwise it will be
  119.    automatically deduced at runtime.
  120.         STACK_DIRECTION > 0 => grows toward higher addresses
  121.         STACK_DIRECTION < 0 => grows toward lower addresses
  122.         STACK_DIRECTION = 0 => direction of growth unknown */
  123. /* #undef STACK_DIRECTION */

  124. /* Define to 1 if you have the ANSI C header files. */
  125. #define STDC_HEADERS 1

  126. /* Version number of package */
  127. #define VERSION "1.2"

  128. /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
  129.    significant byte first (like Motorola and SPARC, unlike Intel). */
  130. #if defined AC_APPLE_UNIVERSAL_BUILD
  131. # if defined __BIG_ENDIAN__
  132. #  define WORDS_BIGENDIAN 1
  133. # endif
  134. #else
  135. # ifndef WORDS_BIGENDIAN
  136. /* #  undef WORDS_BIGENDIAN */
  137. # endif
  138. #endif

  139. /* Number of bits in a file offset, on hosts where this is settable. */
  140. #define _FILE_OFFSET_BITS 64

  141. /* Define for large files, on AIX-style hosts. */
  142. /* #undef _LARGE_FILES */

  143. /* Define to empty if `const' does not conform to ANSI C. */
  144. /* #undef const */

  145. /* Define to `__inline__' or `__inline' if that's what the C compiler
  146.    calls it, or to nothing if 'inline' is not supported under any name.  */
  147. #ifndef __cplusplus
  148. /* #undef inline */
  149. #endif

复制代码

论坛徽章:
0
5 [报告]
发表于 2010-01-13 13:03 |只看该作者
编译:
      gcc   -lssh2  -o server server.c  libssh2_exec.* libssh2_config.h

运行:
       ./server

论坛徽章:
0
6 [报告]
发表于 2010-01-13 13:05 |只看该作者
明天给10个小手,今天没有了。
gcc   -lssh2  -o server server.c  libssh2_exec.* libssh2_config.h
*是什么意思啊?
这个server的功能是?

论坛徽章:
0
7 [报告]
发表于 2010-01-13 13:08 |只看该作者
libssh2_exec.*==libssh2_exec.c + libssh2_exec.h


连接到sshd,执行命令。

[ 本帖最后由 diyself 于 2010-1-13 13:09 编辑 ]

论坛徽章:
0
8 [报告]
发表于 2010-01-13 13:11 |只看该作者
那么不交互,我指定多个命令,怎么个写法啊?
比如,我指定ls update 和 pwd 命令

论坛徽章:
0
9 [报告]
发表于 2010-01-13 13:13 |只看该作者

回复 #8 prolj 的帖子

请看三楼

论坛徽章:
0
10 [报告]
发表于 2010-01-13 13:16 |只看该作者

回复 #9 diyself 的帖子

谢谢!忙完手头的东西慢慢看。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP