在公司的实际应用中,服务器需要共享一些文件夹给客户端,让客户端用户可以使用特定的软件对这些文件夹中的文件进行读写操作,然而现在面临的问题是:要不就不能访问共享文件夹;要不就通过那个程序成功访问一次,然后用户就可以从网上邻居或开始菜单运行里直接进去随便乱逛了。
其实这个问题由来已久,一直也没想到有什么比较简便的办法来解决。但是随着用户的增多,保障文件的安全性就显得越来越重要了。
解决这个问题的最好方案就是将那个软件进行SOCKET编程。可是SOCKET编程比较底层,需要通过程序来处理很多网络通信方面问题,另外一点,我对SOCKET编程也不太熟悉,所以这个方案就被放到了最后。
随着.Net不断发布新的版本,出现了可以TCP传输的Remoting和WCF,让我看到了新的希望。不过前两天自学了一下WCF,发现对普通的传数据输还是不错的,不过对流处理的稳定性方面还是有点缺乏,会出现一些比较奇怪的错误。还是等微软先完善一下以后再考虑吧。所以这个方案也被搁置了。
今天在QQ群里问了下别人这个问题有没有好的办法解决,得到两个答案:SOCKET编程,在共享文件夹的共享名称前加美元号($),让用户不能从网上邻居里看到而直接访问。方法一直接跳过,方法二想法不错,不过只能骗骗那些不会直接输入网络路径的人。只要知道路径,一样是可以进的。不过这个方法却提醒了我一点:无论是SOCKET编程还是WCF,我实际上一直是站在服务器端考虑怎么解决这个问题。服务器端不好实现,并不代表客户端不好实现。所以,我决定从客户端开始下手。
整个网络是由一台WIN2003服务器和几十台WINXP和WIN2K客户端组成的内部局域网,服务器装有MSSQL,并共享了若干个文件夹的文件给客户端进行处理操作,由于处理文件的软件是我自己编写的,因此这个问题就转化成了在客户端中如何只让我的程序能够访问服务器共享文件,而其他的都不行。
所谓其他的程序,在我人为地限制安装软件的情况下,实际上就只有Explorer.exe这一个了。要禁掉这个程序是不现实的,但换一个方法,我可以通过程序来杀掉它。我想起了病毒“熊猫烧香”,曾经看过一篇文章介绍它的主要工作行为,其中很重要的一点就是根据名称或显示的标题杀掉一些特定的进程,这种方法我也可以借鉴。只要进程名是Explorer.exe,并且标题中包含共享文件夹的实际路径的,就可以将它杀掉。直接掉是一种处理方式,另外,还可以将此进程的窗口给隐藏掉,然后我的程序再弹出个窗口来要求输入特定的密码,如果密码正确则可以继续访问,这样就可以方便管理员的操作。
除了这种直接通过“网上邻居”,打开“我的电脑”或“开始”菜单的“运行”来直接输入路径的方法,我还想到一种比较隐秘的方法,那就是通过记事本等程序的打开文件对话框来选到“网上邻居”中进行操作了,这个时候,在共享文件夹的共享名称前加美元号($)就是个很好的方法了。
以上讲的是实现的主要方法及其产生的过程,下面说一下具体的实现步骤。
1.在服务器上设置共享文件夹,设置的时候要将其共享名称以“$”开头。
2.将这些共享文件夹的路径信息存入服务器的MSSQL数据库中。
3.修改客户端读写共享文件的程序,在其中加入一个WINDOWS服务,这个服务每隔几分钟访问一次数据库,获取最新的共享文件夹路径列表,根据这个列表中的路径每隔几秒钟查找本机进程中窗口标题包含共享路径的进程,直接杀掉该进程,或将它的窗口隐藏,再提示输入密码以继续操作。
4.为了保护这个监控服务,还可以在读写共享文件的程序中加入启动或定时检测监控服务的功能,在监控服务被停止时自己也不工作。这样,当监控服务被用户人为停止后,用户将因无法继续使用读写程序而报告管理员,管理员就可以及时发现这种非法操作。另外,还可以在监控服务中添加因手动停止产生事件日志的代码,可以将事件日志保存到本地,并备份到服务器数据库中。
5.最后,将程序及服务打包安装到客户端中。
后来,又想到一个服务器端的解决方法:在服务器上,通过程序获取访问本机共享文件夹的会话和被访问文件等信息,如果这些信息中包含了访问者的进程名称,就可以直接停止这个文件的访问。如果这样的话,这个问题就更简便地解决了。不过从“计算机管理”中没有看到里面包含我所想要的信息,网上也暂时没有找到有关的编程方法,所以还是决定采用以上的客户端处理方案。