TL;DR security.nocertdb設定為true會讓Firefox Sync無法運作,改回false即可
最近發現我的Firefox Sync無法正常運作,在一台電腦上新加的addon沒有同步到其他電腦上。
about:sync-log中的紀錄檔有以下錯誤訊息:
1520939110858 Sync.Service INFO User logged in successfully - verifying login.
1520939110862 Sync.BrowserIDManager DEBUG unlockAndVerifyAuthState: user declined to unlock master-password
1520939110862 Sync.Status DEBUG Status.login: success.login => service.master_password_locked
1520939110862 Sync.Status DEBUG Status.service: success.status_ok => error.login.failed
1520939110862 Sync.Service DEBUG Fetching unlocked auth state returned service.master_password_locked
1520939110862 Sync.ErrorHandler ERROR Sync encountered a login error
但是我並沒有設定master password。如果試著去建立一個master password,則會有"unable to change master password"的訊息。
由於我曾經在Nightly、Beta、Stable之間切換,因此我猜可能是改版造成的問題。然而,試了各種版本後,問題依舊。
此時,我懷疑可能我的profile有損毀的情況。官方說法是如果把Firefox降版,而profile沿用,有可能會發生。之前研究過Firefox Sync,他需要把登入用的一些資訊存在Firefox的password storage中。Profile損毀的話的確有可能會無法sync。
然而,用firepwd解密我的profile,又可以正常印出Firefox Sync登入用的資訊,所以問題可能出在Firefox本身。
首先,將signon.debug設為true,可以多印出一些訊息。從訊息中可以得知logins.json中的username和password解密失敗。
根據firepwd提供的Firefox密碼解密原理說明,解密需要一把3DES的key,而這把key會用一組key ID來操作。
我自行編譯mozilla-central,再gdb後,發現Firefox可以解開所需的key ID,但找不到所對應的key。
根據firepwd,3DES key是存在key3.db或key4.db中,然而讀取這兩種db的函數都沒有被執行到,表示key3.db或key4.db都沒有被讀進來。strace也給出相同的結論。
接著發現在initialize NSS module時,configdir為空,因此NSS不會去找key3.db或是key4.db。我原本以為profile裡面設定錯誤,但看pkcs11.txt和secmod.db似乎都沒問題。
最後發現如果security.nocertdb為true,就會把config設為空,因此整個解密的過程都無法進行。
經過一番回想,當初設定這個參數是為了讓Firefox不要保留SSL immediate certificate,沒想到這個參數還有副作用。我猜他的本意是:不要讀取或寫入任何在permanent storage上和密碼以及安全有關的資料。沒了immediate certificate,也沒了password storage。
現在只好先改回來,等哪天發現有更好的辦法可以disable immediate certificate,不然一大堆immediate certificate列在那邊實在很礙眼。