zoukankan      html  css  js  c++  java
  • 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
    ",_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]
     ",_FUN_);
    			throw logic_error("Fail connect");
    		}
    
    		m_hSSHSession = libssh2_session_init();
    		if (!m_hSSHSession)
    		{
    			WLI("<%s>Error: libssh2_session_init = [%d]
    ",_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]
    ",_FUN_,rc);
    			throw logic_error("Fail libssh2_session_handshake");
    		}
    		nh = libssh2_knownhost_init(m_hSSHSession);
    		if(!nh) 
    		{
    			WLI("<%s>Error: libssh2_knownhost_init = [%d]
    ",_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
    ", 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] ",_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. ",_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. ",_FUN_,fingerprint); throw logic_error("Fail libssh2_userauth_password"); } } } catch (logic_error &e) { WLE("<%s>Error: Desc[%s] ",_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] ",_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]. ",_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: "); for( i=0; i < rc; ++i ) TRACE("%c",buffer[i]); TRACE(" "); } else { if( rc != LIBSSH2_ERROR_EAGAIN ) TRACE( "libssh2_channel_read returned %d ", 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]. ",_FUN_,rc); return RET_FAIL; } WLE("<%s> Info:Success sCommand[%s] ",_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] ",_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">
    
    



  • 相关阅读:
    Visual Studio使用Git忽略不想上传到远程仓库的文件
    使用git处理github中提交有冲突的pull request
    C#基础访问修饰符概述
    从代码角度理解NNLM(A Neural Probabilistic Language Model)
    命名实体识别数据预处理
    基于bert命名实体识别(一)数据处理
    transformer多头注意力的不同框架实现(tensorflow+pytorch)
    基于tensorflow的bilstm_crf的命名实体识别(数据集是msra命名实体识别数据集)
    python实现命名实体识别指标(实体级别)
    基于tensorflow的文本分类总结(数据集是复旦中文语料)
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/5149103.html
Copyright © 2011-2022 走看看