github.com/metaworking/channeld@v0.7.3/pkg/channeld/ddos_test.go (about) 1 package channeld 2 3 import ( 4 "errors" 5 "net" 6 "os" 7 "testing" 8 "time" 9 10 "github.com/metaworking/channeld/pkg/channeldpb" 11 "github.com/stretchr/testify/assert" 12 "google.golang.org/protobuf/proto" 13 ) 14 15 func TestUnauthTimeout(t *testing.T) { 16 InitLogs() 17 InitAntiDDoS() 18 // InitChannels() 19 InitConnections("../../config/server_conn_fsm_test.json", "../../config/client_non_authoratative_fsm.json") 20 21 GlobalSettings.ConnectionAuthTimeoutMs = 1000 22 23 // go StartListening(channeldpb.ConnectionType_SERVER, "tcp", ":31288") 24 go StartListening(channeldpb.ConnectionType_CLIENT, "tcp", ":32108") 25 time.Sleep(time.Millisecond * 100) 26 27 conn, err := net.Dial("tcp", "127.0.0.1:32108") 28 assert.NoError(t, err, "Error connecting to server") 29 30 assert.True(t, checkConnOpen(conn), "Connection should not have been closed yet") 31 32 time.Sleep(time.Millisecond * time.Duration(GlobalSettings.ConnectionAuthTimeoutMs)) 33 assert.True(t, checkConnClosed(conn), "Connection should have been closed by now") 34 35 // IP blacklisted. Should still be able to connect, but will be soon be disconnected 36 conn, _ = net.Dial("tcp", "127.0.0.1:32108") 37 time.Sleep(time.Millisecond * 100) 38 assert.True(t, checkConnClosed(conn), "Connection should have been closed by now") 39 } 40 41 func TestInvalidUsername(t *testing.T) { 42 InitLogs() 43 InitAntiDDoS() 44 InitChannels() 45 InitConnections("../../config/server_conn_fsm_test.json", "../../config/client_non_authoratative_fsm.json") 46 47 // Turn off dev mode to force authentication 48 GlobalSettings.Development = false 49 GlobalSettings.MaxFailedAuthAttempts = 2 50 SetAuthProvider(&AlwaysFailAuthProvider{}) 51 52 go StartListening(channeldpb.ConnectionType_CLIENT, "tcp", ":32108") 53 time.Sleep(time.Millisecond * 100) 54 55 conn, err := net.Dial("tcp", "127.0.0.1:32108") 56 assert.NoError(t, err, "Error connecting to server") 57 58 sendMessage(conn, uint32(channeldpb.MessageType_AUTH), &channeldpb.AuthMessage{ 59 PlayerIdentifierToken: "user1", 60 }) 61 time.Sleep(time.Millisecond * 100) 62 assert.Contains(t, failedAuthCounters, "127.0.0.1", "Failed auth counter should contain 127.0.0.1") 63 assert.True(t, checkConnOpen(conn), "Connection should not have been closed yet") 64 65 sendMessage(conn, uint32(channeldpb.MessageType_AUTH), &channeldpb.AuthMessage{ 66 PlayerIdentifierToken: "user2", 67 }) 68 time.Sleep(time.Millisecond * 200) 69 assert.EqualValues(t, 2, failedAuthCounters["127.0.0.1"], "Failed auth counter should be 2") 70 // Read all bytes to clear the read buffer, so checkConnOpen/Closed can work 71 readAll(conn) 72 assert.False(t, checkConnOpen(conn), "Connection should have been closed now") 73 /* 74 _, err = conn.Write([]byte{0, 0, 0, 0}) 75 assert.Error(t, err, "Connection should have been closed now") 76 */ 77 78 // IP blacklisted. Should still be able to connect, but will be soon be disconnected 79 conn, _ = net.Dial("tcp", "127.0.0.1:32108") 80 time.Sleep(time.Millisecond * 100) 81 assert.True(t, checkConnClosed(conn), "Connection should have been closed now") 82 } 83 84 func TestWrongPassword(t *testing.T) { 85 InitLogs() 86 InitAntiDDoS() 87 InitChannels() 88 InitConnections("../../config/server_conn_fsm_test.json", "../../config/client_non_authoratative_fsm.json") 89 90 // Turn off dev mode to force authentication 91 GlobalSettings.Development = false 92 GlobalSettings.MaxFailedAuthAttempts = 3 93 SetAuthProvider(&FixedPasswordAuthProvider{"rightpassword"}) 94 95 go StartListening(channeldpb.ConnectionType_CLIENT, "tcp", ":32108") 96 time.Sleep(time.Millisecond * 100) 97 98 conn, err := net.Dial("tcp", "127.0.0.1:32108") 99 assert.NoError(t, err, "Error connecting to server") 100 101 sendMessage(conn, uint32(channeldpb.MessageType_AUTH), &channeldpb.AuthMessage{ 102 PlayerIdentifierToken: "user1", 103 LoginToken: "wrongpassword", 104 }) 105 time.Sleep(time.Millisecond * 100) 106 assert.Contains(t, failedAuthCounters, "user1", "Failed auth counter should contain user1") 107 assert.True(t, checkConnOpen(conn), "Connection should not have been closed yet") 108 109 sendMessage(conn, uint32(channeldpb.MessageType_AUTH), &channeldpb.AuthMessage{ 110 PlayerIdentifierToken: "user1", 111 LoginToken: "wrongpassword", 112 }) 113 time.Sleep(time.Millisecond * 100) 114 assert.EqualValues(t, 2, failedAuthCounters["user1"], "Failed auth counter should be 2") 115 assert.True(t, checkConnOpen(conn), "Connection should not have been closed yet") 116 117 sendMessage(conn, uint32(channeldpb.MessageType_AUTH), &channeldpb.AuthMessage{ 118 PlayerIdentifierToken: "user1", 119 LoginToken: "rightpassword", 120 }) 121 time.Sleep(time.Millisecond * 100) 122 assert.EqualValues(t, 2, failedAuthCounters["user1"], "Failed auth counter should still be 2") 123 assert.True(t, checkConnOpen(conn), "Connection should not have been closed yet") 124 125 conn.Close() 126 time.Sleep(time.Millisecond * 100) 127 // Re-open connection as the FSM only allows valid AuthMessage once 128 conn, err = net.Dial("tcp", "127.0.0.1:32108") 129 assert.NoError(t, err, "Error connecting to server") 130 131 sendMessage(conn, uint32(channeldpb.MessageType_AUTH), &channeldpb.AuthMessage{ 132 PlayerIdentifierToken: "user1", 133 LoginToken: "wrongpassword", 134 }) 135 time.Sleep(time.Millisecond * 100) 136 assert.False(t, checkConnOpen(conn), "Connection should have been closed by now") 137 138 // PIT blacklisted. Should still be able to connect, but can't login anymore 139 conn, _ = net.Dial("tcp", "127.0.0.1:32108") 140 time.Sleep(time.Millisecond * 100) 141 assert.True(t, checkConnOpen(conn), "Connection should have been closed by now") 142 sendMessage(conn, uint32(channeldpb.MessageType_AUTH), &channeldpb.AuthMessage{ 143 PlayerIdentifierToken: "user1", 144 LoginToken: "rightpassword", 145 }) 146 time.Sleep(time.Millisecond * 100) 147 // Event the right password won't work anymore 148 assert.False(t, checkConnOpen(conn), "Connection should have been closed by now") 149 } 150 151 func sendMessage(conn net.Conn, msgType uint32, msg proto.Message) { 152 msgBody, _ := proto.Marshal(msg) 153 p := &channeldpb.Packet{ 154 Messages: []*channeldpb.MessagePack{ 155 { 156 MsgType: msgType, 157 MsgBody: msgBody, 158 }, 159 }, 160 } 161 bytes, _ := proto.Marshal(p) 162 tag := []byte{67, 72, 78, byte(len(bytes)), 0} 163 conn.Write(append(tag, bytes...)) 164 } 165 166 func readAll(conn net.Conn) []byte { 167 buff := make([]byte, 1024) 168 conn.SetReadDeadline(time.Now().Add(time.Millisecond * 50)) 169 n, _ := conn.Read(buff) 170 return buff[:n] 171 } 172 173 func checkConnOpen(conn net.Conn) bool { 174 buff := make([]byte, 1) 175 conn.SetReadDeadline(time.Now().Add(time.Millisecond * 50)) 176 _, err := conn.Read(buff) 177 if err != nil { 178 return errors.Is(err, os.ErrDeadlineExceeded) 179 } 180 return true 181 } 182 183 func checkConnClosed(conn net.Conn) bool { 184 buff := make([]byte, 1) 185 conn.SetReadDeadline(time.Time{}) 186 _, err := conn.Read(buff) 187 return err != nil 188 }