Example #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")
			{
				// SILVERLIGHT: ?? what to do here ??
				// PhpException.Throw(PhpError.Warning, CoreResources.GetString("stream_file_access_denied", path));
			}

			return true;
		}
Example #2
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")
            {
                // SILVERLIGHT: ?? what to do here ??
                // PhpException.Throw(PhpError.Warning, CoreResources.GetString("stream_file_access_denied", path));
            }

            return(true);
        }
Example #3
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);

                if (Environment.OSVersion.Platform != PlatformID.Unix)
                {
                    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;
		}
Example #4
0
		/// <summary>
		/// Performs all checks on a path passed to a PHP function.
		/// </summary>
		/// <remarks>
		/// <para>
		/// This method performs a check similar to <c>safe_mode.c: php_checkuid_ex()</c>
		/// together with <c>open_basedir</c> check.
		/// </para>
		/// <para>
		/// The <paramref name="filename"/> may be one of the following:
		/// <list type="bullet">
		/// <item>A relative path. The path is resolved regarding the <c>include_path</c> too if required
		/// and checking continues as in the next case.</item>
		/// <item>An absolute path. The file or directory is checked for existence and for access permissions<sup>1</sup>
		/// according to the given <paramref name="mode"/>.</item>
		/// </list>
		/// <sup>1</sup> Regarding the <c>open_basedir</c> configuration option. 
		/// File access permissions are checked at the time of file manipulation
		/// (opening, copying etc.).
		/// </para>
		/// </remarks>
		/// <param name="filename">A resolved path. Must be an absolute path to a local file.</param>
		/// <param name="mode">One of the <see cref="CheckAccessMode"/>.</param>
		/// <param name="options"><c>true</c> to suppress error messages.</param>
		/// <returns><c>true</c> if the function may continue with file access,
		/// <c>false</c>to fail.</returns>
		/// <exception cref="PhpException">If the file can not be accessed
		/// and the <see cref="CheckAccessOptions.Quiet"/> is not set.</exception>
		public static bool CheckAccess(string filename, CheckAccessMode mode, CheckAccessOptions options)
		{
			Debug.Assert(Path.IsPathRooted(filename));
			string url = FileSystemUtils.StripPassword(filename);
			bool quiet = (options & CheckAccessOptions.Quiet) > 0;

			switch (mode)
			{
				case CheckAccessMode.FileMayExist:
					break;

				case CheckAccessMode.FileExists:
					if (!File.Exists(filename))
					{
						if (!quiet) PhpException.Throw(PhpError.Warning, CoreResources.GetString("stream_file_not_exists", url));
						return false;
					}
					break;

				case CheckAccessMode.FileNotExists:
					if (File.Exists(filename))
					{
						if (!quiet) PhpException.Throw(PhpError.Warning, CoreResources.GetString("stream_file_exists", url));
						return false;
					}
					break;

				case CheckAccessMode.FileOrDirectory:
					if ((!Directory.Exists(filename)) && (!File.Exists(filename)))
					{
						if (!quiet) PhpException.Throw(PhpError.Warning, CoreResources.GetString("stream_path_not_exists", url));
						return false;
					}
					break;

				case CheckAccessMode.Directory:
					if (!Directory.Exists(filename))
					{
						if (!quiet) PhpException.Throw(PhpError.Warning, CoreResources.GetString("stream_directory_not_exists", url));
						return false;
					}
					break;

				default:
					Debug.Assert(false);
					return false;
			}

			return true;
		}
Example #5
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);
        }
Example #6
0
        /// <summary>
        /// Performs all checks on a path passed to a PHP function.
        /// </summary>
        /// <remarks>
        /// <para>
        /// This method performs a check similar to <c>safe_mode.c: php_checkuid_ex()</c>
        /// together with <c>open_basedir</c> check.
        /// </para>
        /// <para>
        /// The <paramref name="filename"/> may be one of the following:
        /// <list type="bullet">
        /// <item>A relative path. The path is resolved regarding the <c>include_path</c> too if required
        /// and checking continues as in the next case.</item>
        /// <item>An absolute path. The file or directory is checked for existence and for access permissions<sup>1</sup>
        /// according to the given <paramref name="mode"/>.</item>
        /// </list>
        /// <sup>1</sup> Regarding the <c>open_basedir</c> configuration option.
        /// File access permissions are checked at the time of file manipulation
        /// (opening, copying etc.).
        /// </para>
        /// </remarks>
        /// <param name="filename">A resolved path. Must be an absolute path to a local file.</param>
        /// <param name="mode">One of the <see cref="CheckAccessMode"/>.</param>
        /// <param name="options"><c>true</c> to suppress error messages.</param>
        /// <returns><c>true</c> if the function may continue with file access,
        /// <c>false</c>to fail.</returns>
        /// <exception cref="PhpException">If the file can not be accessed
        /// and the <see cref="CheckAccessOptions.Quiet"/> is not set.</exception>
        public static bool CheckAccess(string filename, CheckAccessMode mode, CheckAccessOptions options)
        {
            Debug.Assert(Path.IsPathRooted(filename));
            string url   = FileSystemUtils.StripPassword(filename);
            bool   quiet = (options & CheckAccessOptions.Quiet) > 0;

            switch (mode)
            {
            case CheckAccessMode.FileMayExist:
                break;

            case CheckAccessMode.FileExists:
                if (!File.Exists(filename))
                {
                    if (!quiet)
                    {
                        PhpException.Throw(PhpError.Warning, CoreResources.GetString("stream_file_not_exists", url));
                    }
                    return(false);
                }
                break;

            case CheckAccessMode.FileNotExists:
                if (File.Exists(filename))
                {
                    if (!quiet)
                    {
                        PhpException.Throw(PhpError.Warning, CoreResources.GetString("stream_file_exists", url));
                    }
                    return(false);
                }
                break;

            case CheckAccessMode.FileOrDirectory:
                if ((!Directory.Exists(filename)) && (!File.Exists(filename)))
                {
                    if (!quiet)
                    {
                        PhpException.Throw(PhpError.Warning, CoreResources.GetString("stream_path_not_exists", url));
                    }
                    return(false);
                }
                break;

            case CheckAccessMode.Directory:
                if (!Directory.Exists(filename))
                {
                    if (!quiet)
                    {
                        PhpException.Throw(PhpError.Warning, CoreResources.GetString("stream_directory_not_exists", url));
                    }
                    return(false);
                }
                break;

            default:
                Debug.Assert(false);
                return(false);
            }

            return(true);
        }