2008年07月22日 23時32分22秒
これは、qmailの構成プログラムである qmail-remote にSMTP-AUTH対応させた際のメモ。 OSは FreeBSD/amd64 7.0RELEASE 、qmailはportsで導入した qmail-1.03_7 です。
まぁ、去年・一昨年くらいから「停止するるよぅ」っていってましたから。 一応メールを出して確認したのですがヘルプデスクの回答は、「SMTP-AUTH対応のサーバに切り替えてくれ」しか書いてない。 こちらの質問に全く答えてないし。 この回答は予想通りではあるけど、もうちっときちんとした回答できないかなぁ。
こちらは、室内にqmailを使ったメールサーバがあり、室内から出すメールはこのメールサーバがISPのSMTPサーバへメールを転送していました。 このISPのSMTPサーバが使用不能となり、新たな SMTP-AUTH対応の SMTPサーバを利用する必要があります。
しかし、室内のqmailは素のqmailなので、SMTP-AUTH に対応していません。
今回やりたいことは、お部屋のqmailにSMTP-AUTHをおしゃべりさせてISPのメールサーバに接続できる様にする事です。 お部屋のqmailがメール送信の際にユーザに対してアカウントを要求する、という話とは全く違うのでご注意を。 グーグル先生にお伺いを立てたところ、 http://search.luky.org/linux-users.a/msg02384.html を通して http://tomclegg.net/qmail/#qmail-smtpd-auth が見つかりました。 グーグル様さまです。
http://tomclegg.net/qmail/#qmail-smtpd-auth の説明どおりにオペレーションを行うと、残念ですがパッチはあたりません。 このパッチは素のqmailに対してのものなので、portsで展開された他のパッチが当たったソースには適用できません。 ただ、内容を見た限りだとそれほど大量なパッチではないので、手作業で修正してみました。
chopin# pwd
/usr/ports/mail/qmail/work/qmail-1.03
chopin#
chopin# diff -c qmail-remote.c.orig qmail-remote.c
*** qmail-remote.c.orig 2008-07-22 21:55:44.000000000 +0900
--- qmail-remote.c 2008-07-22 22:34:02.000000000 +0900
***************
*** 45,50 ****
--- 45,52 ----
struct constmap maproutes;
stralloc host = {0};
stralloc sender = {0};
+ stralloc auth_smtp_user = {0};
+ stralloc auth_smtp_pass = {0};
saa reciplist = {0};
***************
*** 225,246 ****
unsigned long code;
int flagbother;
int i;
code = smtpcode();
if (code >= 500 && code < 600) quit("DConnected to "," but greeting failed");
if (code >= 400 && code < 500) return; /* try next MX, see RFC-2821 */
if (code != 220) quit("ZConnected to "," but greeting failed");
! substdio_puts(&smtpto,"HELO ");
substdio_put(&smtpto,helohost.s,helohost.len);
substdio_puts(&smtpto,"\r\n");
substdio_flush(&smtpto);
! if (smtpcode() != 250) quit("ZConnected to "," but my name was rejected");
!
! substdio_puts(&smtpto,"MAIL FROM:<");
! substdio_put(&smtpto,sender.s,sender.len);
! substdio_puts(&smtpto,">\r\n");
! substdio_flush(&smtpto);
code = smtpcode();
if (code >= 500) quit("DConnected to "," but sender was rejected");
if (code >= 400) quit("ZConnected to "," but sender was rejected");
--- 227,284 ----
unsigned long code;
int flagbother;
int i;
+ stralloc slop = {0};
code = smtpcode();
if (code >= 500 && code < 600) quit("DConnected to "," but greeting failed");
if (code >= 400 && code < 500) return; /* try next MX, see RFC-2821 */
if (code != 220) quit("ZConnected to "," but greeting failed");
! substdio_puts(&smtpto,"EHLO ");
substdio_put(&smtpto,helohost.s,helohost.len);
substdio_puts(&smtpto,"\r\n");
substdio_flush(&smtpto);
! if (smtpcode() != 250) {
! substdio_puts(&smtpto,"HELO ");
! substdio_put(&smtpto,helohost.s,helohost.len);
! substdio_puts(&smtpto,"\r\n");
! substdio_flush(&smtpto);
! if (smtpcode() != 250) quit("ZConnected to "," but my name was rejected");
! }
! i = 0;
! while((i += str_chr(smtptext.s+i,'\n') + 1) && (i+14 < smtptext.len) &&
! str_diffn(smtptext.s+i+4,"AUTH LOGIN\n",11) &&
! str_diffn(smtptext.s+i+4,"AUTH LOGIN ",11) &&
! str_diffn(smtptext.s+i+4,"AUTH PLAIN LOGIN\n",17) &&
! str_diffn(smtptext.s+i+4,"AUTH PLAIN LOGIN ",17) &&
! str_diffn(smtptext.s+i+4,"AUTH=LOGIN\n",11) &&
! str_diffn(smtptext.s+i+4,"AUTH=LOGIN ",11));
! if ((i+14 < smtptext.len) && auth_smtp_user.len && auth_smtp_pass.len) {
! substdio_puts(&smtpto,"AUTH LOGIN\r\n");
! substdio_flush(&smtpto);
! if (smtpcode() != 334) quit("ZConnected to "," but authentication was rejected (AUTH LOGIN)");
! if (b64encode(&auth_smtp_user,&slop) < 0) temp_nomem();
! substdio_put(&smtpto,slop.s,slop.len);
! substdio_puts(&smtpto,"\r\n");
! substdio_flush(&smtpto);
! if (smtpcode() != 334) quit("ZConnected to "," but authentication was rejected (username)");
! if (b64encode(&auth_smtp_pass,&slop) < 0) temp_nomem();
! substdio_put(&smtpto,slop.s,slop.len);
! substdio_puts(&smtpto,"\r\n");
! substdio_flush(&smtpto);
! if (smtpcode() != 235) quit("ZConnected to "," but authentication was rejected (password)");
! substdio_puts(&smtpto,"MAIL FROM:<");
! substdio_put(&smtpto,sender.s,sender.len);
! substdio_puts(&smtpto,"> AUTH=<");
! substdio_put(&smtpto,sender.s,sender.len);
! substdio_puts(&smtpto,">\r\n");
! substdio_flush(&smtpto);
! } else {
! substdio_puts(&smtpto,"MAIL FROM:<");
! substdio_put(&smtpto,sender.s,sender.len);
! substdio_puts(&smtpto,">\r\n");
! substdio_flush(&smtpto);
! }
code = smtpcode();
if (code >= 500) quit("DConnected to "," but sender was rejected");
if (code >= 400) quit("ZConnected to "," but sender was rejected");
***************
*** 445,451 ****
char **argv;
{
static ipalloc ip = {0};
! int i;
unsigned long random;
char **recips;
unsigned long prefme;
--- 483,489 ----
char **argv;
{
static ipalloc ip = {0};
! int i,j;
unsigned long random;
char **recips;
unsigned long prefme;
***************
*** 461,466 ****
--- 499,507 ----
if (!stralloc_copys(&host,argv[1])) temp_nomem();
+ if (!stralloc_copys(&auth_smtp_user,"")) temp_nomem();
+ if (!stralloc_copys(&auth_smtp_pass,"")) temp_nomem();
+
relayhost = 0;
for (i = 0;i <= host.len;++i)
if ((i == 0) || (i == host.len) || (host.s[i] == '.'))
***************
*** 469,474 ****
--- 510,525 ----
if (relayhost && !*relayhost) relayhost = 0;
if (relayhost) {
+ i = str_chr(relayhost,' ');
+ if (relayhost[i]) {
+ j = str_chr(relayhost + i + 1,' ');
+ if (relayhost[j]) {
+ relayhost[i] = 0;
+ relayhost[i + j + 1] = 0;
+ if (!stralloc_copys(&auth_smtp_user,relayhost + i + 1)) temp_nomem();
+ if (!stralloc_copys(&auth_smtp_pass,relayhost + i + j + 2)) temp_nomem();
+ }
+ }
i = str_chr(relayhost,':');
if (relayhost[i]) {
scan_ulong(relayhost + i + 1,&smtp_port);
chopin# pwd
/usr/ports/mail/qmail/work/qmail-1.03
chopin#
chopin# diff -c Makefile.orig Makefile
*** Makefile.orig 2008-07-22 21:55:44.000000000 +0900
--- Makefile 2008-07-22 22:07:22.000000000 +0900
***************
*** 1502,1513 ****
load qmail-remote.o control.o constmap.o timeoutread.o timeoutwrite.o \
timeoutconn.o tcpto.o now.o dns.o ip.o ipalloc.o strsalloc.o ipme.o quote.o \
ndelay.a case.a sig.a open.a lock.a seek.a getln.a stralloc.a alloc.a \
! substdio.a error.a str.a fs.a auto_qmail.o dns.lib socket.lib
./load qmail-remote control.o constmap.o timeoutread.o \
timeoutwrite.o timeoutconn.o tcpto.o now.o dns.o ip.o \
ipalloc.o strsalloc.o ipme.o quote.o ndelay.a case.a sig.a open.a \
lock.a seek.a getln.a stralloc.a alloc.a substdio.a error.a \
! str.a fs.a auto_qmail.o `cat dns.lib` `cat socket.lib`
qmail-remote.0: \
qmail-remote.8
--- 1502,1513 ----
load qmail-remote.o control.o constmap.o timeoutread.o timeoutwrite.o \
timeoutconn.o tcpto.o now.o dns.o ip.o ipalloc.o strsalloc.o ipme.o quote.o \
ndelay.a case.a sig.a open.a lock.a seek.a getln.a stralloc.a alloc.a \
! substdio.a error.a str.a fs.a auto_qmail.o base64.o dns.lib socket.lib
./load qmail-remote control.o constmap.o timeoutread.o \
timeoutwrite.o timeoutconn.o tcpto.o now.o dns.o ip.o \
ipalloc.o strsalloc.o ipme.o quote.o ndelay.a case.a sig.a open.a \
lock.a seek.a getln.a stralloc.a alloc.a substdio.a error.a \
! str.a fs.a auto_qmail.o base64.o `cat dns.lib` `cat socket.lib`
qmail-remote.0: \
qmail-remote.8
パッチを当てた事で、ファイル smtproutes の記述形式がちょっぴり変わります。 例えば、
:smtp.hogehoge.jp
の smtp.hogehoge.jp が廃止され、asmtp.hogehoge.jp となり、ポート 784 を指定する必要が出た場合、
:asmtp.hogehoge.jp:784
ユーザID,パスワードも必要な場合は、
:asmtp.hogehoge.jp:784 userid password
となります。