• 设置 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);



  • 相关阅读:
    四个数判断大小
    生成随机数的效率问题
    vmware下ubuntu的网络配置
    安装Orcacle后使用DBCA(Database Configuration Assistant)卡住的问题
    Spring Tool Suit安装virgo server插件、virgo的下载
    centos的终端字体杂乱的问题
    vmware下minimum安装centos后配置网络
    hibernate session.save()和session.persist()的区别
    bootstrap结合google code prettify的问题
    jsp乱码问题
  • 原文地址:https://www.cnblogs.com/eaglet/p/1196762.html
Copyright © 2020-2023  润新知