クラス FSSH{
プライベート $conn;
プライベート $shell;
/**
* key=文字列パスワード認証、key=array('pub'=>,'pri'=>,'type'=>,'phrase'=>) キー認証
※鍵認証にはssh-rsa、ssh-dssの2種類があります
* $host[addr]=文字列アドレス,$host['fp']=array() サーバーフィンガープリント
*/
関数 __construct($host,$user,$key){
if(empty($host['addr'])){
debug_print('ホストを空にすることはできません',E_USER_ERROR);
}
if(empty($host['fp'])){
debug_print('指紋認証が指定されていません',E_USER_ERROR);
}
$this->stdin=fopen('php://stdin','r');
$this->stdout=fopen('php://stdout','w');
if(false!==strpos($host['addr'],':')){
$temp=explode(':',$host['addr']);
$host['addr']=$temp[0];
$port=$temp[1];
}その他{
$ポート=22;
}
if(is_string($key) || empty($key['type'])){
$methods=null;
}その他{
$methods=array('hostkey'=>$key['type']);
}
$conn=ssh2_connect($host['addr'],$port,$methods,array('disconnect'=>array($this,'disconnect')));
$fp=ssh2_fingerprint($conn,SSH2_FINGERPRINT_MD5);
$success=false;
$fpOK=false;
if(in_array($fp,$host['fp'])){
$fpOK=true;
}その他{
fwrite($this->stdout,"$fpn指紋はOKですか?(y/n)");
$input=strto lower(stream_get_line($this->stdin,1));
if($input=='y'){
$fpOK=true;
}その他{
$fpOK=false;
}
}
if($fpOK){
if(is_array($key)){
if (ssh2_auth_pubkey_file($conn,$user,$key['pub'],$key['pri'],$key['phrase'])){
$success=true;
}その他{
debug_print('公開鍵認証に失敗しました',E_USER_ERROR);
}
}elseif(is_string($key)){
if(ssh2_auth_password($conn,$user,$key)){
$success=true;
}その他{
debug_print('パスワード認証に失敗しました',E_USER_ERROR);
}
}
}その他{
debug_print('指紋が無効です',E_USER_ERROR);
}
if($成功){
$this->conn=$conn;
$this->shell=ssh2_shell($conn,null,null,1024);
}
$success を返します;
}
関数シェル(){
//最後の一条コマンド
$last='';
//先结束シェル、再结束while
$signalTerminate=false;
while(true){
$cmd=$this->fread($this->標準入力);
$out=stream_get_contents($this->shell,1024);
if(!empty($out) と !empty($last)){
$l1=strlen($out);
$l2=strlen($last);
$l=$l1>$l2?$l2:$l1;
$last=substr($last,$l);
$out=substr($out,$l);
}
echo ltrim($out);
if($signalTerminate){
休憩;
}
if(in_array(trim($cmd),array('exit'))){
$signalTerminate=true;
}
if(!empty($cmd)){
$last=$cmd;
fwrite($this->shell,$cmd);
}
}
}
//Windows コマンドラインの読み取りの問題を解決する他の方法はありません。
プライベート関数 fread($fd){
静的 $data='';
$read = 配列($fd);
$write = array();
$excel = array();
$result = stream_select($read,$write,$excel,0,1000);
if($result === false)
debug_print('stream_select に失敗しました',E_USER_ERROR);
if($result !== 0){
$c= stream_get_line($fd,1);
if($c!=chr(13))
$data.=$c;
if($c==chr(10)){
$t=$データ;
$data='';
$t; を返します
}
}
}
関数__destruct(){
fclose($this->stdin);
fclose($this->stdout);
$this->disconnect();
}
プライベート関数切断(){
if(is_resource($this->conn)){
設定を解除($this->conn);
fclose($this->shell);
}
}
}
|