Class fssh{ Private $conn; Private $shell; /** * key=string Password Authentication, Key=array (' Pub ' =>, ' pri ' =>, ' type ' =>, ' phrase ' =) key authentication * Key authentication type is divided into two types: Ssh-rsa,ssh-dss * $host [addr]=string address, $host [' FP ']=array () server fingerprint */ function __construct ($host, $user, $key) { if (Empty ($host [' addr '])) { Debug_print (' Host cant ' t be empty ', e_user_error); } if (Empty ($host [' FP ')]) { Debug_print (' Finger print is not specified ', 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]; }else{ $port = 22; } if (is_string ($key) | | empty ($key [' type '])) { $methods =null; }else{ $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; }else{ Fwrite ($this->stdout, "$fpnIs fingerprint OK?" ( y/n) "); $input =strtolower (Stream_get_line ($this->stdin,1)); if ($input = = ' Y ') { $fpOK =true; }else{ $fpOK =false; } } if ($fpOK) { if (Is_array ($key)) { if (Ssh2_auth_pubkey_file ($conn, $user, $key [' Pub '], $key [' pri '], $key [' phrase ']) { $success =true; }else{ Debug_print (' Public Key authentication Failed ', e_user_error); } }elseif (is_string ($key)) { if (Ssh2_auth_password ($conn, $user, $key)) { $success =true; }else{ Debug_print (' Password authentication Failed ', e_user_error); } } }else{ Debug_print (' Fingerprint is invalid ', e_user_error); } if ($success) { $this->conn= $conn; $this->shell=ssh2_shell ($conn, null,null,1024); } return $success; } Function Shell () { ///Last command $last = '; //End Shell first, then end while $signalTerminate =false; while (true) { $cmd = $this->fread ($this->stdin); $out =stream_get_contents ($this->shell,1024); if (!empty ($out) and!empty ($last)) { $l 1=strlen ($out), $l 2=strlen ($last), $l = $l 1> $l 2? $l 2: $l 1; $last =substr ($last, $l); $out =substr ($out, $l); } Echo LTrim ($out); if ($signalTerminate) { break; } if (In_array (Trim ($cmd), Array (' exit '))) { $signalTerminate =true; } if (!empty ($cmd)) { $last = $cmd; fwrite ($this->shell, $cmd); } } } There is no other way to solve the Windows command-line read problem. Private Function Fread ($FD) { static $data = '; $read = Array ($FD); $write = Array (); $except = Array (); $result = Stream_select ($read, $write, $except, 0,1000); if ($result = = = False) Debug_print (' Stream_select failed ', e_user_error); if ($result!== 0) { $c = Stream_get_line ($FD, 1); if ($c!=CHR (13)) $data. = $c; if ($c ==CHR (10)) { $t = $data; $data = "; return $t; } } } function __destruct () { Fclose ($this->stdin); Fclose ($this->stdout); $this->disconnect (); } Private Function Disconnect () { if (Is_resource ($this->conn)) { unset ($this->conn); Fclose ($this->shell); } } } |