<? Php Class FSSH { Private $ conn; Private $ shell; /** * Key = String password authentication, key = array ('pub' =>, 'pri '=>, 'type' =>, 'phrase' =>) key Authentication * Two key authentication types are available: ssh-rsa and 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 (){ // The Last Command $ Last = ''; // End shell first and then while $ SignalTerminate = false; While (true ){ $ Cmd = $ this-> fread ($ this-> stdin ); $ Out = stream_get_contents ($ this-& gt; shell, 1024 ); If (! Empty ($ out) and! 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 ){ 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 problem of reading windows command lines. Private function fread ($ fd ){ Static $ data = ''; $ Read = array ($ fd ); $ Write = array (); $ Response T = array (); $ Result = stream_select ($ read, $ write, $ hour T ); 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 ); } } } |