コード例 #1
0
ファイル: ssh_server.c プロジェクト: seem8/friendup
int handleSSHCommands( SSHSession *sess, const char *buf, const int len )
{	
	char outbuf[ 2048 ];
	
	if( strncmp( buf, "help", 4 ) == 0 )
	{
		strcpy( outbuf, 	"Main commands:\n" \
			" logout - logout user from current session\n" \
			" cd - change current directory\n" \
			);
		
		ssh_channel_write( sess->sshs_Chan, outbuf, strlen( buf ) );
	
	}else if( strncmp( buf, "logout", 6 ) == 0 )
	{
		sess->sshs_Quit = TRUE;
	}else if( strncmp( buf, "cd", 2 ) == 0 )
	{
			
	}else{	// command not found
		ssh_channel_write( sess->sshs_Chan, "Command not found\n", 18 );
		
		//ssh_channel_write( chan, buf, i );
		//if( write( 1, buf, i ) < 0 )
		//{
		//	ERROR("error writing to buffer\n");
		//	break;
		//}
	}
	
	return 0;
}
コード例 #2
0
ファイル: scp.c プロジェクト: Paxxi/libssh
/**
 * @brief Write into a remote scp file.
 *
 * @param[in]  scp      The scp handle.
 *
 * @param[in]  buffer   The buffer to write.
 *
 * @param[in]  len      The number of bytes to write.
 *
 * @returns             SSH_OK if the write was successful, SSH_ERROR an error
 *                      occured while writing.
 */
int ssh_scp_write(ssh_scp scp, const void *buffer, size_t len){
  int w;
  int r;
  uint8_t code;
  if(scp==NULL)
      return SSH_ERROR;
  if(scp->state != SSH_SCP_WRITE_WRITING){
    ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_write called under invalid state");
    return SSH_ERROR;
  }
  if(scp->processed + len > scp->filelen)
    len = (size_t) (scp->filelen - scp->processed);
  /* hack to avoid waiting for window change */
  r = ssh_channel_poll(scp->channel, 0);
  if (r == SSH_ERROR) {
      scp->state = SSH_SCP_ERROR;
      return SSH_ERROR;
  }
  w=ssh_channel_write(scp->channel,buffer,len);
  if(w != SSH_ERROR)
    scp->processed += w;
  else {
    scp->state=SSH_SCP_ERROR;
    //return=channel_get_exit_status(scp->channel);
    return SSH_ERROR;
  }
  /* Far end sometimes send a status message, which we need to read
   * and handle */
  r = ssh_channel_poll(scp->channel,0);
  if(r > 0){
    r = ssh_channel_read(scp->channel, &code, 1, 0);
    if(r == SSH_ERROR){
      return SSH_ERROR;
    }
    if(code == 1 || code == 2){
      ssh_set_error(scp->session,SSH_REQUEST_DENIED, "SCP: Error: status code %i received", code);
      return SSH_ERROR;
    }
  }
  /* Check if we arrived at end of file */
  if(scp->processed == scp->filelen) {
    code = 0;
    w = ssh_channel_write(scp->channel, &code, 1);
    if(w == SSH_ERROR){
      scp->state = SSH_SCP_ERROR;
      return SSH_ERROR;
    }
    scp->processed=scp->filelen=0;
    scp->state=SSH_SCP_WRITE_INITED;
  }
  return SSH_OK;
}
コード例 #3
0
ファイル: scp.c プロジェクト: Paxxi/libssh
/**
 * @brief Create a directory in a scp in sink mode.
 *
 * @param[in]  scp      The scp handle.
 *
 * @param[in]  dirname  The name of the directory being created.
 *
 * @param[in]  mode     The UNIX permissions for the new directory, e.g. 0755.
 *
 * @returns             SSH_OK if the directory has been created, SSH_ERROR if
 *                      an error occured.
 *
 * @see ssh_scp_leave_directory()
 */
int ssh_scp_push_directory(ssh_scp scp, const char *dirname, int mode){
  char buffer[1024];
  int r;
  uint8_t code;
  char *dir;
  char *perms;
  if(scp==NULL)
      return SSH_ERROR;
  if(scp->state != SSH_SCP_WRITE_INITED){
    ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_push_directory called under invalid state");
    return SSH_ERROR;
  }
  dir=ssh_basename(dirname);
  perms=ssh_scp_string_mode(mode);
  snprintf(buffer, sizeof(buffer), "D%s 0 %s\n", perms, dir);
  SAFE_FREE(dir);
  SAFE_FREE(perms);
  r=ssh_channel_write(scp->channel,buffer,strlen(buffer));
  if(r==SSH_ERROR){
    scp->state=SSH_SCP_ERROR;
    return SSH_ERROR;
  }
  r=ssh_channel_read(scp->channel,&code,1,0);
  if(r<=0){
    ssh_set_error(scp->session,SSH_FATAL, "Error reading status code: %s",ssh_get_error(scp->session));
    scp->state=SSH_SCP_ERROR;
    return SSH_ERROR;
  }
  if(code != 0){
    ssh_set_error(scp->session,SSH_FATAL, "scp status code %ud not valid", code);
    scp->state=SSH_SCP_ERROR;
    return SSH_ERROR;
  }
  return SSH_OK;
}
コード例 #4
0
ファイル: scp.c プロジェクト: Paxxi/libssh
/**
 * @brief Leave a directory.
 *
 * @returns             SSH_OK if the directory has been left,SSH_ERROR if an
 *                      error occured.
 *
 * @see ssh_scp_push_directory()
 */
 int ssh_scp_leave_directory(ssh_scp scp){
  char buffer[]="E\n";
  int r;
  uint8_t code;
  if(scp==NULL)
      return SSH_ERROR;
  if(scp->state != SSH_SCP_WRITE_INITED){
    ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_leave_directory called under invalid state");
    return SSH_ERROR;
  }
  r=ssh_channel_write(scp->channel,buffer,strlen(buffer));
  if(r==SSH_ERROR){
    scp->state=SSH_SCP_ERROR;
    return SSH_ERROR;
  }
  r=ssh_channel_read(scp->channel,&code,1,0);
  if(r<=0){
    ssh_set_error(scp->session,SSH_FATAL, "Error reading status code: %s",ssh_get_error(scp->session));
    scp->state=SSH_SCP_ERROR;
    return SSH_ERROR;
  }
  if(code != 0){
    ssh_set_error(scp->session,SSH_FATAL, "scp status code %ud not valid", code);
    scp->state=SSH_SCP_ERROR;
    return SSH_ERROR;
  }
  return SSH_OK;
}
コード例 #5
0
static void on_pty_event(struct tmate_session *session)
{
	ssize_t len, written;
	char buf[4096];

	for (;;) {
		len = read(session->pty, buf, sizeof(buf));
		if (len < 0) {
			if (errno == EAGAIN)
				return;
			tmate_fatal("pty read error");
		}

		if (len == 0)
			tmate_fatal("pty reached EOF");

		written = ssh_channel_write(session->ssh_client.channel, buf, len);
		if (written < 0)
			tmate_fatal("Error writing to channel: %s",
				    ssh_get_error(session->ssh_client.session));
		if (len != written)
			tmate_fatal("Cannot write %d bytes, wrote %d",
				    (int)len, (int)written);
	}
}
コード例 #6
0
ファイル: ciscodump.c プロジェクト: acaceres2176/wireshark
static int check_ios_version(ssh_channel channel)
{
	gchar* cmdline = "show version | include Cisco IOS\n";
	gchar version[255];
	guint major = 0;
	guint minor = 0;
	gchar* cur;

	memset(version, 0x0, 255);

	if (ssh_channel_write(channel, cmdline, (guint32)strlen(cmdline)) == SSH_ERROR)
		return FALSE;
	if (read_output_bytes(channel, (int)strlen(cmdline), NULL) == EXIT_FAILURE)
		return FALSE;
	if (read_output_bytes(channel, 255, version) == EXIT_FAILURE)
		return FALSE;

	cur = g_strstr_len(version, strlen(version), "Version");
	if (cur) {
		cur += strlen("Version ");
		if (sscanf(cur, "%u.%u", &major, &minor) != 2)
			return FALSE;

		if ((major > MINIMUM_IOS_MAJOR) || (major == MINIMUM_IOS_MAJOR && minor >= MINIMUM_IOS_MINOR)) {
			g_debug("Current IOS Version: %u.%u", major, minor);
			if (read_output_bytes(channel, -1, NULL) == EXIT_FAILURE)
				return FALSE;
			return TRUE;
		}
	}

	g_warning("Invalid IOS version. Minimum version: 12.4, current: %u.%u", major, minor);
	return FALSE;
}
コード例 #7
0
ファイル: scp.c プロジェクト: Paxxi/libssh
/**
 * @brief Initialize the scp channel.
 *
 * @param[in]  scp      The scp context to initialize.
 *
 * @return SSH_OK on success or an SSH error code.
 *
 * @see ssh_scp_new()
 */
int ssh_scp_init(ssh_scp scp)
{
  int r;
  char execbuffer[1024];
  uint8_t code;
  if(scp==NULL)
      return SSH_ERROR;
  if(scp->state != SSH_SCP_NEW){
    ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_init called under invalid state");
    return SSH_ERROR;
  }
  SSH_LOG(SSH_LOG_PROTOCOL,"Initializing scp session %s %son location '%s'",
		  scp->mode==SSH_SCP_WRITE?"write":"read",
				  scp->recursive?"recursive ":"",
						  scp->location);
  scp->channel=ssh_channel_new(scp->session);
  if(scp->channel == NULL){
    scp->state=SSH_SCP_ERROR;
    return SSH_ERROR;
  }
  r= ssh_channel_open_session(scp->channel);
  if(r==SSH_ERROR){
    scp->state=SSH_SCP_ERROR;
    return SSH_ERROR;
  }
  if(scp->mode == SSH_SCP_WRITE)
    snprintf(execbuffer,sizeof(execbuffer),"scp -t %s %s",
    		scp->recursive ? "-r":"", scp->location);
  else
    snprintf(execbuffer,sizeof(execbuffer),"scp -f %s %s",
    		scp->recursive ? "-r":"", scp->location);
  if(ssh_channel_request_exec(scp->channel,execbuffer) == SSH_ERROR){
    scp->state=SSH_SCP_ERROR;
    return SSH_ERROR;
  }
  if(scp->mode == SSH_SCP_WRITE){
	  r=ssh_channel_read(scp->channel,&code,1,0);
	  if(r<=0){
	    ssh_set_error(scp->session,SSH_FATAL, "Error reading status code: %s",ssh_get_error(scp->session));
	    scp->state=SSH_SCP_ERROR;
	    return SSH_ERROR;
	  }
	  if(code != 0){
		  ssh_set_error(scp->session,SSH_FATAL, "scp status code %ud not valid", code);
		  scp->state=SSH_SCP_ERROR;
		  return SSH_ERROR;
	  }
  } else {
	  ssh_channel_write(scp->channel,"",1);
  }
  if(scp->mode == SSH_SCP_WRITE)
    scp->state=SSH_SCP_WRITE_INITED;
  else
    scp->state=SSH_SCP_READ_INITED;
  return SSH_OK;
}
コード例 #8
0
ファイル: socketSSH.cpp プロジェクト: carriercomm/EtherTerm
/* returns 0 on any errors, length sent on success */
int SSH_Socket::sendSocket(unsigned char *buf, Uint32 len)
{
    Uint32 result = 0;

    result = ssh_channel_write(sshChannel, buf, len);
    if(result < strlen((char *)buf))
    {
        return SSH_ERROR; // or Zero.
    }
    return(result);
}
コード例 #9
0
ファイル: cl_ssh.cpp プロジェクト: eranif/codelite
void clSSH::ExecuteShellCommand(wxEvtHandler* owner, const wxString& command)
{
    DoOpenChannel();

    m_owner = owner;
    if(!m_owner) { throw clException(wxString() << "No owner specified for output"); }

    wxCharBuffer buffer = command.mb_str(wxConvUTF8);
    int rc = ssh_channel_write(m_channel, buffer.data(), buffer.length());
    if(rc != (int)buffer.length()) { throw clException("SSH Socket error"); }

    // Start a timer to check for the output on 10ms intervals
    if(!m_timer->IsRunning()) { m_timer->Start(50); }
}
コード例 #10
0
ファイル: ssh_server_fork.c プロジェクト: cedral/libssh
static int process_stdout(socket_t fd, int revents, void *userdata) {
    char buf[BUF_SIZE];
    int n = -1;
    ssh_channel channel = (ssh_channel) userdata;

    if (channel != NULL && (revents & POLLIN) != 0) {
        n = read(fd, buf, BUF_SIZE);
        if (n > 0) {
            ssh_channel_write(channel, buf, n);
        }
    }

    return n;
}
コード例 #11
0
/* Write data to the channel.  Throw `guile-ssh-error' on a libssh
   error, or signal a system error if amount of data written is
   smaller than size SZ. */
static void
ptob_write (SCM channel, const void *data, size_t sz)
#define FUNC_NAME "ptob_write"
{
  struct channel_data *channel_data = _scm_to_channel_data (channel);
  int res = ssh_channel_write (channel_data->ssh_channel, data, sz);
  if (res == SSH_ERROR)
    {
      ssh_session session = ssh_channel_get_session (channel_data->ssh_channel);
      guile_ssh_session_error1 (FUNC_NAME, session, channel);
    }

  if (res < sz)
    scm_syserror (FUNC_NAME);
}
コード例 #12
0
static size_t
write_to_channel_port (SCM channel, SCM src, size_t start, size_t count)
#define FUNC_NAME "write_to_channel_port"
{
  char *data = (char *) SCM_BYTEVECTOR_CONTENTS (src) + start;
  struct channel_data *channel_data = _scm_to_channel_data (channel);

  int res = ssh_channel_write (channel_data->ssh_channel, data, count);
  if (res == SSH_ERROR)
    {
      ssh_session session = ssh_channel_get_session (channel_data->ssh_channel);
      guile_ssh_session_error1 (FUNC_NAME, session, channel);
    }

  assert (res >= 0);
  return res;
}
コード例 #13
0
ファイル: scp.c プロジェクト: Paxxi/libssh
/**
 * @brief Accepts transfer of a file or creation of a directory coming from the
 * remote party.
 *
 * @param[in]  scp      The scp handle.
 *
 * @returns             SSH_OK if the message was sent, SSH_ERROR if sending the
 *                      message failed, or sending it in a bad state.
 */
int ssh_scp_accept_request(ssh_scp scp){
  char buffer[]={0x00};
  int err;
  if(scp==NULL)
      return SSH_ERROR;
  if(scp->state != SSH_SCP_READ_REQUESTED){
    ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_deny_request called under invalid state");
    return SSH_ERROR;
  }
  err=ssh_channel_write(scp->channel,buffer,1);
  if(err==SSH_ERROR) {
    return SSH_ERROR;
  }
  if(scp->request_type==SSH_SCP_REQUEST_NEWFILE)
    scp->state=SSH_SCP_READ_READING;
  else
    scp->state=SSH_SCP_READ_INITED;
  return SSH_OK;
}
コード例 #14
0
ファイル: scp.c プロジェクト: Paxxi/libssh
/**
 * @brief Deny the transfer of a file or creation of a directory coming from the
 * remote party.
 *
 * @param[in]  scp      The scp handle.
 * @param[in]  reason   A nul-terminated string with a human-readable
 *                      explanation of the deny.
 *
 * @returns             SSH_OK if the message was sent, SSH_ERROR if the sending
 *                      the message failed, or sending it in a bad state.
 */
int ssh_scp_deny_request(ssh_scp scp, const char *reason){
  char buffer[MAX_BUF_SIZE];
  int err;
  if(scp==NULL)
      return SSH_ERROR;
  if(scp->state != SSH_SCP_READ_REQUESTED){
    ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_deny_request called under invalid state");
    return SSH_ERROR;
  }
  snprintf(buffer,sizeof(buffer),"%c%s\n",2,reason);
  err=ssh_channel_write(scp->channel,buffer,strlen(buffer));
  if(err==SSH_ERROR) {
    return SSH_ERROR;
  }
  else {
    scp->state=SSH_SCP_READ_INITED;
    return SSH_OK;
  }
}
コード例 #15
0
ファイル: scp.c プロジェクト: Paxxi/libssh
/** @brief Read from a remote scp file
 * @param[in]  scp      The scp handle.
 *
 * @param[in]  buffer   The destination buffer.
 *
 * @param[in]  size     The size of the buffer.
 *
 * @returns             The nNumber of bytes read, SSH_ERROR if an error occured
 *                      while reading.
 */
int ssh_scp_read(ssh_scp scp, void *buffer, size_t size){
  int r;
  int code;
  if(scp==NULL)
      return SSH_ERROR;
  if(scp->state == SSH_SCP_READ_REQUESTED && scp->request_type == SSH_SCP_REQUEST_NEWFILE){
    r=ssh_scp_accept_request(scp);
    if(r==SSH_ERROR)
      return r;
  }
  if(scp->state != SSH_SCP_READ_READING){
    ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_read called under invalid state");
    return SSH_ERROR;
  }
  if(scp->processed + size > scp->filelen)
    size = (size_t) (scp->filelen - scp->processed);
  if(size > 65536)
    size=65536; /* avoid too large reads */
  r=ssh_channel_read(scp->channel,buffer,size,0);
  if(r != SSH_ERROR)
    scp->processed += r;
  else {
    scp->state=SSH_SCP_ERROR;
    return SSH_ERROR;
  }
  /* Check if we arrived at end of file */
  if(scp->processed == scp->filelen) {
    scp->processed=scp->filelen=0;
    ssh_channel_write(scp->channel,"",1);
    code=ssh_scp_response(scp,NULL);
    if(code == 0){
    	scp->state=SSH_SCP_READ_INITED;
    	return r;
    }
    if(code==1){
    	scp->state=SSH_SCP_READ_INITED;
    	return SSH_ERROR;
    }
    scp->state=SSH_SCP_ERROR;
    return SSH_ERROR;
  }
  return r;
}
コード例 #16
0
/* Complete the processing of buffered output data.  Currently this
   callback makes no effect because the channel CHANNEL uses
   unbuffered output. */
static void
ptob_flush (SCM channel)
#define FUNC_NAME "ptob_flush"
{
  scm_port *pt = SCM_PTAB_ENTRY (channel);
  struct channel_data *cd = _scm_to_channel_data (channel);
  size_t wrsize = pt->write_pos - pt->write_buf;

  if (wrsize)
    {
      int res = ssh_channel_write (cd->ssh_channel, pt->write_buf, wrsize);
      if (res == SSH_ERROR)
        {
          ssh_session session = ssh_channel_get_session (cd->ssh_channel);
          guile_ssh_session_error1 (FUNC_NAME, session, channel);
        }
    }

  pt->write_pos = pt->write_buf;
}
コード例 #17
0
ファイル: samplesshd-tty.c プロジェクト: FuckingCoder/libssh
static int copy_fd_to_chan(socket_t fd, int revents, void *userdata) {
    ssh_channel chan = (ssh_channel)userdata;
    char buf[2048];
    int sz = 0;

    if(!chan) {
        close(fd);
        return -1;
    }
    if(revents & POLLIN) {
        sz = read(fd, buf, 2048);
        if(sz > 0) {
            ssh_channel_write(chan, buf, sz);
        }
    }
    if(revents & POLLHUP) {
        ssh_channel_close(chan);
        sz = -1;
    }
    return sz;
}
コード例 #18
0
ファイル: scp.c プロジェクト: Ludoovik5/libssh
/**
 * @brief Write into a remote scp file.
 *
 * @param[in]  scp      The scp handle.
 *
 * @param[in]  buffer   The buffer to write.
 *
 * @param[in]  len      The number of bytes to write.
 *
 * @returns             SSH_OK if the write was successful, SSH_ERROR an error
 *                      occured while writing.
 */
int ssh_scp_write(ssh_scp scp, const void *buffer, size_t len){
  int w;
  //int r;
  //uint8_t code;
  if(scp==NULL)
      return SSH_ERROR;
  if(scp->state != SSH_SCP_WRITE_WRITING){
    ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_write called under invalid state");
    return SSH_ERROR;
  }
  if(scp->processed + len > scp->filelen)
    len = scp->filelen - scp->processed;
  /* hack to avoid waiting for window change */
  ssh_channel_poll(scp->channel,0);
  w=ssh_channel_write(scp->channel,buffer,len);
  if(w != SSH_ERROR)
    scp->processed += w;
  else {
    scp->state=SSH_SCP_ERROR;
    //return=channel_get_exit_status(scp->channel);
    return SSH_ERROR;
  }
  /* Check if we arrived at end of file */
  if(scp->processed == scp->filelen) {
/*    r=channel_read(scp->channel,&code,1,0);
    if(r==SSH_ERROR){
      scp->state=SSH_SCP_ERROR;
      return SSH_ERROR;
    }
    if(code != 0){
      ssh_set_error(scp->session,SSH_FATAL, "scp status code %ud not valid", code);
      scp->state=SSH_SCP_ERROR;
      return SSH_ERROR;
    }
*/
    scp->processed=scp->filelen=0;
    scp->state=SSH_SCP_WRITE_INITED;
  }
  return SSH_OK;
}
コード例 #19
0
ファイル: scp.c プロジェクト: Paxxi/libssh
/**
 * @brief Initialize the sending of a file to a scp in sink mode, using a 64-bit size.
 *
 * @param[in]  scp      The scp handle.
 *
 * @param[in]  filename The name of the file being sent. It should not contain
 *                      any path indicator
 *
 * @param[in]  size     Exact size in bytes of the file being sent.
 *
 * @param[in]  mode     The UNIX permissions for the new file, e.g. 0644.
 *
 * @returns             SSH_OK if the file is ready to be sent, SSH_ERROR if an
 *                      error occured.
 *
 * @see ssh_scp_push_file()
 */
int ssh_scp_push_file64(ssh_scp scp, const char *filename, uint64_t size, int mode){
  char buffer[1024];
  int r;
  uint8_t code;
  char *file;
  char *perms;
  if(scp==NULL)
      return SSH_ERROR;
  if(scp->state != SSH_SCP_WRITE_INITED){
    ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_push_file called under invalid state");
    return SSH_ERROR;
  }
  file=ssh_basename(filename);
  perms=ssh_scp_string_mode(mode);
  SSH_LOG(SSH_LOG_PROTOCOL,"SCP pushing file %s, size %" PRIu64 " with permissions '%s'",file,size,perms);
  snprintf(buffer, sizeof(buffer), "C%s %" PRIu64 " %s\n", perms, size, file);
  SAFE_FREE(file);
  SAFE_FREE(perms);
  r=ssh_channel_write(scp->channel,buffer,strlen(buffer));
  if(r==SSH_ERROR){
    scp->state=SSH_SCP_ERROR;
    return SSH_ERROR;
  }
  r=ssh_channel_read(scp->channel,&code,1,0);
  if(r<=0){
    ssh_set_error(scp->session,SSH_FATAL, "Error reading status code: %s",ssh_get_error(scp->session));
    scp->state=SSH_SCP_ERROR;
    return SSH_ERROR;
  }
  if(code != 0){
    ssh_set_error(scp->session,SSH_FATAL, "scp status code %ud not valid", code);
    scp->state=SSH_SCP_ERROR;
    return SSH_ERROR;
  }
  scp->filelen = size;
  scp->processed = 0;
  scp->state=SSH_SCP_WRITE_WRITING;
  return SSH_OK;
}
コード例 #20
0
ファイル: cockpitsshtransport.c プロジェクト: leospol/cockpit
static gboolean
dispatch_queue (CockpitSshTransport *self)
{
  GBytes *block;
  const guchar *data;
  gsize length;
  gsize want;
  int rc;

  if (self->sent_eof)
    return FALSE;
  if (self->received_close)
    return FALSE;

  for (;;)
    {
      block = g_queue_peek_head (self->queue);
      if (!block)
        return FALSE;

      data = g_bytes_get_data (block, &length);
      g_assert (self->partial <= length);

      want = length - self->partial;
      rc = ssh_channel_write (self->data->channel, data + self->partial, want);
      if (rc < 0)
        {
          if (ssh_get_error_code (self->data->session) == SSH_REQUEST_DENIED)
            {
              g_debug ("%s: couldn't write: %s", self->logname,
                       ssh_get_error (self->data->session));
              return FALSE;
            }
          else
            {
              g_warning ("%s: couldn't write: %s", self->logname,
                         ssh_get_error (self->data->session));
              close_immediately (self, "internal-error");
            }
          break;
        }

      if (rc == want)
        {
          g_debug ("%s: wrote %d bytes", self->logname, rc);
          g_queue_pop_head (self->queue);
          g_bytes_unref (block);
          self->partial = 0;
        }
      else
        {
          g_debug ("%s: wrote %d of %d bytes", self->logname, rc, (int)want);
          g_return_val_if_fail (rc < want, FALSE);
          self->partial += rc;
          if (rc == 0)
            break;
        }
    }

  return TRUE;
}
コード例 #21
0
ファイル: scp.c プロジェクト: Paxxi/libssh
/**
 * @brief Wait for a scp request (file, directory).
 *
 * @returns             SSH_SCP_REQUEST_NEWFILE:       The other side is sending
 *                                                     a file
 *                      SSH_SCP_REQUEST_NEWDIR:  The other side is sending
 *                                                     a directory
 *                      SSH_SCP_REQUEST_ENDDIR: The other side has
 *                                                     finished with the current
 *                                                     directory
 *                      SSH_SCP_REQUEST_WARNING: The other side sent us a warning
 *                      SSH_SCP_REQUEST_EOF: The other side finished sending us
 *                                           files and data.
 *                      SSH_ERROR:                     Some error happened
 *
 * @see ssh_scp_read()
 * @see ssh_scp_deny_request()
 * @see ssh_scp_accept_request()
 * @see ssh_scp_request_get_warning()
 */
int ssh_scp_pull_request(ssh_scp scp){
  char buffer[MAX_BUF_SIZE] = {0};
  char *mode=NULL;
  char *p,*tmp;
  uint64_t size;
  char *name=NULL;
  int err;
  if(scp==NULL)
      return SSH_ERROR;
  if(scp->state != SSH_SCP_READ_INITED){
    ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_pull_request called under invalid state");
    return SSH_ERROR;
  }
  err=ssh_scp_read_string(scp,buffer,sizeof(buffer));
  if(err==SSH_ERROR){
	if(ssh_channel_is_eof(scp->channel)){
		scp->state=SSH_SCP_TERMINATED;
		return SSH_SCP_REQUEST_EOF;
	}
    return err;
  }
  p=strchr(buffer,'\n');
  if(p!=NULL)
	  *p='\0';
  SSH_LOG(SSH_LOG_PROTOCOL,"Received SCP request: '%s'",buffer);
  switch(buffer[0]){
    case 'C':
      /* File */
    case 'D':
      /* Directory */
      p=strchr(buffer,' ');
      if(p==NULL)
        goto error;
      *p='\0';
      p++;
      //mode=strdup(&buffer[1]);
      scp->request_mode=ssh_scp_integer_mode(&buffer[1]);
      tmp=p;
      p=strchr(p,' ');
      if(p==NULL)
        goto error;
      *p=0;
      size = strtoull(tmp,NULL,10);
      p++;
      name=strdup(p);
      SAFE_FREE(scp->request_name);
      scp->request_name=name;
      if(buffer[0]=='C'){
        scp->filelen=size;
        scp->request_type=SSH_SCP_REQUEST_NEWFILE;
      } else {
        scp->filelen='0';
        scp->request_type=SSH_SCP_REQUEST_NEWDIR;
      }
      scp->state=SSH_SCP_READ_REQUESTED;
      scp->processed = 0;
      return scp->request_type;
      break;
    case 'E':
    	scp->request_type=SSH_SCP_REQUEST_ENDDIR;
    	ssh_channel_write(scp->channel,"",1);
    	return scp->request_type;
    case 0x1:
    	ssh_set_error(scp->session,SSH_REQUEST_DENIED,"SCP: Warning: %s",&buffer[1]);
    	scp->request_type=SSH_SCP_REQUEST_WARNING;
    	SAFE_FREE(scp->warning);
    	scp->warning=strdup(&buffer[1]);
    	return scp->request_type;
    case 0x2:
    	ssh_set_error(scp->session,SSH_FATAL,"SCP: Error: %s",&buffer[1]);
    	return SSH_ERROR;
    case 'T':
      /* Timestamp */
    default:
      ssh_set_error(scp->session,SSH_FATAL,"Unhandled message: (%d)%s",buffer[0],buffer);
      return SSH_ERROR;
  }

  /* a parsing error occured */
  error:
  SAFE_FREE(name);
  SAFE_FREE(mode);
  ssh_set_error(scp->session,SSH_FATAL,"Parsing error while parsing message: %s",buffer);
  return SSH_ERROR;
}
コード例 #22
0
ファイル: channel.c プロジェクト: sorah/libssh-ruby
static void *nogvl_write(void *ptr) {
  struct nogvl_write_args *args = ptr;
  args->rc = ssh_channel_write(args->channel, args->data, args->len);
  return NULL;
}
コード例 #23
0
ファイル: ssh_server.c プロジェクト: seem8/friendup
int SSHThread( void *data )
{
	// TODO: Hogne was here, disabling this problem child.. :)
	return 0;
#ifdef ENABLE_SSH	
	ssh_session session = NULL;
	ssh_bind sshbind = NULL;
	
	ssh_event mainloop;
	struct ssh_server_callbacks_struct cb = {
		.userdata = NULL,
		.auth_password_function = auth_password,
		.auth_gssapi_mic_function = auth_gssapi_mic,
		.channel_open_request_session_function = new_session_channel
	};
	
	char buf[2048];
	int i;
	int r;
	
	DEBUG("Starting SSH Process\n");
	
	SSHServer *ts = (SSHServer *)data;
	if( !ts ) return 0;

	ts->sshs_FriendHome = getenv( "FRIEND_HOME" );
		
	int len = strlen( ts->sshs_FriendHome );
	ts->sshs_RSAKeyHome = calloc( len+64, sizeof(char) );
	ts->sshs_DSAKeyHome = calloc( len+64, sizeof(char) );
		
	strcpy( ts->sshs_RSAKeyHome, ts->sshs_FriendHome );
	strcpy( ts->sshs_DSAKeyHome, ts->sshs_FriendHome );
	strcat( ts->sshs_RSAKeyHome, "keys/ssh_host_rsa_key" );
	strcat( ts->sshs_DSAKeyHome, "keys/ssh_host_dsa_key" );
	
	//DEBUG("SSH sshs_RSAKeyHome set to %s\n", ts->sshs_RSAKeyHome );
		
	sshbind = ssh_bind_new();
		
	BOOL welcomeMessage = FALSE;
		
	ssh_bind_options_set( sshbind, SSH_BIND_OPTIONS_DSAKEY, ts->sshs_DSAKeyHome );
	ssh_bind_options_set( sshbind, SSH_BIND_OPTIONS_RSAKEY, ts->sshs_RSAKeyHome );
	//ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg);
	
	//DEBUG("IMPORT RSA KEY %s\n", ts->sshs_RSAKeyHome );
	
	ssh_bind_options_set( sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, SSH_SERVER_PORT );	
	//verbose
	ssh_bind_options_set( sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "2" );
	ssh_bind_options_set( sshbind, SSH_BIND_OPTIONS_BINDADDR, "127.0.0.1" );
		
	if( ts->sshs_RSAKeyHome ) free( ts->sshs_RSAKeyHome );
	if( ts->sshs_DSAKeyHome ) free( ts->sshs_DSAKeyHome );
	
	// TODO: ts->sshs_Quit sometimes can not be read!
	while( ts != NULL && !ts->sshs_Quit )
	{
		DEBUG("Server options set\n");
	
	#ifdef WITH_PCAP
		set_pcap(session);
	#endif
		
		DEBUG("Server before bind\n");
		if( ssh_bind_listen( sshbind )<0 )
		{
			ERROR("Error listening to socket: %s\n",ssh_get_error(sshbind) );
			break;
		}
		
		DEBUG("Server before accept\n");

		session=ssh_new();
		r = ssh_bind_accept( sshbind , session );
		if( r==SSH_ERROR )
		{
			ERROR("error accepting a connection : %s\n",ssh_get_error(sshbind));
			break;
		}
		
		ssh_callbacks_init( &cb );
		SSHSession *sess = calloc( 1, sizeof( SSHSession ) );
		sess->sshs_Session = session;
		cb.userdata = sess;
		
		DEBUG("User data set\n");
		ssh_set_server_callbacks( session, &cb );
    
		if ( ssh_handle_key_exchange( session ) ) 
		{
			ERROR("ssh_handle_key_exchange: %s\n", ssh_get_error(session));
			continue;
			//goto disconnect;
		}
	
		DEBUG("Connection accepted\n");
	
		ssh_set_auth_methods( session,SSH_AUTH_METHOD_PASSWORD | SSH_AUTH_METHOD_GSSAPI_MIC );
		
		//
		// New session/connection put it into thread
		//
		
		switch( fork() ) 
		{
			case 0:
				// Remove the SIGCHLD handler inherited from parent 
				signal(SIGCHLD, SIG_DFL);
			
				mainloop = ssh_event_new();
				ssh_event_add_session( mainloop, session );
			
				while( !(sess->sshs_Authenticated && sess->sshs_Chan != NULL) )
				{
					if( sess->sshs_Error )
					{
						ERROR("SSHSession error %d\n", sess->sshs_Error );
						break;
					}
			
					r = ssh_event_dopoll( mainloop, -1 );
					if( r == SSH_ERROR )
					{
						ERROR("Error : %s\n",ssh_get_error( session ) );
						ssh_disconnect( session );
						return 1;
					}
				
					strcpy( buf,	"------------------------------------------------------\n\r" \
									"--- Welcome in FC server, use help to work with me ---\n\r" \
									"------------------------------------------------------\n\r" );
				
					ssh_channel_write( sess->sshs_Chan, buf, strlen( buf ) );
				
					if( sess->sshs_Path == NULL )
					{
						sess->sshs_Path = calloc( 1024, sizeof(char) );
						sess->sshs_DispText = calloc( 1024+48, sizeof(char) );
					}
					strcpy( sess->sshs_Path, "/" );
		
					if( sess->sshs_Usr )
					{
						sprintf( sess->sshs_DispText, "%s:%s ", sess->sshs_Usr->u_Name, sess->sshs_Path );
					}else{
						sprintf( sess->sshs_DispText, ":%s ", sess->sshs_Path );
					}
				
					int i = 0;
				
					do
					{
						ssh_channel_write( sess->sshs_Chan, sess->sshs_DispText, strlen( sess->sshs_DispText ) );
					
						i = ssh_channel_read( sess->sshs_Chan, buf, 2048, 0 );
						if( i > 0 )
						{
							DEBUG("READING FROM CHANNEL %d - size %d  %d  %c -n  %d\n", i, strlen( buf ), buf[0], buf[0], '\n' );
							//ssh_channel_write( sess->sshs_Chan, buf, 1 );
						
							handleSSHCommands( sess, buf, i );
						}
					
						if( sess->sshs_Quit )
						{
							break;
						}
					
					}
					while( i>0 );
				
					if( sess->sshs_Quit )
						break;
				}
				DEBUG("Closing ssh connection\n");
			
				ssh_event_free( mainloop );
				ssh_disconnect( session );
				ssh_free( session );
			
				if( sess->sshs_DispText )
				{
					FFree( sess->sshs_DispText );
				}
			
				if( sess->sshs_Path )
				{
					FFree( sess->sshs_Path );
				}
			
				DEBUG("Connection released\n");

				FFree( sess );
			
				abort();
			
				DEBUG("AUTH\n");
				break;
			case -1:
				ERROR("Cannot create fork!\n");
				break;
		}
		

	#ifdef WITH_PCAP
		cleanup_pcap();
	#endif
		
	}	// main loop
	disconnect:
	DEBUG("DISCONNECTED\n");
#endif // ENABLE_SSH	
    return 0;
}
コード例 #24
0
ファイル: ciscodump.c プロジェクト: acaceres2176/wireshark
static ssh_channel run_capture(ssh_session sshs, const char* iface, const char* cfilter, const guint32 count)
{
	char* cmdline = NULL;
	ssh_channel channel;
	int ret = 0;

	channel = ssh_channel_new(sshs);
	if (!channel)
		return NULL;

	if (ssh_channel_open_session(channel) != SSH_OK)
		goto error;

	if (ssh_channel_request_pty(channel) != SSH_OK)
		goto error;

	if (ssh_channel_change_pty_size(channel, 80, 24) != SSH_OK)
		goto error;

	if (ssh_channel_request_shell(channel) != SSH_OK)
		goto error;

	if (!check_ios_version(channel))
		goto error;

	if (ssh_channel_printf(channel, "terminal length 0\n") == EXIT_FAILURE)
		goto error;

	if (ssh_channel_printf(channel, "monitor capture buffer %s max-size 9500\n", WIRESHARK_CAPTURE_BUFFER) == EXIT_FAILURE)
		goto error;

	if (ssh_channel_printf(channel, "monitor capture buffer %s limit packet-count %u\n", WIRESHARK_CAPTURE_BUFFER, count) == EXIT_FAILURE)
		goto error;

	if (cfilter) {
		gchar* multiline_filter;
		gchar* chr;

		if (ssh_channel_printf(channel, "configure terminal\n") == EXIT_FAILURE)
			goto error;

		if (ssh_channel_printf(channel, "ip access-list ex %s\n", WIRESHARK_CAPTURE_ACCESSLIST) == EXIT_FAILURE)
			goto error;

		multiline_filter = g_strdup(cfilter);
		chr = multiline_filter;
		while((chr = g_strstr_len(chr, strlen(chr), ",")) != NULL) {
			chr[0] = '\n';
			g_debug("Splitting filter into multiline");
		}
		ret = ssh_channel_write(channel, multiline_filter, (uint32_t)strlen(multiline_filter));
		g_free(multiline_filter);
		if (ret == SSH_ERROR)
			goto error;

		if (ssh_channel_printf(channel, "\nend\n") == EXIT_FAILURE)
			goto error;

		if (ssh_channel_printf(channel, "monitor capture buffer %s filter access-list %s\n",
				WIRESHARK_CAPTURE_BUFFER, WIRESHARK_CAPTURE_ACCESSLIST) == EXIT_FAILURE)
			goto error;
	}

	if (ssh_channel_printf(channel, "monitor capture point ip cef %s %s both\n", WIRESHARK_CAPTURE_POINT,
			iface) == EXIT_FAILURE)
		goto error;

	if (ssh_channel_printf(channel, "monitor capture point associate %s %s \n", WIRESHARK_CAPTURE_POINT,
			WIRESHARK_CAPTURE_BUFFER) == EXIT_FAILURE)
		goto error;

	if (ssh_channel_printf(channel, "monitor capture point start %s\n", WIRESHARK_CAPTURE_POINT) == EXIT_FAILURE)
		goto error;

	if (read_output_bytes(channel, -1, NULL) == EXIT_FAILURE)
		goto error;

	if (wait_until_data(channel, count) == EXIT_FAILURE)
		goto error;

	if (read_output_bytes(channel, -1, NULL) == EXIT_FAILURE)
		goto error;

	cmdline = g_strdup_printf("show monitor capture buffer %s dump\n", WIRESHARK_CAPTURE_BUFFER);
	if (ssh_channel_printf(channel, cmdline) == EXIT_FAILURE)
		goto error;

	if (read_output_bytes(channel, (int)strlen(cmdline), NULL) == EXIT_FAILURE)
		goto error;

	g_free(cmdline);
	return channel;
error:
	g_free(cmdline);
	g_warning("Error running ssh remote command");
	read_output_bytes(channel, -1, NULL);

	ssh_channel_close(channel);
	ssh_channel_free(channel);
	return NULL;
}
コード例 #25
0
ファイル: pkd_daemon.c プロジェクト: ShiftMediaProject/libssh
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;
}
コード例 #26
0
ファイル: ssh.c プロジェクト: isdrupter/busybotnet
/* 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);
}
コード例 #27
0
ファイル: ssh.c プロジェクト: caidongyun/ssh-proxy
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);

    }
}
コード例 #28
0
ファイル: mock-sshd.c プロジェクト: arilivigni/cockpit
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;
}
コード例 #29
0
int main(int argc, char **argv){
    ssh_session session;
    ssh_bind sshbind;
    ssh_message message;
    ssh_channel chan=0;
    char buf[2048];
    int auth=0;
    int shell=0;
    int i;
    int r;

    sshbind=ssh_bind_new();
    session=ssh_new();

    ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY,
                                            KEYS_FOLDER "ssh_host_dsa_key");
    ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY,
                                            KEYS_FOLDER "ssh_host_rsa_key");

#ifdef HAVE_ARGP_H
    /*
     * Parse our arguments; every option seen by parse_opt will
     * be reflected in arguments.
     */
    argp_parse (&argp, argc, argv, 0, 0, sshbind);
#else
    (void) argc;
    (void) argv;
#endif
#ifdef WITH_PCAP
    set_pcap(session);
#endif

    if(ssh_bind_listen(sshbind)<0){
        printf("Error listening to socket: %s\n", ssh_get_error(sshbind));
        return 1;
    }
    printf("Started sample libssh sshd on port %d\n", port);
    printf("You can login as the user %s with the password %s\n", SSHD_USER,
                                                            SSHD_PASSWORD);
    r = ssh_bind_accept(sshbind, session);
    if(r==SSH_ERROR){
      printf("Error accepting a connection: %s\n", ssh_get_error(sshbind));
      return 1;
    }
    if (ssh_handle_key_exchange(session)) {
        printf("ssh_handle_key_exchange: %s\n", ssh_get_error(session));
        return 1;
    }

    /* proceed to authentication */
    auth = authenticate(session);
    if (!auth || !authenticated) {
        printf("Authentication error: %s\n", ssh_get_error(session));
        ssh_disconnect(session);
        return 1;
    }


    /* wait for a channel session */
    do {
        message = ssh_message_get(session);
        if(message){
            if(ssh_message_type(message) == SSH_REQUEST_CHANNEL_OPEN &&
                    ssh_message_subtype(message) == SSH_CHANNEL_SESSION) {
                chan = ssh_message_channel_request_open_reply_accept(message);
                ssh_message_free(message);
                break;
            } else {
                ssh_message_reply_default(message);
                ssh_message_free(message);
            }
        } else {
            break;
        }
    } while(!chan);

    if(!chan) {
        printf("Error: cleint did not ask for a channel session (%s)\n",
                                                    ssh_get_error(session));
        ssh_finalize();
        return 1;
    }


    /* wait for a shell */
    do {
        message = ssh_message_get(session);
        if(message != NULL) {
            if(ssh_message_type(message) == SSH_REQUEST_CHANNEL &&
                    ssh_message_subtype(message) == SSH_CHANNEL_REQUEST_SHELL) {
                shell = 1;
                ssh_message_channel_request_reply_success(message);
                ssh_message_free(message);
                break;
            }
            ssh_message_reply_default(message);
            ssh_message_free(message);
        } else {
            break;
        }
    } while(!shell);

    if(!shell) {
        printf("Error: No shell requested (%s)\n", ssh_get_error(session));
        return 1;
    }


    printf("it works !\n");
    do{
        i=ssh_channel_read(chan,buf, 2048, 0);
        if(i>0) {
            if(*buf == '' || *buf == '')
                    break;
            if(i == 1 && *buf == '\r')
                ssh_channel_write(chan, "\r\n", 2);
            else
                ssh_channel_write(chan, buf, i);
            if (write(1,buf,i) < 0) {
                printf("error writing to buffer\n");
                return 1;
            }
        }
    } while (i>0);
    ssh_channel_close(chan);
    ssh_disconnect(session);
    ssh_bind_free(sshbind);
#ifdef WITH_PCAP
    cleanup_pcap();
#endif
    ssh_finalize();
    return 0;
}
コード例 #30
0
ファイル: samplesshd.c プロジェクト: FuckingCoder/libssh
int main(int argc, char **argv){
    ssh_session session;
    ssh_bind sshbind;
    ssh_message message;
    ssh_channel chan=0;
    char buf[2048];
    int auth=0;
    int sftp=0;
    int i;
    int r;

    sshbind=ssh_bind_new();
    session=ssh_new();

    ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, KEYS_FOLDER "ssh_host_dsa_key");
    ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, KEYS_FOLDER "ssh_host_rsa_key");

#ifdef HAVE_ARGP_H
    /*
     * Parse our arguments; every option seen by parse_opt will
     * be reflected in arguments.
     */
    argp_parse (&argp, argc, argv, 0, 0, sshbind);
#else
    (void) argc;
    (void) argv;
#endif
#ifdef WITH_PCAP
    set_pcap(session);
#endif

    if(ssh_bind_listen(sshbind)<0){
        printf("Error listening to socket: %s\n",ssh_get_error(sshbind));
        return 1;
    }
    r=ssh_bind_accept(sshbind,session);
    if(r==SSH_ERROR){
      printf("error accepting a connection : %s\n",ssh_get_error(sshbind));
      return 1;
    }
    if (ssh_handle_key_exchange(session)) {
        printf("ssh_handle_key_exchange: %s\n", ssh_get_error(session));
        return 1;
    }
    do {
        message=ssh_message_get(session);
        if(!message)
            break;
        switch(ssh_message_type(message)){
            case SSH_REQUEST_AUTH:
                switch(ssh_message_subtype(message)){
                    case SSH_AUTH_METHOD_PASSWORD:
                        printf("User %s wants to auth with pass %s\n",
                               ssh_message_auth_user(message),
                               ssh_message_auth_password(message));
                        if(auth_password(ssh_message_auth_user(message),
                           ssh_message_auth_password(message))){
                               auth=1;
                               ssh_message_auth_reply_success(message,0);
                               break;
                           }
                        // not authenticated, send default message
                    case SSH_AUTH_METHOD_NONE:
                    default:
                        ssh_message_auth_set_methods(message,SSH_AUTH_METHOD_PASSWORD);
                        ssh_message_reply_default(message);
                        break;
                }
                break;
            default:
                ssh_message_reply_default(message);
        }
        ssh_message_free(message);
    } while (!auth);
    if(!auth){
        printf("auth error: %s\n",ssh_get_error(session));
        ssh_disconnect(session);
        return 1;
    }
    do {
        message=ssh_message_get(session);
        if(message){
            switch(ssh_message_type(message)){
                case SSH_REQUEST_CHANNEL_OPEN:
                    if(ssh_message_subtype(message)==SSH_CHANNEL_SESSION){
                        chan=ssh_message_channel_request_open_reply_accept(message);
                        break;
                    }
                default:
                ssh_message_reply_default(message);
            }
            ssh_message_free(message);
        }
    } while(message && !chan);
    if(!chan){
        printf("error : %s\n",ssh_get_error(session));
        ssh_finalize();
        return 1;
    }
    do {
        message=ssh_message_get(session);
        if(message && ssh_message_type(message)==SSH_REQUEST_CHANNEL &&
           ssh_message_subtype(message)==SSH_CHANNEL_REQUEST_SHELL){
//            if(!strcmp(ssh_message_channel_request_subsystem(message),"sftp")){
                sftp=1;
                ssh_message_channel_request_reply_success(message);
                break;
 //           }
           }
        if(!sftp){
            ssh_message_reply_default(message);
        }
        ssh_message_free(message);
    } while (message && !sftp);
    if(!sftp){
        printf("error : %s\n",ssh_get_error(session));
        return 1;
    }
    printf("it works !\n");
    do{
        i=ssh_channel_read(chan,buf, 2048, 0);
        if(i>0) {
            ssh_channel_write(chan, buf, i);
            if (write(1,buf,i) < 0) {
                printf("error writing to buffer\n");
                return 1;
            }
        }
    } while (i>0);
    ssh_disconnect(session);
    ssh_bind_free(sshbind);
#ifdef WITH_PCAP
    cleanup_pcap();
#endif
    ssh_finalize();
    return 0;
}