最新发表

Magento special价格无法关掉的bug

Magento的代码是在是太难跟踪了,看得头晕脑胀。只好从数据库入手,在其官网上找到一帮同病相怜的人:

http://www.magentocommerce.com/boards/viewthread/14039/

根据文章的提示:

To clear out the sticky ‘special’ products, you’ll need to erase the contents of tables ‘catalogrule_product_price’ and ‘catalogrule_product’. That worked for me as I was able to detect where the problem was.

清除掉catalogrule_product_price和catalogrule_product,然后后台刷新页面缓存问题就解决了。

devstack安装openstack-nova遇到mysql无法执行rename操作

遇到

Engine(mysql://root:xxx@localhost/nova) from (pid=8177) with_engine /usr/lib/python2.7/dist-packages/migrate/versioning/util/__init__.py:162

mysql报下面的错误

"Error on rename of './nova/#sql-19b6_2b' to './nova/instance_actions' (errno: 150)") '\nALTER TABLE instance_actions DROP COLUMN instance_id' ()

用错误信息在弱爆的bing搜不到任何信息,用google一下,在lunchpad的nova项目里找到这个bug 原因:(https://bugs.launchpad.net/nova/+bug/904888)说是由于ubuntu的mysql升级5.5后默认的存储引擎变成了innodb了,innodb删除列之前需要先删除外键导致整个错误。安装连接里的说明,这个bug已经在2011年的12月15日修复了,不知道为何我今天git clone下最新版的还有这个问题。实在懒得去自己hack代码了,还是直接修改mysql的默认存储引擎为MyISAM方便写,修改:

/etc/mysql/my.cnf

在[mysqld]段添加一行

default-storage-engine=MyISAM

重启mysql,然后在重新执行stack.sh就可以解决问题了

ubuntu设置静态ip

ubuntu火了很久了,因为公司已经选择centos作为标准,所以也没有花精力去学习这一个发行版本。无奈现在openstack发展的如火如荼,而openstack在ubuntu下有良好的支持,自动化安装配置openstack脚本devstack也是在ubuntu上支持的好。关注openstack这么久,不装一套测试实在是不安,于是安装了最新版的ubuntu 12测试版。安装完毕后一般是设置一个静态ip,方便远程登录管理,静态ip设置方法和centos不太一样,现记录如下:
编辑文件:/etc/network/interfaces

1
2
3
4
5
6
7
auto eth0 
iface eth0 inet static 
address 192.168.0.109 
gateway 192.168.0.1 
netmask 255.255.255.0 
network 192.168.0.0 
broadcast 192.168.0.255

这样,IP并没有立即生效。

1
sudo /etc/init.d/networking restart

当我们使用vim编辑类似于/etc/network/interfaces这样的文件的时候总是会遇到权限问题不能保存,原因是所有的配置文件的权限只属于root。 那么怎样直接以root权限直接vim这些文件?
方法是:
结合sudo和tee两个命令来实现:

1
w !sudo tee %

解释如下:
:w – Write a file.
!sudo – Call shell sudo command.
tee – The output of write (vim :w) command redirected using tee.
% – is nothing but current file name

Unix目录结构的来历(RT)

Unix(包含Linux)的初学者,常常会很困惑,不明白目录结构的含义何在。

举例来说,根目录下面有一个子目录/bin,用于存放二进制程序。但是,/usr子目录下面还有/usr/bin,以及/usr/local/bin,也用于存放二进制程序;某些系统甚至还有/opt/bin。它们有何区别?

长久以来,我也感到很费解,不明白为什么这样设计。像大多数人一样,我只是根据《Unix文件系统结构标准》(Filesystem Hierarchy Standard),死记硬背不同目录的区别。

昨天,我读到了Rob Landley的简短解释,这才恍然大悟,原来Unix目录结构是历史造成的。

话说1969年,Ken ThompsonDennis Ritchie在小型机PDP-7上发明了Unix。1971年,他们将主机升级到了PDP-11。

当时,他们使用一种叫做RK05的储存盘,一盘的容量大约是1.5MB。

没过多久,操作系统(根目录)变得越来越大,一块盘已经装不下了。于是,他们加上了第二盘RK05,并且规定第一块盘专门放系统程序,第二块盘专门放用户自己的程序,因此挂载的目录点取名为/usr。也就是说,根目录”/”挂载在第一块盘,”/usr”目录挂载在第二块盘。除此之外,两块盘的目录结构完全相同,第一块盘的目录(/bin, /sbin, /lib, /tmp…)都在/usr目录下重新出现一次。

后来,第二块盘也满了,他们只好又加了第三盘RK05,挂载的目录点取名为/home,并且规定/usr用于存放用户的程序,/home用于存放用户的数据。

从此,这种目录结构就延续了下来。随着硬盘容量越来越大,各个目录的含义进一步得到明确。

  /:存放系统程序,也就是At&t开发的Unix程序。

  /usr:存放Unix系统商(比如IBM和HP)开发的程序。

  /usr/local:存放用户自己安装的程序。

  /opt:在某些系统,用于存放第三方厂商开发的程序,所以取名为option,意为”选装”。

(完)

农行支付接口的PHP实现

概述

农行的支付网关提供了PHP的开发说明和相关的程序包。它是利用webservice实现php和java的TrustPayClient提供服务的交互。由于webservice需要运行在tomcat,无法跟php常见的lamp运行环境合用,增加的系统的复杂度,无论从开发还是维护上看都是不好的。还好农行的java包是做到非常棒的,所有关键点都做log4j做了记录,我们可以根据它的log文件得到它提交和返回的数据报文。我们从log中可以看到农行是采用SHA1withRSA的算法对数据进行签名和验签。用SHA1withRSA算法在php中我们可以用openssl扩展的openssl_sign()和openssl_verify()实现。下面详细说明如何用openssl简化农行接口的开发工作。
提交

发起交易的数据格式是这样的

1
<MSG><Message><Merchant><ECMerchantType>B2C</ECMerchantType><MerchantID>233010300330A01</MerchantID></Merchant><TrxRequest><TrxType>PayReq</TrxType><Order><OrderNo>ON200306300001</OrderNo><OrderAmount>280.0</OrderAmount><OrderDesc>Game Card Order</OrderDesc><OrderDate>2003/11/12</OrderDate><OrderTime>23:55:30</OrderTime><OrderURL>http://127.0.0.1/Merchant/MerchantQueryOrder.jsp?ON=ON200306300001&QueryType=1</OrderURL><OrderItems><OrderItem><ProductID>IP000001</ProductID><ProductName>中国移动IP卡</ProductName><UnitPrice>100.0</UnitPrice><Qty>1</Qty></OrderItem><OrderItem><ProductID>IP000002</ProductID><ProductName>网通IP卡</ProductName><UnitPrice>90.0</UnitPrice><Qty>2</Qty></OrderItem></OrderItems></Order><ProductType>1</ProductType><PaymentType>1</PaymentType><NotifyType>0</NotifyType><ResultNotifyURL>http://127.0.0.1/Merchant/MerchantResult.jsp</ResultNotifyURL><MerchantRemarks>Hi!</MerchantRemarks><PaymentLinkType>1</PaymentLinkType></TrxRequest></Message><Signature-Algorithm>SHA1withRSA</Signature-Algorithm><Signature>nfJAveUtLG1YHqsjUdopB8Jl9QX4ZtlQrUn+HoiCy0yS9An19z5IxTIVYOuQXjNnbMGgmZlCwK3dSSnRTLHxZMC3zJUiE58qEwxatOgHNFUhAHTBxkUMO5ikC7C5qm/9L67/Xp7kYvHK9Fo/8CyXckROb+w+eLYcPaYo6+Of2Dg=</Signature></MSG>

数据有以下几部分构成

1
<MSG><Message>订单信息</Message><Signature-Algorithm>SHA1withRSA</Signature-Algorithm><Signature>订单信息的签名</Signature></MSG>

订单信息的构造参考:

1
<Merchant><ECMerchantType>B2C</ECMerchantType><MerchantID>233010300330A01</MerchantID></Merchant><TrxRequest><TrxType>PayReq</TrxType><Order><OrderNo>ON200306300001</OrderNo><OrderAmount>280.0</OrderAmount><OrderDesc>Game Card Order</OrderDesc><OrderDate>2003/11/12</OrderDate><OrderTime>23:55:30</OrderTime><OrderURL>http://127.0.0.1/Merchant/MerchantQueryOrder.jsp?ON=ON200306300001&QueryType=1</OrderURL><OrderItems><OrderItem><ProductID>IP000001</ProductID><ProductName>中国移动IP卡</ProductName><UnitPrice>100.0</UnitPrice><Qty>1</Qty></OrderItem><OrderItem><ProductID>IP000002</ProductID><ProductName>网通IP卡</ProductName><UnitPrice>90.0</UnitPrice><Qty>2</Qty></OrderItem></OrderItems></Order><ProductType>1</ProductType><PaymentType>1</PaymentType><NotifyType>0</NotifyType><ResultNotifyURL>http://127.0.0.1/Merchant/MerchantResult.jsp</ResultNotifyURL><MerchantRemarks>Hi!</MerchantRemarks><PaymentLinkType>1</PaymentLinkType></TrxRequest>

整体上由Merchant商户信息段和TrxRequest请求信息段,两部分构成。

Signature是采用SHA1withRSA对订单信息进行签名在base64 encode后得到,在php中可以用openssl实现。参考代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
 
$cert_file = "D:/user.pem";
$password = '666666';
 
$signature = null;
$toSign = "<Merchant><ECMerchantType>B2C</ECMerchantType><MerchantID>233010300330A01</MerchantID></Merchant><TrxRequest><TrxType>PayReq</TrxType><Order><OrderNo>ON200306300001</OrderNo><OrderAmount>280.0</OrderAmount><OrderDesc>Game Card Order</OrderDesc><OrderDate>2003/11/12</OrderDate><OrderTime>23:55:30</OrderTime><OrderURL>http://127.0.0.1/Merchant/MerchantQueryOrder.jsp?ON=ON200306300001&QueryType=1</OrderURL><OrderItems><OrderItem><ProductID>IP000001</ProductID><ProductName>中国移动IP卡</ProductName><UnitPrice>100.0</UnitPrice><Qty>1</Qty></OrderItem><OrderItem><ProductID>IP000002</ProductID><ProductName>网通IP卡</ProductName><UnitPrice>90.0</UnitPrice><Qty>2</Qty></OrderItem></OrderItems></Order><ProductType>1</ProductType><PaymentType>1</PaymentType><NotifyType>0</NotifyType><ResultNotifyURL>http://127.0.0.1/Merchant/MerchantResult.jsp</ResultNotifyURL><MerchantRemarks>Hi!</MerchantRemarks><PaymentLinkType>1</PaymentLinkType></TrxRequest>";
 
// $toSign签名后的数据应该是nfJAveUtLG1YHqsjUdopB8Jl9QX4ZtlQrUn+HoiCy0yS9An19z5IxTIVYOuQXjNnbMGgmZlCwK3dSSnRTLHxZMC3zJUiE58qEwxatOgHNFUhAHTBxkUMO5ikC7C5qm/9L67/Xp7kYvHK9Fo/8CyXckROb+w+eLYcPaYo6+Of2Dg=
 
$fp = fopen($cert_file, "rb");
$priv_key = fread($fp, 8192);
fclose($fp);
//获取pem文件中的私钥
$pkeyid = openssl_get_privatekey($priv_key,$password);
//使用用户私钥对消息进行签名
openssl_sign($toSign, $signature, $pkeyid);
// Free the key.
openssl_free_key($pkeyid);
 
$b64 = base64_encode( $signature );
echo $b64;
 
?>

代码中用到的user.pem由农行网银后台下载的pfx或则p12文件转换而已,pfx转pem文件的方法是:

1
openssl pkcs12 -nocerts -nodes -in cert.p12 -out user.pem

返回

返回的数据是POST回来的key为msg,内容是用base64编码过的:

1
PE1TRz48TWVzc2FnZT48VHJ4UmVzcG9uc2U+PFJldHVybkNvZGU+MDAwMDwvUmV0dXJuQ29kZT48RXJyb3JNZXNzYWdlPjwvRXJyb3JNZXNzYWdlPjxFQ01lcmNoYW50VHlwZT5CMkM8L0VDTWVyY2hhbnRUeXBlPjxNZXJjaGFudElEPjIzMzAxMDMwMDMzMEEwMTwvTWVyY2hhbnRJRD48VHJ4VHlwZT5QYXlSZXN1bHQ8L1RyeFR5cGU+PE9yZGVyTm8+MTI5ODk1ODQyNTMxODU8L09yZGVyTm8+PEFtb3VudD4wLjAzPC9BbW91bnQ+PEJhdGNoTm8+MDAwMDAxPC9CYXRjaE5vPjxWb3VjaGVyTm8+MDAwMDEyPC9Wb3VjaGVyTm8+PEhvc3REYXRlPjIwMTEvMDMvMDE8L0hvc3REYXRlPjxIb3N0VGltZT4xMzozNjozMDwvSG9zdFRpbWU+PE1lcmNoYW50UmVtYXJrcz5IaSE8L01lcmNoYW50UmVtYXJrcz48UGF5VHlwZT5QQVkwMTwvUGF5VHlwZT48Tm90aWZ5VHlwZT4wPC9Ob3RpZnlUeXBlPjxQYXlJUD42MC4xOTAuNzMuMTIyPC9QYXlJUD48UGF5UmVmZXJlcj5sdXNlbi52aXAuaXNob3BleC5jbjwvUGF5UmVmZXJlcj48aVJzcFJlZj4zNjAzMDExMzkxNTM8L2lSc3BSZWY+PC9UcnhSZXNwb25zZT48L01lc3NhZ2U+PFNpZ25hdHVyZS1BbGdvcml0aG0+U0hBMXdpdGhSU0E8L1NpZ25hdHVyZS1BbGdvcml0aG0+PFNpZ25hdHVyZT5MM0VlQW1yMTdPYTloaHVxU0E5NEFXSEVhVjN5RnFOTHZZQ29qem0xVm5PMWtMSnVhVkZTekdyV0Y3NjhPMUtMelBaY1M1MVFMRko1dUFMUlFtUVM1Ylp3Tm5kZ1FHeUxPZGRaMUpjRGdjazh3RE9UYkJPSTJFQWRhdElGL0czR1QrRENoRkVyVlZMR01oa1VGRTRpVTVrM3YvdXMwM3pZQ1UxbUR4SzFtbGM9PC9TaWduYXR1cmU+PC9NU0c+

base64解码后是这样:

1
2
3
4
5
6
7
8
9
10
11
<MSG><Message><TrxResponse><ReturnCode>0000</ReturnCode><ErrorMessage></ErrorMes
sage><ECMerchantType>B2C</ECMerchantType><MerchantID>233010300330A01</MerchantID
><TrxType>PayResult</TrxType><OrderNo>12989584253185</OrderNo><Amount>0.03</Amou
nt><BatchNo>000001</BatchNo><VoucherNo>000012</VoucherNo><HostDate>2011/03/01</H
ostDate><HostTime>13:36:30</HostTime><MerchantRemarks>Hi!</MerchantRemarks><PayT
ype>PAY01</PayType><NotifyType>0</NotifyType><PayIP>60.190.73.122</PayIP><PayRef
erer>lusen.vip.ishopex.cn</PayReferer><iRspRef>360301139153</iRspRef></TrxRespon
se></Message><Signature-Algorithm>SHA1withRSA</Signature-Algorithm><Signature>L3
EeAmr17Oa9hhuqSA94AWHEaV3yFqNLvYCojzm1VnO1kLJuaVFSzGrWF768O1KLzPZcS51QLFJ5uALRQm
QS5bZwNndgQGyLOddZ1JcDgck8wDOTbBOI2EAdatIF/G3GT+DChFErVVLGMhkUFE4iU5k3v/us03zYCU
1mDxK1mlc=</Signature></MSG>

我们需要对Message段的数据进行和Signature段的数据进行验签。同提交请求时一样,php有openssl_verify这个函数可以对农行提交过来的数据进行验证。测试用例见下文:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php
 
$ret = array (
  'MSG' => 'PE1TRz48TWVzc2FnZT48VHJ4UmVzcG9uc2U+PFJldHVybkNvZGU+MDAwMDwvUmV0dXJuQ29kZT48RXJyb3JNZXNzYWdlPjwvRXJyb3JNZXNzYWdlPjxFQ01lcmNoYW50VHlwZT5CMkM8L0VDTWVyY2hhbnRUeXBlPjxNZXJjaGFudElEPjIzMzAxMDMwMDMzMEEwMTwvTWVyY2hhbnRJRD48VHJ4VHlwZT5QYXlSZXN1bHQ8L1RyeFR5cGU+PE9yZGVyTm8+MTI5ODk1ODQyNTMxODU8L09yZGVyTm8+PEFtb3VudD4wLjAzPC9BbW91bnQ+PEJhdGNoTm8+MDAwMDAxPC9CYXRjaE5vPjxWb3VjaGVyTm8+MDAwMDEyPC9Wb3VjaGVyTm8+PEhvc3REYXRlPjIwMTEvMDMvMDE8L0hvc3REYXRlPjxIb3N0VGltZT4xMzozNjozMDwvSG9zdFRpbWU+PE1lcmNoYW50UmVtYXJrcz5IaSE8L01lcmNoYW50UmVtYXJrcz48UGF5VHlwZT5QQVkwMTwvUGF5VHlwZT48Tm90aWZ5VHlwZT4wPC9Ob3RpZnlUeXBlPjxQYXlJUD42MC4xOTAuNzMuMTIyPC9QYXlJUD48UGF5UmVmZXJlcj5sdXNlbi52aXAuaXNob3BleC5jbjwvUGF5UmVmZXJlcj48aVJzcFJlZj4zNjAzMDExMzkxNTM8L2lSc3BSZWY+PC9UcnhSZXNwb25zZT48L01lc3NhZ2U+PFNpZ25hdHVyZS1BbGdvcml0aG0+U0hBMXdpdGhSU0E8L1NpZ25hdHVyZS1BbGdvcml0aG0+PFNpZ25hdHVyZT5MM0VlQW1yMTdPYTloaHVxU0E5NEFXSEVhVjN5RnFOTHZZQ29qem0xVm5PMWtMSnVhVkZTekdyV0Y3NjhPMUtMelBaY1M1MVFMRko1dUFMUlFtUVM1Ylp3Tm5kZ1FHeUxPZGRaMUpjRGdjazh3RE9UYkJPSTJFQWRhdElGL0czR1QrRENoRkVyVlZMR01oa1VGRTRpVTVrM3YvdXMwM3pZQ1UxbUR4SzFtbGM9PC9TaWduYXR1cmU+PC9NU0c+',
);
 
$msg = base64_decode($ret['MSG']);
 
preg_match("/\<Message\>(.*)\<\/Message\>.*\<Signature\>(.*)\<\/Signature\>/i",$msg,$match);
$contents = $match[1];
$signature = $match[2];
 
$pub_cert_file = "TrustPay.pem";
verify($contents,$signature,$pub_cert_file );          
 
function verify($data,$signature,$cert_file){
    $fp = fopen($cert_file, "r");
    $cert = fread($fp, 8192);
    fclose($fp);
    $pubkeyid = openssl_get_publickey($cert);
    $signature = base64_decode($signature);
    // state whether signature is okay or not
    $ok = openssl_verify($data, $signature, $pubkeyid);
    openssl_free_key($pubkeyid);
    return $ok;
}
 
?>

代码中TrustPay.pem可以这么生成

1
openssl x509 -inform DER -in TrustPay.cer  -out TrustPay.pem

-EOF-

mysql服务器被挂马

一台mysql在系统重启后突然起不来了,冲上服务器,手工启动后发现错误日志里有这样的信息:


120120 12:00:41 [ERROR] Can't open shared library 'amd.dll' (errno: 0 )
120120 12:00:41 [ERROR] Can't open shared library '360.dll' (errno: 0 )
120120 12:00:41 [ERROR] Can't open shared library 'CHS.dll' (errno: 0 )

根据dll的名字判断以为是360升级后导致冲突的,就不以为意。但是过不了三分钟,mysql又挂了!冲上mysql控制台执行下面的命令:


mysql> select * from func;
+----------+-----+---------+----------+
| name | ret | dl | type |
+----------+-----+---------+----------+
| cmdshelv | 0 | amd.dll | function |
| piaoyaoc | 0 | 360.dll | function |
| cmdsheln | 0 | CHS.dll | function |
+----------+-----+---------+----------+
3 rows in set (0.00 sec)

这三个dll太可疑了,而且应用也没有用到自定义dll函数这么高级的功能,mysql可以加载dll函数的功能实在是太无耻了,于是干掉之,执行:


mysql> delete from func where dl in ('amd.dll','360.dll','CHS.dll');
Query OK, 3 rows affected (0.00 sec)

干掉了三个注册函数。怀疑是系统被挂马了,杀毒软件扫了一下,果然发现了一些木马,杀之,重启后正常。再检查一下应用的配置文件,发现是用root在跑的,难怪会被利用,改用一个低权限帐号运行应用,从此以后不应该再有这种麻烦事儿了。

 

无觅相关文章插件,快速提升流量