TPM 與 ecryptfs

基本都是參考:

另外遇到問題可以參考 IBM 的 troubleshooting,最近 IBM 不知道是網站改版還怎樣,之前留的網址都失聯了,你可以用 ibm ecryptfs troubleshooting 去 google 找。
下面的步驟最好全部以 root 或 sudo 來執行:

  1. 進 BIOS 把 TPM clear 掉
  2. 我的環境正好是用 infineon 的,所以用 modprobe tpm_infineon,一般好像是用 tpm_tis 就行了。
  3. 啟動 trousers:tcsd -f,不用 -f 的話,會掛…這個 daemon 提供 tspi 服務並且與 TPM device 溝通。
  4. 取得 ownership:tpm_takeownership ,這個步驟裡,SRK password 跟其後的 Confirm password 不要輸入!!否則要回到步驟 0 重設。SRK 是 Storage Root Key 的縮寫,不使用密碼保護的原因是為了 ecryptfs 取用方便。
  5. 掛載 ecryptfs:modprobe ecryptfs
  6. 啟動 ecryptfsd
  7. 產生 UUID:ecryptfs-generate-tpm-key -p 1 ,這個 UUID 是提領 key 用的,實際的 key 會透過 PCR 1 的 key 來取得(如果我沒理解錯的話)。

至此,準備工作已經完成,接下來就是操作,這裡我假設 private 是放置要加密的資料的地方:

  1. 先建立:mkdir private
  2. 進行掛載:mount -t ecryptfs private private
  3. 依序回答問題,第一個先選 tspi,第二個問題(cipher)選 aes,第三個問題(key bytes)選 16 bytes,第四個問題(passthrough)選 n,最後問題照預設值。第一個問題是加密方式,你也可以使用其他方式,但這樣就用不到 TPM 了;cipher 跟 key bytes 可以視需要自行調整。這樣就能 mount 上,mount 以後,ecryptfs 會把 UUID 存到 keyring (用 keyctl show 可以看 keyring 內容)裡。

在 private 資料夾裡的操作,基本上不能複寫,只能複製、貼上,但 vim 可編輯。
umount 之前,最好先輸入 mount,把參數記下。
umount 之後,可以直接以參數來掛載,這樣就不用再次回答問題:mount -t ecryptfs -o sig=UUID,ecryptfs_cipher=aes,ecryptfs_key_bytes=16,ecryptfs_passthrough=n private private
參數裡,有個 sig,這個 sig 就是填 UUID,不過你輸入 mount 時,看到的卻不是 UUID,而是一個較短的字串。這字串其實是一個提領 UUID 的鑰匙,ecryptfs 會用這個鑰匙去 keyring 裡(用 keyctl show 可以看到),取出 UUID,再以 UUID 去掛載。keyring 主要存放在 kernel 的某個地方,所以重開機以後就會消失,我還不知道怎麼把 keyring 內容存起來。
好吧,以上就是我這幾天跟 TPM 奮戰的紀錄…

Seed(4) – Database

Seed 也支援對資料庫的存取,目前只支援 SQLite。
用法也超級簡單…
基本上只有 constructor 跟用來執行 SQL 的 exec()。以下代碼來自源碼裡 (modules/sqlite/example.js):
[javascript]
#!/usr/local/bin/seed
Seed.import_namespace(“sqlite”);
d = new sqlite.Database(Seed.argv[2]);
d.exec(“create table t1 (t1key INTEGER PRIMARY KEY,data TEXT,num double,timeEnter DATE);”);
d.exec(“insert into t1 (data,num) values (‘This is sample data’,3);”);
d.exec(“insert into t1 (data,num) values (‘More sample data’,6);”);
d.exec(“insert into t1 (data,num) values (‘And a little more’,9);”);
d.exec(“select * from t1”, function(results){Seed.print(JSON.stringify(results))});
[/javascript]
取出資料的作法則是將 callback 傳入,以處理一筆 record。上面是用 JSON 輸出整筆 record 內容,其實你也可以將欄位名稱代入 indexer 來取得該欄內容:
[javascript]
d.exec(“select * from t1”, function(results){Seed.print(results[“data”])});
[/javascript]

電影流水帳(2009/3/21~2009/3/27)

有隻蟲叫做小明,某天,它跟另一隻蟲,小華,一起往上爬。
爬啊爬~爬到一半時,他們碰到一隻瓢蟲,小明突然笑了起來,小華問他,為甚麼笑呢?
小明說,那是我的點….
後來他們繼續走,又碰到一隻瓢蟲,但這次沒有笑,小華又問啦,為甚麼沒笑呢?
小明說,那不是我的點…
對,這就是我想說的,”送行者:禮儀師的樂章”不是我的點…

  • 停車(IMDB)。有趣,不過還是有點悶的電影。所有的故事都從主角停車之後開始,誰能想到停個車可以被並排停車的人擋那麼久呢?看完電影以後,其實我很想知道後續發展的有:
    • 陳莫回家以後會不會跟小美大吵一架,小孩是否能被認養??
    • 兩個老人日後何去何從??
    • Peggy 演的大陸妹能不能回大陸??最後會是由杜汶澤帶回去嗎??
    • 戴立忍醒了以後,會不會跟納豆去找陳莫算帳??

    不過呢~留下這麼多的想像空間也不錯。

  • おくりびと(IMDB, Wikipedia),中譯:送行者:禮儀師的樂章。劇情很平淡樸實的電影,據說很多人看了都哭了,不過這部片子沒擊中我的哭點。裡面的對白安排的很有趣,故事也說得很好,能得獎是應該的。看完以後,我一直在想,NK辦事處裡的大姐到底跟主角的父母有沒有關係,我認為應該是有些關係的,但是導演可能認為不重要而沒有去說明。另外我還想知道主角的父親到底是為了什麼而離開?留下這個未解的謎團,實在是讓人有點心癢啊~
  • The pursuit of happyness(IMDB, Wikipedia),中譯:當幸福來敲門。跟上面的片子比起來,這部片子倒是擊中了我的哭點,不知道為什麼,對於這種片子,我難以抵擋,記得國中看魯冰花時,還大哭了一場,拼了命地去洗臉,怕被家人知道我哭了。仔細想想,或許是因為小時候我媽曾經帶我去當舖當、贖東西有關,只要想到這種可能的情況,我實在是忍不住。片裡有句話,我印象深刻:”別讓別人跟你說,你作不到,即使是我也不行”,有別讓人看不起的意思。

電影流水帳(2009/3/12~2009/3/20)

我看以後學校很有可能都不用國內出的電腦技術書籍了,都會改用原文或是對岸的書籍。很多不錯的書本來就是翻譯自原文書,這毋庸置疑,但我想說的是,對岸的書籍品質真的越來越不錯~

  • Equilibrium(IMDB, Wikipedia,中譯:重裝任務。整個感覺跟 V 怪客相似,但這部片子是在 V 怪客之前上映的。故事發生在未來,在發生世界大戰以後,為了防止人類情感帶來的災害,強迫每個人都要吃藥以避免情感的波動,同時也銷毀會影響人類情感的一切事物,像音樂、書籍…等等。男主角在經歷過一些事情以後,決意加入反抗軍,進行反抗,最後就是推翻了當政者。裡面男主角修習的槍道很有趣,把功夫揉合開槍,強調利用這功夫可以減少被槍射到的機率,同時可以進行反擊,片子的後半不時可以看到男主角以此功夫幹掉一群人…
  • Perfume: The story of a Murderer(IMDB, Wikipedia),中譯:香水。這是由小說改編的電影,最早看到這故事,應該是在我五專畢業的前後,我在我二妹書桌上看到這本書,稍稍一翻,裡面的故事就吸引了我,讓我用很快的速度看完。事隔了十年,再來看電影,覺得電影拍得不錯,相當忠於原著,不會偏離太多。真的是很好看的電影,在主角要謀殺貴族的女兒時,我心裡甚至已經跟主角站到同一邊,擔心主角會失敗。電影配樂也很不錯,值得一看的電影。

Run Android on VirtualBox/VMWare

有人問了,所以這裡大致整理一下,也算是留下一個記憶(之後沒有要繼續…Orz…)。
事實上,網路上可以找到許多人的文章,根據歸納之後,我發現大多都是從 android-porting 裡的這篇:Howto build Android full source for X86 Architecture like EeePC(ASUS)轉貼來的,所以只要耐心爬完這篇,大致上都沒問題。

  1. 第一步當然是要把 source 拉下來,這個步驟,官方描述得很清楚:Get source (Android Open Source Project),這裡不多作描述。如果你用的是 Ubuntu 8.10,會踩到雷的只有 libreadline5-dev,因為並沒有該頁面描述的 lib32readline5-dev。這裡我假設你跟官方教學步驟一樣,建了 mydroid 目錄。
  2. sync 整份 source code 以後,還需要 eee 701 的部份,所以要在 .repo 下新增一個檔案,並命名為 local_manifest.xml:
    <manifest>
    <project name="platform/vendor/asus/eee_701" path="vendor/asus/eee_701"/>
    </manifest>

    ,然後再 sync 一次。

  3. 這次的 sync 會很快,結束以後,要先 build kernel。切到 mydroid/kernel 目錄下,複製 mydroid/vendor/asus/eee_701/kernel.config 為 mydroid/kernel/.config,接著執行 make menuconfig,進入 kernel configuration 選單以後,把這幾個 driver 選為 built-in:
    • Device drivers / Network device support / Ethernet (10 or 100Mbit) / EISA, VLB, PCI and on board controllers / AMD PCnet32 PCI support
    • Device drivers / Graphics support / Support for frame buffer devices / VESA VGA graphics support
    • Device drivers / Graphics support / Console display driver support / Framebuffer Console support
    • Device drivers / Graphics support / Console display driver support / Select Compiled-in fonts (VGA 8×8 font, VGA 8×16 font)

    ,再把這些取消:

    • Device drivers / Real Time Clock / Android alarm driver
    • Device drivers / Misc devices / Android pmem allocator

    ,然後重新建置 kernel:make bzImage。

  4. 編譯好之後,把 arch/x86/boot/bzImage 複製為 mydroid/vendor/asus/eee_701/kernel。
  5. 我稍稍更動了一些設定,這樣我後面就省打一些東西:
    • vendor/asus/eee_701/BoardConfig.mk:在 BOARD_KERNEL_CMDLINE 加上 vga=788
    • vendor/asus/eee_701/init.eee_701.sh:把 netcfg eth0 dhcp 改為 dhcpcd eth0
  6. 接著就是建置 image 了,這裡是我用的 script,把以下內容存為 build.sh,並放在 mydroid 下:
    #!/bin/bash
    cp kernel/arch/x86/boot/bzImage vendor/asus/eee_701/kernel
    mkdir -p out/target/product/eee_701/data/
    cp kernel/arch/x86/boot/bzImage out/target/product/eee_701/kernel
    TARGET_ARCH=x86 TARGET_PRODUCT=eee_701 DISABLE_DEXPREOPT=true make -j2 installer_img
    

    ,執行前別忘了 chmod +x 。

  7. 建置完以後,你會在 out/target/product/eee_701 下找到 installer.img。
  8. 把 installer.img 轉為 VirtualBox/VMWare 可用的 disk image,這邊要利用 VirtualBox 的 vboxmanage 來轉:vboxmanage convertfromraw -format vdi installer.img installer.vdi,如果你用 VMWare,則是:vboxmanage convertfromraw -format vmdk installer.img installer.vmdk
  9. 建置新的 VM,設置為 Linux kernel 2.6,256M 的 RAM,以及一個超過 2G 的硬碟。然後把上個步驟轉好的 disk image 加為第二個儲存裝置。
  10. 接下來,我只以 VirtualBox 為例,因為我沒試過 VMWare,不過原理一樣。將這個 VM 開機,一開機馬上按 F12,選擇從第二個儲存裝置開機。一開機,你會看到 grub 的開機選單,趕緊按下任意鍵,因為這邊要修改一下,預設 Loader 的開機磁碟是 hd(0,0),你要按 e 進行修改,把 hd(0,0) 改為 hd(1,0),再按 b 繼續開機(如果你不熟 grub,麻煩熟悉,這邊我不多說)。開機以後,就會開始進行安裝的動作,Android 會安裝到第一個磁碟上去,這個步驟要等一陣子,如果有錯誤,再重複一次即可,根據我的經驗,有時候會因為切割磁碟失敗而停止安裝,但再從第二個磁碟開機安裝一次,通常即可解決。安裝完成不會有什麼訊息,但看一下畫面上訊息,你應該可以知道已經完成,輸入 reboot 重新開機。
  11. 最後就大功告成啦~接著你可以移除第二個磁碟,因為再也用不到啦~

最後的最後,希望我沒有遺漏~
android

Seed(3) – Glade

純手工寫 UI 實在是很苦,還好有 Glade,你可以用 Glade 設計出介面以後,再用 Seed 把事件指派一下就可以完成一個程式了。這裡假設你已經用 Glade 設計出畫面,把主要的視窗命名為 window1,並且存為 glade-1.glade。存好以後,要使用 gtk-builder-convert 把 .glade 轉為 .xml。

gtk-builder-convert glade-1.glade glade-1.xml

接著就可以寫 code 了:

#!/usr/bin/env seed
// First, you need to use gtk-builder-convert to convert glade to xml.
// gtk-builder-convert glade-1.glade glade-1.xml
// Import libraries that are used by the program
Seed.import_namespace("Gtk");
// Initialize GTK+
Gtk.init(null, null);
var ui = new Gtk.Builder();
ui.add_from_file("glade-1.xml");
var window = ui.get_object("window1");
window.signal.hide.connect(Gtk.main_quit);
// Start the main GTK+ loop and initiate the program
Gtk.main();

參考資料:Desktop Linux Applications with Javascript

電影流水帳(2009/2/28~2009/3/11)

這兩天感冒了,由於鼻子的關係,除了流鼻水以外,眼淚也不爭氣地一直流下~超難過的。
看來今天以前是不會好起來,晚上要去看醫生,用西藥來擋一陣。

  • The Number 23(IMDB, Wikipedia),中譯:靈異23。精神病患者的故事,由於家族病史,對 23 特別執著,執著的結果,使得他殺人,並決定自殺,自殺前寫自白書,卻不知不覺地寫成小說,寫完的末了,自殺失敗,喪失記憶,進了精神病院。痊癒以後,忘了之前的事情,展開新生活。但卻在十幾年後,他的太太看到了這本書並買下來,他一開始看,就發現書裡的遭遇跟自己非常雷同,於是展開一連串的追尋,最後發現自己真的就是主角。驚悚小說,電影採倒敘法,不用倒敘法的話,看起來大概就沒意思了吧~
  • Get SMart(IMDB, Wikipedia),中譯:特務行不行。還不錯的電影,笑點不多,但可以接受。感覺上主角並不糊塗啊,他只是比較一板一眼,開槍、打鬥可是一點都不含糊。

new()

昨天有同事問到可不可以讓物件 new 在 share memory 裡面,我跟他說 c++ 的 new 可以像下面例子這樣用,但是他後來沒試。好吧,反正我以前也沒試過,就寫了個小程式試一下:

/**
*       Filename:  test_new.cpp
*    Description:  Test new(storage) Person();
*/
#include <cstdlib>
#include <string>
#include <iostream>
class Person {
public:
Person() {}
~Person() {}
std::string getName() { return _name; };
void setName( std::string name ) { _name=name; }
std::string toString() { return _name; }
private:
std::string _name;
};
int main( int argc, char* argv[] ) {
char* storage = (char*)malloc( 1024 ); // allocate 1K
Person* person = new(storage) Person();
person->setName( "anonymous" );
std::cout << person->toString() << std::endl;
// if just storage, person will be replaced by intArray. (2)
// int* intArray = new(storage) int[10];
int* intArray = new(storage+sizeof(person)) int[10];
int i=0;
// assign value.
for( i=0; i<10; i++ )
intArray[i] = i;
// show the values
for( i=0; i<10; i++ )
printf( "%d ", intArray[i]);
printf("\n");
// dump storage
char* iter=storage;
printf("=== begin dump ===\n");
i=0;
while( i!=512 ) {
printf( "%02x ", (unsigned char)*iter );
iter++;
i++;
if( !(i%16) )
printf( "\n" );
}
printf("=== end dump ===\n");
printf( "person address = %08x intArray address = %08x\n",
(unsigned int)person, (unsigned int)intArray );
// cannot delete, it cause segmentation fault. (1)
//delete person;
//delete[] intArray;
// but we can use free.
free( storage );
}

結論:

  1. new(storage) Person() 實際上是 new 在 storage 這塊空間裡面,所以之後如果呼叫 delete,會出錯。
  2. 如果不累加 storage 的話,會把之前配置的空間覆蓋掉。
  3. malloc() 可以用 shmget()、shmat() 代替,沒有問題。
  4. 以上面的例子,std::string 會配置一塊空間來放字串,這塊空間並不在 storage 裡面,使用時要注意。如果要這樣用,應該要再取代掉 STL allocator 的機制。

amr 轉 mp3

環境:Ubuntu 8.10

  1. 安裝必要的套件:
    sudo apt-get install amrnb sox lame
  2. 輸入以下指令:
    amrnb-decoder file.amr file.raw # 先轉成 raw 檔
    sox -r 8000 -w -c 1 -s file.raw -r 16000 -w -c 1 file.wav # 再轉為 wav
    lame babycry.wav babycry.mp3 # 最後轉為 mp3
    

整理一下,把它作成 script:

#!/bin/bash
# amr2mp3.sh
FILE=`basename $1 .amr`  # remove .amr
amrnb-decoder $1 $FILE.raw
sox -r 8000 -w -c 1 -s $FILE.raw -r 16000 -w -c 1 $FILE.wav
lame $FILE.wav $FILE.mp3
rm -f $FILE.raw $FILE.wav
exit 0

收工。

參考自Aquarionics 的 blog:How to convert AMR files to MP3

pam_smbpass.so

安裝 samba 以後,讓 samba 密碼跟 linux 密碼一致的好方法,先安裝 libpam-smbpass,然後執行 sudo pam-auth-update,把 SMB password synchronization 選起來即可。以後改密碼時,samba 密碼也會自動被更改。
對了,我的 linux 是 ubuntu 8.10,samba security level 是 user,安裝以後有先利用 smbpasswd -a 把必要的使用者加進去。