inc/dns.inc.php
changeset 138 3e36ebbfe048
parent 136 c795dd75a77e
child 140 e68c3d6094d1
equal deleted inserted replaced
137:79c33038ca14 138:3e36ebbfe048
    17  *
    17  *
    18  *  You should have received a copy of the GNU General Public License
    18  *  You should have received a copy of the GNU General Public License
    19  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
    19  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
    20  */
    20  */
    21 
    21 
    22 /*
    22 function validate_input($zid, $type, &$content, &$name, &$prio, &$ttl)
    23  * Validates an IPv4 IP.
       
    24  * returns true if valid.
       
    25  */
       
    26 function validate_input($zoneid, $type, &$content, &$name, &$prio, &$ttl)
       
    27 {
    23 {
    28 	global $db;
    24 	global $db;
    29 
    25 	$domain = get_domain_name_from_id($zid);
    30 	// Has to validate content first then it can do the rest
       
    31 	// Since if content is invalid already it can aswell be just removed
       
    32 	// Check first if content is IPv4, IPv6 or Hostname
       
    33 	// We accomplish this by just running all tests over it
       
    34 	// We start with IPv6 since its not able to have these ip's in domains.
       
    35 	//
       
    36 	// <TODO>
       
    37 	// The nocheck has to move to the configuration file
       
    38 	// </TODO>
       
    39 	//
       
    40 	$domain = get_domain_name_from_id($zoneid);
       
    41 	$nocheck = array('SOA', 'HINFO', 'NAPTR', 'URL', 'MBOXFW', 'TXT');
    26 	$nocheck = array('SOA', 'HINFO', 'NAPTR', 'URL', 'MBOXFW', 'TXT');
    42 	$hostname = false;
    27 	$hostname = false;
    43 	$ip4 = false;
    28 	$ip4 = false;
    44 	$ip6 = false;
    29 	$ip6 = false;
    45 
    30 
   120 			error(ERR_DNS_NS_CNAME);
   105 			error(ERR_DNS_NS_CNAME);
   121 			return false;
   106 			return false;
   122 		}
   107 		}
   123 	}
   108 	}
   124 
   109 
   125 	if ($type == 'SOA') {
   110 	if ($type == 'SOA' && !is_valid_rr_soa($content)) {
   126 		$status = is_valid_soa($content, $zoneid);
   111 		return false;
   127 		if($status == -1) {
       
   128 			error(ERR_DNS_SOA_UNIQUE);
       
   129 		} elseif($status == -2) {
       
   130 			error(ERR_DNS_SOA_NUMERIC);
       
   131 			return false;
       
   132 		}
       
   133 	}
   112 	}
   134 
   113 
   135 	// HINFO and TXT require no validation.
   114 	// HINFO and TXT require no validation.
   136 
   115 
   137 	if ($type == 'URL') {
   116 	if ($type == 'URL') {
   180 	// Validate the TTL, it has to be numeric.
   159 	// Validate the TTL, it has to be numeric.
   181 	$ttl = (!isset($ttl) || !is_numeric($ttl)) ? $dns_ttl : $ttl;
   160 	$ttl = (!isset($ttl) || !is_numeric($ttl)) ? $dns_ttl : $ttl;
   182 	
   161 	
   183 	return true;
   162 	return true;
   184 }
   163 }
   185 
       
   186 
       
   187 
       
   188 		/****************************************
       
   189 		 *					*
       
   190 		 * RECORD VALIDATING PART.		*
       
   191 		 * CHANGES HERE SHOULD BE CONSIDERED	*
       
   192 		 * THEY REQUIRE KNOWLEDGE ABOUT THE 	*
       
   193 		 * DNS SPECIFICATIONS			*
       
   194 		 *					*
       
   195 		 ***************************************/
       
   196 
       
   197 
   164 
   198 /*
   165 /*
   199  * Validatis a CNAME record by the name it will have and its destination
   166  * Validatis a CNAME record by the name it will have and its destination
   200  *
   167  *
   201  */
   168  */
   409 	}
   376 	}
   410 	return 1;
   377 	return 1;
   411 }
   378 }
   412 
   379 
   413 
   380 
   414 /*
   381 function is_valid_hostname_label($hostname_label) {
   415  * Function to check the validity of SOA records.
   382 
   416  * return values: true if succesful
   383         // See <https://www.poweradmin.org/trac/wiki/Documentation/DNS-hostnames>.
   417  */
   384         if (!preg_match('/^[a-z\d]([a-z\d-]*[a-z\d])*$/i',$hostname_label)) {
   418 function is_valid_soa(&$content, $zoneid)
   385 		return false;
   419 {
   386         } elseif (preg_match('/^[\d]+$/i',$hostname_label)) {
   420 
   387                 return false;
   421 	/*
   388         } elseif ((strlen($hostname_label) < 2) || (strlen($hostname_label) > 63)) {
   422 	 * The stored format is: primary hostmaster serial refresh retry expire default_ttl
   389                 return false;
   423 	 */
   390         }
   424 
   391         return true;
   425 	$return = get_records_by_type_from_domid("SOA", $zoneid);
   392 }
   426 	if($return->numRows() > 1) {
   393 
   427 		return -1;
   394 function is_valid_hostname_fqdn($hostname) {
   428 	}
   395 
   429 
   396         // See <https://www.poweradmin.org/trac/wiki/Documentation/DNS-hostnames>.
   430 	$soacontent = preg_split("/\s+/", $content);
   397 	global $dns_strict_tld_check;
   431 	
   398 	global $valid_tlds;
   432 	if(is_valid_hostname($soacontent[0])) {
   399 
   433 
   400 	$hostname = ereg_replace("\.$","",$hostname);
   434 		$totalsoa = $soacontent[0];
   401 
   435 		// It doesnt matter what field 2 contains, but lets check if its there
   402 	if (strlen($hostname) > 255) {
   436 		// We assume the 2nd field wont have numbers, otherwise its a TTL field
   403 		error(ERR_DNS_HN_TOO_LONG);
   437 
   404 		return false;
   438 		if(count($soacontent) > 1) {
   405 	}
   439 			if(is_numeric($soacontent[1])) {
   406 
   440 				// its a TTL field, or at least not hostmaster or alike
   407         $hostname_labels = explode ('.', $hostname);
   441 				// Set final string to the default hostmaster addy
   408         $label_count = count($hostname_labels);
   442 				global $dns_hostmaster;
   409 
   443 				$totalsoa .= " ". $dns_hostmaster;
   410 	if ($dns_strict_tld_check == "1" && !in_array($hostname_labels[$label_count-1], $valid_tlds)) {
   444 			} else {
   411 		error(ERR_DNS_INV_TLD);
   445 				$totalsoa .= " ".$soacontent[1];
   412 		return false;
   446 			}
   413 	}
   447 			// For loop to iterate over the numbers
   414 
   448 			$imax = count($soacontent);
   415 	if ($hostname_labels[$label_count-1] == "arpa") {
   449 			for($i = 2; ($i < $imax) && ($i < 7); $i++) {
   416 		// FIXME
   450 				if(!is_numeric($soacontent[$i])) {
   417 	} else {
   451 					return -2;
   418 		foreach ($hostname_labels as $hostname_label) {
       
   419 			if (!is_valid_hostname_label($hostname_label)) {
       
   420 				error(ERR_DNS_HOSTNAME);
       
   421 				return false;
       
   422 			}
       
   423 		}
       
   424 	}
       
   425 	return true;
       
   426 }
       
   427 
       
   428 function is_valid_rr_soa(&$content) {
       
   429 
       
   430 	// TODO move to appropiate location
       
   431 //	$return = get_records_by_type_from_domid("SOA", $zid);
       
   432 //	if($return->numRows() > 1) {
       
   433 //		return false;
       
   434 //	}
       
   435 
       
   436 	$fields = preg_split("/\s+/", trim($content));
       
   437         $field_count = count($fields);
       
   438 
       
   439 	if ($field_count == 0 || $field_count > 7) {
       
   440 		return false;
       
   441 	} else {
       
   442 		if (!is_valid_hostname_fqdn($fields[0]) || preg_match('/\.arpa\.?$/',$fields[0])) {
       
   443 			return false;
       
   444 		}
       
   445 		$final_soa = $fields[0];
       
   446 
       
   447 		if (isset($fields[1])) {
       
   448 			$addr_input = $fields[1];
       
   449 		} else {
       
   450 			global $dns_hostmaster;
       
   451 			$addr_input = $dns_hostmaster;
       
   452 		}
       
   453 		if (!preg_match("/@/", $addr_input)) {
       
   454 			$addr_input = preg_split('/(?<!\\\)\./', $addr_input, 2);
       
   455 			$addr_to_check = str_replace("\\", "", $addr_input[0]) . "@" . $addr_input[1];
       
   456 		} else {
       
   457 			$addr_to_check = $addr_input;
       
   458 		}
       
   459 		
       
   460 		if (!is_valid_email($addr_to_check)) {
       
   461 			return false;
       
   462 		} else {
       
   463 			$addr_final = explode('@', $addr_to_check, 2);
       
   464 			$final_soa .= " " . str_replace(".", "\\.", $addr_final[0]) . "." . $addr_final[1];
       
   465 		}
       
   466 
       
   467 		if (isset($fields[2])) {
       
   468 			if (!is_numeric($fields[2])) {
       
   469 				return false;
       
   470 			}
       
   471 			$final_soa .= " " . $fields[2];
       
   472 		} else {
       
   473 			$final_soa .= " 0";
       
   474 		}
       
   475 		
       
   476 		if ($field_count == 7) {
       
   477 			for ($i = 3; ($i < 7); $i++) {
       
   478 				if (!is_numeric($fields[$i])) {
       
   479 					return false;
   452 				} else {
   480 				} else {
   453 					$totalsoa .= " ".$soacontent[$i];
   481 					$final_soa .= " " . $fields[$i];
   454 				}
   482 				}
   455 			}
   483 			}
   456 			// if($i > 7) --> SOA contained too many fields, should we provide error?
   484 		}
   457 		}
   485 	}
   458 	} else {
   486 	$content = $final_soa;
   459 		error(ERR_DNS_SOA_HOSTNAME);
   487 	return true;
   460 	}
       
   461 	$content = $totalsoa;
       
   462 	return 1;
       
   463 }
   488 }
   464 
   489 
   465 
   490 
   466 function is_valid_url($url)
   491 function is_valid_url($url)
   467 {
   492 {