Page Menu
Home
WickedGov Phorge
Search
Configure Global Search
Log In
Files
F1432416
CommandFactory.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
CommandFactory.php
View Options
<?php
/**
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
* @file
*/
namespace
MediaWiki\Shell
;
use
ExecutableFinder
;
use
Psr\Log\LoggerAwareTrait
;
use
Psr\Log\NullLogger
;
use
Shellbox\Command\BoxedCommand
;
use
Shellbox\Command\RemoteBoxedExecutor
;
use
Shellbox\Shellbox
;
/**
* Factory facilitating dependency injection for Command
*
* @since 1.30
*/
class
CommandFactory
{
use
LoggerAwareTrait
;
/** @var array */
private
$limits
;
/** @var string|bool */
private
$cgroup
;
/** @var bool */
private
$doLogStderr
=
false
;
/**
* @var string|bool
*/
private
$restrictionMethod
;
/**
* @var string|bool|null
*/
private
$firejail
;
/** @var bool */
private
$useAllUsers
;
/** @var ShellboxClientFactory */
private
$shellboxClientFactory
;
/**
* @param ShellboxClientFactory $shellboxClientFactory
* @param array $limits See {@see Command::limits()}
* @param string|bool $cgroup
* @param string|bool $restrictionMethod
*/
public
function
__construct
(
ShellboxClientFactory
$shellboxClientFactory
,
array
$limits
,
$cgroup
,
$restrictionMethod
)
{
$this
->
shellboxClientFactory
=
$shellboxClientFactory
;
$this
->
limits
=
$limits
;
$this
->
cgroup
=
$cgroup
;
if
(
$restrictionMethod
===
'autodetect'
)
{
// On Linux systems check for firejail
if
(
PHP_OS
===
'Linux'
&&
$this
->
findFirejail
()
)
{
$this
->
restrictionMethod
=
'firejail'
;
}
else
{
$this
->
restrictionMethod
=
false
;
}
}
else
{
$this
->
restrictionMethod
=
$restrictionMethod
;
}
$this
->
setLogger
(
new
NullLogger
()
);
}
/**
* @return bool|string
*/
protected
function
findFirejail
()
{
if
(
$this
->
firejail
===
null
)
{
$this
->
firejail
=
ExecutableFinder
::
findInDefaultPaths
(
'firejail'
);
}
return
$this
->
firejail
;
}
/**
* When enabled, text sent to stderr will be logged with a level of 'error'.
*
* @param bool $yesno
* @see Command::logStderr
*/
public
function
logStderr
(
bool
$yesno
=
true
):
void
{
$this
->
doLogStderr
=
$yesno
;
}
/**
* Get the options which will be used for local unboxed execution.
* Shellbox should be configured to act in an approximately backwards
* compatible way, equivalent to the pre-Shellbox MediaWiki shell classes.
*
* @return array
*/
private
function
getLocalShellboxOptions
()
{
$options
=
[
'tempDir'
=>
wfTempDir
(),
'useBashWrapper'
=>
file_exists
(
'/bin/bash'
),
'cgroup'
=>
$this
->
cgroup
];
if
(
$this
->
restrictionMethod
===
'firejail'
)
{
$firejailPath
=
$this
->
findFirejail
();
if
(
!
$firejailPath
)
{
throw
new
\RuntimeException
(
'firejail is enabled, but cannot be found'
);
}
$options
[
'useFirejail'
]
=
true
;
$options
[
'firejailPath'
]
=
$firejailPath
;
$options
[
'firejailProfile'
]
=
__DIR__
.
'/firejail.profile'
;
}
return
$options
;
}
/**
* Instantiates a new Command
*
* @return Command
*/
public
function
create
():
Command
{
$allUsers
=
false
;
if
(
$this
->
restrictionMethod
===
'firejail'
)
{
if
(
$this
->
useAllUsers
===
null
)
{
global
$IP
;
// In case people are doing funny things with symlinks
// or relative paths, resolve them all.
$realIP
=
realpath
(
$IP
);
$currentUser
=
posix_getpwuid
(
posix_geteuid
()
);
$this
->
useAllUsers
=
str_starts_with
(
$realIP
,
'/home/'
)
&&
!
str_starts_with
(
$realIP
,
$currentUser
[
'dir'
]
);
if
(
$this
->
useAllUsers
)
{
$this
->
logger
->
warning
(
'firejail: MediaWiki is located '
.
'in a home directory that does not belong to the '
.
'current user, so allowing access to all home '
.
'directories (--allusers)'
);
}
}
$allUsers
=
$this
->
useAllUsers
;
}
$executor
=
Shellbox
::
createUnboxedExecutor
(
$this
->
getLocalShellboxOptions
(),
$this
->
logger
);
$command
=
new
Command
(
$executor
);
$command
->
setLogger
(
$this
->
logger
);
if
(
$allUsers
)
{
$command
->
allowPath
(
'/home'
);
}
return
$command
->
limits
(
$this
->
limits
)
->
logStderr
(
$this
->
doLogStderr
);
}
/**
* Instantiates a new BoxedCommand.
*
* @since 1.36
* @param ?string $service Name of Shellbox (as configured in
* $wgShellboxUrls) that should be used
* @param int|float|null $wallTimeLimit The wall time limit, or null to use the default.
* This needs to be set early so that the HTTP timeout is configured correctly.
* @return BoxedCommand
*/
public
function
createBoxed
(
?
string
$service
=
null
,
$wallTimeLimit
=
null
):
BoxedCommand
{
$wallTimeLimit
??=
$this
->
limits
[
'walltime'
];
if
(
$this
->
shellboxClientFactory
->
isEnabled
(
$service
)
)
{
$client
=
$this
->
shellboxClientFactory
->
getClient
(
[
'timeout'
=>
$wallTimeLimit
+
1
,
'service'
=>
$service
,
]
);
$executor
=
new
RemoteBoxedExecutor
(
$client
);
$executor
->
setLogger
(
$this
->
logger
);
}
else
{
$executor
=
Shellbox
::
createBoxedExecutor
(
$this
->
getLocalShellboxOptions
(),
$this
->
logger
);
}
return
$executor
->
createCommand
()
->
cpuTimeLimit
(
$this
->
limits
[
'time'
]
)
->
wallTimeLimit
(
$wallTimeLimit
)
->
memoryLimit
(
$this
->
limits
[
'memory'
]
*
1024
)
->
fileSizeLimit
(
$this
->
limits
[
'filesize'
]
*
1024
)
->
logStderr
(
$this
->
doLogStderr
);
}
}
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Sat, May 16, 21:44 (1 d, 4 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
dd/80/cbcff60a058f6dfc440737a1b54b
Default Alt Text
CommandFactory.php (5 KB)
Attached To
Mode
rMWPROD MediaWiki Production
Attached
Detach File
Event Timeline
Log In to Comment