Pārlūkot izejas kodu

Automatic trusted_sources during install (#5358)

* Automatic trusted_sources during install
Fix https://github.com/FreshRSS/FreshRSS/issues/5357

* Fix install for http_auth

* Update lib/lib_rss.php

Co-authored-by: Luc SANCHEZ <4697568+ColonelMoutarde@users.noreply.github.com>

* Fill null exception e-mail

* Revert some syntax

* Minor parentheses
Alexandre Alapetite 2 gadi atpakaļ
vecāks
revīzija
0a38aa7456

+ 1 - 1
app/Controllers/authController.php

@@ -75,7 +75,7 @@ class FreshRSS_auth_Controller extends FreshRSS_ActionController {
 				break;
 			case 'http_auth':
 				Minz_Error::error(403, array('error' => array(_t('feedback.access.denied'),
-						' [HTTP Remote-User=' . htmlspecialchars(httpAuthUser(), ENT_NOQUOTES, 'UTF-8') .
+						' [HTTP Remote-User=' . htmlspecialchars(httpAuthUser(false), ENT_NOQUOTES, 'UTF-8') .
 						' ; Remote IP address=' . ($_SERVER['REMOTE_ADDR'] ?? '') . ']'
 					)), false);
 				break;

+ 1 - 1
app/Controllers/userController.php

@@ -212,7 +212,7 @@ class FreshRSS_user_Controller extends FreshRSS_ActionController {
 	}
 
 	/** @param array<string,mixed> $userConfigOverride */
-	public static function createUser(string $new_user_name, string $email, string $passwordPlain,
+	public static function createUser(string $new_user_name, ?string $email, string $passwordPlain,
 		array $userConfigOverride = [], bool $insertDefaultFeeds = true): bool {
 		$userConfig = [];
 

+ 1 - 1
app/Models/Auth.php

@@ -75,7 +75,7 @@ class FreshRSS_Auth {
 				$email = null;
 				if (FreshRSS_Context::$system_conf->http_auth_auto_register_email_field !== '' &&
 					isset($_SERVER[FreshRSS_Context::$system_conf->http_auth_auto_register_email_field])) {
-					$email = $_SERVER[FreshRSS_Context::$system_conf->http_auth_auto_register_email_field];
+					$email = (string)$_SERVER[FreshRSS_Context::$system_conf->http_auth_auto_register_email_field];
 				}
 				$language = Minz_Translate::getLanguage(null, Minz_Request::getPreferredLanguages(), FreshRSS_Context::$system_conf->language);
 				Minz_Translate::init($language);

+ 2 - 2
app/Models/SystemConfiguration.php

@@ -7,7 +7,7 @@
  * @property-read bool $allow_robots
  * @property bool $api_enabled
  * @property string $archiving
- * @property string $auth_type
+ * @property 'form'|'http_auth'|'none' $auth_type
  * @property string $auto_update_url
  * @property-read array<int,mixed> $curl_options
  * @property string $default_user
@@ -23,7 +23,7 @@
  * @property-read string $salt
  * @property-read bool $simplepie_syslog_enabled
  * @property bool $unsafe_autologin_enabled
- * @property-read array<string> $trusted_sources
+ * @property array<string> $trusted_sources
  */
 final class FreshRSS_SystemConfiguration extends Minz_Configuration {
 

+ 23 - 28
app/install.php

@@ -18,16 +18,8 @@ if (STEP === 2 && isset($_POST['type'])) {
 	Minz_Session::_param('bd_type', $_POST['type']);
 }
 
-/**
- * @param mixed $default
- * @return mixed
- */
-function param(string $key, $default = false) {
-	if (isset($_POST[$key])) {
-		return $_POST[$key];
-	} else {
-		return $default;
-	}
+function param(string $key, string $default = ''): string {
+	return isset($_POST[$key]) && is_string($_POST[$key]) ? trim($_POST[$key]) : $default;
 }
 
 // gestion internationalisation
@@ -146,9 +138,6 @@ function saveStep2(): void {
 		if (Minz_Session::param('title') != '') {
 			$config_array['title'] = Minz_Session::param('title');
 		}
-		if (Minz_Session::param('auth_type') != '') {
-			$config_array['auth_type'] = Minz_Session::param('auth_type');
-		}
 
 		$customConfigPath = DATA_PATH . '/config.custom.php';
 		if (file_exists($customConfigPath)) {
@@ -196,27 +185,33 @@ function saveStep2(): void {
 }
 
 function saveStep3(): bool {
+	FreshRSS_Context::initSystem();
+	Minz_Translate::init(Minz_Session::param('language'));
+
 	if (!empty($_POST)) {
-		$system_default_config = FreshRSS_SystemConfiguration::get('default_system');
-		Minz_Session::_params([
-				'title' => $system_default_config->title,
-				'auth_type' => param('auth_type', 'form'),
-			]);
-		if (FreshRSS_user_Controller::checkUsername(param('default_user', ''))) {
-			Minz_Session::_param('default_user', param('default_user', ''));
+		if (param('auth_type', 'form') != '') {
+			FreshRSS_Context::$system_conf->auth_type = param('auth_type', 'form');
+			Minz_Session::_param('auth_type', FreshRSS_Context::$system_conf->auth_type);
+		} else {
+			return false;
 		}
 
-		if (Minz_Session::param('auth_type') == '' || Minz_Session::param('default_user') == '') {
+		$password_plain = param('passwordPlain', '');
+		if (FreshRSS_Context::$system_conf->auth_type === 'form' && $password_plain == '') {
 			return false;
 		}
 
-		$password_plain = param('passwordPlain', false);
-		if (Minz_Session::param('auth_type') === 'form' && $password_plain == '') {
+		if (FreshRSS_user_Controller::checkUsername(param('default_user', ''))) {
+			FreshRSS_Context::$system_conf->default_user = param('default_user', '');
+			Minz_Session::_param('default_user', FreshRSS_Context::$system_conf->default_user);
+		} else {
 			return false;
 		}
 
-		FreshRSS_Context::initSystem();
-		Minz_Translate::init(Minz_Session::param('language'));
+		if (FreshRSS_Context::$system_conf->auth_type === 'http_auth' && !empty($_SERVER['REMOTE_ADDR']) && is_string($_SERVER['REMOTE_ADDR'])) {
+			// Trust by default the remote IP address (e.g. proxy) used during install to provide remote user name
+			FreshRSS_Context::$system_conf->trusted_sources = [ $_SERVER['REMOTE_ADDR'] ];
+		}
 
 		// Create default user files but first, we delete previous data to
 		// avoid access right problems.
@@ -242,7 +237,6 @@ function saveStep3(): bool {
 			return false;
 		}
 
-		FreshRSS_Context::$system_conf->default_user = Minz_Session::param('default_user');
 		FreshRSS_Context::$system_conf->save();
 
 		header('Location: index.php?step=4');
@@ -591,7 +585,7 @@ function printStep3(): void {
 			<div class="group-controls">
 				<input type="text" id="default_user" name="default_user" autocomplete="username" required="required" size="16"
 					pattern="<?= FreshRSS_user_Controller::USERNAME_PATTERN ?>" value="<?= isset($_SESSION['default_user']) ? $_SESSION['default_user'] : '' ?>"
-					placeholder="<?= httpAuthUser() == '' ? 'alice' : httpAuthUser() ?>" tabindex="1" />
+					placeholder="<?= httpAuthUser(false) == '' ? 'alice' : httpAuthUser(false) ?>" tabindex="1" />
 				<p class="help"><?= _i('help') ?> <?= _t('install.default_user.max_char') ?></p>
 			</div>
 		</div>
@@ -603,7 +597,8 @@ function printStep3(): void {
 					<option value="form"<?= $auth_type === 'form' || (no_auth($auth_type) && cryptAvailable()) ? ' selected="selected"' : '',
 						cryptAvailable() ? '' : ' disabled="disabled"' ?>><?= _t('install.auth.form') ?></option>
 					<option value="http_auth"<?= $auth_type === 'http_auth' ? ' selected="selected"' : '',
-						httpAuthUser() == '' ? ' disabled="disabled"' : '' ?>><?= _t('install.auth.http') ?>(REMOTE_USER = '<?= httpAuthUser() ?>')</option>
+						httpAuthUser(false) == '' ? ' disabled="disabled"' : '' ?>>
+							<?= _t('install.auth.http') ?> (REMOTE_USER = '<?= httpAuthUser(false) ?>')</option>
 					<option value="none"<?= $auth_type === 'none' || (no_auth($auth_type) && !cryptAvailable()) ? ' selected="selected"' : ''
 						?>><?= _t('install.auth.none') ?></option>
 				</select>

+ 24 - 10
lib/lib_rss.php

@@ -634,13 +634,22 @@ function ipToBits(string $ip): string {
  */
 function checkCIDR(string $ip, string $range): bool {
 	$binary_ip = ipToBits($ip);
-	list($subnet, $mask_bits) = explode('/', $range);
-	$mask_bits = intval($mask_bits);
+	$split = explode('/', $range);
+
+	$subnet = $split[0] ?? '';
+	if ($subnet == '') {
+		return false;
+	}
 	$binary_subnet = ipToBits($subnet);
 
+	$mask_bits = $split[1] ?? '';
+	$mask_bits = (int)$mask_bits;
+	if ($mask_bits === 0) {
+		$mask_bits = null;
+	}
+
 	$ip_net_bits = substr($binary_ip, 0, $mask_bits);
 	$subnet_bits = substr($binary_subnet, 0, $mask_bits);
-
 	return $ip_net_bits === $subnet_bits;
 }
 
@@ -653,7 +662,7 @@ function checkCIDR(string $ip, string $range): bool {
  */
 function checkTrustedIP(): bool {
 	if (FreshRSS_Context::$system_conf === null) {
-		throw new FreshRSS_Context_Exception('System configuration not initialised!');
+		return false;
 	}
 	if (!empty($_SERVER['REMOTE_ADDR'])) {
 		foreach (FreshRSS_Context::$system_conf->trusted_sources as $cidr) {
@@ -665,15 +674,20 @@ function checkTrustedIP(): bool {
 	return false;
 }
 
-function httpAuthUser(): string {
+function httpAuthUser(bool $onlyTrusted = true): string {
 	if (!empty($_SERVER['REMOTE_USER'])) {
 		return $_SERVER['REMOTE_USER'];
-	} elseif (!empty($_SERVER['HTTP_REMOTE_USER']) && checkTrustedIP()) {
-		return $_SERVER['HTTP_REMOTE_USER'];
-	} elseif (!empty($_SERVER['REDIRECT_REMOTE_USER'])) {
+	}
+	if (!empty($_SERVER['REDIRECT_REMOTE_USER'])) {
 		return $_SERVER['REDIRECT_REMOTE_USER'];
-	} elseif (!empty($_SERVER['HTTP_X_WEBAUTH_USER']) && checkTrustedIP()) {
-		return $_SERVER['HTTP_X_WEBAUTH_USER'];
+	}
+	if (!$onlyTrusted || checkTrustedIP()) {
+		if (!empty($_SERVER['HTTP_REMOTE_USER'])) {
+			return $_SERVER['HTTP_REMOTE_USER'];
+		}
+		if (!empty($_SERVER['HTTP_X_WEBAUTH_USER'])) {
+			return $_SERVER['HTTP_X_WEBAUTH_USER'];
+		}
 	}
 	return '';
 }