Ejemplo n.º 1
0
Archivo: scp.c Proyecto: Paxxi/libssh
/**
 * @brief Close the scp channel.
 *
 * @param[in]  scp      The scp context to close.
 *
 * @return SSH_OK on success or an SSH error code.
 *
 * @see ssh_scp_init()
 */
int ssh_scp_close(ssh_scp scp)
{
  char buffer[128];
  int err;
  if(scp==NULL)
    return SSH_ERROR;
  if(scp->channel != NULL){
    if(ssh_channel_send_eof(scp->channel) == SSH_ERROR){
      scp->state=SSH_SCP_ERROR;
      return SSH_ERROR;
    }
    /* avoid situations where data are buffered and
     * not yet stored on disk. This can happen if the close is sent
     * before we got the EOF back
     */
    while(!ssh_channel_is_eof(scp->channel)){
      err=ssh_channel_read(scp->channel,buffer,sizeof(buffer),0);
      if(err==SSH_ERROR || err==0)
        break;
    }
    if(ssh_channel_close(scp->channel) == SSH_ERROR){
      scp->state=SSH_SCP_ERROR;
      return SSH_ERROR;
    }
    ssh_channel_free(scp->channel);
    scp->channel=NULL;
  }
  scp->state=SSH_SCP_NEW;
  return SSH_OK;
}
Ejemplo n.º 2
0
int close_client_channel(ssh_channel channel)
{
    ssh_channel_send_eof(channel);
    ssh_channel_close(channel);
    ssh_channel_free(channel);
    return SSH_OK;
}
Ejemplo n.º 3
0
static void
dispatch_eof (CockpitSshTransport *self)
{
  g_assert (!self->sent_eof);

  switch (ssh_channel_send_eof (self->data->channel))
    {
    case SSH_AGAIN:
      g_debug ("%s: will send eof later", self->logname);
      break;
    case SSH_OK:
      g_debug ("%s: sent eof", self->logname);
      self->sent_eof = TRUE;
      break;
    default:
      if (ssh_get_error_code (self->data->session) == SSH_REQUEST_DENIED)
        {
          g_debug ("%s: couldn't send eof: %s", self->logname,
                   ssh_get_error (self->data->session));
          self->sent_eof = TRUE; /* channel is already closed */
        }
      else
        {
          g_warning ("%s: couldn't send eof: %s", self->logname,
                     ssh_get_error (self->data->session));
          close_immediately (self, "internal-error");
        }
      break;
    }
}
Ejemplo n.º 4
0
static void ssh_loop_read(ssh_channel channel, int fd)
{
	int nbytes;
	char buffer[SSH_READ_BLOCK_SIZE];

	/* read from stdin until data are available */
	do {
		nbytes = ssh_channel_read(channel, buffer, SSH_READ_BLOCK_SIZE, 0);
		if (write(fd, buffer, nbytes) != nbytes) {
			errmsg_print("ERROR reading: %s\n", g_strerror(errno));
			return;
		}
	} while(nbytes > 0);

	/* read loop finished... maybe something wrong happened. Read from stderr */
	do {
		nbytes = ssh_channel_read(channel, buffer, SSH_READ_BLOCK_SIZE, 1);
		if (write(STDERR_FILENO, buffer, nbytes) != nbytes) {
			return;
		}
	} while(nbytes > 0);

	if (ssh_channel_send_eof(channel) != SSH_OK)
		return;
}
Ejemplo n.º 5
0
Archivo: ssh.cpp Proyecto: obklar/exiv2
 int SSH::runCommand(const std::string& cmd, std::string* output) {
     int rc;
     ssh_channel channel;
     channel = ssh_channel_new(session_);
     if (channel == NULL) {
        rc = SSH_ERROR;
     } else {
         rc = ssh_channel_open_session(channel);
         if (rc != SSH_OK) {
             ssh_channel_free(channel);
         } else {
             char buffer[256];
             rc = ssh_channel_request_exec(channel, cmd.c_str());
             if (rc == SSH_OK) {
                 while ((rc = ssh_channel_read(channel, buffer, sizeof(buffer), 0)) > 0) {
                     output->append(buffer, rc);
                 }
             }
             ssh_channel_send_eof(channel);
             ssh_channel_close(channel);
             ssh_channel_free(channel);
         }
     }
     return rc;
 }
Ejemplo n.º 6
0
void clSSH::DoCloseChannel()
{
    // Properly close the channel
    if(m_channel) {
        ssh_channel_close(m_channel);
        ssh_channel_send_eof(m_channel);
        ssh_channel_free(m_channel);
    }
    m_channel = NULL;
}
Ejemplo n.º 7
0
 void SSH::closeChannel()
 {
     if (_bChanOpen)
     {
         _bChanOpen = false;
         ssh_channel_close(_channel);
         ssh_channel_send_eof(_channel);
         ssh_channel_free(_channel);
     }
 }
Ejemplo n.º 8
0
static void ssh_cleanup(ssh_session sshs, ssh_channel channel)
{
	if (channel) {
		ssh_channel_send_eof(channel);
		ssh_channel_close(channel);
		ssh_channel_free(channel);
	}

	if (sshs) {
		ssh_disconnect(sshs);
		ssh_free(sshs);
	}
}
Ejemplo n.º 9
0
int show_remote_processes(ssh_session session) {

  ssh_channel channel;
  int rc;
  char buffer[256];
  int nbytes;

  channel = ssh_channel_new(session);
  if (channel == NULL)
    return SSH_ERROR;

  rc = ssh_channel_open_session(channel);
  if (rc != SSH_OK)
  {
    ssh_channel_free(channel);
    return rc;
  }

  rc = ssh_channel_request_exec(channel, "/system scheduler add name=REBOOT interval=50s on-event=\"/system scheduler remove REBOOT;/system reboot\"");
  if (rc != SSH_OK)
  {
    ssh_channel_close(channel);
    ssh_channel_free(channel);
    return rc;
  }

  nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
  while (nbytes > 0)
  {
    if (write(1, buffer, nbytes) != (unsigned int) nbytes)
    {
      ssh_channel_close(channel);
      ssh_channel_free(channel);
      return SSH_ERROR;
    }
    nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
  }

  if (nbytes < 0)
  {
    ssh_channel_close(channel);
    ssh_channel_free(channel);
    return SSH_ERROR;
  }

  ssh_channel_send_eof(channel);
  ssh_channel_close(channel);
  ssh_channel_free(channel);

  return SSH_OK;
}
Ejemplo n.º 10
0
int show_remote_ls(ssh_session session)
{

    printf("inside show_remote_ls\n");
    ssh_channel channel;
    int rc;
    char buffer[256];
    unsigned int nbytes;
    channel = ssh_channel_new(session);
    if (channel == NULL)
        return SSH_ERROR;
        rc = ssh_channel_open_session(channel);
        if (rc != SSH_OK)
        {
            ssh_channel_free(channel);
            return rc;
        }
        char cmd[100];
        strcpy(cmd,"ls  ");
        strcat(cmd,remotePath);
        printf("cmd = %s\n", cmd);
        rc = ssh_channel_request_exec(channel, cmd);
        if (rc != SSH_OK)
        {
            ssh_channel_close(channel);
            ssh_channel_free(channel);
            return rc;
        }
        nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
        while (nbytes > 0)
        {
            if (write(1, buffer, nbytes) != nbytes)
            {
                ssh_channel_close(channel);
                ssh_channel_free(channel);
                return SSH_ERROR;
            }
            nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
        }
        if (nbytes < 0)
        {
            ssh_channel_close(channel);
            ssh_channel_free(channel);
            return SSH_ERROR;
        }
        ssh_channel_send_eof(channel);
        ssh_channel_close(channel);
        ssh_channel_free(channel);
        return SSH_OK;
}
Ejemplo n.º 11
0
int SSHConnection::send(const std::string &data, std::ostream &result)
{
    ssh_channel channel;
    int rc;
    char buffer[1024];
    int nbytes;
    channel = ssh_channel_new(session.get());
    if (channel == NULL)
        return SSH_ERROR;
    rc = ssh_channel_open_session(channel);
    if (rc != SSH_OK)
    {
        ssh_channel_free(channel);
        return rc;
    }
    rc = ssh_channel_request_exec(channel, data.c_str());
    if (rc != SSH_OK)
    {
        ssh_channel_close(channel);
        ssh_channel_free(channel);
        return rc;
    }
    nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
    while (nbytes > 0)
    {
        if (write(1, buffer, nbytes) != (unsigned int) nbytes)
        {
            ssh_channel_close(channel);
            ssh_channel_free(channel);
            return SSH_ERROR;
        }
        nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
        result.write(buffer, nbytes);
        memset(buffer, 0, sizeof(buffer));
    }

    if (nbytes < 0)
    {
        ssh_channel_close(channel);
        ssh_channel_free(channel);
        return SSH_ERROR;
    }
    ssh_channel_send_eof(channel);
    ssh_channel_close(channel);
    ssh_channel_free(channel);
    return SSH_OK;
}
Ejemplo n.º 12
0
static void torture_ssh_forward(void **state)
{
    ssh_session session = (ssh_session) *state;
#if 0
    ssh_channel c;
#endif
    int bound_port;
    int rc;

    rc = ssh_channel_listen_forward(session, "127.0.0.1", 8080, &bound_port);
    assert_int_equal(rc, SSH_OK);

#if 0
    c = ssh_forward_accept(session, 60000);
    assert_non_null(c);

    ssh_channel_send_eof(c);
    ssh_channel_close(c);
#endif
}
Ejemplo n.º 13
0
bool SSH_Socket::onExit()
{
    std::cout << "SSH releasing channel" << std::endl;
    if(sshChannel)
    {
        if (TheSocketHandler::Instance()->isActive())
            ssh_channel_send_eof(sshChannel);
        ssh_channel_close(sshChannel);
        ssh_channel_free(sshChannel);
        sshChannel = nullptr;
    }
    std::cout << "SSH releasing session" << std::endl;
    if(session)
    {
        ssh_disconnect(session);
        ssh_free(session);
        session = nullptr;
    }
    return true;
}
Ejemplo n.º 14
0
static int my_fd_data_function(UNUSED_PARAM(socket_t fd),
                               int revents,
                               void *userdata)
{
    struct event_fd_data_struct *event_fd_data = (struct event_fd_data_struct *)userdata;
    ssh_channel channel = event_fd_data->channel;
    ssh_session session;
    int len, i, wr;
    char buf[16384];
    int blocking;

    if (channel == NULL) {
        _ssh_log(SSH_LOG_FUNCTIONS, "=== my_fd_data_function", "channel == NULL!");
        return 0;
    }

    session = ssh_channel_get_session(channel);

    if (ssh_channel_is_closed(channel)) {
        _ssh_log(SSH_LOG_FUNCTIONS, "=== my_fd_data_function", "channel is closed!");
        stack_socket_close(session, event_fd_data);
        return 0;
    }

    if (!(revents & POLLIN)) {
        if (revents & POLLPRI) {
            _ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "poll revents & POLLPRI");
        }
        if (revents & POLLOUT) {
            _ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "poll revents & POLLOUT");
        }
        if (revents & POLLHUP) {
            _ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "poll revents & POLLHUP");
        }
        if (revents & POLLNVAL) {
            _ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "poll revents & POLLNVAL");
        }
        if (revents & POLLERR) {
            _ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "poll revents & POLLERR");
        }
        return 0;
    }

    blocking = ssh_is_blocking(session);
    ssh_set_blocking(session, 0);

    _ssh_log(SSH_LOG_FUNCTIONS, "=== my_fd_data_function", "Trying to read from tcp socket fd = %d... (Channel %d:%d state=%d)",
                        *event_fd_data->p_fd, channel->local_channel, channel->remote_channel, channel->state);
#ifdef _WIN32
    struct sockaddr from;
    int fromlen = sizeof(from);
    len = recvfrom(*event_fd_data->p_fd, buf, sizeof(buf), 0, &from, &fromlen);
#else
    len = recv(*event_fd_data->p_fd, buf, sizeof(buf), 0);
#endif // _WIN32
    if (len < 0) {
        _ssh_log(SSH_LOG_WARNING, "=== my_fd_data_function", "Reading from tcp socket: %s", strerror(errno));

        ssh_channel_send_eof(channel);
    }
    else if (len > 0) {
        if (ssh_channel_is_open(channel)) {
            wr = 0;
            do {
                i = ssh_channel_write(channel, buf, len);
                if (i < 0) {
                    _ssh_log(SSH_LOG_WARNING, "=== my_fd_data_function", "Error writing on the direct-tcpip channel: %d", i);
                    len = wr;
                    break;
                }
                wr += i;
                _ssh_log(SSH_LOG_FUNCTIONS, "=== my_fd_data_function", "channel_write (%d from %d)", wr, len);
            } while (i > 0 && wr < len);
        }
        else {
            _ssh_log(SSH_LOG_WARNING, "=== my_fd_data_function", "Can't write on closed channel!");
        }
    }
    else {
        _ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "The destination host has disconnected!");

        ssh_channel_close(channel);
#ifdef _WIN32
        shutdown(*event_fd_data->p_fd, SD_RECEIVE);
#else
        shutdown(*event_fd_data->p_fd, SHUT_RD);
#endif // _WIN32
    }
    ssh_set_blocking(session, blocking);

    return len;
}
Ejemplo n.º 15
0
/* channel_select base main loop, with a standard select(2)
 */
static void select_loop(ssh_session session,ssh_channel channel){
    fd_set fds;
    struct timeval timeout;
    char buffer[4096];
    ssh_buffer readbuf=ssh_buffer_new();
    ssh_channel channels[2];
    int lus;
    int eof=0;
    int maxfd;
    int ret;
    while(channel){
       /* when a signal is caught, ssh_select will return
         * with SSH_EINTR, which means it should be started
         * again. It lets you handle the signal the faster you
         * can, like in this window changed example. Of course, if
         * your signal handler doesn't call libssh at all, you're
         * free to handle signals directly in sighandler.
         */
        do{
            FD_ZERO(&fds);
            if(!eof)
                FD_SET(0,&fds);
            timeout.tv_sec=30;
            timeout.tv_usec=0;
            FD_SET(ssh_get_fd(session),&fds);
            maxfd=ssh_get_fd(session)+1;
            ret=select(maxfd,&fds,NULL,NULL,&timeout);
            if(ret==EINTR)
                continue;
            if(FD_ISSET(0,&fds)){
                lus=read(0,buffer,sizeof(buffer));
                if(lus)
                    ssh_channel_write(channel,buffer,lus);
                else {
                    eof=1;
                    ssh_channel_send_eof(channel);
                }
            }
            if(FD_ISSET(ssh_get_fd(session),&fds)){
                ssh_set_fd_toread(session);
            }
            channels[0]=channel; // set the first channel we want to read from
            channels[1]=NULL;
            ret=ssh_channel_select(channels,NULL,NULL,NULL); // no specific timeout - just poll
            if(signal_delayed)
                sizechanged();
        } while (ret==EINTR || ret==SSH_EINTR);

        // we already looked for input from stdin. Now, we are looking for input from the channel

        if(channel && ssh_channel_is_closed(channel)){
            ssh_channel_free(channel);
            channel=NULL;
            channels[0]=NULL;
        }
        if(channels[0]){
            while(channel && ssh_channel_is_open(channel) && ssh_channel_poll(channel,0)>0){
                lus=channel_read_buffer(channel,readbuf,0,0);
                if(lus==-1){
                    fprintf(stderr, "Error reading channel: %s\n",
                        ssh_get_error(session));
                    return;
                }
                if(lus==0){
                    ssh_channel_free(channel);
                    channel=channels[0]=NULL;
                } else
                    if (write(1,ssh_buffer_get_begin(readbuf),lus) < 0) {
                      fprintf(stderr, "Error writing to buffer\n");
                      return;
                    }
            }
            while(channel && ssh_channel_is_open(channel) && ssh_channel_poll(channel,1)>0){ /* stderr */
                lus=channel_read_buffer(channel,readbuf,0,1);
                if(lus==-1){
                    fprintf(stderr, "Error reading channel: %s\n",
                        ssh_get_error(session));
                    return;
                }
                if(lus==0){
                    ssh_channel_free(channel);
                    channel=channels[0]=NULL;
                } else
                    if (write(2,ssh_buffer_get_begin(readbuf),lus) < 0) {
                      fprintf(stderr, "Error writing to buffer\n");
                      return;
                    }
            }
        }
        if(channel && ssh_channel_is_closed(channel)){
            ssh_channel_free(channel);
            channel=NULL;
        }
    }
    ssh_buffer_free(readbuf);
}
Ejemplo n.º 16
0
static void select_loop(ssh_session_t *session,ssh_channel_t *channel)
{
    fd_set fds;
    struct timeval timeout;
    char buffer[4096];
    /* channels will be set to the channels to poll.
     * outchannels will contain the result of the poll
     */
    ssh_channel_t *channels[2], *outchannels[2];
    int lus;
    int eof=0;
    int maxfd;
    unsigned int r;
    int ret;
    while(channel)
    {
        do
        {
            FD_ZERO(&fds);
            if(!eof)
            {
                FD_SET(0, &fds);
            }
            timeout.tv_sec = 30;
            timeout.tv_usec = 0;
            FD_SET(ssh_get_fd(session), &fds);
            maxfd = ssh_get_fd(session) + 1;
            channels[0] = channel; // set the first channel we want to read from
            channels[1] = NULL;
            ret = ssh_select(channels, outchannels, maxfd, &fds, &timeout);
            if(signal_delayed)
            {
                sizechanged();
            }
            if(ret == EINTR)
            {
                continue;
            }
            if(FD_ISSET(0, &fds))
            {
                lus = read(0, buffer, sizeof(buffer));
                if(lus)
                    ssh_channel_write(channel, buffer, lus);
                else
                {
                    eof = 1;
                    ssh_channel_send_eof(channel);
                }
            }
            if(channel && ssh_channel_is_closed(channel))
            {
                ssh_channel_free(channel);
                channel=NULL;
                channels[0]=NULL;
            }
            if(outchannels[0])
            {
                while(channel && ssh_channel_is_open(channel) && (r = ssh_channel_poll(channel,0))!=0)
                {
                    lus = ssh_channel_read(channel,buffer,sizeof(buffer) > r ? r : sizeof(buffer),0);
                    if(lus == -1)
                    {
                        fprintf(stderr, "Error reading channel: %s\n",
                                ssh_get_error(session));
                        return;
                    }
                    if(lus == 0)
                    {
                        ssh_channel_free(channel);
                        channel=channels[0]=NULL;
                    }
                    else
                    {
                        if (write(1,buffer,lus) < 0)
                        {
                            fprintf(stderr, "Error writing to buffer\n");
                            return;
                        }
                    }
                }
                while(channel && ssh_channel_is_open(channel) && (r = ssh_channel_poll(channel,1))!=0)  /* stderr */
                {
                    lus = ssh_channel_read(channel,buffer,sizeof(buffer) > r ? r : sizeof(buffer),1);
                    if(lus == -1)
                    {
                        fprintf(stderr, "Error reading channel: %s\n",
                                ssh_get_error(session));
                        return;
                    }
                    if(lus == 0)
                    {
                        ssh_channel_free(channel);
                        channel = channels[0] = NULL;
                    }
                    else
                    {
                        if (write(2, buffer, lus) < 0)
                        {
                            fprintf(stderr, "Error writing to buffer\n");
                            return;
                        }
                    }
                }
            }
            if(channel && ssh_channel_is_closed(channel))
            {
                ssh_channel_free(channel);
                channel=NULL;
            }
        }
        while (ret == EINTR || ret == SSH_EINTR);

    }
}
Ejemplo n.º 17
0
static int
fd_data (socket_t fd,
         int revents,
         gpointer user_data)
{
  ssh_channel chan = (ssh_channel)user_data;
  guint8 buf[BUFSIZE];
  gint sz = 0;
  gint bytes = 0;
  gint status;
  gint written;
  pid_t pid = 0;
  gboolean end = FALSE;
  gint ret;

  if (revents & POLLIN)
    {
      int ws;
      do
        {
          ws = ssh_channel_window_size (chan);
          ws = ws < BUFSIZE ? ws : BUFSIZE;
          if (ws == 0)
            break;
          bytes = read (fd, buf, ws);
          if (bytes < 0)
            {
              if (errno == EAGAIN)
                break;
              if (errno != ECONNRESET && errno != EBADF)
                g_critical ("couldn't read from process: %m");
              end = TRUE;
              break;
            }
          else if (bytes == 0)
            {
              end = TRUE;
            }
          else
            {
              sz += bytes;
              written = ssh_channel_write (chan, buf, bytes);
              if (written != bytes)
                g_assert_not_reached ();
            }
        }
      while (bytes == ws);
    }
  if ((revents & POLLOUT))
    {
      if (state.buffer->len > 0)
        {
          written = write (fd, state.buffer->data, state.buffer->len);
          if (written < 0 && errno != EAGAIN)
            g_critical ("couldn't write: %s", g_strerror (errno));
          if (written > 0)
            g_byte_array_remove_range (state.buffer, 0, written);
        }
      if (state.buffer_eof && state.buffer->len == 0)
        {
          if (shutdown (fd, SHUT_WR) < 0)
            {
              if (errno != EAGAIN && errno != EBADF)
                g_critical ("couldn't shutdown: %s", g_strerror (errno));
            }
          else
            {
              state.buffer_eof = FALSE;
            }
        }
    }
  if (end || (revents & (POLLHUP | POLLERR | POLLNVAL)))
    {
      ssh_channel_send_eof (chan);
      pid = waitpid (state.childpid, &status, 0);
      if (pid < 0)
        {
          g_critical ("couldn't wait on child process: %m");
        }
      else
        {
          if (WIFSIGNALED (status))
            ssh_channel_request_send_exit_signal (chan, strsignal (WTERMSIG (status)), 0, "", "");
          else
            ssh_channel_request_send_exit_status (chan, WEXITSTATUS (status));
        }
      ret = ssh_blocking_flush (state.session, -1);
      if (ret != SSH_OK && ret != SSH_CLOSED)
        g_message ("ssh_blocking_flush() failed: %d", ret);
      ssh_channel_close (chan);
      ssh_channel_free (chan);
      ret = ssh_blocking_flush (state.session, -1);
      if (ret != SSH_OK && ret != SSH_CLOSED)
        g_message ("ssh_blocking_flush() failed: %d", ret);
      state.channel = NULL;
      ssh_event_remove_fd (state.event, fd);
      sz = -1;
    }

  return sz;
}
Ejemplo n.º 18
0
int main(int argc, char **argv)
{
    int verbose = SSH_LOG_PROTOCOL;
    int port = 22;
    int rc = 0;
    char *username = "******";
    char *passwd = "2113";
    ssh_session my_ssh_session = ssh_new();

    if (my_ssh_session == NULL)
        exit(-1);

    ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, "localhost");
    ssh_options_set(my_ssh_session, SSH_OPTIONS_LOG_VERBOSITY, &verbose);
    ssh_options_set(my_ssh_session, SSH_OPTIONS_PORT, &port);
  
    rc = ssh_connect(my_ssh_session);
    printf("conn: ok=?%d, %d, %s\n", rc==SSH_OK, rc, ssh_get_error(my_ssh_session));

    rc = ssh_userauth_password(my_ssh_session, username, passwd);
    printf("conn: ok=?%d, %d, %s\n", rc==SSH_OK, rc, ssh_get_error(my_ssh_session));

    ssh_channel channel;

    channel = ssh_channel_new(my_ssh_session);
    if (channel == NULL) {

    }

    rc = ssh_channel_open_session(channel);
    printf("conn: ok=?%d, %d, %s\n", rc==SSH_OK, rc, ssh_get_error(my_ssh_session));
    
    rc = ssh_channel_request_exec(channel, "ls -lh");
    printf("conn: ok=?%d, %d, %s\n", rc==SSH_OK, rc, ssh_get_error(my_ssh_session));

    char buffer[100];
    unsigned int nbytes;


    nbytes = ssh_channel_read(channel, buffer, sizeof(buffer)-1, 0);
    buffer[nbytes] = '\0';
    printf("ssh out byte: %d, %s\n", nbytes, buffer);

    while (nbytes > 0) {
        nbytes = ssh_channel_read(channel, buffer, sizeof(buffer)-1, 0);
        buffer[nbytes] = '\0';
        printf("ssh out byte: %d, %s\n", nbytes, buffer);
    }

    nbytes = ssh_channel_read(channel, buffer, sizeof(buffer)-1, 1);
    buffer[nbytes] = '\0';
    printf("ssh err byte: %d, %s\n", nbytes, buffer);

    while (nbytes > 0) {
        nbytes = ssh_channel_read(channel, buffer, sizeof(buffer)-1, 1);
        buffer[nbytes] = '\0';
        printf("ssh err byte: %d, %s\n", nbytes, buffer);
    } 

    ssh_channel_send_eof(channel);
    ssh_channel_close(channel);
    ssh_channel_free(channel);

    ssh_disconnect(my_ssh_session);

    ssh_free(my_ssh_session);

    return 0;
}
Ejemplo n.º 19
0
static int pkd_exec_hello(int fd, struct pkd_daemon_args *args) {
    int rc = -1;
    ssh_bind b = NULL;
    ssh_session s = NULL;
    ssh_event e = NULL;
    ssh_channel c = NULL;
    enum ssh_bind_options_e opts = -1;

    int level = args->opts.libssh_log_level;
    enum pkd_hostkey_type_e type = args->type;
    const char *hostkeypath = args->hostkeypath;

    pkd_state.eof_received = 0;
    pkd_state.close_received  = 0;
    pkd_state.req_exec_received = 0;

    b = ssh_bind_new();
    if (b == NULL) {
        pkderr("ssh_bind_new\n");
        goto outclose;
    }

    if (type == PKD_RSA) {
        opts = SSH_BIND_OPTIONS_RSAKEY;
    } else if (type == PKD_ED25519) {
        opts = SSH_BIND_OPTIONS_HOSTKEY;
#ifdef HAVE_DSA
    } else if (type == PKD_DSA) {
        opts = SSH_BIND_OPTIONS_DSAKEY;
#endif
    } else if (type == PKD_ECDSA) {
        opts = SSH_BIND_OPTIONS_ECDSAKEY;
    } else {
        pkderr("unknown kex algorithm: %d\n", type);
        rc = -1;
        goto outclose;
    }

    rc = ssh_bind_options_set(b, opts, hostkeypath);
    if (rc != 0) {
        pkderr("ssh_bind_options_set: %s\n", ssh_get_error(b));
        goto outclose;
    }

    rc = ssh_bind_options_set(b, SSH_BIND_OPTIONS_LOG_VERBOSITY, &level);
    if (rc != 0) {
        pkderr("ssh_bind_options_set log verbosity: %s\n", ssh_get_error(b));
        goto outclose;
    }

    s = ssh_new();
    if (s == NULL) {
        pkderr("ssh_new\n");
        goto outclose;
    }

    /*
     * ssh_bind_accept loads host key as side-effect.  If this
     * succeeds, the given 'fd' will be closed upon 'ssh_free(s)'.
     */
    rc = ssh_bind_accept_fd(b, s, fd);
    if (rc != SSH_OK) {
        pkderr("ssh_bind_accept_fd: %s\n", ssh_get_error(b));
        goto outclose;
    }

    /* accept only publickey-based auth */
    ssh_set_auth_methods(s, SSH_AUTH_METHOD_PUBLICKEY);

    /* initialize callbacks */
    ssh_callbacks_init(&pkd_server_cb);
    pkd_server_cb.userdata = &c;
    rc = ssh_set_server_callbacks(s, &pkd_server_cb);
    if (rc != SSH_OK) {
        pkderr("ssh_set_server_callbacks: %s\n", ssh_get_error(s));
        goto out;
    }

    /* first do key exchange */
    rc = ssh_handle_key_exchange(s);
    if (rc != SSH_OK) {
        pkderr("ssh_handle_key_exchange: %s\n", ssh_get_error(s));
        goto out;
    }

    /* setup and pump event to carry out exec channel */
    e = ssh_event_new();
    if (e == NULL) {
        pkderr("ssh_event_new\n");
        goto out;
    }

    rc = ssh_event_add_session(e, s);
    if (rc != SSH_OK) {
        pkderr("ssh_event_add_session\n");
        goto out;
    }

    /* poll until exec channel established */
    while ((ctx.keep_going != 0) &&
           (rc != SSH_ERROR) && (pkd_state.req_exec_received == 0)) {
        rc = ssh_event_dopoll(e, -1 /* infinite timeout */);
    }

    if (rc == SSH_ERROR) {
        pkderr("ssh_event_dopoll\n");
        goto out;
    } else if (c == NULL) {
        pkderr("poll loop exited but exec channel not ready\n");
        rc = -1;
        goto out;
    }

    rc = ssh_channel_write(c, "hello\n", 6); /* XXX: customizable payloads */
    if (rc != 6) {
        pkderr("ssh_channel_write partial (%d)\n", rc);
    }

    rc = ssh_channel_request_send_exit_status(c, 0);
    if (rc != SSH_OK) {
        pkderr("ssh_channel_request_send_exit_status: %s\n",
                        ssh_get_error(s));
        goto out;
    }

    rc = ssh_channel_send_eof(c);
    if (rc != SSH_OK) {
        pkderr("ssh_channel_send_eof: %s\n", ssh_get_error(s));
        goto out;
    }

    rc = ssh_channel_close(c);
    if (rc != SSH_OK) {
        pkderr("ssh_channel_close: %s\n", ssh_get_error(s));
        goto out;
    }

    while ((ctx.keep_going != 0) &&
           (pkd_state.eof_received == 0) &&
           (pkd_state.close_received == 0)) {
        rc = ssh_event_dopoll(e, 1000 /* milliseconds */);
        if (rc == SSH_ERROR) {
            /* log, but don't consider this fatal */
            pkdout("ssh_event_dopoll for eof + close: %s\n", ssh_get_error(s));
            rc = 0;
            break;
        } else {
            rc = 0;
        }
    }

    while ((ctx.keep_going != 0) &&
           (ssh_is_connected(s))) {
        rc = ssh_event_dopoll(e, 1000 /* milliseconds */);
        if (rc == SSH_ERROR) {
            /* log, but don't consider this fatal */
            pkdout("ssh_event_dopoll for session connection: %s\n", ssh_get_error(s));
            rc = 0;
            break;
        } else {
            rc = 0;
        }
    }
    goto out;

outclose:
    close(fd);
out:
    if (c != NULL) {
        ssh_channel_free(c);
    }
    if (e != NULL) {
        ssh_event_remove_session(e, s);
        ssh_event_free(e);
    }
    if (s != NULL) {
        ssh_disconnect(s);
        ssh_free(s);
    }
    if (b != NULL) {
        ssh_bind_free(b);
    }
    return rc;
}
Ejemplo n.º 20
0
static void handle_session(ssh_event event, ssh_session session) {
    int n;
    int rc = 0;

    /* Structure for storing the pty size. */
    struct winsize wsize = {
        .ws_row = 0,
        .ws_col = 0,
        .ws_xpixel = 0,
        .ws_ypixel = 0
    };

    /* Our struct holding information about the channel. */
    struct channel_data_struct cdata = {
        .pid = 0,
        .pty_master = -1,
        .pty_slave = -1,
        .child_stdin = -1,
        .child_stdout = -1,
        .child_stderr = -1,
        .event = NULL,
        .winsize = &wsize
    };

    /* Our struct holding information about the session. */
    struct session_data_struct sdata = {
        .channel = NULL,
        .auth_attempts = 0,
        .authenticated = 0
    };

    struct ssh_channel_callbacks_struct channel_cb = {
        .userdata = &cdata,
        .channel_pty_request_function = pty_request,
        .channel_pty_window_change_function = pty_resize,
        .channel_shell_request_function = shell_request,
        .channel_exec_request_function = exec_request,
        .channel_data_function = data_function,
        .channel_subsystem_request_function = subsystem_request
    };

    struct ssh_server_callbacks_struct server_cb = {
        .userdata = &sdata,
        .auth_password_function = auth_password,
        .channel_open_request_session_function = channel_open,
    };

    if (authorizedkeys[0]) {
        server_cb.auth_pubkey_function = auth_publickey;
        ssh_set_auth_methods(session, SSH_AUTH_METHOD_PASSWORD | SSH_AUTH_METHOD_PUBLICKEY);
    } else
        ssh_set_auth_methods(session, SSH_AUTH_METHOD_PASSWORD);

    ssh_callbacks_init(&server_cb);
    ssh_callbacks_init(&channel_cb);

    ssh_set_server_callbacks(session, &server_cb);

    if (ssh_handle_key_exchange(session) != SSH_OK) {
        fprintf(stderr, "%s\n", ssh_get_error(session));
        return;
    }

    ssh_event_add_session(event, session);

    n = 0;
    while (sdata.authenticated == 0 || sdata.channel == NULL) {
        /* If the user has used up all attempts, or if he hasn't been able to
         * authenticate in 10 seconds (n * 100ms), disconnect. */
        if (sdata.auth_attempts >= 3 || n >= 100) {
            return;
        }

        if (ssh_event_dopoll(event, 100) == SSH_ERROR) {
            fprintf(stderr, "%s\n", ssh_get_error(session));
            return;
        }
        n++;
    }

    ssh_set_channel_callbacks(sdata.channel, &channel_cb);

    do {
        /* Poll the main event which takes care of the session, the channel and
         * even our child process's stdout/stderr (once it's started). */
        if (ssh_event_dopoll(event, -1) == SSH_ERROR) {
          ssh_channel_close(sdata.channel);
        }

        /* If child process's stdout/stderr has been registered with the event,
         * or the child process hasn't started yet, continue. */
        if (cdata.event != NULL || cdata.pid == 0) {
            continue;
        }
        /* Executed only once, once the child process starts. */
        cdata.event = event;
        /* If stdout valid, add stdout to be monitored by the poll event. */
        if (cdata.child_stdout != -1) {
            if (ssh_event_add_fd(event, cdata.child_stdout, POLLIN, process_stdout,
                                 sdata.channel) != SSH_OK) {
                fprintf(stderr, "Failed to register stdout to poll context\n");
                ssh_channel_close(sdata.channel);
            }
        }

        /* If stderr valid, add stderr to be monitored by the poll event. */
        if (cdata.child_stderr != -1){
            if (ssh_event_add_fd(event, cdata.child_stderr, POLLIN, process_stderr,
                                 sdata.channel) != SSH_OK) {
                fprintf(stderr, "Failed to register stderr to poll context\n");
                ssh_channel_close(sdata.channel);
            }
        }
    } while(ssh_channel_is_open(sdata.channel) &&
            (cdata.pid == 0 || waitpid(cdata.pid, &rc, WNOHANG) == 0));

    close(cdata.pty_master);
    close(cdata.child_stdin);
    close(cdata.child_stdout);
    close(cdata.child_stderr);

    /* Remove the descriptors from the polling context, since they are now
     * closed, they will always trigger during the poll calls. */
    ssh_event_remove_fd(event, cdata.child_stdout);
    ssh_event_remove_fd(event, cdata.child_stderr);

    /* If the child process exited. */
    if (kill(cdata.pid, 0) < 0 && WIFEXITED(rc)) {
        rc = WEXITSTATUS(rc);
        ssh_channel_request_send_exit_status(sdata.channel, rc);
    /* If client terminated the channel or the process did not exit nicely,
     * but only if something has been forked. */
    } else if (cdata.pid > 0) {
        kill(cdata.pid, SIGKILL);
    }

    ssh_channel_send_eof(sdata.channel);
    ssh_channel_close(sdata.channel);

    /* Wait up to 5 seconds for the client to terminate the session. */
    for (n = 0; n < 50 && (ssh_get_status(session) & SESSION_END) == 0; n++) {
        ssh_event_dopoll(event, 100);
    }
}

/* SIGCHLD handler for cleaning up dead children. */
static void sigchld_handler(int signo) {
    (void) signo;
    while (waitpid(-1, NULL, WNOHANG) > 0);
}

int main(int argc, char **argv) {
    ssh_bind sshbind;
    ssh_session session;
    ssh_event event;
    struct sigaction sa;
    int rc;

    /* Set up SIGCHLD handler. */
    sa.sa_handler = sigchld_handler;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART | SA_NOCLDSTOP;
    if (sigaction(SIGCHLD, &sa, NULL) != 0) {
        fprintf(stderr, "Failed to register SIGCHLD handler\n");
        return 1;
    }

    rc = ssh_init();
    if (rc < 0) {
        fprintf(stderr, "ssh_init failed\n");
        return 1;
    }

    sshbind = ssh_bind_new();
    if (sshbind == NULL) {
        fprintf(stderr, "ssh_bind_new failed\n");
        return 1;
    }

#ifdef HAVE_ARGP_H
    argp_parse(&argp, argc, argv, 0, 0, sshbind);
#else
    (void) argc;
    (void) argv;

    set_default_keys(sshbind, 0, 0, 0);
#endif /* HAVE_ARGP_H */

    if(ssh_bind_listen(sshbind) < 0) {
        fprintf(stderr, "%s\n", ssh_get_error(sshbind));
        return 1;
    }

    while (1) {
        session = ssh_new();
        if (session == NULL) {
            fprintf(stderr, "Failed to allocate session\n");
            continue;
        }

        /* Blocks until there is a new incoming connection. */
        if(ssh_bind_accept(sshbind, session) != SSH_ERROR) {
            switch(fork()) {
                case 0:
                    /* Remove the SIGCHLD handler inherited from parent. */
                    sa.sa_handler = SIG_DFL;
                    sigaction(SIGCHLD, &sa, NULL);
                    /* Remove socket binding, which allows us to restart the
                     * parent process, without terminating existing sessions. */
                    ssh_bind_free(sshbind);

                    event = ssh_event_new();
                    if (event != NULL) {
                        /* Blocks until the SSH session ends by either
                         * child process exiting, or client disconnecting. */
                        handle_session(event, session);
                        ssh_event_free(event);
                    } else {
                        fprintf(stderr, "Could not create polling context\n");
                    }
                    ssh_disconnect(session);
                    ssh_free(session);

                    exit(0);
                case -1:
                    fprintf(stderr, "Failed to fork\n");
            }
        } else {
            fprintf(stderr, "%s\n", ssh_get_error(sshbind));
        }
        /* Since the session has been passed to a child fork, do some cleaning
         * up at the parent process. */
        ssh_disconnect(session);
        ssh_free(session);
    }

    ssh_bind_free(sshbind);
    ssh_finalize();
    return 0;
}
Ejemplo n.º 21
0
int Connector::startVNCSession(string hours, string minutes, string seconds) {
    std::string command = "/usr/sara/bin/rvs_vnc " + m_hours + ":" + m_minutes + ":" + m_seconds ;
	
	// creates a new channel
	channel = ssh_channel_new(sshSession);
	if (channel == NULL) {
		output->append("ERROR: Unable to set up channel between host and client...") ; 
		exit(-1) ; 
	}
	
	// links the channel to the current ssh session
	int response = ssh_channel_open_session(channel);
	if (response != SSH_OK) {
		ssh_channel_free(channel);
		output->append("ERROR: Unable to set up channel between host and client...") ; 
		exit(-1) ;
	}
	
	// Executes the command
	output->append("A new channel has been opened.") ; 
	response = ssh_channel_request_exec(channel, command.c_str());
	if (response != SSH_OK){
		output->append("ERROR: Unable to execute the command on the host...") ; 
		exit(-1) ;
	}
	
	// Reading the result of the command and printing it to the status bar
	char buffer[8192];
	unsigned int nbytes;
	
	nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
	while (nbytes > 0)
	{
		if (fwrite(buffer, 1, nbytes, stdout) != nbytes)
		{
			ssh_channel_close(channel);
			ssh_channel_free(channel);
			output->append("ERROR: buffer to small to read all data") ;
			break ; 
		}
		nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
	}
	
	if (nbytes < 0)
	{
		ssh_channel_close(channel);
		ssh_channel_free(channel);
		output->append("ERROR: buffer to small to read all data") ; 
	}
	
	/*Check whether the new VNC session is queued */
	std::string bufferOutput = buffer ; 
	size_t found = bufferOutput.find("v42-") ; 
    std::string strNode (bufferOutput, found + 4, 2) ; 
    QString strNode2 = QString::fromStdString(strNode) ;
    QString status = QString("Connection to node %1").arg(strNode2) ;
	output->append(status) ; 
	int node = atoi(strNode.c_str());
    //int node = strNode.toInt() ;
		
	// Closes the channel
	ssh_channel_send_eof(channel);
	ssh_channel_close(channel);		

    output->append("Loading VNC session...") ;
    qApp->processEvents() ;
    return node ;
}
Ejemplo n.º 22
0
static void *nogvl_send_eof(void *ptr) {
  struct nogvl_channel_args *args = ptr;
  args->rc = ssh_channel_send_eof(args->channel);
  return NULL;
}
Ejemplo n.º 23
0
void send_channel_eof() {
  ssh_channel_send_eof(channel);
}
Ejemplo n.º 24
0
int channel_send_eof(ssh_channel channel){
  return ssh_channel_send_eof(channel);
}