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
# 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

  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_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



123
124
125
# File 'lib/remailer/smtp/server.rb', line 123

def check_for_timeout!
  @interpreter.check_for_timeout!
end

#log(level, message) ⇒ Object



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

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

#on_transactionObject



79
80
81
# File 'lib/remailer/smtp/server.rb', line 79

def on_transaction
  @on_transaction = Proc.new
end

#post_initObject



69
70
71
72
73
74
75
76
77
# File 'lib/remailer/smtp/server.rb', line 69

def post_init
  super

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

#receive_line(line) ⇒ Object



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

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.



115
116
117
118
119
120
121
# File 'lib/remailer/smtp/server.rb', line 115

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

#remote_hostObject



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

def remote_host
  @remote_host
end

#send_line(line) ⇒ Object



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

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

#tls?Boolean

Returns:

  • (Boolean)


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

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

#unbindObject



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

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

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

Yields:

  • (true)


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

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