Class: RubySMB::Server

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby_smb/server.rb,
lib/ruby_smb/server/share.rb,
lib/ruby_smb/server/session.rb,
lib/ruby_smb/server/server_client.rb,
lib/ruby_smb/server/share/provider.rb,
lib/ruby_smb/server/share/provider/disk.rb,
lib/ruby_smb/server/share/provider/pipe.rb,
lib/ruby_smb/server/server_client/share_io.rb,
lib/ruby_smb/server/server_client/encryption.rb,
lib/ruby_smb/server/share/provider/processor.rb,
lib/ruby_smb/server/server_client/negotiation.rb,
lib/ruby_smb/server/server_client/tree_connect.rb,
lib/ruby_smb/server/server_client/session_setup.rb,
lib/ruby_smb/server/share/provider/virtual_disk.rb,
lib/ruby_smb/server/share/provider/disk/processor.rb,
lib/ruby_smb/server/share/provider/disk/file_system.rb,
lib/ruby_smb/server/share/provider/disk/processor/read.rb,
lib/ruby_smb/server/share/provider/disk/processor/close.rb,
lib/ruby_smb/server/share/provider/disk/processor/query.rb,
lib/ruby_smb/server/share/provider/disk/processor/create.rb,
lib/ruby_smb/server/share/provider/virtual_disk/virtual_file.rb,
lib/ruby_smb/server/share/provider/virtual_disk/virtual_stat.rb,
lib/ruby_smb/server/share/provider/virtual_disk/virtual_pathname.rb

Overview

This class provides the SMB server core. Settings that are relevant server wide are managed by this object. Currently, the server only supports negotiating and authenticating requests. No other server functionality is available at this time. The negotiating and authentication is supported for SMB versions 1 through 3.1.1.

Defined Under Namespace

Modules: Share Classes: Connection, ServerClient, Session

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(server_sock: nil, gss_provider: nil, logger: nil, thread_factory: nil) ⇒ Server

Returns a new instance of Server.

Parameters:

  • server_sock (defaults to: nil)

    the socket on which the server should listen

  • gss_provider (Gss::Provider) (defaults to: nil)

    the authentication provider

  • logger (::Logger) (defaults to: nil)

    the logger to use for diagnostic messages

  • thread_factory (defaults to: nil)

    a block to create threads for serving clients



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/ruby_smb/server.rb', line 20

def initialize(server_sock: nil, gss_provider: nil, logger: nil, thread_factory: nil)
  server_sock = ::TCPServer.new(445) if server_sock.nil?

  @guid = Random.new.bytes(16)
  @socket = server_sock
  @connections = []
  @gss_provider = gss_provider || Gss::Provider::NTLM.new
  # reject the wildcard dialect because it's not a real dialect we can use for this purpose
  @dialects = RubySMB::Dialect::ALL.keys.reject { |dialect| dialect == "0x%04x" % RubySMB::SMB2::SMB2_WILDCARD_REVISION }.reverse

  case logger
  when nil
    @logger = Logger.new(File.open(File::NULL, 'w'))
  when :stdout
    @logger = Logger.new(STDOUT)
  when :stderr
    @logger = Logger.new(STDERR)
  else
    @logger = logger
  end

  if thread_factory.nil?
    # the default thread factory uses Ruby's standard Thread#new
    thread_factory = Proc.new do |_server_client, &block|
      Thread.new(&block)
    end
  end
  @thread_factory = thread_factory

  # share name => provider instance
  @shares = {
    'IPC$' => Share::Provider::IpcPipe.new
  }
end

Instance Attribute Details

#dialectsArray<String>

Returns:

  • (Array<String>)


75
76
77
# File 'lib/ruby_smb/server.rb', line 75

def dialects
  @dialects
end

#gss_providerObject (readonly)

The GSS Provider instance that this server will use to authenticate incoming client connections.



81
82
83
# File 'lib/ruby_smb/server.rb', line 81

def gss_provider
  @gss_provider
end

#guidObject (readonly)

The 16 byte GUID that uniquely identifies this server instance.



85
86
87
# File 'lib/ruby_smb/server.rb', line 85

def guid
  @guid
end

#loggerObject (readonly)

The logger instance to use for diagnostic messages.



89
90
91
# File 'lib/ruby_smb/server.rb', line 89

def logger
  @logger
end

#sharesObject (readonly)

The shares that are provided by this server



93
94
95
# File 'lib/ruby_smb/server.rb', line 93

def shares
  @shares
end

Instance Method Details

#add_share(share_provider) ⇒ Object



55
56
57
58
# File 'lib/ruby_smb/server.rb', line 55

def add_share(share_provider)
  logger.debug("Adding #{share_provider.type} share: #{share_provider.name}")
  @shares[share_provider.name] = share_provider
end

#run(&block) ⇒ Object

Run the server and accept any connections. For each connection, the block will be executed if specified. When the block returns false, the loop will exit and the server will no long accept new connections.



62
63
64
65
66
67
68
69
70
# File 'lib/ruby_smb/server.rb', line 62

def run(&block)
  loop do
    sock = @socket.accept
    server_client = ServerClient.new(self, RubySMB::Dispatcher::Socket.new(sock, read_timeout: nil))
    @connections << Connection.new(server_client, @thread_factory.call(server_client) { server_client.run })

    break unless block.nil? || block.call(server_client)
  end
end