/*
*
*              Reverse MX Filter for Postfix 2
*                    reject_bad_rmx
*           (c) 2004 Elita rozanski@sergiusz.com
*
*/

/*
MXfilter is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
*/

#include <string.h>
#include <ctype.h>
#include <stdio.h>

#include "acl.h"

/*
test access list for mxfilter
return 0 for skip
return 1 for check
return < 0 for error
*/

int mxfilter_acl(char *sender, char *recipient, char *result, int sresult, 
	char *reason, int sreason, char *config, char *sconfig) {
FILE *p;
char buf[1024],*k,*sp;
char r[1024],s[1024];
int i;

result[0]=0;
reason[0]=0;

if(strlen(recipient)==0)return -1; //recipient empty

snprintf(r,sizeof(r),"%s",recipient);
snprintf(s,sizeof(s),"%s",sender);

for(i=0;i<strlen(r);i++)
    r[i]=tolower(r[i]);
for(i=0;i<strlen(s);i++)
    s[i]=tolower(s[i]);

if(!(p=fopen("/etc/postfix/mxfilter.acl","r"))) return -2; //acl error

while(fgets(buf,sizeof(buf)-1,p)) {
    k=(char *)index(buf,10);
    if(k)k[0]=0;
    k=(char *)index(buf,13);
    if(k)k[0]=0;

//printf("l:%s\n",buf);
    
    if(strlen(buf)>0) { // empty line ignore
	if(buf[0]!='#') { // remark line ignore
	    k=(char *)index(buf,9);
	    sp=(char *)index(buf,32);
	    if(k && sp)
		if(sp<k)k=sp;
	    if(!k && sp)k=sp;
	    if(k) { //bad line ignore
		k++[0]=0;
//printf("* |%s|%s|\n",recipient,buf);
		if(strlen(buf)>0 && 
			(
			    strstr(r,buf) || 
			    strcmp(buf,"*")==0 || 
			    ( buf[0]=='|' && strstr(s,buf+1) )
			)
			    ) { // ok
		    int j=strlen(k);
//		    printf("kb:|%s|\n",k);
		    for(i=0;i<j;i++) {
			if(k[0]==9 || k[0]==32)
			    k++;
			else
			    i=j;
			}
//		    printf("ka:|%s|\n",k);
		    if(strncmp(k,"config:",7)==0) {
			if(buf[0]!='|') {
			    if(strlen(config)==0) {
				snprintf(config,1023,"%s",k+7);
				}
			    }
			else {
			    if(strlen(sconfig)==0) {
				snprintf(sconfig,1023,"%s",k+7);
				}
			    }
			}
		    else
		    if(strncmp(k,"check",5)==0) {
			sp=(char *)index(k,32);
			k=(char *)index(k,9);
			if(k && sp)
			    if(sp<k)k=sp;
			if(!k && sp)k=sp;
			if(k) {
			    k++;
			    j=strlen(k);
			    for(i=0;i<j;i++) {
				if(k[0]==9 || k[0]==32)
				    k++;
				else
				    i=j;
				}
			    snprintf(result,sresult,"%s",k);
			    k=(char *)index(result,9);
			    sp=(char *)index(result,32);
			    if(k && sp)
				if(sp<k)k=sp;
			    if(!k && sp)k=sp;
			    if(k) {
				k++[0]=0;
				j=strlen(k);
				for(i=0;i<j;i++) {
				    if(k[0]==9 || k[0]==32)
					k++;
				    else
					i=j;
				    }
				snprintf(reason,sreason,"%s",k);
				}
			    }
//printf("** |%s|%s|\n",result,reason);
			return 1;
			}
		    else
		    if(strcmp(k,"skip")==0)
			return 0;
		    // other action ignore
		    }
		}
	    }    
	}
    }
fclose(p);
return 0; //default skip
}
