-
-
Notifications
You must be signed in to change notification settings - Fork 78
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unable to open database with enabled vfs=win32-longpath option #104
Comments
I'm aware of that.
The VFS win32-longpath does not support encryption on its own, so you can't create or open an encrypted database with this VFS alone. On initialization SQLite3 Multiple Ciphers creates a VFS shim for the default VFS of the operating system (for Windows that is the VFS win32). The name of this VFS shim that supports encryption is multipleciphers-win32. If encryption support for other VFSs is required, a VFS shim has to be created for those VFSs, too.
The problem does not depend on the encryption scheme or the path length, but only on the VFS in use.
Of course, the VFS win32-longpath supports unencrypted databases with long as well as short paths.
I agree that it would be nice to select a VFS with encryption support without requiring to set up a VFS shim manually. In the current implementation a VFS shim needs to be created in advance.
The SQLite3 Multiple Ciphers implementation is correct, at least as far as I know. However, unfortunately the documentation lacks the information what needs to be done to be able to use other VFSs than the default one with encryption support. The SQLite3 Multiple Ciphers API includes the function int sqlite3mc_vfs_create(const char* zVfsReal, int makeDefault); that can be used to create a new VFS shim with encryption support, In your use case you have to call int rc = sqlite3mc_vfs_create("win32-longpath", 0); This creates a VFS shim with encryption support using the VFS win32-longpath for the real file access. The name of the VFS shim will be multipleciphers-win32-longpath - and that name can then be used in the vfs URI parameter ( I will complement the documentation in the near future. Additionally, I will check whether I can implement an easier way to use any of the available VFSs with encryption support. |
Oh great. Now it works perfectly. |
You are welcome. So, I will close the issue. In the meantime I experimented a bit. As a result the next release will allow to specify a VFS name with encryption support without the need to call |
@utelle I tried without setting a special VFS but when the path is longer than 512 characters i get an InvalidDatabaseException when trying to open the database. All documented VFSes for unix seems not to solve the problem. Do you have an idea? Or do you know if there exists a limitation for sqlite in path length in unix? |
That is a hard coded limitation in the SQLite sources. For Unix-like systems there is a symbol #define MAX_PATHNAME 512 This number is fixed and is used for all VFSs.
Right. All Unix VFSs use the same limit for pathnames.
AFAIK the limitation to 512 characters in SQLite is arbitrary. Most Linux systems should support pathname with up to 4096 characters in total. So, IMHO there are 2 options:
|
We already use a self compiled version because we also need RC4 encryption . So i set MAX_PATHNAME to 4096 in the source.
I also tried your newest version (1.6.0) with your extension without the need to call sqlite3mc_vfs_create(). |
I assume you know that SQLite3 Multiple Ciphers supports the RC4 variant that was included in prior versions of System.Data.SQLite.
I asked about
You are welcome. |
- Based on SQLite version 3.41.1 Symbol MAX_PATHNAME (used on Unix-like platforms) has a fixed value of 512 in the original SQLite source code. This can now be configured at compile time to use a higher value (like 4096 - which is supported by most Linux variants) (see issue #104). Use symbol SQLITE3MC_MAX_PATHNAME to define a higher value.
Now i have another question to the same subject. Unfortunately it is not possible to unload native dlls (also the sqlite-multicipher-dll). So if a sqlite-multicipher-dll first was loaded in an earlier version which does not support your new feature yet (creating vfs without calling sqlite3mc_vfs_create), we will get an error if we load and use our actual assembly which assumes that the vfs will be created automatically because in this case the older sqlite-multicipher-dll is used. I think due to compatibility reasons the only solution is to call sqlite3mc_vfs_create in our new version because older versions of your sqlite-dll already has this method since a longer time. So our new versions will also work with an older sqlite-multicipher-dll. Now my question. Do you think it will be a problem if we call sqlite3mc_vfs_create multiple times in the same process in different AppDomains? Because it will be difficult to know if sqlite3mc_vfs_create was already called by some AppDomain. |
Can't you update older assembly versions to use a more recent SQLite3MC DLL? Isn't that a legitimate requirement to be able to replace an old assembly by a new one - to fix bugs or to introduce new features?
Well, yes, that is certainly a problem. However, the older SQLite3MC versions weren't able to use the VFS "win32-longpath" with encryption support, unless the VFS was explicitly created by the application in advance.
Of course you can always create VFSs explicitly. However, I assume that your older assemblies didn't do that. So, you have to update your assembles anyway, and in that course you could update the SQLite3MC DLL as well.
In principal, you can call |
For us there is no need to update older versions because new features or bugfixes are always introduced with a newer version or new service packs
We have decided to check with sqlite3_vfs_find if the vfs already exists (multipleciphers-win32-longpath) and only if it not exists we will call sqlite3mc_vfs_create . So we do not call it multiple times and there should not be any memory leaks. Thanks again for your help. |
Sure, by checking first whether the VFS already exists, you can easily avoid memory leaks. |
I need to use databases in paths that are longer than 1024 characters. Therefore sqlite has different VFSes (https://www.sqlite.org/vfs.html).
But if i set vfs=win32-longpath in my connecton string i cannot open any database that is encrypted. Also dbs in paths shorter than 260 characters cannot be opened any more. I use RC4 and chacha20 encryption.
But when i remove encryption from the database it works without any problems with paths shorter than 260 characters and also with paths with more than 1024 characters.
So it must be something wrong when there is an encryption for the db.
I use an URI connection string like this:
"file:///E:/DatabaseFilename.db?vfs=win32-longpath&cipher=chacha20&key=XXXX"
Is there a bug in the SQLite3MultipleCiphers implementation? Or am i doing something wrong?
The text was updated successfully, but these errors were encountered: