<?php
/* $Id$ */
/* Copyright (C) 2006 Daniel S. Haischt */
require_once("functions.inc");
require_once("dspam.inc");

function sync_package_dspam() {
  global $config, $g;
  conf_mount_rw();
  config_lock();
  $fd = fopen("/etc/dspam.conf","w");

  $dspamcfg = <<<EOD
## dspam.conf -- DSPAM configuration file
## Generated by pfSense
Home			/var/db/dspam
## Database Settings
StorageDriver		/usr/local/lib/libmysql_drv.so
MySQLServer		/tmp/mysql.sock
MySQLPort
MySQLUser		dspam
MySQLPass		dspam
MySQLDb			dspam
MySQLCompress		true
MySQLSupressQuote	off
MySQLConnectionCache	10
MySQLUIDInSignature	on
## Delivery Settings
TrustedDeliveryAgent	"/usr/bin/mail"
DeliveryHost		192.168.1.6
DeliveryPort		24
DeliveryIdent		localhost
DeliveryProto		smtp
OnFail			error
## DSPAM Privileges
Trust			root
Trust			mail
Trust			mailnull
Trust			smmsp
Trust			daemon
## DSPAM Engine Settings
TrainingMode		teft
TestConditionalTraining	on
Feature			chained
Feature			whitelist
Algorithm		graham burton
PValue			graham
ImprobabilityDrive	on
Preference		"spamAction=quarantine"
Preference		"signatureLocation=message"
Preference		"showFactors=on"
AllowOverride		trainingMode
AllowOverride		spamAction spamSubject
AllowOverride		statisticalSedation
AllowOverride		enableBNR
AllowOverride		enableWhitelist
AllowOverride		signatureLocation
AllowOverride		showFactors
AllowOverride		optIn optOut
AllowOverride		whitelistThreshold
## Miscellaneous Settings
FailoverAttempts	1
IgnoreHeader		X-Spam-Scanned
IgnoreHeader		X-Spam-Status
IgnoreHeader		X-Virus-Scanner-Result
RBLInoculate		on
Notifications		on
## Maintainance Settings
PurgeSignatures		14
PurgeNeutral		90
PurgeUnused		90
PurgeHapaxes		30
PurgeHits1S		15
PurgeHits1I		15
## System Settings
LocalMX			127.0.0.1
SystemLog		on
UserLog			on
Opt			out
ParseToHeaders		on
ChangeModeOnParse	on
ChangeUserOnParse	on
Broken			returnCodes
Broken			case
Broken			lineStripping
MaxMessageSize		307200
ProcessorBias		on
## ClamAV Engine Settings
ClamAVPort		3310
ClamAVHost		127.0.0.1
ClamAVResponse		accept
## DSPAM Daemon Settings (Server)
ServerPort		24
ServerQueueSize		32
ServerPID		/var/run/dspam/dspam.pid
ServerMode		standard
ServerParameters	"--deliver=innocent -d %u"
ServerIdent		"abysseleven.abyssworld.de"
ServerDomainSocketPath	"/var/run/dspam/dspam.sock"
## EOF

EOD;

  /* flush the default config to the file */
  fwrite($fd, $dspamcfg);
  fclose($fd);

  $fd = fopen("/usr/local/bin/dspam_spamfeed","w");

  $spamfeed = <<<EOD
#!/bin/sh
#
# automatically generated by pfSense

cat \${2} | dspam --mode=teft --source=corpus --class=spam --feature=chained,noise --user \${1}

EOD;

  fwrite($fd, $spamfeed);
  fclose($fd);
  mwexec("chmod a+x /usr/local/bin/dspam_spamfeed");

  $fd = fopen("/usr/local/bin/dspam_innocentfeed","w");

  $innocentfeed = <<<EOD
#!/bin/sh
#
# automatically generated by pfSense

cat \${2} | dspam --mode=teft --source=corpus --class=innocent --feature=chained,noise --user \${1}

EOD;

  fwrite($fd, $innocentfeed);
  fclose($fd);
  mwexec("chmod a+x /usr/local/bin/dspam_innocentfeed");

  $start = <<<EOD
test_dspam_user=`cat /etc/passwd | grep dspam`
test_dspam_db=`mysql information_schema -e "select schema_name from schemata" | grep dspam`
test_dspam_db_user=`mysql mysql -e "select User from user" | grep dspam`

if [ -z "\${test_dspam_user}" ]; then
  pw useradd dspam -u 107 -g mail -d /var/db/dspam -s /bin/csh -c 'DSPAM Daemon User'
fi

if [ ! -d "/var/run/dspam" ]; then
  mkdir /var/run/dspam && chown dspam:mail /var/run/dspam
fi

if [ -z "\${test_dspam_db}" ]; then
  mysql -D mysql -e "create database dspam"
  if [ -z "\${test_dspam_db_user}" ]; then
    mysql -D mysql -e "GRANT ALL PRIVILEGES ON dspam.* TO dspam@localhost IDENTIFIED BY 'dspam'"
  fi
  mysql -udspam -pdspam dspam < /usr/local/share/examples/dspam/mysql/mysql_objects-space.sql && \
    mysql -udspam -pdspam dspam < /usr/local/share/examples/dspam/mysql/virtual_users.sql
fi

/sbin/mount_fdescfs fdescfs /dev/fd
/usr/local/bin/dspam --daemon &

EOD;

  $stop  = "/usr/bin/killall dspam\n" .
          "sleep 2";
  write_rcfile(array(
              "file" => "dspam.sh",
              "start" => $start,
              "stop" =>  $stop
              )
  );
  conf_mount_ro();
  config_unlock();

  if (! file_exists("/usr/local/etc/dspam.conf")) {
    mwexec("ln -s /etc/dspam.conf /usr/local/etc/dspam.conf");
  }

  mwexec("/usr/local/etc/rc.d/dspam.sh stop");
  mwexec("/usr/local/etc/rc.d/dspam.sh start");

  return 0;
}

function dspam_configure() {
  global $config, $g;

  $dspamcfg = $config['installedpackages']['dspam']['config'][0];

  if ($g['booting'])
    echo "Starting DSPAM service... ";
  else
    sleep(1);

  /* write dhcpd.conf */
  $fd = fopen("/usr/local/etc/dspam.conf", "w");
  if (!$fd) {
    printf("Error: cannot open dhcpd.conf in services_dhcpd_configure().\n");
    return 1;
  }

  $dspamconf = <<<EOD
## dspam.conf -- DSPAM configuration file
## Generated by pfSense
Home			/var/db/dspam
## Database Settings

EOD;

  if ($dspamcfg['storage-driver'] == "mysql") {
    $dspamconf .= "StorageDriver\t\t/usr/local/lib/libmysql_drv.so\n";
    $dspamconf .= <<<EOD
MySQLServer		{$dspamcfg['dbsettings'][0]['mysql-server']}
MySQLPort		{$dspamcfg['dbsettings'][0]['mysql-port']}
MySQLUser		{$dspamcfg['dbsettings'][0]['mysql-user']}
MySQLPass		{$dspamcfg['dbsettings'][0]['mysql-password']}
MySQLDb			{$dspamcfg['dbsettings'][0]['mysql-database']}

EOD;
    isset($dspamcfg['dbsettings'][0]['mysql-compress']) ? $dspamconf .= "MySQLCompress\t\ttrue\n" : $dspamconf .= "MySQLCompress\tfalse\n";
    isset($dspamcfg['dbsettings'][0]['mysql-squote']) ? $dspamconf .= "MySQLSupressQuote\ton\n" : $dspamconf .= "MySQLSupressQuote\toff\n";
    isset($dspamcfg['dbsettings'][0]['mysql-ccache']) ? $dspamconf .= "MySQLConnectionCache\t{$dspamcfg['dbsettings'][0]['mysql-ccache']}\n" : $dspamconf .= "MySQLConnectionCache\t10\n";
    isset($dspamcfg['dbsettings'][0]['mysql-uid']) ? $dspamconf .= "MySQLUIDInSignature\ton\n" : $dspamconf .= "MySQLUIDInSignature\toff\n";
  } else if ($dspamcfg['storage-driver'] == "sqlite") {
    $dspamconf .= "StorageDriver\t\t/usr/local/lib/libsqlite3_drv.so\n";
    if (isset($dspamcfg['dbsettings'][0]['sqlite-pragma'])) $dspamconf .= "SQLitePragma\t\t{$dspamcfg['dbsettings'][0]['sqlite-pragma']}\n";
  } else if ($dspamcfg['storage-driver'] == "pgsql") {
    $dspamconf .= "StorageDriver\t\t/usr/local/lib/libpgsql_drv.so\n";
    $dspamconf .= <<<EOD
PgSQLServer		{$dspamcfg['dbsettings'][0]['pgsql-server']}
PgSQLPort		{$dspamcfg['dbsettings'][0]['pgsql-port']}
PgSQLUser		{$dspamcfg['dbsettings'][0]['pgsql-user']}
PgSQLPass		{$dspamcfg['dbsettings'][0]['pgsql-password']}
PgSQLDb			{$dspamcfg['dbsettings'][0]['pgsql-database']}

EOD;
    isset($dspamcfg['dbsettings'][0]['pgsql-ccache']) ? $dspamconf .= "PgSQLConnectionCache\t{$dspamcfg['dbsettings'][0]['pgsql-ccache']}\n" : $dspamconf .= "PgSQLConnectionCache\t3\n";
    isset($dspamcfg['dbsettings'][0]['pgsql-uid']) ? $dspamconf .= "PgSQLUIDInSignature\ton\n" : $dspamconf .= "PgSQLUIDInSignature\toff\n";
  } else if ($dspamcfg['storage-driver'] == "oracle") {
    $dspamconf .= "StorageDriver\t/usr/local/lib/libora_drv.so\n";
    $dspamconf .= <<<EOD
OraServer	{$dspamcfg['dbsettings'][0]['ora-server']}
OraUser		{$dspamcfg['dbsettings'][0]['ora-user']}
OraPass		{$dspamcfg['dbsettings'][0]['ora-password']}
OraSchema	{$dspamcfg['dbsettings'][0]['ora-schema']}

EOD;
  } else if ($dspamcfg['storage-driver'] == "hash") {
    $dspamconf .= "StorageDriver\t\t/usr/local/lib/libhash_drv.so\n";
    $dspamconf .= <<<EOD
HashRecMax		{$dspamcfg['dbsettings'][0]['hash-rec-max']}
HashMaxExtents		{$dspamcfg['dbsettings'][0]['hash-max-ext']}
HashExtentSize		{$dspamcfg['dbsettings'][0]['hash-ext-size']}
HashMaxSeek		{$dspamcfg['dbsettings'][0]['hash-max-seek']}
HashConnectionCache	{$dspamcfg['dbsettings'][0]['hash-co-cache']}

EOD;
    isset($dspamcfg['dbsettings'][0]['hash-auto-ex']) ? $dspamconf .= "HashAutoExtend\t\ton\n" : $dspamconf .= "HashAutoExtend\toff\n";
    if (isset($dspamcfg['dbsettings'][0]['hash-co-user'])) $dspamconf .= "HashConcurrentUser\t{$dspamcfg['dbsettings'][0]['hash-co-user']}\n";
  }

  $dspamconf .= "## Delivery Settings\n";

  if ($dspamcfg['tdelivery-agent'] == "procmail") {
    $dspamconf .= "TrustedDeliveryAgent\t\"/usr/local/bin/procmail\"\n";
  } else if ($dspamcfg['tdelivery-agent'] == "mail") {
    $dspamconf .= "TrustedDeliveryAgent\t\"/usr/bin/mail\"\n";
  } else if ($dspamcfg['tdelivery-agent'] == "mail.local") {
    $dspamconf .= "TrustedDeliveryAgent\t\"/usr/libexec/mail.local\"\n";
  } else if ($dspamcfg['tdelivery-agent'] == "deliver") {
    $dspamconf .= "TrustedDeliveryAgent\t\"/usr/local/cyrus/bin/deliver\"\n";
  } else if ($dspamcfg['tdelivery-agent'] == "maildrop") {
    $dspamconf .= "TrustedDeliveryAgent\t\"/usr/local/bin/maildrop\"\n";
  } else if ($dspamcfg['tdelivery-agent'] == "exim") {
    $dspamconf .= "TrustedDeliveryAgent\t\"/usr/local/sbin/exim -oMr spam-scanned\"\n";
  }

  if (isset($dspamcfg['tcpip-delivery'])) {
    $dspamconf .= <<<EOD
DeliveryHost		{$dspamcfg['tcpip-delivery-host']}
DeliveryPort		{$dspamcfg['tcpip-delivery-port']}
DeliveryIdent		{$dspamcfg['tcpip-delivery-ident']}
DeliveryProto		{$dspamcfg['tcpip-delivery-proto']}

EOD;
  }

  /* TODO: If required add the following, currently
     missing options:

     - QuarantineAgent
     - EnablePlusedDetail
     - QuarantineMailbox
  */

  $dspamconf .= "OnFail\t\t\t{$dspamcfg['delivery-onfail']}\n";
  $dspamconf .= "## DSPAM Privileges\n";

  $t_users = &$dspamcfg['tuser'];

  foreach ($t_users as $user) {
    $dspamconf .= "Trust\t\t\t{$user['name']}\n";
  }

  if (isset($dspamcfg['debug-enable'])) {
    $dspamconf .= "## DSPAM Debugging Options\n";
    $dspamconf .= "Debug\t\t\t{$dspamcfg['debug-whom']}\n";
    $dspamconf .= "DebugOpt\t\t{$dspamcfg['debug-options']}\n";
  }

  $dspamconf .= "## DSPAM Engine Settings\n";
  $dspamconf .= "TrainingMode\t\t{$dspamcfg['training-mode']}\n";
  isset($dspamcfg['test-cond-training']) ? $dspamconf .= "TestConditionalTraining\ton\n" : $dspamconf .= "TestConditionalTraining\toff\n";

  $t_features = &$dspamcfg['feature'];

  foreach ($t_features as $feature) {
    $dspamconf .= "Feature\t\t\t{$feature['name']}\n";
  }

  $t_algos = &$dspamcfg['algorithm'];

  if (count($t_algos) > 0) {
    $dspamconf .= "Algorithm\t\t";

    foreach ($t_algos as $algo) {
      $dspamconf .= "{$algo['name']} ";
    }

    $dspamconf .= "\n";
  }

  $dspamconf .= "PValue\t\t\t{$dspamcfg['pvalue']}\n";
  isset($dspamcfg['improbability-drive']) ? $dspamconf .= "ImprobabilityDrive\ton\n" : $dspamconf .= "ImprobabilityDrive\toff\n";

  $t_prefs = &$dspamcfg['preference'];

  foreach ($t_prefs as $pref) {
    $dspamconf .= "Preference\t\t{$pref['value']}\n";
  }

  $t_overr = &$dspamcfg['override'];

  foreach ($t_overr as $over) {
    $dspamconf .= "AllowOverride\t\t{$over['value']}\n";
  }

  if (isset($dspamcfg['ldap-enable'])) {
    $dspamconf .= <<<EOD
## LDAP Settings
LDAPMode		{$dspamcfg['ldap-mode']}
LDAPHost		{$dspamcfg['ldap-host']}
LDAPFilter		{$dspamcfg['ldap-filter']}
LDAPBase		{$dspamcfg['ldap-base']}

EOD;
  }

  $dspamconf .= "## Miscellaneous Settings\n";
  if (isset($dspamcfg['failover-attempts'])) $dspamconf .= "FailoverAttempts\t{$dspamcfg['failover-attempts']}\n";

  $t_headers = &$dspamcfg['header'];

  if (is_array($t_headers)) {
    foreach ($t_headers as $header) {
      $dspamconf .= "IgnoreHeader\t\t{$header['name']}\n";
    }
  }

  if (isset($dspamcfg['sbl-enable'])) {
    $dspamconf .= "Lookup\t\t\t\"{$dspamcfg['sbl-host']}\"\n";
  }

  isset($dspamcfg['rbl-inoculate']) ? $dspamconf .= "RBLInoculate\t\ton\n" : $dspamconf .= "RBLInoculate\toff\n";
  isset($dspamcfg['notification-email']) ? $dspamconf .= "Notifications\t\ton\n" : $dspamconf .= "Notifications\toff\n";

  $dspamconf .= <<<EOD
## Maintainance Settings
PurgeSignatures		{$dspamcfg['purge-signatures']}
PurgeNeutral		{$dspamcfg['purge-neutral']}
PurgeUnused		{$dspamcfg['purge-unused']}
PurgeHapaxes		{$dspamcfg['purge-hapaxes']}
PurgeHits1S		{$dspamcfg['purge-hits-1s']}
PurgeHits1I		{$dspamcfg['purge-hits-1s']}

EOD;

  $dspamconf .= "## System Settings\n";
  $dspamconf .= "LocalMX\t\t\t{$dspamcfg['local-mx']}\n";
  isset($dspamcfg['system-log']) ? $dspamconf .= "SystemLog\t\ton\n" : $dspamconf .= "SystemLog\toff\n";
  isset($dspamcfg['user-log']) ? $dspamconf .= "UserLog\t\t\ton\n" : $dspamconf .= "UserLog\toff\n";
  $dspamconf .= "Opt\t\t\t{$dspamcfg['filter-opt']}\n";
  isset($dspamcfg['parse-to-headers']) ? $dspamconf .= "ParseToHeaders\t\ton\n" : $dspamconf .= "ParseToHeaders\toff\n";
  isset($dspamcfg['change-mode-on-parse']) ? $dspamconf .= "ChangeModeOnParse\ton\n" : $dspamconf .= "ChangeModeOnParse\toff\n";
  isset($dspamcfg['change-user-on-parse']) ? $dspamconf .= "ChangeUserOnParse\ton\n" : $dspamconf .= "ChangeUserOnParse\toff\n";

  if (isset($dspamcfg['broken-mta-settings'])) {
    $t_bmtas = &$dspamcfg['bmta'];

    foreach ($t_bmtas as $bmta) {
      $dspamconf .= "Broken\t\t\t{$bmta['name']}\n";
    }
  }

  $dspamconf .= "MaxMessageSize\t\t{$dspamcfg['max-message-size']}\n";
  isset($dspamcfg['processor-bias']) ? $dspamconf .= "ProcessorBias\t\ton\n" : $dspamconf .= "ProcessorBias\toff\n";

  if (isset($dspamcfg['clamav-enable'])) {
    $dspamconf .= <<<EOD
## ClamAV Engine Settings
ClamAVPort		{$dspamcfg['clamav-port']}
ClamAVHost		{$dspamcfg['clamav-host']}
ClamAVResponse		{$dspamcfg['clamav-response']}

EOD;
  }

  $dspamconf .= <<<EOD
## DSPAM Daemon Settings (Server)
ServerPort		{$dspamcfg['dspam-server-port']}
ServerQueueSize		{$dspamcfg['dspam-server-queue-size']}
ServerPID		{$dspamcfg['dspam-server-pid']}
ServerMode		{$dspamcfg['dspam-server-mode']}

EOD;

  if ($dspamcfg['dspam-server-mode'] == "dspam") {
    $t_spwds = &$dspamcfg['server-pwd'];
    $i = 1;

      if (is_array($t_spwds)) {
      foreach ($t_spwds as $spwd) {
        $dspamconf .= "ServerPass.Relay{$i}\t\"{$spwd['value']}\"\n";
        $i++;
      }
    }
  } else if ($dspamcfg['dspam-server-mode'] == "standard") {
    $dspamconf .= <<<EOD
ServerParameters	"{$dspamcfg['dspam-server-params']}"
ServerIdent		"{$dspamcfg['dspam-server-id']}"

EOD;
  }

  if (isset($dspamcfg['dspam-server-socket'])) {
    $dspamconf .= "ServerDomainSocketPath\t\"{$dspamcfg['dspam-server-socket']}\"\n";
  }

  if (isset($dspamcfg['dspam-client-enable']) && $dspamcfg['dspam-client-enable'] <> "") {
    $dspamconf .= <<<EOD
## DSPAM Daemon Settings (Client)
ClientHost		{$dspamcfg['dspam-client-host']}
ClientIdent		{$dspamcfg['dspam-client-id']}

EOD;

    if (isset($dspamcfg['dspam-client-port']) && $dspamcfg['dspam-client-port'] <> "") {
      $dspamconf .= "ClientPort\t\t{$dspamcfg['dspam-client-port']}\n";
    }
  }

  $dspamconf .= "## EOF\n";

  fwrite($fd, $dspamconf);
  fclose($fd);

  /* fire up dspam --daemon */
  mwexec("/usr/local/etc/rc.d/dspam.sh stop");
  mwexec("/usr/local/etc/rc.d/dspam.sh start");

  if ($g['booting']) {
    print "done.\n";
  }

  return 0;
}

function custom_php_install_command() {
  global $config, $g;
  /* create a default config */
  sync_package_dspam();
}

function custom_php_deinstall_command() {
  global $config, $g;
  conf_mount_rw();
  unlink_if_exists("/usr/local/etc/rc.d/dspam.sh");
  unlink_if_exists("/usr/local/etc/dspam.conf");
  unlink_if_exists("/usr/local/bin/dspam_spamfeed");
  unlink_if_exists("/usr/local/bin/dspam_innocentfeed");
  conf_mount_ro();
}

function checkForLDAPSupport() {
        $pd = popen("ldd /usr/local/bin/dspam", "r");
        while (!feof($pd)) {
          $dspamstr .= fgets($pd, 4096);
        }
        pclose($pd);

        if (strpos($dspamstr, "libldap") !== false &&
            file_exists("/usr/local/lib/libldap.so") &&
            file_exists("/usr/local/lib/liblber.so")) {
            return true;
        }

        return false;
}

function checkForPgSQLSupport() {
  if (file_exists("/usr/local/lib/libpgsql_drv.so") &&
      file_exists("/usr/local/lib/libpq.so")) {
    return true;
  }

  return false;
}

function checkForMySQLSupport() {
  if (file_exists("/usr/local/lib/libmysql_drv.so") &&
      file_exists("/usr/local/lib/mysql/libmysqlclient.so")) {
    return true;
  }

  return false;
}

function checkForSQLiteSupport() {
  if (file_exists("/usr/local/lib/libsqlite3_drv.so") &&
      file_exists("/usr/local/lib/mysql/libsqlite3.so")) {
    return true;
  }

  return false;
}

function checkForClamAVSupport() {
  if (file_exists("/usr/local/bin/clamdscan") &&
      file_exists("/usr/local/bin/clamscan") &&
      file_exists("/usr/local/sbin/clamd")) {
    return true;
  }

  return false;
}

?>