-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.py
More file actions
239 lines (180 loc) · 6.83 KB
/
Copy pathserver.py
File metadata and controls
239 lines (180 loc) · 6.83 KB
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
"""
Server side program for communicating with client devices
via a UDP port.
by: Brandon Main
date: March 4, 2019
"""
import socket
import sys
import time
import hashlib
# Use loopback address.
SERVER_IP = "127.0.0.1"
# Get UDP port entered from command line.
UDP_PORT = int(sys.argv[1])
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
data = ""
addr = ""
# Function that returns an ack code to a client.
#
# ack format: ACK code device-ID time hash parameter(s)
#
# codes:
# 00 - Successful device registration
# 01 - Device already registered
# 02 - Updated IP registration
# 12 - Reused IP address
# 13 - Reused MAC address
# 20 - Successful deregister
# 21 - Unsuccessful deregister (bad MAC or IP)
# 30 - Device was never registered
# 31 - Unsuccessful login/logoff
# 50 - Successful data transmission from client
# 51 - Data transmitted but client device-ID not in system
# 70 - Successful login
# 80 - Successful logoff
#
def ack(code):
server_socket.sendto(code, addr)
# Function to register device
def register(arg):
device = arg.split(" ", 1)[1]
found = False
# check database of devices
with open('devices.db') as device_file:
lines = device_file.readlines()
for line in lines:
# Device id found
if line.split(" ")[0] == device.split(" ")[0]:
found = True
ack("01 " + device.split(" ", 1)[0] + " " + str(time.ctime())
+ " " + hashlib.sha256(arg).hexdigest() + " " + "This device is already registered.")
if not found:
# Device not found, create new device
device_file = open("devices.db", "a+")
device_file.write("\n" + arg.split(" ", 1)[1])
device_file.close()
ack("00 " + device.split(" ", 1)[0] + " " + str(time.ctime())
+ " " + hashlib.sha256(arg).hexdigest() + " " + "New device added.")
# Function that lets a client deregister from server
def deregister(arg):
device = arg.split(" ", 1)[1]
found = False
# check database of devices
with open('devices.db') as device_file:
lines = device_file.readlines()
for line in lines:
# Device id found
if line.split(" ")[0] == device.split(" ")[0]:
found = True
# Check if device registered to another mac
if line.split(" ")[2] == device.split(" ")[2]:
lines.remove(line)
open("devices.db", "w").close()
device_file = open("devices.db", "w")
for l in lines:
device_file.write(l + "\n")
device_file.close()
ack("20 " + device.split(" ", 1)[0] + " " + str(time.ctime())
+ " " + hashlib.sha256(arg).hexdigest() + " " + "Device removed from server.")
break
# mac doesn't match, don't deregister and send ack 30
else:
ack("30 " + device.split(" ", 1)[0] + " " + str(time.ctime())
+ " " + hashlib.sha256(arg).hexdigest() + " " + "Device registered with different MAC address.")
break
# Device not found
if not found:
ack("21 " + device.split(" ", 1)[0] + " " + str(time.ctime())
+ " " + hashlib.sha256(arg).hexdigest() + " " + "Device was never registered.")
# Function to handle login from client
def login(arg):
device = arg.split(" ", 1)[1]
found = False
# check database of devices
with open('devices.db') as device_file:
lines = device_file.readlines()
for line in lines:
# Device id found & phrases match
if line.split(" ")[0] == device.split(" ")[0] & line.split(" ")[1] == device.split(" ")[1]:
ack("70 " + device.split(" ", 1)[0] + " " + str(time.ctime())
+ " " + hashlib.sha256(arg).hexdigest() + " " + "Login successful.")
if not found:
# Device not found
ack("31 " + device.split(" ", 1)[0] + " " + str(time.ctime())
+ " " + hashlib.sha256(arg).hexdigest() + " " + "Login unsuccessful.")
# Function to handle login from client
def logoff(arg):
device = arg.split(" ", 1)[1]
found = False
# check database of devices
with open('devices.db') as device_file:
lines = device_file.readlines()
for line in lines:
# Device id found
if line.split(" ")[0] == device.split(" ")[0] & line.split(" ")[3] == device.split(" ")[1]:
ack("80 " + device.split(" ", 1)[0] + " " + str(time.ctime())
+ " " + hashlib.sha256(arg).hexdigest() + " " + "Logoff successful.")
if not found:
# Device not found
ack("31 " + device.split(" ", 1)[0] + " " + str(time.ctime())
+ " " + hashlib.sha256(arg).hexdigest() + " " + "Logoff unsuccessful.")
# Function to receive data messages from client
def rcv_data(arg):
device = arg.split(" ", 1)[1]
found = False
# check database of devices
with open('devices.db') as device_file:
lines = device_file.readlines()
for line in lines:
# Device id found
if line.split(" ")[0] == device.split(" ")[0]:
ack("50 " + device.split(" ", 1)[0] + " " + str(time.ctime())
+ " " + hashlib.sha256(arg).hexdigest() + " " + "Data received.")
if not found:
# Device not found
ack("51 " + device.split(" ", 1)[0] + " " + str(time.ctime())
+ " " + hashlib.sha256(arg).hexdigest() + " " + "Device not in system.")
# Function that determines what to do from client input
def operate(arg):
if arg.split(' ', 1)[0] == "REGISTER":
register(arg)
elif arg.split(' ', 1)[0] == "DEREGISTER":
deregister(arg)
elif arg.split(' ', 1)[0] == "LOGIN":
login(arg)
elif arg.split(' ', 1)[0] == "LOGOFF":
logoff(arg)
elif arg.split(' ', 1)[0] == "DATA":
rcv_data(arg)
# Function to check for proper port input
def check_port_num():
global UDP_PORT
if UDP_PORT < 0:
print("\n\n\tError: non-existent port number, please enter a new one.\n")
UDP_PORT = input()
elif UDP_PORT > 65535:
print("\n\n\tError: non-existent port number, please enter a new one.\n")
UDP_PORT = input()
else:
print("Starting server on port " + str(UDP_PORT) + "...")
# Server loops until given an exit command of "quit".
def run():
global data
global addr
while True:
data, addr = server_socket.recvfrom(1024)
arg = data + " " + str(addr[0]) + " " + str(addr[1])
operate(arg)
### Main function ###
def main():
global server_socket
# Check for correct UDP port input
check_port_num()
# Bind server ip to port after checking for good port
server_socket.bind((SERVER_IP, UDP_PORT))
# Stay Alive
run()
# Program start
if __name__ == "__main__":
main()