· 9 years ago · Feb 06, 2017, 12:32 PM
1import socket
2import threading
3import hashlib
4import rsa
5import sqlite3
6
7ID = 'id'
8NAME = 'name'
9VOTES = 'votes'
10TABLE_VOTE_DICT = \
11 {
12 ID: 0,
13 NAME: 1,
14 VOTES: 2
15 }
16CREATE_VOTE_TABLE = 'CREATE TABLE IF NOT EXISTS elections (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name varchar, votes INTEGER)'
17INC_VOTE = "UPDATE elections SET votes = '%s' WHERE name = '%s'"
18VOTE_DICT = \
19 {
20 0: 'Putin',
21 1: 'Zyuganov',
22 2: 'Zhirinovsky',
23 3: 'Mironov'
24 }
25
26def _incVote_(c, vote, name):
27 c.execute(INC_VOTE%(vote+1,name))
28
29def _checkIfTableExists_(c):
30 c.execute(CREATE_VOTE_TABLE)
31
32def handleVote(vote):
33 vote &= ((1 << 20) - 1)
34 print(vote)
35 conn = sqlite3.connect('elections.sqlite')
36 c = conn.cursor()
37 c.execute('SELECT * FROM elections')
38 row = c.fetchone()
39 while row is not None:
40 if row[TABLE_VOTE_DICT[NAME]] == VOTE_DICT[vote]:
41 _incVote_(c, row[TABLE_VOTE_DICT[VOTES]], VOTE_DICT[vote])
42 break
43 row = c.fetchone()
44 conn.commit()
45 c.close()
46 conn.close()
47
48def addCandidate(name):
49 conn = sqlite3.connect('elections.sqlite')
50 c = conn.cursor()
51 c.execute("INSERT INTO elections (name,votes) VALUES ('%s','%i')"%(name,0))
52 conn.commit()
53 c.close()
54 conn.close()
55
56def resetElection():
57 conn = sqlite3.connect('elections.sqlite')
58 c = conn.cursor()
59 c.execute("UPDATE elections SET votes = 0")
60 conn.commit()
61 c.close()
62 conn.close()
63
64LOGIN = 'login'
65PASSWORD = 'password'
66VOTED = 'voted'
67ERR_PASSWORD_TOO_SHORT = 'Password is too short!'
68ERR_LOGIN_EXISTS = 'Login already exists!'
69MIN_PASS = 6
70MAX_PASS = 20
71TABLE_DICT = \
72 {
73 ID: 0,
74 LOGIN: 1,
75 PASSWORD: 2,
76 VOTED: 3
77 }
78CREATE_TABLE = 'CREATE TABLE IF NOT EXISTS '\
79 +'users (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, '\
80 +'login varchar, password varchar, voted INTEGER)'
81ADD_USER = "INSERT INTO users (login, password, voted) VALUES ('%s','%s', 0)"
82MARK_AS_VOTED = "UPDATE users SET voted = 1 WHERE login = '%s'"
83NULL_VOTES = "UPDATE users SET voted = 0"
84
85def _checkPassLength_(password):
86 length = len(password)
87 return length >= MIN_PASS or length <= MAX_PASS
88
89def _checkLoginUniqueness_(c, login):
90 # TODO: simplify the query
91 c.execute("SELECT * FROM users")
92 for row in c:
93 if (login == row[TABLE_DICT[LOGIN]]):
94 return False
95 return True
96
97def _str2hashstr_(string):
98 tNumber = string
99 hashObj = hashlib.sha256()
100 byteArray = str.encode(string)
101 hashObj.update(byteArray)
102 return hashObj.hexdigest()
103
104def _initDB_():
105 conn = sqlite3.connect('users.sqlite')
106 c = conn.cursor()
107 c.execute(CREATE_TABLE)
108 return (conn, c)
109
110def _closeDB_(conn, c):
111 conn.commit()
112 c.close()
113 conn.close()
114
115def createAccount(login, password):
116 if not _checkPassLength_(password):
117 print(ERR_PASSWORD_TOO_SHORT)
118 return False
119 conn, c = _initDB_()
120 if not _checkLoginUniqueness_(c, login):
121 print(ERR_LOGIN_EXISTS)
122 return False
123 hash = _str2hashstr_(password)
124 c.execute(ADD_USER%(login,hash))
125 _closeDB_(conn, c)
126 return True
127
128def authentification(login, password):
129 conn, c = _initDB_()
130 # TODO: simplify the query
131 c.execute("SELECT * FROM users")
132 for row in c:
133 if login == row[TABLE_DICT[LOGIN]]:
134 _closeDB_(conn, c)
135 return _str2hashstr_(password) == row[TABLE_DICT[PASSWORD]]
136 #print('Login not found!')
137 _closeDB_(conn, c)
138
139def markAsVoted(login):
140 ret = False
141 conn, c = _initDB_()
142 # TODO: simplify the query
143 c.execute("SELECT * FROM users")
144 for row in c:
145 if row[TABLE_DICT[LOGIN]] == login:
146 c.execute(MARK_AS_VOTED%login)
147 ret = True
148 _closeDB_(conn, c)
149 return ret
150
151def checkIfVoted(login):
152 conn, c = _initDB_()
153 # TODO: simplify the query
154 c.execute("SELECT * FROM users")
155 for row in c:
156 if row[TABLE_DICT[LOGIN]] == login:
157 return bool(row[TABLE_DICT[VOTED]])
158 _closeDB_(conn, c)
159
160def nullVotes():
161 conn, c = _initDB_()
162 c.execute("SELECT * FROM users")
163 c.execute(NULL_VOTES)
164 _closeDB_(conn, c)
165
166def powMod (n ,pow ,mod):
167 res=1
168 while pow>0:
169 if (pow&1):
170 res = (res * n) % mod
171 n = (n * n) % mod
172 pow>>=1
173 return res
174
175def number2hashnum(number):
176 tNumber = number
177 hashObj = hashlib.sha256()
178 byteNumber = bytearray()
179 while tNumber > 0:
180 byteNumber.append(tNumber & 0xFF)
181 tNumber >>= 8
182 byteNumber.reverse()
183 hashObj.update(byteNumber)
184 hash = hashObj.digest()
185 hashArray = bytearray(hash)
186 hashNumber = 0
187 hashArray.reverse()
188 length = len(hashArray)
189 i = 0
190 while i<length :
191 hashNumber += hashArray[i] << (i * 8)
192 i += 1
193 return hashNumber
194
195def checkVote(R,S,D,N):
196 res = powMod(S,D,N)
197 hash = number2hashnum(R)
198 return res==hash
199
200def sendKeys(client,N,D):
201 client.send((str(N)+' '+str(D)+' ').encode())
202
203 print('Keys sent')
204
205def sendBulletin(client):
206 bulletin = 'President elections 2018\nChoose the candidate:\n1.Putin\n2.Zuganov\n3.Zhirinovsky\n4.Mironov\n'
207 client.send((bulletin).encode())
208
209def signVote(h_, c, n):
210 return powMod(h_, c, n)
211
212def receiveVote():
213 voteSock = socket.socket()
214 voteSock.bind(('', 9091))
215 voteSock.listen(5)
216 while(True):
217 clientSock, clientAddr = voteSock.accept()
218 vote = clientSock.recv(2048)
219 R, S = parseMessageTo2Ints(vote)
220 isValid = checkVote(R,S,D,N)
221 print(isValid)
222 if(isValid):
223 handleVote(R)
224 clientSock.close()
225 print('Vote received')
226
227def userThread(clientSock):
228 while(True):
229 message = clientSock.recv(2048)
230 message = message.decode().split(' ')
231 if(message[0]=="reg"):
232 clientSock.send(('1').encode()) if createAccount(message[1],message[2]) else clientSock.send(('0').encode())
233 if(message[0]=="log" and authentification(message[1],message[2])):
234 if(checkIfVoted(message[1])):
235 print('User already voted')
236 clientSock.send(('2').encode())
237 else:
238 markAsVoted(message[1])
239 clientSock.send(('1').encode())
240 print('Ready to send')
241 break
242 if(message[0]=="log" and not authentification(message[1],message[2])):
243 print('Login failed')
244 clientSock.send(('0').encode())
245 sendKeys(clientSock, N, D)
246 clientSock.recv(2048)
247 sendBulletin(clientSock)
248 h_ = clientSock.recv(2048)
249 signedVote = signVote(int(h_.decode()), C, N)
250 clientSock.send(str(signedVote).encode())
251 clientSock.close()
252
253def parseMessageTo2Ints(message):
254 message = message.decode()
255 message = message.split(' ')
256 return int(message[0]), int(message[1])
257
258def ParametrPrivkeys():
259 (pubkey, privkey) = rsa.newkeys(1024)
260 D = privkey.e
261 C = privkey.d
262 N = privkey.n
263 Q = privkey.q
264 P = privkey.p
265 return D, C, N, Q, P
266
267D, C, N, Q, P = ParametrPrivkeys()
268servSock = socket.socket()
269servSock.bind(('', 9090))
270servSock.listen(5)
271resetElection()
272nullVotes()
273print('Server launched!')
274
275voteThread = threading.Thread(target=receiveVote)
276voteThread.start()
277
278userThreads = list()
279
280while(True):
281 clientSock, clientAddr = servSock.accept()
282 userThreads.append(threading.Thread(target=userThread,args=[clientSock]))
283 userThreads[len(userThreads)-1].start()
284
285print("I'm off")