Merge "Add semantic tags to license info text"
[lhc/web/wiklou.git] / includes / shell / Shell.php
index c293ff2..d57bf4f 100644 (file)
@@ -22,6 +22,8 @@
 
 namespace MediaWiki\Shell;
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * Executes shell commands
  *
@@ -29,20 +31,80 @@ namespace MediaWiki\Shell;
  *
  * Use call chaining with this class for expressiveness:
  *  $result = Shell::command( 'some command' )
+ *       ->input( 'foo' )
  *       ->environment( [ 'ENVIRONMENT_VARIABLE' => 'VALUE' ] )
  *       ->limits( [ 'time' => 300 ] )
  *       ->execute();
  *
  *  ... = $result->getExitCode();
  *  ... = $result->getStdout();
+ *  ... = $result->getStderr();
  */
 class Shell {
 
        /**
-        * Returns a new instance of this class
+        * Apply a default set of restrictions for improved
+        * security out of the box.
+        *
+        * Equal to NO_ROOT | SECCOMP | PRIVATE_DEV | NO_LOCALSETTINGS
+        *
+        * @note This value will change over time to provide increased security
+        *       by default, and is not guaranteed to be backwards-compatible.
+        * @since 1.31
+        */
+       const RESTRICT_DEFAULT = 39;
+
+       /**
+        * Disallow any root access. Any setuid binaries
+        * will be run without elevated access.
+        *
+        * @since 1.31
+        */
+       const NO_ROOT = 1;
+
+       /**
+        * Use seccomp to block dangerous syscalls
+        * @see <https://en.wikipedia.org/wiki/seccomp>
+        *
+        * @since 1.31
+        */
+       const SECCOMP = 2;
+
+       /**
+        * Create a private /dev
+        *
+        * @since 1.31
+        */
+       const PRIVATE_DEV = 4;
+
+       /**
+        * Restrict the request to have no
+        * network access
+        *
+        * @since 1.31
+        */
+       const NO_NETWORK = 8;
+
+       /**
+        * Deny execve syscall with seccomp
+        * @see <https://en.wikipedia.org/wiki/exec_(system_call)>
+        *
+        * @since 1.31
+        */
+       const NO_EXECVE = 16;
+
+       /**
+        * Deny access to LocalSettings.php (MW_CONFIG_FILE)
+        *
+        * @since 1.31
+        */
+       const NO_LOCALSETTINGS = 32;
+
+       /**
+        * Returns a new instance of Command class
         *
-        * @param string|string[] $command If string, a properly shell-escaped command line,
-        *   or an array of unescaped arguments, in which case each value will be escaped
+        * @param string|string[] $command String or array of strings representing the command to
+        * be executed, each value will be escaped.
         *   Example:   [ 'convert', '-font', 'font name' ] would produce "'convert' '-font' 'font name'"
         * @return Command
         */
@@ -53,7 +115,10 @@ class Shell {
                        // treat it as a list of arguments
                        $args = reset( $args );
                }
-               $command = new Command();
+               $command = MediaWikiServices::getInstance()
+                       ->getShellCommandFactory()
+                       ->create();
+
                return $command->params( $args );
        }
 
@@ -85,7 +150,7 @@ class Shell {
         * PHP 5.2.6+ (bug backported to earlier distro releases of PHP).
         *
         * @param string $args,... strings to escape and glue together, or a single array of
-        *     strings parameter
+        *     strings parameter. Null values are ignored.
         * @return string
         */
        public static function escape( /* ... */ ) {
@@ -99,6 +164,9 @@ class Shell {
                $first = true;
                $retVal = '';
                foreach ( $args as $arg ) {
+                       if ( $arg === null ) {
+                               continue;
+                       }
                        if ( !$first ) {
                                $retVal .= ' ';
                        } else {
@@ -107,14 +175,12 @@ class Shell {
 
                        if ( wfIsWindows() ) {
                                // Escaping for an MSVC-style command line parser and CMD.EXE
-                               // @codingStandardsIgnoreStart For long URLs
                                // Refs:
                                //  * https://web.archive.org/web/20020708081031/http://mailman.lyra.org/pipermail/scite-interest/2002-March/000436.html
                                //  * https://technet.microsoft.com/en-us/library/cc723564.aspx
                                //  * T15518
                                //  * CR r63214
                                // Double the backslashes before any double quotes. Escape the double quotes.
-                               // @codingStandardsIgnoreEnd
                                $tokens = preg_split( '/(\\\\*")/', $arg, -1, PREG_SPLIT_DELIM_CAPTURE );
                                $arg = '';
                                $iteration = 0;