WinSsh2Proc.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. #include "StdAfx.h"
  2. #include "WinSsh2Proc.h"
  3. CWinSsh2Proc::CWinSsh2Proc(void)
  4. {
  5. }
  6. CWinSsh2Proc::~CWinSsh2Proc(void)
  7. {
  8. }
  9. bool CWinSsh2Proc::InitSocket()
  10. {
  11. WSADATA wsadata;
  12. int err = WSAStartup(MAKEWORD(2, 0), &wsadata);
  13. if( err != 0 ) {
  14. fprintf(stderr, "WSAStartup failed with error: %d\n", err);
  15. return false;
  16. }
  17. return true;
  18. }
  19. int CWinSsh2Proc::waitsocket(int socket_fd, LIBSSH2_SESSION *session)
  20. {
  21. struct timeval timeout;
  22. int rc;
  23. fd_set fd;
  24. fd_set *writefd = NULL;
  25. fd_set *readfd = NULL;
  26. int dir;
  27. timeout.tv_sec = 10;
  28. timeout.tv_usec = 0;
  29. FD_ZERO(&fd);
  30. FD_SET(socket_fd, &fd);
  31. /* now make sure we wait in the correct direction */
  32. dir = libssh2_session_block_directions(session);
  33. if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
  34. readfd = &fd;
  35. if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
  36. writefd = &fd;
  37. rc = select(socket_fd + 1, readfd, writefd, NULL, &timeout);
  38. return rc;
  39. }
  40. bool CWinSsh2Proc::ssh2_connect(std::string host, std::string user, std::string pwd, int port /*=22*/)
  41. {
  42. m_user = user;
  43. m_pwd = pwd;
  44. m_port = port;
  45. m_host = host;
  46. // 创建socket连接;
  47. unsigned long hostaddr = inet_addr(host.c_str());
  48. SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
  49. m_sin.sin_family = AF_INET;
  50. m_sin.sin_port = htons(port);
  51. m_sin.sin_addr.s_addr = hostaddr;
  52. if ( connect(sock, (const sockaddr*)&m_sin, sizeof(m_sin)) != 0 ) {
  53. printf("failed to connect!\n");
  54. return false;
  55. }
  56. closesocket(sock);
  57. return true;
  58. }
  59. /*
  60. void CWinSsh2Proc::ssh2_disconnect()
  61. {
  62. int rc;
  63. int bytecount = 0;
  64. int exitcode = 127;
  65. char *exitsignal = (char *)"none";
  66. m_bStatus = false;
  67. if ( m_pChannel == NULL )
  68. goto shutdown;
  69. while((rc = libssh2_channel_close(m_pChannel)) == LIBSSH2_ERROR_EAGAIN)
  70. waitsocket(m_sock, m_pSession);
  71. if(rc == 0) {
  72. exitcode = libssh2_channel_get_exit_status(m_pChannel);
  73. libssh2_channel_get_exit_signal(m_pChannel, &exitsignal, NULL, NULL, NULL, NULL, NULL);
  74. }
  75. if(exitsignal)
  76. fprintf(stderr, "\nGot signal: %s\n", exitsignal);
  77. else
  78. fprintf(stderr, "\nEXIT: %d bytecount: %d\n", exitcode, bytecount);
  79. libssh2_channel_free(m_pChannel);
  80. m_pChannel = NULL;
  81. shutdown:
  82. libssh2_session_disconnect(m_pSession, "Normal Shutdown, Thank you for playing");
  83. libssh2_session_free(m_pSession);
  84. m_pSession = NULL;
  85. #ifdef WIN32
  86. closesocket(m_sock);
  87. #else
  88. close(m_sock);
  89. #endif
  90. fprintf(stderr, "all done\n");
  91. libssh2_exit();
  92. }
  93. */
  94. bool CWinSsh2Proc::ssh2_execute_command(std::string cmd, std::string &result, DWORD dwTimeout /*= 1000*/)
  95. {
  96. int rc;
  97. bool bRet = false;
  98. SOCKET sock = INVALID_SOCKET;
  99. LIBSSH2_SESSION* pSession = NULL;
  100. LIBSSH2_CHANNEL* pChannel = NULL;
  101. if ( !ssh2_init_session(&pSession, sock) )
  102. return false;
  103. // 请求一个shell;
  104. while((pChannel= libssh2_channel_open_session(pSession)) == NULL &&
  105. libssh2_session_last_error(pSession, NULL, NULL, 0) == LIBSSH2_ERROR_EAGAIN) {
  106. waitsocket(sock, pSession);
  107. }
  108. if ( pChannel == NULL ) {
  109. printf("Error\n");
  110. goto shutdown;
  111. }
  112. #if 0
  113. // 请求一个模拟终端;
  114. if( libssh2_channel_request_pty(pChannel,"VT100") != LIBSSH2_ERROR_NONE ) {
  115. printf("ssh请求伪终端失败,退出。\n");
  116. goto skip_shell;
  117. }
  118. // 在模拟终端上开户shell;
  119. if(libssh2_channel_shell(pChannel) != LIBSSH2_ERROR_NONE ) {
  120. printf("ssh shell请求失败,退出\n");
  121. goto shutdown;
  122. }
  123. #else
  124. while((rc = libssh2_channel_exec(pChannel, cmd.c_str())) == LIBSSH2_ERROR_EAGAIN) {
  125. waitsocket(sock, pSession);
  126. }
  127. if ( rc != LIBSSH2_ERROR_NONE )
  128. goto skip_shell;
  129. #endif
  130. // 设置为阻塞模式;
  131. libssh2_channel_set_blocking(pChannel,0);
  132. if ( cmd.at(cmd.size()-1) != '\n' )
  133. cmd.append("\n");
  134. while((rc = libssh2_channel_write(pChannel, cmd.c_str(), cmd.size())) == LIBSSH2_ERROR_EAGAIN ) {
  135. printf("ssh写堵塞,重试\n");
  136. waitsocket(sock, pSession);
  137. }
  138. if ( rc < 0 )
  139. goto shutdown;
  140. Sleep(dwTimeout);
  141. ssh2_read_channel(pChannel, result);
  142. bRet = true;
  143. skip_shell:
  144. if(pChannel) {
  145. libssh2_channel_free(pChannel);
  146. pChannel = NULL;
  147. }
  148. shutdown:
  149. libssh2_session_disconnect(pSession,"Normal Shutdown, Thank you for playing");
  150. libssh2_session_free(pSession);
  151. #ifdef WIN32
  152. closesocket(sock);
  153. #else
  154. close(sock);
  155. #endif
  156. libssh2_exit();
  157. return bRet;
  158. }
  159. void CWinSsh2Proc::ssh2_read_channel(LIBSSH2_CHANNEL* pChannel, std::string &buffer)
  160. {
  161. if ( pChannel == NULL )
  162. return;
  163. int rc;
  164. char buf[1024] = "";
  165. buffer.clear();
  166. do {
  167. rc = libssh2_channel_read(pChannel, buf, sizeof(buf) - 1);
  168. if(rc > 0) {
  169. buf[rc] = 0;
  170. buffer.append(buf, rc);
  171. memset(buf, 0, sizeof(buf));
  172. }
  173. }while( rc > 0 );
  174. printf("%s \n", buffer.c_str());
  175. }
  176. bool CWinSsh2Proc::ssh2_init_session(LIBSSH2_SESSION** pSession, SOCKET &sock)
  177. {
  178. // 初始化库;
  179. int rc = libssh2_init(0);
  180. if ( rc != LIBSSH2_ERROR_NONE ) {
  181. fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
  182. return false;
  183. }
  184. sock = socket(AF_INET, SOCK_STREAM, 0);
  185. if ( connect(sock, (const sockaddr*)&m_sin, sizeof(m_sin)) != 0 ) {
  186. fprintf(stderr, "failed to connect!\n");
  187. return false;
  188. }
  189. // 建立ssh会话实例;
  190. *pSession = libssh2_session_init();
  191. libssh2_session_set_blocking(*pSession, 1);
  192. rc = libssh2_session_handshake(*pSession, sock);
  193. if ( rc != LIBSSH2_ERROR_NONE ){
  194. printf("Failure establishing SSH session: %d\n", rc);
  195. // 释放资源;
  196. SHUTDOWN(*pSession, sock)
  197. return false;
  198. }
  199. // 登录linux;
  200. rc = libssh2_userauth_password(*pSession, m_user.c_str(), m_pwd.c_str());
  201. if( rc != LIBSSH2_ERROR_NONE ) {
  202. printf("Authentication by password failed: %d\n", rc);
  203. // 释放资源;
  204. SHUTDOWN(*pSession, sock)
  205. return false;
  206. }
  207. return true;
  208. }
  209. bool CWinSsh2Proc::ssh2_sftp_download(std::string sftppath, std::string localpath)
  210. {
  211. SOCKET sock = -1;
  212. LIBSSH2_SESSION *session;
  213. LIBSSH2_SFTP *sftp_session;
  214. LIBSSH2_SFTP_HANDLE *sftp_handle;
  215. // 初始化库;
  216. int rc = libssh2_init(0);
  217. if ( rc != LIBSSH2_ERROR_NONE ) {
  218. fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
  219. return false;
  220. }
  221. // 创建socket连接;
  222. sock = socket(AF_INET, SOCK_STREAM, 0);
  223. if ( connect(sock, (const sockaddr*)&m_sin, sizeof(m_sin)) != 0 ) {
  224. fprintf(stderr, "failed to connect!\n");
  225. return false;
  226. }
  227. // 建立ssh会话实例;
  228. session = libssh2_session_init();
  229. /* Since we have set non-blocking, tell libssh2 we are blocking */
  230. libssh2_session_set_blocking(session, 1);
  231. //while ( LIBSSH2_ERROR_EAGAIN == (rc = libssh2_session_handshake(m_pSession, m_sock)) );
  232. rc = libssh2_session_handshake(session, sock);
  233. if ( rc != LIBSSH2_ERROR_NONE ){
  234. fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
  235. return false;
  236. }
  237. // 登录linux;
  238. bool bDone = false;
  239. //while ( LIBSSH2_ERROR_EAGAIN == (rc = libssh2_userauth_password(m_pSession, user.c_str(), pwd.c_str())));
  240. rc = libssh2_userauth_password(session, m_user.c_str(), m_pwd.c_str());
  241. if( rc != LIBSSH2_ERROR_NONE ) {
  242. fprintf(stderr, "Authentication by password failed: %d\n", rc);
  243. goto shutdown;
  244. }
  245. sftp_session = libssh2_sftp_init(session);
  246. if (!sftp_session) {
  247. goto shutdown;
  248. }
  249. /* Request a file via SFTP */
  250. sftp_handle = libssh2_sftp_open(sftp_session, sftppath.c_str(), LIBSSH2_FXF_READ, 0);
  251. if (!sftp_handle) {
  252. goto shutdown;
  253. }
  254. FILE *stream;
  255. if (fopen_s(&stream, localpath.c_str(), "wb") == 0) {
  256. do {
  257. char mem[1024];
  258. /* loop until we fail */
  259. rc = libssh2_sftp_read(sftp_handle, mem, sizeof(mem));
  260. if (rc > 0) {
  261. //从内存到磁盘
  262. fwrite(mem, 1, rc, stream);
  263. }
  264. else {
  265. break;
  266. }
  267. } while (1);
  268. bDone = true;
  269. fclose(stream);
  270. }
  271. libssh2_sftp_close(sftp_handle);
  272. libssh2_sftp_shutdown(sftp_session);
  273. shutdown:
  274. libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing");
  275. libssh2_session_free(session);
  276. closesocket(sock);//INVALID_SOCKET
  277. return bDone;
  278. }