Example #1
0
function PackageDownload()
{
    global $txt, $scripturl, $boarddir, $context, $sourcedir, $db_prefix;
    // Use the downloaded sub template.
    $context['sub_template'] = 'downloaded';
    // Security is good...
    checkSession('get');
    if (isset($_GET['server'])) {
        $server = (int) $_GET['server'];
        // Query the server table to find the requested server.
        $request = db_query("\n\t\t\tSELECT name, url\n\t\t\tFROM {$db_prefix}package_servers\n\t\t\tWHERE ID_SERVER = {$server}\n\t\t\tLIMIT 1", __FILE__, __LINE__);
        list($name, $url) = mysql_fetch_row($request);
        mysql_free_result($request);
        // If server does not exist then dump out.
        if (empty($url)) {
            fatal_lang_error('smf191', false);
        }
        $url = $url . '/';
    } else {
        // Initialize the requried variables.
        $server = '';
        $url = '';
    }
    $package_name = basename($_REQUEST['package']);
    if (isset($_REQUEST['conflict']) || isset($_REQUEST['auto']) && file_exists($boarddir . '/Packages/' . $package_name)) {
        // Find the extension, change abc.tar.gz to abc_1.tar.gz...
        if (strrpos(substr($package_name, 0, -3), '.') !== false) {
            $ext = substr($package_name, strrpos(substr($package_name, 0, -3), '.'));
            $package_name = substr($package_name, 0, strrpos(substr($package_name, 0, -3), '.')) . '_';
        } else {
            $ext = '';
        }
        // Find the first available.
        $i = 1;
        while (file_exists($boarddir . '/Packages/' . $package_name . $i . $ext)) {
            $i++;
        }
        $package_name = $package_name . $i . $ext;
    }
    // First make sure it's a package.
    if (getPackageInfo($url . $_REQUEST['package']) == false) {
        fatal_lang_error('package45', false);
    }
    // Use FTP if necessary.
    packageRequireFTP($scripturl . '?action=packageget;sa=download' . (isset($_GET['server']) ? ';server=' . $_GET['server'] : '') . (isset($_REQUEST['auto']) ? ';auto' : '') . ';package=' . $_REQUEST['package'] . (isset($_REQUEST['conflict']) ? ';conflict' : '') . ';sesc=' . $context['session_id'], array($boarddir . '/Packages/' . $package_name));
    package_put_contents($boarddir . '/Packages/' . $package_name, fetch_web_data($url . $_REQUEST['package']));
    // Done!  Did we get this package automatically?
    if (preg_match('~^http://[\\w_\\-]+\\.simplemachines\\.org/~', $_REQUEST['package']) == 1 && strpos($_REQUEST['package'], 'dlattach') === false && isset($_REQUEST['auto'])) {
        redirectexit('action=packages;sa=install;package=' . $package_name . ';sesc=' . $context['session_id']);
    }
    // You just downloaded a mod from SERVER_NAME_GOES_HERE.
    $context['package_server'] = $server;
    $context['package'] = getPackageInfo($package_name);
    if (empty($context['package'])) {
        fatal_lang_error('package_cant_download', false);
    }
    if ($context['package']['type'] == 'modification') {
        $context['package']['install']['link'] = '<a href="' . $scripturl . '?action=packages;sa=install;package=' . $context['package']['filename'] . ';sesc=' . $context['session_id'] . '">[ ' . $txt['package11'] . ' ]</a>';
    } elseif ($context['package']['type'] == 'avatar') {
        $context['package']['install']['link'] = '<a href="' . $scripturl . '?action=packages;sa=install;package=' . $context['package']['filename'] . ';sesc=' . $context['session_id'] . '">[ ' . $txt['package12'] . ' ]</a>';
    } elseif ($context['package']['type'] == 'language') {
        $context['package']['install']['link'] = '<a href="' . $scripturl . '?action=packages;sa=install;package=' . $context['package']['filename'] . ';sesc=' . $context['session_id'] . '">[ ' . $txt['package13'] . ' ]</a>';
    } else {
        $context['package']['install']['link'] = '';
    }
    $context['package']['list_files']['link'] = '<a href="' . $scripturl . '?action=packages;sa=list;package=' . $context['package']['filename'] . '">[ ' . $txt['package14'] . ' ]</a>';
    // Free a little bit of memory...
    unset($context['package']['xml']);
    $context['page_title'] = $txt['smf192'];
}
Example #2
0
function PackageRemove()
{
    global $scripturl, $boarddir;
    checkSession('get');
    // Ack, don't allow deletion of arbitrary files here, could become a security hole somehow!
    if (!isset($_GET['package']) || $_GET['package'] == 'index.php' || $_GET['package'] == 'installed.list') {
        redirectexit('action=packages;sa=browse');
    }
    $_GET['package'] = preg_replace('~[\\.]+~', '.', strtr($_GET['package'], array('/' => '_', '\\' => '_')));
    // Can't delete what's not there.
    if (file_exists($boarddir . '/Packages/' . $_GET['package']) && (substr($_GET['package'], -4) == '.zip' || substr($_GET['package'], -4) == '.tgz' || substr($_GET['package'], -7) == '.tar.gz' || is_dir($boarddir . '/Packages/' . $_GET['package'])) && $_GET['package'] != 'backups' && substr($_GET['package'], 0, 1) != '.') {
        packageRequireFTP($scripturl . '?action=packages;sa=remove;package=' . $_GET['package'], array($boarddir . '/Packages/' . $_GET['package']));
        if (is_dir($boarddir . '/Packages/' . $_GET['package'])) {
            deltree($boarddir . '/Packages/' . $_GET['package']);
        } else {
            @chmod($boarddir . '/Packages/' . $_GET['package'], 0777);
            unlink($boarddir . '/Packages/' . $_GET['package']);
        }
    }
    redirectexit('action=packages;sa=browse');
}
Example #3
0
function packageRequireFTP($destination_url, $files = null, $return = false)
{
    global $context, $modSettings, $package_ftp, $boarddir, $txt;
    // Try to make them writable the manual way.
    if ($files !== null) {
        foreach ($files as $k => $file) {
            // If this file doesn't exist, then we actually want to look at the directory, no?
            if (!file_exists($file)) {
                $file = dirname($file);
            }
            // This looks odd, but it's an attempt to work around PHP suExec.
            if (!@is_writable($file)) {
                @chmod($file, 0755);
            }
            if (!@is_writable($file)) {
                @chmod($file, 0777);
            }
            if (!@is_writable(dirname($file))) {
                @chmod($file, 0755);
            }
            if (!@is_writable(dirname($file))) {
                @chmod($file, 0777);
            }
            $fp = is_dir($file) ? @opendir($file) : @fopen($file, 'rb');
            if (@is_writable($file) && $fp) {
                unset($files[$k]);
                if (!is_dir($file)) {
                    fclose($fp);
                } else {
                    closedir($fp);
                }
            }
        }
        // No FTP required!
        if (empty($files)) {
            return array();
        }
    }
    // They've opted to not use FTP, and try anyway.
    if (isset($_SESSION['pack_ftp']) && $_SESSION['pack_ftp'] == false) {
        if ($files === null) {
            return array();
        }
        foreach ($files as $k => $file) {
            // This looks odd, but it's an attempt to work around PHP suExec.
            if (!file_exists($file)) {
                mktree(dirname($file), 0755);
                @touch($file);
                @chmod($file, 0755);
            }
            if (!@is_writable($file)) {
                @chmod($file, 0777);
            }
            if (!@is_writable(dirname($file))) {
                @chmod(dirname($file), 0777);
            }
            if (@is_writable($file)) {
                unset($files[$k]);
            }
        }
        return $files;
    } elseif (isset($_SESSION['pack_ftp'])) {
        // Load the file containing the ftp_connection class.
        loadClassFile('Class-Package.php');
        $package_ftp = new ftp_connection($_SESSION['pack_ftp']['server'], $_SESSION['pack_ftp']['port'], $_SESSION['pack_ftp']['username'], package_crypt($_SESSION['pack_ftp']['password']));
        if ($files === null) {
            return array();
        }
        foreach ($files as $k => $file) {
            $ftp_file = strtr($file, array($_SESSION['pack_ftp']['root'] => ''));
            // This looks odd, but it's an attempt to work around PHP suExec.
            if (!file_exists($file)) {
                mktree(dirname($file), 0755);
                $package_ftp->create_file($ftp_file);
                $package_ftp->chmod($ftp_file, 0755);
            }
            if (!@is_writable($file)) {
                $package_ftp->chmod($ftp_file, 0777);
            }
            if (!@is_writable(dirname($file))) {
                $package_ftp->chmod(dirname($ftp_file), 0777);
            }
            if (@is_writable($file)) {
                unset($files[$k]);
            }
        }
        return $files;
    }
    if (isset($_POST['ftp_none'])) {
        $_SESSION['pack_ftp'] = false;
        $files = packageRequireFTP($destination_url, $files, $return);
        return $files;
    } elseif (isset($_POST['ftp_username'])) {
        loadClassFile('Class-Package.php');
        $ftp = new ftp_connection($_POST['ftp_server'], $_POST['ftp_port'], $_POST['ftp_username'], $_POST['ftp_password']);
        if ($ftp->error === false) {
            // Common mistake, so let's try to remedy it...
            if (!$ftp->chdir($_POST['ftp_path'])) {
                $ftp_error = $ftp->last_message;
                $ftp->chdir(preg_replace('~^/home[2]?/[^/]+?~', '', $_POST['ftp_path']));
            }
        }
    }
    if (!isset($ftp) || $ftp->error !== false) {
        if (!isset($ftp)) {
            loadClassFile('Class-Package.php');
            $ftp = new ftp_connection(null);
        } elseif ($ftp->error !== false && !isset($ftp_error)) {
            $ftp_error = $ftp->last_message === null ? '' : $ftp->last_message;
        }
        list($username, $detect_path, $found_path) = $ftp->detect_path($boarddir);
        if ($found_path) {
            $_POST['ftp_path'] = $detect_path;
        } elseif (!isset($_POST['ftp_path'])) {
            $_POST['ftp_path'] = isset($modSettings['package_path']) ? $modSettings['package_path'] : $detect_path;
        }
        if (!isset($_POST['ftp_username'])) {
            $_POST['ftp_username'] = $username;
        }
        $context['package_ftp'] = array('server' => isset($_POST['ftp_server']) ? $_POST['ftp_server'] : (isset($modSettings['package_server']) ? $modSettings['package_server'] : 'localhost'), 'port' => isset($_POST['ftp_port']) ? $_POST['ftp_port'] : (isset($modSettings['package_port']) ? $modSettings['package_port'] : '21'), 'username' => isset($_POST['ftp_username']) ? $_POST['ftp_username'] : (isset($modSettings['package_username']) ? $modSettings['package_username'] : ''), 'path' => $_POST['ftp_path'], 'error' => empty($ftp_error) ? null : $ftp_error, 'destination' => $destination_url);
        // If we're returning dump out here.
        if ($return) {
            return $files;
        }
        $context['page_title'] = $txt['package_ftp_necessary'];
        $context['sub_template'] = 'ftp_required';
        obExit();
    } else {
        if (!in_array($_POST['ftp_path'], array('', '/'))) {
            $ftp_root = strtr($boarddir, array($_POST['ftp_path'] => ''));
            if (substr($ftp_root, -1) == '/' && ($_POST['ftp_path'] == '' || substr($_POST['ftp_path'], 0, 1) == '/')) {
                $ftp_root = substr($ftp_root, 0, -1);
            }
        } else {
            $ftp_root = $boarddir;
        }
        $_SESSION['pack_ftp'] = array('server' => $_POST['ftp_server'], 'port' => $_POST['ftp_port'], 'username' => $_POST['ftp_username'], 'password' => package_crypt($_POST['ftp_password']), 'path' => $_POST['ftp_path'], 'root' => $ftp_root);
        if (!isset($modSettings['package_path']) || $modSettings['package_path'] != $_POST['ftp_path']) {
            updateSettings(array('package_path' => $_POST['ftp_path']));
        }
        $files = packageRequireFTP($destination_url, $files, $return);
    }
    return $files;
}
Example #4
0
function CleanupPermissions()
{
    global $boarddir, $sourcedir, $scripturl, $package_ftp, $modSettings;
    isAllowedTo('admin_forum');
    umask(0);
    loadTemplate('Packages');
    loadLanguage('Packages');
    if (!isset($_REQUEST['perm_type']) || !in_array($_REQUEST['perm_type'], array('free', 'restrictive', 'standard'))) {
        $_REQUEST['perm_type'] = 'free';
    }
    checkSession();
    // FTP to the rescue!
    require_once $sourcedir . '/Subs-Package.php';
    packageRequireFTP($scripturl . '?action=cleanperms;perm_type=' . $_REQUEST['perm_type']);
    // The files that should be chmod'd are here - add any if you add any files with a modification.
    $special_files = array();
    $special_files['restrictive'] = array('/attachments', '/custom_avatar_dir', '/Settings.php', '/Settings_bak.php');
    $special_files['standard'] = array('/attachments', '/avatars', '/custom_avatar_dir', '/Packages', '/Packages/installed.list', '/Smileys', '/Themes', '/agreement.txt', '/Settings.php', '/Settings_bak.php');
    @chmod($boarddir . '/Settings.php', 0755);
    if (isset($package_ftp)) {
        $package_ftp->chmod(strtr($boarddir . '/Settings.php', array($_SESSION['pack_ftp']['root'] => '')), 0755);
    }
    // If the owner of PHP is not nobody, this should probably pass through - in which case 755 is better than 777.
    if ((!function_exists('is_executable') || is_executable($boarddir . '/Settings.php')) && is_writable($boarddir . '/Settings.php')) {
        $suexec_fix = 0755;
    } else {
        $suexec_fix = 0777;
    }
    @chmod($boarddir, $_REQUEST['perm_type'] == 'free' ? $suexec_fix : 0755);
    if (isset($package_ftp)) {
        $package_ftp->chmod(strtr($boarddir . '/.', array($_SESSION['pack_ftp']['root'] => '')), $_REQUEST['perm_type'] == 'free' ? $suexec_fix : 0755);
    }
    $dirs = array('' => $boarddir);
    if (substr($sourcedir, 0, strlen($boarddir)) != $boarddir) {
        $dirs['/Sources'] = $sourcedir;
    }
    if (substr($modSettings['attachmentUploadDir'], 0, strlen($boarddir)) != $boarddir) {
        $dirs['/attachments'] = $modSettings['attachmentUploadDir'];
    }
    if (substr($modSettings['smileys_dir'], 0, strlen($boarddir)) != $boarddir) {
        $dirs['/Smileys'] = $modSettings['smileys_dir'];
    }
    if (substr($modSettings['avatar_directory'], 0, strlen($boarddir)) != $boarddir) {
        $dirs['/avatars'] = $modSettings['avatar_directory'];
    }
    if (isset($modSettings['custom_avatar_dir']) && substr($modSettings['custom_avatar_dir'], 0, strlen($boarddir)) != $boarddir) {
        $dirs['/custom_avatar_dir'] = $modSettings['custom_avatar_dir'];
    }
    $done_dirs = array();
    while (count($dirs) > 0) {
        // The alias is what we know it as.  The attachments directory *could* be named "uploads".
        $temp = array_keys($dirs);
        $alias = $temp[0];
        // The actual full filename...
        $dirname = $dirs[$alias];
        unset($dirs[$alias]);
        $dir = dir($dirname);
        if (!$dir) {
            continue;
        }
        while ($entry = $dir->read()) {
            if ($entry == '.' || $entry == '..') {
                continue;
            }
            // Figure out the filenames to chmod with...
            $filename = $dirname . '/' . $entry;
            $ftp_file = strtr($filename, array($_SESSION['pack_ftp']['root'] => ''));
            // Is this one we want writable?
            if ($_REQUEST['perm_type'] == 'free' || in_array($alias . '/' . $entry, $special_files[$_REQUEST['perm_type']])) {
                @chmod($filename, $suexec_fix);
                if (isset($package_ftp)) {
                    $package_ftp->chmod($ftp_file, $suexec_fix);
                }
            } else {
                @chmod($filename, 0755);
                if (isset($package_ftp)) {
                    $package_ftp->chmod($ftp_file, 0755);
                }
            }
            // Directories get added to the todo list.
            if (@is_dir($filename) && !in_array($filename, $done_dirs)) {
                $dirs[$alias . '/' . $entry] = $filename;
            }
        }
        $done_dirs[] = $dirname;
    }
    redirectexit('action=packages;sa=options');
}