24use Psr\Log\LoggerAwareTrait;
25use Psr\Log\NullLogger;
26use Shellbox\Command\BoxedCommand;
27use Shellbox\Command\RemoteBoxedExecutor;
45 private $doLogStderr =
false;
50 private $restrictionMethod;
61 private $shellboxClientFactory;
70 array $limits, $cgroup, $restrictionMethod
72 $this->shellboxClientFactory = $shellboxClientFactory;
73 $this->limits = $limits;
74 $this->cgroup = $cgroup;
75 if ( $restrictionMethod ===
'autodetect' ) {
78 $this->restrictionMethod =
'firejail';
80 $this->restrictionMethod =
false;
83 $this->restrictionMethod = $restrictionMethod;
85 $this->setLogger(
new NullLogger() );
92 if ( $this->firejail ===
null ) {
93 $this->firejail = ExecutableFinder::findInDefaultPaths(
'firejail' );
96 return $this->firejail;
106 $this->doLogStderr = $yesno;
116 private function getLocalShellboxOptions() {
119 'useBashWrapper' => file_exists(
'/bin/bash' ),
120 'cgroup' => $this->cgroup
122 if ( $this->restrictionMethod ===
'firejail' ) {
123 $firejailPath = $this->findFirejail();
124 if ( !$firejailPath ) {
125 throw new \RuntimeException(
'firejail is enabled, but cannot be found' );
127 $options[
'useFirejail'] =
true;
128 $options[
'firejailPath'] = $firejailPath;
129 $options[
'firejailProfile'] = __DIR__ .
'/firejail.profile';
139 if ( $this->restrictionMethod ===
'firejail' ) {
140 if ( $this->useAllUsers ===
null ) {
144 $realIP = realpath(
$IP );
145 $currentUser = posix_getpwuid( posix_geteuid() );
146 $this->useAllUsers = str_starts_with( $realIP,
'/home/' )
147 && !str_starts_with( $realIP, $currentUser[
'dir'] );
148 if ( $this->useAllUsers ) {
149 $this->logger->warning(
'firejail: MediaWiki is located ' .
150 'in a home directory that does not belong to the ' .
151 'current user, so allowing access to all home ' .
152 'directories (--allusers)' );
155 $allUsers = $this->useAllUsers;
157 $executor = Shellbox::createUnboxedExecutor(
158 $this->getLocalShellboxOptions(), $this->logger );
160 $command =
new Command( $executor );
161 $command->setLogger( $this->logger );
163 $command->allowPath(
'/home' );
166 ->limits( $this->limits )
167 ->logStderr( $this->doLogStderr );
180 public function createBoxed( ?
string $service =
null, $wallTimeLimit =
null ): BoxedCommand {
181 $wallTimeLimit ??= $this->limits[
'walltime'];
182 if ( $this->shellboxClientFactory->isEnabled( $service ) ) {
183 $client = $this->shellboxClientFactory->getClient( [
184 'timeout' => $wallTimeLimit + 1,
185 'service' => $service,
187 $executor =
new RemoteBoxedExecutor( $client );
188 $executor->setLogger( $this->logger );
190 $executor = Shellbox::createBoxedExecutor(
191 $this->getLocalShellboxOptions(),
194 return $executor->createCommand()
195 ->cpuTimeLimit( $this->limits[
'time'] )
196 ->wallTimeLimit( $wallTimeLimit )
197 ->memoryLimit( $this->limits[
'memory'] * 1024 )
198 ->fileSizeLimit( $this->limits[
'filesize'] * 1024 )
199 ->logStderr( $this->doLogStderr );
wfTempDir()
Tries to get the system directory for temporary files.
if(!defined( 'MEDIAWIKI')) if(ini_get('mbstring.func_overload')) if(!defined( 'MW_ENTRY_POINT')) global $IP
Environment checks.
Utility class to find executables in likely places.