class Ronin::Support::Network::EmailAddress
Represents an email address.
## Features
-
Supports normalizing tagged emails.
-
Supports {EmailAddress.deobfuscate deobfuscating} email addresses.
-
Supports {EmailAddress#obfuscate obfuscating} email addresses.
## Examples
Builds a new email address:
email = EmailAddress.new(mailbox: 'john.smith', domain: 'example.com')
Parses an email address:
email = EmailAddress.parse("John Smith <john.smith@example.com>") # => #<Ronin::Support::Network::EmailAddress:0x00007f49586d6a20 @address=nil, @domain="example.com", @mailbox="john.smith", @name="John Smith", @routing=nil, @tag=nil>
Deobfuscate an obfuscated email address:
EmailAddress.deobfuscate("john[dot]smith [at] example[dot]com") # => "john.smith@example.com"
Obfuscate an email address:
email = EmailAddress.parse("john.smith@example.com") email.obfuscate # => "john <dot> smith <at> example <dot> com"
Get every obfuscation of an email address:
email.obfuscations # => ["john.smith AT example.com", # "john.smith at example.com", # "john.smith[AT]example.com", # "john.smith[at]example.com", # "john.smith [AT] example.com", # "john.smith [at] example.com", # "john.smith<AT>example.com", # "john.smith<at>example.com", # "john.smith <AT> example.com", # "john.smith <at> example.com", # "john.smith{AT}example.com", # "john.smith{at}example.com", # "john.smith {AT} example.com", # "john.smith {at} example.com", # "john.smith(AT)example.com", # "john.smith(at)example.com", # "john.smith (AT) example.com", # "john.smith (at) example.com", # "john DOT smith AT example DOT com", # "john dot smith at example dot com", # "john[DOT]smith[AT]example[DOT]com", # "john[dot]smith[at]example[dot]com", # "john [DOT] smith [AT] example [DOT] com", # "john [dot] smith [at] example [dot] com", # "john<DOT>smith<AT>example<DOT>com", # "john<dot>smith<at>example<dot>com", # "john <DOT> smith <AT> example <DOT> com", # "john <dot> smith <at> example <dot> com", # "john{DOT}smith{AT}example{DOT}com", # "john{dot}smith{at}example{dot}com", # "john {DOT} smith {AT} example {DOT} com", # "john {dot} smith {at} example {dot} com", # "john(DOT)smith(AT)example(DOT)com", # "john(dot)smith(at)example(dot)com", # "john (DOT) smith (AT) example (DOT) com", # "john (dot) smith (at) example (dot) com"]
@see datatracker.ietf.org/doc/html/rfc2822#section-3.4
@api public
@since 1.0.0
Constants
- DEOBFUSCATIONS
-
Email address de-obfuscation rules.
- OBFUSCATIONS
-
Email address obfuscation rules.
Attributes
The IP
address of the email address (ex: ‘john.smith@`).
@return [String, nil]
The domain of the email address (ex: ‘john.smith@example.com`).
@return [String, nil]
The mailbox or username of the email address.
@return [String]
The optional name associated with the email address (ex: ‘John Smith <john.smith@example.com`).
@return [String, nil]
Additional hosts to route sent emails through; aka the “percent hack” (ex: ‘john.smith%host3.com%host2.com@host1.com`).
@return [Array<String>, nil]
The optional sorting tag of the email address (ex: ‘john.smith+tag@example.com`).
@return [String, nil]
The mailbox or username of the email address.
@return [String]
Public Class Methods
Source
# File lib/ronin/support/network/email_address.rb, line 355 def self.deobfuscate(string) DEOBFUSCATIONS.each do |pattern,replace| string = string.gsub(pattern,replace) end return string end
Deobfuscates an obfuscated email address.
@param [String] string
The obfuscated email address to deobfuscate.
@return [String]
The deobfuscated email address.
@example
EmailAddress.deobfuscate("john[dot]smith [at] example[dot]com") # => "john.smith@example.com"
Source
# File lib/ronin/support/network/email_address.rb, line 180 def initialize(name: nil, mailbox: , tag: nil, routing: nil, domain: nil, address: nil) @name = name @mailbox = mailbox @tag = tag @routing = routing unless (domain.nil? ^ address.nil?) raise(ArgumentError,"must specify domain: or address: keyword arguments") end @domain = domain @address = address end
Initializes the email address.
@param [String, nil] name
The optional name associated with the email address (ex: `John Smith <john.smith@example.com`).
@param [String] mailbox
The mailbox or username of the email address.
@param [String, nil] tag
The optional sorting tag of the email address (ex: `john.smith+tag@example.com`).
@param [Array<String>, nil] routing
Additional hosts to route sent emails through; aka the "percent hack" (ex: `john.smith%host3.com%host2.com@host1.com`).
@param [String, nil] domain
The domain of the email address (ex: `john.smith@example.com`).
@param [String, nil] address
The IP address of the email address (ex: `john.smith@[1.2.3.4]`).
@raise [ArgumentError]
Must specify either the `domain:` or `address:` keyword arguments.
@example Initializing a basic email address.
email = EmailAddress.new(mailbox: 'john.smith', domain: 'example.com')
@example Initializing an email address with a name:
email = EmailAddress.new(name: 'John Smith', mailbox: 'john.smith', domain: 'example.com')
@example Initializing an email address with a sorting tag:
email = EmailAddress.new(mailbox: 'john.smith', tag: 'spam', domain: 'example.com')
Source
# File lib/ronin/support/network/email_address.rb, line 218 def self.parse(string) if string.include?('<') && string.end_with?('>') # Name <local-part@domain.com> if (match = string.match(/^([^<]+)\s+<([^>]+)>$/)) name = match[1] address = match[2] else raise(InvalidEmailAddress,"invalid email address: #{string.inspect}") end else name = nil address = string end return new(name: name, **parse_address(address)) end
Parses an email address.
@param [String] string
The email string to parse.
@return [EmailAddress]
The parsed email address.
@raise [InvalidEmailAddress]
The string is not a valid formatted email address.
@example
email = EmailAddress.parse("John Smith <john.smith@example.com>") # => #<Ronin::Support::Network::EmailAddress:0x00007f49586d6a20 @address=nil, @domain="example.com", @mailbox="john.smith", @name="John Smith", @routing=nil, @tag=nil>
Source
# File lib/ronin/support/network/email_address.rb, line 249 def self.parse_address(string) unless string.include?('@') raise(InvalidEmailAddress,"invalid email address: #{string.inspect}") end # local-part@domain.com local_part, domain = string.split('@',2) return {**parse_local_part(local_part), **parse_domain(domain)} end
Parses the address portion of an email address.
@param [String] string
the email address string to parse.
@return [Hash{Symbol => Object}]
Keyword arguments for {#initialize}.
@raise [InvalidEmailAddress]
The string did not contain a `@` character.
@api private
Source
# File lib/ronin/support/network/email_address.rb, line 313 def self.parse_domain(string) domain = nil address = nil # extract IP addresses from the domain part (ex: `user@[1.2.3.4]`) if string.start_with?('[') && string.end_with?(']') address = string[1..-2] else domain = string end return {domain: domain, address: address} end
Parses the domain portion of an email address.
@param [String] string
The domain portion to parse.
@return [Hash{Symbol => Object}]
Keyword arguments for {#initialize}.
@api private
Source
# File lib/ronin/support/network/email_address.rb, line 271 def self.parse_local_part(string) routing = nil if string.include?('%') mailbox, *routing = string.split('%') else mailbox = string routing = nil end return {routing: routing, **parse_mailbox(mailbox)} end
Parses the local-part portion of an email address.
@param [String] string
the local-part string to parse.
@return [Hash{Symbol => Object}]
Keyword arguments for {#initialize}.
@api private
Source
# File lib/ronin/support/network/email_address.rb, line 295 def self.parse_mailbox(string) # extract any sorting-tags (ex: `user+service@domain.com`) mailbox, tag = string.split('+',2) return {mailbox: mailbox, tag: tag} end
Parses the mailbox portion of an email address.
@param [String] string
The mailbox string to parse.
@return [Hash{Symbol => Object}]
Keyword arguments for {#initialize}.
@api private
Public Instance Methods
Source
# File lib/ronin/support/network/email_address.rb, line 503 def each_obfuscation return enum_for(__method__) unless block_given? string = to_s OBFUSCATIONS.each do |gsub_args| yield string.gsub(*gsub_args) end return nil end
Enumerates over each obfuscation of the email address.
@yield [obfuscated]
If a block is given, it will be passed every obfuscation of the email address.
@yieldparam [String] obfuscated
An obfuscated version of the email address.
@return [Enumerator]
If no block is given, an Enumerator will be returned.
@example
email = EmailAddress.parse("john.smith@example.com") email.each_obfuscation { |obfuscated_email| ... }
@see OBFUSCATIONS
Source
# File lib/ronin/support/network/email_address.rb, line 389 def hostname @domain || @address end
The hostname to connect to.
@return [String]
The {#domain} or {#address}.
Source
# File lib/ronin/support/network/email_address.rb, line 375 def normalize EmailAddress.new( mailbox: mailbox, domain: domain, address: address ) end
Creates a new email address without the {#tag} or {#routing} attribute.
@return [EmailAddress]
The new normalized email address object.
@example
email = EmailAddress.parse("John Smith <john.smith+spam@example.com>") email.normalize.to_s # => "john.smith@example.com"
Source
# File lib/ronin/support/network/email_address.rb, line 478 def obfuscate string = to_s string.gsub!(*OBFUSCATIONS.sample) return string end
Obfuscates the email address.
@return [String]
A randomly obfuscated version of the email address.
@see OBFUSCATIONS
@example
email = EmailAddress.parse("john.smith@example.com") email.obfuscate # => "john.smith [AT] example.com" email.obfuscate # => "john <dot> smith <at> example <dot> com"
Source
# File lib/ronin/support/network/email_address.rb, line 563 def obfuscations each_obfuscation.to_a end
Returns every obfuscation of the email address.
@return [Array<String>]
The Array containing every obfuscation of the email address.
@example
email = EmailAddress.parse("john.smith@example.com") email.obfuscations # => ["john.smith AT example.com", # "john.smith at example.com", # "john.smith[AT]example.com", # "john.smith[at]example.com", # "john.smith [AT] example.com", # "john.smith [at] example.com", # "john.smith<AT>example.com", # "john.smith<at>example.com", # "john.smith <AT> example.com", # "john.smith <at> example.com", # "john.smith{AT}example.com", # "john.smith{at}example.com", # "john.smith {AT} example.com", # "john.smith {at} example.com", # "john.smith(AT)example.com", # "john.smith(at)example.com", # "john.smith (AT) example.com", # "john.smith (at) example.com", # "john DOT smith AT example DOT com", # "john dot smith at example dot com", # "john[DOT]smith[AT]example[DOT]com", # "john[dot]smith[at]example[dot]com", # "john [DOT] smith [AT] example [DOT] com", # "john [dot] smith [at] example [dot] com", # "john<DOT>smith<AT>example<DOT>com", # "john<dot>smith<at>example<dot>com", # "john <DOT> smith <AT> example <DOT> com", # "john <dot> smith <at> example <dot> com", # "john{DOT}smith{AT}example{DOT}com", # "john{dot}smith{at}example{dot}com", # "john {DOT} smith {AT} example {DOT} com", # "john {dot} smith {at} example {dot} com", # "john(DOT)smith(AT)example(DOT)com", # "john(dot)smith(at)example(dot)com", # "john (DOT) smith (AT) example (DOT) com", # "john (dot) smith (at) example (dot) com"]
@see each_obfuscation
Source
# File lib/ronin/support/network/email_address.rb, line 404 def to_s string = "#{@mailbox}" string << "+#{@tag}" if @tag string << "%#{@routing.join('%')}" if @routing string << "@" string << if @address then "[#{@address}]" else @domain end string = "#{@name} <#{string}>" if @name return string end
Converts the email address back into a string.
@return [String]
The string representation of the email address.
@example
email = EmailAddress.parse("John Smith <john.smith+spam@example.com>") email.to_s # => "John Smith <john.smith+spam@example.com>"