#33919 closed defect (bug) (fixed)
ssh2/sftp doesn't work in chrooted environments, FTP_BASE, FTP_CONTENT_DIR, FTP_PLUGIN_DIR not available
Reported by: | talatorre | Owned by: | dd32 |
---|---|---|---|
Milestone: | 4.4 | Priority: | normal |
Severity: | major | Version: | 4.3 |
Component: | Filesystem API | Keywords: | |
Focuses: | Cc: |
Description
This is a follow-up to #32345.
My server is setup with multiple domains in chrooted environments. Users can connect to the server using rsa keys. Without modification to the system files the SSH2 extension still does not work for me in this environment.
Tested on 4.3.1 here is extra debug from WP_Filesystem_Base::$verbose when attempting an update to a plugin:
Looking for /var/www/user/usersite.com/htdocs/wp-content in / The update process is starting. This process may take a while on some hosts, so please be patient. Looking for /var/www/user/usersite.com/htdocs/wp-content in / Updating Plugin Akismet (1/1) An error occurred while updating Akismet: Unable to locate WordPress Content directory (wp-content). Looking for /var/www/user/usersite.com/htdocs in / All updates have been completed.
The FS Tester plugin returns the following:
Connection Method ftpext ABSPATH /var/www/user/usersite.com/htdocs/ PLUGINDIR wp-content/plugins FS Errors None FS CWD / FS WordPress Locator Looking for /var/www/user/usersite.com/htdocs in / FS WordPress Location FS0 WordPress Locator (Old code) Changing to / FS0 WordPress Location (Old code) Tests Stopped; Error: WordPress could not be located Files in folder
However, if I modify the find_folder( $folder ) function in the file wp-admin/includes/class-wp-filesystem-base.php as outlined by @aberbenni in ticket #32345 then WP recognizes the FTP_BASE, FTP_CONTENT_DIR, and FTP_PLUGIN_DIR and everything works as expected. I am able to update plugins and the system files again. That is until class-wp-filesystem-base.php is overwritten.
I then receive the following output from FS Tester plugin:
Connection Method ftpext ABSPATH /var/www/user/usersite.com/htdocs/ PLUGINDIR wp-content/plugins FS Errors None FS CWD / FS WordPress Locator FS WordPress Location /usersite.com/htdocs/ FS0 WordPress Locator (Old code) Changing to / FS0 WordPress Location (Old code) NOTICE: WordPress locations different. Which is the correct one? Please email me at wordpress@dd32.id.au with the output from this page, and mention which is the correct path, Thanks :) Files in folder Plugin location: /var/www/user/usersite.com/htdocs/wp-content/plugins/wp-filesystem-tester.php (Local) /usersite.com/htdocs/wp-content/plugins/wp-filesystem-tester.php (FTP) Plugin Locations hello.php /usersite.com/htdocs/wp-content/plugins/ Delete file: /usersite.com/htdocs/wp-content/plugins/hello.php akismet/akismet.php /usersite.com/htdocs/wp-content/plugins/akismet/ Delete entire folder: /usersite.com/htdocs/wp-content/plugins/akismet/ File IO Errors All File IO tests passed. Created /usersite.com/htdocs/wp-content/plugins/super-long-name-not-to-conflict.php Verified conents Deleted /usersite.com/htdocs/wp-content/plugins/super-long-name-not-to-conflict.php Downloading a zip Downloading http://downloads.wordpress.org/plugin/akismet.zip... Suceeded Extracting Zip Suceeded Zip Contents akismet/ 0 ok binary akismet/akismet.php 2442 ok <?php /** * @package Akismet */ /* Plugin Name: ... akismet/class.akismet-admin.php 38939 ok <?php class Akismet_Admin { const NONCE = 'akism... akismet/.htaccess 616 ok binary akismet/_inc/ 0 ok binary akismet/_inc/img/ 0 ok binary akismet/_inc/img/logo-full-2x.png 4970 ok binary akismet/_inc/form.js 700 ok binary akismet/_inc/akismet.js 5969 ok binary akismet/_inc/akismet.css 6148 ok binary akismet/readme.txt 11775 ok === Akismet === Contributors: matt, ryan, andy, md... akismet/wrapper.php 6427 ok <?php global $wpcom_api_key, $akismet_api_host, $... akismet/class.akismet.php 42614 ok <?php class Akismet { const API_HOST = 'rest.aki... akismet/LICENSE.txt 18092 ok GNU GENERAL PUBLIC LICENSE ... akismet/index.php 26 ok <?php # Silence is golden.... akismet/class.akismet-widget.php 2719 ok <?php /** * @package Akismet */ class Akismet_Wi... akismet/views/ 0 ok binary akismet/views/notice.php 10572 ok <?php if ( $type == 'plugin' ) :?> <div class="upd... akismet/views/strict.php 830 ok <tr valign="top"> <th scope="row"><?php esc_html_... akismet/views/start.php 6547 ok <div class="no-key config-wrap"><?php if ( $akism... akismet/views/get.php 595 ok <form name="akismet_activate" action="https://akis... akismet/views/config.php 10537 ok <div class="wrap"> <h2><?php esc_html_e( 'Akisme... akismet/views/stats.php 551 ok <div class="wrap"> <h2><?php esc_html_e( 'Akismet...
The plugin says to report which path is correct, but the problem is they both are. Apache views the entire folder structure but the user SSH login views the shorter chrooted structure.
Being able to use the FTP_BASE, FTP_CONTENT_DIR, and FTP_PLUGIN_DIR variables, or an analogous SSH_BASE, SSH_CONTENT_DIR, and SSH_PLUGIN_DIR would solve the problem but there may be a better way to address it.
Attachments (2)
Change History (10)
#2
@
9 years ago
- Keywords has-patch removed
Please only mark as 'has patch' if a suitable patch file has been submitted.
#3
@
9 years ago
An additional comment on my system configuration:
My system is configured with two folders as follows:
/home/user/website /var/www/user/website
The users are chrooted to their home folders but I have all of the publicly accessible (web facing) folders for all users located in /var/www/.
I am mounting /var/www/user/website into the home folder so the users can access them as if they were in the same place.
When logging in via an ftp client the user just sees /website, the SSH2 module is seeing /home/user/website, and apache is seeing /var/www/user/website.
#4
@
9 years ago
"patch"
use:
public function find_folder( $folder ) { if ( isset( $this->cache[ $folder ] ) ) return $this->cache[ $folder ]; if ( stripos($this->method, 'ftp') !== false || stripos($this->method, 'ssh2') !== false ) {
isntead of
public function find_folder( $folder ) { if ( isset( $this->cache[ $folder ] ) ) return $this->cache[ $folder ]; if ( stripos($this->method, 'ftp') !== false ) {
#5
@
9 years ago
- Milestone changed from Awaiting Review to 4.4
@talatorre gratefully allowed me access to a test account on the server in question, I was able to find one major bug that was preventing it working:
- The PHP SSH2 extension was failing to be able to access, or list, the contents of the
/
directory.
This affected two main things:
$wp_filesystem->is_dir( '/' )
would return false$wp_filesystem->dirlist( '/' )
would return false
I'm not sure why, but this appears to be something to do with the way the SSH2 wrappers interact with the server. Take the following two examples:
dir(ssh2.sftp://Resource id #9/)
- Listing the/
directory, failsdir(ssh2.sftp://Resource id #9/home/account/)
- Listing my accounts home directory succeedsdir(ssh2.sftp://Resource id #9/./)
- Listing the/./
directory, which is really/
succeeds (you could also use/../
)
This has lead me to this PHP bug: https://bugs.php.net/bug.php?id=64169 which actually offers up the same workaround as I've already come up with.
Attached is 33919.diff which implements that workaround and centralises the code. Also attached a full copy of `class-wp-filesystem-ssh2.php` which can be dropped in to test with - @aberbenni can you try that out?
I'm using the find_folder( $folder ) "patch" too, waiting for a more stable and durable solution.