Ejemplo n.º 1
0
        /// <summary>
        /// Merges the path with the current working directory
        /// to get a canonicalized absolute pathname representing the same file.
        /// </summary>
        /// <remarks>
        /// This method is an analogy of <c>main/safe_mode.c: php_checkuid</c>.
        /// Looks for the file in the <c>include_path</c> and checks for <c>open_basedir</c> restrictions.
        /// </remarks>
        /// <param name="path">An absolute or relative path to a file.</param>
        /// <param name="wrapper">The wrapper found for the specified file or <c>null</c> if the path resolution fails.</param>
        /// <param name="mode">The checking mode of the <see cref="CheckAccess"/> method (file, directory etc.).</param>
        /// <param name="options">Additional options for the <see cref="CheckAccess"/> method.</param>
        /// <returns><c>true</c> if all the resolution and checking passed without an error, <b>false</b> otherwise.</returns>
        /// <exception cref="PhpException">Security violation - when the target file
        /// lays outside the tree defined by <c>open_basedir</c> configuration option.</exception>
        public static bool ResolvePath(ref string path, out StreamWrapper wrapper, CheckAccessMode mode, CheckAccessOptions options)
        {
            // Path will contain the absolute path without file:// or the complete URL; filename is the relative path.
            string filename, scheme = GetSchemeInternal(path, out filename);

            wrapper = StreamWrapper.GetWrapper(scheme, (StreamOptions)options);
            if (wrapper == null)
            {
                return(false);
            }

            if (wrapper.IsUrl)
            {
                // Note: path contains the whole URL, filename the same without the scheme:// portion.
                // What to check more?
            }
            else if (scheme != "php")
            {
                try
                {
                    // Filename contains the original path without the scheme:// portion, check for include path.
                    bool isInclude = false;
                    if ((options & CheckAccessOptions.UseIncludePath) > 0)
                    {
                        isInclude = CheckIncludePath(filename, ref path);
                    }

                    // Path will now contain an absolute path (either to an include or actual directory).
                    if (!isInclude)
                    {
                        path = Path.GetFullPath(Path.Combine(ScriptContext.CurrentContext.WorkingDirectory, filename));
                    }
                }
                catch (Exception)
                {
                    if ((options & CheckAccessOptions.Quiet) == 0)
                    {
                        PhpException.Throw(PhpError.Warning, CoreResources.GetString("stream_filename_invalid",
                                                                                     FileSystemUtils.StripPassword(path)));
                    }
                    return(false);
                }

                GlobalConfiguration global_config = Configuration.Global;

                // Note: extensions check open_basedir too -> double check..
                if (!global_config.SafeMode.IsPathAllowed(path))
                {
                    if ((options & CheckAccessOptions.Quiet) == 0)
                    {
                        PhpException.Throw(PhpError.Warning, CoreResources.GetString("open_basedir_effect",
                                                                                     path, global_config.SafeMode.GetAllowedPathPrefixesJoin()));
                    }
                    return(false);
                }

                // Replace all '/' with '\'.
                // path = path.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
                Debug.Assert(
                    path.IndexOf(Path.AltDirectorySeparatorChar) == -1 ||
                    (Path.AltDirectorySeparatorChar == Path.DirectorySeparatorChar),    // on Mono, so ignore it
                    string.Format("'{0}' should not contain '{1}' char.", path, Path.AltDirectorySeparatorChar));

                // The file wrapper expects an absolute path w/o the scheme, others expect the scheme://url.
                if (scheme != "file")
                {
                    path = String.Format("{0}://{1}", scheme, path);
                }
            }

            return(true);
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Creates a new <see cref="ExternalStream"/> with the given proxy object.
 /// </summary>
 /// <param name="proxy">Instance of a class derived from <see cref="MarshalByRefObject"/> that should
 /// serve as a proxy for this <see cref="ExternalStream"/>.</param>
 /// <param name="openingWrapper">The parent instance.</param>
 /// <param name="accessOptions">The additional options parsed from the <c>fopen()</c> mode.</param>
 /// <param name="openedPath">The absolute path to the opened resource.</param>
 /// <param name="context">The stream context passed to fopen().</param>
 internal ExternalStream(IExternalStream proxy, StreamWrapper openingWrapper, StreamAccessOptions accessOptions, string openedPath, StreamContext context)
     : base(openingWrapper, accessOptions, openedPath, context)
 {
     this.proxy = proxy;
 }