para paginas lista instrucciones formularios formulario ejemplos comandos codigos codigo php passwords

paginas - lista de comandos php



Solicitud de contraseña de la línea de comando en PHP (10)

Estoy escribiendo una herramienta de línea de comandos para ayudar a mi aplicación web. Necesita una contraseña para conectarse al servicio. Me gustaría que el script muestre un mensaje de contraseña para que no tenga que pasarlo como un argumento de línea de comando.

Eso es bastante fácil, pero me gustaría que no se haga eco de la contraseña de la pantalla a medida que se escribe. ¿Cómo puedo hacer esto con PHP?

Puntos de bonificación por hacerlo en PHP puro (sin system(''stty'') ) y reemplazando los caracteres por * .

EDITAR:

El script se ejecutará en un sistema de tipo Unix (Linux o Mac). La secuencia de comandos está escrita en PHP, y probablemente seguirá así.

Además, para el registro, la forma más stty de hacerlo es:

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";

Preferiría no tener las llamadas al system() allí.


¿Por qué no usar una conexión SSH? Puede abstraer los comandos, redirigir la entrada / salida y tener control total.

Puede proporcionarle a alguien una shell pura y limpia con los mínimos derechos necesarios, y dejar que la contraseña se envíe por POST junto con SSH2 :: Connect () para abrir el shell.

Creé una buena clase para trabajar con la extensión php SSH2, tal vez te ayude; (y también hace transferencias seguras de archivos)

<?php /** * SSH2 * * @package Pork * @author SchizoDuckie * @version 1.0 * @access public */ class SSH2 { private $host; private $port; private $connection; private $timeout; private $debugMode; private $debugPointer; public $connected; public $error; /** * SSH2::__construct() * * @param mixed $host * @param integer $port * @param integer $timeout * @return */ function __construct($host, $port=22, $timeout=10) { $this->host = $host; $this->port = $port; $this->timeout = 10; $this->error = ''not connected''; $this->connection = false; $this->debugMode = Settings::Load()->->get(''Debug'', ''Debugmode''); $this->debugPointer = ($this->debugMode) ? fopen(''./logs/''.date(''Y-m-d--H-i-s'').''.log'', ''w+'') : false; $this->connected = false; } /** * SSH2::connect() * * @param mixed $username * @param mixed $password * @return */ function connect($username, $password) { $this->connection = ssh2_connect($this->host, $this->port); if (!$this->connection) return $this->error("Could not connect to {$this->host}:{$this->port}"); $this->debug("Connected to {$this->host}:{$this->port}"); $authenticated = ssh2_auth_password($this->connection, $username, $password); if(!$authenticated) return $this->error("Could not authenticate: {$username}, check your password"); $this->debug("Authenticated successfully as {$username}"); $this->connected = true; return true; } /** * SSH2::exec() * * @param mixed $command shell command to execute * @param bool $onAvailableFunction a function to handle any available data. * @param bool $blocking blocking or non-blocking mode. This ''hangs'' php execution until the command has completed if you set it to true. If you just want to start an import and go on, use this icm onAvailableFunction and false * @return */ function exec($command, $onAvailableFunction=false, $blocking=true) { $output = ''''; $stream = ssh2_exec($this->connection, $command); $this->debug("Exec: {$command}"); if($onAvailableFunction !== false) { $lastReceived = time(); $timeout =false; while (!feof($stream) && !$timeout) { $input = fgets($stream, 1024); if(strlen($input) >0) { call_user_func($onAvailableFunction, $input); $this->debug($input); $lastReceived = time(); } else { if(time() - $lastReceived >= $this->timeout) { $timeout = true; $this->error(''Connection timed out''); return($this->error); } } } } if($blocking === true && $onAvailableFunction === false) { stream_set_blocking($stream, true); $output = stream_get_contents($stream); $this->debug($output); } fclose($stream); return($output); } /** * SSH2::createDirectory() * * Creates a directory via sftp * * @param string $dirname * @return boolean success * */ function createDirectory($dirname) { $ftpconnection = ssh2_sftp ($this->connection); $dircreated = ssh2_sftp_mkdir($ftpconnection, $dirname, true); if(!$dircreated) { $this->debug("Directory not created: ".$dirname); } return $dircreated; } public function listFiles($dirname) { $input = $this->exec(escapeshellcmd("ls {$dirname}")); return(explode("/n", trim($input))); } public function sendFile($filename, $remotename) { $this->debug("sending {$filename} to {$remotename} "); if(file_exists($filename) && is_readable($filename)) { $result = ssh2_scp_send($this->connection, $filename, $remotename, 0664); } else { $this->debug("Unable to read file : ".$filename); return false; } if(!$result) $this->debug("Failure uploading {$filename} to {$remotename}"); return $result; } public function getFile($remotename, $localfile) { $this->debug("grabbing {$remotename} to {$localfile}"); $result = ssh2_scp_recv($this->connection, $remotename, $localfile); if(!$result) $this->debug("Failure downloading {$remotename} to {$localfile}"); return $result; } /** * SSH2::debug() * * @param mixed $message * @return */ function debug($message) { if($this->debugMode) { fwrite($this->debugPointer, date(''Y-m-d H:i:s'')." : ".$message."/n"); } } /** * SSH2::error() * * @param mixed $errorMsg * @return */ function error($errorMsg) { $this->error = $errorMsg; $this->debug($errorMsg); return false; } /** * SSH2::__destruct() * * @return */ function __destruct() { if($this->connection){ $this->connection = null; } if($this->debugMode && $this->debugPointer) { fclose($this->debugPointer); } } }

Ejemplo de uso:

$settings = Settings::Load()->Get("SecureServer"); $ssh = new SSH2($settings[''host'']); if( $ssh->connect($settings[''username''], $settings[''password''])) { echo $ssh->exec("ls -la ".$settings[''path''], false, true); flush(); }


Dependiendo de su entorno (es decir, no en Windows), puede usar la biblioteca ncurses (específicamente, la función ncurses_noecho() para detener el eco del teclado y ncurses_getch() para leer la entrada) para obtener la contraseña sin mostrarla en la pantalla.


Encontrado en el 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; } }


Esta es la solución más fácil para todas las plataformas:

function prompt($message = ''prompt: '', $hidden = false) { if (PHP_SAPI !== ''cli'') { return false; } echo $message; $ret = $hidden ? exec( PHP_OS === ''WINNT'' || PHP_OS === ''WIN32'' ? __DIR__ . ''/prompt_win.bat'' : ''read -s PW; echo $PW'' ) : rtrim(fgets(STDIN), PHP_EOL) ; if ($hidden) { echo PHP_EOL; } return $ret; }

Luego crea prompt_win.bat en el mismo directorio:

SetLocal DisableDelayedExpansion Set "Line=" For /F %%# In (''"Prompt;$H & For %%# in (1) Do Rem"'') Do ( Set "BS=%%#" ) :loop_start Set "Key=" For /F "delims=" %%# In (''Xcopy /L /W "%~f0" "%~f0" 2^>Nul'') Do ( If Not Defined Key ( Set "Key=%%#" ) ) Set "Key=%Key:~-1%" SetLocal EnableDelayedExpansion If Not Defined Key ( Goto :loop_end ) If %BS%==^%Key% ( Set "Key=" If Defined Line ( Set "Line=!Line:~0,-1!" ) ) If Not Defined Line ( EndLocal Set "Line=%Key%" ) Else ( For /F "delims=" %%# In ("!Line!") Do ( EndLocal Set "Line=%%#%Key%" ) ) Goto :loop_start :loop_end Echo;!Line!


He JMW la solución de 3 líneas de JMW para que pueda cortarla y pegarla en su código PHP existente.

function getPassword() { $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]; return $pwd; }

Para usarlo:

$usersPassword=getPassword();

Estoy en Powershell V5.0 pero la ruta del directorio aún se muestra como v1.0 por lo que la cadena entrecomillada en la llamada de shell_exec debería estar bien.


La respuesta aceptada no es lo suficientemente buena. En primer lugar, la solución de Windows no funciona en Windows 7 y superior. La solución para otros sistemas operativos depende de Bash y bash built-in ''read''. Sin embargo, hay sistemas que no usan Bash (por ejemplo, OpenBSD) y donde obviamente esto no funcionará.

En este blog he discutido la solución que funciona en casi cualquier sistema operativo basado en Unix y Windows de 95 a 8. La solución de Windows usa un programa externo escrito en C en la API superior de Win32. La solución para otros sistemas operativos utiliza el comando externo ''stty''. Aún no he visto un sistema basado en Unix que no tenga ''stty''


Puede usar mi archivo github.com/Seldaek/hidden-input para obtener una entrada real oculta sin filtrar la información en ningún lugar de la pantalla.

<?php echo ''Enter password: ''; $password = exec(''hiddeninput.exe''); echo PHP_EOL; echo ''Password was: '' . $password . PHP_EOL;

Si elimina el último eco, la contraseña nunca debería aparecer, pero puede usarla para la validación de forma obvia.


Supongo que no hay una forma sencilla de hacerlo (en realidad no puedo pensar de ninguna manera) sin usar st-echo. Si intenta ejecutarlo en Windows, podría crear un script por lotes que proporcionaría la información tipeada sin eco a su script php.

@echo off cls SET /P uname=Enter Username: echo hP1X500P[PZBBBfh#b##fXf-V@`$fPf]f3/f1/5++u5>in.com set /p password=Enter password :<nul for /f “tokens=*” %%i in (’in.com’) do set password=%%i del in.com echo. c:/php/php.exe d:/php/test.php %uname% “%password%” Pause

ejemplo tomado de http://www.indiangnu.org/2008/php-hide-user-input-using-batch-script-windows/


Teóricamente puedes hacerlo usando stream_set_blocking (), pero parece que hay algunos errores de PHP manejando STDIN.

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

Pruebe usted mismo:

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'');


Funciona en todos los sistemas de Windows, que tiene soporte de powershell. (fuente de: 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";