免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 4322 | 回复: 17
打印 上一主题 下一主题

[Mail] 请教一段代码,关于mimedefang [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-05-28 13:23 |只看该作者 |倒序浏览
以前没有学过perl,现在突然领导给一个任务,用mimedefang做sendmail的milter,对邮件组的发送权限进行控制,
昨天临时看了一下perl,在mimedefang-filter中加了一段代码,但是测试时,所有人都不能对all组发邮件了,
说明:我的思路是,先对收件人进行检查,如果收件人是all@rhel4.local,则再检查发件人是不是在文件all_allow内,如果不在就REJECT.
         如果收件人不是all@rhel4.local则直接放行。以是下代码:


  1. sub filter_recipient {
  2.     use strict;
  3.     my ($recipient, $sender, $ip, $hostname, $first, $helo,$rcpt_mailer, $rcpt_host, $rcpt_addr) = @_;
  4.     if ($recipient =~ /^<?all\@rhel4\.local>?$/i) {
  5.         open (FILE,'/etc/mail/all_allow') || die "Can't open file:$!\n";
  6.         while ($line = <FILE>) {
  7.                 if ($line =~ /$sender/) {
  8.                    return ('CONTINUE', "ok");
  9.                     }
  10.                 return ('REJECT', 'Sorry; you are not allowed to mail to [email]all@rhel4.local[/email]');
  11.                 }
  12.         }
  13.     return ('CONTINUE', "ok");
  14. }
复制代码

各位有谁接触过mimedefang,指点一下吧,谢谢!

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
2 [报告]
发表于 2008-05-28 14:07 |只看该作者
# 在 SMTP rcpt to 指令後, mimedefang 做這個 sub
sub filter_recipient {
    use strict;
# mimedefang 固定傳給此 sub 之參數
    my ($recipient, $sender, $ip, $hostname, $first, $helo,$rcpt_mailer, $rcpt_host, $rcpt_addr) = @_;
# 收件人(一封信有時會有很多收件人,一個 rcpt to 會觸發一起此  sub )若含有 all@....  (@ 是 perl 的限制字元,所以要用 \@)
    if ($recipient =~ /^<?all\@rhel4\.local>?$/i) {
# 開啟一個檔案
        open (FILE,'/etc/mail/all_allow') || die "Can't open file!\n";
# 循序讀檔
        while ($line = <FILE> {
# 該行若有寄件人,則表示可以寄給 all@.. , 此處有個小地方要注意, $sender 若沒有限制,容易形成問題
                if ($line =~ /$sender/) {
                   return ('CONTINUE', "ok";
                    }
#若無則拒絕
                return ('REJECT', 'Sorry; you are not allowed to mail to all@rhel4.local');
                }
        }
#沒有寄給 all@... 就直接 ok 了
    return ('CONTINUE', "ok";
}

论坛徽章:
0
3 [报告]
发表于 2008-05-28 14:25 |只看该作者
原帖由 abel 于 2008-5-28 14:07 发表
# 在 SMTP rcpt to 指令後, mimedefang 做這個 sub
sub filter_recipient {
    use strict;
# mimedefang 固定傳給此 sub 之參數
    my ($recipient, $sender, $ip, $hostname, $first, $helo,$rcpt_mai ...



谢谢回复,你说的all包括在收件中这样的情况我真还没有考虑到,谢谢提醒!不过我刚才有人给我指出这个段代码,他说只有被匹配的sender在all_allow的第一行才能返回'CONTINUE', "ok",如果不在第一行,即使是在all_allow列表中,也不会返回'CONTINUE', "ok"的,我的错应该就在从表中查找sender这一环节上,以前从未接触过perl,不知道应该怎么查?

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
4 [报告]
发表于 2008-05-28 14:27 |只看该作者
一個我自己的例子, 實際運行中:



  1. sub filter_sender {
  2. # .....略, 以下取列表, 非公開的 (NO)僅限制只有成員用員工可以寄
  3. my $sql="select list from mailing where PUBLIC='NO'";
  4. $restrict=mysql_query($sql);

  5. }

  6. sub filter_recipient {
  7. my ($recip, $sender, $ip, $hostname, $first, $helo, $rcpt_mailer, $rcpt_host, $rcpt_addr) = @_;

  8. # 取得 sender 的 Local_Part
  9. $sender=~ m/\<(.*)@.*\>/;
  10. $From=$1;
  11. $sender=~ m/\<(.*)\>/;
  12. $sender=$1;

  13. # 取得 RCPT TO 的 Local-Part
  14. $recip=~ m/\<(.*)@.*\>/;
  15. my $To=$1;

  16. # 下列 IP 或特別的 Envelope From 到特別的 TO 不進行檢查動作
  17. return ('CONTINUE', "ok") if ($ip=~/$my_network/); # 我自己的網路時,不做檢查
  18. return ('CONTINUE', "ok") if($sender=~/enews.enews4u.com/ and $recip=~/all\@abc.tw/); # 特別允許 enews 可以寄 all
  19. return ('CONTINUE', "ok") if ($sender=~ /ntu.edu.tw/ and $recip=~/all@/);

  20. # 如果 RCPT TO 是一個受保護的 Aliases , 進行檢查
  21. if ($restrict=~ / $To /) {
  22.         # aliases.pl 回應 aliases 中的 user list
  23.         $member=`/usr/bin/aliases.pl $To`;
  24.         # 比對 user list 中是否含有 envelope from
  25.         if ($member=~ /$sender/ ) {
  26.                 return ('CONTINUE', "ok");
  27.         } else {
  28.                 return ('REJECT', "$recip restrict for member or staff only.");
  29.         }
  30. }
  31. return ('CONTINUE', "Ok");
  32. }

复制代码


  1. # aliases.pl 程式, aliases 會有 rescurive 之狀況,需注意
  2. #!/usr/bin/perl

  3. use DB_File;
  4. print aliases_lookup($ARGV[0]);


  5. use DB_File;

  6. sub aliases_lookup()
  7. {
  8. my $user=$_;
  9. dbmopen(ALIASES,'/etc/aliases.db',0000) || die "can't dbmopen aliases";
  10. chop($host = `hostname`);
  11. while ($user = shift) {
  12.     local(%seen);
  13.     if ($short) {
  14.         return " ".join(' ', &resolve($user))." ";
  15.     } else {
  16.         return  " ".join(' ', sort &resolve($user))." ";
  17.     }
  18. }
  19. dbmclose(ALIASES);
  20. }
  21. sub resolve {
  22.     local($addr,$alias,@list,@ilist);

  23.     while ($addr = shift) {
  24.         if ($seen{$addr}++) {
  25.             #push(@list, $addr);
  26.             next;
  27.         }
  28.         $addr .= "\0";
  29.         unless (defined $ALIASES{$addr}) {
  30.             push(@list, &forward($addr));
  31.             next;
  32.         }
  33.         $alias = $ALIASES{$addr};
  34.         $alias =~ s/^\s*(.*)\s*$/$1/;
  35.         if ($alias eq $addr) {
  36.             push(@list, &forward($addr));
  37.             next;
  38.         }
  39.         if ($alias =~ /^"/) {
  40.             push(@list, $alias);
  41.             next;
  42.         }
  43.         if ($alias eq "$addr@$host") {
  44.             push(@list, &forward($addr));
  45.             next;
  46.         }
  47.         if ($alias =~ /^:include:(.*)/) {
  48.             unless (open(INC, $file = $1)) {
  49.                 print STDERR "$0: can't open $file: $!\n";
  50.                 next;
  51.             }
  52.             @ilist = grep(!/^#/, <INC>);
  53.             for (@ilist) { s/\s//g; }
  54.             close(INC);
  55.             push(@list,&resolve(@ilist));
  56.         } else {
  57.             push(@list,&resolve(split(/\s*,\s*/,$alias)));
  58.         }
  59.     }
  60.     return map { /([^\0]+)/ } @list;
  61. }


  62. ##############################################################

  63. sub forward {
  64.      local($user) = @_;
  65.      local($forward);

  66.      return $user if $user =~ /^\s*"?[|\/]/;
  67.      return $user if $user =~ /^\s*.+@.+$/;
  68.      return $user if $user =~ /^\s*.+\\?!.+$/;
  69.      return $user if $user =~ /^\s*\\/;

  70.      $user = "$user <MAILER-DAEMON>" unless $forward;
  71.      return $user;

  72. }

  73. ##############################################################

  74. sub logdir {
  75.     if (! $been_here_before++) {
  76.         setpwent unless $dbm_passwd = dbmopen(PASSWD,'/etc/passwd', undef);
  77.     }

  78.     if ($dbm_passwd) {
  79.         return '' unless defined $PASSWD{$_[0]};
  80.         local(@a);
  81.         @a = split(/[\000]+/,$PASSWD{$_[0]});
  82.         return $a[$#a-1];
  83.     } else {
  84.         return (getpwnam($_[0]))[7];
  85.     }
  86. }

复制代码

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
5 [报告]
发表于 2008-05-28 14:32 |只看该作者
在你的 open 處,改成

  1. #前略
  2.   open (FILE,'/etc/mail/all_allow') || die "Can't open file:$!\n";
  3. -        while ($line = <FILE>) {
  4. +      $sender=~s/[<>]//;  # 要去掉 < , > 字符,因為你的 all 裏很可能沒有 <, >
  5. +       @lines=<FILE>;
  6. +       if (join(@lines(" ",@lines)=~/$sender/i) {
  7. -                if ($line =~ /$sender/) {
  8.                    return ('CONTINUE', "ok");
  9.                     }
  10. +        else {     
  11.                 return ('REJECT', 'Sorry; you are not allowed to mail to [email]all@rhel4.local[/email]');
  12.                 }
复制代码


最後,提醒您,利用 md_syslog('info',"Your Debug Messagesender $recip"; 等方式來除錯

论坛徽章:
0
6 [报告]
发表于 2008-05-28 14:36 |只看该作者

回复 #4 abel 的帖子

哎呀,我遇到偶像了,你是用数据库来存放要查询的列表?我领导就要求我用MIMEDEFANG做这些,由于不会perl,就决定先做一个不用数据库的,然后学习perl,再进行下一步。以后得多向你请教了,谢谢!
不多说了,还是先研究一下你的实现方法吧,3Q!

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
7 [报告]
发表于 2008-05-28 15:00 |只看该作者
還有 N 種方式可以達到你的需求
像在 open 後用

if ( grep(/^$sender$/, <FILE>)

论坛徽章:
0
8 [报告]
发表于 2008-05-28 16:15 |只看该作者
可惜呀,我住在金屋子里,却看不到金子,还在拼命的找金子,以后得努力把perl学好才行。新到公司上班,但愿领导能多给点时间吧。
对了,abel:你说的[code]利用 md_syslog('info',"Your Debug Messagesender $recip"; 等方式來除錯[/code]
是把这句话加到代码的中间吗?

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
9 [报告]
发表于 2008-05-28 16:54 |只看该作者
原帖由 sunrocs 于 2008-5-28 16:15 发表
可惜呀,我住在金屋子里,却看不到金子,还在拼命的找金子,以后得努力把perl学好才行。新到公司上班,但愿领导能多给点时间吧。
对了,abel:你说的[code]利用 md_syslog('info',"Your Debug Messagesender $ ...

是的,加入你想要加的任何一處都可以
它會把訊息寫到 syslog 中, $SyslogFacility="???"  (? 為自己設,例如 mail/local[0-7]/auth/cron......

论坛徽章:
0
10 [报告]
发表于 2008-05-28 17:57 |只看该作者
晕死,走了很弯路,mimedefang用的filter文件是/etc/mail/mimedefang-filter,我一直在改/etc/mimedefang-filter,我说怎么一点作用都没有呢

#前略
  open (FILE,'/etc/mail/all_allow') || die "Can't open file!\n";
-        while ($line = <FILE> {
+      $sender=~s/[<>]//;  # 要去掉 < , > 字符,因為你的 all 裏很可能沒有 <, >
+       @lines=<FILE>;
+       if (join(@lines(" ",@lines)=~/$sender/i) {
-                if ($line =~ /$sender/) {
                   return ('CONTINUE', "ok";
                    }
+        else {     
                return ('REJECT', 'Sorry; you are not allowed to mail to all@rhel4.local');
                }


红色的那句是什么意思呀,没看太懂?那句老是报错,是不是少一个“)”,但是加上也报错。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP