$values) { // UnBreak special cases $section = str_replace("_", " ", $section); $content .= "[".$section."]\n"; //append the values foreach($values as $key=>$value) { // Strip CR/LF from values before they reach the INI // line. Same rationale as fulledit_dapnetapi.php: a // newline inside $value would split into a fresh // INI line and let an attacker inject extra keys. $value = str_replace(array("\r", "\n"), "", (string)$value); if ($value == '') { $content .= $key."=none\n"; } else { $content .= $key."=".$value."\n"; } } $content .= "\n"; } //write it into file if (!$handle = fopen($filepath, 'w')) { return false; } $success = fwrite($handle, $content); fclose($handle); // Atomic install: mode + owner set in one syscall sequence. // /etc/bmapi.key holds the BrandMeister API token — mode 600 // keeps it readable only by www-data (the dashboard user). // Owner left as www-data because banner_warnings.inc / bm_links.php / // bm_manager.php read the file directly via parse_ini_file() // without sudo — switching to root:root here would silently // break those reads. (Tightening to root:root is a follow-up // once the read sites move to a sudo-cat helper.) exec('sudo mount -o remount,rw /'); exec('sudo install -m 600 -o www-data -g www-data ' . escapeshellarg($filepath) . ' /etc/bmapi.key'); exec('sudo mount -o remount,ro /'); return $success; } //parse the ini file using default parse_ini_file() PHP function $parsed_ini = parse_ini_file($filepath, true); if (!isset($parsed_ini['key']['apikey'])) { $parsed_ini['key']['apikey'] = ""; } echo '
'."\n"; echo csrf_field_html()."\n"; foreach($parsed_ini as $section=>$values) { // INI section / key / value all come from /etc/bmapi.key. Same // hardening as edit_mmdvmhost.php (#23) but the value lands // inside a body — htmlspecialchars // covers both attribute and body contexts safely. Browser // decodes the named entities on form submit, so legitimate // values containing `<`, `>`, `&`, `"` round-trip byte-identically. $sectionHtml = htmlspecialchars((string)$section, ENT_QUOTES, 'UTF-8'); // keep the section as hidden text so we can update once the form submitted echo "\n"; echo "\n"; echo "\n"; // print all other values as input fields, so can edit. // note the name='' attribute it has both section and key foreach($values as $key=>$value) { $keyHtml = htmlspecialchars((string)$key, ENT_QUOTES, 'UTF-8'); $valueHtml = htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8'); if (($key == "Options") || ($value)) { echo "\n"; } elseif (($key == "Display") && ($value == '')) { echo "\n"; } else { echo "\n"; } } echo "
$sectionHtml
$keyHtml
$keyHtml
$keyHtml
\n"; echo ''."\n"; echo "
\n"; } echo "
"; ?>