Advertisement
pmontp19

server

Jun 5th, 2017
135
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 14.38 KB | None | 0 0
  1. import os
  2. import select
  3. import socket
  4. import re
  5. import threading
  6. import signal
  7.  
  8. from comms import send, receive
  9.  
  10. from Crypto.PublicKey import RSA
  11. from Crypto.Signature import PKCS1_PSS
  12. from Crypto.Hash import SHA
  13.  
  14. clients = list()
  15. rooms = list()
  16. HOST = "127.0.0.1"
  17. PORT = 5000
  18.  
  19.  
  20. class Client(object):
  21.     clientCountOnline=0
  22.     def __init__(self, socket, address, pubkey):
  23.         """Constructor"""
  24.         self.sock = socket
  25.         self.addr = address
  26.         self.pubkey = pubkey
  27.         self.room = None
  28.         self.name = None
  29.         Client.clientCountOnline += 1
  30.         thread = threading.Thread(target=self.run, args=())
  31.         thread.daemon = True
  32.         self._is_online = True
  33.         thread.start()
  34.  
  35.     def run(self):
  36.         try:
  37.             message = receive(self.sock)
  38.             name = self.desencriptar(message)
  39.             name = name.split(' ',1)[0].capitalize()
  40.             #name = self.sock.recv(1024).strip().capitalize()
  41.         except socket.error as e:
  42.             print e
  43.         while name in [client.name for client in clients]:
  44.             self.sock.send("El nom ja esta en us.\n")
  45.             name = self.sock.recv(1024).strip().capitalize()
  46.         self.name = name
  47.         message = self.encriptar('[SERVIDOR] Benvingut/da %s!' % self.name, self)
  48.         #self.sock.send(message)
  49.         send(self.sock, message)
  50.         #self.sock.send('[SERVIDOR] Benvingut/da %s!' % self.name)
  51.         print "* Usuari %s s'ha connectat" % name
  52.         self.send_all("+++ L'usuari %s s'acaba de connectar" % self.name)
  53.  
  54.         while (self._is_online):
  55.             #message = self.sock.recv(1024)
  56.             message = receive(self.sock)
  57.             message = self.desencriptar(message)
  58.             if not message:
  59.                 print "* Usuari %s s'ha desconnectat" % self.name
  60.                 clients.remove(self)
  61.                 Client.clientCountOnline -= 1
  62.                 self.stop()
  63.  
  64.             elif message.lower().startswith('/mostra_tots'):
  65.                 self.mostra_tots()
  66.  
  67.             elif message.startswith("@"):
  68.                 recip_name = re.findall(r"(?<=@)(\b\w*\b)", message)[0]
  69.                 if not self.send_private_msg(message):
  70.                     print "* Error: usuari %s offline -> %s" % (recip_name, self.name)
  71.                     self.sock.send("[SERVIDOR] ERROR: usuari %s offline" % recip_name)
  72.  
  73.  
  74.             elif message.lower().startswith("/mostra_canals"):
  75.                 self.mostra_canals()
  76.  
  77.             elif message.lower().startswith("/help"):
  78.                 self.print_help()
  79.  
  80.             elif message.lower().startswith("/crea"):
  81.                 new_room_name = self.crea_canal(message)
  82.                 if new_room_name:
  83.                     self.sock.send('========================================================\n')
  84.                     self.sock.send('[SERVIDOR] Acabes d\'unir-te al canal %s' % (new_room_name,))
  85.                     print '* Nou canal %s' % new_room_name
  86.                 else:
  87.                     self.sock.send('[SERVIDOR] No s\'ha pogut crear el canal :(')
  88.                     print '* Error al crear un canal de %s' % (self.name)
  89.  
  90.             elif message.lower().startswith("/surt"):
  91.                 room_to_leave = self.surt_canal()
  92.                 if room_to_leave:
  93.                     self.sock.send('[SERVIDOR] Acabes d\'abandonar el canal %s' % (room_to_leave,))
  94.                     self.sock.send('========================================================\n')
  95.                     print '* %s surt del canal %s' % (self.name, room_to_leave, )
  96.                 else:
  97.                     self.sock.send('[SERVIDOR] No s\'ha pogut realitzar la operacio :(')
  98.                     print '* Error de %s al fer command surt canal' % (self.name)
  99.  
  100.             elif message.lower().startswith("/canvia"):
  101.                 room_to_join = self.canvia_canal(message)
  102.                 if room_to_join:
  103.                     self.sock.send('========================================================\n')
  104.                     self.sock.send('[SERVIDOR] T\'acabes de canviar al canal %s' % (room_to_join,))
  105.                     print '* %s canvia al canal %s' % (self.name, room_to_join, )
  106.                 else:
  107.                     self.sock.send('[SERVIDOR] No s\'ha pogut realitzar la operacio :(')
  108.                     print '* Error de %s al fer command surt canal' % (self.name)
  109.  
  110.             elif message.lower().startswith("/esborra"):
  111.                 room_to_remove = self.borra_canal(message)
  112.                 if room_to_remove:
  113.                     self.sock.send('[SERVIDOR] Acabes d\'esborrar el canal %s' % (room_to_remove,))
  114.                     print '* Canal %s esborrat per %s' % (room_to_remove, self.name, )
  115.                 else:
  116.                     self.sock.send('[SERVIDOR] No s\'ha pogut esborrar, ets el propietari del canal?')
  117.                     print '* Error de %s al fer command esborrar canal' % (self.name)
  118.  
  119.             elif message.lower().startswith("/mostra_usuaris"):
  120.                 if not self.room:
  121.                     self.sock.send("[SERVIDOR] No estas a cap sala")
  122.                 else:
  123.                     self.mostra_usuaris_canal()
  124.  
  125.             elif message.lower().startswith("/"):
  126.                 self.sock.send("[SERVIDOR] %s no es cap comanda" % message)
  127.  
  128.             else:
  129.                 if self.room:
  130.                     message = "[" + self.name + " a " + self.room.name + "]" + " " + message
  131.                     print message
  132.                     self.send_room(message)
  133.  
  134.                 else:
  135.                     message = "["+self.name+"]" + " " + message
  136.                     print message
  137.                     self.send_all_no_room(message)
  138.  
  139.  
  140.     def encriptar(self, message, to_who):
  141.         try:
  142.             encryptor = to_who.pubkey
  143.             encrypted_message = encryptor.encrypt(message, 0)
  144.             return encrypted_message[0]
  145.         except IOError:
  146.             return 'PLAIN: No s\'ha pogut trobat la clau publica per %s' % to_who.name
  147.  
  148.  
  149.     def desencriptar(self, message):
  150.         dataparts = message.split('#^[[')
  151.         signature = dataparts[1]
  152.         message = dataparts[0]
  153.  
  154.         verified = self.verify_signature(message, signature)
  155.         message = server_privkey.decrypt(message)
  156.  
  157.         if message != '\x00':
  158.             if verified:
  159.                 message = '%s [OK]' % message
  160.             else:
  161.                 message = '%s [No verificat]' % message
  162.  
  163.             return message
  164.  
  165.  
  166.     def verify_signature(self, message, signature):
  167.         try:
  168.             key = self.pubkey
  169.             msg_hash = SHA.new()
  170.             msg_hash.update(message)
  171.  
  172.             verifier = PKCS1_PSS.new(key)
  173.             return verifier.verify(msg_hash, signature)
  174.  
  175.         except IOError:
  176.             return False
  177.  
  178.  
  179.     def send_private_msg(self, message):
  180.         """Method to send a private message with @ handle
  181.        regex finds recipient name after @ handle
  182.        r"(?<=@)(\b\w*\b)" means whole word after @
  183.        tries to send the message, if user not found = offline
  184.        """
  185.         recip_name = re.findall(r"(?<=@)(\b\w*\b)", message)[0]
  186.         exp = re.compile(r'^@(\b\w*\b)')
  187.         message = exp.sub("", message)
  188.         for client in clients:
  189.             if client.name == recip_name:
  190.                 message = "[" + self.name + " to " + client.name + "]" + message
  191.                 client.sock.send(message)
  192.                 print message
  193.                 return True
  194.         return False
  195.  
  196.  
  197.     def mostra_tots(self):
  198.         """Show all users online at a moment
  199.        """
  200.         message = '[SERVIDOR] Usuaris online: '
  201.         message += ', '.join([client.name for client in clients])
  202.         self.sock.send(message)
  203.  
  204.  
  205.     def send_all(self, message):
  206.         """Send to all method, broadcast a message"""
  207.         for sock in [client.sock for client in clients]:
  208.             if sock != self.sock:
  209.                 message_encripted = self.encriptar(message,client)
  210.                 send(sock,message_encripted)
  211.                 #sock.send(message)
  212.  
  213.  
  214.     def send_all_no_room(self, message):
  215.         """Send to all method, broadcast a message"""
  216.         for sock in [client.sock for client in clients]:
  217.             if sock != self.sock and not client.room:
  218.                 message_encripted = self.encriptar(message,client)
  219.                 send(sock,message_encripted)
  220.                 #sock.send(message)
  221.  
  222.  
  223.     def crea_canal(self, new_room_name):
  224.         """Create a new room and join
  225.        regex expression ^([^\s]*)(\s) -> group of 1st word and whitespace"""
  226.         exp = re.compile(r'^([^\s]*)(\s)')
  227.         new_room_name = exp.sub("", new_room_name)
  228.         if not new_room_name in [room.name for room in rooms]:
  229.             self.room = Room(new_room_name, self)
  230.             rooms.append( self.room )
  231.             self.send_all('+++ %s acaba de crear el canal %s' % (self.name, new_room_name, ))
  232.             return new_room_name
  233.         else:
  234.             return None
  235.  
  236.  
  237.     def mostra_canals(self):
  238.         """Show all created rooms to chat"""
  239.         message = '[SERVIDOR] Canals online: '
  240.         message += ', '.join([room.name for room in rooms])
  241.         if not [room for room in rooms]:
  242.             self.sock.send("[SERVIDOR] No hi ha canals online creats")
  243.         else:
  244.             self.sock.send(message)
  245.  
  246.  
  247.     def surt_canal(self):
  248.         """Exit from a chat room"""
  249.         removed = None
  250.         for room in rooms:
  251.             if self in room.clients_in_room:
  252.                 room.remove_client(self)
  253.                 self.room = None
  254.                 removed = room.name
  255.         return removed
  256.  
  257.  
  258.     def canvia_canal(self, room_to_join):
  259.         exp = re.compile(r'^([^\s]*)(\s)')
  260.         room_to_join = exp.sub("", room_to_join)
  261.         if not room_to_join in [room.name for room in rooms]:
  262.             self.sock.send('[SERVIDOR] El canal %s no existeix' % (room_to_join,))
  263.             return None
  264.         for room in rooms:
  265.             if self in room.clients_in_room:
  266.                 room.remove_client(self)
  267.             if room.name == room_to_join:
  268.                 room.add_client(self)
  269.                 self.room = room
  270.         return room_to_join
  271.  
  272.  
  273.     def borra_canal(self, room_to_remove):
  274.         exp = re.compile(r'^([^\s]*)(\s)')
  275.         room_to_remove = exp.sub("", room_to_remove)
  276.         if not room_to_remove in [room.name for room in rooms]:
  277.             self.sock.send('[SERVIDOR] El canal %s no existeix' % (room_to_remove,))
  278.             return None
  279.         removed = None
  280.         for this_room in rooms:
  281.             if this_room.name == room_to_remove and this_room.creator == self:
  282.                 for client in [client for client in this_room.clients_in_room]:
  283.                     this_room.remove_client(client)
  284.                     if self.sock != client.sock:
  285.                         client.sock.send('[SERVIDOR] El canal %s ha sigut esborrat' % (this_room.name))
  286.                     client.room = None
  287.                 removed = this_room.name
  288.                 rooms.remove(this_room)
  289.                 del this_room
  290.         return removed
  291.  
  292.  
  293.     def mostra_usuaris_canal(self):
  294.         message = '[SERVIDOR] Usuaris online: '
  295.         message += ', '.join([client.name for client in self.room.clients_in_room])
  296.         self.sock.send(message)
  297.  
  298.  
  299.     def send_room(self, message):
  300.         for sock in [client.sock for client in self.room.clients_in_room]:
  301.             if sock != self.sock:
  302.                 sock.send(message)
  303.  
  304.  
  305.     def print_help(self):
  306.         self.sock.send("""
  307.        **************************************************************
  308.        **                      HELP - Commands                     **
  309.        **                                                          **
  310.        **  1. /CREA "nom_canal": crear canal                       **
  311.        **  2. /CANVIA "nom_canal": canviar a canal                 **
  312.        **  3. /SURT : sortir del canal actual                      **
  313.        **  4. /ESBORRA "nom_canal": esborrar un canal              **
  314.        **  5. /MOSTRA_CANALS: mostrar canals online                **
  315.        **  6. /MOSTRA_USUARIS: mostrar usuaris en el canal actual  **
  316.        **  7. /MOSTRA_TOTS: mostrar usuaris en tots els canals     **
  317.        **  8. @usuari "missatge": enviar missatge privat           **
  318.        **  9. /EXIT: sortir del xat                                **
  319.        **                                                          **
  320.        **  *Nota sobre l'encriptacio: aquest xat esta encriptat,   **
  321.        **   al final d'un missatge es mostra [OK] si aquest ha     **
  322.        **   estat correctament encriptat.                          **
  323.        **************************************************************
  324.        """)
  325.  
  326.  
  327.  
  328.     def stop(self):
  329.         """Method to let Client thread die"""
  330.         self._is_online = False
  331.  
  332.  
  333. class Room(object):
  334.     """docstring for Room."""
  335.     def __init__(self, name, creator):
  336.         self.name = name
  337.         self.clients_in_room = list()
  338.         self.clients_in_room.append(creator)
  339.         self.creator = creator      #Client class object
  340.  
  341.  
  342.     def remove_client(self, client):
  343.         self.clients_in_room.remove(client)
  344.  
  345.  
  346.     def add_client(self, client):
  347.         self.clients_in_room.append(client)
  348.  
  349. def sighandler(signum, f):
  350.     print 'Apagant el servidor del xat...'
  351.     for client in clients:
  352.         client.sock.close()
  353.     sckt.close()
  354.  
  355. # Set up the listening socket
  356. sckt = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  357. sckt.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  358. sckt.bind((HOST, PORT))
  359.  
  360. print 'Generant claus RSA...'
  361. server_privkey = RSA.generate(1024, os.urandom)
  362. server_pubkey = server_privkey.publickey()
  363.  
  364. sckt.listen(10)
  365. print "Servidor escoltant a %s esperant usuaris..." % ("%s:%s" % sckt.getsockname())
  366.  
  367. signal.signal(signal.SIGINT, sighandler)
  368.  
  369. # Accepting connections in a loop
  370. while True:
  371.     (ready_to_read, _, _) = select.select([sckt] + [client.sock for client in clients], [], [])
  372.     for connection in ready_to_read:
  373.         if connection == sckt:
  374.             (connection, address) = sckt.accept()
  375.             #pubkey = RSA.importKey(connection.recv(1024))
  376.             pubkey = RSA.importKey( receive(connection) )
  377.             #connection.send(server_pubkey.exportKey())
  378.             send(connection, server_pubkey.exportKey() )
  379.             clients.append( Client(connection, address, pubkey) )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement