ssl_scan 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
 - data/.gitignore +17 -0
 - data/Gemfile +4 -0
 - data/LICENSE.txt +22 -0
 - data/README.md +51 -0
 - data/Rakefile +1 -0
 - data/bin/ssl_scan +4 -0
 - data/lib/ssl_scan/client.rb +0 -0
 - data/lib/ssl_scan/compat.rb +388 -0
 - data/lib/ssl_scan/exceptions.rb +274 -0
 - data/lib/ssl_scan/io/bidirectional_pipe.rb +161 -0
 - data/lib/ssl_scan/io/datagram_abstraction.rb +35 -0
 - data/lib/ssl_scan/io/ring_buffer.rb +369 -0
 - data/lib/ssl_scan/io/stream.rb +312 -0
 - data/lib/ssl_scan/io/stream_abstraction.rb +209 -0
 - data/lib/ssl_scan/io/stream_server.rb +221 -0
 - data/lib/ssl_scan/result.rb +165 -0
 - data/lib/ssl_scan/scanner.rb +241 -0
 - data/lib/ssl_scan/socket/comm/local.rb +526 -0
 - data/lib/ssl_scan/socket/comm.rb +120 -0
 - data/lib/ssl_scan/socket/ip.rb +131 -0
 - data/lib/ssl_scan/socket/parameters.rb +363 -0
 - data/lib/ssl_scan/socket/range_walker.rb +470 -0
 - data/lib/ssl_scan/socket/ssl_tcp.rb +345 -0
 - data/lib/ssl_scan/socket/ssl_tcp_server.rb +188 -0
 - data/lib/ssl_scan/socket/subnet_walker.rb +76 -0
 - data/lib/ssl_scan/socket/switch_board.rb +289 -0
 - data/lib/ssl_scan/socket/tcp.rb +79 -0
 - data/lib/ssl_scan/socket/tcp_server.rb +67 -0
 - data/lib/ssl_scan/socket/udp.rb +165 -0
 - data/lib/ssl_scan/socket.rb +773 -0
 - data/lib/ssl_scan/sync/thread_safe.rb +83 -0
 - data/lib/ssl_scan/version.rb +9 -0
 - data/lib/ssl_scan.rb +11 -0
 - data/sslscan.gemspec +23 -0
 - metadata +107 -0
 
| 
         @@ -0,0 +1,289 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # -*- coding: binary -*-
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'singleton'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'thread'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'ssl_scan/socket'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            module SSLScan
         
     | 
| 
      
 7 
     | 
    
         
            +
            module Socket
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            ###
         
     | 
| 
      
 10 
     | 
    
         
            +
            #
         
     | 
| 
      
 11 
     | 
    
         
            +
            # This class provides a global routing table that associates subnets with Comm
         
     | 
| 
      
 12 
     | 
    
         
            +
            # classes.  Comm classes are used to instantiate objects that are tied to
         
     | 
| 
      
 13 
     | 
    
         
            +
            # remote network entities.  For example, the Local Comm class is used to
         
     | 
| 
      
 14 
     | 
    
         
            +
            # building network connections directly from the local machine whereas, for
         
     | 
| 
      
 15 
     | 
    
         
            +
            # instance, a Meterpreter Comm would build a local socket pair that is
         
     | 
| 
      
 16 
     | 
    
         
            +
            # associated with a connection established by a remote entity.  This can be
         
     | 
| 
      
 17 
     | 
    
         
            +
            # seen as a uniform way of communicating with hosts through arbitrary
         
     | 
| 
      
 18 
     | 
    
         
            +
            # channels.
         
     | 
| 
      
 19 
     | 
    
         
            +
            #
         
     | 
| 
      
 20 
     | 
    
         
            +
            ###
         
     | 
| 
      
 21 
     | 
    
         
            +
            class SwitchBoard
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
              include Singleton
         
     | 
| 
      
 24 
     | 
    
         
            +
              include Enumerable
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              def initialize
         
     | 
| 
      
 27 
     | 
    
         
            +
                @_initialized = false
         
     | 
| 
      
 28 
     | 
    
         
            +
              end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
              ###
         
     | 
| 
      
 31 
     | 
    
         
            +
              #
         
     | 
| 
      
 32 
     | 
    
         
            +
              # This class represents a logical switch board route.
         
     | 
| 
      
 33 
     | 
    
         
            +
              # TODO: Enable this to work with IPv6 addresses
         
     | 
| 
      
 34 
     | 
    
         
            +
              #
         
     | 
| 
      
 35 
     | 
    
         
            +
              ###
         
     | 
| 
      
 36 
     | 
    
         
            +
              class Route
         
     | 
| 
      
 37 
     | 
    
         
            +
                def initialize(subnet, netmask, comm)
         
     | 
| 
      
 38 
     | 
    
         
            +
                  self.subnet      = subnet
         
     | 
| 
      
 39 
     | 
    
         
            +
                  self.netmask     = netmask
         
     | 
| 
      
 40 
     | 
    
         
            +
                  self.comm        = comm
         
     | 
| 
      
 41 
     | 
    
         
            +
                  self.subnet_nbo  = Socket.resolv_nbo_i(subnet)
         
     | 
| 
      
 42 
     | 
    
         
            +
                  self.netmask_nbo = Socket.resolv_nbo_i(netmask)
         
     | 
| 
      
 43 
     | 
    
         
            +
                end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                #
         
     | 
| 
      
 46 
     | 
    
         
            +
                # Sort according to bitmask
         
     | 
| 
      
 47 
     | 
    
         
            +
                #
         
     | 
| 
      
 48 
     | 
    
         
            +
                def <=>(other)
         
     | 
| 
      
 49 
     | 
    
         
            +
                  self.bitmask <=> other.bitmask
         
     | 
| 
      
 50 
     | 
    
         
            +
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                #
         
     | 
| 
      
 53 
     | 
    
         
            +
                # Convert the netmask to a bitmask and cache it.
         
     | 
| 
      
 54 
     | 
    
         
            +
                #
         
     | 
| 
      
 55 
     | 
    
         
            +
                def bitmask
         
     | 
| 
      
 56 
     | 
    
         
            +
                  @_bitmask = Socket.net2bitmask(self.netmask) if (@_bitmask == nil)
         
     | 
| 
      
 57 
     | 
    
         
            +
                  @_bitmask
         
     | 
| 
      
 58 
     | 
    
         
            +
                end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                attr_reader :subnet, :netmask, :comm
         
     | 
| 
      
 61 
     | 
    
         
            +
                attr_reader :subnet_nbo, :netmask_nbo
         
     | 
| 
      
 62 
     | 
    
         
            +
              protected
         
     | 
| 
      
 63 
     | 
    
         
            +
                attr_writer :subnet, :netmask, :comm
         
     | 
| 
      
 64 
     | 
    
         
            +
                attr_writer :subnet_nbo, :netmask_nbo
         
     | 
| 
      
 65 
     | 
    
         
            +
              end
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
              ##
         
     | 
| 
      
 68 
     | 
    
         
            +
              #
         
     | 
| 
      
 69 
     | 
    
         
            +
              # Class method wrappers
         
     | 
| 
      
 70 
     | 
    
         
            +
              #
         
     | 
| 
      
 71 
     | 
    
         
            +
              ##
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
              #
         
     | 
| 
      
 74 
     | 
    
         
            +
              # Adds a route to the switch board routing table using the supplied Comm
         
     | 
| 
      
 75 
     | 
    
         
            +
              # instance.
         
     | 
| 
      
 76 
     | 
    
         
            +
              #
         
     | 
| 
      
 77 
     | 
    
         
            +
              def self.add_route(subnet, mask, comm)
         
     | 
| 
      
 78 
     | 
    
         
            +
                ret = self.instance.add_route(subnet, mask, comm)
         
     | 
| 
      
 79 
     | 
    
         
            +
                if ret && comm.respond_to?(:routes) && comm.routes.kind_of?(Array)
         
     | 
| 
      
 80 
     | 
    
         
            +
                  comm.routes << "#{subnet}/#{mask}"
         
     | 
| 
      
 81 
     | 
    
         
            +
                end
         
     | 
| 
      
 82 
     | 
    
         
            +
                ret
         
     | 
| 
      
 83 
     | 
    
         
            +
              end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
              #
         
     | 
| 
      
 86 
     | 
    
         
            +
              # Removes a route from the switch board routing table for the supplied
         
     | 
| 
      
 87 
     | 
    
         
            +
              # subnet routing through the supplied Comm instance.
         
     | 
| 
      
 88 
     | 
    
         
            +
              #
         
     | 
| 
      
 89 
     | 
    
         
            +
              def self.remove_route(subnet, mask, comm)
         
     | 
| 
      
 90 
     | 
    
         
            +
                ret = self.instance.remove_route(subnet, mask, comm)
         
     | 
| 
      
 91 
     | 
    
         
            +
                if ret && comm.respond_to?(:routes) && comm.routes.kind_of?(Array)
         
     | 
| 
      
 92 
     | 
    
         
            +
                  comm.routes.delete "#{subnet}/#{mask}"
         
     | 
| 
      
 93 
     | 
    
         
            +
                end
         
     | 
| 
      
 94 
     | 
    
         
            +
                ret
         
     | 
| 
      
 95 
     | 
    
         
            +
              end
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
              #
         
     | 
| 
      
 98 
     | 
    
         
            +
              # Flush all the routes from the switch board routing table.
         
     | 
| 
      
 99 
     | 
    
         
            +
              #
         
     | 
| 
      
 100 
     | 
    
         
            +
              def self.flush_routes
         
     | 
| 
      
 101 
     | 
    
         
            +
                ret = self.instance.flush_routes
         
     | 
| 
      
 102 
     | 
    
         
            +
              end
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
              #
         
     | 
| 
      
 105 
     | 
    
         
            +
              # Enumerate each route in the routing table.
         
     | 
| 
      
 106 
     | 
    
         
            +
              #
         
     | 
| 
      
 107 
     | 
    
         
            +
              def self.each(&block)
         
     | 
| 
      
 108 
     | 
    
         
            +
                self.instance.each(&block)
         
     | 
| 
      
 109 
     | 
    
         
            +
              end
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
              #
         
     | 
| 
      
 112 
     | 
    
         
            +
              # Returns the array of routes.
         
     | 
| 
      
 113 
     | 
    
         
            +
              #
         
     | 
| 
      
 114 
     | 
    
         
            +
              def self.routes
         
     | 
| 
      
 115 
     | 
    
         
            +
                self.instance.routes
         
     | 
| 
      
 116 
     | 
    
         
            +
              end
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
              def self.route_exists?(subnet, mask)
         
     | 
| 
      
 119 
     | 
    
         
            +
                self.instance.route_exists?(subnet, mask)
         
     | 
| 
      
 120 
     | 
    
         
            +
              end
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
              #
         
     | 
| 
      
 123 
     | 
    
         
            +
              # Returns the Comm instance that should be used for the supplied address.
         
     | 
| 
      
 124 
     | 
    
         
            +
              # If no comm can be found, the default Local Comm is returned.
         
     | 
| 
      
 125 
     | 
    
         
            +
              #
         
     | 
| 
      
 126 
     | 
    
         
            +
              def self.best_comm(addr)
         
     | 
| 
      
 127 
     | 
    
         
            +
                self.instance.best_comm(addr)
         
     | 
| 
      
 128 
     | 
    
         
            +
              end
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
              #
         
     | 
| 
      
 131 
     | 
    
         
            +
              # Removes all routes that go through the supplied Comm.
         
     | 
| 
      
 132 
     | 
    
         
            +
              #
         
     | 
| 
      
 133 
     | 
    
         
            +
              def self.remove_by_comm(comm)
         
     | 
| 
      
 134 
     | 
    
         
            +
                self.instance.remove_by_comm(comm)
         
     | 
| 
      
 135 
     | 
    
         
            +
              end
         
     | 
| 
      
 136 
     | 
    
         
            +
             
     | 
| 
      
 137 
     | 
    
         
            +
              ##
         
     | 
| 
      
 138 
     | 
    
         
            +
              #
         
     | 
| 
      
 139 
     | 
    
         
            +
              # Instance methods
         
     | 
| 
      
 140 
     | 
    
         
            +
              #
         
     | 
| 
      
 141 
     | 
    
         
            +
              ##
         
     | 
| 
      
 142 
     | 
    
         
            +
             
     | 
| 
      
 143 
     | 
    
         
            +
              #
         
     | 
| 
      
 144 
     | 
    
         
            +
              # Adds a route for a given subnet and netmask destined through a given comm
         
     | 
| 
      
 145 
     | 
    
         
            +
              # instance.
         
     | 
| 
      
 146 
     | 
    
         
            +
              #
         
     | 
| 
      
 147 
     | 
    
         
            +
              def add_route(subnet, mask, comm)
         
     | 
| 
      
 148 
     | 
    
         
            +
                # If a bitmask was supplied, convert it.
         
     | 
| 
      
 149 
     | 
    
         
            +
                netmask = (mask.to_s =~ /^\d+$/) ? Rex::Socket.bit2netmask(mask.to_i) : mask
         
     | 
| 
      
 150 
     | 
    
         
            +
                rv      = true
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
                _init
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
                mutex.synchronize {
         
     | 
| 
      
 155 
     | 
    
         
            +
                  # If the route already exists, return false to the caller.
         
     | 
| 
      
 156 
     | 
    
         
            +
                  if (route_exists?(subnet, netmask) == false)
         
     | 
| 
      
 157 
     | 
    
         
            +
                    self.routes << Route.new(subnet, netmask, comm)
         
     | 
| 
      
 158 
     | 
    
         
            +
                  else
         
     | 
| 
      
 159 
     | 
    
         
            +
                    rv = false
         
     | 
| 
      
 160 
     | 
    
         
            +
                  end
         
     | 
| 
      
 161 
     | 
    
         
            +
                }
         
     | 
| 
      
 162 
     | 
    
         
            +
             
     | 
| 
      
 163 
     | 
    
         
            +
                rv
         
     | 
| 
      
 164 
     | 
    
         
            +
              end
         
     | 
| 
      
 165 
     | 
    
         
            +
             
     | 
| 
      
 166 
     | 
    
         
            +
              #
         
     | 
| 
      
 167 
     | 
    
         
            +
              # Removes a route for a given subnet and netmask destined through a given
         
     | 
| 
      
 168 
     | 
    
         
            +
              # comm instance.
         
     | 
| 
      
 169 
     | 
    
         
            +
              #
         
     | 
| 
      
 170 
     | 
    
         
            +
              def remove_route(subnet, mask, comm)
         
     | 
| 
      
 171 
     | 
    
         
            +
                # If a bitmask was supplied, convert it.
         
     | 
| 
      
 172 
     | 
    
         
            +
                netmask = (mask.to_s =~ /^\d+$/) ? Rex::Socket.bit2netmask(mask.to_i) : mask
         
     | 
| 
      
 173 
     | 
    
         
            +
                rv      = false
         
     | 
| 
      
 174 
     | 
    
         
            +
             
     | 
| 
      
 175 
     | 
    
         
            +
                _init
         
     | 
| 
      
 176 
     | 
    
         
            +
             
     | 
| 
      
 177 
     | 
    
         
            +
                mutex.synchronize {
         
     | 
| 
      
 178 
     | 
    
         
            +
                  self.routes.delete_if { |route|
         
     | 
| 
      
 179 
     | 
    
         
            +
                    if (route.subnet == subnet and route.netmask == netmask and route.comm == comm)
         
     | 
| 
      
 180 
     | 
    
         
            +
                      rv = true
         
     | 
| 
      
 181 
     | 
    
         
            +
                    else
         
     | 
| 
      
 182 
     | 
    
         
            +
                      false
         
     | 
| 
      
 183 
     | 
    
         
            +
                    end
         
     | 
| 
      
 184 
     | 
    
         
            +
                  }
         
     | 
| 
      
 185 
     | 
    
         
            +
                }
         
     | 
| 
      
 186 
     | 
    
         
            +
             
     | 
| 
      
 187 
     | 
    
         
            +
                rv
         
     | 
| 
      
 188 
     | 
    
         
            +
              end
         
     | 
| 
      
 189 
     | 
    
         
            +
             
     | 
| 
      
 190 
     | 
    
         
            +
              #
         
     | 
| 
      
 191 
     | 
    
         
            +
              # Flushes all established routes.
         
     | 
| 
      
 192 
     | 
    
         
            +
              #
         
     | 
| 
      
 193 
     | 
    
         
            +
              def flush_routes
         
     | 
| 
      
 194 
     | 
    
         
            +
                _init
         
     | 
| 
      
 195 
     | 
    
         
            +
             
     | 
| 
      
 196 
     | 
    
         
            +
                # Remove each of the individual routes so the comms don't think they're
         
     | 
| 
      
 197 
     | 
    
         
            +
                # still routing after a flush.
         
     | 
| 
      
 198 
     | 
    
         
            +
                self.routes.each { |r|
         
     | 
| 
      
 199 
     | 
    
         
            +
                  if r.comm.respond_to? :routes
         
     | 
| 
      
 200 
     | 
    
         
            +
                    r.comm.routes.delete("#{r.subnet}/#{r.netmask}")
         
     | 
| 
      
 201 
     | 
    
         
            +
                  end
         
     | 
| 
      
 202 
     | 
    
         
            +
                }
         
     | 
| 
      
 203 
     | 
    
         
            +
                # Re-initialize to an empty array
         
     | 
| 
      
 204 
     | 
    
         
            +
                self.routes = Array.new
         
     | 
| 
      
 205 
     | 
    
         
            +
              end
         
     | 
| 
      
 206 
     | 
    
         
            +
             
     | 
| 
      
 207 
     | 
    
         
            +
              #
         
     | 
| 
      
 208 
     | 
    
         
            +
              # Checks to see if a route already exists for the supplied subnet and
         
     | 
| 
      
 209 
     | 
    
         
            +
              # netmask.
         
     | 
| 
      
 210 
     | 
    
         
            +
              #
         
     | 
| 
      
 211 
     | 
    
         
            +
              def route_exists?(subnet, netmask)
         
     | 
| 
      
 212 
     | 
    
         
            +
                each { |route|
         
     | 
| 
      
 213 
     | 
    
         
            +
                  return true if (route.subnet == subnet and route.netmask == netmask)
         
     | 
| 
      
 214 
     | 
    
         
            +
                }
         
     | 
| 
      
 215 
     | 
    
         
            +
             
     | 
| 
      
 216 
     | 
    
         
            +
                false
         
     | 
| 
      
 217 
     | 
    
         
            +
              end
         
     | 
| 
      
 218 
     | 
    
         
            +
             
     | 
| 
      
 219 
     | 
    
         
            +
              #
         
     | 
| 
      
 220 
     | 
    
         
            +
              # Enumerates each entry in the routing table.
         
     | 
| 
      
 221 
     | 
    
         
            +
              #
         
     | 
| 
      
 222 
     | 
    
         
            +
              def each(&block)
         
     | 
| 
      
 223 
     | 
    
         
            +
                _init
         
     | 
| 
      
 224 
     | 
    
         
            +
             
     | 
| 
      
 225 
     | 
    
         
            +
                routes.each(&block)
         
     | 
| 
      
 226 
     | 
    
         
            +
              end
         
     | 
| 
      
 227 
     | 
    
         
            +
             
     | 
| 
      
 228 
     | 
    
         
            +
              #
         
     | 
| 
      
 229 
     | 
    
         
            +
              # Finds the best possible comm for the supplied target address.
         
     | 
| 
      
 230 
     | 
    
         
            +
              #
         
     | 
| 
      
 231 
     | 
    
         
            +
              def best_comm(addr)
         
     | 
| 
      
 232 
     | 
    
         
            +
             
     | 
| 
      
 233 
     | 
    
         
            +
                addr_nbo = Socket.resolv_nbo_i(addr)
         
     | 
| 
      
 234 
     | 
    
         
            +
                comm     = nil
         
     | 
| 
      
 235 
     | 
    
         
            +
                msb      = 0
         
     | 
| 
      
 236 
     | 
    
         
            +
             
     | 
| 
      
 237 
     | 
    
         
            +
                each { |route|
         
     | 
| 
      
 238 
     | 
    
         
            +
                  if ((route.subnet_nbo & route.netmask_nbo) ==
         
     | 
| 
      
 239 
     | 
    
         
            +
                      (addr_nbo & route.netmask_nbo))
         
     | 
| 
      
 240 
     | 
    
         
            +
                    if (route.bitmask >= msb)
         
     | 
| 
      
 241 
     | 
    
         
            +
                      comm = route.comm
         
     | 
| 
      
 242 
     | 
    
         
            +
                      msb  = route.bitmask
         
     | 
| 
      
 243 
     | 
    
         
            +
                    end
         
     | 
| 
      
 244 
     | 
    
         
            +
                  end
         
     | 
| 
      
 245 
     | 
    
         
            +
                }
         
     | 
| 
      
 246 
     | 
    
         
            +
             
     | 
| 
      
 247 
     | 
    
         
            +
                comm
         
     | 
| 
      
 248 
     | 
    
         
            +
              end
         
     | 
| 
      
 249 
     | 
    
         
            +
             
     | 
| 
      
 250 
     | 
    
         
            +
              #
         
     | 
| 
      
 251 
     | 
    
         
            +
              # Remove all routes that go through the supplied comm.
         
     | 
| 
      
 252 
     | 
    
         
            +
              #
         
     | 
| 
      
 253 
     | 
    
         
            +
              def remove_by_comm(comm)
         
     | 
| 
      
 254 
     | 
    
         
            +
                _init
         
     | 
| 
      
 255 
     | 
    
         
            +
                mutex.synchronize {
         
     | 
| 
      
 256 
     | 
    
         
            +
                  routes.delete_if { |route|
         
     | 
| 
      
 257 
     | 
    
         
            +
                    route.comm == comm
         
     | 
| 
      
 258 
     | 
    
         
            +
                  }
         
     | 
| 
      
 259 
     | 
    
         
            +
                }
         
     | 
| 
      
 260 
     | 
    
         
            +
              end
         
     | 
| 
      
 261 
     | 
    
         
            +
             
     | 
| 
      
 262 
     | 
    
         
            +
              #
         
     | 
| 
      
 263 
     | 
    
         
            +
              # The routes array.
         
     | 
| 
      
 264 
     | 
    
         
            +
              #
         
     | 
| 
      
 265 
     | 
    
         
            +
              attr_reader :routes
         
     | 
| 
      
 266 
     | 
    
         
            +
              #
         
     | 
| 
      
 267 
     | 
    
         
            +
              # The mutex protecting the routes array.
         
     | 
| 
      
 268 
     | 
    
         
            +
              #
         
     | 
| 
      
 269 
     | 
    
         
            +
              attr_reader :mutex
         
     | 
| 
      
 270 
     | 
    
         
            +
             
     | 
| 
      
 271 
     | 
    
         
            +
            protected
         
     | 
| 
      
 272 
     | 
    
         
            +
             
     | 
| 
      
 273 
     | 
    
         
            +
              attr_writer :routes, :mutex # :nodoc:
         
     | 
| 
      
 274 
     | 
    
         
            +
             
     | 
| 
      
 275 
     | 
    
         
            +
              #
         
     | 
| 
      
 276 
     | 
    
         
            +
              # Initializes the underlying stuff.
         
     | 
| 
      
 277 
     | 
    
         
            +
              #
         
     | 
| 
      
 278 
     | 
    
         
            +
              def _init
         
     | 
| 
      
 279 
     | 
    
         
            +
                if (@_initialized != true)
         
     | 
| 
      
 280 
     | 
    
         
            +
                  @_initialized = true
         
     | 
| 
      
 281 
     | 
    
         
            +
                  self.routes   = Array.new
         
     | 
| 
      
 282 
     | 
    
         
            +
                  self.mutex    = Mutex.new
         
     | 
| 
      
 283 
     | 
    
         
            +
                end
         
     | 
| 
      
 284 
     | 
    
         
            +
              end
         
     | 
| 
      
 285 
     | 
    
         
            +
             
     | 
| 
      
 286 
     | 
    
         
            +
            end
         
     | 
| 
      
 287 
     | 
    
         
            +
             
     | 
| 
      
 288 
     | 
    
         
            +
            end
         
     | 
| 
      
 289 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,79 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # -*- coding: binary -*-
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'ssl_scan/socket'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'ssl_scan/io/stream'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            ###
         
     | 
| 
      
 6 
     | 
    
         
            +
            #
         
     | 
| 
      
 7 
     | 
    
         
            +
            # This class provides methods for interacting with a TCP client connection.
         
     | 
| 
      
 8 
     | 
    
         
            +
            #
         
     | 
| 
      
 9 
     | 
    
         
            +
            ###
         
     | 
| 
      
 10 
     | 
    
         
            +
            module SSLScan::Socket::Tcp
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              include SSLScan::Socket
         
     | 
| 
      
 13 
     | 
    
         
            +
              include SSLScan::IO::Stream
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              ##
         
     | 
| 
      
 16 
     | 
    
         
            +
              #
         
     | 
| 
      
 17 
     | 
    
         
            +
              # Factory
         
     | 
| 
      
 18 
     | 
    
         
            +
              #
         
     | 
| 
      
 19 
     | 
    
         
            +
              ##
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
              #
         
     | 
| 
      
 22 
     | 
    
         
            +
              # Creates the client using the supplied hash.
         
     | 
| 
      
 23 
     | 
    
         
            +
              #
         
     | 
| 
      
 24 
     | 
    
         
            +
              # @see create_param
         
     | 
| 
      
 25 
     | 
    
         
            +
              # @see SSLScan::Socket::Parameters.from_hash
         
     | 
| 
      
 26 
     | 
    
         
            +
              def self.create(hash = {})
         
     | 
| 
      
 27 
     | 
    
         
            +
                hash['Proto'] = 'tcp'
         
     | 
| 
      
 28 
     | 
    
         
            +
                self.create_param(SSLScan::Socket::Parameters.from_hash(hash))
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
              #
         
     | 
| 
      
 32 
     | 
    
         
            +
              # Wrapper around the base socket class' creation method that automatically
         
     | 
| 
      
 33 
     | 
    
         
            +
              # sets the parameter's protocol to TCP.
         
     | 
| 
      
 34 
     | 
    
         
            +
              #
         
     | 
| 
      
 35 
     | 
    
         
            +
              def self.create_param(param)
         
     | 
| 
      
 36 
     | 
    
         
            +
                param.proto = 'tcp'
         
     | 
| 
      
 37 
     | 
    
         
            +
                SSLScan::Socket.create_param(param)
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
              ##
         
     | 
| 
      
 41 
     | 
    
         
            +
              #
         
     | 
| 
      
 42 
     | 
    
         
            +
              # Stream mixin implementations
         
     | 
| 
      
 43 
     | 
    
         
            +
              #
         
     | 
| 
      
 44 
     | 
    
         
            +
              ##
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
              #
         
     | 
| 
      
 47 
     | 
    
         
            +
              # Calls shutdown on the TCP connection.
         
     | 
| 
      
 48 
     | 
    
         
            +
              #
         
     | 
| 
      
 49 
     | 
    
         
            +
              def shutdown(how = ::Socket::SHUT_RDWR)
         
     | 
| 
      
 50 
     | 
    
         
            +
                begin
         
     | 
| 
      
 51 
     | 
    
         
            +
                  return (super(how) == 0)
         
     | 
| 
      
 52 
     | 
    
         
            +
                rescue ::Exception
         
     | 
| 
      
 53 
     | 
    
         
            +
                end
         
     | 
| 
      
 54 
     | 
    
         
            +
              end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
              #
         
     | 
| 
      
 57 
     | 
    
         
            +
              # Returns peer information (host + port) in host:port format.
         
     | 
| 
      
 58 
     | 
    
         
            +
              #
         
     | 
| 
      
 59 
     | 
    
         
            +
              def peerinfo
         
     | 
| 
      
 60 
     | 
    
         
            +
                if (pi = getpeername)
         
     | 
| 
      
 61 
     | 
    
         
            +
                  return pi[1] + ':' + pi[2].to_s
         
     | 
| 
      
 62 
     | 
    
         
            +
                end
         
     | 
| 
      
 63 
     | 
    
         
            +
              end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
              #
         
     | 
| 
      
 66 
     | 
    
         
            +
              # Returns local information (host + port) in host:port format.
         
     | 
| 
      
 67 
     | 
    
         
            +
              #
         
     | 
| 
      
 68 
     | 
    
         
            +
              def localinfo
         
     | 
| 
      
 69 
     | 
    
         
            +
                if (pi = getlocalname)
         
     | 
| 
      
 70 
     | 
    
         
            +
                  return pi[1] + ':' + pi[2].to_s
         
     | 
| 
      
 71 
     | 
    
         
            +
                end
         
     | 
| 
      
 72 
     | 
    
         
            +
              end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
              # returns socket type
         
     | 
| 
      
 75 
     | 
    
         
            +
              def type?
         
     | 
| 
      
 76 
     | 
    
         
            +
                return 'tcp'
         
     | 
| 
      
 77 
     | 
    
         
            +
              end
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,67 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # -*- coding: binary -*-
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'ssl_scan/socket'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'ssl_scan/socket/tcp'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'ssl_scan/io/stream_server'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            ###
         
     | 
| 
      
 7 
     | 
    
         
            +
            #
         
     | 
| 
      
 8 
     | 
    
         
            +
            # This class provides methods for interacting with a TCP server.  It
         
     | 
| 
      
 9 
     | 
    
         
            +
            # implements the SSLScan::IO::StreamServer interface.
         
     | 
| 
      
 10 
     | 
    
         
            +
            #
         
     | 
| 
      
 11 
     | 
    
         
            +
            ###
         
     | 
| 
      
 12 
     | 
    
         
            +
            module  SSLScan::Socket::TcpServer
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              include SSLScan::Socket
         
     | 
| 
      
 15 
     | 
    
         
            +
              include SSLScan::IO::StreamServer
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
              ##
         
     | 
| 
      
 18 
     | 
    
         
            +
              #
         
     | 
| 
      
 19 
     | 
    
         
            +
              # Factory
         
     | 
| 
      
 20 
     | 
    
         
            +
              #
         
     | 
| 
      
 21 
     | 
    
         
            +
              ##
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
              #
         
     | 
| 
      
 24 
     | 
    
         
            +
              # Creates the server using the supplied hash.
         
     | 
| 
      
 25 
     | 
    
         
            +
              #
         
     | 
| 
      
 26 
     | 
    
         
            +
              def self.create(hash = {})
         
     | 
| 
      
 27 
     | 
    
         
            +
                hash['Proto'] = 'tcp'
         
     | 
| 
      
 28 
     | 
    
         
            +
                hash['Server'] = true
         
     | 
| 
      
 29 
     | 
    
         
            +
                self.create_param(SSLScan::Socket::Parameters.from_hash(hash))
         
     | 
| 
      
 30 
     | 
    
         
            +
              end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
              #
         
     | 
| 
      
 33 
     | 
    
         
            +
              # Wrapper around the base class' creation method that automatically sets
         
     | 
| 
      
 34 
     | 
    
         
            +
              # the parameter's protocol to TCP and sets the server flag to true.
         
     | 
| 
      
 35 
     | 
    
         
            +
              #
         
     | 
| 
      
 36 
     | 
    
         
            +
              def self.create_param(param)
         
     | 
| 
      
 37 
     | 
    
         
            +
                param.proto  = 'tcp'
         
     | 
| 
      
 38 
     | 
    
         
            +
                param.server = true
         
     | 
| 
      
 39 
     | 
    
         
            +
                SSLScan::Socket.create_param(param)
         
     | 
| 
      
 40 
     | 
    
         
            +
              end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
              #
         
     | 
| 
      
 43 
     | 
    
         
            +
              # Accepts a child connection.
         
     | 
| 
      
 44 
     | 
    
         
            +
              #
         
     | 
| 
      
 45 
     | 
    
         
            +
              def accept(opts = {})
         
     | 
| 
      
 46 
     | 
    
         
            +
                t = super()
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                # jRuby compatibility
         
     | 
| 
      
 49 
     | 
    
         
            +
                if t.respond_to?('[]')
         
     | 
| 
      
 50 
     | 
    
         
            +
                  t = t[0]
         
     | 
| 
      
 51 
     | 
    
         
            +
                end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                if (t)
         
     | 
| 
      
 54 
     | 
    
         
            +
                  t.extend(SSLScan::Socket::Tcp)
         
     | 
| 
      
 55 
     | 
    
         
            +
                  t.context = self.context
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                  pn = t.getpeername
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                  t.peerhost = pn[1]
         
     | 
| 
      
 60 
     | 
    
         
            +
                  t.peerport = pn[2]
         
     | 
| 
      
 61 
     | 
    
         
            +
                end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                t
         
     | 
| 
      
 64 
     | 
    
         
            +
              end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
            end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
         @@ -0,0 +1,165 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # -*- coding: binary -*-
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'ssl_scan/socket'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            ###
         
     | 
| 
      
 5 
     | 
    
         
            +
            #
         
     | 
| 
      
 6 
     | 
    
         
            +
            # This class provides methods for interacting with a UDP socket.
         
     | 
| 
      
 7 
     | 
    
         
            +
            #
         
     | 
| 
      
 8 
     | 
    
         
            +
            ###
         
     | 
| 
      
 9 
     | 
    
         
            +
            module SSLScan::Socket::Udp
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              include SSLScan::Socket
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
              ##
         
     | 
| 
      
 14 
     | 
    
         
            +
              #
         
     | 
| 
      
 15 
     | 
    
         
            +
              # Factory
         
     | 
| 
      
 16 
     | 
    
         
            +
              #
         
     | 
| 
      
 17 
     | 
    
         
            +
              ##
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
              #
         
     | 
| 
      
 20 
     | 
    
         
            +
              # Creates the client using the supplied hash.
         
     | 
| 
      
 21 
     | 
    
         
            +
              #
         
     | 
| 
      
 22 
     | 
    
         
            +
              def self.create(hash = {})
         
     | 
| 
      
 23 
     | 
    
         
            +
                hash['Proto'] = 'udp'
         
     | 
| 
      
 24 
     | 
    
         
            +
                # If we have are to bind to a LocalHost we must be a Server to avail of pivoting.
         
     | 
| 
      
 25 
     | 
    
         
            +
                # SSLScan::Socket::Parameters will subsequently turn off the sever flag after the correct
         
     | 
| 
      
 26 
     | 
    
         
            +
                # comm has been chosen.
         
     | 
| 
      
 27 
     | 
    
         
            +
                if( hash['LocalHost'] )
         
     | 
| 
      
 28 
     | 
    
         
            +
                  hash['Server'] = true
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
                self.create_param(SSLScan::Socket::Parameters.from_hash(hash))
         
     | 
| 
      
 31 
     | 
    
         
            +
              end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
              #
         
     | 
| 
      
 34 
     | 
    
         
            +
              # Wrapper around the base socket class' creation method that automatically
         
     | 
| 
      
 35 
     | 
    
         
            +
              # sets the parameter's protocol to UDP.
         
     | 
| 
      
 36 
     | 
    
         
            +
              #
         
     | 
| 
      
 37 
     | 
    
         
            +
              def self.create_param(param)
         
     | 
| 
      
 38 
     | 
    
         
            +
                param.proto = 'udp'
         
     | 
| 
      
 39 
     | 
    
         
            +
                SSLScan::Socket.create_param(param)
         
     | 
| 
      
 40 
     | 
    
         
            +
              end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
              ##
         
     | 
| 
      
 43 
     | 
    
         
            +
              #
         
     | 
| 
      
 44 
     | 
    
         
            +
              # UDP connected state methods
         
     | 
| 
      
 45 
     | 
    
         
            +
              #
         
     | 
| 
      
 46 
     | 
    
         
            +
              ##
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
              #
         
     | 
| 
      
 49 
     | 
    
         
            +
              # Write the supplied datagram to the connected UDP socket.
         
     | 
| 
      
 50 
     | 
    
         
            +
              #
         
     | 
| 
      
 51 
     | 
    
         
            +
              def write(gram)
         
     | 
| 
      
 52 
     | 
    
         
            +
                begin
         
     | 
| 
      
 53 
     | 
    
         
            +
                  return syswrite(gram)
         
     | 
| 
      
 54 
     | 
    
         
            +
                rescue  ::Errno::EHOSTUNREACH,::Errno::ENETDOWN,::Errno::ENETUNREACH,::Errno::ENETRESET,::Errno::EHOSTDOWN,::Errno::EACCES,::Errno::EINVAL,::Errno::EADDRNOTAVAIL
         
     | 
| 
      
 55 
     | 
    
         
            +
                  return nil
         
     | 
| 
      
 56 
     | 
    
         
            +
                end
         
     | 
| 
      
 57 
     | 
    
         
            +
              end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
              alias put write
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
              #
         
     | 
| 
      
 62 
     | 
    
         
            +
              # Read a datagram from the UDP socket.
         
     | 
| 
      
 63 
     | 
    
         
            +
              #
         
     | 
| 
      
 64 
     | 
    
         
            +
              def read(length = 65535)
         
     | 
| 
      
 65 
     | 
    
         
            +
                if length < 0
         
     | 
| 
      
 66 
     | 
    
         
            +
                  length = 65535
         
     | 
| 
      
 67 
     | 
    
         
            +
                end
         
     | 
| 
      
 68 
     | 
    
         
            +
                return sysread(length)
         
     | 
| 
      
 69 
     | 
    
         
            +
              end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
              #
         
     | 
| 
      
 72 
     | 
    
         
            +
              # Read a datagram from the UDP socket with a timeout
         
     | 
| 
      
 73 
     | 
    
         
            +
              #
         
     | 
| 
      
 74 
     | 
    
         
            +
              def timed_read(length = 65535, timeout=def_read_timeout)
         
     | 
| 
      
 75 
     | 
    
         
            +
                begin
         
     | 
| 
      
 76 
     | 
    
         
            +
                  if ((rv = ::IO.select([ fd ], nil, nil, timeout)) and
         
     | 
| 
      
 77 
     | 
    
         
            +
                      (rv[0]) and (rv[0][0] == fd)
         
     | 
| 
      
 78 
     | 
    
         
            +
                     )
         
     | 
| 
      
 79 
     | 
    
         
            +
                      return read(length)
         
     | 
| 
      
 80 
     | 
    
         
            +
                  else
         
     | 
| 
      
 81 
     | 
    
         
            +
                    return ''
         
     | 
| 
      
 82 
     | 
    
         
            +
                  end
         
     | 
| 
      
 83 
     | 
    
         
            +
                rescue Exception
         
     | 
| 
      
 84 
     | 
    
         
            +
                  return ''
         
     | 
| 
      
 85 
     | 
    
         
            +
                end
         
     | 
| 
      
 86 
     | 
    
         
            +
              end
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
              #alias send write
         
     | 
| 
      
 89 
     | 
    
         
            +
              #alias recv read
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
              ##
         
     | 
| 
      
 92 
     | 
    
         
            +
              #
         
     | 
| 
      
 93 
     | 
    
         
            +
              # UDP non-connected state methods
         
     | 
| 
      
 94 
     | 
    
         
            +
              #
         
     | 
| 
      
 95 
     | 
    
         
            +
              ##
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
              #
         
     | 
| 
      
 98 
     | 
    
         
            +
              # Sends a datagram to the supplied host:port with optional flags.
         
     | 
| 
      
 99 
     | 
    
         
            +
              #
         
     | 
| 
      
 100 
     | 
    
         
            +
              def sendto(gram, peerhost, peerport, flags = 0)
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
                # Catch unconnected IPv6 sockets talking to IPv4 addresses
         
     | 
| 
      
 103 
     | 
    
         
            +
                peer = SSLScan::Socket.resolv_nbo(peerhost)
         
     | 
| 
      
 104 
     | 
    
         
            +
                if (peer.length == 4 and self.ipv == 6)
         
     | 
| 
      
 105 
     | 
    
         
            +
                  peerhost = SSLScan::Socket.getaddress(peerhost, true)
         
     | 
| 
      
 106 
     | 
    
         
            +
                  if peerhost[0,7].downcase != '::ffff:'
         
     | 
| 
      
 107 
     | 
    
         
            +
                    peerhost = '::ffff:' + peerhost
         
     | 
| 
      
 108 
     | 
    
         
            +
                  end
         
     | 
| 
      
 109 
     | 
    
         
            +
                end
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
                begin
         
     | 
| 
      
 112 
     | 
    
         
            +
                  send(gram, flags, SSLScan::Socket.to_sockaddr(peerhost, peerport))
         
     | 
| 
      
 113 
     | 
    
         
            +
                rescue  ::Errno::EHOSTUNREACH,::Errno::ENETDOWN,::Errno::ENETUNREACH,::Errno::ENETRESET,::Errno::EHOSTDOWN,::Errno::EACCES,::Errno::EINVAL,::Errno::EADDRNOTAVAIL
         
     | 
| 
      
 114 
     | 
    
         
            +
                  return nil
         
     | 
| 
      
 115 
     | 
    
         
            +
                end
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
              end
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
              #
         
     | 
| 
      
 120 
     | 
    
         
            +
              # Receives a datagram and returns the data and host:port of the requestor
         
     | 
| 
      
 121 
     | 
    
         
            +
              # as [ data, host, port ].
         
     | 
| 
      
 122 
     | 
    
         
            +
              #
         
     | 
| 
      
 123 
     | 
    
         
            +
              def recvfrom(length = 65535, timeout=def_read_timeout)
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
                begin
         
     | 
| 
      
 126 
     | 
    
         
            +
                  if ((rv = ::IO.select([ fd ], nil, nil, timeout)) and
         
     | 
| 
      
 127 
     | 
    
         
            +
                      (rv[0]) and (rv[0][0] == fd)
         
     | 
| 
      
 128 
     | 
    
         
            +
                     )
         
     | 
| 
      
 129 
     | 
    
         
            +
                      data, saddr    = recvfrom_nonblock(length)
         
     | 
| 
      
 130 
     | 
    
         
            +
                      af, host, port = SSLScan::Socket.from_sockaddr(saddr)
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
                      return [ data, host, port ]
         
     | 
| 
      
 133 
     | 
    
         
            +
                  else
         
     | 
| 
      
 134 
     | 
    
         
            +
                    return [ '', nil, nil ]
         
     | 
| 
      
 135 
     | 
    
         
            +
                  end
         
     | 
| 
      
 136 
     | 
    
         
            +
                rescue ::Timeout::Error
         
     | 
| 
      
 137 
     | 
    
         
            +
                  return [ '', nil, nil ]
         
     | 
| 
      
 138 
     | 
    
         
            +
                rescue ::Interrupt
         
     | 
| 
      
 139 
     | 
    
         
            +
                  raise $!
         
     | 
| 
      
 140 
     | 
    
         
            +
                rescue ::Exception
         
     | 
| 
      
 141 
     | 
    
         
            +
                  return [ '', nil, nil ]
         
     | 
| 
      
 142 
     | 
    
         
            +
                end
         
     | 
| 
      
 143 
     | 
    
         
            +
              end
         
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
      
 145 
     | 
    
         
            +
              #
         
     | 
| 
      
 146 
     | 
    
         
            +
              # Calls recvfrom and only returns the data
         
     | 
| 
      
 147 
     | 
    
         
            +
              #
         
     | 
| 
      
 148 
     | 
    
         
            +
              def get(timeout=nil)
         
     | 
| 
      
 149 
     | 
    
         
            +
                data, saddr, sport = recvfrom(65535, timeout)
         
     | 
| 
      
 150 
     | 
    
         
            +
                return data
         
     | 
| 
      
 151 
     | 
    
         
            +
              end
         
     | 
| 
      
 152 
     | 
    
         
            +
             
     | 
| 
      
 153 
     | 
    
         
            +
              #
         
     | 
| 
      
 154 
     | 
    
         
            +
              # The default number of seconds to wait for a read operation to timeout.
         
     | 
| 
      
 155 
     | 
    
         
            +
              #
         
     | 
| 
      
 156 
     | 
    
         
            +
              def def_read_timeout
         
     | 
| 
      
 157 
     | 
    
         
            +
                10
         
     | 
| 
      
 158 
     | 
    
         
            +
              end
         
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
      
 160 
     | 
    
         
            +
              def type?
         
     | 
| 
      
 161 
     | 
    
         
            +
                return 'udp'
         
     | 
| 
      
 162 
     | 
    
         
            +
              end
         
     | 
| 
      
 163 
     | 
    
         
            +
             
     | 
| 
      
 164 
     | 
    
         
            +
            end
         
     | 
| 
      
 165 
     | 
    
         
            +
             
     |