2021-06-01 12:20:20 +00:00
|
|
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
2013-06-12 15:59:58 +00:00
|
|
|
|
2012-04-13 16:42:25 +00:00
|
|
|
require 'net/pop'
|
2012-04-10 14:06:46 +00:00
|
|
|
|
2015-08-28 00:53:14 +00:00
|
|
|
class Channel::Driver::Pop3 < Channel::EmailParser
|
2012-04-10 14:06:46 +00:00
|
|
|
|
2015-09-06 07:50:51 +00:00
|
|
|
=begin
|
|
|
|
|
|
|
|
fetch emails from Pop3 account
|
|
|
|
|
2016-01-10 13:24:54 +00:00
|
|
|
instance = Channel::Driver::Pop3.new
|
2015-09-06 07:50:51 +00:00
|
|
|
result = instance.fetch(params[:inbound][:options], channel, 'verify', subject_looking_for)
|
|
|
|
|
|
|
|
returns
|
|
|
|
|
|
|
|
{
|
|
|
|
result: 'ok',
|
|
|
|
fetched: 123,
|
|
|
|
notice: 'e. g. message about to big emails in mailbox',
|
|
|
|
}
|
|
|
|
|
|
|
|
check if connect to Pop3 account is possible, return count of mails in mailbox
|
|
|
|
|
2016-01-10 13:24:54 +00:00
|
|
|
instance = Channel::Driver::Pop3.new
|
2015-09-06 07:50:51 +00:00
|
|
|
result = instance.fetch(params[:inbound][:options], channel, 'check')
|
|
|
|
|
|
|
|
returns
|
|
|
|
|
|
|
|
{
|
|
|
|
result: 'ok',
|
|
|
|
content_messages: 123,
|
|
|
|
}
|
|
|
|
|
|
|
|
verify Pop3 account, check if search email is in there
|
|
|
|
|
2016-01-10 13:24:54 +00:00
|
|
|
instance = Channel::Driver::Pop3.new
|
2015-09-06 07:50:51 +00:00
|
|
|
result = instance.fetch(params[:inbound][:options], channel, 'verify', subject_looking_for)
|
|
|
|
|
|
|
|
returns
|
|
|
|
|
|
|
|
{
|
|
|
|
result: 'ok', # 'verify not ok'
|
|
|
|
}
|
|
|
|
|
|
|
|
=end
|
|
|
|
|
2017-10-02 11:23:14 +00:00
|
|
|
def fetch(options, channel, check_type = '', verify_string = '')
|
2014-11-18 21:09:01 +00:00
|
|
|
ssl = true
|
|
|
|
port = 995
|
2016-11-06 15:46:36 +00:00
|
|
|
if options.key?(:ssl) && options[:ssl] == false
|
2014-11-18 21:09:01 +00:00
|
|
|
ssl = false
|
|
|
|
port = 110
|
2013-01-04 23:14:08 +00:00
|
|
|
end
|
2016-12-02 11:24:00 +00:00
|
|
|
if options.key?(:port) && options[:port].present?
|
2016-11-10 23:04:10 +00:00
|
|
|
port = options[:port]
|
2016-12-02 11:24:00 +00:00
|
|
|
|
|
|
|
# disable ssl for non ssl ports
|
|
|
|
if port == 110 && !options.key?(:ssl)
|
|
|
|
ssl = false
|
|
|
|
end
|
2016-11-10 23:04:10 +00:00
|
|
|
end
|
2013-01-04 23:14:08 +00:00
|
|
|
|
2015-08-28 00:53:14 +00:00
|
|
|
Rails.logger.info "fetching pop3 (#{options[:host]}/#{options[:user]} port=#{port},ssl=#{ssl})"
|
2012-04-13 16:42:25 +00:00
|
|
|
|
2018-04-26 08:55:53 +00:00
|
|
|
@pop = ::Net::POP3.new(options[:host], port)
|
2015-09-06 07:50:51 +00:00
|
|
|
#@pop.set_debug_output $stderr
|
2014-11-16 22:45:57 +00:00
|
|
|
|
|
|
|
# on check, reduce open_timeout to have faster probing
|
2017-01-04 12:36:52 +00:00
|
|
|
@pop.open_timeout = 16
|
2017-01-09 14:47:47 +00:00
|
|
|
@pop.read_timeout = 45
|
2014-11-16 22:45:57 +00:00
|
|
|
if check_type == 'check'
|
2014-11-18 11:51:35 +00:00
|
|
|
@pop.open_timeout = 4
|
2014-11-16 22:45:57 +00:00
|
|
|
@pop.read_timeout = 6
|
|
|
|
end
|
|
|
|
|
2013-01-04 23:14:08 +00:00
|
|
|
if ssl
|
2014-11-16 22:45:57 +00:00
|
|
|
@pop.enable_ssl(OpenSSL::SSL::VERIFY_NONE)
|
2013-01-04 23:14:08 +00:00
|
|
|
end
|
2015-09-06 07:50:51 +00:00
|
|
|
@pop.start(options[:user], options[:password])
|
|
|
|
|
|
|
|
mails = @pop.mails
|
|
|
|
|
2014-10-22 21:00:11 +00:00
|
|
|
if check_type == 'check'
|
2015-05-04 19:34:04 +00:00
|
|
|
Rails.logger.info 'check only mode, fetch no emails'
|
2015-09-06 07:50:51 +00:00
|
|
|
content_max_check = 2
|
|
|
|
content_messages = 0
|
|
|
|
|
|
|
|
# check messages
|
|
|
|
mails.each do |m|
|
|
|
|
mail = m.pop
|
|
|
|
next if !mail
|
|
|
|
|
|
|
|
# check how many content messages we have, for notice used
|
2021-05-12 11:37:44 +00:00
|
|
|
if !mail.match?(%r{(X-Zammad-Ignore: true|X-Zammad-Verify: true)})
|
2015-09-06 07:50:51 +00:00
|
|
|
content_messages += 1
|
|
|
|
break if content_max_check < content_messages
|
|
|
|
end
|
|
|
|
end
|
2015-09-06 11:39:16 +00:00
|
|
|
if content_messages >= content_max_check
|
2015-09-06 07:50:51 +00:00
|
|
|
content_messages = mails.count
|
|
|
|
end
|
2014-10-22 21:00:11 +00:00
|
|
|
disconnect
|
2015-09-06 07:50:51 +00:00
|
|
|
return {
|
2018-12-19 17:31:51 +00:00
|
|
|
result: 'ok',
|
2015-09-06 07:50:51 +00:00
|
|
|
content_messages: content_messages,
|
|
|
|
}
|
2014-10-22 21:00:11 +00:00
|
|
|
end
|
2014-11-09 20:18:13 +00:00
|
|
|
|
|
|
|
# reverse message order to increase performance
|
|
|
|
if check_type == 'verify'
|
2015-09-06 07:50:51 +00:00
|
|
|
Rails.logger.info 'verify mode, fetch no emails'
|
2014-11-09 20:18:13 +00:00
|
|
|
mails.reverse!
|
2012-04-13 17:06:09 +00:00
|
|
|
|
2014-10-22 21:00:11 +00:00
|
|
|
# check for verify message
|
2019-01-14 14:53:26 +00:00
|
|
|
mails.first(2000).each do |m|
|
2014-10-22 21:00:11 +00:00
|
|
|
mail = m.pop
|
2015-09-06 07:50:51 +00:00
|
|
|
next if !mail
|
|
|
|
|
|
|
|
# check if verify message exists
|
2021-05-12 11:37:44 +00:00
|
|
|
next if !mail.match?(%r{#{verify_string}})
|
2018-10-09 06:17:41 +00:00
|
|
|
|
2015-09-06 11:39:16 +00:00
|
|
|
Rails.logger.info " - verify email #{verify_string} found"
|
|
|
|
m.delete
|
|
|
|
disconnect
|
|
|
|
return {
|
|
|
|
result: 'ok',
|
|
|
|
}
|
2015-09-06 07:50:51 +00:00
|
|
|
end
|
2014-10-22 21:00:11 +00:00
|
|
|
|
2015-09-06 07:50:51 +00:00
|
|
|
return {
|
|
|
|
result: 'verify not ok',
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
# fetch regular messages
|
2019-04-30 07:27:32 +00:00
|
|
|
count_all = mails.size
|
|
|
|
count = 0
|
|
|
|
count_fetched = 0
|
2019-08-06 15:26:29 +00:00
|
|
|
too_large_messages = []
|
2019-04-30 07:27:32 +00:00
|
|
|
active_check_interval = 20
|
|
|
|
notice = ''
|
2019-01-14 14:53:26 +00:00
|
|
|
mails.first(2000).each do |m|
|
2015-09-06 07:50:51 +00:00
|
|
|
count += 1
|
2019-04-30 07:27:32 +00:00
|
|
|
|
2020-09-30 09:07:01 +00:00
|
|
|
break if (count % active_check_interval).zero? && channel_has_changed?(channel)
|
2019-04-30 07:27:32 +00:00
|
|
|
|
2015-09-06 07:50:51 +00:00
|
|
|
Rails.logger.info " - message #{count}/#{count_all}"
|
|
|
|
mail = m.pop
|
2015-09-06 11:39:16 +00:00
|
|
|
next if !mail
|
2015-09-06 07:50:51 +00:00
|
|
|
|
2019-01-14 14:53:26 +00:00
|
|
|
# ignore verify messages
|
2021-05-12 11:37:44 +00:00
|
|
|
if mail.match?(%r{(X-Zammad-Ignore: true|X-Zammad-Verify: true)}) && mail =~ %r{X-Zammad-Verify-Time:\s(.+?)\s}
|
2020-09-30 09:07:01 +00:00
|
|
|
begin
|
|
|
|
verify_time = Time.zone.parse($1)
|
|
|
|
if verify_time > Time.zone.now - 30.minutes
|
|
|
|
info = " - ignore message #{count}/#{count_all} - because it's a verify message"
|
|
|
|
Rails.logger.info info
|
|
|
|
next
|
2019-01-14 14:53:26 +00:00
|
|
|
end
|
2020-09-30 09:07:01 +00:00
|
|
|
rescue => e
|
|
|
|
Rails.logger.error e
|
2019-01-14 14:53:26 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-08-06 15:26:29 +00:00
|
|
|
# do not process too large messages, instead download and send postmaster reply
|
2015-09-06 11:39:16 +00:00
|
|
|
max_message_size = Setting.get('postmaster_max_size').to_f
|
2015-09-06 07:50:51 +00:00
|
|
|
real_message_size = mail.size.to_f / 1024 / 1024
|
|
|
|
if real_message_size > max_message_size
|
2019-08-06 15:26:29 +00:00
|
|
|
if Setting.get('postmaster_send_reject_if_mail_too_large') == true
|
|
|
|
info = " - download message #{count}/#{count_all} - ignore message because it's too large (is:#{real_message_size} MB/max:#{max_message_size} MB)"
|
|
|
|
Rails.logger.info info
|
|
|
|
notice += "#{info}\n"
|
|
|
|
process_oversized_mail(channel, mail)
|
|
|
|
else
|
|
|
|
info = " - ignore message #{count}/#{count_all} - because message is too large (is:#{real_message_size} MB/max:#{max_message_size} MB)"
|
|
|
|
Rails.logger.info info
|
|
|
|
notice += "#{info}\n"
|
|
|
|
too_large_messages.push info
|
|
|
|
next
|
|
|
|
end
|
2015-09-06 07:50:51 +00:00
|
|
|
|
|
|
|
# delete email from server after article was created
|
2019-08-06 15:26:29 +00:00
|
|
|
else
|
|
|
|
process(channel, m.pop, false)
|
|
|
|
end
|
|
|
|
|
2016-11-07 22:20:58 +00:00
|
|
|
m.delete
|
|
|
|
count_fetched += 1
|
2012-04-13 16:42:25 +00:00
|
|
|
end
|
2014-06-22 07:00:09 +00:00
|
|
|
disconnect
|
2016-01-16 10:05:04 +00:00
|
|
|
if count.zero?
|
2015-05-04 19:34:04 +00:00
|
|
|
Rails.logger.info ' - no message'
|
2012-04-13 17:06:09 +00:00
|
|
|
end
|
2019-08-06 15:26:29 +00:00
|
|
|
|
|
|
|
if too_large_messages.present?
|
|
|
|
raise too_large_messages.join("\n")
|
|
|
|
end
|
|
|
|
|
2015-05-04 19:34:04 +00:00
|
|
|
Rails.logger.info 'done'
|
2015-09-06 07:50:51 +00:00
|
|
|
{
|
2018-12-19 17:31:51 +00:00
|
|
|
result: 'ok',
|
2015-09-06 07:50:51 +00:00
|
|
|
fetched: count_fetched,
|
2018-12-19 17:31:51 +00:00
|
|
|
notice: notice,
|
2015-09-06 07:50:51 +00:00
|
|
|
}
|
2012-04-13 16:42:25 +00:00
|
|
|
end
|
2014-06-22 07:00:09 +00:00
|
|
|
|
2016-01-10 13:24:54 +00:00
|
|
|
=begin
|
|
|
|
|
|
|
|
instance = Channel::Driver::Pop3.new
|
|
|
|
instance.fetchable?(channel)
|
|
|
|
|
|
|
|
=end
|
|
|
|
|
|
|
|
def fetchable?(_channel)
|
|
|
|
true
|
|
|
|
end
|
|
|
|
|
2017-10-02 11:23:14 +00:00
|
|
|
=begin
|
|
|
|
|
|
|
|
Channel::Driver::Pop3.streamable?
|
|
|
|
|
|
|
|
returns
|
|
|
|
|
|
|
|
true|false
|
|
|
|
|
|
|
|
=end
|
|
|
|
|
|
|
|
def self.streamable?
|
|
|
|
false
|
|
|
|
end
|
|
|
|
|
2019-04-30 07:27:32 +00:00
|
|
|
=begin
|
|
|
|
|
|
|
|
check if channel config has changed
|
|
|
|
|
|
|
|
Channel::Driver::IMAP.channel_has_changed?(channel)
|
|
|
|
|
|
|
|
returns
|
|
|
|
|
|
|
|
true|false
|
|
|
|
|
|
|
|
=end
|
|
|
|
|
|
|
|
def channel_has_changed?(channel)
|
|
|
|
current_channel = Channel.find_by(id: channel.id)
|
|
|
|
if !current_channel
|
|
|
|
Rails.logger.info "Channel with id #{channel.id} is deleted in the meantime. Stop fetching."
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
return false if channel.updated_at == current_channel.updated_at
|
|
|
|
|
|
|
|
Rails.logger.info "Channel with id #{channel.id} has changed. Stop fetching."
|
|
|
|
true
|
|
|
|
end
|
|
|
|
|
2014-06-22 07:00:09 +00:00
|
|
|
def disconnect
|
2015-04-30 15:25:04 +00:00
|
|
|
return if !@pop
|
2018-10-09 06:17:41 +00:00
|
|
|
|
2015-04-30 15:25:04 +00:00
|
|
|
@pop.finish
|
2014-06-22 07:00:09 +00:00
|
|
|
end
|
|
|
|
|
2015-04-27 14:15:29 +00:00
|
|
|
end
|