Class: SSLScan::Socket::SwitchBoard

Inherits:
Object
  • Object
show all
Includes:
Enumerable, Singleton
Defined in:
lib/ssl_scan/socket/switch_board.rb

Overview

This class provides a global routing table that associates subnets with Comm classes. Comm classes are used to instantiate objects that are tied to remote network entities. For example, the Local Comm class is used to building network connections directly from the local machine whereas, for instance, a Meterpreter Comm would build a local socket pair that is associated with a connection established by a remote entity. This can be seen as a uniform way of communicating with hosts through arbitrary channels.

Defined Under Namespace

Classes: Route

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeSwitchBoard

Returns a new instance of SwitchBoard.



25
26
27
# File 'lib/ssl_scan/socket/switch_board.rb', line 25

def initialize
  @_initialized = false
end

Instance Attribute Details

#mutexObject

The mutex protecting the routes array.



268
269
270
# File 'lib/ssl_scan/socket/switch_board.rb', line 268

def mutex
  @mutex
end

#routesObject

The routes array.



264
265
266
# File 'lib/ssl_scan/socket/switch_board.rb', line 264

def routes
  @routes
end

Class Method Details

.add_route(subnet, mask, comm) ⇒ Object

Adds a route to the switch board routing table using the supplied Comm instance.



76
77
78
79
80
81
82
# File 'lib/ssl_scan/socket/switch_board.rb', line 76

def self.add_route(subnet, mask, comm)
  ret = self.instance.add_route(subnet, mask, comm)
  if ret && comm.respond_to?(:routes) && comm.routes.kind_of?(Array)
    comm.routes << "#{subnet}/#{mask}"
  end
  ret
end

.best_comm(addr) ⇒ Object

Returns the Comm instance that should be used for the supplied address. If no comm can be found, the default Local Comm is returned.



125
126
127
# File 'lib/ssl_scan/socket/switch_board.rb', line 125

def self.best_comm(addr)
  self.instance.best_comm(addr)
end

.each(&block) ⇒ Object

Enumerate each route in the routing table.



106
107
108
# File 'lib/ssl_scan/socket/switch_board.rb', line 106

def self.each(&block)
  self.instance.each(&block)
end

.flush_routesObject

Flush all the routes from the switch board routing table.



99
100
101
# File 'lib/ssl_scan/socket/switch_board.rb', line 99

def self.flush_routes
  ret = self.instance.flush_routes
end

.remove_by_comm(comm) ⇒ Object

Removes all routes that go through the supplied Comm.



132
133
134
# File 'lib/ssl_scan/socket/switch_board.rb', line 132

def self.remove_by_comm(comm)
  self.instance.remove_by_comm(comm)
end

.remove_route(subnet, mask, comm) ⇒ Object

Removes a route from the switch board routing table for the supplied subnet routing through the supplied Comm instance.



88
89
90
91
92
93
94
# File 'lib/ssl_scan/socket/switch_board.rb', line 88

def self.remove_route(subnet, mask, comm)
  ret = self.instance.remove_route(subnet, mask, comm)
  if ret && comm.respond_to?(:routes) && comm.routes.kind_of?(Array)
    comm.routes.delete "#{subnet}/#{mask}"
  end
  ret
end

.route_exists?(subnet, mask) ⇒ Boolean

Returns:

  • (Boolean)


117
118
119
# File 'lib/ssl_scan/socket/switch_board.rb', line 117

def self.route_exists?(subnet, mask)
  self.instance.route_exists?(subnet, mask)
end

.routesObject

Returns the array of routes.



113
114
115
# File 'lib/ssl_scan/socket/switch_board.rb', line 113

def self.routes
  self.instance.routes
end

Instance Method Details

#add_route(subnet, mask, comm) ⇒ Object

Adds a route for a given subnet and netmask destined through a given comm instance.



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/ssl_scan/socket/switch_board.rb', line 146

def add_route(subnet, mask, comm)
  # If a bitmask was supplied, convert it.
  netmask = (mask.to_s =~ /^\d+$/) ? Rex::Socket.bit2netmask(mask.to_i) : mask
  rv      = true

  _init

  mutex.synchronize {
    # If the route already exists, return false to the caller.
    if (route_exists?(subnet, netmask) == false)
      self.routes << Route.new(subnet, netmask, comm)
    else
      rv = false
    end
  }

  rv
end

#best_comm(addr) ⇒ Object

Finds the best possible comm for the supplied target address.



230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/ssl_scan/socket/switch_board.rb', line 230

def best_comm(addr)

  addr_nbo = Socket.resolv_nbo_i(addr)
  comm     = nil
  msb      = 0

  each { |route|
    if ((route.subnet_nbo & route.netmask_nbo) ==
        (addr_nbo & route.netmask_nbo))
      if (route.bitmask >= msb)
        comm = route.comm
        msb  = route.bitmask
      end
    end
  }

  comm
end

#each(&block) ⇒ Object

Enumerates each entry in the routing table.



221
222
223
224
225
# File 'lib/ssl_scan/socket/switch_board.rb', line 221

def each(&block)
  _init

  routes.each(&block)
end

#flush_routesObject

Flushes all established routes.



192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/ssl_scan/socket/switch_board.rb', line 192

def flush_routes
  _init

  # Remove each of the individual routes so the comms don't think they're
  # still routing after a flush.
  self.routes.each { |r|
    if r.comm.respond_to? :routes
      r.comm.routes.delete("#{r.subnet}/#{r.netmask}")
    end
  }
  # Re-initialize to an empty array
  self.routes = Array.new
end

#remove_by_comm(comm) ⇒ Object

Remove all routes that go through the supplied comm.



252
253
254
255
256
257
258
259
# File 'lib/ssl_scan/socket/switch_board.rb', line 252

def remove_by_comm(comm)
  _init
  mutex.synchronize {
    routes.delete_if { |route|
      route.comm == comm
    }
  }
end

#remove_route(subnet, mask, comm) ⇒ Object

Removes a route for a given subnet and netmask destined through a given comm instance.



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/ssl_scan/socket/switch_board.rb', line 169

def remove_route(subnet, mask, comm)
  # If a bitmask was supplied, convert it.
  netmask = (mask.to_s =~ /^\d+$/) ? Rex::Socket.bit2netmask(mask.to_i) : mask
  rv      = false

  _init

  mutex.synchronize {
    self.routes.delete_if { |route|
      if (route.subnet == subnet and route.netmask == netmask and route.comm == comm)
        rv = true
      else
        false
      end
    }
  }

  rv
end

#route_exists?(subnet, netmask) ⇒ Boolean

Checks to see if a route already exists for the supplied subnet and netmask.

Returns:

  • (Boolean)


210
211
212
213
214
215
216
# File 'lib/ssl_scan/socket/switch_board.rb', line 210

def route_exists?(subnet, netmask)
  each { |route|
    return true if (route.subnet == subnet and route.netmask == netmask)
  }

  false
end