zoukankan      html  css  js  c++  java
  • ssh2.cpp

    //============================================================================
    // Name : ssh2.cpp
    // Author :
    // Version :
    // Copyright : Your copyright notice
    // Description : Hello World in C++, Ansi-style
    //============================================================================

    #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 <iostream>
    #include <sys/time.h>
    #include <sys/types.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <errno.h>
    #include <stdio.h>
    #include <ctype.h>
    #include <iostream>
    #include <string.h>
    #include <vector>

    using namespace std;
    vector<string> Split(const char* data,const char c)
    {
    vector<string> vec;
    size_t cur = 0;
    string strData(data);
    int len = strlen(data) + 1;
    while((int)cur < len)
    {
    string::size_type pos = strData.find(c,cur);
    if (pos == string::npos)
    {
    break;
    }

    string s = strData.substr(cur,pos - cur);
    vec.push_back(s);
    cur = pos + 1;
    }

    string s = strData.substr(cur,len - cur);
    vec.push_back(s);

    return vec;
    }
    int readfile(const char* filename ,char** ppBuf)
    {
    FILE* fp;
    fp = fopen(filename,"rb");
    if(fp == NULL)
    {
    fprintf(stdout,"open file %s error! ", filename);
    return -1;
    }

    fseek(fp, 0, SEEK_END);
    int len = ftell(fp);
    fseek(fp, 0, SEEK_SET);
    *ppBuf = new char[len];
    memset(*ppBuf, 0, len);
    fread(*ppBuf, 1, len, fp);
    fclose(fp);
    return len;
    }

    int 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 test(const char *hostname,const char *username,const char *password)
    {
    unsigned long hostaddr;
    int sock;
    struct sockaddr_in sin;
    const char *fingerprint;
    LIBSSH2_SESSION *session;
    LIBSSH2_CHANNEL *channel;
    int rc;
    int exitcode;
    char *exitsignal=(char *)"none";
    int bytecount = 0;
    size_t len;
    LIBSSH2_KNOWNHOSTS *nh;
    int type;
    char * command = NULL;
    #ifdef WIN32
    WSADATA wsadata;
    WSAStartup(MAKEWORD(2,0), &wsadata);
    #endif

    rc = libssh2_init (0);
    if (rc != 0) {
    fprintf (stdout, "libssh2 initialization failed (%d) ", rc);
    return 1;
    }

    hostaddr = inet_addr(hostname);

    /* Ultra basic "connect to port 22 on localhost"
    * Your code is responsible for creating the socket establishing the
    * connection
    */
    sock = socket(AF_INET, SOCK_STREAM, 0);

    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) {
    fprintf(stdout, "failed to connect! ");
    return -1;
    }

    /* Create a session instance */
    session = libssh2_session_init();
    if (!session)
    return -1;

    /* 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
    */
    while ((rc = libssh2_session_startup(session, sock)) ==
    LIBSSH2_ERROR_EAGAIN);
    if (rc) {
    fprintf(stdout, "Failure establishing SSH session: %d ", rc);
    return -1;
    }

    nh = libssh2_knownhost_init(session);
    if(!nh) {
    /* eeek, do cleanup here */
    return 2;
    }

    /* read all hosts from here */
    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(session, &len, &type);
    if(fingerprint) {
    struct libssh2_knownhost *host;
    #if LIBSSH2_VERSION_NUM >= 0x010206
    /* introduced in 1.2.6 */
    int check = libssh2_knownhost_checkp(nh, hostname, 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
    /*fprintf(stdout, "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 */
    return 3;
    }
    libssh2_knownhost_free(nh);

    if ( strlen(password) != 0 ) {
    /* We could authenticate via password */
    while ((rc = libssh2_userauth_password(session, username, password)) ==
    LIBSSH2_ERROR_EAGAIN);
    if (rc) {
    fprintf(stdout, "1 %s %s Authentication by password failed(%d). ",username,password,rc);
    }
    else
    {
    fprintf(stdout, "0 %s %s",username,password);
    }
    }
    else {
    /* Or by public key */
    while ((rc = libssh2_userauth_publickey_fromfile(session, username,
    "/home/user/"
    ".ssh/id_rsa.pub",
    "/home/user/"
    ".ssh/id_rsa",
    password)) ==
    LIBSSH2_ERROR_EAGAIN);
    if (rc) {
    fprintf(stdout, "1 %s %s Authentication by public key failed(%d) ",username,password,rc);
    }
    else
    {
    fprintf(stdout, "0 %s %s",username,password);
    }
    }

    shutdown:

    libssh2_session_disconnect(session,
    "Normal Shutdown, Thank you for playing");
    libssh2_session_free(session);

    #ifdef WIN32
    closesocket(sock);
    #else
    close(sock);
    #endif
    //fprintf(stdout, "all done ");

    libssh2_exit();

    return rc;
    }

    int testecho(const char* hostname, const char* usr_pass,char aFlag, char bFlag)
    {
    vector<string> data = Split(usr_pass,bFlag);
    int size = data.size();
    if( size > 0)
    {
    for(int i = 0; i < size ; i ++)
    {
    string tmpstr = data[i];

    vector<string> info = Split(tmpstr.c_str(),aFlag);

    if(info.size() == 2)
    {
    string username = info[0];
    string password = info[1];
    if( 0 == test(hostname,username.c_str(),password.c_str()))
    {
    return 0;
    }
    }
    }
    }

    return 0;
    }

    int execute(const char *hostname,const char *username,const char *password,const char *typeparam,int _type)
    {
    unsigned long hostaddr;
    int sock;
    struct sockaddr_in sin;
    const char *fingerprint;
    LIBSSH2_SESSION *session;
    LIBSSH2_CHANNEL *channel;
    int rc;
    int exitcode;
    char *exitsignal=(char *)"none";
    int bytecount = 0;
    size_t len;
    LIBSSH2_KNOWNHOSTS *nh;
    int type;
    char * command = NULL;
    #ifdef WIN32
    WSADATA wsadata;
    WSAStartup(MAKEWORD(2,0), &wsadata);
    #endif

    rc = libssh2_init (0);
    if (rc != 0) {
    fprintf (stdout, "libssh2 initialization failed (%d) ", rc);
    return 1;
    }

    hostaddr = inet_addr(hostname);

    /* Ultra basic "connect to port 22 on localhost"
    * Your code is responsible for creating the socket establishing the
    * connection
    */
    sock = socket(AF_INET, SOCK_STREAM, 0);

    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) {
    fprintf(stdout, "failed to connect! ");
    return -1;
    }

    /* Create a session instance */
    session = libssh2_session_init();
    if (!session)
    return -1;

    /* 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
    */
    while ((rc = libssh2_session_startup(session, sock)) ==
    LIBSSH2_ERROR_EAGAIN);
    if (rc) {
    fprintf(stdout, "Failure establishing SSH session: %d ", rc);
    return -1;
    }

    nh = libssh2_knownhost_init(session);
    if(!nh) {
    /* eeek, do cleanup here */
    return 2;
    }

    /* read all hosts from here */
    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(session, &len, &type);
    if(fingerprint) {
    struct libssh2_knownhost *host;
    #if LIBSSH2_VERSION_NUM >= 0x010206
    /* introduced in 1.2.6 */
    int check = libssh2_knownhost_checkp(nh, hostname, 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
    /*fprintf(stdout, "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 */
    return 3;
    }
    libssh2_knownhost_free(nh);

    if ( strlen(password) != 0 ) {
    /* We could authenticate via password */
    while ((rc = libssh2_userauth_password(session, username, password)) ==
    LIBSSH2_ERROR_EAGAIN);
    if (rc) {
    fprintf(stdout, "Authentication by password failed(%d). ",rc);
    goto shutdown;
    }
    }
    else {
    /* Or by public key */
    while ((rc = libssh2_userauth_publickey_fromfile(session, username,
    "/home/user/"
    ".ssh/id_rsa.pub",
    "/home/user/"
    ".ssh/id_rsa",
    password)) ==
    LIBSSH2_ERROR_EAGAIN);
    if (rc) {
    fprintf(stdout, "Authentication by public key failed(rc) ",rc);
    goto shutdown;
    }
    }

    #if 0
    libssh2_trace(session, ~0 );
    #endif

    /* Exec non-blocking on the remove host */
    while( (channel = libssh2_channel_open_session(session)) == NULL &&
    libssh2_session_last_error(session,NULL,NULL,0) ==
    LIBSSH2_ERROR_EAGAIN )
    {
    waitsocket(sock, session);
    }
    if( channel == NULL )
    {
    fprintf(stdout,"channel Error ");
    goto shutdown;
    }

    if( 2 == _type)
    {
    int nLen = readfile(typeparam,&command);
    if(nLen == -1)
    {
    fprintf(stdout,"read file error! ");
    goto shutdown;
    }
    }
    else
    {
    int len = strlen(typeparam) + 1;
    command = new char[len];
    strncpy(command,typeparam,len);
    }

    while( (rc = libssh2_channel_exec(channel, command)) ==
    LIBSSH2_ERROR_EAGAIN )
    {
    waitsocket(sock, session);
    }
    if( rc != 0 )
    {
    fprintf(stdout,"Error ");
    goto shutdown;
    }
    for( ;; )
    {
    /* loop until we block */
    int rc;
    do
    {
    char buffer[0x4000];
    rc = libssh2_channel_read( channel, buffer, sizeof(buffer) );
    if( rc > 0 )
    {
    int i;
    bytecount += rc;
    //fprintf(stdout, "We read: ");
    for( i=0; i < rc; ++i )
    fputc( buffer[i], stdout);
    //fprintf(stdout, " ");
    }
    else {
    //fprintf(stdout, "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(sock, session);
    }
    else
    break;
    }
    exitcode = 127;
    while( (rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN )
    waitsocket(sock, session);

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

    /* if (exitsignal)
    printf(" Got signal: %s ", exitsignal);
    else
    printf(" EXIT: %d bytecount: %d ", exitcode, bytecount);
    */
    libssh2_channel_free(channel);
    channel = NULL;

    shutdown:

    if (NULL != command) delete[] command;

    libssh2_session_disconnect(session,
    "Normal Shutdown, Thank you for playing");
    libssh2_session_free(session);

    #ifdef WIN32
    closesocket(sock);
    #else
    close(sock);
    #endif
    //fprintf(stdout, "all done ");

    libssh2_exit();

    return 0;
    }

    int transfer(const char *hostname,const char *username,const char *password,const char *loclfile,const char *scppath)
    {
    unsigned long hostaddr;
    int sock, i, auth_pw = 1;
    struct sockaddr_in sin;
    const char *fingerprint;
    LIBSSH2_SESSION *session = NULL;
    LIBSSH2_CHANNEL *channel;
    FILE *local;
    int rc;
    char mem[1024];
    size_t nread;
    char *ptr;
    struct stat fileinfo;

    #ifdef WIN32
    WSADATA wsadata;

    WSAStartup(MAKEWORD(2,0), &wsadata);
    #endif

    if ( NULL != hostname) {
    hostaddr = inet_addr(hostname);
    } else {
    hostaddr = htonl(0x7F000001);
    }

    rc = libssh2_init (0);
    if (rc != 0) {
    fprintf (stdout, "libssh2 initialization failed (%d) ", rc);
    return 1;
    }

    local = fopen(loclfile, "rb");
    if (!local) {
    fprintf(stdout, "Can't open local file %s ", loclfile);
    return -1;
    }

    stat(loclfile, &fileinfo);

    /* Ultra basic "connect to port 22 on localhost"
    * Your code is responsible for creating the socket establishing the
    * connection
    */
    sock = socket(AF_INET, SOCK_STREAM, 0);
    if(-1 == sock) {
    fprintf(stdout, "failed to create socket! ");
    return -1;
    }

    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) {
    fprintf(stdout, "failed to connect! ");
    return -1;
    }

    /* Create a session instance
    */
    session = libssh2_session_init();
    if(!session)
    return -1;

    /* ... start it up. This will trade welcome banners, exchange keys,
    * and setup crypto, compression, and MAC layers
    */
    rc = libssh2_session_startup(session, sock);
    if(rc) {
    fprintf(stdout, "Failure establishing SSH session: %d ", rc);
    return -1;
    }

    /* At this point we havn't yet authenticated. The first thing to do
    * is check the hostkey's fingerprint against our known hosts Your app
    * may have it hard coded, may go to a file, may present it to the
    * user, that's your call
    */
    fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
    /* fprintf(stdout, "Fingerprint: ");
    for(i = 0; i < 20; i++) {
    fprintf(stdout, "%02X ", (unsigned char)fingerprint[i]);
    }
    fprintf(stdout, " ");
    */
    if (auth_pw) {
    /* We could authenticate via password */
    if (libssh2_userauth_password(session, username, password)) {
    fprintf(stdout, "Authentication by password failed. ");
    goto shutdown;
    }
    } else {
    /* Or by public key */
    if (libssh2_userauth_publickey_fromfile(session, username,
    "/home/username/.ssh/id_rsa.pub",
    "/home/username/.ssh/id_rsa",
    password)) {
    fprintf(stdout, " Authentication by public key failed ");
    goto shutdown;
    }
    }

    /* Send a file via scp. The mode parameter must only have permissions! */
    channel = libssh2_scp_send(session, scppath, fileinfo.st_mode & 0777,
    (unsigned long)fileinfo.st_size);

    if (!channel) {
    char *errmsg;
    int errlen;
    int err = libssh2_session_last_error(session, &errmsg, &errlen, 0);
    fprintf(stdout, "Unable to open a session: (%d) %s ", err, errmsg);
    goto shutdown;
    }

    //fprintf(stdout, "SCP session waiting to send file ");
    do {
    nread = fread(mem, 1, sizeof(mem), local);
    if (nread <= 0) {
    /* end of file */
    fprintf(stdout, "0 send success ");
    break;
    }
    ptr = mem;

    do {
    /* write the same data over and over, until error or completion */
    rc = libssh2_channel_write(channel, ptr, nread);
    if (rc < 0) {
    fprintf(stdout, "ERROR %d ", rc);
    break;
    }
    else {
    /* rc indicates how many bytes were written this time */
    ptr += rc;
    nread -= rc;
    }
    } while (nread);

    } while (1);

    //fprintf(stdout, "Sending EOF ");
    libssh2_channel_send_eof(channel);

    //fprintf(stdout, "Waiting for EOF ");
    libssh2_channel_wait_eof(channel);

    //fprintf(stdout, "Waiting for channel to close ");
    libssh2_channel_wait_closed(channel);

    libssh2_channel_free(channel);
    channel = NULL;

    shutdown:

    if(session) {
    libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing");
    libssh2_session_free(session);
    }
    #ifdef WIN32
    closesocket(sock);
    #else
    close(sock);
    #endif
    if (local)
    fclose(local);
    //fprintf(stdout, "all done ");

    libssh2_exit();

    return 0;
    }

    void Help(FILE* file, const char* program_name)
    {
    fprintf(file,
    "-------------------------------- "
    "Program information options: "
    " %s print help info "
    "-------------------------------- "
    "Example: "
    " %s ip username password type param "
    " --test connect: %s 10.3.2.171 "bomc/asiainfo|bomc1/asiainfo2" "/|" "
    " --test connect: %s 10.3.2.171 bomc asiainfo 0 "
    " --execute cmd: %s 10.3.2.171 bomc asiainfo 1 "cmd" "
    " --execut file content: %s 10.3.2.171 bomc asiainfo 2 shell_file_path_name "
    " --transfer file: %s 10.3.2.171 bomc asiainfo 3 source_path_file dest_path_file "
    " "
    , program_name
    , program_name
    , program_name
    , program_name
    , program_name
    , program_name
    );
    }

    int main(int argc, char *argv[])
    {
    if(argc < 3)
    {
    Help(stdout, argv[0]);
    return 0;
    }
    const char* programName = argv[0];
    const char *hostname = "127.0.0.1";
    const char *username = "user";
    const char *password = "password";
    int type = 0;
    const char *typeparam1 = "source_filename";
    const char *typeparam2 = "desc_temp_file";
    if (argc > 1)
    {
    /* must be ip address only */
    hostname = argv[1];
    }
    if (argc > 2) {
    username = argv[2];
    }
    if( 3 == argc)
    {
    return testecho(hostname,username,'/','|');
    }

    if (argc > 3) {
    password = argv[3];
    }

    if( 4 == argc)
    {
    if(2 == strlen(password))
    {
    return testecho(hostname,username,password[0],password[1]);
    }
    }

    if (argc > 4) {
    type = atoi(argv[4]);
    }

    if (argc > 5) {
    typeparam1 = argv[5];
    }

    switch(type)
    {
    case 0:
    test(hostname,username,password);
    break;
    case 1:
    case 2:
    execute(hostname,username,password,typeparam1,type);
    break;
    case 3:
    if (argc > 6) {
    typeparam2 = argv[6];
    }
    transfer(hostname,username,password,typeparam1,typeparam2);
    break;

    default:
    Help(stdout, argv[0]);
    break;
    }

    return 0;
    }

    makefile:

    SYSTYPE:=$(shell uname)
    CXX=g++

    LDFLAG=-g -DHAVE_SYS_SOCKET_H -DHAVE_ARPA_INET_H -DHAVE_UNISTD_H

    SSH2=/opt/wangcc/myDir/ssh/libssh2
    LIB=-I$(SSH2)/include $(SSH2)/lib -lssh2 -ldl -lcrypto -lz

    ssh2:ssh2.cpp
    $(CXX) -o ssh2 ssh2.cpp $(LDFLAG) $(LIB)
    clean:
    rm -f ssh2

  • 相关阅读:
    Reasoning and Learing学习笔记
    Study in JI During the Summer Vacation
    2018-计算机系机试-A
    2018-计算机系机试(第二批)-E-绝对值排序
    2018-计算机系机试(第二批)-D-最小差值
    2018-计算机系机试(第二批)-C-数字字符个数
    2018-计算机系机试(第二批)-B-二进制输出
    2018-计算机系机试(第二批)-A-最大数
    2018-软工机试-E-热河路(TLE只拿了90分,待思考)
    2015年四川省赛
  • 原文地址:https://www.cnblogs.com/wcc331902579/p/5912850.html
Copyright © 2011-2022 走看看