RES: [MASOCH-L] Servidor de e-mails

Lao DanTong danton at inexo.com.br
Thu May 12 09:36:49 BRT 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