Search code examples
sslserverclientchat

Two clients do not communicate on python with ssl


El servidor tiene problemas para funcionar, he sacado el código de openai.com, pero parece que sus respuestas estan sacadas del código de personas que han posteado dudas y problemas en lugar de ejemplos funcionales.

El servidor.

import socketserver
import ssl

class Server:
    def __init__(self, host, port, context):
        self.host = host
        self.port = port
        self.context = context
        self.context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
        self.context.load_cert_chain(certfile='./cer.pem', keyfile='./clave.key')
        self.server = socketserver.TCPServer((host, port), ServerHandler, context)
        self.server.clients = []

    def start(self):
        self.server.serve_forever()

    def stop(self):
        self.server.shutdown()
        self.server.server_close()
        
    def send_message_to_all_clients(self, message):
        for client in self.server.clients:
            client.sendall(message)

class ServerHandler(socketserver.BaseRequestHandler):
    def __init__(self, request, client_address, server):
        self.context = context
        super().__init__(request, client_address, server)
        
    def handle(self):
        self.server.clients.append(self.request)
        self.request = self.context.wrap_socket(self.request, server_side=True)
        while True:
            data = self.request.recv(1024)
            if not data:
                break
            self.send_message_to_all_clients(data)

    def send_message_to_all_clients(self, message, context):
        for client in self.server.clients:
            client = context.wrap_socket(client, server_side=True)
            client.sendall(message)

if __name__ == "__main__":
    host = "127.0.0.1"
    port = 8080
    context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
    context.load_cert_chain(certfile='./cer.pem', keyfile='./clave.key')
    server = Server(host, port, context)
    server.start()


Solution

  • #!/usr/bin/python
    
    
    from Crypto.Cipher import PKCS1_OAEP
    from Crypto.PublicKey import RSA
    
    from cifrar import CIFRAR
    from descifrar import DESCIFRAR
    from comprobar import *
    import sys, os
    from PyQt5.QtWidgets import *
    from PyQt5.QtGui import QIcon, QFont, QImage, QPixmap
    from PyQt5.QtCore import pyqtSlot, Qt, pyqtSignal
    
    
    class Ventana(QMainWindow, QWidget):
        def __init__(self):
            super().__init__()
            #Icono
            self.setWindowIcon(QIcon('v.png'))
    
            #Variables de estado
            self.conectado=False
    
            #Fuente tipo negrita
            fetiqueta=QFont()
            fetiqueta.setBold(True)
    
            #Avatar
            self.archivoAvatar = "avatar.png"
            self.avatar = QLabel(self)
            self.avatar.setPixmap(QPixmap(self.archivoAvatar).scaled(120, 120, Qt.KeepAspectRatio))
            self.avatar.move(720,130)
            self.avatar.resize(120,120)
            self.avatar.show()
    
            #Texto de entrada
            self.lineEntry = QPlainTextEdit(self)
            self.lineEntry.move(10,10)
            self.lineEntry.resize(700,200)
            self.lineEntry.setReadOnly(True)
            
            #Texto a enviar
            self.linaEnvio = QLineEdit(self)
            self.linaEnvio.move(10,500)
            self.linaEnvio.resize(700,40)
            self.linaEnvio.setReadOnly(False)
            
            #Texto estado y avisos
            self.linestado = QLineEdit(self)
            self.linestado.move(10,210)
            self.linestado.resize(700,40)
            self.linestado.setReadOnly(True)
            
            #Etiqueta bajo boton conectar -> IP
            self.etiquetaIPS = QLabel(self)
            self.etiquetaIPS.move(720,60)
            self.etiquetaIPS.setText("IP:192.168.1.100  ")
            self.etiquetaIPS.setStyleSheet("font-weight: 300")
    
            #Etiqueta bajo boton conectar -> Puerto
            self.etiquetaPS = QLabel(self)
            self.etiquetaPS.move(720,80)
            self.etiquetaPS.setText("Puerto: 8080 ")
            self.etiquetaPS.setStyleSheet("font-weight: 300")
            
            #Etiqueta bajo boton conectar -> Certificados
            self.etiquetaCer = QLabel(self)
            self.etiquetaCer.move(720,100)
            self.etiquetaCer.setText("Puerto: 8080 ")
            self.etiquetaCer.setStyleSheet("font-weight: 300")
    
            #Boton conectar
            self.boton1 = QPushButton(self)
            self.boton1.move(720,10)
            self.boton1.resize(130,40)
            self.boton1.setText("Conectar")
            self.boton1.setFont(fetiqueta)
            self.boton1.setStyleSheet("background-color: red")
    
            #Boton cerrar
            self.boton2 = QPushButton(self)
            self.boton2.move(720,550)
            self.boton2.resize(130,40)
            self.boton2.setFont(fetiqueta)
            self.boton2.setText("Cerrar")
            
            #Boton Enviar
            self.boton3 = QPushButton(self)
            self.boton3.move(10,550)
            self.boton3.resize(700,40)
            self.boton3.setText("Enviar")
            self.boton3.setFont(fetiqueta)
    
            #Señales
            self.boton1.clicked.connect(self.conectar)
            self.boton2.clicked.connect(self.cerrar)
            self.boton3.clicked.connect(self.enviar)
            
            # self.avatar.clicked.connect(self.seleccionarAvatar)
            
            #Ventana principal
            self.setGeometry(50,50,860,600)
            self.setWindowTitle("Chat")
            self.show()
    
        #Funciones
        def alinicio(self):
            #Comprobamos estado de conexión, coloreamos boton de conexión y desactivamos boton y linea de envio
            self.conecado = True
            if self.conectado == False:
                self.linestado.setText("Pulsa en el botón Desconectado para empezar.")
                self.linaEnvio.setEnabled(False)
                self.boton3.setEnabled(False)
                self.boton1.setText("Desconectado")
                self.boton1.setStyleSheet("background-color: red")
            else:
                self.linestado.setText("Conexión establecida!")
                self.linaEnvio.setEnabled(True)
                self.boton3.setEnabled(True)
                self.conectado == True
                self.boton1.setText("Conectado")
                self.boton1.setStyleSheet("background-color: green")
                
            #Comprobamos existencia de certificados
            if os.path.isfile('./public0.pem') and os.path.isfile('./privad0.pem'):
                self.etiquetaCer.setText("Certificados OK")
            elif not os.path.isfile('./public0.pem') and not os.path.isfile('./privad0.pem'):
                self.etiquetaCer.setText("¿Certificados?")
                self.linestado.setStyleSheet("background-color: red")
                self.linestado.setText("Faltan los certificados de cifrado!")
    
        def seleccionarAvatar(self):
                self.avatar = QFileDialog.getOpenFileName(self, 'Selecciona una imagen',".","Imagenes (*.png *.jpg *.bmp *.gif)")
                if self.avatar:
                    self.image = QImage(self.avatar)
                    if self.image.isNull():
                        popup = QMessageBox(QMessageBox.Critical, "Image load error", "Could not load image file!", QMessageBox.Ok, self)
                        popup.show()
                    else:
                        cursor = self.text.textCursor()
                        cursor.insertImage(self.image, self.avatar) 
    
        def conectar(self):
            self.conectado=True
            self.alinicio()
    
        def enviar(self, texto):
            texto = self.linaEnvio.text()
            tes = b''
            resultado = tes + texto.encode('utf-8')
    
            if self.linaEnvio.text():
                key = RSA.import_key(open('public0.pem').read())
                cipher = PKCS1_OAEP.new(key)
                textoCifrado = cipher.encrypt(resultado)
                self.lineEntry.appendPlainText(str(textoCifrado))
            else:
                self.linestado.setText("Escribe algo en el campo de texto encima del botón enviar...")
    
        def cerrar(self):
            self.seleccionarAvatar()
           # sys.exit(app.exec_())
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        ex = Ventana()
        ex.alinicio()
        sys.exit(app.exec_())
    
    # des= DESCIFRAR(cif)
    # print(des)
    
    
    
    # Aquí esta una solución.
    
    # key = RSA.import_key(open('privad0.pem').read())
    # cipher = PKCS1_OAEP.new(key)
    # textoDesCifrado = cipher.decrypt(mensaje)
    # return textoDesCifrado.decode("utf-8")