diff --git a/emhttp/login.php b/emhttp/login.php index 9c6bd96f9..9752dc3f7 100644 --- a/emhttp/login.php +++ b/emhttp/login.php @@ -1,6 +1,7 @@ SHA256) { - logger("checking: $name - SHA256"); + my_logger('plugin-manager',"checking: $name - SHA256"); if (hash_file('sha256', $name) != $file->SHA256) { unlink($name); } } elseif ($file->MD5) { - logger("checking: $name - MD5"); + my_logger('plugin-manager',"checking: $name - MD5"); if (md5_file($name) != $file->MD5) { unlink($name); } @@ -396,12 +393,12 @@ function plugin($method, $plugin_file, &$error) { // If file already exists, do not overwrite // if (file_exists($name)) { - logger("skipping: $name already exists"); + my_logger('plugin-manager',"skipping: $name already exists"); } elseif ($file->LOCAL) { // Create the file // // for local file, just copy it - logger("creating: $name - copying LOCAL file $file->LOCAL"); + my_logger('plugin-manager',"creating: $name - copying LOCAL file $file->LOCAL"); if (!copy($file->LOCAL, $name)) { $error = "unable to copy LOCAL file: $name"; @unlink($name); @@ -409,10 +406,10 @@ function plugin($method, $plugin_file, &$error) { } } elseif ($file->INLINE) { // for inline file, create with inline contents - logger("creating: $name - from INLINE content"); + my_logger('plugin-manager',"creating: $name - from INLINE content"); $contents = trim($file->INLINE).PHP_EOL; if ($file->attributes()->Type == 'base64') { - logger("decoding: $name as base64"); + my_logger('plugin-manager',"decoding: $name as base64"); $contents = base64_decode($contents); if ($contents === false) { $error = "unable to decode inline base64: $name"; @@ -426,20 +423,20 @@ function plugin($method, $plugin_file, &$error) { } } elseif ($file->URL) { // for download file, download and maybe verify the file MD5 - logger("creating: $name - downloading from URL $file->URL"); + my_logger('plugin-manager',"creating: $name - downloading from URL $file->URL"); if ( (download($file->URL, $name, $error) === false) && (download(filter_url($file->URL), $name, $error) === false) ) { @unlink($name); return false; } if ($file->SHA256) { - logger("checking: $name - SHA256"); + my_logger('plugin-manager',"checking: $name - SHA256"); if (hash_file('sha256', $name) != $file->SHA256) { $error = "bad file SHA256: $name"; unlink($name); return false; } } elseif ($file->MD5) { - logger("checking: $name - MD5"); + my_logger('plugin-manager',"checking: $name - MD5"); if (md5_file($name) != $file->MD5) { $error = "bad file MD5: $name"; unlink($name); @@ -452,7 +449,7 @@ function plugin($method, $plugin_file, &$error) { if ($file->attributes()->Mode) { // if file has 'Mode' attribute, apply it $mode = $file->attributes()->Mode; - logger("setting: $name - mode to $mode"); + my_logger('plugin-manager',"setting: $name - mode to $mode"); if (!chmod($name, octdec($mode))) { $error = "chmod failure: $name"; return false; @@ -464,13 +461,13 @@ function plugin($method, $plugin_file, &$error) { if ($file->attributes()->Run) { $command = $file->attributes()->Run; if ($name) { - logger("running: $command $name"); + my_logger('plugin-manager',"running: $command $name"); $retval = run("$command $name"); } elseif ($file->LOCAL) { - logger("running: $command $file->LOCAL"); + my_logger('plugin-manager',"running: $command $file->LOCAL"); $retval = run("$command $file->LOCAL"); } elseif ($file->INLINE) { - logger("running: 'anonymous'"); + my_logger('plugin-manager',"running: 'anonymous'"); $name = '/tmp/inline.sh'; file_put_contents($name, $file->INLINE); $retval = run("$command $name"); @@ -718,10 +715,10 @@ if ($method == 'install') { if ($target != $plugin_file) copy($plugin_file, $target); symlink($target, $symlink); write("plugin: $plugin installed\n"); - logger("$plugin installed"); + my_logger('plugin-manager',"$plugin installed"); } else { write("script: $plugin executed\n"); - logger("script: $plugin executed"); + my_logger('plugin-manager',"script: $plugin executed"); } // run hook scripts for post processing post_hooks(); @@ -835,7 +832,7 @@ if ($method == 'update') { copy($plugin_file, $target); symlink($target, $symlink); write("plugin: $plugin updated\n"); - logger("$plugin updated"); + my_logger('plugin-manager',"$plugin updated"); // run hook scripts for post processing post_hooks(); done(0); @@ -867,7 +864,7 @@ if ($method == 'remove') { // remove the plugin file move($installed_plugin_file, "$boot-removed"); write("plugin: $plugin removed\n"); - logger("$plugin removed"); + my_logger('plugin-manager',"$plugin removed"); exec("/usr/local/sbin/update_cron"); // run hook scripts for post processing post_hooks(); diff --git a/emhttp/plugins/dynamix/include/.login.php b/emhttp/plugins/dynamix/include/.login.php index 58e03f789..aac485100 100644 --- a/emhttp/plugins/dynamix/include/.login.php +++ b/emhttp/plugins/dynamix/include/.login.php @@ -119,12 +119,12 @@ function verifyTwoFactorToken(string $username, string $token): bool { // This should accept 200 or 204 status codes if ($httpCode !== 200 && $httpCode !== 204) { // Log error to syslog - exec("logger -t webGUI -- \"2FA code for {$username} is invalid, blocking access!\""); + my_logger('webGUI', "2FA code for {$username} is invalid, blocking access!"); return false; } // Log success to syslog - exec("logger -t webGUI -- \"2FA code for {$username} is valid, allowing login!\""); + my_logger('webGUI', "2FA code for {$username} is valid, allowing login!"); // Success return true; @@ -199,7 +199,7 @@ if (!empty($username) && !empty($password)) { // Check if we're limited if ($failCount >= $maxFails) { - if ($failCount == $maxFails) exec("logger -t webGUI -- \"Ignoring login attempts for {$username} from {$remote_addr}\""); + if ($failCount == $maxFails) my_logger('webGUI', "Ignoring login attempts for {$username} from {$remote_addr}"); throw new Exception(_('Too many invalid login attempts')); } @@ -216,7 +216,7 @@ if (!empty($username) && !empty($password)) { $_SESSION['unraid_user'] = $username; session_regenerate_id(true); session_write_close(); - exec("logger -t webGUI -- \"Successful login user {$username} from {$remote_addr}\""); + my_logger('webGUI', "Successful login user {$username} from {$remote_addr}"); // Redirect the user to the start page header("Location: /".$start_page); @@ -226,7 +226,7 @@ if (!empty($username) && !empty($password)) { $error = $exception->getMessage(); // Log error to syslog - exec("logger -t webGUI -- \"Unsuccessful login user {$username} from {$remote_addr}\""); + my_logger('webGUI', "Unsuccessful login user {$username} from {$remote_addr}"); appendToFile($failFile, $time."\n"); } } diff --git a/emhttp/plugins/dynamix/include/.set-password.php b/emhttp/plugins/dynamix/include/.set-password.php index 3e3256f46..f19b97b91 100644 --- a/emhttp/plugins/dynamix/include/.set-password.php +++ b/emhttp/plugins/dynamix/include/.set-password.php @@ -36,7 +36,7 @@ if (!empty($_POST['password']) && !empty($_POST['confirmPassword'])) { } // Error when attempting to set password - exec("logger -t webGUI -- \"{$VALIDATION_MESSAGES['saveError']} [REMOTE_ADDR]: {$REMOTE_ADDR}\""); + my_logger('webGUI', "{$VALIDATION_MESSAGES['saveError']} [REMOTE_ADDR]: {$REMOTE_ADDR}"); return $POST_ERROR = $VALIDATION_MESSAGES['saveError']; } diff --git a/emhttp/plugins/dynamix/include/PageBuilder.php b/emhttp/plugins/dynamix/include/PageBuilder.php index 931d05943..e2c88ff4d 100644 --- a/emhttp/plugins/dynamix/include/PageBuilder.php +++ b/emhttp/plugins/dynamix/include/PageBuilder.php @@ -12,6 +12,7 @@ ?> 'D j M Y h:i A','%A' => 'l','%Y' => 'Y','%B' => 'F','%e' => 'j','%d' => 'd','%m' => 'm','%I' => 'h','%H' => 'H','%M' => 'i','%S' => 's','%p' => 'a','%R' => 'H:i', '%F' => 'Y-m-d', '%T' => 'H:i:s']; return date(strtr($fmt,$legacy), $time); } +// ensure params passed to logger are properly escaped +function my_logger($tag, $message) { + exec('logger -t '.escapeshellarg($tag).' -- '.escapeshellarg($message)); +} ?> diff --git a/emhttp/plugins/dynamix/include/local_prepend.php b/emhttp/plugins/dynamix/include/local_prepend.php index 0f5458f7a..c683c1b87 100644 --- a/emhttp/plugins/dynamix/include/local_prepend.php +++ b/emhttp/plugins/dynamix/include/local_prepend.php @@ -15,7 +15,7 @@ // auto_prepend_file="/usr/local/emhttp/webGui/include/local_prepend.php" function csrf_terminate($reason) { - exec("logger -t webGUI -- \"error: {$_SERVER['REQUEST_URI']} - {$reason} csrf_token\""); + exec('logger -t webGUI -- '.escapeshellarg("error: {$_SERVER['REQUEST_URI']} - {$reason} csrf_token")); exit; } diff --git a/emhttp/plugins/dynamix/include/publish.php b/emhttp/plugins/dynamix/include/publish.php index f4340dc4f..87bf0d3f3 100644 --- a/emhttp/plugins/dynamix/include/publish.php +++ b/emhttp/plugins/dynamix/include/publish.php @@ -11,13 +11,16 @@ */ ?> $socket, CURLOPT_RETURNTRANSFER => 1]); if ($message) curl_setopt_array($com, [CURLOPT_POSTFIELDS => $message, CURLOPT_POST => 1]); $reply = curl_exec($com); curl_close($com); - if ($reply===false) exec("logger -t curl_socket -- 'curl to $url failed'"); + if ($reply===false) my_logger('curl_socket', "curl to $url failed"); return $reply; } @@ -32,7 +35,7 @@ function publish($endpoint, $message, $len=1) { ]); $reply = curl_exec($com); curl_close($com); - if ($reply===false) exec("logger -t publish -- 'curl to $endpoint failed'"); + if ($reply===false) my_logger('publish', "curl to $endpoint failed"); return $reply; } ?> diff --git a/emhttp/plugins/dynamix/scripts/netconfig b/emhttp/plugins/dynamix/scripts/netconfig index 0621a9c97..7aca65912 100755 --- a/emhttp/plugins/dynamix/scripts/netconfig +++ b/emhttp/plugins/dynamix/scripts/netconfig @@ -12,6 +12,9 @@ */ ?>