Command Line Password Prompt in PHP

后端 未结 10 1460
北海茫月
北海茫月 2020-11-30 21:48

I\'m writing a command line tool to help my web app. It needs a password to connect to the service. I\'d like the script to show a password prompt so I don\'t have to pass i

相关标签:
10条回答
  • 2020-11-30 22:21

    Theorically you can do it using stream_set_blocking(), but looks like there are some PHP bugs managing STDIN.

    Look: http://bugs.php.net/bug.php?id=34972 http://bugs.php.net/bug.php?id=36030

    Try yourself:

    echo "Enter Password: ";
    $stdin = fopen('php://stdin','r');
    // Trying to disable stream blocking
    stream_set_blocking($stdin, FALSE) or die ('Failed to disable stdin blocking');
    // Trying to set stream timeout to 1sec
    stream_set_timeout ($stdin, 1) or die ('Failed to enable stdin timeout');
    0 讨论(0)
  • 2020-11-30 22:28

    The below method works under Linux CLI but not under Windows CLI or Apache. It also only works with chars in the standard Ascii table (It would not take much to make it compatible with extended char sets though).

    I have put a bit of code in to protect against copy and paste passwords. If the bit between the two comments is removed then a password can be injected/pasted in.

    I hope this helps someone.

    <?php
    
        echo("Password: ");
        $strPassword=getObscuredText();
        echo("\n");
        echo("You entered: ".$strPassword."\n");
    
        function getObscuredText($strMaskChar='*')
        {
            if(!is_string($strMaskChar) || $strMaskChar=='')
            {
                $strMaskChar='*';
            }
            $strMaskChar=substr($strMaskChar,0,1);
            readline_callback_handler_install('', function(){});
            $strObscured='';
            while(true)
            {
                $strChar = stream_get_contents(STDIN, 1);
                $intCount=0;
    // Protect against copy and paste passwords
    // Comment \/\/\/ to remove password injection protection
                $arrRead = array(STDIN);
                $arrWrite = NULL;
                $arrExcept = NULL;
                while (stream_select($arrRead, $arrWrite, $arrExcept, 0,0) && in_array(STDIN, $arrRead))            
                {
                    stream_get_contents(STDIN, 1);
                    $intCount++;
                }
    //        /\/\/\
    // End of protection against copy and paste passwords
                if($strChar===chr(10))
                {
                    break;
                }
                if ($intCount===0)
                {
                    if(ord($strChar)===127)
                    {
                        if(strlen($strObscured)>0)
                        {
                            $strObscured=substr($strObscured,0,strlen($strObscured)-1);
                            echo(chr(27).chr(91)."D"." ".chr(27).chr(91)."D");
                        }
                    }
                    elseif ($strChar>=' ')
                    {
                        $strObscured.=$strChar;
                        echo($strMaskChar);
                        //echo(ord($strChar));
                    }
                }
            }
            readline_callback_handler_remove();
            return($strObscured);
        }
    ?>
    
    0 讨论(0)
  • 2020-11-30 22:29

    Works on every windows system, that has powershell support. (source from: http://www.qxs.ch/2013/02/08/php-cli-password-prompts-on-windows-7/ )

    <?php
    // please set the path to your powershell, here it is: C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe
    $pwd=shell_exec('C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe -Command "$Password=Read-Host -assecurestring \"Please enter your password\" ; $PlainPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Password)) ; echo $PlainPassword;"');
    $pwd=explode("\n", $pwd); $pwd=$pwd[0];
    echo "You have entered the following password: $pwd\n";
    
    0 讨论(0)
  • 2020-11-30 22:33

    Found on sitepoint.

    function prompt_silent($prompt = "Enter Password:") {
      if (preg_match('/^win/i', PHP_OS)) {
        $vbscript = sys_get_temp_dir() . 'prompt_password.vbs';
        file_put_contents(
          $vbscript, 'wscript.echo(InputBox("'
          . addslashes($prompt)
          . '", "", "password here"))');
        $command = "cscript //nologo " . escapeshellarg($vbscript);
        $password = rtrim(shell_exec($command));
        unlink($vbscript);
        return $password;
      } else {
        $command = "/usr/bin/env bash -c 'echo OK'";
        if (rtrim(shell_exec($command)) !== 'OK') {
          trigger_error("Can't invoke bash");
          return;
        }
        $command = "/usr/bin/env bash -c 'read -s -p \""
          . addslashes($prompt)
          . "\" mypassword && echo \$mypassword'";
        $password = rtrim(shell_exec($command));
        echo "\n";
        return $password;
      }
    }
    
    0 讨论(0)
提交回复
热议问题