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/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

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) ⇒ Server

Returns a new instance of Server.

Parameters:

  • server_sock (defaults to: nil)

    the socket on which the server should listen

  • the (Gss::Provider)

    authentication provider



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/ruby_smb/server.rb', line 18

def initialize(server_sock: nil, gss_provider: nil, logger: 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

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

Instance Attribute Details

#dialectsArray<String>

Returns:

  • (Array<String>)


65
66
67
# File 'lib/ruby_smb/server.rb', line 65

def dialects
  @dialects
end

#gss_providerObject (readonly)

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



71
72
73
# File 'lib/ruby_smb/server.rb', line 71

def gss_provider
  @gss_provider
end

#guidObject (readonly)

The 16 byte GUID that uniquely identifies this server instance.



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

def guid
  @guid
end

#loggerObject (readonly)

The logger instance to use for diagnostic messages.



79
80
81
# File 'lib/ruby_smb/server.rb', line 79

def logger
  @logger
end

#sharesObject (readonly)

The shares that are provided by this server



83
84
85
# File 'lib/ruby_smb/server.rb', line 83

def shares
  @shares
end

Instance Method Details

#add_share(share_provider) ⇒ Object



45
46
47
48
# File 'lib/ruby_smb/server.rb', line 45

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.



52
53
54
55
56
57
58
59
60
# File 'lib/ruby_smb/server.rb', line 52

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.new { server_client.run })

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