libssh2进行远程执行LINUX命令

来源:互联网 发布:unity3d 支持的模型 编辑:程序博客网 时间:2024/05/20 08:22

/*** CSSHClient.h* @file 说明信息..* DATE February 13 2015* * @author Ming_zhang*/ #ifndef _CSSHCLIENT_H_#define _CSSHCLIENT_H_/***********************Global Variable Declare***************///#define    -1;    ///< 定义 的宏为0。                                   ///////////////////////////////////////////////////////////////************************INCLUDE FILES*************************/#include <string>extern "C"{#include "libssh2.h"};using namespace std;////////////////////////////////////////////////////////////////*** @brief SSH2协议进行远程登录**/class CSSHClient{public:// Constructors & DestructorCSSHClient();virtual ~CSSHClient();static int Init();static int ClearUp();int Login(string sIp,int nPort,string sUser,string sPasswd);int Logout();int ExecuteCommand(string sCommand);private:int WaitSocket(int socket_fd, LIBSSH2_SESSION *session);private:SOCKET m_nSSHSocket;LIBSSH2_SESSION *m_hSSHSession ;LIBSSH2_CHANNEL *m_hSSHChannel ;};#endif
/*** CSSHClient.cpp* @file 说明信息..* DATE February 13 2015* * @author Ming_zhang*/ /************************INCLUDE FILES*************************/#include "stdafx.h"#include "CSSHClient.h"#include <libssh2.h>#ifdef HAVE_WINSOCK2_H#include <winsock2.h>#endif#ifdef HAVE_SYS_SOCKET_H#include <sys/socket.h>#endif#ifdef HAVE_NETINET_IN_H#include <netinet/in.h>#endif#ifdef HAVE_SYS_SELECT_H#include <sys/select.h>#endif#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#ifdef HAVE_ARPA_INET_H#include <arpa/inet.h>#endif#include <time.h>#include <sys/types.h>#include <stdlib.h>#include <fcntl.h>#include <errno.h>#include <stdio.h>#include <ctype.h>#include <stdexcept>using namespace std;#pragma  comment(lib,"libssh2.lib")///////////////////////////////////////////////////////////////CSSHClient::CSSHClient():m_nSSHSocket(INVALID_SOCKET),m_hSSHSession(0),m_hSSHChannel(0){}CSSHClient::~CSSHClient(){}int CSSHClient::WaitSocket(int socket_fd, LIBSSH2_SESSION *session){struct timeval timeout;int rc;fd_set fd;fd_set *writefd = NULL;fd_set *readfd = NULL;int dir;timeout.tv_sec = 10;timeout.tv_usec = 0;FD_ZERO(&fd);FD_SET(socket_fd, &fd);/* now make sure we wait in the correct direction */ dir = libssh2_session_block_directions(session);if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)readfd = &fd;if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)writefd = &fd;rc = select(socket_fd + 1, readfd, writefd, NULL, &timeout);return rc;}int CSSHClient::Login(string sIp,int nPort,string sUser,string sPasswd){ENTER_FUN(m_hSSHChannel);if(m_nSSHSocket!=INVALID_SOCKET){WLE("<%s>Error: m_nSSHSocket=[%d] can't relogin\n",_FUN_,m_nSSHSocket);return RET_FAIL;}string commandline ="ls /root/";char *exitsignal=(char *)"none";const char *fingerprint;int exitcode;#ifdef WIN32WSADATA wsadata;WSAStartup(MAKEWORD(2,0), &wsadata);#endifstruct sockaddr_in sin;int bytecount = 0;size_t len;LIBSSH2_KNOWNHOSTS *nh;int type;int rc = 0;//建立SOCKET 连接m_nSSHSocket = socket(AF_INET, SOCK_STREAM, 0);memset(&sin, 0, sizeof(struct sockaddr_in));sin.sin_family = AF_INET;sin.sin_port = htons(nPort);sin.sin_addr.S_un.S_addr = inet_addr(sIp.c_str());try{int nRet = connect(m_nSSHSocket, (struct sockaddr*)(&sin),sizeof(struct sockaddr_in));if ( nRet!= 0) {WLI("<%s>Error: connect==[%d]\n ",_FUN_);throw logic_error("Fail connect");}m_hSSHSession = libssh2_session_init();if (!m_hSSHSession){WLI("<%s>Error: libssh2_session_init = [%d]\n",_FUN_,m_hSSHSession);throw logic_error("Fail libssh2_session_init");}/* ... start it up. This will trade welcome banners, exchange keys,* and setup crypto, compression, and MAC layers*/ while ((rc = libssh2_session_handshake(m_hSSHSession, m_nSSHSocket)) ==LIBSSH2_ERROR_EAGAIN);if (rc) {WLI("<%s>Error: libssh2_session_handshake = [%d]\n",_FUN_,rc);throw logic_error("Fail libssh2_session_handshake");}nh = libssh2_knownhost_init(m_hSSHSession);if(!nh) {WLI("<%s>Error: libssh2_knownhost_init = [%d]\n",_FUN_,nh);throw logic_error("Fail libssh2_knownhost_init");}libssh2_knownhost_readfile(nh, "known_hosts",LIBSSH2_KNOWNHOST_FILE_OPENSSH);/* store all known hosts to here */ libssh2_knownhost_writefile(nh, "dumpfile",LIBSSH2_KNOWNHOST_FILE_OPENSSH);fingerprint = libssh2_session_hostkey(m_hSSHSession, &len, &type);if(fingerprint) {struct libssh2_knownhost *host;#if LIBSSH2_VERSION_NUM >= 0x010206/* introduced in 1.2.6 */ int check = libssh2_knownhost_checkp(nh, sIp.c_str(), 22,fingerprint, len,LIBSSH2_KNOWNHOST_TYPE_PLAIN|LIBSSH2_KNOWNHOST_KEYENC_RAW,&host);#else/* 1.2.5 or older */ int check = libssh2_knownhost_check(nh, hostname,fingerprint, len,LIBSSH2_KNOWNHOST_TYPE_PLAIN|LIBSSH2_KNOWNHOST_KEYENC_RAW,&host);#endifWLI( "Host check: %d, key: %s\n", check,(check <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?host->key:"<none>");/****** At this point, we could verify that 'check' tells us the key is* fine or bail out.*****/ }else {/* eeek, do cleanup here */ WLI("<%s>Error: libssh2_session_hostkey = [%d]\n",_FUN_,fingerprint);throw logic_error("Fail libssh2_session_hostkey");}libssh2_knownhost_free(nh);if ( strlen(sPasswd.c_str()) != 0 ) {/* We could authenticate via password */ while ((rc = libssh2_userauth_password(m_hSSHSession, sUser.c_str(), sPasswd.c_str())) ==LIBSSH2_ERROR_EAGAIN);if (rc) {WLI("<%s>Error: Authentication by password failed.\n",_FUN_,fingerprint);throw logic_error("Fail libssh2_userauth_password");}}else {/* Or by public key */ while ((rc = libssh2_userauth_publickey_fromfile(m_hSSHSession, sUser.c_str(),"/home/user/"".ssh/id_rsa.pub","/home/user/"".ssh/id_rsa",sPasswd.c_str())) ==LIBSSH2_ERROR_EAGAIN);if (rc) {WLI("<%s>Error: Authentication by public key failed.\n",_FUN_,fingerprint);throw logic_error("Fail libssh2_userauth_password");}}}catch (logic_error &e){WLE("<%s>Error: Desc[%s]\n",_FUN_,e.what());return RET_FAIL;}return RET_OK;}int CSSHClient::Logout(){char *exitsignal=(char *)"none";int exitcode= 0 ;int rc = 0;if(m_hSSHSession!=0){libssh2_session_disconnect(m_hSSHSession,"Normal Shutdown, Thank you for playing");libssh2_session_free(m_hSSHSession);m_hSSHSession = NULL;}if(m_nSSHSocket!=INVALID_SOCKET){#ifdef WIN32closesocket(m_nSSHSocket);#elseclose(m_nSSHSocket);#endifm_nSSHSocket = INVALID_SOCKET;}return RET_OK;}int CSSHClient::ExecuteCommand(string commandline){ENTER_FUN(CSSHClient::ExecuteCommand);if(m_hSSHSession==0){WLE("<%s>Error: m_hSSHSession==0 commandline[%s]\n",_FUN_,commandline.c_str());return RET_FAIL;}char *exitsignal=(char *)"none";/* Exec non-blocking on the remove host */ while( (m_hSSHChannel = libssh2_channel_open_session(m_hSSHSession)) == NULL &&libssh2_session_last_error(m_hSSHSession,NULL,NULL,0) ==LIBSSH2_ERROR_EAGAIN ){WaitSocket(m_nSSHSocket, m_hSSHSession);}if( m_hSSHChannel == NULL ){WLI("<%s>Error: libssh2_channel_open_session [%d].\n",_FUN_,m_hSSHChannel);//throw logic_error("Fail libssh2_channel_open_session");return RET_FAIL;}int bytecount = 0;int rc = 0;int exitcode = 0;while( (rc = libssh2_channel_exec(m_hSSHChannel, commandline.c_str()))==LIBSSH2_ERROR_EAGAIN ){WaitSocket(m_nSSHSocket, m_hSSHSession);}for( ;; ){/* loop until we block */ int rc;do{char buffer[0x4000];rc = libssh2_channel_read( m_hSSHChannel, buffer, sizeof(buffer) );if( rc > 0 ){int i;bytecount += rc;TRACE("We read:\n");for( i=0; i < rc; ++i )TRACE("%c",buffer[i]);TRACE("\n");}else {if( rc != LIBSSH2_ERROR_EAGAIN )TRACE( "libssh2_channel_read returned %d\n", rc);}}while( rc > 0 );/* this is due to blocking that would occur otherwise so we loop onthis condition */ if( rc == LIBSSH2_ERROR_EAGAIN ){WaitSocket(m_nSSHSocket, m_hSSHSession);}elsebreak;}if(m_hSSHChannel!=0){//释放 Channelwhile( (rc = libssh2_channel_close(m_hSSHChannel)) == LIBSSH2_ERROR_EAGAIN )WaitSocket(m_nSSHSocket, m_hSSHSession);if( rc == 0 ){exitcode = libssh2_channel_get_exit_status( m_hSSHChannel );libssh2_channel_get_exit_signal(m_hSSHChannel, &exitsignal,NULL, NULL, NULL, NULL, NULL);}if(m_hSSHChannel!=0)libssh2_channel_free(m_hSSHChannel);m_hSSHChannel = 0;}if( rc != 0 ){WLI("<%s>Error: libssh2_channel_exec [%d].\n",_FUN_,rc);return RET_FAIL;}WLE("<%s> Info:Success sCommand[%s]\n",_FUN_,commandline.c_str());return RET_OK;}int CSSHClient::Init(){ENTER_FUN(CSSHClient::Init);int rc = libssh2_init (0);if (rc != 0) {WLI("<%s>Error: libssh2_init = [%d]\n",_FUN_,rc);return RET_FAIL;}return RET_OK;}int CSSHClient::ClearUp(){libssh2_exit();return RET_OK;}


对 linux 服务器进行远程执行命令,可以通过 libss2 库进行,下面是 使用这个库的类的定义
</pre><pre name="code" class="cpp">



0 0