Hi,

This is a very simple (read insecure) way of adding authentication to
xpra: we just add a new field to capabilities and check the password
before accepting the connection past the "hello".

It does help protect local users, but is of absolutely no benefit if the
data is sent over the wire as this is absolutely trivial to snoop.

A more secure (but intrusive) password patch will follow.

Cheers
Antoine

Index: trunk/dev/xpra/client.py
===================================================================
--- trunk/dev/xpra/client.py	(revision 67)
+++ trunk/dev/xpra/client.py	(working copy)
@@ -268,7 +268,7 @@
 gobject.type_register(ClientWindow)
 
 class XpraClient(gobject.GObject):
-    def __init__(self, sock, compression_level, title_suffix):
+    def __init__(self, sock, compression_level, title_suffix, password):
         gobject.GObject.__init__(self)
         self._window_to_id = {}
         self._id_to_window = {}
@@ -277,6 +277,8 @@
         self._protocol = Protocol(sock, self.process_packet)
         ClientSource(self._protocol)
         capabilities_request = dict(default_capabilities)
+        if len(password)>0:
+            capabilities_request["password"] = password
         if compression_level:
             capabilities_request["deflate"] = compression_level
         self.send(["hello", capabilities_request])
Index: trunk/dev/xpra/scripts/server.py
===================================================================
--- trunk/dev/xpra/scripts/server.py	(revision 67)
+++ trunk/dev/xpra/scripts/server.py	(working copy)
@@ -284,7 +284,7 @@
 
     # This import is delayed because the module depends on gtk:
     import xpra.server
-    app = xpra.server.XpraServer(upgrading, sockets)
+    app = xpra.server.XpraServer(upgrading, sockets, opts.password)
     def cleanup_socket(self):
         print "removing socket"
         try:
Index: trunk/dev/xpra/server.py
===================================================================
--- trunk/dev/xpra/server.py	(revision 67)
+++ trunk/dev/xpra/server.py	(working copy)
@@ -207,7 +207,7 @@
         "wimpiggy-child-map-event": one_arg_signal,
         }
 
-    def __init__(self, clobber, sockets):
+    def __init__(self, clobber, sockets, password):
         gobject.GObject.__init__(self)
         
         # Do this before creating the Wm object, to avoid clobbering its
@@ -289,6 +289,8 @@
         self._has_focus = 0
         self._upgrading = False
 
+        self.password = password
+
         ### All right, we're ready to accept customers:
         self._protocol = None
         self._potential_protocols = []
@@ -483,7 +485,7 @@
 
     def _calculate_capabilities(self, client_capabilities):
         capabilities = {}
-        for cap in ("deflate", "__prerelease_version"):
+        for cap in ("deflate", "__prerelease_version", "password"):
             if cap in client_capabilities:
                 capabilities[cap] = client_capabilities[cap]
         return capabilities
@@ -497,6 +499,16 @@
                       + "of exactly the same version (v%s)", xpra.__version__)
             proto.close()
             return
+        if self.password:
+            client_pass = capabilities.get("password")
+            if not client_pass:
+                log.error("Client did not supply a password!")
+                proto.close()
+                return
+            if client_pass != self.password:
+                log.error("Password supplied does not match!")
+                proto.close()
+                return
         # Okay, things are okay, so let's boot out any existing connection and
         # set this as our new one:
         if self._protocol is not None:
Index: trunk/dev/xpra/scripts/main.py
===================================================================
--- trunk/dev/xpra/scripts/main.py	(revision 67)
+++ trunk/dev/xpra/scripts/main.py	(working copy)
@@ -53,6 +53,9 @@
                       dest="bind_tcp", default=None,
                       metavar="[HOST]:PORT",
                       help="Listen for connections over TCP (insecure)")
+    parser.add_option("--password", action="store",
+                      dest="password", default=None,
+                      help="Password required to connect (useful to secure TCP mode)")
     parser.add_option("--title-suffix", action="store",
                       dest="title_suffix", default=" (via xpra)",
                       help="Text which is appended to the window's title")
@@ -164,7 +167,7 @@
     sock, local = client_sock(parser, opts, pick_display(parser, extra_args))
     if opts.compression_level < 0 or opts.compression_level > 9:
         parser.error("Compression level must be between 0 and 9 inclusive.")
-    app = XpraClient(sock, opts.compression_level, opts.title_suffix)
+    app = XpraClient(sock, opts.compression_level, opts.title_suffix, opts.password)
     sys.stdout.write("Attached\n")
     app.run()
 

Attachment: signature.asc
Description: OpenPGP digital signature

_______________________________________________
Parti-discuss mailing list
[email protected]
http://lists.partiwm.org/cgi-bin/mailman/listinfo/parti-discuss

Reply via email to