10use Psr\Log\LoggerAwareTrait;
11use Psr\Log\NullLogger;
12use Shellbox\Command\BoxedCommand;
13use Shellbox\Command\RemoteBoxedExecutor;
31 private $doLogStderr =
false;
36 private $restrictionMethod;
47 private $shellboxClientFactory;
56 array $limits, $cgroup, $restrictionMethod
58 $this->shellboxClientFactory = $shellboxClientFactory;
59 $this->limits = $limits;
60 $this->cgroup = $cgroup;
61 if ( $restrictionMethod ===
'autodetect' ) {
64 $this->restrictionMethod =
'firejail';
66 $this->restrictionMethod =
false;
69 $this->restrictionMethod = $restrictionMethod;
71 $this->setLogger(
new NullLogger() );
78 if ( $this->firejail ===
null ) {
79 $this->firejail = ExecutableFinder::findInDefaultPaths(
'firejail' );
82 return $this->firejail;
91 public function logStderr(
bool $yesno =
true ): void {
92 $this->doLogStderr = $yesno;
102 private function getLocalShellboxOptions() {
105 'useBashWrapper' => file_exists(
'/bin/bash' ),
106 'cgroup' => $this->cgroup
108 if ( $this->restrictionMethod ===
'firejail' ) {
109 $firejailPath = $this->findFirejail();
110 if ( !$firejailPath ) {
111 throw new \RuntimeException(
'firejail is enabled, but cannot be found' );
113 $options[
'useFirejail'] =
true;
114 $options[
'firejailPath'] = $firejailPath;
115 $options[
'firejailProfile'] = __DIR__ .
'/firejail.profile';
125 if ( $this->restrictionMethod ===
'firejail' ) {
126 if ( $this->useAllUsers ===
null ) {
130 $realIP = realpath(
$IP );
131 $currentUser = posix_getpwuid( posix_geteuid() );
132 $this->useAllUsers = str_starts_with( $realIP,
'/home/' )
133 && !str_starts_with( $realIP, $currentUser[
'dir'] );
134 if ( $this->useAllUsers ) {
135 $this->logger->warning(
'firejail: MediaWiki is located ' .
136 'in a home directory that does not belong to the ' .
137 'current user, so allowing access to all home ' .
138 'directories (--allusers)' );
141 $allUsers = $this->useAllUsers;
143 $executor = Shellbox::createUnboxedExecutor(
144 $this->getLocalShellboxOptions(), $this->logger );
146 $command =
new Command( $executor );
147 $command->setLogger( $this->logger );
149 $command->allowPath(
'/home' );
152 ->limits( $this->limits )
153 ->logStderr( $this->doLogStderr );
166 public function createBoxed( ?
string $service =
null, $wallTimeLimit =
null ): BoxedCommand {
167 $wallTimeLimit ??= $this->limits[
'walltime'];
168 if ( $this->shellboxClientFactory->isEnabled( $service ) ) {
169 $client = $this->shellboxClientFactory->getClient( [
170 'timeout' => $wallTimeLimit + 1,
171 'service' => $service,
173 $executor =
new RemoteBoxedExecutor( $client );
174 $executor->setLogger( $this->logger );
176 $executor = Shellbox::createBoxedExecutor(
177 $this->getLocalShellboxOptions(),
180 return $executor->createCommand()
181 ->cpuTimeLimit( $this->limits[
'time'] )
182 ->wallTimeLimit( $wallTimeLimit )
183 ->memoryLimit( $this->limits[
'memory'] * 1024 )
184 ->fileSizeLimit( $this->limits[
'filesize'] * 1024 )
185 ->logStderr( $this->doLogStderr );
wfTempDir()
Tries to get the system directory for temporary files.
if(!defined('MEDIAWIKI')) if(!defined( 'MW_ENTRY_POINT')) global $IP
Environment checks.