I've made a TCP echo client/server with bits from here and here. How can I verify that the socket is encrypted and cannot be intercepted and read? I've tried using Wireshark, but both SSL and non-SSL show encrypted packets. This makes me question their validity.
Client:
import socket
import ssl
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('HOSTNAME', 10000)
print('Connecting to %s port %s' % server_address)
sock.connect(server_address)
ssl_sock = ssl.wrap_socket(
sock,
ssl_version = ssl.PROTOCOL_TLSv1_2
)
try:
message = str.encode(input('>>> '))
print('Sending "%s"' % message)
ssl_sock.sendall(message)
amount_received = 0
amount_expected = len(message)
while amount_received < amount_expected:
data = ssl_sock.recv(16)
amount_received += len(data)
print('Received "%s"' % data)
finally:
print('Closing socket')
ssl_sock.close()
Server:
import socket
import ssl
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('HOSTNAME', 10000)
print('Starting up on %s port %s' % server_address)
sock.bind(server_address)
sock.listen(1)
while True:
print('Waiting for a connection')
try:
connection, client_address = sock.accept()
stream = ssl.wrap_socket(
connection,
server_side = True,
certfile = 'fullchain.pem',
keyfile = 'privkey.pem',
ssl_version = ssl.PROTOCOL_TLSv1_2
)
except KeyboardInterrupt:
print('\nStopping server')
exit()
except:
print('ERROR')
continue
try:
print('Connection from', client_address)
while True:
data = stream.recv(16)
print('Received "%s"' % data)
if data:
print('Sending data back to the client')
stream.sendall(data)
else:
print('No more data from', client_address)
break
finally:
stream.close()
The server is running on my VPS and using the real certificate for HTTPS. Everything works, but I just want to be sure this test is secure before I build anything for real.
Related
i am trying to implement a TLS secured socket server in python, and i want multiple clients to connect to the server and talk to each other,
what i would like to do is that each client connecting can receive messages sent by other clients also,
Server code:
import socket
import threading
HEADER = 64
PORT = 5050
SERVER = socket.gethostbyname(socket.gethostname())
ADDR = (SERVER, PORT)
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "!DISCONNECT"
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDR)
def handle_client(conn, addr):
print(f"[NEW CONNECTION] {addr} connected.")
connected = True
while connected:
msg_length = conn.recv(HEADER).decode(FORMAT)
if msg_length:
msg_length = int(msg_length)
msg = conn.recv(msg_length).decode(FORMAT)
if msg == DISCONNECT_MESSAGE:
connected = False
print(f"[{addr}] {msg}")
conn.send("Msg received".encode(FORMAT))
conn.close()
def start():
server.listen()
print(f"[LISTENING] Server is listening on {SERVER}")
while True:
conn, addr = server.accept()
thread = threading.Thread(target=handle_client, args=(conn, addr))
thread.start()
print(f"[ACTIVE CONNECTIONS] {threading.activeCount() - 1}")
print("[STARTING] server is starting ...")
start()
Client Code:
import socket
HEADER = 64
PORT = 5050
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "!DISCONNECT"
SERVER = "192.168.1.141"
ADDR = (SERVER, PORT)
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(ADDR)
def send(msg):
message = msg.encode(FORMAT)
msg_length = len(message)
send_length = str(msg_length).encode(FORMAT)
send_length += b' ' * (HEADER - len(send_length))
client.send(send_length)
client.send(message)
print(client.recv(2048).decode(FORMAT))
send(input('[Send a Message]: '))
send(DISCONNECT_MESSAGE)
where can i add the TLS in this?:/
if something isn't right please inform me :)
---------------------EDIT------------------------------
SERVER:
import socket
import select
HEADER_LENGTH = 10
IP = "127.0.0.1"
PORT = 1234
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind((IP, PORT))
server_socket.listen(5)
sockets_list = [server_socket]
clients = {}
def receive_message(client_socket):
try:
message_header = client_socket.recv(HEADER_LENGTH)
if not len(message_header):
return False
message_length = int(message_header.decode('utf-8').strip())
return {"header": message_header, "data": client_socket.recv(message_length)}
except:
return False
while True:
read_sockets, _, exception_sockets = select.select(
sockets_list, [], sockets_list)
for notified_socket in read_sockets:
if notified_socket == server_socket:
client_socket, client_address = server_socket.accept()
user = receive_message(client_socket)
if user is False:
continue
sockets_list.append(client_socket)
clients[client_socket] = user
print(
f"Accepted new connection from {client_address[0]}:{client_address[1]} username: {user['data'].decode('utf-8')}")
else:
message = receive_message(notified_socket)
if message is False:
print(
f"closed connection from {clients[notified_socket]['data'].decode('utf-8')}")
sockets_list.remove(notified_socket)
del clients[notified_socket]
continue
user = clients[notified_socket]
print(
f"Received message from {user['data'].decode('utf-8')}: {message['data'].decode('utf-8')}")
for client_socket in clients:
if client_socket != notified_socket:
client_socket.send(
user['header'] + user['data'] + message['header'] + message['data'])
for notified_socket in exception_sockets:
sockets_list.remove(notified_socket)
del clients[notified_socket]
CLIENT:
from http import client
import socket
import select
import errno
import sys
import threading
HEADER_LENGTH = 10
IP = '127.0.0.1'
PORT = 1234
my_username = input("Username: ")
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((IP, PORT))
client_socket.setblocking(False)
username = my_username.encode('utf-8')
username_header = f"{len(username):<{HEADER_LENGTH}}".encode('utf-8')
client_socket.send(username_header + username)
def send_message():
message = input(f"{my_username} > ")
if message:
message = message.encode('utf-8')
message_header = f"{len(message):<{HEADER_LENGTH}}".encode('utf-8')
client_socket.send(message_header + message)
while True:
thread = threading.Thread(target=send_message)
thread.start()
try:
while True:
# receive things
username_header = client_socket.recv(HEADER_LENGTH)
if not len(username_header):
print("connection closed by the server")
sys.exit()
username_length = int(username_header.decode('utf-8').strip())
username = client_socket.recv(username_length).decode('utf-8')
message_header = client_socket.recv(HEADER_LENGTH)
message_length = int(message_header.decode('utf-8').strip())
message = client_socket.recv(message_length).decode('utf-8')
print(f"{username} > {message}")
except IOError as e:
if e.errno != errno.EAGAIN and e.errno != errno.EWOULDBLOCK:
print('Reading error', str(e))
sys.exit()
continue
except Exception as e:
print('General error', str(e))
sys.exit()
unfortunately, i cant seem to get the buffer to work right , other clients only receive other clients input when they send messages, so the output is always unordered correctly.
Here's the code, I wonder how to save the messages separately.
It can only get and send messages back to client. But I can't distinguish which are from client 1 and which are from client 2. Is there any way to save these messages into separate list or something else? so that I can distinguish them
Client 1:
import socket
import sys
messages = [b'This is client 1',
b'It is a good day!',
]
server_address = ('localhost', 1234)
socks = [ socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
for i in range(1)]
print('connecting to %s port %s' % server_address)
for s in socks:
s.connect(server_address)
for message in messages:
for s in socks:
s.send(message)
for s in socks:
data = s.recv(1024)
print(data.decode())
if not data:
print(sys.stderr, 'closing socket', s.getsockname())
Client 2:
import socket
import sys
messages = [b'This is client 2',
b'It is raining today',
]
server_address = ('localhost', 5678)
socks = [ socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
for i in range(1)]
print('connecting to %s port %s' % server_address)
for s in socks:
s.connect(server_address)
for message in messages:
for s in socks:
s.send(message)
for s in socks:
data = s.recv(1024)
print(data.decode())
if not data:
print(sys.stderr, 'closing socket', s.getsockname())
Server:
import selectors
import socket
sel = selectors.DefaultSelector()
def accept(sock, mask):
conn, addr = sock.accept()
print('accepted', conn, 'from', addr)
conn.setblocking(False)
sel.register(conn, selectors.EVENT_READ, read)
def read(conn, mask):
data = conn.recv(1000)
if data:
conn.send(data)
else:
print('closing', conn)
sel.unregister(conn)
conn.close()
sock = socket.socket()
sock.bind(('localhost', int(input())))
sock.listen(1)
sock.setblocking(False)
sel.register(sock, selectors.EVENT_READ, accept)
while True:
events = sel.select()
for key, mask in events:
callback = key.data
callback(key.fileobj, mask)
If you want to validate the ip on the network layer then you can use the variable addr that you create when you accept the connection.
However when you are doing this with multiple clients on the same host then it will not work since the ip is the same.
This will also not work if you are behind a NAT, because you would just get the IP of the nearest router in your network.
Another solution would be to validate the client on the application layer and simply give the client an identification value that you pass into the message that you send from the client.
I'm trying to have multiple clients connect to a server socket and transfer data between them, however I want to limit the number of connections that can be made to the server/ number of client processes to 3. How can I do this?
server:
import socket
from _thread import *
PORT = 5050
HOST = socket.gethostbyname(socket.gethostname())
ADDR = (HOST, PORT)
ThreadCount = 0
tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
tcp.bind(ADDR)
except socket.error as e:
print(str(e))
print("Awaiting connection")
tcp.listen(5)
def threaded_client(connection):
connection.send(str.encode('Welcome to sv'))
while True:
data = connection.recv(2048)
reply = 'Server returns: ' + data.decode('utf-8')
if not data:
break
connection.sendall(str.encode(reply))
connection.close()
while True:
Client, address = tcp.accept()
print('Connected to: ' + address[0] + ':' + str(address[1]))
start_new_thread(threaded_client, (Client, ))
ThreadCount += 1
print('Number of threads: ' + str(ThreadCount))
ServerSocket.close()
client:
import socket
Client = socket.socket(socket.AF_INET, socket. SOCK_STREAM)
PORT = 5050
HOST = socket.gethostbyname(socket.gethostname())
ADDR = (HOST, PORT)
print('Awaiting connection')
try:
Client.connect(ADDR)
except socket.error as e:
print(str(e))
Response = Client.recv(1024)
while True:
Input = input('Sends Info: ')
Client.send(str.encode(Input))
Response = Client.recv(1024)
print(Response.decode('utf-8'))
Cliente.close()
We work at 2 on a project in which we implement TCP mechanisms over UDP connexion. But it seems I have a python config problem. Both of us use Python 3. But the code does work for the other person and not for me.
Here is what I obtain when I run the code
And here are my codes :
-server.py
IP = "127.0.0.1"
PORT_A = 7007
PORT_B = 6006
SYN_ACK = b"SYN_ACK6006"
END = b"END"
MAXLINE = 1024
buffer_fichier = bytearray()
buffer_ack = bytearray()
nb_segment = 0
timeout = 0.2
#socket creation
try:
socket_connect = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
except socket.error:
print("socket creation failed")
exit()
try:
socket_transfer = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
except socket.error:
print("socket creation failed")
exit()
socket_transfer.setblocking(0)
#socket bind
try:
socket_connect.bind((IP, PORT_A))
except socket.error:
print("socket bind failed")
exit()
print("Server waiting for a client")
#tree handshake connection
data, addr = socket_connect.recvfrom(1024)
print("Client: %s" % data)
socket_connect.sendto(SYN_ACK, addr)
print("ME: SYN_ACK")
data, addr = socket_connect.recvfrom(1024)
print("Client: %s" % data)
#open file and put it in a buffer
my_file = open("image.jpg", "rb")
bytes = my_file.read()
my_file.close()
for elem in bytes:
buffer_fichier.append(elem)
size = len(buffer_fichier)
#file sending
for i in range(0,size,MAXLINE):
buffer_segment = bytearray()
buffer_segment.append(nb_segment)
for j in range(i, i + MAXLINE):
if j < size:
buffer_segment.append(buffer_fichier[j])
else:
break
socket_transfer.sendto(buffer_segment, (IP, PORT_B))
nb_segment += 1
ready = select.select([socket_transfer], [], [], timeout)
if ready[0]:
data, addr = socket_transfer.recvfrom(1)
else:
print("pas de ack recu, probleme")
buffer_ack.append(data)
socket_transfer.sendto(END, (IP, PORT_B))
print("File of %d bytes received" % os.path.getsize("image.jpg"))
print("nb of ack received %d" % len(buffer_ack))
-client.py
IP = "127.0.0.1"
PORT_A = 7007
SYN = str.encode("SYN")
ACK = str.encode("ACK")
buffer_ack = bytearray()
#function to slip text and integer in a string
def text_num_split(item):
for index, letter in enumerate(item, 0):
if letter.isdigit():
return [item[:index],item[index:]]
#socket creation
try:
socket_connect = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
except socket.error:
print("socket creation failed")
exit()
try:
socket_transfer = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
except socket.error:
print("socket creation failed")
exit()
#tree handshake connexion
socket_connect.sendto(SYN, (IP, PORT_A))
print("Me: SYN")
data, addr = socket_connect.recvfrom(1024)
msg = text_num_split(data)
PORT_B= int(msg[1])
print("Server: %s" % data)
try:
socket_transfer.bind((IP, PORT_B)) #on bind la socket pour qu'elle ecoute
except socket.error: #sur le port ou le serveur envoie le fichier
print("socket bind failed")
exit()
socket_connect.sendto(ACK, addr)
print("Me: ACK")
#Receive file
my_file = open('my_file', 'w+b')
while True:
data, addr = socket_transfer.recvfrom(1025)
if(data == "END"):
break
else:
data = bytearray(data)
buffer_ack.append(data[0])
ack = str(data[0])
socket_transfer.sendto(ack, addr)
data.pop(0)
my_file.write(data)
my_file.close()
print("File of %d bytes sent" % os.path.getsize('my_file'))
print("nb of ack sent %d" % len(buffer_ack))
Does anyone see where the problem could be coming from ?
Thanks and have a nice day
Charlotte
The Problem is your text_num_split which assumes you pass it a string, you however pass a bytestring.
A bytestring will be cast to ints by enumerate.
To fix this add this line to your text_num_split
item = item.decode("utf-8")
I have to make a simple udp echo client and server, currently my problem is that the client hangs itself up at the code "data, address = sock.recvfrom(dataSize)". Here is my client and server code (I removed some api functions, so it aint long). I tried same ports and different ports and the same goes with the ip's but i dont get any message back. I tried the original file from a friend and his version works, I have the same port and ip and the same methods on both files, but it still keeps hanging at the echoClient method receiveMSG at the first line.
echoServerUDP.py
0<0# : ^
'''
#echo off
python "%~f0" %*
pause
exit /b 0
'''
#!/usr/bin/env python
import socket
import json
host = '0.0.0.0'
sport = 11111 # own port
dataSize = 1024
ip_adresses = {}
def echo_server():
receiveSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
receiveSock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
receiveSock.bind((host,sport))
print("Starting up echo server on %s port %s" % (host, sport))
while True:
print("Waiting to receive message")
print("Generate a Session ...")
data, address = receiveSock.recvfrom(dataSize)
data = data.decode("utf-8")
if data:
print("receive data: %s from %s" % (data,address))
json_object = json.loads(data)
operation=json_object["operation"]
if operation == "register":
register(json_object["name"],json_object["value"],json_object["sid"])
json_message={"ergebnis":"ok"}
dump = json.dumps(json_message)
sendMSG(bytes(dump,encoding="utf-8"),address)
print("er")
if operation == "unregister":
unregister(json_object["name"],json_object["sid"])
if operation == "query":
query(json_object["sid"])
if operation == "reset":
reset(json_object["sid"])
print("sent %s bytes back to %s" % (data,address))
def sendMSG(data,address):
sendSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sendSock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sendSock.sendto(data,address)
sendSock.close()
if __name__ == '__main__':
echo_server()
and here the echoClientUDP.py
0<0# : ^
'''
#echo off
python "%~f0" %*
pause
exit /b 0
'''
#!/usr/bin/env python
import socket
import time
import json
from random import randint
host = '127.0.0.1'
sport = 11111
dataSize = 1024
sid= randint(1,10000)
name=socket.gethostname()
own_ip = socket.gethostbyname(name)
def echo_client():
sendSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
json_message = {"operation":"register","name":name,"value":own_ip,"sid":sid}
dump = json.dumps(json_message)
print("Sending %s to %s:%s" % (dump,host,sport))
sendMSG(sendSock, dump)
data = receiveMSG(sendSock)
if data:
print("Received: %s" % data)
except Exception as err:
print("Socket error: %s" %str(err))
finally:
print("Closing connection to the server")
sendSock.close()
def sendMSG(sendSock, data):
sendSock.connect((host, sport))
sendSock.sendall(bytes(data,encoding="utf-8"))
def receiveMSG(sock):
data, address = sock.recvfrom(dataSize)
print(data)
return data
if __name__ == '__main__':
echo_client()
Please put more effort in some areas like you have not added any headers and you have gone more complicated i have also created a similar working script see and observe that script and make changes to your script
client.py :-
import socket
import sys
HEADER = 64
PORT = 65432
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "!DISCONNECT"
SERVER = socket.gethostbyname(socket.gethostname())
ADDR = (SERVER, PORT)
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(ADDR)
def send(msg):
message = msg.encode(FORMAT)
msg_length = len(message)
send_length = str(msg_length).encode(FORMAT)
send_length += b' ' * (HEADER - len(send_length))
client.send(send_length)
client.send(message)
print(client.recv(2048).decode(FORMAT))
def chat():
while True:
try:
a = input()
if 'quit' in a:
sys.exit()
else:
send(a)
except Exception as e:
print(e)
sys.exit()
chat()
server.py :-
import socket
import threading
HEADER = 64
PORT = 65432
SERVER = socket.gethostbyname(socket.gethostname())
ADDR = (SERVER, PORT)
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "Bye"
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDR)
def handle_client(conn, addr):
print(f"[NEW CONNECTION] {addr} connected.")
connected = True
while connected:
msg_length = conn.recv(HEADER).decode(FORMAT)
if msg_length:
msg_length = int(msg_length)
msg = conn.recv(msg_length).decode(FORMAT)
if msg == DISCONNECT_MESSAGE:
connected = False
print(f"[{addr}] left")
print(f"[{addr}] {msg}")
conn.send("Msg received".encode(FORMAT))
conn.close()
def start():
server.listen()
print(f"[LISTENING] Server is listening on {SERVER}")
while True:
conn, addr = server.accept()
thread = threading.Thread(target=handle_client, args=(conn, addr))
thread.start()
print(f"[ACTIVE CONNECTIONS] {threading.activeCount() - 1}")
print("[STARTING] server is starting...")
start()
and i have used threading here to make the process more fast.
First run the server.py in background and then run client.py to connect to the server.