Page MenuHome GnuPG

Cleanup temporary files / dirs with decrypted content
Testing, HighPublic

Description

In the openWith code we extract the file to a QTemporaryDir and set autoDelete to false. This means that on Windows where tmp is not cleaned up on reboot this will add up with a lot of files.

My suggestion would be to save the temporary folders where we opened the files with in a list in the mailviewer and then delete them when the mailviewer is closed. Due to Windows "You cannot delete an open file" mechanic there should be no data loss, but at least we would be innocent if the files then stick around.

Event Timeline

aheinecke created this task.

My suggestion would be to save the temporary folders where we opened the files with in a list in the mailviewer and then delete them when the mailviewer is closed. Due to Windows "You cannot delete an open file" mechanic there should be no data loss, but at least we would be innocent if the files then stick around.

I don't think this will work as if I click on open with to see an image in an image viewer, we can't remove the image until the image viewer is also closed.

So I just checked how Outlook does this. It saves its temporary files not into temp but into:

C:\Users\Andre Heinecke\AppData\Local\Microsoft\Windows\INetCache\Content.Outlook\PK5RYJME

(Last part is only random) Now the fun part is that when you close outlook, it just closes the Windows in which the files are open. In your case it would close the image viewer and then deletes the file. The files are write protected so there is no real data loss. So for a high security mail client that might not be the worst behavior. Maybe we should do it like this, too: https://learn.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-ifileisinuse-closefile I mean we want to be an Outlook plugin so why not do the same?

aheinecke raised the priority of this task from Normal to High.Nov 13 2023, 9:53 AM
aheinecke added a project: vsd32.

Yeah we should fix that before a release. Otherwise we might get disgruntled customers that will notice that their VS-NfD files are lying around unencrypted. First step IMO should be to make the files write protected. And then CloseFile on them when the viewer window closes. Btw. what does KMail do? It remove them afaik when you close the message.

Btw. what does KMail do? It remove them afaik when you close the message.

This is that KMail is doing https://invent.kde.org/pim/messagelib/-/blob/master/messageviewer/src/viewer/viewer_p.cpp?ref_type=heads#L639

It use a KIO::ApplicationLauncherJob and remove the file once the job is done. This is maybe something we should be also doing, if this can work without KIO on windows.

I don't see how it removes the file immediately. Only on job->error(), or am I missing something? It also leaves write permission so that is something that I would not do.

On Linux you can remove a file while it is in use (open) but on Windows you cannot. So removing it immediately after the open will not work for us.

I am rather thinking of setting permissions to the file to "read only" and store them in something like a member variable of the mimeviewer that stores all QUrls that it used QDesktopServices::openUrl on and in the dtor of the viewer then use "CloseFile" on all the files and remove them after the call to CloseFile. That would be more akin to what Outlook does.

My Idea is now that we will will write the file, Then open it natively with CreateFile https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea (With FILE_SHARE_READ | FILE_SHARE_DELETE) then store the Handle. Call QDesktopServices::openURL on it. And if we are closed we call DeleteFile on all our open Handles.

aheinecke changed the task status from Open to Testing.Nov 21 2023, 3:33 PM
aheinecke claimed this task.

Assigned to me for testing.

aheinecke changed the task status from Testing to Open.Nov 24 2023, 3:00 PM
aheinecke moved this task from Restricted Project Column to Restricted Project Column on the Restricted Project board.

I tested it and for me the files are not deleted:

I am a bit suprised by this because if we open the file first with delete permission we should imo always be able to delete it.
But: [8616] Unable to delete file "C:/Users/Andre Heinecke/AppData/Local/Temp/kleopatra.qzRNDD/license.rtf" 0 0
But at least the files are now read only.

I can probably do some more testing with delete modes. FILE_FLAG_DELETE_ON_CLOSE also sounds interesting in that should delete the file when all handles to the file are closed. I think this needs some experiments because from what I took from the documentation the current code should work.

It might also depends on the file type as I wouldn't be surprised if for example the photo viewer opens the file differently than the text editor.

Maybe also in addition of trying to delete the files when closing the mimetreeviewer, we could also delete all files in C:/Users/Andre Heinecke/AppData/Local/Temp/kleopatra.* when we are starting kleopatra. This would be more of a safeguard than a complete solution.

Or you use a Cleaner like the one I added to QGpgME: https://dev.gnupg.org/rM278f92b189ece58dee2036450ac029e3599fdb1f

It's private API of QGpgME and I think it shouldn't be public API. But something like this might be useful for KDE Frameworks. Is there maybe already something like this?

I read the documentation (and stackoverflow) as owner we have to close our handle before deleting the file. With FILE_SHARE_DELETE we only ensure that others must live with the fact that we can always delete the file, but since we hold an exclusive READ right (which we gracefully share with others) our handle needs to be closed. So the trick was just to CloseHandle first and then the file could be deleted.

Cleaning up the directories on start sounds like a good idea in case we crash or are killed. Because I tried FILE_FLAG_DELETE_ON_CLOSE just as a safeguard but if that is added, even in combination with some other flags at least the ZIP file handler on Windows refused to open the file.

On another note: Please do not use "auto" for Windows API return codes. That makes the code harder to read since you have to check MSDN what the actual return type is. And since it will never change using auto is wrong IMO. E.g. from the code I would have guessed that CloseHandle returns a DWORD and not a BOOL as you wrote it out in the following warning.

Btw. GetLastError always needs to be called before you call any Qt functions like QString::fromStdWString since they might reset (and in this case here do) modify the last error and we should really add a function to libgpg-error that converts GetLastError to a string. I have about a dozen or so of such functions lying around in various repos.

aheinecke changed the task status from Open to Testing.Nov 25 2023, 5:04 PM

I created T6842 for the "Cleaning Kleopatra directories on startup" so that we can close this task once ebo confirms that all is fine. Usually I would close this task myself since I already tested it. But well we have QA now ;-)

aheinecke edited projects, added vsd32 (vsd-3.2.0); removed vsd32.