AlkantarClanX12
Current Path : /usr/local/lsws/admin/html.6.3.1/classes/ |
Current File : //usr/local/lsws/admin/html.6.3.1/classes/CValidation.php |
<?php class CValidation { protected $_info; public function __construct() { $this->_info = null; } public function ExtractPost($tbl, &$d, $disp) { $this->_info = $disp->_info; $goFlag = 1 ; $index = array_keys($tbl->_dattrs); foreach ( $index as $i ) { $attr = $tbl->_dattrs[$i]; if ( $attr == null || $attr->bypassSavePost()) continue; $d[$attr->_key] = $attr->extractPost(); $needCheck = true; if ( $attr->_type == 'sel1' || $attr->_type == 'sel2' ) { if ( $disp->_act == 'c' ) { $needCheck = false; } else { $attr->populate_sel1_options($this->_info, $d); } } if ( $needCheck ) { $res = $this->validateAttr($attr, $d[$attr->_key]); $this->setValid($goFlag, $res); } } $res = $this->validatePostTbl($tbl, $d); $this->setValid($goFlag, $res); $this->_info = null; // if 0 , make it always point to curr page return $goFlag; } protected function checkListener(&$listener) { if ( $listener['secure']->GetVal() == '0' ) { if ( isset($listener['certFile']) && !$listener['certFile']->HasVal() ) { $listener['certFile']->SetErr(null); } if ( isset($listener['keyFile']) && !$listener['keyFile']->HasVal() ) { $listener['keyFile']->SetErr(null); } } else { $tids = array('L_SSL_CERT'); $this->validateElement($tids, $listener); } } protected function validateElement($tids, &$data) { $tblDef = DTblDef::GetInstance(); $valid = 1; foreach ( $tids as $tid ) { $tbl = $tblDef->GetTblDef($tid); $d = &DUtil::locateData( $data, $tbl->_dataLoc ); if ( $d == null ) continue; if ( $tbl->_holderIndex != null ) { $keys = array_keys( $d ); foreach( $keys as $key ) { $res = $this->validateTblAttr($tblDef, $tbl, $d[$key]); $this->setValid($valid, $res); } } else { $res = $this->validateTblAttr($tblDef, $tbl, $d); $this->setValid($valid, $res); } } return $valid; } protected function setValid(&$valid, $res) { if ( $valid != -1 ) { if ( $res == -1 ) { $valid = -1; } elseif ( $res == 0 && $valid == 1 ) { $valid = 0; } } if ( $res == 2 ) { $valid = 2; } } protected function validatePostTbl($tbl, &$d) { $isValid = 1; if ( $tbl->_holderIndex != null && isset($d[$tbl->_holderIndex])) { $newref = $d[$tbl->_holderIndex]->GetVal(); $oldref = null; if(isset($this->_info['holderIndex_cur'])) { $oldref = $this->_info['holderIndex_cur']; } //echo "oldref = $oldref newref = $newref \n"; if ( $oldref == null || $newref != $oldref ) { if (isset($this->_info['holderIndex']) && $this->_info['holderIndex'] != null && in_array($newref, $this->_info['holderIndex']) ) { $d[$tbl->_holderIndex]->SetErr('This value has been used! Please choose a unique one.'); $isValid = -1; } } } $checkedTids = array( 'VH_TOP_D', 'VH_BASE', 'VH_UDB', 'ADMIN_USR', 'ADMIN_USR_NEW', 'L_GENERAL', 'L_GENERAL1', 'ADMIN_L_GENERAL', 'ADMIN_L_GENERAL1', // WS 'L_GENERAL_NEW', 'L_GENERAL_DEL', 'LT_GENERAL_NEW', 'LT_GENERAL', // LSLB 'L_SSL_CERT', 'TP', 'TP1' ) ; if ( in_array($tbl->_id, $checkedTids) ) { switch ($tbl->_id) { case 'TP': case 'TP1': $isValid = $this->chkPostTbl_TP($d); break; case 'VH_BASE': case 'VH_TOP_D': $isValid = $this->chkPostTbl_VH_BASE($d); break; case 'VH_UDB': $isValid = $this->chkPostTbl_VH_UDB($d); break; case 'ADMIN_USR': $isValid = $this->chkPostTbl_ADMIN_USR($d); break; case 'ADMIN_USR_NEW': $isValid = $this->chkPostTbl_ADMIN_USR_NEW($d); break; case 'L_GENERAL_NEW': // for lb case 'L_GENERAL_DEL': case 'L_GENERAL': case 'LT_GENERAL_NEW': case 'LT_GENERAL': case 'L_GENERAL1': // for ws case 'ADMIN_L_GENERAL': case 'ADMIN_L_GENERAL1': $isValid = $this->chkPostTbl_L_GENERAL($d); break; case 'L_SSL_CERT': $isValid = $this->chkPostTbl_L_SSL_CERT($d); break; } } return $isValid; } protected function chkPostTbl_TP(&$d) { $isValid = 1; $confCenter = ConfCenter::singleton(); $oldName = trim($confCenter->GetDispInfo()->_name); $newName = trim($d['name']->GetVal()); if($oldName != $newName && array_key_exists($newName, $confCenter->_serv->_data['tpTop'])) { $d['name']->SetErr("Template: \"$newName\" already exists. Please use a different name."); $isValid = -1; } return $isValid; } protected function chkPostTbl_VH_BASE(&$d) { $isValid = 1; $confCenter = ConfCenter::singleton(); $oldName = trim($confCenter->GetDispInfo()->_name); $newName = trim($d['name']->GetVal()); if($oldName != $newName && array_key_exists($newName, $confCenter->_serv->_data['vhTop'])) { $d['name']->SetErr("Virtual Hostname: \"$newName\" already exists. Please use a different name."); $isValid = -1; } return $isValid; } protected function chkPostTbl_VH_UDB(&$d) { $isValid = 1; if ( $d['pass']->GetVal() != $d['pass1']->GetVal() ) { $d['pass']->SetErr('Passwords do not match!'); $isValid = -1; } if ( !$d['pass']->HasVal() ) { //new user $d['pass']->SetErr('Missing password!'); $isValid = -1; } if ( $isValid == -1 ) { return -1; } if ( strlen($d['pass']->GetVal()) > 0 ) { $newpass = $this->encryptPass($d['pass']->GetVal()); $d['passwd'] = new CVal($newpass); } return 1; } protected function encryptPass($val) { $pass = password_hash($val, PASSWORD_BCRYPT); return $pass; } protected function chk_admname($name) { if (!$name->HasErr()) { $val = $name->GetVal(); if (strlen($val) > 25) { $name->SetErr('name cannot be longer than 25 characters'); } else { $v1 = escapeshellcmd($val); if (($v1 !== $val) || preg_match('/[:\/]/', $val)) { $name->SetErr('invalid characters in name'); } } } return $name->HasErr(); } protected function chkPostTbl_ADMIN_USR(&$d) { $isValid = 1; $this->chk_admname($d['name']); if ($d['name']->HasErr()) { $isValid = -1; } elseif ( !$d['oldpass']->HasVal() ) { $d['oldpass']->SetErr('Missing Old password!'); $isValid = -1; } else { $file = $_SERVER['LS_SERVER_ROOT'] . 'admin/conf/htpasswd'; $udb = ConfigFileEx::loadUserDB($file); $olduser = $this->_info['holderIndex_cur']; $passwd = $udb[$olduser]['passwd']->GetVal(); $oldpass = $d['oldpass']->GetVal(); $encypt = crypt($oldpass, $passwd); if ( $encypt != $passwd ) { $d['oldpass']->SetErr('Invalid old password!'); $isValid = -1; } } if ( !$d['pass']->HasVal() ) { $d['pass']->SetErr('Missing new password!'); $isValid = -1; } elseif ( $d['pass']->GetVal() != $d['pass1']->GetVal() ) { $d['pass']->SetErr('New passwords do not match!'); $isValid = -1; } if ( $isValid == -1 ) { return -1; } $newpass = $this->encryptPass($d['pass']->GetVal()); $d['passwd'] = new CVal($newpass); return 1; } protected function chkPostTbl_ADMIN_USR_NEW(&$d) { $isValid = 1; $this->chk_admname($d['name']); if ($d['name']->HasErr()) { $isValid = -1; } if ( !$d['pass']->HasVal() ) { $d['pass']->SetErr('Missing new password!'); $isValid = -1; } elseif ( $d['pass']->GetVal() != $d['pass1']->GetVal() ) { $d['pass']->SetErr('New passwords do not match!'); $isValid = -1; } if ( $isValid == -1 ) { return -1; } $newpass = $this->encryptPass($d['pass']->GetVal()); $d['passwd'] = new CVal($newpass); return 1; } protected function chkPostTbl_L_GENERAL(&$d) { $isValid = 1; $ip = $d['ip']->GetVal(); if ( $ip == 'ANY' ) { $ip = '*'; } $port = $d['port']->GetVal(); $d['address'] = new CVal("$ip:$port"); $confCenter = ConfCenter::singleton(); $oldName = trim($confCenter->GetDispInfo()->_name); $newName = trim($d['name']->GetVal()); if($oldName != $newName && array_key_exists($newName, $confCenter->_serv->_data['listeners'])) { $d['name']->SetErr("Listener \"$newName\" already exists. Please use a different name."); $isValid = -1; } return $isValid; } protected function isCurrentListenerSecure() { $confCenter = ConfCenter::singleton(); $listenerName = trim($confCenter->GetDispInfo()->_name); $l = $confCenter->_serv->_data['listeners'][$listenerName]; return ($l['secure']->GetVal() == 1); } protected function chkPostTbl_L_SSL_CERT(&$d) { $isValid = 1; if ($this->isCurrentListenerSecure()) { $err = 'Value must be set for secured listener'; if (!$d['keyFile']->HasVal()) { $d['keyFile']->SetErr($err); $isValid = -1; } if (!$d['certFile']->HasVal()) { $d['certFile']->SetErr($err); $isValid = -1; } } return $isValid; } protected function validateTblAttr($tblDef, $tbl, &$data) { $valid = 1; if ( $tbl->_subTbls ) { $tid = DUtil::getSubTid($tbl->_subTbls, $data); if ( $tid == null ) { return; } $tbl1 = $tblDef->GetTblDef($tid); } else { $tbl1 = $tbl; } $index = array_keys($tbl1->_dattrs); foreach ( $index as $i ) { $attr = $tbl1->_dattrs[$i]; if ( $attr->_type == 'sel1' || $attr->_type == 'sel2' ) { $attr->populate_sel1_options($this->_info, $data); } $res = $this->validateAttr($attr, $data[$attr->_key]); $this->setValid($valid, $res); } return $valid; } protected function validateAttr($attr, &$cvals) { $valid = 1; if ( is_array($cvals) ) { for ( $i = 0 ; $i < count($cvals) ; ++$i ) { $res = $this->isValidAttr($attr, $cvals[$i]); $this->setValid($valid, $res); } } else { $valid = $this->isValidAttr($attr, $cvals); } return $valid; } protected function isValidAttr($attr, $cval) { if ($cval == null || $cval->HasErr()) return -1; if ( !$cval->HasVal()) { if ( $attr->_allowNull ) { return 1; } $cval->SetErr('value must be set'); return -1; } if ( $attr->_type == 'cust' ) { return 1; } $chktype = array('uint', 'name', 'vhname', 'dbname', 'sel','sel1','sel2', 'bool','file','filep','file0','file1', 'filetp', 'path', 'note', 'uri','expuri','url', 'httpurl', 'email', 'dir', 'addr', 'ipport', 'wsaddr', 'parse'); if ( !in_array($attr->_type, $chktype) ) { // not checked type ('domain', 'subnet' return 1; } $type3 = substr($attr->_type, 0, 3); if ( $type3 == 'sel' ) { // for sel, sel1, sel2 $funcname = 'chkAttr_sel'; } elseif ( $type3 == 'fil' || $type3 == 'pat' ) { $funcname = 'chkAttr_file'; } else { $funcname = 'chkAttr_' . $attr->_type; } if ( $attr->_multiInd == 1 ) { $valid = 1; $vals = DUtil::splitMultiple($cval->GetVal()); $err = []; $funcname .= '_val'; foreach( $vals as $i=>$v ) { $res = $this->$funcname($attr, $v, $err[$i]); $this->setValid($valid, $res); } $cval->SetErr(trim(implode(' ', $err))); return $valid; }else { return $this->$funcname($attr, $cval); } } protected function chkAttr_sel($attr, $cval) { $err = ''; $res = $this->chkAttr_sel_val($attr, $cval->GetVal(), $err); $cval->SetErr($err); return $res; } protected function chkAttr_sel_val($attr, $val, &$err) { if ( isset( $attr->_maxVal ) && !array_key_exists($val, $attr->_maxVal) ) { $err = "invalid value: $val"; return -1; } return 1; } protected function chkAttr_name($attr, $cval) { $cval->SetVal( preg_replace("/\s+/", ' ', $cval->GetVal())); $res = $this->chkAttr_name_val($attr, $cval->GetVal(), $err); $cval->SetErr($err); return $res; } protected function chkAttr_name_val($attr, $val, &$err) { if ( preg_match( "/[{}<>&%]/", $val) ) { $err = 'invalid characters in name'; return -1; } if ( strlen($val) > 100 ) { $err = 'name can not be longer than 100 characters'; return -1; } return 1; } protected function chkAttr_dbname($attr, $cval) { $cval->SetVal(preg_replace("/\s+/", ' ', $cval->GetVal())); $val = $cval->GetVal(); if ( preg_match( "/[,;<>&%=\(\)\"']/", $val ) ) { $cval->SetErr('Invalid characters found in name'); return -1; } if ( strpos($val, ' ') !== false ) { $cval->SetErr('No space allowed in the name'); return -1; } if ( strlen($val) > 100 ) { $cval->SetErr('name can not be longer than 100 characters'); return -1; } return 1; } protected function chkAttr_note($attr, $cval) { $m = []; if (preg_match("/[{}<]/", $cval->GetVal(), $m)) { // avoid <script, also {} for conf format $cval->SetErr("character $m[0] not allowed"); return -1; } return 1; } protected function chkAttr_vhname($attr, $cval) { $res = $this->chkAttr_dbname($attr, $cval); if ($res == 1) { $this->_info['VH_NAME'] = $cval->GetVal(); } return $res; } protected function allow_create($attr, $absname) { if (strpos($attr->_maxVal, 'c') === false) { return false; } if ($attr->_minVal >= 2 && ( strpos($absname, $_SERVER['LS_SERVER_ROOT']) === 0 )) { return true; } if (isset($this->_info['VH_ROOT'])) { $VH_ROOT = $this->_info['VH_ROOT']; } else { $VH_ROOT = null; } if (isset($this->_info['DOC_ROOT'])) { $DOC_ROOT = $this->_info['DOC_ROOT']; } if ($attr->_minVal >= 3 && ( strpos($absname, $VH_ROOT) === 0 )) { return true; } if ($attr->_minVal == 4 && ( strpos($absname, $DOC_ROOT) === 0 )) { return true; } return false; } protected function clean_absolute_path($abspath) { $absname = PathTool::clean($abspath); if ( isset( $_SERVER['LS_CHROOT'] ) ) { $root = $_SERVER['LS_CHROOT']; $len = strlen($root); if ( strncmp( $absname, $root, $len ) == 0 ) { $absname = substr($absname, $len); } } return $absname; } protected function test_file(&$absname, &$err, $attr) { $absname = $this->clean_absolute_path($absname); if ($attr->_type == 'file0') { if (!file_exists($absname)) { return 1; //allow non-exist } } if ($attr->_type == 'path' || $attr->_type == 'filep' || $attr->_type == 'dir') { $type = 'path'; } else { $type = 'file'; } if (($type == 'path' && !is_dir($absname)) || ($type == 'file' && !is_file($absname))) { $err = $type . ' ' . htmlspecialchars($absname) . ' does not exist.'; if ($this->allow_create($attr, $absname)) { $err .= ' <a href="javascript:createFile(\'' . $attr->_htmlName . '\')">CLICK TO CREATE</a>'; } else { $err .= ' Please create manually.'; } return -1; } if ((strpos($attr->_maxVal, 'r') !== false) && !is_readable($absname)) { $err = $type . ' ' . htmlspecialchars($absname) . ' is not readable'; return -1; } if ((strpos($attr->_maxVal, 'w') !== false) && !is_writable($absname)) { $err = $type . ' ' . htmlspecialchars($absname) . ' is not writable'; return -1; } if ((strpos($attr->_maxVal, 'x') !== false) && !is_executable($absname)) { $err = $type . ' ' . htmlspecialchars($absname) . ' is not executable'; return -1; } return 1; } protected function chkAttr_file($attr, $cval) { $val = $cval->GetVal(); $err = ''; $res = $this->chkAttr_file_val($attr, $val, $err); $cval->SetVal($val); $cval->SetErr($err); return $res; } protected function chkAttr_dir($attr, $cval) { $val = $cval->GetVal(); $err = ''; if ( substr($val,-1) == '*' ) { $res = $this->chkAttr_file_val($attr, substr($val,0,-1), $err); } else { $res = $this->chkAttr_file_val($attr, $val, $err); } $cval->SetVal($val); $cval->SetErr($err); return $res; } protected function isNotAllowedPath($path) { $blocked = '/admin/html/'; if (strpos($path, $blocked) !== false) { return true; } return false; } protected function isNotAllowedExtension($path) { $ext = substr($path, -4); $notallowed = ['.php', '.cgi', '.pl', '.shtml']; foreach ($notallowed as $test) { if (strcasecmp($ext, $test) == 0) { return true; } } return false; } protected function check_cmd_invalid_str($cmd) { // check if it's allowed command, do not allow ' " -c -i /dev/tcp bash sh csh tcsh zsh ksh $cmd = str_replace('.', 'a', $cmd); // replace . with char before pattern check $pattern = '#("|\'|;|-c|-i|/dev/tcp|curl|wget|fetch|\Wbash\W|\Wsh\W|\Wcsh\W|\Wtcsh\W|\Wzsh\W|\Wksh\W)#'; $m = []; if (preg_match($pattern, $cmd, $m)) { return $m[0]; } $cmd = str_replace('\\', '', $cmd); // remove all escape & try again if (preg_match($pattern, $cmd, $m)) { return $m[0]; } return null; } public function chkAttr_file_val($attr, $val, &$err) { // apply to all if ($this->isNotAllowedPath($val)) { $err = 'Directory not allowed'; return -1; } if ( $attr->_type == 'file0' && $this->isNotAllowedExtension($val)) { $err = 'File extension not allowed'; return -1; } clearstatcache(); $err = null; if ( $attr->_type == 'filep' ) { $path = substr($val, 0, strrpos($val,'/')); } else { $path = $val; if ($attr->_type == 'file1') { // file1 is command $invalid_str = $this->check_cmd_invalid_str($path); if ($invalid_str) { $err = 'Cannot contain string ' . htmlspecialchars($invalid_str, ENT_QUOTES); return -1; } $pos = strpos($val, ' '); if ($pos > 0) { $path = substr($val, 0, $pos); // check first part is valid path } } } $res = $this->chk_file1($attr, $path, $err); if ($attr->_type == 'filetp') { $pathtp = $_SERVER['LS_SERVER_ROOT'] . 'conf/templates/'; if (strstr($path, $pathtp) === false) { $err = ' Template file must locate within $SERVER_ROOT/conf/templates/'; $res = -1; } else if (substr($path, -4) != '.xml') { $err = ' Template file name needs to be ".xml"'; $res = -1; } } if ($res == -1 && $_POST['file_create'] == $attr->_htmlName && $this->allow_create($attr, $path)) { if (PathTool::createFile($path, $err, $attr->_htmlName)) { $err = "$path has been created successfully."; } $res = 0; // make it always point to curr page } if ( $attr->_key == 'vhRoot' ) { if ( substr($path,-1) != '/' ) { $path .= '/'; } if ($res == -1) { // do not check path for vhroot, it may be different owner $err = ''; $res = 1; } $this->_info['VH_ROOT'] = $path; } elseif ($attr->_key == 'docRoot') { if ($res == -1) { // do not check path for vhroot, it may be different owner $err = ''; $res = 1; } } return $res; } protected function chk_file1($attr, &$path, &$err) { if ($this->get_abs_path($attr->_minVal, $path, $err) == 1) { return $this->test_file($path, $err, $attr); } } protected function get_cleaned_abs_path($attr_minVal, &$path, &$err) { if ($this->get_abs_path($attr_minVal, $path, $err) == 1) { $absname = $this->clean_absolute_path($path); return $absname; } return null; } protected function get_abs_path($attr_minVal, &$path, &$err) { if(!strlen($path)) { $err = "Invalid Path."; return -1; } $s = substr($path, 0, 1); if ( strpos($path, '$VH_NAME') !== false ) { $path = str_replace('$VH_NAME', $this->_info['VH_NAME'], $path); } if ( $s == '/' ) { return 1; } if ( $attr_minVal == 1 ) { $err = 'only accept absolute path'; return -1; } elseif ( $attr_minVal == 2 ) { if (strncasecmp('$SERVER_ROOT', $path, 12) == 0) { $path = $_SERVER['LS_SERVER_ROOT'] . substr($path, 13); } elseif ($s == '$') { $err = 'only accept absolute path or path relative to $SERVER_ROOT: ' . $path; return -1; } else { $path = $_SERVER['LS_SERVER_ROOT'] . $path; // treat as relative to SERVER_ROOT } } elseif ( $attr_minVal == 3 ) { if ( strncasecmp('$SERVER_ROOT', $path, 12) == 0 ) { $path = $_SERVER['LS_SERVER_ROOT'] . substr($path, 13); } elseif ( strncasecmp('$VH_ROOT', $path, 8) == 0 ) { if (isset($this->_info['VH_ROOT'])) { $path = $this->_info['VH_ROOT'] . substr($path, 9); } } elseif ($s == '$') { $err = 'only accept absolute path or path relative to $SERVER_ROOT or $VH_ROOT'; return -1; } else { $path = $_SERVER['LS_SERVER_ROOT'] . $path; // treat as relative to SERVER_ROOT } } elseif ( $attr_minVal == 4 ) { if ( strncasecmp('$SERVER_ROOT', $path, 12) == 0 ) { $path = $_SERVER['LS_SERVER_ROOT'] . substr($path, 13); } elseif ( strncasecmp('$VH_ROOT', $path, 8) == 0 ) { $path = $this->_info['VH_ROOT'] . substr($path, 9); } elseif ( strncasecmp('$DOC_ROOT', $path, 9) == 0 ) { $path = $this->_info['DOC_ROOT'] . substr($path, 10); } else { $path = $this->_info['DOC_ROOT'] . $path; } } return 1; } protected function chkAttr_uri($attr, $cval) { $val = $cval->GetVal(); if ( $val[0] != '/' ) { $cval->SetErr('URI must start with "/"'); return -1; } return 1; } protected function chkAttr_expuri($attr, $cval) { $val = $cval->GetVal(); if ( substr($val, 0, 1) == '/' || strncmp( $val, 'exp:', 4 ) == 0 ) { return 1; } $cval->SetErr('URI must start with "/" or "exp:"'); return -1; } protected function chkAttr_url($attr, $cval) { $val = $cval->GetVal(); if (( substr($val, 0, 1) != '/' ) && ( strncmp($val, 'http://', 7) != 0 ) && ( strncmp($val, 'https://', 8) != 0 )) { $cval->SetErr('URL must start with "/" or "http(s)://"'); return -1; } return 1; } protected function chkAttr_httpurl($attr, $cval) { $val = $cval->GetVal(); if (strncmp($val, 'http://', 7) != 0) { $cval->SetErr('Http URL must start with "http://"'); return -1; } return 1; } protected function chkAttr_email($attr, $cval) { $err = ''; $res = $this->chkAttr_email_val($attr, $cval->GetVal(), $err); $cval->SetErr($err); return $res; } protected function chkAttr_email_val($attr, $val, &$err) { if ( preg_match("/^[[:alnum:]._-]+@.+/", $val ) ) { return 1; } $err = 'invalid email format: ' . $val; return -1; } protected function isUdsAddr($v) { $m = []; // check UDS:// unix: if (preg_match('/^(UDS:\/\/|unix:)(.+)$/i', $v, $m)) { $v = $m[2]; $supportedvar = ['$SERVER_ROOT', '$VH_NAME', '$VH_ROOT', '$DOC_ROOT']; $v = str_replace($supportedvar, 'VAR', $v); if (preg_match("/^[a-z0-9\-_\/\.]+$/i", $v)) { return 1; } } return 0; } protected function chkAttr_addr($attr, $cval) { $v = $cval->GetVal(); if (preg_match("/^([[:alnum:]._-]+|\[[[:xdigit:]:]+\]):(\d)+$/", $v)) { return 1; } if ($this->isUdsAddr($v)) { return 1; } $cval->SetErr('invalid address: correct syntax is "IPV4|IPV6_address:port" or UDS://path or unix:path'); return -1; } protected function chkAttr_ipport($attr, $cval) { if ( preg_match("/^([[:alnum:]._-]+|\[[[:xdigit:]:]+\]|\*):(\d)+$/", $cval->GetVal()) ) { return 1; } $cval->SetErr('invalid address: correct syntax is "IPV4|IPV6_address:port" or "*:port" for any IP.'); return -1; } protected function chkAttr_wsaddr($attr, $cval) { $v = $cval->GetVal(); if ( preg_match("/^((http|https):\/\/)?([[:alnum:]._-]+|\[[[:xdigit:]:]+\])(:\d+)?$/", $v) ) { return 1; } if ($this->isUdsAddr($v)) { return 1; } $cval->SetErr('invalid address: correct syntax is "[http|https://]IPV4|IPV6_address[:port]" or Unix Domain Socket address "UDS://path or unix:path".'); return -1; } protected function chkAttr_bool($attr, $cval) { $val = $cval->GetVal(); if ( $val === '1' || $val === '0' ) { return 1; } $cval->SetErr('invalid value'); return -1; } protected function chkAttr_parse($attr, $cval) { $err = ''; $res = $this->chkAttr_parse_val($attr, $cval->GetVal(), $err); $cval->SetErr($err); return $res; } protected function chkAttr_parse_val($attr, $val, &$err) { if (preg_match($attr->_minVal, $val)) { return 1; } if ($attr->_maxVal) { $err = "invalid format - $val, please check syntax"; } else { $err = "invalid value - $val"; } return -1; } protected function getKNum($strNum) { $tag = substr($strNum, -1); switch( $tag ) { case 'K': case 'k': $multi = 1024; break; case 'M': case 'm': $multi = 1048576; break; case 'G': case 'g': $multi = 1073741824; break; default: return intval($strNum); } return (intval(substr($strNum, 0, -1)) * $multi); } protected function chkAttr_uint($attr, $cval) { $val = $cval->GetVal(); if ( preg_match("/^(-?\d+)([KkMmGg]?)$/", $val) ) { $val1 = $this->getKNum($val); if (isset($attr->_minVal)) { $min = $this->getKNum($attr->_minVal); if ($val1 < $min) { $cval->SetErr('number is less than the minumum required'); return -1; } } if (isset($attr->_maxVal)) { $max = $this->getKNum($attr->_maxVal); if ( $val1 > $max ) { $cval->SetErr('number exceeds maximum allowed'); return -1; } } return 1; } $cval->SetErr('invalid number format'); return -1; } protected function chkDups(&$data, &$checkList, $key) { if ( in_array( $data[$key]->GetVal(), $checkList ) ) { $data[$key]->SetErr( "This $key \"" . $data[$key]->GetVal() . '\" already exists. Please enter a different one.'); return false; } return true; } protected function chkExtApp(&$data, &$attr) { $isValid = true; if ( $data['autoStart']->GetVal() ) { if ( !$data['path']->HasVal() ) { $data['path']->SetErr('must provide path when autoStart is enabled'); $isValid = false; } if ( !$data['backlog']->HasVal() ) { $data['backlog']->SetErr('must enter backlog value when autoStart is enabled'); $isValid = false; } if ( !$data['instances']->HasVal() ) { $data['instances']->SetErr('must give number of instances when autoStart is enabled'); $isValid = false; } } if ( isset($attr['names']) && (!$this->chkDups($to, $attr['names'], 'name')) ) { $isValid = false; } return $isValid; } protected function chkScriptHandler(&$to, &$attr) { $vals = DUtil::splitMultiple( $to['suffix']->GetVal() ); $isValid = true; foreach( $vals as $suffix ) { if ( in_array( $suffix, $attr['names'] ) ) { $t[] = $suffix; $isValid = false; } } if ( !$isValid ) { $to['suffix']->SetErr(' Suffix ' . implode(', ', $t) . ' already exists. Please use a different suffix.'); } return $isValid; } }