Class: String
- Defined in:
- lib/rubymta/base-x.rb,
lib/rubymta/extended_classes.rb
Instance Method Summary collapse
-
#blacklisted?(dx) ⇒ Boolean
returns true if the IP is blacklisted; otherwise false examples: barracuda = ‘b.barracudacentral.org’.blacklisted?(ip) spamhaus = ‘zen.spamhaus.org’.blacklisted?(ip).
-
#dig_a ⇒ Object
returns list of IPV4 addresses, or nil (there should only be one IPV4 address).
-
#dig_aaaa ⇒ Object
returns list of IPV6 addresses, or nil (there should only be one IPV6 address).
-
#dig_dk ⇒ Object
returns a publibdomainkey, or nil (there should only be one DKIM public key).
-
#dig_mx ⇒ Object
returns list of MX names, or nil (there may be multiple MX names for a domain) WARNING: use the #dig_mxs to get the preferences also.
-
#dig_mxs ⇒ Object
returns a hash of { <preference> => [ <mx,ip>, … ] } preferences sorted in numerical order from low–>high (IOW, highest preference to lowest preference) if there is no mx, returns {} ex: “173.194.78.26”]], 20=>[[“alt1.aspmx.l.google.com”, “173.194.219.27”]], 30=>[[“alt2.aspmx.l.google.com”, “74.125.192.27”], [“alt3.aspmx.l.google.com”, “74.125.141.27”]], 40=>[[“alt4.aspmx.l.google.com”, “64.233.190.26”]].
-
#dig_ptr ⇒ Object
returns a reverse DNS hostname or nil.
-
#from_b(base = 62) ⇒ Object
this is used to convert numbers in the email IDs back to base 10.
-
#mta_live?(port) ⇒ Boolean
opens a socket to the IP/port to see if there is an SMTP server there - returns “250 …” if the server is there, or times out in 5 seconds to prevent hanging the process.
-
#utf8 ⇒ Object
returns a UTF-8 encoded string – be carefule using this with email: email has to be received and transported with NO changes, except the addition of extra headers at the beginning (before any DKIM headers).
-
#validate_plain ⇒ Object
this validates a password with the base64 plaintext in an AUTH command encoded -> AGNvY29AY3phcm1haWwuY29tAG15LXBhc3N3b3Jk => [“[email protected]”, “my-password”] call UnixCrypt::SHA256.build(“my-password”) “my-password” –> “$5$BsHk6IIvndgdBmo9$iuO6WMaXzgzpGmGreV4uiH72VRGG1USNK/e5tL7P9jC” “AGNvY29AY3phcm1haWwuY29tAG15LXBhc3N3b3Jk”.validate_plain { “$5$BsHk6IIvndgdBmo9$iuO6WMaXzgzpGmGreV4uiH72VRGG1USNK/e5tL7P9jC” } => “[email protected]”, true.
Instance Method Details
#blacklisted?(dx) ⇒ Boolean
returns true if the IP is blacklisted; otherwise false examples: barracuda = ‘b.barracudacentral.org’.blacklisted?(ip) spamhaus = ‘zen.spamhaus.org’.blacklisted?(ip)
103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/rubymta/extended_classes.rb', line 103 def blacklisted?(dx) domain = dx.split('.').reverse.join('.')+"."+self a = [] Resolv::DNS.open do |dns| begin a = dns.getresources(domain, Resolv::DNS::Resource::IN::A) rescue Resolv::NXDomainError a=[] end end if a.size>0 then true else false end end |
#dig_a ⇒ Object
returns list of IPV4 addresses, or nil (there should only be one IPV4 address)
30 31 32 33 34 35 |
# File 'lib/rubymta/extended_classes.rb', line 30 def dig_a Resolv::DNS.open do |dns| txts = dns.getresources(self,Resolv::DNS::Resource::IN::A).collect { |r| r.address.to_s } if txts.empty? then nil else txts[0] end end end |
#dig_aaaa ⇒ Object
returns list of IPV6 addresses, or nil (there should only be one IPV6 address)
39 40 41 42 43 44 |
# File 'lib/rubymta/extended_classes.rb', line 39 def dig_aaaa Resolv::DNS.open do |dns| txts = dns.getresources(self,Resolv::DNS::Resource::IN::AAAA).collect { |r| r.address.to_s.downcase } if txts.empty? then nil else txts[0] end end end |
#dig_dk ⇒ Object
returns a publibdomainkey, or nil (there should only be one DKIM public key)
83 84 85 86 87 88 |
# File 'lib/rubymta/extended_classes.rb', line 83 def dig_dk Resolv::DNS.open do |dns| txts = dns.getresources(self,Resolv::DNS::Resource::IN::TXT).collect { |r| r.strings } if txts.empty? then nil else txts[0][0] end end end |
#dig_mx ⇒ Object
returns list of MX names, or nil (there may be multiple MX names for a domain) WARNING: use the #dig_mxs to get the preferences also
49 50 51 52 53 54 |
# File 'lib/rubymta/extended_classes.rb', line 49 def dig_mx Resolv::DNS.open do |dns| txts = dns.getresources(self,Resolv::DNS::Resource::IN::MX).collect { |r| r.exchange.to_s } if txts.empty? then nil else txts end end end |
#dig_mxs ⇒ Object
returns a hash of { <preference> => [ <mx,ip>, … ] } preferences sorted in numerical order from low–>high (IOW, highest preference to lowest preference) if there is no mx, returns {} ex: “173.194.78.26”]],
20=>[["alt1.aspmx.l.google.com", "173.194.219.27"]],
30=>[["alt2.aspmx.l.google.com", "74.125.192.27"], ["alt3.aspmx.l.google.com", "74.125.141.27"]],
40=>[["alt4.aspmx.l.google.com", "64.233.190.26"]]
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/rubymta/extended_classes.rb', line 64 def dig_mxs mxs = {} Resolv::DNS.open do |dns| res = dns.getresources(self,Resolv::DNS::Resource::IN::MX) if res.size>0 res = res.sort {|a,b| a.preference<=>b.preference } res.each do |mx| mxs[mx.preference] ||= [] domain = mx.exchange.to_s ip = domain.dig_a mxs[mx.preference] << [domain,ip] end end end return mxs end |
#dig_ptr ⇒ Object
returns a reverse DNS hostname or nil
91 92 93 94 95 96 97 |
# File 'lib/rubymta/extended_classes.rb', line 91 def dig_ptr begin Resolv.new.getname(self.downcase) rescue Resolv::ResolvError nil end end |
#from_b(base = 62) ⇒ Object
this is used to convert numbers in the email IDs back to base 10
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# File 'lib/rubymta/base-x.rb', line 4 def from_b(base=62) n = 0 self.each_char do |ch| n = n*base m = ch.ord case when m>=97 k = m-61 when m>=65 k = m-55 when m>=48 k = m-48 end n += k end return n end |
#mta_live?(port) ⇒ Boolean
opens a socket to the IP/port to see if there is an SMTP server there - returns “250 …” if the server is there, or times out in 5 seconds to prevent hanging the process
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/rubymta/extended_classes.rb', line 126 def mta_live?(port) tcp_socket = nil welcome = nil begin Timeout.timeout(60) do begin tcp_socket = TCPSocket.open(self,port) rescue Errno::ECONNREFUSED => e return "421 Service not available (port closed)" end begin welcome = tcp_socket.gets return welcome if welcome[1]!='2' tcp_socket.write("QUIT\r\n") line = tcp_socket.gets return line if line[1]!='2' ensure tcp_socket.close if tcp_socket end end return "250 #{welcome.chomp[4..-1]}" rescue SocketError => e return "421 Service not available (#{e})" rescue Timeout::Error => e return "421 Service not available (#{e})" end end |
#utf8 ⇒ Object
returns a UTF-8 encoded string – be carefule using this with email: email has to be received and transported with NO changes, except the addition of extra headers at the beginning (before any DKIM headers)
119 120 121 |
# File 'lib/rubymta/extended_classes.rb', line 119 def utf8 self.encode('UTF-8', 'binary', :invalid => :replace, :undef => :replace, :replace => '?') end |
#validate_plain ⇒ Object
this validates a password with the base64 plaintext in an AUTH command encoded -> AGNvY29AY3phcm1haWwuY29tAG15LXBhc3N3b3Jk => [“[email protected]”, “my-password”] call UnixCrypt::SHA256.build(“my-password”) “my-password” –> “$5$BsHk6IIvndgdBmo9$iuO6WMaXzgzpGmGreV4uiH72VRGG1USNK/e5tL7P9jC” “AGNvY29AY3phcm1haWwuY29tAG15LXBhc3N3b3Jk”.validate_plain { “$5$BsHk6IIvndgdBmo9$iuO6WMaXzgzpGmGreV4uiH72VRGG1USNK/e5tL7P9jC” } => “[email protected]”, true
159 160 161 162 163 164 165 166 |
# File 'lib/rubymta/extended_classes.rb', line 159 def validate_plain # decode and split up the username and password) username, password = Base64::decode64(self).split("\x00")[1..-1] return "", false if username.nil? || password.nil? passwd_hash = yield(username) # get the hash return username, false if passwd_hash.nil? return username, UnixCrypt.valid?(password, passwd_hash) end |