jcs / rubywarden

An unofficial, mostly Bitwarden-compatible API server written in Ruby (Sinatra and ActiveRecord)
ISC License
592 stars 49 forks source link

Bitwarden import breaks syncronization #59

Closed alxchk closed 6 years ago

alxchk commented 6 years ago

How to reproduce:

  1. Setup clean rubywarden db
  2. Start server (allow registration)
  3. Register via Android mobile App
  4. Stop server
  5. Import CSV (common format). Records like:
    folder,favorite,type,name,notes,fields,login_uri,login_username,login_password,
    web,,login,site.xx,,,https://site.xx,login,"password",
  6. Start server
  7. Login into app - storage never shown
  8. Manual sync doesn't work either (200 OK from server but sync failed message in app)
jcs commented 6 years ago

What did you use to import the CSV?

alxchk commented 6 years ago

The script bitwarden_import.rb

Joshndroid commented 6 years ago

I can confirm this issue is present with a fresh install and utilising a bitwarden exported csv. Tried utilising root user as well as an adduser of _rubywarden. Conducted numerous re-installs of rubywarden same error. Database seems to get broken. From fresh install, manual input of passwords will work just fine. Infact i had to do this in order to actually use this (200+ passwords later :[ ).

jcs commented 6 years ago

@logic Can you help here with your importer?

valantur commented 6 years ago

Yeah the importer is broken now. Looks like bitwarden.rb defines hashPassword with needing 4 arguments (password, salt, kdf_type, kdf_iterations), and bitwarden_import.rb only provides two (password, salt) when calling that function. Hope this helps.

valantur commented 6 years ago

Hi @jcs , thanks to your changes to the importer tools, I think I was able to import my passwords from bitwarden. I say I "think" because I get a spinning wheel on the Chrome plugin right after logging on., and my passwords never show up. This didn't happen before importing passwords onto my user. Here's what the terminal shows:

"POST /api/accounts/prelogin HTTP/1.1" 200 30 0.0338 "POST /identity/connect/token HTTP/1.1" 200 1090 0.0843 "POST /api/accounts/keys HTTP/1.1" 404 18 0.0071 "POST /notifications/hub/negotiate HTTP/1.1" 404 18 0.0005 "GET /api/sync HTTP/1.1" 200 194390 0.1019

Thanks for your continued help.

Joshndroid commented 6 years ago

Unfortunately that seems like the issue I had to begin with (with Firefox and official app) for bitwarden import.. Spinning wheel of death with no actual passwords ever showing

phischmi commented 6 years ago

Are there any news on this issue? When importing and syncing, first everything looks fine, but then i get that spinning wheel and the imported data never shows up :/

qbit commented 6 years ago

Looks like this impacts the keepass importer as well. Folders seem to make it in fine. I will try to get more info here pretty quick.

Joshndroid commented 6 years ago

Bitwarden import still broken... really dont want to have to reimport my whole database by hand again :(

qbit commented 6 years ago

Looks like the data field in the ciphers table is being populated with a hash vs the expected data:

sqlite> select uuid, name from ciphers where uuid in ('c63a59c8-c25f-4e73-bf27-1830d231f474', 'e2957f43-11dc-45ab-ab2e-c4942bbc1bf4');
c63a59c8-c25f-4e73-bf27-1830d231f474|{"type"=>2, "iv"=>"eJ9XOwHfE8ZyxRcrAb6+HA==", "ct"=>"9NCIxichG3jmCb+1T/6lPg==", "mac"=>"gGp3ifvUIHLCqu8o+vhWOzhOfpGPHc+T7z2t3sUxC9k="}

Other Working entries are lacking the identifiers like type, iv and mac.

jcs commented 6 years ago

@qbit Oh are there more to_s casts needed like in 763092a? (I'm on a phone, I can't test)

qbit commented 6 years ago

Not entirely sure. Poking around there isn't an obvious location to add it.

For fun I tried here:

diff --git a/lib/cipher.rb b/lib/cipher.rb
index 8648606..e31bc5d 100644
--- a/lib/cipher.rb
+++ b/lib/cipher.rb
@@ -75,7 +75,8 @@ class Cipher < DBModel
       TYPE_CARD => "card",
       TYPE_IDENTITY => "identity",
     }
-    self.send("#{fmap[self.type]}=", js)
+
+    self.send("#{fmap[self.type]}=", js.to_s)

     self.save || raise("failed migrating #{self.inspect}")
     true

And it imports a blank entry, so I am fairly sure that isn't right :D

qbit commented 6 years ago

Looks like this diff fixes keepass import:

diff --git a/tools/keepass_import.rb b/tools/keepass_import.rb
index 5ce3534..a019089 100644
--- a/tools/keepass_import.rb
+++ b/tools/keepass_import.rb
@@ -91,7 +91,7 @@ end
 end

 def encrypt(str)
-  @u.encrypt_data_with_master_password_key(str, @master_key)
+  @u.encrypt_data_with_master_password_key(str, @master_key).to_s
 end

 def get_or_create_folder_uuid(str)
jcs commented 6 years ago

@alxchk @Joshndroid @phischmi Can you test re-importing with e539b67?

Joshndroid commented 6 years ago

@jcs IT WORKED... IT WORKED :D :D :D

Bitwarden generated export. fresh database. imported as listed in readme, no spinning wheel of death

phischmi commented 6 years ago

Works as expected! Thanks!