forked from will-scargill/Echo-Server
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.py
160 lines (140 loc) · 6 KB
/
server.py
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
import socket
import threading
import json
import base64
import sqlite3
import os, sys
import datetime
from logzero import logger
import random
import string
from objects import echo, user
from modules import encoding
from modules import aes
from modules import config
from net.sendMessage import sendMessage
from net import changeChannel
from net import userMessage
from net import disconnect
from net import historyRequest
from net import leaveChannel
if not os.path.exists("data"):
os.mkdir("data")
if not os.path.exists(r"data/key.txt"):
key = ''.join(random.choices(string.ascii_letters + string.digits, k=32))
with open(r"data/key.txt", "w") as f:
f.write(key)
logger.warning("No starterkey file detected")
print("-----------------------------")
logger.info("Welcome to Echo!")
logger.info("Use the command /letmein [key] to be given the administrator role")
logger.info("The key can be found in the data folder in your install directory")
print("-----------------------------")
def ClientConnectionThread(conn, addr):
try:
logger.info("Client connected from " + str(addr))
byteData = conn.recv(1024) # Receive serverInfoRequest
data = encoding.DecodePlain(byteData)
sendMessage(conn, "", "serverInfo", server.RSAPublicToSend, enc=False)
byteData = conn.recv(1024) # Receive clientSecret
data = encoding.DecodePlain(byteData)
userSecret = server.RSAPrivate.decrypt(base64.b64decode(data["data"]))
sendMessage(conn, userSecret, "gotSecret", "")
byteData = conn.recv(1024) # Receive connectionRequest
data = encoding.DecodeEncrypted(byteData, userSecret)
connectionRequest = json.loads(data["data"])
currentUser = user.User(data["userid"], connectionRequest[0], userSecret, addr, conn)
currentUser.connectionValid = True
isServerFull = server.IsServerFull()
if isServerFull:
connInvalidReason = "Server is full"
currentUser.connectionValid = False
logger.warning("Client " + str(addr) + " tried to join but the server was full")
validPassword = server.Authenticate(connectionRequest[1]);
if validPassword == False:
connInvalidReason = "Incorrect Password"
currentUser.connectionValid = False
logger.warning("Client " + str(addr) + " used incorrect password")
isNotBanned = server.IsNotBanned(currentUser)
if isNotBanned == False:
connInvalidReason = "You are banned from this server"
currentUser.connectionValid = False
logger.warning("Client " + str(addr) + " tried to join but was banned")
validID = server.ValidID(currentUser)
if validID == False:
connInvalidReason = "Invalid eID"
currentUser.connectionValid = False
logger.warning("Client " + str(addr) + " tried to join but was already connected from the same device")
if connectionRequest[2] not in server.compatibleClientVers:
connInvalidReason = "Incompatible Client version"
currentUser.connectionValid = False
logger.warning("Client " + str(addr) + " tried to join but was has an incompatible client version")
validUsername = server.ValidUsername(currentUser)
currentUser.username = validUsername
except ConnectionResetError:
logger.error("Client " + str(addr) + " disconnected during handshake")
currentUser.connectionValid = False
if currentUser.connectionValid == True:
try:
sendMessage(conn, userSecret, "CRAccepted", "")
server.AddUser(currentUser)
sendMessage(conn, userSecret, "serverData", server.packagedData)
logger.info("Client " + str(addr) + " completed handshake")
while currentUser.connectionValid:
byteData = conn.recv(1024)
data = encoding.DecodeEncrypted(byteData, currentUser.secret)
logger.info("Received messagetype " + data["messagetype"] + " from client " + str(addr))
if data["messagetype"] == "disconnect":
disconnect.handle(conn, addr, currentUser, server, data)
break
elif data["messagetype"] == "requestInfo":
sendMessage(conn, userSecret, "serverData", server.packagedData)
elif data["messagetype"] == "userMessage":
userMessage.handle(conn, addr, currentUser, server, data)
elif data["messagetype"] == "changeChannel":
changeChannel.handle(conn, addr, currentUser, server, data)
elif data["messagetype"] == "historyRequest":
historyRequest.handle(conn, addr, currentUser, server, data)
elif data["messagetype"] == "leaveChannel":
leaveChannel.handle(conn, addr, currentUser, server, data)
except json.decoder.JSONDecodeError:
logger.error("Received illegal disconnect from client " + str(addr))
disconnect.handle(conn, addr, currentUser, server, data)
currentUser.connectionValid = False
except ConnectionResetError:
logger.error("Received illegal disconnect from client " + str(addr))
disconnect.handle(conn, addr, currentUser, server, data)
currentUser.connectionValid = False
except ConnectionAbortedError as e:
if currentUser.connectionValid == False:
pass
else:
logger.error(e)
else:
logger.warning("Client " + str(addr) + " failed handshake");
sendMessage(conn, userSecret, "CRDenied", connInvalidReason)
conn.close()
conn.close()
logger.info("Client " + str(addr) + " connection closed");
name = config.GetSetting("name", "Server")
channels = config.GetSetting("channels", "Server")
password = config.GetSetting("password", "Server")
port = config.GetSetting("port", "Server")
clientnums = config.GetSetting("clientnum", "Server")
motd = config.GetSetting("motd", "Server")
compatibleClientVers = config.GetSetting("compatibleClientVers", "Server")
strictBanning = config.GetSetting("strictBanning", "Server")
logger.info("Config loaded")
server = echo.Echo(name, "", port, password, channels, motd, clientnums, compatibleClientVers, strictBanning)
#server.initDB()
server.initAlchemy()
server.StartServer(ClientConnectionThread)
live_server = os.environ.get("ECHO_MYSQL_DB")
if not live_server:
userInp = input("")
if userInp == "q":
server.StopServer()
sys.exit()
else:
while True:
pass