If we receive data without base64 encoding for encryption, it makes
sense to get it without base64 encoding out of decryption.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
For branded clients try to load a png of the right size, for unbranded
clients use the SVGs. If something fails at load time skip it.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
Now that we adjusted our protocol to follow the slightly updated server
API, let's make sure we don't try to talk to a server with an older API.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
Turns out that when we added a new e2e folder during sync, we were
passing the wrong path to the e2e object. We have several path
convention in the sync code, just happened to be the wrong one.
I still long for the day when we'll use the type system to deal with
paths. All those strings are error-prone.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
Other clients seem to allow creating empty encrypted folders with no
metadata associated to them, so let's get ready to handle it. In case of
a 404 to get the metadata, we create an empty metadata payload and pass
it further down.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
It used to be a base64 encoded '|', now it is still a '|' but not
encoded, let's adjust accordingly.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
We need to finish deleting the file before we can actually unlock. Also
the token will be necessary for the delete to succeed.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
The headers() method is used to pass extra headers to the PUT jobs for
instance, definitely needed for uploads now.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
The value gets already initialized by default member initialization,
so there is no need to set it again.
Signed-off-by: Stephan Beyer <s-beyer@gmx.net>
The value gets already initialized by default member initialization,
so there is no need to set it again in the copy constructor.
Signed-off-by: Stephan Beyer <s-beyer@gmx.net>
If we try to produce the avatar before we managed to connect we'd end up
trying to paint in a null image. Just return early, which will allow the
caller to do something else instead.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
The XML we get as reply has href entities properly percent encoded.
Since we didn't go through QUrl next we didn't get a properly decoded
version. Make sure we decode it before storage.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
- Use QEventLoop for synchronous exec()
- Rename startAwait() to exec()
- Add code for auto deletion
- Add new DeleteJob class
- Cleanup, tweaks
Signed-off-by: Michael Schuster <michael@schuster.ms>
When specified in the config file, the Proxy password will be migrated
to the keychain, for backward compatibility and to allow admins to
overwrite an existing password by rolling out updated config files.
Once migrated to the keychain, the password will be removed from the
config file.
Signed-off-by: Michael Schuster <michael@schuster.ms>
Awaits completion with no need to connect some slot to the finished() signal first,
inspired by the ProxyAuthHandler class.
Also add:
- Job dtor to safely erase passwords
- textData() method
- New ctor overloads to work with arbitrary keys (without Account ptrs)
Signed-off-by: Michael Schuster <michael@schuster.ms>
When the ClientSideEncryption object is fed, also serialize the
encryption info of the folders inside the metadata table.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
This will turn useful for other consumers of that data. The alternative
would be to expose a method breaking all form of encapsulation.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
We used to do it when the propagation starts, let's do it even before
the discovery starts. This way we'll have a chance to exploit the
information during the discovery phase.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
With the current design of the file upload this necessarily pushed to a
lock starvation on the folder. Indeed you could end up with N jobs
asking for the lock at the same time. So just avoid parallelizing for
now even though it will be slow.
We could try to optimize but that'd require some serious changes to the
sync logic on the jobs... let's stabilize first and optimize later.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
In such cases we get a download for which _file is already the demangled
name and _encryptedFileName has the mangled information. This is
different to what we encountered so far where initially _file was
mangled and _encryptedFileName was empty. Let's deal with that case
properly.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
Yes... I still wish this would be all driven by the type system, would be
much less error-prone.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
I wish this would be all driven by the type system instead of
error-prone string concatenation everywhere. That will be for a (much)
later refactoring hopefully.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
It turns out this job expected an absolute remote path even in the case
of a subfolder sync point.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
This was half broken before that commit and the previous one since some
of the categories would not be captured.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
Otherwise it was a bit confusing and annoying for filter rules:
e.g. "nextcloud.sync.*" vs "sync.*".
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
This means adjusting PropagateDownloadEncrypted so that it knows where
the file will end (otherwise it would create temporary files in non
existant paths for instance).
In turn we have to adjust PropagateDownloadFile accordingly so that it
resolves the local folder the file will end up in.
And last we adjust PropagateLocalMkdir to resolve paths as well and
demangle as needed.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
We give them a parent to make sure they will be destroyed when the jobs
which created them are destroyed themselves.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
PropagateUploadEncrypted made the assumption of the folder names never
being mangled. This is not true since the previous commits so make sure
we properly deal with that using the journal db.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
This is not only a question of performances in our case (complexity
being better on look ups). It also provides a few more services.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
We ensure the PROPFIND Depth is infinity by explicitly specifying the
header (turns out our implementation just doesn't assume infinity
otherwise). This way we have a clear picture about *all* the folders of
the user, otherwise ClientSideEncryption couldn't be a trustable oracle
on the encryption state for any folder not on the root and all the
encryption code assumes it has a full picture of encryption.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
We catch when a directory is inside a known encrypted folder and in such
a case we now do the following:
1) we encrypt the folder meta data (its name) properly and create it
under that mangled name on the server side
2) we mark the new folder itself as encrypted
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
It was assuming we'd encrypt only files but directory names also need to
be encrypted. We just skip the writing to temp file part in that case.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
This way this whole logic isn't stuck into the settings dialog anymore.
Also cleaned up the unused "decrypt folder" logic.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
This is a much better place than the GUI, this way we ensure the
propagator is always operating of up to date information. Previously if
the propagator kicked in without user interaction from startup (not
showing the settings dialog) it would have no E2E information available
whatsoever... unsurprisingly it would thus take wrong information at
every turn.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
Discovered on Windows in conjunction with PAC scripts:
- Already configured accounts worked
- Fresh client account setup did not work
Reason:
- Proxy was reset over and over again in Account::setCredentials
Signed-off-by: Michael Schuster <michael@schuster.ms>
Build failed on Windows, missing libsync export for printQNetworkProxy after
moving ClientProxy class from gui to libsync.
Signed-off-by: Michael Schuster <michael@schuster.ms>
The format in the client log was: 3://host:port
Now it is shown like: HttpProxy://host:port
The old ID display was confusing and misleading users (and people debugging it ;p)
Signed-off-by: Michael Schuster <michael@schuster.ms>
Make the codebase consistent, we already have a lot of implicit pointer comparisons.
Exception: Stay explicit on return's, example:
return _db != nullptr;
Signed-off-by: Michael Schuster <michael@schuster.ms>
This also fixes a couple of warnings at places (out of order init for
instance) and a potential bug in the webflow credentials / qtkeychain
integration.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
The E2E application allows creating unencrypted subdirectories
in an encrypted parent. This is a big privacy problem.
This patch shows a red broken lock icon for these subdirectories
in the NC client UI.
Signed-off-by: Ivan Čukić <ivan.cukic@kde.org>
Due to usage of early-returns, combined with malloc/free,
several buffers that get allocated are leaked when an error
occurs.
Several functions had potential leaks:
- `encryptStringSymmetric` leaked `ctext`
- `EncryptionHelper::fileDecryption` leaked `out`
- `EncryptionHelper::fileEncryption` leaked `out`
Most of the functions had leaks of the cypher context.
This patch uses `QByteArray` as the handler for the dynamically
allocated buffers for openssl to operate on. This also removes
the need for conversions from malloc'd buffers to `QByteArray`
variables previously present in the code.
It also introduces a `CypherCtx` thin wrapper class to provide
a leak-free handling of `EVP_CIPHER_CTX`.
In owncloudsetupnocredspage.ui, the URL input field leUrl has a
placeholder text saying "https://..." which is a very useful hint
for the user. However, in the OwncloudSetupPage constructor, the
placeholer text is overwritten by the return string of the theme's
wizardUrlHint() method. The NextcloudTheme class does not override
this virtual method, so an empty string is used.
To make available the "https://..." hint, it is moved from the
UI file to NextcloudTheme::wizardUrlHint(). Note that, if a
theme is used which does not allow a custom server URL, the
placeholder text is now empty. This makes sense because the
input field is disabled in that case.
Signed-off-by: Stephan Beyer <s-beyer@gmx.net>
In case of denormalized paths in the dav href (presence of . or .. in
the path) simple string startsWith comparison wasn't enough to know if
said href ended up in the right namespace. That's why we're now using
QUrl (pretending local file since we don't have a full URL in the href)
to normalize the path before comparison.
This could happen with broken proxies for instance where we would
wrongly validate the dav information resulting in potentially surprising
syncing and name collisions.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
The message handler globally installed by the logger silently drop
messages if the logger is not logging. On top of it, it doesn't log
debug messages by default.
Anything not logged is currently silently discarded. This can come as a
surprise to a developer trying to contribute for the first time and
adding some debug message for some reason.
We're thus trying to strike a middle ground which is that debug messages
get a regular output if the logger isn't interested in them.
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
- Application name, version number, OS
Example: Nextcloud Desktop Client
Version 2.6.4 (macOS)
- Keep previous version info in new method Theme::aboutDetails()
Signed-off-by: Michael Schuster <michael@schuster.ms>
So that user may continue to use http2 on their webpage
Signed-off-by: XNG <Milokita@users.noreply.github.com>
(cherry picked from commit dad95d4e4617211360bf2b4391e29c341e939844)
Signed-off-by: Michael Schuster <michael@schuster.ms>
- Fetch in ConnectionValidator::slotCapabilitiesRecieved
- Add editors to a list made of the new DirectEditor class
TODO:
- Add support for re-fetch and continously check for changes (ETag)
Signed-off-by: Michael Schuster <michael@schuster.ms>
This introduces a new method to change the colours in the links in QLabel's.
Utilizes a custom crafted RegEx function to replace already-coloured links.
Moved code is based on stuff from the SettingsDialog class.
Signed-off-by: Michael Schuster <michael@schuster.ms>
In certain cases don't write the app password in Account::writeAppPasswordOnce:
- id() is empty: This always happend once the Account Wizard showed the folder selection
- appPassword is empty: Caused by Logout -> Relaunch, preventing remote wipe on relaunch
Implement some logging to ease debugging in the future.
Signed-off-by: Michael Schuster <michael@schuster.ms>
Client SSL certificates and keys cannot be deleted at this time because there is
no UI for selecting them on re-login.
We introduce this dirty hack here, to allow deleting them upon Remote Wipe.
Signed-off-by: Michael Schuster <michael@schuster.ms>
The app password for the remote wipe was constantly being written in
WebFlowCredentials::slotFinished to the keychain, leading to unnecessary
write and log overhead on the system.
This fix introduces a check to only store the app password once in
a lifetime of the Account class. Also the method used to store the
password will be renamed from setAppPassword to writeAppPasswordOnce
to be more expressive.
Signed-off-by: Michael Schuster <michael@schuster.ms>
Drone builds failed with Qt 5.7 and we introduce a new ifdef here
to avoid patching specifically for Ubuntu Xenial only.
Signed-off-by: Michael Schuster <michael@schuster.ms>
- When the the users logs because of 401 or 403 errors, it checks if the
server requested the remote wipe. If yes, locally deletes account and folders
connected to the account and notify the server. If no, proceeds to ask the
user to login again.
- The app password is restored in the keychain.
- WIP: The change also includes a test class for RemoteWipe.
Signed-off-by: Camila San <hello@camila.codes>
This replaces `davUser()`, which is replaced by a numeric ID when using
LDAP, by the username that was actually used for logging in.
Fixes#836
Signed-off-by: Felix Eckhofer <felix@eckhofer.com>
There in no "return" in
PropagateUploadFileCommon::slotStartUpload in if (prevModtime != _item-
>_modtime) {... }
There is possibility that
PropagateItemJob::done(status, errorString)
maybe called two times from PropagateUploadFileCommon::slotStartUpload
1. in if (prevModtime != _item->_modtime) {... }
2. in if (fileIsStillChanging(*_item)) {..}
if changes in files are frequent the second call is possible.
This two calls has effect in PropagatorCompositeJob::slotSubJobFinished
and job is removed two times in _runningJobs.remove(i);
(the second time with argumetnt -1 (because first call removed job).
This return was removed in commit
efc039863b - by accident I think.
Good simulation is to synchronize firefox profile with frequent page
refresh.
Signed-off-by: Mariusz Wasak <mawasak@gmail.com>
It filters the error out of the list of blocking errors. It now shows up
in the Activities and Notificattions list as a warning.
Signed-off-by: Camila San <hello@camila.codes>
Instead of immediately popping up the mnemonic dialogue,
only show a notification bar on the account setup page.
For the cases where the user does not want to use E2E,
this is significantly less intrusive than the old approach.
For #566
Since we only showed the user exclude list (and some extra items) the
system exclude list was still used.
This copies over the system exclude list (if it isn't there).
If it fails we use the system one still.
However if you now remove items from your own list it will really be
gone.
Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
Fixes#788Fixes#834
If the activity app is not enabled we should not try to fetch the
activities at all.
Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
If we use the source format it can result in fully black images. As the
basic generated avatar doesn't have an alpha channel.
Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
Add a test to test the data fingerprint feature make me realize it was broken.
The code was relying in the distinction between empty and null QByteArray,
but this was a bad idea as this difference is lost when going through QString.
The server reply with a code 400 when the token is invalid,
the client was understanding this error as a network error, and was retying
again with the same token.
Instead, we must rely on what the json is saying, even if the reply is
not a 200 code.
Issue https://github.com/owncloud/enterprise/issues/2777
The check was added for #6317 in commit
13eb64584f.
We did see missing mtimes in replies in tests with live servers though.
Possibly those were old incomplete responses cached in the stat cache?
It could happen that readyRead was emitted for incoming data while the
download was not yet finished. Then the network job could finish with
no more data arriving - so readyRead wasn't emitted again.
To fix this, the finished signal also gets connected to the readyRead
slot.
The goal is to avoid confusion described in issue #6422 by removing
duplicates between the Theme and owncloudTheme.
- Use the about from ownCloudTheme everywhere
- Create default applicationIcons() and condifFileName() that should work
everywhere
- trayFolderIcon was removed as it is not used
- the helpUrl from the default Theme now points to the owncloud client
documentation. Before there was no help entry by default for branded
client if the function was not overriden.
- Do not merge functions that would otherwise break compatibility with
theme that did not override them. For example colors or customMedia.
When owncloud is restored, at boot time, it might be started before the
crendential manager. So if we detect an error, wait 10 seconds and hopefully
it'd be loaded by then.
Issues: #4274, #6522
Some servers have virus scanners and the like that can delay the
response of the final chunked upload assembly significantly, often
breaking the current 5min (!) timeout. See owncloud/enterprise#2480
for details.
Previously it tried to abort even jobs that had already finished, which
was not going to work as they wouldn't emit finished() again.
Also, in some cases the abortCount would never go to zero and that case
wasn't well documented.
Since commit 4dc49ff3, we store an entry in the upload info table even
for non chunked uploads. However, if this fails we don't want to remove
non-existant stale chunks if the upload fails.
Without this commit, we would send a DELETE command to clean non-existant
chunks in the dav/uploads/ namespace.
Before, we only cleared the _avoidReadFromDbOnNextSyncFilter *after* a
sync which meant that we had to sync twice after selective sync setup.
Now, we clear the filter *before* a sync as well which allows the actual
next sync to write the correct etags to the db again - instead of only
the sync after that one.
Also expand on comments and rename _avoidReadFromDbOnNextSyncFilter to
_etagStorageFilter.
We otherwise normalize all path in the C form, so we must have
the Folder's path normalized the same. Or all comparizon will fail
(such as knowing if a file from the SocketAPI or the FilesystemWatcher
are part of the folder)
Issue #4424
If the SyncResult incorrectly believes that there are no conflicts, the
tray icon won't be correct and there will be no warning about unresolved
conflicts on the account.
Nevertheless, it's pretty awkward that the IssuesWidget is better
informed about pending conflicts than the Folder itself. This kind of
backwards data flow is very confusing.
Unfortunately the only alternative I see is to either keep track of
this information in two places (also in Folder), or create a common
data-holding class that can serve as a model instance for the issues
view as well as provide data directly to the Folder - which would
have been a much larger change.
Everything is invalidated later: after discovery, not before. In
addition entries that should only be invalidated when new local
discovery is done have that behavior now.
(PR #6265)
- Remove the UI completely
- Move the #ifdef inside the FileSystem::moveToTrash function, so it is easier to
implement on other platforms
- Q_OS_UNIX includes mac, so we need to disable it. (not using Q_OS_LINUX because of
other BSD that uses XDG spec as well
- Translate the error messages
- Add a couple of doc comments
QFileInfo::isSymLink() does detect reparse points that are symlinks but
returns false for junctions. The new function FileSystem::isJunction()
can detect those and is used to not recursively delete files inside
directories that are junctions.
See also https://bugreports.qt.io/browse/QTBUG-45344 and the
discussion in the PR https://codereview.qt-project.org/#/c/113019/.
When populating the tree from the filesystem we need to fill
the e2eMangledName from DB and we when trying to find another
match on the oposite tree we need to take in account that names
don't match and search with the mangled name information
When a file on the server of an encrypted folder do
not have a matching entry on the JSON metadata, we
need to report an error and be done with the job
so that Sync status is not "running".
This eventually should cause the file to be removed
from the server as it can not be recovered anymore.
- Changes the configuration name in ConfigFile and GeneralSettings
accordingly with the new text.
- Makes sure the user sees error and conflict messages even if the
setting is disabled.
Signed-off-by: Camila San <hello@camila.codes>
If the code was not complex enough syncing two tables
already started to give UNIQUE constrains errors on
simple sync operations, this also adds initial support
remote delete of an encrypted file
Android only creates the metadata file when the first encrypted file is
added. We assumed it would be there.
This hacky code makes us store the metadata if there wasn't any yet.
Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
* Add a mimetype (mobile clients need this)
* Add the tag unencoded as we encode it when we send the metadata
already
Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
* Don't store the metadata yet this crashes android
- Yes android should be fixed but for now this is quicker ;)
* QSslKey exports PEM as PKCS#1
- This is not handled properly on android so use PKCS#8 helper
Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
* Pregerenate IV
* Pregenerate key
* Pregenerate filename
TODO:
- Reuse existing file entries and update (we might need logic in the
metadatahandling to do this properly).
Previously conflicts with a different type on both ends lead to sync
errors. Now they are handled in the expected way: the local item gets
renamed and the remote item gets propagated downwards.
This also adds a unittest for the TYPE_CHANGE case. That one looks like
parts of it might be unified with CONFLICT cases.
Mainly uses target_include_directories instead of include_directories
so libraries public include directory get automatically added when adding
the target in target_link_library
We append the salt (just like the IV) to the ciphertext of the private
key. This means we also have to split it off properly.
This breaks compartibility with currently stored keys on your server.
Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
Those functions had no use anymore since we store the key and cert in
the keychain. Removed them so we don't use them by accident.
Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
If the server has the 'uploadConflictFiles' capability conflict
files will be uploaded instead of ignored.
Uploaded conflict files have the following headers set during upload
OC-Conflict: 1
OC-ConflictBaseFileId: 172489174instanceid
OC-ConflictBaseMtime: 1235789213
OC-ConflictBaseEtag: myetag
when the data is available. Downloads accept the same headers in return
when downloading a conflict file.
In the absence of server support clients will identify conflict files
through the file name pattern and attempt to deduce the base fileid.
Base etag and mtime can't be deduced though.
The upload job for a new conflict file will be triggered directly from
the job that created the conflict file now. No second sync run is
necessary anymore.
This commit does not yet introduce a 'username' like identifier that
automatically gets added to conflict file filenames (to name the files
foo_conflict-Fred-1345.txt instead of just foo_conflict-1345.txt).
Previously, there was csync_ftw_type_e and SyncFileItem::Type. Having
two enums lead to a bug where Type::Unknown == Type::File that went
unnoticed for a good while.
This patch keeps only a single enum.
If the application binary is not installed in /usr/bin the client
with this patch considers to check the relative location
../../etc/owncloud-client/ to find the system exclude.
This is an important bit for AppImage based packages of the client,
as this runs from a temporar mountpoint and the system file can not
be found under /etc.
This can happen if the upload of a file is finished, but we just got
disconnected right before recieving the reply containing the etag.
So nothing was save din the DB, and we are not sure if the server
recieved the file properly or not. Further local update of the file
will cause a conflict.
In order to fix this, store the checksum of the uploading file in
the uploadinfo table of the local db (even if there is no chunking
involved). And when we have a conflict, check that it is not because
of this situation by checking the entry in the uploadinfo table.
Issue #5106
The upload is made in an event loop with more than one
upload at the same time, this confuses the hell out of the
folder locking mechanism.
We need to lock the folder and ask the other trials to try
again in a few seconds in the future to give time for the
uploader to actually upload the current file that's locking
the folder.