Class: Percolate::Responder
- Inherits:
-
Object
- Object
- Percolate::Responder
- Defined in:
- lib/percolate/responder.rb
Overview
This is the bit that actually handles the SMTP conversation with the client. Basically, you send it commands, and it acts on them. There is a small amount of Rubyish magic but that’s there mainly because I’m lazy. And besides, if I weren’t lazy, some guys on IRC would flame me. Haha! I kid. Greetz to RubyPanther by the wya. Even though I know you’ve never contributed anything and never will, at least you can live with the satisfaction that you don’t have to deal with my evil racist ass any more.
Instance Method Summary collapse
-
#command(offered_command) ⇒ Object
Send an SMTP command to the responder.
-
#initialize(mailhostname, opts = {}) ⇒ Responder
constructor
Sets up the new smtp responder, with the parameter “mailhostname” as the SMTP hostname (as returned in the response to the SMTP HELO command.) Note that “mailhostname” can be anything at all, because I no longer believe that it’s possible to actually figure out your own full hostname without actually literally being told it.
-
#process_message(message_object) ⇒ Object
This is one of the methods you have to override in a subclass in order to use this class properly (unless chuckmail really is acceptable for you, in which case excellent! Also its default behaviour is to pretend to be an open relay, which should delight spammers until they figure out that all of their mail is being silently and cheerfully discarded, but they’re spammers so they won’t).
-
#response ⇒ Object
Returns the response from the server.
-
#sender ⇒ Object
The current message’s sender, if the MAIL FROM: command has been processed yet.
-
#validate_recipient(address) ⇒ Object
Override this if you care about the recipient (which you should).
-
#validate_sender(address) ⇒ Object
Override this if you care about who the sender is (you probably do care who the sender is).
Constructor Details
#initialize(mailhostname, opts = {}) ⇒ Responder
Sets up the new smtp responder, with the parameter “mailhostname” as the SMTP hostname (as returned in the response to the SMTP HELO command.) Note that “mailhostname” can be anything at all, because I no longer believe that it’s possible to actually figure out your own full hostname without actually literally being told it. This is probably excessively-cynical of me, but I’ve seen what happens when wide-eyed optimists try to guess hostnames, and it just isn’t pretty.
Let’s just leave it at “mailhostname is a required parameter”, shall we?
Also, there are some interesting options you can give this. Well, only a couple. The first is :debug which you can set to true or false, which will cause it to print the SMTP conversation out. This is, of course, mostly only useful for debugging.
The other option, :originating_ip, probably more interesting, comes from the listener–the IP address of the client that connected.
63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/percolate/responder.rb', line 63 def initialize(mailhostname, opts={}) @verbose_debug = opts[:debug] @originating_ip = opts[:originating_ip] @mailhostname = mailhostname @current_state = nil @current_command = nil @response = connect @mail_object=nil @debug_output = [] debug "\n\n" end |
Instance Method Details
#command(offered_command) ⇒ Object
Send an SMTP command to the responder. Use this to send a line of input to the responder (including a single line of DATA).
Parameters:
offered_command
-
The SMTP command (with end-of-line characters removed)
152 153 154 155 156 157 158 159 |
# File 'lib/percolate/responder.rb', line 152 def command offered_command debug ">>> #{offered_command}" begin dispatch offered_command rescue ResponderError => error @response = error. end end |
#process_message(message_object) ⇒ Object
This is one of the methods you have to override in a subclass in order to use this class properly (unless chuckmail really is acceptable for you, in which case excellent! Also its default behaviour is to pretend to be an open relay, which should delight spammers until they figure out that all of their mail is being silently and cheerfully discarded, but they’re spammers so they won’t).
Parameters:
message_object
-
A SMTP::MessageObject object, with envelope data and the message itself (which could, as the RFC says, be any old crap at all! Don’t even expect an RFC2822-formatted message)
89 90 91 |
# File 'lib/percolate/responder.rb', line 89 def return "250 accepted, SMTP id is #{@mail_object.smtp_id}" end |
#response ⇒ Object
Returns the response from the server. When there’s no response, returns nil.
I still haven’t figured out what to do when there’s more than one response (like in the case of an ESMTP capabilities list).
138 139 140 141 142 143 |
# File 'lib/percolate/responder.rb', line 138 def response resp = @response @response = nil debug "<<< #{resp}" resp end |
#sender ⇒ Object
The current message’s sender, if the MAIL FROM: command has been processed yet. If it hasn’t, then it returns nil, and probably isn’t meaningful anyway.
126 127 128 129 130 |
# File 'lib/percolate/responder.rb', line 126 def sender if @mail_object @mail_object.envelope_from end end |
#validate_recipient(address) ⇒ Object
Override this if you care about the recipient (which you should). When you get to this point, the accessor “sender” will work to return the sender, so that you can deal with both recipient and sender here.
119 120 121 |
# File 'lib/percolate/responder.rb', line 119 def validate_recipient address return true, "ok" end |
#validate_sender(address) ⇒ Object
Override this if you care about who the sender is (you probably do care who the sender is).
Incidentally, you probably Do Not Want To Become An Open Spam Relay–you really should validate both senders and recipients, and only accept mail if:
(a) the sender is local, and the recipient is remote, or (b) the sender is remote, and the recipient is local.
The definition of “local” and “remote” are, of course, up to you–if you’re using this to handle mail for a hundred domains, then all those hundred domains are local for you–but the idea is that you shoud be picky about who your mail is from and to.
This method takes one argument:
address
-
The email address you’re validating
111 112 113 |
# File 'lib/percolate/responder.rb', line 111 def validate_sender address return true, "ok" end |