mirror of
https://github.com/octoleo/syncthing.git
synced 2024-12-23 11:28:59 +00:00
Merge pull request #2639 from calmh/minihashalgo
Detect nonstandard hash algo and stop folder (ref #2314)
This commit is contained in:
commit
44d5a61cfe
@ -520,11 +520,7 @@ func (m *Model) Index(deviceID protocol.DeviceID, folder string, fs []protocol.F
|
|||||||
l.Debugf("IDX(in): %s %q: %d files", deviceID, folder, len(fs))
|
l.Debugf("IDX(in): %s %q: %d files", deviceID, folder, len(fs))
|
||||||
|
|
||||||
if !m.folderSharedWith(folder, deviceID) {
|
if !m.folderSharedWith(folder, deviceID) {
|
||||||
events.Default.Log(events.FolderRejected, map[string]string{
|
l.Debugf("Unexpected folder ID %q sent from device %q; ensure that the folder exists and that this device is selected under \"Share With\" in the folder configuration.", folder, deviceID)
|
||||||
"folder": folder,
|
|
||||||
"device": deviceID.String(),
|
|
||||||
})
|
|
||||||
l.Infof("Unexpected folder ID %q sent from device %q; ensure that the folder exists and that this device is selected under \"Share With\" in the folder configuration.", folder, deviceID)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -566,7 +562,7 @@ func (m *Model) IndexUpdate(deviceID protocol.DeviceID, folder string, fs []prot
|
|||||||
l.Debugf("%v IDXUP(in): %s / %q: %d files", m, deviceID, folder, len(fs))
|
l.Debugf("%v IDXUP(in): %s / %q: %d files", m, deviceID, folder, len(fs))
|
||||||
|
|
||||||
if !m.folderSharedWith(folder, deviceID) {
|
if !m.folderSharedWith(folder, deviceID) {
|
||||||
l.Infof("Update for unexpected folder ID %q sent from device %q; ensure that the folder exists and that this device is selected under \"Share With\" in the folder configuration.", folder, deviceID)
|
l.Debugf("Update for unexpected folder ID %q sent from device %q; ensure that the folder exists and that this device is selected under \"Share With\" in the folder configuration.", folder, deviceID)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -596,6 +592,10 @@ func (m *Model) IndexUpdate(deviceID protocol.DeviceID, folder string, fs []prot
|
|||||||
func (m *Model) folderSharedWith(folder string, deviceID protocol.DeviceID) bool {
|
func (m *Model) folderSharedWith(folder string, deviceID protocol.DeviceID) bool {
|
||||||
m.fmut.RLock()
|
m.fmut.RLock()
|
||||||
defer m.fmut.RUnlock()
|
defer m.fmut.RUnlock()
|
||||||
|
return m.folderSharedWithUnlocked(folder, deviceID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Model) folderSharedWithUnlocked(folder string, deviceID protocol.DeviceID) bool {
|
||||||
for _, nfolder := range m.deviceFolders[deviceID] {
|
for _, nfolder := range m.deviceFolders[deviceID] {
|
||||||
if nfolder == folder {
|
if nfolder == folder {
|
||||||
return true
|
return true
|
||||||
@ -629,6 +629,37 @@ func (m *Model) ClusterConfig(deviceID protocol.DeviceID, cm protocol.ClusterCon
|
|||||||
|
|
||||||
m.pmut.Unlock()
|
m.pmut.Unlock()
|
||||||
|
|
||||||
|
// Check the peer device's announced folders against our own. Emits events
|
||||||
|
// for folders that we don't expect (unknown or not shared).
|
||||||
|
|
||||||
|
m.fmut.Lock()
|
||||||
|
nextFolder:
|
||||||
|
for _, folder := range cm.Folders {
|
||||||
|
cfg := m.folderCfgs[folder.ID]
|
||||||
|
|
||||||
|
if _, err := protocol.HashAlgorithmFromFlagBits(folder.Flags); err != nil {
|
||||||
|
// The hash algorithm failed to deserialize, so it's not SHA256
|
||||||
|
// (the only acceptable algorithm).
|
||||||
|
l.Warnf("Device %v: %v", deviceID, err)
|
||||||
|
cfg.Invalid = err.Error() + " from " + deviceID.String()
|
||||||
|
m.cfg.SetFolder(cfg)
|
||||||
|
if srv := m.folderRunners[folder.ID]; srv != nil {
|
||||||
|
srv.setError(fmt.Errorf(cfg.Invalid))
|
||||||
|
}
|
||||||
|
continue nextFolder
|
||||||
|
}
|
||||||
|
|
||||||
|
if !m.folderSharedWithUnlocked(folder.ID, deviceID) {
|
||||||
|
events.Default.Log(events.FolderRejected, map[string]string{
|
||||||
|
"folder": folder.ID,
|
||||||
|
"device": deviceID.String(),
|
||||||
|
})
|
||||||
|
l.Infof("Unexpected folder ID %q sent from device %q; ensure that the folder exists and that this device is selected under \"Share With\" in the folder configuration.", folder.ID, deviceID)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m.fmut.Unlock()
|
||||||
|
|
||||||
events.Default.Log(events.DeviceConnected, event)
|
events.Default.Log(events.DeviceConnected, event)
|
||||||
|
|
||||||
l.Infof(`Device %s client is "%s %s" named "%s"`, deviceID, cm.ClientName, cm.ClientVersion, cm.DeviceName)
|
l.Infof(`Device %s client is "%s %s" named "%s"`, deviceID, cm.ClientName, cm.ClientVersion, cm.DeviceName)
|
||||||
|
54
lib/protocol/hashalgorithm.go
Normal file
54
lib/protocol/hashalgorithm.go
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
// Copyright (C) 2016 The Protocol Authors.
|
||||||
|
|
||||||
|
package protocol
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type HashAlgorithm int
|
||||||
|
|
||||||
|
const (
|
||||||
|
SHA256 HashAlgorithm = iota
|
||||||
|
)
|
||||||
|
|
||||||
|
func (h HashAlgorithm) String() string {
|
||||||
|
switch h {
|
||||||
|
case SHA256:
|
||||||
|
return "sha256"
|
||||||
|
default:
|
||||||
|
return "unknown"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FlagBits returns the bits that we should or into the folder flag field to
|
||||||
|
// indicate the hash algorithm.
|
||||||
|
func (h HashAlgorithm) FlagBits() uint32 {
|
||||||
|
switch h {
|
||||||
|
case SHA256:
|
||||||
|
return FolderHashSHA256 << FolderHashShiftBits
|
||||||
|
default:
|
||||||
|
panic("unknown hash algorithm")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HashAlgorithm) UnmarshalText(bs []byte) error {
|
||||||
|
switch string(bs) {
|
||||||
|
case "sha256":
|
||||||
|
*h = SHA256
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Unknown hash algorithm %q", string(bs))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HashAlgorithm) MarshalText() ([]byte, error) {
|
||||||
|
return []byte(h.String()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func HashAlgorithmFromFlagBits(flags uint32) (HashAlgorithm, error) {
|
||||||
|
algo := flags >> FolderHashShiftBits & FolderHashMask
|
||||||
|
switch algo {
|
||||||
|
case FolderHashSHA256:
|
||||||
|
return SHA256, nil
|
||||||
|
default:
|
||||||
|
return 0, fmt.Errorf("Unknown hash algorithm %d", algo)
|
||||||
|
}
|
||||||
|
}
|
35
lib/protocol/hashalgorithm_test.go
Normal file
35
lib/protocol/hashalgorithm_test.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// Copyright (C) 2016 The Protocol Authors.
|
||||||
|
|
||||||
|
package protocol
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
/*
|
||||||
|
0 1 2 3
|
||||||
|
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
| Reserved | Hash |D|P|R|
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
*/
|
||||||
|
func TestHashAlgorithmFromFlagBits(t *testing.T) {
|
||||||
|
// SHA256 is algorithm zero, shifted three bits to the left (for clarity,
|
||||||
|
// I know it doesn't actually do anything).
|
||||||
|
|
||||||
|
sha256 := uint32(0 << 3)
|
||||||
|
|
||||||
|
h, err := HashAlgorithmFromFlagBits(sha256)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if h != SHA256 {
|
||||||
|
t.Error("Zero should have unmarshalled as SHA256")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Any other algorithm is unknown
|
||||||
|
unknown := uint32(1 << 3)
|
||||||
|
|
||||||
|
_, err = HashAlgorithmFromFlagBits(unknown)
|
||||||
|
if err == nil {
|
||||||
|
t.Error("Unknown algo should not have unmarshalled")
|
||||||
|
}
|
||||||
|
}
|
@ -66,6 +66,13 @@ const (
|
|||||||
FlagFolderReadOnly uint32 = 1 << 0
|
FlagFolderReadOnly uint32 = 1 << 0
|
||||||
FlagFolderIgnorePerms = 1 << 1
|
FlagFolderIgnorePerms = 1 << 1
|
||||||
FlagFolderIgnoreDelete = 1 << 2
|
FlagFolderIgnoreDelete = 1 << 2
|
||||||
|
|
||||||
|
// The folder hash algorithm IDs, to be put in the flags field by shifting
|
||||||
|
// left FolderHashShiftBits
|
||||||
|
FolderHashSHA256 = 0
|
||||||
|
// ... 1 through 15 currently reserved
|
||||||
|
FolderHashMask = 15
|
||||||
|
FolderHashShiftBits = 3
|
||||||
)
|
)
|
||||||
|
|
||||||
// ClusterConfigMessage.Folders.Devices flags
|
// ClusterConfigMessage.Folders.Devices flags
|
||||||
|
Loading…
Reference in New Issue
Block a user