Archives

  • 网络安全通讯(4)—-为Python Webserver添加HTTPS支持

    前面我们说的都是为Apache服务器添加HTTPS的支持,今天我们讨论一下为Python的Webserver添加HTTPS的支持。 Python的Webserver基本上都是遵循Python的WSGI标准,包括我使用的CherryPy和webpy。在这两个Webserver的源代码中都有一个package叫做wsgiserver,里面只有__init__.py。这两个Webserver的wsgiserver内容几乎一样,而且明显有CherryPy的痕迹,看来CherryPy可能是WSGI标准的一个(半)官方实现,就好像Tomcat至于Servlet。 WSGI标准写的很是笼统,他只是说可以支持SSL,无他。只好阅读源代码,代码里面写的倒不是很差。需要同时给出ssl需要的服务器端的私钥和证书,分别使用如下两个变量存放。ssl_certificate: the filename of the server SSL certificate.      服务器端的SSL证书ssl_privatekey: the filename of the server’s private key file.    服务器端的私钥我们只要遵循每个服务器的文档设置上就可以了。我们以CherryPy为例。(好吧,我说实话,我只会这个。) 在CherryPy的配置文件里面,可以设置这两个变量,分别指向文件系统的文件。[global]server.socket_port : 8081server.socket_host : “0.0.0.0″server.ssl_certificate : “conf/cert/server.crt”server.ssl_private_key : “conf/cert/server.key”这样,当我们重新启动的时候,我们的webserver就已经开始支持HTTPS了。如果这两个变量有一个没有设置的话,HTTPS就不会起作用。 这里我不得不说一下,CherryPy的文档已经算是不错的了,但是还是不行,只有在ServerAPI里面稍微提及了一下这两个变量而已。想要完整的搞明白,就只能祭出hack源代码大发,还得有连蒙带唬的功能。 至于webpy,就最好看看他的文档了。

    Mar 14th, 2008 | Filed under python, 安全
  • [Cherrypy]配置设置,静态内容支持

    Cherrypy是一个很不错的python webserver,不过好东西也会让人抓狂的。Cherrypy的配置可以放在一个配置文件中,然后在启动的时候提供出文件名就可以。cherrypy.quickstart(handler, config=’/path/to/conf_file’) 我需要用到的一个功能就是要增加一个静态内容的支持,也就是当用户访问http://localhost/static的时候指向的是我的一个存放静态内容(js,css等)的目录。这个可以使用配置文件的tools.staticfile和tools.staticdir参数设置(相见Cherrypy的StaticContent章节)。但是你写在配置文件中的都需要是一个绝对路径,而我的程序是不一定安装到哪里的,所以只能后期配置。此时的配置信息是分两部分的,一部分是通用的,一部分是静态内容,需要根据当前所在目录组合起来的。 正确的写法是cherrypy.config.update(global_config)然后是cherrypy的quickstart里面的config是static的配置cherrypy.quickstart(handler, config=static_conf) 首先是把全局的配置设置在cherrypy的config中,然后在quickstart里面给出静态内容的配置。 我走了一个弯路,无法正确的使用静态内容 把所有的内容都放在一个配置信息中,使用cherrypy.config.update,在quickstart的时候不给config参数 就原因来说,我查看了一下cherrypy的源代码,他会在quickstart的时候,把config参数应用在tree的mount上,而static content的配置在此时才会起作用的。所以这样做是不行的。

    Mar 14th, 2008 | Filed under cherrypy
  • 从extjs的ComboBox探究form的提交

    今天又差点被extjs搞死了,好吧,我承认是已经搞死了。具体的事情是这样的,我有一个页面是填写数据,就是一个Form啊,里面有下拉列表,使用extjs里面的ComboBox,然后就发现鸟几个诡异的事情。 一旦选中了某一个选项,就无法选择其他的了,因为下拉选项里面只有这个当前选中的备选项。 无论我怎么提交,提交过去的都是显示的选项而不是对应的value。 第一个问题抄了别人的代码看明白了,原来是在设置ComboBox的时候需要把参数triggerAction设置成为’all’,它默认的是’query’。这是表示我下面显示的是全部内容还是根据当前ComboBox里面输入的内容进行筛选的内容。 下面来说说第二个问题,折腾了我几个小时的问题。我们看一下原来的<select>的写法,其中的选项<option value=”value”>Text</option>。给用户看到的是Text,而post到server的是value。但是extjs的ComboBox呢?我尝试了n次,他都是把Text给我传回去了。翻文档,google,也没有个所以然,最后继续祭出hack大法。用firebug看一下生成的页面,ComboBox是由一个input和一个div组成的,这个input的名字就是你在ComboBox里面设定的名字,随着你的选择,你选中项的Text也就写进了这个input。也就是说明在提交的时候,form用的是这个内容。这里面有两个疑惑我的问题。 文档上说默认情况下FormPanel(其实是FormPanel内置的BasicForm)会使用BasicForm的Action方法进行Ajax提交。 文档上说ComboBox的值,由制定的valueField从Store里面获取。 看到这两个文档说,你会想到什么,至少我是下意识的想到,form提交的时候,遍历他的所有的孩子,然后获取各自的value,组织一下,用Ajax post到服务器。多make sense。Bingo,恭喜你,跟我一样,答错了。我从BasicForm的submit一路寻找到底,才发现他到底怎么做的。我说说,你听听,在想当初。 submit的方法都是归并到doAction方法,然后根据你是submit,再去寻找Ext.form.Action.Submit类的run方法。 Ext.form.Action.Submit.run里面有一个方法是getParams用来拼接参数,这是继承自Ext.form.Action.getParams Ext.form.Action.getParams调用Ext.lib.Ajax.serializeForm方法。在这里我却找了半天没找到这个方法,因为我是直接grep Ext.lib.Ajax.serializeForm,未果,全是调用。最后grep Ext.lib.Ajax,才发现在每一个adapter里面有这么一个类,进去才找到serializeForm方法。 因为我使用的adapter是ext-base,所以分析他的serializeForm方法,是根据传入的form遍历所有的孩子 恍然大悟,原来拼接的参数也是从form里面抠出来的,而不是各个组件自己维护的value。 既然这样,那就得从ComboBox如何能够正确的生成input下手了。查看Ext.form.ComboBox.onRender方法,对一个叫做hiddenName的变量进行判断,然后根据判断的结果生成input。并且里面的数据是取自hiddenField的值,而hiddenField的值是在定义了hiddenValue时候使用,没定义的时候使用ComboBox的value,所以也就是ComboBox的valueField定义的。修改代码,在生成ComboBox的时候,添加hiddenName参数,这时候生成的form终于对了,post到server的内容也对了。太不容易了。 这时候我还有一个疑问,根据文档,如果我在生成BasicForm的时候,给定参数standardSubmit为true,那么就会使用默认的DOM的form.submit()方法,也就是标准的刷新页面的提交方法。但是这个和非standardSubmit的区别仅仅是方法的不同,而不是一个原生的(native)的提交方法和Ajax(自组织value)的提交方法。 对extjs的建议 对文档和名称再标准化一些,至少要比较make sense吧(也许是以前我自己写UI框架时候中毒太深吧) 最好给一个设计的文档出来,要知道OO的代码看上去是比较费劲的 ComboBox很不错,就是文档糟糕了点,至少例子里面的注释多点好伐

    Mar 6th, 2008 | Filed under extjs
    Tags: ,
  • 给extjs的grid添加一个动作按钮的列,搞不定

    extjs非常好,真的非常好,他的代码写的也很好,很多东西用起来很舒服。 我说的是用起来舒服,并不代表学习使用的时候舒服,其实学习使用extjs真是一个恶心的事情,文档乍看上去很美,但是组织的并不是很好。就好像我写一个FormPanel的时候,里面的items,我需要指定他的显示类型(xtype)就找了半天也无法找到一个完整的类型列表,还是在别人提示下终于抠出来了,原来给放在Ext.Component当中了。好吧,我承认我没有完整的度过API文档,但是你不觉得API文档应该是一个速查手册么? 好了,不啰嗦了,说一下我遇到的问题。实话实说Extjs的Grid还是很不错的,我现在要实现一个很简单的grid,就是前面的几列都是显示相关内容,但是最后一列显示的是几个动作按钮,比如”查看”、”删除”。相信这些都是非常显而易见的东西吧。但是在extjs当中却无法实现。 我想要的 Name Email Action Tom tom@tom.com View 但是我在extjs当中却无法找到如何实现。因为这个View按钮加不上。看文档,未果;Google之,依然未果。只能祭起最后的绝招了,hack源代码。 Grid有两个可以调整的地方,在ColumnModel里面的renderer和editor,但是通过阅读源代码发现renderer只是针对最基本的值类型的,也就是他只是在最终要显示之前的东西进行一下再包装,但是再包装的结果必须是一个值类型(你可以理解成就是一个字符串),如果不是值类型,那么会调用Object.toString()方法。至于editor属性是当grid的一个cell需要有编辑动作时候提供的一个对当前值的编辑器。他必须是一个Ext.Form.Field的子类,而Button不是Field的子类,故,无法使用。我曾经想通过hack extjs的源代码让他按照类似editor的方法添加一个button,但是发现比较麻烦。是因为extjs的代码写的不错,逻辑很严密,这也就说明如果不能把他的结构了然于胸就很难下手去进行大幅度的修改,而模拟editor添加button这个动作,就算是一个大修改,我放弃了。 既然都不可以,那么怎么办?看来只能使用一些龌龊的招数了。既然renderer只能返回一个文本,而这个文本又是会按照innerHTML塞进Cell中的,那么为何不让她产生一个占位的div,然后在grid render之后再操作这些占位div呢?好想法,很容易实现,但是效果不好,生成的Ext.Button太高,把Cell都撑破了,每个Row都有自己的小滚动条了,真是恶心啊。其实这时候只要能修改一下这个row的css,让她的height再高一些就好了,但是发现extjs无法只修改其中一个css,要改就是整个的css class。作罢。 最后采用连接的形式替换了这个button,很无奈。 总结: Extjs代码很不错,是一个优秀的代码,可以用来学习 Extjs代码逻辑严谨,很多思想跟我以前在Hansky时候写的HFC(Hansky Foundational Component,一套类似Extjs的UI框架)的想法都是一样的,说明我没走错路。 给Extjs的建议 提供对Component每一个style向的精准读取设置功能,最简单的增加一个setStyle/getStyle方法就可以了 提供对Grid的更多的支持,允许renderer返回类型为Mixed,这样可以实现更加丰富的grid展示效果 把文档再写好点吧,求求你了。  

    Mar 4th, 2008 | Filed under extjs
  • 网络安全通讯(3)—-相信你的客户

    在前两篇文章中网络安全通讯(1)—-给你的Webserver启用SSL网络安全通讯(2)—-让别人相信你的服务器我们探讨了如何让你的客户相信你的服务器,这篇文章我们探讨一下你如何去相信你的客户。 在很多场景下,我们是需要关心客户的身份的,一个很安全的做法就是给你的客户发放一个签名的证书,让你的客户拿着证书来,这时候你验证了证书,你也就相信了你的客户。我们可以使用Apache提供的客户端验证(Client Certificate)功能。 生成客户端的私钥和CSR文件openssl genrsa -out client.key 1024openssl req -new -key client.key -out client.csr 用前面我们自己的CA签发客户的证书openssl x509 -req -days 360 -in client.csr -CA ca.crt -CAkey ca.key -CAserial ca.srl -out client.crt 此时客户端的证书已经制作完毕(和制作Server的一样),但是我们的浏览器需要pkcs12格式的文件,所以我们需要签一个pkcs12格式的文件openssl pkcs12 -export -clcerts -in client.crt -inkey client.key -out client.p12 -name your_certificate_client_name这里需要你的client的CSR文件设置的密码,还有your_certificate_client_name替换成你client的名字 打开Apache需要客户验证的设置SSLVerifyClient requireSSLVerifyDepth  1SSLCACertificateFile “/path_to/ca.crt” 重新启动apache,尝试一下访问,此时访问并不成功Firefox会包一个-12227的错误,IE干脆显示不出来,说明客户端验证没有通过 把生成的客户端pkcs12文件导入到浏览器,Firefox Tools->Options->Advanced->Encryption->View Certificates->Your Certificates->ImportIE Tools->Internet Options->Content->Certificates->Personal->Import 再次访问服务器,It works. 此时你的客户端(也就是浏览器)可以通过服务器的验证了。你也可以相信你的客户了。

    Mar 3rd, 2008 | Filed under 安全
    Tags: , ,
  • 网络安全通讯(2)—-让别人相信你的服务器

    上文(网络安全通讯(1)—-给你的Webserver启用SSL)我们讲解了我们如何能够保证我们的服务器和客户端之间的安全通讯。 但是有些时候,用户凭什么相信你呢,你总得想办法证明你的身份吧。该CA(Certificate Authority)出场了,CA是一个大家都相信的第三方,因为你的客户相信CA,而CA又说你(你的服务器)是可以被信任的,那么你的客户就会相信你。所以刚才那个自签名的证书可是不行,你需要ca用他的key给你签个名字,这样别人才相信不是。Q:我们不认识CA怎么办?A:去公认的CA申请啊!Q:难道就我们自己用也要申请?A:好吧,我们可以自己假装自己就是CA,只要大家相信你就好。 我们开始假装CA,创建自己的CA。    1. 建立CA私钥      openssl genrsa -out ca.key 1024   2. 建立自己的CRT文件      openssl req -new -x509 -key ca.key -out ca.crt -days 3600   3. 用自己的CA文件签署刚刚的服务器CSR,生成服务器证书      openssl x509 -req -days 360 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt      注意,这里的参数-CAcreateserial会建立一个serial文件ca.srl,用来记录ca的serial number,如果你已经有了这个文件,那么请使用-CAserial serial_file替换-CAcreateserial参数。   4. 使用新的server.key和server.crt文件,重启apache,再次访问。看一下你的浏览器说什么,是不是此时的Issuer已经是你自己的CA了? 如果你是使用第三方的CA,你就需要把你的server.csr发给他们,然后他们会签一个证书发挥给你的。 此时我们的客户已经相信了你的服务器了。好了本本没电了,明天我们再讨论如何相信你的客户吧。

    Mar 3rd, 2008 | Filed under 安全
  • 网络安全通讯(1)—-给你的Webserver启用SSL

    互联网很危险,你还是回火星吧。好吧,我们还有SSL,你可以等一下了。 先说一下这里面用到的库OpenSSL 0.9.8gApache Httpd 2.2 SSL是一个可以保证你的通讯安全的机制,采用公钥私钥的非对加密机制,具体机制我就不说了,网上一抓一大把。你可以使用openssl建立自己的密钥,并使用在Apache Webserver上,让你的服务器支持https。 建立你自己的服务器私钥,一个1024位的就够了openssl genrsa -des3 -out server.key 1024 生成CSR文件,Certificate Signing Requestopenssl req -new -key server.key -out server.csr 生成证书CRT文件,X509协议openssl x509 -req -in server.csr -signkey server.key -out server.crt注意,这是一个自签名的证书 修改你apache的ssl配置,SSLCertificateFile “/path-to/server.crt”SSLCertificateKeyFile “/path-to/server.key” 启动你的apache,使用https访问试试看,是不是要你确认是否允许证书通过 这时候,你的服务器已经支持SSL了,刚才浏览器问你是否通过你服务器提供的证书是表示客户端(浏览器)信任了你的服务器,这里也就是服务器认证。你们之间的通讯已经是加密的了。

    Mar 2nd, 2008 | Filed under 安全
Archive for March, 2008