作者: Hui-Hong YOU

  • 嘗試做一個 envchain 的仿品 (6)

    最近這幾天,下班後沒什麼動力,而且胃病又找上門,更是折磨人,還是沒有什麼明顯的進度。看了一下 dbus-rs 給的範例裡滿滿的 unwrap(),很好奇這方法是何作用,便搜尋了一下:

    To “unwrap” something in Rust is to say, “Give me the result of the computation, and if there was an error, panic and stop the program.”

    原來是一個錯誤處理用的便捷(且看來有點暴力?)方法。

  • 嘗試做一個 envchain 的仿品 (5)

    今天沒有什麼特別的進度,就是慢慢地把 Ruby PoC code 往 Rust 改寫而已。因為想要採行 TDD,所以按照  convention 為專案加上 tests/ 目錄,測試程式就可以放在裡面。過程當中因為同檔名程式的關係在鬼打牆,還以為怎麼程式就是無法跑出預期的結果。

    同時把 rustfmt 架起來,仿照 gofmt 自動在我用 VIm 儲存 Rust 程式時自動排版程式碼。

  • 嘗試做一個 envchain 的仿品 (4)

    剛剛試了一下 writePassword(),沒問題,可以用 key-value pair 的方式儲存想要保密的資料:

    require 'dbus'
    require 'pp'
     
    session_bus = DBus.session_bus
     
    kwalletd_service = session_bus["org.kde.kwalletd5"]
    kwalletd_object = kwalletd_service.object "/modules/kwalletd5"
    kwalletd_object.introspect
    kwalletd_interface = kwalletd_object["org.kde.KWallet"]
    handle = kwalletd_interface.open("kdewallet", 0, "Ruby D-Bus Client").first
    pp kwalletd_interface
     
    kwalletd_interface.createFolder(handle, "envpick", "Ruby D-Bus Client")
    pp kwalletd_interface.folderList(handle, "Ruby D-Bus Client")
     
    kwalletd_interface.writePassword(handle, "envpick", "key-0", "value-0", "Ruby D-Bus Client")
    kwalletd_interface.writePassword(handle, "envpick", "key-1", "value-1", "Ruby D-Bus Client")
    pp kwalletd_interface.entryList(handle, "envpick", "Ruby D-Bus Client")

    完全符合我的需求。

  • 嘗試做一個 envchain 的仿品 (3)

    ruby-dbus 去戳 D-Bus,可以順利解出 KWallet 的…binary 資料?

    require 'dbus'
    require 'pp'
     
    session_bus = DBus.session_bus
     
    kwalletd_service = session_bus["org.kde.kwalletd5"]
    kwalletd_object = kwalletd_service.object "/modules/kwalletd5"
    kwalletd_object.introspect
    kwalletd_interface = kwalletd_object["org.kde.KWallet"]
    handle = kwalletd_interface.open("kdewallet", 0, "Ruby D-Bus Client").first
    pp kwalletd_interface
    pp kwalletd_interface.folderList(handle, "Ruby D-Bus Client")
    pp kwalletd_interface.entryList(handle, "Network Management", "Ruby D-Bus Client")
    pp kwalletd_interface.readMap(handle, "Network Management", "{????????-????-????-????-????????????};802-11-wireless-security", "Ruby D-Bus Client").first

    翻了一下網上資料才知道是這個原因:[Bug 256155 – KWallet’s readMap is not friendly to non-C++ applications],昏倒,這同時解釋了為什麼 kwallet-query 這專用工具可以解出 human readable 的密碼,而泛用工具不行。

    以上只是想要瞭解 KWallet 的操作,為之後的 coding 鋪路,實務上應該還有路可繞。為了泛用性,最多就是不要用 map 而已。

  • 嘗試做一個 envchain 的仿品 (2)

    在 qdbus 上面試著操作 KWallet 資料,撞了不少牆。參考 [Learning on the Job: Accessing the KDE Wallet from the Cmdline] 這篇,目前還是不曉得怎麼用 qdbus 取出 NetworkManager 儲在裡頭的 Wi-Fi 密碼,當然在 KWallet Manager 裡頭是沒問題的,用

    kwallet-query -r "{????????-????-????-????-????????????};802-11-wireless-security" -f "Network Management" kdewallet

    也可以取出密碼,但是用 qdbus 就是卡在最後不曉得怎麼把

    qdbus org.kde.kwalletd5 /modules/kwalletd5 org.kde.KWallet.entryList [handle] "Network Management" "Testing"

    得到的 entry 去推出 key-value。無論是用 org.kde.KWallet.readMap 抑或 org.kde.KWallet.readMapList 都得不到我預期的回傳結果,目前只能先猜是我不知道怎麼用這工具的問題。晚一點可能可以來試試用 Ruby 去戳 D-Bus。

  • 嘗試做一個 envchain 的仿品 (1)

    前幾天在公司跟同事聊「果黑」、「果粉黑」話題時順道聊到的:「Linux 上似乎還沒有一個像 envchain 這樣使用系統內建密鑰管理系統(如 OS X Keychain, GNOME Keyring, KWallet)來維護環境變數的同質產品,看是不是可以用 Rust 刻一個?」於是這幾天就在做一些基礎研究。

    其實 envchain 程式最關鍵處,就是從 Keychain 取出來環境變數,然後在呼叫 execvp() 執行程式時加上這些環境變數,原理不難懂。

    我自己使用的桌面環境是 KDE Plasma,所以預設的密鑰管理系統就是 KWallet。一開始直接去 Google 搜尋 “KWallet API”,心想大概就是要用 FFI 之類的去 call C ABI 來解,雖然很硬斗,但是也還能接受。

    再找了一下既有的 Rust crates 資源,以及瞄了一下 KWallet 的 package 內容檔案列表,發現其實不用這麼硬幹,透過 D-Bus 的介面就可以操作 KWallet API。