Files
metasploit-gs/lib/rex/exceptions.rb
T
HD Moore 6b4eb9a8e2 Differentiate failed binds from connects, closes #4169
This change adds two new Rex exceptions and changes the local comm to raise the right one depending on the circumstances. The problem with the existing model is
that failed binds and failed connections both raised the same exception. This change is backwards compatible with modules that rescue Rex::AddressInUse in additi
on to Rex::ConnectionError. There were two corner cases that rescued Rex::AddressInUse specifically:

1. The 'r'-services mixin and modules caught the old exception when handling bind errors. These have been updated to use BindFailed
2. The meterpreter client had a catch for the old exception when the socket reports a bad destination (usually a network connection dropped). This has been updat
ed to use InvalidDestination as that was the intention prior to this change.

Since AddressInUse was part of ConnectionError, modules and mixins which caught both in the same rescue have been updated to just catch ConnectionError.
2014-11-11 14:59:41 -06:00

308 lines
5.2 KiB
Ruby

# -*- coding: binary -*-
module Rex
###
#
# Base mixin for all exceptions that can be thrown from inside Rex.
#
###
module Exception
end
###
#
# This exception is raised when a timeout occurs.
#
###
class TimeoutError < Interrupt
include Exception
def to_s
"Operation timed out."
end
end
###
#
# This exception is raised when a method is called or a feature is used that
# is not implemented.
#
###
class NotImplementedError < ::NotImplementedError
include Exception
def to_s
"The requested method is not implemented."
end
end
###
#
# This exception is raised when a generalized runtime error occurs.
#
###
class RuntimeError < ::RuntimeError
include Exception
end
###
#
# This exception is raised when an invalid argument is supplied to a method.
#
###
class ArgumentError < ::ArgumentError
include Exception
def initialize(message = nil)
@message = message
end
def to_s
str = 'An invalid argument was specified.'
if @message
str << " #{@message}"
end
str
end
end
###
#
# This exception is raised when an argument that was supplied to a method
# could not be parsed correctly.
#
###
class ArgumentParseError < ::ArgumentError
include Exception
def to_s
"The argument could not be parsed correctly."
end
end
###
#
# This exception is raised when an argument is ambiguous.
#
###
class AmbiguousArgumentError < ::RuntimeError
include Exception
def initialize(name = nil)
@name = name
end
def to_s
"The name #{@name} is ambiguous."
end
end
###
#
# This error is thrown when a stream is detected as being closed.
#
###
class StreamClosedError < ::IOError
include Exception
def initialize(stream)
@stream = stream
end
def stream
@stream
end
def to_s
"Stream #{@stream} is closed."
end
end
##
#
# Socket exceptions
#
##
###
#
# This exception is raised when a general socket error occurs.
#
###
module SocketError
include Exception
def to_s
"A socket error occurred."
end
end
###
#
# This exception is raised when there is some kind of error related to
# communication with a host.
#
###
module HostCommunicationError
def initialize(addr = nil, port = nil)
self.host = addr
self.port = port
end
#
# This method returns a printable address and optional port associated
# with the host that triggered the exception.
#
def addr_to_s
if host and port
"(#{host}:#{port})"
elsif host
"(#{host})"
else
""
end
end
attr_accessor :host, :port
end
###
#
# This is a generic exception for errors that cause a connection to fail.
#
###
class ConnectionError < ::IOError
include SocketError
include HostCommunicationError
end
###
#
# This exception is raised when a connection attempt fails because the remote
# side refused the connection.
#
###
class ConnectionRefused < ConnectionError
def to_s
"The connection was refused by the remote host #{addr_to_s}."
end
end
###
#
# This exception is raised when a connection attempt fails because the remote
# side is unreachable.
#
###
class HostUnreachable < ConnectionError
def to_s
"The host #{addr_to_s} was unreachable."
end
end
###
#
# This exception is raised when a connection attempt times out.
#
###
class ConnectionTimeout < ConnectionError
def to_s
"The connection timed out #{addr_to_s}."
end
end
###
#
# This connection error is raised when an attempt is made to connect
# to a broadcast or network address.
#
###
class InvalidDestination < ConnectionError
include SocketError
include HostCommunicationError
def to_s
"The destination is invalid: #{addr_to_s}."
end
end
###
#
# This exception is raised when an attempt to use an address or port that is
# already in use or onot available occurs. such as binding to a host on a
# given port that is already in use, or when a bind address is specified that
# is not available to the host.
#
###
class BindFailed < ::ArgumentError
include SocketError
include HostCommunicationError
def to_s
"The address is already in use or unavailable: #{addr_to_s}."
end
end
##
#
# This exception is listed for backwards compatibility. We had been
# using AddressInUse as the exception for both bind errors and connection
# errors triggered by connection attempts to broadcast and network addresses.
# The two classes above have split this into their respective sources, but
# callers may still expect the old behavior.
#
##
class AddressInUse < ConnectionError
include SocketError
include HostCommunicationError
def to_s
"The address is already in use or unavailable: #{addr_to_s}."
end
end
###
#
# This exception is raised when an unsupported internet protocol is specified.
#
###
class UnsupportedProtocol < ::ArgumentError
include SocketError
def initialize(proto = nil)
self.proto = proto
end
def to_s
"The protocol #{proto} is not supported."
end
attr_accessor :proto
end
###
#
# This exception is raised when a proxy fails to pass a connection
#
###
class ConnectionProxyError < ConnectionError
def initialize(host,port,ptype,reason)
super(host,port)
self.ptype = ptype
self.reason = reason
end
def to_s
self.ptype + ": " + self.reason
end
attr_accessor :ptype, :reason
end
end