[gnome-keysign: 2/65] bluetooth: initial commit using the bt_mac as code



commit 58d3602eb18beee338e0836b6289745e1df0a506
Author: RyuzakiKK <aasonykk gmail com>
Date:   Sun Jul 23 19:30:37 2017 +0200

    bluetooth: initial commit using the bt_mac as code

 keysign/bluetoothoffer.py   | 66 +++++++++++++++++++++++++++++++++++++++++++++
 keysign/bluetoothreceive.py | 39 +++++++++++++++++++++++++++
 keysign/send.py             | 17 ++++++++++--
 keysign/util.py             | 20 ++++++++++++++
 4 files changed, 140 insertions(+), 2 deletions(-)
---
diff --git a/keysign/bluetoothoffer.py b/keysign/bluetoothoffer.py
new file mode 100644
index 0000000..3f5787c
--- /dev/null
+++ b/keysign/bluetoothoffer.py
@@ -0,0 +1,66 @@
+import logging
+from bluetooth import *
+from twisted.internet import threads
+from twisted.internet.defer import inlineCallbacks
+
+from .gpgmh import get_public_key_data
+from .util import get_local_bt_address
+
+
+log = logging.getLogger(__name__)
+
+
+class BluetoothOffer:
+    def __init__(self, key, port=3, size=1024):
+        self.key = key
+        self.port = port
+        self.size = size
+        self.server_socket = None
+        self.message_def = None
+        self.stopped = False
+
+    @inlineCallbacks
+    def start(self):
+        self.stopped = False
+        client_socket = None
+        message = None
+        if self.server_socket is None:
+            self.server_socket = BluetoothSocket(RFCOMM)
+            self.server_socket.bind(("", self.port))
+            # Number of unaccepted connections that the system will allow before refusing new connections
+            backlog = 1
+            self.server_socket.listen(backlog)
+        try:
+            client_socket, address = yield threads.deferToThread(self.server_socket.accept)
+            key_data = get_public_key_data(self.key.fingerprint)
+            kd_decoded = key_data.decode('utf-8')
+            yield threads.deferToThread(client_socket.send, kd_decoded)
+            log.info("Key has been sent")
+            success = True
+        except Exception as e:
+            log.error("An error occurred: %s" % e)
+            success = False
+            message = e
+
+        if client_socket:
+            client_socket.close()
+        if not self.stopped:
+            return success, message
+
+    @staticmethod
+    def generate_code():
+        code = get_local_bt_address().upper()
+        log.info("BT Code: %s", code)
+        bt_data = "BT={0}".format(code)
+        return code, bt_data
+
+    def stop(self):
+        self.stopped = True
+
+    def stop_receive(self):
+        # FIXME right now it seems that even after stop()
+        # the used port is not released
+        log.debug("Stopping bt receive")
+        if self.server_socket:
+            self.server_socket.close()
+            self.server_socket = None
diff --git a/keysign/bluetoothreceive.py b/keysign/bluetoothreceive.py
new file mode 100644
index 0000000..a6fc09b
--- /dev/null
+++ b/keysign/bluetoothreceive.py
@@ -0,0 +1,39 @@
+import logging
+from bluetooth import *
+from twisted.internet import threads
+from twisted.internet.defer import inlineCallbacks, returnValue
+
+from .util import strip_fingerprint
+
+
+log = logging.getLogger(__name__)
+
+
+class BluetoothReceive:
+    def __init__(self, port=3, size=1024):
+        self.port = port
+        self.size = size
+        self.client_socket = None
+
+    @inlineCallbacks
+    def find_key(self, code):
+        mac = strip_fingerprint(code)
+        self.client_socket = BluetoothSocket(RFCOMM)
+        try:
+            yield threads.deferToThread(self.client_socket.connect, (mac, self.port))
+            message = yield threads.deferToThread(self.client_socket.recv, self.size)
+        except Exception as e:  # TODO better handling
+            log.error("An error occurred connecting or receiving: %s" % e)
+            key_data = None
+            success = False
+            returnValue((key_data, success, e))
+
+        if self.client_socket:
+            self.client_socket.close()
+
+        success = True
+        returnValue((message.decode("utf-8"), success, None))
+
+    def stop(self):
+        if self.client_socket:
+            self.client_socket.close()
diff --git a/keysign/send.py b/keysign/send.py
index f7f7f61..974101f 100755
--- a/keysign/send.py
+++ b/keysign/send.py
@@ -8,6 +8,11 @@ import gi
 gi.require_version('Gtk', '3.0')
 from gi.repository import Gtk
 from gi.repository import GLib  # for markup_escape_text
+if __name__ == "__main__":
+    from twisted.internet import gtk3reactor
+    gtk3reactor.install()
+from twisted.internet import reactor
+from twisted.internet.defer import inlineCallbacks
 
 if  __name__ == "__main__" and __package__ is None:
     logging.getLogger().error("You seem to be trying to execute " +
@@ -25,6 +30,7 @@ from .keylistwidget import KeyListWidget
 from .KeyPresent import KeyPresentWidget
 from .avahioffer import AvahiHTTPOffer
 from . import gpgmh
+from .bluetoothoffer import BluetoothOffer
 # We import i18n to have the locale set up for Glade
 from .i18n import _
 
@@ -75,6 +81,7 @@ class SendApp:
         kpw = KeyPresentWidget(fakekey, builder=builder)
 
 
+    @inlineCallbacks
     def on_key_activated(self, widget, key):
         log.info("Activated key %r", key)
         ####
@@ -120,6 +127,7 @@ class App(Gtk.Application):
         self.builder = Gtk.Builder.new_from_file(ui_file_path)
         window = self.builder.get_object("appwindow")
         assert window
+        window.connect("delete-event", self.on_delete_window)
         self.headerbar = self.builder.get_object("headerbar")
         hb = self.builder.get_object("headerbutton")
         hb.connect("clicked", self.on_headerbutton_clicked)
@@ -131,6 +139,9 @@ class App(Gtk.Application):
         window.show_all()
         self.add_window(window)
 
+    @staticmethod
+    def on_delete_window(*args):
+        reactor.callFromThread(reactor.stop)
 
     
 
@@ -168,7 +179,9 @@ if __name__ == "__main__":
     logging.basicConfig(level=logging.DEBUG)
     app = App()
     try:
-        GLib.unix_signal_add_full(GLib.PRIORITY_HIGH, signal.SIGINT, lambda *args : app.quit(), None)
+        GLib.unix_signal_add_full(GLib.PRIORITY_HIGH, signal.SIGINT,
+                                  lambda *args: reactor.callFromThread(reactor.stop), None)
     except AttributeError:
         pass
-    app.run()
+    reactor.registerGApplication(app)
+    reactor.run()
diff --git a/keysign/util.py b/keysign/util.py
index 5b6317e..5a9f8d0 100644
--- a/keysign/util.py
+++ b/keysign/util.py
@@ -18,6 +18,7 @@
 from __future__ import unicode_literals
 
 import hmac
+import json
 import logging
 from subprocess import call
 from string import Template
@@ -31,6 +32,8 @@ except ImportError:
 
 import requests
 
+from gi.repository import Gtk, GLib
+
 from .gpgmh import fingerprint_from_keydata
 from .gpgmh import sign_keydata_and_encrypt
 
@@ -220,3 +223,20 @@ def download_key_http(address, port):
     data = requests.get(url.geturl(), timeout=5).content
     log.debug("finished downloading %d bytes", len(data))
     return data
+
+
+def fix_infobar(infobar):
+    # Work around https://bugzilla.gnome.org/show_bug.cgi?id=710888
+    # Taken from here https://phabricator.freedesktop.org/D1103#34aa2703
+    def make_sure_revealer_does_nothing(widget):
+        if not isinstance(widget, Gtk.Revealer):
+            return
+        widget.set_transition_type(Gtk.RevealerTransitionType.NONE)
+    infobar.forall(make_sure_revealer_does_nothing)
+
+
+def get_local_bt_address(hci_number=0):
+    bus = dbus.SystemBus()
+    adapter = dbus.Interface(bus.get_object("org.bluez", "/org/bluez/hci%i" % hci_number),
+                             "org.freedesktop.DBus.Properties")
+    return adapter.Get("org.bluez.Adapter1", "Address")


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]