Created
December 22, 2017 06:00
-
-
Save pareshchouhan/ceecb5fc97e6f6d2b8f8a4001b975ce4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Replace '\n' with "\n". The escape sequence is not recognized when you use '. | |
* For the question of how to write line endings, see the note here. | |
* Basically, different operating systems have different conventions for line endings. | |
* Windows uses "\r\n", unix based operating systems use "\n". | |
* You should stick to one convention (I'd chose "\n") and open your file in binary mode (fopen should get "wb", not "w"). | |
*/ | |
/** | |
* DKIMHelper | |
* Used to create keys (using opendkim-keygen) and add entries to KeyTable and SigningTable | |
*/ | |
class DKIMHelper { | |
//Selector for DKIM record | |
public $selector; | |
//Domain name for DKIM record ex. domain.com | |
public $domain; | |
//Path to DKIM Base Directory | |
public static $OPENDKIM_BASE_DIRECTORY = "G://opt//opendkim//"; | |
//Name of Keytable | |
public static $OPENDKIM_KEY_TABLE = "KeyTable"; | |
//Name of SigningTable | |
public static $OPENDKIM_SIGNING_TABLE = "SigningTable"; | |
//Name of keys directory for storing folders and private key for use with DKIM | |
public static $OPENDKIM_KEY_DIRECTORY = "keys"; | |
public function __construct($selector, $domain) { | |
$this->selector = $selector; | |
$this->domain = $domain; | |
echo "Creating Folder structure\n"; | |
$this->_createDKIMKeyFolder(); | |
echo "Adding Key Table Entry\n"; | |
$this->_addKeyTableEntry(); | |
echo "Adding Signing Table Entry\n"; | |
$this->_addSigningTableEntry(); | |
// echo $this->getDKIMValue(); | |
// $this->enableDKIM(); | |
// $this->disableDKIM(); | |
// $this->removeDKIM(); | |
} | |
private function _isValidDomain() { | |
} | |
/** | |
* getDKIMValue - returns the contents of keys/example.com/selector.txt contents(which is the actual DKIM record value.) | |
*/ | |
public function getDKIMValue() { | |
$filePath = $this->_getKeyFolderPath()."//".$this->selector.".txt"; | |
$contents = file_get_contents($filePath); | |
// echo $contents; | |
return $contents; | |
} | |
/** | |
* _addKeyTableEntry - add a DKIM Key Table Entry to KeyTable file if none exists. | |
* | |
*/ | |
//key table entry format : mail._domainkey.example.com example.com:mail:/etc/opendkim/keys/example.com/mail.private | |
private function _addKeyTableEntry() { | |
$keyTableFile = fopen(self::$OPENDKIM_BASE_DIRECTORY.self::$OPENDKIM_KEY_TABLE, "a+"); | |
// print_r(stream_get_meta_data($keyTableFile)); | |
while(!feof($keyTableFile)) { | |
$line = fgets($keyTableFile); | |
$offset = strpos($line, $this->_getKeyTableEntryRecord()); | |
if($offset !== FALSE) { | |
//found the key | |
//do nothing if key found. | |
break; | |
} | |
} | |
if($offset === FALSE) { | |
//lets add it | |
//move to end | |
fseek($keyTableFile, 0, SEEK_END); | |
flock($keyTableFile, LOCK_EX); | |
fwrite($keyTableFile, "\n"); | |
//add metadata if necessary. | |
//append data | |
fputs($keyTableFile, $this->_getKeyTableEntryRecord()); | |
fwrite($keyTableFile, "\n"); | |
flock($keyTableFile, LOCK_UN); | |
//close | |
} | |
fclose($keyTableFile); | |
} | |
public function enableDKIM() { | |
//enable DKIM Records? | |
$this->_enableDKIMKeyTableFile(); | |
$this->_enableDKIMSigningTableFile(); | |
} | |
public function disableDKIM() { | |
$this->_disableDKIMKeyTableFile(); | |
$this->_disableDKIMSigningTableFile(); | |
} | |
private function _enableDKIMKeyTableFile() { | |
$keyTableFile = fopen(self::$OPENDKIM_BASE_DIRECTORY.self::$OPENDKIM_KEY_TABLE, "c+"); | |
// print_r(stream_get_meta_data($keyTableFile)); | |
while(!feof($keyTableFile)) { | |
$line = fgets($keyTableFile); | |
$offset = strpos($line, $this->_getKeyTableEntryRecord()); | |
if($offset !== FALSE) { | |
//found the key | |
//do nothing if key found. | |
break; | |
} | |
} | |
$cursorPosition = ftell($keyTableFile); | |
//move cursor position to starrt of line | |
$cursorPosition = $cursorPosition - strlen($line); | |
fseek($keyTableFile, $cursorPosition, SEEK_SET); | |
$disabledOffset = strpos($line, "#"); | |
// echo fread($keyTableFile, 15); | |
//if disabledOffset = FALSE then item is not disabled | |
if($disabledOffset === FALSE) { | |
// do nothing | |
echo "Already Enabled\n"; | |
} else { | |
echo "Writing data to file \n"; | |
//get a lock on file before editing | |
$lineLength = strlen($line); | |
$line = preg_replace("/./", " ", $line); | |
//fwrite and flock are used since this file can be accessed by multiple processes at once | |
//updation by other process should not result in our changes being lost so we get a exclusive write to it. | |
flock($keyTableFile, LOCK_EX); | |
fwrite($keyTableFile, $line, $lineLength); | |
fseek($keyTableFile, $cursorPosition, SEEK_SET); | |
fwrite($keyTableFile, $this->_getKeyTableEntryRecord()); | |
flock($keyTableFile, LOCK_UN); | |
} | |
fclose($keyTableFile); | |
} | |
private function _disableDKIMKeyTableFile() { | |
//disable DKIM records. | |
$keyTableFile = fopen(self::$OPENDKIM_BASE_DIRECTORY.self::$OPENDKIM_KEY_TABLE, "c+"); | |
// print_r(stream_get_meta_data($keyTableFile)); | |
while(!feof($keyTableFile)) { | |
$line = fgets($keyTableFile); | |
$offset = strpos($line, $this->_getKeyTableEntryRecord()); | |
if($offset !== FALSE) { | |
//found the key | |
//do nothing if key found. | |
break; | |
} | |
} | |
$cursorPosition = ftell($keyTableFile); | |
//move cursor position to starrt of line | |
$cursorPosition = $cursorPosition - strlen($line); | |
fseek($keyTableFile, $cursorPosition, SEEK_SET); | |
$disabledOffset = strpos($line, "#"); | |
// echo fread($keyTableFile, 15); | |
//if disabledOffset = FALSE then item is not disabled | |
if($disabledOffset === FALSE) { | |
// do nothing | |
//get a lock on file before editing | |
$lineLength = strlen($line); | |
$line = preg_replace("/./", " ", $line); | |
//fwrite and flock are used since this file can be accessed by multiple processes at once | |
//updation by other process should not result in our changes being lost so we get a exclusive write to it. | |
flock($keyTableFile, LOCK_EX); | |
fwrite($keyTableFile, $line, $lineLength); | |
fseek($keyTableFile, $cursorPosition, SEEK_SET); | |
fwrite($keyTableFile, '#'.$this->_getKeyTableEntryRecord()); | |
flock($keyTableFile, LOCK_UN); | |
} else { | |
} | |
fclose($keyTableFile); | |
} | |
private function _getKeyTableEntryRecord() { | |
return $this->selector."._domainkey.".$this->domain." ".$this->domain.":".$this->selector.":".$this->_getKeyFolderPath()."/".$this->selector.".private"; | |
} | |
private function _addSigningTableEntry() { | |
$signingTableFile = fopen(self::$OPENDKIM_BASE_DIRECTORY.self::$OPENDKIM_SIGNING_TABLE, "a+"); | |
while(!feof($signingTableFile)) { | |
$line = fgets($signingTableFile); | |
$offset = strpos($line, $this->_getSigningTableEntryRecord()); | |
if($offset !== FALSE) { | |
//found the key | |
//do nothing if key found. | |
break; | |
} | |
} | |
if($offset === FALSE) { | |
//lets add it | |
//move to end | |
fseek($signingTableFile, 0, SEEK_END); | |
flock($signingTableFile, LOCK_EX); | |
fwrite($signingTableFile, "\n"); | |
//append data | |
fputs($signingTableFile, $this->_getSigningTableEntryRecord()); | |
fwrite($signingTableFile, "\n"); | |
flock($signingTableFile, LOCK_UN); | |
//close | |
} | |
fclose($signingTableFile); | |
} | |
private function _enableDKIMSigningTableFile() { | |
$signingTableFile = fopen(self::$OPENDKIM_BASE_DIRECTORY.self::$OPENDKIM_SIGNING_TABLE, "c+"); | |
// print_r(stream_get_meta_data($signingTableFile)); | |
while(!feof($signingTableFile)) { | |
$line = fgets($signingTableFile); | |
$offset = strpos($line, $this->_getSigningTableEntryRecord()); | |
if($offset !== FALSE) { | |
//found the key | |
//do nothing if key found. | |
break; | |
} | |
} | |
$cursorPosition = ftell($signingTableFile); | |
//move cursor position to starrt of line | |
$cursorPosition = $cursorPosition - strlen($line); | |
fseek($signingTableFile, $cursorPosition, SEEK_SET); | |
$disabledOffset = strpos($line, "#"); | |
// echo fread($signingTableFile, 15); | |
//if disabledOffset = FALSE then item is not disabled | |
if($disabledOffset === FALSE) { | |
// do nothing | |
echo "Already Enabled\n"; | |
} else { | |
echo "Writing data to file \n"; | |
//get a lock on file before editing | |
$lineLength = strlen($line); | |
$line = preg_replace("/./", " ", $line); | |
//fwrite and flock are used since this file can be accessed by multiple processes at once | |
//updation by other process should not result in our changes being lost so we get a exclusive write to it. | |
flock($signingTableFile, LOCK_EX); | |
fwrite($signingTableFile, $line, $lineLength); | |
fseek($signingTableFile, $cursorPosition, SEEK_SET); | |
fwrite($signingTableFile, $this->_getSigningTableEntryRecord()); | |
flock($signingTableFile, LOCK_UN); | |
} | |
fclose($signingTableFile); | |
} | |
private function _disableDKIMSigningTableFile() { | |
//disable DKIM records. | |
$signingTableFile = fopen(self::$OPENDKIM_BASE_DIRECTORY.self::$OPENDKIM_SIGNING_TABLE, "c+"); | |
// print_r(stream_get_meta_data($signingTableFile)); | |
while(!feof($signingTableFile)) { | |
$line = fgets($signingTableFile); | |
$offset = strpos($line, $this->_getSigningTableEntryRecord()); | |
if($offset !== FALSE) { | |
//found the key | |
//do nothing if key found. | |
break; | |
} | |
} | |
$cursorPosition = ftell($signingTableFile); | |
//move cursor position to starrt of line | |
$cursorPosition = $cursorPosition - strlen($line); | |
fseek($signingTableFile, $cursorPosition, SEEK_SET); | |
$disabledOffset = strpos($line, "#"); | |
// echo fread($signingTableFile, 15); | |
//if disabledOffset = FALSE then item is not disabled | |
if($disabledOffset === FALSE) { | |
// do nothing | |
//get a lock on file before editing | |
$lineLength = strlen($line); | |
$line = preg_replace("/./", " ", $line); | |
//fwrite and flock are used since this file can be accessed by multiple processes at once | |
//updation by other process should not result in our changes being lost so we get a exclusive write to it. | |
flock($signingTableFile, LOCK_EX); | |
fwrite($signingTableFile, $line, $lineLength); | |
fseek($signingTableFile, $cursorPosition, SEEK_SET); | |
fwrite($signingTableFile, '#'.$this->_getSigningTableEntryRecord()); | |
flock($signingTableFile, LOCK_UN); | |
} else { | |
} | |
fclose($signingTableFile); | |
} | |
//Signing tablle entry format *@example.com mail._domainkey.example.com | |
private function _getSigningTableEntryRecord() { | |
return "*@".$this->domain." ".$this->selector."._domainkey.".$this->domain; | |
} | |
/** | |
* _createDKIMKeyFolder - create key folder if none exists | |
* a folder inside /opt/opendkim/keys/ is created with the same name as that of $this->domain | |
* /opt/opendkim/keys/google.com | |
* Private key and DKIM TXT record is generated if none exists. | |
*/ | |
private function _createDKIMKeyFolder() { | |
if(file_exists($this->_getKeyFolderPath())) { | |
//if folder exists make see if file is present | |
if(file_exists($this->_getKeyFolderPath()."//".$this->selector.".txt") && file_exists($this->_getKeyFolderPath()."//".$this->selector.".private")) { | |
//if keyfile and dkim exists. | |
//do nothing. | |
} else { | |
echo $this->_generateDKIMKeys(); | |
} | |
} else { | |
//create folder | |
if(mkdir($this->_getKeyFolderPath())) { | |
//directory created. | |
echo "Directory Created"; | |
echo $this->_generateDKIMKeys(); | |
} else { | |
//stop | |
die(); | |
} | |
} | |
} | |
private function _generateDKIMKeys() { | |
return shell_exec("cd ".$this->_getKeyFolderPath()."//".$this->domain." && opendkim-keygen -s ".$this->selector." -d ".$this->domain); | |
} | |
private function _getKeyFolderPath() { | |
return self::$OPENDKIM_BASE_DIRECTORY.self::$OPENDKIM_KEY_DIRECTORY."//".$this->domain; | |
} | |
public function removeDKIM() { | |
//delete keys | |
$output = shell_exec("rm -rf ".$this->_getKeyFolderPath()."//".$this->domain); | |
//remove entries from KeyTable and SigningTable. | |
$this->_removeKeyTablEntry(); | |
$this->_removeSigningTableEntry(); | |
} | |
private function _removeKeyTablEntry() { | |
$keyTableFile = fopen(self::$OPENDKIM_BASE_DIRECTORY.self::$OPENDKIM_KEY_TABLE, "c+"); | |
// print_r(stream_get_meta_data($keyTableFile)); | |
while(!feof($keyTableFile)) { | |
$line = fgets($keyTableFile); | |
$offset = strpos($line, $this->_getKeyTableEntryRecord()); | |
if($offset !== FALSE) { | |
//found the key | |
//do nothing if key found. | |
break; | |
} | |
} | |
$cursorPosition = ftell($keyTableFile); | |
//move cursor position to starrt of line | |
$cursorPosition = $cursorPosition - strlen($line); | |
fseek($keyTableFile, $cursorPosition, SEEK_SET); | |
if($offset === FALSE) { | |
// do nothing | |
echo "Non Existent\n"; | |
} else { | |
//get a lock on file before editing | |
$lineLength = strlen($line); | |
$line = preg_replace("/./", " ", $line); | |
//fwrite and flock are used since this file can be accessed by multiple processes at once | |
//updation by other process should not result in our changes being lost so we get a exclusive write to it. | |
flock($keyTableFile, LOCK_EX); | |
fwrite($keyTableFile, $line, $lineLength); | |
flock($keyTableFile, LOCK_UN); | |
} | |
fclose($keyTableFile); | |
} | |
private function _removeSigningTableEntry() { | |
$signingTableFile = fopen(self::$OPENDKIM_BASE_DIRECTORY.self::$OPENDKIM_SIGNING_TABLE, "c+"); | |
// print_r(stream_get_meta_data($signingTableFile)); | |
while(!feof($signingTableFile)) { | |
$line = fgets($signingTableFile); | |
$offset = strpos($line, $this->_getSigningTableEntryRecord()); | |
if($offset !== FALSE) { | |
//found the key | |
//do nothing if key found. | |
break; | |
} | |
} | |
$cursorPosition = ftell($signingTableFile); | |
//move cursor position to starrt of line | |
$cursorPosition = $cursorPosition - strlen($line); | |
fseek($signingTableFile, $cursorPosition, SEEK_SET); | |
if($offset === FALSE) { | |
// do nothing | |
echo "Non Existent\n"; | |
} else { | |
//get a lock on file before editing | |
$lineLength = strlen($line); | |
$line = preg_replace("/./", " ", $line); | |
//fwrite and flock are used since this file can be accessed by multiple processes at once | |
//updation by other process should not result in our changes being lost so we get a exclusive write to it. | |
flock($signingTableFile, LOCK_EX); | |
fwrite($signingTableFile, $line, $lineLength); | |
flock($signingTableFile, LOCK_UN); | |
} | |
fclose($signingTableFile); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment