Compare commits

...

66 Commits

Author SHA1 Message Date
228230bb1b Config
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-30 11:00:16 +02:00
9d3c011816 Config files
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-29 20:15:27 +02:00
18bfac4a86 Bcrypt salting
Some checks failed
continuous-integration/drone/push Build is failing
2021-04-29 20:09:37 +02:00
6d2441d931 dirty workaround
Some checks failed
continuous-integration/drone/push Build is failing
2021-04-29 18:05:37 +02:00
841c5d4c20 asd
Some checks failed
continuous-integration/drone/push Build is failing
2021-04-29 17:52:54 +02:00
0e3ba17a8e basedir
Some checks failed
continuous-integration/drone/push Build is failing
2021-04-29 17:52:34 +02:00
ec5a36c700 do not allow getting out
Some checks failed
continuous-integration/drone/push Build is failing
2021-04-29 17:45:23 +02:00
fe26bd1727 asd
Some checks failed
continuous-integration/drone/push Build is failing
2021-04-29 17:38:28 +02:00
4466ee6172 use unipath
Some checks failed
continuous-integration/drone/push Build is failing
2021-04-29 17:33:15 +02:00
7f1a5f1013 now
Some checks failed
continuous-integration/drone/push Build is failing
2021-04-29 17:22:14 +02:00
3bcb7e18ce maybe this
Some checks failed
continuous-integration/drone/push Build is failing
2021-04-29 17:18:41 +02:00
37d2e06a18 OK
Some checks failed
continuous-integration/drone/push Build is failing
2021-04-29 17:16:08 +02:00
978d7cf092 Merge branch 'master' of https://git.kmlabz.com/BiztProtoBois/server
Some checks failed
continuous-integration/drone/push Build is failing
2021-04-29 17:11:41 +02:00
73c91d1426 OK 2021-04-29 17:11:33 +02:00
fc5385af63 seb
Some checks failed
continuous-integration/drone/push Build is failing
2021-04-29 17:07:42 +02:00
fd4434f504 listdir
Some checks failed
continuous-integration/drone/push Build is failing
2021-04-29 17:06:25 +02:00
152177473d better things
Some checks failed
continuous-integration/drone/push Build is failing
2021-04-29 17:00:50 +02:00
00d4542404 remove more redundant try
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-26 23:22:45 +02:00
09c376debf remove redundant try
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-26 23:16:47 +02:00
8acd49fe09 omg
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-26 22:59:23 +02:00
034f1e3403 fail better
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-26 22:56:06 +02:00
c4333ed827 remove autism
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-26 22:48:11 +02:00
784f065478 return error
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-26 22:41:37 +02:00
2d426a9f73 some niceness2
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-26 22:40:04 +02:00
cced3c49ef error
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-26 22:33:44 +02:00
3d1178d8ac do the magic
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-26 22:33:04 +02:00
62dd8872d6 hatvannegyedik bazis
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-26 22:23:20 +02:00
66877d52a1 lets see
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-26 22:19:09 +02:00
b4a9ccb334 szezon meg a fazon
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-26 22:06:07 +02:00
d40b20e753 fix public key shittery
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-26 22:02:06 +02:00
90969aeadb better append to dict
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-26 21:52:11 +02:00
101a8ab8d6 fixie wuxie
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-26 21:41:45 +02:00
540044c259 some printing, should replace with logger
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-26 20:37:32 +02:00
1616150c2f minor mistake
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-26 19:35:03 +02:00
c682fe1e2a missing comma
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-26 19:33:33 +02:00
4837948fba refactor and better crypto
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-26 19:31:55 +02:00
56d77f0476 refactor chacha
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-26 18:13:38 +02:00
a8730ceac3 foggyos vagyok
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-26 17:19:36 +02:00
f409aefdc0 use authenticated chacha20
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-26 16:58:50 +02:00
b08da25d21 Test for MKD / RMD works like a charm
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-26 14:40:32 +02:00
3e0afb0d45 copypaste went wild
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-26 13:50:28 +02:00
df79776ede move
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-26 13:31:00 +02:00
0c6c1c6622 memes
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-26 13:30:17 +02:00
a14e0414b6 fail less
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-26 13:28:57 +02:00
ae743cde15 some more login rework
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-26 13:18:50 +02:00
772a9e6d2c encode
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-26 00:26:23 +02:00
6bf93241f1 pep8
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-26 00:24:24 +02:00
63733a317f cipherkey is now guaranteed to be 32 characters strong
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-26 00:22:05 +02:00
ded1968f26 fail harder
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-25 20:27:37 +02:00
4fc32ddeea key
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-25 19:23:07 +02:00
45bab9c9f3 Long key
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-25 19:15:08 +02:00
c5d4859326 Error in auth
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-25 18:42:38 +02:00
149c206830 fix circular dependency
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-25 18:40:41 +02:00
798b74e5d8 fix server
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-25 18:35:01 +02:00
3ad96cf71a Merge branch 'master' of https://git.kmlabz.com/BiztProtoBois/server into master
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-25 18:34:09 +02:00
56a77f9c7e fix import 2021-04-25 18:33:50 +02:00
ccc664e0ea Merge branch 'master' of https://git.kmlabz.com/BiztProtoBois/server
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-25 18:29:55 +02:00
4e5634eb1d DNL 2021-04-25 18:29:49 +02:00
b6d46ea1bf return bytes
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-25 18:29:00 +02:00
b70c214584 fix cascading memes
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-25 18:25:27 +02:00
b6b3dd3a35 fixd
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-25 18:20:55 +02:00
f345d4b961 Merge branch 'master' of https://git.kmlabz.com/BiztProtoBois/server
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-25 18:19:18 +02:00
487f5ec772 UPL 2021-04-25 18:19:08 +02:00
5378ec8cdc better recievemessage
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-25 18:18:37 +02:00
89e8bd1295 Merge branch 'master' of https://git.kmlabz.com/BiztProtoBois/server into master
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-25 18:13:24 +02:00
dc43cc3056 use bytes 2021-04-25 18:13:14 +02:00
11 changed files with 212 additions and 148 deletions

View File

@ -1,2 +1,3 @@
pycryptodome
pydh
unipath

View File

@ -11,6 +11,7 @@ from Crypto.Hash import SHA256
from Crypto.Protocol.KDF import bcrypt, bcrypt_check
from Crypto.PublicKey import RSA
from Crypto.PublicKey.RSA import RsaKey
from Crypto.Random import get_random_bytes
auth_logger = logging.getLogger('AUTH APPLICATION ')
auth_logger.setLevel(logging.INFO)
@ -51,7 +52,7 @@ class Authetication:
b64pwd = b64encode(SHA256.new(password.encode('utf-8')).digest())
bcrypt_check(b64pwd, user['password'].encode('utf-8'))
auth_logger.debug("User logged in: " + username)
return user['homeDir']
return self.HOME_DIRECTORY_LOCATION + os.path.sep + user['homeDir']
except ValueError:
auth_logger.debug("User NOT logged in: " + username)
return ''
@ -76,14 +77,16 @@ class Authetication:
shutil.rmtree(self.HOME_DIRECTORY_LOCATION)
os.mkdir(self.HOME_DIRECTORY_LOCATION)
os.mkdir(self.HOME_DIRECTORY_LOCATION + os.path.sep + '0')
shutil.rmtree(self.PRIVATE_KEY_DIRECTORY_LOCATION)
os.mkdir(self.PRIVATE_KEY_DIRECTORY_LOCATION)
def saveUser(self, username: str, password: str) -> bool:
user_salt = get_random_bytes(16)
bytePass = password.encode('utf-8')
b64pwd = b64encode(SHA256.new(bytePass).digest())
bcrypt_hash = bcrypt(b64pwd, 12)
bcrypt_hash = bcrypt(password=b64pwd, cost=12, salt=user_salt)
with open(self.CONFIG_FILE_LOCATION) as json_file:
data = json.load(json_file)
@ -123,7 +126,7 @@ class Authetication:
dictionary = dict()
for user in data['user']:
key = data['publicKey']
key = user['publicKey']
key = bytes.fromhex(key)
try:
rsaKey = RSA.import_key(key)

View File

@ -35,7 +35,7 @@ def testAuth(username: str, password: str):
auth.saveUser(username, password)
homeDir = auth.login(username, password)
if homeDir == '1':
if homeDir == auth.HOME_DIRECTORY_LOCATION + os.path.sep + '1':
test_logger.info('TEST 1 --> Authentication test with VALID :: PASSED')
else:
test_logger.info('TEST 1 --> Authentication test with VALID :: FAILED')
@ -118,4 +118,4 @@ if __name__ == '__main__':
testSaveUser("Diósbejglia", "Diósbejgli")
testAuth("Diósbejglia", "Diósbejgli")
testUserExists("Diósbejglia", "Diósbejgli")
testPersistency()
#testPersistency()

View File

@ -1,2 +0,0 @@
#!/usr/bin/env python3

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -12,7 +12,7 @@ def generatePrivateKeyForUser(auth: Authetication,username: str, user_passphrase
with open(auth.CONFIG_FILE_LOCATION) as json_file:
data = json.load(json_file)
private_key = RSA.generate(2048)
private_key = RSA.generate(8192)
public_key = private_key.publickey()
private_key_value = bytes.hex(private_key.exportKey('DER', passphrase=user_passphrase, pkcs=8))
public_key_value = bytes.hex(public_key.exportKey('DER', pkcs=8))
@ -44,7 +44,7 @@ def generatePrivateKeyForServer(auth: Authetication,passphrase: str) -> str:
data = json.load(json_file)
json_file.close()
private_key = RSA.generate(2048)
private_key = RSA.generate(8192)
public_key = private_key.publickey()
private_key_value = bytes.hex(private_key.exportKey('DER', passphrase=passphrase, pkcs=8, protection="scryptAndAES128-CBC"))
public_key_value = bytes.hex(public_key.exportKey('DER', pkcs=8))

View File

@ -3,16 +3,14 @@
import os
import re
from unipath import Path
class Executor:
"""This class executes commands recieved by the server"""
def __init__(self, currentDiectory: str, baseDir: str = ""):
self.currentDirectory = currentDiectory
if baseDir == "":
self.baseDir = self.currentDirectory
else:
self.baseDir = baseDir
def __init__(self, baseDir: str):
self.currentDirectory = ""
self.baseDir = baseDir + os.path.sep
def sanitizeDirectory(self, inDirectory: str) -> str:
return re.sub('[^a-zA-Z0-9]', '', inDirectory)
@ -22,13 +20,13 @@ class Executor:
def createDirectory(self, dirName: str) -> str:
dirName = self.sanitizeDirectory(dirName)
actualDirName = os.path.join(self.currentDirectory, dirName)
actualDirName: str = os.path.join(self.baseDir,self.currentDirectory,dirName)
os.mkdir(actualDirName)
return actualDirName
def removeDirectory(self, dirName: str) -> str:
dirName = self.sanitizeDirectory(dirName)
actualDirName = os.path.join(self.currentDirectory, dirName)
actualDirName: str = os.path.join(self.baseDir, self.currentDirectory, dirName)
if actualDirName:
os.rmdir(actualDirName)
return actualDirName
@ -38,51 +36,58 @@ class Executor:
def setCurrentDirectory(self, dirName: str) -> str:
if dirName == "..":
if self.currentDirectory == self.baseDir:
p = Path(os.path.join(self.baseDir, self.currentDirectory))
parentpath = p.parent
if (str(parentpath) + os.path.sep)== self.baseDir:
self.currentDirectory = ""
return self.currentDirectory
else:
directories = self.currentDirectory.split(os.path.sep)
strdirectory = ""
for dir in directories:
strdirectory += dir + os.path.sep
strdirectory = strdirectory[:-3]
if os.path.exists(strdirectory):
self.currentDirectory = strdirectory
if len(str(parentpath).split('/')) < len(self.baseDir.split('/')):
return self.currentDirectory
newpath = str(parentpath).replace(self.baseDir,'')
if os.path.exists(os.path.join(self.baseDir,newpath)):
self.currentDirectory = newpath
return self.currentDirectory
else:
dirName = self.sanitizeDirectory(dirName)
joinedDir = os.path.join(self.currentDirectory, dirName)
if os.path.exists(joinedDir):
if os.path.join(self.baseDir, joinedDir):
self.currentDirectory = joinedDir
return self.currentDirectory
def listCurrentDirectoryContent(self) -> str:
contents = os.listdir(self.currentDirectory)
contents = os.listdir(os.path.join(self.baseDir, self.currentDirectory))
strdirectory = ""
for content in contents:
strdirectory += content + ", "
strdirectory = strdirectory[:-1]
return strdirectory
def putFileInCurrentDirectory(self, filename: str, content) -> str:
def putFileInCurrentDirectory(self, filename: str, content: bytes) -> str:
filename = self.sanitizeFile(filename)
currenctfile = os.path.join(self.currentDirectory, filename)
currenctfile = os.path.join(self.baseDir, self.currentDirectory, filename)
f = open(currenctfile, "wb")
f.write(content)
f.close()
return currenctfile
def getFileInCurrentDirectory(self, file: str):
def getFileInCurrentDirectory(self, file: str) -> bytes:
file = self.sanitizeFile(file)
currentfile = os.path.join(self.currentDirectory, file)
currentfile = os.path.join(self.baseDir, self.currentDirectory, file)
if os.path.exists(currentfile):
return open(currentfile, "r")
f = open(currentfile, "rb")
content = f.read()
f.close()
return content
else:
raise Exception('File not found')
def removeFileInCurrentDirectory(self, file: str) -> str:
file = self.sanitizeFile(file)
currentfile = os.path.join(self.currentDirectory, file)
if self.currentDirectory == "":
currentfile = os.path.join(self.baseDir, file)
else:
currentfile = os.path.join(self.baseDir, self.currentDirectory, file)
if os.path.exists(currentfile):
os.remove(currentfile)
return currentfile

View File

@ -2,110 +2,150 @@
import json
from base64 import b64encode, b64decode
import pyDH
from Crypto.Hash import SHA512
from Crypto.Cipher import PKCS1_OAEP
from Crypto.PublicKey import RSA
from Crypto.Cipher import ChaCha20
from Crypto.Cipher import ChaCha20_Poly1305
from Crypto.PublicKey.RSA import RsaKey
from Crypto.Random import get_random_bytes
from Crypto.Signature import pkcs1_15
from netsim import network_interface
from server.server import Server
from authentication import Authetication
class NetWrapper:
def __init__(self, clientPublicKey: dict, serverPrivateKey: RsaKey, serverInstance: Server):
def __init__(self, clientPublicKey: dict, serverPrivateKey: RsaKey, authenticationInstance: Authetication):
self.clientPublicKey = clientPublicKey
self.currentClientPublicKey = "".encode('UTF-8')
self.serverPrivateKey = serverPrivateKey
self.cipherkey = "".encode('UTF-8')
self.network = network_interface('./', 'A')
self.network = network_interface('./../../netsim/network/', 'A')
self.clientAddr = ""
self.currentUser = ""
self.serverInstance = serverInstance
self.homeDirectory = ""
self.authenticationInstance = authenticationInstance
def encryptRSAMessage(self, message: bytes) -> bytes:
cipher_rsa = PKCS1_OAEP.new(self.currentClientPublicKey)
encrypted_msg = cipher_rsa.encrypt(message)
return encrypted_msg
def signRSAHeader(self, type: str, extradata: dict) -> (bytes, bytes):
mandatory = {'type': type, 'source': self.network.own_addr}
header = json.dumps({**mandatory, **extradata}).encode('UTF-8')
h = SHA512.new(header)
headersignature = pkcs1_15.new(self.serverPrivateKey).sign(h)
return header, headersignature
def verifyRSAHeaderSignature(self, header: bytes, headersignature: bytes) -> bool:
h = SHA512.new(header)
try:
pkcs1_15.new(self.currentClientPublicKey).verify(h, headersignature)
return True
except Exception:
return False
def decryptRSAMessage(self, message: bytes) -> bytes:
cipher_rsa = PKCS1_OAEP.new(self.serverPrivateKey)
return cipher_rsa.decrypt(message)
def serverIdentify(self, msg: bytes) -> None:
incommingJson = json.loads(msg.decode('UTF-8'))
if incommingJson['type'] != "IDY":
raise Exception('Wrong message type encountered')
self.clientAddr = incommingJson['source']
self.currentUser = incommingJson['username']
header = json.loads(b64decode(incommingJson['header']).decode('UTF-8'))
self.clientAddr = header['source']
self.currentUser = header['username']
self.currentClientPublicKey = self.clientPublicKey[self.currentUser]
cipher_rsa = PKCS1_OAEP.new(self.serverPrivateKey)
retmsg = cipher_rsa.decrypt(b64decode(incommingJson['message'])).decode('UTF-8')
cipher = PKCS1_OAEP.new(self.currentClientPublicKey)
if not self.verifyRSAHeaderSignature(b64decode(incommingJson['header']),
b64decode(incommingJson['headersignature'])) or header[
'type'] != 'IDY':
raise Exception('Bad initial message')
retheader, retheadersignature = self.signRSAHeader("IDY", {})
dcryptedmsg = self.decryptRSAMessage(b64decode(incommingJson['message']))
retmsg = self.encryptRSAMessage(dcryptedmsg)
identMsg = json.dumps(
{'type': 'IDY', 'source': self.network.own_addr,
'message': b64encode(cipher.encrypt(retmsg.encode('UTF-8'))).decode('ASCII')}).encode(
{'header': b64encode(retheader).decode('UTF-8'),
'headersignature': b64encode(retheadersignature).decode('UTF-8'),
'message': b64encode(retmsg).decode('UTF-8')}).encode(
'UTF-8')
self.network.send_msg(self.clientAddr, identMsg)
def sendMessage(self, message: bytes) -> None:
cipher = ChaCha20.new(self.cipherkey, get_random_bytes(12))
ciphertext = cipher.encrypt(message)
nonce = b64encode(cipher.nonce).decode('ASCII')
ct = b64encode(ciphertext).decode('ASCII')
sendjson = json.dumps({'type': 'CMD', 'source': self.network.own_addr, 'nonce': nonce, 'message': ct}).encode(
self.sendTypedMessage(message, "CMD")
def sendTypedMessage(self, message: bytes, type: str) -> None:
if not (type == "AUT" or type == "CMD"):
raise Exception('Unknown message type')
cipher = ChaCha20_Poly1305.new(key=self.cipherkey)
header = json.dumps({'source': self.network.own_addr, 'type': type}).encode('UTF-8')
cipher.update(header)
ciphertext, tag = cipher.encrypt_and_digest(message)
nonce = b64encode(cipher.nonce).decode('UTF-8')
ct = b64encode(ciphertext).decode('UTF-8')
b64tag = b64encode(tag).decode('UTF-8')
sendjson = json.dumps(
{'header': b64encode(header).decode('UTF-8'), 'nonce': nonce, 'message': ct, 'tag': b64tag}).encode(
'UTF-8')
self.network.send_msg(self.clientAddr, sendjson)
def keyExchange(self) -> None:
dh = pyDH.DiffieHellman()
cipher = PKCS1_OAEP.new(self.currentClientPublicKey)
mypubkey = b64encode(cipher.encrypt(str(dh.gen_public_key()).encode('UTF-8'))).decode('ASCII')
jsonmsg = json.dumps({'type': 'DH', 'source': self.network.own_addr, 'message': mypubkey}).encode('UTF-8')
mypubkey = self.encryptRSAMessage(str(dh.gen_public_key()).encode('UTF-8'))
header, headersignature = self.signRSAHeader("DH", {})
jsonmsg = json.dumps(
{'header': b64encode(header).decode('UTF-8'), 'headersignature': b64encode(headersignature).decode('UTF-8'),
'message': b64encode(mypubkey).decode('UTF-8')}).encode('UTF-8')
self.network.send_msg(self.clientAddr, jsonmsg)
decodedmsg = {'source': '', 'type': ''}
while not (decodedmsg['source'] == self.clientAddr and decodedmsg['type'] == 'DH'):
status, msg = self.network.receive_msg(blocking=True)
if not status:
raise Exception('Network error during connection.')
decodedmsg = json.loads(msg.decode('UTF-8'))
cipher_rsa = PKCS1_OAEP.new(self.serverPrivateKey)
serverpubkey = int(cipher_rsa.decrypt(b64decode(decodedmsg['message'])).decode('UTF-8'))
self.cipherkey = dh.gen_shared_key(serverpubkey).encode('UTF-8')
status, msg = self.network.receive_msg(blocking=True)
if not status:
raise Exception('Network error during connection.')
decodedmsg = json.loads(msg.decode('UTF-8'))
header = json.loads(b64decode(decodedmsg['header']).decode('UTF-8'))
if not self.verifyRSAHeaderSignature(b64decode(decodedmsg['header']),
b64decode(decodedmsg['headersignature'])) or not (
header['source'] == self.clientAddr and header['type'] == 'DH'):
raise Exception('Header signature error')
clientpubkey = int(self.decryptRSAMessage(b64decode(decodedmsg['message'])).decode('UTF-8'))
cipherkey = dh.gen_shared_key(clientpubkey).encode('UTF-8')
hasher = SHA512.new()
hasher.update(cipherkey)
self.cipherkey = (hasher.hexdigest()[:32]).encode('UTF-8')
def login(self) -> bool:
b64 = {'source': '', 'type': ''}
while not (b64['source'] == self.clientAddr and b64['type'] == 'AUT'):
status, msg = self.network.receive_msg(blocking=True)
if not status:
raise Exception('Network error during connection.')
b64 = json.loads(msg.decode('UTF-8'))
try:
retnonce = b64decode(b64['nonce'])
retciphertext = b64decode(b64['message'])
retcipher = ChaCha20.new(self.cipherkey, nonce=retnonce)
plaintext = retcipher.decrypt(retciphertext).decode('UTF-8').split(' ')
linsuccess = (not (len(plaintext) != 3 or plaintext[0] != "LIN" or plaintext[
1] != self.currentUser)) and self.serverInstance.login(plaintext[1], plaintext[2])
if linsuccess:
message = "OK".encode('UTF-8')
else:
message = "ERROR".encode('UTF-8')
cipher = ChaCha20.new(self.cipherkey, get_random_bytes(12))
ciphertext = cipher.encrypt(message)
nonce = b64encode(cipher.nonce).decode('ASCII')
ct = b64encode(ciphertext).decode('ASCII')
sendjson = json.dumps(
{'type': 'AUT', 'source': self.network.own_addr, 'nonce': nonce, 'message': ct}).encode(
'UTF-8')
self.network.send_msg(self.clientAddr, sendjson)
return linsuccess
except Exception:
print("Incorrect decryption")
status, msg = self.network.receive_msg(blocking=True)
if not status:
raise Exception('Network error during connection.')
cleartext = self.recieveEncryptedMessage(msg, "AUT").decode('UTF-8')
if cleartext == "ERROR":
return False
else:
plaintext = cleartext.split(' ')
self.homeDirectory = self.authenticationInstance.login(plaintext[1], plaintext[2])
linsuccess = (not (len(plaintext) != 3 or plaintext[0] != "LIN" or plaintext[
1] != self.currentUser)) and self.homeDirectory
if linsuccess:
message = "OK".encode('UTF-8')
else:
message = "ERROR".encode('UTF-8')
self.sendTypedMessage(message, "AUT")
return linsuccess
def initClientConnection(self, msg: bytes) -> bytes:
print('A client is trying to connect')
try:
print('Server and Client identity verification started')
self.serverIdentify(msg)
print('Key exchange started')
self.keyExchange()
print('Authorization started')
success = self.login()
print(f'Authorization completed, success: {success}')
if success:
return "LINOK".encode('UTF-8')
else:
self.logout()
return "LINERROR".encode('UTF-8')
except Exception:
print("Error ecountered, resetting")
self.logout()
return "LINERROR".encode('UTF-8')
@ -116,22 +156,31 @@ class NetWrapper:
if not self.clientAddr:
return self.initClientConnection(msg)
else:
return self.recieveEncryptedMessage(msg)
return self.recieveEncryptedMessage(msg, "CMD")
def logout(self) -> None:
self.serverInstance.logout()
self.clientAddr = ""
self.cipherkey = "".encode('UTF-8')
self.currentClientPublicKey = "".encode('UTF-8')
self.currentUser = ""
self.homeDirectory = ""
def recieveEncryptedMessage(self, msg: bytes) -> bytes:
def recieveEncryptedMessage(self, msg: bytes, type: str) -> bytes:
if not (type == "AUT" or type == "CMD"):
raise Exception('Unknown message type')
try:
b64 = json.loads(msg)
b64 = json.loads(msg.decode('UTF-8'))
retheader = json.loads(b64decode(b64['header']).decode('UTF-8'))
retnonce = b64decode(b64['nonce'])
retciphertext = b64decode(b64['message'])
retcipher = ChaCha20.new(self.cipherkey, nonce=retnonce)
plaintext = retcipher.decrypt(retciphertext)
return plaintext
rettag = b64decode(b64['tag'])
retcipher = ChaCha20_Poly1305.new(key=self.cipherkey, nonce=retnonce)
retcipher.update(b64decode(b64['header']))
plaintext = retcipher.decrypt_and_verify(retciphertext, rettag)
if not (retheader['source'] == self.clientAddr and retheader['type'] == type):
return "ERROR".encode('UTF-8')
else:
return plaintext
except Exception:
print("Incorrect decryption")
return "ERROR".encode('UTF-8')

View File

@ -1,4 +1,5 @@
#!/usr/bin/env python3
import os
from authentication import Authetication
from executor import Executor
from netwrapper import NetWrapper
@ -6,55 +7,59 @@ from netwrapper import NetWrapper
class Server:
def __init__(self, homeDirectory: str = "", sessionTimeout: int = 120, availableServer: bool = True):
def __init__(self, sessionTimeout: int = 120, availableServer: bool = True):
self.isAuthenticated = False
self.homeDirectory = homeDirectory
self.sessionTimeout = sessionTimeout
self.availableServer = availableServer
self.executor = Executor(homeDirectory)
self.executor = Executor("")
self.auth = Authetication()
def initServer(self):
print("Please enter your private key passphrase")
passphrase = input()
self.auth = Authetication()
self.networkInstance = NetWrapper(self.auth.loadUserPublicKeys(), self.auth.loadServerPrivateKey(passphrase),
self)
self.auth)
def login(self, username: str, password: str) -> bool:
def login(self, homeDir: str) -> None:
self.isAuthenticated = True
home_directory = self.auth.login(username, password)
self.executor.baseDir = Executor(home_directory)
if not home_directory:
return False
else:
return True
self.executor = Executor(homeDir + os.path.sep)
def logout(self) -> None:
self.networkInstance.logout()
self.isAuthenticated = False
self.availableServer = False
self.homeDirectory = ""
self.executor.baseDir = Executor(self.homeDirectory)
self.executor = Executor("")
def parseCommand(self, command: str) -> None:
if command == "LINOK":
self.networkInstance.sendMessage("LINOK".encode('UTF-8'))
self.login(self.networkInstance.homeDirectory)
self.networkInstance.sendMessage("OK".encode('UTF-8'))
return None
elif command == "LINERROR":
self.networkInstance.sendMessage("LINERROR".encode('UTF-8'))
return None
elif command == "ERROR":
self.networkInstance.sendMessage("ERROR".encode('UTF-8'))
return None
parsedCommand = command.split(" ")
if len(parsedCommand) > 3:
self.networkInstance.sendMessage("ERROR".encode('UTF-8'))
# TODO: Ez igy gecironda, ezt meg kene csinalni rendesen.
elif len(parsedCommand) == 1:
return self.execute(parsedCommand[0])
self.execute(parsedCommand[0])
elif len(parsedCommand) == 2:
return self.execute(parsedCommand[0], parsedCommand[1])
self.execute(parsedCommand[0], parsedCommand[1])
elif len(parsedCommand) == 3:
return self.execute(parsedCommand[0], parsedCommand[1], parsedCommand[2])
self.execute(parsedCommand[0], parsedCommand[1], parsedCommand[2])
def execute(self, command: str, firstParam: str = "", secondParam: str = "") -> None:
if self.homeDirectory == "" or self.executor.currentDirectory == "" or self.executor.baseDir == "":
raise Exception("Directories must not be empty string. Did the user log in?")
if command == "MKD":
if self.executor.baseDir == "":
raise Exception("Home directory must not be empty string. Did the user log in?")
if command == "LOUT":
if not (secondParam == "" and firstParam == ""):
self.networkInstance.sendMessage("ERROR".encode('UTF-8'))
else:
self.networkInstance.sendMessage("OK".encode('UTF-8'))
self.logout()
elif command == "MKD":
if secondParam != "":
self.networkInstance.sendMessage("ERROR".encode('UTF-8'))
else:
@ -67,11 +72,10 @@ class Server:
self.executor.removeDirectory(firstParam)
self.networkInstance.sendMessage("OK".encode('UTF-8'))
elif command == "GWD":
if secondParam != "" or firstParam != "":
if not (secondParam == "" and firstParam == ""):
self.networkInstance.sendMessage("ERROR".encode('UTF-8'))
else:
self.executor.getCurrentDirectory()
self.networkInstance.sendMessage("OK".encode('UTF-8'))
self.networkInstance.sendMessage(self.executor.getCurrentDirectory().encode('UTF-8'))
elif command == "CWD":
if secondParam != "":
self.networkInstance.sendMessage("ERROR".encode('UTF-8'))
@ -79,11 +83,10 @@ class Server:
self.executor.setCurrentDirectory(firstParam)
self.networkInstance.sendMessage("OK".encode('UTF-8'))
elif command == "LST":
if secondParam != "" or firstParam != "":
if not (secondParam == "" and firstParam == ""):
self.networkInstance.sendMessage("ERROR".encode('UTF-8'))
else:
self.executor.listCurrentDirectoryContent()
self.networkInstance.sendMessage("OK".encode('UTF-8'))
self.networkInstance.sendMessage(self.executor.listCurrentDirectoryContent().encode('UTF-8'))
elif command == "RMF":
if secondParam != "":
self.networkInstance.sendMessage("ERROR".encode('UTF-8'))
@ -94,28 +97,31 @@ class Server:
if secondParam != "":
self.networkInstance.sendMessage("ERROR".encode('UTF-8'))
else:
# TODO
# Megkapod a filenevet argumentumneknt
# Fogadni kell egy uzenetet, ami a fajl tartalma
# Fogadni kell egy uzenetet, ami "EOF"
# Mindig minden legyen UTF-8-kent kodolva, kiveve a falj, az marard
# Ha sikeres, OK kuldese, kulonben ERROR kuldese
pass
fileMessage = self.networkInstance.recieveMessage()
eof = self.networkInstance.recieveMessage().decode('UTF-8')
if eof == "EOF":
self.executor.putFileInCurrentDirectory(firstParam, fileMessage)
self.networkInstance.sendMessage("OK".encode('UTF-8'))
else:
self.networkInstance.sendMessage("ERROR".encode('UTF-8'))
elif command == "DNL":
if secondParam != "":
self.networkInstance.sendMessage("ERROR".encode('UTF-8'))
else:
# TODO
# Megkapod a filenevet arguemntumkent
# Kuldeni kell egy uzenetet, ami a falj tartalma
# Kuldeni kell egy uzenetet, ami EOF
# Mindig minden legyen UTF-8-kent kodolva, kiveve a falj, az marard
# Ha sikeres, OK valaszt megkapod, kulonben ERROR valaszt megkapod
pass
try:
file = self.executor.getFileInCurrentDirectory(firstParam)
self.networkInstance.sendMessage(file)
self.networkInstance.sendMessage("EOF".encode('UTF-8'))
except Exception:
self.networkInstance.sendMessage("ERROR".encode('UTF-8'))
else:
self.networkInstance.sendMessage("ERROR".encode('UTF-8'))
def startServer(self):
while True:
message = self.networkInstance.recieveMessage().decode('UTF-8')
self.parseCommand(message)
try:
message = self.networkInstance.recieveMessage().decode('UTF-8')
self.parseCommand(message)
except Exception as e:
self.networkInstance.sendMessage("ERROR".encode('UTF-8'))
print(e)