sabeechen / decrypt-ha-backup

Decrypts password protected Home Assistant Backups
The Unlicense
22 stars 3 forks source link

Issue with single addon causes entire decryption to fail #5

Open nathang21 opened 5 months ago

nathang21 commented 5 months ago

I'm getting this error when trying to extract/decrypt, however I confirmed that the cebe7a76_hassio_google_drive_backup.tar.gz file is present in the .tar archive, as well as in the backup.json (see attached). backup.json

I only want to recover part of the files from this backup, but I haven't found a workaround.

I looked at #1 and confirmed I am able to open the root .tar file without issue, and can see all the .tar.gz files, but can not decrypt any of them. Is it possible to decrypt only one of these subfolders/archives? The utility as designed currently only appears to work on the root archive.

python3 -m decrypt-ha-backup Partial\ Backup\ 2024-03-01\ 03:00:00.tar --password='<redacted>'
Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "/Users/nathang21/Downloads/ha-restore/lib/python3.12/site-packages/decrypt-ha-backup/__main__.py", line 266, in <module>
    main()
  File "/Users/nathang21/Downloads/ha-restore/lib/python3.12/site-packages/decrypt-ha-backup/__main__.py", line 233, in main
    backup = Backup(backup_file)
             ^^^^^^^^^^^^^^^^^^^
  File "/Users/nathang21/Downloads/ha-restore/lib/python3.12/site-packages/decrypt-ha-backup/__main__.py", line 66, in __init__
    self._items = [BackupItem(entry['slug'], entry['name'], self) for entry in self._config.get("addons")]
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/nathang21/Downloads/ha-restore/lib/python3.12/site-packages/decrypt-ha-backup/__main__.py", line 124, in __init__
    self._info = self._backup._tarfile.getmember(self.fileName)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/Cellar/python@3.12/3.12.2_1/Frameworks/Python.framework/Versions/3.12/lib/python3.12/tarfile.py", line 1985, in getmember
    raise KeyError("filename %r not found" % name)
KeyError: "filename './cebe7a76_hassio_google_drive_backup.tar.gz' not found"
sabeechen commented 4 months ago

sorry it took me a while to get back. You're right, this is a a relatively arbitrary limitation in the script, mostly just because of how its written. The easiest way to work around this would be to edit the archive manually:

I'll see about adding a commandline arg to limit it to interacting with a subset of the archives inside it.

domolys commented 3 months ago

Just trying to restore a backup with a password made by HA 2024.1 Is this tool still working ?

sabeechen commented 3 months ago

It looks like they changed the backup format a little bit, and I'm having trouble getting HA to import encrypted backups that even it makes. I'll fix this when I'm able to dedicate some time to sort out whats goign wrong here.

habandy commented 2 months ago

Having the same problem as mentioned here. Just for information. :) no pressure.

domolys commented 2 months ago

When I rearrange the tar file structure, I can use decrypt-ha-backup without any issue...

tar-decrypt tar-decrypt-file

habandy commented 2 months ago

Ah sorry, i wanted to post in #1 , I'm getting the same problem with "invalid header". i think the problem there could be the used password with special characters. backups without password war just fine.

kblin commented 1 month ago

When I rearrange the tar file structure, I can use decrypt-ha-backup without any issue...

I'm running in the same issue, but I don't understand what you were rearranging to get things to work. Could you elaborate?

kblin commented 1 month ago

ah, now I get it, it's the leading ./ that's the problem.

diff --git a/decrypt-ha-backup/__main__.py b/decrypt-ha-backup/__main__.py
index 7ed4110..c24f16a 100644
--- a/decrypt-ha-backup/__main__.py
+++ b/decrypt-ha-backup/__main__.py
@@ -128,7 +128,7 @@ class BackupItem:
     @property
     def fileName(self):
         ext = ".tar.gz" if self._backup.compressed else ".tar"
-        return f"./{self._slug.replace('/', '_')}{ext}"
+        return f"{self._slug.replace('/', '_')}{ext}"

     @property
     def slug(self):

is the code change that gets things to work for me without futzing with my archive.