// walletSeedsHandlerGET handles a GET request to /wallet/seeds. func (srv *Server) walletSeedsHandlerGET(w http.ResponseWriter, req *http.Request) { dictionary := mnemonics.DictionaryID(req.FormValue("dictionary")) if dictionary == "" { dictionary = mnemonics.English } // Get the primary seed information. primarySeed, progress, err := srv.wallet.PrimarySeed() if err != nil { writeError(w, "error after call to /wallet/seed: "+err.Error(), http.StatusBadRequest) return } primarySeedStr, err := modules.SeedToString(primarySeed, dictionary) if err != nil { writeError(w, "error after call to /wallet/seed: "+err.Error(), http.StatusBadRequest) return } // Get the list of seeds known to the wallet. allSeeds, err := srv.wallet.AllSeeds() if err != nil { writeError(w, "error after call to /wallet/seed: "+err.Error(), http.StatusBadRequest) return } var allSeedsStrs []string for _, seed := range allSeeds { str, err := modules.SeedToString(seed, dictionary) if err != nil { writeError(w, "error after call to /wallet/seed: "+err.Error(), http.StatusBadRequest) return } allSeedsStrs = append(allSeedsStrs, str) } writeJSON(w, WalletSeedsGET{ PrimarySeed: primarySeedStr, AddressesRemaining: int(modules.PublicKeysPerSeed - progress), AllSeeds: allSeedsStrs, }) }
// walletInitHandler handles API calls to /wallet/init. func (api *API) walletInitHandler(w http.ResponseWriter, req *http.Request, _ httprouter.Params) { var encryptionKey crypto.TwofishKey if req.FormValue("encryptionpassword") != "" { encryptionKey = crypto.TwofishKey(crypto.HashObject(req.FormValue("encryptionpassword"))) } seed, err := api.wallet.Encrypt(encryptionKey) if err != nil { WriteError(w, Error{"error when calling /wallet/init: " + err.Error()}, http.StatusBadRequest) return } dictID := mnemonics.DictionaryID(req.FormValue("dictionary")) if dictID == "" { dictID = "english" } seedStr, err := modules.SeedToString(seed, dictID) if err != nil { WriteError(w, Error{"error when calling /wallet/init: " + err.Error()}, http.StatusBadRequest) return } WriteJSON(w, WalletInitPOST{ PrimarySeed: seedStr, }) }
// walletEncryptHandlerPOST handles a POST call to /wallet/encrypt. func (srv *Server) walletEncryptHandlerPOST(w http.ResponseWriter, req *http.Request) { var encryptionKey crypto.TwofishKey if req.FormValue("encryptionpassword") != "" { encryptionKey = crypto.TwofishKey(crypto.HashObject(req.FormValue("encryptionpassword"))) } seed, err := srv.wallet.Encrypt(encryptionKey) if err != nil { writeError(w, "error when calling /wallet/encrypt: "+err.Error(), http.StatusBadRequest) return } dictID := mnemonics.DictionaryID(req.FormValue("dictionary")) if dictID == "" { dictID = "english" } seedStr, err := modules.SeedToString(seed, dictID) if err != nil { writeError(w, "error when calling /wallet/encrypt: "+err.Error(), http.StatusBadRequest) return } writeJSON(w, WalletEncryptPOST{ PrimarySeed: seedStr, }) }
// Tests that the /wallet/siagkey call checks for relative paths. func TestWalletRelativePathErrorSiag(t *testing.T) { if testing.Short() { t.SkipNow() } st, err := createServerTester("TestWalletRelativePathErrorSiag") if err != nil { t.Fatal(err) } defer st.server.Close() // Announce the host. if err := st.announceHost(); err != nil { t.Fatal(err) } // Create tmp directory for uploads/downloads. walletTestDir := build.TempDir("wallet_relative_path_sig") err = os.MkdirAll(walletTestDir, 0700) if err != nil { t.Fatal(err) } // Wallet loading from siag should error if its source is a relative path loadSiagAbsoluteError := "error when calling /wallet/siagkey: keyfiles contains a non-absolute path" rawSeed, _, err := st.wallet.PrimarySeed() if err != nil { t.Fatal(err) } // This is not the actual wallet password. The createServerTester does not // return the string password. So for the sucess tests we check if we make // it past the absolute value check and instead error because of the key. seed, err := modules.SeedToString(rawSeed, "english") if err != nil { t.Fatal(err) } // This should fail. loadSiagValues := url.Values{} loadSiagValues.Set("keyfiles", "test.dat") loadSiagValues.Set("encryptionpassword", seed) err = st.stdPostAPI("/wallet/siagkey", loadSiagValues) if err == nil || err.Error() != loadSiagAbsoluteError { t.Fatal(err) } // As should this. loadSiagValues = url.Values{} loadSiagValues.Set("keyfiles", "../test.dat") loadSiagValues.Set("encryptionpassword", seed) err = st.stdPostAPI("/wallet/siagkey", loadSiagValues) if err == nil || err.Error() != loadSiagAbsoluteError { t.Fatal(err) } // This should fail. loadSiagValues = url.Values{} loadSiagValues.Set("keyfiles", "/test.dat,test.dat,../test.dat") loadSiagValues.Set("encryptionpassword", seed) err = st.stdPostAPI("/wallet/siagkey", loadSiagValues) if err == nil || err.Error() != loadSiagAbsoluteError { t.Fatal(err) } // As should this. loadSiagValues = url.Values{} loadSiagValues.Set("keyfiles", "../test.dat,/test.dat") loadSiagValues.Set("encryptionpassword", seed) err = st.stdPostAPI("/wallet/siagkey", loadSiagValues) if err == nil || err.Error() != loadSiagAbsoluteError { t.Fatal(err) } // This should succeed. loadSiagValues = url.Values{} if err = createRandFile(filepath.Join(walletTestDir, "test.dat"), 0); err != nil { t.Fatal(err) } loadSiagValues.Set("keyfiles", filepath.Join(walletTestDir, "test.dat")) loadSiagValues.Set("encryptionpassword", seed) err = st.stdPostAPI("/wallet/siagkey", loadSiagValues) if err == nil || err.Error() != "error when calling /wallet/siagkey: provided encryption key is incorrect" { t.Fatal(err) } // As should this. loadSiagValues = url.Values{} if err = createRandFile(filepath.Join(walletTestDir, "test1.dat"), 0); err != nil { t.Fatal(err) } loadSiagValues.Set("keyfiles", filepath.Join(walletTestDir, "test.dat")+","+filepath.Join(walletTestDir, "test1.dat")) loadSiagValues.Set("encryptionpassword", seed) err = st.stdPostAPI("/wallet/siagkey", loadSiagValues) if err == nil || err.Error() != "error when calling /wallet/siagkey: provided encryption key is incorrect" { t.Fatal(err) } }