Class: Remailer::SMTP::Server

Inherits:
EventMachine::Protocols::LineAndTextProtocol
  • Object
show all
Includes:
Constants
Defined in:
lib/remailer/smtp/server.rb

Defined Under Namespace

Classes: Interpreter, Transaction

Constant Summary collapse

DEFAULT_BIND_ADDR =

Constants ============================================================

'0.0.0.0'.freeze

Constants included from Constants

Constants::CRLF, Constants::IMAPS_PORT, Constants::LINE_REGEXP, Constants::SMTP_PORT, Constants::SOCKS5_PORT

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = nil) ⇒ Server

Instance Methods =====================================================



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/remailer/smtp/server.rb', line 53

def initialize(options = nil)
  super
  
  @options = options || { }

  @remote_port, @remote_ip = Socket.unpack_sockaddr_in(get_peername)
  @local_port, @local_ip = Socket.unpack_sockaddr_in(get_sockname)
  
  @server_name = @options[:server_name] || self.class.hostname(@local_ip) || @local_ip

  @logger = nil
  @remote_host = nil
  @tls_support = false
  @interpreter_class = options && options[:interpreter] || Interpreter

  log(:debug, "Connection from #{@remote_ip}:#{@remote_port} to #{@local_ip}:#{@local_port}")
  
  @on_transaction = @options[:on_transaction]
  @on_connect = @options[:on_connect]
end

Instance Attribute Details

#local_configObject (readonly)

Returns the value of attribute local_config.



24
25
26
# File 'lib/remailer/smtp/server.rb', line 24

def local_config
  @local_config
end

#local_ipObject (readonly)

Returns the value of attribute local_ip.



23
24
25
# File 'lib/remailer/smtp/server.rb', line 23

def local_ip
  @local_ip
end

#local_portObject (readonly)

Returns the value of attribute local_port.



23
24
25
# File 'lib/remailer/smtp/server.rb', line 23

def local_port
  @local_port
end

#loggerObject

Properties ===========================================================



20
21
22
# File 'lib/remailer/smtp/server.rb', line 20

def logger
  @logger
end

#private_key_pathObject

Returns the value of attribute private_key_path.



26
27
28
# File 'lib/remailer/smtp/server.rb', line 26

def private_key_path
  @private_key_path
end

#quirksObject (readonly)

Returns the value of attribute quirks.



21
22
23
# File 'lib/remailer/smtp/server.rb', line 21

def quirks
  @quirks
end

#remote_ipObject (readonly)

Returns the value of attribute remote_ip.



22
23
24
# File 'lib/remailer/smtp/server.rb', line 22

def remote_ip
  @remote_ip
end

#remote_nameObject (readonly)

Returns the value of attribute remote_name.



22
23
24
# File 'lib/remailer/smtp/server.rb', line 22

def remote_name
  @remote_name
end

#remote_portObject (readonly)

Returns the value of attribute remote_port.



22
23
24
# File 'lib/remailer/smtp/server.rb', line 22

def remote_port
  @remote_port
end

#server_nameObject (readonly)

Returns the value of attribute server_name.



21
22
23
# File 'lib/remailer/smtp/server.rb', line 21

def server_name
  @server_name
end

#ssl_cert_pathObject

Returns the value of attribute ssl_cert_path.



27
28
29
# File 'lib/remailer/smtp/server.rb', line 27

def ssl_cert_path
  @ssl_cert_path
end

Class Method Details

.bind(bind_addr = nil, port = nil, options = nil) ⇒ Object



42
43
44
45
46
47
48
49
# File 'lib/remailer/smtp/server.rb', line 42

def self.bind(bind_addr = nil, port = nil, options = nil)
  EventMachine.start_server(
    bind_addr || DEFAULT_BIND_ADDR,
    port || SMTP_PORT,
    self,
    options
  )
end

.hostname(ip) ⇒ Object

This returns the hostname for the specified IP if one is to be assigned. The default is to return the IP as-is, but this can be customized in a subclass.



34
35
36
# File 'lib/remailer/smtp/server.rb', line 34

def self.hostname(ip)
  ip
end

.hostname_for_ip(ip) ⇒ Object



38
39
40
# File 'lib/remailer/smtp/server.rb', line 38

def self.hostname_for_ip(ip)
  nil
end

Instance Method Details

#check_for_timeout!Object



128
129
130
# File 'lib/remailer/smtp/server.rb', line 128

def check_for_timeout!
  @interpreter.check_for_timeout!
end

#log(level, message) ⇒ Object



95
96
97
# File 'lib/remailer/smtp/server.rb', line 95

def log(level, message)
  @logger and @logger.send(level, message)
end

#on_transaction(&block) ⇒ Object



84
85
86
# File 'lib/remailer/smtp/server.rb', line 84

def on_transaction(&block)
  @on_transaction = block
end

#post_initObject



74
75
76
77
78
79
80
81
82
# File 'lib/remailer/smtp/server.rb', line 74

def post_init
  super

  @interpreter = @interpreter_class.new(delegate: self)
  
  if (@on_connect)
    @on_connect.call(@remote_ip)
  end
end

#receive_line(line) ⇒ Object



88
89
90
91
92
93
# File 'lib/remailer/smtp/server.rb', line 88

def receive_line(line)
  @interpreter.process(line)

rescue Object => e
  STDERR.puts("#{e.class}: #{e}")
end

#receive_transaction(transaction) ⇒ Object

This is called with the transaction state established by the SMTP client. The return value should be the response code and message sent back to the client.



120
121
122
123
124
125
126
# File 'lib/remailer/smtp/server.rb', line 120

def receive_transaction(transaction)
  if (@on_transaction)
    @on_transaction.call(transaction)
  end
  
  [ true, "250 Message received" ]
end

#remote_hostObject



113
114
115
# File 'lib/remailer/smtp/server.rb', line 113

def remote_host
  @remote_host
end

#send_line(line) ⇒ Object



105
106
107
# File 'lib/remailer/smtp/server.rb', line 105

def send_line(line)
  send_data(line + CRLF)
end

#tls?Boolean

Returns:

  • (Boolean)


109
110
111
# File 'lib/remailer/smtp/server.rb', line 109

def tls?
  ENV['TLS'] and self.private_key_path and self.ssl_cert_path
end

#unbindObject



99
100
101
102
103
# File 'lib/remailer/smtp/server.rb', line 99

def unbind
  super
  
  log(:debug, "Connection from #{@remote_ip} to #{@local_ip} closed")
end

#validate_hostname(remote_host) {|true| ... } ⇒ Object

Yields:

  • (true)


132
133
134
# File 'lib/remailer/smtp/server.rb', line 132

def validate_hostname(remote_host)
  yield(true) if (block_given?)
end