Version: 1
Type: Class
Category: Networking
License: GNU General Public License
Description: Telnet script class. Written in french, but may be translatable :-). Tested, seems to work fine.
<? /* Fichier : scriptTelnet.inc (fichier d'include dclarant la classe ScriptTelnet) Role de la classe : Grer un script se droulant via une socket telnet Exemple d'utilisation, ne tenant pas compte des codes retour des methodes : $script = new ScriptTelnet; $script->setHote("unhote.quelquepart.fr"); $script->setPrompt(">"); $script->connecter(); $script->lireJusqua("ogin: "); $script->ecrire("Jojo")); $script->lireJusqua("word: "); $script->ecrire("monpasse"); $script->attendrePrompt(); $script->ecrire("ps"); $script->attendrePrompt(); $script->deconnecter(); Auteur : Marc Ennaji */ define ("TELNET_ERREUR", 0); define ("TELNET_OK", 1); define ("TELNET_DEMANDE_CONFIRMATION", 2); define ("LIBELLE_CONFIRMATION", "[confirm]"); Class ScriptTelnet { var $socket = NULL; var $hote = ""; var $port = "23"; var $libelleErreur = ""; var $codeErreur = ""; var $prompt = "$ "; var $log = NULL; // handle de fichier var $repertoireLog= ""; var $nomFichierLog = ""; var $test; //------------------------------------------------------------------------ function connecter() { $this->socket = fsockopen($this->hote,$this->port); if (! $this->socket) { $this->libelleErreur = "Impossible d'etablir la connexion telnet : " . strerror ($this->socket) . "n"; return TELNET_ERREUR; } socket_set_timeout($this->socket,5,0); return TELNET_OK; } //------------------------------------------------------------------------ function lireJusqua($chaine) { $NULL = chr(0); $IAC = chr(255); $buf = ''; if (! $this->socket) { $this->libelleErreur = "socket telnet non ouverte"; return TELNET_ERREUR; } while (1) { $c = $this->getc(); if ($c === false) // plus de caracteres a lire sur la socket { if ($this->contientErreur($buf)) return TELNET_ERREUR; $this->libelleErreur = " La chaine attendue : '" . $chaine . "', n'a pas trouve dans les donnes reues : '" . $buf . "'" ; $this->logger($this->libelleErreur); return TELNET_ERREUR; } if ($c == $NULL || $c == " 21") continue; if ($c == $IAC) // Interpreted As Command { $c = $this->getc(); if ($c != $IAC) // car le 'vrai' caractere 255 est doubl pour le differencier du IAC if (! $this->negocierOptionTelnet($c)) return TELNET_ERREUR; else continue; } $buf .= $c; // indiquer l'utilisateur de la classe qu'il a une demande de confirmation if (substr($buf,strlen($buf)-strlen(LIBELLE_CONFIRMATION)) == LIBELLE_CONFIRMATION) { $this->logger($this->getDernieresLignes($buf)); return TELNET_DEMANDE_CONFIRMATION; } if ((substr($buf,strlen($buf)-strlen($chaine))) == $chaine) { // on a trouve la chaine attendue $this->logger($this->getDernieresLignes($buf)); if ($this->contientErreur($buf)) return TELNET_ERREUR; else return TELNET_OK; } } } //------------------------------------------------------------------------ function getc() { return fgetc($this->socket); } //------------------------------------------------------------------------ function negocierOptionTelnet($commande) { // on negocie des options minimales $IAC = chr(255); $DONT = chr(254); $DO = chr(253); $WONT = chr(252); $WILL = chr(251); if (($commande == $DO) || ($commande == $DONT)) { $opt = $this->getc(); //echo "wont ".ord($opt)."n"; fwrite($this->socket,$IAC.$WONT.$opt); } else if (($commande == $WILL) || ($commande == $WONT)) { $opt = fgetc($this->socket); //echo "dont ".ord($opt)."n"; fwrite($this->socket,$IAC.$DONT.$opt); } else { $this->libelleErreur = "Erreur : commande inconnue ".ord($commande)."n"; return false; } return true; } //------------------------------------------------------------------------ function ecrire($buffer, $valeurLoggee = "", $ajouterfinLigne = true) { if (! $this->socket) { $this->libelleErreur = "socket non ouverte"; return TELNET_ERREUR; } if ($ajouterfinLigne) $buffer .= "n"; if (fwrite($this->socket,$buffer) < 0) { $this->libelleErreur = "erreur d'ecriture sur la socket telnet"; return TELNET_ERREUR; } if ($valeurLoggee != "") // cacher les valeurs confidentielles dans la log (mots de passe...) $buffer = $valeurLoggee . "n"; if (! $ajouterfinLigne) // dans la log (mais pas sur la socket), rajouter tout de meme le caractere de fin de ligne $buffer .= "n"; $this->logger("> " .$buffer); return TELNET_OK; } //------------------------------------------------------------------------ function deconnecter() { if ($this->socket) { if (! fclose($this->socket)) { $this->libelleErreur = "erreur a la fermeture de la socket telnet"; return TELNET_ERREUR; } $this->socket = NULL; } $this->setLog(false,""); return TELNET_OK; } //------------------------------------------------------------------------ function contientErreur($buf) { $messagesErreurs[] = "nvalid"; // Invalid input, ... $messagesErreurs[] = "o specified"; // No specified atm, ... $messagesErreurs[] = "nknown"; // Unknown profile, ... $messagesErreurs[] = "o such file or directory"; // sauvegarde dans un repertoire inexistant $messagesErreurs[] = "llegal"; // illegal file name, ... foreach ($messagesErreurs as $erreur) { if (strpos ($buf, $erreur) === false) continue; // une erreur est dtecte $this->libelleErreur = "Un message d'erreur a t dtect dans la rponse de l'hte distant : " . "<BR><BR>" . $this->getDernieresLignes($buf,"<BR>") . "<BR>"; return true; } return false; } //------------------------------------------------------------------------ function attendrePrompt() { return $this->lireJusqua($this->prompt); } //------------------------------------------------------------------------ function setPrompt($s) { $this->prompt = $s; return TELNET_OK; } //------------------------------------------------------------------------ function setHote($s) { $this->hote = $s;} //------------------------------------------------------------------------ function setPort($s) { $this->port = $s;} //------------------------------------------------------------------------ function getDerniereErreur() { return $this->libelleErreur; } //------------------------------------------------------------------------ function setLog($activerLog, $traitement) { if ($this->log && $activerLog) return TELNET_OK; if ($activerLog) { $this->repertoireLog = "/log/" . date("m"); if (! file_exists($this->repertoireLog)) // repertoire mensuel inexistant ? { if (mkdir($this->repertoireLog, 0700) === false) { $this->libelleErreur = "Impossible de crer le repertoire de log " . $this->repertoireLog; return TELNET_ERREUR; } } global $HTTP_SERVER_VARS; $this->nomFichierLog = date("d") . "_" . date("H:i:s") . "_" . $traitement . "_" . $HTTP_SERVER_VARS["PHP_AUTH_USER"] . ".log"; $this->log = fopen($this->repertoireLog . "/" . $this->nomFichierLog,"a"); if (empty($this->log)) { $this->libelleErreur = "Impossible de crer le fichier de log " . $this->nomFichierLog; return TELNET_ERREUR; } $this->logger("----------------------------------------------rn"); $this->logger("Dbut de la log de l'utilisateur " . $HTTP_SERVER_VARS["PHP_AUTH_USER"] . ", adresse IP " . $HTTP_SERVER_VARS["REMOTE_ADDR"] . "rn"); $this->logger("Connexion telnet sur " . $this->hote . ", port " . $this->port . "rn"); $this->logger("Date : " . date("d-m-Y"). " " . date("H:i:s") . "rn"); $this->logger("Type de traitement effectu : " . $traitement . "rn"); $this->logger("----------------------------------------------rn"); return TELNET_OK; } else { if ($this->log) { $this->logger("----------------------------------------------rn"); $this->logger("Fin de la logrn"); fflush($this->log); if (! fclose($this->log)) { $this->libelleErreur = "erreur a la fermeture du fichier de log"; return TELNET_ERREUR; } $this->log = NULL; } return TELNET_OK; } } //------------------------------------------------------------------------ function logger($s) { if ($this->log) fwrite($this->log, $s); } //------------------------------------------------------------------------ function getDernieresLignes($s, $separateur="n") { // une reponse telnet contient (en principe) en premiere ligne l'echo de la commande utilisateur. // cette methode renvoie tout sauf la premiere ligne, afin de ne pas polluer les logs telnet $lignes = split("n",$s); $resultat = ""; $premiereLigne = true; while(list($key, $data) = each($lignes)) { if ($premiereLigne) $premiereLigne = false; else if ($data != "") $resultat .= $data . $separateur; } $resultat == substr($resultat,strlen($resultat)-1); // enlever le dernier caractere de fin de ligne return $resultat; } //------------------------------------------------------------------------ } // Fin de la classe ?>