Repository: syncthing/syncthing (language: go)

Issue:
v1.23.6 introduces untrusted sharing regression
I upgraded my Syncthing "server"/central peer to 1.23.6 (Linux/docker) and it broke resharing an untrusted folder.

Peer A shares a folder with Server. Peer A considers Server as untrusted. The folder is shared encrypted.
Peer B also shares that same folder with Server. It also considers Server as untrusted.

After updating, syncthing on Server says "Folder \<id> (\<name>) is shared in trusted mode with untrusted device \<Peer B>; unsharing".

Downgrading to 1.23.5 fixes it. I also re-upgraded and it broke again, so it seems likely to be a regression.


Discussion / hints:
I don't understand your setup. `B` considers `Server` untrusted. `Server` apparently considers `B` untrusted. Why?
Thanks for the quick reply!  

I marked B as untrusted on Server. I forgot I had done that, sorry, definitely should've included it.  
I want to be sure Server never sends anything unencrypted to B. B is actually another person's device, who I allow to use Server to simplify syncing between devices that aren't necessarily online at the same time. Basically a laptop and a phone.

So my understanding is with 1.23.6, Server no longer considers a folder received as encrypted safe to share with an untrusted peer. I think that's a valid use case as my situation is not too weird :)
Yeah, I think the situation for re-sharing already-encrypted data isn't especially polished...

For `untrusted`, I guess you can see it as a flag to say the other side cannot be trusted with the data we have without additional encryption. When sending already-encrypted data the other side is not less trusted than you are, you're at the same trust level.
This is causing some errors. My friend and I are using synching to cross backup each others information. They have a synching set to untrusted and set a password for the share, and I set them to be untrusted with a password for my share. I am running 1.23.4 and I can accept their share but they cannot accept my share and they are on 1.23.6. 
> This is causing some errors. My friend and I are using synching to cross backup each others information. They have a synching set to untrusted and set a password for the share, and I set them to be untrusted with a password for my share. I am running 1.23.4 and I can accept their share but they cannot accept my share and they are on 1.23.6.

Can confirm this. The following configuration does not work when "my device" is running 1.23.6, and "their device" is running 1.23.4:
- their device and my device both mark each other as untrusted
- their folder is shared (as encrypted) with my device
- when I accept the share (as receive encrypted), my device unshares it and a notice pops up saying: "Folder { their folder } is shared in trusted mode with untrusted device { their device }; unsharing."
- The only workaround I've found is to not mark "their device" as untrusted, which means my device cannot use the "untrusted" functionality. Having them delete "their folder" on "their device", recreate it, then share it with my device didn't help.

It is noted that the reverse setup (my device shares encrypted folder with device running 1.23.4) does not have this same issue. To confirm, I have downgraded my device to 1.23.5, marked "their device" as untrusted, and the share works as expected. When I upgrade back to 1.23.6, the share is immediately unshared like described above.

It seems that commit 6b475bdb78eb671866419ff84a4cda6285c90244 is the source of this bug, or reveals a bug elsewhere. Is there anything I can do to help troubleshoot this?

For some context on the use case for a configuration like this, this allows two people to provide offsite backup as well as redundancy to each other without revealing the contents of each person's data. It's very useful. 

Right, it should be possible to have receive-encrypted folders from an untrusted device.
Would replacing the following code added in 6b475bdb78eb671866419ff84a4cda6285c90244 in lib/config/config.go be consistent with the intent of the untrusted feature and likely to fix the problem? 
```
if dev.EncryptionPassword != "" {
			// There's a password set, no check required
			continue
		}
```
Add OR:
```
if dev.EncryptionPassword != "" || f.type == config.FolderTypeReceiveEncrypted {
			// There's a password set or the folder is received encrypted, no check required
			continue
		}
```
The syntax and other aspects may not be correct (I don't know go or the syncthing code structure), but it seems like an untrusted device share is acceptable if a password is set OR the folder is a receive encrypted type (where you shouldn't know the password). 
That seems about correct, yes.
> That seems about correct, yes.

Ok, I'll test this change and if it seems to work I'll submit a PR for review.

Thanks
I'm hit by what could be a variation of this bug, possibly with a common root cause, since updating to 1.23.6, but probably specific to Windows:

My setup:

3 devices: server (Debian 11, running 24/7), notebook (Windows 10), desktop (Ubuntu 22.04), all in the same LAN.
All devices are trusting each other and are sharing multiple shares.
Some data ("crypto" share) must be encrypted on the server by organizational policy, but is o.k. to reside normally on desktop and notebook (their disks are fully encrypted, server's disk is not), so I'm using this setup for the crypto share:
@Desktop, @Notebook: sharing normally to each other, but sharing encrypted to server
@Server: share type is "receive encrypted"


Expected behaviour:
All 3 devices consider all others connected and do exchange data.

Actual behaviour:

Server and Notebook consider each other disconnected. That's the problem.
Desktop is connecting fine to Server and Notebook.
Notebook is connecting to Desktop but not to Server.
Server is connecting to Desktop but not to Notebook.


The observation that only the Notebook is having issues makes me think that this is bug is Windows specific and encryption specific, because it works unencrypted between Windows and Linux and it works encrypted between Linux and Linux.

Log at Server (repeats ca. every 15 seconds):
2023-07-06 21:46:02 Established secure connection to (notebook-id) at (server-ip):22000-(notebook-ip):22000/quic-server/TLS1.3-TLS_AES_128_GCM_SHA256/LAN-P20
2023-07-06 21:46:02 Device (ID of notebook) client is "syncthing v1.23.6" named "(notebook's name)" at (server-ip):22000-(notebook-ip):22000/quic-server/TLS1.3-TLS_AES_128_GCM_SHA256/LAN-P20
2023-07-06 21:46:02 Connection to (notebook-id) at (server-ip):22000-(notebook-ip):22000/quic-server/TLS1.3-TLS_AES_128_GCM_SHA256/LAN-P20 closed: reading length: Application error 0x0 (remote): closing

Log at Notebook (repeats ca. every 15 seconds):
2023-07-06 21:46:02 Established secure connection to (server-id) at [::]:22000-(server-ip):22000/quic-client/TLS1.3-TLS_AES_128_GCM_SHA256/LAN-P20
2023-07-06 21:46:02 Device (server-id) client is "syncthing v1.23.6" named "(server's name)" at [::]:22000-(server-ip):22000/quic-client/TLS1.3-TLS_AES_128_GCM_SHA256/LAN-P20
2023-07-06 21:46:02 Connection to (server-id) at [::]:22000-(server-ip):22000/quic-client/TLS1.3-TLS_AES_128_GCM_SHA256/LAN-P20 closed: handling index-update for (crypto-share-id): chacha20poly1305: message authentication failed

What I've tried but didn't help:
- restarting Syncthing and machines, multiple times
- Suspend Antivirus (ESET) on Notebook (Windows). (Desktop (Linux) also has ESET AV, but ESET on Linux is quite different from ESET on Windows.)
- remove and re-add the crypto share on Notebook

What additional information do you need to track this down?
@martinstut your issue is unrelated, please use the forum. 

Fix patch:
diff --git a/lib/config/config.go b/lib/config/config.go
index 0534d5f91eb..8787cf8b504 100644
--- a/lib/config/config.go
+++ b/lib/config/config.go
@@ -556,8 +556,8 @@ loop:
 func ensureNoUntrustedTrustingSharing(f *FolderConfiguration, devices []FolderDeviceConfiguration, existingDevices map[protocol.DeviceID]*DeviceConfiguration) []FolderDeviceConfiguration {
 	for i := 0; i < len(devices); i++ {
 		dev := devices[i]
-		if dev.EncryptionPassword != "" {
-			// There's a password set, no check required
+		if dev.EncryptionPassword != "" || f.Type == FolderTypeReceiveEncrypted {
+			// There's a password set or the folder is received encrypted, no check required
 			continue
 		}
 		if devCfg := existingDevices[dev.DeviceID]; devCfg.Untrusted {


Test patch: