예제 #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
  /**
   *  Blocks until the result code of the process has been returned.
   */
  int process::result() {
    if (!my->return_code && !my->return_signal) {
      // we don't have any cached exit status, so wait and obtain the values now
      my->sshc->my->call_ssh2_function(boost::bind(libssh2_channel_wait_eof, my->chan));
      my->sshc->my->call_ssh2_function_throw(boost::bind(libssh2_channel_wait_closed, my->chan),
                                                        "Error waiting on socket to close: ${message}");

      char* exit_signal;
      char* error_message;
      libssh2_channel_get_exit_signal(my->chan, &exit_signal, NULL, &error_message, NULL, NULL, NULL);
      if (exit_signal) {
        // process terminated with a signal
        my->return_signal = exit_signal;
        libssh2_free(my->chan->session, exit_signal);
        if (error_message) {
          my->return_signal_message = error_message;
          libssh2_free(my->chan->session, error_message);
        }
      } else
        my->return_code = libssh2_channel_get_exit_status(my->chan);
    }
    if (my->return_signal)
      FC_THROW("process terminated with signal ${signal}: ${signal_message}", ("signal", *my->return_signal)
                                                                              ("signal_message", my->return_signal_message ? *my->return_signal_message : ""));
    else
      return *my->return_code;
  }
예제 #4
0
int SSH2Channel::getExitStatus(ExceptionSink *xsink) {
   AutoLocker al(parent->m);
   if (check_open(xsink))
      return -1;

   return libssh2_channel_get_exit_status(channel);
}
예제 #5
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;
}
예제 #6
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;
	}
예제 #7
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;
}
예제 #8
0
void clear(LIBSSH2_SESSION *session, LIBSSH2_CHANNEL *channel, int sock)
{
    int exitcode = 127, rc;
    char *exitsignal=(char *)"none";
    if( rc == 0 )
    {
        exitcode = libssh2_channel_get_exit_status( channel );
        libssh2_channel_get_exit_signal(channel, &exitsignal, NULL, NULL, NULL, NULL, NULL);
    }

    libssh2_channel_free(channel);
    channel = NULL;

    libssh2_session_disconnect(session, "");
    libssh2_session_free(session);
    close(sock);
    libssh2_exit();
}
예제 #9
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;
}
예제 #10
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;
}
예제 #11
0
파일: ssh_lib.c 프로젝트: allspace/fexec
int ssh_exec(ssh_conn_t *conn, param_t *params)
{
	LIBSSH2_CHANNEL *channel;
    int rc;
    int exitcode = 127;
    char *exitsignal=(char *)"none";	
	const char *commandline = params->command;

    /* Exec non-blocking on the remove host */
    while( (channel = libssh2_channel_open_session(conn->session)) == NULL &&
           libssh2_session_last_error(conn->session,NULL,NULL,0) ==
           LIBSSH2_ERROR_EAGAIN )
    {
        waitsocket(conn);
    }
    if( channel == NULL )
    {
        fprintf(stderr,"Error\n");
        return ( 1 );
    }
	
	rc = ssh_setenv(channel, params);
	if(rc<0)
	{
		if(rc==LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED)
			printf("Error: Environment variable is not accepted by target SSH server.");
		goto shutdown;
	}
	
    while( (rc = libssh2_channel_exec(channel, commandline)) ==
           LIBSSH2_ERROR_EAGAIN )
    {
        waitsocket(conn);
    }
    if( rc != 0 )
    {
        fprintf(stderr,"Error\n");
        return ( 1 );
    }
	
	int stream_id = 0;
    for( ;; )
    {
        /* loop until we block */
        int rc;
        do
        {
            char buffer[0x4000];
            rc = libssh2_channel_read_ex( channel, stream_id, buffer, sizeof(buffer) );
            if( rc > 0 )
            {
				fwrite(buffer, sizeof(char), rc, stream_id==0?stdout:stderr);
            }else{
                if( rc != LIBSSH2_ERROR_EAGAIN ) goto shutdown;
            }
        }
        while( rc > 0 );

        /* this is due to blocking that would occur otherwise so we loop on
           this condition */
        if( rc == LIBSSH2_ERROR_EAGAIN )
        {
            waitsocket(conn);
        }
        else
            break;
			
		stream_id = stream_id==0?1:0;
    }
    
    while( (rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN )
        waitsocket(conn);

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


shutdown:
    libssh2_channel_free(channel);
    channel = NULL;

    return exitcode;
}
예제 #12
0
파일: tunnel.c 프로젝트: Tiedye/seashell
/**
 * usage: seashell-tunnel [username] [host] [target]
 *
 * First n bytes on standard input should be:
 *
 * ----------------------------------------------------------------------------------------------------------
 * | length / 4 byte unsigned integer | authentication method / 1 byte | authentication data : length bytes |
 * ----------------------------------------------------------------------------------------------------------
 *
 * Authentication methods:
 *  0 - password.
 *
 * Currently, only password authentication is supported.  Therefore,
 * the authentication method is ignored.  It might be worth looking
 * at supporting public key authentication in the future.  This'll
 * require extending the connection launcher.
 *
 * Bytes after n are simply forwarded onwards with no processing applied.
 *
 * For password authentication, the null terminating byte is expected to be in the authentication data.
 *
 * seashell-tunnel will write a single ASCII 'O' (79) denoting handshake success before starting
 * two-way forwarding.
 *
 * IP address are also written; IPv4 passed as X.X.X.X, IPv6 as [:X:X::X]
 */
int main (int argc, char *argv[]) {
  uint32_t length = 0;
  uint8_t method = 0;
  int8_t* data = NULL;
  int i = 0;
  char stderr_buffer[4096];
  ssize_t stderr_read = 0;

  if (argc < 4) {
    fprintf(stderr, "usage: %s [username] [host] [target]\n", argv[0]);
    return IO_ERROR;
  }

  FPRINTF_IF_DEBUG(stderr, "%s: Launching tunnel!\n", argv[1]);

  for (i = 0; i < 4; i++) {
    uint8_t buf;
    if (1 != read(0, &buf, 1)) {
      fprintf(stderr, "%s: I/O error on reading authentication packet length.\n", argv[1]);
      return IO_ERROR;
    }
    length |= buf << (8 * i);
  }
  FPRINTF_IF_DEBUG(stderr, "%s: Read authentication packet length.\n", argv[1]);

  if (1 != read(0, &method, 1)) {
    fprintf(stderr, "%s: I/O error on reading authentication method.\n", argv[1]);
    return IO_ERROR;
  }
  FPRINTF_IF_DEBUG(stderr, "%s: Read authentication method.\n", argv[1]);

  data = malloc(length);
  if (!data) {
    fprintf(stderr, "%s: Ran out of memory!\n", argv[1]);
    return OTHER_ERROR;
  }
  if (length != read(0, data, length)) {
    fprintf(stderr, "%s: Couldn't read authentication data!\n", argv[1]);
    return IO_ERROR;
  }
  FPRINTF_IF_DEBUG(stderr, "%s: Read authentication data.\n", argv[1]);

  /** This is where we need to handle extra authentication methods. */
  int error; char* exitsignal;

  error = seashell_tunnel_startup();
  if (error) {
    fprintf(stderr, "%s: Error launching libssh2!\n", argv[1]);
    goto end;
  }

  char remote_addr[128];
  memset(remote_addr, 0, 128);
  int family;

  struct seashell_connection* conn = seashell_tunnel_connect_password(
      argv[2], argv[1], data, &error, remote_addr, &family, argv[3]);

  if (!conn) {
    fprintf(stderr, "%s: Error on opening tunnel to %s: %d\n", argv[1], argv[2], error);
    goto end;
  }

  /** Signal success */
  {
    const int8_t success = 'O';
    write(1, &success, 1);
    uint8_t addrlen = strlen(remote_addr);

    /** Write the address, formatted for URI safety. */

    /** IPv6 addresses need to be formatted for safety. */
    if (family == AF_INET6) {
      char buffer[130] = {0};
      int bufferlen = snprintf(buffer, 130, "[%s]", remote_addr);
          
      write(1, &bufferlen, 1);
      write(1, buffer, bufferlen);
    }
    /** IPv4 addresses do not need to be formatted. */
    else if (family == AF_INET) {
      write(1, &addrlen, 1);
      write(1, remote_addr, addrlen);
    } else {
      fprintf(stderr, "%s: Unknown address family %d!\n", argv[1], family);
      goto end;
    }

    FPRINTF_IF_DEBUG(stderr, "%s: Remote address is '%s' (%d) (%d)\n", argv[1], remote_addr, (int)addrlen, family);
  }
  FPRINTF_IF_DEBUG(stderr, "%s: Tunnel launched!\n", argv[1]);

  /** Now we select from fd 0, write to socket,
   *  select from socket, write to fd 1 */
  error = loop_and_copy(0, 1, conn);

  if (error) {
    fprintf(stderr, "%s: I/O error on copy: %d\n", argv[1], error);
    goto report_errors;
  }

  /** Make sure the remote end hung up cleanly. */
  error = libssh2_channel_get_exit_status(conn->channel);
  libssh2_channel_get_exit_signal(conn->channel, &exitsignal,
      NULL, NULL, NULL, NULL, NULL);

  FPRINTF_IF_DEBUG(stderr, "%s: Remote end hung up with %d (%s)\n", argv[1], error, exitsignal);

  if (exitsignal) {
    error = OTHER_ERROR;
  }
report_errors:
  /** Drain stderr on the SSH connection. */
  while ((stderr_read = libssh2_channel_read_stderr(conn->channel, stderr_buffer, sizeof(char)*4096)) > 0) {
    fwrite(stderr_buffer, sizeof(char), stderr_read, stderr);
  }
end:
  seashell_tunnel_free(conn);
  seashell_tunnel_teardown();
  return error;
}
예제 #13
0
//获取此分站范围内的设备IP
std::string CEasyssh::GetDeviceMAC(void)
{
	if (m_bIsErr)
	{
		//自动重连
		ConnectAP();
		return std::string("Error");
	}

	std::string str_ip_pool = "";

	char *exitsignal=(char *)"none";
	int rc = 0;
	const char *commandline = "/usr/www/wstalist ath0";
	/* Exec non-blocking on the remove host */ 
	LIBSSH2_CHANNEL *channel;

    while( (channel = libssh2_channel_open_session(m_ssh_session)) == NULL && 
			libssh2_session_last_error(m_ssh_session, NULL, NULL, 0) == LIBSSH2_ERROR_EAGAIN)
    {
        waitsocket(m_sock, m_ssh_session);
    }
    if(channel == NULL)
    {
		TRACE(_T("libssh2_channel_open_session Error\n"));
		return std::string("Error");
    }
    while( (rc = libssh2_channel_exec(channel, commandline)) == LIBSSH2_ERROR_EAGAIN)
    {
        waitsocket(m_sock, m_ssh_session);
    }
    if(rc != 0)
    {
		return std::string("Error");
    }
    for( ;; )
    {
        /* loop until we block */ 
        int rc;
        do
        {
            char buffer[0x4000];
            rc = libssh2_channel_read(channel, buffer, sizeof(buffer));

            if(rc > 0)
            {
				std::string str_temp(buffer, 0, rc);
				str_ip_pool += str_temp;
            }
        }
        while( rc > 0 );
 
        /* this is due to blocking that would occur otherwise so we loop on
           this condition */ 
        if( rc == LIBSSH2_ERROR_EAGAIN )
        {
            waitsocket(m_sock, m_ssh_session);
        }
        else
            break;
    }

    while( (rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN )
        waitsocket(m_sock, m_ssh_session);
 
    if( rc == 0 )
    {
        libssh2_channel_get_exit_status(channel);
        libssh2_channel_get_exit_signal(channel, &exitsignal, NULL, NULL, NULL, NULL, NULL);
    }
 
    libssh2_channel_free(channel);
    channel = NULL;
	return str_ip_pool;
}
예제 #14
0
int oph_ssh_submit(const char *cmd)
{
	int sock;
	struct sockaddr_in sin;
	struct addrinfo hints, *result;
	LIBSSH2_SESSION *session;
	LIBSSH2_CHANNEL *channel;
	int rc;
	int exitcode;
	char *exitsignal = (char *) "none";
	int bytecount = 0;

	memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_family = AF_INET;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_flags = 0;
	hints.ai_protocol = 0;
	result = NULL;
	rc = getaddrinfo(oph_ip_target_host, NULL, &hints, &result);
	if (rc != 0) {
		pmesg_safe(&global_flag, LOG_ERROR, __FILE__, __LINE__, "Unable to resolve address from target hostname: %s\n", gai_strerror(rc));
		return OPH_LIBSSH_ERROR;
	}

	sock = socket(AF_INET, SOCK_STREAM, 0);
	sin.sin_family = AF_INET;
	sin.sin_port = htons(22);
	sin.sin_addr.s_addr = ((struct sockaddr_in *) result->ai_addr)->sin_addr.s_addr;
	freeaddrinfo(result);
	if (connect(sock, (struct sockaddr *) (&sin), sizeof(struct sockaddr_in)) != 0) {
#ifdef WIN32
		closesocket(sock);
#else
		close(sock);
#endif
		pmesg_safe(&global_flag, LOG_ERROR, __FILE__, __LINE__, "Failed to connect to submission host\n");
		return OPH_LIBSSH_ERROR;
	}

	pthread_mutex_lock(&libssh2_flag);	// Lock the access to SSH library
	pmesg_safe(&global_flag, LOG_DEBUG, __FILE__, __LINE__, "SSH2 library locked\n");

	rc = libssh2_init(0);
	if (rc != 0) {
#ifdef WIN32
		closesocket(sock);
#else
		close(sock);
#endif
		pthread_mutex_unlock(&libssh2_flag);
		pmesg_safe(&global_flag, LOG_ERROR, __FILE__, __LINE__, "libssh2 initialization failed (%d)\n", rc);
		return OPH_LIBSSH_ERROR;
	}

	session = libssh2_session_init();
	if (!session) {
#ifdef WIN32
		closesocket(sock);
#else
		close(sock);
#endif
		libssh2_exit();
		pthread_mutex_unlock(&libssh2_flag);
		pmesg_safe(&global_flag, LOG_ERROR, __FILE__, __LINE__, "Failed to init ssh sessione\n");
		return OPH_LIBSSH_ERROR;
	}

	libssh2_session_set_blocking(session, 0);

	while ((rc = libssh2_session_handshake(session, sock)) == LIBSSH2_ERROR_EAGAIN);
	if (rc) {
		libssh2_session_disconnect(session, "Session disconnected");
		libssh2_session_free(session);
#ifdef WIN32
		closesocket(sock);
#else
		close(sock);
#endif
		libssh2_exit();
		pthread_mutex_unlock(&libssh2_flag);
		pmesg_safe(&global_flag, LOG_ERROR, __FILE__, __LINE__, "Failure establishing SSH session: %d\n", rc);
		return OPH_LIBSSH_ERROR;
	}

	while ((rc = libssh2_userauth_publickey_fromfile(session, oph_subm_user, oph_subm_user_publk, oph_subm_user_privk, "")) == LIBSSH2_ERROR_EAGAIN);
	if (rc) {
		libssh2_session_disconnect(session, "Session disconnected");
		libssh2_session_free(session);
#ifdef WIN32
		closesocket(sock);
#else
		close(sock);
#endif
		libssh2_exit();
		pthread_mutex_unlock(&libssh2_flag);
		pmesg_safe(&global_flag, LOG_ERROR, __FILE__, __LINE__, "Authentication by public key failed\n");
		return OPH_LIBSSH_ERROR;
	}

	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) {
		libssh2_session_disconnect(session, "Session disconnected");
		libssh2_session_free(session);
#ifdef WIN32
		closesocket(sock);
#else
		close(sock);
#endif
		libssh2_exit();
		pthread_mutex_unlock(&libssh2_flag);
		pmesg_safe(&global_flag, LOG_ERROR, __FILE__, __LINE__, "Error during opening session channel\n");
		return OPH_LIBSSH_ERROR;
	}
	while ((rc = libssh2_channel_exec(channel, cmd)) == LIBSSH2_ERROR_EAGAIN) {
		waitsocket(sock, session);
	}
	if (rc != 0) {
		libssh2_channel_free(channel);
		libssh2_session_disconnect(session, "Session disconnected");
		libssh2_session_free(session);
#ifdef WIN32
		closesocket(sock);
#else
		close(sock);
#endif
		libssh2_exit();
		pthread_mutex_unlock(&libssh2_flag);
		pmesg_safe(&global_flag, LOG_ERROR, __FILE__, __LINE__, "Error during opening session channel\n");
		return OPH_LIBSSH_ERROR;
	}

	int flag = 0;
	for (;;) {
		int rc;
		do {
			char buffer[0x4000];
			rc = libssh2_channel_read(channel, buffer, sizeof(buffer));

			if (rc > 0) {
				int i;
				bytecount += rc;
				if (!flag) {
					pmesg_safe(&global_flag, LOG_DEBUG, __FILE__, __LINE__, "ssh submission returned:\n");
					flag = 1;
				}
				for (i = 0; i < rc; ++i)
					pmesg_safe(&global_flag, LOG_DEBUG, __FILE__, __LINE__, "%c\n", buffer[i]);
			} else if (rc != LIBSSH2_ERROR_EAGAIN)
				pmesg_safe(&global_flag, LOG_DEBUG, __FILE__, __LINE__, "ssh channel read returned %d\n", rc);
		}
		while (rc > 0);

		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)
		pmesg_safe(&global_flag, LOG_DEBUG, __FILE__, __LINE__, "ssh got signal %s\n", exitsignal);
	else
		pmesg_safe(&global_flag, LOG_DEBUG, __FILE__, __LINE__, "ssh exit code %d with: bytecount %d\n", exitcode, bytecount);

	libssh2_channel_free(channel);
	channel = NULL;

	libssh2_session_disconnect(session, "Session ended normally");
	libssh2_session_free(session);
#ifdef WIN32
	closesocket(sock);
#else
	close(sock);
#endif
	pmesg_safe(&global_flag, LOG_DEBUG, __FILE__, __LINE__, "Session ended normally\n");

	libssh2_exit();

	pthread_mutex_unlock(&libssh2_flag);	// Release the lock for SSH library
	pmesg_safe(&global_flag, LOG_DEBUG, __FILE__, __LINE__, "SSH2 library unlocked\n");

	return OPH_LIBSSH_OK;
}