设置 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);
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值