Collapse some nested if statements
[lhc/web/wiklou.git] / tests / integration / includes / shell / FirejailCommandIntegrationTest.php
1 <?php
2
3 use MediaWiki\Shell\FirejailCommand;
4 use MediaWiki\Shell\Shell;
5
6 /**
7 * Integration tests to ensure that firejail actually prevents execution.
8 * Meant to run on vagrant, although will probably work on other setups
9 * as long as firejail and sudo has similar config.
10 *
11 * @group large
12 * @group Shell
13 * @covers FirejailCommand
14 */
15 class FirejailCommandIntegrationTest extends PHPUnit\Framework\TestCase {
16
17 public function setUp() {
18 parent::setUp();
19 if ( Shell::isDisabled() ) {
20 $this->markTestSkipped( 'shelling out is disabled' );
21 } elseif ( Shell::command( 'which', 'firejail' )->execute()->getExitCode() ) {
22 $this->markTestSkipped( 'firejail not installed' );
23 } elseif ( wfIsWindows() ) {
24 $this->markTestSkipped( 'test supports POSIX environments only' );
25 }
26 }
27
28 public function testSanity() {
29 // Make sure that firejail works at all.
30 $command = new FirejailCommand( 'firejail' );
31 $command
32 ->unsafeParams( 'ls .' )
33 ->restrict( Shell::RESTRICT_DEFAULT );
34 $result = $command->execute();
35 $this->assertSame( 0, $result->getExitCode() );
36 }
37
38 /**
39 * @coversNothing
40 * @dataProvider provideExecute
41 */
42 public function testExecute( $testCommand, $flag ) {
43 if ( preg_match( '/^sudo /', $testCommand )
44 && Shell::command( 'sudo', '-n', 'ls', '/' )->execute()->getExitCode()
45 ) {
46 $this->markTestSkipped( 'need passwordless sudo' );
47 }
48
49 $command = new FirejailCommand( 'firejail' );
50 $command
51 ->unsafeParams( $testCommand )
52 // If we don't restrict at all, firejail won't be invoked,
53 // so the test will give a false positive if firejail breaks
54 // the command for some non-flag-related reason. Instead,
55 // set some flag that won't get in the way.
56 ->restrict( $flag === Shell::NO_NETWORK ? Shell::PRIVATE_DEV : Shell::NO_NETWORK );
57 $result = $command->execute();
58 $this->assertSame( 0, $result->getExitCode(), 'sanity check' );
59
60 $command = new FirejailCommand( 'firejail' );
61 $command
62 ->unsafeParams( $testCommand )
63 ->restrict( $flag );
64 $result = $command->execute();
65 $this->assertNotSame( 0, $result->getExitCode(), 'real check' );
66 }
67
68 public function provideExecute() {
69 global $IP;
70 return [
71 [ 'sudo -n ls /', Shell::NO_ROOT ],
72 [ 'sudo -n ls /', Shell::SECCOMP ], // not a great test but seems to work
73 [ 'ls /dev/cpu', Shell::PRIVATE_DEV ],
74 [ 'curl -fsSo /dev/null https://wikipedia.org/', Shell::NO_NETWORK ],
75 [ 'exec ls /', Shell::NO_EXECVE ],
76 [ "cat $IP/LocalSettings.php", Shell::NO_LOCALSETTINGS ],
77 ];
78 }
79
80 }