PHP Komut Satırı Şifre İstemi

8 Cevap php

Benim web uygulaması yardım etmek için bir komut satırı aracı yazıyorum. Bu servise bağlanmak için bir şifre gerekiyor. Ben bir komut satırı argümanı olarak geçmek zorunda kalmamak komut bir parola istemi göstermek istiyorum.

Bu yeterince kolay, ama ben daktilo gibi ekrana şifreyi echo istiyorum. Bu PHP ile nasıl yapabilirim?

Saf PHP bunu yapmak için bonus puan (hayır system('stty')) ve karakterler yerine *.

EDIT:

Komut sistemi (linux veya mac) gibi bir unix üzerinde çalışacaktır. PHP ile yazılmış olup, büyük olasılıkla böyle kalacak.

Ayrıca, kayıt için, bunu yapmanın stty yoludur:

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

Ben system() orada aramaları sahip değil tercih ediyorum.

8 Cevap

Bulunan 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;
  }
}

Senin çevreye (yani, değil Windows) bağlı olarak almak için, (klavye yankı durdurmak için, özellikle ncurses_noecho() fonksiyonu ve ncurses_getch() girişi okumak için) ncurses kütüphane kullanabilirsiniz ekranda görüntülemeden şifre.

I guess that there is no simple way of doing it (actually I can't think of any way) without using stty -echo. If you intent running it on windows, you could create a batch script that would provide the unechoed typed info to your php script.

@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

Örnek http://www.indiangnu.org/2008/php-hide-user-input-using-batch-script-windows/ alınan

Neden bir SSH bağlantısı kullanmak değil mi? Soyut komutları uzak, giriş / çıkış yönlendirme ve tam denetime sahip olabilir.

Sen karşılaşılmasına kadar az haklara sahip saf, temiz kabuğu birisi sağlamak ve kabuk açmak için) (şifre sadece SSH2 :: Connect ile birlikte POST'ed sağlayabilirsiniz.

I created a nice class to work with the php SSH2 extension, maybe it helps you; (and it also does secure file transfers)

<?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);
		}
	}		


}

Kullanımı örnek:

$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();	
}

Kabul cevabı yeterince iyi değil. Öncelikle, Windows çözümü Windows 7 ve üstü çalışmıyor. Diğer işletim için çözüm Bash ve bash yerleşik 'okundu' bağlıdır. Ancak, Bash (örn. OpenBSD) kullanmak değildir ve bu tabii ki çalışmaz nerede sistemleri vardır.

95-8 hemen her Unix tabanlı işletim sistemi ile Windows üzerinde çalışır bu blog ben ele aldık çözeltide., Windows solüsyon üst Win32 API üzerine yazılmış C dış programını kullanır. Diğer işletim için çözüm dış komut 'stty' kullanır. Ben 'stty' yok Unix tabanlı bir sistem henüz görmedik

Ekranda herhangi bir yere bilgi sızdırdığı olmadan gerçek gizli giriş almak benim hiddeninput.exe dosyasını kullanabilirsiniz.

<?php

echo 'Enter password: ';
$password = exec('hiddeninput.exe');
echo PHP_EOL;

echo 'Password was: ' . $password . PHP_EOL;

Eğer son yankı kaldırırsanız, şifre göstermek asla, ama obvoiusly doğrulama için kullanabilirsiniz.

Teorik Eğer stream_set_blocking () kullanarak bunu, ama STDIN yöneten bazı PHP hata var gibi görünüyor olabilir.

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

Kendiniz deneyin:

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