当前位置: 首页 > 工具软件 > libssh2 > 使用案例 >

c++对libssh2的封装,完成远程命令

彭鸿彩
2023-12-01

1.mSSH2头文件源码及说明

1.1源码

#include <libssh2.h>
#include <libssh2_sftp.h>
#include<string>
#include <arpa/inet.h>
#include <sys/socket.h>
using std::string;

enum MSSH2ErrorCode{
    socketError,
    initSSH2Error,
    connectError,
    initSessionError,
    passwordAuthenticationMethodNotAllow,
    usernameOrPasswordError,
    openSessionError,
    requestPtyError,
    openShellError,
    noError
};
class MSSH2
{
private:
    int sock;
    int rc;
    struct sockaddr_in sin;
    LIBSSH2_SESSION *session;
    LIBSSH2_CHANNEL *channel;
    MSSH2ErrorCode initSSH2();
    MSSH2ErrorCode connectSSH(const string &hostaddr);
    MSSH2ErrorCode initSession();
    MSSH2ErrorCode isAllowPasswordAuthenticationMethod(const string &username);
    MSSH2ErrorCode userauthPassword(const string &username,const string &password);
    MSSH2ErrorCode openSession();
    MSSH2ErrorCode requestPty();    // 保留
    MSSH2ErrorCode openShell(); // 保留
    void closeChannel();
    void closeSession();
public:
    MSSH2();
    MSSH2ErrorCode start(const string &hostaddr,const string &username,const string &password);
    string execCmd(const string &cmd);
    ~MSSH2();
};

1.2说明

private中包含了一些初始化操作需要用到的函数,比如初始化ssh,初始化会话,初始化套接字等。

public中包含了启动mSSH2和执行命令的函数。

该类的使用过程是:创建一个mSSH2对象,然后start,然后execCmd即可。使用过程比较简单,但是需要提前安装libssh2。

2.mSSH2的具体实现

#include "mSSH2.h"

MSSH2::MSSH2()
{
    sock = socket(AF_INET, SOCK_STREAM, 0);
}

MSSH2ErrorCode MSSH2::initSSH2()
{
    rc = libssh2_init(0);
    if (rc != 0)
    {
        return MSSH2ErrorCode::initSSH2Error;
    }
    return MSSH2ErrorCode::noError;
}

MSSH2ErrorCode MSSH2::connectSSH(const string &hostAddr)
{
    /* Ultra basic "connect to port 22 on localhost"
     * Your code is responsible for creating the socket establishing the
     * connection
     */
    unsigned long hostaddr = inet_addr(hostAddr.c_str());
    sin.sin_family = AF_INET;
    sin.sin_port = htons(22);
    sin.sin_addr.s_addr = hostaddr;
    if (connect(sock, (struct sockaddr *)(&sin), sizeof(struct sockaddr_in)) != 0)
    {
        return MSSH2ErrorCode::connectError;
    }
    return MSSH2ErrorCode::noError;
}

MSSH2ErrorCode MSSH2::initSession()
{
     /* Create a session instance */
    session = libssh2_session_init();

    /* tell libssh2 we want it all done non-blocking */
    // libssh2_session_set_blocking(session, 0);
    
    /* ... start it up. This will trade welcome banners, exchange keys,
     * and setup crypto, compression, and MAC layers
     */
    if (libssh2_session_handshake(session, sock))
    {
        return MSSH2ErrorCode::initSessionError;
    }
    return MSSH2ErrorCode::noError;
}

MSSH2ErrorCode MSSH2::isAllowPasswordAuthenticationMethod(const string &username)
{
    char *userauthlist = libssh2_userauth_list(session, username.c_str(), strlen(username.c_str()));
    if (strstr(userauthlist, "password") == NULL)
    {
        return MSSH2ErrorCode::passwordAuthenticationMethodNotAllow;
    }
    return MSSH2ErrorCode::noError;
}

MSSH2ErrorCode MSSH2::userauthPassword(const string &username, const string &password)
{
    if (libssh2_userauth_password(session, username.c_str(), password.c_str()))
    {
        return MSSH2ErrorCode::usernameOrPasswordError;
    }
    return MSSH2ErrorCode::noError;
}

MSSH2ErrorCode MSSH2::openSession()
{
    channel = libssh2_channel_open_session(session);
    if(!channel)
    {
        return MSSH2ErrorCode::openSessionError;
    }
    return MSSH2ErrorCode::noError;
}
// 弃用
MSSH2ErrorCode MSSH2::requestPty()
{
    if(libssh2_channel_request_pty(channel, "vanilla")) {
        return MSSH2ErrorCode::requestPtyError;
    }
    return MSSH2ErrorCode::noError;
}
//弃用
MSSH2ErrorCode MSSH2::openShell()
{
    if(libssh2_channel_shell(channel)) {
        return MSSH2ErrorCode::openShellError;
    }
    return MSSH2ErrorCode::noError;
}

MSSH2ErrorCode MSSH2::start(const string &hostaddr,const string &username,const string &password)
{
    if(sock == -1)
    {
        return MSSH2ErrorCode::socketError;
    }

    MSSH2ErrorCode mSSH2ErrorCode = initSSH2();
    if(mSSH2ErrorCode!=MSSH2ErrorCode::noError)
    {
        return mSSH2ErrorCode;
    }

    mSSH2ErrorCode = connectSSH(hostaddr);
    if(mSSH2ErrorCode!=MSSH2ErrorCode::noError)
    {
        return mSSH2ErrorCode;
    }

    mSSH2ErrorCode = initSession();
    if(mSSH2ErrorCode!=MSSH2ErrorCode::noError)
    {
        return mSSH2ErrorCode;
    }

    mSSH2ErrorCode = isAllowPasswordAuthenticationMethod(username);
    if(mSSH2ErrorCode!=MSSH2ErrorCode::noError)
    {
        return mSSH2ErrorCode;
    }

    mSSH2ErrorCode = userauthPassword(username,password);
    if(mSSH2ErrorCode!=MSSH2ErrorCode::noError)
    {
        return mSSH2ErrorCode;
    }

    mSSH2ErrorCode =openSession();
    if(mSSH2ErrorCode!=MSSH2ErrorCode::noError)
    {
        return mSSH2ErrorCode;
    }
    /*
    mSSH2ErrorCode =requestPty();
    if(mSSH2ErrorCode!=MSSH2ErrorCode::noError)
    {
        return mSSH2ErrorCode;
    }

    mSSH2ErrorCode =openShell();
    if(mSSH2ErrorCode!=MSSH2ErrorCode::noError)
    {
        return mSSH2ErrorCode;
    }
    */
    return MSSH2ErrorCode::noError;
}
string MSSH2::execCmd(const string &cmd)
{
    // exec cmd
    rc = libssh2_channel_exec(channel,cmd.c_str());
    if(rc !=0)
    {
        return "";
    }
    // get end
    char buffer[0x4000];
    rc = libssh2_channel_read(channel, buffer, sizeof(buffer) );
    if(rc >0)
    {
        return buffer;
    }
    else
    {
        return "";
    }
}

void MSSH2::closeChannel()
{
    int exitcode = 127;
    rc = libssh2_channel_close(channel);

    char *exitsignal = (char *)"none";
    if(rc == 0) {
        exitcode = libssh2_channel_get_exit_status(channel);
        libssh2_channel_get_exit_signal(channel, &exitsignal,
                                        NULL, NULL, NULL, NULL, NULL);
    }

    if(exitsignal)
        fprintf(stderr, "\nGot signal: %s\n", exitsignal);
    else
        fprintf(stderr, "\nEXIT: %d\n", exitcode);

    libssh2_channel_free(channel);
    channel = NULL;
}

void MSSH2::closeSession()
{
    libssh2_session_disconnect(session,
                               "Normal Shutdown, Thank you for playing");
    libssh2_session_free(session);
}

MSSH2::~MSSH2()
{
    if (channel)
    {
        closeChannel();
    }
    if (session)
    {
        closeSession();
    }
    close(sock);
    libssh2_exit();
}

3.mSSH2的使用

#include"mSSH2.h"
#include<iostream>
using std::cout;

int main(int argc,char *argv[])
{
    MSSH2 mSSH2;
    if(mSSH2.start("127.0.0.1","ubuntu","123456")!=MSSH2ErrorCode::noError)
    {
        cout<<"start error\n";
        return 0;
    }
    std::cout<<mSSH2.execCmd("ls -ltr");
    return 0;
}

 类似资料: