2011年5月29日 星期日

Android 開發筆記 - 使用 Facebook SDK

android-fb


在 Android 上使用 Facebook SDK 比在 iOS 上麻煩了一點,也算是安全性在高了一點點。


相關資料:



細節:


所有操作流程可以在 Facebok Developer - Mobile Apps 找到。發布 Android apk 時,將拿著一把鑰匙進行簽名的動作,因此在 Facebook Developer 頁面上,可以填寫用哪一把 key 作簽名,代表只有使用此把 key 簽名的 app 才能使用你的 Facebook api key 進行存取。


例如 OAuth 的使用是要有一對 key-pair 的,使用時一把擺在 server site ,另一把擺在 client 端使用,但要用在 Mobile 端時就會很不安全,因為兩把 key 都會寫在 app 裡,變相就是都存在 client 端。以 iOS 來說,雖然編譯的成果是 binary 檔案,但用特殊工具還是可以設法找到字串,不一會兒兩把 key 就被拿到了!至於Android 上可以參考 Android 開發教學筆記 - 關於反組譯 Android 程式,還真的不用 30 秒就搞定!只需幾個步驟就把 apk 檔打開將程式碼看個清楚了,更別說兩把 key 在哪 XD


在 Facebook 上頭,對 Android 來說,需使用簽署 apk 的資訊跟 Facebook api key 共兩個資訊,在 iOS 則是使用 Facebook api key 而已。在 app 裡存放 facebook api key 的缺點是存在被別人盜用的機會,所以在 Android 上算是相對安全一點點點點,因為還包含簽署的 apk 資訊。


所需的軟體:



流程:


開啟 Eclipse 後,先把下載的 facebook-android-sdk 匯入


[File] -> [New] -> [Projeect] -> [Android Project] -> Create project from existing source ,此例是  C:\facebook-facebook-android-sdk-5d44d0c\facebook ,並按 Finish 結束


facebok_sdk_lib


建立 FB Test Project,版本應該可以隨意,在此使用 Android 2.2 版:


fb_test


並且設定編譯時使用 facebook-android-sdk:


點選 Project 後,選 [Project] -> [Properties] -> [Android] -> [Library] -> 透過 Add 新增 com_facebook_android


com_facebook_sdk


撰寫相關測試的程式碼:


package com.test.fb;

import android.app.Activity;
import android.os.Bundle;
import com.facebook.android.*;
import com.facebook.android.Facebook.*;


public class FB extends Activity {
    private Facebook facebook = new Facebook("Your_Facebook_API_Key");
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        facebook.authorize( this, new DialogListener(){
@Override
public void onComplete(Bundle values) {
// TODO Auto-generated method stub
}
@Override
public void onFacebookError(FacebookError e) {
// TODO Auto-generated method stub
}
@Override
public void onError(DialogError e) {
// TODO Auto-generated method stub
}
@Override
public void onCancel() {
// TODO Auto-generated method stub
}
        });

    }
}


設定 AndroidManifest.xml 新增 android.permission.INTERNET 權限:


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.test.fb"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-permission android:name="android.permission.INTERNET"></uses-permission>
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".FB"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>


上述就是程式碼的設定部分,只是編譯完跑在模擬器上,只會顯示一下下 Loading 的頁面,就結束了,主因是還未設定對應的 key:


facebook_test_not_ready


接著進行設定 Facebook API Key 的使用,須到 Facebook Developer 頁面上,對你自己新增的 Facebook App 新增 Android Hash Key:


facebook_key_hash


至於新增 Android Hash Key 的方式,主要參考簽署 apk 所用的 key ,假設沒有特別設定,那預設數值可以在 Eclipse -> [Windpw] -> [Preferences] -> [Build] 查看到 Default debug keystore 資訊,預設是在 C:\Users\id\.android\debug.keystore 位置 (Win 7) ,並且在 Signing Your Applications | Android Developers 可得知預設的資訊:


Keystore name: "debug.keystore"
Keystore password: "android"
Key alias: "androiddebugkey"
Key password: "android"
CN: "CN=Android Debug,O=Android,C=US"


所以,接著須要使用 kyetool 和 openssl 來建立 Android Hash Key 啦,我把 openssl 解壓縮在 C:\openssl\bin\openssl.exe 裡頭,連續動作:


"C:\Program Files\Java\jdk1.6.0_25\bin\keytool.exe" -exportcert -alias androiddebugkey -keystore C:\Users\id\.android\debug.keystore | | C:\openssl\bin\openssl.exe sha1 -binary | C:\openssl\bin\openssl.exe base64


輸入 keystore 密碼:android


就會產生一組 Android Hash Key,例如 dsfDFjakldEajdlfad+ha783j4g= 這種訊息,把它填入 Facebook App 之 Android Hash Key 欄位即可。


補充一下,如果你使用的 keystore 是自己產生的,那請自行更改對應的位置,以及使用 Custom debug keystore 吧( Eclipse -> [Windpw] -> [Preferences] -> [Build] ),不然就是建立 Android apk 時,改成手動簽名,相關資訊:


建立自己的 apk-key:


"C:\Program Files\Java\jdk1.6.0_25\bin\keytool.exe" -genkey -v -keystore C:\Path\your-apk-key.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 10000


並填寫相關資訊


手動 apk 簽名:


"C:\Program Files\Java\jdk1.6.0_25\bin\jarsigner.exe" -verbose -keystore C:\Path\your-apk-key.keystore C:\Users\id\workspace\YourProject\bin\YourProject.apk your_alias_name


手動安裝 apk:


"C:\Program Files (x86)\Android\android-sdk\platform-tools" install C:\Users\id\workspace\YourProject\bin\YourProject.apk


若軟體已存在,則使用 -r 指令重裝:


"C:\Program Files (x86)\Android\android-sdk\platform-tools" install -r C:\Users\id\workspace\YourProject\bin\YourProject.apk


最後,如果運行的結果還是沒有呈現出來,請參考 Android 開發教學筆記 - 模擬器無法建立網路連線 這篇,去新增 dns-server 資訊。可以在 onError 裡,使用 TextView 把錯誤訊息印出來:


com.facebook.android.DialogError: The Connection to the server was unsuccessful.


fb test error


Android 開發筆記 - 模擬器無法建立網路連線

android no network


在測試 Facebook Android SDK 時,發現程式無法建立網路連線,接著用 Browser 嘗試網路連線,才發現連 Browser 也連不出去。


網路上找一下資訊,一種是在模擬器視窗上按 F8 (Windows平台),即可啟動網路連線,這時候右上方會顯示 3G 圖示:


android 3g


但是,有時還是無法連上網,這時候就可以設定模擬器的 DNS 資訊:


[Run] -> [Run Configurations] -> [Android Application] -> [Your Project Name] -> [Target]


Additional Emulator Command Line Options 填寫 -dns-server 8.8.8.8,8.8.4.4 即可


android add dns


調完記得把模擬器關掉再重跑,就可以連上網路:


android 3g testing


2011年5月27日 星期五

[Linux] VNC + SSH Tunnel + iptables @ Ubuntu 10.04 desktop

由於要上課的關係且手邊的筆電只有 EEE PC 等級,課程卻是要開 Eclipse 跑 Android 模擬器,故選用了遠端桌面啦,但 Ubuntu 的遠端桌面不太好用?!不曉得可能是因為我不太懂,每次啟動 VNC 時,除了本機端不能 logout 外,且 VNC 好像也不是加密連線?


簡單的說,當 Ubuntu desktop 要開啟遠端連線時,遠端看到的畫面就目前本機端看到的,所以不能 logout ,因為 logout 的話,遠端也是看到一樣的畫面 XD 我記得 Ubuntu 裡頭有 "遠端桌面" 跟 "遠端登入",我猜我可能有些誤解,印象中以前有用過遠端登入使用 X-Window 的說。


至於在 Ubuntu 上使用遠端桌面且希望加密的解法,就是使用 SSH Tunnel ,讓所有連線內容都走 SSH 加密連線。而 iptables 是 Ubuntu 的防火牆設定,把 VNC 的預設 5900 port 限制一下,僅限本地端連線,這樣算是基本的安全設定吧。


環境敘述:


一台 Ubuntu 10.04 desktop 工作機、一台 Windows XP 小筆電


Ubuntu:


vnc_remote_desktop



  • 開啟 SSH 服務提供遠端登入

    • $ sudo apt-get install openssh-server



  • 開啟 VNC 服務,並限定需要密碼才能登入

    • [System] -> [Preferences] -> [Remote Desktop]



  • 設定 iptable ,限制只能本地端 localhost 登入 5900 port (VNC port),對外網卡是 eth0

    • $ sudo iptables -A INPUT -i eth0 -p tcp --dport 5900 -j DROP




Windows XP:


ssh_tunnel



  • 使用 PuTTY 建立 SSH Tunnels,讓本地端 localhost 5900 對應到 Ubuntu 機器的 5900 


    • PuTTY -> Connection -> SSH -> Tunnels -> Source Port (5900) 、Destination(ubuntu_ip:5900) ,按 Add 新增,之後就可以點 Open 開啟連線



  • 使用 RealVNC - VNC® remote control softwareVNC Viewer Free 軟體進行遠端登入,免費的,下載軟體時可以不填資料

    • 連線位置 localhost 即可,過程會需要輸入 Ubuntu 設定的遠端桌面的密碼




使用的感覺是堪用,如果在 VNC Viewer 進行登出、鎖定螢幕等動作,會導致無法連回 Ubuntu 機器。最大的缺點是... Ubuntu 本機端無法 lock screen 會有資安問題!


2011年5月26日 星期四

[Unix] awk: Too many open files @ FreeBSD

之前用 awk 練習,[Unix] 簡易分析 Squid 產生的 log @ FreeBSD,結果最近跑的時候開始碰到這個問題:Too many open files,一時之間還以為是自己程式的 bug,最後發現是 awk 裡有用到 pipe 等相關開檔動作,做完要記得 close 就行了。


簡易範例:


awk  ' { data[$1]++ } END { for( d in data ) { cmd = "wc -l /tmp/file";  cmd | getline result ;  close( cmd );   print result;   }   }'


由於是跑迴圈,資料多筆時就會碰到 Too many open files 的問題,只要把每個 pipe 或 file 相關的動作都有 close 掉就能解決囉。


2011年5月23日 星期一

[Linux] Building Pidgin 2.7.11 & MSN MPOP Problem @ Ubuntu 10.04

即時通(IM)軟體,已經成為 RD 人員對內或對外的溝通管道,在 Ubuntu 環境上,有幾種可以選擇,我選擇使用 Pidgin (鴿子圖)軟體,Open source 的,目前 Ubuntu 10.04 Desktop 64bit 環境中,可以用軟體管理安裝 Pidgin 2.6.6 版本。此 Pidgin 支援眾多 IM 服務,如 MSN、GTalk、QQ、ICQ 等,另外在 Mac OSX 的 Adium (鴨子圖)軟體也採用 Pidgin 核心


至於為啥要安裝最新版?去年底有一陣子使用 MSN 時,會有 CA 憑證問題,當時使用新版可以解決,最近則是看到 Adium 1.5hg 版可以支援多重地點上線(例如 WinXP 與 Ubuntu 同時使用同一個帳號上線),在加上他的核心是 Pidgin,所以就想來編看看新版,目前使用 Pidgin 2.6.6 版時,不支援多重地點上線。


安裝環境:


Ubuntu 10.04.2 Desktop 64-bit @ 2011-05-23 & VirtualBox


$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo reboot


相關環境:


$ sudo apt-get install intltool libgtk2.0-dev libxss-dev libgtkspell-dev libxml2-dev libgstreamer0.10-dev libgstfarsight0.10-dev libgstreamermm-0.10-dev libidn11-dev libmeanwhile-dev libavahi-core-dev libavahi-client-dev libavahi-glib-dev libdbus-glib-1-dev libnm-glib-dev libperl-dev libgnutls-dev tcl8.4-dev tk-dev


編譯(Pidgin 原始碼 http://pidgin.im/download/source/):


$ wget "http://downloads.sourceforge.net/project/pidgin/Pidgin/2.7.11/pidgin-2.7.11.tar.bz2?r=http%3A%2F%2Fpidgin.im%2Fdownload%2Fsource%2F&ts=1306119851&use_mirror=nchc" -O pidgin-2.7.11.tar.bz2
$ tar -xvf pidgin-2.7.11.tar.bz2
$ cd pidgin-2.7.11
$ ./configure
$ sudo make install clean


重開機(登入?)以後,就可以在 Internet 那邊看到 Pidgin 軟體。 


其他編譯時會碰到訊息(已安裝相關環境則不會碰到):


configure: error:  (libxss-dev)
XScreenSaver extension development headers not found.
Use --disable-screensaver if you do not need XScreenSaver extension support,
this is required for detecting idle time by mouse and keyboard usage.

configure: error: (libgtkspell-dev libxml2-dev)
GtkSpell development headers not found.
Use --disable-gtkspell if you do not need it.

configure: error: (libgstreamer0.10-dev)
GStreamer development headers not found.
Use --disable-gstreamer if you do not need GStreamer (sound) support.

configure: error: (libgstreamermm-0.10-dev libgstfarsight0.10-dev)
Dependencies for voice/video were not met.
Install the necessary gstreamer and farsight packages first.
Or use --disable-vv if you do not need voice/video support.

configure: error: (libidn11-dev)
GNU Libidn development header not found.
Use --disable-idn if you do not need it.

configure: error: (libmeanwhile-dev)
Meanwhile development headers not found.
Use --disable-meanwhile if you do not need meanwhile (Sametime) support.

configure: error:  (libavahi-core-dev libavahi-client-dev libavahi-glib-dev)
avahi development headers not found.
Use --disable-avahi if you do not need avahi (Bonjour) support.

configure: error:  (libdbus-glib-1-dev)
D-Bus development headers not found.
Use --disable-dbus if you do not need D-Bus support.

configure: error:  (libnm-glib-dev)
NetworkManager development header not found.
Use --disable-nm if you do not need D-Bus support.

configure: error:  (libperl-dev)
Perl development headers not found.
Use --disable-perl if you do not need Perl scripting support.

configure: error:  (libgnutls-dev)
Neither GnuTLS or NSS SSL development headers not found.
Use --disable-nss --disable-gnutls if you do not need SSL support.
MSN, Yahoo!, Novell Groupwise and Google Talk will not work without SSL. OpenSSL is NOT usable!

configure: error:  (tcl8.4-dev)
Tcl development headers not found.
Use --disable-tcl if you do not need Tcl scripting support.

configure: error:  (tk-dev)
TK development headers not found.
Use --disable-tk if you do not need Tk scripting support.


關於 Multiple Points of Presence (MPOP):


去年 11 月底,有碰到一陣子 MSN CA 憑證問題,當時有看到一些文章在講 Pidgin 2.7.6 除了解決此問題外,也支援 MSNP16 及 MPOP 功能,而甚麼是 MPOP 功能呢?就是支援同一帳號多處上線的功能。


相關文件:


Microsoft_Notification_Protocol#MSNP16


Ticket #8247 (closed enhancement: fixed) - Support MSNP16 multiple logins


Pidgin News @ November 01, 2010 - MSNP16 and SLP-rewrite merged


隨後我也翻了一下 Pidgin-2.7.11 的程式碼,發現的確有對應的程式,但不知為啥我在使用 Pidgin-2.7.11 時,在設定帳號那邊,卻找不到相對應設定 MPOP 的選項?後來發現,如果是使用 /usr/local/bin/pidgin 就不會看到,但用 src 裡 pidgin/pidgin 執行,就可以看到設定選項多了 Allow connecting from multiple locations 啦!


mpop


如果把 mpop 關掉,則是在 ~/.purple/account.xml 裡 <settings> 中會多一欄(預設並不會設定此直,可能預設就是啟用 MPOP 模式):


<setting name='mpop' type='bool'>0</setting>


那如果看不到此 UI 的話,強制去更新 account.xml 加上 <setting name='mpop' type='bool'>1</setting> 好像可強制啟用 MPOP 吧?但測試的結果,無論打開選項或關掉都沒有影響。感覺此功能好像是被隱藏起來,不然就是有使用條件的限制。


另外一提,Ubuntu 10.04 內建環境的 Pidgin-2.6.6 哩,是使用 libpurple 2.6.6 ,但我安裝新版的 Pidgin-2.7.11 哩,在"說明"中還是用 libpurple 2.6.6 而已。簡單的說,我覺得內建環境的 Pidgin-2.6.6 應該就可以使用 MPOP 才對 :P 因為函式庫是同版本。我想我應該有遺漏甚麼,有空再來查查。