<?php
use WHMCS\Database\Capsule;
if (!defined("WHMCS"))
{
    die("This file cannot be accessed directly");
}
require_once 'Net/DNS2.php';

const NS1 = '185.163.51.130';
const NS2 = '185.163.51.131';
const MX  = 'mail3.seecure.ch';
const SPF = 'v=spf1 mx a:mail3.seecure.ch ip4:185.163.51.0/24 ip4:89.35.78.0/23 ~all';
const DMARC = 'v=DMARC1; p=reject; rua=mailto:technik@thurdata.ch; ruf=mailto:technik@thurdata.ch';

function KerioEmail_ClientAreaCustomButtonArray ($params)
{
    return array(
        'DNS-Settings' => 'DNS',
    );
}

function KerioEmail_ClientAreaAllowedFunctions ($params)
{
    return array(
        'MX konfigurieren' => 'setMX',
        'SPF konfigurieren' => 'setSPF',
    );
}

function KerioEmail_DNS($params)
{
    $vars = KerioEmailCheckDNS($params);
    return array(
        'breadcrumb' => array(
            'clientarea.php?action=productdetails&id=' . $params['serviceid'] . '&modop=custom&a=DNS' => 'DNS Mail Settings',
        ),
        'templatefile' => 'kerioEmail_help_mx',
        'vars' => $vars,
    );
}

function KerioEmail_setMX($params)
{
    $zoneIDcollection = Capsule::table('dns_manager2_zone')
        ->select('id')
        ->where('name', '=', $params['domain'])
        ->get();
    $zoneIDobj = $zoneIDcollection[0];
    $zoneID = $zoneIDobj->{'id'};
    if(!isset($zoneID)) {
        return 'Error: zone ID not found for domain ' . $params['domain'];
    }
    $dnsZone = localAPI('dnsmanager', array( 'dnsaction' => 'getZone', 'zone_id' => $zoneID));
    if($dnsZone['result'] != 'success') {
        return 'Error: cloud not fetch zone for ID ' . $zoneID;
    }
    $zoneRecords = array();
    $mxRecord = array(
        'line' => $params['domain'].'.|MX|0',
        'name' => '@',
        'type' => 'MX',
        'class' => 'IN',
        'data' => array(
            'preference' => '10',
            'exchange' => MX,
        ),
    );
    array_push($zoneRecords, $mxRecord);
    foreach($dnsZone['data']->records as $record) {
    if($record->type != 'MX') {
            array_push($zoneRecords, $record);
        };
    }
    $result = localAPI('dnsmanager' ,
        array(
            'dnsaction' => 'updateZone',
            'zone_id' => $zoneID,
            'records' => $zoneRecords,
        )
    );
    if($result['result'] != 'success') {
        return 'Error: cloud not update zone for ID ' . $zoneID;
    }
    return 'success';
}

function KerioEmail_setSPF($params)
{
    $zoneIDcollection = Capsule::table('dns_manager2_zone')
        ->select('id')
        ->where('name', '=', $params['domain'])
        ->get();
    $zoneIDobj = $zoneIDcollection[0];
    $zoneID = $zoneIDobj->{'id'};
    if(!isset($zoneID)) {
        return 'Error: zone ID not found for domain ' . $params['domain'];
    }
    $dnsZone = localAPI('dnsmanager', array( 'dnsaction' => 'getZone', 'zone_id' => $zoneID));
    if($dnsZone['result'] != 'success') {
        return 'Error: cloud not fetch zone for ID ' . $zoneID;
    }
    $zoneRecords = array();
    $spfRecord = array(
            'line' => $params['domain'].'.|TXT|0',
            'name' => '@',
            'type' => 'TXT',
            'class' => 'IN',
            'data' => SPF
        );
    array_push($zoneRecords, $spfRecord);

    foreach($dnsZone['data']->records as $record) {

        if(!$record->type === 'TXT'){
            array_push($zoneRecords, $record);
        } elseif (!preg_match('/^v=spf(.*)$/i', trim($record->rdata->txtdata,'"'))) {
            array_push($zoneRecords, $record);
        };
    }
    $result = localAPI('dnsmanager' ,
        array(
            'dnsaction' => 'updateZone',
            'zone_id' => $zoneID,
            'records' => $zoneRecords,
        )
    );

    if($result['result'] != 'success') {
        return 'Error: cloud not update zone for ID ' . $zoneID;
    }
    return 'success';
}

function KerioEmailCheckDNS($params)
{
    unset($zoneID);
    unset($mxStatus);
    unset($dnsData);
    unset($vars);
    $vars['maildomain'] = $params['domain'];
    $clientDomains = localAPI('GetClientsDomains', array('clientid' => $params['userid']));
    $nameserver = array(
        NS1,
        NS2);
    
    $resolver = new Net_DNS2_Resolver(array('nameservers' => $nameserver));
    try {
            $result = $resolver->query($params['domain'], 'MX');
            
    } catch(Net_DNS2_Exception $e) {
            
            echo "::query() failed: ", $e->getMessage(), "\n";
    }
    $domainMX = $result->answer;
    try {
        $result = $resolver->query($params['domain'], 'TXT');
        
    } catch(Net_DNS2_Exception $e) {
            
            echo "::query() failed: ", $e->getMessage(), "\n";
    }
    $domainTXT = $result->answer;
    $domainSPF = array();
    $domainDKIM = array();
    $domainDMARC = array();
    foreach($domainTXT as $txtRecord) {
        foreach($txtRecord->text as $txtData) {
            if(strstr($txtData,'v=spf')) {
                array_push($domainSPF,$txtData);
            }
            if(strstr($txtData,'v=DKIM')) {
                array_push($domainDKIM,$txtData);
            }
            if(strstr($txtData,'v=DMARC')) {
                array_push($domainDMARC,$txtData);
            }
        }
    }
    # self hosted DNS
    $vars['selfDNS'] = FALSE;
    if(!empty($clientDomains['domains'])) {
        for($i=$clientDomains['startnumber'];$i<=$clientDomains['numreturned'];$i++) {
            if($params['domain'] == $clientDomains['domains']['domain'][$i]['domainname']) {
                $vars['selfDNS'] = TRUE;
                $vars['domainId'] = $clientDomains['domains']['domain'][$i]['id'];
            }
        }
    }
    # SPF
    if (count($domainSPF) > 1) {
        $vars['multiSPF'] = TRUE;
    } else {
        $vars['multiSPF'] = FALSE;
    }
    $vars['spf'] = 'wrong';
    if (empty($domainSPF)) {
        $vars['spf'] = 'unset';
    } else {        
        foreach($domainSPF as $spf) {
            if($spf === SPF) {
                $vars['spf'] = 'set';
            }
        }
    }
    $vars['domainSPF'] = $domainSPF;
    # DKIM
    if (count($domainDKIM) > 1) {
        $vars['multiDKIM'] = TRUE;
    } else {
        $vars['multiDKIM'] = FALSE;
    }
    if (empty($domainDKIM)) {
        $vars['dkim'] = 'unset';
    } else {        
        $vars['dkim'] = 'set';
    }
    $vars['domainDKIM'] = $domainDKIM;
    # DMARC
    if (count($domainDMARC) > 1) {
        $vars['multiDMARC'] = TRUE;
    } else {
        $vars['multiDMARC'] = FALSE;
    }
    $vars['dmarc'] = 'wrong';
    if (empty($domainDMARC)) {
        $vars['dmarc'] = 'unset';
    } else {        
        foreach($domainDMARC as $dmarc) {
            if($dmarc === DMARC) {
                $vars['dmarc'] = 'set';
            }
        }
    }
    $vars['domainDMARC'] = $domainDMARC;
    # MX
    if(count($domainMX) > 1) {
        $vars['multiMX'] = TRUE;
    } else {
        $vars['multiMX'] = FALSE;
    }
    if(empty($domainMX)){
        $vars['mx'] = 'unset';
        $vars['mxtarget'] = MX;
    } else {
        $vars['domainMX'] = $domainMX;
        $domainMXrecord = array_shift($domainMX);
        $vars['mxtarget'] = $domainMXrecord->exchange;
        if($domainMXrecord->exchange == MX) {
            $vars['mx'] = 'set';
        } else {
            $var['mx'] = 'wrong';
        }
    }
    return $vars;
}

