-
Notifications
You must be signed in to change notification settings - Fork 32
/
ipacl_test.go
144 lines (128 loc) · 3.06 KB
/
ipacl_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package rsync_test
import (
"bytes"
"net"
"os"
"os/exec"
"path/filepath"
"strings"
"testing"
"github.com/gokrazy/rsync/internal/rsyncdconfig"
"github.com/gokrazy/rsync/internal/rsynctest"
)
type connWithRemoteAddrListener struct {
net.Listener
remoteAddr net.Addr
}
func (l *connWithRemoteAddrListener) Accept() (net.Conn, error) {
conn, err := l.Listener.Accept()
if err != nil {
return nil, err
}
return &connWithRemoteAddr{
Conn: conn,
remoteAddr: l.remoteAddr,
}, nil
}
type connWithRemoteAddr struct {
net.Conn
remoteAddr net.Addr
}
func (c *connWithRemoteAddr) RemoteAddr() net.Addr {
return c.remoteAddr
}
func TestIPACL(t *testing.T) {
tmp := t.TempDir()
source := filepath.Join(tmp, "source")
dest := filepath.Join(tmp, "dest")
// create files in source to be copied
if err := os.MkdirAll(source, 0755); err != nil {
t.Fatal(err)
}
cfg, err := rsyncdconfig.FromString(`
[[module]]
name = "interop"
path = "` + source + `"
acl = [
"allow 192.168.1.0/24",
"allow 2001:db8::1/32",
"deny all"
]
`)
if err != nil {
t.Fatal(err)
}
for _, tt := range []struct {
remoteAddr string
wantError bool
}{
{
remoteAddr: "192.168.1.1",
wantError: false,
},
{
remoteAddr: "2001:db8::1234",
wantError: false,
},
{
remoteAddr: "10.0.0.1",
wantError: true,
},
} {
t.Run(tt.remoteAddr, func(t *testing.T) {
ln, err := net.Listen("tcp", "localhost:0")
if err != nil {
t.Fatal(err)
}
ln = &connWithRemoteAddrListener{
Listener: ln,
remoteAddr: &net.TCPAddr{
IP: net.ParseIP(tt.remoteAddr),
Port: 1234,
},
}
srv := rsynctest.New(t, cfg.Modules, rsynctest.Listener(ln))
// request module list: this should work regardless of the source IP
var buf bytes.Buffer
rsync := exec.Command("rsync", //"/home/michael/src/openrsync/openrsync",
// "--debug=all4",
"--archive",
"-v", "-v", "-v", "-v",
"--port="+srv.Port,
"rsync://localhost")
rsync.Stdout = &buf
rsync.Stderr = os.Stderr
if err := rsync.Run(); err != nil {
t.Fatalf("%v: %v", rsync.Args, err)
}
output := buf.String()
if want := "interop\tinterop"; !strings.Contains(output, want) {
t.Fatalf("rsync output unexpectedly did not contain %q:\n%s", want, output)
}
buf.Reset()
// actually transfer the interop module (in dry-run mode) to trigger
// the ACL check dry run (slight differences in protocol)
rsync = exec.Command("rsync", //"/home/michael/src/openrsync/openrsync",
// "--debug=all4",
"--archive",
"-v", "-v", "-v", "-v",
"--port="+srv.Port,
"--dry-run",
"rsync://localhost/interop/", // copy contents of interop
//source+"/", // sync from local directory
dest) // directly into dest
rsync.Stdout = os.Stdout
rsync.Stderr = &buf
if err := rsync.Run(); err != nil {
if !tt.wantError {
t.Fatalf("%v: %v", rsync.Args, err)
}
}
if tt.wantError {
if !strings.Contains(buf.String(), "@ERROR: access denied") {
t.Fatalf("expected access denied error, got: %q", buf.String())
}
}
})
}
}