libssh2进行远程执行LINUX命令

/**
* 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 & Destructor
	CSSHClient();
	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 WIN32
	WSADATA wsadata;
	WSAStartup(MAKEWORD(2,0), &wsadata);
#endif
	struct 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);
#endif
			WLI( "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 WIN32
		closesocket(m_nSSHSocket);
#else
		close(m_nSSHSocket);
#endif
		m_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 on
		this condition */ 
		if( rc == LIBSSH2_ERROR_EAGAIN )
		{
			WaitSocket(m_nSSHSocket, m_hSSHSession);
		}
		else
			break;
	}

	if(m_hSSHChannel!=0)
	{//释放 Channel
		while( (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">




郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。