Chinaunix

标题: 修正Qmail auth smtp中电子邮件地址任意的patch [打印本页]

作者: gadfly    时间: 2003-04-05 18:15
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
qmail 的auth smtp有两个patch,
分别在:http://members.elysium.pl/brush/qmail-smtpd-auth/和www.nimh.org/hacks/qmail-smtpd.c。

不过都有个问题,就是auth 的用户可以和mail from的用户不一样,这样就
给了垃圾邮件发送者可乘之机,只要知道了某个用户的地址和口令,就可以
以自己的名义发信。同时认证用户的过程并不记录在邮件日志中,这给了系统管理员造成了很大不便,难以知道是哪个用户被黑掉了。

下面这个patch就是针对这种情况写的。

作用有两个:
1. 通过环境变量来控制是否记录认证过程。
2. 如果mail from和auth user name不一致,拒绝发送信件。


这个patch是基于www.nimh.org/hacks/qmail-smtpd.c,iceblood版本中实际上也是的这个。因此,用iceblood版本的可以直接使用。如果是用
http://members.elysium.pl/brush/qmail-smtpd-auth/版本的就需要自己
相应的修改了。

安装方法,如下,将下面这些内容存到qmail-smtpd.patch。放到qmail的源码目录。然后
1. patch < qmail-smtpd.patch
2. make qmail-smtpd
3. 替换qmail-smtpd
   或者复制到新的执行文件例如qmail-smtpd.auth,这样你的旧版本就能保留
  了,只需要在smtpd的启动脚本中,修改为对应的执行文件就可以。

如果你需要记录smtp认证的信息,在smtpd的启动脚本中定义环境变量,如下:
LOG_AUTH=1
export LOG_AUTH

缺省情况下,认证信息不记入log

--- qmail-smtpd.c       2003-04-05 17:55:20.000000000 -0500
+++ qmail-smtpd.c.new   2003-04-05 17:50:58.000000000 -0500
@@ -304,7 +304,11 @@
   if (!stralloc_copys(&rcptto,"") die_nomem();
   if (!stralloc_copys(&mailfrom,addr.s)) die_nomem();
   if (!stralloc_0(&mailfrom)) die_nomem();
+  if (smtp_auth_validfrom(mailfrom.s)) {
   out("250 ok\r\n";
+  } else {
+    out("must use username as From authenticated! (#5.7.1)\r\n";
+  }
}
void smtp_rcpt(arg) char *arg; {
   if (!seenmail) { err_wantmail(); return; }
@@ -527,6 +531,82 @@
static stralloc smtpauth = {0};
static char smtpauthlogin[65];
static char smtpauthpass[65];
+static int authd = 0;
+
+/* Author: gadfly@163.com.
+ * 1. Check consistent between auth user and 'From' user.
+ * 2. Read the LOG_AUTH enviroment variable to determine whether logging the auth info.
+ * LOG_AUTH=1, write the auth smtp info into syslog.
+ */
+#include <syslog.h>;
+
+#define SMTP_AUTH_SUCCESS     0
+#define SMTP_AUTH_FAILED      1
+
+int smtp_auth_validfrom(from) char * from;
+{
+  stralloc tmplogin={0},mydefaultdomain={0};
+  char authusername[256];
+  int k, userlen;
+
+  if (!authd) return 1;
+
+  authusername[255] = '\0';
+  userlen = k = str_len(smtpauthlogin);
+  k = byte_rchr(smtpauthlogin, k, '@');
+
+  if (k == userlen)
+  {
+    k = byte_rchr(smtpauthlogin, userlen, '%');
+
+    if (k == userlen)
+    {
+      if (control_readfile(&mydefaultdomain,"/var/qmail/control/me",1) != 1)
+      {
+        die_nomem();
+      }
+      if (!stralloc_copys(&tmplogin, smtpauthlogin) )
+      {
+        die_nomem();
+      }
+      if (!stralloc_cats(&tmplogin, "@" )
+      {
+        die_nomem();
+      }
+      if (!stralloc_cat(&tmplogin, &mydefaultdomain))
+      {
+        die_nomem();
+      }
+      strncpy(authusername, tmplogin.s, sizeof(authusername));
+      }
+      else
+      {
+        strcpy(authusername, smtpauthlogin);
+      authusername[k]='@';
+      }
+  }
+  else {
+    strcpy(authusername, smtpauthlogin);
+  }
+  return !strcasecmp(from, authusername);
+}
+
+
+void auth_smtplog(authlogin, authresult)
+char * authlogin;
+int authresult;
+{
+  char * x = env_get("LOG_AUTH";
+
+  if (!x || (*x != '1')) return;
+
+  if (authresult == SMTP_AUTH_SUCCESS) {
+    syslog(LOG_MAIL | LOG_INFO, "smtp auth: user name is %s, success!", authlogin);
+  } else {
+    syslog(LOG_MAIL | LOG_INFO, "smtp auth: user name is %s, failed!", authlogin);
+  }
+}
+
static int smtpauth_getl(void) {
   int i;
   if (!stralloc_copys(&smtpauth, "") return -1;
@@ -611,11 +691,14 @@
   wait_pid(&st, pid);
   if (wait_exitcode(st) == 0) {
     out("235 go ahead\r\n";
+    authd = 1;
+    auth_smtplog(smtpauthlogin, SMTP_AUTH_SUCCESS);
     flush();
     relayclient="";
     return;
   }
   sleep(2);
+  auth_smtplog(smtpauthlogin, SMTP_AUTH_FAILED);
   out("535 auth failure\r\n"; flush(); _exit(0);
   /* done */
}


呵呵,正式用之前,各位多测试测试。

几种情况需要测测看:
1. 其它服务器发到本域,smtp过程是否正常,本域能否收到
2. from和auth user 不一样会出现什么情况, 一样的话,能否发信。
3. LOG_AUTH是否起作用。

呵呵,qmail的对齐用空格,实在不习惯,没办法,为保持一致,我也用了。     

更新版本
应一些朋友的要求,加了本地发信人发给本地,也需要auth的功能。

另外而且还加了一些注释,版本号。方法和前面一样。

代码如下:

  1. --- qmail-smtpd.c        2003-06-02 18:34:51.000000000 -0400
  2. +++ qmail-smtpd.c.new        2003-06-02 18:42:31.000000000 -0400
  3. @@ -268,6 +268,7 @@
  4.    int r;
  5.    r = rcpthosts(addr.s,str_len(addr.s));
  6.    if (r == -1) die_control();
  7. +  if (!localauthd()) return 0;
  8.    return r;
  9. }

  10. @@ -304,7 +305,11 @@
  11.    if (!stralloc_copys(&rcptto,"")) die_nomem();
  12.    if (!stralloc_copys(&mailfrom,addr.s)) die_nomem();
  13.    if (!stralloc_0(&mailfrom)) die_nomem();
  14. -  out("250 ok\r\n");
  15. +  if (smtp_auth_validfrom(mailfrom.s)) {
  16. +    out("250 ok\r\n");
  17. +  } else {
  18. +    out("must use username as From authenticated! (#5.7.1)\r\n");
  19. +  }
  20. }
  21. void smtp_rcpt(arg) char *arg; {
  22.    if (!seenmail) { err_wantmail(); return; }
  23. @@ -527,6 +532,89 @@
  24. static stralloc smtpauth = {0};
  25. static char smtpauthlogin[65];
  26. static char smtpauthpass[65];
  27. +static int authd = 0;
  28. +
  29. +/* Author: gadfly@163.com. Version: 1.2.
  30. + * 1. Check consistent between auth user and 'From' user.
  31. + * 2. Read the LOG_AUTH enviroment variable to determine whether logging the auth info.
  32. + * LOG_AUTH=1, write the auth smtp info into syslog.
  33. + * 3. If mail from local, rcpt to local domain, user must auth before send data.
  34. + */
  35. +#include <syslog.h>;
  36. +
  37. +#define SMTP_AUTH_SUCCESS     0
  38. +#define SMTP_AUTH_FAILED      1
  39. +
  40. +int localauthd() {
  41. +
  42. +  if (rcpthosts(mailfrom.s, strlen(mailfrom.s)) && !authd) return 0;
  43. +  return 1;
  44. +}
  45. +
  46. +int smtp_auth_validfrom(from) char * from;
  47. +{
  48. +  stralloc tmplogin={0},mydefaultdomain={0};
  49. +  char authusername[256];
  50. +  int k, userlen;
  51. +
  52. +  if (!authd) return 1;
  53. +
  54. +  authusername[255] = '\0';
  55. +  userlen = k = str_len(smtpauthlogin);
  56. +  k = byte_rchr(smtpauthlogin, k, '@');
  57. +
  58. +  if (k == userlen)
  59. +  {
  60. +    k = byte_rchr(smtpauthlogin, userlen, '%');
  61. +
  62. +    if (k == userlen)
  63. +    {
  64. +      if (control_readfile(&mydefaultdomain,"/var/qmail/control/me",1) != 1)
  65. +      {
  66. +        die_nomem();
  67. +      }
  68. +      if (!stralloc_copys(&tmplogin, smtpauthlogin) )
  69. +      {
  70. +        die_nomem();
  71. +      }
  72. +      if (!stralloc_cats(&tmplogin, "@") )
  73. +      {
  74. +        die_nomem();
  75. +      }
  76. +      if (!stralloc_cat(&tmplogin, &mydefaultdomain))
  77. +      {
  78. +        die_nomem();
  79. +      }
  80. +      strncpy(authusername, tmplogin.s, sizeof(authusername));
  81. +      }
  82. +      else
  83. +      {
  84. +        strcpy(authusername, smtpauthlogin);
  85. +      authusername[k]='@';
  86. +      }
  87. +  }
  88. +  else {
  89. +    strcpy(authusername, smtpauthlogin);
  90. +  }
  91. +  return !strcasecmp(from, authusername);
  92. +}
  93. +
  94. +
  95. +void auth_smtplog(authlogin, authresult)
  96. +char * authlogin;
  97. +int authresult;
  98. +{
  99. +  char * x = env_get("LOG_AUTH");
  100. +
  101. +  if (!x || (*x != '1')) return;
  102. +
  103. +  if (authresult == SMTP_AUTH_SUCCESS) {
  104. +    syslog(LOG_MAIL | LOG_INFO, "smtp auth: user name is %s, success!", authlogin);
  105. +  } else {
  106. +    syslog(LOG_MAIL | LOG_INFO, "smtp auth: user name is %s, failed!", authlogin);
  107. +  }
  108. +}
  109. +
  110. static int smtpauth_getl(void) {
  111.    int i;
  112.    if (!stralloc_copys(&smtpauth, "")) return -1;
  113. @@ -611,11 +699,14 @@
  114.    wait_pid(&st, pid);
  115.    if (wait_exitcode(st) == 0) {
  116.      out("235 go ahead\r\n");
  117. +    authd = 1;
  118. +    auth_smtplog(smtpauthlogin, SMTP_AUTH_SUCCESS);
  119.      flush();
  120.      relayclient="";
  121.      return;
  122.    }
  123.    sleep(2);
  124. +  auth_smtplog(smtpauthlogin, SMTP_AUTH_FAILED);
  125.    out("535 auth failure\r\n"); flush(); _exit(0);
  126.    /* done */
  127. }
复制代码


另外,感谢erehw提供的空间可以下载这个patch。
http://gadfly.shanji.com/qmail-smtpd/


由于网页上的代码贴上去,格式有问题。
我就不再更新了。
请各位到以上的url下载。
或给我发信索要

作者: Fun-FreeBSD    时间: 2003-04-05 18:32
提示: 作者被禁止或删除 内容自动屏蔽
作者: peng    时间: 2003-04-06 21:22
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
gadfly真强啊!
看来做研发的就是厉害啊。
好文章。
作者: gadfly    时间: 2003-04-07 00:40
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
晕,这上面的patch中,每行前面的空格都不显示出来,复制下来肯定没法用.

本站的ftp服务也关了.

如果手工复制下来,需要在每行没有@或+开头的代码行前面加个空格,
就可以使用了.

如果觉得麻烦,可以给我发信,我把patch发给你们. gadfly@163.com

最好能有个上载的地方
作者: gadfly    时间: 2003-04-07 00:42
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
peng老大过奖了,都在技术的苦海中苦苦挣扎. 兄弟们得携手共进才是.

说不定还有不少问题呢
作者: gadfly    时间: 2003-04-07 11:43
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
由于,有网友给我发信提了一些问题,我想还是到这里说比较方便。

其实下面的问题,在我上面都说明了。没办法,我还是重点说一下

FAQ:

1. patch是基于哪一个auth的?
auth smtp有两个patch,
分别在:http://members.elysium.pl/brush/qmail-smtpd-auth/
和www.nimh.org/hacks/qmail-smtpd.c。
基于的是后者。
如果你们auth smtp用的是前者,我提供的patch就不能直接使用。
等我有时间,在写一个基于前者的patch吧。

2. patch执行后的结果是什么?
晕,刚发现,www.nimh.org/hacks/qmail-smtpd.c又更新了,做的糟糕,没有版本信息,我还不知道我针对的哪一个版本。下次我也要加上版本信息了。
现在只好说: iceblood版本: 正常执行成功的话,没有任何输出。
          最新版本(nimh.org主页上的):输出入下:
Hunk #1 succeeded at 252 (offset -52 lines).
Hunk #2 succeeded at 498 (offset -33 lines).
Hunk #3 succeeded at 633 (offset -58 lines).

但是还好,编译出来的可以正常使用。

3.编译出来的大小没有区别?
这个和系统环境相关,不是绝对的。只要前两个没问题,你就看测试结果吧。

4.网页上的patch不好用?
是的,因为格式的原因,手工复制下来,需要在每行没有@或+开头的代码行前面加个空格, 就可以使用了.

如果觉得麻烦,可以给我发信,我把patch发给你们. gadfly@163.com

最好能有个上载的地方
作者: netloafer    时间: 2003-04-07 12:13
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
gadfly真是强呀~~
有关资料可以上传到linux版的FTP服务器上~~~~
作者: gadfly    时间: 2003-04-07 12:23
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
原帖由 "netloafer" 发表:


gadfly真是强呀~~
有关资料可以上传到linux版的FTP服务器上~~~~


呵呵,过奖了。

ftpserver我昨天试过了,还是没有开。

听说因为受攻击,还影响了电信的其他业务,现在已经关闭了。只有另寻他途。
作者: 夜未眠    时间: 2003-04-28 19:41
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
针对http://members.elysium.pl/brush/qmail-smtpd-auth/认证补丁再加上楼主所说的功能.

[ 非patch ]

首先你要打补丁,然后照下面的方法修改qmail-smtpd.c源代码.

1.增加全局变量:
        stralloc authusername={0};   //全局变量用于记录认证的email地址

2.在认证成功后将mailfrom存入上面的authusername中,也就是在函数
int authenticate(void)最后return 0;语句前插入下面的语句
         /*将用户名存入全局变量 authusername*/
         if(!stralloc_copy(&authusername,&user)) return 1;

3.在void smtp_rcpt(arg)函数的if (relayclient) {语句后插入下面的语句.
             if(case_diffs(authusername.s,mailfrom.s)) {
                    err_noauth(); //认证用户名与mailfrom中的地址不符
                    /*在这儿加入log代码*/
                    return; //出错返回
             }

===========================================================
一个问题:也不知道我想的对不对,在此提出与各位讨论.

    但是我觉得你的patch和我上面的方法好象都有一个问题.就是如果远程连接到服务器25号端口,不通过认证。一样可以向control/rcpthosts中列出的地址发邮件(就象是别的MTA与你对话一样,别人的MTA不可能知道你的用户名和密码)因为不通过认证那么relayclient将会是null,那么就会进行rcpthosts的比较,如果rcpt 指定的email地址在rcpthosts中列出,qmail会接收并转发该邮件,如果一个快速请求对一个慢速服务器,那是什么情况?
     有人想把用户名与mailfrom地址比较的操作放在if(relayclient)这前,前面我说了,别人的MTA不会知道你的用户名及密码。如果你这样作了,你将收不到邮件。
    我想就一台服务器再打补丁也是白打。可以用两台服务器比较安全,分别打不同的补丁<也就是在前面提到的if(relayclient)处>;,一台专收,一台专发。两台之间进行通信。这样可能才能比较安全.

    不知道各位大虾有什么看法。不仿在此讨论讨论..
作者: tutux    时间: 2003-04-28 21:04
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
原帖由 "夜未眠"]  发表:


首先你要打补丁,然后照下面的方法修改qmail-smtpd.c源代码.

1.增加全局变量:
        stralloc authusername={0};   //全局变量用于记录认证的email地址

2.在认证成功后将mailfrom存入上面的authusern..........

就是如果远程连接到服务器25号端口,不通过认证。一样可以向control/rcpthosts中列出的地址发邮件(就象是别的MTA与你对话一样,别人的MTA不可能知道你的用户名和密码)因为不通过认证那么relayclient将会是null,那么就会进行rcpthosts的比较,如果rcpt 指定的email地址在rcpthosts中列出,qmail会接收并转发该邮件,如果一个快速请求对一个慢速服务器,那是什么情况?


这个情况,是暂时没办法的啦。
作者: iceblood    时间: 2003-04-29 08:50
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
谢谢,希望加精。
能否mail给我一份?
我尽快把qmail-smtpd.c替换掉。
作者: gadfly    时间: 2003-04-29 12:22
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
to 夜未眠:

大概明白你的意思.
1.smtp的这种机制下,安全就是相对的,我知道你服务器的域和用户,我就可以向你发信。
2.其实你说的分开,也就是将mail relay(本域用户向外发信)和mail receive(用于MTA)之间,我记得和peng以前讨论过,确实可以这么做.而且不同的patch确实能使效率提高,同时又起到了分流的作用.不过大部分的情况下,效率的问题并不大, 这两者还是合一的.不过我想用不同的patch,效率上的提高还是有限的。即使有效率问题,完全可以通过多服务器负载均衡来避免.
3.你说白打,我的理解你是针对发往本域的,我同意。不过这些patch基本上都是针对relay的,从这个角度来说,patch是很有作用的.

to iceblood:
看不到你的mail address。不知如何给你
作者: iceblood    时间: 2003-04-29 14:32
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
晕到~一时忽疏~居然忘记留下地址,现在补上~
iceblood@163.com
作者: 夜未眠    时间: 2003-04-29 18:20
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
to gadfly
我都不是很清楚自已在说什么,谁叫我表达能力太差呢。大哥居然能够理解我的意图,佩服佩服。
作者: haohaoo    时间: 2003-04-30 12:54
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
这个patch是基于www.nimh.org/hacks/qmail-smtpd.c,iceblood版本中实际上也是的这个。因此,用iceblood版本的可以直接使用。

那要怎么用?你还没有说呢?下载qmail-smtpd.c后要怎么办?我用iceblood版本已经安装好了,要怎么打?
作者: gadfly    时间: 2003-04-30 13:31
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
不仔细看?
安装方法,如下,将下面这些内容存到qmail-smtpd.patch。放到qmail的源码目录。然后
1. patch < qmail-smtpd.patch
2. make qmail-smtpd
3. 替换qmail-smtpd

作者: haohaoo    时间: 2003-04-30 17:45
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
[quote]原帖由 "gadfly"][/quote 发表:

有看啊,不过我说iceblood版本已经安装好了的啊?
是不是把包解开,然后把qmail-smtpd.c改名,然后编译好后,把qmail-smtpd拿到已安装的机器上去替换就行了?
作者: gadfly    时间: 2003-04-30 21:01
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
??
不用改名,解包后按我说的步骤作就好了
作者: haohaoo    时间: 2003-05-02 12:55
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
我替换掉qmail-smtpd后还是出问题啊,smtp不用验证就可以发信啊
作者: ryanxyz    时间: 2003-05-02 20:43
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
我一開始就用了gadfly兄的patch
完全沒有問題
一次搞定 如果是從網頁上複製下來的
需要注意空白的問題
作者: microcao    时间: 2003-05-04 20:45
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
我来补充一下

首先

http://nimh.org/ 的补丁地址改变了不在本来的地方了新地地方是

http://nimh.org/dl/

其次推荐所有使用 http://nimh.org/ 发布的 qmail-smtpd.c  的朋友
换成另外一个补丁

http://www.cuni.cz/~vhor/qmail/smtpauth-en.html

这个补丁是在 http://nimh.org/ 基础上改进来的, 他解决了楼主说的问题
增加了系统认证的日志应该是比较完善的!
作者: gadfly    时间: 2003-05-05 20:12
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
原帖由 "microcao" 发表:

http://www.cuni.cz/~vhor/qmail/smtpauth-en.html

这个补丁是在 http://nimh.org/ 基础上改进来的, 他解决了楼主说的问题
增加了系统认证的日志应该是比较完善的!

呵呵,看了你写的链接上的说明以及代码,我都没看到检查mail from和auth login name的一致性。另外syslog也就两个地方用到了,不觉的它的更完善。而且是直接写日志,而不是通过环境变量来判断是否写日志。

所以结论是那个链接上的patch没有解决本文涉及的问题.
作者: IPphone    时间: 2003-05-12 16:04
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
哈,原来这有这么多高手在的呢??求教一个问题:我用的是http://members.elysium.pl/brush/qmail-smtpd-auth/
上的补丁,完成后可以认证发邮件,可问题是我在OUTLOOK上去掉认证时一样还是可以发送邮件。我曾经怀疑那个relayclient的问题,就是它还是在我每次收邮件时会记录我的客户端IP让它可以忘外发邮件;于是我去掉roaming-users重新编译vpopmail,但是那样就不能给外面发邮件了。各位大大能不能告诉我哪里出问题了??


gadfly,可不可以给我一份你的补丁程序??地址是:xzj35@msn.com
作者: gadfly    时间: 2003-05-12 16:33
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
你说的这个问题,不少的网友都遇到过。iceblood的
包中带的qmail-smtpd-auth*.tar.gz就是这个patch。

我没有仔细研究,反正其它问题排除,我帮他们改用了qmail-smtpd.c,也就是http://nimh.org/ 上的,这个问题就不存在了。

patch 给你发过去了。
作者: IPphone    时间: 2003-05-12 16:51
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
原帖由 "gadfly" 发表:
你说的这个问题,不少的网友都遇到过。iceblood的
包中带的qmail-smtpd-auth*.tar.gz就是这个patch。

我没有仔细研究,反正其它问题排除,我帮他们改用了qmail-smtpd.c,也就是http://nimh.org/ 上的,这个问题?.........



谢了!!我再玩玩看。
作者: gadfly    时间: 2003-05-18 12:45
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
由于网友xmubeta用这个patch遇到了问题,

我仔细察看了一下代码。

确实如xmubeta 所说,代码有点问题。

问题出在,以前我给的patch,smtp_auth_validfrom的调用和定义的参数都不一致。

编译居然也不报错,也是DJK风格的一个缺点:所有的内部函数都不预定义,即使预定义也不定义参数,所以编译不报错。

好了,我把我的patch改过来了。

改动的地方只有一个,原来是
  if (smtp_auth_validfrom(mailfrom)) {
现在是
  if (smtp_auth_validfrom(mailfrom.s)) {

谢谢xmubeta的指正。

至于为什么原来的patch在linux不出错,在solaris上出错。
我理解是linux上将结构传入参数,转化成char *的时候,实际上是将第一个结构成员转化了,而这个正好是mailfrom.s。所以没有问题。

而solaris上就有所不同了,所以造成错误。

iceblood, patch我给你重发了。
作者: gadfly    时间: 2003-06-02 18:51
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
应一些朋友的要求,加了本地发信人发给本地,也需要auth的功能。

另外而且还加了一些注释,版本号。方法和前面一样。

我稍微测试了一下。各位测恻看吧。


  1. --- qmail-smtpd.c       2003-06-02 18:34:51.000000000 -0400
  2. +++ qmail-smtpd.c.new   2003-06-02 18:42:31.000000000 -0400
  3. @@ -268,6 +268,7 @@
  4.    int r;
  5.    r = rcpthosts(addr.s,str_len(addr.s));
  6.    if (r == -1) die_control();
  7. +  if (!localauthd()) return 0;
  8.    return r;
  9. }

  10. @@ -304,7 +305,11 @@
  11.    if (!stralloc_copys(&rcptto,"")) die_nomem();
  12.    if (!stralloc_copys(&mailfrom,addr.s)) die_nomem();
  13.    if (!stralloc_0(&mailfrom)) die_nomem();
  14. -  out("250 ok\r\n");
  15. +  if (smtp_auth_validfrom(mailfrom.s)) {
  16. +    out("250 ok\r\n");
  17. +  } else {
  18. +    out("must use username as From authenticated! (#5.7.1)\r\n");
  19. +  }
  20. }
  21. void smtp_rcpt(arg) char *arg; {
  22.    if (!seenmail) { err_wantmail(); return; }
  23. @@ -527,6 +532,89 @@
  24. static stralloc smtpauth = {0};
  25. static char smtpauthlogin[65];
  26. static char smtpauthpass[65];
  27. +static int authd = 0;
  28. +
  29. +/* Author: gadfly@163.com. Version: 1.2.
  30. + * 1. Check consistent between auth user and 'From' user.
  31. + * 2. Read the LOG_AUTH enviroment variable to determine whether logging the auth info.
  32. + * LOG_AUTH=1, write the auth smtp info into syslog.
  33. + * 3. If mail from local, rcpt to local domain, user must auth before send data.
  34. + */
  35. +#include <syslog.h>;
  36. +
  37. +#define SMTP_AUTH_SUCCESS     0
  38. +#define SMTP_AUTH_FAILED      1
  39. +
  40. +int localauthd() {
  41. +
  42. +  if (rcpthosts(mailfrom.s, strlen(mailfrom.s)) && !authd) return 0;
  43. +  return 1;
  44. +}
  45. +
  46. +int smtp_auth_validfrom(from) char * from;
  47. +{
  48. +  stralloc tmplogin={0},mydefaultdomain={0};
  49. +  char authusername[256];
  50. +  int k, userlen;
  51. +
  52. +  if (!authd) return 1;
  53. +
  54. +  authusername[255] = '\0';
  55. +  userlen = k = str_len(smtpauthlogin);
  56. +  k = byte_rchr(smtpauthlogin, k, '@');
  57. +
  58. +  if (k == userlen)
  59. +  {
  60. +    k = byte_rchr(smtpauthlogin, userlen, '%');
  61. +
  62. +    if (k == userlen)
  63. +    {
  64. +      if (control_readfile(&mydefaultdomain,"/var/qmail/control/me",1) != 1)
  65. +      {
  66. +        die_nomem();
  67. +      }
  68. +      if (!stralloc_copys(&tmplogin, smtpauthlogin) )
  69. +      {
  70. +        die_nomem();
  71. +      }
  72. +      if (!stralloc_cats(&tmplogin, "@") )
  73. +      {
  74. +        die_nomem();
  75. +      }
  76. +      if (!stralloc_cat(&tmplogin, &mydefaultdomain))
  77. +      {
  78. +        die_nomem();
  79. +      }
  80. +      strncpy(authusername, tmplogin.s, sizeof(authusername));
  81. +      }
  82. +      else
  83. +      {
  84. +        strcpy(authusername, smtpauthlogin);
  85. +      authusername[k]='@';
  86. +      }
  87. +  }
  88. +  else {
  89. +    strcpy(authusername, smtpauthlogin);
  90. +  }
  91. +  return !strcasecmp(from, authusername);
  92. +}
  93. +
  94. +
  95. +void auth_smtplog(authlogin, authresult)
  96. +char * authlogin;
  97. +int authresult;
  98. +{
  99. +  char * x = env_get("LOG_AUTH");
  100. +
  101. +  if (!x || (*x != '1')) return;
  102. +
  103. +  if (authresult == SMTP_AUTH_SUCCESS) {
  104. +    syslog(LOG_MAIL | LOG_INFO, "smtp auth: user name is %s, success!", authlogin);
  105. +  } else {
  106. +    syslog(LOG_MAIL | LOG_INFO, "smtp auth: user name is %s, failed!", authlogin);
  107. +  }
  108. +}
  109. +
  110. static int smtpauth_getl(void) {
  111.    int i;
  112.    if (!stralloc_copys(&smtpauth, "")) return -1;
  113. @@ -611,11 +699,14 @@
  114.    wait_pid(&st, pid);
  115.    if (wait_exitcode(st) == 0) {
  116.      out("235 go ahead\r\n");
  117. +    authd = 1;
  118. +    auth_smtplog(smtpauthlogin, SMTP_AUTH_SUCCESS);
  119.      flush();
  120.      relayclient="";
  121.      return;
  122.    }
  123.    sleep(2);
  124. +  auth_smtplog(smtpauthlogin, SMTP_AUTH_FAILED);
  125.    out("535 auth failure\r\n"); flush(); _exit(0);
  126.    /* done */
  127. }
复制代码

作者: IPphone    时间: 2003-06-02 19:18
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
这个怎么用呢,是不是作为一个 patch 来打啊???


另外我有个问题请问 gadfly ,我用呢前面的那个补丁打入最新的那个 qmail-smtpd.c (就是有三行输出的那个)。用编译后的 qmail-smtpd 来跑,认证没有问题,但是客户端的地址设置还是可以随便改啊,可不可以帮我分析一下原因??


我的 runsmtp 启动脚本是:
#/bin/sh
LOG_AUTH=1
export LOG_AUTH

tcpserver -H -R -l 0 0 smtp /var/qmail/bin/qmail-smtpd-auth /bin/checkpassword /bin/true &
作者: IPphone    时间: 2003-06-02 20:07
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
老兄啊,你那第十行的 “}” 又问题吧??我 patch 打不上啊。     



另外加了你的那个日志记录后会记录一些什么内容啊?仍然是在 Linux 的 /var/log/maillog 中吗??


我的 runsmtp 脚本改为:     

#/bin/sh
LOG_AUTH=1
export LOG_AUTH

tcpserver -H -R -l 0 -u qmailduid -g qmaildgid 0 smtp /var/qmail/bin/qmail-smtpd-auth /bin/checkpassword /bin/true | /var/qmail/bin/splogger &
作者: gadfly    时间: 2003-06-02 20:30
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
??不会呀,具体的错误信息。

另外看我最前面的说明。

特别要说明的是粘贴上来后,有些没有空格了。得自己补上
作者: IPphone    时间: 2003-06-02 20:59
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
看来确实是空格问题。后来用 gadfly 发过来的补丁就可以了。

后来在 gadfly 的热心帮助下解决了遇到的一些我在运行脚本和 qmail 配置文件上的问题;描述如下,供大家参考。

runsmtpd-auth脚本:
#!/bin/sh

LOG_AUTH=1
export LOG_AUTH

tcpserver -H -R -v -p -l 0 -u 0 -g 0 0 smtp /var/qmail/bin/qmail-smtpd-auth-gadfly /bin/checkpassword /bin/true 2>;&1 | /var/qmail/bin/splogger &

/var/qmail/control/me 里面的内容改成了域的名称(原来是服务器的完整域名)




这里我的服务器是只需要给本域用户发送email 的。(呵呵,是不是有点大材小用阿?)现在不会出现乱发邮件的问题了。

谢谢 gadfly !!!!!
作者: jeff183    时间: 2003-08-08 21:59
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
可以直接把文件给我吗?
谢谢!

jeff183@sina.com
作者: erehw    时间: 2003-09-03 15:54
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
gadfly :
你好,这个修改过的c文件,能否提供一个地方下载?或者麻烦发一个到我的邮箱.erehw@163.com。
谢谢。
作者: carelezz    时间: 2003-09-05 20:39
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
gadfly:
     您好,我也想要您修正过的qmail-smtpd.c文件或者patch
     我的邮箱:carelezz74@hotmail.com
     再次感谢


carelezz
作者: gadfly    时间: 2003-09-07 22:33
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
呵呵,以上各位朋友,不好意思,由于帖子浏览的这个配置
默认方式只列出: 3月内的帖子
注意:回复这个时间段以外的普通帖子不能被按默认方式浏览的朋友看到!

导致我没有及时的看到各位的回复。

不过还好,非常感谢erehw,提供空间下载patch。

楼顶的帖子我更新了。包括最新的patch和下载地址。
作者: xiaoxiaoke    时间: 2004-02-06 22:13
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
前提是你已经成功安装了smtp-auth的补丁!!

删除/var/qmail/control/rcphosts中的本机域名
~~~~~~~~~~~~~~~~~~~~~~~~~~~
作者: yjc2688    时间: 2004-12-20 22:30
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
这样会不会影响资源??
作者: 毛天吹    时间: 2004-12-22 01:15
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
谢谢各们楼主的无私的提供了。。我现在就赶快去更更新我的MAIL 了
.
楼上可以发给我一份不: yixiang.wang@126.com
作者: platinum    时间: 2005-02-12 00:16
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
哪位能提供一下打好补丁的qmail-smtp.c文件呢?
补丁太多,打乱了~~
作者: hongfengyue    时间: 2005-03-16 16:02
标题: 修正Qmail auth smtp中电子邮件地址任意的patch
是呀,谁有打好的补丁的c文件?
mail:  hongfengwbw@yahoo.com.cn
谢谢!!
作者: 红雨    时间: 2005-11-16 16:46
# vi /service/qmail-smtpd/run
exec /usr/local/bin/softlimit -m 40000000
    /usr/local/bin/tcpserver -v -H -R -l 0
    -x /home/vpopmail/etc/tcp.smtp.cdb -c "$MAXSMTPD"
    -u "$QMAILDUID" -g "$NOFILESGID" 0 smtp
    /var/qmail/bin/qmail-smtpd
    /home/vpopmail/bin/vchkpw /bin/true 2>&1

这样的配置如何应用这个补丁?
作者: 思一克    时间: 2005-11-17 09:15
我多说一句。首先感谢gladfly.
下面代码的第3行
stralloc tmplogin={0},mydefaultdomain={0};
应该改为
static stralloc tmplogin={0},mydefaultdomain={0};
否则有内存泄露。
因为坏人可以用RSET在一个连接发出许多MAIL FROM
smtp_auth_validfrom()被许多次调用。
tmplogin, mydefaultdomain会占用内存不退,越占越多。

也许我看的不完全对,因为我没有看PATCH后的代码。但希望你研究。




  1. +int smtp_auth_validfrom(from) char * from;
  2. +{
  3. +  stralloc tmplogin={0},mydefaultdomain={0};
  4. +  char authusername[256];
  5. +  int k, userlen;
  6. +
  7. +  if (!authd) return 1;
  8. +
  9. +  authusername[255] = '';
  10. +  userlen = k = str_len(smtpauthlogin);
  11. +  k = byte_rchr(smtpauthlogin, k, '@');
  12. +
  13. +  if (k == userlen)
  14. +  {
  15. +    k = byte_rchr(smtpauthlogin, userlen, '%');
  16. +
  17. +    if (k == userlen)

  18. ......................
复制代码

作者: 红雨    时间: 2005-11-19 09:10
[root@testmailserver netqmail-1.05]# patch < qmail-smtpd.patch
patching file qmail-smtpd.c
Hunk #1 succeeded at 216 (offset -52 lines).
Hunk #3 succeeded at 447 (offset -85 lines).
Hunk #4 succeeded at 693 (offset -6 lines).
[root@testmailserver netqmail-1.05]# make qmail-smtpd
./compile qmail-smtpd.c
qmail-smtpd.c: In function `main':
qmail-smtpd.c:642: warning: return type of `main' is not `int'
./load qmail-smtpd rcpthosts.o commands.o timeoutread.o
timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o
received.o date822fmt.o now.o qmail.o cdb.a fd.a wait.a
datetime.a getln.a open.a sig.a case.a env.a stralloc.a
alloc.a substdio.a error.a str.a fs.a auto_qmail.o  `cat
socket.lib`
作者: vyouzhi    时间: 2006-02-18 11:18
留个印
过些时候有用
作者: 红雨    时间: 2006-02-18 20:40
原帖由 vyouzhi 于 2006-2-18 11:18 发表
留个印
过些时候有用

已经没有必要了
作者: xghong    时间: 2006-06-29 11:17
好文章!!!
作者: zhanghj_ok    时间: 2006-06-30 02:31
我的服务器安装完后也出现了与楼主一样的故障,任何非法用户只要使用了我的服务器就可以给我的域内所有成员发邮件,我的服务器环境是:

qmail 1.05 +vpopmail 5.4.10 +mysql+LINUX AS 4

请问应该用什么补丁,或者有什么比较好的解决方案呢,

先谢谢大家的帮助

详细烦请查看连接:http://bbs.chinaunix.net/viewthr ... &extra=page%3D1
作者: yjc2688    时间: 2006-07-07 11:58
文件又找不到了希望那位发给我一份yjc2688@163.com
作者: chhts    时间: 2008-06-08 11:45
标题: 现在的下载地址在那里
没有下载的了




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2