samwilson / diagrams-extension

A MediaWiki extension that displays GraphViz, Mscgen, PlantUML, and Mermaid diagrams in wiki pages.
https://www.mediawiki.org/wiki/Extension:Diagrams
GNU General Public License v2.0
8 stars 12 forks source link

Diagrams error: /bin/bash: dot: command not found #22

Open WolfgangFahl opened 3 years ago

WolfgangFahl commented 3 years ago

This time on Ubuntu 20.04. LTS things get harder in the firejailed environment.

Im using https://www.mediawiki.org/wiki/Extension:Piwo which also uses Shell::Command so i can see what can be executed and what not.

import subprocess
cmds=[["pwd"],["env"],["/bin/which", "dot"],["which", "dot"],["ls","-l","/usr/bin/dot"]]
for cmd in cmds:
  proc=subprocess.run(cmd,capture_output=True)
  print("=%s=\n<pre>%s</pre>" % (cmd,proc.stdout.decode()))

will work and i can see that e.g.

which dot

will not return anything

ls -l
lrwxrwxrwx 1 nobody nogroup 29 Mar  2  2020 /usr/bin/dot -> ../sbin/libgvc6-config-update

looks fine but might give trouble due to the symlink into the sbin environment.

Calling

/usr/bin/dot -V

leads to

PermissionError: [Errno 13] Permission denied: '/usr/bin/dot'

where is this permission filter configured? i want the keys for my house back :-)

WolfgangFahl commented 3 years ago

I'd love to alternatively use the traditional direct shell_exec since functionality has much higher priority than security in my usecase:

/**
     * @param string $commandName
     * @param array $cmdArgs
     * @return Result
     */
  private function execShellCommand($commandName,$cmdArgs) {
    $shellcmd=$commandName;
    foreach ($cmdArgs as $arg) {
            $shellcmd.=' '.escapeshellarg($arg);
    }
    $shellcmd.=" 2>&1";
    //$output=$shellcmd;
    $output=shell_exec($shellcmd);
    return $output;
  }
samwilson commented 3 years ago

I'm not sure I completely follow: you mean you want to have local graph generation in an environment in which you're not permitted to run dot? I don't think that's possible. Or is dot just not in your web server user's $PATH?

As for using shell_exec() directly, that's not a good idea: MediaWiki provides a system for shelling out for security reasons, and although you say you're not worried about security it's not worth compromising things I think.

The idea of the Diagrams service is to provide a way to do the rendering outside the MediaWiki environment. It sounds like that is working for you; why do you need to enable local rendering?

WolfgangFahl commented 3 years ago

@samwilson thx for the swift reply. Currently i am between a rock and hard place. There is an error using diagrams.bitplan.com service which i can't debug right now since my eclipse doesn't work in my Ubuntu environment. With a MediaWiki befor 1.35 LTS i could use the local services and then #21 hit me which is why i want the shell_exec back and not the crippling try for security which makes the system unusable. I will never trade security which i do not need for a non working system and therefore will switch to an unsafer version in my safe intranet environments happily. I also do not see what the security problem shall be of calling a predefined command with predefined arguments. The work on a newer system for shell access is ongoing and not available yet so I'd rather go with a working system while things are improved.

WolfgangFahl commented 3 years ago

Also for proper svg support with hyperlinks local rendering might be a must or at least the results of the service might need to be copied locally since the browers won't render hyperlinks in foreign svg files.

WolfgangFahl commented 3 years ago

The svg hyperlinking feature is one of the most important ones for me since it is very convenient to make items in graphviz and uml clickable this way and the rendering is in vector format which allows zooming in into large graphs.

samwilson commented 3 years ago

(Can you please try to stick to the topic? If you're having issues with SVG, open a separate ticket.)

As for this issue, can you try disabling seccomp in Diagrams::runCommand()? Something like:

$cmd->restrict( Shell::RESTRICT_DEFAULT | Shell::NO_NETWORK & ~Shell::SECCOMP );
WolfgangFahl commented 3 years ago

Certainly:

Diagrams error (with dot command): /bin/bash: dot: command not found 
$useShell=True;
        if ($useShell) {
           $cmd = Shell::command( array_merge( [ $commandName ], $cmdArgs, [ $inputFilename ] ) );
       $cmd->restrict( Shell::RESTRICT_DEFAULT | Shell::NO_NETWORK & ~Shell::SECCOMP );
           #$cmd->restrict( Shell::RESTRICT_DEFAULT | Shell::NO_NETWORK );
           return $cmd->execute();
    } else {
      return self::execShellCommand($commandName,$cmdArgs); 
    }

whill set useShell=False to make progress again ...

WolfgangFahl commented 3 years ago

I got my eclipse debugging environment according to http://wiki.bitplan.com/index.php/PHP_Mediawiki_Eclipse_debugging#2020-10 working again and could fix the details. The following code works:

/**
     * @param string $commandName
     * @param string $outputFormat
     * @param string $inputFilename
     * @param string $outputFilename
     * @return Result
     */
    private function runCommand( $commandName, $outputFormat, $inputFilename, $outputFilename ): Result {
        if ( $commandName === 'plantuml' ) {
            $cmdArgs = [ "-t$outputFormat", '-output', dirname( $outputFilename ), '-syntax' ];
        } else {
            $cmdArgs = [ '-T', $outputFormat, '-o', $outputFilename ];
        }
        $useShell=False;
        if ($useShell) {
           $cmd = Shell::command( array_merge( [ $commandName ], $cmdArgs, [ $inputFilename ] ) );
       $cmd->restrict( Shell::RESTRICT_DEFAULT | Shell::NO_NETWORK & ~Shell::SECCOMP );
           #$cmd->restrict( Shell::RESTRICT_DEFAULT | Shell::NO_NETWORK );
           return $cmd->execute();
    } else {
      return self::execShellCommand($commandName,$cmdArgs,$inputFilename); 
    }
    }

    /**
     * @param string $commandName
     * @param array $cmdArgs
     * @param string inputFilename
     * @return Result
     */
  private function execShellCommand($commandName,$cmdArgs,$inputFilename):Result {
    $shellcmd=$commandName;
    foreach ($cmdArgs as $arg) {
            $shellcmd.=' '.escapeshellarg($arg);
    }
    $shellcmd.=' '.escapeshellarg($inputFilename);
    $shellcmd.=" 2>&1";
    #$output=$shellcmd;
    $output=shell_exec($shellcmd);
    if (empty($output)) {
        $output="";
    }
    $result=new Result(0,$output,"");
    return $result;
  }
WolfgangFahl commented 3 years ago

see http://wiki.bitplan.com/index.php/GraphViz#Graph