Viewing file: class.sshAccessDriver.php (24.77 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php /** * @package info.ajaxplorer.plugins * * Copyright 2007-2009 Cyril Russo * This file is part of AjaXplorer. * The latest code can be found at http://www.ajaxplorer.info/ * * This program is published under the LGPL Gnu Lesser General Public License. * You should have received a copy of the license along with AjaXplorer. * * The main conditions are as follow : * You must conspicuously and appropriately publish on each copy distributed * an appropriate copyright notice and disclaimer of warranty and keep intact * all the notices that refer to this License and to the absence of any warranty; * and give any other recipients of the Program a copy of the GNU Lesser General * Public License along with the Program. * * If you modify your copy or copies of the library or any portion of it, you may * distribute the resulting library provided you do so under the GNU Lesser * General Public License. However, programs that link to the library may be * licensed under terms of your choice, so long as the library itself can be changed. * Any translation of the GNU Lesser General Public License must be accompanied by the * GNU Lesser General Public License. * * If you copy or distribute the program, you must accompany it with the complete * corresponding machine-readable source code or with a written offer, valid for at * least three years, to furnish the complete corresponding machine-readable source code. * * Any of the above conditions can be waived if you get permission from the copyright holder. * AjaXplorer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * Description : Access a remote server via SSH protocol. */ require_once("class.SSHOperations.php");
class sshAccessDriver extends AbstractAccessDriver { /** The SSH operation object * @var SSHOperation */ var $SSHOperation;
/** The remote path (used to make absolute path) * @var cwd */ var $serverCwd; /** The remote charset (if known) * @var charset */ var $charset; function sshAccessDriver($driverName, $filePath, $repository, $optOption = NULL){ $repositoryPath = $repository->getOption("PATH"); $accountLimit = strpos($repositoryPath, "@"); if ($accountLimit !== false) { $account = substr($repositoryPath, 0, $accountLimit); $repositoryPath = substr($repositoryPath, $accountLimit+1); $repository->setOption("PATH", $repositoryPath); } // Set the password from a per user specific config $account = $optOption ? $optOption["account"] : $this->getUserName($repository); $password = $optOption ? $optOption["password"] : $this->getPassword($repository); $this->SSHOperation = new SSHOperations($repositoryPath, $account, $password); parent::AbstractAccessDriver($driverName, $filePath, $repository); }
function getUserName($repository){ $logUser = AuthService::getLoggedUser(); $wallet = $logUser->getPref("AJXP_WALLET"); return is_array($wallet) ? $wallet[$repository->getUniqueId()]["remote_username"] : ""; }
function getPassword($repository){ $logUser = AuthService::getLoggedUser(); $wallet = $logUser->getPref("AJXP_WALLET"); return is_array($wallet) ? $logUser->decodeUserPassword($wallet[$repository->getUniqueId()]["remote_password"]) : ""; } function initRepository(){ $path = $this->repository->getOption("PATH"); // We cache this in the session object so it's only done once global $_SESSION; if (!isset($_SESSION["cwd"]) || !strlen($_SESSION["cwd"])) { $param = $this->SSHOperation->checkConnection(); if (count($param)==0) { return new AJXP_Exception("Cannot connect to remote server. Please check repository configuration and install.txt!"); } $_SESSION["cwd"] = trim($param[0]); $fullCharset = explode('.', trim($param[1])); if ($_SESSION["AJXP_CHARSET"] == "") $_SESSION["AJXP_CHARSET"] = array_pop($fullCharset); } // If it's set, then cache the result to avoid multiple connection on the remote server $this->serverCwd = rtrim(trim($_SESSION["cwd"]), '/').'/'; $this->charset = trim($_SESSION["AJXP_CHARSET"]); } function switchAction($action, $httpVars, $fileVars){ if(!isSet($this->actions[$action])) return; $xmlBuffer = ""; foreach($httpVars as $getName=>$getValue){ $$getName = Utils::securePath(SystemTextEncoding::magicDequote($getValue)); } $selection = new UserSelection(); $selection->initFromHttpVars($httpVars); if(isSet($dir) && $action != "upload") { $safeDir = $dir; $dir = SystemTextEncoding::fromUTF8($dir); } if(isSet($dest)) $dest = SystemTextEncoding::fromUTF8($dest); $mess = ConfService::getMessages(); $recycleBinOption = $this->repository->getOption("RECYCLE_BIN"); // FILTER ACTION FOR DELETE if($recycleBinOption!="" && $action == "delete" && $dir != "/".$recycleBinOption) { $action = "move"; $dest = "/".$recycleBinOption; $dest_node = "AJAXPLORER_RECYCLE_NODE"; } // FILTER ACTION FOR RESTORE if($recycleBinOption!="" && $action == "restore" && $dir == "/".$recycleBinOption) { $originalRep = RecycleBinManager::getFileOrigin($selection->getUniqueFile()); if($originalRep != "") { $action = "move"; $dest = $originalRep; } } switch($action) { //------------------------------------ // DOWNLOAD, IMAGE & MP3 PROXYS //------------------------------------ case "download"; AJXP_Logger::logAction("Download", array("files"=>$selection)); $zip = false; if($selection->isUnique()){ if(is_dir($this->getPath()."/".$selection->getUniqueFile())) { $zip = true; $dir .= "/".basename($selection->getUniqueFile()); } }else{ $zip = true; } if($zip){ // Make a temp zip and send it as download $this->downFile($this->makeName($selection->getFiles()), "force-download", "archive.zip"); }else{ $this->downFile($this->makeName($selection->getUniqueFile()), "force-download", $selection->getUniqueFile()); } exit(0); break; case "image_proxy": $this->downFile($this->makeName($file), "image", $file); exit(0); break; case "mp3_proxy": $this->downFile($this->makeName($file), "mp3", $file); exit(0); break; //------------------------------------ // ONLINE EDIT //------------------------------------ case "edit"; if(isset($save) && $save==1) { AJXP_Logger::logAction("Online Edition", array("file"=>SystemTextEncoding::fromUTF8($file))); $code=stripslashes($code); $code=str_replace("<","<",$code); $this->SSHOperation->setRemoteContent($this->makeName($file), $code); echo $mess[115]; } else { $this->sendFile($this->SSHOperation->getRemoteContent($this->makeName($file)), "plain", $file); } exit(0); break; //------------------------------------ // COPY / MOVE //------------------------------------ case "copy"; case "move"; if($selection->isEmpty()) { $errorMessage = $mess[113]; break; } $result = ""; if ($action == "move") $result = $this->SSHOperation->moveFile($this->makeName($selection->getFiles()), $this->makeName($dest)); else $result = $this->SSHOperation->copyFile($this->makeName($selection->getFiles()), $this->makeName($dest)); { $mess = ConfService::getMessages(); if(strlen($result)) { $errorMessage = $mess[114]; } else { foreach($selection->getFiles() as $files) $logMessage .= $mess[34]." ".SystemTextEncoding::toUTF8(basename($file))." ".$mess[$action=="move" ? 74:73]." ".SystemTextEncoding::toUTF8($dest)."\n"; AJXP_Logger::logAction(($action=="move"?"Move":"Copy"), array("files"=>$selection, "destination"=>$dest)); } } $reload_current_node = true; if(isSet($dest_node)) $reload_dest_node = $dest_node; $reload_file_list = true; break; //------------------------------------ // CHANGE FILE PERMISSION //------------------------------------ case "chmod";
$messtmp=""; $changedFiles = array(); $value = "0".decoct(octdec(ltrim($chmod_value, "0"))); // On error, the command will fail $result = $this->SSHOperation->chmodFile($this->makeName($selection->getFiles()), $chmod_value); { $mess = ConfService::getMessages(); if(strlen($result)) { $errorMessage = $mess[114]; } else { $logMessage="Successfully changed permission to ".$chmod_value." for ".count($selection->getFiles())." files or folders"; AJXP_Logger::logAction("Chmod", array("dir"=>$dir, "filesCount"=>count($selection->getFiles()))); $reload_file_list = $dir; } }
break; //------------------------------------ // SUPPRIMER / DELETE //------------------------------------ case "delete"; if($selection->isEmpty()) { $errorMessage = $mess[113]; break; } $logMessages = array(); $result = $this->SSHOperation->deleteFile($this->makeName($selection->getFiles())); if(strlen($result)) { $mess = ConfService::getMessages(); $errorMessage = $mess[120]; } else { $mess = ConfService::getMessages(); foreach($selection->getFiles() as $file) $logMessages[]="$mess[34] ".SystemTextEncoding::toUTF8($file)." $mess[44]."; $logMessage = join("\n", $logMessages); } AJXP_Logger::logAction("Delete", array("files"=>$selection)); $reload_current_node = true; $reload_file_list = true; break; //------------------------------------ // RENOMMER / RENAME //------------------------------------ case "rename"; $filename_new = $dir."/".$filename_new; $error = $this->SSHOperation->moveFile($this->makeName($file), $this->makeName($filename_new)); if($error != null) { $errorMessage = $error; break; } $logMessage= SystemTextEncoding::toUTF8($file)." $mess[41] ".SystemTextEncoding::toUTF8($filename_new); $reload_current_node = true; $reload_file_list = basename($filename_new); AJXP_Logger::logAction("Rename", array("original"=>$file, "new"=>$filename_new)); break; //------------------------------------ // CREER UN REPERTOIRE / CREATE DIR //------------------------------------ case "mkdir"; $messtmp=""; $dirname=Utils::processFileName($dirname); $error = $this->SSHOperation->createRemoteDirectory($this->makeName($dir."/".$dirname)); if(isSet($error)){ $errorMessage = $error; break; } $reload_file_list = $dirname; $messtmp.="$mess[38] ".SystemTextEncoding::toUTF8($dirname)." $mess[39] "; if($dir=="") {$messtmp.="/";} else {$messtmp.= SystemTextEncoding::toUTF8($dir);} $logMessage = $messtmp; $reload_current_node = true; AJXP_Logger::logAction("Create Dir", array("dir"=>$dir."/".$dirname)); break; //------------------------------------ // CREER UN FICHIER / CREATE FILE //------------------------------------ case "mkfile"; $messtmp=""; $filename=Utils::processFileName($filename); $error = $this->SSHOperation->setRemoteContent($this->makeName($dir."/".$filename), ""); if(isSet($error)){ $errorMessage = $error; break; } $messtmp.="$mess[34] ".SystemTextEncoding::toUTF8($filename)." $mess[39] "; if($dir=="") {$messtmp.="/";} else {$messtmp.=SystemTextEncoding::toUTF8($dir);} $logMessage = $messtmp; $reload_file_list = $filename; AJXP_Logger::logAction("Create File", array("file"=>$dir."/".$filename)); break; //------------------------------------ // UPLOAD //------------------------------------ case "upload": $fancyLoader = false; if(isSet($fileVars["Filedata"])){ $fancyLoader = true; if($dir!="") $dir = "/".base64_decode($dir); } if($dir!=""){$rep_source="/$dir";} else $rep_source = ""; $destination = $rep_source; $logMessage = ""; //$fancyLoader = false; foreach ($fileVars as $boxName => $boxData) { if($boxName != "Filedata" && substr($boxName, 0, 9) != "userfile_") continue; if($boxName == "Filedata") $fancyLoader = true; $err = Utils::parseFileDataErrors($boxData, $fancyLoader); if($err != null) { $errorMessage = $err; break; } $userfile_name = $boxData["name"]; $userfile_name=Utils::processFileName($userfile_name); if (!$this->SSHOperation->uploadFile($boxData["tmp_name"], $this->makeName($destination."/".$userfile_name))) { $errorMessage=($fancyLoader?"411 ":"")."$mess[33] ".$userfile_name; break; } $logMessage.="$mess[34] ".SystemTextEncoding::toUTF8($userfile_name)." $mess[35] $dir"; AJXP_Logger::logAction("Upload File", array("file"=>$dir."/".$userfile_name)); } if($fancyLoader) { if(isSet($errorMessage)){ header('HTTP/1.0 '.$errorMessage); die('Error '.$errorMessage); }else{ header('HTTP/1.0 200 OK'); die("200 OK"); } } else { print("<html><script language=\"javascript\">\n"); if(isSet($errorMessage)){ print("\n if(parent.ajaxplorer.actionBar.multi_selector)parent.ajaxplorer.actionBar.multi_selector.submitNext('".str_replace("'", "\'", $errorMessage)."');"); }else{ print("\n if(parent.ajaxplorer.actionBar.multi_selector)parent.ajaxplorer.actionBar.multi_selector.submitNext();"); } print("</script></html>"); } exit; break;
//------------------------------------ // Public URL //------------------------------------ case "public_url": $file = SystemTextEncoding::fromUTF8($file); $url = $this->makePubliclet($file, $password, $expiration); header("Content-type:text/plain"); echo $url; exit(1); break; //------------------------------------ // XML LISTING //------------------------------------ case "ls": if(!isSet($dir) || $dir == "/") $dir = ""; $searchMode = $fileListMode = $completeMode = false; if(isSet($mode)){ if($mode == "search") $searchMode = true; else if($mode == "file_list") $fileListMode = true; else if($mode == "complete") $completeMode = true; }
$nom_rep = $dir; AJXP_Exception::errorToXml($nom_rep); $result = $this->SSHOperation->listFilesIn($nom_rep); AJXP_XMLWriter::header(); foreach ($result as $file) { $attributes = ""; $fileName = SystemTextEncoding::toUTF8($file["name"]); $icon = Utils::mimetype($fileName, "image", $file["isDir"]==1); if ($searchMode) { if($file["isDir"] == 0) { $attributes = "is_file=\"true\" icon=\"".SystemTextEncoding::toUTF8($icon)."\""; } } else if ($fileListMode) { $atts = array(); $atts[] = "is_file=\"".(1 - $file["isDir"])."\""; $atts[] = "is_image=\"".Utils::is_image($fileName)."\""; $atts[] = "mimestring=\"".Utils::mimetype($fileName, "type", $file["isDir"]==1)."\""; $atts[] = "ajxp_modiftime=\"".$this->dateModif($file["time"])."\""; $atts[] = "filesize=\"".Utils::roundSize($file["size"])."\""; $atts[] = "bytesize=\"".$file["size"]."\""; $atts[] = "filename=\"".str_replace("&", "&", $dir."/".$fileName)."\""; $atts[] = "icon=\"".($file["isDir"]==1 ? "folder.png" : SystemTextEncoding::toUTF8($icon))."\""; $attributes = join(" ", $atts); } else if ($file["isDir"]==1) { $link = SERVER_ACCESS."?dir=".$dir."/".$fileName; $link = urlencode($link); $folderBaseName = str_replace("&", "&", $fileName); $folderFullName = "$dir/".$folderBaseName; $parentFolderName = $dir; if(!$completeMode){ $icon = CLIENT_RESOURCES_FOLDER."/images/foldericon.png"; $openicon = CLIENT_RESOURCES_FOLDER."/images/openfoldericon.png"; if(eregi("\.zip$",$file["name"])){ $icon = $openicon = CLIENT_RESOURCES_FOLDER."/images/crystal/actions/16/accessories-archiver.png"; } $attributes = "icon=\"$icon\" openicon=\"$openicon\" filename=\"".$folderFullName."\" src=\"$link\""; } } if (strlen($attributes) > 0) { print("<tree text=\"".str_replace("&", "&", SystemTextEncoding::toUTF8($this->SSHOperation->unescapeFileName($file["name"])))."\" $attributes>"); print("</tree>"); } } AJXP_XMLWriter::close(); exit(1); break; }
if(isset($logMessage) || isset($errorMessage)) { $xmlBuffer .= AJXP_XMLWriter::sendMessage((isSet($logMessage)?$logMessage:null), (isSet($errorMessage)?$errorMessage:null), false); } if(isset($requireAuth)) { $xmlBuffer .= AJXP_XMLWriter::requireAuth(false); } if(isset($reload_current_node) && $reload_current_node == "true") { $xmlBuffer .= AJXP_XMLWriter::reloadCurrentNode(false); } if(isset($reload_dest_node) && $reload_dest_node != "") { $xmlBuffer .= AJXP_XMLWriter::reloadNode($reload_dest_node, false); } if(isset($reload_file_list)) { $xmlBuffer .= AJXP_XMLWriter::reloadFileList($reload_file_list, false); } return $xmlBuffer; } function getPath(){ return $this->repository->getOption("PATH"); }
function makeName($param) { if (is_array($param)) { $retArray = array(); foreach($param as $item) { $retArray[] = $this->serverCwd.SystemTextEncoding::fromUTF8(trim($item, './')); } return $retArray; } else { $param = SystemTextEncoding::fromUTF8(trim($param, './')); return $this->serverCwd.$param; } } /** The publiclet URL making */ function makePubliclet($filePath, $password, $expire) { $data = array("DRIVER"=>"ssh", "OPTIONS"=>array('account'=>$this->getUserName($this->repository), 'password'=>$this->getPassword($this->repository)), "FILE_PATH"=>$filePath, "ACTION"=>"download", "EXPIRE_TIME"=>$expire ? (time() + $expire * 86400) : 0, "PASSWORD"=>$password); return $this->writePubliclet($data); }
function zipListing($zipPath, $localPath, &$filteredList){ require_once("server/classes/pclzip.lib.php"); $crtZip = new PclZip($this->getPath()."/".$zipPath); $liste = $crtZip->listContent(); $files = array(); if($localPath[strlen($localPath)-1] != "/") $localPath.="/"; foreach ($liste as $item){ $stored = $item["stored_filename"]; if($stored[0] != "/") $stored = "/".$stored; $pathPos = strpos($stored, $localPath); if($pathPos !== false){ $afterPath = substr($stored, $pathPos+strlen($localPath)); if($afterPath != "" && strpos($afterPath, "/")=== false || strpos($afterPath, "/") == strlen($afterPath)-1){ $item["filename"] = $zipPath.$localPath.$afterPath; if($item["folder"]){ $filteredList[] = $item; }else{ $files[] = $item; } } } } $filteredList = array_merge($filteredList, $files); return $crtZip; } function initName($dir) { $racine = $this->getPath(); $mess = ConfService::getMessages(); if(!isset($dir) || $dir=="" || $dir == "/") { $nom_rep=$racine; } else { $nom_rep="$racine/$dir"; } if(!file_exists($racine)) { return new AJXP_Exception(72); } if(!is_dir($nom_rep)) { return new AJXP_Exception(100); } return $nom_rep; } function sendFile($filePath, $headerType="plain", $fileName, $gzip=true) { $size = strlen($filePath); if($headerType == "plain") { header("Content-type:text/plain"); } else if($headerType == "image") { header("Content-Type: ".Utils::getImageMimeType(basename($fileName))."; name=\"".basename($fileName)."\""); header("Content-Length: ".$size); header('Cache-Control: public'); } else if($headerType == "mp3") { header("Content-Type: audio/mp3; name=\"".basename($fileName)."\""); header("Content-Length: ".$size); } else { header("Content-Type: application/force-download; name=\"".$fileName."\""); header("Content-Transfer-Encoding: binary"); if($gzip) header("Content-Encoding: gzip"); header("Content-Length: ".$size); header("Content-Disposition: attachment; filename=\"".$fileName."\""); header("Expires: 0"); header("Cache-Control: no-cache, must-revalidate"); header("Pragma: no-cache"); // For SSL websites there is a bug with IE see article KB 323308 // therefore we must reset the Cache-Control and Pragma Header if (ConfService::getConf("USE_HTTPS")==1 && preg_match('/ MSIE /',$_SERVER['HTTP_USER_AGENT'])) { header("Cache-Control:"); header("Pragma:"); } if($gzip){ print(gzencode($filePath, 9)); return ; } } print($filePath); }
function downFile($fileArray, $headerType="plain", $fileName) { if($headerType == "plain") { header("Content-type:text/plain"); } else if($headerType == "image") { header("Content-Type: ".Utils::getImageMimeType(basename($fileName))."; name=\"".basename($fileName)."\""); header('Cache-Control: public'); } else if($headerType == "mp3") { header("Content-Type: audio/mp3; name=\"".basename($fileName)."\""); } else { header("Content-Type: application/force-download; name=\"".$fileName."\""); header("Content-Transfer-Encoding: binary"); if($gzip) header("Content-Encoding: gzip"); header("Content-Disposition: attachment; filename=\"".$fileName."\""); header("Expires: 0"); header("Cache-Control: no-cache, must-revalidate"); header("Pragma: no-cache"); // For SSL websites there is a bug with IE see article KB 323308 // therefore we must reset the Cache-Control and Pragma Header if (ConfService::getConf("USE_HTTPS")==1 && preg_match('/ MSIE /',$_SERVER['HTTP_USER_AGENT'])) { header("Cache-Control:"); header("Pragma:"); } } $this->SSHOperation->downloadRemoteFile($fileArray); } function dateModif($time) { $tmp = mktime(substr($time, 11, 2), substr($time, 14, 2), 0, substr($time, 5, 2), substr($time, 8, 2), substr($time, 0, 4)); return $tmp;//date("d/m/Y H:i",$tmp); } /** * @return zipfile */ function makeZip ($src, $dest, $basedir) { set_time_limit(60); require_once(SERVER_RESOURCES_FOLDER."/pclzip.lib.php"); $filePaths = array(); $totalSize = 0; foreach ($src as $item){ $filePaths[] = $this->getPath().$item; } $archive = new PclZip($dest); $vList = $archive->create($filePaths, PCLZIP_OPT_REMOVE_PATH, $this->getPath().$basedir, PCLZIP_OPT_NO_COMPRESSION); if($vList == 0) return false; } /** * @param $selection UserSelection */ function convertSelectionToTmpFiles($tmpDir, $selection){ $zipPath = $selection->getZipPath(); $localDir = $selection->getZipLocalPath(); $files = $selection->getFiles(); foreach ($files as $key => $item){// Remove path $item = substr($item, strlen($zipPath)); if($item[0] == "/") $item = substr($item, 1); $files[$key] = $item; } require_once("server/classes/pclzip.lib.php"); $zip = new PclZip($this->getPath().$zipPath); $err = $zip->extract(PCLZIP_OPT_BY_NAME, $files, PCLZIP_OPT_PATH, $this->getPath()."/".$tmpDir); foreach ($files as $key => $item){// Remove path $files[$key] = $tmpDir."/".$item; } $selection->setFiles($files); } }
?>
|