zoukankan      html  css  js  c++  java
  • 设置 NULL DACL 权限描述符解决ASP.NET 通过 FileMapping 与其他进程通信问题

    最近做了一个采用FileMapping进行进程间通信的程序,目的是希望通过这个程序实现WebService和我写的其他服务之间
    通信,实现安全隔离以及一些状态的跟踪、保持和管理。做好后,先用两个普通的Windows 进程测试了一下,在1.8G双核
    笔记本电脑上,每秒钟可以发送3万个1000字节大小的消息,效率基本达到我的要求(我没有把效率优化到极致,效率瓶颈
    和优化方法我基本知道,就是人懒,现在的方案已经可以达到系统要求,就暂时不想弄了,等以后有时间再优化吧)
    立即将客户端移植到ASP.NET中,结果打开FileMapping失败,立即意识到是权限问题。到网上搜了一遍,有网友说强制让
    ASP.NET扮演系统管理员权限来解决,觉得不妥,一听就觉得不是一个安全的解决方案。第二种是采用NULL DACL 权限描述
    符,赋予系统内核对象对任何用户都开放的完全的访问权限,这种方法比第一种好一些,不过攻击者依然可以用很低的权限
    登录系统后对系统内核对象进行操作,破坏系统。第三种方法是只把服务自生和ASP.NET的权限描述符赋予系统内核对象,这种
    方法安全性最高。
    网上代码大多是C++写的,我用C#先写了一个NULL DACL 的代码,用了一下,果然和预期的结果一样,WebService可以和
    服务进程通讯了。把这个代码给大家共享一下。第三种方法的代码以后再补充。
    推荐参考这篇文章: http://dev.csdn.net/article/33/33903.shtm

    NULL DACL 的C#写法:
     
        [StructLayoutAttribute(LayoutKind.Sequential)]
        
    public struct SECURITY_DESCRIPTOR
        
    {
            
    public byte revision;
            
    public byte size;
            
    public short control;
            
    public IntPtr owner;
            
    public IntPtr group;
            
    public IntPtr sacl;
            
    public IntPtr dacl;

        }



        [StructLayout(LayoutKind.Sequential)]
        
    public class SecurityAttributes : IDisposable
        
    {
            [DllImport(
    "advapi32.dll", SetLastError = true)]
            
    static extern bool SetSecurityDescriptorDacl(IntPtr sd, bool daclPresent, IntPtr dacl, bool daclDefaulted);


            [DllImport(
    "advapi32.dll", SetLastError = true)]
            
    static extern bool InitializeSecurityDescriptor(IntPtr pSecurityDescriptor, uint dwRevision);

            
    private int nLength;
            
    private IntPtr lpSecurityDescriptor;
            
    private int bInheritHandle;

            
    public SecurityAttributes()
            
    {
                
    //Get SecurityAttributes size
                nLength = Marshal.SizeOf(typeof(SecurityAttributes));
                
                
    //Inherit handle
                bInheritHandle = 1;

                
    //Create a NULL DACL 
                SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR();

                
    //Alloc memory for security descriptor
                lpSecurityDescriptor = Marshal.AllocCoTaskMem(Marshal.SizeOf(sd));

                
    //Struct to Ptr
                Marshal.StructureToPtr(sd, lpSecurityDescriptor, false);
                
                InitializeSecurityDescriptor(lpSecurityDescriptor, 
    1);
                SetSecurityDescriptorDacl(lpSecurityDescriptor, 
    true, IntPtr.Zero, false);
            }


            
    public void Dispose()
            
    {
                
    lock (this)
                
    {
                    
    if (lpSecurityDescriptor != IntPtr.Zero)
                    
    {
                        Marshal.FreeHGlobal(lpSecurityDescriptor);
                        lpSecurityDescriptor 
    = IntPtr.Zero;
                    }

                }

            }


            
    ~SecurityAttributes()
            
    {
                Dispose();
            }


        }

    和FileMapping内核对象相关的API函数申明:

            [DllImport("Kernel32.dll", EntryPoint = "CreateFileMapping", SetLastError = true, CharSet = CharSet.Unicode)]
            
    internal static extern IntPtr CreateFileMapping(uint hFile, SecurityAttributes lpAttributes, uint flProtect, uint dwMaximumSizeHigh, uint dwMaximumSizeLow, string lpName);

            [DllImport(
    "Kernel32.dll", EntryPoint = "OpenFileMapping", SetLastError = true, CharSet = CharSet.Unicode)]
            
    internal static extern IntPtr OpenFileMapping(uint dwDesiredAccess, bool bInheritHandle, string lpName);

            [DllImport(
    "Kernel32.dll", EntryPoint = "MapViewOfFile", SetLastError = true, CharSet = CharSet.Unicode)]
            
    internal static extern IntPtr MapViewOfFile(IntPtr hFileMappingObject, uint dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow, uint dwNumberOfBytesToMap);

            [DllImport(
    "Kernel32.dll", EntryPoint = "UnmapViewOfFile", SetLastError = true, CharSet = CharSet.Unicode)]
            [
    return: MarshalAs(UnmanagedType.VariantBool)]
            
    internal static extern bool UnmapViewOfFile(IntPtr lpBaseAddress);

            [DllImport(
    "Kernel32.dll", EntryPoint = "FlushViewOfFile", SetLastError = true, CharSet = CharSet.Unicode)]
            [
    return: MarshalAs(UnmanagedType.VariantBool)]
            
    internal static extern bool FlushViewOfFile(IntPtr lpBaseAddress, uint dwNumberOfBytesToFlush);



  • 相关阅读:
    AX 2012 Security Framework
    The new concept 'Model' in AX 2012
    How to debug the SSRS report in AX 2012
    Using The 'Report Data Provider' As The Data Source For AX 2012 SSRS Report
    Deploy SSRS Report In AX 2012
    AX 2012 SSRS Report Data Source Type
    《Taurus Database: How to be Fast, Available, and Frugal in the Cloud》阅读笔记
    图分析理论 大纲小结
    一文快速了解Posix IO 缓冲
    #转载备忘# Linux程序调试工具
  • 原文地址:https://www.cnblogs.com/eaglet/p/1196762.html
Copyright © 2011-2022 走看看