/*
*
*              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 <stdio.h>
#include <time.h>
#include <string.h>
#include <openssl/sha.h>

#include "sign.h"

char tabbase[]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_";

/*
return 0  - ok signed
return -1 - strange sender w/o domain
return -2 - no domainsign dunno
*/

int set_sign_sender(char *scheme, char *senderorg, char *signed_sender, int sizeof_signed_sender, char *pczas) {
unsigned char out[40];

if ( ! index(senderorg,'@')) {
    return -1;
    }


if ( strcmp(scheme,"none")==0) {
    snprintf(signed_sender,sizeof_signed_sender,"%s",senderorg);
    return 0;
    }

if ( strcmp(scheme,"LRS")==0) {
    FILE *plik;
    char domain_sign_file[512];
    char domain_sign[512];
    char czas[9];
    char tmp[1024];
    time_t t;
    char sender[256];
    char *senderdm;

    snprintf(sender,sizeof(sender),"%s",senderorg);
    senderdm=(char *)index(sender,'@');
    senderdm++[0]=0;
    
// get time
    if(strlen(pczas)==0) {
	t=time(NULL);
	strftime(czas,sizeof(czas),"%Y%m%d",localtime((time_t *)&t));
	}
    else {
	snprintf(czas,sizeof(czas),"%s",pczas);
	}

// get domain sign
    snprintf(domain_sign_file,sizeof(domain_sign_file),
	"/etc/postfix/domainsign/%s",senderdm);
    if(!(plik=fopen(domain_sign_file,"r"))) {
	return -2;
	}
    fgets(domain_sign,sizeof(domain_sign),plik);
    fclose(plik);

    snprintf(tmp,sizeof(tmp),"|%s|%s|%s|",senderorg,czas,domain_sign);

    SHA1(tmp, strlen(tmp),out);
    snprintf(signed_sender,sizeof_signed_sender,"%s+LRS%c%c%c%c@%s",
	sender,
	tabbase[out[0]%64],
	tabbase[out[1]%64],
	tabbase[out[2]%64],
	tabbase[out[3]%64],
	senderdm);
    return 0;
    }

return 0;
}

/*
return 0 - sign ok
return -1 - sign fail
return -2 - no domainsign
*/

int check_sign_sender(char *scheme, char *signed_sender, char* org_sender, int sizeof_org_sender) {

if(strcmp(scheme,"none")==0) {
    snprintf(org_sender, sizeof_org_sender,"%s",signed_sender);
    return 0;
    }

if(strcmp(scheme,"LRS")==0) {
    char tmp[1024],tmp2[1024];
    int i;
    int dni;
    time_t t;
    char czas[9];
    char *k;

    k=(char *)index(signed_sender,'+');
    if(!k)
	return -1;
    if(strncmp(k,"+LRS",4)!=0)
	return -1;
    if((k+8)[0]!='@')
	return -1;

    t=time(NULL);
        
    if(strlen(signed_sender)>10) {
	for(dni=0;dni<3;dni++) {
	    strftime(czas,sizeof(czas),"%Y%m%d",localtime((time_t *)&t));
	    t-=(time_t)(24*60*60);
	    k[0]=0;
	    snprintf(tmp2,sizeof(tmp2),"%s@%s",signed_sender,k+9);
	    k[0]='+';
	    i=set_sign_sender("LRS", tmp2, tmp, sizeof(tmp),"");
	    if(i==-2)return -2;
	    if(strcmp(signed_sender,tmp)==0) {
	        snprintf(org_sender,sizeof_org_sender,"%s",signed_sender+7);
	        return 0;
	        }
	    }
	}
    return -1;
    }

return 0;
}
