Asked  7 Months ago    Answers:  5   Viewed   26 times

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 it as a command line argument.

That's easy enough, but I'd like it to not echo the password to the screen as it's typed. How can I do this with PHP?

Bonus points for doing it in pure PHP (no system('stty')) and replacing the characters with *.

EDIT:

The script will run on a unix like system (linux or mac). The script is written in PHP, and will most likely stay like that.

Also, for the record, the stty way of doing it is:

echo "Password: ";
system('stty -echo');
$password = trim(fgets(STDIN));
system('stty echo');
// add a new line since the users CR didn't echo
echo "n";

I'd prefer to not have the system() calls in there.

 Answers

52

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;
  }
}
Wednesday, March 31, 2021
 
max_
answered 7 Months ago
66

The problem with your code is that you are using the double quotation marks " instead of the single quotation marks ' when dealing with your hash.

When assigning:

$hash = "$2y$10$fXJEsC0zWAR2tDrmlJgSaecbKyiEOK9GDCRKDReYM8gH2bG2mbO4e";

It's making php think you have a variable called $2y and another one called $10 and finally a third one called $fXJEsC0zWAR2tDrmlJgSaecbKyiEOK9GDCRKDReYM8gH2bG2mbO4e. Which obviously isn't the case.

I noticed when turning on error reporting that the error:

Notice: Undefined variable: fXJEsC0zWAR2tDrmlJgSaecbKyiEOK9GDCRKDReYM8gH2bG2mbO4e

Was being thrown by PHP.

Replace all your double quote marks with single quote marks to fix.

E.g

$hash = '$2y$10$fXJEsC0zWAR2tDrmlJgSaecbKyiEOK9GDCRKDReYM8gH2bG2mbO4e';

Treats the whole hash as a literal string instead of a string with embedded variables.

Wednesday, March 31, 2021
 
Sethunath
answered 7 Months ago
86

Usually, the process what do you send to background with the & and the script waiting for an input from the terminal, going into the stopped state.

E.g. have a bash script valecho:

#!/bin/sh
read val
echo $val

runnig it as:

./valecho &

the script will stop.

When run it as

echo hello | ./valecho &

will correctly run and finish.

So, check your php - probably wants some input from the stdin

Edit - based on comment:

i'm not an php developer - but just tried the next script (p.php)

<?php
    while(true){
        echo 'hi '.time()."n";
        sleep(3);
    }
?>

with the command:

php -f p.php &

and running nicely... so... sry for confusion...

Wednesday, March 31, 2021
 
Powering
answered 7 Months ago
37

Prefix the command with LANG = <language>.UTF8.

Example:

$ php -r "echo exec('LANG="en_US.UTF8" locale charmap');"
UTF-8
$ php -r "echo exec('LANG="en_US.iso88591" locale charmap');
ISO-8859-1

You should have the locale installed.

Tuesday, August 10, 2021
 
Razvan N
answered 3 Months ago
37

The given hash string example has 50 characters instead of 60. Double-Check the database - CHAR(60) - and var_dump($hash).

Monday, August 23, 2021
 
vcsjones
answered 2 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :