From 7a4f0fac692bdd42904891e1658801d969d04532 Mon Sep 17 00:00:00 2001 From: Benjamin Renard Date: Fri, 13 Oct 2023 19:04:22 +0200 Subject: [PATCH] LSaddon::ftp: Remove PEAR Net_FTP dependency --- .phpstan/compat.php | 9 + .phpstan/config.neon | 3 + .phpstan/init.php | 1 - INSTALL | 4 +- debian/control | 4 +- doc/src/install/requirements.md | 9 +- src/conf/LSaddons/config.LSaddons.ftp.php | 30 ---- src/includes/addons/LSaddons.ftp.php | 202 ++++++++++++---------- 8 files changed, 134 insertions(+), 128 deletions(-) create mode 100644 .phpstan/compat.php delete mode 100644 src/conf/LSaddons/config.LSaddons.ftp.php diff --git a/.phpstan/compat.php b/.phpstan/compat.php new file mode 100644 index 00000000..03b8eb98 --- /dev/null +++ b/.phpstan/compat.php @@ -0,0 +1,9 @@ + Package: ldapsaisie Architecture: all -Depends: apache2 | httpd, php-ldap | php5-ldap, php-fpm | libapache2-mod-php5 | libapache2-mod-php | php5-cli | php-cli, smarty | smarty3, php-net-ldap2, php-net-ftp, php-mail, php-mail-mime, php-console-table -Recommends: php-mbstring, php-phpseclib, php-unidecode, php-zxcvbn +Depends: apache2 | httpd, php-ldap | php5-ldap, php-fpm | libapache2-mod-php5 | libapache2-mod-php | php5-cli | php-cli, smarty | smarty3, php-net-ldap2, php-console-table +Recommends: php-mbstring, php-phpseclib, php-unidecode, php-zxcvbn, php-ftp, php-mail, php-mail-mime Description: web based interface for managing LDAP servers content LdapSaisie is a Web application developed to manage LDAP directory. It has been written in PHP / JavaScript and is published under the diff --git a/doc/src/install/requirements.md b/doc/src/install/requirements.md index 00b9178c..107fe979 100644 --- a/doc/src/install/requirements.md +++ b/doc/src/install/requirements.md @@ -36,12 +36,13 @@ [PEAR_Mail_Mime](https://pear.php.net/package/Mail_Mime) (nécessaire pour l'envoi de courriels, paquets `php-mail` et `php-mail-mime` dans Debian) -- La librairie [Net_FTP](https://pear.php.net/package/Net_FTP) (nécessaire pour le fonctionnement du - [LSaddon](../conf/index.md#configuration-des-lsaddons) FTP, paquet `php-console-table` dans Debian) +- L'[extension PHP `ftp`](https://www.php.net/manual/fr/intro.ftp.php) (nécessaire pour le + fonctionnement du [LSaddon](../conf/index.md#configuration-des-lsaddons) FTP, paquet `php-ftp` + dans Debian) - La librairie [PhpSecLib](https://github.com/phpseclib/phpseclib) (nécessaire pour le - fonctionnement du [LSaddon](../conf/index.md#configuration-des-lsaddons) SSH, paquet `php-console-table` - dans Debian) + fonctionnement du [LSaddon](../conf/index.md#configuration-des-lsaddons) SSH, paquet + `php-phpseclib` dans Debian) !!! warning diff --git a/src/conf/LSaddons/config.LSaddons.ftp.php b/src/conf/LSaddons/config.LSaddons.ftp.php deleted file mode 100644 index d32bf4ba..00000000 --- a/src/conf/LSaddons/config.LSaddons.ftp.php +++ /dev/null @@ -1,30 +0,0 @@ - -* -* @param string $host FTP server FQDN or IP address -* @param string $port The TCP port of the FTP server -* @param string $user The username -* @param string $pwd The password -* -* @return Net_FTP|false Net_FTP object in case of success, false otherwise -*/ -function connectToFTP($host, $port, $user, $pwd) { - $cnx = new Net_FTP(); - $do = $cnx -> connect($host, $port); - if (!$do instanceof PEAR_Error){ - $do = $cnx -> login($user, $pwd); - if (!$do instanceof PEAR_Error) { - return $cnx; - } - else { - LSerror :: addErrorCode('FTP_01', "2"); - LSerror :: addErrorCode('FTP_00', $do -> getMessage()); - return false; - } - } - else { - LSerror :: addErrorCode('FTP_01', "1"); - LSerror :: addErrorCode('FTP_00', $do -> getMessage()); - return false; - } + * Log last FTP error + * @return void + */ +function _logLastFtpError() { + $error = error_get_last(); + if ($error) LSerror :: addErrorCode('FTP_00', $error['message']); } /** -* Creation d'un ou plusieurs dossiers via FTP -* -* @author Benjamin Renard -* -* @param string $host Le nom ou l'IP du serveur FTP -* @param string $port Le port de connexion au serveur ftp -* @param string $user Le nom d'utilidateur de connexion -* @param string $pwd Le mot de passe de connexion -* @param array $dirs ou string Le(s) dossier(s) à ajouter -* -* @return bool True ou false si il y a un problème durant la création du/des dossier(s) + * Connect to FTP server + * + * @author Benjamin Renard + * + * @param string $host FTP server FQDN or IP address + * @param string $port The TCP port of the FTP server + * @param string $user The username + * @param string $pwd The password + * + * @return FTP\Connection|resource|false FTP\Connection (or resource with PHP <= 8.1.0) in case of + * success, false otherwise + */ +function connectToFTP($host, $port, $user, $pwd) { + $cnx = @ftp_connect($host, $port); + if ($cnx === false) { + _logLastFtpError(); + LSerror :: addErrorCode('FTP_01', "1"); + return false; + } + if (@ftp_login($cnx, $user, $pwd)) + return $cnx; + _logLastFtpError(); + LSerror :: addErrorCode('FTP_01', "2"); + return false; +} +/** * Create one or more directories throught FTP * * @author Benjamin Renard @@ -135,7 +120,7 @@ function connectToFTP($host, $port, $user, $pwd) { * @param string $pwd The password * @param array|string $dirs The directory/ies to add * @param int $chmod The directory/ies mode as an octal number (do not forget leading zero, - * example: 0755 or 02755, default : default umask on the SSH server) + * example: 0755 or 02755, default : default umask on the SSH server) * * @return boolean */ @@ -143,20 +128,68 @@ function createDirsByFTP($host, $port, $user, $pwd, $dirs, $chmod=NULL) { $cnx = connectToFTP($host, $port, $user, $pwd); if (!$cnx) return false; foreach(ensureIsArray($dirs) as $dir) { - $do = $cnx -> mkdir($dir, true); - if ($do instanceof PEAR_Error) { + if (@ftp_mkdir($cnx, $dir) === false) { + _logLastFtpError(); LSerror :: addErrorCode('FTP_02', $dir); - LSerror :: addErrorCode('FTP_00', $do -> getMessage()); return false; } - if ($chmod) { - $do = $cnx -> chmod($dir, $chmod); - if ($do instanceof PEAR_Error) { - LSerror :: addErrorCode('FTP_04', $dir); - LSerror :: addErrorCode('FTP_00', $do -> getMessage()); + if ($chmod && !@ftp_chmod($cnx, $chmod, $dir)) { + _logLastFtpError(); + LSerror :: addErrorCode('FTP_06', $dir); + } + } + return true; +} + +/** + * Internal function call recursively to remove a directory and its content + * @param FTP\Connection|resource $cnx The FTP\Connection object (or resource with PHP < 8.1.0) + * @param string $dir The directory path to remove + * @return boolean + */ +function _removeDirByFTP(&$cnx, $dir) { + if ($dir[strlen($dir)-1] == '/') + $dir = substr($dir, 0, strlen($dir)-1); + $items = @ftp_nlist($cnx, $dir); + LSlog :: get_logger('LSaddon_ftp') -> trace( + "_removeDirByFTP($dir): directory content: ".varDump($items)); + if (!is_array($items)) { + _logLastFtpError(); + LSerror :: addErrorCode('FTP_03', $dir); + return false; + } + + foreach($items as $item) { + if (@ftp_chdir($cnx, $item)) { + LSlog :: get_logger('LSaddon_ftp') -> trace( + "_removeDirByFTP($dir): item '$item' is a directory, delete it recursively"); + if (!_removeDirByFTP($cnx, $item)) + return false; + } + else { + LSlog :: get_logger('LSaddon_ftp') -> trace( + "_removeDirByFTP($dir): item '$item' is a file, delete it"); + if (!@ftp_delete($cnx, $item)) { + _logLastFtpError(); + LSerror :: addErrorCode('FTP_05', $item); + return false; + } + else { + LSlog :: get_logger('LSaddon_ftp') -> trace( + "_removeDirByFTP($dir): file '$item' removed"); } } } + + if (@!ftp_rmdir($cnx, $dir)) { + _logLastFtpError(); + LSerror :: addErrorCode('FTP_04', $dir); + return false; + } + else { + LSlog :: get_logger('LSaddon_ftp') -> trace( + "_removeDirByFTP($dir): directory '$dir' removed"); + } return true; } @@ -181,17 +214,9 @@ function createDirsByFTP($host, $port, $user, $pwd, $dirs, $chmod=NULL) { function removeDirsByFTP($host, $port, $user, $pwd, $dirs) { $cnx = connectToFTP($host, $port, $user, $pwd); if (!$cnx) return false; - foreach(ensureIsArray($dirs) as $dir) { - if ($dir[strlen($dir)-1] != '/') { - $dir .= '/'; - } - $do = $cnx -> rm($dir,true); - if ($do instanceof PEAR_Error) { - LSerror :: addErrorCode('FTP_03', $dir); - LSerror :: addErrorCode('FTP_00', $do -> getMessage()); + foreach(ensureIsArray($dirs) as $dir) + if (!_removeDirByFTP($cnx, $dir)) return false; - } - } return true; } @@ -212,10 +237,9 @@ function removeDirsByFTP($host, $port, $user, $pwd, $dirs) { function renameDirByFTP($host, $port, $user, $pwd, $old, $new) { $cnx = connectToFTP($host, $port, $user, $pwd); if (!$cnx) return false; - $do = $cnx -> rename($old, $new); - if ($do instanceof PEAR_Error) { - LSerror :: addErrorCode('FTP_05', array('old' => $old, 'new' => $new)); - LSerror :: addErrorCode('FTP_00', $do -> getMessage()); + if (!@ftp_rename($cnx, $old, $new)) { + _logLastFtpError(); + LSerror :: addErrorCode('FTP_07', array('old' => $old, 'new' => $new)); return false; } return true;