예제 #1
2
int SSH2Utils::exec(const char *cmd) {
	m_execResultStr.clear();
	int rc = -1;
	LIBSSH2_CHANNEL *channel;
	/* Exec non-blocking on the remove host */
	while ((channel = libssh2_channel_open_session(m_session)) == NULL
			&& libssh2_session_last_error(m_session, NULL, NULL, 0)
					== LIBSSH2_ERROR_EAGAIN) {
		waitsocket();
	}
	if (channel == NULL) {
		fprintf(stderr, "Channel Error\n");
		m_errCode = 9;
		return -1;
	}

    /* Request a terminal with 'vanilla' terminal emulation
     * See /etc/termcap for more options
     */
    if (libssh2_channel_request_pty(channel, "vanilla")) {
        fprintf(stderr, "Failed requesting pty\n");
    }

    /* Open a SHELL on that pty */
    if (libssh2_channel_shell(channel)) {
        fprintf(stderr, "Unable to request shell on allocated pty\n");
    }

    libssh2_channel_write(channel, cmd, strlen(cmd));
    libssh2_channel_send_eof(channel);
	char buffer[BUF_SIZE];
	memset(buffer, 0, BUF_SIZE);
	rc = libssh2_channel_read(channel, buffer, BUF_SIZE);
	if (rc > 0) {
		m_execResultStr.append(buffer);
	}

	m_channelExitCode = 127;
	while ((rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN)
		waitsocket();
	if (rc == 0) {
		m_channelExitCode = libssh2_channel_get_exit_status(channel);
	}

skip_shell:
	if (channel) {
		libssh2_channel_free(channel);
		channel = NULL;
	}
	return rc;
}
예제 #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
파일: ssh.c 프로젝트: dmgctrl/libgit2
static void ssh_stream_free(git_smart_subtransport_stream *stream)
{
	ssh_stream *s = (ssh_stream *)stream;
	ssh_subtransport *t = OWNING_SUBTRANSPORT(s);
	int ret;
	
	GIT_UNUSED(ret);
	
	t->current_stream = NULL;
	
	if (s->channel) {
		libssh2_channel_close(s->channel);
        libssh2_channel_free(s->channel);
        s->channel = NULL;
	}
	
	if (s->session) {
		libssh2_session_free(s->session), s->session = NULL;
	}
	
	if (s->socket.socket) {
		ret = gitno_close(&s->socket);
		assert(!ret);
	}
	
	git__free(s->url);
	git__free(s);
}
예제 #4
0
파일: ssh.c 프로젝트: Nangal/libgit2
static void ssh_stream_free(git_smart_subtransport_stream *stream)
{
	ssh_stream *s = (ssh_stream *)stream;
	ssh_subtransport *t = OWNING_SUBTRANSPORT(s);
	int ret;

	GIT_UNUSED(ret);

	t->current_stream = NULL;

	if (s->channel) {
		libssh2_channel_close(s->channel);
		libssh2_channel_free(s->channel);
		s->channel = NULL;
	}

	if (s->session) {
		libssh2_session_free(s->session);
		s->session = NULL;
	}

	if (s->socket.socket) {
		(void)gitno_close(&s->socket);
		/* can't do anything here with error return value */
	}

	git__free(s->url);
	git__free(s);
}
예제 #5
0
void PJSSH::ExecuteCmd(const char* aCommand) const
{
  if( !SessionIsOk )
  {
    std::ostringstream o;
    o<<"Can not execute command since the SSH session is not set up ok. "
      "Last error message: ";
    throw std::logic_error(o.str());
  }

  // Try to open a channel to be used for executing the command.
  LIBSSH2_CHANNEL* channel = libssh2_channel_open_session(mSession);
  if( NULL == channel )
  {
    throw std::runtime_error("Could not open communication channel for "
        "executing remote command.");
  }

  //  Execute the command.
  if( -1 == libssh2_channel_exec(channel,aCommand))
  {
    throw std::runtime_error("Failed to execute the remote command.");
  }

  // Close the channel.
  libssh2_channel_close(channel);

  // Free resources.
  libssh2_channel_free(channel);
}
예제 #6
0
파일: ssh.c 프로젝트: Nemchinovrp/sonic-pi
static void ssh_stream_free(git_smart_subtransport_stream *stream)
{
	ssh_stream *s = (ssh_stream *)stream;
	ssh_subtransport *t;

	if (!stream)
		return;

	t = OWNING_SUBTRANSPORT(s);
	t->current_stream = NULL;

	if (s->channel) {
		libssh2_channel_close(s->channel);
		libssh2_channel_free(s->channel);
		s->channel = NULL;
	}

	if (s->session) {
		libssh2_session_free(s->session);
		s->session = NULL;
	}

	if (s->io) {
		git_stream_close(s->io);
		git_stream_free(s->io);
		s->io = NULL;
	}

	git__free(s->url);
	git__free(s);
}
예제 #7
0
static void
virNetSSHSessionDispose(void *obj)
{
    virNetSSHSessionPtr sess = obj;
    VIR_DEBUG("sess=0x%p", sess);

    if (!sess)
        return;

    if (sess->channel) {
        libssh2_channel_send_eof(sess->channel);
        libssh2_channel_close(sess->channel);
        libssh2_channel_free(sess->channel);
    }

    libssh2_knownhost_free(sess->knownHosts);
    libssh2_agent_free(sess->agent);

    if (sess->session) {
        libssh2_session_disconnect(sess->session,
                                   "libvirt: virNetSSHSessionFree()");
        libssh2_session_free(sess->session);
    }

    virNetSSHSessionAuthMethodsFree(sess);

    VIR_FREE(sess->channelCommand);
    VIR_FREE(sess->hostname);
    VIR_FREE(sess->knownHostsFile);
    VIR_FREE(sess->authPath);
}
예제 #8
0
CURLcode Curl_scp_done(struct connectdata *conn, CURLcode status,
                       bool premature)
{
  struct SSHPROTO *scp = conn->data->reqdata.proto.ssh;
  (void)premature; /* not used */

  Curl_safefree(scp->path);
  scp->path = NULL;

  if (scp->ssh_channel) {
    if (libssh2_channel_close(scp->ssh_channel) < 0) {
      infof(conn->data, "Failed to stop libssh2 channel subsystem\n");
    }
  }

  if (scp->ssh_session) {
    libssh2_session_disconnect(scp->ssh_session, "Shutdown");
    libssh2_session_free(scp->ssh_session);
    scp->ssh_session = NULL;
  }

  free(conn->data->reqdata.proto.ssh);
  conn->data->reqdata.proto.ssh = NULL;
  Curl_pgrsDone(conn);

  (void)status; /* unused */

  return CURLE_OK;
}
예제 #9
0
int ssh::quit_channel()
{
	int rc;

	exitcode = 127;
	while( (rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN )
	waitsocket(_sock_fd, session);

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

	if (exitsignal)
	{
		printf("\nGot signal: %s\n", exitsignal);      }
/*	else 
		printf("\nEXIT: %d bytecount: %d\n", exitcode, bytecount);*/

	libssh2_channel_free(channel);
	channel = NULL;
	return 0;
}
예제 #10
0
	bool RunCommand(const char *aCommand) {
		if (!mSessionOK) {
			return false;
		}
		LIBSSH2_CHANNEL *channel = libssh2_channel_open_session(mSession);
		if (channel == NULL) {
			strcpy(mErrorMessage, "Could not open SSH2 channel");
			return false;
		}
#ifdef libssh2_session_set_timeout
		libssh2_session_set_timeout(mTimeout);
#endif
		if (libssh2_channel_exec(channel, aCommand) == -1) {
			strcpy(mErrorMessage, "Could not execute SSH2 command");
			return false;
		}
		std::string response;
		char buf[1025];
		ssize_t size = 1024;
		while (size == 1024) {
			size = libssh2_channel_read(channel, buf, 1024);
			buf[size] = '\0';
			response += buf;
		}
		if (mResponse) {
			delete [] mResponse;
		}
		mResponse = new char[response.size()+1];
		strcpy(mResponse, response.c_str());
		libssh2_channel_close(channel);
		mExitCode = libssh2_channel_get_exit_status(channel);
		libssh2_channel_free(channel);
		return true;
	}
예제 #11
0
int exec_shell_script(char* fname, LIBSSH2_SESSION *session, LIBSSH2_CHANNEL **channel, int sock)
{
    int rc;
    if((rc=open_shell(session, channel, sock)) <0) return -1;
    
    FILE* cmdfile = fopen(fname, "r");
    if(cmdfile == NULL)
    {
        printf("open file %s errno: %s\n", fname, strerror(errno));
        exit(errno);
    }
    
    char buf[BUFSIZ];
    int i;
    
    
    do
    {
        fgets(buf, BUFSIZ, cmdfile);
        if(feof(cmdfile) == 1) break;
        write_channel(buf, session, *channel, sock);
    }while(!feof(cmdfile));
    
    strncpy(buf, "\nexit\n", 6);
    write_channel(buf, session, *channel, sock);
    read_channel(session, *channel, sock);
    fclose(cmdfile);
//    while((rc = libssh2_channel_close(*channel)) == LIBSSH2_ERROR_EAGAIN) waitsocket(sock, session);
    rc = libssh2_channel_close(*channel);
    return rc;
}
예제 #12
0
파일: parser.cpp 프로젝트: alexadmin/main
void Parser::closeChannel(LIBSSH2_CHANNEL *channel)
{
    if(channel)
    {
        //libssh2_channel_wait_closed(channel);
        libssh2_channel_close(channel);
        libssh2_channel_free(channel); // free will auto close the channel
    }
}
예제 #13
0
static int
netsnmp_ssh_close(netsnmp_transport *t)
{
    int rc = -1;
    netsnmp_ssh_addr_pair *addr_pair = NULL;

    if (t != NULL && t->data != NULL) {
	addr_pair = (netsnmp_ssh_addr_pair *) t->data;
    }

    if (t != NULL && addr_pair && t->sock >= 0) {
        DEBUGMSGTL(("ssh", "close fd %d\n", t->sock));

        if (addr_pair->channel) {
            libssh2_channel_close(addr_pair->channel);
            libssh2_channel_free(addr_pair->channel);
            addr_pair->channel = NULL;
        }

        if (addr_pair->session) {
            libssh2_session_disconnect(addr_pair->session, "Normal Shutdown");
            libssh2_session_free(addr_pair->session);
            addr_pair->session = NULL;
        }

#ifndef HAVE_CLOSESOCKET
        rc = close(t->sock);
#else
        rc = closesocket(t->sock);
#endif
        t->sock = -1;

#ifdef SNMPSSHDOMAIN_USE_EXTERNAL_PIPE

        if (!addr_pair->session && !addr_pair->channel) {
            /* XXX: make configurable */
            unlink(addr_pair->socket_path);
        }

#else /* we're called directly by sshd and use stdin/out */

        /* on the server: close stdin/out */
        close(STDIN_FILENO);
        close(STDOUT_FILENO);
#endif /* ! SNMPSSHDOMAIN_USE_EXTERNAL_PIPE */

    } else {

#ifndef SNMPSSHDOMAIN_USE_EXTERNAL_PIPE
        /* on the server: close stdin/out */
        close(STDIN_FILENO);
        close(STDOUT_FILENO);
#endif /* ! SNMPSSHDOMAIN_USE_EXTERNAL_PIPE */

    }
    return rc;
}
예제 #14
0
파일: channel.c 프로젝트: elektro79/ssh4py
static PyObject *
channel_close(SSH2_ChannelObj *self)
{
	int ret;

	Py_BEGIN_ALLOW_THREADS
	ret = libssh2_channel_close(self->channel);
	Py_END_ALLOW_THREADS

	CHECK_RETURN_CODE(ret, self->session)

	Py_RETURN_NONE;
}
예제 #15
0
파일: libssh2.cpp 프로젝트: ly20119/mooon
int CLibssh2::close_ssh_channel(void* channel, std::string* exitsignal, std::string* errmsg)
{
    int exitcode = 127; // 127: command not exists
    LIBSSH2_CHANNEL* channel_ = static_cast<LIBSSH2_CHANNEL*>(channel);

    while (channel_ != NULL)
    {
        int errcode = libssh2_channel_close(channel_);
        if (0 == errcode)
        {
            char* errmsg_ = NULL;
            char* exitsignal_ = NULL;

            exitcode = libssh2_channel_get_exit_status(channel_);
            if (exitcode != 0) // 0 success
            {
                // 调用端可以strerror(*exitcode)取得出错原因
                libssh2_channel_get_exit_signal(channel_, &exitsignal_, NULL, &errmsg_, NULL, NULL, NULL);
                if (errmsg_ != NULL)
                {
                    *errmsg = errmsg_;
                    free(errmsg_);
                }
                if (exitsignal_ != NULL)
                {
                    *exitsignal = exitsignal_;
                    free(exitsignal_);
                }
            }

            libssh2_channel_free(channel_);
            channel_ = NULL;
            break;
        }
        else if (LIBSSH2_ERROR_EAGAIN == errcode)
        {
            if (!timedwait_socket())
            {
                THROW_SYSCALL_EXCEPTION("channel close timeout", ETIMEDOUT, "poll");
            }
        }
        else
        {
            THROW_EXCEPTION(get_session_errmsg(), errcode);
        }
    }

    return exitcode;
}
예제 #16
0
int ssh_guac_client_free_handler(guac_client* client) {

    ssh_guac_client_data* guac_client_data = (ssh_guac_client_data*) client->data;

    /* Close SSH channel */
    if (guac_client_data->term_channel != NULL) {
        libssh2_channel_send_eof(guac_client_data->term_channel);
        libssh2_channel_close(guac_client_data->term_channel);
    }

    /* Free terminal */
    guac_terminal_free(guac_client_data->term);
    pthread_join(guac_client_data->client_thread, NULL);

    /* Free channels */
    libssh2_channel_free(guac_client_data->term_channel);

    /* Clean up SFTP */
    if (guac_client_data->sftp_session)
        libssh2_sftp_shutdown(guac_client_data->sftp_session);

    if (guac_client_data->sftp_ssh_session) {
        libssh2_session_disconnect(guac_client_data->sftp_ssh_session, "Bye");
        libssh2_session_free(guac_client_data->sftp_ssh_session);
    }

    /* Free session */
    if (guac_client_data->session != NULL)
        libssh2_session_free(guac_client_data->session);

    /* Free auth key */
    if (guac_client_data->key != NULL)
        ssh_key_free(guac_client_data->key);

    /* Free clipboard */
    guac_common_clipboard_free(guac_client_data->clipboard);

    /* Free cursors */
    guac_ssh_cursor_free(client, guac_client_data->ibar_cursor);
    guac_ssh_cursor_free(client, guac_client_data->blank_cursor);

    /* Free generic data struct */
    free(client->data);

    return 0;
}
예제 #17
0
파일: main.c 프로젝트: dgoulet/debind
/*
 * Get DNS query using SSH transport layer.
 */
static ssize_t dig_ssh_request(struct ssh_session *ssh_info,
		char *buf, size_t buf_size, ssize_t len)
{
	int ret;
	ssize_t recv_size;

	do {
		ret = libssh2_channel_write(ssh_info->channel, buf, len);
		if (ret < 0) {
			ERR("libssh2_channel_write: %d", ret);
			goto error;
		}
		DBG("DNS request of size %ld sent to ssh channel", len);

		recv_size = libssh2_channel_read(ssh_info->channel, buf, buf_size);
		if (recv_size < 0) {
			char *buf;
			ERR("SSH channel read failed");
			libssh2_session_last_error(ssh_info->session, &buf, NULL, 0);
			ERR("Failure: %s", buf);
		} else if (recv_size == 0) {
			ret = libssh2_channel_eof(ssh_info->channel);
			if (ret) {
				DBG("SSH server disconnected!");
				libssh2_channel_close(ssh_info->channel);
				libssh2_channel_free(ssh_info->channel);
				/* Create new channel */
				ret = ssh_setup_tunnel(ssh_info, dns_ip);
				if (ret < 0) {
					goto error;
				}
			}
		} else {
			DBG("DNS reply red from ssh channel (size: %ld)",
					recv_size);
			goto end;
		}
	} while (1);

end:
	return recv_size;

error:
	return -1;
}
예제 #18
0
int close_ssh_connection(void* ssh_session)
{
    int ec;
    SSH_SESSION* p_session;
    
    p_session = (SSH_SESSION*)ssh_session;
    if(!(login_check(p_session)))
    {
        debug_log(SSH_TERMINAL_NO_SESSION_ERROR, "close_ssh_connection : no session.");
        return SSH_TERMINAL_NO_SESSION_ERROR;
    }
    
    if(p_session->session_param->channel != NULL)
    {
        exit_thread(ssh_session);
    
        while((ec = libssh2_channel_close(p_session->session_param->channel)) == LIBSSH2_ERROR_EAGAIN)
        {
            waitsocket(p_session->session_param->sock, p_session->session_param->session, TIMEOUT_SEC);
        }
        libssh2_channel_free(p_session->session_param->channel);
        p_session->session_param->channel = NULL;
    }
    
    while((ec = libssh2_session_disconnect(p_session->session_param->session, "normal")) == LIBSSH2_ERROR_EAGAIN)
    {
        waitsocket(p_session->session_param->sock, p_session->session_param->session, TIMEOUT_SEC);
    }
    if(ec < 0)
    {
        debug_log(SSH_TERMINAL_SESSION_DISCONNECT_ERROR, "close_ssh_connection : disconnect failed.");
        return SSH_TERMINAL_SESSION_DISCONNECT_ERROR;
    }
    libssh2_session_free(p_session->session_param->session);
    close(p_session->session_param->sock);
    free(p_session->session_param);
    ori_thread_mutex_free(p_session->thread_param->command_queue_mutex);
    ori_thread_mutex_free(p_session->thread_param->add_list_mutex);
    ori_thread_condition_free(p_session->thread_param->command_queue_condition);
    ori_thread_condition_free(p_session->thread_param->add_list_condition);
    free(p_session->thread_param);
    free(p_session);
    
    return 0;
}
예제 #19
0
int guac_ssh_client_free_handler(guac_client* client) {

    guac_ssh_client* ssh_client = (guac_ssh_client*) client->data;

    /* Close SSH channel */
    if (ssh_client->term_channel != NULL) {
        libssh2_channel_send_eof(ssh_client->term_channel);
        libssh2_channel_close(ssh_client->term_channel);
    }

    /* Free terminal (which may still be using term_channel) */
    if (ssh_client->term != NULL) {
        guac_terminal_free(ssh_client->term);
        pthread_join(ssh_client->client_thread, NULL);
    }

    /* Free terminal channel now that the terminal is finished */
    if (ssh_client->term_channel != NULL)
        libssh2_channel_free(ssh_client->term_channel);

    /* Clean up the SFTP filesystem object and session */
    if (ssh_client->sftp_filesystem) {
        guac_common_ssh_destroy_sftp_filesystem(ssh_client->sftp_filesystem);
        guac_common_ssh_destroy_session(ssh_client->sftp_session);
    }

    /* Free interactive SSH session */
    if (ssh_client->session != NULL)
        guac_common_ssh_destroy_session(ssh_client->session);

    /* Free SSH client credentials */
    if (ssh_client->user != NULL)
        guac_common_ssh_destroy_user(ssh_client->user);

    /* Free parsed settings */
    if (ssh_client->settings != NULL)
        guac_ssh_settings_free(ssh_client->settings);

    /* Free client structure */
    free(ssh_client);

    guac_common_ssh_uninit();
    return 0;
}
예제 #20
0
static void
ssh_relay_teardown_cb(obfsproxyssh_client_session_t *session)
{
	struct evbuffer *buf;
	int rval;

	buf = bufferevent_get_input(session->socks_ev);
	if (1 == session->ssh_is_valid && 0 < evbuffer_get_length(buf)) {
		socks_relay_cb(session->socks_ev, session);
		return;
	}

	buf = bufferevent_get_output(session->ssh_ev);
	if (1 == session->ssh_is_valid && 0 < evbuffer_get_length(buf))
		return;

	if (NULL != session->ssh_channel) {
		rval = libssh2_channel_close(session->ssh_channel);
		if (LIBSSH2_ERROR_EAGAIN == rval)
			return;
		libssh2_channel_free(session->ssh_channel);
		session->ssh_channel = NULL;
	}

	if (1 == session->ssh_is_valid && 0 < evbuffer_get_length(buf))
		return;

	if (NULL != session->ssh_session) {
		rval = libssh2_session_disconnect(session->ssh_session,
				ssh_client_profile_get_disconnect_msg());
		if (LIBSSH2_ERROR_EAGAIN == rval)
			return;
		libssh2_session_free(session->ssh_session);
		session->ssh_session = NULL;
	}

	if (1 == session->ssh_is_valid && 0 < evbuffer_get_length(buf))
		return;

	session_free(session);
}
예제 #21
0
파일: ssh.c 프로젝트: davidreynolds/rtop
int open_channel_and_exec(LIBSSH2_SESSION *session, int sock, const char *cmd,
                          char **out)
{
    int rc;
    LIBSSH2_CHANNEL *chan;
    chan = waitfor_open_channel(session, sock);
    if (!chan)
        return -1;

    while ((rc = libssh2_channel_exec(chan, cmd)) == LIBSSH2_ERROR_EAGAIN)
        waitsocket(session, sock);
    if (rc != 0)
        return -1;

    rc = read_channel(chan, session, sock, out);

    while ((rc = libssh2_channel_close(chan)) == LIBSSH2_ERROR_EAGAIN)
        waitsocket(session, sock);
    libssh2_channel_free(chan);
    return 0;
}
예제 #22
0
파일: channel.c 프로젝트: wodny/pylibssh2
@return 0 on success or negative on failure\n\
@rtype int";

static PyObject *
PYLIBSSH2_Channel_close(PYLIBSSH2_CHANNEL *self, PyObject *args)
{
    int rc;

    Py_BEGIN_ALLOW_THREADS
    rc = libssh2_channel_close(self->channel);
    rc = libssh2_channel_wait_closed(self->channel);
    Py_END_ALLOW_THREADS

    if (rc) {
        /* CLEAN: PYLIBSSH2_CHANNEL_CANT_CLOSE_MSG */
        PyErr_SetString(PYLIBSSH2_Error, "Unable to close the channel.");
        return NULL; 
    }

    return Py_BuildValue("i", rc);
}
예제 #23
0
int SSH2Channel::close(ExceptionSink *xsink, int timeout_ms) {
   AutoLocker al(parent->m);
   if (check_open(xsink))
      return -1;

   BlockingHelper bh(parent);

   int rc;
   while (true) {
      rc = libssh2_channel_close(channel);
      if (rc == LIBSSH2_ERROR_EAGAIN) {
	 if ((rc = parent->waitSocketUnlocked(xsink, SSH2CHANNEL_TIMEOUT, "SSH2CHANNEL-CLOSE-ERROR", "SSH2Channel::close", timeout_ms)))
	    break;
	 continue;
      }
      if (rc < 0)
	 parent->doSessionErrUnlocked(xsink);
      break;
   }

   return rc;
}
예제 #24
0
int exec_one_cmd(char* cmd, LIBSSH2_SESSION *session, LIBSSH2_CHANNEL **channel, int sock)
{
    int rc;
    //while((*channel = libssh2_channel_open_session(session)) == NULL && libssh2_session_last_error(session,NULL,NULL,0) == LIBSSH2_ERROR_EAGAIN ) waitsocket(sock, session);
    *channel = libssh2_channel_open_session(session);
    if( *channel == NULL )
    {
        fprintf(stderr,"Error\n");
        exit(1);
    }
    
//    while((rc = libssh2_channel_exec(*channel, cmd)) == LIBSSH2_ERROR_EAGAIN ) waitsocket(sock, session);
    rc = libssh2_channel_exec(*channel, cmd);
    if(rc!=0)
    {
        fprintf(stderr,"Error\n");
        exit(1);
    }
    
    read_channel(session, *channel, sock);
//    while((rc = libssh2_channel_close(*channel)) == LIBSSH2_ERROR_EAGAIN) waitsocket(sock, session);
    rc = libssh2_channel_close(*channel);
    return rc;
}
예제 #25
0
static int exec_channel_command_exec(SSH_SESSION* p_session, const char* command, int (*callback)(char*, const char*, void*), void* obj)
{
    char* buffer;
    int buffer_length = COMMAND_RESULT_BUFFER_LENGTH;
    int ec;
    int result_code;
    LIBSSH2_CHANNEL* channel;
    
    while((ec = libssh2_channel_exec(p_session->session_param->channel, command)) == LIBSSH2_ERROR_EAGAIN)
    {
        waitsocket(p_session->session_param->sock, p_session->session_param->session, TIMEOUT_SEC);
    }
    if(ec < 0)
    {
        debug_log(SSH_TERMINAL_COMMAND_EXEC_ERROR, "sync_command_exec : channel exec failed.");
        return SSH_TERMINAL_COMMAND_EXEC_ERROR;
    }
    
    buffer = (char*)malloc(sizeof(char) * (buffer_length + 1));
    
    while(1)
    {
        do{
            memset(buffer, 0, buffer_length + 1);
            ec = libssh2_channel_read(p_session->session_param->channel, buffer, buffer_length);
            if(ec == 0)
            {
                ec = libssh2_channel_read_stderr(p_session->session_param->channel, buffer, buffer_length);
            }
            if(ec > 0)
            {
                callback(buffer, command, obj);
            }
        }
        while(ec > 0);
        
        if(ec == LIBSSH2_ERROR_EAGAIN)
        {
            waitsocket(p_session->session_param->sock, p_session->session_param->session, TIMEOUT_SEC);
        }
        else
        {
            break;
        }
    }
    free(buffer);
    if(ec < 0)
    {
        debug_log(SSH_TERMINAL_CHANNEL_READ_ERROR, "sync_command_exec : channel read failed.");
        result_code = SSH_TERMINAL_CHANNEL_READ_ERROR;
    }
    else
    {
        result_code = 0;
    }
    
    while(libssh2_channel_close(p_session->session_param->channel) == LIBSSH2_ERROR_EAGAIN)
    {
        waitsocket(p_session->session_param->sock, p_session->session_param->session, TIMEOUT_SEC);
    }
    
    libssh2_channel_free(p_session->session_param->channel);
    
    while((channel = libssh2_channel_open_session(p_session->session_param->session)) == NULL &&
          libssh2_session_last_error(p_session->session_param->session, NULL, NULL, 0) == LIBSSH2_ERROR_EAGAIN)
    {
        waitsocket(p_session->session_param->sock, p_session->session_param->session, TIMEOUT_SEC);
    }
    if(channel == NULL)
    {
        result_code = SSH_TERMINAL_CHANNEL_OPEN_ERROR;
    }
    
    p_session->session_param->channel = channel;
    
    return result_code;
}
예제 #26
0
int ssh_shell_channel_open(void* ssh_session)
{
    SSH_SESSION* p_session;
    LIBSSH2_CHANNEL* channel;
    int ec;
    
    p_session = (SSH_SESSION*)ssh_session;
    if(!(login_check(p_session)))
    {
        debug_log(SSH_TERMINAL_NO_SESSION_ERROR, "ssh_shell_channel_open : no session.");
        return SSH_TERMINAL_NO_SESSION_ERROR;
    }
    
    if(p_session->session_param->channel != NULL)
    {
        debug_log(SSH_TERMINAL_ALREADY_CHANNEL_OPEN, "ssh_shell_channel_open : already channel open.");
        return SSH_TERMINAL_ALREADY_CHANNEL_OPEN;
    }
    
    while((channel = libssh2_channel_open_session(p_session->session_param->session)) == NULL &&
          libssh2_session_last_error(p_session->session_param->session, NULL, NULL, 0) == LIBSSH2_ERROR_EAGAIN)
    {
        waitsocket(p_session->session_param->sock, p_session->session_param->session, TIMEOUT_SEC);
    }
    
    if(channel == NULL)
    {
        debug_log(SSH_TERMINAL_CHANNEL_OPEN_ERROR, "ssh_shell_channel_open : channel open failed.");
        return SSH_TERMINAL_CHANNEL_OPEN_ERROR;
    }
    
    while((ec = libssh2_channel_request_pty(channel, "vt100")) == LIBSSH2_ERROR_EAGAIN)
    {
        waitsocket(p_session->session_param->sock, p_session->session_param->session, TIMEOUT_SEC);;
    }
    if(ec < 0){
        debug_log(SSH_TERMINAL_REQUEST_PTY_ERROR, "ssh_shell_channel_open : request pty failed.");
        while(libssh2_channel_close(channel) == LIBSSH2_ERROR_EAGAIN)
        {
            waitsocket(p_session->session_param->sock, p_session->session_param->session, TIMEOUT_SEC);
        }
        libssh2_channel_free(channel);
        return SSH_TERMINAL_REQUEST_PTY_ERROR;
    }
    
    while((ec = libssh2_channel_request_pty_size(channel, DEFAULT_PTY_SIZE_WIDTH, DEFAULT_PTY_SIZE_HEIGHT)) == LIBSSH2_ERROR_EAGAIN)
    {
        waitsocket(p_session->session_param->sock, p_session->session_param->session, TIMEOUT_SEC);
    }
    if(ec < 0){
        debug_log(SSH_TERMINAL_REQUEST_PTY_ERROR, "ssh_shell_channel_open : request pty failed.");
        while(libssh2_channel_close(channel) == LIBSSH2_ERROR_EAGAIN)
        {
            waitsocket(p_session->session_param->sock, p_session->session_param->session, TIMEOUT_SEC);
        }
        libssh2_channel_free(channel);
        return SSH_TERMINAL_REQUEST_PTY_ERROR;
    }
    
    while((ec = libssh2_channel_shell(channel)) == LIBSSH2_ERROR_EAGAIN)
    {
        waitsocket(p_session->session_param->sock, p_session->session_param->session, TIMEOUT_SEC);
    }
    if(ec < 0)
    {
        debug_log(SSH_TERMINAL_SHELL_ERROR, "ssh_shell_channel_open : channel shell failed.");
        while(libssh2_channel_close(channel) == LIBSSH2_ERROR_EAGAIN)
        {
            waitsocket(p_session->session_param->sock, p_session->session_param->session, TIMEOUT_SEC);
        }
        libssh2_channel_free(channel);
        return SSH_TERMINAL_SHELL_ERROR;
    }
    
    p_session->session_param->channel = channel;
    p_session->session_param->channel_type = CHANNEL_TYPE_SHELL;
    
    return 0;
}
예제 #27
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;
}
예제 #28
0
파일: ssh.c 프로젝트: 3mao/stool
int ssh_cmd(SSH * pSsh,char * pCmdstr)
{
		int ret=0;
		int exitcode;
		char *exitsignal=(char *)"none";

	if (NULL==pSsh || NULL==pCmdstr)
	{
		return 0;
	}

	while( (pSsh->channel = libssh2_channel_open_session(pSsh->session)) == NULL &&
		libssh2_session_last_error(pSsh->session,NULL,NULL,0) ==
		LIBSSH2_ERROR_EAGAIN )
	{
		waitsocket(pSsh->sock_fd, pSsh->session);
	}
	if( pSsh->channel == NULL )
	{
		fprintf(stderr,"Error\n");
		exit( 1 );
	}
	while( (ret = libssh2_channel_exec(pSsh->channel, pCmdstr)) ==
		LIBSSH2_ERROR_EAGAIN )
	{
		waitsocket(pSsh->sock_fd, pSsh->session);
	}
	if( ret != 0 )
	{
		fprintf(stderr,"Error\n");
		exit( 1 );
	}

	for( ;; )
    {
        /* loop until we block */
        int rc;
        do
        {
            char buffer[0x4000];
            rc = libssh2_channel_read( pSsh->channel, buffer, sizeof(buffer) );
            if( rc > 0 )
            {
                int i;
                
                for( i=0; i < rc; ++i )
                    fputc( buffer[i], stdout);
                fprintf(stderr, "\n");
            }
            else {
                if( ret != LIBSSH2_ERROR_EAGAIN )
                    /* no need to output this for the EAGAIN case */
                    fprintf(stderr, "libssh2_channel_read returned %d\n", rc);
            }
        }
        while( ret > 0 );

        /* this is due to blocking that would occur otherwise so we loop on
           this condition */
        if( rc == LIBSSH2_ERROR_EAGAIN )
        {
            waitsocket(pSsh->sock_fd, pSsh->session);
        }
        else
            break;
    }
    exitcode = 127;
    while( (ret = libssh2_channel_close(pSsh->channel)) == LIBSSH2_ERROR_EAGAIN )
        waitsocket(pSsh->sock_fd, pSsh->session);

    if( ret == 0 )
    {
        exitcode = libssh2_channel_get_exit_status( pSsh->channel );
        libssh2_channel_get_exit_signal(pSsh->channel, &exitsignal,
                                        NULL, NULL, NULL, NULL, NULL);
    }

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

	fprintf(stderr,"\n*ssh_cmd::pcmdstr=%s\n",pCmdstr);


	return 0;
}
예제 #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
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;
}