RES: [MASOCH-L] Servidor de e-mails
Lao DanTong
danton at inexo.com.br
Thu May 12 09:36:49 -03 2005
On Thu, 12 May 2005, Paulo Augusto M. Gontijo wrote:
> Marcelo,
>
> vc usa qmail + vpopmail?
> Como vc faz para dar User unknown, pois o qmail não vem assim por default.
> Algum patch para tcpserver, etc?
tcpserver não adianta, porque quando a conexão está sendo tratada por ele
o SMTP ainda não começou a rolar, o tcpserver não tem idéia de para quem
vai a mensagem.
o programa que tem que fazer a verificação de destinatário é o
qmail-smtpd. sim, há patches para isso, verifique em http://www.qmail.org/
eu escrevi um patch assim, mas é específico de minha configuração de
domínios virtuais, porisso não o recomendo para uso geral. entretanto,
como pode servir de fonte de inspiração a rotina principal vai no anexo.
-------------- next part --------------
/*
verificação de validade do RCPT. Na medida do impossível
(obrigado, Rita Lee) verifico os arquivos do qmail-control,
mas meu propósito é fazer isto funcionar no ambiente da InterNexo.
Por enquanto não testo usuários contra qmail-users, só contra o
passwd tradicional.
este treco testa RCPTs locais, retornando "550 User unknown" caso
não existam. Espera um tempo que cresce progressivamente antes
de dar a mensagem e aborta após x erros.
o objetivo é evitar 'bounces' desnecessários em função de spam
aleatório, isto é, em que o spammer simplesmente chuta o nome da
vítima.
ao contrário do autor do qmail, eu vou comentar meu código :-)
agosto de 2003. Danton Nunes.
*/
#include <pwd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
static int flagvh = 0;
static stralloc vh = {0};
static struct constmap mapvh;
/* eventualmente estes dois parâmetros irão para o qmail-control */
static int pavio = 8; // nível de paciência com RCPTs bichados.
static int soneca = 1; // tempo progressivo de espera.
int check_rcpt_init()
{
/* cria tabela de domínios virtuais, as principais vítimas de spam. */
flagvh = control_readfile(&vh,"control/virtualdomains",0);
if (flagvh != 1) return flagvh;
if (!constmap_init(&mapvh,vh.s,vh.len,1)) return flagvh = -1;
return 0;
}
static stralloc dotq = {0}, dotqx = {0}, dotqd = {0}, buf = {0};
int check_rcpt(addr,len)
char *addr;
int len;
{
int n,j,l,ll; char *k,*u;
struct stat fstat;
struct passwd *pw;
if (flagvh != 1) return 1; // bichou na inicialização.
stralloc_copyb(&buf,addr,len);
case_lowerb(buf.s,buf.len); // minusculeia tudo.
//stralloc_0(&buf);
l = byte_rchr(buf.s,buf.len,'@');
if (l >= buf.len) return 1; // não tem '@': deve ser local.
j = byte_chr(buf.s,l,'-'); // trunca no primeiro '-' (por causa de listas)
ll=(j<l)?j:l;
k=constmap(&mapvh,buf.s+l+1,buf.len-l-1); // focinha na tabela de hosts virtuais.
if (!k) return 1; // se não achou, presume que seja local ou smtp-route
// e se comporta como o qmail convencional.
if(!*k) return 0; // domínio virtual desabilitado.
/* achamos um domínio virtual. agora temos que validar o que vem antes do '@'
essencialmente se trata de verificar se existe o .qmail-xxx-{fulano,default} */
j=str_len(k);
u=k; // separa o nome do usuário real (antes do '-')
n=byte_rchr(k,j,'-');
stralloc_copyb(&dotq,u,n); // obtém o diretório home do mané, para montar
stralloc_0(&dotq); // o caminho para ~/.qmail
pw=getpwnam(dotq.s);
if (!pw) return -1;
stralloc_copys(&dotq,pw->pw_dir);
stralloc_cats(&dotq,"/.qmail");
if (n<j)
{ // achou alguma coisa depois do nome do usuário real.
k+=n; j-=n; // k aponta agora para o '-'
stralloc_catb(&dotq,k,j);
}
stralloc_append(&dotq,"-"); // adiciona ao nome -default ou -fulano
stralloc_copy(&dotqd,&dotq);
stralloc_copy(&dotqx,&dotq);
stralloc_cats(&dotqd,"default");
stralloc_0(&dotqd);
if (lstat(dotqd.s,&fstat)==0) return 1; // achou .qmail-xxx-default (ralo geral).
if (ll<l) {
stralloc_catb(&dotqx,buf.s,l);
stralloc_0(&dotqx);
if (lstat(dotqx.s,&fstat)==0) return 1; // achou .qmail-xxx-fulano-de-tal
}
for(n=0;n<l;n++)if(buf.s[n]=='.')buf.s[n]=':'; // troca '.' por ':' no .qmail.
stralloc_catb(&dotq,buf.s,ll);
stralloc_0(&dotq);
if (lstat(dotq.s,&fstat)==0) return 1; // achou .qmail-xxx-fulano (caixa postal).
dotq.len--; // deleta o 0 final.
stralloc_cats(&dotq,"-default");
stralloc_0(&dotq);
if (lstat(dotq.s,&fstat)==0) return 1; // achou .qmail-xxx-fulano-default (típico de listas).
if (--pavio)
{
sleep(soneca);
soneca<<=1; // o tempo dobra a cada RCPT bichado.
return 0;
}
else return -2;
}
void err_norcpt() { out("550 User unknown (#5.1.1)\r\n"); }
int rcpt_ok()
{
int r;
r = check_rcpt(addr.s,str_len(addr.s));
if (r == -1) die_control();
if (r == -2) die_alarm();
return r;
}
More information about the masoch-l
mailing list