浏览代码

Merge pull request #1259 from calmh/check-folder-shared

Verify folder<->device permission in Request
Audrius Butkevicius 11 年之前
父节点
当前提交
5ac7564bfe
共有 2 个文件被更改,包括 32 次插入4 次删除
  1. 7 2
      internal/model/model.go
  2. 25 2
      internal/model/model_test.go

+ 7 - 2
internal/model/model.go

@@ -710,9 +710,14 @@ func (m *Model) Close(device protocol.DeviceID, err error) {
 // Request returns the specified data segment by reading it from local disk.
 // Implements the protocol.Model interface.
 func (m *Model) Request(deviceID protocol.DeviceID, folder, name string, offset int64, size int) ([]byte, error) {
+	if !m.folderSharedWith(folder, deviceID) {
+		l.Warnf("Request from %s for file %s in unshared folder %q", deviceID, name, folder)
+		return nil, ErrNoSuchFile
+	}
+
 	// Verify that the requested file exists in the local model.
 	m.fmut.RLock()
-	r, ok := m.folderFiles[folder]
+	folderFiles, ok := m.folderFiles[folder]
 	m.fmut.RUnlock()
 
 	if !ok {
@@ -720,7 +725,7 @@ func (m *Model) Request(deviceID protocol.DeviceID, folder, name string, offset
 		return nil, ErrNoSuchFile
 	}
 
-	lf, ok := r.Get(protocol.LocalDeviceID, name)
+	lf, ok := folderFiles.Get(protocol.LocalDeviceID, name)
 	if !ok {
 		return nil, ErrNoSuchFile
 	}

+ 25 - 2
internal/model/model_test.go

@@ -68,18 +68,41 @@ func init() {
 
 func TestRequest(t *testing.T) {
 	db, _ := leveldb.Open(storage.NewMemStorage(), nil)
+
 	m := NewModel(config.Wrap("/tmp/test", config.Configuration{}), "device", "syncthing", "dev", db)
-	m.AddFolder(config.FolderConfiguration{ID: "default", Path: "testdata"})
+
+	// device1 shares default, but device2 doesn't
+	m.AddFolder(config.FolderConfiguration{ID: "default", Path: "testdata", Devices: []config.FolderDeviceConfiguration{{DeviceID: device1}}})
 	m.ScanFolder("default")
 
+	// Existing, shared file
 	bs, err := m.Request(device1, "default", "foo", 0, 6)
 	if err != nil {
-		t.Fatal(err)
+		t.Error(err)
 	}
 	if bytes.Compare(bs, []byte("foobar")) != 0 {
 		t.Errorf("Incorrect data from request: %q", string(bs))
 	}
 
+	// Existing, nonshared file
+	bs, err = m.Request(device2, "default", "foo", 0, 6)
+	if err == nil {
+		t.Error("Unexpected nil error on insecure file read")
+	}
+	if bs != nil {
+		t.Errorf("Unexpected non nil data on insecure file read: %q", string(bs))
+	}
+
+	// Nonexistent file
+	bs, err = m.Request(device1, "default", "nonexistent", 0, 6)
+	if err == nil {
+		t.Error("Unexpected nil error on insecure file read")
+	}
+	if bs != nil {
+		t.Errorf("Unexpected non nil data on insecure file read: %q", string(bs))
+	}
+
+	// Shared folder, but disallowed file name
 	bs, err = m.Request(device1, "default", "../walk.go", 0, 6)
 	if err == nil {
 		t.Error("Unexpected nil error on insecure file read")