DnsHelper.php 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. <?php
  2. namespace ThurData\Servers\KerioEmail\Core\Helper;
  3. use ThurData\Servers\KerioEmail\Core\Models\Whmcs\Server;
  4. use ThurData\Servers\KerioEmail\Api\KerioWhmcs;
  5. use \WHMCS\Database\Capsule;
  6. require_once '/usr/share/php/Net/DNS2.php';
  7. use \Net\DNS2\Net_DNS2_Resolver as Net_DNS2_Resolver;
  8. /**
  9. * Wrapper for WHMCS params passed to controler functions
  10. *
  11. * @autor ThurData <info@thurdata.ch>
  12. */
  13. class DnsHelper
  14. {
  15. use \ThurData\Servers\KerioEmail\Core\UI\Traits\WhmcsParams;
  16. public function __construct()
  17. {
  18. $this->params = $this->getWhmcsParamsByKeys(['domain', 'userid', 'serverhostname', 'serverusername', 'serverpassword', 'domainid', 'serverid', 'pid']);
  19. $this->server = Server::select('id', 'nameserver1ip', 'nameserver2ip')->findOrFail($this->params['serverid']);
  20. $this->nameserver = array(trim($this->server->nameserver1ip), trim($this->server->nameserver2ip));
  21. // $this->nameserver = array('127.0.0.1', '127.0.0.2'); //test
  22. $this->resolver = new \Net_DNS2_Resolver(array('nameservers' => $this->nameserver));
  23. }
  24. public function getMX($domain){
  25. try {
  26. $result = $this->resolver->query($domain, 'MX');
  27. } catch(\Net_DNS2_Exception $e) {
  28. echo "::query() failed: ", $e->getMessage(), "\n";
  29. }
  30. $domainMX = $result->answer;
  31. if(empty($domainMX)){
  32. $vars['mx'] = 'unset';
  33. $vars['mxtarget'] = $this->params['serverhostname'];
  34. } else {
  35. if(count($domainMX) > 1) {
  36. $vars['multiMX'] = TRUE;
  37. } else {
  38. $vars['multiMX'] = FALSE;
  39. }
  40. $vars['domainMX'] = $domainMX;
  41. $domainMXrecord = array_shift($domainMX);
  42. $vars['mxtarget'] = $domainMXrecord->exchange;
  43. if($domainMXrecord->exchange == $this->params['serverhostname']) {
  44. $vars['mx'] = 'set';
  45. } else {
  46. $var['mx'] = 'wrong';
  47. }
  48. }
  49. return $vars;
  50. }
  51. public function getSPF($domain){
  52. try {
  53. $result = $this->resolver->query($domain, 'MX');
  54. } catch(\Net_DNS2_Exception $e) {
  55. echo "::query() failed: ", $e->getMessage(), "\n";
  56. }
  57. $domainMX = $result->answer;
  58. if(count($domainMX) > 1) {
  59. $vars['multiMX'] = TRUE;
  60. } else {
  61. $vars['multiMX'] = FALSE;
  62. }
  63. if(empty($domainMX)){
  64. $vars['mx'] = 'unset';
  65. $vars['mxtarget'] = $this->params['serverhostname'];
  66. } else {
  67. $vars['domainMX'] = $domainMX;
  68. $domainMXrecord = array_shift($domainMX);
  69. $vars['mxtarget'] = $domainMXrecord->exchange;
  70. if($domainMXrecord->exchange == $this->params['serverhostname']) {
  71. $vars['mx'] = 'set';
  72. } else {
  73. $var['mx'] = 'wrong';
  74. }
  75. }
  76. return $vars;
  77. }
  78. public function getRecords($domain) {
  79. $zoneID = $this->selfDns($domain);
  80. if($zoneID) {
  81. return $this->getLocalRecords($zoneID);
  82. }
  83. return $this->getResolverRecords($domain);
  84. }
  85. public function getResolverRecords($domain)
  86. {
  87. $vars['mx'] = array();
  88. $vars['spf'] = array();
  89. $vars['dmarc'] = array();
  90. $vars['dkim'] = array();
  91. try {
  92. $responseMX = $this->resolver->query($domain, 'MX');
  93. $responseTXT = $this->resolver->query($domain, 'TXT');
  94. } catch(\Net_DNS2_Exception $e) {
  95. echo "::query() failed: ", $e->getMessage(), "\n";
  96. }
  97. $domainMX = $responseMX->answer;
  98. $domainTXT = $responseTXT->answer;
  99. foreach($domainMX as $mxRecord) {
  100. array_push($vars['mx'], $mxRecord->exchange);
  101. }
  102. foreach($domainTXT as $txtRecord) {
  103. foreach($txtRecord->text as $txtData) {
  104. if(strstr($txtData,'v=spf')) {
  105. array_push($vars['spf'],$txtData);
  106. }
  107. if(strstr($txtData,'v=DMARC')) {
  108. array_push($vars['dmarc'],$txtData);
  109. }
  110. if(strstr($txtData,'v=DKIM')) {
  111. array_push($vars['dkim'],$txtData);
  112. }
  113. }
  114. }
  115. logModuleCall(
  116. 'kerioEmail',
  117. __FUNCTION__,
  118. $vars,
  119. 'DEbug',
  120. $domain
  121. );
  122. return $vars;
  123. }
  124. public function selfDns($domain){
  125. $zoneIDcollection = Capsule::table('dns_manager2_zone')
  126. ->select('id')
  127. ->where('name', '=', $domain)
  128. ->get();
  129. $zoneIDobj = $zoneIDcollection[0];
  130. if(!isset($zoneIDobj->{'id'})) {
  131. return false;
  132. }
  133. return $zoneIDobj->{'id'};
  134. }
  135. public function getLocalRecords($zoneID) {
  136. $dnsZone = localAPI('dnsmanager', array( 'dnsaction' => 'getZone', 'zone_id' => $zoneID));
  137. if($dnsZone['result'] != 'success') {
  138. return 'Error: cloud not fetch zone for ID ' . $zoneID;
  139. }
  140. logModuleCall(
  141. 'kerioEmail',
  142. __FUNCTION__,
  143. $zoneID,
  144. 'DEbug',
  145. $dnsZone
  146. );
  147. $zoneRecords = array();
  148. foreach($dnsZone['data']->records as $record) {
  149. if(in_array($record->type, ['MX', 'TXT'])){
  150. array_push($zoneRecords, $record);
  151. }
  152. }
  153. return $zoneRecords;
  154. }
  155. function KerioEmailsetDNS()
  156. {
  157. return 'success';
  158. $zoneIDcollection = Capsule::table('dns_manager2_zone')
  159. ->select('id')
  160. ->where('name', '=', $this->params['domain'])
  161. ->get();
  162. $zoneIDobj = $zoneIDcollection[0];
  163. $zoneID = $zoneIDobj->{'id'};
  164. if(!isset($zoneID)) {
  165. return 'Error: zone ID not found for domain ' . $this->params['domain'];
  166. }
  167. $dnsZone = localAPI('dnsmanager', array( 'dnsaction' => 'getZone', 'zone_id' => $zoneID));
  168. logModuleCall(
  169. 'kerioEmail',
  170. __FUNCTION__,
  171. $this->params,
  172. 'DEbug',
  173. $dnsZone['result']
  174. );
  175. if($dnsZone['result'] != 'success') {
  176. return 'Error: cloud not fetch zone for ID ' . $zoneID;
  177. }
  178. $zoneRecords = array();
  179. $mxRecord = array(
  180. 'line' => $this->params['domain'].'.|MX|0',
  181. 'name' => '@',
  182. 'type' => 'MX',
  183. 'class' => 'IN',
  184. 'data' => array(
  185. 'preference' => '10',
  186. 'exchange' => $this->params['serverhostname'],
  187. ),
  188. );
  189. array_push($zoneRecords, $mxRecord);
  190. $spfRecord = array(
  191. 'line' => $this->params['domain'].'.|TXT|0',
  192. 'name' => '@',
  193. 'type' => 'TXT',
  194. 'class' => 'IN',
  195. 'data' => $this->spfConfig
  196. );
  197. array_push($zoneRecords, $spfRecord);
  198. $dmarcRecord = array(
  199. 'line' => $this->params['domain'].'.|TXT|0',
  200. 'name' => '@',
  201. 'type' => 'TXT',
  202. 'class' => 'IN',
  203. 'data' => $this->dmarcConfig
  204. );
  205. array_push($zoneRecords, $dmarcRecord);
  206. foreach($dnsZone['data']->records as $record) {
  207. if($record->type == 'MX') continue;
  208. if(!$record->type === 'TXT') {
  209. // skip dmarc
  210. if(preg_match('/^v=DMARC1(.*)$/i', trim($record->rdata->txtdata,'"'))) continue;
  211. // skip spf
  212. if(preg_match('/^v=spf(.*)$/i', trim($record->rdata->txtdata,'"'))) continue;
  213. // skip own dkim
  214. if(($this->dkimName == $record->name) && ($this->domainKey == trim($record->rdata->txtdata,'"'))) continue;
  215. };
  216. array_push($zoneRecords, $record);
  217. }
  218. logModuleCall(
  219. 'kerioEmail',
  220. __FUNCTION__,
  221. $this->params,
  222. 'DEbug',
  223. $zoneRecords
  224. );
  225. /* $result = localAPI('dnsmanager' ,
  226. array(
  227. 'dnsaction' => 'updateZone',
  228. 'zone_id' => $zoneID,
  229. 'records' => $zoneRecords,
  230. )
  231. );
  232. if($result['result'] != 'success') {
  233. return 'Error: cloud not update zone for ID ' . $zoneID;
  234. } */
  235. return 'success';
  236. }
  237. function KerioEmailunsetMX()
  238. {
  239. $zoneIDcollection = Capsule::table('dns_manager2_zone')
  240. ->select('id')
  241. ->where('name', '=', $this->params['domain'])
  242. ->get();
  243. $zoneIDobj = $zoneIDcollection[0];
  244. $zoneID = $zoneIDobj->{'id'};
  245. if(!isset($zoneID)) {
  246. return 'Error: zone ID not found for domain ' . $this->params['domain'];
  247. }
  248. $dnsZone = localAPI('dnsmanager', array( 'dnsaction' => 'getZone', 'zone_id' => $zoneID));
  249. if($dnsZone['result'] != 'success') {
  250. return 'Error: cloud not fetch zone for ID ' . $zoneID;
  251. }
  252. $zoneRecords = array();
  253. foreach($dnsZone['data']->records as $record) {
  254. if($record->type == 'MX') continue;
  255. array_push($zoneRecords, $record);
  256. }
  257. logModuleCall(
  258. 'kerioEmail',
  259. __FUNCTION__,
  260. $this->params,
  261. 'DEbug',
  262. $zoneRecords
  263. );
  264. /* $result = localAPI('dnsmanager' ,
  265. array(
  266. 'dnsaction' => 'updateZone',
  267. 'zone_id' => $zoneID,
  268. 'records' => $zoneRecords,
  269. )
  270. );
  271. if($result['result'] != 'success') {
  272. return 'Error: cloud not update zone for ID ' . $zoneID;
  273. } */
  274. return 'success';
  275. }
  276. }