This commit is contained in:
Gašper Dobrovoljc 2024-05-26 18:10:13 +02:00
parent d7d1a45e78
commit 885ce73d7e
No known key found for this signature in database
GPG Key ID: 0E7E037018CFA5A5
16 changed files with 438 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.DS_Store

8
LDN10/.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

10
LDN10/.idea/LDN10.iml Normal file
View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.venv" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

7
LDN10/.idea/misc.xml Normal file
View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Black">
<option name="sdkName" value="Python 3.12 (LDN10)" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12 (LDN10)" project-jdk-type="Python SDK" />
</project>

8
LDN10/.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/LDN10.iml" filepath="$PROJECT_DIR$/.idea/LDN10.iml" />
</modules>
</component>
</project>

6
LDN10/.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>

21
LDN10/certs/clients.pem Normal file
View File

@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDizCCAnOgAwIBAgIUVPHhcVC0FfI3dsbcMAd0AEifmPMwDQYJKoZIhvcNAQEL
BQAwVTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEOMAwGA1UEAwwFamFuZXowHhcNMjQw
NTI2MTU1ODQ4WhcNMjUwNTI2MTU1ODQ4WjBVMQswCQYDVQQGEwJBVTETMBEGA1UE
CAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRk
MQ4wDAYDVQQDDAVqYW5lejCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AJd9GojC/SaEAUFopY1T6P/U2jZlBkYlGgLh4QWLOdwQr3O9SwbKovVaCANtFWBo
vXFaduJ2d19RaEI8CbffjONlYIGecppoeKXoSe9z7qSjQPvqnijcOVLyuLNsTM1U
mewsdDjVxa+ZjLNAkqU3QrKl28ms945nogYYvOYiyNelwb6VkCi+Sm+Gu7lDQytZ
OteFA9o3OLXP5tbPJT3AjRbXReuARHFy3Q6rburszyUfeT9XatQQ9zLWAlnU3w3X
a5vP7lJHLoF1NiVdbmE2H12LPR43Ima0zLfDOf8YpY2DQaENlNuMuJ4NRjUydI69
kbonAaZNX196FmX03GHZUCUCAwEAAaNTMFEwHQYDVR0OBBYEFKE0+A+tQNYWGRff
dPhuISf1W7qvMB8GA1UdIwQYMBaAFKE0+A+tQNYWGRffdPhuISf1W7qvMA8GA1Ud
EwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAD0uiU+vjpLIRqshFBtzWJ7K
zRXb6zR1EGhbs63HRoTmW4s/YCuwZqdvmggd4j5a9RtFCIRO/4MjswrXV6rG0IiN
JXSb4ugz44oGUXsWboGHq3e8/pTJMq+cT4EO2t+irZ2qPe+jtZOJQwDU2NEJzkN6
P+mcNR1I3pVfA+h1kLDspyv/6pbGQrfo0S8sJzetGYSFPBvEOagS6iHRlC7PwqrZ
gCADDHeewNksX8wGqiselXYQbiIrcGrb42fDgoX0aovEqUuux8Ukifm+DU1P9Hzv
FdMuT/pFNcwOXaETKN4oS4zMB/qGxqEnh3d7oItSBY3XjTgSORC25yf3irTWTww=
-----END CERTIFICATE-----

View File

@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDizCCAnOgAwIBAgIUVPHhcVC0FfI3dsbcMAd0AEifmPMwDQYJKoZIhvcNAQEL
BQAwVTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEOMAwGA1UEAwwFamFuZXowHhcNMjQw
NTI2MTU1ODQ4WhcNMjUwNTI2MTU1ODQ4WjBVMQswCQYDVQQGEwJBVTETMBEGA1UE
CAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRk
MQ4wDAYDVQQDDAVqYW5lejCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AJd9GojC/SaEAUFopY1T6P/U2jZlBkYlGgLh4QWLOdwQr3O9SwbKovVaCANtFWBo
vXFaduJ2d19RaEI8CbffjONlYIGecppoeKXoSe9z7qSjQPvqnijcOVLyuLNsTM1U
mewsdDjVxa+ZjLNAkqU3QrKl28ms945nogYYvOYiyNelwb6VkCi+Sm+Gu7lDQytZ
OteFA9o3OLXP5tbPJT3AjRbXReuARHFy3Q6rburszyUfeT9XatQQ9zLWAlnU3w3X
a5vP7lJHLoF1NiVdbmE2H12LPR43Ima0zLfDOf8YpY2DQaENlNuMuJ4NRjUydI69
kbonAaZNX196FmX03GHZUCUCAwEAAaNTMFEwHQYDVR0OBBYEFKE0+A+tQNYWGRff
dPhuISf1W7qvMB8GA1UdIwQYMBaAFKE0+A+tQNYWGRffdPhuISf1W7qvMA8GA1Ud
EwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAD0uiU+vjpLIRqshFBtzWJ7K
zRXb6zR1EGhbs63HRoTmW4s/YCuwZqdvmggd4j5a9RtFCIRO/4MjswrXV6rG0IiN
JXSb4ugz44oGUXsWboGHq3e8/pTJMq+cT4EO2t+irZ2qPe+jtZOJQwDU2NEJzkN6
P+mcNR1I3pVfA+h1kLDspyv/6pbGQrfo0S8sJzetGYSFPBvEOagS6iHRlC7PwqrZ
gCADDHeewNksX8wGqiselXYQbiIrcGrb42fDgoX0aovEqUuux8Ukifm+DU1P9Hzv
FdMuT/pFNcwOXaETKN4oS4zMB/qGxqEnh3d7oItSBY3XjTgSORC25yf3irTWTww=
-----END CERTIFICATE-----

View File

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCXfRqIwv0mhAFB
aKWNU+j/1No2ZQZGJRoC4eEFizncEK9zvUsGyqL1WggDbRVgaL1xWnbidndfUWhC
PAm334zjZWCBnnKaaHil6Envc+6ko0D76p4o3DlS8rizbEzNVJnsLHQ41cWvmYyz
QJKlN0KypdvJrPeOZ6IGGLzmIsjXpcG+lZAovkpvhru5Q0MrWTrXhQPaNzi1z+bW
zyU9wI0W10XrgERxct0Oq27q7M8lH3k/V2rUEPcy1gJZ1N8N12ubz+5SRy6BdTYl
XW5hNh9diz0eNyJmtMy3wzn/GKWNg0GhDZTbjLieDUY1MnSOvZG6JwGmTV9fehZl
9Nxh2VAlAgMBAAECggEADrICoHC16QYWLxetM6QHrsWhs3QiYyyXNN9fmk+Suc/e
jU44GH0QyNdGfrqWv8b5VaUucjKGyvbVM9OqJ62md6qubXSG7oai6Yk6nuFyrYLu
u2FbnWAbqXnFRBaF7sc9tUTss1S9fBbbqMnjT+an8DeZthsy2pwgAhJlRLfsHssd
2nbXhF2Ko9lMHECzqPggD0LKN7UfDTOqdJHiSm1svMiY026ec1VUe0UepC7F1o2V
mG39RPqFjTnsXJ2ajzFDVMvWM75J8DfTvsdAyaxjvoWamMrZap8ibWpnm0UxSWIh
A46O5y4/CSxUVl3Bp/Oxnu+Agdo5fHA8yqlilC5a8wKBgQDPDajNhaC3YnvBiftg
ImKqbjbprPppbjs6IQfNw4tMoKgQ6zPOCAm4fZCBs1ag4VwXmd6HH12f7dsgYIIV
cbz98MoH7RUwGAPV33QxbImp00LhhjHNE70ZeGz399+XXuRnER5MDoII1jcQCGTQ
qf15RgtjHMNC8S6kPhQLTNktMwKBgQC7TM/t+gfE94CZme/D4ZxDZ488UtVppt1k
KKsE6qqLSkyy0MPmf3xwOakS+cy+AZY8Votx2eAyk2wCq2MhCdvz21ZQZWB5pmWj
vKO74a4xpyPuX2gzlMhX/9y1usNfIvyUjMVTzfEWhrCFWlywctcGXkcruHthM3R9
QOWzFIUdRwKBgGfEs73U47gkrltP2ODUOtiphfHU1Gc0bJB0b2HLR6vutGxORFdU
pfKFU3/9LkRQzYOyhNj5ekWlwnVWiLtQlmQ6YjZYto606m8snyIKAHBRRaqbQ6hA
5Tu3o/0eiDtnvlZ9OM7rUnY1TcFGQ6hkGXnHBfv1NVL+Zt6/kfIb4JgLAoGBAIZs
M1LNPmQ7aX1TwINp2Rd7LI6TuHyx+HRYx5youqtrMK6pK9+yoWF90H1A8JNxWhyF
1GBqiQBjU4J69JMSm1xhj4n1qA7GwG2KBkziRH14Qk5jBMr4Pe0CQanflzYhSvtm
KHzj8eJD2k5qstkkInR8l0Gmjk4Nes4mFHS5BmwjAoGAaHU+iAIKKZwIl4ta6ih7
NpKH/oC+dGI8I7EoCwt7uk1y6+k7v3uTWZHS6TimVRaiRnRp21EjhC4WdJ4uKoia
wynq8v3palgKbMPvocp/Ni4XYjqFL9UG7OFY1Bl7N90XyuxGNJNzL3ZCe4L5Cip7
+cuWKDY8V09Jml8wMEyu1FQ=
-----END PRIVATE KEY-----

View File

@ -0,0 +1,22 @@
-----BEGIN CERTIFICATE-----
MIIDkzCCAnugAwIBAgIUEZiP8qpFxBwq/1urH/vY8xLPa30wDQYJKoZIhvcNAQEL
BQAwWTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MB4X
DTI0MDUyNjE1NTcxOFoXDTI1MDUyNjE1NTcxOFowWTELMAkGA1UEBhMCQVUxEzAR
BgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5
IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEAxoKRGOyYRuDCMyd/Q3IHEQXRdJPg/hE5C1yzJGrLyoMjPhLLLFww
GobQE4xCXA/7bzUpVyOHy+1t80YlD4GIiWz+x04U6thsTTh9oMCIK2Uo3lSzyS2W
JINzbT1dQuvt4icgEzcyDYUA6P7rFe+iMFKPxw0h7kPHPtnnpuFsq0SLk7Aopj6a
7TpvxtjSpvcc/D7MLAqAA6u1Ws/JOmdN+4ZD2W4P/t4yiUCzyESxjPYy1DbgLpEr
w82wVcXjBgV82MmtmXZTgcPVNHM1FFXURPCkwOmwjatyRu+S8feBCXJnEfMYrmJB
Kk5AKXkb3viAxAoYokx388tv2YgpknDtCwIDAQABo1MwUTAdBgNVHQ4EFgQUMem3
SX7Wo2R9gX+BzVQ5rznFsZ0wHwYDVR0jBBgwFoAUMem3SX7Wo2R9gX+BzVQ5rznF
sZ0wDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEARAsNxVNw5Tsz
6Kh5nm3DhCVbaXjy2jdnFK/Arleay2VXQQaVHf8+9USz6hxmo2qKbf6noY5sXIrO
TAb/Eig2XXEYJth5qIHpNHBY7ccRhrAsMokbSQSlUUz7Ip10AoVDVqwp9P6GWdei
Er2Hgw9JyzaKcbo2rMR/r5TGYnJ4Yg2f0Z5aO9uBCUdqTZvJfHulVEgn+YsCRV90
Tz4TVleel3vS6Jljqtj6Rie8DnIX9q1bQQjEten6wHKy2eglpp2uJTPSVThxDTrA
7PQBuizGsvPohjBgNx92oOSXIeeJHHPViKb4wTDrTnNPdkK7pKk7uJMGkh6SwhSf
bYnwL9cS+A==
-----END CERTIFICATE-----

View File

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDGgpEY7JhG4MIz
J39DcgcRBdF0k+D+ETkLXLMkasvKgyM+EsssXDAahtATjEJcD/tvNSlXI4fL7W3z
RiUPgYiJbP7HThTq2GxNOH2gwIgrZSjeVLPJLZYkg3NtPV1C6+3iJyATNzINhQDo
/usV76IwUo/HDSHuQ8c+2eem4WyrRIuTsCimPprtOm/G2NKm9xz8PswsCoADq7Va
z8k6Z037hkPZbg/+3jKJQLPIRLGM9jLUNuAukSvDzbBVxeMGBXzYya2ZdlOBw9U0
czUUVdRE8KTA6bCNq3JG75Lx94EJcmcR8xiuYkEqTkApeRve+IDEChiiTHfzy2/Z
iCmScO0LAgMBAAECggEABdfH/4zPOp7Y+Hp8I3cSwCyEqsLDh5boL+5tk2/VScOs
YOJaupaID+/R5hFlzqHly7Mr4VW5ZIY7i0KQSrGMXEcqBKHGudbe8TLtd7LTDzvu
BQVHOW+vEKoR1rBMs3CQUuzF4+rm/UDh8vm137Jq+rMjaj93tTSng7EUQXQ3J59S
mgCm48GIuZmTOKd14KrsmKjBUbB15XNqoKsIqIrIBJ3CUvPnmpneztD8jxAd0zm4
wk9XJ63MZduZmjpNsJ82m1VXPSKHPt2euKYEQTZlNs2dsnrcSYATJKMCgY8ImDpb
LpjnUM1wiIO33b5YsinLFO0Vlxk3ph/VaWa29fK7MQKBgQDnRZTL3fxa8exMIDSK
Jil+BszzikCPdEvNfHtUyC/dR2Jn4MPE3hwGB2rcWmSrj3wPfIoU9gYj8n2rt+gu
HJ3+p6saRE36n1ejZ43hRgbdb+9aVTZT616lFKz3F7PHyASa8pMIZ9O2924Mq+jt
S9HqZvySCE50FORuZvSNYzdk2QKBgQDbvDk8nKxa533Oa36nxdbgLN8SCXcu0Dqa
fJEPgllXCaK9OHgOA3/Dkvt7Ui54eX1TPz4vBGTMrI1FASWDr44U4Rn8xmQmROmH
XQ4VIsJdyiUwZYWbfcGigGglqgTMVM+vEKIIWhkLuyMJfhDagD2lh6GQIeoCXZPb
dgKkMR+igwKBgQCyIICbiQ2uSnkSpRdydDQvEjPXPFu/YfZkfYVMZqefCjU8Bv0h
62SwLBRdRe4VyXznPKfpvxg5pbKviQV2RqpWEnQR1hwtdX79p2u638G32lgDPnCK
sFWEVmlmI0ZgEKmjYkRnC/kgCnEjp2DPLD+xB8NvAqDSfaj3c6rWH13x+QKBgQCW
nqfxR0fRrBqNcxvHbxKCad+iooBiw3NYUAizQ9tvkPhPkjShDn72lXrypnuaM1TX
ymMaoX1i2uifI1EOuji/USmaHnepz9Tv57ZugHwRBC6HxR9XXVVsyW4aWzecxInz
64fWB8RhSS6UJCjzTbJ0E8uIW+bnJjPi3DqlR9LydwKBgQDNKAJeYBuiMQaBpLcj
YA44tTmqtydZbnjxhZ4bnn7/4N9uCKTSmLCDo/J+CbPT9HGImlmx+s72CREZBSAP
doUYM1LT9Iwj8elEmACTaLkcrkM4+qF4wLeUicYxXRcMmyhc38re85PYqfWCdqXs
dKydz9baCWldimI7/soS/fGUVw==
-----END PRIVATE KEY-----

107
LDN10/client.py Normal file
View File

@ -0,0 +1,107 @@
import json
import socket
import struct
import sys
import ssl
import threading
from datetime import datetime
PORT = 1234
HEADER_LENGTH = 2
def setup_SSL_context():
#uporabi samo TLS, ne SSL
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
# certifikat je obvezen
context.verify_mode = ssl.CERT_REQUIRED
#nalozi svoje certifikate
context.load_cert_chain(certfile="certs/janez_cert.crt", keyfile="certs/janez_private.key")
# nalozi certifikate CAjev (samopodp. cert.= svoja CA!)
context.load_verify_locations('certs/server_cert.crt')
# nastavi SSL CipherSuites (nacin kriptiranja)
context.set_ciphers('ECDHE-RSA-AES128-GCM-SHA256')
return context
def receive_fixed_length_msg(sock, msglen):
message = b''
while len(message) < msglen:
chunk = sock.recv(msglen - len(message)) # preberi nekaj bajtov
if chunk == b'':
raise RuntimeError("socket connection broken")
message = message + chunk # pripni prebrane bajte sporocilu
return message
def receive_json(sock):
# preberi glavo sporocila (v prvih 2 bytih je dolzina sporocila)
header = receive_fixed_length_msg(sock, HEADER_LENGTH)
message_length = struct.unpack("!H", header)[0] # pretvori dolzino sporocila v int
message = None
if message_length > 0: # ce je vse OK
message = receive_fixed_length_msg(sock, message_length) # preberi sporocilo
message = message.decode("utf-8")
message = json.loads(message)
return message
def send_json(sock, data):
data["time"] = datetime.now().strftime("%c")
# pretvori sporocilo v niz bajtov, uporabi UTF-8 kodno tabelo
encoded_data = json.dumps(data).encode("utf-8")
# ustvari glavo v prvih 2 bytih je dolzina sporocila (HEADER_LENGTH)
# metoda pack "!H" : !=network byte order, H=unsigned short
header = struct.pack("!H", len(encoded_data))
data = header + encoded_data # najprj posljemo dolzino sporocilo, sele nato sporocilo samo
sock.sendall(data)
def send_message(sock, message):
send_json(sock, {
"type": "message",
"data": message,
})
# message_receiver funkcija tece v loceni niti
def message_receiver():
while True:
msg_received = receive_json(sock)
msg_type = msg_received["type"]
data = msg_received["data"]
time = msg_received["time"]
match msg_type:
case "message":
username = msg_received["username"]
print(f'[{time}] [{username}] : {data}')
case "error":
print(f'Error: {data}')
# povezi se na streznik
print("[system] connecting to chat server ...")
my_ssl_ctx = setup_SSL_context()
sock = my_ssl_ctx.wrap_socket(socket.socket(socket.AF_INET, socket.SOCK_STREAM))
sock.connect(("localhost", PORT))
print("[system] connected!")
# zazeni message_receiver funkcijo v loceni niti
thread = threading.Thread(target=message_receiver)
thread.daemon = True
thread.start()
# pocakaj da uporabnik nekaj natipka in poslji na streznik
while True:
try:
msg_send = input("")
send_message(sock, msg_send)
except KeyboardInterrupt:
sys.exit()

165
LDN10/server.py Normal file
View File

@ -0,0 +1,165 @@
import json
import signal
import socket
import struct
import ssl
import threading
from datetime import datetime
signal.signal(signal.SIGINT, signal.SIG_DFL)
PORT = 1234
HEADER_LENGTH = 2
def setup_SSL_context():
#uporabi samo TLS, ne SSL
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
# certifikat je obvezen
context.verify_mode = ssl.CERT_REQUIRED
#nalozi svoje certifikate
context.load_cert_chain(certfile="certs/server_cert.crt", keyfile="certs/server_private.key")
# nalozi certifikate CAjev, ki jim zaupas
# (samopodp. cert. = svoja CA!)
context.load_verify_locations('certs/clients.pem')
# nastavi SSL CipherSuites (nacin kriptiranja)
context.set_ciphers('ECDHE-RSA-AES128-GCM-SHA256')
return context
def receive_fixed_length_msg(sock, msglen):
message = b''
while len(message) < msglen:
chunk = sock.recv(msglen - len(message)) # preberi nekaj bajtov
if chunk == b'':
raise RuntimeError("socket connection broken")
message = message + chunk # pripni prebrane bajte sporocilu
return message
def receive_json(sock) -> dict:
# preberi glavo sporocila (v prvih 2 bytih je dolzina sporocila)
header = receive_fixed_length_msg(sock, HEADER_LENGTH)
message_length = struct.unpack("!H", header)[0] # pretvori dolzino sporocila v int
message = None
if message_length > 0: # ce je vse OK
message = receive_fixed_length_msg(sock, message_length) # preberi sporocilo
message = message.decode("utf-8")
message = json.loads(message)
return message
def send_json(sock, message):
message["time"] = datetime.now().strftime("%c")
encoded_message = json.dumps(message).encode("utf-8") # pretvori sporocilo v niz bajtov, uporabi UTF-8 kodno tabelo
# ustvari glavo v prvih 2 bytih je dolzina sporocila (HEADER_LENGTH)
# metoda pack "!H" : !=network byte order, H=unsigned short
header = struct.pack("!H", len(encoded_message))
message = header + encoded_message # najprj posljemo dolzino sporocilo, slee nato sporocilo samo
sock.sendall(message)
def send_error(sock, message):
send_json(sock, {
"type": "error",
"data": message,
})
# funkcija za komunikacijo z odjemalcem (tece v loceni niti za vsakega odjemalca)
def client_thread(client_sock, client_addr):
global clients
global usernames
cert = client_sock.getpeercert()
for sub in cert['subject']:
for key, value in sub:
if key == 'commonName':
usernames[client_sock] = value
print("[system] connected with " + client_addr[0] + ":" + str(client_addr[1]))
print("[system] we now have " + str(len(clients)) + " clients")
try:
while True: # neskoncna zanka
msg_received = receive_json(client_sock)
msg_type = str(msg_received["type"])
data = str(msg_received["data"])
time = str(msg_received["time"])
if not msg_received: # ce obstaja sporocilo
break
match msg_type:
case "message":
username = usernames[client_sock]
if username is None:
username = client_addr[0] + ":" + str(client_addr[1])
msg_received["username"] = username
print(f'[{time}] [{username}] : {data}')
if data.startswith("@"):
[username, *data] = data.split()
username = str(username).replace("@", "")
cl = [c for c, u in usernames.items() if u == username]
if len(cl) == 0:
send_error(client_sock, "Client with this username does not exist.")
continue
client = cl[0]
msg_received["data"] = "".join(data)
send_json(client, msg_received)
continue
for client in clients:
if client == client_sock:
continue
send_json(client, msg_received)
except:
# tule bi lahko bolj elegantno reagirali, npr. na posamezne izjeme. Trenutno kar pozremo izjemo
pass
# prisli smo iz neskoncne zanke
with clients_lock:
clients.remove(client_sock)
if client_sock in usernames:
usernames.pop(client_sock)
print("[system] we now have " + str(len(clients)) + " clients")
client_sock.close()
# kreiraj socket
my_ssl_ctx = setup_SSL_context()
server_socket = my_ssl_ctx.wrap_socket(socket.socket(socket.AF_INET, socket.SOCK_STREAM))
server_socket.bind(("localhost", PORT))
server_socket.listen(1)
# cakaj na nove odjemalce
print("[system] listening ...")
clients = set()
usernames = dict()
clients_lock = threading.Lock()
while True:
try:
# pocakaj na novo povezavo - blokirajoc klic
client_sock, client_addr = server_socket.accept()
with clients_lock:
clients.add(client_sock)
thread = threading.Thread(target=client_thread, args=(client_sock, client_addr))
thread.daemon = True
thread.start()
except KeyboardInterrupt:
break
print("[system] closing server socket ...")
server_socket.close()

BIN
LDN9/dns-transfer.pcapng Normal file

Binary file not shown.

BIN
LDN9/screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB