<?php

function check_machine_with_ip_exists($con, $safe_ipv4){
    $r = mysqli_query($con, "SELECT * FROM machines WHERE ipaddr='$safe_ipv4'");
    $n = mysqli_num_rows($r);
    if($n != 1){
        return FALSE;
    }else{
        return TRUE;
    }
}

function check_cluster_with_id_exists($con, $safe_id){
    $q = "SELECT * FROM clusters WHERE id='$safe_id'";
    $r = mysqli_query($con, $q);
    $n = mysqli_num_rows($r);
    if($n != 1){
        return FALSE;
    }else{
        return TRUE;
    }
}

# IPv4
function validate_ipv4_str($param){
    $reg = "/^([0-9]){1,3}\.([0-9]){1,3}\.([0-9]){1,3}\.([0-9]){1,3}\$/";
    if(!preg_match($reg,$param)){
        return FALSE;
    }
    return TRUE;
}

function validate_ip($param_name){
    if(!isset($_REQUEST[$param_name]) || $_REQUEST[$param_name] == ""){
        return FALSE;
    }
    $param = $_REQUEST[$param_name];
    return validate_ipv4_str($param);
}

function safe_ipv4($param_name){
    if(validate_ip($param_name) === FALSE){
        return FALSE;
    }
    return $_REQUEST[$param_name];
}

# IPv6
function validate_ipv6_str($param){
    $reg = "/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\$/";
# Lamely taken from https://stackoverflow.com/questions/53497/regular-expression-that-matches-valid-ipv6-addresses
#
# It should match:
#
#    IPv6 addresses
#    zero compressed IPv6 addresses (section 2.2 of rfc5952)
#    link-local IPv6 addresses with zone index (section 11 of rfc4007)
#    IPv4-Embedded IPv6 Address (section 2 of rfc6052)
#    IPv4-mapped IPv6 addresses (section 2.1 of rfc2765)
#    IPv4-translated addresses (section 2.1 of rfc2765)
#
# For ease of reading, the following is the above regular expression split at major OR points into separate lines:
#
# IPv6 RegEx
# (
# ([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|          # 1:2:3:4:5:6:7:8
# ([0-9a-fA-F]{1,4}:){1,7}:|                         # 1::                              1:2:3:4:5:6:7::
# ([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|         # 1::8             1:2:3:4:5:6::8  1:2:3:4:5:6::8
# ([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|  # 1::7:8           1:2:3:4:5::7:8  1:2:3:4:5::8
# ([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|  # 1::6:7:8         1:2:3:4::6:7:8  1:2:3:4::8
# ([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|  # 1::5:6:7:8       1:2:3::5:6:7:8  1:2:3::8
# ([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|  # 1::4:5:6:7:8     1:2::4:5:6:7:8  1:2::8
# [0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|       # 1::3:4:5:6:7:8   1::3:4:5:6:7:8  1::8
# :((:[0-9a-fA-F]{1,4}){1,7}|:)|                     # ::2:3:4:5:6:7:8  ::2:3:4:5:6:7:8 ::8       ::
# fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|     # fe80::7:8%eth0   fe80::7:8%1     (link-local IPv6 addresses with zone index)
# ::(ffff(:0{1,4}){0,1}:){0,1}
# ((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}
# (25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|          # ::255.255.255.255   ::ffff:255.255.255.255  ::ffff:0:255.255.255.255  (IPv4-mapped IPv6 addresses and IPv4-translated addresses)
# ([0-9a-fA-F]{1,4}:){1,4}:
# ((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}
# (25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])           # 2001:db8:3:4::192.0.2.33  64:ff9b::192.0.2.33 (IPv4-Embedded IPv6 Address)
# )

    if(!preg_match($reg,$param)){
        return FALSE;
    }
    return TRUE;
}

function validate_ipv6($param_name){
    if(!isset($_REQUEST[$param_name]) || $_REQUEST[$param_name] == ""){
        return FALSE;
    }
    $param = $_REQUEST[$param_name];
    return validate_ipv6_str($param);
}

function safe_ipv6($param_name){
    if(validate_ipv6($param_name) === FALSE){
        return FALSE;
    }
    return $_REQUEST[$param_name];
}

function safe_ip_list($param_name){
    if(!isset($_REQUEST[$param_name]) || $_REQUEST[$param_name] == ""){
        return FALSE;
    }
    if($_REQUEST[$param_name] == 'none'){
        # provides a way to clear the list
        return 'none';
    }
    $safe_value = $_REQUEST[$param_name];
    foreach(explode(";", $safe_value) as $input_ip) {
        if(strpos($input_ip, '/') !== FALSE) {
            $input_ip_ar = explode("/", $input_ip);
            if(count($input_ip_ar) != 2) return FALSE;
            $input_addr = $input_ip_ar[0];
            $input_cidr = $input_ip_ar[1];
            $reg = '/^[0-9]{1,253}$/';
            if(!preg_match($reg,$input_cidr)) return FALSE;

            if(strpos($input_addr, ':') !== FALSE) {
                if($input_cidr < 0 || $input_cidr > 128) return FALSE;
                if(validate_ipv6_str($input_addr) == FALSE){ $safe_value = FALSE; }
            }else{
                if($input_cidr < 0 || $input_cidr > 32) return FALSE;
                if(validate_ipv4_str($input_addr) == FALSE){ $safe_value = FALSE; }
            }
        }else{
            if(strpos($input_ip, ':') !== FALSE) {
                if(validate_ipv6_str($input_ip) == FALSE){ $safe_value = FALSE; }
            } else {
                if(validate_ipv4_str($input_ip) == FALSE){ $safe_value = FALSE; }
            }
        }
    }
    return $safe_value;
}

function validate_uuid($uuid){
    if(!isset($_REQUEST[$uuid]) || $_REQUEST[$uuid] == ""){
       return FALSE;
    }
    $param = $_REQUEST[$uuid];
    $reg = "/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\$/";
    if(!preg_match($reg,$param))       return FALSE;
    else                    return TRUE;
}

function safe_uuid($param_name){
    if(validate_uuid($param_name) === FALSE){
        return FALSE;
    }
    return $_REQUEST[$param_name];
}

function validate_uuid_list($uuid_list){
    if(!isset($_REQUEST[$uuid_list])){
        return FALSE;
    }
    $param = $_REQUEST[$uuid_list];
    $tok = strtok($param, ",");

    $reg = "/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\$/";

    while ($tok !== FALSE) {
        if(!preg_match($reg,$tok))       return FALSE;
        $tok = strtok(",");
    }
    return TRUE;
}

function safe_uuid_list($param_name){
    if(validate_uuid_list($param_name) === FALSE){
        return FALSE;
    }
    return $_REQUEST[$param_name];
}

# Domain name
function validate_domain_name($hostname){
    if(!isset($_REQUEST[$hostname]) || $_REQUEST[$hostname] == ""){
        return FALSE;
    }
    $param = $_REQUEST[$hostname];
    $reg = "/^\b((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b\$/";
    if(!preg_match($reg,$param))       return FALSE;
    else                    return TRUE;
}

function safe_domain_name($param_name){
    if(validate_domain_name($param_name) === FALSE){
        return FALSE;
    }else{
        $dom = $_REQUEST[$param_name];
        $IDN = new idna_convert(array('idn_version' => 2008));
        $punnycode = $IDN->encode_uri($dom);
        return $punnycode;
    }
}

# Cluster name
function validate_cluster_name($cluster){
    if(!isset($_REQUEST[$cluster]) || $_REQUEST[$cluster] == ""){
        return FALSE;
    }
    $param = $_REQUEST[$cluster];
    $reg = "/^([a-z0-9]+)([a-z0-9-]*)([a-z0-9]+)\$/";
    if(!preg_match($reg,$param))	return FALSE;
    else	return TRUE;
}

function safe_cluster_name($param_name){
    if(validate_cluster_name($param_name) === FALSE){
        return FALSE;
    }
    return $_REQUEST[$param_name];
}

# Passwords
function validate_password($password){
    if(!isset($_REQUEST[$password]) || $_REQUEST[$password] == ""){
        return FALSE;
    }
    $param = $_REQUEST[$password];
    $reg = '/^[-a-zA-Z0-9\/_,+ :@.=]+$/';
    if(!preg_match($reg,$param))       return FALSE;
    else                    return TRUE;
}

function safe_password($param_name){
    if(validate_password($param_name) === FALSE){
        return FALSE;
    }
    return $_REQUEST[$param_name];
}

# Machine serial number
function validate_serial($serial){
    if(!isset($_REQUEST[$serial]) || $_REQUEST[$serial] == ""){
        return FALSE;
    }
    $param = $_REQUEST[$serial];
    $reg = "/^[-a-zA-Z0-9.]+\$/";
    if(!preg_match($reg,$param))       return FALSE;
     else                    return TRUE;
}

function safe_serial($param_name){
    if(validate_serial($param_name) === FALSE){
        return FALSE;
    }
    return $_REQUEST[$param_name];
}

# FQDN
function validate_fqdn_str($param){
    # No more than 253 chars total
    $reg = '/^.{1,253}$/';
    if(!preg_match($reg,$param)) return FALSE;
    # Split each strings separated by dots and check then one by one
    $fqdn_array = explode("." , $param);
    foreach($fqdn_array as $subdom){
        # Each elements cannot be >= 63 in length
        # and allow punnycode (ie: xn--)
        $reg = '/^((?!-))(xn--)?[a-z0-9][a-z0-9-]{0,61}[a-z0-9]{0,1}$/';
        if(!preg_match($reg,$subdom)) return FALSE;
    }
    return TRUE;
}

function validate_fqdn($param_name){
    if(!isset($_REQUEST[$param_name]) || $_REQUEST[$param_name] == ""){
        return FALSE;
    }
    $param = $_REQUEST[$param_name];
    return validate_fqdn_str($param);
}

function safe_fqdn($param_name){
    if(validate_fqdn($param_name) === FALSE) return FALSE;
    return $_REQUEST[$param_name];
}

function validate_hostname_with_wildcard($param_name){
    if(!isset($_REQUEST[$param_name]) || $_REQUEST[$param_name] == ""){
        return FALSE;
    }
    $param = $_REQUEST[$param_name];

    $reg = '/^[-a-zA-Z0-9_ :@.%]+$/';
    if(!preg_match($reg,$param)){
        return FALSE;
    }else{
        return TRUE;
    }
}

function safe_hostname_with_wildcard($param_name){
    if(!isset($_REQUEST[$param_name]) || $_REQUEST[$param_name] == ""){
        return FALSE;
    }
    if(!validate_hostname_with_wildcard($param_name)) return FALSE;
    else return $_REQUEST[$param_name];
}

# Is numeric int
function validate_int($param_name){
    if(!isset($_REQUEST[$param_name]) || $_REQUEST[$param_name] == ""){
        return FALSE;
    }
    $param = $_REQUEST[$param_name];
    $reg = '/^[0-9]{1,253}$/';
    if(!preg_match($reg,$param))        return FALSE;
    else        return TRUE;
}

function safe_int($param_name){
    if(validate_int($param_name) === FALSE) return FALSE;
    return $_REQUEST[$param_name];
}

# Is numeric float
function validate_float($param_name){
    if(!isset($_REQUEST[$param_name]) || $_REQUEST[$param_name] == ""){
        return FALSE;
    }
    $param = $_REQUEST[$param_name];
    $reg = '/^[0-9,.]{1,253}$/';
    if(!preg_match($reg,$param))        return FALSE;
    else        return TRUE;
}

function safe_float($param_name){
    if(validate_float($param_name) === FALSE) return FALSE;
    return $_REQUEST[$param_name];
}

# URL
function validate_url($param_name){
    if(!isset($_REQUEST[$param_name]) || $_REQUEST[$param_name] == ""){
        return FALSE;
    }
    $param = $_REQUEST[$param_name];
    # No more than 253 chars total
    $reg = '/^.{1,253}$/';
    if(!preg_match($reg,$param)) return FALSE;
    if(!filter_var($param, FILTER_VALIDATE_URL)) {
        return FALSE;
    }
    return TRUE;
}

function safe_url($param_name){
    if(validate_url($param_name) === FALSE) return FALSE;
    return $_REQUEST[$param_name];
}

function validate_ethname($param_name){
    if(!isset($_REQUEST[$param_name]) || $_REQUEST[$param_name] == ""){
        return FALSE; 
    }
    $param = $_REQUEST[$param_name];

    switch($param){
    case "none":
    case "eth0":
    case "eth1":
    case "eth2":
    case "eth3":
    case "eth4":
    case "eth5":
    case "10m1":
    case "10m2":
    case "10m3":
    case "10m4":
    case "100m1":
    case "100m2":
    case "100m3":
    case "100m4":
    case "1g1":
    case "1g2":
    case "1g3":
    case "1g4":
    case "10g1":
    case "10g2":
    case "10g3":
    case "10g4":
        return TRUE;
    default:
        return validate_blockdev_name($param_name);
    }
}

function safe_ethname($param_name){
    if(validate_ethname($param_name) === FALSE) return FALSE;
    return $_REQUEST[$param_name];
}

function validate_blockdev_name($param_name){
    if(!isset($_REQUEST[$param_name]) || $_REQUEST[$param_name] == ""){
        return FALSE;
    }
    $param = $_REQUEST[$param_name];
    $reg = "/^[-a-zA-Z0-9.]+\$/";
    if(!preg_match($reg,$param))       return FALSE;
     else                    return TRUE;
}

function safe_blockdev_name($param_name){
    if(validate_blockdev_name($param_name) === FALSE) return FALSE;
    return $_REQUEST[$param_name];
}

?>
