diff --git a/lib/quickml/config.rb b/lib/quickml/config.rb index 74a810f..7d9cbd3 100644 --- a/lib/quickml/config.rb +++ b/lib/quickml/config.rb @@ -56,6 +56,26 @@ def initialize (config = {}) @group = (config[:group] or "root") @use_qmail_verp = (config[:use_qmail_verp] or false) + @creator_check = (config[:creator_check] or false) + @creator_addresses = if config[:creator_addresses] + config[:creator_addresses] + else + [ @domain ] + end + @member_check = (config[:member_check] or false) + @member_addresses = if config[:member_addresses] + config[:member_addresses] + else + [ @domain ] + end + + @sender_check = (config[:sender_check] or false) + @sender_addresses = if config[:sender_addresses] + config[:sender_addresses] + else + [ @domain ] + end + charset = @catalog.charset if @catalog @content_type = "text/plain" diff --git a/lib/quickml/core.rb b/lib/quickml/core.rb index bf9cfbb..a6b2370 100644 --- a/lib/quickml/core.rb +++ b/lib/quickml/core.rb @@ -17,6 +17,9 @@ class QuickMLException < StandardError; end class TooLargeMail < QuickMLException; end class TooManyMembers < QuickMLException; end class InvalidMLName < QuickMLException; end + class InvalidCreator < QuickMLException; end + class InvalidMembers < QuickMLException; end + class InvalidSender < QuickMLException; end # It preserves case information. but it accepts an # address case-insensitively for member management. @@ -96,6 +99,13 @@ def initialize (config, address, creator = nil, message_charset = nil) @logger = @config.logger @catalog = @config.catalog + if @config.sender_check and !creator.nil? + raise InvalidSender unless valid_members?(creator, @config.sender_addresses) + end + if newly_created? and @config.creator_check and !creator.nil? + raise InvalidCreator unless valid_members?(creator, @config.creator_addresses) + end + init_ml_config init_members init_count @@ -114,6 +124,13 @@ def initialize (config, address, creator = nil, message_charset = nil) attr_reader :charset attr_reader :max_members + def valid_members? (address, pat) + pat.each do |entry| + return true if /#{entry}/i =~ address + end + false + end + def self.valid_name? (name) /^([0-9a-zA-Z_.-]+)(@[0-9a-zA-Z_.-]+)?$/ =~ name end @@ -607,6 +624,7 @@ def accept_confirmation begin add_member(address) rescue TooManyMembers + rescue InvalidMembers end } submit(mail) @@ -636,6 +654,9 @@ def remove_member (address) end def add_member (address) + if @config.member_check + raise InvalidMembers unless valid_members?(address, @config.member_addresses) + end if exclude?(address) @logger.vlog "Excluded: #{address}" return @@ -827,6 +848,29 @@ def report_too_many_members (ml, unadded_addresses) @logger.log "[#{ml.name}]: Too Many Members: #{address}" end + def report_invalid_members (ml, invalid_members) + header = [] + subject = Mail.encode_field(_("[QuickML] Error: %s", @mail["Subject"])) + header.push(["To", @mail.from], + ["From", ml.address], + ["Subject", subject], + ["Content-type", content_type]) + + body = _("The following addresses cannot be added because <%s> mailing list can join known members only.\n\n", + ml.address) + invalid_members.each {|address| + body << sprintf("<%s>\n", address) + } + + body << generate_footer + Mail.send_mail(@config.smtp_host, @config.smtp_port, @logger, + :mail_from => '', + :recipient => @mail.from, + :header => header, + :body => body) + @logger.log "[#{ml.name}]: Invalid Members by #{@mail.from}" + end + def report_invalid_mladdress (mladdress) header = [] subject = Mail.encode_field(_("[QuickML] Error: %s", @mail["Subject"])) @@ -846,6 +890,40 @@ def report_invalid_mladdress (mladdress) @logger.log "Invalid ML Address: #{mladdress}" end + def report_invalid_creator (mladdress) + header = [] + subject = Mail.encode_field(_("[QuickML] Error: %s", @mail["Subject"])) + header.push(["To", @mail.from], + ["From", @config.postmaster], + ["Subject", subject], + ["Content-type", content_type]) + body = _("Invalid Creator: <%s> by <%s>.\n", mladdress, @mail.from) + body << generate_footer + Mail.send_mail(@config.smtp_host, @config.smtp_port, @logger, + :mail_from => '', + :recipient => @mail.from, + :header => header, + :body => body) + @logger.log "Invalid Creator: #{mladdress} by #{@mail.from}" + end + + def report_invalid_sender (mladdress) + header = [] + subject = Mail.encode_field(_("[QuickML] Error: %s", @mail["Subject"])) + header.push(["To", @mail.from], + ["From", @config.postmaster], + ["Subject", subject], + ["Content-type", content_type]) + body = _("Invalid Sender: <%s> by <%s>.\n", mladdress, @mail.from) + body << generate_footer + Mail.send_mail(@config.smtp_host, @config.smtp_port, @logger, + :mail_from => '', + :recipient => @mail.from, + :header => header, + :body => body) + @logger.log "Invalid Sender: #{mladdress} by #{@mail.from}" + end + def mail_log @logger.vlog "MAIL FROM:<#{@mail.mail_from}>" @mail.recipients.each {|recipient| @@ -868,6 +946,8 @@ def add_member (ml, address) ml.add_member(address) rescue TooManyMembers @unadded_addresses.push(address) + rescue InvalidMembers + @invalid_members.push(address) end end @@ -879,6 +959,7 @@ def ml_address_in_to? (ml) def submit_article (ml) @unadded_addresses = [] + @invalid_members = [] if ml_address_in_to?(ml) add_member(ml, @mail.from) @mail.collect_cc.each {|address| @@ -888,6 +969,9 @@ def submit_article (ml) unless @unadded_addresses.empty? report_too_many_members(ml, @unadded_addresses) end + unless @invalid_members.empty? + report_invalid_members(ml, @invalid_members) + end ml.submit(@mail) end @@ -937,7 +1021,8 @@ def acceptable_submission? (ml) ml.newly_created? or ml.active_members.include?(@mail.from) or ml.former_members.include?(@mail.from) or - sender_knows_an_active_member?(ml) + sender_knows_an_active_member?(ml) or + @config.sender_check end def confirmation_required? (ml) @@ -991,6 +1076,10 @@ def process_recipient (recipient) } rescue InvalidMLName report_invalid_mladdress(mladdress) + rescue InvalidCreator + report_invalid_creator(mladdress) + rescue InvalidSender + report_invalid_sender(mladdress) end end end diff --git a/messages.ja b/messages.ja index 9da65c8..68edb85 100644 --- a/messages.ja +++ b/messages.ja @@ -92,6 +92,16 @@ Messages = { "Please simply reply this mail to create ML <%s>.\n" => "このメールに返信すると <%s> メーリングリストが作られます。\n", + + "Invalid Creator: <%s> by <%s>.\n" => + "<%s> メーリングリストは <%s> には作成できません。\n", + + "Invalid Sender: <%s> by <%s>.\n" => + "<%s> メーリングリストに <%s> は投稿できません。\n", + + "The following addresses cannot be added because <%s> mailing list can join known members only.\n\n" => + "<%s> メーリングリストは参加できるメンバーが制限されているので、以下のアドレスは追加できませんでした。\n\n", + } Charset = "iso-2022-jp" diff --git a/quickmlrc.sample.in b/quickmlrc.sample.in index 89fd277..350a4cc 100644 --- a/quickmlrc.sample.in +++ b/quickmlrc.sample.in @@ -31,4 +31,19 @@ Config = { # :message_catalog => nil # for English messages :message_catalog => '%DATADIR%/messages.ja', + + :creator_check => false, + :creator_addresses => [ + '^.+@example\.net$', + ], + + :member_check => false, + :member_addresses => [ + '^.+@example\.net$', + ], + + :sender_check => false, + :sender_addresses => [ + '^.+@example\.net$', + ], }