Beispiel #1
3
int open_shell(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_request_pty(*channel, "vanilla")) == LIBSSH2_ERROR_EAGAIN ) waitsocket(sock, session);
    rc=libssh2_channel_request_pty(*channel, "vanilla");
    if( rc != 0 )
    {
        fprintf(stderr,"get pty Error %d\n", rc);
        exit(1);
    }
    
//    while((rc=libssh2_channel_shell(*channel)) == LIBSSH2_ERROR_EAGAIN ) waitsocket(sock, session);
    rc=libssh2_channel_shell(*channel);
    if( rc != 0 )
    {
        fprintf(stderr,"get shell Error %d\n", rc);
        exit(1);
    }
    return rc;
}
Beispiel #2
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;
}
void cql_ccm_bridge_t::start_ssh_connection(const cql_ccm_bridge_configuration_t& settings) {
  _ssh_internals->_session = libssh2_session_init();
  if (!_ssh_internals->_session)
    throw cql_ccm_bridge_exception_t("cannot create ssh session");

  try {
    if (libssh2_session_handshake(_ssh_internals->_session, _socket))
      throw cql_ccm_bridge_exception_t("ssh session handshake failed");

    // get authentication modes supported by server
    char* auth_methods = libssh2_userauth_list(_ssh_internals->_session,
                                               settings.ssh_username().c_str(),
                                               settings.ssh_username().size());

    int auth_result;
    if (!settings.ssh_public_key_file().empty() && !settings.ssh_private_key_file().empty()) {
      auth_result = libssh2_userauth_publickey_fromfile(_ssh_internals->_session,
                                                        settings.ssh_username().c_str(),
                                                        settings.ssh_public_key_file().c_str(),
                                                        settings.ssh_private_key_file().c_str(),
                                                        "");
    } else {
      if (strstr(auth_methods, "password") == NULL)
        throw cql_ccm_bridge_exception_t("server doesn't support authentication by password");

      // try to login using username and password
      auth_result = libssh2_userauth_password(_ssh_internals->_session,
                                              settings.ssh_username().c_str(),
                                              settings.ssh_password().c_str());
    }

    if (auth_result != 0)
      throw cql_ccm_bridge_exception_t("invalid password or user");

    if (!(_ssh_internals->_channel = libssh2_channel_open_session(_ssh_internals->_session)))
      throw cql_ccm_bridge_exception_t("cannot open ssh session");

    try {

      if (libssh2_channel_request_pty(_ssh_internals->_channel, "vanilla"))
        throw cql_ccm_bridge_exception_t("pty requests failed");

      if (libssh2_channel_shell(_ssh_internals->_channel))
        throw cql_ccm_bridge_exception_t("cannot open shell");

      //TODO: Copy SSL files to remote connection for CCM to enable SSL with Cassandra instances (or use keytool to simply generate the files remotely)
    } catch (cql_ccm_bridge_exception_t&) {
      // calls channel_close
      libssh2_channel_free(_ssh_internals->_channel);
    }
  } catch (cql_ccm_bridge_exception_t&) {
    close_ssh_session();
    throw;
  }
}
Beispiel #4
0
int main(int argc, char *argv[])
{
    unsigned long hostaddr;
    int rc, sock, i, auth_pw = 0;
    struct sockaddr_in sin;
    const char *fingerprint;
    char *userauthlist;
    LIBSSH2_SESSION *session;
    LIBSSH2_CHANNEL *channel;

#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) {
        hostaddr = inet_addr(argv[1]);
    } else {
        hostaddr = htonl(0x7F000001);
    }

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

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

    /* 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 and start it up. This will trade welcome
     * banners, exchange keys, and setup crypto, compression, and MAC layers
     */
    session = libssh2_session_init();
    if (libssh2_session_handshake(session, sock)) {
        fprintf(stderr, "Failure establishing SSH session\n");
        return -1;
    }

    /* At this point we havn't authenticated. The first thing to do is check
     * the hostkey's fingerprint against our known hosts Your app may have it
     * hard coded, may go to a file, may present it to the user, that's your
     * call
     */
    fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
    fprintf(stderr, "Fingerprint: ");
    for(i = 0; i < 20; i++) {
        fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
    }
    fprintf(stderr, "\n");

    /* check what authentication methods are available */
    userauthlist = libssh2_userauth_list(session, username, strlen(username));
    fprintf(stderr, "Authentication methods: %s\n", userauthlist);
    if (strstr(userauthlist, "password") != NULL) {
        auth_pw |= 1;
    }
    if (strstr(userauthlist, "keyboard-interactive") != NULL) {
        auth_pw |= 2;
    }
    if (strstr(userauthlist, "publickey") != NULL) {
        auth_pw |= 4;
    }

    /* if we got an 4. argument we set this option if supported */
    if(argc > 4) {
        if ((auth_pw & 1) && !strcasecmp(argv[4], "-p")) {
            auth_pw = 1;
        }
        if ((auth_pw & 2) && !strcasecmp(argv[4], "-i")) {
            auth_pw = 2;
        }
        if ((auth_pw & 4) && !strcasecmp(argv[4], "-k")) {
            auth_pw = 4;
        }
    }

    if (auth_pw & 1) {
        /* We could authenticate via password */
        if (libssh2_userauth_password(session, username, password)) {
            fprintf(stderr, "\tAuthentication by password failed!\n");
            goto shutdown;
        } else {
            fprintf(stderr, "\tAuthentication by password succeeded.\n");
        }
    } else if (auth_pw & 2) {
        /* Or via keyboard-interactive */
        if (libssh2_userauth_keyboard_interactive(session, username,
                                                  &kbd_callback) ) {
            fprintf(stderr,
                "\tAuthentication by keyboard-interactive failed!\n");
            goto shutdown;
        } else {
            fprintf(stderr,
                "\tAuthentication by keyboard-interactive succeeded.\n");
        }
    } else if (auth_pw & 4) {
        /* Or by public key */
        if (libssh2_userauth_publickey_fromfile(session, username, keyfile1,
                                                keyfile2, password)) {
            fprintf(stderr, "\tAuthentication by public key failed!\n");
            goto shutdown;
        } else {
            fprintf(stderr, "\tAuthentication by public key succeeded.\n");
        }
    } else {
        fprintf(stderr, "No supported authentication methods found!\n");
        goto shutdown;
    }

    /* Request a shell */
    if (!(channel = libssh2_channel_open_session(session))) {
        fprintf(stderr, "Unable to open a session\n");
        goto shutdown;
    }

    /* Some environment variables may be set,
     * It's up to the server which ones it'll allow though
     */
    libssh2_channel_setenv(channel, "FOO", "bar");

    /* 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");
        goto skip_shell;
    }

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

    /* At this point the shell can be interacted with using
     * libssh2_channel_read()
     * libssh2_channel_read_stderr()
     * libssh2_channel_write()
     * libssh2_channel_write_stderr()
     *
     * Blocking mode may be (en|dis)abled with: libssh2_channel_set_blocking()
     * If the server send EOF, libssh2_channel_eof() will return non-0
     * To send EOF to the server use: libssh2_channel_send_eof()
     * A channel can be closed with: libssh2_channel_close()
     * A channel can be freed with: libssh2_channel_free()
     */

  skip_shell:
    if (channel) {
        libssh2_channel_free(channel);
        channel = NULL;
    }

    /* Other channel types are supported via:
     * libssh2_scp_send()
     * libssh2_scp_recv()
     * libssh2_channel_direct_tcpip()
     */

  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;
}
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;
}
bool QxtSshChannelPrivate::activate(){
    //session
    if(d_state==1){
        d_channel=libssh2_channel_open_session(d_session);
        if(d_channel==NULL){
            if(libssh2_session_last_error(d_session,NULL,NULL,0)==LIBSSH2_ERROR_EAGAIN) {
                return true;
            }else{
                return false;
            }
        }
#ifdef QXT_DEBUG_SSH
        qDebug("session opened");
#endif
        d_state=2;
        return activate();

    //transition to allow early cmd
    }else if (d_state==2){
        if(!d_next_actions.isEmpty()){
            d_state=d_next_actions.takeFirst();
            return activate();
        }else{
            return true;
        }

    //request pty
    }else if (d_state==5){
        int r=libssh2_channel_request_pty(d_channel,d_pty.data());
        if(r){
            if(r==LIBSSH2_ERROR_EAGAIN){
                return true;
            }else{
                qWarning("QxtSshChannel: pty allocation failed");
                return false;
            }
        }
#ifdef QXT_DEBUG_SSH
        qDebug("pty opened");
#endif
        d_state=2;
        return activate();

    //start
    }else if (d_state==3){
        int r=libssh2_channel_exec(d_channel,qPrintable(d_cmd));
        if(r){
            if(r==LIBSSH2_ERROR_EAGAIN){
                return true;
            }else{
#ifdef QXT_DEBUG_SSH
                qDebug("exec failed");
#endif
                return false;
            }
        }
#ifdef QXT_DEBUG_SSH
        qDebug("exec opened");
#endif
        p->setOpenMode(QIODevice::ReadWrite);
        d_state=66;
        emit p->connected();
        return true;

    //start shell
    }else if (d_state==4){
        int r=libssh2_channel_shell(d_channel);
        if(r){
            if(r==LIBSSH2_ERROR_EAGAIN){
                return true;
            }else{
#ifdef QXT_DEBUG_SSH
                qDebug("exec failed");
#endif
                return false;
            }
        }
#ifdef QXT_DEBUG_SSH
        qDebug("shell opened");
#endif
        p->setOpenMode(QIODevice::ReadWrite);
        d_state=9999;
        emit p->connected();
        return true;

    // tcp channel
    }else if (d_state==10){
        d_channel=libssh2_channel_direct_tcpip(d_session, qPrintable(d_host),d_port);
        if(d_channel==NULL){
            if(libssh2_session_last_error(d_session,NULL,NULL,0)==LIBSSH2_ERROR_EAGAIN) {
                return true;
            }else{
                return false;
            }
        }
#ifdef QXT_DEBUG_SSH
        qDebug("tcp channel opened");
#endif
        p->setOpenMode(QIODevice::ReadWrite);
        d_state=9999;
        return activate();

    //read channel
    }else if (d_state==9999){
        emit p->readyRead();
    }
    return true;
}
Beispiel #7
0
int main(int argc, char *argv[])
{
    unsigned long hostaddr;
    int sock, i, auth_pw = 0;
    struct sockaddr_in sin;
    const char *fingerprint;
    char *userauthlist;
    LIBSSH2_SESSION *session;
    LIBSSH2_CHANNEL *channel;
#ifdef WIN32
    WSADATA wsadata;

    WSAStartup(MAKEWORD(2,0), &wsadata);
#endif
    const char *pubkeyfile="etc/user.pub";
    const char *privkeyfile="etc/user";
    const char *username="******";
    const char *password="******";
    int ec = 1;

    (void)argc;
    (void)argv;

    if (getenv ("USER"))
      username = getenv ("USER");

    if (getenv ("PRIVKEY"))
      privkeyfile = getenv ("PRIVKEY");

    if (getenv ("PRIVKEY"))
      pubkeyfile = getenv ("PUBKEY");

    hostaddr = htonl(0x7F000001);

    sock = socket(AF_INET, SOCK_STREAM, 0);
#ifndef WIN32
    fcntl(sock, F_SETFL, 0);
#endif
    sin.sin_family = AF_INET;
    sin.sin_port = htons(4711);
    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 and start it up
     * This will trade welcome banners, exchange keys, and setup crypto, compression, and MAC layers
     */
    session = libssh2_session_init();
    if (libssh2_session_startup(session, sock)) {
        fprintf(stderr, "Failure establishing SSH session\n");
        return -1;
    }

    /* At this point we havn't authenticated,
     * The first thing to do is check the hostkey's fingerprint against our known hosts
     * Your app may have it hard coded, may go to a file, may present it to the user, that's your call
     */
    fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
    printf("Fingerprint: ");
    for(i = 0; i < 16; i++) {
        printf("%02X ", (unsigned char)fingerprint[i]);
    }
    printf("\n");

    /* check what authentication methods are available */
    userauthlist = libssh2_userauth_list(session, username, strlen(username));
    printf("Authentication methods: %s\n", userauthlist);
    if (strstr(userauthlist, "password") != NULL) {
        auth_pw |= 1;
    }
    if (strstr(userauthlist, "keyboard-interactive") != NULL) {
        auth_pw |= 2;
    }
    if (strstr(userauthlist, "publickey") != NULL) {
        auth_pw |= 4;
    }

    if (auth_pw & 4) {
        /* Authenticate by public key */
        if (libssh2_userauth_publickey_fromfile(session, username, pubkeyfile, privkeyfile, password)) {
            printf("\tAuthentication by public key failed!\n");
            goto shutdown;
        } else {
            printf("\tAuthentication by public key succeeded.\n");
        }
    } else {
        printf("No supported authentication methods found!\n");
        goto shutdown;
    }

    /* Request a shell */
    if (!(channel = libssh2_channel_open_session(session))) {
        fprintf(stderr, "Unable to open a session\n");
        goto shutdown;
    }

    /* Some environment variables may be set,
     * It's up to the server which ones it'll allow though
     */
    libssh2_channel_setenv(channel, "FOO", "bar");

    /* 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");
        goto skip_shell;
    }

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

    ec = 0;

  skip_shell:
    if (channel) {
        libssh2_channel_free(channel);
        channel = NULL;
    }

  shutdown:

    libssh2_session_disconnect(session, "Normal Shutdown");
    libssh2_session_free(session);

#ifdef WIN32
    Sleep(1000);
    closesocket(sock);
#else
    sleep(1);
    close(sock);
#endif

    return ec;
}
Beispiel #8
0
int main(int argc, char *argv[])
{
    unsigned long hostaddr;
    int sock = -1, i, rc;
    struct sockaddr_in sin;
    const char *fingerprint;
    char *userauthlist;
    LIBSSH2_SESSION *session = NULL;
    LIBSSH2_CHANNEL *channel;
    LIBSSH2_AGENT *agent = NULL;
    struct libssh2_agent_publickey *identity, *prev_identity = NULL;
#ifdef WIN32
    WSADATA wsadata;

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

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

    if(argc > 2) {
        username = argv[2];
    }

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

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

    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");
        goto shutdown;
    }

    /* Create a session instance and start it up. This will trade welcome
     * banners, exchange keys, and setup crypto, compression, and MAC layers
     */
    session = libssh2_session_init();
    if (libssh2_session_handshake(session, sock)) {
        fprintf(stderr, "Failure establishing SSH session\n");
        return 1;
    }

    /* At this point we havn't authenticated. The first thing to do is check
     * the hostkey's fingerprint against our known hosts Your app may have it
     * hard coded, may go to a file, may present it to the user, that's your
     * call
     */
    fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
    fprintf(stderr, "Fingerprint: ");
    for(i = 0; i < 20; i++) {
        fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
    }
    fprintf(stderr, "\n");

    /* check what authentication methods are available */
    userauthlist = libssh2_userauth_list(session, username, strlen(username));
    fprintf(stderr, "Authentication methods: %s\n", userauthlist);
    if (strstr(userauthlist, "publickey") == NULL) {
        fprintf(stderr, "\"publickey\" authentication is not supported\n");
        goto shutdown;
    }

    /* Connect to the ssh-agent */
    agent = libssh2_agent_init(session);
    if (!agent) {
        fprintf(stderr, "Failure initializing ssh-agent support\n");
        rc = 1;
        goto shutdown;
    }
    if (libssh2_agent_connect(agent)) {
        fprintf(stderr, "Failure connecting to ssh-agent\n");
        rc = 1;
        goto shutdown;
    }
    if (libssh2_agent_list_identities(agent)) {
        fprintf(stderr, "Failure requesting identities to ssh-agent\n");
        rc = 1;
        goto shutdown;
    }
    while (1) {
        rc = libssh2_agent_get_identity(agent, &identity, prev_identity);
        if (rc == 1)
            break;
        if (rc < 0) {
            fprintf(stderr,
                    "Failure obtaining identity from ssh-agent support\n");
            rc = 1;
            goto shutdown;
        }
        if (libssh2_agent_userauth(agent, username, identity)) {
            fprintf(stderr, "\tAuthentication with username %s and "
                   "public key %s failed!\n",
                   username, identity->comment);
        } else {
            fprintf(stderr, "\tAuthentication with username %s and "
                   "public key %s succeeded!\n",
                   username, identity->comment);
            break;
        }
        prev_identity = identity;
    }
    if (rc) {
        fprintf(stderr, "Couldn't continue authentication\n");
        goto shutdown;
    }

    /* We're authenticated now. */

    /* Request a shell */
    if (!(channel = libssh2_channel_open_session(session))) {
        fprintf(stderr, "Unable to open a session\n");
        goto shutdown;
    }

    /* Some environment variables may be set,
     * It's up to the server which ones it'll allow though
     */
    libssh2_channel_setenv(channel, "FOO", "bar");

    /* 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");
        goto skip_shell;
    }

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

    /* At this point the shell can be interacted with using
     * libssh2_channel_read()
     * libssh2_channel_read_stderr()
     * libssh2_channel_write()
     * libssh2_channel_write_stderr()
     *
     * Blocking mode may be (en|dis)abled with: libssh2_channel_set_blocking()
     * If the server send EOF, libssh2_channel_eof() will return non-0
     * To send EOF to the server use: libssh2_channel_send_eof()
     * A channel can be closed with: libssh2_channel_close()
     * A channel can be freed with: libssh2_channel_free()
     */

  skip_shell:
    if (channel) {
        libssh2_channel_free(channel);
        channel = NULL;
    }

    /* Other channel types are supported via:
     * libssh2_scp_send()
     * libssh2_scp_recv()
     * libssh2_channel_direct_tcpip()
     */

  shutdown:

    libssh2_agent_disconnect(agent);
    libssh2_agent_free(agent);

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

    if (sock != -1) {
#ifdef WIN32
        closesocket(sock);
#else
        close(sock);
#endif
    }

    fprintf(stderr, "all done!\n");

    libssh2_exit();

    return rc;
}
Beispiel #9
0
bool ShellChannel::handleOpening()
{
	int rc;

	if (mInternalStatus == _OpenSession)
	{
		mHandle = libssh2_channel_open_session(mSession->sessionHandle());
		if (mHandle == NULL)
		{
			int rc = libssh2_session_last_errno(mSession->sessionHandle());
			if (rc == LIBSSH2_ERROR_EAGAIN)
				return true;
			else
			{
				if (rc == LIBSSH2_ERROR_CHANNEL_FAILURE)
					//	This channel needs to be given away; this connection can't handle it.
					//	TODO: Detect if this channel request has been handed off too often and kill it if so.
					setSession(NULL);
				else
					criticalError(tr("Failed to open a channel %1: %2").arg((unsigned long)mHandle, 0, 16).arg(rc));
				return false;
			}
		}
		setInternalStatus(_RequestPty);
	}

	if (mInternalStatus == _RequestPty)
	{
		//	Due to a bug in OpenSSH (popular server-side implementation of SSH), we must simulate blocking for PTY request.
                while ((rc = libssh2_channel_request_pty(mHandle, mPtyType)) == LIBSSH2_ERROR_EAGAIN) {};
		if (rc < 0)
		{
			criticalError(tr("Failed to request an appropriate pty %1: %2").arg((unsigned long)mHandle, 0, 16).arg(rc));
			return false;
		}

		setInternalStatus(_StartShell);
	}

	if (mInternalStatus == _StartShell)
	{
		if (mMachineReadable)
			rc = libssh2_channel_exec(mHandle, "sh");
		else
			rc = libssh2_channel_shell(mHandle);
		if (rc < 0)
		{
			if (rc == -1) rc = libssh2_session_last_errno(mSession->sessionHandle());
			if (rc == LIBSSH2_ERROR_EAGAIN)
				return true;
			criticalError(tr("Failed to open a shell %1: %2").arg((unsigned long)mHandle, 0, 16).arg(rc));
			return false;
		}

		if (mMachineReadable)
			setInternalStatus(_SendInit);
		else
			shellReady();
	}

	if (mInternalStatus == _SendInit)
	{
		SendResponse r = sendData(MACHINE_READABLE_INIT);
		if (r == SendAgain) return true;
		if (r != SendSucceed) criticalError("Failed to send shell initializer");

		setInternalStatus(_WaitForInitReply);
	}

	if (mInternalStatus == _WaitForInitReply)
	{
		ReadReply reply = readUntilPrompt();
		if (reply.readAgain) return true;
		if (reply.data.isNull()) return false;

		shellReady();
	}

	return true;
}