Module: HrrRbSftp

Defined in:
lib/hrr_rb_sftp.rb,
lib/hrr_rb_sftp/sender.rb,
lib/hrr_rb_sftp/server.rb,
lib/hrr_rb_sftp/version.rb,
lib/hrr_rb_sftp/loggable.rb,
lib/hrr_rb_sftp/protocol.rb,
lib/hrr_rb_sftp/receiver.rb,
lib/hrr_rb_sftp/protocol/common.rb,
lib/hrr_rb_sftp/protocol/version1.rb,
lib/hrr_rb_sftp/protocol/version2.rb,
lib/hrr_rb_sftp/protocol/version3.rb,
lib/hrr_rb_sftp/protocol/common/packets.rb,
lib/hrr_rb_sftp/protocol/version1/packets.rb,
lib/hrr_rb_sftp/protocol/version2/packets.rb,
lib/hrr_rb_sftp/protocol/version3/packets.rb,
lib/hrr_rb_sftp/protocol/common/data_types.rb,
lib/hrr_rb_sftp/protocol/version1/data_types.rb,
lib/hrr_rb_sftp/protocol/version2/data_types.rb,
lib/hrr_rb_sftp/protocol/version3/data_types.rb,
lib/hrr_rb_sftp/protocol/version3/extensions.rb,
lib/hrr_rb_sftp/protocol/common/packets/packet.rb,
lib/hrr_rb_sftp/protocol/common/data_types/byte.rb,
lib/hrr_rb_sftp/protocol/version1/packets/packet.rb,
lib/hrr_rb_sftp/protocol/common/data_types/string.rb,
lib/hrr_rb_sftp/protocol/common/data_types/uint32.rb,
lib/hrr_rb_sftp/protocol/common/data_types/uint64.rb,
lib/hrr_rb_sftp/protocol/version1/data_types/attrs.rb,
lib/hrr_rb_sftp/protocol/version3/extensions/extension.rb,
lib/hrr_rb_sftp/protocol/common/packets/001_ssh_fxp_init.rb,
lib/hrr_rb_sftp/protocol/common/data_types/extension_pair.rb,
lib/hrr_rb_sftp/protocol/common/data_types/extension_pairs.rb,
lib/hrr_rb_sftp/protocol/version1/packets/003_ssh_fxp_open.rb,
lib/hrr_rb_sftp/protocol/version1/packets/005_ssh_fxp_read.rb,
lib/hrr_rb_sftp/protocol/version1/packets/017_ssh_fxp_stat.rb,
lib/hrr_rb_sftp/protocol/version1/packets/103_ssh_fxp_data.rb,
lib/hrr_rb_sftp/protocol/version1/packets/104_ssh_fxp_name.rb,
lib/hrr_rb_sftp/protocol/common/packets/002_ssh_fxp_version.rb,
lib/hrr_rb_sftp/protocol/version1/packets/004_ssh_fxp_close.rb,
lib/hrr_rb_sftp/protocol/version1/packets/006_ssh_fxp_write.rb,
lib/hrr_rb_sftp/protocol/version1/packets/007_ssh_fxp_lstat.rb,
lib/hrr_rb_sftp/protocol/version1/packets/008_ssh_fxp_fstat.rb,
lib/hrr_rb_sftp/protocol/version1/packets/014_ssh_fxp_mkdir.rb,
lib/hrr_rb_sftp/protocol/version1/packets/015_ssh_fxp_rmdir.rb,
lib/hrr_rb_sftp/protocol/version1/packets/105_ssh_fxp_attrs.rb,
lib/hrr_rb_sftp/protocol/version3/packets/014_ssh_fxp_mkdir.rb,
lib/hrr_rb_sftp/protocol/version1/packets/013_ssh_fxp_remove.rb,
lib/hrr_rb_sftp/protocol/version1/packets/101_ssh_fxp_status.rb,
lib/hrr_rb_sftp/protocol/version1/packets/102_ssh_fxp_handle.rb,
lib/hrr_rb_sftp/protocol/version2/packets/018_ssh_fxp_rename.rb,
lib/hrr_rb_sftp/protocol/version3/packets/101_ssh_fxp_status.rb,
lib/hrr_rb_sftp/protocol/version1/packets/009_ssh_fxp_setstat.rb,
lib/hrr_rb_sftp/protocol/version1/packets/011_ssh_fxp_opendir.rb,
lib/hrr_rb_sftp/protocol/version1/packets/012_ssh_fxp_readdir.rb,
lib/hrr_rb_sftp/protocol/version3/packets/020_ssh_fxp_symlink.rb,
lib/hrr_rb_sftp/protocol/version1/packets/010_ssh_fxp_fsetstat.rb,
lib/hrr_rb_sftp/protocol/version1/packets/016_ssh_fxp_realpath.rb,
lib/hrr_rb_sftp/protocol/version3/packets/019_ssh_fxp_readlink.rb,
lib/hrr_rb_sftp/protocol/version3/packets/200_ssh_fxp_extended.rb,
lib/hrr_rb_sftp/protocol/version3/extensions/fsync_at_openssh_com.rb,
lib/hrr_rb_sftp/protocol/version3/extensions/hardlink_at_openssh_com.rb,
lib/hrr_rb_sftp/protocol/version3/extensions/lsetstat_at_openssh_com.rb,
lib/hrr_rb_sftp/protocol/version3/packets/201_ssh_fxp_extended_reply.rb,
lib/hrr_rb_sftp/protocol/version3/extensions/posix_rename_at_openssh_com.rb

Overview

Note:
  • Reversal of SSH_FXP_SYMLINK arguments

    Because OpenSSH’s sftp-server implementation takes SSH_FXP_SYMLINK request linkpath and targetpath arguments in reverse order, this library follows it.

    The SSH_FXP_SYMLINK request format is as follows:

    uint32          id
    string          targetpath
    string          linkpath
    

hrr_rb_sftp is a pure Ruby SFTP server implementation. hrr_rb_sftp now supports SFTP protocol version 1, 2, and 3. hrr_rb_sftp can be run on SSH 2.0 server like OpenSSH or hrr_rb_ssh.

It is straightforward to implement SFTP server on SSH 2.0 server library written in Ruby like hrr_rb_ssh. There are two ways to work with hrr_rb_ssh, on same process or spawning child process. On both cases, hrr_rb_ssh’s request handler mechanism is used.

To run hrr_rb_sftp server on the same process that hrr_rb_ssh is running, instantiate and start the hrr_rb_sftp server in a sftp subsystem request. On the other hand, because the arguments for the hrr_rb_sftp server can be standard input, output, and error, so hrr_rb_sftp can be a independent program and be spawned as a child process.

OpenSSH has capability to run user-defined subsystems. Subsystems that the OpenSSH server recognizes are listed in /etc/ssh/sshd_config file. Usually SFTP subsystem is defined by default to use OpenSSH’s SFTP server implementation. hrr_rb_sftp can be an alternative with replacing the line in the config file. (After editing the config, reloading or restarting sshd is required.)

The following extensions are supported.

- [email protected]
- [email protected]
- [email protected]
- [email protected]

Examples:

On the same process that hrr_rb_ssh is running

subsys = HrrRbSsh::Connection::RequestHandler.new { |ctx|
  ctx.chain_proc { |chain|
    case ctx.subsystem_name
    when 'sftp'
      begin
        sftp_server = HrrRbSftp::Server.new(logger: nil)
        sftp_server.start(ctx.io[0], ctx.io[1], ctx.io[2])
        exitstatus = 0
      rescue
        exitstatus = 1
      end
    else
      # Do something for other subsystem, or just return exitstatus
      exitstatus = 0
    end
    exitstatus
  }
}
options['connection_channel_request_subsystem']  = subsys

Spawnning SFTP server process

subsys = HrrRbSsh::Connection::RequestHandler.new { |ctx|
  ctx.chain_proc { |chain|
    case ctx.subsystem_name
    when 'sftp'
      pid = spawn("/path/to/hrr_rb_sftp_server.rb", {in: ctx.io[0], out: ctx.io[1], err: ctx.io[2]})
      exitstatus = Process.waitpid(pid).to_i
    else
      # Do something for other subsystem, or just return exitstatus
      exitstatus = 0
    end
    exitstatus
  }
}
options['connection_channel_request_subsystem']  = subsys

hrr_rb_sftp_server.rb

#!/usr/bin/env ruby
require "hrr_rb_sftp"
server = HrrRbSftp::Server.new(logger: nil)
server.start($stdin, $stdout, $stderr)

Replacing OpenSSH’s sftp-server

$ cat /etc/ssh/sshd_config | grep Subsystem
#Subsystem  sftp    /usr/lib/openssh/sftp-server    # Comment out the original line
Subsystem   sftp    /path/to/hrr_rb_sftp_server.rb

Defined Under Namespace

Modules: Loggable Classes: Protocol, Receiver, Sender, Server

Constant Summary collapse

VERSION =

hrr_rb_sftp library version.

"0.2.0"