Repository navigation
Conversation
|
/backport to stable-34.0 |
|
/backport to stable-35.0 |
1cb5951 to
d16fa95
Compare
d16fa95 to
7e665b1
Compare
7e665b1 to
aad263a
Compare
The file provider extension stored the account password as a generic password and scoped it with kSecAttrServer. That attribute belongs to internet passwords and macOS ignores it on generic passwords, so every lookup and update matched on the account name alone. Saving the password overwrote the generic passwords of other applications using the same account name, as reported in #9865, and a lookup could return one of them. Key the item by the file provider domain identifier as service and the user name as account, and show the domain display name as its label. Items written by earlier versions are left alone because they cannot be told apart from the items of other applications. Refs #9865 Co-authored-by: Jonathan Stucklen <stuckj@gmail.com> Assisted-by: ClaudeCode:claude-opus-5-5 Signed-off-by: Iva Horn <iva.horn@nextcloud.com>
… out removeAccountConfig now also deletes every keychain item of the domain. The main app sends it when the account is signed out, needs credentials again, is redirected or must accept the terms of service. Without this, Finder could authenticate the domain again with a password the user signed out of, and every account removed and added again would leave one more item behind now that items are keyed by domain. Refs #9865 Assisted-by: ClaudeCode:claude-opus-5-5 Signed-off-by: Iva Horn <iva.horn@nextcloud.com>
The extension cannot run once its domain is removed, so the password it stored would stay in the keychain. Add a request through which the main app asks the extension of a domain to delete its stored password, and send it as the first step of every domain removal. The main app waits at most one second for the reply and removes the domain in any case. The request is a new method instead of a changed removeAccountConfig because an extension still running an older build drops a selector it does not know, which would also drop the existing sign-out handling. Refs #9865 Assisted-by: ClaudeCode:claude-opus-5-5 Signed-off-by: Iva Horn <iva.horn@nextcloud.com>
…eProviderKit The keychain regression tests skip themselves when the default keychain is not usable. In CI that would hide them silently, so require them there, and limit how long the test job can run in case the keychain waits for user interaction. Refs #9865 Assisted-by: ClaudeCode:claude-opus-5-5 Signed-off-by: Iva Horn <iva.horn@nextcloud.com>
aad263a to
33a8c62
Compare
|
| if (!xpc) { | ||
| qCInfo(lcMacFileProvider) << "Not deleting password because XPC is not configured." << fileProviderDomainIdentifier; | ||
| return std::nullopt; | ||
| } |
There was a problem hiding this comment.
Startup orphan removal skips password cleanup -> returns immediately without XPC. The settings controller removes orphaned domains before calling configureXPC(), so that path removes domains without sending a deletion request, leaving scoped credentials behind. It needs to acquire the domain’s service before removal. This finding is based on source inspection.
| public func deletePassword(completionHandler: ((Bool) -> Void)?) { | ||
| logger.info("Received request to delete the stored password.") | ||
| let deleted = keychain.deletePassword() | ||
| completionHandler?(deleted) | ||
| } |
There was a problem hiding this comment.
Queued setup can recreate a deleted password -> deletes independently of setupChain. This is reproducible: hold authentication A, queue configuration B, delete successfully, then release A—B stores its password afterward. Deletion needs to invalidate pending setup and coordinate with credential writes. The sign-out path has the same ordering problem.



Intentionally skipping 34.0.5 and 35.0.0 and to be ported back later! Fixes #10976. Replaces #10858. Relates to #9865.
Thanks to @stuckj for clearing this issue up and taking the initiative! I probably would not have seen the problem here without their help and first draft.
Checklist
AI (if applicable)