Bladeren bron

Add tests for obfuscated2 clientside

tags/v2.0.0-rc1
9seconds 5 jaren geleden
bovenliggende
commit
69203f3e23

+ 0
- 2
.github/workflows/ci.yaml Bestand weergeven

@@ -30,8 +30,6 @@ jobs:
30 30
     strategy:
31 31
       matrix:
32 32
         go_version:
33
-          - ~1.14
34
-          - ~1.15
35 33
           - ^1.16
36 34
     steps:
37 35
       - name: Checkout

+ 2
- 3
cli/access.go Bestand weergeven

@@ -5,7 +5,6 @@ import (
5 5
 	"encoding/json"
6 6
 	"fmt"
7 7
 	"io"
8
-	"io/ioutil"
9 8
 	"net"
10 9
 	"net/http"
11 10
 	"net/url"
@@ -123,11 +122,11 @@ func (c *Access) getIP(protocol string) net.IP {
123 122
 	}
124 123
 
125 124
 	defer func() {
126
-		io.Copy(ioutil.Discard, resp.Body) // nolint: errcheck
125
+		io.Copy(io.Discard, resp.Body) // nolint: errcheck
127 126
 		resp.Body.Close()
128 127
 	}()
129 128
 
130
-	data, err := ioutil.ReadAll(resp.Body)
129
+	data, err := io.ReadAll(resp.Body)
131 130
 	if err != nil {
132 131
 		return nil
133 132
 	}

+ 2
- 2
cli/base.go Bestand weergeven

@@ -2,9 +2,9 @@ package cli
2 2
 
3 3
 import (
4 4
 	"fmt"
5
-	"io/ioutil"
6 5
 	"net"
7 6
 	"net/url"
7
+	"os"
8 8
 
9 9
 	"github.com/9seconds/mtg/v2/config"
10 10
 	"github.com/9seconds/mtg/v2/mtglib"
@@ -19,7 +19,7 @@ type base struct {
19 19
 }
20 20
 
21 21
 func (b *base) ReadConfig(version string) error {
22
-	content, err := ioutil.ReadFile(b.ConfigPath)
22
+	content, err := os.ReadFile(b.ConfigPath)
23 23
 	if err != nil {
24 24
 		return fmt.Errorf("cannot read config file: %w", err)
25 25
 	}

+ 2
- 2
config/config_test.go Bestand weergeven

@@ -1,7 +1,7 @@
1 1
 package config_test
2 2
 
3 3
 import (
4
-	"io/ioutil"
4
+	"os"
5 5
 	"path/filepath"
6 6
 	"testing"
7 7
 
@@ -14,7 +14,7 @@ type ConfigTestSuite struct {
14 14
 }
15 15
 
16 16
 func (suite *ConfigTestSuite) ReadConfig(filename string) []byte {
17
-	data, err := ioutil.ReadFile(filepath.Join("testdata", filename))
17
+	data, err := os.ReadFile(filepath.Join("testdata", filename))
18 18
 	suite.NoError(err)
19 19
 
20 20
 	return data

+ 1
- 2
ipblocklist/firehol.go Bestand weergeven

@@ -5,7 +5,6 @@ import (
5 5
 	"context"
6 6
 	"fmt"
7 7
 	"io"
8
-	"io/ioutil"
9 8
 	"net"
10 9
 	"net/http"
11 10
 	"net/url"
@@ -216,7 +215,7 @@ func (f *Firehol) updateRemoteURL(ctx context.Context, url string,
216 215
 	}(ctx, resp.Body)
217 216
 
218 217
 	defer func(rc io.ReadCloser) {
219
-		io.Copy(ioutil.Discard, rc) // nolint: errcheck
218
+		io.Copy(io.Discard, rc) // nolint: errcheck
220 219
 		rc.Close()
221 220
 	}(resp.Body)
222 221
 

+ 1
- 1
mtglib/internal/obfuscated2/client_handshake.go Bestand weergeven

@@ -8,7 +8,7 @@ import (
8 8
 	"io"
9 9
 )
10 10
 
11
-func ClientHandshake(secret []byte, reader io.Reader) (int16, cipher.Stream, cipher.Stream, error) {
11
+func ClientHandshake(secret []byte, reader io.Reader) (int, cipher.Stream, cipher.Stream, error) {
12 12
 	handshake := clientHandhakeFrame{}
13 13
 
14 14
 	if _, err := io.ReadFull(reader, handshake.data[:]); err != nil {

+ 85
- 0
mtglib/internal/obfuscated2/client_handshake_test.go Bestand weergeven

@@ -0,0 +1,85 @@
1
+package obfuscated2_test
2
+
3
+import (
4
+	"bytes"
5
+	"testing"
6
+
7
+	"github.com/9seconds/mtg/v2/mtglib/internal/obfuscated2"
8
+	"github.com/9seconds/mtg/v2/testlib"
9
+	"github.com/stretchr/testify/assert"
10
+	"github.com/stretchr/testify/mock"
11
+	"github.com/stretchr/testify/suite"
12
+)
13
+
14
+type ClientHandshakeTestSuite struct {
15
+	suite.Suite
16
+	SnapshotTestSuite
17
+}
18
+
19
+func (suite *ClientHandshakeTestSuite) SetupSuite() {
20
+	suite.NoError(suite.IngestSnapshots("client_snapshots", "snapshot-ok-"))
21
+}
22
+
23
+func (suite *ClientHandshakeTestSuite) TestCannotRead() {
24
+	buf := bytes.NewBuffer([]byte{1, 2, 3})
25
+	_, _, _, err := obfuscated2.ClientHandshake([]byte{1, 2, 3}, buf) // nolint: dogsled
26
+
27
+	suite.Error(err)
28
+}
29
+
30
+func (suite *ClientHandshakeTestSuite) TestOk() {
31
+	for nameV, snapshotV := range suite.snapshots {
32
+		snapshot := snapshotV
33
+
34
+		suite.T().Run(nameV, func(t *testing.T) {
35
+			buf := bytes.NewBuffer(snapshot.Frame.data)
36
+
37
+			dc, encryptor, decryptor, err := obfuscated2.ClientHandshake(
38
+				snapshot.Secret.data, buf)
39
+			assert.NoError(t, err)
40
+			assert.EqualValues(t, snapshot.DC, dc)
41
+
42
+			writeData := make([]byte, len(snapshot.Encrypted.Text.data))
43
+			readData := make([]byte, len(snapshot.Decrypted.Text.data))
44
+
45
+			connMock := &testlib.NetConnMock{}
46
+			connMock.On("Read", mock.Anything).
47
+				Once().
48
+				Return(len(snapshot.Decrypted.Text.data), nil).
49
+				Run(func(args mock.Arguments) {
50
+					arr := args.Get(0).([]byte)
51
+					copy(arr, snapshot.Decrypted.Cipher.data)
52
+				})
53
+			connMock.On("Write", mock.Anything).
54
+				Once().
55
+				Return(len(snapshot.Encrypted.Text.data), nil).
56
+				Run(func(args mock.Arguments) {
57
+					arr := args.Get(0).([]byte)
58
+					copy(writeData, arr)
59
+				})
60
+
61
+			conn := &obfuscated2.Conn{
62
+				Conn:      connMock,
63
+				Encryptor: encryptor,
64
+				Decryptor: decryptor,
65
+			}
66
+
67
+			n, err := conn.Read(readData)
68
+			assert.Equal(t, len(readData), n)
69
+			assert.NoError(t, err)
70
+			assert.Equal(t, snapshot.Decrypted.Text.data, readData)
71
+
72
+			n, err = conn.Write(snapshot.Encrypted.Text.data)
73
+			assert.Equal(t, len(writeData), n)
74
+			assert.NoError(t, err)
75
+			assert.Equal(t, snapshot.Encrypted.Cipher.data, writeData)
76
+
77
+			connMock.AssertExpectations(t)
78
+		})
79
+	}
80
+}
81
+
82
+func TestClientHandshake(t *testing.T) {
83
+	t.Parallel()
84
+	suite.Run(t, &ClientHandshakeTestSuite{})
85
+}

+ 11
- 3
mtglib/internal/obfuscated2/handshake_frame.go Bestand weergeven

@@ -35,10 +35,18 @@ type handshakeFrame struct {
35 35
 	data [handshakeFrameLen]byte
36 36
 }
37 37
 
38
-func (h *handshakeFrame) dc() int16 {
38
+func (h *handshakeFrame) dc() int {
39 39
 	data := h.data[handshakeFrameOffsetDC:handshakeFrameOffsetEnd]
40
-
41
-	return int16(binary.LittleEndian.Uint16(data))
40
+	idx := int16(binary.LittleEndian.Uint16(data))
41
+
42
+	switch {
43
+	case idx > 0:
44
+		return int(idx) - 1
45
+	case idx < 0:
46
+		return -int(idx + 1)
47
+	default:
48
+		return 0
49
+	}
42 50
 }
43 51
 
44 52
 func (h *handshakeFrame) key() []byte {

+ 83
- 0
mtglib/internal/obfuscated2/init_test.go Bestand weergeven

@@ -0,0 +1,83 @@
1
+package obfuscated2_test
2
+
3
+import (
4
+	"encoding/base64"
5
+	"encoding/json"
6
+	"fmt"
7
+	"os"
8
+	"path/filepath"
9
+	"strings"
10
+)
11
+
12
+type snapshotBytes struct {
13
+	data []byte
14
+}
15
+
16
+func (s snapshotBytes) MarshalText() ([]byte, error) {
17
+	if len(s.data) == 0 {
18
+		return nil, nil
19
+	}
20
+
21
+	return []byte(base64.RawStdEncoding.EncodeToString(s.data)), nil
22
+}
23
+
24
+func (s *snapshotBytes) UnmarshalText(data []byte) error {
25
+	val, err := base64.RawStdEncoding.DecodeString(string(data))
26
+	if err != nil {
27
+		return fmt.Errorf("cannot unmarshal %v: %w", len(val), err)
28
+	}
29
+
30
+	s.data = val
31
+
32
+	return nil
33
+}
34
+
35
+type Obfuscated2Snapshot struct {
36
+	Secret    snapshotBytes `json:"secret"`
37
+	Frame     snapshotBytes `json:"frame"`
38
+	DC        int16         `json:"dc"`
39
+	Encrypted struct {
40
+		Text   snapshotBytes `json:"text"`
41
+		Cipher snapshotBytes `json:"cipher"`
42
+	} `json:"encrypted"`
43
+	Decrypted struct {
44
+		Text   snapshotBytes `json:"text"`
45
+		Cipher snapshotBytes `json:"cipher"`
46
+	} `json:"decrypted"`
47
+}
48
+
49
+type SnapshotTestSuite struct {
50
+	snapshots map[string]*Obfuscated2Snapshot
51
+}
52
+
53
+func (suite *SnapshotTestSuite) IngestSnapshots(dirname, namePrefix string) error {
54
+	suite.snapshots = map[string]*Obfuscated2Snapshot{}
55
+
56
+	files, err := os.ReadDir(filepath.Join("testdata", dirname))
57
+	if err != nil {
58
+		return fmt.Errorf("cannot ingest snapshots: %w", err)
59
+	}
60
+
61
+	for _, v := range files {
62
+		if !strings.HasPrefix(v.Name(), namePrefix) {
63
+			continue
64
+		}
65
+
66
+		filename := filepath.Join("testdata", dirname, v.Name())
67
+
68
+		contents, err := os.ReadFile(filename)
69
+		if err != nil {
70
+			return fmt.Errorf("cannot read %s: %w", filename, err)
71
+		}
72
+
73
+		value := &Obfuscated2Snapshot{}
74
+
75
+		if err := json.Unmarshal(contents, value); err != nil {
76
+			return fmt.Errorf("cannot unmarshal %s: %w", filename, err)
77
+		}
78
+
79
+		suite.snapshots[v.Name()] = value
80
+	}
81
+
82
+	return nil
83
+}

+ 13
- 0
mtglib/internal/obfuscated2/testdata/client_snapshots/snapshot-ok-4529d55776e2d427 Bestand weergeven

@@ -0,0 +1,13 @@
1
+{
2
+  "secret": "NnoYmu4Y+jHBkAVO/UqOlQ",
3
+  "frame": "gDcXwaMY4RwlR+nJw+ILDr123UJHHjjE/U5pF4m/Y04AmH7lEpEL6UYRnIYDbDlOHSDxc1ToziPvNlJJh8RMow",
4
+  "dc": 1,
5
+  "encrypted": {
6
+    "text": "AQIDBAUGBwgJCg",
7
+    "cipher": "wZV3TR39l9nRoQ"
8
+  },
9
+  "decrypted": {
10
+    "text": "4wZj6mUUew",
11
+    "cipher": "YWJjZGVmZw"
12
+  }
13
+}

+ 13
- 0
mtglib/internal/obfuscated2/testdata/client_snapshots/snapshot-ok-585c944d672f60a2 Bestand weergeven

@@ -0,0 +1,13 @@
1
+{
2
+  "secret": "NnoYmu4Y+jHBkAVO/UqOlQ",
3
+  "frame": "M2WyxeiwIQB+ZOFxNzSNHtu9OdESkfxv3JkKFimCxUoYA3BD/Ql9nXB/OIonCKLUKCcS0VzZ2P6/+5oQ9GI8YA",
4
+  "dc": 1,
5
+  "encrypted": {
6
+    "text": "AQIDBAUGBwgJCg",
7
+    "cipher": "tzAwrCz00odERg"
8
+  },
9
+  "decrypted": {
10
+    "text": "QkIvwGQDgA",
11
+    "cipher": "YWJjZGVmZw"
12
+  }
13
+}

+ 13
- 0
mtglib/internal/obfuscated2/testdata/client_snapshots/snapshot-ok-e3cedb3c8b05c39d Bestand weergeven

@@ -0,0 +1,13 @@
1
+{
2
+  "secret": "NnoYmu4Y+jHBkAVO/UqOlQ",
3
+  "frame": "ZEZY1K3SZZgHX2MgMeYMMVoIPYR6eP+bgKxjI7IHl6sPLhfH2jRitS7/VA6Kz8E2L+uLqVom7x4zO+D5Q5iARA",
4
+  "dc": 1,
5
+  "encrypted": {
6
+    "text": "AQIDBAUGBwgJCg",
7
+    "cipher": "WptF2u4ZSDMZxQ"
8
+  },
9
+  "decrypted": {
10
+    "text": "DT+Ob9yGWA",
11
+    "cipher": "YWJjZGVmZw"
12
+  }
13
+}

+ 13
- 0
mtglib/internal/obfuscated2/testdata/client_snapshots/snapshot-ok-e7d2a1e5e479cf50 Bestand weergeven

@@ -0,0 +1,13 @@
1
+{
2
+  "secret": "NnoYmu4Y+jHBkAVO/UqOlQ",
3
+  "frame": "/rbO1fCVLR7o28nrc9inrdDU+4Z4uOqbC2kMnNnzItv0fJmn4hcUXK6YBJQZVI01i7rFlgiCtTgrHtyfQp9p9w",
4
+  "dc": 1,
5
+  "encrypted": {
6
+    "text": "AQIDBAUGBwgJCg",
7
+    "cipher": "jKZzALBemf72Cw"
8
+  },
9
+  "decrypted": {
10
+    "text": "fMOlRiN20A",
11
+    "cipher": "YWJjZGVmZw"
12
+  }
13
+}

+ 13
- 0
mtglib/internal/obfuscated2/testdata/client_snapshots/snapshot-ok-eae4de34f1ab0bdf Bestand weergeven

@@ -0,0 +1,13 @@
1
+{
2
+  "secret": "NnoYmu4Y+jHBkAVO/UqOlQ",
3
+  "frame": "SfqaPWt1F8WTfrTkTl06s7F1nUcBR6AUp5uniCcYpVCJvgYpOO3TQHUZbLaFbI5qYRjJBQDe9OpXDJjR/5z4lg",
4
+  "dc": 1,
5
+  "encrypted": {
6
+    "text": "AQIDBAUGBwgJCg",
7
+    "cipher": "0DtHeQPN2bv7Qw"
8
+  },
9
+  "decrypted": {
10
+    "text": "BWPiYKe4bA",
11
+    "cipher": "YWJjZGVmZw"
12
+  }
13
+}

+ 13
- 0
mtglib/internal/obfuscated2/testdata/client_snapshots/snapshot-ok-ec9c53fa17f4b39b Bestand weergeven

@@ -0,0 +1,13 @@
1
+{
2
+  "secret": "NnoYmu4Y+jHBkAVO/UqOlQ",
3
+  "frame": "MF6BfhvxyI61vFHZN/ecrDF1sZux/JdgVjKX1Yzy7SmBhYu+8bS25ta8iFsj/4y2moBpeNFp7rqekCE3FRb29A",
4
+  "dc": 1,
5
+  "encrypted": {
6
+    "text": "AQIDBAUGBwgJCg",
7
+    "cipher": "MujITanGx9xf9g"
8
+  },
9
+  "decrypted": {
10
+    "text": "0xVTx0JKug",
11
+    "cipher": "YWJjZGVmZw"
12
+  }
13
+}

+ 13
- 0
mtglib/internal/obfuscated2/testdata/client_snapshots/snapshot-ok-ee4b5ad981dcce87 Bestand weergeven

@@ -0,0 +1,13 @@
1
+{
2
+  "secret": "NnoYmu4Y+jHBkAVO/UqOlQ",
3
+  "frame": "YY3y0amcDqggxeNbnyyacKl++b3Q7X0XL9coxctXxJOYZQ/uXIaWFm1KD3s0VIKQ6C7NqJ8hnnJOcpp2Bdau6A",
4
+  "dc": 1,
5
+  "encrypted": {
6
+    "text": "AQIDBAUGBwgJCg",
7
+    "cipher": "mni7eHb24tufLQ"
8
+  },
9
+  "decrypted": {
10
+    "text": "Aqi/2cgHXA",
11
+    "cipher": "YWJjZGVmZw"
12
+  }
13
+}

+ 13
- 0
mtglib/internal/obfuscated2/testdata/client_snapshots/snapshot-ok-f122ea426238564c Bestand weergeven

@@ -0,0 +1,13 @@
1
+{
2
+  "secret": "NnoYmu4Y+jHBkAVO/UqOlQ",
3
+  "frame": "k0f9Sv7V7svvxmHlIP4Ajg0sTGb0NXHfJDk1h6VgAnV0my1F+NU8KPG35kqXC9IDQZK/6fOABb7npO8/TCHEzQ",
4
+  "dc": 1,
5
+  "encrypted": {
6
+    "text": "AQIDBAUGBwgJCg",
7
+    "cipher": "efUzYxRvqEYPlw"
8
+  },
9
+  "decrypted": {
10
+    "text": "FFPwzZkL2A",
11
+    "cipher": "YWJjZGVmZw"
12
+  }
13
+}

+ 13
- 0
mtglib/internal/obfuscated2/testdata/client_snapshots/snapshot-ok-f3e117d7ac4e44f9 Bestand weergeven

@@ -0,0 +1,13 @@
1
+{
2
+  "secret": "NnoYmu4Y+jHBkAVO/UqOlQ",
3
+  "frame": "NiK5AnDAJw+fsytYBnxOmcDl6jx3uQECznBS4WIaHXGWP0tcioPikE1mVtkp33aXT7bCfFlst+b0PvcldGSARw",
4
+  "dc": 1,
5
+  "encrypted": {
6
+    "text": "AQIDBAUGBwgJCg",
7
+    "cipher": "56aF+oauHVDbPQ"
8
+  },
9
+  "decrypted": {
10
+    "text": "KycK+00LvQ",
11
+    "cipher": "YWJjZGVmZw"
12
+  }
13
+}

+ 13
- 0
mtglib/internal/obfuscated2/testdata/client_snapshots/snapshot-ok-f5e00132a81f7a61 Bestand weergeven

@@ -0,0 +1,13 @@
1
+{
2
+  "secret": "NnoYmu4Y+jHBkAVO/UqOlQ",
3
+  "frame": "nYvAavvf0TywZ4hkfGEgf6ZmnIUsDWjRKzLktqF65D+3ha/LqViPdpvsexguXBd5HClDaY6YNXjb1TbjWWfYGQ",
4
+  "dc": 1,
5
+  "encrypted": {
6
+    "text": "AQIDBAUGBwgJCg",
7
+    "cipher": "t4GyXOdaa/phBw"
8
+  },
9
+  "decrypted": {
10
+    "text": "lWNj5kAaug",
11
+    "cipher": "YWJjZGVmZw"
12
+  }
13
+}

+ 2
- 6
mtglib/proxy.go Bestand weergeven

@@ -100,12 +100,8 @@ func (p *Proxy) doObfuscated2Handshake(ctx *streamContext) error {
100 100
 		return fmt.Errorf("cannot process client handshake: %w", err)
101 101
 	}
102 102
 
103
-	if dc < 0 {
104
-		dc = -dc
105
-	}
106
-
107
-	ctx.dc = int(dc)
108
-	ctx.logger = ctx.logger.BindInt("dc", ctx.dc)
103
+	ctx.dc = dc
104
+	ctx.logger = ctx.logger.BindInt("dc", dc)
109 105
 	ctx.clientConn = &obfuscated2.Conn{
110 106
 		Conn:      ctx.clientConn,
111 107
 		Encryptor: encryptor,

+ 2
- 2
stats/prometheus_test.go Bestand weergeven

@@ -2,7 +2,7 @@ package stats_test
2 2
 
3 3
 import (
4 4
 	"fmt"
5
-	"io/ioutil"
5
+	"io"
6 6
 	"net"
7 7
 	"net/http"
8 8
 	"testing"
@@ -32,7 +32,7 @@ func (suite *PrometheusTestSuite) Get() (string, error) {
32 32
 
33 33
 	defer resp.Body.Close()
34 34
 
35
-	data, err := ioutil.ReadAll(resp.Body)
35
+	data, err := io.ReadAll(resp.Body)
36 36
 	if err != nil {
37 37
 		return "", err // nolint: wrapcheck
38 38
 	}

Laden…
Annuleren
Opslaan