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 server进行远程运行命令。能够通过 libss2 库进行。以下是 使用这个库的类的定义
</pre><pre name="code" class="cpp">
浙公网安备 33010602011771号