]> jfr.im git - irc/weechat/qweechat.git/commitdiff
Add SSL support
authorSebastien Helleu <redacted>
Fri, 27 Jul 2012 15:56:55 +0000 (17:56 +0200)
committerSebastien Helleu <redacted>
Fri, 27 Jul 2012 15:56:55 +0000 (17:56 +0200)
src/qweechat/config.py
src/qweechat/connection.py
src/qweechat/network.py
src/qweechat/qweechat.py

index 120a4bb18b26f2d3aa86e1a349091bc0abc75e54..31d7355dece5c8c5959c2ebd99214d434af7799c 100644 (file)
@@ -32,6 +32,7 @@ CONFIG_FILENAME = '%s/qweechat.conf' % CONFIG_DIR
 CONFIG_DEFAULT_SECTIONS = ('relay', 'look', 'color')
 CONFIG_DEFAULT_OPTIONS = (('relay.server', ''),
                           ('relay.port', ''),
+                          ('relay.ssl', 'off'),
                           ('relay.password', ''),
                           ('relay.autoconnect', 'off'),
                           ('look.debug', 'off'),
index 573038ea72f734d7f6d654af4dabec9d8bcff982..9092b1ce8a3f412959aa4b818a47a30e5a12c567 100644 (file)
@@ -42,11 +42,17 @@ class ConnectionDialog(QtGui.QDialog):
         for y, field in enumerate(('server', 'port', 'password')):
             grid.addWidget(QtGui.QLabel(field.capitalize()), y, 0)
             lineEdit = QtGui.QLineEdit()
+            lineEdit.setFixedWidth(200)
             if field == 'password':
                 lineEdit.setEchoMode(QtGui.QLineEdit.Password)
             lineEdit.insert(self.values[field])
             grid.addWidget(lineEdit, y, 1)
             self.fields[field] = lineEdit
+            if field == 'port':
+                ssl = QtGui.QCheckBox('SSL')
+                ssl.setChecked(self.values['ssl'] == 'on')
+                grid.addWidget(ssl, y, 2)
+                self.fields['ssl'] = ssl
 
         self.dialog_buttons = QtGui.QDialogButtonBox()
         self.dialog_buttons.setStandardButtons(QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel)
index 636afcf494db441df6c9639cd641017ad5945ad9..e97bb65c34e439e1e78bba8ece765953e2959949 100644 (file)
@@ -49,9 +49,10 @@ class Network(QtCore.QObject):
         self.status_connected = 'connected'
         self._server = None
         self._port = None
+        self._ssl = None
         self._password = None
         self._buffer = QtCore.QByteArray()
-        self._socket = QtNetwork.QTcpSocket()
+        self._socket = QtNetwork.QSslSocket()
         self._socket.connected.connect(self._socket_connected)
         self._socket.error.connect(self._socket_error)
         self._socket.readyRead.connect(self._socket_read)
@@ -61,7 +62,7 @@ class Network(QtCore.QObject):
         """Slot: socket connected."""
         self.statusChanged.emit(self.status_connected, None)
         if self._password:
-            self._socket.write('\n'.join(_PROTO_INIT_CMD + _PROTO_SYNC_CMDS) % {'password': str(self._password)})
+            self.send_to_weechat('\n'.join(_PROTO_INIT_CMD + _PROTO_SYNC_CMDS) % {'password': str(self._password)})
 
     def _socket_error(self, error):
         """Slot: socket error."""
@@ -69,8 +70,7 @@ class Network(QtCore.QObject):
 
     def _socket_read(self):
         """Slot: data available on socket."""
-        avail = self._socket.bytesAvailable()
-        bytes = self._socket.read(avail)
+        bytes = self._socket.readAll()
         self._buffer.append(bytes)
         while len(self._buffer) >= 4:
             remainder = None
@@ -84,6 +84,8 @@ class Network(QtCore.QObject):
                 remainder = self._buffer[length:]
                 self._buffer = self._buffer[0:length]
             self.messageFromWeechat.emit(self._buffer)
+            if not self.is_connected():
+                return
             self._buffer.clear()
             if remainder:
                 self._buffer.append(remainder)
@@ -92,30 +94,38 @@ class Network(QtCore.QObject):
         """Slot: socket disconnected."""
         self._server = None
         self._port = None
+        self._ssl = None
         self._password = None
         self.statusChanged.emit(self.status_disconnected, None)
 
     def is_connected(self):
         return self._socket.state() == QtNetwork.QAbstractSocket.ConnectedState
 
-    def connect_weechat(self, server, port, password):
+    def is_ssl(self):
+        return self._ssl
+
+    def connect_weechat(self, server, port, ssl, password):
         self._server = server
         try:
             self._port = int(port)
         except:
             self._port = 0
+        self._ssl = ssl
         self._password = password
         if self._socket.state() == QtNetwork.QAbstractSocket.ConnectedState:
             return
         if self._socket.state() != QtNetwork.QAbstractSocket.UnconnectedState:
             self._socket.abort()
         self._socket.connectToHost(self._server, self._port)
+        if self._ssl:
+            self._socket.ignoreSslErrors()
+            self._socket.startClientEncryption()
         self.statusChanged.emit(self.status_connecting, None)
 
     def disconnect_weechat(self):
         if self._socket.state() != QtNetwork.QAbstractSocket.UnconnectedState:
             if self._socket.state() == QtNetwork.QAbstractSocket.ConnectedState:
-                self._socket.write('quit\n')
+                self.send_to_weechat('quit\n')
                 self._socket.waitForBytesWritten(1000)
             else:
                 self.statusChanged.emit(self.status_disconnected, None)
@@ -125,10 +135,10 @@ class Network(QtCore.QObject):
         self._socket.write(str(message))
 
     def desync_weechat(self):
-        self._socket.write('desync\n')
+        self.send_to_weechat('desync\n')
 
     def sync_weechat(self):
-        self._socket.write('\n'.join(_PROTO_SYNC_CMDS))
+        self.send_to_weechat('\n'.join(_PROTO_SYNC_CMDS))
 
     def status_icon(self, status):
         icon = {self.status_disconnected: 'dialog-close.png',
index 1680669bc289436c739156075c0d0e9e48cea0ae..265a60453e9a4318212c9f1e894fad9b59d734b9 100755 (executable)
@@ -139,6 +139,7 @@ class MainWindow(QtGui.QMainWindow):
         if self.config.getboolean('relay', 'autoconnect'):
             self.network.connect_weechat(self.config.get('relay', 'server'),
                                          self.config.get('relay', 'port'),
+                                         self.config.get('relay', 'ssl') == 'on',
                                          self.config.get('relay', 'password'))
 
         self.show()
@@ -195,7 +196,7 @@ class MainWindow(QtGui.QMainWindow):
 
     def open_connection_dialog(self):
         values = {}
-        for option in ('server', 'port', 'password'):
+        for option in ('server', 'port', 'ssl', 'password'):
             values[option] = self.config.get('relay', option)
         self.connection_dialog = ConnectionDialog(values, self)
         self.connection_dialog.dialog_buttons.accepted.connect(self.connect_weechat)
@@ -203,6 +204,7 @@ class MainWindow(QtGui.QMainWindow):
     def connect_weechat(self):
         self.network.connect_weechat(self.connection_dialog.fields['server'].text(),
                                      self.connection_dialog.fields['port'].text(),
+                                     self.connection_dialog.fields['ssl'].isChecked(),
                                      self.connection_dialog.fields['password'].text())
         self.connection_dialog.close()
 
@@ -214,14 +216,15 @@ class MainWindow(QtGui.QMainWindow):
 
     def network_status_set(self, status, extra):
         pal = self.network_status.palette()
-        if self.network.is_connected():
+        if status == self.network.status_connected:
             pal.setColor(self.network_status.foregroundRole(), QtGui.QColor('green'))
         else:
             pal.setColor(self.network_status.foregroundRole(), QtGui.QColor('#aa0000'))
+        ssl = ' (SSL)' if status != self.network.status_disconnected and self.network.is_ssl() else ''
         self.network_status.setPalette(pal)
         icon = self.network.status_icon(status)
         if icon:
-            self.network_status.setText('<img src="data/icons/%s"> %s' % (icon, status.capitalize()))
+            self.network_status.setText('<img src="data/icons/%s"> %s' % (icon, status.capitalize() + ssl))
         else:
             self.network_status.setText(status.capitalize())
         if status == self.network.status_disconnected:
@@ -236,16 +239,20 @@ class MainWindow(QtGui.QMainWindow):
                            'message (%d bytes):\n%s'
                            % (len(message), protocol.hex_and_ascii(message, 20)),
                            forcecolor='#008800')
-        proto = protocol.Protocol()
-        message = proto.decode(str(message))
-        if message.uncompressed:
-            self.debug_display(0, '==>',
-                               'message uncompressed (%d bytes):\n%s'
-                               % (message.size_uncompressed,
-                                  protocol.hex_and_ascii(message.uncompressed, 20)),
-                               forcecolor='#008800')
-        self.debug_display(0, '', 'Message: %s' % message)
-        self.parse_message(message)
+        try:
+            proto = protocol.Protocol()
+            message = proto.decode(str(message))
+            if message.uncompressed:
+                self.debug_display(0, '==>',
+                                   'message uncompressed (%d bytes):\n%s'
+                                   % (message.size_uncompressed,
+                                      protocol.hex_and_ascii(message.uncompressed, 20)),
+                                   forcecolor='#008800')
+            self.debug_display(0, '', 'Message: %s' % message)
+            self.parse_message(message)
+        except:
+            print("Error while decoding message from WeeChat")
+            self.network.disconnect_weechat()
 
     def parse_message(self, message):
         if message.msgid.startswith('debug'):